From 13ad6adb492b4a888c356a43a2ab0350d65c2e5b Mon Sep 17 00:00:00 2001 From: bzp2010 Date: Tue, 6 Aug 2024 10:03:13 +0800 Subject: [PATCH 1/2] fix: allow ssl cert and key use secret ref --- apps/cli/src/linter/schema.ts | 24 +++++++++++++++--------- schema.json | 30 +++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/apps/cli/src/linter/schema.ts b/apps/cli/src/linter/schema.ts index c484956..34f4461 100644 --- a/apps/cli/src/linter/schema.ts +++ b/apps/cli/src/linter/schema.ts @@ -1,4 +1,3 @@ -import { max } from 'lodash'; import { z } from 'zod'; const nameSchema = z.string().min(1).max(100); @@ -17,14 +16,21 @@ const timeoutSchema = z.object({ read: z.number().gt(0), }); const portSchema = z.number().int().min(1).max(65535); -const certificateSchema = z - .string() - .min(128) - .max(64 * 1024); -const certificateKeySchema = z - .string() - .min(32) - .max(64 * 1024); +const secretRefSchema = z.string().regex(/^\$(secret|env):\/\//); +const certificateSchema = z.union([ + z + .string() + .min(128) + .max(64 * 1024), + secretRefSchema, +]); +const certificateKeySchema = z.union([ + z + .string() + .min(32) + .max(64 * 1024), + secretRefSchema, +]); const upstreamHealthCheckPassiveHealthy = z .object({ diff --git a/schema.json b/schema.json index 7915f7f..c6ee913 100644 --- a/schema.json +++ b/schema.json @@ -380,9 +380,6 @@ "additionalProperties": {} } }, - "required": [ - "nodes" - ], "additionalProperties": false }, "plugins": { @@ -576,14 +573,29 @@ "type": "object", "properties": { "certificate": { - "type": "string", - "minLength": 128, - "maxLength": 65536 + "anyOf": [ + { + "type": "string", + "minLength": 128, + "maxLength": 65536 + }, + { + "type": "string", + "pattern": "^\\$(secret|env):\\/\\/" + } + ] }, "key": { - "type": "string", - "minLength": 32, - "maxLength": 65536 + "anyOf": [ + { + "type": "string", + "minLength": 32, + "maxLength": 65536 + }, + { + "$ref": "#/properties/ssls/items/properties/certificates/items/properties/certificate/anyOf/1" + } + ] } }, "required": [ From 3795b648fa39a934b51d48a52fe31057f48787aa Mon Sep 17 00:00:00 2001 From: bzp2010 Date: Tue, 6 Aug 2024 10:12:15 +0800 Subject: [PATCH 2/2] test: add ssl linter cases --- apps/cli/src/linter/specs/ssl.spec.ts | 90 +++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 apps/cli/src/linter/specs/ssl.spec.ts diff --git a/apps/cli/src/linter/specs/ssl.spec.ts b/apps/cli/src/linter/specs/ssl.spec.ts new file mode 100644 index 0000000..d34d9de --- /dev/null +++ b/apps/cli/src/linter/specs/ssl.spec.ts @@ -0,0 +1,90 @@ +import * as ADCSDK from '@api7/adc-sdk'; + +import { check } from '../'; + +describe('SSL Linter', () => { + const cases = [ + { + name: 'should check for too short certificates and keys', + input: { + ssls: [ + { + snis: ['test.com'], + certificates: [ + { + certificate: 'short', + key: 'short', + }, + ], + }, + ], + } as ADCSDK.Configuration, + expect: false, + errors: [ + { + code: 'too_small', + exact: false, + inclusive: true, + message: 'String must contain at least 128 character(s)', + minimum: 128, + path: ['ssls', 0, 'certificates', 0, 'certificate'], + type: 'string', + }, + { + code: 'too_small', + exact: false, + inclusive: true, + message: 'String must contain at least 32 character(s)', + minimum: 32, + path: ['ssls', 0, 'certificates', 0, 'key'], + type: 'string', + }, + ], + }, + { + name: 'should check for dataplane env ref certificates and keys', + input: { + ssls: [ + { + snis: ['test.com'], + certificates: [ + { + certificate: '$env://CERT', + key: '$env://CERT_KEY', + }, + ], + }, + ], + } as ADCSDK.Configuration, + expect: true, + }, + { + name: 'should check for dataplane secret ref certificates and keys', + input: { + ssls: [ + { + snis: ['test.com'], + certificates: [ + { + certificate: '$secret://vault/test.com/cert', + key: '$secret://vault/test.com/key', + }, + ], + }, + ], + } as ADCSDK.Configuration, + expect: true, + }, + ]; + + // test cases runner + cases.forEach((item) => { + it(item.name, () => { + const result = check(item.input); + expect(result.success).toEqual(item.expect); + if (!item.expect) { + expect(result.error.errors).toEqual(item.errors); + } + }); + }); +});