Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

Commit

Permalink
Merge pull request #4822 from hashicorp/cli-config-source-list
Browse files Browse the repository at this point in the history
Add CLI option to get all config sources with `config source-get`
  • Loading branch information
paladin-devops committed Jun 30, 2023
2 parents 076667d + d43575f commit 314efef
Show file tree
Hide file tree
Showing 10 changed files with 1,899 additions and 1,564 deletions.
8 changes: 8 additions & 0 deletions .changelog/4822.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
```release-note:improvement
cli: Add option `all` to flag `-scope` on `waypoint config source-get` command
to output all config sources.
```
```release-note:improvement
cli: Add config source's plugin type, scope, project, app, and workspace to
output of `waypoint config source-get` when getting a specific config source.
```
134 changes: 110 additions & 24 deletions internal/cli/config_source_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ func (c *ConfigSourceGetCommand) Run(args []string) int {
return 1
}

// type is required
if c.flagType == "" {
// type is required if not all config sources are being retrieved
if c.flagScope != "all" && c.flagType == "" {
c.ui.Output("A source type must be specified with '-type'.\n"+c.Help(), terminal.WithErrorStyle())
return 1
}
Expand Down Expand Up @@ -70,6 +70,9 @@ func (c *ConfigSourceGetCommand) Run(args []string) int {
},
}

case "all":
getConfigSourceRequest.Scope = &pb.GetConfigSourceRequest_All{All: true}

default:
err := fmt.Errorf("-scope needs to be one of 'global', 'project', or 'app'")
c.project.UI.Output(clierrors.Humanize(err), terminal.WithErrorStyle())
Expand All @@ -84,28 +87,111 @@ func (c *ConfigSourceGetCommand) Run(args []string) int {
return 1
}

if len(resp.ConfigSources) == 0 {
c.project.UI.Output(
"Dynamic config source %q is not configured.\n\n"+
"Note that this doesn't mean that this config source is not usable.\n"+
"Many config sources work with no explicitly set configurations.",
c.flagType, terminal.WithErrorStyle())
return 1
}
var table *terminal.Table
var scope, project, app, workspace string
if c.flagScope == "all" {
if len(resp.ConfigSources) == 0 {
c.project.UI.Output(
"No dynamic config sources are configured.\nUse the command "+
"\"waypoint config source-set\" to add config sources.",
terminal.WithWarningStyle())
return 0
}
table = terminal.NewTable("Type", "Scope", "Project", "App", "Workspace")
for _, cs := range resp.ConfigSources {
switch ref := cs.Scope.(type) {
case *pb.ConfigSource_Global:
scope = "global"
case *pb.ConfigSource_Project:
scope = "project"
project = ref.Project.Project
case *pb.ConfigSource_Application:
scope = "app"
project = ref.Application.Project
app = ref.Application.Application
}

if cs.Workspace != nil {
workspace = cs.Workspace.Workspace
}
table.Rich([]string{
cs.Type,
scope,
project,
app,
workspace,
}, []string{
"",
"",
"",
"",
"",
})
}
} else {
if len(resp.ConfigSources) == 0 {
c.project.UI.Output(
"Dynamic config source %q is not configured.\n\n"+
"Note that this doesn't mean that this config source is not usable.\n"+
"Many config sources work with no explicitly set configurations.",
c.flagType, terminal.WithErrorStyle())
return 1
}

// we use the first value because this will be the most specific since
// we do a prefix search.
cs := resp.ConfigSources[len(resp.ConfigSources)-1]
table := terminal.NewTable("Key", "Value")
for k, v := range cs.Config {
table.Rich([]string{
k,
v,
}, []string{
"",
"",
})
// we use the first value because this will be the most specific since
// we do a prefix search.
cs := resp.ConfigSources[len(resp.ConfigSources)-1]
switch ref := cs.Scope.(type) {
case *pb.ConfigSource_Global:
scope = "global"
case *pb.ConfigSource_Project:
scope = "project"
project = ref.Project.Project
case *pb.ConfigSource_Application:
scope = "app"
project = ref.Application.Project
app = ref.Application.Application
}

if cs.Workspace != nil {
workspace = cs.Workspace.Workspace
}
// Show config source info in a flat list where each project option
//is its own row
c.ui.Output("Config Source Info:", terminal.WithHeaderStyle())

// Unset value strings will be omitted automatically
c.ui.NamedValues([]terminal.NamedValue{
{
Name: "Type", Value: cs.Type,
},
{
Name: "Scope", Value: scope,
},
{
Name: "Project", Value: project,
},
{
Name: "App", Value: app,
},
{
Name: "Workspace", Value: workspace,
},
}, terminal.WithInfoStyle())
c.ui.Output("")

table = terminal.NewTable("Key", "Value")
for k, v := range cs.Config {
table.Rich([]string{
k,
v,
}, []string{
"",
"",
})
}
}

c.ui.Table(table)
return 0
}
Expand All @@ -122,8 +208,8 @@ func (c *ConfigSourceGetCommand) Flags() *flag.Sets {
f.StringVar(&flag.StringVar{
Name: "scope",
Usage: "The scope for this configuration source. The configuration source " +
"will only appear within this scope. This can be one of 'global', 'project'," +
" or 'app'.",
"will only appear within this scope. This can be one of 'all', " +
"'global', 'project', or 'app'.",
Default: "project",
Target: &c.flagScope,
})
Expand Down
108 changes: 71 additions & 37 deletions internal/server/boltdbstate/config_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ func (s *State) configSourceGetMerged(

sources = append(sources, appSources...)

case *pb.GetConfigSourceRequest_All:
sources, err = s.configSourceGetExact(dbTxn, memTxn, ws, nil, req.Type)
if err != nil {
return nil, err
}
goto SORT
default:
panic("unknown scope")
}
Expand All @@ -192,13 +198,13 @@ func (s *State) configSourceGetMerged(
}
}

