@kensio/yulin 1.21.7 → 1.21.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -2
- package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-properties.js +2 -0
- package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-property-rules.js +1 -1
- package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping-input.d.ts +2 -0
- package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping-input.js +4 -0
- package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping-refusals.js +0 -5
- package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping.handler.d.ts +2 -0
- package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping.handler.js +2 -0
- package/dist/service/lambda/command/event-source-mapping/sim-lambda-event-source-mapping-commands.d.ts +2 -0
- package/dist/service/lambda/destination/sim-lambda-destination-targets.d.ts +2 -1
- package/dist/service/lambda/event-source/poll/kinesis/sim-lambda-kinesis-shard-poller.d.ts +0 -4
- package/dist/service/lambda/event-source/poll/kinesis/sim-lambda-kinesis-shard-poller.js +10 -15
- package/dist/service/lambda/event-source/poll/sim-lambda-dynamodb-stream-event-source-poller.d.ts +1 -6
- package/dist/service/lambda/event-source/poll/sim-lambda-dynamodb-stream-event-source-poller.js +9 -27
- package/dist/service/lambda/event-source/poll/sim-lambda-dynamodb-stream-polling.d.ts +19 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-dynamodb-stream-polling.js +27 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-event-source-function.d.ts +1 -1
- package/dist/service/lambda/event-source/poll/sim-lambda-event-source-function.js +3 -1
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-age.d.ts +13 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-age.js +27 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-info.d.ts +15 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-info.js +26 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-outcome.d.ts +1 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-outcome.js +7 -1
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-processing.d.ts +17 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-processing.js +12 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-cursor.d.ts +15 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-cursor.js +28 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-expiry.d.ts +19 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-expiry.js +23 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-context.d.ts +3 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-context.js +19 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-destination.d.ts +15 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-destination.js +38 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-record.d.ts +41 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-record.js +17 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-progress-state.d.ts +21 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-progress-state.js +39 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-progress.d.ts +7 -37
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-progress.js +22 -62
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-retry.d.ts +4 -39
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-retry.js +12 -64
- package/dist/service/lambda/event-source/sim-lambda-event-source-mapping.d.ts +10 -3
- package/dist/service/lambda/event-source/sim-lambda-event-source-mapping.js +12 -3
- package/dist/service/lambda/event-source/sim-lambda-stream-destination-config.d.ts +7 -0
- package/dist/service/lambda/event-source/sim-lambda-stream-destination-config.js +38 -0
- package/dist/service/lambda/event-source/stream/kinesis/sim-kinesis-event-source-streams.js +1 -0
- package/dist/service/lambda/event-source/stream/sim-dynamodb-event-source-stream-reader.js +1 -0
- package/dist/service/lambda/event-source/stream/sim-dynamodb-event-source-stream-shard.d.ts +1 -0
- package/dist/service/lambda/event-source/stream/sim-dynamodb-event-source-stream-shard.js +7 -0
- package/dist/service/lambda/event-source/stream/sim-lambda-event-source-streams.d.ts +1 -0
- package/dist/service/lambda/index.d.ts +1 -0
- package/dist/service/lambda/sim-lambda-commands.js +1 -0
- package/dist/service/ses/command/authorize/sim-ses-authorizer.d.ts +9 -0
- package/dist/service/ses/command/authorize/sim-ses-authorizer.js +18 -2
- package/dist/service/ses/command/send/sim-ses-send-email.js +2 -1
- package/docs/README.md +7 -0
- package/docs/ai-skill/README.md +6 -1
- package/docs/sdk/README.md +15 -0
- package/docs/services/acm/README.md +24 -40
- package/docs/services/apigateway/README.md +52 -71
- package/docs/services/apigatewayv2/README.md +55 -74
- package/docs/services/athena/README.md +17 -26
- package/docs/services/backup/README.md +29 -39
- package/docs/services/bedrock/README.md +38 -52
- package/docs/services/cloudformation/README.md +43 -55
- package/docs/services/cloudfront/README.md +69 -95
- package/docs/services/cloudwatch/README.md +40 -54
- package/docs/services/cognito/README.md +30 -45
- package/docs/services/dynamodb/README.md +34 -51
- package/docs/services/ecr/README.md +36 -77
- package/docs/services/ecs/README.md +26 -46
- package/docs/services/elbv2/README.md +19 -29
- package/docs/services/eventbridge/README.md +14 -18
- package/docs/services/firehose/README.md +24 -32
- package/docs/services/glue/README.md +41 -78
- package/docs/services/iam/README.md +13 -15
- package/docs/services/kinesis/README.md +53 -93
- package/docs/services/kms/README.md +22 -32
- package/docs/services/lambda/README.md +112 -85
- package/docs/services/logs/README.md +41 -50
- package/docs/services/organizations/README.md +50 -85
- package/docs/services/personalize/README.md +28 -44
- package/docs/services/rekognition/README.md +26 -38
- package/docs/services/route53/README.md +17 -17
- package/docs/services/s3/README.md +47 -51
- package/docs/services/scheduler/README.md +41 -52
- package/docs/services/secretsmanager/README.md +27 -42
- package/docs/services/ses/README.md +24 -34
- package/docs/services/sns/README.md +18 -26
- package/docs/services/sqs/README.md +14 -14
- package/docs/services/ssm/README.md +13 -17
- package/docs/services/stepfunctions/README.md +18 -20
- package/docs/services/sts/README.md +32 -45
- package/docs/services/wafv2/README.md +12 -17
- package/docs/testing/README.md +228 -0
- package/docs/time/README.md +10 -0
- package/llms.txt +1 -0
- package/package.json +1 -1
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
# Simulated EventBridge Scheduler
|
|
2
2
|
|
|
3
|
-
Yulin
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Yulin simulates Amazon EventBridge Scheduler in memory. Schedules run when simulated time advances,
|
|
4
|
+
and every management operation is authorized by simulated IAM. Import Scheduler-specific types from
|
|
5
|
+
`@kensio/yulin/scheduler`.
|
|
6
6
|
|
|
7
|
-
Scheduler is
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
A project using Scheduler cannot be tested against simulated EventBridge rules. That is why this
|
|
11
|
-
exists separately.
|
|
7
|
+
Scheduler is separate from [EventBridge](https://yulinsim.dev/services/eventbridge/). It uses its own
|
|
8
|
+
SDK client and ARN format. It also assumes an execution role to invoke a target, while EventBridge
|
|
9
|
+
rules use the target's resource policy.
|
|
12
10
|
|
|
13
11
|
## Creating a schedule
|
|
14
12
|
|
|
@@ -56,8 +54,7 @@ IAM policy naming a schedule needs the group in it, or it matches no schedule.
|
|
|
56
54
|
|
|
57
55
|
## Writing the schedule expression
|
|
58
56
|
|
|
59
|
-
|
|
60
|
-
rule](https://yulinsim.dev/services/eventbridge/#rules-that-fire-on-a-schedule) with two differences:
|
|
57
|
+
Scheduler accepts three expression forms:
|
|
61
58
|
|
|
62
59
|
- `at(yyyy-mm-ddThh:mm:ss)` runs once, at that instant. The timezone is a separate setting on the
|
|
63
60
|
schedule, outside the expression, and a trailing `Z` is refused.
|
|
@@ -71,9 +68,7 @@ rule](https://yulinsim.dev/services/eventbridge/#rules-that-fire-on-a-schedule)
|
|
|
71
68
|
|
|
72
69
|
## Firing a schedule
|
|
73
70
|
|
|
74
|
-
A schedule fires on the simulation's clock.
|
|
75
|
-
instant invokes the target. Leave time alone and the target is never invoked. A nightly job takes no
|
|
76
|
-
time at all to test.
|
|
71
|
+
A schedule fires on the simulation's clock. Advance time past a due instant to invoke the target.
|
|
77
72
|
|
|
78
73
|
```typescript sim-scheduler-firing
|
|
79
74
|
/**
|
|
@@ -163,12 +158,11 @@ own to describe.
|
|
|
163
158
|
|
|
164
159
|
### The execution role
|
|
165
160
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
its target, and that role's policies decide. No resource policy on the target is involved at all.
|
|
161
|
+
A schedule assumes the target's `RoleArn`, and that role's policies authorize delivery. An
|
|
162
|
+
[EventBridge rule](https://yulinsim.dev/services/eventbridge/) instead invokes as
|
|
163
|
+
`events.amazonaws.com` and depends on the target's resource policy.
|
|
170
164
|
|
|
171
|
-
|
|
165
|
+
The execution role needs both:
|
|
172
166
|
|
|
173
167
|
- The role's **trust policy** has to let `scheduler.amazonaws.com` assume it. A role copied from an
|
|
174
168
|
EventBridge rule trusts `events.amazonaws.com` and fails here.
|
|
@@ -176,14 +170,13 @@ Two things therefore have to be right, and they are fixed in different places:
|
|
|
176
170
|
`sqs:SendMessage`, `sns:Publish` or `ecs:RunTask`.
|
|
177
171
|
|
|
178
172
|
A trust policy may also carry the condition AWS recommends against the confused deputy problem. The
|
|
179
|
-
schedule's group ARN is supplied as `aws:SourceArn`, and the
|
|
180
|
-
`aws:SourceAccount`. A role scoped to one schedule group is assumable by schedules in that
|
|
181
|
-
|
|
182
|
-
|
|
173
|
+
schedule's group ARN is supplied as `aws:SourceArn`, and the account is supplied as
|
|
174
|
+
`aws:SourceAccount`. A role scoped to one schedule group is assumable only by schedules in that
|
|
175
|
+
group. CDK writes that condition into the execution roles it generates for a schedule target, so a
|
|
176
|
+
role from a synthesized template works unchanged.
|
|
183
177
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
test asserting on a failed invocation reads `deliveryFailures`:
|
|
178
|
+
If either permission is missing, `advanceBy(...)` still returns normally and the target is not
|
|
179
|
+
invoked. Read `deliveryFailures` to assert on the failed delivery:
|
|
187
180
|
|
|
188
181
|
```typescript sim-scheduler-delivery-failures
|
|
189
182
|
/**
|
|
@@ -256,9 +249,8 @@ following delay doubles to 2, 4, 8 seconds and so on. A retry does not run while
|
|
|
256
249
|
still. `advanceBy(...)` runs every retry that becomes due in the interval and settles their work
|
|
257
250
|
before it returns.
|
|
258
251
|
|
|
259
|
-
Scheduler
|
|
260
|
-
|
|
261
|
-
permanent failures. They are abandoned after the initial attempt.
|
|
252
|
+
Scheduler retries only failures that may clear. A missing target, missing execution role, invalid
|
|
253
|
+
trust policy, or IAM denial is permanent and is abandoned after the initial attempt.
|
|
262
254
|
|
|
263
255
|
Set `Target.DeadLetterConfig.Arn` to a standard SQS queue ARN to keep an input that Scheduler abandons.
|
|
264
256
|
The execution role needs `sqs:SendMessage` on this queue as well as permission to invoke the target.
|
|
@@ -267,19 +259,17 @@ shape and include the error, schedule ARN, target ARN, scheduled time and retry
|
|
|
267
259
|
`EXHAUSTED_RETRY_CONDITION` is `MaximumRetryAttempts` or `MaximumEventAgeInSeconds` for an exhausted
|
|
268
260
|
retryable failure. A permanent failure leaves that attribute out.
|
|
269
261
|
|
|
270
|
-
A successful DLQ send
|
|
271
|
-
|
|
272
|
-
a misconfigured DLQ visible to a test.
|
|
262
|
+
A successful DLQ send leaves `deliveryFailures` empty because the configured destination received the
|
|
263
|
+
input. A missing queue or denied `sqs:SendMessage` is recorded there instead.
|
|
273
264
|
|
|
274
265
|
### One-time schedules and what happens after
|
|
275
266
|
|
|
276
|
-
An `at(...)` schedule fires once
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
`GetSchedule` reports it gone.
|
|
267
|
+
An `at(...)` schedule fires once. It remains in the account unless
|
|
268
|
+
`ActionAfterCompletion: "DELETE"` removes it. A retained schedule continues to appear in listings
|
|
269
|
+
and count against the schedule quota.
|
|
280
270
|
|
|
281
|
-
A schedule
|
|
282
|
-
|
|
271
|
+
A disabled schedule remains incomplete when its only instant passes. It stays in the account
|
|
272
|
+
regardless of `ActionAfterCompletion`.
|
|
283
273
|
|
|
284
274
|
`State: "DISABLED"` stops a recurring schedule firing while it is off, and an `UpdateSchedule`
|
|
285
275
|
enabling it picks up from the next due instant. What it missed is never replayed. An update that
|
|
@@ -287,9 +277,8 @@ changes the expression reschedules from the new one.
|
|
|
287
277
|
|
|
288
278
|
## Running an ECS task on a schedule
|
|
289
279
|
|
|
290
|
-
A target whose ARN names an ECS cluster runs a [simulated ECS](https://yulinsim.dev/services/ecs/)
|
|
291
|
-
|
|
292
|
-
its work and stops.
|
|
280
|
+
A target whose ARN names an ECS cluster runs a [simulated ECS](https://yulinsim.dev/services/ecs/)
|
|
281
|
+
task. Use `EcsParameters` to select the task definition and use `Input` for task overrides.
|
|
293
282
|
|
|
294
283
|
```typescript sim-scheduler-ecs-target
|
|
295
284
|
/**
|
|
@@ -404,8 +393,8 @@ target with no `Input` runs the task with no overrides.
|
|
|
404
393
|
|
|
405
394
|
[Simulated ECS](https://yulinsim.dev/services/ecs/) decides which containers actually run. A container
|
|
406
395
|
with a binding runs its handler, and a container without one is recorded as not simulated.
|
|
407
|
-
A target naming a task definition
|
|
408
|
-
|
|
396
|
+
A target naming a task definition without a bound container records a task that never started, and
|
|
397
|
+
the schedule counts as invoked.
|
|
409
398
|
|
|
410
399
|
## Updating and deleting
|
|
411
400
|
|
|
@@ -457,8 +446,8 @@ console.log(described.ScheduleExpression); // "rate(30 minutes)"
|
|
|
457
446
|
console.log(described.Description); // undefined, and not by accident
|
|
458
447
|
```
|
|
459
448
|
|
|
460
|
-
`UpdateSchedule`
|
|
461
|
-
|
|
449
|
+
`UpdateSchedule` replaces the full schedule definition. Any optional value omitted from the update
|
|
450
|
+
is removed. The schedule must already exist.
|
|
462
451
|
Updating one that is absent raises `ResourceNotFoundException`. EventBridge's `PutRule` creates it.
|
|
463
452
|
|
|
464
453
|
`CreateSchedule` for a name that already exists raises `ConflictException`. A deployment running it
|
|
@@ -618,10 +607,10 @@ against the `RoleArn` on the target.
|
|
|
618
607
|
|
|
619
608
|
## Deploying from a CloudFormation template
|
|
620
609
|
|
|
621
|
-
`AWS::Scheduler::Schedule` deploys through [simulated
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
610
|
+
`AWS::Scheduler::Schedule` deploys through [simulated
|
|
611
|
+
CloudFormation](https://yulinsim.dev/services/cloudformation/). Its properties follow
|
|
612
|
+
`CreateSchedule`, and the target ARN or execution role can use `Fn::GetAtt` references to resources
|
|
613
|
+
in the same template.
|
|
625
614
|
|
|
626
615
|
```typescript sim-scheduler-cloudformation
|
|
627
616
|
/**
|
|
@@ -786,7 +775,7 @@ anyway. Read the record back from `stack.getResource("<logicalId>")?.ignoredProp
|
|
|
786
775
|
Tearing the stack down removes the group. Its schedules go with it, whether or not they are
|
|
787
776
|
Resources of the same stack.
|
|
788
777
|
|
|
789
|
-
##
|
|
778
|
+
## Supported operations
|
|
790
779
|
|
|
791
780
|
- `CreateSchedule`, `GetSchedule`, `UpdateSchedule`, `DeleteSchedule` and `ListSchedules`.
|
|
792
781
|
- `at(...)`, `rate(...)` and six-field `cron(...)` expressions, fired by advancing the simulation's
|
|
@@ -839,7 +828,7 @@ Resources of the same stack.
|
|
|
839
828
|
- A target `EventBridgeParameters`, `KinesisParameters`, `SageMakerPipelineParameters` and
|
|
840
829
|
`SqsParameters` are refused outright, as is `EcsParameters` on a target whose ARN names something
|
|
841
830
|
other than an ECS cluster. A `DeadLetterConfig` must name a standard SQS queue because simulated
|
|
842
|
-
SQS
|
|
831
|
+
SQS supports only standard queues.
|
|
843
832
|
- An ECS target's `EcsParameters` takes `TaskDefinitionArn` and `TaskCount`, and takes and ignores
|
|
844
833
|
`LaunchType`, `PlatformVersion`, `NetworkConfiguration` and `CapacityProviderStrategy`, since
|
|
845
834
|
there is no placement and no network here for them to apply to. Anything else it can carry, such
|
|
@@ -849,5 +838,5 @@ Resources of the same stack.
|
|
|
849
838
|
on an ECS target, where every other target type takes any text.
|
|
850
839
|
- A `TaskCount` above one runs that many simulated tasks, and a bound container handler runs once
|
|
851
840
|
for each of them, in this process and one after another.
|
|
852
|
-
- `KmsKeyArn` is refused, and `ClientToken` is accepted and ignored.
|
|
853
|
-
|
|
841
|
+
- `KmsKeyArn` is refused, and `ClientToken` is accepted and ignored. Yulin makes each schedule
|
|
842
|
+
management request once, so the token has no retry to make idempotent.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Simulated Secrets Manager
|
|
2
2
|
|
|
3
|
-
Yulin
|
|
4
|
-
|
|
3
|
+
Yulin simulates AWS Secrets Manager in memory. Secrets have encrypted versions and staging labels,
|
|
4
|
+
and simulated IAM authorizes every operation.
|
|
5
5
|
|
|
6
6
|
Secrets Manager-specific types are imported from the `@kensio/yulin/secretsmanager` subpath.
|
|
7
7
|
|
|
@@ -45,19 +45,14 @@ on read.
|
|
|
45
45
|
|
|
46
46
|
## Encryption and KMS permissions
|
|
47
47
|
|
|
48
|
-
Every version is encrypted through simulated KMS
|
|
49
|
-
|
|
50
|
-
either returns the plaintext or fails.
|
|
48
|
+
Every secret version is encrypted through simulated KMS. `GetSecretValue` decrypts the version and
|
|
49
|
+
either returns its plaintext or fails.
|
|
51
50
|
|
|
52
|
-
A secret
|
|
53
|
-
|
|
54
|
-
the account's principals to use it through Secrets Manager. A Lambda role granted only
|
|
55
|
-
`secretsmanager:GetSecretValue` therefore reads the secret, as it does on real AWS.
|
|
51
|
+
A secret without `KmsKeyId` uses the `aws/secretsmanager` AWS managed key. Its policy permits use
|
|
52
|
+
through Secrets Manager, so callers do not need a separate KMS permission.
|
|
56
53
|
|
|
57
|
-
Pass `KmsKeyId` to
|
|
58
|
-
|
|
59
|
-
version. A write needs `kms:GenerateDataKey` and a read needs `kms:Decrypt`. A role granted the
|
|
60
|
-
secret but not the key fails here, ahead of a deployment.
|
|
54
|
+
Pass `KmsKeyId` to use a customer managed key. Writing a version requires `kms:GenerateDataKey`, and
|
|
55
|
+
reading it requires `kms:Decrypt`, in addition to the relevant Secrets Manager permission.
|
|
61
56
|
|
|
62
57
|
```typescript sim-secrets-manager-customer-key
|
|
63
58
|
/**
|
|
@@ -141,10 +136,9 @@ they were made with and stay readable, as they do on real AWS.
|
|
|
141
136
|
|
|
142
137
|
## Secret ARNs and IAM policies
|
|
143
138
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
`-??????` or a wildcard.
|
|
139
|
+
Secret ARNs end with a hyphen and six random characters. A secret named `db-creds`, for example,
|
|
140
|
+
gets an ARN ending in `:secret:db-creds-AbCdEf`. An IAM resource pattern for the secret must include
|
|
141
|
+
that suffix, such as `-??????` or `-*`.
|
|
148
142
|
|
|
149
143
|
```typescript sim-secrets-manager-iam-policy
|
|
150
144
|
/**
|
|
@@ -214,17 +208,16 @@ nothing, here as there.
|
|
|
214
208
|
|
|
215
209
|
## Naming a secret
|
|
216
210
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
it.
|
|
211
|
+
`SecretId` accepts the friendly name, the full ARN with its random suffix, or the partial ARN without
|
|
212
|
+
the suffix.
|
|
220
213
|
|
|
221
214
|
An ARN naming another account or region resolves to no secret at all. Its name is never read out and
|
|
222
215
|
looked up locally, and a foreign ARN cannot reach a secret that happens to share a name.
|
|
223
216
|
|
|
224
217
|
## Versions and staging labels
|
|
225
218
|
|
|
226
|
-
Every write creates a version
|
|
227
|
-
|
|
219
|
+
Every write creates a version. `AWSCURRENT` marks the version returned by a plain read. Writing a new
|
|
220
|
+
current version moves `AWSPREVIOUS` to the former current version.
|
|
228
221
|
|
|
229
222
|
```typescript sim-secrets-manager-staging-labels
|
|
230
223
|
/**
|
|
@@ -273,12 +266,9 @@ label. A version that has lost every label is on its way out of existence, and i
|
|
|
273
266
|
|
|
274
267
|
## Deletion and the recovery window
|
|
275
268
|
|
|
276
|
-
`DeleteSecret` schedules deletion
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
Holding the name is what a redeployed stack hits. Advancing the simulated clock past the window frees
|
|
281
|
-
it.
|
|
269
|
+
`DeleteSecret` schedules deletion after a recovery window of 7 to 30 days, defaulting to 30. During
|
|
270
|
+
that window the secret can be described or restored, but it cannot be read or changed. Its name also
|
|
271
|
+
remains reserved. Advance simulated time past the window to complete deletion.
|
|
282
272
|
|
|
283
273
|
```typescript sim-secrets-manager-deletion
|
|
284
274
|
/**
|
|
@@ -435,14 +425,14 @@ console.log(credentials.username); // "app"
|
|
|
435
425
|
console.log(credentials.password?.length); // 24
|
|
436
426
|
```
|
|
437
427
|
|
|
438
|
-
Generated passwords are random.
|
|
439
|
-
|
|
428
|
+
Generated passwords are random. Read the deployed value through Secrets Manager instead of asserting
|
|
429
|
+
on an exact password.
|
|
440
430
|
|
|
441
431
|
## Reading a secret with a dynamic reference
|
|
442
432
|
|
|
443
|
-
A
|
|
444
|
-
|
|
445
|
-
|
|
433
|
+
A `{{resolve:secretsmanager:...}}` dynamic reference reads an existing secret while CloudFormation
|
|
434
|
+
creates the resource containing the reference. CDK emits this form for
|
|
435
|
+
`SecretValue.secretsManager`.
|
|
446
436
|
|
|
447
437
|
The whole form is
|
|
448
438
|
`{{resolve:secretsmanager:secret-id:secret-string:json-key:version-stage:version-id}}`. Only the
|
|
@@ -554,11 +544,10 @@ another resource of the same stack creates is only there in time when the templa
|
|
|
554
544
|
Resource properties are reported as they resolved, including this one. Real CloudFormation keeps a
|
|
555
545
|
resolved secret out of its own logs and events, and sim CloudFormation has no such protection.
|
|
556
546
|
|
|
557
|
-
###
|
|
547
|
+
### Unresolved references
|
|
558
548
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
secret a test does not care about is still worth deploying for everything else in it.
|
|
549
|
+
If Yulin cannot resolve a reference, it substitutes `dummy-value-for-<secret-id>` and continues the
|
|
550
|
+
deployment.
|
|
562
551
|
|
|
563
552
|
The substitution is recorded on
|
|
564
553
|
[`stack.ignoredProperties`](https://yulinsim.dev/services/cloudformation/#properties-a-resource-was-created-without),
|
|
@@ -596,9 +585,7 @@ The same applies to `SimSdk` interception. Intercepting `SecretsManagerClient` r
|
|
|
596
585
|
code into the simulation, served in process. See
|
|
597
586
|
[AWS SDK interception](https://yulinsim.dev/sdk/ "Simulated AWS SDK docs").
|
|
598
587
|
|
|
599
|
-
##
|
|
600
|
-
|
|
601
|
-
Sim Secrets Manager currently supports:
|
|
588
|
+
## Supported operations
|
|
602
589
|
|
|
603
590
|
- `CreateSecretCommand`, holding either a string or binary
|
|
604
591
|
- `GetSecretValueCommand`, by staging label or by version id
|
|
@@ -619,8 +606,6 @@ Sim Secrets Manager currently supports:
|
|
|
619
606
|
|
|
620
607
|
## Limitations
|
|
621
608
|
|
|
622
|
-
Current documented limitations:
|
|
623
|
-
|
|
624
609
|
- A `KmsKeyId` is checked when a version is written under it, not when it is set on its own. An
|
|
625
610
|
`UpdateSecret` changing only the key accepts a key that is absent, and the next write of a value
|
|
626
611
|
fails.
|
|
@@ -1,20 +1,14 @@
|
|
|
1
1
|
# Simulated SES
|
|
2
2
|
|
|
3
|
-
Yulin
|
|
4
|
-
|
|
5
|
-
sent. A test can assert that signing someone up produced a welcome email addressed to them, without
|
|
6
|
-
an AWS account and without a mailbox to read.
|
|
7
|
-
|
|
8
|
-
There is no delivery to simulate. A message SES accepts leaves AWS for a mail system. The whole of
|
|
9
|
-
the observable AWS behaviour is whether SES would have accepted the message and what it would have
|
|
10
|
-
sent. That is what makes this service small and what makes it useful.
|
|
3
|
+
Yulin simulates the Amazon SES v2 API in memory. It stores email identities, applies sandbox and
|
|
4
|
+
suppression rules, renders templates, and records accepted messages. It does not deliver email.
|
|
11
5
|
|
|
12
6
|
SES specific types are imported from the `@kensio/yulin/ses` subpath.
|
|
13
7
|
|
|
14
8
|
## Asserting on a message that was sent
|
|
15
9
|
|
|
16
|
-
`sentEmails()`
|
|
17
|
-
|
|
10
|
+
Use `sentEmails()` to inspect accepted messages. Each record contains the sender, To/Cc/Bcc lists,
|
|
11
|
+
subject, body, attachments, and message ID.
|
|
18
12
|
|
|
19
13
|
```typescript sim-ses-send-and-assert
|
|
20
14
|
/**
|
|
@@ -115,9 +109,8 @@ console.log(
|
|
|
115
109
|
|
|
116
110
|
## Verifying identities
|
|
117
111
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
instead of an API call. `verifyIdentity` performs it, creating the identity where one is absent.
|
|
112
|
+
SES normally verifies an address by email and a domain through DNS. In tests, call `verifyIdentity`
|
|
113
|
+
instead. It creates the identity if necessary and marks it verified.
|
|
121
114
|
|
|
122
115
|
Everything else about identities is the ordinary SES API. `CreateEmailIdentity` starts one, and it
|
|
123
116
|
starts unverified, exactly as a real one does:
|
|
@@ -631,13 +624,10 @@ one answer whoever asked.
|
|
|
631
624
|
|
|
632
625
|
## The sandbox
|
|
633
626
|
|
|
634
|
-
An account starts in the SES sandbox
|
|
635
|
-
|
|
636
|
-
refuses to mail an address nobody verified, and catching that refusal in a test is much better than
|
|
637
|
-
catching it in an account.
|
|
627
|
+
An account starts in the SES sandbox. Both the sender and every recipient must be verified. Outside
|
|
628
|
+
the sandbox, only the sender must be verified.
|
|
638
629
|
|
|
639
|
-
|
|
640
|
-
is how an account gets there:
|
|
630
|
+
Call `PutAccountDetails` with `ProductionAccessEnabled` to leave the sandbox:
|
|
641
631
|
|
|
642
632
|
```typescript sim-ses-sandbox
|
|
643
633
|
/**
|
|
@@ -696,17 +686,12 @@ caller finds out everything it has to verify from one failure:
|
|
|
696
686
|
Email address is not verified. The following identities failed the check in region US-EAST-1: someone@example.org
|
|
697
687
|
```
|
|
698
688
|
|
|
699
|
-
|
|
700
|
-
account stays in the sandbox until that review lands. Granting it immediately is a deliberate
|
|
701
|
-
divergence. The alternative is a simulator no test can get out of the sandbox in, and waiting for a
|
|
702
|
-
review is beyond what a test can assert on anyway.
|
|
689
|
+
Unlike AWS, Yulin grants production access immediately instead of waiting for a manual review.
|
|
703
690
|
|
|
704
691
|
## The suppression list
|
|
705
692
|
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
list. The support tool that lists suppressed addresses, the form that removes one and the script
|
|
709
|
-
that seeds the list all have somewhere to run.
|
|
693
|
+
SES maintains an account suppression list for hard bounces and complaints. Tests add feedback with
|
|
694
|
+
`recordFeedback`, and the suppression commands read and change the same list.
|
|
710
695
|
|
|
711
696
|
`PutSuppressedDestination`, `GetSuppressedDestination`, `ListSuppressedDestinations` and
|
|
712
697
|
`DeleteSuppressedDestination` manage it.
|
|
@@ -870,8 +855,7 @@ recorded.
|
|
|
870
855
|
|
|
871
856
|
## Messages on the console
|
|
872
857
|
|
|
873
|
-
|
|
874
|
-
with, so `serveSimAws` prints a summary of each one as SES accepts it:
|
|
858
|
+
For local development, `serveSimAws` prints a summary whenever SES accepts a message:
|
|
875
859
|
|
|
876
860
|
```
|
|
877
861
|
sim SES: hello@example.com to alice@example.com, bcc audit@example.com
|
|
@@ -899,13 +883,12 @@ pool kept. Both services recorded it, and each block says what that service hold
|
|
|
899
883
|
|
|
900
884
|
## Permissions
|
|
901
885
|
|
|
902
|
-
Every command
|
|
903
|
-
|
|
904
|
-
should cover a send and fails to.
|
|
886
|
+
Every command uses simulated IAM. A send authorizes against the sender identity, not the recipient
|
|
887
|
+
addresses.
|
|
905
888
|
|
|
906
889
|
```typescript sim-ses-permissions
|
|
907
890
|
/**
|
|
908
|
-
* A Role that may only send from one domain.
|
|
891
|
+
* A Role that may only send from one address at a verified domain.
|
|
909
892
|
*/
|
|
910
893
|
|
|
911
894
|
import { CreateRoleCommand, PutRolePolicyCommand } from "@aws-sdk/client-iam";
|
|
@@ -945,6 +928,9 @@ await simAws.iam().putRolePolicy(
|
|
|
945
928
|
Effect: "Allow",
|
|
946
929
|
Action: "ses:SendEmail",
|
|
947
930
|
Resource: "arn:aws:ses:us-east-1:111111111111:identity/example.com",
|
|
931
|
+
Condition: {
|
|
932
|
+
StringEquals: { "ses:FromAddress": "hello@example.com" },
|
|
933
|
+
},
|
|
948
934
|
},
|
|
949
935
|
],
|
|
950
936
|
}),
|
|
@@ -953,7 +939,7 @@ await simAws.iam().putRolePolicy(
|
|
|
953
939
|
|
|
954
940
|
await ses.sendEmail(
|
|
955
941
|
new SendEmailCommand({
|
|
956
|
-
FromEmailAddress: "
|
|
942
|
+
FromEmailAddress: "hello@example.com",
|
|
957
943
|
Destination: { ToAddresses: ["someone@example.com"] },
|
|
958
944
|
Content: {
|
|
959
945
|
Simple: {
|
|
@@ -978,6 +964,10 @@ The more specific identity wins when both exist. A policy naming `identity/examp
|
|
|
978
964
|
send from any address at the domain, unless that address is an identity in its own right, in which
|
|
979
965
|
case the send authorizes against `identity/hello@example.com` instead.
|
|
980
966
|
|
|
967
|
+
`ses:FromAddress` carries the bare `FromEmailAddress`. A policy can use it to allow one address at a
|
|
968
|
+
verified domain. A display name does not change the value. For example, `Welcome team
|
|
969
|
+
<hello@example.com>` supplies `hello@example.com` to IAM.
|
|
970
|
+
|
|
981
971
|
`ses:ListEmailIdentities`, `ses:GetAccount` and `ses:PutAccountDetails` have no resource type at all
|
|
982
972
|
on real SES, and only a policy written against `*` allows them. A policy scoped to identity ARNs
|
|
983
973
|
allows none of the three. Not even one written against `identity/*`, the intuitive reading and the
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
# Simulated SNS
|
|
2
2
|
|
|
3
|
-
Yulin
|
|
4
|
-
|
|
3
|
+
Yulin simulates Amazon SNS standard topics for tests and local development. A published message can
|
|
4
|
+
reach simulated SQS queues, invoke simulated Lambda functions or create SMS records that tests can
|
|
5
|
+
inspect. Direct SMS publishes are recorded in the same way.
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
A message published to a topic is delivered to every queue subscribed to it, invokes every Lambda
|
|
9
|
-
function subscribed to it, and is recorded as an SMS for every phone number subscribed to it. Only
|
|
10
|
-
those three protocols are simulated. A message published straight to a phone number is recorded
|
|
11
|
-
as an SMS a test can assert on.
|
|
7
|
+
Topics are stored in memory, and simulated IAM authorizes every operation. FIFO topics and other
|
|
8
|
+
subscription protocols are not simulated. Import SNS-specific types from `@kensio/yulin/sns`.
|
|
12
9
|
|
|
13
10
|
## Creating a topic and publishing to it
|
|
14
11
|
|
|
@@ -103,11 +100,10 @@ console.log(read.Attributes?.["SubscriptionsConfirmed"]); // "0"
|
|
|
103
100
|
reports it. The three subscription counts are reported as zero, the counts a topic with no
|
|
104
101
|
subscriptions has.
|
|
105
102
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
`
|
|
109
|
-
|
|
110
|
-
would look encrypted to the request that set it and be plain to everything else.
|
|
103
|
+
Unsupported topic attributes are rejected instead of being stored without effect. These include
|
|
104
|
+
`FifoTopic`, `KmsMasterKeyId`, `SignatureVersion`, `TracingConfig`, `ArchivePolicy`, `DeliveryPolicy`,
|
|
105
|
+
`ContentBasedDeduplication` and delivery status logging attributes such as
|
|
106
|
+
`SQSSuccessFeedbackRoleArn`.
|
|
111
107
|
|
|
112
108
|
## Publishing
|
|
113
109
|
|
|
@@ -148,12 +144,11 @@ const published = await sns.publish(
|
|
|
148
144
|
console.log(published.MessageId !== undefined); // true
|
|
149
145
|
```
|
|
150
146
|
|
|
151
|
-
|
|
152
|
-
`Binary
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
[Sending an SMS](#sending-an-sms) covers those.
|
|
147
|
+
Message attributes use the AWS name and type rules. A type starts with `String`, `String.Array`,
|
|
148
|
+
`Number` or `Binary` and may add a custom label after a dot, such as `Number.int`. SNS rejects
|
|
149
|
+
reserved `AWS.` and `Amazon.` name prefixes, unknown base types and values that do not match their
|
|
150
|
+
type. The SMS attributes `AWS.SNS.SMS.SenderID` and `AWS.SNS.SMS.SMSType` are exceptions. See
|
|
151
|
+
[Sending an SMS](#sending-an-sms).
|
|
157
152
|
|
|
158
153
|
A `Subject` is UTF-8 text with no line breaks or control characters, of fewer than 100 characters.
|
|
159
154
|
That is the contract real SNS states. A subject of exactly 100 characters is already too long. A
|
|
@@ -164,9 +159,8 @@ publish with no `Message`, or with one over the size limit, is refused with
|
|
|
164
159
|
the rest of the batch goes through, as real SNS reports it. An empty batch, more than ten entries, a
|
|
165
160
|
malformed entry id or two entries sharing an id fail the whole request.
|
|
166
161
|
|
|
167
|
-
The size limit
|
|
168
|
-
|
|
169
|
-
`BatchRequestTooLongException`. The response singles out no entry.
|
|
162
|
+
The size limit applies to the whole batch. A batch over the limit fails with
|
|
163
|
+
`BatchRequestTooLongException`, without identifying one entry as the cause.
|
|
170
164
|
|
|
171
165
|
```typescript sim-sns-publish-batch
|
|
172
166
|
/**
|
|
@@ -1762,9 +1756,9 @@ synthesises an `AWS::SNS::Subscription` alongside the `AWS::SQS::QueuePolicy` th
|
|
|
1762
1756
|
delivery, and both deploy. `new subscriptions.LambdaSubscription(fn)` does the same with the
|
|
1763
1757
|
`AWS::Lambda::Permission` beside it.
|
|
1764
1758
|
|
|
1765
|
-
##
|
|
1759
|
+
## Supported operations
|
|
1766
1760
|
|
|
1767
|
-
|
|
1761
|
+
Simulated SNS supports:
|
|
1768
1762
|
|
|
1769
1763
|
- `CreateTopicCommand`, idempotent for a name already taken, and `DeleteTopicCommand`
|
|
1770
1764
|
- `ListTopicsCommand`, paged at a hundred topics with a `NextToken`
|
|
@@ -1807,8 +1801,6 @@ Sim SNS currently supports:
|
|
|
1807
1801
|
|
|
1808
1802
|
## Limitations
|
|
1809
1803
|
|
|
1810
|
-
Current documented limitations:
|
|
1811
|
-
|
|
1812
1804
|
- Only the `sqs`, `lambda` and `sms` subscription protocols are simulated. A queue, a function and a
|
|
1813
1805
|
phone number are the only things a topic can deliver to. `http`, `https`, `email`, `email-json`,
|
|
1814
1806
|
`application` and `firehose` are refused at `Subscribe` time.
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# Simulated SQS
|
|
2
2
|
|
|
3
|
-
Yulin
|
|
4
|
-
|
|
3
|
+
Yulin simulates Amazon SQS standard queues for tests and local development. You can create queues,
|
|
4
|
+
send and receive messages, test visibility timeouts and redrive messages to dead-letter queues.
|
|
5
|
+
Messages are stored in memory, time-based behavior uses the simulation's clock, and simulated IAM
|
|
6
|
+
authorizes every operation.
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
FIFO queues are not simulated. Import SQS-specific types from `@kensio/yulin/sqs`.
|
|
7
9
|
|
|
8
10
|
## Creating a queue and sending a message
|
|
9
11
|
|
|
@@ -57,10 +59,9 @@ differ. A request naming no attributes always matches.
|
|
|
57
59
|
|
|
58
60
|
## Visibility timeouts
|
|
59
61
|
|
|
60
|
-
A received message is hidden from other consumers for the queue's visibility timeout,
|
|
61
|
-
default.
|
|
62
|
-
simulated
|
|
63
|
-
message come back.
|
|
62
|
+
A received message is hidden from other consumers for the queue's visibility timeout, which is 30
|
|
63
|
+
seconds by default. If the consumer does not delete it, the message becomes available again when the
|
|
64
|
+
simulated clock reaches the end of that timeout.
|
|
64
65
|
|
|
65
66
|
```typescript sim-sqs-visibility-timeout
|
|
66
67
|
/**
|
|
@@ -127,8 +128,8 @@ Every receive issues a fresh receipt handle, and a delete has to use the handle
|
|
|
127
128
|
receive of that message. A handle from an earlier receive is accepted and deletes nothing. Real SQS
|
|
128
129
|
accepts one too, and promises only that the message might not be deleted.
|
|
129
130
|
|
|
130
|
-
|
|
131
|
-
|
|
131
|
+
This can happen when a consumer runs past the visibility timeout and another consumer receives the
|
|
132
|
+
same message. The first consumer's later delete succeeds without deleting the message.
|
|
132
133
|
|
|
133
134
|
```typescript sim-sqs-stale-receipt-handle
|
|
134
135
|
/**
|
|
@@ -187,10 +188,9 @@ still the most recent one, so deleting with it works. A handle the queue never i
|
|
|
187
188
|
|
|
188
189
|
## Dead-letter queues
|
|
189
190
|
|
|
190
|
-
A `RedrivePolicy`
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
the move, as it drives the timeout itself.
|
|
191
|
+
A `RedrivePolicy` sends repeatedly received messages to a dead-letter queue. After a message reaches
|
|
192
|
+
`maxReceiveCount` without being deleted, the next visibility timeout moves it to the queue named by
|
|
193
|
+
`deadLetterTargetArn`. Advance the simulated clock to trigger the timeout and move.
|
|
194
194
|
|
|
195
195
|
```typescript sim-sqs-dead-letter-queue
|
|
196
196
|
/**
|
|
@@ -1137,7 +1137,7 @@ that deploys here, with the queue URL reaching the function through its environm
|
|
|
1137
1137
|
policy naming the queue by the ARN `Fn::GetAtt` gives. A grant to a service principal synthesises an
|
|
1138
1138
|
`AWS::SQS::QueuePolicy` alongside it, which deploys too.
|
|
1139
1139
|
|
|
1140
|
-
##
|
|
1140
|
+
## Supported operations
|
|
1141
1141
|
|
|
1142
1142
|
Sim SQS currently supports:
|
|
1143
1143
|
|