Select Git revision
setup.go 6.33 KiB
package setup
import (
"context"
"time"
"git.perx.ru/perxis/perxis-go/pkg/clients"
"git.perx.ru/perxis/perxis-go/pkg/collections"
"git.perx.ru/perxis/perxis-go/pkg/content"
"git.perx.ru/perxis/perxis-go/pkg/errors"
"git.perx.ru/perxis/perxis-go/pkg/items"
"git.perx.ru/perxis/perxis-go/pkg/roles"
"git.perx.ru/perxis/perxis-go/pkg/spaces"
"go.uber.org/zap"
)
var (
ErrInvalidSetupConfig = errors.New("invalid setup config")
)
// Setup реализует процесс настройки пространства. Указав необходимые требования к конфигурации пространства можно
// выполнить процесс установки, проверки и удаления требований.
type Setup struct {
SpaceID string
EnvironmentID string
Roles []RoleConfig
Clients []ClientConfig
Collections []CollectionConfig
Items []ItemConfig
content *content.Content
force bool
remove bool
waitForSpace bool
attempts uint
delay time.Duration
errors []error
logger *zap.Logger
}
func NewSetup(content *content.Content, spaceID, environmentID string, logger *zap.Logger) *Setup {
if logger == nil {
logger = zap.NewNop()
}
logger = logger.With(zap.String("Space", spaceID), zap.String("Environment", environmentID))
return &Setup{
SpaceID: spaceID,
EnvironmentID: environmentID,
content: content,
logger: logger,
}
}
func (s *Setup) WithForce(force bool) *Setup {
setup := *s
setup.force = force
return &setup
}
func (s *Setup) IsForce() bool {
return s.force
}
func (s *Setup) WithRemove(remove bool) *Setup {
setup := *s
setup.remove = remove
return &setup
}
func (s *Setup) IsRemove() bool {
return s.remove
}
func (s *Setup) WithWaitForSpace(wait bool) *Setup {
setup := *s
setup.waitForSpace = wait
if setup.attempts == 0 {
setup.attempts = 60000
}
if setup.delay.Milliseconds() == 0 {
setup.delay = 100 * time.Millisecond
}
return &setup
}
func (s *Setup) WaitForSpace() bool {
return s.waitForSpace
}
func (s *Setup) SetAttempts(attempts uint) *Setup {
setup := *s
setup.attempts = attempts
return &setup
}
func (s *Setup) SetDelay(delay time.Duration) *Setup {
setup := *s
setup.delay = delay
return &setup
}
func (s *Setup) HasErrors() bool {
return len(s.errors) > 0
}
func (s *Setup) AddError(err error) {
s.errors = append(s.errors, err)
}
func (s *Setup) Errors() []error {
return s.errors
}
func (s *Setup) Error() error {
return errors.WithErrors(ErrInvalidSetupConfig, s.errors...)
}
// AddRoles добавляет требования к настройке ролей в пространстве
func (s *Setup) AddRoles(roles []*roles.Role, opt ...RolesOption) *Setup {
for _, role := range roles {
s.AddRole(role, opt...)
}
return s
}
func (s *Setup) AddRole(role *roles.Role, opt ...RolesOption) *Setup {
s.Roles = append(s.Roles, NewRoleConfig(role, opt...))
return s
}
// AddClients добавляет требования к настройке приложений в пространстве
func (s *Setup) AddClients(clients []*clients.Client, opt ...ClientsOption) *Setup {
for _, client := range clients {
s.AddClient(client, opt...)
}
return s
}
func (s *Setup) AddClient(client *clients.Client, opt ...ClientsOption) *Setup {
s.Clients = append(s.Clients, NewClientConfig(client, opt...))
return s
}
// AddCollections добавляет требования к настройке коллекций в пространстве
func (s *Setup) AddCollections(collections []*collections.Collection, opt ...CollectionsOption) *Setup {
for _, col := range collections {
s.AddCollection(col, opt...)
}
return s
}
func (s *Setup) AddCollection(collection *collections.Collection, opt ...CollectionsOption) *Setup {
config, err := NewCollectionConfig(collection, opt...)
if err != nil {
s.AddError(err)
return s
}
s.Collections = append(s.Collections, config)
return s
}
// AddItems добавляет требования к настройке элементов в пространстве
func (s *Setup) AddItems(items []*items.Item, opt ...ItemsOption) *Setup {
for _, item := range items {
s.AddItem(item, opt...)
}
return s
}
func (s *Setup) AddItem(item *items.Item, opt ...ItemsOption) *Setup {
s.Items = append(s.Items, NewItemConfig(item, opt...))
return s
}
// Install выполняет установку необходимых требований
func (s *Setup) Install(ctx context.Context) error {
var err error
if s.waitForSpace {
err = spaces.CheckIsSpaceAvailableWithRetry(ctx, s.content.Spaces, s.SpaceID, s.delay, s.attempts, s.logger)
}
if err == nil {
if err := s.InstallRoles(ctx); err != nil {
return err
}
if err := s.InstallClients(ctx); err != nil {
return err
}
if err := s.InstallCollections(ctx); err != nil {
return err
}
if err := s.InstallItems(ctx); err != nil {
return err
}
}
return err
}
// Check выполняет проверку требований
func (s *Setup) Check(ctx context.Context) error {
var err error
if s.waitForSpace {
err = spaces.CheckIsReadAvailableWithRetry(ctx, s.content.Spaces, s.SpaceID, s.delay, s.attempts, s.logger)
}
if err == nil {
if err := s.CheckRoles(ctx); err != nil {
return err
}
if err := s.CheckClients(ctx); err != nil {
return err
}
if err := s.CheckCollections(ctx); err != nil {
return err
}
if err := s.CheckItems(ctx); err != nil {
return err
}
return nil
}
return err
}
// Uninstall выполняет удаление установленных раннее требований
func (s *Setup) Uninstall(ctx context.Context) error {
var err error
if s.waitForSpace {
err = spaces.CheckIsSpaceAvailableWithRetry(ctx, s.content.Spaces, s.SpaceID, s.delay, s.attempts, s.logger)
}
if err == nil {
// В случае если необходимо удалить данные удаляем все что создано при установке расширения
if err := s.UninstallClients(ctx); err != nil {
return err
}
if err := s.UninstallRoles(ctx); err != nil {
return err
}
if err := s.UninstallCollections(ctx); err != nil {
return err
}
if err := s.UninstallItems(ctx); err != nil {
return err
}
s.logger.Info("Uninstall finished", zap.String(s.SpaceID, "spaceID"))
return nil
}
return err
}