Skip to content

Commit 67041aa

Browse files
authored
Merge pull request #25 from kubeshop/f1ames/fix/validation-action-sync
fix: fix mapping of validation action for synchronized bindings
2 parents 541babd + bb6eae2 commit 67041aa

File tree

6 files changed

+86
-2
lines changed

6 files changed

+86
-2
lines changed

admission-controller/synchronizer/src/utils/policy-updater.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ export class PolicyUpdater {
216216

217217
return {
218218
policyName: binding.policy.id,
219-
validationActions: ['Warn'],
219+
validationActions: [this.mapValidationAction(binding.action)],
220220
matchResources: {
221221
namespaceSelector: {
222222
matchExpressions: [{
@@ -239,4 +239,18 @@ export class PolicyUpdater {
239239

240240
return _.isEqual(binding1Copy, binding2Copy);
241241
}
242+
243+
protected mapValidationAction(action: string) {
244+
const actionNormalized = (action || '').toLowerCase().trim();
245+
246+
switch (actionNormalized) {
247+
case 'warn':
248+
return 'Warn';
249+
case 'deny':
250+
return 'Deny';
251+
default:
252+
this._logger.error({ msg: 'Unknown validation action.', action });
253+
return action;
254+
}
255+
}
242256
}

admission-controller/synchronizer/src/utils/queries.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export type ClusterQueryResponseBindingPolicy = {
1010
export type ClusterQueryResponseBinding = {
1111
id: string
1212
mode: 'ALLOW_LIST' | 'BLOCK_LIST'
13+
action: 'warn' | 'deny'
1314
namespaces: string[]
1415
policy: ClusterQueryResponseBindingPolicy
1516
};
@@ -53,6 +54,7 @@ export const getClusterQuery = `
5354
bindings {
5455
id
5556
mode
57+
action
5658
namespaces
5759
policy {
5860
id

tests/src/cloud.e2e.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,21 @@ describe(`Cloud (dir: ${mainDir})`, () => {
8181
assertResource(policy2, 'cluster-1-binding-2-policy');
8282
}, 45 * 1000);
8383

84+
it('correctly maps deny action', async () => {
85+
mockServer = await startMockServer('actionDeny');
86+
87+
// Wait for getCluster query to run.
88+
await waitForRequests(mockServer, 2);
89+
// Wait for CRDs propagation.
90+
await sleep(500);
91+
92+
const policy1 = await run('kubectl get monoklepolicy.monokle.io/cluster-1-binding-1-policy -o yaml');
93+
const binding1 = await run('kubectl get monoklepolicybinding.monokle.io/cluster-1-binding-1-deny -o yaml');
94+
95+
assertResource(binding1, 'cluster-1-binding-1-deny');
96+
assertResource(policy1, 'cluster-1-binding-1-policy');
97+
}, 45 * 1000);
98+
8499
// @TODO updates policy CRDs with new data
85100
// @TODO deletes policy CRDs
86101
// @TODO updates binding CRDs with new data

tests/src/utils/expected-crds.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,26 @@ export const EXPECTED_CRDS: Record<string, any> = {
1919
}
2020
}
2121
},
22+
'cluster-1-binding-1-deny': {
23+
apiVersion: 'monokle.io/v1alpha1',
24+
kind: 'MonoklePolicyBinding',
25+
metadata: {
26+
name: 'cluster-1-binding-1-deny'
27+
},
28+
spec: {
29+
policyName: 'cluster-1-binding-1-policy',
30+
validationActions: ['Deny'],
31+
matchResources: {
32+
namespaceSelector: {
33+
matchExpressions: [{
34+
key: 'name',
35+
operator: 'In',
36+
values: ['my-namespace-0'],
37+
}]
38+
}
39+
}
40+
}
41+
},
2242
'cluster-1-binding-2': {
2343
apiVersion: 'monokle.io/v1alpha1',
2444
kind: 'MonoklePolicyBinding',

tests/src/utils/response-mocks.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const RESPONSE_MOCK: Record<string, any> = {
4545
{
4646
id: "cluster-1-binding-1",
4747
mode: "ALLOW_LIST",
48+
action: "warn",
4849
namespaces: ["ns-0","ns-1"],
4950
policy: {
5051
id: "cluster-1-binding-1-policy",
@@ -58,6 +59,7 @@ export const RESPONSE_MOCK: Record<string, any> = {
5859
{
5960
id: "cluster-1-binding-2",
6061
mode: "ALLOW_LIST",
62+
action: "warn",
6163
namespaces: ["ns-2","ns-1"],
6264
policy: {
6365
id: "cluster-1-binding-2-policy",
@@ -71,5 +73,36 @@ export const RESPONSE_MOCK: Record<string, any> = {
7173
]
7274
}
7375
}
76+
},
77+
actionDeny: {
78+
data: {
79+
getCluster: {
80+
id: "cluster-1",
81+
name: "Cluster 1",
82+
namespaceSync: true,
83+
namespaces: [
84+
{
85+
id: "ns-0",
86+
name: "my-namespace-0"
87+
}
88+
],
89+
bindings: [
90+
{
91+
id: "cluster-1-binding-1-deny",
92+
mode: "ALLOW_LIST",
93+
action: "deny",
94+
namespaces: ["ns-0"],
95+
policy: {
96+
id: "cluster-1-binding-1-policy",
97+
content: "plugins:\n open-policy-agent: true\n pod-security-standards: true\n",
98+
project: {
99+
id: "cluster-1-binding-1-policy-project",
100+
name: "cluster-1-binding-1-policy-project"
101+
}
102+
}
103+
}
104+
]
105+
}
106+
}
74107
}
75108
}

tests/src/utils/server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import cors from 'cors';
44
import _ from 'lodash';
55
import {RESPONSE_MOCK} from './response-mocks.js';
66

7-
type ResponseMockName = 'empty' | 'emptySync' | 'dataAllow' | 'dataBlock';
7+
type ResponseMockName = 'empty' | 'emptySync' | 'dataAllow' | 'actionDeny';
88

99
type MockServer = {
1010
server: Server;

0 commit comments

Comments
 (0)