SORT:
var result []*pb.ConfigSource
for _, source := range sources {
if source != nil {
result = append(result, source)
}
}

sort.Sort(serversort.ConfigSource(result))

return result, nil
Expand All @@ -216,47 +222,64 @@ func (s *State) configSourceGetExact(
// We have to get the correct iterator based on the scope. We check the
// scope and use the proper index to get the iterator here.
var iter memdb.ResultIterator
switch ref := ref.(type) {
case *pb.Ref_Global:
var err error
iter, err = memTxn.Get(
configSourceIndexTableName,
configSourceIndexGlobalIndexName+"_prefix",
true,
typeVal,
)
if err != nil {
return nil, err
}
var err error
if ref != nil {
switch ref := ref.(type) {
case *pb.Ref_Global:
iter, err = memTxn.Get(
configSourceIndexTableName,
configSourceIndexGlobalIndexName+"_prefix",
true,
typeVal,
)
if err != nil {
return nil, err
}

case *pb.Ref_Project:
var err error
iter, err = memTxn.Get(
configSourceIndexTableName,
configIndexProjectIndexName+"_prefix",
ref.Project,
true,
typeVal,
)
if err != nil {
return nil, err
}
case *pb.Ref_Project:
iter, err = memTxn.Get(
configSourceIndexTableName,
configIndexProjectIndexName+"_prefix",
ref.Project,
true,
typeVal,
)
if err != nil {
return nil, err
}

case *pb.Ref_Application:
var err error
iter, err = memTxn.Get(
configSourceIndexTableName,
configSourceIndexApplicationIndexName+"_prefix",
ref.Project,
ref.Application,
typeVal,
)
case *pb.Ref_Application:
iter, err = memTxn.Get(
configSourceIndexTableName,
configSourceIndexApplicationIndexName+"_prefix",
ref.Project,
ref.Application,
typeVal,
)
if err != nil {
return nil, err
}

default:
panic("unknown scope")
}
} else {
// if no scope was passed in here, we're either getting all config
// sources, or getting all config sources of a certain type
if typeVal != "" {
iter, err = memTxn.Get(
configSourceIndexTableName,
configSourceIndexTypeIndexName+"_prefix",
typeVal)
} else {
iter, err = memTxn.Get(
configSourceIndexTableName,
configSourceIndexIdIndexName+"_prefix",
"")
}
if err != nil {
return nil, err
}

default:
panic("unknown scope")
}

// Add to our watchset
Expand Down Expand Up @@ -381,6 +404,16 @@ func configSourceIndexSchema() *memdb.TableSchema {
},
},

configSourceIndexTypeIndexName: {
Name: configSourceIndexTypeIndexName,
AllowMissing: false,
Unique: false,
Indexer: &memdb.StringFieldIndex{
Field: "Type",
Lowercase: true,
},
},

configSourceIndexGlobalIndexName: {
Name: configSourceIndexGlobalIndexName,
AllowMissing: true,
Expand Down Expand Up @@ -452,6 +485,7 @@ func configSourceIndexSchema() *memdb.TableSchema {
const (
configSourceIndexTableName = "config-source-index"
configSourceIndexIdIndexName = "id"
configSourceIndexTypeIndexName = "type"
configSourceIndexGlobalIndexName = "global"
configSourceIndexProjectIndexName = "project"
configSourceIndexApplicationIndexName = "application"
Expand Down
Loading

0 comments on commit 314efef

Please sign in to comment.