@vibesdotdev/integrations-digitalocean 0.0.0-stage → 1.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +126 -0
- package/README.md +78 -2
- package/dist/ai/index.d.ts +4 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +4 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/inference.transport.impl.d.ts +5 -0
- package/dist/ai/inference.transport.impl.d.ts.map +1 -0
- package/dist/ai/inference.transport.impl.js +54 -0
- package/dist/ai/inference.transport.impl.js.map +1 -0
- package/dist/ai/provider.plugin.d.ts +6 -0
- package/dist/ai/provider.plugin.d.ts.map +1 -0
- package/dist/ai/provider.plugin.js +126 -0
- package/dist/ai/provider.plugin.js.map +1 -0
- package/dist/ai/providers/cloud/frontier/digitalocean/config/schemas/index.d.ts +62 -0
- package/dist/ai/providers/cloud/frontier/digitalocean/config/schemas/index.d.ts.map +1 -0
- package/dist/ai/providers/cloud/frontier/digitalocean/config/schemas/index.js +73 -0
- package/dist/ai/providers/cloud/frontier/digitalocean/config/schemas/index.js.map +1 -0
- package/dist/ai/providers/cloud/frontier/digitalocean/index.d.ts +2 -0
- package/dist/ai/providers/cloud/frontier/digitalocean/index.d.ts.map +1 -0
- package/dist/ai/providers/cloud/frontier/digitalocean/index.js +2 -0
- package/dist/ai/providers/cloud/frontier/digitalocean/index.js.map +1 -0
- package/dist/ai/providers/cloud/frontier/digitalocean/provider.digitalocean.descriptor.d.ts +183 -0
- package/dist/ai/providers/cloud/frontier/digitalocean/provider.digitalocean.descriptor.d.ts.map +1 -0
- package/dist/ai/providers/cloud/frontier/digitalocean/provider.digitalocean.descriptor.js +66 -0
- package/dist/ai/providers/cloud/frontier/digitalocean/provider.digitalocean.descriptor.js.map +1 -0
- package/dist/apps/api-client.d.ts +45 -0
- package/dist/apps/api-client.d.ts.map +1 -0
- package/dist/apps/api-client.js +47 -0
- package/dist/apps/api-client.js.map +1 -0
- package/dist/apps/build-spec.d.ts +44 -0
- package/dist/apps/build-spec.d.ts.map +1 -0
- package/dist/apps/build-spec.js +463 -0
- package/dist/apps/build-spec.js.map +1 -0
- package/dist/apps/deploy-client.d.ts +42 -0
- package/dist/apps/deploy-client.d.ts.map +1 -0
- package/dist/apps/deploy-client.js +300 -0
- package/dist/apps/deploy-client.js.map +1 -0
- package/dist/apps/index.d.ts +5 -0
- package/dist/apps/index.d.ts.map +1 -0
- package/dist/apps/index.js +4 -0
- package/dist/apps/index.js.map +1 -0
- package/dist/apps/types.d.ts +204 -0
- package/dist/apps/types.d.ts.map +1 -0
- package/dist/apps/types.js +13 -0
- package/dist/apps/types.js.map +1 -0
- package/dist/client/control-plane.d.ts +49 -0
- package/dist/client/control-plane.d.ts.map +1 -0
- package/dist/client/control-plane.js +85 -0
- package/dist/client/control-plane.js.map +1 -0
- package/dist/client/do-fetch.d.ts +41 -0
- package/dist/client/do-fetch.d.ts.map +1 -0
- package/dist/client/do-fetch.js +199 -0
- package/dist/client/do-fetch.js.map +1 -0
- package/dist/client/errors.d.ts +6 -0
- package/dist/client/errors.d.ts.map +1 -0
- package/dist/client/errors.js +34 -0
- package/dist/client/errors.js.map +1 -0
- package/dist/client/factory.d.ts +53 -0
- package/dist/client/factory.d.ts.map +1 -0
- package/dist/client/factory.js +220 -0
- package/dist/client/factory.js.map +1 -0
- package/dist/client/helpers.d.ts +5 -0
- package/dist/client/helpers.d.ts.map +1 -0
- package/dist/client/helpers.js +8 -0
- package/dist/client/helpers.js.map +1 -0
- package/dist/client/index.d.ts +12 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +10 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/paginated.d.ts +19 -0
- package/dist/client/paginated.d.ts.map +1 -0
- package/dist/client/paginated.js +56 -0
- package/dist/client/paginated.js.map +1 -0
- package/dist/client/retry.d.ts +34 -0
- package/dist/client/retry.d.ts.map +1 -0
- package/dist/client/retry.js +53 -0
- package/dist/client/retry.js.map +1 -0
- package/dist/config/digitalocean.config.descriptor.d.ts +197 -0
- package/dist/config/digitalocean.config.descriptor.d.ts.map +1 -0
- package/dist/config/digitalocean.config.descriptor.js +59 -0
- package/dist/config/digitalocean.config.descriptor.js.map +1 -0
- package/dist/credentials/index.d.ts +38 -0
- package/dist/credentials/index.d.ts.map +1 -0
- package/dist/credentials/index.js +56 -0
- package/dist/credentials/index.js.map +1 -0
- package/dist/databases/index.d.ts +82 -0
- package/dist/databases/index.d.ts.map +1 -0
- package/dist/databases/index.js +57 -0
- package/dist/databases/index.js.map +1 -0
- package/dist/digitalocean-friction.policy.d.ts +29 -0
- package/dist/digitalocean-friction.policy.d.ts.map +1 -0
- package/dist/digitalocean-friction.policy.js +21 -0
- package/dist/digitalocean-friction.policy.js.map +1 -0
- package/dist/digitalocean.plugin.d.ts +3 -0
- package/dist/digitalocean.plugin.d.ts.map +1 -0
- package/dist/digitalocean.plugin.js +27 -0
- package/dist/digitalocean.plugin.js.map +1 -0
- package/dist/droplets/index.d.ts +106 -0
- package/dist/droplets/index.d.ts.map +1 -0
- package/dist/droplets/index.js +227 -0
- package/dist/droplets/index.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/inference-control-plane/index.d.ts +63 -0
- package/dist/inference-control-plane/index.d.ts.map +1 -0
- package/dist/inference-control-plane/index.js +93 -0
- package/dist/inference-control-plane/index.js.map +1 -0
- package/dist/infra/billing.d.ts +26 -0
- package/dist/infra/billing.d.ts.map +1 -0
- package/dist/infra/billing.js +43 -0
- package/dist/infra/billing.js.map +1 -0
- package/dist/infra/credentials.d.ts +11 -0
- package/dist/infra/credentials.d.ts.map +1 -0
- package/dist/infra/credentials.js +15 -0
- package/dist/infra/credentials.js.map +1 -0
- package/dist/infra/deployment-provider/deploy-secrets.d.ts +10 -0
- package/dist/infra/deployment-provider/deploy-secrets.d.ts.map +1 -0
- package/dist/infra/deployment-provider/deploy-secrets.js +66 -0
- package/dist/infra/deployment-provider/deploy-secrets.js.map +1 -0
- package/dist/infra/deployment-provider/digitalocean-deployment-provider.impl.d.ts +97 -0
- package/dist/infra/deployment-provider/digitalocean-deployment-provider.impl.d.ts.map +1 -0
- package/dist/infra/deployment-provider/digitalocean-deployment-provider.impl.js +242 -0
- package/dist/infra/deployment-provider/digitalocean-deployment-provider.impl.js.map +1 -0
- package/dist/infra/deployment-provider/image-publish.d.ts +39 -0
- package/dist/infra/deployment-provider/image-publish.d.ts.map +1 -0
- package/dist/infra/deployment-provider/image-publish.js +146 -0
- package/dist/infra/deployment-provider/image-publish.js.map +1 -0
- package/dist/infra/deployment-provider.descriptor.d.ts +34 -0
- package/dist/infra/deployment-provider.descriptor.d.ts.map +1 -0
- package/dist/infra/deployment-provider.descriptor.js +9 -0
- package/dist/infra/deployment-provider.descriptor.js.map +1 -0
- package/dist/infra/digitalocean-infra.plugin.d.ts +101 -0
- package/dist/infra/digitalocean-infra.plugin.d.ts.map +1 -0
- package/dist/infra/digitalocean-infra.plugin.js +283 -0
- package/dist/infra/digitalocean-infra.plugin.js.map +1 -0
- package/dist/infra/doks/clients.d.ts +183 -0
- package/dist/infra/doks/clients.d.ts.map +1 -0
- package/dist/infra/doks/clients.js +172 -0
- package/dist/infra/doks/clients.js.map +1 -0
- package/dist/infra/doks/digitalocean.d.ts +34 -0
- package/dist/infra/doks/digitalocean.d.ts.map +1 -0
- package/dist/infra/doks/digitalocean.js +267 -0
- package/dist/infra/doks/digitalocean.js.map +1 -0
- package/dist/infra/doks/service-release-schemas.d.ts +1037 -0
- package/dist/infra/doks/service-release-schemas.d.ts.map +1 -0
- package/dist/infra/doks/service-release-schemas.js +51 -0
- package/dist/infra/doks/service-release-schemas.js.map +1 -0
- package/dist/infra/doks/service-release.d.ts +415 -0
- package/dist/infra/doks/service-release.d.ts.map +1 -0
- package/dist/infra/doks/service-release.js +3201 -0
- package/dist/infra/doks/service-release.js.map +1 -0
- package/dist/infra/doks/worker.d.ts +14 -0
- package/dist/infra/doks/worker.d.ts.map +1 -0
- package/dist/infra/doks/worker.js +343 -0
- package/dist/infra/doks/worker.js.map +1 -0
- package/dist/infra/droplet.impl.d.ts +172 -0
- package/dist/infra/droplet.impl.d.ts.map +1 -0
- package/dist/infra/droplet.impl.js +379 -0
- package/dist/infra/droplet.impl.js.map +1 -0
- package/dist/infra/functions.impl.d.ts +123 -0
- package/dist/infra/functions.impl.d.ts.map +1 -0
- package/dist/infra/functions.impl.js +202 -0
- package/dist/infra/functions.impl.js.map +1 -0
- package/dist/infra/index.d.ts +15 -0
- package/dist/infra/index.d.ts.map +1 -0
- package/dist/infra/index.js +12 -0
- package/dist/infra/index.js.map +1 -0
- package/dist/infra/inventory.d.ts +7 -0
- package/dist/infra/inventory.d.ts.map +1 -0
- package/dist/infra/inventory.js +259 -0
- package/dist/infra/inventory.js.map +1 -0
- package/dist/infra/kubernetes-log-stream.d.ts +5 -0
- package/dist/infra/kubernetes-log-stream.d.ts.map +1 -0
- package/dist/infra/kubernetes-log-stream.js +186 -0
- package/dist/infra/kubernetes-log-stream.js.map +1 -0
- package/dist/infra/kubernetes-logs.d.ts +33 -0
- package/dist/infra/kubernetes-logs.d.ts.map +1 -0
- package/dist/infra/kubernetes-logs.descriptor.d.ts +14 -0
- package/dist/infra/kubernetes-logs.descriptor.d.ts.map +1 -0
- package/dist/infra/kubernetes-logs.descriptor.js +28 -0
- package/dist/infra/kubernetes-logs.descriptor.js.map +1 -0
- package/dist/infra/kubernetes-logs.js +196 -0
- package/dist/infra/kubernetes-logs.js.map +1 -0
- package/dist/infra/utilization.d.ts +44 -0
- package/dist/infra/utilization.d.ts.map +1 -0
- package/dist/infra/utilization.js +108 -0
- package/dist/infra/utilization.js.map +1 -0
- package/dist/kubernetes/authority.d.ts +40 -0
- package/dist/kubernetes/authority.d.ts.map +1 -0
- package/dist/kubernetes/authority.js +90 -0
- package/dist/kubernetes/authority.js.map +1 -0
- package/dist/kubernetes/encoding.d.ts +4 -0
- package/dist/kubernetes/encoding.d.ts.map +1 -0
- package/dist/kubernetes/encoding.js +8 -0
- package/dist/kubernetes/encoding.js.map +1 -0
- package/dist/kubernetes/index.d.ts +105 -0
- package/dist/kubernetes/index.d.ts.map +1 -0
- package/dist/kubernetes/index.js +99 -0
- package/dist/kubernetes/index.js.map +1 -0
- package/dist/kubernetes/transport.d.ts +11 -0
- package/dist/kubernetes/transport.d.ts.map +1 -0
- package/dist/kubernetes/transport.js +27 -0
- package/dist/kubernetes/transport.js.map +1 -0
- package/dist/network/index.d.ts +24 -0
- package/dist/network/index.d.ts.map +1 -0
- package/dist/network/index.js +16 -0
- package/dist/network/index.js.map +1 -0
- package/dist/registry/index.d.ts +39 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +20 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/schemas/app-deployment.d.ts +1474 -0
- package/dist/schemas/app-deployment.d.ts.map +1 -0
- package/dist/schemas/app-deployment.js +156 -0
- package/dist/schemas/app-deployment.js.map +1 -0
- package/dist/schemas/app-platform.d.ts +755 -0
- package/dist/schemas/app-platform.d.ts.map +1 -0
- package/dist/schemas/app-platform.js +253 -0
- package/dist/schemas/app-platform.js.map +1 -0
- package/dist/schemas/cache-database.d.ts +210 -0
- package/dist/schemas/cache-database.d.ts.map +1 -0
- package/dist/schemas/cache-database.js +105 -0
- package/dist/schemas/cache-database.js.map +1 -0
- package/dist/schemas/control-plane.d.ts +456 -0
- package/dist/schemas/control-plane.d.ts.map +1 -0
- package/dist/schemas/control-plane.js +123 -0
- package/dist/schemas/control-plane.js.map +1 -0
- package/dist/schemas/credential-use.d.ts +714 -0
- package/dist/schemas/credential-use.d.ts.map +1 -0
- package/dist/schemas/credential-use.js +73 -0
- package/dist/schemas/credential-use.js.map +1 -0
- package/dist/schemas/doks-worker.d.ts +4071 -0
- package/dist/schemas/doks-worker.d.ts.map +1 -0
- package/dist/schemas/doks-worker.js +330 -0
- package/dist/schemas/doks-worker.js.map +1 -0
- package/dist/schemas/droplet.d.ts +110 -0
- package/dist/schemas/droplet.d.ts.map +1 -0
- package/dist/schemas/droplet.js +22 -0
- package/dist/schemas/droplet.js.map +1 -0
- package/dist/schemas/functions.d.ts +22 -0
- package/dist/schemas/functions.d.ts.map +1 -0
- package/dist/schemas/functions.js +25 -0
- package/dist/schemas/functions.js.map +1 -0
- package/dist/schemas/gitea-git-hosting.d.ts +20 -0
- package/dist/schemas/gitea-git-hosting.d.ts.map +1 -0
- package/dist/schemas/gitea-git-hosting.js +26 -0
- package/dist/schemas/gitea-git-hosting.js.map +1 -0
- package/dist/schemas/http.d.ts +2594 -0
- package/dist/schemas/http.d.ts.map +1 -0
- package/dist/schemas/http.js +4548 -0
- package/dist/schemas/http.js.map +1 -0
- package/dist/schemas/infra-kinds.d.ts +113 -0
- package/dist/schemas/infra-kinds.d.ts.map +1 -0
- package/dist/schemas/infra-kinds.js +93 -0
- package/dist/schemas/infra-kinds.js.map +1 -0
- package/dist/schemas/kubernetes-responses.d.ts +457 -0
- package/dist/schemas/kubernetes-responses.d.ts.map +1 -0
- package/dist/schemas/kubernetes-responses.js +681 -0
- package/dist/schemas/kubernetes-responses.js.map +1 -0
- package/dist/schemas/kubernetes.d.ts +143 -0
- package/dist/schemas/kubernetes.d.ts.map +1 -0
- package/dist/schemas/kubernetes.js +68 -0
- package/dist/schemas/kubernetes.js.map +1 -0
- package/dist/schemas/logs.d.ts +15 -0
- package/dist/schemas/logs.d.ts.map +1 -0
- package/dist/schemas/logs.js +11 -0
- package/dist/schemas/logs.js.map +1 -0
- package/dist/schemas/object-storage.d.ts +167 -0
- package/dist/schemas/object-storage.d.ts.map +1 -0
- package/dist/schemas/object-storage.js +124 -0
- package/dist/schemas/object-storage.js.map +1 -0
- package/dist/schemas/service-settings.d.ts +9 -0
- package/dist/schemas/service-settings.d.ts.map +1 -0
- package/dist/schemas/service-settings.js +21 -0
- package/dist/schemas/service-settings.js.map +1 -0
- package/dist/schemas/utilization.d.ts +57 -0
- package/dist/schemas/utilization.d.ts.map +1 -0
- package/dist/schemas/utilization.js +58 -0
- package/dist/schemas/utilization.js.map +1 -0
- package/dist/schemas/worker-status.d.ts +22 -0
- package/dist/schemas/worker-status.d.ts.map +1 -0
- package/dist/schemas/worker-status.js +14 -0
- package/dist/schemas/worker-status.js.map +1 -0
- package/dist/schemas/worker.d.ts +125 -0
- package/dist/schemas/worker.d.ts.map +1 -0
- package/dist/schemas/worker.js +129 -0
- package/dist/schemas/worker.js.map +1 -0
- package/dist/secrets/app-platform/app-credentials.impl.d.ts +14 -0
- package/dist/secrets/app-platform/app-credentials.impl.d.ts.map +1 -0
- package/dist/secrets/app-platform/app-credentials.impl.js +237 -0
- package/dist/secrets/app-platform/app-credentials.impl.js.map +1 -0
- package/dist/secrets/container-registry/image-publish-settings.descriptor.d.ts +11 -0
- package/dist/secrets/container-registry/image-publish-settings.descriptor.d.ts.map +1 -0
- package/dist/secrets/container-registry/image-publish-settings.descriptor.js +26 -0
- package/dist/secrets/container-registry/image-publish-settings.descriptor.js.map +1 -0
- package/dist/secrets/doks-secret.descriptor.d.ts +18 -0
- package/dist/secrets/doks-secret.descriptor.d.ts.map +1 -0
- package/dist/secrets/doks-secret.descriptor.js +35 -0
- package/dist/secrets/doks-secret.descriptor.js.map +1 -0
- package/dist/secrets/doks-secret.impl.d.ts +98 -0
- package/dist/secrets/doks-secret.impl.d.ts.map +1 -0
- package/dist/secrets/doks-secret.impl.js +451 -0
- package/dist/secrets/doks-secret.impl.js.map +1 -0
- package/dist/secrets/index.d.ts +4 -0
- package/dist/secrets/index.d.ts.map +1 -0
- package/dist/secrets/index.js +4 -0
- package/dist/secrets/index.js.map +1 -0
- package/dist/secrets/secrets-backend-doks.plugin.d.ts +3 -0
- package/dist/secrets/secrets-backend-doks.plugin.d.ts.map +1 -0
- package/dist/secrets/secrets-backend-doks.plugin.js +35 -0
- package/dist/secrets/secrets-backend-doks.plugin.js.map +1 -0
- package/dist/storage/index.d.ts +50 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +92 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/spaces-keys.d.ts +25 -0
- package/dist/storage/spaces-keys.d.ts.map +1 -0
- package/dist/storage/spaces-keys.js +32 -0
- package/dist/storage/spaces-keys.js.map +1 -0
- package/package.json +172 -4
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Implementation: infra/worker -> digitalocean-functions
|
|
3
|
+
*
|
|
4
|
+
* Provider that reconciles DigitalOcean Functions for a worker descriptor.
|
|
5
|
+
* Two delivery modes are supported (selected via the descriptor's
|
|
6
|
+
* `config.mode`):
|
|
7
|
+
*
|
|
8
|
+
* - `app-platform`: attach the function as a `functions[]` component on
|
|
9
|
+
* an App Platform App. This is the recommended path because it shares
|
|
10
|
+
* the App's region, env, secrets, alerts, log destinations, and
|
|
11
|
+
* deploy lifecycle with the rest of the application. The reconciler
|
|
12
|
+
* calls into `@vibesdotdev/integrations-digitalocean/apps` to read the
|
|
13
|
+
* existing App spec and produce an updated spec containing the
|
|
14
|
+
* function component. Applying the spec is delegated to the App
|
|
15
|
+
* Platform deploy client (the same one that handles services/workers/
|
|
16
|
+
* jobs), so this impl never mutates the App directly — it returns a
|
|
17
|
+
* plan + an `apply()` that the runtime can drive.
|
|
18
|
+
*
|
|
19
|
+
* - `namespace`: a standalone Functions namespace package. The DO
|
|
20
|
+
* Functions namespace API surface lives outside the App Platform
|
|
21
|
+
* control plane; we model the descriptor here but the reconciler
|
|
22
|
+
* leaves namespace mutation as a TODO (returns `unsupported`) until
|
|
23
|
+
* the connector-side namespace client lands. This keeps the runtime
|
|
24
|
+
* contract stable — descriptors are valid today, with a clear error
|
|
25
|
+
* surface if you try to apply the standalone path.
|
|
26
|
+
*
|
|
27
|
+
* Inventory + status reads use the App Platform read client
|
|
28
|
+
* (`DigitalOceanAppsClient`) and surface the function-component summary
|
|
29
|
+
* via the same `runtime/inventory` path as other DO resources.
|
|
30
|
+
*/
|
|
31
|
+
import * as z from 'zod/v4';
|
|
32
|
+
import { type FunctionComponent } from '../schemas/functions.ts';
|
|
33
|
+
import type { DigitalOceanAppsClient, DoApp, DoAppSpec } from '../apps/index.ts';
|
|
34
|
+
export declare const DigitalOceanFunctionsDescriptorSchema: z.ZodObject<{
|
|
35
|
+
kind: z.ZodLiteral<"infra/worker">;
|
|
36
|
+
id: z.ZodString;
|
|
37
|
+
name: z.ZodOptional<z.ZodString>;
|
|
38
|
+
description: z.ZodOptional<z.ZodString>;
|
|
39
|
+
entrypoint: z.ZodOptional<z.ZodString>;
|
|
40
|
+
queues: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
41
|
+
concurrency: z.ZodOptional<z.ZodNumber>;
|
|
42
|
+
env: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
43
|
+
name: z.ZodString;
|
|
44
|
+
value: z.ZodOptional<z.ZodString>;
|
|
45
|
+
secret: z.ZodOptional<z.ZodBoolean>;
|
|
46
|
+
storeKey: z.ZodOptional<z.ZodString>;
|
|
47
|
+
}, z.core.$strip>>>;
|
|
48
|
+
config: z.ZodObject<{
|
|
49
|
+
namespace: z.ZodOptional<z.ZodString>;
|
|
50
|
+
mode: z.ZodDefault<z.ZodEnum<{
|
|
51
|
+
namespace: "namespace";
|
|
52
|
+
"app-platform": "app-platform";
|
|
53
|
+
}>>;
|
|
54
|
+
region: z.ZodOptional<z.ZodString>;
|
|
55
|
+
appName: z.ZodOptional<z.ZodString>;
|
|
56
|
+
sourceDir: z.ZodOptional<z.ZodString>;
|
|
57
|
+
github: z.ZodOptional<z.ZodObject<{
|
|
58
|
+
repo: z.ZodString;
|
|
59
|
+
branch: z.ZodDefault<z.ZodString>;
|
|
60
|
+
deployOnPush: z.ZodDefault<z.ZodBoolean>;
|
|
61
|
+
}, z.core.$strip>>;
|
|
62
|
+
environmentSlug: z.ZodOptional<z.ZodString>;
|
|
63
|
+
label: z.ZodOptional<z.ZodString>;
|
|
64
|
+
memoryMb: z.ZodOptional<z.ZodNumber>;
|
|
65
|
+
timeoutSeconds: z.ZodOptional<z.ZodNumber>;
|
|
66
|
+
adapter: z.ZodLiteral<"digitalocean-functions">;
|
|
67
|
+
}, z.core.$strip>;
|
|
68
|
+
}, z.core.$strip>;
|
|
69
|
+
export type DigitalOceanFunctionsDescriptorInput = z.input<typeof DigitalOceanFunctionsDescriptorSchema>;
|
|
70
|
+
export type DigitalOceanFunctionsDescriptor = z.infer<typeof DigitalOceanFunctionsDescriptorSchema>;
|
|
71
|
+
export interface DigitalOceanFunctionsPlanAction {
|
|
72
|
+
op: 'create-component' | 'update-component' | 'unchanged' | 'unsupported';
|
|
73
|
+
componentName: string;
|
|
74
|
+
reason?: string;
|
|
75
|
+
diff?: {
|
|
76
|
+
before?: FunctionComponent;
|
|
77
|
+
after?: FunctionComponent;
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export interface DigitalOceanFunctionsPlan {
|
|
81
|
+
mode: 'app-platform' | 'namespace';
|
|
82
|
+
appName?: string;
|
|
83
|
+
componentName: string;
|
|
84
|
+
actions: DigitalOceanFunctionsPlanAction[];
|
|
85
|
+
/**
|
|
86
|
+
* Resulting App spec when applied. Undefined for the `namespace` mode
|
|
87
|
+
* because the namespace path mutates the Functions API, not an App spec.
|
|
88
|
+
*/
|
|
89
|
+
nextAppSpec?: DoAppSpec;
|
|
90
|
+
}
|
|
91
|
+
export interface DigitalOceanFunctionsApplyResult {
|
|
92
|
+
mode: 'app-platform' | 'namespace';
|
|
93
|
+
componentName: string;
|
|
94
|
+
appId?: string;
|
|
95
|
+
updatedSpec?: DoAppSpec;
|
|
96
|
+
skipped?: boolean;
|
|
97
|
+
reason?: string;
|
|
98
|
+
}
|
|
99
|
+
export interface DigitalOceanFunctionsPlanContext {
|
|
100
|
+
apps?: DigitalOceanAppsClient;
|
|
101
|
+
}
|
|
102
|
+
export interface DigitalOceanFunctionsApplyContext {
|
|
103
|
+
apps?: DigitalOceanAppsClient;
|
|
104
|
+
/** Optional callback for status updates while the reconciler runs. */
|
|
105
|
+
onLine?: (stream: 'stdout' | 'stderr', line: string) => void;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Build a plan for a functions descriptor. The plan is pure — it can be
|
|
109
|
+
* computed without making API calls when the caller passes the existing
|
|
110
|
+
* App spec via `existingApp`. When `apps` is provided, the planner reads
|
|
111
|
+
* the App by name to produce a real diff.
|
|
112
|
+
*/
|
|
113
|
+
export declare function planDigitalOceanFunctions(descriptor: DigitalOceanFunctionsDescriptor, ctx?: DigitalOceanFunctionsPlanContext & {
|
|
114
|
+
existingApp?: DoApp;
|
|
115
|
+
}): Promise<DigitalOceanFunctionsPlan>;
|
|
116
|
+
/**
|
|
117
|
+
* Apply a functions plan. For the `app-platform` mode, this updates the
|
|
118
|
+
* App spec via the apps client. For the `namespace` mode, this returns
|
|
119
|
+
* `skipped: true` with a reason — the standalone namespace path is not
|
|
120
|
+
* yet implemented and the caller (CLI/routine) should surface the reason.
|
|
121
|
+
*/
|
|
122
|
+
export declare function reconcileDigitalOceanFunctions(descriptor: DigitalOceanFunctionsDescriptor, ctx?: DigitalOceanFunctionsApplyContext): Promise<DigitalOceanFunctionsApplyResult>;
|
|
123
|
+
//# sourceMappingURL=functions.impl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functions.impl.d.ts","sourceRoot":"","sources":["../../src/infra/functions.impl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAA2B,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG1F,OAAO,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEjF,eAAO,MAAM,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqBhD,CAAC;AACH,MAAM,MAAM,oCAAoC,GAAG,CAAC,CAAC,KAAK,CACzD,OAAO,qCAAqC,CAC5C,CAAC;AACF,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;AAEpG,MAAM,WAAW,+BAA+B;IAC/C,EAAE,EAAE,kBAAkB,GAAG,kBAAkB,GAAG,WAAW,GAAG,aAAa,CAAC;IAC1E,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE;QACN,MAAM,CAAC,EAAE,iBAAiB,CAAC;QAC3B,KAAK,CAAC,EAAE,iBAAiB,CAAC;KAC1B,CAAC;CACF;AAED,MAAM,WAAW,yBAAyB;IACzC,IAAI,EAAE,cAAc,GAAG,WAAW,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,+BAA+B,EAAE,CAAC;IAC3C;;;OAGG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;CACxB;AAED,MAAM,WAAW,gCAAgC;IAChD,IAAI,EAAE,cAAc,GAAG,WAAW,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gCAAgC;IAChD,IAAI,CAAC,EAAE,sBAAsB,CAAC;CAC9B;AAED,MAAM,WAAW,iCAAiC;IACjD,IAAI,CAAC,EAAE,sBAAsB,CAAC;IAC9B,sEAAsE;IACtE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7D;AAiCD;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC9C,UAAU,EAAE,+BAA+B,EAC3C,GAAG,GAAE,gCAAgC,GAAG;IAAE,WAAW,CAAC,EAAE,KAAK,CAAA;CAAO,GAClE,OAAO,CAAC,yBAAyB,CAAC,CAkEpC;AAED;;;;;GAKG;AACH,wBAAsB,8BAA8B,CACnD,UAAU,EAAE,+BAA+B,EAC3C,GAAG,GAAE,iCAAsC,GACzC,OAAO,CAAC,gCAAgC,CAAC,CAmD3C"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Implementation: infra/worker -> digitalocean-functions
|
|
3
|
+
*
|
|
4
|
+
* Provider that reconciles DigitalOcean Functions for a worker descriptor.
|
|
5
|
+
* Two delivery modes are supported (selected via the descriptor's
|
|
6
|
+
* `config.mode`):
|
|
7
|
+
*
|
|
8
|
+
* - `app-platform`: attach the function as a `functions[]` component on
|
|
9
|
+
* an App Platform App. This is the recommended path because it shares
|
|
10
|
+
* the App's region, env, secrets, alerts, log destinations, and
|
|
11
|
+
* deploy lifecycle with the rest of the application. The reconciler
|
|
12
|
+
* calls into `@vibesdotdev/integrations-digitalocean/apps` to read the
|
|
13
|
+
* existing App spec and produce an updated spec containing the
|
|
14
|
+
* function component. Applying the spec is delegated to the App
|
|
15
|
+
* Platform deploy client (the same one that handles services/workers/
|
|
16
|
+
* jobs), so this impl never mutates the App directly — it returns a
|
|
17
|
+
* plan + an `apply()` that the runtime can drive.
|
|
18
|
+
*
|
|
19
|
+
* - `namespace`: a standalone Functions namespace package. The DO
|
|
20
|
+
* Functions namespace API surface lives outside the App Platform
|
|
21
|
+
* control plane; we model the descriptor here but the reconciler
|
|
22
|
+
* leaves namespace mutation as a TODO (returns `unsupported`) until
|
|
23
|
+
* the connector-side namespace client lands. This keeps the runtime
|
|
24
|
+
* contract stable — descriptors are valid today, with a clear error
|
|
25
|
+
* surface if you try to apply the standalone path.
|
|
26
|
+
*
|
|
27
|
+
* Inventory + status reads use the App Platform read client
|
|
28
|
+
* (`DigitalOceanAppsClient`) and surface the function-component summary
|
|
29
|
+
* via the same `runtime/inventory` path as other DO resources.
|
|
30
|
+
*/
|
|
31
|
+
import * as z from 'zod/v4';
|
|
32
|
+
import { FunctionComponentSchema } from "../schemas/functions.js";
|
|
33
|
+
import { DigitalOceanJsonBodySchema } from "../schemas/control-plane.js";
|
|
34
|
+
import { DigitalOceanFunctionsWorkerConfigSchema } from "../schemas/worker.js";
|
|
35
|
+
export const DigitalOceanFunctionsDescriptorSchema = z.object({
|
|
36
|
+
kind: z.literal('infra/worker'),
|
|
37
|
+
id: z.string().min(1),
|
|
38
|
+
name: z.string().optional(),
|
|
39
|
+
description: z.string().optional(),
|
|
40
|
+
entrypoint: z.string().min(1).optional(),
|
|
41
|
+
queues: z.array(z.string().min(1)).optional(),
|
|
42
|
+
concurrency: z.number().int().positive().optional(),
|
|
43
|
+
env: z
|
|
44
|
+
.array(z.object({
|
|
45
|
+
name: z.string().regex(/^[_A-Z0-9]+$/),
|
|
46
|
+
value: z.string().optional(),
|
|
47
|
+
secret: z.boolean().optional(),
|
|
48
|
+
storeKey: z.string().min(1).optional()
|
|
49
|
+
}))
|
|
50
|
+
.optional(),
|
|
51
|
+
config: DigitalOceanFunctionsWorkerConfigSchema.extend({
|
|
52
|
+
adapter: z.literal('digitalocean-functions')
|
|
53
|
+
})
|
|
54
|
+
});
|
|
55
|
+
function componentNameFor(descriptor) {
|
|
56
|
+
return descriptor.name ?? descriptor.id;
|
|
57
|
+
}
|
|
58
|
+
function buildFunctionComponent(descriptor) {
|
|
59
|
+
const c = descriptor.config;
|
|
60
|
+
const component = {
|
|
61
|
+
name: componentNameFor(descriptor),
|
|
62
|
+
source_dir: c.sourceDir,
|
|
63
|
+
environment_slug: c.environmentSlug,
|
|
64
|
+
github: c.github
|
|
65
|
+
? {
|
|
66
|
+
repo: c.github.repo,
|
|
67
|
+
branch: c.github.branch,
|
|
68
|
+
deploy_on_push: c.github.deployOnPush
|
|
69
|
+
}
|
|
70
|
+
: undefined,
|
|
71
|
+
envs: descriptor.env?.map((req) => ({
|
|
72
|
+
key: req.name,
|
|
73
|
+
value: req.value,
|
|
74
|
+
scope: 'RUN_AND_BUILD_TIME',
|
|
75
|
+
type: req.secret ? 'SECRET' : 'GENERAL'
|
|
76
|
+
}))
|
|
77
|
+
};
|
|
78
|
+
return FunctionComponentSchema.parse(DigitalOceanJsonBodySchema.parse(component));
|
|
79
|
+
}
|
|
80
|
+
function specsEqual(a, b) {
|
|
81
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Build a plan for a functions descriptor. The plan is pure — it can be
|
|
85
|
+
* computed without making API calls when the caller passes the existing
|
|
86
|
+
* App spec via `existingApp`. When `apps` is provided, the planner reads
|
|
87
|
+
* the App by name to produce a real diff.
|
|
88
|
+
*/
|
|
89
|
+
export async function planDigitalOceanFunctions(descriptor, ctx = {}) {
|
|
90
|
+
const config = descriptor.config;
|
|
91
|
+
const componentName = componentNameFor(descriptor);
|
|
92
|
+
if (config.mode === 'namespace') {
|
|
93
|
+
return {
|
|
94
|
+
mode: 'namespace',
|
|
95
|
+
componentName,
|
|
96
|
+
actions: [
|
|
97
|
+
{
|
|
98
|
+
op: 'unsupported',
|
|
99
|
+
componentName,
|
|
100
|
+
reason: 'Standalone DigitalOcean Functions namespace deployment is not yet wired. Use mode="app-platform" to attach the function to an App Platform App.'
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
if (!config.appName) {
|
|
106
|
+
return {
|
|
107
|
+
mode: 'app-platform',
|
|
108
|
+
componentName,
|
|
109
|
+
actions: [
|
|
110
|
+
{
|
|
111
|
+
op: 'unsupported',
|
|
112
|
+
componentName,
|
|
113
|
+
reason: 'config.appName is required when mode="app-platform" so the reconciler knows which App to update.'
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const existingApp = ctx.existingApp;
|
|
119
|
+
const desired = buildFunctionComponent(descriptor);
|
|
120
|
+
const nextSpec = existingApp?.spec
|
|
121
|
+
? structuredClone(existingApp.spec)
|
|
122
|
+
: { name: config.appName };
|
|
123
|
+
const functions = (nextSpec.functions ??= []);
|
|
124
|
+
const existingIdx = functions.findIndex((fn) => FunctionComponentSchema.parse(fn).name === componentName);
|
|
125
|
+
const actions = [];
|
|
126
|
+
if (existingIdx < 0) {
|
|
127
|
+
functions.push(desired);
|
|
128
|
+
actions.push({ op: 'create-component', componentName, diff: { after: desired } });
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
const before = FunctionComponentSchema.parse(functions[existingIdx]);
|
|
132
|
+
if (specsEqual(before, desired)) {
|
|
133
|
+
actions.push({ op: 'unchanged', componentName });
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
functions[existingIdx] = desired;
|
|
137
|
+
actions.push({ op: 'update-component', componentName, diff: { before, after: desired } });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
mode: 'app-platform',
|
|
142
|
+
appName: config.appName,
|
|
143
|
+
componentName,
|
|
144
|
+
actions,
|
|
145
|
+
nextAppSpec: nextSpec
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Apply a functions plan. For the `app-platform` mode, this updates the
|
|
150
|
+
* App spec via the apps client. For the `namespace` mode, this returns
|
|
151
|
+
* `skipped: true` with a reason — the standalone namespace path is not
|
|
152
|
+
* yet implemented and the caller (CLI/routine) should surface the reason.
|
|
153
|
+
*/
|
|
154
|
+
export async function reconcileDigitalOceanFunctions(descriptor, ctx = {}) {
|
|
155
|
+
const inventory = ctx.apps ? await ctx.apps.list() : [];
|
|
156
|
+
const current = inventory.find((app) => app.spec?.name === descriptor.config.appName);
|
|
157
|
+
const plan = await planDigitalOceanFunctions(descriptor, { existingApp: current });
|
|
158
|
+
if (plan.mode === 'namespace' || plan.actions[0]?.op === 'unsupported') {
|
|
159
|
+
const reason = plan.actions[0]?.reason ?? 'unsupported';
|
|
160
|
+
ctx.onLine?.('stderr', `[functions ${plan.componentName}] skipped: ${reason}`);
|
|
161
|
+
return { mode: plan.mode, componentName: plan.componentName, skipped: true, reason };
|
|
162
|
+
}
|
|
163
|
+
if (plan.actions.every((a) => a.op === 'unchanged')) {
|
|
164
|
+
ctx.onLine?.('stdout', `[functions ${plan.componentName}] unchanged`);
|
|
165
|
+
return {
|
|
166
|
+
mode: 'app-platform',
|
|
167
|
+
componentName: plan.componentName,
|
|
168
|
+
updatedSpec: plan.nextAppSpec,
|
|
169
|
+
skipped: true,
|
|
170
|
+
reason: 'no diff'
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
if (!ctx.apps || !plan.nextAppSpec) {
|
|
174
|
+
return {
|
|
175
|
+
mode: 'app-platform',
|
|
176
|
+
componentName: plan.componentName,
|
|
177
|
+
updatedSpec: plan.nextAppSpec,
|
|
178
|
+
skipped: true,
|
|
179
|
+
reason: 'no apps client provided'
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
const existing = current;
|
|
183
|
+
if (!existing) {
|
|
184
|
+
const created = await ctx.apps.create(plan.nextAppSpec);
|
|
185
|
+
ctx.onLine?.('stdout', `[functions ${plan.componentName}] created App ${created.id}`);
|
|
186
|
+
return {
|
|
187
|
+
mode: 'app-platform',
|
|
188
|
+
componentName: plan.componentName,
|
|
189
|
+
appId: created.id,
|
|
190
|
+
updatedSpec: created.spec
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
const finalApp = await ctx.apps.update(existing.id, plan.nextAppSpec);
|
|
194
|
+
ctx.onLine?.('stdout', `[functions ${plan.componentName}] updated App ${finalApp.id}`);
|
|
195
|
+
return {
|
|
196
|
+
mode: 'app-platform',
|
|
197
|
+
componentName: plan.componentName,
|
|
198
|
+
appId: finalApp.id,
|
|
199
|
+
updatedSpec: finalApp.spec ?? plan.nextAppSpec
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=functions.impl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functions.impl.js","sourceRoot":"","sources":["../../src/infra/functions.impl.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { default as digitalOceanInfraPlugin } from './digitalocean-infra.plugin.ts';
|
|
2
|
+
export { DigitalOceanImagePublishSettingsSchema, DigitalOceanReleaseOptionsSchema, SanitizedAppSpecEvidenceSchema } from '../schemas/app-deployment.ts';
|
|
3
|
+
export type { DigitalOceanImagePublishSettings, DigitalOceanReleaseOptions, SanitizedAppSpecEvidence } from '../schemas/app-deployment.ts';
|
|
4
|
+
export { DigitalOceanDoksWorkerAdapterSchema, DigitalOceanDoksWorkerCredentialDeliveryOwnerSchema, DigitalOceanDoksWorkerCreateOptionsSchema, DigitalOceanDoksWorkerExecutionInputSchema, DigitalOceanDoksWorkerExecutionOwnerSchema, DigitalOceanDoksWorkerInfraImplementationSchema, DigitalOceanDoksWorkerSourceOperationAnnotationsSchema } from '../schemas/doks-worker.ts';
|
|
5
|
+
export type { DigitalOceanDoksWorkerAdapter, DigitalOceanDoksWorkerCreateOptions, DigitalOceanDoksWorkerExecutionInput, DigitalOceanDoksWorkerExecutionOwner, DigitalOceanDoksWorkerInfraImplementation, DigitalOceanDoksWorkerPlan } from '../schemas/doks-worker.ts';
|
|
6
|
+
export { DigitalOceanDoksWorkerStatusSchema } from '../schemas/worker-status.ts';
|
|
7
|
+
export type { DigitalOceanDoksWorkerStatus } from '../schemas/worker-status.ts';
|
|
8
|
+
export { DigitalOceanBillingClient } from './billing.ts';
|
|
9
|
+
export { DigitalOceanUtilizationClient } from './utilization.ts';
|
|
10
|
+
export { createDigitalOceanProviderControlPlaneClient } from './credentials.ts';
|
|
11
|
+
export * from './droplet.impl.ts';
|
|
12
|
+
export * from './functions.impl.ts';
|
|
13
|
+
export * from './inventory.ts';
|
|
14
|
+
export * from './doks/service-release.ts';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/infra/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACpF,OAAO,EACN,sCAAsC,EACtC,gCAAgC,EAChC,8BAA8B,EAC9B,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACX,gCAAgC,EAChC,0BAA0B,EAC1B,wBAAwB,EACxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACN,mCAAmC,EACnC,mDAAmD,EACnD,yCAAyC,EACzC,0CAA0C,EAC1C,0CAA0C,EAC1C,+CAA+C,EAC/C,sDAAsD,EACtD,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACX,6BAA6B,EAC7B,mCAAmC,EACnC,oCAAoC,EACpC,oCAAoC,EACpC,yCAAyC,EACzC,0BAA0B,EAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,kCAAkC,EAAE,MAAM,6BAA6B,CAAC;AACjF,YAAY,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAChF,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,4CAA4C,EAAE,MAAM,kBAAkB,CAAC;AAChF,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { default as digitalOceanInfraPlugin } from "./digitalocean-infra.plugin.js";
|
|
2
|
+
export { DigitalOceanImagePublishSettingsSchema, DigitalOceanReleaseOptionsSchema, SanitizedAppSpecEvidenceSchema } from "../schemas/app-deployment.js";
|
|
3
|
+
export { DigitalOceanDoksWorkerAdapterSchema, DigitalOceanDoksWorkerCredentialDeliveryOwnerSchema, DigitalOceanDoksWorkerCreateOptionsSchema, DigitalOceanDoksWorkerExecutionInputSchema, DigitalOceanDoksWorkerExecutionOwnerSchema, DigitalOceanDoksWorkerInfraImplementationSchema, DigitalOceanDoksWorkerSourceOperationAnnotationsSchema } from "../schemas/doks-worker.js";
|
|
4
|
+
export { DigitalOceanDoksWorkerStatusSchema } from "../schemas/worker-status.js";
|
|
5
|
+
export { DigitalOceanBillingClient } from "./billing.js";
|
|
6
|
+
export { DigitalOceanUtilizationClient } from "./utilization.js";
|
|
7
|
+
export { createDigitalOceanProviderControlPlaneClient } from "./credentials.js";
|
|
8
|
+
export * from "./droplet.impl.js";
|
|
9
|
+
export * from "./functions.impl.js";
|
|
10
|
+
export * from "./inventory.js";
|
|
11
|
+
export * from "./doks/service-release.js";
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/infra/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACpF,OAAO,EACN,sCAAsC,EACtC,gCAAgC,EAChC,8BAA8B,EAC9B,MAAM,8BAA8B,CAAC;AAMtC,OAAO,EACN,mCAAmC,EACnC,mDAAmD,EACnD,yCAAyC,EACzC,0CAA0C,EAC1C,0CAA0C,EAC1C,+CAA+C,EAC/C,sDAAsD,EACtD,MAAM,2BAA2B,CAAC;AASnC,OAAO,EAAE,kCAAkC,EAAE,MAAM,6BAA6B,CAAC;AAEjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,4CAA4C,EAAE,MAAM,kBAAkB,CAAC;AAChF,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type VibesRuntime } from '@vibesdotdev/kernel';
|
|
2
|
+
import type { InventoryImplementation } from '@vibesdotdev/infra-core/kinds';
|
|
3
|
+
import type { DigitalOceanControlPlaneClient } from '../client/control-plane.ts';
|
|
4
|
+
export declare function createDigitalOceanInventoryImplementation(runtime: VibesRuntime, options?: {
|
|
5
|
+
client?: DigitalOceanControlPlaneClient;
|
|
6
|
+
}): Promise<InventoryImplementation>;
|
|
7
|
+
//# sourceMappingURL=inventory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inventory.d.ts","sourceRoot":"","sources":["../../src/infra/inventory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEhE,OAAO,KAAK,EACX,uBAAuB,EAGvB,MAAM,+BAA+B,CAAC;AAOvC,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,4BAA4B,CAAC;AA2BjF,wBAAsB,yCAAyC,CAC9D,OAAO,EAAE,YAAY,EACrB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,8BAA8B,CAAA;CAAE,GACnD,OAAO,CAAC,uBAAuB,CAAC,CAuPlC"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { settle } from '@vibesdotdev/kernel';
|
|
2
|
+
import { sanitizeInfraProviderFailure } from '@vibesdotdev/infra-core';
|
|
3
|
+
import { DigitalOceanKubernetesClient } from "../kubernetes/index.js";
|
|
4
|
+
import { DigitalOceanDropletsClient } from "../droplets/index.js";
|
|
5
|
+
import { DigitalOceanStorageClient, DigitalOceanSpacesKeysClient } from "../storage/index.js";
|
|
6
|
+
import { DigitalOceanAppsClient } from "../apps/index.js";
|
|
7
|
+
import { DigitalOceanNetworkClient } from "../network/index.js";
|
|
8
|
+
import { DigitalOceanContainerRegistryClient } from "../registry/index.js";
|
|
9
|
+
import { createDigitalOceanProviderControlPlaneClient } from "./credentials.js";
|
|
10
|
+
const SPACES_KEY_KIND = 'infra/object-storage-credential';
|
|
11
|
+
export async function createDigitalOceanInventoryImplementation(runtime, options) {
|
|
12
|
+
// The control-plane client is injectable so this module can be exercised
|
|
13
|
+
// without resolving an operator credential; production callers pass nothing
|
|
14
|
+
// and get the canonical credential path.
|
|
15
|
+
const controlPlane = options?.client ??
|
|
16
|
+
(await createDigitalOceanProviderControlPlaneClient(runtime));
|
|
17
|
+
const kubernetes = new DigitalOceanKubernetesClient(controlPlane);
|
|
18
|
+
const droplets = new DigitalOceanDropletsClient(controlPlane);
|
|
19
|
+
const storage = new DigitalOceanStorageClient(controlPlane);
|
|
20
|
+
const spacesKeys = new DigitalOceanSpacesKeysClient(controlPlane);
|
|
21
|
+
const apps = new DigitalOceanAppsClient(controlPlane);
|
|
22
|
+
const network = new DigitalOceanNetworkClient(controlPlane);
|
|
23
|
+
const registry = new DigitalOceanContainerRegistryClient(controlPlane);
|
|
24
|
+
const collectors = [
|
|
25
|
+
{
|
|
26
|
+
kind: 'infra/kubernetes-cluster',
|
|
27
|
+
collect: async () => (await kubernetes.listClusters()).map((cluster) => ({
|
|
28
|
+
id: cluster.id,
|
|
29
|
+
kind: 'infra/kubernetes-cluster',
|
|
30
|
+
name: cluster.name,
|
|
31
|
+
region: cluster.region,
|
|
32
|
+
status: cluster.status.state,
|
|
33
|
+
tags: cluster.tags,
|
|
34
|
+
createdAt: cluster.created_at,
|
|
35
|
+
raw: {
|
|
36
|
+
version: cluster.version,
|
|
37
|
+
ha: cluster.ha ?? false,
|
|
38
|
+
autoUpgrade: cluster.auto_upgrade ?? false,
|
|
39
|
+
surgeUpgrade: cluster.surge_upgrade ?? false,
|
|
40
|
+
registryEnabled: cluster.registry_enabled ?? false,
|
|
41
|
+
clusterSubnet: cluster.cluster_subnet,
|
|
42
|
+
serviceSubnet: cluster.service_subnet,
|
|
43
|
+
vpcId: cluster.vpc_uuid,
|
|
44
|
+
nodePools: cluster.node_pools.map((pool) => ({
|
|
45
|
+
id: pool.id,
|
|
46
|
+
name: pool.name,
|
|
47
|
+
size: pool.size,
|
|
48
|
+
count: pool.count,
|
|
49
|
+
autoScale: pool.auto_scale ?? false,
|
|
50
|
+
minNodes: pool.min_nodes,
|
|
51
|
+
maxNodes: pool.max_nodes
|
|
52
|
+
}))
|
|
53
|
+
}
|
|
54
|
+
}))
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
kind: 'infra/compute-instance',
|
|
58
|
+
collect: async () => (await droplets.list()).map((droplet) => ({
|
|
59
|
+
id: String(droplet.id),
|
|
60
|
+
kind: 'infra/compute-instance',
|
|
61
|
+
name: droplet.name,
|
|
62
|
+
region: droplet.region.slug,
|
|
63
|
+
status: droplet.status,
|
|
64
|
+
// A DOKS worker carries `k8s:<cluster-id>`; anything else is a
|
|
65
|
+
// standalone droplet somebody has to own by hand.
|
|
66
|
+
managedBy: kubernetesClusterTag(droplet.tags) ?? undefined,
|
|
67
|
+
tags: droplet.tags,
|
|
68
|
+
createdAt: droplet.created_at,
|
|
69
|
+
raw: {
|
|
70
|
+
size: droplet.size_slug,
|
|
71
|
+
vcpus: droplet.vcpus,
|
|
72
|
+
memoryMb: droplet.memory,
|
|
73
|
+
diskGb: droplet.disk,
|
|
74
|
+
image: droplet.image?.slug ?? droplet.image?.distribution,
|
|
75
|
+
publicIps: publicIps(droplet.networks?.v4),
|
|
76
|
+
backupsEnabled: featureEnabled(droplet, 'backups'),
|
|
77
|
+
monitoringEnabled: featureEnabled(droplet, 'monitoring')
|
|
78
|
+
}
|
|
79
|
+
}))
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
kind: 'infra/load-balancer',
|
|
83
|
+
collect: async () => (await network.listLoadBalancers()).map((lb) => ({
|
|
84
|
+
id: lb.id,
|
|
85
|
+
kind: 'infra/load-balancer',
|
|
86
|
+
name: lb.name,
|
|
87
|
+
region: lb.region?.slug,
|
|
88
|
+
status: lb.status,
|
|
89
|
+
createdAt: lb.created_at,
|
|
90
|
+
raw: {
|
|
91
|
+
ip: lb.ip,
|
|
92
|
+
size: lb.size ?? lb.size_unit,
|
|
93
|
+
dropletCount: lb.droplet_ids?.length ?? 0,
|
|
94
|
+
dropletIds: lb.droplet_ids ?? [],
|
|
95
|
+
tag: lb.tag || undefined,
|
|
96
|
+
forwardingRules: (lb.forwarding_rules ?? []).map((rule) => `${rule.entry_protocol}:${rule.entry_port}->${rule.target_protocol}:${rule.target_port}`)
|
|
97
|
+
}
|
|
98
|
+
}))
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
kind: 'infra/volume',
|
|
102
|
+
collect: async () => (await storage.listVolumes()).map((volume) => ({
|
|
103
|
+
id: volume.id,
|
|
104
|
+
kind: 'infra/volume',
|
|
105
|
+
name: volume.name,
|
|
106
|
+
region: volume.region.slug,
|
|
107
|
+
// An unattached volume bills exactly like an attached one.
|
|
108
|
+
status: volume.droplet_ids.length > 0 ? 'attached' : 'detached',
|
|
109
|
+
tags: volume.tags,
|
|
110
|
+
createdAt: volume.created_at,
|
|
111
|
+
raw: {
|
|
112
|
+
sizeGb: volume.size_gigabytes,
|
|
113
|
+
dropletIds: volume.droplet_ids,
|
|
114
|
+
filesystemType: volume.filesystem_type
|
|
115
|
+
}
|
|
116
|
+
}))
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
kind: 'infra/snapshot',
|
|
120
|
+
collect: async () => (await droplets.listSnapshots()).map((snapshot) => ({
|
|
121
|
+
id: snapshot.id,
|
|
122
|
+
kind: 'infra/snapshot',
|
|
123
|
+
name: snapshot.name,
|
|
124
|
+
region: snapshot.regions?.[0],
|
|
125
|
+
createdAt: snapshot.created_at,
|
|
126
|
+
raw: {
|
|
127
|
+
sizeGb: snapshot.size_gigabytes,
|
|
128
|
+
resourceType: snapshot.resource_type,
|
|
129
|
+
resourceId: snapshot.resource_id,
|
|
130
|
+
regions: snapshot.regions ?? []
|
|
131
|
+
}
|
|
132
|
+
}))
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
kind: 'infra/web-app',
|
|
136
|
+
collect: async () => (await apps.list()).map((app) => ({
|
|
137
|
+
id: app.id,
|
|
138
|
+
kind: 'infra/web-app',
|
|
139
|
+
name: app.spec?.name,
|
|
140
|
+
region: app.spec?.region,
|
|
141
|
+
status: app.active_deployment?.phase ?? 'unknown',
|
|
142
|
+
createdAt: app.created_at,
|
|
143
|
+
raw: {
|
|
144
|
+
liveUrl: app.live_url,
|
|
145
|
+
defaultIngress: app.default_ingress,
|
|
146
|
+
activeDeploymentId: app.active_deployment?.id,
|
|
147
|
+
inProgressDeploymentPhase: app.in_progress_deployment?.phase,
|
|
148
|
+
updatedAt: app.updated_at
|
|
149
|
+
}
|
|
150
|
+
}))
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
kind: 'infra/container-registry',
|
|
154
|
+
collect: async () => {
|
|
155
|
+
const found = await registry.get();
|
|
156
|
+
if (!found)
|
|
157
|
+
return [];
|
|
158
|
+
const repositories = await registry.listRepositories(found.registry.name);
|
|
159
|
+
// tag_count and manifest_count diverge as soon as an image is
|
|
160
|
+
// overwritten: the old manifest loses its tag but keeps its blobs.
|
|
161
|
+
// Reporting the difference is the point — it is invisible in the
|
|
162
|
+
// console and bills as storage until a garbage collection runs.
|
|
163
|
+
const untagged = repositories.reduce((total, repo) => total + Math.max((repo.manifest_count ?? 0) - (repo.tag_count ?? 0), 0), 0);
|
|
164
|
+
return [
|
|
165
|
+
{
|
|
166
|
+
id: found.registry.name,
|
|
167
|
+
kind: 'infra/container-registry',
|
|
168
|
+
name: found.registry.name,
|
|
169
|
+
region: found.registry.region,
|
|
170
|
+
status: found.registry.read_only ? 'read-only' : 'active',
|
|
171
|
+
createdAt: found.registry.created_at,
|
|
172
|
+
raw: {
|
|
173
|
+
storageUsageBytes: found.registry.storage_usage_bytes,
|
|
174
|
+
storageUsageUpdatedAt: found.registry.storage_usage_updated_at,
|
|
175
|
+
includedStorageBytes: found.subscription?.tier?.included_storage_bytes,
|
|
176
|
+
tier: found.subscription?.tier?.slug,
|
|
177
|
+
repositoryCount: repositories.length,
|
|
178
|
+
untaggedManifestCount: untagged,
|
|
179
|
+
repositories: repositories.map((repo) => ({
|
|
180
|
+
name: repo.name,
|
|
181
|
+
tagCount: repo.tag_count ?? 0,
|
|
182
|
+
manifestCount: repo.manifest_count ?? 0,
|
|
183
|
+
latestUpdatedAt: repo.latest_manifest?.updated_at
|
|
184
|
+
}))
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
];
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
kind: SPACES_KEY_KIND,
|
|
192
|
+
collect: async () =>
|
|
193
|
+
// Names, grants and creation dates only. The access key id is an
|
|
194
|
+
// identifier, not a credential, and the secret is never returned by
|
|
195
|
+
// this endpoint at all — but a `fullaccess` grant from a retired
|
|
196
|
+
// project is a finding, so the grant has to be reported.
|
|
197
|
+
(await spacesKeys.list()).map((key) => ({
|
|
198
|
+
id: key.access_key,
|
|
199
|
+
kind: SPACES_KEY_KIND,
|
|
200
|
+
name: key.name,
|
|
201
|
+
status: grantSummary(key.grants),
|
|
202
|
+
createdAt: key.created_at,
|
|
203
|
+
raw: {
|
|
204
|
+
grants: (key.grants ?? []).map((grant) => ({
|
|
205
|
+
bucket: grant.bucket || '*',
|
|
206
|
+
permission: grant.permission
|
|
207
|
+
}))
|
|
208
|
+
}
|
|
209
|
+
}))
|
|
210
|
+
}
|
|
211
|
+
];
|
|
212
|
+
return {
|
|
213
|
+
async collect(opts) {
|
|
214
|
+
const requested = new Set(opts?.kinds ?? []);
|
|
215
|
+
const selected = collectors.filter((collector) => requested.size === 0 || requested.has(collector.kind));
|
|
216
|
+
const resources = [];
|
|
217
|
+
// One failing endpoint must not blank the whole inventory: a token
|
|
218
|
+
// scoped without registry read still has to report its droplets, and
|
|
219
|
+
// the gap is reported as a row rather than as silence.
|
|
220
|
+
for (const collector of selected) {
|
|
221
|
+
const result = await settle(() => collector.collect());
|
|
222
|
+
if (result.ok)
|
|
223
|
+
resources.push(...result.value);
|
|
224
|
+
else
|
|
225
|
+
resources.push({
|
|
226
|
+
id: collector.kind,
|
|
227
|
+
kind: 'infra/inventory-error',
|
|
228
|
+
name: collector.kind,
|
|
229
|
+
status: 'error',
|
|
230
|
+
raw: { message: sanitizeInfraProviderFailure(result.cause).message }
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
provider: 'digitalocean',
|
|
235
|
+
collectedAt: new Date().toISOString(),
|
|
236
|
+
resources,
|
|
237
|
+
credentialPath: 'canonical-config'
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
/** The `k8s:<cluster-id>` tag DOKS puts on every worker it owns. */
|
|
243
|
+
function kubernetesClusterTag(tags) {
|
|
244
|
+
const tag = (tags ?? []).find((t) => t.startsWith('k8s:') && t !== 'k8s:worker');
|
|
245
|
+
return tag ? tag.slice('k8s:'.length) : null;
|
|
246
|
+
}
|
|
247
|
+
function publicIps(v4) {
|
|
248
|
+
return (v4 ?? []).filter((n) => n.type === 'public').map((n) => n.ip_address);
|
|
249
|
+
}
|
|
250
|
+
function featureEnabled(droplet, feature) {
|
|
251
|
+
const features = droplet.features;
|
|
252
|
+
return Array.isArray(features) && features.includes(feature);
|
|
253
|
+
}
|
|
254
|
+
function grantSummary(grants) {
|
|
255
|
+
if (!grants || grants.length === 0)
|
|
256
|
+
return 'no-grants';
|
|
257
|
+
return grants.some((grant) => grant.permission === 'fullaccess') ? 'fullaccess' : 'scoped';
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=inventory.js.map
|