applicationautoscaling

package
v1.3.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: 21 Imported by: 0

README

Application Auto Scaling

Parity grade: A · SDK aws-sdk-go-v2/service/applicationautoscaling@v1.41.12 · last audited 2026-07-24 (bf3aabe3d)

Coverage

Metric Value
Operations audited 14 (14 ok)
Feature families 2 (2 ok)
Known gaps 4
Deferred items 3
Resource leaks clean
Known gaps
  • DescribeScalingActivities accepts IncludeNotScaledActivities (now threaded into the backend filter, and the response shape now has NotScaledReasons/Details fields) but it remains observably vacuous: gopherstack's mock backend never generates "not scaled" activities (no real metric evaluation loop exists to decide not-to-scale), so there is nothing to surface regardless of the flag's value. Verified vacuous, not a fabricated stub -- generating fake not-scaled events would be worse than reporting none.
  • GetPredictiveScalingForecast returns a flat synthetic capacity/load curve (constant 10.0 per hourly point) rather than any real forecasting simulation. Unchanged this pass; only its error-type wire shape was fixed.
  • PolicyType/ScalableDimension/ServiceNamespace enum values are accepted permissively (no allowlist validation) rather than validated against the real AWS enum lists. Consistent with this codebase's general emulator philosophy of not over-validating; not treated as a bug.
  • The "scalable targets per resource type" AWS quota (5,000 for DynamoDB, 3,000 for ECS, 1,500 for Keyspaces, 500 for other resource types, all adjustable) is not enforced. Only the two non-adjustable, resource-type-independent quotas were implemented this pass (50 scaling policies/target, 200 scheduled actions/target) plus the adjustable-but-defaulted 20 step-adjustments/policy quota. Mapping every real AWS resource type to its specific quota bucket for a soft/adjustable, rarely-hit limit was judged out of scope for this pass.
Deferred
  • Full CloudWatch cross-service integration for scaling-policy alarms: real AWS creates genuine backing CloudWatch alarms (visible via cloudwatch:DescribeAlarms) and can fail PutScalingPolicy with FailedResourceAccessException if the scalable target's RoleARN lacks CloudWatch permissions. This pass synthesizes stable, correctly-shaped Alarm entries (name + ARN) on the Application Auto Scaling side so PutScalingPolicy/DescribeScalingPolicies' Alarms field is populated like real AWS instead of always empty, but there is no actual CloudWatch alarm resource created in the cloudwatch service. Real cross-service alarm creation/verification remains out of scope.
  • ConcurrentUpdateException: sentinel (ErrConcurrentUpdate) and correct HTTP 500 status now exist in errors.go/handler.go, but no backend method returns it. gopherstack's backend serializes every operation behind one coarse lockmetrics.RWMutex, so there is no window in which two updates to the same resource can race -- the real AWS scenario (a resource that already has a pending update) has no analogue in a synchronous single-process emulator. Wiring the type without a fabricated trigger condition is the honest option; inventing an artificial pending-update state machine just to exercise this exception would be scope creep unrelated to real client-observable behavior.
  • FailedResourceAccessException: sentinel (ErrFailedResourceAccess) and correct HTTP 400 status now exist, but unreachable -- see the CloudWatch cross-service deferred item above. Requires real cross-service CloudWatch alarm/permission checking, out of scope.

