@astrogate/sdk 0.1.0-rc.1 → 0.2.0
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/admission.d.ts +35 -0
- package/dist/admission.js +112 -0
- package/dist/http.d.ts +4 -1
- package/dist/http.js +78 -20
- package/dist/inventory.js +2 -0
- package/dist/management.d.ts +20 -0
- package/dist/management.js +2 -0
- package/dist/operator-resources.d.ts +8 -0
- package/dist/operator-resources.js +73 -0
- package/dist/operator.d.ts +51 -0
- package/dist/operator.js +23 -2
- package/dist/wire.gen.d.ts +685 -0
- package/package.json +1 -1
- package/release.json +2 -2
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ManagementOptions } from "./management.js";
|
|
2
|
+
import type { components } from "./wire.gen.js";
|
|
3
|
+
type Schemas = components["schemas"];
|
|
4
|
+
export type AdmissionPolicy = Schemas["AdmissionPolicy"];
|
|
5
|
+
export type AdmissionState = Schemas["AdmissionState"];
|
|
6
|
+
export type AdmissionUsagePage = Schemas["AdmissionUsagePage"];
|
|
7
|
+
export interface UsageQuery {
|
|
8
|
+
from: string;
|
|
9
|
+
until: string;
|
|
10
|
+
limit: number;
|
|
11
|
+
project?: string;
|
|
12
|
+
environment?: string;
|
|
13
|
+
workload?: "application" | "database" | "identity" | "storage" | "jobs" | "builds" | "realtime";
|
|
14
|
+
subject?: string;
|
|
15
|
+
after?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function admissionState(value: unknown): value is AdmissionState;
|
|
18
|
+
export declare function admissionUsage(value: unknown): value is AdmissionUsagePage;
|
|
19
|
+
export declare function admissionClient(options: ManagementOptions, endpoint: URL, base: string): {
|
|
20
|
+
get: (signal?: AbortSignal) => Promise<{
|
|
21
|
+
policy: components["schemas"]["AdmissionPolicy"];
|
|
22
|
+
occupancy: components["schemas"]["AdmissionOccupancy"][];
|
|
23
|
+
storageCredits: components["schemas"]["TenantStorageCredit"][];
|
|
24
|
+
}>;
|
|
25
|
+
assign: (input: Schemas["AssignAdmissionPolicy"], signal?: AbortSignal) => Promise<{
|
|
26
|
+
revision: number;
|
|
27
|
+
profile: components["schemas"]["AdmissionProfile"];
|
|
28
|
+
assignedAt: string;
|
|
29
|
+
}>;
|
|
30
|
+
usage: (query: UsageQuery, signal?: AbortSignal) => Promise<{
|
|
31
|
+
points: components["schemas"]["AdmissionUsagePoint"][];
|
|
32
|
+
next?: string;
|
|
33
|
+
}>;
|
|
34
|
+
};
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { AstrogateError, object, requestJSON } from "./http.js";
|
|
2
|
+
function count(value) {
|
|
3
|
+
return Number.isSafeInteger(value) && Number(value) >= 0;
|
|
4
|
+
}
|
|
5
|
+
function date(value) {
|
|
6
|
+
return typeof value === "string" && Number.isFinite(Date.parse(value));
|
|
7
|
+
}
|
|
8
|
+
function positive(value) {
|
|
9
|
+
return count(value) && value > 0;
|
|
10
|
+
}
|
|
11
|
+
function rule(value) {
|
|
12
|
+
return (object(value) &&
|
|
13
|
+
typeof value.requestsPerSecond === "number" &&
|
|
14
|
+
Number.isFinite(value.requestsPerSecond) &&
|
|
15
|
+
value.requestsPerSecond > 0 &&
|
|
16
|
+
["burst", "concurrent", "executionMs"].every((key) => positive(value[key])) &&
|
|
17
|
+
["pending", "pendingBytes", "waitMs"].every((key) => count(value[key])));
|
|
18
|
+
}
|
|
19
|
+
function validRetention(value) {
|
|
20
|
+
return (object(value) &&
|
|
21
|
+
positive(value.rawLogsSeconds) &&
|
|
22
|
+
positive(value.usageSeconds) &&
|
|
23
|
+
count(value.subjectSeconds) &&
|
|
24
|
+
value.subjectSeconds <= value.usageSeconds);
|
|
25
|
+
}
|
|
26
|
+
function policy(value) {
|
|
27
|
+
if (!object(value) ||
|
|
28
|
+
!positive(value.revision) ||
|
|
29
|
+
!date(value.assignedAt) ||
|
|
30
|
+
!object(value.profile))
|
|
31
|
+
return false;
|
|
32
|
+
const p = value.profile;
|
|
33
|
+
return (typeof p.id === "string" &&
|
|
34
|
+
p.id.length > 0 &&
|
|
35
|
+
typeof p.evidence === "string" &&
|
|
36
|
+
p.evidence.length > 0 &&
|
|
37
|
+
positive(p.durableBytes) &&
|
|
38
|
+
validRetention(p.retention) &&
|
|
39
|
+
object(p.rules) &&
|
|
40
|
+
object(p.rules.all) &&
|
|
41
|
+
Object.entries(p.rules).every(([kind, value]) => [
|
|
42
|
+
"all",
|
|
43
|
+
"application",
|
|
44
|
+
"database",
|
|
45
|
+
"identity",
|
|
46
|
+
"storage",
|
|
47
|
+
"jobs",
|
|
48
|
+
"builds",
|
|
49
|
+
"realtime",
|
|
50
|
+
].includes(kind) &&
|
|
51
|
+
object(value) &&
|
|
52
|
+
rule(value.tenant) &&
|
|
53
|
+
rule(value.application)));
|
|
54
|
+
}
|
|
55
|
+
export function admissionState(value) {
|
|
56
|
+
return (object(value) &&
|
|
57
|
+
policy(value.policy) &&
|
|
58
|
+
Array.isArray(value.occupancy) &&
|
|
59
|
+
value.occupancy.every((o) => object(o) &&
|
|
60
|
+
typeof o.projectId === "string" &&
|
|
61
|
+
typeof o.workload === "string" &&
|
|
62
|
+
["running", "unacknowledged", "pending", "pendingBytes"].every((key) => count(o[key])) &&
|
|
63
|
+
(o.oldest === undefined || date(o.oldest))) &&
|
|
64
|
+
Array.isArray(value.storageCredits) &&
|
|
65
|
+
value.storageCredits.every((c) => object(c) &&
|
|
66
|
+
["projectId", "environmentId", "block", "owner"].every((key) => typeof c[key] === "string") &&
|
|
67
|
+
count(c.bytes) &&
|
|
68
|
+
count(c.epoch)));
|
|
69
|
+
}
|
|
70
|
+
export function admissionUsage(value) {
|
|
71
|
+
return (object(value) &&
|
|
72
|
+
(value.next === undefined || date(value.next)) &&
|
|
73
|
+
Array.isArray(value.points) &&
|
|
74
|
+
value.points.every((p) => object(p) &&
|
|
75
|
+
date(p.hour) &&
|
|
76
|
+
typeof p.workload === "string" &&
|
|
77
|
+
typeof p.outcome === "string" &&
|
|
78
|
+
["requests", "bytes", "elapsedMs"].every((key) => count(p[key]))));
|
|
79
|
+
}
|
|
80
|
+
// This namespace uses the same authority and transport as the management client.
|
|
81
|
+
// A profile reference is the only writable entitlement, never arbitrary limits.
|
|
82
|
+
export function admissionClient(options, endpoint, base) {
|
|
83
|
+
const headers = { authorization: `Bearer ${options.token}` };
|
|
84
|
+
return {
|
|
85
|
+
get: (signal) => requestJSON(new URL(base + "/admission", endpoint), options, { headers }, admissionState, signal),
|
|
86
|
+
assign: (input, signal) => {
|
|
87
|
+
if (!input.profileId || !count(input.expectedRevision))
|
|
88
|
+
throw new AstrogateError("invalid_policy_assignment", 0, "", false);
|
|
89
|
+
// A lost response to CAS needs a read/reconciliation, not a blind replay.
|
|
90
|
+
return requestJSON(new URL(base + "/admission", endpoint), { ...options, maxAttempts: 1 }, {
|
|
91
|
+
method: "POST",
|
|
92
|
+
headers: { ...headers, "content-type": "application/json" },
|
|
93
|
+
body: JSON.stringify(input),
|
|
94
|
+
}, policy, signal);
|
|
95
|
+
},
|
|
96
|
+
usage: (query, signal) => {
|
|
97
|
+
if (!date(query.from) ||
|
|
98
|
+
!date(query.until) ||
|
|
99
|
+
Date.parse(query.from) >= Date.parse(query.until) ||
|
|
100
|
+
!count(query.limit) ||
|
|
101
|
+
query.limit === 0 ||
|
|
102
|
+
(query.environment && !query.project) ||
|
|
103
|
+
(query.after && !date(query.after)))
|
|
104
|
+
throw new AstrogateError("invalid_usage_query", 0, "", false);
|
|
105
|
+
const url = new URL(base + "/usage", endpoint);
|
|
106
|
+
for (const [key, value] of Object.entries(query))
|
|
107
|
+
if (value !== undefined)
|
|
108
|
+
url.searchParams.set(key, String(value));
|
|
109
|
+
return requestJSON(url, options, { headers }, admissionUsage, signal);
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
package/dist/http.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import type { components } from "./wire.gen.js";
|
|
2
|
+
export type FailureDetails = Pick<components["schemas"]["Error"], "message" | "scope" | "dimension" | "reason">;
|
|
1
3
|
export declare class AstrogateError extends Error {
|
|
2
4
|
readonly code: string;
|
|
3
5
|
readonly status: number;
|
|
4
6
|
readonly requestId: string;
|
|
5
7
|
readonly retryable: boolean;
|
|
6
|
-
|
|
8
|
+
readonly details?: Partial<FailureDetails> | undefined;
|
|
9
|
+
constructor(code: string, status: number, requestId: string, retryable: boolean, details?: Partial<FailureDetails> | undefined);
|
|
7
10
|
}
|
|
8
11
|
export interface TransportBudget {
|
|
9
12
|
deadlineMs: number;
|
package/dist/http.js
CHANGED
|
@@ -1,42 +1,85 @@
|
|
|
1
|
-
// Shared owned HTTP behavior. Native database/auth clients retain their own
|
|
2
|
-
// return values and transport semantics.
|
|
3
1
|
export class AstrogateError extends Error {
|
|
4
2
|
code;
|
|
5
3
|
status;
|
|
6
4
|
requestId;
|
|
7
5
|
retryable;
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
details;
|
|
7
|
+
constructor(code, status, requestId, retryable, details) {
|
|
8
|
+
super(details?.message ?? code);
|
|
10
9
|
this.code = code;
|
|
11
10
|
this.status = status;
|
|
12
11
|
this.requestId = requestId;
|
|
13
12
|
this.retryable = retryable;
|
|
13
|
+
this.details = details;
|
|
14
14
|
this.name = "AstrogateError";
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
export function object(value) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export function
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
export function object(value) {
|
|
18
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19
|
+
}
|
|
20
|
+
export function identifier(value) {
|
|
21
|
+
if (!/^[A-Za-z0-9_-]+$/.test(value))
|
|
22
|
+
throw new AstrogateError("invalid_resource_reference", 0, "", false);
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
export function validateBudget(options) {
|
|
26
|
+
if (!Number.isSafeInteger(options.deadlineMs) ||
|
|
27
|
+
options.deadlineMs <= 0 ||
|
|
28
|
+
options.deadlineMs > timerMaximumMs ||
|
|
29
|
+
!Number.isSafeInteger(options.maxAttempts) ||
|
|
30
|
+
options.maxAttempts < 1)
|
|
31
|
+
throw new AstrogateError("explicit_transport_budget_required", 0, "", false);
|
|
32
|
+
}
|
|
33
|
+
// Native browser/Node timers use signed 32-bit millisecond delays. Durable
|
|
34
|
+
// operations outlive transport calls and are polled instead of held for days.
|
|
35
|
+
const timerMaximumMs = 2 ** 31 - 1;
|
|
36
|
+
function optionalText(value, key) {
|
|
37
|
+
const field = value[key];
|
|
38
|
+
if (field !== undefined && typeof field !== "string")
|
|
39
|
+
throw new AstrogateError("invalid_error_response", 0, "", false);
|
|
40
|
+
return field;
|
|
41
|
+
}
|
|
42
|
+
function delay(ms, signal) {
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
if (signal.aborted) {
|
|
45
|
+
reject(signal.reason);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const abort = () => {
|
|
49
|
+
clearTimeout(timer);
|
|
50
|
+
reject(signal.reason);
|
|
51
|
+
};
|
|
52
|
+
const timer = setTimeout(() => {
|
|
53
|
+
signal.removeEventListener("abort", abort);
|
|
54
|
+
resolve();
|
|
55
|
+
}, ms);
|
|
56
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
57
|
+
});
|
|
58
|
+
}
|
|
26
59
|
export async function requestResponse(url, options, input, signal) {
|
|
27
60
|
validateBudget(options);
|
|
28
|
-
const combined = signal
|
|
61
|
+
const combined = signal
|
|
62
|
+
? AbortSignal.any([AbortSignal.timeout(options.deadlineMs), signal])
|
|
63
|
+
: AbortSignal.timeout(options.deadlineMs);
|
|
29
64
|
let last;
|
|
30
65
|
for (let attempt = 0; attempt < options.maxAttempts; attempt++) {
|
|
31
66
|
let retryAfter = 0;
|
|
32
67
|
try {
|
|
33
|
-
const response = await fetch(url, {
|
|
68
|
+
const response = await fetch(url, {
|
|
69
|
+
...input,
|
|
70
|
+
signal: combined,
|
|
71
|
+
redirect: "error",
|
|
72
|
+
cache: "no-store",
|
|
73
|
+
});
|
|
34
74
|
if (response.ok)
|
|
35
75
|
return response;
|
|
36
76
|
const after = response.headers.get("retry-after");
|
|
37
77
|
if (after) {
|
|
38
78
|
const seconds = Number(after);
|
|
39
|
-
|
|
79
|
+
const parsed = Number.isFinite(seconds)
|
|
80
|
+
? seconds * 1000
|
|
81
|
+
: Date.parse(after) - Date.now();
|
|
82
|
+
retryAfter = Number.isFinite(parsed) ? Math.max(0, parsed) : 0;
|
|
40
83
|
}
|
|
41
84
|
let value;
|
|
42
85
|
try {
|
|
@@ -45,9 +88,17 @@ export async function requestResponse(url, options, input, signal) {
|
|
|
45
88
|
catch {
|
|
46
89
|
throw new AstrogateError("invalid_error_response", response.status, "", false);
|
|
47
90
|
}
|
|
48
|
-
if (!object(value) ||
|
|
91
|
+
if (!object(value) ||
|
|
92
|
+
typeof value.code !== "string" ||
|
|
93
|
+
typeof value.requestId !== "string" ||
|
|
94
|
+
typeof value.retryable !== "boolean")
|
|
49
95
|
throw new AstrogateError("invalid_error_response", response.status, "", false);
|
|
50
|
-
throw new AstrogateError(value.code, response.status, value.requestId, value.retryable
|
|
96
|
+
throw new AstrogateError(value.code, response.status, value.requestId, value.retryable, {
|
|
97
|
+
message: optionalText(value, "message"),
|
|
98
|
+
scope: optionalText(value, "scope"),
|
|
99
|
+
dimension: optionalText(value, "dimension"),
|
|
100
|
+
reason: optionalText(value, "reason"),
|
|
101
|
+
});
|
|
51
102
|
}
|
|
52
103
|
catch (error) {
|
|
53
104
|
if (combined.aborted)
|
|
@@ -57,7 +108,7 @@ export async function requestResponse(url, options, input, signal) {
|
|
|
57
108
|
throw error;
|
|
58
109
|
if (attempt + 1 === options.maxAttempts)
|
|
59
110
|
break;
|
|
60
|
-
await delay(Math.max(retryAfter, 100 * 2 ** attempt * (0.5 + Math.random())), combined);
|
|
111
|
+
await delay(Math.min(options.deadlineMs, Math.max(retryAfter, 100 * 2 ** attempt * (0.5 + Math.random()))), combined);
|
|
61
112
|
}
|
|
62
113
|
}
|
|
63
114
|
if (last instanceof AstrogateError)
|
|
@@ -83,7 +134,14 @@ export function managementAuthority(options) {
|
|
|
83
134
|
if (typeof window !== "undefined")
|
|
84
135
|
throw new AstrogateError("server_only_entrypoint", 0, "", false);
|
|
85
136
|
const endpoint = new URL(options.endpoint);
|
|
86
|
-
if ((endpoint.protocol !== "https:" &&
|
|
137
|
+
if ((endpoint.protocol !== "https:" &&
|
|
138
|
+
!(endpoint.protocol === "http:" &&
|
|
139
|
+
["127.0.0.1", "[::1]", "localhost"].includes(endpoint.hostname))) ||
|
|
140
|
+
endpoint.username ||
|
|
141
|
+
endpoint.password ||
|
|
142
|
+
endpoint.search ||
|
|
143
|
+
endpoint.hash ||
|
|
144
|
+
endpoint.pathname !== "/")
|
|
87
145
|
throw new AstrogateError("unsafe_management_authority", 0, "", false);
|
|
88
146
|
validateBudget(options);
|
|
89
147
|
if (!options.token)
|
package/dist/inventory.js
CHANGED
|
@@ -6,6 +6,8 @@ export function listQuery(options) {
|
|
|
6
6
|
throw new AstrogateError("invalid_page_limit", 0, "", false);
|
|
7
7
|
query.set("limit", String(options.limit));
|
|
8
8
|
}
|
|
9
|
+
if (options.search !== undefined)
|
|
10
|
+
query.set("search", options.search);
|
|
9
11
|
if (options.cursor !== undefined)
|
|
10
12
|
query.set("cursor", options.cursor);
|
|
11
13
|
return query.size ? `?${query}` : "";
|
package/dist/management.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type PageOptions } from "./inventory.js";
|
|
2
|
+
export type { AdmissionPolicy, AdmissionState, AdmissionUsagePage, UsageQuery } from "./admission.js";
|
|
2
3
|
export { AstrogateError } from "./http.js";
|
|
3
4
|
import type { components } from "./wire.gen.js";
|
|
4
5
|
type Schemas = components["schemas"];
|
|
@@ -47,6 +48,25 @@ export interface ManagementOptions {
|
|
|
47
48
|
maxAttempts: number;
|
|
48
49
|
}
|
|
49
50
|
export declare function createManagement(options: ManagementOptions): {
|
|
51
|
+
admission: {
|
|
52
|
+
get: (signal?: AbortSignal) => Promise<{
|
|
53
|
+
policy: components["schemas"]["AdmissionPolicy"];
|
|
54
|
+
occupancy: components["schemas"]["AdmissionOccupancy"][];
|
|
55
|
+
storageCredits: components["schemas"]["TenantStorageCredit"][];
|
|
56
|
+
}>;
|
|
57
|
+
assign: (input: {
|
|
58
|
+
profileId: string;
|
|
59
|
+
expectedRevision: number;
|
|
60
|
+
}, signal?: AbortSignal) => Promise<{
|
|
61
|
+
revision: number;
|
|
62
|
+
profile: components["schemas"]["AdmissionProfile"];
|
|
63
|
+
assignedAt: string;
|
|
64
|
+
}>;
|
|
65
|
+
usage: (query: import("./admission.js").UsageQuery, signal?: AbortSignal) => Promise<{
|
|
66
|
+
points: components["schemas"]["AdmissionUsagePoint"][];
|
|
67
|
+
next?: string;
|
|
68
|
+
}>;
|
|
69
|
+
};
|
|
50
70
|
projects: {
|
|
51
71
|
create: (input: CreateProject, controls: RequestOptions) => Promise<{
|
|
52
72
|
operationId: string;
|
package/dist/management.js
CHANGED
|
@@ -3,6 +3,7 @@ import { project, environment, placementState, placementLocations, operation, op
|
|
|
3
3
|
import { listQuery, pageOf } from "./inventory.js";
|
|
4
4
|
import { managementAuthority } from "./http.js";
|
|
5
5
|
import { serviceBindings } from "./services.js";
|
|
6
|
+
import { admissionClient } from "./admission.js";
|
|
6
7
|
export { AstrogateError } from "./http.js";
|
|
7
8
|
function object(value) {
|
|
8
9
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -66,6 +67,7 @@ export function createManagement(options) {
|
|
|
66
67
|
return requestJSON(new URL(base + path, endpoint), options, { method: method ?? (body === undefined ? "GET" : "POST"), headers, body }, validate, controls?.signal ?? signal);
|
|
67
68
|
}
|
|
68
69
|
return {
|
|
70
|
+
admission: admissionClient(options, endpoint, base),
|
|
69
71
|
projects: { create: (input, controls) => request(`/projects`, accepted, input, controls), list: (page = {}, signal) => request(`/projects${listQuery(page)}`, pageOf(project), undefined, undefined, signal), get: (resource, signal) => request(`/projects/${id(resource)}`, project, undefined, undefined, signal) },
|
|
70
72
|
repositories: {
|
|
71
73
|
create: (project, input, controls) => request(`/projects/${id(project)}/repository`, accepted, input, controls),
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { components } from "./wire.gen.js";
|
|
2
|
+
export type ResourceSummary = components["schemas"]["ResourceSummary"];
|
|
3
|
+
export type ResourceRelationships = components["schemas"]["ResourceRelationships"];
|
|
4
|
+
export type ResourceNode = components["schemas"]["ResourceNode"];
|
|
5
|
+
export type ResourceRelationship = components["schemas"]["ResourceRelationship"];
|
|
6
|
+
export type ResourceSummaryPage = components["schemas"]["ResourceSummaryPage"];
|
|
7
|
+
export declare function resourceSummary(value: unknown): value is ResourceSummary;
|
|
8
|
+
export declare function resourceRelationships(value: unknown): value is ResourceRelationships;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { object } from "./http.js";
|
|
2
|
+
function strings(value, fields) {
|
|
3
|
+
return object(value) && fields.every((key) => typeof value[key] === "string");
|
|
4
|
+
}
|
|
5
|
+
export function resourceSummary(value) {
|
|
6
|
+
return strings(value, [
|
|
7
|
+
"product",
|
|
8
|
+
"tenant",
|
|
9
|
+
"project",
|
|
10
|
+
"projectName",
|
|
11
|
+
"environment",
|
|
12
|
+
"environmentName",
|
|
13
|
+
"environmentKind",
|
|
14
|
+
"cell",
|
|
15
|
+
"location",
|
|
16
|
+
"phase",
|
|
17
|
+
]);
|
|
18
|
+
}
|
|
19
|
+
function dateOrNull(value) {
|
|
20
|
+
return (value === null ||
|
|
21
|
+
(typeof value === "string" && Number.isFinite(Date.parse(value))));
|
|
22
|
+
}
|
|
23
|
+
export function resourceRelationships(value) {
|
|
24
|
+
if (!object(value) ||
|
|
25
|
+
!resourceSummary(value.resource) ||
|
|
26
|
+
!Number.isSafeInteger(value.epoch) ||
|
|
27
|
+
!dateOrNull(value.observedAt) ||
|
|
28
|
+
!dateOrNull(value.validUntil) ||
|
|
29
|
+
typeof value.fresh !== "boolean")
|
|
30
|
+
return false;
|
|
31
|
+
if (!Array.isArray(value.nodes) ||
|
|
32
|
+
!value.nodes.every((node) => strings(node, [
|
|
33
|
+
"id",
|
|
34
|
+
"kind",
|
|
35
|
+
"label",
|
|
36
|
+
"resourceId",
|
|
37
|
+
"providerId",
|
|
38
|
+
"cell",
|
|
39
|
+
"location",
|
|
40
|
+
"state",
|
|
41
|
+
"allocation",
|
|
42
|
+
"evidence",
|
|
43
|
+
"operationId",
|
|
44
|
+
])))
|
|
45
|
+
return false;
|
|
46
|
+
const ids = new Set(value.nodes.map((node) => node.id));
|
|
47
|
+
if (ids.size !== value.nodes.length ||
|
|
48
|
+
!Array.isArray(value.relationships) ||
|
|
49
|
+
!value.relationships.every((edge) => strings(edge, ["id", "source", "target", "kind", "evidence"]) &&
|
|
50
|
+
object(edge) &&
|
|
51
|
+
ids.has(edge.source) &&
|
|
52
|
+
ids.has(edge.target)))
|
|
53
|
+
return false;
|
|
54
|
+
if (!object(value.recovery) ||
|
|
55
|
+
!strings(value.recovery, [
|
|
56
|
+
"protection",
|
|
57
|
+
"targetCell",
|
|
58
|
+
"targetLocation",
|
|
59
|
+
"automaticFailover",
|
|
60
|
+
]) ||
|
|
61
|
+
value.recovery.automaticFailover !== "not-established" ||
|
|
62
|
+
!dateOrNull(value.recovery.checkpointAt))
|
|
63
|
+
return false;
|
|
64
|
+
const test = value.recovery.latestTest;
|
|
65
|
+
if (test !== null &&
|
|
66
|
+
(!strings(test, ["operationId", "state", "recordedAt"]) ||
|
|
67
|
+
!object(test) ||
|
|
68
|
+
typeof test.recordedAt !== "string" ||
|
|
69
|
+
!Number.isFinite(Date.parse(test.recordedAt))))
|
|
70
|
+
return false;
|
|
71
|
+
return (Array.isArray(value.notes) &&
|
|
72
|
+
value.notes.every((note) => typeof note === "string"));
|
|
73
|
+
}
|
package/dist/operator.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { type TransportBudget } from "./http.js";
|
|
2
|
+
import { type UsageQuery } from "./admission.js";
|
|
3
|
+
export type { AdmissionState, AdmissionPolicy, AdmissionUsagePage, UsageQuery } from "./admission.js";
|
|
4
|
+
export type { ResourceSummary, ResourceRelationships, ResourceNode, ResourceRelationship, ResourceSummaryPage } from "./operator-resources.js";
|
|
2
5
|
import { type PageOptions } from "./inventory.js";
|
|
3
6
|
import type { components } from "./wire.gen.js";
|
|
4
7
|
export { AstrogateError } from "./http.js";
|
|
@@ -9,6 +12,54 @@ export type OperatorOptions = TransportBudget & {
|
|
|
9
12
|
export type { PageOptions } from "./inventory.js";
|
|
10
13
|
type EnvironmentTopology = components["schemas"]["EnvironmentTopology"];
|
|
11
14
|
export declare function createOperator(options: OperatorOptions): {
|
|
15
|
+
admission: {
|
|
16
|
+
get: (product: string, tenant: string, signal?: AbortSignal) => Promise<{
|
|
17
|
+
policy: components["schemas"]["AdmissionPolicy"];
|
|
18
|
+
occupancy: components["schemas"]["AdmissionOccupancy"][];
|
|
19
|
+
storageCredits: components["schemas"]["TenantStorageCredit"][];
|
|
20
|
+
}>;
|
|
21
|
+
usage: (product: string, tenant: string, query: UsageQuery, signal?: AbortSignal) => Promise<{
|
|
22
|
+
points: components["schemas"]["AdmissionUsagePoint"][];
|
|
23
|
+
next?: string;
|
|
24
|
+
}>;
|
|
25
|
+
};
|
|
26
|
+
resources: {
|
|
27
|
+
list: (product: string, tenant: string, page?: PageOptions, signal?: AbortSignal) => Promise<import("./inventory.js").InventoryPage<{
|
|
28
|
+
product: string;
|
|
29
|
+
tenant: string;
|
|
30
|
+
project: string;
|
|
31
|
+
projectName: string;
|
|
32
|
+
environment: string;
|
|
33
|
+
environmentName: string;
|
|
34
|
+
environmentKind: string;
|
|
35
|
+
cell: string;
|
|
36
|
+
location: string;
|
|
37
|
+
phase: string;
|
|
38
|
+
}>>;
|
|
39
|
+
relationships: (product: string, tenant: string, project: string, environment: string, signal?: AbortSignal) => Promise<{
|
|
40
|
+
resource: components["schemas"]["ResourceSummary"];
|
|
41
|
+
epoch: number;
|
|
42
|
+
observedAt: string | null;
|
|
43
|
+
validUntil: string | null;
|
|
44
|
+
fresh: boolean;
|
|
45
|
+
nodes: components["schemas"]["ResourceNode"][];
|
|
46
|
+
relationships: components["schemas"]["ResourceRelationship"][];
|
|
47
|
+
recovery: components["schemas"]["ResourceRecovery"];
|
|
48
|
+
notes: string[];
|
|
49
|
+
}>;
|
|
50
|
+
forHost: (providerId: string, page?: PageOptions, signal?: AbortSignal) => Promise<import("./inventory.js").InventoryPage<{
|
|
51
|
+
product: string;
|
|
52
|
+
tenant: string;
|
|
53
|
+
project: string;
|
|
54
|
+
projectName: string;
|
|
55
|
+
environment: string;
|
|
56
|
+
environmentName: string;
|
|
57
|
+
environmentKind: string;
|
|
58
|
+
cell: string;
|
|
59
|
+
location: string;
|
|
60
|
+
phase: string;
|
|
61
|
+
}>>;
|
|
62
|
+
};
|
|
12
63
|
products: {
|
|
13
64
|
list: (page?: PageOptions, signal?: AbortSignal) => Promise<import("./inventory.js").InventoryPage<{
|
|
14
65
|
id: string;
|
package/dist/operator.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
// authenticate here. Issuance and mutation remain installation-owned.
|
|
3
3
|
import { identifier, managementAuthority, object, requestJSON, } from "./http.js";
|
|
4
4
|
import { project, environment, placementState, operation, operationLog, operatorOperationDetail, buildingBlock, hostnameBinding } from "./management-read.js";
|
|
5
|
+
import { admissionState, admissionUsage } from "./admission.js";
|
|
6
|
+
import { resourceSummary, resourceRelationships } from "./operator-resources.js";
|
|
5
7
|
import { listQuery, pageOf } from "./inventory.js";
|
|
6
8
|
export { AstrogateError } from "./http.js";
|
|
7
9
|
function catalogEntry(value) {
|
|
@@ -14,13 +16,32 @@ function environmentTopology(value) {
|
|
|
14
16
|
}
|
|
15
17
|
export function createOperator(options) {
|
|
16
18
|
const endpoint = managementAuthority(options);
|
|
17
|
-
function read(path, validate, signal) {
|
|
18
|
-
return requestJSON(new URL(
|
|
19
|
+
function read(path, validate, signal, root = "/v1/operator/products") {
|
|
20
|
+
return requestJSON(new URL(`${root}${path}`, endpoint), options, { method: "GET", headers: { authorization: `Bearer ${options.token}` } }, validate, signal);
|
|
19
21
|
}
|
|
20
22
|
const scope = (product, tenant) => `/${identifier(product)}/tenants/${identifier(tenant)}`;
|
|
21
23
|
const projectPath = (product, tenant, id) => `${scope(product, tenant)}/projects/${identifier(id)}`;
|
|
22
24
|
const environmentPath = (product, tenant, project, id) => `${projectPath(product, tenant, project)}/environments/${identifier(id)}`;
|
|
23
25
|
return {
|
|
26
|
+
admission: {
|
|
27
|
+
get: (product, tenant, signal) => read(`${scope(product, tenant)}/admission`, admissionState, signal),
|
|
28
|
+
usage: (product, tenant, query, signal) => {
|
|
29
|
+
const parameters = new URLSearchParams();
|
|
30
|
+
for (const [key, value] of Object.entries(query))
|
|
31
|
+
if (value !== undefined)
|
|
32
|
+
parameters.set(key, String(value));
|
|
33
|
+
return read(`${scope(product, tenant)}/usage?${parameters}`, admissionUsage, signal);
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
resources: {
|
|
37
|
+
list: (product, tenant, page = {}, signal) => read(`${scope(product, tenant)}/resources${listQuery(page)}`, pageOf(resourceSummary), signal),
|
|
38
|
+
relationships: (product, tenant, project, environment, signal) => read(`${environmentPath(product, tenant, project, environment)}/relationships`, resourceRelationships, signal),
|
|
39
|
+
forHost: (providerId, page = {}, signal) => {
|
|
40
|
+
const query = new URLSearchParams(listQuery(page));
|
|
41
|
+
query.set("providerId", providerId);
|
|
42
|
+
return read(`?${query}`, pageOf(resourceSummary), signal, "/v1/operator/host-environments");
|
|
43
|
+
},
|
|
44
|
+
},
|
|
24
45
|
products: {
|
|
25
46
|
list: (page = {}, signal) => read(listQuery(page), pageOf(catalogEntry), signal),
|
|
26
47
|
},
|
package/dist/wire.gen.d.ts
CHANGED
|
@@ -1037,6 +1037,119 @@ export interface paths {
|
|
|
1037
1037
|
patch?: never;
|
|
1038
1038
|
trace?: never;
|
|
1039
1039
|
};
|
|
1040
|
+
"/v1/operator/products/{productId}/tenants/{tenantId}/resources": {
|
|
1041
|
+
parameters: {
|
|
1042
|
+
query?: never;
|
|
1043
|
+
header?: never;
|
|
1044
|
+
path?: never;
|
|
1045
|
+
cookie?: never;
|
|
1046
|
+
};
|
|
1047
|
+
get: operations["listOperatorResources"];
|
|
1048
|
+
put?: never;
|
|
1049
|
+
post?: never;
|
|
1050
|
+
delete?: never;
|
|
1051
|
+
options?: never;
|
|
1052
|
+
head?: never;
|
|
1053
|
+
patch?: never;
|
|
1054
|
+
trace?: never;
|
|
1055
|
+
};
|
|
1056
|
+
"/v1/operator/host-environments": {
|
|
1057
|
+
parameters: {
|
|
1058
|
+
query?: never;
|
|
1059
|
+
header?: never;
|
|
1060
|
+
path?: never;
|
|
1061
|
+
cookie?: never;
|
|
1062
|
+
};
|
|
1063
|
+
get: operations["listOperatorHostEnvironments"];
|
|
1064
|
+
put?: never;
|
|
1065
|
+
post?: never;
|
|
1066
|
+
delete?: never;
|
|
1067
|
+
options?: never;
|
|
1068
|
+
head?: never;
|
|
1069
|
+
patch?: never;
|
|
1070
|
+
trace?: never;
|
|
1071
|
+
};
|
|
1072
|
+
"/v1/operator/products/{productId}/tenants/{tenantId}/projects/{projectId}/environments/{environmentId}/relationships": {
|
|
1073
|
+
parameters: {
|
|
1074
|
+
query?: never;
|
|
1075
|
+
header?: never;
|
|
1076
|
+
path?: never;
|
|
1077
|
+
cookie?: never;
|
|
1078
|
+
};
|
|
1079
|
+
get: operations["getOperatorResourceRelationships"];
|
|
1080
|
+
put?: never;
|
|
1081
|
+
post?: never;
|
|
1082
|
+
delete?: never;
|
|
1083
|
+
options?: never;
|
|
1084
|
+
head?: never;
|
|
1085
|
+
patch?: never;
|
|
1086
|
+
trace?: never;
|
|
1087
|
+
};
|
|
1088
|
+
"/v1/tenants/{tenant}/admission": {
|
|
1089
|
+
parameters: {
|
|
1090
|
+
query?: never;
|
|
1091
|
+
header?: never;
|
|
1092
|
+
path?: never;
|
|
1093
|
+
cookie?: never;
|
|
1094
|
+
};
|
|
1095
|
+
get: operations["getAdmissionState"];
|
|
1096
|
+
put?: never;
|
|
1097
|
+
/** @description Requires policy.assign and an installation-registered profile grant. Revision compare-and-set does not auto-retry an uncertain response. Read current state before deciding whether to submit another change. */
|
|
1098
|
+
post: operations["assignAdmissionPolicy"];
|
|
1099
|
+
delete?: never;
|
|
1100
|
+
options?: never;
|
|
1101
|
+
head?: never;
|
|
1102
|
+
patch?: never;
|
|
1103
|
+
trace?: never;
|
|
1104
|
+
};
|
|
1105
|
+
"/v1/tenants/{tenant}/usage": {
|
|
1106
|
+
parameters: {
|
|
1107
|
+
query?: never;
|
|
1108
|
+
header?: never;
|
|
1109
|
+
path?: never;
|
|
1110
|
+
cookie?: never;
|
|
1111
|
+
};
|
|
1112
|
+
get: operations["getAdmissionUsage"];
|
|
1113
|
+
put?: never;
|
|
1114
|
+
post?: never;
|
|
1115
|
+
delete?: never;
|
|
1116
|
+
options?: never;
|
|
1117
|
+
head?: never;
|
|
1118
|
+
patch?: never;
|
|
1119
|
+
trace?: never;
|
|
1120
|
+
};
|
|
1121
|
+
"/v1/operator/products/{product}/tenants/{tenant}/admission": {
|
|
1122
|
+
parameters: {
|
|
1123
|
+
query?: never;
|
|
1124
|
+
header?: never;
|
|
1125
|
+
path?: never;
|
|
1126
|
+
cookie?: never;
|
|
1127
|
+
};
|
|
1128
|
+
get: operations["operatorAdmission"];
|
|
1129
|
+
put?: never;
|
|
1130
|
+
post?: never;
|
|
1131
|
+
delete?: never;
|
|
1132
|
+
options?: never;
|
|
1133
|
+
head?: never;
|
|
1134
|
+
patch?: never;
|
|
1135
|
+
trace?: never;
|
|
1136
|
+
};
|
|
1137
|
+
"/v1/operator/products/{product}/tenants/{tenant}/usage": {
|
|
1138
|
+
parameters: {
|
|
1139
|
+
query?: never;
|
|
1140
|
+
header?: never;
|
|
1141
|
+
path?: never;
|
|
1142
|
+
cookie?: never;
|
|
1143
|
+
};
|
|
1144
|
+
get: operations["operatorUsage"];
|
|
1145
|
+
put?: never;
|
|
1146
|
+
post?: never;
|
|
1147
|
+
delete?: never;
|
|
1148
|
+
options?: never;
|
|
1149
|
+
head?: never;
|
|
1150
|
+
patch?: never;
|
|
1151
|
+
trace?: never;
|
|
1152
|
+
};
|
|
1040
1153
|
}
|
|
1041
1154
|
export type webhooks = Record<string, never>;
|
|
1042
1155
|
export interface components {
|
|
@@ -1064,6 +1177,10 @@ export interface components {
|
|
|
1064
1177
|
message: string;
|
|
1065
1178
|
requestId: string;
|
|
1066
1179
|
retryable: boolean;
|
|
1180
|
+
scope?: string;
|
|
1181
|
+
dimension?: string;
|
|
1182
|
+
reason?: string;
|
|
1183
|
+
error?: string;
|
|
1067
1184
|
};
|
|
1068
1185
|
CreateDeployment: {
|
|
1069
1186
|
releaseId: string;
|
|
@@ -1562,6 +1679,168 @@ export interface components {
|
|
|
1562
1679
|
items: components["schemas"]["HostnameBinding"][];
|
|
1563
1680
|
nextCursor: string;
|
|
1564
1681
|
};
|
|
1682
|
+
ResourceSummary: {
|
|
1683
|
+
product: string;
|
|
1684
|
+
tenant: string;
|
|
1685
|
+
project: string;
|
|
1686
|
+
projectName: string;
|
|
1687
|
+
environment: string;
|
|
1688
|
+
environmentName: string;
|
|
1689
|
+
environmentKind: string;
|
|
1690
|
+
cell: string;
|
|
1691
|
+
location: string;
|
|
1692
|
+
phase: string;
|
|
1693
|
+
};
|
|
1694
|
+
ResourceSummaryPage: {
|
|
1695
|
+
items: components["schemas"]["ResourceSummary"][];
|
|
1696
|
+
nextCursor: string;
|
|
1697
|
+
};
|
|
1698
|
+
ResourceNode: {
|
|
1699
|
+
id: string;
|
|
1700
|
+
kind: string;
|
|
1701
|
+
label: string;
|
|
1702
|
+
resourceId: string;
|
|
1703
|
+
providerId: string;
|
|
1704
|
+
cell: string;
|
|
1705
|
+
location: string;
|
|
1706
|
+
state: string;
|
|
1707
|
+
allocation: string;
|
|
1708
|
+
evidence: string;
|
|
1709
|
+
operationId: string;
|
|
1710
|
+
};
|
|
1711
|
+
ResourceRelationship: {
|
|
1712
|
+
id: string;
|
|
1713
|
+
source: string;
|
|
1714
|
+
target: string;
|
|
1715
|
+
kind: string;
|
|
1716
|
+
evidence: string;
|
|
1717
|
+
};
|
|
1718
|
+
ResourceRecoveryTest: {
|
|
1719
|
+
operationId: string;
|
|
1720
|
+
state: string;
|
|
1721
|
+
/** Format: date-time */
|
|
1722
|
+
recordedAt: string;
|
|
1723
|
+
};
|
|
1724
|
+
ResourceRecovery: {
|
|
1725
|
+
protection: string;
|
|
1726
|
+
targetCell: string;
|
|
1727
|
+
targetLocation: string;
|
|
1728
|
+
/** Format: date-time */
|
|
1729
|
+
checkpointAt: string | null;
|
|
1730
|
+
latestTest: components["schemas"]["ResourceRecoveryTest"] | null;
|
|
1731
|
+
/** @enum {string} */
|
|
1732
|
+
automaticFailover: "not-established";
|
|
1733
|
+
};
|
|
1734
|
+
ResourceRelationships: {
|
|
1735
|
+
resource: components["schemas"]["ResourceSummary"];
|
|
1736
|
+
/** Format: int64 */
|
|
1737
|
+
epoch: number;
|
|
1738
|
+
/** Format: date-time */
|
|
1739
|
+
observedAt: string | null;
|
|
1740
|
+
/** Format: date-time */
|
|
1741
|
+
validUntil: string | null;
|
|
1742
|
+
fresh: boolean;
|
|
1743
|
+
nodes: components["schemas"]["ResourceNode"][];
|
|
1744
|
+
relationships: components["schemas"]["ResourceRelationship"][];
|
|
1745
|
+
recovery: components["schemas"]["ResourceRecovery"];
|
|
1746
|
+
notes: string[];
|
|
1747
|
+
};
|
|
1748
|
+
AdmissionRule: {
|
|
1749
|
+
/** Format: double */
|
|
1750
|
+
requestsPerSecond: number;
|
|
1751
|
+
/** Format: int64 */
|
|
1752
|
+
burst: number;
|
|
1753
|
+
/** Format: int64 */
|
|
1754
|
+
concurrent: number;
|
|
1755
|
+
/** Format: int64 */
|
|
1756
|
+
pending: number;
|
|
1757
|
+
/** Format: int64 */
|
|
1758
|
+
pendingBytes: number;
|
|
1759
|
+
/** Format: int64 */
|
|
1760
|
+
waitMs: number;
|
|
1761
|
+
/** Format: int64 */
|
|
1762
|
+
executionMs: number;
|
|
1763
|
+
};
|
|
1764
|
+
WorkloadRule: {
|
|
1765
|
+
tenant: components["schemas"]["AdmissionRule"];
|
|
1766
|
+
application: components["schemas"]["AdmissionRule"];
|
|
1767
|
+
};
|
|
1768
|
+
AdmissionRetention: {
|
|
1769
|
+
/** Format: int64 */
|
|
1770
|
+
rawLogsSeconds: number;
|
|
1771
|
+
/** Format: int64 */
|
|
1772
|
+
usageSeconds: number;
|
|
1773
|
+
/** Format: int64 */
|
|
1774
|
+
subjectSeconds: number;
|
|
1775
|
+
};
|
|
1776
|
+
AdmissionProfile: {
|
|
1777
|
+
id: string;
|
|
1778
|
+
evidence: string;
|
|
1779
|
+
rules: {
|
|
1780
|
+
[key: string]: components["schemas"]["WorkloadRule"];
|
|
1781
|
+
};
|
|
1782
|
+
/** Format: int64 */
|
|
1783
|
+
durableBytes: number;
|
|
1784
|
+
retention: components["schemas"]["AdmissionRetention"];
|
|
1785
|
+
};
|
|
1786
|
+
AdmissionPolicy: {
|
|
1787
|
+
/** Format: int64 */
|
|
1788
|
+
revision: number;
|
|
1789
|
+
profile: components["schemas"]["AdmissionProfile"];
|
|
1790
|
+
/** Format: date-time */
|
|
1791
|
+
assignedAt: string;
|
|
1792
|
+
};
|
|
1793
|
+
AssignAdmissionPolicy: {
|
|
1794
|
+
profileId: string;
|
|
1795
|
+
/** Format: int64 */
|
|
1796
|
+
expectedRevision: number;
|
|
1797
|
+
};
|
|
1798
|
+
AdmissionOccupancy: {
|
|
1799
|
+
projectId: string;
|
|
1800
|
+
workload: string;
|
|
1801
|
+
/** Format: int64 */
|
|
1802
|
+
running: number;
|
|
1803
|
+
/** Format: int64 */
|
|
1804
|
+
unacknowledged: number;
|
|
1805
|
+
/** Format: int64 */
|
|
1806
|
+
pending: number;
|
|
1807
|
+
/** Format: int64 */
|
|
1808
|
+
pendingBytes: number;
|
|
1809
|
+
/** Format: date-time */
|
|
1810
|
+
oldest?: string;
|
|
1811
|
+
};
|
|
1812
|
+
TenantStorageCredit: {
|
|
1813
|
+
projectId: string;
|
|
1814
|
+
environmentId: string;
|
|
1815
|
+
block: string;
|
|
1816
|
+
owner: string;
|
|
1817
|
+
/** Format: int64 */
|
|
1818
|
+
bytes: number;
|
|
1819
|
+
/** Format: int64 */
|
|
1820
|
+
epoch: number;
|
|
1821
|
+
};
|
|
1822
|
+
AdmissionState: {
|
|
1823
|
+
policy: components["schemas"]["AdmissionPolicy"];
|
|
1824
|
+
occupancy: components["schemas"]["AdmissionOccupancy"][];
|
|
1825
|
+
storageCredits: components["schemas"]["TenantStorageCredit"][];
|
|
1826
|
+
};
|
|
1827
|
+
AdmissionUsagePoint: {
|
|
1828
|
+
/** Format: date-time */
|
|
1829
|
+
hour: string;
|
|
1830
|
+
workload: string;
|
|
1831
|
+
outcome: string;
|
|
1832
|
+
/** Format: int64 */
|
|
1833
|
+
requests: number;
|
|
1834
|
+
/** Format: int64 */
|
|
1835
|
+
bytes: number;
|
|
1836
|
+
/** Format: int64 */
|
|
1837
|
+
elapsedMs: number;
|
|
1838
|
+
};
|
|
1839
|
+
AdmissionUsagePage: {
|
|
1840
|
+
points: components["schemas"]["AdmissionUsagePoint"][];
|
|
1841
|
+
/** Format: date-time */
|
|
1842
|
+
next?: string;
|
|
1843
|
+
};
|
|
1565
1844
|
};
|
|
1566
1845
|
responses: never;
|
|
1567
1846
|
parameters: never;
|
|
@@ -1576,6 +1855,8 @@ export interface operations {
|
|
|
1576
1855
|
query?: {
|
|
1577
1856
|
limit?: number;
|
|
1578
1857
|
cursor?: string;
|
|
1858
|
+
/** @description Case-insensitive literal substring over registered IDs and available names, applied before pagination. Cursors bind the search. */
|
|
1859
|
+
search?: string;
|
|
1579
1860
|
};
|
|
1580
1861
|
header?: never;
|
|
1581
1862
|
path: {
|
|
@@ -5494,6 +5775,8 @@ export interface operations {
|
|
|
5494
5775
|
query?: {
|
|
5495
5776
|
limit?: number;
|
|
5496
5777
|
cursor?: string;
|
|
5778
|
+
/** @description Case-insensitive literal substring over registered IDs and available names, applied before pagination. Cursors bind the search. */
|
|
5779
|
+
search?: string;
|
|
5497
5780
|
};
|
|
5498
5781
|
header?: never;
|
|
5499
5782
|
path: {
|
|
@@ -5565,6 +5848,8 @@ export interface operations {
|
|
|
5565
5848
|
query?: {
|
|
5566
5849
|
limit?: number;
|
|
5567
5850
|
cursor?: string;
|
|
5851
|
+
/** @description Case-insensitive literal substring over registered IDs and available names, applied before pagination. Cursors bind the search. */
|
|
5852
|
+
search?: string;
|
|
5568
5853
|
};
|
|
5569
5854
|
header?: never;
|
|
5570
5855
|
path?: never;
|
|
@@ -5633,6 +5918,8 @@ export interface operations {
|
|
|
5633
5918
|
query?: {
|
|
5634
5919
|
limit?: number;
|
|
5635
5920
|
cursor?: string;
|
|
5921
|
+
/** @description Case-insensitive literal substring over registered IDs and available names, applied before pagination. Cursors bind the search. */
|
|
5922
|
+
search?: string;
|
|
5636
5923
|
};
|
|
5637
5924
|
header?: never;
|
|
5638
5925
|
path: {
|
|
@@ -5703,6 +5990,8 @@ export interface operations {
|
|
|
5703
5990
|
query?: {
|
|
5704
5991
|
limit?: number;
|
|
5705
5992
|
cursor?: string;
|
|
5993
|
+
/** @description Case-insensitive literal substring over registered IDs and available names, applied before pagination. Cursors bind the search. */
|
|
5994
|
+
search?: string;
|
|
5706
5995
|
};
|
|
5707
5996
|
header?: never;
|
|
5708
5997
|
path: {
|
|
@@ -5774,6 +6063,8 @@ export interface operations {
|
|
|
5774
6063
|
query?: {
|
|
5775
6064
|
limit?: number;
|
|
5776
6065
|
cursor?: string;
|
|
6066
|
+
/** @description Case-insensitive literal substring over registered IDs and available names, applied before pagination. Cursors bind the search. */
|
|
6067
|
+
search?: string;
|
|
5777
6068
|
};
|
|
5778
6069
|
header?: never;
|
|
5779
6070
|
path: {
|
|
@@ -7104,4 +7395,398 @@ export interface operations {
|
|
|
7104
7395
|
};
|
|
7105
7396
|
};
|
|
7106
7397
|
};
|
|
7398
|
+
listOperatorResources: {
|
|
7399
|
+
parameters: {
|
|
7400
|
+
query?: {
|
|
7401
|
+
limit?: number;
|
|
7402
|
+
cursor?: string;
|
|
7403
|
+
/** @description Case-insensitive literal substring over registered IDs and available names, applied before pagination. Cursors bind the search. */
|
|
7404
|
+
search?: string;
|
|
7405
|
+
};
|
|
7406
|
+
header?: never;
|
|
7407
|
+
path: {
|
|
7408
|
+
productId: string;
|
|
7409
|
+
tenantId: string;
|
|
7410
|
+
};
|
|
7411
|
+
cookie?: never;
|
|
7412
|
+
};
|
|
7413
|
+
requestBody?: never;
|
|
7414
|
+
responses: {
|
|
7415
|
+
/** @description Authorized stable keyset page. Empty nextCursor marks the end. */
|
|
7416
|
+
200: {
|
|
7417
|
+
headers: {
|
|
7418
|
+
[name: string]: unknown;
|
|
7419
|
+
};
|
|
7420
|
+
content: {
|
|
7421
|
+
"application/json": components["schemas"]["ResourceSummaryPage"];
|
|
7422
|
+
};
|
|
7423
|
+
};
|
|
7424
|
+
/** @description Rejected request or unavailable dependency */
|
|
7425
|
+
400: {
|
|
7426
|
+
headers: {
|
|
7427
|
+
[name: string]: unknown;
|
|
7428
|
+
};
|
|
7429
|
+
content: {
|
|
7430
|
+
"application/json": components["schemas"]["Error"];
|
|
7431
|
+
};
|
|
7432
|
+
};
|
|
7433
|
+
/** @description Rejected request or unavailable dependency */
|
|
7434
|
+
401: {
|
|
7435
|
+
headers: {
|
|
7436
|
+
[name: string]: unknown;
|
|
7437
|
+
};
|
|
7438
|
+
content: {
|
|
7439
|
+
"application/json": components["schemas"]["Error"];
|
|
7440
|
+
};
|
|
7441
|
+
};
|
|
7442
|
+
/** @description Rejected request or unavailable dependency */
|
|
7443
|
+
403: {
|
|
7444
|
+
headers: {
|
|
7445
|
+
[name: string]: unknown;
|
|
7446
|
+
};
|
|
7447
|
+
content: {
|
|
7448
|
+
"application/json": components["schemas"]["Error"];
|
|
7449
|
+
};
|
|
7450
|
+
};
|
|
7451
|
+
/** @description Rejected request or unavailable dependency */
|
|
7452
|
+
404: {
|
|
7453
|
+
headers: {
|
|
7454
|
+
[name: string]: unknown;
|
|
7455
|
+
};
|
|
7456
|
+
content: {
|
|
7457
|
+
"application/json": components["schemas"]["Error"];
|
|
7458
|
+
};
|
|
7459
|
+
};
|
|
7460
|
+
/** @description Rejected request or unavailable dependency */
|
|
7461
|
+
503: {
|
|
7462
|
+
headers: {
|
|
7463
|
+
[name: string]: unknown;
|
|
7464
|
+
};
|
|
7465
|
+
content: {
|
|
7466
|
+
"application/json": components["schemas"]["Error"];
|
|
7467
|
+
};
|
|
7468
|
+
};
|
|
7469
|
+
};
|
|
7470
|
+
};
|
|
7471
|
+
listOperatorHostEnvironments: {
|
|
7472
|
+
parameters: {
|
|
7473
|
+
query: {
|
|
7474
|
+
limit?: number;
|
|
7475
|
+
cursor?: string;
|
|
7476
|
+
/** @description Case-insensitive literal substring over registered IDs and available names, applied before pagination. Cursors bind the search. */
|
|
7477
|
+
search?: string;
|
|
7478
|
+
/** @description Exact native provider identity, never a server name. */
|
|
7479
|
+
providerId: string;
|
|
7480
|
+
};
|
|
7481
|
+
header?: never;
|
|
7482
|
+
path?: never;
|
|
7483
|
+
cookie?: never;
|
|
7484
|
+
};
|
|
7485
|
+
requestBody?: never;
|
|
7486
|
+
responses: {
|
|
7487
|
+
/** @description Authorized stable keyset page. Empty nextCursor marks the end. */
|
|
7488
|
+
200: {
|
|
7489
|
+
headers: {
|
|
7490
|
+
[name: string]: unknown;
|
|
7491
|
+
};
|
|
7492
|
+
content: {
|
|
7493
|
+
"application/json": components["schemas"]["ResourceSummaryPage"];
|
|
7494
|
+
};
|
|
7495
|
+
};
|
|
7496
|
+
/** @description Rejected request or unavailable dependency */
|
|
7497
|
+
400: {
|
|
7498
|
+
headers: {
|
|
7499
|
+
[name: string]: unknown;
|
|
7500
|
+
};
|
|
7501
|
+
content: {
|
|
7502
|
+
"application/json": components["schemas"]["Error"];
|
|
7503
|
+
};
|
|
7504
|
+
};
|
|
7505
|
+
/** @description Rejected request or unavailable dependency */
|
|
7506
|
+
401: {
|
|
7507
|
+
headers: {
|
|
7508
|
+
[name: string]: unknown;
|
|
7509
|
+
};
|
|
7510
|
+
content: {
|
|
7511
|
+
"application/json": components["schemas"]["Error"];
|
|
7512
|
+
};
|
|
7513
|
+
};
|
|
7514
|
+
/** @description Rejected request or unavailable dependency */
|
|
7515
|
+
403: {
|
|
7516
|
+
headers: {
|
|
7517
|
+
[name: string]: unknown;
|
|
7518
|
+
};
|
|
7519
|
+
content: {
|
|
7520
|
+
"application/json": components["schemas"]["Error"];
|
|
7521
|
+
};
|
|
7522
|
+
};
|
|
7523
|
+
/** @description Rejected request or unavailable dependency */
|
|
7524
|
+
404: {
|
|
7525
|
+
headers: {
|
|
7526
|
+
[name: string]: unknown;
|
|
7527
|
+
};
|
|
7528
|
+
content: {
|
|
7529
|
+
"application/json": components["schemas"]["Error"];
|
|
7530
|
+
};
|
|
7531
|
+
};
|
|
7532
|
+
/** @description Rejected request or unavailable dependency */
|
|
7533
|
+
503: {
|
|
7534
|
+
headers: {
|
|
7535
|
+
[name: string]: unknown;
|
|
7536
|
+
};
|
|
7537
|
+
content: {
|
|
7538
|
+
"application/json": components["schemas"]["Error"];
|
|
7539
|
+
};
|
|
7540
|
+
};
|
|
7541
|
+
};
|
|
7542
|
+
};
|
|
7543
|
+
getOperatorResourceRelationships: {
|
|
7544
|
+
parameters: {
|
|
7545
|
+
query?: never;
|
|
7546
|
+
header?: never;
|
|
7547
|
+
path: {
|
|
7548
|
+
productId: string;
|
|
7549
|
+
tenantId: string;
|
|
7550
|
+
projectId: string;
|
|
7551
|
+
environmentId: string;
|
|
7552
|
+
};
|
|
7553
|
+
cookie?: never;
|
|
7554
|
+
};
|
|
7555
|
+
requestBody?: never;
|
|
7556
|
+
responses: {
|
|
7557
|
+
/** @description Authorized stable keyset page. Empty nextCursor marks the end. */
|
|
7558
|
+
200: {
|
|
7559
|
+
headers: {
|
|
7560
|
+
[name: string]: unknown;
|
|
7561
|
+
};
|
|
7562
|
+
content: {
|
|
7563
|
+
"application/json": components["schemas"]["ResourceRelationships"];
|
|
7564
|
+
};
|
|
7565
|
+
};
|
|
7566
|
+
/** @description Rejected request or unavailable dependency */
|
|
7567
|
+
400: {
|
|
7568
|
+
headers: {
|
|
7569
|
+
[name: string]: unknown;
|
|
7570
|
+
};
|
|
7571
|
+
content: {
|
|
7572
|
+
"application/json": components["schemas"]["Error"];
|
|
7573
|
+
};
|
|
7574
|
+
};
|
|
7575
|
+
/** @description Rejected request or unavailable dependency */
|
|
7576
|
+
401: {
|
|
7577
|
+
headers: {
|
|
7578
|
+
[name: string]: unknown;
|
|
7579
|
+
};
|
|
7580
|
+
content: {
|
|
7581
|
+
"application/json": components["schemas"]["Error"];
|
|
7582
|
+
};
|
|
7583
|
+
};
|
|
7584
|
+
/** @description Rejected request or unavailable dependency */
|
|
7585
|
+
403: {
|
|
7586
|
+
headers: {
|
|
7587
|
+
[name: string]: unknown;
|
|
7588
|
+
};
|
|
7589
|
+
content: {
|
|
7590
|
+
"application/json": components["schemas"]["Error"];
|
|
7591
|
+
};
|
|
7592
|
+
};
|
|
7593
|
+
/** @description Rejected request or unavailable dependency */
|
|
7594
|
+
404: {
|
|
7595
|
+
headers: {
|
|
7596
|
+
[name: string]: unknown;
|
|
7597
|
+
};
|
|
7598
|
+
content: {
|
|
7599
|
+
"application/json": components["schemas"]["Error"];
|
|
7600
|
+
};
|
|
7601
|
+
};
|
|
7602
|
+
/** @description Rejected request or unavailable dependency */
|
|
7603
|
+
503: {
|
|
7604
|
+
headers: {
|
|
7605
|
+
[name: string]: unknown;
|
|
7606
|
+
};
|
|
7607
|
+
content: {
|
|
7608
|
+
"application/json": components["schemas"]["Error"];
|
|
7609
|
+
};
|
|
7610
|
+
};
|
|
7611
|
+
};
|
|
7612
|
+
};
|
|
7613
|
+
getAdmissionState: {
|
|
7614
|
+
parameters: {
|
|
7615
|
+
query?: never;
|
|
7616
|
+
header?: never;
|
|
7617
|
+
path: {
|
|
7618
|
+
tenant: string;
|
|
7619
|
+
};
|
|
7620
|
+
cookie?: never;
|
|
7621
|
+
};
|
|
7622
|
+
requestBody?: never;
|
|
7623
|
+
responses: {
|
|
7624
|
+
/** @description Authorized tenant projection */
|
|
7625
|
+
200: {
|
|
7626
|
+
headers: {
|
|
7627
|
+
[name: string]: unknown;
|
|
7628
|
+
};
|
|
7629
|
+
content: {
|
|
7630
|
+
"application/json": components["schemas"]["AdmissionState"];
|
|
7631
|
+
};
|
|
7632
|
+
};
|
|
7633
|
+
/** @description Scoped API error */
|
|
7634
|
+
default: {
|
|
7635
|
+
headers: {
|
|
7636
|
+
[name: string]: unknown;
|
|
7637
|
+
};
|
|
7638
|
+
content: {
|
|
7639
|
+
"application/json": components["schemas"]["Error"];
|
|
7640
|
+
};
|
|
7641
|
+
};
|
|
7642
|
+
};
|
|
7643
|
+
};
|
|
7644
|
+
assignAdmissionPolicy: {
|
|
7645
|
+
parameters: {
|
|
7646
|
+
query?: never;
|
|
7647
|
+
header?: never;
|
|
7648
|
+
path: {
|
|
7649
|
+
tenant: string;
|
|
7650
|
+
};
|
|
7651
|
+
cookie?: never;
|
|
7652
|
+
};
|
|
7653
|
+
requestBody: {
|
|
7654
|
+
content: {
|
|
7655
|
+
"application/json": components["schemas"]["AssignAdmissionPolicy"];
|
|
7656
|
+
};
|
|
7657
|
+
};
|
|
7658
|
+
responses: {
|
|
7659
|
+
/** @description Authorized tenant projection */
|
|
7660
|
+
200: {
|
|
7661
|
+
headers: {
|
|
7662
|
+
[name: string]: unknown;
|
|
7663
|
+
};
|
|
7664
|
+
content: {
|
|
7665
|
+
"application/json": components["schemas"]["AdmissionPolicy"];
|
|
7666
|
+
};
|
|
7667
|
+
};
|
|
7668
|
+
/** @description Scoped API error */
|
|
7669
|
+
default: {
|
|
7670
|
+
headers: {
|
|
7671
|
+
[name: string]: unknown;
|
|
7672
|
+
};
|
|
7673
|
+
content: {
|
|
7674
|
+
"application/json": components["schemas"]["Error"];
|
|
7675
|
+
};
|
|
7676
|
+
};
|
|
7677
|
+
};
|
|
7678
|
+
};
|
|
7679
|
+
getAdmissionUsage: {
|
|
7680
|
+
parameters: {
|
|
7681
|
+
query: {
|
|
7682
|
+
project?: string;
|
|
7683
|
+
environment?: string;
|
|
7684
|
+
workload?: string;
|
|
7685
|
+
subject?: string;
|
|
7686
|
+
from: string;
|
|
7687
|
+
until: string;
|
|
7688
|
+
after?: string;
|
|
7689
|
+
limit: number;
|
|
7690
|
+
};
|
|
7691
|
+
header?: never;
|
|
7692
|
+
path: {
|
|
7693
|
+
tenant: string;
|
|
7694
|
+
};
|
|
7695
|
+
cookie?: never;
|
|
7696
|
+
};
|
|
7697
|
+
requestBody?: never;
|
|
7698
|
+
responses: {
|
|
7699
|
+
/** @description Authorized tenant projection */
|
|
7700
|
+
200: {
|
|
7701
|
+
headers: {
|
|
7702
|
+
[name: string]: unknown;
|
|
7703
|
+
};
|
|
7704
|
+
content: {
|
|
7705
|
+
"application/json": components["schemas"]["AdmissionUsagePage"];
|
|
7706
|
+
};
|
|
7707
|
+
};
|
|
7708
|
+
/** @description Scoped API error */
|
|
7709
|
+
default: {
|
|
7710
|
+
headers: {
|
|
7711
|
+
[name: string]: unknown;
|
|
7712
|
+
};
|
|
7713
|
+
content: {
|
|
7714
|
+
"application/json": components["schemas"]["Error"];
|
|
7715
|
+
};
|
|
7716
|
+
};
|
|
7717
|
+
};
|
|
7718
|
+
};
|
|
7719
|
+
operatorAdmission: {
|
|
7720
|
+
parameters: {
|
|
7721
|
+
query?: never;
|
|
7722
|
+
header?: never;
|
|
7723
|
+
path: {
|
|
7724
|
+
product: string;
|
|
7725
|
+
tenant: string;
|
|
7726
|
+
};
|
|
7727
|
+
cookie?: never;
|
|
7728
|
+
};
|
|
7729
|
+
requestBody?: never;
|
|
7730
|
+
responses: {
|
|
7731
|
+
/** @description Authorized tenant projection */
|
|
7732
|
+
200: {
|
|
7733
|
+
headers: {
|
|
7734
|
+
[name: string]: unknown;
|
|
7735
|
+
};
|
|
7736
|
+
content: {
|
|
7737
|
+
"application/json": components["schemas"]["AdmissionState"];
|
|
7738
|
+
};
|
|
7739
|
+
};
|
|
7740
|
+
/** @description Scoped API error */
|
|
7741
|
+
default: {
|
|
7742
|
+
headers: {
|
|
7743
|
+
[name: string]: unknown;
|
|
7744
|
+
};
|
|
7745
|
+
content: {
|
|
7746
|
+
"application/json": components["schemas"]["Error"];
|
|
7747
|
+
};
|
|
7748
|
+
};
|
|
7749
|
+
};
|
|
7750
|
+
};
|
|
7751
|
+
operatorUsage: {
|
|
7752
|
+
parameters: {
|
|
7753
|
+
query: {
|
|
7754
|
+
project?: string;
|
|
7755
|
+
environment?: string;
|
|
7756
|
+
workload?: string;
|
|
7757
|
+
subject?: string;
|
|
7758
|
+
from: string;
|
|
7759
|
+
until: string;
|
|
7760
|
+
after?: string;
|
|
7761
|
+
limit: number;
|
|
7762
|
+
};
|
|
7763
|
+
header?: never;
|
|
7764
|
+
path: {
|
|
7765
|
+
product: string;
|
|
7766
|
+
tenant: string;
|
|
7767
|
+
};
|
|
7768
|
+
cookie?: never;
|
|
7769
|
+
};
|
|
7770
|
+
requestBody?: never;
|
|
7771
|
+
responses: {
|
|
7772
|
+
/** @description Authorized tenant projection */
|
|
7773
|
+
200: {
|
|
7774
|
+
headers: {
|
|
7775
|
+
[name: string]: unknown;
|
|
7776
|
+
};
|
|
7777
|
+
content: {
|
|
7778
|
+
"application/json": components["schemas"]["AdmissionUsagePage"];
|
|
7779
|
+
};
|
|
7780
|
+
};
|
|
7781
|
+
/** @description Scoped API error */
|
|
7782
|
+
default: {
|
|
7783
|
+
headers: {
|
|
7784
|
+
[name: string]: unknown;
|
|
7785
|
+
};
|
|
7786
|
+
content: {
|
|
7787
|
+
"application/json": components["schemas"]["Error"];
|
|
7788
|
+
};
|
|
7789
|
+
};
|
|
7790
|
+
};
|
|
7791
|
+
};
|
|
7107
7792
|
}
|
package/package.json
CHANGED
package/release.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrogate/sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"sourceRevision": "
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"sourceRevision": "f5fdbfd8322cc353cddda48d89e35ee8b2c4c16a",
|
|
5
5
|
"cleanSource": true,
|
|
6
6
|
"sdkLockSHA256": "18c62b4e44914fefcd3a06c72121bac03545170d6a77d9d6333dfab276382990",
|
|
7
7
|
"nativeLockSHA256": "747051f0cdb1b0c493967c480c1bef111cde7661cdf66eb2d132803c11bd8d3a",
|