summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEddie Arrage <eddie.arrage@huawei.com>2018-08-02 23:15:39 +0000
committerEddie Arrage <eddie.arrage@huawei.com>2018-08-02 23:56:23 +0000
commitc0837d0701009e6142f9800f2b146bec17d6910f (patch)
tree8b07c911619c889e0f16d24fca6cbc115f760bab
parent25285393777b4e0ce7989cb6c9cce6b040523feb (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>
-rwxr-xr-xclover/cloverctl/build.sh36
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/clear.go26
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/clear_visibility.go41
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/create.go26
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/create_idsrules.go56
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/create_system.go37
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/create_testplan.go57
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/delete.go26
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/delete_system.go33
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/get.go26
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/get_services.go26
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/get_testresult.go56
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/get_visibility.go41
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/init.go26
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/init_visibility.go41
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/root.go90
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/start.go26
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/start_ids.go42
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/start_testplan.go59
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/start_visibility.go60
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/stop.go26
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/stop_ids.go42
-rw-r--r--clover/cloverctl/src/cloverctl/cmd/stop_visibility.go42
-rw-r--r--clover/cloverctl/src/cloverctl/main.go14
-rw-r--r--clover/cloverctl/src/cloverctl/yaml/idsrule_scan.yaml9
-rw-r--r--clover/cloverctl/src/cloverctl/yaml/idsrule_tcp.yaml10
-rw-r--r--clover/cloverctl/src/cloverctl/yaml/jmeter_testplan.yaml11
-rw-r--r--clover/cloverctl/src/cloverctl/yaml/visibility.yaml7
-rw-r--r--clover/cloverctl/src/cloverinject/inject.go141
-rw-r--r--clover/cloverctl/src/cloverkube/main.go400
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
+}