cloudcontrol

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 3, 2026 License: MIT Imports: 19 Imported by: 0

README

Cloud Control API

Parity grade: A · SDK aws-sdk-go-v2/service/cloudcontrol@v1.29.15 · last audited 2026-07-24 (0689b86e)

Coverage

Metric Value
Operations audited 8 (8 ok)
Feature families 3 (3 ok)
Known gaps 3
Deferred items 2
Resource leaks clean
Known gaps
  • cloudcontrol keeps its own generic resource store; it does NOT delegate to the real per-service backend (e.g. AWS::S3::Bucket via CreateResource does not create a row visible to services/s3's ListBuckets, and vice versa). This is explicitly allowed by the task brief (either design is parity-correct) but is a real cross-service gap for any test that mixes CloudControl and native-service calls against the same logical resource. No bd issue filed yet -- flagging for triage.
  • TypeNotFoundException (extension not registered in the CFN registry) is unreachable: this backend has no type registry, so any well-formed TypeName (ns::svc::type) is implicitly accepted. Not fixed -- would require building a registry concept out of scope for this pass.
  • ListResourcesInput.ResourceModel ('The resource model to use to select the resources to return') is a real input field this backend accepts on the wire (unknown-field JSON decode is a no-op, not an error) but never applies as a filter -- this backend has no secondary resource-model index to filter against. Low-impact/rarely-used field; not fixed this pass.
Deferred
  • Full errCodeLookup coverage for the remaining documented-but-unreachable exceptions (ThrottlingException, ServiceLimitExceededException, HandlerFailureException, NotStabilizedException, NotUpdatableException, ResourceConflictException, PrivateTypeException, GeneralServiceException, NetworkFailureException, InvalidCredentialsException, HandlerInternalFailureException, ConcurrentOperationException, ClientTokenConflictException). None of these are currently producible by this backend's logic (no chaos-injection wiring specific to cloudcontrol beyond the generic ChaosServiceName/ChaosOperations hooks), so adding dead mapping cases was judged out of scope/gold-plating this pass. Revisit if chaos fault injection or a richer validation model is added.
  • ClientTokenConflictException specifically: reusing the same ClientToken across a genuinely DIFFERENT request (different TypeName/Identifier/op) is not detected -- the cached ProgressEvent is returned unconditionally on any token match, same simplification CreateResource already made pre-existing this pass, now applied consistently to Update/Delete too. Real conflict detection would require persisting and diffing the full original request, out of scope.

More

Documentation

Overview

Package cloudcontrol provides an in-memory implementation of the AWS CloudControl API service.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotFound is returned when a requested resource does not exist.
	ErrNotFound = awserr.New("ResourceNotFoundException", awserr.ErrNotFound)
	// ErrAlreadyExists is returned when a resource with the same identifier already exists.
	ErrAlreadyExists = awserr.New("AlreadyExistsException", awserr.ErrConflict)
	// ErrValidation is returned when a required field is missing or has an invalid value.
	// CloudControl's error model has no ValidationException shape at all: every
	// operation instead declares InvalidRequestException ("invalid input from the
	// user has generated a generic exception") as its generic input-validation error.
	// See the Errors section of e.g. the CreateResource API reference.
	ErrValidation = awserr.New("InvalidRequestException", awserr.ErrInvalidParameter)
	// ErrRequestTokenNotFound is returned when a RequestToken does not correspond to
	// any tracked resource operation request. GetResourceRequestStatus declares
	// RequestTokenNotFoundException as its ONLY error, and CancelResourceRequest
	// declares it alongside ConcurrentModificationException; real AWS never returns
	// ResourceNotFoundException for an unrecognized RequestToken.
	ErrRequestTokenNotFound = awserr.New("RequestTokenNotFoundException", awserr.ErrNotFound)
	// ErrConcurrentModification is returned by CancelResourceRequest when the target
	// request is not in a cancellable (PENDING/IN_PROGRESS) state. Confirmed against
	// the CancelResourceRequest API reference's Errors section:
	// ConcurrentModificationException, HTTP 500 -- "The resource is currently being
	// modified by another operation".
	ErrConcurrentModification = awserr.New("ConcurrentModificationException", awserr.ErrConflict)
	// ErrClientTokenConflict is returned by CreateResource/UpdateResource/DeleteResource
	// when a ClientToken is reused with a genuinely different request (different
	// TypeName/Identifier/desired-state/patch document) than the one originally
	// associated with that token. Confirmed against
	// aws-sdk-go-v2/service/cloudcontrol/types/errors.go: ClientTokenConflictException
	// has ErrorFault() == smithy.FaultClient, so it is HTTP 400 like the other client
	// faults here, not 500.
	ErrClientTokenConflict = awserr.New("ClientTokenConflictException", awserr.ErrConflict)
)