More

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotFound is returned when a requested scalable target, scaling
	// policy, or scheduled action does not exist. Wire type ObjectNotFoundException.
	ErrNotFound = awserr.New("ObjectNotFoundException", awserr.ErrNotFound)
	// ErrAlreadyExists is returned when a resource already exists. No backend
	// method currently returns this: every Put*/Register* op is upsert-only
	// by design, matching real AWS semantics (there is no create-only path
	// that could conflict). Kept for completeness of the error-handling
	// switch, not dead in the sense of being unreachable-and-harmful.
	ErrAlreadyExists = awserr.New("ValidationException", awserr.ErrAlreadyExists)
	// ErrValidation is returned when a request parameter fails validation.
	// Wire type ValidationException.
	ErrValidation = awserr.New("ValidationException", awserr.ErrInvalidParameter)
	// ErrResourceNotFound is returned by the tagging operations
	// (ListTagsForResource/TagResource/UntagResource) when the resource ARN
	// does not correspond to a registered scalable target. Real AWS models
	// these three ops with ResourceNotFoundException, NOT
	// ObjectNotFoundException -- confirmed against the modeled error sets in
	// aws-sdk-go-v2/service/applicationautoscaling's deserializers.go
	// (awsAwsjson11_deserializeOpErrorTagResource et al. switch only on
	// ResourceNotFoundException/TooManyTagsException/ValidationException,
	// never ObjectNotFoundException).
	ErrResourceNotFound = awserr.New("ResourceNotFoundException", awserr.ErrNotFound)
	// ErrTooManyTags is returned by TagResource when applying the requested
	// tags would exceed the per-resource tag limit. Wire type
	// TooManyTagsException (only modeled on TagResource, not on
	// RegisterScalableTarget -- see ErrLimitExceeded).
	ErrTooManyTags = awserr.New("TooManyTagsException", awserr.ErrInvalidParameter)
	// ErrLimitExceeded is returned when a per-account/per-target quota is
	// exceeded: tags on RegisterScalableTarget (that op's modeled error set
	// has LimitExceededException, not TooManyTagsException), scaling
	// policies per scalable target (50, not adjustable), step adjustments
	// per step scaling policy (20, adjustable), and scheduled actions per
	// scalable target (200, not adjustable) -- quotas confirmed against the
	// "Quotas for Application Auto Scaling" AWS documentation page.
	ErrLimitExceeded = awserr.New("LimitExceededException", awserr.ErrInvalidParameter)
	// ErrInvalidNextToken is returned by Describe* operations when the
	// caller supplies a NextToken that fails to decode.
	ErrInvalidNextToken = awserr.New("InvalidNextTokenException", awserr.ErrInvalidParameter)
	// ErrConcurrentUpdate corresponds to real AWS's ConcurrentUpdateException
	// (thrown when a resource already has a pending update). gopherstack's
	// backend serializes every operation behind one coarse write lock, so
	// there is no window in which two updates to the same resource can race
	// -- this sentinel exists so the error-handling switch and HTTP-status
	// mapping are complete, but no backend method currently returns it.
	ErrConcurrentUpdate = awserr.New("ConcurrentUpdateException", awserr.ErrConflict)
	// ErrFailedResourceAccess corresponds to real AWS's
	// FailedResourceAccessException (thrown when Application Auto Scaling
	// cannot retrieve the CloudWatch alarms behind a scaling policy, e.g. a
	// bad RoleARN). gopherstack does not perform real CloudWatch
	// cross-service calls (see the deferred CloudWatch alarm integration
	// note in PARITY.md), so no backend method currently returns it; the
	// sentinel exists for a complete error-handling switch.
	ErrFailedResourceAccess = awserr.New("FailedResourceAccessException", awserr.ErrInvalidParameter)
	// ErrInternalService is the generic InternalServiceException fallback
	// used for the handler's default error case, matching real AWS's wire
	// shape for unexpected server-side failures instead of a bespoke,
	// non-AWS-shaped JSON body. No existing awserr category (NotFound/
	// AlreadyExists/InvalidParameter/Conflict) represents a server fault, so
	// this is a plain local sentinel rather than an awserr.New wrapper.
	ErrInternalService = errors.New("InternalServiceException")
)

Functions

This section is empty.

Types

type Alarm added in v1.2.0

type Alarm struct {
	AlarmARN  string `json:"alarmArn"`
	AlarmName string `json:"alarmName"`
}

Alarm mirrors the CloudWatch alarm reference AWS attaches to TargetTrackingScaling/StepScaling policies (PutScalingPolicy and DescribeScalingPolicies both return this on the wire). Real AWS creates backing CloudWatch alarms server-side; gopherstack has no cross-service reference to the cloudwatch backend to create a real one, so this is never populated (see PARITY.md gaps -- honestly empty, not fabricated).

type CapacityForecastData

type CapacityForecastData struct {
	Timestamps []time.Time
	Values     []float64
}

CapacityForecastData holds the timestamps and capacity values for a forecast.

type DescribeScalableTargetsFilter

type DescribeScalableTargetsFilter struct {
	ServiceNamespace  string
	ScalableDimension string
	// NextToken is the opaque pagination cursor returned by a prior call.
	NextToken   string
	ResourceIDs []string
	// MaxResults, when > 0, limits the number of returned items. Capped at maxDescribeResults.
	MaxResults int32
}

DescribeScalableTargetsFilter carries optional filters for DescribeScalableTargets.

type DescribeScalingActivitiesFilter

