From c0185aa41711231ba40d264cc115867c8c32ae90 Mon Sep 17 00:00:00 2001 From: Maicon Berlofa Date: Thu, 2 Jul 2026 17:55:42 -0300 Subject: [PATCH 1/4] docs(apache): sync template standards --- src/pages/docs/charts/apache.mdx | 15 ++++++++++++--- src/pages/playground.astro | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/pages/docs/charts/apache.mdx b/src/pages/docs/charts/apache.mdx index 79172292..19b16b87 100644 --- a/src/pages/docs/charts/apache.mdx +++ b/src/pages/docs/charts/apache.mdx @@ -10,7 +10,7 @@ Apache HTTP Server chart for Kubernetes using the official `docker.io/library/ht ## Key Features -- Official `httpd` image pinned to Apache HTTP Server `2.4.67` +- Official `httpd` image pinned to Apache HTTP Server `2.4.68` - Non-root runtime on port `8080` with a read-only root filesystem - Generated Apache configuration for security headers, health checks, logging, and static content - Inline content, existing ConfigMap content, and extra virtual host snippets @@ -118,6 +118,13 @@ networkPolicy: enabled: true allowDns: true allowInternet: false + extraEgress: + - to: + - ipBlock: + cidr: 10.0.0.0/8 + ports: + - protocol: TCP + port: 443 ``` Use immutable content names instead of mutating a live ConfigMap. That keeps rollbacks deterministic and avoids confusing pod checksums. @@ -247,6 +254,7 @@ networkPolicy: ``` Set `networkPolicy.egress.allowInternet=true` only when Apache needs outbound access for reverse proxy targets or remote content integrations. +Use `networkPolicy.egress.extraEgress` for complete additional egress rules with `to` and `ports`. ## Configuration Reference @@ -260,7 +268,7 @@ Set `networkPolicy.egress.allowInternet=true` only when Apache needs outbound ac | `commonLabels` | `{}` | Labels added to chart resources. | | `serverName` | `localhost` | Apache `ServerName` value. | | `image.repository` | `docker.io/library/httpd` | Official Apache HTTP Server image. | -| `image.tag` | `2.4.67` | Apache image tag. | +| `image.tag` | `2.4.68` | Apache image tag. | | `image.pullPolicy` | `IfNotPresent` | Image pull policy. | | `imagePullSecrets` | `[]` | Image pull secrets. | | `containerPorts.http` | `8080` | Non-root Apache listener port. | @@ -333,7 +341,8 @@ Set `networkPolicy.egress.allowInternet=true` only when Apache needs outbound ac | `networkPolicy.egress.enabled` | `true` | Restrict outbound traffic when policy is enabled. | | `networkPolicy.egress.allowDns` | `true` | Allow DNS egress. | | `networkPolicy.egress.allowInternet` | `true` | Allow IPv4 and IPv6 internet egress. | -| `networkPolicy.egress.extraRules` | `[]` | Additional egress rules. | +| `networkPolicy.egress.extraRules` | `[]` | Legacy additional egress rules. | +| `networkPolicy.egress.extraEgress` | `[]` | Additional complete egress rule objects. | ### Probes, Resources, And Scheduling diff --git a/src/pages/playground.astro b/src/pages/playground.astro index 07b8fe5b..6de8a060 100644 --- a/src/pages/playground.astro +++ b/src/pages/playground.astro @@ -22,6 +22,7 @@ const scenariosJson = JSON.stringify(scenarios); const siteSyncPlaygroundConfigs: Record = { 'adguard-home': 'src/data/playground-configs.ts', + apache: 'src/data/playground-schema.ts', booklore: 'src/data/playground-configs.ts', changedetection: 'src/data/playground-configs.ts', medikeep: 'src/data/playground-configs.ts', From c6494b2043dfbe0c9515dd2902d3dce420c8d397 Mon Sep 17 00:00:00 2001 From: Maicon Berlofa Date: Thu, 2 Jul 2026 19:15:29 -0300 Subject: [PATCH 2/4] docs(apache): expose extra egress playground fields --- src/data/playground-configs.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/data/playground-configs.ts b/src/data/playground-configs.ts index ddd39839..fcb8ee17 100644 --- a/src/data/playground-configs.ts +++ b/src/data/playground-configs.ts @@ -258,6 +258,28 @@ export const chartConfigs: Record = { default: 'true', description: 'Allow general outbound traffic', }, + { + label: 'Extra Egress CIDR', + key: 'networkPolicy.egress.extraEgress[0].to[0].ipBlock.cidr', + type: 'text', + default: '', + description: 'Optional extra egress CIDR', + }, + { + label: 'Extra Egress Protocol', + key: 'networkPolicy.egress.extraEgress[0].ports[0].protocol', + type: 'select', + default: '', + options: ['', 'TCP', 'UDP', 'SCTP'], + description: 'Optional extra egress protocol', + }, + { + label: 'Extra Egress Port', + key: 'networkPolicy.egress.extraEgress[0].ports[0].port', + type: 'number', + default: '', + description: 'Optional extra egress port', + }, ], }, { From 837234c4838fe7a31e3ac1e752bf0995b3c1248a Mon Sep 17 00:00:00 2001 From: Maicon Berlofa Date: Sat, 4 Jul 2026 16:29:03 -0300 Subject: [PATCH 3/4] fix(apache): guard playground extra egress rule --- src/scripts/playground.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/scripts/playground.ts b/src/scripts/playground.ts index 79712dcd..4a9c689f 100644 --- a/src/scripts/playground.ts +++ b/src/scripts/playground.ts @@ -759,9 +759,28 @@ function getChangedValues(): { key: string; value: string; defaultValue: string changes.unshift({ key: 'tunnel.quickTunnel.enabled', value: 'false', defaultValue: 'true' }); } + pruneIncompleteApacheExtraEgress(changes); + return changes; } +function pruneIncompleteApacheExtraEgress(changes: { key: string; value: string; defaultValue: string }[]): void { + if (selectedSlug !== 'apache') return; + + const ruleKeys = new Set([ + 'networkPolicy.egress.extraEgress[0].to[0].ipBlock.cidr', + 'networkPolicy.egress.extraEgress[0].ports[0].protocol', + 'networkPolicy.egress.extraEgress[0].ports[0].port', + ]); + const emittedRuleKeys = changes.filter((change) => ruleKeys.has(change.key)).map((change) => change.key); + + if (emittedRuleKeys.length === 0 || emittedRuleKeys.length === ruleKeys.size) return; + + for (let index = changes.length - 1; index >= 0; index -= 1) { + if (ruleKeys.has(changes[index].key)) changes.splice(index, 1); + } +} + function buildSetFlags(): string[] { return getChangedValues().map((c) => { const setter = shouldPreserveString(c.key) ? '--set-string' : '--set'; From 9de3dee3b7b6dfcab34451d9cb69798a38a00cdf Mon Sep 17 00:00:00 2001 From: Maicon Berlofa Date: Sun, 5 Jul 2026 22:40:20 -0300 Subject: [PATCH 4/4] fix(apache): generalize coupled playground rules --- src/scripts/playground.ts | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/scripts/playground.ts b/src/scripts/playground.ts index 4a9c689f..fed59bc4 100644 --- a/src/scripts/playground.ts +++ b/src/scripts/playground.ts @@ -70,6 +70,16 @@ const linkedFieldValues: Record> = { }, }; +const coupledRuleKeysBySlug: Record = { + apache: [ + [ + 'networkPolicy.egress.extraEgress[0].to[0].ipBlock.cidr', + 'networkPolicy.egress.extraEgress[0].ports[0].protocol', + 'networkPolicy.egress.extraEgress[0].ports[0].port', + ], + ], +}; + const giteaPostgresqlPassword = 'change-me-gitea-postgresql'; function getGroups(slug: string): GroupConfig[] { @@ -759,25 +769,21 @@ function getChangedValues(): { key: string; value: string; defaultValue: string changes.unshift({ key: 'tunnel.quickTunnel.enabled', value: 'false', defaultValue: 'true' }); } - pruneIncompleteApacheExtraEgress(changes); + pruneIncompleteCoupledRules(changes); return changes; } -function pruneIncompleteApacheExtraEgress(changes: { key: string; value: string; defaultValue: string }[]): void { - if (selectedSlug !== 'apache') return; +function pruneIncompleteCoupledRules(changes: { key: string; value: string; defaultValue: string }[]): void { + for (const keys of coupledRuleKeysBySlug[selectedSlug] ?? []) { + const ruleKeys = new Set(keys); + const emittedRuleKeys = changes.filter((change) => ruleKeys.has(change.key)).map((change) => change.key); - const ruleKeys = new Set([ - 'networkPolicy.egress.extraEgress[0].to[0].ipBlock.cidr', - 'networkPolicy.egress.extraEgress[0].ports[0].protocol', - 'networkPolicy.egress.extraEgress[0].ports[0].port', - ]); - const emittedRuleKeys = changes.filter((change) => ruleKeys.has(change.key)).map((change) => change.key); + if (emittedRuleKeys.length === 0 || emittedRuleKeys.length === ruleKeys.size) continue; - if (emittedRuleKeys.length === 0 || emittedRuleKeys.length === ruleKeys.size) return; - - for (let index = changes.length - 1; index >= 0; index -= 1) { - if (ruleKeys.has(changes[index].key)) changes.splice(index, 1); + for (let index = changes.length - 1; index >= 0; index -= 1) { + if (ruleKeys.has(changes[index].key)) changes.splice(index, 1); + } } }