timonel 0.4.0 → 1.0.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/CHANGELOG.md +33 -0
- package/README.md +234 -0
- package/dist/cli.js +32 -72
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -20
- package/dist/index.js.map +1 -1
- package/dist/lib/HelmChartWriter.js +7 -47
- package/dist/lib/HelmChartWriter.js.map +1 -1
- package/dist/lib/Rutter.d.ts +99 -1
- package/dist/lib/Rutter.d.ts.map +1 -1
- package/dist/lib/Rutter.js +228 -49
- package/dist/lib/Rutter.js.map +1 -1
- package/dist/lib/UmbrellaRutter.d.ts +2 -2
- package/dist/lib/UmbrellaRutter.d.ts.map +1 -1
- package/dist/lib/UmbrellaRutter.js +12 -20
- package/dist/lib/UmbrellaRutter.js.map +1 -1
- package/dist/lib/helm.js +11 -24
- package/dist/lib/helm.js.map +1 -1
- package/dist/lib/umbrella.d.ts +2 -2
- package/dist/lib/umbrella.d.ts.map +1 -1
- package/dist/lib/umbrella.js +3 -6
- package/dist/lib/umbrella.js.map +1 -1
- package/package.json +16 -8
package/dist/lib/Rutter.js
CHANGED
|
@@ -1,23 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.Rutter = void 0;
|
|
7
|
-
const cdk8s_1 = require("cdk8s");
|
|
8
|
-
const yaml_1 = __importDefault(require("yaml"));
|
|
9
|
-
const helm_1 = require("./helm");
|
|
10
|
-
const HelmChartWriter_1 = require("./HelmChartWriter");
|
|
1
|
+
import { App, Chart, Testing, ApiObject } from 'cdk8s';
|
|
2
|
+
import YAML from 'yaml';
|
|
3
|
+
import { include, helm } from './helm.js';
|
|
4
|
+
import { HelmChartWriter } from './HelmChartWriter.js';
|
|
11
5
|
/**
|
|
12
6
|
* Rutter builds Kubernetes manifests using cdk8s and writes a Helm chart.
|
|
13
7
|
*/
|
|
14
|
-
class Rutter {
|
|
8
|
+
export class Rutter {
|
|
15
9
|
constructor(props) {
|
|
16
10
|
this.assets = [];
|
|
17
11
|
this.valueOverrides = {};
|
|
18
12
|
this.props = props;
|
|
19
|
-
this.app = new
|
|
20
|
-
this.chart = new
|
|
13
|
+
this.app = new App();
|
|
14
|
+
this.chart = new Chart(this.app, props.manifestName ?? props.meta.name);
|
|
21
15
|
}
|
|
22
16
|
/**
|
|
23
17
|
* Set dynamic value overrides (from --set flags)
|
|
@@ -68,8 +62,8 @@ class Rutter {
|
|
|
68
62
|
}
|
|
69
63
|
addDeployment(spec) {
|
|
70
64
|
const match = spec.matchLabels ?? {
|
|
71
|
-
[Rutter.LABEL_NAME]:
|
|
72
|
-
[Rutter.LABEL_INSTANCE]:
|
|
65
|
+
[Rutter.LABEL_NAME]: include(Rutter.HELPER_NAME),
|
|
66
|
+
[Rutter.LABEL_INSTANCE]: helm.releaseName,
|
|
73
67
|
};
|
|
74
68
|
const envEntries = spec.env
|
|
75
69
|
? Object.entries(spec.env).map(([name, value]) => ({ name, value }))
|
|
@@ -99,7 +93,7 @@ class Rutter {
|
|
|
99
93
|
}))
|
|
100
94
|
: undefined;
|
|
101
95
|
const templateLabels = { ...match, ...(spec.podLabels ?? {}) };
|
|
102
|
-
const dep = new
|
|
96
|
+
const dep = new ApiObject(this.chart, spec.name, {
|
|
103
97
|
apiVersion: 'apps/v1',
|
|
104
98
|
kind: 'Deployment',
|
|
105
99
|
metadata: {
|
|
@@ -140,7 +134,7 @@ class Rutter {
|
|
|
140
134
|
return dep;
|
|
141
135
|
}
|
|
142
136
|
addService(spec) {
|
|
143
|
-
const svc = new
|
|
137
|
+
const svc = new ApiObject(this.chart, spec.name, {
|
|
144
138
|
apiVersion: 'v1',
|
|
145
139
|
kind: 'Service',
|
|
146
140
|
metadata: {
|
|
@@ -175,8 +169,8 @@ class Rutter {
|
|
|
175
169
|
}
|
|
176
170
|
addReplicaSet(spec) {
|
|
177
171
|
const match = spec.matchLabels ?? {
|
|
178
|
-
[Rutter.LABEL_NAME]:
|
|
179
|
-
[Rutter.LABEL_INSTANCE]:
|
|
172
|
+
[Rutter.LABEL_NAME]: include(Rutter.HELPER_NAME),
|
|
173
|
+
[Rutter.LABEL_INSTANCE]: helm.releaseName,
|
|
180
174
|
};
|
|
181
175
|
const envEntries = spec.env
|
|
182
176
|
? Object.entries(spec.env).map(([name, value]) => ({ name, value }))
|
|
@@ -206,7 +200,7 @@ class Rutter {
|
|
|
206
200
|
}))
|
|
207
201
|
: undefined;
|
|
208
202
|
const templateLabels = { ...match, ...(spec.podLabels ?? {}) };
|
|
209
|
-
const rs = new
|
|
203
|
+
const rs = new ApiObject(this.chart, spec.name, {
|
|
210
204
|
apiVersion: 'apps/v1',
|
|
211
205
|
kind: 'ReplicaSet',
|
|
212
206
|
metadata: {
|
|
@@ -247,8 +241,8 @@ class Rutter {
|
|
|
247
241
|
return rs;
|
|
248
242
|
}
|
|
249
243
|
addIngress(spec) {
|
|
250
|
-
const ing = new
|
|
251
|
-
apiVersion:
|
|
244
|
+
const ing = new ApiObject(this.chart, spec.name, {
|
|
245
|
+
apiVersion: Rutter.NETWORKING_API_VERSION,
|
|
252
246
|
kind: 'Ingress',
|
|
253
247
|
metadata: {
|
|
254
248
|
name: spec.name,
|
|
@@ -321,7 +315,7 @@ class Rutter {
|
|
|
321
315
|
pvSpec[key] = value;
|
|
322
316
|
}
|
|
323
317
|
}
|
|
324
|
-
const pv = new
|
|
318
|
+
const pv = new ApiObject(this.chart, spec.name, {
|
|
325
319
|
apiVersion: 'v1',
|
|
326
320
|
kind: 'PersistentVolume',
|
|
327
321
|
metadata: {
|
|
@@ -378,7 +372,7 @@ class Rutter {
|
|
|
378
372
|
addPersistentVolumeClaim(spec) {
|
|
379
373
|
// Validate access modes compatibility
|
|
380
374
|
this.validatePVCAccessModes(spec);
|
|
381
|
-
const pvc = new
|
|
375
|
+
const pvc = new ApiObject(this.chart, spec.name, {
|
|
382
376
|
apiVersion: 'v1',
|
|
383
377
|
kind: 'PersistentVolumeClaim',
|
|
384
378
|
metadata: {
|
|
@@ -413,7 +407,7 @@ class Rutter {
|
|
|
413
407
|
}
|
|
414
408
|
}
|
|
415
409
|
addConfigMap(spec) {
|
|
416
|
-
const cm = new
|
|
410
|
+
const cm = new ApiObject(this.chart, spec.name, {
|
|
417
411
|
apiVersion: 'v1',
|
|
418
412
|
kind: 'ConfigMap',
|
|
419
413
|
metadata: {
|
|
@@ -429,7 +423,7 @@ class Rutter {
|
|
|
429
423
|
return cm;
|
|
430
424
|
}
|
|
431
425
|
addSecret(spec) {
|
|
432
|
-
const sec = new
|
|
426
|
+
const sec = new ApiObject(this.chart, spec.name, {
|
|
433
427
|
apiVersion: 'v1',
|
|
434
428
|
kind: 'Secret',
|
|
435
429
|
metadata: {
|
|
@@ -447,7 +441,7 @@ class Rutter {
|
|
|
447
441
|
}
|
|
448
442
|
addServiceAccount(spec) {
|
|
449
443
|
const annotations = this.buildServiceAccountAnnotations(spec);
|
|
450
|
-
const sa = new
|
|
444
|
+
const sa = new ApiObject(this.chart, spec.name, {
|
|
451
445
|
apiVersion: 'v1',
|
|
452
446
|
kind: 'ServiceAccount',
|
|
453
447
|
metadata: {
|
|
@@ -515,7 +509,7 @@ class Rutter {
|
|
|
515
509
|
},
|
|
516
510
|
},
|
|
517
511
|
];
|
|
518
|
-
const hpa = new
|
|
512
|
+
const hpa = new ApiObject(this.chart, spec.name, {
|
|
519
513
|
apiVersion: 'autoscaling/v2',
|
|
520
514
|
kind: 'HorizontalPodAutoscaler',
|
|
521
515
|
metadata: {
|
|
@@ -535,7 +529,7 @@ class Rutter {
|
|
|
535
529
|
return hpa;
|
|
536
530
|
}
|
|
537
531
|
addVerticalPodAutoscaler(spec) {
|
|
538
|
-
const vpa = new
|
|
532
|
+
const vpa = new ApiObject(this.chart, spec.name, {
|
|
539
533
|
apiVersion: 'autoscaling.k8s.io/v1',
|
|
540
534
|
kind: 'VerticalPodAutoscaler',
|
|
541
535
|
metadata: {
|
|
@@ -554,7 +548,7 @@ class Rutter {
|
|
|
554
548
|
return vpa;
|
|
555
549
|
}
|
|
556
550
|
addPodDisruptionBudget(spec) {
|
|
557
|
-
const pdb = new
|
|
551
|
+
const pdb = new ApiObject(this.chart, spec.name, {
|
|
558
552
|
apiVersion: 'policy/v1',
|
|
559
553
|
kind: 'PodDisruptionBudget',
|
|
560
554
|
metadata: {
|
|
@@ -588,7 +582,7 @@ class Rutter {
|
|
|
588
582
|
if (spec.throughput && spec.volumeType === DEFAULT_VOLUME_TYPE) {
|
|
589
583
|
parameters['throughput'] = String(spec.throughput);
|
|
590
584
|
}
|
|
591
|
-
const sc = new
|
|
585
|
+
const sc = new ApiObject(this.chart, spec.name, {
|
|
592
586
|
apiVersion: 'storage.k8s.io/v1',
|
|
593
587
|
kind: 'StorageClass',
|
|
594
588
|
metadata: {
|
|
@@ -606,7 +600,7 @@ class Rutter {
|
|
|
606
600
|
return sc;
|
|
607
601
|
}
|
|
608
602
|
addAWSEBSPersistentVolumeClaim(spec) {
|
|
609
|
-
const pvc = new
|
|
603
|
+
const pvc = new ApiObject(this.chart, spec.name, {
|
|
610
604
|
apiVersion: 'v1',
|
|
611
605
|
kind: 'PersistentVolumeClaim',
|
|
612
606
|
metadata: {
|
|
@@ -628,7 +622,7 @@ class Rutter {
|
|
|
628
622
|
return pvc;
|
|
629
623
|
}
|
|
630
624
|
addAWSEFSStorageClass(spec) {
|
|
631
|
-
const sc = new
|
|
625
|
+
const sc = new ApiObject(this.chart, spec.name, {
|
|
632
626
|
apiVersion: 'storage.k8s.io/v1',
|
|
633
627
|
kind: 'StorageClass',
|
|
634
628
|
metadata: {
|
|
@@ -670,7 +664,7 @@ class Rutter {
|
|
|
670
664
|
if (Object.keys(volumeAttributes).length > 0) {
|
|
671
665
|
csiSpec['volumeAttributes'] = volumeAttributes;
|
|
672
666
|
}
|
|
673
|
-
const pv = new
|
|
667
|
+
const pv = new ApiObject(this.chart, spec.name, {
|
|
674
668
|
apiVersion: 'v1',
|
|
675
669
|
kind: 'PersistentVolume',
|
|
676
670
|
metadata: {
|
|
@@ -692,7 +686,7 @@ class Rutter {
|
|
|
692
686
|
return pv;
|
|
693
687
|
}
|
|
694
688
|
addAWSEFSPersistentVolumeClaim(spec) {
|
|
695
|
-
const pvc = new
|
|
689
|
+
const pvc = new ApiObject(this.chart, spec.name, {
|
|
696
690
|
apiVersion: 'v1',
|
|
697
691
|
kind: 'PersistentVolumeClaim',
|
|
698
692
|
metadata: {
|
|
@@ -715,8 +709,8 @@ class Rutter {
|
|
|
715
709
|
}
|
|
716
710
|
addAWSALBIngress(spec) {
|
|
717
711
|
const annotations = this.buildALBAnnotations(spec);
|
|
718
|
-
const ingress = new
|
|
719
|
-
apiVersion:
|
|
712
|
+
const ingress = new ApiObject(this.chart, spec.name, {
|
|
713
|
+
apiVersion: Rutter.NETWORKING_API_VERSION,
|
|
720
714
|
kind: 'Ingress',
|
|
721
715
|
metadata: {
|
|
722
716
|
name: spec.name,
|
|
@@ -812,7 +806,7 @@ class Rutter {
|
|
|
812
806
|
: {}),
|
|
813
807
|
...(spec.annotations ?? {}),
|
|
814
808
|
};
|
|
815
|
-
const sa = new
|
|
809
|
+
const sa = new ApiObject(this.chart, spec.name, {
|
|
816
810
|
apiVersion: 'v1',
|
|
817
811
|
kind: 'ServiceAccount',
|
|
818
812
|
metadata: {
|
|
@@ -841,14 +835,14 @@ class Rutter {
|
|
|
841
835
|
}
|
|
842
836
|
return baseObj;
|
|
843
837
|
});
|
|
844
|
-
const objectsYaml =
|
|
838
|
+
const objectsYaml = YAML.stringify(objects, { indent: 2 }).trim();
|
|
845
839
|
const parameters = {
|
|
846
840
|
objects: `|\n ${objectsYaml.split('\n').join('\n ')}`,
|
|
847
841
|
};
|
|
848
842
|
if (spec.region) {
|
|
849
843
|
parameters['region'] = spec.region;
|
|
850
844
|
}
|
|
851
|
-
const spc = new
|
|
845
|
+
const spc = new ApiObject(this.chart, spec.name, {
|
|
852
846
|
apiVersion: 'secrets-store.csi.x-k8s.io/v1',
|
|
853
847
|
kind: 'SecretProviderClass',
|
|
854
848
|
metadata: {
|
|
@@ -864,6 +858,190 @@ class Rutter {
|
|
|
864
858
|
this.capture(spc, `${spec.name}-secretproviderclass`);
|
|
865
859
|
return spc;
|
|
866
860
|
}
|
|
861
|
+
addNetworkPolicy(spec) {
|
|
862
|
+
// Validate policy types
|
|
863
|
+
this.validateNetworkPolicyTypes(spec);
|
|
864
|
+
// Validate CIDR blocks if present
|
|
865
|
+
this.validateNetworkPolicyCIDRs(spec);
|
|
866
|
+
const np = new ApiObject(this.chart, spec.name, {
|
|
867
|
+
apiVersion: Rutter.NETWORKING_API_VERSION,
|
|
868
|
+
kind: 'NetworkPolicy',
|
|
869
|
+
metadata: {
|
|
870
|
+
name: spec.name,
|
|
871
|
+
...(spec.labels ? { labels: spec.labels } : {}),
|
|
872
|
+
...(spec.annotations ? { annotations: spec.annotations } : {}),
|
|
873
|
+
},
|
|
874
|
+
spec: {
|
|
875
|
+
podSelector: spec.podSelector ?? {},
|
|
876
|
+
policyTypes: spec.policyTypes,
|
|
877
|
+
...(spec.ingress ? { ingress: spec.ingress } : {}),
|
|
878
|
+
...(spec.egress ? { egress: spec.egress } : {}),
|
|
879
|
+
},
|
|
880
|
+
});
|
|
881
|
+
this.capture(np, `${spec.name}-networkpolicy`);
|
|
882
|
+
return np;
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Create a deny-all ingress NetworkPolicy for the current namespace
|
|
886
|
+
*/
|
|
887
|
+
addDenyAllIngressNetworkPolicy(name = 'deny-all-ingress') {
|
|
888
|
+
return this.addNetworkPolicy({
|
|
889
|
+
name,
|
|
890
|
+
podSelector: Rutter.EMPTY_POD_SELECTOR,
|
|
891
|
+
policyTypes: ['Ingress'],
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
/**
|
|
895
|
+
* Create a deny-all egress NetworkPolicy for the current namespace
|
|
896
|
+
*/
|
|
897
|
+
addDenyAllEgressNetworkPolicy(name = 'deny-all-egress') {
|
|
898
|
+
return this.addNetworkPolicy({
|
|
899
|
+
name,
|
|
900
|
+
podSelector: Rutter.EMPTY_POD_SELECTOR,
|
|
901
|
+
policyTypes: ['Egress'],
|
|
902
|
+
});
|
|
903
|
+
}
|
|
904
|
+
/**
|
|
905
|
+
* Create a deny-all NetworkPolicy for both ingress and egress
|
|
906
|
+
*/
|
|
907
|
+
addDenyAllNetworkPolicy(name = 'deny-all') {
|
|
908
|
+
return this.addNetworkPolicy({
|
|
909
|
+
name,
|
|
910
|
+
podSelector: Rutter.EMPTY_POD_SELECTOR,
|
|
911
|
+
policyTypes: ['Ingress', 'Egress'],
|
|
912
|
+
});
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* Allow traffic from specific pods to target pods on specific ports
|
|
916
|
+
*/
|
|
917
|
+
addAllowFromPodsNetworkPolicy(spec) {
|
|
918
|
+
return this.addNetworkPolicy({
|
|
919
|
+
name: spec.name,
|
|
920
|
+
podSelector: { matchLabels: spec.targetPodSelector },
|
|
921
|
+
policyTypes: ['Ingress'],
|
|
922
|
+
ingress: [
|
|
923
|
+
{
|
|
924
|
+
from: [{ podSelector: { matchLabels: spec.sourcePodSelector } }],
|
|
925
|
+
...(spec.ports ? { ports: spec.ports } : {}),
|
|
926
|
+
},
|
|
927
|
+
],
|
|
928
|
+
...(spec.labels ? { labels: spec.labels } : {}),
|
|
929
|
+
...(spec.annotations ? { annotations: spec.annotations } : {}),
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
/**
|
|
933
|
+
* Allow traffic from specific namespace to target pods
|
|
934
|
+
*/
|
|
935
|
+
addAllowFromNamespaceNetworkPolicy(spec) {
|
|
936
|
+
return this.addNetworkPolicy({
|
|
937
|
+
name: spec.name,
|
|
938
|
+
podSelector: { matchLabels: spec.targetPodSelector },
|
|
939
|
+
policyTypes: ['Ingress'],
|
|
940
|
+
ingress: [
|
|
941
|
+
{
|
|
942
|
+
from: [{ namespaceSelector: { matchLabels: spec.sourceNamespaceSelector } }],
|
|
943
|
+
...(spec.ports ? { ports: spec.ports } : {}),
|
|
944
|
+
},
|
|
945
|
+
],
|
|
946
|
+
...(spec.labels ? { labels: spec.labels } : {}),
|
|
947
|
+
...(spec.annotations ? { annotations: spec.annotations } : {}),
|
|
948
|
+
});
|
|
949
|
+
}
|
|
950
|
+
validateNetworkPolicyTypes(spec) {
|
|
951
|
+
if (!spec.policyTypes || spec.policyTypes.length === 0) {
|
|
952
|
+
throw new Error(`NetworkPolicy ${spec.name}: policyTypes must be specified`);
|
|
953
|
+
}
|
|
954
|
+
this.validatePolicyTypeValues(spec);
|
|
955
|
+
this.validatePolicyTypeRules(spec);
|
|
956
|
+
}
|
|
957
|
+
validatePolicyTypeValues(spec) {
|
|
958
|
+
const validTypes = ['Ingress', 'Egress'];
|
|
959
|
+
for (const type of spec.policyTypes) {
|
|
960
|
+
if (!validTypes.includes(type)) {
|
|
961
|
+
throw new Error(`NetworkPolicy ${spec.name}: invalid policyType '${type}', must be 'Ingress' or 'Egress'`);
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
validatePolicyTypeRules(spec) {
|
|
966
|
+
if (spec.policyTypes.includes('Ingress') && spec.ingress === undefined) {
|
|
967
|
+
console.warn(`NetworkPolicy ${spec.name}: policyType 'Ingress' specified but no ingress rules defined (will deny all ingress)`);
|
|
968
|
+
}
|
|
969
|
+
if (spec.policyTypes.includes('Egress') && spec.egress === undefined) {
|
|
970
|
+
console.warn(`NetworkPolicy ${spec.name}: policyType 'Egress' specified but no egress rules defined (will deny all egress)`);
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
validateNetworkPolicyCIDRs(spec) {
|
|
974
|
+
const validateCIDR = (cidr, context) => {
|
|
975
|
+
if (!this.isValidCIDR(cidr)) {
|
|
976
|
+
throw new Error(`NetworkPolicy ${spec.name}: invalid CIDR '${cidr}' in ${context}`);
|
|
977
|
+
}
|
|
978
|
+
};
|
|
979
|
+
this.validateIngressCIDRs(spec, validateCIDR);
|
|
980
|
+
this.validateEgressCIDRs(spec, validateCIDR);
|
|
981
|
+
}
|
|
982
|
+
isValidCIDR(cidr) {
|
|
983
|
+
// IPv4 CIDR validation
|
|
984
|
+
const ipv4Parts = cidr.split('/');
|
|
985
|
+
if (ipv4Parts.length === 2) {
|
|
986
|
+
const [ip, prefix] = ipv4Parts;
|
|
987
|
+
if (ip && prefix && this.isValidIPv4(ip) && this.isValidPrefix(prefix, 32)) {
|
|
988
|
+
return true;
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
// IPv6 CIDR validation (basic)
|
|
992
|
+
if (cidr.includes(':') && ipv4Parts.length === 2) {
|
|
993
|
+
const [, prefix] = ipv4Parts;
|
|
994
|
+
if (prefix) {
|
|
995
|
+
return this.isValidPrefix(prefix, 128);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
return false;
|
|
999
|
+
}
|
|
1000
|
+
isValidIPv4(ip) {
|
|
1001
|
+
const parts = ip.split('.');
|
|
1002
|
+
if (parts.length !== 4)
|
|
1003
|
+
return false;
|
|
1004
|
+
return parts.every((part) => {
|
|
1005
|
+
const num = parseInt(part, 10);
|
|
1006
|
+
return !isNaN(num) && num >= 0 && num <= 255 && String(num) === part;
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
isValidPrefix(prefix, maxPrefix) {
|
|
1010
|
+
const num = parseInt(prefix, 10);
|
|
1011
|
+
return !isNaN(num) && num >= 0 && num <= maxPrefix && String(num) === prefix;
|
|
1012
|
+
}
|
|
1013
|
+
validateIngressCIDRs(spec, validateCIDR) {
|
|
1014
|
+
if (!spec.ingress)
|
|
1015
|
+
return;
|
|
1016
|
+
for (const rule of spec.ingress) {
|
|
1017
|
+
if (rule.from) {
|
|
1018
|
+
for (const peer of rule.from) {
|
|
1019
|
+
this.validatePeerCIDRs(peer, validateCIDR, 'ingress rule');
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
validateEgressCIDRs(spec, validateCIDR) {
|
|
1025
|
+
if (!spec.egress)
|
|
1026
|
+
return;
|
|
1027
|
+
for (const rule of spec.egress) {
|
|
1028
|
+
if (rule.to) {
|
|
1029
|
+
for (const peer of rule.to) {
|
|
1030
|
+
this.validatePeerCIDRs(peer, validateCIDR, 'egress rule');
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
validatePeerCIDRs(peer, validateCIDR, context) {
|
|
1036
|
+
if (peer.ipBlock?.cidr) {
|
|
1037
|
+
validateCIDR(peer.ipBlock.cidr, context);
|
|
1038
|
+
if (peer.ipBlock.except) {
|
|
1039
|
+
for (const except of peer.ipBlock.except) {
|
|
1040
|
+
validateCIDR(except, `${context} except block`);
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
867
1045
|
/**
|
|
868
1046
|
* Capture the YAML of an ApiObject or Construct into assets.
|
|
869
1047
|
*/
|
|
@@ -898,7 +1076,7 @@ class Rutter {
|
|
|
898
1076
|
*/
|
|
899
1077
|
write(outDir) {
|
|
900
1078
|
// Use cdk8s Testing.synth to obtain manifest objects
|
|
901
|
-
const manifestObjs =
|
|
1079
|
+
const manifestObjs = Testing.synth(this.chart);
|
|
902
1080
|
// Enforce common labels best-practice on all rendered objects
|
|
903
1081
|
const enriched = manifestObjs.map((obj) => {
|
|
904
1082
|
if (obj && typeof obj === 'object') {
|
|
@@ -908,11 +1086,11 @@ class Rutter {
|
|
|
908
1086
|
const labels = o.metadata.labels;
|
|
909
1087
|
const defaults = {
|
|
910
1088
|
'helm.sh/chart': '{{ .Chart.Name }}-{{ .Chart.Version }}',
|
|
911
|
-
'app.kubernetes.io/name':
|
|
912
|
-
'app.kubernetes.io/instance':
|
|
913
|
-
'app.kubernetes.io/version':
|
|
1089
|
+
'app.kubernetes.io/name': include(Rutter.HELPER_NAME),
|
|
1090
|
+
'app.kubernetes.io/instance': helm.releaseName,
|
|
1091
|
+
'app.kubernetes.io/version': helm.chartVersion,
|
|
914
1092
|
'app.kubernetes.io/managed-by': '{{ .Release.Service }}',
|
|
915
|
-
'app.kubernetes.io/part-of':
|
|
1093
|
+
'app.kubernetes.io/part-of': helm.chartName,
|
|
916
1094
|
};
|
|
917
1095
|
for (const [k, v] of Object.entries(defaults)) {
|
|
918
1096
|
if (!(k in labels)) {
|
|
@@ -926,7 +1104,7 @@ class Rutter {
|
|
|
926
1104
|
if (this.props.singleManifestFile) {
|
|
927
1105
|
// Combine all resources into a single manifest file
|
|
928
1106
|
const combinedYaml = enriched
|
|
929
|
-
.map((obj) =>
|
|
1107
|
+
.map((obj) => YAML.stringify(obj).trim())
|
|
930
1108
|
.filter(Boolean)
|
|
931
1109
|
.join('\n---\n');
|
|
932
1110
|
this.assets.length = 0;
|
|
@@ -937,7 +1115,7 @@ class Rutter {
|
|
|
937
1115
|
// Create separate files for each resource (default behavior)
|
|
938
1116
|
this.assets.length = 0;
|
|
939
1117
|
enriched.forEach((obj, _index) => {
|
|
940
|
-
const yaml =
|
|
1118
|
+
const yaml = YAML.stringify(obj).trim();
|
|
941
1119
|
if (yaml) {
|
|
942
1120
|
const resourceName = this.getResourceName(obj);
|
|
943
1121
|
const manifestId = this.props.manifestName
|
|
@@ -994,11 +1172,12 @@ class Rutter {
|
|
|
994
1172
|
...(this.props.notesTpl !== undefined ? { notesTpl: this.props.notesTpl } : {}),
|
|
995
1173
|
...(this.props.valuesSchema !== undefined ? { valuesSchema: this.props.valuesSchema } : {}),
|
|
996
1174
|
};
|
|
997
|
-
|
|
1175
|
+
HelmChartWriter.write(options);
|
|
998
1176
|
}
|
|
999
1177
|
}
|
|
1000
|
-
exports.Rutter = Rutter;
|
|
1001
1178
|
Rutter.LABEL_NAME = 'app.kubernetes.io/name';
|
|
1002
1179
|
Rutter.LABEL_INSTANCE = 'app.kubernetes.io/instance';
|
|
1003
1180
|
Rutter.HELPER_NAME = 'timonel.name';
|
|
1181
|
+
Rutter.NETWORKING_API_VERSION = 'networking.k8s.io/v1';
|
|
1182
|
+
Rutter.EMPTY_POD_SELECTOR = {};
|
|
1004
1183
|
//# sourceMappingURL=Rutter.js.map
|