diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4988ca2..9e99d03c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,15 +2,15 @@ name: CI on: push: branches-ignore: - - "generated" - - "codegen/**" - - "integrated/**" - - "stl-preview-head/**" - - "stl-preview-base/**" + - 'generated' + - 'codegen/**' + - 'integrated/**' + - 'stl-preview-head/**' + - 'stl-preview-base/**' pull_request: branches-ignore: - - "stl-preview-head/**" - - "stl-preview-base/**" + - 'stl-preview-head/**' + - 'stl-preview-base/**' jobs: lint: @@ -26,8 +26,8 @@ jobs: curl -sSf https://rye.astral.sh/get | bash echo "$HOME/.rye/shims" >> $GITHUB_PATH env: - RYE_VERSION: "0.44.0" - RYE_INSTALL_OPTION: "--yes" + RYE_VERSION: '0.44.0' + RYE_INSTALL_OPTION: '--yes' - name: Install dependencies run: rye sync --all-features @@ -51,8 +51,8 @@ jobs: curl -sSf https://rye.astral.sh/get | bash echo "$HOME/.rye/shims" >> $GITHUB_PATH env: - RYE_VERSION: "0.44.0" - RYE_INSTALL_OPTION: "--yes" + RYE_VERSION: '0.44.0' + RYE_INSTALL_OPTION: '--yes' - name: Install dependencies run: rye sync --all-features @@ -63,7 +63,7 @@ jobs: - name: Get GitHub OIDC Token if: github.repository == 'stainless-sdks/gitpod-python' id: github-oidc - uses: actions/github-script@00f12e3e20659f42342b1c0226afda7f7c042325 # v6 + uses: actions/github-script@v8 with: script: core.setOutput('github_token', await core.getIDToken()); @@ -88,8 +88,8 @@ jobs: curl -sSf https://rye.astral.sh/get | bash echo "$HOME/.rye/shims" >> $GITHUB_PATH env: - RYE_VERSION: "0.44.0" - RYE_INSTALL_OPTION: "--yes" + RYE_VERSION: '0.44.0' + RYE_INSTALL_OPTION: '--yes' - name: Bootstrap run: ./scripts/bootstrap diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 1b77f506..6538ca91 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.7.0" + ".": "0.8.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 886c83c4..592d8a4c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 170 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-2423c089f280cdf34a987d40531692097a69f4aa971c6adf9aeec4fd7984cec2.yml -openapi_spec_hash: 24037c3ab9ceca689150d07ecec7aa80 -config_hash: d726afb2a92132197e4eae04303e8041 +configured_endpoints: 172 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-b97dcde84128bcf3740b0cf3c2c005e1dcd1cdac9b0768a28bd734f8d83c9fa2.yml +openapi_spec_hash: 1172889d2eb3f0453514c6caae3459b3 +config_hash: 49d499b8ab46cede0e3461ef7cd549ca diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d5779cb..b5584aed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,58 @@ # Changelog +## 0.8.0 (2026-02-11) + +Full Changelog: [v0.7.0...v0.8.0](https://github.com/gitpod-io/gitpod-sdk-python/compare/v0.7.0...v0.8.0) + +### Features + +* [backend] Resource admin should be able to see all resource shares ([153d9ba](https://github.com/gitpod-io/gitpod-sdk-python/commit/153d9babce677adb9cda8b900b078ed7d16879b7)) +* [SCIM] Configurable token expiration duration ([71eb2b6](https://github.com/gitpod-io/gitpod-sdk-python/commit/71eb2b62d685a409abe4a27129e0408758bc735f)) +* [SCIM] Configurable token expiration duration ([16049ed](https://github.com/gitpod-io/gitpod-sdk-python/commit/16049ed4392e5551137a0bf7930b0a8ebcaa7b5e)) +* **agent:** add annotations field to AgentExecution ([09c2210](https://github.com/gitpod-io/gitpod-sdk-python/commit/09c2210f258504cbebaed878233e2d5e06f939ec)) +* **api:** add additional_scopes to organization SSO configuration ([07aa0cc](https://github.com/gitpod-io/gitpod-sdk-python/commit/07aa0cc02a4b65244104be04289c949bfb013c14)) +* **api:** add announcement banner fields to organization proto ([1cbdaaa](https://github.com/gitpod-io/gitpod-sdk-python/commit/1cbdaaa69c1077d7d354991621af88f7e71e4df0)) +* **api:** add derivedFromOrgRole field to RoleAssignment ([e1ed935](https://github.com/gitpod-io/gitpod-sdk-python/commit/e1ed9353e48590389e21fa38137280daeef56da9)) +* **api:** add dev_runner_id to agents, dev_environment_id and provider to runners ([c345871](https://github.com/gitpod-io/gitpod-sdk-python/commit/c3458714c345048e05c74b213bcf087f3b977313)) +* **api:** add exclude_group_id filter to organization list members ([008ae2b](https://github.com/gitpod-io/gitpod-sdk-python/commit/008ae2b90fef5c2f8eb5e1d624c9e5a2a6a1f83a)) +* **api:** add ExecutableDenyList to environment and organization policy ([110c2ef](https://github.com/gitpod-io/gitpod-sdk-python/commit/110c2efc4f4d5dac2fa1209b7c85554060110889)) +* **api:** add filters to ListPrebuilds for inventory page ([4bc3f9f](https://github.com/gitpod-io/gitpod-sdk-python/commit/4bc3f9f92f2de35c0cb1427df1af602014856000)) +* **api:** add mcp_integrations field and type to agent_execution ([911140b](https://github.com/gitpod-io/gitpod-sdk-python/commit/911140bc7050b5e02daec1f207bbced61db39e0b)) +* **api:** add opus 4.6 model variants to agent supported models ([71e660d](https://github.com/gitpod-io/gitpod-sdk-python/commit/71e660d25b7d164b2d37b09058aa3e74f445e5ca)) +* **api:** add port access methods and organization admission level to environments ([af512f5](https://github.com/gitpod-io/gitpod-sdk-python/commit/af512f54181bc7da478f5e47b949715bec0e8b03)) +* **api:** add ResourceRoleOrgAutomationsAdmin to ResourceRole enum ([320b285](https://github.com/gitpod-io/gitpod-sdk-python/commit/320b285f1fd8723e6c6fa0dc027812cff0891485)) +* **api:** add ResourceRoleOrgGroupsAdmin to ResourceRole enum ([c2fceff](https://github.com/gitpod-io/gitpod-sdk-python/commit/c2fceff932dc786e8fc66d1fb44021e25f59c07e)) +* **api:** add restrict_account_creation_to_scim field to organization policy ([c1272d1](https://github.com/gitpod-io/gitpod-sdk-python/commit/c1272d1a95dbcdb0366cff0c3158e3f9d4769f1a)) +* **api:** add scope field and enum to environment secrets ([371f8f7](https://github.com/gitpod-io/gitpod-sdk-python/commit/371f8f7fc5e3fc882205b852aa684d5626c34e11)) +* **api:** add user_ids filter to organization list members method ([5abdcae](https://github.com/gitpod-io/gitpod-sdk-python/commit/5abdcaecdc351d12e4715c1e4970d836173d6d9f)) +* **api:** add warm pools resource to prebuilds ([b997cfe](https://github.com/gitpod-io/gitpod-sdk-python/commit/b997cfe8e95a7e55a645e7fa54446555ed0108e4)) +* **api:** implement GetAnnouncementBanner and UpdateAnnouncementBanner handlers ([6482c1a](https://github.com/gitpod-io/gitpod-sdk-python/commit/6482c1a4b50742622a90815484c6b59020d196f6)) +* **chat:** add Pylon identity verification for chat widget ([f7b7cb3](https://github.com/gitpod-io/gitpod-sdk-python/commit/f7b7cb37e2349ef60d26890c1a4cc72db34b32f8)) +* **cli:** add --name flag to environment create command ([b292d8f](https://github.com/gitpod-io/gitpod-sdk-python/commit/b292d8f4fb2520ba65bb6701ac8507b16f56080e)) +* **client:** add custom JSON encoder for extended type support ([48e0b49](https://github.com/gitpod-io/gitpod-sdk-python/commit/48e0b4951e34166dba1c29cd4e6b15fb2314b54e)) +* **db:** add service_account_tokens table ([688cf2e](https://github.com/gitpod-io/gitpod-sdk-python/commit/688cf2e01a33ca12de9443d3857360d4223fa0f8)) +* Introduce projects admin org role ([2777780](https://github.com/gitpod-io/gitpod-sdk-python/commit/2777780d987da76ab00f131c243b1ee69e39c901)) +* **runner:** add capability check for ListSCMOrganizations ([4a87ef2](https://github.com/gitpod-io/gitpod-sdk-python/commit/4a87ef22bd88a83fb2eaa9255d9ae60bf8eee618)) +* **types:** add RoleAssignment value to ResourceType enum ([d59ab98](https://github.com/gitpod-io/gitpod-sdk-python/commit/d59ab9810266a68d5b4cd31dd6da669d2691436f)) + + +### Bug Fixes + +* **api:** reject double-slash prefix in secret file paths ([fb4f63f](https://github.com/gitpod-io/gitpod-sdk-python/commit/fb4f63f9369cdcdb2cbc729bcd0a4bc0aa7b7745)) + + +### Chores + +* **ci:** upgrade `actions/github-script` ([d6a1726](https://github.com/gitpod-io/gitpod-sdk-python/commit/d6a1726d9806c8433ba7bc1612018bc84309147e)) +* **internal:** bump dependencies ([330558d](https://github.com/gitpod-io/gitpod-sdk-python/commit/330558de3704863336c8b0bce5559237ef2d0e79)) +* **internal:** formatting ([ecb24f2](https://github.com/gitpod-io/gitpod-sdk-python/commit/ecb24f297e892aecf91c294594f062c0baf6f8f5)) +* update OpenAPI spec to e50946de8cddc549be7f7423903ad444632abce6 ([1176fce](https://github.com/gitpod-io/gitpod-sdk-python/commit/1176fce9b14b0bf657282228a20c222b2cb14ea5)) + + +### Documentation + +* **api:** clarify port_sharing_disabled behavior in organization policy ([2154cd8](https://github.com/gitpod-io/gitpod-sdk-python/commit/2154cd8abfa221c6c5aa4af9e85919fc927d888e)) + ## 0.7.0 (2026-01-21) Full Changelog: [v0.6.0...v0.7.0](https://github.com/gitpod-io/gitpod-sdk-python/compare/v0.6.0...v0.7.0) diff --git a/api.md b/api.md index 0b70b7bf..ce41da2a 100644 --- a/api.md +++ b/api.md @@ -121,6 +121,8 @@ from gitpod.types import ( EnvironmentRole, EnvironmentSpec, EnvironmentStatus, + KernelControlsConfig, + Veto, EnvironmentCreateResponse, EnvironmentRetrieveResponse, EnvironmentCreateEnvironmentTokenResponse, @@ -365,6 +367,23 @@ Methods: - client.organizations.list_members(\*\*params) -> SyncMembersPage[OrganizationMember] - client.organizations.set_role(\*\*params) -> object +## AnnouncementBanner + +Types: + +```python +from gitpod.types.organizations import ( + AnnouncementBanner, + AnnouncementBannerUpdateResponse, + AnnouncementBannerGetResponse, +) +``` + +Methods: + +- client.organizations.announcement_banner.update(\*\*params) -> AnnouncementBannerUpdateResponse +- client.organizations.announcement_banner.get(\*\*params) -> AnnouncementBannerGetResponse + ## CustomDomains Types: @@ -435,6 +454,7 @@ Types: from gitpod.types.organizations import ( AgentPolicy, CrowdStrikeConfig, + ExecutableDenyList, OrganizationPolicies, SecurityAgentPolicy, PolicyRetrieveResponse, @@ -475,6 +495,7 @@ Types: ```python from gitpod.types.organizations import ( + AdditionalScopesUpdate, ProviderType, SSOConfiguration, SSOConfigurationState, diff --git a/pyproject.toml b/pyproject.toml index 4f4d826f..6e89f84a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "gitpod-sdk" -version = "0.7.0" +version = "0.8.0" description = "The official Python library for the gitpod API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/requirements-dev.lock b/requirements-dev.lock index 7e743238..08e698e6 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -12,15 +12,15 @@ -e file:. aiohappyeyeballs==2.6.1 # via aiohttp -aiohttp==3.13.2 +aiohttp==3.13.3 # via gitpod-sdk # via httpx-aiohttp aiosignal==1.4.0 # via aiohttp annotated-types==0.7.0 # via pydantic -anthropic==0.45.2 -anyio==4.4.0 +anthropic==0.79.0 +anyio==4.12.1 # via anthropic # via gitpod-sdk # via httpx @@ -30,25 +30,32 @@ async-timeout==5.0.1 # via aiohttp attrs==25.4.0 # via aiohttp -bcrypt==4.2.1 + # via nox +backports-asyncio-runner==1.2.0 + # via pytest-asyncio +bcrypt==5.0.0 # via paramiko -certifi==2023.7.22 +certifi==2026.1.4 # via httpcore # via httpx -cffi==1.17.1 +cffi==2.0.0 # via cryptography # via pynacl -colorlog==6.7.0 +colorlog==6.10.1 # via nox -cryptography==44.0.1 +cryptography==46.0.5 # via paramiko # via types-paramiko -dirty-equals==0.6.0 -distlib==0.3.7 +dependency-groups==1.3.1 + # via nox +dirty-equals==0.11 +distlib==0.4.0 # via virtualenv -distro==1.8.0 +distro==1.9.0 # via anthropic # via gitpod-sdk +docstring-parser==0.17.0 + # via anthropic exceptiongroup==1.3.1 # via anyio # via pytest @@ -68,7 +75,7 @@ httpx==0.28.1 # via gitpod-sdk # via httpx-aiohttp # via respx -httpx-aiohttp==0.1.9 +httpx-aiohttp==0.1.12 # via gitpod-sdk humanize==4.13.0 # via nox @@ -76,10 +83,12 @@ idna==3.11 # via anyio # via httpx # via yarl -importlib-metadata==8.7.0 +importlib-metadata==8.7.1 iniconfig==2.1.0 # via pytest -jiter==0.8.2 +invoke==2.2.1 + # via paramiko +jiter==0.13.0 # via anthropic markdown-it-py==3.0.0 # via rich @@ -91,33 +100,34 @@ multidict==6.7.0 mypy==1.17.0 mypy-extensions==1.1.0 # via mypy -nodeenv==1.9.1 +nodeenv==1.10.0 # via pyright nox==2025.11.12 packaging==25.0 # via dependency-groups # via nox # via pytest -pathspec==0.12.1 +paramiko==4.0.0 +pathspec==1.0.3 # via mypy -paramiko==3.5.1 -platformdirs==3.11.0 +platformdirs==4.4.0 # via virtualenv pluggy==1.6.0 # via pytest propcache==0.4.1 # via aiohttp # via yarl -pydantic==2.11.9 - # via anthropic -pycparser==2.22 +pycparser==2.23 # via cffi -pydantic-core==2.33.2 +pydantic==2.12.5 + # via anthropic + # via gitpod-sdk +pydantic-core==2.41.5 # via pydantic pygments==2.19.2 # via pytest # via rich -pynacl==1.5.0 +pynacl==1.6.2 # via paramiko pyright==1.1.399 pytest==8.4.2 @@ -129,23 +139,24 @@ python-dateutil==2.9.0.post0 # via time-machine respx==0.22.0 rich==14.2.0 -ruff==0.14.7 +ruff==0.14.13 six==1.17.0 # via python-dateutil -sniffio==1.3.0 +sniffio==1.3.1 # via anthropic - # via anyio # via gitpod-sdk time-machine==2.19.0 -tomli==2.3.0 +tomli==2.4.0 # via dependency-groups # via mypy # via nox # via pytest -types-paramiko==3.5.0.20240928 -typing-extensions==4.12.2 +types-paramiko==4.0.0.20250822 +typing-extensions==4.15.0 + # via aiosignal # via anthropic # via anyio + # via cryptography # via exceptiongroup # via gitpod-sdk # via multidict @@ -158,7 +169,7 @@ typing-extensions==4.12.2 # via virtualenv typing-inspection==0.4.2 # via pydantic -virtualenv==20.35.4 +virtualenv==20.36.1 # via nox yarl==1.22.0 # via aiohttp diff --git a/requirements.lock b/requirements.lock index 73d1ab78..009f1a16 100644 --- a/requirements.lock +++ b/requirements.lock @@ -12,21 +12,21 @@ -e file:. aiohappyeyeballs==2.6.1 # via aiohttp -aiohttp==3.13.2 +aiohttp==3.13.3 # via gitpod-sdk # via httpx-aiohttp aiosignal==1.4.0 # via aiohttp annotated-types==0.7.0 # via pydantic -anyio==4.12.0 +anyio==4.12.1 # via gitpod-sdk # via httpx async-timeout==5.0.1 # via aiohttp attrs==25.4.0 # via aiohttp -certifi==2025.11.12 +certifi==2026.1.4 # via httpcore # via httpx distro==1.9.0 @@ -43,7 +43,7 @@ httpcore==1.0.9 httpx==0.28.1 # via gitpod-sdk # via httpx-aiohttp -httpx-aiohttp==0.1.9 +httpx-aiohttp==0.1.12 # via gitpod-sdk idna==3.11 # via anyio diff --git a/src/gitpod/_base_client.py b/src/gitpod/_base_client.py index e6ccedfa..cc7f8af2 100644 --- a/src/gitpod/_base_client.py +++ b/src/gitpod/_base_client.py @@ -86,6 +86,7 @@ APIConnectionError, APIResponseValidationError, ) +from ._utils._json import openapi_dumps log: logging.Logger = logging.getLogger(__name__) @@ -554,8 +555,10 @@ def _build_request( kwargs["content"] = options.content elif isinstance(json_data, bytes): kwargs["content"] = json_data - else: - kwargs["json"] = json_data if is_given(json_data) else None + elif not files: + # Don't set content when JSON is sent as multipart/form-data, + # since httpx's content param overrides other body arguments + kwargs["content"] = openapi_dumps(json_data) if is_given(json_data) and json_data is not None else None kwargs["files"] = files else: headers.pop("Content-Type", None) diff --git a/src/gitpod/_compat.py b/src/gitpod/_compat.py index bdef67f0..786ff42a 100644 --- a/src/gitpod/_compat.py +++ b/src/gitpod/_compat.py @@ -139,6 +139,7 @@ def model_dump( exclude_defaults: bool = False, warnings: bool = True, mode: Literal["json", "python"] = "python", + by_alias: bool | None = None, ) -> dict[str, Any]: if (not PYDANTIC_V1) or hasattr(model, "model_dump"): return model.model_dump( @@ -148,13 +149,12 @@ def model_dump( exclude_defaults=exclude_defaults, # warnings are not supported in Pydantic v1 warnings=True if PYDANTIC_V1 else warnings, + by_alias=by_alias, ) return cast( "dict[str, Any]", model.dict( # pyright: ignore[reportDeprecated, reportUnnecessaryCast] - exclude=exclude, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, + exclude=exclude, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, by_alias=bool(by_alias) ), ) diff --git a/src/gitpod/_utils/_json.py b/src/gitpod/_utils/_json.py new file mode 100644 index 00000000..60584214 --- /dev/null +++ b/src/gitpod/_utils/_json.py @@ -0,0 +1,35 @@ +import json +from typing import Any +from datetime import datetime +from typing_extensions import override + +import pydantic + +from .._compat import model_dump + + +def openapi_dumps(obj: Any) -> bytes: + """ + Serialize an object to UTF-8 encoded JSON bytes. + + Extends the standard json.dumps with support for additional types + commonly used in the SDK, such as `datetime`, `pydantic.BaseModel`, etc. + """ + return json.dumps( + obj, + cls=_CustomEncoder, + # Uses the same defaults as httpx's JSON serialization + ensure_ascii=False, + separators=(",", ":"), + allow_nan=False, + ).encode() + + +class _CustomEncoder(json.JSONEncoder): + @override + def default(self, o: Any) -> Any: + if isinstance(o, datetime): + return o.isoformat() + if isinstance(o, pydantic.BaseModel): + return model_dump(o, exclude_unset=True, mode="json", by_alias=True) + return super().default(o) diff --git a/src/gitpod/_version.py b/src/gitpod/_version.py index 88739dd6..58df5031 100644 --- a/src/gitpod/_version.py +++ b/src/gitpod/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "gitpod" -__version__ = "0.7.0" # x-release-please-version +__version__ = "0.8.0" # x-release-please-version diff --git a/src/gitpod/resources/agents.py b/src/gitpod/resources/agents.py index 9c2e9d18..3206d8ce 100644 --- a/src/gitpod/resources/agents.py +++ b/src/gitpod/resources/agents.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Optional +from typing import Dict, Optional import httpx @@ -537,9 +537,11 @@ def start_execution( self, *, agent_id: str | Omit = omit, + annotations: Dict[str, str] | Omit = omit, code_context: AgentCodeContextParam | Omit = omit, mode: AgentMode | Omit = omit, name: str | Omit = omit, + runner_id: str | Omit = omit, workflow_action_id: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -566,9 +568,17 @@ def start_execution( ``` Args: + annotations: annotations are key-value pairs for tracking external context (e.g., Linear + session IDs, GitHub issue references). Keys should follow domain/name convention + (e.g., "linear.app/session-id"). + mode: mode specifies the operational mode for this agent execution If not specified, defaults to AGENT_MODE_EXECUTION + runner_id: runner_id specifies a runner for this agent execution. When set, the agent + execution is routed to this runner instead of the runner associated with the + environment. + workflow_action_id: workflow_action_id is an optional reference to the workflow execution action that created this agent execution. Used for tracking and event correlation. @@ -585,9 +595,11 @@ def start_execution( body=maybe_transform( { "agent_id": agent_id, + "annotations": annotations, "code_context": code_context, "mode": mode, "name": name, + "runner_id": runner_id, "workflow_action_id": workflow_action_id, }, agent_start_execution_params.AgentStartExecutionParams, @@ -1191,9 +1203,11 @@ async def start_execution( self, *, agent_id: str | Omit = omit, + annotations: Dict[str, str] | Omit = omit, code_context: AgentCodeContextParam | Omit = omit, mode: AgentMode | Omit = omit, name: str | Omit = omit, + runner_id: str | Omit = omit, workflow_action_id: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -1220,9 +1234,17 @@ async def start_execution( ``` Args: + annotations: annotations are key-value pairs for tracking external context (e.g., Linear + session IDs, GitHub issue references). Keys should follow domain/name convention + (e.g., "linear.app/session-id"). + mode: mode specifies the operational mode for this agent execution If not specified, defaults to AGENT_MODE_EXECUTION + runner_id: runner_id specifies a runner for this agent execution. When set, the agent + execution is routed to this runner instead of the runner associated with the + environment. + workflow_action_id: workflow_action_id is an optional reference to the workflow execution action that created this agent execution. Used for tracking and event correlation. @@ -1239,9 +1261,11 @@ async def start_execution( body=await async_maybe_transform( { "agent_id": agent_id, + "annotations": annotations, "code_context": code_context, "mode": mode, "name": name, + "runner_id": runner_id, "workflow_action_id": workflow_action_id, }, agent_start_execution_params.AgentStartExecutionParams, diff --git a/src/gitpod/resources/environments/environments.py b/src/gitpod/resources/environments/environments.py index 6de9f762..3f5defc8 100644 --- a/src/gitpod/resources/environments/environments.py +++ b/src/gitpod/resources/environments/environments.py @@ -91,6 +91,7 @@ def with_streaming_response(self) -> EnvironmentsResourceWithStreamingResponse: def create( self, *, + name: Optional[str] | Omit = omit, spec: EnvironmentSpecParam | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -164,6 +165,9 @@ def create( ``` Args: + name: name is a user-defined identifier for the environment. If not specified, the + system will generate a name. + spec: spec is the configuration of the environment that's required for the to start the environment @@ -177,7 +181,13 @@ def create( """ return self._post( "/gitpod.v1.EnvironmentService/CreateEnvironment", - body=maybe_transform({"spec": spec}, environment_create_params.EnvironmentCreateParams), + body=maybe_transform( + { + "name": name, + "spec": spec, + }, + environment_create_params.EnvironmentCreateParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -549,6 +559,7 @@ def create_environment_token( def create_from_project( self, *, + name: Optional[str] | Omit = omit, project_id: str | Omit = omit, spec: EnvironmentSpecParam | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -591,6 +602,9 @@ def create_from_project( ``` Args: + name: name is a user-defined identifier for the environment. If not specified, the + system will generate a name. + spec: Spec is the configuration of the environment that's required for the runner to start the environment Configuration already defined in the Project will override parts of the spec, if set @@ -607,6 +621,7 @@ def create_from_project( "/gitpod.v1.EnvironmentService/CreateEnvironmentFromProject", body=maybe_transform( { + "name": name, "project_id": project_id, "spec": spec, }, @@ -905,6 +920,7 @@ def with_streaming_response(self) -> AsyncEnvironmentsResourceWithStreamingRespo async def create( self, *, + name: Optional[str] | Omit = omit, spec: EnvironmentSpecParam | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -978,6 +994,9 @@ async def create( ``` Args: + name: name is a user-defined identifier for the environment. If not specified, the + system will generate a name. + spec: spec is the configuration of the environment that's required for the to start the environment @@ -991,7 +1010,13 @@ async def create( """ return await self._post( "/gitpod.v1.EnvironmentService/CreateEnvironment", - body=await async_maybe_transform({"spec": spec}, environment_create_params.EnvironmentCreateParams), + body=await async_maybe_transform( + { + "name": name, + "spec": spec, + }, + environment_create_params.EnvironmentCreateParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1363,6 +1388,7 @@ async def create_environment_token( async def create_from_project( self, *, + name: Optional[str] | Omit = omit, project_id: str | Omit = omit, spec: EnvironmentSpecParam | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -1405,6 +1431,9 @@ async def create_from_project( ``` Args: + name: name is a user-defined identifier for the environment. If not specified, the + system will generate a name. + spec: Spec is the configuration of the environment that's required for the runner to start the environment Configuration already defined in the Project will override parts of the spec, if set @@ -1421,6 +1450,7 @@ async def create_from_project( "/gitpod.v1.EnvironmentService/CreateEnvironmentFromProject", body=await async_maybe_transform( { + "name": name, "project_id": project_id, "spec": spec, }, diff --git a/src/gitpod/resources/organizations/__init__.py b/src/gitpod/resources/organizations/__init__.py index 21debecf..c0a5e791 100644 --- a/src/gitpod/resources/organizations/__init__.py +++ b/src/gitpod/resources/organizations/__init__.py @@ -40,6 +40,14 @@ SSOConfigurationsResourceWithStreamingResponse, AsyncSSOConfigurationsResourceWithStreamingResponse, ) +from .announcement_banner import ( + AnnouncementBannerResource, + AsyncAnnouncementBannerResource, + AnnouncementBannerResourceWithRawResponse, + AsyncAnnouncementBannerResourceWithRawResponse, + AnnouncementBannerResourceWithStreamingResponse, + AsyncAnnouncementBannerResourceWithStreamingResponse, +) from .scim_configurations import ( ScimConfigurationsResource, AsyncScimConfigurationsResource, @@ -58,6 +66,12 @@ ) __all__ = [ + "AnnouncementBannerResource", + "AsyncAnnouncementBannerResource", + "AnnouncementBannerResourceWithRawResponse", + "AsyncAnnouncementBannerResourceWithRawResponse", + "AnnouncementBannerResourceWithStreamingResponse", + "AsyncAnnouncementBannerResourceWithStreamingResponse", "CustomDomainsResource", "AsyncCustomDomainsResource", "CustomDomainsResourceWithRawResponse", diff --git a/src/gitpod/resources/organizations/announcement_banner.py b/src/gitpod/resources/organizations/announcement_banner.py new file mode 100644 index 00000000..e8ab3a97 --- /dev/null +++ b/src/gitpod/resources/organizations/announcement_banner.py @@ -0,0 +1,342 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional + +import httpx + +from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ..._utils import maybe_transform, async_maybe_transform +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..._base_client import make_request_options +from ...types.organizations import announcement_banner_get_params, announcement_banner_update_params +from ...types.organizations.announcement_banner_get_response import AnnouncementBannerGetResponse +from ...types.organizations.announcement_banner_update_response import AnnouncementBannerUpdateResponse + +__all__ = ["AnnouncementBannerResource", "AsyncAnnouncementBannerResource"] + + +class AnnouncementBannerResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> AnnouncementBannerResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#accessing-raw-response-data-eg-headers + """ + return AnnouncementBannerResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AnnouncementBannerResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#with_streaming_response + """ + return AnnouncementBannerResourceWithStreamingResponse(self) + + def update( + self, + *, + organization_id: str, + enabled: Optional[bool] | Omit = omit, + message: Optional[str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AnnouncementBannerUpdateResponse: + """ + Updates the announcement banner configuration for an organization. + + Use this method to configure the announcement banner displayed to all users. + Only organization admins can update the banner. Requires Enterprise tier. + + ### Examples + + - Enable announcement banner: + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + message: "Scheduled maintenance on Saturday 10pm-2am UTC" + enabled: true + ``` + + - Disable announcement banner: + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + enabled: false + ``` + + Args: + organization_id: organization_id is the ID of the organization + + enabled: enabled controls whether the banner is displayed + + message: message is the banner message. Supports basic Markdown. Maximum 1000 characters. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.OrganizationService/UpdateAnnouncementBanner", + body=maybe_transform( + { + "organization_id": organization_id, + "enabled": enabled, + "message": message, + }, + announcement_banner_update_params.AnnouncementBannerUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AnnouncementBannerUpdateResponse, + ) + + def get( + self, + *, + organization_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AnnouncementBannerGetResponse: + """ + Retrieves the announcement banner configuration for an organization. + + Use this method to fetch the current announcement banner settings. All + organization members can read the banner configuration. + + ### Examples + + - Get announcement banner: + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + ``` + + Args: + organization_id: organization_id is the ID of the organization + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.OrganizationService/GetAnnouncementBanner", + body=maybe_transform( + {"organization_id": organization_id}, announcement_banner_get_params.AnnouncementBannerGetParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AnnouncementBannerGetResponse, + ) + + +class AsyncAnnouncementBannerResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncAnnouncementBannerResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncAnnouncementBannerResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAnnouncementBannerResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#with_streaming_response + """ + return AsyncAnnouncementBannerResourceWithStreamingResponse(self) + + async def update( + self, + *, + organization_id: str, + enabled: Optional[bool] | Omit = omit, + message: Optional[str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AnnouncementBannerUpdateResponse: + """ + Updates the announcement banner configuration for an organization. + + Use this method to configure the announcement banner displayed to all users. + Only organization admins can update the banner. Requires Enterprise tier. + + ### Examples + + - Enable announcement banner: + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + message: "Scheduled maintenance on Saturday 10pm-2am UTC" + enabled: true + ``` + + - Disable announcement banner: + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + enabled: false + ``` + + Args: + organization_id: organization_id is the ID of the organization + + enabled: enabled controls whether the banner is displayed + + message: message is the banner message. Supports basic Markdown. Maximum 1000 characters. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/gitpod.v1.OrganizationService/UpdateAnnouncementBanner", + body=await async_maybe_transform( + { + "organization_id": organization_id, + "enabled": enabled, + "message": message, + }, + announcement_banner_update_params.AnnouncementBannerUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AnnouncementBannerUpdateResponse, + ) + + async def get( + self, + *, + organization_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AnnouncementBannerGetResponse: + """ + Retrieves the announcement banner configuration for an organization. + + Use this method to fetch the current announcement banner settings. All + organization members can read the banner configuration. + + ### Examples + + - Get announcement banner: + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + ``` + + Args: + organization_id: organization_id is the ID of the organization + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/gitpod.v1.OrganizationService/GetAnnouncementBanner", + body=await async_maybe_transform( + {"organization_id": organization_id}, announcement_banner_get_params.AnnouncementBannerGetParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AnnouncementBannerGetResponse, + ) + + +class AnnouncementBannerResourceWithRawResponse: + def __init__(self, announcement_banner: AnnouncementBannerResource) -> None: + self._announcement_banner = announcement_banner + + self.update = to_raw_response_wrapper( + announcement_banner.update, + ) + self.get = to_raw_response_wrapper( + announcement_banner.get, + ) + + +class AsyncAnnouncementBannerResourceWithRawResponse: + def __init__(self, announcement_banner: AsyncAnnouncementBannerResource) -> None: + self._announcement_banner = announcement_banner + + self.update = async_to_raw_response_wrapper( + announcement_banner.update, + ) + self.get = async_to_raw_response_wrapper( + announcement_banner.get, + ) + + +class AnnouncementBannerResourceWithStreamingResponse: + def __init__(self, announcement_banner: AnnouncementBannerResource) -> None: + self._announcement_banner = announcement_banner + + self.update = to_streamed_response_wrapper( + announcement_banner.update, + ) + self.get = to_streamed_response_wrapper( + announcement_banner.get, + ) + + +class AsyncAnnouncementBannerResourceWithStreamingResponse: + def __init__(self, announcement_banner: AsyncAnnouncementBannerResource) -> None: + self._announcement_banner = announcement_banner + + self.update = async_to_streamed_response_wrapper( + announcement_banner.update, + ) + self.get = async_to_streamed_response_wrapper( + announcement_banner.get, + ) diff --git a/src/gitpod/resources/organizations/organizations.py b/src/gitpod/resources/organizations/organizations.py index c45b8a54..d1a9f666 100644 --- a/src/gitpod/resources/organizations/organizations.py +++ b/src/gitpod/resources/organizations/organizations.py @@ -60,6 +60,14 @@ SSOConfigurationsResourceWithStreamingResponse, AsyncSSOConfigurationsResourceWithStreamingResponse, ) +from .announcement_banner import ( + AnnouncementBannerResource, + AsyncAnnouncementBannerResource, + AnnouncementBannerResourceWithRawResponse, + AsyncAnnouncementBannerResourceWithRawResponse, + AnnouncementBannerResourceWithStreamingResponse, + AsyncAnnouncementBannerResourceWithStreamingResponse, +) from .scim_configurations import ( ScimConfigurationsResource, AsyncScimConfigurationsResource, @@ -88,6 +96,10 @@ class OrganizationsResource(SyncAPIResource): + @cached_property + def announcement_banner(self) -> AnnouncementBannerResource: + return AnnouncementBannerResource(self._client) + @cached_property def custom_domains(self) -> CustomDomainsResource: return CustomDomainsResource(self._client) @@ -678,6 +690,10 @@ def set_role( class AsyncOrganizationsResource(AsyncAPIResource): + @cached_property + def announcement_banner(self) -> AsyncAnnouncementBannerResource: + return AsyncAnnouncementBannerResource(self._client) + @cached_property def custom_domains(self) -> AsyncCustomDomainsResource: return AsyncCustomDomainsResource(self._client) @@ -1296,6 +1312,10 @@ def __init__(self, organizations: OrganizationsResource) -> None: organizations.set_role, ) + @cached_property + def announcement_banner(self) -> AnnouncementBannerResourceWithRawResponse: + return AnnouncementBannerResourceWithRawResponse(self._organizations.announcement_banner) + @cached_property def custom_domains(self) -> CustomDomainsResourceWithRawResponse: return CustomDomainsResourceWithRawResponse(self._organizations.custom_domains) @@ -1350,6 +1370,10 @@ def __init__(self, organizations: AsyncOrganizationsResource) -> None: organizations.set_role, ) + @cached_property + def announcement_banner(self) -> AsyncAnnouncementBannerResourceWithRawResponse: + return AsyncAnnouncementBannerResourceWithRawResponse(self._organizations.announcement_banner) + @cached_property def custom_domains(self) -> AsyncCustomDomainsResourceWithRawResponse: return AsyncCustomDomainsResourceWithRawResponse(self._organizations.custom_domains) @@ -1404,6 +1428,10 @@ def __init__(self, organizations: OrganizationsResource) -> None: organizations.set_role, ) + @cached_property + def announcement_banner(self) -> AnnouncementBannerResourceWithStreamingResponse: + return AnnouncementBannerResourceWithStreamingResponse(self._organizations.announcement_banner) + @cached_property def custom_domains(self) -> CustomDomainsResourceWithStreamingResponse: return CustomDomainsResourceWithStreamingResponse(self._organizations.custom_domains) @@ -1458,6 +1486,10 @@ def __init__(self, organizations: AsyncOrganizationsResource) -> None: organizations.set_role, ) + @cached_property + def announcement_banner(self) -> AsyncAnnouncementBannerResourceWithStreamingResponse: + return AsyncAnnouncementBannerResourceWithStreamingResponse(self._organizations.announcement_banner) + @cached_property def custom_domains(self) -> AsyncCustomDomainsResourceWithStreamingResponse: return AsyncCustomDomainsResourceWithStreamingResponse(self._organizations.custom_domains) diff --git a/src/gitpod/resources/organizations/policies.py b/src/gitpod/resources/organizations/policies.py index 93b785e9..28d2142d 100644 --- a/src/gitpod/resources/organizations/policies.py +++ b/src/gitpod/resources/organizations/policies.py @@ -19,6 +19,7 @@ from ..._base_client import make_request_options from ...types.organizations import policy_update_params, policy_retrieve_params from ...types.organizations.policy_retrieve_response import PolicyRetrieveResponse +from ...types.organizations.executable_deny_list_param import ExecutableDenyListParam __all__ = ["PoliciesResource", "AsyncPoliciesResource"] @@ -104,6 +105,7 @@ def update( default_environment_image: Optional[str] | Omit = omit, delete_archived_environments_after: Optional[str] | Omit = omit, editor_version_restrictions: Dict[str, policy_update_params.EditorVersionRestrictions] | Omit = omit, + executable_deny_list: Optional[ExecutableDenyListParam] | Omit = omit, maximum_environment_lifetime: Optional[str] | Omit = omit, maximum_environments_per_user: Optional[str] | Omit = omit, maximum_environment_timeout: Optional[str] | Omit = omit, @@ -112,6 +114,7 @@ def update( members_require_projects: Optional[bool] | Omit = omit, port_sharing_disabled: Optional[bool] | Omit = omit, require_custom_domain_access: Optional[bool] | Omit = omit, + restrict_account_creation_to_scim: Optional[bool] | Omit = omit, security_agent_policy: Optional[policy_update_params.SecurityAgentPolicy] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -179,6 +182,9 @@ def update( editor_version_restrictions: editor_version_restrictions restricts which editor versions can be used. Maps editor ID to version policy with allowed major versions. + executable_deny_list: executable_deny_list contains executables that are blocked from execution in + environments. + maximum_environment_lifetime: maximum_environment_lifetime controls for how long environments are allowed to be reused. 0 means no maximum lifetime. Maximum duration is 180 days (15552000 seconds). @@ -198,12 +204,17 @@ def update( members_require_projects: members_require_projects controls whether environments can only be created from projects by non-admin users - port_sharing_disabled: port_sharing_disabled controls whether port sharing is disabled in the - organization + port_sharing_disabled: port_sharing_disabled controls whether user-initiated port sharing is disabled + in the organization. System ports (VS Code Browser, agents) are always exempt + from this policy. require_custom_domain_access: require_custom_domain_access controls whether users must access via custom domain when one is configured. When true, access via app.gitpod.io is blocked. + restrict_account_creation_to_scim: restrict_account_creation_to_scim controls whether account creation is + restricted to SCIM-provisioned users only. When true and SCIM is configured for + the organization, only users provisioned via SCIM can create accounts. + security_agent_policy: security_agent_policy contains security agent configuration updates extra_headers: Send extra headers @@ -226,6 +237,7 @@ def update( "default_environment_image": default_environment_image, "delete_archived_environments_after": delete_archived_environments_after, "editor_version_restrictions": editor_version_restrictions, + "executable_deny_list": executable_deny_list, "maximum_environment_lifetime": maximum_environment_lifetime, "maximum_environments_per_user": maximum_environments_per_user, "maximum_environment_timeout": maximum_environment_timeout, @@ -234,6 +246,7 @@ def update( "members_require_projects": members_require_projects, "port_sharing_disabled": port_sharing_disabled, "require_custom_domain_access": require_custom_domain_access, + "restrict_account_creation_to_scim": restrict_account_creation_to_scim, "security_agent_policy": security_agent_policy, }, policy_update_params.PolicyUpdateParams, @@ -328,6 +341,7 @@ async def update( default_environment_image: Optional[str] | Omit = omit, delete_archived_environments_after: Optional[str] | Omit = omit, editor_version_restrictions: Dict[str, policy_update_params.EditorVersionRestrictions] | Omit = omit, + executable_deny_list: Optional[ExecutableDenyListParam] | Omit = omit, maximum_environment_lifetime: Optional[str] | Omit = omit, maximum_environments_per_user: Optional[str] | Omit = omit, maximum_environment_timeout: Optional[str] | Omit = omit, @@ -336,6 +350,7 @@ async def update( members_require_projects: Optional[bool] | Omit = omit, port_sharing_disabled: Optional[bool] | Omit = omit, require_custom_domain_access: Optional[bool] | Omit = omit, + restrict_account_creation_to_scim: Optional[bool] | Omit = omit, security_agent_policy: Optional[policy_update_params.SecurityAgentPolicy] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -403,6 +418,9 @@ async def update( editor_version_restrictions: editor_version_restrictions restricts which editor versions can be used. Maps editor ID to version policy with allowed major versions. + executable_deny_list: executable_deny_list contains executables that are blocked from execution in + environments. + maximum_environment_lifetime: maximum_environment_lifetime controls for how long environments are allowed to be reused. 0 means no maximum lifetime. Maximum duration is 180 days (15552000 seconds). @@ -422,12 +440,17 @@ async def update( members_require_projects: members_require_projects controls whether environments can only be created from projects by non-admin users - port_sharing_disabled: port_sharing_disabled controls whether port sharing is disabled in the - organization + port_sharing_disabled: port_sharing_disabled controls whether user-initiated port sharing is disabled + in the organization. System ports (VS Code Browser, agents) are always exempt + from this policy. require_custom_domain_access: require_custom_domain_access controls whether users must access via custom domain when one is configured. When true, access via app.gitpod.io is blocked. + restrict_account_creation_to_scim: restrict_account_creation_to_scim controls whether account creation is + restricted to SCIM-provisioned users only. When true and SCIM is configured for + the organization, only users provisioned via SCIM can create accounts. + security_agent_policy: security_agent_policy contains security agent configuration updates extra_headers: Send extra headers @@ -450,6 +473,7 @@ async def update( "default_environment_image": default_environment_image, "delete_archived_environments_after": delete_archived_environments_after, "editor_version_restrictions": editor_version_restrictions, + "executable_deny_list": executable_deny_list, "maximum_environment_lifetime": maximum_environment_lifetime, "maximum_environments_per_user": maximum_environments_per_user, "maximum_environment_timeout": maximum_environment_timeout, @@ -458,6 +482,7 @@ async def update( "members_require_projects": members_require_projects, "port_sharing_disabled": port_sharing_disabled, "require_custom_domain_access": require_custom_domain_access, + "restrict_account_creation_to_scim": restrict_account_creation_to_scim, "security_agent_policy": security_agent_policy, }, policy_update_params.PolicyUpdateParams, diff --git a/src/gitpod/resources/organizations/scim_configurations.py b/src/gitpod/resources/organizations/scim_configurations.py index 529ae165..6176c402 100644 --- a/src/gitpod/resources/organizations/scim_configurations.py +++ b/src/gitpod/resources/organizations/scim_configurations.py @@ -61,6 +61,7 @@ def create( organization_id: str, sso_configuration_id: str, name: Optional[str] | Omit = omit, + token_expires_in: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -81,13 +82,24 @@ def create( - Create basic SCIM configuration: - Creates a SCIM configuration linked to an SSO provider. + Creates a SCIM configuration linked to an SSO provider with default 1 year + token expiration. ```yaml organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" ssoConfigurationId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" ``` + - Create SCIM configuration with custom token expiration: + + Creates a SCIM configuration with a 90-day token expiration. + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + ssoConfigurationId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + tokenExpiresIn: "7776000s" + ``` + Args: organization_id: organization_id is the ID of the organization to create the SCIM configuration for @@ -97,6 +109,9 @@ def create( name: name is a human-readable name for the SCIM configuration + token_expires_in: token_expires_in is the duration until the token expires. Defaults to 1 year. + Minimum 1 day, maximum 2 years. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -112,6 +127,7 @@ def create( "organization_id": organization_id, "sso_configuration_id": sso_configuration_id, "name": name, + "token_expires_in": token_expires_in, }, scim_configuration_create_params.ScimConfigurationCreateParams, ), @@ -373,6 +389,7 @@ def regenerate_token( self, *, scim_configuration_id: str, + token_expires_in: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -393,16 +410,29 @@ def regenerate_token( - Regenerate token: - Creates a new bearer token, invalidating the old one. + Creates a new bearer token with the same expiration duration as the previous + token. ```yaml scimConfigurationId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" ``` + - Regenerate token with new expiration: + + Creates a new bearer token with a custom 180-day expiration. + + ```yaml + scimConfigurationId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + tokenExpiresIn: "15552000s" + ``` + Args: scim_configuration_id: scim_configuration_id is the ID of the SCIM configuration to regenerate token for + token_expires_in: token_expires_in is the duration until the new token expires. If not specified, + uses the same duration as the previous token. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -414,7 +444,10 @@ def regenerate_token( return self._post( "/gitpod.v1.OrganizationService/RegenerateSCIMToken", body=maybe_transform( - {"scim_configuration_id": scim_configuration_id}, + { + "scim_configuration_id": scim_configuration_id, + "token_expires_in": token_expires_in, + }, scim_configuration_regenerate_token_params.ScimConfigurationRegenerateTokenParams, ), options=make_request_options( @@ -450,6 +483,7 @@ async def create( organization_id: str, sso_configuration_id: str, name: Optional[str] | Omit = omit, + token_expires_in: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -470,13 +504,24 @@ async def create( - Create basic SCIM configuration: - Creates a SCIM configuration linked to an SSO provider. + Creates a SCIM configuration linked to an SSO provider with default 1 year + token expiration. ```yaml organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" ssoConfigurationId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" ``` + - Create SCIM configuration with custom token expiration: + + Creates a SCIM configuration with a 90-day token expiration. + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + ssoConfigurationId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + tokenExpiresIn: "7776000s" + ``` + Args: organization_id: organization_id is the ID of the organization to create the SCIM configuration for @@ -486,6 +531,9 @@ async def create( name: name is a human-readable name for the SCIM configuration + token_expires_in: token_expires_in is the duration until the token expires. Defaults to 1 year. + Minimum 1 day, maximum 2 years. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -501,6 +549,7 @@ async def create( "organization_id": organization_id, "sso_configuration_id": sso_configuration_id, "name": name, + "token_expires_in": token_expires_in, }, scim_configuration_create_params.ScimConfigurationCreateParams, ), @@ -762,6 +811,7 @@ async def regenerate_token( self, *, scim_configuration_id: str, + token_expires_in: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -782,16 +832,29 @@ async def regenerate_token( - Regenerate token: - Creates a new bearer token, invalidating the old one. + Creates a new bearer token with the same expiration duration as the previous + token. ```yaml scimConfigurationId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" ``` + - Regenerate token with new expiration: + + Creates a new bearer token with a custom 180-day expiration. + + ```yaml + scimConfigurationId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + tokenExpiresIn: "15552000s" + ``` + Args: scim_configuration_id: scim_configuration_id is the ID of the SCIM configuration to regenerate token for + token_expires_in: token_expires_in is the duration until the new token expires. If not specified, + uses the same duration as the previous token. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -803,7 +866,10 @@ async def regenerate_token( return await self._post( "/gitpod.v1.OrganizationService/RegenerateSCIMToken", body=await async_maybe_transform( - {"scim_configuration_id": scim_configuration_id}, + { + "scim_configuration_id": scim_configuration_id, + "token_expires_in": token_expires_in, + }, scim_configuration_regenerate_token_params.ScimConfigurationRegenerateTokenParams, ), options=make_request_options( diff --git a/src/gitpod/resources/organizations/sso_configurations.py b/src/gitpod/resources/organizations/sso_configurations.py index 7d9796cc..a6b0056b 100644 --- a/src/gitpod/resources/organizations/sso_configurations.py +++ b/src/gitpod/resources/organizations/sso_configurations.py @@ -28,6 +28,7 @@ ) from ...types.organizations.sso_configuration import SSOConfiguration from ...types.organizations.sso_configuration_state import SSOConfigurationState +from ...types.organizations.additional_scopes_update_param import AdditionalScopesUpdateParam from ...types.organizations.sso_configuration_create_response import SSOConfigurationCreateResponse from ...types.organizations.sso_configuration_retrieve_response import SSOConfigurationRetrieveResponse @@ -61,6 +62,7 @@ def create( client_secret: str, issuer_url: str, organization_id: str, + additional_scopes: SequenceNotStr[str] | Omit = omit, display_name: str | Omit = omit, email_domain: Optional[str] | Omit = omit, email_domains: SequenceNotStr[str] | Omit = omit, @@ -114,6 +116,10 @@ def create( issuer_url: issuer_url is the URL of the IdP issuer + additional_scopes: additional_scopes are extra OIDC scopes to request from the identity provider + during sign-in. These are appended to the default scopes (openid, email, + profile). + email_domain: email_domain is the domain that is allowed to sign in to the organization extra_headers: Send extra headers @@ -132,6 +138,7 @@ def create( "client_secret": client_secret, "issuer_url": issuer_url, "organization_id": organization_id, + "additional_scopes": additional_scopes, "display_name": display_name, "email_domain": email_domain, "email_domains": email_domains, @@ -201,6 +208,7 @@ def update( self, *, sso_configuration_id: str, + additional_scopes: Optional[AdditionalScopesUpdateParam] | Omit = omit, claims: Dict[str, str] | Omit = omit, client_id: Optional[str] | Omit = omit, client_secret: Optional[str] | Omit = omit, @@ -251,6 +259,10 @@ def update( Args: sso_configuration_id: sso_configuration_id is the ID of the SSO configuration to update + additional_scopes: additional_scopes replaces the configured OIDC scopes when present. When absent + (nil), scopes are left unchanged. When present with an empty scopes list, all + additional scopes are cleared. + claims: claims are key/value pairs that defines a mapping of claims issued by the IdP. client_id: client_id is the client ID of the SSO provider @@ -274,6 +286,7 @@ def update( body=maybe_transform( { "sso_configuration_id": sso_configuration_id, + "additional_scopes": additional_scopes, "claims": claims, "client_id": client_id, "client_secret": client_secret, @@ -455,6 +468,7 @@ async def create( client_secret: str, issuer_url: str, organization_id: str, + additional_scopes: SequenceNotStr[str] | Omit = omit, display_name: str | Omit = omit, email_domain: Optional[str] | Omit = omit, email_domains: SequenceNotStr[str] | Omit = omit, @@ -508,6 +522,10 @@ async def create( issuer_url: issuer_url is the URL of the IdP issuer + additional_scopes: additional_scopes are extra OIDC scopes to request from the identity provider + during sign-in. These are appended to the default scopes (openid, email, + profile). + email_domain: email_domain is the domain that is allowed to sign in to the organization extra_headers: Send extra headers @@ -526,6 +544,7 @@ async def create( "client_secret": client_secret, "issuer_url": issuer_url, "organization_id": organization_id, + "additional_scopes": additional_scopes, "display_name": display_name, "email_domain": email_domain, "email_domains": email_domains, @@ -595,6 +614,7 @@ async def update( self, *, sso_configuration_id: str, + additional_scopes: Optional[AdditionalScopesUpdateParam] | Omit = omit, claims: Dict[str, str] | Omit = omit, client_id: Optional[str] | Omit = omit, client_secret: Optional[str] | Omit = omit, @@ -645,6 +665,10 @@ async def update( Args: sso_configuration_id: sso_configuration_id is the ID of the SSO configuration to update + additional_scopes: additional_scopes replaces the configured OIDC scopes when present. When absent + (nil), scopes are left unchanged. When present with an empty scopes list, all + additional scopes are cleared. + claims: claims are key/value pairs that defines a mapping of claims issued by the IdP. client_id: client_id is the client ID of the SSO provider @@ -668,6 +692,7 @@ async def update( body=await async_maybe_transform( { "sso_configuration_id": sso_configuration_id, + "additional_scopes": additional_scopes, "claims": claims, "client_id": client_id, "client_secret": client_secret, diff --git a/src/gitpod/resources/secrets.py b/src/gitpod/resources/secrets.py index 6367df25..915a0c79 100644 --- a/src/gitpod/resources/secrets.py +++ b/src/gitpod/resources/secrets.py @@ -126,10 +126,10 @@ def create( secret file_path: absolute path to the file where the secret is mounted value must be an absolute - path (start with a /): + path (e.g. /path/to/file): ``` - this.matches("^/(?:[^/]*/)*.*$") + this.matches("^/[^/].*$") ``` project_id: project_id is the ProjectID this Secret belongs to Deprecated: use scope instead @@ -502,10 +502,10 @@ async def create( secret file_path: absolute path to the file where the secret is mounted value must be an absolute - path (start with a /): + path (e.g. /path/to/file): ``` - this.matches("^/(?:[^/]*/)*.*$") + this.matches("^/[^/].*$") ``` project_id: project_id is the ProjectID this Secret belongs to Deprecated: use scope instead diff --git a/src/gitpod/types/__init__.py b/src/gitpod/types/__init__.py index 4b195c70..b6f524e5 100644 --- a/src/gitpod/types/__init__.py +++ b/src/gitpod/types/__init__.py @@ -3,6 +3,7 @@ from __future__ import annotations from .user import User as User +from .veto import Veto as Veto from .group import Group as Group from .editor import Editor as Editor from .prompt import Prompt as Prompt @@ -41,6 +42,7 @@ from .prebuild import Prebuild as Prebuild from .log_level import LogLevel as LogLevel from .agent_mode import AgentMode as AgentMode +from .veto_param import VetoParam as VetoParam from .environment import Environment as Environment from .error_level import ErrorLevel as ErrorLevel from .prompt_spec import PromptSpec as PromptSpec @@ -120,6 +122,7 @@ from .project_update_params import ProjectUpdateParams as ProjectUpdateParams from .editor_retrieve_params import EditorRetrieveParams as EditorRetrieveParams from .environment_spec_param import EnvironmentSpecParam as EnvironmentSpecParam +from .kernel_controls_config import KernelControlsConfig as KernelControlsConfig from .prebuild_cancel_params import PrebuildCancelParams as PrebuildCancelParams from .prebuild_create_params import PrebuildCreateParams as PrebuildCreateParams from .prebuild_delete_params import PrebuildDeleteParams as PrebuildDeleteParams @@ -184,6 +187,7 @@ from .agent_update_prompt_response import AgentUpdatePromptResponse as AgentUpdatePromptResponse from .environment_unarchive_params import EnvironmentUnarchiveParams as EnvironmentUnarchiveParams from .identity_get_id_token_params import IdentityGetIDTokenParams as IdentityGetIDTokenParams +from .kernel_controls_config_param import KernelControlsConfigParam as KernelControlsConfigParam from .organization_create_response import OrganizationCreateResponse as OrganizationCreateResponse from .organization_retrieve_params import OrganizationRetrieveParams as OrganizationRetrieveParams from .organization_set_role_params import OrganizationSetRoleParams as OrganizationSetRoleParams diff --git a/src/gitpod/types/admission_level.py b/src/gitpod/types/admission_level.py index 40ee48da..cfa4ee41 100644 --- a/src/gitpod/types/admission_level.py +++ b/src/gitpod/types/admission_level.py @@ -5,5 +5,9 @@ __all__ = ["AdmissionLevel"] AdmissionLevel: TypeAlias = Literal[ - "ADMISSION_LEVEL_UNSPECIFIED", "ADMISSION_LEVEL_OWNER_ONLY", "ADMISSION_LEVEL_EVERYONE" + "ADMISSION_LEVEL_UNSPECIFIED", + "ADMISSION_LEVEL_OWNER_ONLY", + "ADMISSION_LEVEL_EVERYONE", + "ADMISSION_LEVEL_ORGANIZATION", + "ADMISSION_LEVEL_CREATOR_ONLY", ] diff --git a/src/gitpod/types/agent_execution.py b/src/gitpod/types/agent_execution.py index ad119381..ee64847f 100644 --- a/src/gitpod/types/agent_execution.py +++ b/src/gitpod/types/agent_execution.py @@ -20,6 +20,7 @@ "StatusCurrentOperation", "StatusCurrentOperationLlm", "StatusCurrentOperationToolUse", + "StatusMcpIntegrationStatus", "StatusOutputs", "StatusUsedEnvironment", ] @@ -31,6 +32,9 @@ class Metadata(BaseModel): parts of Gitpod to function """ + annotations: Optional[Dict[str, str]] = None + """annotations are key-value pairs for tracking external context.""" + created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None) """ A Timestamp represents a point in time independent of any time zone or local @@ -293,6 +297,39 @@ class StatusCurrentOperation(BaseModel): tool_use: Optional[StatusCurrentOperationToolUse] = FieldInfo(alias="toolUse", default=None) +class StatusMcpIntegrationStatus(BaseModel): + """ + MCPIntegrationStatus represents the status of a single MCP integration + within an agent execution context + """ + + id: Optional[str] = None + """id is the unique name of the MCP integration""" + + failure_message: Optional[str] = FieldInfo(alias="failureMessage", default=None) + """ + failure_message contains the reason the MCP integration failed to connect or + operate + """ + + name: Optional[str] = None + """name is the unique name of the MCP integration (e.g., "linear", "notion")""" + + phase: Optional[ + Literal[ + "MCP_INTEGRATION_PHASE_UNSPECIFIED", + "MCP_INTEGRATION_PHASE_INITIALIZING", + "MCP_INTEGRATION_PHASE_READY", + "MCP_INTEGRATION_PHASE_FAILED", + "MCP_INTEGRATION_PHASE_UNAVAILABLE", + ] + ] = None + """phase is the current connection/health phase""" + + warning_message: Optional[str] = FieldInfo(alias="warningMessage", default=None) + """warning_message contains warnings (e.g., rate limiting, degraded performance)""" + + class StatusOutputs(BaseModel): bool_value: Optional[bool] = FieldInfo(alias="boolValue", default=None) @@ -352,6 +389,14 @@ class Status(BaseModel): judgement: Optional[str] = None """judgement is the judgement of the agent run produced by the judgement prompt.""" + mcp_integration_statuses: Optional[List[StatusMcpIntegrationStatus]] = FieldInfo( + alias="mcpIntegrationStatuses", default=None + ) + """ + mcp_integration_statuses contains the status of all MCP integrations used by + this agent execution + """ + mode: Optional[AgentMode] = None """ mode is the current operational mode of the agent execution. This is set by the @@ -395,6 +440,8 @@ class Status(BaseModel): "SUPPORTED_MODEL_OPUS_4_EXTENDED", "SUPPORTED_MODEL_OPUS_4_5", "SUPPORTED_MODEL_OPUS_4_5_EXTENDED", + "SUPPORTED_MODEL_OPUS_4_6", + "SUPPORTED_MODEL_OPUS_4_6_EXTENDED", "SUPPORTED_MODEL_OPENAI_4O", "SUPPORTED_MODEL_OPENAI_4O_MINI", "SUPPORTED_MODEL_OPENAI_O1", diff --git a/src/gitpod/types/agent_list_executions_params.py b/src/gitpod/types/agent_list_executions_params.py index 3a613411..f01aef28 100644 --- a/src/gitpod/types/agent_list_executions_params.py +++ b/src/gitpod/types/agent_list_executions_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import List +from typing import Dict, List from typing_extensions import Literal, Annotated, TypedDict from .._types import SequenceNotStr @@ -24,6 +24,13 @@ class AgentListExecutionsParams(TypedDict, total=False): class Filter(TypedDict, total=False): agent_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="agentIds")] + annotations: Dict[str, str] + """annotations filters by key-value pairs. + + Only executions containing all specified annotations (with matching values) are + returned. + """ + creator_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="creatorIds")] environment_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="environmentIds")] diff --git a/src/gitpod/types/agent_start_execution_params.py b/src/gitpod/types/agent_start_execution_params.py index b021f7ed..4d9f640a 100644 --- a/src/gitpod/types/agent_start_execution_params.py +++ b/src/gitpod/types/agent_start_execution_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Optional +from typing import Dict, Optional from typing_extensions import Annotated, TypedDict from .._utils import PropertyInfo @@ -15,6 +15,13 @@ class AgentStartExecutionParams(TypedDict, total=False): agent_id: Annotated[str, PropertyInfo(alias="agentId")] + annotations: Dict[str, str] + """ + annotations are key-value pairs for tracking external context (e.g., Linear + session IDs, GitHub issue references). Keys should follow domain/name convention + (e.g., "linear.app/session-id"). + """ + code_context: Annotated[AgentCodeContextParam, PropertyInfo(alias="codeContext")] mode: AgentMode @@ -25,6 +32,13 @@ class AgentStartExecutionParams(TypedDict, total=False): name: str + runner_id: Annotated[str, PropertyInfo(alias="runnerId")] + """ + runner_id specifies a runner for this agent execution. When set, the agent + execution is routed to this runner instead of the runner associated with the + environment. + """ + workflow_action_id: Annotated[Optional[str], PropertyInfo(alias="workflowActionId")] """ workflow_action_id is an optional reference to the workflow execution action diff --git a/src/gitpod/types/environment_create_from_project_params.py b/src/gitpod/types/environment_create_from_project_params.py index 2c9806f7..4a26228d 100644 --- a/src/gitpod/types/environment_create_from_project_params.py +++ b/src/gitpod/types/environment_create_from_project_params.py @@ -2,6 +2,7 @@ from __future__ import annotations +from typing import Optional from typing_extensions import Annotated, TypedDict from .._utils import PropertyInfo @@ -11,6 +12,12 @@ class EnvironmentCreateFromProjectParams(TypedDict, total=False): + name: Optional[str] + """ + name is a user-defined identifier for the environment. If not specified, the + system will generate a name. + """ + project_id: Annotated[str, PropertyInfo(alias="projectId")] spec: EnvironmentSpecParam diff --git a/src/gitpod/types/environment_create_params.py b/src/gitpod/types/environment_create_params.py index e49a7d27..d5c55e8e 100644 --- a/src/gitpod/types/environment_create_params.py +++ b/src/gitpod/types/environment_create_params.py @@ -2,6 +2,7 @@ from __future__ import annotations +from typing import Optional from typing_extensions import TypedDict from .environment_spec_param import EnvironmentSpecParam @@ -10,6 +11,12 @@ class EnvironmentCreateParams(TypedDict, total=False): + name: Optional[str] + """ + name is a user-defined identifier for the environment. If not specified, the + system will generate a name. + """ + spec: EnvironmentSpecParam """ spec is the configuration of the environment that's required for the to start diff --git a/src/gitpod/types/environment_spec.py b/src/gitpod/types/environment_spec.py index 679336f4..c4a10ecd 100644 --- a/src/gitpod/types/environment_spec.py +++ b/src/gitpod/types/environment_spec.py @@ -8,6 +8,7 @@ from .._models import BaseModel from .admission_level import AdmissionLevel from .environment_phase import EnvironmentPhase +from .kernel_controls_config import KernelControlsConfig from .environment_initializer import EnvironmentInitializer from .shared.automation_trigger import AutomationTrigger @@ -157,6 +158,21 @@ class Secret(BaseModel): name: Optional[str] = None """name is the human readable description of the secret""" + scope: Optional[ + Literal[ + "SCOPE_UNSPECIFIED", + "SCOPE_ORGANIZATION", + "SCOPE_PROJECT", + "SCOPE_USER", + "SCOPE_SERVICE_ACCOUNT", + "SCOPE_RUNNER", + ] + ] = None + """ + scope indicates where this secret originated from. Used to filter secrets during + build (only org and project secrets are injected). + """ + session: Optional[str] = None """ session indicated the current session of the secret. When the session does not @@ -209,6 +225,9 @@ class EnvironmentSpec(BaseModel): devcontainer: Optional[Devcontainer] = None """devcontainer is the devcontainer spec of the environment""" + kernel_controls_config: Optional[KernelControlsConfig] = FieldInfo(alias="kernelControlsConfig", default=None) + """kernel_controls_config configures kernel-level controls for this environment""" + machine: Optional[Machine] = None """machine is the machine spec of the environment""" diff --git a/src/gitpod/types/environment_spec_param.py b/src/gitpod/types/environment_spec_param.py index 3c10dbd3..a646dac6 100644 --- a/src/gitpod/types/environment_spec_param.py +++ b/src/gitpod/types/environment_spec_param.py @@ -8,6 +8,7 @@ from .._utils import PropertyInfo from .admission_level import AdmissionLevel from .environment_phase import EnvironmentPhase +from .kernel_controls_config_param import KernelControlsConfigParam from .environment_initializer_param import EnvironmentInitializerParam from .shared_params.automation_trigger import AutomationTrigger @@ -164,6 +165,19 @@ class Secret(TypedDict, total=False): name: str """name is the human readable description of the secret""" + scope: Literal[ + "SCOPE_UNSPECIFIED", + "SCOPE_ORGANIZATION", + "SCOPE_PROJECT", + "SCOPE_USER", + "SCOPE_SERVICE_ACCOUNT", + "SCOPE_RUNNER", + ] + """ + scope indicates where this secret originated from. Used to filter secrets during + build (only org and project secrets are injected). + """ + session: str """ session indicated the current session of the secret. When the session does not @@ -216,6 +230,9 @@ class EnvironmentSpecParam(TypedDict, total=False): devcontainer: Devcontainer """devcontainer is the devcontainer spec of the environment""" + kernel_controls_config: Annotated[KernelControlsConfigParam, PropertyInfo(alias="kernelControlsConfig")] + """kernel_controls_config configures kernel-level controls for this environment""" + machine: Machine """machine is the machine spec of the environment""" diff --git a/src/gitpod/types/environment_update_params.py b/src/gitpod/types/environment_update_params.py index 904aa438..28879ebc 100644 --- a/src/gitpod/types/environment_update_params.py +++ b/src/gitpod/types/environment_update_params.py @@ -7,6 +7,7 @@ from .._utils import PropertyInfo from .admission_level import AdmissionLevel +from .kernel_controls_config_param import KernelControlsConfigParam from .environment_initializer_param import EnvironmentInitializerParam __all__ = [ @@ -132,6 +133,9 @@ class Spec(TypedDict, total=False): devcontainer: Optional[SpecDevcontainer] + kernel_controls_config: Annotated[Optional[KernelControlsConfigParam], PropertyInfo(alias="kernelControlsConfig")] + """kernel_controls_config configures kernel-level controls for this environment""" + ports: Iterable[SpecPort] """ports controls port sharing""" diff --git a/src/gitpod/types/groups/role_assignment.py b/src/gitpod/types/groups/role_assignment.py index 39512d04..89733094 100644 --- a/src/gitpod/types/groups/role_assignment.py +++ b/src/gitpod/types/groups/role_assignment.py @@ -17,6 +17,14 @@ class RoleAssignment(BaseModel): id: Optional[str] = None """Unique identifier for the role assignment""" + derived_from_org_role: Optional[ResourceRole] = FieldInfo(alias="derivedFromOrgRole", default=None) + """ + The org-level role that created this assignment, if any. + RESOURCE_ROLE_UNSPECIFIED means this is a direct share (manually created). + Non-zero (e.g., ORG_PROJECTS_ADMIN, ORG_RUNNERS_ADMIN) means this assignment was + derived from an org-level role. + """ + group_id: Optional[str] = FieldInfo(alias="groupId", default=None) """Group identifier""" diff --git a/src/gitpod/types/groups/role_assignment_list_params.py b/src/gitpod/types/groups/role_assignment_list_params.py index 63b97bd1..52ceaacb 100644 --- a/src/gitpod/types/groups/role_assignment_list_params.py +++ b/src/gitpod/types/groups/role_assignment_list_params.py @@ -33,6 +33,14 @@ class Filter(TypedDict, total=False): Empty string is allowed and means no filtering by group """ + resource_id: Annotated[str, PropertyInfo(alias="resourceId")] + """ + resource_id filters the response to only role assignments for this specific + resource When provided, users with :grant permission on the resource can see its + role assignments even if they don't belong to the assigned groups Empty string + is allowed and means no filtering by resource + """ + resource_roles: Annotated[List[ResourceRole], PropertyInfo(alias="resourceRoles")] """ resource_roles filters the response to only role assignments with these specific diff --git a/src/gitpod/types/kernel_controls_config.py b/src/gitpod/types/kernel_controls_config.py new file mode 100644 index 00000000..f8f06a94 --- /dev/null +++ b/src/gitpod/types/kernel_controls_config.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from .veto import Veto +from .._models import BaseModel + +__all__ = ["KernelControlsConfig"] + + +class KernelControlsConfig(BaseModel): + """KernelControlsConfig configures kernel-level controls for the environment""" + + veto: Optional[Veto] = None + """veto controls blocking mechanisms""" diff --git a/src/gitpod/types/kernel_controls_config_param.py b/src/gitpod/types/kernel_controls_config_param.py new file mode 100644 index 00000000..11e6a86f --- /dev/null +++ b/src/gitpod/types/kernel_controls_config_param.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import TypedDict + +from .veto_param import VetoParam + +__all__ = ["KernelControlsConfigParam"] + + +class KernelControlsConfigParam(TypedDict, total=False): + """KernelControlsConfig configures kernel-level controls for the environment""" + + veto: VetoParam + """veto controls blocking mechanisms""" diff --git a/src/gitpod/types/organization_list_members_params.py b/src/gitpod/types/organization_list_members_params.py index 2e5f87ec..986af24e 100644 --- a/src/gitpod/types/organization_list_members_params.py +++ b/src/gitpod/types/organization_list_members_params.py @@ -5,6 +5,7 @@ from typing import List from typing_extensions import Literal, Required, Annotated, TypedDict +from .._types import SequenceNotStr from .._utils import PropertyInfo from .shared.user_status import UserStatus from .shared.organization_role import OrganizationRole @@ -36,6 +37,12 @@ class OrganizationListMembersParams(TypedDict, total=False): class Filter(TypedDict, total=False): + exclude_group_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="excludeGroupIds")] + """ + exclude_group_ids excludes members who are already in any of the specified + groups + """ + roles: List[OrganizationRole] """roles filters members by their organization role""" @@ -45,6 +52,9 @@ class Filter(TypedDict, total=False): statuses: List[UserStatus] """status filters members by their user status""" + user_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="userIds")] + """user_ids filters the response to only members with the specified user IDs""" + class Pagination(TypedDict, total=False): """pagination contains the pagination options for listing members""" diff --git a/src/gitpod/types/organizations/__init__.py b/src/gitpod/types/organizations/__init__.py index 60c60ebe..86ec7aed 100644 --- a/src/gitpod/types/organizations/__init__.py +++ b/src/gitpod/types/organizations/__init__.py @@ -7,9 +7,11 @@ from .provider_type import ProviderType as ProviderType from .sso_configuration import SSOConfiguration as SSOConfiguration from .scim_configuration import ScimConfiguration as ScimConfiguration +from .announcement_banner import AnnouncementBanner as AnnouncementBanner from .crowd_strike_config import CrowdStrikeConfig as CrowdStrikeConfig from .domain_verification import DomainVerification as DomainVerification from .organization_invite import OrganizationInvite as OrganizationInvite +from .executable_deny_list import ExecutableDenyList as ExecutableDenyList from .invite_create_params import InviteCreateParams as InviteCreateParams from .policy_update_params import PolicyUpdateParams as PolicyUpdateParams from .organization_policies import OrganizationPolicies as OrganizationPolicies @@ -23,6 +25,7 @@ from .policy_retrieve_response import PolicyRetrieveResponse as PolicyRetrieveResponse from .domain_verification_state import DomainVerificationState as DomainVerificationState from .invite_get_summary_params import InviteGetSummaryParams as InviteGetSummaryParams +from .executable_deny_list_param import ExecutableDenyListParam as ExecutableDenyListParam from .custom_domain_create_params import CustomDomainCreateParams as CustomDomainCreateParams from .custom_domain_delete_params import CustomDomainDeleteParams as CustomDomainDeleteParams from .custom_domain_update_params import CustomDomainUpdateParams as CustomDomainUpdateParams @@ -31,15 +34,19 @@ from .custom_domain_retrieve_params import CustomDomainRetrieveParams as CustomDomainRetrieveParams from .custom_domain_update_response import CustomDomainUpdateResponse as CustomDomainUpdateResponse from .sso_configuration_list_params import SSOConfigurationListParams as SSOConfigurationListParams +from .additional_scopes_update_param import AdditionalScopesUpdateParam as AdditionalScopesUpdateParam +from .announcement_banner_get_params import AnnouncementBannerGetParams as AnnouncementBannerGetParams from .scim_configuration_list_params import ScimConfigurationListParams as ScimConfigurationListParams from .custom_domain_retrieve_response import CustomDomainRetrieveResponse as CustomDomainRetrieveResponse from .domain_verification_list_params import DomainVerificationListParams as DomainVerificationListParams from .sso_configuration_create_params import SSOConfigurationCreateParams as SSOConfigurationCreateParams from .sso_configuration_delete_params import SSOConfigurationDeleteParams as SSOConfigurationDeleteParams from .sso_configuration_update_params import SSOConfigurationUpdateParams as SSOConfigurationUpdateParams +from .announcement_banner_get_response import AnnouncementBannerGetResponse as AnnouncementBannerGetResponse from .scim_configuration_create_params import ScimConfigurationCreateParams as ScimConfigurationCreateParams from .scim_configuration_delete_params import ScimConfigurationDeleteParams as ScimConfigurationDeleteParams from .scim_configuration_update_params import ScimConfigurationUpdateParams as ScimConfigurationUpdateParams +from .announcement_banner_update_params import AnnouncementBannerUpdateParams as AnnouncementBannerUpdateParams from .domain_verification_create_params import DomainVerificationCreateParams as DomainVerificationCreateParams from .domain_verification_delete_params import DomainVerificationDeleteParams as DomainVerificationDeleteParams from .domain_verification_verify_params import DomainVerificationVerifyParams as DomainVerificationVerifyParams @@ -48,6 +55,7 @@ from .scim_configuration_create_response import ScimConfigurationCreateResponse as ScimConfigurationCreateResponse from .scim_configuration_retrieve_params import ScimConfigurationRetrieveParams as ScimConfigurationRetrieveParams from .scim_configuration_update_response import ScimConfigurationUpdateResponse as ScimConfigurationUpdateResponse +from .announcement_banner_update_response import AnnouncementBannerUpdateResponse as AnnouncementBannerUpdateResponse from .domain_verification_create_response import DomainVerificationCreateResponse as DomainVerificationCreateResponse from .domain_verification_retrieve_params import DomainVerificationRetrieveParams as DomainVerificationRetrieveParams from .domain_verification_verify_response import DomainVerificationVerifyResponse as DomainVerificationVerifyResponse diff --git a/src/gitpod/types/organizations/additional_scopes_update_param.py b/src/gitpod/types/organizations/additional_scopes_update_param.py new file mode 100644 index 00000000..8c45b5e4 --- /dev/null +++ b/src/gitpod/types/organizations/additional_scopes_update_param.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import TypedDict + +from ..._types import SequenceNotStr + +__all__ = ["AdditionalScopesUpdateParam"] + + +class AdditionalScopesUpdateParam(TypedDict, total=False): + """ + AdditionalScopesUpdate wraps a list of OIDC scopes so that the update request + can distinguish "not changing scopes" (field absent) from "clearing all scopes" + (field present, empty list). + """ + + scopes: SequenceNotStr[str] diff --git a/src/gitpod/types/organizations/announcement_banner.py b/src/gitpod/types/organizations/announcement_banner.py new file mode 100644 index 00000000..299540a9 --- /dev/null +++ b/src/gitpod/types/organizations/announcement_banner.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["AnnouncementBanner"] + + +class AnnouncementBanner(BaseModel): + organization_id: str = FieldInfo(alias="organizationId") + """organization_id is the ID of the organization""" + + enabled: Optional[bool] = None + """enabled controls whether the banner is displayed""" + + message: Optional[str] = None + """message is the banner message displayed to users. Supports basic Markdown.""" diff --git a/src/gitpod/types/organizations/announcement_banner_get_params.py b/src/gitpod/types/organizations/announcement_banner_get_params.py new file mode 100644 index 00000000..59c75b8f --- /dev/null +++ b/src/gitpod/types/organizations/announcement_banner_get_params.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["AnnouncementBannerGetParams"] + + +class AnnouncementBannerGetParams(TypedDict, total=False): + organization_id: Required[Annotated[str, PropertyInfo(alias="organizationId")]] + """organization_id is the ID of the organization""" diff --git a/src/gitpod/types/organizations/announcement_banner_get_response.py b/src/gitpod/types/organizations/announcement_banner_get_response.py new file mode 100644 index 00000000..da432404 --- /dev/null +++ b/src/gitpod/types/organizations/announcement_banner_get_response.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..._models import BaseModel +from .announcement_banner import AnnouncementBanner + +__all__ = ["AnnouncementBannerGetResponse"] + + +class AnnouncementBannerGetResponse(BaseModel): + banner: AnnouncementBanner + """banner is the announcement banner configuration""" diff --git a/src/gitpod/types/organizations/announcement_banner_update_params.py b/src/gitpod/types/organizations/announcement_banner_update_params.py new file mode 100644 index 00000000..7dfe53fb --- /dev/null +++ b/src/gitpod/types/organizations/announcement_banner_update_params.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["AnnouncementBannerUpdateParams"] + + +class AnnouncementBannerUpdateParams(TypedDict, total=False): + organization_id: Required[Annotated[str, PropertyInfo(alias="organizationId")]] + """organization_id is the ID of the organization""" + + enabled: Optional[bool] + """enabled controls whether the banner is displayed""" + + message: Optional[str] + """message is the banner message. + + Supports basic Markdown. Maximum 1000 characters. + """ diff --git a/src/gitpod/types/organizations/announcement_banner_update_response.py b/src/gitpod/types/organizations/announcement_banner_update_response.py new file mode 100644 index 00000000..d4701890 --- /dev/null +++ b/src/gitpod/types/organizations/announcement_banner_update_response.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..._models import BaseModel +from .announcement_banner import AnnouncementBanner + +__all__ = ["AnnouncementBannerUpdateResponse"] + + +class AnnouncementBannerUpdateResponse(BaseModel): + banner: AnnouncementBanner + """banner is the updated announcement banner configuration""" diff --git a/src/gitpod/types/organizations/executable_deny_list.py b/src/gitpod/types/organizations/executable_deny_list.py new file mode 100644 index 00000000..0fc4ea34 --- /dev/null +++ b/src/gitpod/types/organizations/executable_deny_list.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from ..._models import BaseModel + +__all__ = ["ExecutableDenyList"] + + +class ExecutableDenyList(BaseModel): + """ + ExecutableDenyList contains executables that are blocked from execution in environments. + """ + + enabled: Optional[bool] = None + """enabled controls whether executable blocking is active""" + + executables: Optional[List[str]] = None + """executables is the list of executable paths or names to block""" diff --git a/src/gitpod/types/organizations/executable_deny_list_param.py b/src/gitpod/types/organizations/executable_deny_list_param.py new file mode 100644 index 00000000..bfe2677d --- /dev/null +++ b/src/gitpod/types/organizations/executable_deny_list_param.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import TypedDict + +from ..._types import SequenceNotStr + +__all__ = ["ExecutableDenyListParam"] + + +class ExecutableDenyListParam(TypedDict, total=False): + """ + ExecutableDenyList contains executables that are blocked from execution in environments. + """ + + enabled: bool + """enabled controls whether executable blocking is active""" + + executables: SequenceNotStr[str] + """executables is the list of executable paths or names to block""" diff --git a/src/gitpod/types/organizations/organization_policies.py b/src/gitpod/types/organizations/organization_policies.py index e84968b0..ea62f2eb 100644 --- a/src/gitpod/types/organizations/organization_policies.py +++ b/src/gitpod/types/organizations/organization_policies.py @@ -6,6 +6,7 @@ from ..._models import BaseModel from .agent_policy import AgentPolicy +from .executable_deny_list import ExecutableDenyList from .security_agent_policy import SecurityAgentPolicy __all__ = ["OrganizationPolicies", "EditorVersionRestrictions"] @@ -77,8 +78,9 @@ class OrganizationPolicies(BaseModel): port_sharing_disabled: bool = FieldInfo(alias="portSharingDisabled") """ - port_sharing_disabled controls whether port sharing is disabled in the - organization + port_sharing_disabled controls whether user-initiated port sharing is disabled + in the organization. System ports (VS Code Browser, agents) are always exempt + from this policy. """ require_custom_domain_access: bool = FieldInfo(alias="requireCustomDomainAccess") @@ -87,6 +89,13 @@ class OrganizationPolicies(BaseModel): domain when one is configured. When true, access via app.gitpod.io is blocked. """ + restrict_account_creation_to_scim: bool = FieldInfo(alias="restrictAccountCreationToScim") + """ + restrict_account_creation_to_scim controls whether account creation is + restricted to SCIM-provisioned users only. When true and SCIM is configured for + the organization, only users provisioned via SCIM can create accounts. + """ + delete_archived_environments_after: Optional[str] = FieldInfo(alias="deleteArchivedEnvironmentsAfter", default=None) """ delete_archived_environments_after controls how long archived environments are @@ -104,6 +113,12 @@ class OrganizationPolicies(BaseModel): of the editor """ + executable_deny_list: Optional[ExecutableDenyList] = FieldInfo(alias="executableDenyList", default=None) + """ + executable_deny_list contains executables that are blocked from execution in + environments. + """ + maximum_environment_lifetime: Optional[str] = FieldInfo(alias="maximumEnvironmentLifetime", default=None) """ maximum_environment_lifetime controls for how long environments are allowed to diff --git a/src/gitpod/types/organizations/policy_update_params.py b/src/gitpod/types/organizations/policy_update_params.py index 6c5f5ebb..33cc3143 100644 --- a/src/gitpod/types/organizations/policy_update_params.py +++ b/src/gitpod/types/organizations/policy_update_params.py @@ -7,6 +7,7 @@ from ..._types import SequenceNotStr from ..._utils import PropertyInfo +from .executable_deny_list_param import ExecutableDenyListParam __all__ = [ "PolicyUpdateParams", @@ -63,6 +64,12 @@ class PolicyUpdateParams(TypedDict, total=False): editor ID to version policy with allowed major versions. """ + executable_deny_list: Annotated[Optional[ExecutableDenyListParam], PropertyInfo(alias="executableDenyList")] + """ + executable_deny_list contains executables that are blocked from execution in + environments. + """ + maximum_environment_lifetime: Annotated[Optional[str], PropertyInfo(alias="maximumEnvironmentLifetime")] """ maximum_environment_lifetime controls for how long environments are allowed to @@ -102,8 +109,9 @@ class PolicyUpdateParams(TypedDict, total=False): port_sharing_disabled: Annotated[Optional[bool], PropertyInfo(alias="portSharingDisabled")] """ - port_sharing_disabled controls whether port sharing is disabled in the - organization + port_sharing_disabled controls whether user-initiated port sharing is disabled + in the organization. System ports (VS Code Browser, agents) are always exempt + from this policy. """ require_custom_domain_access: Annotated[Optional[bool], PropertyInfo(alias="requireCustomDomainAccess")] @@ -112,6 +120,13 @@ class PolicyUpdateParams(TypedDict, total=False): domain when one is configured. When true, access via app.gitpod.io is blocked. """ + restrict_account_creation_to_scim: Annotated[Optional[bool], PropertyInfo(alias="restrictAccountCreationToScim")] + """ + restrict_account_creation_to_scim controls whether account creation is + restricted to SCIM-provisioned users only. When true and SCIM is configured for + the organization, only users provisioned via SCIM can create accounts. + """ + security_agent_policy: Annotated[Optional[SecurityAgentPolicy], PropertyInfo(alias="securityAgentPolicy")] """security_agent_policy contains security agent configuration updates""" diff --git a/src/gitpod/types/organizations/scim_configuration.py b/src/gitpod/types/organizations/scim_configuration.py index 289db0f5..8b12ff05 100644 --- a/src/gitpod/types/organizations/scim_configuration.py +++ b/src/gitpod/types/organizations/scim_configuration.py @@ -24,6 +24,9 @@ class ScimConfiguration(BaseModel): organization_id is the ID of the organization this SCIM configuration belongs to """ + token_expires_at: datetime = FieldInfo(alias="tokenExpiresAt") + """token_expires_at is when the current SCIM token expires""" + updated_at: datetime = FieldInfo(alias="updatedAt") """updated_at is when the SCIM configuration was last updated""" diff --git a/src/gitpod/types/organizations/scim_configuration_create_params.py b/src/gitpod/types/organizations/scim_configuration_create_params.py index fae33808..e8f5a2ee 100644 --- a/src/gitpod/types/organizations/scim_configuration_create_params.py +++ b/src/gitpod/types/organizations/scim_configuration_create_params.py @@ -25,3 +25,9 @@ class ScimConfigurationCreateParams(TypedDict, total=False): name: Optional[str] """name is a human-readable name for the SCIM configuration""" + + token_expires_in: Annotated[Optional[str], PropertyInfo(alias="tokenExpiresIn")] + """token_expires_in is the duration until the token expires. Defaults to 1 year. + + Minimum 1 day, maximum 2 years. + """ diff --git a/src/gitpod/types/organizations/scim_configuration_create_response.py b/src/gitpod/types/organizations/scim_configuration_create_response.py index 95ba89b9..af949703 100644 --- a/src/gitpod/types/organizations/scim_configuration_create_response.py +++ b/src/gitpod/types/organizations/scim_configuration_create_response.py @@ -1,5 +1,7 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +from datetime import datetime + from pydantic import Field as FieldInfo from ..._models import BaseModel @@ -17,3 +19,6 @@ class ScimConfigurationCreateResponse(BaseModel): scim_configuration: ScimConfiguration = FieldInfo(alias="scimConfiguration") """scim_configuration is the created SCIM configuration""" + + token_expires_at: datetime = FieldInfo(alias="tokenExpiresAt") + """token_expires_at is when the token will expire""" diff --git a/src/gitpod/types/organizations/scim_configuration_regenerate_token_params.py b/src/gitpod/types/organizations/scim_configuration_regenerate_token_params.py index b6cedadf..42dc8056 100644 --- a/src/gitpod/types/organizations/scim_configuration_regenerate_token_params.py +++ b/src/gitpod/types/organizations/scim_configuration_regenerate_token_params.py @@ -2,6 +2,7 @@ from __future__ import annotations +from typing import Optional from typing_extensions import Required, Annotated, TypedDict from ..._utils import PropertyInfo @@ -15,3 +16,9 @@ class ScimConfigurationRegenerateTokenParams(TypedDict, total=False): scim_configuration_id is the ID of the SCIM configuration to regenerate token for """ + + token_expires_in: Annotated[Optional[str], PropertyInfo(alias="tokenExpiresIn")] + """ + token_expires_in is the duration until the new token expires. If not specified, + uses the same duration as the previous token. + """ diff --git a/src/gitpod/types/organizations/scim_configuration_regenerate_token_response.py b/src/gitpod/types/organizations/scim_configuration_regenerate_token_response.py index 0af03b1e..16d79ab0 100644 --- a/src/gitpod/types/organizations/scim_configuration_regenerate_token_response.py +++ b/src/gitpod/types/organizations/scim_configuration_regenerate_token_response.py @@ -1,5 +1,9 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +from datetime import datetime + +from pydantic import Field as FieldInfo + from ..._models import BaseModel __all__ = ["ScimConfigurationRegenerateTokenResponse"] @@ -11,3 +15,6 @@ class ScimConfigurationRegenerateTokenResponse(BaseModel): token is the new bearer token for SCIM API authentication. This invalidates the previous token - store it securely. """ + + token_expires_at: datetime = FieldInfo(alias="tokenExpiresAt") + """token_expires_at is when the new token will expire""" diff --git a/src/gitpod/types/organizations/sso_configuration.py b/src/gitpod/types/organizations/sso_configuration.py index 7f7f70b7..f5dd4db4 100644 --- a/src/gitpod/types/organizations/sso_configuration.py +++ b/src/gitpod/types/organizations/sso_configuration.py @@ -26,6 +26,12 @@ class SSOConfiguration(BaseModel): state: SSOConfigurationState """state is the state of the SSO configuration""" + additional_scopes: Optional[List[str]] = FieldInfo(alias="additionalScopes", default=None) + """ + additional_scopes are extra OIDC scopes requested from the identity provider + during sign-in. + """ + claims: Optional[Dict[str, str]] = None """claims are key/value pairs that defines a mapping of claims issued by the IdP.""" diff --git a/src/gitpod/types/organizations/sso_configuration_create_params.py b/src/gitpod/types/organizations/sso_configuration_create_params.py index 04f39fb1..16ffadb1 100644 --- a/src/gitpod/types/organizations/sso_configuration_create_params.py +++ b/src/gitpod/types/organizations/sso_configuration_create_params.py @@ -23,6 +23,13 @@ class SSOConfigurationCreateParams(TypedDict, total=False): organization_id: Required[Annotated[str, PropertyInfo(alias="organizationId")]] + additional_scopes: Annotated[SequenceNotStr[str], PropertyInfo(alias="additionalScopes")] + """ + additional_scopes are extra OIDC scopes to request from the identity provider + during sign-in. These are appended to the default scopes (openid, email, + profile). + """ + display_name: Annotated[str, PropertyInfo(alias="displayName")] email_domain: Annotated[Optional[str], PropertyInfo(alias="emailDomain")] diff --git a/src/gitpod/types/organizations/sso_configuration_update_params.py b/src/gitpod/types/organizations/sso_configuration_update_params.py index 998789ab..7f85387e 100644 --- a/src/gitpod/types/organizations/sso_configuration_update_params.py +++ b/src/gitpod/types/organizations/sso_configuration_update_params.py @@ -8,6 +8,7 @@ from ..._types import SequenceNotStr from ..._utils import PropertyInfo from .sso_configuration_state import SSOConfigurationState +from .additional_scopes_update_param import AdditionalScopesUpdateParam __all__ = ["SSOConfigurationUpdateParams"] @@ -16,6 +17,13 @@ class SSOConfigurationUpdateParams(TypedDict, total=False): sso_configuration_id: Required[Annotated[str, PropertyInfo(alias="ssoConfigurationId")]] """sso_configuration_id is the ID of the SSO configuration to update""" + additional_scopes: Annotated[Optional[AdditionalScopesUpdateParam], PropertyInfo(alias="additionalScopes")] + """ + additional_scopes replaces the configured OIDC scopes when present. When absent + (nil), scopes are left unchanged. When present with an empty scopes list, all + additional scopes are cleared. + """ + claims: Dict[str, str] """claims are key/value pairs that defines a mapping of claims issued by the IdP.""" diff --git a/src/gitpod/types/prebuild_list_params.py b/src/gitpod/types/prebuild_list_params.py index 59075354..68931404 100644 --- a/src/gitpod/types/prebuild_list_params.py +++ b/src/gitpod/types/prebuild_list_params.py @@ -8,6 +8,7 @@ from .._types import SequenceNotStr from .._utils import PropertyInfo from .prebuild_phase import PrebuildPhase +from .prebuild_trigger import PrebuildTrigger __all__ = ["PrebuildListParams", "Filter", "Pagination"] @@ -27,12 +28,21 @@ class PrebuildListParams(TypedDict, total=False): class Filter(TypedDict, total=False): """filter contains the filter options for listing prebuilds""" + creator_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="creatorIds")] + """creator_ids filters prebuilds by who created them""" + + executor_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="executorIds")] + """executor_ids filters prebuilds by whose credentials were used to run them""" + phases: List[PrebuildPhase] """phases filters prebuilds by their current phase""" project_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="projectIds")] """project_ids filters prebuilds to specific projects""" + triggered_by: Annotated[List[PrebuildTrigger], PropertyInfo(alias="triggeredBy")] + """triggered_by filters prebuilds by how they were triggered""" + class Pagination(TypedDict, total=False): """pagination contains the pagination options for listing prebuilds""" diff --git a/src/gitpod/types/runner_capability.py b/src/gitpod/types/runner_capability.py index 36bb1f9b..be53db06 100644 --- a/src/gitpod/types/runner_capability.py +++ b/src/gitpod/types/runner_capability.py @@ -13,4 +13,6 @@ "RUNNER_CAPABILITY_DEFAULT_DEV_CONTAINER_IMAGE", "RUNNER_CAPABILITY_ENVIRONMENT_SNAPSHOT", "RUNNER_CAPABILITY_PREBUILDS_BEFORE_SNAPSHOT_TRIGGER", + "RUNNER_CAPABILITY_LIST_SCM_ORGANIZATIONS", + "RUNNER_CAPABILITY_CHECK_REPOSITORY_ACCESS", ] diff --git a/src/gitpod/types/runner_provider.py b/src/gitpod/types/runner_provider.py index f0730df4..4d40404b 100644 --- a/src/gitpod/types/runner_provider.py +++ b/src/gitpod/types/runner_provider.py @@ -11,4 +11,5 @@ "RUNNER_PROVIDER_DESKTOP_MAC", "RUNNER_PROVIDER_MANAGED", "RUNNER_PROVIDER_GCP", + "RUNNER_PROVIDER_DEV_AGENT", ] diff --git a/src/gitpod/types/secret_create_params.py b/src/gitpod/types/secret_create_params.py index 37c24627..99e545f3 100644 --- a/src/gitpod/types/secret_create_params.py +++ b/src/gitpod/types/secret_create_params.py @@ -33,10 +33,10 @@ class SecretCreateParams(TypedDict, total=False): file_path: Annotated[str, PropertyInfo(alias="filePath")] """ absolute path to the file where the secret is mounted value must be an absolute - path (start with a /): + path (e.g. /path/to/file): ``` - this.matches('^/(?:[^/]*/)*.*$') + this.matches('^/[^/].*$') ``` """ diff --git a/src/gitpod/types/shared/resource_role.py b/src/gitpod/types/shared/resource_role.py index 33ecbb72..82289489 100644 --- a/src/gitpod/types/shared/resource_role.py +++ b/src/gitpod/types/shared/resource_role.py @@ -9,6 +9,9 @@ "RESOURCE_ROLE_ORG_ADMIN", "RESOURCE_ROLE_ORG_MEMBER", "RESOURCE_ROLE_ORG_RUNNERS_ADMIN", + "RESOURCE_ROLE_ORG_PROJECTS_ADMIN", + "RESOURCE_ROLE_ORG_AUTOMATIONS_ADMIN", + "RESOURCE_ROLE_ORG_GROUPS_ADMIN", "RESOURCE_ROLE_GROUP_ADMIN", "RESOURCE_ROLE_GROUP_VIEWER", "RESOURCE_ROLE_USER_IDENTITY", @@ -56,4 +59,5 @@ "RESOURCE_ROLE_SNAPSHOT_RUNNER", "RESOURCE_ROLE_WEBHOOK_ADMIN", "RESOURCE_ROLE_WEBHOOK_VIEWER", + "RESOURCE_ROLE_WARMPOOL_RUNNER", ] diff --git a/src/gitpod/types/shared/resource_type.py b/src/gitpod/types/shared/resource_type.py index 599108b9..0f7f7567 100644 --- a/src/gitpod/types/shared/resource_type.py +++ b/src/gitpod/types/shared/resource_type.py @@ -50,4 +50,8 @@ "RESOURCE_TYPE_WEBHOOK", "RESOURCE_TYPE_SCIM_CONFIGURATION", "RESOURCE_TYPE_SERVICE_ACCOUNT_SECRET", + "RESOURCE_TYPE_ANNOUNCEMENT_BANNER", + "RESOURCE_TYPE_SERVICE_ACCOUNT_TOKEN", + "RESOURCE_TYPE_ROLE_ASSIGNMENT", + "RESOURCE_TYPE_WARM_POOL", ] diff --git a/src/gitpod/types/shared_params/resource_role.py b/src/gitpod/types/shared_params/resource_role.py index 053e9545..dd7e43a1 100644 --- a/src/gitpod/types/shared_params/resource_role.py +++ b/src/gitpod/types/shared_params/resource_role.py @@ -11,6 +11,9 @@ "RESOURCE_ROLE_ORG_ADMIN", "RESOURCE_ROLE_ORG_MEMBER", "RESOURCE_ROLE_ORG_RUNNERS_ADMIN", + "RESOURCE_ROLE_ORG_PROJECTS_ADMIN", + "RESOURCE_ROLE_ORG_AUTOMATIONS_ADMIN", + "RESOURCE_ROLE_ORG_GROUPS_ADMIN", "RESOURCE_ROLE_GROUP_ADMIN", "RESOURCE_ROLE_GROUP_VIEWER", "RESOURCE_ROLE_USER_IDENTITY", @@ -58,4 +61,5 @@ "RESOURCE_ROLE_SNAPSHOT_RUNNER", "RESOURCE_ROLE_WEBHOOK_ADMIN", "RESOURCE_ROLE_WEBHOOK_VIEWER", + "RESOURCE_ROLE_WARMPOOL_RUNNER", ] diff --git a/src/gitpod/types/shared_params/resource_type.py b/src/gitpod/types/shared_params/resource_type.py index 9d489e4d..4928c237 100644 --- a/src/gitpod/types/shared_params/resource_type.py +++ b/src/gitpod/types/shared_params/resource_type.py @@ -52,4 +52,8 @@ "RESOURCE_TYPE_WEBHOOK", "RESOURCE_TYPE_SCIM_CONFIGURATION", "RESOURCE_TYPE_SERVICE_ACCOUNT_SECRET", + "RESOURCE_TYPE_ANNOUNCEMENT_BANNER", + "RESOURCE_TYPE_SERVICE_ACCOUNT_TOKEN", + "RESOURCE_TYPE_ROLE_ASSIGNMENT", + "RESOURCE_TYPE_WARM_POOL", ] diff --git a/src/gitpod/types/veto.py b/src/gitpod/types/veto.py new file mode 100644 index 00000000..e01f3abb --- /dev/null +++ b/src/gitpod/types/veto.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from .._models import BaseModel + +__all__ = ["Veto", "Exec"] + + +class Exec(BaseModel): + """exec controls executable blocking""" + + denylist: Optional[List[str]] = None + """denylist is the list of executable paths or names to block""" + + enabled: Optional[bool] = None + """enabled controls whether executable blocking is active""" + + +class Veto(BaseModel): + """Veto controls kernel-level blocking mechanisms""" + + exec: Optional[Exec] = None + """exec controls executable blocking""" diff --git a/src/gitpod/types/veto_param.py b/src/gitpod/types/veto_param.py new file mode 100644 index 00000000..ba6d52dd --- /dev/null +++ b/src/gitpod/types/veto_param.py @@ -0,0 +1,26 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import TypedDict + +from .._types import SequenceNotStr + +__all__ = ["VetoParam", "Exec"] + + +class Exec(TypedDict, total=False): + """exec controls executable blocking""" + + denylist: SequenceNotStr[str] + """denylist is the list of executable paths or names to block""" + + enabled: bool + """enabled controls whether executable blocking is active""" + + +class VetoParam(TypedDict, total=False): + """Veto controls kernel-level blocking mechanisms""" + + exec: Exec + """exec controls executable blocking""" diff --git a/tests/api_resources/groups/test_role_assignments.py b/tests/api_resources/groups/test_role_assignments.py index 23940822..a21be7e3 100644 --- a/tests/api_resources/groups/test_role_assignments.py +++ b/tests/api_resources/groups/test_role_assignments.py @@ -74,6 +74,7 @@ def test_method_list_with_all_params(self, client: Gitpod) -> None: page_size=0, filter={ "group_id": "groupId", + "resource_id": "resourceId", "resource_roles": ["RESOURCE_ROLE_UNSPECIFIED"], "resource_types": ["RESOURCE_TYPE_RUNNER"], "user_id": "userId", @@ -202,6 +203,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncGitpod) -> N page_size=0, filter={ "group_id": "groupId", + "resource_id": "resourceId", "resource_roles": ["RESOURCE_ROLE_UNSPECIFIED"], "resource_types": ["RESOURCE_TYPE_RUNNER"], "user_id": "userId", diff --git a/tests/api_resources/organizations/test_announcement_banner.py b/tests/api_resources/organizations/test_announcement_banner.py new file mode 100644 index 00000000..2e1c5b8e --- /dev/null +++ b/tests/api_resources/organizations/test_announcement_banner.py @@ -0,0 +1,183 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from gitpod import Gitpod, AsyncGitpod +from tests.utils import assert_matches_type +from gitpod.types.organizations import ( + AnnouncementBannerGetResponse, + AnnouncementBannerUpdateResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestAnnouncementBanner: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_update(self, client: Gitpod) -> None: + announcement_banner = client.organizations.announcement_banner.update( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(AnnouncementBannerUpdateResponse, announcement_banner, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_update_with_all_params(self, client: Gitpod) -> None: + announcement_banner = client.organizations.announcement_banner.update( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + enabled=False, + message="message", + ) + assert_matches_type(AnnouncementBannerUpdateResponse, announcement_banner, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_raw_response_update(self, client: Gitpod) -> None: + response = client.organizations.announcement_banner.with_raw_response.update( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + announcement_banner = response.parse() + assert_matches_type(AnnouncementBannerUpdateResponse, announcement_banner, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_streaming_response_update(self, client: Gitpod) -> None: + with client.organizations.announcement_banner.with_streaming_response.update( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + announcement_banner = response.parse() + assert_matches_type(AnnouncementBannerUpdateResponse, announcement_banner, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_get(self, client: Gitpod) -> None: + announcement_banner = client.organizations.announcement_banner.get( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(AnnouncementBannerGetResponse, announcement_banner, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_raw_response_get(self, client: Gitpod) -> None: + response = client.organizations.announcement_banner.with_raw_response.get( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + announcement_banner = response.parse() + assert_matches_type(AnnouncementBannerGetResponse, announcement_banner, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_streaming_response_get(self, client: Gitpod) -> None: + with client.organizations.announcement_banner.with_streaming_response.get( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + announcement_banner = response.parse() + assert_matches_type(AnnouncementBannerGetResponse, announcement_banner, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncAnnouncementBanner: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_update(self, async_client: AsyncGitpod) -> None: + announcement_banner = await async_client.organizations.announcement_banner.update( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(AnnouncementBannerUpdateResponse, announcement_banner, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> None: + announcement_banner = await async_client.organizations.announcement_banner.update( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + enabled=False, + message="message", + ) + assert_matches_type(AnnouncementBannerUpdateResponse, announcement_banner, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_raw_response_update(self, async_client: AsyncGitpod) -> None: + response = await async_client.organizations.announcement_banner.with_raw_response.update( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + announcement_banner = await response.parse() + assert_matches_type(AnnouncementBannerUpdateResponse, announcement_banner, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_streaming_response_update(self, async_client: AsyncGitpod) -> None: + async with async_client.organizations.announcement_banner.with_streaming_response.update( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + announcement_banner = await response.parse() + assert_matches_type(AnnouncementBannerUpdateResponse, announcement_banner, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_get(self, async_client: AsyncGitpod) -> None: + announcement_banner = await async_client.organizations.announcement_banner.get( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(AnnouncementBannerGetResponse, announcement_banner, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_raw_response_get(self, async_client: AsyncGitpod) -> None: + response = await async_client.organizations.announcement_banner.with_raw_response.get( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + announcement_banner = await response.parse() + assert_matches_type(AnnouncementBannerGetResponse, announcement_banner, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_streaming_response_get(self, async_client: AsyncGitpod) -> None: + async with async_client.organizations.announcement_banner.with_streaming_response.get( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + announcement_banner = await response.parse() + assert_matches_type(AnnouncementBannerGetResponse, announcement_banner, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/organizations/test_policies.py b/tests/api_resources/organizations/test_policies.py index eed1d45d..b7a74d82 100644 --- a/tests/api_resources/organizations/test_policies.py +++ b/tests/api_resources/organizations/test_policies.py @@ -9,7 +9,9 @@ from gitpod import Gitpod, AsyncGitpod from tests.utils import assert_matches_type -from gitpod.types.organizations import PolicyRetrieveResponse +from gitpod.types.organizations import ( + PolicyRetrieveResponse, +) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -76,6 +78,10 @@ def test_method_update_with_all_params(self, client: Gitpod) -> None: default_environment_image="defaultEnvironmentImage", delete_archived_environments_after="+9125115.360s", editor_version_restrictions={"foo": {"allowed_versions": ["string"]}}, + executable_deny_list={ + "enabled": True, + "executables": ["string"], + }, maximum_environment_lifetime="+9125115.360s", maximum_environments_per_user="20", maximum_environment_timeout="3600s", @@ -84,6 +90,7 @@ def test_method_update_with_all_params(self, client: Gitpod) -> None: members_require_projects=True, port_sharing_disabled=True, require_custom_domain_access=True, + restrict_account_creation_to_scim=True, security_agent_policy={ "crowdstrike": { "additional_options": {"foo": "string"}, @@ -187,6 +194,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> default_environment_image="defaultEnvironmentImage", delete_archived_environments_after="+9125115.360s", editor_version_restrictions={"foo": {"allowed_versions": ["string"]}}, + executable_deny_list={ + "enabled": True, + "executables": ["string"], + }, maximum_environment_lifetime="+9125115.360s", maximum_environments_per_user="20", maximum_environment_timeout="3600s", @@ -195,6 +206,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> members_require_projects=True, port_sharing_disabled=True, require_custom_domain_access=True, + restrict_account_creation_to_scim=True, security_agent_policy={ "crowdstrike": { "additional_options": {"foo": "string"}, diff --git a/tests/api_resources/organizations/test_scim_configurations.py b/tests/api_resources/organizations/test_scim_configurations.py index 16c6e252..4404e237 100644 --- a/tests/api_resources/organizations/test_scim_configurations.py +++ b/tests/api_resources/organizations/test_scim_configurations.py @@ -40,6 +40,7 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", sso_configuration_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", name="name", + token_expires_in="+9125115.360s", ) assert_matches_type(ScimConfigurationCreateResponse, scim_configuration, path=["response"]) @@ -233,6 +234,15 @@ def test_method_regenerate_token(self, client: Gitpod) -> None: ) assert_matches_type(ScimConfigurationRegenerateTokenResponse, scim_configuration, path=["response"]) + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_regenerate_token_with_all_params(self, client: Gitpod) -> None: + scim_configuration = client.organizations.scim_configurations.regenerate_token( + scim_configuration_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + token_expires_in="+9125115.360s", + ) + assert_matches_type(ScimConfigurationRegenerateTokenResponse, scim_configuration, path=["response"]) + @pytest.mark.skip(reason="Prism tests are disabled") @parametrize def test_raw_response_regenerate_token(self, client: Gitpod) -> None: @@ -281,6 +291,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", sso_configuration_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", name="name", + token_expires_in="+9125115.360s", ) assert_matches_type(ScimConfigurationCreateResponse, scim_configuration, path=["response"]) @@ -474,6 +485,15 @@ async def test_method_regenerate_token(self, async_client: AsyncGitpod) -> None: ) assert_matches_type(ScimConfigurationRegenerateTokenResponse, scim_configuration, path=["response"]) + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_regenerate_token_with_all_params(self, async_client: AsyncGitpod) -> None: + scim_configuration = await async_client.organizations.scim_configurations.regenerate_token( + scim_configuration_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + token_expires_in="+9125115.360s", + ) + assert_matches_type(ScimConfigurationRegenerateTokenResponse, scim_configuration, path=["response"]) + @pytest.mark.skip(reason="Prism tests are disabled") @parametrize async def test_raw_response_regenerate_token(self, async_client: AsyncGitpod) -> None: diff --git a/tests/api_resources/organizations/test_sso_configurations.py b/tests/api_resources/organizations/test_sso_configurations.py index 9e10ff80..9dd1f95a 100644 --- a/tests/api_resources/organizations/test_sso_configurations.py +++ b/tests/api_resources/organizations/test_sso_configurations.py @@ -41,6 +41,7 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: client_secret="GOCSPX-abcdefghijklmnopqrstuvwxyz123456", issuer_url="https://accounts.google.com", organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + additional_scopes=["x"], display_name="displayName", email_domain="acme-corp.com", email_domains=["sfN2.l.iJR-BU.u9JV9.a.m.o2D-4b-Jd.0Z-kX.L.n.S.f.UKbxB"], @@ -126,6 +127,7 @@ def test_method_update(self, client: Gitpod) -> None: def test_method_update_with_all_params(self, client: Gitpod) -> None: sso_configuration = client.organizations.sso_configurations.update( sso_configuration_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + additional_scopes={"scopes": ["x"]}, claims={"foo": "string"}, client_id="new-client-id", client_secret="new-client-secret", @@ -270,6 +272,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> client_secret="GOCSPX-abcdefghijklmnopqrstuvwxyz123456", issuer_url="https://accounts.google.com", organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + additional_scopes=["x"], display_name="displayName", email_domain="acme-corp.com", email_domains=["sfN2.l.iJR-BU.u9JV9.a.m.o2D-4b-Jd.0Z-kX.L.n.S.f.UKbxB"], @@ -355,6 +358,7 @@ async def test_method_update(self, async_client: AsyncGitpod) -> None: async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> None: sso_configuration = await async_client.organizations.sso_configurations.update( sso_configuration_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + additional_scopes={"scopes": ["x"]}, claims={"foo": "string"}, client_id="new-client-id", client_secret="new-client-secret", diff --git a/tests/api_resources/test_agents.py b/tests/api_resources/test_agents.py index e006c3cf..979d8ae1 100644 --- a/tests/api_resources/test_agents.py +++ b/tests/api_resources/test_agents.py @@ -192,6 +192,7 @@ def test_method_list_executions_with_all_params(self, client: Gitpod) -> None: page_size=0, filter={ "agent_ids": ["b8a64cfa-43e2-4b9d-9fb3-07edc63f5971"], + "annotations": {"foo": "string"}, "creator_ids": ["string"], "environment_ids": ["string"], "project_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], @@ -412,6 +413,7 @@ def test_method_start_execution(self, client: Gitpod) -> None: def test_method_start_execution_with_all_params(self, client: Gitpod) -> None: agent = client.agents.start_execution( agent_id="b8a64cfa-43e2-4b9d-9fb3-07edc63f5971", + annotations={"foo": "string"}, code_context={ "context_url": { "environment_class_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", @@ -438,6 +440,7 @@ def test_method_start_execution_with_all_params(self, client: Gitpod) -> None: }, mode="AGENT_MODE_UNSPECIFIED", name="name", + runner_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", workflow_action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(AgentStartExecutionResponse, agent, path=["response"]) @@ -717,6 +720,7 @@ async def test_method_list_executions_with_all_params(self, async_client: AsyncG page_size=0, filter={ "agent_ids": ["b8a64cfa-43e2-4b9d-9fb3-07edc63f5971"], + "annotations": {"foo": "string"}, "creator_ids": ["string"], "environment_ids": ["string"], "project_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], @@ -937,6 +941,7 @@ async def test_method_start_execution(self, async_client: AsyncGitpod) -> None: async def test_method_start_execution_with_all_params(self, async_client: AsyncGitpod) -> None: agent = await async_client.agents.start_execution( agent_id="b8a64cfa-43e2-4b9d-9fb3-07edc63f5971", + annotations={"foo": "string"}, code_context={ "context_url": { "environment_class_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", @@ -963,6 +968,7 @@ async def test_method_start_execution_with_all_params(self, async_client: AsyncG }, mode="AGENT_MODE_UNSPECIFIED", name="name", + runner_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", workflow_action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(AgentStartExecutionResponse, agent, path=["response"]) diff --git a/tests/api_resources/test_environments.py b/tests/api_resources/test_environments.py index b2a37f6f..5c33ab50 100644 --- a/tests/api_resources/test_environments.py +++ b/tests/api_resources/test_environments.py @@ -36,6 +36,7 @@ def test_method_create(self, client: Gitpod) -> None: @parametrize def test_method_create_with_all_params(self, client: Gitpod) -> None: environment = client.environments.create( + name="name", spec={ "admission": "ADMISSION_LEVEL_UNSPECIFIED", "automations_file": { @@ -79,6 +80,14 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: "lifecycle_stage": "LIFECYCLE_STAGE_UNSPECIFIED", "session": "session", }, + "kernel_controls_config": { + "veto": { + "exec": { + "denylist": ["string"], + "enabled": True, + } + } + }, "machine": { "class": "d2c94c27-3b76-4a42-b88c-95a85e392c68", "session": "session", @@ -100,6 +109,7 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: "file_path": "filePath", "git_credential_host": "gitCredentialHost", "name": "name", + "scope": "SCOPE_UNSPECIFIED", "session": "session", "source": "source", "source_ref": "sourceRef", @@ -214,6 +224,14 @@ def test_method_update_with_all_params(self, client: Gitpod) -> None: "devcontainer_file_path": "devcontainerFilePath", "session": "session", }, + "kernel_controls_config": { + "veto": { + "exec": { + "denylist": ["string"], + "enabled": True, + } + } + }, "ports": [ { "admission": "ADMISSION_LEVEL_UNSPECIFIED", @@ -387,6 +405,7 @@ def test_method_create_from_project(self, client: Gitpod) -> None: @parametrize def test_method_create_from_project_with_all_params(self, client: Gitpod) -> None: environment = client.environments.create_from_project( + name="name", project_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", spec={ "admission": "ADMISSION_LEVEL_UNSPECIFIED", @@ -431,6 +450,14 @@ def test_method_create_from_project_with_all_params(self, client: Gitpod) -> Non "lifecycle_stage": "LIFECYCLE_STAGE_UNSPECIFIED", "session": "session", }, + "kernel_controls_config": { + "veto": { + "exec": { + "denylist": ["string"], + "enabled": True, + } + } + }, "machine": { "class": "d2c94c27-3b76-4a42-b88c-95a85e392c68", "session": "session", @@ -452,6 +479,7 @@ def test_method_create_from_project_with_all_params(self, client: Gitpod) -> Non "file_path": "filePath", "git_credential_host": "gitCredentialHost", "name": "name", + "scope": "SCOPE_UNSPECIFIED", "session": "session", "source": "source", "source_ref": "sourceRef", @@ -692,6 +720,7 @@ async def test_method_create(self, async_client: AsyncGitpod) -> None: @parametrize async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> None: environment = await async_client.environments.create( + name="name", spec={ "admission": "ADMISSION_LEVEL_UNSPECIFIED", "automations_file": { @@ -735,6 +764,14 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> "lifecycle_stage": "LIFECYCLE_STAGE_UNSPECIFIED", "session": "session", }, + "kernel_controls_config": { + "veto": { + "exec": { + "denylist": ["string"], + "enabled": True, + } + } + }, "machine": { "class": "d2c94c27-3b76-4a42-b88c-95a85e392c68", "session": "session", @@ -756,6 +793,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> "file_path": "filePath", "git_credential_host": "gitCredentialHost", "name": "name", + "scope": "SCOPE_UNSPECIFIED", "session": "session", "source": "source", "source_ref": "sourceRef", @@ -870,6 +908,14 @@ async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> "devcontainer_file_path": "devcontainerFilePath", "session": "session", }, + "kernel_controls_config": { + "veto": { + "exec": { + "denylist": ["string"], + "enabled": True, + } + } + }, "ports": [ { "admission": "ADMISSION_LEVEL_UNSPECIFIED", @@ -1043,6 +1089,7 @@ async def test_method_create_from_project(self, async_client: AsyncGitpod) -> No @parametrize async def test_method_create_from_project_with_all_params(self, async_client: AsyncGitpod) -> None: environment = await async_client.environments.create_from_project( + name="name", project_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", spec={ "admission": "ADMISSION_LEVEL_UNSPECIFIED", @@ -1087,6 +1134,14 @@ async def test_method_create_from_project_with_all_params(self, async_client: As "lifecycle_stage": "LIFECYCLE_STAGE_UNSPECIFIED", "session": "session", }, + "kernel_controls_config": { + "veto": { + "exec": { + "denylist": ["string"], + "enabled": True, + } + } + }, "machine": { "class": "d2c94c27-3b76-4a42-b88c-95a85e392c68", "session": "session", @@ -1108,6 +1163,7 @@ async def test_method_create_from_project_with_all_params(self, async_client: As "file_path": "filePath", "git_credential_host": "gitCredentialHost", "name": "name", + "scope": "SCOPE_UNSPECIFIED", "session": "session", "source": "source", "source_ref": "sourceRef", diff --git a/tests/api_resources/test_organizations.py b/tests/api_resources/test_organizations.py index b404eb78..a8653c7c 100644 --- a/tests/api_resources/test_organizations.py +++ b/tests/api_resources/test_organizations.py @@ -267,9 +267,11 @@ def test_method_list_members_with_all_params(self, client: Gitpod) -> None: token="token", page_size=0, filter={ + "exclude_group_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], "roles": ["ORGANIZATION_ROLE_UNSPECIFIED"], "search": "search", "statuses": ["USER_STATUS_UNSPECIFIED"], + "user_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], }, pagination={ "token": "token", @@ -604,9 +606,11 @@ async def test_method_list_members_with_all_params(self, async_client: AsyncGitp token="token", page_size=0, filter={ + "exclude_group_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], "roles": ["ORGANIZATION_ROLE_UNSPECIFIED"], "search": "search", "statuses": ["USER_STATUS_UNSPECIFIED"], + "user_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], }, pagination={ "token": "token", diff --git a/tests/api_resources/test_prebuilds.py b/tests/api_resources/test_prebuilds.py index 258dcef1..8d1518e7 100644 --- a/tests/api_resources/test_prebuilds.py +++ b/tests/api_resources/test_prebuilds.py @@ -122,8 +122,11 @@ def test_method_list_with_all_params(self, client: Gitpod) -> None: token="token", page_size=0, filter={ + "creator_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + "executor_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], "phases": ["PREBUILD_PHASE_UNSPECIFIED"], "project_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + "triggered_by": ["PREBUILD_TRIGGER_UNSPECIFIED"], }, pagination={ "token": "token", @@ -360,8 +363,11 @@ async def test_method_list_with_all_params(self, async_client: AsyncGitpod) -> N token="token", page_size=0, filter={ + "creator_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + "executor_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], "phases": ["PREBUILD_PHASE_UNSPECIFIED"], "project_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + "triggered_by": ["PREBUILD_TRIGGER_UNSPECIFIED"], }, pagination={ "token": "token", diff --git a/tests/test_utils/test_json.py b/tests/test_utils/test_json.py new file mode 100644 index 00000000..28f61d20 --- /dev/null +++ b/tests/test_utils/test_json.py @@ -0,0 +1,126 @@ +from __future__ import annotations + +import datetime +from typing import Union + +import pydantic + +from gitpod import _compat +from gitpod._utils._json import openapi_dumps + + +class TestOpenapiDumps: + def test_basic(self) -> None: + data = {"key": "value", "number": 42} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"key":"value","number":42}' + + def test_datetime_serialization(self) -> None: + dt = datetime.datetime(2023, 1, 1, 12, 0, 0) + data = {"datetime": dt} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"datetime":"2023-01-01T12:00:00"}' + + def test_pydantic_model_serialization(self) -> None: + class User(pydantic.BaseModel): + first_name: str + last_name: str + age: int + + model_instance = User(first_name="John", last_name="Kramer", age=83) + data = {"model": model_instance} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"model":{"first_name":"John","last_name":"Kramer","age":83}}' + + def test_pydantic_model_with_default_values(self) -> None: + class User(pydantic.BaseModel): + name: str + role: str = "user" + active: bool = True + score: int = 0 + + model_instance = User(name="Alice") + data = {"model": model_instance} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"model":{"name":"Alice"}}' + + def test_pydantic_model_with_default_values_overridden(self) -> None: + class User(pydantic.BaseModel): + name: str + role: str = "user" + active: bool = True + + model_instance = User(name="Bob", role="admin", active=False) + data = {"model": model_instance} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"model":{"name":"Bob","role":"admin","active":false}}' + + def test_pydantic_model_with_alias(self) -> None: + class User(pydantic.BaseModel): + first_name: str = pydantic.Field(alias="firstName") + last_name: str = pydantic.Field(alias="lastName") + + model_instance = User(firstName="John", lastName="Doe") + data = {"model": model_instance} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"model":{"firstName":"John","lastName":"Doe"}}' + + def test_pydantic_model_with_alias_and_default(self) -> None: + class User(pydantic.BaseModel): + user_name: str = pydantic.Field(alias="userName") + user_role: str = pydantic.Field(default="member", alias="userRole") + is_active: bool = pydantic.Field(default=True, alias="isActive") + + model_instance = User(userName="charlie") + data = {"model": model_instance} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"model":{"userName":"charlie"}}' + + model_with_overrides = User(userName="diana", userRole="admin", isActive=False) + data = {"model": model_with_overrides} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"model":{"userName":"diana","userRole":"admin","isActive":false}}' + + def test_pydantic_model_with_nested_models_and_defaults(self) -> None: + class Address(pydantic.BaseModel): + street: str + city: str = "Unknown" + + class User(pydantic.BaseModel): + name: str + address: Address + verified: bool = False + + if _compat.PYDANTIC_V1: + # to handle forward references in Pydantic v1 + User.update_forward_refs(**locals()) # type: ignore[reportDeprecated] + + address = Address(street="123 Main St") + user = User(name="Diana", address=address) + data = {"user": user} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"user":{"name":"Diana","address":{"street":"123 Main St"}}}' + + address_with_city = Address(street="456 Oak Ave", city="Boston") + user_verified = User(name="Eve", address=address_with_city, verified=True) + data = {"user": user_verified} + json_bytes = openapi_dumps(data) + assert ( + json_bytes == b'{"user":{"name":"Eve","address":{"street":"456 Oak Ave","city":"Boston"},"verified":true}}' + ) + + def test_pydantic_model_with_optional_fields(self) -> None: + class User(pydantic.BaseModel): + name: str + email: Union[str, None] + phone: Union[str, None] + + model_with_none = User(name="Eve", email=None, phone=None) + data = {"model": model_with_none} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"model":{"name":"Eve","email":null,"phone":null}}' + + model_with_values = User(name="Frank", email="frank@example.com", phone=None) + data = {"model": model_with_values} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"model":{"name":"Frank","email":"frank@example.com","phone":null}}'