Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
e5ec174
Add Azure AI Emulation (CognitiveServices + Machine Learning, ARM + D…
thzgajendra Jul 11, 2026
afc6b0e
ci: add GitHub Actions workflow for build, vet, test, and lint
NitinKumar004 Jul 12, 2026
fa1d3b2
ci: install golangci-lint v2 via official script (advisory job)
NitinKumar004 Jul 12, 2026
e44fd55
feat(aws): add STS SDK-compat query-protocol handler
NitinKumar004 Jul 12, 2026
794453d
ci: slim to one lean job (build·vet·test), PR-only + push-to-master
NitinKumar004 Jul 12, 2026
3caa41d
feat(s3): add multipart, tagging, and versioning wire operations
NitinKumar004 Jul 12, 2026
c4278a9
ci: split into parallel per-check jobs + add a security workflow
NitinKumar004 Jul 12, 2026
4a3dd2d
feat(server): add Azure Queue Storage + Table Storage SDK-compat (#243)
NitinKumar004 Jul 12, 2026
0678096
ci: make advisory scanners report-only (green with warnings)
NitinKumar004 Jul 12, 2026
7951cbc
fix(sts): gofmt + robust roleNameFromArn trailing-slash handling
NitinKumar004 Jul 12, 2026
ba1d241
ci: fix go vet failure + combine Build & Vet to cut CI time
NitinKumar004 Jul 12, 2026
5581528
ci: cache Go build+module dirs with restore-keys for fast repeat runs
NitinKumar004 Jul 12, 2026
29f85b5
fix(s3): sort multipart parts, map NoSuchUpload, reject empty Complete
NitinKumar004 Jul 12, 2026
c859068
test(s3): assert out-of-order multipart parts assemble by PartNumber
NitinKumar004 Jul 12, 2026
85ee5f6
fix(azure-table): support UpsertEntity; document Queue/Blob shared-ho…
NitinKumar004 Jul 12, 2026
1086e72
Merge pull request #261 from stackshy/feat/ci-github-actions
NitinKumar004 Jul 12, 2026
3716654
Merge pull request #264 from stackshy/feat/s3-advanced-ops
NitinKumar004 Jul 12, 2026
23b479a
Merge pull request #262 from stackshy/feat/sts-sdk-compat
NitinKumar004 Jul 12, 2026
6787eca
Merge pull request #265 from stackshy/feat/azure-queue-table
NitinKumar004 Jul 12, 2026
a3180f3
feat(ssm): add AWS SSM Parameter Store SDK-compat service (#239)
NitinKumar004 Jul 12, 2026
bdd3466
fix(ssm): validate parameter labels + thread context in Put retry
NitinKumar004 Jul 12, 2026
848a505
Merge pull request #263 from stackshy/feat/ssm-parameterstore
NitinKumar004 Jul 12, 2026
21ec949
chore(v2)!: bump module path to github.com/stackshy/cloudemu/v2
NitinKumar004 Jul 12, 2026
c45972c
refactor(v2): move azureai → services/azureai
NitinKumar004 Jul 12, 2026
aa9d5e8
refactor(v2): move azuresearch → services/azuresearch
NitinKumar004 Jul 12, 2026
c1f0325
refactor(v2): move bedrock → services/bedrock
NitinKumar004 Jul 12, 2026
a2d2ddf
refactor(v2): move cache → services/cache
NitinKumar004 Jul 12, 2026
ce3eb77
refactor(v2): move compute → services/compute
NitinKumar004 Jul 12, 2026
12121ec
refactor(v2): move containerregistry → services/containerregistry
NitinKumar004 Jul 12, 2026
910aa39
refactor(v2): move database → services/database
NitinKumar004 Jul 12, 2026
7941f72
refactor(v2): move databricks → services/databricks
NitinKumar004 Jul 12, 2026
ddc81b5
refactor(v2): move dns → services/dns
NitinKumar004 Jul 12, 2026
13e5c2b
refactor(v2): move eventbus → services/eventbus
NitinKumar004 Jul 12, 2026
3aff960
refactor(v2): move iam → services/iam
NitinKumar004 Jul 12, 2026
849ca64
refactor(v2): move loadbalancer → services/loadbalancer
NitinKumar004 Jul 12, 2026
3f7954b
refactor(v2): move logging → services/logging
NitinKumar004 Jul 12, 2026
a8f9061
refactor(v2): move messagequeue → services/messagequeue
NitinKumar004 Jul 12, 2026
b5beb44
refactor(v2): move monitoring → services/monitoring
NitinKumar004 Jul 12, 2026
aeee56e
refactor(v2): move networking → services/networking
NitinKumar004 Jul 12, 2026
3374336
refactor(v2): move notification → services/notification
NitinKumar004 Jul 12, 2026
5980c1f
refactor(v2): move parameterstore → services/parameterstore
NitinKumar004 Jul 12, 2026
886ddf7
refactor(v2): move relationaldb → services/relationaldb
NitinKumar004 Jul 12, 2026
6801c95
refactor(v2): move sagemaker → services/sagemaker
NitinKumar004 Jul 12, 2026
3090af5
refactor(v2): move secrets → services/secrets
NitinKumar004 Jul 12, 2026
08e7a19
refactor(v2): move serverless → services/serverless
NitinKumar004 Jul 12, 2026
c9a6656
refactor(v2): move storage → services/storage
NitinKumar004 Jul 12, 2026
0a483e5
refactor(v2): move tablestorage → services/tablestorage
NitinKumar004 Jul 12, 2026
b6a6edc
refactor(v2): move vertexai → services/vertexai
NitinKumar004 Jul 12, 2026
3571b56
refactor(v2): move kubernetes → services/kubernetes
NitinKumar004 Jul 12, 2026
8d8ee97
refactor(v2): move cost → services/cost
NitinKumar004 Jul 12, 2026
41f5909
refactor(v2): move resourcediscovery → services/resourcediscovery
NitinKumar004 Jul 12, 2026
6f76949
refactor(v2): move chaos → features/chaos
NitinKumar004 Jul 12, 2026
7d42a08
refactor(v2): move inject → features/inject
NitinKumar004 Jul 12, 2026
132bb90
refactor(v2): move metrics → features/metrics
NitinKumar004 Jul 12, 2026
5aa13cd
refactor(v2): move ratelimit → features/ratelimit
NitinKumar004 Jul 12, 2026
761f05b
refactor(v2): move recorder → features/recorder
NitinKumar004 Jul 12, 2026
d23ca93
refactor(v2): move topology → features/topology
NitinKumar004 Jul 12, 2026
99e1547
refactor(v2): move pagination → internal/pagination
NitinKumar004 Jul 12, 2026
1e4a31c
refactor(v2): move statemachine → internal/statemachine
NitinKumar004 Jul 12, 2026
9c67a35
refactor(v2): update AWS provider imports to v2 layout
NitinKumar004 Jul 12, 2026
8dd4161
refactor(v2): update Azure provider imports to v2 layout
NitinKumar004 Jul 12, 2026
91d3257
refactor(v2): update GCP provider imports to v2 layout
NitinKumar004 Jul 12, 2026
0821ccf
refactor(v2): update AWS server imports to v2 layout
NitinKumar004 Jul 12, 2026
67592a0
refactor(v2): update Azure server imports to v2 layout
NitinKumar004 Jul 12, 2026
6a0c36c
refactor(v2): update GCP server imports to v2 layout
NitinKumar004 Jul 12, 2026
3a6f400
refactor(v2): update server core/wire imports to v2 layout
NitinKumar004 Jul 12, 2026
52c0c1e
refactor(v2): update examples imports to v2 layout
NitinKumar004 Jul 12, 2026
eb440bf
refactor(v2): update internal helper imports to v2 layout
NitinKumar004 Jul 12, 2026
7dafb8a
docs(v2): rewrite package overview for the new services/features/prov…
NitinKumar004 Jul 12, 2026
2337f73
docs(v2): update README import paths and badges to the v2 module
NitinKumar004 Jul 12, 2026
8a3b1db
docs(v2): update in-repo docs import paths to the v2 module layout
NitinKumar004 Jul 12, 2026
5b07503
fix(security): bound RunInstances count + drop sized alloc in FindNei…
NitinKumar004 Jul 12, 2026
d411048
Merge pull request #268 from stackshy/feat/v2-restructure
NitinKumar004 Jul 12, 2026
c0a5a2d
docs(v2): update in-repo docs to the new services/features layout
NitinKumar004 Jul 12, 2026
5d775eb
docs(v2): fix remaining bare service-package refs
NitinKumar004 Jul 12, 2026
cabe2d2
Merge pull request #269 from stackshy/docs/v2-inrepo-paths
NitinKumar004 Jul 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
111 changes: 111 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
name: CI

# Public repo → GitHub-hosted Actions are free. Kept fast: Build and Vet share
# one job so `go vet` reuses the compile cache `go build` just populated
# (standalone `go vet ./...` recompiles everything and is slow). Test runs in
# parallel; the quick checks (Tidy/Format) give sub-minute feedback. Every job
# restores the Go build+module cache. One run per PR (+ push to master);
# superseded runs cancel.
on:
pull_request:
push:
branches: [master]

permissions:
contents: read

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build-vet:
name: Build & Vet
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.25"
cache: false
# Manual cache with restore-keys so a changed go.sum still restores the
# previous build+module cache (only the changed deps recompile) instead
# of a full cold compile of the whole cloud-SDK dependency tree.
- uses: actions/cache@v4
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: go-${{ runner.os }}-${{ hashFiles('**/go.sum') }}
restore-keys: |
go-${{ runner.os }}-
- name: go build
run: go build ./...
- name: go vet (reuses the build cache)
run: go vet ./...

test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.25"
cache: false
- uses: actions/cache@v4
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: go-${{ runner.os }}-${{ hashFiles('**/go.sum') }}
restore-keys: |
go-${{ runner.os }}-
- run: go test ./...

tidy:
name: Tidy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.25"
cache: true
- name: go mod tidy is clean
run: |
go mod tidy
git diff --exit-code go.mod go.sum

format:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.25"
cache: true
- name: gofmt (report-only)
run: |
unformatted="$(gofmt -l .)"
if [ -n "$unformatted" ]; then
echo "::warning::gofmt needed on the following files (advisory):"
echo "$unformatted"
else
echo "all files gofmt-clean"
fi

lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.25"
cache: true
- name: install golangci-lint v2
run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b "$(go env GOPATH)/bin"
- name: golangci-lint run (report-only)
run: "$(go env GOPATH)/bin/golangci-lint run --timeout=9m ./... || echo '::warning::golangci-lint reported findings (advisory)'"
83 changes: 83 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Security

# Security scanning, separate from CI so it runs in parallel and is easy to
# read. Each scanner is its own cached job. Runs on PRs, on push to master, and
# weekly (so newly-disclosed CVEs are caught even without a push).
on:
pull_request:
push:
branches: [master]
schedule:
- cron: "0 6 * * 1" # Mondays 06:00 UTC

permissions:
contents: read

concurrency:
group: security-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
govulncheck:
name: Vulnerabilities (govulncheck)
runs-on: ubuntu-latest
# Advisory to start: flags known CVEs in dependencies the code reaches.
# Flip to blocking once the baseline is confirmed clean.
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.25"
cache: true
- name: install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
- name: govulncheck (report-only)
run: "$(go env GOPATH)/bin/govulncheck ./... || echo '::warning::govulncheck reported findings (advisory)'"

gosec:
name: SAST (gosec)
runs-on: ubuntu-latest
# Advisory to start: static security analysis (hardcoded creds, weak crypto,
# unsafe patterns). Reports without blocking until the baseline is triaged.
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.25"
cache: true
- name: install gosec
run: go install github.com/securego/gosec/v2/cmd/gosec@latest
- name: gosec (report-only)
run: "$(go env GOPATH)/bin/gosec -exclude-generated ./... || echo '::warning::gosec reported findings (advisory)'"

codeql:
name: CodeQL (SAST)
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
actions: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.25"
cache: true
- uses: github/codeql-action/init@v3
with:
languages: go
- uses: github/codeql-action/autobuild@v3
- uses: github/codeql-action/analyze@v3

dependency-review:
name: Dependency Review
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v4
- name: Review dependency changes for known vulnerabilities
uses: actions/dependency-review-action@v4
with:
fail-on-severity: high
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
</p>

<p align="center">
<a href="https://pkg.go.dev/github.com/stackshy/cloudemu"><img src="https://pkg.go.dev/badge/github.com/stackshy/cloudemu.svg" alt="Go Reference"></a>
<a href="https://goreportcard.com/report/github.com/stackshy/cloudemu"><img src="https://goreportcard.com/badge/github.com/stackshy/cloudemu" alt="Go Report Card"></a>
<a href="https://pkg.go.dev/github.com/stackshy/cloudemu/v2"><img src="https://pkg.go.dev/badge/github.com/stackshy/cloudemu/v2.svg" alt="Go Reference"></a>
<a href="https://goreportcard.com/report/github.com/stackshy/cloudemu/v2"><img src="https://goreportcard.com/badge/github.com/stackshy/cloudemu/v2" alt="Go Report Card"></a>
<a href="https://github.com/stackshy/cloudemu/blob/development/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License"></a>
<img src="https://img.shields.io/badge/Go-1.25+-00ADD8?logo=go&logoColor=white" alt="Go Version">
<img src="https://img.shields.io/badge/providers-AWS_|_Azure_|_GCP-orange" alt="Providers">
Expand All @@ -30,7 +30,7 @@ It ships two surfaces you can mix and match:
## Install

```bash
go get github.com/stackshy/cloudemu
go get github.com/stackshy/cloudemu/v2
```

Requires Go 1.25+.
Expand All @@ -45,8 +45,8 @@ import (

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/stackshy/cloudemu"
awsserver "github.com/stackshy/cloudemu/server/aws"
"github.com/stackshy/cloudemu/v2"
awsserver "github.com/stackshy/cloudemu/v2/server/aws"
)

cloud := cloudemu.NewAWS()
Expand Down
8 changes: 4 additions & 4 deletions cloudemu.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package cloudemu

import (
"github.com/stackshy/cloudemu/config"
"github.com/stackshy/cloudemu/providers/aws"
"github.com/stackshy/cloudemu/providers/azure"
"github.com/stackshy/cloudemu/providers/gcp"
"github.com/stackshy/cloudemu/v2/config"
"github.com/stackshy/cloudemu/v2/providers/aws"
"github.com/stackshy/cloudemu/v2/providers/azure"
"github.com/stackshy/cloudemu/v2/providers/gcp"
)

// NewAWS creates a new AWS mock provider.
Expand Down
58 changes: 30 additions & 28 deletions cloudemu_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,34 @@ import (
"testing"
"time"

"github.com/stackshy/cloudemu/compute"
computedriver "github.com/stackshy/cloudemu/compute/driver"
"github.com/stackshy/cloudemu/config"
"github.com/stackshy/cloudemu/cost"
"github.com/stackshy/cloudemu/database/driver"
dnsdriver "github.com/stackshy/cloudemu/dns/driver"
cerrors "github.com/stackshy/cloudemu/errors"
iamdriver "github.com/stackshy/cloudemu/iam/driver"
"github.com/stackshy/cloudemu/inject"
mqdriver "github.com/stackshy/cloudemu/messagequeue/driver"
"github.com/stackshy/cloudemu/metrics"
mondriver "github.com/stackshy/cloudemu/monitoring/driver"
netdriver "github.com/stackshy/cloudemu/networking/driver"
"github.com/stackshy/cloudemu/ratelimit"
"github.com/stackshy/cloudemu/recorder"
serverlessdriver "github.com/stackshy/cloudemu/serverless/driver"
"github.com/stackshy/cloudemu/storage"
storagedriver "github.com/stackshy/cloudemu/storage/driver"

lbdriver "github.com/stackshy/cloudemu/loadbalancer/driver"

cachedriver "github.com/stackshy/cloudemu/cache/driver"
crdriver "github.com/stackshy/cloudemu/containerregistry/driver"
ebdriver "github.com/stackshy/cloudemu/eventbus/driver"
loggingdriver "github.com/stackshy/cloudemu/logging/driver"
notifdriver "github.com/stackshy/cloudemu/notification/driver"
secretsdriver "github.com/stackshy/cloudemu/secrets/driver"
"github.com/stackshy/cloudemu/topology"
"github.com/stackshy/cloudemu/v2/config"
cerrors "github.com/stackshy/cloudemu/v2/errors"
"github.com/stackshy/cloudemu/v2/features/inject"
"github.com/stackshy/cloudemu/v2/features/metrics"
"github.com/stackshy/cloudemu/v2/features/ratelimit"
"github.com/stackshy/cloudemu/v2/features/recorder"
"github.com/stackshy/cloudemu/v2/services/compute"
computedriver "github.com/stackshy/cloudemu/v2/services/compute/driver"
"github.com/stackshy/cloudemu/v2/services/cost"
"github.com/stackshy/cloudemu/v2/services/database/driver"
dnsdriver "github.com/stackshy/cloudemu/v2/services/dns/driver"
iamdriver "github.com/stackshy/cloudemu/v2/services/iam/driver"
mqdriver "github.com/stackshy/cloudemu/v2/services/messagequeue/driver"
mondriver "github.com/stackshy/cloudemu/v2/services/monitoring/driver"
netdriver "github.com/stackshy/cloudemu/v2/services/networking/driver"
serverlessdriver "github.com/stackshy/cloudemu/v2/services/serverless/driver"
"github.com/stackshy/cloudemu/v2/services/storage"
storagedriver "github.com/stackshy/cloudemu/v2/services/storage/driver"

lbdriver "github.com/stackshy/cloudemu/v2/services/loadbalancer/driver"

"github.com/stackshy/cloudemu/v2/features/topology"
cachedriver "github.com/stackshy/cloudemu/v2/services/cache/driver"
crdriver "github.com/stackshy/cloudemu/v2/services/containerregistry/driver"
ebdriver "github.com/stackshy/cloudemu/v2/services/eventbus/driver"
loggingdriver "github.com/stackshy/cloudemu/v2/services/logging/driver"
notifdriver "github.com/stackshy/cloudemu/v2/services/notification/driver"
secretsdriver "github.com/stackshy/cloudemu/v2/services/secrets/driver"
)

func TestStorageLifecycle(t *testing.T) {
Expand Down Expand Up @@ -8229,6 +8229,7 @@ func testGSIOperations(t *testing.T, ctx context.Context, d driver.Database) {
t.Errorf("expected NotFound for missing table, got %v", err)
}
}

// Event Source Mapping Tests
func testEventSourceMapping(t *testing.T, ctx context.Context, d serverlessdriver.Serverless) {
t.Helper()
Expand Down Expand Up @@ -8423,6 +8424,7 @@ func TestEventSourceMappingGCP(t *testing.T) {
p := NewGCP()
testEventSourceMapping(t, ctx, p.CloudFunctions)
}

// ─── VPC Endpoints ────────────────────────────────────────────

func TestVPCEndpointAWS(t *testing.T) {
Expand Down
27 changes: 16 additions & 11 deletions doc.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
// Package cloudemu provides zero-cost, in-memory cloud emulation of
// AWS, Azure, and GCP cloud services for Go.
//
// cloudemu follows a three-layer architecture:
// The repository is organized by role so new services and features slot into
// predictable places:
//
// - Portable API: High-level types (storage.Bucket, compute.Compute, etc.)
// that wrap drivers with cross-cutting concerns like recording, metrics,
// rate limiting, and error injection.
// - services/<name>: the emulated cloud services. Each holds the Portable API
// type (e.g. services/storage's storage.Bucket) plus its driver interface
// under services/<name>/driver.
//
// - Driver Interfaces: Minimal contracts (storage/driver, compute/driver, etc.)
// that each provider must implement.
// - providers/{aws,azure,gcp}: in-memory backends implementing the drivers.
//
// - Provider Implementations: In-memory backends (providers/aws/s3, providers/azure/blobstorage,
// providers/gcp/gcs, etc.) powered by a generic memstore.
// - server/{aws,azure,gcp}: SDK-compat HTTP servers that speak each cloud's
// real wire protocol, so unmodified SDK clients drive the backends.
//
// 10 cloud services are covered across all three providers: Storage, Compute,
// Database, Serverless, Networking, Monitoring, IAM, DNS, Load Balancer,
// and Message Queue.
// - features/<name>: cross-cutting capabilities you wrap drivers with —
// chaos, recorder, metrics, inject, ratelimit, and topology.
//
// - config, errors: foundational options and the canonical error type.
//
// The three surfaces build on the same drivers: the SDK-compat server (the
// primary entrypoint), the Portable API (services/<name>), and the cross-cutting
// features, so a behavior implemented in a driver lights up across all of them.
package cloudemu
Loading
Loading