type DescribeScalingActivitiesFilter struct {
	// ServiceNamespace limits results to this namespace when non-empty.
	ServiceNamespace string
	// ResourceID limits results to this resource when non-empty.
	ResourceID string
	// ScalableDimension limits results to this dimension when non-empty.
	ScalableDimension string
	// NextToken is the opaque pagination cursor returned by a prior call.
	NextToken string
	// MaxResults, when > 0, limits the number of returned items. Capped at maxDescribeResults.
	MaxResults int32
	// IncludeNotScaledActivities is accepted for wire completeness; see the
	// doc comment on [InMemoryBackend.DescribeScalingActivities].
	IncludeNotScaledActivities bool
}

DescribeScalingActivitiesFilter carries optional filters for DescribeScalingActivities.

type DescribeScalingPoliciesFilter

type DescribeScalingPoliciesFilter struct {
	ServiceNamespace  string
	ResourceID        string
	ScalableDimension string
	NextToken         string
	PolicyNames       []string
	MaxResults        int32
}

DescribeScalingPoliciesFilter carries optional filters for DescribeScalingPolicies.

type DescribeScheduledActionsFilter

type DescribeScheduledActionsFilter struct {
	// ServiceNamespace limits results to this namespace when non-empty.
	ServiceNamespace string
	// ResourceID limits results to this resource when non-empty.
	ResourceID string
	// ScalableDimension limits results to this dimension when non-empty.
	ScalableDimension string
	// NextToken is the opaque pagination cursor returned by a prior call.
	NextToken string
	// ScheduledActionNames, when non-empty, limits results to the named actions.
	ScheduledActionNames []string
	// MaxResults, when > 0, limits the number of returned items.
	MaxResults int32
}

DescribeScheduledActionsFilter carries optional filters for DescribeScheduledActions.

type Handler

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

Handler is the Echo HTTP handler for Application Auto Scaling operations.

func NewHandler

func NewHandler(backend *InMemoryBackend) *Handler

NewHandler creates a new Application Auto Scaling 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 Application Auto Scaling action from the X-Amz-Target header.

func (*Handler) ExtractResource

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

ExtractResource extracts the resource identifier from the request body.

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 Application Auto Scaling 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.

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 Application Auto Scaling requests.

func (*Handler) Snapshot

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

Snapshot implements persistence.Persistable by delegating to the backend.

type InMemoryBackend

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

InMemoryBackend stores Application Auto Scaling state in memory.

func NewInMemoryBackend

func NewInMemoryBackend(accountID, region string) *InMemoryBackend

NewInMemoryBackend creates a new InMemoryBackend.

func (*InMemoryBackend) DeleteScalingPolicy

func (b *InMemoryBackend) DeleteScalingPolicy(
	serviceNamespace, resourceID, scalableDimension, policyName string,
) error

DeleteScalingPolicy removes a scaling policy by name.

func (*InMemoryBackend) DeleteScheduledAction

func (b *InMemoryBackend) DeleteScheduledAction(
	serviceNamespace, resourceID, scalableDimension, scheduledActionName string,
) error

DeleteScheduledAction removes a scheduled action.

func (*InMemoryBackend) DeregisterScalableTarget

func (b *InMemoryBackend) DeregisterScalableTarget(serviceNamespace, resourceID, scalableDimension string) error

DeregisterScalableTarget removes a scalable target. DeregisterScalableTarget removes a scalable target and cascades the deletion to all scaling policies and scheduled actions that belong to the same resource (AWS behaviour).

func (*InMemoryBackend) DescribeScalableTargets

func (b *InMemoryBackend) DescribeScalableTargets(f DescribeScalableTargetsFilter) ([]*ScalableTarget, string, error)

DescribeScalableTargets lists scalable targets, optionally filtered, and returns the NextToken for the following page (empty on the last page). Returns ErrInvalidNextToken if f.NextToken fails to decode.

func (*InMemoryBackend) DescribeScalingActivities

func (b *InMemoryBackend) DescribeScalingActivities(
	f DescribeScalingActivitiesFilter,
) ([]*ScalingActivity, string, error)

DescribeScalingActivities returns recorded scaling activities filtered by the optional fields in f, most recent first, with pagination. Returns ErrInvalidNextToken if f.NextToken fails to decode.

f.IncludeNotScaledActivities is accepted for wire completeness but has no observable effect: gopherstack has no metric-evaluation loop capable of producing a "not scaled" activity (every recorded activity is a real capacity-changing event), so there is never anything for the flag to include or exclude -- this is a verified-vacuous gap, not an unimplemented filter (see PARITY.md).

func (*InMemoryBackend) DescribeScalingPolicies

func (b *InMemoryBackend) DescribeScalingPolicies(f DescribeScalingPoliciesFilter) ([]*ScalingPolicy, string, error)

