package service import ( "context" "fmt" "git.perx.ru/perxis/perxis-go/pkg/actionurl" "git.perx.ru/perxis/perxis-go/pkg/clients" "git.perx.ru/perxis/perxis-go/pkg/content" "git.perx.ru/perxis/perxis-go/pkg/errors" "git.perx.ru/perxis/perxis-go/pkg/extension" "git.perx.ru/perxis/perxis-go/pkg/roles" "git.perx.ru/perxis/perxis-go/pkg/setup" "go.uber.org/zap" ) const ( roleID = "%s_extension" roleDesc = "Роль расширения \"%s\"" clientID = "%s_extension" clientName = "Клиент расширения \"%s\"" clientDesc = "Клиент используется при работе расширения \"%s\"" ) type SetupFunc func(spaceID, envID string) *setup.Setup type SignatureFunc func(spaceID string) string // Extension реализация сервиса с одним расширением type Extension struct { desc *extension.ExtensionDescriptor setupFunc SetupFunc Content *content.Content Logger *zap.Logger manager extension.Manager withClient bool role *roles.Role client *clients.Client keyFn extension.KeyFunc } func NewExtension(desc *extension.ExtensionDescriptor, cnt *content.Content, setupFunc SetupFunc, logger *zap.Logger) *Extension { if logger == nil { logger = zap.NewNop() } return &Extension{ desc: desc, setupFunc: setupFunc, Content: cnt, Logger: logger, } } func (s *Extension) GetDescriptor() *extension.ExtensionDescriptor { return s.desc } func (s *Extension) GetName() string { return s.desc.Extension } // WithClient добавляет в процесс установки расширения создание роли и приложения для работы расширения func (s *Extension) WithClient(role *roles.Role, client *clients.Client, fn extension.KeyFunc) *Extension { s.withClient = true s.keyFn = fn s.role = role s.client = client return s } // GetKey Получить ключ для доступа к пространству func (s *Extension) GetKey(spaceID string) string { if s == nil || s.keyFn == nil { return "" } return s.keyFn(spaceID) } // setupExtensionClient добавляет роль и клиента для авторизации расширения func (s *Extension) setupExtensionClient(set *setup.Setup, spaceID string) { if !s.withClient { return } if s.role == nil { s.role = &roles.Role{} } if s.role.ID == "" { s.role.ID = fmt.Sprintf(roleID, s.desc.Extension) } if s.role.Description == "" { s.role.Description = fmt.Sprintf(roleDesc, s.desc.Title) } role := *s.role role.SpaceID = spaceID set.AddRole(&role, setup.DeleteRoleIfRemove()) if s.client == nil { s.client = &clients.Client{} } if s.client.ID == "" { s.client.ID = fmt.Sprintf(clientID, s.desc.Extension) } if s.client.RoleID == "" { s.client.RoleID = s.role.ID } if s.client.Name == "" { s.client.Name = fmt.Sprintf(clientName, s.desc.Title) } if s.client.Description == "" { s.client.Description = fmt.Sprintf(clientDesc, s.desc.Description) } if s.client.OAuth == nil { s.client.OAuth = &clients.OAuth{ ClientID: fmt.Sprintf(clientID, s.desc.Extension), } } client := *s.client client.SpaceID = spaceID if client.APIKey == nil { client.APIKey = &clients.APIKey{ Key: s.GetKey(spaceID), } } set.AddClient(&client, setup.OverwriteClient(), setup.DeleteClientIfRemove()) } func (s *Extension) GetSetup(spaceID, envID string) *setup.Setup { set := s.setupFunc(spaceID, envID) s.setupExtensionClient(set, spaceID) return set } func (s *Extension) Install(ctx context.Context, in *extension.InstallRequest) error { return s.GetSetup(in.SpaceId, in.EnvId).WithForce(in.Force).Install(ctx) } func (s *Extension) Check(ctx context.Context, in *extension.CheckRequest) error { return s.GetSetup(in.SpaceId, in.EnvId).Check(ctx) } func (s *Extension) Update(ctx context.Context, in *extension.UpdateRequest) error { return s.GetSetup(in.SpaceId, in.EnvId).WithForce(in.Force).Install(ctx) } func (s *Extension) Uninstall(ctx context.Context, in *extension.UninstallRequest) error { return s.GetSetup(in.SpaceId, in.EnvId).WithForce(in.Force).WithRemove(in.Remove).Uninstall(ctx) } func (s *Extension) Action(ctx context.Context, in *extension.ActionRequest) (*extension.ActionResponse, error) { ext := in.Extension if ext == "" { actionURL, err := actionurl.New(in.Action) if err != nil { return nil, err } ext = actionURL.Extension() } ok, err := extension.CheckInstalled(ctx, s.Content, in.SpaceId, in.EnvId, ext) if err != nil { return nil, errors.Wrap(err, "check extension installed") } if !ok { return nil, errors.New("extension not installed") } return &extension.ActionResponse{}, nil }