From a0f4342f366570056480ed783c990e5e5e2727ef Mon Sep 17 00:00:00 2001 From: GT Date: Tue, 18 Aug 2020 14:58:55 +0530 Subject: [PATCH 1/8] added New BotKube command to list the supported kubectl cmds --- pkg/execute/executor.go | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/pkg/execute/executor.go b/pkg/execute/executor.go index bfb34b4ab..aff9dda73 100644 --- a/pkg/execute/executor.go +++ b/pkg/execute/executor.go @@ -50,6 +50,9 @@ var ( validFilterCommand = map[string]bool{ "filters": true, } + validInfoCommand = map[string]bool{ + "commands": true, + } validDebugCommands = map[string]bool{ "exec": true, "logs": true, @@ -78,6 +81,9 @@ const ( // IncompleteCmdMsg incomplete command response message IncompleteCmdMsg = "You missed to pass options for the command. Please run /botkubehelp to see command options." + //IncompleteInfoCmdMsg incomplete command response message + IncompleteInfoCmdMsg = "You missed to pass correct option i.e. list" + // Custom messages for teams platform teamsUnsupportedCmdMsg = "Command not supported. Please visit botkube.io/usage to see supported commands." teamsIncompleteCmdMsg = "You missed to pass options for the command. Please run /botkubehelp to see command options." @@ -146,6 +152,14 @@ const ( FilterDisable FiltersAction = "disable" ) +// InfoAction for options in Info commands +type InfoAction string + +// Info command options +const ( + InfoList InfoAction = "list" +) + func (action FiltersAction) String() string { return string(action) } @@ -205,6 +219,12 @@ func (e *DefaultExecutor) Execute() string { if validFilterCommand[args[0]] { return e.runFilterCommand(args, e.ClusterName, e.IsAuthChannel) } + + //Check if info command + if validInfoCommand[args[0]] { + return e.runInfoCommand(args, e.IsAuthChannel) + } + if e.IsAuthChannel { return printDefaultMsg(e.Platform) } @@ -355,6 +375,34 @@ func (e *DefaultExecutor) runFilterCommand(args []string, clusterName string, is return printDefaultMsg(e.Platform) } +//runInfoCommand to list allowed commands +func (e *DefaultExecutor) runInfoCommand(args []string, isAuthChannel bool) string { + if isAuthChannel == false { + return "" + } + if len(args) < 2 && args[1] != string(InfoList) { + return IncompleteInfoCmdMsg + } + return makeCommandInfoList() +} + +func makeCommandInfoList() string { + var b strings.Builder + fmt.Fprintln(&b, "allowed verbs:") + for k, v := range utils.AllowedKubectlVerbMap { + if v { + fmt.Fprintf(&b, "- %s\n", k) + } + } + fmt.Fprintln(&b, "allowed resources:") + for k, v := range utils.AllowedKubectlResourceMap { + if v { + fmt.Fprintf(&b, "- %s\n", k) + } + } + return b.String() +} + // Use tabwriter to display string in tabular form // https://golang.org/pkg/text/tabwriter func makeFiltersList() string { From beeccaafd31d3db70e5d70a0f6be73e8ac654435 Mon Sep 17 00:00:00 2001 From: GT Date: Tue, 18 Aug 2020 16:15:25 +0530 Subject: [PATCH 2/8] created method to get the formated command string --- pkg/execute/executor.go | 22 ++++------------------ pkg/utils/utils.go | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/pkg/execute/executor.go b/pkg/execute/executor.go index aff9dda73..14c5d3d8d 100644 --- a/pkg/execute/executor.go +++ b/pkg/execute/executor.go @@ -81,9 +81,6 @@ const ( // IncompleteCmdMsg incomplete command response message IncompleteCmdMsg = "You missed to pass options for the command. Please run /botkubehelp to see command options." - //IncompleteInfoCmdMsg incomplete command response message - IncompleteInfoCmdMsg = "You missed to pass correct option i.e. list" - // Custom messages for teams platform teamsUnsupportedCmdMsg = "Command not supported. Please visit botkube.io/usage to see supported commands." teamsIncompleteCmdMsg = "You missed to pass options for the command. Please run /botkubehelp to see command options." @@ -381,26 +378,15 @@ func (e *DefaultExecutor) runInfoCommand(args []string, isAuthChannel bool) stri return "" } if len(args) < 2 && args[1] != string(InfoList) { - return IncompleteInfoCmdMsg + return IncompleteCmdMsg } return makeCommandInfoList() } func makeCommandInfoList() string { - var b strings.Builder - fmt.Fprintln(&b, "allowed verbs:") - for k, v := range utils.AllowedKubectlVerbMap { - if v { - fmt.Fprintf(&b, "- %s\n", k) - } - } - fmt.Fprintln(&b, "allowed resources:") - for k, v := range utils.AllowedKubectlResourceMap { - if v { - fmt.Fprintf(&b, "- %s\n", k) - } - } - return b.String() + allowedVerbs := utils.GetFormatedCommandsList("allowed verbs:", utils.AllowedKubectlVerbMap) + allowedResources := utils.GetFormatedCommandsList("allowed resources:", utils.AllowedKubectlResourceMap) + return allowedVerbs + allowedResources } // Use tabwriter to display string in tabular form diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index c1783cbd8..544fbafd5 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -20,6 +20,8 @@ package utils import ( + "bytes" + "fmt" "os" "regexp" "strconv" @@ -477,3 +479,15 @@ func GetClusterNameFromKubectlCmd(cmd string) string { } return s } + +//Get the formated commands list +func GetFormatedCommandsList(header string, commands map[string]bool) string { + var b bytes.Buffer + fmt.Fprintln(&b, header) + for k, v := range commands { + if v { + fmt.Fprintf(&b, " - %s\n", k) + } + } + return b.String() +} From a233569b1362963e6eaa375144067763da2b81fd Mon Sep 17 00:00:00 2001 From: GT Date: Tue, 18 Aug 2020 18:07:37 +0530 Subject: [PATCH 3/8] added test cases --- pkg/utils/utils.go | 2 +- pkg/utils/utils_test.go | 13 +++++++++++++ test/e2e/command/botkube.go | 26 +++++++++++++++++++++++++- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 544fbafd5..26aff6448 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -480,7 +480,7 @@ func GetClusterNameFromKubectlCmd(cmd string) string { return s } -//Get the formated commands list +//GetFormatedCommandsList get the formated commands list func GetFormatedCommandsList(header string, commands map[string]bool) string { var b bytes.Buffer fmt.Fprintln(&b, header) diff --git a/pkg/utils/utils_test.go b/pkg/utils/utils_test.go index 286ae371e..b6ed33a1a 100644 --- a/pkg/utils/utils_test.go +++ b/pkg/utils/utils_test.go @@ -20,6 +20,7 @@ package utils import ( + "fmt" "testing" ) @@ -49,3 +50,15 @@ func TestGetClusterNameFromKubectlCmd(t *testing.T) { } } } + +func TestGetFormatedCommandsList(t *testing.T) { + var header = "allowed verbs" + var commands = map[string]bool{ + "api-versions": true, + } + expected := fmt.Sprintf(header + "\n - api-versions\n") + got := GetFormatedCommandsList(header, commands) + if got != expected { + t.Errorf("expected: %v, got: %v", expected, got) + } +} diff --git a/test/e2e/command/botkube.go b/test/e2e/command/botkube.go index 6028cef90..621695090 100644 --- a/test/e2e/command/botkube.go +++ b/test/e2e/command/botkube.go @@ -59,8 +59,29 @@ func (c *context) testBotkubeCommand(t *testing.T) { "ImageTagChecker true Checks and adds recommendation if 'latest' image tag is used for container image.\n" + "IngressValidator true Checks if services and tls secrets used in ingress specs are available.\n", }, + "BotKube commands list": { + command: "commands list", + expected: "allowed verbs:\n" + + " - api-resources\n" + + " - describe\n" + + " - diff\n" + + " - explain\n" + + " - get\n" + + " - logs\n" + + " - api-versions\n" + + " - cluster-info\n" + + " - top\n" + + " - auth\n" + + "allowed resources:\n" + + " - nodes\n" + + " - deployments\n" + + " - pods\n" + + " - namespaces\n" + + " - daemonsets\n" + + " - statefulsets\n" + + " - storageclasses\n", + }, } - for name, test := range tests { t.Run(name, func(t *testing.T) { if c.TestEnv.Config.Communications.Slack.Enabled { @@ -80,6 +101,9 @@ func (c *context) testBotkubeCommand(t *testing.T) { case "filters list": fl := compareFilters(strings.Split(test.expected, "\n"), strings.Split(strings.Trim(m.Text, "```"), "\n")) assert.Equal(t, fl, true) + case "commands list": + cl := compareFilters(strings.Split(test.expected, "\n"), strings.Split(strings.Trim(m.Text, "```"), "\n")) + assert.Equal(t, cl, true) default: assert.Equal(t, test.expected, m.Text) } From 122dd350b1592cd4a97222e43260559e6afd27ff Mon Sep 17 00:00:00 2001 From: GT Date: Thu, 20 Aug 2020 11:46:42 +0530 Subject: [PATCH 4/8] added logs to debug testcases --- test/e2e/command/botkube.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/e2e/command/botkube.go b/test/e2e/command/botkube.go index 621695090..fcff62553 100644 --- a/test/e2e/command/botkube.go +++ b/test/e2e/command/botkube.go @@ -28,6 +28,7 @@ import ( "github.com/infracloudio/botkube/pkg/config" "github.com/infracloudio/botkube/pkg/execute" + "github.com/infracloudio/botkube/pkg/log" "github.com/infracloudio/botkube/test/e2e/utils" "github.com/nlopes/slack" "github.com/stretchr/testify/assert" @@ -114,6 +115,7 @@ func (c *context) testBotkubeCommand(t *testing.T) { func compareFilters(expected, actual []string) bool { if len(expected) != len(actual) { + log.Infof("************************Expected %d Actual %d", len(expected), len(actual)) return false } @@ -127,6 +129,7 @@ func compareFilters(expected, actual []string) bool { } } if !found { + log.Infof("************************Not Found %s", a) return false } } From 2243b17e3b05b02b91796cb6da30274589c5bd6a Mon Sep 17 00:00:00 2001 From: GT Date: Thu, 20 Aug 2020 11:54:51 +0530 Subject: [PATCH 5/8] service account was missing in config file --- test/resource_config.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/resource_config.yaml b/test/resource_config.yaml index 2aba10947..a3cfcf41d 100644 --- a/test/resource_config.yaml +++ b/test/resource_config.yaml @@ -212,7 +212,8 @@ settings: # method which are allowed verbs: ["api-resources", "api-versions", "cluster-info", "describe", "diff", "explain", "get", "logs", "top", "auth"] # resource configuration which is allowed - resources: ["deployments", "pods" , "namespaces", "daemonsets", "statefulsets", "storageclasses", "serviceaccounts"] + resources: ["deployments", "pods" , "namespaces", "daemonsets", "statefulsets", "storageclasses", "nodes"] + # set Namespace to execute botkube kubectl commands by default defaultNamespace: default # Set true to enable commands execution from configured channel only From e4617fa08593ceee527b48967be6efb359bb8c99 Mon Sep 17 00:00:00 2001 From: GT Date: Mon, 24 Aug 2020 10:26:11 +0530 Subject: [PATCH 6/8] corrected code as per review comment --- pkg/execute/executor.go | 10 +++++----- pkg/utils/utils.go | 4 ++-- pkg/utils/utils_test.go | 4 ++-- test/e2e/command/botkube.go | 3 --- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/pkg/execute/executor.go b/pkg/execute/executor.go index 2538d9c56..dcc151dc7 100644 --- a/pkg/execute/executor.go +++ b/pkg/execute/executor.go @@ -149,12 +149,12 @@ const ( FilterDisable FiltersAction = "disable" ) -// InfoAction for options in Info commands -type InfoAction string +// infoAction for options in Info commands +type infoAction string // Info command options const ( - InfoList InfoAction = "list" + InfoList infoAction = "list" ) func (action FiltersAction) String() string { @@ -389,8 +389,8 @@ func (e *DefaultExecutor) runInfoCommand(args []string, isAuthChannel bool) stri } func makeCommandInfoList() string { - allowedVerbs := utils.GetFormatedCommandsList("allowed verbs:", utils.AllowedKubectlVerbMap) - allowedResources := utils.GetFormatedCommandsList("allowed resources:", utils.AllowedKubectlResourceMap) + allowedVerbs := utils.GetStingInYamlFormat("allowed verbs:", utils.AllowedKubectlVerbMap) + allowedResources := utils.GetStingInYamlFormat("allowed resources:", utils.AllowedKubectlResourceMap) return allowedVerbs + allowedResources } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 26aff6448..a50c9b95d 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -480,8 +480,8 @@ func GetClusterNameFromKubectlCmd(cmd string) string { return s } -//GetFormatedCommandsList get the formated commands list -func GetFormatedCommandsList(header string, commands map[string]bool) string { +//GetStingInYamlFormat get the formated commands list +func GetStingInYamlFormat(header string, commands map[string]bool) string { var b bytes.Buffer fmt.Fprintln(&b, header) for k, v := range commands { diff --git a/pkg/utils/utils_test.go b/pkg/utils/utils_test.go index b6ed33a1a..5edae3f71 100644 --- a/pkg/utils/utils_test.go +++ b/pkg/utils/utils_test.go @@ -51,13 +51,13 @@ func TestGetClusterNameFromKubectlCmd(t *testing.T) { } } -func TestGetFormatedCommandsList(t *testing.T) { +func TestGetStingInYamlFormat(t *testing.T) { var header = "allowed verbs" var commands = map[string]bool{ "api-versions": true, } expected := fmt.Sprintf(header + "\n - api-versions\n") - got := GetFormatedCommandsList(header, commands) + got := GetStingInYamlFormat(header, commands) if got != expected { t.Errorf("expected: %v, got: %v", expected, got) } diff --git a/test/e2e/command/botkube.go b/test/e2e/command/botkube.go index fcff62553..621695090 100644 --- a/test/e2e/command/botkube.go +++ b/test/e2e/command/botkube.go @@ -28,7 +28,6 @@ import ( "github.com/infracloudio/botkube/pkg/config" "github.com/infracloudio/botkube/pkg/execute" - "github.com/infracloudio/botkube/pkg/log" "github.com/infracloudio/botkube/test/e2e/utils" "github.com/nlopes/slack" "github.com/stretchr/testify/assert" @@ -115,7 +114,6 @@ func (c *context) testBotkubeCommand(t *testing.T) { func compareFilters(expected, actual []string) bool { if len(expected) != len(actual) { - log.Infof("************************Expected %d Actual %d", len(expected), len(actual)) return false } @@ -129,7 +127,6 @@ func compareFilters(expected, actual []string) bool { } } if !found { - log.Infof("************************Not Found %s", a) return false } } From 13f9fce921a68da322a2b16166049cbdaff79d2f Mon Sep 17 00:00:00 2001 From: GT Date: Wed, 2 Sep 2020 09:56:17 +0530 Subject: [PATCH 7/8] removed exposing of variables --- pkg/execute/executor.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/execute/executor.go b/pkg/execute/executor.go index dcc151dc7..8cbb48b29 100644 --- a/pkg/execute/executor.go +++ b/pkg/execute/executor.go @@ -154,7 +154,7 @@ type infoAction string // Info command options const ( - InfoList infoAction = "list" + infoList infoAction = "list" ) func (action FiltersAction) String() string { @@ -382,7 +382,7 @@ func (e *DefaultExecutor) runInfoCommand(args []string, isAuthChannel bool) stri if isAuthChannel == false { return "" } - if len(args) < 2 && args[1] != string(InfoList) { + if len(args) < 2 && args[1] != string(infoList) { return IncompleteCmdMsg } return makeCommandInfoList() From 7b45aae0734a5037d84853d7b981e12f3fbb4815 Mon Sep 17 00:00:00 2001 From: GT Date: Wed, 2 Sep 2020 10:10:54 +0530 Subject: [PATCH 8/8] corrected typo --- pkg/execute/executor.go | 4 ++-- pkg/utils/utils.go | 4 ++-- pkg/utils/utils_test.go | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/execute/executor.go b/pkg/execute/executor.go index 8cbb48b29..07b7a4515 100644 --- a/pkg/execute/executor.go +++ b/pkg/execute/executor.go @@ -389,8 +389,8 @@ func (e *DefaultExecutor) runInfoCommand(args []string, isAuthChannel bool) stri } func makeCommandInfoList() string { - allowedVerbs := utils.GetStingInYamlFormat("allowed verbs:", utils.AllowedKubectlVerbMap) - allowedResources := utils.GetStingInYamlFormat("allowed resources:", utils.AllowedKubectlResourceMap) + allowedVerbs := utils.GetStringInYamlFormat("allowed verbs:", utils.AllowedKubectlVerbMap) + allowedResources := utils.GetStringInYamlFormat("allowed resources:", utils.AllowedKubectlResourceMap) return allowedVerbs + allowedResources } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index a50c9b95d..a0b3f2ced 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -480,8 +480,8 @@ func GetClusterNameFromKubectlCmd(cmd string) string { return s } -//GetStingInYamlFormat get the formated commands list -func GetStingInYamlFormat(header string, commands map[string]bool) string { +//GetStringInYamlFormat get the formated commands list +func GetStringInYamlFormat(header string, commands map[string]bool) string { var b bytes.Buffer fmt.Fprintln(&b, header) for k, v := range commands { diff --git a/pkg/utils/utils_test.go b/pkg/utils/utils_test.go index 5edae3f71..203f1ff07 100644 --- a/pkg/utils/utils_test.go +++ b/pkg/utils/utils_test.go @@ -51,13 +51,13 @@ func TestGetClusterNameFromKubectlCmd(t *testing.T) { } } -func TestGetStingInYamlFormat(t *testing.T) { +func TestGetStringInYamlFormat(t *testing.T) { var header = "allowed verbs" var commands = map[string]bool{ "api-versions": true, } expected := fmt.Sprintf(header + "\n - api-versions\n") - got := GetStingInYamlFormat(header, commands) + got := GetStringInYamlFormat(header, commands) if got != expected { t.Errorf("expected: %v, got: %v", expected, got) }