ssm-browse: new utility to browse SSM parameters
This is more of an exercise to work out how best to use controllers
This commit is contained in:
parent
46be54b5fb
commit
0b745a6dfa
44
cmd/ssm-browse/main.go
Normal file
44
cmd/ssm-browse/main.go
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/config"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/service/ssm"
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"github.com/charmbracelet/lipgloss"
|
||||||
|
"github.com/lmika/awstools/internal/common/ui/logging"
|
||||||
|
"github.com/lmika/awstools/internal/ssm-browse/controllers"
|
||||||
|
"github.com/lmika/awstools/internal/ssm-browse/providers/awsssm"
|
||||||
|
"github.com/lmika/awstools/internal/ssm-browse/services/ssmparameters"
|
||||||
|
"github.com/lmika/awstools/internal/ssm-browse/ui"
|
||||||
|
"github.com/lmika/gopkgs/cli"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Pre-determine if layout has dark background. This prevents calls for creating a list to hang.
|
||||||
|
lipgloss.HasDarkBackground()
|
||||||
|
|
||||||
|
closeFn := logging.EnableLogging()
|
||||||
|
defer closeFn()
|
||||||
|
|
||||||
|
cfg, err := config.LoadDefaultConfig(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
cli.Fatalf("cannot load AWS config: %v", err)
|
||||||
|
}
|
||||||
|
ssmClient := ssm.NewFromConfig(cfg)
|
||||||
|
|
||||||
|
provider := awsssm.NewProvider(ssmClient)
|
||||||
|
service := ssmparameters.NewService(provider)
|
||||||
|
|
||||||
|
ctrl := controllers.New(service)
|
||||||
|
model := ui.NewModel(ctrl)
|
||||||
|
|
||||||
|
p := tea.NewProgram(model, tea.WithAltScreen())
|
||||||
|
|
||||||
|
if err := p.Start(); err != nil {
|
||||||
|
fmt.Printf("Alas, there's been an error: %v", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
9
go.mod
9
go.mod
|
@ -5,7 +5,7 @@ go 1.18
|
||||||
require (
|
require (
|
||||||
github.com/alecthomas/participle/v2 v2.0.0-alpha7
|
github.com/alecthomas/participle/v2 v2.0.0-alpha7
|
||||||
github.com/asdine/storm v2.1.2+incompatible
|
github.com/asdine/storm v2.1.2+incompatible
|
||||||
github.com/aws/aws-sdk-go-v2 v1.15.0
|
github.com/aws/aws-sdk-go-v2 v1.16.1
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.13.1
|
github.com/aws/aws-sdk-go-v2/config v1.13.1
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.8.0
|
github.com/aws/aws-sdk-go-v2/credentials v1.8.0
|
||||||
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.8.0
|
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.8.0
|
||||||
|
@ -27,16 +27,17 @@ require (
|
||||||
require (
|
require (
|
||||||
github.com/atotto/clipboard v0.1.4 // indirect
|
github.com/atotto/clipboard v0.1.4 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.10.0 // indirect
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.10.0 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.6 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.8 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.0 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.2 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.5 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.5 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.13.0 // indirect
|
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.13.0 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.0 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.0 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.0 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.0 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.7.0 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.7.0 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/ssm v1.24.0 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.9.0 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sso v1.9.0 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.14.0 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sts v1.14.0 // indirect
|
||||||
github.com/aws/smithy-go v1.11.1 // indirect
|
github.com/aws/smithy-go v1.11.2 // indirect
|
||||||
github.com/containerd/console v1.0.3 // indirect
|
github.com/containerd/console v1.0.3 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||||
|
|
10
go.sum
10
go.sum
|
@ -10,6 +10,8 @@ github.com/aws/aws-sdk-go-v2 v1.13.0 h1:1XIXAfxsEmbhbj5ry3D3vX+6ZcUYvIqSm4CWWEuG
|
||||||
github.com/aws/aws-sdk-go-v2 v1.13.0/go.mod h1:L6+ZpqHaLbAaxsqV0L4cvxZY7QupWJB4fhkf8LXvC7w=
|
github.com/aws/aws-sdk-go-v2 v1.13.0/go.mod h1:L6+ZpqHaLbAaxsqV0L4cvxZY7QupWJB4fhkf8LXvC7w=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.15.0 h1:f9kWLNfyCzCB43eupDAk3/XgJ2EpgktiySD6leqs0js=
|
github.com/aws/aws-sdk-go-v2 v1.15.0 h1:f9kWLNfyCzCB43eupDAk3/XgJ2EpgktiySD6leqs0js=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.15.0/go.mod h1:lJYcuZZEHWNIb6ugJjbQY1fykdoobWbOS7kJYb4APoI=
|
github.com/aws/aws-sdk-go-v2 v1.15.0/go.mod h1:lJYcuZZEHWNIb6ugJjbQY1fykdoobWbOS7kJYb4APoI=
|
||||||
|
github.com/aws/aws-sdk-go-v2 v1.16.1 h1:udzee98w8H6ikRgtFdVN9JzzYEbi/quFfSvduZETJIU=
|
||||||
|
github.com/aws/aws-sdk-go-v2 v1.16.1/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU=
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.13.1 h1:yLv8bfNoT4r+UvUKQKqRtdnvuWGMK5a82l4ru9Jvnuo=
|
github.com/aws/aws-sdk-go-v2/config v1.13.1 h1:yLv8bfNoT4r+UvUKQKqRtdnvuWGMK5a82l4ru9Jvnuo=
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.13.1/go.mod h1:Ba5Z4yL/UGbjQUzsiaN378YobhFo0MLfueXGiOsYtEs=
|
github.com/aws/aws-sdk-go-v2/config v1.13.1/go.mod h1:Ba5Z4yL/UGbjQUzsiaN378YobhFo0MLfueXGiOsYtEs=
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.8.0 h1:8Ow0WcyDesGNL0No11jcgb1JAtE+WtubqXjgxau+S0o=
|
github.com/aws/aws-sdk-go-v2/credentials v1.8.0 h1:8Ow0WcyDesGNL0No11jcgb1JAtE+WtubqXjgxau+S0o=
|
||||||
|
@ -22,10 +24,14 @@ github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.4 h1:CRiQJ4E2RhfDdqbie1
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.4/go.mod h1:XHgQ7Hz2WY2GAn//UXHofLfPXWh+s62MbMOijrg12Lw=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.4/go.mod h1:XHgQ7Hz2WY2GAn//UXHofLfPXWh+s62MbMOijrg12Lw=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.6 h1:xiGjGVQsem2cxoIX61uRGy+Jux2s9C/kKbTrWLdrU54=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.6 h1:xiGjGVQsem2cxoIX61uRGy+Jux2s9C/kKbTrWLdrU54=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.6/go.mod h1:SSPEdf9spsFgJyhjrXvawfpyzrXHBCUe+2eQ1CjC1Ak=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.6/go.mod h1:SSPEdf9spsFgJyhjrXvawfpyzrXHBCUe+2eQ1CjC1Ak=
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.8 h1:CDaO90VZVBAL1sK87S5oSPIrp7yZqORv1hPIi2UsTMk=
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.8/go.mod h1:LnTQMTqbKsbtt+UI5+wPsB7jedW+2ZgozoPG8k6cMxg=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.2.0 h1:3ADoioDMOtF4uiK59vCpplpCwugEU+v4ZFD29jDL3RQ=
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.2.0 h1:3ADoioDMOtF4uiK59vCpplpCwugEU+v4ZFD29jDL3RQ=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.2.0/go.mod h1:BsCSJHx5DnDXIrOcqB8KN1/B+hXLG/bi4Y6Vjcx/x9E=
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.2.0/go.mod h1:BsCSJHx5DnDXIrOcqB8KN1/B+hXLG/bi4Y6Vjcx/x9E=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.0 h1:bt3zw79tm209glISdMRCIVRCwvSDXxgAxh5KWe2qHkY=
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.0 h1:bt3zw79tm209glISdMRCIVRCwvSDXxgAxh5KWe2qHkY=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.0/go.mod h1:viTrxhAuejD+LszDahzAE2x40YjYWhMqzHxv2ZiWaME=
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.0/go.mod h1:viTrxhAuejD+LszDahzAE2x40YjYWhMqzHxv2ZiWaME=
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.2 h1:XXR3cdOcKRCTZf6ctcqpMf+go1BdzTm6+T9Ul5zxcMI=
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.2/go.mod h1:1x4ZP3Z8odssdhuLI+/1Tqw6Pt/VAaP4Tr8EUxHvPXE=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.5 h1:ixotxbfTCFpqbuwFv/RcZwyzhkxPSYDYEMcj4niB5Uk=
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.5 h1:ixotxbfTCFpqbuwFv/RcZwyzhkxPSYDYEMcj4niB5Uk=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.5/go.mod h1:R3sWUqPcfXSiF/LSFJhjyJmpg9uV6yP2yv3YZZjldVI=
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.5/go.mod h1:R3sWUqPcfXSiF/LSFJhjyJmpg9uV6yP2yv3YZZjldVI=
|
||||||
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.15.0 h1:qnx+WyIH9/AD+wAxi05WCMNanO236ceqHg6hChCWs3M=
|
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.15.0 h1:qnx+WyIH9/AD+wAxi05WCMNanO236ceqHg6hChCWs3M=
|
||||||
|
@ -40,6 +46,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.7.0 h1:4QAOB3KrvI
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.7.0/go.mod h1:K/qPe6AP2TGYv4l6n7c88zh9jWBDf6nHhvg1fx/EWfU=
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.7.0/go.mod h1:K/qPe6AP2TGYv4l6n7c88zh9jWBDf6nHhvg1fx/EWfU=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sqs v1.16.0 h1:dzWS4r8E9bA0TesHM40FSAtedwpTVCuTsLI8EziSqyk=
|
github.com/aws/aws-sdk-go-v2/service/sqs v1.16.0 h1:dzWS4r8E9bA0TesHM40FSAtedwpTVCuTsLI8EziSqyk=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sqs v1.16.0/go.mod h1:IBTQMG8mtyj37OWg7vIXcg714Ntcb/LlYou/rZpvV1k=
|
github.com/aws/aws-sdk-go-v2/service/sqs v1.16.0/go.mod h1:IBTQMG8mtyj37OWg7vIXcg714Ntcb/LlYou/rZpvV1k=
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/ssm v1.24.0 h1:p22U2yL/AeRToERGcZv1R26Yci5VQnWIrpzcZdG54cg=
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/ssm v1.24.0/go.mod h1:chcyLYBEVRac/7rWJsD6cUHUR2osROwavvNqCplfwog=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.9.0 h1:1qLJeQGBmNQW3mBNzK2CFmrQNmoXWrscPqsrAaU1aTA=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.9.0 h1:1qLJeQGBmNQW3mBNzK2CFmrQNmoXWrscPqsrAaU1aTA=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.9.0/go.mod h1:vCV4glupK3tR7pw7ks7Y4jYRL86VvxS+g5qk04YeWrU=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.9.0/go.mod h1:vCV4glupK3tR7pw7ks7Y4jYRL86VvxS+g5qk04YeWrU=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.14.0 h1:ksiDXhvNYg0D2/UFkLejsaz3LqpW5yjNQ8Nx9Sn2c0E=
|
github.com/aws/aws-sdk-go-v2/service/sts v1.14.0 h1:ksiDXhvNYg0D2/UFkLejsaz3LqpW5yjNQ8Nx9Sn2c0E=
|
||||||
|
@ -48,6 +56,8 @@ github.com/aws/smithy-go v1.10.0 h1:gsoZQMNHnX+PaghNw4ynPsyGP7aUCqx5sY2dlPQsZ0w=
|
||||||
github.com/aws/smithy-go v1.10.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
|
github.com/aws/smithy-go v1.10.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
|
||||||
github.com/aws/smithy-go v1.11.1 h1:IQ+lPZVkSM3FRtyaDox41R8YS6iwPMYIreejOgPW49g=
|
github.com/aws/smithy-go v1.11.1 h1:IQ+lPZVkSM3FRtyaDox41R8YS6iwPMYIreejOgPW49g=
|
||||||
github.com/aws/smithy-go v1.11.1/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM=
|
github.com/aws/smithy-go v1.11.1/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM=
|
||||||
|
github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE=
|
||||||
|
github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM=
|
||||||
github.com/brianvoe/gofakeit/v6 v6.15.0 h1:lJPGJZ2/07TRGDazyTzD5b18N3y4tmmJpdhCUw18FlI=
|
github.com/brianvoe/gofakeit/v6 v6.15.0 h1:lJPGJZ2/07TRGDazyTzD5b18N3y4tmmJpdhCUw18FlI=
|
||||||
github.com/brianvoe/gofakeit/v6 v6.15.0/go.mod h1:Ow6qC71xtwm79anlwKRlWZW6zVq9D2XHE4QSSMP/rU8=
|
github.com/brianvoe/gofakeit/v6 v6.15.0/go.mod h1:Ow6qC71xtwm79anlwKRlWZW6zVq9D2XHE4QSSMP/rU8=
|
||||||
github.com/calyptia/go-bubble-table v0.1.0 h1:mXpaaBlrHGH4K8v5PvM8YqBFT9jlysS1YOycU2u3gEQ=
|
github.com/calyptia/go-bubble-table v0.1.0 h1:mXpaaBlrHGH4K8v5PvM8YqBFT9jlysS1YOycU2u3gEQ=
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
package events
|
package events
|
||||||
|
|
||||||
import tea "github.com/charmbracelet/bubbletea"
|
import (
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
func Error(err error) tea.Msg {
|
func Error(err error) tea.Msg {
|
||||||
|
log.Println(err)
|
||||||
return ErrorMsg(err)
|
return ErrorMsg(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
18
internal/common/ui/logging/debug.go
Normal file
18
internal/common/ui/logging/debug.go
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
package logging
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func EnableLogging() (closeFn func()) {
|
||||||
|
f, err := tea.LogToFile("debug.log", "debug")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("fatal:", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return func() {
|
||||||
|
f.Close()
|
||||||
|
}
|
||||||
|
}
|
7
internal/ssm-browse/controllers/events.go
Normal file
7
internal/ssm-browse/controllers/events.go
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import "github.com/lmika/awstools/internal/ssm-browse/models"
|
||||||
|
|
||||||
|
type NewParameterListMsg struct {
|
||||||
|
Parameters *models.SSMParameters
|
||||||
|
}
|
31
internal/ssm-browse/controllers/ssmcontroller.go
Normal file
31
internal/ssm-browse/controllers/ssmcontroller.go
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"github.com/lmika/awstools/internal/common/ui/events"
|
||||||
|
"github.com/lmika/awstools/internal/ssm-browse/services/ssmparameters"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SSMController struct {
|
||||||
|
service *ssmparameters.Service
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(service *ssmparameters.Service) *SSMController {
|
||||||
|
return &SSMController{
|
||||||
|
service: service,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *SSMController) Fetch() tea.Cmd {
|
||||||
|
return func() tea.Msg {
|
||||||
|
res, err := c.service.List(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
return events.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewParameterListMsg{
|
||||||
|
Parameters: res,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
internal/ssm-browse/models/models.go
Normal file
10
internal/ssm-browse/models/models.go
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package models
|
||||||
|
|
||||||
|
type SSMParameters struct {
|
||||||
|
Items []SSMParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
type SSMParameter struct {
|
||||||
|
Name string
|
||||||
|
Value string
|
||||||
|
}
|
42
internal/ssm-browse/providers/awsssm/provider.go
Normal file
42
internal/ssm-browse/providers/awsssm/provider.go
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
package awsssm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/aws"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/service/ssm"
|
||||||
|
"github.com/lmika/awstools/internal/ssm-browse/models"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Provider struct {
|
||||||
|
client *ssm.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProvider(client *ssm.Client) *Provider {
|
||||||
|
return &Provider{
|
||||||
|
client: client,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Provider) List(ctx context.Context) (*models.SSMParameters, error) {
|
||||||
|
pars, err := p.client.GetParametersByPath(ctx, &ssm.GetParametersByPathInput{
|
||||||
|
Path: aws.String("/"),
|
||||||
|
MaxResults: 10,
|
||||||
|
Recursive: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "cannot get parameters from path")
|
||||||
|
}
|
||||||
|
|
||||||
|
res := &models.SSMParameters{
|
||||||
|
Items: make([]models.SSMParameter, len(pars.Parameters)),
|
||||||
|
}
|
||||||
|
for i, p := range pars.Parameters {
|
||||||
|
res.Items[i] = models.SSMParameter{
|
||||||
|
Name: aws.ToString(p.Name),
|
||||||
|
Value: aws.ToString(p.Value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
10
internal/ssm-browse/services/ssmparameters/iface.go
Normal file
10
internal/ssm-browse/services/ssmparameters/iface.go
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package ssmparameters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/lmika/awstools/internal/ssm-browse/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SSMProvider interface {
|
||||||
|
List(ctx context.Context) (*models.SSMParameters, error)
|
||||||
|
}
|
20
internal/ssm-browse/services/ssmparameters/service.go
Normal file
20
internal/ssm-browse/services/ssmparameters/service.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package ssmparameters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/lmika/awstools/internal/ssm-browse/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
provider SSMProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewService(provider SSMProvider) *Service {
|
||||||
|
return &Service{
|
||||||
|
provider: provider,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) List(ctx context.Context) (*models.SSMParameters, error) {
|
||||||
|
return s.provider.List(ctx)
|
||||||
|
}
|
55
internal/ssm-browse/ui/model.go
Normal file
55
internal/ssm-browse/ui/model.go
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"github.com/lmika/awstools/internal/dynamo-browse/ui/teamodels/layout"
|
||||||
|
"github.com/lmika/awstools/internal/dynamo-browse/ui/teamodels/statusandprompt"
|
||||||
|
"github.com/lmika/awstools/internal/ssm-browse/controllers"
|
||||||
|
"github.com/lmika/awstools/internal/ssm-browse/ui/ssmlist"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Model struct {
|
||||||
|
controller *controllers.SSMController
|
||||||
|
|
||||||
|
root tea.Model
|
||||||
|
ssmList *ssmlist.Model
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewModel(controller *controllers.SSMController) Model {
|
||||||
|
ssmList := ssmlist.New()
|
||||||
|
root := layout.FullScreen(
|
||||||
|
statusandprompt.New(ssmList, "Hello SSM"),
|
||||||
|
)
|
||||||
|
|
||||||
|
return Model{
|
||||||
|
controller: controller,
|
||||||
|
root: root,
|
||||||
|
ssmList: ssmList,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (m Model) Init() tea.Cmd {
|
||||||
|
return m.controller.Fetch()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case controllers.NewParameterListMsg:
|
||||||
|
m.ssmList.SetParameters(msg.Parameters)
|
||||||
|
case tea.KeyMsg:
|
||||||
|
switch msg.String() {
|
||||||
|
case "ctrl+c", "q":
|
||||||
|
return m, tea.Quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newRoot, cmd := m.root.Update(msg)
|
||||||
|
m.root = newRoot
|
||||||
|
return m, cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) View() string {
|
||||||
|
return m.root.View()
|
||||||
|
}
|
||||||
|
|
69
internal/ssm-browse/ui/ssmlist/ssmlist.go
Normal file
69
internal/ssm-browse/ui/ssmlist/ssmlist.go
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
package ssmlist
|
||||||
|
|
||||||
|
import (
|
||||||
|
table "github.com/calyptia/go-bubble-table"
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"github.com/charmbracelet/lipgloss"
|
||||||
|
"github.com/lmika/awstools/internal/dynamo-browse/ui/teamodels/frame"
|
||||||
|
"github.com/lmika/awstools/internal/dynamo-browse/ui/teamodels/layout"
|
||||||
|
"github.com/lmika/awstools/internal/ssm-browse/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Model struct {
|
||||||
|
frameTitle frame.FrameTitle
|
||||||
|
table table.Model
|
||||||
|
|
||||||
|
parameters *models.SSMParameters
|
||||||
|
|
||||||
|
w, h int
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() *Model {
|
||||||
|
frameTitle := frame.NewFrameTitle("SSM", true)
|
||||||
|
table := table.New([]string{"name", "type", "value"}, 0, 0)
|
||||||
|
|
||||||
|
return &Model{
|
||||||
|
frameTitle: frameTitle,
|
||||||
|
table: table,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Model) SetParameters(parameters *models.SSMParameters) {
|
||||||
|
m.parameters = parameters
|
||||||
|
cols := []string{"name", "type", "value"}
|
||||||
|
|
||||||
|
newTbl := table.New(cols, m.w, m.h-m.frameTitle.HeaderHeight())
|
||||||
|
newRows := make([]table.Row, len(parameters.Items))
|
||||||
|
for i, r := range parameters.Items {
|
||||||
|
newRows[i] = itemTableRow{r}
|
||||||
|
}
|
||||||
|
newTbl.SetRows(newRows)
|
||||||
|
|
||||||
|
m.table = newTbl
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Model) Init() tea.Cmd {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
|
var cmd tea.Cmd
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case tea.KeyMsg:
|
||||||
|
m.table, cmd = m.table.Update(msg)
|
||||||
|
return m, cmd
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Model) View() string {
|
||||||
|
return lipgloss.JoinVertical(lipgloss.Top, m.frameTitle.View(), m.table.View())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Model) Resize(w, h int) layout.ResizingModel {
|
||||||
|
m.w, m.h = w, h
|
||||||
|
m.frameTitle.Resize(w, h)
|
||||||
|
m.table.SetSize(w, h - m.frameTitle.HeaderHeight())
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
22
internal/ssm-browse/ui/ssmlist/tblmodel.go
Normal file
22
internal/ssm-browse/ui/ssmlist/tblmodel.go
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package ssmlist
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
table "github.com/calyptia/go-bubble-table"
|
||||||
|
"github.com/lmika/awstools/internal/ssm-browse/models"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type itemTableRow struct {
|
||||||
|
item models.SSMParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mtr itemTableRow) Render(w io.Writer, model table.Model, index int) {
|
||||||
|
line := fmt.Sprintf("%s\t%s\t%s", mtr.item.Name, "String", mtr.item.Value)
|
||||||
|
|
||||||
|
if index == model.Cursor() {
|
||||||
|
fmt.Fprintln(w, model.Styles.SelectedRow.Render(line))
|
||||||
|
} else {
|
||||||
|
fmt.Fprintln(w, line)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue