@solo.io/platform-portal-backstage-plugin-backend 0.0.17 → 0.0.19

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/dist/index.cjs.js CHANGED
@@ -301,7 +301,7 @@ class GlooPlatformPortalProvider {
301
301
  const portalServerUrl = getPortalServerUrl(this.warn, this.config);
302
302
  const apisEndpoint = `${portalServerUrl}/apis`;
303
303
  try {
304
- const res = await fetch__default["default"](apisEndpoint, {
304
+ const res = await fetch__default["default"](apisEndpoint + "?includeSchema=true", {
305
305
  headers: {
306
306
  Authorization: `Bearer ${this.latestTokensResponse.access_token}`
307
307
  }
@@ -315,6 +315,13 @@ class GlooPlatformPortalProvider {
315
315
  processedAPIs = apiProducts.reduce((accum, curProd) => {
316
316
  accum.push(
317
317
  ...curProd.apiVersions.reduce((accumVer, api) => {
318
+ if (!!api.openapiSpecFetchErr) {
319
+ this.warn(
320
+ `Schema fetch error for ${api.apiId} : ${JSON.stringify(
321
+ api.openapiSpecFetchErr
322
+ )}`
323
+ );
324
+ }
318
325
  accumVer.push({
319
326
  apiId: api.apiId,
320
327
  apiProductDisplayName: curProd.apiProductDisplayName,
@@ -326,7 +333,9 @@ class GlooPlatformPortalProvider {
326
333
  license: api.license,
327
334
  termsOfService: api.termsOfService,
328
335
  title: api.title,
329
- usagePlans: api.usagePlans
336
+ usagePlans: api.usagePlans,
337
+ openapiSpec: api.openapiSpec,
338
+ openapiSpecFetchErr: api.openapiSpecFetchErr
330
339
  });
331
340
  return accumVer;
332
341
  }, [])
@@ -336,22 +345,27 @@ class GlooPlatformPortalProvider {
336
345
  }
337
346
  for (let i = 0; i < processedAPIs.length; i++) {
338
347
  const apiVersion = processedAPIs[i];
339
- const schemaRes = await fetch__default["default"](
340
- `${apisEndpoint}/${apiVersion.apiId}/schema`,
341
- {
342
- headers: {
343
- Authorization: `Bearer ${this.latestTokensResponse.access_token}`
348
+ let schema = apiVersion.openapiSpec;
349
+ if (!schema && !apiVersion.openapiSpecFetchErr) {
350
+ const schemaRes = await fetch__default["default"](
351
+ `${apisEndpoint}/${apiVersion.apiId}/schema`,
352
+ {
353
+ headers: {
354
+ Authorization: `Bearer ${this.latestTokensResponse.access_token}`
355
+ }
344
356
  }
345
- }
346
- );
347
- const schema = await schemaRes.json();
357
+ );
358
+ schema = await schemaRes.json();
359
+ }
348
360
  entities.push({
349
361
  apiVersion: "backstage.io/v1alpha1",
350
362
  kind: "API",
351
363
  metadata: {
352
364
  tags: [
353
365
  "gloo-platform",
354
- ...!!apiVersion.apiVersion ? ["api-version-" + apiVersion.apiVersion.replaceAll(" ", "_")] : []
366
+ ...!!apiVersion.apiVersion ? [
367
+ "api-version-" + apiVersion.apiVersion.replaceAll(" ", "-").replaceAll(".", "-").replaceAll(",", "-")
368
+ ] : []
355
369
  ],
356
370
  name: apiVersion.apiId,
357
371
  title: apiVersion.apiId,
@@ -366,7 +380,6 @@ class GlooPlatformPortalProvider {
366
380
  lifecycle: "production",
367
381
  system: bsSystemName,
368
382
  owner: `user:${bsServiceAccountName}`,
369
- // definition: 'openapi: "3.0.0"',
370
383
  definition: JSON.stringify(schema)
371
384
  }
372
385
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/provider/configHelpers.ts","../src/provider/utility.ts","../src/provider/GlooPlatformPortalProvider.ts"],"sourcesContent":["import { Config } from '@backstage/config';\n\ntype logFn = (s: string) => any;\n\nexport const getPortalServerUrl = (_: logFn, config: Config) => {\n let value = config.getOptionalString('glooPlatformPortal.portalServerUrl');\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\nexport const getClientSecret = (logWarning: logFn, config: Config) => {\n const value = config.getOptionalString('glooPlatformPortal.clientSecret');\n if (!value) {\n logWarning(\n 'No glooPlatformPortal.clientSecret found in app-config.local.yaml',\n );\n }\n return value ?? '';\n};\n\nexport const getClientId = (logWarning: logFn, config: Config) => {\n const value = config.getOptionalString('glooPlatformPortal.clientId');\n if (!value) {\n logWarning('No glooPlatformPortal.clientId found in app-config.local.yaml');\n }\n return value ?? '';\n};\n\nexport const getTokenEndpoint = (logWarning: logFn, config: Config) => {\n const value = config.getOptionalString('glooPlatformPortal.tokenEndpoint');\n if (!value) {\n logWarning(\n 'No glooPlatformPortal.tokenEndpoint found in app-config.local.yaml',\n );\n }\n return value ?? '';\n};\n\nexport const getServiceAccountPassword = (\n logWarning: logFn,\n config: Config,\n) => {\n const value = config.getOptionalString(\n 'glooPlatformPortal.serviceAccountPassword',\n );\n if (!value) {\n logWarning(\n 'No glooPlatformPortal.serviceAccountPassword found in app-config.local.yaml',\n );\n }\n return value ?? '';\n};\n\nexport const getServiceAccountUsername = (\n logWarning: logFn,\n config: Config,\n) => {\n const value = config.getOptionalString(\n 'glooPlatformPortal.serviceAccountUsername',\n );\n if (!value) {\n logWarning(\n 'No glooPlatformPortal.serviceAccountUsername found in app-config.local.yaml',\n );\n }\n return value ?? '';\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' | 'password',\n tokenEndpoint: string,\n clientId: string,\n clientSecret: string,\n username: string,\n password: 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 if (grantType === 'password') {\n formData.username = username;\n formData.password = password;\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","import { Entity, EntityMeta } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\n\nimport { PluginTaskScheduler } from '@backstage/backend-tasks';\nimport {\n EntityProvider,\n EntityProviderConnection,\n} from '@backstage/plugin-catalog-node';\nimport fetch from 'node-fetch';\nimport * as winston from 'winston';\nimport { API, APIProduct, APISchema, AccessTokensResponse } from './api-types';\nimport {\n getClientId,\n getClientSecret,\n getPortalServerUrl,\n getServiceAccountPassword,\n getServiceAccountUsername,\n getTokenEndpoint,\n} from './configHelpers';\nimport { doAccessTokenRequest, parseJwt } from './utility';\n\n/**\n * Provides API entities from the Gloo Platform Portal REST server.\n */\nexport class GlooPlatformPortalProvider implements EntityProvider {\n private readonly env: string;\n private connection?: EntityProviderConnection;\n private logger: winston.Logger;\n private config: Config;\n private latestTokensResponse?: AccessTokensResponse;\n private debugLogging = false;\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-${this.env}`;\n async connect(connection: EntityProviderConnection): Promise<void> {\n this.connection = connection;\n }\n\n //\n // 1. Init class\n //\n constructor(env: string, logger: winston.Logger, config: Config) {\n this.env = env;\n this.logger = logger;\n this.config = config;\n // Default extra debug-logging to false\n this.debugLogging = !!config.getOptionalBoolean(\n 'glooPlatformPortal.debugLogging',\n );\n this.log('Initializing GlooPlatformPortalProvider.');\n this.startTokensRequests();\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 const res = await doAccessTokenRequest(\n 'password',\n getTokenEndpoint(this.warn, this.config),\n getClientId(this.warn, this.config),\n getClientSecret(this.warn, this.config),\n getServiceAccountUsername(this.warn, this.config),\n getServiceAccountPassword(this.warn, this.config),\n );\n this.latestTokensResponse = res;\n if (this.debugLogging) {\n this.log('Got the initial access_token. ');\n }\n //\n // Set up a timeout to get refresh tokens this\n // updates this.latestToken on each callback.\n this.refreshTheToken();\n }\n\n /**\n *\n * 3. Get refresh_tokens.\n *\n * Calling this will refresh the access_token when it is expiring soon,\n * using the refresh_token in the access tokens response.\n * */\n async refreshTheToken() {\n const restartAccessTokenRequests = () => {\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, 5000);\n };\n if (!this.latestTokensResponse) {\n restartAccessTokenRequests();\n return;\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 refresh the token.');\n }\n // Set the timeout to request new tokens.\n setTimeout(\n async () => {\n if (!this.latestTokensResponse) {\n restartAccessTokenRequests();\n return;\n }\n try {\n if (this.debugLogging) {\n this.log('Making a refresh_token request.');\n }\n const res = await doAccessTokenRequest(\n 'refresh_token',\n getTokenEndpoint(this.warn, this.config),\n getClientId(this.warn, this.config),\n getClientSecret(this.warn, this.config),\n getServiceAccountUsername(this.warn, this.config),\n getServiceAccountPassword(this.warn, this.config),\n this.latestTokensResponse.refresh_token,\n );\n this.latestTokensResponse = res;\n if (this.debugLogging) {\n this.log('Got a new refresh_token.');\n }\n // Recurse\n this.refreshTheToken();\n } catch (e) {\n if (!!e && typeof e === 'string') {\n this.warn(e);\n }\n }\n },\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 * 4. Schedule sync.\n *\n * This is called during setup, and passes the user config into the\n * Backstage plugin task scheduler.\n * */\n async startScheduler(scheduler: PluginTaskScheduler) {\n const frequency = this.config.getOptionalConfig(\n 'glooPlatformPortal.syncFrequency',\n );\n const timeout = this.config.getOptionalConfig(\n 'glooPlatformPortal.syncTimeout',\n );\n await scheduler.scheduleTask({\n id: 'run_gloo_platform_portal_refresh',\n fn: async () => {\n await this.run();\n },\n frequency: !!frequency\n ? {\n hours: frequency.getOptionalNumber('hours'),\n minutes: frequency.getOptionalNumber('minutes'),\n seconds: frequency.getOptionalNumber('seconds'),\n milliseconds: frequency.getOptionalNumber('milliseconds'),\n }\n : {\n minutes: 5,\n },\n timeout: !!timeout\n ? {\n hours: timeout.getOptionalNumber('hours'),\n minutes: timeout.getOptionalNumber('minutes'),\n seconds: timeout.getOptionalNumber('seconds'),\n milliseconds: timeout.getOptionalNumber('milliseconds'),\n }\n : {\n seconds: 30,\n },\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\n const entities: Entity[] = [];\n const bsGroupName = 'solo-io-service-accounts';\n const bsServiceAccountName = 'gloo-platform-portal-service-account';\n const bsSystemName = 'gloo-platform-portal-apis';\n const portalServerUrl = getPortalServerUrl(this.warn, this.config);\n const apisEndpoint = `${portalServerUrl}/apis`;\n //\n // Make API request\n try {\n // TODO: Update this request once the server can optionally include the schema string in the response.\n const res = await fetch(apisEndpoint, {\n headers: {\n Authorization: `Bearer ${this.latestTokensResponse.access_token}`,\n },\n });\n let processedAPIs = (await res.json()) as API[];\n if (this.debugLogging) {\n this.log('Fetched APIs: ' + JSON.stringify(processedAPIs));\n }\n\n //\n // The server returns the APIs grouped by APIProduct,\n // so we can convert it back to a list here.\n //\n if (!!processedAPIs?.length && 'apiVersions' in processedAPIs[0]) {\n const apiProducts = processedAPIs as unknown 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 }\n\n //\n // Convert the APIs to entities\n for (let i = 0; i < processedAPIs.length; i++) {\n const apiVersion = processedAPIs[i];\n // TODO: Remove this once the schema is fetched along with the rest of the api info.\n const schemaRes = await fetch(\n `${apisEndpoint}/${apiVersion.apiId}/schema`,\n {\n headers: {\n Authorization: `Bearer ${this.latestTokensResponse.access_token}`,\n },\n },\n );\n const schema = (await schemaRes.json()) as APISchema;\n // this.log(JSON.stringify(schema));\n entities.push({\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'API',\n metadata: {\n tags: [\n 'gloo-platform',\n ...(!!apiVersion.apiVersion\n ? ['api-version-' + apiVersion.apiVersion.replaceAll(' ', '_')]\n : []),\n ],\n name: apiVersion.apiId,\n title: apiVersion.apiId,\n description: apiVersion.description,\n annotations: {\n 'backstage.io/managed-by-location': `url:${apisEndpoint}`,\n 'backstage.io/managed-by-origin-location': `url:${apisEndpoint}`,\n },\n } as EntityMeta,\n spec: {\n type: 'openapi',\n lifecycle: 'production',\n system: bsSystemName,\n owner: `user:${bsServiceAccountName}`,\n // definition: 'openapi: \"3.0.0\"',\n definition: JSON.stringify(schema),\n },\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 (${apisEndpoint}). Error: ${JSON.stringify(\n e,\n )}`,\n );\n }\n\n const locationKey = `gloo-platform-portal-provider:${this.env}`;\n await this.connection.applyMutation({\n type: 'full',\n entities: [\n {\n locationKey,\n entity: {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'Group',\n metadata: {\n name: bsGroupName,\n annotations: {\n 'backstage.io/managed-by-location': `url:${portalServerUrl}`,\n 'backstage.io/managed-by-origin-location': `url:${portalServerUrl}`,\n },\n },\n spec: {\n type: 'service-account-group',\n children: [],\n members: [bsServiceAccountName],\n },\n },\n },\n {\n locationKey,\n entity: {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'User',\n metadata: {\n name: bsServiceAccountName,\n annotations: {\n 'backstage.io/managed-by-location': `url:${portalServerUrl}`,\n 'backstage.io/managed-by-origin-location': `url:${portalServerUrl}`,\n },\n },\n spec: {\n displayName: 'Solo.io Service Account',\n email: '',\n picture: '',\n memberOf: [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:' + apisEndpoint,\n // 'backstage.io/managed-by-origin-location':\n // 'url:' + 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: bsSystemName,\n title: 'Gloo Platform Portal APIs',\n annotations: {\n 'backstage.io/managed-by-location': `url:${apisEndpoint}`,\n 'backstage.io/managed-by-origin-location': `url:${apisEndpoint}`,\n },\n } as EntityMeta,\n spec: {\n owner: `user:${bsServiceAccountName}`,\n // domain: 'api-product',\n },\n },\n },\n ...entities.map(entity => ({ locationKey, entity })),\n ],\n });\n }\n}\n"],"names":["fetch"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/provider/configHelpers.ts","../src/provider/utility.ts","../src/provider/GlooPlatformPortalProvider.ts"],"sourcesContent":["import { Config } from '@backstage/config';\n\ntype logFn = (s: string) => any;\n\nexport const getPortalServerUrl = (_: logFn, config: Config) => {\n let value = config.getOptionalString('glooPlatformPortal.portalServerUrl');\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\nexport const getClientSecret = (logWarning: logFn, config: Config) => {\n const value = config.getOptionalString('glooPlatformPortal.clientSecret');\n if (!value) {\n logWarning(\n 'No glooPlatformPortal.clientSecret found in app-config.local.yaml',\n );\n }\n return value ?? '';\n};\n\nexport const getClientId = (logWarning: logFn, config: Config) => {\n const value = config.getOptionalString('glooPlatformPortal.clientId');\n if (!value) {\n logWarning('No glooPlatformPortal.clientId found in app-config.local.yaml');\n }\n return value ?? '';\n};\n\nexport const getTokenEndpoint = (logWarning: logFn, config: Config) => {\n const value = config.getOptionalString('glooPlatformPortal.tokenEndpoint');\n if (!value) {\n logWarning(\n 'No glooPlatformPortal.tokenEndpoint found in app-config.local.yaml',\n );\n }\n return value ?? '';\n};\n\nexport const getServiceAccountPassword = (\n logWarning: logFn,\n config: Config,\n) => {\n const value = config.getOptionalString(\n 'glooPlatformPortal.serviceAccountPassword',\n );\n if (!value) {\n logWarning(\n 'No glooPlatformPortal.serviceAccountPassword found in app-config.local.yaml',\n );\n }\n return value ?? '';\n};\n\nexport const getServiceAccountUsername = (\n logWarning: logFn,\n config: Config,\n) => {\n const value = config.getOptionalString(\n 'glooPlatformPortal.serviceAccountUsername',\n );\n if (!value) {\n logWarning(\n 'No glooPlatformPortal.serviceAccountUsername found in app-config.local.yaml',\n );\n }\n return value ?? '';\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' | 'password',\n tokenEndpoint: string,\n clientId: string,\n clientSecret: string,\n username: string,\n password: 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 if (grantType === 'password') {\n formData.username = username;\n formData.password = password;\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","import { Entity, EntityMeta } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\n\nimport { PluginTaskScheduler } from '@backstage/backend-tasks';\nimport {\n EntityProvider,\n EntityProviderConnection,\n} from '@backstage/plugin-catalog-node';\nimport fetch from 'node-fetch';\nimport * as winston from 'winston';\nimport { API, APIProduct, APISchema, AccessTokensResponse } from './api-types';\nimport {\n getClientId,\n getClientSecret,\n getPortalServerUrl,\n getServiceAccountPassword,\n getServiceAccountUsername,\n getTokenEndpoint,\n} from './configHelpers';\nimport { doAccessTokenRequest, parseJwt } from './utility';\n\n/**\n * Provides API entities from the Gloo Platform Portal REST server.\n */\nexport class GlooPlatformPortalProvider implements EntityProvider {\n private readonly env: string;\n private connection?: EntityProviderConnection;\n private logger: winston.Logger;\n private config: Config;\n private latestTokensResponse?: AccessTokensResponse;\n private debugLogging = false;\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-${this.env}`;\n async connect(connection: EntityProviderConnection): Promise<void> {\n this.connection = connection;\n }\n\n //\n // 1. Init class\n //\n constructor(env: string, logger: winston.Logger, config: Config) {\n this.env = env;\n this.logger = logger;\n this.config = config;\n // Default extra debug-logging to false\n this.debugLogging = !!config.getOptionalBoolean(\n 'glooPlatformPortal.debugLogging',\n );\n this.log('Initializing GlooPlatformPortalProvider.');\n this.startTokensRequests();\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 const res = await doAccessTokenRequest(\n 'password',\n getTokenEndpoint(this.warn, this.config),\n getClientId(this.warn, this.config),\n getClientSecret(this.warn, this.config),\n getServiceAccountUsername(this.warn, this.config),\n getServiceAccountPassword(this.warn, this.config),\n );\n this.latestTokensResponse = res;\n if (this.debugLogging) {\n this.log('Got the initial access_token. ');\n }\n //\n // Set up a timeout to get refresh tokens this\n // updates this.latestToken on each callback.\n this.refreshTheToken();\n }\n\n /**\n *\n * 3. Get refresh_tokens.\n *\n * Calling this will refresh the access_token when it is expiring soon,\n * using the refresh_token in the access tokens response.\n * */\n async refreshTheToken() {\n const restartAccessTokenRequests = () => {\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, 5000);\n };\n if (!this.latestTokensResponse) {\n restartAccessTokenRequests();\n return;\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 refresh the token.');\n }\n // Set the timeout to request new tokens.\n setTimeout(\n async () => {\n if (!this.latestTokensResponse) {\n restartAccessTokenRequests();\n return;\n }\n try {\n if (this.debugLogging) {\n this.log('Making a refresh_token request.');\n }\n const res = await doAccessTokenRequest(\n 'refresh_token',\n getTokenEndpoint(this.warn, this.config),\n getClientId(this.warn, this.config),\n getClientSecret(this.warn, this.config),\n getServiceAccountUsername(this.warn, this.config),\n getServiceAccountPassword(this.warn, this.config),\n this.latestTokensResponse.refresh_token,\n );\n this.latestTokensResponse = res;\n if (this.debugLogging) {\n this.log('Got a new refresh_token.');\n }\n // Recurse\n this.refreshTheToken();\n } catch (e) {\n if (!!e && typeof e === 'string') {\n this.warn(e);\n }\n }\n },\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 * 4. Schedule sync.\n *\n * This is called during setup, and passes the user config into the\n * Backstage plugin task scheduler.\n * */\n async startScheduler(scheduler: PluginTaskScheduler) {\n const frequency = this.config.getOptionalConfig(\n 'glooPlatformPortal.syncFrequency',\n );\n const timeout = this.config.getOptionalConfig(\n 'glooPlatformPortal.syncTimeout',\n );\n await scheduler.scheduleTask({\n id: 'run_gloo_platform_portal_refresh',\n fn: async () => {\n await this.run();\n },\n frequency: !!frequency\n ? {\n hours: frequency.getOptionalNumber('hours'),\n minutes: frequency.getOptionalNumber('minutes'),\n seconds: frequency.getOptionalNumber('seconds'),\n milliseconds: frequency.getOptionalNumber('milliseconds'),\n }\n : {\n minutes: 5,\n },\n timeout: !!timeout\n ? {\n hours: timeout.getOptionalNumber('hours'),\n minutes: timeout.getOptionalNumber('minutes'),\n seconds: timeout.getOptionalNumber('seconds'),\n milliseconds: timeout.getOptionalNumber('milliseconds'),\n }\n : {\n seconds: 30,\n },\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\n const entities: Entity[] = [];\n const bsGroupName = 'solo-io-service-accounts';\n const bsServiceAccountName = 'gloo-platform-portal-service-account';\n const bsSystemName = 'gloo-platform-portal-apis';\n const portalServerUrl = getPortalServerUrl(this.warn, this.config);\n const apisEndpoint = `${portalServerUrl}/apis`;\n //\n // Make API request\n try {\n const res = await fetch(apisEndpoint + '?includeSchema=true', {\n headers: {\n Authorization: `Bearer ${this.latestTokensResponse.access_token}`,\n },\n });\n let processedAPIs = (await res.json()) as API[];\n if (this.debugLogging) {\n this.log('Fetched APIs: ' + JSON.stringify(processedAPIs));\n }\n\n //\n // The server returns the APIs grouped by APIProduct,\n // so we can convert it back to a list here.\n //\n if (!!processedAPIs?.length && 'apiVersions' in processedAPIs[0]) {\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 //\n // Convert the APIs to entities\n for (let i = 0; i < processedAPIs.length; i++) {\n const apiVersion = processedAPIs[i];\n let schema = apiVersion.openapiSpec;\n if (!schema && !apiVersion.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 `${apisEndpoint}/${apiVersion.apiId}/schema`,\n {\n headers: {\n Authorization: `Bearer ${this.latestTokensResponse.access_token}`,\n },\n },\n );\n schema = (await schemaRes.json()) as APISchema;\n }\n entities.push({\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'API',\n metadata: {\n tags: [\n 'gloo-platform',\n ...(!!apiVersion.apiVersion\n ? [\n 'api-version-' +\n apiVersion.apiVersion\n .replaceAll(' ', '-')\n .replaceAll('.', '-')\n .replaceAll(',', '-'),\n ]\n : []),\n ],\n name: apiVersion.apiId,\n title: apiVersion.apiId,\n description: apiVersion.description,\n annotations: {\n 'backstage.io/managed-by-location': `url:${apisEndpoint}`,\n 'backstage.io/managed-by-origin-location': `url:${apisEndpoint}`,\n },\n } as EntityMeta,\n spec: {\n type: 'openapi',\n lifecycle: 'production',\n system: bsSystemName,\n owner: `user:${bsServiceAccountName}`,\n definition: JSON.stringify(schema),\n },\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 (${apisEndpoint}). Error: ${JSON.stringify(\n e,\n )}`,\n );\n }\n\n const locationKey = `gloo-platform-portal-provider:${this.env}`;\n await this.connection.applyMutation({\n type: 'full',\n entities: [\n {\n locationKey,\n entity: {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'Group',\n metadata: {\n name: bsGroupName,\n annotations: {\n 'backstage.io/managed-by-location': `url:${portalServerUrl}`,\n 'backstage.io/managed-by-origin-location': `url:${portalServerUrl}`,\n },\n },\n spec: {\n type: 'service-account-group',\n children: [],\n members: [bsServiceAccountName],\n },\n },\n },\n {\n locationKey,\n entity: {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'User',\n metadata: {\n name: bsServiceAccountName,\n annotations: {\n 'backstage.io/managed-by-location': `url:${portalServerUrl}`,\n 'backstage.io/managed-by-origin-location': `url:${portalServerUrl}`,\n },\n },\n spec: {\n displayName: 'Solo.io Service Account',\n email: '',\n picture: '',\n memberOf: [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:' + apisEndpoint,\n // 'backstage.io/managed-by-origin-location':\n // 'url:' + 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: bsSystemName,\n title: 'Gloo Platform Portal APIs',\n annotations: {\n 'backstage.io/managed-by-location': `url:${apisEndpoint}`,\n 'backstage.io/managed-by-origin-location': `url:${apisEndpoint}`,\n },\n } as EntityMeta,\n spec: {\n owner: `user:${bsServiceAccountName}`,\n // domain: 'api-product',\n },\n },\n },\n ...entities.map(entity => ({ locationKey, entity })),\n ],\n });\n }\n}\n"],"names":["fetch"],"mappings":"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"}
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.17",
4
+ "version": "0.0.19",
5
5
  "main": "dist/index.cjs.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "license": "Apache-2.0",