DescribeScalingPolicies lists scaling policies, optionally filtered, and returns the NextToken for the following page (empty on the last page). Returns ErrInvalidNextToken if f.NextToken fails to decode.

func (*InMemoryBackend) DescribeScheduledActions

func (b *InMemoryBackend) DescribeScheduledActions(
	f DescribeScheduledActionsFilter,
) ([]*ScheduledAction, string, error)

DescribeScheduledActions lists scheduled actions, optionally filtered, and returns the NextToken for the following page (empty on the last page). Returns ErrInvalidNextToken if f.NextToken fails to decode.

func (*InMemoryBackend) GetPredictiveScalingForecast

func (b *InMemoryBackend) GetPredictiveScalingForecast(
	serviceNamespace, resourceID, scalableDimension, policyName string,
	startTime, endTime time.Time,
) (*CapacityForecastData, []LoadForecastData, time.Time, error)

GetPredictiveScalingForecast returns simulated hourly forecast data for the requested policy over the given time window. It verifies the associated scaling policy exists.

func (*InMemoryBackend) ListTagsForResource

func (b *InMemoryBackend) ListTagsForResource(resourceARN string) (map[string]string, error)

ListTagsForResource returns tags for a scalable target identified by its ARN.

func (*InMemoryBackend) Purge

func (b *InMemoryBackend) Purge()

Purge removes all resources from the backend. It is safe to call concurrently.

func (*InMemoryBackend) PutScalingPolicy

func (b *InMemoryBackend) PutScalingPolicy(
	serviceNamespace, resourceID, scalableDimension, policyName, policyType string,
	targetTrackingConfig, stepScalingConfig, predictiveScalingConfig map[string]any,
) (*ScalingPolicy, error)

PutScalingPolicy upserts a scaling policy (update if policyName matches for resource, create otherwise).

func (*InMemoryBackend) PutScheduledAction

func (b *InMemoryBackend) PutScheduledAction(
	serviceNamespace, resourceID, scalableDimension, scheduledActionName, schedule, timezone string,
	startTime, endTime *time.Time,
	scalableTargetAction *ScalableTargetAction,
) (*ScheduledAction, error)

PutScheduledAction upserts a scheduled action.

func (*InMemoryBackend) Region

func (b *InMemoryBackend) Region() string

Region returns the AWS region this backend is configured for.

func (*InMemoryBackend) RegisterScalableTarget

func (b *InMemoryBackend) RegisterScalableTarget(
	serviceNamespace, resourceID, scalableDimension string,
	minCapacity, maxCapacity int32,
	tags map[string]string,
	roleARN string,
	suspendedState *SuspendedState,
) (*ScalableTarget, error)

RegisterScalableTarget upserts a scalable target (creates or updates).

func (*InMemoryBackend) Reset

func (b *InMemoryBackend) Reset()

Reset clears all backend state, resetting to an empty store.

func (*InMemoryBackend) Restore

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

Restore loads backend state from a JSON snapshot. It implements persistence.Persistable.

func (*InMemoryBackend) Snapshot

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

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

func (*InMemoryBackend) TagResource

func (b *InMemoryBackend) TagResource(resourceARN string, kv map[string]string) error

TagResource adds or updates tags on a scalable target identified by its ARN.

func (*InMemoryBackend) UntagResource

func (b *InMemoryBackend) UntagResource(resourceARN string, tagKeys []string) error

UntagResource removes tags from a scalable target identified by its ARN.

type LoadForecastData

type LoadForecastData struct {
	MetricSpecification string
	Timestamps          []time.Time
	Values              []float64
}

LoadForecastData holds the timestamps, values, and a metric specification label for a load forecast.

type NotScaledReason added in v1.2.0

type NotScaledReason struct {
	CurrentCapacity *int32 `json:"currentCapacity,omitempty"`
	MaxCapacity     *int32 `json:"maxCapacity,omitempty"`
	MinCapacity     *int32 `json:"minCapacity,omitempty"`
	Code            string `json:"code"`
}

NotScaledReason mirrors the real AWS NotScaledReason type: it explains why a scaling activity did not change capacity, and is only ever returned when a client sets IncludeNotScaledActivities=true. gopherstack has no metric evaluation loop capable of deciding "not scaled" outcomes (see PARITY.md), so NotScaledReasons on ScalingActivity is always empty rather than fabricated -- documented, not a fabricated stub.

type Provider

type Provider struct{}

Provider implements service.Provider for Application Auto Scaling.

func (*Provider) Init

Init initializes the Application Auto Scaling backend and handler.

func (*Provider) Name

func (p *Provider) Name() string

Name returns the provider name.

