Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 54 additions & 1 deletion docs/services.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ This document lists every service and operation available in CloudEmu across all
| 23 | AI Search | — | `search` (Microsoft.Search) | — |
| 24 | Container Orchestration | `ecs` | — | — |
| 25 | DNS Resolver | `route53resolver` | — | — |
| 26 | Application Networking | `vpclattice` | — | — |

---

Expand Down Expand Up @@ -2310,6 +2311,57 @@ policies are stored verbatim without RAM enforcement.

---

## 26. Application Networking

**Driver interface:** `services/vpclattice/driver/driver.go`
**AWS:** VPC Lattice (REST-JSON, `awsRestjson1`) | **Azure:** — | **GCP:** —

AWS-only. Real `aws-sdk-go-v2/service/vpclattice` clients work against the
SDK-compat server (`awsserver.Drivers{VPCLattice: cloud.VPCLattice}`). Full
parity: **all 73 SDK operations**, no stubs.

Unlike the AWS JSON 1.1 services, VPC Lattice uses **REST-JSON**: the operation
is selected by HTTP method + URL path (e.g. `POST /services`, `GET
/services/{id}/listeners/{id}`, `PATCH /servicenetworks/{id}`) rather than an
`X-Amz-Target` header. The handler gates on path root + method + **identifier
shape**, so a path-style S3 object op on a bucket named like a Lattice root
(e.g. `GET /services/mykey`) falls through to the S3 catch-all — only a
Lattice-shaped id (a known prefix or a `vpc-lattice` ARN) is claimed. The single
unavoidable residual is a bare `GET /<root>` (list) vs. an S3 list-bucket on an
identically-named bucket. Identifiers accept either a bare ID or a full ARN. Union-typed fields
(a listener's `defaultAction`, a rule's `match`/`action`, a target group's
`config`, a resource configuration's `resourceConfigurationDefinition`) are
stored as raw JSON and echoed back verbatim. Create-time tags are persisted;
deletes block on live service-network associations and cascade contained
children (service→listeners→rules); association counts are recomputed on read
and skip targets that no longer exist.

| Family | Operations |
|--------|-----------|
| Service networks | Create/Get/Update/Delete/ListServiceNetwork(s) |
| Services | Create/Get/Update/Delete/ListService(s) |
| Listeners | Create/Get/Update/Delete/ListListener(s) |
| Rules | Create/Get/Update/Delete/ListRule(s), BatchUpdateRule |
| Target groups & targets | Create/Get/Update/Delete/ListTargetGroup(s), Register/Deregister/ListTargets |
| Service-network associations | Create/Get/Update/Delete/List ServiceNetworkVpcAssociation(s) + ListServiceNetworkVpcEndpointAssociations; Create/Get/Delete/List ServiceNetworkService & ServiceNetworkResource Association(s) |
| Resource configurations | Create/Get/Update/Delete/ListResourceConfiguration(s) |
| Resource gateways | Create/Get/Update/Delete/ListResourceGateway(s) |
| Resource endpoint associations | List/DeleteResourceEndpointAssociation(s) |
| Access-log subscriptions | Create/Get/Update/Delete/ListAccessLogSubscription(s) |
| Auth & resource policies | Put/Get/DeleteAuthPolicy, Put/Get/DeleteResourcePolicy |
| Domain verifications | Start/Get/Delete/ListDomainVerification(s) |
| Tagging | TagResource, UntagResource, ListTagsForResource |

*Accepted but not simulated* (stored/echoed so SDK calls succeed, no behavioral
effect): resources are created directly in a terminal `ACTIVE`/`PENDING` status
(no async state machine); VPC-endpoint and resource-endpoint associations are a
managed surface returned as empty lists; `Forward`/health-check targeting is
stored but not used to route real traffic.

**Total: 73 operations.**

---

## Provider-specific resources

Resources below are served for one provider only, because the concept exists in
Expand Down Expand Up @@ -2423,7 +2475,8 @@ still sees success.
| AI Search — Azure AI Search (control + data plane) | 53 |
| Container Orchestration — AWS ECS | 37 |
| DNS Resolver — AWS Route 53 Resolver | 72 |
| **Grand Total** | **1634** (+138 optional) |
| Application Networking — AWS VPC Lattice | 73 |
| **Grand Total** | **1707** (+138 optional) |

Optional operations are capabilities a driver may implement but is not required
to; see the sections marked "optional capability". They are counted separately
Expand Down
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.5.0
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.4
github.com/Azure/azure-sdk-for-go/sdk/storage/azqueue v1.0.1
github.com/aws/aws-sdk-go-v2 v1.43.3
github.com/aws/aws-sdk-go-v2 v1.43.4
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.14
github.com/aws/aws-sdk-go-v2/config v1.32.14
github.com/aws/aws-sdk-go-v2/credentials v1.19.14
Expand Down Expand Up @@ -79,6 +79,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/sqs v1.42.27
github.com/aws/aws-sdk-go-v2/service/ssm v1.71.0
github.com/aws/aws-sdk-go-v2/service/sts v1.41.10
github.com/aws/aws-sdk-go-v2/service/vpclattice v1.25.5
github.com/aws/smithy-go v1.27.6
github.com/databricks/databricks-sdk-go v0.144.0
github.com/fxamacker/cbor/v2 v2.9.1
Expand Down Expand Up @@ -109,8 +110,8 @@ require (
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.34 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.34 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.35 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.35 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.31 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.14 // indirect
Expand Down
14 changes: 8 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0/go.mod h1:vB2GH9GAYYJTO3mEn8oYwzEdhlayZIdQz6zdzgUIRvA=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 h1:0s6TxfCu2KHkkZPnBfsQ2y5qia0jl3MMrmBhu3nCOYk=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc=
github.com/aws/aws-sdk-go-v2 v1.43.3 h1:XJIcfv8uDs2ukdQsoAC8/Ebu1ejxwzlayl2ZsiFns2A=
github.com/aws/aws-sdk-go-v2 v1.43.3/go.mod h1:70vwSy16txshwG+g55WkpgPKDIByzHI8ccBsOteo3bQ=
github.com/aws/aws-sdk-go-v2 v1.43.4 h1:b9FTvbRwy+JCsfp2Wp6wV/KbOx3Aj7nkoFb2cRX0IhE=
github.com/aws/aws-sdk-go-v2 v1.43.4/go.mod h1:70vwSy16txshwG+g55WkpgPKDIByzHI8ccBsOteo3bQ=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.14 h1:3IZY0XAJquT3aHzbkHfPzy4ACPcEjVG0x87KOwtpqGY=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.14/go.mod h1:zwM6veDkhGgQFqkBy+uT28AAYpLu+uFMlPl+rCg/73E=
github.com/aws/aws-sdk-go-v2/config v1.32.14 h1:opVIRo/ZbbI8OIqSOKmpFaY7IwfFUOCCXBsUpJOwDdI=
Expand All @@ -126,10 +126,10 @@ github.com/aws/aws-sdk-go-v2/credentials v1.19.14 h1:n+UcGWAIZHkXzYt87uMFBv/l8TH
github.com/aws/aws-sdk-go-v2/credentials v1.19.14/go.mod h1:cJKuyWB59Mqi0jM3nFYQRmnHVQIcgoxjEMAbLkpr62w=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21 h1:NUS3K4BTDArQqNu2ih7yeDLaS3bmHD0YndtA6UP884g=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21/go.mod h1:YWNWJQNjKigKY1RHVJCuupeWDrrHjRqHm0N9rdrWzYI=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.34 h1:vuIfjzoeqhQMGJyOBU3t0ZEjn2jrN8Bbg1N4CgjzM5Q=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.34/go.mod h1:hP28cN4CPJLZHirdQPrZR50JcLN4ApRJP2tzG8cRlhY=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.34 h1:9faHsnqxJ1vDvB4wMZy/ajIDyz5QhllQjjc72RJpXAw=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.34/go.mod h1:Yp6nIyejpa23nzlB/LhT63KTla9Jdi06nv/HH/OkAH8=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.35 h1:kzVuGlatQtYinwBJEEyLAbggepCoavosiaHHX9+fD+c=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.35/go.mod h1:0yLx0yEI+SfqeJMPvOtIEFoZbiQYXMGszBueiutQyaI=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.35 h1:WK6CjihTuLisCjSKKbildJ79sGZZgbBz3iNa7VsKIhU=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.35/go.mod h1:KYleN57luLoe97R7vTnx8PMcVrr9gAcRECtOjl91DNg=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 h1:qYQ4pzQ2Oz6WpQ8T3HvGHnZydA72MnLuFK9tJwmrbHw=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6/go.mod h1:O3h0IK87yXci+kg6flUKzJnWeziQUKciKrLjcatSNcY=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.31 h1:3GUprIsfmGcC5SACIyB0e7E0BM1O1b3Erl5CePYIAeQ=
Expand Down Expand Up @@ -224,6 +224,8 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.19 h1:dzztQ1YmfPrxdrOiuZRMF6f
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.19/go.mod h1:YO8TrYtFdl5w/4vmjL8zaBSsiNp3w0L1FfKVKenZT7w=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.10 h1:p8ogvvLugcR/zLBXTXrTkj0RYBUdErbMnAFFp12Lm/U=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.10/go.mod h1:60dv0eZJfeVXfbT1tFJinbHrDfSJ2GZl4Q//OSSNAVw=
github.com/aws/aws-sdk-go-v2/service/vpclattice v1.25.5 h1:MYTOPMWy6a0zO3LxEAJbh/6FebfIRRjmR/CUgj3raLs=
github.com/aws/aws-sdk-go-v2/service/vpclattice v1.25.5/go.mod h1:7AHfzbcrbB4ZrwONKrCNdvIwTpyoGL+2CGSNYx1+wko=
github.com/aws/smithy-go v1.27.6 h1:0zjT8jgK3jbrTT7JJ3EE6JsMhX8JTrZ+f1sEndYDXrA=
github.com/aws/smithy-go v1.27.6/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
Expand Down
3 changes: 3 additions & 0 deletions providers/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"github.com/stackshy/cloudemu/v2/providers/aws/sqs"
"github.com/stackshy/cloudemu/v2/providers/aws/ssm"
"github.com/stackshy/cloudemu/v2/providers/aws/vpc"
"github.com/stackshy/cloudemu/v2/providers/aws/vpclattice"
"github.com/stackshy/cloudemu/v2/services/resourcediscovery"
)

Expand Down Expand Up @@ -145,6 +146,7 @@ type Provider struct {
SageMaker *sagemaker.Mock
SSM *ssm.Mock
ECS *ecs.Mock
VPCLattice *vpclattice.Mock
Route53Resolver *route53resolver.Mock
ResourceDiscovery *resourcediscovery.Engine
AccountID string
Expand Down Expand Up @@ -183,6 +185,7 @@ func New(opts ...config.Option) *Provider {
SageMaker: sagemaker.New(o),
SSM: ssm.New(o),
ECS: ecs.New(o),
VPCLattice: vpclattice.New(o),
Route53Resolver: route53resolver.New(o),
AccountID: o.AccountID,
Region: o.Region,
Expand Down
102 changes: 102 additions & 0 deletions providers/aws/vpclattice/access_logs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package vpclattice

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[STRUCTURE.md §3] Smashed multi-word filenames should be snake_case: accesslogs.goaccess_logs.go, and likewise service_networks.go, resource_gateways.go, resource_configs.go, domain_verifications.go, target_groups.go — in BOTH providers/aws/vpclattice/ and server/aws/vpclattice/ (a feature keeps the same filename across layers). New services now go through the STRUCTURE.md loop, so worth doing here.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[STRUCTURE.md §3] Fixed. Renamed to snake_case in both layers: access_logs.go, service_networks.go, resource_gateways.go, resource_configs.go, domain_verifications.go, target_groups.go (via git mv).


import (
"context"

"github.com/stackshy/cloudemu/v2/errors"
"github.com/stackshy/cloudemu/v2/internal/idgen"
"github.com/stackshy/cloudemu/v2/services/vpclattice/driver"
)

func accessLogSubNotFound(id string) error {
return errors.Newf(errors.NotFound, "access log subscription %q not found", id)
}

func cloneAccessLogSub(a *driver.AccessLogSubscription) driver.AccessLogSubscription { return *a }

func (m *Mock) CreateAccessLogSubscription(
_ context.Context, resourceIdentifier, destinationARN, logType string, tags map[string]string,
) (*driver.AccessLogSubscription, error) {
m.mu.Lock()
defer m.mu.Unlock()

id := idgen.GenerateID("als-")
a := &driver.AccessLogSubscription{
ID: id,
ARN: m.arn("accesslogsubscription/" + id),
DestinationARN: destinationARN,
ResourceID: idFromIdentifier(resourceIdentifier),
ResourceARN: resourceIdentifier,
ServiceNetworkLogType: logType,
CreatedAt: m.now(),
LastUpdatedAt: m.now(),
}
m.accessLogSubs.Set(id, a)
m.writeTags(a.ARN, tags)

out := cloneAccessLogSub(a)

return &out, nil
}

func (m *Mock) GetAccessLogSubscription(_ context.Context, identifier string) (*driver.AccessLogSubscription, error) {
m.mu.Lock()
defer m.mu.Unlock()

id := idFromIdentifier(identifier)

a, ok := m.accessLogSubs.Get(id)
if !ok {
return nil, accessLogSubNotFound(id)
}

out := cloneAccessLogSub(a)

return &out, nil
}

func (m *Mock) UpdateAccessLogSubscription(
_ context.Context, identifier, destinationARN string,
) (*driver.AccessLogSubscription, error) {
m.mu.Lock()
defer m.mu.Unlock()

id := idFromIdentifier(identifier)

a, ok := m.accessLogSubs.Get(id)
if !ok {
return nil, accessLogSubNotFound(id)
}

if destinationARN != "" {
a.DestinationARN = destinationARN
}

a.LastUpdatedAt = m.now()

out := cloneAccessLogSub(a)

return &out, nil
}

func (m *Mock) DeleteAccessLogSubscription(_ context.Context, identifier string) error {
m.mu.Lock()
defer m.mu.Unlock()

id := idFromIdentifier(identifier)

if !m.accessLogSubs.Has(id) {
return accessLogSubNotFound(id)
}

m.accessLogSubs.Delete(id)

return nil
}

func (m *Mock) ListAccessLogSubscriptions(_ context.Context) ([]driver.AccessLogSubscription, error) {
m.mu.Lock()
defer m.mu.Unlock()

return sortedValues(m.accessLogSubs.All(), cloneAccessLogSub), nil
}
Loading
Loading