@solo.io/platform-portal-backstage-plugin-backend 0.0.3 → 0.0.4
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 +2 -2
- package/config.d.ts +0 -15
- package/dist/index.cjs.js +37 -24
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
package/config.d.ts
CHANGED
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2023 The Backstage Authors
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
1
|
export interface Config {
|
|
17
2
|
glooPlatformPortal: {
|
|
18
3
|
/**
|
package/dist/index.cjs.js
CHANGED
|
@@ -72,14 +72,14 @@ function parseJwt(token) {
|
|
|
72
72
|
}
|
|
73
73
|
function objectToUrlFormEncodedPayload(requestJSON) {
|
|
74
74
|
const formBodyPieces = [];
|
|
75
|
-
for (
|
|
75
|
+
for (const property in requestJSON) {
|
|
76
76
|
if (!requestJSON.hasOwnProperty(property))
|
|
77
77
|
continue;
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
const encodedKey = encodeURIComponent(property);
|
|
79
|
+
const encodedValue = encodeURIComponent(
|
|
80
80
|
requestJSON[property]
|
|
81
81
|
);
|
|
82
|
-
formBodyPieces.push(encodedKey
|
|
82
|
+
formBodyPieces.push(`${encodedKey}=${encodedValue}`);
|
|
83
83
|
}
|
|
84
84
|
const formBodyString = formBodyPieces.join("&");
|
|
85
85
|
return formBodyString;
|
|
@@ -126,15 +126,26 @@ async function doAccessTokenRequest(grantType, tokenEndpoint, clientId, clientSe
|
|
|
126
126
|
return resJSON;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
var __defProp = Object.defineProperty;
|
|
130
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
131
|
+
var __publicField = (obj, key, value) => {
|
|
132
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
133
|
+
return value;
|
|
134
|
+
};
|
|
129
135
|
class GlooPlatformPortalProvider {
|
|
130
136
|
//
|
|
131
137
|
// 1. Init class
|
|
132
138
|
//
|
|
133
139
|
constructor(env, logger, config) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
this
|
|
137
|
-
this
|
|
140
|
+
__publicField(this, "env");
|
|
141
|
+
__publicField(this, "connection");
|
|
142
|
+
__publicField(this, "logger");
|
|
143
|
+
__publicField(this, "config");
|
|
144
|
+
__publicField(this, "latestTokensResponse");
|
|
145
|
+
__publicField(this, "log", (s) => this.logger.info(`gloo-platform-portal: ${s}`));
|
|
146
|
+
__publicField(this, "warn", (s) => this.logger.warn(`gloo-platform-portal: ${s}`));
|
|
147
|
+
__publicField(this, "error", (s) => this.logger.error(`gloo-platform-portal: ${s}`));
|
|
148
|
+
__publicField(this, "getProviderName", () => `gloo-platform-portal-${this.env}`);
|
|
138
149
|
this.env = env;
|
|
139
150
|
this.logger = logger;
|
|
140
151
|
this.config = config;
|
|
@@ -206,7 +217,9 @@ class GlooPlatformPortalProvider {
|
|
|
206
217
|
this.latestTokensResponse = res;
|
|
207
218
|
this.refreshTheToken();
|
|
208
219
|
} catch (e) {
|
|
209
|
-
|
|
220
|
+
if (!!e && typeof e === "string") {
|
|
221
|
+
this.warn(e);
|
|
222
|
+
}
|
|
210
223
|
}
|
|
211
224
|
},
|
|
212
225
|
// Don't make this request more than once a second,
|
|
@@ -225,16 +238,16 @@ class GlooPlatformPortalProvider {
|
|
|
225
238
|
if (!this.connection || !this.latestTokensResponse) {
|
|
226
239
|
throw new Error("Not initialized");
|
|
227
240
|
}
|
|
228
|
-
|
|
241
|
+
const entities = [];
|
|
229
242
|
const bsGroupName = "solo-io-service-accounts";
|
|
230
243
|
const bsServiceAccountName = "gloo-platform-portal-service-account";
|
|
231
244
|
const bsSystemName = "gloo-platform-portal-apis";
|
|
232
245
|
const portalServerUrl = getPortalServerUrl(this.warn, this.config);
|
|
233
|
-
const apisEndpoint = portalServerUrl
|
|
246
|
+
const apisEndpoint = `${portalServerUrl}/apis`;
|
|
234
247
|
try {
|
|
235
248
|
const res = await fetch__default["default"](apisEndpoint, {
|
|
236
249
|
headers: {
|
|
237
|
-
Authorization:
|
|
250
|
+
Authorization: `Bearer ${this.latestTokensResponse.access_token}`
|
|
238
251
|
}
|
|
239
252
|
});
|
|
240
253
|
const apiProducts = await res.json();
|
|
@@ -243,10 +256,10 @@ class GlooPlatformPortalProvider {
|
|
|
243
256
|
for (let j = 0; j < apiProduct.apiVersions.length; j++) {
|
|
244
257
|
const apiVersion = apiProduct.apiVersions[j];
|
|
245
258
|
const schemaRes = await fetch__default["default"](
|
|
246
|
-
apisEndpoint
|
|
259
|
+
`${apisEndpoint}/${apiVersion.apiId}/schema`,
|
|
247
260
|
{
|
|
248
261
|
headers: {
|
|
249
|
-
Authorization:
|
|
262
|
+
Authorization: `Bearer ${this.latestTokensResponse.access_token}`
|
|
250
263
|
}
|
|
251
264
|
}
|
|
252
265
|
);
|
|
@@ -260,15 +273,15 @@ class GlooPlatformPortalProvider {
|
|
|
260
273
|
title: apiVersion.apiId,
|
|
261
274
|
description: apiVersion.description,
|
|
262
275
|
annotations: {
|
|
263
|
-
"backstage.io/managed-by-location":
|
|
264
|
-
"backstage.io/managed-by-origin-location":
|
|
276
|
+
"backstage.io/managed-by-location": `url:${apisEndpoint}`,
|
|
277
|
+
"backstage.io/managed-by-origin-location": `url:${apisEndpoint}`
|
|
265
278
|
}
|
|
266
279
|
},
|
|
267
280
|
spec: {
|
|
268
281
|
type: "openapi",
|
|
269
282
|
lifecycle: "production",
|
|
270
283
|
system: bsSystemName,
|
|
271
|
-
owner:
|
|
284
|
+
owner: `user:${bsServiceAccountName}`,
|
|
272
285
|
// definition: 'openapi: "3.0.0"',
|
|
273
286
|
definition: JSON.stringify(schema)
|
|
274
287
|
}
|
|
@@ -294,8 +307,8 @@ class GlooPlatformPortalProvider {
|
|
|
294
307
|
metadata: {
|
|
295
308
|
name: bsGroupName,
|
|
296
309
|
annotations: {
|
|
297
|
-
"backstage.io/managed-by-location":
|
|
298
|
-
"backstage.io/managed-by-origin-location":
|
|
310
|
+
"backstage.io/managed-by-location": `url:${portalServerUrl}`,
|
|
311
|
+
"backstage.io/managed-by-origin-location": `url:${portalServerUrl}`
|
|
299
312
|
}
|
|
300
313
|
},
|
|
301
314
|
spec: {
|
|
@@ -313,8 +326,8 @@ class GlooPlatformPortalProvider {
|
|
|
313
326
|
metadata: {
|
|
314
327
|
name: bsServiceAccountName,
|
|
315
328
|
annotations: {
|
|
316
|
-
"backstage.io/managed-by-location":
|
|
317
|
-
"backstage.io/managed-by-origin-location":
|
|
329
|
+
"backstage.io/managed-by-location": `url:${portalServerUrl}`,
|
|
330
|
+
"backstage.io/managed-by-origin-location": `url:${portalServerUrl}`
|
|
318
331
|
}
|
|
319
332
|
},
|
|
320
333
|
spec: {
|
|
@@ -355,12 +368,12 @@ class GlooPlatformPortalProvider {
|
|
|
355
368
|
name: bsSystemName,
|
|
356
369
|
title: "Gloo Platform Portal APIs",
|
|
357
370
|
annotations: {
|
|
358
|
-
"backstage.io/managed-by-location":
|
|
359
|
-
"backstage.io/managed-by-origin-location":
|
|
371
|
+
"backstage.io/managed-by-location": `url:${apisEndpoint}`,
|
|
372
|
+
"backstage.io/managed-by-origin-location": `url:${apisEndpoint}`
|
|
360
373
|
}
|
|
361
374
|
},
|
|
362
375
|
spec: {
|
|
363
|
-
owner:
|
|
376
|
+
owner: `user:${bsServiceAccountName}`
|
|
364
377
|
// domain: 'api-product',
|
|
365
378
|
}
|
|
366
379
|
}
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -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 (var property in requestJSON) {\n if (!requestJSON.hasOwnProperty(property)) continue;\n var encodedKey = encodeURIComponent(property);\n var 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 {\n EntityProvider,\n EntityProviderConnection,\n} from '@backstage/plugin-catalog-node';\nimport fetch from 'node-fetch';\nimport * as winston from 'winston';\nimport { 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\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 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 // this.log('Making the initial access_token request.');\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 // this.log('Got the initial access_token.');\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 // this.log('Setting a timeout to refresh the token.');\n // Set the timeout to request new tokens.\n setTimeout(\n async () => {\n if (!this.latestTokensResponse) {\n restartAccessTokenRequests();\n return;\n }\n try {\n // this.log('Making a refresh_token request.');\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 // this.log('Got a new refresh_token.');\n // Recurse\n this.refreshTheToken();\n } catch (e) {\n this.warn(e);\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. 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 let 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 const apiProducts = (await res.json()) as APIProduct[];\n // this.log(JSON.stringify(apiProducts));\n //\n // Convert the APIs to entities\n for (let i = 0; i < apiProducts.length; i++) {\n const apiProduct = apiProducts[i];\n // entities.push({\n // apiVersion: 'backstage.io/v1alpha1',\n // kind: 'Component',\n // metadata: {\n // tags: ['gloo-platform', 'api-product'],\n // name: apiProduct.apiProductId,\n // title: apiProduct.apiProductDisplayName,\n // description: 'This is a Gloo Platform Portal ApiProduct.',\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: 'service',\n // lifecycle: 'production',\n // owner: 'user:' + bsServiceAccountName,\n // providesApis: apiProduct.apiVersions.map(api => api.apiId),\n // system: bsSystemName,\n // },\n // });\n for (let j = 0; j < apiProduct.apiVersions.length; j++) {\n const apiVersion = apiProduct.apiVersions[j];\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:\n '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: ['gloo-platform', 'api-version', apiVersion.apiVersion],\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':\n '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 }\n // this.log(JSON.stringify(entities));\n } catch (e) {\n this.error(\n `Could not get APIs from the portal server endpoint (${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':\n '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':\n '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':\n '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 {\n EntityProvider,\n EntityProviderConnection,\n} from '@backstage/plugin-catalog-node';\nimport fetch from 'node-fetch';\nimport * as winston from 'winston';\nimport { 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\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 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 // this.log('Making the initial access_token request.');\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 // this.log('Got the initial access_token.');\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 // this.log('Setting a timeout to refresh the token.');\n // Set the timeout to request new tokens.\n setTimeout(\n async () => {\n if (!this.latestTokensResponse) {\n restartAccessTokenRequests();\n return;\n }\n try {\n // this.log('Making a refresh_token request.');\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 // this.log('Got a new refresh_token.');\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. 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 const apiProducts = (await res.json()) as APIProduct[];\n // this.log(JSON.stringify(apiProducts));\n //\n // Convert the APIs to entities\n for (let i = 0; i < apiProducts.length; i++) {\n const apiProduct = apiProducts[i];\n // entities.push({\n // apiVersion: 'backstage.io/v1alpha1',\n // kind: 'Component',\n // metadata: {\n // tags: ['gloo-platform', 'api-product'],\n // name: apiProduct.apiProductId,\n // title: apiProduct.apiProductDisplayName,\n // description: 'This is a Gloo Platform Portal ApiProduct.',\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: 'service',\n // lifecycle: 'production',\n // owner: 'user:' + bsServiceAccountName,\n // providesApis: apiProduct.apiVersions.map(api => api.apiId),\n // system: bsSystemName,\n // },\n // });\n for (let j = 0; j < apiProduct.apiVersions.length; j++) {\n const apiVersion = apiProduct.apiVersions[j];\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: ['gloo-platform', 'api-version', apiVersion.apiVersion],\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 }\n // this.log(JSON.stringify(entities));\n } catch (e) {\n this.error(\n `Could not get APIs from the portal server endpoint (${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/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Config } from '@backstage/config';
|
|
2
2
|
import { EntityProvider, EntityProviderConnection } from '@backstage/plugin-catalog-node';
|
|
3
|
-
import winston from 'winston';
|
|
3
|
+
import * as winston from 'winston';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Provides API entities from the Gloo Platform Portal REST server.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solo.io/platform-portal-backstage-plugin-backend",
|
|
3
|
-
"description": "",
|
|
4
|
-
"version": "0.0.
|
|
3
|
+
"description": "A Backstage backend plugin that synchronizes Gloo Platform Portal APIs with the Backstage catalog.",
|
|
4
|
+
"version": "0.0.4",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"yn": "^4.0.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@backstage/cli": "
|
|
44
|
+
"@backstage/cli": "^0.22.1",
|
|
45
45
|
"@types/supertest": "^2.0.8",
|
|
46
46
|
"msw": "^0.49.0",
|
|
47
47
|
"supertest": "^6.2.4"
|