@kensio/yulin 1.20.14 → 1.20.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{dist/config/oxlint/cffjs2.oxlintrc.json → cffjs2.oxlintrc.json} +1 -1
- package/dist/config/oxlint/cffjs2.oxlint.config.js +4 -3
- package/dist/service/cloudformation/resource/resolve/property/sim-cfn-resource-property-resolver.d.ts +11 -4
- package/dist/service/cloudformation/resource/resolve/property/sim-cfn-resource-property-resolver.js +21 -8
- package/dist/service/cloudformation/resource/sim-cfn-resource.type.d.ts +9 -0
- package/dist/service/cloudformation/template/dynamic/make-sim-cfn-dynamic-references.d.ts +2 -0
- package/dist/service/cloudformation/template/dynamic/make-sim-cfn-dynamic-references.js +2 -2
- package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-reference-resolvers.d.ts +10 -0
- package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-reference-resolvers.js +4 -3
- package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-reference-scan.d.ts +11 -0
- package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-reference-scan.js +21 -0
- package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-references.d.ts +24 -2
- package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-references.js +50 -11
- package/dist/service/cloudformation/template/dynamic/sim-cfn-prefetched-dynamic-references.d.ts +42 -0
- package/dist/service/cloudformation/template/dynamic/sim-cfn-prefetched-dynamic-references.js +80 -0
- package/dist/service/eventbridge/delivery/sim-event-bridge-delivery-failures.d.ts +16 -0
- package/dist/service/eventbridge/delivery/sim-event-bridge-delivery-failures.js +19 -0
- package/dist/service/iam/command/policy/create-policy/create-policy-input-resolver.js +4 -1
- package/dist/service/iam/command/policy/put-role-policy/put-role-policy.handler.js +5 -1
- package/dist/service/iam/command/policy/put-user-policy/put-user-policy.handler.js +5 -1
- package/dist/service/iam/policy/parse/sim-iam-document-parser.d.ts +4 -1
- package/dist/service/iam/policy/parse/sim-iam-document-parser.js +13 -15
- package/dist/service/iam/policy/sim-iam-statement-label.d.ts +28 -0
- package/dist/service/iam/policy/sim-iam-statement-label.js +17 -0
- package/dist/service/iam/policy/sim-iam-statement-strings.d.ts +11 -0
- package/dist/service/iam/policy/sim-iam-statement-strings.js +27 -0
- package/dist/service/iam/validate/sim-iam-policy-document-validator.d.ts +9 -2
- package/dist/service/iam/validate/sim-iam-policy-document-validator.js +37 -19
- package/dist/service/lambda/function/code/sim-lambda-vm-zip-function.factory.d.ts +7 -0
- package/dist/service/lambda/function/code/sim-lambda-vm-zip-function.factory.js +1 -0
- package/dist/service/lambda/function/code/vm/sdk/sim-lambda-provided-sdk-module.d.ts +19 -0
- package/dist/service/lambda/function/code/vm/sdk/sim-lambda-provided-sdk-module.js +78 -0
- package/dist/service/lambda/function/code/vm/sdk/sim-lambda-sdk-packages-not-installed.error.d.ts +15 -0
- package/dist/service/lambda/function/code/vm/sdk/sim-lambda-sdk-packages-not-installed.error.js +27 -0
- package/dist/service/lambda/function/code/vm/sdk/sim-lambda-vm-sdk-module-provider.d.ts +9 -0
- package/dist/service/lambda/function/code/vm/sdk/sim-sdk-lambda-vm-module-provider.d.ts +10 -0
- package/dist/service/lambda/function/code/vm/sdk/sim-sdk-lambda-vm-module-provider.js +28 -34
- package/dist/service/lambda/function/code/vm/sim-lambda-host-modules.d.ts +15 -0
- package/dist/service/lambda/function/code/vm/sim-lambda-host-modules.js +31 -0
- package/dist/service/lambda/function/code/vm/sim-lambda-vm-module-resolver.d.ts +7 -0
- package/dist/service/lambda/function/code/vm/sim-lambda-vm-module-resolver.js +15 -0
- package/dist/service/lambda/function/code/vm/sim-lambda-vm-modules.js +5 -4
- package/dist/service/s3/command/put-bucket-policy/put-bucket-policy.handler.js +4 -1
- package/dist/service/scheduler/delivery/sim-scheduler-delivery-failures.d.ts +16 -0
- package/dist/service/scheduler/delivery/sim-scheduler-delivery-failures.js +19 -0
- package/dist/service/scheduler/index.d.ts +1 -1
- package/dist/service/scheduler/index.js +1 -1
- package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-dynamic-reference-resolver.d.ts +13 -15
- package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-dynamic-reference-resolver.js +22 -43
- package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-reference-stand-in.d.ts +9 -0
- package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-reference-stand-in.js +14 -0
- package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-reference-value.d.ts +12 -0
- package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-reference-value.js +29 -0
- package/dist/service/ssm/cfn/dynamic/sim-cfn-ssm-dynamic-reference-resolver.d.ts +22 -6
- package/dist/service/ssm/cfn/dynamic/sim-cfn-ssm-dynamic-reference-resolver.js +39 -24
- package/dist/service/ssm/cfn/dynamic/sim-cfn-ssm-secure-dynamic-reference-resolver.d.ts +10 -5
- package/dist/service/ssm/cfn/dynamic/sim-cfn-ssm-secure-dynamic-reference-resolver.js +10 -8
- package/dist/service/ssm/sim-ssm.d.ts +10 -2
- package/dist/service/ssm/sim-ssm.js +12 -4
- package/package.json +4 -3
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isBuiltin } from "node:module";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import vm from "node:vm";
|
|
4
|
+
import { requireHostModule } from "./sim-lambda-host-modules.js";
|
|
5
|
+
import { provideSdkModule } from "./sdk/sim-lambda-provided-sdk-module.js";
|
|
4
6
|
import { loadJsonModule } from "./sim-lambda-vm-json-module.js";
|
|
5
7
|
import { SimLambdaVmModuleResolver } from "./sim-lambda-vm-module-resolver.js";
|
|
6
8
|
import { userCodeSyntaxError } from "./sim-lambda-vm-syntax-error.js";
|
|
@@ -9,7 +11,6 @@ import { userCodeSyntaxError } from "./sim-lambda-vm-syntax-error.js";
|
|
|
9
11
|
* bounded like real Lambda bounds its init phase.
|
|
10
12
|
*/
|
|
11
13
|
const moduleEvaluationTimeoutMs = 5000;
|
|
12
|
-
const hostRequire = createRequire(import.meta.url);
|
|
13
14
|
/**
|
|
14
15
|
* A CommonJS module system over a sim Lambda function code zip archive.
|
|
15
16
|
*
|
|
@@ -35,7 +36,7 @@ export class SimLambdaVmModules {
|
|
|
35
36
|
// those too. Anything it declines is the host built-in itself.
|
|
36
37
|
if (isBuiltin(specifier)) {
|
|
37
38
|
return (this.properties.sdkModuleProvider.provideModule(specifier) ??
|
|
38
|
-
|
|
39
|
+
requireHostModule(specifier));
|
|
39
40
|
}
|
|
40
41
|
let filePath;
|
|
41
42
|
try {
|
|
@@ -59,7 +60,7 @@ export class SimLambdaVmModules {
|
|
|
59
60
|
* original archive resolution error is reported.
|
|
60
61
|
*/
|
|
61
62
|
provideModule(specifier, archiveError) {
|
|
62
|
-
const provided = this.properties
|
|
63
|
+
const provided = provideSdkModule(specifier, this.properties);
|
|
63
64
|
if (provided === undefined) {
|
|
64
65
|
throw archiveError;
|
|
65
66
|
}
|
|
@@ -28,7 +28,10 @@ export class PutBucketPolicyCommandHandler {
|
|
|
28
28
|
async handle(command, options) {
|
|
29
29
|
assertDefined(command.input.Bucket, "PutBucketPolicyCommand.input.Bucket");
|
|
30
30
|
assertDefined(command.input.Policy, "PutBucketPolicyCommand.input.Policy");
|
|
31
|
-
this.policyValidator.validateRequired(command.input.Policy
|
|
31
|
+
this.policyValidator.validateRequired(command.input.Policy, {
|
|
32
|
+
attachedTo: "Bucket",
|
|
33
|
+
name: command.input.Bucket,
|
|
34
|
+
});
|
|
32
35
|
const bucketName = command.input.Bucket;
|
|
33
36
|
const bucket = requireSimS3Bucket(this.buckets, bucketName);
|
|
34
37
|
await this.background.sequence();
|
|
@@ -6,6 +6,13 @@ interface SimSchedulerDeliveryFailureProperties {
|
|
|
6
6
|
readonly at: Date;
|
|
7
7
|
readonly error: unknown;
|
|
8
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* A failed invocation as it serialises. Every property the failure holds, plus
|
|
11
|
+
* the message the getter reads off the error.
|
|
12
|
+
*/
|
|
13
|
+
export interface SimSchedulerDeliveryFailureJson extends SimSchedulerDeliveryFailureProperties {
|
|
14
|
+
readonly message: string;
|
|
15
|
+
}
|
|
9
16
|
/**
|
|
10
17
|
* One invocation a schedule could not make.
|
|
11
18
|
*/
|
|
@@ -28,6 +35,15 @@ export declare class SimSchedulerDeliveryFailure {
|
|
|
28
35
|
* What went wrong, as a message.
|
|
29
36
|
*/
|
|
30
37
|
get message(): string;
|
|
38
|
+
/**
|
|
39
|
+
* The failure as JSON.stringify renders it, message included.
|
|
40
|
+
*
|
|
41
|
+
* Serialising a failure is the first thing to reach for when a schedule did
|
|
42
|
+
* not do what a test expected. The message is a getter on the prototype and
|
|
43
|
+
* would be left out. An Error keeps its own message on a non-enumerable
|
|
44
|
+
* property and prints as `{}`.
|
|
45
|
+
*/
|
|
46
|
+
toJSON(): SimSchedulerDeliveryFailureJson;
|
|
31
47
|
}
|
|
32
48
|
/**
|
|
33
49
|
* Every invocation one simulated Scheduler scope could not make.
|
|
@@ -32,6 +32,25 @@ export class SimSchedulerDeliveryFailure {
|
|
|
32
32
|
}
|
|
33
33
|
return String(this.error);
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* The failure as JSON.stringify renders it, message included.
|
|
37
|
+
*
|
|
38
|
+
* Serialising a failure is the first thing to reach for when a schedule did
|
|
39
|
+
* not do what a test expected. The message is a getter on the prototype and
|
|
40
|
+
* would be left out. An Error keeps its own message on a non-enumerable
|
|
41
|
+
* property and prints as `{}`.
|
|
42
|
+
*/
|
|
43
|
+
toJSON() {
|
|
44
|
+
return {
|
|
45
|
+
scheduleName: this.scheduleName,
|
|
46
|
+
scheduleArn: this.scheduleArn,
|
|
47
|
+
targetArn: this.targetArn,
|
|
48
|
+
roleArn: this.roleArn,
|
|
49
|
+
at: this.at,
|
|
50
|
+
message: this.message,
|
|
51
|
+
error: this.error,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
35
54
|
}
|
|
36
55
|
/**
|
|
37
56
|
* Every invocation one simulated Scheduler scope could not make.
|
|
@@ -10,6 +10,6 @@ export { schedulerScheduleDialect } from "./schedule/sim-scheduler-schedule-expr
|
|
|
10
10
|
export { SimSchedulerTarget } from "./target/sim-scheduler-target.js";
|
|
11
11
|
export { simSchedulerTargetServices, SimSchedulerTargetArn, type SimSchedulerTargetService, } from "./target/sim-scheduler-target-arn.js";
|
|
12
12
|
export { simSchedulerServicePrincipal, type SimSchedulerDeliveryTargets, } from "./delivery/sim-scheduler-delivery.js";
|
|
13
|
-
export { SimSchedulerDeliveryFailure } from "./delivery/sim-scheduler-delivery-failures.js";
|
|
13
|
+
export { SimSchedulerDeliveryFailure, type SimSchedulerDeliveryFailureJson, } from "./delivery/sim-scheduler-delivery-failures.js";
|
|
14
14
|
export { SimSchedulerDeliveryNotPermitted, SimSchedulerTargetNotFound, } from "./error/sim-scheduler-delivery.error.js";
|
|
15
15
|
export { SimSchedulerAccessDeniedException, SimSchedulerConflictException, SimSchedulerError, SimSchedulerResourceNotFoundException, SimSchedulerUnsimulatedInputException, SimSchedulerValidationException, } from "./error/sim-scheduler.error.js";
|
|
@@ -9,6 +9,6 @@ export { schedulerScheduleDialect } from "./schedule/sim-scheduler-schedule-expr
|
|
|
9
9
|
export { SimSchedulerTarget } from "./target/sim-scheduler-target.js";
|
|
10
10
|
export { simSchedulerTargetServices, SimSchedulerTargetArn, } from "./target/sim-scheduler-target-arn.js";
|
|
11
11
|
export { simSchedulerServicePrincipal, } from "./delivery/sim-scheduler-delivery.js";
|
|
12
|
-
export { SimSchedulerDeliveryFailure } from "./delivery/sim-scheduler-delivery-failures.js";
|
|
12
|
+
export { SimSchedulerDeliveryFailure, } from "./delivery/sim-scheduler-delivery-failures.js";
|
|
13
13
|
export { SimSchedulerDeliveryNotPermitted, SimSchedulerTargetNotFound, } from "./error/sim-scheduler-delivery.error.js";
|
|
14
14
|
export { SimSchedulerAccessDeniedException, SimSchedulerConflictException, SimSchedulerError, SimSchedulerResourceNotFoundException, SimSchedulerUnsimulatedInputException, SimSchedulerValidationException, } from "./error/sim-scheduler.error.js";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SimAwsCaller } from "../../../aws/caller/sim-aws-caller.js";
|
|
1
2
|
import type { SimAwsAccountRegionScope } from "../../../aws/sim-aws-account-region-scope.js";
|
|
2
3
|
import type { SimCfnDynamicReference, SimCfnDynamicReferenceResolution, SimCfnDynamicReferenceResolver } from "../../../cloudformation/template/dynamic/sim-cfn-dynamic-reference.type.js";
|
|
3
4
|
import type { SimSecretsManager } from "../../sim-secrets-manager.js";
|
|
@@ -6,16 +7,19 @@ interface SimCfnSecretsManagerDynamicReferenceResolverProperties {
|
|
|
6
7
|
readonly secretsManager: SimSecretsManager;
|
|
7
8
|
/** Secrets Manager for another Account and Region, which a full ARN names. */
|
|
8
9
|
readonly secretsManagerIn: (scope: SimAwsAccountRegionScope) => SimSecretsManager;
|
|
10
|
+
/** The principal the deployment runs as, which the secret is read as. */
|
|
11
|
+
readonly caller?: SimAwsCaller | undefined;
|
|
9
12
|
}
|
|
10
13
|
/**
|
|
11
14
|
* Answers `{{resolve:secretsmanager:...}}` references from simulated Secrets
|
|
12
15
|
* Manager.
|
|
13
16
|
*
|
|
14
|
-
* The secret is read as the
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* The secret is read as the principal the deployment names, at the point the
|
|
18
|
+
* Resource holding the reference is created. A deployment naming none reads as
|
|
19
|
+
* the Account root, which is Secrets Manager's own default. Real
|
|
20
|
+
* CloudFormation makes no dependency out of a dynamic reference, so a secret
|
|
21
|
+
* another Resource of the same Stack creates is only there in time if the
|
|
22
|
+
* template says `DependsOn`.
|
|
19
23
|
*
|
|
20
24
|
* Reading goes through the ordinary GetSecretValue command, which decrypts the
|
|
21
25
|
* version through simulated KMS, so the answer comes back as a promise. That
|
|
@@ -29,22 +33,16 @@ interface SimCfnSecretsManagerDynamicReferenceResolverProperties {
|
|
|
29
33
|
export declare class SimCfnSecretsManagerDynamicReferenceResolver implements SimCfnDynamicReferenceResolver {
|
|
30
34
|
private readonly secretsManager;
|
|
31
35
|
private readonly secretsManagerIn;
|
|
36
|
+
private readonly callerOptions;
|
|
32
37
|
constructor(properties: SimCfnSecretsManagerDynamicReferenceResolverProperties);
|
|
33
38
|
/**
|
|
34
39
|
* Resolve one reference to the secret value it names.
|
|
35
40
|
*/
|
|
36
41
|
resolve(reference: SimCfnDynamicReference): Promise<SimCfnDynamicReferenceResolution>;
|
|
37
42
|
/**
|
|
38
|
-
*
|
|
43
|
+
* The Secrets Manager a reference reads from: the Stack's own, or the one a
|
|
44
|
+
* full secret ARN names.
|
|
39
45
|
*/
|
|
40
|
-
private
|
|
41
|
-
/**
|
|
42
|
-
* The value a reference Secrets Manager could not answer resolves to.
|
|
43
|
-
*
|
|
44
|
-
* The shape follows the `ssm` references beside it, and CDK before them,
|
|
45
|
-
* which fills an unresolved context lookup with `dummy-value-for-<name>`. A
|
|
46
|
-
* test reading one back sees where it came from.
|
|
47
|
-
*/
|
|
48
|
-
private standIn;
|
|
46
|
+
private secretsManagerFor;
|
|
49
47
|
}
|
|
50
48
|
export {};
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
+
import { simCfnResourceCallerOptions, } from "../../../cloudformation/resource/caller/sim-cfn-resource-caller-options.js";
|
|
1
2
|
import { SimSecretsManagerError } from "../../error/sim-secrets-manager.error.js";
|
|
2
|
-
import {
|
|
3
|
+
import { simCfnSecretsManagerReferenceStandIn } from "./sim-cfn-secrets-manager-reference-stand-in.js";
|
|
4
|
+
import { simCfnSecretsManagerReferenceValue } from "./sim-cfn-secrets-manager-reference-value.js";
|
|
3
5
|
import { parseSimCfnSecretsManagerReference, SimCfnSecretsManagerReferenceProblem, } from "./sim-cfn-secrets-manager-reference-body.js";
|
|
4
6
|
/**
|
|
5
7
|
* Answers `{{resolve:secretsmanager:...}}` references from simulated Secrets
|
|
6
8
|
* Manager.
|
|
7
9
|
*
|
|
8
|
-
* The secret is read as the
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* The secret is read as the principal the deployment names, at the point the
|
|
11
|
+
* Resource holding the reference is created. A deployment naming none reads as
|
|
12
|
+
* the Account root, which is Secrets Manager's own default. Real
|
|
13
|
+
* CloudFormation makes no dependency out of a dynamic reference, so a secret
|
|
14
|
+
* another Resource of the same Stack creates is only there in time if the
|
|
15
|
+
* template says `DependsOn`.
|
|
13
16
|
*
|
|
14
17
|
* Reading goes through the ordinary GetSecretValue command, which decrypts the
|
|
15
18
|
* version through simulated KMS, so the answer comes back as a promise. That
|
|
@@ -23,9 +26,11 @@ import { parseSimCfnSecretsManagerReference, SimCfnSecretsManagerReferenceProble
|
|
|
23
26
|
export class SimCfnSecretsManagerDynamicReferenceResolver {
|
|
24
27
|
secretsManager;
|
|
25
28
|
secretsManagerIn;
|
|
29
|
+
callerOptions;
|
|
26
30
|
constructor(properties) {
|
|
27
31
|
this.secretsManager = properties.secretsManager;
|
|
28
32
|
this.secretsManagerIn = properties.secretsManagerIn;
|
|
33
|
+
this.callerOptions = simCfnResourceCallerOptions(properties.caller);
|
|
29
34
|
}
|
|
30
35
|
/**
|
|
31
36
|
* Resolve one reference to the secret value it names.
|
|
@@ -35,54 +40,28 @@ export class SimCfnSecretsManagerDynamicReferenceResolver {
|
|
|
35
40
|
try {
|
|
36
41
|
const parsed = parseSimCfnSecretsManagerReference(reference.body);
|
|
37
42
|
secretId = parsed.secretId;
|
|
38
|
-
return {
|
|
43
|
+
return {
|
|
44
|
+
value: await simCfnSecretsManagerReferenceValue(this.secretsManagerFor(parsed.scope), parsed, this.callerOptions),
|
|
45
|
+
};
|
|
39
46
|
}
|
|
40
47
|
catch (error) {
|
|
41
48
|
if (error instanceof SimCfnSecretsManagerReferenceProblem) {
|
|
42
|
-
return
|
|
49
|
+
return simCfnSecretsManagerReferenceStandIn(reference, secretId, error.message);
|
|
43
50
|
}
|
|
44
51
|
/* v8 ignore next 3 -- defensive: only Secrets Manager reaches here */
|
|
45
52
|
if (!(error instanceof SimSecretsManagerError)) {
|
|
46
53
|
throw error;
|
|
47
54
|
}
|
|
48
|
-
return
|
|
55
|
+
return simCfnSecretsManagerReferenceStandIn(reference, secretId, `and simulated Secrets Manager could not read it (${error.message})`);
|
|
49
56
|
}
|
|
50
57
|
}
|
|
51
58
|
/**
|
|
52
|
-
*
|
|
59
|
+
* The Secrets Manager a reference reads from: the Stack's own, or the one a
|
|
60
|
+
* full secret ARN names.
|
|
53
61
|
*/
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
input: {
|
|
59
|
-
SecretId: secretId,
|
|
60
|
-
VersionStage: versionStage,
|
|
61
|
-
VersionId: versionId,
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
const secretString = read.SecretString;
|
|
65
|
-
if (secretString === undefined) {
|
|
66
|
-
throw new SimCfnSecretsManagerReferenceProblem(`and '${secretId}' holds a binary value, which a dynamic reference ` +
|
|
67
|
-
`cannot read`);
|
|
68
|
-
}
|
|
69
|
-
if (jsonKey === undefined) {
|
|
70
|
-
return secretString;
|
|
71
|
-
}
|
|
72
|
-
return simCfnSecretsManagerJsonKeyValue(secretString, secretId, jsonKey);
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* The value a reference Secrets Manager could not answer resolves to.
|
|
76
|
-
*
|
|
77
|
-
* The shape follows the `ssm` references beside it, and CDK before them,
|
|
78
|
-
* which fills an unresolved context lookup with `dummy-value-for-<name>`. A
|
|
79
|
-
* test reading one back sees where it came from.
|
|
80
|
-
*/
|
|
81
|
-
standIn(reference, secretId, reason) {
|
|
82
|
-
return {
|
|
83
|
-
value: `dummy-value-for-${secretId}`,
|
|
84
|
-
reason: `holds ${reference.text}, ${reason}, so the Resource is created ` +
|
|
85
|
-
`with a stand-in value`,
|
|
86
|
-
};
|
|
62
|
+
secretsManagerFor(scope) {
|
|
63
|
+
return scope === undefined
|
|
64
|
+
? this.secretsManager
|
|
65
|
+
: this.secretsManagerIn(scope);
|
|
87
66
|
}
|
|
88
67
|
}
|
package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-reference-stand-in.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SimCfnDynamicReference, SimCfnDynamicReferenceResolution } from "../../../cloudformation/template/dynamic/sim-cfn-dynamic-reference.type.js";
|
|
2
|
+
/**
|
|
3
|
+
* The value a reference Secrets Manager could not answer resolves to.
|
|
4
|
+
*
|
|
5
|
+
* The shape follows the `ssm` references beside it, and CDK before them, which
|
|
6
|
+
* fills an unresolved context lookup with `dummy-value-for-<name>`. A test
|
|
7
|
+
* reading one back sees where it came from.
|
|
8
|
+
*/
|
|
9
|
+
export declare function simCfnSecretsManagerReferenceStandIn(reference: SimCfnDynamicReference, secretId: string, reason: string): SimCfnDynamicReferenceResolution;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The value a reference Secrets Manager could not answer resolves to.
|
|
3
|
+
*
|
|
4
|
+
* The shape follows the `ssm` references beside it, and CDK before them, which
|
|
5
|
+
* fills an unresolved context lookup with `dummy-value-for-<name>`. A test
|
|
6
|
+
* reading one back sees where it came from.
|
|
7
|
+
*/
|
|
8
|
+
export function simCfnSecretsManagerReferenceStandIn(reference, secretId, reason) {
|
|
9
|
+
return {
|
|
10
|
+
value: `dummy-value-for-${secretId}`,
|
|
11
|
+
reason: `holds ${reference.text}, ${reason}, so the Resource is created ` +
|
|
12
|
+
`with a stand-in value`,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SimCfnResourceCallerOptions } from "../../../cloudformation/resource/caller/sim-cfn-resource-caller-options.js";
|
|
2
|
+
import type { SimSecretsManager } from "../../sim-secrets-manager.js";
|
|
3
|
+
import { type SimCfnSecretsManagerReference } from "./sim-cfn-secrets-manager-reference-body.js";
|
|
4
|
+
/**
|
|
5
|
+
* The secret value one parsed reference names.
|
|
6
|
+
*
|
|
7
|
+
* The version the reference selects, or the current one, read through the
|
|
8
|
+
* ordinary GetSecretValue command as the principal the deployment named. That
|
|
9
|
+
* decrypts the version through simulated KMS, which is why reading a secret
|
|
10
|
+
* has to be waited on.
|
|
11
|
+
*/
|
|
12
|
+
export declare function simCfnSecretsManagerReferenceValue(secretsManager: SimSecretsManager, reference: SimCfnSecretsManagerReference, callerOptions: SimCfnResourceCallerOptions): Promise<string>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { simCfnSecretsManagerJsonKeyValue } from "./sim-cfn-secrets-manager-json-key.js";
|
|
2
|
+
import { SimCfnSecretsManagerReferenceProblem, } from "./sim-cfn-secrets-manager-reference-body.js";
|
|
3
|
+
/**
|
|
4
|
+
* The secret value one parsed reference names.
|
|
5
|
+
*
|
|
6
|
+
* The version the reference selects, or the current one, read through the
|
|
7
|
+
* ordinary GetSecretValue command as the principal the deployment named. That
|
|
8
|
+
* decrypts the version through simulated KMS, which is why reading a secret
|
|
9
|
+
* has to be waited on.
|
|
10
|
+
*/
|
|
11
|
+
export async function simCfnSecretsManagerReferenceValue(secretsManager, reference, callerOptions) {
|
|
12
|
+
const { secretId, jsonKey, versionStage, versionId } = reference;
|
|
13
|
+
const read = await secretsManager.getSecretValue({
|
|
14
|
+
input: {
|
|
15
|
+
SecretId: secretId,
|
|
16
|
+
VersionStage: versionStage,
|
|
17
|
+
VersionId: versionId,
|
|
18
|
+
},
|
|
19
|
+
}, callerOptions);
|
|
20
|
+
const secretString = read.SecretString;
|
|
21
|
+
if (secretString === undefined) {
|
|
22
|
+
throw new SimCfnSecretsManagerReferenceProblem(`and '${secretId}' holds a binary value, which a dynamic reference ` +
|
|
23
|
+
`cannot read`);
|
|
24
|
+
}
|
|
25
|
+
if (jsonKey === undefined) {
|
|
26
|
+
return secretString;
|
|
27
|
+
}
|
|
28
|
+
return simCfnSecretsManagerJsonKeyValue(secretString, secretId, jsonKey);
|
|
29
|
+
}
|
|
@@ -1,16 +1,26 @@
|
|
|
1
|
+
import type { SimAwsCaller } from "../../../aws/caller/sim-aws-caller.js";
|
|
1
2
|
import type { SimCfnDynamicReference, SimCfnDynamicReferenceResolution, SimCfnDynamicReferenceResolver } from "../../../cloudformation/template/dynamic/sim-cfn-dynamic-reference.type.js";
|
|
2
3
|
import type { SimSsm } from "../../sim-ssm.js";
|
|
3
4
|
interface SimCfnSsmDynamicReferenceResolverProperties {
|
|
4
5
|
readonly ssm: SimSsm;
|
|
6
|
+
/** The principal the deployment runs as, which the parameter is read as. */
|
|
7
|
+
readonly caller?: SimAwsCaller | undefined;
|
|
5
8
|
}
|
|
6
9
|
/**
|
|
7
10
|
* Answers `{{resolve:ssm:...}}` references from the simulated Parameter Store.
|
|
8
11
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* the
|
|
13
|
-
*
|
|
12
|
+
* The parameter is read the way `GetParameter` reads it, as the principal the
|
|
13
|
+
* deployment names, so a caller that may not read it is denied here and the
|
|
14
|
+
* Resource fails. That is the failure a real deployment hits, where the read
|
|
15
|
+
* runs under the Stack's execution role. A deployment naming no principal
|
|
16
|
+
* reads as the Account root, which is Parameter Store's own default. Reading
|
|
17
|
+
* through the Command means waiting on it, so the answer comes back as a
|
|
18
|
+
* promise for the CloudFormation engine to wait on.
|
|
19
|
+
*
|
|
20
|
+
* A reference is read at the point the Resource holding it is created. Real
|
|
21
|
+
* CloudFormation makes no dependency out of a dynamic reference, so a
|
|
22
|
+
* parameter another Resource of the same Stack creates is only there in time
|
|
23
|
+
* if the template says `DependsOn`.
|
|
14
24
|
*
|
|
15
25
|
* Anything Parameter Store cannot answer becomes a stand-in value carrying a
|
|
16
26
|
* reason. A template naming parameters a test never created still deploys, and
|
|
@@ -18,14 +28,20 @@ interface SimCfnSsmDynamicReferenceResolverProperties {
|
|
|
18
28
|
*/
|
|
19
29
|
export declare class SimCfnSsmDynamicReferenceResolver implements SimCfnDynamicReferenceResolver {
|
|
20
30
|
private readonly ssm;
|
|
31
|
+
private readonly callerOptions;
|
|
21
32
|
constructor(properties: SimCfnSsmDynamicReferenceResolverProperties);
|
|
22
33
|
/**
|
|
23
34
|
* Resolve one reference to the parameter value it names.
|
|
24
35
|
*/
|
|
25
|
-
resolve(reference: SimCfnDynamicReference): SimCfnDynamicReferenceResolution
|
|
36
|
+
resolve(reference: SimCfnDynamicReference): SimCfnDynamicReferenceResolution | Promise<SimCfnDynamicReferenceResolution>;
|
|
26
37
|
/**
|
|
27
38
|
* Read the version the reference selects, or the current one.
|
|
28
39
|
*/
|
|
29
40
|
private parameterValue;
|
|
41
|
+
/**
|
|
42
|
+
* The value the read reports, unless it is a ciphertext this reference has
|
|
43
|
+
* no business handing to a Resource.
|
|
44
|
+
*/
|
|
45
|
+
private readValue;
|
|
30
46
|
}
|
|
31
47
|
export {};
|
|
@@ -1,14 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { assertDefined } from "../../../../util/type-guard/defined.js";
|
|
2
|
+
import { simCfnResourceCallerOptions, } from "../../../cloudformation/resource/caller/sim-cfn-resource-caller-options.js";
|
|
3
|
+
import { SimSsmError } from "../../error/sim-ssm.error.js";
|
|
2
4
|
import { parseSimCfnSsmReferenceBody } from "./sim-cfn-ssm-reference-body.js";
|
|
3
5
|
import { simCfnSsmReferenceStandIn } from "./sim-cfn-ssm-reference-stand-in.js";
|
|
6
|
+
/** The parameter type a plain `ssm` reference leaves to `ssm-secure`. */
|
|
7
|
+
const secureString = "SecureString";
|
|
4
8
|
/**
|
|
5
9
|
* Answers `{{resolve:ssm:...}}` references from the simulated Parameter Store.
|
|
6
10
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* the
|
|
11
|
-
*
|
|
11
|
+
* The parameter is read the way `GetParameter` reads it, as the principal the
|
|
12
|
+
* deployment names, so a caller that may not read it is denied here and the
|
|
13
|
+
* Resource fails. That is the failure a real deployment hits, where the read
|
|
14
|
+
* runs under the Stack's execution role. A deployment naming no principal
|
|
15
|
+
* reads as the Account root, which is Parameter Store's own default. Reading
|
|
16
|
+
* through the Command means waiting on it, so the answer comes back as a
|
|
17
|
+
* promise for the CloudFormation engine to wait on.
|
|
18
|
+
*
|
|
19
|
+
* A reference is read at the point the Resource holding it is created. Real
|
|
20
|
+
* CloudFormation makes no dependency out of a dynamic reference, so a
|
|
21
|
+
* parameter another Resource of the same Stack creates is only there in time
|
|
22
|
+
* if the template says `DependsOn`.
|
|
12
23
|
*
|
|
13
24
|
* Anything Parameter Store cannot answer becomes a stand-in value carrying a
|
|
14
25
|
* reason. A template naming parameters a test never created still deploys, and
|
|
@@ -16,8 +27,10 @@ import { simCfnSsmReferenceStandIn } from "./sim-cfn-ssm-reference-stand-in.js";
|
|
|
16
27
|
*/
|
|
17
28
|
export class SimCfnSsmDynamicReferenceResolver {
|
|
18
29
|
ssm;
|
|
30
|
+
callerOptions;
|
|
19
31
|
constructor(properties) {
|
|
20
32
|
this.ssm = properties.ssm;
|
|
33
|
+
this.callerOptions = simCfnResourceCallerOptions(properties.caller);
|
|
21
34
|
}
|
|
22
35
|
/**
|
|
23
36
|
* Resolve one reference to the parameter value it names.
|
|
@@ -28,33 +41,35 @@ export class SimCfnSsmDynamicReferenceResolver {
|
|
|
28
41
|
return simCfnSsmReferenceStandIn(reference, reference.body, `which is not the parameter name, optionally followed by an integer ` +
|
|
29
42
|
`version, that an ssm dynamic reference takes`);
|
|
30
43
|
}
|
|
31
|
-
|
|
32
|
-
const parameter = this.ssm.findParameter(name);
|
|
33
|
-
if (parameter === undefined) {
|
|
34
|
-
return simCfnSsmReferenceStandIn(reference, name, `and simulated Parameter Store holds no parameter '${name}'`);
|
|
35
|
-
}
|
|
36
|
-
if (parameter.type.value === "SecureString") {
|
|
37
|
-
return simCfnSsmReferenceStandIn(reference, name, `and '${name}' is a SecureString, which real CloudFormation reads ` +
|
|
38
|
-
`through an ssm-secure reference`);
|
|
39
|
-
}
|
|
40
|
-
return this.parameterValue(reference, parameter, name, version);
|
|
44
|
+
return this.parameterValue(reference, parsed.name, parsed.version);
|
|
41
45
|
}
|
|
42
46
|
/**
|
|
43
47
|
* Read the version the reference selects, or the current one.
|
|
44
48
|
*/
|
|
45
|
-
parameterValue(reference,
|
|
46
|
-
|
|
47
|
-
return { value: parameter.currentVersion.value.value };
|
|
48
|
-
}
|
|
49
|
+
async parameterValue(reference, name, version) {
|
|
50
|
+
const selector = version === undefined ? name : `${name}:${version}`;
|
|
49
51
|
try {
|
|
50
|
-
|
|
52
|
+
const read = await this.ssm.getParameter({ input: { Name: selector } }, this.callerOptions);
|
|
53
|
+
assertDefined(read.Parameter, `the parameter read for '${name}'`);
|
|
54
|
+
return this.readValue(reference, name, read.Parameter);
|
|
51
55
|
}
|
|
52
56
|
catch (error) {
|
|
53
|
-
|
|
54
|
-
if (!(error instanceof SimSsmParameterVersionNotFound)) {
|
|
57
|
+
if (!(error instanceof SimSsmError)) {
|
|
55
58
|
throw error;
|
|
56
59
|
}
|
|
57
|
-
return simCfnSsmReferenceStandIn(reference, name, `and
|
|
60
|
+
return simCfnSsmReferenceStandIn(reference, name, `and simulated Parameter Store could not read it (${error.message})`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The value the read reports, unless it is a ciphertext this reference has
|
|
65
|
+
* no business handing to a Resource.
|
|
66
|
+
*/
|
|
67
|
+
readValue(reference, name, parameter) {
|
|
68
|
+
if (parameter.Type === secureString) {
|
|
69
|
+
return simCfnSsmReferenceStandIn(reference, name, `and '${name}' is a SecureString, which real CloudFormation reads ` +
|
|
70
|
+
`through an ssm-secure reference`);
|
|
58
71
|
}
|
|
72
|
+
assertDefined(parameter.Value, `the value read for '${name}'`);
|
|
73
|
+
return { value: parameter.Value };
|
|
59
74
|
}
|
|
60
75
|
}
|
|
@@ -1,18 +1,22 @@
|
|
|
1
|
+
import type { SimAwsCaller } from "../../../aws/caller/sim-aws-caller.js";
|
|
1
2
|
import type { SimCfnDynamicReference, SimCfnDynamicReferenceResolution, SimCfnDynamicReferenceResolver, SimCfnDynamicReferenceSite } from "../../../cloudformation/template/dynamic/sim-cfn-dynamic-reference.type.js";
|
|
2
3
|
import type { SimSsm } from "../../sim-ssm.js";
|
|
3
4
|
interface SimCfnSsmSecureDynamicReferenceResolverProperties {
|
|
4
5
|
readonly ssm: SimSsm;
|
|
6
|
+
/** The principal the deployment runs as, which the parameter is read as. */
|
|
7
|
+
readonly caller?: SimAwsCaller | undefined;
|
|
5
8
|
}
|
|
6
9
|
/**
|
|
7
10
|
* Answers `{{resolve:ssm-secure:...}}` references from the simulated Parameter
|
|
8
11
|
* Store.
|
|
9
12
|
*
|
|
10
13
|
* The parameter is read the way `GetParameter` with `WithDecryption` reads it,
|
|
11
|
-
* as the
|
|
12
|
-
* the simulated KMS key it was written under. A caller the key does
|
|
13
|
-
* is denied here, which is the failure a real deployment hits.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
14
|
+
* as the principal the deployment names, so the value comes back decrypted
|
|
15
|
+
* through the simulated KMS key it was written under. A caller the key does
|
|
16
|
+
* not admit is denied here, which is the failure a real deployment hits. A
|
|
17
|
+
* deployment naming no principal reads as the Account root, which is Parameter
|
|
18
|
+
* Store's own default. Decrypting cannot be done synchronously, so the answer
|
|
19
|
+
* comes back as a promise for the CloudFormation engine to wait on.
|
|
16
20
|
*
|
|
17
21
|
* A reference the template had no business writing fails the Resource, which
|
|
18
22
|
* `sim-cfn-ssm-secure-refusals.ts` holds the rules for. Everything else
|
|
@@ -22,6 +26,7 @@ interface SimCfnSsmSecureDynamicReferenceResolverProperties {
|
|
|
22
26
|
*/
|
|
23
27
|
export declare class SimCfnSsmSecureDynamicReferenceResolver implements SimCfnDynamicReferenceResolver {
|
|
24
28
|
private readonly ssm;
|
|
29
|
+
private readonly callerOptions;
|
|
25
30
|
constructor(properties: SimCfnSsmSecureDynamicReferenceResolverProperties);
|
|
26
31
|
/**
|
|
27
32
|
* Resolve one reference to the decrypted parameter value it names.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { assertDefined } from "../../../../util/type-guard/defined.js";
|
|
2
|
+
import { simCfnResourceCallerOptions, } from "../../../cloudformation/resource/caller/sim-cfn-resource-caller-options.js";
|
|
2
3
|
import { SimSsmError } from "../../error/sim-ssm.error.js";
|
|
3
4
|
import { parseSimCfnSsmReferenceBody } from "./sim-cfn-ssm-reference-body.js";
|
|
4
5
|
import { simCfnSsmReferenceStandIn } from "./sim-cfn-ssm-reference-stand-in.js";
|
|
@@ -8,11 +9,12 @@ import { requireSecureStringParameter, requireSsmSecureReferenceProperty, } from
|
|
|
8
9
|
* Store.
|
|
9
10
|
*
|
|
10
11
|
* The parameter is read the way `GetParameter` with `WithDecryption` reads it,
|
|
11
|
-
* as the
|
|
12
|
-
* the simulated KMS key it was written under. A caller the key does
|
|
13
|
-
* is denied here, which is the failure a real deployment hits.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* as the principal the deployment names, so the value comes back decrypted
|
|
13
|
+
* through the simulated KMS key it was written under. A caller the key does
|
|
14
|
+
* not admit is denied here, which is the failure a real deployment hits. A
|
|
15
|
+
* deployment naming no principal reads as the Account root, which is Parameter
|
|
16
|
+
* Store's own default. Decrypting cannot be done synchronously, so the answer
|
|
17
|
+
* comes back as a promise for the CloudFormation engine to wait on.
|
|
16
18
|
*
|
|
17
19
|
* A reference the template had no business writing fails the Resource, which
|
|
18
20
|
* `sim-cfn-ssm-secure-refusals.ts` holds the rules for. Everything else
|
|
@@ -22,8 +24,10 @@ import { requireSecureStringParameter, requireSsmSecureReferenceProperty, } from
|
|
|
22
24
|
*/
|
|
23
25
|
export class SimCfnSsmSecureDynamicReferenceResolver {
|
|
24
26
|
ssm;
|
|
27
|
+
callerOptions;
|
|
25
28
|
constructor(properties) {
|
|
26
29
|
this.ssm = properties.ssm;
|
|
30
|
+
this.callerOptions = simCfnResourceCallerOptions(properties.caller);
|
|
27
31
|
}
|
|
28
32
|
/**
|
|
29
33
|
* Resolve one reference to the decrypted parameter value it names.
|
|
@@ -47,9 +51,7 @@ export class SimCfnSsmSecureDynamicReferenceResolver {
|
|
|
47
51
|
async decrypted(reference, name, version) {
|
|
48
52
|
const selector = version === undefined ? name : `${name}:${version}`;
|
|
49
53
|
try {
|
|
50
|
-
const read = await this.ssm.getParameter({
|
|
51
|
-
input: { Name: selector, WithDecryption: true },
|
|
52
|
-
});
|
|
54
|
+
const read = await this.ssm.getParameter({ input: { Name: selector, WithDecryption: true } }, this.callerOptions);
|
|
53
55
|
const parameter = read.Parameter;
|
|
54
56
|
assertDefined(parameter, `the parameter read for '${name}'`);
|
|
55
57
|
requireSecureStringParameter(name, parameter);
|
|
@@ -86,12 +86,20 @@ export declare class SimSsm {
|
|
|
86
86
|
cfnResourceFactory(): SimSsmCfnResourceFactory;
|
|
87
87
|
/**
|
|
88
88
|
* Get the resolver for `{{resolve:ssm:...}}` dynamic references.
|
|
89
|
+
*
|
|
90
|
+
* The caller is the principal the deployment holding the reference runs as,
|
|
91
|
+
* which the parameter is read as. Left out where the deployment named none,
|
|
92
|
+
* leaving the read as the Account root.
|
|
89
93
|
*/
|
|
90
|
-
cfnDynamicReferenceResolver(): SimCfnSsmDynamicReferenceResolver;
|
|
94
|
+
cfnDynamicReferenceResolver(caller?: SimAwsCaller): SimCfnSsmDynamicReferenceResolver;
|
|
91
95
|
/**
|
|
92
96
|
* Get the resolver for `{{resolve:ssm-secure:...}}` dynamic references.
|
|
97
|
+
*
|
|
98
|
+
* The caller is the principal the deployment holding the reference runs as,
|
|
99
|
+
* which the parameter is read as. Left out where the deployment named none,
|
|
100
|
+
* leaving the read as the Account root.
|
|
93
101
|
*/
|
|
94
|
-
cfnSecureDynamicReferenceResolver(): SimCfnSsmSecureDynamicReferenceResolver;
|
|
102
|
+
cfnSecureDynamicReferenceResolver(caller?: SimAwsCaller): SimCfnSsmSecureDynamicReferenceResolver;
|
|
95
103
|
/**
|
|
96
104
|
* Get the reader for `AWS::SSM::Parameter::Value<...>` template Parameters.
|
|
97
105
|
*/
|