@intentius/chant-lexicon-k3s 0.44.3
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/README.md +36 -0
- package/dist/codegen/docs.d.ts +7 -0
- package/dist/codegen/docs.d.ts.map +1 -0
- package/dist/codegen/generate-cli.d.ts +3 -0
- package/dist/codegen/generate-cli.d.ts.map +1 -0
- package/dist/codegen/generate-lexicon.d.ts +19 -0
- package/dist/codegen/generate-lexicon.d.ts.map +1 -0
- package/dist/codegen/generate-typescript.d.ts +11 -0
- package/dist/codegen/generate-typescript.d.ts.map +1 -0
- package/dist/codegen/generate.d.ts +15 -0
- package/dist/codegen/generate.d.ts.map +1 -0
- package/dist/codegen/naming.d.ts +13 -0
- package/dist/codegen/naming.d.ts.map +1 -0
- package/dist/codegen/package.d.ts +17 -0
- package/dist/codegen/package.d.ts.map +1 -0
- package/dist/codegen/parse.d.ts +93 -0
- package/dist/codegen/parse.d.ts.map +1 -0
- package/dist/generated/index.d.ts +8 -0
- package/dist/generated/index.d.ts.map +1 -0
- package/dist/generated/runtime.d.ts +5 -0
- package/dist/generated/runtime.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/integrity.json +10 -0
- package/dist/lint/audit-catalog.d.ts +13 -0
- package/dist/lint/audit-catalog.d.ts.map +1 -0
- package/dist/lint/post-synth/index.d.ts +3 -0
- package/dist/lint/post-synth/index.d.ts.map +1 -0
- package/dist/lint/post-synth/k3s-helpers.d.ts +19 -0
- package/dist/lint/post-synth/k3s-helpers.d.ts.map +1 -0
- package/dist/lint/post-synth/k3s101.d.ts +13 -0
- package/dist/lint/post-synth/k3s101.d.ts.map +1 -0
- package/dist/lint/post-synth/k3s102.d.ts +11 -0
- package/dist/lint/post-synth/k3s102.d.ts.map +1 -0
- package/dist/lint/post-synth/k3s103.d.ts +11 -0
- package/dist/lint/post-synth/k3s103.d.ts.map +1 -0
- package/dist/lint/post-synth/k3s104.d.ts +12 -0
- package/dist/lint/post-synth/k3s104.d.ts.map +1 -0
- package/dist/lint/post-synth/k3s105.d.ts +11 -0
- package/dist/lint/post-synth/k3s105.d.ts.map +1 -0
- package/dist/lint/rules/index.d.ts +5 -0
- package/dist/lint/rules/index.d.ts.map +1 -0
- package/dist/lint/rules/token-literal.d.ts +17 -0
- package/dist/lint/rules/token-literal.d.ts.map +1 -0
- package/dist/lsp/completions.d.ts +7 -0
- package/dist/lsp/completions.d.ts.map +1 -0
- package/dist/lsp/hover.d.ts +6 -0
- package/dist/lsp/hover.d.ts.map +1 -0
- package/dist/manifest.json +6 -0
- package/dist/meta.json +37 -0
- package/dist/okf/index.md +9 -0
- package/dist/okf/types/Agent.md +55 -0
- package/dist/okf/types/Registries.md +14 -0
- package/dist/okf/types/Server.md +122 -0
- package/dist/package-cli.d.ts +3 -0
- package/dist/package-cli.d.ts.map +1 -0
- package/dist/plugin.d.ts +8 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/serializer.d.ts +37 -0
- package/dist/serializer.d.ts.map +1 -0
- package/dist/skills/chant-k3s.md +90 -0
- package/dist/spec/fetch.d.ts +39 -0
- package/dist/spec/fetch.d.ts.map +1 -0
- package/dist/types/index.d.ts +370 -0
- package/dist/validate-cli.d.ts +3 -0
- package/dist/validate-cli.d.ts.map +1 -0
- package/dist/validate.d.ts +15 -0
- package/dist/validate.d.ts.map +1 -0
- package/package.json +68 -0
- package/src/codegen/docs.ts +25 -0
- package/src/codegen/generate-cli.ts +8 -0
- package/src/codegen/generate-lexicon.ts +58 -0
- package/src/codegen/generate-typescript.ts +63 -0
- package/src/codegen/generate.test.ts +157 -0
- package/src/codegen/generate.ts +116 -0
- package/src/codegen/naming.ts +42 -0
- package/src/codegen/package.ts +28 -0
- package/src/codegen/parse.ts +386 -0
- package/src/generated/.gitkeep +0 -0
- package/src/generated/index.d.ts +370 -0
- package/src/generated/index.ts +13 -0
- package/src/generated/lexicon-k3s.json +37 -0
- package/src/generated/runtime.ts +4 -0
- package/src/index.ts +11 -0
- package/src/lint/audit-catalog.ts +53 -0
- package/src/lint/post-synth/index.ts +15 -0
- package/src/lint/post-synth/k3s-helpers.ts +34 -0
- package/src/lint/post-synth/k3s101.ts +58 -0
- package/src/lint/post-synth/k3s102.ts +59 -0
- package/src/lint/post-synth/k3s103.ts +38 -0
- package/src/lint/post-synth/k3s104.ts +44 -0
- package/src/lint/post-synth/k3s105.ts +52 -0
- package/src/lint/post-synth/post-synth.test.ts +137 -0
- package/src/lint/rules/index.ts +7 -0
- package/src/lint/rules/token-literal.test.ts +53 -0
- package/src/lint/rules/token-literal.ts +87 -0
- package/src/lsp/completions.test.ts +10 -0
- package/src/lsp/completions.ts +25 -0
- package/src/lsp/hover.test.ts +10 -0
- package/src/lsp/hover.ts +43 -0
- package/src/package-cli.ts +24 -0
- package/src/plugin.test.ts +17 -0
- package/src/plugin.ts +129 -0
- package/src/serializer.acceptance.test.ts +137 -0
- package/src/serializer.test.ts +172 -0
- package/src/serializer.ts +191 -0
- package/src/skills/chant-k3s.md +90 -0
- package/src/spec/fetch.ts +80 -0
- package/src/validate-cli.ts +5 -0
- package/src/validate.ts +41 -0
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* k3s CLI flag-definition parser.
|
|
3
|
+
*
|
|
4
|
+
* The spec is the pinned Go source of pkg/cli/cmds (#1599): urfave/cli
|
|
5
|
+
* struct literals carrying Name, Usage, Value and Hidden. This parser
|
|
6
|
+
* extracts the server and agent flag lists, resolves shared flag-var
|
|
7
|
+
* references across the fetched files, and produces one entity per config
|
|
8
|
+
* document k3s consumes:
|
|
9
|
+
*
|
|
10
|
+
* K3s::Server — /etc/rancher/k3s/config.yaml for `k3s server`
|
|
11
|
+
* K3s::Agent — /etc/rancher/k3s/config.yaml for `k3s agent`
|
|
12
|
+
* K3s::Registries — /etc/rancher/k3s/registries.yaml
|
|
13
|
+
*
|
|
14
|
+
* registries.yaml has no flag surface; its shape is hand-typed from the
|
|
15
|
+
* documented structure (docs.k3s.io/installation/private-registry) and
|
|
16
|
+
* pinned by the same release constant.
|
|
17
|
+
*
|
|
18
|
+
* ## The token boundary (#1601)
|
|
19
|
+
*
|
|
20
|
+
* `token`, `agent-token` and the deprecated `cluster-secret` are excluded
|
|
21
|
+
* from the typed surface on purpose. A literal shared secret in an emitted
|
|
22
|
+
* config.yaml is the #1365 wall; the reference forms (`token-file`,
|
|
23
|
+
* `agent-token-file`, and the K3S_TOKEN/K3S_TOKEN_FILE env vars at install
|
|
24
|
+
* time) stay. K3SC001 catches a literal that arrives through a raw prop
|
|
25
|
+
* anyway.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import type { PropertyConstraints } from "@intentius/chant/codegen/json-schema";
|
|
29
|
+
|
|
30
|
+
// ── Result types (ParsedResult contract) ───────────────────────────
|
|
31
|
+
|
|
32
|
+
export interface ParsedProperty {
|
|
33
|
+
name: string;
|
|
34
|
+
tsType: string;
|
|
35
|
+
required: boolean;
|
|
36
|
+
description?: string;
|
|
37
|
+
enum?: string[];
|
|
38
|
+
constraints: PropertyConstraints;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface ParsedPropertyType {
|
|
42
|
+
name: string;
|
|
43
|
+
defType: string;
|
|
44
|
+
properties: ParsedProperty[];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface ParsedResource {
|
|
48
|
+
typeName: string;
|
|
49
|
+
description?: string;
|
|
50
|
+
properties: ParsedProperty[];
|
|
51
|
+
attributes: Array<{ name: string; tsType: string }>;
|
|
52
|
+
deprecatedProperties: string[];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface K3sParseResult {
|
|
56
|
+
resource: ParsedResource;
|
|
57
|
+
propertyTypes: ParsedPropertyType[];
|
|
58
|
+
enums: Array<{ name: string; values: string[] }>;
|
|
59
|
+
isProperty?: boolean;
|
|
60
|
+
warnings?: string[];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ── Flag extraction ────────────────────────────────────────────────
|
|
64
|
+
|
|
65
|
+
interface FlagDef {
|
|
66
|
+
varName?: string;
|
|
67
|
+
flagType: string; // String | StringSlice | Int | Bool | Duration | Float64 | ...
|
|
68
|
+
name?: string;
|
|
69
|
+
usage?: string;
|
|
70
|
+
value?: string;
|
|
71
|
+
hidden: boolean;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Config keys that must not reach the typed surface.
|
|
76
|
+
*
|
|
77
|
+
* - `config`: the --config flag itself — a config file naming its own path
|
|
78
|
+
* is not a property.
|
|
79
|
+
* - `token` / `agent-token` / `cluster-secret`: literal shared secrets;
|
|
80
|
+
* see the module doc.
|
|
81
|
+
* - `help`: urfave built-in.
|
|
82
|
+
*/
|
|
83
|
+
const SKIP_KEYS = new Set(["config", "token", "agent-token", "cluster-secret", "help"]);
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Extract every `&cli.<T>Flag{...}` literal in a Go source text, keyed by
|
|
87
|
+
* the variable name it is assigned to when there is one.
|
|
88
|
+
*/
|
|
89
|
+
export function extractFlagLiterals(text: string): { byVar: Map<string, FlagDef>; all: FlagDef[] } {
|
|
90
|
+
const byVar = new Map<string, FlagDef>();
|
|
91
|
+
const all: FlagDef[] = [];
|
|
92
|
+
const re = /(?:([A-Za-z_][A-Za-z0-9_]*)\s*=\s*)?&cli\.([A-Za-z0-9]+)Flag\{/g;
|
|
93
|
+
let m: RegExpExecArray | null;
|
|
94
|
+
while ((m = re.exec(text)) !== null) {
|
|
95
|
+
const bodyStart = m.index + m[0].length;
|
|
96
|
+
const body = balancedBody(text, bodyStart);
|
|
97
|
+
if (body === null) continue;
|
|
98
|
+
const def = parseFlagBody(m[2], body);
|
|
99
|
+
if (m[1]) {
|
|
100
|
+
def.varName = m[1];
|
|
101
|
+
byVar.set(m[1], def);
|
|
102
|
+
}
|
|
103
|
+
all.push(def);
|
|
104
|
+
re.lastIndex = bodyStart + body.length;
|
|
105
|
+
}
|
|
106
|
+
return { byVar, all };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Return the text between an opening brace's position and its matching `}` (exclusive). */
|
|
110
|
+
function balancedBody(text: string, start: number): string | null {
|
|
111
|
+
let depth = 1;
|
|
112
|
+
let inString = false;
|
|
113
|
+
for (let i = start; i < text.length; i++) {
|
|
114
|
+
const c = text[i];
|
|
115
|
+
if (inString) {
|
|
116
|
+
if (c === "\\") i++;
|
|
117
|
+
else if (c === '"') inString = false;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (c === '"') inString = true;
|
|
121
|
+
else if (c === "{") depth++;
|
|
122
|
+
else if (c === "}") {
|
|
123
|
+
depth--;
|
|
124
|
+
if (depth === 0) return text.slice(start, i);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function parseFlagBody(flagType: string, body: string): FlagDef {
|
|
131
|
+
const def: FlagDef = { flagType, hidden: /(^|\n)\s*Hidden:\s*true\s*,/.test(body) };
|
|
132
|
+
|
|
133
|
+
const name = body.match(/(^|\n)\s*Name:\s*"([^"]+)"/);
|
|
134
|
+
if (name) def.name = name[2];
|
|
135
|
+
|
|
136
|
+
// Usage may be a multi-line concatenation of string literals; join every
|
|
137
|
+
// quoted segment between `Usage:` and the next field key at line start.
|
|
138
|
+
const usageStart = body.search(/(^|\n)\s*Usage:/);
|
|
139
|
+
if (usageStart >= 0) {
|
|
140
|
+
const rest = body.slice(usageStart);
|
|
141
|
+
const end = rest.slice(1).search(/\n\s*[A-Z][A-Za-z]*:\s/);
|
|
142
|
+
const segment = end >= 0 ? rest.slice(0, end + 1) : rest;
|
|
143
|
+
const parts = [...segment.matchAll(/"((?:[^"\\]|\\.)*)"/g)].map((s) => s[1]);
|
|
144
|
+
if (parts.length > 0) def.usage = parts.join("").replace(/\\"/g, '"');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const value = body.match(/(^|\n)\s*Value:\s*([^,\n]+)/);
|
|
148
|
+
if (value) {
|
|
149
|
+
const raw = value[2].trim();
|
|
150
|
+
const str = raw.match(/^"([^"]*)"$/);
|
|
151
|
+
if (str) def.value = str[1];
|
|
152
|
+
else if (/^[\d.]+$/.test(raw)) def.value = raw;
|
|
153
|
+
else if (/^(true|false)$/.test(raw)) def.value = raw;
|
|
154
|
+
// Composite defaults (cli.NewStringSlice(...), consts) are dropped —
|
|
155
|
+
// they document poorly as a bare expression.
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return def;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Extract the ordered item list of a `[]cli.Flag{...}` block starting at
|
|
163
|
+
* `startIndex` (the index of the opening brace + 1). Items are either
|
|
164
|
+
* bare identifiers (shared flag vars) or inline `&cli.*Flag{...}` literals.
|
|
165
|
+
*/
|
|
166
|
+
export function extractFlagList(text: string, marker: string | RegExp): Array<string | FlagDef> {
|
|
167
|
+
const idx = typeof marker === "string" ? text.indexOf(marker) : (text.match(marker)?.index ?? -1);
|
|
168
|
+
if (idx < 0) return [];
|
|
169
|
+
const open = text.indexOf("{", idx + (typeof marker === "string" ? marker.length - 1 : 0));
|
|
170
|
+
if (open < 0) return [];
|
|
171
|
+
const body = balancedBody(text, open + 1);
|
|
172
|
+
if (body === null) return [];
|
|
173
|
+
|
|
174
|
+
const items: Array<string | FlagDef> = [];
|
|
175
|
+
const re = /(?:^|\n)\s*(?:([A-Za-z_][A-Za-z0-9_]*)\s*,|&cli\.([A-Za-z0-9]+)Flag\{)/g;
|
|
176
|
+
let m: RegExpExecArray | null;
|
|
177
|
+
while ((m = re.exec(body)) !== null) {
|
|
178
|
+
if (m[1]) {
|
|
179
|
+
items.push(m[1]);
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
const bodyStart = m.index + m[0].length;
|
|
183
|
+
const flagBody = balancedBody(body, bodyStart);
|
|
184
|
+
if (flagBody === null) continue;
|
|
185
|
+
items.push(parseFlagBody(m[2], flagBody));
|
|
186
|
+
re.lastIndex = bodyStart + flagBody.length;
|
|
187
|
+
}
|
|
188
|
+
return items;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// ── Flag → property mapping ────────────────────────────────────────
|
|
192
|
+
|
|
193
|
+
function tsTypeFor(flagType: string): string {
|
|
194
|
+
switch (flagType) {
|
|
195
|
+
case "String":
|
|
196
|
+
return "string";
|
|
197
|
+
case "Int":
|
|
198
|
+
case "Int64":
|
|
199
|
+
case "Uint":
|
|
200
|
+
case "Float64":
|
|
201
|
+
return "number";
|
|
202
|
+
case "Bool":
|
|
203
|
+
return "boolean";
|
|
204
|
+
// config.yaml accepts a single value or a list for slice flags.
|
|
205
|
+
case "StringSlice":
|
|
206
|
+
return "string | string[]";
|
|
207
|
+
case "IntSlice":
|
|
208
|
+
return "number | number[]";
|
|
209
|
+
// Durations are Go duration strings ("12h", "5m") in YAML.
|
|
210
|
+
case "Duration":
|
|
211
|
+
return "string";
|
|
212
|
+
default:
|
|
213
|
+
return "string";
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function toProperty(def: FlagDef): ParsedProperty | null {
|
|
218
|
+
if (!def.name || def.hidden) return null;
|
|
219
|
+
// urfave v2 keeps aliases in Aliases, not the Name — but keep the guard
|
|
220
|
+
// for a comma form arriving through an older definition.
|
|
221
|
+
const name = def.name.split(",")[0].trim();
|
|
222
|
+
if (SKIP_KEYS.has(name)) return null;
|
|
223
|
+
if (def.usage && /\(deprecated/i.test(def.usage)) return null;
|
|
224
|
+
|
|
225
|
+
let description = def.usage;
|
|
226
|
+
if (def.value !== undefined && def.value !== "" && description) {
|
|
227
|
+
description += ` (default: ${def.value})`;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return {
|
|
231
|
+
name,
|
|
232
|
+
tsType: tsTypeFor(def.flagType),
|
|
233
|
+
required: false,
|
|
234
|
+
description,
|
|
235
|
+
constraints: {},
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function resolveList(
|
|
240
|
+
items: Array<string | FlagDef>,
|
|
241
|
+
byVar: Map<string, FlagDef>,
|
|
242
|
+
warnings: string[],
|
|
243
|
+
context: string,
|
|
244
|
+
): ParsedProperty[] {
|
|
245
|
+
const props: ParsedProperty[] = [];
|
|
246
|
+
const seen = new Set<string>();
|
|
247
|
+
for (const item of items) {
|
|
248
|
+
let def: FlagDef | undefined;
|
|
249
|
+
if (typeof item === "string") {
|
|
250
|
+
def = byVar.get(item);
|
|
251
|
+
if (!def) {
|
|
252
|
+
warnings.push(`${context}: unresolved flag reference ${item}`);
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
} else {
|
|
256
|
+
def = item;
|
|
257
|
+
}
|
|
258
|
+
const prop = toProperty(def);
|
|
259
|
+
if (!prop || seen.has(prop.name)) continue;
|
|
260
|
+
seen.add(prop.name);
|
|
261
|
+
props.push(prop);
|
|
262
|
+
}
|
|
263
|
+
return props;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// ── Hand-typed registries.yaml surface ─────────────────────────────
|
|
267
|
+
|
|
268
|
+
function prop(name: string, tsType: string, description: string, required = false): ParsedProperty {
|
|
269
|
+
return { name, tsType, required, description, constraints: {} };
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function registriesEntities(): K3sParseResult[] {
|
|
273
|
+
const mk = (
|
|
274
|
+
typeName: string,
|
|
275
|
+
description: string,
|
|
276
|
+
properties: ParsedProperty[],
|
|
277
|
+
isProperty = true,
|
|
278
|
+
): K3sParseResult => ({
|
|
279
|
+
resource: { typeName, description, properties, attributes: [], deprecatedProperties: [] },
|
|
280
|
+
propertyTypes: [],
|
|
281
|
+
enums: [],
|
|
282
|
+
isProperty,
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
return [
|
|
286
|
+
mk(
|
|
287
|
+
"K3s::Registries",
|
|
288
|
+
"Private registry configuration (/etc/rancher/k3s/registries.yaml) for the embedded containerd",
|
|
289
|
+
[
|
|
290
|
+
prop("mirrors", "Record<string, Mirror>", "Registry name (or wildcard) to mirror configuration"),
|
|
291
|
+
prop("configs", "Record<string, RegistryConfig>", "Registry endpoint to auth/TLS configuration"),
|
|
292
|
+
],
|
|
293
|
+
false,
|
|
294
|
+
),
|
|
295
|
+
mk("K3s::Mirror", "Endpoint rewrites for one registry", [
|
|
296
|
+
prop("endpoint", "string | string[]", "Mirror endpoint URLs, tried in order"),
|
|
297
|
+
prop("rewrite", "Record<string, string>", "Image name rewrite rules (regex to replacement)"),
|
|
298
|
+
]),
|
|
299
|
+
mk("K3s::RegistryConfig", "Auth and TLS for one registry endpoint", [
|
|
300
|
+
prop("auth", "RegistryAuth", "Credentials for the registry"),
|
|
301
|
+
prop("tls", "RegistryTLS", "TLS settings for the registry"),
|
|
302
|
+
]),
|
|
303
|
+
mk("K3s::RegistryAuth", "Registry credentials — prefer out-of-band credential helpers; K3SC002 flags literals", [
|
|
304
|
+
prop("username", "string", "Basic auth username"),
|
|
305
|
+
prop("password", "string", "Basic auth password. A literal here fails K3SC002"),
|
|
306
|
+
prop("token", "string", "Bearer token. A literal here fails K3SC002"),
|
|
307
|
+
]),
|
|
308
|
+
mk("K3s::RegistryTLS", "Registry TLS settings", [
|
|
309
|
+
prop("cert_file", "string", "Client certificate path on the node"),
|
|
310
|
+
prop("key_file", "string", "Client key path on the node"),
|
|
311
|
+
prop("ca_file", "string", "CA bundle path on the node"),
|
|
312
|
+
prop("insecure_skip_verify", "boolean", "Skip TLS verification. K3SS002 flags this"),
|
|
313
|
+
]),
|
|
314
|
+
];
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// ── Entry point ────────────────────────────────────────────────────
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Parse the fetched spec envelope (filename → Go source) into the k3s
|
|
321
|
+
* entity results.
|
|
322
|
+
*/
|
|
323
|
+
export function parseSpecFiles(data: string | Buffer): K3sParseResult[] {
|
|
324
|
+
const files: Record<string, string> = JSON.parse(
|
|
325
|
+
typeof data === "string" ? data : data.toString("utf-8"),
|
|
326
|
+
);
|
|
327
|
+
const combined = Object.values(files).join("\n");
|
|
328
|
+
const warnings: string[] = [];
|
|
329
|
+
|
|
330
|
+
const { byVar } = extractFlagLiterals(combined);
|
|
331
|
+
|
|
332
|
+
const serverItems = extractFlagList(files["server.go"] ?? "", "var ServerFlags = []cli.Flag{");
|
|
333
|
+
const serverProps = resolveList(serverItems, byVar, warnings, "ServerFlags");
|
|
334
|
+
|
|
335
|
+
const agentItems = extractFlagList(files["agent.go"] ?? "", /Flags:\s*\[\]cli\.Flag\{/);
|
|
336
|
+
const agentProps = resolveList(agentItems, byVar, warnings, "AgentFlags");
|
|
337
|
+
|
|
338
|
+
// An agent is nothing without the server it joins. `token-file` stays
|
|
339
|
+
// optional because the join secret may arrive as K3S_TOKEN_FILE at
|
|
340
|
+
// install time instead (#1601).
|
|
341
|
+
for (const p of agentProps) {
|
|
342
|
+
if (p.name === "server") p.required = true;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const results: K3sParseResult[] = [
|
|
346
|
+
{
|
|
347
|
+
resource: {
|
|
348
|
+
typeName: "K3s::Server",
|
|
349
|
+
description: `k3s server configuration (/etc/rancher/k3s/config.yaml) — every \`k3s server\` flag as a YAML key`,
|
|
350
|
+
properties: serverProps,
|
|
351
|
+
attributes: [],
|
|
352
|
+
deprecatedProperties: [],
|
|
353
|
+
},
|
|
354
|
+
propertyTypes: [],
|
|
355
|
+
enums: [],
|
|
356
|
+
warnings,
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
resource: {
|
|
360
|
+
typeName: "K3s::Agent",
|
|
361
|
+
description: `k3s agent configuration (/etc/rancher/k3s/config.yaml) — every \`k3s agent\` flag as a YAML key`,
|
|
362
|
+
properties: agentProps,
|
|
363
|
+
attributes: [],
|
|
364
|
+
deprecatedProperties: [],
|
|
365
|
+
},
|
|
366
|
+
propertyTypes: [],
|
|
367
|
+
enums: [],
|
|
368
|
+
},
|
|
369
|
+
...registriesEntities(),
|
|
370
|
+
];
|
|
371
|
+
|
|
372
|
+
return results;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// ── Helpers ────────────────────────────────────────────────────────
|
|
376
|
+
|
|
377
|
+
/** Extract short name: "K3s::Server" → "Server" */
|
|
378
|
+
export function k3sShortName(typeName: string): string {
|
|
379
|
+
const parts = typeName.split("::");
|
|
380
|
+
return parts[parts.length - 1];
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/** Extract service name: always "K3s" — the lexicon is a single flat service. */
|
|
384
|
+
export function k3sServiceName(_typeName: string): string {
|
|
385
|
+
return "K3s";
|
|
386
|
+
}
|
|
File without changes
|