diff --git a/src/pepr/config.ts b/src/pepr/config.ts index e227df63f..b72689f3c 100644 --- a/src/pepr/config.ts +++ b/src/pepr/config.ts @@ -34,6 +34,9 @@ export const UDSConfig = { // Static CIDR range to use for KubeAPI instead of k8s watch kubeApiCidr: process.env.KUBEAPI_CIDR, + // Static CIDRs to use for KubeNodes instead of k8s watch. Comma separated list of CIDRs. + kubeNodeCidrs: process.env.KUBENODE_CIDRS, + // Track if UDS Core identity-authorization layer is deployed isIdentityDeployed: false, }; diff --git a/src/pepr/operator/controllers/network/generators/kubeNodes.ts b/src/pepr/operator/controllers/network/generators/kubeNodes.ts index cf19bd08f..c8cc6565d 100644 --- a/src/pepr/operator/controllers/network/generators/kubeNodes.ts +++ b/src/pepr/operator/controllers/network/generators/kubeNodes.ts @@ -22,6 +22,15 @@ const nodeSet = new Set(); * and populating the nodeSet with their Internal IPs. */ export async function initAllNodesTarget() { + // if a list of CIDRs is defined, use those + if (UDSConfig.kubeNodeCidrs) { + const nodeCidrs = UDSConfig.kubeNodeCidrs.split(","); + for (const nodeCidr of nodeCidrs) { + nodeSet.add(nodeCidr); + } + return; + } + try { const nodes = await retryWithDelay(fetchKubernetesNodes, log); nodeSet.clear(); @@ -125,9 +134,9 @@ export async function updateKubeNodesNetworkPolicies() { await K8s(kind.NetworkPolicy).Apply(netPol, { force: true }); } catch (err) { let message = err.data?.message || "Unknown error while applying KubeNode network policies"; - if (UDSConfig.kubeApiCidr) { + if (UDSConfig.kubeNodeCidrs) { message += - ", ensure that the KUBEAPI_CIDR override configured for the operator is correct."; + ", ensure that the KUBENODE_CIDRS override configured for the operator is correct."; } throw new Error(message); } @@ -140,11 +149,23 @@ export async function updateKubeNodesNetworkPolicies() { function buildNodePolicies(nodeIPs: string[]): V1NetworkPolicyPeer[] { return nodeIPs.map(ip => ({ ipBlock: { - cidr: `${ip}/32`, + cidr: format32cidr(ip), }, })); } +/** + * Utility function conditionally format an IP as a 32-bit CIDR. + */ +function format32cidr(ip: string): string { + // Check if the input already appears to have CIDR notation + if (ip.includes("/")) { + return ip; + } + // If not, append "/32" + return `${ip}/32`; +} + /** * Utility function to get the InternalIP of a node. */ diff --git a/src/pepr/operator/controllers/network/policies.ts b/src/pepr/operator/controllers/network/policies.ts index e24ffc434..169537646 100644 --- a/src/pepr/operator/controllers/network/policies.ts +++ b/src/pepr/operator/controllers/network/policies.ts @@ -160,6 +160,13 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { message += ", ensure that the KUBEAPI_CIDR override configured for the operator is correct."; } + if ( + UDSConfig.kubeNodeCidrs && + policy.metadata.labels["uds/generated"] === RemoteGenerated.KubeAPI + ) { + message += + ", ensure that the KUBENODE_CIDRS override configured for the operator is correct."; + } throw new Error(message); } } diff --git a/src/pepr/operator/index.ts b/src/pepr/operator/index.ts index 765d50920..0a29edb78 100644 --- a/src/pepr/operator/index.ts +++ b/src/pepr/operator/index.ts @@ -94,7 +94,11 @@ When(UDSPackage) }); // Watch for changes to the API server EndpointSlice and update the API server CIDR -When(a.Node).IsCreatedOrUpdated().Reconcile(updateKubeNodesFromCreateUpdate); +if (!UDSConfig.kubeNodeCidrs) { + When(a.Node).IsCreatedOrUpdated().Reconcile(updateKubeNodesFromCreateUpdate); +} // Watch for changes to the API server EndpointSlice and update the API server CIDR -When(a.Node).IsDeleted().Reconcile(updateKubeNodesFromDelete); +if (!UDSConfig.kubeNodeCidrs) { + When(a.Node).IsDeleted().Reconcile(updateKubeNodesFromDelete); +} diff --git a/src/pepr/uds-operator-config/values.yaml b/src/pepr/uds-operator-config/values.yaml index dfd236a58..2ff06e045 100644 --- a/src/pepr/uds-operator-config/values.yaml +++ b/src/pepr/uds-operator-config/values.yaml @@ -8,6 +8,7 @@ operator: UDS_LOG_LEVEL: "###ZARF_VAR_UDS_LOG_LEVEL###" AUTHSERVICE_REDIS_URI: "###ZARF_VAR_AUTHSERVICE_REDIS_URI###" KUBEAPI_CIDR: "" + KUBENODE_CIDRS: "" # Allow Pepr watch to be configurable to react to dropped connections faster PEPR_LAST_SEEN_LIMIT_SECONDS: "300" # Allow Pepr to re-list resources more frequently to avoid missing resources