type ScalableTarget

type ScalableTarget struct {
	CreationTime      time.Time         `json:"creationTime"`
	LastModifiedTime  time.Time         `json:"lastModifiedTime"`
	SuspendedState    *SuspendedState   `json:"suspendedState,omitempty"`
	Tags              map[string]string `json:"tags,omitempty"`
	PredictedCapacity *int32            `json:"predictedCapacity,omitempty"`
	RoleARN           string            `json:"roleArn,omitempty"`
	ARN               string            `json:"arn"`
	ScalableDimension string            `json:"scalableDimension"`
	ServiceNamespace  string            `json:"serviceNamespace"`
	AccountID         string            `json:"accountID"`
	Region            string            `json:"region"`
	ResourceID        string            `json:"resourceId"`
	MinCapacity       int32             `json:"minCapacity"`
	MaxCapacity       int32             `json:"maxCapacity"`
}

ScalableTarget represents a registered Application Auto Scaling scalable target.

type ScalableTargetAction

type ScalableTargetAction struct {
	MinCapacity *int32 `json:"minCapacity,omitempty"`
	MaxCapacity *int32 `json:"maxCapacity,omitempty"`
}

ScalableTargetAction holds the capacity bounds for a scheduled action.

type ScalingActivity

type ScalingActivity struct {
	StartTime         time.Time `json:"StartTime"`
	EndTime           time.Time `json:"EndTime"`
	ActivityID        string    `json:"ActivityId"`
	ServiceNamespace  string    `json:"ServiceNamespace"`
	ResourceID        string    `json:"ResourceId"`
	ScalableDimension string    `json:"ScalableDimension"`
	Description       string    `json:"Description"`
	Cause             string    `json:"Cause"`
	StatusCode        string    `json:"StatusCode"`
	StatusMessage     string    `json:"StatusMessage"`
	// Details holds supplementary JSON detail AWS attaches to some activities
	// (e.g. which step adjustment fired). gopherstack has no such detail to
	// report, so this is always empty.
	Details string `json:"details,omitempty"`
	// NotScaledReasons is always empty; see [NotScaledReason].
	NotScaledReasons []NotScaledReason `json:"notScaledReasons,omitempty"`
}

ScalingActivity records a capacity-changing activity on a scalable target, returned by DescribeScalingActivities.

type ScalingPolicy

type ScalingPolicy struct {
	CreationTime            time.Time      `json:"creationTime"`
	LastModifiedTime        time.Time      `json:"lastModifiedTime"`
	TargetTrackingConfig    map[string]any `json:"targetTrackingConfig,omitempty"`
	StepScalingConfig       map[string]any `json:"stepScalingConfig,omitempty"`
	PredictiveScalingConfig map[string]any `json:"predictiveScalingConfig,omitempty"`
	PolicyType              string         `json:"policyType"`
	PolicyName              string         `json:"policyName"`
	ResourceID              string         `json:"resourceId"`
	ARN                     string         `json:"arn"`
	ScalableDimension       string         `json:"scalableDimension"`
	ServiceNamespace        string         `json:"serviceNamespace"`
	Alarms                  []Alarm        `json:"alarms,omitempty"`
}

ScalingPolicy represents an Application Auto Scaling scaling policy.

type ScheduledAction

type ScheduledAction struct {
	StartTime            *time.Time            `json:"startTime,omitempty"`
	EndTime              *time.Time            `json:"endTime,omitempty"`
	CreationTime         time.Time             `json:"creationTime"`
	LastModifiedTime     time.Time             `json:"lastModifiedTime"`
	ScalableTargetAction *ScalableTargetAction `json:"scalableTargetAction,omitempty"`
	ScheduledActionName  string                `json:"scheduledActionName"`
	ResourceID           string                `json:"resourceId"`
	ARN                  string                `json:"arn"`
	Schedule             string                `json:"schedule"`
	ScalableDimension    string                `json:"scalableDimension"`
	ServiceNamespace     string                `json:"serviceNamespace"`
	Timezone             string                `json:"timezone,omitempty"`
}

ScheduledAction represents an Application Auto Scaling scheduled action.

type SuspendedState

type SuspendedState struct {
	DynamicScalingInSuspended  bool `json:"dynamicScalingInSuspended"`
	DynamicScalingOutSuspended bool `json:"dynamicScalingOutSuspended"`
	ScheduledScalingSuspended  bool `json:"scheduledScalingSuspended"`
}

SuspendedState represents the suspension configuration for a scalable target. Each field independently suspends a category of scaling activity.

Jump to

Keyboard shortcuts

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