Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 40 additions & 6 deletions src/pepr/operator/controllers/istio/ambient-waypoint.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { ambientEgressNamespace, sharedEgressPkgId } from "./istio-resources";
const createMockPackage = (
name: string,
selector: Record<string, string> = {},
mode: "ambient" | "sidecar" = "ambient",
mode: "ambient" | "sidecar" | "unset" = "ambient",
sso: Sso[] = [
{
clientId: "test-client",
Expand All @@ -40,11 +40,14 @@ const createMockPackage = (
uid: "test-uid",
},
spec: {
network: {
serviceMesh: {
mode: mode === "ambient" ? Mode.Ambient : Mode.Sidecar,
},
},
network:
mode === "unset"
? {}
: {
serviceMesh: {
mode: mode === "ambient" ? Mode.Ambient : Mode.Sidecar,
},
},
sso,
},
});
Expand Down Expand Up @@ -319,6 +322,37 @@ describe("reconcileService and reconcilePod", () => {
}
},
);

it.each(testCases)(
"$name - defaults to ambient mode when serviceMesh.mode is undefined",
async ({ createResource, expectedLabels, name }) => {
const resource = createResource();

const pkg = createMockPackage("test-pkg", { "app.kubernetes.io/name": "test-app" }, "unset", [
{
clientId: "test-client",
name: "test-sso",
enableAuthserviceSelector: { "app.kubernetes.io/name": "test-app" },
},
]);

(
PackageStore.getPackageByNamespace as MockedFunction<
typeof PackageStore.getPackageByNamespace
>
).mockImplementation(namespace => {
return namespace === testNamespace ? pkg : undefined;
});

if (name === "service") {
await reconcileService(resource as a.Service);
} else {
await reconcilePod(resource as a.Pod);
}

expect(resource.metadata?.labels).toMatchObject(expectedLabels);
},
);
});

describe("setupAmbientWaypoint", () => {
Expand Down
14 changes: 4 additions & 10 deletions src/pepr/operator/controllers/istio/ambient-waypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,8 @@ export async function reconcileService(svc: a.Service): Promise<void> {
}

const pkg = PackageStore.getPackageByNamespace(namespace);
if (
!pkg ||
pkg.metadata?.deletionTimestamp ||
pkg.spec?.network?.serviceMesh?.mode !== Mode.Ambient
) {
const istioMode = pkg?.spec?.network?.serviceMesh?.mode || Mode.Ambient;
if (!pkg || pkg.metadata?.deletionTimestamp || istioMode !== Mode.Ambient) {
return;
}

Expand Down Expand Up @@ -270,11 +267,8 @@ export async function reconcilePod(pod: a.Pod): Promise<void> {
}

const pkg = PackageStore.getPackageByNamespace(namespace);
if (
!pkg ||
pkg.metadata?.deletionTimestamp ||
pkg.spec?.network?.serviceMesh?.mode !== Mode.Ambient
) {
const istioMode = pkg?.spec?.network?.serviceMesh?.mode || Mode.Ambient;
if (!pkg || pkg.metadata?.deletionTimestamp || istioMode !== Mode.Ambient) {
return;
}

Expand Down
4 changes: 2 additions & 2 deletions src/pepr/operator/controllers/istio/waypoint-utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ describe("shouldUseAmbientWaypoint", () => {
expected: false,
},
{
name: "should return false when no serviceMesh config exists",
name: "should return true when no serviceMesh config exists (ambient default)",
pkg: {
metadata: { name: "test", namespace: "test" },
spec: {
Expand All @@ -106,7 +106,7 @@ describe("shouldUseAmbientWaypoint", () => {
],
},
} as UDSPackage,
expected: false,
expected: true,
},
];

Expand Down
3 changes: 2 additions & 1 deletion src/pepr/operator/controllers/istio/waypoint-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ const WAYPOINT_SUFFIX = "-waypoint"; // Suffix for waypoint resource names
* Determines if a package should use ambient waypoint networking
*/
export const shouldUseAmbientWaypoint = (pkg: UDSPackage): boolean => {
return pkg.spec?.network?.serviceMesh?.mode === Mode.Ambient && hasAuthserviceSSO(pkg);
const istioMode = pkg.spec?.network?.serviceMesh?.mode || Mode.Ambient;
return istioMode === Mode.Ambient && hasAuthserviceSSO(pkg);
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,9 @@ describe("authorization policy generation", () => {
},
],
network: {
serviceMesh: {
mode: Mode.Sidecar,
},
expose: [
{
service: "httpbin",
Expand Down Expand Up @@ -1142,6 +1145,19 @@ describe("findMatchingSsoClient", () => {
expect(findMatchingSsoClient(pkg, { app: "a" })).toBeUndefined();
});

test("defaults to ambient when serviceMesh.mode is undefined", () => {
const pkg: UDSPackage = {
metadata: { name: "app", namespace: "ns" },
spec: {
// No serviceMesh block -> defaults to Ambient
sso: [{ clientId: "c1", name: "", enableAuthserviceSelector: { app: "a" } }],
network: {},
},
};

expect(findMatchingSsoClient(pkg, { app: "a" })).toMatchObject({ clientId: "c1" });
});

test("prefilters to enabled clients only (missing/null/undefined selector are ignored)", () => {
const pkg: UDSPackage = {
metadata: { name: "app", namespace: "ns" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,8 @@ export function findMatchingSsoClient(
pkg: UDSPackage,
selector: Record<string, string> | undefined,
) {
if (!selector || pkg.spec?.network?.serviceMesh?.mode !== Mode.Ambient) {
const istioMode = pkg.spec?.network?.serviceMesh?.mode || Mode.Ambient;
if (!selector || istioMode !== Mode.Ambient) {
return undefined;
}

Expand Down
8 changes: 4 additions & 4 deletions src/pepr/operator/controllers/packages/package-store.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,16 +224,16 @@ describe("Package Store", () => {
const ambientPkg2 = makeMockReq({
metadata: { namespace: "ns2", name: "ambient2" },
spec: {
network: {
serviceMesh: { mode: Mode.Ambient },
},
network: {},
},
}).Raw;

const nonAmbientPkg = makeMockReq({
metadata: { namespace: "ns3", name: "non-ambient" },
spec: {
network: {},
network: {
serviceMesh: { mode: Mode.Sidecar },
},
},
}).Raw;

Expand Down
3 changes: 2 additions & 1 deletion src/pepr/operator/controllers/packages/package-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ function getAmbientPackages(): UDSPackage[] {
const result: UDSPackage[] = [];
for (const namespaceMap of packageNamespaceMap.values()) {
for (const pkg of namespaceMap.values()) {
if (pkg.spec?.network?.serviceMesh?.mode === Mode.Ambient) {
const istioMode = pkg.spec?.network?.serviceMesh?.mode || Mode.Ambient;
if (istioMode === Mode.Ambient) {
result.push(pkg);
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/test/chart/templates/package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ metadata:
namespace: podinfo
spec:
network:
serviceMesh:
mode: ambient
# Relying on default mesh mode
# serviceMesh:
# mode: ambient
expose:
- service: podinfo
selector:
Expand Down
4 changes: 4 additions & 0 deletions test/playwright/podinfo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ test.describe("Podinfo Authservice protection and metrics behavior", () => {

// Basic sanity check that podinfo content is rendered
await expect(page).toHaveURL(podinfoUrl, { timeout: 10000 });

// Verify non-error response (indicates successful JWT validation)
const response = await page.reload();
expect(response?.status()).toBeLessThan(400);
} finally {
await context.close();
}
Expand Down
Loading