Skip to content

Commit

Permalink
feat: basic working version of admission policy validator
Browse files Browse the repository at this point in the history
  • Loading branch information
topliceanurazvan committed Sep 27, 2023
1 parent 8d1236f commit 9e6ce67
Show file tree
Hide file tree
Showing 12 changed files with 1,141 additions and 12 deletions.
43 changes: 32 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion packages/validation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@
"@monokle/parser": "*",
"@types/isomorphic-fetch": "0.0.36",
"@types/lodash": "4.14.185",
"@types/pako": "^2.0.1",
"@types/require-from-string": "1.2.1",
"@types/uuid": "9.0.1",
"rimraf": "3.0.2",
"esbuild": "0.17.18",
"rimraf": "3.0.2",
"tiny-glob": "0.2.9",
"type-fest": "3.0.0",
"typescript": "4.8.3",
Expand All @@ -65,9 +66,11 @@
"@rollup/plugin-virtual": "3.0.1",
"ajv": "6.12.6",
"change-case": "4.1.2",
"get-random-values": "^3.0.0",
"isomorphic-fetch": "3.0.0",
"lodash": "4.17.21",
"node-fetch": "3.3.0",
"pako": "^2.1.0",
"require-from-string": "2.0.2",
"rollup": "3.18.0",
"uuid": "9.0.0",
Expand Down
56 changes: 56 additions & 0 deletions packages/validation/src/__tests__/MonokleValidator.vap.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {expect, it} from 'vitest';
import {MonokleValidator} from '../MonokleValidator.js';

import {ResourceParser} from '../common/resourceParser.js';
import {DefaultPluginLoader} from '../pluginLoaders/PluginLoader';
import {ValidationConfig} from '@monokle/types';
import {DisabledFixer, SchemaLoader} from '../node.js';
import {
NAMESPACE,
VALIDATING_ADMISSION_POLICY,
VALIDATING_ADMISSION_POLICY_BINDING,
DEPLOYMENT,
} from './admissionPolicyValidatorResources.js';

it('test basic admission policy', async () => {
const parser = new ResourceParser();

const validator = createTestValidator(parser, {
plugins: {
'admission-policy': true,
},
});

const response = await validator.validate({
resources: [NAMESPACE, VALIDATING_ADMISSION_POLICY, VALIDATING_ADMISSION_POLICY_BINDING, DEPLOYMENT],
});

const hasErrors = response.runs.reduce((sum, r) => sum + r.results.length, 0);
expect(hasErrors).toBe(1);
});

function createTestValidator(parser: ResourceParser, config?: ValidationConfig) {
return new MonokleValidator(
{
loader: new DefaultPluginLoader(),
parser,
schemaLoader: new SchemaLoader(),
suppressors: [],
fixer: new DisabledFixer(),
},
config ?? {
plugins: {
'yaml-syntax': true,
'resource-links': true,
'kubernetes-schema': true,
'open-policy-agent': true,
},
settings: {
'kubernetes-schema': {
schemaVersion: '1.24.2',
},
debug: true,
},
}
);
}
153 changes: 153 additions & 0 deletions packages/validation/src/__tests__/admissionPolicyValidatorResources.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import {Resource} from '../index.js';

export const VALIDATING_ADMISSION_POLICY: Resource = {
fileId: '18acb3eb78d60',
filePath: 'policy.yaml',
fileOffset: 0,
text: 'apiVersion: admissionregistration.k8s.io/v1beta1\nkind: ValidatingAdmissionPolicy\nmetadata:\n name: "demo-policy.example.com"\nspec:\n failurePolicy: Fail\n matchConstraints:\n resourceRules:\n - apiGroups: [ "apps" ]\n apiVersions: [ "v1" ]\n operations: [ "CREATE", "UPDATE" ]\n resources: [ "deployments" ]\n validations:\n - expression: "object.spec.replicas > 3"\n',
apiVersion: 'admissionregistration.k8s.io/v1beta1',
kind: 'ValidatingAdmissionPolicy',
content: {
apiVersion: 'admissionregistration.k8s.io/v1beta1',
kind: 'ValidatingAdmissionPolicy',
metadata: {
name: 'demo-policy.example.com',
},
spec: {
failurePolicy: 'Fail',
matchConstraints: {
resourceRules: [
{
apiGroups: ['apps'],
apiVersions: ['v1'],
operations: ['CREATE', 'UPDATE'],
resources: ['deployments'],
},
],
},
validations: [
{
expression: 'object.spec.replicas > 3',
},
],
},
},
id: '18acb3eb78d60-0',
name: 'demo-policy.example.com',
};

