@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,31 +1,20 @@
|
|
|
1
1
|
# Simulated ECR
|
|
2
2
|
|
|
3
|
-
Yulin
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
That is what this service is for. A container image Lambda function cannot run here, because Yulin
|
|
7
|
-
never reads an image, so something has to say what the code inside that image actually is. A
|
|
8
|
-
repository is the natural place to say it. It is the stable name for the thing that holds the code,
|
|
9
|
-
outliving any tag and any CDK construct ID, and a repository holding a registered handler outlives
|
|
10
|
-
the stack that declared it too.
|
|
3
|
+
Yulin represents an ECR image with an in-process Lambda handler. Register the handler against a
|
|
4
|
+
repository and tag, then deploy or create a container image function that uses the image URI.
|
|
11
5
|
|
|
12
6
|
ECR-specific types are imported from the `@kensio/yulin/ecr` subpath.
|
|
13
7
|
|
|
14
8
|
## What a simulated image is
|
|
15
9
|
|
|
16
|
-
An image URI
|
|
17
|
-
manifest, digest or scan finding exists. A simulated image is a handler function, registered against
|
|
18
|
-
a repository and a tag.
|
|
10
|
+
An image URI identifies a registered handler. Image content remains outside the simulation.
|
|
19
11
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
registry protocol. None of that happens in this process, and a simulated `PutImage` would be a
|
|
23
|
-
command taking an argument nothing could produce.
|
|
12
|
+
Use the Yulin-specific `simulateImage` method to register a handler. The simulated surface has no
|
|
13
|
+
ECR SDK or Docker registry operations.
|
|
24
14
|
|
|
25
15
|
## Registering a handler as an image
|
|
26
16
|
|
|
27
|
-
Register the handler
|
|
28
|
-
is created from it.
|
|
17
|
+
Register the handler during test setup. Lambda resolves image functions from the same repository.
|
|
29
18
|
|
|
30
19
|
```typescript sim-ecr-register-image
|
|
31
20
|
/**
|
|
@@ -82,36 +71,22 @@ console.log(Buffer.from(output.Payload).toString());
|
|
|
82
71
|
await simAws.backgroundTasksComplete();
|
|
83
72
|
```
|
|
84
73
|
|
|
85
|
-
|
|
86
|
-
declaration to make, and a test can name the repository its templates already point at.
|
|
74
|
+
Calling `repository(name)` creates the repository if it is absent.
|
|
87
75
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
belongs to. A name real ECR would refuse is refused here too.
|
|
76
|
+
Pass a repository name such as `orders` or `platform/orders`. The selected simulated account and
|
|
77
|
+
Region supply the registry host.
|
|
91
78
|
|
|
92
79
|
## How an image URI is matched
|
|
93
80
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
into a test. A CDK image asset is tagged with the asset content hash, which changes whenever the
|
|
99
|
-
image source does, and a pipeline-built image is usually tagged with a git sha or a build number
|
|
100
|
-
passed in as a stack parameter. An `ImageUri` built by `Fn::Sub` or from a stack parameter is
|
|
101
|
-
matched on what it resolves to.
|
|
81
|
+
Yulin first matches the registry host and repository name. It then looks for the requested tag. A
|
|
82
|
+
registered tag selects that handler. An unknown tag, a digest or no tag selects the most recently
|
|
83
|
+
registered handler. This fallback lets content-hash and build-number tags resolve without copying
|
|
84
|
+
those generated values into the test.
|
|
102
85
|
|
|
103
|
-
|
|
104
|
-
|
|
86
|
+
The registry host determines the account and Region. Repositories with the same name in different
|
|
87
|
+
scopes remain separate. Cross-account image references are supported.
|
|
105
88
|
|
|
106
|
-
|
|
107
|
-
run an image from another account's repository, as it can on real AWS, and a same-named repository
|
|
108
|
-
in another account is a different repository.
|
|
109
|
-
|
|
110
|
-
So `orders:blue` runs the handler registered under `blue` where the repository holds one, and the
|
|
111
|
-
handler registered most recently otherwise. That is how a blue/green pair of images in one
|
|
112
|
-
repository can back two functions differently, while a content hash tag nobody registered still
|
|
113
|
-
finds something to run. Registering a tag again both replaces what it held and makes it the most
|
|
114
|
-
recent registration.
|
|
89
|
+
Registering a tag again replaces its handler and makes that handler the most recent registration.
|
|
115
90
|
|
|
116
91
|
```typescript sim-ecr-image-tags
|
|
117
92
|
/**
|
|
@@ -152,18 +127,15 @@ console.log(Buffer.from(output.Payload).toString()); // "blue handler"
|
|
|
152
127
|
await simAws.backgroundTasksComplete();
|
|
153
128
|
```
|
|
154
129
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
the way real Lambda refuses a function whose image it cannot pull.
|
|
130
|
+
Direct `CreateFunction` calls and CloudFormation deployments use the same resolution rules. Lambda
|
|
131
|
+
refuses an image URI that resolves to no handler.
|
|
158
132
|
|
|
159
133
|
## Repositories in CloudFormation
|
|
160
134
|
|
|
161
|
-
`AWS::ECR::Repository
|
|
162
|
-
|
|
163
|
-
been registered in it.
|
|
135
|
+
Simulated CloudFormation creates `AWS::ECR::Repository`. The repository starts empty unless a
|
|
136
|
+
handler was already registered under its name.
|
|
164
137
|
|
|
165
|
-
`Ref` returns the repository name
|
|
166
|
-
application stack can build its function's `ImageUri` from the repository a platform stack declared.
|
|
138
|
+
`Ref` returns the repository name. `Fn::GetAtt` supports `Arn` and `RepositoryUri`.
|
|
167
139
|
|
|
168
140
|
```typescript sim-ecr-cloudformation-repository
|
|
169
141
|
/**
|
|
@@ -236,34 +208,23 @@ console.log(Buffer.from(output.Payload).toString());
|
|
|
236
208
|
await simAws.backgroundTasksComplete();
|
|
237
209
|
```
|
|
238
210
|
|
|
239
|
-
A
|
|
240
|
-
difference. The image can exist before the stack that declares the repository, as it does in real
|
|
241
|
-
life.
|
|
211
|
+
A deployment adopts a repository that already contains a registered handler.
|
|
242
212
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
registered outside any stack and is what every later deploy resolves to. Real ECR also refuses to
|
|
246
|
-
delete a repository that still holds images, which fails the stack unless the template says
|
|
247
|
-
`EmptyOnDelete`. Here the refusal is recorded and the teardown carries on, since what is being
|
|
248
|
-
protected is a test's own registration.
|
|
213
|
+
Stack teardown removes an empty repository. A repository containing a handler remains in place and
|
|
214
|
+
its deletion is recorded as skipped. Teardown continues after the skipped deletion.
|
|
249
215
|
|
|
250
|
-
|
|
251
|
-
is created without it. That covers `ImageScanningConfiguration`, `ImageTagMutability`,
|
|
216
|
+
Other repository properties are recorded as ignored. These include `ImageScanningConfiguration`, `ImageTagMutability`,
|
|
252
217
|
`LifecyclePolicy`, `RepositoryPolicyText`, `EncryptionConfiguration`, `EmptyOnDelete` and `Tags`.
|
|
253
218
|
|
|
254
219
|
## Where a function's handler comes from
|
|
255
220
|
|
|
256
|
-
|
|
221
|
+
Yulin resolves a container image function in this order:
|
|
257
222
|
|
|
258
|
-
1. An [executable binding](https://yulinsim.dev/services/lambda/#executable-bindings)
|
|
259
|
-
|
|
260
|
-
one deploy.
|
|
261
|
-
2. The simulated ECR repository the function's `Code.ImageUri` names. That is a standing statement
|
|
262
|
-
about what the image is, made once and good for every stack that runs it.
|
|
223
|
+
1. An [executable binding](https://yulinsim.dev/services/lambda/#executable-bindings) supplied for the deployment.
|
|
224
|
+
2. The handler registered in the ECR repository named by `Code.ImageUri`.
|
|
263
225
|
|
|
264
|
-
A function with no binding
|
|
265
|
-
|
|
266
|
-
different places. One is a wrong name, and the other is a handler that was never registered.
|
|
226
|
+
A function with no binding or registered image is skipped. The diagnostic distinguishes a missing
|
|
227
|
+
repository from a repository with no handlers.
|
|
267
228
|
|
|
268
229
|
## Available functionality
|
|
269
230
|
|
|
@@ -278,16 +239,14 @@ different places. One is a wrong name, and the other is a handler that was never
|
|
|
278
239
|
|
|
279
240
|
## Limitations
|
|
280
241
|
|
|
281
|
-
Current documented limitations:
|
|
282
|
-
|
|
283
242
|
- No image content, layer, digest, manifest or scan behaviour is simulated. A repository holds
|
|
284
243
|
handlers, and no image is ever pulled or inspected.
|
|
285
244
|
- There are no ECR SDK commands. `CreateRepository`, `DescribeRepositories`, `PutImage`,
|
|
286
245
|
`DescribeImages`, `BatchDeleteImage` and `GetAuthorizationToken` are all absent. Registering an
|
|
287
246
|
image is a Yulin-native operation because real `PutImage` takes a manifest for layers pushed over
|
|
288
247
|
the Docker registry protocol, and that protocol never runs in this process.
|
|
289
|
-
-
|
|
290
|
-
|
|
248
|
+
- CloudFormation authorizes `ecr:CreateRepository` and `ecr:DeleteRepository`. Handler registration
|
|
249
|
+
has no caller and skips authorization. Repository policies are ignored.
|
|
291
250
|
- Lifecycle policies go unevaluated, and no simulated image ever expires. Tag mutability goes
|
|
292
251
|
unenforced, and registering the same tag again replaces what it held.
|
|
293
252
|
- Naming a repository creates it. There is no `CreateRepository` to fail for a name already taken,
|
|
@@ -295,8 +254,8 @@ Current documented limitations:
|
|
|
295
254
|
- A stack teardown records the deletion of a repository holding a simulated image and carries on,
|
|
296
255
|
where real CloudFormation fails the stack unless the template says `EmptyOnDelete`. The repository
|
|
297
256
|
and its handler are left in place, and `EmptyOnDelete` itself goes unread.
|
|
298
|
-
-
|
|
299
|
-
|
|
257
|
+
- The repository model records no owning stack. Teardown of any declaring stack removes an empty
|
|
258
|
+
repository.
|
|
300
259
|
- Repository tags, registry policies, pull through cache rules, replication configuration and ECR
|
|
301
|
-
Public are
|
|
302
|
-
-
|
|
260
|
+
Public are absent.
|
|
261
|
+
- `serveSimAws` exposes no ECR HTTP API or Docker registry endpoint.
|
|
@@ -1,31 +1,20 @@
|
|
|
1
1
|
# Simulated ECS
|
|
2
2
|
|
|
3
|
-
Yulin
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Yulin simulates ECS clusters, task definitions, tasks and services. It runs JavaScript or TypeScript
|
|
4
|
+
handlers bound to container image URIs. Use `simAws.ecs()` directly or intercept an `ECSClient`.
|
|
5
|
+
ECS types are available from `@kensio/yulin/ecs`.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Binding code to a container image
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Yulin uses an image URI as an identifier for an in-process handler. It does not pull or execute the
|
|
10
|
+
image. A container with a matching binding runs the handler. An unbound container is recorded as
|
|
11
|
+
unsimulated while the rest of the task continues.
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
in its own process.
|
|
13
|
+
A task definition may include application and support containers. Yulin stores and reports every
|
|
14
|
+
container, but only runs containers that have a binding.
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
way an image URI identifies a container image Lambda function. The rule that follows is that a
|
|
18
|
-
container matched to a handler runs that handler, and a container with no match is recorded as not
|
|
19
|
-
simulated while the rest of the task carries on.
|
|
20
|
-
|
|
21
|
-
A realistic task definition holds an application container, a log router and an observability agent.
|
|
22
|
-
Only the first of those is something Yulin could ever run, and all three are stored and reported
|
|
23
|
-
back exactly as declared.
|
|
24
|
-
|
|
25
|
-
The case this leaves out is a sidecar the application depends on, such as a Redis or a database in
|
|
26
|
-
the same task. Point its connection details, which are ordinary environment variables, at a real one
|
|
27
|
-
you run yourself. See [non-AWS dependencies](https://yulinsim.dev/non-aws-dependencies/) for how that fits
|
|
28
|
-
together.
|
|
16
|
+
Run required sidecars such as Redis separately and pass their connection details through environment
|
|
17
|
+
variables. See [non-AWS dependencies](https://yulinsim.dev/non-aws-dependencies/).
|
|
29
18
|
|
|
30
19
|
## Registering a task definition
|
|
31
20
|
|
|
@@ -76,9 +65,7 @@ console.log(described.taskDefinition?.containerDefinitions?.[0]?.image);
|
|
|
76
65
|
// "example.dkr.ecr.eu-west-2.amazonaws.com/checkout:1"
|
|
77
66
|
```
|
|
78
67
|
|
|
79
|
-
Container definitions
|
|
80
|
-
ever run it. That covers port mappings, environment variables and secrets. A `valueFrom` naming a
|
|
81
|
-
Secrets Manager secret is held as the identifier it is, and never resolved.
|
|
68
|
+
Container definitions retain their images, port mappings, environment variables and secrets.
|
|
82
69
|
|
|
83
70
|
A registration that declares something this simulation has no room for is refused outright, and
|
|
84
71
|
never trimmed. That way a declaration cannot go missing from the revision it made.
|
|
@@ -132,9 +119,8 @@ a full task definition ARN. The ARN of a revision is
|
|
|
132
119
|
|
|
133
120
|
## Deregistering a revision
|
|
134
121
|
|
|
135
|
-
`DeregisterTaskDefinition` marks
|
|
136
|
-
by `family:revision`
|
|
137
|
-
find out what it declared. What it stops being is the revision the family resolves to.
|
|
122
|
+
`DeregisterTaskDefinition` marks a revision `INACTIVE` without removing it. The revision remains
|
|
123
|
+
available by `family:revision` or ARN, but the family name no longer resolves to it.
|
|
138
124
|
|
|
139
125
|
```typescript sim-ecs-deregister-task-definition
|
|
140
126
|
/**
|
|
@@ -234,8 +220,8 @@ A family counts as inactive once every one of its revisions has been deregistere
|
|
|
234
220
|
|
|
235
221
|
## Clusters
|
|
236
222
|
|
|
237
|
-
A cluster
|
|
238
|
-
`
|
|
223
|
+
A cluster contains tasks and services. Use `CreateCluster`, `DescribeClusters`, `ListClusters` and
|
|
224
|
+
`DeleteCluster` to manage it.
|
|
239
225
|
|
|
240
226
|
```typescript sim-ecs-clusters
|
|
241
227
|
/**
|
|
@@ -290,13 +276,13 @@ A cluster is named either by its short name or by its full ARN, and the two are
|
|
|
290
276
|
ARN belonging to another account or region names a different cluster. `DescribeClusters` reports it
|
|
291
277
|
as a `MISSING` failure, and `DeleteCluster` refuses it.
|
|
292
278
|
|
|
293
|
-
|
|
294
|
-
|
|
279
|
+
Create a cluster before running a task. This includes the `default` cluster, which Yulin does not
|
|
280
|
+
create automatically.
|
|
295
281
|
|
|
296
282
|
## Running a task
|
|
297
283
|
|
|
298
|
-
`bindContainer`
|
|
299
|
-
handlers run in
|
|
284
|
+
`bindContainer` associates an image with a handler. `RunTask` starts the task and schedules bound
|
|
285
|
+
handlers to run in process.
|
|
300
286
|
|
|
301
287
|
```typescript sim-ecs-run-task
|
|
302
288
|
/**
|
|
@@ -376,9 +362,7 @@ The task stops with a `stopCode` of `TaskFailedToStart` saying that nothing ran.
|
|
|
376
362
|
|
|
377
363
|
### Binding by image repository
|
|
378
364
|
|
|
379
|
-
|
|
380
|
-
the container by hand is the wrong way round. A binding can name the repository instead, and the tag
|
|
381
|
-
is ignored on both sides.
|
|
365
|
+
Use a repository binding when image tags change between builds. Repository matching ignores the tag.
|
|
382
366
|
|
|
383
367
|
```typescript sim-ecs-bind-image-repository
|
|
384
368
|
/**
|
|
@@ -505,9 +489,8 @@ Read inside the handler to get the container's own.
|
|
|
505
489
|
|
|
506
490
|
## The task role
|
|
507
491
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
intercepted by `SimSdk` pick this up without the code under test knowing.
|
|
492
|
+
AWS calls made by a container use the task definition's `taskRoleArn`. An SDK client intercepted by
|
|
493
|
+
`SimSdk` picks up the role from the running handler.
|
|
511
494
|
|
|
512
495
|
```typescript sim-ecs-task-role
|
|
513
496
|
/**
|
|
@@ -600,10 +583,8 @@ alone, since there is no image to pull and no log driver to write to.
|
|
|
600
583
|
|
|
601
584
|
## Container secrets
|
|
602
585
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
the container's environment alongside its declared `environment`. A handler reads them through
|
|
606
|
-
`process.env` like anything else.
|
|
586
|
+
Yulin resolves container `secrets` from simulated Secrets Manager or SSM Parameter Store when the
|
|
587
|
+
task starts. The values appear in `process.env` alongside the declared environment variables.
|
|
607
588
|
|
|
608
589
|
They are read as the task definition's `executionRoleArn` rather than its `taskRoleArn`. That is the
|
|
609
590
|
split real ECS makes. The execution role is what the task agent pulls secrets with before a
|
|
@@ -765,8 +746,7 @@ is reported as it stands, keeping the reason it stopped for.
|
|
|
765
746
|
|
|
766
747
|
## Services
|
|
767
748
|
|
|
768
|
-
|
|
769
|
-
usually is. It is a named service in a cluster, running some number of tasks from a task definition.
|
|
749
|
+
An ECS service maintains a desired number of tasks from one task definition in a cluster.
|
|
770
750
|
|
|
771
751
|
`CreateService` creates one. Its tasks exist as soon as the request is answered and reach `RUNNING`
|
|
772
752
|
on the simulation's background work, as real ECS brings a new service up. The service reports the
|
|
@@ -1,24 +1,16 @@
|
|
|
1
1
|
# Simulated Elastic Load Balancing
|
|
2
2
|
|
|
3
|
-
Yulin
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Only the application load balancer is simulated. A network or gateway load balancer routes below
|
|
16
|
-
HTTP, which nothing here speaks, and `Type: "network"` is refused outright.
|
|
17
|
-
|
|
18
|
-
No TLS is performed anywhere in this. An HTTPS listener holds a certificate and is checked against
|
|
19
|
-
simulated ACM, and everything travels in the clear. See
|
|
20
|
-
[HTTPS listeners and certificates](#https-listeners-and-certificates) for what that leaves a test
|
|
21
|
-
able to conclude.
|
|
3
|
+
Yulin simulates Application Load Balancers, target groups, listeners and listener rules for tests
|
|
4
|
+
and local development. Requests pass through the listener and rule configuration before reaching a
|
|
5
|
+
registered Lambda function or simulated ECS service. Simulated IAM authorizes every operation.
|
|
6
|
+
|
|
7
|
+
Each load balancer receives an AWS-shaped DNS name. A simulated
|
|
8
|
+
[Route 53](https://yulinsim.dev/services/route53/) record can point a local hostname at that name, so
|
|
9
|
+
an HTTP request follows the same routing path as the deployed application.
|
|
10
|
+
|
|
11
|
+
Network and Gateway Load Balancers are not simulated. HTTPS listeners validate their certificates
|
|
12
|
+
against simulated ACM, but Yulin does not perform TLS. Import ELBv2-specific types from
|
|
13
|
+
`@kensio/yulin/elbv2`.
|
|
22
14
|
|
|
23
15
|
## Creating a load balancer
|
|
24
16
|
|
|
@@ -73,9 +65,8 @@ why a load balancer cannot be named starting with `internal-`.
|
|
|
73
65
|
|
|
74
66
|
## Target groups hold functions or addresses
|
|
75
67
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
protocol and port at all.
|
|
68
|
+
`TargetType` determines what a target group can contain. It controls the number and shape of target
|
|
69
|
+
IDs, and whether the group requires a protocol and port.
|
|
79
70
|
|
|
80
71
|
```typescript sim-elbv2-lambda-target-group
|
|
81
72
|
/**
|
|
@@ -178,15 +169,14 @@ console.log(health.TargetHealthDescriptions?.length); // 1
|
|
|
178
169
|
console.log(health.TargetHealthDescriptions?.[0]?.Target.Port); // 8080
|
|
179
170
|
```
|
|
180
171
|
|
|
181
|
-
`TargetType: "instance"` is
|
|
182
|
-
|
|
183
|
-
target type at all is refused for the same reason, since real ELB defaults it to `instance`.
|
|
172
|
+
`TargetType: "instance"` is unsupported because Yulin does not simulate EC2 instances. Omitting
|
|
173
|
+
`TargetType` is also rejected because AWS would default it to `instance`.
|
|
184
174
|
|
|
185
175
|
## Listeners and the rules on them
|
|
186
176
|
|
|
187
|
-
A listener
|
|
188
|
-
|
|
189
|
-
|
|
177
|
+
A listener handles one port and provides the default action when no rule matches. When several
|
|
178
|
+
rules match, the lowest priority number wins. Two rules on the same listener cannot use the same
|
|
179
|
+
priority.
|
|
190
180
|
|
|
191
181
|
```typescript sim-elbv2-listener-rules
|
|
192
182
|
/**
|
|
@@ -1761,7 +1751,7 @@ console.log(created.LoadBalancers?.[0]?.DNSName);
|
|
|
1761
1751
|
// "shop-alb-0000000001.eu-west-2.elb.amazonaws.com"
|
|
1762
1752
|
```
|
|
1763
1753
|
|
|
1764
|
-
##
|
|
1754
|
+
## Supported operations
|
|
1765
1755
|
|
|
1766
1756
|
- `CreateLoadBalancer`, `DescribeLoadBalancers` and `DeleteLoadBalancer`, with a DNS name, ARN,
|
|
1767
1757
|
canonical hosted zone id, scheme and state on every load balancer.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# Simulated EventBridge
|
|
2
2
|
|
|
3
|
-
Yulin
|
|
4
|
-
|
|
3
|
+
Yulin simulates Amazon EventBridge event buses, rules, targets and `PutEvents` for tests and local
|
|
4
|
+
development. Rules can match events, run on a simulated schedule, and deliver to simulated Lambda,
|
|
5
|
+
SQS, SNS or ECS. Event buses and rules are stored in memory, and simulated IAM authorizes every
|
|
6
|
+
operation.
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
advances simulated time. [EventBridge Scheduler](https://yulinsim.dev/services/scheduler/) is a separate service with its own
|
|
9
|
-
docs. EventBridge-specific types are imported from the `@kensio/yulin/eventbridge` subpath.
|
|
8
|
+
[EventBridge Scheduler](https://yulinsim.dev/services/scheduler/) is simulated separately. Import
|
|
9
|
+
EventBridge-specific types from `@kensio/yulin/eventbridge`.
|
|
10
10
|
|
|
11
11
|
## Putting an event onto a bus
|
|
12
12
|
|
|
@@ -142,10 +142,8 @@ console.log(output.FailedEntryCount); // 0
|
|
|
142
142
|
console.log(output.Entries?.[0]?.EventId !== undefined); // true
|
|
143
143
|
```
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
looks exactly like a working call. That is worth knowing before it costs an afternoon, and the
|
|
148
|
-
simulation reproduces it faithfully.
|
|
145
|
+
AWS also accepts and drops an event sent to a bus that does not exist. The entry is not counted as a
|
|
146
|
+
failure, so check the bus name when `PutEvents` succeeds but no rule runs.
|
|
149
147
|
|
|
150
148
|
## Inspecting what a bus received
|
|
151
149
|
|
|
@@ -250,9 +248,8 @@ within the account. A rule ARN on the default bus is
|
|
|
250
248
|
`arn:aws:events:<region>:<account>:rule/<name>`, and a rule on a custom bus carries the bus as well,
|
|
251
249
|
as `rule/<bus>/<name>`.
|
|
252
250
|
|
|
253
|
-
`PutRule` creates
|
|
254
|
-
|
|
255
|
-
and a common surprise.
|
|
251
|
+
`PutRule` creates or updates a rule. An update replaces the stored rule instead of merging fields,
|
|
252
|
+
so omitting the description clears it.
|
|
256
253
|
|
|
257
254
|
`DisableRule` stops a rule matching, and `EnableRule` starts it again. A rule that was off picks up
|
|
258
255
|
from the next event and leaves what it missed behind. `DeleteRule` on a rule that was never there
|
|
@@ -285,10 +282,9 @@ field, the pattern matches when the two lists overlap, and a pattern naming one
|
|
|
285
282
|
event whose `resources` names several. `exists` is about the field and not its members, and a field
|
|
286
283
|
carrying an empty list still exists.
|
|
287
284
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
case-insensitive forms of `prefix` and `suffix`.
|
|
291
|
-
like a pattern that was simply too specific, and the rule would go unnoticed until the deployment.
|
|
285
|
+
`PutRule` rejects unsupported operators instead of storing a pattern that can never match. These
|
|
286
|
+
include `cidr`, `equals-ignore-case`, `wildcard`, `$or`, nested `anything-but`, and the
|
|
287
|
+
case-insensitive forms of `prefix` and `suffix`.
|
|
292
288
|
|
|
293
289
|
## Testing a pattern without a rule
|
|
294
290
|
|
|
@@ -1049,7 +1045,7 @@ events across accounts that way, but nothing here can reach another simulation's
|
|
|
1049
1045
|
treating a foreign ARN as local would let a test pass while the real call crossed a boundary it has
|
|
1050
1046
|
no permission for.
|
|
1051
1047
|
|
|
1052
|
-
##
|
|
1048
|
+
## Supported operations
|
|
1053
1049
|
|
|
1054
1050
|
- `CreateEventBus`, `DeleteEventBus`, `DescribeEventBus`, `ListEventBuses` and `PutEvents`.
|
|
1055
1051
|
- `PutRule`, `DeleteRule`, `DescribeRule`, `ListRules`, `EnableRule`, `DisableRule` and
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
# Simulated Kinesis Data Firehose
|
|
2
2
|
|
|
3
|
-
Yulin
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
event and assert on the Object it landed in, without an AWS account and without waiting five minutes
|
|
7
|
-
for a buffer to flush.
|
|
3
|
+
Yulin simulates Kinesis Data Firehose delivery streams in memory. A stream accepts records directly
|
|
4
|
+
or reads them from simulated Kinesis, buffers them, and writes each completed buffer to simulated S3.
|
|
5
|
+
Advance simulated time to flush interval-based buffers without waiting in real time.
|
|
8
6
|
|
|
9
7
|
Firehose specific types are imported from the `@kensio/yulin/firehose` subpath.
|
|
10
8
|
|
|
11
9
|
## Putting a record and finding the Object
|
|
12
10
|
|
|
13
|
-
`simAws.firehose()`
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
`simAws.firehose()` returns Firehose for the default account and region. Create the destination
|
|
12
|
+
bucket and delivery role before the delivery stream. Advance the clock past the buffering interval
|
|
13
|
+
to write the buffered records.
|
|
16
14
|
|
|
17
15
|
```typescript sim-firehose-put-and-deliver
|
|
18
16
|
/**
|
|
@@ -93,15 +91,13 @@ const { Contents } = await simAws
|
|
|
93
91
|
console.log(Contents?.[0]?.Key);
|
|
94
92
|
```
|
|
95
93
|
|
|
96
|
-
|
|
97
|
-
delivered. That delay is what a Firehose pipeline is built around.
|
|
94
|
+
`PutRecord` returns a record ID immediately. The bucket remains empty until the buffer is delivered.
|
|
98
95
|
|
|
99
96
|
## Buffering
|
|
100
97
|
|
|
101
|
-
A delivery stream
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
below does exactly that.
|
|
98
|
+
A delivery stream flushes when it reaches `SizeInMBs` or `IntervalInSeconds`, whichever comes first.
|
|
99
|
+
Firehose concatenates all records in the buffer into one S3 object. Add a newline to each record if
|
|
100
|
+
the object should contain separate lines.
|
|
105
101
|
|
|
106
102
|
`IntervalInSeconds` runs from the first record of a buffer. The default is 300 seconds and the
|
|
107
103
|
default size is 5 MB, as they are on real Firehose.
|
|
@@ -224,8 +220,8 @@ the background scheduler, the way real Firehose answers the producer before it w
|
|
|
224
220
|
|
|
225
221
|
## The Object key
|
|
226
222
|
|
|
227
|
-
|
|
228
|
-
|
|
223
|
+
Object keys contain the configured `Prefix`, UTC date path, delivery stream name, version, delivery
|
|
224
|
+
time, and a random suffix:
|
|
229
225
|
|
|
230
226
|
```
|
|
231
227
|
<Prefix>YYYY/MM/DD/HH/<delivery-stream-name>-<version>-YYYY-MM-DD-HH-MM-SS-<random>
|
|
@@ -234,15 +230,15 @@ delivery time and a random string:
|
|
|
234
230
|
A delivery stream with no `Prefix` gets the bare date path. The version is `1` and stays there,
|
|
235
231
|
since a delivery stream's configuration is fixed once it is created.
|
|
236
232
|
|
|
237
|
-
|
|
238
|
-
|
|
233
|
+
The date path and timestamp use simulated time. Set the clock before delivery to make the prefix
|
|
234
|
+
predictable.
|
|
239
235
|
|
|
240
236
|
## Reading from a Kinesis stream
|
|
241
237
|
|
|
242
|
-
A delivery stream can
|
|
238
|
+
A delivery stream can read records from simulated Kinesis. Create it with a
|
|
243
239
|
`DeliveryStreamType` of `KinesisStreamAsSource` and a `KinesisStreamSourceConfiguration` naming the
|
|
244
|
-
stream and
|
|
245
|
-
|
|
240
|
+
stream and its read role. Records added after the delivery stream is created are buffered and sent
|
|
241
|
+
to S3.
|
|
246
242
|
|
|
247
243
|
```typescript sim-firehose-kinesis-source
|
|
248
244
|
/**
|
|
@@ -382,11 +378,8 @@ Creating a delivery stream hands Firehose the destination `RoleARN`, and the sou
|
|
|
382
378
|
where it reads a Kinesis stream. `CreateDeliveryStream` authorizes `iam:PassRole` against each of
|
|
383
379
|
them. See [passing a Role to a service](https://yulinsim.dev/services/iam/#passing-a-role-to-a-service) in the IAM docs.
|
|
384
380
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
delivery. Real
|
|
388
|
-
Firehose answered that `PutRecord` minutes earlier, and what became of the buffer reaches the
|
|
389
|
-
producer through CloudWatch. The simulator keeps the failure for a test to read instead.
|
|
381
|
+
Delivery uses the delivery stream's `RoleARN`, not the identity that called `PutRecord`. The role
|
|
382
|
+
needs `s3:PutObject` on the destination. Failed writes appear in `getDeliveryFailures()`.
|
|
390
383
|
|
|
391
384
|
```typescript sim-firehose-permissions
|
|
392
385
|
/**
|
|
@@ -507,9 +500,8 @@ what a test checking the denial does. Anything else is also warned about on the
|
|
|
507
500
|
`KinesisStreamSourceConfiguration` and `Tags` are read. A `Ref` gives the delivery stream name and
|
|
508
501
|
`Fn::GetAtt` on `Arn` gives the ARN, the way real CloudFormation publishes them.
|
|
509
502
|
|
|
510
|
-
A CDK `DeliveryStream` with an `S3Bucket` destination synthesizes
|
|
511
|
-
|
|
512
|
-
synthesized template, and nothing here has to be written by hand.
|
|
503
|
+
A CDK `DeliveryStream` with an `S3Bucket` destination synthesizes this resource, its delivery role,
|
|
504
|
+
and the role policy. Deploy that synthesized template directly into simulated CloudFormation.
|
|
513
505
|
|
|
514
506
|
```typescript sim-firehose-cloudformation
|
|
515
507
|
/**
|
|
@@ -627,9 +619,9 @@ A `DeliveryStreamType` of `KinesisStreamAsSource` deploys as well. The
|
|
|
627
619
|
`KinesisStreamSourceConfiguration` names the stream by ARN and the Role to read it as, and a stack
|
|
628
620
|
declaring the stream beside the delivery stream archives what a producer puts on it.
|
|
629
621
|
|
|
630
|
-
A delivery stream
|
|
631
|
-
`stack.skippedResources`,
|
|
632
|
-
S3
|
|
622
|
+
A delivery stream with an unsupported source or destination is recorded in
|
|
623
|
+
`stack.skippedResources`, while the rest of the stack deploys. This includes destinations other than
|
|
624
|
+
S3 and unsupported source properties such as
|
|
633
625
|
`MSKSourceConfiguration` or `DatabaseSourceConfiguration`. The source property is what the skip is
|
|
634
626
|
decided on, because a template that leaves `DeliveryStreamType` out gets `DirectPut` by default.
|
|
635
627
|
|