diff --git a/.github/workflows/breaking-changes.yaml b/.github/workflows/breaking-changes.yaml new file mode 100644 index 0000000..c36ef41 --- /dev/null +++ b/.github/workflows/breaking-changes.yaml @@ -0,0 +1,62 @@ +name: OpenAPI Breaking Changes +on: + pull_request: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + detect-breaking-changes: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + # 1. Checkout Branches + - name: Checkout PR + uses: actions/checkout@v4 + with: + path: pr + persist-credentials: false + + - name: Checkout Base Branch + uses: actions/checkout@v4 + with: + ref: ${{ github.base_ref }} + path: base + persist-credentials: false + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: 'yarn' + cache-dependency-path: | + pr/yarn.lock + base/yarn.lock + + # 2. Build Specs + - name: Build PR Spec + working-directory: pr + run: | + yarn install --frozen-lockfile --ignore-scripts + yarn build + + - name: Build Base Spec + working-directory: base + run: | + yarn install --frozen-lockfile --ignore-scripts + yarn build + + # 3. Compare with oasdiff + - name: Check for Breaking Changes + uses: oasdiff/oasdiff-action/breaking@v0.0.37 + with: + base: 'base/dist/latest/openapi.yaml' + revision: 'pr/dist/latest/openapi.yaml' + fail-on: 'ERR' + diff --git a/apis/cf/latest/components/parameters/UserGuid.yaml b/apis/cf/latest/components/parameters/UserGuid.yaml new file mode 100644 index 0000000..3de29c3 --- /dev/null +++ b/apis/cf/latest/components/parameters/UserGuid.yaml @@ -0,0 +1,6 @@ +name: guid +in: path +required: true +schema: + type: string +description: The unique identifier for the user, matching either a UAA user id or client id. A client id may not be a uuid. diff --git a/apis/cf/latest/components/requestBodies/RoleCreate.yaml b/apis/cf/latest/components/requestBodies/RoleCreate.yaml index 4c7b997..29abf2e 100644 --- a/apis/cf/latest/components/requestBodies/RoleCreate.yaml +++ b/apis/cf/latest/components/requestBodies/RoleCreate.yaml @@ -20,8 +20,7 @@ content: type: object properties: user: - $ref: '../schemas/RelationshipToOne.yaml' - description: A relationship to a user; the user can be defined by either a `guid` or, if the `set_roles_by_username` [feature_flag](#list-of-feature-flags) is enabled, a `username` (with the option of including an `origin` to disambiguate it) + $ref: '../schemas/UserRelationshipToOne.yaml' organization: $ref: '../schemas/RelationshipToOne.yaml' description: A relationship to an organization; required only when creating an organization role diff --git a/apis/cf/latest/components/schemas/Deployment.yaml b/apis/cf/latest/components/schemas/Deployment.yaml index 3261efe..fb28d35 100644 --- a/apis/cf/latest/components/schemas/Deployment.yaml +++ b/apis/cf/latest/components/schemas/Deployment.yaml @@ -44,6 +44,31 @@ allOf: max_in_flight: type: integer description: The maximum number of new instances to deploy simultaneously + web_instances: + type: integer + description: The number of instances for the web process of the new droplet + memory_in_mb: + type: integer + description: The amount of memory in megabytes to allocate for the web process + disk_in_mb: + type: integer + description: The amount of disk space in megabytes to allocate for the web process + log_rate_limit_in_bytes_per_second: + type: integer + description: The log rate limit in bytes per second for the web process. A value of -1 indicates unlimited, 0 prevents any logs from being emitted. + canary: + type: object + description: Configuration for canary deployments. Present when strategy is 'canary'. + properties: + steps: + type: array + description: Array of steps defining the canary deployment progression + items: + type: object + properties: + instance_weight: + type: integer + description: The percentage of instances to be deployed as part of the canary process in this step droplet: type: object properties: diff --git a/apis/cf/latest/components/schemas/IndexLink.yaml b/apis/cf/latest/components/schemas/IndexLink.yaml new file mode 100644 index 0000000..bb19381 --- /dev/null +++ b/apis/cf/latest/components/schemas/IndexLink.yaml @@ -0,0 +1,19 @@ +allOf: + - $ref: ./Link.yaml + - type: object + properties: + meta: + type: object + description: Contains metadata about the link + properties: + version: + type: string + description: The version of the API + host_key_fingerprint: + type: string + description: The host key fingerprint of the link + oauth_client: + type: string + description: The oauth client for the link +description: | + Each link is keyed by its type and will include a href for the URL and an optional method for links that cannot be followed using GET. Can include a meta object with metadata about the link. diff --git a/apis/cf/latest/components/schemas/OrganizationList.yaml b/apis/cf/latest/components/schemas/OrganizationList.yaml index e8f28da..f23e060 100644 --- a/apis/cf/latest/components/schemas/OrganizationList.yaml +++ b/apis/cf/latest/components/schemas/OrganizationList.yaml @@ -1,9 +1,9 @@ type: object -allOf: - - $ref: './Pagination.yaml' - - properties: - resources: - type: array - items: - $ref: './Organization.yaml' +properties: + pagination: + $ref: './Pagination.yaml' + resources: + type: array + items: + $ref: './Organization.yaml' description: A paginated list of organizations diff --git a/apis/cf/latest/components/schemas/PaginatedUsers.yaml b/apis/cf/latest/components/schemas/PaginatedUsers.yaml deleted file mode 100644 index 5fac46b..0000000 --- a/apis/cf/latest/components/schemas/PaginatedUsers.yaml +++ /dev/null @@ -1,10 +0,0 @@ -allOf: - - $ref: './BaseSchema.yaml' - - type: object - properties: - pagination: - $ref: './Pagination.yaml' - resources: - type: array - items: - $ref: './User.yaml' diff --git a/apis/cf/latest/components/schemas/Role.yaml b/apis/cf/latest/components/schemas/Role.yaml index fcbb6ed..f49bb3e 100644 --- a/apis/cf/latest/components/schemas/Role.yaml +++ b/apis/cf/latest/components/schemas/Role.yaml @@ -39,7 +39,7 @@ properties: A relationship to the space the role controls access to; when this is an organization role, `space.data` will be `null`. user: allOf: - - $ref: './RelationshipToOne.yaml' + - $ref: './UserRelationshipToOne.yaml' - description: | A relationship to the user; this is the user that has the role links: diff --git a/apis/cf/latest/components/schemas/User.yaml b/apis/cf/latest/components/schemas/User.yaml index 5c9414e..6252481 100644 --- a/apis/cf/latest/components/schemas/User.yaml +++ b/apis/cf/latest/components/schemas/User.yaml @@ -1,21 +1,30 @@ type: object -allOf: - - $ref: './BaseSchema.yaml' - - properties: - username: - type: [string, "null"] - description: The username of the user - presentation_name: - type: string - description: The presentation name of the user - origin: - type: [string, "null"] - description: The origin of the user - metadata: - $ref: './Metadata.yaml' - links: - type: object - properties: - self: - $ref: './Link.yaml' - description: The URL to get this user \ No newline at end of file +properties: + guid: + type: string + description: Unique identifier for the user, matching either a UAA user id or client id. A client id may not be a uuid. + created_at: + type: string + format: date-time + description: The ISO8601 compatible date and time when resource was created + updated_at: + type: string + format: date-time + description: The ISO8601 compatible date and time when resource was last updated + username: + type: [string, "null"] + description: The username of the user + presentation_name: + type: string + description: The presentation name of the user + origin: + type: [string, "null"] + description: The origin of the user + metadata: + $ref: './Metadata.yaml' + links: + type: object + properties: + self: + $ref: './Link.yaml' + description: The URL to get this user \ No newline at end of file diff --git a/apis/cf/latest/components/schemas/UserRelationshipToOne.yaml b/apis/cf/latest/components/schemas/UserRelationshipToOne.yaml new file mode 100644 index 0000000..12e2fef --- /dev/null +++ b/apis/cf/latest/components/schemas/UserRelationshipToOne.yaml @@ -0,0 +1,30 @@ +type: [object, "null"] +properties: + data: + type: object + description: | + User relationship data that can be specified either by GUID or by username and origin. + When using username and origin, the set_roles_by_username feature flag must be enabled. + oneOf: + - type: object + properties: + guid: + type: string + description: The GUID of the user, matching either a UAA user id or client id. A client id may not be a uuid. + required: + - guid + additionalProperties: false + - type: object + properties: + username: + type: string + description: The username of the user + origin: + type: string + description: The identity provider for the user (e.g., 'ldap', 'saml'). Optional field to disambiguate the username. + required: + - username + additionalProperties: false + description: | + User relationship data that can be specified either by GUID or by username and origin. + Set to null to clear the relationship. \ No newline at end of file diff --git a/apis/cf/latest/openapi.yaml b/apis/cf/latest/openapi.yaml index 296df2c..dcd3c9c 100644 --- a/apis/cf/latest/openapi.yaml +++ b/apis/cf/latest/openapi.yaml @@ -1,7 +1,7 @@ openapi: 3.1.0 info: title: Cloud Foundry V3 API - description: "# Welcome to the Cloud Foundry V3 API docs! This is the latest available specification. \n\n# Getting help\nThe CAPI team can most easily be reached on our Slack channel for questions and issues regarding the API. To report an issue with the docs or API, please feel free to file a GitHub issue on our API repo, cloud_controller_ng.\nWe recommend reaching out to Slack first as we will be most responsive there.\n \n# More resources\n- The Cloud Foundry V2 API is still deprecated but still available for interacting with Cloud Foundry.\n- Running Tasks\n- V3 API Documentation OpenAPI Spec Source Code. " + description: "# Welcome to the Experimental Cloud Foundry V3 API Docs! \n\n# Expermiental Warning\n This OpenAPI specification is a experiment and not ready for productive use.\n# Getting help\nThe CAPI team can most easily be reached on our Slack channel for questions and issues regarding the API. To report an issue with the docs or API, please feel free to file a GitHub issue on our API repo, cloud_controller_ng.\nWe recommend reaching out to Slack first as we will be most responsive there.\n \n# More resources\n- The Cloud Foundry V2 API is still deprecated but still available for interacting with Cloud Foundry.\n- Running Tasks\n- V3 API Documentation OpenAPI Spec Source Code. " version: latest license: name: Apache 2.0 @@ -107,7 +107,10 @@ components: $ref: './components/schemas/RelationshipToOne.yaml' RelationshipToMany: $ref: './components/schemas/RelationshipToMany.yaml' - + UserRelationshipToOne: + $ref: './components/schemas/UserRelationshipToOne.yaml' + IncludedResources: + $ref: './components/schemas/IncludedResources.yaml' Link: $ref: './components/schemas/Link.yaml' Pagination: @@ -120,8 +123,6 @@ components: $ref: './components/schemas/BuildpackList.yaml' User: $ref: './components/schemas/User.yaml' - PaginatedUsers: - $ref: './components/schemas/PaginatedUsers.yaml' Droplet: $ref: './components/schemas/Droplet.yaml' DropletList: @@ -445,6 +446,8 @@ paths: $ref: './paths/IsolationSegments.yaml#/~1v3~1isolation_segments~1{guid}~1relationships~1organizations~1{org_guid}' /v3/isolation_segments/{guid}/relationships/spaces: $ref: './paths/IsolationSegments.yaml#/~1v3~1isolation_segments~1{guid}~1relationships~1spaces' + /v3/isolation_segments/{guid}/organizations: + $ref: './paths/IsolationSegments.yaml#/~1v3~1isolation_segments~1{guid}~1organizations' /v3/jobs/{guid}: $ref: './paths/Jobs.yaml#/~1v3~1jobs~1{guid}' /v3/resource_matches: @@ -539,6 +542,8 @@ paths: $ref: './paths/Spaces.yaml#/~1v3~1spaces~1{guid}~1relationships~1isolation_segment' /v3/spaces/{guid}/routes: $ref: './paths/Spaces.yaml#/~1v3~1spaces~1{guid}~1routes' + /v3/spaces/{guid}/usage_summary: + $ref: './paths/Spaces.yaml#/~1v3~1spaces~1{guid}~1usage_summary' /v3/spaces/{guid}/running_security_groups: $ref: './paths/Spaces.yaml#/~1v3~1spaces~1{guid}~1running_security_groups' /v3/spaces/{guid}/staging_security_groups: @@ -605,6 +610,8 @@ paths: $ref: './paths/Processes.yaml#/~1v3~1processes' /v3/processes/{guid}: $ref: './paths/Processes.yaml#/~1v3~1processes~1{guid}' + /v3/processes/{guid}/process_instances: + $ref: './paths/Processes.yaml#/~1v3~1processes~1{guid}~1process_instances' /v3/processes/{guid}/stats: $ref: './paths/Processes.yaml#/~1v3~1processes~1{guid}~1stats' /v3/processes/{guid}/actions/scale: diff --git a/apis/cf/latest/paths/Builds.yaml b/apis/cf/latest/paths/Builds.yaml index bd3dd3a..54848a8 100644 --- a/apis/cf/latest/paths/Builds.yaml +++ b/apis/cf/latest/paths/Builds.yaml @@ -145,7 +145,7 @@ droplet: operationId: getDroplet parameters: - guid: $response.body#/droplet/data/guid + guid: $response.body#/droplet/guid description: Retrieve the droplet for this build '401': $ref: '../components/responses/Unauthorized.yaml' diff --git a/apis/cf/latest/paths/Deployments.yaml b/apis/cf/latest/paths/Deployments.yaml index b27b47b..40fcc47 100644 --- a/apis/cf/latest/paths/Deployments.yaml +++ b/apis/cf/latest/paths/Deployments.yaml @@ -96,6 +96,39 @@ enum: - rolling - canary + options: + type: object + properties: + max_in_flight: + type: integer + description: The maximum number of instances that will be deployed simultaneously + default: 1 + minimum: 1 + web_instances: + type: integer + description: The number of instances for the web process of the new droplet + memory_in_mb: + type: integer + description: The amount of memory in megabytes to allocate for the web process + disk_in_mb: + type: integer + description: The amount of disk space in megabytes to allocate for the web process + log_rate_limit_in_bytes_per_second: + type: integer + description: The log rate limit in bytes per second for the web process. A value of -1 indicates unlimited, 0 prevents any logs from being emitted. + canary: + type: object + description: Canary steps to use for the deployment. Only available for deployments with strategy ‘canary’. + properties: + steps: + type: array + description: Array of steps defining the canary deployment progression + items: + type: object + properties: + instance_weight: + type: integer + description: The percentage of instances to be deployed as part of the canary process in this step droplet: $ref: '../components/schemas/Relationship.yaml' revision: diff --git a/apis/cf/latest/paths/Processes.yaml b/apis/cf/latest/paths/Processes.yaml index 1cddf91..4150940 100644 --- a/apis/cf/latest/paths/Processes.yaml +++ b/apis/cf/latest/paths/Processes.yaml @@ -147,6 +147,55 @@ $ref: '../components/responses/ServiceUnavailable.yaml' '409': $ref: '../components/responses/Conflict.yaml' +/v3/processes/{guid}/process_instances: + get: + summary: List instances for a process + description: Retrieve the instances for a process. Unlike the stats endpoint, + this returns a simplified view with only the index, state, and uptime of each + instance. + operationId: listProcessInstances + tags: + - Processes + parameters: + - $ref: '../components/parameters/Guid.yaml' + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + resources: + type: array + items: + type: object + properties: + index: + type: integer + state: + type: string + enum: + - RUNNING + - CRASHED + - STARTING + - DOWN + since: + type: number + format: double + links: + type: object + properties: + self: + $ref: '../components/schemas/Link.yaml' + process: + $ref: '../components/schemas/Link.yaml' + '401': + $ref: '../components/responses/Unauthorized.yaml' + '404': + $ref: '../components/responses/NotFound.yaml' + '403': + $ref: '../components/responses/Forbidden.yaml' /v3/processes/{guid}/stats: get: summary: Get stats for a process @@ -189,22 +238,22 @@ type: - integer - 'null' - - string + description: The number of instances to run memory_in_mb: type: - integer - 'null' - - string + description: The memory in MB allocated per instance disk_in_mb: type: - integer - 'null' - - string + description: The disk in MB allocated per instance log_rate_limit_in_bytes_per_second: type: - integer - 'null' - - string + description: The log rate limit in bytes per second per instance responses: '202': description: Accepted @@ -395,20 +444,22 @@ type: - integer - 'null' - - string + description: The number of instances to run memory_in_mb: type: - integer - 'null' - - string + description: The memory in MB allocated per instance disk_in_mb: type: - integer - 'null' + description: The disk in MB allocated per instance log_rate_limit_in_bytes_per_second: type: - integer - 'null' + description: The log rate limit in bytes per second per instance responses: '202': description: Accepted diff --git a/apis/cf/latest/paths/Root.yaml b/apis/cf/latest/paths/Root.yaml index 0410b8f..43d47b2 100644 --- a/apis/cf/latest/paths/Root.yaml +++ b/apis/cf/latest/paths/Root.yaml @@ -19,35 +19,35 @@ get: properties: self: allOf: - - $ref: '../components/schemas/Link.yaml' + - $ref: '../components/schemas/IndexLink.yaml' - description: Link to the current endpoint cloud_controller_v2: allOf: - - $ref: '../components/schemas/Link.yaml' + - $ref: '../components/schemas/IndexLink.yaml' - description: Link to the Cloud Controller V2 API cloud_controller_v3: allOf: - - $ref: '../components/schemas/Link.yaml' + - $ref: '../components/schemas/IndexLink.yaml' - description: Link to the Cloud Controller V3 API network_policy_v1: allOf: - - $ref: '../components/schemas/Link.yaml' + - $ref: '../components/schemas/IndexLink.yaml' - description: Link to the Network Policy V1 API uaa: allOf: - - $ref: '../components/schemas/Link.yaml' + - $ref: '../components/schemas/IndexLink.yaml' - description: Link to the UAA API logging: allOf: - - $ref: '../components/schemas/Link.yaml' + - $ref: '../components/schemas/IndexLink.yaml' - description: Link to the Logging API log_cache: allOf: - - $ref: '../components/schemas/Link.yaml' + - $ref: '../components/schemas/IndexLink.yaml' - description: Link to the Log Cache API log_stream: allOf: - - $ref: '../components/schemas/Link.yaml' + - $ref: '../components/schemas/IndexLink.yaml' - description: Link to the Log Stream API '404': $ref: '../components/responses/NotFound.yaml' diff --git a/apis/cf/latest/paths/Routes.yaml b/apis/cf/latest/paths/Routes.yaml index e336a13..48466b4 100644 --- a/apis/cf/latest/paths/Routes.yaml +++ b/apis/cf/latest/paths/Routes.yaml @@ -534,45 +534,6 @@ $ref: '../components/responses/UnprocessableEntity.yaml' '404': $ref: '../components/responses/NotFound.yaml' - put: - summary: Replace all destinations for a route - description: 'Replaces all destinations for a route, removing any destinations - not included in the provided list. - - - Weighted destinations are **deprecated**. Development of the experimental Istio - Service Mesh routing layer was discontinued in 2020 and is no longer supported - by the platform. Specifying a `weight` for a destination will take no effect. - - - If weighted destinations are provided, however, all destinations provided here - must have a `weight` specified, and all weights for this route must sum to 100. - If not, all provided destinations must not have a `weight`. Mixing weighted - and unweighted destinations for a route is not allowed.' - operationId: replaceDestinationsForRoute - tags: - - Routes - parameters: - - $ref: '../components/parameters/Guid.yaml' - requestBody: - $ref: '../components/requestBodies/RouteDestinations.yaml' - responses: - '200': - description: List of destinations for the route - content: - application/json: - schema: - $ref: '../components/schemas/RouteDestinationList.yaml' - '400': - $ref: '../components/responses/BadRequest.yaml' - '401': - $ref: '../components/responses/Unauthorized.yaml' - '403': - $ref: '../components/responses/Forbidden.yaml' - '422': - $ref: '../components/responses/UnprocessableEntity.yaml' - '500': - $ref: '../components/responses/500.yaml' /v3/routes/{guid}/destinations/{destination_guid}: patch: summary: Update a destination protocol for a route diff --git a/apis/cf/latest/paths/Spaces.yaml b/apis/cf/latest/paths/Spaces.yaml index fd34bf1..8864d89 100644 --- a/apis/cf/latest/paths/Spaces.yaml +++ b/apis/cf/latest/paths/Spaces.yaml @@ -483,6 +483,58 @@ $ref: '../components/responses/Forbidden.yaml' '422': $ref: '../components/responses/UnprocessableEntity.yaml' +/v3/spaces/{guid}/usage_summary: + get: + summary: Get usage summary for a space + description: This endpoint retrieves the specified space's memory and app instance + usage summary. + operationId: getUsageSummaryForSpace + tags: + - Spaces + parameters: + - $ref: '../components/parameters/Guid.yaml' + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + usage_summary: + type: object + properties: + started_instances: + type: integer + memory_in_mb: + type: integer + routes: + type: integer + service_instances: + type: integer + reserved_ports: + type: integer + domains: + type: integer + per_app_tasks: + type: integer + service_keys: + type: integer + links: + type: object + properties: + self: + $ref: '../components/schemas/Link.yaml' + description: The URL to get this usage summary + space: + $ref: '../components/schemas/Link.yaml' + description: The URL to get the space for this usage summary + '401': + $ref: '../components/responses/Unauthorized.yaml' + '404': + $ref: '../components/responses/NotFound.yaml' + '403': + $ref: '../components/responses/Forbidden.yaml' /v3/spaces/{guid}/running_security_groups: get: summary: List running security groups for a space diff --git a/apis/cf/latest/paths/Users.yaml b/apis/cf/latest/paths/Users.yaml index b46f92d..f844746 100644 --- a/apis/cf/latest/paths/Users.yaml +++ b/apis/cf/latest/paths/Users.yaml @@ -18,7 +18,7 @@ type: array items: type: string - description: Comma-delimited list of user guids to filter by + description: Comma-delimited list of user guids to filter by (can include UAA user IDs or client IDs) - name: usernames in: query schema: @@ -46,7 +46,7 @@ content: application/json: schema: - $ref: '../components/schemas/PaginatedUsers.yaml' + $ref: '../components/schemas/UserList.yaml' '400': $ref: '../components/responses/BadRequest.yaml' '401': @@ -111,7 +111,7 @@ tags: - Users parameters: - - $ref: '../components/parameters/Guid.yaml' + - $ref: '../components/parameters/UserGuid.yaml' responses: '200': description: OK @@ -127,12 +127,12 @@ $ref: '../components/responses/Forbidden.yaml' patch: summary: Update a user - description: Update a user’s metadata. + description: Update a user's metadata. operationId: updateUser tags: - Users parameters: - - $ref: '../components/parameters/Guid.yaml' + - $ref: '../components/parameters/UserGuid.yaml' requestBody: $ref: '../components/requestBodies/UserUpdate.yaml' responses: @@ -161,7 +161,7 @@ tags: - Users parameters: - - $ref: '../components/parameters/Guid.yaml' + - $ref: '../components/parameters/UserGuid.yaml' responses: '202': description: Accepted