Skip to content

Commit

Permalink
feat: introduce advancedHTTP for expose field & change podLabels to s…
Browse files Browse the repository at this point in the history
…elector (#154)

This PR deprecates `podLabels`, 'remotePodsLabels', and `match` and
changes this to `selector`, `remoteSelector` and `advancedHTTP.match`,
respectively. This PR also introduces `advancedHTTP` which brings
support for the following `VirtualService` fields:

- `corsPolicy`
- `directResponse`
- `headers`
- `retries`
- `rewrite`
- `timeout`
- `weight`

---------

Co-authored-by: Micah Nagel <micah.nagel@defenseunicorns.com>
Co-authored-by: Micah Nagel <micah.nagel@gmail.com>
  • Loading branch information
3 people committed Feb 9, 2024
1 parent bfab11e commit 1079267
Show file tree
Hide file tree
Showing 22 changed files with 790 additions and 240 deletions.
10 changes: 5 additions & 5 deletions src/grafana/chart/templates/uds-package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ spec:
network:
expose:
- service: grafana
podLabels:
selector:
app.kubernetes.io/name: grafana
host: grafana
gateway: admin
Expand All @@ -16,22 +16,22 @@ spec:

allow:
- direction: Ingress
podLabels:
selector:
app.kubernetes.io/name: grafana
remoteNamespace: tempo
remotePodLabels:
remoteSelector:
app.kubernetes.io/name: tempo
port: 9090
description: "Tempo Datasource"

- direction: Egress
podLabels:
selector:
app.kubernetes.io/name: grafana
remoteGenerated: Anywhere

- direction: Egress
remoteNamespace: tempo
remotePodLabels:
remoteSelector:
app.kubernetes.io/name: tempo
port: 9411
description: "Tempo"
16 changes: 8 additions & 8 deletions src/loki/chart/templates/uds-package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,45 +14,45 @@ spec:
remoteGenerated: IntraNamespace

- direction: Ingress
podLabels:
selector:
app.kubernetes.io/name: loki
remoteNamespace: grafana
remotePodLabels:
remoteSelector:
app.kubernetes.io/name: grafana
ports:
- 8080
description: "Grafana Log Queries"

- direction: Ingress
podLabels:
selector:
app.kubernetes.io/name: loki
remoteNamespace: monitoring
remotePodLabels:
remoteSelector:
app.kubernetes.io/name: prometheus
ports:
- 3100
- 8080
description: "Prometheus Metrics"

- direction: Ingress
podLabels:
selector:
app.kubernetes.io/name: loki
remoteNamespace: promtail
remotePodLabels:
remoteSelector:
app.kubernetes.io/name: promtail
ports:
- 8080
description: "Promtail Log Storage"

# Todo: wide open for now for pushing to s3
- direction: Egress
podLabels:
selector:
app.kubernetes.io/name: loki
remoteGenerated: Anywhere

- direction: Egress
remoteNamespace: tempo
remotePodLabels:
remoteSelector:
app.kubernetes.io/name: tempo
port: 9411
description: "Tempo"
6 changes: 3 additions & 3 deletions src/metrics-server/chart/templates/uds-package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ spec:
network:
allow:
- direction: Egress
podLabels:
selector:
app.kubernetes.io/name: metrics-server
# todo: evaluate an "all nodes" generated rule
remoteGenerated: Anywhere
port: 10250
- direction: Egress
podLabels:
selector:
app.kubernetes.io/name: metrics-server
remoteGenerated: KubeAPI
- direction: Ingress
podLabels:
selector:
app.kubernetes.io/name: metrics-server
# todo: evaluate a "KubeAPI" _ingress_ generated rule
remoteGenerated: Anywhere
Expand Down
12 changes: 6 additions & 6 deletions src/neuvector/chart/templates/uds-package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ spec:
network:
expose:
- service: neuvector-service-webui
podLabels:
selector:
app: neuvector-manager-pod
gateway: admin
host: neuvector
Expand All @@ -23,26 +23,26 @@ spec:

- direction: Egress
remoteGenerated: KubeAPI
podLabels:
selector:
app: neuvector-controller-pod

- direction: Egress
remoteGenerated: KubeAPI
podLabels:
selector:
app: neuvector-updater-pod

- direction: Ingress
remoteNamespace: monitoring
remotePodLabels:
remoteSelector:
app: prometheus
podLabels:
selector:
app: neuvector-prometheus-exporter-pod
port: 8068
description: "Prometheus Metrics"

- direction: Egress
remoteNamespace: tempo
remotePodLabels:
remoteSelector:
app.kubernetes.io/name: tempo
port: 9411
description: "Tempo"
10 changes: 8 additions & 2 deletions src/pepr/config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
const isZarfEnv = process.env.UDS_DOMAIN !== "###ZARF_VAR_DOMAIN###";
import { Log } from "pepr";

// We need to handle `npx pepr <>` commands that will not template the env vars
const domain = process.env.UDS_DOMAIN;
const isZarfEnv = domain ? domain !== "###ZARF_VAR_DOMAIN###" : false;

export const UDSConfig = {
// Ignore the UDS_DOMAIN if not deployed by Zarf
domain: (isZarfEnv && process.env.UDS_DOMAIN) || "uds.dev",
domain: (isZarfEnv && domain) || "uds.dev",
// Assume Istio is installed if not deployed by Zarf
istioInstalled: !isZarfEnv || process.env.UDS_WITH_ISTIO === "true",
};

Log.info(UDSConfig, "Loaded UDS Config");
6 changes: 3 additions & 3 deletions src/pepr/operator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ spec:
network:
expose:
- service: grafana
podLabels:
selector:
app.kubernetes.io/name: grafana
host: grafana
gateway: admin
Expand All @@ -29,13 +29,13 @@ spec:

allow:
- direction: Egress
podLabels:
selector:
app.kubernetes.io/name: grafana
remoteGenerated: Anywhere

- direction: Egress
remoteNamespace: tempo
remotePodLabels:
remoteSelector:
app.kubernetes.io/name: tempo
port: 9411
description: "Tempo"
Expand Down
15 changes: 11 additions & 4 deletions src/pepr/operator/controllers/istio/virtual-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export async function virtualService(pkg: UDSPackage, namespace: string) {

// Iterate over each exposed service
for (const expose of exposeList) {
const { gateway = Gateway.Tenant, host, port, service, match } = expose;
const { gateway = Gateway.Tenant, host, port, service, advancedHTTP = {} } = expose;

const name = generateVSName(pkg, expose);

Expand All @@ -32,6 +32,8 @@ export async function virtualService(pkg: UDSPackage, namespace: string) {
// Append the domain to the host
const fqdn = `${host}.${domain}`;

const http: Istio.HTTP = { ...advancedHTTP };

// Create the route to the service
const route: Istio.HTTPRoute[] = [
{
Expand All @@ -44,6 +46,11 @@ export async function virtualService(pkg: UDSPackage, namespace: string) {
},
];

if (!advancedHTTP.directResponse) {
// Create the route to the service if not using advancedHTTP.directResponse
http.route = route;
}

const payload: Istio.VirtualService = {
metadata: {
name,
Expand All @@ -61,7 +68,7 @@ export async function virtualService(pkg: UDSPackage, namespace: string) {
// Map the gateway (admin, passthrough or tenant) to the VirtualService
gateways: [`istio-${gateway}-gateway/${gateway}-gateway`],
// Apply the route to the VirtualService
http: [{ route, match }],
http: [http],
},
};

Expand Down Expand Up @@ -105,10 +112,10 @@ export async function virtualService(pkg: UDSPackage, namespace: string) {
}

export function generateVSName(pkg: UDSPackage, expose: Expose) {
const { gateway = Gateway.Tenant, host, port, service, match, description } = expose;
const { gateway = Gateway.Tenant, host, port, service, description, advancedHTTP } = expose;

// Ensure the resource name is valid
const matchHash = match?.flatMap(m => m.name).join("-") || "";
const matchHash = advancedHTTP?.match?.flatMap(m => m.name).join("-") || "";
const nameSuffix = description || `${host}-${port}-${service}-${matchHash}`;
const name = sanitizeResourceName(`${pkg.metadata!.name}-${gateway}-${nameSuffix}`);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const allowEgressDNS = (namespace: string) => {
direction: Direction.Egress,
description: "DNS lookup via CoreDNS",
remoteNamespace: "kube-system",
remotePodLabels: {
remoteSelector: {
"k8s-app": "kube-dns",
},
port: 53,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const allowEgressIstiod = (namespace: string) =>
direction: Direction.Egress,
description: "Istiod communication",
remoteNamespace: "istio-system",
remotePodLabels: {
remoteSelector: {
istio: "pilot",
},
port: 15012,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const allowIngressSidecarMonitoring = (namespace: string) =>
direction: Direction.Ingress,
description: "Sidecar monitoring",
remoteNamespace: "monitoring",
remotePodLabels: {
remoteSelector: {
app: "prometheus",
},
port: 15020,
Expand Down
12 changes: 6 additions & 6 deletions src/pepr/operator/controllers/network/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function generate(namespace: string, policy: Allow): kind.NetworkPolicy {
spec: {
policyTypes: [policy.direction],
podSelector: {
matchLabels: policy.podLabels,
matchLabels: policy.selector,
},
},
};
Expand Down Expand Up @@ -53,11 +53,11 @@ export function generate(namespace: string, policy: Allow): kind.NetworkPolicy {
peers.push({ namespaceSelector });
}

// Add the remotePodLabels if they exist
if (policy.remotePodLabels) {
// Add the remoteSelector if they exist
if (policy.remoteSelector) {
peers.push({
podSelector: {
matchLabels: policy.remotePodLabels,
matchLabels: policy.remoteSelector,
},
});
}
Expand Down Expand Up @@ -122,10 +122,10 @@ export function generateName(policy: Allow) {
policy.description ||
// Otherwise use the direction, and combination of remote properties
[
Object.values(policy.podLabels || ["all pods"]),
Object.values(policy.selector || ["all pods"]),
policy.remoteGenerated || [
policy.remoteNamespace,
Object.values(policy.remotePodLabels || ["all pods"]),
Object.values(policy.remoteSelector || ["all pods"]),
],
]
// Flatten the array
Expand Down
11 changes: 6 additions & 5 deletions src/pepr/operator/controllers/network/policies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,21 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) {

// Generate NetworkPolicies for any VirtualServices that are generated
const exposeList = pkg.spec?.network?.expose ?? [];
for (const expose of exposeList) {
const { gateway = Gateway.Tenant, port, podLabels, targetPort } = expose;
// Iterate over each exposed service, excluding directResponse services
for (const expose of exposeList.filter(exp => !exp.advancedHTTP?.directResponse)) {
const { gateway = Gateway.Tenant, port, selector = {}, targetPort } = expose;

// Create the NetworkPolicy for the VirtualService
const policy: Allow = {
direction: Direction.Ingress,
podLabels,
selector,
remoteNamespace: `istio-${gateway}-gateway`,
remotePodLabels: {
remoteSelector: {
app: `${gateway}-ingressgateway`,
},
// Use the same port as the VirtualService if targetPort is not set
port: targetPort ?? port,
description: `${Object.values(podLabels)} Istio ${gateway} gateway`,
description: `${Object.values(selector)} Istio ${gateway} gateway`,
};

// Generate the policy
Expand Down
Loading

0 comments on commit 1079267

Please sign in to comment.