diff --git a/CHANGELOG.md b/CHANGELOG.md
index 763d6e9..ec814d5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,27 +1,183 @@
-## Version 1.12.1
+## Version 1.12.2
### Добавлено
+#### общие изменения
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-525 | Поддержка работы с различными сontent-type |
+| BGOS-514 | Пакет SDN со структурой для SDN запросов |
+| BGOS-587 | Проверка срока действия и обновления JWT токена для `DecortClient`, в связи с добавлением срока действия токена |
+
#### account
| Идентификатор
задачи | Описание |
| --- | --- |
-| BGOS-559 | В структуру ответа `RecordACL` добавлено поле `Emails` в cloudapi/account |
+| BGOS-572 | Поля `StoragePolicyIDs` в структуре ответа `RecordAccount` в cloudapi/account и в `InfoAccount` cloudbroker/account |
+| BGOS-572 | Поля `StoragePolicies` в структуре ответа `ResourceLimits` в cloudapi/account и в cloudbroker/account |
+| BGOS-572 | Методы `AddStoragePolicy`, `DelStoragePolicyRequest` и структуры запросов `AddStoragePolicyRequest`, `DelStoragePolicyRequest` в cloudbroker/account |
+| BGOS-572 | Обязательное поле `StoragePolicies` в структуру запроса `CreateRequest` в cloudbroker/account |
+| BGOS-572 | Опциональное поле `StoragePolicies` в структуру запроса `UpdateRequest` в cloudbroker/account |
+| BGOS-585 | Опциональное поле `ZoneID` в структуру запроса `ListRequest` в cloudapi/account и в cloudbroker/account |
+
+#### audit
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-595 | Поле `CorrelationID` в структуры ответа `RecordAudit` в cloudapi/audit и в `RecordAudit` и `ItemAudit` в cloudbroker/audit |
+
+#### bservice
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-576 | Опциональное поле `StoragePolicyID` в структуру запроса `GroupAddRequest` в cloudapi/bservice и в структуру запроса `GroupAddRequest` в cloudbroker/bservice |
+| BGOS-585 | Опциональное поле `ZoneID` в структуру запроса `ListRequest` в cloudapi/bservice и в cloudbroker/bservice |
#### compute
| Идентификатор
задачи | Описание |
| --- | --- |
-| BGOS-566 | Поле `TrunkTags` в структуру `ItemVNFInterface` в структуре ответа `RecordCompute` в cloudapi/compute и в структуру `ItemInterface` в структуре ответа `RecordCompute` в cloudbroker/compute |
-| BGOS-492 | Метод `MigrateAbort` и структура запроса `MigrateAbortRequest` в cloudbroker/compute |
+| BGOS-569 | Опциональные поля `TimestampAT`, `TimestampTO`, `User`, `Call`, `SortBy`, `Page`, `Size`, `MinStatusCode`, `MaxStatusCode` в структуру запроса `AuditsRequest` в cloudapi/compute и в cloudbroker/compute |
+| BGOS-575 | Обязательное поле `StoragePolicyID` в структуру запроса `CreateTemplateFromBlankRequest`, `DiskAddRequest`, `RedeployRequest` в cloudapi/compute и в cloudbroker/compute |
+| BGOS-575 | Поле `StoragePolicyID` в структуру ответа `ItemComputeDisk` в cloudapi/compute и в структуру ответа `ItemDisk` в cloudbroker/compute |
+| BGOS-580 | Поле `ZoneID` в структуру ответа `ItemCompute` в cloudapi/compute |
+| BGOS-583 | Опциональные поля `SecGroups`, `EnableSecGroups` в структуру запроса `NetAttachRequest` в cloudapi/compute и в cloudbroker/compute |
+| BGOS-583 | Поля `SecGroups`, `EnableSecGroups` в структуру ответа `ItemVNFInterface` в cloudapi/compute и в `ItemInterface` cloudbroker/compute |
+| BGOS-585 | Опциональное поле `ZoneID` в структуру запроса `ListRequest` в cloudapi/compute и в cloudbroker/compute |
+| BGOS-592 | Опциональное поле `Enabled` в структуру запроса `NetAttachRequest` в cloudapi/compute и в cloudbroker/compute |
+| BGOS-593 | Поле `ToClean` в структурах ответа `ItemComputeDisk` в cloudapi/compute и `ItemDisk` cloudbroker/compute |
+
+#### disks
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-574 | Поля `StoragePolicyID` в структуры ответа `RecordDisk` и `ItemDisk` в cloudapi/disks и в `InfoDisk` cloudbroker/disks |
+| BGOS-574 | Метод `ChangeDiskStoragePolicy` и структура запроса `ChangeDiskStoragePolicyRequest` в cloudapi/disks и в cloudbroker/disks |
+| BGOS-574 | Обязательное поле `StoragePolicyID` в структуры запроса `CreateRequest` и `ReplicateRequest` в cloudapi/disks и в cloudbroker/disks |
+| BGOS-593 | Поле `ToClean` в структурах ответа `ItemDisk`, `RecordDisk` в cloudapi/disks и `InfoDisk` cloudbroker/disks |
+
+#### dpdknet
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-584 | Опциональное поле `EnableSecGroups` в структуру запроса `UpdateRequest` в cloudbroker/dpdknet |
+| BGOS-584 | Поле `EnableSecGroups` в структуры ответа `ItemDPDKNet`, `RecordDPDKNet` в cloudapi/dpdknet и в cloudbroker/dpdknet |
+
+#### extnet
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-585 | Опциональное поле `ZoneID` в структуру запроса `ListRequest` в cloudapi/extnet и в cloudbroker/extnet |
+| BGOS-584 | Опциональное поле `EnableSecGroups` в структуру запроса `UpdateRequest` в cloudbroker/extnet |
+| BGOS-584 | Поле `EnableSecGroups` в структуру ответа `ItemExtNet` в cloudbroker/extnet |
+| BGOS-584 | Поле `EnableSecGroups` в структуру ответа `RecordExtNet` в cloudapi/extnet и в cloudbroker/extnet |
+
+#### image
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-578 | Обязательное поле `StoragePolicyID` в структуру запроса `CreateRequest` в cloudapi/image и в структуры запроса `CreateRequest` и `CreateCDROMImageRequest` в cloudbroker/image |
+| BGOS-578 | Поле `StoragePolicyID` в структуру ответа `RecordImage` в cloudapi/image и в структуры ответа `RecordImage` и `ItemImage` в cloudbroker/image |
+| BGOS-578 | Метод `ChangeStoragePolicy` и структура запроса `ChangeStoragePolicyRequest` в cloudapi/image и в cloudbroker/image |
+
+#### k8s
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-577 | Обязательное поле `StoragePolicyID` в структуры запроса `CreateRequest` и `WorkersGroupAddRequest` в cloudapi/k8s и в структуры запроса `CreateRequest` и `WorkersGroupAddRequest` в cloudbroker/k8s |
+| BGOS-585 | Опциональное поле `ZoneID` в структуру запроса `ListRequest` в cloudapi/k8s и в cloudbroker/k8s |
+
+#### kvmx86
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-575 | Обязательное поле `StoragePolicyID` в структуры запросов `CreateRequest`, `DataDisk`, `CreateBlankRequest` в cloudapi/kvmx86 и cloudbroker/kvmx86 и `MassCreateRequest` в cloudbroker/kvmx86 |
+| BGOS-583 | Опциональные поля `SecGroups`, `EnableSecGroups` в структуру запроса `Interface` в cloudapi/kvmx86 и в cloudbroker/kvmx86 |
+| BGOS-592 | Опциональное поле `Enabled` в структуру запроса `Interface` в cloudapi/kvmx86 и в cloudbroker/kvmx86 |
+
+#### lb
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-585 | Опциональное поле `ZoneID` в структуру запроса `ListRequest` в cloudapi/lb и в cloudbroker/lb |
+
+#### node
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-597 | Поле `VCPU` в структуру ответа `FreeResourcesInfo` в cloudbroker/node |
+
+#### rg
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-573 | Поля `StoragePolicyIDs` в структуре ответа `RecordResourceGroup` в cloudapi/rg и в `ItemRG` cloudbroker/rg |
+| BGOS-573 | Поля `StoragePolicies` в структуре ответа `ResourceLimits` в cloudapi/rg и в cloudbroker/rg |
+| BGOS-573 | Методы `AddStoragePolicy`, `DelStoragePolicyRequest` и структуры запросов `AddStoragePolicyRequest`, `DelStoragePolicyRequest` в cloudbroker/rg |
+| BGOS-573 | Опциональное поле `StoragePolicies` в структуры запроса `CreateRequest`, `UpdateRequest` в cloudapi/rg и в cloudbroker/rg |
+
+#### security group
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-582 | Группа ручек `security_group` в cloudapi и в cloudbroker |
+
+#### storage policy
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-571 | Группа ручек `storage_policy` в cloudapi и в cloudbroker |
+
+#### trunk
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-565 | Опциональное поле `Status` в структуру запроса `ListRequest` в cloudapi/trunk и в cloudbroker/trunk |
+
+#### user
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-562 | Опциональное поле `AccountID` в структуру запроса `CreateVirtualRequest` в cloudapi/image и в cloudbroker/image |
+
+#### vins
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-584 | Метод `Update` и структура запроса `UpdateRequest` в cloudbroker/vins |
+| BGOS-584 | Поле `EnableSecGroups` в структуру ответа `ItemVINS` в cloudbroker/vins |
+| BGOS-584 | Поле `EnableSecGroups` в структуру ответа `RecordVINS` в cloudapi/vins и в cloudbroker/vins |
+
+#### SDN access groups
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-514 | Группа api access_groups |
### Исправлено
-#### accounts
+#### compute
| Идентификатор
задачи | Описание |
| --- | --- |
-| BGOS-559 | Структура ответа `ItemAccount` использует структуру `ListRecordACL` в поле `ACL` в cloudapi/account |
+| BGOS-569 | Изменена структура ответа с `ListAudits` на `*ListAudits`, содержащую поля `Data` и `EntryCount` в методе `Audits` в cloudapi/compute |
+| BGOS-569 | Изменена структура ответа с `ListDetailedAudits` на `*ListDetailedAudits`, содержащую поля `Data` и `EntryCount` в методе `Audits` в cloudbroker/compute |
+
+#### user
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-561 | Изменен тип поля `UserIDs` с stirng на []string в структуре запроса `DeleteUsersRequest` в cloudbroker/user |
+
+#### vins
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-560 | Изменен тип возвращаемого значения методов `MassDelete`, `MassDisable`, `MassEnable` c bool на string в cloudbroker/vins|
+
+### Удалено
+
+#### disks
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-563 | Опциональное поле `Drivers` в структуре запроса `FromPlatformDiskRequest` в cloudapi/disks и cloudbroker/disks |
+
+#### compute
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-580 | Поле `ZoneID` в структуре ответа `ItemComputeDisk` в cloudapi/compute |
#### image
| Идентификатор
задачи | Описание |
| --- | --- |
-| BGOS-564 | Загрузка образов в cloudbroker/image |
+| BGOS-563 | Опциональное поле `Drivers` в структуре запроса `CreateRequest` в cloudapi/image и cloudbroker/image |
+| BGOS-563 | Опциональное поле `Drivers` в структуре запроса `CreateCDROMImageRequest` в cloudbroker/image |
+#### k8ci
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-563 | Опциональные поля `MasterDriver` и `WorkerDriver` в структурах запроса `ListRequest` и `ListDeletedRequest` в cloudapi/k8ci и cloudbroker/k8ci |
+| BGOS-563 | Опциональные поля `MasterDriver` и `WorkerDriver` в структуре запроса `CreateRequest` в cloudbroker/k8ci |
+
+#### kvmx86
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BGOS-563 | Опциональное поле `Driver` в структурах запроса `CreateRequest` и `CreateBlankRequest` в cloudapi/kvmx86 и cloudbroker/kvmx86 |
\ No newline at end of file
diff --git a/README.md b/README.md
index ce6b218..cdc5fed 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,3 @@
-# Внимание
-Данная версия предназначена только для версии платформы 4.4.0 build 963!
-
# Decort SDK
Decort SDK - это библиотека, написанная на языке GO, позволяющая взаимодействовать с API облачной платформы **DECORT**. Библиотека содержит в себе структуры и методы, необходимые для отправки запросов. Decort SDK имеет встроенный http-клиент и поддерживает разные способы авторизации на платформе. Библиотека так же содержит в себе модели ответов от платформы.
@@ -100,6 +97,7 @@ go get -u repository.basistech.ru/BASIS/decort-golang-sdk
- `cloudapi` - пользовательская группа, которая позволяет воспользоваться всем стардартным функционалом платформы;
- `cloudbroker` - административная группа, которая позволяет воспользоваться всем стандартным функционалом платформы и расширенными возможностями, включающими в себя управление пользователями, ресурсами, платформами размещения ресурсов и т.д.
+- `sdn` - группа для работы с SDN;
### Cloudapi
@@ -122,8 +120,10 @@ go get -u repository.basistech.ru/BASIS/decort-golang-sdk
- `Locations` - получение информации о grid площадки;
- `Prometheus` - получение статистики prometheus;
- `RG` - управление ресурсными группами аккаунта;
+- `Security group` – управление группами безопасности;
- `SEP` - управление storage endpoint (sep);
- `Stack` - получение информации о вычислительных узлах;
+- `Storage policy` – получение информации о политиках хранения;
- `Tasks` - получение информации о ходе выполнения асинхронных задач (например, создание кластера);
- `Trunk` - получение информации о транковых портах;
- `VFPool` - управление пулом виртуальных сетевых функций;
@@ -157,8 +157,10 @@ go get -u repository.basistech.ru/BASIS/decort-golang-sdk
- `Prometheus` - получение статистики prometheus;
- `Resmon` - получение статистики resource monitoring;
- `RG` - управление ресурсными группами аккаунта;
+- `Security group` – управление группами безопасности;
- `SEP` - управление storage endpoint (sep);
- `Stack` - получение информации о вычислительных узлах;
+- `Storage policy` – управление политиками хранения;
- `Tasks` - получение информации о ходе выполнения асинхронных задач (например, создание кластера);
- `Trunk` - управление транковыми портами;
- `User` - управление пользователями (индивидуально);
@@ -167,6 +169,13 @@ go get -u repository.basistech.ru/BASIS/decort-golang-sdk
- `VINS` - управление виртуальными изолированными сетями.
- `Zone` - управление зонами.
+### SDN
+
+`SDN` позволяет выполнять запросы к группе пользовательских конечных точек
+Данная группа ручек позволяет выполнять следующие операции в платформе:
+
+- `AccessGroup` - управление группами доступа
+
## Работа с библиотекой
Алгоритм работы с библиотекой выглядит следующим образом:
@@ -293,6 +302,7 @@ func main() {
- `pkg/cloudapi` - для `cloudapi`
- `pkg/cloudbroker` - для `cloudbroker`
+- `pkg/sdn` - для `sdn`
В каждом пакете находятся пакеты групп API:
@@ -313,8 +323,10 @@ func main() {
- `pkg/cloudapi/locations` - для `Locations`
- `pkg/cloudapi/prometheus` - для `Prometheus`
- `pkg/cloudapi/rg` - для `RG`
+ - `pkg/cloudapi/security_group` - для `Security group`
- `pkg/cloudapi/sep` - для `SEP`
- `pkg/cloudapi/stack` - для `Stack`
+ - `pkg/cloudapi/storage_policy` - для `Storage policy`
- `pkg/cloudapi/tasks` - для `Tasks`
- `pkg/cloudapi/trunk` - для `Trunk`
- `pkg/cloudapi/vfpool` - для `VFPool`
@@ -343,8 +355,10 @@ func main() {
- `pkg/cloudbroker/prometheus` - для `Prometheus`
- `pkg/cloudbroker/resmon` - для `Resmon`
- `pkg/cloudbroker/rg` - для `RG`
+ - `pkg/cloudbroker/security_group` - для `Security group`
- `pkg/cloudbroker/sep` - для `SEP`
- `pkg/cloudbroker/stack` - для `Stack`
+ - `pkg/cloudbroker/storage_policy` - для `Storage policy`
- `pkg/cloudbroker/tasks` - для `Tasks`
- `pkg/cloudbroker/trunk` - для `Trunk`
- `pkg/cloudbroker/user` - для `User`
@@ -352,6 +366,8 @@ func main() {
- `pkg/cloudbroker/vfpool` - для `VFPool`
- `pkg/cloudbroker/vins` - для `VINS`
- `pkg/cloudbroker/zone` - для `Zone`
+ - **sdn**:
+ - `pkg/sdn/access_groups` - для `AccessGroups`
Все поля структуры имеют описание, в которых содержится:
@@ -485,7 +501,7 @@ func main() {
Чтобы выполнить запрос, необходимо:
-1. Вызвать у клиента метод, отвечаеющий за определение группы API для взаимодействия, это может быть `.CloudAPI()`, либо `.CloudBroker()`. Данные методы возвращаеют соответствующие структуры, с помощью которых можно совершать запросы.
+1. Вызвать у клиента метод, отвечающий за определение группы API для взаимодействия, это может быть `.CloudAPI()`, `.CloudBroker()` или `.SDN()`. Данные методы возвращают соответствующие структуры, с помощью которых можно совершать запросы.
2. Вызвать у возвращенной структуры метод, определяющий группу ручек для взаимодействия.
Доступные методы для `.CloudAPI()`:
@@ -506,8 +522,10 @@ func main() {
- `.Locations()` - для работы с `Locations`
- `.Prometheus()` - для работы с `Prometheus`
- `.RG()` - для работы с `RG`
+ - `.SecurityGroup()` - для работы с `Security Group`
- `.SEP()` - для работы с `SEP`
- `.Stack()` - для работы с `Stack`
+ - `.StoragePolicy()` - для работы с `Storage Policy`
- `.Tasks()` - для работы с `Tasks`
- `.Trunk()` - для работы с `Trunk`
- `.VFPool()` - для работы с `VFPool`
@@ -538,8 +556,10 @@ func main() {
- `.Prometheus()` - для работы с `Prometheus`
- `.Resmon()` - для работы с `Resmon`
- `.RG()` - для работы с `RG`
+ - `.SecurityGroup()` - для работы с `Security Group`
- `.SEP()` - для работы с `SEP`
- `.Stack()` - для работы с `Stack`
+ - `.StoragePolicy()` - для работы с `Storage Policy`
- `.Tasks()` - для работы с `Tasks`
- `.Trunk()` - для работы с `Trunk`
- `.User()` - для работы с `User`
@@ -548,6 +568,10 @@ func main() {
- `.VINS()` - для работы с `VINS`
- `.Zone()` - для работы с `Zone`
+ Доступные методы для `.SDN()`:
+
+ - `.AccessGroup()` - для работы с `AccessGroup`
+
3. Вызвать метод, отвечающий за выполнение запроса и передать в него:
- контекст;
diff --git a/client.go b/client.go
index e0df530..d68e035 100644
--- a/client.go
+++ b/client.go
@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"crypto/tls"
+ "encoding/base64"
"encoding/json"
"fmt"
"io"
@@ -21,6 +22,7 @@ import (
"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"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn"
)
// DecortClient is HTTP-client for platform
@@ -38,12 +40,6 @@ func New(cfg config.Config) *DecortClient {
cfg.Retries = 5
}
- var expiryTime time.Time
-
- if cfg.Token != "" {
- expiryTime = time.Now().AddDate(0, 0, 1)
- }
-
return &DecortClient{
decortURL: cfg.DecortURL,
client: &http.Client{
@@ -54,9 +50,8 @@ func New(cfg config.Config) *DecortClient {
},
},
},
- cfg: trimConfig(&cfg),
- expiryTime: expiryTime,
- mutex: &sync.Mutex{},
+ cfg: trimConfig(&cfg),
+ mutex: &sync.Mutex{},
}
}
@@ -70,6 +65,11 @@ func (dc *DecortClient) CloudBroker() *cloudbroker.CloudBroker {
return cloudbroker.New(dc)
}
+// SDN builder
+func (dc *DecortClient) SDN() *sdn.SDN {
+ return sdn.New(dc)
+}
+
// DecortApiCall method for sending requests to the platform
func (dc *DecortClient) DecortApiCall(ctx context.Context, method, url string, params interface{}) ([]byte, error) {
@@ -107,6 +107,47 @@ func (dc *DecortClient) DecortApiCall(ctx context.Context, method, url string, p
return respBytes, err
}
+// DecortApiCallCtype method for sending requests to the platform with content type
+func (dc *DecortClient) DecortApiCallCtype(ctx context.Context, method, url, ctype string, params interface{}) ([]byte, error) {
+
+ var body *bytes.Buffer
+
+ switch ctype {
+ case constants.MIMESTREAM:
+ body = bytes.NewBuffer(params.([]byte))
+ case constants.MIMEJSON:
+ jsonBody, err := json.Marshal(params)
+ if err != nil {
+ return nil, err
+ }
+ body = bytes.NewBuffer(jsonBody)
+ default:
+ ctype = constants.MIMEPOSTForm
+ 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 {
+ return nil, err
+ }
+
+ // get token
+ if err = dc.getToken(ctx); err != nil {
+ return nil, err
+ }
+ // perform request
+ respBytes, err := dc.do(req, ctype)
+ if err != nil {
+ return nil, err
+ }
+
+ return respBytes, err
+}
+
// DecortApiCallMP method for sending requests to the platform
func (dc *DecortClient) DecortApiCallMP(ctx context.Context, method, url string, params interface{}) ([]byte, error) {
body, ctype, err := multiPartReq(params)
@@ -170,8 +211,13 @@ func (dc *DecortClient) getToken(ctx context.Context) error {
// save token in config
token := string(tokenBytes)
+ expiryTime, err := getTokenExp(token)
+ if err != nil {
+ return fmt.Errorf("cannot get expiry time: %w", err)
+ }
+
dc.cfg.Token = token
- dc.expiryTime = time.Now().AddDate(0, 0, 1)
+ dc.expiryTime = expiryTime
return nil
}
@@ -375,3 +421,29 @@ func trimConfig(cfg *config.Config) config.Config {
cfg.DecortURL = strings.TrimSuffix(cfg.DecortURL, "/")
return *cfg
}
+
+func getTokenExp(token string) (time.Time, error) {
+ parts := strings.Split(token, ".")
+ if len(parts) != 3 {
+ return time.Time{}, fmt.Errorf("invalid token format")
+ }
+
+ payload, err := base64.RawURLEncoding.DecodeString(parts[1])
+ if err != nil {
+ return time.Time{}, fmt.Errorf("error decode payload from token: %w", err)
+ }
+
+ var claims map[string]interface{}
+ if err := json.Unmarshal(payload, &claims); err != nil {
+ return time.Time{}, err
+ }
+
+ exp, ok := claims["exp"]
+ if !ok {
+ return time.Time{}, fmt.Errorf("exp time bot found")
+ }
+
+ expTime := time.Unix(int64(exp.(float64)), 0)
+
+ return expTime, nil
+}
diff --git a/client_bvs.go b/client_bvs.go
index 347d273..31c2cb1 100644
--- a/client_bvs.go
+++ b/client_bvs.go
@@ -131,6 +131,72 @@ func (bdc *BVSDecortClient) DecortApiCall(ctx context.Context, method, url strin
return respBytes, err
}
+// DecortApiCallCtype method for sending requests to the platform with content type
+func (bdc *BVSDecortClient) DecortApiCallCtype(ctx context.Context, method, url, ctype string, params interface{}) ([]byte, error) {
+ var body *bytes.Buffer
+
+ switch ctype {
+ case constants.MIMESTREAM:
+ body = bytes.NewBuffer(params.([]byte))
+ case constants.MIMEJSON:
+ jsonBody, err := json.Marshal(params)
+ if err != nil {
+ return nil, err
+ }
+ body = bytes.NewBuffer(jsonBody)
+ default:
+ ctype = constants.MIMEPOSTForm
+ 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 {
+ return nil, err
+ }
+
+ // get token
+ if bdc.cfg.Token.AccessToken == "" {
+ if _, err = bdc.GetToken(ctx); err != nil {
+ return nil, err
+ }
+ }
+
+ // refresh token
+ if bdc.cfg.Token.RefreshToken != "" && bdc.cfg.Token.Expiry.Add(-time.Duration(bdc.cfg.TimeToRefresh)*time.Minute).Before(time.Now()) {
+ if _, err := bdc.RefreshToken(ctx); err != nil {
+ if _, err = bdc.GetToken(ctx); err != nil {
+ return nil, err
+ }
+ }
+ }
+
+ // perform request
+ reqCopy := req.Clone(ctx)
+ respBytes, err := bdc.do(req, ctype)
+ if err == nil {
+ return respBytes, nil
+ }
+
+ // get token and retry in case of access denied
+ if err.Error() == "access is denied" {
+ _, err = bdc.GetToken(ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ respBytes, err = bdc.do(reqCopy, "")
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return respBytes, err
+}
+
func (bdc *BVSDecortClient) DecortApiCallMP(ctx context.Context, method, url string, params interface{}) ([]byte, error) {
body, ctype, err := multiPartReq(params)
if err != nil {
diff --git a/interfaces/caller.go b/interfaces/caller.go
index c40b0ba..026ac22 100644
--- a/interfaces/caller.go
+++ b/interfaces/caller.go
@@ -7,6 +7,9 @@ type Caller interface {
// DecortApiCall method for sending requests to the platform
DecortApiCall(ctx context.Context, method, url string, params interface{}) ([]byte, error)
+ // DecortApiCallCtype method for sending requests to the platform
+ DecortApiCallCtype(ctx context.Context, method, url, ctype string, params interface{}) ([]byte, error)
+
// DecortApiCallMP method for sending requests to the platform
DecortApiCallMP(ctx context.Context, method, url string, params interface{}) ([]byte, error)
}
diff --git a/internal/constants/constants.go b/internal/constants/constants.go
index 4ebc2e3..831511b 100644
--- a/internal/constants/constants.go
+++ b/internal/constants/constants.go
@@ -2,9 +2,23 @@ package constants
const (
RESTMACHINE = "/restmachine"
+)
- // RAM_DIVISIBILITY sets divisibility of RAM value
- RAM_DIVISIBILITY uint64 = 128
+const (
+ MIMEJSON = "application/json"
+ MIMEHTML = "text/html"
+ MIMEXML = "application/xml"
+ MIMEXML2 = "text/xml"
+ MIMEPlain = "text/plain"
+ MIMEPOSTForm = "application/x-www-form-urlencoded"
+ MIMEMultipartPOSTForm = "multipart/form-data"
+ MIMEPROTOBUF = "application/x-protobuf"
+ MIMEMSGPACK = "application/x-msgpack"
+ MIMEMSGPACK2 = "application/msgpack"
+ MIMEYAML = "application/x-yaml"
+ MIMEYAML2 = "application/yaml"
+ MIMETOML = "application/toml"
+ MIMESTREAM = "application/octet-stream"
)
var FileName = map[string]string{
diff --git a/internal/validators/custom.go b/internal/validators/custom.go
index b8d9306..13a0ace 100644
--- a/internal/validators/custom.go
+++ b/internal/validators/custom.go
@@ -14,13 +14,6 @@ import (
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/multierror"
)
-// computeDriverValidator is used to validate Driver field in kvmx86 create.
-func computeDriverValidator(fe validator.FieldLevel) bool {
- fieldValue := fe.Field().String()
-
- return IsInSlice(fieldValue, computeDriverValues)
-}
-
// protoValidator is used to validate Proto fields.
func protoValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
@@ -58,13 +51,6 @@ func resTypesValidator(fe validator.FieldLevel) bool {
return true
}
-// driverValidator is used to validate Driver fields.
-func driverValidator(fe validator.FieldLevel) bool {
- fieldValue := fe.Field().String()
-
- return IsInSlice(fieldValue, driverValues)
-}
-
// accountCUTypeValidator is used to validate CUType field.
func accountCUTypeValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
@@ -121,6 +107,27 @@ func computex86NetTypeValidator(fe validator.FieldLevel) bool {
return IsInSlice(fieldValue, computex86NetTypeValues)
}
+// securityGroupDirectionValidator is used to validate Direction field
+func securityGroupDirectionValidator(fe validator.FieldLevel) bool {
+ fieldValue := fe.Field().String()
+
+ return IsInSlice(fieldValue, securityGroupDirectionValues)
+}
+
+// securityGroupEthertypeValidator is used to validate Ethertype field
+func securityGroupEthertypeValidator(fe validator.FieldLevel) bool {
+ fieldValue := fe.Field().String()
+
+ return IsInSlice(fieldValue, securityGroupEthertypeValues)
+}
+
+// securityGroupProtocolValidator is used to validate Protocol field
+func securityGroupProtocolValidator(fe validator.FieldLevel) bool {
+ fieldValue := fe.Field().String()
+
+ return IsInSlice(fieldValue, securityGroupProtocolValues)
+}
+
// computeOrderValidator is used to validate Order field.
func computeOrderValidator(fe validator.FieldLevel) bool {
fieldSlice, ok := fe.Field().Interface().([]string)
@@ -207,22 +214,6 @@ func imageTypeValidator(fe validator.FieldLevel) bool {
return IsInSlice(fieldValue, imageTypeValues)
}
-// imageDriversValidator is used to validate Drivers field.
-func imageDriversValidator(fe validator.FieldLevel) bool {
- fieldSlice, ok := fe.Field().Interface().([]string)
- if !ok {
- return false
- }
-
- for _, item := range fieldSlice {
- if !IsInSlice(item, imageDriversValues) {
- return false
- }
- }
-
- return true
-}
-
// imageArchitectureValidator is used to validate Architecture field.
func imageArchitectureValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
diff --git a/internal/validators/messages.go b/internal/validators/messages.go
index 2fa8436..09d1a77 100644
--- a/internal/validators/messages.go
+++ b/internal/validators/messages.go
@@ -28,12 +28,6 @@ func errorMessage(fe validator.FieldError) string {
case "isBool":
return fmt.Sprintf("%s %s: must be bool type", prefix, fe.Field())
- case "driver":
- return fmt.Sprintf("%s %s must be one of the following: %s",
- prefix,
- fe.Field(),
- joinValues(driverValues))
-
case "accessType":
return fmt.Sprintf("%s %s must be one of the following: %s",
prefix,
@@ -128,12 +122,6 @@ func errorMessage(fe validator.FieldError) string {
fe.Field(),
joinValues(computeDataDisksValues))
- case "computeDriver":
- return fmt.Sprintf("%s %s must be one of the following: %s",
- prefix,
- fe.Field(),
- joinValues(computeDriverValues))
-
// Disk Validators
case "diskType":
return fmt.Sprintf("%s %s must be one of the following: %s",
@@ -201,12 +189,6 @@ func errorMessage(fe validator.FieldError) string {
fe.Field(),
joinValues(imageTypeValues))
- case "imageDrivers":
- return fmt.Sprintf("%s %s must contain only the following: %s",
- prefix,
- fe.Field(),
- joinValues(imageDriversValues))
-
case "imageArchitecture":
return fmt.Sprintf("%s %s must be one of the following: %s",
prefix,
@@ -341,6 +323,25 @@ func errorMessage(fe validator.FieldError) string {
fe.Field(),
joinValues(userProviders))
+ // security group validators
+ case "securityGroupDirection":
+ return fmt.Sprintf("%s %s must be one of the following: %s",
+ prefix,
+ fe.Field(),
+ joinValues(securityGroupDirectionValues))
+
+ case "securityGroupEthertype":
+ return fmt.Sprintf("%s %s must be one of the following: %s",
+ prefix,
+ fe.Field(),
+ joinValues(securityGroupEthertypeValues))
+
+ case "securityGroupProtocol":
+ return fmt.Sprintf("%s %s must be one of the following: %s",
+ prefix,
+ fe.Field(),
+ joinValues(securityGroupProtocolValues))
+
// trunk tags validator
case "trunkTags":
return fmt.Sprintf("%s %s must be in range from 1 to 4095",
diff --git a/internal/validators/validator.go b/internal/validators/validator.go
index aaae78e..9a21cc6 100644
--- a/internal/validators/validator.go
+++ b/internal/validators/validator.go
@@ -31,11 +31,6 @@ func registerAllValidators(validate *validator.Validate) error {
return err
}
- err = validate.RegisterValidation("computeDriver", computeDriverValidator)
- if err != nil {
- return err
- }
-
err = validate.RegisterValidation("apiGroup", apiGroupValidator)
if err != nil {
return err
@@ -51,11 +46,6 @@ func registerAllValidators(validate *validator.Validate) error {
return err
}
- err = validate.RegisterValidation("driver", driverValidator)
- if err != nil {
- return err
- }
-
err = validate.RegisterValidation("imageBootType", imageBootTypeValidator)
if err != nil {
return err
@@ -66,11 +56,6 @@ func registerAllValidators(validate *validator.Validate) error {
return err
}
- err = validate.RegisterValidation("imageDrivers", imageDriversValidator)
- if err != nil {
- return err
- }
-
err = validate.RegisterValidation("imageArchitecture", imageArchitectureValidator)
if err != nil {
return err
@@ -301,5 +286,20 @@ func registerAllValidators(validate *validator.Validate) error {
return err
}
+ err = validate.RegisterValidation("securityGroupDirection", securityGroupDirectionValidator)
+ if err != nil {
+ return err
+ }
+
+ err = validate.RegisterValidation("securityGroupEthertype", securityGroupEthertypeValidator)
+ if err != nil {
+ return err
+ }
+
+ err = validate.RegisterValidation("securityGroupProtocol", securityGroupProtocolValidator)
+ if err != nil {
+ return err
+ }
+
return nil
}
diff --git a/internal/validators/values.go b/internal/validators/values.go
index 029309a..5e1802e 100644
--- a/internal/validators/values.go
+++ b/internal/validators/values.go
@@ -3,7 +3,6 @@ package validators
var (
apiGroupValues = []string{"cloudapi", "cloudbroker", "system"}
- driverValues = []string{"KVM_X86"}
accessTypeValues = []string{"R", "RCX", "ARCXDU"}
resTypesValues = []string{"compute", "vins", "k8s", "openshift", "lb", "flipgroup"}
protoValues = []string{"tcp", "udp"}
@@ -20,7 +19,6 @@ var (
computex86NetTypeValues = []string{"EXTNET", "VINS", "VFNIC", "DPDK", "SDN", "EMPTY", "TRUNK"}
computeOrderValues = []string{"cdrom", "network", "hd"}
computeDataDisksValues = []string{"KEEP", "DETACH", "DESTROY"}
- computeDriverValues = []string{"KVM_X86"}
diskTypeValues = []string{"B", "T", "D"}
@@ -38,7 +36,6 @@ var (
imageBootTypeValues = []string{"uefi", "bios"}
imageTypeValues = []string{"windows", "linux", "unknown"}
- imageDriversValues = []string{"KVM_X86"}
imageArchitectureValues = []string{"X86_64"}
sepFieldTypeValues = []string{"int", "str", "bool", "list", "dict"}
@@ -76,6 +73,10 @@ var (
userProviders = []string{"bvs", "decs3o"}
deviceValues = []string{"primary", "secondary"}
+
+ securityGroupDirectionValues = []string{"inbound", "outbound"}
+ securityGroupEthertypeValues = []string{"IPv4", "IPv6"}
+ securityGroupProtocolValues = []string{"icmp", "tcp", "udp"}
)
const (
diff --git a/legacy-client.go b/legacy-client.go
index f605788..9103e1a 100644
--- a/legacy-client.go
+++ b/legacy-client.go
@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"crypto/tls"
+ "encoding/json"
"fmt"
"io"
"net/http"
@@ -102,6 +103,47 @@ func (ldc *LegacyDecortClient) DecortApiCall(ctx context.Context, method, url st
return respBytes, err
}
+// DecortApiCallCtype method for sending requests to the platform with content type
+func (ldc *LegacyDecortClient) DecortApiCallCtype(ctx context.Context, method, url, ctype string, params interface{}) ([]byte, error) {
+ // get token
+ if err := ldc.getToken(ctx); err != nil {
+ return nil, err
+ }
+
+ var body *bytes.Buffer
+
+ switch ctype {
+ case constants.MIMESTREAM:
+ body = bytes.NewBuffer(params.([]byte))
+ case constants.MIMEJSON:
+ jsonBody, err := json.Marshal(params)
+ if err != nil {
+ return nil, err
+ }
+ body = bytes.NewBuffer(jsonBody)
+ default:
+ ctype = constants.MIMEPOSTForm
+ 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 {
+ return nil, err
+ }
+
+ // perform request
+ respBytes, err := ldc.do(req, ctype)
+ if err != nil {
+ return nil, err
+ }
+
+ return respBytes, err
+}
+
func (ldc *LegacyDecortClient) DecortApiCallMP(ctx context.Context, method, url string, params interface{}) ([]byte, error) {
body, ctype, err := multiPartReq(params)
if err != nil {
diff --git a/pkg/cloudapi/account/list.go b/pkg/cloudapi/account/list.go
index 81d355a..07ce97b 100644
--- a/pkg/cloudapi/account/list.go
+++ b/pkg/cloudapi/account/list.go
@@ -30,6 +30,11 @@ type ListRequest struct {
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
+ // Sort by zone id
+ // Default value: 0
+ // Required: false
+ ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
+
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
diff --git a/pkg/cloudapi/account/models.go b/pkg/cloudapi/account/models.go
index 091ba28..16c14a9 100644
--- a/pkg/cloudapi/account/models.go
+++ b/pkg/cloudapi/account/models.go
@@ -73,6 +73,15 @@ type ResourceLimits struct {
// Number of graphics cores
GPUUnits float64 `json:"gpu_units"`
+
+ // Storage policy
+ StoragePolicy []StoragePolicyItem `json:"storage_policy"`
+}
+
+type StoragePolicyItem struct {
+ ID uint64 `json:"id"`
+
+ Limit int `json:"limit"`
}
// Main information in one of if the list of accounts
@@ -103,6 +112,9 @@ type ItemAccount struct {
// Updated time
UpdatedTime uint64 `json:"updatedTime"`
+
+ // Zones
+ ZoneIDs []uint64 `json:"zoneIds"`
}
// List of accounts
@@ -275,6 +287,9 @@ type RecordAccount struct {
// Status
Status string `json:"status"`
+ // Storage policy ids
+ StoragePolicyIDs []uint64 `json:"storage_policy_ids"`
+
// UniqPools
UniqPools []interface{} `json:"uniqPools"`
@@ -291,7 +306,7 @@ type RecordAccount struct {
VINSes uint64 `json:"vinses"`
// Zone
- ZoneIDs []ZoneID
+ ZoneIDs []ZoneID `json:"zoneIds"`
// Zones
DefaultZoneID uint64 `json:"defaultZoneId"`
diff --git a/pkg/cloudapi/audit/models.go b/pkg/cloudapi/audit/models.go
index 8bb0ef0..1e9faff 100644
--- a/pkg/cloudapi/audit/models.go
+++ b/pkg/cloudapi/audit/models.go
@@ -12,6 +12,9 @@ type RecordAudit struct {
// GUID
GUID string `json:"guid"`
+ // Correlation ID
+ CorrelationID string `json:"correlation_id"`
+
// Kwargs
Kwargs string `json:"kwargs"`
diff --git a/pkg/cloudapi/bservice/group_add.go b/pkg/cloudapi/bservice/group_add.go
index 5b5630e..38ca0e8 100644
--- a/pkg/cloudapi/bservice/group_add.go
+++ b/pkg/cloudapi/bservice/group_add.go
@@ -38,11 +38,9 @@ type GroupAddRequest struct {
// Required: true
ImageID uint64 `url:"imageId" json:"imageId" validate:"required"`
- // Compute driver
- // should be one of:
- // - KVM_X86
+ // Compute driver like a KVM_X86, etc.
// Required: true
- Driver string `url:"driver" json:"driver" validate:"driver"`
+ Driver string `url:"driver" json:"driver" validate:"required"`
// Storage endpoint provider ID
// Required: false
@@ -75,6 +73,10 @@ type GroupAddRequest struct {
//Chipset "i440fx" or "Q35
//Required: false
Chipset string `url:"chipset,omitempty" json:"chipset,omitempty" validate:"chipset,omitempty"`
+
+ // ID of the chosen storage policy
+ // Required: false
+ StoragePolicyID uint64 `url:"storage_policy_id,omitempty" json:"storage_policy_id,omitempty"`
}
// GetRAM returns RAM field values
diff --git a/pkg/cloudapi/bservice/list.go b/pkg/cloudapi/bservice/list.go
index 31734c7..6bc4910 100644
--- a/pkg/cloudapi/bservice/list.go
+++ b/pkg/cloudapi/bservice/list.go
@@ -46,6 +46,11 @@ type ListRequest struct {
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
+ // Sort by zone id
+ // Default value: 0
+ // Required: false
+ ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
+
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
diff --git a/pkg/cloudapi/compute/audits.go b/pkg/cloudapi/compute/audits.go
index 9c42fa7..e69bdf8 100644
--- a/pkg/cloudapi/compute/audits.go
+++ b/pkg/cloudapi/compute/audits.go
@@ -12,11 +12,47 @@ import (
type AuditsRequest struct {
// ID of the compute
// Required: true
- ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
+ ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
+
+ // Find all audits after point in time
+ // Required: false
+ TimestampAT uint64 `url:"timestamp_at,omitempty" json:"timestamp_at,omitempty"`
+
+ // Find all audits before point in time
+ // Required: false
+ TimestampTO uint64 `url:"timestamp_to,omitempty" json:"timestamp_to,omitempty"`
+
+ // Find by user
+ // Required: false
+ User string `url:"user,omitempty" json:"user,omitempty"`
+
+ // Find by api endpoints
+ // Required: false
+ Call string `url:"call,omitempty" json:"call,omitempty"`
+
+ // Sort by one of supported fields, format ±
+ // Required: false
+ SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty"`
+
+ // Page number
+ // Required: false
+ Page uint64 `url:"page,omitempty" json:"page,omitempty"`
+
+ // Page size
+ // Required: false
+ Size uint64 `url:"size,omitempty" json:"size,omitempty"`
+
+ // Find by HTTP min status code
+ // Required: false
+ MinStatusCode uint64 `url:"min_status_code,omitempty" json:"min_status_code,omitempty"`
+
+ // Find by HTTP max status code
+ // Required: false
+ MaxStatusCode uint64 `url:"max_status_code,omitempty" json:"max_status_code,omitempty"`
}
// Audits gets audit records for the specified compute object
-func (c Compute) Audits(ctx context.Context, req AuditsRequest) (ListAudits, error) {
+func (c Compute) Audits(ctx context.Context, req AuditsRequest) (*ListAudits, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
@@ -24,7 +60,7 @@ func (c Compute) Audits(ctx context.Context, req AuditsRequest) (ListAudits, err
url := "/cloudapi/compute/audits"
- res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
+ res, err := c.client.DecortApiCall(ctx, http.MethodGet, url, req)
if err != nil {
return nil, err
}
@@ -36,5 +72,5 @@ func (c Compute) Audits(ctx context.Context, req AuditsRequest) (ListAudits, err
return nil, err
}
- return list, nil
+ return &list, nil
}
diff --git a/pkg/cloudapi/compute/change_secutity_group.go b/pkg/cloudapi/compute/change_secutity_group.go
new file mode 100644
index 0000000..4122bf2
--- /dev/null
+++ b/pkg/cloudapi/compute/change_secutity_group.go
@@ -0,0 +1,50 @@
+package compute
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// ChangeSecGroupsRequest struct to change security groups for compute
+type ChangeSecGroupsRequest struct {
+ // Identifier compute
+ // Required: true
+ ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
+
+ // Interface name or MAC address
+ // Required: true
+ Interface string `url:"interface" json:"interface" validate:"required"`
+
+ // List of security group IDs to assign to this interface
+ // Required: false
+ SecGroups []uint64 `url:"security_groups,omitempty" json:"security_groups,omitempty"`
+
+ // Flag indicating whether security groups are enabled for this interface
+ // Required: false
+ EnableSecGroups bool `url:"enable_secgroups,omitempty" json:"enable_secgroups,omitempty"`
+}
+
+// ChangeSecGroups changes security groups for compute
+func (c Compute) ChangeSecGroups(ctx context.Context, req ChangeSecGroupsRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudapi/compute/change_security_groups"
+
+ res, err := c.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
+}
diff --git a/pkg/cloudapi/compute/create_template_from_blank.go b/pkg/cloudapi/compute/create_template_from_blank.go
index a1c0be7..11d6940 100644
--- a/pkg/cloudapi/compute/create_template_from_blank.go
+++ b/pkg/cloudapi/compute/create_template_from_blank.go
@@ -27,6 +27,10 @@ type CreateTemplateFromBlankRequest struct {
// Required: true
ImageType string `url:"imagetype" json:"imagetype" validate:"imageType"`
+ // Storage policy id of disk. The rules of the specified storage policy will be used.
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// Username for the image
// Required: false
Username string `url:"username,omitempty" json:"username,omitempty"`
diff --git a/pkg/cloudapi/compute/disk_add.go b/pkg/cloudapi/compute/disk_add.go
index 3b958ce..fafe9ea 100644
--- a/pkg/cloudapi/compute/disk_add.go
+++ b/pkg/cloudapi/compute/disk_add.go
@@ -22,6 +22,10 @@ type DiskAddRequest struct {
// Required: true
Size uint64 `url:"size" json:"size" validate:"required"`
+ // Storage policy id of disk. The rules of the specified storage policy will be used.
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// Type of the disk
// Should be one of:
// - D
diff --git a/pkg/cloudapi/compute/filter_test.go b/pkg/cloudapi/compute/filter_test.go
index 513d2a9..34095bf 100644
--- a/pkg/cloudapi/compute/filter_test.go
+++ b/pkg/cloudapi/compute/filter_test.go
@@ -83,6 +83,7 @@ var computes = ListComputes{
VGPUs: []uint64{},
VINSConnected: 0,
VirtualImageID: 0,
+ ZoneID: 1,
},
{
ACL: ListACL{},
@@ -145,6 +146,7 @@ var computes = ListComputes{
VGPUs: []uint64{},
VINSConnected: 0,
VirtualImageID: 0,
+ ZoneID: 5,
},
},
EntryCount: 2,
diff --git a/pkg/cloudapi/compute/list.go b/pkg/cloudapi/compute/list.go
index 6ec6b84..284cf47 100644
--- a/pkg/cloudapi/compute/list.go
+++ b/pkg/cloudapi/compute/list.go
@@ -58,6 +58,11 @@ type ListRequest struct {
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
+ // Sort by zone id
+ // Default value: 0
+ // Required: false
+ ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
+
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
diff --git a/pkg/cloudapi/compute/models.go b/pkg/cloudapi/compute/models.go
index 50b00c1..68e1a6a 100644
--- a/pkg/cloudapi/compute/models.go
+++ b/pkg/cloudapi/compute/models.go
@@ -238,7 +238,13 @@ type ItemAudit struct {
}
// List Detailed audits
-type ListAudits []ItemAudit
+type ListAudits struct {
+ // Data
+ Data []ItemAudit `json:"data"`
+
+ // Entry count
+ EntryCount uint64 `json:"entryCount"`
+}
// Short information about audit
type ItemShortAudit struct {
@@ -661,6 +667,9 @@ type ItemVNFInterface struct {
// Enabled
Enabled bool `json:"enabled"`
+ // Enable security groups
+ EnableSecGroups bool `json:"enable_secgroups"`
+
// FLIPGroup ID
FLIPGroupID uint64 `json:"flipgroupId"`
@@ -703,6 +712,9 @@ type ItemVNFInterface struct {
// QOS
QOS QOS `json:"qos"`
+ // List of security groups
+ SecGroups []uint64 `json:"security_groups"`
+
// SDN interface ID
SDNInterfaceID string `json:"sdn_interface_id"`
@@ -848,17 +860,20 @@ type ItemComputeDisk struct {
// Status
Status string `json:"status"`
+ // Storage policy id of compute.
+ StoragePolicyID uint64 `json:"storage_policy_id"`
+
// Tech status
TechStatus string `json:"techStatus"`
+ // Need to clean before destroy
+ ToClean bool `json:"to_clean"`
+
// Type
Type string `json:"type"`
// Updated by
UpdatedBy string `json:"updatedBy"`
-
- // Zone ID
- ZoneID uint64 `json:"zoneId"`
}
type ItemReplication struct {
@@ -1161,6 +1176,9 @@ type ItemCompute struct {
// Virtual image ID
VirtualImageID uint64 `json:"virtualImageId"`
+
+ // Zone ID
+ ZoneID uint64 `json:"zoneId"`
}
// ListInfoDisks
diff --git a/pkg/cloudapi/compute/net_attach.go b/pkg/cloudapi/compute/net_attach.go
index 854a316..0f3ccce 100644
--- a/pkg/cloudapi/compute/net_attach.go
+++ b/pkg/cloudapi/compute/net_attach.go
@@ -42,12 +42,24 @@ type NetAttachRequest struct {
// Used only for EXTNET and DPDK
// For DPDK must be 1-9216
// For EXTNET must be 1500-9216
- // Required: false
+ // Required: false
MTU uint64 `url:"mtu,omitempty" json:"mtu,omitempty" validate:"omitempty,mtu"`
// Unique identifier of logical port on SDN side
// Required: false
SDNInterfaceID string `url:"sdn_interface_id,omitempty" json:"sdn_interface_id,omitempty" validate:"omitempty"`
+
+ // List of security group IDs to assign to this interface
+ // Required: false
+ SecGroups []uint64 `url:"security_groups,omitempty" json:"security_groups,omitempty"`
+
+ // Flag indicating whether security groups are enabled for this interface
+ // Required: false
+ EnableSecGroups bool `url:"enable_secgroups,omitempty" json:"enable_secgroups,omitempty"`
+
+ // Flag indicating whether this interface is enabled (only for VINS, EXTNET, DPDK, SDN, TRUNK)
+ // Required: false
+ Enabled interface{} `url:"enabled,omitempty" json:"enabled,omitempty" validate:"omitempty,isBool"`
}
// NetAttach attaches network to compute and gets info about network
diff --git a/pkg/cloudapi/compute/redeploy.go b/pkg/cloudapi/compute/redeploy.go
index 22ee5fa..a170b5b 100644
--- a/pkg/cloudapi/compute/redeploy.go
+++ b/pkg/cloudapi/compute/redeploy.go
@@ -14,6 +14,10 @@ type RedeployRequest struct {
// Required: true
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
+ // Storage policy id of compute. The rules of the specified storage policy will be used.
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// ID of the new OS image, if image change is required
// Required: false
ImageID uint64 `url:"imageId,omitempty" json:"imageId,omitempty"`
diff --git a/pkg/cloudapi/disks/change_disk_storage_policy.go b/pkg/cloudapi/disks/change_disk_storage_policy.go
new file mode 100644
index 0000000..4221a4e
--- /dev/null
+++ b/pkg/cloudapi/disks/change_disk_storage_policy.go
@@ -0,0 +1,42 @@
+package disks
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// ChangeDiskStoragePolicyRequest struct to change storage policy for disk
+type ChangeDiskStoragePolicyRequest struct {
+ // ID of the disk
+ // Required: true
+ DiskID uint64 `url:"disk_id" json:"disk_id" validate:"required"`
+
+ // ID of the storage policy to which to connect for disk
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+}
+
+// ChangeDiskStoragePolicy changes storage policy for disk
+func (d Disks) ChangeDiskStoragePolicy(ctx context.Context, req ChangeDiskStoragePolicyRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudapi/disks/change_disk_storage_policy"
+
+ 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
+}
diff --git a/pkg/cloudapi/disks/create.go b/pkg/cloudapi/disks/create.go
index ab894cb..ffbce52 100644
--- a/pkg/cloudapi/disks/create.go
+++ b/pkg/cloudapi/disks/create.go
@@ -18,6 +18,10 @@ type CreateRequest struct {
// Required: true
Name string `url:"name" json:"name" validate:"required"`
+ // ID of the storage policy under the disk will be created
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// Description of disk
// Required: false
Description string `url:"description,omitempty" json:"description,omitempty"`
diff --git a/pkg/cloudapi/disks/from_platform_disk.go b/pkg/cloudapi/disks/from_platform_disk.go
index a69fd6a..41b1d69 100644
--- a/pkg/cloudapi/disks/from_platform_disk.go
+++ b/pkg/cloudapi/disks/from_platform_disk.go
@@ -43,11 +43,6 @@ type FromPlatformDiskRequest struct {
// Required: false
PoolName string `url:"poolName,omitempty" json:"poolName,omitempty"`
- // List of types of compute suitable for image
- // Example: [ "KVM_X86" ]
- // Required: true
- Drivers []string `url:"drivers" json:"drivers" validate:"required"`
-
// Does this machine supports hot resize
// Required: false
HotResize bool `url:"hotresize" json:"hotresize"`
diff --git a/pkg/cloudapi/disks/models.go b/pkg/cloudapi/disks/models.go
index 026b78e..db67195 100644
--- a/pkg/cloudapi/disks/models.go
+++ b/pkg/cloudapi/disks/models.go
@@ -119,9 +119,15 @@ type ItemDisk struct {
// Status
Status string `json:"status"`
+ // Storage policy ID
+ StoragePolicyID uint64 `json:"storage_policy_id"`
+
// Tech status
TechStatus string `json:"techStatus"`
+ // Need to clean before destroy
+ ToClean bool `json:"to_clean"`
+
// Type
Type string `json:"type"`
@@ -477,9 +483,15 @@ type RecordDisk struct {
// Status
Status string `json:"status"`
+ // Storage policy ID
+ StoragePolicyID uint64 `json:"storage_policy_id"`
+
// Tech status
TechStatus string `json:"techStatus"`
+ // Need to clean before destroy
+ ToClean bool `json:"to_clean"`
+
// Type
Type string `json:"type"`
diff --git a/pkg/cloudapi/disks/replicate.go b/pkg/cloudapi/disks/replicate.go
index 3e2496e..0af3af9 100644
--- a/pkg/cloudapi/disks/replicate.go
+++ b/pkg/cloudapi/disks/replicate.go
@@ -25,9 +25,13 @@ type ReplicateRequest struct {
// Pool name to create slave disk in
// Required: true
PoolName string `url:"poolName" json:"poolName" validate:"required"`
+
+ // ID of the storage policy under the disk will be created
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
}
-// Create an empty disk in chosen SEP and pool combination.
+// Replicate create an empty disk in chosen SEP and pool combination.
// Starts replication between chosen disk and newly created disk
// Note: only TATLIN type SEP are supported for replications between
func (d Disks) Replicate(ctx context.Context, req ReplicateRequest) (uint64, error) {
diff --git a/pkg/cloudapi/dpdknet/models.go b/pkg/cloudapi/dpdknet/models.go
index 7bcf84d..ebcca93 100644
--- a/pkg/cloudapi/dpdknet/models.go
+++ b/pkg/cloudapi/dpdknet/models.go
@@ -14,6 +14,9 @@ type RecordDPDKNet struct {
// Description
Description string `json:"description"`
+ // Enable Security Groups
+ EnableSecGroups bool `json:"enable_secgroups"`
+
// Grid ID
GID uint64 `json:"gid"`
@@ -63,6 +66,9 @@ type ItemDPDKNet struct {
// Description
Description string `json:"description"`
+ // Enable Security Groups
+ EnableSecGroups bool `json:"enable_secgroups"`
+
// Grid ID
GID uint64 `json:"gid"`
diff --git a/pkg/cloudapi/extnet/list.go b/pkg/cloudapi/extnet/list.go
index e14d313..8af3884 100644
--- a/pkg/cloudapi/extnet/list.go
+++ b/pkg/cloudapi/extnet/list.go
@@ -42,6 +42,11 @@ type ListRequest struct {
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
+ // Sort by zone id
+ // Default value: 0
+ // Required: false
+ ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
+
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
diff --git a/pkg/cloudapi/extnet/models.go b/pkg/cloudapi/extnet/models.go
index 0350823..b7a7e9d 100644
--- a/pkg/cloudapi/extnet/models.go
+++ b/pkg/cloudapi/extnet/models.go
@@ -172,6 +172,9 @@ type RecordExtNet struct {
// Excluded
Excluded []Excluded `json:"excluded"`
+ // Enable Security Groups
+ EnableSecGroups bool `json:"enable_secgroups"`
+
// Free IPs
FreeIPs int64 `json:"free_ips"`
diff --git a/pkg/cloudapi/image/change_storage_policy.go b/pkg/cloudapi/image/change_storage_policy.go
new file mode 100644
index 0000000..4a34293
--- /dev/null
+++ b/pkg/cloudapi/image/change_storage_policy.go
@@ -0,0 +1,41 @@
+package image
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type ChangeStoragePolicyRequest struct {
+ // ID of the image to change the storage policy
+ // Required: true
+ ImageID uint64 `url:"image_id" json:"image_id" validate:"required"`
+
+ // ID of the storage policy to move the image to
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+}
+
+// ChangeStoragePolicy changes the storage policy of the image chosen
+func (i Image) ChangeStoragePolicy(ctx context.Context, req ChangeStoragePolicyRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudapi/image/change_storage_policy"
+
+ res, err := i.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
+}
diff --git a/pkg/cloudapi/image/create.go b/pkg/cloudapi/image/create.go
index f3a94a5..9d21bc8 100644
--- a/pkg/cloudapi/image/create.go
+++ b/pkg/cloudapi/image/create.go
@@ -35,6 +35,10 @@ type CreateRequest struct {
// Required: true
AccountID uint64 `url:"accountId" json:"accountId" validate:"required"`
+ // ID of the chosen storage policy
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// Select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming
// Should be:
// - eth
@@ -69,11 +73,6 @@ type CreateRequest struct {
// Pool for image create
// Required: false
Pool string `url:"poolName,omitempty" json:"poolName,omitempty"`
-
- // List of types of compute suitable for image
- // Example: [ "KVM_X86" ]
- // Required: true
- Drivers []string `url:"drivers" json:"drivers" validate:"min=1,max=2,imageDrivers"`
}
type asyncWrapperCreateRequest struct {
diff --git a/pkg/cloudapi/image/create_virtual.go b/pkg/cloudapi/image/create_virtual.go
index 1f56441..629130d 100644
--- a/pkg/cloudapi/image/create_virtual.go
+++ b/pkg/cloudapi/image/create_virtual.go
@@ -17,6 +17,11 @@ type CreateVirtualRequest struct {
// ID of real image to link this virtual image to upon creation
// Required: true
TargetID uint64 `url:"targetId" json:"targetId" validate:"required"`
+
+ // AccountID to make the virtual image exclusive
+ // Required: false
+ // Default: 0
+ AccountID uint64 `url:"accountId,omitempty" json:"accountId,omitempty"`
}
// CreateVirtual creates virtual image
diff --git a/pkg/cloudapi/image/models.go b/pkg/cloudapi/image/models.go
index fe455e2..c4150ca 100644
--- a/pkg/cloudapi/image/models.go
+++ b/pkg/cloudapi/image/models.go
@@ -191,6 +191,9 @@ type RecordImage struct {
// Status
Status string `json:"status"`
+ // Storage policy ID
+ StoragePolicyID uint64 `json:"storage_policy_id"`
+
// Tech status
TechStatus string `json:"techStatus"`
diff --git a/pkg/cloudapi/k8ci/list.go b/pkg/cloudapi/k8ci/list.go
index dc16d57..c875096 100644
--- a/pkg/cloudapi/k8ci/list.go
+++ b/pkg/cloudapi/k8ci/list.go
@@ -22,14 +22,6 @@ type ListRequest struct {
// Required: false
Status string `url:"status,omitempty" json:"status,omitempty"`
- // Find by worker driver
- // Required: false
- WorkerDriver string `url:"workerDriver,omitempty" json:"workerDriver,omitempty"`
-
- // Find by master driver
- // Required: false
- MasterDriver string `url:"masterDriver,omitempty" json:"masterDriver,omitempty"`
-
// Find by network plugin
// Required: false
NetworkPlugins string `url:"netPlugins,omitempty" json:"netPlugins,omitempty"`
diff --git a/pkg/cloudapi/k8ci/list_deleted.go b/pkg/cloudapi/k8ci/list_deleted.go
index 3fdb485..1561372 100644
--- a/pkg/cloudapi/k8ci/list_deleted.go
+++ b/pkg/cloudapi/k8ci/list_deleted.go
@@ -18,14 +18,6 @@ type ListDeletedRequest struct {
// Required: false
Name string `url:"name,omitempty" json:"name,omitempty"`
- // Find by worker driver
- // Required: false
- WorkerDriver string `url:"workerDriver,omitempty" json:"workerDriver,omitempty"`
-
- // Find by master driver
- // Required: false
- MasterDriver string `url:"masterDriver,omitempty" json:"masterDriver,omitempty"`
-
// Find by network plugin
// Required: false
NetworkPlugins string `url:"netPlugins,omitempty" json:"netPlugins,omitempty"`
diff --git a/pkg/cloudapi/k8s/create.go b/pkg/cloudapi/k8s/create.go
index a98ba8b..4e3f01f 100644
--- a/pkg/cloudapi/k8s/create.go
+++ b/pkg/cloudapi/k8s/create.go
@@ -31,6 +31,10 @@ type CreateRequest struct {
// Required: true
NetworkPlugin string `url:"networkPlugin" json:"networkPlugin" validate:"required,networkPlugin"`
+ // ID of the chosen storage policy
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// ID of SEP to create boot disks for master nodes. Uses images SEP ID if not set
// Required: false
MasterSEPID uint64 `url:"masterSepId,omitempty" json:"masterSepId,omitempty"`
diff --git a/pkg/cloudapi/k8s/list.go b/pkg/cloudapi/k8s/list.go
index 9afe205..904f9d4 100644
--- a/pkg/cloudapi/k8s/list.go
+++ b/pkg/cloudapi/k8s/list.go
@@ -46,6 +46,11 @@ type ListRequest struct {
// Required: false
IncludeDeleted bool `url:"includedeleted,omitempty" json:"includedeleted,omitempty"`
+ // Sort by zone id
+ // Default value: 0
+ // Required: false
+ ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
+
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
diff --git a/pkg/cloudapi/k8s/workers_group_add.go b/pkg/cloudapi/k8s/workers_group_add.go
index 79f6245..31be135 100644
--- a/pkg/cloudapi/k8s/workers_group_add.go
+++ b/pkg/cloudapi/k8s/workers_group_add.go
@@ -17,6 +17,10 @@ type WorkersGroupAddRequest struct {
// Required: true
Name string `url:"name" json:"name" validate:"required"`
+ // ID of the chosen storage policy
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// ID of SEP to create boot disks for default worker nodes group. Uses images SEP ID if not set
// Required: false
WorkerSEPID uint64 `url:"workerSepId,omitempty" json:"workerSepId,omitempty"`
diff --git a/pkg/cloudapi/kvmx86/create.go b/pkg/cloudapi/kvmx86/create.go
index d2640d5..48c7c2b 100644
--- a/pkg/cloudapi/kvmx86/create.go
+++ b/pkg/cloudapi/kvmx86/create.go
@@ -42,6 +42,18 @@ type Interface struct {
// SDN interface id
// Required: false
SDNInterfaceID string `url:"sdn_interface_id,omitempty" json:"sdn_interface_id,omitempty"`
+
+ // List of security group IDs to assign to this interface
+ // Required: false
+ SecGroups []uint64 `url:"security_groups,omitempty" json:"security_groups,omitempty"`
+
+ // Flag indicating whether security groups are enabled for this interface
+ // Required: false
+ EnableSecGroups bool `url:"enable_secgroups,omitempty" json:"enable_secgroups,omitempty"`
+
+ // Flag indicating whether this interface is enabled (only for VINS, EXTNET, DPDK, SDN, TRUNK)
+ // Required: false
+ Enabled interface{} `url:"enabled,omitempty" json:"enabled,omitempty" validate:"omitempty,isBool"`
}
// DataDisk detailed struct for DataDisks field in CreateRequest and CreateBlankRequest
@@ -54,6 +66,10 @@ type DataDisk struct {
// Required: true
Size uint64 `url:"size" json:"size" validate:"required"`
+ // Storage policy id of disk. The rules of the specified storage policy will be used.
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// Storage endpoint provider ID
// By default the same with boot disk
// Required: false
@@ -92,6 +108,10 @@ type CreateRequest struct {
// Required: true
RAM uint64 `url:"ram" json:"ram" validate:"required"`
+ // Storage policy id of сompute. The rules of the specified storage policy will be used.
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" 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"`
@@ -150,10 +170,6 @@ type CreateRequest struct {
// Required: false
CustomFields string `url:"customFields,omitempty" json:"customFields,omitempty"`
- // Type of compute Stateful (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),
diff --git a/pkg/cloudapi/kvmx86/create_blank.go b/pkg/cloudapi/kvmx86/create_blank.go
index ca51757..44f3898 100644
--- a/pkg/cloudapi/kvmx86/create_blank.go
+++ b/pkg/cloudapi/kvmx86/create_blank.go
@@ -28,6 +28,10 @@ type CreateBlankRequest struct {
// Required: true
RAM uint64 `url:"ram" json:"ram" validate:"required"`
+ // Storage policy id of compute. The rules of the specified storage policy will be used.
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" 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"`
@@ -57,10 +61,6 @@ type CreateBlankRequest struct {
// Required: false
Interfaces []Interface `url:"-" json:"interfaces,omitempty" validate:"omitempty,dive"`
- // Type of compute Stateful (KVM_X86)
- // Required: false
- Driver string `url:"driver,omitempty" json:"driver,omitempty" validate:"omitempty,computeDriver"`
-
// Type of the emulated system, Q35 or i440fx
// Required: false
Chipset string `url:"chipset,omitempty" json:"chipset,omitempty" validate:"omitempty,chipset"`
diff --git a/pkg/cloudapi/lb/list.go b/pkg/cloudapi/lb/list.go
index e9c8432..17fbdc0 100644
--- a/pkg/cloudapi/lb/list.go
+++ b/pkg/cloudapi/lb/list.go
@@ -50,6 +50,11 @@ type ListRequest struct {
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
+ // Sort by zone id
+ // Default value: 0
+ // Required: false
+ ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
+
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
diff --git a/pkg/cloudapi/rg/create.go b/pkg/cloudapi/rg/create.go
index dad9add..b76fe7d 100644
--- a/pkg/cloudapi/rg/create.go
+++ b/pkg/cloudapi/rg/create.go
@@ -5,6 +5,7 @@ import (
"net/http"
"strconv"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
@@ -22,6 +23,10 @@ type CreateRequest struct {
// Required: true
Name string `url:"name" json:"name" validate:"required,min=2"`
+ // Storage policies
+ // Required: false
+ StoragePolicies []StoragePolicy `url:"storage_policies" json:"storage_policies"`
+
// Max size of memory in MB
// Required: false
MaxMemoryCapacity int64 `url:"maxMemoryCapacity,omitempty" json:"maxMemoryCapacity,omitempty"`
@@ -77,6 +82,11 @@ type CreateRequest struct {
SDNAccessGroupID string `url:"sdn_access_group_id,omitempty" json:"sdn_access_group_id,omitempty"`
}
+type StoragePolicy struct {
+ ID int64 `url:"id" json:"id"`
+ Limit int `url:"limit" json:"limit"`
+}
+
// Create creates resource group
func (r RG) Create(ctx context.Context, req CreateRequest) (uint64, error) {
err := validators.ValidateRequest(req)
@@ -86,7 +96,7 @@ func (r RG) Create(ctx context.Context, req CreateRequest) (uint64, error) {
url := "/cloudapi/rg/create"
- res, err := r.client.DecortApiCall(ctx, http.MethodPost, url, req)
+ res, err := r.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
if err != nil {
return 0, err
}
diff --git a/pkg/cloudapi/rg/models.go b/pkg/cloudapi/rg/models.go
index a8311cf..ce81b38 100644
--- a/pkg/cloudapi/rg/models.go
+++ b/pkg/cloudapi/rg/models.go
@@ -134,6 +134,9 @@ type RecordResourceGroup struct {
// List of resource types
ResTypes []string `json:"resourceTypes"`
+ // Storage policy ids
+ StoragePolicyIDs []uint64 `json:"storage_policy_ids"`
+
// SDN access group id
SDNAccessGroupID string `json:"sdn_access_group_id"`
@@ -233,6 +236,9 @@ type ItemResourceGroup struct {
// SDN access group id
SDNAccessGroupID string `json:"sdn_access_group_id"`
+ // Storage policy ids
+ StoragePolicyIDs []uint64 `json:"storage_policy_ids"`
+
// Secret
Secret string `json:"secret"`
@@ -308,6 +314,9 @@ type ResourceLimits struct {
// GPU units
GPUUnits float64 `json:"gpu_units"`
+
+ // Storage policies
+ StoragePolicies []StoragePolicy `json:"storage_policy"`
}
// Main information about affinity group
diff --git a/pkg/cloudapi/rg/update.go b/pkg/cloudapi/rg/update.go
index 21448ac..79ab888 100644
--- a/pkg/cloudapi/rg/update.go
+++ b/pkg/cloudapi/rg/update.go
@@ -5,6 +5,7 @@ import (
"net/http"
"strconv"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
@@ -50,6 +51,10 @@ type UpdateRequest struct {
// Default: false
// Required: false
ClearUniqPools bool `url:"clearUniqPools" json:"clearUniqPools"`
+
+ // Storage policies
+ // Required: false
+ StoragePolicies []StoragePolicy `url:"-" json:"storage_policies,omitempty"`
}
// Update updates resource group
@@ -61,7 +66,7 @@ func (r RG) Update(ctx context.Context, req UpdateRequest) (bool, error) {
url := "/cloudapi/rg/update"
- res, err := r.client.DecortApiCall(ctx, http.MethodPost, url, req)
+ res, err := r.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
if err != nil {
return false, err
}
diff --git a/pkg/cloudapi/security_group/create.go b/pkg/cloudapi/security_group/create.go
new file mode 100644
index 0000000..1bab28a
--- /dev/null
+++ b/pkg/cloudapi/security_group/create.go
@@ -0,0 +1,46 @@
+package securitygroup
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type CreateRequest struct {
+ // Account ID that owns security group
+ // Required: true
+ AccountID uint64 `url:"account_id" json:"account_id" validate:"required"`
+
+ // Security group name
+ // Required: true
+ Name string `url:"name" json:"name" validate:"required"`
+
+ // Security group description
+ // Required: false
+ Description string `url:"description,omitempty" json:"description,omitempty"`
+}
+
+func (sg SecurityGroup) Create(ctx context.Context, req CreateRequest) (uint64, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return 0, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudapi/security_group/create"
+
+ res, err := sg.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
+ if err != nil {
+ return 0, err
+ }
+
+ result, err := strconv.ParseUint(string(res), 10, 64)
+ if err != nil {
+ return 0, err
+ }
+
+ return result, nil
+
+}
diff --git a/pkg/cloudapi/security_group/create_rule.go b/pkg/cloudapi/security_group/create_rule.go
new file mode 100644
index 0000000..1d56db4
--- /dev/null
+++ b/pkg/cloudapi/security_group/create_rule.go
@@ -0,0 +1,63 @@
+package securitygroup
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type CreateRuleRequest struct {
+ // Security group ID
+ // Required: true
+ SecurityGroupID uint64 `url:"security_group_id" json:"security_group_id" validate:"required"`
+
+ // Traffic direction (inbound/outbound)
+ // Required: true
+ Direction string `url:"direction" json:"direction" validate:"required,securityGroupDirection"`
+
+ // IP protocol version
+ // Default: IPv4
+ // Required: false
+ Ethertype string `url:"ethertype,omitempty" json:"ethertype,omitempty" validate:"omitempty,securityGroupEthertype"`
+
+ // Network protocol, available values : icmp, tcp, udp
+ // Required: false
+ Protocol string `url:"protocol,omitempty" json:"protocol,omitempty" validate:"omitempty,securityGroupProtocol"`
+
+ // Start port number (for TCP/UDP)
+ // Required: false
+ PortRangeMin uint64 `url:"port_range_min,omitempty" json:"port_range_min,omitempty"`
+
+ // End port number (for TCP/UDP)
+ // Required: false
+ PortRangeMax uint64 `url:"port_range_max,omitempty" json:"port_range_max,omitempty"`
+
+ // Remote IP prefix in CIDR notation
+ // Required: false
+ RemoteIPPrefix string `url:"remote_ip_prefix,omitempty" json:"remote_ip_prefix,omitempty"`
+}
+
+func (sg SecurityGroup) CreateRule(ctx context.Context, req CreateRuleRequest) (uint64, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return 0, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudapi/security_group/create_rule"
+
+ res, err := sg.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
+ if err != nil {
+ return 0, err
+ }
+
+ result, err := strconv.ParseUint(string(res), 10, 64)
+ if err != nil {
+ return 0, err
+ }
+
+ return result, nil
+
+}
diff --git a/pkg/cloudapi/security_group/delete.go b/pkg/cloudapi/security_group/delete.go
new file mode 100644
index 0000000..cd6eea55
--- /dev/null
+++ b/pkg/cloudapi/security_group/delete.go
@@ -0,0 +1,36 @@
+package securitygroup
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type DeleteRequest struct {
+ // Security group ID
+ // Required: true
+ SecurityGroupID uint64 `url:"security_group_id" json:"security_group_id" validate:"required"`
+}
+
+func (sg SecurityGroup) Delete(ctx context.Context, req DeleteRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudapi/security_group/delete"
+
+ res, err := sg.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
+}
diff --git a/pkg/cloudapi/security_group/delete_rule.go b/pkg/cloudapi/security_group/delete_rule.go
new file mode 100644
index 0000000..4491900
--- /dev/null
+++ b/pkg/cloudapi/security_group/delete_rule.go
@@ -0,0 +1,40 @@
+package securitygroup
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type DeleteRuleRequest struct {
+ // Security group ID
+ // Required: true
+ SecurityGroupID uint64 `url:"security_group_id" json:"security_group_id" validate:"required"`
+
+ // Rule ID
+ // Required: true
+ RuleID uint64 `url:"rule_id" json:"rule_id" validate:"required"`
+}
+
+func (sg SecurityGroup) DeleteRule(ctx context.Context, req DeleteRuleRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudapi/security_group/delete_rule"
+
+ res, err := sg.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
+}
diff --git a/pkg/cloudapi/security_group/filter.go b/pkg/cloudapi/security_group/filter.go
new file mode 100644
index 0000000..e95ee28
--- /dev/null
+++ b/pkg/cloudapi/security_group/filter.go
@@ -0,0 +1,80 @@
+package securitygroup
+
+// FilterByID returns ListSecurityGroups with specified ID.
+func (lsg ListSecurityGroups) FilterByID(id uint64) ListSecurityGroups {
+ predicate := func(isg ItemSecurityGroup) bool {
+ return isg.ID == id
+ }
+
+ return lsg.FilterFunc(predicate)
+}
+
+// FilterByID returns ListSecurityGroups with specified Name.
+func (lsg ListSecurityGroups) FilterByName(name string) ListSecurityGroups {
+ predicate := func(isg ItemSecurityGroup) bool {
+ return isg.Name == name
+ }
+
+ return lsg.FilterFunc(predicate)
+}
+
+// FilterByCreatedBy returns ListSecurityGroups with specified CreatedBy.
+func (lsg ListSecurityGroups) FilterByCreatedBy(createdBy string) ListSecurityGroups {
+ predicate := func(isg ItemSecurityGroup) bool {
+ return isg.CreatedBy == createdBy
+ }
+
+ return lsg.FilterFunc(predicate)
+}
+
+// FilterByDescription returns ListSecurityGroups with specified Description.
+func (lsg ListSecurityGroups) FilterByDescription(description string) ListSecurityGroups {
+ predicate := func(isg ItemSecurityGroup) bool {
+ return isg.Description == description
+ }
+
+ return lsg.FilterFunc(predicate)
+}
+
+// FilterByUpdatedBy returns ListSecurityGroups with specified UpdatedBy.
+func (lsg ListSecurityGroups) FilterByUpdatedBy(updatedBy string) ListSecurityGroups {
+ predicate := func(isg ItemSecurityGroup) bool {
+ return isg.UpdatedBy == updatedBy
+ }
+
+ return lsg.FilterFunc(predicate)
+}
+
+// FilterByAccountID returns ListSecurityGroups with specified AccountID.
+func (lsg ListSecurityGroups) FilterByAccountID(accountID uint64) ListSecurityGroups {
+ predicate := func(isg ItemSecurityGroup) bool {
+ return isg.AccountID == accountID
+ }
+
+ return lsg.FilterFunc(predicate)
+}
+
+// FilterFunc allows filtering ListSecurityGroups based on a user-specified predicate.
+func (lsg ListSecurityGroups) FilterFunc(predicate func(ItemSecurityGroup) bool) ListSecurityGroups {
+ var result ListSecurityGroups
+
+ for _, item := range lsg.Data {
+ if predicate(item) {
+ result.Data = append(result.Data, item)
+ }
+ }
+
+ result.EntryCount = uint64(len(result.Data))
+
+ return result
+}
+
+// FindOne returns first found ItemSecurityGroup
+// If none was found, returns an empty struct.
+func (lsg ListSecurityGroups) FindOne() ItemSecurityGroup {
+ if len(lsg.Data) == 0 {
+ return ItemSecurityGroup{}
+ }
+
+ return lsg.Data[0]
+}
diff --git a/pkg/cloudapi/security_group/filter_test.go b/pkg/cloudapi/security_group/filter_test.go
new file mode 100644
index 0000000..821f016
--- /dev/null
+++ b/pkg/cloudapi/security_group/filter_test.go
@@ -0,0 +1,87 @@
+package securitygroup
+
+import "testing"
+
+var securityGroups = ListSecurityGroups{
+ Data: []ItemSecurityGroup{
+ {
+ ID: 1,
+ AccountID: 1,
+ Name: "sg1",
+ Description: "some desc",
+ CreatedBy: "user",
+ },
+ {
+ ID: 3,
+ AccountID: 3,
+ Name: "sg3",
+ Description: "some desc",
+ CreatedBy: "anotheruser",
+ },
+ {
+ ID: 5,
+ AccountID: 3,
+ Name: "sg5",
+ Description: "some other desc",
+ CreatedBy: "anotheruser",
+ UpdatedBy: "user",
+ },
+ },
+ EntryCount: 3,
+}
+
+func TestFilterByID(t *testing.T) {
+ actual := securityGroups.FilterByID(1).FindOne()
+ if actual.ID != 1 {
+ t.Fatal("expected ID 1, found: ", actual.ID)
+ }
+}
+
+func TestFilterByName(t *testing.T) {
+ actual := securityGroups.FilterByName("sg3").FindOne()
+ if actual.Name != "sg3" {
+ t.Fatal("expected Name sg3, found: ", actual.Name)
+ }
+}
+
+func TestFilterByDescription(t *testing.T) {
+ actual := securityGroups.FilterByDescription("some desc")
+
+ if len(actual.Data) != 2 {
+ t.Fatal("expected 2 found, actual: ", len(actual.Data))
+ }
+
+ for _, item := range actual.Data {
+ if item.Description != "some desc" {
+ t.Fatal("expected Description 'some desc', found: ", item.Description)
+ }
+ }
+}
+
+func TestFilterByAccountID(t *testing.T) {
+ actual := securityGroups.FilterByAccountID(1).FindOne()
+ if actual.AccountID != 1 {
+ t.Fatal("expected AccountID 1, found: ", actual.AccountID)
+ }
+}
+
+func TestFilterByCreatedBy(t *testing.T) {
+ actual := securityGroups.FilterByCreatedBy("anotheruser")
+
+ if len(actual.Data) != 2 {
+ t.Fatal("expected 2 found, actual: ", len(actual.Data))
+ }
+
+ for _, item := range actual.Data {
+ if item.CreatedBy != "anotheruser" {
+ t.Fatal("expected CreatedBy 'anotheruser', found: ", item.CreatedBy)
+ }
+ }
+}
+
+func TestFilterByUpdatedBy(t *testing.T) {
+ actual := securityGroups.FilterByUpdatedBy("user").FindOne()
+ if actual.UpdatedBy != "user" {
+ t.Fatal("expected UpdatedBy 'user', found: ", actual.UpdatedBy)
+ }
+}
diff --git a/pkg/cloudapi/security_group/get.go b/pkg/cloudapi/security_group/get.go
new file mode 100644
index 0000000..318dd6b
--- /dev/null
+++ b/pkg/cloudapi/security_group/get.go
@@ -0,0 +1,43 @@
+package securitygroup
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type GetRequest struct {
+ // ID of security group
+ // Required: true
+ SecurityGroupID uint64 `url:"security_group_id" json:"security_group_id" validate:"required"`
+}
+
+func (sg SecurityGroup) Get(ctx context.Context, req GetRequest) (*RecordSecurityGroup, error) {
+ res, err := sg.GetRaw(ctx, req)
+ if err != nil {
+ return nil, err
+ }
+
+ info := RecordSecurityGroup{}
+
+ err = json.Unmarshal(res, &info)
+ if err != nil {
+ return nil, err
+ }
+
+ return &info, nil
+}
+
+func (sg SecurityGroup) GetRaw(ctx context.Context, req GetRequest) ([]byte, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudapi/security_group/get"
+
+ res, err := sg.client.DecortApiCall(ctx, http.MethodGet, url, req)
+ return res, err
+}
diff --git a/pkg/cloudapi/security_group/list.go b/pkg/cloudapi/security_group/list.go
new file mode 100644
index 0000000..0e5fb37
--- /dev/null
+++ b/pkg/cloudapi/security_group/list.go
@@ -0,0 +1,86 @@
+package securitygroup
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type ListRequest struct {
+ // Search by security group id
+ // Required: false
+ ByID uint64 `url:"by_id,omitempty" json:"by_id,omitempty"`
+
+ // Search by account id
+ // Required: false
+ AccountID uint64 `url:"account_id,omitempty" json:"account_id,omitempty"`
+
+ // Search by security group name
+ // Required: false
+ Name string `url:"name,omitempty" json:"name,omitempty"`
+
+ // Search by security group description
+ // Required: false
+ Description string `url:"description,omitempty" json:"description,omitempty"`
+
+ // Search by created after time (unix timestamp)
+ // Required: false
+ CreatedMin uint64 `url:"created_min,omitempty" json:"created_min,omitempty"`
+
+ // Search by created before time (unix timestamp)
+ // Required: false
+ CreatedMax uint64 `url:"created_max,omitempty" json:"created_max,omitempty"`
+
+ // Search by updated after time (unix timestamp)
+ // Required: false
+ UpdatedMin uint64 `url:"updated_min,omitempty" json:"updated_min,omitempty"`
+
+ // Search by updated before time (unix timestamp)
+ // Required: false
+ UpdatedMax uint64 `url:"updated_max,omitempty" json:"updated_max,omitempty"`
+
+ // Sort by one of supported fields, format ±
+ // Required: false
+ SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty"`
+
+ // Page number
+ // Required: false
+ Page uint64 `url:"page,omitempty" json:"page,omitempty"`
+
+ // Page size
+ // Required: false
+ Size uint64 `url:"size,omitempty" json:"size,omitempty"`
+}
+
+// List gets list of security groups as a ListSecurityGroups struct
+func (sg SecurityGroup) List(ctx context.Context, req ListRequest) (*ListSecurityGroups, error) {
+
+ res, err := sg.ListRaw(ctx, req)
+ if err != nil {
+ return nil, err
+ }
+
+ list := ListSecurityGroups{}
+
+ err = json.Unmarshal(res, &list)
+ if err != nil {
+ return nil, err
+ }
+
+ return &list, nil
+}
+
+// ListRaw gets list of security groups as an array of bytes
+func (sg SecurityGroup) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
+
+ if err := validators.ValidateRequest(req); err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudapi/security_group/list"
+
+ res, err := sg.client.DecortApiCall(ctx, http.MethodGet, url, req)
+ return res, err
+}
diff --git a/pkg/cloudapi/security_group/models.go b/pkg/cloudapi/security_group/models.go
new file mode 100644
index 0000000..440e813
--- /dev/null
+++ b/pkg/cloudapi/security_group/models.go
@@ -0,0 +1,43 @@
+package securitygroup
+
+type ListSecurityGroups struct {
+ Data []ItemSecurityGroup `json:"data"`
+ EntryCount uint64 `json:"entryCount"`
+}
+
+type ItemSecurityGroup struct {
+ ID uint64 `json:"id"`
+ AccountID uint64 `json:"account_id"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ Rules Rules `json:"rules"`
+ CreatedAt uint64 `json:"created_at"`
+ UpdatedAt uint64 `json:"updated_at"`
+ CreatedBy string `json:"created_by"`
+ UpdatedBy string `json:"updated_by"`
+}
+
+type RecordSecurityGroup struct {
+ ID uint64 `json:"id"`
+ AccountID uint64 `json:"account_id"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ Rules Rules `json:"rules"`
+ CreatedAt uint64 `json:"created_at"`
+ UpdatedAt uint64 `json:"updated_at"`
+ CreatedBy string `json:"created_by"`
+ UpdatedBy string `json:"updated_by"`
+}
+
+type Rules []Rule
+
+type Rule struct {
+ ID uint64 `json:"id"`
+ Direction string `json:"direction"`
+ Ethertype string `json:"ethertype"`
+ Protocol string `json:"protocol"`
+ PortRangeMin uint64 `json:"port_range_min"`
+ PortRangeMax uint64 `json:"port_range_max"`
+ RemoteIPPrefix string `json:"remote_ip_prefix"`
+ RemoteGroupID uint64 `json:"remote_group_id"`
+}
diff --git a/pkg/cloudapi/security_group/security_group.go b/pkg/cloudapi/security_group/security_group.go
new file mode 100644
index 0000000..35c6a3b
--- /dev/null
+++ b/pkg/cloudapi/security_group/security_group.go
@@ -0,0 +1,15 @@
+package securitygroup
+
+import "repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
+
+// Structure for creating request to storage policy
+type SecurityGroup struct {
+ client interfaces.Caller
+}
+
+// Builder for stack endpoint
+func New(client interfaces.Caller) *SecurityGroup {
+ return &SecurityGroup{
+ client: client,
+ }
+}
diff --git a/pkg/cloudapi/security_group/sorting.go b/pkg/cloudapi/security_group/sorting.go
new file mode 100644
index 0000000..5a54b53
--- /dev/null
+++ b/pkg/cloudapi/security_group/sorting.go
@@ -0,0 +1,41 @@
+package securitygroup
+
+import "sort"
+
+// SortByCreatedAt sorts ListSecurityGroups by the CreatedAt field in ascending order.
+//
+// If inverse param is set to true, the order is reversed.
+func (lsg ListSecurityGroups) SortByCreatedAt(inverse bool) ListSecurityGroups {
+ if len(lsg.Data) < 2 {
+ return lsg
+ }
+
+ sort.Slice(lsg.Data, func(i, j int) bool {
+ if inverse {
+ return lsg.Data[i].CreatedAt > lsg.Data[j].CreatedAt
+ }
+
+ return lsg.Data[i].CreatedAt < lsg.Data[j].CreatedAt
+ })
+
+ return lsg
+}
+
+// SortByUpdatedAt sorts ListSecurityGroups by the UpdatedAt field in ascending order.
+//
+// If inverse param is set to true, the order is reversed.
+func (lsg ListSecurityGroups) SortByUpdatedAt(inverse bool) ListSecurityGroups {
+ if len(lsg.Data) < 2 {
+ return lsg
+ }
+
+ sort.Slice(lsg.Data, func(i, j int) bool {
+ if inverse {
+ return lsg.Data[i].UpdatedAt > lsg.Data[j].UpdatedAt
+ }
+
+ return lsg.Data[i].UpdatedAt < lsg.Data[j].UpdatedAt
+ })
+
+ return lsg
+}
diff --git a/pkg/cloudapi/security_group/update.go b/pkg/cloudapi/security_group/update.go
new file mode 100644
index 0000000..c1e373f
--- /dev/null
+++ b/pkg/cloudapi/security_group/update.go
@@ -0,0 +1,51 @@
+package securitygroup
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type UpdateRequest struct {
+ // Security group ID
+ // Required: true
+ SecurityGroupID uint64 `url:"security_group_id" json:"security_group_id" validate:"required"`
+
+ // New security group name
+ // Required: false
+ Name string `url:"name,omitempty" json:"name,omitempty"`
+
+ // New security group description
+ // Required: false
+ Description string `url:"description,omitempty" json:"description,omitempty"`
+}
+
+func (sg SecurityGroup) Update(ctx context.Context, req UpdateRequest) (*RecordSecurityGroup, error) {
+ res, err := sg.UpdateRaw(ctx, req)
+ if err != nil {
+ return nil, err
+ }
+
+ info := RecordSecurityGroup{}
+
+ err = json.Unmarshal(res, &info)
+ if err != nil {
+ return nil, err
+ }
+
+ return &info, nil
+}
+
+func (sg SecurityGroup) UpdateRaw(ctx context.Context, req UpdateRequest) ([]byte, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudapi/security_group/update"
+
+ res, err := sg.client.DecortApiCall(ctx, http.MethodPost, url, req)
+ return res, err
+}
diff --git a/pkg/cloudapi/securitygroup.go b/pkg/cloudapi/securitygroup.go
new file mode 100644
index 0000000..0ae85c6
--- /dev/null
+++ b/pkg/cloudapi/securitygroup.go
@@ -0,0 +1,10 @@
+package cloudapi
+
+import (
+ securitygroup "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/security_group"
+)
+
+// Accessing the Security Group method group
+func (ca *CloudAPI) SecurityGroup() *securitygroup.SecurityGroup {
+ return securitygroup.New(ca.client)
+}
diff --git a/pkg/cloudapi/storage_policy/get.go b/pkg/cloudapi/storage_policy/get.go
new file mode 100644
index 0000000..5619ed9
--- /dev/null
+++ b/pkg/cloudapi/storage_policy/get.go
@@ -0,0 +1,43 @@
+package storagepolicy
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type GetRequest struct {
+ // ID of storage policy
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+}
+
+func (sp StoragePolicy) Get(ctx context.Context, req GetRequest) (*InfoStoragePolicy, error) {
+ res, err := sp.GetRaw(ctx, req)
+ if err != nil {
+ return nil, err
+ }
+
+ info := InfoStoragePolicy{}
+
+ err = json.Unmarshal(res, &info)
+ if err != nil {
+ return nil, err
+ }
+
+ return &info, nil
+}
+
+func (sp StoragePolicy) GetRaw(ctx context.Context, req GetRequest) ([]byte, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudapi/storage_policy/get"
+
+ res, err := sp.client.DecortApiCall(ctx, http.MethodGet, url, req)
+ return res, err
+}
diff --git a/pkg/cloudapi/storage_policy/list.go b/pkg/cloudapi/storage_policy/list.go
new file mode 100644
index 0000000..330afb5
--- /dev/null
+++ b/pkg/cloudapi/storage_policy/list.go
@@ -0,0 +1,90 @@
+package storagepolicy
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type ListRequest struct {
+ // ID of account ID
+ // Required: true
+ AccountID uint64 `url:"account_id" json:"account_id" validate:"required"`
+
+ // Page number
+ // Required: false
+ Page uint64 `url:"page,omitempty" json:"page,omitempty"`
+
+ // Page size
+ // Required: false
+ Size uint64 `url:"size,omitempty" json:"size,omitempty"`
+
+ // Search by storage policy ID
+ // Required: false
+ ByID uint64 `url:"by_id,omitempty" json:"by_id,omitempty"`
+
+ // Search by storage policy name
+ // Required: false
+ Name string `url:"name,omitempty" json:"name,omitempty"`
+
+ // Search by storage policy status
+ // Required: false
+ Status string `url:"status,omitempty" json:"status,omitempty"`
+
+ // Search by storage policy desc
+ // Required: false
+ Desc string `url:"desc,omitempty" json:"desc,omitempty"`
+
+ // Search by storage policy iops limit
+ // Required: false
+ LimitIOPS uint64 `url:"limit_iops,omitempty" json:"limit_iops,omitempty"`
+
+ // Sort by one of supported fields, format ±
+ // Required: false
+ SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty"`
+
+ // Search by resgroup id
+ // Required: false
+ ResgroupID uint64 `url:"resgroup_id,omitempty" json:"resgroup_id,omitempty"`
+
+ // Search by sep id
+ // Required: false
+ SepID uint64 `url:"sep_id,omitempty" json:"sep_id,omitempty"`
+
+ // Search by pool name
+ // Required: false
+ PoolName string `url:"pool_name,omitempty" json:"pool_name,omitempty"`
+}
+
+// List gets list of storage policies as a ListStoragePolicies struct
+func (sp StoragePolicy) List(ctx context.Context, req ListRequest) (*ListStoragePolicies, error) {
+
+ res, err := sp.ListRaw(ctx, req)
+ if err != nil {
+ return nil, err
+ }
+
+ list := ListStoragePolicies{}
+
+ err = json.Unmarshal(res, &list)
+ if err != nil {
+ return nil, err
+ }
+
+ return &list, nil
+}
+
+// ListRaw gets list of storage policies as an array of bytes
+func (sp StoragePolicy) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
+
+ if err := validators.ValidateRequest(req); err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudapi/storage_policy/list"
+
+ res, err := sp.client.DecortApiCall(ctx, http.MethodGet, url, req)
+ return res, err
+}
diff --git a/pkg/cloudapi/storage_policy/models.go b/pkg/cloudapi/storage_policy/models.go
new file mode 100644
index 0000000..82d45b8
--- /dev/null
+++ b/pkg/cloudapi/storage_policy/models.go
@@ -0,0 +1,40 @@
+package storagepolicy
+
+type ListStoragePolicies struct {
+ Data []ItemStoragePolicy `json:"data"`
+ EntryCount uint64 `json:"entryCount"`
+}
+
+type ItemStoragePolicy struct {
+ ID uint64 `json:"id"`
+ GUID uint64 `json:"guid"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ AccessSepPools ListAccessSepPools `json:"access_seps_pools"`
+ Status string `json:"status"`
+ LimitIOPS uint64 `json:"limit_iops"`
+ Usage Usage `json:"usage"`
+}
+
+type InfoStoragePolicy struct {
+ ID uint64 `json:"id"`
+ GUID uint64 `json:"guid"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ AccessSepPools ListAccessSepPools `json:"access_seps_pools"`
+ Status string `json:"status"`
+ LimitIOPS uint64 `json:"limit_iops"`
+ Usage Usage `json:"usage"`
+}
+
+type ListAccessSepPools []AccessSepPool
+
+type AccessSepPool struct {
+ SepID uint64 `json:"sep_id"`
+ PoolNames []string `json:"pool_names"`
+}
+
+type Usage struct {
+ Accounts []uint64 `json:"accounts"`
+ Resgroups []uint64 `json:"resgroups"`
+}
diff --git a/pkg/cloudapi/storage_policy/storage_policy.go b/pkg/cloudapi/storage_policy/storage_policy.go
new file mode 100644
index 0000000..42b42a2
--- /dev/null
+++ b/pkg/cloudapi/storage_policy/storage_policy.go
@@ -0,0 +1,15 @@
+package storagepolicy
+
+import "repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
+
+// Structure for creating request to storage policy
+type StoragePolicy struct {
+ client interfaces.Caller
+}
+
+// Builder for stack endpoint
+func New(client interfaces.Caller) *StoragePolicy {
+ return &StoragePolicy{
+ client: client,
+ }
+}
diff --git a/pkg/cloudapi/storagepolicy.go b/pkg/cloudapi/storagepolicy.go
new file mode 100644
index 0000000..9f8b288
--- /dev/null
+++ b/pkg/cloudapi/storagepolicy.go
@@ -0,0 +1,10 @@
+package cloudapi
+
+import (
+ storagepolicy "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/storage_policy"
+)
+
+// Accessing the Storage Policy method group
+func (ca *CloudAPI) StoragePolicy() *storagepolicy.StoragePolicy {
+ return storagepolicy.New(ca.client)
+}
diff --git a/pkg/cloudapi/trunk/list.go b/pkg/cloudapi/trunk/list.go
index 6039949..eeca231 100644
--- a/pkg/cloudapi/trunk/list.go
+++ b/pkg/cloudapi/trunk/list.go
@@ -27,6 +27,9 @@ type ListRequest struct {
// Page size
Size uint64 `url:"size,omitempty" json:"size,omitempty"`
+
+ // Status
+ Status string `url:"status,omitempty" json:"status,omitempty"`
}
// List gets list of all trunks as a ListTrunks struct
diff --git a/pkg/cloudapi/vins/list.go b/pkg/cloudapi/vins/list.go
index 631c40a..0879cdc 100644
--- a/pkg/cloudapi/vins/list.go
+++ b/pkg/cloudapi/vins/list.go
@@ -46,6 +46,11 @@ type ListRequest struct {
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
+ // Sort by zone id
+ // Default value: 0
+ // Required: false
+ ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
+
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
diff --git a/pkg/cloudapi/vins/models.go b/pkg/cloudapi/vins/models.go
index 6dfef13..664fc8c 100644
--- a/pkg/cloudapi/vins/models.go
+++ b/pkg/cloudapi/vins/models.go
@@ -673,6 +673,9 @@ type RecordVINS struct {
// Description
Description string `json:"desc"`
+ // Enable Security Groups
+ EnableSecGroups bool `json:"enable_secgroups"`
+
// Grid ID
GID uint64 `json:"gid"`
diff --git a/pkg/cloudapi/zone/models.go b/pkg/cloudapi/zone/models.go
index b2340ca..110f9f9 100644
--- a/pkg/cloudapi/zone/models.go
+++ b/pkg/cloudapi/zone/models.go
@@ -22,12 +22,30 @@ type RecordZone struct {
// Name
Name string `json:"name"`
+ // List of associated account IDs
+ AccountIDs []uint64 `json:"accountIds"`
+
+ // List of associated bservice IDs
+ BserviceIDs []uint64 `json:"bserviceIds"`
+
+ // List of associated compute IDs
+ ComputeIDs []uint64 `json:"computeIds"`
+
// Description
Description string `json:"description"`
// Deletable flag
Deletable bool `json:"deletable"`
+ // List of associated ExtNet IDs
+ ExtnetIDs []uint64 `json:"extnetIds"`
+
+ // List of associated K8s IDs
+ K8SIDs []uint64 `json:"k8sIds"`
+
+ // List of associated LB IDs
+ LBIDs []uint64 `json:"lbIds"`
+
// Status
Status string `json:"status"`
@@ -39,4 +57,7 @@ type RecordZone struct {
// List of associated Node IDs
NodeIDs []uint64 `json:"nodeIds"`
+
+ // List of associated VINS IDs
+ VinsIDs []uint64 `json:"vinsIds"`
}
diff --git a/pkg/cloudbroker/account/add_storage_policy.go b/pkg/cloudbroker/account/add_storage_policy.go
new file mode 100644
index 0000000..62a6100
--- /dev/null
+++ b/pkg/cloudbroker/account/add_storage_policy.go
@@ -0,0 +1,46 @@
+package account
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// AddStoragePolicyRequest struct for adding storage policy to the account
+type AddStoragePolicyRequest struct {
+ // ID of account to add to
+ // Required: true
+ AccountID uint64 `url:"account_id" json:"account_id" validate:"required"`
+
+ // ID of the storage policy to which to connect account
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
+ // Limit storage resources GB. Or -1 unlimit
+ // Required: false
+ Limit int `url:"limit,omitempty" json:"limit,omitempty"`
+}
+
+// AddStoragePolicy add storage policy to the account.
+func (a Account) AddStoragePolicy(ctx context.Context, req AddStoragePolicyRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/account/add_storage_policy"
+
+ res, err := a.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
+}
diff --git a/pkg/cloudbroker/account/create.go b/pkg/cloudbroker/account/create.go
index 087211b..fee5f2e 100644
--- a/pkg/cloudbroker/account/create.go
+++ b/pkg/cloudbroker/account/create.go
@@ -5,6 +5,7 @@ import (
"net/http"
"strconv"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
@@ -26,6 +27,10 @@ type CreateRequest struct {
// Required: false
EmailAddress string `url:"emailaddress,omitempty" json:"emailaddress,omitempty" validate:"omitempty,email"`
+ // Storage policies
+ // Required: false
+ StoragePolicies []StoragePolicy `url:"-" json:"storage_policies" validate:"required"`
+
// Max size of memory in MB
// Required: false
MaxMemoryCapacity int64 `url:"maxMemoryCapacity,omitempty" json:"maxMemoryCapacity,omitempty"`
@@ -73,6 +78,11 @@ type CreateRequest struct {
ZoneIDs []uint64 `url:"zoneIds,omitempty" json:"zoneIds,omitempty"`
}
+type StoragePolicy struct {
+ ID int64 `url:"id" json:"id"`
+ Limit int `url:"limit" json:"limit"`
+}
+
// Create creates account
// Setting a cloud unit maximum to -1 or empty will not put any restrictions on the resource
func (a Account) Create(ctx context.Context, req CreateRequest) (uint64, error) {
@@ -83,7 +93,7 @@ func (a Account) Create(ctx context.Context, req CreateRequest) (uint64, error)
url := "/cloudbroker/account/create"
- res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
+ res, err := a.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
if err != nil {
return 0, err
}
diff --git a/pkg/cloudbroker/account/del_storage_policy.go b/pkg/cloudbroker/account/del_storage_policy.go
new file mode 100644
index 0000000..e5e7f3d
--- /dev/null
+++ b/pkg/cloudbroker/account/del_storage_policy.go
@@ -0,0 +1,42 @@
+package account
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// DelStoragePolicyRequest struct for deleting storage policy to the account
+type DelStoragePolicyRequest struct {
+ // ID of account
+ // Required: true
+ AccountID uint64 `url:"account_id" json:"account_id" validate:"required"`
+
+ // ID of the storage policy to which to disconnect account
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+}
+
+// DelStoragePolicy delete storage policy to the account.
+func (a Account) DelStoragePolicy(ctx context.Context, req DelStoragePolicyRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/account/del_storage_policy"
+
+ res, err := a.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
+}
diff --git a/pkg/cloudbroker/account/list.go b/pkg/cloudbroker/account/list.go
index 13548f8..6e33576 100644
--- a/pkg/cloudbroker/account/list.go
+++ b/pkg/cloudbroker/account/list.go
@@ -30,6 +30,11 @@ type ListRequest struct {
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
+ // Sort by zone id
+ // Default value: 0
+ // Required: false
+ ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
+
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
diff --git a/pkg/cloudbroker/account/models.go b/pkg/cloudbroker/account/models.go
index e0a545a..35625b7 100644
--- a/pkg/cloudbroker/account/models.go
+++ b/pkg/cloudbroker/account/models.go
@@ -133,6 +133,9 @@ type ResourceLimits struct {
// GPUUnits
GPUUnits float64 `json:"gpu_units"`
+
+ // Storage policies
+ StoragePolicies []StoragePolicy `json:"storage_policy"`
}
// Main information about account
@@ -200,6 +203,9 @@ type InfoAccount struct {
// Status
Status string `json:"status"`
+ // Storage policy ids
+ StoragePolicyIDs []uint64 `json:"storage_policy_ids"`
+
// UniqPools
UniqPools []string `json:"uniqPools"`
@@ -234,7 +240,7 @@ type RecordAccount struct {
ACL []ACLWithEmails `json:"acl"`
// Zones IDs
- ZoneIDs []ZoneID
+ ZoneIDs []ZoneID `json:"zoneIds"`
}
// More information about account
@@ -249,7 +255,7 @@ type ItemAccount struct {
InfoAccount
// Zones
- ZoneIDs []uint64
+ ZoneIDs []uint64 `json:"zoneIds"`
}
// List of accounts
diff --git a/pkg/cloudbroker/account/update.go b/pkg/cloudbroker/account/update.go
index 7c4fe5d..afe8843 100644
--- a/pkg/cloudbroker/account/update.go
+++ b/pkg/cloudbroker/account/update.go
@@ -5,6 +5,7 @@ import (
"net/http"
"strconv"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
@@ -46,6 +47,10 @@ type UpdateRequest struct {
// Required: false
SendAccessEmails bool `url:"sendAccessEmails" json:"sendAccessEmails"`
+ // Storage policies
+ // Required: false
+ StoragePolicies []StoragePolicy `url:"-" json:"storage_policies,omitempty"`
+
// Limit (positive) or disable (0) GPU resources
// Required: false
GPUUnits int64 `url:"gpu_units,omitempty" json:"gpu_units,omitempty"`
@@ -74,7 +79,7 @@ func (a Account) Update(ctx context.Context, req UpdateRequest) (bool, error) {
url := "/cloudbroker/account/update"
- res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
+ res, err := a.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
if err != nil {
return false, err
}
diff --git a/pkg/cloudbroker/audit/models.go b/pkg/cloudbroker/audit/models.go
index ef9599b..e498014 100644
--- a/pkg/cloudbroker/audit/models.go
+++ b/pkg/cloudbroker/audit/models.go
@@ -11,6 +11,9 @@ type ItemAudit struct {
// GUID
GUID string `json:"guid"`
+ // Correlation ID
+ CorrelationID string `json:"correlation_id"`
+
// Kwargs
Kwargs string `json:"kwargs"`
@@ -60,6 +63,9 @@ type RecordAudit struct {
// Call
Call string `json:"call"`
+ // Correlation ID
+ CorrelationID string `json:"correlation_id"`
+
// GUID
GUID string `json:"guid"`
diff --git a/pkg/cloudbroker/bservice/group_add.go b/pkg/cloudbroker/bservice/group_add.go
index 618276e..c3e59c9 100644
--- a/pkg/cloudbroker/bservice/group_add.go
+++ b/pkg/cloudbroker/bservice/group_add.go
@@ -38,11 +38,9 @@ type GroupAddRequest struct {
// Required: true
ImageID uint64 `url:"imageId" json:"imageId" validate:"required"`
- // Compute driver
- // should be one of:
- // - KVM_X86
+ // Compute driver like a KVM_X86, etc.
// Required: true
- Driver string `url:"driver" json:"driver" validate:"driver"`
+ Driver string `url:"driver" json:"driver" validate:"required"`
// Storage endpoint provider ID
// Required: false
@@ -75,6 +73,10 @@ type GroupAddRequest struct {
//Chipset "i440fx" or "Q35
//Required: false
Chipset string `url:"chipset,omitempty" json:"chipset,omitempty" validate:"chipset"`
+
+ // ID of the chosen storage policy
+ // Required: false
+ StoragePolicyID uint64 `url:"storage_policy_id,omitempty" json:"storage_policy_id,omitempty"`
}
// GetRAM returns RAM field values
diff --git a/pkg/cloudbroker/bservice/list.go b/pkg/cloudbroker/bservice/list.go
index 9f2ee7a..ff4ace7 100644
--- a/pkg/cloudbroker/bservice/list.go
+++ b/pkg/cloudbroker/bservice/list.go
@@ -42,6 +42,11 @@ type ListRequest struct {
// Required: false
AccountName string `url:"accountName,omitempty" json:"accountName,omitempty"`
+ // Sort by zone id
+ // Default value: 0
+ // Required: false
+ ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
+
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
diff --git a/pkg/cloudbroker/compute/audits.go b/pkg/cloudbroker/compute/audits.go
index 23943e6..6ee690a 100644
--- a/pkg/cloudbroker/compute/audits.go
+++ b/pkg/cloudbroker/compute/audits.go
@@ -12,11 +12,47 @@ import (
type AuditsRequest struct {
// ID of the compute
// Required: true
- ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
+ ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
+
+ // Find all audits after point in time
+ // Required: false
+ TimestampAT uint64 `url:"timestamp_at,omitempty" json:"timestamp_at,omitempty"`
+
+ // Find all audits before point in time
+ // Required: false
+ TimestampTO uint64 `url:"timestamp_to,omitempty" json:"timestamp_to,omitempty"`
+
+ // Find by user
+ // Required: false
+ User string `url:"user,omitempty" json:"user,omitempty"`
+
+ // Find by api endpoints
+ // Required: false
+ Call string `url:"call,omitempty" json:"call,omitempty"`
+
+ // Sort by one of supported fields, format ±
+ // Required: false
+ SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty"`
+
+ // Page number
+ // Required: false
+ Page uint64 `url:"page,omitempty" json:"page,omitempty"`
+
+ // Page size
+ // Required: false
+ Size uint64 `url:"size,omitempty" json:"size,omitempty"`
+
+ // Find by HTTP min status code
+ // Required: false
+ MinStatusCode uint64 `url:"min_status_code,omitempty" json:"min_status_code,omitempty"`
+
+ // Find by HTTP max status code
+ // Required: false
+ MaxStatusCode uint64 `url:"max_status_code,omitempty" json:"max_status_code,omitempty"`
}
// Audits gets audit records for the specified compute object
-func (c Compute) Audits(ctx context.Context, req AuditsRequest) (ListDetailedAudits, error) {
+func (c Compute) Audits(ctx context.Context, req AuditsRequest) (*ListDetailedAudits, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
@@ -24,7 +60,7 @@ func (c Compute) Audits(ctx context.Context, req AuditsRequest) (ListDetailedAud
url := "/cloudbroker/compute/audits"
- res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
+ res, err := c.client.DecortApiCall(ctx, http.MethodGet, url, req)
if err != nil {
return nil, err
}
@@ -36,5 +72,5 @@ func (c Compute) Audits(ctx context.Context, req AuditsRequest) (ListDetailedAud
return nil, err
}
- return list, nil
+ return &list, nil
}
diff --git a/pkg/cloudbroker/compute/change_secutity_group.go b/pkg/cloudbroker/compute/change_secutity_group.go
new file mode 100644
index 0000000..eb494a7
--- /dev/null
+++ b/pkg/cloudbroker/compute/change_secutity_group.go
@@ -0,0 +1,50 @@
+package compute
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// ChangeSecGroupsRequest struct to change security groups for compute
+type ChangeSecGroupsRequest struct {
+ // Identifier compute
+ // Required: true
+ ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
+
+ // Interface name or MAC address
+ // Required: true
+ Interface string `url:"interface" json:"interface" validate:"required"`
+
+ // List of security group IDs to assign to this interface
+ // Required: false
+ SecGroups []uint64 `url:"security_groups,omitempty" json:"security_groups,omitempty"`
+
+ // Flag indicating whether security groups are enabled for this interface
+ // Required: false
+ EnableSecGroups bool `url:"enable_secgroups,omitempty" json:"enable_secgroups,omitempty"`
+}
+
+// ChangeSecGroups changes security groups for compute
+func (c Compute) ChangeSecGroups(ctx context.Context, req ChangeSecGroupsRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/compute/change_security_groups"
+
+ res, err := c.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
+}
diff --git a/pkg/cloudbroker/compute/create_template_from_blank.go b/pkg/cloudbroker/compute/create_template_from_blank.go
index 287f906..c63c4a6 100644
--- a/pkg/cloudbroker/compute/create_template_from_blank.go
+++ b/pkg/cloudbroker/compute/create_template_from_blank.go
@@ -27,6 +27,10 @@ type CreateTemplateFromBlankRequest struct {
// Required: true
ImageType string `url:"imagetype" json:"imagetype" validate:"imageType"`
+ // Storage policy id of compute. The rules of the specified storage policy will be used.
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// Username for the image
// Required: false
Username string `url:"username,omitempty" json:"username,omitempty"`
diff --git a/pkg/cloudbroker/compute/disk_add.go b/pkg/cloudbroker/compute/disk_add.go
index 12a3b8a..4fef0de 100644
--- a/pkg/cloudbroker/compute/disk_add.go
+++ b/pkg/cloudbroker/compute/disk_add.go
@@ -27,6 +27,10 @@ type DiskAddRequest struct {
// Required: false
SepID uint64 `url:"sepId,omitempty" json:"sepId,omitempty"`
+ // Storage policy id of compute. The rules of the specified storage policy will be used.
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// Type of the disk
// Should be one of:
// - D
diff --git a/pkg/cloudbroker/compute/list.go b/pkg/cloudbroker/compute/list.go
index 427245a..80b0ccd 100644
--- a/pkg/cloudbroker/compute/list.go
+++ b/pkg/cloudbroker/compute/list.go
@@ -74,6 +74,11 @@ type ListRequest struct {
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
+ // Sort by zone id
+ // Default value: 0
+ // Required: false
+ ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
+
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
diff --git a/pkg/cloudbroker/compute/migrate.go b/pkg/cloudbroker/compute/migrate.go
index 264ab89..42e521e 100644
--- a/pkg/cloudbroker/compute/migrate.go
+++ b/pkg/cloudbroker/compute/migrate.go
@@ -25,7 +25,7 @@ type MigrateRequest struct {
Force bool `url:"force,omitempty" json:"force,omitempty"`
}
-type asyncWrapperMigrateRequest struct {
+type AsyncWrapperMigrateRequest struct {
MigrateRequest
SyncMode bool `url:"sync"`
}
@@ -39,7 +39,7 @@ func (c Compute) Migrate(ctx context.Context, req MigrateRequest) (bool, error)
url := "/cloudbroker/compute/migrate"
- syncReq := asyncWrapperMigrateRequest{MigrateRequest: req, SyncMode: true}
+ syncReq := AsyncWrapperMigrateRequest{MigrateRequest: req, SyncMode: true}
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, syncReq)
if err != nil {
@@ -63,7 +63,7 @@ func (c Compute) AsyncMigrate(ctx context.Context, req MigrateRequest) (string,
url := "/cloudbroker/compute/migrate"
- asyncReq := asyncWrapperMigrateRequest{MigrateRequest: req, SyncMode: false}
+ asyncReq := AsyncWrapperMigrateRequest{MigrateRequest: req, SyncMode: false}
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, asyncReq)
if err != nil {
diff --git a/pkg/cloudbroker/compute/models.go b/pkg/cloudbroker/compute/models.go
index 60a7412..a35f205 100644
--- a/pkg/cloudbroker/compute/models.go
+++ b/pkg/cloudbroker/compute/models.go
@@ -221,8 +221,14 @@ type ItemDetailedAudit struct {
User string `json:"user"`
}
-// List of detailed audit
-type ListDetailedAudits []ItemDetailedAudit
+// List Detailed audits
+type ListDetailedAudits struct {
+ // Data
+ Data []ItemDetailedAudit `json:"data"`
+
+ // Entry count
+ EntryCount uint64 `json:"entryCount"`
+}
// Main information about port forward
type ItemPFW struct {
@@ -475,9 +481,15 @@ type ItemDisk struct {
// Status
Status string `json:"status"`
+ // Storage policy id of disk.
+ StoragePolicyID uint64 `json:"storage_policy_id"`
+
// Tech status
TechStatus string `json:"techStatus"`
+ // Need to clean before destroy
+ ToClean bool `json:"to_clean"`
+
// Type
Type string `json:"type"`
@@ -525,6 +537,9 @@ type ItemInterface struct {
// Enabled
Enabled bool `json:"enabled"`
+ // Enable security groups
+ EnableSecGroups bool `json:"enable_secgroups"`
+
// FLIPGroup ID
FLIPGroupID uint64 `json:"flipgroupId"`
@@ -567,6 +582,9 @@ type ItemInterface struct {
// QOS
QOS QOS `json:"qos"`
+ // List of security groups
+ SecGroups []uint64 `json:"security_groups"`
+
// SDN interface ID
SDNInterfaceID string `json:"sdn_interface_id"`
diff --git a/pkg/cloudbroker/compute/net_attach.go b/pkg/cloudbroker/compute/net_attach.go
index 7975b14..ae6529e 100644
--- a/pkg/cloudbroker/compute/net_attach.go
+++ b/pkg/cloudbroker/compute/net_attach.go
@@ -42,12 +42,24 @@ type NetAttachRequest struct {
// Used only for EXTNET and DPDK
// For DPDK must be 1-9216
// For EXTNET must be 1500-9216
- // Required: false
+ // Required: false
MTU uint64 `url:"mtu,omitempty" json:"mtu,omitempty" validate:"omitempty,mtu"`
// Unique identifier of logical port on SDN side
// Required: false
SDNInterfaceID string `url:"sdn_interface_id,omitempty" json:"sdn_interface_id,omitempty" validate:"omitempty"`
+
+ // List of security group IDs to assign to this interface
+ // Required: false
+ SecGroups []uint64 `url:"security_groups,omitempty" json:"security_groups,omitempty"`
+
+ // Flag indicating whether security groups are enabled for this interface
+ // Required: false
+ EnableSecGroups bool `url:"enable_secgroups,omitempty" json:"enable_secgroups,omitempty"`
+
+ // Flag indicating whether this interface is enabled (only for VINS, EXTNET, DPDK, SDN, TRUNK)
+ // Required: false
+ Enabled interface{} `url:"enabled,omitempty" json:"enabled,omitempty" validate:"omitempty,isBool"`
}
// NetAttach attaches network to compute and gets info about network
diff --git a/pkg/cloudbroker/compute/redeploy.go b/pkg/cloudbroker/compute/redeploy.go
index 5a74625..e9e43a7 100644
--- a/pkg/cloudbroker/compute/redeploy.go
+++ b/pkg/cloudbroker/compute/redeploy.go
@@ -18,6 +18,10 @@ type RedeployRequest struct {
// Required: false
ImageID uint64 `url:"imageId,omitempty" json:"imageId,omitempty"`
+ // Storage policy id of compute. The rules of the specified storage policy will be used.
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// New size for the boot disk in GB, if boot disk size change is required
// Required: false
DiskSize uint64 `url:"diskSize,omitempty" json:"diskSize,omitempty"`
diff --git a/pkg/cloudbroker/disks/change_disk_storage_policy.go b/pkg/cloudbroker/disks/change_disk_storage_policy.go
new file mode 100644
index 0000000..3d96fdf
--- /dev/null
+++ b/pkg/cloudbroker/disks/change_disk_storage_policy.go
@@ -0,0 +1,42 @@
+package disks
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// ChangeDiskStoragePolicyRequest struct to change storage policy for disk
+type ChangeDiskStoragePolicyRequest struct {
+ // ID of the disk
+ // Required: true
+ DiskID uint64 `url:"disk_id" json:"disk_id" validate:"required"`
+
+ // ID of the storage policy to which to connect account
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+}
+
+// ChangeDiskStoragePolicy changes storage policy for disk
+func (d Disks) ChangeDiskStoragePolicy(ctx context.Context, req ChangeDiskStoragePolicyRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/disks/change_disk_storage_policy"
+
+ 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
+}
diff --git a/pkg/cloudbroker/disks/create.go b/pkg/cloudbroker/disks/create.go
index ae585fd..561a5e1 100644
--- a/pkg/cloudbroker/disks/create.go
+++ b/pkg/cloudbroker/disks/create.go
@@ -18,6 +18,10 @@ type CreateRequest struct {
// Required: true
Name string `url:"name" json:"name" validate:"required"`
+ // ID of the storage policy under the disk will be created
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// Description of disk
// Required: false
Description string `url:"description,omitempty" json:"description,omitempty"`
diff --git a/pkg/cloudbroker/disks/from_platform_disk.go b/pkg/cloudbroker/disks/from_platform_disk.go
index 1682abd..21bc3ba 100644
--- a/pkg/cloudbroker/disks/from_platform_disk.go
+++ b/pkg/cloudbroker/disks/from_platform_disk.go
@@ -43,11 +43,6 @@ type FromPlatformDiskRequest struct {
// Required: false
PoolName string `url:"poolName,omitempty" json:"poolName,omitempty"`
- // List of types of compute suitable for image
- // Example: [ "KVM_X86" ]
- // Required: true
- Drivers []string `url:"drivers" json:"drivers" validate:"required"`
-
// Does this machine supports hot resize
// Required: false
HotResize bool `url:"hotresize" json:"hotresize"`
diff --git a/pkg/cloudbroker/disks/models.go b/pkg/cloudbroker/disks/models.go
index d3791d6..aa565aa 100644
--- a/pkg/cloudbroker/disks/models.go
+++ b/pkg/cloudbroker/disks/models.go
@@ -170,9 +170,15 @@ type InfoDisk struct {
// Status
Status string `json:"status"`
+ // Storage policy ID
+ StoragePolicyID uint64 `json:"storage_policy_id"`
+
// Tech status
TechStatus string `json:"techStatus"`
+ // Need to clean before destroy
+ ToClean bool `json:"to_clean"`
+
// Type
Type string `json:"type"`
diff --git a/pkg/cloudbroker/disks/replicate.go b/pkg/cloudbroker/disks/replicate.go
index 64917bb..ca2ecce 100644
--- a/pkg/cloudbroker/disks/replicate.go
+++ b/pkg/cloudbroker/disks/replicate.go
@@ -25,9 +25,13 @@ type ReplicateRequest struct {
// Pool name to create slave disk in
// Required: true
PoolName string `url:"poolName" json:"poolName" validate:"required"`
+
+ // ID of the storage policy under the disk will be created
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
}
-// Create an empty disk in chosen SEP and pool combination.
+// Replicate create an empty disk in chosen SEP and pool combination.
// Starts replication between chosen disk and newly created disk
// Note: only TATLIN type SEP are supported for replications between
func (d Disks) Replicate(ctx context.Context, req ReplicateRequest) (uint64, error) {
diff --git a/pkg/cloudbroker/dpdknet/models.go b/pkg/cloudbroker/dpdknet/models.go
index 7bcf84d..ebcca93 100644
--- a/pkg/cloudbroker/dpdknet/models.go
+++ b/pkg/cloudbroker/dpdknet/models.go
@@ -14,6 +14,9 @@ type RecordDPDKNet struct {
// Description
Description string `json:"description"`
+ // Enable Security Groups
+ EnableSecGroups bool `json:"enable_secgroups"`
+
// Grid ID
GID uint64 `json:"gid"`
@@ -63,6 +66,9 @@ type ItemDPDKNet struct {
// Description
Description string `json:"description"`
+ // Enable Security Groups
+ EnableSecGroups bool `json:"enable_secgroups"`
+
// Grid ID
GID uint64 `json:"gid"`
diff --git a/pkg/cloudbroker/dpdknet/update.go b/pkg/cloudbroker/dpdknet/update.go
index 06c3481..eb5c0a1 100644
--- a/pkg/cloudbroker/dpdknet/update.go
+++ b/pkg/cloudbroker/dpdknet/update.go
@@ -37,6 +37,10 @@ type UpdateRequest struct {
// Name of OVS Bridge to use for DPDK network
// Required: true
OVSBridge string `url:"ovsBridge,omitempty" json:"ovsBridge,omitempty"`
+
+ // Flag indicating whether security groups are enabled for this network
+ // Required: false
+ EnableSecGroups interface{} `url:"enable_secgroups,omitempty" json:"enable_secgroups,omitempty" validate:"omitempty,isBool"`
}
// Update updates a DPDK networks
diff --git a/pkg/cloudbroker/extnet/list.go b/pkg/cloudbroker/extnet/list.go
index 0f44c49..7983493 100644
--- a/pkg/cloudbroker/extnet/list.go
+++ b/pkg/cloudbroker/extnet/list.go
@@ -42,6 +42,11 @@ type ListRequest struct {
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
+ // Sort by zone id
+ // Default value: 0
+ // Required: false
+ ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
+
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
diff --git a/pkg/cloudbroker/extnet/models.go b/pkg/cloudbroker/extnet/models.go
index fcc44b9..a84c7f6 100644
--- a/pkg/cloudbroker/extnet/models.go
+++ b/pkg/cloudbroker/extnet/models.go
@@ -58,6 +58,9 @@ type ItemExtNet struct {
// CKey
CKey string `json:"_ckey"`
+ // Enable Security Groups
+ EnableSecGroups bool `json:"enable_secgroups"`
+
// Meta
Meta []interface{} `json:"_meta"`
@@ -166,6 +169,9 @@ type RecordExtNet struct {
// List excludes
Excluded ListReservations `json:"excluded"`
+ // Enable Security Groups
+ EnableSecGroups bool `json:"enable_secgroups"`
+
// Free IPs number
FreeIPs int64 `json:"free_ips"`
diff --git a/pkg/cloudbroker/extnet/update.go b/pkg/cloudbroker/extnet/update.go
index 7c35cb0..5bac323 100644
--- a/pkg/cloudbroker/extnet/update.go
+++ b/pkg/cloudbroker/extnet/update.go
@@ -26,6 +26,10 @@ type UpdateRequest struct {
// Default: 1500
// Required: false
MTU uint64 `url:"mtu,omitempty" json:"mtu,omitempty"`
+
+ // Flag indicating whether security groups are enabled for this network
+ // Required: false
+ EnableSecGroups interface{} `url:"enable_secgroups,omitempty" json:"enable_secgroups,omitempty" validate:"omitempty,isBool"`
}
// Update updates external network parameters
diff --git a/pkg/cloudbroker/image/change_storage_policy.go b/pkg/cloudbroker/image/change_storage_policy.go
new file mode 100644
index 0000000..5a9bf3c
--- /dev/null
+++ b/pkg/cloudbroker/image/change_storage_policy.go
@@ -0,0 +1,41 @@
+package image
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type ChangeStoragePolicyRequest struct {
+ // ID of the image to change the storage policy
+ // Required: true
+ ImageID uint64 `url:"image_id" json:"image_id" validate:"required"`
+
+ // ID of the storage policy to move the image to
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+}
+
+// ChangeStoragePolicy changes the storage policy of the image chosen
+func (i Image) ChangeStoragePolicy(ctx context.Context, req ChangeStoragePolicyRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/image/change_storage_policy"
+
+ res, err := i.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
+}
diff --git a/pkg/cloudbroker/image/create_cdrom_image.go b/pkg/cloudbroker/image/create_cdrom_image.go
index b7946af..e5a4221 100644
--- a/pkg/cloudbroker/image/create_cdrom_image.go
+++ b/pkg/cloudbroker/image/create_cdrom_image.go
@@ -18,6 +18,10 @@ type CreateCDROMImageRequest struct {
// Required: true
URL string `url:"url" json:"url" validate:"required,url"`
+ // ID of the chosen storage policy
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// Account ID to make the image exclusive
// Required: false
AccountID uint64 `url:"accountId,omitempty" json:"accountId,omitempty"`
@@ -37,11 +41,6 @@ type CreateCDROMImageRequest struct {
// Password for remote media download
// Required: false
PasswordDl string `url:"passwordDL,omitempty" json:"passwordDL,omitempty"`
-
- // List of types of compute suitable for image.
- // Example: [ "KVM_X86" ]
- // Required: false
- Drivers []string `url:"drivers,omitempty" json:"drivers,omitempty" validate:"max=2,imageDrivers"`
}
// CreateCDROMImage creates CD-ROM image from an ISO identified by URL
diff --git a/pkg/cloudbroker/image/create_image.go b/pkg/cloudbroker/image/create_image.go
index 79d5efe..b9042c2 100644
--- a/pkg/cloudbroker/image/create_image.go
+++ b/pkg/cloudbroker/image/create_image.go
@@ -34,6 +34,10 @@ type CreateRequest struct {
// Required: true
ImageType string `url:"imagetype" json:"imagetype" validate:"required,imageType"`
+ // ID of the chosen storage policy
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// Select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming
// Should be:
// - eth
@@ -73,11 +77,6 @@ type CreateRequest struct {
// Required: false
PoolName string `url:"poolName,omitempty" json:"poolName,omitempty"`
- // List of types of compute suitable for image
- // Example: [ "KVM_X86" ]
- // Required: required
- Drivers []string `url:"drivers" json:"drivers" validate:"min=1,max=2,imageDrivers"`
-
// Bootable image or not
// Required: false
Bootable bool `url:"bootable,omitempty" json:"bootable,omitempty"`
diff --git a/pkg/cloudbroker/image/create_virtual.go b/pkg/cloudbroker/image/create_virtual.go
index df5685a..e1509a8 100644
--- a/pkg/cloudbroker/image/create_virtual.go
+++ b/pkg/cloudbroker/image/create_virtual.go
@@ -17,6 +17,11 @@ type CreateVirtualRequest struct {
// ID of real image to link this virtual image to upon creation
// Required: true
TargetID uint64 `url:"targetId" json:"targetId" validate:"required"`
+
+ // AccountID to make the virtual image exclusive
+ // Required: false
+ // Default: 0
+ AccountID uint64 `url:"accountId,omitempty" json:"accountId,omitempty"`
}
// CreateVirtual creates virtual image
diff --git a/pkg/cloudbroker/image/models.go b/pkg/cloudbroker/image/models.go
index fd4aaa8..c094a9d 100644
--- a/pkg/cloudbroker/image/models.go
+++ b/pkg/cloudbroker/image/models.go
@@ -110,6 +110,9 @@ type RecordImage struct {
// Status
Status string `json:"status"`
+ // Storage policy ID
+ StoragePolicyID uint64 `json:"storage_policy_id"`
+
// Tech status
TechStatus string `json:"techStatus"`
@@ -236,6 +239,9 @@ type ItemImage struct {
// Status
Status string `json:"status"`
+ // Storage policy ID
+ StoragePolicyID uint64 `json:"storage_policy_id"`
+
// Tech status
TechStatus string `json:"techStatus"`
diff --git a/pkg/cloudbroker/k8ci/create.go b/pkg/cloudbroker/k8ci/create.go
index 3e19f96..09dd07e 100644
--- a/pkg/cloudbroker/k8ci/create.go
+++ b/pkg/cloudbroker/k8ci/create.go
@@ -26,24 +26,10 @@ type CreateRequest struct {
// Required: true
MasterImageID uint64 `url:"masterImageId" json:"masterImageId" validate:"required"`
- // Compute driver
- // Should be one of:
- // - KVM_X86
- // - etc
- // Required: true
- MasterDriver string `url:"masterDriver" json:"masterDriver" validate:"driver"`
-
// Image ID for worker K8S node
// Required: true
WorkerImageID uint64 `url:"workerImageId" json:"workerImageId" validate:"required"`
- // Compute driver
- // Should be one of
- // - KVM_X86
- // - etc
- // Required: true
- WorkerDriver string `url:"workerDriver" json:"workerDriver" validate:"driver"`
-
// List of account IDs, which have access to this item.
// If empty, any account has access
// Required: false
diff --git a/pkg/cloudbroker/k8ci/filter_test.go b/pkg/cloudbroker/k8ci/filter_test.go
index fbaa6d4..5df0376 100644
--- a/pkg/cloudbroker/k8ci/filter_test.go
+++ b/pkg/cloudbroker/k8ci/filter_test.go
@@ -12,7 +12,6 @@ var k8ciItems = ListK8CI{
GUID: 1,
ID: 1,
LBImageID: 5,
- MasterDriver: "KVM_X86",
MasterImageID: 120,
MaxMasterCount: 2,
MaxWorkerCount: 3,
@@ -20,7 +19,6 @@ var k8ciItems = ListK8CI{
SharedWith: []uint64{},
Status: "ENABLED",
Version: "1",
- WorkerDriver: "KVM_X86",
WorkerImageID: 120,
},
},
@@ -32,7 +30,6 @@ var k8ciItems = ListK8CI{
GUID: 2,
ID: 2,
LBImageID: 10,
- MasterDriver: "KVM_X86",
MasterImageID: 121,
MaxMasterCount: 3,
MaxWorkerCount: 5,
@@ -40,7 +37,6 @@ var k8ciItems = ListK8CI{
SharedWith: []uint64{},
Status: "DISABLED",
Version: "2",
- WorkerDriver: "KVM_X86",
WorkerImageID: 121,
},
},
@@ -52,7 +48,6 @@ var k8ciItems = ListK8CI{
GUID: 3,
ID: 3,
LBImageID: 12,
- MasterDriver: "KVM_X86",
MasterImageID: 98,
MaxMasterCount: 5,
MaxWorkerCount: 9,
@@ -60,7 +55,6 @@ var k8ciItems = ListK8CI{
SharedWith: []uint64{},
Status: "ENABLED",
Version: "3",
- WorkerDriver: "KVM_X86",
WorkerImageID: 98,
},
},
diff --git a/pkg/cloudbroker/k8ci/list.go b/pkg/cloudbroker/k8ci/list.go
index 538e3fb..68c9651 100644
--- a/pkg/cloudbroker/k8ci/list.go
+++ b/pkg/cloudbroker/k8ci/list.go
@@ -22,14 +22,6 @@ type ListRequest struct {
// Required: false
Status string `url:"status,omitempty" json:"status,omitempty"`
- // Find by worker driver
- // Required: false
- WorkerDriver string `url:"workerDriver,omitempty" json:"workerDriver,omitempty"`
-
- // Find by master driver
- // Required: false
- MasterDriver string `url:"masterDriver,omitempty" json:"masterDriver,omitempty"`
-
// Find by network plugin
// Required: false
NetworkPlugins string `url:"netPlugins,omitempty" json:"masterDrnetPluginsiver,omitempty"`
diff --git a/pkg/cloudbroker/k8ci/list_deleted.go b/pkg/cloudbroker/k8ci/list_deleted.go
index ee66bda..1aef4b1 100644
--- a/pkg/cloudbroker/k8ci/list_deleted.go
+++ b/pkg/cloudbroker/k8ci/list_deleted.go
@@ -18,14 +18,6 @@ type ListDeletedRequest struct {
// Required: false
Name string `url:"name,omitempty" json:"name,omitempty"`
- // Find by worker driver
- // Required: false
- WorkerDriver string `url:"workerDriver,omitempty" json:"workerDriver,omitempty"`
-
- // Find by master driver
- // Required: false
- MasterDriver string `url:"masterDriver,omitempty" json:"masterDriver,omitempty"`
-
// Find by network plugin
// Required: false
NetworkPlugins string `url:"netPlugins,omitempty" json:"netPlugins,omitempty"`
diff --git a/pkg/cloudbroker/k8ci/models.go b/pkg/cloudbroker/k8ci/models.go
index 647956b..cdeb03b 100644
--- a/pkg/cloudbroker/k8ci/models.go
+++ b/pkg/cloudbroker/k8ci/models.go
@@ -34,9 +34,6 @@ type RecordK8CIList struct {
// Load balancer image ID
LBImageID uint64 `json:"lbImageId"`
- // Master driver
- MasterDriver string `json:"masterDriver"`
-
// Master image ID
MasterImageID uint64 `json:"masterImageId"`
@@ -58,14 +55,11 @@ type RecordK8CIList struct {
// Version
Version string `json:"version"`
- // Worker driver
- WorkerDriver string `json:"workerDriver"`
-
// Worker image ID
WorkerImageID uint64 `json:"workerImageId"`
}
-// Detailed information about K8CI
+// Detailed information about K8CI
type RecordK8CI struct {
// Description
Description string `json:"desc"`
@@ -82,12 +76,12 @@ type RecordK8CI struct {
// Load balancer image ID
LBImageID uint64 `json:"lbImageId"`
- // Master driver
- MasterDriver string `json:"masterDriver"`
-
// Master image ID
MasterImageID uint64 `json:"masterImageId"`
+ // Master driver
+ MasterDriver string `json:"masterDriver"`
+
// Max master count
MaxMasterCount uint64 `json:"maxMasterCount"`
@@ -112,9 +106,9 @@ type RecordK8CI struct {
// Version
Version string `json:"version"`
- // Worker driver
- WorkerDriver string `json:"workerDriver"`
-
// Worker image ID
WorkerImageID uint64 `json:"workerImageId"`
+
+ // Worker driver
+ WorkerDriver string `json:"workerDriver"`
}
diff --git a/pkg/cloudbroker/k8s/create.go b/pkg/cloudbroker/k8s/create.go
index c30cf81..5c07c28 100644
--- a/pkg/cloudbroker/k8s/create.go
+++ b/pkg/cloudbroker/k8s/create.go
@@ -31,6 +31,10 @@ type CreateRequest struct {
// Required: true
NetworkPlugin string `url:"networkPlugin" json:"networkPlugin" validate:"required,networkPlugin"`
+ // ID of the chosen storage policy
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// ID of SEP to create boot disks for master nodes.
// Uses images SEP ID if not set
// Required: false
diff --git a/pkg/cloudbroker/k8s/list.go b/pkg/cloudbroker/k8s/list.go
index a677d84..8a088b8 100644
--- a/pkg/cloudbroker/k8s/list.go
+++ b/pkg/cloudbroker/k8s/list.go
@@ -50,6 +50,11 @@ type ListRequest struct {
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
+ // Sort by zone id
+ // Default value: 0
+ // Required: false
+ ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
+
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
diff --git a/pkg/cloudbroker/k8s/workers_group_add.go b/pkg/cloudbroker/k8s/workers_group_add.go
index 3fad133..5ae6334 100644
--- a/pkg/cloudbroker/k8s/workers_group_add.go
+++ b/pkg/cloudbroker/k8s/workers_group_add.go
@@ -18,6 +18,10 @@ type WorkersGroupAddRequest struct {
// Required: true
Name string `url:"name" json:"name" validate:"required"`
+ // ID of the chosen storage policy
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// ID of SEP to create boot disks for default worker nodes group.
// Uses images SEP ID if not set
// Required: false
diff --git a/pkg/cloudbroker/kvmx86/create.go b/pkg/cloudbroker/kvmx86/create.go
index 999bcdf..44138e1 100644
--- a/pkg/cloudbroker/kvmx86/create.go
+++ b/pkg/cloudbroker/kvmx86/create.go
@@ -42,6 +42,18 @@ type Interface struct {
// SDN interface id
// Required: false
SDNInterfaceID string `url:"sdn_interface_id,omitempty" json:"sdn_interface_id,omitempty"`
+
+ // List of security group IDs to assign to this interface
+ // Required: false
+ SecGroups []uint64 `url:"security_groups,omitempty" json:"security_groups,omitempty"`
+
+ // Flag indicating whether security groups are enabled for this interface
+ // Required: false
+ EnableSecGroups bool `url:"enable_secgroups,omitempty" json:"enable_secgroups,omitempty"`
+
+ // Flag indicating whether this interface is enabled (only for VINS, EXTNET, DPDK, SDN, TRUNK)
+ // Required: false
+ Enabled interface{} `url:"enabled,omitempty" json:"enabled,omitempty" validate:"omitempty,isBool"`
}
// DataDisk detailed struct for DataDisks field in CreateRequest, CreateBlankRequest and MassCreateRequest
@@ -54,6 +66,10 @@ type DataDisk struct {
// Required: true
Size uint64 `url:"size" json:"size" validate:"required"`
+ // Storage policy id of disk. The rules of the specified storage policy will be used.
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
// Storage endpoint provider ID
// By default the same with boot disk
// Required: false
@@ -92,6 +108,10 @@ type CreateRequest struct {
// Required: true
RAM uint64 `url:"ram" json:"ram" validate:"required"`
+ // Storage policy id of сompute. The rules of the specified storage policy will be used.
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" 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"`
@@ -154,10 +174,6 @@ type CreateRequest struct {
// Required: false
CustomField string `url:"customFields,omitempty" json:"customFields,omitempty"`
- //Type of compute Stateful (KVM_X86)
- // 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),
diff --git a/pkg/cloudbroker/kvmx86/create_blank.go b/pkg/cloudbroker/kvmx86/create_blank.go
index ab4f54b..ca87665 100644
--- a/pkg/cloudbroker/kvmx86/create_blank.go
+++ b/pkg/cloudbroker/kvmx86/create_blank.go
@@ -28,6 +28,10 @@ type CreateBlankRequest struct {
// Required: true
RAM uint64 `url:"ram" json:"ram" validate:"required"`
+ // Storage policy id of сompute. The rules of the specified storage policy will be used.
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" 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"`
@@ -61,10 +65,6 @@ type CreateBlankRequest struct {
// Required: false
Description string `url:"desc,omitempty" json:"desc,omitempty"`
- //Type of compute Stateful (KVM_X86)
- // Required: false
- Driver string `url:"driver,omitempty" json:"driver,omitempty"`
-
// Type of the emulated system, Q35 or i440fx
// Required: false
Chipset string `url:"chipset,omitempty" json:"chipset,omitempty" validate:"omitempty,chipset"`
diff --git a/pkg/cloudbroker/kvmx86/mass_create.go b/pkg/cloudbroker/kvmx86/mass_create.go
index 4f34fe8..fa8997b 100644
--- a/pkg/cloudbroker/kvmx86/mass_create.go
+++ b/pkg/cloudbroker/kvmx86/mass_create.go
@@ -31,6 +31,10 @@ type MassCreateRequest struct {
// Required: true
RAM uint64 `url:"ram" json:"ram" validate:"required"`
+ // Storage policy id of сompute. The rules of the specified storage policy will be used.
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" 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"`
diff --git a/pkg/cloudbroker/lb/list.go b/pkg/cloudbroker/lb/list.go
index f554e97..78c61c9 100644
--- a/pkg/cloudbroker/lb/list.go
+++ b/pkg/cloudbroker/lb/list.go
@@ -50,6 +50,11 @@ type ListRequest struct {
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
+ // Sort by zone id
+ // Default value: 0
+ // Required: false
+ ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
+
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
diff --git a/pkg/cloudbroker/node/models.go b/pkg/cloudbroker/node/models.go
index b4c9dd5..abe123e 100644
--- a/pkg/cloudbroker/node/models.go
+++ b/pkg/cloudbroker/node/models.go
@@ -100,6 +100,9 @@ type ConsumptionInfo struct {
type FreeResourcesInfo struct {
// RAM
RAM float64 `json:"RAM"`
+
+ // VCPU
+ VCPU uint64 `json:"vCPU"`
}
// Resources Info
diff --git a/pkg/cloudbroker/rg/add_storage_policy.go b/pkg/cloudbroker/rg/add_storage_policy.go
new file mode 100644
index 0000000..b9cec46
--- /dev/null
+++ b/pkg/cloudbroker/rg/add_storage_policy.go
@@ -0,0 +1,46 @@
+package rg
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// AddStoragePolicyRequest struct for adding storage policy to the resource group
+type AddStoragePolicyRequest struct {
+ // ID of resource group to add to
+ // Required: true
+ RGID uint64 `url:"resgroup_id" json:"resgroup_id" validate:"required"`
+
+ // ID of the storage policy to which to connect resource group
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
+ // Limit storage resources GB. Or -1 unlimit
+ // Required: false
+ Limit int `url:"limit,omitempty" json:"limit,omitempty"`
+}
+
+// AddStoragePolicy add storage policy to the account.
+func (r RG) AddStoragePolicy(ctx context.Context, req AddStoragePolicyRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/rg/add_storage_policy"
+
+ res, err := r.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
+}
diff --git a/pkg/cloudbroker/rg/create.go b/pkg/cloudbroker/rg/create.go
index 2181876..ae30cd5 100644
--- a/pkg/cloudbroker/rg/create.go
+++ b/pkg/cloudbroker/rg/create.go
@@ -5,6 +5,7 @@ import (
"net/http"
"strconv"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
@@ -26,6 +27,10 @@ type CreateRequest struct {
// Required: false
MaxMemoryCapacity int64 `url:"maxMemoryCapacity,omitempty" json:"maxMemoryCapacity,omitempty"`
+ // Storage policies
+ // Required: false
+ StoragePolicies []StoragePolicy `url:"-" json:"storage_policies,omitempty"`
+
// Max size of aggregated virtual disks in GB
// Required: false
MaxVDiskCapacity int64 `url:"maxVDiskCapacity,omitempty" json:"maxVDiskCapacity,omitempty"`
@@ -82,6 +87,11 @@ type CreateRequest struct {
SDNAccessGroupID string `url:"sdn_access_group_id,omitempty" json:"sdn_access_group_id,omitempty"`
}
+type StoragePolicy struct {
+ ID int64 `url:"id" json:"id"`
+ Limit int `url:"limit" json:"limit"`
+}
+
// Create creates resource group
func (r RG) Create(ctx context.Context, req CreateRequest) (uint64, error) {
err := validators.ValidateRequest(req)
@@ -91,7 +101,7 @@ func (r RG) Create(ctx context.Context, req CreateRequest) (uint64, error) {
url := "/cloudbroker/rg/create"
- res, err := r.client.DecortApiCall(ctx, http.MethodPost, url, req)
+ res, err := r.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
if err != nil {
return 0, err
}
diff --git a/pkg/cloudbroker/rg/del_storage_policy.go b/pkg/cloudbroker/rg/del_storage_policy.go
new file mode 100644
index 0000000..23fc0f5
--- /dev/null
+++ b/pkg/cloudbroker/rg/del_storage_policy.go
@@ -0,0 +1,42 @@
+package rg
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// DelStoragePolicyRequest struct for deleting storage policy to the resource group
+type DelStoragePolicyRequest struct {
+ // ID of resource group
+ // Required: true
+ RGID uint64 `url:"resgroup_id" json:"resgroup_id" validate:"required"`
+
+ // ID of the storage policy to which to disconnect account
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+}
+
+// DelStoragePolicy delete storage policy to the account.
+func (r RG) DelStoragePolicy(ctx context.Context, req DelStoragePolicyRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/rg/del_storage_policy"
+
+ res, err := r.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
+}
diff --git a/pkg/cloudbroker/rg/models.go b/pkg/cloudbroker/rg/models.go
index fa5798d..3fbe1e7 100644
--- a/pkg/cloudbroker/rg/models.go
+++ b/pkg/cloudbroker/rg/models.go
@@ -126,6 +126,9 @@ type ResourceLimits struct {
// GPU units
GPUUnits float64 `json:"gpu_units"`
+
+ // Storage policies
+ StoragePolicies []StoragePolicy `json:"storage_policy"`
}
// Detailed information about resource group
@@ -208,6 +211,9 @@ type ItemRG struct {
// Secret
Secret string `json:"secret"`
+ // Storage policy ids
+ StoragePolicyIDs []uint64 `json:"storage_policy_ids"`
+
// Status
Status string `json:"status"`
diff --git a/pkg/cloudbroker/rg/update.go b/pkg/cloudbroker/rg/update.go
index 3afce9c..a967d7e 100644
--- a/pkg/cloudbroker/rg/update.go
+++ b/pkg/cloudbroker/rg/update.go
@@ -5,6 +5,7 @@ import (
"net/http"
"strconv"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
@@ -50,6 +51,10 @@ type UpdateRequest struct {
// Default: false
// Required: false
ClearUniqPools bool `url:"clearUniqPools" json:"clearUniqPools"`
+
+ // Storage policies
+ // Required: false
+ StoragePolicies []StoragePolicy `url:"-" json:"storage_policies,omitempty"`
}
// Update updates resource group
@@ -61,7 +66,7 @@ func (r RG) Update(ctx context.Context, req UpdateRequest) (bool, error) {
url := "/cloudbroker/rg/update"
- res, err := r.client.DecortApiCall(ctx, http.MethodPost, url, req)
+ res, err := r.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
if err != nil {
return false, err
}
diff --git a/pkg/cloudbroker/security_group/create.go b/pkg/cloudbroker/security_group/create.go
new file mode 100644
index 0000000..dfe2407
--- /dev/null
+++ b/pkg/cloudbroker/security_group/create.go
@@ -0,0 +1,46 @@
+package securitygroup
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type CreateRequest struct {
+ // Account ID that owns security group
+ // Required: true
+ AccountID uint64 `url:"account_id" json:"account_id" validate:"required"`
+
+ // Security group name
+ // Required: true
+ Name string `url:"name" json:"name" validate:"required"`
+
+ // Security group description
+ // Required: false
+ Description string `url:"description,omitempty" json:"description,omitempty"`
+}
+
+func (sg SecurityGroup) Create(ctx context.Context, req CreateRequest) (uint64, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return 0, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/security_group/create"
+
+ res, err := sg.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
+ if err != nil {
+ return 0, err
+ }
+
+ result, err := strconv.ParseUint(string(res), 10, 64)
+ if err != nil {
+ return 0, err
+ }
+
+ return result, nil
+
+}
diff --git a/pkg/cloudbroker/security_group/create_rule.go b/pkg/cloudbroker/security_group/create_rule.go
new file mode 100644
index 0000000..f7be1d0
--- /dev/null
+++ b/pkg/cloudbroker/security_group/create_rule.go
@@ -0,0 +1,63 @@
+package securitygroup
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type CreateRuleRequest struct {
+ // Security group ID
+ // Required: true
+ SecurityGroupID uint64 `url:"security_group_id" json:"security_group_id" validate:"required"`
+
+ // Traffic direction (inbound/outbound)
+ // Required: true
+ Direction string `url:"direction" json:"direction" validate:"required,securityGroupDirection"`
+
+ // IP protocol version
+ // Default: IPv4
+ // Required: false
+ Ethertype string `url:"ethertype,omitempty" json:"ethertype,omitempty" validate:"omitempty,securityGroupEthertype"`
+
+ // Network protocol, available values : icmp, tcp, udp
+ // Required: false
+ Protocol string `url:"protocol,omitempty" json:"protocol,omitempty" validate:"omitempty,securityGroupProtocol"`
+
+ // Start port number (for TCP/UDP)
+ // Required: false
+ PortRangeMin uint64 `url:"port_range_min,omitempty" json:"port_range_min,omitempty"`
+
+ // End port number (for TCP/UDP)
+ // Required: false
+ PortRangeMax uint64 `url:"port_range_max,omitempty" json:"port_range_max,omitempty"`
+
+ // Remote IP prefix in CIDR notation
+ // Required: false
+ RemoteIPPrefix string `url:"remote_ip_prefix,omitempty" json:"remote_ip_prefix,omitempty"`
+}
+
+func (sg SecurityGroup) CreateRule(ctx context.Context, req CreateRuleRequest) (uint64, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return 0, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/security_group/create_rule"
+
+ res, err := sg.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
+ if err != nil {
+ return 0, err
+ }
+
+ result, err := strconv.ParseUint(string(res), 10, 64)
+ if err != nil {
+ return 0, err
+ }
+
+ return result, nil
+
+}
diff --git a/pkg/cloudbroker/security_group/delete.go b/pkg/cloudbroker/security_group/delete.go
new file mode 100644
index 0000000..4538a6f
--- /dev/null
+++ b/pkg/cloudbroker/security_group/delete.go
@@ -0,0 +1,36 @@
+package securitygroup
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type DeleteRequest struct {
+ // Security group ID
+ // Required: true
+ SecurityGroupID uint64 `url:"security_group_id" json:"security_group_id" validate:"required"`
+}
+
+func (sg SecurityGroup) Delete(ctx context.Context, req DeleteRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/security_group/delete"
+
+ res, err := sg.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
+}
diff --git a/pkg/cloudbroker/security_group/delete_rule.go b/pkg/cloudbroker/security_group/delete_rule.go
new file mode 100644
index 0000000..9609cec
--- /dev/null
+++ b/pkg/cloudbroker/security_group/delete_rule.go
@@ -0,0 +1,40 @@
+package securitygroup
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type DeleteRuleRequest struct {
+ // Security group ID
+ // Required: true
+ SecurityGroupID uint64 `url:"security_group_id" json:"security_group_id" validate:"required"`
+
+ // Rule ID
+ // Required: true
+ RuleID uint64 `url:"rule_id" json:"rule_id" validate:"required"`
+}
+
+func (sg SecurityGroup) DeleteRule(ctx context.Context, req DeleteRuleRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/security_group/delete_rule"
+
+ res, err := sg.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
+}
diff --git a/pkg/cloudbroker/security_group/filter.go b/pkg/cloudbroker/security_group/filter.go
new file mode 100644
index 0000000..e95ee28
--- /dev/null
+++ b/pkg/cloudbroker/security_group/filter.go
@@ -0,0 +1,80 @@
+package securitygroup
+
+// FilterByID returns ListSecurityGroups with specified ID.
+func (lsg ListSecurityGroups) FilterByID(id uint64) ListSecurityGroups {
+ predicate := func(isg ItemSecurityGroup) bool {
+ return isg.ID == id
+ }
+
+ return lsg.FilterFunc(predicate)
+}
+
+// FilterByID returns ListSecurityGroups with specified Name.
+func (lsg ListSecurityGroups) FilterByName(name string) ListSecurityGroups {
+ predicate := func(isg ItemSecurityGroup) bool {
+ return isg.Name == name
+ }
+
+ return lsg.FilterFunc(predicate)
+}
+
+// FilterByCreatedBy returns ListSecurityGroups with specified CreatedBy.
+func (lsg ListSecurityGroups) FilterByCreatedBy(createdBy string) ListSecurityGroups {
+ predicate := func(isg ItemSecurityGroup) bool {
+ return isg.CreatedBy == createdBy
+ }
+
+ return lsg.FilterFunc(predicate)
+}
+
+// FilterByDescription returns ListSecurityGroups with specified Description.
+func (lsg ListSecurityGroups) FilterByDescription(description string) ListSecurityGroups {
+ predicate := func(isg ItemSecurityGroup) bool {
+ return isg.Description == description
+ }
+
+ return lsg.FilterFunc(predicate)
+}
+
+// FilterByUpdatedBy returns ListSecurityGroups with specified UpdatedBy.
+func (lsg ListSecurityGroups) FilterByUpdatedBy(updatedBy string) ListSecurityGroups {
+ predicate := func(isg ItemSecurityGroup) bool {
+ return isg.UpdatedBy == updatedBy
+ }
+
+ return lsg.FilterFunc(predicate)
+}
+
+// FilterByAccountID returns ListSecurityGroups with specified AccountID.
+func (lsg ListSecurityGroups) FilterByAccountID(accountID uint64) ListSecurityGroups {
+ predicate := func(isg ItemSecurityGroup) bool {
+ return isg.AccountID == accountID
+ }
+
+ return lsg.FilterFunc(predicate)
+}
+
+// FilterFunc allows filtering ListSecurityGroups based on a user-specified predicate.
+func (lsg ListSecurityGroups) FilterFunc(predicate func(ItemSecurityGroup) bool) ListSecurityGroups {
+ var result ListSecurityGroups
+
+ for _, item := range lsg.Data {
+ if predicate(item) {
+ result.Data = append(result.Data, item)
+ }
+ }
+
+ result.EntryCount = uint64(len(result.Data))
+
+ return result
+}
+
+// FindOne returns first found ItemSecurityGroup
+// If none was found, returns an empty struct.
+func (lsg ListSecurityGroups) FindOne() ItemSecurityGroup {
+ if len(lsg.Data) == 0 {
+ return ItemSecurityGroup{}
+ }
+
+ return lsg.Data[0]
+}
diff --git a/pkg/cloudbroker/security_group/filter_test.go b/pkg/cloudbroker/security_group/filter_test.go
new file mode 100644
index 0000000..821f016
--- /dev/null
+++ b/pkg/cloudbroker/security_group/filter_test.go
@@ -0,0 +1,87 @@
+package securitygroup
+
+import "testing"
+
+var securityGroups = ListSecurityGroups{
+ Data: []ItemSecurityGroup{
+ {
+ ID: 1,
+ AccountID: 1,
+ Name: "sg1",
+ Description: "some desc",
+ CreatedBy: "user",
+ },
+ {
+ ID: 3,
+ AccountID: 3,
+ Name: "sg3",
+ Description: "some desc",
+ CreatedBy: "anotheruser",
+ },
+ {
+ ID: 5,
+ AccountID: 3,
+ Name: "sg5",
+ Description: "some other desc",
+ CreatedBy: "anotheruser",
+ UpdatedBy: "user",
+ },
+ },
+ EntryCount: 3,
+}
+
+func TestFilterByID(t *testing.T) {
+ actual := securityGroups.FilterByID(1).FindOne()
+ if actual.ID != 1 {
+ t.Fatal("expected ID 1, found: ", actual.ID)
+ }
+}
+
+func TestFilterByName(t *testing.T) {
+ actual := securityGroups.FilterByName("sg3").FindOne()
+ if actual.Name != "sg3" {
+ t.Fatal("expected Name sg3, found: ", actual.Name)
+ }
+}
+
+func TestFilterByDescription(t *testing.T) {
+ actual := securityGroups.FilterByDescription("some desc")
+
+ if len(actual.Data) != 2 {
+ t.Fatal("expected 2 found, actual: ", len(actual.Data))
+ }
+
+ for _, item := range actual.Data {
+ if item.Description != "some desc" {
+ t.Fatal("expected Description 'some desc', found: ", item.Description)
+ }
+ }
+}
+
+func TestFilterByAccountID(t *testing.T) {
+ actual := securityGroups.FilterByAccountID(1).FindOne()
+ if actual.AccountID != 1 {
+ t.Fatal("expected AccountID 1, found: ", actual.AccountID)
+ }
+}
+
+func TestFilterByCreatedBy(t *testing.T) {
+ actual := securityGroups.FilterByCreatedBy("anotheruser")
+
+ if len(actual.Data) != 2 {
+ t.Fatal("expected 2 found, actual: ", len(actual.Data))
+ }
+
+ for _, item := range actual.Data {
+ if item.CreatedBy != "anotheruser" {
+ t.Fatal("expected CreatedBy 'anotheruser', found: ", item.CreatedBy)
+ }
+ }
+}
+
+func TestFilterByUpdatedBy(t *testing.T) {
+ actual := securityGroups.FilterByUpdatedBy("user").FindOne()
+ if actual.UpdatedBy != "user" {
+ t.Fatal("expected UpdatedBy 'user', found: ", actual.UpdatedBy)
+ }
+}
diff --git a/pkg/cloudbroker/security_group/get.go b/pkg/cloudbroker/security_group/get.go
new file mode 100644
index 0000000..2b92d03
--- /dev/null
+++ b/pkg/cloudbroker/security_group/get.go
@@ -0,0 +1,43 @@
+package securitygroup
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type GetRequest struct {
+ // ID of security group
+ // Required: true
+ SecurityGroupID uint64 `url:"security_group_id" json:"security_group_id" validate:"required"`
+}
+
+func (sg SecurityGroup) Get(ctx context.Context, req GetRequest) (*RecordSecurityGroup, error) {
+ res, err := sg.GetRaw(ctx, req)
+ if err != nil {
+ return nil, err
+ }
+
+ info := RecordSecurityGroup{}
+
+ err = json.Unmarshal(res, &info)
+ if err != nil {
+ return nil, err
+ }
+
+ return &info, nil
+}
+
+func (sg SecurityGroup) GetRaw(ctx context.Context, req GetRequest) ([]byte, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/security_group/get"
+
+ res, err := sg.client.DecortApiCall(ctx, http.MethodGet, url, req)
+ return res, err
+}
diff --git a/pkg/cloudbroker/security_group/list.go b/pkg/cloudbroker/security_group/list.go
new file mode 100644
index 0000000..ab13a28
--- /dev/null
+++ b/pkg/cloudbroker/security_group/list.go
@@ -0,0 +1,86 @@
+package securitygroup
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type ListRequest struct {
+ // Search by security group id
+ // Required: false
+ ByID uint64 `url:"by_id,omitempty" json:"by_id,omitempty"`
+
+ // Search by account id
+ // Required: false
+ AccountID uint64 `url:"account_id,omitempty" json:"account_id,omitempty"`
+
+ // Search by security group name
+ // Required: false
+ Name string `url:"name,omitempty" json:"name,omitempty"`
+
+ // Search by security group description
+ // Required: false
+ Description string `url:"description,omitempty" json:"description,omitempty"`
+
+ // Search by created after time (unix timestamp)
+ // Required: false
+ CreatedMin uint64 `url:"created_min,omitempty" json:"created_min,omitempty"`
+
+ // Search by created before time (unix timestamp)
+ // Required: false
+ CreatedMax uint64 `url:"created_max,omitempty" json:"created_max,omitempty"`
+
+ // Search by updated after time (unix timestamp)
+ // Required: false
+ UpdatedMin uint64 `url:"updated_min,omitempty" json:"updated_min,omitempty"`
+
+ // Search by updated before time (unix timestamp)
+ // Required: false
+ UpdatedMax uint64 `url:"updated_max,omitempty" json:"updated_max,omitempty"`
+
+ // Sort by one of supported fields, format ±
+ // Required: false
+ SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty"`
+
+ // Page number
+ // Required: false
+ Page uint64 `url:"page,omitempty" json:"page,omitempty"`
+
+ // Page size
+ // Required: false
+ Size uint64 `url:"size,omitempty" json:"size,omitempty"`
+}
+
+// List gets list of security groups as a ListSecurityGroups struct
+func (sg SecurityGroup) List(ctx context.Context, req ListRequest) (*ListSecurityGroups, error) {
+
+ res, err := sg.ListRaw(ctx, req)
+ if err != nil {
+ return nil, err
+ }
+
+ list := ListSecurityGroups{}
+
+ err = json.Unmarshal(res, &list)
+ if err != nil {
+ return nil, err
+ }
+
+ return &list, nil
+}
+
+// ListRaw gets list of security groups as an array of bytes
+func (sg SecurityGroup) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
+
+ if err := validators.ValidateRequest(req); err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/security_group/list"
+
+ res, err := sg.client.DecortApiCall(ctx, http.MethodGet, url, req)
+ return res, err
+}
diff --git a/pkg/cloudbroker/security_group/models.go b/pkg/cloudbroker/security_group/models.go
new file mode 100644
index 0000000..440e813
--- /dev/null
+++ b/pkg/cloudbroker/security_group/models.go
@@ -0,0 +1,43 @@
+package securitygroup
+
+type ListSecurityGroups struct {
+ Data []ItemSecurityGroup `json:"data"`
+ EntryCount uint64 `json:"entryCount"`
+}
+
+type ItemSecurityGroup struct {
+ ID uint64 `json:"id"`
+ AccountID uint64 `json:"account_id"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ Rules Rules `json:"rules"`
+ CreatedAt uint64 `json:"created_at"`
+ UpdatedAt uint64 `json:"updated_at"`
+ CreatedBy string `json:"created_by"`
+ UpdatedBy string `json:"updated_by"`
+}
+
+type RecordSecurityGroup struct {
+ ID uint64 `json:"id"`
+ AccountID uint64 `json:"account_id"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ Rules Rules `json:"rules"`
+ CreatedAt uint64 `json:"created_at"`
+ UpdatedAt uint64 `json:"updated_at"`
+ CreatedBy string `json:"created_by"`
+ UpdatedBy string `json:"updated_by"`
+}
+
+type Rules []Rule
+
+type Rule struct {
+ ID uint64 `json:"id"`
+ Direction string `json:"direction"`
+ Ethertype string `json:"ethertype"`
+ Protocol string `json:"protocol"`
+ PortRangeMin uint64 `json:"port_range_min"`
+ PortRangeMax uint64 `json:"port_range_max"`
+ RemoteIPPrefix string `json:"remote_ip_prefix"`
+ RemoteGroupID uint64 `json:"remote_group_id"`
+}
diff --git a/pkg/cloudbroker/security_group/security_group.go b/pkg/cloudbroker/security_group/security_group.go
new file mode 100644
index 0000000..35c6a3b
--- /dev/null
+++ b/pkg/cloudbroker/security_group/security_group.go
@@ -0,0 +1,15 @@
+package securitygroup
+
+import "repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
+
+// Structure for creating request to storage policy
+type SecurityGroup struct {
+ client interfaces.Caller
+}
+
+// Builder for stack endpoint
+func New(client interfaces.Caller) *SecurityGroup {
+ return &SecurityGroup{
+ client: client,
+ }
+}
diff --git a/pkg/cloudbroker/security_group/sorting.go b/pkg/cloudbroker/security_group/sorting.go
new file mode 100644
index 0000000..5a54b53
--- /dev/null
+++ b/pkg/cloudbroker/security_group/sorting.go
@@ -0,0 +1,41 @@
+package securitygroup
+
+import "sort"
+
+// SortByCreatedAt sorts ListSecurityGroups by the CreatedAt field in ascending order.
+//
+// If inverse param is set to true, the order is reversed.
+func (lsg ListSecurityGroups) SortByCreatedAt(inverse bool) ListSecurityGroups {
+ if len(lsg.Data) < 2 {
+ return lsg
+ }
+
+ sort.Slice(lsg.Data, func(i, j int) bool {
+ if inverse {
+ return lsg.Data[i].CreatedAt > lsg.Data[j].CreatedAt
+ }
+
+ return lsg.Data[i].CreatedAt < lsg.Data[j].CreatedAt
+ })
+
+ return lsg
+}
+
+// SortByUpdatedAt sorts ListSecurityGroups by the UpdatedAt field in ascending order.
+//
+// If inverse param is set to true, the order is reversed.
+func (lsg ListSecurityGroups) SortByUpdatedAt(inverse bool) ListSecurityGroups {
+ if len(lsg.Data) < 2 {
+ return lsg
+ }
+
+ sort.Slice(lsg.Data, func(i, j int) bool {
+ if inverse {
+ return lsg.Data[i].UpdatedAt > lsg.Data[j].UpdatedAt
+ }
+
+ return lsg.Data[i].UpdatedAt < lsg.Data[j].UpdatedAt
+ })
+
+ return lsg
+}
diff --git a/pkg/cloudbroker/security_group/update.go b/pkg/cloudbroker/security_group/update.go
new file mode 100644
index 0000000..0e6835e
--- /dev/null
+++ b/pkg/cloudbroker/security_group/update.go
@@ -0,0 +1,51 @@
+package securitygroup
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type UpdateRequest struct {
+ // Security group ID
+ // Required: true
+ SecurityGroupID uint64 `url:"security_group_id" json:"security_group_id" validate:"required"`
+
+ // New security group name
+ // Required: false
+ Name string `url:"name,omitempty" json:"name,omitempty"`
+
+ // New security group description
+ // Required: false
+ Description string `url:"description,omitempty" json:"description,omitempty"`
+}
+
+func (sg SecurityGroup) Update(ctx context.Context, req UpdateRequest) (*RecordSecurityGroup, error) {
+ res, err := sg.UpdateRaw(ctx, req)
+ if err != nil {
+ return nil, err
+ }
+
+ info := RecordSecurityGroup{}
+
+ err = json.Unmarshal(res, &info)
+ if err != nil {
+ return nil, err
+ }
+
+ return &info, nil
+}
+
+func (sg SecurityGroup) UpdateRaw(ctx context.Context, req UpdateRequest) ([]byte, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/security_group/update"
+
+ res, err := sg.client.DecortApiCall(ctx, http.MethodPost, url, req)
+ return res, err
+}
diff --git a/pkg/cloudbroker/securitygroup.go b/pkg/cloudbroker/securitygroup.go
new file mode 100644
index 0000000..5dba9c5
--- /dev/null
+++ b/pkg/cloudbroker/securitygroup.go
@@ -0,0 +1,10 @@
+package cloudbroker
+
+import (
+ securitygroup "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/security_group"
+)
+
+// Accessing the Security Group method group
+func (cb *CloudBroker) SecurityGroup() *securitygroup.SecurityGroup {
+ return securitygroup.New(cb.client)
+}
diff --git a/pkg/cloudbroker/storage_policy/add_pool.go b/pkg/cloudbroker/storage_policy/add_pool.go
new file mode 100644
index 0000000..a957e4f
--- /dev/null
+++ b/pkg/cloudbroker/storage_policy/add_pool.go
@@ -0,0 +1,51 @@
+package storagepolicy
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type AddPoolRequest struct {
+ // ID of storage policy
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
+ // Storage endpoint provider ID to add
+ // Required: true
+ SepID uint64 `url:"sep_id" json:"sep_id" validate:"required"`
+
+ // Pool to add
+ // Required: true
+ PoolName string `url:"pool_name" json:"pool_name" validate:"required"`
+}
+
+func (sp StoragePolicy) AddPool(ctx context.Context, req AddPoolRequest) (*InfoStoragePolicyWithID, error) {
+ res, err := sp.AddPoolRaw(ctx, req)
+ if err != nil {
+ return nil, err
+ }
+
+ info := InfoStoragePolicyWithID{}
+
+ err = json.Unmarshal(res, &info)
+ if err != nil {
+ return nil, err
+ }
+
+ return &info, nil
+}
+
+func (sp StoragePolicy) AddPoolRaw(ctx context.Context, req AddPoolRequest) ([]byte, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/storage_policy/add_pool"
+
+ res, err := sp.client.DecortApiCall(ctx, http.MethodPost, url, req)
+ return res, err
+}
diff --git a/pkg/cloudbroker/storage_policy/create.go b/pkg/cloudbroker/storage_policy/create.go
new file mode 100644
index 0000000..b3a4181
--- /dev/null
+++ b/pkg/cloudbroker/storage_policy/create.go
@@ -0,0 +1,63 @@
+package storagepolicy
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type AccessSepsPool struct {
+
+ // Storage endpoint provider ID
+ // Required: true
+ SepID uint64 `url:"sep_id" json:"sep_id" validate:"required"`
+
+ // Names of pools
+ // Required: true
+ PoolNames []string `url:"pool_names" json:"pool_names" validate:"required"`
+}
+
+type CreateRequest struct {
+ // Name of the storage policy
+ // Required: true
+ Name string `url:"name" json:"name" validate:"required"`
+
+ // List of storage endpoint access objects
+ // Required: true
+ AccessSepsPools []AccessSepPool `url:"access_seps_pools" json:"access_seps_pools" validate:"required"`
+
+ // Description of the storage policy
+ // Required: false
+ Description string `url:"description,omitempty" json:"description,omitempty"`
+
+ // Maximum IOPS limit
+ // Default: 2000
+ // Required: false
+ LimitIOPS uint64 `url:"limit_iops,omitempty" json:"limit_iops,omitempty"`
+}
+
+// Create creates a new storage policy
+func (sp StoragePolicy) Create(ctx context.Context, req CreateRequest) (uint64, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return 0, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/storage_policy/create"
+
+ res, err := sp.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
+ if err != nil {
+ return 0, err
+ }
+
+ result, err := strconv.ParseUint(string(res), 10, 64)
+ if err != nil {
+ return 0, err
+ }
+
+ return result, nil
+
+}
diff --git a/pkg/cloudbroker/storage_policy/delete.go b/pkg/cloudbroker/storage_policy/delete.go
new file mode 100644
index 0000000..38e4889
--- /dev/null
+++ b/pkg/cloudbroker/storage_policy/delete.go
@@ -0,0 +1,36 @@
+package storagepolicy
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type DeleteRequest struct {
+ // ID of storage policy to delete
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+}
+
+func (sp StoragePolicy) Delete(ctx context.Context, req DeleteRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/storage_policy/delete"
+
+ res, err := sp.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
+}
diff --git a/pkg/cloudbroker/storage_policy/delete_pool.go b/pkg/cloudbroker/storage_policy/delete_pool.go
new file mode 100644
index 0000000..76d124a
--- /dev/null
+++ b/pkg/cloudbroker/storage_policy/delete_pool.go
@@ -0,0 +1,51 @@
+package storagepolicy
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type DeletePollRequest struct {
+ // ID of storage policy
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
+ // Storage endpoint provider ID to delete
+ // Required: true
+ SepID uint64 `url:"sep_id" json:"sep_id" validate:"required"`
+
+ // Pool to delete
+ // Required: true
+ PoolName string `url:"pool_name" json:"pool_name" validate:"required"`
+}
+
+func (sp StoragePolicy) DeletePool(ctx context.Context, req DeletePollRequest) (*InfoStoragePolicyWithID, error) {
+ res, err := sp.DeletePoolRaw(ctx, req)
+ if err != nil {
+ return nil, err
+ }
+
+ info := InfoStoragePolicyWithID{}
+
+ err = json.Unmarshal(res, &info)
+ if err != nil {
+ return nil, err
+ }
+
+ return &info, nil
+}
+
+func (sp StoragePolicy) DeletePoolRaw(ctx context.Context, req DeletePollRequest) ([]byte, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/storage_policy/delete_pool"
+
+ res, err := sp.client.DecortApiCall(ctx, http.MethodPost, url, req)
+ return res, err
+}
diff --git a/pkg/cloudbroker/storage_policy/disable.go b/pkg/cloudbroker/storage_policy/disable.go
new file mode 100644
index 0000000..c6be2fa
--- /dev/null
+++ b/pkg/cloudbroker/storage_policy/disable.go
@@ -0,0 +1,36 @@
+package storagepolicy
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type DisableRequest struct {
+ // ID of storage policy to disable
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+}
+
+func (sp StoragePolicy) Disable(ctx context.Context, req DisableRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/storage_policy/disable"
+
+ res, err := sp.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
+}
diff --git a/pkg/cloudbroker/storage_policy/enable.go b/pkg/cloudbroker/storage_policy/enable.go
new file mode 100644
index 0000000..b889e69
--- /dev/null
+++ b/pkg/cloudbroker/storage_policy/enable.go
@@ -0,0 +1,36 @@
+package storagepolicy
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type EnableRequest struct {
+ // ID of storage policy to enable
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+}
+
+func (sp StoragePolicy) Enable(ctx context.Context, req EnableRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/storage_policy/enable"
+
+ res, err := sp.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
+}
diff --git a/pkg/cloudbroker/storage_policy/filter.go b/pkg/cloudbroker/storage_policy/filter.go
new file mode 100644
index 0000000..2e053c1
--- /dev/null
+++ b/pkg/cloudbroker/storage_policy/filter.go
@@ -0,0 +1,71 @@
+package storagepolicy
+
+// FilterByID returns ListStoragePolicies with specified ID.
+func (lsp ListStoragePolicies) FilterByID(id uint64) ListStoragePolicies {
+ predicate := func(isp ItemStoragePolicy) bool {
+ return isp.ID == id
+ }
+
+ return lsp.FilterFunc(predicate)
+}
+
+// FilterByName returns ListStoragePolicies with specified Name.
+func (lsp ListStoragePolicies) FilterByName(name string) ListStoragePolicies {
+ predicate := func(isp ItemStoragePolicy) bool {
+ return isp.Name == name
+ }
+
+ return lsp.FilterFunc(predicate)
+}
+
+// FilterByStatus returns ListStoragePolicies with specified Status.
+func (lsp ListStoragePolicies) FilterByStatus(status string) ListStoragePolicies {
+ predicate := func(isp ItemStoragePolicy) bool {
+ return isp.Status == status
+ }
+
+ return lsp.FilterFunc(predicate)
+}
+
+// FilterByStatus returns ListStoragePolicies with specified Desc.
+func (lsp ListStoragePolicies) FilterByDesc(desc string) ListStoragePolicies {
+ predicate := func(isp ItemStoragePolicy) bool {
+ return isp.Description == desc
+ }
+
+ return lsp.FilterFunc(predicate)
+}
+
+// FilterByLimitIOPS returns ListStoragePolicies with specified IOPS.
+func (lsp ListStoragePolicies) FilterByLimitIOPS(limitIOPS uint64) ListStoragePolicies {
+ predicate := func(isp ItemStoragePolicy) bool {
+ return isp.LimitIOPS == limitIOPS
+ }
+
+ return lsp.FilterFunc(predicate)
+}
+
+// FilterFunc allows filtering ListStoragePolicies based on a user-specified predicate.
+func (lsp ListStoragePolicies) FilterFunc(predicate func(ItemStoragePolicy) bool) ListStoragePolicies {
+ var result ListStoragePolicies
+
+ for _, item := range lsp.Data {
+ if predicate(item) {
+ result.Data = append(result.Data, item)
+ }
+ }
+
+ result.EntryCount = uint64(len(result.Data))
+
+ return result
+}
+
+// FindOne returns first found ItemStoragePolicy
+// If none was found, returns an empty struct.
+func (lsp ListStoragePolicies) FindOne() ItemStoragePolicy {
+ if len(lsp.Data) == 0 {
+ return ItemStoragePolicy{}
+ }
+
+ return lsp.Data[0]
+}
diff --git a/pkg/cloudbroker/storage_policy/filter_test.go b/pkg/cloudbroker/storage_policy/filter_test.go
new file mode 100644
index 0000000..2666c10
--- /dev/null
+++ b/pkg/cloudbroker/storage_policy/filter_test.go
@@ -0,0 +1,110 @@
+package storagepolicy
+
+import "testing"
+
+var asp9 = AccessSepPool{
+ SepID: 9,
+ PoolNames: []string{"data03"},
+}
+
+var asp7 = AccessSepPool{
+ SepID: 7,
+ PoolNames: []string{"pool_QA"},
+}
+
+var asp8 = AccessSepPool{
+ SepID: 8,
+ PoolNames: []string{
+ "alpha_pool_block",
+ "alpha_pool_stripe",
+ "alpha_pool_file",
+ },
+}
+
+var storagePolicyItems = ListStoragePolicies{
+ Data: []ItemStoragePolicy{
+ {
+ ID: 1,
+ GUID: 1,
+ Name: "storagePolicy01",
+ Description: "desc",
+ AccessSepPools: ListAccessSepPools{asp7},
+ Status: "ENABLED",
+ LimitIOPS: 2000,
+ Usage: Usage{},
+ },
+ {
+ ID: 3,
+ GUID: 3,
+ Name: "storagePolicy03",
+ Description: "desc",
+ AccessSepPools: ListAccessSepPools{asp7, asp8, asp9},
+ Status: "ENABLED",
+ LimitIOPS: 2500,
+ Usage: Usage{},
+ },
+ {
+ ID: 5,
+ GUID: 5,
+ Name: "storagePolicy05",
+ Description: "another desc",
+ AccessSepPools: ListAccessSepPools{asp8, asp9},
+ Status: "DISABLED",
+ LimitIOPS: 2000,
+ Usage: Usage{},
+ },
+ },
+ EntryCount: 3,
+}
+
+func TestFilterByID(t *testing.T) {
+ actual := storagePolicyItems.FilterByID(1).FindOne()
+
+ if actual.ID != 1 {
+ t.Fatal("expected 1 ID, found: ", actual.ID)
+ }
+}
+
+func TestFilterByName(t *testing.T) {
+ actual := storagePolicyItems.FilterByName("storagePolicy01").FindOne()
+
+ if actual.Name != "storagePolicy01" {
+ t.Fatal("expected Name 'storagePolicy01', found: ", actual.Name)
+ }
+}
+
+func TestFilterByStatus(t *testing.T) {
+ actual := storagePolicyItems.FilterByStatus("ENABLED")
+
+ if len(actual.Data) != 2 {
+ t.Fatal("expected 2 found, actual: ", len(actual.Data))
+ }
+
+ for _, item := range actual.Data {
+ if item.Status != "ENABLED" {
+ t.Fatal("expected Status 'ENABLED', found: ", item.Status)
+ }
+ }
+}
+
+func TestFilterByDesc(t *testing.T) {
+ actual := storagePolicyItems.FilterByDesc("desc")
+
+ if len(actual.Data) != 2 {
+ t.Fatal("expected 2 found, actual: ", len(actual.Data))
+ }
+
+ for _, item := range actual.Data {
+ if item.Description != "desc" {
+ t.Fatal("expected Description 'desc', found: ", item.Status)
+ }
+ }
+}
+
+func TestFilterByLimitIOPS(t *testing.T) {
+ actual := storagePolicyItems.FilterByLimitIOPS(2500).FindOne()
+
+ if actual.LimitIOPS != 2500 {
+ t.Fatal("expected LimitIOPS '2500', found: ", actual.LimitIOPS)
+ }
+}
diff --git a/pkg/cloudbroker/storage_policy/get.go b/pkg/cloudbroker/storage_policy/get.go
new file mode 100644
index 0000000..31ebd3c
--- /dev/null
+++ b/pkg/cloudbroker/storage_policy/get.go
@@ -0,0 +1,43 @@
+package storagepolicy
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type GetRequest struct {
+ // ID of storage policy
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+}
+
+func (sp StoragePolicy) Get(ctx context.Context, req GetRequest) (*InfoStoragePolicy, error) {
+ res, err := sp.GetRaw(ctx, req)
+ if err != nil {
+ return nil, err
+ }
+
+ info := InfoStoragePolicy{}
+
+ err = json.Unmarshal(res, &info)
+ if err != nil {
+ return nil, err
+ }
+
+ return &info, nil
+}
+
+func (sp StoragePolicy) GetRaw(ctx context.Context, req GetRequest) ([]byte, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/storage_policy/get"
+
+ res, err := sp.client.DecortApiCall(ctx, http.MethodGet, url, req)
+ return res, err
+}
diff --git a/pkg/cloudbroker/storage_policy/list.go b/pkg/cloudbroker/storage_policy/list.go
new file mode 100644
index 0000000..8827ff5
--- /dev/null
+++ b/pkg/cloudbroker/storage_policy/list.go
@@ -0,0 +1,90 @@
+package storagepolicy
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type ListRequest struct {
+ // Page number
+ // Required: false
+ Page uint64 `url:"page,omitempty" json:"page,omitempty"`
+
+ // Page size
+ // Required: false
+ Size uint64 `url:"size,omitempty" json:"size,omitempty"`
+
+ // Search by storage policy ID
+ // Required: false
+ ByID uint64 `url:"by_id,omitempty" json:"by_id,omitempty"`
+
+ // Search by storage policy name
+ // Required: false
+ Name string `url:"name,omitempty" json:"name,omitempty"`
+
+ // Search by storage policy status
+ // Required: false
+ Status string `url:"status,omitempty" json:"status,omitempty"`
+
+ // Search by storage policy desc
+ // Required: false
+ Desc string `url:"desc,omitempty" json:"desc,omitempty"`
+
+ // Search by storage policy iops limit
+ // Required: false
+ LimitIOPS uint64 `url:"limit_iops,omitempty" json:"limit_iops,omitempty"`
+
+ // Sort by one of supported fields, format ±
+ // Required: false
+ SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty"`
+
+ // ID of account ID
+ // Required: false
+ AccountID uint64 `url:"account_id,omitempty" json:"account_id,omitempty"`
+
+ // Search by resgroup id
+ // Required: false
+ ResgroupID uint64 `url:"resgroup_id,omitempty" json:"resgroup_id,omitempty"`
+
+ // Search by sep id
+ // Required: false
+ SepID uint64 `url:"sep_id,omitempty" json:"sep_id,omitempty"`
+
+ // Search by pool name
+ // Required: false
+ PoolName string `url:"pool_name,omitempty" json:"pool_name,omitempty"`
+}
+
+// List gets list of storage policies as a ListStoragePolicies struct
+func (sp StoragePolicy) List(ctx context.Context, req ListRequest) (*ListStoragePolicies, error) {
+
+ res, err := sp.ListRaw(ctx, req)
+ if err != nil {
+ return nil, err
+ }
+
+ list := ListStoragePolicies{}
+
+ err = json.Unmarshal(res, &list)
+ if err != nil {
+ return nil, err
+ }
+
+ return &list, nil
+}
+
+// ListRaw gets list of storage policies as an array of bytes
+func (sp StoragePolicy) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
+
+ if err := validators.ValidateRequest(req); err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/storage_policy/list"
+
+ res, err := sp.client.DecortApiCall(ctx, http.MethodGet, url, req)
+ return res, err
+}
diff --git a/pkg/cloudbroker/storage_policy/models.go b/pkg/cloudbroker/storage_policy/models.go
new file mode 100644
index 0000000..8643881
--- /dev/null
+++ b/pkg/cloudbroker/storage_policy/models.go
@@ -0,0 +1,51 @@
+package storagepolicy
+
+type InfoStoragePolicyWithID struct {
+ ID uint64 `json:"id"`
+ GUID uint64 `json:"guid"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ AccessSepPools ListAccessSepPools `json:"access_seps_pools"`
+ Status string `json:"status"`
+ LimitIOPS uint64 `json:"limit_iops"`
+ StoragePolicyID uint64 `json:"storage_policy_id"`
+}
+
+type ListStoragePolicies struct {
+ Data []ItemStoragePolicy `json:"data"`
+ EntryCount uint64 `json:"entryCount"`
+}
+
+type ItemStoragePolicy struct {
+ ID uint64 `json:"id"`
+ GUID uint64 `json:"guid"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ AccessSepPools ListAccessSepPools `json:"access_seps_pools"`
+ Status string `json:"status"`
+ LimitIOPS uint64 `json:"limit_iops"`
+ Usage Usage `json:"usage"`
+}
+
+type InfoStoragePolicy struct {
+ ID uint64 `json:"id"`
+ GUID uint64 `json:"guid"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ AccessSepPools ListAccessSepPools `json:"access_seps_pools"`
+ Status string `json:"status"`
+ LimitIOPS uint64 `json:"limit_iops"`
+ Usage Usage `json:"usage"`
+}
+
+type ListAccessSepPools []AccessSepPool
+
+type AccessSepPool struct {
+ SepID uint64 `json:"sep_id"`
+ PoolNames []string `json:"pool_names"`
+}
+
+type Usage struct {
+ Accounts []uint64 `json:"accounts"`
+ Resgroups []uint64 `json:"resgroups"`
+}
diff --git a/pkg/cloudbroker/storage_policy/storage_policy.go b/pkg/cloudbroker/storage_policy/storage_policy.go
new file mode 100644
index 0000000..42b42a2
--- /dev/null
+++ b/pkg/cloudbroker/storage_policy/storage_policy.go
@@ -0,0 +1,15 @@
+package storagepolicy
+
+import "repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
+
+// Structure for creating request to storage policy
+type StoragePolicy struct {
+ client interfaces.Caller
+}
+
+// Builder for stack endpoint
+func New(client interfaces.Caller) *StoragePolicy {
+ return &StoragePolicy{
+ client: client,
+ }
+}
diff --git a/pkg/cloudbroker/storage_policy/update.go b/pkg/cloudbroker/storage_policy/update.go
new file mode 100644
index 0000000..d233c76
--- /dev/null
+++ b/pkg/cloudbroker/storage_policy/update.go
@@ -0,0 +1,56 @@
+package storagepolicy
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+type UpdateRequest struct {
+ // ID of storage policy
+ // Required: true
+ StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
+
+ // New name for the storage policy
+ // Required: false
+ Name string `url:"name,omitempty" json:"name,omitempty"`
+
+ // New value for limit IOPS
+ // Required: false
+ LimitIOPS uint64 `url:"limit_iops,omitempty" json:"limit_iops,omitempty"`
+
+ // New description of the storage policy
+ // Required: false
+ Description string `url:"description,omitempty" json:"description,omitempty"`
+}
+
+// Update updates storage policy
+func (sp StoragePolicy) Update(ctx context.Context, req UpdateRequest) (*InfoStoragePolicyWithID, error) {
+ res, err := sp.UpdateRaw(ctx, req)
+ if err != nil {
+ return nil, err
+ }
+
+ info := InfoStoragePolicyWithID{}
+
+ err = json.Unmarshal(res, &info)
+ if err != nil {
+ return nil, err
+ }
+
+ return &info, nil
+}
+
+func (sp StoragePolicy) UpdateRaw(ctx context.Context, req UpdateRequest) ([]byte, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/storage_policy/update"
+
+ res, err := sp.client.DecortApiCall(ctx, http.MethodPost, url, req)
+ return res, err
+}
diff --git a/pkg/cloudbroker/storagepolicy.go b/pkg/cloudbroker/storagepolicy.go
new file mode 100644
index 0000000..732eb08
--- /dev/null
+++ b/pkg/cloudbroker/storagepolicy.go
@@ -0,0 +1,10 @@
+package cloudbroker
+
+import (
+ storagepolicy "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/storage_policy"
+)
+
+// Accessing the Storage Policy method group
+func (cb *CloudBroker) StoragePolicy() *storagepolicy.StoragePolicy {
+ return storagepolicy.New(cb.client)
+}
diff --git a/pkg/cloudbroker/trunk/list.go b/pkg/cloudbroker/trunk/list.go
index da75c08..eb0fcb7 100644
--- a/pkg/cloudbroker/trunk/list.go
+++ b/pkg/cloudbroker/trunk/list.go
@@ -27,6 +27,9 @@ type ListRequest struct {
// Page size
Size uint64 `url:"size,omitempty" json:"size,omitempty"`
+
+ // Status
+ Status string `url:"status,omitempty" json:"status,omitempty"`
}
// List gets list of all trunks as a ListTrunks struct
diff --git a/pkg/cloudbroker/user/delete_users.go b/pkg/cloudbroker/user/delete_users.go
index a879b8e..1a7c69e 100644
--- a/pkg/cloudbroker/user/delete_users.go
+++ b/pkg/cloudbroker/user/delete_users.go
@@ -3,15 +3,16 @@ package user
import (
"context"
"net/http"
- "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
"strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// DeleteUsersRequest struct for bulk delete a list of users.
type DeleteUsersRequest struct {
// List of user ids
// Required: true
- UserIDs string `url:"userIds" json:"userIds" validate:"required"`
+ UserIDs []string `url:"userIds" json:"userIds" validate:"required"`
}
// DeleteUsers bulk delete a list of users.
diff --git a/pkg/cloudbroker/vins/list.go b/pkg/cloudbroker/vins/list.go
index fe35a34..fbe8c63 100644
--- a/pkg/cloudbroker/vins/list.go
+++ b/pkg/cloudbroker/vins/list.go
@@ -46,6 +46,11 @@ type ListRequest struct {
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
+ // Sort by zone id
+ // Default value: 0
+ // Required: false
+ ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
+
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
diff --git a/pkg/cloudbroker/vins/mass_delete.go b/pkg/cloudbroker/vins/mass_delete.go
index f783270..a47c53f 100644
--- a/pkg/cloudbroker/vins/mass_delete.go
+++ b/pkg/cloudbroker/vins/mass_delete.go
@@ -28,18 +28,18 @@ type MassDeleteRequest struct {
}
// MassDelete start jobs to delete several VINSes
-func (v VINS) MassDelete(ctx context.Context, req MassDeleteRequest) (bool, error) {
+func (v VINS) MassDelete(ctx context.Context, req MassDeleteRequest) (string, error) {
err := validators.ValidateRequest(req)
if err != nil {
- return false, validators.ValidationErrors(validators.GetErrors(err))
+ return "", validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudbroker/vins/massDelete"
- _, err = v.client.DecortApiCall(ctx, http.MethodPost, url, req)
+ res, err := v.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
- return false, err
+ return "", err
}
- return true, nil
+ return string(res), nil
}
diff --git a/pkg/cloudbroker/vins/mass_disable.go b/pkg/cloudbroker/vins/mass_disable.go
index faf370f..6e92dbe 100644
--- a/pkg/cloudbroker/vins/mass_disable.go
+++ b/pkg/cloudbroker/vins/mass_disable.go
@@ -15,18 +15,18 @@ type MassDisableRequest struct {
}
// MassDisable start jobs to disable several VINSes
-func (v VINS) MassDisable(ctx context.Context, req MassDisableRequest) (bool, error) {
+func (v VINS) MassDisable(ctx context.Context, req MassDisableRequest) (string, error) {
err := validators.ValidateRequest(req)
if err != nil {
- return false, validators.ValidationErrors(validators.GetErrors(err))
+ return "", validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudbroker/vins/massDisable"
- _, err = v.client.DecortApiCall(ctx, http.MethodPost, url, req)
+ res, err := v.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
- return false, err
+ return "", err
}
- return true, nil
+ return string(res), nil
}
diff --git a/pkg/cloudbroker/vins/mass_enable.go b/pkg/cloudbroker/vins/mass_enable.go
index 4224c40..116544f 100644
--- a/pkg/cloudbroker/vins/mass_enable.go
+++ b/pkg/cloudbroker/vins/mass_enable.go
@@ -15,18 +15,18 @@ type MassEnableRequest struct {
}
// MassEnable start jobs to enable several VINSes
-func (v VINS) MassEnable(ctx context.Context, req MassEnableRequest) (bool, error) {
+func (v VINS) MassEnable(ctx context.Context, req MassEnableRequest) (string, error) {
err := validators.ValidateRequest(req)
if err != nil {
- return false, validators.ValidationErrors(validators.GetErrors(err))
+ return "", validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudbroker/vins/massEnable"
- _, err = v.client.DecortApiCall(ctx, http.MethodPost, url, req)
+ res, err := v.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
- return false, err
+ return "", err
}
- return true, nil
+ return string(res), nil
}
diff --git a/pkg/cloudbroker/vins/models.go b/pkg/cloudbroker/vins/models.go
index 16f3a81..6c59e2b 100644
--- a/pkg/cloudbroker/vins/models.go
+++ b/pkg/cloudbroker/vins/models.go
@@ -508,6 +508,9 @@ type RecordVINS struct {
// Description
Description string `json:"desc"`
+ // Enable Security Groups
+ EnableSecGroups bool `json:"enable_secgroups"`
+
// Grid ID
GID uint64 `json:"gid"`
@@ -718,6 +721,9 @@ type ItemVINS struct {
// Description
Description string `json:"desc"`
+ // Enable Security Groups
+ EnableSecGroups bool `json:"enable_secgroups"`
+
// External IP
ExternalIP string `json:"externalIP"`
diff --git a/pkg/cloudbroker/vins/update.go b/pkg/cloudbroker/vins/update.go
new file mode 100644
index 0000000..1ad584b
--- /dev/null
+++ b/pkg/cloudbroker/vins/update.go
@@ -0,0 +1,51 @@
+package vins
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// UpdateRequest struct to update vins parameters
+type UpdateRequest struct {
+ // VINS ID
+ // Required: true
+ VINSID uint64 `url:"vins_id" json:"vins_id" validate:"required"`
+
+ // Name
+ // Required: false
+ Name string `url:"name,omitempty" json:"name,omitempty"`
+
+ // Desc
+ // Required: false
+ Desc string `url:"desc,omitempty" json:"desc,omitempty"`
+
+ // Flag indicating whether security groups are enabled for this network
+ // Required: false
+ EnableSecGroups interface{} `url:"enable_secgroups,omitempty" json:"enable_secgroups,omitempty" validate:"omitempty,isBool"`
+}
+
+// Update updates a vins parameters
+func (v VINS) Update(ctx context.Context, req UpdateRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/cloudbroker/vins/update"
+
+ res, err := v.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
+
+}
diff --git a/pkg/cloudbroker/zone/models.go b/pkg/cloudbroker/zone/models.go
index b2340ca..110f9f9 100644
--- a/pkg/cloudbroker/zone/models.go
+++ b/pkg/cloudbroker/zone/models.go
@@ -22,12 +22,30 @@ type RecordZone struct {
// Name
Name string `json:"name"`
+ // List of associated account IDs
+ AccountIDs []uint64 `json:"accountIds"`
+
+ // List of associated bservice IDs
+ BserviceIDs []uint64 `json:"bserviceIds"`
+
+ // List of associated compute IDs
+ ComputeIDs []uint64 `json:"computeIds"`
+
// Description
Description string `json:"description"`
// Deletable flag
Deletable bool `json:"deletable"`
+ // List of associated ExtNet IDs
+ ExtnetIDs []uint64 `json:"extnetIds"`
+
+ // List of associated K8s IDs
+ K8SIDs []uint64 `json:"k8sIds"`
+
+ // List of associated LB IDs
+ LBIDs []uint64 `json:"lbIds"`
+
// Status
Status string `json:"status"`
@@ -39,4 +57,7 @@ type RecordZone struct {
// List of associated Node IDs
NodeIDs []uint64 `json:"nodeIds"`
+
+ // List of associated VINS IDs
+ VinsIDs []uint64 `json:"vinsIds"`
}
diff --git a/pkg/sdn/access_groups.go b/pkg/sdn/access_groups.go
new file mode 100644
index 0000000..4b0e83f
--- /dev/null
+++ b/pkg/sdn/access_groups.go
@@ -0,0 +1,10 @@
+package sdn
+
+import (
+ ag "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/acsgroups"
+)
+
+// Accessing the SDN method group
+func (sdn *SDN) AccessGroups() *ag.AccessGroups {
+ return ag.New(sdn.client)
+}
diff --git a/pkg/sdn/acsgroups/access_groups.go b/pkg/sdn/acsgroups/access_groups.go
new file mode 100644
index 0000000..458ec4b
--- /dev/null
+++ b/pkg/sdn/acsgroups/access_groups.go
@@ -0,0 +1,18 @@
+// API Actor API for managing SDN access groups
+package acsgroups
+
+import (
+ "repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
+)
+
+// Structure for creating request to access groups
+type AccessGroups struct {
+ client interfaces.Caller
+}
+
+// Builder for access groups endpoints
+func New(client interfaces.Caller) *AccessGroups {
+ return &AccessGroups{
+ client,
+ }
+}
diff --git a/pkg/sdn/acsgroups/create.go b/pkg/sdn/acsgroups/create.go
new file mode 100644
index 0000000..a197e8d
--- /dev/null
+++ b/pkg/sdn/acsgroups/create.go
@@ -0,0 +1,45 @@
+package acsgroups
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// CreateRequest struct to create access group
+type CreateRequest struct {
+ // Comment of the access group
+ // Required: true
+ Comment string `url:"comment" json:"comment" validate:"required"`
+
+ // Name of acces group
+ // Required: true
+ DisplayName string `url:"display_name" json:"display_name" validate:"required"`
+}
+
+// Create creates a access groups
+func (i AccessGroups) Create(ctx context.Context, req CreateRequest) (*AccessGroupItem, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/sdn/access_group/create"
+
+ res, err := i.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
+ if err != nil {
+ return nil, err
+ }
+
+ info := AccessGroupItem{}
+
+ err = json.Unmarshal(res, &info)
+ if err != nil {
+ return nil, err
+ }
+
+ return &info, nil
+}
diff --git a/pkg/sdn/acsgroups/delete.go b/pkg/sdn/acsgroups/delete.go
new file mode 100644
index 0000000..7915e9f
--- /dev/null
+++ b/pkg/sdn/acsgroups/delete.go
@@ -0,0 +1,39 @@
+package acsgroups
+
+import (
+ "context"
+ "net/http"
+ "strconv"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// DeleteRequest struct to delete access group
+type DeleteRequest struct {
+ // Comment of the access group
+ // Required: true
+ GroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
+}
+
+// Delete a access groups
+func (i AccessGroups) Delete(ctx context.Context, req DeleteRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/sdn/access_group/delete"
+
+ res, err := i.client.DecortApiCallCtype(ctx, http.MethodDelete, url, constants.MIMEJSON, req)
+ if err != nil {
+ return false, err
+ }
+
+ result, err := strconv.ParseBool(string(res))
+ if err != nil {
+ return false, err
+ }
+
+ return result, nil
+}
diff --git a/pkg/sdn/acsgroups/filter.go b/pkg/sdn/acsgroups/filter.go
new file mode 100644
index 0000000..2ac4355
--- /dev/null
+++ b/pkg/sdn/acsgroups/filter.go
@@ -0,0 +1,42 @@
+package acsgroups
+
+// FilterByID returns AccessGroupList with specified ID.
+func (agl AccessGroupList) FilterByID(id string) AccessGroupList {
+ predicate := func(ia AccessGroup) bool {
+ return ia.ID == id
+ }
+
+ return agl.FilterFunc(predicate)
+}
+
+// FilterByName returns AccessGroupList with specified Name.
+func (agl AccessGroupList) FilterByName(name string) AccessGroupList {
+ predicate := func(ia AccessGroup) bool {
+ return ia.DisplayName == name
+ }
+
+ return agl.FilterFunc(predicate)
+}
+
+// FilterFunc allows filtering AccessGroupList based on a user-specified predicate.
+func (agl AccessGroupList) FilterFunc(predicate func(AccessGroup) bool) AccessGroupList {
+ var result AccessGroupList
+
+ for _, acc := range agl.AccessGroups {
+ if predicate(acc) {
+ result.AccessGroups = append(result.AccessGroups, acc)
+ }
+ }
+
+ return result
+}
+
+// FindOne returns first element.
+// If none was found, returns an empty struct.
+func (agl AccessGroupList) FindOne() AccessGroup {
+ if len(agl.AccessGroups) == 0 {
+ return AccessGroup{}
+ }
+
+ return agl.AccessGroups[0]
+}
diff --git a/pkg/sdn/acsgroups/filter_test.go b/pkg/sdn/acsgroups/filter_test.go
new file mode 100644
index 0000000..bb55a21
--- /dev/null
+++ b/pkg/sdn/acsgroups/filter_test.go
@@ -0,0 +1,89 @@
+package acsgroups
+
+import (
+ "testing"
+)
+
+var testAccessGroups = AccessGroupList{
+ AccessGroups: []AccessGroup{
+ {
+ ID: "group1",
+ DisplayName: "Developers",
+ Comment: "First group",
+ CreatedAt: "2023-01-01",
+ CreatedBy: "admin",
+ },
+ {
+ ID: "group2",
+ DisplayName: "Admins",
+ Comment: "Second group",
+ CreatedAt: "2023-01-02",
+ CreatedBy: "admin",
+ },
+ {
+ ID: "group3",
+ DisplayName: "Users",
+ Comment: "Third group",
+ CreatedAt: "2023-01-03",
+ CreatedBy: "admin",
+ },
+ },
+}
+
+func TestFilterByID(t *testing.T) {
+ actual := testAccessGroups.FilterByID("group2").FindOne()
+
+ if actual.ID != "group2" {
+ t.Fatal("actual:", actual.ID, "> expected: group2")
+ }
+}
+
+func TestFilterByName(t *testing.T) {
+ actual := testAccessGroups.FilterByName("Users").FindOne()
+
+ if actual.DisplayName != "Users" {
+ t.Fatal("actual:", actual.DisplayName, ">> expected: Users")
+ }
+}
+
+func TestFilterFunc(t *testing.T) {
+ actual := testAccessGroups.FilterFunc(func(ag AccessGroup) bool {
+ return ag.Comment == "Second group"
+ })
+
+ if len(actual.AccessGroups) != 1 || actual.AccessGroups[0].ID != "group2" {
+ t.Fatal("Expected 1 group with comment 'Second group', found:", len(actual.AccessGroups))
+ }
+}
+
+func TestFindOneWithResults(t *testing.T) {
+ result := testAccessGroups.FilterByID("group1").FindOne()
+ if result.ID != "group1" {
+ t.Fatal("Expected group1, got:", result.ID)
+ }
+}
+
+func TestFindOneEmpty(t *testing.T) {
+ emptyList := AccessGroupList{}
+ result := emptyList.FindOne()
+
+ if result.ID != "" || result.DisplayName != "" {
+ t.Fatal("Expected empty AccessGroup, got:", result)
+ }
+}
+
+func TestFilterByIDNotFound(t *testing.T) {
+ actual := testAccessGroups.FilterByID("nonexistent")
+
+ if len(actual.AccessGroups) != 0 {
+ t.Fatal("Expected 0 groups, found:", len(actual.AccessGroups))
+ }
+}
+
+func TestFilterByNameNotFound(t *testing.T) {
+ actual := testAccessGroups.FilterByName("Nonexistent Group")
+
+ if len(actual.AccessGroups) != 0 {
+ t.Fatal("Expected 0 groups, found:", len(actual.AccessGroups))
+ }
+}
diff --git a/pkg/sdn/acsgroups/ids.go b/pkg/sdn/acsgroups/ids.go
new file mode 100644
index 0000000..1c925e8
--- /dev/null
+++ b/pkg/sdn/acsgroups/ids.go
@@ -0,0 +1,19 @@
+package acsgroups
+
+// IDs gets array of IDs from AccessGroupList struct
+func (agl AccessGroupList) IDs() []string {
+ res := make([]string, 0, len(agl.AccessGroups))
+ for _, c := range agl.AccessGroups {
+ res = append(res, c.ID)
+ }
+ return res
+}
+
+// IDs gets array of IDs from UsersList struct
+func (ul UsersList) IDs() []string {
+ res := make([]string, 0, len(ul.Users))
+ for _, c := range ul.Users {
+ res = append(res, c.ID)
+ }
+ return res
+}
diff --git a/pkg/sdn/acsgroups/list.go b/pkg/sdn/acsgroups/list.go
new file mode 100644
index 0000000..38f82b2
--- /dev/null
+++ b/pkg/sdn/acsgroups/list.go
@@ -0,0 +1,80 @@
+package acsgroups
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// ListGroupsRequest struct to get a list of access groups
+type ListGroupsRequest struct {
+ // Find by enabled status, true or false
+ // Required: false
+ Enabled interface{} `url:"enabled,omitempty" json:"enabled,omitempty" validate:"omitempty,isBool"`
+
+ // Find by deleted status, true or false
+ // Required: false
+ Deleted interface{} `url:"deleted,omitempty" json:"deleted,omitempty" validate:"omitempty,isBool"`
+
+ // Display name filter
+ // Required: false
+ DisplayName string `url:"display_name,omitempty" json:"display_name,omitempty"`
+
+ // Page number for pagination
+ // Required: false
+ Page uint64 `url:"page,omitempty" json:"page,omitempty"`
+
+ // Number of results per page
+ // Required: false
+ PerPage uint64 `url:"per_page,omitempty" json:"per_page,omitempty"`
+
+ // Field to sort by (display_name, created_at, updated_at, deleted_at, owner_login)
+ // Required: false
+ SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty"`
+
+ // Sort order (asc/desc)
+ // Required: false
+ SortOrder string `url:"sort_order,omitempty" json:"sort_order,omitempty"`
+
+ // Creation date lower bound (inclusive)
+ // Required: false
+ CreatedFrom string `url:"created_from,omitempty" json:"created_from,omitempty"`
+
+ // Creation date upper bound (inclusive)
+ // Required: false
+ CreatedTo string `url:"created_to,omitempty" json:"created_to,omitempty"`
+}
+
+// List of access groups
+func (i AccessGroups) List(ctx context.Context, req ListGroupsRequest) (*AccessGroupList, error) {
+ res, err := i.ListRaw(ctx, req)
+ if err != nil {
+ return nil, err
+ }
+
+ groups := []AccessGroup{}
+
+ err = json.Unmarshal(res, &groups)
+ if err != nil {
+ return nil, err
+ }
+
+ result := AccessGroupList{AccessGroups: groups}
+
+ return &result, nil
+}
+
+// ListRaw gets a list of all users as an array of bytes
+func (a AccessGroups) ListRaw(ctx context.Context, req ListGroupsRequest) ([]byte, error) {
+
+ if err := validators.ValidateRequest(req); err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/sdn/access_group/list"
+
+ res, err := a.client.DecortApiCall(ctx, http.MethodGet, url, req)
+ return res, err
+}
diff --git a/pkg/sdn/acsgroups/models.go b/pkg/sdn/acsgroups/models.go
new file mode 100644
index 0000000..fb70f4a
--- /dev/null
+++ b/pkg/sdn/acsgroups/models.go
@@ -0,0 +1,49 @@
+package acsgroups
+
+type AccessGroupItem struct {
+ Name string `json:"display_name"`
+ ID string `json:"id"`
+}
+
+type AccessGroupList struct {
+ AccessGroups []AccessGroup
+}
+
+type AccessGroup struct {
+ ID string `json:"id"`
+ DisplayName string `json:"display_name"`
+ Comment string `json:"comment"`
+ CreatedAt string `json:"created_at"`
+ CreatedBy string `json:"created_by"`
+ UpdatedAt string `json:"updated_at"`
+ UpdatedBy string `json:"updated_by"`
+ NetObjectAccessGroup NetObjectAccessGroup `json:"net_object_access_group"`
+ DefaultSecurityPolicy DefaultSecurityPolicy `json:"default_security_policy"`
+}
+
+type NetObjectAccessGroup struct {
+ ID string `json:"id"`
+ VersionID int64 `json:"version_id"`
+ AccessGroupID string `json:"access_group_id"`
+}
+
+type DefaultSecurityPolicy struct {
+ ID string `json:"id"`
+ DisplayName string `json:"display_name"`
+ Description string `json:"description"`
+ VersionID int64 `json:"version_id"`
+ AccessGroupID string `json:"access_group_id"`
+ DefaultAclDrop string `json:"default_acl_drop"`
+ DefaultOpenSessionDrop bool `json:"default_open_session_drop"`
+}
+
+type User struct {
+ Name string `json:"display_name"`
+ ID string `json:"id"`
+ RoleID string `json:"role_id"`
+ Login string `json:"login"`
+}
+
+type UsersList struct {
+ Users []User
+}
diff --git a/pkg/sdn/acsgroups/path.go b/pkg/sdn/acsgroups/path.go
new file mode 100644
index 0000000..d0318cd
--- /dev/null
+++ b/pkg/sdn/acsgroups/path.go
@@ -0,0 +1,49 @@
+package acsgroups
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// PatchRequest struct to update access group
+type PatchRequest struct {
+ // Access group ID
+ // Required: true
+ AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
+
+ // Comment of the acces group
+ // Required: false
+ Comment string `url:"comment,omitempty" json:"comment,omitempty"`
+
+ // Name of acces group
+ // Required: false
+ DisplayName string `url:"display_name,omitempty" json:"display_name,omitempty"`
+}
+
+// Update updates a access groups
+func (i AccessGroups) Patch(ctx context.Context, req PatchRequest) (*AccessGroup, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/sdn/access_group/patch"
+
+ res, err := i.client.DecortApiCallCtype(ctx, http.MethodPatch, url, constants.MIMEJSON, req)
+ if err != nil {
+ return nil, err
+ }
+
+ info := AccessGroup{}
+
+ err = json.Unmarshal(res, &info)
+ if err != nil {
+ return nil, err
+ }
+
+ return &info, nil
+}
diff --git a/pkg/sdn/acsgroups/user_add.go b/pkg/sdn/acsgroups/user_add.go
new file mode 100644
index 0000000..dd7b46e
--- /dev/null
+++ b/pkg/sdn/acsgroups/user_add.go
@@ -0,0 +1,41 @@
+package acsgroups
+
+import (
+ "context"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// UserAddRequest struct to userAdd access group
+type UserAddRequest struct {
+ // Comment of the access group
+ // Required: true
+ GroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
+
+ // Access group role ID
+ // Required: true
+ AccessGroupRoleID string `url:"access_group_role_id" json:"access_group_role_id" validate:"required"`
+
+ // User ID
+ // Required: true
+ UserID string `url:"user_id" json:"user_id" validate:"required"`
+}
+
+// UserAdd a access groups
+func (i AccessGroups) UserAdd(ctx context.Context, req UserAddRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/sdn/access_group/user_add"
+
+ _, err = i.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
+ if err != nil {
+ return false, err
+ }
+
+ return true, nil
+}
diff --git a/pkg/sdn/acsgroups/user_delete.go b/pkg/sdn/acsgroups/user_delete.go
new file mode 100644
index 0000000..546d48b
--- /dev/null
+++ b/pkg/sdn/acsgroups/user_delete.go
@@ -0,0 +1,37 @@
+package acsgroups
+
+import (
+ "context"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// UserDeleteRequest struct to userDelete access group
+type UserDeleteRequest struct {
+ // Comment of the access group
+ // Required: true
+ GroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
+
+ // User ID
+ // Required: true
+ UserID string `url:"user_id" json:"user_id" validate:"required"`
+}
+
+// UserDelete a access groups
+func (i AccessGroups) UserDelete(ctx context.Context, req UserDeleteRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/sdn/access_group/user_delete"
+
+ _, err = i.client.DecortApiCallCtype(ctx, http.MethodDelete, url, constants.MIMEJSON, req)
+ if err != nil {
+ return false, err
+ }
+
+ return true, nil
+}
diff --git a/pkg/sdn/acsgroups/user_list.go b/pkg/sdn/acsgroups/user_list.go
new file mode 100644
index 0000000..6b9d2a5
--- /dev/null
+++ b/pkg/sdn/acsgroups/user_list.go
@@ -0,0 +1,113 @@
+package acsgroups
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// UsersListRequest struct to get a list of users
+type UsersListRequest struct {
+ // Access group identifier
+ // Required: true
+ AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
+
+ // Filter by global role
+ // Required: false
+ GlobalRole string `url:"global_role,omitempty" json:"global_role,omitempty"`
+
+ // Filter by access group role
+ // Required: false
+ AccessGroupRole string `url:"access_group_role,omitempty" json:"access_group_role,omitempty"`
+
+ // Filter by enabled status (true/false)
+ // Required: false
+ Enabled interface{} `url:"enabled,omitempty" json:"enabled,omitempty" validate:"omitempty,isBool"`
+
+ // Filter by deleted status (true/false)
+ // Required: false
+ Deleted interface{} `url:"deleted,omitempty" json:"deleted,omitempty" validate:"omitempty,isBool"`
+
+ // Filter by display name
+ // Required: false
+ DisplayName string `url:"display_name,omitempty" json:"display_name,omitempty"`
+
+ // Filter by user login
+ // Required: false
+ Login string `url:"login,omitempty" json:"login,omitempty"`
+
+ // Filter by creator login
+ // Required: false
+ CreatedBy string `url:"created_by,omitempty" json:"created_by,omitempty"`
+
+ // Filter by last updater login
+ // Required: false
+ UpdatedBy string `url:"updated_by,omitempty" json:"updated_by,omitempty"`
+
+ // Filter by deleter login
+ // Required: false
+ DeletedBy string `url:"deleted_by,omitempty" json:"deleted_by,omitempty"`
+
+ // Filter by disabler login
+ // Required: false
+ DisabledBy string `url:"disabled_by,omitempty" json:"disabled_by,omitempty"`
+
+ // Page number for pagination
+ // Required: false
+ Page uint64 `url:"page,omitempty" json:"page,omitempty"`
+
+ // Number of results per page
+ // Required: false
+ PerPage uint64 `url:"per_page,omitempty" json:"per_page,omitempty"`
+
+ // Field to sort by (display_name, email, phone, created_at, updated_at, deleted_at)
+ // Required: false
+ SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty"`
+
+ // Sort order (asc/desc)
+ // Required: false
+ SortOrder string `url:"sort_order,omitempty" json:"sort_order,omitempty"`
+
+ // Creation date lower bound (inclusive)
+ // Required: false
+ CreatedFrom string `url:"created_from,omitempty" json:"created_from,omitempty"`
+
+ // Creation date upper bound (exclusive)
+ // Required: false
+ CreatedTo string `url:"created_to,omitempty" json:"created_to,omitempty"`
+}
+
+// List of access groups
+func (i AccessGroups) UsersList(ctx context.Context, req UsersListRequest) (*UsersList, error) {
+
+ res, err := i.UserListRaw(ctx, req)
+ if err != nil {
+ return nil, err
+ }
+
+ users := []User{}
+
+ err = json.Unmarshal(res, &users)
+ if err != nil {
+ return nil, err
+ }
+
+ result := UsersList{Users: users}
+
+ return &result, nil
+}
+
+// ListRaw gets a list of all users as an array of bytes
+func (a AccessGroups) UserListRaw(ctx context.Context, req UsersListRequest) ([]byte, error) {
+
+ if err := validators.ValidateRequest(req); err != nil {
+ return nil, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/sdn/access_group/user_list"
+
+ res, err := a.client.DecortApiCall(ctx, http.MethodGet, url, req)
+ return res, err
+}
diff --git a/pkg/sdn/acsgroups/user_update_role.go b/pkg/sdn/acsgroups/user_update_role.go
new file mode 100644
index 0000000..4f20c15
--- /dev/null
+++ b/pkg/sdn/acsgroups/user_update_role.go
@@ -0,0 +1,41 @@
+package acsgroups
+
+import (
+ "context"
+ "net/http"
+
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
+)
+
+// UserUpdateRoleRequest struct to userUpdateRole access group
+type UserUpdateRoleRequest struct {
+ // Comment of the access group
+ // Required: true
+ GroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
+
+ // Access group role ID
+ // Required: true
+ AccessGroupRoleID string `url:"access_group_role_id" json:"access_group_role_id" validate:"required"`
+
+ // User ID
+ // Required: true
+ UserID string `url:"user_id" json:"user_id" validate:"required"`
+}
+
+// UserUpdateRole a access groups
+func (i AccessGroups) UserUpdateRole(ctx context.Context, req UserUpdateRoleRequest) (bool, error) {
+ err := validators.ValidateRequest(req)
+ if err != nil {
+ return false, validators.ValidationErrors(validators.GetErrors(err))
+ }
+
+ url := "/sdn/access_group/update_role"
+
+ _, err = i.client.DecortApiCallCtype(ctx, http.MethodPut, url, constants.MIMEJSON, req)
+ if err != nil {
+ return false, err
+ }
+
+ return true, nil
+}
diff --git a/pkg/sdn/sdn.go b/pkg/sdn/sdn.go
new file mode 100644
index 0000000..8017495
--- /dev/null
+++ b/pkg/sdn/sdn.go
@@ -0,0 +1,16 @@
+// List of method groups for the SDN
+package sdn
+
+import "repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
+
+// Structure for creating request to SDN groups
+type SDN struct {
+ client interfaces.Caller
+}
+
+// Builder to get access to SDN
+func New(client interfaces.Caller) *SDN {
+ return &SDN{
+ client: client,
+ }
+}
diff --git a/tests/platform_upgrade/cloud_test.go b/tests/platform_upgrade/cloud_test.go
index c14ca90..ef6a63c 100644
--- a/tests/platform_upgrade/cloud_test.go
+++ b/tests/platform_upgrade/cloud_test.go
@@ -17,12 +17,15 @@ import (
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg"
+ securitygroup "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/security_group"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/sep"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/stack"
+ storagepolicy "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/storage_policy"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/trunk"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/zone"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/acsgroups"
account_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account"
audit_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/audit"
@@ -39,8 +42,10 @@ import (
node_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/node"
pcidevice_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/pcidevice"
rg_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg"
+ securitygroup_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/security_group"
sep_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep"
stack_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/stack"
+ storagepolicy_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/storage_policy"
tasks_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/tasks"
trunk_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/trunk"
vins_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
@@ -301,6 +306,46 @@ func TestGetListCloudAPI(t *testing.T) {
}
getResult("Stack list", bytes, stack.ListStacks{}, t)
+ // Storage policy
+ // List
+ bytes, err = client.CloudAPI().StoragePolicy().ListRaw(context.Background(), storagepolicy.ListRequest{})
+ if err != nil {
+ t.Error(err)
+ }
+ getResult("Storage policy list", bytes, storagepolicy.ListStoragePolicies{}, t)
+ // Get
+ listStoragePolicies, _ := client.CloudAPI().StoragePolicy().List(context.Background(), storagepolicy.ListRequest{})
+ if len(listStoragePolicies.Data) > 0 {
+ id := listStoragePolicies.Data[0].ID
+ bytes, err = client.CloudAPI().StoragePolicy().GetRaw(context.Background(), storagepolicy.GetRequest{StoragePolicyID: id})
+ if err != nil {
+ t.Error(err)
+ }
+ getResult("Storage policy get", bytes, storagepolicy.InfoStoragePolicy{}, t)
+ } else {
+ t.Errorf("Can not test Storage policy get because Storage policy list is empty")
+ }
+
+ // Security group
+ // List
+ bytes, err = client.CloudAPI().SecurityGroup().ListRaw(context.Background(), securitygroup.ListRequest{})
+ if err != nil {
+ t.Error(err)
+ }
+ getResult("Security group list", bytes, securitygroup.ListSecurityGroups{}, t)
+ // Get
+ listSecurityGroups, _ := client.CloudAPI().SecurityGroup().List(context.Background(), securitygroup.ListRequest{})
+ if len(listSecurityGroups.Data) > 0 {
+ id := listSecurityGroups.Data[0].ID
+ bytes, err = client.CloudAPI().SecurityGroup().GetRaw(context.Background(), securitygroup.GetRequest{SecurityGroupID: id})
+ if err != nil {
+ t.Error(err)
+ }
+ getResult("Security group get", bytes, securitygroup.RecordSecurityGroup{}, t)
+ } else {
+ t.Errorf("Can not test Security group get because Security group list is empty")
+ }
+
// Tasks
// List
bytes, err = client.CloudAPI().Tasks().ListRaw(context.Background(), tasks.ListRequest{})
@@ -681,6 +726,26 @@ func TestGetListCloudbroker(t *testing.T) {
t.Errorf("Can not test RG get because RG list is empty")
}
+ // Security group
+ // List
+ bytes, err = client.CloudBroker().SecurityGroup().ListRaw(context.Background(), securitygroup_cb.ListRequest{})
+ if err != nil {
+ t.Error(err)
+ }
+ getResult("Security group list", bytes, securitygroup_cb.ListSecurityGroups{}, t)
+ // Get
+ listSecurityGroups, _ := client.CloudBroker().SecurityGroup().List(context.Background(), securitygroup_cb.ListRequest{})
+ if len(listSecurityGroups.Data) > 0 {
+ id := listSecurityGroups.Data[0].ID
+ bytes, err = client.CloudBroker().SecurityGroup().GetRaw(context.Background(), securitygroup_cb.GetRequest{SecurityGroupID: id})
+ if err != nil {
+ t.Error(err)
+ }
+ getResult("Security group get", bytes, securitygroup_cb.RecordSecurityGroup{}, t)
+ } else {
+ t.Errorf("Can not test Security group get because Security group list is empty")
+ }
+
// SEP
// List
bytes, err = client.CloudBroker().SEP().ListRaw(context.Background(), sep_cb.ListRequest{})
@@ -727,6 +792,26 @@ func TestGetListCloudbroker(t *testing.T) {
t.Errorf("Can not test Stack get because Stack list is empty")
}
+ // Storage policy
+ // List
+ bytes, err = client.CloudBroker().StoragePolicy().ListRaw(context.Background(), storagepolicy_cb.ListRequest{})
+ if err != nil {
+ t.Error(err)
+ }
+ getResult("Storage policy list", bytes, storagepolicy_cb.ListStoragePolicies{}, t)
+ // Get
+ listStoragePolicies, _ := client.CloudBroker().StoragePolicy().List(context.Background(), storagepolicy_cb.ListRequest{})
+ if len(listStoragePolicies.Data) > 0 {
+ id := listStoragePolicies.Data[0].ID
+ bytes, err = client.CloudBroker().StoragePolicy().GetRaw(context.Background(), storagepolicy_cb.GetRequest{StoragePolicyID: id})
+ if err != nil {
+ t.Error(err)
+ }
+ getResult("Storage policy get", bytes, storagepolicy_cb.InfoStoragePolicy{}, t)
+ } else {
+ t.Errorf("Can not test Storage policy get because Storage policy list is empty")
+ }
+
// Tasks
// List
bytes, err = client.CloudBroker().Tasks().ListRaw(context.Background(), tasks_cb.ListRequest{})
@@ -796,6 +881,40 @@ func TestGetListCloudbroker(t *testing.T) {
}
}
+// TestGetListSDNAPI tests platforms responses vs. json tags of golang structures in cloudapi get/list methods
+func TestGetListSDNAPI(t *testing.T) {
+ var bytes []byte
+ var err error
+ client, err := getClient()
+ if err != nil {
+ t.Fatalf("Cannot get client: %v", err)
+ }
+
+ // AccessGroups
+ // List
+ bytes, err = client.SDN().AccessGroups().ListRaw(context.Background(), acsgroups.ListGroupsRequest{})
+ if err != nil {
+ t.Error(err)
+ }
+
+ getResult("access groups list", bytes, acsgroups.AccessGroup{}, t)
+
+ // Users AccessGroups
+ // list
+ listAcsGroups, _ := client.SDN().AccessGroups().List(context.Background(), acsgroups.ListGroupsRequest{})
+ if len(listAcsGroups.AccessGroups) > 0 {
+ id := listAcsGroups.AccessGroups[0].ID
+ bytes, err = client.SDN().AccessGroups().UserListRaw(context.Background(), acsgroups.UsersListRequest{AccessGroupID: id})
+ if err != nil {
+ t.Error(err)
+ }
+ getResult("access groups users list", bytes, acsgroups.User{}, t)
+ } else {
+ t.Errorf("Can not test users get because acs groups list is empty")
+ }
+
+}
+
// TestRequestsCloudAPI tests platform requests vs. golang request structures in sdk for cloudapi requests
func TestRequestsCloudAPI(t *testing.T) {
bytes := getBytesFromJSON("input.json", t)
@@ -808,6 +927,11 @@ func TestRequestsCloudbroker(t *testing.T) {
getErrorsFromJSON(bytes, t, "cloudbroker")
}
+func TestRequestsSDN(t *testing.T) {
+ bytes := getBytesFromJSON("input.json", t)
+ getErrorsFromJSON(bytes, t, "sdn")
+}
+
// TestGetAllPaths tests if platform has any handlers that golang sdk doesn't. In this case, list of missing handlers is provided.
// Note that DEPRECATED_GROUPS stores list of groups that are considered deprecated. You can add additional grops to DEPRECATED_GROUPS if required.
func TestGetAllPaths(t *testing.T) {
@@ -839,8 +963,9 @@ func TestGetAllPaths(t *testing.T) {
caTestUrls := getRequestsMapCloudAPI()
cbTestUrls := getRequestsMapCloudbroker()
+ sdnTestUrls := getRequestsMapSDN()
- urlsInTest := make([]string, len(caTestUrls)+len(cbTestUrls))
+ urlsInTest := make([]string, len(caTestUrls)+len(cbTestUrls)+len(sdnTestUrls))
i := 0
for k := range caTestUrls {
@@ -851,6 +976,10 @@ func TestGetAllPaths(t *testing.T) {
urlsInTest[i] = k
i++
}
+ for k := range sdnTestUrls {
+ urlsInTest[i] = k
+ i++
+ }
missingUrls = getMissingDecortUrls(jsonUrls, urlsInTest)
if len(missingUrls) > 0 {
diff --git a/tests/platform_upgrade/request_map.go b/tests/platform_upgrade/request_map.go
index 5526088..f6af4cc 100644
--- a/tests/platform_upgrade/request_map.go
+++ b/tests/platform_upgrade/request_map.go
@@ -18,14 +18,17 @@ import (
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/pcidevice"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/prometheus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg"
+ securitygroup "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/security_group"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/sep"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/stack"
+ storagepolicy "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/storage_policy"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/trunk"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/user"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vfpool"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/zone"
+ "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/acsgroups"
account_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account"
apiaccess_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/apiaccess"
@@ -47,8 +50,10 @@ import (
pcidevice_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/pcidevice"
prometheus_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/prometheus"
rg_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg"
+ securitygroup_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/security_group"
sep_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep"
stack_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/stack"
+ storagepolicy_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/storage_policy"
tasks_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/tasks"
trunk_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/trunk"
user_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/user"
@@ -141,6 +146,7 @@ func getRequestsMapCloudAPI() map[string]interface{} {
"/restmachine/cloudapi/compute/cdEject": compute.CDEjectRequest{},
"/restmachine/cloudapi/compute/cdInsert": compute.CDInsertRequest{},
"/restmachine/cloudapi/compute/changeLinkState": compute.ChangeLinkStateRequest{},
+ "/restmachine/cloudapi/compute/change_security_groups": compute.ChangeSecGroupsRequest{},
"/restmachine/cloudapi/compute/clone": compute.CloneRequest{},
"/restmachine/cloudapi/compute/createTemplate": compute.CreateTemplateRequest{},
"/restmachine/cloudapi/compute/createTemplateFromBlank": compute.CreateTemplateFromBlankRequest{},
@@ -207,31 +213,32 @@ func getRequestsMapCloudAPI() map[string]interface{} {
"/restmachine/cloudapi/compute/guest_agent_feature_update": compute.GuestAgentFeatureUpdateRequest{},
// disks
- "/restmachine/cloudapi/disks/create": disks.CreateRequest{},
- "/restmachine/cloudapi/disks/delete": disks.DeleteRequest{},
- "/restmachine/cloudapi/disks/deleteDisks": disks.DisksDeleteRequest{},
- "/restmachine/cloudapi/disks/fromPlatformDisk": disks.FromPlatformDiskRequest{},
- "/restmachine/cloudapi/disks/get": disks.GetRequest{},
- "/restmachine/cloudapi/disks/limitIO": disks.LimitIORequest{},
- "/restmachine/cloudapi/disks/list": disks.ListRequest{},
- "/restmachine/cloudapi/disks/listDeleted": disks.ListDeletedRequest{},
- "/restmachine/cloudapi/disks/listTypes": disks.ListTypesRequest{},
- "/restmachine/cloudapi/disks/listUnattached": disks.ListUnattachedRequest{},
- "/restmachine/cloudapi/disks/rename": disks.RenameRequest{},
- "/restmachine/cloudapi/disks/replicate": disks.ReplicateRequest{},
- "/restmachine/cloudapi/disks/replicationResume": disks.ReplicationResumeRequest{},
- "/restmachine/cloudapi/disks/replicationReverse": disks.ReplicationReverseRequest{},
- "/restmachine/cloudapi/disks/replicationStart": disks.ReplicationStartRequest{},
- "/restmachine/cloudapi/disks/replicationStatus": disks.ReplicationStatusRequest{},
- "/restmachine/cloudapi/disks/replicationStop": disks.ReplicationStopRequest{},
- "/restmachine/cloudapi/disks/replicationSuspend": disks.ReplicationSuspendRequest{},
- "/restmachine/cloudapi/disks/resize2": disks.ResizeRequest{},
- "/restmachine/cloudapi/disks/restore": disks.RestoreRequest{},
- "/restmachine/cloudapi/disks/search": disks.SearchRequest{},
- "/restmachine/cloudapi/disks/share": disks.ShareRequest{},
- "/restmachine/cloudapi/disks/snapshotDelete": disks.SnapshotDeleteRequest{},
- "/restmachine/cloudapi/disks/snapshotRollback": disks.SnapshotRollbackRequest{},
- "/restmachine/cloudapi/disks/unshare": disks.UnshareRequest{},
+ "/restmachine/cloudapi/disks/change_disk_storage_policy": disks.ChangeDiskStoragePolicyRequest{},
+ "/restmachine/cloudapi/disks/create": disks.CreateRequest{},
+ "/restmachine/cloudapi/disks/delete": disks.DeleteRequest{},
+ "/restmachine/cloudapi/disks/deleteDisks": disks.DisksDeleteRequest{},
+ "/restmachine/cloudapi/disks/fromPlatformDisk": disks.FromPlatformDiskRequest{},
+ "/restmachine/cloudapi/disks/get": disks.GetRequest{},
+ "/restmachine/cloudapi/disks/limitIO": disks.LimitIORequest{},
+ "/restmachine/cloudapi/disks/list": disks.ListRequest{},
+ "/restmachine/cloudapi/disks/listDeleted": disks.ListDeletedRequest{},
+ "/restmachine/cloudapi/disks/listTypes": disks.ListTypesRequest{},
+ "/restmachine/cloudapi/disks/listUnattached": disks.ListUnattachedRequest{},
+ "/restmachine/cloudapi/disks/rename": disks.RenameRequest{},
+ "/restmachine/cloudapi/disks/replicate": disks.ReplicateRequest{},
+ "/restmachine/cloudapi/disks/replicationResume": disks.ReplicationResumeRequest{},
+ "/restmachine/cloudapi/disks/replicationReverse": disks.ReplicationReverseRequest{},
+ "/restmachine/cloudapi/disks/replicationStart": disks.ReplicationStartRequest{},
+ "/restmachine/cloudapi/disks/replicationStatus": disks.ReplicationStatusRequest{},
+ "/restmachine/cloudapi/disks/replicationStop": disks.ReplicationStopRequest{},
+ "/restmachine/cloudapi/disks/replicationSuspend": disks.ReplicationSuspendRequest{},
+ "/restmachine/cloudapi/disks/resize2": disks.ResizeRequest{},
+ "/restmachine/cloudapi/disks/restore": disks.RestoreRequest{},
+ "/restmachine/cloudapi/disks/search": disks.SearchRequest{},
+ "/restmachine/cloudapi/disks/share": disks.ShareRequest{},
+ "/restmachine/cloudapi/disks/snapshotDelete": disks.SnapshotDeleteRequest{},
+ "/restmachine/cloudapi/disks/snapshotRollback": disks.SnapshotRollbackRequest{},
+ "/restmachine/cloudapi/disks/unshare": disks.UnshareRequest{},
//dpdknet
"/restmachine/cloudapi/dpdknet/get": dpdknet.GetRequest{},
@@ -254,13 +261,14 @@ func getRequestsMapCloudAPI() map[string]interface{} {
"/restmachine/cloudapi/flipgroup/list": flipgroup.ListRequest{},
// image
- "/restmachine/cloudapi/image/create": image.CreateRequest{},
- "/restmachine/cloudapi/image/createVirtual": image.CreateVirtualRequest{},
- "/restmachine/cloudapi/image/delete": image.DeleteRequest{},
- "/restmachine/cloudapi/image/get": image.GetRequest{},
- "/restmachine/cloudapi/image/link": image.LinkRequest{},
- "/restmachine/cloudapi/image/list": image.ListRequest{},
- "/restmachine/cloudapi/image/rename": image.RenameRequest{},
+ "/restmachine/cloudapi/image/change_storage_policy": image.ChangeStoragePolicyRequest{},
+ "/restmachine/cloudapi/image/create": image.CreateRequest{},
+ "/restmachine/cloudapi/image/createVirtual": image.CreateVirtualRequest{},
+ "/restmachine/cloudapi/image/delete": image.DeleteRequest{},
+ "/restmachine/cloudapi/image/get": image.GetRequest{},
+ "/restmachine/cloudapi/image/link": image.LinkRequest{},
+ "/restmachine/cloudapi/image/list": image.ListRequest{},
+ "/restmachine/cloudapi/image/rename": image.RenameRequest{},
// k8ci, k8s
"/restmachine/cloudapi/k8ci/get": k8ci.GetRequest{},
@@ -375,6 +383,15 @@ func getRequestsMapCloudAPI() map[string]interface{} {
"/restmachine/cloudapi/rg/usage": rg.UsageRequest{},
"/restmachine/cloudapi/rg/removeDefNet": rg.RemoveDefNetRequest{},
+ // security_group
+ "/restmachine/cloudapi/security_group/create": securitygroup.CreateRequest{},
+ "/restmachine/cloudapi/security_group/create_rule": securitygroup.CreateRuleRequest{},
+ "/restmachine/cloudapi/security_group/delete": securitygroup.DeleteRequest{},
+ "/restmachine/cloudapi/security_group/delete_rule": securitygroup.DeleteRuleRequest{},
+ "/restmachine/cloudapi/security_group/get": securitygroup.GetRequest{},
+ "/restmachine/cloudapi/security_group/list": securitygroup.ListRequest{},
+ "/restmachine/cloudapi/security_group/update": securitygroup.UpdateRequest{},
+
// sep
"/restmachine/cloudapi/sep/listAvailableSepAndPools": sep.ListAvailableSEPAndPoolsRequest{},
@@ -384,6 +401,10 @@ func getRequestsMapCloudAPI() map[string]interface{} {
"/restmachine/cloudapi/tasks/get": tasks.GetRequest{},
"/restmachine/cloudapi/tasks/list": tasks.ListRequest{},
+ // storage policy
+ "/restmachine/cloudapi/storage_policy/get": storagepolicy.GetRequest{},
+ "/restmachine/cloudapi/storage_policy/list": storagepolicy.ListRequest{},
+
// trunk
"/restmachine/cloudapi/trunk/get": trunk.GetRequest{},
"/restmachine/cloudapi/trunk/list": trunk.ListRequest{},
@@ -442,8 +463,10 @@ func getRequestsMapCloudbroker() map[string]interface{} {
return map[string]interface{}{
// account_cb
"/restmachine/cloudbroker/account/addUser": account_cb.AddUserRequest{},
+ "/restmachine/cloudbroker/account/add_storage_policy": account_cb.AddStoragePolicyRequest{},
"/restmachine/cloudbroker/account/audits": account_cb.AuditsRequest{},
"/restmachine/cloudbroker/account/create": account_cb.CreateRequest{},
+ "/restmachine/cloudbroker/account/del_storage_policy": account_cb.DelStoragePolicyRequest{},
"/restmachine/cloudbroker/account/delete": account_cb.DeleteRequest{},
"/restmachine/cloudbroker/account/deleteAccounts": account_cb.DeleteAccountsRequest{},
"/restmachine/cloudbroker/account/deleteUser": account_cb.DeleteUserRequest{},
@@ -527,6 +550,7 @@ func getRequestsMapCloudbroker() map[string]interface{} {
"/restmachine/cloudbroker/compute/cdInsert": compute_cb.CDInsertRequest{},
"/restmachine/cloudbroker/compute/changeLinkState": compute_cb.ChangeLinkStateRequest{},
"/restmachine/cloudbroker/compute/change_mtu": compute_cb.ChangeMTURequest{},
+ "/restmachine/cloudbroker/compute/change_security_groups": compute_cb.ChangeSecGroupsRequest{},
"/restmachine/cloudbroker/compute/clone": compute_cb.CloneRequest{},
"/restmachine/cloudbroker/compute/computeciSet": compute_cb.ComputeCISetRequest{},
"/restmachine/cloudbroker/compute/computeciUnset": compute_cb.ComputeCIUnsetRequest{},
@@ -608,33 +632,34 @@ func getRequestsMapCloudbroker() map[string]interface{} {
"/restmachine/cloudbroker/compute/guest_agent_feature_update": compute_cb.GuestAgentFeatureUpdateRequest{},
// disks
- "/restmachine/cloudbroker/disks/create": disks_cb.CreateRequest{},
- "/restmachine/cloudbroker/disks/delete": disks_cb.DeleteRequest{},
- "/restmachine/cloudbroker/disks/deleteDisks": disks_cb.DeleteDisksRequest{},
- "/restmachine/cloudbroker/disks/depresent": disks_cb.DepresentRequest{},
- "/restmachine/cloudbroker/disks/fromPlatformDisk": disks_cb.FromPlatformDiskRequest{},
- "/restmachine/cloudbroker/disks/get": disks_cb.GetRequest{},
- "/restmachine/cloudbroker/disks/limitIO": disks_cb.LimitIORequest{},
- "/restmachine/cloudbroker/disks/list": disks_cb.ListRequest{},
- "/restmachine/cloudbroker/disks/listDeleted": disks_cb.ListDeletedRequest{},
- "/restmachine/cloudbroker/disks/listTypes": disks_cb.ListTypesRequest{},
- "/restmachine/cloudbroker/disks/listUnattached": disks_cb.ListUnattachedRequest{},
- "/restmachine/cloudbroker/disks/rename": disks_cb.RenameRequest{},
- "/restmachine/cloudbroker/disks/present": disks_cb.PresentRequest{},
- "/restmachine/cloudbroker/disks/replicate": disks_cb.ReplicateRequest{},
- "/restmachine/cloudbroker/disks/replicationResume": disks_cb.ReplicationResumeRequest{},
- "/restmachine/cloudbroker/disks/replicationReverse": disks_cb.ReplicationReverseRequest{},
- "/restmachine/cloudbroker/disks/replicationStart": disks_cb.ReplicationStartRequest{},
- "/restmachine/cloudbroker/disks/replicationStatus": disks_cb.ReplicationStatusRequest{},
- "/restmachine/cloudbroker/disks/replicationStop": disks_cb.ReplicationStopRequest{},
- "/restmachine/cloudbroker/disks/replicationSuspend": disks_cb.ReplicationSuspendRequest{},
- "/restmachine/cloudbroker/disks/resize2": disks_cb.ResizeRequest{},
- "/restmachine/cloudbroker/disks/restore": disks_cb.RestoreRequest{},
- "/restmachine/cloudbroker/disks/search": disks_cb.SearchRequest{},
- "/restmachine/cloudbroker/disks/share": disks_cb.ShareRequest{},
- "/restmachine/cloudbroker/disks/snapshotDelete": disks_cb.SnapshotDeleteRequest{},
- "/restmachine/cloudbroker/disks/snapshotRollback": disks_cb.SnapshotRollbackRequest{},
- "/restmachine/cloudbroker/disks/unshare": disks_cb.UnshareRequest{},
+ "/restmachine/cloudbroker/disks/change_disk_storage_policy": disks_cb.ChangeDiskStoragePolicyRequest{},
+ "/restmachine/cloudbroker/disks/create": disks_cb.CreateRequest{},
+ "/restmachine/cloudbroker/disks/delete": disks_cb.DeleteRequest{},
+ "/restmachine/cloudbroker/disks/deleteDisks": disks_cb.DeleteDisksRequest{},
+ "/restmachine/cloudbroker/disks/depresent": disks_cb.DepresentRequest{},
+ "/restmachine/cloudbroker/disks/fromPlatformDisk": disks_cb.FromPlatformDiskRequest{},
+ "/restmachine/cloudbroker/disks/get": disks_cb.GetRequest{},
+ "/restmachine/cloudbroker/disks/limitIO": disks_cb.LimitIORequest{},
+ "/restmachine/cloudbroker/disks/list": disks_cb.ListRequest{},
+ "/restmachine/cloudbroker/disks/listDeleted": disks_cb.ListDeletedRequest{},
+ "/restmachine/cloudbroker/disks/listTypes": disks_cb.ListTypesRequest{},
+ "/restmachine/cloudbroker/disks/listUnattached": disks_cb.ListUnattachedRequest{},
+ "/restmachine/cloudbroker/disks/rename": disks_cb.RenameRequest{},
+ "/restmachine/cloudbroker/disks/present": disks_cb.PresentRequest{},
+ "/restmachine/cloudbroker/disks/replicate": disks_cb.ReplicateRequest{},
+ "/restmachine/cloudbroker/disks/replicationResume": disks_cb.ReplicationResumeRequest{},
+ "/restmachine/cloudbroker/disks/replicationReverse": disks_cb.ReplicationReverseRequest{},
+ "/restmachine/cloudbroker/disks/replicationStart": disks_cb.ReplicationStartRequest{},
+ "/restmachine/cloudbroker/disks/replicationStatus": disks_cb.ReplicationStatusRequest{},
+ "/restmachine/cloudbroker/disks/replicationStop": disks_cb.ReplicationStopRequest{},
+ "/restmachine/cloudbroker/disks/replicationSuspend": disks_cb.ReplicationSuspendRequest{},
+ "/restmachine/cloudbroker/disks/resize2": disks_cb.ResizeRequest{},
+ "/restmachine/cloudbroker/disks/restore": disks_cb.RestoreRequest{},
+ "/restmachine/cloudbroker/disks/search": disks_cb.SearchRequest{},
+ "/restmachine/cloudbroker/disks/share": disks_cb.ShareRequest{},
+ "/restmachine/cloudbroker/disks/snapshotDelete": disks_cb.SnapshotDeleteRequest{},
+ "/restmachine/cloudbroker/disks/snapshotRollback": disks_cb.SnapshotRollbackRequest{},
+ "/restmachine/cloudbroker/disks/unshare": disks_cb.UnshareRequest{},
// dpdknet
"/restmachine/cloudbroker/dpdknet/get": dpdknet_cb.GetRequest{},
@@ -717,26 +742,27 @@ func getRequestsMapCloudbroker() map[string]interface{} {
"/restmachine/cloudbroker/group/list": group_cb.ListRequest{},
// image
- "/restmachine/cloudbroker/image/computeciSet": image_cb.ComputeCISetRequest{},
- "/restmachine/cloudbroker/image/computeciUnset": image_cb.ComputeCIUnsetRequest{},
- "/restmachine/cloudbroker/image/createCDROMImage": image_cb.CreateCDROMImageRequest{},
- "/restmachine/cloudbroker/image/createImage": image_cb.CreateRequest{},
- "/restmachine/cloudbroker/image/createVirtual": image_cb.CreateVirtualRequest{},
- "/restmachine/cloudbroker/image/delete": image_cb.DeleteRequest{},
- "/restmachine/cloudbroker/image/deleteCDROMImage": image_cb.DeleteCDROMImageRequest{},
- "/restmachine/cloudbroker/image/deleteImages": image_cb.DeleteImagesRequest{},
- "/restmachine/cloudbroker/image/disable": image_cb.DisableRequest{},
- "/restmachine/cloudbroker/image/edit": image_cb.EditRequest{},
- "/restmachine/cloudbroker/image/enable": image_cb.EnableRequest{},
- "/restmachine/cloudbroker/image/get": image_cb.GetRequest{},
- "/restmachine/cloudbroker/image/grantAccess": image_cb.GrantAccessRequest{},
- "/restmachine/cloudbroker/image/link": image_cb.LinkRequest{},
- "/restmachine/cloudbroker/image/list": image_cb.ListRequest{},
- "/restmachine/cloudbroker/image/listStacks": image_cb.ListStacksRequest{},
- "/restmachine/cloudbroker/image/rename": image_cb.RenameRequest{},
- "/restmachine/cloudbroker/image/revokeAccess": image_cb.RevokeAccessRequest{},
- "/restmachine/cloudbroker/image/share": image_cb.ShareRequest{},
- "/restmachine/cloudbroker/image/updateNodes": image_cb.UpdateNodesRequest{},
+ "/restmachine/cloudbroker/image/change_storage_policy": image_cb.ChangeStoragePolicyRequest{},
+ "/restmachine/cloudbroker/image/computeciSet": image_cb.ComputeCISetRequest{},
+ "/restmachine/cloudbroker/image/computeciUnset": image_cb.ComputeCIUnsetRequest{},
+ "/restmachine/cloudbroker/image/createCDROMImage": image_cb.CreateCDROMImageRequest{},
+ "/restmachine/cloudbroker/image/createImage": image_cb.CreateRequest{},
+ "/restmachine/cloudbroker/image/createVirtual": image_cb.CreateVirtualRequest{},
+ "/restmachine/cloudbroker/image/delete": image_cb.DeleteRequest{},
+ "/restmachine/cloudbroker/image/deleteCDROMImage": image_cb.DeleteCDROMImageRequest{},
+ "/restmachine/cloudbroker/image/deleteImages": image_cb.DeleteImagesRequest{},
+ "/restmachine/cloudbroker/image/disable": image_cb.DisableRequest{},
+ "/restmachine/cloudbroker/image/edit": image_cb.EditRequest{},
+ "/restmachine/cloudbroker/image/enable": image_cb.EnableRequest{},
+ "/restmachine/cloudbroker/image/get": image_cb.GetRequest{},
+ "/restmachine/cloudbroker/image/grantAccess": image_cb.GrantAccessRequest{},
+ "/restmachine/cloudbroker/image/link": image_cb.LinkRequest{},
+ "/restmachine/cloudbroker/image/list": image_cb.ListRequest{},
+ "/restmachine/cloudbroker/image/listStacks": image_cb.ListStacksRequest{},
+ "/restmachine/cloudbroker/image/rename": image_cb.RenameRequest{},
+ "/restmachine/cloudbroker/image/revokeAccess": image_cb.RevokeAccessRequest{},
+ "/restmachine/cloudbroker/image/share": image_cb.ShareRequest{},
+ "/restmachine/cloudbroker/image/updateNodes": image_cb.UpdateNodesRequest{},
// k8ci
"/restmachine/cloudbroker/k8ci/accessAdd": k8ci_cb.AccessAddRequest{},
@@ -855,11 +881,13 @@ func getRequestsMapCloudbroker() map[string]interface{} {
// rg
"/restmachine/cloudbroker/rg/accessGrant": rg_cb.AccessGrantRequest{},
"/restmachine/cloudbroker/rg/accessRevoke": rg_cb.AccessRevokeRequest{},
+ "/restmachine/cloudbroker/rg/add_storage_policy": rg_cb.AddStoragePolicyRequest{},
"/restmachine/cloudbroker/rg/affinityGroupComputes": rg_cb.AffinityGroupComputesRequest{},
"/restmachine/cloudbroker/rg/affinityGroupsGet": rg_cb.AffinityGroupsGetRequest{},
"/restmachine/cloudbroker/rg/affinityGroupsList": rg_cb.AffinityGroupsListRequest{},
"/restmachine/cloudbroker/rg/audits": rg_cb.AuditsRequest{},
"/restmachine/cloudbroker/rg/create": rg_cb.CreateRequest{},
+ "/restmachine/cloudbroker/rg/del_storage_policy": rg_cb.DelStoragePolicyRequest{},
"/restmachine/cloudbroker/rg/delete": rg_cb.DeleteRequest{},
"/restmachine/cloudbroker/rg/disable": rg_cb.DisableRequest{},
"/restmachine/cloudbroker/rg/enable": rg_cb.EnableRequest{},
@@ -885,6 +913,15 @@ func getRequestsMapCloudbroker() map[string]interface{} {
"/restmachine/cloudbroker/rg/usage": rg_cb.UsageRequest{},
"/restmachine/cloudbroker/rg/removeDefNet": rg_cb.RemoveDefNetRequest{},
+ // security_group
+ "/restmachine/cloudbroker/security_group/create": securitygroup_cb.CreateRequest{},
+ "/restmachine/cloudbroker/security_group/create_rule": securitygroup_cb.CreateRuleRequest{},
+ "/restmachine/cloudbroker/security_group/delete": securitygroup_cb.DeleteRequest{},
+ "/restmachine/cloudbroker/security_group/delete_rule": securitygroup_cb.DeleteRuleRequest{},
+ "/restmachine/cloudbroker/security_group/get": securitygroup_cb.GetRequest{},
+ "/restmachine/cloudbroker/security_group/list": securitygroup_cb.ListRequest{},
+ "/restmachine/cloudbroker/security_group/update": securitygroup_cb.UpdateRequest{},
+
// sep
"/restmachine/cloudbroker/sep/accessGrant": sep_cb.AccessGrantRequest{},
"/restmachine/cloudbroker/sep/accessGrantToPool": sep_cb.AccessGrantToPoolRequest{},
@@ -920,6 +957,17 @@ func getRequestsMapCloudbroker() map[string]interface{} {
"/restmachine/cloudbroker/stack/setCpuAllocationRatio": stack_cb.SetCpuAllocationRatioRequest{},
"/restmachine/cloudbroker/stack/setMemAllocationRatio": stack_cb.SetMemAllocationRatioRequest{},
+ // storage_policy
+ "/restmachine/cloudbroker/storage_policy/get": storagepolicy_cb.GetRequest{},
+ "/restmachine/cloudbroker/storage_policy/list": storagepolicy_cb.ListRequest{},
+ "/restmachine/cloudbroker/storage_policy/create": storagepolicy_cb.CreateRequest{},
+ "/restmachine/cloudbroker/storage_policy/update": storagepolicy_cb.UpdateRequest{},
+ "/restmachine/cloudbroker/storage_policy/add_pool": storagepolicy_cb.AddPoolRequest{},
+ "/restmachine/cloudbroker/storage_policy/delete": storagepolicy_cb.DeleteRequest{},
+ "/restmachine/cloudbroker/storage_policy/disable": storagepolicy_cb.DisableRequest{},
+ "/restmachine/cloudbroker/storage_policy/enable": storagepolicy_cb.EnableRequest{},
+ "/restmachine/cloudbroker/storage_policy/delete_pool": storagepolicy_cb.DeletePollRequest{},
+
// tasks
"/restmachine/cloudbroker/tasks/get": tasks_cb.GetRequest{},
"/restmachine/cloudbroker/tasks/list": tasks_cb.ListRequest{},
@@ -1000,6 +1048,7 @@ func getRequestsMapCloudbroker() map[string]interface{} {
"/restmachine/cloudbroker/vins/staticRouteAdd": vins_cb.StaticRouteAddRequest{},
"/restmachine/cloudbroker/vins/staticRouteDel": vins_cb.StaticRouteDelRequest{},
"/restmachine/cloudbroker/vins/staticRouteList": vins_cb.StaticRouteListRequest{},
+ "/restmachine/cloudbroker/vins/update": vins_cb.UpdateRequest{},
"/restmachine/cloudbroker/vins/vnfdevRedeploy": vins_cb.VNFDevRedeployRequest{},
"/restmachine/cloudbroker/vins/vnfdevRestart": vins_cb.VNFDevRestartRequest{},
"/restmachine/cloudbroker/vins/vnfdevReset": vins_cb.VNFDevResetRequest{},
@@ -1016,3 +1065,18 @@ func getRequestsMapCloudbroker() map[string]interface{} {
"/restmachine/cloudbroker/zone/delNode": zone_cb.DelNodeRequest{},
}
}
+
+// getRequestsMapSDN maps request path with request golang sdk structures for sdn most used requests
+func getRequestsMapSDN() map[string]interface{} {
+ return map[string]interface{}{
+ // access_groups
+ "/restmachine/sdn/access_group/list": acsgroups.ListGroupsRequest{},
+ "/restmachine/sdn/access_group/user_list": acsgroups.UsersListRequest{},
+ "/restmachine/sdn/access_group/create": acsgroups.CreateRequest{},
+ "/restmachine/sdn/access_group/delete": acsgroups.DeleteRequest{},
+ "/restmachine/sdn/access_group/user_add": acsgroups.UserAddRequest{},
+ "/restmachine/sdn/access_group/patch": acsgroups.PatchRequest{},
+ "/restmachine/sdn/access_group/user_delete": acsgroups.UserDeleteRequest{},
+ "/restmachine/sdn/access_group/update_role": acsgroups.UserUpdateRoleRequest{},
+ }
+}
diff --git a/tests/platform_upgrade/utils_get_list.go b/tests/platform_upgrade/utils_get_list.go
index 12f5ddd..3a5d413 100644
--- a/tests/platform_upgrade/utils_get_list.go
+++ b/tests/platform_upgrade/utils_get_list.go
@@ -72,22 +72,25 @@ func getResult(testName string, bytes []byte, structure any, t *testing.T) strin
t.Errorf(result)
return result
}
- return ""
+ result := fmt.Sprint(testName, ": ok")
+ t.Log(result)
+ return result
}
// getDifference tells which fields are present in bytesMap and not present in structMap and vice versa.
func getDifference(testName string, bytesMap, structMap map[string]interface{}) string {
var result string
bytesFields, _ := evaluate(bytesMap, structMap)
+ // structFields, _ := evaluate(structMap, bytesMap)
result += fmt.Sprintf("%s: ", testName)
if len(bytesFields) > 0 {
result += fmt.Sprintf("\nPlatform has these fields that golang struct doesn't: %v\n", bytesFields)
}
- //if len(structFields) > 0 {
- // result += fmt.Sprintf("Golang struct has these fields that platform doesn't: %v\n", structFields)
- //}
+ // if len(structFields) > 0 {
+ // result += fmt.Sprintf("Golang struct has these fields that platform doesn't: %v\n", structFields)
+ // }
if len(bytesFields) == 0 {
result += "OK"
@@ -172,13 +175,25 @@ func appendSelectedElements(slice []string, elements []string) []string {
// GetMapFromBytes converts []byte to map[string]interface{}
func GetMapFromBytes(bytes []byte) (map[string]interface{}, error) {
- var x map[string]interface{}
- err := json.Unmarshal(bytes, &x)
+ var unmarshalMaps map[string]interface{}
+ err := json.Unmarshal(bytes, &unmarshalMaps)
+ if err != nil {
+ var unmarshalSlice []interface{}
+ err = json.Unmarshal(bytes, &unmarshalSlice)
+ if err != nil {
+ return nil, err
+ }
+ t, ok := unmarshalSlice[0].(map[string]interface{})
+ if !ok {
+ return nil, err
+ }
+ unmarshalMaps = t
+ }
if err != nil {
return nil, err
}
- return getMapBytes(x), nil
+ return getMapBytes(unmarshalMaps), nil
}
func getMapBytes(value map[string]interface{}) map[string]interface{} {
diff --git a/tests/platform_upgrade/utils_requests.go b/tests/platform_upgrade/utils_requests.go
index 5545620..72cf31a 100644
--- a/tests/platform_upgrade/utils_requests.go
+++ b/tests/platform_upgrade/utils_requests.go
@@ -11,12 +11,24 @@ import (
func getParameters(input map[string]interface{}) []interface{} {
var emptySlice []interface{}
- post, ok := input["post"]
- if !ok {
+ methods := []string{"get", "post", "put", "delete", "patch", "head", "options"}
+
+ var methodData interface{}
+ found := false
+
+ for _, method := range methods {
+ if data, ok := input[method]; ok {
+ methodData = data
+ found = true
+ break
+ }
+ }
+
+ if !found {
return emptySlice
}
- parameters, ok := post.(map[string]interface{})
+ parameters, ok := methodData.(map[string]interface{})
if !ok {
return emptySlice
}
@@ -30,7 +42,47 @@ func getParameters(input map[string]interface{}) []interface{} {
if !ok {
return emptySlice
}
-
+ // Check if there's a body parameter
+ for _, p := range res {
+ param, ok := p.(map[string]interface{})
+ if !ok {
+ continue
+ }
+ if param["name"] == "body" {
+ schema, ok := param["schema"].(map[string]interface{})
+ if !ok {
+ continue
+ }
+ properties, ok := schema["properties"].(map[string]interface{})
+ if !ok {
+ continue
+ }
+ requiredFields := make(map[string]bool)
+ if req, ok := schema["required"].([]interface{}); ok {
+ for _, r := range req {
+ requiredFields[r.(string)] = true
+ }
+ }
+ var newParams []interface{}
+ for name, prop := range properties {
+ propMap, ok := prop.(map[string]interface{})
+ if !ok {
+ continue
+ }
+ newParam := make(map[string]interface{})
+ newParam["name"] = name
+ newParam["type"] = propMap["type"]
+ newParam["required"] = requiredFields[name]
+ if propMap["type"] == "array" {
+ if items, ok := propMap["items"].(map[string]interface{}); ok {
+ newParam["items"] = items
+ }
+ }
+ newParams = append(newParams, newParam)
+ }
+ return newParams
+ }
+ }
return res
}
@@ -57,8 +109,10 @@ func getErrorsFromJSON(bytes []byte, t *testing.T, cloud string) {
requests = getRequestsMapCloudAPI()
case "cloudbroker":
requests = getRequestsMapCloudbroker()
+ case "sdn":
+ requests = getRequestsMapSDN()
default:
- t.Fatalf("Wrong cloud provided, expected `cloudapi` or `cloudbroker`, got %s", cloud)
+ t.Fatalf("Wrong cloud provided, expected `cloudapi`, `cloudbroker` or `sdn`, got %s", cloud)
}
var dataLogs []string
@@ -96,12 +150,18 @@ func getErrorsFromJSON(bytes []byte, t *testing.T, cloud string) {
continue
}
- name := param["name"].(string)
+ name, ok := param["name"].(string)
+ if !ok {
+ name = ""
+ }
required, ok := param["required"].(bool)
if !ok {
required = false
}
- typ := p.(map[string]interface{})["type"].(string)
+ typ, ok := p.(map[string]interface{})["type"].(string)
+ if !ok {
+ typ = ""
+ }
var items string
if p.(map[string]interface{})["items"] != nil {
@@ -109,7 +169,10 @@ func getErrorsFromJSON(bytes []byte, t *testing.T, cloud string) {
if itemsTemp != nil {
itemsType := itemsTemp.(map[string]interface{})["type"]
if itemsType != nil {
- items = itemsType.(string)
+ items, ok = itemsType.(string)
+ if !ok {
+ items = ""
+ }
}
}
}
@@ -143,7 +206,7 @@ func getErrorsFromJSON(bytes []byte, t *testing.T, cloud string) {
}
if len(requests) != i {
- 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.",
+ msg := fmt.Sprintf("Amount of structure checked (%d) is not the same as amount of platform requests available (%d), please check getRequests func in code.",
i, len(requests))
t.Error(msg)
dataLogs = append(dataLogs, msg)
diff --git a/tests/platform_upgrade/utils_urls.go b/tests/platform_upgrade/utils_urls.go
index 9a7f953..90dd6d7 100644
--- a/tests/platform_upgrade/utils_urls.go
+++ b/tests/platform_upgrade/utils_urls.go
@@ -67,7 +67,7 @@ func getUrlsFromBytes(bytes []byte) ([]string, error) {
}
func validateUrlFromJson(url string) bool {
- if !strings.HasPrefix(url, "/restmachine/cloudapi/") && !strings.HasPrefix(url, "/restmachine/cloudbroker/") {
+ if !strings.HasPrefix(url, "/restmachine/cloudapi/") && !strings.HasPrefix(url, "/restmachine/cloudbroker/") && !strings.HasPrefix(url, "/restmachine/sdn/") {
return false
}
@@ -189,6 +189,11 @@ func readUrlFromFile(fileName string) ([]string, error) {
url := strings.Trim(scanner.Text()[indexStart:], `"`)
result = append(result, "/restmachine"+url)
}
+ if strings.Contains(scanner.Text(), `"/sdn/`) {
+ indexStart := strings.Index(scanner.Text(), "/sdn/")
+ url := strings.Trim(scanner.Text()[indexStart:], `"`)
+ result = append(result, "/restmachine"+url)
+ }
}
if len(result) == 0 {