@kensio/yulin 1.21.6 → 1.21.8
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/eventbridge/cfn/bus/sim-cfn-event-bus-creator.js +1 -0
- package/dist/service/eventbridge/cfn/bus/sim-cfn-event-bus-properties.d.ts +4 -0
- package/dist/service/eventbridge/cfn/bus/sim-cfn-event-bus-properties.js +26 -1
- package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-creator.js +3 -1
- package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-properties.d.ts +0 -7
- package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-properties.js +0 -20
- package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-unsimulated-properties.d.ts +13 -0
- package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-unsimulated-properties.js +59 -0
- package/dist/service/eventbridge/cfn/sim-cfn-event-bridge-resource-error.d.ts +1 -1
- package/dist/service/eventbridge/cfn/sim-cfn-event-bridge-resource-error.js +1 -1
- package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-properties.js +1 -1
- package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-property-rules.d.ts +3 -2
- package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-property-rules.js +25 -3
- 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/dist/service/sns/cfn/topic/sim-cfn-sns-topic-creator.js +1 -0
- package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-properties.d.ts +9 -4
- package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-properties.js +18 -6
- package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-property-names.d.ts +10 -0
- package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-property-names.js +16 -1
- package/dist/service/ssm/cfn/parameter/sim-cfn-ssm-parameter-creator.js +1 -1
- package/dist/service/ssm/cfn/parameter/sim-cfn-ssm-parameter-properties.d.ts +11 -6
- package/dist/service/ssm/cfn/parameter/sim-cfn-ssm-parameter-properties.js +18 -9
- package/docs/README.md +40 -4
- package/docs/ai-skill/README.md +57 -54
- package/docs/cli/README.md +84 -94
- package/docs/factories/README.md +42 -54
- package/docs/lint/README.md +41 -67
- package/docs/non-aws-dependencies/README.md +72 -168
- package/docs/sdk/README.md +109 -95
- package/docs/serve/README.md +192 -898
- 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 +24 -20
- 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 +60 -80
- 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 +31 -33
- package/docs/services/sqs/README.md +14 -14
- package/docs/services/ssm/README.md +19 -21
- 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/terraform/README.md +108 -126
- package/docs/testing/README.md +228 -0
- package/docs/time/README.md +87 -117
- package/llms.txt +2 -1
- package/package.json +1 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# Simulated Route53
|
|
2
2
|
|
|
3
|
-
Yulin
|
|
3
|
+
Yulin simulates Amazon Route 53 hosted zones, records and DNSSEC configuration for tests and local
|
|
4
|
+
development. You can manage them through the AWS SDK or deploy them from CloudFormation and CDK
|
|
5
|
+
templates. When Yulin serves the simulation on localhost, Route 53 records can route local hostnames
|
|
6
|
+
to simulated services such as CloudFront distributions and S3 bucket websites.
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
served on localhost, Route53 records can route custom local hostnames to other simulated AWS
|
|
8
|
-
services, such as simulated CloudFront distributions or simulated S3 bucket websites.
|
|
8
|
+
Use Route 53 through `SimAws` when it should share state with other services. Use `SimRoute53`
|
|
9
|
+
directly when you need an isolated Route 53 simulation.
|
|
9
10
|
|
|
10
11
|
## Basic Hosted Zone usage
|
|
11
12
|
|
|
@@ -54,8 +55,8 @@ console.log(hostedZoneOut.HostedZone?.ResourceRecordSetCount);
|
|
|
54
55
|
Hosted Zone names are normalised with a trailing dot in Route53-style outputs, so `example.test`
|
|
55
56
|
becomes `example.test.`.
|
|
56
57
|
|
|
57
|
-
Hosted
|
|
58
|
-
|
|
58
|
+
Hosted zone creation moves the zone to `INSYNC` in a background task. Call
|
|
59
|
+
`await simAws.backgroundTasksComplete()` before asserting on the final state.
|
|
59
60
|
|
|
60
61
|
Hosted Zone IDs are accepted in any real Route53 shape, being a `Z` prefix followed by uppercase
|
|
61
62
|
alphanumerics, up to 32 characters. A real Hosted Zone ID copied out of an AWS account, such as
|
|
@@ -65,14 +66,12 @@ alphanumerics, up to 32 characters. A real Hosted Zone ID copied out of an AWS a
|
|
|
65
66
|
|
|
66
67
|
## Registering a Hosted Zone with a chosen ID
|
|
67
68
|
|
|
68
|
-
`CreateHostedZoneCommand` allocates
|
|
69
|
-
|
|
70
|
-
setup instead.
|
|
69
|
+
`CreateHostedZoneCommand` allocates the hosted zone ID. When a synthesized template already contains
|
|
70
|
+
an ID, register that hosted zone during test setup instead.
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
template deploy as it is, with no rewriting.
|
|
72
|
+
For example, `HostedZone.fromLookup` writes the resolved hosted zone ID into the synthesized
|
|
73
|
+
template. Registering that ID before deployment lets its `AWS::Route53::RecordSet` resources deploy
|
|
74
|
+
without changing the template.
|
|
76
75
|
|
|
77
76
|
```typescript sim-route53-register-hosted-zone
|
|
78
77
|
/**
|
|
@@ -1701,8 +1700,9 @@ await scopedRoute53.createHostedZone(
|
|
|
1701
1700
|
);
|
|
1702
1701
|
```
|
|
1703
1702
|
|
|
1704
|
-
Each `SimAws` instance has its own isolated state.
|
|
1705
|
-
|
|
1703
|
+
Each `SimAws` instance has its own isolated state. Application tests should normally use the instance
|
|
1704
|
+
from their shared [test suite setup](https://yulinsim.dev/testing/). A fresh instance remains useful
|
|
1705
|
+
when a test specifically needs an empty simulated account.
|
|
1706
1706
|
|
|
1707
1707
|
## Standalone SimRoute53
|
|
1708
1708
|
|
|
@@ -1732,7 +1732,7 @@ console.log(hostedZoneCreation.HostedZone?.Id);
|
|
|
1732
1732
|
A standalone `SimRoute53` instance has its own isolated state, standing apart from any wider
|
|
1733
1733
|
`SimAws` environment. Use `SimAws` when Route53 needs to resolve names to other simulated services.
|
|
1734
1734
|
|
|
1735
|
-
##
|
|
1735
|
+
## Supported operations
|
|
1736
1736
|
|
|
1737
1737
|
Sim Route53 currently supports:
|
|
1738
1738
|
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
# Simulated S3
|
|
2
2
|
|
|
3
|
-
Yulin
|
|
3
|
+
Yulin simulates S3 buckets, objects, policies, notifications and website hosting. Use
|
|
4
|
+
`simAws.s3()` as part of a simulated AWS environment or create a standalone `SimS3`.
|
|
5
|
+
`serveSimAws` exposes the S3 API and website endpoints over localhost.
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
state. Yulin can serve a simulated S3 service on localhost.
|
|
7
|
+
## Create a bucket and object
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Create a simulated AWS environment, get simulated S3, create a Bucket, and put an Object into it.
|
|
9
|
+
Create a bucket, write an object and read it back.
|
|
11
10
|
|
|
12
11
|
```typescript sim-s3-bucket
|
|
13
12
|
/**
|
|
@@ -104,15 +103,15 @@ await scopedS3.createBucket(
|
|
|
104
103
|
);
|
|
105
104
|
```
|
|
106
105
|
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
Bucket names are global within a `SimAws` instance. Creating the same name in another simulated
|
|
107
|
+
account or region fails.
|
|
109
108
|
|
|
110
|
-
Each `SimAws` instance has
|
|
111
|
-
all tests, as you prefer.
|
|
109
|
+
Each `SimAws` instance has isolated state.
|
|
112
110
|
|
|
113
|
-
## Listing
|
|
111
|
+
## Listing buckets
|
|
114
112
|
|
|
115
|
-
|
|
113
|
+
`ListBucketsCommand` lists buckets in the selected account and region. Each bucket reports its
|
|
114
|
+
creation time from the [simulated clock](https://yulinsim.dev/time/).
|
|
116
115
|
|
|
117
116
|
```typescript sim-s3-list-buckets
|
|
118
117
|
/**
|
|
@@ -137,17 +136,20 @@ console.log(listBucketsOutput.Buckets?.map((bucket) => bucket.Name));
|
|
|
137
136
|
console.log(listBucketsOutput.Buckets?.[0]?.CreationDate);
|
|
138
137
|
```
|
|
139
138
|
|
|
140
|
-
##
|
|
139
|
+
## Checking whether a bucket or object exists
|
|
141
140
|
|
|
142
|
-
`HeadObjectCommand`
|
|
141
|
+
`HeadObjectCommand` returns object metadata without the body. `HeadBucketCommand` checks that a
|
|
142
|
+
bucket exists and is accessible, and reports its region.
|
|
143
143
|
|
|
144
|
-
A HEAD response
|
|
144
|
+
A HEAD response has no error document. Yulin returns 404 for a missing bucket or object, which the
|
|
145
|
+
SDK raises as `NotFound`. It returns 403 when the caller lacks permission. `GetObject` can distinguish
|
|
146
|
+
`NoSuchBucket` from `NoSuchKey` because its error response has a body.
|
|
145
147
|
|
|
146
148
|
`HeadObject` authorizes against `s3:GetObject` and `HeadBucket` against `s3:ListBucket`, as real S3 does, so knowing something is there needs the permission to read it.
|
|
147
149
|
|
|
148
|
-
## Listing
|
|
150
|
+
## Listing objects
|
|
149
151
|
|
|
150
|
-
Use `ListObjectsV2Command` to list
|
|
152
|
+
Use `ListObjectsV2Command` to list objects in a bucket. Yulin supports `Prefix`,
|
|
151
153
|
`Delimiter`, `MaxKeys`, `ContinuationToken` and `StartAfter`, and answers with `Contents`,
|
|
152
154
|
`CommonPrefixes`, `KeyCount`, `IsTruncated` and `NextContinuationToken`.
|
|
153
155
|
|
|
@@ -197,18 +199,16 @@ for (const object of listedObjects) {
|
|
|
197
199
|
}
|
|
198
200
|
```
|
|
199
201
|
|
|
200
|
-
Listings
|
|
201
|
-
|
|
202
|
-
returns no keys and completes the listing, and a negative one is refused with `InvalidArgument`.
|
|
202
|
+
Listings sort objects by key and return at most 1,000 entries. Larger `MaxKeys` values are capped at
|
|
203
|
+
1,000. Zero returns an empty complete page, and a negative value raises `InvalidArgument`.
|
|
203
204
|
|
|
204
205
|
A listing that found no keys has no `Contents` at all, and the example reaches for `Contents ?? []`
|
|
205
206
|
for that reason. `KeyCount` is the count either way.
|
|
206
207
|
|
|
207
208
|
### Walking a truncated listing
|
|
208
209
|
|
|
209
|
-
A truncated response
|
|
210
|
-
|
|
211
|
-
out of it, and simulated S3 refuses one it did not issue.
|
|
210
|
+
A truncated response includes `NextContinuationToken`. Pass it unchanged as `ContinuationToken` in
|
|
211
|
+
the next request. Yulin rejects tokens it did not issue.
|
|
212
212
|
|
|
213
213
|
```typescript sim-s3-list-objects-v2-pagination
|
|
214
214
|
/**
|
|
@@ -533,9 +533,8 @@ An Object uploaded in parts gets a different form. See
|
|
|
533
533
|
|
|
534
534
|
## Uploading an Object in parts
|
|
535
535
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
over a served endpoint alike.
|
|
536
|
+
Yulin supports multipart upload through the SDK and served S3 endpoint. This covers the operations
|
|
537
|
+
used by `aws s3 cp` for files above eight megabytes and by `@aws-sdk/lib-storage`.
|
|
539
538
|
|
|
540
539
|
```bash
|
|
541
540
|
aws s3 cp ./big.bin s3://widgets/big.bin # 12MB, multipart under the covers
|
|
@@ -846,9 +845,8 @@ See [Serve simulated S3 on localhost](#serve-simulated-s3-on-localhost) for sett
|
|
|
846
845
|
|
|
847
846
|
## Deleting Objects
|
|
848
847
|
|
|
849
|
-
Use `DeleteObjectCommand` to remove one
|
|
850
|
-
|
|
851
|
-
Bucket cannot empty it.
|
|
848
|
+
Use `DeleteObjectCommand` to remove one object or `DeleteObjectsCommand` to remove several. Each
|
|
849
|
+
object requires `s3:DeleteObject` permission on its ARN.
|
|
852
850
|
|
|
853
851
|
```typescript sim-s3-delete-object
|
|
854
852
|
/**
|
|
@@ -931,9 +929,9 @@ failures come back.
|
|
|
931
929
|
|
|
932
930
|
## Object versioning
|
|
933
931
|
|
|
934
|
-
A versioned
|
|
935
|
-
|
|
936
|
-
`
|
|
932
|
+
A versioned bucket keeps each write as a separate version. Deleting a key adds a delete marker. Enable
|
|
933
|
+
versioning with `PutBucketVersioningCommand` or the `VersioningConfiguration` property of an
|
|
934
|
+
`AWS::S3::Bucket`.
|
|
937
935
|
|
|
938
936
|
```typescript sim-s3-object-versioning
|
|
939
937
|
import {
|
|
@@ -1096,12 +1094,11 @@ A delete on a versioned Bucket raises `s3:ObjectRemoved:DeleteMarkerCreated` rat
|
|
|
1096
1094
|
|
|
1097
1095
|
## Object Lock
|
|
1098
1096
|
|
|
1099
|
-
Object Lock
|
|
1100
|
-
|
|
1101
|
-
`
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
`ObjectLockEnabled` on an `AWS::S3::Bucket` resource.
|
|
1097
|
+
Object Lock protects an object version with a retention period, a legal hold, or both. Deleting a
|
|
1098
|
+
protected version raises `AccessDenied`. A caller with `s3:BypassGovernanceRetention` may bypass
|
|
1099
|
+
`GOVERNANCE` retention by setting `BypassGovernanceRetention`. `COMPLIANCE` retention and legal
|
|
1100
|
+
holds cannot be bypassed. Enable Object Lock with `PutObjectLockConfigurationCommand` or
|
|
1101
|
+
`ObjectLockEnabled` on an `AWS::S3::Bucket`.
|
|
1105
1102
|
|
|
1106
1103
|
Object Lock holds a version, and versioning has to be on underneath it. Turning it on over a Bucket
|
|
1107
1104
|
with versioning off is refused with `InvalidBucketState`, as real S3 refuses it, and a template
|
|
@@ -1256,8 +1253,8 @@ Bucket created around the property would report a default retention it never app
|
|
|
1256
1253
|
|
|
1257
1254
|
## Event notifications
|
|
1258
1255
|
|
|
1259
|
-
A simulated
|
|
1260
|
-
|
|
1256
|
+
A simulated bucket can notify Lambda, SQS or SNS when an object is created or removed. Apply the
|
|
1257
|
+
configuration with
|
|
1261
1258
|
`PutBucketNotificationConfigurationCommand` and read back with
|
|
1262
1259
|
`GetBucketNotificationConfigurationCommand`.
|
|
1263
1260
|
|
|
@@ -1360,10 +1357,10 @@ can take the `.jpg` files under a prefix while another takes the `.png` files un
|
|
|
1360
1357
|
The rule applies across the destination groups. A function and a queue that both want the same
|
|
1361
1358
|
event are refused as readily as two functions.
|
|
1362
1359
|
|
|
1363
|
-
`PutBucketNotificationConfigurationCommand` replaces the
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1360
|
+
`PutBucketNotificationConfigurationCommand` replaces the complete configuration.
|
|
1361
|
+
`GetBucketNotificationConfigurationCommand` returns an empty configuration when none is set. The
|
|
1362
|
+
request nests destination groups under `NotificationConfiguration`, while the response puts them at
|
|
1363
|
+
the top level:
|
|
1367
1364
|
|
|
1368
1365
|
```typescript
|
|
1369
1366
|
const read = await simAws
|
|
@@ -1476,9 +1473,9 @@ function is.
|
|
|
1476
1473
|
|
|
1477
1474
|
### To an SQS queue
|
|
1478
1475
|
|
|
1479
|
-
A `QueueConfigurations` entry names a queue by ARN.
|
|
1480
|
-
message body
|
|
1481
|
-
|
|
1476
|
+
A `QueueConfigurations` entry names a queue by ARN. S3 sends the complete `Records` document as one
|
|
1477
|
+
message body. Add a Lambda event source mapping to consume it, then call
|
|
1478
|
+
`backgroundTasksComplete()` to finish the delivery chain.
|
|
1482
1479
|
|
|
1483
1480
|
The queue's `Policy` attribute has to allow `sqs:SendMessage` for the `s3.amazonaws.com` service
|
|
1484
1481
|
principal. S3 supplies `aws:SourceArn` and `aws:SourceAccount`. The `ArnLike` condition CDK's
|
|
@@ -1633,10 +1630,9 @@ its own policy and its own Account's IAM are what admit the Bucket. A FIFO queue
|
|
|
1633
1630
|
|
|
1634
1631
|
### To an SNS topic
|
|
1635
1632
|
|
|
1636
|
-
A `TopicConfigurations` entry names a topic by ARN.
|
|
1637
|
-
SNS `Message
|
|
1638
|
-
|
|
1639
|
-
SNS envelope, then parse its `Message` for the S3 event.
|
|
1633
|
+
A `TopicConfigurations` entry names a topic by ARN. S3 publishes the complete `Records` document as
|
|
1634
|
+
the SNS `Message` with the subject `Amazon S3 Notification`. A subscribed queue receives an SNS
|
|
1635
|
+
envelope whose `Message` contains the S3 event.
|
|
1640
1636
|
|
|
1641
1637
|
The topic's `Policy` attribute has to allow `sns:Publish` for the `s3.amazonaws.com` service
|
|
1642
1638
|
principal. S3 supplies `aws:SourceArn` and `aws:SourceAccount`. The `ArnLike` condition CDK's
|
|
@@ -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.
|