Select Git revision
recovering_middleware.go
extension.go 4.28 KiB
package extension
import (
"context"
"fmt"
"net/url"
"strings"
"git.perx.ru/perxis/perxis-go/pkg/content"
"git.perx.ru/perxis/perxis-go/pkg/errors"
"git.perx.ru/perxis/perxis-go/pkg/items"
pb "git.perx.ru/perxis/perxis-go/proto/extensions"
)
const (
RequestOK = pb.ExtensionRequestResult_OK
RequestError = pb.ExtensionRequestResult_ERROR
ExtensionsCollectionID = "space_extensions"
ExtensionsCollectionName = "Настройки/Расширения"
StatePending = pb.SpaceExtensions_PENDING
StateInstalled = pb.SpaceExtensions_INSTALLED
StateInProgress = pb.SpaceExtensions_IN_PROGRESS
StateFail = pb.SpaceExtensions_FAIL
ExtensionMetadataKey = "extension"
)
type (
InstallRequest = pb.InstallRequest
InstallResponse = pb.InstallResponse
CheckRequest = pb.CheckRequest
CheckResponse = pb.CheckResponse
UpdateRequest = pb.UpdateRequest
UpdateResponse = pb.UpdateResponse
UninstallRequest = pb.UninstallRequest
UninstallResponse = pb.UninstallResponse
RequestResult = pb.ExtensionRequestResult
ExtensionDescriptor = pb.ExtensionDescriptor
SpaceExtensionsState = pb.SpaceExtensions_State
)
var (
ErrStart = errors.New("start failed")
ErrStop = errors.New("stop failed")
ErrInstall = errors.New("install failed")
ErrUpdate = errors.New("update failed")
ErrCheck = errors.New("check failed")
ErrUninstall = errors.New("uninstall failed")
ErrUpdateAvailable = errors.New("update available")
ErrNotInstalled = errors.New("not installed")
ErrUnknownExtension = errors.New("unknown extension")
)
// Runnable описывает интерфейс сервиса с запуском и остановкой. Вызывается сервером расширений
type Runnable interface {
Start() error
Stop() error
}
// Extension описывает интерфейс расширения Perxis
type Extension interface {
// GetDescriptor возвращает описание расширения
GetDescriptor() *ExtensionDescriptor
// Install вызывается при установке расширения в пространство
Install(ctx context.Context, in *InstallRequest) error
// Check вызывается для проверки состояния расширения
Check(ctx context.Context, in *CheckRequest) error
// Update вызывается для обновления вресии расширения
Update(ctx context.Context, in *UpdateRequest) error
// Uninstall вызывается для удаления расширения из пространства
Uninstall(ctx context.Context, in *UninstallRequest) error
// Action вызывается для выполнения расширением действия
Action(ctx context.Context, in *ActionRequest) (*ActionResponse, error)
}
func CheckInstalled(ctx context.Context, content *content.Content, spaceID, envID, extension string) (bool, error) {
res, _, err := content.Items.Find(ctx, spaceID, envID, ExtensionsCollectionID,
&items.Filter{Q: []string{fmt.Sprintf("extension == '%s'", extension)}})
if err != nil {
return false, err
}
if len(res) == 0 || res[0].Data["extension_state"] != int64(StateInstalled) {
return false, nil
}
return true, nil
}
func ExtensionError(err error, ext string) error {
return errors.WithContext(err, "extension", ext)
}
func ExtensionFromError(err error) string {
v, _ := errors.ContextKey(err, "extension")
ext, _ := v.(string)
return ext
}
type ParsedActionURL struct {
actionID string
extensionID string
scheme string
}
func (p *ParsedActionURL) New() *ParsedActionURL {
return &ParsedActionURL{}
}
func (p *ParsedActionURL) GetActionID() string {
return p.actionID
}
func (p *ParsedActionURL) GetExtensionID() string {
return p.extensionID
}
func (p *ParsedActionURL) GetScheme() string {
return p.scheme
}
func (p *ParsedActionURL) Parse(action string) error {
u, err := url.Parse(action)
if err != nil {
return err
}
p.scheme = u.Scheme
if p.GetScheme() == "grpc" {
path := u.Path
if strings.HasPrefix(u.Path, "/") {
path = u.Path[1:]
}
splitPath := strings.Split(path, "/")
if len(splitPath) < 2 {
return errors.Errorf("incorrect action URL, no action id: '%s'", action)
}
p.extensionID = splitPath[0]
p.actionID = splitPath[1]
}
return nil
}