Network connectors (Lambda Core service) - #37
Merged
Merged
Conversation
All five Lambda Core operations, the PENDING to ACTIVE state machine on the clock, the asynchronous DELETING window, and an injection lever for each of the seven reason codes. Connectors are a second service model, not a second resource: different API version, different URI family, and PascalCase members where Lambda Microvms uses lowercase. One m80 process serves both because both sign as lambda. Four members are modeled optional and enforced anyway — ClientToken, OperatorRole, NetworkProtocol and AssociatedComputeResourceTypes, each recorded live. A client written from the model alone gets four 400s in a row. ClientToken is the strangest of them: the model marks it optional and tags it idempotencyToken, which normally means the SDK generates one. Three findings came out of running the fixtures against a real implementation, all of them things the model would have led me to get wrong. Bad requests come back two ways. Model constraints — list lengths, enum membership — are answered by a validation layer in front of the service, as ValidationException in AWS's standard wording, with the member path in camelCase even though every wire member is PascalCase. ValidationException is not listed as an error of any connector operation in the model. The four enforced-but-optional members are service logic and come back as InvalidParameterValueException with prose. That layer runs first and in full. The too-many-subnets probe sent seventeen subnets and also omitted ClientToken, OperatorRole, NetworkProtocol and AssociatedComputeResourceTypes, and the service still answered about subnetIds. Precedence was the one thing I had assumed was m80's to choose; it is recorded. validate now runs constraints to exhaustion before the service's required-member logic gets a look. Not-found answers with a capital Message, matching Lambda Core's own member style rather than the lowercase message the other service uses, and echoes the ARN it built from whatever identifier arrived rather than the identifier itself. The four responses carry four different member sets, which is the model rather than an accident of recording, and absent means absent: a connector that has never been updated has no LastUpdateStatus at all. List omits NextMarker entirely, so a client looping until the marker is null would loop forever. Type is on the list summary and nowhere else. The seven reason codes are the point of the lever. None can be provoked against real AWS on demand — you cannot ask EC2 to run a subnet out of addresses — so without injection a consumer's whole error path stays untested. One test per code, and the lever is consumed on use so one failing connector does not poison a suite running several. Conformance: 66 pass, 0 fail, 27 of 29 operations exercised, up from 58 and 24. Only ListTags and UntagResource remain, both #14. Closes #13 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X6T4MeDN1RBiWaNtud6x77
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
All five Lambda Core operations, the PENDING → ACTIVE state machine on the clock, the asynchronous DELETING window, and an injection lever for each of the seven reason codes. Based on main.
Connectors are a second service model, not a second resource: different API version, different URI family, and PascalCase members where Lambda Microvms uses lowercase.
Three things the model would have led me to get wrong
All three surfaced by running the recorded fixtures against a real implementation — the same class the handoff warned about, and the reason I ran conformance before believing any of it.
Bad requests come back two ways. Model constraints — list lengths, enum membership — are answered by a validation layer in front of the service, as
ValidationExceptionin AWS's standard wording, with the member path in camelCase even though every wire member is PascalCase:ValidationExceptionis not listed as an error of any connector operation in the Lambda Core model. The four enforced-but-modeled-optional members are service logic instead, and come back asInvalidParameterValueExceptionwith prose.That layer runs first, and in full. Precedence was the one thing I had assumed was m80's to choose. It isn't. The too-many-subnets probe sent seventeen subnets and omitted
ClientToken,OperatorRole,NetworkProtocolandAssociatedComputeResourceTypes— four of the enforced members missing — and the service still answered aboutsubnetIds.validatenow runs constraints to exhaustion before the service's required-member logic gets a look.Not-found uses a capital
Message— Lambda Core's own member style, not the lowercasemessagethe other service uses — and echoes the ARN it built from whatever identifier arrived rather than the identifier itself.Modeled optional, enforced anyway
ClientToken,OperatorRole,NetworkProtocol,AssociatedComputeResourceTypes. A client written from the model alone gets four 400s in a row.ClientTokenis the strangest: the model marks it optional and tags itidempotencyToken, which normally means the SDK generates one for you.Response shapes
Four responses, four different member sets — the model, not an accident of recording. Create and Delete return a base six; Get adds
LastModifiedand the state/update status members; Update addsLastModifiedand update status but notStateReason; only the list summary carriesType. Absent means absent: a connector that has never been updated has noLastUpdateStatusat all, and emitting one asnullwould diverge on every read. List omitsNextMarkerentirely, so a client looping until the marker is null would loop forever.The injection lever
The seven
NetworkConnectorStateReasonCodevalues are the point. None can be provoked against real AWS on demand — you cannot ask EC2 to run a subnet out of addresses — so without injection a consumer's whole error-handling path stays untested, and KubeMicroVM's MicroVMNetwork reconciler has visible handling for them. One test per code; the lever is consumed on use so one failing connector does not poison a suite running several.It is a Go API, matching the images build lever. I deliberately did not add m80-only cases to the conformance suite — that suite is a fidelity instrument measured against real AWS, and injected failures have no recorded fixture and never could. The acceptance's "one injected failure per reason code" is met by unit tests. If you want the lever drivable over HTTP for #18's offline drift UAT, that is a small addition and probably belongs with the rest of the drift levers.
Result
66 pass, 0 fail, 27/29 operations exercised, up from 58 and 24. Only
ListTagsandUntagResourceremain, both #14.go build,go vet,gofmt,go test -raceclean.Closes #13