diff options
author | Eddie Arrage <eddie.arrage@huawei.com> | 2018-08-02 23:15:39 +0000 |
---|---|---|
committer | Eddie Arrage <eddie.arrage@huawei.com> | 2018-08-02 23:56:23 +0000 |
commit | c0837d0701009e6142f9800f2b146bec17d6910f (patch) | |
tree | 8b07c911619c889e0f16d24fca6cbc115f760bab | |
parent | 25285393777b4e0ce7989cb6c9cce6b040523feb (diff) |
Implement initial cloverctl CLI tool
- Uses client-go package to interface to k8s API and implement
functions as cloverkube package.
- Identifies GKE LB IP for clover-controller for user
- Identifies NodePort port number for clover-controller for user
if environment is local k8s (assumes flannel CNI currently)
- Deploys and deletes clover-collector and clover-controller with
native client-go constructs (currently images are defined with
local registry). Future work will implement other clover services
and Istio components. Uses the clover-system namespace.
- Uses Cobra go package to implement CLI (used in kubectl and
istioctl) using cloverctl <verb> <noun> convention.
- Interfaces to clover-controller to configure clover services
(visibility, IDS ...) within the cluster via REST messaging
- Start visibility (collector) engine using input yaml file or
defaults
- Init, stop and clear (truncate Cassandra tables) visibility
engine or get basic stats.
- Add custom rules to IDS from input yaml file and start/stop
IDS
- Generate jmeter testplan on jmeter-master using input yaml
file. Start tests and output log/results from CLI.
- Specify number of jmeter slaves to initiate tests on from
CLI. Automatically find IP addresses of jmeter slaves within
the k8s cluster.
- Sample yaml files for adding IDS rules, starting visibility
engine and generating jmeter test plans.
- Build script to install go and get dependent packages.
- Implement a custom Istio inject package for manual sidecar
injection (cloverinject). Currently, unused as it is built from
Istio 0.8.0/1.0.0 code base.
Change-Id: Ibb8d08cb98267bdffb8905c221473f177d51bbb3
Signed-off-by: Eddie Arrage <eddie.arrage@huawei.com>
30 files changed, 1533 insertions, 0 deletions
diff --git a/clover/cloverctl/build.sh b/clover/cloverctl/build.sh new file mode 100755 index 0000000..2f7be14 --- /dev/null +++ b/clover/cloverctl/build.sh @@ -0,0 +1,36 @@ +# Copyright (c) Authors of Clover +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 + +GOVERSION=1.10.3 +OS=linux +ARCH=amd64 +GOPATH=/home/ubuntu/go +CLIENTGOVERSION=v8.0.0 + +# Install go on Ubuntu 16.04 + +wget https://dl.google.com/go/go$GOVERSION.$OS-$ARCH.tar.gz +sudo tar -C /usr/local -xzf go$GOVERSION.$OS-$ARCH.tar.gz +export PATH=$PATH:/usr/local/go/bin +export PATH=$GOPATH/bin:$PATH + +# Get dependencies + +go get github.com/ghodss/yaml +go get github.com/tools/godep +go get -u github.com/spf13/cobra/cobra +go get -u gopkg.in/resty.v1 + +go get k8s.io/client-go/... +cd $GOPATH/src/k8s.io/client-go +git checkout $CLIENTGOVERSION +godep restore ./... +rm -rf vendor/ + +# Build cloverctl + +go install cloverctl diff --git a/clover/cloverctl/src/cloverctl/cmd/clear.go b/clover/cloverctl/src/cloverctl/cmd/clear.go new file mode 100644 index 0000000..309df70 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/clear.go @@ -0,0 +1,26 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "github.com/spf13/cobra" +) + +var clearCmd = &cobra.Command{ + Use: "clear", + Short: "Truncate visibility tables", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("clear called") + }, +} + +func init() { + rootCmd.AddCommand(clearCmd) +} diff --git a/clover/cloverctl/src/cloverctl/cmd/clear_visibility.go b/clover/cloverctl/src/cloverctl/cmd/clear_visibility.go new file mode 100644 index 0000000..9468714 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/clear_visibility.go @@ -0,0 +1,41 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "gopkg.in/resty.v1" + "github.com/spf13/cobra" +) + + +var visibilityclearCmd = &cobra.Command{ + Use: "visibility", + Short: "Clear visibility tables", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + clearCollector() + }, +} + +func init() { + clearCmd.AddCommand(visibilityclearCmd) +} + +func clearCollector() { + url := controllerIP + "/collector/truncate" + + resp, err := resty.R(). + Get(url) + if err != nil { + panic(err.Error()) + } + fmt.Printf("\n%v\n", resp) +} + + diff --git a/clover/cloverctl/src/cloverctl/cmd/create.go b/clover/cloverctl/src/cloverctl/cmd/create.go new file mode 100644 index 0000000..3a09fa4 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/create.go @@ -0,0 +1,26 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "github.com/spf13/cobra" +) + +var createCmd = &cobra.Command{ + Use: "create", + Short: "Create resources including IDS rules, L7 testplans, etc.", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("create called") + }, +} + +func init() { + rootCmd.AddCommand(createCmd) +} diff --git a/clover/cloverctl/src/cloverctl/cmd/create_idsrules.go b/clover/cloverctl/src/cloverctl/cmd/create_idsrules.go new file mode 100644 index 0000000..bc0d8d5 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/create_idsrules.go @@ -0,0 +1,56 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "io/ioutil" + "gopkg.in/resty.v1" + "github.com/ghodss/yaml" + "github.com/spf13/cobra" +) + + +var idsrulesCmd = &cobra.Command{ + Use: "idsrules", + Short: "Create one or many IDS rules from yaml file", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + createIDSRules() + }, +} + +func init() { + createCmd.AddCommand(idsrulesCmd) + idsrulesCmd.Flags().StringVarP(&cloverFile, "file", "f", "", "Input yaml file to add IDS rules") + idsrulesCmd.MarkFlagRequired("file") + +} + +func createIDSRules() { + url := controllerIP + "/snort/addrule" + in, err := ioutil.ReadFile(cloverFile) + if err != nil { + fmt.Println("Please specify a valid rule definition yaml file") + return + } + out_json, err := yaml.YAMLToJSON(in) + if err != nil { + panic(err.Error()) + } + resp, err := resty.R(). + SetHeader("Content-Type", "application/json"). + SetBody(out_json). + Post(url) + if err != nil { + panic(err.Error()) + } + fmt.Printf("\n%v\n", resp) + //fmt.Println(string(out_json)) + +} diff --git a/clover/cloverctl/src/cloverctl/cmd/create_system.go b/clover/cloverctl/src/cloverctl/cmd/create_system.go new file mode 100644 index 0000000..68fa5af --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/create_system.go @@ -0,0 +1,37 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + //"io/ioutil" + //"github.com/ghodss/yaml" + "github.com/spf13/cobra" + "cloverkube" +) + + +var systemCmd = &cobra.Command{ + Use: "system", + Short: "Deploy clover-system in Kubernetes", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + createCloverSystem() + }, +} + +func init() { + createCmd.AddCommand(systemCmd) + //systemCmd.PersistentFlags().StringVarP(&cloverFile, "f", "f", "", "Input yaml file to create system") + +} + +func createCloverSystem() { + cloverkube.DeployCloverSystem("create", "clover-system") + fmt.Println("Deployed clover-system successfully") +} diff --git a/clover/cloverctl/src/cloverctl/cmd/create_testplan.go b/clover/cloverctl/src/cloverctl/cmd/create_testplan.go new file mode 100644 index 0000000..686d5ba --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/create_testplan.go @@ -0,0 +1,57 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "gopkg.in/resty.v1" + "io/ioutil" + "github.com/ghodss/yaml" + "github.com/spf13/cobra" +) + + +var testplanCmd = &cobra.Command{ + Use: "testplan", + Short: "Create L7 client emulation test plans from yaml file", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + createTestPlan() + //fmt.Printf("%v\n", cmd.Parent().CommandPath()) + }, +} + +func init() { + createCmd.AddCommand(testplanCmd) + testplanCmd.Flags().StringVarP(&cloverFile, "file", "f", "", "Input yaml file with test plan params") + testplanCmd.MarkFlagRequired("file") +} + +func createTestPlan() { + url := controllerIP + "/jmeter/gen" + in, err := ioutil.ReadFile(cloverFile) + if err != nil { + fmt.Println("Please specify a valid test plan yaml file") + return + } + out_json, err := yaml.YAMLToJSON(in) + if err != nil { + panic(err.Error()) + } + resp, err := resty.R(). + SetHeader("Content-Type", "application/json"). + SetBody(out_json). + Post(url) + if err != nil { + panic(err.Error()) + } + fmt.Printf("\n%v\n", resp) + //fmt.Println(string(out_json)) + +} + diff --git a/clover/cloverctl/src/cloverctl/cmd/delete.go b/clover/cloverctl/src/cloverctl/cmd/delete.go new file mode 100644 index 0000000..742d769 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/delete.go @@ -0,0 +1,26 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "github.com/spf13/cobra" +) + +var deleteCmd = &cobra.Command{ + Use: "delete", + Short: "Delete resources including clover-system services", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("delete called") + }, +} + +func init() { + rootCmd.AddCommand(deleteCmd) +} diff --git a/clover/cloverctl/src/cloverctl/cmd/delete_system.go b/clover/cloverctl/src/cloverctl/cmd/delete_system.go new file mode 100644 index 0000000..bc3f22b --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/delete_system.go @@ -0,0 +1,33 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "github.com/spf13/cobra" + "cloverkube" +) + + +var delsystemCmd = &cobra.Command{ + Use: "system", + Short: "Delete clover-system in Kubernetes", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + delCloverSystem() + }, +} + +func init() { + deleteCmd.AddCommand(delsystemCmd) +} + +func delCloverSystem() { + cloverkube.DeployCloverSystem("delete", "clover-system") + fmt.Println("Deleted clover-system successfully") +} diff --git a/clover/cloverctl/src/cloverctl/cmd/get.go b/clover/cloverctl/src/cloverctl/cmd/get.go new file mode 100644 index 0000000..ae3d98e --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/get.go @@ -0,0 +1,26 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "github.com/spf13/cobra" +) + +var getCmd = &cobra.Command{ + Use: "get", + Short: "Get information about a resource", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("get called") + }, +} + +func init() { + rootCmd.AddCommand(getCmd) +} diff --git a/clover/cloverctl/src/cloverctl/cmd/get_services.go b/clover/cloverctl/src/cloverctl/cmd/get_services.go new file mode 100644 index 0000000..cfa56bd --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/get_services.go @@ -0,0 +1,26 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "github.com/spf13/cobra" + "cloverkube" +) + +var servicesCmd = &cobra.Command{ + Use: "services", + Short: "Get info on Kubernetes services", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + cloverkube.GetServices() + }, +} + +func init() { + getCmd.AddCommand(servicesCmd) +} diff --git a/clover/cloverctl/src/cloverctl/cmd/get_testresult.go b/clover/cloverctl/src/cloverctl/cmd/get_testresult.go new file mode 100644 index 0000000..12d47c3 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/get_testresult.go @@ -0,0 +1,56 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "gopkg.in/resty.v1" + "github.com/spf13/cobra" +) + +var JmeterResult string + +var testresultCmd = &cobra.Command{ + Use: "testresult", + Short: "Get test results from L7 client emulation", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + getResult() + }, +} + +func init() { + getCmd.AddCommand(testresultCmd) + testresultCmd.Flags().StringVarP(&JmeterResult, "r", "r", "", "Result to retrieve - use 'log' or 'results'") + testresultCmd.MarkFlagRequired("r") + +} + + +func getResult() { + switch JmeterResult { + case "results": + url := controllerIP + "/jmeter/results/results" + resp, err := resty.R(). + Get(url) + if err != nil { + panic(err.Error()) + } + fmt.Printf("\nResponse Body: %v\n", resp) + case "log": + url := controllerIP + "/jmeter/results/log" + resp, err := resty.R(). + Get(url) + if err != nil { + panic(err.Error()) + } + fmt.Printf("\nResponse Body: %v\n", resp) + default: + fmt.Println("Unrecoginized jmeter result type - use 'log' or 'results'") + } +} diff --git a/clover/cloverctl/src/cloverctl/cmd/get_visibility.go b/clover/cloverctl/src/cloverctl/cmd/get_visibility.go new file mode 100644 index 0000000..d987412 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/get_visibility.go @@ -0,0 +1,41 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "gopkg.in/resty.v1" + "github.com/spf13/cobra" +) + + +var visibilitystatsCmd = &cobra.Command{ + Use: "visibility", + Short: "Get toplevel visibility stats", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + statsCollector() + }, +} + +func init() { + getCmd.AddCommand(visibilitystatsCmd) + //visibilitystartCmd.PersistentFlags().StringVarP(&cloverFile, "f", "f", "", "Input yaml file with test plan params") +} + +func statsCollector() { + url := controllerIP + "/collector/stats" + + resp, err := resty.R(). + SetHeader("Accept", "application/json"). + Get(url) + if err != nil { + panic(err.Error()) + } + fmt.Printf("\nProxy Response Time: %v\n", resp) +} diff --git a/clover/cloverctl/src/cloverctl/cmd/init.go b/clover/cloverctl/src/cloverctl/cmd/init.go new file mode 100644 index 0000000..613b263 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/init.go @@ -0,0 +1,26 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "github.com/spf13/cobra" +) + +var initCmd = &cobra.Command{ + Use: "init", + Short: "Initialize visibility schemas", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("init called") + }, +} + +func init() { + rootCmd.AddCommand(initCmd) +} diff --git a/clover/cloverctl/src/cloverctl/cmd/init_visibility.go b/clover/cloverctl/src/cloverctl/cmd/init_visibility.go new file mode 100644 index 0000000..ac9ec5c --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/init_visibility.go @@ -0,0 +1,41 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "gopkg.in/resty.v1" + "github.com/spf13/cobra" +) + + +var visibilityinitCmd = &cobra.Command{ + Use: "visibility", + Short: "Init visibility data schemas", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + initCollector() + }, +} + +func init() { + initCmd.AddCommand(visibilityinitCmd) +} + +func initCollector() { + url := controllerIP + "/collector/init" + + resp, err := resty.R(). + Get(url) + if err != nil { + panic(err.Error()) + } + fmt.Printf("\n%v\n", resp) +} + + diff --git a/clover/cloverctl/src/cloverctl/cmd/root.go b/clover/cloverctl/src/cloverctl/cmd/root.go new file mode 100644 index 0000000..6878077 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/root.go @@ -0,0 +1,90 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "os" + + homedir "github.com/mitchellh/go-homedir" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "cloverkube" +) + +var cfgFile string + +var controllerIP string +var cloverFile string + +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ + Use: "cloverctl", + Short: "Command-Line Interface (CLI) for Clover", + Long: ``, + // Uncomment the following line if your bare application + // has an action associated with it: + //Run: func(cmd *cobra.Command, args []string) { + //}, +} + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +func init() { + cobra.OnInitialize(initConfig) + + // Here you will define your flags and configuration settings. + // Cobra supports persistent flags, which, if defined here, + // will be global for your application. + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cloverctl.yaml)") + + // Cobra also supports local flags, which will only run + // when this action is called directly. + rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + + cPort, cIP := cloverkube.GetServicesPortIP("clover-controller") + if cIP == "" { + controllerIP = "http://10.244.0.1:" + fmt.Sprint(cPort) + } else { + controllerIP = "http://" + cIP + } + fmt.Printf("\nclover-controller: %s %s\n", fmt.Sprint(cPort), cIP) +} + +// initConfig reads in config file and ENV variables if set. +func initConfig() { + if cfgFile != "" { + // Use config file from the flag. + viper.SetConfigFile(cfgFile) + } else { + // Find home directory. + home, err := homedir.Dir() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // Search config in home directory with name ".cloverctl" (without extension). + viper.AddConfigPath(home) + viper.SetConfigName(".cloverctl") + } + + viper.AutomaticEnv() // read in environment variables that match + + // If a config file is found, read it in. + if err := viper.ReadInConfig(); err == nil { + fmt.Println("Using config file:", viper.ConfigFileUsed()) + } +} diff --git a/clover/cloverctl/src/cloverctl/cmd/start.go b/clover/cloverctl/src/cloverctl/cmd/start.go new file mode 100644 index 0000000..741eacd --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/start.go @@ -0,0 +1,26 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "github.com/spf13/cobra" +) + +var startCmd = &cobra.Command{ + Use: "start", + Short: "Start processes including tests, visibility and ingress services", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("start called") + }, +} + +func init() { + rootCmd.AddCommand(startCmd) +} diff --git a/clover/cloverctl/src/cloverctl/cmd/start_ids.go b/clover/cloverctl/src/cloverctl/cmd/start_ids.go new file mode 100644 index 0000000..0f495a7 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/start_ids.go @@ -0,0 +1,42 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "gopkg.in/resty.v1" + "github.com/spf13/cobra" +) + + +var startidsCmd = &cobra.Command{ + Use: "ids", + Short: "Start IDS process", + Long: `Restart IDS process when adding custom rules`, + Run: func(cmd *cobra.Command, args []string) { + startIDS() + }, +} + +func init() { + startCmd.AddCommand(startidsCmd) +} + +func startIDS() { + + url := controllerIP + "/snort/start" + + resp, err := resty.R(). + Get(url) + if err != nil { + panic(err.Error()) + } + fmt.Printf("\n%v\n", resp) +} + + diff --git a/clover/cloverctl/src/cloverctl/cmd/start_testplan.go b/clover/cloverctl/src/cloverctl/cmd/start_testplan.go new file mode 100644 index 0000000..b516ad6 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/start_testplan.go @@ -0,0 +1,59 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "strings" + "gopkg.in/resty.v1" + "github.com/spf13/cobra" + "cloverkube" +) + + +var testplanstartCmd = &cobra.Command{ + Use: "testplan", + Short: "Start a test for a given test plan", + Long: `Specify number of slaves to use with '-s' flag. Default is 0 slaves, +which runs tests only from jmeter-master.`, + Run: func(cmd *cobra.Command, args []string) { + startTest() + //fmt.Printf("%v\n", cmd.Parent().CommandPath()) + }, +} +var num_slaves int + +func init() { + startCmd.AddCommand(testplanstartCmd) + testplanstartCmd.PersistentFlags().StringVarP(&cloverFile, "file", "f", "", "Currently unused") + testplanstartCmd.PersistentFlags().IntVarP(&num_slaves, "slaves", "s", 0, "Number of slaves to use") +} + +func startTest() { + + ips := cloverkube.GetPodsIP("clover-jmeter-slave", "default") + fmt.Printf("\njmeter-slaves found: %s\n", ips) + if num_slaves > len(ips) { + fmt.Printf("Number of slaves specified must be less than found: %d\n", len(ips)) + return + } + ip_list := strings.Join(ips[0:num_slaves], ",") + + url := controllerIP + "/jmeter/start" + resp, err := resty.R(). + SetHeader("Content-Type", "application/json"). + SetBody(fmt.Sprintf(`{"num_slaves":"%d", "slave_list":"%s"}`, num_slaves, ip_list)). + Post(url) + if err != nil { + panic(err.Error()) + } + fmt.Printf("\n%v\n", resp) + +} + + diff --git a/clover/cloverctl/src/cloverctl/cmd/start_visibility.go b/clover/cloverctl/src/cloverctl/cmd/start_visibility.go new file mode 100644 index 0000000..18f8aac --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/start_visibility.go @@ -0,0 +1,60 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "io/ioutil" + "gopkg.in/resty.v1" + "github.com/ghodss/yaml" + "github.com/spf13/cobra" +) + + +var visibilitystartCmd = &cobra.Command{ + Use: "visibility", + Short: "Start visibility data collection", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + startCollector() + }, +} + +func init() { + startCmd.AddCommand(visibilitystartCmd) + visibilitystartCmd.PersistentFlags().StringVarP(&cloverFile, "file", "f", "", "Optional yaml file with collector params") +} + +func startCollector() { + + var message_body string + if cloverFile != "" { + in, err := ioutil.ReadFile(cloverFile) + if err != nil { + panic(err.Error()) + } + out_json, err := yaml.YAMLToJSON(in) + message_body = string(out_json) + if err != nil { + panic(err.Error()) + } + } else { + message_body = `{"sample_interval":"10", "t_port":"80", "t_host":"jaeger-query.istio-system"}` + } + url := controllerIP + "/collector/start" + resp, err := resty.R(). + SetHeader("Content-Type", "application/json"). + SetBody(message_body). + Post(url) + if err != nil { + panic(err.Error()) + } + fmt.Printf("\n%v\n", resp) +} + + diff --git a/clover/cloverctl/src/cloverctl/cmd/stop.go b/clover/cloverctl/src/cloverctl/cmd/stop.go new file mode 100644 index 0000000..cfb7245 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/stop.go @@ -0,0 +1,26 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "github.com/spf13/cobra" +) + +var stopCmd = &cobra.Command{ + Use: "stop", + Short: "Stop processes including visibility and ingress services", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("stop called") + }, +} + +func init() { + rootCmd.AddCommand(stopCmd) +} diff --git a/clover/cloverctl/src/cloverctl/cmd/stop_ids.go b/clover/cloverctl/src/cloverctl/cmd/stop_ids.go new file mode 100644 index 0000000..b39b1e9 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/stop_ids.go @@ -0,0 +1,42 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "gopkg.in/resty.v1" + "github.com/spf13/cobra" +) + + +var stopidsCmd = &cobra.Command{ + Use: "ids", + Short: "Stop IDS process", + Long: `Restart IDS process when adding custom rules`, + Run: func(cmd *cobra.Command, args []string) { + stopIDS() + }, +} + +func init() { + stopCmd.AddCommand(stopidsCmd) +} + +func stopIDS() { + + url := controllerIP + "/snort/stop" + + resp, err := resty.R(). + Get(url) + if err != nil { + panic(err.Error()) + } + fmt.Printf("\n%v\n", resp) +} + + diff --git a/clover/cloverctl/src/cloverctl/cmd/stop_visibility.go b/clover/cloverctl/src/cloverctl/cmd/stop_visibility.go new file mode 100644 index 0000000..4233157 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/cmd/stop_visibility.go @@ -0,0 +1,42 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cmd + +import ( + "fmt" + "gopkg.in/resty.v1" + "github.com/spf13/cobra" +) + + +var visibilitystopCmd = &cobra.Command{ + Use: "visibility", + Short: "Stop visibility data collection", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + stopCollector() + }, +} + +func init() { + stopCmd.AddCommand(visibilitystopCmd) +} + +func stopCollector() { + + url := controllerIP + "/collector/stop" + + resp, err := resty.R(). + Get(url) + if err != nil { + panic(err.Error()) + } + fmt.Printf("\n%v\n", resp) +} + + diff --git a/clover/cloverctl/src/cloverctl/main.go b/clover/cloverctl/src/cloverctl/main.go new file mode 100644 index 0000000..602dd20 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/main.go @@ -0,0 +1,14 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package main + +import "cloverctl/cmd" + +func main() { + cmd.Execute() +} diff --git a/clover/cloverctl/src/cloverctl/yaml/idsrule_scan.yaml b/clover/cloverctl/src/cloverctl/yaml/idsrule_scan.yaml new file mode 100644 index 0000000..1cce7f7 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/yaml/idsrule_scan.yaml @@ -0,0 +1,9 @@ +sid: "10000003" +protocol: tcp +dest_port: any +dest_ip: $HOME_NET +src_port: any +src_ip: any +msg: MALWARE-CNC User-Agent ASafaWeb Scan +rev: "001" +content: '"asafaweb.com"' diff --git a/clover/cloverctl/src/cloverctl/yaml/idsrule_tcp.yaml b/clover/cloverctl/src/cloverctl/yaml/idsrule_tcp.yaml new file mode 100644 index 0000000..8711f5d --- /dev/null +++ b/clover/cloverctl/src/cloverctl/yaml/idsrule_tcp.yaml @@ -0,0 +1,10 @@ +sid: "10000002" +protocol: tcp +dest_port: any +dest_ip: $HOME_NET +src_port: any +src_ip: any +msg: test +rev: "001" +content: '' + diff --git a/clover/cloverctl/src/cloverctl/yaml/jmeter_testplan.yaml b/clover/cloverctl/src/cloverctl/yaml/jmeter_testplan.yaml new file mode 100644 index 0000000..140e70f --- /dev/null +++ b/clover/cloverctl/src/cloverctl/yaml/jmeter_testplan.yaml @@ -0,0 +1,11 @@ +load_spec: + num_threads: 1 + loops: 1 + ramp_time: 60 +url_list: + - name: url1 + url: http://proxy-access-control.default:9180 + method: GET + - name: url2 + url: http://proxy-access-control.default:9180 + method: GET diff --git a/clover/cloverctl/src/cloverctl/yaml/visibility.yaml b/clover/cloverctl/src/cloverctl/yaml/visibility.yaml new file mode 100644 index 0000000..20264d2 --- /dev/null +++ b/clover/cloverctl/src/cloverctl/yaml/visibility.yaml @@ -0,0 +1,7 @@ +sample_interval: "10" +#t_host: jaeger-deployment.istio-system +#t_port: "16686" +t_host: jaeger-query.istio-system +t_port: "80" +m_port: "9090" +m_host: prometheus.istio-system diff --git a/clover/cloverctl/src/cloverinject/inject.go b/clover/cloverctl/src/cloverinject/inject.go new file mode 100644 index 0000000..1953a3b --- /dev/null +++ b/clover/cloverctl/src/cloverinject/inject.go @@ -0,0 +1,141 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cloverinject + +import ( + "io" + "os" + "fmt" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "istio.io/istio/pilot/pkg/kube/inject" + meshconfig "istio.io/api/mesh/v1alpha1" + "k8s.io/client-go/kubernetes" + "istio.io/istio/pkg/kube" + "istio.io/istio/pilot/pkg/model" + "github.com/ghodss/yaml" + "istio.io/istio/pilot/cmd" + +) +//var _ = inject.InitImageName + +func CloverInject(inFilename string) { + + var err error + var kubeconfig string + + var reader io.Reader + + + var in *os.File + in, err = os.Open(inFilename) + if err != nil { + panic(err.Error()) + } + reader = in + + var writer io.Writer + outFilename := "out_sdc.yaml" + var out *os.File + out, err = os.Create(outFilename) + writer = out + + var sidecarTemplate string + if sidecarTemplate, err = getInjectConfigFromConfigMap(kubeconfig); err != nil { + fmt.Printf("this is a template gen error") + panic(err.Error()) + } + + var meshConfig *meshconfig.MeshConfig + meshConfigFile := "mesh-config.yaml" + if meshConfig, err = cmd.ReadMeshConfig(meshConfigFile); err != nil { + panic(err.Error()) + } + + inject.IntoResourceFile(sidecarTemplate, meshConfig, reader, writer) + +} + +func getMeshConfigFromConfigMap(kubeconfig string) (*meshconfig.MeshConfig, error) { + client, err := createInterface(kubeconfig) + if err != nil { + return nil, err + } + + istioNamespace := "istio-system" + meshConfigMapName := "istio" + configMapKey := "mesh" + + config, err := client.CoreV1().ConfigMaps(istioNamespace).Get(meshConfigMapName, metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("could not read valid configmap %q from namespace %q: %v - "+ + "Use --meshConfigFile or re-run kube-inject with `-i <istioSystemNamespace> and ensure valid MeshConfig exists", + meshConfigMapName, istioNamespace, err) + } + // values in the data are strings, while proto might use a + // different data type. therefore, we have to get a value by a + // key + configYaml, exists := config.Data[configMapKey] + if !exists { + return nil, fmt.Errorf("missing configuration map key %q", configMapKey) + } + return model.ApplyMeshConfigDefaults(configYaml) +} + +func getInjectConfigFromConfigMap(kubeconfig string) (string, error) { + client, err := createInterface(kubeconfig) + if err != nil { + return "", err + } + // added by me + istioNamespace := "istio-system" + injectConfigMapName := "istio-inject" + //injectConfigMapName := "istio-sidecar-injector" + injectConfigMapKey := "config" + + + config, err := client.CoreV1().ConfigMaps(istioNamespace).Get(injectConfigMapName, metav1.GetOptions{}) + if err != nil { + return "", fmt.Errorf("could not find valid configmap %q from namespace %q: %v - "+ + "Use --injectConfigFile or re-run kube-inject with `-i <istioSystemNamespace> and ensure istio-inject configmap exists", + injectConfigMapName, istioNamespace, err) + } + // values in the data are strings, while proto might use a + // different data type. therefore, we have to get a value by a + // key + injectData, exists := config.Data[injectConfigMapKey] + if !exists { + return "", fmt.Errorf("missing configuration map key %q in %q", + injectConfigMapKey, injectConfigMapName) + } + var injectConfig inject.Config + if err := yaml.Unmarshal([]byte(injectData), &injectConfig); err != nil { + return "", fmt.Errorf("unable to convert data from configmap %q: %v", + injectConfigMapName, err) + } + //log.Debugf("using inject template from configmap %q", injectConfigMapName) + return injectConfig.Template, nil +} + + +func homeDir() string { + if h := os.Getenv("HOME"); h != "" { + return h + } + return os.Getenv("USERPROFILE") // windows +} + +func createInterface(kubeconfig string) (kubernetes.Interface, error) { + + var configContext string + restConfig, err := kube.BuildClientConfig(kubeconfig, configContext) + + if err != nil { + return nil, err + } + return kubernetes.NewForConfig(restConfig) +} diff --git a/clover/cloverctl/src/cloverkube/main.go b/clover/cloverctl/src/cloverkube/main.go new file mode 100644 index 0000000..e2854b5 --- /dev/null +++ b/clover/cloverctl/src/cloverkube/main.go @@ -0,0 +1,400 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 + +package cloverkube + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + appsv1 "k8s.io/api/apps/v1" + apiv1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" +) + +func setClient() kubernetes.Interface { + + + kubeconfig := filepath.Join( + os.Getenv("HOME"), ".kube", "config", + ) + config, err := clientcmd.BuildConfigFromFlags("", kubeconfig) + if err != nil { + panic(err.Error()) + } + + // create the clientset + clientset, err := kubernetes.NewForConfig(config) + if err != nil { + panic(err.Error()) + } + return clientset +} + +func setControllerDeploy () (*appsv1.Deployment, *apiv1.Service) { + + deployment := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "clover-controller", + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "clover-controller", + }, + }, + Template: apiv1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app": "clover-controller", + }, + }, + Spec: apiv1.PodSpec{ + Containers: []apiv1.Container{ + { + Name: "clover-controller", + Image: "localhost:5000/clover-controller:latest", + Ports: []apiv1.ContainerPort{ + { + Name: "redis", + Protocol: apiv1.ProtocolTCP, + ContainerPort: 6379, + }, + { + Name: "grpc", + Protocol: apiv1.ProtocolTCP, + ContainerPort: 50054, + }, + { + Name: "gprcsecurity", + Protocol: apiv1.ProtocolTCP, + ContainerPort: 50052, + }, + { + Name: "cassandra", + Protocol: apiv1.ProtocolTCP, + ContainerPort: 9042, + }, + + + }, + }, + }, + }, + }, + }, + } + + service := &apiv1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "clover-controller", + Labels: map[string]string{ + "app": "clover-controller", + }, + + }, + Spec: apiv1.ServiceSpec{ + Selector: map[string]string{ + "app": "clover-controller", + }, + Type: "NodePort", + Ports: []apiv1.ServicePort{ + { + Name: "http", + Port: 80, + NodePort: 32044, + Protocol: "TCP", + }, + }, + }, + } + + return deployment, service + +} + +func setCollectorDeploy () (*appsv1.Deployment, *apiv1.Service) { + + deployment := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "clover-collector", + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "clover-collector", + }, + }, + Template: apiv1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app": "clover-collector", + }, + }, + Spec: apiv1.PodSpec{ + Containers: []apiv1.Container{ + { + Name: "clover-collector", + Image: "localhost:5000/clover-collector:latest", + Ports: []apiv1.ContainerPort{ + { + Name: "redis", + Protocol: apiv1.ProtocolTCP, + ContainerPort: 6379, + }, + { + Name: "grpc", + Protocol: apiv1.ProtocolTCP, + ContainerPort: 50054, + }, + { + Name: "prometheus", + Protocol: apiv1.ProtocolTCP, + ContainerPort: 9090, + }, + { + Name: "jaeger", + Protocol: apiv1.ProtocolTCP, + ContainerPort: 16686, + }, + { + Name: "cassandra", + Protocol: apiv1.ProtocolTCP, + ContainerPort: 9042, + }, + + + }, + }, + }, + }, + }, + }, + } + + service := &apiv1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "clover-collector", + Labels: map[string]string{ + "app": "clover-collector", + }, + + }, + Spec: apiv1.ServiceSpec{ + Selector: map[string]string{ + "app": "clover-collector", + }, + Ports: []apiv1.ServicePort{ + { + Name: "grpc", + Port: 50054, + }, + { + Name: "redis", + Port: 6379, + }, + { + Name: "prometheus", + Port: 9090, + }, + { + Name: "jaeger", + Port: 16686, + }, + { + Name: "cassandra", + Port: 9042, + }, + + }, + }, + } + return deployment, service +} + +func DeployCloverSystem(action string, namespace string) { + if action == "create" { + // Create clover-system namespace + configNamespace("clover-system", "create") + // Controller + deployment, service := setControllerDeploy() + DeployService(deployment, service, namespace) + // Collector + deployment, service = setCollectorDeploy() + DeployService(deployment, service, namespace) + } else if action == "delete" { + fmt.Println("Deleting clover-system services...\n") + DeleteService("clover-controller", namespace) + DeleteService("clover-collector", namespace) + configNamespace("clover-system", "delete") + } + +} + +func DeleteService(deploy_name string, namespace string) { + + clientset := setClient() + deploymentsClient := clientset.AppsV1().Deployments(namespace) + servicesClient := clientset.CoreV1().Services(namespace) + + // Delete Deployment + deletePolicy := metav1.DeletePropagationForeground + if err := deploymentsClient.Delete(deploy_name, &metav1.DeleteOptions{ + PropagationPolicy: &deletePolicy, + }); err != nil { + panic(err) + } + fmt.Printf("Deleted %s deployment\n", deploy_name) + + // Delete Service + if err := servicesClient.Delete(deploy_name, &metav1.DeleteOptions{ + PropagationPolicy: &deletePolicy, + }); err != nil { + panic(err) + } + fmt.Printf("Deleted %s service\n", deploy_name) +} + +func DeployService(deployment *appsv1.Deployment, service *apiv1.Service, namespace string) { + + clientset := setClient() + deploymentsClient := clientset.AppsV1().Deployments(namespace) + + + // Create Deployment + fmt.Println("Creating deployment...") + result, err := deploymentsClient.Create(deployment) + if err != nil { + panic(err) + } + fmt.Printf("Created deployment %q.\n", result.GetObjectMeta().GetName()) + + // Create Service + fmt.Println("Creating service...") + servicesClient := clientset.CoreV1().Services(namespace) + + result1, err := servicesClient.Create(service) + if err != nil { + panic(err) + } + fmt.Printf("Created service %q.\n", result1.GetObjectMeta().GetName()) + +} + +func configNamespace (name string, action string) { + clientset := setClient() + nameClient := clientset.CoreV1().Namespaces() + + if action == "create" { + namespace := &apiv1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + } + nameClient.Create(namespace) + fmt.Printf("Created %s namespace\n", name) + } else if action == "delete" { + deletePolicy := metav1.DeletePropagationForeground + if err := nameClient.Delete(name, &metav1.DeleteOptions{ + PropagationPolicy: &deletePolicy, + }); err != nil { + panic(err) + } + fmt.Printf("Deleted %s namespace\n", name) + } +} + +func GetServices() *apiv1.ServiceList { + + clientset := setClient() + services, err := clientset.Core().Services("").List(metav1.ListOptions{}) + for _, service := range services.Items { + if err != nil { + panic(err.Error()) + } + fmt.Printf(" * SERVICE Name: %s\n", service.GetName()) + fmt.Printf("Kind: %s\n", service.Kind) + fmt.Printf("Labels: %s\n", service.GetLabels()) + fmt.Printf("Type: %s\n", service.Spec.Type) + //fmt.Printf("External IP: %v\n", service.Spec.ExternalIPs) + fmt.Printf("Cluster IP: %s\n", service.Spec.ClusterIP) + + for _, port := range service.Spec.Ports { + fmt.Printf("Port Name: %s, Port# %d, NodePort: %d\n", port.Name, port.Port, port.NodePort) + } + + for _, ip := range service.Status.LoadBalancer.Ingress { + fmt.Printf("LB IP: %s \n", ip.IP) + } + } + return services +} + +func GetDeployments(namespace string) []appsv1.Deployment { + + clientset := setClient() + + deploymentsClient := clientset.AppsV1().Deployments(namespace) + list, err := deploymentsClient.List(metav1.ListOptions{}) + if err != nil { + panic(err) + } + for _, d := range list.Items { + fmt.Printf(" * %s (%d replicas)\n", d.Name, *d.Spec.Replicas) + } + return list.Items +} + +func GetServicesPortIP(service_name string) (int32, string) { + + clientset := setClient() + services, err := clientset.Core().Services("").List(metav1.ListOptions{}) + var nodeport int32 + var ipaddress string + nodeport = 0 + ipaddress = "" + for _, service := range services.Items { + if err != nil { + panic(err.Error()) + } + if service.GetName() == service_name { + for _, port := range service.Spec.Ports { + if port.NodePort > 0 { + nodeport = port.NodePort + } + } + for _, ip := range service.Status.LoadBalancer.Ingress { + ipaddress = ip.IP + } + } + } + + return nodeport, ipaddress +} + +func GetPodsIP(pod_name string, namespace string) []string { + + clientset := setClient() + + var ips []string + pods, err := clientset.CoreV1().Pods(namespace).List(metav1.ListOptions{}) + if err != nil { + panic(err) + } + for _, pod := range pods.Items { + if strings.Contains(pod.Name, pod_name) { + fmt.Println(pod.Name, pod.Status.PodIP) + ips = append(ips, pod.Status.PodIP) + } + } + + return ips +} |