From 0f58937fbd02399707c4549b7c4bf1e253f03922 Mon Sep 17 00:00:00 2001 From: WoodProgrammer Date: Wed, 24 May 2023 04:03:43 +0300 Subject: [PATCH 1/2] backup only mode gencode added --- src/backup.bin | Bin 0 -> 38 bytes src/backup.go | 8 +++---- src/binary.go | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ src/cli.go | 24 +++++++++++++++++--- src/restore.go | 10 ++++----- src/types.go | 8 +++---- 6 files changed, 94 insertions(+), 16 deletions(-) create mode 100644 src/backup.bin create mode 100644 src/binary.go diff --git a/src/backup.bin b/src/backup.bin new file mode 100644 index 0000000000000000000000000000000000000000..f9b3cf80f7565f637c21c61977b777060d133bbc GIT binary patch literal 38 qcmd=6-^|3w^uL9H@qZHogZTeOW=2MCkJOyppwyhy#Nt%2FarScmJA92 literal 0 HcmV?d00001 diff --git a/src/backup.go b/src/backup.go index bf8277c..3cf2377 100644 --- a/src/backup.go +++ b/src/backup.go @@ -25,10 +25,10 @@ func getBackup(namespace string, clientset *kubernetes.Clientset) []HelmRelease for _, item := range secrets.Items { r := HelmRelease{ - status: item.ObjectMeta.Labels["status"], - version: item.ObjectMeta.Labels["version"], - content: string(item.Data["release"]), - name: item.ObjectMeta.Labels["name"], + Status: item.ObjectMeta.Labels["status"], + Version: item.ObjectMeta.Labels["version"], + Content: string(item.Data["release"]), + Name: item.ObjectMeta.Labels["name"], } releaseMap = append(releaseMap, r) } diff --git a/src/binary.go b/src/binary.go new file mode 100644 index 0000000..770c676 --- /dev/null +++ b/src/binary.go @@ -0,0 +1,60 @@ +package main + +import ( + "bufio" + "bytes" + "encoding/gob" + "fmt" + "log" + "os" +) + +func dump(filename string, value []HelmRelease) { + file, _ := os.Create(filename) + + enc := gob.NewEncoder(file) + + if err := enc.Encode(value); err != nil { + log.Fatal(err) + } +} + +func encodedBackup(filename string) []byte { + file, err := os.Open(filename) + + if err != nil { + fmt.Println(err) + } + defer file.Close() + + stats, statsErr := file.Stat() + if statsErr != nil { + fmt.Println(statsErr) + } + + var size int64 = stats.Size() + bytes := make([]byte, size) + + bufr := bufio.NewReader(file) + _, err = bufr.Read(bytes) + + return bytes +} + +func decodeFromBackup(filename string) error { + + data := encodedBackup(filename) + + buf := bytes.NewBuffer(data) + dec := gob.NewDecoder(buf) + + m := []HelmRelease{} + + if err := dec.Decode(&m); err != nil { + log.Fatal(err) + return err + } + + return nil + +} diff --git a/src/cli.go b/src/cli.go index 18be0cb..89e12b8 100644 --- a/src/cli.go +++ b/src/cli.go @@ -1,7 +1,9 @@ package main import ( + "fmt" "os" + "time" "github.com/spf13/cobra" ) @@ -25,23 +27,38 @@ var mode = &cobra.Command{ targetCluster, _ := cmd.Flags().GetString("targetcluster") sourceCluster, _ := cmd.Flags().GetString("sourcecluster") targetNs, _ := cmd.Flags().GetString("ns") + rollback, _ := cmd.Flags().GetBool("rollback") WarningLogger.Println("Source cluster is :: ", sourceCluster) WarningLogger.Println("Target cluster is ::", targetCluster) WarningLogger.Println("Source namespace is ::", targetNs) + sourceClusterclientset := configHandler(sourceCluster) if args[0] == "backup" { WarningLogger.Println("Running only backup mode.. Extracting files under this directory...") + backup := getBackup(targetNs, sourceClusterclientset) + currentTime := time.Now() + + backupFile := fmt.Sprintf("%d-%d-%d-%d-%d-%d-helm.backup\n", + currentTime.Year(), + currentTime.Month(), + currentTime.Day(), + currentTime.Hour(), + currentTime.Hour(), + currentTime.Second()) - // TODO backup only mode - } else if args[0] == "restore" { + dump(backupFile, backup) + + } else if args[0] == "restore" || args[0] == "full" { WarningLogger.Println("This option provides both backup and restore functionality...") sourceClusterclientset := configHandler(sourceCluster) targetClusterclientset := configHandler(targetCluster) backup := getBackup(targetNs, sourceClusterclientset) restoreBackup(targetNs, targetClusterclientset, backup) - + if rollback == true { + WarningLogger.Println("Rollback option is enabled ") + } } }, } @@ -52,6 +69,7 @@ func Execute() { mode.PersistentFlags().String("ns", "", "The target namespace to fetch helm release and restore") mode.PersistentFlags().String("targetcluster", "", "Source of the backup of helm releases") mode.PersistentFlags().String("sourcecluster", "", "Target cluster address of helm restore operation") + mode.PersistentFlags().String("rollback", "", "This option provides rollback option enabled whether or not") if err := rootCmd.Execute(); err != nil { ErrorLogger.Println(os.Stderr, "Whoops. There was an error while executing your CLI '%s'", err) diff --git a/src/restore.go b/src/restore.go index bffc556..b9247b7 100644 --- a/src/restore.go +++ b/src/restore.go @@ -12,7 +12,7 @@ import ( func restoreBackup(namespace string, clientset *kubernetes.Clientset, releaseMap []HelmRelease) { for _, release := range releaseMap { - secretName := fmt.Sprintf("sh.helm.release.v1.%s.v%s", release.name, release.version) + secretName := fmt.Sprintf("sh.helm.release.v1.%s.v%s", release.Name, release.Version) secret := corev1.Secret{ TypeMeta: metav1.TypeMeta{ @@ -26,12 +26,12 @@ func restoreBackup(namespace string, clientset *kubernetes.Clientset, releaseMap Namespace: namespace, Labels: map[string]string{ "owner": "helm", - "name": release.name, - "status": release.status, - "version": release.version, + "name": release.Name, + "status": release.Status, + "version": release.Version, }, }, - Data: map[string][]byte{"release": []byte(release.content)}, + Data: map[string][]byte{"release": []byte(release.Content)}, } _, err := clientset.CoreV1().Secrets(namespace).Create(context.TODO(), &secret, metav1.CreateOptions{}) diff --git a/src/types.go b/src/types.go index e77bab1..d510453 100644 --- a/src/types.go +++ b/src/types.go @@ -1,8 +1,8 @@ package main type HelmRelease struct { - name string - version string - status string - content string + Name string + Version string + Status string + Content string } From 2e52aa102dae5c1488229cb3af1727cc536676a1 Mon Sep 17 00:00:00 2001 From: WoodProgrammer Date: Sat, 27 May 2023 01:32:34 +0300 Subject: [PATCH 2/2] kubeconfig parameter added --- src/backup.bin | Bin 38 -> 0 bytes src/cli.go | 12 +++++++----- src/config.go | 22 ++++++++++++++-------- 3 files changed, 21 insertions(+), 13 deletions(-) delete mode 100644 src/backup.bin diff --git a/src/backup.bin b/src/backup.bin deleted file mode 100644 index f9b3cf80f7565f637c21c61977b777060d133bbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38 qcmd=6-^|3w^uL9H@qZHogZTeOW=2MCkJOyppwyhy#Nt%2FarScmJA92 diff --git a/src/cli.go b/src/cli.go index 89e12b8..1fa3373 100644 --- a/src/cli.go +++ b/src/cli.go @@ -28,18 +28,19 @@ var mode = &cobra.Command{ sourceCluster, _ := cmd.Flags().GetString("sourcecluster") targetNs, _ := cmd.Flags().GetString("ns") rollback, _ := cmd.Flags().GetBool("rollback") + kubeconfig, _ := cmd.Flags().GetString("kubeconfig") WarningLogger.Println("Source cluster is :: ", sourceCluster) WarningLogger.Println("Target cluster is ::", targetCluster) WarningLogger.Println("Source namespace is ::", targetNs) - sourceClusterclientset := configHandler(sourceCluster) + sourceClusterclientset := configHandler(sourceCluster, kubeconfig) if args[0] == "backup" { WarningLogger.Println("Running only backup mode.. Extracting files under this directory...") backup := getBackup(targetNs, sourceClusterclientset) currentTime := time.Now() - backupFile := fmt.Sprintf("%d-%d-%d-%d-%d-%d-helm.backup\n", + backupFile := fmt.Sprintf("%d-%d-%d-%d-%d-%d-helm.backup", currentTime.Year(), currentTime.Month(), currentTime.Day(), @@ -49,10 +50,10 @@ var mode = &cobra.Command{ dump(backupFile, backup) - } else if args[0] == "restore" || args[0] == "full" { + } else if args[0] == "full" { WarningLogger.Println("This option provides both backup and restore functionality...") - sourceClusterclientset := configHandler(sourceCluster) - targetClusterclientset := configHandler(targetCluster) + sourceClusterclientset := configHandler(sourceCluster, kubeconfig) + targetClusterclientset := configHandler(targetCluster, kubeconfig) backup := getBackup(targetNs, sourceClusterclientset) restoreBackup(targetNs, targetClusterclientset, backup) @@ -70,6 +71,7 @@ func Execute() { mode.PersistentFlags().String("targetcluster", "", "Source of the backup of helm releases") mode.PersistentFlags().String("sourcecluster", "", "Target cluster address of helm restore operation") mode.PersistentFlags().String("rollback", "", "This option provides rollback option enabled whether or not") + mode.PersistentFlags().String("kubeconfig", "", "This path of the kubeconfig") if err := rootCmd.Execute(); err != nil { ErrorLogger.Println(os.Stderr, "Whoops. There was an error while executing your CLI '%s'", err) diff --git a/src/config.go b/src/config.go index 4091909..ead2049 100644 --- a/src/config.go +++ b/src/config.go @@ -1,22 +1,28 @@ package main import ( + "fmt" + "os" + "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" ) -func configHandler(contextToUse string) *kubernetes.Clientset { - /*var kubeconfig *string +func configHandler(contextToUse string, kubeconfig string) *kubernetes.Clientset { + var filename string + var kubeconfigPath string + dirname, err := os.UserHomeDir() + + if kubeconfig == "" { + filename = ".kube/config" + kubeconfigPath = fmt.Sprintf("%s/%s", dirname, filename) - if home := homedir.HomeDir(); home != "" { - kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file") - } else { - kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file") } - flag.Parse()*/ + + WarningLogger.Println("The obtained kubeconfig path is %s", kubeconfigPath) config, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( - &clientcmd.ClientConfigLoadingRules{ExplicitPath: "/Users/user/.kube/config"}, + &clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfigPath}, &clientcmd.ConfigOverrides{ CurrentContext: contextToUse, }).ClientConfig()