timonel 2.8.0-beta.5 → 2.8.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 +9 -25
- package/README.md +12 -55
- package/dist/cli.d.ts.map +1 -0
- package/dist/{src/cli.js → cli.js} +4 -35
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/{src/lib → lib}/helm.d.ts +234 -4
- package/dist/lib/helm.d.ts.map +1 -0
- package/dist/{src/lib → lib}/helm.js +309 -20
- package/dist/lib/helm.js.map +1 -0
- package/dist/lib/helmChartWriter.d.ts.map +1 -0
- package/dist/{src/lib → lib}/helmChartWriter.js +5 -19
- package/dist/lib/helmChartWriter.js.map +1 -0
- package/dist/{src/lib → lib}/resources/baseResourceProvider.d.ts +1 -1
- package/dist/lib/resources/baseResourceProvider.d.ts.map +1 -0
- package/dist/lib/resources/baseResourceProvider.js.map +1 -0
- package/dist/{src/lib → lib}/resources/cloud/aws/awsResources.d.ts +5 -14
- package/dist/lib/resources/cloud/aws/awsResources.d.ts.map +1 -0
- package/dist/{src/lib → lib}/resources/cloud/aws/awsResources.js +63 -78
- package/dist/lib/resources/cloud/aws/awsResources.js.map +1 -0
- package/dist/lib/resources/cloud/aws/karpenterResources.d.ts.map +1 -0
- package/dist/lib/resources/cloud/aws/karpenterResources.js.map +1 -0
- package/dist/lib/rutter.d.ts +445 -0
- package/dist/lib/rutter.d.ts.map +1 -0
- package/dist/lib/rutter.js +585 -0
- package/dist/lib/rutter.js.map +1 -0
- package/dist/{src/lib → lib}/security.d.ts +2 -72
- package/dist/lib/security.d.ts.map +1 -0
- package/dist/lib/security.js +390 -0
- package/dist/lib/security.js.map +1 -0
- package/dist/lib/umbrella.d.ts.map +1 -0
- package/dist/lib/umbrella.js.map +1 -0
- package/dist/{src/lib → lib}/umbrellaRutter.d.ts +1 -1
- package/dist/lib/umbrellaRutter.d.ts.map +1 -0
- package/dist/lib/umbrellaRutter.js.map +1 -0
- package/dist/{src/lib → lib}/utils/helmHelpers.d.ts +2 -12
- package/dist/lib/utils/helmHelpers.d.ts.map +1 -0
- package/dist/{src/lib → lib}/utils/helmHelpers.js +2 -46
- package/dist/lib/utils/helmHelpers.js.map +1 -0
- package/package.json +3 -4
- package/dist/src/cli.d.ts.map +0 -1
- package/dist/src/cli.js.map +0 -1
- package/dist/src/index.d.ts +0 -23
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js +0 -15
- package/dist/src/index.js.map +0 -1
- package/dist/src/lib/constants.d.ts +0 -142
- package/dist/src/lib/constants.d.ts.map +0 -1
- package/dist/src/lib/constants.js +0 -167
- package/dist/src/lib/constants.js.map +0 -1
- package/dist/src/lib/helm.d.ts.map +0 -1
- package/dist/src/lib/helm.js.map +0 -1
- package/dist/src/lib/helmChartWriter.d.ts.map +0 -1
- package/dist/src/lib/helmChartWriter.js.map +0 -1
- package/dist/src/lib/resources/autoscaling/autoscalingResources.d.ts +0 -248
- package/dist/src/lib/resources/autoscaling/autoscalingResources.d.ts.map +0 -1
- package/dist/src/lib/resources/autoscaling/autoscalingResources.js +0 -81
- package/dist/src/lib/resources/autoscaling/autoscalingResources.js.map +0 -1
- package/dist/src/lib/resources/baseResourceProvider.d.ts.map +0 -1
- package/dist/src/lib/resources/baseResourceProvider.js.map +0 -1
- package/dist/src/lib/resources/cloud/aws/awsResources.d.ts.map +0 -1
- package/dist/src/lib/resources/cloud/aws/awsResources.js.map +0 -1
- package/dist/src/lib/resources/cloud/aws/karpenterResources.d.ts.map +0 -1
- package/dist/src/lib/resources/cloud/aws/karpenterResources.js.map +0 -1
- package/dist/src/lib/resources/cloud/azure/azureResources.d.ts +0 -169
- package/dist/src/lib/resources/cloud/azure/azureResources.d.ts.map +0 -1
- package/dist/src/lib/resources/cloud/azure/azureResources.js +0 -218
- package/dist/src/lib/resources/cloud/azure/azureResources.js.map +0 -1
- package/dist/src/lib/resources/cloud/gcp/gcpResources.d.ts +0 -164
- package/dist/src/lib/resources/cloud/gcp/gcpResources.d.ts.map +0 -1
- package/dist/src/lib/resources/cloud/gcp/gcpResources.js +0 -192
- package/dist/src/lib/resources/cloud/gcp/gcpResources.js.map +0 -1
- package/dist/src/lib/resources/core/coreResources.d.ts +0 -790
- package/dist/src/lib/resources/core/coreResources.d.ts.map +0 -1
- package/dist/src/lib/resources/core/coreResources.js +0 -1115
- package/dist/src/lib/resources/core/coreResources.js.map +0 -1
- package/dist/src/lib/resources/core/storageResources.d.ts +0 -133
- package/dist/src/lib/resources/core/storageResources.d.ts.map +0 -1
- package/dist/src/lib/resources/core/storageResources.js +0 -120
- package/dist/src/lib/resources/core/storageResources.js.map +0 -1
- package/dist/src/lib/resources/network/networkResources.d.ts +0 -515
- package/dist/src/lib/resources/network/networkResources.d.ts.map +0 -1
- package/dist/src/lib/resources/network/networkResources.js +0 -784
- package/dist/src/lib/resources/network/networkResources.js.map +0 -1
- package/dist/src/lib/resources/security/encryption.d.ts +0 -290
- package/dist/src/lib/resources/security/encryption.d.ts.map +0 -1
- package/dist/src/lib/resources/security/encryption.js +0 -295
- package/dist/src/lib/resources/security/encryption.js.map +0 -1
- package/dist/src/lib/resources/security/index.d.ts +0 -6
- package/dist/src/lib/resources/security/index.d.ts.map +0 -1
- package/dist/src/lib/resources/security/index.js +0 -6
- package/dist/src/lib/resources/security/index.js.map +0 -1
- package/dist/src/lib/resources/validation/validationResources.d.ts +0 -26
- package/dist/src/lib/resources/validation/validationResources.d.ts.map +0 -1
- package/dist/src/lib/resources/validation/validationResources.js +0 -33
- package/dist/src/lib/resources/validation/validationResources.js.map +0 -1
- package/dist/src/lib/rutter.d.ts +0 -1106
- package/dist/src/lib/rutter.d.ts.map +0 -1
- package/dist/src/lib/rutter.js +0 -1295
- package/dist/src/lib/rutter.js.map +0 -1
- package/dist/src/lib/security.d.ts.map +0 -1
- package/dist/src/lib/security.js +0 -569
- package/dist/src/lib/security.js.map +0 -1
- package/dist/src/lib/umbrella.d.ts.map +0 -1
- package/dist/src/lib/umbrella.js.map +0 -1
- package/dist/src/lib/umbrellaRutter.d.ts.map +0 -1
- package/dist/src/lib/umbrellaRutter.js.map +0 -1
- package/dist/src/lib/utils/helmHelpers.d.ts.map +0 -1
- package/dist/src/lib/utils/helmHelpers.js.map +0 -1
- package/dist/src/lib/utils/podTemplates.d.ts +0 -192
- package/dist/src/lib/utils/podTemplates.d.ts.map +0 -1
- package/dist/src/lib/utils/podTemplates.js +0 -331
- package/dist/src/lib/utils/podTemplates.js.map +0 -1
- package/dist/src/lib/utils/resourceNaming.d.ts +0 -57
- package/dist/src/lib/utils/resourceNaming.d.ts.map +0 -1
- package/dist/src/lib/utils/resourceNaming.js +0 -82
- package/dist/src/lib/utils/resourceNaming.js.map +0 -1
- /package/dist/{src/cli.d.ts → cli.d.ts} +0 -0
- /package/dist/{src/lib → lib}/helmChartWriter.d.ts +0 -0
- /package/dist/{src/lib → lib}/resources/baseResourceProvider.js +0 -0
- /package/dist/{src/lib → lib}/resources/cloud/aws/karpenterResources.d.ts +0 -0
- /package/dist/{src/lib → lib}/resources/cloud/aws/karpenterResources.js +0 -0
- /package/dist/{src/lib → lib}/umbrella.d.ts +0 -0
- /package/dist/{src/lib → lib}/umbrella.js +0 -0
- /package/dist/{src/lib → lib}/umbrellaRutter.js +0 -0
|
@@ -1,784 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Network resources for Kubernetes networking
|
|
3
|
-
* @since 2.7.0
|
|
4
|
-
*/
|
|
5
|
-
import { BaseResourceProvider } from '../baseResourceProvider.js';
|
|
6
|
-
/**
|
|
7
|
-
* Network resources provider for NetworkPolicy and Ingress
|
|
8
|
-
* @extends BaseResourceProvider
|
|
9
|
-
* @since 2.7.0
|
|
10
|
-
*/
|
|
11
|
-
export class NetworkResources extends BaseResourceProvider {
|
|
12
|
-
/**
|
|
13
|
-
* Creates a NetworkPolicy resource with enhanced defaults
|
|
14
|
-
* @param spec - NetworkPolicy specification
|
|
15
|
-
* @returns Created NetworkPolicy ApiObject
|
|
16
|
-
* @since 2.7.0
|
|
17
|
-
*/
|
|
18
|
-
addNetworkPolicy(spec) {
|
|
19
|
-
const policySpec = {
|
|
20
|
-
podSelector: spec.podSelector,
|
|
21
|
-
};
|
|
22
|
-
// Provide default policy types if not specified
|
|
23
|
-
let policyTypes = spec.policyTypes;
|
|
24
|
-
if (!policyTypes) {
|
|
25
|
-
// Determine policy types based on rules provided
|
|
26
|
-
const hasIngress = spec.ingress && spec.ingress.length > 0;
|
|
27
|
-
const hasEgress = spec.egress && spec.egress.length > 0;
|
|
28
|
-
if (hasIngress && hasEgress) {
|
|
29
|
-
policyTypes = ['Ingress', 'Egress'];
|
|
30
|
-
}
|
|
31
|
-
else if (hasIngress) {
|
|
32
|
-
policyTypes = ['Ingress'];
|
|
33
|
-
}
|
|
34
|
-
else if (hasEgress) {
|
|
35
|
-
policyTypes = ['Egress'];
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
// Default to both for explicit security posture
|
|
39
|
-
policyTypes = ['Ingress', 'Egress'];
|
|
40
|
-
console.warn(NetworkResources.NETWORK_POLICY_DEFAULT_WARNING.replace('{name}', spec.name));
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
policySpec['policyTypes'] = policyTypes;
|
|
44
|
-
if (spec.ingress) {
|
|
45
|
-
policySpec['ingress'] = spec.ingress;
|
|
46
|
-
}
|
|
47
|
-
if (spec.egress) {
|
|
48
|
-
policySpec['egress'] = spec.egress;
|
|
49
|
-
}
|
|
50
|
-
return this.createApiObject(spec.name, NetworkResources.NETWORKING_API_VERSION, 'NetworkPolicy', policySpec, spec.labels, spec.annotations);
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Creates a deny-all NetworkPolicy that blocks all ingress and egress traffic
|
|
54
|
-
* @param name - Policy name
|
|
55
|
-
* @param podSelector - Pod selector to apply policy to
|
|
56
|
-
* @param labels - Optional labels
|
|
57
|
-
* @param annotations - Optional annotations
|
|
58
|
-
* @returns Created NetworkPolicy ApiObject
|
|
59
|
-
* @since 2.7.0
|
|
60
|
-
*/
|
|
61
|
-
addDenyAllNetworkPolicy(name, podSelector = {}, labels, annotations) {
|
|
62
|
-
return this.addNetworkPolicy({
|
|
63
|
-
name,
|
|
64
|
-
podSelector,
|
|
65
|
-
policyTypes: ['Ingress', 'Egress'],
|
|
66
|
-
ingress: [],
|
|
67
|
-
egress: [],
|
|
68
|
-
...(labels && { labels }),
|
|
69
|
-
...(annotations && { annotations }),
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Creates a NetworkPolicy that allows traffic from specific pods
|
|
74
|
-
* @param name - Policy name
|
|
75
|
-
* @param podSelector - Pod selector to apply policy to
|
|
76
|
-
* @param fromPodSelector - Pod selector for allowed source pods
|
|
77
|
-
* @param ports - Optional ports to allow
|
|
78
|
-
* @param labels - Optional labels
|
|
79
|
-
* @param annotations - Optional annotations
|
|
80
|
-
* @returns Created NetworkPolicy ApiObject
|
|
81
|
-
* @since 2.7.0
|
|
82
|
-
*/
|
|
83
|
-
addAllowFromPodsNetworkPolicy(name, podSelector, fromPodSelector, ports, labels, annotations) {
|
|
84
|
-
const ingressRule = {};
|
|
85
|
-
if (fromPodSelector) {
|
|
86
|
-
ingressRule.podSelector = fromPodSelector;
|
|
87
|
-
}
|
|
88
|
-
if (ports) {
|
|
89
|
-
ingressRule.ports = ports;
|
|
90
|
-
}
|
|
91
|
-
return this.addNetworkPolicy({
|
|
92
|
-
name,
|
|
93
|
-
podSelector,
|
|
94
|
-
policyTypes: ['Ingress'],
|
|
95
|
-
ingress: [ingressRule],
|
|
96
|
-
...(labels && { labels }),
|
|
97
|
-
...(annotations && { annotations }),
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Creates a NetworkPolicy that allows traffic from specific namespaces
|
|
102
|
-
* @param name - Policy name
|
|
103
|
-
* @param podSelector - Pod selector to apply policy to
|
|
104
|
-
* @param fromNamespaceSelector - Namespace selector for allowed source namespaces
|
|
105
|
-
* @param ports - Optional ports to allow
|
|
106
|
-
* @param labels - Optional labels
|
|
107
|
-
* @param annotations - Optional annotations
|
|
108
|
-
* @returns Created NetworkPolicy ApiObject
|
|
109
|
-
* @since 2.7.0
|
|
110
|
-
*/
|
|
111
|
-
addAllowFromNamespaceNetworkPolicy(name, podSelector, fromNamespaceSelector, ports, labels, annotations) {
|
|
112
|
-
const ingressRule = {};
|
|
113
|
-
if (fromNamespaceSelector) {
|
|
114
|
-
ingressRule.namespaceSelector = fromNamespaceSelector;
|
|
115
|
-
}
|
|
116
|
-
if (ports) {
|
|
117
|
-
ingressRule.ports = ports;
|
|
118
|
-
}
|
|
119
|
-
return this.addNetworkPolicy({
|
|
120
|
-
name,
|
|
121
|
-
podSelector,
|
|
122
|
-
policyTypes: ['Ingress'],
|
|
123
|
-
ingress: [ingressRule],
|
|
124
|
-
...(labels && { labels }),
|
|
125
|
-
...(annotations && { annotations }),
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Validates TLS configuration for security compliance
|
|
130
|
-
* @param spec - Ingress specification to validate
|
|
131
|
-
* @throws Error if TLS validation fails
|
|
132
|
-
* @since 2.8.0
|
|
133
|
-
*/
|
|
134
|
-
validateIngressSecurity(spec) {
|
|
135
|
-
const isProductionEnvironment = spec.environment === 'production';
|
|
136
|
-
const tlsRequired = spec.requireTLS || isProductionEnvironment;
|
|
137
|
-
// Check if TLS is required but not configured
|
|
138
|
-
if (tlsRequired && (!spec.tls || spec.tls.length === 0)) {
|
|
139
|
-
throw new Error(NetworkResources.TLS_REQUIRED_ERROR_MESSAGE);
|
|
140
|
-
}
|
|
141
|
-
// Validate TLS configuration if present
|
|
142
|
-
if (spec.tls && spec.tls.length > 0) {
|
|
143
|
-
spec.tls.forEach((tlsConfig, index) => {
|
|
144
|
-
if (!tlsConfig.secretName) {
|
|
145
|
-
throw new Error(`TLS configuration at index ${index} must specify a secretName. ` +
|
|
146
|
-
'The secret should contain "tls.crt" and "tls.key" data.');
|
|
147
|
-
}
|
|
148
|
-
// Validate secret name format (RFC 1123 DNS subdomain)
|
|
149
|
-
// This regex is safe as it only matches alphanumeric characters and hyphens
|
|
150
|
-
// eslint-disable-next-line security/detect-unsafe-regex
|
|
151
|
-
const secretNameRegex = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
152
|
-
if (!secretNameRegex.test(tlsConfig.secretName)) {
|
|
153
|
-
throw new Error(`Invalid TLS secret name "${tlsConfig.secretName}" at index ${index}. ` +
|
|
154
|
-
'Secret names must be valid RFC 1123 DNS subdomains (lowercase alphanumeric and hyphens).');
|
|
155
|
-
}
|
|
156
|
-
// Validate hosts if specified
|
|
157
|
-
if (tlsConfig.hosts && tlsConfig.hosts.length > 0) {
|
|
158
|
-
tlsConfig.hosts.forEach((host, hostIndex) => {
|
|
159
|
-
if (!this.isValidHostname(host)) {
|
|
160
|
-
throw new Error(`Invalid hostname "${host}" in TLS configuration at index ${index}, host ${hostIndex}. ` +
|
|
161
|
-
'Hostnames must be valid DNS names or wildcard patterns.');
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
// Validate that TLS hosts match Ingress rule hosts
|
|
168
|
-
if (spec.tls && spec.rules) {
|
|
169
|
-
const tlsHosts = new Set(spec.tls.flatMap((tls) => tls.hosts || []));
|
|
170
|
-
const ruleHosts = spec.rules
|
|
171
|
-
.map((rule) => rule.host)
|
|
172
|
-
.filter((host) => Boolean(host));
|
|
173
|
-
for (const ruleHost of ruleHosts) {
|
|
174
|
-
if (!tlsHosts.has(ruleHost)) {
|
|
175
|
-
console.warn(`Warning: Host "${ruleHost}" in Ingress rules is not covered by TLS configuration. ` +
|
|
176
|
-
'Consider adding it to the TLS hosts for secure communication.');
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Validates hostname format (supports wildcards) with ReDoS protection
|
|
183
|
-
* @param hostname - Hostname to validate
|
|
184
|
-
* @returns True if hostname is valid
|
|
185
|
-
* @since 2.8.0
|
|
186
|
-
*/
|
|
187
|
-
isValidHostname(hostname) {
|
|
188
|
-
if (!hostname || hostname.length === 0 || hostname.length > 253) {
|
|
189
|
-
return false;
|
|
190
|
-
}
|
|
191
|
-
// Split hostname into parts and validate each part
|
|
192
|
-
const parts = hostname.split('.');
|
|
193
|
-
if (parts.length < 2)
|
|
194
|
-
return false;
|
|
195
|
-
// Handle wildcard
|
|
196
|
-
if (hostname.startsWith('*.')) {
|
|
197
|
-
parts.shift(); // Remove wildcard part
|
|
198
|
-
if (parts.length < 2)
|
|
199
|
-
return false; // Must have at least two parts after wildcard
|
|
200
|
-
}
|
|
201
|
-
// Validate each part
|
|
202
|
-
return parts.every((part) => {
|
|
203
|
-
if (part.length === 0 || part.length > 63)
|
|
204
|
-
return false;
|
|
205
|
-
if (part.startsWith('-') || part.endsWith('-'))
|
|
206
|
-
return false;
|
|
207
|
-
return /^[a-z0-9-]+$/i.test(part);
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
* Applies NGINX Ingress specific annotations
|
|
212
|
-
* @param spec - Ingress specification
|
|
213
|
-
* @param annotations - Base annotations to enhance
|
|
214
|
-
* @returns Enhanced annotations with NGINX specific settings
|
|
215
|
-
* @since 2.9.0
|
|
216
|
-
*/
|
|
217
|
-
applyNginxAnnotations(spec, annotations) {
|
|
218
|
-
if (!spec.nginx)
|
|
219
|
-
return annotations;
|
|
220
|
-
const nginxAnnotations = { ...annotations };
|
|
221
|
-
this.applySSLAnnotations(spec.nginx, nginxAnnotations);
|
|
222
|
-
this.applyHSTSAnnotations(spec.nginx, nginxAnnotations);
|
|
223
|
-
this.applyProxyAnnotations(spec.nginx, nginxAnnotations);
|
|
224
|
-
this.applyCORSAnnotations(spec.nginx, nginxAnnotations);
|
|
225
|
-
this.applyRateLimitingAnnotations(spec.nginx, nginxAnnotations);
|
|
226
|
-
this.applyRewriteAnnotations(spec.nginx, nginxAnnotations);
|
|
227
|
-
this.applyBackendAnnotations(spec.nginx, nginxAnnotations);
|
|
228
|
-
this.applySessionAffinityAnnotations(spec.nginx, nginxAnnotations);
|
|
229
|
-
this.applySecurityAnnotations(spec.nginx, nginxAnnotations);
|
|
230
|
-
this.applyCustomAnnotations(spec.nginx, nginxAnnotations);
|
|
231
|
-
return nginxAnnotations;
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Apply SSL/TLS annotations
|
|
235
|
-
* @private
|
|
236
|
-
*/
|
|
237
|
-
applySSLAnnotations(nginx, annotations) {
|
|
238
|
-
if (nginx.sslRedirect !== undefined) {
|
|
239
|
-
annotations['nginx.ingress.kubernetes.io/ssl-redirect'] = nginx.sslRedirect.toString();
|
|
240
|
-
}
|
|
241
|
-
if (nginx.forceSSLRedirect !== undefined) {
|
|
242
|
-
annotations['nginx.ingress.kubernetes.io/force-ssl-redirect'] =
|
|
243
|
-
nginx.forceSSLRedirect.toString();
|
|
244
|
-
}
|
|
245
|
-
if (nginx.sslProtocols) {
|
|
246
|
-
annotations['nginx.ingress.kubernetes.io/ssl-protocols'] = nginx.sslProtocols;
|
|
247
|
-
}
|
|
248
|
-
if (nginx.sslCiphers) {
|
|
249
|
-
annotations['nginx.ingress.kubernetes.io/ssl-ciphers'] = nginx.sslCiphers;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Apply HSTS annotations
|
|
254
|
-
* @private
|
|
255
|
-
*/
|
|
256
|
-
applyHSTSAnnotations(nginx, annotations) {
|
|
257
|
-
if (nginx.enableHSTS !== undefined) {
|
|
258
|
-
annotations['nginx.ingress.kubernetes.io/hsts'] = nginx.enableHSTS.toString();
|
|
259
|
-
}
|
|
260
|
-
if (nginx.hstsMaxAge !== undefined) {
|
|
261
|
-
annotations['nginx.ingress.kubernetes.io/hsts-max-age'] = nginx.hstsMaxAge.toString();
|
|
262
|
-
}
|
|
263
|
-
if (nginx.hstsIncludeSubdomains !== undefined) {
|
|
264
|
-
annotations['nginx.ingress.kubernetes.io/hsts-include-subdomains'] =
|
|
265
|
-
nginx.hstsIncludeSubdomains.toString();
|
|
266
|
-
}
|
|
267
|
-
if (nginx.hstsPreload !== undefined) {
|
|
268
|
-
annotations['nginx.ingress.kubernetes.io/hsts-preload'] = nginx.hstsPreload.toString();
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* Apply proxy annotations
|
|
273
|
-
* @private
|
|
274
|
-
*/
|
|
275
|
-
applyProxyAnnotations(nginx, annotations) {
|
|
276
|
-
if (nginx.proxyBodySize) {
|
|
277
|
-
annotations['nginx.ingress.kubernetes.io/proxy-body-size'] = nginx.proxyBodySize;
|
|
278
|
-
}
|
|
279
|
-
if (nginx.proxyConnectTimeout !== undefined) {
|
|
280
|
-
annotations['nginx.ingress.kubernetes.io/proxy-connect-timeout'] =
|
|
281
|
-
nginx.proxyConnectTimeout.toString();
|
|
282
|
-
}
|
|
283
|
-
if (nginx.proxySendTimeout !== undefined) {
|
|
284
|
-
annotations['nginx.ingress.kubernetes.io/proxy-send-timeout'] =
|
|
285
|
-
nginx.proxySendTimeout.toString();
|
|
286
|
-
}
|
|
287
|
-
if (nginx.proxyReadTimeout !== undefined) {
|
|
288
|
-
annotations['nginx.ingress.kubernetes.io/proxy-read-timeout'] =
|
|
289
|
-
nginx.proxyReadTimeout.toString();
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
/**
|
|
293
|
-
* Apply CORS annotations
|
|
294
|
-
* @private
|
|
295
|
-
*/
|
|
296
|
-
applyCORSAnnotations(nginx, annotations) {
|
|
297
|
-
if (nginx.enableCORS !== undefined) {
|
|
298
|
-
annotations['nginx.ingress.kubernetes.io/enable-cors'] = nginx.enableCORS.toString();
|
|
299
|
-
}
|
|
300
|
-
if (nginx.corsAllowOrigin) {
|
|
301
|
-
annotations['nginx.ingress.kubernetes.io/cors-allow-origin'] = nginx.corsAllowOrigin;
|
|
302
|
-
}
|
|
303
|
-
if (nginx.corsAllowMethods) {
|
|
304
|
-
annotations['nginx.ingress.kubernetes.io/cors-allow-methods'] = nginx.corsAllowMethods;
|
|
305
|
-
}
|
|
306
|
-
if (nginx.corsAllowHeaders) {
|
|
307
|
-
annotations['nginx.ingress.kubernetes.io/cors-allow-headers'] = nginx.corsAllowHeaders;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
/**
|
|
311
|
-
* Apply rate limiting annotations
|
|
312
|
-
* @private
|
|
313
|
-
*/
|
|
314
|
-
applyRateLimitingAnnotations(nginx, annotations) {
|
|
315
|
-
if (nginx.rateLimiting) {
|
|
316
|
-
if (nginx.rateLimiting.rps !== undefined) {
|
|
317
|
-
annotations['nginx.ingress.kubernetes.io/rate-limit-rps'] =
|
|
318
|
-
nginx.rateLimiting.rps.toString();
|
|
319
|
-
}
|
|
320
|
-
if (nginx.rateLimiting.rpm !== undefined) {
|
|
321
|
-
annotations['nginx.ingress.kubernetes.io/rate-limit-rpm'] =
|
|
322
|
-
nginx.rateLimiting.rpm.toString();
|
|
323
|
-
}
|
|
324
|
-
if (nginx.rateLimiting.connections !== undefined) {
|
|
325
|
-
annotations['nginx.ingress.kubernetes.io/rate-limit-connections'] =
|
|
326
|
-
nginx.rateLimiting.connections.toString();
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
/**
|
|
331
|
-
* Apply rewrite annotations
|
|
332
|
-
* @private
|
|
333
|
-
*/
|
|
334
|
-
applyRewriteAnnotations(nginx, annotations) {
|
|
335
|
-
if (nginx.rewriteTarget) {
|
|
336
|
-
annotations['nginx.ingress.kubernetes.io/rewrite-target'] = nginx.rewriteTarget;
|
|
337
|
-
}
|
|
338
|
-
if (nginx.useRegex !== undefined) {
|
|
339
|
-
annotations['nginx.ingress.kubernetes.io/use-regex'] = nginx.useRegex.toString();
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* Apply backend annotations
|
|
344
|
-
* @private
|
|
345
|
-
*/
|
|
346
|
-
applyBackendAnnotations(nginx, annotations) {
|
|
347
|
-
if (nginx.backendProtocol) {
|
|
348
|
-
annotations['nginx.ingress.kubernetes.io/backend-protocol'] = nginx.backendProtocol;
|
|
349
|
-
}
|
|
350
|
-
if (nginx.upstreamHashBy) {
|
|
351
|
-
annotations['nginx.ingress.kubernetes.io/upstream-hash-by'] = nginx.upstreamHashBy;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
/**
|
|
355
|
-
* Apply session affinity annotations
|
|
356
|
-
* @private
|
|
357
|
-
*/
|
|
358
|
-
applySessionAffinityAnnotations(nginx, annotations) {
|
|
359
|
-
if (nginx.sessionAffinity) {
|
|
360
|
-
annotations['nginx.ingress.kubernetes.io/affinity'] = nginx.sessionAffinity;
|
|
361
|
-
}
|
|
362
|
-
if (nginx.sessionCookieName) {
|
|
363
|
-
annotations['nginx.ingress.kubernetes.io/affinity-cookie-name'] = nginx.sessionCookieName;
|
|
364
|
-
}
|
|
365
|
-
if (nginx.sessionCookieExpires !== undefined) {
|
|
366
|
-
annotations['nginx.ingress.kubernetes.io/affinity-cookie-expires'] =
|
|
367
|
-
nginx.sessionCookieExpires.toString();
|
|
368
|
-
}
|
|
369
|
-
if (nginx.sessionCookieMaxAge !== undefined) {
|
|
370
|
-
annotations['nginx.ingress.kubernetes.io/affinity-cookie-max-age'] =
|
|
371
|
-
nginx.sessionCookieMaxAge.toString();
|
|
372
|
-
}
|
|
373
|
-
if (nginx.sessionCookiePath) {
|
|
374
|
-
annotations['nginx.ingress.kubernetes.io/affinity-cookie-path'] = nginx.sessionCookiePath;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
/**
|
|
378
|
-
* Apply security annotations
|
|
379
|
-
* @private
|
|
380
|
-
*/
|
|
381
|
-
applySecurityAnnotations(nginx, annotations) {
|
|
382
|
-
if (nginx.whitelistSourceRange && nginx.whitelistSourceRange.length > 0) {
|
|
383
|
-
annotations['nginx.ingress.kubernetes.io/whitelist-source-range'] =
|
|
384
|
-
nginx.whitelistSourceRange.join(',');
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* Apply custom annotations
|
|
389
|
-
* @private
|
|
390
|
-
*/
|
|
391
|
-
applyCustomAnnotations(nginx, annotations) {
|
|
392
|
-
if (nginx.configurationSnippet) {
|
|
393
|
-
annotations['nginx.ingress.kubernetes.io/configuration-snippet'] = nginx.configurationSnippet;
|
|
394
|
-
}
|
|
395
|
-
if (nginx.serverSnippet) {
|
|
396
|
-
annotations['nginx.ingress.kubernetes.io/server-snippet'] = nginx.serverSnippet;
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
/**
|
|
400
|
-
* Applies cert-manager annotations for automatic certificate management
|
|
401
|
-
* @param spec - Ingress specification
|
|
402
|
-
* @param annotations - Base annotations to enhance
|
|
403
|
-
* @returns Enhanced annotations with cert-manager settings
|
|
404
|
-
* @since 2.9.0
|
|
405
|
-
*/
|
|
406
|
-
applyCertManagerAnnotations(spec, annotations) {
|
|
407
|
-
if (!spec.certManager)
|
|
408
|
-
return annotations;
|
|
409
|
-
const certManager = spec.certManager;
|
|
410
|
-
const certAnnotations = { ...annotations };
|
|
411
|
-
// ClusterIssuer or Issuer
|
|
412
|
-
if (certManager.clusterIssuer) {
|
|
413
|
-
certAnnotations['cert-manager.io/cluster-issuer'] = certManager.clusterIssuer;
|
|
414
|
-
}
|
|
415
|
-
else if (certManager.issuer) {
|
|
416
|
-
certAnnotations['cert-manager.io/issuer'] = certManager.issuer;
|
|
417
|
-
}
|
|
418
|
-
// ACME challenge type
|
|
419
|
-
if (certManager.acmeChallenge) {
|
|
420
|
-
certAnnotations['cert-manager.io/acme-challenge-type'] = certManager.acmeChallenge;
|
|
421
|
-
}
|
|
422
|
-
// Certificate class
|
|
423
|
-
if (certManager.certificateClass) {
|
|
424
|
-
certAnnotations['cert-manager.io/certificate-class'] = certManager.certificateClass;
|
|
425
|
-
}
|
|
426
|
-
return certAnnotations;
|
|
427
|
-
}
|
|
428
|
-
/**
|
|
429
|
-
* Applies security defaults to Ingress annotations
|
|
430
|
-
* @param spec - Ingress specification
|
|
431
|
-
* @returns Enhanced annotations with security defaults
|
|
432
|
-
* @since 2.8.0
|
|
433
|
-
*/
|
|
434
|
-
applySecurityDefaults(spec) {
|
|
435
|
-
let annotations = { ...spec.annotations };
|
|
436
|
-
// Apply SSL redirect if TLS is configured or force SSL redirect is enabled
|
|
437
|
-
if ((spec.tls && spec.tls.length > 0) || spec.forceSSLRedirect) {
|
|
438
|
-
// NGINX Ingress Controller annotations
|
|
439
|
-
annotations['nginx.ingress.kubernetes.io/ssl-redirect'] = 'true';
|
|
440
|
-
annotations['nginx.ingress.kubernetes.io/force-ssl-redirect'] = 'true';
|
|
441
|
-
// Traefik annotations
|
|
442
|
-
annotations['traefik.ingress.kubernetes.io/redirect-entry-point'] = 'https';
|
|
443
|
-
// HAProxy annotations
|
|
444
|
-
annotations['haproxy.org/ssl-redirect'] = 'true';
|
|
445
|
-
}
|
|
446
|
-
// Add security headers for production environments
|
|
447
|
-
if (spec.environment === 'production' || spec.requireTLS) {
|
|
448
|
-
// NGINX security headers with CSP
|
|
449
|
-
annotations['nginx.ingress.kubernetes.io/configuration-snippet'] = `
|
|
450
|
-
more_set_headers "X-Frame-Options: DENY";
|
|
451
|
-
more_set_headers "X-Content-Type-Options: nosniff";
|
|
452
|
-
more_set_headers "X-XSS-Protection: 1; mode=block";
|
|
453
|
-
more_set_headers "Referrer-Policy: strict-origin-when-cross-origin";
|
|
454
|
-
more_set_headers "Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';";
|
|
455
|
-
`.trim();
|
|
456
|
-
}
|
|
457
|
-
// Apply NGINX specific annotations
|
|
458
|
-
annotations = this.applyNginxAnnotations(spec, annotations);
|
|
459
|
-
// Apply cert-manager annotations
|
|
460
|
-
annotations = this.applyCertManagerAnnotations(spec, annotations);
|
|
461
|
-
return annotations;
|
|
462
|
-
}
|
|
463
|
-
/**
|
|
464
|
-
* Creates a secure Ingress with TLS validation and environment-aware defaults
|
|
465
|
-
* @param spec - Enhanced Ingress specification
|
|
466
|
-
* @returns Created Ingress ApiObject
|
|
467
|
-
* @example
|
|
468
|
-
* ```typescript
|
|
469
|
-
* // Production Ingress with mandatory TLS
|
|
470
|
-
* networkResources.addSecureIngress({
|
|
471
|
-
* name: 'web-ingress',
|
|
472
|
-
* environment: 'production',
|
|
473
|
-
* tls: [{
|
|
474
|
-
* hosts: ['example.com'],
|
|
475
|
-
* secretName: 'example-tls'
|
|
476
|
-
* }],
|
|
477
|
-
* rules: [{
|
|
478
|
-
* host: 'example.com',
|
|
479
|
-
* http: {
|
|
480
|
-
* paths: [{
|
|
481
|
-
* path: '/',
|
|
482
|
-
* pathType: 'Prefix',
|
|
483
|
-
* backend: {
|
|
484
|
-
* service: { name: 'web-service', port: { number: 80 } }
|
|
485
|
-
* }
|
|
486
|
-
* }]
|
|
487
|
-
* }
|
|
488
|
-
* }]
|
|
489
|
-
* });
|
|
490
|
-
* ```
|
|
491
|
-
* @since 2.8.0
|
|
492
|
-
*/
|
|
493
|
-
addSecureIngress(spec) {
|
|
494
|
-
// Validate TLS configuration and security requirements
|
|
495
|
-
this.validateIngressSecurity(spec);
|
|
496
|
-
// Apply security defaults to annotations
|
|
497
|
-
const enhancedAnnotations = this.applySecurityDefaults(spec);
|
|
498
|
-
// Create the Ingress with enhanced security
|
|
499
|
-
const ingressSpec = {};
|
|
500
|
-
if (spec.ingressClassName) {
|
|
501
|
-
ingressSpec['ingressClassName'] = spec.ingressClassName;
|
|
502
|
-
}
|
|
503
|
-
if (spec.tls) {
|
|
504
|
-
ingressSpec['tls'] = spec.tls;
|
|
505
|
-
}
|
|
506
|
-
if (spec.rules) {
|
|
507
|
-
ingressSpec['rules'] = spec.rules;
|
|
508
|
-
}
|
|
509
|
-
return this.createApiObject(spec.name, NetworkResources.NETWORKING_API_VERSION, 'Ingress', ingressSpec, spec.labels, enhancedAnnotations);
|
|
510
|
-
}
|
|
511
|
-
/**
|
|
512
|
-
* Creates an Ingress resource with optional TLS validation
|
|
513
|
-
* @param spec - Ingress specification
|
|
514
|
-
* @returns Created Ingress ApiObject
|
|
515
|
-
* @deprecated Use addSecureIngress for enhanced security validation
|
|
516
|
-
* @since 2.7.0
|
|
517
|
-
*/
|
|
518
|
-
addIngress(spec) {
|
|
519
|
-
// Apply basic validation if environment is specified
|
|
520
|
-
if (spec.environment || spec.requireTLS) {
|
|
521
|
-
this.validateIngressSecurity(spec);
|
|
522
|
-
const enhancedAnnotations = this.applySecurityDefaults(spec);
|
|
523
|
-
const ingressSpec = {};
|
|
524
|
-
if (spec.ingressClassName) {
|
|
525
|
-
ingressSpec['ingressClassName'] = spec.ingressClassName;
|
|
526
|
-
}
|
|
527
|
-
if (spec.tls) {
|
|
528
|
-
ingressSpec['tls'] = spec.tls;
|
|
529
|
-
}
|
|
530
|
-
if (spec.rules) {
|
|
531
|
-
ingressSpec['rules'] = spec.rules;
|
|
532
|
-
}
|
|
533
|
-
return this.createApiObject(spec.name, NetworkResources.NETWORKING_API_VERSION, 'Ingress', ingressSpec, spec.labels, enhancedAnnotations);
|
|
534
|
-
}
|
|
535
|
-
// Legacy behavior for backward compatibility
|
|
536
|
-
const ingressSpec = {};
|
|
537
|
-
if (spec.ingressClassName) {
|
|
538
|
-
ingressSpec['ingressClassName'] = spec.ingressClassName;
|
|
539
|
-
}
|
|
540
|
-
if (spec.tls) {
|
|
541
|
-
ingressSpec['tls'] = spec.tls;
|
|
542
|
-
}
|
|
543
|
-
if (spec.rules) {
|
|
544
|
-
ingressSpec['rules'] = spec.rules;
|
|
545
|
-
}
|
|
546
|
-
return this.createApiObject(spec.name, NetworkResources.NETWORKING_API_VERSION, 'Ingress', ingressSpec, spec.labels, spec.annotations);
|
|
547
|
-
}
|
|
548
|
-
/**
|
|
549
|
-
* Creates an NGINX Ingress with enhanced configuration and cert-manager integration
|
|
550
|
-
* @param spec - Enhanced Ingress specification with NGINX and cert-manager support
|
|
551
|
-
* @returns Created Ingress ApiObject
|
|
552
|
-
* @example
|
|
553
|
-
* ```typescript
|
|
554
|
-
* // NGINX Ingress with Let's Encrypt and advanced features
|
|
555
|
-
* networkResources.addNginxIngress({
|
|
556
|
-
* name: 'web-ingress',
|
|
557
|
-
* ingressClassName: 'nginx',
|
|
558
|
-
* environment: 'production',
|
|
559
|
-
* rules: [{
|
|
560
|
-
* host: 'example.com',
|
|
561
|
-
* http: {
|
|
562
|
-
* paths: [{
|
|
563
|
-
* path: '/',
|
|
564
|
-
* pathType: 'Prefix',
|
|
565
|
-
* backend: {
|
|
566
|
-
* service: { name: 'web-service', port: { number: 80 } }
|
|
567
|
-
* }
|
|
568
|
-
* }]
|
|
569
|
-
* }
|
|
570
|
-
* }],
|
|
571
|
-
* tls: [{
|
|
572
|
-
* hosts: ['example.com'],
|
|
573
|
-
* secretName: 'example-tls'
|
|
574
|
-
* }],
|
|
575
|
-
* nginx: {
|
|
576
|
-
* sslRedirect: true,
|
|
577
|
-
* enableHSTS: true,
|
|
578
|
-
* hstsMaxAge: 31536000,
|
|
579
|
-
* proxyBodySize: '10m',
|
|
580
|
-
* rateLimiting: { rps: 100 }
|
|
581
|
-
* },
|
|
582
|
-
* certManager: {
|
|
583
|
-
* clusterIssuer: 'letsencrypt-prod'
|
|
584
|
-
* }
|
|
585
|
-
* });
|
|
586
|
-
* ```
|
|
587
|
-
* @since 2.9.0
|
|
588
|
-
*/
|
|
589
|
-
addNginxIngress(spec) {
|
|
590
|
-
// Set default ingress class for NGINX
|
|
591
|
-
const nginxSpec = {
|
|
592
|
-
...spec,
|
|
593
|
-
ingressClassName: spec.ingressClassName || 'nginx',
|
|
594
|
-
};
|
|
595
|
-
// Use the enhanced secure ingress method
|
|
596
|
-
return this.addSecureIngress(nginxSpec);
|
|
597
|
-
}
|
|
598
|
-
/**
|
|
599
|
-
* Creates an NGINX Ingress with Let's Encrypt certificate automation
|
|
600
|
-
* @param name - Ingress name
|
|
601
|
-
* @param host - Primary hostname
|
|
602
|
-
* @param serviceName - Backend service name
|
|
603
|
-
* @param servicePort - Backend service port
|
|
604
|
-
* @param clusterIssuer - Let's Encrypt ClusterIssuer name
|
|
605
|
-
* @param additionalHosts - Additional hostnames
|
|
606
|
-
* @param path - URL path (default: '/')
|
|
607
|
-
* @param pathType - Path type (default: 'Prefix')
|
|
608
|
-
* @param nginxConfig - Optional NGINX configuration
|
|
609
|
-
* @param labels - Optional labels
|
|
610
|
-
* @param annotations - Optional additional annotations
|
|
611
|
-
* @returns Created Ingress ApiObject
|
|
612
|
-
* @example
|
|
613
|
-
* ```typescript
|
|
614
|
-
* // Simple NGINX Ingress with Let's Encrypt
|
|
615
|
-
* networkResources.addNginxIngressWithLetsEncrypt(
|
|
616
|
-
* 'web-ingress',
|
|
617
|
-
* 'example.com',
|
|
618
|
-
* 'web-service',
|
|
619
|
-
* 80,
|
|
620
|
-
* 'letsencrypt-prod',
|
|
621
|
-
* ['www.example.com'],
|
|
622
|
-
* '/',
|
|
623
|
-
* 'Prefix',
|
|
624
|
-
* { enableHSTS: true, rateLimiting: { rps: 50 } }
|
|
625
|
-
* );
|
|
626
|
-
* ```
|
|
627
|
-
* @since 2.9.0
|
|
628
|
-
*/
|
|
629
|
-
addNginxIngressWithLetsEncrypt(name, host, serviceName, servicePort, clusterIssuer, additionalHosts = [], path = '/', pathType = 'Prefix', nginxConfig, labels, annotations) {
|
|
630
|
-
const allHosts = [host, ...additionalHosts];
|
|
631
|
-
const secretName = `${name}-tls`;
|
|
632
|
-
return this.addNginxIngress({
|
|
633
|
-
name,
|
|
634
|
-
ingressClassName: 'nginx',
|
|
635
|
-
environment: 'production',
|
|
636
|
-
tls: [
|
|
637
|
-
{
|
|
638
|
-
hosts: allHosts,
|
|
639
|
-
secretName,
|
|
640
|
-
},
|
|
641
|
-
],
|
|
642
|
-
rules: [
|
|
643
|
-
{
|
|
644
|
-
host,
|
|
645
|
-
http: {
|
|
646
|
-
paths: [
|
|
647
|
-
{
|
|
648
|
-
path,
|
|
649
|
-
pathType,
|
|
650
|
-
backend: {
|
|
651
|
-
service: {
|
|
652
|
-
name: serviceName,
|
|
653
|
-
port: { number: servicePort },
|
|
654
|
-
},
|
|
655
|
-
},
|
|
656
|
-
},
|
|
657
|
-
],
|
|
658
|
-
},
|
|
659
|
-
},
|
|
660
|
-
],
|
|
661
|
-
nginx: {
|
|
662
|
-
sslRedirect: true,
|
|
663
|
-
enableHSTS: true,
|
|
664
|
-
hstsMaxAge: 31536000,
|
|
665
|
-
hstsIncludeSubdomains: true,
|
|
666
|
-
...nginxConfig,
|
|
667
|
-
},
|
|
668
|
-
certManager: {
|
|
669
|
-
clusterIssuer,
|
|
670
|
-
},
|
|
671
|
-
...(labels && { labels }),
|
|
672
|
-
...(annotations && { annotations }),
|
|
673
|
-
});
|
|
674
|
-
}
|
|
675
|
-
/**
|
|
676
|
-
* Gets predefined NetworkPolicy templates for common security patterns
|
|
677
|
-
* @returns Array of predefined NetworkPolicy templates
|
|
678
|
-
* @since 2.9.0
|
|
679
|
-
*/
|
|
680
|
-
static getNetworkPolicyTemplates() {
|
|
681
|
-
return [
|
|
682
|
-
{
|
|
683
|
-
name: 'deny-all',
|
|
684
|
-
description: 'Deny all ingress and egress traffic (Zero Trust baseline)',
|
|
685
|
-
policyTypes: ['Ingress', 'Egress'],
|
|
686
|
-
ingress: [],
|
|
687
|
-
egress: [],
|
|
688
|
-
},
|
|
689
|
-
{
|
|
690
|
-
name: 'allow-dns-only',
|
|
691
|
-
description: 'Allow only DNS queries (port 53) for egress',
|
|
692
|
-
policyTypes: ['Ingress', 'Egress'],
|
|
693
|
-
ingress: [],
|
|
694
|
-
egress: [
|
|
695
|
-
{
|
|
696
|
-
ports: [
|
|
697
|
-
{ protocol: 'UDP', port: 53 },
|
|
698
|
-
{ protocol: 'TCP', port: 53 },
|
|
699
|
-
],
|
|
700
|
-
},
|
|
701
|
-
],
|
|
702
|
-
},
|
|
703
|
-
{
|
|
704
|
-
name: 'web-frontend',
|
|
705
|
-
description: 'Allow ingress on port 80/443, egress to backend services',
|
|
706
|
-
policyTypes: ['Ingress', 'Egress'],
|
|
707
|
-
ingress: [
|
|
708
|
-
{
|
|
709
|
-
ports: [
|
|
710
|
-
{ protocol: 'TCP', port: 80 },
|
|
711
|
-
{ protocol: 'TCP', port: 443 },
|
|
712
|
-
],
|
|
713
|
-
},
|
|
714
|
-
],
|
|
715
|
-
egress: [
|
|
716
|
-
{
|
|
717
|
-
ports: [
|
|
718
|
-
{ protocol: 'UDP', port: 53 },
|
|
719
|
-
{ protocol: 'TCP', port: 53 },
|
|
720
|
-
],
|
|
721
|
-
},
|
|
722
|
-
],
|
|
723
|
-
},
|
|
724
|
-
];
|
|
725
|
-
}
|
|
726
|
-
/**
|
|
727
|
-
* Creates a NetworkPolicy from a predefined template
|
|
728
|
-
* @param templateName - Name of the predefined template
|
|
729
|
-
* @param name - Policy name
|
|
730
|
-
* @param podSelector - Pod selector to apply policy to
|
|
731
|
-
* @param labels - Optional labels
|
|
732
|
-
* @param annotations - Optional annotations
|
|
733
|
-
* @returns Created NetworkPolicy ApiObject
|
|
734
|
-
* @example
|
|
735
|
-
* ```typescript
|
|
736
|
-
* // Create a deny-all policy
|
|
737
|
-
* networkResources.addNetworkPolicyFromTemplate(
|
|
738
|
-
* 'deny-all',
|
|
739
|
-
* 'default-deny',
|
|
740
|
-
* { matchLabels: { app: 'web' } }
|
|
741
|
-
* );
|
|
742
|
-
* ```
|
|
743
|
-
* @since 2.9.0
|
|
744
|
-
*/
|
|
745
|
-
addNetworkPolicyFromTemplate(templateName, name, podSelector, labels, annotations) {
|
|
746
|
-
const templates = NetworkResources.getNetworkPolicyTemplates();
|
|
747
|
-
const template = templates.find((t) => t.name === templateName);
|
|
748
|
-
if (!template) {
|
|
749
|
-
const availableTemplates = templates.map((t) => t.name).join(', ');
|
|
750
|
-
throw new Error(`NetworkPolicy template '${templateName}' not found. Available templates: ${availableTemplates}`);
|
|
751
|
-
}
|
|
752
|
-
console.warn(NetworkResources.NETWORK_POLICY_TEMPLATE_INFO.replace('{templateName}', templateName).replace('{description}', template.description));
|
|
753
|
-
return this.addNetworkPolicy({
|
|
754
|
-
name,
|
|
755
|
-
podSelector,
|
|
756
|
-
policyTypes: template.policyTypes,
|
|
757
|
-
...(template.ingress && { ingress: template.ingress }),
|
|
758
|
-
...(template.egress && { egress: template.egress }),
|
|
759
|
-
...(labels && { labels }),
|
|
760
|
-
...(annotations && { annotations }),
|
|
761
|
-
});
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
/**
|
|
765
|
-
* Error message for missing TLS configuration in production environments
|
|
766
|
-
* @since 2.9.0
|
|
767
|
-
*/
|
|
768
|
-
NetworkResources.TLS_REQUIRED_ERROR_MESSAGE = 'TLS configuration is required for production Ingress resources. Please configure the "tls" field with valid certificate references.';
|
|
769
|
-
/**
|
|
770
|
-
* Warning message for NetworkPolicy with default policy types
|
|
771
|
-
* @since 2.9.0
|
|
772
|
-
*/
|
|
773
|
-
NetworkResources.NETWORK_POLICY_DEFAULT_WARNING = "⚠️ WARNING: NetworkPolicy '{name}' has no explicit policyTypes or rules. Defaulting to ['Ingress', 'Egress'] for security. Consider specifying explicit rules.";
|
|
774
|
-
/**
|
|
775
|
-
* Info message for NetworkPolicy template usage
|
|
776
|
-
* @since 2.9.0
|
|
777
|
-
*/
|
|
778
|
-
NetworkResources.NETWORK_POLICY_TEMPLATE_INFO = "⚠️ INFO: Using NetworkPolicy template '{templateName}': {description}";
|
|
779
|
-
/**
|
|
780
|
-
* Kubernetes networking API version
|
|
781
|
-
* @since 2.9.0
|
|
782
|
-
*/
|
|
783
|
-
NetworkResources.NETWORKING_API_VERSION = 'networking.k8s.io/v1';
|
|
784
|
-
//# sourceMappingURL=networkResources.js.map
|