@highstate/cilium 0.9.9 → 0.9.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/dist/chunk-M4DV2DAJ.js +18 -0
- package/dist/chunk-M4DV2DAJ.js.map +1 -0
- package/dist/highstate.manifest.json +2 -1
- package/dist/index.js +19 -18
- package/dist/index.js.map +1 -1
- package/dist/unit/index.js +54 -0
- package/dist/unit/index.js.map +1 -0
- package/package.json +10 -8
- package/src/network-policy.ts +19 -6
- package/src/shared.ts +23 -0
- package/src/unit/index.ts +57 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
// assets/charts.json
|
2
|
+
var cilium = {
|
3
|
+
repo: "https://helm.cilium.io",
|
4
|
+
name: "cilium",
|
5
|
+
version: "1.17.4",
|
6
|
+
sha256: "06dcedfe25c08c770d193690d561037153e233f9cde31e0705a06802d24cea87"
|
7
|
+
};
|
8
|
+
|
9
|
+
// src/shared.ts
|
10
|
+
function getCiliumClusterMetadata(cluster) {
|
11
|
+
return cluster.metadata?.cilium ?? {};
|
12
|
+
}
|
13
|
+
|
14
|
+
export {
|
15
|
+
cilium,
|
16
|
+
getCiliumClusterMetadata
|
17
|
+
};
|
18
|
+
//# sourceMappingURL=chunk-M4DV2DAJ.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../assets/charts.json","../src/shared.ts"],"sourcesContent":["{\n \"cilium\": {\n \"repo\": \"https://helm.cilium.io\",\n \"name\": \"cilium\",\n \"version\": \"1.17.4\",\n \"sha256\": \"06dcedfe25c08c770d193690d561037153e233f9cde31e0705a06802d24cea87\"\n }\n}\n","import type { k8s } from \"@highstate/library\"\n\nexport { cilium as chart } from \"../assets/charts.json\"\n\nexport type CiliumClusterMetadata = {\n /**\n * If set to `true`, the generated network policy will allow\n * all DNS queries to be resolved, even if they are\n * for forbidden (non-allowed) FQDNs.\n *\n * By default, is not set.\n */\n allowForbiddenFqdnResolution?: boolean\n}\n\nexport function getCiliumClusterMetadata(cluster: k8s.Cluster): CiliumClusterMetadata {\n return cluster.metadata?.cilium ?? {}\n}\n\nexport function hasCiliumClusterMetadata(\n cluster: k8s.Cluster,\n): cluster is k8s.Cluster & { metadata: { cilium: CiliumClusterMetadata } } {\n return Boolean(cluster.metadata?.cilium)\n}\n"],"mappings":";AACE,aAAU;AAAA,EACR,MAAQ;AAAA,EACR,MAAQ;AAAA,EACR,SAAW;AAAA,EACX,QAAU;AACZ;;;ACSK,SAAS,yBAAyB,SAA6C;AACpF,SAAO,QAAQ,UAAU,UAAU,CAAC;AACtC;","names":[]}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"sourceHashes": {
|
3
|
-
"./dist/index.js": "
|
3
|
+
"./dist/index.js": "80797b7d18c03770033c08b8022740afa970339ab64f319f3f5362d9a5104d2d",
|
4
|
+
"./dist/unit/index.js": "7389086e95165fdc5c418fa499211b38c655e940e20338cee2f3588b18edf760"
|
4
5
|
}
|
5
6
|
}
|
package/dist/index.js
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
import {
|
2
|
+
cilium,
|
3
|
+
getCiliumClusterMetadata
|
4
|
+
} from "./chunk-M4DV2DAJ.js";
|
5
|
+
|
1
6
|
// src/network-policy.ts
|
2
7
|
import { output } from "@highstate/pulumi";
|
3
8
|
import {
|
@@ -7,12 +12,12 @@ import {
|
|
7
12
|
mapServiceToLabelSelector,
|
8
13
|
NetworkPolicy
|
9
14
|
} from "@highstate/k8s";
|
10
|
-
import { cilium } from "@highstate/cilium-crds";
|
15
|
+
import { cilium as cilium2 } from "@highstate/cilium-crds";
|
11
16
|
import "@pulumi/kubernetes";
|
12
17
|
import { map, mapKeys, pipe, uniqueBy } from "remeda";
|
13
18
|
var CiliumNetworkPolicy = class _CiliumNetworkPolicy extends NetworkPolicy {
|
14
19
|
create(name, args, opts) {
|
15
|
-
return new
|
20
|
+
return new cilium2.v2.CiliumNetworkPolicy(
|
16
21
|
name,
|
17
22
|
{
|
18
23
|
metadata: mapMetadata(args, name),
|
@@ -31,7 +36,9 @@ var CiliumNetworkPolicy = class _CiliumNetworkPolicy extends NetworkPolicy {
|
|
31
36
|
return [{}];
|
32
37
|
}
|
33
38
|
return uniqueBy(
|
34
|
-
args.ingressRules.flatMap(
|
39
|
+
args.ingressRules.flatMap(
|
40
|
+
(rule) => _CiliumNetworkPolicy.createRules("from", rule, args.cluster)
|
41
|
+
),
|
35
42
|
(rule) => JSON.stringify(rule)
|
36
43
|
);
|
37
44
|
}
|
@@ -44,11 +51,11 @@ var CiliumNetworkPolicy = class _CiliumNetworkPolicy extends NetworkPolicy {
|
|
44
51
|
extraRules.push({ toEntities: ["kube-apiserver"] });
|
45
52
|
}
|
46
53
|
return uniqueBy(
|
47
|
-
args.egressRules.flatMap((rule) => _CiliumNetworkPolicy.createRules("to", rule)).concat(extraRules),
|
54
|
+
args.egressRules.flatMap((rule) => _CiliumNetworkPolicy.createRules("to", rule, args.cluster)).concat(extraRules),
|
48
55
|
(rule) => JSON.stringify(rule)
|
49
56
|
);
|
50
57
|
}
|
51
|
-
static createRules(prefix, rule) {
|
58
|
+
static createRules(prefix, rule, cluster) {
|
52
59
|
const port = _CiliumNetworkPolicy.mapPorts(rule.ports);
|
53
60
|
const ports = port ? [port] : void 0;
|
54
61
|
return [
|
@@ -56,7 +63,7 @@ var CiliumNetworkPolicy = class _CiliumNetworkPolicy extends NetworkPolicy {
|
|
56
63
|
..._CiliumNetworkPolicy.createCidrRules(prefix, rule, ports),
|
57
64
|
..._CiliumNetworkPolicy.createServiceRules(prefix, rule, ports),
|
58
65
|
..._CiliumNetworkPolicy.createSelectorRules(prefix, rule, ports),
|
59
|
-
...prefix === "to" ? _CiliumNetworkPolicy.createFqdnRules(rule, ports) : []
|
66
|
+
...prefix === "to" ? _CiliumNetworkPolicy.createFqdnRules(rule, ports, cluster) : []
|
60
67
|
];
|
61
68
|
}
|
62
69
|
static createAllRules(prefix, rule, ports) {
|
@@ -81,7 +88,7 @@ var CiliumNetworkPolicy = class _CiliumNetworkPolicy extends NetworkPolicy {
|
|
81
88
|
}
|
82
89
|
];
|
83
90
|
}
|
84
|
-
static createFqdnRules(rule, ports) {
|
91
|
+
static createFqdnRules(rule, ports, cluster) {
|
85
92
|
if (rule.fqdns.length === 0) {
|
86
93
|
return [];
|
87
94
|
}
|
@@ -105,7 +112,9 @@ var CiliumNetworkPolicy = class _CiliumNetworkPolicy extends NetworkPolicy {
|
|
105
112
|
toPorts: [
|
106
113
|
{
|
107
114
|
ports: [{ port: "53", protocol: "UDP" }],
|
108
|
-
rules: {
|
115
|
+
rules: {
|
116
|
+
dns: getCiliumClusterMetadata(cluster).allowForbiddenFqdnResolution ? [{ matchPattern: "*" }] : fqdnRules
|
117
|
+
}
|
109
118
|
}
|
110
119
|
]
|
111
120
|
}
|
@@ -177,7 +186,7 @@ var CiliumNetworkPolicy = class _CiliumNetworkPolicy extends NetworkPolicy {
|
|
177
186
|
});
|
178
187
|
return [
|
179
188
|
{
|
180
|
-
[`${prefix}Endpoints`]: selectors,
|
189
|
+
[`${prefix}Endpoints`]: uniqueBy(selectors, (rule2) => JSON.stringify(rule2)),
|
181
190
|
toPorts: ports
|
182
191
|
}
|
183
192
|
];
|
@@ -203,16 +212,8 @@ var CiliumNetworkPolicy = class _CiliumNetworkPolicy extends NetworkPolicy {
|
|
203
212
|
};
|
204
213
|
}
|
205
214
|
};
|
206
|
-
|
207
|
-
// assets/charts.json
|
208
|
-
var cilium2 = {
|
209
|
-
repo: "https://helm.cilium.io",
|
210
|
-
name: "cilium",
|
211
|
-
version: "1.17.4",
|
212
|
-
sha256: "06dcedfe25c08c770d193690d561037153e233f9cde31e0705a06802d24cea87"
|
213
|
-
};
|
214
215
|
export {
|
215
216
|
CiliumNetworkPolicy,
|
216
|
-
|
217
|
+
cilium as chart
|
217
218
|
};
|
218
219
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/network-policy.ts","../assets/charts.json"],"sourcesContent":["import { type ResourceOptions, type Resource, output } from \"@highstate/pulumi\"\nimport {\n mapMetadata,\n mapNamespaceLikeToNamespaceName,\n mapSelectorLikeToSelector,\n mapServiceToLabelSelector,\n NetworkPolicy,\n type NetworkPolicyPort,\n type NormalizedNetworkPolicyArgs,\n type NormalizedRuleArgs,\n} from \"@highstate/k8s\"\nimport { cilium, types } from \"@highstate/cilium-crds\"\nimport { types as k8sTypes } from \"@pulumi/kubernetes\"\nimport { map, mapKeys, pipe, uniqueBy } from \"remeda\"\n\ntype Rule = types.input.cilium.v2.CiliumNetworkPolicySpecIngress &\n types.input.cilium.v2.CiliumNetworkPolicySpecEgress\n\nexport class CiliumNetworkPolicy extends NetworkPolicy {\n protected create(\n name: string,\n args: NormalizedNetworkPolicyArgs,\n opts?: ResourceOptions,\n ): Resource {\n return new cilium.v2.CiliumNetworkPolicy(\n name,\n {\n metadata: mapMetadata(args, name),\n spec: {\n description: args.description,\n endpointSelector: args.podSelector,\n ingress: CiliumNetworkPolicy.createIngressRules(args),\n egress: CiliumNetworkPolicy.createEgressRules(args),\n },\n },\n opts,\n )\n }\n\n private static createIngressRules(args: NormalizedNetworkPolicyArgs): Rule[] {\n if (args.isolateIngress) {\n return [{}]\n }\n\n return uniqueBy(\n args.ingressRules.flatMap(rule => CiliumNetworkPolicy.createRules(\"from\", rule)),\n rule => JSON.stringify(rule),\n )\n }\n\n private static createEgressRules(args: NormalizedNetworkPolicyArgs): Rule[] {\n if (args.isolateEgress) {\n return [{}]\n }\n\n const extraRules: Rule[] = []\n\n if (args.allowKubeApiServer) {\n extraRules.push({ toEntities: [\"kube-apiserver\"] })\n }\n\n return uniqueBy(\n args.egressRules\n .flatMap(rule => CiliumNetworkPolicy.createRules(\"to\", rule))\n .concat(extraRules),\n rule => JSON.stringify(rule),\n )\n }\n\n private static createRules(prefix: \"from\" | \"to\", rule: NormalizedRuleArgs): Rule[] {\n const port = CiliumNetworkPolicy.mapPorts(rule.ports)\n const ports = port ? [port] : undefined\n\n return [\n ...CiliumNetworkPolicy.createAllRules(prefix, rule, ports),\n ...CiliumNetworkPolicy.createCidrRules(prefix, rule, ports),\n ...CiliumNetworkPolicy.createServiceRules(prefix, rule, ports),\n ...CiliumNetworkPolicy.createSelectorRules(prefix, rule, ports),\n ...(prefix === \"to\" ? CiliumNetworkPolicy.createFqdnRules(rule, ports) : []),\n ]\n }\n\n private static createAllRules(\n prefix: \"from\" | \"to\",\n rule: NormalizedRuleArgs,\n ports: types.input.cilium.v2.CiliumNetworkPolicySpecEgressToPorts[] | undefined,\n ): Rule[] {\n if (!rule.all) {\n return []\n }\n\n return [\n {\n [`${prefix}Entities`]: [\"all\"],\n toPorts: ports,\n },\n ]\n }\n\n private static createCidrRules(\n prefix: \"from\" | \"to\",\n rule: NormalizedRuleArgs,\n ports: types.input.cilium.v2.CiliumNetworkPolicySpecEgressToPorts[] | undefined,\n ): Rule[] {\n if (rule.cidrs.length === 0) {\n return []\n }\n\n return [\n {\n [`${prefix}CIDR`]: rule.cidrs,\n toPorts: ports,\n },\n ]\n }\n\n private static createFqdnRules(\n rule: NormalizedRuleArgs,\n ports: types.input.cilium.v2.CiliumNetworkPolicySpecEgressToPorts[] | undefined,\n ): types.input.cilium.v2.CiliumNetworkPolicySpecEgress[] {\n if (rule.fqdns.length === 0) {\n return []\n }\n\n const fqdnRules = rule.fqdns.map(fqdn => {\n return fqdn.includes(\"*\") ? { matchPattern: fqdn } : { matchName: fqdn }\n })\n\n return [\n {\n toFQDNs: fqdnRules,\n toPorts: ports,\n },\n {\n toEndpoints: [\n {\n matchLabels: {\n \"k8s:io.kubernetes.pod.namespace\": \"kube-system\",\n \"k8s:k8s-app\": \"kube-dns\",\n },\n },\n ],\n toPorts: [\n {\n ports: [{ port: \"53\", protocol: \"UDP\" }],\n rules: { dns: fqdnRules },\n },\n ],\n },\n ]\n }\n\n private static createServiceRules(\n prefix: \"from\" | \"to\",\n rule: NormalizedRuleArgs,\n ports: types.input.cilium.v2.CiliumNetworkPolicySpecEgressToPorts[] | undefined,\n ): Rule[] {\n if (rule.services.length === 0) {\n return []\n }\n\n const selectors = rule.services.map(service => {\n const selector = mapServiceToLabelSelector(service)\n\n return output(selector).apply(selector => ({\n matchLabels: {\n ...mapKeys(selector.matchLabels ?? {}, key => `k8s:${key}`),\n \"k8s:io.kubernetes.pod.namespace\": service.metadata.namespace,\n },\n }))\n })\n\n return [\n {\n [`${prefix}Endpoints`]: selectors,\n toPorts: ports,\n },\n ]\n }\n\n private static createNamespaceExpressions(\n rule: NormalizedRuleArgs,\n ): k8sTypes.input.meta.v1.LabelSelectorRequirement[] {\n if (rule.namespaces.length === 0) {\n return []\n }\n\n return pipe(\n //\n rule.namespaces,\n map(mapNamespaceLikeToNamespaceName),\n names => [\n {\n key: \"k8s:io.kubernetes.pod.namespace\",\n operator: \"In\",\n values: names,\n },\n ],\n )\n }\n\n private static createSelectorRules(\n prefix: \"from\" | \"to\",\n rule: NormalizedRuleArgs,\n ports: types.input.cilium.v2.CiliumNetworkPolicySpecEgressToPorts[] | undefined,\n ): types.input.cilium.v2.CiliumNetworkPolicySpecIngress[] {\n const namespaceExpressions = CiliumNetworkPolicy.createNamespaceExpressions(rule)\n\n if (rule.selectors.length === 0) {\n if (namespaceExpressions.length === 0) {\n // if no selectors and no namespaces are provided, we do not match\n return []\n }\n\n // if no selectors are provided, we only match on namespaces\n return [\n {\n [`${prefix}Endpoints`]: [{ matchExpressions: namespaceExpressions }],\n toPorts: ports,\n },\n ]\n }\n\n // otherwise, we match on selectors and namespaces\n const selectors = rule.selectors.map(selector => {\n const rawSelector = mapSelectorLikeToSelector(selector)\n\n return output(rawSelector).apply(rawSelector => {\n const expressions = map(rawSelector.matchExpressions ?? [], expression => ({\n key: `k8s:${expression.key}`,\n operator: expression.operator,\n values: expression.values,\n }))\n\n return {\n matchLabels: mapKeys(rawSelector.matchLabels ?? {}, key => `k8s:${key}`),\n matchExpressions: [...expressions, ...namespaceExpressions],\n }\n })\n })\n\n return [\n {\n [`${prefix}Endpoints`]: selectors,\n toPorts: ports,\n },\n ]\n }\n\n private static mapPorts(\n ports: NetworkPolicyPort[],\n ): types.input.cilium.v2.CiliumNetworkPolicySpecEgressToPorts | undefined {\n if (ports.length === 0) {\n return\n }\n\n return {\n ports: ports.map(port => {\n if (\"port\" in port) {\n return {\n port: port.port.toString(),\n protocol: port.protocol ?? \"TCP\",\n }\n }\n\n return {\n port: port.range[0].toString(),\n endPort: port.range[1],\n protocol: port.protocol ?? \"TCP\",\n }\n }),\n }\n }\n}\n","{\n \"cilium\": {\n \"repo\": \"https://helm.cilium.io\",\n \"name\": \"cilium\",\n \"version\": \"1.17.4\",\n \"sha256\": \"06dcedfe25c08c770d193690d561037153e233f9cde31e0705a06802d24cea87\"\n }\n}\n"],"mappings":"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","names":["selector","rawSelector","cilium"]}
|
1
|
+
{"version":3,"sources":["../src/network-policy.ts"],"sourcesContent":["import type { k8s } from \"@highstate/library\"\nimport { type ResourceOptions, type Resource, output } from \"@highstate/pulumi\"\nimport {\n mapMetadata,\n mapNamespaceLikeToNamespaceName,\n mapSelectorLikeToSelector,\n mapServiceToLabelSelector,\n NetworkPolicy,\n type NetworkPolicyPort,\n type NormalizedNetworkPolicyArgs,\n type NormalizedRuleArgs,\n} from \"@highstate/k8s\"\nimport { cilium, types } from \"@highstate/cilium-crds\"\nimport { types as k8sTypes } from \"@pulumi/kubernetes\"\nimport { map, mapKeys, pipe, uniqueBy } from \"remeda\"\nimport { getCiliumClusterMetadata } from \"./shared\"\n\ntype Rule = types.input.cilium.v2.CiliumNetworkPolicySpecIngress &\n types.input.cilium.v2.CiliumNetworkPolicySpecEgress\n\nexport class CiliumNetworkPolicy extends NetworkPolicy {\n protected create(\n name: string,\n args: NormalizedNetworkPolicyArgs,\n opts?: ResourceOptions,\n ): Resource {\n return new cilium.v2.CiliumNetworkPolicy(\n name,\n {\n metadata: mapMetadata(args, name),\n spec: {\n description: args.description,\n endpointSelector: args.podSelector,\n ingress: CiliumNetworkPolicy.createIngressRules(args),\n egress: CiliumNetworkPolicy.createEgressRules(args),\n },\n },\n opts,\n )\n }\n\n private static createIngressRules(args: NormalizedNetworkPolicyArgs): Rule[] {\n if (args.isolateIngress) {\n return [{}]\n }\n\n return uniqueBy(\n args.ingressRules.flatMap(rule =>\n CiliumNetworkPolicy.createRules(\"from\", rule, args.cluster),\n ),\n rule => JSON.stringify(rule),\n )\n }\n\n private static createEgressRules(args: NormalizedNetworkPolicyArgs): Rule[] {\n if (args.isolateEgress) {\n return [{}]\n }\n\n const extraRules: Rule[] = []\n\n if (args.allowKubeApiServer) {\n extraRules.push({ toEntities: [\"kube-apiserver\"] })\n }\n\n return uniqueBy(\n args.egressRules\n .flatMap(rule => CiliumNetworkPolicy.createRules(\"to\", rule, args.cluster))\n .concat(extraRules),\n rule => JSON.stringify(rule),\n )\n }\n\n private static createRules(\n prefix: \"from\" | \"to\",\n rule: NormalizedRuleArgs,\n cluster: k8s.Cluster,\n ): Rule[] {\n const port = CiliumNetworkPolicy.mapPorts(rule.ports)\n const ports = port ? [port] : undefined\n\n return [\n ...CiliumNetworkPolicy.createAllRules(prefix, rule, ports),\n ...CiliumNetworkPolicy.createCidrRules(prefix, rule, ports),\n ...CiliumNetworkPolicy.createServiceRules(prefix, rule, ports),\n ...CiliumNetworkPolicy.createSelectorRules(prefix, rule, ports),\n ...(prefix === \"to\" ? CiliumNetworkPolicy.createFqdnRules(rule, ports, cluster) : []),\n ]\n }\n\n private static createAllRules(\n prefix: \"from\" | \"to\",\n rule: NormalizedRuleArgs,\n ports: types.input.cilium.v2.CiliumNetworkPolicySpecEgressToPorts[] | undefined,\n ): Rule[] {\n if (!rule.all) {\n return []\n }\n\n return [\n {\n [`${prefix}Entities`]: [\"all\"],\n toPorts: ports,\n },\n ]\n }\n\n private static createCidrRules(\n prefix: \"from\" | \"to\",\n rule: NormalizedRuleArgs,\n ports: types.input.cilium.v2.CiliumNetworkPolicySpecEgressToPorts[] | undefined,\n ): Rule[] {\n if (rule.cidrs.length === 0) {\n return []\n }\n\n return [\n {\n [`${prefix}CIDR`]: rule.cidrs,\n toPorts: ports,\n },\n ]\n }\n\n private static createFqdnRules(\n rule: NormalizedRuleArgs,\n ports: types.input.cilium.v2.CiliumNetworkPolicySpecEgressToPorts[] | undefined,\n cluster: k8s.Cluster,\n ): types.input.cilium.v2.CiliumNetworkPolicySpecEgress[] {\n if (rule.fqdns.length === 0) {\n return []\n }\n\n const fqdnRules = rule.fqdns.map(fqdn => {\n return fqdn.includes(\"*\") ? { matchPattern: fqdn } : { matchName: fqdn }\n })\n\n return [\n {\n toFQDNs: fqdnRules,\n toPorts: ports,\n },\n {\n toEndpoints: [\n {\n matchLabels: {\n \"k8s:io.kubernetes.pod.namespace\": \"kube-system\",\n \"k8s:k8s-app\": \"kube-dns\",\n },\n },\n ],\n toPorts: [\n {\n ports: [{ port: \"53\", protocol: \"UDP\" }],\n rules: {\n dns: getCiliumClusterMetadata(cluster).allowForbiddenFqdnResolution\n ? [{ matchPattern: \"*\" }]\n : fqdnRules,\n },\n },\n ],\n },\n ]\n }\n\n private static createServiceRules(\n prefix: \"from\" | \"to\",\n rule: NormalizedRuleArgs,\n ports: types.input.cilium.v2.CiliumNetworkPolicySpecEgressToPorts[] | undefined,\n ): Rule[] {\n if (rule.services.length === 0) {\n return []\n }\n\n const selectors = rule.services.map(service => {\n const selector = mapServiceToLabelSelector(service)\n\n return output(selector).apply(selector => ({\n matchLabels: {\n ...mapKeys(selector.matchLabels ?? {}, key => `k8s:${key}`),\n \"k8s:io.kubernetes.pod.namespace\": service.metadata.namespace,\n },\n }))\n })\n\n return [\n {\n [`${prefix}Endpoints`]: selectors,\n toPorts: ports,\n },\n ]\n }\n\n private static createNamespaceExpressions(\n rule: NormalizedRuleArgs,\n ): k8sTypes.input.meta.v1.LabelSelectorRequirement[] {\n if (rule.namespaces.length === 0) {\n return []\n }\n\n return pipe(\n //\n rule.namespaces,\n map(mapNamespaceLikeToNamespaceName),\n names => [\n {\n key: \"k8s:io.kubernetes.pod.namespace\",\n operator: \"In\",\n values: names,\n },\n ],\n )\n }\n\n private static createSelectorRules(\n prefix: \"from\" | \"to\",\n rule: NormalizedRuleArgs,\n ports: types.input.cilium.v2.CiliumNetworkPolicySpecEgressToPorts[] | undefined,\n ): types.input.cilium.v2.CiliumNetworkPolicySpecIngress[] {\n const namespaceExpressions = CiliumNetworkPolicy.createNamespaceExpressions(rule)\n\n if (rule.selectors.length === 0) {\n if (namespaceExpressions.length === 0) {\n // if no selectors and no namespaces are provided, we do not match\n return []\n }\n\n // if no selectors are provided, we only match on namespaces\n return [\n {\n [`${prefix}Endpoints`]: [{ matchExpressions: namespaceExpressions }],\n toPorts: ports,\n },\n ]\n }\n\n // otherwise, we match on selectors and namespaces\n const selectors = rule.selectors.map(selector => {\n const rawSelector = mapSelectorLikeToSelector(selector)\n\n return output(rawSelector).apply(rawSelector => {\n const expressions = map(rawSelector.matchExpressions ?? [], expression => ({\n key: `k8s:${expression.key}`,\n operator: expression.operator,\n values: expression.values,\n }))\n\n return {\n matchLabels: mapKeys(rawSelector.matchLabels ?? {}, key => `k8s:${key}`),\n matchExpressions: [...expressions, ...namespaceExpressions],\n }\n })\n })\n\n return [\n {\n [`${prefix}Endpoints`]: uniqueBy(selectors, rule => JSON.stringify(rule)),\n toPorts: ports,\n },\n ]\n }\n\n private static mapPorts(\n ports: NetworkPolicyPort[],\n ): types.input.cilium.v2.CiliumNetworkPolicySpecEgressToPorts | undefined {\n if (ports.length === 0) {\n return\n }\n\n return {\n ports: ports.map(port => {\n if (\"port\" in port) {\n return {\n port: port.port.toString(),\n protocol: port.protocol ?? \"TCP\",\n }\n }\n\n return {\n port: port.range[0].toString(),\n endPort: port.range[1],\n protocol: port.protocol ?? \"TCP\",\n }\n }),\n }\n }\n}\n"],"mappings":"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","names":["cilium","cilium","selector","rawSelector","rule"]}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import {
|
2
|
+
cilium
|
3
|
+
} from "../chunk-M4DV2DAJ.js";
|
4
|
+
|
5
|
+
// src/unit/index.ts
|
6
|
+
import { Chart } from "@highstate/k8s";
|
7
|
+
import { k8s } from "@highstate/library";
|
8
|
+
import { forUnit, secret, toPromise } from "@highstate/pulumi";
|
9
|
+
import { l3EndpointToString } from "@highstate/common";
|
10
|
+
var { args, inputs, outputs } = forUnit(k8s.cilium);
|
11
|
+
var cluster = await toPromise(inputs.k8sCluster);
|
12
|
+
new Chart("cilium", {
|
13
|
+
cluster,
|
14
|
+
namespace: "kube-system",
|
15
|
+
chart: cilium,
|
16
|
+
values: {
|
17
|
+
ipam: {
|
18
|
+
mode: "kubernetes"
|
19
|
+
},
|
20
|
+
kubeProxyReplacement: "true",
|
21
|
+
operator: {
|
22
|
+
replicas: 1
|
23
|
+
},
|
24
|
+
hubble: {
|
25
|
+
relay: {
|
26
|
+
enabled: true
|
27
|
+
},
|
28
|
+
ui: {
|
29
|
+
enabled: true
|
30
|
+
}
|
31
|
+
},
|
32
|
+
dnsProxy: {
|
33
|
+
dnsRejectResponseCode: "nameError"
|
34
|
+
},
|
35
|
+
k8sServiceHost: l3EndpointToString(cluster.apiEndpoints[0]),
|
36
|
+
k8sServicePort: cluster.apiEndpoints[0].port.toString()
|
37
|
+
}
|
38
|
+
});
|
39
|
+
var unit_default = outputs({
|
40
|
+
k8sCluster: secret({
|
41
|
+
...cluster,
|
42
|
+
cni: "cilium",
|
43
|
+
metadata: {
|
44
|
+
...cluster.metadata,
|
45
|
+
cilium: {
|
46
|
+
allowForbiddenFqdnResolution: args.allowForbiddenFqdnResolution
|
47
|
+
}
|
48
|
+
}
|
49
|
+
})
|
50
|
+
});
|
51
|
+
export {
|
52
|
+
unit_default as default
|
53
|
+
};
|
54
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../src/unit/index.ts"],"sourcesContent":["import { Chart } from \"@highstate/k8s\"\nimport { k8s } from \"@highstate/library\"\nimport { forUnit, secret, toPromise } from \"@highstate/pulumi\"\nimport { l3EndpointToString } from \"@highstate/common\"\nimport { chart, type CiliumClusterMetadata } from \"../shared\"\n\nconst { args, inputs, outputs } = forUnit(k8s.cilium)\n\nconst cluster = await toPromise(inputs.k8sCluster)\n\nnew Chart(\"cilium\", {\n cluster,\n namespace: \"kube-system\",\n\n chart,\n\n values: {\n ipam: {\n mode: \"kubernetes\",\n },\n\n kubeProxyReplacement: \"true\",\n\n operator: {\n replicas: 1,\n },\n\n hubble: {\n relay: {\n enabled: true,\n },\n ui: {\n enabled: true,\n },\n },\n\n dnsProxy: {\n dnsRejectResponseCode: \"nameError\",\n },\n\n k8sServiceHost: l3EndpointToString(cluster.apiEndpoints[0]),\n k8sServicePort: cluster.apiEndpoints[0].port.toString(),\n },\n})\n\nexport default outputs({\n k8sCluster: secret({\n ...cluster,\n cni: \"cilium\",\n metadata: {\n ...cluster.metadata,\n cilium: {\n allowForbiddenFqdnResolution: args.allowForbiddenFqdnResolution,\n } satisfies CiliumClusterMetadata,\n },\n }),\n})\n"],"mappings":";;;;;AAAA,SAAS,aAAa;AACtB,SAAS,WAAW;AACpB,SAAS,SAAS,QAAQ,iBAAiB;AAC3C,SAAS,0BAA0B;AAGnC,IAAM,EAAE,MAAM,QAAQ,QAAQ,IAAI,QAAQ,IAAI,MAAM;AAEpD,IAAM,UAAU,MAAM,UAAU,OAAO,UAAU;AAEjD,IAAI,MAAM,UAAU;AAAA,EAClB;AAAA,EACA,WAAW;AAAA,EAEX;AAAA,EAEA,QAAQ;AAAA,IACN,MAAM;AAAA,MACJ,MAAM;AAAA,IACR;AAAA,IAEA,sBAAsB;AAAA,IAEtB,UAAU;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,IAEA,QAAQ;AAAA,MACN,OAAO;AAAA,QACL,SAAS;AAAA,MACX;AAAA,MACA,IAAI;AAAA,QACF,SAAS;AAAA,MACX;AAAA,IACF;AAAA,IAEA,UAAU;AAAA,MACR,uBAAuB;AAAA,IACzB;AAAA,IAEA,gBAAgB,mBAAmB,QAAQ,aAAa,CAAC,CAAC;AAAA,IAC1D,gBAAgB,QAAQ,aAAa,CAAC,EAAE,KAAK,SAAS;AAAA,EACxD;AACF,CAAC;AAED,IAAO,eAAQ,QAAQ;AAAA,EACrB,YAAY,OAAO;AAAA,IACjB,GAAG;AAAA,IACH,KAAK;AAAA,IACL,UAAU;AAAA,MACR,GAAG,QAAQ;AAAA,MACX,QAAQ;AAAA,QACN,8BAA8B,KAAK;AAAA,MACrC;AAAA,IACF;AAAA,EACF,CAAC;AACH,CAAC;","names":[]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@highstate/cilium",
|
3
|
-
"version": "0.9.
|
3
|
+
"version": "0.9.11",
|
4
4
|
"type": "module",
|
5
5
|
"files": [
|
6
6
|
"dist",
|
@@ -10,7 +10,8 @@
|
|
10
10
|
".": {
|
11
11
|
"types": "./src/index.ts",
|
12
12
|
"default": "./dist/index.js"
|
13
|
-
}
|
13
|
+
},
|
14
|
+
"./unit": "./dist/unit/index.js"
|
14
15
|
},
|
15
16
|
"publishConfig": {
|
16
17
|
"access": "public"
|
@@ -21,17 +22,18 @@
|
|
21
22
|
"generate-crds": "./scripts/generate-crds.sh"
|
22
23
|
},
|
23
24
|
"dependencies": {
|
24
|
-
"@highstate/cilium-crds": "^0.9.
|
25
|
-
"@highstate/
|
26
|
-
"@highstate/
|
27
|
-
"@highstate/
|
25
|
+
"@highstate/cilium-crds": "^0.9.11",
|
26
|
+
"@highstate/common": "^0.9.11",
|
27
|
+
"@highstate/k8s": "^0.9.11",
|
28
|
+
"@highstate/library": "^0.9.11",
|
29
|
+
"@highstate/pulumi": "^0.9.11",
|
28
30
|
"@pulumi/command": "^1.0.2",
|
29
31
|
"@pulumi/kubernetes": "^4.18.0",
|
30
32
|
"@pulumi/pulumi": "^3.165.0",
|
31
33
|
"remeda": "^2.21.0"
|
32
34
|
},
|
33
35
|
"devDependencies": {
|
34
|
-
"@highstate/cli": "^0.9.
|
36
|
+
"@highstate/cli": "^0.9.11"
|
35
37
|
},
|
36
|
-
"gitHead": "
|
38
|
+
"gitHead": "d62cae30ea9fadaa1aa4fb3b5734a16cf53810ce"
|
37
39
|
}
|
package/src/network-policy.ts
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import type { k8s } from "@highstate/library"
|
1
2
|
import { type ResourceOptions, type Resource, output } from "@highstate/pulumi"
|
2
3
|
import {
|
3
4
|
mapMetadata,
|
@@ -12,6 +13,7 @@ import {
|
|
12
13
|
import { cilium, types } from "@highstate/cilium-crds"
|
13
14
|
import { types as k8sTypes } from "@pulumi/kubernetes"
|
14
15
|
import { map, mapKeys, pipe, uniqueBy } from "remeda"
|
16
|
+
import { getCiliumClusterMetadata } from "./shared"
|
15
17
|
|
16
18
|
type Rule = types.input.cilium.v2.CiliumNetworkPolicySpecIngress &
|
17
19
|
types.input.cilium.v2.CiliumNetworkPolicySpecEgress
|
@@ -43,7 +45,9 @@ export class CiliumNetworkPolicy extends NetworkPolicy {
|
|
43
45
|
}
|
44
46
|
|
45
47
|
return uniqueBy(
|
46
|
-
args.ingressRules.flatMap(rule =>
|
48
|
+
args.ingressRules.flatMap(rule =>
|
49
|
+
CiliumNetworkPolicy.createRules("from", rule, args.cluster),
|
50
|
+
),
|
47
51
|
rule => JSON.stringify(rule),
|
48
52
|
)
|
49
53
|
}
|
@@ -61,13 +65,17 @@ export class CiliumNetworkPolicy extends NetworkPolicy {
|
|
61
65
|
|
62
66
|
return uniqueBy(
|
63
67
|
args.egressRules
|
64
|
-
.flatMap(rule => CiliumNetworkPolicy.createRules("to", rule))
|
68
|
+
.flatMap(rule => CiliumNetworkPolicy.createRules("to", rule, args.cluster))
|
65
69
|
.concat(extraRules),
|
66
70
|
rule => JSON.stringify(rule),
|
67
71
|
)
|
68
72
|
}
|
69
73
|
|
70
|
-
private static createRules(
|
74
|
+
private static createRules(
|
75
|
+
prefix: "from" | "to",
|
76
|
+
rule: NormalizedRuleArgs,
|
77
|
+
cluster: k8s.Cluster,
|
78
|
+
): Rule[] {
|
71
79
|
const port = CiliumNetworkPolicy.mapPorts(rule.ports)
|
72
80
|
const ports = port ? [port] : undefined
|
73
81
|
|
@@ -76,7 +84,7 @@ export class CiliumNetworkPolicy extends NetworkPolicy {
|
|
76
84
|
...CiliumNetworkPolicy.createCidrRules(prefix, rule, ports),
|
77
85
|
...CiliumNetworkPolicy.createServiceRules(prefix, rule, ports),
|
78
86
|
...CiliumNetworkPolicy.createSelectorRules(prefix, rule, ports),
|
79
|
-
...(prefix === "to" ? CiliumNetworkPolicy.createFqdnRules(rule, ports) : []),
|
87
|
+
...(prefix === "to" ? CiliumNetworkPolicy.createFqdnRules(rule, ports, cluster) : []),
|
80
88
|
]
|
81
89
|
}
|
82
90
|
|
@@ -117,6 +125,7 @@ export class CiliumNetworkPolicy extends NetworkPolicy {
|
|
117
125
|
private static createFqdnRules(
|
118
126
|
rule: NormalizedRuleArgs,
|
119
127
|
ports: types.input.cilium.v2.CiliumNetworkPolicySpecEgressToPorts[] | undefined,
|
128
|
+
cluster: k8s.Cluster,
|
120
129
|
): types.input.cilium.v2.CiliumNetworkPolicySpecEgress[] {
|
121
130
|
if (rule.fqdns.length === 0) {
|
122
131
|
return []
|
@@ -143,7 +152,11 @@ export class CiliumNetworkPolicy extends NetworkPolicy {
|
|
143
152
|
toPorts: [
|
144
153
|
{
|
145
154
|
ports: [{ port: "53", protocol: "UDP" }],
|
146
|
-
rules: {
|
155
|
+
rules: {
|
156
|
+
dns: getCiliumClusterMetadata(cluster).allowForbiddenFqdnResolution
|
157
|
+
? [{ matchPattern: "*" }]
|
158
|
+
: fqdnRules,
|
159
|
+
},
|
147
160
|
},
|
148
161
|
],
|
149
162
|
},
|
@@ -241,7 +254,7 @@ export class CiliumNetworkPolicy extends NetworkPolicy {
|
|
241
254
|
|
242
255
|
return [
|
243
256
|
{
|
244
|
-
[`${prefix}Endpoints`]: selectors,
|
257
|
+
[`${prefix}Endpoints`]: uniqueBy(selectors, rule => JSON.stringify(rule)),
|
245
258
|
toPorts: ports,
|
246
259
|
},
|
247
260
|
]
|
package/src/shared.ts
CHANGED
@@ -1 +1,24 @@
|
|
1
|
+
import type { k8s } from "@highstate/library"
|
2
|
+
|
1
3
|
export { cilium as chart } from "../assets/charts.json"
|
4
|
+
|
5
|
+
export type CiliumClusterMetadata = {
|
6
|
+
/**
|
7
|
+
* If set to `true`, the generated network policy will allow
|
8
|
+
* all DNS queries to be resolved, even if they are
|
9
|
+
* for forbidden (non-allowed) FQDNs.
|
10
|
+
*
|
11
|
+
* By default, is not set.
|
12
|
+
*/
|
13
|
+
allowForbiddenFqdnResolution?: boolean
|
14
|
+
}
|
15
|
+
|
16
|
+
export function getCiliumClusterMetadata(cluster: k8s.Cluster): CiliumClusterMetadata {
|
17
|
+
return cluster.metadata?.cilium ?? {}
|
18
|
+
}
|
19
|
+
|
20
|
+
export function hasCiliumClusterMetadata(
|
21
|
+
cluster: k8s.Cluster,
|
22
|
+
): cluster is k8s.Cluster & { metadata: { cilium: CiliumClusterMetadata } } {
|
23
|
+
return Boolean(cluster.metadata?.cilium)
|
24
|
+
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
import { Chart } from "@highstate/k8s"
|
2
|
+
import { k8s } from "@highstate/library"
|
3
|
+
import { forUnit, secret, toPromise } from "@highstate/pulumi"
|
4
|
+
import { l3EndpointToString } from "@highstate/common"
|
5
|
+
import { chart, type CiliumClusterMetadata } from "../shared"
|
6
|
+
|
7
|
+
const { args, inputs, outputs } = forUnit(k8s.cilium)
|
8
|
+
|
9
|
+
const cluster = await toPromise(inputs.k8sCluster)
|
10
|
+
|
11
|
+
new Chart("cilium", {
|
12
|
+
cluster,
|
13
|
+
namespace: "kube-system",
|
14
|
+
|
15
|
+
chart,
|
16
|
+
|
17
|
+
values: {
|
18
|
+
ipam: {
|
19
|
+
mode: "kubernetes",
|
20
|
+
},
|
21
|
+
|
22
|
+
kubeProxyReplacement: "true",
|
23
|
+
|
24
|
+
operator: {
|
25
|
+
replicas: 1,
|
26
|
+
},
|
27
|
+
|
28
|
+
hubble: {
|
29
|
+
relay: {
|
30
|
+
enabled: true,
|
31
|
+
},
|
32
|
+
ui: {
|
33
|
+
enabled: true,
|
34
|
+
},
|
35
|
+
},
|
36
|
+
|
37
|
+
dnsProxy: {
|
38
|
+
dnsRejectResponseCode: "nameError",
|
39
|
+
},
|
40
|
+
|
41
|
+
k8sServiceHost: l3EndpointToString(cluster.apiEndpoints[0]),
|
42
|
+
k8sServicePort: cluster.apiEndpoints[0].port.toString(),
|
43
|
+
},
|
44
|
+
})
|
45
|
+
|
46
|
+
export default outputs({
|
47
|
+
k8sCluster: secret({
|
48
|
+
...cluster,
|
49
|
+
cni: "cilium",
|
50
|
+
metadata: {
|
51
|
+
...cluster.metadata,
|
52
|
+
cilium: {
|
53
|
+
allowForbiddenFqdnResolution: args.allowForbiddenFqdnResolution,
|
54
|
+
} satisfies CiliumClusterMetadata,
|
55
|
+
},
|
56
|
+
}),
|
57
|
+
})
|