@solo.io/platform-portal-backstage-plugin-backend 0.0.32 → 0.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -5
- package/dist/index.cjs.js +14 -4
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,6 +21,9 @@ yarn add --cwd ./packages/backend @solo.io/platform-portal-backstage-plugin-back
|
|
|
21
21
|
|
|
22
22
|
2. Update your backend plugin in `packages/backend/src/index.ts` with the following code. The parts that you will need to update should similar to what is described in the Backstage docs [here](https://backstage.io/docs/features/software-catalog/external-integrations/#new-backend-system). The lines to create the backend variable and start the backend should already exist, and are included here as a frame of reference.
|
|
23
23
|
|
|
24
|
+
> [!TIP]
|
|
25
|
+
> Users can also transform the Entity that is added to the catalog by defining an `entityTransformation` function, like the one that is outlined in the commented out code below.
|
|
26
|
+
|
|
24
27
|
```ts
|
|
25
28
|
// ...
|
|
26
29
|
// -> 1. Add the imports in.
|
|
@@ -28,10 +31,26 @@ import {
|
|
|
28
31
|
coreServices,
|
|
29
32
|
createBackendModule,
|
|
30
33
|
} from '@backstage/backend-plugin-api';
|
|
34
|
+
import { Entity } from '@backstage/catalog-model';
|
|
31
35
|
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
|
|
32
36
|
import { GlooPlatformPortalProvider } from '@solo.io/platform-portal-backstage-plugin-backend';
|
|
33
37
|
|
|
34
|
-
// -> 2.
|
|
38
|
+
// -> 2. Optionally define an `entityTransformation`.
|
|
39
|
+
// Entities can be transformed using this function.
|
|
40
|
+
// The entity that is returned here will be added to the catalog.
|
|
41
|
+
const entityTransformation = async (entity: Entity, api: any) => {
|
|
42
|
+
// The following commented out lines would add an "example-" prefix to your Entities.
|
|
43
|
+
// entity = {
|
|
44
|
+
// ...entity,
|
|
45
|
+
// metadata: {
|
|
46
|
+
// ...entity.metadata,
|
|
47
|
+
// title: 'example-' + (entity?.metadata?.title ?? ''),
|
|
48
|
+
// },
|
|
49
|
+
// };
|
|
50
|
+
return entity;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// -> 3. Create the provider for our plugin.
|
|
35
54
|
export const catalogGlooPlatformPortalBackendProvider = createBackendModule({
|
|
36
55
|
pluginId: 'catalog',
|
|
37
56
|
moduleId: 'gloo-platform-portal-backend-provider',
|
|
@@ -45,14 +64,19 @@ export const catalogGlooPlatformPortalBackendProvider = createBackendModule({
|
|
|
45
64
|
},
|
|
46
65
|
async init({ catalog, logger, config, scheduler }) {
|
|
47
66
|
catalog.addEntityProvider(
|
|
48
|
-
new GlooPlatformPortalProvider(
|
|
67
|
+
new GlooPlatformPortalProvider(
|
|
68
|
+
logger,
|
|
69
|
+
config,
|
|
70
|
+
scheduler,
|
|
71
|
+
entityTransformation,
|
|
72
|
+
),
|
|
49
73
|
);
|
|
50
74
|
},
|
|
51
75
|
});
|
|
52
76
|
},
|
|
53
77
|
});
|
|
54
78
|
|
|
55
|
-
// ->
|
|
79
|
+
// -> 4. Create the backend (this line should already exist).
|
|
56
80
|
const backend = createBackend();
|
|
57
81
|
|
|
58
82
|
// ...
|
|
@@ -62,10 +86,10 @@ const backend = createBackend();
|
|
|
62
86
|
// Add the @backstage/plugin-catalog-backend/alpha (this line should already exist).
|
|
63
87
|
backend.add(import('@backstage/plugin-catalog-backend/alpha'));
|
|
64
88
|
|
|
65
|
-
// ->
|
|
89
|
+
// -> 5. Add our provider to the backend.
|
|
66
90
|
backend.add(catalogGlooPlatformPortalBackendProvider);
|
|
67
91
|
|
|
68
|
-
// ->
|
|
92
|
+
// -> 6. The backend is started (this line should already exist).
|
|
69
93
|
backend.start();
|
|
70
94
|
```
|
|
71
95
|
|
package/dist/index.cjs.js
CHANGED
|
@@ -307,12 +307,13 @@ class GlooPlatformPortalProvider {
|
|
|
307
307
|
//
|
|
308
308
|
// 1. Init class
|
|
309
309
|
//
|
|
310
|
-
constructor(logger, config, scheduler) {
|
|
310
|
+
constructor(logger, config, scheduler, entityTransformation) {
|
|
311
311
|
__publicField(this, "connection");
|
|
312
312
|
__publicField(this, "logger");
|
|
313
313
|
__publicField(this, "config");
|
|
314
314
|
__publicField(this, "latestTokensResponse");
|
|
315
315
|
__publicField(this, "debugLogging", false);
|
|
316
|
+
__publicField(this, "entityTransformation");
|
|
316
317
|
// Helper classes
|
|
317
318
|
__publicField(this, "configUtil");
|
|
318
319
|
__publicField(this, "entityBuilder");
|
|
@@ -339,6 +340,7 @@ class GlooPlatformPortalProvider {
|
|
|
339
340
|
var _a;
|
|
340
341
|
this.logger = logger;
|
|
341
342
|
this.config = config;
|
|
343
|
+
this.entityTransformation = entityTransformation;
|
|
342
344
|
this.configUtil = new ConfigUtil(this.error, this.warn, this.config);
|
|
343
345
|
this.entityBuilder = new EntityBuilder();
|
|
344
346
|
this.debugLogging = !!((_a = this.config) == null ? void 0 : _a.getOptionalBoolean(
|
|
@@ -357,7 +359,7 @@ class GlooPlatformPortalProvider {
|
|
|
357
359
|
return this._apisEndpoint;
|
|
358
360
|
}
|
|
359
361
|
get gmg_apisEndpoint() {
|
|
360
|
-
return this.portalServerUrl + "/apis
|
|
362
|
+
return this.portalServerUrl + "/apis";
|
|
361
363
|
}
|
|
362
364
|
get gg_apisEndpoint() {
|
|
363
365
|
return this.portalServerUrl + "/api-products";
|
|
@@ -541,10 +543,12 @@ class GlooPlatformPortalProvider {
|
|
|
541
543
|
const api = processedAPIs[i];
|
|
542
544
|
if ("id" in api) {
|
|
543
545
|
this.updatePortalServerType("gloo-gateway");
|
|
544
|
-
|
|
546
|
+
let entity = await this.getGlooGatewayApiEntity(api);
|
|
547
|
+
entities.push(await this.applyEntityTransformation(entity, api));
|
|
545
548
|
} else if ("apiProductId" in api) {
|
|
546
549
|
this.updatePortalServerType("gloo-mesh-gateway");
|
|
547
|
-
|
|
550
|
+
let entity = await this.getGlooMeshGatewayApiEntity(api);
|
|
551
|
+
entities.push(await this.applyEntityTransformation(entity, api));
|
|
548
552
|
}
|
|
549
553
|
}
|
|
550
554
|
if (this.debugLogging) {
|
|
@@ -718,6 +722,12 @@ class GlooPlatformPortalProvider {
|
|
|
718
722
|
}
|
|
719
723
|
return processedAPIs;
|
|
720
724
|
}
|
|
725
|
+
async applyEntityTransformation(entity, api) {
|
|
726
|
+
if (!!this.entityTransformation) {
|
|
727
|
+
return await this.entityTransformation(entity, api);
|
|
728
|
+
}
|
|
729
|
+
return entity;
|
|
730
|
+
}
|
|
721
731
|
}
|
|
722
732
|
|
|
723
733
|
exports.GlooPlatformPortalProvider = GlooPlatformPortalProvider;
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../src/provider/ConfigUtil.ts","../src/provider/utility.ts","../src/provider/EntityBuilder.ts","../src/provider/GlooPlatformPortalProvider.ts"],"sourcesContent":["import { Config } from '@backstage/config';\n\ntype logFn = (s: string) => any;\n\nexport class ConfigUtil {\n logErr: logFn;\n logWarning: logFn;\n config: Config;\n\n constructor(logErr: logFn, logWarning: logFn, config: Config) {\n this.logErr = logErr;\n this.logWarning = logWarning;\n this.config = config;\n }\n\n getPortalServerUrl() {\n if (!this.config) {\n this.logErr('No backstage config found when getting portal server url.');\n return '';\n }\n let value = this.config.getOptionalString(\n 'glooPlatformPortal.backend.portalServerUrl',\n );\n // Remove trailing slash if supplied.\n if (!!value && value.at(-1) === '/')\n value = value.substring(0, value.length - 1);\n return value ?? 'http://localhost:31080/v1';\n }\n\n getClientSecret() {\n if (!this.config) {\n this.logErr('No backstage config found when getting client secret.');\n return '';\n }\n const value = this.config.getOptionalString(\n 'glooPlatformPortal.backend.clientSecret',\n );\n if (!value) {\n this.logWarning(\n 'No glooPlatformPortal.backend.clientSecret found in app-config.local.yaml',\n );\n }\n return value ?? '';\n }\n\n getClientId() {\n if (!this.config) {\n this.logErr('No backstage config found when getting client id.');\n return '';\n }\n const value = this.config.getOptionalString(\n 'glooPlatformPortal.backend.clientId',\n );\n if (!value) {\n this.logWarning(\n 'No glooPlatformPortal.backend.clientId found in app-config.local.yaml',\n );\n }\n return value ?? '';\n }\n\n getTokenEndpoint() {\n if (!this.config) {\n this.logErr('No backstage config found when getting token endpoint.');\n return '';\n }\n const value = this.config.getOptionalString(\n 'glooPlatformPortal.backend.tokenEndpoint',\n );\n if (!value) {\n this.logWarning(\n 'No glooPlatformPortal.backend.tokenEndpoint found in app-config.local.yaml',\n );\n }\n return value ?? '';\n }\n}\n","import fetch from 'node-fetch';\nimport { AccessTokensResponse } from './api-types';\n\nexport function parseJwt(token: string) {\n const base64Url = token.split('.')[1];\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');\n const jsonPayload = decodeURIComponent(\n atob(base64)\n .split('')\n .map(c => `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`)\n .join(''),\n );\n return JSON.parse(jsonPayload);\n}\n\nexport function objectToUrlFormEncodedPayload(\n requestJSON: Record<string, string>,\n) {\n const formBodyPieces = [] as string[];\n for (const property in requestJSON) {\n if (!requestJSON.hasOwnProperty(property)) continue;\n const encodedKey = encodeURIComponent(property);\n const encodedValue = encodeURIComponent(\n requestJSON[property as keyof typeof requestJSON],\n );\n formBodyPieces.push(`${encodedKey}=${encodedValue}`);\n }\n const formBodyString = formBodyPieces.join('&');\n return formBodyString;\n}\n\nexport async function doAccessTokenRequest(\n grantType: 'refresh_token' | 'client_credentials',\n tokenEndpoint: string,\n clientId: string,\n clientSecret: string,\n refreshToken?: string,\n) {\n const formData = {} as Record<string, string>;\n //\n // Build the request payload for a new oauth access token.\n //\n formData.grant_type = grantType;\n formData.client_id = clientId;\n formData.client_secret = clientSecret;\n if (grantType === 'refresh_token') {\n if (!refreshToken) {\n return undefined;\n }\n formData.refresh_token = refreshToken;\n }\n //\n // Make the request\n //\n const rawRes = await fetch(tokenEndpoint, {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',\n },\n method: 'POST',\n body: objectToUrlFormEncodedPayload(formData),\n });\n let resJSON: any;\n try {\n resJSON = await rawRes.json();\n } catch {\n throw new Error('Error parsing oauth response.');\n }\n if (!!resJSON.error_description) {\n throw new Error(resJSON.error_description);\n }\n if (!!resJSON.error) {\n throw new Error(resJSON.error);\n }\n //\n // Check for the access token in the response.\n //\n if (!resJSON.access_token) {\n throw new Error(\n \"No 'access_token' property was found in the oauth response body.\",\n );\n }\n return resJSON as AccessTokensResponse;\n}\n\n//\n// From: https://backstage.io/docs/features/software-catalog/descriptor-format\n//\nconst sanitizeRegex = {\n // Each tag must be sequences of [a-z0-9:+#] separated by -, at most 63 characters in total\n tag: /[a-z]|[0-9]|\\:|\\+|\\#|\\-/,\n // Strings of length at least 1, and at most 63\n // Must consist of sequences of [a-z0-9A-Z] possibly separated by one of [-_.].\n name: /[a-z]|[0-9]|[A-Z]|\\-|\\_|\\./,\n // Namespaces must be sequences of [a-zA-Z0-9], possibly separated by -, at most 63 characters in total.\n namespace: /[a-z]|[0-9]|[A-Z]|\\-/,\n};\n\n/**\n * Sanitizes a string before adding it to a backstage entity.\n */\nexport const sanitizeStringForEntity = (\n propertyType: keyof typeof sanitizeRegex,\n propertyValue: string,\n) => {\n return propertyValue\n .split('')\n .map(ch => (!sanitizeRegex[propertyType].test(ch) ? '-' : ch))\n .reduce(\n (prev, cur) =>\n // Don't go over 63 characters.\n prev.length >= 62\n ? prev\n : // Don't repeat \"-\"\n prev.at(-1) === '-' && cur === '-'\n ? prev\n : prev + cur,\n '',\n );\n};\n","import { Entity, EntityMeta } from '@backstage/catalog-model';\nimport { EntityProviderMutation } from '@backstage/plugin-catalog-node';\nimport { APISchema } from './api-types';\nimport { sanitizeStringForEntity } from './utility';\n\nexport class EntityBuilder {\n // Backstage catalog metadata.\n private bsGroupName = 'solo-io-service-accounts';\n private bsServiceAccountName = 'gloo-platform-portal-service-account';\n private bsSystemName = 'gloo-platform-portal-apis';\n\n private apisEndpoint = '';\n private portalServerUrl = '';\n\n onApisEndpointChange = (apisEndpoint: string) =>\n (this.apisEndpoint = apisEndpoint);\n onPortalServerUrlChange = (portalServerUrl: string) =>\n (this.portalServerUrl = portalServerUrl);\n\n /**\n * A helper function to return a Backstage catalog entity for an API.\n */\n buildApiVersionEntity(\n apiId: string,\n apiVersion: string | undefined,\n apiDescription: string,\n schema: APISchema | string | undefined,\n ): Entity {\n const newEntity: Entity = {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'API',\n metadata: {\n tags: [\n 'gloo-platform',\n ...(!!apiVersion\n ? ['api-version-' + sanitizeStringForEntity('tag', apiVersion)]\n : []),\n ],\n name: sanitizeStringForEntity('name', apiId),\n title: apiId,\n description: apiDescription,\n annotations: {\n 'backstage.io/managed-by-location': `url:${this.apisEndpoint}`,\n 'backstage.io/managed-by-origin-location': `url:${this.apisEndpoint}`,\n },\n } as EntityMeta,\n spec: {\n type: 'openapi',\n lifecycle: 'production',\n system: this.bsSystemName,\n owner: `user:${this.bsServiceAccountName}`,\n definition: JSON.stringify(schema),\n },\n };\n return newEntity;\n }\n\n /**\n * A helper function to return a Backstage catalog EntityProviderMutation object for the GlooPlatformPortalProvider plugin.\n * The returned object includes entities that will be added to the catalog.\n */\n buildEntityProviderMutation(entities: Entity[]) {\n const locationKey = `gloo-platform-portal-provider`;\n const mutationObj: EntityProviderMutation = {\n type: 'full',\n entities: [\n {\n locationKey,\n entity: {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'Group',\n metadata: {\n name: this.bsGroupName,\n annotations: {\n 'backstage.io/managed-by-location': `url:${this.portalServerUrl}`,\n 'backstage.io/managed-by-origin-location': `url:${this.portalServerUrl}`,\n },\n },\n spec: {\n type: 'service-account-group',\n children: [],\n members: [this.bsServiceAccountName],\n },\n },\n },\n {\n locationKey,\n entity: {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'User',\n metadata: {\n name: this.bsServiceAccountName,\n annotations: {\n 'backstage.io/managed-by-location': `url:${this.portalServerUrl}`,\n 'backstage.io/managed-by-origin-location': `url:${this.portalServerUrl}`,\n },\n },\n spec: {\n displayName: 'Solo.io Service Account',\n email: '',\n picture: '',\n memberOf: [this.bsGroupName],\n },\n },\n },\n // {\n // locationKey,\n // entity: {\n // apiVersion: 'backstage.io/v1alpha1',\n // kind: 'Domain',\n // metadata: {\n // tags: ['gloo-platform'],\n // name: 'api-product',\n // description: 'Gloo Platform Portal ApiProduct resources.',\n // annotations: {\n // 'backstage.io/managed-by-location': 'url:' + this.apisEndpoint,\n // 'backstage.io/managed-by-origin-location':\n // 'url:' + this.apisEndpoint,\n // },\n // } as EntityMeta,\n // spec: {\n // owner: 'user:' + bsServiceAccountName,\n // },\n // },\n // },\n {\n locationKey,\n entity: {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'System',\n metadata: {\n tags: ['gloo-platform'],\n name: this.bsSystemName,\n title: 'Gloo Platform Portal APIs',\n annotations: {\n 'backstage.io/managed-by-location': `url:${this.portalServerUrl}`,\n 'backstage.io/managed-by-origin-location': `url:${this.portalServerUrl}`,\n },\n } as EntityMeta,\n spec: {\n owner: `user:${this.bsServiceAccountName}`,\n // domain: 'api-product',\n },\n },\n },\n ...entities.map(entity => ({ locationKey, entity })),\n ],\n };\n return mutationObj;\n }\n}\n","import { LoggerService, SchedulerService } from '@backstage/backend-plugin-api';\nimport { Entity } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport {\n EntityProvider,\n EntityProviderConnection,\n} from '@backstage/plugin-catalog-node';\nimport fetch from 'node-fetch';\nimport { ConfigUtil } from './ConfigUtil';\nimport { EntityBuilder } from './EntityBuilder';\nimport {\n API,\n APIProduct,\n APISchema,\n AccessTokensResponse,\n ApiProductSummary,\n ApiVersion,\n ApiVersionExtended,\n} from './api-types';\nimport { doAccessTokenRequest, parseJwt } from './utility';\n\ntype PortalServerType = 'gloo-mesh-gateway' | 'gloo-gateway' | 'unknown';\n\ntype ApisEndpointResponseType =\n | API[]\n | APIProduct[]\n | ApiProductSummary[]\n | null;\n\n/**\n * Provides API entities from the Gloo Platform Portal REST server.\n */\nexport class GlooPlatformPortalProvider implements EntityProvider {\n private connection?: EntityProviderConnection;\n private logger: LoggerService;\n private config: Config;\n private latestTokensResponse?: AccessTokensResponse;\n private debugLogging = false;\n\n // Helper classes\n private configUtil: ConfigUtil;\n private entityBuilder: EntityBuilder;\n\n /**\n * Defaults to 'unknown'.\n * This is updated to 'gloo-gateway' or 'gloo-mesh-gateway' depending on the api response.\n */\n private _portalServerType: PortalServerType = 'unknown';\n private get portalServerType() {\n return this._portalServerType;\n }\n private _portalServerUrl = '';\n private get portalServerUrl() {\n return this._portalServerUrl;\n }\n private _apisEndpoint = '';\n private get apisEndpoint() {\n return this._apisEndpoint;\n }\n private get gmg_apisEndpoint() {\n return this.portalServerUrl + '/apis?includeSchema=true';\n }\n private get gg_apisEndpoint() {\n return this.portalServerUrl + '/api-products';\n }\n\n log = (s: string) => this.logger?.info(`gloo-platform-portal: ${s}`);\n warn = (s: string) => this.logger?.warn(`gloo-platform-portal: ${s}`);\n error = (s: string) => this.logger?.error(`gloo-platform-portal: ${s}`);\n getProviderName = () => `gloo-platform-portal-backend-provider`;\n async connect(connection: EntityProviderConnection): Promise<void> {\n this.connection = connection;\n }\n\n updatePortalServerUrl() {\n this._portalServerUrl = this.configUtil.getPortalServerUrl();\n this.entityBuilder.onPortalServerUrlChange(this.portalServerUrl);\n }\n\n updateApisEndpoint() {\n // For portalServerType:\n // - \"unknown, and \"gloo-mesh-gateway\": use GMG endpoint\n // - \"gloo-gateway\": use GG endpoint\n this._apisEndpoint =\n this.portalServerType === 'gloo-gateway'\n ? this.gg_apisEndpoint\n : this.gmg_apisEndpoint;\n this.entityBuilder.onApisEndpointChange(this.apisEndpoint);\n }\n\n updatePortalServerType(newType: typeof this.portalServerType) {\n this._portalServerType = newType;\n // When the portal server type changes, the apis endpoint may be updated.\n this.updateApisEndpoint();\n }\n\n //\n // 1. Init class\n //\n constructor(\n logger: LoggerService,\n config: Config,\n scheduler: SchedulerService,\n ) {\n this.logger = logger;\n this.config = config;\n this.configUtil = new ConfigUtil(this.error, this.warn, this.config);\n this.entityBuilder = new EntityBuilder();\n // Default extra debug-logging to false\n this.debugLogging = !!this.config?.getOptionalBoolean(\n 'glooPlatformPortal.backend.debugLogging',\n );\n this.log('Initializing GlooPlatformPortalProvider.');\n // Get the tokens, then schedule the task to update the catalog.\n this.startTokensRequests().then(() => this.startScheduler(scheduler));\n }\n\n //\n // 2. Get access_token\n //\n async startTokensRequests() {\n //\n // Make the initial request for the access_token.\n if (this.debugLogging) {\n this.log('Making the initial access_token request.');\n }\n if (!this.config) {\n this.error(\n 'Backstage config object not found when doing access token request.',\n );\n return;\n }\n const res = await doAccessTokenRequest(\n 'client_credentials',\n this.configUtil.getTokenEndpoint(),\n this.configUtil.getClientId(),\n this.configUtil.getClientSecret(),\n );\n this.latestTokensResponse = res;\n if (!this.latestTokensResponse) {\n // If there's a problem, wait to restart the access token\n // requests so as to not overload the auth server.\n this.warn('No latest access token. Re-requesting the access_token.');\n setTimeout(this.startTokensRequests.bind(this), 5000);\n return;\n }\n if (this.debugLogging) {\n this.log('Got the access_token.');\n }\n //\n // Parse the access_token JWT to find when it expires.\n const parsedToken = parseJwt(this.latestTokensResponse.access_token);\n if (!parsedToken.exp) {\n this.warn('No `exp` property found in the access_token JWT.');\n }\n const nowDate = new Date();\n const expiresDate = new Date(parsedToken.exp * 1000);\n const millisUntilExpires = expiresDate.getTime() - nowDate.getTime();\n if (millisUntilExpires <= 0) {\n this.warn('access token is expired!');\n this.latestTokensResponse = undefined;\n return;\n }\n if (this.debugLogging) {\n this.log('Setting a timeout to get the next access token.');\n }\n // Set the timeout to request new tokens.\n setTimeout(\n this.startTokensRequests.bind(this),\n // Don't make this request more than once a second,\n // and do the refresh 5 seconds early.\n Math.max(1000, millisUntilExpires - 5000),\n );\n }\n\n /**\n *\n * 3. Schedule sync.\n *\n * This passes the user config into the\n * Backstage plugin task scheduler.\n * */\n async startScheduler(scheduler: SchedulerService) {\n if (this.debugLogging) {\n this.log('Scheduling backstage catalog sync.');\n }\n const frequencyConfig = this.config?.getOptionalConfig(\n 'glooPlatformPortal.backend.syncFrequency',\n );\n // Get frequency from the config.\n const frequency = {\n hours: frequencyConfig?.getOptionalNumber('hours') ?? 0,\n minutes: frequencyConfig?.getOptionalNumber('minutes') ?? 0,\n seconds: frequencyConfig?.getOptionalNumber('seconds') ?? 0,\n milliseconds: frequencyConfig?.getOptionalNumber('milliseconds') ?? 0,\n };\n if (Object.values(frequency).every(v => v === 0)) {\n // If there are no values for frequency, set a resonable default instead of 0.\n frequency.minutes = 5;\n if (this.debugLogging) {\n this.log(\n `No frequency value was set, so the default value of ${frequency.minutes} minutes will be used.`,\n );\n }\n }\n if (this.debugLogging) {\n this.log(`Frequency set to ${JSON.stringify(frequency)}.`);\n }\n // Get timeout from the config.\n const timeoutConfig = this.config?.getOptionalConfig(\n 'glooPlatformPortal.backend.syncTimeout',\n );\n const timeout = {\n hours: timeoutConfig?.getOptionalNumber('hours') ?? 0,\n minutes: timeoutConfig?.getOptionalNumber('minutes') ?? 0,\n seconds: timeoutConfig?.getOptionalNumber('seconds') ?? 0,\n milliseconds: timeoutConfig?.getOptionalNumber('milliseconds') ?? 0,\n };\n if (Object.values(timeout).every(v => v === 0)) {\n // If there are no values for timeout, set a resonable default instead of 0.\n timeout.seconds = 30;\n if (this.debugLogging) {\n this.log(\n `No timeout value was set. The default value of ${timeout.seconds} seconds will be used.`,\n );\n }\n }\n if (this.debugLogging) {\n this.log(`Timeout set to ${JSON.stringify(timeout)}.`);\n }\n // Start the sync task on the Backstage scheduler.\n await scheduler.scheduleTask({\n id: 'run_gloo_platform_portal_refresh',\n fn: async () => {\n await this.run();\n },\n frequency,\n timeout,\n });\n }\n\n /**\n *\n * 4. Return new Backstage entities.\n *\n * Requests API information from the Gloo Platform Portal REST server,\n * and transforms the response into Backstage API entities.\n */\n async run(): Promise<void> {\n if (!this.connection || !this.latestTokensResponse) {\n throw new Error('Not initialized');\n }\n const entities: Entity[] = [];\n this.updatePortalServerUrl();\n this.updateApisEndpoint();\n\n // Make API request\n try {\n let processedAPIs = await this.fetchAPIs();\n\n //\n // Some Gloo Mesh Gateway portal servers returned the APIs grouped by APIProduct,\n // so we can convert it back to a list here.\n //\n if (\n this.portalServerType === 'gloo-mesh-gateway' &&\n !!processedAPIs?.length &&\n 'apiVersions' in processedAPIs[0]\n ) {\n const apiProducts = processedAPIs as unknown as APIProduct[];\n processedAPIs = apiProducts.reduce((accum, curProd) => {\n accum.push(\n ...curProd.apiVersions.reduce((accumVer, api) => {\n if (!!api.openapiSpecFetchErr) {\n this.warn(\n `Schema fetch error for ${api.apiId} : ${JSON.stringify(\n api.openapiSpecFetchErr,\n )}`,\n );\n }\n accumVer.push({\n apiId: api.apiId,\n apiProductDisplayName: curProd.apiProductDisplayName,\n apiProductId: curProd.apiProductId,\n apiVersion: api.apiVersion,\n contact: api.contact,\n customMetadata: api.customMetadata,\n description: api.description,\n license: api.license,\n termsOfService: api.termsOfService,\n title: api.title,\n usagePlans: api.usagePlans,\n openapiSpec: api.openapiSpec,\n openapiSpecFetchErr: api.openapiSpecFetchErr,\n });\n return accumVer;\n }, [] as API[]),\n );\n return accum;\n }, [] as API[]);\n }\n\n // Convert the APIs to entities\n for (let i = 0; i < processedAPIs.length; i++) {\n const api = processedAPIs[i];\n if ('id' in api) {\n //\n // For \"gloo-gateway\"\n //\n this.updatePortalServerType('gloo-gateway');\n entities.push(await this.getGlooGatewayApiEntity(api));\n } else if ('apiProductId' in api) {\n //\n // For \"gloo-mesh-gateway\"\n //\n this.updatePortalServerType('gloo-mesh-gateway');\n entities.push(await this.getGlooMeshGatewayApiEntity(api));\n }\n }\n if (this.debugLogging) {\n this.log(\n 'Transformed APIs into new entities: ' + JSON.stringify(entities),\n );\n }\n } catch (e) {\n this.error(\n `Could not get APIs from the portal server endpoint or their schemas or transform them into entities (${\n this.apisEndpoint\n }). Error: ${JSON.stringify(e)}`,\n );\n }\n\n await this.connection.applyMutation(\n this.entityBuilder.buildEntityProviderMutation(entities),\n );\n }\n\n /**\n * Returns the Backstage catalog entity for the \"gloo-gateway\" Portal Server API response.\n */\n async getGlooGatewayApiEntity(api: ApiVersionExtended): Promise<Entity> {\n return this.entityBuilder.buildApiVersionEntity(\n api.id,\n api.name,\n api.apiProductDescription,\n api.apiSpec,\n );\n }\n\n /**\n * Returns the Backstage catalog entity for the \"gloo-mesh-gateway\" Portal Server API response.\n */\n async getGlooMeshGatewayApiEntity(api: API): Promise<Entity> {\n if (!this.connection || !this.latestTokensResponse || !this.apisEndpoint) {\n throw new Error('Unable to getGlooMeshGatewayApiEntity');\n }\n let schema = api.openapiSpec;\n if (!schema && !api.openapiSpecFetchErr) {\n // If the schema was not attempted to be fetched with\n // the /apis call, we individually fetch it here.\n // This is for backwards compatibility only, for\n // when the schema was not in the /apis response.\n const schemaRes = await fetch(\n `${this.apisEndpoint}/${api.apiId}/schema`,\n {\n headers: {\n Authorization: `Bearer ${this.latestTokensResponse.access_token}`,\n },\n },\n );\n schema = (await schemaRes.json()) as APISchema;\n }\n return this.entityBuilder.buildApiVersionEntity(\n api.apiId,\n api.apiVersion,\n api.description,\n schema,\n );\n }\n\n /**\n * A helper function for getting the API's from the Portal Server.\n * This abstracts away the \"gloo-gateway\"/\"gloo-mesh-gateway\" portal server details.\n */\n async fetchAPIs() {\n if (!this.connection || !this.latestTokensResponse || !this.apisEndpoint) {\n throw new Error('Unable to fetch APIs');\n }\n const fetchInit: fetch.RequestInit = {\n headers: {\n Authorization: `Bearer ${this.latestTokensResponse.access_token}`,\n },\n };\n\n //\n // Make the initial apis request.\n //\n if (this.debugLogging) {\n this.log(\n `Fetching APIs from ${this.apisEndpoint} (identified as ${this.portalServerType}) with header: \"Authorization: Bearer ${this.latestTokensResponse.access_token}\"`,\n );\n }\n let res: ApisEndpointResponseType = null;\n try {\n res = await (await fetch(this.apisEndpoint, fetchInit)).json();\n } catch {}\n if (\n // If we didn't just try the GG endpoint, and\n this.apisEndpoint !== this.gg_apisEndpoint &&\n // the GG+GMG endpoints aren't the same, and\n this.gg_apisEndpoint !== this.gmg_apisEndpoint &&\n // the GMG request failed, or\n (!res ||\n // the GMG request didn't fail, it returned data, but it's not an array, or\n !Array.isArray(res) ||\n // the GMG request didn't fail, it returned data, but\n (!!res.length &&\n // it didn't return either GG or GMG data,\n !('id' in res[0]) &&\n !('apiVersions' in res[0])))\n ) {\n // try with the GG endpoint.\n if (this.debugLogging) {\n this.log(`Retrying fetching APIs using ${this.gg_apisEndpoint}`);\n }\n try {\n res = await (await fetch(this.gg_apisEndpoint, fetchInit)).json();\n } catch {}\n }\n if (this.debugLogging) {\n this.log(\n 'Performed fetch and recieved the response: ' + JSON.stringify(res),\n );\n }\n\n let processedAPIs: (API | ApiVersionExtended)[] = [];\n if (!!res?.length) {\n //\n // Check the portal server API type\n //\n var identifiedPortalServerType: PortalServerType = 'unknown';\n if ('id' in res[0]) {\n identifiedPortalServerType = 'gloo-gateway';\n } else {\n identifiedPortalServerType = 'gloo-mesh-gateway';\n }\n if (\n this.debugLogging &&\n this.portalServerType !== identifiedPortalServerType\n ) {\n this.log(\n 'Portal server type identified as: ' + identifiedPortalServerType,\n );\n }\n this.updatePortalServerType(identifiedPortalServerType);\n\n //\n // Transform the data\n //\n // For \"gloo-mesh-gateway\"\n if (identifiedPortalServerType === 'gloo-mesh-gateway') {\n if ('apiVersions' in res[0]) {\n // Some versions return the data grouped by APIProduct,\n // so we convert it back to a list here.\n const apiProducts = res as APIProduct[];\n processedAPIs = apiProducts.reduce((accum, curProd) => {\n accum.push(\n ...curProd.apiVersions.reduce((accumVer, api) => {\n accumVer.push({\n apiId: api.apiId,\n apiProductDisplayName: curProd.apiProductDisplayName,\n apiProductId: curProd.apiProductId,\n apiVersion: api.apiVersion,\n contact: api.contact,\n customMetadata: api.customMetadata,\n description: api.description,\n license: api.license,\n termsOfService: api.termsOfService,\n title: api.title,\n usagePlans: api.usagePlans,\n });\n return accumVer;\n }, [] as API[]),\n );\n return accum;\n }, [] as API[]);\n } else {\n processedAPIs = res as API[];\n }\n }\n // For \"gloo-gateway\"\n else if (identifiedPortalServerType === 'gloo-gateway') {\n // Fetch the information for each version.\n const summaries = res as ApiProductSummary[];\n // Reset the processedAPIs so we can add each version to it.\n processedAPIs = [];\n // We have to do a separate request for each ApiProduct in order to get their versions.\n for (let i = 0; i < summaries.length; i++) {\n const apiProductSummary = summaries[i];\n const getVersionsUrl = `${this.apisEndpoint}/${apiProductSummary.id}/versions`;\n if (this.debugLogging) {\n this.log(\n `Fetching API versions from ${getVersionsUrl} (identified as ${this.portalServerType}).`,\n );\n }\n let versions: ApiVersion[] = [];\n try {\n versions = await (await fetch(getVersionsUrl, fetchInit)).json();\n } catch {}\n if (this.debugLogging) {\n this.log(\n `Fetched ${getVersionsUrl} (identified as ${\n this.portalServerType\n }) and recieved the response: ${JSON.stringify(versions)}`,\n );\n }\n if (!!versions?.length) {\n // Add each API product's version to the processedAPIs.\n processedAPIs.push(\n ...versions.map(v => ({\n ...v,\n apiProductDescription: apiProductSummary.description,\n })),\n );\n }\n }\n }\n }\n\n return processedAPIs;\n }\n}\n"],"names":["__publicField","fetch"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/provider/ConfigUtil.ts","../src/provider/utility.ts","../src/provider/EntityBuilder.ts","../src/provider/GlooPlatformPortalProvider.ts"],"sourcesContent":["import { Config } from '@backstage/config';\n\ntype logFn = (s: string) => any;\n\nexport class ConfigUtil {\n logErr: logFn;\n logWarning: logFn;\n config: Config;\n\n constructor(logErr: logFn, logWarning: logFn, config: Config) {\n this.logErr = logErr;\n this.logWarning = logWarning;\n this.config = config;\n }\n\n getPortalServerUrl() {\n if (!this.config) {\n this.logErr('No backstage config found when getting portal server url.');\n return '';\n }\n let value = this.config.getOptionalString(\n 'glooPlatformPortal.backend.portalServerUrl',\n );\n // Remove trailing slash if supplied.\n if (!!value && value.at(-1) === '/')\n value = value.substring(0, value.length - 1);\n return value ?? 'http://localhost:31080/v1';\n }\n\n getClientSecret() {\n if (!this.config) {\n this.logErr('No backstage config found when getting client secret.');\n return '';\n }\n const value = this.config.getOptionalString(\n 'glooPlatformPortal.backend.clientSecret',\n );\n if (!value) {\n this.logWarning(\n 'No glooPlatformPortal.backend.clientSecret found in app-config.local.yaml',\n );\n }\n return value ?? '';\n }\n\n getClientId() {\n if (!this.config) {\n this.logErr('No backstage config found when getting client id.');\n return '';\n }\n const value = this.config.getOptionalString(\n 'glooPlatformPortal.backend.clientId',\n );\n if (!value) {\n this.logWarning(\n 'No glooPlatformPortal.backend.clientId found in app-config.local.yaml',\n );\n }\n return value ?? '';\n }\n\n getTokenEndpoint() {\n if (!this.config) {\n this.logErr('No backstage config found when getting token endpoint.');\n return '';\n }\n const value = this.config.getOptionalString(\n 'glooPlatformPortal.backend.tokenEndpoint',\n );\n if (!value) {\n this.logWarning(\n 'No glooPlatformPortal.backend.tokenEndpoint found in app-config.local.yaml',\n );\n }\n return value ?? '';\n }\n}\n","import fetch from 'node-fetch';\nimport { AccessTokensResponse } from './api-types';\n\nexport function parseJwt(token: string) {\n const base64Url = token.split('.')[1];\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');\n const jsonPayload = decodeURIComponent(\n atob(base64)\n .split('')\n .map(c => `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`)\n .join(''),\n );\n return JSON.parse(jsonPayload);\n}\n\nexport function objectToUrlFormEncodedPayload(\n requestJSON: Record<string, string>,\n) {\n const formBodyPieces = [] as string[];\n for (const property in requestJSON) {\n if (!requestJSON.hasOwnProperty(property)) continue;\n const encodedKey = encodeURIComponent(property);\n const encodedValue = encodeURIComponent(\n requestJSON[property as keyof typeof requestJSON],\n );\n formBodyPieces.push(`${encodedKey}=${encodedValue}`);\n }\n const formBodyString = formBodyPieces.join('&');\n return formBodyString;\n}\n\nexport async function doAccessTokenRequest(\n grantType: 'refresh_token' | 'client_credentials',\n tokenEndpoint: string,\n clientId: string,\n clientSecret: string,\n refreshToken?: string,\n) {\n const formData = {} as Record<string, string>;\n //\n // Build the request payload for a new oauth access token.\n //\n formData.grant_type = grantType;\n formData.client_id = clientId;\n formData.client_secret = clientSecret;\n if (grantType === 'refresh_token') {\n if (!refreshToken) {\n return undefined;\n }\n formData.refresh_token = refreshToken;\n }\n //\n // Make the request\n //\n const rawRes = await fetch(tokenEndpoint, {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',\n },\n method: 'POST',\n body: objectToUrlFormEncodedPayload(formData),\n });\n let resJSON: any;\n try {\n resJSON = await rawRes.json();\n } catch {\n throw new Error('Error parsing oauth response.');\n }\n if (!!resJSON.error_description) {\n throw new Error(resJSON.error_description);\n }\n if (!!resJSON.error) {\n throw new Error(resJSON.error);\n }\n //\n // Check for the access token in the response.\n //\n if (!resJSON.access_token) {\n throw new Error(\n \"No 'access_token' property was found in the oauth response body.\",\n );\n }\n return resJSON as AccessTokensResponse;\n}\n\n//\n// From: https://backstage.io/docs/features/software-catalog/descriptor-format\n//\nconst sanitizeRegex = {\n // Each tag must be sequences of [a-z0-9:+#] separated by -, at most 63 characters in total\n tag: /[a-z]|[0-9]|\\:|\\+|\\#|\\-/,\n // Strings of length at least 1, and at most 63\n // Must consist of sequences of [a-z0-9A-Z] possibly separated by one of [-_.].\n name: /[a-z]|[0-9]|[A-Z]|\\-|\\_|\\./,\n // Namespaces must be sequences of [a-zA-Z0-9], possibly separated by -, at most 63 characters in total.\n namespace: /[a-z]|[0-9]|[A-Z]|\\-/,\n};\n\n/**\n * Sanitizes a string before adding it to a backstage entity.\n */\nexport const sanitizeStringForEntity = (\n propertyType: keyof typeof sanitizeRegex,\n propertyValue: string,\n) => {\n return propertyValue\n .split('')\n .map(ch => (!sanitizeRegex[propertyType].test(ch) ? '-' : ch))\n .reduce(\n (prev, cur) =>\n // Don't go over 63 characters.\n prev.length >= 62\n ? prev\n : // Don't repeat \"-\"\n prev.at(-1) === '-' && cur === '-'\n ? prev\n : prev + cur,\n '',\n );\n};\n","import { Entity, EntityMeta } from '@backstage/catalog-model';\nimport { EntityProviderMutation } from '@backstage/plugin-catalog-node';\nimport { APISchema } from './api-types';\nimport { sanitizeStringForEntity } from './utility';\n\nexport class EntityBuilder {\n // Backstage catalog metadata.\n private bsGroupName = 'solo-io-service-accounts';\n private bsServiceAccountName = 'gloo-platform-portal-service-account';\n private bsSystemName = 'gloo-platform-portal-apis';\n\n private apisEndpoint = '';\n private portalServerUrl = '';\n\n onApisEndpointChange = (apisEndpoint: string) =>\n (this.apisEndpoint = apisEndpoint);\n onPortalServerUrlChange = (portalServerUrl: string) =>\n (this.portalServerUrl = portalServerUrl);\n\n /**\n * A helper function to return a Backstage catalog entity for an API.\n */\n buildApiVersionEntity(\n apiId: string,\n apiVersion: string | undefined,\n apiDescription: string,\n schema: APISchema | string | undefined,\n ): Entity {\n const newEntity: Entity = {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'API',\n metadata: {\n tags: [\n 'gloo-platform',\n ...(!!apiVersion\n ? ['api-version-' + sanitizeStringForEntity('tag', apiVersion)]\n : []),\n ],\n name: sanitizeStringForEntity('name', apiId),\n title: apiId,\n description: apiDescription,\n annotations: {\n 'backstage.io/managed-by-location': `url:${this.apisEndpoint}`,\n 'backstage.io/managed-by-origin-location': `url:${this.apisEndpoint}`,\n },\n } as EntityMeta,\n spec: {\n type: 'openapi',\n lifecycle: 'production',\n system: this.bsSystemName,\n owner: `user:${this.bsServiceAccountName}`,\n definition: JSON.stringify(schema),\n },\n };\n return newEntity;\n }\n\n /**\n * A helper function to return a Backstage catalog EntityProviderMutation object for the GlooPlatformPortalProvider plugin.\n * The returned object includes entities that will be added to the catalog.\n */\n buildEntityProviderMutation(entities: Entity[]) {\n const locationKey = `gloo-platform-portal-provider`;\n const mutationObj: EntityProviderMutation = {\n type: 'full',\n entities: [\n {\n locationKey,\n entity: {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'Group',\n metadata: {\n name: this.bsGroupName,\n annotations: {\n 'backstage.io/managed-by-location': `url:${this.portalServerUrl}`,\n 'backstage.io/managed-by-origin-location': `url:${this.portalServerUrl}`,\n },\n },\n spec: {\n type: 'service-account-group',\n children: [],\n members: [this.bsServiceAccountName],\n },\n },\n },\n {\n locationKey,\n entity: {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'User',\n metadata: {\n name: this.bsServiceAccountName,\n annotations: {\n 'backstage.io/managed-by-location': `url:${this.portalServerUrl}`,\n 'backstage.io/managed-by-origin-location': `url:${this.portalServerUrl}`,\n },\n },\n spec: {\n displayName: 'Solo.io Service Account',\n email: '',\n picture: '',\n memberOf: [this.bsGroupName],\n },\n },\n },\n // {\n // locationKey,\n // entity: {\n // apiVersion: 'backstage.io/v1alpha1',\n // kind: 'Domain',\n // metadata: {\n // tags: ['gloo-platform'],\n // name: 'api-product',\n // description: 'Gloo Platform Portal ApiProduct resources.',\n // annotations: {\n // 'backstage.io/managed-by-location': 'url:' + this.apisEndpoint,\n // 'backstage.io/managed-by-origin-location':\n // 'url:' + this.apisEndpoint,\n // },\n // } as EntityMeta,\n // spec: {\n // owner: 'user:' + bsServiceAccountName,\n // },\n // },\n // },\n {\n locationKey,\n entity: {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'System',\n metadata: {\n tags: ['gloo-platform'],\n name: this.bsSystemName,\n title: 'Gloo Platform Portal APIs',\n annotations: {\n 'backstage.io/managed-by-location': `url:${this.portalServerUrl}`,\n 'backstage.io/managed-by-origin-location': `url:${this.portalServerUrl}`,\n },\n } as EntityMeta,\n spec: {\n owner: `user:${this.bsServiceAccountName}`,\n // domain: 'api-product',\n },\n },\n },\n ...entities.map(entity => ({ locationKey, entity })),\n ],\n };\n return mutationObj;\n }\n}\n","import { LoggerService, SchedulerService } from '@backstage/backend-plugin-api';\nimport { Entity } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport {\n EntityProvider,\n EntityProviderConnection,\n} from '@backstage/plugin-catalog-node';\nimport fetch from 'node-fetch';\nimport { ConfigUtil } from './ConfigUtil';\nimport { EntityBuilder } from './EntityBuilder';\nimport {\n API,\n APIProduct,\n APISchema,\n AccessTokensResponse,\n ApiProductSummary,\n ApiVersion,\n ApiVersionExtended,\n} from './api-types';\nimport { doAccessTokenRequest, parseJwt } from './utility';\n\ntype PortalServerType = 'gloo-mesh-gateway' | 'gloo-gateway' | 'unknown';\n\ntype ApisEndpointResponseType =\n | API[]\n | APIProduct[]\n | ApiProductSummary[]\n | null;\n\n\ntype EntityTransformation = (entity: Entity, api: ApiVersionExtended | API) => Promise<Entity>\n\n/**\n * Provides API entities from the Gloo Platform Portal REST server.\n */\nexport class GlooPlatformPortalProvider implements EntityProvider {\n private connection?: EntityProviderConnection;\n private logger: LoggerService;\n private config: Config;\n private latestTokensResponse?: AccessTokensResponse;\n private debugLogging = false;\n private entityTransformation?: EntityTransformation;\n\n // Helper classes\n private configUtil: ConfigUtil;\n private entityBuilder: EntityBuilder;\n\n /**\n * Defaults to 'unknown'.\n * This is updated to 'gloo-gateway' or 'gloo-mesh-gateway' depending on the api response.\n */\n private _portalServerType: PortalServerType = 'unknown';\n private get portalServerType() {\n return this._portalServerType;\n }\n private _portalServerUrl = '';\n private get portalServerUrl() {\n return this._portalServerUrl;\n }\n private _apisEndpoint = '';\n private get apisEndpoint() {\n return this._apisEndpoint;\n }\n private get gmg_apisEndpoint() {\n return this.portalServerUrl + '/apis';\n }\n private get gg_apisEndpoint() {\n return this.portalServerUrl + '/api-products';\n }\n\n log = (s: string) => this.logger?.info(`gloo-platform-portal: ${s}`);\n warn = (s: string) => this.logger?.warn(`gloo-platform-portal: ${s}`);\n error = (s: string) => this.logger?.error(`gloo-platform-portal: ${s}`);\n getProviderName = () => `gloo-platform-portal-backend-provider`;\n async connect(connection: EntityProviderConnection): Promise<void> {\n this.connection = connection;\n }\n\n updatePortalServerUrl() {\n this._portalServerUrl = this.configUtil.getPortalServerUrl();\n this.entityBuilder.onPortalServerUrlChange(this.portalServerUrl);\n }\n\n updateApisEndpoint() {\n // For portalServerType:\n // - \"unknown, and \"gloo-mesh-gateway\": use GMG endpoint\n // - \"gloo-gateway\": use GG endpoint\n this._apisEndpoint =\n this.portalServerType === 'gloo-gateway'\n ? this.gg_apisEndpoint\n : this.gmg_apisEndpoint;\n this.entityBuilder.onApisEndpointChange(this.apisEndpoint);\n }\n\n updatePortalServerType(newType: typeof this.portalServerType) {\n this._portalServerType = newType;\n // When the portal server type changes, the apis endpoint may be updated.\n this.updateApisEndpoint();\n }\n\n\n //\n // 1. Init class\n //\n constructor(\n logger: LoggerService,\n config: Config,\n scheduler: SchedulerService,\n entityTransformation?: EntityTransformation\n ) {\n this.logger = logger;\n this.config = config;\n this.entityTransformation = entityTransformation;\n this.configUtil = new ConfigUtil(this.error, this.warn, this.config);\n this.entityBuilder = new EntityBuilder();\n // Default extra debug-logging to false\n this.debugLogging = !!this.config?.getOptionalBoolean(\n 'glooPlatformPortal.backend.debugLogging',\n );\n this.log('Initializing GlooPlatformPortalProvider.');\n // Get the tokens, then schedule the task to update the catalog.\n this.startTokensRequests().then(() => this.startScheduler(scheduler));\n }\n\n //\n // 2. Get access_token\n //\n async startTokensRequests() {\n //\n // Make the initial request for the access_token.\n if (this.debugLogging) {\n this.log('Making the initial access_token request.');\n }\n if (!this.config) {\n this.error(\n 'Backstage config object not found when doing access token request.',\n );\n return;\n }\n const res = await doAccessTokenRequest(\n 'client_credentials',\n this.configUtil.getTokenEndpoint(),\n this.configUtil.getClientId(),\n this.configUtil.getClientSecret(),\n );\n this.latestTokensResponse = res;\n if (!this.latestTokensResponse) {\n // If there's a problem, wait to restart the access token\n // requests so as to not overload the auth server.\n this.warn('No latest access token. Re-requesting the access_token.');\n setTimeout(this.startTokensRequests.bind(this), 5000);\n return;\n }\n if (this.debugLogging) {\n this.log('Got the access_token.');\n }\n //\n // Parse the access_token JWT to find when it expires.\n const parsedToken = parseJwt(this.latestTokensResponse.access_token);\n if (!parsedToken.exp) {\n this.warn('No `exp` property found in the access_token JWT.');\n }\n const nowDate = new Date();\n const expiresDate = new Date(parsedToken.exp * 1000);\n const millisUntilExpires = expiresDate.getTime() - nowDate.getTime();\n if (millisUntilExpires <= 0) {\n this.warn('access token is expired!');\n this.latestTokensResponse = undefined;\n return;\n }\n if (this.debugLogging) {\n this.log('Setting a timeout to get the next access token.');\n }\n // Set the timeout to request new tokens.\n setTimeout(\n this.startTokensRequests.bind(this),\n // Don't make this request more than once a second,\n // and do the refresh 5 seconds early.\n Math.max(1000, millisUntilExpires - 5000),\n );\n }\n\n /**\n *\n * 3. Schedule sync.\n *\n * This passes the user config into the\n * Backstage plugin task scheduler.\n * */\n async startScheduler(scheduler: SchedulerService) {\n if (this.debugLogging) {\n this.log('Scheduling backstage catalog sync.');\n }\n const frequencyConfig = this.config?.getOptionalConfig(\n 'glooPlatformPortal.backend.syncFrequency',\n );\n // Get frequency from the config.\n const frequency = {\n hours: frequencyConfig?.getOptionalNumber('hours') ?? 0,\n minutes: frequencyConfig?.getOptionalNumber('minutes') ?? 0,\n seconds: frequencyConfig?.getOptionalNumber('seconds') ?? 0,\n milliseconds: frequencyConfig?.getOptionalNumber('milliseconds') ?? 0,\n };\n if (Object.values(frequency).every(v => v === 0)) {\n // If there are no values for frequency, set a resonable default instead of 0.\n frequency.minutes = 5;\n if (this.debugLogging) {\n this.log(\n `No frequency value was set, so the default value of ${frequency.minutes} minutes will be used.`,\n );\n }\n }\n if (this.debugLogging) {\n this.log(`Frequency set to ${JSON.stringify(frequency)}.`);\n }\n // Get timeout from the config.\n const timeoutConfig = this.config?.getOptionalConfig(\n 'glooPlatformPortal.backend.syncTimeout',\n );\n const timeout = {\n hours: timeoutConfig?.getOptionalNumber('hours') ?? 0,\n minutes: timeoutConfig?.getOptionalNumber('minutes') ?? 0,\n seconds: timeoutConfig?.getOptionalNumber('seconds') ?? 0,\n milliseconds: timeoutConfig?.getOptionalNumber('milliseconds') ?? 0,\n };\n if (Object.values(timeout).every(v => v === 0)) {\n // If there are no values for timeout, set a resonable default instead of 0.\n timeout.seconds = 30;\n if (this.debugLogging) {\n this.log(\n `No timeout value was set. The default value of ${timeout.seconds} seconds will be used.`,\n );\n }\n }\n if (this.debugLogging) {\n this.log(`Timeout set to ${JSON.stringify(timeout)}.`);\n }\n // Start the sync task on the Backstage scheduler.\n await scheduler.scheduleTask({\n id: 'run_gloo_platform_portal_refresh',\n fn: async () => {\n await this.run();\n },\n frequency,\n timeout,\n });\n }\n\n /**\n *\n * 4. Return new Backstage entities.\n *\n * Requests API information from the Gloo Platform Portal REST server,\n * and transforms the response into Backstage API entities.\n */\n async run(): Promise<void> {\n if (!this.connection || !this.latestTokensResponse) {\n throw new Error('Not initialized');\n }\n const entities: Entity[] = [];\n this.updatePortalServerUrl();\n this.updateApisEndpoint();\n\n // Make API request\n try {\n let processedAPIs = await this.fetchAPIs();\n\n //\n // Some Gloo Mesh Gateway portal servers returned the APIs grouped by APIProduct,\n // so we can convert it back to a list here.\n //\n if (\n this.portalServerType === 'gloo-mesh-gateway' &&\n !!processedAPIs?.length &&\n 'apiVersions' in processedAPIs[0]\n ) {\n const apiProducts = processedAPIs as unknown as APIProduct[];\n processedAPIs = apiProducts.reduce((accum, curProd) => {\n accum.push(\n ...curProd.apiVersions.reduce((accumVer, api) => {\n if (!!api.openapiSpecFetchErr) {\n this.warn(\n `Schema fetch error for ${api.apiId} : ${JSON.stringify(\n api.openapiSpecFetchErr,\n )}`,\n );\n }\n accumVer.push({\n apiId: api.apiId,\n apiProductDisplayName: curProd.apiProductDisplayName,\n apiProductId: curProd.apiProductId,\n apiVersion: api.apiVersion,\n contact: api.contact,\n customMetadata: api.customMetadata,\n description: api.description,\n license: api.license,\n termsOfService: api.termsOfService,\n title: api.title,\n usagePlans: api.usagePlans,\n openapiSpec: api.openapiSpec,\n openapiSpecFetchErr: api.openapiSpecFetchErr,\n });\n return accumVer;\n }, [] as API[]),\n );\n return accum;\n }, [] as API[]);\n }\n\n // Convert the APIs to entities\n for (let i = 0; i < processedAPIs.length; i++) {\n const api = processedAPIs[i];\n if ('id' in api) {\n //\n // For \"gloo-gateway\"\n //\n this.updatePortalServerType('gloo-gateway');\n let entity = await this.getGlooGatewayApiEntity(api);\n entities.push(await this.applyEntityTransformation(entity, api));\n } else if ('apiProductId' in api) {\n //\n // For \"gloo-mesh-gateway\"\n //\n this.updatePortalServerType('gloo-mesh-gateway');\n let entity = await this.getGlooMeshGatewayApiEntity(api);\n entities.push(await this.applyEntityTransformation(entity, api));\n }\n }\n if (this.debugLogging) {\n this.log(\n 'Transformed APIs into new entities: ' + JSON.stringify(entities),\n );\n }\n } catch (e) {\n this.error(\n `Could not get APIs from the portal server endpoint or their schemas or transform them into entities (${\n this.apisEndpoint\n }). Error: ${JSON.stringify(e)}`,\n );\n }\n\n await this.connection.applyMutation(\n this.entityBuilder.buildEntityProviderMutation(entities),\n );\n }\n\n /**\n * Returns the Backstage catalog entity for the \"gloo-gateway\" Portal Server API response.\n */\n async getGlooGatewayApiEntity(api: ApiVersionExtended): Promise<Entity> {\n return this.entityBuilder.buildApiVersionEntity(\n api.id,\n api.name,\n api.apiProductDescription,\n api.apiSpec,\n );\n }\n\n /**\n * Returns the Backstage catalog entity for the \"gloo-mesh-gateway\" Portal Server API response.\n */\n async getGlooMeshGatewayApiEntity(api: API): Promise<Entity> {\n if (!this.connection || !this.latestTokensResponse || !this.apisEndpoint) {\n throw new Error('Unable to getGlooMeshGatewayApiEntity');\n }\n let schema = api.openapiSpec;\n if (!schema && !api.openapiSpecFetchErr) {\n // If the schema was not attempted to be fetched with\n // the /apis call, we individually fetch it here.\n // This is for backwards compatibility only, for\n // when the schema was not in the /apis response.\n const schemaRes = await fetch(\n `${this.apisEndpoint}/${api.apiId}/schema`,\n {\n headers: {\n Authorization: `Bearer ${this.latestTokensResponse.access_token}`,\n },\n },\n );\n schema = (await schemaRes.json()) as APISchema;\n }\n return this.entityBuilder.buildApiVersionEntity(\n api.apiId,\n api.apiVersion,\n api.description,\n schema,\n );\n }\n\n /**\n * A helper function for getting the API's from the Portal Server.\n * This abstracts away the \"gloo-gateway\"/\"gloo-mesh-gateway\" portal server details.\n */\n async fetchAPIs() {\n if (!this.connection || !this.latestTokensResponse || !this.apisEndpoint) {\n throw new Error('Unable to fetch APIs');\n }\n const fetchInit: fetch.RequestInit = {\n headers: {\n Authorization: `Bearer ${this.latestTokensResponse.access_token}`,\n },\n };\n\n //\n // Make the initial apis request.\n //\n if (this.debugLogging) {\n this.log(\n `Fetching APIs from ${this.apisEndpoint} (identified as ${this.portalServerType}) with header: \"Authorization: Bearer ${this.latestTokensResponse.access_token}\"`,\n );\n }\n let res: ApisEndpointResponseType = null;\n try {\n res = await (await fetch(this.apisEndpoint, fetchInit)).json();\n } catch {}\n if (\n // If we didn't just try the GG endpoint, and\n this.apisEndpoint !== this.gg_apisEndpoint &&\n // the GG+GMG endpoints aren't the same, and\n this.gg_apisEndpoint !== this.gmg_apisEndpoint &&\n // the GMG request failed, or\n (!res ||\n // the GMG request didn't fail, it returned data, but it's not an array, or\n !Array.isArray(res) ||\n // the GMG request didn't fail, it returned data, but\n (!!res.length &&\n // it didn't return either GG or GMG data,\n !('id' in res[0]) &&\n !('apiVersions' in res[0])))\n ) {\n // try with the GG endpoint.\n if (this.debugLogging) {\n this.log(`Retrying fetching APIs using ${this.gg_apisEndpoint}`);\n }\n try {\n res = await (await fetch(this.gg_apisEndpoint, fetchInit)).json();\n } catch {}\n }\n if (this.debugLogging) {\n this.log(\n 'Performed fetch and recieved the response: ' + JSON.stringify(res),\n );\n }\n\n let processedAPIs: (API | ApiVersionExtended)[] = [];\n if (!!res?.length) {\n //\n // Check the portal server API type\n //\n var identifiedPortalServerType: PortalServerType = 'unknown';\n if ('id' in res[0]) {\n identifiedPortalServerType = 'gloo-gateway';\n } else {\n identifiedPortalServerType = 'gloo-mesh-gateway';\n }\n if (\n this.debugLogging &&\n this.portalServerType !== identifiedPortalServerType\n ) {\n this.log(\n 'Portal server type identified as: ' + identifiedPortalServerType,\n );\n }\n this.updatePortalServerType(identifiedPortalServerType);\n\n //\n // Transform the data\n //\n // For \"gloo-mesh-gateway\"\n if (identifiedPortalServerType === 'gloo-mesh-gateway') {\n if ('apiVersions' in res[0]) {\n // Some versions return the data grouped by APIProduct,\n // so we convert it back to a list here.\n const apiProducts = res as APIProduct[];\n processedAPIs = apiProducts.reduce((accum, curProd) => {\n accum.push(\n ...curProd.apiVersions.reduce((accumVer, api) => {\n accumVer.push({\n apiId: api.apiId,\n apiProductDisplayName: curProd.apiProductDisplayName,\n apiProductId: curProd.apiProductId,\n apiVersion: api.apiVersion,\n contact: api.contact,\n customMetadata: api.customMetadata,\n description: api.description,\n license: api.license,\n termsOfService: api.termsOfService,\n title: api.title,\n usagePlans: api.usagePlans,\n });\n return accumVer;\n }, [] as API[]),\n );\n return accum;\n }, [] as API[]);\n } else {\n processedAPIs = res as API[];\n }\n }\n // For \"gloo-gateway\"\n else if (identifiedPortalServerType === 'gloo-gateway') {\n // Fetch the information for each version.\n const summaries = res as ApiProductSummary[];\n // Reset the processedAPIs so we can add each version to it.\n processedAPIs = [];\n // We have to do a separate request for each ApiProduct in order to get their versions.\n for (let i = 0; i < summaries.length; i++) {\n const apiProductSummary = summaries[i];\n const getVersionsUrl = `${this.apisEndpoint}/${apiProductSummary.id}/versions`;\n if (this.debugLogging) {\n this.log(\n `Fetching API versions from ${getVersionsUrl} (identified as ${this.portalServerType}).`,\n );\n }\n let versions: ApiVersion[] = [];\n try {\n versions = await (await fetch(getVersionsUrl, fetchInit)).json();\n } catch {}\n if (this.debugLogging) {\n this.log(\n `Fetched ${getVersionsUrl} (identified as ${\n this.portalServerType\n }) and recieved the response: ${JSON.stringify(versions)}`,\n );\n }\n if (!!versions?.length) {\n // Add each API product's version to the processedAPIs.\n processedAPIs.push(\n ...versions.map(v => ({\n ...v,\n apiProductDescription: apiProductSummary.description,\n })),\n );\n }\n }\n }\n }\n\n return processedAPIs;\n }\n\n private async applyEntityTransformation(entity: Entity, api: ApiVersionExtended | API) {\n if (!!this.entityTransformation) {\n return await this.entityTransformation(entity, api);\n }\n\n return entity;\n }\n}\n"],"names":["__publicField","fetch"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -68,6 +68,7 @@ type APISchema = {
|
|
|
68
68
|
}[];
|
|
69
69
|
};
|
|
70
70
|
|
|
71
|
+
type EntityTransformation = (entity: Entity, api: ApiVersionExtended | API) => Promise<Entity>;
|
|
71
72
|
/**
|
|
72
73
|
* Provides API entities from the Gloo Platform Portal REST server.
|
|
73
74
|
*/
|
|
@@ -77,6 +78,7 @@ declare class GlooPlatformPortalProvider implements EntityProvider {
|
|
|
77
78
|
private config;
|
|
78
79
|
private latestTokensResponse?;
|
|
79
80
|
private debugLogging;
|
|
81
|
+
private entityTransformation?;
|
|
80
82
|
private configUtil;
|
|
81
83
|
private entityBuilder;
|
|
82
84
|
/**
|
|
@@ -99,7 +101,7 @@ declare class GlooPlatformPortalProvider implements EntityProvider {
|
|
|
99
101
|
updatePortalServerUrl(): void;
|
|
100
102
|
updateApisEndpoint(): void;
|
|
101
103
|
updatePortalServerType(newType: typeof this.portalServerType): void;
|
|
102
|
-
constructor(logger: LoggerService, config: Config, scheduler: SchedulerService);
|
|
104
|
+
constructor(logger: LoggerService, config: Config, scheduler: SchedulerService, entityTransformation?: EntityTransformation);
|
|
103
105
|
startTokensRequests(): Promise<void>;
|
|
104
106
|
/**
|
|
105
107
|
*
|
|
@@ -130,6 +132,7 @@ declare class GlooPlatformPortalProvider implements EntityProvider {
|
|
|
130
132
|
* This abstracts away the "gloo-gateway"/"gloo-mesh-gateway" portal server details.
|
|
131
133
|
*/
|
|
132
134
|
fetchAPIs(): Promise<(API | ApiVersionExtended)[]>;
|
|
135
|
+
private applyEntityTransformation;
|
|
133
136
|
}
|
|
134
137
|
|
|
135
138
|
export { GlooPlatformPortalProvider };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solo.io/platform-portal-backstage-plugin-backend",
|
|
3
3
|
"description": "A Backstage backend plugin that synchronizes Gloo Platform Portal APIs with the Backstage catalog.",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.34",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"license": "Apache-2.0",
|