Skip to content
This repository has been archived by the owner on Dec 21, 2023. It is now read-only.

refactor(cli): Use Viper to manage Keptn config #5694

Merged

Conversation

vadasambar
Copy link
Member

@vadasambar vadasambar commented Oct 13, 2021

Fixes #5490

This PR uses Viper internally to manage the Keptn Config.

Why

  • Viper allows reading config fields from the environment variables
  • Viper allows aliasing fields
  • Changing file type of the config is relatively easier
  • Viper decouples the CLI from the internal representation of the Config

How to test

  • You can do keptn <any-command> --cli-config ~/.foo/my-keptn-config to use a config stored at path other than ~/.keptn/config

Things to note

  • Please check go.sum. Adding viper 1.9.0 lead to many changes in go.sum (additive. I have not removed any dependency)

@vadasambar vadasambar force-pushed the refactor/5490/use-viper-in-root-cmd branch from 29cd494 to 15966bf Compare October 15, 2021 17:03
@vadasambar vadasambar force-pushed the refactor/5490/use-viper-in-root-cmd branch 3 times, most recently from d891e1a to 4c17d6d Compare November 2, 2021 17:56
@vadasambar vadasambar changed the title refactor(cli): (WIP) migrate CLIConfigManager to viper refactor(cli): (WIP) use viper to manage Keptn config Nov 2, 2021
@codecov
Copy link

codecov bot commented Nov 3, 2021

Codecov Report

Merging #5694 (586d557) into master (d89cab9) will decrease coverage by 1.10%.
The diff coverage is 65.07%.

❗ Current head 586d557 differs from pull request most recent head 5c5a7be. Consider uploading reports for the commit 5c5a7be to get more accurate results

@@            Coverage Diff             @@
##           master    #5694      +/-   ##
==========================================
- Coverage   54.33%   53.23%   -1.11%     
==========================================
  Files         399      326      -73     
  Lines       23436    22351    -1085     
  Branches     1204     1054     -150     
==========================================
- Hits        12735    11899     -836     
+ Misses       9788     9553     -235     
+ Partials      913      899      -14     
Impacted Files Coverage Δ
cli/cmd/set_config.go 36.36% <0.00%> (ø)
cli/pkg/version/keptn_version_checker.go 44.57% <0.00%> (ø)
cli/pkg/config/cli_config.go 57.74% <62.26%> (+6.13%) ⬆️
cli/cmd/root.go 69.30% <100.00%> (+6.20%) ⬆️
cli/cmd/version.go 52.72% <100.00%> (-5.17%) ⬇️
cli/pkg/credentialmanager/handler.go 17.14% <100.00%> (ø)
cli/pkg/version/version_checker.go 57.03% <100.00%> (ø)
...s/ktb-sequence-view/ktb-sequence-view.component.ts 30.32% <0.00%> (-29.02%) ⬇️
bridge/client/app/_utils/form.utils.ts 63.63% <0.00%> (-27.28%) ⬇️
...ient/app/_interceptors/http-loading-interceptor.ts 81.81% <0.00%> (-18.19%) ⬇️
... and 120 more

@vadasambar vadasambar force-pushed the refactor/5490/use-viper-in-root-cmd branch from ac615c9 to 1fe2872 Compare November 3, 2021 16:20
@vadasambar vadasambar changed the title refactor(cli): (WIP) use viper to manage Keptn config refactor(cli): Use viper to manage Keptn config Nov 4, 2021
@@ -62,6 +62,8 @@ func init() {
rootCmd.PersistentFlags().BoolVarP(&mocking, "mock", "", false, "Disables communication to a Keptn endpoint")
rootCmd.PersistentFlags().StringVarP(&namespace, "namespace", "n", "keptn",
"Specify the namespace where Keptn should be installed, used and uninstalled in")
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config-file", "", "",
Copy link
Member Author

@vadasambar vadasambar Nov 4, 2021

Choose a reason for hiding this comment

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

I tried -c (1, 2, 3, 4, 5) and -f shorthands but both are being used in the subcommands. I have left the short hand field empty for now. We can add a shorthand in the future if needed or if there's a good short hand we haven't used and is intuitive, we can go with that.

@@ -32,7 +32,7 @@ Supported keys:
cmd.SilenceUsage = false
return errors.New("required arguments KEY and VALUE")
}
configMng = config.NewCLIConfigManager()
configMng = config.NewCLIConfigManager("")
Copy link
Member Author

