From bade23cecfb9c7d1e552cba3eca1277a4ce2759c Mon Sep 17 00:00:00 2001 From: qiaozp <47812250+chivalryq@users.noreply.github.com> Date: Thu, 18 Nov 2021 12:24:01 +0800 Subject: [PATCH] Feat: add addon arguments API (#2732) * temp * test * move to status --- pkg/addon/addon.go | 19 +++++++++++ pkg/apiserver/rest/apis/v1/types.go | 7 +++- pkg/apiserver/rest/usecase/addon.go | 44 +++++++++++++++++++------ pkg/apiserver/rest/utils/bcode/addon.go | 9 +++++ pkg/apiserver/rest/webservice/addon.go | 2 +- 5 files changed, 69 insertions(+), 12 deletions(-) diff --git a/pkg/addon/addon.go b/pkg/addon/addon.go index 8940fd801..d8e7935b4 100644 --- a/pkg/addon/addon.go +++ b/pkg/addon/addon.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + v1 "k8s.io/api/core/v1" "net/url" "path" "path/filepath" @@ -438,6 +439,7 @@ func renderCUETemplate(elem types.AddonElementFile, parameters string, args map[ } const addonAppPrefix = "addon-" +const addonSecPrefix = "addon-secret-" // Convert2AppName - func Convert2AppName(name string) string { @@ -448,3 +450,20 @@ func Convert2AppName(name string) string { func Convert2AddonName(name string) string { return strings.TrimPrefix(name, addonAppPrefix) } + +func RenderArgsSecret(addon *types.Addon, args map[string]string) *v1.Secret { + sec := v1.Secret{ + TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Secret"}, + ObjectMeta: metav1.ObjectMeta{ + Name: Convert2SecName(addon.Name), + Namespace: types.DefaultKubeVelaNS, + }, + StringData: args, + Type: v1.SecretTypeOpaque, + } + return &sec +} + +func Convert2SecName(name string) string { + return addonSecPrefix + name +} diff --git a/pkg/apiserver/rest/apis/v1/types.go b/pkg/apiserver/rest/apis/v1/types.go index 6ac439710..e52a7743e 100644 --- a/pkg/apiserver/rest/apis/v1/types.go +++ b/pkg/apiserver/rest/apis/v1/types.go @@ -102,7 +102,8 @@ type DetailAddonResponse struct { // AddonStatusResponse defines the format of addon status response type AddonStatusResponse struct { - Phase AddonPhase `json:"phase"` + Phase AddonPhase `json:"phase"` + Args map[string]string `json:"args"` EnablingProgress *EnablingProgress `json:"enabling_progress,omitempty"` } @@ -113,6 +114,10 @@ type EnablingProgress struct { TotalComponents int `json:"total_components"` } +type AddonArgsResponse struct { + Args map[string]string `json:"args"` +} + // AccessKeyRequest request parameters to access cloud provider type AccessKeyRequest struct { AccessKeyID string `json:"accessKeyID"` diff --git a/pkg/apiserver/rest/usecase/addon.go b/pkg/apiserver/rest/usecase/addon.go index 7ca09dc36..154f83856 100644 --- a/pkg/apiserver/rest/usecase/addon.go +++ b/pkg/apiserver/rest/usecase/addon.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + v1 "k8s.io/api/core/v1" "sort" "strings" "time" @@ -34,7 +35,7 @@ type AddonUsecase interface { UpdateAddonRegistry(ctx context.Context, name string, req apis.UpdateAddonRegistryRequest) (*apis.AddonRegistryMeta, error) ListAddonRegistries(ctx context.Context) ([]*apis.AddonRegistryMeta, error) ListAddons(ctx context.Context, detailed bool, registry, query string) ([]*apis.DetailAddonResponse, error) - StatusAddon(name string) (*apis.AddonStatusResponse, error) + StatusAddon(ctx context.Context,name string) (*apis.AddonStatusResponse, error) GetAddon(ctx context.Context, name string, registry string) (*apis.DetailAddonResponse, error) EnableAddon(ctx context.Context, name string, args apis.EnableAddonRequest) error DisableAddon(ctx context.Context, name string) error @@ -96,7 +97,7 @@ func (u *addonUsecaseImpl) GetAddon(ctx context.Context, name string, registry s return nil, bcode.ErrAddonNotExist } -func (u *addonUsecaseImpl) StatusAddon(name string) (*apis.AddonStatusResponse, error) { +func (u *addonUsecaseImpl) StatusAddon(ctx context.Context, name string) (*apis.AddonStatusResponse, error) { var app v1beta1.Application err := u.kubeClient.Get(context.Background(), client.ObjectKey{ Namespace: types.DefaultKubeVelaNS, @@ -113,11 +114,24 @@ func (u *addonUsecaseImpl) StatusAddon(name string) (*apis.AddonStatusResponse, } switch app.Status.Phase { - case common2.ApplicationRunning, common2.ApplicationWorkflowFinished: - return &apis.AddonStatusResponse{ + case common2.ApplicationRunning: + res := apis.AddonStatusResponse{ Phase: apis.AddonPhaseEnabled, EnablingProgress: nil, - }, nil + } + var sec v1.Secret + err := u.kubeClient.Get(ctx, client.ObjectKey{ + Namespace: types.DefaultKubeVelaNS, + Name: pkgaddon.Convert2SecName(name), + }, &sec) + if err != nil { + return nil, bcode.ErrAddonSecretGet + } + res.Args = make(map[string]string, len(sec.Data)) + for k, v := range sec.Data { + res.Args[k] = string(v) + } + return &res, nil default: return &apis.AddonStatusResponse{ Phase: apis.AddonPhaseEnabling, @@ -272,18 +286,28 @@ func (u *addonUsecaseImpl) EnableAddon(ctx context.Context, name string, args ap return bcode.WrapGithubRateLimitErr(err) } - // render default ui schema - addon.UISchema = renderDefaultUISchema(addon.APISchema) - app, err := pkgaddon.RenderApplication(addon, args.Args) if err != nil { - return err + return bcode.ErrAddonRender } + + err = u.kubeClient.Get(ctx, client.ObjectKey{Namespace: app.GetNamespace(), Name: app.GetName()}, app) + if err == nil { + return bcode.ErrAddonIsEnabled + } + err = u.kubeClient.Create(ctx, app) if err != nil { - log.Logger.Errorf("apply application fail: %s", err.Error()) + log.Logger.Errorf("create application fail: %s", err.Error()) return bcode.ErrAddonApply } + + sec := pkgaddon.RenderArgsSecret(addon, args.Args) + err = u.apply.Apply(ctx, sec) + if err != nil { + return bcode.ErrAddonSecretApply + } + return nil } return bcode.ErrAddonNotExist diff --git a/pkg/apiserver/rest/utils/bcode/addon.go b/pkg/apiserver/rest/utils/bcode/addon.go index e57f23abe..2e7566a10 100644 --- a/pkg/apiserver/rest/utils/bcode/addon.go +++ b/pkg/apiserver/rest/utils/bcode/addon.go @@ -49,6 +49,15 @@ var ( // ErrGetAddonApplication fail to get addon application ErrGetAddonApplication = NewBcode(500, 50013, "fail to get addon application") + + // ErrAddonIsEnabled means addon has been enabled + ErrAddonIsEnabled = NewBcode(500, 50014, "addon has been enabled") + + // ErrAddonSecretApply means fail to apply addon argument secret + ErrAddonSecretApply = NewBcode(500, 50015, "fail to apply addon argument secret") + + // ErrAddonSecretGet means fail to get addon argument secret + ErrAddonSecretGet = NewBcode(500, 50016, "fail to get addon argument secret") ) // isGithubRateLimit check if error is github rate limit diff --git a/pkg/apiserver/rest/webservice/addon.go b/pkg/apiserver/rest/webservice/addon.go index 6b15f77da..e41dfda32 100644 --- a/pkg/apiserver/rest/webservice/addon.go +++ b/pkg/apiserver/rest/webservice/addon.go @@ -168,7 +168,7 @@ func (s *addonWebService) disableAddon(req *restful.Request, res *restful.Respon func (s *addonWebService) statusAddon(req *restful.Request, res *restful.Response) { name := req.PathParameter("name") - status, err := s.addonUsecase.StatusAddon(name) + status, err := s.addonUsecase.StatusAddon(req.Request.Context(), name) if err != nil { bcode.ReturnError(req, res, err) return