Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8eeef825c0 | |||
| 9a7a7b6f36 | |||
| 3393934456 |
196
CHANGELOG.md
196
CHANGELOG.md
@@ -1,197 +1,5 @@
|
||||
## Version 1.8.0
|
||||
## Version 1.8.2
|
||||
|
||||
### Feature
|
||||
|
||||
#### account:
|
||||
- Add endpoints GrantAccessTemplates, ListAvailableTemplates, RevokeAccessTemplates in cloudbroker/account
|
||||
- Add SortBy field for list groups and validation functionality
|
||||
- Add ComputeFeatures field to RecordAccount and ItemAccount models in cloudapi/account
|
||||
- Add ComputeFeatures field to InfoAccount and CreateRequest model in cloudbroker/account
|
||||
- Add UpdateComputeFeatures endpoint in cloudbroker/account
|
||||
- Add ExtnetId, FreeIPs fields to model ItemVINS in cloudapi/account and cloudbroker/account
|
||||
|
||||
#### audit:
|
||||
- Add field GUID in model ItemLinkedJobs cloudbroker/audit
|
||||
- Delete field StatusCode in model ListRequest cloudbroker/audit
|
||||
- Add fields MinStatusCode and MaxStatusCode in model ListRequest cloudbroker/audit
|
||||
|
||||
#### bservice:
|
||||
- Add validation of RAM to be divisible by 128 in cloudapi/bservice
|
||||
|
||||
#### compute:
|
||||
- Add field CdImageId in models ItemCompute and RecordCompute in cloudapi/compute and cloudbroker/compute
|
||||
- Add fields NatableVINSID, NatableVINSIP, NatableVINSName, NatableVINSNetwork, NatableVINSNetworkName in models RecordCompute in cloudbroker/compute
|
||||
- Set field LocalBasePort in model PFWAddRequest as optional in cloudapi/compute and cloudbroker/compute
|
||||
- Add SortBy field for list groups and validation functionality
|
||||
- Add HPBacked, CPUPin, NumaAffinity fields to RecordCompute and InfoCompute models in cloudbroker/compute
|
||||
- Add HPBacked, CPUPin, NumaAffinity fields to RecordCompute and ItemCompute models in cloudapi/compute
|
||||
- Add validation of RAM to be divisible by 128 in cloudapi/compute and cloudbroker/compute
|
||||
- Add field NumaNodeId in models RecordCompute and ItemCompute in cloudapi/compute and cloudbroker/compute
|
||||
- Add BootDiskSet endpoints in cloudapi/compute and cloudbroker/compute
|
||||
- Add endpoints DiskSwitchToReplication, DiskMigrate in cloudapi/compute and cloudbroker/compute
|
||||
- Add field Replication in model RecordCompute.Disks.ItemComputeDisk in cloudapi/compute and cloudbroker/compute
|
||||
- Add endpoint getCustomFields in cloudbroker/compute
|
||||
- Delete field AffinityLabel in model AffinityRelationsRequest in cloudbroker/compute
|
||||
- Add fields ImageName and VirtualImageName, delete VINSConnected fields in RecordCompute model in cloudbroker/compute
|
||||
- Add fields Enabled and NodeID in ItemInterface model in cloudbroker/compute. Add NodeID field in ItemVNFInterface model in cloudapi/compute
|
||||
|
||||
#### disks:
|
||||
- Add endpoints Replicate, ReplicationResume, ReplicationReverse, ReplicationStart, ReplicationStop, ReplicationStatus, ReplicationSuspend in cloudapi/disks and cloudbroker/disks
|
||||
- Add field Replication in models RecordDisk and ItemDisk in cloudapi/disks and cloudbroker/disks
|
||||
- Add CreateTemplateFromBlank and CreateTemplateFromBlankAsync endpoints in cloudapi/compute and cloudbroker/compute
|
||||
- Add fields Page and Size in model SearchRequest in cloudapi/disks
|
||||
- Add FromPlatformDisk and FromPlatformDiskAsync endpoints in cloudapi/disks and cloudbroker/disks
|
||||
|
||||
#### flipgroup:
|
||||
- Add fields ConnId, Status, AccountId to model ListRequest in cloudapi/flipgroup and cloudbroker/flipgroup
|
||||
- Add SortBy field for list groups and validation functionality
|
||||
|
||||
#### grid:
|
||||
- Add endpoints addCustomBackupPath, removeCustomBackupPath, setPasswordPolicy in cloudbroker/grid
|
||||
|
||||
#### image:
|
||||
- Add field CdPresentedTo in model RecordImage in cloudapi/image cloudbroker/image
|
||||
- Set field AccountId in CreateRequest in cloudapi/image as required
|
||||
- Add endpoints GrantAccess, RevokeAccess in cloudbroker/image
|
||||
- Add SortBy field for list groups and validation functionality
|
||||
- Add field NetworkInterfaceNaming in model CreateRequest in cloudapi/image cloudbroker/image, in model EditRequest in cloudbroker/image, in models ItemImage and RecordImage in cloudapi/image and cloudbroker/image
|
||||
- Add validation field NetworkInterfaceNaming in cloudapi/image cloudbroker/image
|
||||
- Delete field GID in model CreateRequest in cloudapi/image
|
||||
- Delete field Meta and Ckey in model and RecordImage in cloudbroker/image
|
||||
- Add model ItemImage in cloudbroker/image
|
||||
|
||||
#### k8s:
|
||||
- Add field LbSysctlParams in model CreateRequest in cloudapi/k8s/create and cloudbroker/k8s/create
|
||||
- Add validation of RAM to be divisible by 128 in cloudapi/k8s and cloudbroker/k8s
|
||||
- Set uint64 as MasterRAM and WorkerRAM types in CreateRequest struct in cloudapi/k8s and cloudbroker/k8s
|
||||
|
||||
#### kvmppc
|
||||
- Add validation of RAM to be divisible by 128 in cloudapi/kvmppc and cloudbroker/kvmppc
|
||||
- Add DataDisks field to CreateRequest and CreateBlankRequest in cloudapi/kvmppc and cloudbroker/kvmppc
|
||||
- Add DataDisks field to MassCreateRequest in cloudbroker/kvmppc
|
||||
|
||||
#### kvmx86
|
||||
- Add validation of RAM to be divisible by 128 in cloudapi/kvmx86 and cloudbroker/kvmx86
|
||||
- Add DataDisks field to CreateRequest and CreateBlankRequest in cloudapi/kvmx86 and cloudbroker/kvmx86
|
||||
- Add DataDisks field to MassCreateRequest in cloudbroker/kvmx86
|
||||
|
||||
#### lb:
|
||||
- Add fields UserManaged, ManagerId, ManagerType, PartK8S in models RecordLB, ItemLBList in cloudapi/lb and cloudbroker/lb
|
||||
- Add SortBy field for list groups and validation functionality
|
||||
- Add field SysctlParams in model CreateRequest in cloudapi/lb/create and cloudbroker/lb/create
|
||||
- Add endpoint update_sysctl_params in cloudapi/lb and cloudbroker/lb
|
||||
|
||||
#### node:
|
||||
- Add ApplyIpmiAction, Consumption, Decommission, Enable, EnableNodes, Get, GetRaw, List, ListRaw, Maintenance, Restrict, SetCoreIsolation, SetHugePages, SetSRIOVStatus, SetVFSNumber and Update endpoints in cloudbroker/node
|
||||
- Add IDs method and Filters methods for ListNodes structure in cloudbroker/node
|
||||
- Add Serialize method for ListNodes, ItemNode and RecordNode structures in cloudbroker/node
|
||||
|
||||
#### pcidevice:
|
||||
- Add List, ListRaw endpoints in cloudapi/pcidevice
|
||||
- Add IDs and Serialize methods for ListPCIDevices structure in cloudapi/pcidevice
|
||||
|
||||
#### rg:
|
||||
- Add ComputeFeatures field to ItemResourceGroup and RecordResourceGroup models in cloudapi/rg
|
||||
- Add ComputeFeatures field to ItemRG and CreateRequest models in cloudbroker/rg
|
||||
- Add UpdateComputeFeatures endpoint in cloudbroker/rg
|
||||
- Add ExtnetId, FreeIPs fields to model ItemVINS in cloudapi/rg and cloudbroker/rg
|
||||
|
||||
#### sep:
|
||||
- Add endpoints addPool, delPool in cloudbroker/sep
|
||||
- Set field Config in CreateRequest as required in cloudbroker/sep
|
||||
- Add SortBy field for list groups and validation functionality
|
||||
|
||||
#### stack:
|
||||
- Add endpoints getLogicalCoresCount, setCpuAllocationRatio, setMemAllocationRatio in cloudbroker/stack
|
||||
|
||||
#### tasks:
|
||||
- Add field TaskId, Status, Completed in model ListRequest in cloudapi/task and cloudbroker/task
|
||||
- Add fields GUID, UpdatedBy in model ItemTask in cloudapi/task and cloudbroker/task
|
||||
- Fix panic in List endpoints in cloudapi/task and cloudbroker/task
|
||||
- Change type field Result from int to interface{} in models RecordAsyncTask, ItemAsyncTask in cloudapi/task and models ItemTask, RecordTask in cloudbroker/task
|
||||
- Add methods ID(), Name(), ToString(), ToMaps() for processing the value of the Result field in model ItemTask in cloudapi/task and cloudbroker/task
|
||||
- Add use case examples for the above methods in README.md
|
||||
- Add SortBy field for list groups and validation functionality
|
||||
- Add fields UpdateTimeAt and UpdateTimeTo in model ListRequest in cloudapi/tasks and cloudbroker/tasks
|
||||
|
||||
#### user:
|
||||
- Add fields Call, StatusCode, TimestampAt, TimestampTo in models GetAuditRequest in cloudbroker/user
|
||||
- Fix return value in GetAudit endpoint in cloudbroker/user
|
||||
- Add model ListAudits and change type field APIAccess in model ItemUser in cloudbroker/user
|
||||
- Add SortBy field for list groups and validation functionality in cloudbroker/user
|
||||
- Add APIList, Authenticate, Brief, GetAudit, GetResourceConsumption, Get, GetRaw, IsValidInviteUserToken, Search, SetData endpoints in cloudapi/user
|
||||
|
||||
#### vfpool:
|
||||
- Add Get, GetRaw, List, ListRaw endpoints in cloudapi/vfpool
|
||||
- Add Create, Delete, Disable, Enable, Get, GetRaw, List, ListRaw, Update endpoints in cloudbroker/vfpool
|
||||
- Add IDs method for ListVFPool, VFSInfoListand in cloudapi/vfpool and cloudbroker/vfpool
|
||||
- Add Filters methods for ListVFPool structure in cloudapi/vfpool and cloudbroker/vfpool
|
||||
- Add Serialize method for ListVFPool, ItemVFPool and RecordVFPool structures in cloudapi/vfpool and cloudbroker/vfpool
|
||||
|
||||
#### vins:
|
||||
- Set field IntPort in model NATRuleAddRequest as optional in cloudapi/vins and cloudbroker/vins
|
||||
- Add SortBy field for list groups and validation functionality
|
||||
- Add ExtnetId, FreeIPs fields to model ItemVINS in cloudapi/vins and cloudbroker/vins
|
||||
- Add DNSList field to models CreateInAccountRequest and CreateInRGRequest in cloudapi/vins and cloudbroker/vins
|
||||
- Add DNSApply endpoints in cloudapi/vins and cloudbroker/vins
|
||||
- Add field NodeID in model RecordVINS.RecordVNFDev.Interfaces in cloudapi/vins and cloudbroker/vins
|
||||
|
||||
### Bugfix
|
||||
|
||||
#### account:
|
||||
- Fix wrong json, url field AccountID in model SetCPUAllocationParameterRequest in cloudbroker/account
|
||||
- Fix wrong json, url field AccountID in model SetCPUAllocationRatioRequest in cloudbroker/account
|
||||
- Change Start and End fields type from uint64 to float64 in model GetConsumptionRequest in cloudapi/account
|
||||
|
||||
#### apiaccess:
|
||||
- Changed Job and Resmon field types in model CloudBrokerEndpoints in cloudbroker/apiaccess
|
||||
- Add fields Page and Size in model UserListRequest in cloudbroker/apiaccess
|
||||
|
||||
#### bservice:
|
||||
- Fix url for Disable endpoint in cloudapi/bservice
|
||||
|
||||
#### compute:
|
||||
- Fix Entrycount tag in model ListComputes in cloudbroker/compute
|
||||
- Add field Name in model ListPCIDeviceRequest in cloudbroker/compute
|
||||
- Fix type of field Data in model ListPCIDevices in cloudapi/compute
|
||||
- Add model ItemPCIDevice in cloudapi/compute
|
||||
- Fix type of field Data in model ListVGPUs in cloudapi/compute and cloudbroker/compute
|
||||
- Add model ItemVGPU in cloudapi/compute and cloudbroker/compute
|
||||
|
||||
#### disks:
|
||||
- Delete tag required from field Detailed in ListTypesRequest model in cloudapi/disks
|
||||
|
||||
#### grid:
|
||||
- Fix json, url tags in field Name in model RenameRequest in cloudbroker/grid
|
||||
|
||||
#### image:
|
||||
- Fix url for ComputeCIUnset endpoint in cloudbroker/image
|
||||
|
||||
#### k8ci:
|
||||
- Delete omitempty from json, url tags in field Permanently in model DeleteRequest in cloudbroker/k8ci
|
||||
- Fix wrong json, url tags field ByID in model ListDeletedRequest in cloudbroker/k8ci
|
||||
- Fix allowed network plugin value from "weawenet" to "weavenet" in validators for cloudbroker/k8ci
|
||||
|
||||
#### k8s:
|
||||
- Fix allowed network plugin value from "weawenet" to "weavenet" in validators for cloudapi/k8s, cloudbroker/k8s
|
||||
|
||||
#### lb:
|
||||
- Fix wrong json, url tags field AccountID in model ListDeletedRequest in cloudapi/lb
|
||||
- Add field Safe in model RestartRequest in cloudbroker/lb
|
||||
- Fix wrong json, url tags field AccountID in models ListRequest, ListDeletedRequest in cloudbroker/lb
|
||||
- Fix url for Stop endpoint in cloudapi/lb
|
||||
|
||||
#### rg:
|
||||
- Fix wrong json, url field AccountID in model ListLBRequest in cloudapi/rg and cloudbroker/rg
|
||||
- Fix wrong json, url field UniqPools in model CreateRequest in cloudbroker/rg
|
||||
|
||||
#### sep:
|
||||
- Fix wrong json, url tag in field GID in model ListRequest in cloudbroker/sep
|
||||
|
||||
#### user:
|
||||
- Fix wrong json, url field Password in model ItemUser in cloudbroker/user
|
||||
- Change ByID field type from uint64 to string in model ListRequest in cloudbroker/user
|
||||
|
||||
#### vins:
|
||||
- Fix wrong json, url tags in models DefaultQOSUpdateRequest and NetQOSRequest in field IngressBirst in cloudbroker/vins
|
||||
- Fix wrong name field ListNatRule to ListNATRule in cloudbroker/vins
|
||||
- Add universal client for connections
|
||||
135
README.md
135
README.md
@@ -69,6 +69,13 @@ Decort SDK - это библиотека, написанная на языке G
|
||||
- [Пример выполнения запроса](#пример-выполнения-запроса-2)
|
||||
- [Пример валидации запросов, имеющих в своей структуре поле RAM (или MasterRam/WorkerRAM)](#пример-валидации-запросов-имеющих-в-своей-структуре-поле-ram-или-masterramworkerram)
|
||||
- [Пример выполнения запроса](#пример-выполнения-запроса-3)
|
||||
- [Работа с универсальным клиентом](#работа-с-универсальным-клиентом)
|
||||
- [Настройка конфигурации универсального клиента](#настройка-конфигурации-универсального-клиента)
|
||||
- [Пример конфигурации универсального клиента](#пример-конфигурации-универсального-клиента)
|
||||
- [Парсинг универсальной конфигурации из файла](#парсинг-универсальной-конфигурации-из-файла)
|
||||
- [Создание универсального клиента](#создание-универсального-клиента)
|
||||
- [Пример создания универсального клиента](#пример-создания-универсального-клиента)
|
||||
- [Пример выполнения запроса](#пример-выполнения-запроса-4)
|
||||
|
||||
## Установка
|
||||
|
||||
@@ -166,7 +173,7 @@ go get -u repository.basistech.ru/BASIS/decort-golang-sdk
|
||||
| SSLSkipVerify | bool | Нет | Пропуск проверки подлинности сертификата |
|
||||
| Token | string | Нет | JWT токен |
|
||||
|
||||
#### Пример конфигурации клиента
|
||||
##### Пример конфигурации клиента
|
||||
|
||||
```go
|
||||
import (
|
||||
@@ -1455,4 +1462,130 @@ func main() {
|
||||
log.Println(res)
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Работа с универсальным клиентом
|
||||
|
||||
Работа с универсальным клиентом позволяет использовать любой тип авторизации
|
||||
|
||||
### Настройка конфигурации универсального клиента
|
||||
|
||||
| Параметр | Тип | Обязательный | Описание |
|
||||
| --- | --- | --- | --- |
|
||||
| Decs3oConfig | *Config | Нет | Конфигурация Decs3o |
|
||||
| BVSConfig | *BVSConfig | Нет | Конфигурация BVS |
|
||||
| LegacyConfig | string | Нет | Конфигурация Legacy |
|
||||
|
||||
В универсальном клиенте можно использовать только один тип конфигурации одновременно.
|
||||
|
||||
#### Пример конфигурации универсального клиента
|
||||
|
||||
```go
|
||||
import (
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/config"
|
||||
)
|
||||
|
||||
func main(){
|
||||
// Настройка конфигурации
|
||||
BVSConfig := config.BVSConfig{
|
||||
AppID: "<APP_ID>",
|
||||
AppSecret: "<APP_SECRET>",
|
||||
SSOURL: "https://sso.digitalenergy.online",
|
||||
DecortURL: "https://mr4.digitalenergy.online",
|
||||
Username: "<Username>",
|
||||
Password: "<Password>",
|
||||
Retries: 5,
|
||||
}
|
||||
|
||||
BVSConfig.SetTimeout(5 * time.Minute)
|
||||
|
||||
cfg := config.UniversalConfig{
|
||||
BVSConfig: &BVScfg,
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Создание универсального клиента
|
||||
|
||||
Создание клиента происходит с помощью функции-строителя `NewUniversal` из основного пакета `decort-sdk`, для избежания проблем с именами, пакету можно присвоить алиас `decort`. Функция принимает конфигурацию, возвращает структуру `ClientInterface`, с помощью которой можно взаимодействовать с платформой.
|
||||
|
||||
#### Пример создания универсального клиента
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/config"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Настройка конфигурации
|
||||
legacyCfg := config.LegacyConfig{
|
||||
Username: "<USERNAME>",
|
||||
Password: "<PASSWORD>",
|
||||
DecortURL: "https://mr4.digitalenergy.online",
|
||||
Retries: 5,
|
||||
}
|
||||
|
||||
legacyCfg.SetTimeout(5 * time.Minute)
|
||||
|
||||
cfg := config.UniversalConfig{
|
||||
LegacyConfig: &legacyCfg,
|
||||
}
|
||||
|
||||
// Создание клиента
|
||||
universalClient := decort.NewUniversal(cfg)
|
||||
}
|
||||
```
|
||||
|
||||
#### Пример выполнения запроса
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/config"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Настройка конфигурации
|
||||
legacyCfg := config.LegacyConfig{
|
||||
Username: "<USERNAME>",
|
||||
Password: "<PASSWORD>",
|
||||
Domain: "dynamix",
|
||||
DecortURL: "https://mr4.digitalenergy.online",
|
||||
Retries: 5,
|
||||
}
|
||||
|
||||
legacyCfg.SetTimeout(5 * time.Minute)
|
||||
|
||||
cfg := config.UniversalConfig{
|
||||
LegacyConfig: &legacyCfg,
|
||||
}
|
||||
|
||||
// Создание клиента
|
||||
universalClient := decort.NewUniversal(cfg)
|
||||
|
||||
// Создание структуры запроса
|
||||
// CreateRequest - реквест на создание виртуальной машины
|
||||
req := kvmx86.CreateRequest{
|
||||
RGID: 123,
|
||||
Name: "compute",
|
||||
CPU: 4,
|
||||
RAM: 4096,
|
||||
ImageID: 321,
|
||||
}
|
||||
|
||||
// Выполнение запроса
|
||||
res, err := universalClient.CloudAPI().KVMX86().Create(context.Background(), req)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(res)
|
||||
}
|
||||
```
|
||||
47
client.go
47
client.go
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/google/go-querystring/query"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/config"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker"
|
||||
)
|
||||
@@ -53,7 +54,7 @@ func New(cfg config.Config) *DecortClient {
|
||||
},
|
||||
},
|
||||
},
|
||||
cfg: cfg,
|
||||
cfg: trimConfig(&cfg),
|
||||
expiryTime: expiryTime,
|
||||
mutex: &sync.Mutex{},
|
||||
}
|
||||
@@ -71,12 +72,22 @@ func (dc *DecortClient) CloudBroker() *cloudbroker.CloudBroker {
|
||||
|
||||
// DecortApiCall method for sending requests to the platform
|
||||
func (dc *DecortClient) DecortApiCall(ctx context.Context, method, url string, params interface{}) ([]byte, error) {
|
||||
values, err := query.Values(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body := bytes.NewBufferString(values.Encode())
|
||||
var body *bytes.Buffer
|
||||
var ctype string
|
||||
|
||||
byteSlice, ok := params.([]byte)
|
||||
if ok {
|
||||
body = bytes.NewBuffer(byteSlice)
|
||||
// ctype = "application/x-iso9660-image"
|
||||
ctype = "application/octet-stream"
|
||||
} else {
|
||||
values, err := query.Values(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body = bytes.NewBufferString(values.Encode())
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, dc.decortURL+constants.RESTMACHINE+url, body)
|
||||
if err != nil {
|
||||
@@ -87,9 +98,8 @@ func (dc *DecortClient) DecortApiCall(ctx context.Context, method, url string, p
|
||||
if err = dc.getToken(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// perform request
|
||||
respBytes, err := dc.do(req, "")
|
||||
respBytes, err := dc.do(req, ctype)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -284,11 +294,22 @@ func multiPartReq(params interface{}) (*bytes.Buffer, string, error) {
|
||||
if values.Field(i).Type().Kind() == reflect.Slice {
|
||||
switch slice := values.Field(i).Interface().(type) {
|
||||
case []string:
|
||||
for _, val := range slice {
|
||||
err := writer.WriteField(trimString(types.Field(i)), val)
|
||||
if validators.IsInSlice(trimString(types.Field(i)), constants.K8sValues) {
|
||||
code, err := json.Marshal(slice)
|
||||
if err != nil {
|
||||
return &bytes.Buffer{}, "", err
|
||||
}
|
||||
err = writer.WriteField(trimString(types.Field(i)), string(code))
|
||||
if err != nil {
|
||||
return &bytes.Buffer{}, "", err
|
||||
}
|
||||
} else {
|
||||
for _, val := range slice {
|
||||
err := writer.WriteField(trimString(types.Field(i)), val)
|
||||
if err != nil {
|
||||
return &bytes.Buffer{}, "", err
|
||||
}
|
||||
}
|
||||
}
|
||||
case []uint:
|
||||
for _, val := range slice {
|
||||
@@ -348,3 +369,9 @@ func valueToString(a any) string {
|
||||
func trimString(el reflect.StructField) string {
|
||||
return strings.TrimSuffix(el.Tag.Get("url"), ",omitempty")
|
||||
}
|
||||
|
||||
func trimConfig(cfg *config.Config) config.Config {
|
||||
cfg.SSOURL = strings.TrimSuffix(cfg.SSOURL, "/")
|
||||
cfg.DecortURL = strings.TrimSuffix(cfg.DecortURL, "/")
|
||||
return *cfg
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ func NewBVS(cfg config.BVSConfig) *BVSDecortClient {
|
||||
},
|
||||
},
|
||||
},
|
||||
cfg: cfg,
|
||||
cfg: trimBVSConfig(&cfg),
|
||||
mutex: &sync.Mutex{},
|
||||
}
|
||||
}
|
||||
@@ -71,12 +71,21 @@ func (bdc *BVSDecortClient) CloudBroker() *cloudbroker.CloudBroker {
|
||||
|
||||
// DecortApiCall method for sending requests to the platform
|
||||
func (bdc *BVSDecortClient) DecortApiCall(ctx context.Context, method, url string, params interface{}) ([]byte, error) {
|
||||
values, err := query.Values(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var body *bytes.Buffer
|
||||
var ctype string
|
||||
|
||||
body := bytes.NewBufferString(values.Encode())
|
||||
byteSlice, ok := params.([]byte)
|
||||
if ok {
|
||||
body = bytes.NewBuffer(byteSlice)
|
||||
// ctype = "application/x-iso9660-image"
|
||||
ctype = "application/octet-stream"
|
||||
} else {
|
||||
values, err := query.Values(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body = bytes.NewBufferString(values.Encode())
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, bdc.decortURL+constants.RESTMACHINE+url, body)
|
||||
if err != nil {
|
||||
@@ -101,7 +110,7 @@ func (bdc *BVSDecortClient) DecortApiCall(ctx context.Context, method, url strin
|
||||
|
||||
// perform request
|
||||
reqCopy := req.Clone(ctx)
|
||||
respBytes, err := bdc.do(req, "")
|
||||
respBytes, err := bdc.do(req, ctype)
|
||||
if err == nil {
|
||||
return respBytes, nil
|
||||
}
|
||||
@@ -378,3 +387,9 @@ func (bdc *BVSDecortClient) do(req *http.Request, ctype string) ([]byte, error)
|
||||
err = fmt.Errorf("%s", respBytes)
|
||||
return nil, fmt.Errorf("could not execute request: %w", err)
|
||||
}
|
||||
|
||||
func trimBVSConfig(cfg *config.BVSConfig) config.BVSConfig {
|
||||
cfg.SSOURL = strings.TrimSuffix(cfg.SSOURL, "/")
|
||||
cfg.DecortURL = strings.TrimSuffix(cfg.DecortURL, "/")
|
||||
return *cfg
|
||||
}
|
||||
|
||||
8
config/universal-config.go
Normal file
8
config/universal-config.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package config
|
||||
|
||||
// UniversalConfig combines configurations for different types of clients
|
||||
type UniversalConfig struct {
|
||||
Decs3oConfig *Config `json:"decs3oConfig,omitempty" yaml:"decs3oConfig,omitempty"`
|
||||
BVSConfig *BVSConfig `json:"bvsConfig,omitempty" yaml:"bvsConfig,omitempty"`
|
||||
LegacyConfig *LegacyConfig `json:"legacyConfig,omitempty" yaml:"legacyConfig,omitempty"`
|
||||
}
|
||||
@@ -10,3 +10,5 @@ const (
|
||||
var FileName = map[string]string{
|
||||
"OidcCertificate": "ca.crt",
|
||||
}
|
||||
|
||||
var K8sValues = []string{"labels", "taints", "annotations, additionalSANs"}
|
||||
|
||||
@@ -3,6 +3,7 @@ package validators
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
@@ -104,6 +105,13 @@ func computeNetTypeValidator(fe validator.FieldLevel) bool {
|
||||
return IsInSlice(fieldValue, computeNetTypeValues)
|
||||
}
|
||||
|
||||
// computex86NetTypeValidator is used to validate NetType field.
|
||||
func computex86NetTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, computex86NetTypeValues)
|
||||
}
|
||||
|
||||
// computeOrderValidator is used to validate Order field.
|
||||
func computeOrderValidator(fe validator.FieldLevel) bool {
|
||||
fieldSlice, ok := fe.Field().Interface().([]string)
|
||||
@@ -312,6 +320,23 @@ func networkInterfaceNamingValidator(fe validator.FieldLevel) bool {
|
||||
return IsInSlice(fieldValue, networkInterfaceNamingValues)
|
||||
}
|
||||
|
||||
func numaAffinityValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, numaAffinityValues)
|
||||
}
|
||||
|
||||
// kvmx86NetTypeValidator is used to validate NetType field for x86 compute.
|
||||
func kvmx86NetTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, kvmx86NetTypeValues)
|
||||
}
|
||||
|
||||
func isBoolTypeValidator(fe validator.FieldLevel) bool {
|
||||
return fe.Field().CanConvert(reflect.TypeOf(true))
|
||||
}
|
||||
|
||||
// ValidateRAM checks if request contains RAM value that is positive integer divisible by divisibility passed.
|
||||
// It is recommended to pass constants.RAM_DIVISIBILITY as divisility arguement
|
||||
func ValidateRAM(r interfaces.RequestWithRAM, divisibility uint64) error {
|
||||
|
||||
@@ -95,6 +95,12 @@ func errorMessage(fe validator.FieldError) string {
|
||||
fe.Field(),
|
||||
joinValues(computeNetTypeValues))
|
||||
|
||||
case "computex86NetType":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(computex86NetTypeValues))
|
||||
|
||||
case "computeOrder":
|
||||
return fmt.Sprintf("%s %s can contain only the following values: %s",
|
||||
prefix,
|
||||
@@ -258,6 +264,18 @@ func errorMessage(fe validator.FieldError) string {
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(networkInterfaceNamingValues))
|
||||
|
||||
case "numaAffinity":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(numaAffinityValues))
|
||||
|
||||
case "kvmx86NetType":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(kvmx86NetTypeValues))
|
||||
}
|
||||
|
||||
return fe.Error()
|
||||
|
||||
@@ -106,6 +106,11 @@ func registerAllValidators(validate *validator.Validate) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("computex86NetType", computex86NetTypeValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("computeOrder", computeOrderValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -211,5 +216,20 @@ func registerAllValidators(validate *validator.Validate) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("numaAffinity", numaAffinityValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("kvmx86NetType", kvmx86NetTypeValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("isBool", isBoolTypeValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -10,20 +10,22 @@ var (
|
||||
|
||||
bserviceModeValues = []string{"ABSOLUTE", "RELATIVE"}
|
||||
|
||||
computeTopologyValues = []string{"compute", "node"}
|
||||
computePolicyValues = []string{"RECOMMENDED", "REQUIRED"}
|
||||
computeModeValues = []string{"EQ", "EN", "ANY"}
|
||||
computeDiskTypeValues = []string{"D", "B"}
|
||||
computeNetTypeValues = []string{"EXTNET", "VINS"}
|
||||
computeOrderValues = []string{"cdrom", "network", "hd"}
|
||||
computeDataDisksValues = []string{"KEEP", "DETACH", "DESTROY"}
|
||||
computeDriverValues = []string{"KVM_X86", "SVA_KVM_X86"}
|
||||
computeTopologyValues = []string{"compute", "node"}
|
||||
computePolicyValues = []string{"RECOMMENDED", "REQUIRED"}
|
||||
computeModeValues = []string{"EQ", "EN", "ANY"}
|
||||
computeDiskTypeValues = []string{"D", "B"}
|
||||
computeNetTypeValues = []string{"EXTNET", "VINS"}
|
||||
computex86NetTypeValues = []string{"EXTNET", "VINS", "VFNIC"}
|
||||
computeOrderValues = []string{"cdrom", "network", "hd"}
|
||||
computeDataDisksValues = []string{"KEEP", "DETACH", "DESTROY"}
|
||||
computeDriverValues = []string{"KVM_X86", "SVA_KVM_X86"}
|
||||
|
||||
diskTypeValues = []string{"B", "T", "D"}
|
||||
|
||||
flipgroupClientTypeValues = []string{"compute", "vins"}
|
||||
|
||||
kvmNetTypeValues = []string{"EXTNET", "VINS", "NONE"}
|
||||
kvmNetTypeValues = []string{"EXTNET", "VINS", "NONE"}
|
||||
kvmx86NetTypeValues = []string{"EXTNET", "VINS", "NONE", "VFNIC"}
|
||||
|
||||
lbAlgorithmValues = []string{"roundrobin", "static-rr", "leastconn"}
|
||||
|
||||
@@ -52,4 +54,6 @@ var (
|
||||
computeFeaturesValues = []string{"hugepages", "numa", "cpupin", "vfnic"}
|
||||
|
||||
networkInterfaceNamingValues = []string{"eth", "ens"}
|
||||
|
||||
numaAffinityValues = []string{"none", "strict", "loose"}
|
||||
)
|
||||
|
||||
@@ -50,7 +50,7 @@ func NewLegacy(cfg config.LegacyConfig) *LegacyDecortClient {
|
||||
},
|
||||
},
|
||||
},
|
||||
cfg: cfg,
|
||||
cfg: trimLegacyConfig(&cfg),
|
||||
expiryTime: expiryTime,
|
||||
mutex: &sync.Mutex{},
|
||||
}
|
||||
@@ -73,12 +73,20 @@ func (ldc *LegacyDecortClient) DecortApiCall(ctx context.Context, method, url st
|
||||
return nil, err
|
||||
}
|
||||
|
||||
values, err := query.Values(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var body *bytes.Buffer
|
||||
var ctype string
|
||||
|
||||
body := bytes.NewBufferString(values.Encode() + fmt.Sprintf("&authkey=%s", ldc.cfg.Token))
|
||||
byteSlice, ok := params.([]byte)
|
||||
if ok {
|
||||
body = bytes.NewBuffer(byteSlice)
|
||||
ctype = "application/octet-stream"
|
||||
} else {
|
||||
values, err := query.Values(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body = bytes.NewBufferString(values.Encode() + fmt.Sprintf("&authkey=%s", ldc.cfg.Token))
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, ldc.decortURL+constants.RESTMACHINE+url, body)
|
||||
if err != nil {
|
||||
@@ -86,7 +94,7 @@ func (ldc *LegacyDecortClient) DecortApiCall(ctx context.Context, method, url st
|
||||
}
|
||||
|
||||
// perform request
|
||||
respBytes, err := ldc.do(req, "")
|
||||
respBytes, err := ldc.do(req, ctype)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -233,3 +241,8 @@ func (ldc *LegacyDecortClient) do(req *http.Request, ctype string) ([]byte, erro
|
||||
err = fmt.Errorf("%s", respBytes)
|
||||
return nil, fmt.Errorf("could not execute request: %w", err)
|
||||
}
|
||||
|
||||
func trimLegacyConfig(cfg *config.LegacyConfig) config.LegacyConfig {
|
||||
cfg.DecortURL = strings.TrimSuffix(cfg.DecortURL, "/")
|
||||
return *cfg
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ type CreateTemplateRequest struct {
|
||||
type wrapperCreateTemplateRequest struct {
|
||||
CreateTemplateRequest
|
||||
|
||||
Async bool `url:"async"`
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// CreateTemplate create template from compute instance
|
||||
@@ -35,7 +35,7 @@ func (c Compute) CreateTemplate(ctx context.Context, req CreateTemplateRequest)
|
||||
|
||||
reqWrapped := wrapperCreateTemplateRequest{
|
||||
CreateTemplateRequest: req,
|
||||
Async: false,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/createTemplate"
|
||||
@@ -62,7 +62,7 @@ func (c Compute) CreateTemplateAsync(ctx context.Context, req CreateTemplateRequ
|
||||
|
||||
reqWrapped := wrapperCreateTemplateRequest{
|
||||
CreateTemplateRequest: req,
|
||||
Async: true,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/createTemplate"
|
||||
|
||||
@@ -431,6 +431,9 @@ type RecordCompute struct {
|
||||
// Resource name
|
||||
ResName string `json:"resName"`
|
||||
|
||||
// Reserved Node Cpus
|
||||
ReservedNodeCpus []uint64 `json:"reservedNodeCpus"`
|
||||
|
||||
// Resource group ID
|
||||
RGID uint64 `json:"rgId"`
|
||||
|
||||
@@ -673,7 +676,7 @@ type ItemComputeDisk struct {
|
||||
RealityDeviceNumber uint64 `json:"realityDeviceNumber"`
|
||||
|
||||
// Replication
|
||||
Replication interface{} `json:"replication"`
|
||||
Replication ItemReplication `json:"replication"`
|
||||
|
||||
// Resource ID
|
||||
ResID string `json:"resId"`
|
||||
@@ -709,6 +712,26 @@ type ItemComputeDisk struct {
|
||||
VMID uint64 `json:"vmid"`
|
||||
}
|
||||
|
||||
type ItemReplication struct {
|
||||
// DiskID
|
||||
DiskID uint64 `json:"diskId"`
|
||||
|
||||
// PoolID
|
||||
PoolID string `json:"poolId"`
|
||||
|
||||
// Role
|
||||
Role string `json:"role"`
|
||||
|
||||
// SelfVolumeID
|
||||
SelfVolumeID string `json:"selfVolumeId"`
|
||||
|
||||
// StorageID
|
||||
StorageID string `json:"storageId"`
|
||||
|
||||
// VolumeID
|
||||
VolumeID string `json:"volumeId"`
|
||||
}
|
||||
|
||||
// Main information about snapshot extend
|
||||
type SnapshotExtend struct {
|
||||
// GUID
|
||||
@@ -915,6 +938,9 @@ type ItemCompute struct {
|
||||
// Resource name
|
||||
ResName string `json:"resName"`
|
||||
|
||||
// Reserved Node Cpus
|
||||
ReservedNodeCpus []uint64 `json:"reservedNodeCpus"`
|
||||
|
||||
// Resource group ID
|
||||
RGID uint64 `json:"rgId"`
|
||||
|
||||
@@ -1085,6 +1111,7 @@ type ItemPCIDevice struct {
|
||||
type ListPCIDevices struct {
|
||||
// Data
|
||||
Data []ItemPCIDevice `json:"data"`
|
||||
|
||||
// Entry count
|
||||
EntryCount uint64 `json:"entryCount"`
|
||||
}
|
||||
|
||||
@@ -16,9 +16,10 @@ type NetAttachRequest struct {
|
||||
|
||||
// Network type
|
||||
// 'EXTNET' for connect to external network directly
|
||||
// and 'VINS' for connect to ViNS
|
||||
// 'VINS' for connect to ViNS
|
||||
// 'VFNIC' for connect to vfpool
|
||||
// Required: true
|
||||
NetType string `url:"netType" json:"netType" validate:"computeNetType"`
|
||||
NetType string `url:"netType" json:"netType" validate:"computex86NetType"`
|
||||
|
||||
// Network ID for connect to
|
||||
// For EXTNET - external network ID
|
||||
|
||||
@@ -21,6 +21,24 @@ type UpdateRequest struct {
|
||||
// New description
|
||||
// Required: false
|
||||
Description string `url:"desc,omitempty" json:"desc,omitempty"`
|
||||
|
||||
// Rule for VM placement with NUMA affinity.
|
||||
// Possible values - none (placement without NUMA affinity),
|
||||
// strict (strictly with NUMA affinity, if not possible - do not start VM),
|
||||
// loose (use NUMA affinity if possible)
|
||||
// Required: false
|
||||
// Default: none
|
||||
NumaAffinity string `url:"numaAffinity,omitempty" json:"numaAffinity,omitempty" validate:"omitempty,numaAffinity"`
|
||||
|
||||
// Run VM on dedicated CPUs. To use this feature, the system must be pre-configured by allocating CPUs on the physical node
|
||||
// Required: false
|
||||
// Default: false
|
||||
CPUPin bool `url:"cpupin" json:"cpupin"`
|
||||
|
||||
// Use Huge Pages to allocate RAM of the virtual machine. The system must be pre-configured by allocating Huge Pages on the physical node
|
||||
// Required: false
|
||||
// Default: false
|
||||
HPBacked bool `url:"hpBacked" json:"hpBacked"`
|
||||
}
|
||||
|
||||
// Update updates some properties of the compute
|
||||
|
||||
@@ -57,7 +57,7 @@ type FromPlatformDiskRequest struct {
|
||||
// List of types of compute suitable for image
|
||||
// Example: [ "KVM_X86" ]
|
||||
// Required: false
|
||||
Drivers []string `url:"drivers" json:"drivers" validate:"min=1,max=2,imageDrivers"`
|
||||
Drivers []string `url:"drivers,omitempty" json:"drivers,omitempty"`
|
||||
|
||||
// Does this machine supports hot resize
|
||||
// Required: false
|
||||
|
||||
@@ -32,7 +32,7 @@ type ListRequest struct {
|
||||
|
||||
// Find by shared, true or false
|
||||
// Required: false
|
||||
Shared bool `url:"shared,omitempty" json:"shared,omitempty"`
|
||||
Shared interface{} `url:"shared,omitempty" json:"shared,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// ID of the account the disks belong to
|
||||
// Required: false
|
||||
|
||||
@@ -28,7 +28,7 @@ type ListDeletedRequest struct {
|
||||
|
||||
// Find by shared, true or false
|
||||
// Required: false
|
||||
Shared bool `url:"shared,omitempty" json:"shared,omitempty"`
|
||||
Shared interface{} `url:"shared,omitempty" json:"shared,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// ID of the account the disks belong to
|
||||
// Required: false
|
||||
|
||||
@@ -75,7 +75,7 @@ type ItemDisk struct {
|
||||
PurgeTime uint64 `json:"purgeTime"`
|
||||
|
||||
// Replication
|
||||
Replication interface{} `json:"replication"`
|
||||
Replication ItemReplication `json:"replication"`
|
||||
|
||||
// Resource ID
|
||||
ResID string `json:"resId"`
|
||||
@@ -265,8 +265,10 @@ type ListDisks struct {
|
||||
|
||||
// List of unattached disks
|
||||
type ListDisksUnattached struct {
|
||||
// Data
|
||||
Data []ItemDiskUnattached `json:"data"`
|
||||
|
||||
// Entry count
|
||||
EntryCount uint64 `json:"entryCount"`
|
||||
}
|
||||
|
||||
@@ -407,7 +409,7 @@ type RecordDisk struct {
|
||||
PurgeTime uint64 `json:"purgeTime"`
|
||||
|
||||
// Replication
|
||||
Replication interface{} `json:"replication"`
|
||||
Replication ItemReplication `json:"replication"`
|
||||
|
||||
// Resource ID
|
||||
ResID string `json:"resId"`
|
||||
@@ -449,6 +451,26 @@ type RecordDisk struct {
|
||||
VMID uint64 `json:"vmid"`
|
||||
}
|
||||
|
||||
type ItemReplication struct {
|
||||
// DiskID
|
||||
DiskID uint64 `json:"diskId"`
|
||||
|
||||
// PoolID
|
||||
PoolID string `json:"poolId"`
|
||||
|
||||
// Role
|
||||
Role string `json:"role"`
|
||||
|
||||
// SelfVolumeID
|
||||
SelfVolumeID string `json:"selfVolumeId"`
|
||||
|
||||
// StorageID
|
||||
StorageID string `json:"storageId"`
|
||||
|
||||
// VolumeID
|
||||
VolumeID string `json:"volumeId"`
|
||||
}
|
||||
|
||||
type ListTypes struct {
|
||||
// Data
|
||||
Data []interface{} `json:"data"`
|
||||
|
||||
@@ -15,23 +15,18 @@ type ReplicationStatusRequest struct {
|
||||
}
|
||||
|
||||
// ReplicationStatus get replication status
|
||||
func (d Disks) ReplicationStatus(ctx context.Context, req ReplicationStatusRequest) (interface{}, error) {
|
||||
func (d Disks) ReplicationStatus(ctx context.Context, req ReplicationStatusRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/disks/replicationStatus"
|
||||
|
||||
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
// result, err := strconv.ParseBool(string(res))
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
return res, nil
|
||||
return string(res), nil
|
||||
}
|
||||
|
||||
@@ -42,6 +42,10 @@ type ListRequest struct {
|
||||
// Required: false
|
||||
ByID uint64 `url:"by_id,omitempty" json:"by_id,omitempty"`
|
||||
|
||||
// Find by list of clientIds
|
||||
// Required: false
|
||||
ClientIDs []uint64 `url:"clientIds,omitempty" json:"clientIds,omitempty"`
|
||||
|
||||
// Page number
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
|
||||
@@ -48,15 +48,15 @@ type ListRequest struct {
|
||||
|
||||
// Find by public True or False
|
||||
// Required: false
|
||||
Public bool `url:"public,omitempty" json:"public,omitempty"`
|
||||
Public interface{} `url:"public,omitempty" json:"public,omitempty" validate:"omitempty,sortBy"`
|
||||
|
||||
// Find by hot resize True or False
|
||||
// Required: false
|
||||
HotResize bool `url:"hotResize,omitempty" json:"hotResize,omitempty"`
|
||||
HotResize interface{} `url:"hotResize,omitempty" json:"hotResize,omitempty" validate:"omitempty,sortBy"`
|
||||
|
||||
// Find by bootable True or False
|
||||
// Required: false
|
||||
Bootable bool `url:"bootable,omitempty" json:"bootable,omitempty"`
|
||||
Bootable interface{} `url:"bootable,omitempty" json:"bootable,omitempty" validate:"omitempty,sortBy"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
|
||||
@@ -14,7 +14,8 @@ type Interface struct {
|
||||
// Should be one of:
|
||||
// - VINS
|
||||
// - EXTNET
|
||||
NetType string `url:"netType" json:"netType" validate:"required,kvmNetType"`
|
||||
// - VFNIC
|
||||
NetType string `url:"netType" json:"netType" validate:"required,kvmx86NetType"`
|
||||
|
||||
// Network ID for connect to,
|
||||
// for EXTNET - external network ID,
|
||||
@@ -74,10 +75,14 @@ type CreateRequest struct {
|
||||
// Required: true
|
||||
RAM uint64 `url:"ram" json:"ram" validate:"required"`
|
||||
|
||||
// If True, the imageId, bootDisk, sepId, pool parameters are ignored and the compute is created without a boot disk in the stopped state
|
||||
// Required: false
|
||||
WithoutBootDisk bool `url:"withoutBootDisk" json:"withoutBootDisk"`
|
||||
|
||||
// ID of the OS image to base this VM on;
|
||||
// Could be boot disk image or CD-ROM image
|
||||
// Required: true
|
||||
ImageID uint64 `url:"imageId" json:"imageId" validate:"required"`
|
||||
// Required: false
|
||||
ImageID uint64 `url:"imageId,omitempty" json:"imageId,omitempty"`
|
||||
|
||||
// Size of the boot disk in GB
|
||||
// Required: false
|
||||
@@ -131,6 +136,24 @@ type CreateRequest struct {
|
||||
// Type of compute Stateful (KVM_X86) or Stateless (SVA_KVM_X86)
|
||||
// Required: false
|
||||
Driver string `url:"driver,omitempty" json:"driver,omitempty" validate:"omitempty,computeDriver"`
|
||||
|
||||
// Rule for VM placement with NUMA affinity.
|
||||
// Possible values - none (placement without NUMA affinity),
|
||||
// strict (strictly with NUMA affinity, if not possible - do not start VM),
|
||||
// loose (use NUMA affinity if possible)
|
||||
// Required: false
|
||||
// Default: none
|
||||
NumaAffinity string `url:"numaAffinity,omitempty" json:"numaAffinity,omitempty" validate:"omitempty,numaAffinity"`
|
||||
|
||||
// Run VM on dedicated CPUs. To use this feature, the system must be pre-configured by allocating CPUs on the physical node
|
||||
// Required: false
|
||||
// Default: false
|
||||
CPUPin bool `url:"cpupin" json:"cpupin"`
|
||||
|
||||
// Use Huge Pages to allocate RAM of the virtual machine. The system must be pre-configured by allocating Huge Pages on the physical node
|
||||
// Required: false
|
||||
// Default: false
|
||||
HPBacked bool `url:"hpBacked" json:"hpBacked"`
|
||||
}
|
||||
|
||||
// GetRAM returns RAM field values
|
||||
|
||||
@@ -28,18 +28,22 @@ type CreateBlankRequest struct {
|
||||
// Required: true
|
||||
RAM uint64 `url:"ram" json:"ram" validate:"required"`
|
||||
|
||||
// If True, the imageId, bootDisk, sepId, pool parameters are ignored and the compute is created without a boot disk in the stopped state
|
||||
// Required: false
|
||||
WithoutBootDisk bool `url:"withoutBootDisk" json:"withoutBootDisk"`
|
||||
|
||||
// Size of the boot disk in GB
|
||||
// Required: true
|
||||
BootDisk uint64 `url:"bootDisk" json:"bootDisk" validate:"required"`
|
||||
// Required: false
|
||||
BootDisk uint64 `url:"bootDisk,omitempty" json:"bootDisk,omitempty"`
|
||||
|
||||
// ID of SEP to create boot disk on.
|
||||
// Uses images SEP ID if not set
|
||||
// Required: true
|
||||
SEPID uint64 `url:"sepId" json:"sepId" validate:"required"`
|
||||
// Required: false
|
||||
SEPID uint64 `url:"sepId,omitempty" json:"sepId,omitempty"`
|
||||
|
||||
// Pool to use if sepId is set, can be also empty if needed to be chosen by system
|
||||
// Required: true
|
||||
Pool string `url:"pool" json:"pool" validate:"required"`
|
||||
// Required: false
|
||||
Pool string `url:"pool,omitempty" json:"pool,omitempty"`
|
||||
|
||||
// Slice of structs with data disk description. Each disk has parameters: required - diskName, size; optional - sepId, pool, desc and imageId.
|
||||
// If not specified, compute will be created without disks.
|
||||
|
||||
@@ -22,10 +22,6 @@ type ListLBRequest struct {
|
||||
// Required: false
|
||||
Name string `url:"name,omitempty" json:"name,omitempty"`
|
||||
|
||||
// Find by account ID
|
||||
// Required: false
|
||||
AccountID uint64 `url:"accountId,omitempty" json:"accountId,omitempty"`
|
||||
|
||||
// Find by tech status
|
||||
// Required: false
|
||||
TechStatus string `url:"techStatus,omitempty" json:"techStatus,omitempty"`
|
||||
|
||||
@@ -14,14 +14,17 @@ type ListRequest struct {
|
||||
// Required: false
|
||||
TaskID string `url:"taskId,omitempty" json:"taskId,omitempty"`
|
||||
|
||||
// Find by auditId
|
||||
// Required: false
|
||||
AuditID string `url:"auditId,omitempty" json:"auditId,omitempty"`
|
||||
|
||||
// Find by status
|
||||
// Required: false
|
||||
Status string `url:"status,omitempty" json:"status,omitempty"`
|
||||
|
||||
// Find by completed True or False
|
||||
// Default: false
|
||||
// Required: false
|
||||
Completed bool `url:"completed" json:"completed"`
|
||||
Completed interface{} `url:"completed,omitempty" json:"completed,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
@@ -29,19 +32,21 @@ type ListRequest struct {
|
||||
|
||||
// Find all tasks after point in time (unixtime)
|
||||
// Required: false
|
||||
UpdateTimeAt uint64 `url:"page,updateTimeAt" json:"updateTimeAt,omitempty"`
|
||||
UpdateTimeAt uint64 `url:"updateTimeAt,omitempty" json:"updateTimeAt,omitempty"`
|
||||
|
||||
// Find all tasks before point in time (unixtime)
|
||||
// Required: false
|
||||
UpdateTimeTo uint64 `url:"page,updateTimeTo" json:"updateTimeTo,omitempty"`
|
||||
UpdateTimeTo uint64 `url:"updateTimeTo,omitempty" json:"updateTimeTo,omitempty"`
|
||||
|
||||
// Page number
|
||||
// Default: 0
|
||||
// Default: 0
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
|
||||
// Page size
|
||||
// Default: 0
|
||||
// Default: 0
|
||||
// Required: false
|
||||
Size uint64 `url:"size,omitempty" json:"size,omitempty"`
|
||||
}
|
||||
@@ -71,6 +76,10 @@ func (t Tasks) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/tasks/list"
|
||||
|
||||
res, err := t.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
|
||||
@@ -30,6 +30,10 @@ type ListDeletedRequest struct {
|
||||
// Required: false
|
||||
ExtIP string `url:"extIp,omitempty" json:"extIp,omitempty"`
|
||||
|
||||
// Find by VNF Device id
|
||||
// Required: false
|
||||
VNFDevID uint64 `url:"vnfdevId,omitempty" json:"vnfdevId,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||
@@ -50,6 +54,10 @@ func (v VINS) ListDeleted(ctx context.Context, req ListDeletedRequest) (*ListVIN
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/vins/listDeleted"
|
||||
|
||||
res, err := v.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
|
||||
@@ -27,7 +27,7 @@ type CreateDiskBackupRequest struct {
|
||||
type wrapperCreateDiskBackupRequest struct {
|
||||
CreateDiskBackupRequest
|
||||
|
||||
Async bool `url:"async"`
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// CreateDiskBackup creates disk backup
|
||||
@@ -39,7 +39,7 @@ func (b Backup) CreateDiskBackup(ctx context.Context, req CreateDiskBackupReques
|
||||
|
||||
reqWrapped := wrapperCreateDiskBackupRequest{
|
||||
CreateDiskBackupRequest: req,
|
||||
Async: false,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudbroker/backup/createDiskBackup"
|
||||
@@ -68,7 +68,7 @@ func (b Backup) CreateDiskBackupAsync(ctx context.Context, req CreateDiskBackupR
|
||||
|
||||
reqWrapped := wrapperCreateDiskBackupRequest{
|
||||
CreateDiskBackupRequest: req,
|
||||
Async: true,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudbroker/backup/createDiskBackup"
|
||||
|
||||
@@ -29,7 +29,7 @@ type CreateDisksBackupRequest struct {
|
||||
type wrapperCreateDisksBackupRequest struct {
|
||||
CreateDisksBackupRequest
|
||||
|
||||
Async bool `url:"async"`
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// CreateDisksBackup creates disks backup
|
||||
@@ -41,7 +41,7 @@ func (b Backup) CreateDisksBackup(ctx context.Context, req CreateDisksBackupRequ
|
||||
|
||||
reqWrapped := wrapperCreateDisksBackupRequest{
|
||||
CreateDisksBackupRequest: req,
|
||||
Async: false,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudbroker/backup/createDisksBackup"
|
||||
@@ -70,7 +70,7 @@ func (b Backup) CreateDisksBackupAsync(ctx context.Context, req CreateDisksBacku
|
||||
|
||||
reqWrapped := wrapperCreateDisksBackupRequest{
|
||||
CreateDisksBackupRequest: req,
|
||||
Async: true,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudbroker/backup/createDisksBackup"
|
||||
|
||||
@@ -21,7 +21,7 @@ type DeleteDiskBackupRequest struct {
|
||||
type wrapperDeleteDiskBackupRequest struct {
|
||||
DeleteDiskBackupRequest
|
||||
|
||||
Async bool `url:"async"`
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// DeleteDiskBackup deletes disk backup
|
||||
@@ -33,7 +33,7 @@ func (b Backup) DeleteDiskBackup(ctx context.Context, req DeleteDiskBackupReques
|
||||
|
||||
reqWrapped := wrapperDeleteDiskBackupRequest{
|
||||
DeleteDiskBackupRequest: req,
|
||||
Async: false,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudbroker/backup/deleteDiskBackup"
|
||||
@@ -60,7 +60,7 @@ func (b Backup) DeleteDiskBackupAsync(ctx context.Context, req DeleteDiskBackupR
|
||||
|
||||
reqWrapped := wrapperDeleteDiskBackupRequest{
|
||||
DeleteDiskBackupRequest: req,
|
||||
Async: true,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudbroker/backup/deleteDiskBackup"
|
||||
|
||||
@@ -27,7 +27,7 @@ type RestoreDiskFromBackupRequest struct {
|
||||
type wrapperRestoreDiskFromBackupRequest struct {
|
||||
RestoreDiskFromBackupRequest
|
||||
|
||||
Async bool `url:"async"`
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// RestoreDiskFromBackup restores disk from backup
|
||||
@@ -39,7 +39,7 @@ func (b Backup) RestoreDiskFromBackup(ctx context.Context, req RestoreDiskFromBa
|
||||
|
||||
reqWrapped := wrapperRestoreDiskFromBackupRequest{
|
||||
RestoreDiskFromBackupRequest: req,
|
||||
Async: false,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudbroker/backup/restoreDiskFromBackup"
|
||||
@@ -68,7 +68,7 @@ func (b Backup) RestoreDiskFromBackupAsync(ctx context.Context, req RestoreDiskF
|
||||
|
||||
reqWrapped := wrapperRestoreDiskFromBackupRequest{
|
||||
RestoreDiskFromBackupRequest: req,
|
||||
Async: true,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudbroker/backup/restoreDiskFromBackup"
|
||||
|
||||
@@ -32,7 +32,7 @@ type RestoreDisksFromBackupRequest struct {
|
||||
type wrapperRestoreDisksFromBackupRequest struct {
|
||||
RestoreDisksFromBackupRequest
|
||||
|
||||
Async bool `url:"async"`
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// RestoreDisksFromBackup restores disks from backup
|
||||
@@ -44,7 +44,7 @@ func (b Backup) RestoreDisksFromBackup(ctx context.Context, req RestoreDisksFrom
|
||||
|
||||
reqWrapped := wrapperRestoreDisksFromBackupRequest{
|
||||
RestoreDisksFromBackupRequest: req,
|
||||
Async: false,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudbroker/backup/restoreDisksFromBackup"
|
||||
@@ -73,7 +73,7 @@ func (b Backup) RestoreDisksFromBackupAsync(ctx context.Context, req RestoreDisk
|
||||
|
||||
reqWrapped := wrapperRestoreDisksFromBackupRequest{
|
||||
RestoreDisksFromBackupRequest: req,
|
||||
Async: true,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudbroker/backup/restoreDisksFromBackup"
|
||||
|
||||
@@ -27,7 +27,7 @@ type CreateTemplateRequest struct {
|
||||
type wrapperCreateTemplateRequest struct {
|
||||
CreateTemplateRequest
|
||||
|
||||
Async bool `url:"async"`
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// CreateTemplateAsync create template from compute instance
|
||||
@@ -39,7 +39,7 @@ func (c Compute) CreateTemplateAsync(ctx context.Context, req CreateTemplateRequ
|
||||
|
||||
reqWrapped := wrapperCreateTemplateRequest{
|
||||
CreateTemplateRequest: req,
|
||||
Async: true,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudbroker/compute/createTemplate"
|
||||
@@ -63,7 +63,7 @@ func (c Compute) CreateTemplate(ctx context.Context, req CreateTemplateRequest)
|
||||
|
||||
reqWrapped := wrapperCreateTemplateRequest{
|
||||
CreateTemplateRequest: req,
|
||||
Async: false,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudbroker/compute/createTemplate"
|
||||
|
||||
@@ -440,7 +440,7 @@ type ItemDisk struct {
|
||||
RealityDeviceNumber uint64 `json:"realityDeviceNumber"`
|
||||
|
||||
// Replication
|
||||
Replication interface{} `json:"replication"`
|
||||
Replication ItemReplication `json:"replication"`
|
||||
|
||||
// Reference ID
|
||||
ReferenceID string `json:"referenceId"`
|
||||
@@ -485,6 +485,26 @@ type ItemDisk struct {
|
||||
VMID uint64 `json:"vmid"`
|
||||
}
|
||||
|
||||
type ItemReplication struct {
|
||||
// DiskID
|
||||
DiskID uint64 `json:"diskId"`
|
||||
|
||||
// PoolID
|
||||
PoolID string `json:"poolId"`
|
||||
|
||||
// Role
|
||||
Role string `json:"role"`
|
||||
|
||||
// SelfVolumeID
|
||||
SelfVolumeID string `json:"selfVolumeId"`
|
||||
|
||||
// StorageID
|
||||
StorageID string `json:"storageId"`
|
||||
|
||||
// VolumeID
|
||||
VolumeID string `json:"volumeId"`
|
||||
}
|
||||
|
||||
// List disks
|
||||
type ListDisks []ItemDisk
|
||||
|
||||
@@ -706,6 +726,9 @@ type InfoCompute struct {
|
||||
// Resource name
|
||||
ResName string `json:"resName"`
|
||||
|
||||
// Reserved Node Cpus
|
||||
ReservedNodeCpus []uint64 `json:"reservedNodeCpus"`
|
||||
|
||||
// Resource group ID
|
||||
RGID uint64 `json:"rgId"`
|
||||
|
||||
@@ -919,6 +942,9 @@ type RecordCompute struct {
|
||||
// Resource name
|
||||
ResName string `json:"resName"`
|
||||
|
||||
// Reserved Node Cpus
|
||||
ReservedNodeCpus []uint64 `json:"reservedNodeCpus"`
|
||||
|
||||
// Resource group ID
|
||||
RGID uint64 `json:"rgId"`
|
||||
|
||||
@@ -1010,6 +1036,7 @@ type ListComputes struct {
|
||||
EntryCount uint64 `json:"entryCount"`
|
||||
}
|
||||
|
||||
// Short information about audit
|
||||
// Short information about audit
|
||||
type ItemAudit struct {
|
||||
// Epoch
|
||||
|
||||
@@ -16,9 +16,10 @@ type NetAttachRequest struct {
|
||||
|
||||
// Network type
|
||||
// 'EXTNET' for connect to external network directly
|
||||
// and 'VINS' for connect to ViNS
|
||||
// 'VINS' for connect to ViNS
|
||||
// 'VFNIC' for connect to vfpool
|
||||
// Required: true
|
||||
NetType string `url:"netType" json:"netType" validate:"computeNetType"`
|
||||
NetType string `url:"netType" json:"netType" validate:"computex86NetType"`
|
||||
|
||||
// Network ID for connect to
|
||||
// For EXTNET - external network ID
|
||||
|
||||
@@ -18,6 +18,11 @@ type StopRequest struct {
|
||||
// Required: false
|
||||
Force bool `url:"force,omitempty" json:"force,omitempty"`
|
||||
|
||||
// whether to depresent compute disks from node or not
|
||||
// Default: true
|
||||
// Required: false
|
||||
Depresent bool `url:"depresent" json:"depresent"`
|
||||
|
||||
// Reason for action
|
||||
// Required: false
|
||||
Reason string `url:"reason,omitempty" json:"reason,omitempty"`
|
||||
|
||||
@@ -22,6 +22,24 @@ type UpdateRequest struct {
|
||||
// Required: false
|
||||
Description string `url:"desc,omitempty" json:"desc,omitempty"`
|
||||
|
||||
// Rule for VM placement with NUMA affinity.
|
||||
// Possible values - none (placement without NUMA affinity),
|
||||
// strict (strictly with NUMA affinity, if not possible - do not start VM),
|
||||
// loose (use NUMA affinity if possible)
|
||||
// Required: false
|
||||
// Default: none
|
||||
NumaAffinity string `url:"numaAffinity,omitempty" json:"numaAffinity,omitempty" validate:"omitempty,numaAffinity"`
|
||||
|
||||
// Run VM on dedicated CPUs. To use this feature, the system must be pre-configured by allocating CPUs on the physical node
|
||||
// Required: false
|
||||
// Default: false
|
||||
CPUPin bool `url:"cpupin" json:"cpupin"`
|
||||
|
||||
// Use Huge Pages to allocate RAM of the virtual machine. The system must be pre-configured by allocating Huge Pages on the physical node
|
||||
// Required: false
|
||||
// Default: false
|
||||
HPBacked bool `url:"hpBacked" json:"hpBacked"`
|
||||
|
||||
// Reason for action
|
||||
// Required: false
|
||||
Reason string `url:"reason,omitempty" json:"reason,omitempty"`
|
||||
|
||||
41
pkg/cloudbroker/disks/depresent.go
Normal file
41
pkg/cloudbroker/disks/depresent.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package disks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// DepresentRequest struct to depresent disk from node
|
||||
type DepresentRequest struct {
|
||||
// ID of the disk to depresent
|
||||
// Required: true
|
||||
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
|
||||
|
||||
// ID of the node to depresent disk from
|
||||
// Required: true
|
||||
NodeID uint64 `url:"nodeId" json:"nodeId" validate:"required"`
|
||||
}
|
||||
|
||||
// Depresent depresents disk from node
|
||||
func (d Disks) Depresent(ctx context.Context, req DepresentRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudbroker/disks/depresent"
|
||||
|
||||
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseBool(string(res))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
@@ -57,7 +57,7 @@ type FromPlatformDiskRequest struct {
|
||||
// List of types of compute suitable for image
|
||||
// Example: [ "KVM_X86" ]
|
||||
// Required: false
|
||||
Drivers []string `url:"drivers" json:"drivers" validate:"min=1,max=2,imageDrivers"`
|
||||
Drivers []string `url:"drivers,omitempty" json:"drivers,omitempty"`
|
||||
|
||||
// Does this machine supports hot resize
|
||||
// Required: false
|
||||
|
||||
@@ -32,7 +32,7 @@ type ListRequest struct {
|
||||
|
||||
// Find by shared, true or false
|
||||
// Required: false
|
||||
Shared bool `url:"shared,omitempty" json:"shared,omitempty"`
|
||||
Shared interface{} `url:"shared,omitempty" json:"shared,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// ID of the account the disks belong to
|
||||
// Required: false
|
||||
|
||||
@@ -28,7 +28,7 @@ type ListDeletedRequest struct {
|
||||
|
||||
// Find by shared, true or false
|
||||
// Required: false
|
||||
Shared bool `url:"shared,omitempty" json:"shared,omitempty"`
|
||||
Shared interface{} `url:"shared,omitempty" json:"shared,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// ID of the account the disks belong to
|
||||
// Required: false
|
||||
|
||||
@@ -138,7 +138,7 @@ type InfoDisk struct {
|
||||
ReferenceID string `json:"referenceId"`
|
||||
|
||||
// Replication
|
||||
Replication interface{} `json:"replication"`
|
||||
Replication ItemReplication `json:"replication"`
|
||||
|
||||
// Resource ID
|
||||
ResID string `json:"resId"`
|
||||
@@ -177,6 +177,26 @@ type InfoDisk struct {
|
||||
VMID uint64 `json:"vmid"`
|
||||
}
|
||||
|
||||
type ItemReplication struct {
|
||||
// DiskID
|
||||
DiskID uint64 `json:"diskId"`
|
||||
|
||||
// PoolID
|
||||
PoolID string `json:"poolId"`
|
||||
|
||||
// Role
|
||||
Role string `json:"role"`
|
||||
|
||||
// SelfVolumeID
|
||||
SelfVolumeID string `json:"selfVolumeId"`
|
||||
|
||||
// StorageID
|
||||
StorageID string `json:"storageId"`
|
||||
|
||||
// VolumeID
|
||||
VolumeID string `json:"volumeId"`
|
||||
}
|
||||
|
||||
// Detailed indormation about disk
|
||||
type RecordDisk struct {
|
||||
// Device name
|
||||
|
||||
41
pkg/cloudbroker/disks/present.go
Normal file
41
pkg/cloudbroker/disks/present.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package disks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// PresentRequest struct to present disk to node
|
||||
type PresentRequest struct {
|
||||
// ID of the disk to present
|
||||
// Required: true
|
||||
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
|
||||
|
||||
// ID of the node to present disk to
|
||||
// Required: true
|
||||
NodeID uint64 `url:"nodeId" json:"nodeId" validate:"required"`
|
||||
}
|
||||
|
||||
// Present presents disk to node
|
||||
func (d Disks) Present(ctx context.Context, req PresentRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudbroker/disks/present"
|
||||
|
||||
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseBool(string(res))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
@@ -15,23 +15,18 @@ type ReplicationStatusRequest struct {
|
||||
}
|
||||
|
||||
// ReplicationStatus get replication status
|
||||
func (d Disks) ReplicationStatus(ctx context.Context, req ReplicationStatusRequest) (interface{}, error) {
|
||||
func (d Disks) ReplicationStatus(ctx context.Context, req ReplicationStatusRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudbroker/disks/replicationStatus"
|
||||
|
||||
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
// result, err := strconv.ParseBool(string(res))
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
return res, nil
|
||||
return string(res), nil
|
||||
}
|
||||
|
||||
@@ -42,6 +42,10 @@ type ListRequest struct {
|
||||
// Required: false
|
||||
ByID uint64 `url:"by_id,omitempty" json:"by_id,omitempty"`
|
||||
|
||||
// Find by list of clientIds
|
||||
// Required: false
|
||||
ClientIDs []uint64 `url:"clientIds,omitempty" json:"clientIds,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||
@@ -88,6 +92,10 @@ func (f FLIPGroup) ListRaw(ctx context.Context, req ListRequest) ([]byte, error)
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudbroker/flipgroup/list"
|
||||
|
||||
res, err := f.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
|
||||
@@ -31,6 +31,7 @@ type ListRequest struct {
|
||||
Size uint64 `url:"size,omitempty" json:"size,omitempty"`
|
||||
|
||||
// Find by active True or False.
|
||||
// Default: true
|
||||
// Required: false
|
||||
Active bool `url:"active" json:"active"`
|
||||
}
|
||||
|
||||
@@ -48,15 +48,15 @@ type ListRequest struct {
|
||||
|
||||
// Find by public True or False
|
||||
// Required: false
|
||||
Public bool `url:"public,omitempty" json:"public,omitempty"`
|
||||
Public interface{} `url:"public,omitempty" json:"public,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// Find by hot resize True or False
|
||||
// Required: false
|
||||
HotResize bool `url:"hotResize,omitempty" json:"hotResize,omitempty"`
|
||||
HotResize interface{} `url:"hotResize,omitempty" json:"hotResize,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// Find by bootable True or False
|
||||
// Required: false
|
||||
Bootable bool `url:"bootable,omitempty" json:"bootable,omitempty"`
|
||||
Bootable interface{} `url:"bootable,omitempty" json:"bootable,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
|
||||
39
pkg/cloudbroker/image/upload_image_file.go
Normal file
39
pkg/cloudbroker/image/upload_image_file.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
// UploadImageFileResponse struct to enable image
|
||||
type UploadImageFileResponse struct {
|
||||
// ImageFileUri
|
||||
ImageFileUri string `json:"image_file_uri"`
|
||||
}
|
||||
|
||||
// UploadImageFile uploads file image to platform
|
||||
func (i Image) UploadImageFile(ctx context.Context, filePath string) (string, error) {
|
||||
file, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("can not read file %v", err)
|
||||
}
|
||||
|
||||
url := "/cloudbroker/image/uploadImageFile"
|
||||
|
||||
res, err := i.client.DecortApiCall(ctx, http.MethodPost, url, file)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
result := UploadImageFileResponse{}
|
||||
|
||||
err = json.Unmarshal(res, &result)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return result.ImageFileUri, nil
|
||||
}
|
||||
@@ -14,7 +14,8 @@ type Interface struct {
|
||||
// Should be one of:
|
||||
// - VINS
|
||||
// - EXTNET
|
||||
NetType string `url:"netType" json:"netType" validate:"required,kvmNetType"`
|
||||
// - VFNIC
|
||||
NetType string `url:"netType" json:"netType" validate:"required,kvmx86NetType"`
|
||||
|
||||
// Network ID for connect to,
|
||||
// for EXTNET - external network ID,
|
||||
@@ -74,10 +75,14 @@ type CreateRequest struct {
|
||||
// Required: true
|
||||
RAM uint64 `url:"ram" json:"ram" validate:"required"`
|
||||
|
||||
// If True, the imageId, bootDisk, sepId, pool parameters are ignored and the compute is created without a boot disk in the stopped state
|
||||
// Required: false
|
||||
WithoutBootDisk bool `url:"withoutBootDisk" json:"withoutBootDisk"`
|
||||
|
||||
// ID of the OS image to base this VM on;
|
||||
// Could be boot disk image or CD-ROM image
|
||||
// Required: true
|
||||
ImageID uint64 `url:"imageId" json:"imageId" validate:"required"`
|
||||
// Required: false
|
||||
ImageID uint64 `url:"imageId,omitempty" json:"imageId,omitempty"`
|
||||
|
||||
// Size of the boot disk in GB
|
||||
// Required: false
|
||||
@@ -136,6 +141,24 @@ type CreateRequest struct {
|
||||
// Required: false
|
||||
Driver string `url:"driver,omitempty" json:"driver,omitempty"`
|
||||
|
||||
// Rule for VM placement with NUMA affinity.
|
||||
// Possible values - none (placement without NUMA affinity),
|
||||
// strict (strictly with NUMA affinity, if not possible - do not start VM),
|
||||
// loose (use NUMA affinity if possible)
|
||||
// Required: false
|
||||
// Default: none
|
||||
NumaAffinity string `url:"numaAffinity,omitempty" json:"numaAffinity,omitempty" validate:"omitempty,numaAffinity"`
|
||||
|
||||
// Run VM on dedicated CPUs. To use this feature, the system must be pre-configured by allocating CPUs on the physical node
|
||||
// Required: false
|
||||
// Default: false
|
||||
CPUPin bool `url:"cpupin" json:"cpupin"`
|
||||
|
||||
// Use Huge Pages to allocate RAM of the virtual machine. The system must be pre-configured by allocating Huge Pages on the physical node
|
||||
// Required: false
|
||||
// Default: false
|
||||
HPBacked bool `url:"hpBacked" json:"hpBacked"`
|
||||
|
||||
// Reason for action
|
||||
// Required: false
|
||||
Reason string `url:"reason,omitempty" json:"reason,omitempty"`
|
||||
|
||||
@@ -28,18 +28,22 @@ type CreateBlankRequest struct {
|
||||
// Required: true
|
||||
RAM uint64 `url:"ram" json:"ram" validate:"required"`
|
||||
|
||||
// If True, the imageId, bootDisk, sepId, pool parameters are ignored and the compute is created without a boot disk in the stopped state
|
||||
// Required: false
|
||||
WithoutBootDisk bool `url:"withoutBootDisk" json:"withoutBootDisk"`
|
||||
|
||||
// Size of the boot disk in GB
|
||||
// Required: true
|
||||
BootDisk uint64 `url:"bootDisk" json:"bootDisk" validate:"required"`
|
||||
// Required: false
|
||||
BootDisk uint64 `url:"bootDisk,omitempty" json:"bootDisk,omitempty"`
|
||||
|
||||
// ID of SEP to create boot disk on.
|
||||
// Uses images SEP ID if not set
|
||||
// Required: true
|
||||
SEPID uint64 `url:"sepId" json:"sepId" validate:"required"`
|
||||
// Required: false
|
||||
SEPID uint64 `url:"sepId,omitempty" json:"sepId,omitempty"`
|
||||
|
||||
// Pool to use if sepId is set, can be also empty if needed to be chosen by system
|
||||
// Required: true
|
||||
Pool string `url:"pool" json:"pool" validate:"required"`
|
||||
// Required: false
|
||||
Pool string `url:"pool,omitempty" json:"pool,omitempty"`
|
||||
|
||||
// Slice of structs with data disk description. Each disk has parameters: required - diskName, size; optional - sepId, pool, desc and imageId.
|
||||
// If not specified, compute will be created without disks.
|
||||
|
||||
@@ -31,9 +31,13 @@ type MassCreateRequest struct {
|
||||
// Required: true
|
||||
RAM uint64 `url:"ram" json:"ram" validate:"required"`
|
||||
|
||||
// Image ID
|
||||
// Required: true
|
||||
ImageID uint64 `url:"imageId" json:"imageId" validate:"required"`
|
||||
// If True, the imageId, bootDisk, sepId, pool parameters are ignored and the compute is created without a boot disk in the stopped state
|
||||
// Required: false
|
||||
WithoutBootDisk bool `url:"withoutBootDisk" json:"withoutBootDisk"`
|
||||
|
||||
// ID of the OS image to base this VM on; Could be boot disk image or CD-ROM image
|
||||
// Required: false
|
||||
ImageID uint64 `url:"imageId,omitempty" json:"imageId,omitempty"`
|
||||
|
||||
// Size of the boot disk in GB
|
||||
// Required: false
|
||||
|
||||
@@ -102,7 +102,7 @@ type ConsumedResourcesInfo struct {
|
||||
// Information about node CPU
|
||||
type CpuInfo struct {
|
||||
// Clock Speed
|
||||
ClockSpeed uint64 `json:"clockSpeed"`
|
||||
ClockSpeed float64 `json:"clockSpeed"`
|
||||
|
||||
// CoreCount
|
||||
CoreCount uint64 `json:"coreCount"`
|
||||
|
||||
@@ -22,10 +22,6 @@ type ListLBRequest struct {
|
||||
// Required: false
|
||||
Name string `url:"name,omitempty" json:"name,omitempty"`
|
||||
|
||||
// Find by account ID
|
||||
// Required: false
|
||||
AccountID uint64 `url:"accountId,omitempty" json:"accountId,omitempty"`
|
||||
|
||||
// Find by tech status
|
||||
// Required: false
|
||||
TechStatus string `url:"techStatus,omitempty" json:"techStatus,omitempty"`
|
||||
|
||||
@@ -14,14 +14,17 @@ type ListRequest struct {
|
||||
// Required: false
|
||||
TaskID string `url:"taskId,omitempty" json:"taskId,omitempty"`
|
||||
|
||||
// Find by auditId
|
||||
// Required: false
|
||||
AuditID string `url:"auditId,omitempty" json:"auditId,omitempty"`
|
||||
|
||||
// Find by status
|
||||
// Required: false
|
||||
Status string `url:"status,omitempty" json:"status,omitempty"`
|
||||
|
||||
// Find by completed True or False
|
||||
// Default: false
|
||||
// Required: false
|
||||
Completed bool `url:"completed" json:"completed"`
|
||||
Completed interface{} `url:"completed,omitempty" json:"completed,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
@@ -29,19 +32,21 @@ type ListRequest struct {
|
||||
|
||||
// Find all tasks after point in time (unixtime)
|
||||
// Required: false
|
||||
UpdateTimeAt uint64 `url:"page,updateTimeAt" json:"updateTimeAt,omitempty"`
|
||||
UpdateTimeAt uint64 `url:"updateTimeAt,omitempty" json:"updateTimeAt,omitempty"`
|
||||
|
||||
// Find all tasks before point in time (unixtime)
|
||||
// Required: false
|
||||
UpdateTimeTo uint64 `url:"page,updateTimeTo" json:"updateTimeTo,omitempty"`
|
||||
UpdateTimeTo uint64 `url:"updateTimeTo,omitempty" json:"updateTimeTo,omitempty"`
|
||||
|
||||
// Page number
|
||||
// Default: 0
|
||||
// Default: 0
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
|
||||
// Page size
|
||||
// Default: 0
|
||||
// Default: 0
|
||||
// Required: false
|
||||
Size uint64 `url:"size,omitempty" json:"size,omitempty"`
|
||||
}
|
||||
|
||||
@@ -16,11 +16,11 @@ type ListRequest struct {
|
||||
|
||||
// Find by active. True or False.
|
||||
// Required: false
|
||||
Active bool `url:"active,omitempty" json:"active,omitempty"`
|
||||
Active interface{} `url:"active,omitempty" json:"active,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// Find by serviceaccount. True or False.
|
||||
// Required: false
|
||||
ServiceAccount bool `url:"serviceaccount,omitempty" json:"serviceaccount,omitempty"`
|
||||
ServiceAccount interface{} `url:"serviceaccount,omitempty" json:"serviceaccount,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
|
||||
@@ -15,8 +15,8 @@ type DNSApplyRequest struct {
|
||||
VINSID uint64 `url:"vinsId" json:"vinsId" validate:"required"`
|
||||
|
||||
// List of DNS ip address
|
||||
// Required: true
|
||||
DNSList []string `url:"dnsList" json:"dnsList" validate:"required"`
|
||||
// Required: false
|
||||
DNSList []string `url:"dnsList" json:"dnsList"`
|
||||
}
|
||||
|
||||
// DNSApply applies new DNS list in VINS
|
||||
|
||||
@@ -30,6 +30,10 @@ type ListRequest struct {
|
||||
// Required: false
|
||||
ExtIP string `url:"extIp,omitempty" json:"extIp,omitempty"`
|
||||
|
||||
// Find by VNF Device id
|
||||
// Required: false
|
||||
VNFDevID uint64 `url:"vnfdevId,omitempty" json:"vnfdevId,omitempty"`
|
||||
|
||||
// Include deleted
|
||||
// Required: false
|
||||
IncludeDeleted bool `url:"includeDeleted,omitempty" json:"includeDeleted,omitempty"`
|
||||
|
||||
@@ -17,7 +17,11 @@
|
||||
|
||||
1. Тесты находятся по директории `decort-sdk/tests/platform_upgrade`
|
||||
2. Внутри директории нужно создать и заполнить файл `.env` по аналогии с `.env.template` для доступа к платформе
|
||||
3. Внутри директории нужно создать и заполнить файл `input.json`, содержащий json с раздела [POST /system/docgenerator/prepareCatalog](https://delta.qa.loc/system/ActorApi?group=system#!/system__docgenerator/post_system_docgenerator_prepareCatalog) (для получения json нажать кнопку Try it Out!) - требуется только для тестов запросов
|
||||
3. Внутри директории нужно создать и заполнить файл `input.json`, содержащий json с раздела [POST /system/docgenerator/prepareCatalog](https://delta.qa.loc/system/ActorApi?group=system#!/system__docgenerator/post_system_docgenerator_prepareCatalog) (для получения json нажать кнопку Try it Out!) - требуется только для тестов запросов и тестов API методов
|
||||
|
||||
Примечание: тесты можно запускать напрямую методами среды разработки либо из командной строки из нужной директории, например командой `go test -v -run <TestName>`, где `<TestName>` - название запускаемого теста.
|
||||
|
||||
Примечание 2: все тесты, кроме `TestGetAllPaths` при первом запуске генерируют фал `.log`. При каждом последующем запуске результаты вывода сравниваются с файлом и в случае, если они одинаковы, то в консоль будет выведено `All lines match the log file.`. В противном случае будут выведены различающиеся строки.
|
||||
|
||||
## Тесты Raw методов (Get, List)
|
||||
|
||||
@@ -90,7 +94,7 @@ FAIL
|
||||
## Тесты API методов
|
||||
|
||||
Запустить тест `TestGetAllPaths` в `decort-sdk/tests/platform_upgrade/cloud_test.go`
|
||||
При наличии подсвеченных ошибок, проверить, что указанные методы API не являются устаревшими (deprecated). В противном случе добавить устаревшие методы в переменную `DEPRECATED_GROUPS` по адресу `decort-sdk/tests/platform_upgrade/utils_url.go`.
|
||||
При наличии подсвеченных ошибок, проверить, что указанные методы API не являются устаревшими (deprecated). В противном случае добавить устаревшие методы в переменную `DEPRECATED_GROUPS` по адресу `decort-sdk/tests/platform_upgrade/utils_url.go`.
|
||||
|
||||
Пример вывода:
|
||||
```go
|
||||
|
||||
@@ -50,13 +50,16 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
t.Fatalf("Cannot get client: %v", err)
|
||||
}
|
||||
|
||||
const logFileName = "test_get_list_cloudAPI.log"
|
||||
var testLogs []string
|
||||
// Account
|
||||
// List
|
||||
bytes, err = client.CloudAPI().Account().ListRaw(context.Background(), account.ListRequest{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Account list", bytes, account.ListAccounts{}, t)
|
||||
|
||||
testLogs = append(testLogs, getResult("Account list", bytes, account.ListAccounts{}, t))
|
||||
// Get
|
||||
listAcc, _ := client.CloudAPI().Account().List(context.Background(), account.ListRequest{})
|
||||
if len(listAcc.Data) > 0 {
|
||||
@@ -65,7 +68,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Account get", bytes, account.RecordAccount{}, t)
|
||||
testLogs = append(testLogs, getResult("Account get", bytes, account.RecordAccount{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test Account get because account list is empty")
|
||||
}
|
||||
@@ -76,7 +79,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Bservice list", bytes, bservice.ListBasicServices{}, t)
|
||||
testLogs = append(testLogs, getResult("Bservice list", bytes, bservice.ListBasicServices{}, t))
|
||||
// Get
|
||||
listBServ, _ := client.CloudAPI().BService().List(context.Background(), bservice.ListRequest{})
|
||||
if len(listBServ.Data) > 0 {
|
||||
@@ -85,7 +88,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Bservice get", bytes, bservice.RecordBasicService{}, t)
|
||||
testLogs = append(testLogs, getResult("Bservice get", bytes, bservice.RecordBasicService{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test Bservice get because bservice list is empty")
|
||||
}
|
||||
@@ -96,7 +99,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Compute list", bytes, compute.ListComputes{}, t)
|
||||
testLogs = append(testLogs, getResult("Compute list", bytes, compute.ListComputes{}, t))
|
||||
// Get
|
||||
listComp, _ := client.CloudAPI().Compute().List(context.Background(), compute.ListRequest{})
|
||||
if len(listComp.Data) > 0 {
|
||||
@@ -105,7 +108,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Compute get", bytes, compute.RecordCompute{}, t)
|
||||
testLogs = append(testLogs, getResult("Compute get", bytes, compute.RecordCompute{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test Compute get because compute list is empty")
|
||||
}
|
||||
@@ -116,7 +119,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Disk list", bytes, disks.ListDisks{}, t)
|
||||
testLogs = append(testLogs, getResult("Disk list", bytes, disks.ListDisks{}, t))
|
||||
// Get
|
||||
listDisk, _ := client.CloudAPI().Disks().List(context.Background(), disks.ListRequest{})
|
||||
if len(listDisk.Data) > 0 {
|
||||
@@ -125,7 +128,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Disk get", bytes, disks.RecordDisk{}, t)
|
||||
testLogs = append(testLogs, getResult("Disk get", bytes, disks.RecordDisk{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test Disk get because disk list is empty")
|
||||
}
|
||||
@@ -136,7 +139,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("ExtNet list", bytes, extnet.ListExtNets{}, t)
|
||||
testLogs = append(testLogs, getResult("ExtNet list", bytes, extnet.ListExtNets{}, t))
|
||||
// Get
|
||||
listExtNet, _ := client.CloudAPI().ExtNet().List(context.Background(), extnet.ListRequest{})
|
||||
if len(listExtNet.Data) > 0 {
|
||||
@@ -145,7 +148,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("ExtNet get", bytes, extnet.RecordExtNet{}, t)
|
||||
testLogs = append(testLogs, getResult("ExtNet get", bytes, extnet.RecordExtNet{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test ExtNet get because listExtNet list is empty")
|
||||
}
|
||||
@@ -156,7 +159,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("FLIPGroup list", bytes, flipgroup.ListFLIPGroups{}, t)
|
||||
testLogs = append(testLogs, getResult("FLIPGroup list", bytes, flipgroup.ListFLIPGroups{}, t))
|
||||
// Get
|
||||
listFG, _ := client.CloudAPI().FLIPGroup().List(context.Background(), flipgroup.ListRequest{})
|
||||
if len(listFG.Data) > 0 {
|
||||
@@ -165,7 +168,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("FLIPGroup get", bytes, flipgroup.RecordFLIPGroup{}, t)
|
||||
testLogs = append(testLogs, getResult("FLIPGroup get", bytes, flipgroup.RecordFLIPGroup{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test FLIPGroup get because flipgroup list is empty")
|
||||
}
|
||||
@@ -176,7 +179,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Image list", bytes, image.ListImages{}, t)
|
||||
testLogs = append(testLogs, getResult("Image list", bytes, image.ListImages{}, t))
|
||||
// Get
|
||||
listImg, _ := client.CloudAPI().Image().List(context.Background(), image.ListRequest{})
|
||||
if len(listImg.Data) > 0 {
|
||||
@@ -185,7 +188,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Image get", bytes, image.RecordImage{}, t)
|
||||
testLogs = append(testLogs, getResult("Image get", bytes, image.RecordImage{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test Image get because Image list is empty")
|
||||
}
|
||||
@@ -196,7 +199,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("K8CI list", bytes, k8ci.ListK8CI{}, t)
|
||||
testLogs = append(testLogs, getResult("K8CI list", bytes, k8ci.ListK8CI{}, t))
|
||||
// Get
|
||||
listk8ci, _ := client.CloudAPI().K8CI().List(context.Background(), k8ci.ListRequest{})
|
||||
if len(listk8ci.Data) > 0 {
|
||||
@@ -205,7 +208,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("K8CI get", bytes, k8ci.RecordK8CI{}, t)
|
||||
testLogs = append(testLogs, getResult("K8CI get", bytes, k8ci.RecordK8CI{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test K8CI get because K8CI list is empty")
|
||||
}
|
||||
@@ -216,7 +219,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("K8S list", bytes, k8s.ListK8SClusters{}, t)
|
||||
testLogs = append(testLogs, getResult("K8S list", bytes, k8s.ListK8SClusters{}, t))
|
||||
// Get
|
||||
listk8s, _ := client.CloudAPI().K8S().List(context.Background(), k8s.ListRequest{})
|
||||
if len(listk8s.Data) > 0 {
|
||||
@@ -225,7 +228,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("K8S get", bytes, k8s.RecordK8S{}, t)
|
||||
testLogs = append(testLogs, getResult("K8S get", bytes, k8s.RecordK8S{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test K8S get because K8S list is empty")
|
||||
}
|
||||
@@ -236,7 +239,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("LB list", bytes, lb.ListLB{}, t)
|
||||
testLogs = append(testLogs, getResult("LB list", bytes, lb.ListLB{}, t))
|
||||
// Get
|
||||
listLB, _ := client.CloudAPI().LB().List(context.Background(), lb.ListRequest{})
|
||||
if len(listLB.Data) > 0 {
|
||||
@@ -245,7 +248,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("LB get", bytes, lb.RecordLB{}, t)
|
||||
testLogs = append(testLogs, getResult("LB get", bytes, lb.RecordLB{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test LB get because LB list is empty")
|
||||
}
|
||||
@@ -256,7 +259,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Locations list", bytes, locations.ListLocations{}, t)
|
||||
testLogs = append(testLogs, getResult("Locations list", bytes, locations.ListLocations{}, t))
|
||||
|
||||
// RG
|
||||
// List
|
||||
@@ -264,7 +267,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("RG list", bytes, rg.ListResourceGroups{}, t)
|
||||
testLogs = append(testLogs, getResult("RG list", bytes, rg.ListResourceGroups{}, t))
|
||||
// Get
|
||||
listRG, _ := client.CloudAPI().RG().List(context.Background(), rg.ListRequest{})
|
||||
if len(listRG.Data) > 0 {
|
||||
@@ -273,7 +276,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("RG get", bytes, rg.RecordResourceGroup{}, t)
|
||||
testLogs = append(testLogs, getResult("RG get", bytes, rg.RecordResourceGroup{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test RG get because RG list is empty")
|
||||
}
|
||||
@@ -284,7 +287,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Sizes list", bytes, sizes.ListSizes{}, t)
|
||||
testLogs = append(testLogs, getResult("Sizes list", bytes, sizes.ListSizes{}, t))
|
||||
|
||||
// Stack
|
||||
// List
|
||||
@@ -292,7 +295,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Stack list", bytes, stack.ListStacks{}, t)
|
||||
testLogs = append(testLogs, getResult("Stack list", bytes, stack.ListStacks{}, t))
|
||||
|
||||
// Tasks
|
||||
// List
|
||||
@@ -300,7 +303,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Tasks list", bytes, tasks.ListTasks{}, t)
|
||||
testLogs = append(testLogs, getResult("Tasks list", bytes, tasks.ListTasks{}, t))
|
||||
// Get
|
||||
listTasks, _ := client.CloudAPI().Tasks().List(context.Background(), tasks.ListRequest{})
|
||||
if len(listTasks.Data) > 0 {
|
||||
@@ -309,7 +312,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Tasks get", bytes, tasks.RecordAsyncTask{}, t)
|
||||
testLogs = append(testLogs, getResult("Tasks get", bytes, tasks.RecordAsyncTask{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test Tasks get because Tasks list is empty")
|
||||
}
|
||||
@@ -320,7 +323,7 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("VINS list", bytes, vins.ListVINS{}, t)
|
||||
testLogs = append(testLogs, getResult("VINS list", bytes, vins.ListVINS{}, t))
|
||||
// Get
|
||||
listVINS, _ := client.CloudAPI().VINS().List(context.Background(), vins.ListRequest{})
|
||||
if len(listVINS.Data) > 0 {
|
||||
@@ -329,10 +332,12 @@ func TestGetListCloudAPI(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("VINS get", bytes, vins.RecordVINS{}, t)
|
||||
testLogs = append(testLogs, getResult("VINS get", bytes, vins.RecordVINS{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test VINS get because VINS list is empty")
|
||||
}
|
||||
|
||||
compareLogs(logFileName, testLogs, t, "get")
|
||||
}
|
||||
|
||||
// WARNING: not working correctly due to inclusions of tagless structures in cloudbroker
|
||||
@@ -345,13 +350,15 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
t.Fatalf("Cannot get client: %v", err)
|
||||
}
|
||||
|
||||
const logFileName = "test_get_list_cloudbroker.log"
|
||||
var testLogs = make([]string, 0)
|
||||
// Account
|
||||
// List
|
||||
bytes, err = client.CloudBroker().Account().ListRaw(context.Background(), account_cb.ListRequest{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Account list", bytes, account_cb.ListAccounts{}, t)
|
||||
testLogs = append(testLogs, getResult("Account list", bytes, account_cb.ListAccounts{}, t))
|
||||
// Get
|
||||
listAcc, _ := client.CloudBroker().Account().List(context.Background(), account_cb.ListRequest{})
|
||||
if len(listAcc.Data) > 0 {
|
||||
@@ -360,7 +367,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Account get", bytes, account_cb.RecordAccount{}, t)
|
||||
testLogs = append(testLogs, getResult("Account get", bytes, account_cb.RecordAccount{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test Account get because account list is empty")
|
||||
}
|
||||
@@ -371,7 +378,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Audit list", bytes, audit_cb.ListAudits{}, t)
|
||||
testLogs = append(testLogs, getResult("Audit list", bytes, audit_cb.ListAudits{}, t))
|
||||
// Get
|
||||
listAudits, _ := client.CloudBroker().Audit().List(context.Background(), audit_cb.ListRequest{})
|
||||
if len(listAudits.Data) > 0 {
|
||||
@@ -380,7 +387,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Audit get", bytes, audit_cb.RecordAudit{}, t)
|
||||
testLogs = append(testLogs, getResult("Audit get", bytes, audit_cb.RecordAudit{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test Audit get because Audit list is empty")
|
||||
}
|
||||
@@ -391,7 +398,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Compute list", bytes, compute_cb.ListComputes{}, t)
|
||||
testLogs = append(testLogs, getResult("Compute list", bytes, compute_cb.ListComputes{}, t))
|
||||
// Get
|
||||
listComp, _ := client.CloudBroker().Compute().List(context.Background(), compute_cb.ListRequest{})
|
||||
if len(listComp.Data) > 0 {
|
||||
@@ -400,7 +407,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Compute get", bytes, compute_cb.RecordCompute{}, t)
|
||||
testLogs = append(testLogs, getResult("Compute get", bytes, compute_cb.RecordCompute{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test Compute get because compute list is empty")
|
||||
}
|
||||
@@ -411,7 +418,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Disk list", bytes, disks_cb.ListDisks{}, t)
|
||||
testLogs = append(testLogs, getResult("Disk list", bytes, disks_cb.ListDisks{}, t))
|
||||
// Get
|
||||
listDisk, _ := client.CloudBroker().Disks().List(context.Background(), disks_cb.ListRequest{})
|
||||
if len(listDisk.Data) > 0 {
|
||||
@@ -420,7 +427,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Disk get", bytes, disks_cb.RecordDisk{}, t)
|
||||
testLogs = append(testLogs, getResult("Disk get", bytes, disks_cb.RecordDisk{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test Disk get because disk list is empty")
|
||||
}
|
||||
@@ -431,7 +438,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("ExtNet list", bytes, extnet_cb.ListExtNet{}, t)
|
||||
testLogs = append(testLogs, getResult("ExtNet list", bytes, extnet_cb.ListExtNet{}, t))
|
||||
// Get
|
||||
listExtNet, _ := client.CloudBroker().ExtNet().List(context.Background(), extnet_cb.ListRequest{})
|
||||
if len(listExtNet.Data) > 0 {
|
||||
@@ -440,7 +447,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("ExtNet get", bytes, extnet_cb.RecordExtNet{}, t)
|
||||
testLogs = append(testLogs, getResult("ExtNet get", bytes, extnet_cb.RecordExtNet{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test ExtNet get because listExtNet list is empty")
|
||||
}
|
||||
@@ -451,7 +458,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("FLIPGroup list", bytes, flipgroup_cb.ListFLIPGroups{}, t)
|
||||
testLogs = append(testLogs, getResult("FLIPGroup list", bytes, flipgroup_cb.ListFLIPGroups{}, t))
|
||||
// Get
|
||||
listFG, _ := client.CloudBroker().FLIPGroup().List(context.Background(), flipgroup_cb.ListRequest{})
|
||||
if len(listFG.Data) > 0 {
|
||||
@@ -460,7 +467,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("FLIPGroup get", bytes, flipgroup_cb.RecordFLIPGroup{}, t)
|
||||
testLogs = append(testLogs, getResult("FLIPGroup get", bytes, flipgroup_cb.RecordFLIPGroup{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test FLIPGroup get because flipgroup list is empty")
|
||||
}
|
||||
@@ -471,7 +478,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Grid list", bytes, grid_cb.ListGrids{}, t)
|
||||
testLogs = append(testLogs, getResult("Grid list", bytes, grid_cb.ListGrids{}, t))
|
||||
// Get
|
||||
listGrid, _ := client.CloudBroker().Grid().List(context.Background(), grid_cb.ListRequest{})
|
||||
if len(listGrid.Data) > 0 {
|
||||
@@ -480,7 +487,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Grid get", bytes, grid_cb.RecordGrid{}, t)
|
||||
testLogs = append(testLogs, getResult("Grid get", bytes, grid_cb.RecordGrid{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test Grid get because Grid list is empty")
|
||||
}
|
||||
@@ -491,7 +498,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Image list", bytes, image_cb.ListImages{}, t)
|
||||
testLogs = append(testLogs, getResult("Image list", bytes, image_cb.ListImages{}, t))
|
||||
// Get
|
||||
listImg, _ := client.CloudBroker().Image().List(context.Background(), image_cb.ListRequest{})
|
||||
if len(listImg.Data) > 0 {
|
||||
@@ -500,7 +507,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Image get", bytes, image_cb.RecordImage{}, t)
|
||||
testLogs = append(testLogs, getResult("Image get", bytes, image_cb.RecordImage{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test Image get because Image list is empty")
|
||||
}
|
||||
@@ -511,7 +518,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("K8CI list", bytes, k8ci_cb.ListK8CI{}, t)
|
||||
testLogs = append(testLogs, getResult("K8CI list", bytes, k8ci_cb.ListK8CI{}, t))
|
||||
// Get
|
||||
listk8ci, _ := client.CloudBroker().K8CI().List(context.Background(), k8ci_cb.ListRequest{})
|
||||
if len(listk8ci.Data) > 0 {
|
||||
@@ -520,7 +527,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("K8CI get", bytes, k8ci_cb.RecordK8CI{}, t)
|
||||
testLogs = append(testLogs, getResult("K8CI get", bytes, k8ci_cb.RecordK8CI{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test K8CI get because K8CI list is empty")
|
||||
}
|
||||
@@ -531,7 +538,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("K8S list", bytes, k8s_cb.ListK8S{}, t)
|
||||
testLogs = append(testLogs, getResult("K8S list", bytes, k8s_cb.ListK8S{}, t))
|
||||
// Get
|
||||
listk8s, _ := client.CloudBroker().K8S().List(context.Background(), k8s_cb.ListRequest{})
|
||||
if len(listk8s.Data) > 0 {
|
||||
@@ -540,7 +547,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("K8S get", bytes, k8s_cb.RecordK8S{}, t)
|
||||
testLogs = append(testLogs, getResult("K8S get", bytes, k8s_cb.RecordK8S{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test K8S get because K8S list is empty")
|
||||
}
|
||||
@@ -551,7 +558,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("LB list", bytes, lb_cb.ListLB{}, t)
|
||||
testLogs = append(testLogs, getResult("LB list", bytes, lb_cb.ListLB{}, t))
|
||||
// Get
|
||||
listLB, _ := client.CloudBroker().LB().List(context.Background(), lb_cb.ListRequest{})
|
||||
if len(listLB.Data) > 0 {
|
||||
@@ -560,7 +567,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("LB get", bytes, lb_cb.RecordLB{}, t)
|
||||
testLogs = append(testLogs, getResult("LB get", bytes, lb_cb.RecordLB{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test LB get because LB list is empty")
|
||||
}
|
||||
@@ -571,7 +578,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Pcidevice list", bytes, pcidevice_cb.ListPCIDevices{}, t)
|
||||
testLogs = append(testLogs, getResult("Pcidevice list", bytes, pcidevice_cb.ListPCIDevices{}, t))
|
||||
|
||||
// RG
|
||||
// List
|
||||
@@ -579,7 +586,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("RG list", bytes, rg_cb.ListRG{}, t)
|
||||
testLogs = append(testLogs, getResult("RG list", bytes, rg_cb.ListRG{}, t))
|
||||
// Get
|
||||
listRG, _ := client.CloudBroker().RG().List(context.Background(), rg_cb.ListRequest{})
|
||||
if len(listRG.Data) > 0 {
|
||||
@@ -588,7 +595,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("RG get", bytes, rg_cb.RecordRG{}, t)
|
||||
testLogs = append(testLogs, getResult("RG get", bytes, rg_cb.RecordRG{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test RG get because RG list is empty")
|
||||
}
|
||||
@@ -599,7 +606,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("SEP list", bytes, sep_cb.ListSEP{}, t)
|
||||
testLogs = append(testLogs, getResult("SEP list", bytes, sep_cb.ListSEP{}, t))
|
||||
// Get
|
||||
listSEP, _ := client.CloudBroker().SEP().List(context.Background(), sep_cb.ListRequest{})
|
||||
if len(listSEP.Data) > 0 {
|
||||
@@ -608,7 +615,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("SEP get", bytes, sep_cb.RecordSEP{}, t)
|
||||
testLogs = append(testLogs, getResult("SEP get", bytes, sep_cb.RecordSEP{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test SEP get because SEP list is empty")
|
||||
}
|
||||
@@ -619,7 +626,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Stack list", bytes, stack_cb.ListStacks{}, t)
|
||||
testLogs = append(testLogs, getResult("Stack list", bytes, stack_cb.ListStacks{}, t))
|
||||
// Get
|
||||
listStack, _ := client.CloudBroker().Stack().List(context.Background(), stack_cb.ListRequest{})
|
||||
if len(listStack.Data) > 0 {
|
||||
@@ -628,7 +635,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Stack get", bytes, stack_cb.InfoStack{}, t)
|
||||
testLogs = append(testLogs, getResult("Stack get", bytes, stack_cb.InfoStack{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test Stack get because Stack list is empty")
|
||||
}
|
||||
@@ -639,7 +646,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("Tasks list", bytes, tasks_cb.ListTasks{}, t)
|
||||
testLogs = append(testLogs, getResult("Tasks list", bytes, tasks_cb.ListTasks{}, t))
|
||||
|
||||
// VINS
|
||||
// List
|
||||
@@ -647,7 +654,7 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("VINS list", bytes, vins_cb.ListVINS{}, t)
|
||||
testLogs = append(testLogs, getResult("VINS list", bytes, vins_cb.ListVINS{}, t))
|
||||
// Get
|
||||
listVINS, _ := client.CloudBroker().VINS().List(context.Background(), vins_cb.ListRequest{})
|
||||
if len(listVINS.Data) > 0 {
|
||||
@@ -656,10 +663,11 @@ func TestGetListCloudbroker(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
getResult("VINS get", bytes, vins_cb.RecordVINS{}, t)
|
||||
testLogs = append(testLogs, getResult("VINS get", bytes, vins_cb.RecordVINS{}, t))
|
||||
} else {
|
||||
t.Errorf("Can not test VINS get because VINS list is empty")
|
||||
}
|
||||
compareLogs(logFileName, testLogs, t, "get")
|
||||
}
|
||||
|
||||
// TestRequestsCloudAPI tests platform requests vs. golang request structures in sdk for cloudapi requests
|
||||
|
||||
@@ -557,6 +557,7 @@ func getRequestsMapCloudbroker() map[string]interface{} {
|
||||
"/cloudbroker/disks/create": disks_cb.CreateRequest{},
|
||||
"/cloudbroker/disks/delete": disks_cb.DeleteRequest{},
|
||||
"/cloudbroker/disks/deleteDisks": disks_cb.DeleteDisksRequest{},
|
||||
"/cloudbroker/disks/depresent": disks_cb.DepresentRequest{},
|
||||
"/cloudbroker/disks/fromPlatformDisk": disks_cb.FromPlatformDiskRequest{},
|
||||
"/cloudbroker/disks/get": disks_cb.GetRequest{},
|
||||
"/cloudbroker/disks/limitIO": disks_cb.LimitIORequest{},
|
||||
@@ -565,6 +566,7 @@ func getRequestsMapCloudbroker() map[string]interface{} {
|
||||
"/cloudbroker/disks/listTypes": disks_cb.ListTypesRequest{},
|
||||
"/cloudbroker/disks/listUnattached": disks_cb.ListUnattachedRequest{},
|
||||
"/cloudbroker/disks/rename": disks_cb.RenameRequest{},
|
||||
"/cloudbroker/disks/present": disks_cb.PresentRequest{},
|
||||
"/cloudbroker/disks/replicate": disks_cb.ReplicateRequest{},
|
||||
"/cloudbroker/disks/replicationResume": disks_cb.ReplicationResumeRequest{},
|
||||
"/cloudbroker/disks/replicationReverse": disks_cb.ReplicationReverseRequest{},
|
||||
|
||||
31
tests/platform_upgrade/test_get_list_cloudAPI.log
Normal file
31
tests/platform_upgrade/test_get_list_cloudAPI.log
Normal file
@@ -0,0 +1,31 @@
|
||||
[
|
||||
"Account list: OK",
|
||||
"Account get: OK",
|
||||
"",
|
||||
"Bservice get: OK",
|
||||
"Compute list: \nPlatform has these fields that golang struct doesn't: [lb mgmt_target mgmt_mac mgmt_slot]\n",
|
||||
"Compute get: \nPlatform has these fields that golang struct doesn't: [mgmt_target mgmt_mac mgmt_slot lb]\n",
|
||||
"Disk list: OK",
|
||||
"Disk get: OK",
|
||||
"",
|
||||
"ExtNet get: OK",
|
||||
"FLIPGroup list: OK",
|
||||
"",
|
||||
"",
|
||||
"Image get: \nPlatform has these fields that golang struct doesn't: [12]\n",
|
||||
"K8CI list: OK",
|
||||
"",
|
||||
"K8S list: OK",
|
||||
"K8S get: OK",
|
||||
"LB list: \nPlatform has these fields that golang struct doesn't: [fs.inotify.max_queued_events kernel.kptr_restrict net.ipv4.tcp_congestion_control]\n",
|
||||
"LB get: \nPlatform has these fields that golang struct doesn't: [kernel.kptr_restrict net.ipv4.tcp_congestion_control fs.inotify.max_queued_events]\n",
|
||||
"Locations list: OK",
|
||||
"RG list: OK",
|
||||
"",
|
||||
"Sizes list: OK",
|
||||
"",
|
||||
"Tasks list: \nPlatform has these fields that golang struct doesn't: [completed guid stage updateTime updatedTime auditId error log status]\n",
|
||||
"Tasks get: \nPlatform has these fields that golang struct doesn't: [updatedTime completed error updateTime auditId stage status log]\n",
|
||||
"",
|
||||
"VINS get: OK"
|
||||
]
|
||||
34
tests/platform_upgrade/test_get_list_cloudbroker.log
Normal file
34
tests/platform_upgrade/test_get_list_cloudbroker.log
Normal file
@@ -0,0 +1,34 @@
|
||||
[
|
||||
"Account list: OK",
|
||||
"Account get: OK",
|
||||
"",
|
||||
"Audit get: OK",
|
||||
"Compute list: \nPlatform has these fields that golang struct doesn't: [disks]\n",
|
||||
"Compute get: OK",
|
||||
"Disk list: \nPlatform has these fields that golang struct doesn't: [machineId machineName sepType devicename]\n",
|
||||
"Disk get: \nPlatform has these fields that golang struct doesn't: [devicename sepType updatedBy]\n",
|
||||
"ExtNet list: OK",
|
||||
"ExtNet get: OK",
|
||||
"FLIPGroup list: OK",
|
||||
"",
|
||||
"Grid list: \nPlatform has these fields that golang struct doesn't: [1 90 380 1 90 380]\n",
|
||||
"Grid get: OK",
|
||||
"Image list: OK",
|
||||
"Image get: OK",
|
||||
"K8CI list: \nPlatform has these fields that golang struct doesn't: [createdTime]\n",
|
||||
"K8CI get: OK",
|
||||
"K8S list: OK",
|
||||
"K8S get: OK",
|
||||
"LB list: OK",
|
||||
"LB get: OK",
|
||||
"Pcidevice list: OK",
|
||||
"RG list: OK",
|
||||
"RG get: OK",
|
||||
"SEP list: \nPlatform has these fields that golang struct doesn't: [protocol disk_max_size format name name_prefix pools]\n",
|
||||
"SEP get: \nPlatform has these fields that golang struct doesn't: [format name name_prefix pools protocol disk_max_size]\n",
|
||||
"Stack list: OK",
|
||||
"Stack get: OK",
|
||||
"Tasks list: \nPlatform has these fields that golang struct doesn't: [stage status error log auditId completed updateTime guid]\n",
|
||||
"",
|
||||
"VINS get: \nPlatform has these fields that golang struct doesn't: [computes config config config]\n"
|
||||
]
|
||||
14
tests/platform_upgrade/test_requests_cloudAPI.log
Normal file
14
tests/platform_upgrade/test_requests_cloudAPI.log
Normal file
@@ -0,0 +1,14 @@
|
||||
[
|
||||
"Path /cloudapi/compute/antiAffinityRuleAdd has following errors: [Field value has different required parameters on the platform and in golang structure]",
|
||||
"Path /cloudapi/user/setData has following errors: [Field data has different required parameters on the platform and in golang structure]",
|
||||
"Path /cloudapi/compute/affinityRuleRemove has following errors: [Field value has different required parameters on the platform and in golang structure]",
|
||||
"Path /cloudapi/compute/createTemplate has following errors: [Platform (3) and golang structure (2) have different amount of fields. Platform has field asyncMode that golang structure doesn't]",
|
||||
"Path /cloudapi/k8s/create has following errors: [Field oidcCertificate has different type parameters on the platform and in golang structure]",
|
||||
"Path /cloudapi/disks/fromPlatformDisk has following errors: [Platform (14) and golang structure (13) have different amount of fields. Field drivers has different type parameters on the platform and in golang structure Platform has field asyncMode that golang structure doesn't]",
|
||||
"Path /cloudapi/compute/affinityRuleAdd has following errors: [Field value has different required parameters on the platform and in golang structure]",
|
||||
"Path /cloudapi/compute/antiAffinityRuleRemove has following errors: [Field value has different required parameters on the platform and in golang structure]",
|
||||
"Path /cloudapi/compute/createTemplateFromBlank has following errors: [Platform (11) and golang structure (10) have different amount of fields. Platform has field asyncMode that golang structure doesn't]",
|
||||
"Path /cloudapi/lb/create has following errors: [Field extnetId has different required parameters on the platform and in golang structure Field vinsId has different required parameters on the platform and in golang structure]",
|
||||
"Path /cloudapi/image/list has following errors: [Field size has different type parameters on the platform and in golang structure]",
|
||||
"Path /cloudapi/compute/snapshotDelete has following errors: [Platform (3) and golang structure (2) have different amount of fields. Platform has field asyncMode that golang structure doesn't]"
|
||||
]
|
||||
1
tests/platform_upgrade/test_requests_cloudbroker.log
Normal file
1
tests/platform_upgrade/test_requests_cloudbroker.log
Normal file
@@ -0,0 +1 @@
|
||||
["Path /cloudbroker/compute/createTemplate has following errors: [Platform (4) and golang structure (3) have different amount of fields. Platform has field asyncMode that golang structure doesn't]","Path /cloudbroker/backup/createDisksBackup has following errors: [Platform (3) and golang structure (2) have different amount of fields. Platform has field asyncMode that golang structure doesn't]","Path /cloudbroker/compute/affinityRuleAdd has following errors: [Field value has different required parameters on the platform and in golang structure]","Path /cloudbroker/apiaccess/update has following errors: [Platform has field apis that golang structure doesn't]","Path /cloudbroker/compute/antiAffinityRuleRemove has following errors: [Field value has different required parameters on the platform and in golang structure]","Path /cloudbroker/compute/snapshotDelete has following errors: [Platform (3) and golang structure (2) have different amount of fields. Platform has field asyncMode that golang structure doesn't]","Path /cloudbroker/backup/restoreDiskFromBackup has following errors: [Platform (5) and golang structure (4) have different amount of fields. Platform has field asyncMode that golang structure doesn't]","Path /cloudbroker/backup/createDiskBackup has following errors: [Platform (4) and golang structure (3) have different amount of fields. Platform has field asyncMode that golang structure doesn't]","Path /cloudbroker/compute/createTemplateFromBlank has following errors: [Platform (11) and golang structure (10) have different amount of fields. Platform has field asyncMode that golang structure doesn't]","Path /cloudbroker/account/setCpuAllocationRatio has following errors: [Field ratio has different required parameters on the platform and in golang structure]","Path /cloudbroker/disks/fromPlatformDisk has following errors: [Platform (14) and golang structure (13) have different amount of fields. Field drivers has different type parameters on the platform and in golang structure Platform has field asyncMode that golang structure doesn't]","Path /cloudbroker/lb/create has following errors: [Field extnetId has different required parameters on the platform and in golang structure Field vinsId has different required parameters on the platform and in golang structure]","Path /cloudbroker/stack/setCpuAllocationRatio has following errors: [Field ratio has different required parameters on the platform and in golang structure]","Path /cloudbroker/backup/deleteDiskBackup has following errors: [Platform (3) and golang structure (2) have different amount of fields. Platform has field asyncMode that golang structure doesn't]","Path /cloudbroker/image/updateNodes has following errors: [Field enabledStacks has different type parameters on the platform and in golang structure]","Path /cloudbroker/stack/setMemAllocationRatio has following errors: [Field ratio has different required parameters on the platform and in golang structure]","Path /cloudbroker/compute/antiAffinityRuleAdd has following errors: [Field value has different required parameters on the platform and in golang structure]","Path /cloudbroker/k8s/create has following errors: [Field oidcCertificate has different type parameters on the platform and in golang structure]","Path /cloudbroker/backup/restoreDisksFromBackup has following errors: [Platform (3) and golang structure (2) have different amount of fields. Platform has field disks that golang structure doesn't Platform has field asyncMode that golang structure doesn't]","Path /cloudbroker/node/enable has following errors: [Platform (4) and golang structure (3) have different amount of fields. Platform has field asyncMode that golang structure doesn't]","Path /cloudbroker/compute/affinityRuleRemove has following errors: [Field value has different required parameters on the platform and in golang structure]","Path /cloudbroker/image/list has following errors: [Field size has different type parameters on the platform and in golang structure]"]
|
||||
@@ -56,7 +56,7 @@ func getClient() (*decort.DecortClient, error) {
|
||||
}
|
||||
|
||||
// getResult checks how json-structure of bytes is different from golang structure and return t.Error if there are any differences.
|
||||
func getResult(testName string, bytes []byte, structure any, t *testing.T) {
|
||||
func getResult(testName string, bytes []byte, structure any, t *testing.T) string {
|
||||
// convert bytes to map[string]interface{}
|
||||
bytesMap, err := GetMapFromBytes(bytes)
|
||||
if err != nil {
|
||||
@@ -68,8 +68,11 @@ func getResult(testName string, bytes []byte, structure any, t *testing.T) {
|
||||
|
||||
// assert if they are equal
|
||||
if !reflect.DeepEqual(bytesMap, structMap) {
|
||||
t.Errorf(getDifference(testName, bytesMap, structMap))
|
||||
var result = getDifference(testName, bytesMap, structMap)
|
||||
t.Errorf(result)
|
||||
return result
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// getDifference tells which fields are present in bytesMap and not present in structMap and vice versa.
|
||||
|
||||
119
tests/platform_upgrade/utils_log.go
Normal file
119
tests/platform_upgrade/utils_log.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func compareLogs(logFileName string, logsData []string, t *testing.T, testType string) {
|
||||
if _, err := os.Stat(logFileName); os.IsNotExist(err) {
|
||||
file, err := os.Create(logFileName)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create log file: %v", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
writer := bufio.NewWriter(file)
|
||||
|
||||
jsonData, err := json.MarshalIndent(logsData, "", " ")
|
||||
if err != nil {
|
||||
t.Errorf("Failed to marshal logsData to JSON: %v", err)
|
||||
}
|
||||
|
||||
_, err = writer.WriteString(string(jsonData))
|
||||
if err != nil {
|
||||
t.Errorf("Failed to write JSON to log file: %v", err)
|
||||
}
|
||||
|
||||
writer.Flush()
|
||||
} else {
|
||||
file, err := os.Open(logFileName)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to open log file: %v", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
reader := bufio.NewReader(file)
|
||||
var sb strings.Builder
|
||||
for {
|
||||
line, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
sb.WriteString(strings.TrimSpace(line))
|
||||
break
|
||||
}
|
||||
t.Errorf("Error reading log file: %v", err)
|
||||
return
|
||||
}
|
||||
sb.WriteString(strings.TrimSpace(line))
|
||||
}
|
||||
|
||||
var fileContent = sb.String()
|
||||
|
||||
var fileLogsData []string
|
||||
err = json.Unmarshal([]byte(fileContent), &fileLogsData)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to unmarshal JSON from log file: %v", err)
|
||||
}
|
||||
|
||||
if len(fileLogsData) != len(logsData) {
|
||||
t.Errorf("Log data length does not match. Got: %d, Expected: %d", len(fileLogsData), len(logsData))
|
||||
}
|
||||
|
||||
var allLinesMatch = true
|
||||
|
||||
switch testType {
|
||||
default:
|
||||
for i := range logsData {
|
||||
if sortBracketsContent(fileLogsData[i]) != sortBracketsContent(logsData[i]) {
|
||||
allLinesMatch = false
|
||||
t.Errorf("Line %d does not match. Got: %s, Expected: %s", i+1, sortBracketsContent(fileLogsData[i]), sortBracketsContent(logsData[i]))
|
||||
}
|
||||
}
|
||||
if allLinesMatch {
|
||||
t.Log("\nAll lines match the log file.")
|
||||
}
|
||||
case "request":
|
||||
var tmp = make(map[string]struct{})
|
||||
for _, v := range fileLogsData {
|
||||
if _, ok := tmp[v]; ok {
|
||||
delete(tmp, v)
|
||||
} else {
|
||||
tmp[v] = struct{}{}
|
||||
}
|
||||
|
||||
}
|
||||
for _, v := range logsData {
|
||||
if _, ok := tmp[v]; ok {
|
||||
delete(tmp, v)
|
||||
} else {
|
||||
tmp[v] = struct{}{}
|
||||
}
|
||||
|
||||
}
|
||||
if len(tmp) == 0 {
|
||||
t.Log("\nAll lines match the log file.")
|
||||
return
|
||||
}
|
||||
for i := range tmp {
|
||||
t.Errorf("Line %s does not match.", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sortBracketsContent(log string) string {
|
||||
re := regexp.MustCompile(`\[([^\[\]]*)\]`)
|
||||
return re.ReplaceAllStringFunc(log, func(match string) string {
|
||||
content := match[1 : len(match)-1]
|
||||
parts := strings.Split(content, " ")
|
||||
sort.Strings(parts)
|
||||
return "[" + strings.Join(parts, " ") + "]"
|
||||
})
|
||||
}
|
||||
@@ -51,16 +51,21 @@ func getBytesFromJSON(fileName string, t *testing.T) []byte {
|
||||
|
||||
func getErrorsFromJSON(bytes []byte, t *testing.T, cloud string) {
|
||||
var requests map[string]interface{}
|
||||
var logFileName string
|
||||
|
||||
switch cloud {
|
||||
case "cloudapi":
|
||||
requests = getRequestsMapCloudAPI()
|
||||
logFileName = "test_requests_cloudAPI.log"
|
||||
case "cloudbroker":
|
||||
requests = getRequestsMapCloudbroker()
|
||||
logFileName = "test_requests_cloudbroker.log"
|
||||
default:
|
||||
t.Fatalf("Wrong cloud provided, expected `cloudapi` or `cloudbroker`, got %s", cloud)
|
||||
}
|
||||
|
||||
var dataLogs []string
|
||||
|
||||
paths, err := getMapFromFile(bytes)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
@@ -131,14 +136,19 @@ func getErrorsFromJSON(bytes []byte, t *testing.T, cloud string) {
|
||||
}
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
t.Errorf("Path %s has following errors: %v", k, errs)
|
||||
msg := fmt.Sprintf("Path %s has following errors: %v", k, errs)
|
||||
t.Error(msg)
|
||||
dataLogs = append(dataLogs, msg)
|
||||
}
|
||||
}
|
||||
|
||||
if len(requests) != i {
|
||||
t.Errorf("Amount of structure checked (%d) is not the same as amount of platform requests available (%d), please check getRequestsMapCloudAPI func in code.",
|
||||
msg := fmt.Sprintf("Amount of structure checked (%d) is not the same as amount of platform requests available (%d), please check getRequestsMapCloudAPI func in code.",
|
||||
i, len(requests))
|
||||
t.Error(msg)
|
||||
dataLogs = append(dataLogs, msg)
|
||||
}
|
||||
compareLogs(logFileName, dataLogs, t, "request")
|
||||
}
|
||||
|
||||
// checkName checks if name field from platform has the same value as json tag in golang structure (maybe including omitempty)
|
||||
@@ -211,8 +221,13 @@ func checkKind(platformType, items string, typ reflect.Type) bool {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
default: // for cases like dataDisks etc.
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
default: // for cases like drivers etc
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
37
universal-client.go
Normal file
37
universal-client.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package decortsdk
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/config"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker"
|
||||
)
|
||||
|
||||
type ClientInterface interface {
|
||||
CloudAPI() *cloudapi.CloudAPI
|
||||
CloudBroker() *cloudbroker.CloudBroker
|
||||
}
|
||||
|
||||
func NewUniversal(cfg config.UniversalConfig) (ClientInterface, error) {
|
||||
countConfigs := 0
|
||||
var client ClientInterface
|
||||
|
||||
switch {
|
||||
case cfg.Decs3oConfig != nil && reflect.TypeOf(*cfg.Decs3oConfig) == reflect.TypeOf(config.Config{}):
|
||||
client = New(*cfg.Decs3oConfig)
|
||||
countConfigs++
|
||||
case cfg.BVSConfig != nil && reflect.TypeOf(*cfg.BVSConfig) == reflect.TypeOf(config.BVSConfig{}):
|
||||
client = NewBVS(*cfg.BVSConfig)
|
||||
countConfigs++
|
||||
case cfg.LegacyConfig != nil && reflect.TypeOf(*cfg.LegacyConfig) == reflect.TypeOf(config.LegacyConfig{}):
|
||||
client = NewLegacy(*cfg.LegacyConfig)
|
||||
countConfigs++
|
||||
}
|
||||
if countConfigs != 1 {
|
||||
return nil, fmt.Errorf("only 1 config can be used at a time")
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
Reference in New Issue
Block a user