Functions

This section is empty.

Types

type Handler

type Handler struct {
	Backend *InMemoryBackend
	// contains filtered or unexported fields
}

Handler is the Echo HTTP handler for CloudControl API operations.

func NewHandler

func NewHandler(backend *InMemoryBackend) *Handler

NewHandler creates a new CloudControl handler backed by backend. backend must not be nil.

func (*Handler) ChaosOperations

func (h *Handler) ChaosOperations() []string

ChaosOperations returns all operations that can be fault-injected.

func (*Handler) ChaosRegions

func (h *Handler) ChaosRegions() []string

ChaosRegions returns all regions this handler instance handles.

func (*Handler) ChaosServiceName

func (h *Handler) ChaosServiceName() string

ChaosServiceName returns the lowercase AWS service name for fault rule matching.

func (*Handler) ExtractOperation

func (h *Handler) ExtractOperation(c *echo.Context) string

ExtractOperation extracts the CloudControl action from the X-Amz-Target header.

func (*Handler) ExtractResource

func (h *Handler) ExtractResource(_ *echo.Context) string

ExtractResource extracts the resource type name from the request body for metrics/logging. Returns "cloudcontrol" as a stable low-cardinality label when a TypeName is absent.

func (*Handler) GetSupportedOperations

func (h *Handler) GetSupportedOperations() []string

GetSupportedOperations returns the list of supported operations.

func (*Handler) Handler

func (h *Handler) Handler() echo.HandlerFunc

Handler returns the Echo handler function for CloudControl requests.

func (*Handler) MatchPriority

func (h *Handler) MatchPriority() int

MatchPriority returns the routing priority.

func (*Handler) Name

func (h *Handler) Name() string

Name returns the service name.

func (*Handler) Reset

func (h *Handler) Reset()

Reset clears all backend state. Useful for test isolation.

func (*Handler) Restore

func (h *Handler) Restore(ctx context.Context, data []byte) error

Restore implements persistence.Persistable by delegating to the backend.

func (*Handler) RouteMatcher

func (h *Handler) RouteMatcher() service.Matcher

RouteMatcher returns a function that matches CloudControl requests.

func (*Handler) Snapshot

func (h *Handler) Snapshot(ctx context.Context) []byte

Snapshot implements persistence.Persistable by delegating to the backend. Handler previously had no Snapshot/Restore of its own -- and neither did InMemoryBackend -- so cli.go's generic setupPersistence never picked CloudControl up at all. This delegation (matching the codecommit/cleanrooms pattern) is what wires CloudControl into persistence for the first time.

type InMemoryBackend

type InMemoryBackend struct {
	// contains filtered or unexported fields
}

InMemoryBackend is a thread-safe in-memory store for CloudControl resources.

func NewInMemoryBackend

func NewInMemoryBackend(accountID, region string) *InMemoryBackend

NewInMemoryBackend creates a new backend for the given account and region.

func (*InMemoryBackend) AddProgressEvent

func (b *InMemoryBackend) AddProgressEvent(event *ProgressEvent)

AddProgressEvent inserts a ProgressEvent directly into the requests map. This is intended for use in tests to set up specific request states that cannot be reached through the normal API (e.g. IN_PROGRESS).

