@intentius/chant-lexicon-azure 0.124.32 → 0.124.34
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/codegen/generate-typescript.js +1 -1
- package/dist/codegen/generate.js +1 -1
- package/dist/generated/index.d.ts.map +1 -1
- package/dist/generated/index.js +1 -1
- package/dist/health.d.ts +42 -0
- package/dist/health.d.ts.map +1 -0
- package/dist/health.js +137 -0
- package/dist/integrity.json +5 -5
- package/dist/lint/post-synth/arm-refs.d.ts +1 -0
- package/dist/lint/post-synth/arm-refs.d.ts.map +1 -1
- package/dist/lint/post-synth/arm-refs.js +5 -3
- package/dist/manifest.json +1 -1
- package/dist/meta.json +6 -1
- package/dist/okf/types/containerApps.md +5 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +6 -0
- package/dist/rules/arm-refs.ts +5 -3
- package/dist/serializer.d.ts +7 -0
- package/dist/serializer.d.ts.map +1 -1
- package/dist/serializer.js +115 -29
- package/dist/spec/parse.d.ts.map +1 -1
- package/dist/spec/parse.js +10 -0
- package/dist/types/index.d.ts +5 -0
- package/package.json +2 -2
- package/src/attributes.test.ts +17 -0
- package/src/codegen/generate-typescript.ts +1 -1
- package/src/codegen/generate.ts +1 -1
- package/src/generated/index.d.ts +5 -0
- package/src/generated/index.ts +1 -1
- package/src/generated/lexicon-azure.json +6 -1
- package/src/health.test.ts +66 -0
- package/src/health.ts +162 -0
- package/src/lint/post-synth/arm-refs.ts +5 -3
- package/src/lint/post-synth/post-synth.test.ts +1 -1
- package/src/plugin.ts +8 -0
- package/src/serializer-names.test.ts +83 -0
- package/src/serializer-outputs.test.ts +65 -0
- package/src/serializer.ts +110 -28
- package/src/spec/parse.test.ts +15 -0
- package/src/spec/parse.ts +10 -0
package/dist/generated/index.js
CHANGED
|
@@ -313,7 +313,7 @@ export const connections_flows = /* @__PURE__ */ createResource("Microsoft.Azure
|
|
|
313
313
|
export const connectors = /* @__PURE__ */ createResource("Microsoft.Workloads/connectors", "azure", { "id": "id" });
|
|
314
314
|
export const connectors_acssBackups = /* @__PURE__ */ createResource("Microsoft.Workloads/connectors_acssBackups", "azure", { "id": "id" });
|
|
315
315
|
export const Consumptionbudgets = /* @__PURE__ */ createResource("Microsoft.Consumption/budgets", "azure", { "id": "id" });
|
|
316
|
-
export const containerApps = /* @__PURE__ */ createResource("Microsoft.App/containerApps", "azure", { "id": "id" });
|
|
316
|
+
export const containerApps = /* @__PURE__ */ createResource("Microsoft.App/containerApps", "azure", { "id": "id", "configuration_ingress_fqdn": "configuration.ingress.fqdn", "latestRevisionFqdn": "latestRevisionFqdn", "latestRevisionName": "latestRevisionName", "outboundIpAddresses": "outboundIpAddresses", "provisioningState": "provisioningState" });
|
|
317
317
|
export const containerApps_authConfigs = /* @__PURE__ */ createResource("Microsoft.App/containerApps_authConfigs", "azure", { "id": "id" });
|
|
318
318
|
export const containerApps_resiliencyPolicies = /* @__PURE__ */ createResource("Microsoft.App/containerApps_resiliencyPolicies", "azure", { "id": "id" });
|
|
319
319
|
export const containerApps_sourcecontrols = /* @__PURE__ */ createResource("Microsoft.App/containerApps_sourcecontrols", "azure", { "id": "id" });
|
package/dist/health.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime health for Azure (#4177): Container Apps.
|
|
3
|
+
*
|
|
4
|
+
* For each declared `Microsoft.App/containerApps`, GET the app (a 404 is
|
|
5
|
+
* absent), then its revisions, and judge the active ones by their running and
|
|
6
|
+
* health state. Same transport and endpoint rule as `describe-resources.ts`, so
|
|
7
|
+
* `AZURE_ENDPOINT_URL` (floci-az) answers.
|
|
8
|
+
*
|
|
9
|
+
* When the revisions list cannot be read but the app carries a
|
|
10
|
+
* `runningStatus` (newer API versions do), that answers instead, and the detail
|
|
11
|
+
* says so.
|
|
12
|
+
*/
|
|
13
|
+
import type { HealthEntry, HealthReadOptions, HealthReadResult } from "@intentius/chant/lexicon";
|
|
14
|
+
import type { AzHttp } from "./op/activities/az-apply.js";
|
|
15
|
+
export declare const AZURE_HEALTH_TYPES: readonly ["Microsoft.App/containerApps"];
|
|
16
|
+
export interface AzureHealthOptions extends HealthReadOptions {
|
|
17
|
+
http?: AzHttp;
|
|
18
|
+
now?: () => Date;
|
|
19
|
+
}
|
|
20
|
+
/** The fields of one revision that decide health. */
|
|
21
|
+
export interface RevisionState {
|
|
22
|
+
name?: string;
|
|
23
|
+
properties?: {
|
|
24
|
+
active?: boolean;
|
|
25
|
+
runningState?: string;
|
|
26
|
+
healthState?: string;
|
|
27
|
+
replicas?: number;
|
|
28
|
+
trafficWeight?: number;
|
|
29
|
+
lastActiveTime?: string;
|
|
30
|
+
createdTime?: string;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The active revisions' verdict: unhealthy if none is active or any active one
|
|
35
|
+
* failed, degraded, stopped or reports `Unhealthy`; healthy if every active one
|
|
36
|
+
* is running and none is unhealthy; otherwise unknown (still provisioning).
|
|
37
|
+
*/
|
|
38
|
+
export declare function containerAppEntry(revisions: RevisionState[], observedAt: string): HealthEntry;
|
|
39
|
+
/** An app's own `runningStatus`, for when its revisions cannot be listed. */
|
|
40
|
+
export declare function appRunningStatusEntry(runningStatus: string, observedAt: string): HealthEntry;
|
|
41
|
+
export declare function observeHealthAzure(options: AzureHealthOptions): Promise<HealthReadResult>;
|
|
42
|
+
//# sourceMappingURL=health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,gBAAgB,EAAoB,MAAM,0BAA0B,CAAC;AAGnH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAEvD,eAAO,MAAM,kBAAkB,YAAI,6BAA6B,CAAU,CAAC;AAK3E,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,qDAAqD;AACrD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE;QACX,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAKD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,aAAa,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAyB7F;AAED,6EAA6E;AAC7E,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAS5F;AAiCD,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAyC/F"}
|
package/dist/health.js
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime health for Azure (#4177): Container Apps.
|
|
3
|
+
*
|
|
4
|
+
* For each declared `Microsoft.App/containerApps`, GET the app (a 404 is
|
|
5
|
+
* absent), then its revisions, and judge the active ones by their running and
|
|
6
|
+
* health state. Same transport and endpoint rule as `describe-resources.ts`, so
|
|
7
|
+
* `AZURE_ENDPOINT_URL` (floci-az) answers.
|
|
8
|
+
*
|
|
9
|
+
* When the revisions list cannot be read but the app carries a
|
|
10
|
+
* `runningStatus` (newer API versions do), that answers instead, and the detail
|
|
11
|
+
* says so.
|
|
12
|
+
*/
|
|
13
|
+
import { armResourceReadUrl, AzureReadError, getResource, isNotFound } from "./api/read-client.js";
|
|
14
|
+
import { classifyArmFailure } from "./describe-resources.js";
|
|
15
|
+
export const AZURE_HEALTH_TYPES = ["Microsoft.App/containerApps"];
|
|
16
|
+
/** The Container Apps API version whose revisions carry `runningState` and `healthState`. */
|
|
17
|
+
const CONTAINER_APPS_API_VERSION = "2024-03-01";
|
|
18
|
+
const RUNNING = new Set(["running", "runningatmaxscale"]);
|
|
19
|
+
const DOWN = new Set(["failed", "degraded", "stopped"]);
|
|
20
|
+
/**
|
|
21
|
+
* The active revisions' verdict: unhealthy if none is active or any active one
|
|
22
|
+
* failed, degraded, stopped or reports `Unhealthy`; healthy if every active one
|
|
23
|
+
* is running and none is unhealthy; otherwise unknown (still provisioning).
|
|
24
|
+
*/
|
|
25
|
+
export function containerAppEntry(revisions, observedAt) {
|
|
26
|
+
const type = "Microsoft.App/containerApps";
|
|
27
|
+
const active = revisions.filter((r) => r.properties?.active === true);
|
|
28
|
+
if (active.length === 0) {
|
|
29
|
+
return { type, state: "unhealthy", detail: `no active revision (${revisions.length} revision(s))`, observedAt };
|
|
30
|
+
}
|
|
31
|
+
const describe = (r) => {
|
|
32
|
+
const p = r.properties ?? {};
|
|
33
|
+
const bits = [p.runningState ?? "no running state"];
|
|
34
|
+
if (p.healthState && p.healthState !== "None")
|
|
35
|
+
bits.push(p.healthState);
|
|
36
|
+
if (typeof p.replicas === "number")
|
|
37
|
+
bits.push(`${p.replicas} replica(s)`);
|
|
38
|
+
if (typeof p.trafficWeight === "number")
|
|
39
|
+
bits.push(`${p.trafficWeight}% traffic`);
|
|
40
|
+
return `${r.name ?? "revision"} ${bits.join(", ")}`;
|
|
41
|
+
};
|
|
42
|
+
const detail = active.map(describe).join("; ");
|
|
43
|
+
const running = (r) => RUNNING.has((r.properties?.runningState ?? "").toLowerCase());
|
|
44
|
+
const down = (r) => DOWN.has((r.properties?.runningState ?? "").toLowerCase()) || r.properties?.healthState?.toLowerCase() === "unhealthy";
|
|
45
|
+
const checkedAt = active
|
|
46
|
+
.map((r) => r.properties?.lastActiveTime ?? r.properties?.createdTime)
|
|
47
|
+
.filter((t) => typeof t === "string")
|
|
48
|
+
.sort()
|
|
49
|
+
.pop();
|
|
50
|
+
const state = active.some(down) ? "unhealthy" : active.every(running) ? "healthy" : "unknown";
|
|
51
|
+
return { type, state, detail, observedAt, ...(checkedAt ? { checkedAt } : {}) };
|
|
52
|
+
}
|
|
53
|
+
/** An app's own `runningStatus`, for when its revisions cannot be listed. */
|
|
54
|
+
export function appRunningStatusEntry(runningStatus, observedAt) {
|
|
55
|
+
const lower = runningStatus.toLowerCase();
|
|
56
|
+
const state = RUNNING.has(lower) ? "healthy" : DOWN.has(lower) ? "unhealthy" : "unknown";
|
|
57
|
+
return {
|
|
58
|
+
type: "Microsoft.App/containerApps",
|
|
59
|
+
state,
|
|
60
|
+
detail: `app runningStatus ${runningStatus} (revisions not readable)`,
|
|
61
|
+
observedAt,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function hole(err) {
|
|
65
|
+
const { reason, detail } = classifyArmFailure(err);
|
|
66
|
+
return { type: "Microsoft.App/containerApps", reason, detail };
|
|
67
|
+
}
|
|
68
|
+
async function listRevisions(client, name) {
|
|
69
|
+
const http = client.http;
|
|
70
|
+
const url = armResourceReadUrl(client, "Microsoft.App/containerApps", `${name}/revisions`, CONTAINER_APPS_API_VERSION);
|
|
71
|
+
const res = await http("GET", url, undefined, client.signal);
|
|
72
|
+
if (res.status >= 300)
|
|
73
|
+
throw new AzureReadError(`revisions read failed with HTTP ${res.status}`, res.status);
|
|
74
|
+
let body;
|
|
75
|
+
try {
|
|
76
|
+
body = JSON.parse(res.text);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
throw new AzureReadError("unparseable revisions list", res.status);
|
|
80
|
+
}
|
|
81
|
+
const value = body && typeof body === "object" ? body.value : undefined;
|
|
82
|
+
if (!Array.isArray(value))
|
|
83
|
+
throw new AzureReadError("unparseable revisions list", res.status);
|
|
84
|
+
return value;
|
|
85
|
+
}
|
|
86
|
+
const defaultHttp = async (method, url, body, signal) => {
|
|
87
|
+
const res = await fetch(url, {
|
|
88
|
+
method,
|
|
89
|
+
headers: body === undefined ? undefined : { "content-type": "application/json" },
|
|
90
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
91
|
+
signal,
|
|
92
|
+
});
|
|
93
|
+
return { status: res.status, text: await res.text() };
|
|
94
|
+
};
|
|
95
|
+
export async function observeHealthAzure(options) {
|
|
96
|
+
const observedAt = (options.now?.() ?? new Date()).toISOString();
|
|
97
|
+
const client = {
|
|
98
|
+
resourceGroup: options.environment,
|
|
99
|
+
...(process.env.AZURE_ENDPOINT_URL ? { endpoint: process.env.AZURE_ENDPOINT_URL } : {}),
|
|
100
|
+
...(process.env.AZURE_SUBSCRIPTION_ID ? { subscriptionId: process.env.AZURE_SUBSCRIPTION_ID } : {}),
|
|
101
|
+
http: options.http ?? defaultHttp,
|
|
102
|
+
};
|
|
103
|
+
const entities = {};
|
|
104
|
+
const unobserved = {};
|
|
105
|
+
const absent = [];
|
|
106
|
+
await Promise.all([...options.entities].map(async ([entityName, { entityType, props }]) => {
|
|
107
|
+
const name = props.name;
|
|
108
|
+
if (!name) {
|
|
109
|
+
unobserved[entityName] = { type: entityType, reason: "read-failed", detail: "declared entity has no name to query by" };
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
let app;
|
|
113
|
+
try {
|
|
114
|
+
app = await getResource(client, entityType, name, CONTAINER_APPS_API_VERSION);
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
if (isNotFound(err))
|
|
118
|
+
absent.push(entityName);
|
|
119
|
+
else
|
|
120
|
+
unobserved[entityName] = hole(err);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
entities[entityName] = containerAppEntry(await listRevisions(client, name), observedAt);
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
const runningStatus = app.properties?.runningStatus;
|
|
128
|
+
if (typeof runningStatus === "string" && runningStatus.length > 0) {
|
|
129
|
+
entities[entityName] = appRunningStatusEntry(runningStatus, observedAt);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
unobserved[entityName] = hole(err);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}));
|
|
136
|
+
return { entities, unobserved, absent };
|
|
137
|
+
}
|
package/dist/integrity.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
5
|
-
"meta.json": "
|
|
6
|
-
"types/index.d.ts": "
|
|
4
|
+
"manifest.json": "b7cb2339ce19b5990cef0993cd7beddc1d038585d6578f379d7a7eadb5f868a7",
|
|
5
|
+
"meta.json": "d2521221ed616d882ded4296f0071685bd74e4b645d55dabc9685733c37dc419",
|
|
6
|
+
"types/index.d.ts": "29631032bda9533849178968290e65d72250eab0b8bab424f2d9ef9b4e8546a4",
|
|
7
7
|
"rules/hardcoded-location.ts": "0b895449c8c94066e81721c46be24249231029fe13b471477456df5c4e45b8bf",
|
|
8
8
|
"rules/nsg-wildcard.ts": "8f9d44833ba364778c05731f84c20f00734bb0d40d9fd0d91645965d18a258ae",
|
|
9
9
|
"rules/storage-https.ts": "d340ba970bd9b35304bd7d288a9e99610a7677e6c56af4846305a98d4df0fbbc",
|
|
10
|
-
"rules/arm-refs.ts": "
|
|
10
|
+
"rules/arm-refs.ts": "1ff54e29511d5b0572586d64d7c5ca476a13f401f14f89b4d601b01aa6dde891",
|
|
11
11
|
"rules/azr010.ts": "c61da411a3b325d49f2f790030f11aa4d518a671a23ff3d13be5206e2ddfedab",
|
|
12
12
|
"rules/azr011.ts": "81b05ecaaf6e90a8afc692cd203d28eddf6126a3d7d9d4d4955e4aa6f2c7fa4c",
|
|
13
13
|
"rules/azr012.ts": "e59ddbab64c0bddd2d65bd5cb66e976f858d86216825a18837653d14224a321e",
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
"skills/chant-azure-patterns.md": "1a3bacfac612826b77332d2692a59195638db9f1b5e8ea2eda7579621d25f603",
|
|
38
38
|
"skills/chant-azure-aks.md": "2d4e0098c1a22b54ffadd410564d9df0f3a04cb4eb7c6261f20ae33106e7aca8"
|
|
39
39
|
},
|
|
40
|
-
"composite": "
|
|
40
|
+
"composite": "039009b3a310fec3985cbd427c59397fa4b2cd76797302c53c1a7d1e1d8e1e77"
|
|
41
41
|
}
|
|
@@ -55,6 +55,7 @@ export declare function isBracketExpression(value: unknown): boolean;
|
|
|
55
55
|
*
|
|
56
56
|
* Handles:
|
|
57
57
|
* - [resourceId('Type', 'name')] -> extracts 'name'
|
|
58
|
+
* - [resourceId('Type', 'a', 'b')] -> extracts 'a/b'
|
|
58
59
|
* - [reference('name')] -> extracts 'name'
|
|
59
60
|
* - [reference('name').prop] -> extracts 'name'
|
|
60
61
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"arm-refs.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/arm-refs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,GAAG,IAAI,CAWzF;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAI/D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE3D;AAED
|
|
1
|
+
{"version":3,"file":"arm-refs.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/arm-refs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,GAAG,IAAI,CAWzF;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAI/D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAkBhE"}
|
|
@@ -50,16 +50,18 @@ export function isBracketExpression(value) {
|
|
|
50
50
|
*
|
|
51
51
|
* Handles:
|
|
52
52
|
* - [resourceId('Type', 'name')] -> extracts 'name'
|
|
53
|
+
* - [resourceId('Type', 'a', 'b')] -> extracts 'a/b'
|
|
53
54
|
* - [reference('name')] -> extracts 'name'
|
|
54
55
|
* - [reference('name').prop] -> extracts 'name'
|
|
55
56
|
*/
|
|
56
57
|
export function extractRefsFromExpression(expr) {
|
|
57
58
|
const refs = [];
|
|
58
|
-
// Match resourceId('
|
|
59
|
-
|
|
59
|
+
// Match resourceId('Type', 'name', ...): the name is every quoted argument
|
|
60
|
+
// after the type, joined with "/" for a child resource ('vnet', 'subnet').
|
|
61
|
+
const resourceIdPattern = /resourceId\s*\(\s*'[^']+'((?:\s*,\s*'[^']+')+)\s*\)/g;
|
|
60
62
|
let match;
|
|
61
63
|
while ((match = resourceIdPattern.exec(expr)) !== null) {
|
|
62
|
-
refs.push(match[1]);
|
|
64
|
+
refs.push([...match[1].matchAll(/'([^']+)'/g)].map((m) => m[1]).join("/"));
|
|
63
65
|
}
|
|
64
66
|
// Match reference('name') — extract the name
|
|
65
67
|
const referencePattern = /reference\s*\(\s*'([^']+)'\s*\)/g;
|
package/dist/manifest.json
CHANGED
package/dist/meta.json
CHANGED
|
@@ -33235,7 +33235,12 @@
|
|
|
33235
33235
|
"lexicon": "azure",
|
|
33236
33236
|
"apiVersion": "2025-02-02-preview",
|
|
33237
33237
|
"attrs": {
|
|
33238
|
-
"id": "id"
|
|
33238
|
+
"id": "id",
|
|
33239
|
+
"configuration_ingress_fqdn": "configuration.ingress.fqdn",
|
|
33240
|
+
"latestRevisionFqdn": "latestRevisionFqdn",
|
|
33241
|
+
"latestRevisionName": "latestRevisionName",
|
|
33242
|
+
"outboundIpAddresses": "outboundIpAddresses",
|
|
33243
|
+
"provisioningState": "provisioningState"
|
|
33239
33244
|
},
|
|
33240
33245
|
"propertyConstraints": {
|
|
33241
33246
|
"kind": {
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,0BAA0B,CAAC;AA0B5E;;;;;GAKG;AACH,eAAO,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,0BAA0B,CAAC;AA0B5E;;;;;GAKG;AACH,eAAO,MAAM,WAAW,EAAE,aA4dzB,CAAC"}
|
package/dist/plugin.js
CHANGED
|
@@ -457,6 +457,12 @@ export const tags = defaultTags([
|
|
|
457
457
|
},
|
|
458
458
|
/** The noise rules the deep pass applies to both the live and declared trees. */
|
|
459
459
|
deepNormalizationHooks: azureDeepNormalizationHooks,
|
|
460
|
+
/** Runtime health (#4177): Container Apps. Implementation in ./health.ts. */
|
|
461
|
+
healthTypes: ["Microsoft.App/containerApps"],
|
|
462
|
+
async observeHealth(options) {
|
|
463
|
+
const { observeHealthAzure } = await import("./health.js");
|
|
464
|
+
return observeHealthAzure(options);
|
|
465
|
+
},
|
|
460
466
|
async exportResources(options) {
|
|
461
467
|
const { exportResources } = await import("./export-resources.js");
|
|
462
468
|
return exportResources(options);
|
package/dist/rules/arm-refs.ts
CHANGED
|
@@ -76,17 +76,19 @@ export function isBracketExpression(value: unknown): boolean {
|
|
|
76
76
|
*
|
|
77
77
|
* Handles:
|
|
78
78
|
* - [resourceId('Type', 'name')] -> extracts 'name'
|
|
79
|
+
* - [resourceId('Type', 'a', 'b')] -> extracts 'a/b'
|
|
79
80
|
* - [reference('name')] -> extracts 'name'
|
|
80
81
|
* - [reference('name').prop] -> extracts 'name'
|
|
81
82
|
*/
|
|
82
83
|
export function extractRefsFromExpression(expr: string): string[] {
|
|
83
84
|
const refs: string[] = [];
|
|
84
85
|
|
|
85
|
-
// Match resourceId('
|
|
86
|
-
|
|
86
|
+
// Match resourceId('Type', 'name', ...): the name is every quoted argument
|
|
87
|
+
// after the type, joined with "/" for a child resource ('vnet', 'subnet').
|
|
88
|
+
const resourceIdPattern = /resourceId\s*\(\s*'[^']+'((?:\s*,\s*'[^']+')+)\s*\)/g;
|
|
87
89
|
let match: RegExpExecArray | null;
|
|
88
90
|
while ((match = resourceIdPattern.exec(expr)) !== null) {
|
|
89
|
-
refs.push(match[1]);
|
|
91
|
+
refs.push([...match[1].matchAll(/'([^']+)'/g)].map((m) => m[1]).join("/"));
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
// Match reference('name') — extract the name
|
package/dist/serializer.d.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* - ARM bracket expression references
|
|
10
10
|
* - parameters, outputs sections
|
|
11
11
|
*/
|
|
12
|
+
import type { Declarable } from "@intentius/chant/declarable";
|
|
12
13
|
import type { Serializer } from "@intentius/chant/serializer";
|
|
13
14
|
export declare function apiVersionRegistryCandidates(dir?: string): string[];
|
|
14
15
|
export declare function loadApiVersions(candidates?: string[]): Map<string, string>;
|
|
@@ -24,6 +25,12 @@ export declare function resetApiVersionCache(): void;
|
|
|
24
25
|
*/
|
|
25
26
|
export declare function lookupApiVersion(resourceType: string): string | undefined;
|
|
26
27
|
export declare function getApiVersion(resourceType: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* An attribute of an export. `id` is `resourceId()`, since `reference()`
|
|
30
|
+
* returns the resource's properties and they have no `id`; anything else
|
|
31
|
+
* reads `reference()` by the ARM name.
|
|
32
|
+
*/
|
|
33
|
+
export declare function armAttrExpression(entityNames: Map<Declarable, string>, name: string, attr: string): string;
|
|
27
34
|
/**
|
|
28
35
|
* Azure ARM template serializer implementation.
|
|
29
36
|
*/
|
package/dist/serializer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,6BAA6B,CAAC;AAE7E,OAAO,KAAK,EAAE,UAAU,EAAsC,MAAM,6BAA6B,CAAC;AA8ElG,wBAAgB,4BAA4B,CAAC,GAAG,GAAE,MAAqB,GAAG,MAAM,EAAE,CAKjF;AAED,wBAAgB,eAAe,CAAC,UAAU,GAAE,MAAM,EAAmC,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAwB1G;AAcD,yEAAyE;AACzE,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAWzE;AAED,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAO1D;AA6BD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAK1G;AAiWD;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,UA+C7B,CAAC"}
|
package/dist/serializer.js
CHANGED
|
@@ -121,20 +121,50 @@ export function getApiVersion(resourceType) {
|
|
|
121
121
|
console.warn(`azure: no pinned apiVersion for ${resourceType} in the lexicon registry; falling back to 2023-01-01`);
|
|
122
122
|
return "2023-01-01";
|
|
123
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* The ARM name of a chant export, as the arguments an ARM function takes
|
|
126
|
+
* (#4183). A resource's `name` prop is its ARM name, and the export name is
|
|
127
|
+
* used only when it has none. A literal name is quoted, one argument per
|
|
128
|
+
* segment of a child's `parent/child` name; a bracket expression such as
|
|
129
|
+
* `[parameters('n')]` is passed unwrapped.
|
|
130
|
+
*/
|
|
131
|
+
function armNameArgs(entity, exportName) {
|
|
132
|
+
const props = entity && isResourceDeclarable(entity) && typeof entity.props === "object" && entity.props !== null
|
|
133
|
+
? entity.props
|
|
134
|
+
: undefined;
|
|
135
|
+
const name = typeof props?.name === "string" ? props.name : exportName;
|
|
136
|
+
if (name.startsWith("[") && name.endsWith("]"))
|
|
137
|
+
return { args: name.slice(1, -1), literal: null };
|
|
138
|
+
return { args: name.split("/").map((seg) => `'${seg}'`).join(", "), literal: name };
|
|
139
|
+
}
|
|
140
|
+
function entityNamed(entityNames, name) {
|
|
141
|
+
return [...entityNames.entries()].find(([, n]) => n === name)?.[0];
|
|
142
|
+
}
|
|
143
|
+
/** `resourceId(...)` for an export: the type and its ARM name. */
|
|
144
|
+
function armResourceId(entityNames, name) {
|
|
145
|
+
const entity = entityNamed(entityNames, name);
|
|
146
|
+
const { args } = armNameArgs(entity, name);
|
|
147
|
+
return entity ? `resourceId('${entity.entityType}', ${args})` : `resourceId(${args})`;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* An attribute of an export. `id` is `resourceId()`, since `reference()`
|
|
151
|
+
* returns the resource's properties and they have no `id`; anything else
|
|
152
|
+
* reads `reference()` by the ARM name.
|
|
153
|
+
*/
|
|
154
|
+
export function armAttrExpression(entityNames, name, attr) {
|
|
155
|
+
if (attr === "id")
|
|
156
|
+
return `[${armResourceId(entityNames, name)}]`;
|
|
157
|
+
const { args, literal } = armNameArgs(entityNamed(entityNames, name), name);
|
|
158
|
+
const target = literal !== null && !literal.includes("/") ? args : armResourceId(entityNames, name);
|
|
159
|
+
return `[reference(${target}).${attr}]`;
|
|
160
|
+
}
|
|
124
161
|
/**
|
|
125
162
|
* ARM-specific visitor for the generic serializer walker.
|
|
126
163
|
*/
|
|
127
164
|
function armVisitor(entityNames) {
|
|
128
165
|
return {
|
|
129
|
-
attrRef: (name, attr) =>
|
|
130
|
-
resourceRef: (name) => {
|
|
131
|
-
// Look up the resource type from entityNames
|
|
132
|
-
const entity = [...entityNames.entries()].find(([, n]) => n === name)?.[0];
|
|
133
|
-
if (entity) {
|
|
134
|
-
return `[resourceId('${entity.entityType}', '${name}')]`;
|
|
135
|
-
}
|
|
136
|
-
return `[resourceId('${name}')]`;
|
|
137
|
-
},
|
|
166
|
+
attrRef: (name, attr) => armAttrExpression(entityNames, name, attr),
|
|
167
|
+
resourceRef: (name) => `[${armResourceId(entityNames, name)}]`,
|
|
138
168
|
propertyDeclarable: (entity, walk) => {
|
|
139
169
|
if (!isResourceDeclarable(entity) || typeof entity.props !== "object" || entity.props === null) {
|
|
140
170
|
return undefined;
|
|
@@ -153,13 +183,38 @@ function armVisitor(entityNames) {
|
|
|
153
183
|
/**
|
|
154
184
|
* Convert a value to ARM-compatible JSON using the generic walker.
|
|
155
185
|
*/
|
|
186
|
+
/** An ARM output for a literal, or for an azure intrinsic's `[...]` expression. */
|
|
187
|
+
function armOutputValue(value) {
|
|
188
|
+
if (typeof value === "string")
|
|
189
|
+
return { type: "string", value };
|
|
190
|
+
if (typeof value === "number" && Number.isInteger(value))
|
|
191
|
+
return { type: "int", value };
|
|
192
|
+
if (typeof value === "boolean")
|
|
193
|
+
return { type: "bool", value };
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
function isIntrinsicLike(value) {
|
|
197
|
+
return typeof value === "object" && value !== null && typeof value.toJSON === "function";
|
|
198
|
+
}
|
|
199
|
+
function isCloudFormationShaped(value) {
|
|
200
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
201
|
+
return false;
|
|
202
|
+
const keys = Object.keys(value);
|
|
203
|
+
return keys.length === 1 && (keys[0] === "Ref" || keys[0].startsWith("Fn::"));
|
|
204
|
+
}
|
|
205
|
+
function isPlainObject(value) {
|
|
206
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
207
|
+
return false;
|
|
208
|
+
const proto = Object.getPrototypeOf(value);
|
|
209
|
+
return proto === Object.prototype || proto === null;
|
|
210
|
+
}
|
|
156
211
|
function toArmValue(value, entityNames) {
|
|
157
212
|
return walkValue(value, entityNames, armVisitor(entityNames));
|
|
158
213
|
}
|
|
159
214
|
/**
|
|
160
215
|
* Serialize entities into an ARM template object.
|
|
161
216
|
*/
|
|
162
|
-
function serializeToTemplate(entities, outputs, ownership) {
|
|
217
|
+
function serializeToTemplate(entities, outputs, ownership, warnings = []) {
|
|
163
218
|
// Resolve the deployment scope from the resource types being emitted
|
|
164
219
|
// (#1545): a template of tenant-only resources (management groups, policy
|
|
165
220
|
// definitions at management-group scope, ...) must carry the matching
|
|
@@ -270,6 +325,14 @@ function serializeToTemplate(entities, outputs, ownership) {
|
|
|
270
325
|
else if (key === "name") {
|
|
271
326
|
resource.name = toArmValue(value, entityNames);
|
|
272
327
|
}
|
|
328
|
+
else if (key === "properties" && isPlainObject(value)) {
|
|
329
|
+
// The generated types take ARM's own `properties` object, so
|
|
330
|
+
// merge it, not nest it (#4183).
|
|
331
|
+
for (const [inner, innerValue] of Object.entries(value)) {
|
|
332
|
+
if (innerValue !== undefined)
|
|
333
|
+
armProperties[inner] = toArmValue(innerValue, entityNames);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
273
336
|
else {
|
|
274
337
|
armProperties[key] = toArmValue(value, entityNames);
|
|
275
338
|
}
|
|
@@ -292,14 +355,7 @@ function serializeToTemplate(entities, outputs, ownership) {
|
|
|
292
355
|
if (attrs?.DependsOn !== undefined) {
|
|
293
356
|
const resolved = resolveDependsOn(attrs.DependsOn, entityNames, name);
|
|
294
357
|
if (resolved.length > 0) {
|
|
295
|
-
resource.dependsOn = resolved.map((dep) => {
|
|
296
|
-
// Convert to resourceId expression
|
|
297
|
-
const depEntity = [...entityNames.entries()].find(([, n]) => n === dep)?.[0];
|
|
298
|
-
if (depEntity) {
|
|
299
|
-
return `[resourceId('${depEntity.entityType}', '${dep}')]`;
|
|
300
|
-
}
|
|
301
|
-
return dep;
|
|
302
|
-
});
|
|
358
|
+
resource.dependsOn = resolved.map((dep) => entityNamed(entityNames, dep) ? `[${armResourceId(entityNames, dep)}]` : dep);
|
|
303
359
|
}
|
|
304
360
|
}
|
|
305
361
|
template.resources.push(resource);
|
|
@@ -358,7 +414,7 @@ function serializeToTemplate(entities, outputs, ownership) {
|
|
|
358
414
|
// Find the resource to build the resourceId expression
|
|
359
415
|
const depResource = template.resources.find((r) => r.name === refName);
|
|
360
416
|
if (depResource) {
|
|
361
|
-
const depExpr = `[resourceId('${depResource.type}', '${
|
|
417
|
+
const depExpr = `[resourceId('${depResource.type}', ${refName.split("/").map((seg) => `'${seg}'`).join(", ")})]`;
|
|
362
418
|
if (!existing.has(depExpr)) {
|
|
363
419
|
existing.add(depExpr);
|
|
364
420
|
}
|
|
@@ -376,29 +432,54 @@ function serializeToTemplate(entities, outputs, ownership) {
|
|
|
376
432
|
template.outputs = {};
|
|
377
433
|
const stackOutput = entity;
|
|
378
434
|
// `unknown` so isAttrRefLike narrows cleanly across the workspace/published
|
|
379
|
-
// type boundary.
|
|
380
|
-
// reference form, so skip it here (only aws/CFN emits those).
|
|
435
|
+
// type boundary.
|
|
381
436
|
const ref = stackOutput.sourceRef;
|
|
382
437
|
if (isAttrRefLike(ref)) {
|
|
383
438
|
const logicalName = ref.getLogicalName();
|
|
384
439
|
if (logicalName) {
|
|
385
440
|
template.outputs[name] = {
|
|
386
441
|
type: "string",
|
|
387
|
-
value:
|
|
442
|
+
value: armAttrExpression(entityNames, logicalName, ref.attribute),
|
|
388
443
|
};
|
|
389
444
|
}
|
|
390
445
|
}
|
|
446
|
+
else {
|
|
447
|
+
const value = armOutputValue(isIntrinsicLike(ref) ? ref.toJSON() : ref);
|
|
448
|
+
if (value)
|
|
449
|
+
template.outputs[name] = value;
|
|
450
|
+
else
|
|
451
|
+
warnings.push(`azure: stack output "${name}" is not written: its value has no ARM form.`);
|
|
452
|
+
}
|
|
391
453
|
}
|
|
392
454
|
}
|
|
393
455
|
// Add LexiconOutputs
|
|
394
456
|
if (outputs && outputs.length > 0) {
|
|
395
457
|
template.outputs = template.outputs ?? {};
|
|
396
458
|
for (const output of outputs) {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
459
|
+
if (output.sourceAttribute !== null) {
|
|
460
|
+
if (output.sourceEntity) {
|
|
461
|
+
template.outputs[output.outputName] = {
|
|
462
|
+
type: "string",
|
|
463
|
+
value: armAttrExpression(entityNames, output.sourceEntity, output.sourceAttribute),
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
else {
|
|
467
|
+
warnings.push(`azure: output "${output.outputName}" is not written: its resource has no name in this build.`);
|
|
468
|
+
}
|
|
469
|
+
continue;
|
|
470
|
+
}
|
|
471
|
+
// A literal or an intrinsic (#4181). It has no source lexicon, so every
|
|
472
|
+
// lexicon receives it; a CloudFormation-shaped value is aws's to write.
|
|
473
|
+
const raw = output.getOutputValue();
|
|
474
|
+
const value = armOutputValue(raw);
|
|
475
|
+
if (value)
|
|
476
|
+
template.outputs[output.outputName] = value;
|
|
477
|
+
else if (!isCloudFormationShaped(raw)) {
|
|
478
|
+
warnings.push(`azure: output "${output.outputName}" is not written: its value has no ARM form.`);
|
|
479
|
+
}
|
|
401
480
|
}
|
|
481
|
+
if (Object.keys(template.outputs).length === 0)
|
|
482
|
+
delete template.outputs;
|
|
402
483
|
}
|
|
403
484
|
return template;
|
|
404
485
|
}
|
|
@@ -447,11 +528,16 @@ export const azureSerializer = {
|
|
|
447
528
|
}
|
|
448
529
|
}
|
|
449
530
|
}
|
|
450
|
-
const
|
|
531
|
+
const warnings = [];
|
|
532
|
+
const template = serializeToTemplate(entities, outputs, context?.ownership, warnings);
|
|
451
533
|
const primary = JSON.stringify(template, null, 2);
|
|
452
|
-
if (!hasChildProjects) {
|
|
534
|
+
if (!hasChildProjects && warnings.length === 0) {
|
|
453
535
|
return primary;
|
|
454
536
|
}
|
|
455
|
-
return {
|
|
537
|
+
return {
|
|
538
|
+
primary,
|
|
539
|
+
...(hasChildProjects ? { files: allFiles } : {}),
|
|
540
|
+
...(warnings.length > 0 ? { warnings } : {}),
|
|
541
|
+
};
|
|
456
542
|
},
|
|
457
543
|
};
|
package/dist/spec/parse.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/spec/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAiE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC1G,OAAO,EAGL,kBAAkB,IAAI,sBAAsB,EAE5C,KAAK,mBAAmB,EAIzB,MAAM,sCAAsC,CAAC;AAI9C,YAAY,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAEhF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,mBAAmB,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,cAAc,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,OAAO,CAAC,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,YAAY,EAAE,OAAO,CAAA;KAAE,CAAC;IAC7E;;;;OAIG;IACH,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,cAAc,CAAC;IACzB,aAAa,EAAE,kBAAkB,EAAE,CAAC;IACpC,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/spec/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAiE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC1G,OAAO,EAGL,kBAAkB,IAAI,sBAAsB,EAE5C,KAAK,mBAAmB,EAIzB,MAAM,sCAAsC,CAAC;AAI9C,YAAY,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAEhF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,mBAAmB,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,cAAc,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,OAAO,CAAC,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,YAAY,EAAE,OAAO,CAAA;KAAE,CAAC;IAC7E;;;;OAIG;IACH,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,cAAc,CAAC;IACzB,aAAa,EAAE,kBAAkB,EAAE,CAAC;IACpC,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAyHD;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,aAWrC,CAAC;AAEH;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,oBAAoB,CAwI1E;AA+CD,eAAO,MAAM,kBAAkB,+BAAyB,CAAC;AAMzD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIvD"}
|
package/dist/spec/parse.js
CHANGED
|
@@ -104,6 +104,16 @@ const CURATED_ATTRIBUTES = {
|
|
|
104
104
|
{ name: "id", tsType: "string" },
|
|
105
105
|
{ name: "provisioningState", tsType: "string" },
|
|
106
106
|
],
|
|
107
|
+
// The app's hostname, for DNS in front of it (#4179). Dotted names read a
|
|
108
|
+
// nested field of reference()'s properties, as AWS's Endpoint.Address does.
|
|
109
|
+
"Microsoft.App/containerApps": [
|
|
110
|
+
{ name: "id", tsType: "string" },
|
|
111
|
+
{ name: "configuration.ingress.fqdn", tsType: "string" },
|
|
112
|
+
{ name: "latestRevisionFqdn", tsType: "string" },
|
|
113
|
+
{ name: "latestRevisionName", tsType: "string" },
|
|
114
|
+
{ name: "outboundIpAddresses", tsType: "string[]" },
|
|
115
|
+
{ name: "provisioningState", tsType: "string" },
|
|
116
|
+
],
|
|
107
117
|
};
|
|
108
118
|
/**
|
|
109
119
|
* Maximum nesting depth of generated property-type interfaces.
|
package/dist/types/index.d.ts
CHANGED
|
@@ -4232,7 +4232,12 @@ export declare class containerApps {
|
|
|
4232
4232
|
/** Resource tags. */
|
|
4233
4233
|
tags?: Record<string, unknown>;
|
|
4234
4234
|
}, attributes?: ArmResourceAttributes);
|
|
4235
|
+
readonly configuration_ingress_fqdn: string;
|
|
4235
4236
|
readonly id: string;
|
|
4237
|
+
readonly latestRevisionFqdn: string;
|
|
4238
|
+
readonly latestRevisionName: string;
|
|
4239
|
+
readonly outboundIpAddresses: string[];
|
|
4240
|
+
readonly provisioningState: string;
|
|
4236
4241
|
}
|
|
4237
4242
|
|
|
4238
4243
|
export declare class containerApps_authConfigs {
|