From b22d2df28caaa2a51baca9c00c2f93fe06a407cd Mon Sep 17 00:00:00 2001 From: Zexi Li Date: Tue, 11 Jul 2023 15:38:28 +0800 Subject: [PATCH] feat(climc): upload helm chart to a repository --- cmd/climc/shell/k8s/repos.go | 35 ++++++++++++++++++++++++++ pkg/mcclient/modules/k8s/helm.go | 43 ++++++++++++++++++++++++++++---- pkg/mcclient/options/k8s/repo.go | 30 ++++++++++++++++++---- 3 files changed, 98 insertions(+), 10 deletions(-) diff --git a/cmd/climc/shell/k8s/repos.go b/cmd/climc/shell/k8s/repos.go index f86e69b379..cc0c86bceb 100644 --- a/cmd/climc/shell/k8s/repos.go +++ b/cmd/climc/shell/k8s/repos.go @@ -15,6 +15,14 @@ package k8s import ( + "os" + "path/filepath" + + "github.com/cheggaaa/pb/v3" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/mcclient/modules/k8s" o "yunion.io/x/onecloud/pkg/mcclient/options/k8s" ) @@ -29,4 +37,31 @@ func initRepo() { cmd.Perform("sync", new(o.RepoGetOptions)) cmd.Perform("public", new(o.RepoPublicOptions)) cmd.Perform("private", new(o.RepoGetOptions)) + + type UploadOptions struct { + REPO string `help:"The name or id of helm repository` + FILE string `help:"Helm packaged file"` + } + R(new(UploadOptions), "k8s-repo-upload-chart", "Upload chart to the repository", func(s *mcclient.ClientSession, args *UploadOptions) error { + f, err := os.Open(args.FILE) + if err != nil { + return err + } + defer f.Close() + finfo, err := f.Stat() + if err != nil { + return err + } + size := finfo.Size() + bar := pb.Full.Start64(size) + barReader := bar.NewProxyReader(f) + param := jsonutils.Marshal(args) + param.(*jsonutils.JSONDict).Add(jsonutils.NewString(filepath.Base(args.FILE)), "chart_name") + ret, err := k8s.Repos.UploadChart(s, args.REPO, param, barReader, size) + if err != nil { + return err + } + printObject(ret) + return nil + }) } diff --git a/pkg/mcclient/modules/k8s/helm.go b/pkg/mcclient/modules/k8s/helm.go index 9c4076f63d..361ddbf93e 100644 --- a/pkg/mcclient/modules/k8s/helm.go +++ b/pkg/mcclient/modules/k8s/helm.go @@ -15,17 +15,50 @@ package k8s import ( + "fmt" + "io" + "net/http" + + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/util/httputils" + + "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/onecloud/pkg/mcclient/modulebase" "yunion.io/x/onecloud/pkg/mcclient/modules" ) var ( - Repos *ResourceManager + Repos *RepoManager ) func init() { - Repos = NewResourceManager("repo", "repos", - NewResourceCols("Url", "Is_Public", "Source", "Type"), - NewColumns(), - ) + Repos = NewRepoManager() modules.Register(Repos) } + +type RepoManager struct { + *ResourceManager +} + +func NewRepoManager() *RepoManager { + return &RepoManager{ + ResourceManager: NewResourceManager("repo", "repos", + NewResourceCols("Url", "Is_Public", "Source", "Type", "Backend"), + NewColumns()), + } +} + +func (m *RepoManager) UploadChart(s *mcclient.ClientSession, id string, params jsonutils.JSONObject, body io.Reader, size int64) (jsonutils.JSONObject, error) { + path := fmt.Sprintf("/%s/%s/upload-chart?%s", m.URLPath(), id, params.QueryString()) + headers := http.Header{} + headers.Add("Content-Type", "application/octet-stream") + if size > 0 { + headers.Add("Content-Length", fmt.Sprintf("%d", size)) + } + resp, err := modulebase.RawRequest(*m.ResourceManager.ResourceManager, s, httputils.POST, path, headers, body) + _, json, err := s.ParseJSONResponse("", resp, err) + if err != nil { + return nil, err + } + return json, nil +} diff --git a/pkg/mcclient/options/k8s/repo.go b/pkg/mcclient/options/k8s/repo.go index b4be8dfbba..0bddeb02dd 100644 --- a/pkg/mcclient/options/k8s/repo.go +++ b/pkg/mcclient/options/k8s/repo.go @@ -50,9 +50,12 @@ func (o *RepoGetOptions) Params() (jsonutils.JSONObject, error) { type RepoCreateOptions struct { RepoGetOptions - Type string `help:"Repository type" choices:"internal|external"` - URL string `help:"Repository url"` - Public bool `help:"Make repostitory public"` + Type string `help:"Repository type" choices:"internal|external"` + URL string `help:"Repository url"` + Public bool `help:"Make repostitory public"` + Backend string `help:"Repository backend" choices:"common|nexus"` + Username string `help:"Repository auth username"` + Password string `help:"Repository auth password"` } func (o RepoCreateOptions) Params() (jsonutils.JSONObject, error) { @@ -65,13 +68,24 @@ func (o RepoCreateOptions) Params() (jsonutils.JSONObject, error) { if o.Public { params.Add(jsonutils.JSONTrue, "is_public") } + if o.Backend != "" { + params.Add(jsonutils.NewString(o.Backend), "backend") + } + if o.Username != "" { + params.Add(jsonutils.NewString(o.Username), "username") + } + if o.Password != "" { + params.Add(jsonutils.NewString(o.Password), "password") + } return params, nil } type RepoUpdateOptions struct { RepoGetOptions - Name string `help:"Repository name to change"` - Url string `help:"Repository url to change"` + Name string `help:"Repository name to change"` + Url string `help:"Repository url to change"` + Username string `help:"Repository auth username"` + Password string `help:"Repository auth password"` } func (o RepoUpdateOptions) GetId() string { @@ -86,6 +100,12 @@ func (o RepoUpdateOptions) Params() (jsonutils.JSONObject, error) { if o.Url != "" { params.Add(jsonutils.NewString(o.Url), "url") } + if o.Username != "" { + params.Add(jsonutils.NewString(o.Username), "username") + } + if o.Password != "" { + params.Add(jsonutils.NewString(o.Password), "password") + } return params, nil }