From d42566c5c9ebb82b833388a19e5b59c0fc7e422a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Wed, 22 Sep 2021 17:40:56 +0200 Subject: [PATCH] Loosen catalog constraints on entity tag string validity. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding `+` and `#` as valid chars, to e.g. allow "c++" and "c#". Signed-off-by: Gustaf Räntilä --- .changeset/spicy-spies-roll.md | 5 ++++ packages/catalog-model/api-report.md | 1 + .../policies/FieldFormatEntityPolicy.ts | 4 +++ .../CommonValidatorFunctions.test.ts | 25 +++++++++++++++++++ .../validation/CommonValidatorFunctions.ts | 14 +++++++++++ .../src/validation/makeValidator.ts | 2 +- 6 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 .changeset/spicy-spies-roll.md diff --git a/.changeset/spicy-spies-roll.md b/.changeset/spicy-spies-roll.md new file mode 100644 index 0000000000..f20e5b8aae --- /dev/null +++ b/.changeset/spicy-spies-roll.md @@ -0,0 +1,5 @@ +--- +'@backstage/catalog-model': patch +--- + +Loosen constraints on what's a valid catalog entity tag name (include + and #) diff --git a/packages/catalog-model/api-report.md b/packages/catalog-model/api-report.md index 7d734339b3..3f92a671fa 100644 --- a/packages/catalog-model/api-report.md +++ b/packages/catalog-model/api-report.md @@ -50,6 +50,7 @@ export class CommonValidatorFunctions { isValidSuffix: (value: string) => boolean, ): boolean; static isValidString(value: unknown): boolean; + static isValidTag(value: unknown): boolean; static isValidUrl(value: unknown): boolean; } diff --git a/packages/catalog-model/src/entity/policies/FieldFormatEntityPolicy.ts b/packages/catalog-model/src/entity/policies/FieldFormatEntityPolicy.ts index 8655116ec6..b99901b89b 100644 --- a/packages/catalog-model/src/entity/policies/FieldFormatEntityPolicy.ts +++ b/packages/catalog-model/src/entity/policies/FieldFormatEntityPolicy.ts @@ -78,6 +78,10 @@ export class FieldFormatEntityPolicy implements EntityPolicy { expectation = 'a string that is sequences of [a-z0-9] separated by [-], at most 63 characters in total'; break; + case 'isValidTag': + expectation = + 'a string that is sequences of [a-z0-9+#] separated by [-], at most 63 characters in total'; + break; case 'isValidAnnotationValue': expectation = 'a string'; break; diff --git a/packages/catalog-model/src/validation/CommonValidatorFunctions.test.ts b/packages/catalog-model/src/validation/CommonValidatorFunctions.test.ts index b15ac385b1..88e3f9b002 100644 --- a/packages/catalog-model/src/validation/CommonValidatorFunctions.test.ts +++ b/packages/catalog-model/src/validation/CommonValidatorFunctions.test.ts @@ -162,6 +162,31 @@ describe('CommonValidatorFunctions', () => { expect(CommonValidatorFunctions.isValidDnsLabel(value)).toBe(result); }); + it.each([ + // These are identical to isValidDnsLabel + [null, false], + [7, false], + ['', false], + ['a', true], + ['a-b', true], + ['-a-b', false], + ['a-b-', false], + ['a--b', false], + ['a_b', false], + [`${'a'.repeat(63)}`, true], + [`${'a'.repeat(64)}`, false], + // Tags can have other characters though + ['a+b', true], + ['+a+b', true], + ['a+b+', true], + ['a++b', true], + ['c++', true], + ['c#', true], + ['#c++', true], + ])(`isValidTag %p ? %p`, (value, result) => { + expect(CommonValidatorFunctions.isValidTag(value)).toBe(result); + }); + it.each([ [null, false], [7, false], diff --git a/packages/catalog-model/src/validation/CommonValidatorFunctions.ts b/packages/catalog-model/src/validation/CommonValidatorFunctions.ts index 5fcd2ee755..d0357660fc 100644 --- a/packages/catalog-model/src/validation/CommonValidatorFunctions.ts +++ b/packages/catalog-model/src/validation/CommonValidatorFunctions.ts @@ -95,6 +95,20 @@ export class CommonValidatorFunctions { ); } + /** + * Checks that the value is a valid tag. + * + * @param value - The value to check + */ + static isValidTag(value: unknown): boolean { + return ( + typeof value === 'string' && + value.length >= 1 && + value.length <= 63 && + /^[a-z0-9+#]+(\-[a-z0-9+#]+)*$/.test(value) + ); + } + /** * Checks that the value is a valid URL. * diff --git a/packages/catalog-model/src/validation/makeValidator.ts b/packages/catalog-model/src/validation/makeValidator.ts index 48eff566f2..bd6dccc419 100644 --- a/packages/catalog-model/src/validation/makeValidator.ts +++ b/packages/catalog-model/src/validation/makeValidator.ts @@ -27,7 +27,7 @@ const defaultValidators: Validators = { isValidLabelValue: KubernetesValidatorFunctions.isValidLabelValue, isValidAnnotationKey: KubernetesValidatorFunctions.isValidAnnotationKey, isValidAnnotationValue: KubernetesValidatorFunctions.isValidAnnotationValue, - isValidTag: CommonValidatorFunctions.isValidDnsLabel, + isValidTag: CommonValidatorFunctions.isValidTag, }; /** @public */