diff --git a/plugins/ocm-backend/CONTRIBUTING.md b/plugins/ocm-backend/CONTRIBUTING.md index 91424e430e..61e98d6ff2 100644 --- a/plugins/ocm-backend/CONTRIBUTING.md +++ b/plugins/ocm-backend/CONTRIBUTING.md @@ -3,7 +3,9 @@ You can run a development setup using the following command: ```console -yarn start +yarn workspace @janus-idp/backstage-plugin-ocm-backend run start ``` When you run the previous command, the Kubernetes API is mocked to provide two clusters: `foo` (works as the hub) and `cluster1`. Also, an error response is mocked for non-existent clusters. + +To view the data provided by the OCM backend, navigate to `http://localhost:7007/api/ocm/status`. diff --git a/plugins/ocm-backend/dev/index.ts b/plugins/ocm-backend/dev/index.ts index 857193c3f5..08f8f2ecd8 100644 --- a/plugins/ocm-backend/dev/index.ts +++ b/plugins/ocm-backend/dev/index.ts @@ -1,17 +1,86 @@ -import { createServiceBuilder } from '@backstage/backend-common'; -import { ConfigReader } from '@backstage/config'; +import { + CacheManager, + createServiceBuilder, + DatabaseManager, + getRootLogger, + HostDiscovery, + ServerTokenManager, + UrlReaders, + useHotMemoize, +} from '@backstage/backend-common'; +import { TaskScheduler } from '@backstage/backend-tasks'; +import { Config, ConfigReader } from '@backstage/config'; +import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; +import { CatalogBuilder } from '@backstage/plugin-catalog-backend'; +import { ServerPermissionClient } from '@backstage/plugin-permission-node'; +import { Router } from 'express'; import { Logger } from 'winston'; import { Server } from 'http'; +import { ManagedClusterProvider } from '../src/'; import { createRouter, RouterOptions } from '../src/service/router'; +import { PluginEnvironment } from './types'; export interface ServerOptions { port: number; logger: Logger; } +function makeCreateEnv(config: Config) { + const root = getRootLogger(); + const reader = UrlReaders.default({ logger: root, config }); + const discovery = HostDiscovery.fromConfig(config); + const cacheManager = CacheManager.fromConfig(config); + const databaseManager = DatabaseManager.fromConfig(config, { logger: root }); + const tokenManager = ServerTokenManager.noop(); + const taskScheduler = TaskScheduler.fromConfig(config); + + const identity = DefaultIdentityClient.create({ + discovery, + }); + const permissions = ServerPermissionClient.fromConfig(config, { + discovery, + tokenManager, + }); + + root.info(`Created UrlReader ${reader}`); + + return (plugin: string): PluginEnvironment => { + const logger = root.child({ type: 'plugin', plugin }); + const database = databaseManager.forPlugin(plugin); + const cache = cacheManager.forPlugin(plugin); + const scheduler = taskScheduler.forPlugin(plugin); + return { + logger, + database, + cache, + config, + reader, + discovery, + tokenManager, + scheduler, + permissions, + identity, + }; + }; +} +const catalog = async (env: PluginEnvironment): Promise => { + const builder = await CatalogBuilder.create(env); + const ocm = ManagedClusterProvider.fromConfig(env.config, { + logger: env.logger, + schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 1 }, + timeout: { minutes: 1 }, + }), + }); + builder.addEntityProvider(ocm); + const { processingEngine, router } = await builder.build(); + await processingEngine.start(); + return router; +}; + export async function startStandaloneServer( options: ServerOptions, ): Promise { @@ -21,6 +90,13 @@ export async function startStandaloneServer( logger.info('Starting application server...'); const config = new ConfigReader({ + backend: { + baseUrl: 'http://localhost:7007', + database: { + client: 'better-sqlite3', + connection: ':memory:', + }, + }, catalog: { providers: { ocm: { @@ -33,13 +109,17 @@ export async function startStandaloneServer( }, }, }); - const routerOptions: RouterOptions = { logger, config }; + const createEnv = makeCreateEnv(config); + const catalogEnv = useHotMemoize(module, () => createEnv('catalog')); + + const ocmRouterOptions: RouterOptions = { logger, config }; const service = createServiceBuilder(module) .setPort(options.port) .enableCors({ origin: '*', }) - .addRouter('/api/ocm', await createRouter(routerOptions)); + .addRouter('/api/ocm', await createRouter(ocmRouterOptions)) + .addRouter('/catalog', await catalog(catalogEnv)); return await service.start().catch(err => { logger.error(err); diff --git a/plugins/ocm-backend/dev/types.ts b/plugins/ocm-backend/dev/types.ts new file mode 100644 index 0000000000..a2c43b45de --- /dev/null +++ b/plugins/ocm-backend/dev/types.ts @@ -0,0 +1,26 @@ +import { + PluginCacheManager, + PluginDatabaseManager, + PluginEndpointDiscovery, + TokenManager, + UrlReader, +} from '@backstage/backend-common'; +import { PluginTaskScheduler } from '@backstage/backend-tasks'; +import { Config } from '@backstage/config'; +import { IdentityApi } from '@backstage/plugin-auth-node'; +import { PermissionEvaluator } from '@backstage/plugin-permission-common'; + +import { Logger } from 'winston'; + +export type PluginEnvironment = { + logger: Logger; + database: PluginDatabaseManager; + cache: PluginCacheManager; + config: Config; + reader: UrlReader; + discovery: PluginEndpointDiscovery; + tokenManager: TokenManager; + scheduler: PluginTaskScheduler; + permissions: PermissionEvaluator; + identity: IdentityApi; +}; diff --git a/plugins/ocm-backend/package.json b/plugins/ocm-backend/package.json index 03b6bd4a76..3f7cfdb0af 100644 --- a/plugins/ocm-backend/package.json +++ b/plugins/ocm-backend/package.json @@ -41,6 +41,10 @@ }, "devDependencies": { "@backstage/cli": "0.22.9", + "@backstage/plugin-auth-node": "^0.2.16", + "@backstage/plugin-catalog-backend": "^1.11.0", + "@backstage/plugin-permission-common": "^0.7.7", + "@backstage/plugin-permission-node": "^0.7.10", "@types/express": "4.17.17", "@types/supertest": "2.0.12", "msw": "1.2.1",