From cbcfa722ab49a89e8edb637c90f5b445496ccaea Mon Sep 17 00:00:00 2001 From: Dawn James Date: Mon, 27 Mar 2023 17:41:04 +0100 Subject: [PATCH 01/11] Allow a domain entity to have a domain so that a domain hierarchy can be represented. Signed-off-by: Dawn James --- packages/catalog-model/examples/all-domains.yaml | 1 + .../examples/domains/artists-domain.yaml | 1 + .../examples/domains/audio-domain.yaml | 13 +++++++++++++ .../src/kinds/DomainEntityV1alpha1.test.ts | 16 ++++++++++++++++ .../src/kinds/DomainEntityV1alpha1.ts | 1 + .../src/schema/kinds/Domain.v1alpha1.schema.json | 9 ++++++++- 6 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 packages/catalog-model/examples/domains/audio-domain.yaml diff --git a/packages/catalog-model/examples/all-domains.yaml b/packages/catalog-model/examples/all-domains.yaml index 91a8a5b76d..5855fde34b 100644 --- a/packages/catalog-model/examples/all-domains.yaml +++ b/packages/catalog-model/examples/all-domains.yaml @@ -5,5 +5,6 @@ metadata: description: A collection of all Backstage example domains spec: targets: + - ./domains/audio-domain.yaml - ./domains/artists-domain.yaml - ./domains/playback-domain.yaml diff --git a/packages/catalog-model/examples/domains/artists-domain.yaml b/packages/catalog-model/examples/domains/artists-domain.yaml index 2a74425791..44963e8a34 100644 --- a/packages/catalog-model/examples/domains/artists-domain.yaml +++ b/packages/catalog-model/examples/domains/artists-domain.yaml @@ -11,3 +11,4 @@ metadata: icon: dashboard spec: owner: team-a + domain: audio diff --git a/packages/catalog-model/examples/domains/audio-domain.yaml b/packages/catalog-model/examples/domains/audio-domain.yaml new file mode 100644 index 0000000000..c454a7cf8d --- /dev/null +++ b/packages/catalog-model/examples/domains/audio-domain.yaml @@ -0,0 +1,13 @@ +apiVersion: backstage.io/v1alpha1 +kind: Domain +metadata: + name: audio + description: Everything related to audio + links: + - url: http://example.com/domain/audio/ + title: Domain Readme + - url: http://example.com/domains/audio/dashboard + title: Domain Metrics Dashboard + icon: dashboard +spec: + owner: acme-corp diff --git a/packages/catalog-model/src/kinds/DomainEntityV1alpha1.test.ts b/packages/catalog-model/src/kinds/DomainEntityV1alpha1.test.ts index 822a7984e9..40c3e3ee5e 100644 --- a/packages/catalog-model/src/kinds/DomainEntityV1alpha1.test.ts +++ b/packages/catalog-model/src/kinds/DomainEntityV1alpha1.test.ts @@ -31,6 +31,7 @@ describe('DomainV1alpha1Validator', () => { }, spec: { owner: 'me', + domain: 'parent', }, }; }); @@ -68,4 +69,19 @@ describe('DomainV1alpha1Validator', () => { (entity as any).spec.owner = ''; await expect(validator.check(entity)).rejects.toThrow(/owner/); }); + + it('accepts missing domain', async () => { + delete (entity as any).spec.domain; + await expect(validator.check(entity)).resolves.toBe(true); + }); + + it('rejects wrong domain', async () => { + (entity as any).spec.domain = 7; + await expect(validator.check(entity)).rejects.toThrow(/domain/); + }); + + it('rejects empty domain', async () => { + (entity as any).spec.domain = ''; + await expect(validator.check(entity)).rejects.toThrow(/domain/); + }); }); diff --git a/packages/catalog-model/src/kinds/DomainEntityV1alpha1.ts b/packages/catalog-model/src/kinds/DomainEntityV1alpha1.ts index e0302fcc52..dacb5f817b 100644 --- a/packages/catalog-model/src/kinds/DomainEntityV1alpha1.ts +++ b/packages/catalog-model/src/kinds/DomainEntityV1alpha1.ts @@ -32,6 +32,7 @@ export interface DomainEntityV1alpha1 extends Entity { kind: 'Domain'; spec: { owner: string; + domain?: string; }; } diff --git a/packages/catalog-model/src/schema/kinds/Domain.v1alpha1.schema.json b/packages/catalog-model/src/schema/kinds/Domain.v1alpha1.schema.json index a1a09b1213..00549db11b 100644 --- a/packages/catalog-model/src/schema/kinds/Domain.v1alpha1.schema.json +++ b/packages/catalog-model/src/schema/kinds/Domain.v1alpha1.schema.json @@ -11,7 +11,8 @@ "description": "Everything about artists" }, "spec": { - "owner": "artist-relations-team" + "owner": "artist-relations-team", + "domain": "artists" } } ], @@ -38,6 +39,12 @@ "description": "An entity reference to the owner of the component.", "examples": ["artist-relations-team", "user:john.johnson"], "minLength": 1 + }, + "domain": { + "type": "string", + "description": "An entity reference to the domain that the system belongs to.", + "examples": ["artists"], + "minLength": 1 } } } From 79025f3f2890867817c1d476d8693e1a01444ff1 Mon Sep 17 00:00:00 2001 From: Dawn James Date: Mon, 27 Mar 2023 17:59:06 +0100 Subject: [PATCH 02/11] Add a changeset and update docs. Signed-off-by: Dawn James --- .changeset/dry-sloths-impress.md | 5 +++++ docs/features/software-catalog/descriptor-format.md | 1 + 2 files changed, 6 insertions(+) create mode 100644 .changeset/dry-sloths-impress.md diff --git a/.changeset/dry-sloths-impress.md b/.changeset/dry-sloths-impress.md new file mode 100644 index 0000000000..6bd5ba4156 --- /dev/null +++ b/.changeset/dry-sloths-impress.md @@ -0,0 +1,5 @@ +--- +'@backstage/catalog-model': minor +--- + +Introduce a domain attribute to the domain entity to allow a hierarchy of domains to exist. diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md index 52ba540430..1c95cfeb2a 100644 --- a/docs/features/software-catalog/descriptor-format.md +++ b/docs/features/software-catalog/descriptor-format.md @@ -1240,6 +1240,7 @@ metadata: description: Everything about artists spec: owner: artist-relations-team + domain: audio-domain ``` In addition to the [common envelope metadata](#common-to-all-kinds-the-metadata) From 8d96b58adbf74eeeb61b4abfd5e59c9ded2cb67c Mon Sep 17 00:00:00 2001 From: Dawn James Date: Mon, 27 Mar 2023 18:48:11 +0100 Subject: [PATCH 03/11] yarn build:api-reports Signed-off-by: Dawn James --- packages/catalog-model/api-report.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/catalog-model/api-report.md b/packages/catalog-model/api-report.md index b8eb20c590..f204c0b76d 100644 --- a/packages/catalog-model/api-report.md +++ b/packages/catalog-model/api-report.md @@ -122,6 +122,7 @@ interface DomainEntityV1alpha1 extends Entity { // (undocumented) spec: { owner: string; + domain?: string; }; } export { DomainEntityV1alpha1 as DomainEntity }; From 645668a1b3cc3e7b554dbcfe3ab7dc375c6f3b28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jano=20Gonz=C3=A1lez?= Date: Fri, 5 Apr 2024 16:38:46 +0200 Subject: [PATCH 04/11] Change parent domain attribute to subdomainOf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jano González Signed-off-by: Dawn James --- .../examples/domains/artists-domain.yaml | 2 +- .../examples/domains/playback-domain.yaml | 1 + .../src/kinds/DomainEntityV1alpha1.test.ts | 18 +++++++++--------- .../src/kinds/DomainEntityV1alpha1.ts | 2 +- .../schema/kinds/Domain.v1alpha1.schema.json | 8 ++++---- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/packages/catalog-model/examples/domains/artists-domain.yaml b/packages/catalog-model/examples/domains/artists-domain.yaml index 44963e8a34..bf805fc037 100644 --- a/packages/catalog-model/examples/domains/artists-domain.yaml +++ b/packages/catalog-model/examples/domains/artists-domain.yaml @@ -11,4 +11,4 @@ metadata: icon: dashboard spec: owner: team-a - domain: audio + subdomainOf: audio diff --git a/packages/catalog-model/examples/domains/playback-domain.yaml b/packages/catalog-model/examples/domains/playback-domain.yaml index c9933ebf5e..58b5afe56e 100644 --- a/packages/catalog-model/examples/domains/playback-domain.yaml +++ b/packages/catalog-model/examples/domains/playback-domain.yaml @@ -5,3 +5,4 @@ metadata: description: Everything related to audio playback spec: owner: user:frank.tiernan + subdomainOf: audio diff --git a/packages/catalog-model/src/kinds/DomainEntityV1alpha1.test.ts b/packages/catalog-model/src/kinds/DomainEntityV1alpha1.test.ts index 40c3e3ee5e..3c1e7f0a6d 100644 --- a/packages/catalog-model/src/kinds/DomainEntityV1alpha1.test.ts +++ b/packages/catalog-model/src/kinds/DomainEntityV1alpha1.test.ts @@ -31,7 +31,7 @@ describe('DomainV1alpha1Validator', () => { }, spec: { owner: 'me', - domain: 'parent', + subdomainOf: 'parent-domain', }, }; }); @@ -70,18 +70,18 @@ describe('DomainV1alpha1Validator', () => { await expect(validator.check(entity)).rejects.toThrow(/owner/); }); - it('accepts missing domain', async () => { - delete (entity as any).spec.domain; + it('accepts missing subdomainOf', async () => { + delete (entity as any).spec.subdomainOf; await expect(validator.check(entity)).resolves.toBe(true); }); - it('rejects wrong domain', async () => { - (entity as any).spec.domain = 7; - await expect(validator.check(entity)).rejects.toThrow(/domain/); + it('rejects wrong subdomainOf', async () => { + (entity as any).spec.subdomainOf = 7; + await expect(validator.check(entity)).rejects.toThrow(/subdomainOf/); }); - it('rejects empty domain', async () => { - (entity as any).spec.domain = ''; - await expect(validator.check(entity)).rejects.toThrow(/domain/); + it('rejects empty subdomainOf', async () => { + (entity as any).spec.subdomainOf = ''; + await expect(validator.check(entity)).rejects.toThrow(/subdomainOf/); }); }); diff --git a/packages/catalog-model/src/kinds/DomainEntityV1alpha1.ts b/packages/catalog-model/src/kinds/DomainEntityV1alpha1.ts index dacb5f817b..1fe3dfb522 100644 --- a/packages/catalog-model/src/kinds/DomainEntityV1alpha1.ts +++ b/packages/catalog-model/src/kinds/DomainEntityV1alpha1.ts @@ -32,7 +32,7 @@ export interface DomainEntityV1alpha1 extends Entity { kind: 'Domain'; spec: { owner: string; - domain?: string; + subdomainOf?: string; }; } diff --git a/packages/catalog-model/src/schema/kinds/Domain.v1alpha1.schema.json b/packages/catalog-model/src/schema/kinds/Domain.v1alpha1.schema.json index 00549db11b..7d0d7e25ff 100644 --- a/packages/catalog-model/src/schema/kinds/Domain.v1alpha1.schema.json +++ b/packages/catalog-model/src/schema/kinds/Domain.v1alpha1.schema.json @@ -12,7 +12,7 @@ }, "spec": { "owner": "artist-relations-team", - "domain": "artists" + "subdomainOf": "audio" } } ], @@ -40,10 +40,10 @@ "examples": ["artist-relations-team", "user:john.johnson"], "minLength": 1 }, - "domain": { + "subdomainOf": { "type": "string", - "description": "An entity reference to the domain that the system belongs to.", - "examples": ["artists"], + "description": "An entity reference to another domain of which the domain is a part.", + "examples": ["audio"], "minLength": 1 } } From 889b017b907350e5de7ecf8c5c11be42152661e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jano=20Gonz=C3=A1lez?= Date: Fri, 5 Apr 2024 16:40:02 +0200 Subject: [PATCH 05/11] Generate relations for subdomainOf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jano González Signed-off-by: Dawn James --- .../core/BuiltinKindsEntityProcessor.test.ts | 19 ++++++++++++++++++- .../core/BuiltinKindsEntityProcessor.ts | 6 ++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/plugins/catalog-backend/src/modules/core/BuiltinKindsEntityProcessor.test.ts b/plugins/catalog-backend/src/modules/core/BuiltinKindsEntityProcessor.test.ts index dbb9922fe0..e0368d40a6 100644 --- a/plugins/catalog-backend/src/modules/core/BuiltinKindsEntityProcessor.test.ts +++ b/plugins/catalog-backend/src/modules/core/BuiltinKindsEntityProcessor.test.ts @@ -418,12 +418,13 @@ describe('BuiltinKindsEntityProcessor', () => { metadata: { name: 'n' }, spec: { owner: 'o', + subdomainOf: 'p', }, }; await processor.postProcessEntity(entity, location, emit); - expect(emit).toHaveBeenCalledTimes(2); + expect(emit).toHaveBeenCalledTimes(4); expect(emit).toHaveBeenCalledWith({ type: 'relation', relation: { @@ -440,6 +441,22 @@ describe('BuiltinKindsEntityProcessor', () => { target: { kind: 'Group', namespace: 'default', name: 'o' }, }, }); + expect(emit).toHaveBeenCalledWith({ + type: 'relation', + relation: { + source: { kind: 'Domain', namespace: 'default', name: 'n' }, + type: 'partOf', + target: { kind: 'Domain', namespace: 'default', name: 'p' }, + }, + }); + expect(emit).toHaveBeenCalledWith({ + type: 'relation', + relation: { + source: { kind: 'Domain', namespace: 'default', name: 'p' }, + type: 'hasPart', + target: { kind: 'Domain', namespace: 'default', name: 'n' }, + }, + }); }); it('generates relations for user entities', async () => { diff --git a/plugins/catalog-backend/src/modules/core/BuiltinKindsEntityProcessor.ts b/plugins/catalog-backend/src/modules/core/BuiltinKindsEntityProcessor.ts index 4dbb23addc..c9ea0dbdc1 100644 --- a/plugins/catalog-backend/src/modules/core/BuiltinKindsEntityProcessor.ts +++ b/plugins/catalog-backend/src/modules/core/BuiltinKindsEntityProcessor.ts @@ -298,6 +298,12 @@ export class BuiltinKindsEntityProcessor implements CatalogProcessor { RELATION_OWNED_BY, RELATION_OWNER_OF, ); + doEmit( + domain.spec.subdomainOf, + { defaultKind: 'Domain', defaultNamespace: selfRef.namespace }, + RELATION_PART_OF, + RELATION_HAS_PART, + ); } return entity; From a8a21fabc672e663953d0342d7eed5fcb652d764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jano=20Gonz=C3=A1lez?= Date: Fri, 5 Apr 2024 16:39:17 +0200 Subject: [PATCH 06/11] Document subdomainOf attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jano González Signed-off-by: Dawn James --- docs/features/software-catalog/descriptor-format.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md index 1c95cfeb2a..f14f211ca9 100644 --- a/docs/features/software-catalog/descriptor-format.md +++ b/docs/features/software-catalog/descriptor-format.md @@ -1269,6 +1269,15 @@ but there will always be one ultimate owner. | ------------------------------------------------------ | ------------------------------------------ | ------------------------------------------------------------------------------- | | [`Group`](#kind-group) (default), [`User`](#kind-user) | Same as this entity, typically `default` | [`ownerOf`, and reverse `ownedBy`](well-known-relations.md#ownedby-and-ownerof) | +### `spec.subdomainOf` [optional] + +An [entity reference](references.md#string-references) to another domain of +which the domain is a part, e.g. `audio`. This field is optional. + +| [`kind`](#apiversion-and-kind-required) | Default [`namespace`](#namespace-optional) | Generated [relation](well-known-relations.md) type | +| --------------------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------- | +| [`Domain`](#kind-domain) | Same as this entity, typically `default` | [`partOf`, and reverse `hasPart`](well-known-relations.md#partof-and-haspart) | + ## Kind: Location Describes the following entity kind: From 4ba5aa681b8cf4c2729bcb5fa950601c3d797aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jano=20Gonz=C3=A1lez?= Date: Mon, 8 Apr 2024 14:43:03 +0200 Subject: [PATCH 07/11] run yarn build:api-reports Signed-off-by: Dawn James --- packages/catalog-model/api-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/catalog-model/api-report.md b/packages/catalog-model/api-report.md index f204c0b76d..2d91fa44a5 100644 --- a/packages/catalog-model/api-report.md +++ b/packages/catalog-model/api-report.md @@ -122,7 +122,7 @@ interface DomainEntityV1alpha1 extends Entity { // (undocumented) spec: { owner: string; - domain?: string; + subdomainOf?: string; }; } export { DomainEntityV1alpha1 as DomainEntity }; From 593a773b2a78b3874a0a84f3140f3c84e766379c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jano=20Gonz=C3=A1lez?= Date: Tue, 9 Apr 2024 12:09:14 +0200 Subject: [PATCH 08/11] Fix descriptor format for domain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jano González Signed-off-by: Dawn James --- docs/features/software-catalog/descriptor-format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md index f14f211ca9..ac810b611d 100644 --- a/docs/features/software-catalog/descriptor-format.md +++ b/docs/features/software-catalog/descriptor-format.md @@ -1240,7 +1240,7 @@ metadata: description: Everything about artists spec: owner: artist-relations-team - domain: audio-domain + subdomainOf: audio-domain ``` In addition to the [common envelope metadata](#common-to-all-kinds-the-metadata) From ba7bd1b893f3c4ae0553ab15708e9c7a1cd42e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jano=20Gonz=C3=A1lez?= Date: Tue, 9 Apr 2024 12:11:49 +0200 Subject: [PATCH 09/11] Update well known relations doc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jano González Signed-off-by: Dawn James --- docs/features/software-catalog/well-known-relations.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/features/software-catalog/well-known-relations.md b/docs/features/software-catalog/well-known-relations.md index bfcbcb780a..6d61847a15 100644 --- a/docs/features/software-catalog/well-known-relations.md +++ b/docs/features/software-catalog/well-known-relations.md @@ -99,11 +99,12 @@ A relation with a [Domain](descriptor-format.md#kind-domain), [System](descriptor-format.md#kind-system) or [Component](descriptor-format.md#kind-component) entity, typically from a [Component](descriptor-format.md#kind-component), -[API](descriptor-format.md#kind-api), or -[System](descriptor-format.md#kind-system). +[API](descriptor-format.md#kind-api), +[System](descriptor-format.md#kind-system), or +[Domain](descriptor-format.md#kind-domain), These relations express that a component belongs to a larger component; a -component, API or resource belongs to a system; or that a system is grouped -under a domain. +component, API or resource belongs to a system; that a system is grouped +under a domain; or that a domain belongs to a larger domain. This relation is commonly based on `spec.system` or `spec.domain`. From 8d1447559af08c01b13aac15dcc3edf9afd29a04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jano=20Gonz=C3=A1lez?= Date: Thu, 11 Apr 2024 11:38:28 +0200 Subject: [PATCH 10/11] Add changeset for plugin-catalog-backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jano González Signed-off-by: Dawn James --- .changeset/sour-socks-approve.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/sour-socks-approve.md diff --git a/.changeset/sour-socks-approve.md b/.changeset/sour-socks-approve.md new file mode 100644 index 0000000000..db40806280 --- /dev/null +++ b/.changeset/sour-socks-approve.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': minor +--- + +Emit well known relationships for the Domain entity kind. From a2ce77a1cef892bd4d7b904a1bbff73bc7fb01a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 22 Apr 2024 14:00:48 +0200 Subject: [PATCH 11/11] Update docs/features/software-catalog/descriptor-format.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- docs/features/software-catalog/descriptor-format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md index ac810b611d..140696a85d 100644 --- a/docs/features/software-catalog/descriptor-format.md +++ b/docs/features/software-catalog/descriptor-format.md @@ -1276,7 +1276,7 @@ which the domain is a part, e.g. `audio`. This field is optional. | [`kind`](#apiversion-and-kind-required) | Default [`namespace`](#namespace-optional) | Generated [relation](well-known-relations.md) type | | --------------------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------- | -| [`Domain`](#kind-domain) | Same as this entity, typically `default` | [`partOf`, and reverse `hasPart`](well-known-relations.md#partof-and-haspart) | +| [`Domain`](#kind-domain) (default) | Same as this entity, typically `default` | [`partOf`, and reverse `hasPart`](well-known-relations.md#partof-and-haspart) | ## Kind: Location