internal/pkg/exec/ssm_plugin.go (59 lines of code) (raw):
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package exec provides an interface to execute certain commands.
package exec
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ecs"
)
const (
ssmPluginBinaryName = "session-manager-plugin"
startSessionAction = "StartSession"
executableNotExistErrMessage = "executable file not found"
ssmPluginBinaryLatestVersionURL = "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/VERSION"
)
// SSMPluginCommand represents commands that can be run to trigger the ssm plugin.
type SSMPluginCommand struct {
sess *session.Session
runner
http httpClient
// facilitate unit test.
latestVersionBuffer bytes.Buffer
currentVersionBuffer bytes.Buffer
linuxDistVersionBuffer bytes.Buffer
tempDir string
}
// NewSSMPluginCommand returns a SSMPluginCommand.
func NewSSMPluginCommand(s *session.Session) SSMPluginCommand {
return SSMPluginCommand{
runner: NewCmd(),
sess: s,
http: http.DefaultClient,
}
}
// StartSession starts a session using the ssm plugin.
func (s SSMPluginCommand) StartSession(ssmSess *ecs.Session) error {
response, err := json.Marshal(ssmSess)
if err != nil {
return fmt.Errorf("marshal session response: %w", err)
}
if err := s.runner.InteractiveRun(ssmPluginBinaryName,
[]string{string(response), aws.StringValue(s.sess.Config.Region), startSessionAction}); err != nil {
return fmt.Errorf("start session: %w", err)
}
return nil
}
func download(client httpClient, filepath string, url string) error {
resp, err := client.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
return err
}