@ninedeploy/sdk 0.18.4 → 0.18.10
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/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/resources/auth.d.ts +20 -1
- package/dist/resources/auth.d.ts.map +1 -1
- package/dist/resources/auth.js +9 -0
- package/dist/resources/auth.js.map +1 -1
- package/dist/resources/databases.d.ts +6 -1
- package/dist/resources/databases.d.ts.map +1 -1
- package/dist/resources/databases.js +4 -0
- package/dist/resources/databases.js.map +1 -1
- package/dist/resources/deploys.d.ts +34 -1
- package/dist/resources/deploys.d.ts.map +1 -1
- package/dist/resources/deploys.js +11 -0
- package/dist/resources/deploys.js.map +1 -1
- package/dist/resources/domains.d.ts +16 -1
- package/dist/resources/domains.d.ts.map +1 -1
- package/dist/resources/domains.js +9 -0
- package/dist/resources/domains.js.map +1 -1
- package/dist/resources/servers.d.ts +49 -1
- package/dist/resources/servers.d.ts.map +1 -1
- package/dist/resources/servers.js +26 -0
- package/dist/resources/servers.js.map +1 -1
- package/dist/resources/services.d.ts +78 -1
- package/dist/resources/services.d.ts.map +1 -1
- package/dist/resources/services.js +47 -0
- package/dist/resources/services.js.map +1 -1
- package/dist/resources/settings.d.ts +47 -2
- package/dist/resources/settings.d.ts.map +1 -1
- package/dist/resources/settings.js +6 -0
- package/dist/resources/settings.js.map +1 -1
- package/dist/resources/sources.d.ts +6 -1
- package/dist/resources/sources.d.ts.map +1 -1
- package/dist/resources/sources.js +5 -0
- package/dist/resources/sources.js.map +1 -1
- package/dist/resources/system.d.ts +20 -1
- package/dist/resources/system.d.ts.map +1 -1
- package/dist/resources/system.js +8 -0
- package/dist/resources/system.js.map +1 -1
- package/dist/resources/traefik.d.ts +9 -0
- package/dist/resources/traefik.d.ts.map +1 -1
- package/dist/resources/traefik.js +4 -0
- package/dist/resources/traefik.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +2 -2
- package/src/resources/auth.ts +25 -0
- package/src/resources/databases.ts +11 -0
- package/src/resources/deploys.ts +37 -0
- package/src/resources/domains.ts +30 -0
- package/src/resources/servers.ts +80 -0
- package/src/resources/services.ts +138 -0
- package/src/resources/settings.ts +45 -1
- package/src/resources/sources.ts +12 -0
- package/src/resources/system.ts +24 -0
- package/src/resources/traefik.ts +9 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"traefik.d.ts","sourceRoot":"","sources":["../../src/resources/traefik.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,kBAAkB,EAClB,yBAAyB,EACzB,0BAA0B,EAC1B,WAAW,EACX,aAAa,EACb,mBAAmB,EACnB,0BAA0B,EAC1B,6BAA6B,EAC7B,iBAAiB,EACjB,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;QAChC,MAAM,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;QACrC,YAAY,EAAE,MAAM,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;QAClD;;;;;;;;WAQG;QACH,oBAAoB,EAAE,CAAC,IAAI,CAAC,EAAE;YAAE,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAC;QAC7F;;;;WAIG;QACH,oBAAoB,EAAE,CAAC,IAAI,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO,CAAC;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,YAAY,EAAE,yBAAyB,EAAE,CAAA;SAAE,CAAC,CAAC;QAC7I,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;YAAE,IAAI,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC,CAAC;QACtD,OAAO,EAAE,MAAM,OAAO,CAAC;YAAE,EAAE,EAAE,OAAO,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC1D,sEAAsE;QACtE,WAAW,EAAE,MAAM,OAAO,CAAC;YAAE,EAAE,EAAE,OAAO,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAChE,sFAAsF;QACtF,MAAM,EAAE,MAAM,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC5C,+DAA+D;QAC/D,OAAO,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAC3C;;;;WAIG;QACH,MAAM,EAAE,MAAM,OAAO,CAAC;YAAE,EAAE,EAAE,OAAO,CAAC;YAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;SAAE,CAAC,CAAC;QAClE;;;WAGG;QACH,sGAAsG;QACtG,KAAK,EAAE;YACL,GAAG,EAAE,MAAM,OAAO,CAAC;gBAAE,OAAO,EAAE,OAAO,CAAA;aAAE,CAAC,CAAC;YACzC,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;gBAAE,OAAO,EAAE,OAAO,CAAA;aAAE,CAAC,CAAC;SAC1D,CAAC;QACF,YAAY,EAAE;YACZ,GAAG,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;YACxC,uBAAuB;YACvB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,6BAA6B,CAAC,CAAC;YACtE,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAC;YAC9D,KAAK,EAAE,MAAM,OAAO,CAAC;gBAAE,EAAE,EAAE,OAAO,CAAC;gBAAC,OAAO,EAAE,OAAO,CAAA;aAAE,CAAC,CAAC;SACzD,CAAC;QACF,0FAA0F;QAC1F,kBAAkB,EAAE;YAClB,IAAI,EAAE,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;YACzC,MAAM,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;YAC5E,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,wBAAwB,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;YAC1F,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;gBAAE,EAAE,EAAE,OAAO,CAAA;aAAE,CAAC,CAAC;SAClD,CAAC;KACH,CAAC;CACH;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,SAAS,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"traefik.d.ts","sourceRoot":"","sources":["../../src/resources/traefik.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,6 +33,10 @@ export function traefikApi(t) {
|
|
|
33
33
|
replace: (id, input) => send('PUT', `/v1/traefik/certificates/custom/${id}`, input),
|
|
34
34
|
delete: (id) => send('DELETE', `/v1/traefik/certificates/custom/${id}`),
|
|
35
35
|
},
|
|
36
|
+
sharedCertificates: {
|
|
37
|
+
get: () => get('/v1/traefik/certificates/shared'),
|
|
38
|
+
set: (enabled) => send('PUT', '/v1/traefik/certificates/shared', { enabled }),
|
|
39
|
+
},
|
|
36
40
|
},
|
|
37
41
|
};
|
|
38
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"traefik.js","sourceRoot":"","sources":["../../src/resources/traefik.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"traefik.js","sourceRoot":"","sources":["../../src/resources/traefik.ts"],"names":[],"mappings":"AAsFA,MAAM,UAAU,UAAU,CAAC,CAAY;IACrC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IACjC,OAAO;QACL,OAAO,EAAE;YACP,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAc,aAAa,CAAC;YAC1C,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAgB,oBAAoB,CAAC;YACtD,YAAY,EAAE,GAAG,EAAE,CAAC,GAAG,CAAuB,0BAA0B,CAAC;YACzE,oBAAoB,EAAE,CAAC,IAAI,EAAE,EAAE,CAC7B,GAAG;YACD,mEAAmE;YACnE,+DAA+D;YAC/D,6BAA6B;YAC7B,qCAAqC,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CACrG;YACH,oBAAoB,EAAE,CAAC,IAAI,EAAE,EAAE,CAC7B,GAAG,CACD,oCAAoC,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CACrF;YACH,IAAI,EAAE,CAAC,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,CAAqB,0BAA0B,KAAK,EAAE,CAAC;YAChF,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAmC,MAAM,EAAE,qBAAqB,CAAC;YACpF,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,CAAsC,MAAM,EAAE,0BAA0B,CAAC;YAChG,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAuB,oBAAoB,CAAC;YAC7D,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,CAAqB,qBAAqB,CAAC;YAC7D,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAA6C,oBAAoB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC;YACxH,KAAK,EAAE;gBACL,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAuB,mBAAmB,CAAC;gBACzD,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAuB,KAAK,EAAE,mBAAmB,EAAE,EAAE,OAAO,EAAE,CAAC;aACtF;YACD,YAAY,EAAE;gBACZ,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAsB,2BAA2B,CAAC;gBAChE,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAgC,MAAM,EAAE,oCAAoC,EAAE,EAAE,OAAO,EAAE,CAAC;gBACrH,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,CACf,OAAO,CAA6B,2BAA2B,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;gBACxH,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAoC,QAAQ,EAAE,2BAA2B,CAAC;aAC5F;YACD,kBAAkB,EAAE;gBAClB,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,CAAsB,iCAAiC,CAAC;gBACvE,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAyB,MAAM,EAAE,iCAAiC,EAAE,KAAK,CAAC;gBACjG,OAAO,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAyB,KAAK,EAAE,mCAAmC,EAAE,EAAE,EAAE,KAAK,CAAC;gBAC3G,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAkB,QAAQ,EAAE,mCAAmC,EAAE,EAAE,CAAC;aACzF;YACD,kBAAkB,EAAE;gBAClB,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAuB,iCAAiC,CAAC;gBACvE,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAuB,KAAK,EAAE,iCAAiC,EAAE,EAAE,OAAO,EAAE,CAAC;aACpG;SACF;KACF,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ninedeploy/sdk",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.10",
|
|
4
4
|
"description": "Official TypeScript SDK for NineDeploy PaaS",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@ninedeploy/schemas": "0.18.
|
|
28
|
+
"@ninedeploy/schemas": "0.18.10",
|
|
29
29
|
"js-yaml": "^4.3.1"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
package/src/index.ts
CHANGED
|
@@ -116,7 +116,7 @@ export type {
|
|
|
116
116
|
|
|
117
117
|
export { createClient } from './client.js';
|
|
118
118
|
export type { NineDeployClient } from './client.js';
|
|
119
|
-
export type { AutoUrlMode, AutoUrlEffective, AutoUrlSettings, OnboardingStatus, OnboardingStepId } from './resources/settings.js';
|
|
120
|
-
export type { SourceUpload } from './resources/services.js';
|
|
119
|
+
export type { AutoUrlMode, AutoUrlEffective, AutoUrlSettings, OnboardingStatus, OnboardingStepId, DnsCredentialProviderName, DnsProviderSettings } from './resources/settings.js';
|
|
120
|
+
export type { RegistryHookView, SourceUpload } from './resources/services.js';
|
|
121
121
|
export type { HostIpEntry } from './resources/network.js';
|
|
122
122
|
export type { MonitorCheckNowResult } from './resources/uptime.js';
|
package/src/resources/auth.ts
CHANGED
|
@@ -37,6 +37,9 @@ import type {
|
|
|
37
37
|
AccessGrantUpdate,
|
|
38
38
|
AccessMe,
|
|
39
39
|
ProjectAccessEntry,
|
|
40
|
+
TwoFactorRequirementView,
|
|
41
|
+
WorkspaceTwoFactorInput,
|
|
42
|
+
WorkspaceTwoFactorView,
|
|
40
43
|
} from '@ninedeploy/schemas';
|
|
41
44
|
import { apiGetUrl } from '../apiPath.js';
|
|
42
45
|
import type { TokenIntrospection } from '../types.js';
|
|
@@ -85,6 +88,8 @@ export interface AuthApi {
|
|
|
85
88
|
status: () => Promise<{ totpEnabled: boolean; remaining: number }>;
|
|
86
89
|
regenerate: (input: { code: string; password?: string }) => Promise<{ recoveryCodes: string[] }>;
|
|
87
90
|
};
|
|
91
|
+
/** G1.4: what the workspace 2FA policies ask of this session (403 `two_factor_required` elsewhere until enrolled). */
|
|
92
|
+
requirement: () => Promise<TwoFactorRequirementView>;
|
|
88
93
|
};
|
|
89
94
|
me: () => Promise<PublicUser>;
|
|
90
95
|
tokens: {
|
|
@@ -113,6 +118,12 @@ export interface AuthApi {
|
|
|
113
118
|
list: () => Promise<ActiveSession[]>;
|
|
114
119
|
revoke: (id: number) => Promise<{ ok: boolean }>;
|
|
115
120
|
};
|
|
121
|
+
/** G3.6: SAML providers for the sign-in page; start each `authUrl` like an OIDC one. */
|
|
122
|
+
saml: {
|
|
123
|
+
publicProviders: () => Promise<Array<{ id: number; name: string; authUrl: string }>>;
|
|
124
|
+
/** Link a SAML identity to the signed-in account: open the answer's `authUrl`. */
|
|
125
|
+
link: (id: number) => Promise<{ authUrl: string }>;
|
|
126
|
+
};
|
|
116
127
|
oidc: {
|
|
117
128
|
publicProviders: () => Promise<OidcPublicProvider[]>;
|
|
118
129
|
link: (slug: string) => Promise<{ authUrl: string }>;
|
|
@@ -133,6 +144,11 @@ export interface AuthApi {
|
|
|
133
144
|
create: (input: WorkspaceCreateInput) => Promise<WorkspaceEntry>;
|
|
134
145
|
update: (id: number, input: WorkspaceUpdateInput) => Promise<WorkspaceEntry>;
|
|
135
146
|
delete: (id: number) => Promise<{ ok: boolean }>;
|
|
147
|
+
/** G1.4: require TOTP or a passkey of every member (admins and owners). */
|
|
148
|
+
twoFactor: {
|
|
149
|
+
get: (id: number) => Promise<WorkspaceTwoFactorView>;
|
|
150
|
+
set: (id: number, input: WorkspaceTwoFactorInput) => Promise<WorkspaceTwoFactorView>;
|
|
151
|
+
};
|
|
136
152
|
/**
|
|
137
153
|
* Add a member by email. r604: only an instance operator gets a direct
|
|
138
154
|
* add (a `WorkspaceMemberEntry`) for a registered address; for everyone
|
|
@@ -253,6 +269,7 @@ export function authApi(t: Transport): AuthApi {
|
|
|
253
269
|
status: () => get<{ totpEnabled: boolean; remaining: number }>('/v1/auth/2fa/recovery-codes'),
|
|
254
270
|
regenerate: (input) => send<{ recoveryCodes: string[] }>('POST', '/v1/auth/2fa/recovery-codes', input),
|
|
255
271
|
},
|
|
272
|
+
requirement: () => get<TwoFactorRequirementView>('/v1/auth/2fa/requirement'),
|
|
256
273
|
},
|
|
257
274
|
me: () => get<PublicUser>('/v1/auth/me'),
|
|
258
275
|
tokens: {
|
|
@@ -283,6 +300,10 @@ export function authApi(t: Transport): AuthApi {
|
|
|
283
300
|
list: () => get<ActiveSession[]>('/v1/auth/sessions'),
|
|
284
301
|
revoke: (id) => send<{ ok: boolean }>('DELETE', `/v1/auth/sessions/${id}`),
|
|
285
302
|
},
|
|
303
|
+
saml: {
|
|
304
|
+
publicProviders: () => get<Array<{ id: number; name: string; authUrl: string }>>('/v1/auth/saml/providers/public'),
|
|
305
|
+
link: (id) => send<{ authUrl: string }>('POST', `/v1/auth/saml/${id}/link`, {}),
|
|
306
|
+
},
|
|
286
307
|
oidc: {
|
|
287
308
|
publicProviders: () => get<OidcPublicProvider[]>('/v1/auth/oidc/providers/public'),
|
|
288
309
|
link: (slug) => request<{ authUrl: string }>(`/v1/auth/oidc/${encodeURIComponent(slug)}/link`, { method: 'POST', credentials: 'include' }),
|
|
@@ -302,6 +323,10 @@ export function authApi(t: Transport): AuthApi {
|
|
|
302
323
|
get: (id) => get<WorkspaceDetail>(`/v1/workspaces/${id}`),
|
|
303
324
|
create: (input) => send<WorkspaceEntry>('POST', '/v1/workspaces', input),
|
|
304
325
|
update: (id, input) => send<WorkspaceEntry>('PATCH', `/v1/workspaces/${id}`, input),
|
|
326
|
+
twoFactor: {
|
|
327
|
+
get: (id) => get<WorkspaceTwoFactorView>(`/v1/workspaces/${id}/two-factor`),
|
|
328
|
+
set: (id, input) => send<WorkspaceTwoFactorView>('PUT', `/v1/workspaces/${id}/two-factor`, input),
|
|
329
|
+
},
|
|
305
330
|
delete: (id) => send<{ ok: boolean }>('DELETE', `/v1/workspaces/${id}`),
|
|
306
331
|
addMember: (id, input) =>
|
|
307
332
|
send<WorkspaceMemberEntry | WorkspaceMemberInviteEntry>('POST', `/v1/workspaces/${id}/members`, input),
|
|
@@ -16,6 +16,8 @@ import type {
|
|
|
16
16
|
DatabaseImport,
|
|
17
17
|
DatabaseImportCreate,
|
|
18
18
|
BackupDestinationObject,
|
|
19
|
+
BackupReplica,
|
|
20
|
+
BackupReplicasView,
|
|
19
21
|
} from '@ninedeploy/schemas';
|
|
20
22
|
import type { ImportWaitOptions, ImportFileData, ImportFileOptions } from '../databaseImport.js';
|
|
21
23
|
import type { BackupDrillResult, BackupDrillEntry, PgbouncerStatus, DatabaseCredentialsWithPublic } from '../types.js';
|
|
@@ -115,6 +117,11 @@ export interface DatabasesApi {
|
|
|
115
117
|
getPolicy: (databaseId: number) => Promise<BackupPolicy>;
|
|
116
118
|
/** 0.12: save (replace) the database's backup schedule, retention and destination. */
|
|
117
119
|
setPolicy: (databaseId: number, input: BackupPolicyInput) => Promise<BackupPolicy>;
|
|
120
|
+
/** G3.3: more destinations for the scheduled dumps, each with its own retention (operators set them). */
|
|
121
|
+
replicas: {
|
|
122
|
+
get: (databaseId: number) => Promise<BackupReplicasView>;
|
|
123
|
+
set: (databaseId: number, replicas: BackupReplica[]) => Promise<BackupReplicasView>;
|
|
124
|
+
};
|
|
118
125
|
};
|
|
119
126
|
backupDestinations: {
|
|
120
127
|
list: () => Promise<Array<{ id: number; name: string; endpoint: string; region: string; bucket: string; prefix: string; active: boolean; createdAt: string }>>;
|
|
@@ -201,6 +208,10 @@ export function databasesApi(t: Transport): DatabasesApi {
|
|
|
201
208
|
downloadUrl: (backupId) => `/v1/backups/${backupId}/download`,
|
|
202
209
|
getPolicy: (databaseId) => get<BackupPolicy>(`/v1/databases/${databaseId}/backup-policy`),
|
|
203
210
|
setPolicy: (databaseId, input) => send<BackupPolicy>('PUT', `/v1/databases/${databaseId}/backup-policy`, input),
|
|
211
|
+
replicas: {
|
|
212
|
+
get: (databaseId) => get<BackupReplicasView>(`/v1/databases/${databaseId}/backup-replicas`),
|
|
213
|
+
set: (databaseId, replicas) => send<BackupReplicasView>('PUT', `/v1/databases/${databaseId}/backup-replicas`, { replicas }),
|
|
214
|
+
},
|
|
204
215
|
},
|
|
205
216
|
backupDestinations: {
|
|
206
217
|
list: () => get('/v1/backup-destinations'),
|
package/src/resources/deploys.ts
CHANGED
|
@@ -17,6 +17,11 @@ import type {
|
|
|
17
17
|
TriggerDeploy,
|
|
18
18
|
Webhook,
|
|
19
19
|
ImageTransfer,
|
|
20
|
+
DeployFreeze,
|
|
21
|
+
DeployFreezeCreate,
|
|
22
|
+
ImageScanPolicy,
|
|
23
|
+
ImageScanPolicyPatch,
|
|
24
|
+
ImageScanResult,
|
|
20
25
|
} from '@ninedeploy/schemas';
|
|
21
26
|
import type { JobKind, ScheduledJob, JobRun } from '../types.js';
|
|
22
27
|
import type { Transport } from '../transport.js';
|
|
@@ -144,11 +149,43 @@ export interface DeploysApi {
|
|
|
144
149
|
*/
|
|
145
150
|
analyzeLogs: (serviceId: number, input?: { tail?: number }) => Promise<RuntimeLogAnalysis>;
|
|
146
151
|
};
|
|
152
|
+
/**
|
|
153
|
+
* G5.5 deploy freezes (operator only). A freeze holds every deploy of the
|
|
154
|
+
* instance, a workspace, a project or an environment in the queue until it
|
|
155
|
+
* ends (`until`) or is lifted; held deploys then start.
|
|
156
|
+
*/
|
|
157
|
+
deployFreezes: {
|
|
158
|
+
list: () => Promise<DeployFreeze[]>;
|
|
159
|
+
create: (input: DeployFreezeCreate) => Promise<DeployFreeze>;
|
|
160
|
+
lift: (id: string) => Promise<DeployFreeze>;
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* G5.1 image vulnerability scanning (Trivy on the panel host). The policy is
|
|
164
|
+
* operator only; a service's latest scan is readable by its viewers, and
|
|
165
|
+
* `scan` (service admin) starts a scan of what runs now in the background.
|
|
166
|
+
*/
|
|
167
|
+
imageScans: {
|
|
168
|
+
policy: () => Promise<{ policy: ImageScanPolicy; trivyImage: string }>;
|
|
169
|
+
setPolicy: (patch: ImageScanPolicyPatch) => Promise<{ policy: ImageScanPolicy; trivyImage: string }>;
|
|
170
|
+
get: (serviceId: number) => Promise<{ result: ImageScanResult | null; scanning: boolean }>;
|
|
171
|
+
scan: (serviceId: number) => Promise<{ started: true; imageId: string | null }>;
|
|
172
|
+
};
|
|
147
173
|
}
|
|
148
174
|
|
|
149
175
|
export function deploysApi(t: Transport): DeploysApi {
|
|
150
176
|
const { get, send, request } = t;
|
|
151
177
|
return {
|
|
178
|
+
imageScans: {
|
|
179
|
+
policy: () => get<{ policy: ImageScanPolicy; trivyImage: string }>('/v1/image-scanning'),
|
|
180
|
+
setPolicy: (patch) => send<{ policy: ImageScanPolicy; trivyImage: string }>('PUT', '/v1/image-scanning', patch),
|
|
181
|
+
get: (serviceId) => get<{ result: ImageScanResult | null; scanning: boolean }>(`/v1/services/${serviceId}/image-scan`),
|
|
182
|
+
scan: (serviceId) => send<{ started: true; imageId: string | null }>('POST', `/v1/services/${serviceId}/image-scan`),
|
|
183
|
+
},
|
|
184
|
+
deployFreezes: {
|
|
185
|
+
list: () => get<DeployFreeze[]>('/v1/deploy-freezes'),
|
|
186
|
+
create: (input) => send<DeployFreeze>('POST', '/v1/deploy-freezes', input),
|
|
187
|
+
lift: (id) => send<DeployFreeze>('DELETE', `/v1/deploy-freezes/${encodeURIComponent(id)}`),
|
|
188
|
+
},
|
|
152
189
|
deploys: {
|
|
153
190
|
trigger: (serviceId, input) =>
|
|
154
191
|
send<{ deploymentId: number; alreadyInProgress?: boolean }>('POST', `/v1/services/${serviceId}/deploys`, input ?? {}),
|
package/src/resources/domains.ts
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
// Split out of the former single-file SDK entry (src/index.ts); the public
|
|
3
3
|
// surface is re-exported unchanged from there.
|
|
4
4
|
import type {
|
|
5
|
+
ComposeRoute,
|
|
6
|
+
ComposeRouteView,
|
|
7
|
+
ForwardAuthConfig,
|
|
8
|
+
ForwardAuthGrant,
|
|
9
|
+
ForwardAuthGrantInput,
|
|
10
|
+
ForwardAuthView,
|
|
5
11
|
CreateDomainInput,
|
|
6
12
|
Domain,
|
|
7
13
|
DomainPatch,
|
|
@@ -12,6 +18,21 @@ import type { Transport } from '../transport.js';
|
|
|
12
18
|
|
|
13
19
|
export interface DomainsApi {
|
|
14
20
|
domains: {
|
|
21
|
+
/**
|
|
22
|
+
* G2.3: panel sign-in in front of a domain. `set(id, null)` takes it off;
|
|
23
|
+
* `grant` is what the panel's /forward-auth page calls to send a signed-in
|
|
24
|
+
* user back to the protected domain.
|
|
25
|
+
*/
|
|
26
|
+
forwardAuth: {
|
|
27
|
+
get: (domainId: number) => Promise<ForwardAuthView>;
|
|
28
|
+
set: (domainId: number, forwardAuth: Partial<ForwardAuthConfig> | null) => Promise<ForwardAuthView>;
|
|
29
|
+
grant: (input: ForwardAuthGrantInput) => Promise<ForwardAuthGrant>;
|
|
30
|
+
};
|
|
31
|
+
/** G2.1: route a compose stack's domain to another service of the stack (null for the main service). */
|
|
32
|
+
composeRoute: {
|
|
33
|
+
get: (domainId: number) => Promise<ComposeRouteView>;
|
|
34
|
+
set: (domainId: number, route: ComposeRoute | null) => Promise<ComposeRouteView>;
|
|
35
|
+
};
|
|
15
36
|
list: (serviceId: number) => Promise<Domain[]>;
|
|
16
37
|
/** Add a domain. A non-operator's hostname outside the instance zone comes back `pending` with a TXT `verification` challenge. */
|
|
17
38
|
create: (serviceId: number, input: CreateDomainInput) => Promise<CreatedDomain>;
|
|
@@ -100,6 +121,15 @@ export function domainsApi(t: Transport): DomainsApi {
|
|
|
100
121
|
const { get, send, request } = t;
|
|
101
122
|
return {
|
|
102
123
|
domains: {
|
|
124
|
+
forwardAuth: {
|
|
125
|
+
get: (domainId) => get<ForwardAuthView>(`/v1/domains/${domainId}/forward-auth`),
|
|
126
|
+
set: (domainId, forwardAuth) => send<ForwardAuthView>('PUT', `/v1/domains/${domainId}/forward-auth`, { forwardAuth }),
|
|
127
|
+
grant: (input) => send<ForwardAuthGrant>('POST', '/v1/forward-auth/grant', input),
|
|
128
|
+
},
|
|
129
|
+
composeRoute: {
|
|
130
|
+
get: (domainId) => get<ComposeRouteView>(`/v1/domains/${domainId}/compose-route`),
|
|
131
|
+
set: (domainId, route) => send<ComposeRouteView>('PUT', `/v1/domains/${domainId}/compose-route`, { route }),
|
|
132
|
+
},
|
|
103
133
|
list: (serviceId) => get<Domain[]>(`/v1/services/${serviceId}/domains`),
|
|
104
134
|
create: (serviceId, input) => send<CreatedDomain>('POST', `/v1/services/${serviceId}/domains`, input),
|
|
105
135
|
verify: (serviceId, domainId) =>
|
package/src/resources/servers.ts
CHANGED
|
@@ -10,12 +10,22 @@ import type {
|
|
|
10
10
|
SwarmInitInput,
|
|
11
11
|
SwarmSettingsInput,
|
|
12
12
|
SwarmStatus,
|
|
13
|
+
OsUpdateStatus,
|
|
14
|
+
CloudServer,
|
|
15
|
+
DigitalOceanOptions,
|
|
16
|
+
DigitalOceanServerCreate,
|
|
17
|
+
DigitalOceanStatus,
|
|
18
|
+
HetznerOptions,
|
|
19
|
+
HetznerServerCreate,
|
|
20
|
+
HetznerStatus,
|
|
13
21
|
} from '@ninedeploy/schemas';
|
|
14
22
|
import type { ServerListEntry, ServerRolesResult, SwarmJoinResult, SwarmLeaveResult } from '../types.js';
|
|
15
23
|
import type { Transport } from '../transport.js';
|
|
16
24
|
|
|
17
25
|
/** Long Swarm calls: a leave drains for up to 5 minutes; init and join run Docker on two hosts. */
|
|
18
26
|
const SWARM_CALL_TIMEOUT_MS = 10 * 60_000;
|
|
27
|
+
/** G4.2: a refresh or an install of unattended-upgrades / dnf-automatic can take minutes. */
|
|
28
|
+
const OS_UPDATE_CALL_TIMEOUT_MS = 18 * 60_000;
|
|
19
29
|
|
|
20
30
|
export interface ServersApi {
|
|
21
31
|
servers: {
|
|
@@ -69,6 +79,40 @@ export interface ServersApi {
|
|
|
69
79
|
/** Enable (step-up; 409 `swarm_not_manager`) or disable Swarm deploys. */
|
|
70
80
|
settings: (input: SwarmSettingsInput) => Promise<SwarmStatus>;
|
|
71
81
|
};
|
|
82
|
+
/**
|
|
83
|
+
* G4.2 OS security updates (operator only). `serverId` null is the panel
|
|
84
|
+
* host. `refresh` refreshes the package lists first. Nothing here reboots.
|
|
85
|
+
*/
|
|
86
|
+
osUpdates: {
|
|
87
|
+
get: (serverId: number | null, options?: { refresh?: boolean }) => Promise<OsUpdateStatus>;
|
|
88
|
+
/** Turn automatic security updates on or off; answers the status read afterwards. */
|
|
89
|
+
setAuto: (serverId: number | null, enabled: boolean) => Promise<OsUpdateStatus>;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* G4.3 cloud servers (operator only). The Hetzner Cloud token is write-only;
|
|
93
|
+
* a created server bootstraps the agent itself and turns online when it answers.
|
|
94
|
+
*/
|
|
95
|
+
cloud: {
|
|
96
|
+
digitalocean: {
|
|
97
|
+
status: () => Promise<DigitalOceanStatus>;
|
|
98
|
+
setToken: (token: string) => Promise<DigitalOceanStatus>;
|
|
99
|
+
deleteToken: () => Promise<DigitalOceanStatus>;
|
|
100
|
+
options: () => Promise<DigitalOceanOptions>;
|
|
101
|
+
servers: () => Promise<CloudServer[]>;
|
|
102
|
+
createServer: (input: DigitalOceanServerCreate) => Promise<{ serverId: number; providerServerId: number; ipv4: string }>;
|
|
103
|
+
deleteServer: (serverId: number) => Promise<{ ok: boolean }>;
|
|
104
|
+
};
|
|
105
|
+
hetzner: {
|
|
106
|
+
status: () => Promise<HetznerStatus>;
|
|
107
|
+
setToken: (token: string) => Promise<HetznerStatus>;
|
|
108
|
+
deleteToken: () => Promise<HetznerStatus>;
|
|
109
|
+
options: () => Promise<HetznerOptions>;
|
|
110
|
+
servers: () => Promise<CloudServer[]>;
|
|
111
|
+
createServer: (input: HetznerServerCreate) => Promise<{ serverId: number; providerServerId: number; ipv4: string }>;
|
|
112
|
+
/** Delete the VM and its node (409 while the node hosts anything). */
|
|
113
|
+
deleteServer: (serverId: number) => Promise<{ ok: boolean }>;
|
|
114
|
+
};
|
|
115
|
+
};
|
|
72
116
|
orchestrators: {
|
|
73
117
|
/** Every `IOrchestrator` the running kernel has registered. G-10 PR-A. */
|
|
74
118
|
list: () => Promise<{
|
|
@@ -122,6 +166,42 @@ export function serversApi(t: Transport): ServersApi {
|
|
|
122
166
|
init: (input) => request<SwarmStatus>('/v1/swarm/init', { method: 'POST', body: input }, SWARM_CALL_TIMEOUT_MS),
|
|
123
167
|
settings: (input) => send<SwarmStatus>('PUT', '/v1/swarm/settings', input),
|
|
124
168
|
},
|
|
169
|
+
osUpdates: {
|
|
170
|
+
get: (serverId, options) =>
|
|
171
|
+
request<OsUpdateStatus>(
|
|
172
|
+
`${serverId == null ? '/v1/os-updates' : `/v1/servers/${serverId}/os-updates`}${options?.refresh ? '?refresh=1' : ''}`,
|
|
173
|
+
{ method: 'GET' },
|
|
174
|
+
OS_UPDATE_CALL_TIMEOUT_MS,
|
|
175
|
+
),
|
|
176
|
+
setAuto: (serverId, enabled) =>
|
|
177
|
+
request<OsUpdateStatus>(
|
|
178
|
+
serverId == null ? '/v1/os-updates/auto' : `/v1/servers/${serverId}/os-updates/auto`,
|
|
179
|
+
{ method: 'POST', body: { enabled } },
|
|
180
|
+
OS_UPDATE_CALL_TIMEOUT_MS,
|
|
181
|
+
),
|
|
182
|
+
},
|
|
183
|
+
cloud: {
|
|
184
|
+
digitalocean: {
|
|
185
|
+
status: () => get<DigitalOceanStatus>('/v1/cloud/digitalocean'),
|
|
186
|
+
setToken: (token) => send<DigitalOceanStatus>('PUT', '/v1/cloud/digitalocean/token', { token }),
|
|
187
|
+
deleteToken: () => send<DigitalOceanStatus>('DELETE', '/v1/cloud/digitalocean/token'),
|
|
188
|
+
options: () => get<DigitalOceanOptions>('/v1/cloud/digitalocean/options'),
|
|
189
|
+
servers: () => get<CloudServer[]>('/v1/cloud/digitalocean/servers'),
|
|
190
|
+
createServer: (input) =>
|
|
191
|
+
send<{ serverId: number; providerServerId: number; ipv4: string }>('POST', '/v1/cloud/digitalocean/servers', input),
|
|
192
|
+
deleteServer: (serverId) => send<{ ok: boolean }>('DELETE', `/v1/cloud/digitalocean/servers/${serverId}`),
|
|
193
|
+
},
|
|
194
|
+
hetzner: {
|
|
195
|
+
status: () => get<HetznerStatus>('/v1/cloud/hetzner'),
|
|
196
|
+
setToken: (token) => send<HetznerStatus>('PUT', '/v1/cloud/hetzner/token', { token }),
|
|
197
|
+
deleteToken: () => send<HetznerStatus>('DELETE', '/v1/cloud/hetzner/token'),
|
|
198
|
+
options: () => get<HetznerOptions>('/v1/cloud/hetzner/options'),
|
|
199
|
+
servers: () => get<CloudServer[]>('/v1/cloud/hetzner/servers'),
|
|
200
|
+
createServer: (input) =>
|
|
201
|
+
send<{ serverId: number; providerServerId: number; ipv4: string }>('POST', '/v1/cloud/hetzner/servers', input),
|
|
202
|
+
deleteServer: (serverId) => send<{ ok: boolean }>('DELETE', `/v1/cloud/hetzner/servers/${serverId}`),
|
|
203
|
+
},
|
|
204
|
+
},
|
|
125
205
|
orchestrators: {
|
|
126
206
|
list: () => get<{
|
|
127
207
|
orchestrators: Array<{ name: string; stacks: Array<{ name: string; serviceCount: number }> }>;
|
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
import type {
|
|
5
5
|
Attachment,
|
|
6
6
|
AutoscaleStatusView,
|
|
7
|
+
SizingReport,
|
|
8
|
+
RestartLimitConfig,
|
|
9
|
+
RestartLimitView,
|
|
10
|
+
PendingChangesView,
|
|
11
|
+
PendingApplyInput,
|
|
12
|
+
PendingApplyResult,
|
|
7
13
|
ComposePreviewRequestInput,
|
|
8
14
|
ComposePreviewResponse,
|
|
9
15
|
CreateProjectInput,
|
|
@@ -42,12 +48,31 @@ import type {
|
|
|
42
48
|
ServiceLifecycleResult,
|
|
43
49
|
ServiceLifecycleView,
|
|
44
50
|
ServiceLifecycleRetry,
|
|
51
|
+
ErrorPagesInput,
|
|
52
|
+
InlineDockerfileView,
|
|
53
|
+
ServiceMoveView,
|
|
54
|
+
ServiceCommitStatusView,
|
|
55
|
+
ErrorEventView,
|
|
56
|
+
ErrorIngestView,
|
|
57
|
+
ErrorIssueView,
|
|
58
|
+
ErrorPagesView,
|
|
59
|
+
MaintenanceInput,
|
|
60
|
+
MaintenanceView,
|
|
45
61
|
} from '@ninedeploy/schemas';
|
|
46
62
|
import { apiGetUrl } from '../apiPath.js';
|
|
47
63
|
import type { ApplyManifestResult, ApplyManifestInput, ServiceDetail } from '../types.js';
|
|
48
64
|
import type { Transport } from '../transport.js';
|
|
49
65
|
|
|
50
66
|
/** 0.16.1: one kept upload of a service's source archive. */
|
|
67
|
+
/** G1.7: the registry push webhook of one service. `url` is set only in the answer that made it. */
|
|
68
|
+
export interface RegistryHookView {
|
|
69
|
+
enabled: boolean;
|
|
70
|
+
mine: boolean;
|
|
71
|
+
url: string | null;
|
|
72
|
+
createdAt: string | null;
|
|
73
|
+
lastPushAt: string | null;
|
|
74
|
+
}
|
|
75
|
+
|
|
51
76
|
export interface SourceUpload {
|
|
52
77
|
/** First 40 hex chars of the archive's SHA-256 (the deployment's `commitSha`). */
|
|
53
78
|
sha: string;
|
|
@@ -194,6 +219,72 @@ export interface ServicesApi {
|
|
|
194
219
|
swarmRecovery: (id: number) => Promise<SwarmRecoveryEntry | null>;
|
|
195
220
|
retrySwarmRecovery: (id: number) => Promise<SwarmRecoveryResult>;
|
|
196
221
|
autoscale: (id: number) => Promise<AutoscaleStatusView>;
|
|
222
|
+
/** G5.6: memory and CPU limit suggestions from the metric history (viewer; advisory). */
|
|
223
|
+
sizing: (id: number) => Promise<SizingReport>;
|
|
224
|
+
/** G2.2: maintenance mode (a config turns it on, null off) and custom 502/503/504 pages. */
|
|
225
|
+
maintenance: {
|
|
226
|
+
get: (id: number) => Promise<MaintenanceView>;
|
|
227
|
+
set: (id: number, maintenance: MaintenanceInput['maintenance']) => Promise<MaintenanceView>;
|
|
228
|
+
};
|
|
229
|
+
errorPages: {
|
|
230
|
+
get: (id: number) => Promise<ErrorPagesView>;
|
|
231
|
+
set: (id: number, pages: ErrorPagesInput['pages']) => Promise<ErrorPagesView>;
|
|
232
|
+
};
|
|
233
|
+
/** G1.1: a Dockerfile pasted in the panel (null builds from the repository again). */
|
|
234
|
+
/** G5.4: errors reported by Sentry SDKs, grouped into issues. */
|
|
235
|
+
errors: {
|
|
236
|
+
list: (id: number, status?: 'unresolved' | 'resolved' | 'ignored') => Promise<ErrorIssueView[]>;
|
|
237
|
+
get: (id: number, issueId: number) => Promise<{ issue: ErrorIssueView; events: ErrorEventView[] }>;
|
|
238
|
+
setStatus: (id: number, issueId: number, status: 'unresolved' | 'resolved' | 'ignored') => Promise<ErrorIssueView>;
|
|
239
|
+
/** The DSN: `create` answers it once and replaces any earlier one. */
|
|
240
|
+
ingest: {
|
|
241
|
+
get: (id: number) => Promise<ErrorIngestView>;
|
|
242
|
+
create: (id: number) => Promise<ErrorIngestView>;
|
|
243
|
+
remove: (id: number) => Promise<ErrorIngestView>;
|
|
244
|
+
};
|
|
245
|
+
};
|
|
246
|
+
/** G3.1: move a stopped docker service to another host with its data volume (operators). */
|
|
247
|
+
move: {
|
|
248
|
+
get: (id: number) => Promise<ServiceMoveView>;
|
|
249
|
+
/** `serverId` null = the panel host. Answers at once; follow it with `get`. */
|
|
250
|
+
start: (id: number, serverId: number | null) => Promise<ServiceMoveView>;
|
|
251
|
+
};
|
|
252
|
+
inlineDockerfile: {
|
|
253
|
+
get: (id: number) => Promise<InlineDockerfileView>;
|
|
254
|
+
set: (id: number, content: string | null) => Promise<InlineDockerfileView>;
|
|
255
|
+
};
|
|
256
|
+
/**
|
|
257
|
+
* G1.7 registry push webhook: a secret URL a registry (Docker Hub, GHCR,
|
|
258
|
+
* Harbor, registry:2) calls after a push; the service redeploys when the
|
|
259
|
+
* pushed tag is its image. The URL is returned once, by `enable`.
|
|
260
|
+
*/
|
|
261
|
+
/** GitLab, Gitea and Bitbucket commit statuses (ROADMAP 0.16.8 item 8). */
|
|
262
|
+
commitStatus: {
|
|
263
|
+
get: (id: number) => Promise<ServiceCommitStatusView>;
|
|
264
|
+
set: (id: number, enabled: boolean) => Promise<ServiceCommitStatusView>;
|
|
265
|
+
};
|
|
266
|
+
registryHook: {
|
|
267
|
+
get: (id: number) => Promise<RegistryHookView>;
|
|
268
|
+
enable: (id: number) => Promise<RegistryHookView>;
|
|
269
|
+
disable: (id: number) => Promise<RegistryHookView>;
|
|
270
|
+
};
|
|
271
|
+
/** G1.3: stop the service when its containers keep restarting (opt-in; member to set). */
|
|
272
|
+
restartLimit: {
|
|
273
|
+
get: (id: number) => Promise<RestartLimitView>;
|
|
274
|
+
set: (id: number, limit: RestartLimitConfig | null) => Promise<RestartLimitView>;
|
|
275
|
+
};
|
|
276
|
+
/**
|
|
277
|
+
* G5.2 pending changes tray. With staging on, edits collect (`stage`, a
|
|
278
|
+
* PATCH body) instead of applying; `apply` sends them through
|
|
279
|
+
* `update` together, optionally with a deploy.
|
|
280
|
+
*/
|
|
281
|
+
pending: {
|
|
282
|
+
get: (id: number) => Promise<PendingChangesView>;
|
|
283
|
+
stage: (id: number, patch: UpdateServiceInput) => Promise<PendingChangesView>;
|
|
284
|
+
setStaging: (id: number, staging: boolean) => Promise<PendingChangesView>;
|
|
285
|
+
discard: (id: number) => Promise<PendingChangesView>;
|
|
286
|
+
apply: (id: number, input?: PendingApplyInput) => Promise<PendingApplyResult>;
|
|
287
|
+
};
|
|
197
288
|
// ── 0.16.11 scale to zero ──
|
|
198
289
|
/**
|
|
199
290
|
* Put a docker service to sleep now (`POST /v1/services/:id/sleep`,
|
|
@@ -337,6 +428,53 @@ export function servicesApi(t: Transport): ServicesApi {
|
|
|
337
428
|
swarmRecovery: async id => (await get<{ entry: SwarmRecoveryEntry | null }>(`/v1/services/${id}/swarm/recovery`)).entry,
|
|
338
429
|
retrySwarmRecovery: id => request<SwarmRecoveryResult>(`/v1/services/${id}/swarm/recovery`, { method: 'POST' }, 600_000),
|
|
339
430
|
autoscale: (id) => get<AutoscaleStatusView>(`/v1/services/${id}/autoscale`),
|
|
431
|
+
sizing: (id) => get<SizingReport>(`/v1/services/${id}/sizing`),
|
|
432
|
+
maintenance: {
|
|
433
|
+
get: (id) => get<MaintenanceView>(`/v1/services/${id}/maintenance`),
|
|
434
|
+
set: (id, maintenance) => send<MaintenanceView>('PUT', `/v1/services/${id}/maintenance`, { maintenance }),
|
|
435
|
+
},
|
|
436
|
+
errorPages: {
|
|
437
|
+
get: (id) => get<ErrorPagesView>(`/v1/services/${id}/error-pages`),
|
|
438
|
+
set: (id, pages) => send<ErrorPagesView>('PUT', `/v1/services/${id}/error-pages`, { pages }),
|
|
439
|
+
},
|
|
440
|
+
errors: {
|
|
441
|
+
list: (id, status) => get<ErrorIssueView[]>(`/v1/services/${id}/errors${status ? `?status=${status}` : ''}`),
|
|
442
|
+
get: (id, issueId) => get<{ issue: ErrorIssueView; events: ErrorEventView[] }>(`/v1/services/${id}/errors/${issueId}`),
|
|
443
|
+
setStatus: (id, issueId, status) => send<ErrorIssueView>('PATCH', `/v1/services/${id}/errors/${issueId}`, { status }),
|
|
444
|
+
ingest: {
|
|
445
|
+
get: (id) => get<ErrorIngestView>(`/v1/services/${id}/error-ingest`),
|
|
446
|
+
create: (id) => send<ErrorIngestView>('POST', `/v1/services/${id}/error-ingest`),
|
|
447
|
+
remove: (id) => send<ErrorIngestView>('DELETE', `/v1/services/${id}/error-ingest`),
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
move: {
|
|
451
|
+
get: (id) => get<ServiceMoveView>(`/v1/services/${id}/move`),
|
|
452
|
+
start: (id, serverId) => send<ServiceMoveView>('POST', `/v1/services/${id}/move`, { serverId }),
|
|
453
|
+
},
|
|
454
|
+
inlineDockerfile: {
|
|
455
|
+
get: (id) => get<InlineDockerfileView>(`/v1/services/${id}/inline-dockerfile`),
|
|
456
|
+
set: (id, content) => send<InlineDockerfileView>('PUT', `/v1/services/${id}/inline-dockerfile`, { content }),
|
|
457
|
+
},
|
|
458
|
+
commitStatus: {
|
|
459
|
+
get: (id) => get<ServiceCommitStatusView>(`/v1/services/${id}/commit-status`),
|
|
460
|
+
set: (id, enabled) => send<ServiceCommitStatusView>('PUT', `/v1/services/${id}/commit-status`, { enabled }),
|
|
461
|
+
},
|
|
462
|
+
registryHook: {
|
|
463
|
+
get: (id) => get<RegistryHookView>(`/v1/services/${id}/registry-hook`),
|
|
464
|
+
enable: (id) => send<RegistryHookView>('POST', `/v1/services/${id}/registry-hook`),
|
|
465
|
+
disable: (id) => request<RegistryHookView>(`/v1/services/${id}/registry-hook`, { method: 'DELETE' }),
|
|
466
|
+
},
|
|
467
|
+
restartLimit: {
|
|
468
|
+
get: (id) => get<RestartLimitView>(`/v1/services/${id}/restart-limit`),
|
|
469
|
+
set: (id, limit) => send<RestartLimitView>('PUT', `/v1/services/${id}/restart-limit`, { limit }),
|
|
470
|
+
},
|
|
471
|
+
pending: {
|
|
472
|
+
get: (id) => get<PendingChangesView>(`/v1/services/${id}/pending`),
|
|
473
|
+
stage: (id, patch) => send<PendingChangesView>('PUT', `/v1/services/${id}/pending`, patch),
|
|
474
|
+
setStaging: (id, staging) => send<PendingChangesView>('PUT', `/v1/services/${id}/pending/staging`, { staging }),
|
|
475
|
+
discard: (id) => send<PendingChangesView>('DELETE', `/v1/services/${id}/pending`),
|
|
476
|
+
apply: (id, input) => send<PendingApplyResult>('POST', `/v1/services/${id}/pending/apply`, input ?? {}),
|
|
477
|
+
},
|
|
340
478
|
sleep: (id) => send<{ ok: boolean; asleep: boolean }>('POST', `/v1/services/${id}/sleep`),
|
|
341
479
|
wake: (id) => send<{ ok: boolean; status: string }>('POST', `/v1/services/${id}/wake`),
|
|
342
480
|
// ── end 0.16 T8 ──
|
|
@@ -11,10 +11,36 @@ import type {
|
|
|
11
11
|
SecretProviderView,
|
|
12
12
|
VaultProviderPut,
|
|
13
13
|
AwsProviderPut,
|
|
14
|
+
GcpProviderPut,
|
|
15
|
+
AzureProviderPut,
|
|
16
|
+
OnePasswordProviderPut,
|
|
17
|
+
ExecProviderPut,
|
|
14
18
|
} from '@ninedeploy/schemas';
|
|
15
19
|
import type { VaultAllowlistView, VaultSettings, EmailTemplateName, EmailTemplateEntry, EmailTemplateRender } from '../types.js';
|
|
16
20
|
import type { Transport } from '../transport.js';
|
|
17
21
|
|
|
22
|
+
/** The PUT body of each secret provider kind (G3.2 added gcp, azure, onepassword, exec). */
|
|
23
|
+
export type SecretProviderPutFor<K extends SecretProviderKind> = {
|
|
24
|
+
vault: VaultProviderPut;
|
|
25
|
+
aws: AwsProviderPut;
|
|
26
|
+
gcp: GcpProviderPut;
|
|
27
|
+
azure: AzureProviderPut;
|
|
28
|
+
onepassword: OnePasswordProviderPut;
|
|
29
|
+
exec: ExecProviderPut;
|
|
30
|
+
}[K];
|
|
31
|
+
|
|
32
|
+
/** G3.5: the DNS record providers configured through `settings.dnsProvider`. */
|
|
33
|
+
export type DnsCredentialProviderName = 'route53' | 'ovh' | 'porkbun' | 'hetzner';
|
|
34
|
+
export interface DnsProviderSettings {
|
|
35
|
+
providers: DnsCredentialProviderName[];
|
|
36
|
+
/** The active `dns_records_provider` (may be cloudflare, dnsimple, …). */
|
|
37
|
+
provider: string | null;
|
|
38
|
+
/** Which of these four has credentials saved. */
|
|
39
|
+
configured: DnsCredentialProviderName | null;
|
|
40
|
+
/** The saved non-secret fields (an access key id, an OVH endpoint). */
|
|
41
|
+
fields: Record<string, string>;
|
|
42
|
+
}
|
|
43
|
+
|
|
18
44
|
export type AutoUrlMode = 'off' | 'domain' | 'sslip';
|
|
19
45
|
export interface AutoUrlEffective {
|
|
20
46
|
mode: AutoUrlMode;
|
|
@@ -88,6 +114,17 @@ export interface SettingsApi {
|
|
|
88
114
|
get: () => Promise<{ configured: boolean; apiUser: string | null; clientIp: string | null; hasKey: boolean }>;
|
|
89
115
|
set: (input: { apiUser: string; apiKey: string; clientIp: string }) => Promise<{ ok: boolean; apiUser: string }>;
|
|
90
116
|
};
|
|
117
|
+
/**
|
|
118
|
+
* G3.5: Route 53, OVH, Porkbun and Hetzner DNS record auto-provisioning.
|
|
119
|
+
* Saving credentials makes that provider the active one; `get` never
|
|
120
|
+
* returns a secret.
|
|
121
|
+
*/
|
|
122
|
+
dnsProvider: {
|
|
123
|
+
get: () => Promise<DnsProviderSettings>;
|
|
124
|
+
set: (input: { provider: DnsCredentialProviderName; credentials: Record<string, string> }) => Promise<{ ok: boolean; provider: string }>;
|
|
125
|
+
clear: () => Promise<{ ok: boolean }>;
|
|
126
|
+
test: () => Promise<{ ok: boolean; provider?: string; zones?: string[]; zoneCount?: number; error?: string }>;
|
|
127
|
+
};
|
|
91
128
|
/**
|
|
92
129
|
* Master-key rotation. `rotate` re-encrypts every stored secret onto the
|
|
93
130
|
* highest key version in `NINEDEPLOY_MASTER_KEYS`; it does NOT rewrite
|
|
@@ -114,7 +151,7 @@ export interface SettingsApi {
|
|
|
114
151
|
*/
|
|
115
152
|
secretProviders: {
|
|
116
153
|
list: () => Promise<SecretProviderView[]>;
|
|
117
|
-
set: <K extends SecretProviderKind>(kind: K, input: K
|
|
154
|
+
set: <K extends SecretProviderKind>(kind: K, input: SecretProviderPutFor<K>) => Promise<SecretProviderView>;
|
|
118
155
|
delete: (kind: SecretProviderKind) => Promise<{ ok: boolean; deleted: boolean }>;
|
|
119
156
|
test: (kind: SecretProviderKind, probe?: SecretProviderTestRequest) => Promise<SecretProviderTestResult>;
|
|
120
157
|
};
|
|
@@ -237,6 +274,13 @@ export function settingsApi(t: Transport): SettingsApi {
|
|
|
237
274
|
get: () => get<{ configured: boolean; apiUser: string | null; clientIp: string | null; hasKey: boolean }>('/v1/settings/dns-records/namecheap'),
|
|
238
275
|
set: (input) => send<{ ok: boolean; apiUser: string }>('PUT', '/v1/settings/dns-records/namecheap', input),
|
|
239
276
|
},
|
|
277
|
+
dnsProvider: {
|
|
278
|
+
get: () => get<DnsProviderSettings>('/v1/settings/dns-records/provider'),
|
|
279
|
+
set: (input) => send<{ ok: boolean; provider: string }>('PUT', '/v1/settings/dns-records/provider', input),
|
|
280
|
+
clear: () => send<{ ok: boolean }>('DELETE', '/v1/settings/dns-records/provider'),
|
|
281
|
+
test: () =>
|
|
282
|
+
send<{ ok: boolean; provider?: string; zones?: string[]; zoneCount?: number; error?: string }>('POST', '/v1/settings/dns-records/provider/test'),
|
|
283
|
+
},
|
|
240
284
|
masterKey: {
|
|
241
285
|
get: () => get<{ activeVersion: number; knownVersions: number[]; rotatable: boolean }>('/v1/settings/master-key'),
|
|
242
286
|
rotate: () =>
|