func (*InMemoryBackend) CancelResourceRequest

func (b *InMemoryBackend) CancelResourceRequest(requestToken string) (*ProgressEvent, error)

CancelResourceRequest cancels the request identified by requestToken. An unrecognized requestToken returns ErrRequestTokenNotFound (RequestTokenNotFoundException). Cancelling an already-terminal request (SUCCESS, FAILED, CANCEL_COMPLETE, CANCEL_IN_PROGRESS) returns ErrConcurrentModification (ConcurrentModificationException), matching the real AWS API reference for this operation -- not a validation error.

func (*InMemoryBackend) CreateResource

func (b *InMemoryBackend) CreateResource(typeName, desiredState, clientToken string) (*ProgressEvent, error)

CreateResource creates a new resource of the given type with the given desired state JSON. An optional clientToken may be supplied for idempotency: if the same token is supplied again with the SAME desiredState, the original ProgressEvent is returned without creating a duplicate resource. Supplying the same token with a DIFFERENT typeName/desiredState returns ErrClientTokenConflict (real ClientTokenConflictException semantics).

func (*InMemoryBackend) DeleteResource

func (b *InMemoryBackend) DeleteResource(typeName, identifier, clientToken string) (*ProgressEvent, error)

DeleteResource removes the resource identified by typeName and identifier. An optional clientToken may be supplied for idempotency, matching the real DeleteResourceInput.ClientToken field: if the same token is supplied again for the SAME typeName/identifier, the original ProgressEvent is returned without re-deleting (or erroring on an already-deleted resource). Supplying the same token for a DIFFERENT typeName/identifier returns ErrClientTokenConflict.

func (*InMemoryBackend) GetResource

func (b *InMemoryBackend) GetResource(typeName, identifier string) (*Resource, error)

GetResource returns a copy of the resource identified by typeName and identifier.

func (*InMemoryBackend) GetResourceRequestStatus

func (b *InMemoryBackend) GetResourceRequestStatus(requestToken string) (*ProgressEvent, error)

GetResourceRequestStatus returns a copy of the ProgressEvent for the given request token. Events are retained in the map until Reset() is called. An unrecognized requestToken returns ErrRequestTokenNotFound (RequestTokenNotFoundException), the only error this operation declares -- not ErrNotFound (ResourceNotFoundException), which describes a missing *resource*, not a missing *request token*.

func (*InMemoryBackend) ListAllResources

func (b *InMemoryBackend) ListAllResources() []*Resource

ListAllResources returns all resources regardless of type, sorted by TypeName then Identifier. This is used by the dashboard only and is not a CloudControl API operation.

func (*InMemoryBackend) ListResourceRequests

func (b *InMemoryBackend) ListResourceRequests(
	filter *ResourceRequestFilter, maxResults int, nextToken string,
) ([]*ProgressEvent, string, error)

ListResourceRequests returns all tracked resource requests, optionally filtered by operation type, operation status, and/or resource type name. Results are sorted by EventTime descending (most recent first) for deterministic output. Returns ErrValidation if the filter contains unknown operation or status strings.

func (*InMemoryBackend) ListResources

func (b *InMemoryBackend) ListResources(
	typeName string, maxResults int, nextToken, resourceModel string,
) ([]*Resource, string)

ListResources returns a paginated list of resources of the given type, sorted by Identifier. resourceModel, when non-empty, is a JSON object of property name/value pairs (the real ListResourcesInput.ResourceModel field -- "The resource model to use to select the resources to return"); only resources whose current Properties contain every one of those key/value pairs are returned. An unparseable resourceModel matches nothing, same as AWS rejecting a malformed selector.

func (*InMemoryBackend) Region

func (b *InMemoryBackend) Region() string

Region returns the region for this backend instance.

func (*InMemoryBackend) Reset

func (b *InMemoryBackend) Reset()

Reset clears all state from the backend, returning it to a clean initial state.

