diff --git a/cmd/get/get.go b/cmd/get/get.go index 93f3043..6a5f639 100644 --- a/cmd/get/get.go +++ b/cmd/get/get.go @@ -50,6 +50,7 @@ import ( "github.com/awslabs/eksdemo/pkg/resource/security_group_rule" "github.com/awslabs/eksdemo/pkg/resource/sqs_queue" ssmnode "github.com/awslabs/eksdemo/pkg/resource/ssm/node" + "github.com/awslabs/eksdemo/pkg/resource/ssm/parameter" "github.com/awslabs/eksdemo/pkg/resource/ssm/session" "github.com/awslabs/eksdemo/pkg/resource/subnet" "github.com/awslabs/eksdemo/pkg/resource/target_group" @@ -124,6 +125,7 @@ func NewGetCmd() *cobra.Command { cmd.AddCommand(security_group_rule.NewResource().NewGetCmd()) cmd.AddCommand(sqs_queue.NewResource().NewGetCmd()) cmd.AddCommand(ssmnode.NewResource().NewGetCmd()) + cmd.AddCommand(parameter.NewResource().NewGetCmd()) cmd.AddCommand(session.NewResource().NewGetCmd()) cmd.AddCommand(subnet.NewResource().NewGetCmd()) cmd.AddCommand(target_group.NewResource().NewGetCmd()) diff --git a/pkg/application/aws_lb_controller/aws_lb_controller.go b/pkg/application/aws_lb_controller/aws_lb_controller.go index 3294f25..d0fad88 100644 --- a/pkg/application/aws_lb_controller/aws_lb_controller.go +++ b/pkg/application/aws_lb_controller/aws_lb_controller.go @@ -13,7 +13,7 @@ import ( // GitHub: https://github.com/kubernetes-sigs/aws-load-balancer-controller // Helm: https://github.com/aws/eks-charts/tree/master/stable/aws-load-balancer-controller // Repo: https://gallery.ecr.aws/eks/aws-load-balancer-controller -// Version: Latest is v2.7.0 (as of 2/1/24) +// Version: Latest is v2.8.1 (as of 6/1/24) from 2.7.0, was 2/1/24 func NewApp() *application.Application { app := &application.Application{ @@ -222,6 +222,7 @@ Statement: Resource: "*" ` +// https://github.com/aws/eks-charts/blob/master/stable/aws-load-balancer-controller/values.yaml const valuesTemplate = `--- replicaCount: {{ .Replicas }} image: diff --git a/pkg/aws/ssm.go b/pkg/aws/ssm.go index 48ae9ac..f986fd2 100644 --- a/pkg/aws/ssm.go +++ b/pkg/aws/ssm.go @@ -97,6 +97,29 @@ func (c *SSMClient) GetParameter(name string) (*types.Parameter, error) { return out.Parameter, nil } +func (c *SSMClient) GetParametersByPath(path string) ([]types.Parameter, error) { + parameters := []types.Parameter{} + pageNum := 0 + + input := &ssm.GetParametersByPathInput{ + Path: aws.String(path), + Recursive: aws.Bool(true), + } + + paginator := ssm.NewGetParametersByPathPaginator(c.Client, input) + + for paginator.HasMorePages() && pageNum < maxPages { + out, err := paginator.NextPage(context.Background()) + if err != nil { + return nil, err + } + parameters = append(parameters, out.Parameters...) + pageNum++ + } + + return parameters, nil +} + func (c *SSMClient) StartSession(documentName, target string, params map[string][]string) (*ssm.StartSessionOutput, error) { input := &ssm.StartSessionInput{ DocumentName: aws.String(documentName), diff --git a/pkg/resource/ssm/parameter/get.go b/pkg/resource/ssm/parameter/get.go new file mode 100644 index 0000000..f7c934c --- /dev/null +++ b/pkg/resource/ssm/parameter/get.go @@ -0,0 +1,59 @@ +package parameter + +import ( + "errors" + "os" + + "github.com/aws/aws-sdk-go-v2/service/ssm/types" + "github.com/awslabs/eksdemo/pkg/aws" + "github.com/awslabs/eksdemo/pkg/printer" + "github.com/awslabs/eksdemo/pkg/resource" +) + +type Getter struct { + ssmClient *aws.SSMClient +} + +func NewGetter(ssmClient *aws.SSMClient) *Getter { + return &Getter{ssmClient} +} + +func (g *Getter) Init() { + if g.ssmClient == nil { + g.ssmClient = aws.NewSSMClient() + } +} + +func (g *Getter) Get(pathOrName string, output printer.Output, options resource.Options) error { + params, err := g.GetByPathOrName(pathOrName) + if err != nil { + return err + } + + return output.Print(os.Stdout, NewPrinter(params)) +} + +func (g *Getter) GetByPathOrName(pathOrName string) ([]types.Parameter, error) { + params, err := g.ssmClient.GetParametersByPath(pathOrName) + if err != nil { + return nil, err + } + + if len(params) > 0 { + return params, nil + } + + param, err := g.ssmClient.GetParameter(pathOrName) + + // Return all errors except NotFound + var rnfe *types.ParameterNotFound + if err != nil && !errors.As(err, &rnfe) { + return nil, err + } + + if param != nil { + return []types.Parameter{*param}, nil + } + + return nil, nil +} diff --git a/pkg/resource/ssm/parameter/printer.go b/pkg/resource/ssm/parameter/printer.go new file mode 100644 index 0000000..bf48bfc --- /dev/null +++ b/pkg/resource/ssm/parameter/printer.go @@ -0,0 +1,46 @@ +package parameter + +import ( + "io" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/ssm/types" + "github.com/awslabs/eksdemo/pkg/printer" + "github.com/hako/durafmt" +) + +type Printer struct { + params []types.Parameter +} + +func NewPrinter(params []types.Parameter) *Printer { + return &Printer{params} +} + +func (p *Printer) PrintTable(writer io.Writer) error { + table := printer.NewTablePrinter() + table.SetHeader([]string{"Age", "Name", "Value"}) + + for _, p := range p.params { + age := durafmt.ParseShort(time.Since(aws.ToTime(p.LastModifiedDate))) + + table.AppendRow([]string{ + age.String(), + aws.ToString(p.Name), + aws.ToString(p.Value), + }) + } + + table.Print(writer) + + return nil +} + +func (p *Printer) PrintJSON(writer io.Writer) error { + return printer.EncodeJSON(writer, p.params) +} + +func (p *Printer) PrintYAML(writer io.Writer) error { + return printer.EncodeYAML(writer, p.params) +} diff --git a/pkg/resource/ssm/parameter/ssm_parameter.go b/pkg/resource/ssm/parameter/ssm_parameter.go new file mode 100644 index 0000000..670097f --- /dev/null +++ b/pkg/resource/ssm/parameter/ssm_parameter.go @@ -0,0 +1,23 @@ +package parameter + +import ( + "github.com/awslabs/eksdemo/pkg/cmd" + "github.com/awslabs/eksdemo/pkg/resource" +) + +func NewResource() *resource.Resource { + return &resource.Resource{ + Command: cmd.Command{ + Name: "ssm-parameter", + Description: "SSM Parameter", + Aliases: []string{"ssm-parameters", "ssm-params", "ssm-param", "params", "param"}, + Args: []string{"PATH_OR_NAME"}, + }, + + Getter: &Getter{}, + + Options: &resource.CommonOptions{ + ClusterFlagDisabled: true, + }, + } +}