Skip to content

Commit

Permalink
RESP-10243: Add support for backlinking an enum to the catalog type t…
Browse files Browse the repository at this point in the history
…hat created it (#155)

This feature enables the importer to automatically create a backlink
from the catalog type the enum creates to the catalog type that the enum
is created from.

Example:
An **Integration** can have an enum of **contacts** 
<img width="1410" alt="Screenshot 2025-01-15 at 14 40 51"
src="https://github.com/user-attachments/assets/0369a8a6-676e-45b7-be98-5de5c397d184"
/>

With `enable_backfill` set to true, **Integration Contact** will have an
**Integration** backlink attribute automatically created

<img width="1410" alt="Screenshot 2025-01-15 at 14 41 44"
src="https://github.com/user-attachments/assets/46047f63-c563-4fa6-9664-8611239d58ef"
/>
  • Loading branch information
aaronsheah authored Jan 15, 2025
1 parent 10d93d4 commit 8d0f02c
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 15 deletions.
69 changes: 69 additions & 0 deletions docs/outputs.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,72 @@ given a single attribute:
For more information on how to use filter expressions, read [Using
expressions](expressions.md) or look at the [Backstage](backstage) example for
real-life use cases.

### Enum attribute

Enums are useful when you have an attribute of 'String' type (both array and non-array), that you'd like to have as as separate catalog type, such as tags. Using the above example of `BackstageAPIType`, we can instead generate it from `BackstageAPI`

```jsonnet
{
sync_id: 'example-org/example-repo',
pipelines: [
// Backstage API
{
sources: [
{
inline: {
entries: [
{
name: "Payments API",
external_id: "payments"
type: "grpc",
}
],
},
},
],
outputs: [
{
name: 'Backstage API',
description: 'APIs that we have',
type_name: 'Custom["BackstageAPI"]',
source: {
name: 'name',
external_id: 'external_id',
},
categories: ['service'],
attributes: [
{
id: "type",
name: "API type",
array: false,
source: "$.type"
enum: {
name: 'Backstage API Type',
description: 'Type or format of the API.',
type_name: 'Custom["BackstageAPIType"]',
enable_backlink: true,
},
},
],
},
],
},
],
}
```

The above we generate the following catalog types:

- `BackstageAPI` with attributes:
- `Name`
- `API type`
- `BackstageAPIType` with attributes:
- `Name`
- `Backstage API`

The `enable_backlink` option allows you to specify if the created enum should have an attribute pointing back to the
attribute that created it. If disabled, the `BackstageAPIType` above will not have a `Backstage API` attribute.


See [simple/importer.jsonnet](https://github.com/incident-io/catalog-importer/blob/bbb659c312af7c45a626a68643e1cd4e890376d5/docs/simple/importer.jsonnet#L161-L166) for a working example
3 changes: 3 additions & 0 deletions docs/simple/catalog.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,9 @@
name: 'Zoom',
description: 'Use Zoom to automatically start call links for your incident channels, and more.',
owner: 'response',
contacts: [
'[email protected]',
]
},
]
],
Expand Down
12 changes: 12 additions & 0 deletions docs/simple/importer.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,18 @@ local catalog = import 'catalog.jsonnet';
type: 'Text',
source: '$.description',
},
{
id: 'contacts',
name: 'Contacts',
array: true,
source: '$.contacts',
enum: {
name: 'Integration Contact',
type_name: 'Custom["IntegrationContact"]',
description: 'Contact we have in the company for this integration.',
enable_backlink: true,
}
}
],
},
],
Expand Down
38 changes: 26 additions & 12 deletions output/marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,19 +85,33 @@ func MarshalType(output *Output) (base *CatalogTypeModel, enumTypes []*CatalogTy
// The enums we generate should be returned as types too, as we'll need to sync them
// just as any other.
if attr.Enum != nil {
enumTypes = append(enumTypes, &CatalogTypeModel{
Name: attr.Enum.Name,
Description: attr.Enum.Description,
TypeName: attr.Enum.TypeName,
Ranked: output.Ranked,
Attributes: []client.CatalogTypeAttributePayloadV2{
{
Id: lo.ToPtr("description"),
Name: "Description",
Type: "String",
Mode: lo.ToPtr(client.CatalogTypeAttributePayloadV2ModeManual),
},
attributes := []client.CatalogTypeAttributePayloadV2{
{
Id: lo.ToPtr("description"),
Name: "Description",
Type: "String",
Mode: lo.ToPtr(client.CatalogTypeAttributePayloadV2ModeManual),
},
}
if attr.Enum.EnableBacklink {
attributes = append(attributes,
client.CatalogTypeAttributePayloadV2{
Id: lo.ToPtr("enum_backlink"),
Name: base.Name,
Type: base.TypeName,
// An enum value can be used by multiple entries,
// by definition enums are either one-to-many or many-to-many.
Array: true,
BacklinkAttribute: lo.ToPtr(attr.ID),
Mode: lo.ToPtr(client.CatalogTypeAttributePayloadV2ModeBacklink),
})
}
enumTypes = append(enumTypes, &CatalogTypeModel{
Name: attr.Enum.Name,
Description: attr.Enum.Description,
TypeName: attr.Enum.TypeName,
Ranked: output.Ranked,
Attributes: attributes,
SourceAttribute: lo.ToPtr(*attr),
})
}
Expand Down
7 changes: 4 additions & 3 deletions output/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ func (a Attribute) Validate() error {
}

type AttributeEnum struct {
Name string `json:"name"`
Description string `json:"description"`
TypeName string `json:"type_name"`
Name string `json:"name"`
Description string `json:"description"`
TypeName string `json:"type_name"`
EnableBacklink bool `json:"enable_backlink"`
}

0 comments on commit 8d0f02c

Please sign in to comment.