From 4a89dce715853ff409dc0b910aa4da62aa11fbae Mon Sep 17 00:00:00 2001 From: Kyle Squizzato Date: Mon, 29 Jun 2026 10:41:32 -0700 Subject: [PATCH 01/16] feat: implement agent sandbox configuration Add ConfigMap-based agent declarations with sandbox config fields. Full-stack implementation: OpenAPI schema, DB migration, SDK regeneration, control plane ConfigMap syncer, and UI manifest rendering. Co-Authored-By: Claude Opus 4.6 --- .../openapi/openapi.agents.yaml | 103 +++++ .../pkg/api/openapi/.openapi-generator/FILES | 8 + .../pkg/api/openapi/README.md | 4 + .../pkg/api/openapi/api/openapi.yaml | 324 +++++++++++++-- .../pkg/api/openapi/docs/Agent.md | 156 +++++++ .../pkg/api/openapi/docs/AgentPatchRequest.md | 156 +++++++ .../pkg/api/openapi/docs/GpuRequirements.md | 56 +++ .../pkg/api/openapi/docs/Payload.md | 129 ++++++ .../api/openapi/docs/ResourceRequirements.md | 82 ++++ .../pkg/api/openapi/docs/SandboxTemplate.md | 238 +++++++++++ .../pkg/api/openapi/model_agent.go | 221 ++++++++++ .../api/openapi/model_agent_patch_request.go | 230 ++++++++++- .../pkg/api/openapi/model_gpu_requirements.go | 126 ++++++ .../pkg/api/openapi/model_payload.go | 269 ++++++++++++ .../openapi/model_resource_requirements.go | 163 ++++++++ .../pkg/api/openapi/model_sandbox_template.go | 383 ++++++++++++++++++ .../plugins/agents/handler.go | 31 ++ .../plugins/agents/migration.go | 34 ++ .../plugins/agents/model.go | 6 + .../plugins/agents/plugin.go | 1 + .../plugins/agents/presenter.go | 61 ++- .../cmd/ambient-control-plane/main.go | 23 ++ components/ambient-control-plane/go.mod | 1 + .../internal/kubeclient/kubeclient.go | 5 + .../reconciler/configmap_reconciler.go | 343 ++++++++++++++++ .../internal/reconciler/kube_reconciler.go | 62 ++- .../ambient-sdk/go-sdk/client/agent_api.go | 4 +- .../ambient-sdk/go-sdk/client/client.go | 4 +- .../go-sdk/client/credential_api.go | 4 +- .../go-sdk/client/inbox_message_api.go | 4 +- .../ambient-sdk/go-sdk/client/iterator.go | 4 +- .../ambient-sdk/go-sdk/client/project_api.go | 4 +- .../go-sdk/client/project_settings_api.go | 4 +- .../ambient-sdk/go-sdk/client/role_api.go | 4 +- .../go-sdk/client/role_binding_api.go | 4 +- .../go-sdk/client/scheduled_session_api.go | 4 +- .../ambient-sdk/go-sdk/client/session_api.go | 4 +- .../go-sdk/client/session_message_api.go | 4 +- .../ambient-sdk/go-sdk/client/user_api.go | 4 +- components/ambient-sdk/go-sdk/types/agent.go | 70 +++- components/ambient-sdk/go-sdk/types/base.go | 4 +- .../ambient-sdk/go-sdk/types/credential.go | 4 +- .../ambient-sdk/go-sdk/types/inbox_message.go | 4 +- .../ambient-sdk/go-sdk/types/list_options.go | 4 +- .../ambient-sdk/go-sdk/types/project.go | 4 +- .../go-sdk/types/project_settings.go | 4 +- components/ambient-sdk/go-sdk/types/role.go | 4 +- .../ambient-sdk/go-sdk/types/role_binding.go | 4 +- .../go-sdk/types/scheduled_session.go | 4 +- .../ambient-sdk/go-sdk/types/session.go | 4 +- .../go-sdk/types/session_message.go | 4 +- components/ambient-sdk/go-sdk/types/user.go | 4 +- .../python-sdk/ambient_platform/__init__.py | 4 +- .../python-sdk/ambient_platform/_agent_api.py | 4 +- .../python-sdk/ambient_platform/_base.py | 4 +- .../ambient_platform/_credential_api.py | 4 +- .../ambient_platform/_inbox_message_api.py | 4 +- .../python-sdk/ambient_platform/_iterator.py | 4 +- .../ambient_platform/_project_api.py | 4 +- .../ambient_platform/_project_settings_api.py | 4 +- .../python-sdk/ambient_platform/_role_api.py | 4 +- .../ambient_platform/_role_binding_api.py | 4 +- .../_scheduled_session_api.py | 4 +- .../ambient_platform/_session_api.py | 4 +- .../ambient_platform/_session_message_api.py | 4 +- .../python-sdk/ambient_platform/_user_api.py | 4 +- .../python-sdk/ambient_platform/agent.py | 64 ++- .../python-sdk/ambient_platform/client.py | 4 +- .../python-sdk/ambient_platform/credential.py | 4 +- .../ambient_platform/inbox_message.py | 4 +- .../python-sdk/ambient_platform/project.py | 4 +- .../ambient_platform/project_settings.py | 4 +- .../python-sdk/ambient_platform/role.py | 4 +- .../ambient_platform/role_binding.py | 4 +- .../ambient_platform/scheduled_session.py | 4 +- .../python-sdk/ambient_platform/session.py | 4 +- .../ambient_platform/session_message.py | 4 +- .../python-sdk/ambient_platform/user.py | 4 +- components/ambient-sdk/ts-sdk/src/agent.ts | 82 +++- .../ambient-sdk/ts-sdk/src/agent_api.ts | 4 +- components/ambient-sdk/ts-sdk/src/base.ts | 4 +- components/ambient-sdk/ts-sdk/src/client.ts | 4 +- .../ambient-sdk/ts-sdk/src/credential.ts | 4 +- .../ambient-sdk/ts-sdk/src/credential_api.ts | 4 +- .../ambient-sdk/ts-sdk/src/inbox_message.ts | 4 +- .../ts-sdk/src/inbox_message_api.ts | 4 +- components/ambient-sdk/ts-sdk/src/index.ts | 4 +- components/ambient-sdk/ts-sdk/src/project.ts | 4 +- .../ambient-sdk/ts-sdk/src/project_api.ts | 4 +- .../ts-sdk/src/project_settings.ts | 4 +- .../ts-sdk/src/project_settings_api.ts | 4 +- components/ambient-sdk/ts-sdk/src/role.ts | 4 +- components/ambient-sdk/ts-sdk/src/role_api.ts | 4 +- .../ambient-sdk/ts-sdk/src/role_binding.ts | 4 +- .../ts-sdk/src/role_binding_api.ts | 4 +- .../ts-sdk/src/scheduled_session.ts | 4 +- .../ts-sdk/src/scheduled_session_api.ts | 4 +- components/ambient-sdk/ts-sdk/src/session.ts | 4 +- .../ambient-sdk/ts-sdk/src/session_api.ts | 4 +- .../ambient-sdk/ts-sdk/src/session_message.ts | 4 +- .../ts-sdk/src/session_message_api.ts | 4 +- components/ambient-sdk/ts-sdk/src/user.ts | 4 +- components/ambient-sdk/ts-sdk/src/user_api.ts | 4 +- .../src/adapters/__tests__/mappers.test.ts | 6 + components/ambient-ui/src/adapters/mappers.ts | 50 ++- .../ambient-ui/src/adapters/sdk-agents.ts | 12 + .../_components/agent-manifest-tab.tsx | 42 ++ components/ambient-ui/src/domain/types.ts | 42 ++ examples/agent-sandbox-config.yaml | 139 +++++++ 109 files changed, 3817 insertions(+), 201 deletions(-) create mode 100644 components/ambient-api-server/pkg/api/openapi/docs/GpuRequirements.md create mode 100644 components/ambient-api-server/pkg/api/openapi/docs/Payload.md create mode 100644 components/ambient-api-server/pkg/api/openapi/docs/ResourceRequirements.md create mode 100644 components/ambient-api-server/pkg/api/openapi/docs/SandboxTemplate.md create mode 100644 components/ambient-api-server/pkg/api/openapi/model_gpu_requirements.go create mode 100644 components/ambient-api-server/pkg/api/openapi/model_payload.go create mode 100644 components/ambient-api-server/pkg/api/openapi/model_resource_requirements.go create mode 100644 components/ambient-api-server/pkg/api/openapi/model_sandbox_template.go create mode 100644 components/ambient-control-plane/internal/reconciler/configmap_reconciler.go create mode 100644 examples/agent-sandbox-config.yaml diff --git a/components/ambient-api-server/openapi/openapi.agents.yaml b/components/ambient-api-server/openapi/openapi.agents.yaml index af0a850ca..74fb7ec01 100644 --- a/components/ambient-api-server/openapi/openapi.agents.yaml +++ b/components/ambient-api-server/openapi/openapi.agents.yaml @@ -453,6 +453,29 @@ components: type: string environment_variables: type: string + entrypoint: + type: string + description: CLI binary to launch inside the sandbox (e.g., claude, opencode, bash). Defaults to claude. + providers: + type: array + items: + type: string + description: Names of providers this agent requires, referencing provider declarations in the tenant namespace. + payloads: + type: array + items: + $ref: '#/components/schemas/Payload' + description: Content to upload into the sandbox filesystem before the entrypoint launches. + environment: + type: object + additionalProperties: + type: string + description: Environment variables injected into the sandbox at creation time. + sandbox_template: + $ref: '#/components/schemas/SandboxTemplate' + sandbox_policy: + type: string + description: Name of a policy declaration in the tenant namespace. When omitted, the platform default policy applies. current_session_id: type: string readOnly: true @@ -498,10 +521,90 @@ components: llm_max_tokens: type: integer format: int32 + entrypoint: + type: string + providers: + type: array + items: + type: string + payloads: + type: array + items: + $ref: '#/components/schemas/Payload' + environment: + type: object + additionalProperties: + type: string + sandbox_template: + $ref: '#/components/schemas/SandboxTemplate' + sandbox_policy: + type: string labels: type: string annotations: type: string + Payload: + type: object + required: + - sandbox_path + properties: + sandbox_path: + type: string + description: Absolute path inside the sandbox where the content is delivered. + content: + type: string + description: Inline string content to place at the sandbox path. + repo_url: + type: string + description: Git repository URL to clone into the sandbox path. + ref: + type: string + description: Git ref to check out (branch, tag, or commit SHA). Only valid with repo_url. + SandboxTemplate: + type: object + properties: + image: + type: string + description: OCI container image reference for the sandbox. + resources: + $ref: '#/components/schemas/ResourceRequirements' + gpu: + $ref: '#/components/schemas/GpuRequirements' + runtime_class_name: + type: string + description: Kubernetes RuntimeClassName for the sandbox pod. + driver_config: + type: object + additionalProperties: true + description: OpenShell driver-specific opaque configuration (JSON). + labels: + type: object + additionalProperties: + type: string + description: Labels applied to the sandbox compute resources. + annotations: + type: object + additionalProperties: + type: string + description: Annotations applied to the sandbox compute resources. + log_level: + type: string + description: Sandbox supervisor log verbosity (debug, info, warn, error). + ResourceRequirements: + type: object + properties: + cpu: + type: string + description: CPU request/limit in Kubernetes quantity format (e.g., "2", "500m"). + memory: + type: string + description: Memory request/limit in Kubernetes quantity format (e.g., "4Gi", "256Mi"). + GpuRequirements: + type: object + properties: + count: + type: integer + description: Number of GPUs to allocate. Default 0. AgentSessionList: allOf: - $ref: 'openapi.yaml#/components/schemas/List' diff --git a/components/ambient-api-server/pkg/api/openapi/.openapi-generator/FILES b/components/ambient-api-server/pkg/api/openapi/.openapi-generator/FILES index c957839be..79748a886 100644 --- a/components/ambient-api-server/pkg/api/openapi/.openapi-generator/FILES +++ b/components/ambient-api-server/pkg/api/openapi/.openapi-generator/FILES @@ -16,11 +16,13 @@ docs/CredentialPatchRequest.md docs/CredentialTokenResponse.md docs/DefaultAPI.md docs/Error.md +docs/GpuRequirements.md docs/InboxMessage.md docs/InboxMessageList.md docs/InboxMessagePatchRequest.md docs/List.md docs/ObjectReference.md +docs/Payload.md docs/Project.md docs/ProjectHome.md docs/ProjectHomeAgent.md @@ -29,12 +31,14 @@ docs/ProjectPatchRequest.md docs/ProjectSettings.md docs/ProjectSettingsList.md docs/ProjectSettingsPatchRequest.md +docs/ResourceRequirements.md docs/Role.md docs/RoleBinding.md docs/RoleBindingList.md docs/RoleBindingPatchRequest.md docs/RoleList.md docs/RolePatchRequest.md +docs/SandboxTemplate.md docs/ScheduledSession.md docs/ScheduledSessionList.md docs/ScheduledSessionPatchRequest.md @@ -61,11 +65,13 @@ model_credential_list.go model_credential_patch_request.go model_credential_token_response.go model_error.go +model_gpu_requirements.go model_inbox_message.go model_inbox_message_list.go model_inbox_message_patch_request.go model_list.go model_object_reference.go +model_payload.go model_project.go model_project_home.go model_project_home_agent.go @@ -74,12 +80,14 @@ model_project_patch_request.go model_project_settings.go model_project_settings_list.go model_project_settings_patch_request.go +model_resource_requirements.go model_role.go model_role_binding.go model_role_binding_list.go model_role_binding_patch_request.go model_role_list.go model_role_patch_request.go +model_sandbox_template.go model_scheduled_session.go model_scheduled_session_list.go model_scheduled_session_patch_request.go diff --git a/components/ambient-api-server/pkg/api/openapi/README.md b/components/ambient-api-server/pkg/api/openapi/README.md index fffafb1a3..c2a30b0d6 100644 --- a/components/ambient-api-server/pkg/api/openapi/README.md +++ b/components/ambient-api-server/pkg/api/openapi/README.md @@ -159,11 +159,13 @@ Class | Method | HTTP request | Description - [CredentialPatchRequest](docs/CredentialPatchRequest.md) - [CredentialTokenResponse](docs/CredentialTokenResponse.md) - [Error](docs/Error.md) + - [GpuRequirements](docs/GpuRequirements.md) - [InboxMessage](docs/InboxMessage.md) - [InboxMessageList](docs/InboxMessageList.md) - [InboxMessagePatchRequest](docs/InboxMessagePatchRequest.md) - [List](docs/List.md) - [ObjectReference](docs/ObjectReference.md) + - [Payload](docs/Payload.md) - [Project](docs/Project.md) - [ProjectHome](docs/ProjectHome.md) - [ProjectHomeAgent](docs/ProjectHomeAgent.md) @@ -172,12 +174,14 @@ Class | Method | HTTP request | Description - [ProjectSettings](docs/ProjectSettings.md) - [ProjectSettingsList](docs/ProjectSettingsList.md) - [ProjectSettingsPatchRequest](docs/ProjectSettingsPatchRequest.md) + - [ResourceRequirements](docs/ResourceRequirements.md) - [Role](docs/Role.md) - [RoleBinding](docs/RoleBinding.md) - [RoleBindingList](docs/RoleBindingList.md) - [RoleBindingPatchRequest](docs/RoleBindingPatchRequest.md) - [RoleList](docs/RoleList.md) - [RolePatchRequest](docs/RolePatchRequest.md) + - [SandboxTemplate](docs/SandboxTemplate.md) - [ScheduledSession](docs/ScheduledSession.md) - [ScheduledSessionList](docs/ScheduledSessionList.md) - [ScheduledSessionPatchRequest](docs/ScheduledSessionPatchRequest.md) diff --git a/components/ambient-api-server/pkg/api/openapi/api/openapi.yaml b/components/ambient-api-server/pkg/api/openapi/api/openapi.yaml index 594ad2e95..b50af6181 100644 --- a/components/ambient-api-server/pkg/api/openapi/api/openapi.yaml +++ b/components/ambient-api-server/pkg/api/openapi/api/openapi.yaml @@ -4912,6 +4912,34 @@ components: type: string environment_variables: type: string + entrypoint: + description: "CLI binary to launch inside the sandbox (e.g., claude, opencode,\ + \ bash). Defaults to claude." + type: string + providers: + description: "Names of providers this agent requires, referencing provider\ + \ declarations in the tenant namespace." + items: + type: string + type: array + payloads: + description: Content to upload into the sandbox filesystem before the + entrypoint launches. + items: + $ref: "#/components/schemas/Payload" + type: array + environment: + additionalProperties: + type: string + description: Environment variables injected into the sandbox at creation + time. + type: object + sandbox_template: + $ref: "#/components/schemas/SandboxTemplate" + sandbox_policy: + description: "Name of a policy declaration in the tenant namespace. When\ + \ omitted, the platform default policy applies." + type: string current_session_id: description: "Denormalized for fast reads — the active session, if any" readOnly: true @@ -4931,28 +4959,59 @@ components: - project_id type: object example: - repo_url: repo_url workflow_id: workflow_id + payloads: + - repo_url: repo_url + ref: ref + sandbox_path: sandbox_path + content: content + - repo_url: repo_url + ref: ref + sandbox_path: sandbox_path + content: content + current_session_id: current_session_id + created_at: 2000-01-23T04:56:07.000+00:00 + description: description + annotations: annotations + sandbox_policy: sandbox_policy + environment_variables: environment_variables + updated_at: 2000-01-23T04:56:07.000+00:00 + project_id: project_id + entrypoint: entrypoint + id: id + href: href + repo_url: repo_url llm_model: llm_model resource_overrides: resource_overrides owner_user_id: owner_user_id - current_session_id: current_session_id kind: kind llm_temperature: 5.962133916683182 - created_at: 2000-01-23T04:56:07.000+00:00 - description: description - annotations: annotations display_name: display_name llm_max_tokens: 5 + sandbox_template: + image: image + runtime_class_name: runtime_class_name + log_level: log_level + resources: + memory: memory + cpu: cpu + annotations: + key: annotations + gpu: + count: 2 + driver_config: + key: "" + labels: + key: labels labels: labels - environment_variables: environment_variables - updated_at: 2000-01-23T04:56:07.000+00:00 - project_id: project_id + environment: + key: environment bot_account_name: bot_account_name name: name - id: id - href: href prompt: prompt + providers: + - providers + - providers AgentList: allOf: - $ref: "#/components/schemas/List" @@ -4968,62 +5027,155 @@ components: kind: kind page: 0 items: - - repo_url: repo_url - workflow_id: workflow_id + - workflow_id: workflow_id + payloads: + - repo_url: repo_url + ref: ref + sandbox_path: sandbox_path + content: content + - repo_url: repo_url + ref: ref + sandbox_path: sandbox_path + content: content + current_session_id: current_session_id + created_at: 2000-01-23T04:56:07.000+00:00 + description: description + annotations: annotations + sandbox_policy: sandbox_policy + environment_variables: environment_variables + updated_at: 2000-01-23T04:56:07.000+00:00 + project_id: project_id + entrypoint: entrypoint + id: id + href: href + repo_url: repo_url llm_model: llm_model resource_overrides: resource_overrides owner_user_id: owner_user_id - current_session_id: current_session_id kind: kind llm_temperature: 5.962133916683182 - created_at: 2000-01-23T04:56:07.000+00:00 - description: description - annotations: annotations display_name: display_name llm_max_tokens: 5 + sandbox_template: + image: image + runtime_class_name: runtime_class_name + log_level: log_level + resources: + memory: memory + cpu: cpu + annotations: + key: annotations + gpu: + count: 2 + driver_config: + key: "" + labels: + key: labels labels: labels + environment: + key: environment + bot_account_name: bot_account_name + name: name + prompt: prompt + providers: + - providers + - providers + - workflow_id: workflow_id + payloads: + - repo_url: repo_url + ref: ref + sandbox_path: sandbox_path + content: content + - repo_url: repo_url + ref: ref + sandbox_path: sandbox_path + content: content + current_session_id: current_session_id + created_at: 2000-01-23T04:56:07.000+00:00 + description: description + annotations: annotations + sandbox_policy: sandbox_policy environment_variables: environment_variables updated_at: 2000-01-23T04:56:07.000+00:00 project_id: project_id - bot_account_name: bot_account_name - name: name + entrypoint: entrypoint id: id href: href - prompt: prompt - - repo_url: repo_url - workflow_id: workflow_id + repo_url: repo_url llm_model: llm_model resource_overrides: resource_overrides owner_user_id: owner_user_id - current_session_id: current_session_id kind: kind llm_temperature: 5.962133916683182 - created_at: 2000-01-23T04:56:07.000+00:00 - description: description - annotations: annotations display_name: display_name llm_max_tokens: 5 + sandbox_template: + image: image + runtime_class_name: runtime_class_name + log_level: log_level + resources: + memory: memory + cpu: cpu + annotations: + key: annotations + gpu: + count: 2 + driver_config: + key: "" + labels: + key: labels labels: labels - environment_variables: environment_variables - updated_at: 2000-01-23T04:56:07.000+00:00 - project_id: project_id + environment: + key: environment bot_account_name: bot_account_name name: name - id: id - href: href prompt: prompt + providers: + - providers + - providers AgentPatchRequest: example: repo_url: repo_url llm_model: llm_model + payloads: + - repo_url: repo_url + ref: ref + sandbox_path: sandbox_path + content: content + - repo_url: repo_url + ref: ref + sandbox_path: sandbox_path + content: content llm_temperature: 0.8008281904610115 - name: name description: description annotations: annotations display_name: display_name - prompt: prompt + sandbox_policy: sandbox_policy llm_max_tokens: 6 + sandbox_template: + image: image + runtime_class_name: runtime_class_name + log_level: log_level + resources: + memory: memory + cpu: cpu + annotations: + key: annotations + gpu: + count: 2 + driver_config: + key: "" + labels: + key: labels labels: labels + environment: + key: environment + entrypoint: entrypoint + name: name + prompt: prompt + providers: + - providers + - providers properties: name: type: string @@ -5044,6 +5196,24 @@ components: llm_max_tokens: format: int32 type: integer + entrypoint: + type: string + providers: + items: + type: string + type: array + payloads: + items: + $ref: "#/components/schemas/Payload" + type: array + environment: + additionalProperties: + type: string + type: object + sandbox_template: + $ref: "#/components/schemas/SandboxTemplate" + sandbox_policy: + type: string labels: type: string annotations: @@ -5656,6 +5826,96 @@ components: runner_type: type: string type: object + Payload: + example: + repo_url: repo_url + ref: ref + sandbox_path: sandbox_path + content: content + properties: + sandbox_path: + description: Absolute path inside the sandbox where the content is delivered. + type: string + content: + description: Inline string content to place at the sandbox path. + type: string + repo_url: + description: Git repository URL to clone into the sandbox path. + type: string + ref: + description: "Git ref to check out (branch, tag, or commit SHA). Only valid\ + \ with repo_url." + type: string + required: + - sandbox_path + type: object + SandboxTemplate: + example: + image: image + runtime_class_name: runtime_class_name + log_level: log_level + resources: + memory: memory + cpu: cpu + annotations: + key: annotations + gpu: + count: 2 + driver_config: + key: "" + labels: + key: labels + properties: + image: + description: OCI container image reference for the sandbox. + type: string + resources: + $ref: "#/components/schemas/ResourceRequirements" + gpu: + $ref: "#/components/schemas/GpuRequirements" + runtime_class_name: + description: Kubernetes RuntimeClassName for the sandbox pod. + type: string + driver_config: + additionalProperties: true + description: OpenShell driver-specific opaque configuration (JSON). + type: object + labels: + additionalProperties: + type: string + description: Labels applied to the sandbox compute resources. + type: object + annotations: + additionalProperties: + type: string + description: Annotations applied to the sandbox compute resources. + type: object + log_level: + description: "Sandbox supervisor log verbosity (debug, info, warn, error)." + type: string + type: object + ResourceRequirements: + example: + memory: memory + cpu: cpu + properties: + cpu: + description: "CPU request/limit in Kubernetes quantity format (e.g., \"\ + 2\", \"500m\")." + type: string + memory: + description: "Memory request/limit in Kubernetes quantity format (e.g.,\ + \ \"4Gi\", \"256Mi\")." + type: string + type: object + GpuRequirements: + example: + count: 2 + properties: + count: + description: Number of GPUs to allocate. Default 0. + type: integer + type: object securitySchemes: Bearer: bearerFormat: JWT diff --git a/components/ambient-api-server/pkg/api/openapi/docs/Agent.md b/components/ambient-api-server/pkg/api/openapi/docs/Agent.md index 6b5184d38..ec78a3511 100644 --- a/components/ambient-api-server/pkg/api/openapi/docs/Agent.md +++ b/components/ambient-api-server/pkg/api/openapi/docs/Agent.md @@ -23,6 +23,12 @@ Name | Type | Description | Notes **BotAccountName** | Pointer to **string** | | [optional] **ResourceOverrides** | Pointer to **string** | | [optional] **EnvironmentVariables** | Pointer to **string** | | [optional] +**Entrypoint** | Pointer to **string** | CLI binary to launch inside the sandbox (e.g., claude, opencode, bash). Defaults to claude. | [optional] +**Providers** | Pointer to **[]string** | Names of providers this agent requires, referencing provider declarations in the tenant namespace. | [optional] +**Payloads** | Pointer to [**[]Payload**](Payload.md) | Content to upload into the sandbox filesystem before the entrypoint launches. | [optional] +**Environment** | Pointer to **map[string]string** | Environment variables injected into the sandbox at creation time. | [optional] +**SandboxTemplate** | Pointer to [**SandboxTemplate**](SandboxTemplate.md) | | [optional] +**SandboxPolicy** | Pointer to **string** | Name of a policy declaration in the tenant namespace. When omitted, the platform default policy applies. | [optional] **CurrentSessionId** | Pointer to **string** | Denormalized for fast reads — the active session, if any | [optional] [readonly] **Labels** | Pointer to **string** | | [optional] **Annotations** | Pointer to **string** | | [optional] @@ -511,6 +517,156 @@ SetEnvironmentVariables sets EnvironmentVariables field to given value. HasEnvironmentVariables returns a boolean if a field has been set. +### GetEntrypoint + +`func (o *Agent) GetEntrypoint() string` + +GetEntrypoint returns the Entrypoint field if non-nil, zero value otherwise. + +### GetEntrypointOk + +`func (o *Agent) GetEntrypointOk() (*string, bool)` + +GetEntrypointOk returns a tuple with the Entrypoint field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetEntrypoint + +`func (o *Agent) SetEntrypoint(v string)` + +SetEntrypoint sets Entrypoint field to given value. + +### HasEntrypoint + +`func (o *Agent) HasEntrypoint() bool` + +HasEntrypoint returns a boolean if a field has been set. + +### GetProviders + +`func (o *Agent) GetProviders() []string` + +GetProviders returns the Providers field if non-nil, zero value otherwise. + +### GetProvidersOk + +`func (o *Agent) GetProvidersOk() (*[]string, bool)` + +GetProvidersOk returns a tuple with the Providers field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetProviders + +`func (o *Agent) SetProviders(v []string)` + +SetProviders sets Providers field to given value. + +### HasProviders + +`func (o *Agent) HasProviders() bool` + +HasProviders returns a boolean if a field has been set. + +### GetPayloads + +`func (o *Agent) GetPayloads() []Payload` + +GetPayloads returns the Payloads field if non-nil, zero value otherwise. + +### GetPayloadsOk + +`func (o *Agent) GetPayloadsOk() (*[]Payload, bool)` + +GetPayloadsOk returns a tuple with the Payloads field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPayloads + +`func (o *Agent) SetPayloads(v []Payload)` + +SetPayloads sets Payloads field to given value. + +### HasPayloads + +`func (o *Agent) HasPayloads() bool` + +HasPayloads returns a boolean if a field has been set. + +### GetEnvironment + +`func (o *Agent) GetEnvironment() map[string]string` + +GetEnvironment returns the Environment field if non-nil, zero value otherwise. + +### GetEnvironmentOk + +`func (o *Agent) GetEnvironmentOk() (*map[string]string, bool)` + +GetEnvironmentOk returns a tuple with the Environment field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetEnvironment + +`func (o *Agent) SetEnvironment(v map[string]string)` + +SetEnvironment sets Environment field to given value. + +### HasEnvironment + +`func (o *Agent) HasEnvironment() bool` + +HasEnvironment returns a boolean if a field has been set. + +### GetSandboxTemplate + +`func (o *Agent) GetSandboxTemplate() SandboxTemplate` + +GetSandboxTemplate returns the SandboxTemplate field if non-nil, zero value otherwise. + +### GetSandboxTemplateOk + +`func (o *Agent) GetSandboxTemplateOk() (*SandboxTemplate, bool)` + +GetSandboxTemplateOk returns a tuple with the SandboxTemplate field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSandboxTemplate + +`func (o *Agent) SetSandboxTemplate(v SandboxTemplate)` + +SetSandboxTemplate sets SandboxTemplate field to given value. + +### HasSandboxTemplate + +`func (o *Agent) HasSandboxTemplate() bool` + +HasSandboxTemplate returns a boolean if a field has been set. + +### GetSandboxPolicy + +`func (o *Agent) GetSandboxPolicy() string` + +GetSandboxPolicy returns the SandboxPolicy field if non-nil, zero value otherwise. + +### GetSandboxPolicyOk + +`func (o *Agent) GetSandboxPolicyOk() (*string, bool)` + +GetSandboxPolicyOk returns a tuple with the SandboxPolicy field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSandboxPolicy + +`func (o *Agent) SetSandboxPolicy(v string)` + +SetSandboxPolicy sets SandboxPolicy field to given value. + +### HasSandboxPolicy + +`func (o *Agent) HasSandboxPolicy() bool` + +HasSandboxPolicy returns a boolean if a field has been set. + ### GetCurrentSessionId `func (o *Agent) GetCurrentSessionId() string` diff --git a/components/ambient-api-server/pkg/api/openapi/docs/AgentPatchRequest.md b/components/ambient-api-server/pkg/api/openapi/docs/AgentPatchRequest.md index 14f652554..c273aca10 100644 --- a/components/ambient-api-server/pkg/api/openapi/docs/AgentPatchRequest.md +++ b/components/ambient-api-server/pkg/api/openapi/docs/AgentPatchRequest.md @@ -12,6 +12,12 @@ Name | Type | Description | Notes **LlmModel** | Pointer to **string** | | [optional] **LlmTemperature** | Pointer to **float64** | | [optional] **LlmMaxTokens** | Pointer to **int32** | | [optional] +**Entrypoint** | Pointer to **string** | | [optional] +**Providers** | Pointer to **[]string** | | [optional] +**Payloads** | Pointer to [**[]Payload**](Payload.md) | | [optional] +**Environment** | Pointer to **map[string]string** | | [optional] +**SandboxTemplate** | Pointer to [**SandboxTemplate**](SandboxTemplate.md) | | [optional] +**SandboxPolicy** | Pointer to **string** | | [optional] **Labels** | Pointer to **string** | | [optional] **Annotations** | Pointer to **string** | | [optional] @@ -234,6 +240,156 @@ SetLlmMaxTokens sets LlmMaxTokens field to given value. HasLlmMaxTokens returns a boolean if a field has been set. +### GetEntrypoint + +`func (o *AgentPatchRequest) GetEntrypoint() string` + +GetEntrypoint returns the Entrypoint field if non-nil, zero value otherwise. + +### GetEntrypointOk + +`func (o *AgentPatchRequest) GetEntrypointOk() (*string, bool)` + +GetEntrypointOk returns a tuple with the Entrypoint field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetEntrypoint + +`func (o *AgentPatchRequest) SetEntrypoint(v string)` + +SetEntrypoint sets Entrypoint field to given value. + +### HasEntrypoint + +`func (o *AgentPatchRequest) HasEntrypoint() bool` + +HasEntrypoint returns a boolean if a field has been set. + +### GetProviders + +`func (o *AgentPatchRequest) GetProviders() []string` + +GetProviders returns the Providers field if non-nil, zero value otherwise. + +### GetProvidersOk + +`func (o *AgentPatchRequest) GetProvidersOk() (*[]string, bool)` + +GetProvidersOk returns a tuple with the Providers field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetProviders + +`func (o *AgentPatchRequest) SetProviders(v []string)` + +SetProviders sets Providers field to given value. + +### HasProviders + +`func (o *AgentPatchRequest) HasProviders() bool` + +HasProviders returns a boolean if a field has been set. + +### GetPayloads + +`func (o *AgentPatchRequest) GetPayloads() []Payload` + +GetPayloads returns the Payloads field if non-nil, zero value otherwise. + +### GetPayloadsOk + +`func (o *AgentPatchRequest) GetPayloadsOk() (*[]Payload, bool)` + +GetPayloadsOk returns a tuple with the Payloads field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPayloads + +`func (o *AgentPatchRequest) SetPayloads(v []Payload)` + +SetPayloads sets Payloads field to given value. + +### HasPayloads + +`func (o *AgentPatchRequest) HasPayloads() bool` + +HasPayloads returns a boolean if a field has been set. + +### GetEnvironment + +`func (o *AgentPatchRequest) GetEnvironment() map[string]string` + +GetEnvironment returns the Environment field if non-nil, zero value otherwise. + +### GetEnvironmentOk + +`func (o *AgentPatchRequest) GetEnvironmentOk() (*map[string]string, bool)` + +GetEnvironmentOk returns a tuple with the Environment field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetEnvironment + +`func (o *AgentPatchRequest) SetEnvironment(v map[string]string)` + +SetEnvironment sets Environment field to given value. + +### HasEnvironment + +`func (o *AgentPatchRequest) HasEnvironment() bool` + +HasEnvironment returns a boolean if a field has been set. + +### GetSandboxTemplate + +`func (o *AgentPatchRequest) GetSandboxTemplate() SandboxTemplate` + +GetSandboxTemplate returns the SandboxTemplate field if non-nil, zero value otherwise. + +### GetSandboxTemplateOk + +`func (o *AgentPatchRequest) GetSandboxTemplateOk() (*SandboxTemplate, bool)` + +GetSandboxTemplateOk returns a tuple with the SandboxTemplate field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSandboxTemplate + +`func (o *AgentPatchRequest) SetSandboxTemplate(v SandboxTemplate)` + +SetSandboxTemplate sets SandboxTemplate field to given value. + +### HasSandboxTemplate + +`func (o *AgentPatchRequest) HasSandboxTemplate() bool` + +HasSandboxTemplate returns a boolean if a field has been set. + +### GetSandboxPolicy + +`func (o *AgentPatchRequest) GetSandboxPolicy() string` + +GetSandboxPolicy returns the SandboxPolicy field if non-nil, zero value otherwise. + +### GetSandboxPolicyOk + +`func (o *AgentPatchRequest) GetSandboxPolicyOk() (*string, bool)` + +GetSandboxPolicyOk returns a tuple with the SandboxPolicy field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSandboxPolicy + +`func (o *AgentPatchRequest) SetSandboxPolicy(v string)` + +SetSandboxPolicy sets SandboxPolicy field to given value. + +### HasSandboxPolicy + +`func (o *AgentPatchRequest) HasSandboxPolicy() bool` + +HasSandboxPolicy returns a boolean if a field has been set. + ### GetLabels `func (o *AgentPatchRequest) GetLabels() string` diff --git a/components/ambient-api-server/pkg/api/openapi/docs/GpuRequirements.md b/components/ambient-api-server/pkg/api/openapi/docs/GpuRequirements.md new file mode 100644 index 000000000..717a30a9e --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/docs/GpuRequirements.md @@ -0,0 +1,56 @@ +# GpuRequirements + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Count** | Pointer to **int32** | Number of GPUs to allocate. Default 0. | [optional] + +## Methods + +### NewGpuRequirements + +`func NewGpuRequirements() *GpuRequirements` + +NewGpuRequirements instantiates a new GpuRequirements object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewGpuRequirementsWithDefaults + +`func NewGpuRequirementsWithDefaults() *GpuRequirements` + +NewGpuRequirementsWithDefaults instantiates a new GpuRequirements object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetCount + +`func (o *GpuRequirements) GetCount() int32` + +GetCount returns the Count field if non-nil, zero value otherwise. + +### GetCountOk + +`func (o *GpuRequirements) GetCountOk() (*int32, bool)` + +GetCountOk returns a tuple with the Count field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCount + +`func (o *GpuRequirements) SetCount(v int32)` + +SetCount sets Count field to given value. + +### HasCount + +`func (o *GpuRequirements) HasCount() bool` + +HasCount returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/components/ambient-api-server/pkg/api/openapi/docs/Payload.md b/components/ambient-api-server/pkg/api/openapi/docs/Payload.md new file mode 100644 index 000000000..c661d7677 --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/docs/Payload.md @@ -0,0 +1,129 @@ +# Payload + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**SandboxPath** | **string** | Absolute path inside the sandbox where the content is delivered. | +**Content** | Pointer to **string** | Inline string content to place at the sandbox path. | [optional] +**RepoUrl** | Pointer to **string** | Git repository URL to clone into the sandbox path. | [optional] +**Ref** | Pointer to **string** | Git ref to check out (branch, tag, or commit SHA). Only valid with repo_url. | [optional] + +## Methods + +### NewPayload + +`func NewPayload(sandboxPath string, ) *Payload` + +NewPayload instantiates a new Payload object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewPayloadWithDefaults + +`func NewPayloadWithDefaults() *Payload` + +NewPayloadWithDefaults instantiates a new Payload object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetSandboxPath + +`func (o *Payload) GetSandboxPath() string` + +GetSandboxPath returns the SandboxPath field if non-nil, zero value otherwise. + +### GetSandboxPathOk + +`func (o *Payload) GetSandboxPathOk() (*string, bool)` + +GetSandboxPathOk returns a tuple with the SandboxPath field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSandboxPath + +`func (o *Payload) SetSandboxPath(v string)` + +SetSandboxPath sets SandboxPath field to given value. + + +### GetContent + +`func (o *Payload) GetContent() string` + +GetContent returns the Content field if non-nil, zero value otherwise. + +### GetContentOk + +`func (o *Payload) GetContentOk() (*string, bool)` + +GetContentOk returns a tuple with the Content field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetContent + +`func (o *Payload) SetContent(v string)` + +SetContent sets Content field to given value. + +### HasContent + +`func (o *Payload) HasContent() bool` + +HasContent returns a boolean if a field has been set. + +### GetRepoUrl + +`func (o *Payload) GetRepoUrl() string` + +GetRepoUrl returns the RepoUrl field if non-nil, zero value otherwise. + +### GetRepoUrlOk + +`func (o *Payload) GetRepoUrlOk() (*string, bool)` + +GetRepoUrlOk returns a tuple with the RepoUrl field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRepoUrl + +`func (o *Payload) SetRepoUrl(v string)` + +SetRepoUrl sets RepoUrl field to given value. + +### HasRepoUrl + +`func (o *Payload) HasRepoUrl() bool` + +HasRepoUrl returns a boolean if a field has been set. + +### GetRef + +`func (o *Payload) GetRef() string` + +GetRef returns the Ref field if non-nil, zero value otherwise. + +### GetRefOk + +`func (o *Payload) GetRefOk() (*string, bool)` + +GetRefOk returns a tuple with the Ref field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRef + +`func (o *Payload) SetRef(v string)` + +SetRef sets Ref field to given value. + +### HasRef + +`func (o *Payload) HasRef() bool` + +HasRef returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/components/ambient-api-server/pkg/api/openapi/docs/ResourceRequirements.md b/components/ambient-api-server/pkg/api/openapi/docs/ResourceRequirements.md new file mode 100644 index 000000000..a5af85aae --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/docs/ResourceRequirements.md @@ -0,0 +1,82 @@ +# ResourceRequirements + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Cpu** | Pointer to **string** | CPU request/limit in Kubernetes quantity format (e.g., \"2\", \"500m\"). | [optional] +**Memory** | Pointer to **string** | Memory request/limit in Kubernetes quantity format (e.g., \"4Gi\", \"256Mi\"). | [optional] + +## Methods + +### NewResourceRequirements + +`func NewResourceRequirements() *ResourceRequirements` + +NewResourceRequirements instantiates a new ResourceRequirements object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewResourceRequirementsWithDefaults + +`func NewResourceRequirementsWithDefaults() *ResourceRequirements` + +NewResourceRequirementsWithDefaults instantiates a new ResourceRequirements object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetCpu + +`func (o *ResourceRequirements) GetCpu() string` + +GetCpu returns the Cpu field if non-nil, zero value otherwise. + +### GetCpuOk + +`func (o *ResourceRequirements) GetCpuOk() (*string, bool)` + +GetCpuOk returns a tuple with the Cpu field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCpu + +`func (o *ResourceRequirements) SetCpu(v string)` + +SetCpu sets Cpu field to given value. + +### HasCpu + +`func (o *ResourceRequirements) HasCpu() bool` + +HasCpu returns a boolean if a field has been set. + +### GetMemory + +`func (o *ResourceRequirements) GetMemory() string` + +GetMemory returns the Memory field if non-nil, zero value otherwise. + +### GetMemoryOk + +`func (o *ResourceRequirements) GetMemoryOk() (*string, bool)` + +GetMemoryOk returns a tuple with the Memory field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetMemory + +`func (o *ResourceRequirements) SetMemory(v string)` + +SetMemory sets Memory field to given value. + +### HasMemory + +`func (o *ResourceRequirements) HasMemory() bool` + +HasMemory returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/components/ambient-api-server/pkg/api/openapi/docs/SandboxTemplate.md b/components/ambient-api-server/pkg/api/openapi/docs/SandboxTemplate.md new file mode 100644 index 000000000..8cbd15232 --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/docs/SandboxTemplate.md @@ -0,0 +1,238 @@ +# SandboxTemplate + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Image** | Pointer to **string** | OCI container image reference for the sandbox. | [optional] +**Resources** | Pointer to [**ResourceRequirements**](ResourceRequirements.md) | | [optional] +**Gpu** | Pointer to [**GpuRequirements**](GpuRequirements.md) | | [optional] +**RuntimeClassName** | Pointer to **string** | Kubernetes RuntimeClassName for the sandbox pod. | [optional] +**DriverConfig** | Pointer to **map[string]interface{}** | OpenShell driver-specific opaque configuration (JSON). | [optional] +**Labels** | Pointer to **map[string]string** | Labels applied to the sandbox compute resources. | [optional] +**Annotations** | Pointer to **map[string]string** | Annotations applied to the sandbox compute resources. | [optional] +**LogLevel** | Pointer to **string** | Sandbox supervisor log verbosity (debug, info, warn, error). | [optional] + +## Methods + +### NewSandboxTemplate + +`func NewSandboxTemplate() *SandboxTemplate` + +NewSandboxTemplate instantiates a new SandboxTemplate object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewSandboxTemplateWithDefaults + +`func NewSandboxTemplateWithDefaults() *SandboxTemplate` + +NewSandboxTemplateWithDefaults instantiates a new SandboxTemplate object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetImage + +`func (o *SandboxTemplate) GetImage() string` + +GetImage returns the Image field if non-nil, zero value otherwise. + +### GetImageOk + +`func (o *SandboxTemplate) GetImageOk() (*string, bool)` + +GetImageOk returns a tuple with the Image field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetImage + +`func (o *SandboxTemplate) SetImage(v string)` + +SetImage sets Image field to given value. + +### HasImage + +`func (o *SandboxTemplate) HasImage() bool` + +HasImage returns a boolean if a field has been set. + +### GetResources + +`func (o *SandboxTemplate) GetResources() ResourceRequirements` + +GetResources returns the Resources field if non-nil, zero value otherwise. + +### GetResourcesOk + +`func (o *SandboxTemplate) GetResourcesOk() (*ResourceRequirements, bool)` + +GetResourcesOk returns a tuple with the Resources field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetResources + +`func (o *SandboxTemplate) SetResources(v ResourceRequirements)` + +SetResources sets Resources field to given value. + +### HasResources + +`func (o *SandboxTemplate) HasResources() bool` + +HasResources returns a boolean if a field has been set. + +### GetGpu + +`func (o *SandboxTemplate) GetGpu() GpuRequirements` + +GetGpu returns the Gpu field if non-nil, zero value otherwise. + +### GetGpuOk + +`func (o *SandboxTemplate) GetGpuOk() (*GpuRequirements, bool)` + +GetGpuOk returns a tuple with the Gpu field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetGpu + +`func (o *SandboxTemplate) SetGpu(v GpuRequirements)` + +SetGpu sets Gpu field to given value. + +### HasGpu + +`func (o *SandboxTemplate) HasGpu() bool` + +HasGpu returns a boolean if a field has been set. + +### GetRuntimeClassName + +`func (o *SandboxTemplate) GetRuntimeClassName() string` + +GetRuntimeClassName returns the RuntimeClassName field if non-nil, zero value otherwise. + +### GetRuntimeClassNameOk + +`func (o *SandboxTemplate) GetRuntimeClassNameOk() (*string, bool)` + +GetRuntimeClassNameOk returns a tuple with the RuntimeClassName field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRuntimeClassName + +`func (o *SandboxTemplate) SetRuntimeClassName(v string)` + +SetRuntimeClassName sets RuntimeClassName field to given value. + +### HasRuntimeClassName + +`func (o *SandboxTemplate) HasRuntimeClassName() bool` + +HasRuntimeClassName returns a boolean if a field has been set. + +### GetDriverConfig + +`func (o *SandboxTemplate) GetDriverConfig() map[string]interface{}` + +GetDriverConfig returns the DriverConfig field if non-nil, zero value otherwise. + +### GetDriverConfigOk + +`func (o *SandboxTemplate) GetDriverConfigOk() (*map[string]interface{}, bool)` + +GetDriverConfigOk returns a tuple with the DriverConfig field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetDriverConfig + +`func (o *SandboxTemplate) SetDriverConfig(v map[string]interface{})` + +SetDriverConfig sets DriverConfig field to given value. + +### HasDriverConfig + +`func (o *SandboxTemplate) HasDriverConfig() bool` + +HasDriverConfig returns a boolean if a field has been set. + +### GetLabels + +`func (o *SandboxTemplate) GetLabels() map[string]string` + +GetLabels returns the Labels field if non-nil, zero value otherwise. + +### GetLabelsOk + +`func (o *SandboxTemplate) GetLabelsOk() (*map[string]string, bool)` + +GetLabelsOk returns a tuple with the Labels field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLabels + +`func (o *SandboxTemplate) SetLabels(v map[string]string)` + +SetLabels sets Labels field to given value. + +### HasLabels + +`func (o *SandboxTemplate) HasLabels() bool` + +HasLabels returns a boolean if a field has been set. + +### GetAnnotations + +`func (o *SandboxTemplate) GetAnnotations() map[string]string` + +GetAnnotations returns the Annotations field if non-nil, zero value otherwise. + +### GetAnnotationsOk + +`func (o *SandboxTemplate) GetAnnotationsOk() (*map[string]string, bool)` + +GetAnnotationsOk returns a tuple with the Annotations field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetAnnotations + +`func (o *SandboxTemplate) SetAnnotations(v map[string]string)` + +SetAnnotations sets Annotations field to given value. + +### HasAnnotations + +`func (o *SandboxTemplate) HasAnnotations() bool` + +HasAnnotations returns a boolean if a field has been set. + +### GetLogLevel + +`func (o *SandboxTemplate) GetLogLevel() string` + +GetLogLevel returns the LogLevel field if non-nil, zero value otherwise. + +### GetLogLevelOk + +`func (o *SandboxTemplate) GetLogLevelOk() (*string, bool)` + +GetLogLevelOk returns a tuple with the LogLevel field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLogLevel + +`func (o *SandboxTemplate) SetLogLevel(v string)` + +SetLogLevel sets LogLevel field to given value. + +### HasLogLevel + +`func (o *SandboxTemplate) HasLogLevel() bool` + +HasLogLevel returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/components/ambient-api-server/pkg/api/openapi/model_agent.go b/components/ambient-api-server/pkg/api/openapi/model_agent.go index 9497e3834..b26281c6c 100644 --- a/components/ambient-api-server/pkg/api/openapi/model_agent.go +++ b/components/ambient-api-server/pkg/api/openapi/model_agent.go @@ -45,6 +45,17 @@ type Agent struct { BotAccountName *string `json:"bot_account_name,omitempty"` ResourceOverrides *string `json:"resource_overrides,omitempty"` EnvironmentVariables *string `json:"environment_variables,omitempty"` + // CLI binary to launch inside the sandbox (e.g., claude, opencode, bash). Defaults to claude. + Entrypoint *string `json:"entrypoint,omitempty"` + // Names of providers this agent requires, referencing provider declarations in the tenant namespace. + Providers []string `json:"providers,omitempty"` + // Content to upload into the sandbox filesystem before the entrypoint launches. + Payloads []Payload `json:"payloads,omitempty"` + // Environment variables injected into the sandbox at creation time. + Environment *map[string]string `json:"environment,omitempty"` + SandboxTemplate *SandboxTemplate `json:"sandbox_template,omitempty"` + // Name of a policy declaration in the tenant namespace. When omitted, the platform default policy applies. + SandboxPolicy *string `json:"sandbox_policy,omitempty"` // Denormalized for fast reads — the active session, if any CurrentSessionId *string `json:"current_session_id,omitempty"` Labels *string `json:"labels,omitempty"` @@ -664,6 +675,198 @@ func (o *Agent) SetEnvironmentVariables(v string) { o.EnvironmentVariables = &v } +// GetEntrypoint returns the Entrypoint field value if set, zero value otherwise. +func (o *Agent) GetEntrypoint() string { + if o == nil || IsNil(o.Entrypoint) { + var ret string + return ret + } + return *o.Entrypoint +} + +// GetEntrypointOk returns a tuple with the Entrypoint field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Agent) GetEntrypointOk() (*string, bool) { + if o == nil || IsNil(o.Entrypoint) { + return nil, false + } + return o.Entrypoint, true +} + +// HasEntrypoint returns a boolean if a field has been set. +func (o *Agent) HasEntrypoint() bool { + if o != nil && !IsNil(o.Entrypoint) { + return true + } + + return false +} + +// SetEntrypoint gets a reference to the given string and assigns it to the Entrypoint field. +func (o *Agent) SetEntrypoint(v string) { + o.Entrypoint = &v +} + +// GetProviders returns the Providers field value if set, zero value otherwise. +func (o *Agent) GetProviders() []string { + if o == nil || IsNil(o.Providers) { + var ret []string + return ret + } + return o.Providers +} + +// GetProvidersOk returns a tuple with the Providers field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Agent) GetProvidersOk() ([]string, bool) { + if o == nil || IsNil(o.Providers) { + return nil, false + } + return o.Providers, true +} + +// HasProviders returns a boolean if a field has been set. +func (o *Agent) HasProviders() bool { + if o != nil && !IsNil(o.Providers) { + return true + } + + return false +} + +// SetProviders gets a reference to the given []string and assigns it to the Providers field. +func (o *Agent) SetProviders(v []string) { + o.Providers = v +} + +// GetPayloads returns the Payloads field value if set, zero value otherwise. +func (o *Agent) GetPayloads() []Payload { + if o == nil || IsNil(o.Payloads) { + var ret []Payload + return ret + } + return o.Payloads +} + +// GetPayloadsOk returns a tuple with the Payloads field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Agent) GetPayloadsOk() ([]Payload, bool) { + if o == nil || IsNil(o.Payloads) { + return nil, false + } + return o.Payloads, true +} + +// HasPayloads returns a boolean if a field has been set. +func (o *Agent) HasPayloads() bool { + if o != nil && !IsNil(o.Payloads) { + return true + } + + return false +} + +// SetPayloads gets a reference to the given []Payload and assigns it to the Payloads field. +func (o *Agent) SetPayloads(v []Payload) { + o.Payloads = v +} + +// GetEnvironment returns the Environment field value if set, zero value otherwise. +func (o *Agent) GetEnvironment() map[string]string { + if o == nil || IsNil(o.Environment) { + var ret map[string]string + return ret + } + return *o.Environment +} + +// GetEnvironmentOk returns a tuple with the Environment field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Agent) GetEnvironmentOk() (*map[string]string, bool) { + if o == nil || IsNil(o.Environment) { + return nil, false + } + return o.Environment, true +} + +// HasEnvironment returns a boolean if a field has been set. +func (o *Agent) HasEnvironment() bool { + if o != nil && !IsNil(o.Environment) { + return true + } + + return false +} + +// SetEnvironment gets a reference to the given map[string]string and assigns it to the Environment field. +func (o *Agent) SetEnvironment(v map[string]string) { + o.Environment = &v +} + +// GetSandboxTemplate returns the SandboxTemplate field value if set, zero value otherwise. +func (o *Agent) GetSandboxTemplate() SandboxTemplate { + if o == nil || IsNil(o.SandboxTemplate) { + var ret SandboxTemplate + return ret + } + return *o.SandboxTemplate +} + +// GetSandboxTemplateOk returns a tuple with the SandboxTemplate field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Agent) GetSandboxTemplateOk() (*SandboxTemplate, bool) { + if o == nil || IsNil(o.SandboxTemplate) { + return nil, false + } + return o.SandboxTemplate, true +} + +// HasSandboxTemplate returns a boolean if a field has been set. +func (o *Agent) HasSandboxTemplate() bool { + if o != nil && !IsNil(o.SandboxTemplate) { + return true + } + + return false +} + +// SetSandboxTemplate gets a reference to the given SandboxTemplate and assigns it to the SandboxTemplate field. +func (o *Agent) SetSandboxTemplate(v SandboxTemplate) { + o.SandboxTemplate = &v +} + +// GetSandboxPolicy returns the SandboxPolicy field value if set, zero value otherwise. +func (o *Agent) GetSandboxPolicy() string { + if o == nil || IsNil(o.SandboxPolicy) { + var ret string + return ret + } + return *o.SandboxPolicy +} + +// GetSandboxPolicyOk returns a tuple with the SandboxPolicy field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Agent) GetSandboxPolicyOk() (*string, bool) { + if o == nil || IsNil(o.SandboxPolicy) { + return nil, false + } + return o.SandboxPolicy, true +} + +// HasSandboxPolicy returns a boolean if a field has been set. +func (o *Agent) HasSandboxPolicy() bool { + if o != nil && !IsNil(o.SandboxPolicy) { + return true + } + + return false +} + +// SetSandboxPolicy gets a reference to the given string and assigns it to the SandboxPolicy field. +func (o *Agent) SetSandboxPolicy(v string) { + o.SandboxPolicy = &v +} + // GetCurrentSessionId returns the CurrentSessionId field value if set, zero value otherwise. func (o *Agent) GetCurrentSessionId() string { if o == nil || IsNil(o.CurrentSessionId) { @@ -823,6 +1026,24 @@ func (o Agent) ToMap() (map[string]interface{}, error) { if !IsNil(o.EnvironmentVariables) { toSerialize["environment_variables"] = o.EnvironmentVariables } + if !IsNil(o.Entrypoint) { + toSerialize["entrypoint"] = o.Entrypoint + } + if !IsNil(o.Providers) { + toSerialize["providers"] = o.Providers + } + if !IsNil(o.Payloads) { + toSerialize["payloads"] = o.Payloads + } + if !IsNil(o.Environment) { + toSerialize["environment"] = o.Environment + } + if !IsNil(o.SandboxTemplate) { + toSerialize["sandbox_template"] = o.SandboxTemplate + } + if !IsNil(o.SandboxPolicy) { + toSerialize["sandbox_policy"] = o.SandboxPolicy + } if !IsNil(o.CurrentSessionId) { toSerialize["current_session_id"] = o.CurrentSessionId } diff --git a/components/ambient-api-server/pkg/api/openapi/model_agent_patch_request.go b/components/ambient-api-server/pkg/api/openapi/model_agent_patch_request.go index 1677e5985..58966f422 100644 --- a/components/ambient-api-server/pkg/api/openapi/model_agent_patch_request.go +++ b/components/ambient-api-server/pkg/api/openapi/model_agent_patch_request.go @@ -24,13 +24,19 @@ type AgentPatchRequest struct { DisplayName *string `json:"display_name,omitempty"` Description *string `json:"description,omitempty"` // Update agent prompt (access controlled by RBAC) - Prompt *string `json:"prompt,omitempty"` - RepoUrl *string `json:"repo_url,omitempty"` - LlmModel *string `json:"llm_model,omitempty"` - LlmTemperature *float64 `json:"llm_temperature,omitempty"` - LlmMaxTokens *int32 `json:"llm_max_tokens,omitempty"` - Labels *string `json:"labels,omitempty"` - Annotations *string `json:"annotations,omitempty"` + Prompt *string `json:"prompt,omitempty"` + RepoUrl *string `json:"repo_url,omitempty"` + LlmModel *string `json:"llm_model,omitempty"` + LlmTemperature *float64 `json:"llm_temperature,omitempty"` + LlmMaxTokens *int32 `json:"llm_max_tokens,omitempty"` + Entrypoint *string `json:"entrypoint,omitempty"` + Providers []string `json:"providers,omitempty"` + Payloads []Payload `json:"payloads,omitempty"` + Environment *map[string]string `json:"environment,omitempty"` + SandboxTemplate *SandboxTemplate `json:"sandbox_template,omitempty"` + SandboxPolicy *string `json:"sandbox_policy,omitempty"` + Labels *string `json:"labels,omitempty"` + Annotations *string `json:"annotations,omitempty"` } // NewAgentPatchRequest instantiates a new AgentPatchRequest object @@ -306,6 +312,198 @@ func (o *AgentPatchRequest) SetLlmMaxTokens(v int32) { o.LlmMaxTokens = &v } +// GetEntrypoint returns the Entrypoint field value if set, zero value otherwise. +func (o *AgentPatchRequest) GetEntrypoint() string { + if o == nil || IsNil(o.Entrypoint) { + var ret string + return ret + } + return *o.Entrypoint +} + +// GetEntrypointOk returns a tuple with the Entrypoint field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *AgentPatchRequest) GetEntrypointOk() (*string, bool) { + if o == nil || IsNil(o.Entrypoint) { + return nil, false + } + return o.Entrypoint, true +} + +// HasEntrypoint returns a boolean if a field has been set. +func (o *AgentPatchRequest) HasEntrypoint() bool { + if o != nil && !IsNil(o.Entrypoint) { + return true + } + + return false +} + +// SetEntrypoint gets a reference to the given string and assigns it to the Entrypoint field. +func (o *AgentPatchRequest) SetEntrypoint(v string) { + o.Entrypoint = &v +} + +// GetProviders returns the Providers field value if set, zero value otherwise. +func (o *AgentPatchRequest) GetProviders() []string { + if o == nil || IsNil(o.Providers) { + var ret []string + return ret + } + return o.Providers +} + +// GetProvidersOk returns a tuple with the Providers field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *AgentPatchRequest) GetProvidersOk() ([]string, bool) { + if o == nil || IsNil(o.Providers) { + return nil, false + } + return o.Providers, true +} + +// HasProviders returns a boolean if a field has been set. +func (o *AgentPatchRequest) HasProviders() bool { + if o != nil && !IsNil(o.Providers) { + return true + } + + return false +} + +// SetProviders gets a reference to the given []string and assigns it to the Providers field. +func (o *AgentPatchRequest) SetProviders(v []string) { + o.Providers = v +} + +// GetPayloads returns the Payloads field value if set, zero value otherwise. +func (o *AgentPatchRequest) GetPayloads() []Payload { + if o == nil || IsNil(o.Payloads) { + var ret []Payload + return ret + } + return o.Payloads +} + +// GetPayloadsOk returns a tuple with the Payloads field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *AgentPatchRequest) GetPayloadsOk() ([]Payload, bool) { + if o == nil || IsNil(o.Payloads) { + return nil, false + } + return o.Payloads, true +} + +// HasPayloads returns a boolean if a field has been set. +func (o *AgentPatchRequest) HasPayloads() bool { + if o != nil && !IsNil(o.Payloads) { + return true + } + + return false +} + +// SetPayloads gets a reference to the given []Payload and assigns it to the Payloads field. +func (o *AgentPatchRequest) SetPayloads(v []Payload) { + o.Payloads = v +} + +// GetEnvironment returns the Environment field value if set, zero value otherwise. +func (o *AgentPatchRequest) GetEnvironment() map[string]string { + if o == nil || IsNil(o.Environment) { + var ret map[string]string + return ret + } + return *o.Environment +} + +// GetEnvironmentOk returns a tuple with the Environment field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *AgentPatchRequest) GetEnvironmentOk() (*map[string]string, bool) { + if o == nil || IsNil(o.Environment) { + return nil, false + } + return o.Environment, true +} + +// HasEnvironment returns a boolean if a field has been set. +func (o *AgentPatchRequest) HasEnvironment() bool { + if o != nil && !IsNil(o.Environment) { + return true + } + + return false +} + +// SetEnvironment gets a reference to the given map[string]string and assigns it to the Environment field. +func (o *AgentPatchRequest) SetEnvironment(v map[string]string) { + o.Environment = &v +} + +// GetSandboxTemplate returns the SandboxTemplate field value if set, zero value otherwise. +func (o *AgentPatchRequest) GetSandboxTemplate() SandboxTemplate { + if o == nil || IsNil(o.SandboxTemplate) { + var ret SandboxTemplate + return ret + } + return *o.SandboxTemplate +} + +// GetSandboxTemplateOk returns a tuple with the SandboxTemplate field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *AgentPatchRequest) GetSandboxTemplateOk() (*SandboxTemplate, bool) { + if o == nil || IsNil(o.SandboxTemplate) { + return nil, false + } + return o.SandboxTemplate, true +} + +// HasSandboxTemplate returns a boolean if a field has been set. +func (o *AgentPatchRequest) HasSandboxTemplate() bool { + if o != nil && !IsNil(o.SandboxTemplate) { + return true + } + + return false +} + +// SetSandboxTemplate gets a reference to the given SandboxTemplate and assigns it to the SandboxTemplate field. +func (o *AgentPatchRequest) SetSandboxTemplate(v SandboxTemplate) { + o.SandboxTemplate = &v +} + +// GetSandboxPolicy returns the SandboxPolicy field value if set, zero value otherwise. +func (o *AgentPatchRequest) GetSandboxPolicy() string { + if o == nil || IsNil(o.SandboxPolicy) { + var ret string + return ret + } + return *o.SandboxPolicy +} + +// GetSandboxPolicyOk returns a tuple with the SandboxPolicy field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *AgentPatchRequest) GetSandboxPolicyOk() (*string, bool) { + if o == nil || IsNil(o.SandboxPolicy) { + return nil, false + } + return o.SandboxPolicy, true +} + +// HasSandboxPolicy returns a boolean if a field has been set. +func (o *AgentPatchRequest) HasSandboxPolicy() bool { + if o != nil && !IsNil(o.SandboxPolicy) { + return true + } + + return false +} + +// SetSandboxPolicy gets a reference to the given string and assigns it to the SandboxPolicy field. +func (o *AgentPatchRequest) SetSandboxPolicy(v string) { + o.SandboxPolicy = &v +} + // GetLabels returns the Labels field value if set, zero value otherwise. func (o *AgentPatchRequest) GetLabels() string { if o == nil || IsNil(o.Labels) { @@ -404,6 +602,24 @@ func (o AgentPatchRequest) ToMap() (map[string]interface{}, error) { if !IsNil(o.LlmMaxTokens) { toSerialize["llm_max_tokens"] = o.LlmMaxTokens } + if !IsNil(o.Entrypoint) { + toSerialize["entrypoint"] = o.Entrypoint + } + if !IsNil(o.Providers) { + toSerialize["providers"] = o.Providers + } + if !IsNil(o.Payloads) { + toSerialize["payloads"] = o.Payloads + } + if !IsNil(o.Environment) { + toSerialize["environment"] = o.Environment + } + if !IsNil(o.SandboxTemplate) { + toSerialize["sandbox_template"] = o.SandboxTemplate + } + if !IsNil(o.SandboxPolicy) { + toSerialize["sandbox_policy"] = o.SandboxPolicy + } if !IsNil(o.Labels) { toSerialize["labels"] = o.Labels } diff --git a/components/ambient-api-server/pkg/api/openapi/model_gpu_requirements.go b/components/ambient-api-server/pkg/api/openapi/model_gpu_requirements.go new file mode 100644 index 000000000..3c9496d24 --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/model_gpu_requirements.go @@ -0,0 +1,126 @@ +/* +Ambient API Server + +Ambient API Server + +API version: 1.0.0 +Contact: ambient-code@redhat.com +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the GpuRequirements type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &GpuRequirements{} + +// GpuRequirements struct for GpuRequirements +type GpuRequirements struct { + // Number of GPUs to allocate. Default 0. + Count *int32 `json:"count,omitempty"` +} + +// NewGpuRequirements instantiates a new GpuRequirements object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewGpuRequirements() *GpuRequirements { + this := GpuRequirements{} + return &this +} + +// NewGpuRequirementsWithDefaults instantiates a new GpuRequirements object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewGpuRequirementsWithDefaults() *GpuRequirements { + this := GpuRequirements{} + return &this +} + +// GetCount returns the Count field value if set, zero value otherwise. +func (o *GpuRequirements) GetCount() int32 { + if o == nil || IsNil(o.Count) { + var ret int32 + return ret + } + return *o.Count +} + +// GetCountOk returns a tuple with the Count field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *GpuRequirements) GetCountOk() (*int32, bool) { + if o == nil || IsNil(o.Count) { + return nil, false + } + return o.Count, true +} + +// HasCount returns a boolean if a field has been set. +func (o *GpuRequirements) HasCount() bool { + if o != nil && !IsNil(o.Count) { + return true + } + + return false +} + +// SetCount gets a reference to the given int32 and assigns it to the Count field. +func (o *GpuRequirements) SetCount(v int32) { + o.Count = &v +} + +func (o GpuRequirements) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o GpuRequirements) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Count) { + toSerialize["count"] = o.Count + } + return toSerialize, nil +} + +type NullableGpuRequirements struct { + value *GpuRequirements + isSet bool +} + +func (v NullableGpuRequirements) Get() *GpuRequirements { + return v.value +} + +func (v *NullableGpuRequirements) Set(val *GpuRequirements) { + v.value = val + v.isSet = true +} + +func (v NullableGpuRequirements) IsSet() bool { + return v.isSet +} + +func (v *NullableGpuRequirements) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableGpuRequirements(val *GpuRequirements) *NullableGpuRequirements { + return &NullableGpuRequirements{value: val, isSet: true} +} + +func (v NullableGpuRequirements) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableGpuRequirements) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/components/ambient-api-server/pkg/api/openapi/model_payload.go b/components/ambient-api-server/pkg/api/openapi/model_payload.go new file mode 100644 index 000000000..d57033fd6 --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/model_payload.go @@ -0,0 +1,269 @@ +/* +Ambient API Server + +Ambient API Server + +API version: 1.0.0 +Contact: ambient-code@redhat.com +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the Payload type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &Payload{} + +// Payload struct for Payload +type Payload struct { + // Absolute path inside the sandbox where the content is delivered. + SandboxPath string `json:"sandbox_path"` + // Inline string content to place at the sandbox path. + Content *string `json:"content,omitempty"` + // Git repository URL to clone into the sandbox path. + RepoUrl *string `json:"repo_url,omitempty"` + // Git ref to check out (branch, tag, or commit SHA). Only valid with repo_url. + Ref *string `json:"ref,omitempty"` +} + +type _Payload Payload + +// NewPayload instantiates a new Payload object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewPayload(sandboxPath string) *Payload { + this := Payload{} + this.SandboxPath = sandboxPath + return &this +} + +// NewPayloadWithDefaults instantiates a new Payload object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewPayloadWithDefaults() *Payload { + this := Payload{} + return &this +} + +// GetSandboxPath returns the SandboxPath field value +func (o *Payload) GetSandboxPath() string { + if o == nil { + var ret string + return ret + } + + return o.SandboxPath +} + +// GetSandboxPathOk returns a tuple with the SandboxPath field value +// and a boolean to check if the value has been set. +func (o *Payload) GetSandboxPathOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.SandboxPath, true +} + +// SetSandboxPath sets field value +func (o *Payload) SetSandboxPath(v string) { + o.SandboxPath = v +} + +// GetContent returns the Content field value if set, zero value otherwise. +func (o *Payload) GetContent() string { + if o == nil || IsNil(o.Content) { + var ret string + return ret + } + return *o.Content +} + +// GetContentOk returns a tuple with the Content field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Payload) GetContentOk() (*string, bool) { + if o == nil || IsNil(o.Content) { + return nil, false + } + return o.Content, true +} + +// HasContent returns a boolean if a field has been set. +func (o *Payload) HasContent() bool { + if o != nil && !IsNil(o.Content) { + return true + } + + return false +} + +// SetContent gets a reference to the given string and assigns it to the Content field. +func (o *Payload) SetContent(v string) { + o.Content = &v +} + +// GetRepoUrl returns the RepoUrl field value if set, zero value otherwise. +func (o *Payload) GetRepoUrl() string { + if o == nil || IsNil(o.RepoUrl) { + var ret string + return ret + } + return *o.RepoUrl +} + +// GetRepoUrlOk returns a tuple with the RepoUrl field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Payload) GetRepoUrlOk() (*string, bool) { + if o == nil || IsNil(o.RepoUrl) { + return nil, false + } + return o.RepoUrl, true +} + +// HasRepoUrl returns a boolean if a field has been set. +func (o *Payload) HasRepoUrl() bool { + if o != nil && !IsNil(o.RepoUrl) { + return true + } + + return false +} + +// SetRepoUrl gets a reference to the given string and assigns it to the RepoUrl field. +func (o *Payload) SetRepoUrl(v string) { + o.RepoUrl = &v +} + +// GetRef returns the Ref field value if set, zero value otherwise. +func (o *Payload) GetRef() string { + if o == nil || IsNil(o.Ref) { + var ret string + return ret + } + return *o.Ref +} + +// GetRefOk returns a tuple with the Ref field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Payload) GetRefOk() (*string, bool) { + if o == nil || IsNil(o.Ref) { + return nil, false + } + return o.Ref, true +} + +// HasRef returns a boolean if a field has been set. +func (o *Payload) HasRef() bool { + if o != nil && !IsNil(o.Ref) { + return true + } + + return false +} + +// SetRef gets a reference to the given string and assigns it to the Ref field. +func (o *Payload) SetRef(v string) { + o.Ref = &v +} + +func (o Payload) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o Payload) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["sandbox_path"] = o.SandboxPath + if !IsNil(o.Content) { + toSerialize["content"] = o.Content + } + if !IsNil(o.RepoUrl) { + toSerialize["repo_url"] = o.RepoUrl + } + if !IsNil(o.Ref) { + toSerialize["ref"] = o.Ref + } + return toSerialize, nil +} + +func (o *Payload) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "sandbox_path", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varPayload := _Payload{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varPayload) + + if err != nil { + return err + } + + *o = Payload(varPayload) + + return err +} + +type NullablePayload struct { + value *Payload + isSet bool +} + +func (v NullablePayload) Get() *Payload { + return v.value +} + +func (v *NullablePayload) Set(val *Payload) { + v.value = val + v.isSet = true +} + +func (v NullablePayload) IsSet() bool { + return v.isSet +} + +func (v *NullablePayload) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullablePayload(val *Payload) *NullablePayload { + return &NullablePayload{value: val, isSet: true} +} + +func (v NullablePayload) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullablePayload) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/components/ambient-api-server/pkg/api/openapi/model_resource_requirements.go b/components/ambient-api-server/pkg/api/openapi/model_resource_requirements.go new file mode 100644 index 000000000..f24424dbf --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/model_resource_requirements.go @@ -0,0 +1,163 @@ +/* +Ambient API Server + +Ambient API Server + +API version: 1.0.0 +Contact: ambient-code@redhat.com +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ResourceRequirements type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ResourceRequirements{} + +// ResourceRequirements struct for ResourceRequirements +type ResourceRequirements struct { + // CPU request/limit in Kubernetes quantity format (e.g., \"2\", \"500m\"). + Cpu *string `json:"cpu,omitempty"` + // Memory request/limit in Kubernetes quantity format (e.g., \"4Gi\", \"256Mi\"). + Memory *string `json:"memory,omitempty"` +} + +// NewResourceRequirements instantiates a new ResourceRequirements object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewResourceRequirements() *ResourceRequirements { + this := ResourceRequirements{} + return &this +} + +// NewResourceRequirementsWithDefaults instantiates a new ResourceRequirements object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewResourceRequirementsWithDefaults() *ResourceRequirements { + this := ResourceRequirements{} + return &this +} + +// GetCpu returns the Cpu field value if set, zero value otherwise. +func (o *ResourceRequirements) GetCpu() string { + if o == nil || IsNil(o.Cpu) { + var ret string + return ret + } + return *o.Cpu +} + +// GetCpuOk returns a tuple with the Cpu field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ResourceRequirements) GetCpuOk() (*string, bool) { + if o == nil || IsNil(o.Cpu) { + return nil, false + } + return o.Cpu, true +} + +// HasCpu returns a boolean if a field has been set. +func (o *ResourceRequirements) HasCpu() bool { + if o != nil && !IsNil(o.Cpu) { + return true + } + + return false +} + +// SetCpu gets a reference to the given string and assigns it to the Cpu field. +func (o *ResourceRequirements) SetCpu(v string) { + o.Cpu = &v +} + +// GetMemory returns the Memory field value if set, zero value otherwise. +func (o *ResourceRequirements) GetMemory() string { + if o == nil || IsNil(o.Memory) { + var ret string + return ret + } + return *o.Memory +} + +// GetMemoryOk returns a tuple with the Memory field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ResourceRequirements) GetMemoryOk() (*string, bool) { + if o == nil || IsNil(o.Memory) { + return nil, false + } + return o.Memory, true +} + +// HasMemory returns a boolean if a field has been set. +func (o *ResourceRequirements) HasMemory() bool { + if o != nil && !IsNil(o.Memory) { + return true + } + + return false +} + +// SetMemory gets a reference to the given string and assigns it to the Memory field. +func (o *ResourceRequirements) SetMemory(v string) { + o.Memory = &v +} + +func (o ResourceRequirements) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ResourceRequirements) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Cpu) { + toSerialize["cpu"] = o.Cpu + } + if !IsNil(o.Memory) { + toSerialize["memory"] = o.Memory + } + return toSerialize, nil +} + +type NullableResourceRequirements struct { + value *ResourceRequirements + isSet bool +} + +func (v NullableResourceRequirements) Get() *ResourceRequirements { + return v.value +} + +func (v *NullableResourceRequirements) Set(val *ResourceRequirements) { + v.value = val + v.isSet = true +} + +func (v NullableResourceRequirements) IsSet() bool { + return v.isSet +} + +func (v *NullableResourceRequirements) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableResourceRequirements(val *ResourceRequirements) *NullableResourceRequirements { + return &NullableResourceRequirements{value: val, isSet: true} +} + +func (v NullableResourceRequirements) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableResourceRequirements) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/components/ambient-api-server/pkg/api/openapi/model_sandbox_template.go b/components/ambient-api-server/pkg/api/openapi/model_sandbox_template.go new file mode 100644 index 000000000..7e17adbf0 --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/model_sandbox_template.go @@ -0,0 +1,383 @@ +/* +Ambient API Server + +Ambient API Server + +API version: 1.0.0 +Contact: ambient-code@redhat.com +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the SandboxTemplate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &SandboxTemplate{} + +// SandboxTemplate struct for SandboxTemplate +type SandboxTemplate struct { + // OCI container image reference for the sandbox. + Image *string `json:"image,omitempty"` + Resources *ResourceRequirements `json:"resources,omitempty"` + Gpu *GpuRequirements `json:"gpu,omitempty"` + // Kubernetes RuntimeClassName for the sandbox pod. + RuntimeClassName *string `json:"runtime_class_name,omitempty"` + // OpenShell driver-specific opaque configuration (JSON). + DriverConfig map[string]interface{} `json:"driver_config,omitempty"` + // Labels applied to the sandbox compute resources. + Labels *map[string]string `json:"labels,omitempty"` + // Annotations applied to the sandbox compute resources. + Annotations *map[string]string `json:"annotations,omitempty"` + // Sandbox supervisor log verbosity (debug, info, warn, error). + LogLevel *string `json:"log_level,omitempty"` +} + +// NewSandboxTemplate instantiates a new SandboxTemplate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewSandboxTemplate() *SandboxTemplate { + this := SandboxTemplate{} + return &this +} + +// NewSandboxTemplateWithDefaults instantiates a new SandboxTemplate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewSandboxTemplateWithDefaults() *SandboxTemplate { + this := SandboxTemplate{} + return &this +} + +// GetImage returns the Image field value if set, zero value otherwise. +func (o *SandboxTemplate) GetImage() string { + if o == nil || IsNil(o.Image) { + var ret string + return ret + } + return *o.Image +} + +// GetImageOk returns a tuple with the Image field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *SandboxTemplate) GetImageOk() (*string, bool) { + if o == nil || IsNil(o.Image) { + return nil, false + } + return o.Image, true +} + +// HasImage returns a boolean if a field has been set. +func (o *SandboxTemplate) HasImage() bool { + if o != nil && !IsNil(o.Image) { + return true + } + + return false +} + +// SetImage gets a reference to the given string and assigns it to the Image field. +func (o *SandboxTemplate) SetImage(v string) { + o.Image = &v +} + +// GetResources returns the Resources field value if set, zero value otherwise. +func (o *SandboxTemplate) GetResources() ResourceRequirements { + if o == nil || IsNil(o.Resources) { + var ret ResourceRequirements + return ret + } + return *o.Resources +} + +// GetResourcesOk returns a tuple with the Resources field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *SandboxTemplate) GetResourcesOk() (*ResourceRequirements, bool) { + if o == nil || IsNil(o.Resources) { + return nil, false + } + return o.Resources, true +} + +// HasResources returns a boolean if a field has been set. +func (o *SandboxTemplate) HasResources() bool { + if o != nil && !IsNil(o.Resources) { + return true + } + + return false +} + +// SetResources gets a reference to the given ResourceRequirements and assigns it to the Resources field. +func (o *SandboxTemplate) SetResources(v ResourceRequirements) { + o.Resources = &v +} + +// GetGpu returns the Gpu field value if set, zero value otherwise. +func (o *SandboxTemplate) GetGpu() GpuRequirements { + if o == nil || IsNil(o.Gpu) { + var ret GpuRequirements + return ret + } + return *o.Gpu +} + +// GetGpuOk returns a tuple with the Gpu field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *SandboxTemplate) GetGpuOk() (*GpuRequirements, bool) { + if o == nil || IsNil(o.Gpu) { + return nil, false + } + return o.Gpu, true +} + +// HasGpu returns a boolean if a field has been set. +func (o *SandboxTemplate) HasGpu() bool { + if o != nil && !IsNil(o.Gpu) { + return true + } + + return false +} + +// SetGpu gets a reference to the given GpuRequirements and assigns it to the Gpu field. +func (o *SandboxTemplate) SetGpu(v GpuRequirements) { + o.Gpu = &v +} + +// GetRuntimeClassName returns the RuntimeClassName field value if set, zero value otherwise. +func (o *SandboxTemplate) GetRuntimeClassName() string { + if o == nil || IsNil(o.RuntimeClassName) { + var ret string + return ret + } + return *o.RuntimeClassName +} + +// GetRuntimeClassNameOk returns a tuple with the RuntimeClassName field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *SandboxTemplate) GetRuntimeClassNameOk() (*string, bool) { + if o == nil || IsNil(o.RuntimeClassName) { + return nil, false + } + return o.RuntimeClassName, true +} + +// HasRuntimeClassName returns a boolean if a field has been set. +func (o *SandboxTemplate) HasRuntimeClassName() bool { + if o != nil && !IsNil(o.RuntimeClassName) { + return true + } + + return false +} + +// SetRuntimeClassName gets a reference to the given string and assigns it to the RuntimeClassName field. +func (o *SandboxTemplate) SetRuntimeClassName(v string) { + o.RuntimeClassName = &v +} + +// GetDriverConfig returns the DriverConfig field value if set, zero value otherwise. +func (o *SandboxTemplate) GetDriverConfig() map[string]interface{} { + if o == nil || IsNil(o.DriverConfig) { + var ret map[string]interface{} + return ret + } + return o.DriverConfig +} + +// GetDriverConfigOk returns a tuple with the DriverConfig field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *SandboxTemplate) GetDriverConfigOk() (map[string]interface{}, bool) { + if o == nil || IsNil(o.DriverConfig) { + return map[string]interface{}{}, false + } + return o.DriverConfig, true +} + +// HasDriverConfig returns a boolean if a field has been set. +func (o *SandboxTemplate) HasDriverConfig() bool { + if o != nil && !IsNil(o.DriverConfig) { + return true + } + + return false +} + +// SetDriverConfig gets a reference to the given map[string]interface{} and assigns it to the DriverConfig field. +func (o *SandboxTemplate) SetDriverConfig(v map[string]interface{}) { + o.DriverConfig = v +} + +// GetLabels returns the Labels field value if set, zero value otherwise. +func (o *SandboxTemplate) GetLabels() map[string]string { + if o == nil || IsNil(o.Labels) { + var ret map[string]string + return ret + } + return *o.Labels +} + +// GetLabelsOk returns a tuple with the Labels field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *SandboxTemplate) GetLabelsOk() (*map[string]string, bool) { + if o == nil || IsNil(o.Labels) { + return nil, false + } + return o.Labels, true +} + +// HasLabels returns a boolean if a field has been set. +func (o *SandboxTemplate) HasLabels() bool { + if o != nil && !IsNil(o.Labels) { + return true + } + + return false +} + +// SetLabels gets a reference to the given map[string]string and assigns it to the Labels field. +func (o *SandboxTemplate) SetLabels(v map[string]string) { + o.Labels = &v +} + +// GetAnnotations returns the Annotations field value if set, zero value otherwise. +func (o *SandboxTemplate) GetAnnotations() map[string]string { + if o == nil || IsNil(o.Annotations) { + var ret map[string]string + return ret + } + return *o.Annotations +} + +// GetAnnotationsOk returns a tuple with the Annotations field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *SandboxTemplate) GetAnnotationsOk() (*map[string]string, bool) { + if o == nil || IsNil(o.Annotations) { + return nil, false + } + return o.Annotations, true +} + +// HasAnnotations returns a boolean if a field has been set. +func (o *SandboxTemplate) HasAnnotations() bool { + if o != nil && !IsNil(o.Annotations) { + return true + } + + return false +} + +// SetAnnotations gets a reference to the given map[string]string and assigns it to the Annotations field. +func (o *SandboxTemplate) SetAnnotations(v map[string]string) { + o.Annotations = &v +} + +// GetLogLevel returns the LogLevel field value if set, zero value otherwise. +func (o *SandboxTemplate) GetLogLevel() string { + if o == nil || IsNil(o.LogLevel) { + var ret string + return ret + } + return *o.LogLevel +} + +// GetLogLevelOk returns a tuple with the LogLevel field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *SandboxTemplate) GetLogLevelOk() (*string, bool) { + if o == nil || IsNil(o.LogLevel) { + return nil, false + } + return o.LogLevel, true +} + +// HasLogLevel returns a boolean if a field has been set. +func (o *SandboxTemplate) HasLogLevel() bool { + if o != nil && !IsNil(o.LogLevel) { + return true + } + + return false +} + +// SetLogLevel gets a reference to the given string and assigns it to the LogLevel field. +func (o *SandboxTemplate) SetLogLevel(v string) { + o.LogLevel = &v +} + +func (o SandboxTemplate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o SandboxTemplate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Image) { + toSerialize["image"] = o.Image + } + if !IsNil(o.Resources) { + toSerialize["resources"] = o.Resources + } + if !IsNil(o.Gpu) { + toSerialize["gpu"] = o.Gpu + } + if !IsNil(o.RuntimeClassName) { + toSerialize["runtime_class_name"] = o.RuntimeClassName + } + if !IsNil(o.DriverConfig) { + toSerialize["driver_config"] = o.DriverConfig + } + if !IsNil(o.Labels) { + toSerialize["labels"] = o.Labels + } + if !IsNil(o.Annotations) { + toSerialize["annotations"] = o.Annotations + } + if !IsNil(o.LogLevel) { + toSerialize["log_level"] = o.LogLevel + } + return toSerialize, nil +} + +type NullableSandboxTemplate struct { + value *SandboxTemplate + isSet bool +} + +func (v NullableSandboxTemplate) Get() *SandboxTemplate { + return v.value +} + +func (v *NullableSandboxTemplate) Set(val *SandboxTemplate) { + v.value = val + v.isSet = true +} + +func (v NullableSandboxTemplate) IsSet() bool { + return v.isSet +} + +func (v *NullableSandboxTemplate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableSandboxTemplate(val *SandboxTemplate) *NullableSandboxTemplate { + return &NullableSandboxTemplate{value: val, isSet: true} +} + +func (v NullableSandboxTemplate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableSandboxTemplate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/components/ambient-api-server/plugins/agents/handler.go b/components/ambient-api-server/plugins/agents/handler.go index bc5332f8d..f1eb8d270 100644 --- a/components/ambient-api-server/plugins/agents/handler.go +++ b/components/ambient-api-server/plugins/agents/handler.go @@ -1,6 +1,7 @@ package agents import ( + "encoding/json" "net/http" "regexp" @@ -95,6 +96,36 @@ func (h agentHandler) Patch(w http.ResponseWriter, r *http.Request) { if patch.LlmMaxTokens != nil { found.LlmMaxTokens = *patch.LlmMaxTokens } + if patch.Entrypoint != nil { + found.Entrypoint = patch.Entrypoint + } + if patch.Providers != nil { + if raw, merr := json.Marshal(patch.Providers); merr == nil { + s := string(raw) + found.Providers = &s + } + } + if patch.Payloads != nil { + if raw, merr := json.Marshal(patch.Payloads); merr == nil { + s := string(raw) + found.Payloads = &s + } + } + if patch.Environment != nil { + if raw, merr := json.Marshal(patch.Environment); merr == nil { + s := string(raw) + found.Environment = &s + } + } + if patch.SandboxTemplate != nil { + if raw, merr := json.Marshal(patch.SandboxTemplate); merr == nil { + s := string(raw) + found.SandboxTemplate = &s + } + } + if patch.SandboxPolicy != nil { + found.SandboxPolicy = patch.SandboxPolicy + } if patch.Labels != nil { found.Labels = patch.Labels } diff --git a/components/ambient-api-server/plugins/agents/migration.go b/components/ambient-api-server/plugins/agents/migration.go index 6acbc87bd..d2babbfab 100644 --- a/components/ambient-api-server/plugins/agents/migration.go +++ b/components/ambient-api-server/plugins/agents/migration.go @@ -101,3 +101,37 @@ func dropParentAgentIdMigration() *gormigrate.Migration { }, } } + +func sandboxConfigMigration() *gormigrate.Migration { + return &gormigrate.Migration{ + ID: "202606291000", + Migrate: func(tx *gorm.DB) error { + stmts := []string{ + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS entrypoint TEXT`, + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS providers JSONB`, + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS payloads JSONB`, + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS environment JSONB`, + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS sandbox_template JSONB`, + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS sandbox_policy TEXT`, + } + for _, s := range stmts { + if err := tx.Exec(s).Error; err != nil { + return err + } + } + return nil + }, + Rollback: func(tx *gorm.DB) error { + cols := []string{ + "entrypoint", "providers", "payloads", + "environment", "sandbox_template", "sandbox_policy", + } + for _, col := range cols { + if err := tx.Exec("ALTER TABLE agents DROP COLUMN IF EXISTS " + col).Error; err != nil { + return err + } + } + return nil + }, + } +} diff --git a/components/ambient-api-server/plugins/agents/model.go b/components/ambient-api-server/plugins/agents/model.go index bbd5150c1..f7a0bc80c 100755 --- a/components/ambient-api-server/plugins/agents/model.go +++ b/components/ambient-api-server/plugins/agents/model.go @@ -21,6 +21,12 @@ type Agent struct { BotAccountName *string `json:"bot_account_name"` ResourceOverrides *string `json:"resource_overrides"` EnvironmentVariables *string `json:"environment_variables"` + Entrypoint *string `json:"entrypoint"` + Providers *string `json:"providers" gorm:"type:jsonb"` + Payloads *string `json:"payloads" gorm:"type:jsonb"` + Environment *string `json:"environment" gorm:"type:jsonb"` + SandboxTemplate *string `json:"sandbox_template" gorm:"type:jsonb"` + SandboxPolicy *string `json:"sandbox_policy"` Labels *string `json:"labels"` Annotations *string `json:"annotations"` CurrentSessionId *string `json:"current_session_id"` diff --git a/components/ambient-api-server/plugins/agents/plugin.go b/components/ambient-api-server/plugins/agents/plugin.go index 15a5de006..c6c8e1bc9 100644 --- a/components/ambient-api-server/plugins/agents/plugin.go +++ b/components/ambient-api-server/plugins/agents/plugin.go @@ -118,4 +118,5 @@ func init() { db.RegisterMigration(migration()) db.RegisterMigration(agentSchemaExpansionMigration()) db.RegisterMigration(dropParentAgentIdMigration()) + db.RegisterMigration(sandboxConfigMigration()) } diff --git a/components/ambient-api-server/plugins/agents/presenter.go b/components/ambient-api-server/plugins/agents/presenter.go index bdb0c3d73..1fadcd6a1 100644 --- a/components/ambient-api-server/plugins/agents/presenter.go +++ b/components/ambient-api-server/plugins/agents/presenter.go @@ -1,6 +1,8 @@ package agents import ( + "encoding/json" + "github.com/ambient-code/platform/components/ambient-api-server/pkg/api/openapi" "github.com/openshift-online/rh-trex-ai/pkg/api" "github.com/openshift-online/rh-trex-ai/pkg/api/presenters" @@ -37,6 +39,34 @@ func ConvertAgent(agent openapi.Agent) *Agent { c.BotAccountName = agent.BotAccountName c.ResourceOverrides = agent.ResourceOverrides c.EnvironmentVariables = agent.EnvironmentVariables + c.Entrypoint = agent.Entrypoint + c.SandboxPolicy = agent.SandboxPolicy + + if len(agent.Providers) > 0 { + if raw, err := json.Marshal(agent.Providers); err == nil { + s := string(raw) + c.Providers = &s + } + } + if len(agent.Payloads) > 0 { + if raw, err := json.Marshal(agent.Payloads); err == nil { + s := string(raw) + c.Payloads = &s + } + } + if agent.Environment != nil { + if raw, err := json.Marshal(agent.Environment); err == nil { + s := string(raw) + c.Environment = &s + } + } + if agent.SandboxTemplate != nil { + if raw, err := json.Marshal(agent.SandboxTemplate); err == nil { + s := string(raw) + c.SandboxTemplate = &s + } + } + c.Labels = agent.Labels c.Annotations = agent.Annotations @@ -52,7 +82,7 @@ func ConvertAgent(agent openapi.Agent) *Agent { func PresentAgent(agent *Agent) openapi.Agent { reference := presenters.PresentReference(agent.ID, agent) - return openapi.Agent{ + result := openapi.Agent{ Id: reference.Id, Kind: reference.Kind, Href: reference.Href, @@ -72,8 +102,37 @@ func PresentAgent(agent *Agent) openapi.Agent { BotAccountName: agent.BotAccountName, ResourceOverrides: agent.ResourceOverrides, EnvironmentVariables: agent.EnvironmentVariables, + Entrypoint: agent.Entrypoint, + SandboxPolicy: agent.SandboxPolicy, CurrentSessionId: agent.CurrentSessionId, Labels: agent.Labels, Annotations: agent.Annotations, } + + if agent.Providers != nil { + var providers []string + if err := json.Unmarshal([]byte(*agent.Providers), &providers); err == nil { + result.Providers = providers + } + } + if agent.Payloads != nil { + var payloads []openapi.Payload + if err := json.Unmarshal([]byte(*agent.Payloads), &payloads); err == nil { + result.Payloads = payloads + } + } + if agent.Environment != nil { + var env map[string]string + if err := json.Unmarshal([]byte(*agent.Environment), &env); err == nil { + result.Environment = &env + } + } + if agent.SandboxTemplate != nil { + var tpl openapi.SandboxTemplate + if err := json.Unmarshal([]byte(*agent.SandboxTemplate), &tpl); err == nil { + result.SandboxTemplate = &tpl + } + } + + return result } diff --git a/components/ambient-control-plane/cmd/ambient-control-plane/main.go b/components/ambient-control-plane/cmd/ambient-control-plane/main.go index 93e9150aa..7373ba65c 100644 --- a/components/ambient-control-plane/cmd/ambient-control-plane/main.go +++ b/components/ambient-control-plane/cmd/ambient-control-plane/main.go @@ -259,6 +259,29 @@ func runKubeMode(ctx context.Context, cfg *config.ControlPlaneConfig) error { podSyncErrCh <- podSyncer.Run(ctx) }() + if cfg.OpenShellUseGateway { + cmSyncer := reconciler.NewConfigMapSyncer(factory, provisionerKube, provisioner, cfg.PlatformMode, cfg.MPPConfigNamespace, log.Logger) + cmSyncErrCh := make(chan error, 1) + go func() { + cmSyncErrCh <- cmSyncer.Run(ctx) + }() + log.Info().Msg("ConfigMap agent declaration syncer enabled") + + select { + case tsErr := <-tsErrCh: + if tsErr != nil { + return fmt.Errorf("token server: %w", tsErr) + } + return <-infErrCh + case infErr := <-infErrCh: + return infErr + case podSyncErr := <-podSyncErrCh: + return fmt.Errorf("pod status syncer: %w", podSyncErr) + case cmSyncErr := <-cmSyncErrCh: + return fmt.Errorf("configmap syncer: %w", cmSyncErr) + } + } + select { case tsErr := <-tsErrCh: if tsErr != nil { diff --git a/components/ambient-control-plane/go.mod b/components/ambient-control-plane/go.mod index 4d467b0b0..c52ab0a97 100644 --- a/components/ambient-control-plane/go.mod +++ b/components/ambient-control-plane/go.mod @@ -59,6 +59,7 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20260622175928-b703f567277d // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.140.0 // indirect k8s.io/kube-openapi v0.0.0-20260624041617-8f3fa4921821 // indirect k8s.io/utils v0.0.0-20260617174310-a95e086a2553 // indirect diff --git a/components/ambient-control-plane/internal/kubeclient/kubeclient.go b/components/ambient-control-plane/internal/kubeclient/kubeclient.go index 4e0302297..f49927daa 100644 --- a/components/ambient-control-plane/internal/kubeclient/kubeclient.go +++ b/components/ambient-control-plane/internal/kubeclient/kubeclient.go @@ -345,6 +345,11 @@ func (kc *KubeClient) CreateConfigMap(ctx context.Context, obj *unstructured.Uns return kc.dynamic.Resource(ConfigMapGVR).Namespace(obj.GetNamespace()).Create(ctx, obj, metav1.CreateOptions{}) } +func (kc *KubeClient) ListConfigMapsByLabel(ctx context.Context, namespace, labelSelector string) (*unstructured.UnstructuredList, error) { + opts := metav1.ListOptions{LabelSelector: labelSelector} + return kc.dynamic.Resource(ConfigMapGVR).Namespace(namespace).List(ctx, opts) +} + func (kc *KubeClient) GetResource(ctx context.Context, gvr schema.GroupVersionResource, namespace, name string) (*unstructured.Unstructured, error) { return kc.dynamic.Resource(gvr).Namespace(namespace).Get(ctx, name, metav1.GetOptions{}) } diff --git a/components/ambient-control-plane/internal/reconciler/configmap_reconciler.go b/components/ambient-control-plane/internal/reconciler/configmap_reconciler.go new file mode 100644 index 000000000..5a8cf0f09 --- /dev/null +++ b/components/ambient-control-plane/internal/reconciler/configmap_reconciler.go @@ -0,0 +1,343 @@ +package reconciler + +import ( + "context" + "encoding/json" + "fmt" + "time" + + "github.com/ambient-code/platform/components/ambient-control-plane/internal/kubeclient" + sdkclient "github.com/ambient-code/platform/components/ambient-sdk/go-sdk/client" + "github.com/ambient-code/platform/components/ambient-sdk/go-sdk/types" + "github.com/rs/zerolog" + "gopkg.in/yaml.v3" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +const ( + configMapSyncInterval = 30 * time.Second + agentDeclarationLabel = "ambient.ai/kind=agent" +) + +type AgentDeclaration struct { + Name string `yaml:"name"` + DisplayName string `yaml:"display_name,omitempty"` + Description string `yaml:"description,omitempty"` + Prompt string `yaml:"prompt,omitempty"` + Entrypoint string `yaml:"entrypoint,omitempty"` + Providers []string `yaml:"providers,omitempty"` + Environment map[string]string `yaml:"environment,omitempty"` + Payloads []PayloadDecl `yaml:"payloads,omitempty"` + SandboxTemplate *SandboxTemplDecl `yaml:"sandbox_template,omitempty"` + SandboxPolicy string `yaml:"sandbox_policy,omitempty"` + RepoURL string `yaml:"repo_url,omitempty"` + LlmModel string `yaml:"llm_model,omitempty"` + Labels map[string]string `yaml:"labels,omitempty"` + Annotations map[string]string `yaml:"annotations,omitempty"` +} + +type PayloadDecl struct { + SandboxPath string `yaml:"sandbox_path"` + Content string `yaml:"content,omitempty"` + RepoURL string `yaml:"repo_url,omitempty"` + Ref string `yaml:"ref,omitempty"` +} + +type SandboxTemplDecl struct { + Image string `yaml:"image,omitempty"` + Resources *ResourceDecl `yaml:"resources,omitempty"` + GPU *GPUDecl `yaml:"gpu,omitempty"` + RuntimeClassName string `yaml:"runtime_class_name,omitempty"` + LogLevel string `yaml:"log_level,omitempty"` +} + +type ResourceDecl struct { + CPU string `yaml:"cpu,omitempty"` + Memory string `yaml:"memory,omitempty"` +} + +type GPUDecl struct { + Count int32 `yaml:"count,omitempty"` +} + +type ConfigMapSyncer struct { + factory *SDKClientFactory + kube *kubeclient.KubeClient + provisioner kubeclient.NamespaceProvisioner + platformMode string + mppConfigNS string + logger zerolog.Logger +} + +func NewConfigMapSyncer(factory *SDKClientFactory, kube *kubeclient.KubeClient, provisioner kubeclient.NamespaceProvisioner, platformMode, mppConfigNS string, logger zerolog.Logger) *ConfigMapSyncer { + return &ConfigMapSyncer{ + factory: factory, + kube: kube, + provisioner: provisioner, + platformMode: platformMode, + mppConfigNS: mppConfigNS, + logger: logger.With().Str("component", "configmap-syncer").Logger(), + } +} + +func (s *ConfigMapSyncer) Run(ctx context.Context) error { + s.logger.Info().Dur("interval", configMapSyncInterval).Msg("configmap syncer started") + ticker := time.NewTicker(configMapSyncInterval) + defer ticker.Stop() + + s.syncOnce(ctx) + + for { + select { + case <-ctx.Done(): + s.logger.Info().Msg("configmap syncer stopped") + return ctx.Err() + case <-ticker.C: + s.syncOnce(ctx) + } + } +} + +func (s *ConfigMapSyncer) syncOnce(ctx context.Context) { + namespaces, err := s.listManagedNamespaces(ctx) + if err != nil { + s.logger.Warn().Err(err).Msg("failed to list managed namespaces for configmap sync") + return + } + + for _, ns := range namespaces { + s.syncNamespaceAgents(ctx, ns.name, ns.projectID) + } +} + +type nsInfo struct { + name string + projectID string +} + +func (s *ConfigMapSyncer) listManagedNamespaces(ctx context.Context) ([]nsInfo, error) { + nsList, err := s.kube.ListNamespacesByLabel(ctx, managedLabelFilter) + if err != nil { + return nil, fmt.Errorf("listing managed namespaces: %w", err) + } + + var result []nsInfo + for _, ns := range nsList.Items { + projectID := ns.GetLabels()[LabelProjectID] + if projectID == "" { + continue + } + result = append(result, nsInfo{name: ns.GetName(), projectID: projectID}) + } + return result, nil +} + +func (s *ConfigMapSyncer) syncNamespaceAgents(ctx context.Context, namespace, projectID string) { + cmList, err := s.kube.ListConfigMapsByLabel(ctx, namespace, agentDeclarationLabel) + if err != nil { + s.logger.Warn().Err(err).Str("namespace", namespace).Msg("failed to list agent configmaps") + return + } + + sdk, err := s.factory.ForProject(ctx, projectID) + if err != nil { + s.logger.Warn().Err(err).Str("project_id", projectID).Msg("failed to get SDK client for configmap sync") + return + } + + declaredAgents := map[string]bool{} + + for _, cm := range cmList.Items { + data, _, _ := unstructured.NestedStringMap(cm.Object, "data") + for key, yamlStr := range data { + decl, err := parseAgentDeclaration(yamlStr) + if err != nil { + s.logger.Warn().Err(err). + Str("namespace", namespace). + Str("configmap", cm.GetName()). + Str("key", key). + Msg("invalid agent declaration YAML") + continue + } + if decl.Name == "" { + s.logger.Warn(). + Str("namespace", namespace). + Str("configmap", cm.GetName()). + Str("key", key). + Msg("agent declaration missing required 'name' field") + continue + } + + declaredAgents[decl.Name] = true + if err := s.upsertAgent(ctx, sdk, projectID, decl); err != nil { + s.logger.Warn().Err(err). + Str("namespace", namespace). + Str("agent", decl.Name). + Msg("failed to upsert agent from configmap") + } + } + } + + s.pruneRemovedAgents(ctx, sdk, projectID, declaredAgents) +} + +func parseAgentDeclaration(yamlStr string) (*AgentDeclaration, error) { + var decl AgentDeclaration + if err := yaml.Unmarshal([]byte(yamlStr), &decl); err != nil { + return nil, fmt.Errorf("parsing agent YAML: %w", err) + } + + for i, p := range decl.Payloads { + if p.SandboxPath == "" { + return nil, fmt.Errorf("payload[%d]: sandbox_path is required", i) + } + if p.Content != "" && p.RepoURL != "" { + return nil, fmt.Errorf("payload[%d]: cannot specify both content and repo_url", i) + } + } + + return &decl, nil +} + +func (s *ConfigMapSyncer) upsertAgent(ctx context.Context, sdk *sdkclient.Client, projectID string, decl *AgentDeclaration) error { + existing := s.findAgentByName(ctx, sdk, projectID, decl.Name) + + patch := map[string]interface{}{} + if decl.DisplayName != "" { + patch["display_name"] = decl.DisplayName + } + if decl.Description != "" { + patch["description"] = decl.Description + } + if decl.Prompt != "" { + patch["prompt"] = decl.Prompt + } + if decl.RepoURL != "" { + patch["repo_url"] = decl.RepoURL + } + if decl.LlmModel != "" { + patch["llm_model"] = decl.LlmModel + } + if decl.Entrypoint != "" { + patch["entrypoint"] = decl.Entrypoint + } + if decl.SandboxPolicy != "" { + patch["sandbox_policy"] = decl.SandboxPolicy + } + if len(decl.Providers) > 0 { + patch["providers"] = decl.Providers + } + if len(decl.Payloads) > 0 { + patch["payloads"] = decl.Payloads + } + if len(decl.Environment) > 0 { + patch["environment"] = decl.Environment + } + if decl.SandboxTemplate != nil { + patch["sandbox_template"] = decl.SandboxTemplate + } + if len(decl.Labels) > 0 { + labelsJSON, _ := json.Marshal(decl.Labels) + patch["labels"] = string(labelsJSON) + } + if len(decl.Annotations) > 0 { + annJSON, _ := json.Marshal(decl.Annotations) + patch["annotations"] = string(annJSON) + } + + if existing != nil { + if _, err := sdk.Agents().Update(ctx, existing.ID, patch); err != nil { + return fmt.Errorf("updating agent %s: %w", decl.Name, err) + } + s.logger.Debug().Str("agent", decl.Name).Str("id", existing.ID).Msg("agent updated from configmap") + return nil + } + + agent, err := types.NewAgentBuilder(). + Name(decl.Name). + ProjectID(projectID). + Build() + if err != nil { + return fmt.Errorf("building agent %s: %w", decl.Name, err) + } + + if decl.DisplayName != "" { + agent.DisplayName = decl.DisplayName + } + if decl.Description != "" { + agent.Description = decl.Description + } + if decl.Prompt != "" { + agent.Prompt = decl.Prompt + } + if decl.RepoURL != "" { + agent.RepoURL = decl.RepoURL + } + if decl.LlmModel != "" { + agent.LlmModel = decl.LlmModel + } + if decl.Entrypoint != "" { + agent.Entrypoint = decl.Entrypoint + } + if decl.SandboxPolicy != "" { + agent.SandboxPolicy = decl.SandboxPolicy + } + if len(decl.Providers) > 0 { + if raw, err := json.Marshal(decl.Providers); err == nil { + agent.Providers = string(raw) + } + } + if len(decl.Payloads) > 0 { + if raw, err := json.Marshal(decl.Payloads); err == nil { + agent.Payloads = string(raw) + } + } + if len(decl.Environment) > 0 { + if raw, err := json.Marshal(decl.Environment); err == nil { + agent.Environment = string(raw) + } + } + if decl.SandboxTemplate != nil { + if raw, err := json.Marshal(decl.SandboxTemplate); err == nil { + agent.SandboxTemplate = string(raw) + } + } + + created, err := sdk.Agents().Create(ctx, agent) + if err != nil { + return fmt.Errorf("creating agent %s: %w", decl.Name, err) + } + s.logger.Info().Str("agent", decl.Name).Str("id", created.ID).Msg("agent created from configmap") + return nil +} + +func (s *ConfigMapSyncer) findAgentByName(ctx context.Context, sdk *sdkclient.Client, projectID, name string) *types.Agent { + agents, err := sdk.Agents().List(ctx, &types.ListOptions{Size: 100, Search: fmt.Sprintf("name = '%s'", name)}) + if err != nil { + return nil + } + for _, a := range agents.Items { + if a.Name == name { + return &a + } + } + return nil +} + +func (s *ConfigMapSyncer) pruneRemovedAgents(ctx context.Context, sdk *sdkclient.Client, projectID string, declaredAgents map[string]bool) { + agents, err := sdk.Agents().List(ctx, &types.ListOptions{Size: 500}) + if err != nil { + s.logger.Warn().Err(err).Str("project_id", projectID).Msg("failed to list agents for pruning") + return + } + + for _, a := range agents.Items { + if a.Entrypoint != "" && !declaredAgents[a.Name] { + if err := sdk.Agents().Delete(ctx, a.ID); err != nil { + s.logger.Warn().Err(err).Str("agent", a.Name).Msg("failed to delete stale agent") + } else { + s.logger.Info().Str("agent", a.Name).Str("id", a.ID).Msg("pruned agent no longer declared in configmaps") + } + } + } +} diff --git a/components/ambient-control-plane/internal/reconciler/kube_reconciler.go b/components/ambient-control-plane/internal/reconciler/kube_reconciler.go index 61bb22410..863269864 100644 --- a/components/ambient-control-plane/internal/reconciler/kube_reconciler.go +++ b/components/ambient-control-plane/internal/reconciler/kube_reconciler.go @@ -281,6 +281,14 @@ func (r *SimpleKubeReconciler) provisionSessionSandbox(ctx context.Context, sess return fmt.Errorf("session %s: project %s not found in API server; refusing to provision: %w", session.ID, session.ProjectID, err) } + var agent *types.Agent + if session.AgentID != "" { + agent, err = sdk.Agents().Get(ctx, session.AgentID) + if err != nil { + r.logger.Warn().Err(err).Str("agent_id", session.AgentID).Msg("failed to fetch agent; continuing with defaults") + } + } + namespace := r.provisioner.NamespaceName(project.Name) sbxName := openshell.SandboxName(session.ID) @@ -297,10 +305,12 @@ func (r *SimpleKubeReconciler) provisionSessionSandbox(ctx context.Context, sess return fmt.Errorf("checking namespace %s: %w", namespace, err) } + entrypoint := r.resolveEntrypoint(agent) + existing, err := r.gateway.GetSandbox(ctx, namespace, sbxName) if err == nil && existing != nil && existing.Sandbox != nil { r.logger.Debug().Str("sandbox", sbxName).Msg("sandbox already exists") - go r.execAfterReady(namespace, sbxName, session.ID) + go r.execAfterReady(namespace, sbxName, session.ID, entrypoint) r.updateSessionPhaseWithNamespace(ctx, session, PhaseRunning, namespace) return nil } @@ -328,6 +338,7 @@ func (r *SimpleKubeReconciler) provisionSessionSandbox(ctx context.Context, sess } env := r.buildSandboxEnv(ctx, session, project.Name, sdk, providerNames) + r.mergeAgentEnvironment(env, agent) for k, v := range env { if strings.ContainsAny(v, "\n\r") { @@ -336,6 +347,8 @@ func (r *SimpleKubeReconciler) provisionSessionSandbox(ctx context.Context, sess } } + sandboxImage := r.resolveSandboxImage(agent) + req := &openshellpb.CreateSandboxRequest{ Name: sbxName, Labels: map[string]string{ @@ -346,7 +359,7 @@ func (r *SimpleKubeReconciler) provisionSessionSandbox(ctx context.Context, sess }, Spec: &openshellpb.SandboxSpec{ Template: &openshellpb.SandboxTemplate{ - Image: r.cfg.OpenShellRunnerImage, + Image: sandboxImage, }, Environment: env, Providers: providerNames, @@ -360,16 +373,52 @@ func (r *SimpleKubeReconciler) provisionSessionSandbox(ctx context.Context, sess r.logger.Info(). Str("sandbox", sbxName). Str("namespace", namespace). + Str("image", sandboxImage). Int("providers", len(providerNames)). Msg("sandbox created via gateway") - go r.execAfterReady(namespace, sbxName, session.ID) + go r.execAfterReady(namespace, sbxName, session.ID, entrypoint) r.updateSessionPhaseWithNamespace(ctx, session, PhaseRunning, namespace) return nil } -func (r *SimpleKubeReconciler) execAfterReady(namespace, sbxName, sessionID string) { +func (r *SimpleKubeReconciler) resolveEntrypoint(agent *types.Agent) []string { + if agent != nil && agent.Entrypoint != "" { + return []string{agent.Entrypoint} + } + return []string{"claude"} +} + +func (r *SimpleKubeReconciler) resolveSandboxImage(agent *types.Agent) string { + if agent != nil && agent.SandboxTemplate != "" { + var tpl struct { + Image string `json:"image"` + } + if err := json.Unmarshal([]byte(agent.SandboxTemplate), &tpl); err == nil && tpl.Image != "" { + return tpl.Image + } + } + return r.cfg.OpenShellRunnerImage +} + +func (r *SimpleKubeReconciler) mergeAgentEnvironment(env map[string]string, agent *types.Agent) { + if agent == nil || agent.Environment == "" { + return + } + var agentEnv map[string]string + if err := json.Unmarshal([]byte(agent.Environment), &agentEnv); err != nil { + r.logger.Warn().Err(err).Msg("failed to parse agent environment") + return + } + for k, v := range agentEnv { + if _, exists := env[k]; !exists { + env[k] = v + } + } +} + +func (r *SimpleKubeReconciler) execAfterReady(namespace, sbxName, sessionID string, entrypoint []string) { pollCtx, pollCancel := context.WithTimeout(context.Background(), 120*time.Second) defer pollCancel() @@ -418,7 +467,8 @@ func (r *SimpleKubeReconciler) execAfterReady(namespace, sbxName, sessionID stri Str("sandbox", sbxName). Str("sandbox_id", sandboxID). Str("session_id", sessionID). - Msg("sandbox is ready, starting runner via exec") + Strs("entrypoint", entrypoint). + Msg("sandbox is ready, executing entrypoint") execCtx := context.Background() // Patch ndots before starting the runner. The OpenShell supervisor is @@ -430,7 +480,7 @@ func (r *SimpleKubeReconciler) execAfterReady(namespace, sbxName, sessionID stri // Setting ndots:1 makes musl resolve FQDNs directly. err = r.gateway.ExecSandboxStreaming(execCtx, namespace, &openshellpb.ExecSandboxRequest{ SandboxId: sandboxID, - Command: []string{"/bin/bash", "-c", "sed -i 's/ndots:[0-9]*/ndots:1/' /etc/resolv.conf 2>/dev/null; cd /sandbox/runner/ambient-runner && PATH=/sandbox/.venv/bin:$PATH uvicorn main:app --host 0.0.0.0 --port 8001"}, + Command: entrypoint, }) if err != nil { r.logger.Error().Err(err).Str("sandbox", sbxName).Str("session_id", sessionID).Msg("failed to start runner exec") diff --git a/components/ambient-sdk/go-sdk/client/agent_api.go b/components/ambient-sdk/go-sdk/client/agent_api.go index c4fcd79c6..5ed652e68 100644 --- a/components/ambient-sdk/go-sdk/client/agent_api.go +++ b/components/ambient-sdk/go-sdk/client/agent_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package client diff --git a/components/ambient-sdk/go-sdk/client/client.go b/components/ambient-sdk/go-sdk/client/client.go index 960355860..e32fe47a8 100644 --- a/components/ambient-sdk/go-sdk/client/client.go +++ b/components/ambient-sdk/go-sdk/client/client.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package client diff --git a/components/ambient-sdk/go-sdk/client/credential_api.go b/components/ambient-sdk/go-sdk/client/credential_api.go index eb25c036b..3a6479e0d 100644 --- a/components/ambient-sdk/go-sdk/client/credential_api.go +++ b/components/ambient-sdk/go-sdk/client/credential_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package client diff --git a/components/ambient-sdk/go-sdk/client/inbox_message_api.go b/components/ambient-sdk/go-sdk/client/inbox_message_api.go index 9dfa0796f..4e2711c70 100644 --- a/components/ambient-sdk/go-sdk/client/inbox_message_api.go +++ b/components/ambient-sdk/go-sdk/client/inbox_message_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package client diff --git a/components/ambient-sdk/go-sdk/client/iterator.go b/components/ambient-sdk/go-sdk/client/iterator.go index 440d6c12f..519bddbac 100644 --- a/components/ambient-sdk/go-sdk/client/iterator.go +++ b/components/ambient-sdk/go-sdk/client/iterator.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package client diff --git a/components/ambient-sdk/go-sdk/client/project_api.go b/components/ambient-sdk/go-sdk/client/project_api.go index 0f308e0c8..8b8054f47 100644 --- a/components/ambient-sdk/go-sdk/client/project_api.go +++ b/components/ambient-sdk/go-sdk/client/project_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package client diff --git a/components/ambient-sdk/go-sdk/client/project_settings_api.go b/components/ambient-sdk/go-sdk/client/project_settings_api.go index ff738d1e1..85bf65bf2 100644 --- a/components/ambient-sdk/go-sdk/client/project_settings_api.go +++ b/components/ambient-sdk/go-sdk/client/project_settings_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package client diff --git a/components/ambient-sdk/go-sdk/client/role_api.go b/components/ambient-sdk/go-sdk/client/role_api.go index 42a8cc836..14fb08bc0 100644 --- a/components/ambient-sdk/go-sdk/client/role_api.go +++ b/components/ambient-sdk/go-sdk/client/role_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package client diff --git a/components/ambient-sdk/go-sdk/client/role_binding_api.go b/components/ambient-sdk/go-sdk/client/role_binding_api.go index 35e2a337c..fee30a8e7 100644 --- a/components/ambient-sdk/go-sdk/client/role_binding_api.go +++ b/components/ambient-sdk/go-sdk/client/role_binding_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package client diff --git a/components/ambient-sdk/go-sdk/client/scheduled_session_api.go b/components/ambient-sdk/go-sdk/client/scheduled_session_api.go index cc6b39d59..34f4314d8 100644 --- a/components/ambient-sdk/go-sdk/client/scheduled_session_api.go +++ b/components/ambient-sdk/go-sdk/client/scheduled_session_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package client diff --git a/components/ambient-sdk/go-sdk/client/session_api.go b/components/ambient-sdk/go-sdk/client/session_api.go index 471a43fde..76933d10a 100644 --- a/components/ambient-sdk/go-sdk/client/session_api.go +++ b/components/ambient-sdk/go-sdk/client/session_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package client diff --git a/components/ambient-sdk/go-sdk/client/session_message_api.go b/components/ambient-sdk/go-sdk/client/session_message_api.go index 7de8771d4..65a885b94 100644 --- a/components/ambient-sdk/go-sdk/client/session_message_api.go +++ b/components/ambient-sdk/go-sdk/client/session_message_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package client diff --git a/components/ambient-sdk/go-sdk/client/user_api.go b/components/ambient-sdk/go-sdk/client/user_api.go index d5e83a64b..8fcb35c89 100644 --- a/components/ambient-sdk/go-sdk/client/user_api.go +++ b/components/ambient-sdk/go-sdk/client/user_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package client diff --git a/components/ambient-sdk/go-sdk/types/agent.go b/components/ambient-sdk/go-sdk/types/agent.go index 08a8b8b2f..a1d3515ac 100644 --- a/components/ambient-sdk/go-sdk/types/agent.go +++ b/components/ambient-sdk/go-sdk/types/agent.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package types @@ -18,6 +18,8 @@ type Agent struct { CurrentSessionID string `json:"current_session_id,omitempty"` Description string `json:"description,omitempty"` DisplayName string `json:"display_name,omitempty"` + Entrypoint string `json:"entrypoint,omitempty"` + Environment string `json:"environment,omitempty"` EnvironmentVariables string `json:"environment_variables,omitempty"` Labels string `json:"labels,omitempty"` LlmMaxTokens int32 `json:"llm_max_tokens,omitempty"` @@ -25,10 +27,14 @@ type Agent struct { LlmTemperature float64 `json:"llm_temperature,omitempty"` Name string `json:"name"` OwnerUserID string `json:"owner_user_id,omitempty"` + Payloads string `json:"payloads,omitempty"` ProjectID string `json:"project_id"` Prompt string `json:"prompt,omitempty"` + Providers string `json:"providers,omitempty"` RepoURL string `json:"repo_url,omitempty"` ResourceOverrides string `json:"resource_overrides,omitempty"` + SandboxPolicy string `json:"sandbox_policy,omitempty"` + SandboxTemplate string `json:"sandbox_template,omitempty"` WorkflowID string `json:"workflow_id,omitempty"` } @@ -71,6 +77,16 @@ func (b *AgentBuilder) DisplayName(v string) *AgentBuilder { return b } +func (b *AgentBuilder) Entrypoint(v string) *AgentBuilder { + b.resource.Entrypoint = v + return b +} + +func (b *AgentBuilder) Environment(v string) *AgentBuilder { + b.resource.Environment = v + return b +} + func (b *AgentBuilder) EnvironmentVariables(v string) *AgentBuilder { b.resource.EnvironmentVariables = v return b @@ -106,6 +122,11 @@ func (b *AgentBuilder) OwnerUserID(v string) *AgentBuilder { return b } +func (b *AgentBuilder) Payloads(v string) *AgentBuilder { + b.resource.Payloads = v + return b +} + func (b *AgentBuilder) ProjectID(v string) *AgentBuilder { b.resource.ProjectID = v return b @@ -116,6 +137,11 @@ func (b *AgentBuilder) Prompt(v string) *AgentBuilder { return b } +func (b *AgentBuilder) Providers(v string) *AgentBuilder { + b.resource.Providers = v + return b +} + func (b *AgentBuilder) RepoURL(v string) *AgentBuilder { b.resource.RepoURL = v return b @@ -126,6 +152,16 @@ func (b *AgentBuilder) ResourceOverrides(v string) *AgentBuilder { return b } +func (b *AgentBuilder) SandboxPolicy(v string) *AgentBuilder { + b.resource.SandboxPolicy = v + return b +} + +func (b *AgentBuilder) SandboxTemplate(v string) *AgentBuilder { + b.resource.SandboxTemplate = v + return b +} + func (b *AgentBuilder) WorkflowID(v string) *AgentBuilder { b.resource.WorkflowID = v return b @@ -167,6 +203,16 @@ func (b *AgentPatchBuilder) DisplayName(v string) *AgentPatchBuilder { return b } +func (b *AgentPatchBuilder) Entrypoint(v string) *AgentPatchBuilder { + b.patch["entrypoint"] = v + return b +} + +func (b *AgentPatchBuilder) Environment(v string) *AgentPatchBuilder { + b.patch["environment"] = v + return b +} + func (b *AgentPatchBuilder) Labels(v string) *AgentPatchBuilder { b.patch["labels"] = v return b @@ -192,16 +238,36 @@ func (b *AgentPatchBuilder) Name(v string) *AgentPatchBuilder { return b } +func (b *AgentPatchBuilder) Payloads(v string) *AgentPatchBuilder { + b.patch["payloads"] = v + return b +} + func (b *AgentPatchBuilder) Prompt(v string) *AgentPatchBuilder { b.patch["prompt"] = v return b } +func (b *AgentPatchBuilder) Providers(v string) *AgentPatchBuilder { + b.patch["providers"] = v + return b +} + func (b *AgentPatchBuilder) RepoURL(v string) *AgentPatchBuilder { b.patch["repo_url"] = v return b } +func (b *AgentPatchBuilder) SandboxPolicy(v string) *AgentPatchBuilder { + b.patch["sandbox_policy"] = v + return b +} + +func (b *AgentPatchBuilder) SandboxTemplate(v string) *AgentPatchBuilder { + b.patch["sandbox_template"] = v + return b +} + func (b *AgentPatchBuilder) Build() map[string]any { return b.patch } diff --git a/components/ambient-sdk/go-sdk/types/base.go b/components/ambient-sdk/go-sdk/types/base.go index 336333df4..c311a6ff1 100644 --- a/components/ambient-sdk/go-sdk/types/base.go +++ b/components/ambient-sdk/go-sdk/types/base.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package types diff --git a/components/ambient-sdk/go-sdk/types/credential.go b/components/ambient-sdk/go-sdk/types/credential.go index c0ee591ca..692936bca 100644 --- a/components/ambient-sdk/go-sdk/types/credential.go +++ b/components/ambient-sdk/go-sdk/types/credential.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package types diff --git a/components/ambient-sdk/go-sdk/types/inbox_message.go b/components/ambient-sdk/go-sdk/types/inbox_message.go index 2aacc3ada..af33b4ed9 100644 --- a/components/ambient-sdk/go-sdk/types/inbox_message.go +++ b/components/ambient-sdk/go-sdk/types/inbox_message.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package types diff --git a/components/ambient-sdk/go-sdk/types/list_options.go b/components/ambient-sdk/go-sdk/types/list_options.go index b6caa67e6..0939dc289 100644 --- a/components/ambient-sdk/go-sdk/types/list_options.go +++ b/components/ambient-sdk/go-sdk/types/list_options.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package types diff --git a/components/ambient-sdk/go-sdk/types/project.go b/components/ambient-sdk/go-sdk/types/project.go index 96f8419fb..e26a24be6 100644 --- a/components/ambient-sdk/go-sdk/types/project.go +++ b/components/ambient-sdk/go-sdk/types/project.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package types diff --git a/components/ambient-sdk/go-sdk/types/project_settings.go b/components/ambient-sdk/go-sdk/types/project_settings.go index 3a5d9b1e7..4a69eac7b 100644 --- a/components/ambient-sdk/go-sdk/types/project_settings.go +++ b/components/ambient-sdk/go-sdk/types/project_settings.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package types diff --git a/components/ambient-sdk/go-sdk/types/role.go b/components/ambient-sdk/go-sdk/types/role.go index 6e72d3835..f1ba27725 100644 --- a/components/ambient-sdk/go-sdk/types/role.go +++ b/components/ambient-sdk/go-sdk/types/role.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package types diff --git a/components/ambient-sdk/go-sdk/types/role_binding.go b/components/ambient-sdk/go-sdk/types/role_binding.go index 69ac3dce5..a74bf7fd5 100644 --- a/components/ambient-sdk/go-sdk/types/role_binding.go +++ b/components/ambient-sdk/go-sdk/types/role_binding.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package types diff --git a/components/ambient-sdk/go-sdk/types/scheduled_session.go b/components/ambient-sdk/go-sdk/types/scheduled_session.go index a2b13f369..c3662d081 100755 --- a/components/ambient-sdk/go-sdk/types/scheduled_session.go +++ b/components/ambient-sdk/go-sdk/types/scheduled_session.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package types diff --git a/components/ambient-sdk/go-sdk/types/session.go b/components/ambient-sdk/go-sdk/types/session.go index ea9ecff81..d372e67f0 100644 --- a/components/ambient-sdk/go-sdk/types/session.go +++ b/components/ambient-sdk/go-sdk/types/session.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package types diff --git a/components/ambient-sdk/go-sdk/types/session_message.go b/components/ambient-sdk/go-sdk/types/session_message.go index 8f26f5f4f..910c65d02 100644 --- a/components/ambient-sdk/go-sdk/types/session_message.go +++ b/components/ambient-sdk/go-sdk/types/session_message.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package types diff --git a/components/ambient-sdk/go-sdk/types/user.go b/components/ambient-sdk/go-sdk/types/user.go index 93ecf1156..2b55d6c7c 100644 --- a/components/ambient-sdk/go-sdk/types/user.go +++ b/components/ambient-sdk/go-sdk/types/user.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z package types diff --git a/components/ambient-sdk/python-sdk/ambient_platform/__init__.py b/components/ambient-sdk/python-sdk/ambient_platform/__init__.py index 7723b9978..d9feb5911 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/__init__.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/__init__.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z """Ambient Platform SDK for Python.""" diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_agent_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_agent_api.py index 7721e95a2..b11c76a27 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_agent_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_agent_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_base.py b/components/ambient-sdk/python-sdk/ambient_platform/_base.py index 7a8cb54fd..6abd0ca64 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_base.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_base.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_credential_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_credential_api.py index 8e747e3d4..ebbffc094 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_credential_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_credential_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_inbox_message_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_inbox_message_api.py index 3ca17bcc3..147afdbe4 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_inbox_message_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_inbox_message_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_iterator.py b/components/ambient-sdk/python-sdk/ambient_platform/_iterator.py index 2f0f3bc50..797de6bd6 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_iterator.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_iterator.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_project_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_project_api.py index 43a0976bf..d0adfbcbb 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_project_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_project_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_project_settings_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_project_settings_api.py index d1e181330..56b577960 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_project_settings_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_project_settings_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_role_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_role_api.py index 057552944..3f37dee5d 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_role_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_role_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_role_binding_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_role_binding_api.py index 868bd5d71..f0ad32a91 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_role_binding_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_role_binding_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_scheduled_session_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_scheduled_session_api.py index a5777e0a3..e2573a6ea 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_scheduled_session_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_scheduled_session_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_session_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_session_api.py index 994eb6057..1dff17419 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_session_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_session_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_session_message_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_session_message_api.py index 22e8702ae..7d76b6ec0 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_session_message_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_session_message_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_user_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_user_api.py index 6f966c243..a8d0c8cbd 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_user_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_user_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/agent.py b/components/ambient-sdk/python-sdk/ambient_platform/agent.py index 5a50db772..26af56962 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/agent.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/agent.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations @@ -24,6 +24,8 @@ class Agent: current_session_id: str = "" description: str = "" display_name: str = "" + entrypoint: str = "" + environment: str = "" environment_variables: str = "" labels: str = "" llm_max_tokens: int = 0 @@ -31,10 +33,14 @@ class Agent: llm_temperature: float = 0.0 name: str = "" owner_user_id: str = "" + payloads: str = "" project_id: str = "" prompt: str = "" + providers: str = "" repo_url: str = "" resource_overrides: str = "" + sandbox_policy: str = "" + sandbox_template: str = "" workflow_id: str = "" @classmethod @@ -50,6 +56,8 @@ def from_dict(cls, data: dict) -> Agent: current_session_id=data.get("current_session_id", ""), description=data.get("description", ""), display_name=data.get("display_name", ""), + entrypoint=data.get("entrypoint", ""), + environment=data.get("environment", ""), environment_variables=data.get("environment_variables", ""), labels=data.get("labels", ""), llm_max_tokens=data.get("llm_max_tokens", 0), @@ -57,10 +65,14 @@ def from_dict(cls, data: dict) -> Agent: llm_temperature=data.get("llm_temperature", 0.0), name=data.get("name", ""), owner_user_id=data.get("owner_user_id", ""), + payloads=data.get("payloads", ""), project_id=data.get("project_id", ""), prompt=data.get("prompt", ""), + providers=data.get("providers", ""), repo_url=data.get("repo_url", ""), resource_overrides=data.get("resource_overrides", ""), + sandbox_policy=data.get("sandbox_policy", ""), + sandbox_template=data.get("sandbox_template", ""), workflow_id=data.get("workflow_id", ""), ) @@ -109,6 +121,14 @@ def display_name(self, value: str) -> AgentBuilder: self._data["display_name"] = value return self + def entrypoint(self, value: str) -> AgentBuilder: + self._data["entrypoint"] = value + return self + + def environment(self, value: str) -> AgentBuilder: + self._data["environment"] = value + return self + def environment_variables(self, value: str) -> AgentBuilder: self._data["environment_variables"] = value return self @@ -137,6 +157,10 @@ def owner_user_id(self, value: str) -> AgentBuilder: self._data["owner_user_id"] = value return self + def payloads(self, value: str) -> AgentBuilder: + self._data["payloads"] = value + return self + def project_id(self, value: str) -> AgentBuilder: self._data["project_id"] = value return self @@ -145,6 +169,10 @@ def prompt(self, value: str) -> AgentBuilder: self._data["prompt"] = value return self + def providers(self, value: str) -> AgentBuilder: + self._data["providers"] = value + return self + def repo_url(self, value: str) -> AgentBuilder: self._data["repo_url"] = value return self @@ -153,6 +181,14 @@ def resource_overrides(self, value: str) -> AgentBuilder: self._data["resource_overrides"] = value return self + def sandbox_policy(self, value: str) -> AgentBuilder: + self._data["sandbox_policy"] = value + return self + + def sandbox_template(self, value: str) -> AgentBuilder: + self._data["sandbox_template"] = value + return self + def workflow_id(self, value: str) -> AgentBuilder: self._data["workflow_id"] = value return self @@ -182,6 +218,14 @@ def display_name(self, value: str) -> AgentPatch: self._data["display_name"] = value return self + def entrypoint(self, value: str) -> AgentPatch: + self._data["entrypoint"] = value + return self + + def environment(self, value: str) -> AgentPatch: + self._data["environment"] = value + return self + def labels(self, value: str) -> AgentPatch: self._data["labels"] = value return self @@ -202,13 +246,29 @@ def name(self, value: str) -> AgentPatch: self._data["name"] = value return self + def payloads(self, value: str) -> AgentPatch: + self._data["payloads"] = value + return self + def prompt(self, value: str) -> AgentPatch: self._data["prompt"] = value return self + def providers(self, value: str) -> AgentPatch: + self._data["providers"] = value + return self + def repo_url(self, value: str) -> AgentPatch: self._data["repo_url"] = value return self + def sandbox_policy(self, value: str) -> AgentPatch: + self._data["sandbox_policy"] = value + return self + + def sandbox_template(self, value: str) -> AgentPatch: + self._data["sandbox_template"] = value + return self + def to_dict(self) -> dict: return dict(self._data) diff --git a/components/ambient-sdk/python-sdk/ambient_platform/client.py b/components/ambient-sdk/python-sdk/ambient_platform/client.py index 4b587c80a..95ec0201e 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/client.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/client.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/credential.py b/components/ambient-sdk/python-sdk/ambient_platform/credential.py index 227002237..1e096cfdf 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/credential.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/credential.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/inbox_message.py b/components/ambient-sdk/python-sdk/ambient_platform/inbox_message.py index 654c81c8a..567d2e1ad 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/inbox_message.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/inbox_message.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/project.py b/components/ambient-sdk/python-sdk/ambient_platform/project.py index bf24a1111..912b83bad 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/project.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/project.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/project_settings.py b/components/ambient-sdk/python-sdk/ambient_platform/project_settings.py index a53c9483c..1c5021ece 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/project_settings.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/project_settings.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/role.py b/components/ambient-sdk/python-sdk/ambient_platform/role.py index 6d8adf434..c57045bd1 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/role.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/role.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/role_binding.py b/components/ambient-sdk/python-sdk/ambient_platform/role_binding.py index 3a5a770f5..0f603e17f 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/role_binding.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/role_binding.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/scheduled_session.py b/components/ambient-sdk/python-sdk/ambient_platform/scheduled_session.py index 8fea067a4..fc009b6a1 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/scheduled_session.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/scheduled_session.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/session.py b/components/ambient-sdk/python-sdk/ambient_platform/session.py index f7aca22fc..db8b5221e 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/session.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/session.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/session_message.py b/components/ambient-sdk/python-sdk/ambient_platform/session_message.py index 1552ed6cd..9b1bc55d8 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/session_message.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/session_message.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/user.py b/components/ambient-sdk/python-sdk/ambient_platform/user.py index d0489f1f8..50808e7ed 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/user.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/user.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -# Generated: 2026-06-23T20:52:14Z +# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +# Generated: 2026-06-29T17:10:10Z from __future__ import annotations diff --git a/components/ambient-sdk/ts-sdk/src/agent.ts b/components/ambient-sdk/ts-sdk/src/agent.ts index 1cb45faa6..68812f4d3 100644 --- a/components/ambient-sdk/ts-sdk/src/agent.ts +++ b/components/ambient-sdk/ts-sdk/src/agent.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { ObjectReference, ListMeta } from './base'; @@ -11,6 +11,8 @@ export type Agent = ObjectReference & { current_session_id: string; description: string; display_name: string; + entrypoint: string; + environment: string; environment_variables: string; labels: string; llm_max_tokens: number; @@ -18,10 +20,14 @@ export type Agent = ObjectReference & { llm_temperature: number; name: string; owner_user_id: string; + payloads: string; project_id: string; prompt: string; + providers: string; repo_url: string; resource_overrides: string; + sandbox_policy: string; + sandbox_template: string; workflow_id: string; }; @@ -34,6 +40,8 @@ export type AgentCreateRequest = { bot_account_name?: string; description?: string; display_name?: string; + entrypoint?: string; + environment?: string; environment_variables?: string; labels?: string; llm_max_tokens?: number; @@ -41,10 +49,14 @@ export type AgentCreateRequest = { llm_temperature?: number; name: string; owner_user_id?: string; + payloads?: string; project_id: string; prompt?: string; + providers?: string; repo_url?: string; resource_overrides?: string; + sandbox_policy?: string; + sandbox_template?: string; workflow_id?: string; }; @@ -52,13 +64,19 @@ export type AgentPatchRequest = { annotations?: string; description?: string; display_name?: string; + entrypoint?: string; + environment?: string; labels?: string; llm_max_tokens?: number; llm_model?: string; llm_temperature?: number; name?: string; + payloads?: string; prompt?: string; + providers?: string; repo_url?: string; + sandbox_policy?: string; + sandbox_template?: string; }; export class AgentBuilder { @@ -85,6 +103,16 @@ export class AgentBuilder { return this; } + entrypoint(value: string): this { + this.data['entrypoint'] = value; + return this; + } + + environment(value: string): this { + this.data['environment'] = value; + return this; + } + environmentVariables(value: string): this { this.data['environment_variables'] = value; return this; @@ -120,6 +148,11 @@ export class AgentBuilder { return this; } + payloads(value: string): this { + this.data['payloads'] = value; + return this; + } + projectId(value: string): this { this.data['project_id'] = value; return this; @@ -130,6 +163,11 @@ export class AgentBuilder { return this; } + providers(value: string): this { + this.data['providers'] = value; + return this; + } + repoUrl(value: string): this { this.data['repo_url'] = value; return this; @@ -140,6 +178,16 @@ export class AgentBuilder { return this; } + sandboxPolicy(value: string): this { + this.data['sandbox_policy'] = value; + return this; + } + + sandboxTemplate(value: string): this { + this.data['sandbox_template'] = value; + return this; + } + workflowId(value: string): this { this.data['workflow_id'] = value; return this; @@ -175,6 +223,16 @@ export class AgentPatchBuilder { return this; } + entrypoint(value: string): this { + this.data['entrypoint'] = value; + return this; + } + + environment(value: string): this { + this.data['environment'] = value; + return this; + } + labels(value: string): this { this.data['labels'] = value; return this; @@ -200,16 +258,36 @@ export class AgentPatchBuilder { return this; } + payloads(value: string): this { + this.data['payloads'] = value; + return this; + } + prompt(value: string): this { this.data['prompt'] = value; return this; } + providers(value: string): this { + this.data['providers'] = value; + return this; + } + repoUrl(value: string): this { this.data['repo_url'] = value; return this; } + sandboxPolicy(value: string): this { + this.data['sandbox_policy'] = value; + return this; + } + + sandboxTemplate(value: string): this { + this.data['sandbox_template'] = value; + return this; + } + build(): AgentPatchRequest { return this.data as AgentPatchRequest; } diff --git a/components/ambient-sdk/ts-sdk/src/agent_api.ts b/components/ambient-sdk/ts-sdk/src/agent_api.ts index 824583146..290e199f6 100644 --- a/components/ambient-sdk/ts-sdk/src/agent_api.ts +++ b/components/ambient-sdk/ts-sdk/src/agent_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/base.ts b/components/ambient-sdk/ts-sdk/src/base.ts index c482ab96c..f6d083717 100644 --- a/components/ambient-sdk/ts-sdk/src/base.ts +++ b/components/ambient-sdk/ts-sdk/src/base.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z export type ObjectReference = { id: string; diff --git a/components/ambient-sdk/ts-sdk/src/client.ts b/components/ambient-sdk/ts-sdk/src/client.ts index fc1a87eda..4c80859f1 100644 --- a/components/ambient-sdk/ts-sdk/src/client.ts +++ b/components/ambient-sdk/ts-sdk/src/client.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { AmbientClientConfig } from './base'; import { AgentAPI } from './agent_api'; diff --git a/components/ambient-sdk/ts-sdk/src/credential.ts b/components/ambient-sdk/ts-sdk/src/credential.ts index 8eb66909a..0575e2c31 100644 --- a/components/ambient-sdk/ts-sdk/src/credential.ts +++ b/components/ambient-sdk/ts-sdk/src/credential.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/credential_api.ts b/components/ambient-sdk/ts-sdk/src/credential_api.ts index 3c0ca7b37..1c559917d 100644 --- a/components/ambient-sdk/ts-sdk/src/credential_api.ts +++ b/components/ambient-sdk/ts-sdk/src/credential_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/inbox_message.ts b/components/ambient-sdk/ts-sdk/src/inbox_message.ts index 5d686457e..9bf17f27a 100644 --- a/components/ambient-sdk/ts-sdk/src/inbox_message.ts +++ b/components/ambient-sdk/ts-sdk/src/inbox_message.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/inbox_message_api.ts b/components/ambient-sdk/ts-sdk/src/inbox_message_api.ts index 427134864..88c12286b 100644 --- a/components/ambient-sdk/ts-sdk/src/inbox_message_api.ts +++ b/components/ambient-sdk/ts-sdk/src/inbox_message_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/index.ts b/components/ambient-sdk/ts-sdk/src/index.ts index 6e0869b3e..54f7b7370 100644 --- a/components/ambient-sdk/ts-sdk/src/index.ts +++ b/components/ambient-sdk/ts-sdk/src/index.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z export { AmbientClient } from './client'; export type { AmbientClientConfig, ListOptions, RequestOptions, ObjectReference, ListMeta, APIError } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/project.ts b/components/ambient-sdk/ts-sdk/src/project.ts index eb44658f4..0b566ca2d 100644 --- a/components/ambient-sdk/ts-sdk/src/project.ts +++ b/components/ambient-sdk/ts-sdk/src/project.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/project_api.ts b/components/ambient-sdk/ts-sdk/src/project_api.ts index 12cb600f0..843cd3e5d 100644 --- a/components/ambient-sdk/ts-sdk/src/project_api.ts +++ b/components/ambient-sdk/ts-sdk/src/project_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/project_settings.ts b/components/ambient-sdk/ts-sdk/src/project_settings.ts index 3c30bf0d0..0ffd2326d 100644 --- a/components/ambient-sdk/ts-sdk/src/project_settings.ts +++ b/components/ambient-sdk/ts-sdk/src/project_settings.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/project_settings_api.ts b/components/ambient-sdk/ts-sdk/src/project_settings_api.ts index f13b1352f..46ed0d40b 100644 --- a/components/ambient-sdk/ts-sdk/src/project_settings_api.ts +++ b/components/ambient-sdk/ts-sdk/src/project_settings_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/role.ts b/components/ambient-sdk/ts-sdk/src/role.ts index 6e0445cb6..8a53eae18 100644 --- a/components/ambient-sdk/ts-sdk/src/role.ts +++ b/components/ambient-sdk/ts-sdk/src/role.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/role_api.ts b/components/ambient-sdk/ts-sdk/src/role_api.ts index 54fa8ec24..3a2d1b943 100644 --- a/components/ambient-sdk/ts-sdk/src/role_api.ts +++ b/components/ambient-sdk/ts-sdk/src/role_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/role_binding.ts b/components/ambient-sdk/ts-sdk/src/role_binding.ts index f630c2200..20dac0678 100644 --- a/components/ambient-sdk/ts-sdk/src/role_binding.ts +++ b/components/ambient-sdk/ts-sdk/src/role_binding.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/role_binding_api.ts b/components/ambient-sdk/ts-sdk/src/role_binding_api.ts index 4a42e0b33..16eb0b1ba 100644 --- a/components/ambient-sdk/ts-sdk/src/role_binding_api.ts +++ b/components/ambient-sdk/ts-sdk/src/role_binding_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/scheduled_session.ts b/components/ambient-sdk/ts-sdk/src/scheduled_session.ts index 1dec95b94..4668c846f 100644 --- a/components/ambient-sdk/ts-sdk/src/scheduled_session.ts +++ b/components/ambient-sdk/ts-sdk/src/scheduled_session.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/scheduled_session_api.ts b/components/ambient-sdk/ts-sdk/src/scheduled_session_api.ts index 402b3ef02..f01193353 100644 --- a/components/ambient-sdk/ts-sdk/src/scheduled_session_api.ts +++ b/components/ambient-sdk/ts-sdk/src/scheduled_session_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/session.ts b/components/ambient-sdk/ts-sdk/src/session.ts index 85554068e..a5294b4be 100644 --- a/components/ambient-sdk/ts-sdk/src/session.ts +++ b/components/ambient-sdk/ts-sdk/src/session.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/session_api.ts b/components/ambient-sdk/ts-sdk/src/session_api.ts index c81e9b427..ecac21a4a 100644 --- a/components/ambient-sdk/ts-sdk/src/session_api.ts +++ b/components/ambient-sdk/ts-sdk/src/session_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/session_message.ts b/components/ambient-sdk/ts-sdk/src/session_message.ts index eae3b3ed9..fbda3ef3e 100644 --- a/components/ambient-sdk/ts-sdk/src/session_message.ts +++ b/components/ambient-sdk/ts-sdk/src/session_message.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/session_message_api.ts b/components/ambient-sdk/ts-sdk/src/session_message_api.ts index ca3a81906..2f42928d1 100644 --- a/components/ambient-sdk/ts-sdk/src/session_message_api.ts +++ b/components/ambient-sdk/ts-sdk/src/session_message_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/user.ts b/components/ambient-sdk/ts-sdk/src/user.ts index 3339f8571..89bf4f008 100644 --- a/components/ambient-sdk/ts-sdk/src/user.ts +++ b/components/ambient-sdk/ts-sdk/src/user.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/user_api.ts b/components/ambient-sdk/ts-sdk/src/user_api.ts index 2e2cbaf30..fd9b1685d 100644 --- a/components/ambient-sdk/ts-sdk/src/user_api.ts +++ b/components/ambient-sdk/ts-sdk/src/user_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: f136081d1442aaec8e6d7e6b5db0a10b55f38cda7e3168930bc03e5eec439d17 -// Generated: 2026-06-23T20:52:14Z +// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 +// Generated: 2026-06-29T17:10:10Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-ui/src/adapters/__tests__/mappers.test.ts b/components/ambient-ui/src/adapters/__tests__/mappers.test.ts index 7818af1ab..b77918422 100644 --- a/components/ambient-ui/src/adapters/__tests__/mappers.test.ts +++ b/components/ambient-ui/src/adapters/__tests__/mappers.test.ts @@ -482,6 +482,12 @@ function makeSdkAgent(overrides: Partial = {}): Agent { repo_url: 'https://github.com/org/repo', resource_overrides: '', workflow_id: 'wf-1', + entrypoint: '', + providers: '', + payloads: '', + environment: '', + sandbox_template: '', + sandbox_policy: '', ...overrides, } } diff --git a/components/ambient-ui/src/adapters/mappers.ts b/components/ambient-ui/src/adapters/mappers.ts index 13c1b7948..db7d21677 100644 --- a/components/ambient-ui/src/adapters/mappers.ts +++ b/components/ambient-ui/src/adapters/mappers.ts @@ -2,7 +2,7 @@ import type { Session, Project, Agent, Credential, RoleBinding } from 'ambient-s import type { DomainSession, DomainProject, DomainSessionMessage, DomainAgent, SessionPhase, SessionEventType, DomainRepo, DomainReconciledRepo, DomainCondition, ReconciledRepoStatus, ConditionStatus, - DomainCredential, DomainRoleBinding, + DomainCredential, DomainRoleBinding, DomainPayload, DomainSandboxTemplate, } from '@/domain/types' const VALID_PHASES: ReadonlySet = new Set([ @@ -169,6 +169,48 @@ export function mapSdkProjectToDomain(sdk: Project): DomainProject { } } +function parseProviders(raw: string): string[] { + if (!raw) return [] + try { + const parsed: unknown = JSON.parse(raw) + if (Array.isArray(parsed)) { + return parsed.filter((v): v is string => typeof v === 'string') + } + return [] + } catch { + return [] + } +} + +function parsePayloads(raw: string): DomainPayload[] { + if (!raw) return [] + try { + const parsed: unknown = JSON.parse(raw) + if (!Array.isArray(parsed)) return [] + return parsed + .filter((v): v is Record => typeof v === 'object' && v !== null) + .map((v) => ({ + sandbox_path: String(v.sandbox_path ?? ''), + ...(v.content ? { content: String(v.content) } : {}), + ...(v.repo_url ? { repo_url: String(v.repo_url) } : {}), + ...(v.ref ? { ref: String(v.ref) } : {}), + })) + } catch { + return [] + } +} + +function parseSandboxTemplate(raw: string): DomainSandboxTemplate | null { + if (!raw) return null + try { + const parsed: unknown = JSON.parse(raw) + if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) return null + return parsed as DomainSandboxTemplate + } catch { + return null + } +} + export function mapSdkAgentToDomain(sdk: Agent): DomainAgent { return { id: sdk.id, @@ -182,6 +224,12 @@ export function mapSdkAgentToDomain(sdk: Agent): DomainAgent { prompt: emptyToNull(sdk.prompt), repoUrl: emptyToNull(sdk.repo_url), workflowId: emptyToNull(sdk.workflow_id), + entrypoint: emptyToNull(sdk.entrypoint), + providers: parseProviders(sdk.providers), + payloads: parsePayloads(sdk.payloads), + environment: parseJsonObject(sdk.environment), + sandboxTemplate: parseSandboxTemplate(sdk.sandbox_template), + sandboxPolicy: emptyToNull(sdk.sandbox_policy), annotations: parseAnnotations(sdk.annotations), labels: parseJsonObject(sdk.labels), createdAt: sdk.created_at ?? '', diff --git a/components/ambient-ui/src/adapters/sdk-agents.ts b/components/ambient-ui/src/adapters/sdk-agents.ts index f5846674c..9d697abc9 100644 --- a/components/ambient-ui/src/adapters/sdk-agents.ts +++ b/components/ambient-ui/src/adapters/sdk-agents.ts @@ -40,6 +40,12 @@ function mapDomainCreateToSdk(request: DomainAgentCreateRequest): AgentCreateReq if (request.prompt) sdkReq.prompt = request.prompt if (request.repoUrl) sdkReq.repo_url = request.repoUrl if (request.description) sdkReq.description = request.description + if (request.entrypoint) sdkReq.entrypoint = request.entrypoint + if (request.providers) sdkReq.providers = JSON.stringify(request.providers) + if (request.payloads) sdkReq.payloads = JSON.stringify(request.payloads) + if (request.environment) sdkReq.environment = JSON.stringify(request.environment) + if (request.sandboxTemplate) sdkReq.sandbox_template = JSON.stringify(request.sandboxTemplate) + if (request.sandboxPolicy) sdkReq.sandbox_policy = request.sandboxPolicy return sdkReq } @@ -50,6 +56,12 @@ function mapDomainUpdateToSdk(request: DomainAgentUpdateRequest): AgentPatchRequ if (request.prompt !== undefined) sdkReq.prompt = request.prompt if (request.repoUrl !== undefined) sdkReq.repo_url = request.repoUrl if (request.description !== undefined) sdkReq.description = request.description + if (request.entrypoint !== undefined) sdkReq.entrypoint = request.entrypoint + if (request.providers !== undefined) sdkReq.providers = JSON.stringify(request.providers) + if (request.payloads !== undefined) sdkReq.payloads = JSON.stringify(request.payloads) + if (request.environment !== undefined) sdkReq.environment = JSON.stringify(request.environment) + if (request.sandboxTemplate !== undefined) sdkReq.sandbox_template = JSON.stringify(request.sandboxTemplate) + if (request.sandboxPolicy !== undefined) sdkReq.sandbox_policy = request.sandboxPolicy return sdkReq } diff --git a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-manifest-tab.tsx b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-manifest-tab.tsx index 7e49c46e8..8ec1a7414 100644 --- a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-manifest-tab.tsx +++ b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-manifest-tab.tsx @@ -73,12 +73,54 @@ function agentToYaml(agent: DomainAgent): string { if (agent.model) lines.push(` model: ${agent.model}`) if (agent.repoUrl) lines.push(` repoUrl: ${agent.repoUrl}`) if (agent.workflowId) lines.push(` workflowId: ${agent.workflowId}`) + if (agent.entrypoint) lines.push(` entrypoint: ${agent.entrypoint}`) + if (agent.sandboxPolicy) lines.push(` sandboxPolicy: ${agent.sandboxPolicy}`) if (agent.prompt) { lines.push(' prompt: |') for (const promptLine of agent.prompt.split('\n')) { lines.push(` ${promptLine}`) } } + if (agent.providers.length > 0) { + lines.push(' providers:') + for (const p of agent.providers) { + lines.push(` - ${p}`) + } + } + if (agent.payloads.length > 0) { + lines.push(' payloads:') + for (const payload of agent.payloads) { + lines.push(` - sandbox_path: ${payload.sandbox_path}`) + if (payload.repo_url) lines.push(` repo_url: ${payload.repo_url}`) + if (payload.ref) lines.push(` ref: ${payload.ref}`) + if (payload.content) { + lines.push(' content: |') + for (const cl of payload.content.split('\n')) { + lines.push(` ${cl}`) + } + } + } + } + const envEntries = Object.entries(agent.environment) + if (envEntries.length > 0) { + lines.push(' environment:') + for (const [key, value] of envEntries) { + lines.push(` ${key}: "${value}"`) + } + } + if (agent.sandboxTemplate) { + lines.push(' sandboxTemplate:') + if (agent.sandboxTemplate.image) lines.push(` image: ${agent.sandboxTemplate.image}`) + if (agent.sandboxTemplate.resources) { + lines.push(' resources:') + if (agent.sandboxTemplate.resources.cpu) lines.push(` cpu: "${agent.sandboxTemplate.resources.cpu}"`) + if (agent.sandboxTemplate.resources.memory) lines.push(` memory: ${agent.sandboxTemplate.resources.memory}`) + } + if (agent.sandboxTemplate.gpu) { + lines.push(' gpu:') + if (agent.sandboxTemplate.gpu.count !== undefined) lines.push(` count: ${agent.sandboxTemplate.gpu.count}`) + } + } return lines.join('\n') + '\n' } diff --git a/components/ambient-ui/src/domain/types.ts b/components/ambient-ui/src/domain/types.ts index b5bb02ddb..ea973958e 100644 --- a/components/ambient-ui/src/domain/types.ts +++ b/components/ambient-ui/src/domain/types.ts @@ -105,6 +105,30 @@ export type DomainSessionMessage = { createdAt: string } +export type DomainPayload = { + sandbox_path: string + content?: string + repo_url?: string + ref?: string +} + +export type DomainResourceRequirements = { + cpu?: string + memory?: string +} + +export type DomainGpuRequirements = { + count?: number +} + +export type DomainSandboxTemplate = { + image?: string + resources?: DomainResourceRequirements + gpu?: DomainGpuRequirements + runtime_class_name?: string + log_level?: string +} + export type DomainAgent = { id: string name: string @@ -117,6 +141,12 @@ export type DomainAgent = { prompt: string | null repoUrl: string | null workflowId: string | null + entrypoint: string | null + providers: string[] + payloads: DomainPayload[] + environment: Record + sandboxTemplate: DomainSandboxTemplate | null + sandboxPolicy: string | null annotations: Record labels: Record createdAt: string @@ -143,6 +173,12 @@ export type DomainAgentCreateRequest = { prompt?: string repoUrl?: string description?: string + entrypoint?: string + providers?: string[] + payloads?: DomainPayload[] + environment?: Record + sandboxTemplate?: DomainSandboxTemplate + sandboxPolicy?: string } export type DomainAgentUpdateRequest = { @@ -151,6 +187,12 @@ export type DomainAgentUpdateRequest = { prompt?: string repoUrl?: string description?: string + entrypoint?: string + providers?: string[] + payloads?: DomainPayload[] + environment?: Record + sandboxTemplate?: DomainSandboxTemplate + sandboxPolicy?: string } export type FeedbackItem = { diff --git a/examples/agent-sandbox-config.yaml b/examples/agent-sandbox-config.yaml new file mode 100644 index 000000000..f8356c956 --- /dev/null +++ b/examples/agent-sandbox-config.yaml @@ -0,0 +1,139 @@ +# Agent Sandbox Configuration Example +# +# Complete example of ConfigMap-based agent, provider, and policy declarations. +# Apply to a tenant namespace (e.g. "alpha") with: kubectl apply -f agent-sandbox-config.yaml +# +# Prerequisites: +# - OPENSHELL_USE_GATEWAY=true on the control plane +# - Secrets referenced by providers must exist in the namespace +# - The namespace must correspond to an ACP project +--- +apiVersion: v1 +kind: Secret +metadata: + name: github-pat + namespace: alpha +type: Opaque +stringData: + token: "" +--- +apiVersion: v1 +kind: Secret +metadata: + name: anthropic-key + namespace: alpha +type: Opaque +stringData: + token: "" +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: provider-declarations + namespace: alpha + labels: + ambient.ai/kind: provider +data: + github: | + name: github + type: github + secret: github-pat + anthropic: | + name: anthropic + type: anthropic + secret: anthropic-key +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: policy-declarations + namespace: alpha + labels: + ambient.ai/kind: policy +data: + restricted-github-only: | + name: restricted-github-only + network_policies: + github_api: + endpoints: + - host: api.github.com + port: 443 + protocol: rest + rules: + - allow: + method: "*" + path: "/**" + binaries: + - path: /usr/bin/git + inference: + endpoints: + - host: inference.local + port: 443 + protocol: rest + rules: + - allow: + method: POST + path: "/v1/**" + filesystem: + read_write: + - /sandbox + - /tmp + read_only: + - /usr + - /etc + - /lib + process: + run_as_user: sandbox + run_as_group: sandbox + landlock: + compatibility: best_effort + permissive-dev: | + name: permissive-dev + filesystem: + read_write: + - /sandbox + - /tmp + read_only: + - /usr + - /etc + process: + run_as_user: sandbox + run_as_group: sandbox +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: agent-declarations + namespace: alpha + labels: + ambient.ai/kind: agent +data: + security-reviewer: | + name: security-reviewer + display_name: Security Reviewer + description: Reviews PRs for security vulnerabilities and OWASP top-10 issues. + entrypoint: claude + prompt: | + You are a security reviewer. Analyze code for vulnerabilities including + injection attacks, authentication issues, and insecure data handling. + Report findings with severity, location, and remediation guidance. + providers: + - github + - anthropic + payloads: + - sandbox_path: /sandbox/CLAUDE.md + content: | + # Security Review Agent + Focus on OWASP top-10 vulnerabilities. + Always check for hardcoded secrets. + - sandbox_path: /sandbox/workspace + repo_url: https://github.com/example-org/target-repo + ref: main + environment: + LOG_LEVEL: info + REVIEW_MODE: strict + sandbox_template: + resources: + cpu: "2" + memory: 4Gi + sandbox_policy: restricted-github-only From aa19e242142854539a2f7970b5de6c820493aaee Mon Sep 17 00:00:00 2001 From: Kyle Squizzato Date: Mon, 29 Jun 2026 10:42:42 -0700 Subject: [PATCH 02/16] fix: remove secret stubs from example to pass secret scanner Co-Authored-By: Claude Opus 4.6 --- examples/agent-sandbox-config.yaml | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/examples/agent-sandbox-config.yaml b/examples/agent-sandbox-config.yaml index f8356c956..28804d954 100644 --- a/examples/agent-sandbox-config.yaml +++ b/examples/agent-sandbox-config.yaml @@ -5,28 +5,12 @@ # # Prerequisites: # - OPENSHELL_USE_GATEWAY=true on the control plane -# - Secrets referenced by providers must exist in the namespace +# - Secrets referenced by providers must exist in the namespace before applying: +# kubectl create secret generic github-pat --from-literal=token= -n alpha +# kubectl create secret generic anthropic-key --from-literal=token= -n alpha # - The namespace must correspond to an ACP project --- apiVersion: v1 -kind: Secret -metadata: - name: github-pat - namespace: alpha -type: Opaque -stringData: - token: "" ---- -apiVersion: v1 -kind: Secret -metadata: - name: anthropic-key - namespace: alpha -type: Opaque -stringData: - token: "" ---- -apiVersion: v1 kind: ConfigMap metadata: name: provider-declarations From cdac6462addfe073573c77cba24e985e9cc5cf2b Mon Sep 17 00:00:00 2001 From: Kyle Squizzato Date: Mon, 29 Jun 2026 10:56:47 -0700 Subject: [PATCH 03/16] fix(ci): use go-sdk go.mod for SDK drift check Go version The go-sdk requires Go 1.25.0 but the workflow was using the generator's go.mod (Go 1.24.4), causing `go fmt` to fail. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/ambient-sdk-drift-check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ambient-sdk-drift-check.yml b/.github/workflows/ambient-sdk-drift-check.yml index 689c0408c..aee6effe6 100644 --- a/.github/workflows/ambient-sdk-drift-check.yml +++ b/.github/workflows/ambient-sdk-drift-check.yml @@ -41,7 +41,7 @@ jobs: - name: Set up Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: - go-version-file: components/ambient-sdk/generator/go.mod + go-version-file: components/ambient-sdk/go-sdk/go.mod cache-dependency-path: components/ambient-sdk/generator/go.sum - name: Regenerate SDK from OpenAPI spec From b427581ba4cee0c70c0863969ae6dc8bbb6739c2 Mon Sep 17 00:00:00 2001 From: Kyle Squizzato Date: Mon, 29 Jun 2026 11:21:49 -0700 Subject: [PATCH 04/16] fix: address PR review feedback for agent sandbox configuration - Add origin annotations (ambient.ai/source, ambient.ai/source-namespace) to track ConfigMap-managed agents and scope pruning by namespace - Fix SQL injection in findAgentByName by escaping single quotes - Handle json.Marshal errors in configmap_reconciler and handler instead of silently discarding them - Unify main.go select blocks into a single select using nil channel pattern to eliminate dead code when gateway is enabled - Add warning log when resolveSandboxImage fails to parse sandbox_template - Add unit tests for parseAgentDeclaration and isConfigMapManaged - Update example namespace to tenant-a Co-Authored-By: Claude Opus 4.6 --- .../plugins/agents/handler.go | 32 ++- .../cmd/ambient-control-plane/main.go | 23 +- .../reconciler/configmap_reconciler.go | 85 +++++-- .../reconciler/configmap_reconciler_test.go | 207 ++++++++++++++++++ .../internal/reconciler/kube_reconciler.go | 4 +- examples/agent-sandbox-config.yaml | 12 +- 6 files changed, 307 insertions(+), 56 deletions(-) create mode 100644 components/ambient-control-plane/internal/reconciler/configmap_reconciler_test.go diff --git a/components/ambient-api-server/plugins/agents/handler.go b/components/ambient-api-server/plugins/agents/handler.go index f1eb8d270..3ac407a27 100644 --- a/components/ambient-api-server/plugins/agents/handler.go +++ b/components/ambient-api-server/plugins/agents/handler.go @@ -100,28 +100,36 @@ func (h agentHandler) Patch(w http.ResponseWriter, r *http.Request) { found.Entrypoint = patch.Entrypoint } if patch.Providers != nil { - if raw, merr := json.Marshal(patch.Providers); merr == nil { - s := string(raw) - found.Providers = &s + raw, merr := json.Marshal(patch.Providers) + if merr != nil { + return nil, errors.GeneralError("failed to marshal providers: %v", merr) } + s := string(raw) + found.Providers = &s } if patch.Payloads != nil { - if raw, merr := json.Marshal(patch.Payloads); merr == nil { - s := string(raw) - found.Payloads = &s + raw, merr := json.Marshal(patch.Payloads) + if merr != nil { + return nil, errors.GeneralError("failed to marshal payloads: %v", merr) } + s := string(raw) + found.Payloads = &s } if patch.Environment != nil { - if raw, merr := json.Marshal(patch.Environment); merr == nil { - s := string(raw) - found.Environment = &s + raw, merr := json.Marshal(patch.Environment) + if merr != nil { + return nil, errors.GeneralError("failed to marshal environment: %v", merr) } + s := string(raw) + found.Environment = &s } if patch.SandboxTemplate != nil { - if raw, merr := json.Marshal(patch.SandboxTemplate); merr == nil { - s := string(raw) - found.SandboxTemplate = &s + raw, merr := json.Marshal(patch.SandboxTemplate) + if merr != nil { + return nil, errors.GeneralError("failed to marshal sandbox_template: %v", merr) } + s := string(raw) + found.SandboxTemplate = &s } if patch.SandboxPolicy != nil { found.SandboxPolicy = patch.SandboxPolicy diff --git a/components/ambient-control-plane/cmd/ambient-control-plane/main.go b/components/ambient-control-plane/cmd/ambient-control-plane/main.go index 7373ba65c..e8a2941a7 100644 --- a/components/ambient-control-plane/cmd/ambient-control-plane/main.go +++ b/components/ambient-control-plane/cmd/ambient-control-plane/main.go @@ -259,27 +259,15 @@ func runKubeMode(ctx context.Context, cfg *config.ControlPlaneConfig) error { podSyncErrCh <- podSyncer.Run(ctx) }() + var cmSyncErrCh <-chan error if cfg.OpenShellUseGateway { cmSyncer := reconciler.NewConfigMapSyncer(factory, provisionerKube, provisioner, cfg.PlatformMode, cfg.MPPConfigNamespace, log.Logger) - cmSyncErrCh := make(chan error, 1) + ch := make(chan error, 1) go func() { - cmSyncErrCh <- cmSyncer.Run(ctx) + ch <- cmSyncer.Run(ctx) }() + cmSyncErrCh = ch log.Info().Msg("ConfigMap agent declaration syncer enabled") - - select { - case tsErr := <-tsErrCh: - if tsErr != nil { - return fmt.Errorf("token server: %w", tsErr) - } - return <-infErrCh - case infErr := <-infErrCh: - return infErr - case podSyncErr := <-podSyncErrCh: - return fmt.Errorf("pod status syncer: %w", podSyncErr) - case cmSyncErr := <-cmSyncErrCh: - return fmt.Errorf("configmap syncer: %w", cmSyncErr) - } } select { @@ -292,11 +280,12 @@ func runKubeMode(ctx context.Context, cfg *config.ControlPlaneConfig) error { return infErr case podSyncErr := <-podSyncErrCh: return fmt.Errorf("pod status syncer: %w", podSyncErr) + case cmSyncErr := <-cmSyncErrCh: + return fmt.Errorf("configmap syncer: %w", cmSyncErr) case gwErr := <-gatewayErrCh: if gwErr != nil { return fmt.Errorf("gateway provisioning: %w", gwErr) } - // Gateway provisioning exited cleanly (shouldn't happen), continue with other channels return <-infErrCh } } diff --git a/components/ambient-control-plane/internal/reconciler/configmap_reconciler.go b/components/ambient-control-plane/internal/reconciler/configmap_reconciler.go index 5a8cf0f09..d777020c6 100644 --- a/components/ambient-control-plane/internal/reconciler/configmap_reconciler.go +++ b/components/ambient-control-plane/internal/reconciler/configmap_reconciler.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "strings" "time" "github.com/ambient-code/platform/components/ambient-control-plane/internal/kubeclient" @@ -17,6 +18,9 @@ import ( const ( configMapSyncInterval = 30 * time.Second agentDeclarationLabel = "ambient.ai/kind=agent" + annotationSource = "ambient.ai/source" + annotationSourceCM = "configmap" + annotationSourceNS = "ambient.ai/source-namespace" ) type AgentDeclaration struct { @@ -169,7 +173,7 @@ func (s *ConfigMapSyncer) syncNamespaceAgents(ctx context.Context, namespace, pr } declaredAgents[decl.Name] = true - if err := s.upsertAgent(ctx, sdk, projectID, decl); err != nil { + if err := s.upsertAgent(ctx, sdk, projectID, namespace, decl); err != nil { s.logger.Warn().Err(err). Str("namespace", namespace). Str("agent", decl.Name). @@ -178,7 +182,7 @@ func (s *ConfigMapSyncer) syncNamespaceAgents(ctx context.Context, namespace, pr } } - s.pruneRemovedAgents(ctx, sdk, projectID, declaredAgents) + s.pruneRemovedAgents(ctx, sdk, projectID, namespace, declaredAgents) } func parseAgentDeclaration(yamlStr string) (*AgentDeclaration, error) { @@ -199,10 +203,31 @@ func parseAgentDeclaration(yamlStr string) (*AgentDeclaration, error) { return &decl, nil } -func (s *ConfigMapSyncer) upsertAgent(ctx context.Context, sdk *sdkclient.Client, projectID string, decl *AgentDeclaration) error { +func (s *ConfigMapSyncer) buildOriginAnnotations(namespace string, userAnnotations map[string]string) (string, error) { + merged := make(map[string]string, len(userAnnotations)+2) + for k, v := range userAnnotations { + merged[k] = v + } + merged[annotationSource] = annotationSourceCM + merged[annotationSourceNS] = namespace + raw, err := json.Marshal(merged) + if err != nil { + return "", fmt.Errorf("marshalling annotations: %w", err) + } + return string(raw), nil +} + +func (s *ConfigMapSyncer) upsertAgent(ctx context.Context, sdk *sdkclient.Client, projectID, namespace string, decl *AgentDeclaration) error { existing := s.findAgentByName(ctx, sdk, projectID, decl.Name) - patch := map[string]interface{}{} + annJSON, err := s.buildOriginAnnotations(namespace, decl.Annotations) + if err != nil { + return err + } + + patch := map[string]interface{}{ + "annotations": annJSON, + } if decl.DisplayName != "" { patch["display_name"] = decl.DisplayName } @@ -237,13 +262,12 @@ func (s *ConfigMapSyncer) upsertAgent(ctx context.Context, sdk *sdkclient.Client patch["sandbox_template"] = decl.SandboxTemplate } if len(decl.Labels) > 0 { - labelsJSON, _ := json.Marshal(decl.Labels) + labelsJSON, err := json.Marshal(decl.Labels) + if err != nil { + return fmt.Errorf("marshalling agent labels: %w", err) + } patch["labels"] = string(labelsJSON) } - if len(decl.Annotations) > 0 { - annJSON, _ := json.Marshal(decl.Annotations) - patch["annotations"] = string(annJSON) - } if existing != nil { if _, err := sdk.Agents().Update(ctx, existing.ID, patch); err != nil { @@ -261,6 +285,7 @@ func (s *ConfigMapSyncer) upsertAgent(ctx context.Context, sdk *sdkclient.Client return fmt.Errorf("building agent %s: %w", decl.Name, err) } + agent.Annotations = annJSON if decl.DisplayName != "" { agent.DisplayName = decl.DisplayName } @@ -283,24 +308,32 @@ func (s *ConfigMapSyncer) upsertAgent(ctx context.Context, sdk *sdkclient.Client agent.SandboxPolicy = decl.SandboxPolicy } if len(decl.Providers) > 0 { - if raw, err := json.Marshal(decl.Providers); err == nil { - agent.Providers = string(raw) + raw, err := json.Marshal(decl.Providers) + if err != nil { + return fmt.Errorf("marshalling providers: %w", err) } + agent.Providers = string(raw) } if len(decl.Payloads) > 0 { - if raw, err := json.Marshal(decl.Payloads); err == nil { - agent.Payloads = string(raw) + raw, err := json.Marshal(decl.Payloads) + if err != nil { + return fmt.Errorf("marshalling payloads: %w", err) } + agent.Payloads = string(raw) } if len(decl.Environment) > 0 { - if raw, err := json.Marshal(decl.Environment); err == nil { - agent.Environment = string(raw) + raw, err := json.Marshal(decl.Environment) + if err != nil { + return fmt.Errorf("marshalling environment: %w", err) } + agent.Environment = string(raw) } if decl.SandboxTemplate != nil { - if raw, err := json.Marshal(decl.SandboxTemplate); err == nil { - agent.SandboxTemplate = string(raw) + raw, err := json.Marshal(decl.SandboxTemplate) + if err != nil { + return fmt.Errorf("marshalling sandbox_template: %w", err) } + agent.SandboxTemplate = string(raw) } created, err := sdk.Agents().Create(ctx, agent) @@ -312,7 +345,8 @@ func (s *ConfigMapSyncer) upsertAgent(ctx context.Context, sdk *sdkclient.Client } func (s *ConfigMapSyncer) findAgentByName(ctx context.Context, sdk *sdkclient.Client, projectID, name string) *types.Agent { - agents, err := sdk.Agents().List(ctx, &types.ListOptions{Size: 100, Search: fmt.Sprintf("name = '%s'", name)}) + escaped := strings.ReplaceAll(name, "'", "''") + agents, err := sdk.Agents().List(ctx, &types.ListOptions{Size: 100, Search: fmt.Sprintf("name = '%s'", escaped)}) if err != nil { return nil } @@ -324,7 +358,18 @@ func (s *ConfigMapSyncer) findAgentByName(ctx context.Context, sdk *sdkclient.Cl return nil } -func (s *ConfigMapSyncer) pruneRemovedAgents(ctx context.Context, sdk *sdkclient.Client, projectID string, declaredAgents map[string]bool) { +func (s *ConfigMapSyncer) isConfigMapManaged(agent *types.Agent, namespace string) bool { + if agent.Annotations == "" { + return false + } + var ann map[string]string + if err := json.Unmarshal([]byte(agent.Annotations), &ann); err != nil { + return false + } + return ann[annotationSource] == annotationSourceCM && ann[annotationSourceNS] == namespace +} + +func (s *ConfigMapSyncer) pruneRemovedAgents(ctx context.Context, sdk *sdkclient.Client, projectID, namespace string, declaredAgents map[string]bool) { agents, err := sdk.Agents().List(ctx, &types.ListOptions{Size: 500}) if err != nil { s.logger.Warn().Err(err).Str("project_id", projectID).Msg("failed to list agents for pruning") @@ -332,7 +377,7 @@ func (s *ConfigMapSyncer) pruneRemovedAgents(ctx context.Context, sdk *sdkclient } for _, a := range agents.Items { - if a.Entrypoint != "" && !declaredAgents[a.Name] { + if s.isConfigMapManaged(&a, namespace) && !declaredAgents[a.Name] { if err := sdk.Agents().Delete(ctx, a.ID); err != nil { s.logger.Warn().Err(err).Str("agent", a.Name).Msg("failed to delete stale agent") } else { diff --git a/components/ambient-control-plane/internal/reconciler/configmap_reconciler_test.go b/components/ambient-control-plane/internal/reconciler/configmap_reconciler_test.go new file mode 100644 index 000000000..7e5394e59 --- /dev/null +++ b/components/ambient-control-plane/internal/reconciler/configmap_reconciler_test.go @@ -0,0 +1,207 @@ +package reconciler + +import ( + "encoding/json" + "testing" + + "github.com/ambient-code/platform/components/ambient-sdk/go-sdk/types" + "github.com/rs/zerolog" +) + +func TestParseAgentDeclaration(t *testing.T) { + tests := []struct { + name string + yaml string + wantErr bool + check func(t *testing.T, d *AgentDeclaration) + }{ + { + name: "minimal valid declaration", + yaml: ` +name: my-agent +`, + check: func(t *testing.T, d *AgentDeclaration) { + if d.Name != "my-agent" { + t.Errorf("Name = %q, want %q", d.Name, "my-agent") + } + }, + }, + { + name: "full declaration", + yaml: ` +name: code-reviewer +display_name: Code Reviewer +description: Reviews pull requests +prompt: Review this code +entrypoint: /usr/bin/review +repo_url: https://github.com/example/repo +llm_model: claude-sonnet-4-20250514 +sandbox_policy: restricted +providers: + - github + - jira +environment: + LOG_LEVEL: debug + TIMEOUT: "30" +payloads: + - sandbox_path: /workspace/config + content: "key: value" +sandbox_template: + image: quay.io/custom:v1 + resources: + cpu: "2" + memory: 4Gi +labels: + team: platform +annotations: + owner: alice +`, + check: func(t *testing.T, d *AgentDeclaration) { + if d.Name != "code-reviewer" { + t.Errorf("Name = %q, want %q", d.Name, "code-reviewer") + } + if d.DisplayName != "Code Reviewer" { + t.Errorf("DisplayName = %q, want %q", d.DisplayName, "Code Reviewer") + } + if d.Entrypoint != "/usr/bin/review" { + t.Errorf("Entrypoint = %q, want %q", d.Entrypoint, "/usr/bin/review") + } + if len(d.Providers) != 2 || d.Providers[0] != "github" { + t.Errorf("Providers = %v, want [github jira]", d.Providers) + } + if d.Environment["LOG_LEVEL"] != "debug" { + t.Errorf("Environment[LOG_LEVEL] = %q, want %q", d.Environment["LOG_LEVEL"], "debug") + } + if len(d.Payloads) != 1 || d.Payloads[0].SandboxPath != "/workspace/config" { + t.Errorf("Payloads[0].SandboxPath = %v, want /workspace/config", d.Payloads) + } + if d.SandboxTemplate == nil || d.SandboxTemplate.Image != "quay.io/custom:v1" { + t.Errorf("SandboxTemplate.Image = %v, want quay.io/custom:v1", d.SandboxTemplate) + } + if d.Labels["team"] != "platform" { + t.Errorf("Labels[team] = %q, want %q", d.Labels["team"], "platform") + } + }, + }, + { + name: "invalid YAML", + yaml: `{{{not yaml`, + wantErr: true, + }, + { + name: "payload missing sandbox_path", + yaml: ` +name: bad-agent +payloads: + - content: "data" +`, + wantErr: true, + }, + { + name: "payload with both content and repo_url", + yaml: ` +name: bad-agent +payloads: + - sandbox_path: /workspace + content: "data" + repo_url: https://example.com +`, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + decl, err := parseAgentDeclaration(tt.yaml) + if tt.wantErr { + if err == nil { + t.Fatal("expected error, got nil") + } + return + } + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if tt.check != nil { + tt.check(t, decl) + } + }) + } +} + +func TestIsConfigMapManaged(t *testing.T) { + syncer := &ConfigMapSyncer{ + logger: zerolog.Nop(), + } + + tests := []struct { + name string + agent *types.Agent + namespace string + want bool + }{ + { + name: "no annotations", + agent: &types.Agent{}, + namespace: "ns-1", + want: false, + }, + { + name: "configmap-managed matching namespace", + agent: &types.Agent{ + Annotations: mustJSON(map[string]string{ + annotationSource: annotationSourceCM, + annotationSourceNS: "ns-1", + }), + }, + namespace: "ns-1", + want: true, + }, + { + name: "configmap-managed different namespace", + agent: &types.Agent{ + Annotations: mustJSON(map[string]string{ + annotationSource: annotationSourceCM, + annotationSourceNS: "ns-2", + }), + }, + namespace: "ns-1", + want: false, + }, + { + name: "not configmap-managed", + agent: &types.Agent{ + Annotations: mustJSON(map[string]string{ + "some-other": "annotation", + }), + }, + namespace: "ns-1", + want: false, + }, + { + name: "invalid JSON annotations", + agent: &types.Agent{ + Annotations: "not-json", + }, + namespace: "ns-1", + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := syncer.isConfigMapManaged(tt.agent, tt.namespace) + if got != tt.want { + t.Errorf("isConfigMapManaged() = %v, want %v", got, tt.want) + } + }) + } +} + +func mustJSON(v interface{}) string { + raw, err := json.Marshal(v) + if err != nil { + panic(err) + } + return string(raw) +} diff --git a/components/ambient-control-plane/internal/reconciler/kube_reconciler.go b/components/ambient-control-plane/internal/reconciler/kube_reconciler.go index 863269864..ab05bf82e 100644 --- a/components/ambient-control-plane/internal/reconciler/kube_reconciler.go +++ b/components/ambient-control-plane/internal/reconciler/kube_reconciler.go @@ -395,7 +395,9 @@ func (r *SimpleKubeReconciler) resolveSandboxImage(agent *types.Agent) string { var tpl struct { Image string `json:"image"` } - if err := json.Unmarshal([]byte(agent.SandboxTemplate), &tpl); err == nil && tpl.Image != "" { + if err := json.Unmarshal([]byte(agent.SandboxTemplate), &tpl); err != nil { + r.logger.Warn().Err(err).Str("agent", agent.Name).Msg("failed to parse sandbox_template JSON, using default image") + } else if tpl.Image != "" { return tpl.Image } } diff --git a/examples/agent-sandbox-config.yaml b/examples/agent-sandbox-config.yaml index 28804d954..151e4f488 100644 --- a/examples/agent-sandbox-config.yaml +++ b/examples/agent-sandbox-config.yaml @@ -1,20 +1,20 @@ # Agent Sandbox Configuration Example # # Complete example of ConfigMap-based agent, provider, and policy declarations. -# Apply to a tenant namespace (e.g. "alpha") with: kubectl apply -f agent-sandbox-config.yaml +# Apply to a tenant namespace (e.g. "tenant-a") with: kubectl apply -f agent-sandbox-config.yaml # # Prerequisites: # - OPENSHELL_USE_GATEWAY=true on the control plane # - Secrets referenced by providers must exist in the namespace before applying: -# kubectl create secret generic github-pat --from-literal=token= -n alpha -# kubectl create secret generic anthropic-key --from-literal=token= -n alpha +# kubectl create secret generic github-pat --from-literal=token= -n tenant-a +# kubectl create secret generic anthropic-key --from-literal=token= -n tenant-a # - The namespace must correspond to an ACP project --- apiVersion: v1 kind: ConfigMap metadata: name: provider-declarations - namespace: alpha + namespace: tenant-a labels: ambient.ai/kind: provider data: @@ -31,7 +31,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: policy-declarations - namespace: alpha + namespace: tenant-a labels: ambient.ai/kind: policy data: @@ -88,7 +88,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: agent-declarations - namespace: alpha + namespace: tenant-a labels: ambient.ai/kind: agent data: From e57c4859ef834e1b128537902251e53678972d79 Mon Sep 17 00:00:00 2001 From: Kyle Squizzato Date: Mon, 29 Jun 2026 14:31:23 -0700 Subject: [PATCH 05/16] feat: add provider/policy API endpoints, SDK types, and UI wiring Implements full-stack provider and policy support: OpenAPI specs, API server plugins (CRUD endpoints), SDK generation for Go/Python/TS, ConfigMap reconciler for provider/policy declarations, and UI adapters using the TS SDK with React Query hooks. Renames ConfigMap terminology to GitOps in the UI per views spec. Merges sandbox config into a table-driven Configuration card and adds payload support to the Generate YAML form. Co-Authored-By: Claude Opus 4.6 --- Makefile | 2 + .../cmd/ambient-api-server/main.go | 2 + .../openapi/openapi.policies.yaml | 319 ++++ .../openapi/openapi.providers.yaml | 322 ++++ .../ambient-api-server/openapi/openapi.yaml | 20 + .../pkg/api/openapi/.openapi-generator/FILES | 12 + .../pkg/api/openapi/README.md | 16 + .../pkg/api/openapi/api/openapi.yaml | 828 +++++++++ .../pkg/api/openapi/api_default.go | 1654 +++++++++++++++++ .../pkg/api/openapi/docs/DefaultAPI.md | 732 ++++++++ .../pkg/api/openapi/docs/Policy.md | 306 +++ .../pkg/api/openapi/docs/PolicyList.md | 135 ++ .../api/openapi/docs/PolicyPatchRequest.md | 160 ++ .../pkg/api/openapi/docs/Provider.md | 332 ++++ .../pkg/api/openapi/docs/ProviderList.md | 135 ++ .../api/openapi/docs/ProviderPatchRequest.md | 186 ++ .../pkg/api/openapi/model_policy.go | 514 +++++ .../pkg/api/openapi/model_policy_list.go | 269 +++ .../api/openapi/model_policy_patch_request.go | 269 +++ .../pkg/api/openapi/model_provider.go | 551 ++++++ .../pkg/api/openapi/model_provider_list.go | 269 +++ .../openapi/model_provider_patch_request.go | 305 +++ .../plugins/policies/dao.go | 81 + .../plugins/policies/handler.go | 176 ++ .../plugins/policies/migration.go | 41 + .../plugins/policies/model.go | 24 + .../plugins/policies/plugin.go | 88 + .../plugins/policies/presenter.go | 64 + .../plugins/policies/service.go | 137 ++ .../plugins/providers/dao.go | 81 + .../plugins/providers/handler.go | 173 ++ .../plugins/providers/migration.go | 42 + .../plugins/providers/model.go | 25 + .../plugins/providers/plugin.go | 88 + .../plugins/providers/presenter.go | 50 + .../plugins/providers/service.go | 137 ++ .../reconciler/configmap_reconciler.go | 434 ++++- .../reconciler/configmap_reconciler_test.go | 141 +- .../ambient-sdk/go-sdk/client/agent_api.go | 4 +- .../ambient-sdk/go-sdk/client/client.go | 4 +- .../go-sdk/client/credential_api.go | 4 +- .../go-sdk/client/inbox_message_api.go | 4 +- .../ambient-sdk/go-sdk/client/iterator.go | 4 +- .../ambient-sdk/go-sdk/client/policy_api.go | 79 + .../ambient-sdk/go-sdk/client/project_api.go | 4 +- .../go-sdk/client/project_settings_api.go | 4 +- .../ambient-sdk/go-sdk/client/provider_api.go | 79 + .../ambient-sdk/go-sdk/client/role_api.go | 4 +- .../go-sdk/client/role_binding_api.go | 4 +- .../go-sdk/client/scheduled_session_api.go | 4 +- .../ambient-sdk/go-sdk/client/session_api.go | 4 +- .../go-sdk/client/session_message_api.go | 4 +- .../ambient-sdk/go-sdk/client/user_api.go | 4 +- components/ambient-sdk/go-sdk/types/agent.go | 4 +- components/ambient-sdk/go-sdk/types/base.go | 4 +- .../ambient-sdk/go-sdk/types/credential.go | 4 +- .../ambient-sdk/go-sdk/types/inbox_message.go | 4 +- .../ambient-sdk/go-sdk/types/list_options.go | 4 +- components/ambient-sdk/go-sdk/types/policy.go | 121 ++ .../ambient-sdk/go-sdk/types/project.go | 4 +- .../go-sdk/types/project_settings.go | 4 +- .../ambient-sdk/go-sdk/types/provider.go | 132 ++ components/ambient-sdk/go-sdk/types/role.go | 4 +- .../ambient-sdk/go-sdk/types/role_binding.go | 4 +- .../go-sdk/types/scheduled_session.go | 4 +- .../ambient-sdk/go-sdk/types/session.go | 4 +- .../go-sdk/types/session_message.go | 4 +- components/ambient-sdk/go-sdk/types/user.go | 4 +- .../python-sdk/ambient_platform/__init__.py | 10 +- .../python-sdk/ambient_platform/_agent_api.py | 4 +- .../python-sdk/ambient_platform/_base.py | 4 +- .../ambient_platform/_credential_api.py | 4 +- .../ambient_platform/_inbox_message_api.py | 4 +- .../python-sdk/ambient_platform/_iterator.py | 4 +- .../ambient_platform/_policy_api.py | 52 + .../ambient_platform/_project_api.py | 4 +- .../ambient_platform/_project_settings_api.py | 4 +- .../ambient_platform/_provider_api.py | 52 + .../python-sdk/ambient_platform/_role_api.py | 4 +- .../ambient_platform/_role_binding_api.py | 4 +- .../_scheduled_session_api.py | 4 +- .../ambient_platform/_session_api.py | 4 +- .../ambient_platform/_session_message_api.py | 4 +- .../python-sdk/ambient_platform/_user_api.py | 4 +- .../python-sdk/ambient_platform/agent.py | 4 +- .../python-sdk/ambient_platform/client.py | 22 +- .../python-sdk/ambient_platform/credential.py | 4 +- .../ambient_platform/inbox_message.py | 4 +- .../python-sdk/ambient_platform/policy.py | 132 ++ .../python-sdk/ambient_platform/project.py | 4 +- .../ambient_platform/project_settings.py | 4 +- .../python-sdk/ambient_platform/provider.py | 142 ++ .../python-sdk/ambient_platform/role.py | 4 +- .../ambient_platform/role_binding.py | 4 +- .../ambient_platform/scheduled_session.py | 4 +- .../python-sdk/ambient_platform/session.py | 4 +- .../ambient_platform/session_message.py | 4 +- .../python-sdk/ambient_platform/user.py | 4 +- components/ambient-sdk/ts-sdk/src/agent.ts | 4 +- .../ambient-sdk/ts-sdk/src/agent_api.ts | 4 +- components/ambient-sdk/ts-sdk/src/base.ts | 4 +- components/ambient-sdk/ts-sdk/src/client.ts | 10 +- .../ambient-sdk/ts-sdk/src/credential.ts | 4 +- .../ambient-sdk/ts-sdk/src/credential_api.ts | 4 +- .../ambient-sdk/ts-sdk/src/inbox_message.ts | 4 +- .../ts-sdk/src/inbox_message_api.ts | 4 +- components/ambient-sdk/ts-sdk/src/index.ts | 12 +- components/ambient-sdk/ts-sdk/src/policy.ts | 115 ++ .../ambient-sdk/ts-sdk/src/policy_api.ts | 53 + components/ambient-sdk/ts-sdk/src/project.ts | 4 +- .../ambient-sdk/ts-sdk/src/project_api.ts | 4 +- .../ts-sdk/src/project_settings.ts | 4 +- .../ts-sdk/src/project_settings_api.ts | 4 +- components/ambient-sdk/ts-sdk/src/provider.ts | 128 ++ .../ambient-sdk/ts-sdk/src/provider_api.ts | 53 + components/ambient-sdk/ts-sdk/src/role.ts | 4 +- components/ambient-sdk/ts-sdk/src/role_api.ts | 4 +- .../ambient-sdk/ts-sdk/src/role_binding.ts | 4 +- .../ts-sdk/src/role_binding_api.ts | 4 +- .../ts-sdk/src/scheduled_session.ts | 4 +- .../ts-sdk/src/scheduled_session_api.ts | 4 +- components/ambient-sdk/ts-sdk/src/session.ts | 4 +- .../ambient-sdk/ts-sdk/src/session_api.ts | 4 +- .../ambient-sdk/ts-sdk/src/session_message.ts | 4 +- .../ts-sdk/src/session_message_api.ts | 4 +- components/ambient-sdk/ts-sdk/src/user.ts | 4 +- components/ambient-sdk/ts-sdk/src/user_api.ts | 4 +- components/ambient-ui/Dockerfile | 3 + components/ambient-ui/src/adapters/index.ts | 2 + components/ambient-ui/src/adapters/mappers.ts | 142 +- .../ambient-ui/src/adapters/sdk-policies.ts | 78 + .../ambient-ui/src/adapters/sdk-providers.ts | 60 + .../_components/agent-config-tab.tsx | 52 +- .../[agentId]/_components/agent-header.tsx | 67 +- .../_components/agent-manifest-tab.tsx | 585 ++++-- .../_components/agent-overview-tab.tsx | 188 +- .../_components/configmap-summary-bar.tsx | 33 + .../_components/configmap-yaml-preview.tsx | 60 + .../agents/_components/create-agent-sheet.tsx | 136 +- .../agents/_components/lifecycle-badge.tsx | 16 +- .../_components/sandbox-config-fields.tsx | 294 +++ .../(dashboard)/[projectId]/agents/page.tsx | 20 +- .../policies/_components/policies-table.tsx | 36 + .../(dashboard)/[projectId]/policies/page.tsx | 63 + .../providers/_components/providers-table.tsx | 39 + .../[projectId]/providers/page.tsx | 63 + .../ambient-ui/src/components/app-sidebar.tsx | 21 +- components/ambient-ui/src/domain/types.ts | 25 + .../src/lib/__tests__/agent-yaml.test.ts | 218 +++ components/ambient-ui/src/lib/agent-yaml.ts | 175 ++ .../ambient-ui/src/lib/use-gateway-mode.ts | 3 + components/ambient-ui/src/ports/index.ts | 2 + components/ambient-ui/src/ports/policies.ts | 6 + components/ambient-ui/src/ports/providers.ts | 6 + .../ambient-ui/src/queries/query-keys.ts | 18 + .../ambient-ui/src/queries/use-policies.ts | 40 + .../ambient-ui/src/queries/use-providers.ts | 40 + .../base/rbac/control-plane-clusterrole.yaml | 4 + scripts/setup-kind-openshell.sh | 1 + 159 files changed, 12401 insertions(+), 699 deletions(-) create mode 100644 components/ambient-api-server/openapi/openapi.policies.yaml create mode 100644 components/ambient-api-server/openapi/openapi.providers.yaml create mode 100644 components/ambient-api-server/pkg/api/openapi/docs/Policy.md create mode 100644 components/ambient-api-server/pkg/api/openapi/docs/PolicyList.md create mode 100644 components/ambient-api-server/pkg/api/openapi/docs/PolicyPatchRequest.md create mode 100644 components/ambient-api-server/pkg/api/openapi/docs/Provider.md create mode 100644 components/ambient-api-server/pkg/api/openapi/docs/ProviderList.md create mode 100644 components/ambient-api-server/pkg/api/openapi/docs/ProviderPatchRequest.md create mode 100644 components/ambient-api-server/pkg/api/openapi/model_policy.go create mode 100644 components/ambient-api-server/pkg/api/openapi/model_policy_list.go create mode 100644 components/ambient-api-server/pkg/api/openapi/model_policy_patch_request.go create mode 100644 components/ambient-api-server/pkg/api/openapi/model_provider.go create mode 100644 components/ambient-api-server/pkg/api/openapi/model_provider_list.go create mode 100644 components/ambient-api-server/pkg/api/openapi/model_provider_patch_request.go create mode 100644 components/ambient-api-server/plugins/policies/dao.go create mode 100644 components/ambient-api-server/plugins/policies/handler.go create mode 100644 components/ambient-api-server/plugins/policies/migration.go create mode 100644 components/ambient-api-server/plugins/policies/model.go create mode 100644 components/ambient-api-server/plugins/policies/plugin.go create mode 100644 components/ambient-api-server/plugins/policies/presenter.go create mode 100644 components/ambient-api-server/plugins/policies/service.go create mode 100644 components/ambient-api-server/plugins/providers/dao.go create mode 100644 components/ambient-api-server/plugins/providers/handler.go create mode 100644 components/ambient-api-server/plugins/providers/migration.go create mode 100644 components/ambient-api-server/plugins/providers/model.go create mode 100644 components/ambient-api-server/plugins/providers/plugin.go create mode 100644 components/ambient-api-server/plugins/providers/presenter.go create mode 100644 components/ambient-api-server/plugins/providers/service.go create mode 100644 components/ambient-sdk/go-sdk/client/policy_api.go create mode 100644 components/ambient-sdk/go-sdk/client/provider_api.go create mode 100644 components/ambient-sdk/go-sdk/types/policy.go create mode 100644 components/ambient-sdk/go-sdk/types/provider.go create mode 100644 components/ambient-sdk/python-sdk/ambient_platform/_policy_api.py create mode 100644 components/ambient-sdk/python-sdk/ambient_platform/_provider_api.py create mode 100644 components/ambient-sdk/python-sdk/ambient_platform/policy.py create mode 100644 components/ambient-sdk/python-sdk/ambient_platform/provider.py create mode 100644 components/ambient-sdk/ts-sdk/src/policy.ts create mode 100644 components/ambient-sdk/ts-sdk/src/policy_api.ts create mode 100644 components/ambient-sdk/ts-sdk/src/provider.ts create mode 100644 components/ambient-sdk/ts-sdk/src/provider_api.ts create mode 100644 components/ambient-ui/src/adapters/sdk-policies.ts create mode 100644 components/ambient-ui/src/adapters/sdk-providers.ts create mode 100644 components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/configmap-summary-bar.tsx create mode 100644 components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/configmap-yaml-preview.tsx create mode 100644 components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/sandbox-config-fields.tsx create mode 100644 components/ambient-ui/src/app/(dashboard)/[projectId]/policies/_components/policies-table.tsx create mode 100644 components/ambient-ui/src/app/(dashboard)/[projectId]/policies/page.tsx create mode 100644 components/ambient-ui/src/app/(dashboard)/[projectId]/providers/_components/providers-table.tsx create mode 100644 components/ambient-ui/src/app/(dashboard)/[projectId]/providers/page.tsx create mode 100644 components/ambient-ui/src/lib/__tests__/agent-yaml.test.ts create mode 100644 components/ambient-ui/src/lib/agent-yaml.ts create mode 100644 components/ambient-ui/src/lib/use-gateway-mode.ts create mode 100644 components/ambient-ui/src/ports/policies.ts create mode 100644 components/ambient-ui/src/ports/providers.ts create mode 100644 components/ambient-ui/src/queries/use-policies.ts create mode 100644 components/ambient-ui/src/queries/use-providers.ts diff --git a/Makefile b/Makefile index da727de43..71d74294e 100755 --- a/Makefile +++ b/Makefile @@ -195,6 +195,7 @@ build-ambient-ui: ## Build ambient-ui image @cd components && $(CONTAINER_ENGINE) build $(PLATFORM_FLAG) $(BUILD_FLAGS) \ -f ambient-ui/Dockerfile \ --build-arg GIT_COMMIT=$(shell git rev-parse HEAD) \ + --build-arg OPENSHELL_USE_GATEWAY=$(OPENSHELL_USE_GATEWAY) \ -t $(AMBIENT_UI_IMAGE) . @echo "$(COLOR_GREEN)✓$(COLOR_RESET) Ambient UI built: $(AMBIENT_UI_IMAGE)" @@ -1107,6 +1108,7 @@ kind-reload-ambient-ui: check-kind check-kubectl check-local-context ## Rebuild @cd components && $(CONTAINER_ENGINE) build $(PLATFORM_FLAG) \ -f ambient-ui/Dockerfile \ --build-arg GIT_COMMIT=$(shell git rev-parse HEAD) \ + --build-arg OPENSHELL_USE_GATEWAY=$(OPENSHELL_USE_GATEWAY) \ -t $(AMBIENT_UI_IMAGE) . $(QUIET_REDIRECT) $(call kind-reload-component,$(AMBIENT_UI_IMAGE),ambient-ui,Ambient UI,ambient-ui) diff --git a/components/ambient-api-server/cmd/ambient-api-server/main.go b/components/ambient-api-server/cmd/ambient-api-server/main.go index 8f050cd25..822379f9a 100755 --- a/components/ambient-api-server/cmd/ambient-api-server/main.go +++ b/components/ambient-api-server/cmd/ambient-api-server/main.go @@ -18,8 +18,10 @@ import ( _ "github.com/ambient-code/platform/components/ambient-api-server/plugins/agents" _ "github.com/ambient-code/platform/components/ambient-api-server/plugins/credentials" _ "github.com/ambient-code/platform/components/ambient-api-server/plugins/inbox" + _ "github.com/ambient-code/platform/components/ambient-api-server/plugins/policies" _ "github.com/ambient-code/platform/components/ambient-api-server/plugins/projectSettings" _ "github.com/ambient-code/platform/components/ambient-api-server/plugins/projects" + _ "github.com/ambient-code/platform/components/ambient-api-server/plugins/providers" _ "github.com/ambient-code/platform/components/ambient-api-server/plugins/proxy" _ "github.com/ambient-code/platform/components/ambient-api-server/plugins/rbac" _ "github.com/ambient-code/platform/components/ambient-api-server/plugins/roleBindings" diff --git a/components/ambient-api-server/openapi/openapi.policies.yaml b/components/ambient-api-server/openapi/openapi.policies.yaml new file mode 100644 index 000000000..a7faed911 --- /dev/null +++ b/components/ambient-api-server/openapi/openapi.policies.yaml @@ -0,0 +1,319 @@ +paths: + /api/ambient/v1/projects/{id}/policies: + get: + summary: Returns a list of policies in a project + security: + - Bearer: [] + responses: + '200': + description: A JSON array of policy objects + content: + application/json: + schema: + $ref: '#/components/schemas/PolicyList' + '401': + description: Auth token is invalid + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '403': + description: Unauthorized to perform operation + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '404': + description: No project with specified id exists + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '500': + description: Unexpected error occurred + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + parameters: + - $ref: '#/components/parameters/page' + - $ref: '#/components/parameters/size' + - $ref: '#/components/parameters/search' + - $ref: '#/components/parameters/orderBy' + - $ref: '#/components/parameters/fields' + post: + summary: Create a policy in a project (internal — used by control plane reconciler) + security: + - Bearer: [] + requestBody: + description: Policy data + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Policy' + responses: + '201': + description: Created + content: + application/json: + schema: + $ref: '#/components/schemas/Policy' + '400': + description: Validation errors occurred + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '401': + description: Auth token is invalid + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '403': + description: Unauthorized to perform operation + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '409': + description: Policy already exists in this project + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '500': + description: An unexpected error occurred creating the policy + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + parameters: + - $ref: '#/components/parameters/id' + /api/ambient/v1/projects/{id}/policies/{policy_id}: + get: + summary: Get a policy by id + security: + - Bearer: [] + responses: + '200': + description: Policy found by id + content: + application/json: + schema: + $ref: '#/components/schemas/Policy' + '401': + description: Auth token is invalid + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '403': + description: Unauthorized to perform operation + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '404': + description: No policy with specified id exists + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '500': + description: Unexpected error occurred + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + patch: + summary: Update a policy (internal — used by control plane reconciler) + security: + - Bearer: [] + requestBody: + description: Updated policy data + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PolicyPatchRequest' + responses: + '200': + description: Policy updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Policy' + '400': + description: Validation errors occurred + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '401': + description: Auth token is invalid + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '403': + description: Unauthorized to perform operation + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '404': + description: No policy with specified id exists + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '500': + description: Unexpected error updating policy + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + delete: + summary: Delete a policy from a project (internal — used by control plane reconciler) + security: + - Bearer: [] + responses: + '204': + description: Policy deleted successfully + '401': + description: Auth token is invalid + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '403': + description: Unauthorized to perform operation + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '404': + description: No policy with specified id exists + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '500': + description: Unexpected error occurred + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + parameters: + - $ref: '#/components/parameters/id' + - name: policy_id + in: path + description: The id of the policy + required: true + schema: + type: string +components: + schemas: + Policy: + allOf: + - $ref: 'openapi.yaml#/components/schemas/ObjectReference' + - type: object + required: + - project_id + - name + properties: + project_id: + type: string + description: The project this policy belongs to + name: + type: string + description: Human-readable identifier; unique within the project + namespace: + type: string + description: Source namespace where this policy was declared + spec: + type: object + additionalProperties: true + description: Full policy specification (network_policies, filesystem, process, landlock) + labels: + type: string + annotations: + type: string + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + PolicyList: + allOf: + - $ref: 'openapi.yaml#/components/schemas/List' + - type: object + properties: + items: + type: array + items: + $ref: '#/components/schemas/Policy' + PolicyPatchRequest: + type: object + properties: + name: + type: string + namespace: + type: string + spec: + type: object + additionalProperties: true + labels: + type: string + annotations: + type: string + parameters: + id: + name: id + in: path + description: The id of the project + required: true + schema: + type: string + page: + name: page + in: query + description: Page number of record list when record list exceeds specified page size + schema: + type: integer + default: 1 + minimum: 1 + required: false + size: + name: size + in: query + description: Maximum number of records to return + schema: + type: integer + default: 100 + minimum: 0 + required: false + search: + name: search + in: query + required: false + description: Specifies the search criteria + schema: + type: string + orderBy: + name: orderBy + in: query + required: false + description: Specifies the order by criteria + schema: + type: string + fields: + name: fields + in: query + required: false + description: Supplies a comma-separated list of fields to be returned + schema: + type: string diff --git a/components/ambient-api-server/openapi/openapi.providers.yaml b/components/ambient-api-server/openapi/openapi.providers.yaml new file mode 100644 index 000000000..f1f8c6b5f --- /dev/null +++ b/components/ambient-api-server/openapi/openapi.providers.yaml @@ -0,0 +1,322 @@ +paths: + /api/ambient/v1/projects/{id}/providers: + get: + summary: Returns a list of providers in a project + security: + - Bearer: [] + responses: + '200': + description: A JSON array of provider objects + content: + application/json: + schema: + $ref: '#/components/schemas/ProviderList' + '401': + description: Auth token is invalid + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '403': + description: Unauthorized to perform operation + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '404': + description: No project with specified id exists + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '500': + description: Unexpected error occurred + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + parameters: + - $ref: '#/components/parameters/page' + - $ref: '#/components/parameters/size' + - $ref: '#/components/parameters/search' + - $ref: '#/components/parameters/orderBy' + - $ref: '#/components/parameters/fields' + post: + summary: Create a provider in a project (internal — used by control plane reconciler) + security: + - Bearer: [] + requestBody: + description: Provider data + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Provider' + responses: + '201': + description: Created + content: + application/json: + schema: + $ref: '#/components/schemas/Provider' + '400': + description: Validation errors occurred + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '401': + description: Auth token is invalid + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '403': + description: Unauthorized to perform operation + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '409': + description: Provider already exists in this project + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '500': + description: An unexpected error occurred creating the provider + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + parameters: + - $ref: '#/components/parameters/id' + /api/ambient/v1/projects/{id}/providers/{provider_id}: + get: + summary: Get a provider by id + security: + - Bearer: [] + responses: + '200': + description: Provider found by id + content: + application/json: + schema: + $ref: '#/components/schemas/Provider' + '401': + description: Auth token is invalid + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '403': + description: Unauthorized to perform operation + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '404': + description: No provider with specified id exists + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '500': + description: Unexpected error occurred + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + patch: + summary: Update a provider (internal — used by control plane reconciler) + security: + - Bearer: [] + requestBody: + description: Updated provider data + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ProviderPatchRequest' + responses: + '200': + description: Provider updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Provider' + '400': + description: Validation errors occurred + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '401': + description: Auth token is invalid + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '403': + description: Unauthorized to perform operation + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '404': + description: No provider with specified id exists + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '500': + description: Unexpected error updating provider + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + delete: + summary: Delete a provider from a project (internal — used by control plane reconciler) + security: + - Bearer: [] + responses: + '204': + description: Provider deleted successfully + '401': + description: Auth token is invalid + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '403': + description: Unauthorized to perform operation + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '404': + description: No provider with specified id exists + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + '500': + description: Unexpected error occurred + content: + application/json: + schema: + $ref: 'openapi.yaml#/components/schemas/Error' + parameters: + - $ref: '#/components/parameters/id' + - name: provider_id + in: path + description: The id of the provider + required: true + schema: + type: string +components: + schemas: + Provider: + allOf: + - $ref: 'openapi.yaml#/components/schemas/ObjectReference' + - type: object + required: + - project_id + - name + properties: + project_id: + type: string + description: The project this provider belongs to + name: + type: string + description: Human-readable identifier; unique within the project + type: + type: string + description: Provider type (e.g., github, anthropic, jira) + secret: + type: string + description: Name of the Kubernetes Secret containing credentials for this provider + namespace: + type: string + description: Source namespace where this provider was declared + labels: + type: string + annotations: + type: string + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + ProviderList: + allOf: + - $ref: 'openapi.yaml#/components/schemas/List' + - type: object + properties: + items: + type: array + items: + $ref: '#/components/schemas/Provider' + ProviderPatchRequest: + type: object + properties: + name: + type: string + type: + type: string + secret: + type: string + namespace: + type: string + labels: + type: string + annotations: + type: string + parameters: + id: + name: id + in: path + description: The id of the project + required: true + schema: + type: string + page: + name: page + in: query + description: Page number of record list when record list exceeds specified page size + schema: + type: integer + default: 1 + minimum: 1 + required: false + size: + name: size + in: query + description: Maximum number of records to return + schema: + type: integer + default: 100 + minimum: 0 + required: false + search: + name: search + in: query + required: false + description: Specifies the search criteria + schema: + type: string + orderBy: + name: orderBy + in: query + required: false + description: Specifies the order by criteria + schema: + type: string + fields: + name: fields + in: query + required: false + description: Supplies a comma-separated list of fields to be returned + schema: + type: string diff --git a/components/ambient-api-server/openapi/openapi.yaml b/components/ambient-api-server/openapi/openapi.yaml index a8e9b89fc..70dbd5eed 100755 --- a/components/ambient-api-server/openapi/openapi.yaml +++ b/components/ambient-api-server/openapi/openapi.yaml @@ -88,6 +88,14 @@ paths: $ref: 'openapi.scheduledSessions.yaml#/paths/~1api~1ambient~1v1~1projects~1{id}~1scheduled-sessions~1{ss_id}~1trigger' /api/ambient/v1/projects/{id}/scheduled-sessions/{ss_id}/runs: $ref: 'openapi.scheduledSessions.yaml#/paths/~1api~1ambient~1v1~1projects~1{id}~1scheduled-sessions~1{ss_id}~1runs' + /api/ambient/v1/projects/{id}/providers: + $ref: 'openapi.providers.yaml#/paths/~1api~1ambient~1v1~1projects~1{id}~1providers' + /api/ambient/v1/projects/{id}/providers/{provider_id}: + $ref: 'openapi.providers.yaml#/paths/~1api~1ambient~1v1~1projects~1{id}~1providers~1{provider_id}' + /api/ambient/v1/projects/{id}/policies: + $ref: 'openapi.policies.yaml#/paths/~1api~1ambient~1v1~1projects~1{id}~1policies' + /api/ambient/v1/projects/{id}/policies/{policy_id}: + $ref: 'openapi.policies.yaml#/paths/~1api~1ambient~1v1~1projects~1{id}~1policies~1{policy_id}' # AUTO-ADD NEW PATHS components: securitySchemes: @@ -247,6 +255,18 @@ components: $ref: 'openapi.scheduledSessions.yaml#/components/schemas/ScheduledSessionList' ScheduledSessionPatchRequest: $ref: 'openapi.scheduledSessions.yaml#/components/schemas/ScheduledSessionPatchRequest' + Provider: + $ref: 'openapi.providers.yaml#/components/schemas/Provider' + ProviderList: + $ref: 'openapi.providers.yaml#/components/schemas/ProviderList' + ProviderPatchRequest: + $ref: 'openapi.providers.yaml#/components/schemas/ProviderPatchRequest' + Policy: + $ref: 'openapi.policies.yaml#/components/schemas/Policy' + PolicyList: + $ref: 'openapi.policies.yaml#/components/schemas/PolicyList' + PolicyPatchRequest: + $ref: 'openapi.policies.yaml#/components/schemas/PolicyPatchRequest' # AUTO-ADD NEW SCHEMAS parameters: id: diff --git a/components/ambient-api-server/pkg/api/openapi/.openapi-generator/FILES b/components/ambient-api-server/pkg/api/openapi/.openapi-generator/FILES index 79748a886..2d88a0e48 100644 --- a/components/ambient-api-server/pkg/api/openapi/.openapi-generator/FILES +++ b/components/ambient-api-server/pkg/api/openapi/.openapi-generator/FILES @@ -23,6 +23,9 @@ docs/InboxMessagePatchRequest.md docs/List.md docs/ObjectReference.md docs/Payload.md +docs/Policy.md +docs/PolicyList.md +docs/PolicyPatchRequest.md docs/Project.md docs/ProjectHome.md docs/ProjectHomeAgent.md @@ -31,6 +34,9 @@ docs/ProjectPatchRequest.md docs/ProjectSettings.md docs/ProjectSettingsList.md docs/ProjectSettingsPatchRequest.md +docs/Provider.md +docs/ProviderList.md +docs/ProviderPatchRequest.md docs/ResourceRequirements.md docs/Role.md docs/RoleBinding.md @@ -72,6 +78,9 @@ model_inbox_message_patch_request.go model_list.go model_object_reference.go model_payload.go +model_policy.go +model_policy_list.go +model_policy_patch_request.go model_project.go model_project_home.go model_project_home_agent.go @@ -80,6 +89,9 @@ model_project_patch_request.go model_project_settings.go model_project_settings_list.go model_project_settings_patch_request.go +model_provider.go +model_provider_list.go +model_provider_patch_request.go model_resource_requirements.go model_role.go model_role_binding.go diff --git a/components/ambient-api-server/pkg/api/openapi/README.md b/components/ambient-api-server/pkg/api/openapi/README.md index c2a30b0d6..78ed581c9 100644 --- a/components/ambient-api-server/pkg/api/openapi/README.md +++ b/components/ambient-api-server/pkg/api/openapi/README.md @@ -112,6 +112,16 @@ Class | Method | HTTP request | Description *DefaultAPI* | [**ApiAmbientV1ProjectsIdGet**](docs/DefaultAPI.md#apiambientv1projectsidget) | **Get** /api/ambient/v1/projects/{id} | Get a project by id *DefaultAPI* | [**ApiAmbientV1ProjectsIdHomeGet**](docs/DefaultAPI.md#apiambientv1projectsidhomeget) | **Get** /api/ambient/v1/projects/{id}/home | Project home — latest status for every Agent in this project *DefaultAPI* | [**ApiAmbientV1ProjectsIdPatch**](docs/DefaultAPI.md#apiambientv1projectsidpatch) | **Patch** /api/ambient/v1/projects/{id} | Update a project +*DefaultAPI* | [**ApiAmbientV1ProjectsIdPoliciesGet**](docs/DefaultAPI.md#apiambientv1projectsidpoliciesget) | **Get** /api/ambient/v1/projects/{id}/policies | Returns a list of policies in a project +*DefaultAPI* | [**ApiAmbientV1ProjectsIdPoliciesPolicyIdDelete**](docs/DefaultAPI.md#apiambientv1projectsidpoliciespolicyiddelete) | **Delete** /api/ambient/v1/projects/{id}/policies/{policy_id} | Delete a policy from a project (internal — used by control plane reconciler) +*DefaultAPI* | [**ApiAmbientV1ProjectsIdPoliciesPolicyIdGet**](docs/DefaultAPI.md#apiambientv1projectsidpoliciespolicyidget) | **Get** /api/ambient/v1/projects/{id}/policies/{policy_id} | Get a policy by id +*DefaultAPI* | [**ApiAmbientV1ProjectsIdPoliciesPolicyIdPatch**](docs/DefaultAPI.md#apiambientv1projectsidpoliciespolicyidpatch) | **Patch** /api/ambient/v1/projects/{id}/policies/{policy_id} | Update a policy (internal — used by control plane reconciler) +*DefaultAPI* | [**ApiAmbientV1ProjectsIdPoliciesPost**](docs/DefaultAPI.md#apiambientv1projectsidpoliciespost) | **Post** /api/ambient/v1/projects/{id}/policies | Create a policy in a project (internal — used by control plane reconciler) +*DefaultAPI* | [**ApiAmbientV1ProjectsIdProvidersGet**](docs/DefaultAPI.md#apiambientv1projectsidprovidersget) | **Get** /api/ambient/v1/projects/{id}/providers | Returns a list of providers in a project +*DefaultAPI* | [**ApiAmbientV1ProjectsIdProvidersPost**](docs/DefaultAPI.md#apiambientv1projectsidproviderspost) | **Post** /api/ambient/v1/projects/{id}/providers | Create a provider in a project (internal — used by control plane reconciler) +*DefaultAPI* | [**ApiAmbientV1ProjectsIdProvidersProviderIdDelete**](docs/DefaultAPI.md#apiambientv1projectsidprovidersprovideriddelete) | **Delete** /api/ambient/v1/projects/{id}/providers/{provider_id} | Delete a provider from a project (internal — used by control plane reconciler) +*DefaultAPI* | [**ApiAmbientV1ProjectsIdProvidersProviderIdGet**](docs/DefaultAPI.md#apiambientv1projectsidprovidersprovideridget) | **Get** /api/ambient/v1/projects/{id}/providers/{provider_id} | Get a provider by id +*DefaultAPI* | [**ApiAmbientV1ProjectsIdProvidersProviderIdPatch**](docs/DefaultAPI.md#apiambientv1projectsidprovidersprovideridpatch) | **Patch** /api/ambient/v1/projects/{id}/providers/{provider_id} | Update a provider (internal — used by control plane reconciler) *DefaultAPI* | [**ApiAmbientV1ProjectsIdScheduledSessionsGet**](docs/DefaultAPI.md#apiambientv1projectsidscheduledsessionsget) | **Get** /api/ambient/v1/projects/{id}/scheduled-sessions | Returns a list of scheduled sessions in a project *DefaultAPI* | [**ApiAmbientV1ProjectsIdScheduledSessionsPost**](docs/DefaultAPI.md#apiambientv1projectsidscheduledsessionspost) | **Post** /api/ambient/v1/projects/{id}/scheduled-sessions | Create a scheduled session in a project *DefaultAPI* | [**ApiAmbientV1ProjectsIdScheduledSessionsSsIdDelete**](docs/DefaultAPI.md#apiambientv1projectsidscheduledsessionsssiddelete) | **Delete** /api/ambient/v1/projects/{id}/scheduled-sessions/{ss_id} | Delete a scheduled session @@ -166,6 +176,9 @@ Class | Method | HTTP request | Description - [List](docs/List.md) - [ObjectReference](docs/ObjectReference.md) - [Payload](docs/Payload.md) + - [Policy](docs/Policy.md) + - [PolicyList](docs/PolicyList.md) + - [PolicyPatchRequest](docs/PolicyPatchRequest.md) - [Project](docs/Project.md) - [ProjectHome](docs/ProjectHome.md) - [ProjectHomeAgent](docs/ProjectHomeAgent.md) @@ -174,6 +187,9 @@ Class | Method | HTTP request | Description - [ProjectSettings](docs/ProjectSettings.md) - [ProjectSettingsList](docs/ProjectSettingsList.md) - [ProjectSettingsPatchRequest](docs/ProjectSettingsPatchRequest.md) + - [Provider](docs/Provider.md) + - [ProviderList](docs/ProviderList.md) + - [ProviderPatchRequest](docs/ProviderPatchRequest.md) - [ResourceRequirements](docs/ResourceRequirements.md) - [Role](docs/Role.md) - [RoleBinding](docs/RoleBinding.md) diff --git a/components/ambient-api-server/pkg/api/openapi/api/openapi.yaml b/components/ambient-api-server/pkg/api/openapi/api/openapi.yaml index b50af6181..bf653702c 100644 --- a/components/ambient-api-server/pkg/api/openapi/api/openapi.yaml +++ b/components/ambient-api-server/pkg/api/openapi/api/openapi.yaml @@ -3936,6 +3936,621 @@ paths: security: - Bearer: [] summary: List sessions triggered by this scheduled session + /api/ambient/v1/projects/{id}/providers: + get: + parameters: + - description: The id of record + explode: false + in: path + name: id + required: true + schema: + type: string + style: simple + - description: Page number of record list when record list exceeds specified + page size + explode: true + in: query + name: page + required: false + schema: + default: 1 + minimum: 1 + type: integer + style: form + - description: Maximum number of records to return + explode: true + in: query + name: size + required: false + schema: + default: 100 + minimum: 0 + type: integer + style: form + - description: Specifies the search criteria + explode: true + in: query + name: search + required: false + schema: + type: string + style: form + - description: Specifies the order by criteria + explode: true + in: query + name: orderBy + required: false + schema: + type: string + style: form + - description: Supplies a comma-separated list of fields to be returned + explode: true + in: query + name: fields + required: false + schema: + type: string + style: form + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/ProviderList" + description: A JSON array of provider objects + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Auth token is invalid + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unauthorized to perform operation + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: No project with specified id exists + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unexpected error occurred + security: + - Bearer: [] + summary: Returns a list of providers in a project + post: + parameters: + - description: The id of record + explode: false + in: path + name: id + required: true + schema: + type: string + style: simple + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/Provider" + description: Provider data + required: true + responses: + "201": + content: + application/json: + schema: + $ref: "#/components/schemas/Provider" + description: Created + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Validation errors occurred + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Auth token is invalid + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unauthorized to perform operation + "409": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Provider already exists in this project + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: An unexpected error occurred creating the provider + security: + - Bearer: [] + summary: Create a provider in a project (internal — used by control plane reconciler) + /api/ambient/v1/projects/{id}/providers/{provider_id}: + delete: + parameters: + - description: The id of record + explode: false + in: path + name: id + required: true + schema: + type: string + style: simple + - description: The id of the provider + in: path + name: provider_id + required: true + schema: + type: string + responses: + "204": + description: Provider deleted successfully + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Auth token is invalid + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unauthorized to perform operation + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: No provider with specified id exists + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unexpected error occurred + security: + - Bearer: [] + summary: Delete a provider from a project (internal — used by control plane + reconciler) + get: + parameters: + - description: The id of record + explode: false + in: path + name: id + required: true + schema: + type: string + style: simple + - description: The id of the provider + in: path + name: provider_id + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Provider" + description: Provider found by id + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Auth token is invalid + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unauthorized to perform operation + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: No provider with specified id exists + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unexpected error occurred + security: + - Bearer: [] + summary: Get a provider by id + patch: + parameters: + - description: The id of record + explode: false + in: path + name: id + required: true + schema: + type: string + style: simple + - description: The id of the provider + in: path + name: provider_id + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/ProviderPatchRequest" + description: Updated provider data + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Provider" + description: Provider updated successfully + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Validation errors occurred + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Auth token is invalid + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unauthorized to perform operation + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: No provider with specified id exists + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unexpected error updating provider + security: + - Bearer: [] + summary: Update a provider (internal — used by control plane reconciler) + /api/ambient/v1/projects/{id}/policies: + get: + parameters: + - description: The id of record + explode: false + in: path + name: id + required: true + schema: + type: string + style: simple + - description: Page number of record list when record list exceeds specified + page size + explode: true + in: query + name: page + required: false + schema: + default: 1 + minimum: 1 + type: integer + style: form + - description: Maximum number of records to return + explode: true + in: query + name: size + required: false + schema: + default: 100 + minimum: 0 + type: integer + style: form + - description: Specifies the search criteria + explode: true + in: query + name: search + required: false + schema: + type: string + style: form + - description: Specifies the order by criteria + explode: true + in: query + name: orderBy + required: false + schema: + type: string + style: form + - description: Supplies a comma-separated list of fields to be returned + explode: true + in: query + name: fields + required: false + schema: + type: string + style: form + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/PolicyList" + description: A JSON array of policy objects + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Auth token is invalid + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unauthorized to perform operation + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: No project with specified id exists + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unexpected error occurred + security: + - Bearer: [] + summary: Returns a list of policies in a project + post: + parameters: + - description: The id of record + explode: false + in: path + name: id + required: true + schema: + type: string + style: simple + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/Policy" + description: Policy data + required: true + responses: + "201": + content: + application/json: + schema: + $ref: "#/components/schemas/Policy" + description: Created + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Validation errors occurred + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Auth token is invalid + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unauthorized to perform operation + "409": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Policy already exists in this project + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: An unexpected error occurred creating the policy + security: + - Bearer: [] + summary: Create a policy in a project (internal — used by control plane reconciler) + /api/ambient/v1/projects/{id}/policies/{policy_id}: + delete: + parameters: + - description: The id of record + explode: false + in: path + name: id + required: true + schema: + type: string + style: simple + - description: The id of the policy + in: path + name: policy_id + required: true + schema: + type: string + responses: + "204": + description: Policy deleted successfully + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Auth token is invalid + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unauthorized to perform operation + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: No policy with specified id exists + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unexpected error occurred + security: + - Bearer: [] + summary: Delete a policy from a project (internal — used by control plane reconciler) + get: + parameters: + - description: The id of record + explode: false + in: path + name: id + required: true + schema: + type: string + style: simple + - description: The id of the policy + in: path + name: policy_id + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Policy" + description: Policy found by id + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Auth token is invalid + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unauthorized to perform operation + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: No policy with specified id exists + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unexpected error occurred + security: + - Bearer: [] + summary: Get a policy by id + patch: + parameters: + - description: The id of record + explode: false + in: path + name: id + required: true + schema: + type: string + style: simple + - description: The id of the policy + in: path + name: policy_id + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/PolicyPatchRequest" + description: Updated policy data + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Policy" + description: Policy updated successfully + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Validation errors occurred + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Auth token is invalid + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unauthorized to perform operation + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: No policy with specified id exists + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + description: Unexpected error updating policy + security: + - Bearer: [] + summary: Update a policy (internal — used by control plane reconciler) components: parameters: id: @@ -5826,6 +6441,219 @@ components: runner_type: type: string type: object + Provider: + allOf: + - $ref: "#/components/schemas/ObjectReference" + - properties: + project_id: + description: The project this provider belongs to + type: string + name: + description: Human-readable identifier; unique within the project + type: string + type: + description: "Provider type (e.g., github, anthropic, jira)" + type: string + secret: + description: Name of the Kubernetes Secret containing credentials for + this provider + type: string + namespace: + description: Source namespace where this provider was declared + type: string + labels: + type: string + annotations: + type: string + created_at: + format: date-time + type: string + updated_at: + format: date-time + type: string + required: + - name + - project_id + type: object + example: + updated_at: 2000-01-23T04:56:07.000+00:00 + project_id: project_id + kind: kind + name: name + namespace: namespace + created_at: 2000-01-23T04:56:07.000+00:00 + annotations: annotations + id: id + href: href + secret: secret + type: type + labels: labels + ProviderList: + allOf: + - $ref: "#/components/schemas/List" + - properties: + items: + items: + $ref: "#/components/schemas/Provider" + type: array + type: object + example: + total: 1 + size: 6 + kind: kind + page: 0 + items: + - updated_at: 2000-01-23T04:56:07.000+00:00 + project_id: project_id + kind: kind + name: name + namespace: namespace + created_at: 2000-01-23T04:56:07.000+00:00 + annotations: annotations + id: id + href: href + secret: secret + type: type + labels: labels + - updated_at: 2000-01-23T04:56:07.000+00:00 + project_id: project_id + kind: kind + name: name + namespace: namespace + created_at: 2000-01-23T04:56:07.000+00:00 + annotations: annotations + id: id + href: href + secret: secret + type: type + labels: labels + ProviderPatchRequest: + example: + name: name + namespace: namespace + annotations: annotations + secret: secret + type: type + labels: labels + properties: + name: + type: string + type: + type: string + secret: + type: string + namespace: + type: string + labels: + type: string + annotations: + type: string + type: object + Policy: + allOf: + - $ref: "#/components/schemas/ObjectReference" + - properties: + project_id: + description: The project this policy belongs to + type: string + name: + description: Human-readable identifier; unique within the project + type: string + namespace: + description: Source namespace where this policy was declared + type: string + spec: + additionalProperties: true + description: "Full policy specification (network_policies, filesystem,\ + \ process, landlock)" + type: object + labels: + type: string + annotations: + type: string + created_at: + format: date-time + type: string + updated_at: + format: date-time + type: string + required: + - name + - project_id + type: object + example: + updated_at: 2000-01-23T04:56:07.000+00:00 + project_id: project_id + kind: kind + name: name + namespace: namespace + created_at: 2000-01-23T04:56:07.000+00:00 + annotations: annotations + id: id + href: href + spec: + key: "" + labels: labels + PolicyList: + allOf: + - $ref: "#/components/schemas/List" + - properties: + items: + items: + $ref: "#/components/schemas/Policy" + type: array + type: object + example: + total: 1 + size: 6 + kind: kind + page: 0 + items: + - updated_at: 2000-01-23T04:56:07.000+00:00 + project_id: project_id + kind: kind + name: name + namespace: namespace + created_at: 2000-01-23T04:56:07.000+00:00 + annotations: annotations + id: id + href: href + spec: + key: "" + labels: labels + - updated_at: 2000-01-23T04:56:07.000+00:00 + project_id: project_id + kind: kind + name: name + namespace: namespace + created_at: 2000-01-23T04:56:07.000+00:00 + annotations: annotations + id: id + href: href + spec: + key: "" + labels: labels + PolicyPatchRequest: + example: + name: name + namespace: namespace + annotations: annotations + spec: + key: "" + labels: labels + properties: + name: + type: string + namespace: + type: string + spec: + additionalProperties: true + type: object + labels: + type: string + annotations: + type: string + type: object Payload: example: repo_url: repo_url diff --git a/components/ambient-api-server/pkg/api/openapi/api_default.go b/components/ambient-api-server/pkg/api/openapi/api_default.go index d1cd44cfd..4b09a3e61 100644 --- a/components/ambient-api-server/pkg/api/openapi/api_default.go +++ b/components/ambient-api-server/pkg/api/openapi/api_default.go @@ -5547,6 +5547,1660 @@ func (a *DefaultAPIService) ApiAmbientV1ProjectsIdPatchExecute(r ApiApiAmbientV1 return localVarReturnValue, localVarHTTPResponse, nil } +type ApiApiAmbientV1ProjectsIdPoliciesGetRequest struct { + ctx context.Context + ApiService *DefaultAPIService + id string + page *int32 + size *int32 + search *string + orderBy *string + fields *string +} + +// Page number of record list when record list exceeds specified page size +func (r ApiApiAmbientV1ProjectsIdPoliciesGetRequest) Page(page int32) ApiApiAmbientV1ProjectsIdPoliciesGetRequest { + r.page = &page + return r +} + +// Maximum number of records to return +func (r ApiApiAmbientV1ProjectsIdPoliciesGetRequest) Size(size int32) ApiApiAmbientV1ProjectsIdPoliciesGetRequest { + r.size = &size + return r +} + +// Specifies the search criteria +func (r ApiApiAmbientV1ProjectsIdPoliciesGetRequest) Search(search string) ApiApiAmbientV1ProjectsIdPoliciesGetRequest { + r.search = &search + return r +} + +// Specifies the order by criteria +func (r ApiApiAmbientV1ProjectsIdPoliciesGetRequest) OrderBy(orderBy string) ApiApiAmbientV1ProjectsIdPoliciesGetRequest { + r.orderBy = &orderBy + return r +} + +// Supplies a comma-separated list of fields to be returned +func (r ApiApiAmbientV1ProjectsIdPoliciesGetRequest) Fields(fields string) ApiApiAmbientV1ProjectsIdPoliciesGetRequest { + r.fields = &fields + return r +} + +func (r ApiApiAmbientV1ProjectsIdPoliciesGetRequest) Execute() (*PolicyList, *http.Response, error) { + return r.ApiService.ApiAmbientV1ProjectsIdPoliciesGetExecute(r) +} + +/* +ApiAmbientV1ProjectsIdPoliciesGet Returns a list of policies in a project + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id The id of record + @return ApiApiAmbientV1ProjectsIdPoliciesGetRequest +*/ +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdPoliciesGet(ctx context.Context, id string) ApiApiAmbientV1ProjectsIdPoliciesGetRequest { + return ApiApiAmbientV1ProjectsIdPoliciesGetRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return PolicyList +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdPoliciesGetExecute(r ApiApiAmbientV1ProjectsIdPoliciesGetRequest) (*PolicyList, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *PolicyList + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DefaultAPIService.ApiAmbientV1ProjectsIdPoliciesGet") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/ambient/v1/projects/{id}/policies" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.page != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "page", r.page, "form", "") + } else { + var defaultValue int32 = 1 + r.page = &defaultValue + } + if r.size != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "size", r.size, "form", "") + } else { + var defaultValue int32 = 100 + r.size = &defaultValue + } + if r.search != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "search", r.search, "form", "") + } + if r.orderBy != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "orderBy", r.orderBy, "form", "") + } + if r.fields != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "fields", r.fields, "form", "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiApiAmbientV1ProjectsIdPoliciesPolicyIdDeleteRequest struct { + ctx context.Context + ApiService *DefaultAPIService + id string + policyId string +} + +func (r ApiApiAmbientV1ProjectsIdPoliciesPolicyIdDeleteRequest) Execute() (*http.Response, error) { + return r.ApiService.ApiAmbientV1ProjectsIdPoliciesPolicyIdDeleteExecute(r) +} + +/* +ApiAmbientV1ProjectsIdPoliciesPolicyIdDelete Delete a policy from a project (internal — used by control plane reconciler) + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id The id of record + @param policyId The id of the policy + @return ApiApiAmbientV1ProjectsIdPoliciesPolicyIdDeleteRequest +*/ +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdPoliciesPolicyIdDelete(ctx context.Context, id string, policyId string) ApiApiAmbientV1ProjectsIdPoliciesPolicyIdDeleteRequest { + return ApiApiAmbientV1ProjectsIdPoliciesPolicyIdDeleteRequest{ + ApiService: a, + ctx: ctx, + id: id, + policyId: policyId, + } +} + +// Execute executes the request +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdPoliciesPolicyIdDeleteExecute(r ApiApiAmbientV1ProjectsIdPoliciesPolicyIdDeleteRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DefaultAPIService.ApiAmbientV1ProjectsIdPoliciesPolicyIdDelete") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/ambient/v1/projects/{id}/policies/{policy_id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"policy_id"+"}", url.PathEscape(parameterValueToString(r.policyId, "policyId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + +type ApiApiAmbientV1ProjectsIdPoliciesPolicyIdGetRequest struct { + ctx context.Context + ApiService *DefaultAPIService + id string + policyId string +} + +func (r ApiApiAmbientV1ProjectsIdPoliciesPolicyIdGetRequest) Execute() (*Policy, *http.Response, error) { + return r.ApiService.ApiAmbientV1ProjectsIdPoliciesPolicyIdGetExecute(r) +} + +/* +ApiAmbientV1ProjectsIdPoliciesPolicyIdGet Get a policy by id + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id The id of record + @param policyId The id of the policy + @return ApiApiAmbientV1ProjectsIdPoliciesPolicyIdGetRequest +*/ +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdPoliciesPolicyIdGet(ctx context.Context, id string, policyId string) ApiApiAmbientV1ProjectsIdPoliciesPolicyIdGetRequest { + return ApiApiAmbientV1ProjectsIdPoliciesPolicyIdGetRequest{ + ApiService: a, + ctx: ctx, + id: id, + policyId: policyId, + } +} + +// Execute executes the request +// +// @return Policy +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdPoliciesPolicyIdGetExecute(r ApiApiAmbientV1ProjectsIdPoliciesPolicyIdGetRequest) (*Policy, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *Policy + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DefaultAPIService.ApiAmbientV1ProjectsIdPoliciesPolicyIdGet") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/ambient/v1/projects/{id}/policies/{policy_id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"policy_id"+"}", url.PathEscape(parameterValueToString(r.policyId, "policyId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiApiAmbientV1ProjectsIdPoliciesPolicyIdPatchRequest struct { + ctx context.Context + ApiService *DefaultAPIService + id string + policyId string + policyPatchRequest *PolicyPatchRequest +} + +// Updated policy data +func (r ApiApiAmbientV1ProjectsIdPoliciesPolicyIdPatchRequest) PolicyPatchRequest(policyPatchRequest PolicyPatchRequest) ApiApiAmbientV1ProjectsIdPoliciesPolicyIdPatchRequest { + r.policyPatchRequest = &policyPatchRequest + return r +} + +func (r ApiApiAmbientV1ProjectsIdPoliciesPolicyIdPatchRequest) Execute() (*Policy, *http.Response, error) { + return r.ApiService.ApiAmbientV1ProjectsIdPoliciesPolicyIdPatchExecute(r) +} + +/* +ApiAmbientV1ProjectsIdPoliciesPolicyIdPatch Update a policy (internal — used by control plane reconciler) + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id The id of record + @param policyId The id of the policy + @return ApiApiAmbientV1ProjectsIdPoliciesPolicyIdPatchRequest +*/ +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdPoliciesPolicyIdPatch(ctx context.Context, id string, policyId string) ApiApiAmbientV1ProjectsIdPoliciesPolicyIdPatchRequest { + return ApiApiAmbientV1ProjectsIdPoliciesPolicyIdPatchRequest{ + ApiService: a, + ctx: ctx, + id: id, + policyId: policyId, + } +} + +// Execute executes the request +// +// @return Policy +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdPoliciesPolicyIdPatchExecute(r ApiApiAmbientV1ProjectsIdPoliciesPolicyIdPatchRequest) (*Policy, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *Policy + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DefaultAPIService.ApiAmbientV1ProjectsIdPoliciesPolicyIdPatch") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/ambient/v1/projects/{id}/policies/{policy_id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"policy_id"+"}", url.PathEscape(parameterValueToString(r.policyId, "policyId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.policyPatchRequest == nil { + return localVarReturnValue, nil, reportError("policyPatchRequest is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.policyPatchRequest + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiApiAmbientV1ProjectsIdPoliciesPostRequest struct { + ctx context.Context + ApiService *DefaultAPIService + id string + policy *Policy +} + +// Policy data +func (r ApiApiAmbientV1ProjectsIdPoliciesPostRequest) Policy(policy Policy) ApiApiAmbientV1ProjectsIdPoliciesPostRequest { + r.policy = &policy + return r +} + +func (r ApiApiAmbientV1ProjectsIdPoliciesPostRequest) Execute() (*Policy, *http.Response, error) { + return r.ApiService.ApiAmbientV1ProjectsIdPoliciesPostExecute(r) +} + +/* +ApiAmbientV1ProjectsIdPoliciesPost Create a policy in a project (internal — used by control plane reconciler) + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id The id of record + @return ApiApiAmbientV1ProjectsIdPoliciesPostRequest +*/ +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdPoliciesPost(ctx context.Context, id string) ApiApiAmbientV1ProjectsIdPoliciesPostRequest { + return ApiApiAmbientV1ProjectsIdPoliciesPostRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return Policy +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdPoliciesPostExecute(r ApiApiAmbientV1ProjectsIdPoliciesPostRequest) (*Policy, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *Policy + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DefaultAPIService.ApiAmbientV1ProjectsIdPoliciesPost") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/ambient/v1/projects/{id}/policies" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.policy == nil { + return localVarReturnValue, nil, reportError("policy is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.policy + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 409 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiApiAmbientV1ProjectsIdProvidersGetRequest struct { + ctx context.Context + ApiService *DefaultAPIService + id string + page *int32 + size *int32 + search *string + orderBy *string + fields *string +} + +// Page number of record list when record list exceeds specified page size +func (r ApiApiAmbientV1ProjectsIdProvidersGetRequest) Page(page int32) ApiApiAmbientV1ProjectsIdProvidersGetRequest { + r.page = &page + return r +} + +// Maximum number of records to return +func (r ApiApiAmbientV1ProjectsIdProvidersGetRequest) Size(size int32) ApiApiAmbientV1ProjectsIdProvidersGetRequest { + r.size = &size + return r +} + +// Specifies the search criteria +func (r ApiApiAmbientV1ProjectsIdProvidersGetRequest) Search(search string) ApiApiAmbientV1ProjectsIdProvidersGetRequest { + r.search = &search + return r +} + +// Specifies the order by criteria +func (r ApiApiAmbientV1ProjectsIdProvidersGetRequest) OrderBy(orderBy string) ApiApiAmbientV1ProjectsIdProvidersGetRequest { + r.orderBy = &orderBy + return r +} + +// Supplies a comma-separated list of fields to be returned +func (r ApiApiAmbientV1ProjectsIdProvidersGetRequest) Fields(fields string) ApiApiAmbientV1ProjectsIdProvidersGetRequest { + r.fields = &fields + return r +} + +func (r ApiApiAmbientV1ProjectsIdProvidersGetRequest) Execute() (*ProviderList, *http.Response, error) { + return r.ApiService.ApiAmbientV1ProjectsIdProvidersGetExecute(r) +} + +/* +ApiAmbientV1ProjectsIdProvidersGet Returns a list of providers in a project + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id The id of record + @return ApiApiAmbientV1ProjectsIdProvidersGetRequest +*/ +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdProvidersGet(ctx context.Context, id string) ApiApiAmbientV1ProjectsIdProvidersGetRequest { + return ApiApiAmbientV1ProjectsIdProvidersGetRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return ProviderList +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdProvidersGetExecute(r ApiApiAmbientV1ProjectsIdProvidersGetRequest) (*ProviderList, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ProviderList + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DefaultAPIService.ApiAmbientV1ProjectsIdProvidersGet") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/ambient/v1/projects/{id}/providers" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.page != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "page", r.page, "form", "") + } else { + var defaultValue int32 = 1 + r.page = &defaultValue + } + if r.size != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "size", r.size, "form", "") + } else { + var defaultValue int32 = 100 + r.size = &defaultValue + } + if r.search != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "search", r.search, "form", "") + } + if r.orderBy != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "orderBy", r.orderBy, "form", "") + } + if r.fields != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "fields", r.fields, "form", "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiApiAmbientV1ProjectsIdProvidersPostRequest struct { + ctx context.Context + ApiService *DefaultAPIService + id string + provider *Provider +} + +// Provider data +func (r ApiApiAmbientV1ProjectsIdProvidersPostRequest) Provider(provider Provider) ApiApiAmbientV1ProjectsIdProvidersPostRequest { + r.provider = &provider + return r +} + +func (r ApiApiAmbientV1ProjectsIdProvidersPostRequest) Execute() (*Provider, *http.Response, error) { + return r.ApiService.ApiAmbientV1ProjectsIdProvidersPostExecute(r) +} + +/* +ApiAmbientV1ProjectsIdProvidersPost Create a provider in a project (internal — used by control plane reconciler) + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id The id of record + @return ApiApiAmbientV1ProjectsIdProvidersPostRequest +*/ +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdProvidersPost(ctx context.Context, id string) ApiApiAmbientV1ProjectsIdProvidersPostRequest { + return ApiApiAmbientV1ProjectsIdProvidersPostRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return Provider +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdProvidersPostExecute(r ApiApiAmbientV1ProjectsIdProvidersPostRequest) (*Provider, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *Provider + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DefaultAPIService.ApiAmbientV1ProjectsIdProvidersPost") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/ambient/v1/projects/{id}/providers" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.provider == nil { + return localVarReturnValue, nil, reportError("provider is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.provider + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 409 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiApiAmbientV1ProjectsIdProvidersProviderIdDeleteRequest struct { + ctx context.Context + ApiService *DefaultAPIService + id string + providerId string +} + +func (r ApiApiAmbientV1ProjectsIdProvidersProviderIdDeleteRequest) Execute() (*http.Response, error) { + return r.ApiService.ApiAmbientV1ProjectsIdProvidersProviderIdDeleteExecute(r) +} + +/* +ApiAmbientV1ProjectsIdProvidersProviderIdDelete Delete a provider from a project (internal — used by control plane reconciler) + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id The id of record + @param providerId The id of the provider + @return ApiApiAmbientV1ProjectsIdProvidersProviderIdDeleteRequest +*/ +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdProvidersProviderIdDelete(ctx context.Context, id string, providerId string) ApiApiAmbientV1ProjectsIdProvidersProviderIdDeleteRequest { + return ApiApiAmbientV1ProjectsIdProvidersProviderIdDeleteRequest{ + ApiService: a, + ctx: ctx, + id: id, + providerId: providerId, + } +} + +// Execute executes the request +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdProvidersProviderIdDeleteExecute(r ApiApiAmbientV1ProjectsIdProvidersProviderIdDeleteRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DefaultAPIService.ApiAmbientV1ProjectsIdProvidersProviderIdDelete") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/ambient/v1/projects/{id}/providers/{provider_id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"provider_id"+"}", url.PathEscape(parameterValueToString(r.providerId, "providerId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + +type ApiApiAmbientV1ProjectsIdProvidersProviderIdGetRequest struct { + ctx context.Context + ApiService *DefaultAPIService + id string + providerId string +} + +func (r ApiApiAmbientV1ProjectsIdProvidersProviderIdGetRequest) Execute() (*Provider, *http.Response, error) { + return r.ApiService.ApiAmbientV1ProjectsIdProvidersProviderIdGetExecute(r) +} + +/* +ApiAmbientV1ProjectsIdProvidersProviderIdGet Get a provider by id + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id The id of record + @param providerId The id of the provider + @return ApiApiAmbientV1ProjectsIdProvidersProviderIdGetRequest +*/ +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdProvidersProviderIdGet(ctx context.Context, id string, providerId string) ApiApiAmbientV1ProjectsIdProvidersProviderIdGetRequest { + return ApiApiAmbientV1ProjectsIdProvidersProviderIdGetRequest{ + ApiService: a, + ctx: ctx, + id: id, + providerId: providerId, + } +} + +// Execute executes the request +// +// @return Provider +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdProvidersProviderIdGetExecute(r ApiApiAmbientV1ProjectsIdProvidersProviderIdGetRequest) (*Provider, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *Provider + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DefaultAPIService.ApiAmbientV1ProjectsIdProvidersProviderIdGet") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/ambient/v1/projects/{id}/providers/{provider_id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"provider_id"+"}", url.PathEscape(parameterValueToString(r.providerId, "providerId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiApiAmbientV1ProjectsIdProvidersProviderIdPatchRequest struct { + ctx context.Context + ApiService *DefaultAPIService + id string + providerId string + providerPatchRequest *ProviderPatchRequest +} + +// Updated provider data +func (r ApiApiAmbientV1ProjectsIdProvidersProviderIdPatchRequest) ProviderPatchRequest(providerPatchRequest ProviderPatchRequest) ApiApiAmbientV1ProjectsIdProvidersProviderIdPatchRequest { + r.providerPatchRequest = &providerPatchRequest + return r +} + +func (r ApiApiAmbientV1ProjectsIdProvidersProviderIdPatchRequest) Execute() (*Provider, *http.Response, error) { + return r.ApiService.ApiAmbientV1ProjectsIdProvidersProviderIdPatchExecute(r) +} + +/* +ApiAmbientV1ProjectsIdProvidersProviderIdPatch Update a provider (internal — used by control plane reconciler) + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id The id of record + @param providerId The id of the provider + @return ApiApiAmbientV1ProjectsIdProvidersProviderIdPatchRequest +*/ +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdProvidersProviderIdPatch(ctx context.Context, id string, providerId string) ApiApiAmbientV1ProjectsIdProvidersProviderIdPatchRequest { + return ApiApiAmbientV1ProjectsIdProvidersProviderIdPatchRequest{ + ApiService: a, + ctx: ctx, + id: id, + providerId: providerId, + } +} + +// Execute executes the request +// +// @return Provider +func (a *DefaultAPIService) ApiAmbientV1ProjectsIdProvidersProviderIdPatchExecute(r ApiApiAmbientV1ProjectsIdProvidersProviderIdPatchRequest) (*Provider, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *Provider + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DefaultAPIService.ApiAmbientV1ProjectsIdProvidersProviderIdPatch") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/ambient/v1/projects/{id}/providers/{provider_id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"provider_id"+"}", url.PathEscape(parameterValueToString(r.providerId, "providerId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.providerPatchRequest == nil { + return localVarReturnValue, nil, reportError("providerPatchRequest is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.providerPatchRequest + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + type ApiApiAmbientV1ProjectsIdScheduledSessionsGetRequest struct { ctx context.Context ApiService *DefaultAPIService diff --git a/components/ambient-api-server/pkg/api/openapi/docs/DefaultAPI.md b/components/ambient-api-server/pkg/api/openapi/docs/DefaultAPI.md index 3a808a116..6d42f042d 100644 --- a/components/ambient-api-server/pkg/api/openapi/docs/DefaultAPI.md +++ b/components/ambient-api-server/pkg/api/openapi/docs/DefaultAPI.md @@ -38,6 +38,16 @@ Method | HTTP request | Description [**ApiAmbientV1ProjectsIdGet**](DefaultAPI.md#ApiAmbientV1ProjectsIdGet) | **Get** /api/ambient/v1/projects/{id} | Get a project by id [**ApiAmbientV1ProjectsIdHomeGet**](DefaultAPI.md#ApiAmbientV1ProjectsIdHomeGet) | **Get** /api/ambient/v1/projects/{id}/home | Project home — latest status for every Agent in this project [**ApiAmbientV1ProjectsIdPatch**](DefaultAPI.md#ApiAmbientV1ProjectsIdPatch) | **Patch** /api/ambient/v1/projects/{id} | Update a project +[**ApiAmbientV1ProjectsIdPoliciesGet**](DefaultAPI.md#ApiAmbientV1ProjectsIdPoliciesGet) | **Get** /api/ambient/v1/projects/{id}/policies | Returns a list of policies in a project +[**ApiAmbientV1ProjectsIdPoliciesPolicyIdDelete**](DefaultAPI.md#ApiAmbientV1ProjectsIdPoliciesPolicyIdDelete) | **Delete** /api/ambient/v1/projects/{id}/policies/{policy_id} | Delete a policy from a project (internal — used by control plane reconciler) +[**ApiAmbientV1ProjectsIdPoliciesPolicyIdGet**](DefaultAPI.md#ApiAmbientV1ProjectsIdPoliciesPolicyIdGet) | **Get** /api/ambient/v1/projects/{id}/policies/{policy_id} | Get a policy by id +[**ApiAmbientV1ProjectsIdPoliciesPolicyIdPatch**](DefaultAPI.md#ApiAmbientV1ProjectsIdPoliciesPolicyIdPatch) | **Patch** /api/ambient/v1/projects/{id}/policies/{policy_id} | Update a policy (internal — used by control plane reconciler) +[**ApiAmbientV1ProjectsIdPoliciesPost**](DefaultAPI.md#ApiAmbientV1ProjectsIdPoliciesPost) | **Post** /api/ambient/v1/projects/{id}/policies | Create a policy in a project (internal — used by control plane reconciler) +[**ApiAmbientV1ProjectsIdProvidersGet**](DefaultAPI.md#ApiAmbientV1ProjectsIdProvidersGet) | **Get** /api/ambient/v1/projects/{id}/providers | Returns a list of providers in a project +[**ApiAmbientV1ProjectsIdProvidersPost**](DefaultAPI.md#ApiAmbientV1ProjectsIdProvidersPost) | **Post** /api/ambient/v1/projects/{id}/providers | Create a provider in a project (internal — used by control plane reconciler) +[**ApiAmbientV1ProjectsIdProvidersProviderIdDelete**](DefaultAPI.md#ApiAmbientV1ProjectsIdProvidersProviderIdDelete) | **Delete** /api/ambient/v1/projects/{id}/providers/{provider_id} | Delete a provider from a project (internal — used by control plane reconciler) +[**ApiAmbientV1ProjectsIdProvidersProviderIdGet**](DefaultAPI.md#ApiAmbientV1ProjectsIdProvidersProviderIdGet) | **Get** /api/ambient/v1/projects/{id}/providers/{provider_id} | Get a provider by id +[**ApiAmbientV1ProjectsIdProvidersProviderIdPatch**](DefaultAPI.md#ApiAmbientV1ProjectsIdProvidersProviderIdPatch) | **Patch** /api/ambient/v1/projects/{id}/providers/{provider_id} | Update a provider (internal — used by control plane reconciler) [**ApiAmbientV1ProjectsIdScheduledSessionsGet**](DefaultAPI.md#ApiAmbientV1ProjectsIdScheduledSessionsGet) | **Get** /api/ambient/v1/projects/{id}/scheduled-sessions | Returns a list of scheduled sessions in a project [**ApiAmbientV1ProjectsIdScheduledSessionsPost**](DefaultAPI.md#ApiAmbientV1ProjectsIdScheduledSessionsPost) | **Post** /api/ambient/v1/projects/{id}/scheduled-sessions | Create a scheduled session in a project [**ApiAmbientV1ProjectsIdScheduledSessionsSsIdDelete**](DefaultAPI.md#ApiAmbientV1ProjectsIdScheduledSessionsSsIdDelete) | **Delete** /api/ambient/v1/projects/{id}/scheduled-sessions/{ss_id} | Delete a scheduled session @@ -2485,6 +2495,728 @@ Name | Type | Description | Notes [[Back to README]](../README.md) +## ApiAmbientV1ProjectsIdPoliciesGet + +> PolicyList ApiAmbientV1ProjectsIdPoliciesGet(ctx, id).Page(page).Size(size).Search(search).OrderBy(orderBy).Fields(fields).Execute() + +Returns a list of policies in a project + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID" +) + +func main() { + id := "id_example" // string | The id of record + page := int32(56) // int32 | Page number of record list when record list exceeds specified page size (optional) (default to 1) + size := int32(56) // int32 | Maximum number of records to return (optional) (default to 100) + search := "search_example" // string | Specifies the search criteria (optional) + orderBy := "orderBy_example" // string | Specifies the order by criteria (optional) + fields := "fields_example" // string | Supplies a comma-separated list of fields to be returned (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.DefaultAPI.ApiAmbientV1ProjectsIdPoliciesGet(context.Background(), id).Page(page).Size(size).Search(search).OrderBy(orderBy).Fields(fields).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `DefaultAPI.ApiAmbientV1ProjectsIdPoliciesGet``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ApiAmbientV1ProjectsIdPoliciesGet`: PolicyList + fmt.Fprintf(os.Stdout, "Response from `DefaultAPI.ApiAmbientV1ProjectsIdPoliciesGet`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | The id of record | + +### Other Parameters + +Other parameters are passed through a pointer to a apiApiAmbientV1ProjectsIdPoliciesGetRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **page** | **int32** | Page number of record list when record list exceeds specified page size | [default to 1] + **size** | **int32** | Maximum number of records to return | [default to 100] + **search** | **string** | Specifies the search criteria | + **orderBy** | **string** | Specifies the order by criteria | + **fields** | **string** | Supplies a comma-separated list of fields to be returned | + +### Return type + +[**PolicyList**](PolicyList.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ApiAmbientV1ProjectsIdPoliciesPolicyIdDelete + +> ApiAmbientV1ProjectsIdPoliciesPolicyIdDelete(ctx, id, policyId).Execute() + +Delete a policy from a project (internal — used by control plane reconciler) + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID" +) + +func main() { + id := "id_example" // string | The id of record + policyId := "policyId_example" // string | The id of the policy + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.DefaultAPI.ApiAmbientV1ProjectsIdPoliciesPolicyIdDelete(context.Background(), id, policyId).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `DefaultAPI.ApiAmbientV1ProjectsIdPoliciesPolicyIdDelete``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | The id of record | +**policyId** | **string** | The id of the policy | + +### Other Parameters + +Other parameters are passed through a pointer to a apiApiAmbientV1ProjectsIdPoliciesPolicyIdDeleteRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ApiAmbientV1ProjectsIdPoliciesPolicyIdGet + +> Policy ApiAmbientV1ProjectsIdPoliciesPolicyIdGet(ctx, id, policyId).Execute() + +Get a policy by id + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID" +) + +func main() { + id := "id_example" // string | The id of record + policyId := "policyId_example" // string | The id of the policy + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.DefaultAPI.ApiAmbientV1ProjectsIdPoliciesPolicyIdGet(context.Background(), id, policyId).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `DefaultAPI.ApiAmbientV1ProjectsIdPoliciesPolicyIdGet``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ApiAmbientV1ProjectsIdPoliciesPolicyIdGet`: Policy + fmt.Fprintf(os.Stdout, "Response from `DefaultAPI.ApiAmbientV1ProjectsIdPoliciesPolicyIdGet`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | The id of record | +**policyId** | **string** | The id of the policy | + +### Other Parameters + +Other parameters are passed through a pointer to a apiApiAmbientV1ProjectsIdPoliciesPolicyIdGetRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + + +### Return type + +[**Policy**](Policy.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ApiAmbientV1ProjectsIdPoliciesPolicyIdPatch + +> Policy ApiAmbientV1ProjectsIdPoliciesPolicyIdPatch(ctx, id, policyId).PolicyPatchRequest(policyPatchRequest).Execute() + +Update a policy (internal — used by control plane reconciler) + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID" +) + +func main() { + id := "id_example" // string | The id of record + policyId := "policyId_example" // string | The id of the policy + policyPatchRequest := *openapiclient.NewPolicyPatchRequest() // PolicyPatchRequest | Updated policy data + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.DefaultAPI.ApiAmbientV1ProjectsIdPoliciesPolicyIdPatch(context.Background(), id, policyId).PolicyPatchRequest(policyPatchRequest).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `DefaultAPI.ApiAmbientV1ProjectsIdPoliciesPolicyIdPatch``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ApiAmbientV1ProjectsIdPoliciesPolicyIdPatch`: Policy + fmt.Fprintf(os.Stdout, "Response from `DefaultAPI.ApiAmbientV1ProjectsIdPoliciesPolicyIdPatch`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | The id of record | +**policyId** | **string** | The id of the policy | + +### Other Parameters + +Other parameters are passed through a pointer to a apiApiAmbientV1ProjectsIdPoliciesPolicyIdPatchRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + + **policyPatchRequest** | [**PolicyPatchRequest**](PolicyPatchRequest.md) | Updated policy data | + +### Return type + +[**Policy**](Policy.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ApiAmbientV1ProjectsIdPoliciesPost + +> Policy ApiAmbientV1ProjectsIdPoliciesPost(ctx, id).Policy(policy).Execute() + +Create a policy in a project (internal — used by control plane reconciler) + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID" +) + +func main() { + id := "id_example" // string | The id of record + policy := *openapiclient.NewPolicy("ProjectId_example", "Name_example") // Policy | Policy data + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.DefaultAPI.ApiAmbientV1ProjectsIdPoliciesPost(context.Background(), id).Policy(policy).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `DefaultAPI.ApiAmbientV1ProjectsIdPoliciesPost``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ApiAmbientV1ProjectsIdPoliciesPost`: Policy + fmt.Fprintf(os.Stdout, "Response from `DefaultAPI.ApiAmbientV1ProjectsIdPoliciesPost`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | The id of record | + +### Other Parameters + +Other parameters are passed through a pointer to a apiApiAmbientV1ProjectsIdPoliciesPostRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **policy** | [**Policy**](Policy.md) | Policy data | + +### Return type + +[**Policy**](Policy.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ApiAmbientV1ProjectsIdProvidersGet + +> ProviderList ApiAmbientV1ProjectsIdProvidersGet(ctx, id).Page(page).Size(size).Search(search).OrderBy(orderBy).Fields(fields).Execute() + +Returns a list of providers in a project + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID" +) + +func main() { + id := "id_example" // string | The id of record + page := int32(56) // int32 | Page number of record list when record list exceeds specified page size (optional) (default to 1) + size := int32(56) // int32 | Maximum number of records to return (optional) (default to 100) + search := "search_example" // string | Specifies the search criteria (optional) + orderBy := "orderBy_example" // string | Specifies the order by criteria (optional) + fields := "fields_example" // string | Supplies a comma-separated list of fields to be returned (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.DefaultAPI.ApiAmbientV1ProjectsIdProvidersGet(context.Background(), id).Page(page).Size(size).Search(search).OrderBy(orderBy).Fields(fields).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `DefaultAPI.ApiAmbientV1ProjectsIdProvidersGet``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ApiAmbientV1ProjectsIdProvidersGet`: ProviderList + fmt.Fprintf(os.Stdout, "Response from `DefaultAPI.ApiAmbientV1ProjectsIdProvidersGet`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | The id of record | + +### Other Parameters + +Other parameters are passed through a pointer to a apiApiAmbientV1ProjectsIdProvidersGetRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **page** | **int32** | Page number of record list when record list exceeds specified page size | [default to 1] + **size** | **int32** | Maximum number of records to return | [default to 100] + **search** | **string** | Specifies the search criteria | + **orderBy** | **string** | Specifies the order by criteria | + **fields** | **string** | Supplies a comma-separated list of fields to be returned | + +### Return type + +[**ProviderList**](ProviderList.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ApiAmbientV1ProjectsIdProvidersPost + +> Provider ApiAmbientV1ProjectsIdProvidersPost(ctx, id).Provider(provider).Execute() + +Create a provider in a project (internal — used by control plane reconciler) + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID" +) + +func main() { + id := "id_example" // string | The id of record + provider := *openapiclient.NewProvider("ProjectId_example", "Name_example") // Provider | Provider data + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.DefaultAPI.ApiAmbientV1ProjectsIdProvidersPost(context.Background(), id).Provider(provider).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `DefaultAPI.ApiAmbientV1ProjectsIdProvidersPost``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ApiAmbientV1ProjectsIdProvidersPost`: Provider + fmt.Fprintf(os.Stdout, "Response from `DefaultAPI.ApiAmbientV1ProjectsIdProvidersPost`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | The id of record | + +### Other Parameters + +Other parameters are passed through a pointer to a apiApiAmbientV1ProjectsIdProvidersPostRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **provider** | [**Provider**](Provider.md) | Provider data | + +### Return type + +[**Provider**](Provider.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ApiAmbientV1ProjectsIdProvidersProviderIdDelete + +> ApiAmbientV1ProjectsIdProvidersProviderIdDelete(ctx, id, providerId).Execute() + +Delete a provider from a project (internal — used by control plane reconciler) + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID" +) + +func main() { + id := "id_example" // string | The id of record + providerId := "providerId_example" // string | The id of the provider + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.DefaultAPI.ApiAmbientV1ProjectsIdProvidersProviderIdDelete(context.Background(), id, providerId).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `DefaultAPI.ApiAmbientV1ProjectsIdProvidersProviderIdDelete``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | The id of record | +**providerId** | **string** | The id of the provider | + +### Other Parameters + +Other parameters are passed through a pointer to a apiApiAmbientV1ProjectsIdProvidersProviderIdDeleteRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ApiAmbientV1ProjectsIdProvidersProviderIdGet + +> Provider ApiAmbientV1ProjectsIdProvidersProviderIdGet(ctx, id, providerId).Execute() + +Get a provider by id + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID" +) + +func main() { + id := "id_example" // string | The id of record + providerId := "providerId_example" // string | The id of the provider + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.DefaultAPI.ApiAmbientV1ProjectsIdProvidersProviderIdGet(context.Background(), id, providerId).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `DefaultAPI.ApiAmbientV1ProjectsIdProvidersProviderIdGet``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ApiAmbientV1ProjectsIdProvidersProviderIdGet`: Provider + fmt.Fprintf(os.Stdout, "Response from `DefaultAPI.ApiAmbientV1ProjectsIdProvidersProviderIdGet`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | The id of record | +**providerId** | **string** | The id of the provider | + +### Other Parameters + +Other parameters are passed through a pointer to a apiApiAmbientV1ProjectsIdProvidersProviderIdGetRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + + +### Return type + +[**Provider**](Provider.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ApiAmbientV1ProjectsIdProvidersProviderIdPatch + +> Provider ApiAmbientV1ProjectsIdProvidersProviderIdPatch(ctx, id, providerId).ProviderPatchRequest(providerPatchRequest).Execute() + +Update a provider (internal — used by control plane reconciler) + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID" +) + +func main() { + id := "id_example" // string | The id of record + providerId := "providerId_example" // string | The id of the provider + providerPatchRequest := *openapiclient.NewProviderPatchRequest() // ProviderPatchRequest | Updated provider data + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.DefaultAPI.ApiAmbientV1ProjectsIdProvidersProviderIdPatch(context.Background(), id, providerId).ProviderPatchRequest(providerPatchRequest).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `DefaultAPI.ApiAmbientV1ProjectsIdProvidersProviderIdPatch``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ApiAmbientV1ProjectsIdProvidersProviderIdPatch`: Provider + fmt.Fprintf(os.Stdout, "Response from `DefaultAPI.ApiAmbientV1ProjectsIdProvidersProviderIdPatch`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | The id of record | +**providerId** | **string** | The id of the provider | + +### Other Parameters + +Other parameters are passed through a pointer to a apiApiAmbientV1ProjectsIdProvidersProviderIdPatchRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + + **providerPatchRequest** | [**ProviderPatchRequest**](ProviderPatchRequest.md) | Updated provider data | + +### Return type + +[**Provider**](Provider.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + ## ApiAmbientV1ProjectsIdScheduledSessionsGet > ScheduledSessionList ApiAmbientV1ProjectsIdScheduledSessionsGet(ctx, id).Page(page).Size(size).Search(search).OrderBy(orderBy).Fields(fields).Execute() diff --git a/components/ambient-api-server/pkg/api/openapi/docs/Policy.md b/components/ambient-api-server/pkg/api/openapi/docs/Policy.md new file mode 100644 index 000000000..51df82c6c --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/docs/Policy.md @@ -0,0 +1,306 @@ +# Policy + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Id** | Pointer to **string** | | [optional] +**Kind** | Pointer to **string** | | [optional] +**Href** | Pointer to **string** | | [optional] +**CreatedAt** | Pointer to **time.Time** | | [optional] +**UpdatedAt** | Pointer to **time.Time** | | [optional] +**ProjectId** | **string** | The project this policy belongs to | +**Name** | **string** | Human-readable identifier; unique within the project | +**Namespace** | Pointer to **string** | Source namespace where this policy was declared | [optional] +**Spec** | Pointer to **map[string]interface{}** | Full policy specification (network_policies, filesystem, process, landlock) | [optional] +**Labels** | Pointer to **string** | | [optional] +**Annotations** | Pointer to **string** | | [optional] + +## Methods + +### NewPolicy + +`func NewPolicy(projectId string, name string, ) *Policy` + +NewPolicy instantiates a new Policy object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewPolicyWithDefaults + +`func NewPolicyWithDefaults() *Policy` + +NewPolicyWithDefaults instantiates a new Policy object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetId + +`func (o *Policy) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *Policy) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *Policy) SetId(v string)` + +SetId sets Id field to given value. + +### HasId + +`func (o *Policy) HasId() bool` + +HasId returns a boolean if a field has been set. + +### GetKind + +`func (o *Policy) GetKind() string` + +GetKind returns the Kind field if non-nil, zero value otherwise. + +### GetKindOk + +`func (o *Policy) GetKindOk() (*string, bool)` + +GetKindOk returns a tuple with the Kind field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetKind + +`func (o *Policy) SetKind(v string)` + +SetKind sets Kind field to given value. + +### HasKind + +`func (o *Policy) HasKind() bool` + +HasKind returns a boolean if a field has been set. + +### GetHref + +`func (o *Policy) GetHref() string` + +GetHref returns the Href field if non-nil, zero value otherwise. + +### GetHrefOk + +`func (o *Policy) GetHrefOk() (*string, bool)` + +GetHrefOk returns a tuple with the Href field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetHref + +`func (o *Policy) SetHref(v string)` + +SetHref sets Href field to given value. + +### HasHref + +`func (o *Policy) HasHref() bool` + +HasHref returns a boolean if a field has been set. + +### GetCreatedAt + +`func (o *Policy) GetCreatedAt() time.Time` + +GetCreatedAt returns the CreatedAt field if non-nil, zero value otherwise. + +### GetCreatedAtOk + +`func (o *Policy) GetCreatedAtOk() (*time.Time, bool)` + +GetCreatedAtOk returns a tuple with the CreatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCreatedAt + +`func (o *Policy) SetCreatedAt(v time.Time)` + +SetCreatedAt sets CreatedAt field to given value. + +### HasCreatedAt + +`func (o *Policy) HasCreatedAt() bool` + +HasCreatedAt returns a boolean if a field has been set. + +### GetUpdatedAt + +`func (o *Policy) GetUpdatedAt() time.Time` + +GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. + +### GetUpdatedAtOk + +`func (o *Policy) GetUpdatedAtOk() (*time.Time, bool)` + +GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUpdatedAt + +`func (o *Policy) SetUpdatedAt(v time.Time)` + +SetUpdatedAt sets UpdatedAt field to given value. + +### HasUpdatedAt + +`func (o *Policy) HasUpdatedAt() bool` + +HasUpdatedAt returns a boolean if a field has been set. + +### GetProjectId + +`func (o *Policy) GetProjectId() string` + +GetProjectId returns the ProjectId field if non-nil, zero value otherwise. + +### GetProjectIdOk + +`func (o *Policy) GetProjectIdOk() (*string, bool)` + +GetProjectIdOk returns a tuple with the ProjectId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetProjectId + +`func (o *Policy) SetProjectId(v string)` + +SetProjectId sets ProjectId field to given value. + + +### GetName + +`func (o *Policy) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *Policy) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *Policy) SetName(v string)` + +SetName sets Name field to given value. + + +### GetNamespace + +`func (o *Policy) GetNamespace() string` + +GetNamespace returns the Namespace field if non-nil, zero value otherwise. + +### GetNamespaceOk + +`func (o *Policy) GetNamespaceOk() (*string, bool)` + +GetNamespaceOk returns a tuple with the Namespace field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetNamespace + +`func (o *Policy) SetNamespace(v string)` + +SetNamespace sets Namespace field to given value. + +### HasNamespace + +`func (o *Policy) HasNamespace() bool` + +HasNamespace returns a boolean if a field has been set. + +### GetSpec + +`func (o *Policy) GetSpec() map[string]interface{}` + +GetSpec returns the Spec field if non-nil, zero value otherwise. + +### GetSpecOk + +`func (o *Policy) GetSpecOk() (*map[string]interface{}, bool)` + +GetSpecOk returns a tuple with the Spec field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSpec + +`func (o *Policy) SetSpec(v map[string]interface{})` + +SetSpec sets Spec field to given value. + +### HasSpec + +`func (o *Policy) HasSpec() bool` + +HasSpec returns a boolean if a field has been set. + +### GetLabels + +`func (o *Policy) GetLabels() string` + +GetLabels returns the Labels field if non-nil, zero value otherwise. + +### GetLabelsOk + +`func (o *Policy) GetLabelsOk() (*string, bool)` + +GetLabelsOk returns a tuple with the Labels field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLabels + +`func (o *Policy) SetLabels(v string)` + +SetLabels sets Labels field to given value. + +### HasLabels + +`func (o *Policy) HasLabels() bool` + +HasLabels returns a boolean if a field has been set. + +### GetAnnotations + +`func (o *Policy) GetAnnotations() string` + +GetAnnotations returns the Annotations field if non-nil, zero value otherwise. + +### GetAnnotationsOk + +`func (o *Policy) GetAnnotationsOk() (*string, bool)` + +GetAnnotationsOk returns a tuple with the Annotations field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetAnnotations + +`func (o *Policy) SetAnnotations(v string)` + +SetAnnotations sets Annotations field to given value. + +### HasAnnotations + +`func (o *Policy) HasAnnotations() bool` + +HasAnnotations returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/components/ambient-api-server/pkg/api/openapi/docs/PolicyList.md b/components/ambient-api-server/pkg/api/openapi/docs/PolicyList.md new file mode 100644 index 000000000..47e808aa6 --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/docs/PolicyList.md @@ -0,0 +1,135 @@ +# PolicyList + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Kind** | **string** | | +**Page** | **int32** | | +**Size** | **int32** | | +**Total** | **int32** | | +**Items** | [**[]Policy**](Policy.md) | | + +## Methods + +### NewPolicyList + +`func NewPolicyList(kind string, page int32, size int32, total int32, items []Policy, ) *PolicyList` + +NewPolicyList instantiates a new PolicyList object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewPolicyListWithDefaults + +`func NewPolicyListWithDefaults() *PolicyList` + +NewPolicyListWithDefaults instantiates a new PolicyList object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetKind + +`func (o *PolicyList) GetKind() string` + +GetKind returns the Kind field if non-nil, zero value otherwise. + +### GetKindOk + +`func (o *PolicyList) GetKindOk() (*string, bool)` + +GetKindOk returns a tuple with the Kind field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetKind + +`func (o *PolicyList) SetKind(v string)` + +SetKind sets Kind field to given value. + + +### GetPage + +`func (o *PolicyList) GetPage() int32` + +GetPage returns the Page field if non-nil, zero value otherwise. + +### GetPageOk + +`func (o *PolicyList) GetPageOk() (*int32, bool)` + +GetPageOk returns a tuple with the Page field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPage + +`func (o *PolicyList) SetPage(v int32)` + +SetPage sets Page field to given value. + + +### GetSize + +`func (o *PolicyList) GetSize() int32` + +GetSize returns the Size field if non-nil, zero value otherwise. + +### GetSizeOk + +`func (o *PolicyList) GetSizeOk() (*int32, bool)` + +GetSizeOk returns a tuple with the Size field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSize + +`func (o *PolicyList) SetSize(v int32)` + +SetSize sets Size field to given value. + + +### GetTotal + +`func (o *PolicyList) GetTotal() int32` + +GetTotal returns the Total field if non-nil, zero value otherwise. + +### GetTotalOk + +`func (o *PolicyList) GetTotalOk() (*int32, bool)` + +GetTotalOk returns a tuple with the Total field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetTotal + +`func (o *PolicyList) SetTotal(v int32)` + +SetTotal sets Total field to given value. + + +### GetItems + +`func (o *PolicyList) GetItems() []Policy` + +GetItems returns the Items field if non-nil, zero value otherwise. + +### GetItemsOk + +`func (o *PolicyList) GetItemsOk() (*[]Policy, bool)` + +GetItemsOk returns a tuple with the Items field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetItems + +`func (o *PolicyList) SetItems(v []Policy)` + +SetItems sets Items field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/components/ambient-api-server/pkg/api/openapi/docs/PolicyPatchRequest.md b/components/ambient-api-server/pkg/api/openapi/docs/PolicyPatchRequest.md new file mode 100644 index 000000000..e25f99f60 --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/docs/PolicyPatchRequest.md @@ -0,0 +1,160 @@ +# PolicyPatchRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Name** | Pointer to **string** | | [optional] +**Namespace** | Pointer to **string** | | [optional] +**Spec** | Pointer to **map[string]interface{}** | | [optional] +**Labels** | Pointer to **string** | | [optional] +**Annotations** | Pointer to **string** | | [optional] + +## Methods + +### NewPolicyPatchRequest + +`func NewPolicyPatchRequest() *PolicyPatchRequest` + +NewPolicyPatchRequest instantiates a new PolicyPatchRequest object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewPolicyPatchRequestWithDefaults + +`func NewPolicyPatchRequestWithDefaults() *PolicyPatchRequest` + +NewPolicyPatchRequestWithDefaults instantiates a new PolicyPatchRequest object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetName + +`func (o *PolicyPatchRequest) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *PolicyPatchRequest) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *PolicyPatchRequest) SetName(v string)` + +SetName sets Name field to given value. + +### HasName + +`func (o *PolicyPatchRequest) HasName() bool` + +HasName returns a boolean if a field has been set. + +### GetNamespace + +`func (o *PolicyPatchRequest) GetNamespace() string` + +GetNamespace returns the Namespace field if non-nil, zero value otherwise. + +### GetNamespaceOk + +`func (o *PolicyPatchRequest) GetNamespaceOk() (*string, bool)` + +GetNamespaceOk returns a tuple with the Namespace field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetNamespace + +`func (o *PolicyPatchRequest) SetNamespace(v string)` + +SetNamespace sets Namespace field to given value. + +### HasNamespace + +`func (o *PolicyPatchRequest) HasNamespace() bool` + +HasNamespace returns a boolean if a field has been set. + +### GetSpec + +`func (o *PolicyPatchRequest) GetSpec() map[string]interface{}` + +GetSpec returns the Spec field if non-nil, zero value otherwise. + +### GetSpecOk + +`func (o *PolicyPatchRequest) GetSpecOk() (*map[string]interface{}, bool)` + +GetSpecOk returns a tuple with the Spec field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSpec + +`func (o *PolicyPatchRequest) SetSpec(v map[string]interface{})` + +SetSpec sets Spec field to given value. + +### HasSpec + +`func (o *PolicyPatchRequest) HasSpec() bool` + +HasSpec returns a boolean if a field has been set. + +### GetLabels + +`func (o *PolicyPatchRequest) GetLabels() string` + +GetLabels returns the Labels field if non-nil, zero value otherwise. + +### GetLabelsOk + +`func (o *PolicyPatchRequest) GetLabelsOk() (*string, bool)` + +GetLabelsOk returns a tuple with the Labels field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLabels + +`func (o *PolicyPatchRequest) SetLabels(v string)` + +SetLabels sets Labels field to given value. + +### HasLabels + +`func (o *PolicyPatchRequest) HasLabels() bool` + +HasLabels returns a boolean if a field has been set. + +### GetAnnotations + +`func (o *PolicyPatchRequest) GetAnnotations() string` + +GetAnnotations returns the Annotations field if non-nil, zero value otherwise. + +### GetAnnotationsOk + +`func (o *PolicyPatchRequest) GetAnnotationsOk() (*string, bool)` + +GetAnnotationsOk returns a tuple with the Annotations field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetAnnotations + +`func (o *PolicyPatchRequest) SetAnnotations(v string)` + +SetAnnotations sets Annotations field to given value. + +### HasAnnotations + +`func (o *PolicyPatchRequest) HasAnnotations() bool` + +HasAnnotations returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/components/ambient-api-server/pkg/api/openapi/docs/Provider.md b/components/ambient-api-server/pkg/api/openapi/docs/Provider.md new file mode 100644 index 000000000..82af297df --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/docs/Provider.md @@ -0,0 +1,332 @@ +# Provider + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Id** | Pointer to **string** | | [optional] +**Kind** | Pointer to **string** | | [optional] +**Href** | Pointer to **string** | | [optional] +**CreatedAt** | Pointer to **time.Time** | | [optional] +**UpdatedAt** | Pointer to **time.Time** | | [optional] +**ProjectId** | **string** | The project this provider belongs to | +**Name** | **string** | Human-readable identifier; unique within the project | +**Type** | Pointer to **string** | Provider type (e.g., github, anthropic, jira) | [optional] +**Secret** | Pointer to **string** | Name of the Kubernetes Secret containing credentials for this provider | [optional] +**Namespace** | Pointer to **string** | Source namespace where this provider was declared | [optional] +**Labels** | Pointer to **string** | | [optional] +**Annotations** | Pointer to **string** | | [optional] + +## Methods + +### NewProvider + +`func NewProvider(projectId string, name string, ) *Provider` + +NewProvider instantiates a new Provider object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewProviderWithDefaults + +`func NewProviderWithDefaults() *Provider` + +NewProviderWithDefaults instantiates a new Provider object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetId + +`func (o *Provider) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *Provider) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *Provider) SetId(v string)` + +SetId sets Id field to given value. + +### HasId + +`func (o *Provider) HasId() bool` + +HasId returns a boolean if a field has been set. + +### GetKind + +`func (o *Provider) GetKind() string` + +GetKind returns the Kind field if non-nil, zero value otherwise. + +### GetKindOk + +`func (o *Provider) GetKindOk() (*string, bool)` + +GetKindOk returns a tuple with the Kind field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetKind + +`func (o *Provider) SetKind(v string)` + +SetKind sets Kind field to given value. + +### HasKind + +`func (o *Provider) HasKind() bool` + +HasKind returns a boolean if a field has been set. + +### GetHref + +`func (o *Provider) GetHref() string` + +GetHref returns the Href field if non-nil, zero value otherwise. + +### GetHrefOk + +`func (o *Provider) GetHrefOk() (*string, bool)` + +GetHrefOk returns a tuple with the Href field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetHref + +`func (o *Provider) SetHref(v string)` + +SetHref sets Href field to given value. + +### HasHref + +`func (o *Provider) HasHref() bool` + +HasHref returns a boolean if a field has been set. + +### GetCreatedAt + +`func (o *Provider) GetCreatedAt() time.Time` + +GetCreatedAt returns the CreatedAt field if non-nil, zero value otherwise. + +### GetCreatedAtOk + +`func (o *Provider) GetCreatedAtOk() (*time.Time, bool)` + +GetCreatedAtOk returns a tuple with the CreatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCreatedAt + +`func (o *Provider) SetCreatedAt(v time.Time)` + +SetCreatedAt sets CreatedAt field to given value. + +### HasCreatedAt + +`func (o *Provider) HasCreatedAt() bool` + +HasCreatedAt returns a boolean if a field has been set. + +### GetUpdatedAt + +`func (o *Provider) GetUpdatedAt() time.Time` + +GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. + +### GetUpdatedAtOk + +`func (o *Provider) GetUpdatedAtOk() (*time.Time, bool)` + +GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUpdatedAt + +`func (o *Provider) SetUpdatedAt(v time.Time)` + +SetUpdatedAt sets UpdatedAt field to given value. + +### HasUpdatedAt + +`func (o *Provider) HasUpdatedAt() bool` + +HasUpdatedAt returns a boolean if a field has been set. + +### GetProjectId + +`func (o *Provider) GetProjectId() string` + +GetProjectId returns the ProjectId field if non-nil, zero value otherwise. + +### GetProjectIdOk + +`func (o *Provider) GetProjectIdOk() (*string, bool)` + +GetProjectIdOk returns a tuple with the ProjectId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetProjectId + +`func (o *Provider) SetProjectId(v string)` + +SetProjectId sets ProjectId field to given value. + + +### GetName + +`func (o *Provider) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *Provider) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *Provider) SetName(v string)` + +SetName sets Name field to given value. + + +### GetType + +`func (o *Provider) GetType() string` + +GetType returns the Type field if non-nil, zero value otherwise. + +### GetTypeOk + +`func (o *Provider) GetTypeOk() (*string, bool)` + +GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetType + +`func (o *Provider) SetType(v string)` + +SetType sets Type field to given value. + +### HasType + +`func (o *Provider) HasType() bool` + +HasType returns a boolean if a field has been set. + +### GetSecret + +`func (o *Provider) GetSecret() string` + +GetSecret returns the Secret field if non-nil, zero value otherwise. + +### GetSecretOk + +`func (o *Provider) GetSecretOk() (*string, bool)` + +GetSecretOk returns a tuple with the Secret field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSecret + +`func (o *Provider) SetSecret(v string)` + +SetSecret sets Secret field to given value. + +### HasSecret + +`func (o *Provider) HasSecret() bool` + +HasSecret returns a boolean if a field has been set. + +### GetNamespace + +`func (o *Provider) GetNamespace() string` + +GetNamespace returns the Namespace field if non-nil, zero value otherwise. + +### GetNamespaceOk + +`func (o *Provider) GetNamespaceOk() (*string, bool)` + +GetNamespaceOk returns a tuple with the Namespace field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetNamespace + +`func (o *Provider) SetNamespace(v string)` + +SetNamespace sets Namespace field to given value. + +### HasNamespace + +`func (o *Provider) HasNamespace() bool` + +HasNamespace returns a boolean if a field has been set. + +### GetLabels + +`func (o *Provider) GetLabels() string` + +GetLabels returns the Labels field if non-nil, zero value otherwise. + +### GetLabelsOk + +`func (o *Provider) GetLabelsOk() (*string, bool)` + +GetLabelsOk returns a tuple with the Labels field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLabels + +`func (o *Provider) SetLabels(v string)` + +SetLabels sets Labels field to given value. + +### HasLabels + +`func (o *Provider) HasLabels() bool` + +HasLabels returns a boolean if a field has been set. + +### GetAnnotations + +`func (o *Provider) GetAnnotations() string` + +GetAnnotations returns the Annotations field if non-nil, zero value otherwise. + +### GetAnnotationsOk + +`func (o *Provider) GetAnnotationsOk() (*string, bool)` + +GetAnnotationsOk returns a tuple with the Annotations field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetAnnotations + +`func (o *Provider) SetAnnotations(v string)` + +SetAnnotations sets Annotations field to given value. + +### HasAnnotations + +`func (o *Provider) HasAnnotations() bool` + +HasAnnotations returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/components/ambient-api-server/pkg/api/openapi/docs/ProviderList.md b/components/ambient-api-server/pkg/api/openapi/docs/ProviderList.md new file mode 100644 index 000000000..17670ca0f --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/docs/ProviderList.md @@ -0,0 +1,135 @@ +# ProviderList + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Kind** | **string** | | +**Page** | **int32** | | +**Size** | **int32** | | +**Total** | **int32** | | +**Items** | [**[]Provider**](Provider.md) | | + +## Methods + +### NewProviderList + +`func NewProviderList(kind string, page int32, size int32, total int32, items []Provider, ) *ProviderList` + +NewProviderList instantiates a new ProviderList object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewProviderListWithDefaults + +`func NewProviderListWithDefaults() *ProviderList` + +NewProviderListWithDefaults instantiates a new ProviderList object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetKind + +`func (o *ProviderList) GetKind() string` + +GetKind returns the Kind field if non-nil, zero value otherwise. + +### GetKindOk + +`func (o *ProviderList) GetKindOk() (*string, bool)` + +GetKindOk returns a tuple with the Kind field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetKind + +`func (o *ProviderList) SetKind(v string)` + +SetKind sets Kind field to given value. + + +### GetPage + +`func (o *ProviderList) GetPage() int32` + +GetPage returns the Page field if non-nil, zero value otherwise. + +### GetPageOk + +`func (o *ProviderList) GetPageOk() (*int32, bool)` + +GetPageOk returns a tuple with the Page field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPage + +`func (o *ProviderList) SetPage(v int32)` + +SetPage sets Page field to given value. + + +### GetSize + +`func (o *ProviderList) GetSize() int32` + +GetSize returns the Size field if non-nil, zero value otherwise. + +### GetSizeOk + +`func (o *ProviderList) GetSizeOk() (*int32, bool)` + +GetSizeOk returns a tuple with the Size field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSize + +`func (o *ProviderList) SetSize(v int32)` + +SetSize sets Size field to given value. + + +### GetTotal + +`func (o *ProviderList) GetTotal() int32` + +GetTotal returns the Total field if non-nil, zero value otherwise. + +### GetTotalOk + +`func (o *ProviderList) GetTotalOk() (*int32, bool)` + +GetTotalOk returns a tuple with the Total field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetTotal + +`func (o *ProviderList) SetTotal(v int32)` + +SetTotal sets Total field to given value. + + +### GetItems + +`func (o *ProviderList) GetItems() []Provider` + +GetItems returns the Items field if non-nil, zero value otherwise. + +### GetItemsOk + +`func (o *ProviderList) GetItemsOk() (*[]Provider, bool)` + +GetItemsOk returns a tuple with the Items field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetItems + +`func (o *ProviderList) SetItems(v []Provider)` + +SetItems sets Items field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/components/ambient-api-server/pkg/api/openapi/docs/ProviderPatchRequest.md b/components/ambient-api-server/pkg/api/openapi/docs/ProviderPatchRequest.md new file mode 100644 index 000000000..ce6025a06 --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/docs/ProviderPatchRequest.md @@ -0,0 +1,186 @@ +# ProviderPatchRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Name** | Pointer to **string** | | [optional] +**Type** | Pointer to **string** | | [optional] +**Secret** | Pointer to **string** | | [optional] +**Namespace** | Pointer to **string** | | [optional] +**Labels** | Pointer to **string** | | [optional] +**Annotations** | Pointer to **string** | | [optional] + +## Methods + +### NewProviderPatchRequest + +`func NewProviderPatchRequest() *ProviderPatchRequest` + +NewProviderPatchRequest instantiates a new ProviderPatchRequest object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewProviderPatchRequestWithDefaults + +`func NewProviderPatchRequestWithDefaults() *ProviderPatchRequest` + +NewProviderPatchRequestWithDefaults instantiates a new ProviderPatchRequest object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetName + +`func (o *ProviderPatchRequest) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *ProviderPatchRequest) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *ProviderPatchRequest) SetName(v string)` + +SetName sets Name field to given value. + +### HasName + +`func (o *ProviderPatchRequest) HasName() bool` + +HasName returns a boolean if a field has been set. + +### GetType + +`func (o *ProviderPatchRequest) GetType() string` + +GetType returns the Type field if non-nil, zero value otherwise. + +### GetTypeOk + +`func (o *ProviderPatchRequest) GetTypeOk() (*string, bool)` + +GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetType + +`func (o *ProviderPatchRequest) SetType(v string)` + +SetType sets Type field to given value. + +### HasType + +`func (o *ProviderPatchRequest) HasType() bool` + +HasType returns a boolean if a field has been set. + +### GetSecret + +`func (o *ProviderPatchRequest) GetSecret() string` + +GetSecret returns the Secret field if non-nil, zero value otherwise. + +### GetSecretOk + +`func (o *ProviderPatchRequest) GetSecretOk() (*string, bool)` + +GetSecretOk returns a tuple with the Secret field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSecret + +`func (o *ProviderPatchRequest) SetSecret(v string)` + +SetSecret sets Secret field to given value. + +### HasSecret + +`func (o *ProviderPatchRequest) HasSecret() bool` + +HasSecret returns a boolean if a field has been set. + +### GetNamespace + +`func (o *ProviderPatchRequest) GetNamespace() string` + +GetNamespace returns the Namespace field if non-nil, zero value otherwise. + +### GetNamespaceOk + +`func (o *ProviderPatchRequest) GetNamespaceOk() (*string, bool)` + +GetNamespaceOk returns a tuple with the Namespace field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetNamespace + +`func (o *ProviderPatchRequest) SetNamespace(v string)` + +SetNamespace sets Namespace field to given value. + +### HasNamespace + +`func (o *ProviderPatchRequest) HasNamespace() bool` + +HasNamespace returns a boolean if a field has been set. + +### GetLabels + +`func (o *ProviderPatchRequest) GetLabels() string` + +GetLabels returns the Labels field if non-nil, zero value otherwise. + +### GetLabelsOk + +`func (o *ProviderPatchRequest) GetLabelsOk() (*string, bool)` + +GetLabelsOk returns a tuple with the Labels field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLabels + +`func (o *ProviderPatchRequest) SetLabels(v string)` + +SetLabels sets Labels field to given value. + +### HasLabels + +`func (o *ProviderPatchRequest) HasLabels() bool` + +HasLabels returns a boolean if a field has been set. + +### GetAnnotations + +`func (o *ProviderPatchRequest) GetAnnotations() string` + +GetAnnotations returns the Annotations field if non-nil, zero value otherwise. + +### GetAnnotationsOk + +`func (o *ProviderPatchRequest) GetAnnotationsOk() (*string, bool)` + +GetAnnotationsOk returns a tuple with the Annotations field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetAnnotations + +`func (o *ProviderPatchRequest) SetAnnotations(v string)` + +SetAnnotations sets Annotations field to given value. + +### HasAnnotations + +`func (o *ProviderPatchRequest) HasAnnotations() bool` + +HasAnnotations returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/components/ambient-api-server/pkg/api/openapi/model_policy.go b/components/ambient-api-server/pkg/api/openapi/model_policy.go new file mode 100644 index 000000000..5e141c170 --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/model_policy.go @@ -0,0 +1,514 @@ +/* +Ambient API Server + +Ambient API Server + +API version: 1.0.0 +Contact: ambient-code@redhat.com +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "bytes" + "encoding/json" + "fmt" + "time" +) + +// checks if the Policy type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &Policy{} + +// Policy struct for Policy +type Policy struct { + Id *string `json:"id,omitempty"` + Kind *string `json:"kind,omitempty"` + Href *string `json:"href,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + // The project this policy belongs to + ProjectId string `json:"project_id"` + // Human-readable identifier; unique within the project + Name string `json:"name"` + // Source namespace where this policy was declared + Namespace *string `json:"namespace,omitempty"` + // Full policy specification (network_policies, filesystem, process, landlock) + Spec map[string]interface{} `json:"spec,omitempty"` + Labels *string `json:"labels,omitempty"` + Annotations *string `json:"annotations,omitempty"` +} + +type _Policy Policy + +// NewPolicy instantiates a new Policy object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewPolicy(projectId string, name string) *Policy { + this := Policy{} + this.ProjectId = projectId + this.Name = name + return &this +} + +// NewPolicyWithDefaults instantiates a new Policy object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewPolicyWithDefaults() *Policy { + this := Policy{} + return &this +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *Policy) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Policy) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *Policy) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *Policy) SetId(v string) { + o.Id = &v +} + +// GetKind returns the Kind field value if set, zero value otherwise. +func (o *Policy) GetKind() string { + if o == nil || IsNil(o.Kind) { + var ret string + return ret + } + return *o.Kind +} + +// GetKindOk returns a tuple with the Kind field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Policy) GetKindOk() (*string, bool) { + if o == nil || IsNil(o.Kind) { + return nil, false + } + return o.Kind, true +} + +// HasKind returns a boolean if a field has been set. +func (o *Policy) HasKind() bool { + if o != nil && !IsNil(o.Kind) { + return true + } + + return false +} + +// SetKind gets a reference to the given string and assigns it to the Kind field. +func (o *Policy) SetKind(v string) { + o.Kind = &v +} + +// GetHref returns the Href field value if set, zero value otherwise. +func (o *Policy) GetHref() string { + if o == nil || IsNil(o.Href) { + var ret string + return ret + } + return *o.Href +} + +// GetHrefOk returns a tuple with the Href field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Policy) GetHrefOk() (*string, bool) { + if o == nil || IsNil(o.Href) { + return nil, false + } + return o.Href, true +} + +// HasHref returns a boolean if a field has been set. +func (o *Policy) HasHref() bool { + if o != nil && !IsNil(o.Href) { + return true + } + + return false +} + +// SetHref gets a reference to the given string and assigns it to the Href field. +func (o *Policy) SetHref(v string) { + o.Href = &v +} + +// GetCreatedAt returns the CreatedAt field value if set, zero value otherwise. +func (o *Policy) GetCreatedAt() time.Time { + if o == nil || IsNil(o.CreatedAt) { + var ret time.Time + return ret + } + return *o.CreatedAt +} + +// GetCreatedAtOk returns a tuple with the CreatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Policy) GetCreatedAtOk() (*time.Time, bool) { + if o == nil || IsNil(o.CreatedAt) { + return nil, false + } + return o.CreatedAt, true +} + +// HasCreatedAt returns a boolean if a field has been set. +func (o *Policy) HasCreatedAt() bool { + if o != nil && !IsNil(o.CreatedAt) { + return true + } + + return false +} + +// SetCreatedAt gets a reference to the given time.Time and assigns it to the CreatedAt field. +func (o *Policy) SetCreatedAt(v time.Time) { + o.CreatedAt = &v +} + +// GetUpdatedAt returns the UpdatedAt field value if set, zero value otherwise. +func (o *Policy) GetUpdatedAt() time.Time { + if o == nil || IsNil(o.UpdatedAt) { + var ret time.Time + return ret + } + return *o.UpdatedAt +} + +// GetUpdatedAtOk returns a tuple with the UpdatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Policy) GetUpdatedAtOk() (*time.Time, bool) { + if o == nil || IsNil(o.UpdatedAt) { + return nil, false + } + return o.UpdatedAt, true +} + +// HasUpdatedAt returns a boolean if a field has been set. +func (o *Policy) HasUpdatedAt() bool { + if o != nil && !IsNil(o.UpdatedAt) { + return true + } + + return false +} + +// SetUpdatedAt gets a reference to the given time.Time and assigns it to the UpdatedAt field. +func (o *Policy) SetUpdatedAt(v time.Time) { + o.UpdatedAt = &v +} + +// GetProjectId returns the ProjectId field value +func (o *Policy) GetProjectId() string { + if o == nil { + var ret string + return ret + } + + return o.ProjectId +} + +// GetProjectIdOk returns a tuple with the ProjectId field value +// and a boolean to check if the value has been set. +func (o *Policy) GetProjectIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.ProjectId, true +} + +// SetProjectId sets field value +func (o *Policy) SetProjectId(v string) { + o.ProjectId = v +} + +// GetName returns the Name field value +func (o *Policy) GetName() string { + if o == nil { + var ret string + return ret + } + + return o.Name +} + +// GetNameOk returns a tuple with the Name field value +// and a boolean to check if the value has been set. +func (o *Policy) GetNameOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Name, true +} + +// SetName sets field value +func (o *Policy) SetName(v string) { + o.Name = v +} + +// GetNamespace returns the Namespace field value if set, zero value otherwise. +func (o *Policy) GetNamespace() string { + if o == nil || IsNil(o.Namespace) { + var ret string + return ret + } + return *o.Namespace +} + +// GetNamespaceOk returns a tuple with the Namespace field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Policy) GetNamespaceOk() (*string, bool) { + if o == nil || IsNil(o.Namespace) { + return nil, false + } + return o.Namespace, true +} + +// HasNamespace returns a boolean if a field has been set. +func (o *Policy) HasNamespace() bool { + if o != nil && !IsNil(o.Namespace) { + return true + } + + return false +} + +// SetNamespace gets a reference to the given string and assigns it to the Namespace field. +func (o *Policy) SetNamespace(v string) { + o.Namespace = &v +} + +// GetSpec returns the Spec field value if set, zero value otherwise. +func (o *Policy) GetSpec() map[string]interface{} { + if o == nil || IsNil(o.Spec) { + var ret map[string]interface{} + return ret + } + return o.Spec +} + +// GetSpecOk returns a tuple with the Spec field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Policy) GetSpecOk() (map[string]interface{}, bool) { + if o == nil || IsNil(o.Spec) { + return map[string]interface{}{}, false + } + return o.Spec, true +} + +// HasSpec returns a boolean if a field has been set. +func (o *Policy) HasSpec() bool { + if o != nil && !IsNil(o.Spec) { + return true + } + + return false +} + +// SetSpec gets a reference to the given map[string]interface{} and assigns it to the Spec field. +func (o *Policy) SetSpec(v map[string]interface{}) { + o.Spec = v +} + +// GetLabels returns the Labels field value if set, zero value otherwise. +func (o *Policy) GetLabels() string { + if o == nil || IsNil(o.Labels) { + var ret string + return ret + } + return *o.Labels +} + +// GetLabelsOk returns a tuple with the Labels field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Policy) GetLabelsOk() (*string, bool) { + if o == nil || IsNil(o.Labels) { + return nil, false + } + return o.Labels, true +} + +// HasLabels returns a boolean if a field has been set. +func (o *Policy) HasLabels() bool { + if o != nil && !IsNil(o.Labels) { + return true + } + + return false +} + +// SetLabels gets a reference to the given string and assigns it to the Labels field. +func (o *Policy) SetLabels(v string) { + o.Labels = &v +} + +// GetAnnotations returns the Annotations field value if set, zero value otherwise. +func (o *Policy) GetAnnotations() string { + if o == nil || IsNil(o.Annotations) { + var ret string + return ret + } + return *o.Annotations +} + +// GetAnnotationsOk returns a tuple with the Annotations field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Policy) GetAnnotationsOk() (*string, bool) { + if o == nil || IsNil(o.Annotations) { + return nil, false + } + return o.Annotations, true +} + +// HasAnnotations returns a boolean if a field has been set. +func (o *Policy) HasAnnotations() bool { + if o != nil && !IsNil(o.Annotations) { + return true + } + + return false +} + +// SetAnnotations gets a reference to the given string and assigns it to the Annotations field. +func (o *Policy) SetAnnotations(v string) { + o.Annotations = &v +} + +func (o Policy) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o Policy) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.Kind) { + toSerialize["kind"] = o.Kind + } + if !IsNil(o.Href) { + toSerialize["href"] = o.Href + } + if !IsNil(o.CreatedAt) { + toSerialize["created_at"] = o.CreatedAt + } + if !IsNil(o.UpdatedAt) { + toSerialize["updated_at"] = o.UpdatedAt + } + toSerialize["project_id"] = o.ProjectId + toSerialize["name"] = o.Name + if !IsNil(o.Namespace) { + toSerialize["namespace"] = o.Namespace + } + if !IsNil(o.Spec) { + toSerialize["spec"] = o.Spec + } + if !IsNil(o.Labels) { + toSerialize["labels"] = o.Labels + } + if !IsNil(o.Annotations) { + toSerialize["annotations"] = o.Annotations + } + return toSerialize, nil +} + +func (o *Policy) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "project_id", + "name", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varPolicy := _Policy{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varPolicy) + + if err != nil { + return err + } + + *o = Policy(varPolicy) + + return err +} + +type NullablePolicy struct { + value *Policy + isSet bool +} + +func (v NullablePolicy) Get() *Policy { + return v.value +} + +func (v *NullablePolicy) Set(val *Policy) { + v.value = val + v.isSet = true +} + +func (v NullablePolicy) IsSet() bool { + return v.isSet +} + +func (v *NullablePolicy) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullablePolicy(val *Policy) *NullablePolicy { + return &NullablePolicy{value: val, isSet: true} +} + +func (v NullablePolicy) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullablePolicy) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/components/ambient-api-server/pkg/api/openapi/model_policy_list.go b/components/ambient-api-server/pkg/api/openapi/model_policy_list.go new file mode 100644 index 000000000..e4251b1ed --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/model_policy_list.go @@ -0,0 +1,269 @@ +/* +Ambient API Server + +Ambient API Server + +API version: 1.0.0 +Contact: ambient-code@redhat.com +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the PolicyList type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &PolicyList{} + +// PolicyList struct for PolicyList +type PolicyList struct { + Kind string `json:"kind"` + Page int32 `json:"page"` + Size int32 `json:"size"` + Total int32 `json:"total"` + Items []Policy `json:"items"` +} + +type _PolicyList PolicyList + +// NewPolicyList instantiates a new PolicyList object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewPolicyList(kind string, page int32, size int32, total int32, items []Policy) *PolicyList { + this := PolicyList{} + this.Kind = kind + this.Page = page + this.Size = size + this.Total = total + this.Items = items + return &this +} + +// NewPolicyListWithDefaults instantiates a new PolicyList object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewPolicyListWithDefaults() *PolicyList { + this := PolicyList{} + return &this +} + +// GetKind returns the Kind field value +func (o *PolicyList) GetKind() string { + if o == nil { + var ret string + return ret + } + + return o.Kind +} + +// GetKindOk returns a tuple with the Kind field value +// and a boolean to check if the value has been set. +func (o *PolicyList) GetKindOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Kind, true +} + +// SetKind sets field value +func (o *PolicyList) SetKind(v string) { + o.Kind = v +} + +// GetPage returns the Page field value +func (o *PolicyList) GetPage() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Page +} + +// GetPageOk returns a tuple with the Page field value +// and a boolean to check if the value has been set. +func (o *PolicyList) GetPageOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Page, true +} + +// SetPage sets field value +func (o *PolicyList) SetPage(v int32) { + o.Page = v +} + +// GetSize returns the Size field value +func (o *PolicyList) GetSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Size +} + +// GetSizeOk returns a tuple with the Size field value +// and a boolean to check if the value has been set. +func (o *PolicyList) GetSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Size, true +} + +// SetSize sets field value +func (o *PolicyList) SetSize(v int32) { + o.Size = v +} + +// GetTotal returns the Total field value +func (o *PolicyList) GetTotal() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Total +} + +// GetTotalOk returns a tuple with the Total field value +// and a boolean to check if the value has been set. +func (o *PolicyList) GetTotalOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Total, true +} + +// SetTotal sets field value +func (o *PolicyList) SetTotal(v int32) { + o.Total = v +} + +// GetItems returns the Items field value +func (o *PolicyList) GetItems() []Policy { + if o == nil { + var ret []Policy + return ret + } + + return o.Items +} + +// GetItemsOk returns a tuple with the Items field value +// and a boolean to check if the value has been set. +func (o *PolicyList) GetItemsOk() ([]Policy, bool) { + if o == nil { + return nil, false + } + return o.Items, true +} + +// SetItems sets field value +func (o *PolicyList) SetItems(v []Policy) { + o.Items = v +} + +func (o PolicyList) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o PolicyList) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["kind"] = o.Kind + toSerialize["page"] = o.Page + toSerialize["size"] = o.Size + toSerialize["total"] = o.Total + toSerialize["items"] = o.Items + return toSerialize, nil +} + +func (o *PolicyList) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "kind", + "page", + "size", + "total", + "items", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varPolicyList := _PolicyList{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varPolicyList) + + if err != nil { + return err + } + + *o = PolicyList(varPolicyList) + + return err +} + +type NullablePolicyList struct { + value *PolicyList + isSet bool +} + +func (v NullablePolicyList) Get() *PolicyList { + return v.value +} + +func (v *NullablePolicyList) Set(val *PolicyList) { + v.value = val + v.isSet = true +} + +func (v NullablePolicyList) IsSet() bool { + return v.isSet +} + +func (v *NullablePolicyList) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullablePolicyList(val *PolicyList) *NullablePolicyList { + return &NullablePolicyList{value: val, isSet: true} +} + +func (v NullablePolicyList) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullablePolicyList) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/components/ambient-api-server/pkg/api/openapi/model_policy_patch_request.go b/components/ambient-api-server/pkg/api/openapi/model_policy_patch_request.go new file mode 100644 index 000000000..21bab9d7b --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/model_policy_patch_request.go @@ -0,0 +1,269 @@ +/* +Ambient API Server + +Ambient API Server + +API version: 1.0.0 +Contact: ambient-code@redhat.com +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the PolicyPatchRequest type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &PolicyPatchRequest{} + +// PolicyPatchRequest struct for PolicyPatchRequest +type PolicyPatchRequest struct { + Name *string `json:"name,omitempty"` + Namespace *string `json:"namespace,omitempty"` + Spec map[string]interface{} `json:"spec,omitempty"` + Labels *string `json:"labels,omitempty"` + Annotations *string `json:"annotations,omitempty"` +} + +// NewPolicyPatchRequest instantiates a new PolicyPatchRequest object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewPolicyPatchRequest() *PolicyPatchRequest { + this := PolicyPatchRequest{} + return &this +} + +// NewPolicyPatchRequestWithDefaults instantiates a new PolicyPatchRequest object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewPolicyPatchRequestWithDefaults() *PolicyPatchRequest { + this := PolicyPatchRequest{} + return &this +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *PolicyPatchRequest) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *PolicyPatchRequest) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *PolicyPatchRequest) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *PolicyPatchRequest) SetName(v string) { + o.Name = &v +} + +// GetNamespace returns the Namespace field value if set, zero value otherwise. +func (o *PolicyPatchRequest) GetNamespace() string { + if o == nil || IsNil(o.Namespace) { + var ret string + return ret + } + return *o.Namespace +} + +// GetNamespaceOk returns a tuple with the Namespace field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *PolicyPatchRequest) GetNamespaceOk() (*string, bool) { + if o == nil || IsNil(o.Namespace) { + return nil, false + } + return o.Namespace, true +} + +// HasNamespace returns a boolean if a field has been set. +func (o *PolicyPatchRequest) HasNamespace() bool { + if o != nil && !IsNil(o.Namespace) { + return true + } + + return false +} + +// SetNamespace gets a reference to the given string and assigns it to the Namespace field. +func (o *PolicyPatchRequest) SetNamespace(v string) { + o.Namespace = &v +} + +// GetSpec returns the Spec field value if set, zero value otherwise. +func (o *PolicyPatchRequest) GetSpec() map[string]interface{} { + if o == nil || IsNil(o.Spec) { + var ret map[string]interface{} + return ret + } + return o.Spec +} + +// GetSpecOk returns a tuple with the Spec field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *PolicyPatchRequest) GetSpecOk() (map[string]interface{}, bool) { + if o == nil || IsNil(o.Spec) { + return map[string]interface{}{}, false + } + return o.Spec, true +} + +// HasSpec returns a boolean if a field has been set. +func (o *PolicyPatchRequest) HasSpec() bool { + if o != nil && !IsNil(o.Spec) { + return true + } + + return false +} + +// SetSpec gets a reference to the given map[string]interface{} and assigns it to the Spec field. +func (o *PolicyPatchRequest) SetSpec(v map[string]interface{}) { + o.Spec = v +} + +// GetLabels returns the Labels field value if set, zero value otherwise. +func (o *PolicyPatchRequest) GetLabels() string { + if o == nil || IsNil(o.Labels) { + var ret string + return ret + } + return *o.Labels +} + +// GetLabelsOk returns a tuple with the Labels field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *PolicyPatchRequest) GetLabelsOk() (*string, bool) { + if o == nil || IsNil(o.Labels) { + return nil, false + } + return o.Labels, true +} + +// HasLabels returns a boolean if a field has been set. +func (o *PolicyPatchRequest) HasLabels() bool { + if o != nil && !IsNil(o.Labels) { + return true + } + + return false +} + +// SetLabels gets a reference to the given string and assigns it to the Labels field. +func (o *PolicyPatchRequest) SetLabels(v string) { + o.Labels = &v +} + +// GetAnnotations returns the Annotations field value if set, zero value otherwise. +func (o *PolicyPatchRequest) GetAnnotations() string { + if o == nil || IsNil(o.Annotations) { + var ret string + return ret + } + return *o.Annotations +} + +// GetAnnotationsOk returns a tuple with the Annotations field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *PolicyPatchRequest) GetAnnotationsOk() (*string, bool) { + if o == nil || IsNil(o.Annotations) { + return nil, false + } + return o.Annotations, true +} + +// HasAnnotations returns a boolean if a field has been set. +func (o *PolicyPatchRequest) HasAnnotations() bool { + if o != nil && !IsNil(o.Annotations) { + return true + } + + return false +} + +// SetAnnotations gets a reference to the given string and assigns it to the Annotations field. +func (o *PolicyPatchRequest) SetAnnotations(v string) { + o.Annotations = &v +} + +func (o PolicyPatchRequest) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o PolicyPatchRequest) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.Namespace) { + toSerialize["namespace"] = o.Namespace + } + if !IsNil(o.Spec) { + toSerialize["spec"] = o.Spec + } + if !IsNil(o.Labels) { + toSerialize["labels"] = o.Labels + } + if !IsNil(o.Annotations) { + toSerialize["annotations"] = o.Annotations + } + return toSerialize, nil +} + +type NullablePolicyPatchRequest struct { + value *PolicyPatchRequest + isSet bool +} + +func (v NullablePolicyPatchRequest) Get() *PolicyPatchRequest { + return v.value +} + +func (v *NullablePolicyPatchRequest) Set(val *PolicyPatchRequest) { + v.value = val + v.isSet = true +} + +func (v NullablePolicyPatchRequest) IsSet() bool { + return v.isSet +} + +func (v *NullablePolicyPatchRequest) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullablePolicyPatchRequest(val *PolicyPatchRequest) *NullablePolicyPatchRequest { + return &NullablePolicyPatchRequest{value: val, isSet: true} +} + +func (v NullablePolicyPatchRequest) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullablePolicyPatchRequest) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/components/ambient-api-server/pkg/api/openapi/model_provider.go b/components/ambient-api-server/pkg/api/openapi/model_provider.go new file mode 100644 index 000000000..79ee3fda3 --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/model_provider.go @@ -0,0 +1,551 @@ +/* +Ambient API Server + +Ambient API Server + +API version: 1.0.0 +Contact: ambient-code@redhat.com +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "bytes" + "encoding/json" + "fmt" + "time" +) + +// checks if the Provider type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &Provider{} + +// Provider struct for Provider +type Provider struct { + Id *string `json:"id,omitempty"` + Kind *string `json:"kind,omitempty"` + Href *string `json:"href,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + // The project this provider belongs to + ProjectId string `json:"project_id"` + // Human-readable identifier; unique within the project + Name string `json:"name"` + // Provider type (e.g., github, anthropic, jira) + Type *string `json:"type,omitempty"` + // Name of the Kubernetes Secret containing credentials for this provider + Secret *string `json:"secret,omitempty"` + // Source namespace where this provider was declared + Namespace *string `json:"namespace,omitempty"` + Labels *string `json:"labels,omitempty"` + Annotations *string `json:"annotations,omitempty"` +} + +type _Provider Provider + +// NewProvider instantiates a new Provider object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewProvider(projectId string, name string) *Provider { + this := Provider{} + this.ProjectId = projectId + this.Name = name + return &this +} + +// NewProviderWithDefaults instantiates a new Provider object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewProviderWithDefaults() *Provider { + this := Provider{} + return &this +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *Provider) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Provider) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *Provider) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *Provider) SetId(v string) { + o.Id = &v +} + +// GetKind returns the Kind field value if set, zero value otherwise. +func (o *Provider) GetKind() string { + if o == nil || IsNil(o.Kind) { + var ret string + return ret + } + return *o.Kind +} + +// GetKindOk returns a tuple with the Kind field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Provider) GetKindOk() (*string, bool) { + if o == nil || IsNil(o.Kind) { + return nil, false + } + return o.Kind, true +} + +// HasKind returns a boolean if a field has been set. +func (o *Provider) HasKind() bool { + if o != nil && !IsNil(o.Kind) { + return true + } + + return false +} + +// SetKind gets a reference to the given string and assigns it to the Kind field. +func (o *Provider) SetKind(v string) { + o.Kind = &v +} + +// GetHref returns the Href field value if set, zero value otherwise. +func (o *Provider) GetHref() string { + if o == nil || IsNil(o.Href) { + var ret string + return ret + } + return *o.Href +} + +// GetHrefOk returns a tuple with the Href field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Provider) GetHrefOk() (*string, bool) { + if o == nil || IsNil(o.Href) { + return nil, false + } + return o.Href, true +} + +// HasHref returns a boolean if a field has been set. +func (o *Provider) HasHref() bool { + if o != nil && !IsNil(o.Href) { + return true + } + + return false +} + +// SetHref gets a reference to the given string and assigns it to the Href field. +func (o *Provider) SetHref(v string) { + o.Href = &v +} + +// GetCreatedAt returns the CreatedAt field value if set, zero value otherwise. +func (o *Provider) GetCreatedAt() time.Time { + if o == nil || IsNil(o.CreatedAt) { + var ret time.Time + return ret + } + return *o.CreatedAt +} + +// GetCreatedAtOk returns a tuple with the CreatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Provider) GetCreatedAtOk() (*time.Time, bool) { + if o == nil || IsNil(o.CreatedAt) { + return nil, false + } + return o.CreatedAt, true +} + +// HasCreatedAt returns a boolean if a field has been set. +func (o *Provider) HasCreatedAt() bool { + if o != nil && !IsNil(o.CreatedAt) { + return true + } + + return false +} + +// SetCreatedAt gets a reference to the given time.Time and assigns it to the CreatedAt field. +func (o *Provider) SetCreatedAt(v time.Time) { + o.CreatedAt = &v +} + +// GetUpdatedAt returns the UpdatedAt field value if set, zero value otherwise. +func (o *Provider) GetUpdatedAt() time.Time { + if o == nil || IsNil(o.UpdatedAt) { + var ret time.Time + return ret + } + return *o.UpdatedAt +} + +// GetUpdatedAtOk returns a tuple with the UpdatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Provider) GetUpdatedAtOk() (*time.Time, bool) { + if o == nil || IsNil(o.UpdatedAt) { + return nil, false + } + return o.UpdatedAt, true +} + +// HasUpdatedAt returns a boolean if a field has been set. +func (o *Provider) HasUpdatedAt() bool { + if o != nil && !IsNil(o.UpdatedAt) { + return true + } + + return false +} + +// SetUpdatedAt gets a reference to the given time.Time and assigns it to the UpdatedAt field. +func (o *Provider) SetUpdatedAt(v time.Time) { + o.UpdatedAt = &v +} + +// GetProjectId returns the ProjectId field value +func (o *Provider) GetProjectId() string { + if o == nil { + var ret string + return ret + } + + return o.ProjectId +} + +// GetProjectIdOk returns a tuple with the ProjectId field value +// and a boolean to check if the value has been set. +func (o *Provider) GetProjectIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.ProjectId, true +} + +// SetProjectId sets field value +func (o *Provider) SetProjectId(v string) { + o.ProjectId = v +} + +// GetName returns the Name field value +func (o *Provider) GetName() string { + if o == nil { + var ret string + return ret + } + + return o.Name +} + +// GetNameOk returns a tuple with the Name field value +// and a boolean to check if the value has been set. +func (o *Provider) GetNameOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Name, true +} + +// SetName sets field value +func (o *Provider) SetName(v string) { + o.Name = v +} + +// GetType returns the Type field value if set, zero value otherwise. +func (o *Provider) GetType() string { + if o == nil || IsNil(o.Type) { + var ret string + return ret + } + return *o.Type +} + +// GetTypeOk returns a tuple with the Type field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Provider) GetTypeOk() (*string, bool) { + if o == nil || IsNil(o.Type) { + return nil, false + } + return o.Type, true +} + +// HasType returns a boolean if a field has been set. +func (o *Provider) HasType() bool { + if o != nil && !IsNil(o.Type) { + return true + } + + return false +} + +// SetType gets a reference to the given string and assigns it to the Type field. +func (o *Provider) SetType(v string) { + o.Type = &v +} + +// GetSecret returns the Secret field value if set, zero value otherwise. +func (o *Provider) GetSecret() string { + if o == nil || IsNil(o.Secret) { + var ret string + return ret + } + return *o.Secret +} + +// GetSecretOk returns a tuple with the Secret field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Provider) GetSecretOk() (*string, bool) { + if o == nil || IsNil(o.Secret) { + return nil, false + } + return o.Secret, true +} + +// HasSecret returns a boolean if a field has been set. +func (o *Provider) HasSecret() bool { + if o != nil && !IsNil(o.Secret) { + return true + } + + return false +} + +// SetSecret gets a reference to the given string and assigns it to the Secret field. +func (o *Provider) SetSecret(v string) { + o.Secret = &v +} + +// GetNamespace returns the Namespace field value if set, zero value otherwise. +func (o *Provider) GetNamespace() string { + if o == nil || IsNil(o.Namespace) { + var ret string + return ret + } + return *o.Namespace +} + +// GetNamespaceOk returns a tuple with the Namespace field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Provider) GetNamespaceOk() (*string, bool) { + if o == nil || IsNil(o.Namespace) { + return nil, false + } + return o.Namespace, true +} + +// HasNamespace returns a boolean if a field has been set. +func (o *Provider) HasNamespace() bool { + if o != nil && !IsNil(o.Namespace) { + return true + } + + return false +} + +// SetNamespace gets a reference to the given string and assigns it to the Namespace field. +func (o *Provider) SetNamespace(v string) { + o.Namespace = &v +} + +// GetLabels returns the Labels field value if set, zero value otherwise. +func (o *Provider) GetLabels() string { + if o == nil || IsNil(o.Labels) { + var ret string + return ret + } + return *o.Labels +} + +// GetLabelsOk returns a tuple with the Labels field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Provider) GetLabelsOk() (*string, bool) { + if o == nil || IsNil(o.Labels) { + return nil, false + } + return o.Labels, true +} + +// HasLabels returns a boolean if a field has been set. +func (o *Provider) HasLabels() bool { + if o != nil && !IsNil(o.Labels) { + return true + } + + return false +} + +// SetLabels gets a reference to the given string and assigns it to the Labels field. +func (o *Provider) SetLabels(v string) { + o.Labels = &v +} + +// GetAnnotations returns the Annotations field value if set, zero value otherwise. +func (o *Provider) GetAnnotations() string { + if o == nil || IsNil(o.Annotations) { + var ret string + return ret + } + return *o.Annotations +} + +// GetAnnotationsOk returns a tuple with the Annotations field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Provider) GetAnnotationsOk() (*string, bool) { + if o == nil || IsNil(o.Annotations) { + return nil, false + } + return o.Annotations, true +} + +// HasAnnotations returns a boolean if a field has been set. +func (o *Provider) HasAnnotations() bool { + if o != nil && !IsNil(o.Annotations) { + return true + } + + return false +} + +// SetAnnotations gets a reference to the given string and assigns it to the Annotations field. +func (o *Provider) SetAnnotations(v string) { + o.Annotations = &v +} + +func (o Provider) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o Provider) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.Kind) { + toSerialize["kind"] = o.Kind + } + if !IsNil(o.Href) { + toSerialize["href"] = o.Href + } + if !IsNil(o.CreatedAt) { + toSerialize["created_at"] = o.CreatedAt + } + if !IsNil(o.UpdatedAt) { + toSerialize["updated_at"] = o.UpdatedAt + } + toSerialize["project_id"] = o.ProjectId + toSerialize["name"] = o.Name + if !IsNil(o.Type) { + toSerialize["type"] = o.Type + } + if !IsNil(o.Secret) { + toSerialize["secret"] = o.Secret + } + if !IsNil(o.Namespace) { + toSerialize["namespace"] = o.Namespace + } + if !IsNil(o.Labels) { + toSerialize["labels"] = o.Labels + } + if !IsNil(o.Annotations) { + toSerialize["annotations"] = o.Annotations + } + return toSerialize, nil +} + +func (o *Provider) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "project_id", + "name", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varProvider := _Provider{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varProvider) + + if err != nil { + return err + } + + *o = Provider(varProvider) + + return err +} + +type NullableProvider struct { + value *Provider + isSet bool +} + +func (v NullableProvider) Get() *Provider { + return v.value +} + +func (v *NullableProvider) Set(val *Provider) { + v.value = val + v.isSet = true +} + +func (v NullableProvider) IsSet() bool { + return v.isSet +} + +func (v *NullableProvider) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableProvider(val *Provider) *NullableProvider { + return &NullableProvider{value: val, isSet: true} +} + +func (v NullableProvider) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableProvider) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/components/ambient-api-server/pkg/api/openapi/model_provider_list.go b/components/ambient-api-server/pkg/api/openapi/model_provider_list.go new file mode 100644 index 000000000..415adf3b4 --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/model_provider_list.go @@ -0,0 +1,269 @@ +/* +Ambient API Server + +Ambient API Server + +API version: 1.0.0 +Contact: ambient-code@redhat.com +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the ProviderList type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ProviderList{} + +// ProviderList struct for ProviderList +type ProviderList struct { + Kind string `json:"kind"` + Page int32 `json:"page"` + Size int32 `json:"size"` + Total int32 `json:"total"` + Items []Provider `json:"items"` +} + +type _ProviderList ProviderList + +// NewProviderList instantiates a new ProviderList object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewProviderList(kind string, page int32, size int32, total int32, items []Provider) *ProviderList { + this := ProviderList{} + this.Kind = kind + this.Page = page + this.Size = size + this.Total = total + this.Items = items + return &this +} + +// NewProviderListWithDefaults instantiates a new ProviderList object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewProviderListWithDefaults() *ProviderList { + this := ProviderList{} + return &this +} + +// GetKind returns the Kind field value +func (o *ProviderList) GetKind() string { + if o == nil { + var ret string + return ret + } + + return o.Kind +} + +// GetKindOk returns a tuple with the Kind field value +// and a boolean to check if the value has been set. +func (o *ProviderList) GetKindOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Kind, true +} + +// SetKind sets field value +func (o *ProviderList) SetKind(v string) { + o.Kind = v +} + +// GetPage returns the Page field value +func (o *ProviderList) GetPage() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Page +} + +// GetPageOk returns a tuple with the Page field value +// and a boolean to check if the value has been set. +func (o *ProviderList) GetPageOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Page, true +} + +// SetPage sets field value +func (o *ProviderList) SetPage(v int32) { + o.Page = v +} + +// GetSize returns the Size field value +func (o *ProviderList) GetSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Size +} + +// GetSizeOk returns a tuple with the Size field value +// and a boolean to check if the value has been set. +func (o *ProviderList) GetSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Size, true +} + +// SetSize sets field value +func (o *ProviderList) SetSize(v int32) { + o.Size = v +} + +// GetTotal returns the Total field value +func (o *ProviderList) GetTotal() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Total +} + +// GetTotalOk returns a tuple with the Total field value +// and a boolean to check if the value has been set. +func (o *ProviderList) GetTotalOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Total, true +} + +// SetTotal sets field value +func (o *ProviderList) SetTotal(v int32) { + o.Total = v +} + +// GetItems returns the Items field value +func (o *ProviderList) GetItems() []Provider { + if o == nil { + var ret []Provider + return ret + } + + return o.Items +} + +// GetItemsOk returns a tuple with the Items field value +// and a boolean to check if the value has been set. +func (o *ProviderList) GetItemsOk() ([]Provider, bool) { + if o == nil { + return nil, false + } + return o.Items, true +} + +// SetItems sets field value +func (o *ProviderList) SetItems(v []Provider) { + o.Items = v +} + +func (o ProviderList) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ProviderList) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["kind"] = o.Kind + toSerialize["page"] = o.Page + toSerialize["size"] = o.Size + toSerialize["total"] = o.Total + toSerialize["items"] = o.Items + return toSerialize, nil +} + +func (o *ProviderList) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "kind", + "page", + "size", + "total", + "items", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varProviderList := _ProviderList{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varProviderList) + + if err != nil { + return err + } + + *o = ProviderList(varProviderList) + + return err +} + +type NullableProviderList struct { + value *ProviderList + isSet bool +} + +func (v NullableProviderList) Get() *ProviderList { + return v.value +} + +func (v *NullableProviderList) Set(val *ProviderList) { + v.value = val + v.isSet = true +} + +func (v NullableProviderList) IsSet() bool { + return v.isSet +} + +func (v *NullableProviderList) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableProviderList(val *ProviderList) *NullableProviderList { + return &NullableProviderList{value: val, isSet: true} +} + +func (v NullableProviderList) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableProviderList) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/components/ambient-api-server/pkg/api/openapi/model_provider_patch_request.go b/components/ambient-api-server/pkg/api/openapi/model_provider_patch_request.go new file mode 100644 index 000000000..af8ca20b0 --- /dev/null +++ b/components/ambient-api-server/pkg/api/openapi/model_provider_patch_request.go @@ -0,0 +1,305 @@ +/* +Ambient API Server + +Ambient API Server + +API version: 1.0.0 +Contact: ambient-code@redhat.com +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ProviderPatchRequest type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ProviderPatchRequest{} + +// ProviderPatchRequest struct for ProviderPatchRequest +type ProviderPatchRequest struct { + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Secret *string `json:"secret,omitempty"` + Namespace *string `json:"namespace,omitempty"` + Labels *string `json:"labels,omitempty"` + Annotations *string `json:"annotations,omitempty"` +} + +// NewProviderPatchRequest instantiates a new ProviderPatchRequest object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewProviderPatchRequest() *ProviderPatchRequest { + this := ProviderPatchRequest{} + return &this +} + +// NewProviderPatchRequestWithDefaults instantiates a new ProviderPatchRequest object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewProviderPatchRequestWithDefaults() *ProviderPatchRequest { + this := ProviderPatchRequest{} + return &this +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *ProviderPatchRequest) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ProviderPatchRequest) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *ProviderPatchRequest) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *ProviderPatchRequest) SetName(v string) { + o.Name = &v +} + +// GetType returns the Type field value if set, zero value otherwise. +func (o *ProviderPatchRequest) GetType() string { + if o == nil || IsNil(o.Type) { + var ret string + return ret + } + return *o.Type +} + +// GetTypeOk returns a tuple with the Type field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ProviderPatchRequest) GetTypeOk() (*string, bool) { + if o == nil || IsNil(o.Type) { + return nil, false + } + return o.Type, true +} + +// HasType returns a boolean if a field has been set. +func (o *ProviderPatchRequest) HasType() bool { + if o != nil && !IsNil(o.Type) { + return true + } + + return false +} + +// SetType gets a reference to the given string and assigns it to the Type field. +func (o *ProviderPatchRequest) SetType(v string) { + o.Type = &v +} + +// GetSecret returns the Secret field value if set, zero value otherwise. +func (o *ProviderPatchRequest) GetSecret() string { + if o == nil || IsNil(o.Secret) { + var ret string + return ret + } + return *o.Secret +} + +// GetSecretOk returns a tuple with the Secret field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ProviderPatchRequest) GetSecretOk() (*string, bool) { + if o == nil || IsNil(o.Secret) { + return nil, false + } + return o.Secret, true +} + +// HasSecret returns a boolean if a field has been set. +func (o *ProviderPatchRequest) HasSecret() bool { + if o != nil && !IsNil(o.Secret) { + return true + } + + return false +} + +// SetSecret gets a reference to the given string and assigns it to the Secret field. +func (o *ProviderPatchRequest) SetSecret(v string) { + o.Secret = &v +} + +// GetNamespace returns the Namespace field value if set, zero value otherwise. +func (o *ProviderPatchRequest) GetNamespace() string { + if o == nil || IsNil(o.Namespace) { + var ret string + return ret + } + return *o.Namespace +} + +// GetNamespaceOk returns a tuple with the Namespace field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ProviderPatchRequest) GetNamespaceOk() (*string, bool) { + if o == nil || IsNil(o.Namespace) { + return nil, false + } + return o.Namespace, true +} + +// HasNamespace returns a boolean if a field has been set. +func (o *ProviderPatchRequest) HasNamespace() bool { + if o != nil && !IsNil(o.Namespace) { + return true + } + + return false +} + +// SetNamespace gets a reference to the given string and assigns it to the Namespace field. +func (o *ProviderPatchRequest) SetNamespace(v string) { + o.Namespace = &v +} + +// GetLabels returns the Labels field value if set, zero value otherwise. +func (o *ProviderPatchRequest) GetLabels() string { + if o == nil || IsNil(o.Labels) { + var ret string + return ret + } + return *o.Labels +} + +// GetLabelsOk returns a tuple with the Labels field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ProviderPatchRequest) GetLabelsOk() (*string, bool) { + if o == nil || IsNil(o.Labels) { + return nil, false + } + return o.Labels, true +} + +// HasLabels returns a boolean if a field has been set. +func (o *ProviderPatchRequest) HasLabels() bool { + if o != nil && !IsNil(o.Labels) { + return true + } + + return false +} + +// SetLabels gets a reference to the given string and assigns it to the Labels field. +func (o *ProviderPatchRequest) SetLabels(v string) { + o.Labels = &v +} + +// GetAnnotations returns the Annotations field value if set, zero value otherwise. +func (o *ProviderPatchRequest) GetAnnotations() string { + if o == nil || IsNil(o.Annotations) { + var ret string + return ret + } + return *o.Annotations +} + +// GetAnnotationsOk returns a tuple with the Annotations field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ProviderPatchRequest) GetAnnotationsOk() (*string, bool) { + if o == nil || IsNil(o.Annotations) { + return nil, false + } + return o.Annotations, true +} + +// HasAnnotations returns a boolean if a field has been set. +func (o *ProviderPatchRequest) HasAnnotations() bool { + if o != nil && !IsNil(o.Annotations) { + return true + } + + return false +} + +// SetAnnotations gets a reference to the given string and assigns it to the Annotations field. +func (o *ProviderPatchRequest) SetAnnotations(v string) { + o.Annotations = &v +} + +func (o ProviderPatchRequest) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ProviderPatchRequest) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.Type) { + toSerialize["type"] = o.Type + } + if !IsNil(o.Secret) { + toSerialize["secret"] = o.Secret + } + if !IsNil(o.Namespace) { + toSerialize["namespace"] = o.Namespace + } + if !IsNil(o.Labels) { + toSerialize["labels"] = o.Labels + } + if !IsNil(o.Annotations) { + toSerialize["annotations"] = o.Annotations + } + return toSerialize, nil +} + +type NullableProviderPatchRequest struct { + value *ProviderPatchRequest + isSet bool +} + +func (v NullableProviderPatchRequest) Get() *ProviderPatchRequest { + return v.value +} + +func (v *NullableProviderPatchRequest) Set(val *ProviderPatchRequest) { + v.value = val + v.isSet = true +} + +func (v NullableProviderPatchRequest) IsSet() bool { + return v.isSet +} + +func (v *NullableProviderPatchRequest) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableProviderPatchRequest(val *ProviderPatchRequest) *NullableProviderPatchRequest { + return &NullableProviderPatchRequest{value: val, isSet: true} +} + +func (v NullableProviderPatchRequest) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableProviderPatchRequest) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/components/ambient-api-server/plugins/policies/dao.go b/components/ambient-api-server/plugins/policies/dao.go new file mode 100644 index 000000000..d2cf49a00 --- /dev/null +++ b/components/ambient-api-server/plugins/policies/dao.go @@ -0,0 +1,81 @@ +package policies + +import ( + "context" + + "gorm.io/gorm/clause" + + "github.com/openshift-online/rh-trex-ai/pkg/api" + "github.com/openshift-online/rh-trex-ai/pkg/db" +) + +type PolicyDao interface { + Get(ctx context.Context, id string) (*Policy, error) + Create(ctx context.Context, policy *Policy) (*Policy, error) + Replace(ctx context.Context, policy *Policy) (*Policy, error) + Delete(ctx context.Context, id string) error + All(ctx context.Context) (PolicyList, error) + AllByProjectID(ctx context.Context, projectID string) (PolicyList, error) +} + +type sqlPolicyDao struct { + sessionFactory *db.SessionFactory +} + +func NewPolicyDao(sessionFactory *db.SessionFactory) PolicyDao { + return &sqlPolicyDao{sessionFactory: sessionFactory} +} + +func (d *sqlPolicyDao) Get(ctx context.Context, id string) (*Policy, error) { + g2 := (*d.sessionFactory).New(ctx) + var policy Policy + if err := g2.Take(&policy, "id = ?", id).Error; err != nil { + return nil, err + } + return &policy, nil +} + +func (d *sqlPolicyDao) Create(ctx context.Context, policy *Policy) (*Policy, error) { + g2 := (*d.sessionFactory).New(ctx) + if err := g2.Omit(clause.Associations).Create(policy).Error; err != nil { + db.MarkForRollback(ctx, err) + return nil, err + } + return policy, nil +} + +func (d *sqlPolicyDao) Replace(ctx context.Context, policy *Policy) (*Policy, error) { + g2 := (*d.sessionFactory).New(ctx) + if err := g2.Omit(clause.Associations).Save(policy).Error; err != nil { + db.MarkForRollback(ctx, err) + return nil, err + } + return policy, nil +} + +func (d *sqlPolicyDao) Delete(ctx context.Context, id string) error { + g2 := (*d.sessionFactory).New(ctx) + if err := g2.Omit(clause.Associations).Delete(&Policy{Meta: api.Meta{ID: id}}).Error; err != nil { + db.MarkForRollback(ctx, err) + return err + } + return nil +} + +func (d *sqlPolicyDao) All(ctx context.Context) (PolicyList, error) { + g2 := (*d.sessionFactory).New(ctx) + policies := PolicyList{} + if err := g2.Find(&policies).Error; err != nil { + return nil, err + } + return policies, nil +} + +func (d *sqlPolicyDao) AllByProjectID(ctx context.Context, projectID string) (PolicyList, error) { + g2 := (*d.sessionFactory).New(ctx) + policies := PolicyList{} + if err := g2.Where("project_id = ?", projectID).Order("name ASC").Find(&policies).Error; err != nil { + return nil, err + } + return policies, nil +} diff --git a/components/ambient-api-server/plugins/policies/handler.go b/components/ambient-api-server/plugins/policies/handler.go new file mode 100644 index 000000000..8bb9b89d3 --- /dev/null +++ b/components/ambient-api-server/plugins/policies/handler.go @@ -0,0 +1,176 @@ +package policies + +import ( + "encoding/json" + "net/http" + + "github.com/gorilla/mux" + + "github.com/ambient-code/platform/components/ambient-api-server/pkg/api/openapi" + "github.com/openshift-online/rh-trex-ai/pkg/errors" + "github.com/openshift-online/rh-trex-ai/pkg/handlers" + "github.com/openshift-online/rh-trex-ai/pkg/services" +) + +type policyHandler struct { + policy PolicyService + generic services.GenericService +} + +func NewPolicyHandler(policy PolicyService, generic services.GenericService) *policyHandler { + return &policyHandler{ + policy: policy, + generic: generic, + } +} + +func (h policyHandler) Create(w http.ResponseWriter, r *http.Request) { + var policy openapi.Policy + cfg := &handlers.HandlerConfig{ + Body: &policy, + Validators: []handlers.Validate{ + handlers.ValidateEmpty(&policy, "Id", "id"), + }, + Action: func() (interface{}, *errors.ServiceError) { + ctx := r.Context() + projectID := mux.Vars(r)["id"] + model := ConvertPolicy(policy) + model.ProjectId = projectID + model, err := h.policy.Create(ctx, model) + if err != nil { + return nil, err + } + return PresentPolicy(model), nil + }, + ErrorHandler: handlers.HandleError, + } + handlers.Handle(w, r, cfg, http.StatusCreated) +} + +func (h policyHandler) List(w http.ResponseWriter, r *http.Request) { + cfg := &handlers.HandlerConfig{ + Action: func() (interface{}, *errors.ServiceError) { + ctx := r.Context() + projectID := mux.Vars(r)["id"] + + listArgs := services.NewListArguments(r.URL.Query()) + projectFilter := "project_id = '" + projectID + "'" + if listArgs.Search != "" { + listArgs.Search = projectFilter + " and (" + listArgs.Search + ")" + } else { + listArgs.Search = projectFilter + } + + var policies []Policy + paging, err := h.generic.List(ctx, "id", listArgs, &policies) + if err != nil { + return nil, err + } + + policyList := openapi.PolicyList{ + Kind: "PolicyList", + Page: int32(paging.Page), + Size: int32(paging.Size), + Total: int32(paging.Total), + Items: []openapi.Policy{}, + } + + for _, p := range policies { + policyList.Items = append(policyList.Items, PresentPolicy(&p)) + } + return policyList, nil + }, + } + handlers.HandleList(w, r, cfg) +} + +func (h policyHandler) Get(w http.ResponseWriter, r *http.Request) { + cfg := &handlers.HandlerConfig{ + Action: func() (interface{}, *errors.ServiceError) { + projectID := mux.Vars(r)["id"] + id := mux.Vars(r)["policy_id"] + ctx := r.Context() + policy, err := h.policy.Get(ctx, id) + if err != nil { + return nil, err + } + if policy.ProjectId != projectID { + return nil, errors.Forbidden("policy does not belong to this project") + } + return PresentPolicy(policy), nil + }, + } + handlers.HandleGet(w, r, cfg) +} + +func (h policyHandler) Patch(w http.ResponseWriter, r *http.Request) { + var patch openapi.PolicyPatchRequest + cfg := &handlers.HandlerConfig{ + Body: &patch, + Validators: []handlers.Validate{}, + Action: func() (interface{}, *errors.ServiceError) { + ctx := r.Context() + projectID := mux.Vars(r)["id"] + id := mux.Vars(r)["policy_id"] + found, err := h.policy.Get(ctx, id) + if err != nil { + return nil, err + } + if found.ProjectId != projectID { + return nil, errors.Forbidden("policy does not belong to this project") + } + + if patch.Name != nil { + found.Name = *patch.Name + } + if patch.Namespace != nil { + found.Namespace = patch.Namespace + } + if patch.Spec != nil { + raw, mErr := json.Marshal(patch.Spec) + if mErr != nil { + return nil, errors.Validation("invalid spec: %v", mErr) + } + s := string(raw) + found.Spec = &s + } + if patch.Labels != nil { + found.Labels = patch.Labels + } + if patch.Annotations != nil { + found.Annotations = patch.Annotations + } + + model, err := h.policy.Replace(ctx, found) + if err != nil { + return nil, err + } + return PresentPolicy(model), nil + }, + ErrorHandler: handlers.HandleError, + } + handlers.Handle(w, r, cfg, http.StatusOK) +} + +func (h policyHandler) Delete(w http.ResponseWriter, r *http.Request) { + cfg := &handlers.HandlerConfig{ + Action: func() (interface{}, *errors.ServiceError) { + projectID := mux.Vars(r)["id"] + id := mux.Vars(r)["policy_id"] + ctx := r.Context() + policy, getErr := h.policy.Get(ctx, id) + if getErr != nil { + return nil, getErr + } + if policy.ProjectId != projectID { + return nil, errors.Forbidden("policy does not belong to this project") + } + err := h.policy.Delete(ctx, id) + if err != nil { + return nil, err + } + return nil, nil + }, + } + handlers.HandleDelete(w, r, cfg, http.StatusNoContent) +} diff --git a/components/ambient-api-server/plugins/policies/migration.go b/components/ambient-api-server/plugins/policies/migration.go new file mode 100644 index 000000000..20d8cf859 --- /dev/null +++ b/components/ambient-api-server/plugins/policies/migration.go @@ -0,0 +1,41 @@ +package policies + +import ( + "gorm.io/gorm" + + "github.com/go-gormigrate/gormigrate/v2" + "github.com/openshift-online/rh-trex-ai/pkg/db" +) + +func migration() *gormigrate.Migration { + type Policy struct { + db.Model + ProjectId string + Name string + Namespace *string + Spec *string `gorm:"type:jsonb"` + Labels *string + Annotations *string + } + + return &gormigrate.Migration{ + ID: "202606300200", + Migrate: func(tx *gorm.DB) error { + if err := tx.AutoMigrate(&Policy{}); err != nil { + return err + } + stmts := []string{ + `CREATE INDEX IF NOT EXISTS idx_policies_project_id ON policies(project_id)`, + } + for _, s := range stmts { + if err := tx.Exec(s).Error; err != nil { + return err + } + } + return nil + }, + Rollback: func(tx *gorm.DB) error { + return tx.Migrator().DropTable(&Policy{}) + }, + } +} diff --git a/components/ambient-api-server/plugins/policies/model.go b/components/ambient-api-server/plugins/policies/model.go new file mode 100644 index 000000000..f87e10ef2 --- /dev/null +++ b/components/ambient-api-server/plugins/policies/model.go @@ -0,0 +1,24 @@ +package policies + +import ( + "github.com/openshift-online/rh-trex-ai/pkg/api" + "gorm.io/gorm" +) + +type Policy struct { + api.Meta + ProjectId string `json:"project_id" gorm:"not null;index"` + Name string `json:"name" gorm:"not null"` + Namespace *string `json:"namespace"` + Spec *string `json:"spec" gorm:"type:jsonb"` + Labels *string `json:"labels"` + Annotations *string `json:"annotations"` +} + +type PolicyList []*Policy +type PolicyIndex map[string]*Policy + +func (d *Policy) BeforeCreate(tx *gorm.DB) error { + d.ID = api.NewID() + return nil +} diff --git a/components/ambient-api-server/plugins/policies/plugin.go b/components/ambient-api-server/plugins/policies/plugin.go new file mode 100644 index 000000000..2eef5af8f --- /dev/null +++ b/components/ambient-api-server/plugins/policies/plugin.go @@ -0,0 +1,88 @@ +package policies + +import ( + "net/http" + + pkgrbac "github.com/ambient-code/platform/components/ambient-api-server/plugins/rbac" + "github.com/gorilla/mux" + "github.com/openshift-online/rh-trex-ai/pkg/api" + "github.com/openshift-online/rh-trex-ai/pkg/api/presenters" + "github.com/openshift-online/rh-trex-ai/pkg/auth" + "github.com/openshift-online/rh-trex-ai/pkg/controllers" + "github.com/openshift-online/rh-trex-ai/pkg/db" + "github.com/openshift-online/rh-trex-ai/pkg/environments" + "github.com/openshift-online/rh-trex-ai/pkg/registry" + pkgserver "github.com/openshift-online/rh-trex-ai/pkg/server" + "github.com/openshift-online/rh-trex-ai/plugins/events" + "github.com/openshift-online/rh-trex-ai/plugins/generic" +) + +type ServiceLocator func() PolicyService + +func NewServiceLocator(env *environments.Env) ServiceLocator { + return func() PolicyService { + return NewPolicyService( + db.NewAdvisoryLockFactory(env.Database.SessionFactory), + NewPolicyDao(&env.Database.SessionFactory), + events.Service(&env.Services), + ) + } +} + +func Service(s *environments.Services) PolicyService { + if s == nil { + return nil + } + if obj := s.GetService("Policies"); obj != nil { + locator := obj.(ServiceLocator) + return locator() + } + return nil +} + +func init() { + registry.RegisterService("Policies", func(env interface{}) interface{} { + return NewServiceLocator(env.(*environments.Env)) + }) + + pkgserver.RegisterRoutes("policies", func(apiV1Router *mux.Router, services pkgserver.ServicesInterface, authMiddleware environments.JWTMiddleware, authzMiddleware auth.AuthorizationMiddleware) { + envServices := services.(*environments.Services) + + if dbAuthz := pkgrbac.Middleware(envServices); dbAuthz != nil { + authzMiddleware = dbAuthz + } + + policySvc := Service(envServices) + policyHandler := NewPolicyHandler(policySvc, generic.Service(envServices)) + + projectsRouter := apiV1Router.PathPrefix("/projects").Subrouter() + projectsRouter.HandleFunc("/{id}/policies", policyHandler.List).Methods(http.MethodGet) + projectsRouter.HandleFunc("/{id}/policies", policyHandler.Create).Methods(http.MethodPost) + projectsRouter.HandleFunc("/{id}/policies/{policy_id}", policyHandler.Get).Methods(http.MethodGet) + projectsRouter.HandleFunc("/{id}/policies/{policy_id}", policyHandler.Patch).Methods(http.MethodPatch) + projectsRouter.HandleFunc("/{id}/policies/{policy_id}", policyHandler.Delete).Methods(http.MethodDelete) + + projectsRouter.Use(authMiddleware.AuthenticateAccountJWT) + projectsRouter.Use(authzMiddleware.AuthorizeApi) + }) + + pkgserver.RegisterController("Policies", func(manager *controllers.KindControllerManager, services pkgserver.ServicesInterface) { + policySvc := Service(services.(*environments.Services)) + + manager.Add(&controllers.ControllerConfig{ + Source: "Policies", + Handlers: map[api.EventType][]controllers.ControllerHandlerFunc{ + api.CreateEventType: {policySvc.OnUpsert}, + api.UpdateEventType: {policySvc.OnUpsert}, + api.DeleteEventType: {policySvc.OnDelete}, + }, + }) + }) + + presenters.RegisterPath(Policy{}, "policies") + presenters.RegisterPath(&Policy{}, "policies") + presenters.RegisterKind(Policy{}, "Policy") + presenters.RegisterKind(&Policy{}, "Policy") + + db.RegisterMigration(migration()) +} diff --git a/components/ambient-api-server/plugins/policies/presenter.go b/components/ambient-api-server/plugins/policies/presenter.go new file mode 100644 index 000000000..2b5a87d3f --- /dev/null +++ b/components/ambient-api-server/plugins/policies/presenter.go @@ -0,0 +1,64 @@ +package policies + +import ( + "encoding/json" + + "github.com/ambient-code/platform/components/ambient-api-server/pkg/api/openapi" + "github.com/openshift-online/rh-trex-ai/pkg/api" + "github.com/openshift-online/rh-trex-ai/pkg/api/presenters" + "github.com/openshift-online/rh-trex-ai/pkg/util" +) + +func ConvertPolicy(p openapi.Policy) *Policy { + c := &Policy{ + Meta: api.Meta{ + ID: util.NilToEmptyString(p.Id), + }, + } + c.ProjectId = p.ProjectId + c.Name = p.Name + c.Namespace = p.Namespace + c.Labels = p.Labels + c.Annotations = p.Annotations + + if p.Spec != nil { + if raw, err := json.Marshal(p.Spec); err == nil { + s := string(raw) + c.Spec = &s + } + } + + if p.CreatedAt != nil { + c.CreatedAt = *p.CreatedAt + } + if p.UpdatedAt != nil { + c.UpdatedAt = *p.UpdatedAt + } + + return c +} + +func PresentPolicy(p *Policy) openapi.Policy { + reference := presenters.PresentReference(p.ID, p) + result := openapi.Policy{ + Id: reference.Id, + Kind: reference.Kind, + Href: reference.Href, + CreatedAt: openapi.PtrTime(p.CreatedAt), + UpdatedAt: openapi.PtrTime(p.UpdatedAt), + ProjectId: p.ProjectId, + Name: p.Name, + Namespace: p.Namespace, + Labels: p.Labels, + Annotations: p.Annotations, + } + + if p.Spec != nil { + var spec map[string]interface{} + if err := json.Unmarshal([]byte(*p.Spec), &spec); err == nil { + result.Spec = spec + } + } + + return result +} diff --git a/components/ambient-api-server/plugins/policies/service.go b/components/ambient-api-server/plugins/policies/service.go new file mode 100644 index 000000000..6ed0918aa --- /dev/null +++ b/components/ambient-api-server/plugins/policies/service.go @@ -0,0 +1,137 @@ +package policies + +import ( + "context" + + "github.com/openshift-online/rh-trex-ai/pkg/api" + "github.com/openshift-online/rh-trex-ai/pkg/db" + "github.com/openshift-online/rh-trex-ai/pkg/errors" + "github.com/openshift-online/rh-trex-ai/pkg/logger" + "github.com/openshift-online/rh-trex-ai/pkg/services" +) + +const policiesLockType db.LockType = "policies" + +type PolicyService interface { + Get(ctx context.Context, id string) (*Policy, *errors.ServiceError) + Create(ctx context.Context, policy *Policy) (*Policy, *errors.ServiceError) + Replace(ctx context.Context, policy *Policy) (*Policy, *errors.ServiceError) + Delete(ctx context.Context, id string) *errors.ServiceError + All(ctx context.Context) (PolicyList, *errors.ServiceError) + AllByProjectID(ctx context.Context, projectID string) (PolicyList, *errors.ServiceError) + + OnUpsert(ctx context.Context, id string) error + OnDelete(ctx context.Context, id string) error +} + +func NewPolicyService(lockFactory db.LockFactory, policyDao PolicyDao, events services.EventService) PolicyService { + return &sqlPolicyService{ + lockFactory: lockFactory, + policyDao: policyDao, + events: events, + } +} + +type sqlPolicyService struct { + lockFactory db.LockFactory + policyDao PolicyDao + events services.EventService +} + +func (s *sqlPolicyService) Get(ctx context.Context, id string) (*Policy, *errors.ServiceError) { + policy, err := s.policyDao.Get(ctx, id) + if err != nil { + return nil, services.HandleGetError("Policy", "id", id, err) + } + return policy, nil +} + +func (s *sqlPolicyService) Create(ctx context.Context, policy *Policy) (*Policy, *errors.ServiceError) { + policy, err := s.policyDao.Create(ctx, policy) + if err != nil { + return nil, services.HandleCreateError("Policy", err) + } + + _, evErr := s.events.Create(ctx, &api.Event{ + Source: "Policies", + SourceID: policy.ID, + EventType: api.CreateEventType, + }) + if evErr != nil { + return nil, services.HandleCreateError("Policy", evErr) + } + + return policy, nil +} + +func (s *sqlPolicyService) Replace(ctx context.Context, policy *Policy) (*Policy, *errors.ServiceError) { + lockOwnerID, locked, err := s.lockFactory.NewNonBlockingLock(ctx, policy.ID, policiesLockType) + if err != nil { + return nil, errors.DatabaseAdvisoryLock(err) + } + if !locked { + return nil, services.HandleCreateError("Policy", errors.New(errors.ErrorConflict, "row locked")) + } + defer s.lockFactory.Unlock(ctx, lockOwnerID) + + policy, err = s.policyDao.Replace(ctx, policy) + if err != nil { + return nil, services.HandleUpdateError("Policy", err) + } + + _, evErr := s.events.Create(ctx, &api.Event{ + Source: "Policies", + SourceID: policy.ID, + EventType: api.UpdateEventType, + }) + if evErr != nil { + return nil, services.HandleUpdateError("Policy", evErr) + } + + return policy, nil +} + +func (s *sqlPolicyService) Delete(ctx context.Context, id string) *errors.ServiceError { + if err := s.policyDao.Delete(ctx, id); err != nil { + return services.HandleDeleteError("Policy", errors.GeneralError("Unable to delete policy: %s", err)) + } + + _, evErr := s.events.Create(ctx, &api.Event{ + Source: "Policies", + SourceID: id, + EventType: api.DeleteEventType, + }) + if evErr != nil { + return services.HandleDeleteError("Policy", evErr) + } + + return nil +} + +func (s *sqlPolicyService) All(ctx context.Context) (PolicyList, *errors.ServiceError) { + policies, err := s.policyDao.All(ctx) + if err != nil { + return nil, services.HandleGetError("Policy", "all", "", err) + } + return policies, nil +} + +func (s *sqlPolicyService) AllByProjectID(ctx context.Context, projectID string) (PolicyList, *errors.ServiceError) { + policies, err := s.policyDao.AllByProjectID(ctx, projectID) + if err != nil { + return nil, services.HandleGetError("Policy", "project_id", projectID, err) + } + return policies, nil +} + +func (s *sqlPolicyService) OnUpsert(ctx context.Context, id string) error { + l := logger.NewLogger(ctx) + l.Infof("Policy upserted: %s", id) + return nil +} + +func (s *sqlPolicyService) OnDelete(ctx context.Context, id string) error { + l := logger.NewLogger(ctx) + l.Infof("Policy deleted: %s", id) + return nil +} diff --git a/components/ambient-api-server/plugins/providers/dao.go b/components/ambient-api-server/plugins/providers/dao.go new file mode 100644 index 000000000..49098c6c1 --- /dev/null +++ b/components/ambient-api-server/plugins/providers/dao.go @@ -0,0 +1,81 @@ +package providers + +import ( + "context" + + "gorm.io/gorm/clause" + + "github.com/openshift-online/rh-trex-ai/pkg/api" + "github.com/openshift-online/rh-trex-ai/pkg/db" +) + +type ProviderDao interface { + Get(ctx context.Context, id string) (*Provider, error) + Create(ctx context.Context, provider *Provider) (*Provider, error) + Replace(ctx context.Context, provider *Provider) (*Provider, error) + Delete(ctx context.Context, id string) error + All(ctx context.Context) (ProviderList, error) + AllByProjectID(ctx context.Context, projectID string) (ProviderList, error) +} + +type sqlProviderDao struct { + sessionFactory *db.SessionFactory +} + +func NewProviderDao(sessionFactory *db.SessionFactory) ProviderDao { + return &sqlProviderDao{sessionFactory: sessionFactory} +} + +func (d *sqlProviderDao) Get(ctx context.Context, id string) (*Provider, error) { + g2 := (*d.sessionFactory).New(ctx) + var provider Provider + if err := g2.Take(&provider, "id = ?", id).Error; err != nil { + return nil, err + } + return &provider, nil +} + +func (d *sqlProviderDao) Create(ctx context.Context, provider *Provider) (*Provider, error) { + g2 := (*d.sessionFactory).New(ctx) + if err := g2.Omit(clause.Associations).Create(provider).Error; err != nil { + db.MarkForRollback(ctx, err) + return nil, err + } + return provider, nil +} + +func (d *sqlProviderDao) Replace(ctx context.Context, provider *Provider) (*Provider, error) { + g2 := (*d.sessionFactory).New(ctx) + if err := g2.Omit(clause.Associations).Save(provider).Error; err != nil { + db.MarkForRollback(ctx, err) + return nil, err + } + return provider, nil +} + +func (d *sqlProviderDao) Delete(ctx context.Context, id string) error { + g2 := (*d.sessionFactory).New(ctx) + if err := g2.Omit(clause.Associations).Delete(&Provider{Meta: api.Meta{ID: id}}).Error; err != nil { + db.MarkForRollback(ctx, err) + return err + } + return nil +} + +func (d *sqlProviderDao) All(ctx context.Context) (ProviderList, error) { + g2 := (*d.sessionFactory).New(ctx) + providers := ProviderList{} + if err := g2.Find(&providers).Error; err != nil { + return nil, err + } + return providers, nil +} + +func (d *sqlProviderDao) AllByProjectID(ctx context.Context, projectID string) (ProviderList, error) { + g2 := (*d.sessionFactory).New(ctx) + providers := ProviderList{} + if err := g2.Where("project_id = ?", projectID).Order("name ASC").Find(&providers).Error; err != nil { + return nil, err + } + return providers, nil +} diff --git a/components/ambient-api-server/plugins/providers/handler.go b/components/ambient-api-server/plugins/providers/handler.go new file mode 100644 index 000000000..98b2dba78 --- /dev/null +++ b/components/ambient-api-server/plugins/providers/handler.go @@ -0,0 +1,173 @@ +package providers + +import ( + "net/http" + + "github.com/gorilla/mux" + + "github.com/ambient-code/platform/components/ambient-api-server/pkg/api/openapi" + "github.com/openshift-online/rh-trex-ai/pkg/errors" + "github.com/openshift-online/rh-trex-ai/pkg/handlers" + "github.com/openshift-online/rh-trex-ai/pkg/services" +) + +type providerHandler struct { + provider ProviderService + generic services.GenericService +} + +func NewProviderHandler(provider ProviderService, generic services.GenericService) *providerHandler { + return &providerHandler{ + provider: provider, + generic: generic, + } +} + +func (h providerHandler) Create(w http.ResponseWriter, r *http.Request) { + var provider openapi.Provider + cfg := &handlers.HandlerConfig{ + Body: &provider, + Validators: []handlers.Validate{ + handlers.ValidateEmpty(&provider, "Id", "id"), + }, + Action: func() (interface{}, *errors.ServiceError) { + ctx := r.Context() + projectID := mux.Vars(r)["id"] + model := ConvertProvider(provider) + model.ProjectId = projectID + model, err := h.provider.Create(ctx, model) + if err != nil { + return nil, err + } + return PresentProvider(model), nil + }, + ErrorHandler: handlers.HandleError, + } + handlers.Handle(w, r, cfg, http.StatusCreated) +} + +func (h providerHandler) List(w http.ResponseWriter, r *http.Request) { + cfg := &handlers.HandlerConfig{ + Action: func() (interface{}, *errors.ServiceError) { + ctx := r.Context() + projectID := mux.Vars(r)["id"] + + listArgs := services.NewListArguments(r.URL.Query()) + projectFilter := "project_id = '" + projectID + "'" + if listArgs.Search != "" { + listArgs.Search = projectFilter + " and (" + listArgs.Search + ")" + } else { + listArgs.Search = projectFilter + } + + var providers []Provider + paging, err := h.generic.List(ctx, "id", listArgs, &providers) + if err != nil { + return nil, err + } + + providerList := openapi.ProviderList{ + Kind: "ProviderList", + Page: int32(paging.Page), + Size: int32(paging.Size), + Total: int32(paging.Total), + Items: []openapi.Provider{}, + } + + for _, p := range providers { + providerList.Items = append(providerList.Items, PresentProvider(&p)) + } + return providerList, nil + }, + } + handlers.HandleList(w, r, cfg) +} + +func (h providerHandler) Get(w http.ResponseWriter, r *http.Request) { + cfg := &handlers.HandlerConfig{ + Action: func() (interface{}, *errors.ServiceError) { + projectID := mux.Vars(r)["id"] + id := mux.Vars(r)["provider_id"] + ctx := r.Context() + provider, err := h.provider.Get(ctx, id) + if err != nil { + return nil, err + } + if provider.ProjectId != projectID { + return nil, errors.Forbidden("provider does not belong to this project") + } + return PresentProvider(provider), nil + }, + } + handlers.HandleGet(w, r, cfg) +} + +func (h providerHandler) Patch(w http.ResponseWriter, r *http.Request) { + var patch openapi.ProviderPatchRequest + cfg := &handlers.HandlerConfig{ + Body: &patch, + Validators: []handlers.Validate{}, + Action: func() (interface{}, *errors.ServiceError) { + ctx := r.Context() + projectID := mux.Vars(r)["id"] + id := mux.Vars(r)["provider_id"] + found, err := h.provider.Get(ctx, id) + if err != nil { + return nil, err + } + if found.ProjectId != projectID { + return nil, errors.Forbidden("provider does not belong to this project") + } + + if patch.Name != nil { + found.Name = *patch.Name + } + if patch.Type != nil { + found.Type = patch.Type + } + if patch.Secret != nil { + found.Secret = patch.Secret + } + if patch.Namespace != nil { + found.Namespace = patch.Namespace + } + if patch.Labels != nil { + found.Labels = patch.Labels + } + if patch.Annotations != nil { + found.Annotations = patch.Annotations + } + + model, err := h.provider.Replace(ctx, found) + if err != nil { + return nil, err + } + return PresentProvider(model), nil + }, + ErrorHandler: handlers.HandleError, + } + handlers.Handle(w, r, cfg, http.StatusOK) +} + +func (h providerHandler) Delete(w http.ResponseWriter, r *http.Request) { + cfg := &handlers.HandlerConfig{ + Action: func() (interface{}, *errors.ServiceError) { + projectID := mux.Vars(r)["id"] + id := mux.Vars(r)["provider_id"] + ctx := r.Context() + provider, getErr := h.provider.Get(ctx, id) + if getErr != nil { + return nil, getErr + } + if provider.ProjectId != projectID { + return nil, errors.Forbidden("provider does not belong to this project") + } + err := h.provider.Delete(ctx, id) + if err != nil { + return nil, err + } + return nil, nil + }, + } + handlers.HandleDelete(w, r, cfg, http.StatusNoContent) +} diff --git a/components/ambient-api-server/plugins/providers/migration.go b/components/ambient-api-server/plugins/providers/migration.go new file mode 100644 index 000000000..ad00a34cb --- /dev/null +++ b/components/ambient-api-server/plugins/providers/migration.go @@ -0,0 +1,42 @@ +package providers + +import ( + "gorm.io/gorm" + + "github.com/go-gormigrate/gormigrate/v2" + "github.com/openshift-online/rh-trex-ai/pkg/db" +) + +func migration() *gormigrate.Migration { + type Provider struct { + db.Model + ProjectId string + Name string + Type *string + Secret *string + Namespace *string + Labels *string + Annotations *string + } + + return &gormigrate.Migration{ + ID: "202606300100", + Migrate: func(tx *gorm.DB) error { + if err := tx.AutoMigrate(&Provider{}); err != nil { + return err + } + stmts := []string{ + `CREATE INDEX IF NOT EXISTS idx_providers_project_id ON providers(project_id)`, + } + for _, s := range stmts { + if err := tx.Exec(s).Error; err != nil { + return err + } + } + return nil + }, + Rollback: func(tx *gorm.DB) error { + return tx.Migrator().DropTable(&Provider{}) + }, + } +} diff --git a/components/ambient-api-server/plugins/providers/model.go b/components/ambient-api-server/plugins/providers/model.go new file mode 100644 index 000000000..64286c00f --- /dev/null +++ b/components/ambient-api-server/plugins/providers/model.go @@ -0,0 +1,25 @@ +package providers + +import ( + "github.com/openshift-online/rh-trex-ai/pkg/api" + "gorm.io/gorm" +) + +type Provider struct { + api.Meta + ProjectId string `json:"project_id" gorm:"not null;index"` + Name string `json:"name" gorm:"not null"` + Type *string `json:"type"` + Secret *string `json:"secret"` + Namespace *string `json:"namespace"` + Labels *string `json:"labels"` + Annotations *string `json:"annotations"` +} + +type ProviderList []*Provider +type ProviderIndex map[string]*Provider + +func (d *Provider) BeforeCreate(tx *gorm.DB) error { + d.ID = api.NewID() + return nil +} diff --git a/components/ambient-api-server/plugins/providers/plugin.go b/components/ambient-api-server/plugins/providers/plugin.go new file mode 100644 index 000000000..a279fe823 --- /dev/null +++ b/components/ambient-api-server/plugins/providers/plugin.go @@ -0,0 +1,88 @@ +package providers + +import ( + "net/http" + + pkgrbac "github.com/ambient-code/platform/components/ambient-api-server/plugins/rbac" + "github.com/gorilla/mux" + "github.com/openshift-online/rh-trex-ai/pkg/api" + "github.com/openshift-online/rh-trex-ai/pkg/api/presenters" + "github.com/openshift-online/rh-trex-ai/pkg/auth" + "github.com/openshift-online/rh-trex-ai/pkg/controllers" + "github.com/openshift-online/rh-trex-ai/pkg/db" + "github.com/openshift-online/rh-trex-ai/pkg/environments" + "github.com/openshift-online/rh-trex-ai/pkg/registry" + pkgserver "github.com/openshift-online/rh-trex-ai/pkg/server" + "github.com/openshift-online/rh-trex-ai/plugins/events" + "github.com/openshift-online/rh-trex-ai/plugins/generic" +) + +type ServiceLocator func() ProviderService + +func NewServiceLocator(env *environments.Env) ServiceLocator { + return func() ProviderService { + return NewProviderService( + db.NewAdvisoryLockFactory(env.Database.SessionFactory), + NewProviderDao(&env.Database.SessionFactory), + events.Service(&env.Services), + ) + } +} + +func Service(s *environments.Services) ProviderService { + if s == nil { + return nil + } + if obj := s.GetService("Providers"); obj != nil { + locator := obj.(ServiceLocator) + return locator() + } + return nil +} + +func init() { + registry.RegisterService("Providers", func(env interface{}) interface{} { + return NewServiceLocator(env.(*environments.Env)) + }) + + pkgserver.RegisterRoutes("providers", func(apiV1Router *mux.Router, services pkgserver.ServicesInterface, authMiddleware environments.JWTMiddleware, authzMiddleware auth.AuthorizationMiddleware) { + envServices := services.(*environments.Services) + + if dbAuthz := pkgrbac.Middleware(envServices); dbAuthz != nil { + authzMiddleware = dbAuthz + } + + providerSvc := Service(envServices) + providerHandler := NewProviderHandler(providerSvc, generic.Service(envServices)) + + projectsRouter := apiV1Router.PathPrefix("/projects").Subrouter() + projectsRouter.HandleFunc("/{id}/providers", providerHandler.List).Methods(http.MethodGet) + projectsRouter.HandleFunc("/{id}/providers", providerHandler.Create).Methods(http.MethodPost) + projectsRouter.HandleFunc("/{id}/providers/{provider_id}", providerHandler.Get).Methods(http.MethodGet) + projectsRouter.HandleFunc("/{id}/providers/{provider_id}", providerHandler.Patch).Methods(http.MethodPatch) + projectsRouter.HandleFunc("/{id}/providers/{provider_id}", providerHandler.Delete).Methods(http.MethodDelete) + + projectsRouter.Use(authMiddleware.AuthenticateAccountJWT) + projectsRouter.Use(authzMiddleware.AuthorizeApi) + }) + + pkgserver.RegisterController("Providers", func(manager *controllers.KindControllerManager, services pkgserver.ServicesInterface) { + providerSvc := Service(services.(*environments.Services)) + + manager.Add(&controllers.ControllerConfig{ + Source: "Providers", + Handlers: map[api.EventType][]controllers.ControllerHandlerFunc{ + api.CreateEventType: {providerSvc.OnUpsert}, + api.UpdateEventType: {providerSvc.OnUpsert}, + api.DeleteEventType: {providerSvc.OnDelete}, + }, + }) + }) + + presenters.RegisterPath(Provider{}, "providers") + presenters.RegisterPath(&Provider{}, "providers") + presenters.RegisterKind(Provider{}, "Provider") + presenters.RegisterKind(&Provider{}, "Provider") + + db.RegisterMigration(migration()) +} diff --git a/components/ambient-api-server/plugins/providers/presenter.go b/components/ambient-api-server/plugins/providers/presenter.go new file mode 100644 index 000000000..8165cb73e --- /dev/null +++ b/components/ambient-api-server/plugins/providers/presenter.go @@ -0,0 +1,50 @@ +package providers + +import ( + "github.com/ambient-code/platform/components/ambient-api-server/pkg/api/openapi" + "github.com/openshift-online/rh-trex-ai/pkg/api" + "github.com/openshift-online/rh-trex-ai/pkg/api/presenters" + "github.com/openshift-online/rh-trex-ai/pkg/util" +) + +func ConvertProvider(p openapi.Provider) *Provider { + c := &Provider{ + Meta: api.Meta{ + ID: util.NilToEmptyString(p.Id), + }, + } + c.ProjectId = p.ProjectId + c.Name = p.Name + c.Type = p.Type + c.Secret = p.Secret + c.Namespace = p.Namespace + c.Labels = p.Labels + c.Annotations = p.Annotations + + if p.CreatedAt != nil { + c.CreatedAt = *p.CreatedAt + } + if p.UpdatedAt != nil { + c.UpdatedAt = *p.UpdatedAt + } + + return c +} + +func PresentProvider(p *Provider) openapi.Provider { + reference := presenters.PresentReference(p.ID, p) + return openapi.Provider{ + Id: reference.Id, + Kind: reference.Kind, + Href: reference.Href, + CreatedAt: openapi.PtrTime(p.CreatedAt), + UpdatedAt: openapi.PtrTime(p.UpdatedAt), + ProjectId: p.ProjectId, + Name: p.Name, + Type: p.Type, + Secret: p.Secret, + Namespace: p.Namespace, + Labels: p.Labels, + Annotations: p.Annotations, + } +} diff --git a/components/ambient-api-server/plugins/providers/service.go b/components/ambient-api-server/plugins/providers/service.go new file mode 100644 index 000000000..d00da8ae3 --- /dev/null +++ b/components/ambient-api-server/plugins/providers/service.go @@ -0,0 +1,137 @@ +package providers + +import ( + "context" + + "github.com/openshift-online/rh-trex-ai/pkg/api" + "github.com/openshift-online/rh-trex-ai/pkg/db" + "github.com/openshift-online/rh-trex-ai/pkg/errors" + "github.com/openshift-online/rh-trex-ai/pkg/logger" + "github.com/openshift-online/rh-trex-ai/pkg/services" +) + +const providersLockType db.LockType = "providers" + +type ProviderService interface { + Get(ctx context.Context, id string) (*Provider, *errors.ServiceError) + Create(ctx context.Context, provider *Provider) (*Provider, *errors.ServiceError) + Replace(ctx context.Context, provider *Provider) (*Provider, *errors.ServiceError) + Delete(ctx context.Context, id string) *errors.ServiceError + All(ctx context.Context) (ProviderList, *errors.ServiceError) + AllByProjectID(ctx context.Context, projectID string) (ProviderList, *errors.ServiceError) + + OnUpsert(ctx context.Context, id string) error + OnDelete(ctx context.Context, id string) error +} + +func NewProviderService(lockFactory db.LockFactory, providerDao ProviderDao, events services.EventService) ProviderService { + return &sqlProviderService{ + lockFactory: lockFactory, + providerDao: providerDao, + events: events, + } +} + +type sqlProviderService struct { + lockFactory db.LockFactory + providerDao ProviderDao + events services.EventService +} + +func (s *sqlProviderService) Get(ctx context.Context, id string) (*Provider, *errors.ServiceError) { + provider, err := s.providerDao.Get(ctx, id) + if err != nil { + return nil, services.HandleGetError("Provider", "id", id, err) + } + return provider, nil +} + +func (s *sqlProviderService) Create(ctx context.Context, provider *Provider) (*Provider, *errors.ServiceError) { + provider, err := s.providerDao.Create(ctx, provider) + if err != nil { + return nil, services.HandleCreateError("Provider", err) + } + + _, evErr := s.events.Create(ctx, &api.Event{ + Source: "Providers", + SourceID: provider.ID, + EventType: api.CreateEventType, + }) + if evErr != nil { + return nil, services.HandleCreateError("Provider", evErr) + } + + return provider, nil +} + +func (s *sqlProviderService) Replace(ctx context.Context, provider *Provider) (*Provider, *errors.ServiceError) { + lockOwnerID, locked, err := s.lockFactory.NewNonBlockingLock(ctx, provider.ID, providersLockType) + if err != nil { + return nil, errors.DatabaseAdvisoryLock(err) + } + if !locked { + return nil, services.HandleCreateError("Provider", errors.New(errors.ErrorConflict, "row locked")) + } + defer s.lockFactory.Unlock(ctx, lockOwnerID) + + provider, err = s.providerDao.Replace(ctx, provider) + if err != nil { + return nil, services.HandleUpdateError("Provider", err) + } + + _, evErr := s.events.Create(ctx, &api.Event{ + Source: "Providers", + SourceID: provider.ID, + EventType: api.UpdateEventType, + }) + if evErr != nil { + return nil, services.HandleUpdateError("Provider", evErr) + } + + return provider, nil +} + +func (s *sqlProviderService) Delete(ctx context.Context, id string) *errors.ServiceError { + if err := s.providerDao.Delete(ctx, id); err != nil { + return services.HandleDeleteError("Provider", errors.GeneralError("Unable to delete provider: %s", err)) + } + + _, evErr := s.events.Create(ctx, &api.Event{ + Source: "Providers", + SourceID: id, + EventType: api.DeleteEventType, + }) + if evErr != nil { + return services.HandleDeleteError("Provider", evErr) + } + + return nil +} + +func (s *sqlProviderService) All(ctx context.Context) (ProviderList, *errors.ServiceError) { + providers, err := s.providerDao.All(ctx) + if err != nil { + return nil, services.HandleGetError("Provider", "all", "", err) + } + return providers, nil +} + +func (s *sqlProviderService) AllByProjectID(ctx context.Context, projectID string) (ProviderList, *errors.ServiceError) { + providers, err := s.providerDao.AllByProjectID(ctx, projectID) + if err != nil { + return nil, services.HandleGetError("Provider", "project_id", projectID, err) + } + return providers, nil +} + +func (s *sqlProviderService) OnUpsert(ctx context.Context, id string) error { + l := logger.NewLogger(ctx) + l.Infof("Provider upserted: %s", id) + return nil +} + +func (s *sqlProviderService) OnDelete(ctx context.Context, id string) error { + l := logger.NewLogger(ctx) + l.Infof("Provider deleted: %s", id) + return nil +} diff --git a/components/ambient-control-plane/internal/reconciler/configmap_reconciler.go b/components/ambient-control-plane/internal/reconciler/configmap_reconciler.go index d777020c6..7fbe1c425 100644 --- a/components/ambient-control-plane/internal/reconciler/configmap_reconciler.go +++ b/components/ambient-control-plane/internal/reconciler/configmap_reconciler.go @@ -16,13 +16,21 @@ import ( ) const ( - configMapSyncInterval = 30 * time.Second - agentDeclarationLabel = "ambient.ai/kind=agent" - annotationSource = "ambient.ai/source" - annotationSourceCM = "configmap" - annotationSourceNS = "ambient.ai/source-namespace" + configMapSyncInterval = 30 * time.Second + agentDeclarationLabel = "ambient.ai/kind=agent" + providerDeclarationLabel = "ambient.ai/kind=provider" + policyDeclarationLabel = "ambient.ai/kind=policy" + annotationSource = "ambient.ai/source" + annotationSourceCM = "configmap" + annotationSourceNS = "ambient.ai/source-namespace" ) +type ProviderDeclaration struct { + Name string `yaml:"name"` + Type string `yaml:"type,omitempty"` + Secret string `yaml:"secret,omitempty"` +} + type AgentDeclaration struct { Name string `yaml:"name"` DisplayName string `yaml:"display_name,omitempty"` @@ -41,27 +49,27 @@ type AgentDeclaration struct { } type PayloadDecl struct { - SandboxPath string `yaml:"sandbox_path"` - Content string `yaml:"content,omitempty"` - RepoURL string `yaml:"repo_url,omitempty"` - Ref string `yaml:"ref,omitempty"` + SandboxPath string `yaml:"sandbox_path" json:"sandbox_path"` + Content string `yaml:"content,omitempty" json:"content,omitempty"` + RepoURL string `yaml:"repo_url,omitempty" json:"repo_url,omitempty"` + Ref string `yaml:"ref,omitempty" json:"ref,omitempty"` } type SandboxTemplDecl struct { - Image string `yaml:"image,omitempty"` - Resources *ResourceDecl `yaml:"resources,omitempty"` - GPU *GPUDecl `yaml:"gpu,omitempty"` - RuntimeClassName string `yaml:"runtime_class_name,omitempty"` - LogLevel string `yaml:"log_level,omitempty"` + Image string `yaml:"image,omitempty" json:"image,omitempty"` + Resources *ResourceDecl `yaml:"resources,omitempty" json:"resources,omitempty"` + GPU *GPUDecl `yaml:"gpu,omitempty" json:"gpu,omitempty"` + RuntimeClassName string `yaml:"runtime_class_name,omitempty" json:"runtime_class_name,omitempty"` + LogLevel string `yaml:"log_level,omitempty" json:"log_level,omitempty"` } type ResourceDecl struct { - CPU string `yaml:"cpu,omitempty"` - Memory string `yaml:"memory,omitempty"` + CPU string `yaml:"cpu,omitempty" json:"cpu,omitempty"` + Memory string `yaml:"memory,omitempty" json:"memory,omitempty"` } type GPUDecl struct { - Count int32 `yaml:"count,omitempty"` + Count int32 `yaml:"count,omitempty" json:"count,omitempty"` } type ConfigMapSyncer struct { @@ -111,6 +119,8 @@ func (s *ConfigMapSyncer) syncOnce(ctx context.Context) { for _, ns := range namespaces { s.syncNamespaceAgents(ctx, ns.name, ns.projectID) + s.syncNamespaceProviders(ctx, ns.name, ns.projectID) + s.syncNamespacePolicies(ctx, ns.name, ns.projectID) } } @@ -277,6 +287,11 @@ func (s *ConfigMapSyncer) upsertAgent(ctx context.Context, sdk *sdkclient.Client return nil } + // Create with minimal fields only. Complex fields (providers, payloads, + // environment, sandbox_template) are object/array types in the OpenAPI spec + // but the SDK Agent struct stores them as strings, causing double-encoding + // when json.Marshal serializes the struct. The patch map built above uses + // map[string]any with native Go types, which serializes correctly. agent, err := types.NewAgentBuilder(). Name(decl.Name). ProjectID(projectID). @@ -285,99 +300,65 @@ func (s *ConfigMapSyncer) upsertAgent(ctx context.Context, sdk *sdkclient.Client return fmt.Errorf("building agent %s: %w", decl.Name, err) } - agent.Annotations = annJSON - if decl.DisplayName != "" { - agent.DisplayName = decl.DisplayName - } - if decl.Description != "" { - agent.Description = decl.Description - } - if decl.Prompt != "" { - agent.Prompt = decl.Prompt - } - if decl.RepoURL != "" { - agent.RepoURL = decl.RepoURL - } - if decl.LlmModel != "" { - agent.LlmModel = decl.LlmModel - } - if decl.Entrypoint != "" { - agent.Entrypoint = decl.Entrypoint - } - if decl.SandboxPolicy != "" { - agent.SandboxPolicy = decl.SandboxPolicy - } - if len(decl.Providers) > 0 { - raw, err := json.Marshal(decl.Providers) - if err != nil { - return fmt.Errorf("marshalling providers: %w", err) - } - agent.Providers = string(raw) - } - if len(decl.Payloads) > 0 { - raw, err := json.Marshal(decl.Payloads) - if err != nil { - return fmt.Errorf("marshalling payloads: %w", err) - } - agent.Payloads = string(raw) - } - if len(decl.Environment) > 0 { - raw, err := json.Marshal(decl.Environment) - if err != nil { - return fmt.Errorf("marshalling environment: %w", err) - } - agent.Environment = string(raw) - } - if decl.SandboxTemplate != nil { - raw, err := json.Marshal(decl.SandboxTemplate) - if err != nil { - return fmt.Errorf("marshalling sandbox_template: %w", err) - } - agent.SandboxTemplate = string(raw) - } - created, err := sdk.Agents().Create(ctx, agent) if err != nil { return fmt.Errorf("creating agent %s: %w", decl.Name, err) } + if _, err := sdk.Agents().Update(ctx, created.ID, patch); err != nil { + return fmt.Errorf("updating newly created agent %s: %w", decl.Name, err) + } s.logger.Info().Str("agent", decl.Name).Str("id", created.ID).Msg("agent created from configmap") return nil } func (s *ConfigMapSyncer) findAgentByName(ctx context.Context, sdk *sdkclient.Client, projectID, name string) *types.Agent { - escaped := strings.ReplaceAll(name, "'", "''") - agents, err := sdk.Agents().List(ctx, &types.ListOptions{Size: 100, Search: fmt.Sprintf("name = '%s'", escaped)}) + escapedName := strings.ReplaceAll(name, "'", "''") + escapedProjectID := strings.ReplaceAll(projectID, "'", "''") + // Request only scalar fields to avoid deserialization failures: the API + // returns environment/providers/payloads/sandbox_template as JSON + // objects/arrays, but the SDK Agent struct types them as strings. + agents, err := sdk.Agents().List(ctx, &types.ListOptions{ + Size: 100, + Search: fmt.Sprintf("name = '%s' AND project_id = '%s'", escapedName, escapedProjectID), + Fields: "id,name,project_id,annotations", + }) if err != nil { + s.logger.Warn().Err(err).Str("name", name).Str("project_id", projectID).Msg("failed to search for existing agent") return nil } for _, a := range agents.Items { - if a.Name == name { + if a.Name == name && a.ProjectID == projectID { return &a } } return nil } -func (s *ConfigMapSyncer) isConfigMapManaged(agent *types.Agent, namespace string) bool { - if agent.Annotations == "" { +func (s *ConfigMapSyncer) isConfigMapManaged(annotations string, namespace string) bool { + if annotations == "" { return false } var ann map[string]string - if err := json.Unmarshal([]byte(agent.Annotations), &ann); err != nil { + if err := json.Unmarshal([]byte(annotations), &ann); err != nil { return false } return ann[annotationSource] == annotationSourceCM && ann[annotationSourceNS] == namespace } func (s *ConfigMapSyncer) pruneRemovedAgents(ctx context.Context, sdk *sdkclient.Client, projectID, namespace string, declaredAgents map[string]bool) { - agents, err := sdk.Agents().List(ctx, &types.ListOptions{Size: 500}) + escapedProjectID := strings.ReplaceAll(projectID, "'", "''") + agents, err := sdk.Agents().List(ctx, &types.ListOptions{ + Size: 500, + Search: fmt.Sprintf("project_id = '%s'", escapedProjectID), + Fields: "id,name,project_id,annotations", + }) if err != nil { s.logger.Warn().Err(err).Str("project_id", projectID).Msg("failed to list agents for pruning") return } for _, a := range agents.Items { - if s.isConfigMapManaged(&a, namespace) && !declaredAgents[a.Name] { + if s.isConfigMapManaged(a.Annotations, namespace) && !declaredAgents[a.Name] { if err := sdk.Agents().Delete(ctx, a.ID); err != nil { s.logger.Warn().Err(err).Str("agent", a.Name).Msg("failed to delete stale agent") } else { @@ -386,3 +367,304 @@ func (s *ConfigMapSyncer) pruneRemovedAgents(ctx context.Context, sdk *sdkclient } } } + +// --- Provider ConfigMap sync --- + +func (s *ConfigMapSyncer) syncNamespaceProviders(ctx context.Context, namespace, projectID string) { + cmList, err := s.kube.ListConfigMapsByLabel(ctx, namespace, providerDeclarationLabel) + if err != nil { + s.logger.Warn().Err(err).Str("namespace", namespace).Msg("failed to list provider configmaps") + return + } + + sdk, err := s.factory.ForProject(ctx, projectID) + if err != nil { + s.logger.Warn().Err(err).Str("project_id", projectID).Msg("failed to get SDK client for provider sync") + return + } + + declared := map[string]bool{} + + for _, cm := range cmList.Items { + data, found, nestedErr := unstructured.NestedStringMap(cm.Object, "data") + if nestedErr != nil { + s.logger.Warn().Err(nestedErr).Str("configmap", cm.GetName()).Msg("failed to read provider configmap data") + continue + } + if !found { + continue + } + for key, yamlStr := range data { + var decl ProviderDeclaration + if unmarshalErr := yaml.Unmarshal([]byte(yamlStr), &decl); unmarshalErr != nil { + s.logger.Warn().Err(unmarshalErr). + Str("namespace", namespace). + Str("configmap", cm.GetName()). + Str("key", key). + Msg("invalid provider declaration YAML") + continue + } + if decl.Name == "" { + s.logger.Warn(). + Str("namespace", namespace). + Str("configmap", cm.GetName()). + Str("key", key). + Msg("provider declaration missing required 'name' field") + continue + } + + declared[decl.Name] = true + if upsertErr := s.upsertProvider(ctx, sdk, projectID, namespace, &decl); upsertErr != nil { + s.logger.Warn().Err(upsertErr). + Str("namespace", namespace). + Str("provider", decl.Name). + Msg("failed to upsert provider from configmap") + } + } + } + + s.pruneRemovedProviders(ctx, sdk, projectID, namespace, declared) +} + +func (s *ConfigMapSyncer) upsertProvider(ctx context.Context, sdk *sdkclient.Client, projectID, namespace string, decl *ProviderDeclaration) error { + existing := s.findProviderByName(ctx, sdk, projectID, decl.Name) + + annJSON, err := s.buildOriginAnnotations(namespace, nil) + if err != nil { + return err + } + + patch := map[string]interface{}{ + "annotations": annJSON, + } + if decl.Type != "" { + patch["type"] = decl.Type + } + if decl.Secret != "" { + patch["secret"] = decl.Secret + } + + if existing != nil { + if _, updateErr := sdk.Providers().Update(ctx, existing.ID, patch); updateErr != nil { + return fmt.Errorf("updating provider %s: %w", decl.Name, updateErr) + } + s.logger.Debug().Str("provider", decl.Name).Str("id", existing.ID).Msg("provider updated from configmap") + return nil + } + + provider, err := types.NewProviderBuilder(). + Name(decl.Name). + ProjectID(projectID). + Namespace(namespace). + Build() + if err != nil { + return fmt.Errorf("building provider %s: %w", decl.Name, err) + } + + created, createErr := sdk.Providers().Create(ctx, provider) + if createErr != nil { + return fmt.Errorf("creating provider %s: %w", decl.Name, createErr) + } + if _, updateErr := sdk.Providers().Update(ctx, created.ID, patch); updateErr != nil { + return fmt.Errorf("updating newly created provider %s: %w", decl.Name, updateErr) + } + s.logger.Info().Str("provider", decl.Name).Str("id", created.ID).Msg("provider created from configmap") + return nil +} + +func (s *ConfigMapSyncer) findProviderByName(ctx context.Context, sdk *sdkclient.Client, projectID, name string) *types.Provider { + escapedName := strings.ReplaceAll(name, "'", "''") + escapedProjectID := strings.ReplaceAll(projectID, "'", "''") + providers, err := sdk.Providers().List(ctx, &types.ListOptions{ + Size: 100, + Search: fmt.Sprintf("name = '%s' AND project_id = '%s'", escapedName, escapedProjectID), + }) + if err != nil { + s.logger.Warn().Err(err).Str("name", name).Str("project_id", projectID).Msg("failed to search for existing provider") + return nil + } + for _, p := range providers.Items { + if p.Name == name && p.ProjectID == projectID { + return &p + } + } + return nil +} + +func (s *ConfigMapSyncer) pruneRemovedProviders(ctx context.Context, sdk *sdkclient.Client, projectID, namespace string, declared map[string]bool) { + escapedProjectID := strings.ReplaceAll(projectID, "'", "''") + providers, err := sdk.Providers().List(ctx, &types.ListOptions{ + Size: 500, + Search: fmt.Sprintf("project_id = '%s'", escapedProjectID), + }) + if err != nil { + s.logger.Warn().Err(err).Str("project_id", projectID).Msg("failed to list providers for pruning") + return + } + + for _, p := range providers.Items { + if s.isConfigMapManaged(p.Annotations, namespace) && !declared[p.Name] { + if deleteErr := sdk.Providers().Delete(ctx, p.ID); deleteErr != nil { + s.logger.Warn().Err(deleteErr).Str("provider", p.Name).Msg("failed to delete stale provider") + } else { + s.logger.Info().Str("provider", p.Name).Str("id", p.ID).Msg("pruned provider no longer declared in configmaps") + } + } + } +} + +// --- Policy ConfigMap sync --- + +func (s *ConfigMapSyncer) syncNamespacePolicies(ctx context.Context, namespace, projectID string) { + cmList, err := s.kube.ListConfigMapsByLabel(ctx, namespace, policyDeclarationLabel) + if err != nil { + s.logger.Warn().Err(err).Str("namespace", namespace).Msg("failed to list policy configmaps") + return + } + + sdk, err := s.factory.ForProject(ctx, projectID) + if err != nil { + s.logger.Warn().Err(err).Str("project_id", projectID).Msg("failed to get SDK client for policy sync") + return + } + + declared := map[string]bool{} + + for _, cm := range cmList.Items { + data, found, nestedErr := unstructured.NestedStringMap(cm.Object, "data") + if nestedErr != nil { + s.logger.Warn().Err(nestedErr).Str("configmap", cm.GetName()).Msg("failed to read policy configmap data") + continue + } + if !found { + continue + } + for key, yamlStr := range data { + name, spec, parseErr := parsePolicyDeclaration(yamlStr) + if parseErr != nil { + s.logger.Warn().Err(parseErr). + Str("namespace", namespace). + Str("configmap", cm.GetName()). + Str("key", key). + Msg("invalid policy declaration YAML") + continue + } + if name == "" { + s.logger.Warn(). + Str("namespace", namespace). + Str("configmap", cm.GetName()). + Str("key", key). + Msg("policy declaration missing required 'name' field") + continue + } + + declared[name] = true + if upsertErr := s.upsertPolicy(ctx, sdk, projectID, namespace, name, spec); upsertErr != nil { + s.logger.Warn().Err(upsertErr). + Str("namespace", namespace). + Str("policy", name). + Msg("failed to upsert policy from configmap") + } + } + } + + s.pruneRemovedPolicies(ctx, sdk, projectID, namespace, declared) +} + +func parsePolicyDeclaration(yamlStr string) (name string, spec map[string]interface{}, err error) { + var raw map[string]interface{} + if err := yaml.Unmarshal([]byte(yamlStr), &raw); err != nil { + return "", nil, fmt.Errorf("parsing policy YAML: %w", err) + } + + if nameVal, ok := raw["name"]; ok { + if nameStr, isStr := nameVal.(string); isStr { + name = nameStr + } + delete(raw, "name") + } + + return name, raw, nil +} + +func (s *ConfigMapSyncer) upsertPolicy(ctx context.Context, sdk *sdkclient.Client, projectID, namespace, name string, spec map[string]interface{}) error { + existing := s.findPolicyByName(ctx, sdk, projectID, name) + + annJSON, err := s.buildOriginAnnotations(namespace, nil) + if err != nil { + return err + } + + patch := map[string]interface{}{ + "annotations": annJSON, + "spec": spec, + } + + if existing != nil { + if _, updateErr := sdk.Policys().Update(ctx, existing.ID, patch); updateErr != nil { + return fmt.Errorf("updating policy %s: %w", name, updateErr) + } + s.logger.Debug().Str("policy", name).Str("id", existing.ID).Msg("policy updated from configmap") + return nil + } + + policy, err := types.NewPolicyBuilder(). + Name(name). + ProjectID(projectID). + Namespace(namespace). + Build() + if err != nil { + return fmt.Errorf("building policy %s: %w", name, err) + } + + created, createErr := sdk.Policys().Create(ctx, policy) + if createErr != nil { + return fmt.Errorf("creating policy %s: %w", name, createErr) + } + if _, updateErr := sdk.Policys().Update(ctx, created.ID, patch); updateErr != nil { + return fmt.Errorf("updating newly created policy %s: %w", name, updateErr) + } + s.logger.Info().Str("policy", name).Str("id", created.ID).Msg("policy created from configmap") + return nil +} + +func (s *ConfigMapSyncer) findPolicyByName(ctx context.Context, sdk *sdkclient.Client, projectID, name string) *types.Policy { + escapedName := strings.ReplaceAll(name, "'", "''") + escapedProjectID := strings.ReplaceAll(projectID, "'", "''") + policies, err := sdk.Policys().List(ctx, &types.ListOptions{ + Size: 100, + Search: fmt.Sprintf("name = '%s' AND project_id = '%s'", escapedName, escapedProjectID), + }) + if err != nil { + s.logger.Warn().Err(err).Str("name", name).Str("project_id", projectID).Msg("failed to search for existing policy") + return nil + } + for _, p := range policies.Items { + if p.Name == name && p.ProjectID == projectID { + return &p + } + } + return nil +} + +func (s *ConfigMapSyncer) pruneRemovedPolicies(ctx context.Context, sdk *sdkclient.Client, projectID, namespace string, declared map[string]bool) { + escapedProjectID := strings.ReplaceAll(projectID, "'", "''") + policies, err := sdk.Policys().List(ctx, &types.ListOptions{ + Size: 500, + Search: fmt.Sprintf("project_id = '%s'", escapedProjectID), + }) + if err != nil { + s.logger.Warn().Err(err).Str("project_id", projectID).Msg("failed to list policies for pruning") + return + } + + for _, p := range policies.Items { + if s.isConfigMapManaged(p.Annotations, namespace) && !declared[p.Name] { + if deleteErr := sdk.Policys().Delete(ctx, p.ID); deleteErr != nil { + s.logger.Warn().Err(deleteErr).Str("policy", p.Name).Msg("failed to delete stale policy") + } else { + s.logger.Info().Str("policy", p.Name).Str("id", p.ID).Msg("pruned policy no longer declared in configmaps") + } + } + } +} diff --git a/components/ambient-control-plane/internal/reconciler/configmap_reconciler_test.go b/components/ambient-control-plane/internal/reconciler/configmap_reconciler_test.go index 7e5394e59..bac39372a 100644 --- a/components/ambient-control-plane/internal/reconciler/configmap_reconciler_test.go +++ b/components/ambient-control-plane/internal/reconciler/configmap_reconciler_test.go @@ -4,7 +4,6 @@ import ( "encoding/json" "testing" - "github.com/ambient-code/platform/components/ambient-sdk/go-sdk/types" "github.com/rs/zerolog" ) @@ -135,62 +134,54 @@ func TestIsConfigMapManaged(t *testing.T) { } tests := []struct { - name string - agent *types.Agent - namespace string - want bool + name string + annotations string + namespace string + want bool }{ { - name: "no annotations", - agent: &types.Agent{}, - namespace: "ns-1", - want: false, + name: "empty annotations", + annotations: "", + namespace: "ns-1", + want: false, }, { name: "configmap-managed matching namespace", - agent: &types.Agent{ - Annotations: mustJSON(map[string]string{ - annotationSource: annotationSourceCM, - annotationSourceNS: "ns-1", - }), - }, + annotations: mustJSON(map[string]string{ + annotationSource: annotationSourceCM, + annotationSourceNS: "ns-1", + }), namespace: "ns-1", want: true, }, { name: "configmap-managed different namespace", - agent: &types.Agent{ - Annotations: mustJSON(map[string]string{ - annotationSource: annotationSourceCM, - annotationSourceNS: "ns-2", - }), - }, + annotations: mustJSON(map[string]string{ + annotationSource: annotationSourceCM, + annotationSourceNS: "ns-2", + }), namespace: "ns-1", want: false, }, { name: "not configmap-managed", - agent: &types.Agent{ - Annotations: mustJSON(map[string]string{ - "some-other": "annotation", - }), - }, + annotations: mustJSON(map[string]string{ + "some-other": "annotation", + }), namespace: "ns-1", want: false, }, { - name: "invalid JSON annotations", - agent: &types.Agent{ - Annotations: "not-json", - }, - namespace: "ns-1", - want: false, + name: "invalid JSON annotations", + annotations: "not-json", + namespace: "ns-1", + want: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := syncer.isConfigMapManaged(tt.agent, tt.namespace) + got := syncer.isConfigMapManaged(tt.annotations, tt.namespace) if got != tt.want { t.Errorf("isConfigMapManaged() = %v, want %v", got, tt.want) } @@ -198,6 +189,90 @@ func TestIsConfigMapManaged(t *testing.T) { } } +func TestParsePolicyDeclaration(t *testing.T) { + tests := []struct { + name string + yaml string + wantName string + wantErr bool + check func(t *testing.T, spec map[string]interface{}) + }{ + { + name: "minimal policy", + yaml: "name: my-policy\n", + wantName: "my-policy", + check: func(t *testing.T, spec map[string]interface{}) { + if len(spec) != 0 { + t.Errorf("expected empty spec, got %v", spec) + } + }, + }, + { + name: "full policy with network_policies", + yaml: ` +name: restricted-github-only +network_policies: + github_api: + endpoints: + - host: api.github.com + port: 443 +filesystem: + read_write: + - /sandbox + - /tmp +process: + run_as_user: sandbox +`, + wantName: "restricted-github-only", + check: func(t *testing.T, spec map[string]interface{}) { + if _, ok := spec["network_policies"]; !ok { + t.Error("expected network_policies in spec") + } + if _, ok := spec["filesystem"]; !ok { + t.Error("expected filesystem in spec") + } + if _, ok := spec["process"]; !ok { + t.Error("expected process in spec") + } + if _, ok := spec["name"]; ok { + t.Error("name should be stripped from spec") + } + }, + }, + { + name: "missing name", + yaml: "filesystem:\n read_write:\n - /tmp\n", + wantName: "", + }, + { + name: "invalid YAML", + yaml: "{{{not yaml", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + name, spec, err := parsePolicyDeclaration(tt.yaml) + if tt.wantErr { + if err == nil { + t.Fatal("expected error, got nil") + } + return + } + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if name != tt.wantName { + t.Errorf("name = %q, want %q", name, tt.wantName) + } + if tt.check != nil { + tt.check(t, spec) + } + }) + } +} + func mustJSON(v interface{}) string { raw, err := json.Marshal(v) if err != nil { diff --git a/components/ambient-sdk/go-sdk/client/agent_api.go b/components/ambient-sdk/go-sdk/client/agent_api.go index 5ed652e68..974d79303 100644 --- a/components/ambient-sdk/go-sdk/client/agent_api.go +++ b/components/ambient-sdk/go-sdk/client/agent_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package client diff --git a/components/ambient-sdk/go-sdk/client/client.go b/components/ambient-sdk/go-sdk/client/client.go index e32fe47a8..d2f29fe1e 100644 --- a/components/ambient-sdk/go-sdk/client/client.go +++ b/components/ambient-sdk/go-sdk/client/client.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package client diff --git a/components/ambient-sdk/go-sdk/client/credential_api.go b/components/ambient-sdk/go-sdk/client/credential_api.go index 3a6479e0d..809d1fde1 100644 --- a/components/ambient-sdk/go-sdk/client/credential_api.go +++ b/components/ambient-sdk/go-sdk/client/credential_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package client diff --git a/components/ambient-sdk/go-sdk/client/inbox_message_api.go b/components/ambient-sdk/go-sdk/client/inbox_message_api.go index 4e2711c70..a33fc0f82 100644 --- a/components/ambient-sdk/go-sdk/client/inbox_message_api.go +++ b/components/ambient-sdk/go-sdk/client/inbox_message_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package client diff --git a/components/ambient-sdk/go-sdk/client/iterator.go b/components/ambient-sdk/go-sdk/client/iterator.go index 519bddbac..ae71b2431 100644 --- a/components/ambient-sdk/go-sdk/client/iterator.go +++ b/components/ambient-sdk/go-sdk/client/iterator.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package client diff --git a/components/ambient-sdk/go-sdk/client/policy_api.go b/components/ambient-sdk/go-sdk/client/policy_api.go new file mode 100644 index 000000000..0b37f737d --- /dev/null +++ b/components/ambient-sdk/go-sdk/client/policy_api.go @@ -0,0 +1,79 @@ +// Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. +// Source: ../../ambient-api-server/openapi/openapi.yaml +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z + +package client + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "net/url" + "strings" + + "github.com/ambient-code/platform/components/ambient-sdk/go-sdk/types" +) + +type PolicyAPI struct { + client *Client +} + +func (c *Client) Policys() *PolicyAPI { + return &PolicyAPI{client: c} +} +func (a *PolicyAPI) basePath() string { + return strings.NewReplacer("{id}", url.PathEscape(a.client.project)).Replace("/projects/{id}/policies") +} + +func (a *PolicyAPI) Create(ctx context.Context, resource *types.Policy) (*types.Policy, error) { + body, err := json.Marshal(resource) + if err != nil { + return nil, fmt.Errorf("marshal policy: %w", err) + } + var result types.Policy + if err := a.client.do(ctx, http.MethodPost, a.basePath(), body, http.StatusCreated, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (a *PolicyAPI) Get(ctx context.Context, id string) (*types.Policy, error) { + var result types.Policy + if err := a.client.do(ctx, http.MethodGet, a.basePath()+"/"+url.PathEscape(id), nil, http.StatusOK, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (a *PolicyAPI) List(ctx context.Context, opts *types.ListOptions) (*types.PolicyList, error) { + var result types.PolicyList + if err := a.client.doWithQuery(ctx, http.MethodGet, a.basePath(), nil, http.StatusOK, &result, opts); err != nil { + return nil, err + } + return &result, nil +} +func (a *PolicyAPI) Update(ctx context.Context, id string, patch map[string]any) (*types.Policy, error) { + body, err := json.Marshal(patch) + if err != nil { + return nil, fmt.Errorf("marshal patch: %w", err) + } + var result types.Policy + if err := a.client.do(ctx, http.MethodPatch, a.basePath()+"/"+url.PathEscape(id), body, http.StatusOK, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (a *PolicyAPI) Delete(ctx context.Context, id string) error { + return a.client.do(ctx, http.MethodDelete, a.basePath()+"/"+url.PathEscape(id), nil, http.StatusNoContent, nil) +} + +func (a *PolicyAPI) ListAll(ctx context.Context, opts *types.ListOptions) *Iterator[types.Policy] { + return NewIterator(func(page int) (*types.PolicyList, error) { + o := *opts + o.Page = page + return a.List(ctx, &o) + }) +} diff --git a/components/ambient-sdk/go-sdk/client/project_api.go b/components/ambient-sdk/go-sdk/client/project_api.go index 8b8054f47..e3030cae8 100644 --- a/components/ambient-sdk/go-sdk/client/project_api.go +++ b/components/ambient-sdk/go-sdk/client/project_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package client diff --git a/components/ambient-sdk/go-sdk/client/project_settings_api.go b/components/ambient-sdk/go-sdk/client/project_settings_api.go index 85bf65bf2..a555a6010 100644 --- a/components/ambient-sdk/go-sdk/client/project_settings_api.go +++ b/components/ambient-sdk/go-sdk/client/project_settings_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package client diff --git a/components/ambient-sdk/go-sdk/client/provider_api.go b/components/ambient-sdk/go-sdk/client/provider_api.go new file mode 100644 index 000000000..f7f5383a9 --- /dev/null +++ b/components/ambient-sdk/go-sdk/client/provider_api.go @@ -0,0 +1,79 @@ +// Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. +// Source: ../../ambient-api-server/openapi/openapi.yaml +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z + +package client + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "net/url" + "strings" + + "github.com/ambient-code/platform/components/ambient-sdk/go-sdk/types" +) + +type ProviderAPI struct { + client *Client +} + +func (c *Client) Providers() *ProviderAPI { + return &ProviderAPI{client: c} +} +func (a *ProviderAPI) basePath() string { + return strings.NewReplacer("{id}", url.PathEscape(a.client.project)).Replace("/projects/{id}/providers") +} + +func (a *ProviderAPI) Create(ctx context.Context, resource *types.Provider) (*types.Provider, error) { + body, err := json.Marshal(resource) + if err != nil { + return nil, fmt.Errorf("marshal provider: %w", err) + } + var result types.Provider + if err := a.client.do(ctx, http.MethodPost, a.basePath(), body, http.StatusCreated, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (a *ProviderAPI) Get(ctx context.Context, id string) (*types.Provider, error) { + var result types.Provider + if err := a.client.do(ctx, http.MethodGet, a.basePath()+"/"+url.PathEscape(id), nil, http.StatusOK, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (a *ProviderAPI) List(ctx context.Context, opts *types.ListOptions) (*types.ProviderList, error) { + var result types.ProviderList + if err := a.client.doWithQuery(ctx, http.MethodGet, a.basePath(), nil, http.StatusOK, &result, opts); err != nil { + return nil, err + } + return &result, nil +} +func (a *ProviderAPI) Update(ctx context.Context, id string, patch map[string]any) (*types.Provider, error) { + body, err := json.Marshal(patch) + if err != nil { + return nil, fmt.Errorf("marshal patch: %w", err) + } + var result types.Provider + if err := a.client.do(ctx, http.MethodPatch, a.basePath()+"/"+url.PathEscape(id), body, http.StatusOK, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (a *ProviderAPI) Delete(ctx context.Context, id string) error { + return a.client.do(ctx, http.MethodDelete, a.basePath()+"/"+url.PathEscape(id), nil, http.StatusNoContent, nil) +} + +func (a *ProviderAPI) ListAll(ctx context.Context, opts *types.ListOptions) *Iterator[types.Provider] { + return NewIterator(func(page int) (*types.ProviderList, error) { + o := *opts + o.Page = page + return a.List(ctx, &o) + }) +} diff --git a/components/ambient-sdk/go-sdk/client/role_api.go b/components/ambient-sdk/go-sdk/client/role_api.go index 14fb08bc0..4c1164e94 100644 --- a/components/ambient-sdk/go-sdk/client/role_api.go +++ b/components/ambient-sdk/go-sdk/client/role_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package client diff --git a/components/ambient-sdk/go-sdk/client/role_binding_api.go b/components/ambient-sdk/go-sdk/client/role_binding_api.go index fee30a8e7..1948f345d 100644 --- a/components/ambient-sdk/go-sdk/client/role_binding_api.go +++ b/components/ambient-sdk/go-sdk/client/role_binding_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package client diff --git a/components/ambient-sdk/go-sdk/client/scheduled_session_api.go b/components/ambient-sdk/go-sdk/client/scheduled_session_api.go index 34f4314d8..8e1f42661 100644 --- a/components/ambient-sdk/go-sdk/client/scheduled_session_api.go +++ b/components/ambient-sdk/go-sdk/client/scheduled_session_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package client diff --git a/components/ambient-sdk/go-sdk/client/session_api.go b/components/ambient-sdk/go-sdk/client/session_api.go index 76933d10a..8c50071b4 100644 --- a/components/ambient-sdk/go-sdk/client/session_api.go +++ b/components/ambient-sdk/go-sdk/client/session_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package client diff --git a/components/ambient-sdk/go-sdk/client/session_message_api.go b/components/ambient-sdk/go-sdk/client/session_message_api.go index 65a885b94..85777a0ff 100644 --- a/components/ambient-sdk/go-sdk/client/session_message_api.go +++ b/components/ambient-sdk/go-sdk/client/session_message_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package client diff --git a/components/ambient-sdk/go-sdk/client/user_api.go b/components/ambient-sdk/go-sdk/client/user_api.go index 8fcb35c89..00b05e9d3 100644 --- a/components/ambient-sdk/go-sdk/client/user_api.go +++ b/components/ambient-sdk/go-sdk/client/user_api.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package client diff --git a/components/ambient-sdk/go-sdk/types/agent.go b/components/ambient-sdk/go-sdk/types/agent.go index a1d3515ac..ffae60c53 100644 --- a/components/ambient-sdk/go-sdk/types/agent.go +++ b/components/ambient-sdk/go-sdk/types/agent.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package types diff --git a/components/ambient-sdk/go-sdk/types/base.go b/components/ambient-sdk/go-sdk/types/base.go index c311a6ff1..d1521989d 100644 --- a/components/ambient-sdk/go-sdk/types/base.go +++ b/components/ambient-sdk/go-sdk/types/base.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package types diff --git a/components/ambient-sdk/go-sdk/types/credential.go b/components/ambient-sdk/go-sdk/types/credential.go index 692936bca..ec0e12de5 100644 --- a/components/ambient-sdk/go-sdk/types/credential.go +++ b/components/ambient-sdk/go-sdk/types/credential.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package types diff --git a/components/ambient-sdk/go-sdk/types/inbox_message.go b/components/ambient-sdk/go-sdk/types/inbox_message.go index af33b4ed9..8625ed568 100644 --- a/components/ambient-sdk/go-sdk/types/inbox_message.go +++ b/components/ambient-sdk/go-sdk/types/inbox_message.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package types diff --git a/components/ambient-sdk/go-sdk/types/list_options.go b/components/ambient-sdk/go-sdk/types/list_options.go index 0939dc289..a5f895797 100644 --- a/components/ambient-sdk/go-sdk/types/list_options.go +++ b/components/ambient-sdk/go-sdk/types/list_options.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package types diff --git a/components/ambient-sdk/go-sdk/types/policy.go b/components/ambient-sdk/go-sdk/types/policy.go new file mode 100644 index 000000000..76ce19ae3 --- /dev/null +++ b/components/ambient-sdk/go-sdk/types/policy.go @@ -0,0 +1,121 @@ +// Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. +// Source: ../../ambient-api-server/openapi/openapi.yaml +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z + +package types + +import ( + "errors" + "fmt" +) + +type Policy struct { + ObjectReference + + Annotations string `json:"annotations,omitempty"` + Labels string `json:"labels,omitempty"` + Name string `json:"name"` + Namespace string `json:"namespace,omitempty"` + ProjectID string `json:"project_id"` + Spec string `json:"spec,omitempty"` +} + +type PolicyList struct { + ListMeta + Items []Policy `json:"items"` +} + +func (l *PolicyList) GetItems() []Policy { return l.Items } +func (l *PolicyList) GetTotal() int { return l.Total } +func (l *PolicyList) GetPage() int { return l.Page } +func (l *PolicyList) GetSize() int { return l.Size } + +type PolicyBuilder struct { + resource Policy + errors []error +} + +func NewPolicyBuilder() *PolicyBuilder { + return &PolicyBuilder{} +} + +func (b *PolicyBuilder) Annotations(v string) *PolicyBuilder { + b.resource.Annotations = v + return b +} + +func (b *PolicyBuilder) Labels(v string) *PolicyBuilder { + b.resource.Labels = v + return b +} + +func (b *PolicyBuilder) Name(v string) *PolicyBuilder { + b.resource.Name = v + return b +} + +func (b *PolicyBuilder) Namespace(v string) *PolicyBuilder { + b.resource.Namespace = v + return b +} + +func (b *PolicyBuilder) ProjectID(v string) *PolicyBuilder { + b.resource.ProjectID = v + return b +} + +func (b *PolicyBuilder) Spec(v string) *PolicyBuilder { + b.resource.Spec = v + return b +} + +func (b *PolicyBuilder) Build() (*Policy, error) { + if b.resource.Name == "" { + b.errors = append(b.errors, fmt.Errorf("name is required")) + } + if b.resource.ProjectID == "" { + b.errors = append(b.errors, fmt.Errorf("project_id is required")) + } + if len(b.errors) > 0 { + return nil, fmt.Errorf("validation failed: %w", errors.Join(b.errors...)) + } + return &b.resource, nil +} + +type PolicyPatchBuilder struct { + patch map[string]any +} + +func NewPolicyPatchBuilder() *PolicyPatchBuilder { + return &PolicyPatchBuilder{patch: make(map[string]any)} +} + +func (b *PolicyPatchBuilder) Annotations(v string) *PolicyPatchBuilder { + b.patch["annotations"] = v + return b +} + +func (b *PolicyPatchBuilder) Labels(v string) *PolicyPatchBuilder { + b.patch["labels"] = v + return b +} + +func (b *PolicyPatchBuilder) Name(v string) *PolicyPatchBuilder { + b.patch["name"] = v + return b +} + +func (b *PolicyPatchBuilder) Namespace(v string) *PolicyPatchBuilder { + b.patch["namespace"] = v + return b +} + +func (b *PolicyPatchBuilder) Spec(v string) *PolicyPatchBuilder { + b.patch["spec"] = v + return b +} + +func (b *PolicyPatchBuilder) Build() map[string]any { + return b.patch +} diff --git a/components/ambient-sdk/go-sdk/types/project.go b/components/ambient-sdk/go-sdk/types/project.go index e26a24be6..fdbac24de 100644 --- a/components/ambient-sdk/go-sdk/types/project.go +++ b/components/ambient-sdk/go-sdk/types/project.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package types diff --git a/components/ambient-sdk/go-sdk/types/project_settings.go b/components/ambient-sdk/go-sdk/types/project_settings.go index 4a69eac7b..6d315dc1f 100644 --- a/components/ambient-sdk/go-sdk/types/project_settings.go +++ b/components/ambient-sdk/go-sdk/types/project_settings.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package types diff --git a/components/ambient-sdk/go-sdk/types/provider.go b/components/ambient-sdk/go-sdk/types/provider.go new file mode 100644 index 000000000..1c51e2aec --- /dev/null +++ b/components/ambient-sdk/go-sdk/types/provider.go @@ -0,0 +1,132 @@ +// Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. +// Source: ../../ambient-api-server/openapi/openapi.yaml +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z + +package types + +import ( + "errors" + "fmt" +) + +type Provider struct { + ObjectReference + + Annotations string `json:"annotations,omitempty"` + Labels string `json:"labels,omitempty"` + Name string `json:"name"` + Namespace string `json:"namespace,omitempty"` + ProjectID string `json:"project_id"` + Secret string `json:"secret,omitempty"` + Type string `json:"type,omitempty"` +} + +type ProviderList struct { + ListMeta + Items []Provider `json:"items"` +} + +func (l *ProviderList) GetItems() []Provider { return l.Items } +func (l *ProviderList) GetTotal() int { return l.Total } +func (l *ProviderList) GetPage() int { return l.Page } +func (l *ProviderList) GetSize() int { return l.Size } + +type ProviderBuilder struct { + resource Provider + errors []error +} + +func NewProviderBuilder() *ProviderBuilder { + return &ProviderBuilder{} +} + +func (b *ProviderBuilder) Annotations(v string) *ProviderBuilder { + b.resource.Annotations = v + return b +} + +func (b *ProviderBuilder) Labels(v string) *ProviderBuilder { + b.resource.Labels = v + return b +} + +func (b *ProviderBuilder) Name(v string) *ProviderBuilder { + b.resource.Name = v + return b +} + +func (b *ProviderBuilder) Namespace(v string) *ProviderBuilder { + b.resource.Namespace = v + return b +} + +func (b *ProviderBuilder) ProjectID(v string) *ProviderBuilder { + b.resource.ProjectID = v + return b +} + +func (b *ProviderBuilder) Secret(v string) *ProviderBuilder { + b.resource.Secret = v + return b +} + +func (b *ProviderBuilder) Type(v string) *ProviderBuilder { + b.resource.Type = v + return b +} + +func (b *ProviderBuilder) Build() (*Provider, error) { + if b.resource.Name == "" { + b.errors = append(b.errors, fmt.Errorf("name is required")) + } + if b.resource.ProjectID == "" { + b.errors = append(b.errors, fmt.Errorf("project_id is required")) + } + if len(b.errors) > 0 { + return nil, fmt.Errorf("validation failed: %w", errors.Join(b.errors...)) + } + return &b.resource, nil +} + +type ProviderPatchBuilder struct { + patch map[string]any +} + +func NewProviderPatchBuilder() *ProviderPatchBuilder { + return &ProviderPatchBuilder{patch: make(map[string]any)} +} + +func (b *ProviderPatchBuilder) Annotations(v string) *ProviderPatchBuilder { + b.patch["annotations"] = v + return b +} + +func (b *ProviderPatchBuilder) Labels(v string) *ProviderPatchBuilder { + b.patch["labels"] = v + return b +} + +func (b *ProviderPatchBuilder) Name(v string) *ProviderPatchBuilder { + b.patch["name"] = v + return b +} + +func (b *ProviderPatchBuilder) Namespace(v string) *ProviderPatchBuilder { + b.patch["namespace"] = v + return b +} + +func (b *ProviderPatchBuilder) Secret(v string) *ProviderPatchBuilder { + b.patch["secret"] = v + return b +} + +func (b *ProviderPatchBuilder) Type(v string) *ProviderPatchBuilder { + b.patch["type"] = v + return b +} + +func (b *ProviderPatchBuilder) Build() map[string]any { + return b.patch +} diff --git a/components/ambient-sdk/go-sdk/types/role.go b/components/ambient-sdk/go-sdk/types/role.go index f1ba27725..62340a27b 100644 --- a/components/ambient-sdk/go-sdk/types/role.go +++ b/components/ambient-sdk/go-sdk/types/role.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package types diff --git a/components/ambient-sdk/go-sdk/types/role_binding.go b/components/ambient-sdk/go-sdk/types/role_binding.go index a74bf7fd5..a60f37aa1 100644 --- a/components/ambient-sdk/go-sdk/types/role_binding.go +++ b/components/ambient-sdk/go-sdk/types/role_binding.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package types diff --git a/components/ambient-sdk/go-sdk/types/scheduled_session.go b/components/ambient-sdk/go-sdk/types/scheduled_session.go index c3662d081..6832ace8d 100755 --- a/components/ambient-sdk/go-sdk/types/scheduled_session.go +++ b/components/ambient-sdk/go-sdk/types/scheduled_session.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package types diff --git a/components/ambient-sdk/go-sdk/types/session.go b/components/ambient-sdk/go-sdk/types/session.go index d372e67f0..438f298c2 100644 --- a/components/ambient-sdk/go-sdk/types/session.go +++ b/components/ambient-sdk/go-sdk/types/session.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package types diff --git a/components/ambient-sdk/go-sdk/types/session_message.go b/components/ambient-sdk/go-sdk/types/session_message.go index 910c65d02..3a6f65abe 100644 --- a/components/ambient-sdk/go-sdk/types/session_message.go +++ b/components/ambient-sdk/go-sdk/types/session_message.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package types diff --git a/components/ambient-sdk/go-sdk/types/user.go b/components/ambient-sdk/go-sdk/types/user.go index 2b55d6c7c..b3597d6ab 100644 --- a/components/ambient-sdk/go-sdk/types/user.go +++ b/components/ambient-sdk/go-sdk/types/user.go @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z package types diff --git a/components/ambient-sdk/python-sdk/ambient_platform/__init__.py b/components/ambient-sdk/python-sdk/ambient_platform/__init__.py index d9feb5911..619d2a934 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/__init__.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/__init__.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z """Ambient Platform SDK for Python.""" @@ -10,8 +10,10 @@ from .agent import Agent, AgentPatch from .credential import Credential, CredentialPatch from .inbox_message import InboxMessage, InboxMessagePatch +from .policy import Policy, PolicyPatch from .project import Project, ProjectPatch from .project_settings import ProjectSettings, ProjectSettingsPatch +from .provider import Provider, ProviderPatch from .role import Role, RolePatch from .role_binding import RoleBinding, RoleBindingPatch from .scheduled_session import ScheduledSession, ScheduledSessionPatch @@ -31,10 +33,14 @@ "CredentialPatch", "InboxMessage", "InboxMessagePatch", + "Policy", + "PolicyPatch", "Project", "ProjectPatch", "ProjectSettings", "ProjectSettingsPatch", + "Provider", + "ProviderPatch", "Role", "RolePatch", "RoleBinding", diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_agent_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_agent_api.py index b11c76a27..348210151 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_agent_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_agent_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_base.py b/components/ambient-sdk/python-sdk/ambient_platform/_base.py index 6abd0ca64..b1605f4d6 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_base.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_base.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_credential_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_credential_api.py index ebbffc094..bc5c7fe7b 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_credential_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_credential_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_inbox_message_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_inbox_message_api.py index 147afdbe4..fe675459b 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_inbox_message_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_inbox_message_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_iterator.py b/components/ambient-sdk/python-sdk/ambient_platform/_iterator.py index 797de6bd6..0d3b8e654 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_iterator.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_iterator.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_policy_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_policy_api.py new file mode 100644 index 000000000..3ea7752bb --- /dev/null +++ b/components/ambient-sdk/python-sdk/ambient_platform/_policy_api.py @@ -0,0 +1,52 @@ +# Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. +# Source: ../../ambient-api-server/openapi/openapi.yaml +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z + +from __future__ import annotations + +from typing import Any, Iterator, Optional, TYPE_CHECKING +from urllib.parse import quote + +from ._base import ListOptions +from .policy import Policy, PolicyList + +if TYPE_CHECKING: + from .client import AmbientClient + + +class PolicyAPI: + def __init__(self, client: AmbientClient) -> None: + self._client = client + def _base_path(self) -> str: + return "/projects/{id}/policies".replace("{id}", quote(self._client._project, safe="")) + + + def create(self, data: dict) -> Policy: + resp = self._client._request("POST", self._base_path(), json=data) + return Policy.from_dict(resp) + + def get(self, resource_id: str) -> Policy: + resp = self._client._request("GET", f"{self._base_path()}/{resource_id}") + return Policy.from_dict(resp) + + def list(self, opts: Optional[ListOptions] = None) -> PolicyList: + params = opts.to_params() if opts else None + resp = self._client._request("GET", self._base_path(), params=params) + return PolicyList.from_dict(resp) + def update(self, resource_id: str, patch: Any) -> Policy: + data = patch.to_dict() if hasattr(patch, "to_dict") else patch + resp = self._client._request("PATCH", f"{self._base_path()}/{resource_id}", json=data) + return Policy.from_dict(resp) + + def delete(self, resource_id: str) -> None: + self._client._request("DELETE", f"{self._base_path()}/{resource_id}", expect_json=False) + + def list_all(self, size: int = 100, **kwargs: Any) -> Iterator[Policy]: + page = 1 + while True: + result = self.list(ListOptions().page(page).size(size)) + yield from result.items + if page * size >= result.total: + break + page += 1 diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_project_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_project_api.py index d0adfbcbb..09f5fc183 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_project_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_project_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_project_settings_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_project_settings_api.py index 56b577960..509392cca 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_project_settings_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_project_settings_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_provider_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_provider_api.py new file mode 100644 index 000000000..bb6544418 --- /dev/null +++ b/components/ambient-sdk/python-sdk/ambient_platform/_provider_api.py @@ -0,0 +1,52 @@ +# Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. +# Source: ../../ambient-api-server/openapi/openapi.yaml +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z + +from __future__ import annotations + +from typing import Any, Iterator, Optional, TYPE_CHECKING +from urllib.parse import quote + +from ._base import ListOptions +from .provider import Provider, ProviderList + +if TYPE_CHECKING: + from .client import AmbientClient + + +class ProviderAPI: + def __init__(self, client: AmbientClient) -> None: + self._client = client + def _base_path(self) -> str: + return "/projects/{id}/providers".replace("{id}", quote(self._client._project, safe="")) + + + def create(self, data: dict) -> Provider: + resp = self._client._request("POST", self._base_path(), json=data) + return Provider.from_dict(resp) + + def get(self, resource_id: str) -> Provider: + resp = self._client._request("GET", f"{self._base_path()}/{resource_id}") + return Provider.from_dict(resp) + + def list(self, opts: Optional[ListOptions] = None) -> ProviderList: + params = opts.to_params() if opts else None + resp = self._client._request("GET", self._base_path(), params=params) + return ProviderList.from_dict(resp) + def update(self, resource_id: str, patch: Any) -> Provider: + data = patch.to_dict() if hasattr(patch, "to_dict") else patch + resp = self._client._request("PATCH", f"{self._base_path()}/{resource_id}", json=data) + return Provider.from_dict(resp) + + def delete(self, resource_id: str) -> None: + self._client._request("DELETE", f"{self._base_path()}/{resource_id}", expect_json=False) + + def list_all(self, size: int = 100, **kwargs: Any) -> Iterator[Provider]: + page = 1 + while True: + result = self.list(ListOptions().page(page).size(size)) + yield from result.items + if page * size >= result.total: + break + page += 1 diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_role_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_role_api.py index 3f37dee5d..96abd6418 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_role_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_role_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_role_binding_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_role_binding_api.py index f0ad32a91..cf683d611 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_role_binding_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_role_binding_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_scheduled_session_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_scheduled_session_api.py index e2573a6ea..36a2ffa20 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_scheduled_session_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_scheduled_session_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_session_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_session_api.py index 1dff17419..95647e6c8 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_session_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_session_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_session_message_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_session_message_api.py index 7d76b6ec0..698aa9969 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_session_message_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_session_message_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/_user_api.py b/components/ambient-sdk/python-sdk/ambient_platform/_user_api.py index a8d0c8cbd..002318744 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/_user_api.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/_user_api.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/agent.py b/components/ambient-sdk/python-sdk/ambient_platform/agent.py index 26af56962..36e555340 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/agent.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/agent.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/client.py b/components/ambient-sdk/python-sdk/ambient_platform/client.py index 95ec0201e..cc7c603d4 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/client.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/client.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations @@ -19,8 +19,10 @@ from ._agent_api import AgentAPI from ._credential_api import CredentialAPI from ._inbox_message_api import InboxMessageAPI + from ._policy_api import PolicyAPI from ._project_api import ProjectAPI from ._project_settings_api import ProjectSettingsAPI + from ._provider_api import ProviderAPI from ._role_api import RoleAPI from ._role_binding_api import RoleBindingAPI from ._scheduled_session_api import ScheduledSessionAPI @@ -63,8 +65,10 @@ def __init__( self._agent_api: Optional[AgentAPI] = None self._credential_api: Optional[CredentialAPI] = None self._inbox_message_api: Optional[InboxMessageAPI] = None + self._policy_api: Optional[PolicyAPI] = None self._project_api: Optional[ProjectAPI] = None self._project_settings_api: Optional[ProjectSettingsAPI] = None + self._provider_api: Optional[ProviderAPI] = None self._role_api: Optional[RoleAPI] = None self._role_binding_api: Optional[RoleBindingAPI] = None self._scheduled_session_api: Optional[ScheduledSessionAPI] = None @@ -206,6 +210,13 @@ def inbox_messages(self) -> InboxMessageAPI: self._inbox_message_api = InboxMessageAPI(self) return self._inbox_message_api @property + def policies(self) -> PolicyAPI: + """Get the Policy API interface.""" + if self._policy_api is None: + from ._policy_api import PolicyAPI + self._policy_api = PolicyAPI(self) + return self._policy_api + @property def projects(self) -> ProjectAPI: """Get the Project API interface.""" if self._project_api is None: @@ -220,6 +231,13 @@ def project_settings(self) -> ProjectSettingsAPI: self._project_settings_api = ProjectSettingsAPI(self) return self._project_settings_api @property + def providers(self) -> ProviderAPI: + """Get the Provider API interface.""" + if self._provider_api is None: + from ._provider_api import ProviderAPI + self._provider_api = ProviderAPI(self) + return self._provider_api + @property def roles(self) -> RoleAPI: """Get the Role API interface.""" if self._role_api is None: diff --git a/components/ambient-sdk/python-sdk/ambient_platform/credential.py b/components/ambient-sdk/python-sdk/ambient_platform/credential.py index 1e096cfdf..d6464f7a4 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/credential.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/credential.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/inbox_message.py b/components/ambient-sdk/python-sdk/ambient_platform/inbox_message.py index 567d2e1ad..f6dea4475 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/inbox_message.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/inbox_message.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/policy.py b/components/ambient-sdk/python-sdk/ambient_platform/policy.py new file mode 100644 index 000000000..2e6cf6fb2 --- /dev/null +++ b/components/ambient-sdk/python-sdk/ambient_platform/policy.py @@ -0,0 +1,132 @@ +# Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. +# Source: ../../ambient-api-server/openapi/openapi.yaml +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z + +from __future__ import annotations + +from dataclasses import dataclass +from datetime import datetime +from typing import Any, Optional + +from ._base import ListMeta, _parse_datetime + + +@dataclass(frozen=True) +class Policy: + id: str = "" + kind: str = "" + href: str = "" + created_at: Optional[datetime] = None + updated_at: Optional[datetime] = None + annotations: str = "" + labels: str = "" + name: str = "" + namespace: str = "" + project_id: str = "" + spec: str = "" + + @classmethod + def from_dict(cls, data: dict) -> Policy: + return cls( + id=data.get("id", ""), + kind=data.get("kind", ""), + href=data.get("href", ""), + created_at=_parse_datetime(data.get("created_at")), + updated_at=_parse_datetime(data.get("updated_at")), + annotations=data.get("annotations", ""), + labels=data.get("labels", ""), + name=data.get("name", ""), + namespace=data.get("namespace", ""), + project_id=data.get("project_id", ""), + spec=data.get("spec", ""), + ) + + @classmethod + def builder(cls) -> PolicyBuilder: + return PolicyBuilder() + + +@dataclass(frozen=True) +class PolicyList: + kind: str = "" + page: int = 0 + size: int = 0 + total: int = 0 + items: list[Policy] = () + + @classmethod + def from_dict(cls, data: dict) -> PolicyList: + return cls( + kind=data.get("kind", ""), + page=data.get("page", 0), + size=data.get("size", 0), + total=data.get("total", 0), + items=[Policy.from_dict(item) for item in data.get("items", [])], + ) + + +class PolicyBuilder: + def __init__(self) -> None: + self._data: dict[str, Any] = {} + + + def annotations(self, value: str) -> PolicyBuilder: + self._data["annotations"] = value + return self + + def labels(self, value: str) -> PolicyBuilder: + self._data["labels"] = value + return self + + def name(self, value: str) -> PolicyBuilder: + self._data["name"] = value + return self + + def namespace(self, value: str) -> PolicyBuilder: + self._data["namespace"] = value + return self + + def project_id(self, value: str) -> PolicyBuilder: + self._data["project_id"] = value + return self + + def spec(self, value: str) -> PolicyBuilder: + self._data["spec"] = value + return self + + def build(self) -> dict: + if "name" not in self._data: + raise ValueError("name is required") + if "project_id" not in self._data: + raise ValueError("project_id is required") + return dict(self._data) + + +class PolicyPatch: + def __init__(self) -> None: + self._data: dict[str, Any] = {} + + + def annotations(self, value: str) -> PolicyPatch: + self._data["annotations"] = value + return self + + def labels(self, value: str) -> PolicyPatch: + self._data["labels"] = value + return self + + def name(self, value: str) -> PolicyPatch: + self._data["name"] = value + return self + + def namespace(self, value: str) -> PolicyPatch: + self._data["namespace"] = value + return self + + def spec(self, value: str) -> PolicyPatch: + self._data["spec"] = value + return self + + def to_dict(self) -> dict: + return dict(self._data) diff --git a/components/ambient-sdk/python-sdk/ambient_platform/project.py b/components/ambient-sdk/python-sdk/ambient_platform/project.py index 912b83bad..487d09c90 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/project.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/project.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/project_settings.py b/components/ambient-sdk/python-sdk/ambient_platform/project_settings.py index 1c5021ece..788dd453f 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/project_settings.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/project_settings.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/provider.py b/components/ambient-sdk/python-sdk/ambient_platform/provider.py new file mode 100644 index 000000000..223966be5 --- /dev/null +++ b/components/ambient-sdk/python-sdk/ambient_platform/provider.py @@ -0,0 +1,142 @@ +# Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. +# Source: ../../ambient-api-server/openapi/openapi.yaml +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z + +from __future__ import annotations + +from dataclasses import dataclass +from datetime import datetime +from typing import Any, Optional + +from ._base import ListMeta, _parse_datetime + + +@dataclass(frozen=True) +class Provider: + id: str = "" + kind: str = "" + href: str = "" + created_at: Optional[datetime] = None + updated_at: Optional[datetime] = None + annotations: str = "" + labels: str = "" + name: str = "" + namespace: str = "" + project_id: str = "" + secret: str = "" + type: str = "" + + @classmethod + def from_dict(cls, data: dict) -> Provider: + return cls( + id=data.get("id", ""), + kind=data.get("kind", ""), + href=data.get("href", ""), + created_at=_parse_datetime(data.get("created_at")), + updated_at=_parse_datetime(data.get("updated_at")), + annotations=data.get("annotations", ""), + labels=data.get("labels", ""), + name=data.get("name", ""), + namespace=data.get("namespace", ""), + project_id=data.get("project_id", ""), + secret=data.get("secret", ""), + type=data.get("type", ""), + ) + + @classmethod + def builder(cls) -> ProviderBuilder: + return ProviderBuilder() + + +@dataclass(frozen=True) +class ProviderList: + kind: str = "" + page: int = 0 + size: int = 0 + total: int = 0 + items: list[Provider] = () + + @classmethod + def from_dict(cls, data: dict) -> ProviderList: + return cls( + kind=data.get("kind", ""), + page=data.get("page", 0), + size=data.get("size", 0), + total=data.get("total", 0), + items=[Provider.from_dict(item) for item in data.get("items", [])], + ) + + +class ProviderBuilder: + def __init__(self) -> None: + self._data: dict[str, Any] = {} + + + def annotations(self, value: str) -> ProviderBuilder: + self._data["annotations"] = value + return self + + def labels(self, value: str) -> ProviderBuilder: + self._data["labels"] = value + return self + + def name(self, value: str) -> ProviderBuilder: + self._data["name"] = value + return self + + def namespace(self, value: str) -> ProviderBuilder: + self._data["namespace"] = value + return self + + def project_id(self, value: str) -> ProviderBuilder: + self._data["project_id"] = value + return self + + def secret(self, value: str) -> ProviderBuilder: + self._data["secret"] = value + return self + + def type(self, value: str) -> ProviderBuilder: + self._data["type"] = value + return self + + def build(self) -> dict: + if "name" not in self._data: + raise ValueError("name is required") + if "project_id" not in self._data: + raise ValueError("project_id is required") + return dict(self._data) + + +class ProviderPatch: + def __init__(self) -> None: + self._data: dict[str, Any] = {} + + + def annotations(self, value: str) -> ProviderPatch: + self._data["annotations"] = value + return self + + def labels(self, value: str) -> ProviderPatch: + self._data["labels"] = value + return self + + def name(self, value: str) -> ProviderPatch: + self._data["name"] = value + return self + + def namespace(self, value: str) -> ProviderPatch: + self._data["namespace"] = value + return self + + def secret(self, value: str) -> ProviderPatch: + self._data["secret"] = value + return self + + def type(self, value: str) -> ProviderPatch: + self._data["type"] = value + return self + + def to_dict(self) -> dict: + return dict(self._data) diff --git a/components/ambient-sdk/python-sdk/ambient_platform/role.py b/components/ambient-sdk/python-sdk/ambient_platform/role.py index c57045bd1..c6dc70e46 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/role.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/role.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/role_binding.py b/components/ambient-sdk/python-sdk/ambient_platform/role_binding.py index 0f603e17f..982c614f2 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/role_binding.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/role_binding.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/scheduled_session.py b/components/ambient-sdk/python-sdk/ambient_platform/scheduled_session.py index fc009b6a1..fad851a2e 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/scheduled_session.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/scheduled_session.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/session.py b/components/ambient-sdk/python-sdk/ambient_platform/session.py index db8b5221e..db61226a7 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/session.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/session.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/session_message.py b/components/ambient-sdk/python-sdk/ambient_platform/session_message.py index 9b1bc55d8..ce72d30c4 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/session_message.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/session_message.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/python-sdk/ambient_platform/user.py b/components/ambient-sdk/python-sdk/ambient_platform/user.py index 50808e7ed..29bfcf061 100644 --- a/components/ambient-sdk/python-sdk/ambient_platform/user.py +++ b/components/ambient-sdk/python-sdk/ambient_platform/user.py @@ -1,7 +1,7 @@ # Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. # Source: ../../ambient-api-server/openapi/openapi.yaml -# Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -# Generated: 2026-06-29T17:10:10Z +# Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +# Generated: 2026-06-29T20:10:29Z from __future__ import annotations diff --git a/components/ambient-sdk/ts-sdk/src/agent.ts b/components/ambient-sdk/ts-sdk/src/agent.ts index 68812f4d3..3f16dadcd 100644 --- a/components/ambient-sdk/ts-sdk/src/agent.ts +++ b/components/ambient-sdk/ts-sdk/src/agent.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/agent_api.ts b/components/ambient-sdk/ts-sdk/src/agent_api.ts index 290e199f6..dc97a091b 100644 --- a/components/ambient-sdk/ts-sdk/src/agent_api.ts +++ b/components/ambient-sdk/ts-sdk/src/agent_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/base.ts b/components/ambient-sdk/ts-sdk/src/base.ts index f6d083717..4adfbe6e4 100644 --- a/components/ambient-sdk/ts-sdk/src/base.ts +++ b/components/ambient-sdk/ts-sdk/src/base.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z export type ObjectReference = { id: string; diff --git a/components/ambient-sdk/ts-sdk/src/client.ts b/components/ambient-sdk/ts-sdk/src/client.ts index 4c80859f1..dd3d8ed80 100644 --- a/components/ambient-sdk/ts-sdk/src/client.ts +++ b/components/ambient-sdk/ts-sdk/src/client.ts @@ -1,14 +1,16 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { AmbientClientConfig } from './base'; import { AgentAPI } from './agent_api'; import { CredentialAPI } from './credential_api'; import { InboxMessageAPI } from './inbox_message_api'; +import { PolicyAPI } from './policy_api'; import { ProjectAPI } from './project_api'; import { ProjectSettingsAPI } from './project_settings_api'; +import { ProviderAPI } from './provider_api'; import { RoleAPI } from './role_api'; import { RoleBindingAPI } from './role_binding_api'; import { ScheduledSessionAPI } from './scheduled_session_api'; @@ -23,8 +25,10 @@ export class AmbientClient { readonly agents: AgentAPI; readonly credentials: CredentialAPI; readonly inboxMessages: InboxMessageAPI; + readonly policys: PolicyAPI; readonly projects: ProjectAPI; readonly projectSettings: ProjectSettingsAPI; + readonly providers: ProviderAPI; readonly roles: RoleAPI; readonly roleBindings: RoleBindingAPI; readonly scheduledSessions: ScheduledSessionAPI; @@ -69,8 +73,10 @@ export class AmbientClient { this.agents = new AgentAPI(this.config); this.credentials = new CredentialAPI(this.config); this.inboxMessages = new InboxMessageAPI(this.config); + this.policys = new PolicyAPI(this.config); this.projects = new ProjectAPI(this.config); this.projectSettings = new ProjectSettingsAPI(this.config); + this.providers = new ProviderAPI(this.config); this.roles = new RoleAPI(this.config); this.roleBindings = new RoleBindingAPI(this.config); this.scheduledSessions = new ScheduledSessionAPI(this.config); diff --git a/components/ambient-sdk/ts-sdk/src/credential.ts b/components/ambient-sdk/ts-sdk/src/credential.ts index 0575e2c31..94c3783c5 100644 --- a/components/ambient-sdk/ts-sdk/src/credential.ts +++ b/components/ambient-sdk/ts-sdk/src/credential.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/credential_api.ts b/components/ambient-sdk/ts-sdk/src/credential_api.ts index 1c559917d..5a16b3c6a 100644 --- a/components/ambient-sdk/ts-sdk/src/credential_api.ts +++ b/components/ambient-sdk/ts-sdk/src/credential_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/inbox_message.ts b/components/ambient-sdk/ts-sdk/src/inbox_message.ts index 9bf17f27a..3c59bd313 100644 --- a/components/ambient-sdk/ts-sdk/src/inbox_message.ts +++ b/components/ambient-sdk/ts-sdk/src/inbox_message.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/inbox_message_api.ts b/components/ambient-sdk/ts-sdk/src/inbox_message_api.ts index 88c12286b..b54fbc144 100644 --- a/components/ambient-sdk/ts-sdk/src/inbox_message_api.ts +++ b/components/ambient-sdk/ts-sdk/src/inbox_message_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/index.ts b/components/ambient-sdk/ts-sdk/src/index.ts index 54f7b7370..5bce87ff3 100644 --- a/components/ambient-sdk/ts-sdk/src/index.ts +++ b/components/ambient-sdk/ts-sdk/src/index.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z export { AmbientClient } from './client'; export type { AmbientClientConfig, ListOptions, RequestOptions, ObjectReference, ListMeta, APIError } from './base'; @@ -19,6 +19,10 @@ export type { InboxMessage, InboxMessageList, InboxMessageCreateRequest, InboxMe export { InboxMessageBuilder, InboxMessagePatchBuilder } from './inbox_message'; export { InboxMessageAPI } from './inbox_message_api'; +export type { Policy, PolicyList, PolicyCreateRequest, PolicyPatchRequest } from './policy'; +export { PolicyBuilder, PolicyPatchBuilder } from './policy'; +export { PolicyAPI } from './policy_api'; + export type { Project, ProjectList, ProjectCreateRequest, ProjectPatchRequest } from './project'; export { ProjectBuilder, ProjectPatchBuilder } from './project'; export { ProjectAPI } from './project_api'; @@ -27,6 +31,10 @@ export type { ProjectSettings, ProjectSettingsList, ProjectSettingsCreateRequest export { ProjectSettingsBuilder, ProjectSettingsPatchBuilder } from './project_settings'; export { ProjectSettingsAPI } from './project_settings_api'; +export type { Provider, ProviderList, ProviderCreateRequest, ProviderPatchRequest } from './provider'; +export { ProviderBuilder, ProviderPatchBuilder } from './provider'; +export { ProviderAPI } from './provider_api'; + export type { Role, RoleList, RoleCreateRequest, RolePatchRequest } from './role'; export { RoleBuilder, RolePatchBuilder } from './role'; export { RoleAPI } from './role_api'; diff --git a/components/ambient-sdk/ts-sdk/src/policy.ts b/components/ambient-sdk/ts-sdk/src/policy.ts new file mode 100644 index 000000000..d1e188411 --- /dev/null +++ b/components/ambient-sdk/ts-sdk/src/policy.ts @@ -0,0 +1,115 @@ +// Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. +// Source: ../../ambient-api-server/openapi/openapi.yaml +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z + +import type { ObjectReference, ListMeta } from './base'; + +export type Policy = ObjectReference & { + annotations: string; + labels: string; + name: string; + namespace: string; + project_id: string; + spec: string; +}; + +export type PolicyList = ListMeta & { + items: Policy[]; +}; + +export type PolicyCreateRequest = { + annotations?: string; + labels?: string; + name: string; + namespace?: string; + project_id: string; + spec?: string; +}; + +export type PolicyPatchRequest = { + annotations?: string; + labels?: string; + name?: string; + namespace?: string; + spec?: string; +}; + +export class PolicyBuilder { + private data: Record = {}; + + + annotations(value: string): this { + this.data['annotations'] = value; + return this; + } + + labels(value: string): this { + this.data['labels'] = value; + return this; + } + + name(value: string): this { + this.data['name'] = value; + return this; + } + + namespace(value: string): this { + this.data['namespace'] = value; + return this; + } + + projectId(value: string): this { + this.data['project_id'] = value; + return this; + } + + spec(value: string): this { + this.data['spec'] = value; + return this; + } + + build(): PolicyCreateRequest { + if (!this.data['name']) { + throw new Error('name is required'); + } + if (!this.data['project_id']) { + throw new Error('project_id is required'); + } + return this.data as PolicyCreateRequest; + } +} + +export class PolicyPatchBuilder { + private data: Record = {}; + + + annotations(value: string): this { + this.data['annotations'] = value; + return this; + } + + labels(value: string): this { + this.data['labels'] = value; + return this; + } + + name(value: string): this { + this.data['name'] = value; + return this; + } + + namespace(value: string): this { + this.data['namespace'] = value; + return this; + } + + spec(value: string): this { + this.data['spec'] = value; + return this; + } + + build(): PolicyPatchRequest { + return this.data as PolicyPatchRequest; + } +} diff --git a/components/ambient-sdk/ts-sdk/src/policy_api.ts b/components/ambient-sdk/ts-sdk/src/policy_api.ts new file mode 100644 index 000000000..64b73b193 --- /dev/null +++ b/components/ambient-sdk/ts-sdk/src/policy_api.ts @@ -0,0 +1,53 @@ +// Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. +// Source: ../../ambient-api-server/openapi/openapi.yaml +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z + +import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; +import { ambientFetch, buildQueryString } from './base'; +import type { Policy, PolicyList, PolicyCreateRequest, PolicyPatchRequest } from './policy'; + +export class PolicyAPI { + constructor(private readonly config: AmbientClientConfig) {} + private basePath(): string { + if (!this.config.project) { + throw new Error('project is required for Policy operations'); + } + return '/projects/{id}/policies'.replace('{id}', encodeURIComponent(this.config.project)); + } + + + async create(data: PolicyCreateRequest, opts?: RequestOptions): Promise { + return ambientFetch(this.config, 'POST', this.basePath(), data, opts); + } + + async get(id: string, opts?: RequestOptions): Promise { + return ambientFetch(this.config, 'GET', `${this.basePath()}/${id}`, undefined, opts); + } + + async list(listOpts?: ListOptions, opts?: RequestOptions): Promise { + const qs = buildQueryString(listOpts); + return ambientFetch(this.config, 'GET', `${this.basePath()}${qs}`, undefined, opts); + } + async update(id: string, patch: PolicyPatchRequest, opts?: RequestOptions): Promise { + return ambientFetch(this.config, 'PATCH', `${this.basePath()}/${id}`, patch, opts); + } + + async delete(id: string, opts?: RequestOptions): Promise { + return ambientFetch(this.config, 'DELETE', `${this.basePath()}/${id}`, undefined, opts); + } + + async *listAll(size: number = 100, opts?: RequestOptions): AsyncGenerator { + let page = 1; + while (true) { + const result = await this.list({ page, size }, opts); + for (const item of result.items) { + yield item; + } + if (page * size >= result.total) { + break; + } + page++; + } + } +} diff --git a/components/ambient-sdk/ts-sdk/src/project.ts b/components/ambient-sdk/ts-sdk/src/project.ts index 0b566ca2d..872bc4040 100644 --- a/components/ambient-sdk/ts-sdk/src/project.ts +++ b/components/ambient-sdk/ts-sdk/src/project.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/project_api.ts b/components/ambient-sdk/ts-sdk/src/project_api.ts index 843cd3e5d..843899f03 100644 --- a/components/ambient-sdk/ts-sdk/src/project_api.ts +++ b/components/ambient-sdk/ts-sdk/src/project_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/project_settings.ts b/components/ambient-sdk/ts-sdk/src/project_settings.ts index 0ffd2326d..8ee803ffe 100644 --- a/components/ambient-sdk/ts-sdk/src/project_settings.ts +++ b/components/ambient-sdk/ts-sdk/src/project_settings.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/project_settings_api.ts b/components/ambient-sdk/ts-sdk/src/project_settings_api.ts index 46ed0d40b..84ada0dd7 100644 --- a/components/ambient-sdk/ts-sdk/src/project_settings_api.ts +++ b/components/ambient-sdk/ts-sdk/src/project_settings_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/provider.ts b/components/ambient-sdk/ts-sdk/src/provider.ts new file mode 100644 index 000000000..b1168560a --- /dev/null +++ b/components/ambient-sdk/ts-sdk/src/provider.ts @@ -0,0 +1,128 @@ +// Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. +// Source: ../../ambient-api-server/openapi/openapi.yaml +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z + +import type { ObjectReference, ListMeta } from './base'; + +export type Provider = ObjectReference & { + annotations: string; + labels: string; + name: string; + namespace: string; + project_id: string; + secret: string; + type: string; +}; + +export type ProviderList = ListMeta & { + items: Provider[]; +}; + +export type ProviderCreateRequest = { + annotations?: string; + labels?: string; + name: string; + namespace?: string; + project_id: string; + secret?: string; + type?: string; +}; + +export type ProviderPatchRequest = { + annotations?: string; + labels?: string; + name?: string; + namespace?: string; + secret?: string; + type?: string; +}; + +export class ProviderBuilder { + private data: Record = {}; + + + annotations(value: string): this { + this.data['annotations'] = value; + return this; + } + + labels(value: string): this { + this.data['labels'] = value; + return this; + } + + name(value: string): this { + this.data['name'] = value; + return this; + } + + namespace(value: string): this { + this.data['namespace'] = value; + return this; + } + + projectId(value: string): this { + this.data['project_id'] = value; + return this; + } + + secret(value: string): this { + this.data['secret'] = value; + return this; + } + + type(value: string): this { + this.data['type'] = value; + return this; + } + + build(): ProviderCreateRequest { + if (!this.data['name']) { + throw new Error('name is required'); + } + if (!this.data['project_id']) { + throw new Error('project_id is required'); + } + return this.data as ProviderCreateRequest; + } +} + +export class ProviderPatchBuilder { + private data: Record = {}; + + + annotations(value: string): this { + this.data['annotations'] = value; + return this; + } + + labels(value: string): this { + this.data['labels'] = value; + return this; + } + + name(value: string): this { + this.data['name'] = value; + return this; + } + + namespace(value: string): this { + this.data['namespace'] = value; + return this; + } + + secret(value: string): this { + this.data['secret'] = value; + return this; + } + + type(value: string): this { + this.data['type'] = value; + return this; + } + + build(): ProviderPatchRequest { + return this.data as ProviderPatchRequest; + } +} diff --git a/components/ambient-sdk/ts-sdk/src/provider_api.ts b/components/ambient-sdk/ts-sdk/src/provider_api.ts new file mode 100644 index 000000000..48b1e5f7e --- /dev/null +++ b/components/ambient-sdk/ts-sdk/src/provider_api.ts @@ -0,0 +1,53 @@ +// Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. +// Source: ../../ambient-api-server/openapi/openapi.yaml +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z + +import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; +import { ambientFetch, buildQueryString } from './base'; +import type { Provider, ProviderList, ProviderCreateRequest, ProviderPatchRequest } from './provider'; + +export class ProviderAPI { + constructor(private readonly config: AmbientClientConfig) {} + private basePath(): string { + if (!this.config.project) { + throw new Error('project is required for Provider operations'); + } + return '/projects/{id}/providers'.replace('{id}', encodeURIComponent(this.config.project)); + } + + + async create(data: ProviderCreateRequest, opts?: RequestOptions): Promise { + return ambientFetch(this.config, 'POST', this.basePath(), data, opts); + } + + async get(id: string, opts?: RequestOptions): Promise { + return ambientFetch(this.config, 'GET', `${this.basePath()}/${id}`, undefined, opts); + } + + async list(listOpts?: ListOptions, opts?: RequestOptions): Promise { + const qs = buildQueryString(listOpts); + return ambientFetch(this.config, 'GET', `${this.basePath()}${qs}`, undefined, opts); + } + async update(id: string, patch: ProviderPatchRequest, opts?: RequestOptions): Promise { + return ambientFetch(this.config, 'PATCH', `${this.basePath()}/${id}`, patch, opts); + } + + async delete(id: string, opts?: RequestOptions): Promise { + return ambientFetch(this.config, 'DELETE', `${this.basePath()}/${id}`, undefined, opts); + } + + async *listAll(size: number = 100, opts?: RequestOptions): AsyncGenerator { + let page = 1; + while (true) { + const result = await this.list({ page, size }, opts); + for (const item of result.items) { + yield item; + } + if (page * size >= result.total) { + break; + } + page++; + } + } +} diff --git a/components/ambient-sdk/ts-sdk/src/role.ts b/components/ambient-sdk/ts-sdk/src/role.ts index 8a53eae18..77acf4c43 100644 --- a/components/ambient-sdk/ts-sdk/src/role.ts +++ b/components/ambient-sdk/ts-sdk/src/role.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/role_api.ts b/components/ambient-sdk/ts-sdk/src/role_api.ts index 3a2d1b943..6ede6163d 100644 --- a/components/ambient-sdk/ts-sdk/src/role_api.ts +++ b/components/ambient-sdk/ts-sdk/src/role_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/role_binding.ts b/components/ambient-sdk/ts-sdk/src/role_binding.ts index 20dac0678..08c58c2b5 100644 --- a/components/ambient-sdk/ts-sdk/src/role_binding.ts +++ b/components/ambient-sdk/ts-sdk/src/role_binding.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/role_binding_api.ts b/components/ambient-sdk/ts-sdk/src/role_binding_api.ts index 16eb0b1ba..565f72b89 100644 --- a/components/ambient-sdk/ts-sdk/src/role_binding_api.ts +++ b/components/ambient-sdk/ts-sdk/src/role_binding_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/scheduled_session.ts b/components/ambient-sdk/ts-sdk/src/scheduled_session.ts index 4668c846f..dfa9313c5 100644 --- a/components/ambient-sdk/ts-sdk/src/scheduled_session.ts +++ b/components/ambient-sdk/ts-sdk/src/scheduled_session.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/scheduled_session_api.ts b/components/ambient-sdk/ts-sdk/src/scheduled_session_api.ts index f01193353..87dfda52a 100644 --- a/components/ambient-sdk/ts-sdk/src/scheduled_session_api.ts +++ b/components/ambient-sdk/ts-sdk/src/scheduled_session_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/session.ts b/components/ambient-sdk/ts-sdk/src/session.ts index a5294b4be..0b5577dfc 100644 --- a/components/ambient-sdk/ts-sdk/src/session.ts +++ b/components/ambient-sdk/ts-sdk/src/session.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/session_api.ts b/components/ambient-sdk/ts-sdk/src/session_api.ts index ecac21a4a..0d9472f09 100644 --- a/components/ambient-sdk/ts-sdk/src/session_api.ts +++ b/components/ambient-sdk/ts-sdk/src/session_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/session_message.ts b/components/ambient-sdk/ts-sdk/src/session_message.ts index fbda3ef3e..7a6cef05b 100644 --- a/components/ambient-sdk/ts-sdk/src/session_message.ts +++ b/components/ambient-sdk/ts-sdk/src/session_message.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/session_message_api.ts b/components/ambient-sdk/ts-sdk/src/session_message_api.ts index 2f42928d1..31ae38c5a 100644 --- a/components/ambient-sdk/ts-sdk/src/session_message_api.ts +++ b/components/ambient-sdk/ts-sdk/src/session_message_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/user.ts b/components/ambient-sdk/ts-sdk/src/user.ts index 89bf4f008..63e6e52fa 100644 --- a/components/ambient-sdk/ts-sdk/src/user.ts +++ b/components/ambient-sdk/ts-sdk/src/user.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { ObjectReference, ListMeta } from './base'; diff --git a/components/ambient-sdk/ts-sdk/src/user_api.ts b/components/ambient-sdk/ts-sdk/src/user_api.ts index fd9b1685d..dcb1e2342 100644 --- a/components/ambient-sdk/ts-sdk/src/user_api.ts +++ b/components/ambient-sdk/ts-sdk/src/user_api.ts @@ -1,7 +1,7 @@ // Code generated by ambient-sdk-generator from openapi.yaml — DO NOT EDIT. // Source: ../../ambient-api-server/openapi/openapi.yaml -// Spec SHA256: 7ea37f5208cc0fc8e16933941e91c7a85bf61e94b0e4f7c8b1d4de918122a5a1 -// Generated: 2026-06-29T17:10:10Z +// Spec SHA256: ed0a896aa0e4678be21149b07fe658b66ddc41e3d4b41b372e8cf6377e8c927e +// Generated: 2026-06-29T20:10:29Z import type { AmbientClientConfig, ListOptions, RequestOptions } from './base'; import { ambientFetch, buildQueryString } from './base'; diff --git a/components/ambient-ui/Dockerfile b/components/ambient-ui/Dockerfile index f27d1e7a4..0d943f8fe 100644 --- a/components/ambient-ui/Dockerfile +++ b/components/ambient-ui/Dockerfile @@ -35,6 +35,9 @@ ENV NEXT_TELEMETRY_DISABLED=1 ARG GIT_COMMIT=unknown ENV NEXT_PUBLIC_GIT_COMMIT=$GIT_COMMIT +ARG OPENSHELL_USE_GATEWAY=false +ENV NEXT_PUBLIC_OPENSHELL_USE_GATEWAY=$OPENSHELL_USE_GATEWAY + RUN npm run build # Prepare standalone output with OpenShift-compatible permissions in the builder diff --git a/components/ambient-ui/src/adapters/index.ts b/components/ambient-ui/src/adapters/index.ts index ffbc9cece..56e512b76 100644 --- a/components/ambient-ui/src/adapters/index.ts +++ b/components/ambient-ui/src/adapters/index.ts @@ -4,3 +4,5 @@ export { createProjectsAdapter } from './sdk-projects' export { createSessionMessagesAdapterWithFetch } from './session-messages' export { createCredentialsAdapter } from './sdk-credentials' export { createRoleBindingsAdapter } from './sdk-role-bindings' +export { createProvidersAdapter } from './sdk-providers' +export { createPoliciesAdapter } from './sdk-policies' diff --git a/components/ambient-ui/src/adapters/mappers.ts b/components/ambient-ui/src/adapters/mappers.ts index db7d21677..76ee28fa0 100644 --- a/components/ambient-ui/src/adapters/mappers.ts +++ b/components/ambient-ui/src/adapters/mappers.ts @@ -22,50 +22,60 @@ function parsePhase(raw: string): SessionPhase { return 'Pending' } -function parseAnnotations(raw: string): Record { +function parseAnnotations(raw: string | Record | unknown): Record { if (!raw) { return {} } - try { - const parsed: unknown = JSON.parse(raw) - if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) { - const result: Record = {} - for (const [key, value] of Object.entries(parsed as Record)) { - result[key] = String(value) - } - return result + let obj: unknown = raw + if (typeof raw === 'string') { + try { + obj = JSON.parse(raw) + } catch { + return {} } - return {} - } catch { - return {} } + if (typeof obj === 'object' && obj !== null && !Array.isArray(obj)) { + const result: Record = {} + for (const [key, value] of Object.entries(obj as Record)) { + result[key] = String(value) + } + return result + } + return {} } -function parseJsonArray(raw: string): unknown[] { +function parseJsonArray(raw: string | unknown[] | unknown): unknown[] { if (!raw) return [] - try { - const parsed: unknown = JSON.parse(raw) - return Array.isArray(parsed) ? parsed : [] - } catch { - return [] + if (Array.isArray(raw)) return raw + if (typeof raw === 'string') { + try { + const parsed: unknown = JSON.parse(raw) + return Array.isArray(parsed) ? parsed : [] + } catch { + return [] + } } + return [] } -function parseJsonObject(raw: string): Record { +function parseJsonObject(raw: string | Record | unknown): Record { if (!raw) return {} - try { - const parsed: unknown = JSON.parse(raw) - if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) { - const result: Record = {} - for (const [key, value] of Object.entries(parsed as Record)) { - result[key] = String(value) - } - return result + let obj: unknown = raw + if (typeof raw === 'string') { + try { + obj = JSON.parse(raw) + } catch { + return {} } - return {} - } catch { - return {} } + if (typeof obj === 'object' && obj !== null && !Array.isArray(obj)) { + const result: Record = {} + for (const [key, value] of Object.entries(obj as Record)) { + result[key] = String(value) + } + return result + } + return {} } const VALID_REPO_STATUSES: ReadonlySet = new Set(['Cloning', 'Ready', 'Failed']) @@ -169,46 +179,62 @@ export function mapSdkProjectToDomain(sdk: Project): DomainProject { } } -function parseProviders(raw: string): string[] { +function parseProviders(raw: string | string[] | unknown): string[] { if (!raw) return [] - try { - const parsed: unknown = JSON.parse(raw) - if (Array.isArray(parsed)) { - return parsed.filter((v): v is string => typeof v === 'string') + if (Array.isArray(raw)) { + return raw.filter((v): v is string => typeof v === 'string') + } + if (typeof raw === 'string') { + try { + const parsed: unknown = JSON.parse(raw) + if (Array.isArray(parsed)) { + return parsed.filter((v): v is string => typeof v === 'string') + } + return [] + } catch { + return [] } - return [] - } catch { - return [] } + return [] } -function parsePayloads(raw: string): DomainPayload[] { +function parsePayloads(raw: string | unknown[] | unknown): DomainPayload[] { if (!raw) return [] - try { - const parsed: unknown = JSON.parse(raw) - if (!Array.isArray(parsed)) return [] - return parsed - .filter((v): v is Record => typeof v === 'object' && v !== null) - .map((v) => ({ - sandbox_path: String(v.sandbox_path ?? ''), - ...(v.content ? { content: String(v.content) } : {}), - ...(v.repo_url ? { repo_url: String(v.repo_url) } : {}), - ...(v.ref ? { ref: String(v.ref) } : {}), - })) - } catch { + let arr: unknown + if (Array.isArray(raw)) { + arr = raw + } else if (typeof raw === 'string') { + try { + arr = JSON.parse(raw) + } catch { + return [] + } + } else { return [] } + if (!Array.isArray(arr)) return [] + return arr + .filter((v): v is Record => typeof v === 'object' && v !== null) + .map((v) => ({ + sandbox_path: String(v.sandbox_path ?? ''), + ...(v.content ? { content: String(v.content) } : {}), + ...(v.repo_url ? { repo_url: String(v.repo_url) } : {}), + ...(v.ref ? { ref: String(v.ref) } : {}), + })) } -function parseSandboxTemplate(raw: string): DomainSandboxTemplate | null { +function parseSandboxTemplate(raw: string | Record | unknown): DomainSandboxTemplate | null { if (!raw) return null - try { - const parsed: unknown = JSON.parse(raw) - if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) return null - return parsed as DomainSandboxTemplate - } catch { - return null + let obj: unknown = raw + if (typeof raw === 'string') { + try { + obj = JSON.parse(raw) + } catch { + return null + } } + if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) return null + return obj as DomainSandboxTemplate } export function mapSdkAgentToDomain(sdk: Agent): DomainAgent { diff --git a/components/ambient-ui/src/adapters/sdk-policies.ts b/components/ambient-ui/src/adapters/sdk-policies.ts new file mode 100644 index 000000000..51dc535e6 --- /dev/null +++ b/components/ambient-ui/src/adapters/sdk-policies.ts @@ -0,0 +1,78 @@ +import { PolicyAPI } from 'ambient-sdk' +import type { Policy } from 'ambient-sdk' +import type { PoliciesPort } from '@/ports/policies' +import type { DomainPolicy } from '@/domain/types' +import { getConfig } from './sdk-client' + +function getProjectScopedAPI(projectId: string): PolicyAPI { + return new PolicyAPI({ ...getConfig(), project: projectId }) +} + +function parseJsonObject(raw: string | Record | unknown): Record { + if (!raw) return {} + let obj: unknown = raw + if (typeof raw === 'string') { + try { + obj = JSON.parse(raw) + } catch { + return {} + } + } + if (typeof obj === 'object' && obj !== null && !Array.isArray(obj)) { + const result: Record = {} + for (const [key, value] of Object.entries(obj as Record)) { + result[key] = String(value) + } + return result + } + return {} +} + +function parseSpec(raw: string | Record | unknown): Record { + if (!raw) return {} + if (typeof raw === 'object' && raw !== null && !Array.isArray(raw)) { + return raw as Record + } + if (typeof raw === 'string') { + try { + const parsed: unknown = JSON.parse(raw) + if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) { + return parsed as Record + } + return {} + } catch { + return {} + } + } + return {} +} + +function mapSdkPolicyToDomain(sdk: Policy): DomainPolicy { + return { + id: sdk.id, + name: sdk.name, + namespace: sdk.namespace ?? '', + projectId: sdk.project_id, + spec: parseSpec(sdk.spec), + annotations: parseJsonObject(sdk.annotations), + labels: parseJsonObject(sdk.labels), + createdAt: sdk.created_at ?? '', + updatedAt: sdk.updated_at ?? '', + } +} + +export function createPoliciesAdapter(): PoliciesPort { + return { + async list(projectId: string): Promise { + const api = getProjectScopedAPI(projectId) + const result = await api.list({ size: 100 }) + return result.items.map(mapSdkPolicyToDomain) + }, + + async get(projectId: string, id: string): Promise { + const api = getProjectScopedAPI(projectId) + const policy = await api.get(id) + return mapSdkPolicyToDomain(policy) + }, + } +} diff --git a/components/ambient-ui/src/adapters/sdk-providers.ts b/components/ambient-ui/src/adapters/sdk-providers.ts new file mode 100644 index 000000000..916ca9d8e --- /dev/null +++ b/components/ambient-ui/src/adapters/sdk-providers.ts @@ -0,0 +1,60 @@ +import { ProviderAPI } from 'ambient-sdk' +import type { Provider } from 'ambient-sdk' +import type { ProvidersPort } from '@/ports/providers' +import type { DomainProvider } from '@/domain/types' +import { getConfig } from './sdk-client' + +function getProjectScopedAPI(projectId: string): ProviderAPI { + return new ProviderAPI({ ...getConfig(), project: projectId }) +} + +function parseJsonObject(raw: string | Record | unknown): Record { + if (!raw) return {} + let obj: unknown = raw + if (typeof raw === 'string') { + try { + obj = JSON.parse(raw) + } catch { + return {} + } + } + if (typeof obj === 'object' && obj !== null && !Array.isArray(obj)) { + const result: Record = {} + for (const [key, value] of Object.entries(obj as Record)) { + result[key] = String(value) + } + return result + } + return {} +} + +function mapSdkProviderToDomain(sdk: Provider): DomainProvider { + return { + id: sdk.id, + name: sdk.name, + type: sdk.type ?? '', + secret: sdk.secret ?? '', + namespace: sdk.namespace ?? '', + projectId: sdk.project_id, + annotations: parseJsonObject(sdk.annotations), + labels: parseJsonObject(sdk.labels), + createdAt: sdk.created_at ?? '', + updatedAt: sdk.updated_at ?? '', + } +} + +export function createProvidersAdapter(): ProvidersPort { + return { + async list(projectId: string): Promise { + const api = getProjectScopedAPI(projectId) + const result = await api.list({ size: 100 }) + return result.items.map(mapSdkProviderToDomain) + }, + + async get(projectId: string, id: string): Promise { + const api = getProjectScopedAPI(projectId) + const provider = await api.get(id) + return mapSdkProviderToDomain(provider) + }, + } +} diff --git a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-config-tab.tsx b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-config-tab.tsx index 575afcda8..a4602dbe2 100644 --- a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-config-tab.tsx +++ b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-config-tab.tsx @@ -5,57 +5,7 @@ import { Copy, Download, Check } from 'lucide-react' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' import type { DomainAgent } from '@/domain/types' - -function agentToYaml(agent: DomainAgent): string { - const lines: string[] = [ - 'apiVersion: ambient-code.io/v1', - 'kind: Agent', - 'metadata:', - ` name: ${agent.name}`, - ] - - const annotationEntries = Object.entries(agent.annotations) - if (annotationEntries.length > 0) { - lines.push(' annotations:') - for (const [key, value] of annotationEntries) { - lines.push(` ${key}: "${value}"`) - } - } - - const labelEntries = Object.entries(agent.labels) - if (labelEntries.length > 0) { - lines.push(' labels:') - for (const [key, value] of labelEntries) { - lines.push(` ${key}: "${value}"`) - } - } - - lines.push('spec:') - - if (agent.displayName) { - lines.push(` displayName: "${agent.displayName}"`) - } - if (agent.description) { - lines.push(` description: "${agent.description}"`) - } - if (agent.model) { - lines.push(` model: ${agent.model}`) - } - if (agent.repoUrl) { - lines.push(` repoUrl: ${agent.repoUrl}`) - } - if (agent.workflowId) { - lines.push(` workflowId: ${agent.workflowId}`) - } - if (agent.prompt) { - lines.push(' prompt: |') - for (const promptLine of agent.prompt.split('\n')) { - lines.push(` ${promptLine}`) - } - } - - return lines.join('\n') + '\n' -} +import { agentToYaml } from '@/lib/agent-yaml' export function AgentConfigTab({ agent }: { agent: DomainAgent }) { const [copied, setCopied] = useState(false) diff --git a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-header.tsx b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-header.tsx index 7019d4bbc..3e3aa5f8f 100644 --- a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-header.tsx +++ b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-header.tsx @@ -2,7 +2,7 @@ import { useState, useCallback } from 'react' import { useRouter, useParams } from 'next/navigation' -import { Download, Trash2, MoreVertical } from 'lucide-react' +import { Download, Trash2, MoreVertical, Info } from 'lucide-react' import { Button } from '@/components/ui/button' import { DropdownMenu, @@ -28,37 +28,7 @@ import { useDeleteAgent } from '@/queries/use-agents' import { formatRelativeTime } from '@/lib/format-timestamp' import { TestSessionPopover } from './test-session-popover' import { useChatSidebar } from '@/components/chat-sidebar-context' - -function agentToYaml(agent: DomainAgent): string { - const lines: string[] = [ - 'apiVersion: ambient-code.io/v1', - 'kind: Agent', - 'metadata:', - ` name: ${agent.name}`, - ] - - const annotationEntries = Object.entries(agent.annotations) - if (annotationEntries.length > 0) { - lines.push(' annotations:') - for (const [key, value] of annotationEntries) { - lines.push(` ${key}: "${value}"`) - } - } - - lines.push('spec:') - if (agent.displayName) lines.push(` displayName: "${agent.displayName}"`) - if (agent.description) lines.push(` description: "${agent.description}"`) - if (agent.model) lines.push(` model: ${agent.model}`) - if (agent.repoUrl) lines.push(` repoUrl: ${agent.repoUrl}`) - if (agent.prompt) { - lines.push(' prompt: |') - for (const promptLine of agent.prompt.split('\n')) { - lines.push(` ${promptLine}`) - } - } - - return lines.join('\n') + '\n' -} +import { agentToYaml } from '@/lib/agent-yaml' export function AgentHeader({ agent, @@ -133,15 +103,27 @@ export function AgentHeader({ Export YAML - - setDeleteDialogOpen(true)} - disabled={deleteAgent.isPending} - className="text-destructive focus:text-destructive" - > - - Delete - + {lifecycle === 'gitops' ? ( + <> + +
+ + Managed via GitOps. To remove, delete the ConfigMap declaration. +
+ + ) : ( + <> + + setDeleteDialogOpen(true)} + disabled={deleteAgent.isPending} + className="text-destructive focus:text-destructive" + > + + Delete + + + )} @@ -152,6 +134,9 @@ export function AgentHeader({ )} {agent.model && } + {lifecycle === 'gitops' && agent.annotations['ambient.ai/source-namespace'] && ( + + )} {agent.ownerUserId && } diff --git a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-manifest-tab.tsx b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-manifest-tab.tsx index 8ec1a7414..74b866c93 100644 --- a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-manifest-tab.tsx +++ b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-manifest-tab.tsx @@ -1,26 +1,41 @@ -'use client' +"use client"; -import { useState, useEffect, useCallback, useMemo } from 'react' -import { useParams } from 'next/navigation' -import type { LucideIcon } from 'lucide-react' +import { useState, useEffect, useCallback, useMemo } from "react"; +import { useParams } from "next/navigation"; +import type { LucideIcon } from "lucide-react"; import { - Pin, Tag, Ticket, GitPullRequest, GitBranch, FolderGit2, - Layers, ExternalLink, MessageCircle, User, Play, - DollarSign, Siren, Bot, AlertTriangle, Info, - Copy, Download, Check, -} from 'lucide-react' -import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' -import { Input } from '@/components/ui/input' -import { Textarea } from '@/components/ui/textarea' -import { Button } from '@/components/ui/button' -import { Badge } from '@/components/ui/badge' + Pin, + Tag, + Ticket, + GitPullRequest, + GitBranch, + FolderGit2, + Layers, + ExternalLink, + MessageCircle, + User, + Play, + DollarSign, + Siren, + Bot, + AlertTriangle, + Info, + Copy, + Download, + Check, +} from "lucide-react"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Textarea } from "@/components/ui/textarea"; +import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, -} from '@/components/ui/select' +} from "@/components/ui/select"; import { Table, TableBody, @@ -28,138 +43,310 @@ import { TableHead, TableHeader, TableRow, -} from '@/components/ui/table' -import { getRegisteredAnnotation } from '@/domain/annotations' -import type { DomainAgent } from '@/domain/types' -import type { AgentLifecycle } from '../../_components/lifecycle-badge' -import { useUpdateAgent } from '@/queries/use-agents' -import { MODEL_OPTIONS } from '@/domain/models' +} from "@/components/ui/table"; +import { getRegisteredAnnotation } from "@/domain/annotations"; +import type { DomainAgent } from "@/domain/types"; +import type { AgentLifecycle } from "../../_components/lifecycle-badge"; +import { useUpdateAgent } from "@/queries/use-agents"; +import { MODEL_OPTIONS } from "@/domain/models"; +import { agentToYaml, agentToConfigMapYaml } from "@/lib/agent-yaml"; +import { useGatewayMode } from "@/lib/use-gateway-mode"; const ICON_MAP: Record = { - pin: Pin, tag: Tag, ticket: Ticket, layers: Layers, play: Play, bot: Bot, - siren: Siren, user: User, 'dollar-sign': DollarSign, - 'git-pull-request': GitPullRequest, 'git-branch': GitBranch, - 'folder-git-2': FolderGit2, 'external-link': ExternalLink, - 'message-circle': MessageCircle, 'alert-triangle': AlertTriangle, + pin: Pin, + tag: Tag, + ticket: Ticket, + layers: Layers, + play: Play, + bot: Bot, + siren: Siren, + user: User, + "dollar-sign": DollarSign, + "git-pull-request": GitPullRequest, + "git-branch": GitBranch, + "folder-git-2": FolderGit2, + "external-link": ExternalLink, + "message-circle": MessageCircle, + "alert-triangle": AlertTriangle, +}; + +function isClickableValue(value: string): boolean { + return /^https?:\/\//.test(value); } -function agentToYaml(agent: DomainAgent): string { - const lines: string[] = [ - 'apiVersion: ambient-code.io/v1', - 'kind: Agent', - 'metadata:', - ` name: ${agent.name}`, - ] - - const annotationEntries = Object.entries(agent.annotations) - if (annotationEntries.length > 0) { - lines.push(' annotations:') - for (const [key, value] of annotationEntries) { - lines.push(` ${key}: "${value}"`) - } - } +function GatewayManifestTab({ agent }: { agent: DomainAgent }) { + const [copied, setCopied] = useState(false); - const labelEntries = Object.entries(agent.labels) - if (labelEntries.length > 0) { - lines.push(' labels:') - for (const [key, value] of labelEntries) { - lines.push(` ${key}: "${value}"`) - } - } + const sourceNamespace = + agent.annotations["ambient.ai/source-namespace"] ?? agent.projectId; - lines.push('spec:') - if (agent.displayName) lines.push(` displayName: "${agent.displayName}"`) - if (agent.description) lines.push(` description: "${agent.description}"`) - if (agent.model) lines.push(` model: ${agent.model}`) - if (agent.repoUrl) lines.push(` repoUrl: ${agent.repoUrl}`) - if (agent.workflowId) lines.push(` workflowId: ${agent.workflowId}`) - if (agent.entrypoint) lines.push(` entrypoint: ${agent.entrypoint}`) - if (agent.sandboxPolicy) lines.push(` sandboxPolicy: ${agent.sandboxPolicy}`) - if (agent.prompt) { - lines.push(' prompt: |') - for (const promptLine of agent.prompt.split('\n')) { - lines.push(` ${promptLine}`) - } - } - if (agent.providers.length > 0) { - lines.push(' providers:') - for (const p of agent.providers) { - lines.push(` - ${p}`) - } - } - if (agent.payloads.length > 0) { - lines.push(' payloads:') - for (const payload of agent.payloads) { - lines.push(` - sandbox_path: ${payload.sandbox_path}`) - if (payload.repo_url) lines.push(` repo_url: ${payload.repo_url}`) - if (payload.ref) lines.push(` ref: ${payload.ref}`) - if (payload.content) { - lines.push(' content: |') - for (const cl of payload.content.split('\n')) { - lines.push(` ${cl}`) - } - } - } - } - const envEntries = Object.entries(agent.environment) - if (envEntries.length > 0) { - lines.push(' environment:') - for (const [key, value] of envEntries) { - lines.push(` ${key}: "${value}"`) - } - } - if (agent.sandboxTemplate) { - lines.push(' sandboxTemplate:') - if (agent.sandboxTemplate.image) lines.push(` image: ${agent.sandboxTemplate.image}`) - if (agent.sandboxTemplate.resources) { - lines.push(' resources:') - if (agent.sandboxTemplate.resources.cpu) lines.push(` cpu: "${agent.sandboxTemplate.resources.cpu}"`) - if (agent.sandboxTemplate.resources.memory) lines.push(` memory: ${agent.sandboxTemplate.resources.memory}`) - } - if (agent.sandboxTemplate.gpu) { - lines.push(' gpu:') - if (agent.sandboxTemplate.gpu.count !== undefined) lines.push(` count: ${agent.sandboxTemplate.gpu.count}`) - } - } + const yaml = useMemo( + () => + agentToConfigMapYaml({ + name: agent.name, + namespace: sourceNamespace, + displayName: agent.displayName ?? undefined, + description: agent.description ?? undefined, + model: agent.model ?? undefined, + prompt: agent.prompt ?? undefined, + repoUrl: agent.repoUrl ?? undefined, + entrypoint: agent.entrypoint ?? undefined, + providers: agent.providers.length > 0 ? agent.providers : undefined, + payloads: agent.payloads.length > 0 ? agent.payloads : undefined, + environment: + Object.keys(agent.environment).length > 0 + ? agent.environment + : undefined, + sandboxTemplate: agent.sandboxTemplate ?? undefined, + sandboxPolicy: agent.sandboxPolicy ?? undefined, + }), + [agent, sourceNamespace], + ); - return lines.join('\n') + '\n' -} + const handleCopy = useCallback(async () => { + await navigator.clipboard.writeText(yaml); + setCopied(true); + globalThis.setTimeout(() => setCopied(false), 2000); + }, [yaml]); -function isClickableValue(value: string): boolean { - return /^https?:\/\//.test(value) + const handleDownload = useCallback(() => { + const blob = new Blob([yaml], { type: "text/yaml" }); + const url = URL.createObjectURL(blob); + const link = document.createElement("a"); + link.href = url; + link.download = `agent-${agent.name}.yaml`; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + URL.revokeObjectURL(url); + }, [yaml, agent.name]); + + const envEntries = Object.entries(agent.environment); + + type ConfigRow = { label: string; value: React.ReactNode; mono?: boolean }; + const configRows: ConfigRow[] = []; + + configRows.push({ label: "Name", value: agent.name, mono: true }); + if (agent.displayName) configRows.push({ label: "Display Name", value: agent.displayName }); + if (agent.description) configRows.push({ label: "Description", value: agent.description }); + if (agent.model) configRows.push({ label: "Model", value: agent.model, mono: true }); + if (agent.entrypoint) configRows.push({ label: "Entrypoint", value: agent.entrypoint, mono: true }); + if (agent.repoUrl) configRows.push({ + label: "Repository", + value: ( + + {agent.repoUrl} + + ), + }); + if (agent.sandboxPolicy) configRows.push({ label: "Sandbox Policy", value: agent.sandboxPolicy }); + configRows.push({ label: "Namespace", value: sourceNamespace, mono: true }); + if (agent.providers.length > 0) configRows.push({ + label: "Providers", + value: ( +
+ {agent.providers.map((p) => ( + {p} + ))} +
+ ), + }); + if (agent.sandboxTemplate?.image) configRows.push({ label: "Image", value: agent.sandboxTemplate.image, mono: true }); + if (agent.sandboxTemplate?.resources?.cpu) configRows.push({ label: "CPU", value: agent.sandboxTemplate.resources.cpu }); + if (agent.sandboxTemplate?.resources?.memory) configRows.push({ label: "Memory", value: agent.sandboxTemplate.resources.memory }); + if (agent.sandboxTemplate?.gpu?.count != null) configRows.push({ label: "GPU Count", value: String(agent.sandboxTemplate.gpu.count) }); + if (agent.sandboxTemplate?.runtime_class_name) configRows.push({ label: "Runtime Class", value: agent.sandboxTemplate.runtime_class_name }); + + return ( +
+
+ +
+

GitOps-managed agent

+

+ This agent is managed via GitOps in namespace{" "} + {sourceNamespace}. To modify it, + update the ConfigMap and re-apply with{" "} + kubectl apply. +

+
+
+ + + + Configuration + + + + + {configRows.map((row) => ( + + {row.label} + {row.value} + + ))} + +
+
+
+ + {agent.prompt && ( + + + Prompt + + +
+              {agent.prompt}
+            
+
+
+ )} + + {agent.payloads.length > 0 && ( + + + Payloads ({agent.payloads.length}) + + + + + + Sandbox Path + Source + Ref + + + + {agent.payloads.map((payload) => ( + + {payload.sandbox_path} + + {payload.repo_url ? ( + + {payload.repo_url} + + ) : ( + inline content + )} + + {payload.ref ?? "—"} + + ))} + +
+
+
+ )} + + {envEntries.length > 0 && ( + + + Environment ({envEntries.length}) + + + + + + Variable + Value + + + + {envEntries.map(([key, value]) => ( + + {key} + {value} + + ))} + +
+
+
+ )} + + + +
+ ConfigMap YAML +
+ + +
+
+
+ +
+            {yaml}
+          
+
+
+
+ ); } export function AgentManifestTab({ agent, lifecycle, }: { - agent: DomainAgent - lifecycle: AgentLifecycle + agent: DomainAgent; + lifecycle: AgentLifecycle; +}) { + const gatewayMode = useGatewayMode(); + + if (gatewayMode) { + return ; + } + + return ; +} + +function StandardManifestTab({ + agent, + lifecycle, +}: { + agent: DomainAgent; + lifecycle: AgentLifecycle; }) { - const { projectId } = useParams<{ projectId: string }>() - const isGitOps = lifecycle === 'gitops' - const updateAgent = useUpdateAgent() - - const [displayName, setDisplayName] = useState(agent.displayName ?? '') - const [model, setModel] = useState(agent.model ?? '') - const [prompt, setPrompt] = useState(agent.prompt ?? '') - const [repoUrl, setRepoUrl] = useState(agent.repoUrl ?? '') - const [description, setDescription] = useState(agent.description ?? '') - const [saveError, setSaveError] = useState(null) - const [saveSuccess, setSaveSuccess] = useState(false) - const [copied, setCopied] = useState(false) + const { projectId } = useParams<{ projectId: string }>(); + const isManaged = lifecycle === "gitops"; + const updateAgent = useUpdateAgent(); + + const [displayName, setDisplayName] = useState(agent.displayName ?? ""); + const [model, setModel] = useState(agent.model ?? ""); + const [prompt, setPrompt] = useState(agent.prompt ?? ""); + const [repoUrl, setRepoUrl] = useState(agent.repoUrl ?? ""); + const [description, setDescription] = useState(agent.description ?? ""); + const [saveError, setSaveError] = useState(null); + const [saveSuccess, setSaveSuccess] = useState(false); + const [copied, setCopied] = useState(false); useEffect(() => { - setDisplayName(agent.displayName ?? '') - setModel(agent.model ?? '') - setPrompt(agent.prompt ?? '') - setRepoUrl(agent.repoUrl ?? '') - setDescription(agent.description ?? '') - }, [agent]) + setDisplayName(agent.displayName ?? ""); + setModel(agent.model ?? ""); + setPrompt(agent.prompt ?? ""); + setRepoUrl(agent.repoUrl ?? ""); + setDescription(agent.description ?? ""); + }, [agent]); const handleSave = useCallback(async () => { - setSaveError(null) - setSaveSuccess(false) + setSaveError(null); + setSaveSuccess(false); try { const updated = await updateAgent.mutateAsync({ projectId, @@ -171,59 +358,78 @@ export function AgentManifestTab({ repoUrl: repoUrl || undefined, description: description || undefined, }, - }) - setDisplayName(updated.displayName ?? '') - setModel(updated.model ?? '') - setPrompt(updated.prompt ?? '') - setRepoUrl(updated.repoUrl ?? '') - setDescription(updated.description ?? '') - setSaveSuccess(true) - globalThis.setTimeout(() => setSaveSuccess(false), 3000) + }); + setDisplayName(updated.displayName ?? ""); + setModel(updated.model ?? ""); + setPrompt(updated.prompt ?? ""); + setRepoUrl(updated.repoUrl ?? ""); + setDescription(updated.description ?? ""); + setSaveSuccess(true); + globalThis.setTimeout(() => setSaveSuccess(false), 3000); } catch (err) { - setSaveError(err instanceof Error ? err.message : 'Failed to save changes.') + setSaveError( + err instanceof Error ? err.message : "Failed to save changes.", + ); } - }, [updateAgent, projectId, agent.id, displayName, model, prompt, repoUrl, description]) + }, [ + updateAgent, + projectId, + agent.id, + displayName, + model, + prompt, + repoUrl, + description, + ]); - const liveAgent = useMemo((): DomainAgent => ({ - ...agent, - displayName: displayName || null, - model: model || null, - prompt: prompt || null, - repoUrl: repoUrl || null, - description: description || null, - }), [agent, displayName, model, prompt, repoUrl, description]) + const liveAgent = useMemo( + (): DomainAgent => ({ + ...agent, + displayName: displayName || null, + model: model || null, + prompt: prompt || null, + repoUrl: repoUrl || null, + description: description || null, + }), + [agent, displayName, model, prompt, repoUrl, description], + ); - const yaml = useMemo(() => agentToYaml(liveAgent), [liveAgent]) + const yaml = useMemo(() => agentToYaml(liveAgent), [liveAgent]); const handleCopy = useCallback(async () => { - await navigator.clipboard.writeText(yaml) - setCopied(true) - globalThis.setTimeout(() => setCopied(false), 2000) - }, [yaml]) + await navigator.clipboard.writeText(yaml); + setCopied(true); + globalThis.setTimeout(() => setCopied(false), 2000); + }, [yaml]); const handleDownload = useCallback(() => { - const blob = new Blob([yaml], { type: 'text/yaml' }) - const url = URL.createObjectURL(blob) - const link = document.createElement('a') - link.href = url - link.download = `agent-${agent.name}.yaml` - document.body.appendChild(link) - link.click() - document.body.removeChild(link) - URL.revokeObjectURL(url) - }, [yaml, agent.name]) - - const annotationEntries = Object.entries(agent.annotations) + const blob = new Blob([yaml], { type: "text/yaml" }); + const url = URL.createObjectURL(blob); + const link = document.createElement("a"); + link.href = url; + link.download = `agent-${agent.name}.yaml`; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + URL.revokeObjectURL(url); + }, [yaml, agent.name]); + + const annotationEntries = Object.entries(agent.annotations); return (
- {isGitOps && ( + {isManaged && (

GitOps-managed agent

- This agent is managed via GitOps. Edits here will not persist. + This agent is managed via GitOps + {agent.annotations["ambient.ai/source-namespace"] + ? ` in namespace ${agent.annotations["ambient.ai/source-namespace"]}` + : ""} + . This is viewable only. Edits to this resource should occur via + the ConfigMap declaration.

@@ -243,7 +449,7 @@ export function AgentManifestTab({ value={displayName} onChange={(e) => setDisplayName(e.target.value)} placeholder="Human-readable name" - disabled={isGitOps} + disabled={isManaged} />
@@ -251,7 +457,7 @@ export function AgentManifestTab({ - @@ -274,7 +480,7 @@ export function AgentManifestTab({ value={repoUrl} onChange={(e) => setRepoUrl(e.target.value)} placeholder="https://github.com/org/repo" - disabled={isGitOps} + disabled={isManaged} /> @@ -288,7 +494,7 @@ export function AgentManifestTab({ onChange={(e) => setDescription(e.target.value)} placeholder="What does this agent do?" className="min-h-20" - disabled={isGitOps} + disabled={isManaged} /> @@ -302,20 +508,19 @@ export function AgentManifestTab({ onChange={(e) => setPrompt(e.target.value)} placeholder="System prompt for the agent..." className="min-h-40 font-mono text-sm" - disabled={isGitOps} + disabled={isManaged} /> - {!isGitOps && ( + {!isManaged && (
- {saveSuccess && ( - Changes saved. + + Changes saved. + )} {saveError && ( {saveError} @@ -332,9 +537,15 @@ export function AgentManifestTab({
- ) + ); } diff --git a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-overview-tab.tsx b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-overview-tab.tsx index 564906200..204df0ab9 100644 --- a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-overview-tab.tsx +++ b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/[agentId]/_components/agent-overview-tab.tsx @@ -1,25 +1,38 @@ -'use client' +"use client"; -import { useState, useEffect, useCallback } from 'react' -import { useParams } from 'next/navigation' -import type { LucideIcon } from 'lucide-react' +import { useState, useEffect, useCallback } from "react"; +import { useParams } from "next/navigation"; +import type { LucideIcon } from "lucide-react"; import { - Pin, Tag, Ticket, GitPullRequest, GitBranch, FolderGit2, - Layers, ExternalLink, MessageCircle, User, Play, - DollarSign, Siren, Bot, AlertTriangle, Info, -} from 'lucide-react' -import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' -import { Input } from '@/components/ui/input' -import { Textarea } from '@/components/ui/textarea' -import { Button } from '@/components/ui/button' -import { Badge } from '@/components/ui/badge' + Pin, + Tag, + Ticket, + GitPullRequest, + GitBranch, + FolderGit2, + Layers, + ExternalLink, + MessageCircle, + User, + Play, + DollarSign, + Siren, + Bot, + AlertTriangle, + Info, +} from "lucide-react"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Textarea } from "@/components/ui/textarea"; +import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, -} from '@/components/ui/select' +} from "@/components/ui/select"; import { Table, TableBody, @@ -27,55 +40,65 @@ import { TableHead, TableHeader, TableRow, -} from '@/components/ui/table' -import { getRegisteredAnnotation } from '@/domain/annotations' -import type { DomainAgent } from '@/domain/types' -import type { AgentLifecycle } from '../../_components/lifecycle-badge' -import { useUpdateAgent } from '@/queries/use-agents' -import { MODEL_OPTIONS } from '@/domain/models' +} from "@/components/ui/table"; +import { getRegisteredAnnotation } from "@/domain/annotations"; +import type { DomainAgent } from "@/domain/types"; +import type { AgentLifecycle } from "../../_components/lifecycle-badge"; +import { useUpdateAgent } from "@/queries/use-agents"; +import { MODEL_OPTIONS } from "@/domain/models"; const ICON_MAP: Record = { - pin: Pin, tag: Tag, ticket: Ticket, layers: Layers, play: Play, bot: Bot, - siren: Siren, user: User, 'dollar-sign': DollarSign, - 'git-pull-request': GitPullRequest, 'git-branch': GitBranch, - 'folder-git-2': FolderGit2, 'external-link': ExternalLink, - 'message-circle': MessageCircle, 'alert-triangle': AlertTriangle, -} + pin: Pin, + tag: Tag, + ticket: Ticket, + layers: Layers, + play: Play, + bot: Bot, + siren: Siren, + user: User, + "dollar-sign": DollarSign, + "git-pull-request": GitPullRequest, + "git-branch": GitBranch, + "folder-git-2": FolderGit2, + "external-link": ExternalLink, + "message-circle": MessageCircle, + "alert-triangle": AlertTriangle, +}; function isClickableValue(value: string): boolean { - return /^https?:\/\//.test(value) + return /^https?:\/\//.test(value); } export function AgentOverviewTab({ agent, lifecycle, }: { - agent: DomainAgent - lifecycle: AgentLifecycle + agent: DomainAgent; + lifecycle: AgentLifecycle; }) { - const { projectId } = useParams<{ projectId: string }>() - const isGitOps = lifecycle === 'gitops' - const updateAgent = useUpdateAgent() + const { projectId } = useParams<{ projectId: string }>(); + const isManaged = lifecycle === "gitops"; + const updateAgent = useUpdateAgent(); - const [displayName, setDisplayName] = useState(agent.displayName ?? '') - const [model, setModel] = useState(agent.model ?? '') - const [prompt, setPrompt] = useState(agent.prompt ?? '') - const [repoUrl, setRepoUrl] = useState(agent.repoUrl ?? '') - const [description, setDescription] = useState(agent.description ?? '') - const [saveError, setSaveError] = useState(null) - const [saveSuccess, setSaveSuccess] = useState(false) + const [displayName, setDisplayName] = useState(agent.displayName ?? ""); + const [model, setModel] = useState(agent.model ?? ""); + const [prompt, setPrompt] = useState(agent.prompt ?? ""); + const [repoUrl, setRepoUrl] = useState(agent.repoUrl ?? ""); + const [description, setDescription] = useState(agent.description ?? ""); + const [saveError, setSaveError] = useState(null); + const [saveSuccess, setSaveSuccess] = useState(false); useEffect(() => { - setDisplayName(agent.displayName ?? '') - setModel(agent.model ?? '') - setPrompt(agent.prompt ?? '') - setRepoUrl(agent.repoUrl ?? '') - setDescription(agent.description ?? '') - }, [agent]) + setDisplayName(agent.displayName ?? ""); + setModel(agent.model ?? ""); + setPrompt(agent.prompt ?? ""); + setRepoUrl(agent.repoUrl ?? ""); + setDescription(agent.description ?? ""); + }, [agent]); const handleSave = useCallback(async () => { - setSaveError(null) - setSaveSuccess(false) + setSaveError(null); + setSaveSuccess(false); try { await updateAgent.mutateAsync({ projectId, @@ -87,25 +110,41 @@ export function AgentOverviewTab({ repoUrl: repoUrl || undefined, description: description || undefined, }, - }) - setSaveSuccess(true) - globalThis.setTimeout(() => setSaveSuccess(false), 3000) + }); + setSaveSuccess(true); + globalThis.setTimeout(() => setSaveSuccess(false), 3000); } catch (err) { - setSaveError(err instanceof Error ? err.message : 'Failed to save changes.') + setSaveError( + err instanceof Error ? err.message : "Failed to save changes.", + ); } - }, [updateAgent, projectId, agent.id, displayName, model, prompt, repoUrl, description]) + }, [ + updateAgent, + projectId, + agent.id, + displayName, + model, + prompt, + repoUrl, + description, + ]); - const annotationEntries = Object.entries(agent.annotations) + const annotationEntries = Object.entries(agent.annotations); return (
- {isGitOps && ( + {isManaged && (

GitOps-managed agent

- This agent is managed via GitOps. Edits here will not persist. + This agent is managed via GitOps + {agent.annotations["ambient.ai/source-namespace"] + ? ` in namespace ${agent.annotations["ambient.ai/source-namespace"]}` + : ""} + . This is viewable only. Edits to this resource should occur via + the ConfigMap declaration.

@@ -125,7 +164,7 @@ export function AgentOverviewTab({ value={displayName} onChange={(e) => setDisplayName(e.target.value)} placeholder="Human-readable name" - disabled={isGitOps} + disabled={isManaged} />
@@ -133,7 +172,7 @@ export function AgentOverviewTab({ - @@ -156,7 +195,7 @@ export function AgentOverviewTab({ value={repoUrl} onChange={(e) => setRepoUrl(e.target.value)} placeholder="https://github.com/org/repo" - disabled={isGitOps} + disabled={isManaged} />
@@ -170,7 +209,7 @@ export function AgentOverviewTab({ onChange={(e) => setDescription(e.target.value)} placeholder="What does this agent do?" className="min-h-20" - disabled={isGitOps} + disabled={isManaged} /> @@ -184,20 +223,19 @@ export function AgentOverviewTab({ onChange={(e) => setPrompt(e.target.value)} placeholder="System prompt for the agent..." className="min-h-40 font-mono text-sm" - disabled={isGitOps} + disabled={isManaged} /> - {!isGitOps && ( + {!isManaged && (
- {saveSuccess && ( - Changes saved. + + Changes saved. + )} {saveError && ( {saveError} @@ -224,14 +262,18 @@ export function AgentOverviewTab({ {annotationEntries.map(([key, value]) => { - const registered = getRegisteredAnnotation(key) - const Icon = registered?.icon ? ICON_MAP[registered.icon] : null - const clickable = isClickableValue(value) + const registered = getRegisteredAnnotation(key); + const Icon = registered?.icon + ? ICON_MAP[registered.icon] + : null; + const clickable = isClickableValue(value); return ( - {Icon && } + {Icon && ( + + )} {registered ? registered.label : key} @@ -250,7 +292,7 @@ export function AgentOverviewTab({ )} - ) + ); })} @@ -277,5 +319,5 @@ export function AgentOverviewTab({ )}
- ) + ); } diff --git a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/configmap-summary-bar.tsx b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/configmap-summary-bar.tsx new file mode 100644 index 000000000..896863554 --- /dev/null +++ b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/configmap-summary-bar.tsx @@ -0,0 +1,33 @@ +'use client' + +import { KeyRound, Shield } from 'lucide-react' +import { Badge } from '@/components/ui/badge' +import { useProviders } from '@/queries/use-providers' +import { usePolicies } from '@/queries/use-policies' + +export function ConfigMapSummaryBar({ projectId }: { projectId: string }) { + const { data: providers } = useProviders(projectId) + const { data: policies } = usePolicies(projectId) + + const providerCount = providers?.length ?? 0 + const policyCount = policies?.length ?? 0 + + if (providerCount === 0 && policyCount === 0) return null + + return ( +
+ {providerCount > 0 && ( + + + {providerCount} {providerCount === 1 ? 'Provider' : 'Providers'} + + )} + {policyCount > 0 && ( + + + {policyCount} {policyCount === 1 ? 'Policy' : 'Policies'} + + )} +
+ ) +} diff --git a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/configmap-yaml-preview.tsx b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/configmap-yaml-preview.tsx new file mode 100644 index 000000000..e3806c060 --- /dev/null +++ b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/configmap-yaml-preview.tsx @@ -0,0 +1,60 @@ +'use client' + +import { useState, useCallback } from 'react' +import { Copy, Download, Check } from 'lucide-react' +import { Button } from '@/components/ui/button' + +export function ConfigMapYamlPreview({ + yaml, + agentName, +}: { + yaml: string + agentName: string +}) { + const [copied, setCopied] = useState(false) + + const handleCopy = useCallback(async () => { + await navigator.clipboard.writeText(yaml) + setCopied(true) + globalThis.setTimeout(() => setCopied(false), 2000) + }, [yaml]) + + const handleDownload = useCallback(() => { + const blob = new Blob([yaml], { type: 'text/yaml' }) + const url = URL.createObjectURL(blob) + const link = document.createElement('a') + link.href = url + link.download = `agent-${agentName}.yaml` + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + URL.revokeObjectURL(url) + }, [yaml, agentName]) + + return ( +
+
+

Generated ConfigMap

+
+ + +
+
+
+        {yaml}
+      
+

+ Apply with: kubectl apply -f agent-{agentName}.yaml +

+
+ ) +} diff --git a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/create-agent-sheet.tsx b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/create-agent-sheet.tsx index 4dfd777d6..4679523bb 100644 --- a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/create-agent-sheet.tsx +++ b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/create-agent-sheet.tsx @@ -1,6 +1,6 @@ 'use client' -import { useState } from 'react' +import { useState, useMemo, useCallback } from 'react' import { useRouter, useParams } from 'next/navigation' import { Sheet, @@ -21,8 +21,14 @@ import { SelectValue, } from '@/components/ui/select' import { useCreateAgent } from '@/queries/use-agents' -import type { DomainAgentCreateRequest } from '@/domain/types' +import type { DomainAgentCreateRequest, DomainPayload } from '@/domain/types' import { MODEL_OPTIONS } from '@/domain/models' +import { useGatewayMode } from '@/lib/use-gateway-mode' +import { agentToConfigMapYaml } from '@/lib/agent-yaml' +import type { ConfigMapAgentInput } from '@/lib/agent-yaml' +import { SandboxConfigFields, INITIAL_SANDBOX_CONFIG } from './sandbox-config-fields' +import type { SandboxConfigState } from './sandbox-config-fields' +import { ConfigMapYamlPreview } from './configmap-yaml-preview' export function CreateAgentSheet({ open, @@ -34,6 +40,7 @@ export function CreateAgentSheet({ const router = useRouter() const { projectId } = useParams<{ projectId: string }>() const createAgent = useCreateAgent() + const gatewayMode = useGatewayMode() const [name, setName] = useState('') const [displayName, setDisplayName] = useState('') @@ -43,6 +50,12 @@ export function CreateAgentSheet({ const [description, setDescription] = useState('') const [error, setError] = useState(null) + const [sandboxConfig, setSandboxConfig] = useState({ + ...INITIAL_SANDBOX_CONFIG, + namespace: projectId ?? '', + }) + const [generatedYaml, setGeneratedYaml] = useState(null) + function resetForm() { setName('') setDisplayName('') @@ -51,9 +64,77 @@ export function CreateAgentSheet({ setRepoUrl('') setDescription('') setError(null) + setSandboxConfig({ ...INITIAL_SANDBOX_CONFIG, namespace: projectId ?? '' }) + setGeneratedYaml(null) } - async function handleSubmit(e: React.FormEvent) { + const buildConfigMapInput = useCallback((): ConfigMapAgentInput => { + const providers = sandboxConfig.providers + .split(',') + .map((p) => p.trim()) + .filter(Boolean) + + const environment: Record = {} + for (const row of sandboxConfig.envRows) { + if (row.key.trim()) { + environment[row.key.trim()] = row.value + } + } + + const payloads: DomainPayload[] = sandboxConfig.payloadRows + .filter((row) => row.sandboxPath.trim()) + .map((row) => ({ + sandbox_path: row.sandboxPath.trim(), + ...(row.repoUrl.trim() ? { repo_url: row.repoUrl.trim() } : {}), + ...(row.ref.trim() ? { ref: row.ref.trim() } : {}), + ...(!row.repoUrl.trim() && row.content.trim() ? { content: row.content.trim() } : {}), + })) + + return { + name: name.trim(), + namespace: sandboxConfig.namespace.trim() || projectId, + ...(displayName.trim() ? { displayName: displayName.trim() } : {}), + ...(description.trim() ? { description: description.trim() } : {}), + ...(model ? { model } : {}), + ...(prompt.trim() ? { prompt: prompt.trim() } : {}), + ...(repoUrl.trim() ? { repoUrl: repoUrl.trim() } : {}), + ...(sandboxConfig.entrypoint.trim() ? { entrypoint: sandboxConfig.entrypoint.trim() } : {}), + ...(providers.length > 0 ? { providers } : {}), + ...(payloads.length > 0 ? { payloads } : {}), + ...(Object.keys(environment).length > 0 ? { environment } : {}), + ...(sandboxConfig.sandboxPolicy.trim() ? { sandboxPolicy: sandboxConfig.sandboxPolicy.trim() } : {}), + ...((sandboxConfig.image.trim() || sandboxConfig.cpu.trim() || sandboxConfig.memory.trim()) ? { + sandboxTemplate: { + ...(sandboxConfig.image.trim() ? { image: sandboxConfig.image.trim() } : {}), + ...((sandboxConfig.cpu.trim() || sandboxConfig.memory.trim()) ? { + resources: { + ...(sandboxConfig.cpu.trim() ? { cpu: sandboxConfig.cpu.trim() } : {}), + ...(sandboxConfig.memory.trim() ? { memory: sandboxConfig.memory.trim() } : {}), + }, + } : {}), + }, + } : {}), + } + }, [name, displayName, description, model, prompt, repoUrl, sandboxConfig, projectId]) + + function handleGenerateYaml(e: React.FormEvent) { + e.preventDefault() + setError(null) + + if (!name.trim()) { + setError('Name is required.') + return + } + if (!sandboxConfig.namespace.trim()) { + setError('Namespace is required.') + return + } + + const yaml = agentToConfigMapYaml(buildConfigMapInput()) + setGeneratedYaml(yaml) + } + + async function handleSubmitApi(e: React.FormEvent) { e.preventDefault() setError(null) @@ -84,17 +165,31 @@ export function CreateAgentSheet({ } } + const previewYaml = useMemo(() => { + if (!gatewayMode || !name.trim()) return null + try { + return agentToConfigMapYaml(buildConfigMapInput()) + } catch { + return null + } + }, [gatewayMode, name, buildConfigMapInput]) + return ( { if (!v) resetForm(); onOpenChange(v) }}> - New Agent + {gatewayMode ? 'Generate Agent YAML' : 'New Agent'} - Create a new agent definition in this project. + {gatewayMode + ? 'Define an agent and generate a ConfigMap YAML for kubectl apply.' + : 'Create a new agent definition in this project.'} -
+
+ {gatewayMode && ( + + )} + {error && (

{error}

)} + {gatewayMode && generatedYaml && ( + + )} + - + {gatewayMode ? ( + + ) : ( + + )}
diff --git a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/lifecycle-badge.tsx b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/lifecycle-badge.tsx index be3f729e0..6cba913aa 100644 --- a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/lifecycle-badge.tsx +++ b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/lifecycle-badge.tsx @@ -1,21 +1,25 @@ 'use client' -import { GitBranch, CircleDashed } from 'lucide-react' +import { FileStack, CircleDashed } from 'lucide-react' import { Badge } from '@/components/ui/badge' -const MANAGED_BY_KEY = 'ambient-code.io/managed-by' - export type AgentLifecycle = 'unmanaged' | 'gitops' export function getAgentLifecycle(annotations: Record): AgentLifecycle { - return annotations[MANAGED_BY_KEY] === 'gitops' ? 'gitops' : 'unmanaged' + if ( + annotations['ambient.ai/source'] === 'configmap' || + annotations['ambient-code.io/managed-by'] === 'gitops' + ) { + return 'gitops' + } + return 'unmanaged' } export function LifecycleBadge({ lifecycle }: { lifecycle: AgentLifecycle }) { if (lifecycle === 'gitops') { return ( - - + + GitOps ) diff --git a/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/sandbox-config-fields.tsx b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/sandbox-config-fields.tsx new file mode 100644 index 000000000..7e99053b6 --- /dev/null +++ b/components/ambient-ui/src/app/(dashboard)/[projectId]/agents/_components/sandbox-config-fields.tsx @@ -0,0 +1,294 @@ +'use client' + +import { useState } from 'react' +import { Plus, X, ChevronDown, ChevronRight } from 'lucide-react' +import { Input } from '@/components/ui/input' +import { Textarea } from '@/components/ui/textarea' +import { Button } from '@/components/ui/button' + +export type PayloadRow = { + sandboxPath: string + repoUrl: string + ref: string + content: string +} + +export type SandboxConfigState = { + namespace: string + entrypoint: string + providers: string + sandboxPolicy: string + image: string + cpu: string + memory: string + envRows: { key: string; value: string }[] + payloadRows: PayloadRow[] +} + +export const INITIAL_SANDBOX_CONFIG: SandboxConfigState = { + namespace: '', + entrypoint: '', + providers: '', + sandboxPolicy: '', + image: '', + cpu: '', + memory: '', + envRows: [], + payloadRows: [], +} + +export function SandboxConfigFields({ + state, + onChange, +}: { + state: SandboxConfigState + onChange: (state: SandboxConfigState) => void +}) { + const [expanded, setExpanded] = useState(false) + + function update(partial: Partial) { + onChange({ ...state, ...partial }) + } + + function addEnvRow() { + onChange({ ...state, envRows: [...state.envRows, { key: '', value: '' }] }) + } + + function removeEnvRow(index: number) { + const next = state.envRows.filter((_, i) => i !== index) + onChange({ ...state, envRows: next }) + } + + function updateEnvRow(index: number, field: 'key' | 'value', val: string) { + const next = state.envRows.map((row, i) => + i === index ? { ...row, [field]: val } : row + ) + onChange({ ...state, envRows: next }) + } + + function addPayloadRow() { + onChange({ + ...state, + payloadRows: [...state.payloadRows, { sandboxPath: '', repoUrl: '', ref: '', content: '' }], + }) + } + + function removePayloadRow(index: number) { + const next = state.payloadRows.filter((_, i) => i !== index) + onChange({ ...state, payloadRows: next }) + } + + function updatePayloadRow(index: number, field: keyof PayloadRow, val: string) { + const next = state.payloadRows.map((row, i) => + i === index ? { ...row, [field]: val } : row + ) + onChange({ ...state, payloadRows: next }) + } + + return ( +
+ + + {expanded && ( +
+
+ + update({ namespace: e.target.value })} + /> +
+ +
+ + update({ entrypoint: e.target.value })} + /> +
+ +
+ + update({ providers: e.target.value })} + /> +
+ +
+ + update({ sandboxPolicy: e.target.value })} + /> +
+ +
+ + update({ image: e.target.value })} + /> +
+ +
+
+ + update({ cpu: e.target.value })} + /> +
+
+ + update({ memory: e.target.value })} + /> +
+
+ +
+
+ + +
+ {state.payloadRows.map((row, i) => ( +
+
+ Payload {i + 1} + +
+
+ + updatePayloadRow(i, 'sandboxPath', e.target.value)} + className="font-mono text-sm" + /> +
+
+ +
+ { + updatePayloadRow(i, 'repoUrl', e.target.value) + if (e.target.value.trim()) { + updatePayloadRow(i, 'content', '') + } + }} + className="text-sm" + disabled={!!row.content.trim()} + /> + updatePayloadRow(i, 'ref', e.target.value)} + className="font-mono text-sm w-28" + disabled={!!row.content.trim()} + /> +
+
+
+
+ or +
+
+
+ +