@backstage/integration-aws-node
Advanced tools
Comparing version 0.1.12 to 0.1.13-next.0
# @backstage/integration-aws-node | ||
## 0.1.13-next.0 | ||
### Patch Changes | ||
- 52ae92d: The `getDefaultCredentialsChain` function now accepts and applies a `region` parameter, preventing it from defaulting to `us-east-1` when no region is specified. | ||
- Updated dependencies | ||
- @backstage/config@1.2.0 | ||
- @backstage/errors@1.2.4 | ||
## 0.1.12 | ||
@@ -4,0 +13,0 @@ |
'use strict'; | ||
var clientSts = require('@aws-sdk/client-sts'); | ||
var credentialProviders = require('@aws-sdk/credential-providers'); | ||
var utilArnParser = require('@aws-sdk/util-arn-parser'); | ||
var DefaultAwsCredentialsManager = require('./DefaultAwsCredentialsManager.cjs.js'); | ||
function readAwsIntegrationAccountConfig(config) { | ||
var _a; | ||
const accountConfig = { | ||
accountId: config.getString("accountId"), | ||
accessKeyId: config.getOptionalString("accessKeyId"), | ||
secretAccessKey: (_a = config.getOptionalString("secretAccessKey")) == null ? void 0 : _a.trim(), | ||
profile: config.getOptionalString("profile"), | ||
roleName: config.getOptionalString("roleName"), | ||
region: config.getOptionalString("region"), | ||
partition: config.getOptionalString("partition"), | ||
externalId: config.getOptionalString("externalId") | ||
}; | ||
if (accountConfig.accessKeyId && !accountConfig.secretAccessKey) { | ||
throw new Error( | ||
`AWS integration account ${accountConfig.accountId} has an access key ID configured, but no secret access key.` | ||
); | ||
} | ||
if (!accountConfig.accessKeyId && accountConfig.secretAccessKey) { | ||
throw new Error( | ||
`AWS integration account ${accountConfig.accountId} has a secret access key configured, but no access key ID` | ||
); | ||
} | ||
if (accountConfig.profile && accountConfig.accessKeyId) { | ||
throw new Error( | ||
`AWS integration account ${accountConfig.accountId} has both an access key ID and a profile configured, but only one must be specified` | ||
); | ||
} | ||
if (accountConfig.profile && accountConfig.roleName) { | ||
throw new Error( | ||
`AWS integration account ${accountConfig.accountId} has both an access key ID and a role name configured, but only one must be specified` | ||
); | ||
} | ||
if (!accountConfig.roleName && accountConfig.externalId) { | ||
throw new Error( | ||
`AWS integration account ${accountConfig.accountId} has an external ID configured, but no role name.` | ||
); | ||
} | ||
if (!accountConfig.roleName && accountConfig.region) { | ||
throw new Error( | ||
`AWS integration account ${accountConfig.accountId} has an STS region configured, but no role name.` | ||
); | ||
} | ||
if (!accountConfig.roleName && accountConfig.partition) { | ||
throw new Error( | ||
`AWS integration account ${accountConfig.accountId} has an IAM partition configured, but no role name.` | ||
); | ||
} | ||
return accountConfig; | ||
} | ||
function readMainAwsIntegrationAccountConfig(config) { | ||
var _a; | ||
const mainAccountConfig = { | ||
accessKeyId: config.getOptionalString("accessKeyId"), | ||
secretAccessKey: (_a = config.getOptionalString("secretAccessKey")) == null ? void 0 : _a.trim(), | ||
profile: config.getOptionalString("profile"), | ||
region: config.getOptionalString("region") | ||
}; | ||
if (mainAccountConfig.accessKeyId && !mainAccountConfig.secretAccessKey) { | ||
throw new Error( | ||
`The main AWS integration account has an access key ID configured, but no secret access key.` | ||
); | ||
} | ||
if (!mainAccountConfig.accessKeyId && mainAccountConfig.secretAccessKey) { | ||
throw new Error( | ||
`The main AWS integration account has a secret access key configured, but no access key ID` | ||
); | ||
} | ||
if (mainAccountConfig.profile && mainAccountConfig.accessKeyId) { | ||
throw new Error( | ||
`The main AWS integration account has both an access key ID and a profile configured, but only one must be specified` | ||
); | ||
} | ||
return mainAccountConfig; | ||
} | ||
function readAwsIntegrationAccountDefaultsConfig(config) { | ||
const defaultAccountConfig = { | ||
roleName: config.getOptionalString("roleName"), | ||
partition: config.getOptionalString("partition"), | ||
region: config.getOptionalString("region"), | ||
externalId: config.getOptionalString("externalId") | ||
}; | ||
if (!defaultAccountConfig.roleName && defaultAccountConfig.externalId) { | ||
throw new Error( | ||
`AWS integration account default configuration has an external ID configured, but no role name.` | ||
); | ||
} | ||
if (!defaultAccountConfig.roleName && defaultAccountConfig.region) { | ||
throw new Error( | ||
`AWS integration account default configuration has an STS region configured, but no role name.` | ||
); | ||
} | ||
if (!defaultAccountConfig.roleName && defaultAccountConfig.partition) { | ||
throw new Error( | ||
`AWS integration account default configuration has an IAM partition configured, but no role name.` | ||
); | ||
} | ||
return defaultAccountConfig; | ||
} | ||
function readAwsIntegrationConfig(config) { | ||
var _a; | ||
const accounts = (_a = config.getOptionalConfigArray("accounts")) == null ? void 0 : _a.map(readAwsIntegrationAccountConfig); | ||
const mainAccount = config.has("mainAccount") ? readMainAwsIntegrationAccountConfig(config.getConfig("mainAccount")) : {}; | ||
const accountDefaults = config.has("accountDefaults") ? readAwsIntegrationAccountDefaultsConfig( | ||
config.getConfig("accountDefaults") | ||
) : {}; | ||
return { | ||
accounts: accounts != null ? accounts : [], | ||
mainAccount, | ||
accountDefaults | ||
}; | ||
} | ||
async function fillInAccountId(credProvider) { | ||
if (credProvider.accountId) { | ||
return; | ||
} | ||
const client = new clientSts.STSClient({ | ||
region: credProvider.stsRegion, | ||
customUserAgent: "backstage-aws-credentials-manager", | ||
credentialDefaultProvider: () => credProvider.sdkCredentialProvider | ||
}); | ||
const resp = await client.send(new clientSts.GetCallerIdentityCommand({})); | ||
credProvider.accountId = resp.Account; | ||
} | ||
function getStaticCredentials(accessKeyId, secretAccessKey) { | ||
return async () => { | ||
return Promise.resolve({ | ||
accessKeyId, | ||
secretAccessKey | ||
}); | ||
}; | ||
} | ||
function getProfileCredentials(profile, region) { | ||
return credentialProviders.fromIni({ | ||
profile, | ||
clientConfig: { | ||
region, | ||
customUserAgent: "backstage-aws-credentials-manager" | ||
} | ||
}); | ||
} | ||
function getDefaultCredentialsChain() { | ||
return credentialProviders.fromNodeProviderChain(); | ||
} | ||
function getSdkCredentialProvider(config, mainAccountCredProvider) { | ||
var _a, _b; | ||
if (config.roleName) { | ||
const region = (_a = config.region) != null ? _a : "us-east-1"; | ||
const partition = (_b = config.partition) != null ? _b : "aws"; | ||
return credentialProviders.fromTemporaryCredentials({ | ||
masterCredentials: config.accessKeyId ? getStaticCredentials(config.accessKeyId, config.secretAccessKey) : mainAccountCredProvider, | ||
params: { | ||
RoleArn: `arn:${partition}:iam::${config.accountId}:role/${config.roleName}`, | ||
RoleSessionName: "backstage", | ||
ExternalId: config.externalId | ||
}, | ||
clientConfig: { | ||
region, | ||
customUserAgent: "backstage-aws-credentials-manager" | ||
} | ||
}); | ||
} | ||
if (config.accessKeyId) { | ||
return getStaticCredentials(config.accessKeyId, config.secretAccessKey); | ||
} | ||
if (config.profile) { | ||
return getProfileCredentials(config.profile, config.region); | ||
} | ||
return getDefaultCredentialsChain(); | ||
} | ||
function getMainAccountSdkCredentialProvider(config) { | ||
if (config.accessKeyId) { | ||
return getStaticCredentials(config.accessKeyId, config.secretAccessKey); | ||
} | ||
if (config.profile) { | ||
return getProfileCredentials(config.profile, config.region); | ||
} | ||
return getDefaultCredentialsChain(); | ||
} | ||
class DefaultAwsCredentialsManager { | ||
constructor(accountCredentialProviders, accountDefaults, mainAccountCredentialProvider) { | ||
this.accountCredentialProviders = accountCredentialProviders; | ||
this.accountDefaults = accountDefaults; | ||
this.mainAccountCredentialProvider = mainAccountCredentialProvider; | ||
} | ||
static fromConfig(config) { | ||
const awsConfig = config.has("aws") ? readAwsIntegrationConfig(config.getConfig("aws")) : { | ||
accounts: [], | ||
mainAccount: {}, | ||
accountDefaults: {} | ||
}; | ||
const mainAccountSdkCredProvider = getMainAccountSdkCredentialProvider( | ||
awsConfig.mainAccount | ||
); | ||
const mainAccountCredProvider = { | ||
sdkCredentialProvider: mainAccountSdkCredProvider | ||
}; | ||
const accountCredProviders = /* @__PURE__ */ new Map(); | ||
for (const accountConfig of awsConfig.accounts) { | ||
const sdkCredentialProvider = getSdkCredentialProvider( | ||
accountConfig, | ||
mainAccountSdkCredProvider | ||
); | ||
accountCredProviders.set(accountConfig.accountId, { | ||
accountId: accountConfig.accountId, | ||
stsRegion: accountConfig.region, | ||
sdkCredentialProvider | ||
}); | ||
} | ||
return new DefaultAwsCredentialsManager( | ||
accountCredProviders, | ||
awsConfig.accountDefaults, | ||
mainAccountCredProvider | ||
); | ||
} | ||
/** | ||
* Returns an {@link AwsCredentialProvider} for a given AWS account. | ||
* | ||
* @example | ||
* ```ts | ||
* const { provider } = await getCredentialProvider({ | ||
* accountId: '0123456789012', | ||
* }) | ||
* | ||
* const { provider } = await getCredentialProvider({ | ||
* arn: 'arn:aws:ecs:us-west-2:123456789012:service/my-http-service' | ||
* }) | ||
* ``` | ||
* | ||
* @param opts - the AWS account ID or AWS resource ARN | ||
* @returns A promise of {@link AwsCredentialProvider}. | ||
*/ | ||
async getCredentialProvider(opts) { | ||
if (!opts) { | ||
return this.mainAccountCredentialProvider; | ||
} | ||
let accountId = opts.accountId; | ||
if (opts.arn && !accountId) { | ||
const arnComponents = utilArnParser.parse(opts.arn); | ||
accountId = arnComponents.accountId; | ||
} | ||
if (!accountId) { | ||
return this.mainAccountCredentialProvider; | ||
} | ||
if (this.accountCredentialProviders.has(accountId)) { | ||
return this.accountCredentialProviders.get(accountId); | ||
} | ||
if (this.accountDefaults.roleName) { | ||
const config = { | ||
accountId, | ||
roleName: this.accountDefaults.roleName, | ||
partition: this.accountDefaults.partition, | ||
region: this.accountDefaults.region, | ||
externalId: this.accountDefaults.externalId | ||
}; | ||
const sdkCredentialProvider = getSdkCredentialProvider( | ||
config, | ||
this.mainAccountCredentialProvider.sdkCredentialProvider | ||
); | ||
const credProvider = { | ||
accountId, | ||
sdkCredentialProvider | ||
}; | ||
this.accountCredentialProviders.set(accountId, credProvider); | ||
return credProvider; | ||
} | ||
await fillInAccountId(this.mainAccountCredentialProvider); | ||
if (accountId === this.mainAccountCredentialProvider.accountId) { | ||
return this.mainAccountCredentialProvider; | ||
} | ||
throw new Error( | ||
`There is no AWS integration that matches ${accountId}. Please add a configuration for this AWS account.` | ||
); | ||
} | ||
} | ||
exports.DefaultAwsCredentialsManager = DefaultAwsCredentialsManager; | ||
exports.DefaultAwsCredentialsManager = DefaultAwsCredentialsManager.DefaultAwsCredentialsManager; | ||
//# sourceMappingURL=index.cjs.js.map |
{ | ||
"name": "@backstage/integration-aws-node", | ||
"version": "0.1.12", | ||
"version": "0.1.13-next.0", | ||
"description": "Helpers for fetching AWS account credentials", | ||
@@ -44,9 +44,9 @@ "backstage": { | ||
"@aws-sdk/util-arn-parser": "^3.310.0", | ||
"@backstage/config": "^1.2.0", | ||
"@backstage/errors": "^1.2.4" | ||
"@backstage/config": "1.2.0", | ||
"@backstage/errors": "1.2.4" | ||
}, | ||
"devDependencies": { | ||
"@backstage/cli": "^0.26.2", | ||
"@backstage/config-loader": "^1.7.0", | ||
"@backstage/test-utils": "^1.5.3", | ||
"@backstage/cli": "0.29.0-next.3", | ||
"@backstage/config-loader": "1.9.2-next.0", | ||
"@backstage/test-utils": "1.7.1-next.0", | ||
"aws-sdk-client-mock": "^4.0.0", | ||
@@ -56,3 +56,10 @@ "aws-sdk-client-mock-jest": "^4.0.0" | ||
"configSchema": "config.d.ts", | ||
"typesVersions": { | ||
"*": { | ||
"index": [ | ||
"dist/index.d.ts" | ||
] | ||
} | ||
}, | ||
"module": "dist/index.esm.js" | ||
} |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 2 instances in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
55215
11
470
2
1
+ Added@backstage/config@1.2.0(transitive)
+ Added@backstage/errors@1.2.4(transitive)
- Removed@backstage/config@1.3.2(transitive)
- Removed@backstage/errors@1.2.7(transitive)
- Removedms@2.1.3(transitive)
Updated@backstage/config@1.2.0
Updated@backstage/errors@1.2.4