func (*InMemoryBackend) Restore

func (b *InMemoryBackend) Restore(ctx context.Context, data []byte) error

Restore deserializes backend state from a snapshot. It implements persistence.Persistable.

func (*InMemoryBackend) Snapshot

func (b *InMemoryBackend) Snapshot(ctx context.Context) []byte

Snapshot serializes the backend state to JSON. It implements persistence.Persistable.

func (*InMemoryBackend) UpdateResource

func (b *InMemoryBackend) UpdateResource(typeName, identifier, patchDocument, clientToken string) (
	*ProgressEvent, error,
)

UpdateResource applies a JSON RFC 6902 patch document to the resource. An optional clientToken may be supplied for idempotency, matching the real UpdateResourceInput.ClientToken field: if the same token is supplied again with the SAME typeName/identifier/patchDocument, the original ProgressEvent is returned without re-applying the patch. Supplying the same token with a DIFFERENT typeName/identifier/ patchDocument returns ErrClientTokenConflict.

type ProgressEvent

type ProgressEvent struct {
	// EventTime and RetryAfter are epoch-seconds numbers on the wire, per the
	// real SDK's awsAwsjson10_deserializeDocumentProgressEvent (ParseEpochSeconds),
	// not ISO8601 strings. RetryAfter uses a pointer wrapper since it is unset
	// (real field is *time.Time, omitted) whenever the backend has no retry
	// guidance to give -- which today is always, since no op leaves an event
	// in a non-terminal state.
	EventTime       unixEpochTime  `json:"EventTime"`
	RetryAfter      *unixEpochTime `json:"RetryAfter,omitempty"`
	TypeName        string         `json:"TypeName"`
	Identifier      string         `json:"Identifier,omitempty"`
	RequestToken    string         `json:"RequestToken"`
	Operation       string         `json:"Operation"`
	OperationStatus string         `json:"OperationStatus"`
	StatusMessage   string         `json:"StatusMessage,omitempty"`
	// ErrorCode is the HandlerErrorCode explaining a FAILED request. Real
	// AWS only populates this when OperationStatus is FAILED; this backend
	// currently never leaves a request in FAILED (see PARITY.md), so the
	// field is always empty today but is modeled for wire-shape parity and
	// so a future FAILED path has somewhere real to write.
	ErrorCode string `json:"ErrorCode,omitempty"`
	// HooksRequestToken is the token for the Hooks invocation associated
	// with this request. This backend has no Hooks concept, so it is always
	// empty -- modeled for wire-shape parity only.
	HooksRequestToken string `json:"HooksRequestToken,omitempty"`
	// ResourceModel is a JSON string containing the resource model -- each
	// resource property and its current value -- per the real ProgressEvent
	// shape. Populated on SUCCESS so callers can read the resource straight
	// off the ProgressEvent without a follow-up GetResource call, matching
	// real AWS CLI/SDK/IaC-tool usage of this field.
	ResourceModel string `json:"ResourceModel,omitempty"`
}

ProgressEvent represents the status of a CloudControl resource operation.

type Provider

type Provider struct{}

Provider implements service.Provider for the CloudControl API service.

func (*Provider) Init

Init initializes the CloudControl API service.

func (*Provider) Name

func (p *Provider) Name() string

Name returns the logical name of the provider.

type Resource

type Resource struct {
	TypeName   string
	Identifier string
	Properties string // JSON string of current properties
}

Resource represents an in-memory CloudControl managed resource.

type ResourceRequestFilter

type ResourceRequestFilter struct {
	Operations        []string
	OperationStatuses []string
}

ResourceRequestFilter holds optional filter criteria for ListResourceRequests. This mirrors the real SDK's types.ResourceRequestStatusFilter exactly: Operations and OperationStatuses only. There is no TypeName member on the real filter shape (confirmed against aws-sdk-go-v2/service/cloudcontrol/types and botocore's service-2.json) -- ListResourceRequests has no wire-level way to filter by resource type.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL