Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
P
perxis-go
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Package registry
Operate
Terraform modules
Analyze
Contributor analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
perxis
perxis-go
Commits
9572a290
Commit
9572a290
authored
1 year ago
by
Alena Petraki
Browse files
Options
Downloads
Patches
Plain Diff
Изменен тип Resource struct -> interface
parent
1b8d6062
Branches
feature/PRXS-1257-1914-ResourceManager
No related tags found
No related merge requests found
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
resources/provider.go
+35
-16
35 additions, 16 deletions
resources/provider.go
resources/resource.go
+25
-18
25 additions, 18 deletions
resources/resource.go
resources/service.go
+17
-27
17 additions, 27 deletions
resources/service.go
resources/space_resources.go
+210
-0
210 additions, 0 deletions
resources/space_resources.go
with
287 additions
and
61 deletions
resources/provider.go
+
35
−
16
View file @
9572a290
...
...
@@ -6,8 +6,8 @@ import (
"git.perx.ru/perxis/perxis-go/pkg/spaces"
)
//
type ProviderType string
//
type
ProviderType
string
// const (
// ProviderTypeStandalone ProviderType = "standalone"
// ProviderTypeYandexCloud = "yandex_cloud"
...
...
@@ -15,9 +15,11 @@ import (
type
Kind
string
func
(
k
Kind
)
String
()
string
{
return
string
(
k
)
}
const
(
KindDatabase
Kind
=
"database"
KindObjectStorage
=
"object_storage"
KindObjectStorage
Kind
=
"object_storage"
)
type
ProviderDescription
struct
{
...
...
@@ -38,30 +40,47 @@ func (d *ProviderDescription) SetName(s string) { d.Name = s }
// Provider() (Provider, error)
// }
// Provider отвечает за взаимодействие с провайдером и знает про внутреннее устройство
// ресурсов типа ProviderType:
// - в зависимости от того, имплементирует ли провайдер DatabaseProvider или ObjectStorageProvider,
// отвечает за взаимодействие с провайдером для создания/удаления БД/облачного хранилища
// - является кэшэм для соединений с ресурсами, чтобы соединения могли переиспользоваться для разных ресурсов
// - Знает внутреннее строение ресурсов и может валидировать конфигурацию ресурса
type
Provider
interface
{
GetID
()
string
SetID
(
)
string
SetID
(
s
string
)
GetName
()
string
SetName
(
s
string
)
Kind
()
[]
Kind
//
Type() ProviderType
Type
()
ProviderType
// GetDefaultResource - получить ресурс запрашиваемого типа, готовый к аллокации
// todo: параметр пространства выглядит не к месту, передается для установки
// названия БД. Убрать передачу пространства и генерировать для БД просто ID? Чем грозит?
GetDefaultResource
(
ctx
context
.
Context
,
space
*
spaces
.
Space
,
kind
Kind
)
(
Resource
,
error
)
UpdateResource
(
ctx
context
.
Context
,
space
*
spaces
.
Space
,
params
Resource
)
error
GetConnectedResource
(
ctx
context
.
Context
,
resource
*
Resource
)
(
any
,
error
)
AllocateResource
(
ctx
context
.
Context
,
resource
Resource
)
error
DeallocateResource
(
ctx
context
.
Context
,
resource
Resource
)
error
Close
(
ctx
context
.
Context
)
}
// GetConnectedResource - получить готовый к взаимодействию ресурс. В случае,
// если для ресурса доступна lazy-аллокация, ресурс будет сначала аллоцирован
GetConnectedResource
(
ctx
context
.
Context
,
resource
Resource
)
(
*
ConnectedResource
,
error
)
type
DatabaseProvider
interface
{
CreateDatabase
(
ctx
context
.
Context
,
resource
Resource
)
error
DropDatabase
(
ctx
context
.
Context
,
resource
Resource
)
error
Close
(
ctx
context
.
Context
)
}
type
ObjectStorageProvider
interface
{
CreateObjectStorage
(
ctx
context
.
Context
,
resource
Resource
)
error
DropObjectStorage
(
ctx
context
.
Context
,
resource
Resource
)
error
}
// // DatabaseProvider интерфейс, который должен имплементировать провайдер, если
// // он может управлять БД.
// type DatabaseProvider interface {
// CreateDatabase(ctx context.Context, resource Resource) error
// DropDatabase(ctx context.Context, resource Resource) error
// }
//
// // ObjectStorageProvider интерфейс, который должен имплементировать провайдер, если
// // он может управлять хранилищами объектов.
// type ObjectStorageProvider interface {
// CreateObjectStorage(ctx context.Context, resource Resource) error
// DropObjectStorage(ctx context.Context, resource Resource) error
// }
This diff is collapsed.
Click to expand it.
resources/resource.go
+
25
−
18
View file @
9572a290
...
...
@@ -43,13 +43,16 @@ type Resource interface {
GetName
()
string
SetName
(
s
string
)
GetProviderID
()
GetProviderID
()
string
// SetProviderID(s string)
GetStateInfo
()
StateInfo
SetStateInfo
(
s
StateInfo
)
Kind
()
Kind
Type
()
ResourceType
Validate
()
error
}
type
StateInfo
struct
{
...
...
@@ -58,6 +61,8 @@ type StateInfo struct {
Message
string
}
// ResourceDescription имплементирует часть методов интерфейса Resource и может
// использоваться для встраивания в имплементации ресурсов
type
ResourceDescription
struct
{
ID
string
`json:"id,omitempty"`
Name
string
`json:"name,omitempty"`
...
...
@@ -70,24 +75,26 @@ func (d *ResourceDescription) SetID(s string) { d.ID = s }
func
(
d
*
ResourceDescription
)
GetName
()
string
{
return
d
.
Name
}
func
(
d
*
ResourceDescription
)
SetName
(
s
string
)
{
d
.
Name
=
s
}
func
(
d
*
ResourceDescription
)
GetProviderID
()
string
{
return
d
.
ProviderID
}
func
(
d
*
ResourceDescription
)
SetProviderID
(
s
string
)
{
d
.
ProviderID
=
s
}
// func (d *ResourceDescription) SetProviderID(s string) { d.ProviderID = s }
func
(
d
*
ResourceDescription
)
GetStateInfo
()
StateInfo
{
return
d
.
Info
}
func
(
d
*
ResourceDescription
)
SetStateInfo
(
s
StateInfo
)
{
d
.
Info
=
s
}
type
Resources
struct
{
// ConnectedResource содержит в себе готовый к взаимодействию ресурс, причем один. Остальные поля nil
type
ConnectedResource
struct
{
*
MongoResource
// FSResource
// S3Resource
}
func
NewResources
(
rr
...
any
)
*
Resource
s
{
res
:=
new
(
Resource
s
)
for
_
,
r
:=
range
rr
{
switch
v
:=
r
.
(
type
)
{
case
*
MongoResource
:
res
.
MongoResource
=
v
}
}
return
res
}
//
func NewResources(rr ...any) *
Connected
Resource {
//
res := new(
Connected
Resource)
//
for _, r := range rr {
//
switch v := r.(type) {
//
case *MongoResource:
//
res.MongoResource = v
//
}
//
}
//
return res
//
}
This diff is collapsed.
Click to expand it.
resources/service.go
+
17
−
27
View file @
9572a290
...
...
@@ -2,33 +2,23 @@ package resources
import
"context"
// Service -
// TODO:
// - опционально аллоцировать ресурс при создании/lazy-аллокация (может решаться внутри имплементации провайдера)
// - при обновлении ресурса если изменилась конфигурация и ресурс
// был аллоцирован с ошибкой, пытаться аллоцировать снова - ???
type
Service
interface
{
// // AllocateSpaceResources - инициализировать ресурсы для пространства. Аллокация происходит
// // в синхронном режиме и может занимать значительное время
// AllocateSpaceResources(ctx context.Context, spaceID string) error
//
// // DeallocateSpaceResources - полностью удалить ресурсы для пространства. Деаллокация происходит
// // в синхронном режиме и может занимать значительное время
// DeallocateSpaceResources(ctx context.Context, spaceID string) error
//
// // GetSpaceResources - получить инициализированные и готовые к работе ресурсы пространства
// GetSpaceResources(ctx context.Context, spaceID string) (*Resources, error)
CreateProvider
(
ctx
context
.
Context
,
provider
*
Provider
)
(
*
Provider
,
error
)
UpdateProvider
(
ctx
context
.
Context
,
provider
*
Provider
)
error
GetProvider
(
ctx
context
.
Context
,
providerID
string
)
(
*
Provider
,
error
)
FindProviders
(
ctx
context
.
Context
,
filter
*
Filter
)
([]
*
Provider
,
error
)
CreateProvider
(
ctx
context
.
Context
,
provider
Provider
)
(
Provider
,
error
)
UpdateProvider
(
ctx
context
.
Context
,
provider
Provider
)
error
GetProvider
(
ctx
context
.
Context
,
providerID
string
)
(
Provider
,
error
)
FindProviders
(
ctx
context
.
Context
,
filter
*
Filter
)
([]
Provider
,
error
)
DeleteProvider
(
ctx
context
.
Context
,
providerID
string
)
error
CreateResource
(
ctx
context
.
Context
,
resource
*
Resource
)
(
*
Resource
,
error
)
UpdateResource
(
ctx
context
.
Context
,
resource
*
Resource
)
error
GetResource
(
ctx
context
.
Context
,
resourceID
string
)
(
*
Resource
,
error
)
FindResources
(
ctx
context
.
Context
,
filter
*
Filter
)
([]
*
Resource
,
error
)
CreateResource
(
ctx
context
.
Context
,
resource
Resource
)
(
Resource
,
error
)
UpdateResource
(
ctx
context
.
Context
,
resource
Resource
)
error
GetResource
(
ctx
context
.
Context
,
resourceID
string
)
(
Resource
,
error
)
FindResources
(
ctx
context
.
Context
,
filter
*
Filter
)
([]
Resource
,
error
)
DeleteResource
(
ctx
context
.
Context
,
resourceID
string
)
error
AllocateResource
(
ctx
context
.
Context
,
resourceID
string
)
error
DeallocateResource
(
ctx
context
.
Context
,
resourceID
string
)
error
}
type
Storage
interface
{
...
...
@@ -38,10 +28,10 @@ type Storage interface {
FindProviders
(
ctx
context
.
Context
,
filter
*
Filter
)
([]
Provider
,
error
)
DeleteProvider
(
ctx
context
.
Context
,
providerID
string
)
error
CreateResource
(
ctx
context
.
Context
,
resource
*
Resource
)
error
UpdateResource
(
ctx
context
.
Context
,
resource
*
Resource
)
error
GetResource
(
ctx
context
.
Context
,
resourceID
string
)
(
*
Resource
,
error
)
FindResources
(
ctx
context
.
Context
,
filter
*
Filter
)
([]
*
Resource
,
error
)
CreateResource
(
ctx
context
.
Context
,
resource
Resource
)
error
UpdateResource
(
ctx
context
.
Context
,
resource
Resource
)
error
GetResource
(
ctx
context
.
Context
,
resourceID
string
)
(
Resource
,
error
)
FindResources
(
ctx
context
.
Context
,
filter
*
Filter
)
([]
Resource
,
error
)
DeleteResource
(
ctx
context
.
Context
,
resourceID
string
)
error
}
...
...
This diff is collapsed.
Click to expand it.
resources/space_resources.go
0 → 100644
+
210
−
0
View file @
9572a290
package
resources
import
(
"context"
"fmt"
"sync"
"git.perx.ru/perxis/perxis-go/pkg/data"
"git.perx.ru/perxis/perxis-go/pkg/organizations"
"git.perx.ru/perxis/perxis-go/pkg/spaces"
"github.com/pkg/errors"
)
// SpaceResources используется для управления ресурсами пространств и системными.
type
SpaceResources
struct
{
// ресурсы и провайдеры, которые будут создаваться при старте сервиса
defaultResources
[]
Resource
defaultProviders
[]
Provider
resources
Service
spaces
spaces
.
Spaces
orgs
organizations
.
Organizations
// TODO: разобраться, где будет кэш
resourcesCache
sync
.
Map
providersCache
sync
.
Map
}
func
NewSpaceResources
(
svc
Service
,
spaces
spaces
.
Spaces
,
orgs
organizations
.
Organizations
,
defaultResources
[]
Resource
,
defaultProviders
[]
Provider
,
)
*
SpaceResources
{
return
&
SpaceResources
{
defaultResources
:
defaultResources
,
defaultProviders
:
defaultProviders
,
resources
:
svc
,
spaces
:
spaces
,
orgs
:
orgs
,
resourcesCache
:
sync
.
Map
{},
providersCache
:
sync
.
Map
{},
}
}
// Start создать системные провайдеры и ресурсы, доступные для всех организаций по умолчанию
func
(
m
*
SpaceResources
)
Start
()
{
panic
(
"implement me"
)
}
// Stop - закрыть соединения?
func
(
m
*
SpaceResources
)
Stop
()
{
panic
(
"implement me"
)
}
// Allocate - инициализировать ресурсы для пространства.
// Если для пространства не задан идентификатор ресурса, то ресурс будет создан
// по следующему алгоритму:
// - взять список провайдеров, заданных как основные в организации
// - поскольку список провайдеров упорядочен по приоритету, найти первый
// провайдер подходящего типа (KindDatabase/KindObjectStorage)
// - у выбранного провайдера запросить конфигурацию ресурса по умолчанию
//
// Аллокация происходит в синхронном режиме и может занимать значительное время
func
(
m
*
SpaceResources
)
Allocate
(
ctx
context
.
Context
,
spaceID
string
)
(
*
spaces
.
Resources
,
error
)
{
space
,
err
:=
m
.
spaces
.
Get
(
ctx
,
spaceID
)
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"get space"
)
}
org
,
err
:=
m
.
orgs
.
Get
(
ctx
,
space
.
OrgID
)
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"get organization"
)
}
res
:=
space
.
Resources
// если resourceID уже заполнено, то предполагается, что ответственность за создание ресурса лежит на пользователе
if
res
.
DatabaseResourceID
==
""
{
res
.
DatabaseResourceID
,
err
=
m
.
createSpaceResource
(
ctx
,
KindDatabase
,
space
,
org
)
if
err
!=
nil
{
return
nil
,
err
}
}
if
res
.
ObjectStorageResourceID
==
""
{
res
.
ObjectStorageResourceID
,
err
=
m
.
createSpaceResource
(
ctx
,
KindObjectStorage
,
space
,
org
)
if
err
!=
nil
{
return
nil
,
err
}
}
return
res
,
nil
}
func
(
m
*
SpaceResources
)
createSpaceResource
(
ctx
context
.
Context
,
kind
Kind
,
space
*
spaces
.
Space
,
org
*
organizations
.
Organization
)
(
string
,
error
)
{
providers
,
err
:=
m
.
resources
.
FindProviders
(
ctx
,
&
Filter
{
ID
:
org
.
Providers
})
if
err
!=
nil
{
return
""
,
err
}
var
provider
Provider
for
_
,
p
:=
range
providers
{
if
data
.
Contains
(
kind
,
p
.
Kind
())
{
provider
=
p
break
}
}
if
provider
==
nil
{
return
""
,
errors
.
New
(
"todo"
)
}
resource
,
err
:=
provider
.
GetDefaultResource
(
ctx
,
space
,
kind
)
if
err
!=
nil
{
return
""
,
err
}
resource
.
SetName
(
fmt
.
Sprintf
(
"Resource kind: '%s', space: '%s'"
,
kind
,
space
.
ID
))
if
resource
,
err
=
m
.
resources
.
CreateResource
(
ctx
,
resource
);
err
!=
nil
{
return
""
,
err
}
return
resource
.
GetID
(),
nil
}
func
(
m
*
SpaceResources
)
GetDatabaseResource
(
ctx
context
.
Context
,
spaceID
string
)
(
*
ConnectedResource
,
error
)
{
return
m
.
getConnectedResource
(
ctx
,
spaceID
,
KindDatabase
)
}
func
(
m
*
SpaceResources
)
GetObjectStorageResource
(
ctx
context
.
Context
,
spaceID
string
)
(
*
ConnectedResource
,
error
)
{
return
m
.
getConnectedResource
(
ctx
,
spaceID
,
KindObjectStorage
)
}
func
(
m
*
SpaceResources
)
getConnectedResource
(
ctx
context
.
Context
,
spaceID
string
,
kind
Kind
)
(
*
ConnectedResource
,
error
)
{
if
v
,
ok
:=
m
.
resourcesCache
.
Load
(
spaceID
+
"-"
+
kind
.
String
());
ok
{
return
v
.
(
*
ConnectedResource
),
nil
}
space
,
err
:=
m
.
spaces
.
Get
(
ctx
,
spaceID
)
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"get space"
)
}
if
space
.
Resources
==
nil
{
return
nil
,
errors
.
New
(
"todo"
)
}
var
resourceID
string
switch
kind
{
case
KindDatabase
:
resourceID
=
space
.
Resources
.
DatabaseResourceID
case
KindObjectStorage
:
resourceID
=
space
.
Resources
.
ObjectStorageResourceID
}
if
resourceID
==
""
{
return
nil
,
errors
.
New
(
"todo"
)
}
res
,
err
:=
m
.
resources
.
GetResource
(
ctx
,
resourceID
)
if
err
!=
nil
{
return
nil
,
err
}
// где-то должен быть кэш, из которого будет доставаться провайдер
provider
,
err
:=
m
.
resources
.
GetProvider
(
ctx
,
res
.
GetProviderID
())
if
err
!=
nil
{
return
nil
,
err
}
r
,
err
:=
provider
.
GetConnectedResource
(
ctx
,
res
)
if
err
!=
nil
{
return
nil
,
err
}
m
.
resourcesCache
.
Store
(
spaceID
+
"-"
+
kind
.
String
(),
res
)
return
r
,
nil
}
// TODO - где кэш провайдеров? учесть, что настройки провайдера/ресурса изменились?
// func (m *SpaceResources) getProvider(ctx context.Context, providerID string) (*Provider, error) {
// if v, ok := m.providersCache.Load(providerID); ok {
// return v.(*Provider), nil
// }
// provider, err := m.GetProvider(ctx, providerID)
// if err != nil {
// // todo
// }
// m.providersCache.Store(providerID, provider)
// return provider, nil
// }
func
(
m
*
SpaceResources
)
Deallocate
(
ctx
context
.
Context
,
spaceID
string
)
(
err
error
)
{
space
,
err
:=
m
.
spaces
.
Get
(
ctx
,
spaceID
)
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"get space"
)
}
if
space
.
Resources
.
DatabaseResourceID
!=
""
{
err
=
m
.
resources
.
DeleteResource
(
ctx
,
space
.
Resources
.
DatabaseResourceID
)
if
err
!=
nil
{
// todo
}
}
if
space
.
Resources
.
ObjectStorageResourceID
!=
""
{
err
=
m
.
resources
.
DeleteResource
(
ctx
,
space
.
Resources
.
ObjectStorageResourceID
)
if
err
!=
nil
{
// todo
}
}
return
nil
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment