Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions sdk/openapi/cloud.openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,9 @@ paths:
application/json:
schema: { $ref: '#/components/schemas/ServiceSettings' }
default: { $ref: '#/components/responses/Error' }
/api/cloud/services/{serviceId}/port: { $ref: 'services.yaml#/paths/port' }
/api/cloud/services/{serviceId}/network: { $ref: 'services.yaml#/paths/network' }
/api/cloud/services/{serviceId}/variables/references: { $ref: 'services.yaml#/paths/variableReferences' }
/api/cloud/services/{serviceId}/source-deployments:
post:
operationId: deploySource
Expand Down
126 changes: 126 additions & 0 deletions sdk/openapi/services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
paths:
port:
put:
operationId: setServicePort
description: |
Sets the port the service's container listens on, or clears it with null. A service a
project creation builds from a repository starts without one, and cannot be deployed
until it has one: a deployment asked before fails with `cloud.errors.builds.missing_port`.

The running revision keeps the port it was deployed with; the next deployment takes the
new one.
security: [{ bearerAuth: [] }]
parameters:
- in: path
name: serviceId
required: true
schema: { type: string }
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [port]
properties:
port:
description: The port the container listens on; null for a service that listens on none.
type: [integer, "null"]
minimum: 1024
maximum: 65535
responses:
'200':
description: Done
'400':
description: '`cloud.errors.settings.invalid_port`: the port is not an integer from 1024 to 65535.'
content:
application/json:
schema: { $ref: './cloud.openapi.yaml#/components/schemas/Error' }
'409':
description: '`cloud.errors.settings.public_needs_port`: a public service cannot lose its port. `cloud.errors.settings.preview_read_only`: a preview mirrors its environment and is not edited.'
content:
application/json:
schema: { $ref: './cloud.openapi.yaml#/components/schemas/Error' }
default: { $ref: './cloud.openapi.yaml#/components/responses/Error' }
variableReferences:
post:
operationId: followPublishedValue
description: |
Adds a variable to the service that follows a value another service of the same
environment publishes, such as the `MONGO_URL` of a MongoDB resource: the variable takes
the published value, and takes the new one when it changes. Listed afterwards with a
`resource` origin. The value itself is never sent to the client.
security: [{ bearerAuth: [] }]
parameters:
- in: path
name: serviceId
required: true
schema: { type: string }
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [key, serviceId, publishedKey]
properties:
key:
description: The name of the variable on the service.
type: string
serviceId:
description: The service that publishes the value.
type: string
publishedKey:
description: The key the publisher publishes the value under.
type: string
responses:
'200':
description: Done
'400':
description: '`cloud.errors.settings.invalid_key`: the name is not a valid variable name. `cloud.errors.settings.self_reference`: a service cannot follow its own value.'
content:
application/json:
schema: { $ref: './cloud.openapi.yaml#/components/schemas/Error' }
'404':
description: '`cloud.errors.settings.unknown_publisher`: the environment has no such service. `cloud.errors.settings.key_not_published`: the publisher publishes no such key.'
content:
application/json:
schema: { $ref: './cloud.openapi.yaml#/components/schemas/Error' }
'409':
description: '`cloud.errors.settings.duplicate_key`: the service already holds a variable of that name. `cloud.errors.settings.preview_read_only`: a preview mirrors its environment and is not edited.'
content:
application/json:
schema: { $ref: './cloud.openapi.yaml#/components/schemas/Error' }
default: { $ref: './cloud.openapi.yaml#/components/responses/Error' }
network:
put:
operationId: setServiceExposure
description: |
Opens the service to the internet on its own address, or closes it. A service is created
closed. Sending the exposure it already has changes nothing.
security: [{ bearerAuth: [] }]
parameters:
- in: path
name: serviceId
required: true
schema: { type: string }
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [isPublic]
properties:
isPublic:
description: Whether the internet reaches the service on its own address.
type: boolean
responses:
'200':
description: Done
'409':
description: '`cloud.errors.settings.public_needs_port`: a service without a port cannot be opened. `cloud.errors.settings.subdomain_taken`: another service holds its address. `cloud.errors.settings.preview_read_only`: a preview mirrors its environment and is not edited.'
content:
application/json:
schema: { $ref: './cloud.openapi.yaml#/components/schemas/Error' }
default: { $ref: './cloud.openapi.yaml#/components/responses/Error' }
64 changes: 64 additions & 0 deletions sdk/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ export interface CreateProjectOptions {
idempotencyKey?: string;
}

/** A value a service publishes to the other services of its environment. */
export interface PublishedValue {
/** The service that publishes the value. */
serviceId: string;
/** The key it publishes the value under. */
publishedKey: string;
}

/** How a log read is shaped: one bounded page, or a tail from a cursor. */
export interface LogRequest {
follow: boolean;
Expand Down Expand Up @@ -265,6 +273,62 @@ export class CloudApi {
return dataOf(result);
}

/**
* Sets the port the service's container listens on, from 1024 to 65535, or
* clears it with null. A service created from a repository has none, and is
* refused its deployments until it has one. The running revision keeps its
* port; the next deployment takes the new one.
*/
async setServicePort(serviceId: string, port: number | null): Promise<void> {
const result = await this.client.PUT(
"/api/cloud/services/{serviceId}/port",
{ params: { path: { serviceId } }, body: { port }, parseAs: "text" },
);
acceptedOf(result);
}

/**
* Opens the service to the internet on its own address, or closes it. A
* service without a port is refused with
* `cloud.errors.settings.public_needs_port`.
*/
async setServiceExposure(
serviceId: string,
isPublic: boolean,
): Promise<void> {
const result = await this.client.PUT(
"/api/cloud/services/{serviceId}/network",
{ params: { path: { serviceId } }, body: { isPublic }, parseAs: "text" },
);
acceptedOf(result);
}

/**
* Adds a variable to the service that follows a value another service of
* its environment publishes, such as the `MONGO_URL` of a MongoDB resource.
* The value never reaches the client; the variable is then listed with a
* `resource` origin.
*
* @param serviceId The service that gets the variable
* @param key The variable's name on that service
* @param published The publishing service and the key it publishes
*/
async followPublishedValue(
serviceId: string,
key: string,
published: PublishedValue,
): Promise<void> {
const result = await this.client.POST(
"/api/cloud/services/{serviceId}/variables/references",
{
params: { path: { serviceId } },
body: { key, ...published },
parseAs: "text",
},
);
acceptedOf(result);
}

async deploymentHistory(serviceId: string) {
const result = await this.client.GET(
"/api/cloud/services/{serviceId}/deployments",
Expand Down
Loading
Loading