@vadasambar vadasambar Nov 4, 2021

Choose a reason for hiding this comment

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

Function signature NewCLIConfigManager is changed to support custom config file path. I have done a global replace NewCLIConfigManager() -> NewCLIConfigManager("")

@@ -20,6 +20,7 @@ require (
github.com/mitchellh/mapstructure v1.4.2
github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/cobra v1.2.1
github.com/spf13/viper v1.9.0
Copy link
Member Author

Choose a reason for hiding this comment

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

Latest version of Viper at the time of this PR
image
https://pkg.go.dev/github.com/spf13/viper?tab=versions

@@ -34,6 +34,7 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/firestore v1.6.0/go.mod h1:afJwI0vaXwAG54kI7A//lP/lSPDkQORQuMkv56TxEPU=
Copy link
Member Author

@vadasambar vadasambar Nov 4, 2021

Choose a reason for hiding this comment

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

All the changes in this file are because of two reasons:

  1. I added viper as a dependency (CI was failing) with
# In the keptn root directory
$ go get cli/pkg/config
  1. I updated the dependency from viper 1.8.1 -> 1.9.0 in the go.mod because 1.9.0 is the latest stable version at the time of this comment. 1.8.1 was added automatically on running the go get command above. After updating the go.mod file I ran the same command again
# In the keptn root directory
$ go get cli/pkg/config
  1. Did git pull upstream master --rebase and resolved merge conflicts. I accepted both the changes (from upstream master and my branch)

}

var mgr *CLIConfigManager
Copy link
Member Author

Choose a reason for hiding this comment

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

Maintain an internal CLIConfigManager struct to avoid re-initializing new viper instances.

