Commit 3d30620a authored by Dima Brusilovsky's avatar Dima Brusilovsky
Browse files

feat: support set token

parent 868bab38
Showing with 269 additions and 23 deletions
+269 -23
......@@ -12,3 +12,6 @@ create-bin:
print-version:
go run -tags=staging -ldflags="-X github.com/datreeio/datree/cmd.CliVersion=0.0.1" main.go version
set-token:
go run -tags=staging -ldflags="-X github.com/datreeio/datree/cmd.CliVersion=0.0.1" main.go config set token testtoken
package config
import (
"github.com/datreeio/datree/bl/messager"
"github.com/datreeio/datree/pkg/localConfig"
"github.com/spf13/cobra"
)
type Messager interface {
LoadVersionMessages(messages chan *messager.VersionMessage, cliVersion string)
}
type Printer interface {
PrintMessage(messageText string, messageColor string)
}
type LocalConfig interface {
GetLocalConfiguration() (*localConfig.ConfigContent, error)
Set(key string, value string) error
}
type ConfigCommandContext struct {
Messager Messager
CliVersion string
Printer Printer
LocalConfig LocalConfig
}
func New(ctx *ConfigCommandContext) *cobra.Command {
configCommand := &cobra.Command{
Use: "config",
Short: "Configuration management",
Long: `Internal configuration management for datree config file`,
}
configCommand.AddCommand(NewSetCommand(ctx))
return configCommand
}
package config
import (
"fmt"
"github.com/datreeio/datree/bl/messager"
"github.com/spf13/cobra"
)
func NewSetCommand(ctx *ConfigCommandContext) *cobra.Command {
setCommand := &cobra.Command{
Use: "set",
Short: "Set configuration value",
Long: `Apply value for specific key in datree config.yaml file. Defaults to $HOME/.datree/config.yaml`,
Run: func(cmd *cobra.Command, args []string) {
messages := make(chan *messager.VersionMessage, 1)
go ctx.Messager.LoadVersionMessages(messages, ctx.CliVersion)
err := set(ctx, args[0], args[1])
if err != nil {
fmt.Printf("Failed setting %s with value %s. Error: %s", args[0], args[1], err)
}
msg, ok := <-messages
if ok {
ctx.Printer.PrintMessage(msg.MessageText+"\n", msg.MessageColor)
}
},
Args: cobra.ExactArgs(2),
}
return setCommand
}
func set(ctx *ConfigCommandContext, key string, value string) error {
_, err := ctx.LocalConfig.GetLocalConfiguration()
if err != nil {
return err
}
err = ctx.LocalConfig.Set(key, value)
return err
}
package config
import (
"testing"
"github.com/datreeio/datree/bl/messager"
"github.com/datreeio/datree/pkg/localConfig"
"github.com/datreeio/datree/pkg/printer"
"github.com/stretchr/testify/mock"
)
type mockMessager struct {
mock.Mock
}
func (m *mockMessager) LoadVersionMessages(messages chan *messager.VersionMessage, cliVersion string) {
go func() {
messages <- &messager.VersionMessage{
CliVersion: "1.2.3",
MessageText: "version message mock",
MessageColor: "green"}
close(messages)
}()
m.Called(messages, cliVersion)
}
func (m *mockMessager) HandleVersionMessage(messageChannel <-chan *messager.VersionMessage) {
m.Called(messageChannel)
}
type PrinterMock struct {
mock.Mock
}
func (p *PrinterMock) PrintWarnings(warnings []printer.Warning) {
p.Called(warnings)
}
func (p *PrinterMock) PrintSummaryTable(summary printer.Summary) {
p.Called(summary)
}
func (p *PrinterMock) PrintMessage(messageText string, messageColor string) {
p.Called(messageText, messageColor)
}
func (p *PrinterMock) PrintEvaluationSummary(evaluationSummary printer.EvaluationSummary, k8sVersion string) {
p.Called(evaluationSummary)
}
type LocalConfigMock struct {
mock.Mock
}
func (lc *LocalConfigMock) GetLocalConfiguration() (*localConfig.ConfigContent, error) {
lc.Called()
return &localConfig.ConfigContent{CliId: "previousToken"}, nil
}
func (lc *LocalConfigMock) Set(key string, value string) error {
lc.Called(key, value)
return nil
}
func TestSetCommand(t *testing.T) {
messager := &mockMessager{}
messager.On("LoadVersionMessages", mock.Anything, mock.Anything)
printerMock := &PrinterMock{}
printerMock.On("PrintWarnings", mock.Anything)
printerMock.On("PrintSummaryTable", mock.Anything)
printerMock.On("PrintMessage", mock.Anything, mock.Anything)
printerMock.On("PrintEvaluationSummary", mock.Anything, mock.Anything)
localConfigMock := &LocalConfigMock{}
localConfigMock.On("GetLocalConfiguration").Return(&localConfig.ConfigContent{CliId: "previousToken"}, nil)
localConfigMock.On("Set", mock.Anything, mock.Anything)
ctx := &ConfigCommandContext{
Messager: messager,
CliVersion: "1.2.3",
Printer: printerMock,
LocalConfig: localConfigMock,
}
set(ctx, "testkey", "testvalue")
localConfigMock.AssertCalled(t, "Set", "testkey", "testvalue")
}
......@@ -4,6 +4,7 @@ import (
"github.com/datreeio/datree/bl/evaluation"
"github.com/datreeio/datree/bl/messager"
"github.com/datreeio/datree/bl/validation"
"github.com/datreeio/datree/cmd/config"
"github.com/datreeio/datree/cmd/test"
"github.com/datreeio/datree/cmd/version"
"github.com/datreeio/datree/pkg/cliClient"
......@@ -40,6 +41,13 @@ func init() {
Messager: app.context.Messager,
Printer: app.context.Printer,
}))
rootCmd.AddCommand(config.New(&config.ConfigCommandContext{
CliVersion: CliVersion,
Messager: app.context.Messager,
Printer: app.context.Printer,
LocalConfig: app.context.LocalConfig,
}))
}
func Execute() error {
......@@ -47,7 +55,7 @@ func Execute() error {
}
type context struct {
LocalConfig *localConfig.LocalConfiguration
LocalConfig *localConfig.LocalConfig
Evaluator *evaluation.Evaluator
CliClient *cliClient.CliClient
Messager *messager.Messager
......@@ -61,13 +69,13 @@ type app struct {
}
func startup() *app {
config, _ := localConfig.GetLocalConfiguration()
localConfig := localConfig.NewLocalConfig()
cliClient := cliClient.NewCliClient(deploymentConfig.URL)
printer := printer.CreateNewPrinter()
return &app{
context: &context{
LocalConfig: config,
LocalConfig: localConfig,
Evaluator: evaluation.New(cliClient),
CliClient: cliClient,
Messager: messager.New(cliClient),
......
......@@ -48,9 +48,13 @@ type Reader interface {
FilterFiles(paths []string) ([]string, error)
}
type LocalConfig interface {
GetLocalConfiguration() (*localConfig.ConfigContent, error)
}
type TestCommandContext struct {
CliVersion string
LocalConfig *localConfig.LocalConfiguration
LocalConfig LocalConfig
Evaluator Evaluator
Messager Messager
K8sValidator K8sValidator
......@@ -89,6 +93,11 @@ func New(ctx *TestCommandContext) *cobra.Command {
}
func test(ctx *TestCommandContext, paths []string, flags TestCommandFlags) error {
localConfigContent, err := ctx.LocalConfig.GetLocalConfiguration()
if err != nil {
return err
}
isInteractiveMode := (flags.Output != "json") && (flags.Output != "yaml")
if isInteractiveMode == true {
......@@ -124,7 +133,7 @@ func test(ctx *TestCommandContext, paths []string, flags TestCommandFlags) error
validYamlFilesConfigurationsChan, invalidYamlFilesChan := files.ExtractFilesConfigurations(filesPaths, concurrency)
createEvaluationResponse, err := ctx.Evaluator.CreateEvaluation(ctx.LocalConfig.CliId, ctx.CliVersion, flags.K8sVersion)
createEvaluationResponse, err := ctx.Evaluator.CreateEvaluation(localConfigContent.CliId, ctx.CliVersion, flags.K8sVersion)
if err != nil {
fmt.Println(err.Error())
return err
......@@ -187,7 +196,7 @@ func test(ctx *TestCommandContext, paths []string, flags TestCommandFlags) error
PassedPolicyCheckCount: passedPolicyCheckCount,
}
err = evaluation.PrintResults(results, invalidYamlFiles, invalidK8sFiles, evaluationSummary, fmt.Sprintf("https://app.datree.io/login?cliId=%s", ctx.LocalConfig.CliId), flags.Output, ctx.Printer, createEvaluationResponse.K8sVersion)
err = evaluation.PrintResults(results, invalidYamlFiles, invalidK8sFiles, evaluationSummary, fmt.Sprintf("https://app.datree.io/login?cliId=%s", localConfigContent.CliId), flags.Output, ctx.Printer, createEvaluationResponse.K8sVersion)
var invocationFailedErr error = nil
......
......@@ -99,6 +99,15 @@ func (rm *ReaderMock) FilterFiles(paths []string) ([]string, error) {
return args.Get(0).([]string), nil
}
type LocalConfigMock struct {
mock.Mock
}
func (lc *LocalConfigMock) GetLocalConfiguration() (*localConfig.ConfigContent, error) {
lc.Called()
return &localConfig.ConfigContent{CliId: "134kh"}, nil
}
func TestTestCommand(t *testing.T) {
evaluationId := 444
......@@ -136,13 +145,15 @@ func TestTestCommand(t *testing.T) {
printerMock.On("PrintEvaluationSummary", mock.Anything, mock.Anything)
readerMock := &ReaderMock{}
readerMock.On("FilterFiles", mock.Anything).Return([]string{"file/path"}, nil)
localConfigMock := &LocalConfigMock{}
localConfigMock.On("GetLocalConfiguration").Return(&localConfig.ConfigContent{CliId: "134kh"}, nil)
ctx := &TestCommandContext{
K8sValidator: k8sValidatorMock,
Evaluator: mockedEvaluator,
LocalConfig: &localConfig.LocalConfiguration{CliId: "134kh"},
LocalConfig: localConfigMock,
Messager: messager,
Printer: printerMock,
Reader: readerMock,
......
......@@ -9,31 +9,28 @@ import (
"github.com/spf13/viper"
)
type LocalConfiguration struct {
type ConfigContent struct {
CliId string
}
func GetLocalConfiguration() (*LocalConfiguration, error) {
type LocalConfig struct {
}
func NewLocalConfig() *LocalConfig {
return &LocalConfig{}
}
func (lc *LocalConfig) GetLocalConfiguration() (*ConfigContent, error) {
viper.SetEnvPrefix("datree")
viper.AutomaticEnv()
token := viper.GetString("token")
if token == "" {
usr, err := user.Current()
configHome, configName, configType, err := setViperConfig()
if err != nil {
return &LocalConfiguration{}, err
return nil, err
}
homedir := usr.HomeDir
configHome := filepath.Join(homedir, ".datree")
configName := "config"
configType := "yaml"
viper.SetConfigName(configName)
viper.SetConfigType(configType)
viper.AddConfigPath(configHome)
// workaround for creating config file when not exist
// open issue in viper: https://github.com/spf13/viper/issues/430
// should be fixed in pr https://github.com/spf13/viper/pull/936
......@@ -58,5 +55,52 @@ func GetLocalConfiguration() (*LocalConfiguration, error) {
}
}
return &LocalConfiguration{CliId: token}, nil
return &ConfigContent{CliId: token}, nil
}
func (lc *LocalConfig) Set(key string, value string) error {
_, _, _, err := setViperConfig()
if err != nil {
return err
}
viper.Set(key, value)
viper.WriteConfig()
return nil
}
func getConfigHome() (string, error) {
usr, err := user.Current()
if err != nil {
return "", err
}
homedir := usr.HomeDir
configHome := filepath.Join(homedir, ".datree")
return configHome, nil
}
func getConfigName() string {
return "config"
}
func getConfigType() string {
return "yaml"
}
func setViperConfig() (string, string, string, error) {
configHome, err := getConfigHome()
if err != nil {
return "", "", "", nil
}
configName := getConfigName()
configType := getConfigType()
viper.SetConfigName(configName)
viper.SetConfigType(configType)
viper.AddConfigPath(configHome)
return configHome, configName, configType, nil
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment