Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

catalog-backend-module-okta new backend system #1310

Closed
pmaterer opened this issue Mar 28, 2024 · 2 comments
Closed

catalog-backend-module-okta new backend system #1310

pmaterer opened this issue Mar 28, 2024 · 2 comments
Labels

Comments

@pmaterer
Copy link

Expected Behavior

I'm trying to migrate to the new backend system. I'm using the catalog-backend-module-okta backend plugin.

Following the Backstage docs I'm doing something like this:

// packages/backend/src/catalogModuleOktaProvider.ts
import {
  createBackendModule,
  coreServices,
} from '@backstage/backend-plugin-api';

import { loggerToWinstonLogger } from '@backstage/backend-common';
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
import { OktaOrgEntityProvider } from '@roadiehq/catalog-backend-module-okta';

export default createBackendModule({
  pluginId: 'catalog',
  moduleId: 'okta-discovery-entity-provider',
  register(env) {
    env.registerInit({
      deps: {
        config: coreServices.rootConfig,
        catalog: catalogProcessingExtensionPoint,
        logger: coreServices.logger,
      },
      async init({ config, catalog, logger }) {
        const orgProvider = OktaOrgEntityProvider.fromConfig(config, {
            logger: loggerToWinstonLogger(logger),
            userNamingStrategy: 'strip-domain-email',
            groupNamingStrategy: 'kebab-case-name',
          });
        catalog.addEntityProvider(orgProvider);
      },
    });
  },
});

And then I start the backend:

// packages/backend/src/index.ts

import { createBackend } from '@backstage/backend-defaults';

const backend = createBackend();

...
backend.add(import('./catalogModuleOktaProvider'));
...

backend.start();

However the provider doesn't actually run.

The docs show how to setup the provider using the old backend:

const builder = await CatalogBuilder.create(env);

const orgProvider = OktaOrgEntityProvider.fromConfig(env.config, {
  logger: env.logger,
  userNamingStrategy: 'strip-domain-email',
  groupNamingStrategy: 'kebab-case-name',
});

builder.addEntityProvider(orgProvider);

const { processingEngine, router } = await builder.build();

orgProvider.run();

await processingEngine.start();

So you need to call the run() method for the provider to start, however it is not clear how to best do this in the new backend?

If I call it after adding it like this:

// packages/backend/src/catalogModuleOktaProvider.ts
...
catalog.addEntityProvider(orgProvider);
orgProvider.run();
...

I get an error:

[1] <redacted>/backstage/backstage/node_modules/@roadiehq/catalog-backend-module-okta/src/providers/OktaOrgEntityProvider.ts:131
[1]       throw new Error('Not initialized');
[1]             ^
[1] 
[1] 
[1] Error: Not initialized
[1]     at OktaOrgEntityProvider.run (<redacted>/backstage/backstage/node_modules/@roadiehq/catalog-backend-module-okta/src/providers/OktaOrgEntityProvider.ts:131:13)

From what I can tell the old backend would call the connect() function on all the entity providers when you call const { processingEngine, router } = await builder.build();.

Is there a way to add this provider using the new backend?

@pmaterer pmaterer added the kind/bug Something isn't working label Mar 28, 2024
@Xantier Xantier added update and removed kind/bug Something isn't working labels Mar 29, 2024
@punkle
Copy link
Contributor

punkle commented Apr 3, 2024

@pmaterer you will need to use the scheduler to call the run method after an initial period of time and on a regular schedule. This will ensure that the provider will run periodically.

You would probably do that like this:

export default createBackendModule({
  pluginId: 'catalog',
  moduleId: 'okta-discovery-entity-provider',
  register(env) {
    let schedule;
    env.registerExtensionPoint(scheduleExtensionPoint, {
      setSchedule(newSchedule) {
        schedule = newSchedule;
      },
    });
    env.registerInit({
      deps: {
        config: coreServices.rootConfig,
        catalog: catalogProcessingExtensionPoint,
        logger: coreServices.logger,
        scheduler: coreServices.scheduler,
      },
      async init({ config, catalog, logger }) {
        const orgProvider = OktaOrgEntityProvider.fromConfig(config, {
            logger: loggerToWinstonLogger(logger),
            userNamingStrategy: 'strip-domain-email',
            groupNamingStrategy: 'kebab-case-name',
          });
          if (schedule) {
            scheduler.scheduleTask({
              ...schedule,
              initialDelay: { minutes: 2 },
              id: 'org-entity-provider',
              fn: () => { orgProvider.run() },
            });
        }
        catalog.addEntityProvider(orgProvider);
      },
    });
  },
});

@pmaterer
Copy link
Author

pmaterer commented Apr 4, 2024

@punkle

Appreciate that! I ended up doing this:

export default createBackendModule({
  pluginId: 'catalog',
  moduleId: 'okta-discovery-entity-provider',
  register(env) {
    env.registerInit({
      deps: {
        config: coreServices.rootConfig,
        catalog: catalogProcessingExtensionPoint,
        logger: coreServices.logger,
        scheduler: coreServices.scheduler,
      },
      async init({ config, catalog, logger, scheduler }) {
        const orgProvider = OktaOrgEntityProvider.fromConfig(config, {
          logger: loggerToWinstonLogger(logger),
          userNamingStrategy: 'strip-domain-email',
          groupNamingStrategy: 'kebab-case-name',
        });
        catalog.addEntityProvider(orgProvider);
        await scheduler.scheduleTask({
          id: 'okta-org-entity-provider',
          fn: () => {
            orgProvider.run();
          },
          initialDelay: Duration.fromObject({ minutes: 2 }),
          frequency: Duration.fromObject({ minutes: 5 }),
          timeout: Duration.fromObject({ minutes: 10 })
        });
      },
    });
  },
});

And it appears to be working just fine. Thanks again!

Considering there is a PR to update all plugins/modules to the new backend system (#1304) I will close this.

@pmaterer pmaterer closed this as completed Apr 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants