From 5c6713f4cd2e77e38a68726fa69c77d9f58f7fd0 Mon Sep 17 00:00:00 2001 From: "Md. Emruz Hossain" Date: Wed, 11 Apr 2018 04:56:31 +0600 Subject: [PATCH] Show repository snapshot list (#417) * Implement Get,List,Delete method for snapshots * Added test for snapshots * Added doc for snapshot * Remove unused snapshot handler. --- forget.go | 55 +++++++++++++++++++++++++++ root.go | 2 + snapshot.go | 58 ++++++++++++++++++++++++++++ snapshot_handler.go | 92 --------------------------------------------- 4 files changed, 115 insertions(+), 92 deletions(-) create mode 100644 forget.go create mode 100644 snapshot.go delete mode 100644 snapshot_handler.go diff --git a/forget.go b/forget.go new file mode 100644 index 000000000..ec13c3224 --- /dev/null +++ b/forget.go @@ -0,0 +1,55 @@ +package cmds + +import ( + "fmt" + + "github.com/appscode/kutil/meta" + cs "github.com/appscode/stash/client/clientset/versioned/typed/stash/v1alpha1" + "github.com/appscode/stash/pkg/registry/snapshot" + "github.com/spf13/cobra" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/clientcmd" +) + +func NewCmdForget() *cobra.Command { + var ( + masterURL string + kubeconfigPath string + repositoryName string + ) + + cmd := &cobra.Command{ + Use: "forget [snapshotID ...]", + Short: "Delete snapshots from a restic repository", + DisableAutoGenTag: true, + Run: func(cmd *cobra.Command, args []string) { + config, err := clientcmd.BuildConfigFromFlags(masterURL, kubeconfigPath) + if err != nil { + fmt.Errorf(err.Error()) + } + + stashClient := cs.NewForConfigOrDie(config) + + if repositoryName == "" { + fmt.Errorf("repository name not found") + return + } + repo, err := stashClient.Repositories(meta.Namespace()).Get(repositoryName, metav1.GetOptions{}) + if err != nil { + fmt.Errorf(err.Error()) + return + } + + r := snapshot.NewREST(config) + err = r.ForgetSnapshots(repo, args) + if err != nil { + fmt.Errorf(err.Error()) + } + }, + } + cmd.Flags().StringVar(&masterURL, "master", masterURL, "The address of the Kubernetes API server (overrides any value in kubeconfig)") + cmd.Flags().StringVar(&kubeconfigPath, "kubeconfig", kubeconfigPath, "Path to kubeconfig file with authorization information (the master location is set by the master flag).") + cmd.Flags().StringVar(&repositoryName, "repo-name", repositoryName, "Name of the Repository CRD.") + + return cmd +} diff --git a/root.go b/root.go index e37c8a8df..298e8665c 100644 --- a/root.go +++ b/root.go @@ -58,6 +58,8 @@ func NewRootCmd() *cobra.Command { rootCmd.AddCommand(NewCmdRecover()) rootCmd.AddCommand(NewCmdCheck()) rootCmd.AddCommand(NewCmdScaleDown()) + rootCmd.AddCommand(NewCmdSnapshots()) + rootCmd.AddCommand(NewCmdForget()) return rootCmd } diff --git a/snapshot.go b/snapshot.go new file mode 100644 index 000000000..4e0652441 --- /dev/null +++ b/snapshot.go @@ -0,0 +1,58 @@ +package cmds + +import ( + "encoding/json" + "fmt" + + "github.com/appscode/kutil/meta" + cs "github.com/appscode/stash/client/clientset/versioned/typed/stash/v1alpha1" + "github.com/appscode/stash/pkg/registry/snapshot" + "github.com/spf13/cobra" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/clientcmd" +) + +func NewCmdSnapshots() *cobra.Command { + var ( + masterURL string + kubeconfigPath string + repositoryName string + ) + + cmd := &cobra.Command{ + Use: "snapshots [snapshotID ...]", + Short: "Get snapshots of restic repo", + DisableAutoGenTag: true, + Run: func(cmd *cobra.Command, args []string) { + config, err := clientcmd.BuildConfigFromFlags(masterURL, kubeconfigPath) + if err != nil { + fmt.Errorf(err.Error()) + } + + stashClient := cs.NewForConfigOrDie(config) + + if repositoryName == "" { + fmt.Errorf("repository name not found") + return + } + repo, err := stashClient.Repositories(meta.Namespace()).Get(repositoryName, metav1.GetOptions{}) + if err != nil { + fmt.Errorf(err.Error()) + return + } + + r := snapshot.NewREST(config) + snapshots, err := r.GetSnapshots(repo, args) + if err != nil { + fmt.Errorf(err.Error()) + } + jsonSnaps, err := json.MarshalIndent(snapshots, "", " ") + fmt.Println(string(jsonSnaps)) + }, + } + cmd.Flags().StringVar(&masterURL, "master", masterURL, "The address of the Kubernetes API server (overrides any value in kubeconfig)") + cmd.Flags().StringVar(&kubeconfigPath, "kubeconfig", kubeconfigPath, "Path to kubeconfig file with authorization information (the master location is set by the master flag).") + cmd.Flags().StringVar(&repositoryName, "repo-name", repositoryName, "Name of the Repository CRD.") + + return cmd +} diff --git a/snapshot_handler.go b/snapshot_handler.go deleted file mode 100644 index 11e011f79..000000000 --- a/snapshot_handler.go +++ /dev/null @@ -1,92 +0,0 @@ -package cmds - -import ( - "encoding/json" - "net/http" - _ "net/http/pprof" - - "github.com/appscode/pat" - api "github.com/appscode/stash/apis/stash/v1alpha1" - cs "github.com/appscode/stash/client/clientset/versioned/typed/stash/v1alpha1" - "github.com/appscode/stash/pkg/cli" - core "k8s.io/api/core/v1" - kerr "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" -) - -const ( - PathParamNamespace = ":namespace" - PathParamName = ":name" - QueryParamAutoPrefix = "autoPrefix" -) - -type PrometheusExporter struct { - kubeClient kubernetes.Interface - stashClient cs.StashV1alpha1Interface - scratchDir string -} - -var _ http.Handler = &PrometheusExporter{} - -func (e PrometheusExporter) ServeHTTP(w http.ResponseWriter, r *http.Request) { - params, found := pat.FromContext(r.Context()) - if !found { - http.Error(w, "Missing parameters", http.StatusBadRequest) - return - } - namespace := params.Get(PathParamNamespace) - if namespace == "" { - http.Error(w, "Missing parameter:"+PathParamNamespace, http.StatusBadRequest) - return - } - name := params.Get(PathParamName) - if name == "" { - http.Error(w, "Missing parameter:"+PathParamName, http.StatusBadRequest) - return - } - resticCLI := cli.New(e.scratchDir, true, "") - - var resource *api.Restic - resource, err := e.stashClient.Restics(namespace).Get(name, metav1.GetOptions{}) - if kerr.IsNotFound(err) { - http.Error(w, err.Error(), http.StatusNotFound) - return - } else if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - if resource.Spec.Backend.StorageSecretName == "" { - http.Error(w, "Missing repository secret name", http.StatusBadRequest) - return - } - var secret *core.Secret - secret, err = e.kubeClient.CoreV1().Secrets(resource.Namespace).Get(resource.Spec.Backend.StorageSecretName, metav1.GetOptions{}) - if kerr.IsNotFound(err) { - http.Error(w, err.Error(), http.StatusNotFound) - return - } else if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - _, err = resticCLI.SetupEnv(resource.Spec.Backend, secret, r.URL.Query().Get(QueryParamAutoPrefix)) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - snapshots, err := resticCLI.ListSnapshots() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - js, err := json.Marshal(snapshots) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.Header().Set("Content-Type", "application/json") - w.Write(js) -}