Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add config "get" and "path" subcommands #329

Merged
merged 1 commit into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions cmd/grr/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,24 @@ import (
"github.com/go-clix/cli"
"github.com/grafana/grizzly/pkg/config"
"github.com/grafana/grizzly/pkg/grizzly"
"github.com/spf13/viper"
)

func configPathCmd() *cli.Command {
cmd := &cli.Command{
Use: "path",
Short: "Print the path to the configuration file",
Args: cli.ArgsExact(0),
}
var opts grizzly.LoggingOpts

cmd.Run = func(cmd *cli.Command, args []string) error {
fmt.Println(viper.ConfigFileUsed())
return nil
}
return initialiseLogging(cmd, &opts)
}

func configImportCmd() *cli.Command {
cmd := &cli.Command{
Use: "import configuration",
Expand Down Expand Up @@ -69,6 +85,31 @@ func getContextsCmd() *cli.Command {
return initialiseLogging(cmd, &opts)
}

func getConfigCmd() *cli.Command {
cmd := &cli.Command{
Use: "get [path]",
Short: "get the whole configuration for a context or a specific attribute of the configuration",
Args: cli.ArgsRange(0, 1),
}
var opts grizzly.LoggingOpts
var output string
cmd.Flags().StringVarP(&output, "output", "o", "yaml", "Output format")

cmd.Run = func(cmd *cli.Command, args []string) error {
path := ""
if len(args) > 0 {
path = args[0]
}
val, err := config.Get(path, output)
if err != nil {
return err
}
fmt.Println(val)
return nil
}
return initialiseLogging(cmd, &opts)
}

func setCmd() *cli.Command {
cmd := &cli.Command{
Use: "set configuration value",
Expand Down
2 changes: 2 additions & 0 deletions cmd/grr/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,10 +272,12 @@ func configCmd() *cli.Command {
Short: "Show, select or configure configuration",
Args: cli.ArgsExact(0),
}
cmd.AddCommand(configPathCmd())
cmd.AddCommand(currentContextCmd())
cmd.AddCommand(useContextCmd())
cmd.AddCommand(getContextsCmd())
cmd.AddCommand(configImportCmd())
cmd.AddCommand(getConfigCmd())
cmd.AddCommand(setCmd())
cmd.AddCommand(createContextCmd())
return cmd
Expand Down
45 changes: 43 additions & 2 deletions integration/context_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package integration_test

import (
"path/filepath"
"testing"

"github.com/stretchr/testify/require"
)

func TestContexts(t *testing.T) {
setupContexts(t, "testdata/contexts")
dir := "testdata/contexts"
setupContexts(t, dir)

t.Run("Get contexts - success", func(t *testing.T) {
runTest(t, GrizzlyTest{
TestDir: "testdata/contexts",
TestDir: dir,
Commands: []Command{
{
Command: "config get-contexts",
Expand All @@ -19,4 +23,41 @@ func TestContexts(t *testing.T) {
},
})
})

absConfigPath, err := filepath.Abs("testdata/contexts/settings.yaml")
require.NoError(t, err)
t.Run("Find config path", func(t *testing.T) {
runTest(t, GrizzlyTest{
TestDir: dir,
Commands: []Command{
{
Command: "config path",
ExpectedOutput: absConfigPath,
},
},
})
})

t.Run("Get context config", func(t *testing.T) {
runTest(t, GrizzlyTest{
TestDir: dir,
Commands: []Command{
// Whole config
{
Command: "config get",
ExpectedOutputFile: "get-context-val.yml",
},
// Whole config JSON
{
Command: "config get -o json",
ExpectedOutputFile: "get-context-val.json",
},
// Specific key
{
Command: "config get grafana.url",
ExpectedOutput: "http://localhost:3001",
},
},
})
})
}
6 changes: 6 additions & 0 deletions integration/testdata/contexts/get-context-val.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"grafana": {
"url": "http://localhost:3001"
},
"name": "default"
}
3 changes: 3 additions & 0 deletions integration/testdata/contexts/get-context-val.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
grafana:
url: http://localhost:3001
name: default
2 changes: 1 addition & 1 deletion integration/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func runTest(t *testing.T, test GrizzlyTest) {
command.ExpectedOutput = string(bytes)
}
if command.ExpectedOutput != "" {
require.Equal(t, command.ExpectedOutput, stdout)
require.Equal(t, strings.TrimSpace(command.ExpectedOutput), strings.TrimSpace(stdout))
}
if command.ExpectedOutputContains != "" {
require.Contains(t, stdout, command.ExpectedOutputContains)
Expand Down
40 changes: 24 additions & 16 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package config

import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"sort"
"strings"

"github.com/kirsle/configdir"
"github.com/spf13/viper"
"gopkg.in/yaml.v3"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use github.com/goccy/go-yaml not this one in Grizzly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, it's not in the go.mod file

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh right, that's in an unmerged branch. Ignore this comment then.

)

const (
Expand Down Expand Up @@ -83,17 +84,6 @@ func Import() error {
return err
}

func configPath() (string, error) {
configPath := configdir.LocalConfig("grizzly")
err := configdir.MakePath(configPath)
if err != nil {
return "", err
}

configFile := filepath.Join(configPath, "settings.yaml")
return configFile, nil
}

func NewConfig() {
viper.Set("apiVersion", "v1alpha1")
viper.Set(CURRENT_CONTEXT, "default")
Expand Down Expand Up @@ -165,6 +155,27 @@ var acceptableKeys = map[string]string{
"only-spec": "bool",
}

func Get(path, outputFormat string) (string, error) {
ctx := viper.GetString(CURRENT_CONTEXT)
fullPath := fmt.Sprintf("contexts.%s", ctx)
if path != "" {
fullPath = fmt.Sprintf("%s.%s", fullPath, path)
}
val := viper.Get(fullPath)
if val == nil {
return "", fmt.Errorf("key not found: %s", path)
}
switch outputFormat {
case "yaml":
res, err := yaml.Marshal(val)
return string(res), err
case "json":
res, err := json.MarshalIndent(val, "", " ")
return string(res), err
}
return "", fmt.Errorf("unknown output format: %s", outputFormat)
}

func Set(path string, value string) error {
for key, typ := range acceptableKeys {
if path == key {
Expand Down Expand Up @@ -198,10 +209,7 @@ func Write() error {
err := viper.WriteConfig()
if err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
configpath, err := configPath()
if err != nil {
return err
}
configpath := viper.ConfigFileUsed()
return viper.WriteConfigAs(configpath)
}
}
Expand Down
Loading