Skip to content

feat(aws-ssm): Run Command lifecycle, parameter checks, list and cancel ops (SSM-2) - #1382

Draft
NitinKumar004 wants to merge 1 commit into
developmentfrom
feat/aws-ssm-run-command
Draft

NitinKumar004 wants to merge 1 commit into
developmentfrom
feat/aws-ssm-run-command

Conversation

@NitinKumar004

Copy link
Copy Markdown
Collaborator

Summary

Run Command now behaves like real SSM instead of recording an instant success. This is SSM-2 from the build-out plan, and it also covers tracker row SSM-X3 plus the SendCommand version and parameter checks deferred from #1367.

SendCommand

  • DocumentVersion accepts $DEFAULT, $LATEST or a number. A bad pattern returns ValidationException and a missing version returns InvalidDocumentVersion. The response echoes the requested version ($DEFAULT when none is given).
  • Parameters are checked against the declared parameters of the selected document version: undeclared names, required parameters with no default, type (String/Integer/Boolean/StringList/StringMap/MapList), allowedValues, allowedPattern (full match), minItems/maxItems and minChars/maxChars. Failures return InvalidParameters. AWS-owned names that are not in the catalog are still accepted without checks.
  • Request constraints from the botocore model: MaxConcurrency/MaxErrors patterns, TimeoutSeconds 30..2592000, Comment up to 100 characters, at most 50 instance ids and 5 targets, and the instance id pattern.
  • Explicit instance ids must be running. An unknown id is InvalidInstanceId, and so is a stopped one ("not in a valid state"). Tag targets skip terminated instances. A stopped instance picked by a tag stays Delayed and ends as DeliveryTimedOut after TimeoutSeconds.
  • The response reports Pending, echoes every request field and includes TargetCount, RequestedDateTime and ExpiresAfter.
  • With S3 wired, OutputS3BucketName gets the output object under <prefix>/<command>/<instance>/<plugin>/<step>/stdout once the invocation finishes. Without S3 the bucket is only echoed back. The output URLs are reported on the plugins, and on the invocation when the document has a single plugin.

Lifecycle

  • Status is worked out from the clock at read time, following the FIS pattern. With --async-settle, invocations go Pending (1s), then InProgress (5s), then Success. They run in MaxConcurrency batches. An executionTimeout shorter than the run ends as TimedOut/ExecutionTimedOut.
  • Command status is aggregated with the real rules: Success, Cancelled, Failed once the errors go over MaxErrors, TimedOut, Incomplete and NoInstancesInTag. CompletedCount, ErrorCount and DeliveryTimedOutCount are filled in.
  • With settle off, commands finish at send time, as before.

New ops

  • ListCommands: CommandId, InstanceId, the five filter keys (InvokedAfter/InvokedBefore/Status/ExecutionStage/DocumentName), newest first, paging. An unknown key is InvalidFilterKey and a bad token is InvalidNextToken.
  • ListCommandInvocations: the same filters (except ExecutionStage, which is InvalidFilterKey here) and --details, which returns CommandPlugins (one per runtimeConfig plugin or mainSteps step).
  • CancelCommand: cancels unfinished invocations on all targets or on the listed instances. An unknown command is InvalidCommandId and an instance that is not a target is InvalidInstanceId. Finished invocations keep their result.
  • DescribeInstanceInformation: every EC2 instance that is not terminated is listed as a managed node. Running instances are Online and the rest ConnectionLost. It supports both filter lists and paging (5..50).
  • GetCommandInvocation reads from the same state. It takes PluginName (an unknown one is InvalidPluginName) and reports ResponseCode -1 until the run finishes, along with ExecutionStart/End/Elapsed.

Persistence

Command history is saved in the snapshot under commandHistory, which includes cancels and output-written flags. A restored command keeps settling from its send time. Snapshots in the older per-invocation commands form are converted on restore.

Testing

  • New SDK tests (server/aws/ssm/run_command_lifecycle_test.go) all failed on the old code. The provider tests cover MaxConcurrency staggering, delivery timeout on a stopped tag target, the snapshot round trip and legacy restore.
  • Existing tests were updated where real SSM rejects what they sent: a missing required commands parameter, and instance ids that don't match the id pattern.
  • go build ./.... go vet and go test -race on internal/settle, providers/aws, providers/aws/ssm, server/aws/ssm and persist. golangci-lint --new-from-rev=origin/development is clean. coveragegen regenerated.
  • E2e against cloudemu serve, with and without --async-settle:
    • aws CLI: send-command with AWS-RunShellScript, with a missing required parameter, with a bad pattern and with a bad version; a user document with typed parameters (Integer, allowedValues, required); list-commands with filters and paging; list-command-invocations --details; get-command-invocation with --plugin-name; cancel-command while the command was InProgress (it ended Cancelled) and with an unknown id; the S3 output objects listed.
    • Terraform aws_ssm_document: apply, no-drift plan, update to version 2, no-drift plan, send-command against the TF document, destroy.
    • aws_ssm_association was skipped because Associations are not implemented yet (SSM-3).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant