@backstage/backend-defaults 0.17.4 → 0.17.5-next.1
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 +18 -2
- package/config.schema.json +2396 -0
- package/dist/entrypoints/urlReader/lib/AwsS3UrlReader.cjs.js +45 -26
- package/dist/entrypoints/urlReader/lib/AwsS3UrlReader.cjs.js.map +1 -1
- package/dist/package.json.cjs.js +1 -1
- package/package.json +19 -19
- package/config.d.ts +0 -1475
|
@@ -11,36 +11,14 @@ var node_stream = require('node:stream');
|
|
|
11
11
|
var posix = require('node:path/posix');
|
|
12
12
|
|
|
13
13
|
const DEFAULT_REGION = "us-east-1";
|
|
14
|
+
const STANDARD_AWS_HOST_RE = /^(?:(?<bucket>[a-z0-9.-]+)\.)?s3(?:[.-](?<region>[a-z0-9-]+))?\.amazonaws\.com(?:\.cn)?$/;
|
|
15
|
+
const VPC_ENDPOINT_HOST_RE = /^(?<bucket>[a-z0-9.-]+)\.bucket\.(?<vpceId>vpce-[a-z0-9-]+)\.s3[.-](?<region>[a-z0-9-]+)\.vpce\.amazonaws\.com(?:\.cn)?$/;
|
|
14
16
|
function parseUrl(url, config) {
|
|
15
17
|
const parsedUrl = new URL(url);
|
|
16
18
|
const pathname = parsedUrl.pathname.substring(1);
|
|
17
19
|
const host = parsedUrl.host;
|
|
18
|
-
if (
|
|
19
|
-
|
|
20
|
-
/^(?:([a-z0-9.-]+)\.)?s3(?:[.-]([a-z0-9-]+))?\.amazonaws\.com(\.cn)?$/
|
|
21
|
-
);
|
|
22
|
-
if (!match) {
|
|
23
|
-
throw new Error(`Invalid AWS S3 URL ${url}`);
|
|
24
|
-
}
|
|
25
|
-
const [, hostBucket, hostRegion] = match;
|
|
26
|
-
if (config.s3ForcePathStyle || !hostBucket) {
|
|
27
|
-
const slashIndex = pathname.indexOf("/");
|
|
28
|
-
if (slashIndex < 0) {
|
|
29
|
-
throw new Error(
|
|
30
|
-
`Invalid path-style AWS S3 URL ${url}, does not contain bucket in the path`
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
return {
|
|
34
|
-
path: pathname.substring(slashIndex + 1),
|
|
35
|
-
bucket: pathname.substring(0, slashIndex),
|
|
36
|
-
region: hostRegion ?? DEFAULT_REGION
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
return {
|
|
40
|
-
path: pathname,
|
|
41
|
-
bucket: hostBucket,
|
|
42
|
-
region: hostRegion ?? DEFAULT_REGION
|
|
43
|
-
};
|
|
20
|
+
if (isAmazonHost(config.host)) {
|
|
21
|
+
return parseAmazonUrl(url, host, pathname, config);
|
|
44
22
|
}
|
|
45
23
|
const usePathStyle = config.s3ForcePathStyle || host.length === config.host.length;
|
|
46
24
|
if (usePathStyle) {
|
|
@@ -62,6 +40,47 @@ function parseUrl(url, config) {
|
|
|
62
40
|
region: DEFAULT_REGION
|
|
63
41
|
};
|
|
64
42
|
}
|
|
43
|
+
function isAmazonHost(host) {
|
|
44
|
+
return host === "amazonaws.com" || host === "amazonaws.com.cn" || host.endsWith(".amazonaws.com") || host.endsWith(".amazonaws.com.cn");
|
|
45
|
+
}
|
|
46
|
+
function parseAmazonUrl(url, host, pathname, config) {
|
|
47
|
+
const vpcMatch = host.match(VPC_ENDPOINT_HOST_RE);
|
|
48
|
+
if (vpcMatch?.groups) {
|
|
49
|
+
if (config.s3ForcePathStyle) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`Invalid AWS S3 URL ${url} - path style access is not supported for VPC endpoint URLs`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
path: pathname,
|
|
56
|
+
bucket: vpcMatch.groups.bucket,
|
|
57
|
+
region: vpcMatch.groups.region
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const stdMatch = host.match(STANDARD_AWS_HOST_RE);
|
|
61
|
+
if (!stdMatch?.groups) {
|
|
62
|
+
throw new Error(`Invalid AWS S3 URL ${url}`);
|
|
63
|
+
}
|
|
64
|
+
const { bucket: hostBucket, region: hostRegion } = stdMatch.groups;
|
|
65
|
+
if (config.s3ForcePathStyle || !hostBucket) {
|
|
66
|
+
const slashIndex = pathname.indexOf("/");
|
|
67
|
+
if (slashIndex < 0) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
`Invalid path-style AWS S3 URL ${url}, does not contain bucket in the path`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
path: pathname.substring(slashIndex + 1),
|
|
74
|
+
bucket: pathname.substring(0, slashIndex),
|
|
75
|
+
region: hostRegion ?? DEFAULT_REGION
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
path: pathname,
|
|
80
|
+
bucket: hostBucket,
|
|
81
|
+
region: hostRegion ?? DEFAULT_REGION
|
|
82
|
+
};
|
|
83
|
+
}
|
|
65
84
|
class AwsS3UrlReader {
|
|
66
85
|
static factory = ({ config, treeResponseFactory }) => {
|
|
67
86
|
const integrations = integration.ScmIntegrations.fromConfig(config);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AwsS3UrlReader.cjs.js","sources":["../../../../src/entrypoints/urlReader/lib/AwsS3UrlReader.ts"],"sourcesContent":["/*\n * Copyright 2021 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 {\n UrlReaderService,\n UrlReaderServiceReadTreeOptions,\n UrlReaderServiceReadTreeResponse,\n UrlReaderServiceReadUrlOptions,\n UrlReaderServiceReadUrlResponse,\n UrlReaderServiceSearchOptions,\n UrlReaderServiceSearchResponse,\n} from '@backstage/backend-plugin-api';\nimport { ReaderFactory, ReadTreeResponseFactory } from './types';\nimport {\n AwsCredentialsManager,\n DefaultAwsCredentialsManager,\n} from '@backstage/integration-aws-node';\nimport {\n AwsS3Integration,\n ScmIntegrations,\n AwsS3IntegrationConfig,\n} from '@backstage/integration';\nimport { toError, ForwardedError, NotModifiedError } from '@backstage/errors';\nimport { fromTemporaryCredentials } from '@aws-sdk/credential-providers';\nimport { AwsCredentialIdentityProvider } from '@aws-sdk/types';\nimport {\n S3Client,\n ListObjectsV2Command,\n ListObjectsV2CommandOutput,\n GetObjectCommand,\n GetObjectCommandInput,\n} from '@aws-sdk/client-s3';\nimport { AbortController } from '@aws-sdk/abort-controller';\nimport { ReadUrlResponseFactory } from './ReadUrlResponseFactory';\nimport { Readable } from 'node:stream';\nimport { relative } from 'node:path/posix';\n\nexport const DEFAULT_REGION = 'us-east-1';\n\n/**\n * Path style URLs: https://s3.(region).amazonaws.com/(bucket)/(key)\n * The region can also be on the old form: https://s3-(region).amazonaws.com/(bucket)/(key)\n * Virtual hosted style URLs: https://(bucket).s3.(region).amazonaws.com/(key)\n * See https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#path-style-access\n */\nexport function parseUrl(\n url: string,\n config: AwsS3IntegrationConfig,\n): { path: string; bucket: string; region: string } {\n const parsedUrl = new URL(url);\n\n /**\n * Removes the leading '/' from the pathname to be processed\n * as a parameter by AWS S3 SDK getObject method.\n */\n const pathname = parsedUrl.pathname.substring(1);\n const host = parsedUrl.host;\n\n // Treat Amazon hosted separately because it has special region logic\n if (\n config.host === 'amazonaws.com' ||\n config.host === 'amazonaws.com.cn' ||\n config.host.endsWith('.amazonaws.com') ||\n config.host.endsWith('.amazonaws.com.cn')\n ) {\n const match = host.match(\n /^(?:([a-z0-9.-]+)\\.)?s3(?:[.-]([a-z0-9-]+))?\\.amazonaws\\.com(\\.cn)?$/,\n );\n if (!match) {\n throw new Error(`Invalid AWS S3 URL ${url}`);\n }\n\n const [, hostBucket, hostRegion] = match;\n\n if (config.s3ForcePathStyle || !hostBucket) {\n const slashIndex = pathname.indexOf('/');\n if (slashIndex < 0) {\n throw new Error(\n `Invalid path-style AWS S3 URL ${url}, does not contain bucket in the path`,\n );\n }\n\n return {\n path: pathname.substring(slashIndex + 1),\n bucket: pathname.substring(0, slashIndex),\n region: hostRegion ?? DEFAULT_REGION,\n };\n }\n\n return {\n path: pathname,\n bucket: hostBucket,\n region: hostRegion ?? DEFAULT_REGION,\n };\n }\n\n const usePathStyle =\n config.s3ForcePathStyle || host.length === config.host.length;\n\n if (usePathStyle) {\n const slashIndex = pathname.indexOf('/');\n if (slashIndex < 0) {\n throw new Error(\n `Invalid path-style AWS S3 URL ${url}, does not contain bucket in the path`,\n );\n }\n\n return {\n path: pathname.substring(slashIndex + 1),\n bucket: pathname.substring(0, slashIndex),\n region: DEFAULT_REGION,\n };\n }\n\n return {\n path: pathname,\n bucket: host.substring(0, host.length - config.host.length - 1),\n region: DEFAULT_REGION,\n };\n}\n\n/**\n * Implements a {@link @backstage/backend-plugin-api#UrlReaderService} for AWS S3 buckets.\n *\n * @public\n */\nexport class AwsS3UrlReader implements UrlReaderService {\n static factory: ReaderFactory = ({ config, treeResponseFactory }) => {\n const integrations = ScmIntegrations.fromConfig(config);\n const credsManager = DefaultAwsCredentialsManager.fromConfig(config);\n\n return integrations.awsS3.list().map(integration => {\n const reader = new AwsS3UrlReader(credsManager, integration, {\n treeResponseFactory,\n });\n const predicate = (url: URL) =>\n url.host.endsWith(integration.config.host);\n return { reader, predicate };\n });\n };\n\n private readonly credsManager: AwsCredentialsManager;\n private readonly integration: AwsS3Integration;\n private readonly deps: {\n treeResponseFactory: ReadTreeResponseFactory;\n };\n\n constructor(\n credsManager: AwsCredentialsManager,\n integration: AwsS3Integration,\n deps: {\n treeResponseFactory: ReadTreeResponseFactory;\n },\n ) {\n this.credsManager = credsManager;\n this.integration = integration;\n this.deps = deps;\n }\n\n /**\n * If accessKeyId and secretAccessKey are missing, the standard credentials provider chain will be used:\n * https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html\n */\n private static buildStaticCredentials(\n accessKeyId: string,\n secretAccessKey: string,\n ): AwsCredentialIdentityProvider {\n return async () => {\n return {\n accessKeyId,\n secretAccessKey,\n };\n };\n }\n\n private static async buildCredentials(\n credsManager: AwsCredentialsManager,\n region: string,\n integration?: AwsS3Integration,\n ): Promise<AwsCredentialIdentityProvider> {\n // Fall back to the default credential chain if neither account ID\n // nor explicit credentials are provided\n if (!integration) {\n return (await credsManager.getCredentialProvider()).sdkCredentialProvider;\n }\n\n const accessKeyId = integration.config.accessKeyId;\n const secretAccessKey = integration.config.secretAccessKey;\n let explicitCredentials: AwsCredentialIdentityProvider;\n if (accessKeyId && secretAccessKey) {\n explicitCredentials = AwsS3UrlReader.buildStaticCredentials(\n accessKeyId,\n secretAccessKey,\n );\n } else {\n explicitCredentials = (await credsManager.getCredentialProvider())\n .sdkCredentialProvider;\n }\n\n const roleArn = integration.config.roleArn;\n if (roleArn) {\n return fromTemporaryCredentials({\n masterCredentials: explicitCredentials,\n params: {\n RoleSessionName: 'backstage-aws-s3-url-reader',\n RoleArn: roleArn,\n ExternalId: integration.config.externalId,\n },\n clientConfig: { region },\n });\n }\n\n return explicitCredentials;\n }\n\n private async buildS3Client(\n credsManager: AwsCredentialsManager,\n region: string,\n integration: AwsS3Integration,\n ): Promise<S3Client> {\n const credentials = await AwsS3UrlReader.buildCredentials(\n credsManager,\n region,\n integration,\n );\n\n const s3 = new S3Client({\n customUserAgent: 'backstage-aws-s3-url-reader',\n region: region,\n credentials: credentials,\n endpoint: integration.config.endpoint,\n forcePathStyle: integration.config.s3ForcePathStyle,\n });\n return s3;\n }\n\n private async retrieveS3ObjectData(stream: Readable): Promise<Readable> {\n return new Promise((resolve, reject) => {\n try {\n const chunks: any[] = [];\n stream.on('data', chunk => chunks.push(chunk));\n stream.on('error', (e: Error) =>\n reject(new ForwardedError('Unable to read stream', e)),\n );\n stream.on('end', () => resolve(Readable.from(Buffer.concat(chunks))));\n } catch (e) {\n throw new ForwardedError('Unable to parse the response data', e);\n }\n });\n }\n\n async read(url: string): Promise<Buffer> {\n const response = await this.readUrl(url);\n return response.buffer();\n }\n\n async readUrl(\n url: string,\n options?: UrlReaderServiceReadUrlOptions,\n ): Promise<UrlReaderServiceReadUrlResponse> {\n const { etag, lastModifiedAfter } = options ?? {};\n\n try {\n const { path, bucket, region } = parseUrl(url, this.integration.config);\n const s3Client = await this.buildS3Client(\n this.credsManager,\n region,\n this.integration,\n );\n const abortController = new AbortController();\n\n const params: GetObjectCommandInput = {\n Bucket: bucket,\n Key: path,\n ...(etag && { IfNoneMatch: etag }),\n ...(lastModifiedAfter && {\n IfModifiedSince: lastModifiedAfter,\n }),\n };\n\n options?.signal?.addEventListener('abort', () => abortController.abort());\n const getObjectCommand = new GetObjectCommand(params);\n const response = await s3Client.send(getObjectCommand, {\n abortSignal: abortController.signal,\n });\n\n const s3ObjectData = await this.retrieveS3ObjectData(\n response.Body as Readable,\n );\n\n return ReadUrlResponseFactory.fromReadable(s3ObjectData, {\n etag: response.ETag,\n lastModifiedAt: response.LastModified,\n });\n } catch (e) {\n if (e.$metadata && e.$metadata.httpStatusCode === 304) {\n throw new NotModifiedError();\n }\n\n throw new ForwardedError('Could not retrieve file from S3', e);\n }\n }\n\n async readTree(\n url: string,\n options?: UrlReaderServiceReadTreeOptions,\n ): Promise<UrlReaderServiceReadTreeResponse> {\n try {\n const { path, bucket, region } = parseUrl(url, this.integration.config);\n const s3Client = await this.buildS3Client(\n this.credsManager,\n region,\n this.integration,\n );\n const abortController = new AbortController();\n const allObjects: String[] = [];\n const responses = [];\n let continuationToken: string | undefined;\n let output: ListObjectsV2CommandOutput;\n do {\n const listObjectsV2Command = new ListObjectsV2Command({\n Bucket: bucket,\n ContinuationToken: continuationToken,\n Prefix: path,\n });\n options?.signal?.addEventListener('abort', () =>\n abortController.abort(),\n );\n output = await s3Client.send(listObjectsV2Command, {\n abortSignal: abortController.signal,\n });\n if (output.Contents) {\n output.Contents.forEach(contents => {\n allObjects.push(contents.Key!);\n });\n }\n continuationToken = output.NextContinuationToken;\n } while (continuationToken);\n\n for (let i = 0; i < allObjects.length; i++) {\n const getObjectCommand = new GetObjectCommand({\n Bucket: bucket,\n Key: String(allObjects[i]),\n });\n const response = await s3Client.send(getObjectCommand);\n const s3ObjectData = await this.retrieveS3ObjectData(\n response.Body as Readable,\n );\n\n responses.push({\n data: s3ObjectData,\n path: relative(path, String(allObjects[i])),\n lastModifiedAt: response?.LastModified ?? undefined,\n });\n }\n\n return await this.deps.treeResponseFactory.fromReadableArray(responses);\n } catch (e) {\n throw new ForwardedError('Could not retrieve file tree from S3', e);\n }\n }\n\n async search(\n url: string,\n options?: UrlReaderServiceSearchOptions,\n ): Promise<UrlReaderServiceSearchResponse> {\n const { path } = parseUrl(url, this.integration.config);\n\n if (path.match(/[*?]/)) {\n throw new Error('Unsupported search pattern URL');\n }\n\n try {\n const data = await this.readUrl(url, options);\n\n return {\n files: [\n {\n url: url,\n content: data.buffer,\n lastModifiedAt: data.lastModifiedAt,\n },\n ],\n etag: data.etag ?? '',\n };\n } catch (e) {\n const error = toError(e);\n if (error.name === 'NotFoundError') {\n return {\n files: [],\n etag: '',\n };\n }\n throw error;\n }\n }\n\n toString() {\n const secretAccessKey = this.integration.config.secretAccessKey;\n return `awsS3{host=${this.integration.config.host},authed=${Boolean(\n secretAccessKey,\n )}}`;\n }\n}\n"],"names":["ScmIntegrations","DefaultAwsCredentialsManager","fromTemporaryCredentials","S3Client","ForwardedError","Readable","abortController","AbortController","GetObjectCommand","ReadUrlResponseFactory","NotModifiedError","ListObjectsV2Command","relative","toError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AwsS3UrlReader.cjs.js","sources":["../../../../src/entrypoints/urlReader/lib/AwsS3UrlReader.ts"],"sourcesContent":["/*\n * Copyright 2021 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 {\n UrlReaderService,\n UrlReaderServiceReadTreeOptions,\n UrlReaderServiceReadTreeResponse,\n UrlReaderServiceReadUrlOptions,\n UrlReaderServiceReadUrlResponse,\n UrlReaderServiceSearchOptions,\n UrlReaderServiceSearchResponse,\n} from '@backstage/backend-plugin-api';\nimport { ReaderFactory, ReadTreeResponseFactory } from './types';\nimport {\n AwsCredentialsManager,\n DefaultAwsCredentialsManager,\n} from '@backstage/integration-aws-node';\nimport {\n AwsS3Integration,\n ScmIntegrations,\n AwsS3IntegrationConfig,\n} from '@backstage/integration';\nimport { toError, ForwardedError, NotModifiedError } from '@backstage/errors';\nimport { fromTemporaryCredentials } from '@aws-sdk/credential-providers';\nimport { AwsCredentialIdentityProvider } from '@aws-sdk/types';\nimport {\n S3Client,\n ListObjectsV2Command,\n ListObjectsV2CommandOutput,\n GetObjectCommand,\n GetObjectCommandInput,\n} from '@aws-sdk/client-s3';\nimport { AbortController } from '@aws-sdk/abort-controller';\nimport { ReadUrlResponseFactory } from './ReadUrlResponseFactory';\nimport { Readable } from 'node:stream';\nimport { relative } from 'node:path/posix';\n\nexport const DEFAULT_REGION = 'us-east-1';\n\n/**\n * Standard AWS S3 URLs:\n * Path style: https://s3.(region).amazonaws.com/(bucket)/(key)\n * Path style (old): https://s3-(region).amazonaws.com/(bucket)/(key)\n * Virtual hosted style: https://(bucket).s3.(region).amazonaws.com/(key)\n *\n * AWS PrivateLink (VPC endpoint) S3 URLs:\n * https://(bucket).bucket.(vpce-id).s3.(region).vpce.amazonaws.com/(key)\n *\n * Both forms may have an optional .cn suffix for China regions.\n *\n * See https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html\n * See https://docs.aws.amazon.com/AmazonS3/latest/userguide/privatelink-interface-endpoints.html\n */\n\nconst STANDARD_AWS_HOST_RE =\n /^(?:(?<bucket>[a-z0-9.-]+)\\.)?s3(?:[.-](?<region>[a-z0-9-]+))?\\.amazonaws\\.com(?:\\.cn)?$/;\n\nconst VPC_ENDPOINT_HOST_RE =\n /^(?<bucket>[a-z0-9.-]+)\\.bucket\\.(?<vpceId>vpce-[a-z0-9-]+)\\.s3[.-](?<region>[a-z0-9-]+)\\.vpce\\.amazonaws\\.com(?:\\.cn)?$/;\n\nexport function parseUrl(\n url: string,\n config: AwsS3IntegrationConfig,\n): { path: string; bucket: string; region: string } {\n const parsedUrl = new URL(url);\n const pathname = parsedUrl.pathname.substring(1);\n const host = parsedUrl.host;\n\n if (isAmazonHost(config.host)) {\n return parseAmazonUrl(url, host, pathname, config);\n }\n\n const usePathStyle =\n config.s3ForcePathStyle || host.length === config.host.length;\n\n if (usePathStyle) {\n const slashIndex = pathname.indexOf('/');\n if (slashIndex < 0) {\n throw new Error(\n `Invalid path-style AWS S3 URL ${url}, does not contain bucket in the path`,\n );\n }\n\n return {\n path: pathname.substring(slashIndex + 1),\n bucket: pathname.substring(0, slashIndex),\n region: DEFAULT_REGION,\n };\n }\n\n return {\n path: pathname,\n bucket: host.substring(0, host.length - config.host.length - 1),\n region: DEFAULT_REGION,\n };\n}\n\nfunction isAmazonHost(host: string): boolean {\n return (\n host === 'amazonaws.com' ||\n host === 'amazonaws.com.cn' ||\n host.endsWith('.amazonaws.com') ||\n host.endsWith('.amazonaws.com.cn')\n );\n}\n\nfunction parseAmazonUrl(\n url: string,\n host: string,\n pathname: string,\n config: AwsS3IntegrationConfig,\n): { path: string; bucket: string; region: string } {\n // Try VPC PrivateLink format first (more specific pattern)\n const vpcMatch = host.match(VPC_ENDPOINT_HOST_RE);\n if (vpcMatch?.groups) {\n if (config.s3ForcePathStyle) {\n throw new Error(\n `Invalid AWS S3 URL ${url} - path style access is not supported for VPC endpoint URLs`,\n );\n }\n return {\n path: pathname,\n bucket: vpcMatch.groups.bucket,\n region: vpcMatch.groups.region,\n };\n }\n\n // Try standard AWS S3 format\n const stdMatch = host.match(STANDARD_AWS_HOST_RE);\n if (!stdMatch?.groups) {\n throw new Error(`Invalid AWS S3 URL ${url}`);\n }\n\n const { bucket: hostBucket, region: hostRegion } = stdMatch.groups;\n\n if (config.s3ForcePathStyle || !hostBucket) {\n const slashIndex = pathname.indexOf('/');\n if (slashIndex < 0) {\n throw new Error(\n `Invalid path-style AWS S3 URL ${url}, does not contain bucket in the path`,\n );\n }\n return {\n path: pathname.substring(slashIndex + 1),\n bucket: pathname.substring(0, slashIndex),\n region: hostRegion ?? DEFAULT_REGION,\n };\n }\n\n return {\n path: pathname,\n bucket: hostBucket,\n region: hostRegion ?? DEFAULT_REGION,\n };\n}\n\n/**\n * Implements a {@link @backstage/backend-plugin-api#UrlReaderService} for AWS S3 buckets.\n *\n * @public\n */\nexport class AwsS3UrlReader implements UrlReaderService {\n static factory: ReaderFactory = ({ config, treeResponseFactory }) => {\n const integrations = ScmIntegrations.fromConfig(config);\n const credsManager = DefaultAwsCredentialsManager.fromConfig(config);\n\n return integrations.awsS3.list().map(integration => {\n const reader = new AwsS3UrlReader(credsManager, integration, {\n treeResponseFactory,\n });\n const predicate = (url: URL) =>\n url.host.endsWith(integration.config.host);\n return { reader, predicate };\n });\n };\n\n private readonly credsManager: AwsCredentialsManager;\n private readonly integration: AwsS3Integration;\n private readonly deps: {\n treeResponseFactory: ReadTreeResponseFactory;\n };\n\n constructor(\n credsManager: AwsCredentialsManager,\n integration: AwsS3Integration,\n deps: {\n treeResponseFactory: ReadTreeResponseFactory;\n },\n ) {\n this.credsManager = credsManager;\n this.integration = integration;\n this.deps = deps;\n }\n\n /**\n * If accessKeyId and secretAccessKey are missing, the standard credentials provider chain will be used:\n * https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html\n */\n private static buildStaticCredentials(\n accessKeyId: string,\n secretAccessKey: string,\n ): AwsCredentialIdentityProvider {\n return async () => {\n return {\n accessKeyId,\n secretAccessKey,\n };\n };\n }\n\n private static async buildCredentials(\n credsManager: AwsCredentialsManager,\n region: string,\n integration?: AwsS3Integration,\n ): Promise<AwsCredentialIdentityProvider> {\n // Fall back to the default credential chain if neither account ID\n // nor explicit credentials are provided\n if (!integration) {\n return (await credsManager.getCredentialProvider()).sdkCredentialProvider;\n }\n\n const accessKeyId = integration.config.accessKeyId;\n const secretAccessKey = integration.config.secretAccessKey;\n let explicitCredentials: AwsCredentialIdentityProvider;\n if (accessKeyId && secretAccessKey) {\n explicitCredentials = AwsS3UrlReader.buildStaticCredentials(\n accessKeyId,\n secretAccessKey,\n );\n } else {\n explicitCredentials = (await credsManager.getCredentialProvider())\n .sdkCredentialProvider;\n }\n\n const roleArn = integration.config.roleArn;\n if (roleArn) {\n return fromTemporaryCredentials({\n masterCredentials: explicitCredentials,\n params: {\n RoleSessionName: 'backstage-aws-s3-url-reader',\n RoleArn: roleArn,\n ExternalId: integration.config.externalId,\n },\n clientConfig: { region },\n });\n }\n\n return explicitCredentials;\n }\n\n private async buildS3Client(\n credsManager: AwsCredentialsManager,\n region: string,\n integration: AwsS3Integration,\n ): Promise<S3Client> {\n const credentials = await AwsS3UrlReader.buildCredentials(\n credsManager,\n region,\n integration,\n );\n\n const s3 = new S3Client({\n customUserAgent: 'backstage-aws-s3-url-reader',\n region: region,\n credentials: credentials,\n endpoint: integration.config.endpoint,\n forcePathStyle: integration.config.s3ForcePathStyle,\n });\n return s3;\n }\n\n private async retrieveS3ObjectData(stream: Readable): Promise<Readable> {\n return new Promise((resolve, reject) => {\n try {\n const chunks: any[] = [];\n stream.on('data', chunk => chunks.push(chunk));\n stream.on('error', (e: Error) =>\n reject(new ForwardedError('Unable to read stream', e)),\n );\n stream.on('end', () => resolve(Readable.from(Buffer.concat(chunks))));\n } catch (e) {\n throw new ForwardedError('Unable to parse the response data', e);\n }\n });\n }\n\n async read(url: string): Promise<Buffer> {\n const response = await this.readUrl(url);\n return response.buffer();\n }\n\n async readUrl(\n url: string,\n options?: UrlReaderServiceReadUrlOptions,\n ): Promise<UrlReaderServiceReadUrlResponse> {\n const { etag, lastModifiedAfter } = options ?? {};\n\n try {\n const { path, bucket, region } = parseUrl(url, this.integration.config);\n const s3Client = await this.buildS3Client(\n this.credsManager,\n region,\n this.integration,\n );\n const abortController = new AbortController();\n\n const params: GetObjectCommandInput = {\n Bucket: bucket,\n Key: path,\n ...(etag && { IfNoneMatch: etag }),\n ...(lastModifiedAfter && {\n IfModifiedSince: lastModifiedAfter,\n }),\n };\n\n options?.signal?.addEventListener('abort', () => abortController.abort());\n const getObjectCommand = new GetObjectCommand(params);\n const response = await s3Client.send(getObjectCommand, {\n abortSignal: abortController.signal,\n });\n\n const s3ObjectData = await this.retrieveS3ObjectData(\n response.Body as Readable,\n );\n\n return ReadUrlResponseFactory.fromReadable(s3ObjectData, {\n etag: response.ETag,\n lastModifiedAt: response.LastModified,\n });\n } catch (e) {\n if (e.$metadata && e.$metadata.httpStatusCode === 304) {\n throw new NotModifiedError();\n }\n\n throw new ForwardedError('Could not retrieve file from S3', e);\n }\n }\n\n async readTree(\n url: string,\n options?: UrlReaderServiceReadTreeOptions,\n ): Promise<UrlReaderServiceReadTreeResponse> {\n try {\n const { path, bucket, region } = parseUrl(url, this.integration.config);\n const s3Client = await this.buildS3Client(\n this.credsManager,\n region,\n this.integration,\n );\n const abortController = new AbortController();\n const allObjects: String[] = [];\n const responses = [];\n let continuationToken: string | undefined;\n let output: ListObjectsV2CommandOutput;\n do {\n const listObjectsV2Command = new ListObjectsV2Command({\n Bucket: bucket,\n ContinuationToken: continuationToken,\n Prefix: path,\n });\n options?.signal?.addEventListener('abort', () =>\n abortController.abort(),\n );\n output = await s3Client.send(listObjectsV2Command, {\n abortSignal: abortController.signal,\n });\n if (output.Contents) {\n output.Contents.forEach(contents => {\n allObjects.push(contents.Key!);\n });\n }\n continuationToken = output.NextContinuationToken;\n } while (continuationToken);\n\n for (let i = 0; i < allObjects.length; i++) {\n const getObjectCommand = new GetObjectCommand({\n Bucket: bucket,\n Key: String(allObjects[i]),\n });\n const response = await s3Client.send(getObjectCommand);\n const s3ObjectData = await this.retrieveS3ObjectData(\n response.Body as Readable,\n );\n\n responses.push({\n data: s3ObjectData,\n path: relative(path, String(allObjects[i])),\n lastModifiedAt: response?.LastModified ?? undefined,\n });\n }\n\n return await this.deps.treeResponseFactory.fromReadableArray(responses);\n } catch (e) {\n throw new ForwardedError('Could not retrieve file tree from S3', e);\n }\n }\n\n async search(\n url: string,\n options?: UrlReaderServiceSearchOptions,\n ): Promise<UrlReaderServiceSearchResponse> {\n const { path } = parseUrl(url, this.integration.config);\n\n if (path.match(/[*?]/)) {\n throw new Error('Unsupported search pattern URL');\n }\n\n try {\n const data = await this.readUrl(url, options);\n\n return {\n files: [\n {\n url: url,\n content: data.buffer,\n lastModifiedAt: data.lastModifiedAt,\n },\n ],\n etag: data.etag ?? '',\n };\n } catch (e) {\n const error = toError(e);\n if (error.name === 'NotFoundError') {\n return {\n files: [],\n etag: '',\n };\n }\n throw error;\n }\n }\n\n toString() {\n const secretAccessKey = this.integration.config.secretAccessKey;\n return `awsS3{host=${this.integration.config.host},authed=${Boolean(\n secretAccessKey,\n )}}`;\n }\n}\n"],"names":["ScmIntegrations","DefaultAwsCredentialsManager","fromTemporaryCredentials","S3Client","ForwardedError","Readable","abortController","AbortController","GetObjectCommand","ReadUrlResponseFactory","NotModifiedError","ListObjectsV2Command","relative","toError"],"mappings":"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"}
|
package/dist/package.json.cjs.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/backend-defaults",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.5-next.1",
|
|
4
4
|
"description": "Backend defaults used by Backstage backend apps",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "node-library"
|
|
@@ -196,7 +196,7 @@
|
|
|
196
196
|
}
|
|
197
197
|
},
|
|
198
198
|
"files": [
|
|
199
|
-
"config.
|
|
199
|
+
"config.schema.json",
|
|
200
200
|
"dist",
|
|
201
201
|
"migrations"
|
|
202
202
|
],
|
|
@@ -218,20 +218,20 @@
|
|
|
218
218
|
"@aws-sdk/types": "^3.347.0",
|
|
219
219
|
"@azure/identity": "^4.0.0",
|
|
220
220
|
"@azure/storage-blob": "^12.5.0",
|
|
221
|
-
"@backstage/backend-app-api": "
|
|
222
|
-
"@backstage/backend-dev-utils": "
|
|
223
|
-
"@backstage/backend-plugin-api": "
|
|
224
|
-
"@backstage/cli-node": "
|
|
225
|
-
"@backstage/config": "
|
|
226
|
-
"@backstage/config-loader": "
|
|
227
|
-
"@backstage/errors": "
|
|
228
|
-
"@backstage/integration": "
|
|
229
|
-
"@backstage/integration-aws-node": "
|
|
230
|
-
"@backstage/plugin-auth-node": "
|
|
231
|
-
"@backstage/plugin-events-node": "
|
|
232
|
-
"@backstage/plugin-permission-common": "
|
|
233
|
-
"@backstage/plugin-permission-node": "
|
|
234
|
-
"@backstage/types": "
|
|
221
|
+
"@backstage/backend-app-api": "1.7.2-next.0",
|
|
222
|
+
"@backstage/backend-dev-utils": "0.1.7",
|
|
223
|
+
"@backstage/backend-plugin-api": "1.9.3-next.0",
|
|
224
|
+
"@backstage/cli-node": "0.3.3",
|
|
225
|
+
"@backstage/config": "1.3.8",
|
|
226
|
+
"@backstage/config-loader": "1.11.0-next.1",
|
|
227
|
+
"@backstage/errors": "1.3.1",
|
|
228
|
+
"@backstage/integration": "2.0.3",
|
|
229
|
+
"@backstage/integration-aws-node": "0.2.0",
|
|
230
|
+
"@backstage/plugin-auth-node": "0.7.3-next.0",
|
|
231
|
+
"@backstage/plugin-events-node": "0.4.24-next.0",
|
|
232
|
+
"@backstage/plugin-permission-common": "0.9.9",
|
|
233
|
+
"@backstage/plugin-permission-node": "0.11.2-next.0",
|
|
234
|
+
"@backstage/types": "1.2.2",
|
|
235
235
|
"@google-cloud/storage": "^7.0.0",
|
|
236
236
|
"@keyv/memcache": "^2.0.1",
|
|
237
237
|
"@keyv/redis": "^4.0.1",
|
|
@@ -286,8 +286,8 @@
|
|
|
286
286
|
},
|
|
287
287
|
"devDependencies": {
|
|
288
288
|
"@aws-sdk/util-stream-node": "^3.350.0",
|
|
289
|
-
"@backstage/backend-test-utils": "
|
|
290
|
-
"@backstage/cli": "
|
|
289
|
+
"@backstage/backend-test-utils": "1.11.5-next.0",
|
|
290
|
+
"@backstage/cli": "0.36.4-next.1",
|
|
291
291
|
"@google-cloud/cloud-sql-connector": "^1.4.0",
|
|
292
292
|
"@types/archiver": "^7.0.0",
|
|
293
293
|
"@types/base64-stream": "^1.0.2",
|
|
@@ -319,5 +319,5 @@
|
|
|
319
319
|
"optional": true
|
|
320
320
|
}
|
|
321
321
|
},
|
|
322
|
-
"configSchema": "config.
|
|
322
|
+
"configSchema": "config.schema.json"
|
|
323
323
|
}
|