@backstage/plugin-catalog-backend-module-aws 0.4.28-next.1 → 0.4.28
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/CHANGELOG.md +31 -0
- package/dist/lib/defaultTransformers.cjs.js +1 -1
- package/dist/lib/defaultTransformers.cjs.js.map +1 -1
- package/dist/processors/AwsOrganizationCloudAccountProcessor.cjs.js +2 -2
- package/dist/processors/AwsOrganizationCloudAccountProcessor.cjs.js.map +1 -1
- package/package.json +13 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# @backstage/plugin-catalog-backend-module-aws
|
|
2
2
|
|
|
3
|
+
## 0.4.28
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 8b3c83e: Improved handling of AWS S3 object keys when creating catalog locations.
|
|
8
|
+
- 736d84e: Use locale-insensitive Unicode casing for consistent string handling across environments.
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
- @backstage/backend-defaults@0.18.0
|
|
11
|
+
- @backstage/integration@2.1.2
|
|
12
|
+
- @backstage/plugin-catalog-common@1.2.0
|
|
13
|
+
- @backstage/catalog-model@1.10.1
|
|
14
|
+
- @backstage/config@1.3.9
|
|
15
|
+
- @backstage/plugin-kubernetes-common@0.9.13
|
|
16
|
+
- @backstage/backend-plugin-api@1.10.1
|
|
17
|
+
- @backstage/integration-aws-node@0.2.2
|
|
18
|
+
- @backstage/plugin-catalog-node@2.2.5
|
|
19
|
+
|
|
20
|
+
## 0.4.28-next.2
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- Updated dependencies
|
|
25
|
+
- @backstage/plugin-catalog-common@1.2.0-next.0
|
|
26
|
+
- @backstage/config@1.3.9-next.0
|
|
27
|
+
- @backstage/backend-defaults@0.17.9-next.1
|
|
28
|
+
- @backstage/plugin-catalog-node@2.2.5-next.1
|
|
29
|
+
- @backstage/backend-plugin-api@1.10.1-next.1
|
|
30
|
+
- @backstage/integration@2.1.2-next.1
|
|
31
|
+
- @backstage/integration-aws-node@0.2.2-next.0
|
|
32
|
+
- @backstage/plugin-kubernetes-common@0.9.13-next.1
|
|
33
|
+
|
|
3
34
|
## 0.4.28-next.1
|
|
4
35
|
|
|
5
36
|
### Patch Changes
|
|
@@ -28,7 +28,7 @@ const defaultEksClusterEntityTransformer = async (cluster, accountId) => {
|
|
|
28
28
|
};
|
|
29
29
|
};
|
|
30
30
|
function normalizeName(name) {
|
|
31
|
-
return name.trim().
|
|
31
|
+
return name.trim().toLowerCase().replace(/[^a-zA-Z0-9\-]/g, "-");
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
exports.defaultEksClusterEntityTransformer = defaultEksClusterEntityTransformer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaultTransformers.cjs.js","sources":["../../src/lib/defaultTransformers.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { type Cluster } from '@aws-sdk/client-eks';\nimport {\n ANNOTATION_KUBERNETES_API_SERVER,\n ANNOTATION_KUBERNETES_API_SERVER_CA,\n ANNOTATION_KUBERNETES_AUTH_PROVIDER,\n ANNOTATION_KUBERNETES_AWS_CLUSTER_ID,\n} from '@backstage/plugin-kubernetes-common';\nimport type { EksClusterEntityTransformer } from '../processors/types';\nimport { ANNOTATION_AWS_ACCOUNT_ID, ANNOTATION_AWS_ARN } from '../constants';\n\n/**\n * Default transformer for EKS Cluster to Resource Entity\n * @public\n */\nexport const defaultEksClusterEntityTransformer: EksClusterEntityTransformer =\n async (cluster: Cluster, accountId: string) => {\n const { arn, endpoint, certificateAuthority, name } = cluster;\n const normalizedName = normalizeName(name as string);\n return {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'Resource',\n metadata: {\n annotations: {\n [ANNOTATION_AWS_ACCOUNT_ID]: accountId,\n [ANNOTATION_AWS_ARN]: arn || '',\n [ANNOTATION_KUBERNETES_API_SERVER]: endpoint || '',\n [ANNOTATION_KUBERNETES_API_SERVER_CA]:\n certificateAuthority?.data || '',\n [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'aws',\n [ANNOTATION_KUBERNETES_AWS_CLUSTER_ID]: normalizedName,\n },\n name: normalizedName,\n namespace: 'default',\n },\n spec: {\n type: 'kubernetes-cluster',\n owner: 'unknown',\n },\n };\n };\n\nfunction normalizeName(name: string): string {\n return name\n .trim()\n .
|
|
1
|
+
{"version":3,"file":"defaultTransformers.cjs.js","sources":["../../src/lib/defaultTransformers.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { type Cluster } from '@aws-sdk/client-eks';\nimport {\n ANNOTATION_KUBERNETES_API_SERVER,\n ANNOTATION_KUBERNETES_API_SERVER_CA,\n ANNOTATION_KUBERNETES_AUTH_PROVIDER,\n ANNOTATION_KUBERNETES_AWS_CLUSTER_ID,\n} from '@backstage/plugin-kubernetes-common';\nimport type { EksClusterEntityTransformer } from '../processors/types';\nimport { ANNOTATION_AWS_ACCOUNT_ID, ANNOTATION_AWS_ARN } from '../constants';\n\n/**\n * Default transformer for EKS Cluster to Resource Entity\n * @public\n */\nexport const defaultEksClusterEntityTransformer: EksClusterEntityTransformer =\n async (cluster: Cluster, accountId: string) => {\n const { arn, endpoint, certificateAuthority, name } = cluster;\n const normalizedName = normalizeName(name as string);\n return {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'Resource',\n metadata: {\n annotations: {\n [ANNOTATION_AWS_ACCOUNT_ID]: accountId,\n [ANNOTATION_AWS_ARN]: arn || '',\n [ANNOTATION_KUBERNETES_API_SERVER]: endpoint || '',\n [ANNOTATION_KUBERNETES_API_SERVER_CA]:\n certificateAuthority?.data || '',\n [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'aws',\n [ANNOTATION_KUBERNETES_AWS_CLUSTER_ID]: normalizedName,\n },\n name: normalizedName,\n namespace: 'default',\n },\n spec: {\n type: 'kubernetes-cluster',\n owner: 'unknown',\n },\n };\n };\n\nfunction normalizeName(name: string): string {\n return name\n .trim()\n .toLowerCase()\n .replace(/[^a-zA-Z0-9\\-]/g, '-');\n}\n"],"names":["ANNOTATION_AWS_ACCOUNT_ID","ANNOTATION_AWS_ARN","ANNOTATION_KUBERNETES_API_SERVER","ANNOTATION_KUBERNETES_API_SERVER_CA","ANNOTATION_KUBERNETES_AUTH_PROVIDER","ANNOTATION_KUBERNETES_AWS_CLUSTER_ID"],"mappings":";;;;;AA6BO,MAAM,kCAAA,GACX,OAAO,OAAA,EAAkB,SAAA,KAAsB;AAC7C,EAAA,MAAM,EAAE,GAAA,EAAK,QAAA,EAAU,oBAAA,EAAsB,MAAK,GAAI,OAAA;AACtD,EAAA,MAAM,cAAA,GAAiB,cAAc,IAAc,CAAA;AACnD,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,uBAAA;AAAA,IACZ,IAAA,EAAM,UAAA;AAAA,IACN,QAAA,EAAU;AAAA,MACR,WAAA,EAAa;AAAA,QACX,CAACA,mCAAyB,GAAG,SAAA;AAAA,QAC7B,CAACC,4BAAkB,GAAG,GAAA,IAAO,EAAA;AAAA,QAC7B,CAACC,uDAAgC,GAAG,QAAA,IAAY,EAAA;AAAA,QAChD,CAACC,0DAAmC,GAClC,oBAAA,EAAsB,IAAA,IAAQ,EAAA;AAAA,QAChC,CAACC,0DAAmC,GAAG,KAAA;AAAA,QACvC,CAACC,2DAAoC,GAAG;AAAA,OAC1C;AAAA,MACA,IAAA,EAAM,cAAA;AAAA,MACN,SAAA,EAAW;AAAA,KACb;AAAA,IACA,IAAA,EAAM;AAAA,MACJ,IAAA,EAAM,oBAAA;AAAA,MACN,KAAA,EAAO;AAAA;AACT,GACF;AACF;AAEF,SAAS,cAAc,IAAA,EAAsB;AAC3C,EAAA,OAAO,KACJ,IAAA,EAAK,CACL,aAAY,CACZ,OAAA,CAAQ,mBAAmB,GAAG,CAAA;AACnC;;;;"}
|
|
@@ -65,10 +65,10 @@ class AwsOrganizationCloudAccountProcessor {
|
|
|
65
65
|
return true;
|
|
66
66
|
}
|
|
67
67
|
normalizeName(name) {
|
|
68
|
-
return name.trim().
|
|
68
|
+
return name.trim().toLowerCase().replace(/[^a-zA-Z0-9\-]/g, "-");
|
|
69
69
|
}
|
|
70
70
|
normalizeAccountStatus(name) {
|
|
71
|
-
return name.
|
|
71
|
+
return name.toLowerCase();
|
|
72
72
|
}
|
|
73
73
|
extractInformationFromArn(arn) {
|
|
74
74
|
const parts = arn.split("/");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AwsOrganizationCloudAccountProcessor.cjs.js","sources":["../../src/processors/AwsOrganizationCloudAccountProcessor.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ResourceEntityV1alpha1 } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport {\n CatalogProcessor,\n CatalogProcessorEmit,\n processingResult,\n} from '@backstage/plugin-catalog-node';\nimport { LocationSpec } from '@backstage/plugin-catalog-common';\nimport {\n Account,\n ListAccountsResponse,\n Organizations,\n} from '@aws-sdk/client-organizations';\nimport { readAwsOrganizationConfig } from '../awsOrganization/config';\nimport {\n AwsCredentialProvider,\n DefaultAwsCredentialsManager,\n} from '@backstage/integration-aws-node';\nimport { LoggerService } from '@backstage/backend-plugin-api';\n\nconst AWS_ORGANIZATION_REGION = 'us-east-1';\nconst LOCATION_TYPE = 'aws-cloud-accounts';\n\nconst ACCOUNTID_ANNOTATION = 'amazonaws.com/account-id';\nconst ACCOUNT_EMAIL_ANNOTATION = 'amazonaws.com/account-email';\nconst ARN_ANNOTATION = 'amazonaws.com/arn';\nconst ORGANIZATION_ANNOTATION = 'amazonaws.com/organization-id';\n\nconst ACCOUNT_STATUS_LABEL = 'amazonaws.com/account-status';\n\n/**\n * A processor for ingesting AWS Accounts from AWS Organizations.\n *\n * If custom authentication is needed, it can be achieved by configuring the\n * global AWS.credentials object.\n *\n * @public\n */\nexport class AwsOrganizationCloudAccountProcessor implements CatalogProcessor {\n private readonly organizations: Organizations;\n private readonly logger: LoggerService;\n\n static async fromConfig(config: Config, options: { logger: LoggerService }) {\n const c = config.getOptionalConfig('catalog.processors.awsOrganization');\n const orgConfig = c ? readAwsOrganizationConfig(c) : undefined;\n\n if (orgConfig?.roleArn) {\n options.logger.warn(\n 'The roleArn configuration for AwsOrganizationCloudAccountProcessor ignores the role name, use accountId configuration instead',\n );\n }\n\n const awsCredentialsManager =\n DefaultAwsCredentialsManager.fromConfig(config);\n const credProvider = await awsCredentialsManager.getCredentialProvider({\n arn: orgConfig?.roleArn,\n accountId: orgConfig?.accountId,\n });\n return new AwsOrganizationCloudAccountProcessor(\n credProvider,\n options.logger,\n );\n }\n\n private constructor(\n private readonly credProvider: AwsCredentialProvider,\n logger: LoggerService,\n ) {\n this.logger = logger?.child({\n target: this.getProcessorName(),\n });\n this.organizations = new Organizations({\n credentialDefaultProvider: () => this.credProvider.sdkCredentialProvider,\n region: AWS_ORGANIZATION_REGION,\n }); // Only available in us-east-1\n }\n\n getProcessorName(): string {\n return 'AwsOrganizationCloudAccountProcessor';\n }\n\n async readLocation(\n location: LocationSpec,\n _optional: boolean,\n emit: CatalogProcessorEmit,\n ): Promise<boolean> {\n if (location.type !== LOCATION_TYPE) {\n return false;\n }\n\n this.logger?.info('Discovering AWS Organization Account objects');\n\n (await this.getAwsAccounts())\n .map(account => this.mapAccountToComponent(account))\n .filter(entity => {\n if (location.target !== '') {\n if (entity.metadata.annotations) {\n return (\n entity.metadata.annotations[ORGANIZATION_ANNOTATION] ===\n location.target\n );\n }\n return false;\n }\n return true;\n })\n .forEach(entity => {\n emit(processingResult.entity(location, entity));\n });\n\n return true;\n }\n\n private normalizeName(name: string): string {\n return name\n .trim()\n .toLocaleLowerCase('en-US')\n .replace(/[^a-zA-Z0-9\\-]/g, '-');\n }\n\n private normalizeAccountStatus(name: string): string {\n return name.toLocaleLowerCase('en-US');\n }\n\n private extractInformationFromArn(arn: string): {\n accountId: string;\n organizationId: string;\n } {\n const parts = arn.split('/');\n\n return {\n accountId: parts[parts.length - 1],\n organizationId: parts[parts.length - 2],\n };\n }\n\n private async getAwsAccounts(): Promise<Account[]> {\n let awsAccounts: Account[] = [];\n let isInitialAttempt = true;\n let nextToken = undefined;\n while (isInitialAttempt || nextToken) {\n isInitialAttempt = false;\n const orgAccounts: ListAccountsResponse =\n await this.organizations.listAccounts({ NextToken: nextToken });\n if (orgAccounts.Accounts) {\n awsAccounts = awsAccounts.concat(orgAccounts.Accounts);\n }\n nextToken = orgAccounts.NextToken;\n }\n\n return awsAccounts;\n }\n\n private mapAccountToComponent(account: Account): ResourceEntityV1alpha1 {\n const { accountId, organizationId } = this.extractInformationFromArn(\n account.Arn as string,\n );\n return {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'Resource',\n metadata: {\n annotations: {\n [ACCOUNTID_ANNOTATION]: accountId,\n [ARN_ANNOTATION]: account.Arn || '',\n [ORGANIZATION_ANNOTATION]: organizationId,\n [ACCOUNT_EMAIL_ANNOTATION]: account.Email || '',\n },\n labels: {\n [ACCOUNT_STATUS_LABEL]: this.normalizeAccountStatus(\n account.Status || '',\n ),\n },\n name: this.normalizeName(account.Name || ''),\n title: account.Name || '',\n namespace: 'default',\n },\n spec: {\n type: 'cloud-account',\n owner: 'unknown',\n },\n };\n }\n}\n"],"names":["Organizations","config","readAwsOrganizationConfig","DefaultAwsCredentialsManager","processingResult"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AwsOrganizationCloudAccountProcessor.cjs.js","sources":["../../src/processors/AwsOrganizationCloudAccountProcessor.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ResourceEntityV1alpha1 } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport {\n CatalogProcessor,\n CatalogProcessorEmit,\n processingResult,\n} from '@backstage/plugin-catalog-node';\nimport { LocationSpec } from '@backstage/plugin-catalog-common';\nimport {\n Account,\n ListAccountsResponse,\n Organizations,\n} from '@aws-sdk/client-organizations';\nimport { readAwsOrganizationConfig } from '../awsOrganization/config';\nimport {\n AwsCredentialProvider,\n DefaultAwsCredentialsManager,\n} from '@backstage/integration-aws-node';\nimport { LoggerService } from '@backstage/backend-plugin-api';\n\nconst AWS_ORGANIZATION_REGION = 'us-east-1';\nconst LOCATION_TYPE = 'aws-cloud-accounts';\n\nconst ACCOUNTID_ANNOTATION = 'amazonaws.com/account-id';\nconst ACCOUNT_EMAIL_ANNOTATION = 'amazonaws.com/account-email';\nconst ARN_ANNOTATION = 'amazonaws.com/arn';\nconst ORGANIZATION_ANNOTATION = 'amazonaws.com/organization-id';\n\nconst ACCOUNT_STATUS_LABEL = 'amazonaws.com/account-status';\n\n/**\n * A processor for ingesting AWS Accounts from AWS Organizations.\n *\n * If custom authentication is needed, it can be achieved by configuring the\n * global AWS.credentials object.\n *\n * @public\n */\nexport class AwsOrganizationCloudAccountProcessor implements CatalogProcessor {\n private readonly organizations: Organizations;\n private readonly logger: LoggerService;\n\n static async fromConfig(config: Config, options: { logger: LoggerService }) {\n const c = config.getOptionalConfig('catalog.processors.awsOrganization');\n const orgConfig = c ? readAwsOrganizationConfig(c) : undefined;\n\n if (orgConfig?.roleArn) {\n options.logger.warn(\n 'The roleArn configuration for AwsOrganizationCloudAccountProcessor ignores the role name, use accountId configuration instead',\n );\n }\n\n const awsCredentialsManager =\n DefaultAwsCredentialsManager.fromConfig(config);\n const credProvider = await awsCredentialsManager.getCredentialProvider({\n arn: orgConfig?.roleArn,\n accountId: orgConfig?.accountId,\n });\n return new AwsOrganizationCloudAccountProcessor(\n credProvider,\n options.logger,\n );\n }\n\n private constructor(\n private readonly credProvider: AwsCredentialProvider,\n logger: LoggerService,\n ) {\n this.logger = logger?.child({\n target: this.getProcessorName(),\n });\n this.organizations = new Organizations({\n credentialDefaultProvider: () => this.credProvider.sdkCredentialProvider,\n region: AWS_ORGANIZATION_REGION,\n }); // Only available in us-east-1\n }\n\n getProcessorName(): string {\n return 'AwsOrganizationCloudAccountProcessor';\n }\n\n async readLocation(\n location: LocationSpec,\n _optional: boolean,\n emit: CatalogProcessorEmit,\n ): Promise<boolean> {\n if (location.type !== LOCATION_TYPE) {\n return false;\n }\n\n this.logger?.info('Discovering AWS Organization Account objects');\n\n (await this.getAwsAccounts())\n .map(account => this.mapAccountToComponent(account))\n .filter(entity => {\n if (location.target !== '') {\n if (entity.metadata.annotations) {\n return (\n entity.metadata.annotations[ORGANIZATION_ANNOTATION] ===\n location.target\n );\n }\n return false;\n }\n return true;\n })\n .forEach(entity => {\n emit(processingResult.entity(location, entity));\n });\n\n return true;\n }\n\n private normalizeName(name: string): string {\n return name\n .trim()\n .toLowerCase()\n .replace(/[^a-zA-Z0-9\\-]/g, '-');\n }\n\n private normalizeAccountStatus(name: string): string {\n return name.toLowerCase();\n }\n\n private extractInformationFromArn(arn: string): {\n accountId: string;\n organizationId: string;\n } {\n const parts = arn.split('/');\n\n return {\n accountId: parts[parts.length - 1],\n organizationId: parts[parts.length - 2],\n };\n }\n\n private async getAwsAccounts(): Promise<Account[]> {\n let awsAccounts: Account[] = [];\n let isInitialAttempt = true;\n let nextToken = undefined;\n while (isInitialAttempt || nextToken) {\n isInitialAttempt = false;\n const orgAccounts: ListAccountsResponse =\n await this.organizations.listAccounts({ NextToken: nextToken });\n if (orgAccounts.Accounts) {\n awsAccounts = awsAccounts.concat(orgAccounts.Accounts);\n }\n nextToken = orgAccounts.NextToken;\n }\n\n return awsAccounts;\n }\n\n private mapAccountToComponent(account: Account): ResourceEntityV1alpha1 {\n const { accountId, organizationId } = this.extractInformationFromArn(\n account.Arn as string,\n );\n return {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'Resource',\n metadata: {\n annotations: {\n [ACCOUNTID_ANNOTATION]: accountId,\n [ARN_ANNOTATION]: account.Arn || '',\n [ORGANIZATION_ANNOTATION]: organizationId,\n [ACCOUNT_EMAIL_ANNOTATION]: account.Email || '',\n },\n labels: {\n [ACCOUNT_STATUS_LABEL]: this.normalizeAccountStatus(\n account.Status || '',\n ),\n },\n name: this.normalizeName(account.Name || ''),\n title: account.Name || '',\n namespace: 'default',\n },\n spec: {\n type: 'cloud-account',\n owner: 'unknown',\n },\n };\n }\n}\n"],"names":["Organizations","config","readAwsOrganizationConfig","DefaultAwsCredentialsManager","processingResult"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-catalog-backend-module-aws",
|
|
3
|
-
"version": "0.4.28
|
|
3
|
+
"version": "0.4.28",
|
|
4
4
|
"description": "A Backstage catalog backend module that helps integrate towards AWS",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "backend-plugin-module",
|
|
@@ -70,22 +70,22 @@
|
|
|
70
70
|
"@aws-sdk/client-s3": "^3.350.0",
|
|
71
71
|
"@aws-sdk/middleware-endpoint": "^3.347.0",
|
|
72
72
|
"@aws-sdk/types": "^3.347.0",
|
|
73
|
-
"@backstage/backend-defaults": "0.
|
|
74
|
-
"@backstage/backend-plugin-api": "1.10.1
|
|
75
|
-
"@backstage/catalog-model": "1.10.
|
|
76
|
-
"@backstage/config": "1.3.
|
|
77
|
-
"@backstage/errors": "1.3.1",
|
|
78
|
-
"@backstage/integration": "2.1.2
|
|
79
|
-
"@backstage/integration-aws-node": "0.2.
|
|
80
|
-
"@backstage/plugin-catalog-common": "1.
|
|
81
|
-
"@backstage/plugin-catalog-node": "2.2.5
|
|
82
|
-
"@backstage/plugin-kubernetes-common": "0.9.13
|
|
73
|
+
"@backstage/backend-defaults": "^0.18.0",
|
|
74
|
+
"@backstage/backend-plugin-api": "^1.10.1",
|
|
75
|
+
"@backstage/catalog-model": "^1.10.1",
|
|
76
|
+
"@backstage/config": "^1.3.9",
|
|
77
|
+
"@backstage/errors": "^1.3.1",
|
|
78
|
+
"@backstage/integration": "^2.1.2",
|
|
79
|
+
"@backstage/integration-aws-node": "^0.2.2",
|
|
80
|
+
"@backstage/plugin-catalog-common": "^1.2.0",
|
|
81
|
+
"@backstage/plugin-catalog-node": "^2.2.5",
|
|
82
|
+
"@backstage/plugin-kubernetes-common": "^0.9.13",
|
|
83
83
|
"p-limit": "^3.0.2"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
86
|
"@aws-sdk/util-stream-node": "^3.350.0",
|
|
87
|
-
"@backstage/backend-test-utils": "1.11.7
|
|
88
|
-
"@backstage/cli": "0.36.6
|
|
87
|
+
"@backstage/backend-test-utils": "^1.11.7",
|
|
88
|
+
"@backstage/cli": "^0.36.6",
|
|
89
89
|
"yaml": "^2.0.0"
|
|
90
90
|
},
|
|
91
91
|
"configSchema": "config.schema.json"
|