@mcpg-dev/pulumi 0.1.0-beta.11
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/BUILD.bazel +24 -0
- package/README.md +169 -0
- package/bin/cluster.d.ts +44 -0
- package/bin/cluster.js +80 -0
- package/bin/config.d.ts +30 -0
- package/bin/config.js +22 -0
- package/bin/config.test.d.ts +1 -0
- package/bin/config.test.js +36 -0
- package/bin/gateway.d.ts +52 -0
- package/bin/gateway.js +90 -0
- package/bin/index.d.ts +11 -0
- package/bin/index.js +27 -0
- package/bin/mcpgStack.d.ts +18 -0
- package/bin/mcpgStack.js +58 -0
- package/bin/oci.d.ts +8 -0
- package/bin/oci.js +41 -0
- package/bin/operator.d.ts +28 -0
- package/bin/operator.js +80 -0
- package/bin/pluginSet.d.ts +16 -0
- package/bin/pluginSet.js +55 -0
- package/bin/route.d.ts +35 -0
- package/bin/route.js +64 -0
- package/bin/tenant.d.ts +32 -0
- package/bin/tenant.js +95 -0
- package/bin/tenantCr.d.ts +32 -0
- package/bin/tenantCr.js +65 -0
- package/bin/trustBootstrap.d.ts +21 -0
- package/bin/trustBootstrap.js +56 -0
- package/copy.bara.sky +98 -0
- package/package.json +22 -0
- package/src/cluster.ts +75 -0
- package/src/config.test.ts +36 -0
- package/src/config.ts +44 -0
- package/src/gateway.ts +91 -0
- package/src/index.ts +11 -0
- package/src/mcpgStack.ts +37 -0
- package/src/oci.ts +40 -0
- package/src/operator.ts +65 -0
- package/src/pluginSet.ts +33 -0
- package/src/route.ts +45 -0
- package/src/tenant.ts +79 -0
- package/src/tenantCr.ts +45 -0
- package/src/trustBootstrap.ts +40 -0
- package/tsconfig.json +15 -0
package/src/tenant.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import * as pulumi from "@pulumi/pulumi";
|
|
2
|
+
import * as k8s from "@pulumi/kubernetes";
|
|
3
|
+
import { Gateway, GatewayArgs } from "./gateway";
|
|
4
|
+
import { PluginSet } from "./pluginSet";
|
|
5
|
+
|
|
6
|
+
export interface TenantArgs {
|
|
7
|
+
tenantName: string;
|
|
8
|
+
namespace?: string;
|
|
9
|
+
labels?: { [key: string]: string };
|
|
10
|
+
/** Default true → default-deny cross-tenant ingress NetworkPolicy. */
|
|
11
|
+
networkPolicy?: boolean;
|
|
12
|
+
pluginSet?: { entries: any[]; capabilityGrants?: any[] };
|
|
13
|
+
gateway?: Omit<GatewayArgs, "namespace">;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* One tenant as an imperative fan-out: namespace + NetworkPolicy isolation +
|
|
18
|
+
* (optional) plugin-set + gateway. Instantiate in a loop to fan out a fleet.
|
|
19
|
+
*
|
|
20
|
+
* NB: this does NOT create an MCPGTenant CR, so it does NOT engage the
|
|
21
|
+
* operator's tenant GOVERNANCE (plugin allowlist, ResourceQuota, replica caps,
|
|
22
|
+
* exclusive namespace ownership). For declarative governance use {@link TenantCR}
|
|
23
|
+
* (the MCPGTenant CR) — alongside or instead of this helper.
|
|
24
|
+
*/
|
|
25
|
+
export class Tenant extends pulumi.ComponentResource {
|
|
26
|
+
public readonly namespace: pulumi.Output<string>;
|
|
27
|
+
public readonly gateway?: Gateway;
|
|
28
|
+
public readonly pluginSet?: PluginSet;
|
|
29
|
+
|
|
30
|
+
constructor(name: string, args: TenantArgs, opts?: pulumi.ComponentResourceOptions) {
|
|
31
|
+
super("mcpg:index:Tenant", name, {}, opts);
|
|
32
|
+
|
|
33
|
+
const nsName = args.namespace ?? args.tenantName;
|
|
34
|
+
|
|
35
|
+
const ns = new k8s.core.v1.Namespace(`${name}-ns`, {
|
|
36
|
+
metadata: {
|
|
37
|
+
name: nsName,
|
|
38
|
+
labels: {
|
|
39
|
+
"app.kubernetes.io/managed-by": "pulumi-mcpg",
|
|
40
|
+
"mcpg.dev/tenant": args.tenantName,
|
|
41
|
+
...(args.labels ?? {}),
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
}, { parent: this });
|
|
45
|
+
|
|
46
|
+
if (args.networkPolicy !== false) {
|
|
47
|
+
new k8s.networking.v1.NetworkPolicy(`${name}-isolation`, {
|
|
48
|
+
metadata: { name: "mcpg-tenant-isolation", namespace: nsName },
|
|
49
|
+
spec: {
|
|
50
|
+
podSelector: {},
|
|
51
|
+
policyTypes: ["Ingress"],
|
|
52
|
+
ingress: [{ from: [{ namespaceSelector: { matchLabels: { "mcpg.dev/tenant": args.tenantName } } }] }],
|
|
53
|
+
},
|
|
54
|
+
}, { parent: this, dependsOn: ns });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const setName = `${args.tenantName}-set`;
|
|
58
|
+
if (args.pluginSet) {
|
|
59
|
+
this.pluginSet = new PluginSet(`${name}-set`, {
|
|
60
|
+
namespace: nsName,
|
|
61
|
+
entries: args.pluginSet.entries,
|
|
62
|
+
capabilityGrants: args.pluginSet.capabilityGrants,
|
|
63
|
+
resourceName: setName,
|
|
64
|
+
}, { parent: this, dependsOn: ns });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (args.gateway) {
|
|
68
|
+
this.gateway = new Gateway(`${name}-gw`, {
|
|
69
|
+
...args.gateway,
|
|
70
|
+
namespace: nsName,
|
|
71
|
+
pluginSetRef: args.pluginSet ? setName : args.gateway.pluginSetRef,
|
|
72
|
+
resourceName: args.gateway.resourceName ?? args.tenantName,
|
|
73
|
+
}, { parent: this, dependsOn: ns });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
this.namespace = pulumi.output(nsName);
|
|
77
|
+
this.registerOutputs({ namespace: this.namespace });
|
|
78
|
+
}
|
|
79
|
+
}
|
package/src/tenantCr.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as pulumi from "@pulumi/pulumi";
|
|
2
|
+
import { mcpg } from "@mcpg-dev/pulumi-crds";
|
|
3
|
+
|
|
4
|
+
export interface TenantCRArgs {
|
|
5
|
+
/** Namespaces this tenant owns (non-empty, unique). */
|
|
6
|
+
namespaces: string[];
|
|
7
|
+
/** Plugin allowlist: [{ name? , registryPrefix? }] (each sets ≥1 matcher; [] = deny-all). */
|
|
8
|
+
allowedPlugins?: any[];
|
|
9
|
+
/** { maxGateways?, maxPluginSets?, maxRoutes?, maxReplicasPerGateway? } — each ≥ 0. */
|
|
10
|
+
quotas?: { [key: string]: number };
|
|
11
|
+
/** { key, ... } — key non-empty when set. */
|
|
12
|
+
identityAttribute?: { [key: string]: any };
|
|
13
|
+
labels?: { [key: string]: string };
|
|
14
|
+
resourceName?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* An MCPGTenant (cluster-scoped): the DECLARATIVE tenant governance boundary
|
|
19
|
+
* — plugin allowlist, per-namespace ResourceQuota, replica caps, and
|
|
20
|
+
* exclusive namespace ownership. Distinct from the {@link Tenant} component,
|
|
21
|
+
* which is an imperative namespace+RBAC+NetworkPolicy fan-out that does NOT
|
|
22
|
+
* engage tenant governance.
|
|
23
|
+
*/
|
|
24
|
+
export class TenantCR extends pulumi.ComponentResource {
|
|
25
|
+
public readonly tenant: mcpg.v1alpha1.MCPGTenant;
|
|
26
|
+
public readonly name: pulumi.Output<string>;
|
|
27
|
+
|
|
28
|
+
constructor(name: string, args: TenantCRArgs, opts?: pulumi.ComponentResourceOptions) {
|
|
29
|
+
super("mcpg:index:TenantCR", name, {}, opts);
|
|
30
|
+
|
|
31
|
+
const tName = args.resourceName ?? name;
|
|
32
|
+
const spec: { [key: string]: any } = { namespaces: args.namespaces };
|
|
33
|
+
if (args.allowedPlugins && args.allowedPlugins.length > 0) spec.allowedPlugins = args.allowedPlugins;
|
|
34
|
+
if (args.quotas) spec.quotas = args.quotas;
|
|
35
|
+
if (args.identityAttribute) spec.identityAttribute = args.identityAttribute;
|
|
36
|
+
|
|
37
|
+
this.tenant = new mcpg.v1alpha1.MCPGTenant(tName, {
|
|
38
|
+
metadata: { name: tName, labels: args.labels },
|
|
39
|
+
spec: spec as any,
|
|
40
|
+
}, { parent: this });
|
|
41
|
+
|
|
42
|
+
this.name = pulumi.output(tName);
|
|
43
|
+
this.registerOutputs({ name: this.name });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as pulumi from "@pulumi/pulumi";
|
|
2
|
+
import { mcpg } from "@mcpg-dev/pulumi-crds";
|
|
3
|
+
|
|
4
|
+
export interface SecretRef {
|
|
5
|
+
name: string;
|
|
6
|
+
key: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface TrustBootstrapArgs {
|
|
10
|
+
revocationListName?: string;
|
|
11
|
+
revocations?: any[];
|
|
12
|
+
issuedAt?: string;
|
|
13
|
+
/** Signing-key Secret reference, passed through to plugin trust. Bytes are
|
|
14
|
+
* never read into state (the no-secret-in-state invariant). */
|
|
15
|
+
signingKeySecretRef?: SecretRef;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Seeds the cluster-default MCPGRevocationList and carries the signing-key ref. */
|
|
19
|
+
export class TrustBootstrap extends pulumi.ComponentResource {
|
|
20
|
+
public readonly revocationList: mcpg.v1alpha1.MCPGRevocationList;
|
|
21
|
+
public readonly revocationListName: pulumi.Output<string>;
|
|
22
|
+
public readonly signingKeySecretRef?: SecretRef;
|
|
23
|
+
|
|
24
|
+
constructor(name: string, args: TrustBootstrapArgs = {}, opts?: pulumi.ComponentResourceOptions) {
|
|
25
|
+
super("mcpg:index:TrustBootstrap", name, {}, opts);
|
|
26
|
+
|
|
27
|
+
const rlName = args.revocationListName ?? "cluster-default";
|
|
28
|
+
const spec: { [key: string]: any } = { version: 1, revocations: args.revocations ?? [] };
|
|
29
|
+
if (args.issuedAt) spec.issuedAt = args.issuedAt;
|
|
30
|
+
|
|
31
|
+
this.revocationList = new mcpg.v1alpha1.MCPGRevocationList(rlName, {
|
|
32
|
+
metadata: { name: rlName },
|
|
33
|
+
spec: spec as any,
|
|
34
|
+
}, { parent: this });
|
|
35
|
+
|
|
36
|
+
this.revocationListName = pulumi.output(rlName);
|
|
37
|
+
this.signingKeySecretRef = args.signingKeySecretRef;
|
|
38
|
+
this.registerOutputs({ revocationListName: this.revocationListName });
|
|
39
|
+
}
|
|
40
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es2020",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"outDir": "bin",
|
|
8
|
+
"rootDir": "src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true
|
|
13
|
+
},
|
|
14
|
+
"include": ["src/**/*.ts"]
|
|
15
|
+
}
|