@mizchi/k1c 0.3.0 → 0.4.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/README.md +3 -2
- package/dist/manifest/lower.js +78 -10
- package/dist/manifest/schemas.d.ts +1655 -0
- package/dist/manifest/schemas.js +30 -0
- package/dist/manifest/types.d.ts +43 -1
- package/dist/providers/access-application.d.ts +53 -0
- package/dist/providers/access-application.js +183 -0
- package/dist/providers/index.js +4 -0
- package/dist/providers/worker-route.d.ts +10 -0
- package/dist/providers/worker-route.js +115 -0
- package/dist/reconciler/plan.js +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -49,8 +49,9 @@ $ K1C_ACCOUNT_ID=... CLOUDFLARE_API_TOKEN=... pnpm k1c apply -f manifest.yaml
|
|
|
49
49
|
| `DNSRecord` (CRD) | DNS records | working |
|
|
50
50
|
| `LogpushJob` (CRD) | Logpush (zone- or account-scoped) | working |
|
|
51
51
|
| `ai` / `browser` / `version_metadata` / `analytics_engine` Worker bindings | annotation- / volume-driven | working |
|
|
52
|
-
| `Ingress` (`networking.k8s.io/v1`) | generated router Worker + Custom Domain per host | working |
|
|
53
|
-
| `
|
|
52
|
+
| `Ingress` (`networking.k8s.io/v1`) | generated router Worker + Custom Domain per literal host (Workers Route per wildcard host) | working |
|
|
53
|
+
| `AccessApplication` (CRD) | Cloudflare Access self-hosted app with inline policies | working |
|
|
54
|
+
| `CustomHostname` | — | not implemented (see [`TODO.md`](TODO.md)) |
|
|
54
55
|
|
|
55
56
|
See [`docs/resources.md`](docs/resources.md) for the full mapping and limitations,
|
|
56
57
|
and [`TODO.md`](TODO.md) for what's queued.
|
package/dist/manifest/lower.js
CHANGED
|
@@ -31,6 +31,7 @@ export async function lower(resources, options) {
|
|
|
31
31
|
const dnsRecords = [];
|
|
32
32
|
const logpushJobs = [];
|
|
33
33
|
const ingresses = [];
|
|
34
|
+
const accessApplications = [];
|
|
34
35
|
for (const r of resources) {
|
|
35
36
|
const label = labelOf(r);
|
|
36
37
|
switch (r.kind) {
|
|
@@ -90,6 +91,9 @@ export async function lower(resources, options) {
|
|
|
90
91
|
case 'Ingress':
|
|
91
92
|
ingresses.push(r);
|
|
92
93
|
break;
|
|
94
|
+
case 'AccessApplication':
|
|
95
|
+
accessApplications.push(r);
|
|
96
|
+
break;
|
|
93
97
|
}
|
|
94
98
|
}
|
|
95
99
|
const desired = [];
|
|
@@ -154,8 +158,58 @@ export async function lower(resources, options) {
|
|
|
154
158
|
desired.push(out);
|
|
155
159
|
}
|
|
156
160
|
}
|
|
161
|
+
for (const app of accessApplications) {
|
|
162
|
+
desired.push(lowerAccessApplication(app));
|
|
163
|
+
}
|
|
157
164
|
return { desired, warnings };
|
|
158
165
|
}
|
|
166
|
+
function ruleToWire(rule) {
|
|
167
|
+
if ('email' in rule)
|
|
168
|
+
return { email: { email: rule.email.email } };
|
|
169
|
+
if ('emailDomain' in rule)
|
|
170
|
+
return { email_domain: { domain: rule.emailDomain.domain } };
|
|
171
|
+
if ('everyone' in rule)
|
|
172
|
+
return { everyone: {} };
|
|
173
|
+
if ('ip' in rule)
|
|
174
|
+
return { ip: { ip: rule.ip.ip } };
|
|
175
|
+
if ('country' in rule)
|
|
176
|
+
return { country: { country_code: rule.country.code } };
|
|
177
|
+
if ('serviceToken' in rule)
|
|
178
|
+
return { service_token: { token_id: rule.serviceToken.tokenId } };
|
|
179
|
+
return { any_valid_service_token: {} };
|
|
180
|
+
}
|
|
181
|
+
function policyToWire(p) {
|
|
182
|
+
return {
|
|
183
|
+
name: p.name,
|
|
184
|
+
decision: p.decision,
|
|
185
|
+
include: p.include.map(ruleToWire),
|
|
186
|
+
...(p.exclude !== undefined ? { exclude: p.exclude.map(ruleToWire) } : {}),
|
|
187
|
+
...(p.require !== undefined ? { require: p.require.map(ruleToWire) } : {}),
|
|
188
|
+
...(p.sessionDuration !== undefined ? { session_duration: p.sessionDuration } : {}),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
function lowerAccessApplication(app) {
|
|
192
|
+
const ns = app.metadata.namespace ?? 'default';
|
|
193
|
+
const name = app.metadata.name;
|
|
194
|
+
const properties = {
|
|
195
|
+
appName: `k1c-${ns}-${name}`,
|
|
196
|
+
domain: app.spec.domain,
|
|
197
|
+
...(app.spec.sessionDuration !== undefined
|
|
198
|
+
? { sessionDuration: app.spec.sessionDuration }
|
|
199
|
+
: {}),
|
|
200
|
+
...(app.spec.autoRedirectToIdentity !== undefined
|
|
201
|
+
? { autoRedirectToIdentity: app.spec.autoRedirectToIdentity }
|
|
202
|
+
: {}),
|
|
203
|
+
...(app.spec.allowedIdps !== undefined ? { allowedIdps: [...app.spec.allowedIdps] } : {}),
|
|
204
|
+
policies: app.spec.policies.map(policyToWire),
|
|
205
|
+
};
|
|
206
|
+
return {
|
|
207
|
+
resourceType: 'AccessApplication',
|
|
208
|
+
ref: refOf(app),
|
|
209
|
+
label: `${ns}/${name}`,
|
|
210
|
+
properties,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
159
213
|
function lowerVectorize(v) {
|
|
160
214
|
const ns = v.metadata.namespace ?? 'default';
|
|
161
215
|
const name = v.metadata.name;
|
|
@@ -336,25 +390,19 @@ async function lowerIngress(ing, tables, warnings, options) {
|
|
|
336
390
|
throw new LowerError(`Ingress ${ns}/${name}: missing required annotation \`cloudflare.com/zone-id\``);
|
|
337
391
|
}
|
|
338
392
|
const literalHosts = new Set();
|
|
339
|
-
|
|
393
|
+
const wildcardHosts = new Set();
|
|
340
394
|
for (const rule of ing.spec.rules) {
|
|
341
395
|
if (rule.host === undefined)
|
|
342
396
|
continue;
|
|
343
397
|
if (rule.host.startsWith('*.')) {
|
|
344
|
-
|
|
398
|
+
wildcardHosts.add(rule.host);
|
|
345
399
|
}
|
|
346
400
|
else {
|
|
347
401
|
literalHosts.add(rule.host);
|
|
348
402
|
}
|
|
349
403
|
}
|
|
350
|
-
if (literalHosts.size === 0) {
|
|
351
|
-
throw new LowerError(`Ingress ${ns}/${name}: at least one rule must specify a literal
|
|
352
|
-
}
|
|
353
|
-
if (hasWildcardHost) {
|
|
354
|
-
warnings.push({
|
|
355
|
-
ref,
|
|
356
|
-
message: `Ingress ${ns}/${name}: wildcard hosts are matched in-router only; create a Workers Route or extra Custom Domain manifest to actually receive traffic for the wildcard`,
|
|
357
|
-
});
|
|
404
|
+
if (literalHosts.size === 0 && wildcardHosts.size === 0) {
|
|
405
|
+
throw new LowerError(`Ingress ${ns}/${name}: at least one rule must specify a host (literal or wildcard) so traffic can be bound to the router`);
|
|
358
406
|
}
|
|
359
407
|
// Assign one binding name per unique backend Service.
|
|
360
408
|
const backendBindings = new Map(); // serviceName -> bindingName
|
|
@@ -454,6 +502,26 @@ async function lowerIngress(ing, tables, warnings, options) {
|
|
|
454
502
|
dependsOn: [routerRef],
|
|
455
503
|
});
|
|
456
504
|
}
|
|
505
|
+
// Wildcard hosts cannot be bound via Custom Domain (which takes literal
|
|
506
|
+
// hostnames only); fall back to a zone-scoped Workers Route at `<host>/*`.
|
|
507
|
+
// The router Worker already matches the wildcard in-source, so this just
|
|
508
|
+
// delivers traffic to it.
|
|
509
|
+
for (const host of wildcardHosts) {
|
|
510
|
+
const pattern = `${host}/*`;
|
|
511
|
+
const routeRef = { ...ref, name: `${name}--route--${host}` };
|
|
512
|
+
const routeProps = {
|
|
513
|
+
zoneId,
|
|
514
|
+
pattern,
|
|
515
|
+
scriptName: routerScriptName,
|
|
516
|
+
};
|
|
517
|
+
results.push({
|
|
518
|
+
resourceType: 'WorkerRoute',
|
|
519
|
+
ref: routeRef,
|
|
520
|
+
label: pattern,
|
|
521
|
+
properties: routeProps,
|
|
522
|
+
dependsOn: [routerRef],
|
|
523
|
+
});
|
|
524
|
+
}
|
|
457
525
|
return results;
|
|
458
526
|
}
|
|
459
527
|
function findWorkloadBySelector(selector, namespace, deployments, rollouts) {
|