summaryrefslogtreecommitdiffstats
path: root/clover/cloverctl/src/cloverkube/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'clover/cloverctl/src/cloverkube/main.go')
-rw-r--r--clover/cloverctl/src/cloverkube/main.go459
1 files changed, 459 insertions, 0 deletions
diff --git a/clover/cloverctl/src/cloverkube/main.go b/clover/cloverctl/src/cloverkube/main.go
new file mode 100644
index 0000000..bcda990
--- /dev/null
+++ b/clover/cloverctl/src/cloverkube/main.go
@@ -0,0 +1,459 @@
+// 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"
+ "io/ioutil"
+ "io"
+ "bytes"
+ "github.com/ghodss/yaml"
+ "encoding/json"
+
+ appsv1 "k8s.io/api/apps/v1"
+ v1beta1 "k8s.io/api/apps/v1beta1"
+ v1beta1ext "k8s.io/api/extensions/v1beta1"
+ apiv1 "k8s.io/api/core/v1"
+ rbacv1 "k8s.io/api/rbac/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/tools/clientcmd"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/client-go/tools/remotecommand"
+)
+
+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
+}
+
+// Create various K8s resources
+func CreateResource(input_yaml string, resource_type string,
+ image string, namespace string) {
+ if namespace == "" {
+ namespace = "clover-system"
+ }
+ // Check path from cloverctl first
+ exe_path, err := os.Executable()
+ abs_input_yaml := strings.Replace(exe_path, "cloverctl", "", -1) +
+ "/yaml/" + input_yaml
+ if _, err := os.Stat(abs_input_yaml); !os.IsNotExist(err) {
+ input_yaml = abs_input_yaml
+ }
+ in, err := ioutil.ReadFile(input_yaml)
+ if err != nil {
+ fmt.Println("Please specify a valid manifest yaml file")
+ return
+ }
+ out_json, err := yaml.YAMLToJSON(in)
+ if err != nil {
+ panic(err.Error())
+ }
+
+ switch resource_type {
+ case "deployment":
+ deploy := v1beta1.Deployment{}
+ err = json.Unmarshal(out_json, &deploy)
+ deploy.Spec.Template.Spec.Containers[0].Image = image
+ CreateDeployment(&deploy, namespace)
+ fmt.Printf("Image: %s\n",
+ deploy.Spec.Template.Spec.Containers[0].Image)
+ case "service":
+ service := apiv1.Service{}
+ err = json.Unmarshal(out_json, &service)
+ CreateService(&service, namespace)
+ case "serviceaccount":
+ sa := apiv1.ServiceAccount{}
+ err = json.Unmarshal(out_json, &sa)
+ CreateServiceAccount(&sa, namespace)
+ case "clusterrolebinding":
+ clusterrolebinding := rbacv1.ClusterRoleBinding{}
+ err = json.Unmarshal(out_json, &clusterrolebinding)
+ CreateCRB(&clusterrolebinding)
+ case "statefulset":
+ statefulset := appsv1.StatefulSet{}
+ err = json.Unmarshal(out_json, &statefulset)
+ CreateStatefulSet(&statefulset, namespace)
+ case "pod":
+ pod := apiv1.Pod{}
+ err = json.Unmarshal(out_json, &pod)
+ CreatePod(&pod, namespace)
+ case "daemonset":
+ daemon := v1beta1ext.DaemonSet{}
+ err = json.Unmarshal(out_json, &daemon)
+ daemon.Spec.Template.Spec.Containers[0].Image = image
+ CreateDaemonSet(&daemon, namespace)
+ fmt.Printf("Image: %s\n",
+ daemon.Spec.Template.Spec.Containers[0].Image)
+
+ default:
+ fmt.Println("No resource selected")
+ }
+}
+
+// Delete K8s resources
+func DeleteResource(deploy_name string, resource_type string,
+ namespace string) {
+ clientset := setClient()
+ deletePolicy := metav1.DeletePropagationForeground
+
+ switch resource_type {
+ case "deployment":
+ deploymentsClient := clientset.AppsV1().Deployments(namespace)
+ if err := deploymentsClient.Delete(deploy_name,
+ &metav1.DeleteOptions{
+ PropagationPolicy: &deletePolicy,
+ }); err != nil {
+ fmt.Printf("Error deleting %v: %v\n", resource_type, err)
+ return
+ }
+ case "service":
+ servicesClient := clientset.CoreV1().Services(namespace)
+ if err := servicesClient.Delete(deploy_name, &metav1.DeleteOptions{
+ PropagationPolicy: &deletePolicy,
+ }); err != nil {
+ fmt.Printf("Error deleting %v: %v\n", resource_type, err)
+ return
+ }
+ case "serviceaccount":
+ saClient := clientset.CoreV1().ServiceAccounts(namespace)
+ if err := saClient.Delete(deploy_name, &metav1.DeleteOptions{
+ PropagationPolicy: &deletePolicy,
+ }); err != nil {
+ fmt.Printf("Error deleting %v: %v\n", resource_type, err)
+ return
+ }
+ case "clusterrolebinding":
+ crbClient := clientset.RbacV1().ClusterRoleBindings()
+ if err := crbClient.Delete(deploy_name, &metav1.DeleteOptions{
+ PropagationPolicy: &deletePolicy,
+ }); err != nil {
+ fmt.Printf("Error deleting %v: %v\n", resource_type, err)
+ return
+ }
+ case "statefulset":
+ statefulClient := clientset.AppsV1().StatefulSets(namespace)
+ if err := statefulClient.Delete(deploy_name, &metav1.DeleteOptions{
+ PropagationPolicy: &deletePolicy,
+ }); err != nil {
+ fmt.Printf("Error deleting %v: %v\n", resource_type, err)
+ return
+ }
+ case "pod":
+ podClient := clientset.CoreV1().Pods(namespace)
+ if err := podClient.Delete(deploy_name, &metav1.DeleteOptions{
+ PropagationPolicy: &deletePolicy,
+ }); err != nil {
+ fmt.Printf("Error deleting %v: %v\n", resource_type, err)
+ return
+ }
+ case "daemonset":
+ daemonsClient := clientset.AppsV1().DaemonSets(namespace)
+ if err := daemonsClient.Delete(deploy_name,
+ &metav1.DeleteOptions{
+ PropagationPolicy: &deletePolicy,
+ }); err != nil {
+ fmt.Printf("Error deleting %v: %v\n", resource_type, err)
+ return
+ }
+ }
+ fmt.Printf("Deleted %s %s\n", deploy_name, resource_type)
+}
+
+// Create ServiceAccount
+func CreateServiceAccount(sa *apiv1.ServiceAccount, namespace string) {
+ clientset := setClient()
+ saClient := clientset.CoreV1().ServiceAccounts(namespace)
+ result, err := saClient.Create(sa)
+ if err != nil {
+ fmt.Printf("Error creating serviceaccount: %v\n", err); return
+ }
+ fmt.Printf("Created serviceaccount %q.\n",
+ result.GetObjectMeta().GetName())
+}
+
+// Create ClusterRoleBinding
+func CreateCRB(sa *rbacv1.ClusterRoleBinding) {
+ clientset := setClient()
+ crbClient := clientset.RbacV1().ClusterRoleBindings()
+ result, err := crbClient.Create(sa)
+ if err != nil {
+ fmt.Printf("Error creating clusterrolebinding: %v\n", err); return
+ }
+ fmt.Printf("Created clusterrolebinding %q.\n",
+ result.GetObjectMeta().GetName())
+}
+
+// Create DaemonSet
+func CreateDaemonSet(daemonset *v1beta1ext.DaemonSet, namespace string) {
+ clientset := setClient()
+ daemonsClient := clientset.ExtensionsV1beta1().DaemonSets(namespace)
+ result, err := daemonsClient.Create(daemonset)
+ if err != nil {
+ fmt.Printf("Error creating daemonset: %v\n", err); return
+ }
+ fmt.Printf("Created daemonset %q.\n", result.GetObjectMeta().GetName())
+}
+
+// Create Deployment
+func CreateDeployment(deployment *v1beta1.Deployment, namespace string) {
+ clientset := setClient()
+ deploymentsClient := clientset.AppsV1beta1().Deployments(namespace)
+ result, err := deploymentsClient.Create(deployment)
+ if err != nil {
+ fmt.Printf("Error creating deployment: %v\n", err); return
+ }
+ fmt.Printf("Created deployment %q.\n", result.GetObjectMeta().GetName())
+}
+
+// Create StatefulSet
+func CreateStatefulSet(statefulset *appsv1.StatefulSet, namespace string) {
+ clientset := setClient()
+ statefulsetClient := clientset.AppsV1().StatefulSets(namespace)
+ result, err := statefulsetClient.Create(statefulset)
+ if err != nil {
+ fmt.Printf("Error creating statefulset: %v\n", err); return
+ }
+ fmt.Printf("Created statefulset %q.\n", result.GetObjectMeta().GetName())
+}
+
+// Create Pod
+func CreatePod(pod *apiv1.Pod, namespace string) {
+ clientset := setClient()
+ podClient := clientset.CoreV1().Pods(namespace)
+ result, err := podClient.Create(pod)
+ if err != nil {
+ fmt.Printf("Error creating pod: %v\n", err); return
+ panic(err)
+ }
+ fmt.Printf("Created pod %q.\n", result.GetObjectMeta().GetName())
+}
+
+// Create Service
+func CreateService(service *apiv1.Service, namespace string) {
+ clientset := setClient()
+ servicesClient := clientset.CoreV1().Services(namespace)
+
+ result1, err := servicesClient.Create(service)
+ if err != nil {
+ fmt.Printf("Error creating service: %v\n", err); return
+ }
+ fmt.Printf("Created service %q\n", result1.GetObjectMeta().GetName())
+}
+
+// Create or delete namespace
+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 {
+ fmt.Printf("Error deleting namespace: %v\n", err); return
+ }
+ 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("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
+}
+
+func CopyFileToPod(src, dest string) error {
+
+ // dest must be "namespace/podname/containername:<your path>"
+ pSplit := strings.Split(dest, ":")
+ pathPrefix := pSplit[0]
+ pathToCopy := pSplit[1]
+
+ buffer, err := ioutil.ReadFile(src)
+ if err != nil {
+ fmt.Print(err)
+ }
+
+ dir, _ := filepath.Split(pathToCopy)
+ command := "mkdir -p " + dir
+ _, stderr, err := Exec(pathPrefix, command, nil)
+
+ if err != nil {
+ fmt.Print(err)
+ fmt.Print(stderr)
+ return err
+ }
+
+ command = "cp /dev/stdin " + pathToCopy
+ stdin := bytes.NewReader(buffer)
+ _, stderr, err = Exec(pathPrefix, command, stdin)
+
+ if err != nil {
+ fmt.Print(err)
+ fmt.Print(stderr)
+ return err
+ }
+
+ return nil
+}
+
+
+func Exec(pathPrefix, command string, stdin io.Reader) ([]byte, []byte, error) {
+ clientset := setClient()
+ kubeconfig := filepath.Join(
+ os.Getenv("HOME"), ".kube", "config",
+ )
+ config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
+ if err != nil {
+ panic(err.Error())
+ }
+
+ prefixSplit := strings.Split(pathPrefix, "/")
+ namespace := prefixSplit[0]
+ podName := prefixSplit[1]
+ containerName := prefixSplit[2]
+
+ req := clientset.Core().RESTClient().Post().
+ Resource("pods").
+ Name(podName).
+ Namespace(namespace).
+ SubResource("exec")
+ scheme := runtime.NewScheme()
+ if err := apiv1.AddToScheme(scheme); err != nil {
+ return nil, nil, fmt.Errorf("error adding to scheme: %v", err)
+ }
+
+ parameterCodec := runtime.NewParameterCodec(scheme)
+ req.VersionedParams(&apiv1.PodExecOptions{
+ Command: strings.Fields(command),
+ Container: containerName,
+ Stdin: stdin != nil,
+ Stdout: true,
+ Stderr: true,
+ TTY: false,
+ }, parameterCodec)
+
+ exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())
+ if err != nil {
+ return nil, nil, fmt.Errorf("error while creating Executor: %v", err)
+ }
+
+ var stdout, stderr bytes.Buffer
+ err = exec.Stream(remotecommand.StreamOptions{
+ Stdin: stdin,
+ Stdout: &stdout,
+ Stderr: &stderr,
+ Tty: false,
+ })
+ if err != nil {
+ return nil, nil, fmt.Errorf("error in Stream: %v", err)
+ }
+
+ return stdout.Bytes(), stderr.Bytes(), nil
+}