export const VALIDATING_ADMISSION_POLICY_BINDING: Resource = {
fileId: '19b972898cc6be',
filePath: 'policy-binding.yaml',
fileOffset: 0,
text: 'apiVersion: admissionregistration.k8s.io/v1beta1\nkind: ValidatingAdmissionPolicyBinding\nmetadata:\n name: "demo-binding-test.example.com"\nspec:\n policyName: "demo-policy.example.com"\n validationActions: [ Deny ]\n matchResources:\n namespaceSelector:\n matchLabels:\n environment: test\n',
apiVersion: 'admissionregistration.k8s.io/v1beta1',
kind: 'ValidatingAdmissionPolicyBinding',
content: {
apiVersion: 'admissionregistration.k8s.io/v1beta1',
kind: 'ValidatingAdmissionPolicyBinding',
metadata: {
name: 'demo-binding-test.example.com',
},
spec: {
policyName: 'demo-policy.example.com',
validationActions: ['Deny'],
matchResources: {
namespaceSelector: {
matchLabels: {
environment: 'test',
},
},
},
},
},
id: '19b972898cc6be-0',
name: 'demo-binding-test.example.com',
};

export const NAMESPACE: Resource = {
fileId: '1926d9cf253e4c',
filePath: 'namespace.yaml',
fileOffset: 0,
text: 'apiVersion: v1\nkind: Namespace\nmetadata:\n name: demo\n labels:\n environment: test\n',
apiVersion: 'v1',
kind: 'Namespace',
content: {
apiVersion: 'v1',
kind: 'Namespace',
metadata: {
name: 'demo',
labels: {
environment: 'test',
},
},
},
id: '1926d9cf253e4c-0',
name: 'demo',
};

export const DEPLOYMENT: Resource = {
fileId: '2f92c46b9eb02',
filePath: 'deployment.yaml',
fileOffset: 0,
text: 'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: nginx-deployment\n namespace: demo\n labels:\n app: nginx\nspec:\n replicas: 5\n selector:\n matchLabels:\n app: nginx\n template:\n metadata:\n labels:\n app: nginx\n spec:\n containers:\n - name: nginx\n image: nginx:1.14.2\n ports:\n - containerPort: 80\n securityContext:\n runAsNonRoot: true\n capabilities:\n drop:\n - ALL\n runAsUser: 10001\n runAsGroup: 10001\n readOnlyRootFilesystem: true\n automountServiceAccountToken: false\n securityContext:\n seccompProfile:\n type: RuntimeDefault\n',
apiVersion: 'apps/v1',
kind: 'Deployment',
content: {
apiVersion: 'apps/v1',
kind: 'Deployment',
metadata: {
name: 'nginx-deployment',
namespace: 'demo',
labels: {
app: 'nginx',
},
},
spec: {
replicas: 2,
selector: {
matchLabels: {
app: 'nginx',
},
},
template: {
metadata: {
labels: {
app: 'nginx',
},
},
spec: {
containers: [
{
name: 'nginx',
image: 'nginx:1.14.2',
ports: [
{
containerPort: 80,
},
],
securityContext: {
runAsNonRoot: true,
capabilities: {
drop: ['ALL'],
},
runAsUser: 10001,
runAsGroup: 10001,
readOnlyRootFilesystem: true,
},
},
],
automountServiceAccountToken: false,
securityContext: {
seccompProfile: {
type: 'RuntimeDefault',
},
},
},
},
},
},
id: '2f92c46b9eb02-0',
name: 'nginx-deployment',
namespace: 'demo',
};
Loading

0 comments on commit 9e6ce67

Please sign in to comment.