From f25700217df3d01e48c5f50e7108ded4c4549aa9 Mon Sep 17 00:00:00 2001 From: Gerson Trujillo Date: Thu, 24 Oct 2024 12:30:25 +0200 Subject: [PATCH 1/4] updating okta readme --- .../catalog-backend-module-okta/README.md | 100 +++++++++++++----- 1 file changed, 71 insertions(+), 29 deletions(-) diff --git a/plugins/backend/catalog-backend-module-okta/README.md b/plugins/backend/catalog-backend-module-okta/README.md index 7719f7d6d..c9046f21b 100644 --- a/plugins/backend/catalog-backend-module-okta/README.md +++ b/plugins/backend/catalog-backend-module-okta/README.md @@ -5,6 +5,12 @@ entity providers to read Okta Group and User objects as Backstage Entities. To setup the Okta providers you will need an [Okta API Token](https://developer.okta.com/docs/guides/create-an-api-token/main/) +## Installation +To install the plugin dependency in your Backstage app, from the root of your project run: + +```bash +yarn --cwd packages/backend add @roadiehq/catalog-backend-module-okta +``` ## App Config You will need to configure your okta credentials in the `app-config.yaml`. @@ -71,62 +77,98 @@ catalog: minutes: 1 ``` -## Adding the provider with default configuration +## Adding the provider +First, add the required okta-entity-provider dependency to your backend in the `packages/backend/src/index.ts` file: +```typescript +backend.add( + import('@roadiehq/catalog-backend-module-okta/okta-entity-provider'), +); +``` -The Okta catalog module provides default implementations of 3 entity providers that can be used with the Backstage backend system. +Now, you need to add a provider factory that will define the strategy used to load users and groups. We provide three default +factory that you can use out of the box, or your can create your own custom one, let's explore both options. -To integrate these into your application, you can use the following lines in your Backstage backend entry file: +### Default entity providers +The Okta catalog module provides default implementations of 3 entity providers that can be used with the Backstage backend system. +To integrate these into your application, add them after the okta-entity-provider, like this: ```typescript backend.add( - import('@roadiehq/catalog-backend-module-okta/okta-entity-provider'), + import('@roadiehq/catalog-backend-module-okta/okta-entity-provider'), // The required entity provider ); backend.add( - import('@roadiehq/catalog-backend-module-okta/org-provider-factory'), + import('@roadiehq/catalog-backend-module-okta/org-provider-factory'), // Optional - Load both users and groups ); ``` -You need to register the `okta-entity-provider` module and one of three options for the provider factory. The provider factory decides which kind of entities are provided for you. You can either use the `OktaOrgEntityProvider` found as `org-provider-factory` which loads both users and groups. Or you can load user or groups separately user the `OktaUserEntityProvider` (`user-provider-factory`) and `OktaGroupEntityProvider` (`group-provider-factory`) providers. +The provider factory decides which kind of entities are provided for you. +The options are: + +- `org-provider-factory` - Loads both users and groups +- `user-provider-factory` - Loads only users +- `group-provider-factory` - Loads only groups -Note that this is the automatic configuration of provider factories and does not allow customization of naming strategies or other configurations. -## Adding provider(s) with customized configuration + +## Custom entity provider(s) + +Instead of using the default entity providers, you can create your own custom entity provider(s) by implementing the `EntityProvider` interface. You can also tailor the entity providers to handle different configurations if there is a need to add specific logic for example naming strategies for your entities. +> ⚠️ **Note:** You use either the custom entity provider\(s\) or the default ones, not both. ### Load Users and Groups Together - OktaOrgEntityProvider You can construct your own configuration of OktaOrgEntityProvider factory and register it into the backend: +In a separated file of your choice, to avoid cluttering the `packages/backend/src/index.ts` file, + you can create a new module that will contain the custom entity provider registration logic. + ```typescript -export const oktaOrgEntityProviderModule = createBackendModule({ - pluginId: 'catalog', - moduleId: 'default-okta-org-entity-provider', - register(env) { - env.registerInit({ - deps: { - provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, - logger: coreServices.logger, - }, - async init({ provider, logger }) { - const factory: EntityProviderFactory = (oktaConfig: Config) => - OktaOrgEntityProvider.fromConfig(oktaConfig, { - logger: logger, - userNamingStrategy: 'strip-domain-email', - groupNamingStrategy: 'kebab-case-name', - }); +import { + createBackendModule, + coreServices, +} from '@backstage/backend-plugin-api'; +import { + oktaCatalogBackendEntityProviderFactoryExtensionPoint, + EntityProviderFactory, + OktaOrgEntityProvider, +} from '@roadiehq/catalog-backend-module-okta/new-backend'; +import { Config } from '@backstage/config'; - provider.setEntityProviderFactory(factory); - }, - }); - }, +export const oktaOrgEntityProviderModule = createBackendModule({ + pluginId: 'catalog', + moduleId: 'default-okta-org-entity-provider', + register(env) { + env.registerInit({ + deps: { + provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, + logger: coreServices.logger, + }, + async init({ provider, logger }) { + const factory: EntityProviderFactory = (oktaConfig: Config) => + OktaOrgEntityProvider.fromConfig(oktaConfig, { + logger: logger, + userNamingStrategy: 'strip-domain-email', + groupNamingStrategy: 'kebab-case-name', + }); + + provider.setEntityProviderFactory(factory); + }, + }); + }, }); +``` -// ...snip... +This is your custom entity provider module. You can now add it to the backend in the `packages/backend/src/index.ts` file: +```typescript +// We need to comment or remove the default entity provider, since now we have a custom one. +// backend.add(import('@roadiehq/catalog-backend-module-okta/org-provider-factory')); backend.add(oktaOrgEntityProviderModule); ``` + You can configure the provider with different naming strategies. The configured strategy will be used to generate the discovered entity's `metadata.name` field. The currently supported strategies are the following: #### User naming strategies From d6c256f1afabeff7792fa7eff5a3885fd380f97f Mon Sep 17 00:00:00 2001 From: Jussi Hallila Date: Thu, 24 Oct 2024 14:36:42 +0200 Subject: [PATCH 2/4] Run prettier. Add changeset --- .changeset/cuddly-snakes-beam.md | 5 ++ .../catalog-backend-module-okta/README.md | 66 ++++++++++--------- 2 files changed, 40 insertions(+), 31 deletions(-) create mode 100644 .changeset/cuddly-snakes-beam.md diff --git a/.changeset/cuddly-snakes-beam.md b/.changeset/cuddly-snakes-beam.md new file mode 100644 index 000000000..ef0e70eab --- /dev/null +++ b/.changeset/cuddly-snakes-beam.md @@ -0,0 +1,5 @@ +--- +'@roadiehq/catalog-backend-module-okta': patch +--- + +Update README.md diff --git a/plugins/backend/catalog-backend-module-okta/README.md b/plugins/backend/catalog-backend-module-okta/README.md index c9046f21b..f27127c71 100644 --- a/plugins/backend/catalog-backend-module-okta/README.md +++ b/plugins/backend/catalog-backend-module-okta/README.md @@ -6,11 +6,13 @@ entity providers to read Okta Group and User objects as Backstage Entities. To setup the Okta providers you will need an [Okta API Token](https://developer.okta.com/docs/guides/create-an-api-token/main/) ## Installation + To install the plugin dependency in your Backstage app, from the root of your project run: ```bash yarn --cwd packages/backend add @roadiehq/catalog-backend-module-okta ``` + ## App Config You will need to configure your okta credentials in the `app-config.yaml`. @@ -78,20 +80,24 @@ catalog: ``` ## Adding the provider + First, add the required okta-entity-provider dependency to your backend in the `packages/backend/src/index.ts` file: + ```typescript backend.add( - import('@roadiehq/catalog-backend-module-okta/okta-entity-provider'), + import('@roadiehq/catalog-backend-module-okta/okta-entity-provider'), ); ``` Now, you need to add a provider factory that will define the strategy used to load users and groups. We provide three default factory that you can use out of the box, or your can create your own custom one, let's explore both options. -### Default entity providers +### Default entity providers + The Okta catalog module provides default implementations of 3 entity providers that can be used with the Backstage backend system. To integrate these into your application, add them after the okta-entity-provider, like this: + ```typescript backend.add( import('@roadiehq/catalog-backend-module-okta/okta-entity-provider'), // The required entity provider @@ -108,8 +114,6 @@ The options are: - `user-provider-factory` - Loads only users - `group-provider-factory` - Loads only groups - - ## Custom entity provider(s) Instead of using the default entity providers, you can create your own custom entity provider(s) by implementing the `EntityProvider` interface. @@ -117,46 +121,47 @@ Instead of using the default entity providers, you can create your own custom en You can also tailor the entity providers to handle different configurations if there is a need to add specific logic for example naming strategies for your entities. > ⚠️ **Note:** You use either the custom entity provider\(s\) or the default ones, not both. + ### Load Users and Groups Together - OktaOrgEntityProvider You can construct your own configuration of OktaOrgEntityProvider factory and register it into the backend: In a separated file of your choice, to avoid cluttering the `packages/backend/src/index.ts` file, - you can create a new module that will contain the custom entity provider registration logic. +you can create a new module that will contain the custom entity provider registration logic. ```typescript import { - createBackendModule, - coreServices, + createBackendModule, + coreServices, } from '@backstage/backend-plugin-api'; import { - oktaCatalogBackendEntityProviderFactoryExtensionPoint, - EntityProviderFactory, - OktaOrgEntityProvider, + oktaCatalogBackendEntityProviderFactoryExtensionPoint, + EntityProviderFactory, + OktaOrgEntityProvider, } from '@roadiehq/catalog-backend-module-okta/new-backend'; import { Config } from '@backstage/config'; export const oktaOrgEntityProviderModule = createBackendModule({ - pluginId: 'catalog', - moduleId: 'default-okta-org-entity-provider', - register(env) { - env.registerInit({ - deps: { - provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, - logger: coreServices.logger, - }, - async init({ provider, logger }) { - const factory: EntityProviderFactory = (oktaConfig: Config) => - OktaOrgEntityProvider.fromConfig(oktaConfig, { - logger: logger, - userNamingStrategy: 'strip-domain-email', - groupNamingStrategy: 'kebab-case-name', - }); - - provider.setEntityProviderFactory(factory); - }, - }); - }, + pluginId: 'catalog', + moduleId: 'default-okta-org-entity-provider', + register(env) { + env.registerInit({ + deps: { + provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, + logger: coreServices.logger, + }, + async init({ provider, logger }) { + const factory: EntityProviderFactory = (oktaConfig: Config) => + OktaOrgEntityProvider.fromConfig(oktaConfig, { + logger: logger, + userNamingStrategy: 'strip-domain-email', + groupNamingStrategy: 'kebab-case-name', + }); + + provider.setEntityProviderFactory(factory); + }, + }); + }, }); ``` @@ -168,7 +173,6 @@ This is your custom entity provider module. You can now add it to the backend in backend.add(oktaOrgEntityProviderModule); ``` - You can configure the provider with different naming strategies. The configured strategy will be used to generate the discovered entity's `metadata.name` field. The currently supported strategies are the following: #### User naming strategies From e49432414ea54c96db0d15ea36411eb3395260a6 Mon Sep 17 00:00:00 2001 From: Gerson Trujillo Date: Thu, 24 Oct 2024 14:40:14 +0200 Subject: [PATCH 3/4] formatting --- .../catalog-backend-module-okta/README.md | 485 +++++++++--------- 1 file changed, 253 insertions(+), 232 deletions(-) diff --git a/plugins/backend/catalog-backend-module-okta/README.md b/plugins/backend/catalog-backend-module-okta/README.md index f27127c71..2c1262702 100644 --- a/plugins/backend/catalog-backend-module-okta/README.md +++ b/plugins/backend/catalog-backend-module-okta/README.md @@ -3,7 +3,8 @@ This is an extension module to the plugin-catalog-backend plugin, providing entity providers to read Okta Group and User objects as Backstage Entities. -To setup the Okta providers you will need an [Okta API Token](https://developer.okta.com/docs/guides/create-an-api-token/main/) +To setup the Okta providers you will need +an [Okta API Token](https://developer.okta.com/docs/guides/create-an-api-token/main/) ## Installation @@ -36,7 +37,9 @@ catalog: ### OAuth 2.0 Scoped Authentication -[Create an OAuth app](https://developer.okta.com/docs/guides/implement-oauth-for-okta/main/#create-an-oauth-2-0-app-in-okta) in Okta. You will need to grant it with the `okta.groups.read` and `okta.users.read` scopes as a bare minimum. In the following example the `oauth.privateKey` may be passed as either a string encoded PEM or stringified JWK. +[Create an OAuth app](https://developer.okta.com/docs/guides/implement-oauth-for-okta/main/#create-an-oauth-2-0-app-in-okta) +in Okta. You will need to grant it with the `okta.groups.read` and `okta.users.read` scopes as a bare minimum. In the +following example the `oauth.privateKey` may be passed as either a string encoded PEM or stringified JWK. ```yaml catalog: @@ -60,7 +63,8 @@ Note: `keyId` is optional but _must_ be passed when using a PEM as the `privateK ### Filter Users and Groups -The provider allows configuring Okta search filtering for users and groups. See here for more details on what is possible: https://developer.okta.com/docs/reference/core-okta-api/#filter +The provider allows configuring Okta search filtering for users and groups. See here for more details on what is +possible: https://developer.okta.com/docs/reference/core-okta-api/#filter ```yaml catalog: @@ -85,25 +89,27 @@ First, add the required okta-entity-provider dependency to your backend in the ` ```typescript backend.add( - import('@roadiehq/catalog-backend-module-okta/okta-entity-provider'), + import('@roadiehq/catalog-backend-module-okta/okta-entity-provider'), ); ``` -Now, you need to add a provider factory that will define the strategy used to load users and groups. We provide three default +Now, you need to add a provider factory that will define the strategy used to load users and groups. We provide three +default factory that you can use out of the box, or your can create your own custom one, let's explore both options. ### Default entity providers -The Okta catalog module provides default implementations of 3 entity providers that can be used with the Backstage backend system. +The Okta catalog module provides default implementations of 3 entity providers that can be used with the Backstage +backend system. To integrate these into your application, add them after the okta-entity-provider, like this: ```typescript backend.add( - import('@roadiehq/catalog-backend-module-okta/okta-entity-provider'), // The required entity provider + import('@roadiehq/catalog-backend-module-okta/okta-entity-provider'), // The required entity provider ); backend.add( - import('@roadiehq/catalog-backend-module-okta/org-provider-factory'), // Optional - Load both users and groups + import('@roadiehq/catalog-backend-module-okta/org-provider-factory'), // Optional - Load both users and groups ); ``` @@ -116,9 +122,11 @@ The options are: ## Custom entity provider(s) -Instead of using the default entity providers, you can create your own custom entity provider(s) by implementing the `EntityProvider` interface. +Instead of using the default entity providers, you can create your own custom entity provider(s) by implementing the +`EntityProvider` interface. -You can also tailor the entity providers to handle different configurations if there is a need to add specific logic for example naming strategies for your entities. +You can also tailor the entity providers to handle different configurations if there is a need to add specific logic for +example naming strategies for your entities. > ⚠️ **Note:** You use either the custom entity provider\(s\) or the default ones, not both. @@ -131,41 +139,42 @@ you can create a new module that will contain the custom entity provider registr ```typescript import { - createBackendModule, - coreServices, + createBackendModule, + coreServices, } from '@backstage/backend-plugin-api'; import { - oktaCatalogBackendEntityProviderFactoryExtensionPoint, - EntityProviderFactory, - OktaOrgEntityProvider, + oktaCatalogBackendEntityProviderFactoryExtensionPoint, + EntityProviderFactory, + OktaOrgEntityProvider, } from '@roadiehq/catalog-backend-module-okta/new-backend'; -import { Config } from '@backstage/config'; +import {Config} from '@backstage/config'; export const oktaOrgEntityProviderModule = createBackendModule({ - pluginId: 'catalog', - moduleId: 'default-okta-org-entity-provider', - register(env) { - env.registerInit({ - deps: { - provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, - logger: coreServices.logger, - }, - async init({ provider, logger }) { - const factory: EntityProviderFactory = (oktaConfig: Config) => - OktaOrgEntityProvider.fromConfig(oktaConfig, { - logger: logger, - userNamingStrategy: 'strip-domain-email', - groupNamingStrategy: 'kebab-case-name', - }); - - provider.setEntityProviderFactory(factory); - }, - }); - }, + pluginId: 'catalog', + moduleId: 'default-okta-org-entity-provider', + register(env) { + env.registerInit({ + deps: { + provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, + logger: coreServices.logger, + }, + async init({provider, logger}) { + const factory: EntityProviderFactory = (oktaConfig: Config) => + OktaOrgEntityProvider.fromConfig(oktaConfig, { + logger: logger, + userNamingStrategy: 'strip-domain-email', + groupNamingStrategy: 'kebab-case-name', + }); + + provider.setEntityProviderFactory(factory); + }, + }); + }, }); ``` -This is your custom entity provider module. You can now add it to the backend in the `packages/backend/src/index.ts` file: +This is your custom entity provider module. You can now add it to the backend in the `packages/backend/src/index.ts` +file: ```typescript // We need to comment or remove the default entity provider, since now we have a custom one. @@ -173,7 +182,8 @@ This is your custom entity provider module. You can now add it to the backend in backend.add(oktaOrgEntityProviderModule); ``` -You can configure the provider with different naming strategies. The configured strategy will be used to generate the discovered entity's `metadata.name` field. The currently supported strategies are the following: +You can configure the provider with different naming strategies. The configured strategy will be used to generate the +discovered entity's `metadata.name` field. The currently supported strategies are the following: #### User naming strategies @@ -185,20 +195,22 @@ You may also choose to implement a custom naming strategy by providing a functio ```typescript jsx export const customUserNamingStrategy: UserNamingStrategy = user => - user.profile.customField; + user.profile.customField; ``` #### Group naming strategies - id (default) | Group entities will be named by the group id. - kebab-case-name | Group entities will be named by their group profile name converted to kebab case. -- profile-name | Group entities will be named exactly as their group profile name. ⚠ The Okta field supports characters not supported as [entity names in backstage](https://backstage.io/docs/features/software-catalog/descriptor-format#name-required). ⚠ +- profile-name | Group entities will be named exactly as their group profile name. ⚠ The Okta field supports characters + not supported + as [entity names in backstage](https://backstage.io/docs/features/software-catalog/descriptor-format#name-required). ⚠ You may also choose to implement a custom naming strategy by providing a function. ```typescript jsx export const customGroupNamingStrategy: GroupNamingStrategy = group => - group.profile.customField; + group.profile.customField; ``` #### Hierarchy config @@ -207,63 +219,64 @@ You can optionally provide the ability to create a hierarchy of groups by provid ```typescript const factory: EntityProviderFactory = (oktaConfig: Config) => - OktaOrgEntityProvider.fromConfig(oktaConfig, { - logger: logger, - userNamingStrategy: 'strip-domain-email', - groupNamingStrategy: 'kebab-case-name', - hierarchyConfig: { - key: 'profile.orgId', - parentKey: 'profile.parentOrgId', - }, - }); + OktaOrgEntityProvider.fromConfig(oktaConfig, { + logger: logger, + userNamingStrategy: 'strip-domain-email', + groupNamingStrategy: 'kebab-case-name', + hierarchyConfig: { + key: 'profile.orgId', + parentKey: 'profile.parentOrgId', + }, + }); ``` #### Custom Transformers The module supports also custom transformers that can be configured as part of the customized registration. -In case you want to customize the emitted entities, the provider allows to pass custom transformers for users and groups by providing `userTransformer` and `groupTransformer`. +In case you want to customize the emitted entities, the provider allows to pass custom transformers for users and groups +by providing `userTransformer` and `groupTransformer`. 1. Create a transformer: ```typescript -import { GroupNamingStrategy } from '@roadiehq/catalog-backend-module-okta'; -import { GroupEntity } from '@backstage/catalog-model'; -import { Group } from '@okta/okta-sdk-nodejs'; +import {GroupNamingStrategy} from '@roadiehq/catalog-backend-module-okta'; +import {GroupEntity} from '@backstage/catalog-model'; +import {Group} from '@okta/okta-sdk-nodejs'; function myGroupTransformer( - group: Group, - namingStrategy: GroupNamingStrategy, - parentGroup: Group | undefined, - options: { - annotations: Record; - members: string[]; - }, -): GroupEntity { - // Enrich it with your logic - const groupEntity: GroupEntity = { - kind: 'Group', - apiVersion: 'backstage.io/v1alpha1', - metadata: { - annotations: { - ...options.annotations, - }, - name: namingStrategy(group), - title: group.profile.name, - title: group.profile.description || group.profile.name, - description: group.profile.description || '', + group: Group, + namingStrategy: GroupNamingStrategy, + parentGroup: Group | undefined, + options: { + annotations: Record; + members: string[]; }, - spec: { - members: options.members, - type: 'group', - children: [], - }, - }; - - if (parentGroup) { - groupEntity.spec.parent = namingStrategy(parentGroup); - } - return groupEntity; +): GroupEntity { + // Enrich it with your logic + const groupEntity: GroupEntity = { + kind: 'Group', + apiVersion: 'backstage.io/v1alpha1', + metadata: { + annotations: { + ...options.annotations, + }, + name: namingStrategy(group), + title: group.profile.name, + title: group.profile.description || group.profile.name, + description: group.profile.description || '', + }, + spec: { + members: options.members, + type: 'group', + children: [], + }, + }; + + if (parentGroup) { + groupEntity.spec.parent = namingStrategy(parentGroup); + } + return groupEntity; } ``` @@ -271,12 +284,12 @@ function myGroupTransformer( ```typescript const factory: EntityProviderFactory = (oktaConfig: Config) => - OktaOrgEntityProvider.fromConfig(oktaConfig, { - logger: logger, - userNamingStrategy: 'strip-domain-email', - groupNamingStrategy: 'kebab-case-name', - groupTransformer: myGroupTransformer, - }); + OktaOrgEntityProvider.fromConfig(oktaConfig, { + logger: logger, + userNamingStrategy: 'strip-domain-email', + groupNamingStrategy: 'kebab-case-name', + groupTransformer: myGroupTransformer, + }); ``` #### Legacy backend @@ -286,30 +299,30 @@ const factory: EntityProviderFactory = (oktaConfig: Config) => Expand for example legacy configuration ```typescript -import { OktaOrgEntityProvider } from '@roadiehq/catalog-backend-module-okta'; +import {OktaOrgEntityProvider} from '@roadiehq/catalog-backend-module-okta'; export default async function createPlugin( - env: PluginEnvironment, + env: PluginEnvironment, ): Promise { - const builder = await CatalogBuilder.create(env); + const builder = await CatalogBuilder.create(env); - const orgProvider = OktaOrgEntityProvider.fromConfig(env.config, { - logger: env.logger, - userNamingStrategy: 'strip-domain-email', - groupNamingStrategy: 'kebab-case-name', - }); + const orgProvider = OktaOrgEntityProvider.fromConfig(env.config, { + logger: env.logger, + userNamingStrategy: 'strip-domain-email', + groupNamingStrategy: 'kebab-case-name', + }); - builder.addEntityProvider(orgProvider); + builder.addEntityProvider(orgProvider); - const { processingEngine, router } = await builder.build(); + const {processingEngine, router} = await builder.build(); - orgProvider.run(); + orgProvider.run(); - await processingEngine.start(); + await processingEngine.start(); - // ...snip... + // ...snip... - return router; + return router; } ``` @@ -321,25 +334,25 @@ You can construct your own configuration of OktaUserEntityProvider factory and r ```typescript export const oktaUserEntityProviderModule = createBackendModule({ - pluginId: 'catalog', - moduleId: 'default-okta-user-entity-provider', - register(env) { - env.registerInit({ - deps: { - provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, - logger: coreServices.logger, - }, - async init({ provider, logger }) { - const factory: EntityProviderFactory = (oktaConfig: Config) => - OktaUserEntityProvider.fromConfig(oktaConfig, { - logger: logger, - namingStrategy: 'strip-domain-email', - }); - - provider.setEntityProviderFactory(factory); - }, - }); - }, + pluginId: 'catalog', + moduleId: 'default-okta-user-entity-provider', + register(env) { + env.registerInit({ + deps: { + provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, + logger: coreServices.logger, + }, + async init({provider, logger}) { + const factory: EntityProviderFactory = (oktaConfig: Config) => + OktaUserEntityProvider.fromConfig(oktaConfig, { + logger: logger, + namingStrategy: 'strip-domain-email', + }); + + provider.setEntityProviderFactory(factory); + }, + }); + }, }); // ...snip... @@ -347,7 +360,8 @@ export const oktaUserEntityProviderModule = createBackendModule({ backend.add(oktaUserEntityProviderModule); ``` -You can configure the provider with different naming strategies. The configured strategy will be used to generate the discovered entity's `metadata.name` field. The currently supported strategies are the following: +You can configure the provider with different naming strategies. The configured strategy will be used to generate the +discovered entity's `metadata.name` field. The currently supported strategies are the following: - id (default) | User entities will be named by the user id. - kebab-case-email | User entities will be named by their profile email converted to kebab case. @@ -357,40 +371,41 @@ You may also choose to implement a custom naming strategy by providing a functio ```typescript jsx export const customUserNamingStrategy: UserNamingStrategy = user => - user.profile.customField; + user.profile.customField; ``` -In case you want to customize the emitted entities, the provider allows to pass custom transformer by providing `userTransformer`. +In case you want to customize the emitted entities, the provider allows to pass custom transformer by providing +`userTransformer`. 1. Create a transformer: ```typescript -import { UserEntity } from '@backstage/catalog-model'; -import { User } from '@okta/okta-sdk-nodejs'; -import { UserNamingStrategy } from '@roadiehq/catalog-backend-module-okta'; +import {UserEntity} from '@backstage/catalog-model'; +import {User} from '@okta/okta-sdk-nodejs'; +import {UserNamingStrategy} from '@roadiehq/catalog-backend-module-okta'; function myUserTransformer( - user: User, - namingStrategy: UserNamingStrategy, - options: { annotations: Record }, + user: User, + namingStrategy: UserNamingStrategy, + options: { annotations: Record }, ): UserEntity { - // Enrich it with your logic - return { - kind: 'User', - apiVersion: 'backstage.io/v1alpha1', - metadata: { - annotations: { ...options.annotations }, - name: namingStrategy(user), - title: user.profile.email, - }, - spec: { - profile: { - displayName: user.profile.displayName, - email: user.profile.email, - }, - memberOf: [], - }, - }; + // Enrich it with your logic + return { + kind: 'User', + apiVersion: 'backstage.io/v1alpha1', + metadata: { + annotations: {...options.annotations}, + name: namingStrategy(user), + title: user.profile.email, + }, + spec: { + profile: { + displayName: user.profile.displayName, + email: user.profile.email, + }, + memberOf: [], + }, + }; } ``` @@ -413,30 +428,31 @@ You can manually construct your own configuration of OktaGroupEntityProvider fac ```typescript export const oktaGroupEntityProviderModule = createBackendModule({ - pluginId: 'catalog', - moduleId: 'default-okta-group-entity-provider', - register(env) { - env.registerInit({ - deps: { - provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, - logger: coreServices.logger, - }, - async init({ provider, logger }) { - const factory: EntityProviderFactory = (oktaConfig: Config) => - OktaGroupEntityProvider.fromConfig(oktaConfig, { - logger: logger, - userNamingStrategy: 'strip-domain-email', - namingStrategy: 'kebab-case-name', - }); - - provider.setEntityProviderFactory(factory); - }, - }); - }, + pluginId: 'catalog', + moduleId: 'default-okta-group-entity-provider', + register(env) { + env.registerInit({ + deps: { + provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, + logger: coreServices.logger, + }, + async init({provider, logger}) { + const factory: EntityProviderFactory = (oktaConfig: Config) => + OktaGroupEntityProvider.fromConfig(oktaConfig, { + logger: logger, + userNamingStrategy: 'strip-domain-email', + namingStrategy: 'kebab-case-name', + }); + + provider.setEntityProviderFactory(factory); + }, + }); + }, }); ``` -You can configure the provider with different naming strategies. The configured strategy will be used to generate the discovered entities `metadata.name` field. The currently supported strategies are the following: +You can configure the provider with different naming strategies. The configured strategy will be used to generate the +discovered entities `metadata.name` field. The currently supported strategies are the following: User naming strategies: @@ -448,68 +464,72 @@ You may also choose to implement a custom naming strategy by providing a functio ```typescript jsx export const customUserNamingStrategy: UserNamingStrategy = user => - user.profile.customField; + user.profile.customField; ``` Group naming strategies: - id (default) | Group entities will be named by the group id. - kebab-case-name | Group entities will be named by their group profile name converted to kebab case. -- profile-name | Group entities will be named exactly as their group profile name. ⚠ The Okta field supports characters not supported as [entity names in backstage](https://backstage.io/docs/features/software-catalog/descriptor-format#name-required). ⚠ +- profile-name | Group entities will be named exactly as their group profile name. ⚠ The Okta field supports characters + not supported + as [entity names in backstage](https://backstage.io/docs/features/software-catalog/descriptor-format#name-required). ⚠ You may also choose to implement a custom naming strategy by providing a function. ```typescript jsx export const customGroupNamingStrategy: GroupNamingStrategy = group => - group.profile.customField; + group.profile.customField; ``` Make sure you use the OktaUserEntityProvider's naming strategy for the OktaGroupEntityProvider's user naming strategy. -You can optionally provide the ability to create a hierarchy of groups by providing the `hierarchyConfig`. See example of OrgEntityProvider above for usage instructions. +You can optionally provide the ability to create a hierarchy of groups by providing the `hierarchyConfig`. See example +of OrgEntityProvider above for usage instructions. -In case you want to customize the emitted entities, the provider allows to pass custom transformer by providing `groupTransformer`. +In case you want to customize the emitted entities, the provider allows to pass custom transformer by providing +`groupTransformer`. 1. Create a transformer: ```typescript -import { GroupNamingStrategy } from '@roadiehq/catalog-backend-module-okta'; -import { GroupEntity } from '@backstage/catalog-model'; -import { Group } from '@okta/okta-sdk-nodejs'; +import {GroupNamingStrategy} from '@roadiehq/catalog-backend-module-okta'; +import {GroupEntity} from '@backstage/catalog-model'; +import {Group} from '@okta/okta-sdk-nodejs'; function myGroupTransformer( - group: Group, - namingStrategy: GroupNamingStrategy, - parentGroup: Group | undefined, - options: { - annotations: Record; - members: string[]; - }, -): GroupEntity { - // Enrich it with your logic - const groupEntity: GroupEntity = { - kind: 'Group', - apiVersion: 'backstage.io/v1alpha1', - metadata: { - annotations: { - ...options.annotations, - }, - name: namingStrategy(group), - title: group.profile.name, - title: group.profile.description || group.profile.name, - description: group.profile.description || '', + group: Group, + namingStrategy: GroupNamingStrategy, + parentGroup: Group | undefined, + options: { + annotations: Record; + members: string[]; }, - spec: { - members: options.members, - type: 'group', - children: [], - }, - }; - - if (parentGroup) { - groupEntity.spec.parent = namingStrategy(parentGroup); - } - return groupEntity; +): GroupEntity { + // Enrich it with your logic + const groupEntity: GroupEntity = { + kind: 'Group', + apiVersion: 'backstage.io/v1alpha1', + metadata: { + annotations: { + ...options.annotations, + }, + name: namingStrategy(group), + title: group.profile.name, + title: group.profile.description || group.profile.name, + description: group.profile.description || '', + }, + spec: { + members: options.members, + type: 'group', + children: [], + }, + }; + + if (parentGroup) { + groupEntity.spec.parent = namingStrategy(parentGroup); + } + return groupEntity; } ``` @@ -517,30 +537,31 @@ function myGroupTransformer( ```typescript export const oktaGroupEntityProviderModule = createBackendModule({ - pluginId: 'catalog', - moduleId: 'default-okta-group-entity-provider', - register(env) { - env.registerInit({ - deps: { - provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, - logger: coreServices.logger, - }, - async init({ provider, logger }) { - const factory: EntityProviderFactory = (oktaConfig: Config) => - OktaGroupEntityProvider.fromConfig(oktaConfig, { - logger: logger, - userNamingStrategy: 'strip-domain-email', - namingStrategy: 'kebab-case-name', - groupTransformer: myGroupTransformer, - }); - - provider.setEntityProviderFactory(factory); - }, - }); - }, + pluginId: 'catalog', + moduleId: 'default-okta-group-entity-provider', + register(env) { + env.registerInit({ + deps: { + provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, + logger: coreServices.logger, + }, + async init({provider, logger}) { + const factory: EntityProviderFactory = (oktaConfig: Config) => + OktaGroupEntityProvider.fromConfig(oktaConfig, { + logger: logger, + userNamingStrategy: 'strip-domain-email', + namingStrategy: 'kebab-case-name', + groupTransformer: myGroupTransformer, + }); + + provider.setEntityProviderFactory(factory); + }, + }); + }, }); ``` --- -Roadie gives you a hassle-free, fully customisable SaaS Backstage. Find out more here: [https://roadie.io](https://roadie.io). +Roadie gives you a hassle-free, fully customisable SaaS Backstage. Find out more +here: [https://roadie.io](https://roadie.io). From 7e12a53797b9ff1bb1068d2c2eef2de7295b187f Mon Sep 17 00:00:00 2001 From: Jussi Hallila Date: Thu, 24 Oct 2024 16:12:53 +0200 Subject: [PATCH 4/4] Run prettier. --- .../catalog-backend-module-okta/README.md | 428 +++++++++--------- 1 file changed, 214 insertions(+), 214 deletions(-) diff --git a/plugins/backend/catalog-backend-module-okta/README.md b/plugins/backend/catalog-backend-module-okta/README.md index 2c1262702..d861f32c4 100644 --- a/plugins/backend/catalog-backend-module-okta/README.md +++ b/plugins/backend/catalog-backend-module-okta/README.md @@ -89,7 +89,7 @@ First, add the required okta-entity-provider dependency to your backend in the ` ```typescript backend.add( - import('@roadiehq/catalog-backend-module-okta/okta-entity-provider'), + import('@roadiehq/catalog-backend-module-okta/okta-entity-provider'), ); ``` @@ -106,10 +106,10 @@ To integrate these into your application, add them after the okta-entity-provide ```typescript backend.add( - import('@roadiehq/catalog-backend-module-okta/okta-entity-provider'), // The required entity provider + import('@roadiehq/catalog-backend-module-okta/okta-entity-provider'), // The required entity provider ); backend.add( - import('@roadiehq/catalog-backend-module-okta/org-provider-factory'), // Optional - Load both users and groups + import('@roadiehq/catalog-backend-module-okta/org-provider-factory'), // Optional - Load both users and groups ); ``` @@ -139,37 +139,37 @@ you can create a new module that will contain the custom entity provider registr ```typescript import { - createBackendModule, - coreServices, + createBackendModule, + coreServices, } from '@backstage/backend-plugin-api'; import { - oktaCatalogBackendEntityProviderFactoryExtensionPoint, - EntityProviderFactory, - OktaOrgEntityProvider, + oktaCatalogBackendEntityProviderFactoryExtensionPoint, + EntityProviderFactory, + OktaOrgEntityProvider, } from '@roadiehq/catalog-backend-module-okta/new-backend'; -import {Config} from '@backstage/config'; +import { Config } from '@backstage/config'; export const oktaOrgEntityProviderModule = createBackendModule({ - pluginId: 'catalog', - moduleId: 'default-okta-org-entity-provider', - register(env) { - env.registerInit({ - deps: { - provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, - logger: coreServices.logger, - }, - async init({provider, logger}) { - const factory: EntityProviderFactory = (oktaConfig: Config) => - OktaOrgEntityProvider.fromConfig(oktaConfig, { - logger: logger, - userNamingStrategy: 'strip-domain-email', - groupNamingStrategy: 'kebab-case-name', - }); - - provider.setEntityProviderFactory(factory); - }, - }); - }, + pluginId: 'catalog', + moduleId: 'default-okta-org-entity-provider', + register(env) { + env.registerInit({ + deps: { + provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, + logger: coreServices.logger, + }, + async init({ provider, logger }) { + const factory: EntityProviderFactory = (oktaConfig: Config) => + OktaOrgEntityProvider.fromConfig(oktaConfig, { + logger: logger, + userNamingStrategy: 'strip-domain-email', + groupNamingStrategy: 'kebab-case-name', + }); + + provider.setEntityProviderFactory(factory); + }, + }); + }, }); ``` @@ -195,7 +195,7 @@ You may also choose to implement a custom naming strategy by providing a functio ```typescript jsx export const customUserNamingStrategy: UserNamingStrategy = user => - user.profile.customField; + user.profile.customField; ``` #### Group naming strategies @@ -210,7 +210,7 @@ You may also choose to implement a custom naming strategy by providing a functio ```typescript jsx export const customGroupNamingStrategy: GroupNamingStrategy = group => - group.profile.customField; + group.profile.customField; ``` #### Hierarchy config @@ -219,15 +219,15 @@ You can optionally provide the ability to create a hierarchy of groups by provid ```typescript const factory: EntityProviderFactory = (oktaConfig: Config) => - OktaOrgEntityProvider.fromConfig(oktaConfig, { - logger: logger, - userNamingStrategy: 'strip-domain-email', - groupNamingStrategy: 'kebab-case-name', - hierarchyConfig: { - key: 'profile.orgId', - parentKey: 'profile.parentOrgId', - }, - }); + OktaOrgEntityProvider.fromConfig(oktaConfig, { + logger: logger, + userNamingStrategy: 'strip-domain-email', + groupNamingStrategy: 'kebab-case-name', + hierarchyConfig: { + key: 'profile.orgId', + parentKey: 'profile.parentOrgId', + }, + }); ``` #### Custom Transformers @@ -240,43 +240,43 @@ by providing `userTransformer` and `groupTransformer`. 1. Create a transformer: ```typescript -import {GroupNamingStrategy} from '@roadiehq/catalog-backend-module-okta'; -import {GroupEntity} from '@backstage/catalog-model'; -import {Group} from '@okta/okta-sdk-nodejs'; +import { GroupNamingStrategy } from '@roadiehq/catalog-backend-module-okta'; +import { GroupEntity } from '@backstage/catalog-model'; +import { Group } from '@okta/okta-sdk-nodejs'; function myGroupTransformer( - group: Group, - namingStrategy: GroupNamingStrategy, - parentGroup: Group | undefined, - options: { - annotations: Record; - members: string[]; - }, + group: Group, + namingStrategy: GroupNamingStrategy, + parentGroup: Group | undefined, + options: { + annotations: Record; + members: string[]; + }, ): GroupEntity { - // Enrich it with your logic - const groupEntity: GroupEntity = { - kind: 'Group', - apiVersion: 'backstage.io/v1alpha1', - metadata: { - annotations: { - ...options.annotations, - }, - name: namingStrategy(group), - title: group.profile.name, - title: group.profile.description || group.profile.name, - description: group.profile.description || '', - }, - spec: { - members: options.members, - type: 'group', - children: [], - }, - }; - - if (parentGroup) { - groupEntity.spec.parent = namingStrategy(parentGroup); - } - return groupEntity; + // Enrich it with your logic + const groupEntity: GroupEntity = { + kind: 'Group', + apiVersion: 'backstage.io/v1alpha1', + metadata: { + annotations: { + ...options.annotations, + }, + name: namingStrategy(group), + title: group.profile.name, + title: group.profile.description || group.profile.name, + description: group.profile.description || '', + }, + spec: { + members: options.members, + type: 'group', + children: [], + }, + }; + + if (parentGroup) { + groupEntity.spec.parent = namingStrategy(parentGroup); + } + return groupEntity; } ``` @@ -284,12 +284,12 @@ function myGroupTransformer( ```typescript const factory: EntityProviderFactory = (oktaConfig: Config) => - OktaOrgEntityProvider.fromConfig(oktaConfig, { - logger: logger, - userNamingStrategy: 'strip-domain-email', - groupNamingStrategy: 'kebab-case-name', - groupTransformer: myGroupTransformer, - }); + OktaOrgEntityProvider.fromConfig(oktaConfig, { + logger: logger, + userNamingStrategy: 'strip-domain-email', + groupNamingStrategy: 'kebab-case-name', + groupTransformer: myGroupTransformer, + }); ``` #### Legacy backend @@ -299,30 +299,30 @@ const factory: EntityProviderFactory = (oktaConfig: Config) => Expand for example legacy configuration ```typescript -import {OktaOrgEntityProvider} from '@roadiehq/catalog-backend-module-okta'; +import { OktaOrgEntityProvider } from '@roadiehq/catalog-backend-module-okta'; export default async function createPlugin( - env: PluginEnvironment, + env: PluginEnvironment, ): Promise { - const builder = await CatalogBuilder.create(env); + const builder = await CatalogBuilder.create(env); - const orgProvider = OktaOrgEntityProvider.fromConfig(env.config, { - logger: env.logger, - userNamingStrategy: 'strip-domain-email', - groupNamingStrategy: 'kebab-case-name', - }); + const orgProvider = OktaOrgEntityProvider.fromConfig(env.config, { + logger: env.logger, + userNamingStrategy: 'strip-domain-email', + groupNamingStrategy: 'kebab-case-name', + }); - builder.addEntityProvider(orgProvider); + builder.addEntityProvider(orgProvider); - const {processingEngine, router} = await builder.build(); + const { processingEngine, router } = await builder.build(); - orgProvider.run(); + orgProvider.run(); - await processingEngine.start(); + await processingEngine.start(); - // ...snip... + // ...snip... - return router; + return router; } ``` @@ -334,25 +334,25 @@ You can construct your own configuration of OktaUserEntityProvider factory and r ```typescript export const oktaUserEntityProviderModule = createBackendModule({ - pluginId: 'catalog', - moduleId: 'default-okta-user-entity-provider', - register(env) { - env.registerInit({ - deps: { - provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, - logger: coreServices.logger, - }, - async init({provider, logger}) { - const factory: EntityProviderFactory = (oktaConfig: Config) => - OktaUserEntityProvider.fromConfig(oktaConfig, { - logger: logger, - namingStrategy: 'strip-domain-email', - }); - - provider.setEntityProviderFactory(factory); - }, - }); - }, + pluginId: 'catalog', + moduleId: 'default-okta-user-entity-provider', + register(env) { + env.registerInit({ + deps: { + provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, + logger: coreServices.logger, + }, + async init({ provider, logger }) { + const factory: EntityProviderFactory = (oktaConfig: Config) => + OktaUserEntityProvider.fromConfig(oktaConfig, { + logger: logger, + namingStrategy: 'strip-domain-email', + }); + + provider.setEntityProviderFactory(factory); + }, + }); + }, }); // ...snip... @@ -371,7 +371,7 @@ You may also choose to implement a custom naming strategy by providing a functio ```typescript jsx export const customUserNamingStrategy: UserNamingStrategy = user => - user.profile.customField; + user.profile.customField; ``` In case you want to customize the emitted entities, the provider allows to pass custom transformer by providing @@ -380,32 +380,32 @@ In case you want to customize the emitted entities, the provider allows to pass 1. Create a transformer: ```typescript -import {UserEntity} from '@backstage/catalog-model'; -import {User} from '@okta/okta-sdk-nodejs'; -import {UserNamingStrategy} from '@roadiehq/catalog-backend-module-okta'; +import { UserEntity } from '@backstage/catalog-model'; +import { User } from '@okta/okta-sdk-nodejs'; +import { UserNamingStrategy } from '@roadiehq/catalog-backend-module-okta'; function myUserTransformer( - user: User, - namingStrategy: UserNamingStrategy, - options: { annotations: Record }, + user: User, + namingStrategy: UserNamingStrategy, + options: { annotations: Record }, ): UserEntity { - // Enrich it with your logic - return { - kind: 'User', - apiVersion: 'backstage.io/v1alpha1', - metadata: { - annotations: {...options.annotations}, - name: namingStrategy(user), - title: user.profile.email, - }, - spec: { - profile: { - displayName: user.profile.displayName, - email: user.profile.email, - }, - memberOf: [], - }, - }; + // Enrich it with your logic + return { + kind: 'User', + apiVersion: 'backstage.io/v1alpha1', + metadata: { + annotations: { ...options.annotations }, + name: namingStrategy(user), + title: user.profile.email, + }, + spec: { + profile: { + displayName: user.profile.displayName, + email: user.profile.email, + }, + memberOf: [], + }, + }; } ``` @@ -428,26 +428,26 @@ You can manually construct your own configuration of OktaGroupEntityProvider fac ```typescript export const oktaGroupEntityProviderModule = createBackendModule({ - pluginId: 'catalog', - moduleId: 'default-okta-group-entity-provider', - register(env) { - env.registerInit({ - deps: { - provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, - logger: coreServices.logger, - }, - async init({provider, logger}) { - const factory: EntityProviderFactory = (oktaConfig: Config) => - OktaGroupEntityProvider.fromConfig(oktaConfig, { - logger: logger, - userNamingStrategy: 'strip-domain-email', - namingStrategy: 'kebab-case-name', - }); - - provider.setEntityProviderFactory(factory); - }, - }); - }, + pluginId: 'catalog', + moduleId: 'default-okta-group-entity-provider', + register(env) { + env.registerInit({ + deps: { + provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, + logger: coreServices.logger, + }, + async init({ provider, logger }) { + const factory: EntityProviderFactory = (oktaConfig: Config) => + OktaGroupEntityProvider.fromConfig(oktaConfig, { + logger: logger, + userNamingStrategy: 'strip-domain-email', + namingStrategy: 'kebab-case-name', + }); + + provider.setEntityProviderFactory(factory); + }, + }); + }, }); ``` @@ -464,7 +464,7 @@ You may also choose to implement a custom naming strategy by providing a functio ```typescript jsx export const customUserNamingStrategy: UserNamingStrategy = user => - user.profile.customField; + user.profile.customField; ``` Group naming strategies: @@ -479,7 +479,7 @@ You may also choose to implement a custom naming strategy by providing a functio ```typescript jsx export const customGroupNamingStrategy: GroupNamingStrategy = group => - group.profile.customField; + group.profile.customField; ``` Make sure you use the OktaUserEntityProvider's naming strategy for the OktaGroupEntityProvider's user naming strategy. @@ -493,43 +493,43 @@ In case you want to customize the emitted entities, the provider allows to pass 1. Create a transformer: ```typescript -import {GroupNamingStrategy} from '@roadiehq/catalog-backend-module-okta'; -import {GroupEntity} from '@backstage/catalog-model'; -import {Group} from '@okta/okta-sdk-nodejs'; +import { GroupNamingStrategy } from '@roadiehq/catalog-backend-module-okta'; +import { GroupEntity } from '@backstage/catalog-model'; +import { Group } from '@okta/okta-sdk-nodejs'; function myGroupTransformer( - group: Group, - namingStrategy: GroupNamingStrategy, - parentGroup: Group | undefined, - options: { - annotations: Record; - members: string[]; - }, + group: Group, + namingStrategy: GroupNamingStrategy, + parentGroup: Group | undefined, + options: { + annotations: Record; + members: string[]; + }, ): GroupEntity { - // Enrich it with your logic - const groupEntity: GroupEntity = { - kind: 'Group', - apiVersion: 'backstage.io/v1alpha1', - metadata: { - annotations: { - ...options.annotations, - }, - name: namingStrategy(group), - title: group.profile.name, - title: group.profile.description || group.profile.name, - description: group.profile.description || '', - }, - spec: { - members: options.members, - type: 'group', - children: [], - }, - }; - - if (parentGroup) { - groupEntity.spec.parent = namingStrategy(parentGroup); - } - return groupEntity; + // Enrich it with your logic + const groupEntity: GroupEntity = { + kind: 'Group', + apiVersion: 'backstage.io/v1alpha1', + metadata: { + annotations: { + ...options.annotations, + }, + name: namingStrategy(group), + title: group.profile.name, + title: group.profile.description || group.profile.name, + description: group.profile.description || '', + }, + spec: { + members: options.members, + type: 'group', + children: [], + }, + }; + + if (parentGroup) { + groupEntity.spec.parent = namingStrategy(parentGroup); + } + return groupEntity; } ``` @@ -537,27 +537,27 @@ function myGroupTransformer( ```typescript export const oktaGroupEntityProviderModule = createBackendModule({ - pluginId: 'catalog', - moduleId: 'default-okta-group-entity-provider', - register(env) { - env.registerInit({ - deps: { - provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, - logger: coreServices.logger, - }, - async init({provider, logger}) { - const factory: EntityProviderFactory = (oktaConfig: Config) => - OktaGroupEntityProvider.fromConfig(oktaConfig, { - logger: logger, - userNamingStrategy: 'strip-domain-email', - namingStrategy: 'kebab-case-name', - groupTransformer: myGroupTransformer, - }); - - provider.setEntityProviderFactory(factory); - }, - }); - }, + pluginId: 'catalog', + moduleId: 'default-okta-group-entity-provider', + register(env) { + env.registerInit({ + deps: { + provider: oktaCatalogBackendEntityProviderFactoryExtensionPoint, + logger: coreServices.logger, + }, + async init({ provider, logger }) { + const factory: EntityProviderFactory = (oktaConfig: Config) => + OktaGroupEntityProvider.fromConfig(oktaConfig, { + logger: logger, + userNamingStrategy: 'strip-domain-email', + namingStrategy: 'kebab-case-name', + groupTransformer: myGroupTransformer, + }); + + provider.setEntityProviderFactory(factory); + }, + }); + }, }); ```