if err := json.Unmarshal(data, &cliConfig); err != nil {

if err := c.viper.Unmarshal(&cliConfig, func(dConfig *mapstructure.DecoderConfig) {
dConfig.DecodeHook = mapstructure.StringToTimeHookFunc(time.RFC3339)
Copy link
Member Author

Choose a reason for hiding this comment

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

StringToTimeHookFunc decode hook was added because viper.Unmarshal does not know how to unmarshal json time string into *time.Time (it throws an error if we don't add the decode hook)

}

// GetCLIConfig gets the already loaded configuration
func (c *CLIConfigManager) GetCLIConfig() (CLIConfig, error) {
Copy link
Member Author

@vadasambar vadasambar Nov 4, 2021

Choose a reason for hiding this comment

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

Many places in the code use LoadCLIConfig which reads in the config file every time LoadCLIConfig function is called. GetCLIConfig is lighter version of the function. It only returns the config already loaded in the Viper.

data, err := json.Marshal(config)
if err != nil {
return fmt.Errorf("error when marshalling config file: %w", err)
}
if err := ioutil.WriteFile(c.CLIConfigPath, []byte(data), 0644); err != nil {

if err := c.viper.MergeConfig(bytes.NewReader(data)); err != nil {
Copy link
Member Author

Choose a reason for hiding this comment

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

config passed as parameter overwrites config stored in the Viper

return nil
}

// GetKeptnDefaultConfigPath returns default Keptn Config file path
func GetKeptnDefaultConfigPath() (string, error) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Helper function to get default keptn config file path

@@ -60,6 +64,12 @@ func TestStoreCLIConfig(t *testing.T) {
}

data, err := fileutils.ReadFileAsStr(mng.CLIConfigPath)

// This is to remove the indentation viper adds
data = strings.ReplaceAll(data, " ", "")
Copy link
Member Author

Choose a reason for hiding this comment

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

Viper stores the config like this

{
  "automatic_version_check":true,
  "current-context":"",
  "kube_context_check":true,
  "last_version_check":"2020-02-20T00:00:00Z"
}

But we want to flatten it out (remove indentations) so that we can compare it with the testConfig

@vadasambar vadasambar force-pushed the refactor/5490/use-viper-in-root-cmd branch 3 times, most recently from d6e4051 to 8e9701a Compare November 4, 2021 15:28
KubeContextCheck bool `json:"kube_context_check"`
LastVersionCheck *time.Time `json:"last_version_check"`
CurrentContext string `json:"current-context"`
AutomaticVersionCheck bool `json:"automatic_version_check" mapstructure:"automatic_version_check"`
Copy link
Member Author

Choose a reason for hiding this comment

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

}

// CLIConfigManager manages the path of the CLI config
type CLIConfigManager struct {
CLIConfigPath string
viper *viper.Viper
Copy link
Member Author

Choose a reason for hiding this comment

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

I have kept the field private for now. We can make this public in the future if required.

@vadasambar vadasambar marked this pull request as ready for review November 4, 2021 15:59
@vadasambar vadasambar requested a review from a team as a code owner November 4, 2021 15:59
@vadasambar vadasambar changed the title refactor(cli): Use viper to manage Keptn config refactor(cli): Use Viper to manage Keptn config Nov 4, 2021
dir, err := keptnutils.GetKeptnDirectory()
if err != nil {
log.Fatal(err)
fmt.Printf("no value for --config-file was specified\n defaulting to: %s\n", cfgFile)
Copy link
Member

Choose a reason for hiding this comment

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

please use logging.PrintLog() with VerboseLevel instead of fmt.Printf

Copy link
Member Author

Choose a reason for hiding this comment

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

I will change this. Thanks for the review 🙏

@vadasambar vadasambar force-pushed the refactor/5490/use-viper-in-root-cmd branch 2 times, most recently from 428afea to ef509e0 Compare November 16, 2021 16:04
- custom config file path
- this is an overwrite of yesterday's PR
- use decode hook to unmarshal time
- move viper to CLIConfigMgr
- try out writing config using viper
- add string param to `NewCLIConfigManager`
- use json marshal with viper to write the config
-- add a new func to get already loaded cli config
-- this would prevent reading in the cli config from the file every time
- add viper to go.mod
- clean up
-- remove shorthand for `config-file`
-- shorthand `c` and `f` are already used in subcommands (go test fails)
- rename `KeptnConfigPath` -> `GetKeptnDefaultConfigPath`
- fix spacing
- add viper to go.sum
- move cli config path check to NewCLIConfigManager
- use specified config path in LoadCLIConfig
- print msg about using default config path if none is specified
-- print `data` and `testConfig` to analyse the difference
-- CI is failing because of ^
- remove indentation added by viper in the tests
- add `\n` to log msg
- use the same config mgr everywhere
-- make viper private (can make it public later if needed)
- use viper 1.9.0
-- latest version at the time of this commit
- revert cli/main.go (changes not needed)
- replace fmt.Printf with verbose level logging.PrintLog
- update go.sum

Signed-off-by: Suraj Banakar (vadasambar) <surajrbanakar@gmail.com>
@vadasambar vadasambar force-pushed the refactor/5490/use-viper-in-root-cmd branch from ef509e0 to 5c5a7be Compare November 16, 2021 16:15
@sonarcloud
Copy link

sonarcloud bot commented Nov 16, 2021

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.8% 0.8% Duplication

Copy link
Member

@bacherfl bacherfl left a comment

Choose a reason for hiding this comment

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

lgtm

@bacherfl bacherfl merged commit 498d893 into keptn:master Nov 17, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use Viper to manage CLIConfig
2 participants