main v1.8.0
Sergey Kisil 10 months ago
parent bc264c4d90
commit e7c968797b

@ -1,4 +1,197 @@
## Version 1.7.7
## Version 1.8.0
### Feature
#### account:
- Add endpoints GrantAccessTemplates, ListAvailableTemplates, RevokeAccessTemplates in cloudbroker/account
- Add SortBy field for list groups and validation functionality
- Add ComputeFeatures field to RecordAccount and ItemAccount models in cloudapi/account
- Add ComputeFeatures field to InfoAccount and CreateRequest model in cloudbroker/account
- Add UpdateComputeFeatures endpoint in cloudbroker/account
- Add ExtnetId, FreeIPs fields to model ItemVINS in cloudapi/account and cloudbroker/account
#### audit:
- Add field GUID in model ItemLinkedJobs cloudbroker/audit
- Delete field StatusCode in model ListRequest cloudbroker/audit
- Add fields MinStatusCode and MaxStatusCode in model ListRequest cloudbroker/audit
#### bservice:
- Add validation of RAM to be divisible by 128 in cloudapi/bservice
#### compute:
- Add field CdImageId in models ItemCompute and RecordCompute in cloudapi/compute and cloudbroker/compute
- Add fields NatableVINSID, NatableVINSIP, NatableVINSName, NatableVINSNetwork, NatableVINSNetworkName in models RecordCompute in cloudbroker/compute
- Set field LocalBasePort in model PFWAddRequest as optional in cloudapi/compute and cloudbroker/compute
- Add SortBy field for list groups and validation functionality
- Add HPBacked, CPUPin, NumaAffinity fields to RecordCompute and InfoCompute models in cloudbroker/compute
- Add HPBacked, CPUPin, NumaAffinity fields to RecordCompute and ItemCompute models in cloudapi/compute
- Add validation of RAM to be divisible by 128 in cloudapi/compute and cloudbroker/compute
- Add field NumaNodeId in models RecordCompute and ItemCompute in cloudapi/compute and cloudbroker/compute
- Add BootDiskSet endpoints in cloudapi/compute and cloudbroker/compute
- Add endpoints DiskSwitchToReplication, DiskMigrate in cloudapi/compute and cloudbroker/compute
- Add field Replication in model RecordCompute.Disks.ItemComputeDisk in cloudapi/compute and cloudbroker/compute
- Add endpoint getCustomFields in cloudbroker/compute
- Delete field AffinityLabel in model AffinityRelationsRequest in cloudbroker/compute
- Add fields ImageName and VirtualImageName, delete VINSConnected fields in RecordCompute model in cloudbroker/compute
- Add fields Enabled and NodeID in ItemInterface model in cloudbroker/compute. Add NodeID field in ItemVNFInterface model in cloudapi/compute
#### disks:
- Add endpoints Replicate, ReplicationResume, ReplicationReverse, ReplicationStart, ReplicationStop, ReplicationStatus, ReplicationSuspend in cloudapi/disks and cloudbroker/disks
- Add field Replication in models RecordDisk and ItemDisk in cloudapi/disks and cloudbroker/disks
- Add CreateTemplateFromBlank and CreateTemplateFromBlankAsync endpoints in cloudapi/compute and cloudbroker/compute
- Add fields Page and Size in model SearchRequest in cloudapi/disks
- Add FromPlatformDisk and FromPlatformDiskAsync endpoints in cloudapi/disks and cloudbroker/disks
#### flipgroup:
- Add fields ConnId, Status, AccountId to model ListRequest in cloudapi/flipgroup and cloudbroker/flipgroup
- Add SortBy field for list groups and validation functionality
#### grid:
- Add endpoints addCustomBackupPath, removeCustomBackupPath, setPasswordPolicy in cloudbroker/grid
#### image:
- Add field CdPresentedTo in model RecordImage in cloudapi/image cloudbroker/image
- Set field AccountId in CreateRequest in cloudapi/image as required
- Add endpoints GrantAccess, RevokeAccess in cloudbroker/image
- Add SortBy field for list groups and validation functionality
- Add field NetworkInterfaceNaming in model CreateRequest in cloudapi/image cloudbroker/image, in model EditRequest in cloudbroker/image, in models ItemImage and RecordImage in cloudapi/image and cloudbroker/image
- Add validation field NetworkInterfaceNaming in cloudapi/image cloudbroker/image
- Delete field GID in model CreateRequest in cloudapi/image
- Delete field Meta and Ckey in model and RecordImage in cloudbroker/image
- Add model ItemImage in cloudbroker/image
#### k8s:
- Add field LbSysctlParams in model CreateRequest in cloudapi/k8s/create and cloudbroker/k8s/create
- Add validation of RAM to be divisible by 128 in cloudapi/k8s and cloudbroker/k8s
- Set uint64 as MasterRAM and WorkerRAM types in CreateRequest struct in cloudapi/k8s and cloudbroker/k8s
#### kvmppc
- Add validation of RAM to be divisible by 128 in cloudapi/kvmppc and cloudbroker/kvmppc
- Add DataDisks field to CreateRequest and CreateBlankRequest in cloudapi/kvmppc and cloudbroker/kvmppc
- Add DataDisks field to MassCreateRequest in cloudbroker/kvmppc
#### kvmx86
- Add validation of RAM to be divisible by 128 in cloudapi/kvmx86 and cloudbroker/kvmx86
- Add DataDisks field to CreateRequest and CreateBlankRequest in cloudapi/kvmx86 and cloudbroker/kvmx86
- Add DataDisks field to MassCreateRequest in cloudbroker/kvmx86
#### lb:
- Add fields UserManaged, ManagerId, ManagerType, PartK8S in models RecordLB, ItemLBList in cloudapi/lb and cloudbroker/lb
- Add SortBy field for list groups and validation functionality
- Add field SysctlParams in model CreateRequest in cloudapi/lb/create and cloudbroker/lb/create
- Add endpoint update_sysctl_params in cloudapi/lb and cloudbroker/lb
#### node:
- Add ApplyIpmiAction, Consumption, Decommission, Enable, EnableNodes, Get, GetRaw, List, ListRaw, Maintenance, Restrict, SetCoreIsolation, SetHugePages, SetSRIOVStatus, SetVFSNumber and Update endpoints in cloudbroker/node
- Add IDs method and Filters methods for ListNodes structure in cloudbroker/node
- Add Serialize method for ListNodes, ItemNode and RecordNode structures in cloudbroker/node
#### pcidevice:
- Add List, ListRaw endpoints in cloudapi/pcidevice
- Add IDs and Serialize methods for ListPCIDevices structure in cloudapi/pcidevice
#### rg:
- Add ComputeFeatures field to ItemResourceGroup and RecordResourceGroup models in cloudapi/rg
- Add ComputeFeatures field to ItemRG and CreateRequest models in cloudbroker/rg
- Add UpdateComputeFeatures endpoint in cloudbroker/rg
- Add ExtnetId, FreeIPs fields to model ItemVINS in cloudapi/rg and cloudbroker/rg
#### sep:
- Add endpoints addPool, delPool in cloudbroker/sep
- Set field Config in CreateRequest as required in cloudbroker/sep
- Add SortBy field for list groups and validation functionality
#### stack:
- Add endpoints getLogicalCoresCount, setCpuAllocationRatio, setMemAllocationRatio in cloudbroker/stack
#### tasks:
- Add field TaskId, Status, Completed in model ListRequest in cloudapi/task and cloudbroker/task
- Add fields GUID, UpdatedBy in model ItemTask in cloudapi/task and cloudbroker/task
- Fix panic in List endpoints in cloudapi/task and cloudbroker/task
- Change type field Result from int to interface{} in models RecordAsyncTask, ItemAsyncTask in cloudapi/task and models ItemTask, RecordTask in cloudbroker/task
- Add methods ID(), Name(), ToString(), ToMaps() for processing the value of the Result field in model ItemTask in cloudapi/task and cloudbroker/task
- Add use case examples for the above methods in README.md
- Add SortBy field for list groups and validation functionality
- Add fields UpdateTimeAt and UpdateTimeTo in model ListRequest in cloudapi/tasks and cloudbroker/tasks
#### user:
- Add fields Call, StatusCode, TimestampAt, TimestampTo in models GetAuditRequest in cloudbroker/user
- Fix return value in GetAudit endpoint in cloudbroker/user
- Add model ListAudits and change type field APIAccess in model ItemUser in cloudbroker/user
- Add SortBy field for list groups and validation functionality in cloudbroker/user
- Add APIList, Authenticate, Brief, GetAudit, GetResourceConsumption, Get, GetRaw, IsValidInviteUserToken, Search, SetData endpoints in cloudapi/user
#### vfpool:
- Add Get, GetRaw, List, ListRaw endpoints in cloudapi/vfpool
- Add Create, Delete, Disable, Enable, Get, GetRaw, List, ListRaw, Update endpoints in cloudbroker/vfpool
- Add IDs method for ListVFPool, VFSInfoListand in cloudapi/vfpool and cloudbroker/vfpool
- Add Filters methods for ListVFPool structure in cloudapi/vfpool and cloudbroker/vfpool
- Add Serialize method for ListVFPool, ItemVFPool and RecordVFPool structures in cloudapi/vfpool and cloudbroker/vfpool
#### vins:
- Set field IntPort in model NATRuleAddRequest as optional in cloudapi/vins and cloudbroker/vins
- Add SortBy field for list groups and validation functionality
- Add ExtnetId, FreeIPs fields to model ItemVINS in cloudapi/vins and cloudbroker/vins
- Add DNSList field to models CreateInAccountRequest and CreateInRGRequest in cloudapi/vins and cloudbroker/vins
- Add DNSApply endpoints in cloudapi/vins and cloudbroker/vins
- Add field NodeID in model RecordVINS.RecordVNFDev.Interfaces in cloudapi/vins and cloudbroker/vins
### Bugfix
- Fix url for Disable method in cloudapi/bservice
#### account:
- Fix wrong json, url field AccountID in model SetCPUAllocationParameterRequest in cloudbroker/account
- Fix wrong json, url field AccountID in model SetCPUAllocationRatioRequest in cloudbroker/account
- Change Start and End fields type from uint64 to float64 in model GetConsumptionRequest in cloudapi/account
#### apiaccess:
- Changed Job and Resmon field types in model CloudBrokerEndpoints in cloudbroker/apiaccess
- Add fields Page and Size in model UserListRequest in cloudbroker/apiaccess
#### bservice:
- Fix url for Disable endpoint in cloudapi/bservice
#### compute:
- Fix Entrycount tag in model ListComputes in cloudbroker/compute
- Add field Name in model ListPCIDeviceRequest in cloudbroker/compute
- Fix type of field Data in model ListPCIDevices in cloudapi/compute
- Add model ItemPCIDevice in cloudapi/compute
- Fix type of field Data in model ListVGPUs in cloudapi/compute and cloudbroker/compute
- Add model ItemVGPU in cloudapi/compute and cloudbroker/compute
#### disks:
- Delete tag required from field Detailed in ListTypesRequest model in cloudapi/disks
#### grid:
- Fix json, url tags in field Name in model RenameRequest in cloudbroker/grid
#### image:
- Fix url for ComputeCIUnset endpoint in cloudbroker/image
#### k8ci:
- Delete omitempty from json, url tags in field Permanently in model DeleteRequest in cloudbroker/k8ci
- Fix wrong json, url tags field ByID in model ListDeletedRequest in cloudbroker/k8ci
- Fix allowed network plugin value from "weawenet" to "weavenet" in validators for cloudbroker/k8ci
#### k8s:
- Fix allowed network plugin value from "weawenet" to "weavenet" in validators for cloudapi/k8s, cloudbroker/k8s
#### lb:
- Fix wrong json, url tags field AccountID in model ListDeletedRequest in cloudapi/lb
- Add field Safe in model RestartRequest in cloudbroker/lb
- Fix wrong json, url tags field AccountID in models ListRequest, ListDeletedRequest in cloudbroker/lb
- Fix url for Stop endpoint in cloudapi/lb
#### rg:
- Fix wrong json, url field AccountID in model ListLBRequest in cloudapi/rg and cloudbroker/rg
- Fix wrong json, url field UniqPools in model CreateRequest in cloudbroker/rg
#### sep:
- Fix wrong json, url tag in field GID in model ListRequest in cloudbroker/sep
#### user:
- Fix wrong json, url field Password in model ItemUser in cloudbroker/user
- Change ByID field type from uint64 to string in model ListRequest in cloudbroker/user
#### vins:
- Fix wrong json, url tags in models DefaultQOSUpdateRequest and NetQOSRequest in field IngressBirst in cloudbroker/vins
- Fix wrong name field ListNatRule to ListNATRule in cloudbroker/vins

@ -12,49 +12,63 @@ Decort SDK - это библиотека, написанная на языке G
- Версия 1.5.x Decort-SDK соответствует 3.8.7 версии платформы
- Версия 1.6.x Decort-SDK соответствует 3.8.8 версии платформы
- Версия 1.7.х Decort-SDK соответствует 3.8.9 версии платформы
- Версия 1.8.х Decort-SDK соответствует 4.0.0 версии платформы
## Оглавление
- [Установка](#установка)
- [Список API](#список-api)
- [Decort SDK](#decort-sdk)
- [Версии](#версии)
- [Оглавление](#оглавление)
- [Установка](#установка)
- [Список API](#список-api)
- [Cloudapi](#cloudapi)
- [Cloudbroker](#cloudbroker)
- [Работа с библиотекой](#работа-с-библиотекой)
- [Работа с библиотекой](#работа-с-библиотекой)
- [Настройка конфигурации клиента](#настройка-конфигурации-клиента)
- [Пример конфигурации клиента](#пример-конфигурации-клиента)
- [Парсинг конфигурации из файла](#парсинг-конфигурации-из-файла)
- [Пример JSON конфигурации](#пример-json-конфигурации)
- [Пример YAML конфигурации](#пример-yaml-конфигурации)
- [Пример конфигурации клиента](#пример-конфигурации-клиента)
- [Парсинг конфигурации из файла](#парсинг-конфигурации-из-файла)
- [Пример JSON конфигурации](#пример-json-конфигурации)
- [Пример YAML конфигурации](#пример-yaml-конфигурации)
- [Создание клиента](#создание-клиента)
- [Создание структуры запроса](#cоздание-структуры-запроса)
- [Пример](#пример)
- [Создание структуры запроса](#создание-структуры-запроса)
- [Пример комментариев структуры](#пример-комментариев-структуры)
- [Пример создания запроса для развертывания виртуальной машины:](#пример-создания-запроса-для-развертывания-виртуальной-машины)
- [Выполнение запроса](#выполнение-запроса)
- [Пример выполнения запроса](#пример-выполнения-запроса)
- [Пример выполнения GetRaw и ListRaw запросов](#пример-выполнения-getraw-и-listraw-запросов)
- [Фильтрация](#фильтрация)
- [Использование на примере `compute.FilterByK8SID`:](#использование-на-примере-computefilterbyk8sid)
- [Сортировка](#сортировка)
- [Сериализация](#сериализация)
- [Получение списка уникальных идентификаторов (ID) объекта](#получение-списка-уникальных-идентификаторов-id-объекта)
- [Работа с legacy клиентом](#работа-с-legacy-клиентом)
- [Комплексный пример](#комплексный-пример)
- [Получение списка уникальных идентификаторов ID объекта](#получение-списка-уникальных-идентификаторов-id-объекта)
- [Методы поля Result для группы tasks](#методы-поля-result-для-группы-tasks)
- [Работа с legacy клиентом](#работа-с-legacy-клиентом)
- [Настройка конфигурации legacy клиента](#настройка-конфигурации-legacy-клиента)
- [Пример конфигурации legacy клиента](#пример-конфигурации-legacy-клиента)
- [Парсинг legacy конфигурации из файла](#парсинг-legacy-конфигурации-из-файла)
- [Пример legacy JSON конфигурации](#пример-legacy-json-конфигурации)
- [Пример legacy YAML конфигурации](#пример-legacy-yaml-конфигурации)
- [Пример конфигурации legacy клиента](#пример-конфигурации-legacy-клиента)
- [Парсинг legacy конфигурации из файла](#парсинг-legacy-конфигурации-из-файла)
- [Пример legacy JSON конфигурации](#пример-legacy-json-конфигурации)
- [Пример legacy YAML конфигурации](#пример-legacy-yaml-конфигурации)
- [Создание legacy клиента](#создание-legacy-клиента)
- [Создание структуры запроса](#cоздание-структуры-запроса)
- [Выполнение запроса](#выполнение-запроса)
- [Работа с BVS клиентом](#работа-с-bvs-клиентом)
- [Пример создания legacy клиента](#пример-создания-legacy-клиента)
- [Пример выполнения запроса](#пример-выполнения-запроса-1)
- [Работа с BVS клиентом](#работа-с-bvs-клиентом)
- [Настройка параметров BVS в кабинете администратора](#настройка-параметров-bvs-в-кабинете-администратора)
- [Настройка конфигурации BVS клиента](#настройка-конфигурации-bvs-клиента)
- [Описание структуры token](#описание-структуры-token)
- [Пример конфигурации BVS клиента](#пример-конфигурации-bvs-клиента)
- [Парсинг BVS конфигурации из файла](#парсинг-bvs-конфигурации-из-файла)
- [Парсинг BVS токена из файла](#парсинг-bvs-токена-из-файла)
- [Пример BVS JSON конфигурации](#пример-bvs-json-конфигурации)
- [Пример BVS YAML конфигурации](#пример-bvs-yaml-конфигурации)
- [Пример конфигурации BVS клиента](#пример-конфигурации-bvs-клиента)
- [Парсинг BVS конфигурации из файла](#парсинг-bvs-конфигурации-из-файла)
- [Парсинг BVS токена из файла](#парсинг-bvs-токена-из-файла)
- [Пример BVS JSON конфигурации](#пример-bvs-json-конфигурации)
- [Пример BVS YAML конфигурации](#пример-bvs-yaml-конфигурации)
- [Создание BVS клиента](#создание-bvs-клиента)
- [Пример создания BVS клиента](#пример-создания-bvs-клиента)
- [Пример получения BVS токена](#пример-получения-bvs-токена)
- [Пример обновления BVS токена](#пример-обновления-bvs-токена)
- [Пример выполнения запроса](#пример-выполнения-запроса)
- [Пример создания BVS клиента](#пример-создания-bvs-клиента)
- [Пример получения BVS токена](#пример-получения-bvs-токена)
- [Пример обновления BVS токена](#пример-обновления-bvs-токена)
- [Пример выполнения запроса](#пример-выполнения-запроса-2)
- [Пример валидации запросов, имеющих в своей структуре поле RAM (или MasterRam/WorkerRAM)](#пример-валидации-запросов-имеющих-в-своей-структуре-поле-ram-или-masterramworkerram)
- [Пример выполнения запроса](#пример-выполнения-запроса-3)
## Установка
@ -93,6 +107,7 @@ go get -u repository.basistech.ru/BASIS/decort-golang-sdk
- `Sizes` - получение информации о потребляемых ресурсах виртуальными машинами и дисками;
- `Stack` - получение информации о вычислительных узлах;
- `Tasks` - получение информации о ходе выполнения асинхронных задач (например, создание кластера);
- `VFPool` - управление пулом виртуальных сетевых функций;
- `VINS` - управление виртуальными изолированными сетями.
### Cloudbroker
@ -115,6 +130,7 @@ go get -u repository.basistech.ru/BASIS/decort-golang-sdk
- `KVMPPC` - создание виртуальной машины Power PC (IBM);
- `KVMx86` - создание виртуальной машины x86;
- `LB` - управление балансировщиками нагрузки;
- `Node` - управление нодами платформы;
- `PCIDevice` - управление устройствами;
- `RG` - управление ресурсными группами аккаунта;
- `SEP` - управление storage endpoint (sep);
@ -122,6 +138,7 @@ go get -u repository.basistech.ru/BASIS/decort-golang-sdk
- `Tasks` - получение информации о ходе выполнения асинхронных задач (например, создание кластера);
- `User` - управление пользователями (индивидуально);
- `VGPU` - управление виртуальными графическими процессорами;
- `VFPool` - управление пулом виртуальных сетевых функций;
- `VINS` - управление виртуальными изолированными сетями.
## Работа с библиотекой
@ -271,6 +288,7 @@ func main() {
- `pkg/cloudapi/sizes` - для `Sizes`
- `pkg/cloudapi/stack` - для `Stack`
- `pkg/cloudapi/tasks` - для `Tasks`
- `pkg/cloudapi/vfpool` - для `VFPool`
- `pkg/cloudapi/vins` - для `VINS`
- **cloudbroker**:
- `pkg/cloudbroker/account` - для `Account`
@ -288,6 +306,7 @@ func main() {
- `pkg/cloudbroker/kvmppc` - для `KVMPPC`
- `pkg/cloudbroker/kvmx86` - для `KVMX86`
- `pkg/cloudbroker/lb` - для `LB`
- `pkg/cloudbroker/node` - для `Node`
- `pkg/cloudbroker/pcidevice` - для `PCIDevice`
- `pkg/cloudbroker/rg` - для `RG`
- `pkg/cloudbroker/sep` - для `SEP`
@ -295,6 +314,7 @@ func main() {
- `pkg/cloudbroker/tasks` - для `Tasks`
- `pkg/cloudbroker/user` - для `User`
- `pkg/cloudbroker/vgpu` - для `VGPU`
- `pkg/cloudbroker/vfpool` - для `VFPool`
- `pkg/cloudbroker/vins` - для `VINS`
Все поля структуры имеют описание, в которых содержится:
@ -453,6 +473,7 @@ func main() {
- `.Sizes()` - для работы с `Sizes`
- `.Stack()` - для работы с `Stack`
- `.Tasks()` - для работы с `Tasks`
- `.VFPool()` - для работы с `VFPool`
- `.VINS()` - для работы с `VINS`
Доступные методы для `.CloudBroker()`:
@ -472,6 +493,7 @@ func main() {
- `.KVMPPC()` - для работы с `KVMPPC`
- `.KVMx86()` - для работы с `KVMX86`
- `.LB()` - для работы с `LB`
- `.Node()` - для работы с `Node`
- `.PCIDevice()` - для работы с `PCIDevice`
- `.RG()` - для работы с `RG`
- `.SEP()` - для работы с `SEP`
@ -479,6 +501,7 @@ func main() {
- `.Tasks()` - для работы с `Tasks`
- `.User()` - для работы с `User`
- `.VGPU()` - для работы с `VGPU`
- `.VFPool()` - для работы с `VFPool`
- `.VINS()` - для работы с `VINS`
3. Вызвать метод, отвечающий за выполнение запроса и передать в него:
@ -828,6 +851,87 @@ func main() {
}
```
### Методы поля Result для группы tasks
Поле Result внутри структур группы tasks имеет тип интерфейс и может содержать:
- строку о результате выполнения задачи, например `true`
- массив, содержащий ID и имя созданного ресурса, например `[12345, "resource_name"]`
- массив, содержащий информацию о восстновленных дисках, например `[{"computeId": 123, "diskId": 456}, {"computeId": 789, "diskId": 10}]`
Соответственно, для получения информации из поля Result доступны следующие методы:
- ToString(): строковое представление результата выполнения задачи
- ID() и Name(): получение ID и имени созданного в результате выполнения задачи ресурса
- ToMaps(): получение списка карт, содержащих информацию о дисках, восстановленных в результате выполнения задачи.
Все методы оборудованы возвратом ошибок. Непустая ошибка означает, что из поля Result нельзя получить информацию, которую предоставляет метод.
```go
package main
import (
"log"
"fmt"
"repository.basistech.ru/BASIS/decort-golang-sdk/config"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks"
tasks_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/tasks"
)
func main() {
// Настройка конфигурации
cfg := config.Config{
AppID: "<APPID>",
AppSecret: "<APPSECRET>",
SSOURL: "https://sso.digitalenergy.online",
DecortURL: "https://mr4.digitalenergy.online",
Retries: 5,
}
// Создание клиента
client := decort.New(cfg)
// Создание структуры запроса GetRequest на получение информации о конкретной задаче и выполнение запроса с помощью конвейера
getReq := tasks.GetRequest{
AuditID: "b6316",
}
task, err := client.CloudAPI().Tasks().Get(context.Background(), getReq)
if err != nil {
log.Fatal(err)
}
// Получение списка карт с информацией о восстановленных дисках
maps, err := task.Result.ToMaps()
if err != nil {
log.Fatal(err)
}
fmt.Println(maps)
// Получение строкового результата выполнения задачи task
res, _ := task.Result.ToString()
fmt.Println(res)
// Создание структуры запроса ListRequest на получение информации о всех задачах и выполнение запроса с помощью конвейера
listReq := tasks_cb.ListRequest{}
tasks, err := client.CloudBroker().Tasks().List(context.Background(), listReq)
if err != nil {
log.Fatal(err)
}
for _, t := range tasks {
// Получение id ресурса, созданного в результате выполнения задачи t
id, err := task.Result.ID()
if err != nil {
log.Fatal(err)
}
fmt.Println(id)
// Получение имени ресурса, созданного в результате выполнения задачи t
name, _ := task.Result.Name()
fmt.Println(name)
}
}
```
## Работа с legacy клиентом
Работа с legacy клиентом применяется для пользователей, которые не используют для авторизации decs3o.
@ -1290,3 +1394,65 @@ func main() {
fmt.Println(res)
}
```
#### Пример валидации запросов, имеющих в своей структуре поле RAM (или MasterRam/WorkerRAM)
Если структура запроса содержит поле RAM (или MasterRam/WorkerRAM), то он может быть проверен на валидность. Для этого запрос должен быть передан в функцию ValidateRAM. Вторым аргументом ValidateRAM ожидает число uint64. Рекомендуется использовать константу constants.RAM_DIVISIBILITY. Функция проверит кратно ли значение поля RAM (или MasterRam/WorkerRAM) этому числу.
#### Пример выполнения запроса
```go
package main
import (
"context"
"fmt"
"log"
"os"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/decort-golang-sdk/config"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/kvmx86"
)
func main() {
// Настройка конфигурации
cfg := config.Config{
AppID: "<APPID>",
AppSecret: "<APPSECRET>",
SSOURL: "https://sso-delta.qa.loc:8443",
DecortURL: "https://delta.qa.loc",
Retries: 5,
SSLSkipVerify: true,
}
// Создание клиента
client := decort.New(cfg)
// Создание структуры запроса
// CreateRequest - реквест на создание виртуальной машины
req := kvmx86.CreateRequest{
Name: "kvmx86",
RGID: 907,
CPU: 2048,
RAM: 1024,
ImageID: 161,
}
// Валидация запроса
err := validators.ValidateRAM(req, constants.RAM_DIVISIBILITY)
if err != nil {
log.Fatalf("unable to validate request: %v", err)
}
//Выполнение запроса с помощью конвейера
res, err := client.CloudBroker().KVMX86().Create(context.Background(), req)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
log.Println(res)
}
```

@ -4,6 +4,7 @@ import (
"bytes"
"context"
"crypto/tls"
"encoding/json"
"fmt"
"io"
"mime/multipart"
@ -77,7 +78,7 @@ func (dc *DecortClient) DecortApiCall(ctx context.Context, method, url string, p
body := bytes.NewBufferString(values.Encode())
req, err := http.NewRequestWithContext(ctx, method, dc.decortURL+constants.Restmachine+url, body)
req, err := http.NewRequestWithContext(ctx, method, dc.decortURL+constants.RESTMACHINE+url, body)
if err != nil {
return nil, err
}
@ -103,7 +104,7 @@ func (dc *DecortClient) DecortApiCallMP(ctx context.Context, method, url string,
return nil, err
}
req, err := http.NewRequestWithContext(ctx, method, dc.decortURL+constants.Restmachine+url, body)
req, err := http.NewRequestWithContext(ctx, method, dc.decortURL+constants.RESTMACHINE+url, body)
if err != nil {
return nil, err
}
@ -303,10 +304,20 @@ func multiPartReq(params interface{}) (*bytes.Buffer, string, error) {
return &bytes.Buffer{}, "", err
}
}
case []map[string]interface{}:
for _, val := range slice {
encodeStr, err := json.Marshal(val)
if err != nil {
return &bytes.Buffer{}, "", err
}
err = writer.WriteField(trimString(types.Field(i)), string(encodeStr))
if err != nil {
return &bytes.Buffer{}, "", err
}
}
default:
return &bytes.Buffer{}, "", fmt.Errorf("unsupported slice type:%T", slice)
}
continue
}

@ -78,7 +78,7 @@ func (bdc *BVSDecortClient) DecortApiCall(ctx context.Context, method, url strin
body := bytes.NewBufferString(values.Encode())
req, err := http.NewRequestWithContext(ctx, method, bdc.decortURL+constants.Restmachine+url, body)
req, err := http.NewRequestWithContext(ctx, method, bdc.decortURL+constants.RESTMACHINE+url, body)
if err != nil {
return nil, err
}
@ -128,7 +128,7 @@ func (bdc *BVSDecortClient) DecortApiCallMP(ctx context.Context, method, url str
return nil, err
}
req, err := http.NewRequestWithContext(ctx, method, bdc.decortURL+constants.Restmachine+url, body)
req, err := http.NewRequestWithContext(ctx, method, bdc.decortURL+constants.RESTMACHINE+url, body)
if err != nil {
return nil, err
}

@ -5,6 +5,7 @@ go 1.20
require (
github.com/go-playground/validator/v10 v10.11.2
github.com/google/go-querystring v1.1.0
github.com/joho/godotenv v1.5.1
gopkg.in/yaml.v3 v3.0.1
)

@ -13,6 +13,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=

@ -0,0 +1,7 @@
package interfaces
// Interface to valiate RAM values
type RequestWithRAM interface {
// GetRAM returns RAM values
GetRAM() map[string]uint64
}

@ -1,6 +1,11 @@
package constants
const Restmachine = "/restmachine"
const (
RESTMACHINE = "/restmachine"
// RAM_DIVISIBILITY sets divisibility of RAM value
RAM_DIVISIBILITY uint64 = 128
)
var FileName = map[string]string{
"OidcCertificate": "ca.crt",

@ -1,31 +1,35 @@
package validators
import (
"errors"
"fmt"
"regexp"
"strings"
"github.com/go-playground/validator/v10"
"repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/multierror"
)
// computeDriverValidator is used to validate Driver field in kvmx86/kvmppc create.
func computeDriverValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, computeDriverValues)
return IsInSlice(fieldValue, computeDriverValues)
}
// protoValidator is used to validate Proto fields.
func protoValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, protoValues)
return IsInSlice(fieldValue, protoValues)
}
// accessTypeValidator is used to validate AccessType fields.
func accessTypeValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, accessTypeValues)
return IsInSlice(fieldValue, accessTypeValues)
}
// resTypesValidator is used to validate ResTypes fields.
@ -36,7 +40,7 @@ func resTypesValidator(fe validator.FieldLevel) bool {
}
for _, value := range fieldSlice {
if !StringInSlice(value, resTypesValues) {
if !IsInSlice(value, resTypesValues) {
return false
}
}
@ -48,56 +52,56 @@ func resTypesValidator(fe validator.FieldLevel) bool {
func driverValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, driverValues)
return IsInSlice(fieldValue, driverValues)
}
// accountCUTypeValidator is used to validate CUType field.
func accountCUTypeValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, accountCUTypeValues)
return IsInSlice(fieldValue, accountCUTypeValues)
}
// bserviceModeValidator is used to validate Mode field.
func bserviceModeValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, bserviceModeValues)
return IsInSlice(fieldValue, bserviceModeValues)
}
// computeTopologyValidator is used to validate Topology field.
func computeTopologyValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, computeTopologyValues)
return IsInSlice(fieldValue, computeTopologyValues)
}
// computePolicyValidator is used to validate Policy field.
func computePolicyValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, computePolicyValues)
return IsInSlice(fieldValue, computePolicyValues)
}
// computeModeValidator is used to validate Mode field.
func computeModeValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, computeModeValues)
return IsInSlice(fieldValue, computeModeValues)
}
// computeDiskTypeValidator is used to validate DiskType field.
func computeDiskTypeValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, computeDiskTypeValues)
return IsInSlice(fieldValue, computeDiskTypeValues)
}
// computeNetTypeValidator is used to validate NetType field.
func computeNetTypeValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, computeNetTypeValues)
return IsInSlice(fieldValue, computeNetTypeValues)
}
// computeOrderValidator is used to validate Order field.
@ -108,7 +112,7 @@ func computeOrderValidator(fe validator.FieldLevel) bool {
}
for _, value := range fieldSlice {
if !StringInSlice(value, computeOrderValues) {
if !IsInSlice(value, computeOrderValues) {
return false
}
}
@ -120,70 +124,70 @@ func computeOrderValidator(fe validator.FieldLevel) bool {
func computeDataDisksValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, computeDataDisksValues)
return IsInSlice(fieldValue, computeDataDisksValues)
}
// diskTypeValidator is used to validate Type field.
func diskTypeValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, diskTypeValues)
return IsInSlice(fieldValue, diskTypeValues)
}
// flipgroupClientTypeValidator is used to validate ClientType field.
func flipgroupClientTypeValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, flipgroupClientTypeValues)
return IsInSlice(fieldValue, flipgroupClientTypeValues)
}
// kvmNetTypeValidator is used to validate NetType field.
func kvmNetTypeValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, kvmNetTypeValues)
return IsInSlice(fieldValue, kvmNetTypeValues)
}
// lbAlgorithmValidator is used to validate Algorithm field.
func lbAlgorithmValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, lbAlgorithmValues)
return IsInSlice(fieldValue, lbAlgorithmValues)
}
// rgDefNetValidator is used to validate DefNet field.
func rgDefNetValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, rgDefNetValues)
return IsInSlice(fieldValue, rgDefNetValues)
}
// rgNetTypeValidator is used to validate NetType field.
func rgNetTypeValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, rgNetTypeValues)
return IsInSlice(fieldValue, rgNetTypeValues)
}
// vinsTypeValidator is used to validate Type field.
func vinsTypeValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, vinsTypeValues)
return IsInSlice(fieldValue, vinsTypeValues)
}
// imageBootTypeValidator is used to validate BootType field.
func imageBootTypeValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, imageBootTypeValues)
return IsInSlice(fieldValue, imageBootTypeValues)
}
// imageTypeValidator is used to validate ImageType field.
func imageTypeValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, imageTypeValues)
return IsInSlice(fieldValue, imageTypeValues)
}
// imageDriversValidator is used to validate Drivers field.
@ -194,7 +198,7 @@ func imageDriversValidator(fe validator.FieldLevel) bool {
}
for _, item := range fieldSlice {
if !StringInSlice(item, imageDriversValues) {
if !IsInSlice(item, imageDriversValues) {
return false
}
}
@ -206,14 +210,14 @@ func imageDriversValidator(fe validator.FieldLevel) bool {
func imageArchitectureValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, imageArchitectureValues)
return IsInSlice(fieldValue, imageArchitectureValues)
}
// sepFieldTypeValidator is used to validate FieldType field.
func sepFieldTypeValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return StringInSlice(fieldValue, sepFieldTypeValues)
return IsInSlice(fieldValue, sepFieldTypeValues)
}
// hwPathValidator is used to validate HWPath field.
@ -230,7 +234,7 @@ func networkPluginValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
fieldValue = strings.ToLower(fieldValue)
return StringInSlice(fieldValue, networkPluginValues)
return IsInSlice(fieldValue, networkPluginValues)
}
// networkPluginsValidator is used to validate NetworkPlugins field
@ -243,7 +247,7 @@ func networkPluginsValidator(fe validator.FieldLevel) bool {
for _, item := range fieldSlice {
item = strings.ToLower(item)
if !StringInSlice(item, networkPluginValues) {
if !IsInSlice(item, networkPluginValues) {
return false
}
}
@ -255,14 +259,14 @@ func interfaceStateValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
fieldValue = strings.ToLower(fieldValue)
return StringInSlice(fieldValue, interfaceStateValues)
return IsInSlice(fieldValue, interfaceStateValues)
}
func strictLooseValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
fieldValue = strings.ToLower(fieldValue)
return StringInSlice(fieldValue, strictLooseValues)
return IsInSlice(fieldValue, strictLooseValues)
}
// name workerGroup must be more 3 symbol
@ -272,3 +276,60 @@ func workerGroupNameValidator(fe validator.FieldLevel) bool {
return len(fieldValue) >= 3
}
func sortByValidator(fe validator.FieldLevel) bool {
sortByRegexp := regexp.MustCompile(`^[+-][a-zA-Z_]+`)
return sortByRegexp.MatchString(fe.Field().String())
}
func actionValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return IsInSlice(fieldValue, actionValues)
}
func vmActionValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return IsInSlice(fieldValue, vmActionValues)
}
func computeFeaturesValidator(fe validator.FieldLevel) bool {
field := fe.Field()
slice, ok := field.Interface().([]string)
if !ok {
return false
}
return IsSubSlice(slice, computeFeaturesValues)
}
func networkInterfaceNamingValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
return IsInSlice(fieldValue, networkInterfaceNamingValues)
}
// ValidateRAM checks if request contains RAM value that is positive integer divisible by divisibility passed.
// It is recommended to pass constants.RAM_DIVISIBILITY as divisility arguement
func ValidateRAM(r interfaces.RequestWithRAM, divisibility uint64) error {
if divisibility == 0 {
return errors.New("second argument of ValidateRAM should be greater than 0")
}
mapRAM := r.GetRAM()
errs := make([]error, 0, len(mapRAM))
for k, v := range mapRAM {
if v%divisibility != 0 {
errs = append(errs, fmt.Errorf("expected value of %s: \"%d\" should be divisible by %d", k, v, divisibility))
}
}
return multierror.Join(errs...)
}

@ -34,7 +34,7 @@ func GetErrors(err error) validator.ValidationErrors {
return err.(validator.ValidationErrors)
}
func StringInSlice(str string, target []string) bool {
func IsInSlice(str string, target []string) bool {
for _, v := range target {
if v == str {
return true
@ -42,3 +42,12 @@ func StringInSlice(str string, target []string) bool {
}
return false
}
func IsSubSlice(source []string, target []string) bool {
for _, s := range source {
if !IsInSlice(s, target) {
return false
}
}
return true
}

@ -229,6 +229,35 @@ func errorMessage(fe validator.FieldError) string {
prefix,
fe.Field(),
joinValues(interfaceStateValues))
case "sortBy":
return fmt.Sprintf("%s %s must be in format +|-(field)",
prefix,
fe.Field())
case "action":
return fmt.Sprintf("%s %s must be one of the following: %s",
prefix,
fe.Field(),
joinValues(actionValues))
case "vmaction":
return fmt.Sprintf("%s %s must be one of the following: %s",
prefix,
fe.Field(),
joinValues(vmActionValues))
case "computeFeatures":
return fmt.Sprintf("%s %s must be one of the following: %s",
prefix,
fe.Field(),
joinValues(computeFeaturesValues))
case "networkInterfaceNaming":
return fmt.Sprintf("%s %s must be one of the following: %s",
prefix,
fe.Field(),
joinValues(networkInterfaceNamingValues))
}
return fe.Error()

@ -25,6 +25,7 @@ func getDecortValidator() *validator.Validate {
// registerAllValidators registers all custom validators in DecortValidator.
func registerAllValidators(validate *validator.Validate) error {
err := validate.RegisterValidation("proto", protoValidator)
if err != nil {
return err
@ -185,5 +186,30 @@ func registerAllValidators(validate *validator.Validate) error {
return err
}
err = validate.RegisterValidation("sortBy", sortByValidator)
if err != nil {
return err
}
err = validate.RegisterValidation("action", actionValidator)
if err != nil {
return err
}
err = validate.RegisterValidation("vmaction", vmActionValidator)
if err != nil {
return err
}
err = validate.RegisterValidation("computeFeatures", computeFeaturesValidator)
if err != nil {
return err
}
err = validate.RegisterValidation("networkInterfaceNaming", networkInterfaceNamingValidator)
if err != nil {
return err
}
return nil
}

@ -44,4 +44,12 @@ var (
strictLooseValues = []string{"strict", "loose"}
interfaceStateValues = []string{"on", "off"}
actionValues = []string{"power_on", "shutdown", "force_shutdown", "reboot"}
vmActionValues = []string{"stop", "move"}
computeFeaturesValues = []string{"hugepages", "numa", "cpupin", "vfnic"}
networkInterfaceNamingValues = []string{"eth", "ens"}
)

@ -80,7 +80,7 @@ func (ldc *LegacyDecortClient) DecortApiCall(ctx context.Context, method, url st
body := bytes.NewBufferString(values.Encode() + fmt.Sprintf("&authkey=%s", ldc.cfg.Token))
req, err := http.NewRequestWithContext(ctx, method, ldc.decortURL+constants.Restmachine+url, body)
req, err := http.NewRequestWithContext(ctx, method, ldc.decortURL+constants.RESTMACHINE+url, body)
if err != nil {
return nil, err
}
@ -100,7 +100,7 @@ func (ldc *LegacyDecortClient) DecortApiCallMP(ctx context.Context, method, url
return nil, err
}
req, err := http.NewRequestWithContext(ctx, method, ldc.decortURL+constants.Restmachine+url, body)
req, err := http.NewRequestWithContext(ctx, method, ldc.decortURL+constants.RESTMACHINE+url, body)
if err != nil {
return nil, err
}
@ -132,7 +132,7 @@ func (ldc *LegacyDecortClient) getToken(ctx context.Context) error {
body := fmt.Sprintf("username=%s&password=%s", url.QueryEscape(ldc.cfg.Username), url.QueryEscape(ldc.cfg.Password))
bodyReader := strings.NewReader(body)
req, _ := http.NewRequestWithContext(ctx, "POST", ldc.cfg.DecortURL+"/restmachine/cloudapi/user/authenticate", bodyReader)
req, _ := http.NewRequestWithContext(ctx, "POST", ldc.cfg.DecortURL+constants.RESTMACHINE+"/cloudapi/user/authenticate", bodyReader)
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
// request token

@ -15,11 +15,11 @@ type GetConsumptionRequest struct {
// Epoch represents the start time
// Required: true
Start uint64 `url:"start" json:"start" validate:"required"`
Start float64 `url:"start" json:"start" validate:"required"`
// Epoch represents the end time
// Required: true
End uint64 `url:"end" json:"end" validate:"required"`
End float64 `url:"end" json:"end" validate:"required"`
}
// GetConsumption downloads the resources tracking files for an account within a given period

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get list of accounts
@ -24,6 +26,10 @@ type ListRequest struct {
// Required: false
Status string `url:"status,omitempty" json:"status,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -35,6 +41,7 @@ type ListRequest struct {
// List gets a list of all accounts the user has access to a ListAccounts struct
func (a Account) List(ctx context.Context, req ListRequest) (*ListAccounts, error) {
res, err := a.ListRaw(ctx, req)
if err != nil {
return nil, err
@ -52,6 +59,11 @@ func (a Account) List(ctx context.Context, req ListRequest) (*ListAccounts, erro
// ListRaw gets a list of all accounts the user has access to as an array of bytes
func (a Account) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/account/list"
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -46,6 +46,10 @@ type ListComputesRequest struct {
// Required: false
ExtNetID uint64 `url:"extNetId,omitempty" json:"extNetId,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -57,6 +61,7 @@ type ListComputesRequest struct {
// ListComputes gets list all compute instances under specified account, accessible by the user
func (a Account) ListComputes(ctx context.Context, req ListComputesRequest) (*ListComputes, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListDeletedRequest struct to get a list of deleted accounts
@ -27,10 +29,20 @@ type ListDeletedRequest struct {
// Find by access control list
// Required: false
ACL string `url:"acl,omitempty" json:"acl,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
}
// ListDeleted gets list of all deleted accounts the user has access to
func (a Account) ListDeleted(ctx context.Context, req ListDeletedRequest) (*ListAccounts, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/account/listDeleted"
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -30,6 +30,10 @@ type ListDisksRequest struct {
// Required: false
Type string `url:"type,omitempty" json:"type,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -41,6 +45,7 @@ type ListDisksRequest struct {
// ListDisks gets list all currently unattached disks under specified account
func (a Account) ListDisks(ctx context.Context, req ListDisksRequest) (*ListDisks, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))

@ -49,6 +49,7 @@ type ListFLIPGroupsRequest struct {
// ListFLIPGroups gets list all FLIPGroups under specified account, accessible by the user
func (a Account) ListFLIPGroups(ctx context.Context, req ListFLIPGroupsRequest) (*ListFLIPGroups, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))

@ -41,10 +41,15 @@ type ListRGRequest struct {
// Find by status
// Required: false
Status string `url:"status,omitempty" json:"status,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
}
// ListRG gets list of all resource groups under specified account, accessible by the user
func (a Account) ListRG(ctx context.Context, req ListRGRequest) (*ListRG, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))

@ -30,6 +30,10 @@ type ListTemplatesRequest struct {
// Required: false
Type string `url:"type,omitempty" json:"type,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -41,6 +45,7 @@ type ListTemplatesRequest struct {
// ListTemplates gets list of templates which can be managed by this account
func (a Account) ListTemplates(ctx context.Context, req ListTemplatesRequest) (*ListTemplates, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))

@ -30,6 +30,10 @@ type ListVINSRequest struct {
// Required: false
ExtIP string `url:"extIp,omitempty" json:"extIp,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -41,6 +45,7 @@ type ListVINSRequest struct {
// ListVINS gets list of all ViNSes under specified account, accessible by the user
func (a Account) ListVINS(ctx context.Context, req ListVINSRequest) (*ListVINS, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))

@ -53,6 +53,9 @@ type ItemAccount struct {
// Access Control List
ACL []RecordACL `json:"acl"`
// Compute Features
ComputeFeatures []string `json:"computeFeatures"`
// Created time
CreatedTime uint64 `json:"createdTime"`
@ -176,6 +179,9 @@ type RecordAccount struct {
// Company URL
CompanyURL string `json:"companyurl"`
// Compute Features
ComputeFeatures []string `json:"computeFeatures"`
// Computes
Computes Computes `json:"computes"`
@ -374,6 +380,12 @@ type ItemVINS struct {
// External IP
ExternalIP string `json:"externalIP"`
// Extnet ID
ExtnetId uint64 `json:"extnetId"`
// Free IPs
FreeIPs uint64 `json:"freeIPs"`
// ID
ID uint64 `json:"id"`

@ -74,6 +74,16 @@ type GroupAddRequest struct {
UserData string `url:"userData,omitempty" json:"userData,omitempty"`
}
// GetRAM returns RAM field values
func (r GroupAddRequest) GetRAM() map[string]uint64 {
res := make(map[string]uint64, 1)
res["RAM"] = r.RAM
return res
}
// GroupAdd creates new Compute Group within BasicService.
// Compute Group is NOT started automatically,
// so you need to explicitly start it

@ -43,6 +43,16 @@ type GroupUpdateRequest struct {
Force bool `url:"force,omitempty" json:"force,omitempty"`
}
// GetRAM returns RAM field values
func (r GroupUpdateRequest) GetRAM() map[string]uint64 {
res := make(map[string]uint64, 1)
res["RAM"] = r.RAM
return res
}
// GroupUpdate updates existing Compute group within Basic Service and apply new settings to its computes as necessary
func (b BService) GroupUpdate(ctx context.Context, req GroupUpdateRequest) (bool, error) {
err := validators.ValidateRequest(req)

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get list of BasicService instances
@ -40,6 +42,10 @@ type ListRequest struct {
// Required: false
AccountName string `url:"accountName,omitempty" json:"accountName,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -51,6 +57,7 @@ type ListRequest struct {
// List gets list of BasicService instances associated with the specified Resource Group as a ListBasicServices struct
func (b BService) List(ctx context.Context, req ListRequest) (*ListBasicServices, error) {
res, err := b.ListRaw(ctx, req)
if err != nil {
return nil, err
@ -68,6 +75,11 @@ func (b BService) List(ctx context.Context, req ListRequest) (*ListBasicServices
// ListRaw gets list of BasicService instances associated with the specified Resource Group as an array of bytes
func (b BService) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/bservice/list"
res, err := b.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListDeletedRequest struct to get list of deleted BasicService instances
@ -16,6 +18,10 @@ type ListDeletedRequest struct {
// Required: false
RGID uint64 `url:"rgId,omitempty" json:"rgId,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -27,6 +33,11 @@ type ListDeletedRequest struct {
// ListDeleted gets list of deleted BasicService instances associated with the specified Resource Group
func (b BService) ListDeleted(ctx context.Context, req ListDeletedRequest) (*ListBasicServices, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/bservice/listDeleted"
res, err := b.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -39,6 +39,7 @@ type AffinityRuleAddRequest struct {
// Value that must match the key to be taken into account when analyzing this rule
// Required: false
// Not required on purpose: despite required tag on platform, empty string is allowed
Value string `url:"value" json:"value"`
}

@ -39,6 +39,7 @@ type AffinityRuleRemoveRequest struct {
// Value that must match the key to be taken into account when analyzing this rule
// Required: false
// Not required on purpose: despite required tag on platform, empty string is allowed
Value string `url:"value" json:"value"`
}

@ -39,6 +39,7 @@ type AntiAffinityRuleAddRequest struct {
// Value that must match the key to be taken into account when analyzing this rule
// Required: false
// Not required on purpose: despite required tag on platform, empty string is allowed
Value string `url:"value" json:"value"`
}

@ -39,6 +39,7 @@ type AntiAffinityRuleRemoveRequest struct {
// Value that must match the key to be taken into account when analyzing this rule
// Required: false
// Not required on purpose: despite required tag on platform, empty string is allowed
Value string `url:"value" json:"value"`
}

@ -0,0 +1,42 @@
package compute
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// BootDiskSetRequest struct to set boot disk for compute
type BootDiskSetRequest struct {
// ID of compute instance
// Required: true
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
// ID of the disk to set as boot
// Required: true
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
}
// BootDiskSet sets boot disk for compute
func (c Compute) BootDiskSet(ctx context.Context, req BootDiskSetRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
return false, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/compute/bootDiskSet"
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
}

@ -0,0 +1,112 @@
package compute
import (
"context"
"net/http"
"strconv"
"strings"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// CreateTemplateFromBlankRequest struct to create template from boot disk of current compute
type CreateTemplateFromBlankRequest struct {
// ID of the compute to create template from
// Required: true
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
// Name of the rescue disk
// Required: true
Name string `url:"name" json:"name" validate:"required"`
// Boot type of image BIOS or UEFI
// Required: true
BootType string `url:"boottype" json:"boottype" validate:"imageBootType"`
// Image type linux, windows or other
// Required: true
ImageType string `url:"imagetype" json:"imagetype" validate:"imageType"`
// Username for the image
// Required: false
Username string `url:"username,omitempty" json:"username,omitempty"`
// Password for the image
// Required: false
Password string `url:"password,omitempty" json:"password,omitempty"`
// Account ID to make the image exclusive
// Required: false
AccountID uint64 `url:"accountId,omitempty" json:"accountId,omitempty"`
// SEP ID
// Required: false
SepID uint64 `url:"sepId,omitempty" json:"sepId,omitempty"`
// Pool for image create
// Required: false
PoolName string `url:"poolName,omitempty" json:"poolName,omitempty"`
// Does this machine supports hot resize
// Default: false
// Required: false
HotResize bool `url:"hotresize" json:"hotresize"`
}
type wrapperCreateTemplateFromBlankRequest struct {
CreateTemplateFromBlankRequest
AsyncMode bool `url:"asyncMode"`
}
// CreateTemplateFromBlank creates template from boot disk of current compute in sync mode.
// It returns id of created compute and error.
func (c Compute) CreateTemplateFromBlank(ctx context.Context, req CreateTemplateFromBlankRequest) (uint64, error) {
err := validators.ValidateRequest(req)
if err != nil {
return 0, validators.ValidationErrors(validators.GetErrors(err))
}
reqWrapped := wrapperCreateTemplateFromBlankRequest{
CreateTemplateFromBlankRequest: req,
AsyncMode: false,
}
url := "/cloudapi/compute/createTemplateFromBlank"
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
if err != nil {
return 0, err
}
result, err := strconv.ParseUint(string(res), 10, 64)
if err != nil {
return 0, err
}
return result, nil
}
// CreateTemplateFromBlankAsync creates template from boot disk of current compute in async mode.
// It returns guid of task and error.
func (c Compute) CreateTemplateFromBlankAsync(ctx context.Context, req CreateTemplateFromBlankRequest) (string, error) {
err := validators.ValidateRequest(req)
if err != nil {
return "", validators.ValidationErrors(validators.GetErrors(err))
}
reqWrapped := wrapperCreateTemplateFromBlankRequest{
CreateTemplateFromBlankRequest: req,
AsyncMode: true,
}
url := "/cloudapi/compute/createTemplateFromBlank"
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
if err != nil {
return "", err
}
result := strings.ReplaceAll(string(res), "\"", "")
return result, nil
}

@ -0,0 +1,53 @@
package compute
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// DiskMigrateRequest struct to migrate compute's disk to target disk
type DiskMigrateRequest struct {
// ID of compute instance
// Required: true
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
// ID source disk
// Required: true
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
// ID target disk
// Required: true
TargetDiskID uint64 `url:"targetDiskId" json:"targetDiskId" validate:"required"`
// Migration mode. 1 - Data migration and domain update were already completed by third-party software.
// Use this if target disk already connected to compute and you only need to save changes for next reboot.
// Required: true
Mode int64 `url:"mode" json:"mode" validate:"required"`
}
// DiskMigrate - migrate compute's disk to target disk. Source disk will be detached, target disk will be attached to the same PCI slot.
// (WARNING) Current realisation is limited. No actual data migration will be performed.
// Use this API if target disk already connected to compute and you only need to save changes for next reboot (mode: 1).
func (c Compute) DiskMigrate(ctx context.Context, req DiskMigrateRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
return false, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/compute/diskMigrate"
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
}

@ -0,0 +1,46 @@
package compute
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// DiskSwitchToReplicationRequest struct to switch disk to it's replication
type DiskSwitchToReplicationRequest struct {
// ID of compute instance
// Required: true
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
// ID of the disk to switch
// Required: true
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
// Delete replication relationship
// Required: false
StopReplication bool `url:"stopReplication" json:"stopReplication"`
}
// DiskSwitchToReplication switches disk to it's replication
func (c Compute) DiskSwitchToReplication(ctx context.Context, req DiskSwitchToReplicationRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
return false, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/compute/diskSwitchToReplication"
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
}

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get list of available computes
@ -52,6 +54,10 @@ type ListRequest struct {
// Required: false
IncludeDeleted bool `url:"includedeleted,omitempty" json:"includedeleted,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -64,6 +70,7 @@ type ListRequest struct {
// List gets list of the available computes.
// Filtering based on status is possible
func (c Compute) List(ctx context.Context, req ListRequest) (*ListComputes, error) {
res, err := c.ListRaw(ctx, req)
if err != nil {
return nil, err
@ -81,6 +88,11 @@ func (c Compute) List(ctx context.Context, req ListRequest) (*ListComputes, erro
// ListRaw gets list of the available computes.
func (c Compute) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/compute/list"
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListDeletedRequest struct to get deleted computes list
@ -44,6 +46,10 @@ type ListDeletedRequest struct {
// Required: false
ExtNetID uint64 `url:"extNetId,omitempty" json:"extNetId,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -55,6 +61,11 @@ type ListDeletedRequest struct {
// ListDeleted gets list all deleted computes
func (c Compute) ListDeleted(ctx context.Context, req ListDeletedRequest) (*ListComputes, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/compute/listDeleted"
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -30,6 +30,10 @@ type ListPCIDeviceRequest struct {
// Required: false
Status string `url:"status,omitempty" json:"status,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -41,6 +45,7 @@ type ListPCIDeviceRequest struct {
// ListPCIDevice gets list PCI device
func (c Compute) ListPCIDevice(ctx context.Context, req ListPCIDeviceRequest) (*ListPCIDevices, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))

@ -26,6 +26,10 @@ type ListVGPURequest struct {
// Required: false
Status string `url:"status,omitempty" json:"status,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -41,6 +45,7 @@ type ListVGPURequest struct {
// ListVGPU gets list vGPU
func (c Compute) ListVGPU(ctx context.Context, req ListVGPURequest) (*ListVGPUs, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))

@ -305,6 +305,9 @@ type RecordCompute struct {
// Boot disk size
BootDiskSize uint64 `json:"bootdiskSize"`
// cd Image Id
CdImageId uint64 `json:"cdImageId"`
// Clone reference
CloneReference uint64 `json:"cloneReference"`
@ -314,6 +317,9 @@ type RecordCompute struct {
// Compute CI ID
ComputeCIID uint64 `json:"computeciId"`
// CPU Pin
CPUPin bool `json:"cpupin"`
// Number of cores
CPU uint64 `json:"cpus"`
@ -350,6 +356,9 @@ type RecordCompute struct {
// GUID
GUID uint64 `json:"guid"`
// HPBacked
HPBacked bool `json:"hpBacked"`
// ID
ID uint64 `json:"id"`
@ -383,6 +392,12 @@ type RecordCompute struct {
// NeedReboot
NeedReboot bool `json:"needReboot"`
// Numa Affinity
NumaAffinity string `json:"numaAffinity"`
//NumaNodeId
NumaNodeId int64 `json:"numaNodeId"`
// Natable VINS ID
NatableVINSID uint64 `json:"natableVinsId"`
@ -539,6 +554,9 @@ type ItemVNFInterface struct {
// Network type
NetType string `json:"netType"`
// NodeID
NodeID int64 `json:"nodeId"`
// PCI slot
PCISlot int64 `json:"pciSlot"`
@ -654,6 +672,9 @@ type ItemComputeDisk struct {
// Reality device number
RealityDeviceNumber uint64 `json:"realityDeviceNumber"`
// Replication
Replication interface{} `json:"replication"`
// Resource ID
ResID string `json:"resId"`
@ -761,6 +782,7 @@ type IOTune struct {
type ItemCompute struct {
// Access Control List
ACL ListACL `json:"acl"`
// Account ID
AccountID uint64 `json:"accountId"`
@ -788,6 +810,9 @@ type ItemCompute struct {
// Boot disk size
BootDiskSize uint64 `json:"bootdiskSize"`
// cd Image Id
CdImageId uint64 `json:"cdImageId"`
// Clone reference
CloneReference uint64 `json:"cloneReference"`
@ -797,6 +822,9 @@ type ItemCompute struct {
// Compute CI ID
ComputeCIID uint64 `json:"computeciId"`
// CPU Pin
CPUPin bool `json:"cpupin"`
// Number of cores
CPU uint64 `json:"cpus"`
@ -833,6 +861,9 @@ type ItemCompute struct {
// GUID
GUID uint64 `json:"guid"`
// HPBacked
HPBacked bool `json:"hpBacked"`
// ID
ID uint64 `json:"id"`
@ -863,6 +894,12 @@ type ItemCompute struct {
// NeedReboot
NeedReboot bool `json:"needReboot"`
// Numa Affinity
NumaAffinity string `json:"numaAffinity"`
//NumaNodeId
NumaNodeId int64 `json:"numaNodeId"`
// Pinned or not
Pinned bool `json:"pinned"`
@ -948,17 +985,106 @@ type ListComputes struct {
// List VGPUs
type ListVGPUs struct {
// Data
Data []interface{} `json:"data"`
Data []ItemVGPU `json:"data"`
// Entry count
EntryCount uint64 `json:"entryCount"`
}
// Main information about vgpu device
type ItemVGPU struct {
// Account ID
AccountID uint64 `json:"accountId"`
// Created Time
CreatedTime uint64 `json:"createdTime"`
// Deleted Time
DeletedTime uint64 `json:"deletedTime"`
// GID
GID uint64 `json:"gid"`
// GUID
GUID uint64 `json:"guid"`
// ID
ID uint64 `json:"id"`
// Last Claimed By
LastClaimedBy uint64 `json:"lastClaimedBy"`
// Last Update Time
LastUpdateTime uint64 `json:"lastUpdateTime"`
// Mode
Mode string `json:"mode"`
// PCI Slot
PCISlot uint64 `json:"pciSlot"`
// PGPUID
PGPUID uint64 `json:"pgpuid"`
// Profile ID
ProfileID uint64 `json:"profileId"`
// RAM
RAM uint64 `json:"ram"`
// Reference ID
ReferenceID string `json:"referenceId"`
// RG ID
RGID uint64 `json:"rgId"`
// Status
Status string `json:"status"`
// Type
Type string `json:"type"`
// VM ID
VMID uint64 `json:"vmid"`
}
// Main information about PCI device
type ItemPCIDevice struct {
// Compute ID
ComputeID uint64 `json:"computeId"`
// Description
Description string `json:"description"`
// GUID
GUID uint64 `json:"guid"`
// HwPath
HwPath string `json:"hwPath"`
// ID
ID uint64 `json:"id"`
// Name
Name string `json:"name"`
// Resource group ID
RGID uint64 `json:"rgId"`
// Stack ID
StackID uint64 `json:"stackId"`
// Status
Status string `json:"status"`
// System name
SystemName string `json:"systemName"`
}
// List PCI devices
type ListPCIDevices struct {
// Data
Data []interface{} `json:"data"`
Data []ItemPCIDevice `json:"data"`
// Entry count
EntryCount uint64 `json:"entryCount"`
}

@ -24,8 +24,8 @@ type PFWAddRequest struct {
PublicPortEnd int64 `url:"publicPortEnd,omitempty" json:"publicPortEnd,omitempty"`
// Internal base port number
// Required: true
LocalBasePort uint64 `url:"localBasePort" json:"localBasePort" validate:"required"`
// Required: false
LocalBasePort uint64 `url:"localBasePort,omitempty" json:"localBasePort,omitempty"`
// Network protocol
// either "tcp" or "udp"

@ -29,6 +29,16 @@ type ResizeRequest struct {
Force bool `url:"force,omitempty" json:"force,omitempty"`
}
// GetRAM returns RAM field values
func (r ResizeRequest) GetRAM() map[string]uint64 {
res := make(map[string]uint64, 1)
res["RAM"] = r.RAM
return res
}
// Resize resizes compute instance
func (c Compute) Resize(ctx context.Context, req ResizeRequest) (bool, error) {
err := validators.ValidateRequest(req)

@ -0,0 +1,127 @@
package disks
import (
"context"
"net/http"
"strconv"
"strings"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// FromPlatformDiskRequest struct to create template from platform disk
type FromPlatformDiskRequest struct {
// ID of the disk
// Required: true
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
// Name of the rescue disk
// Required: true
Name string `url:"name" json:"name" validate:"required"`
// Boot type of image BIOS or UEFI
// Required: true
BootType string `url:"boottype" json:"boottype" validate:"imageBootType"`
// Image type linux, windows or other
// Required: true
ImageType string `url:"imagetype" json:"imagetype" validate:"imageType"`
// Binary architecture of this image
// Should be:
// - X86_64
// - PPC64_LE
// Required: true
Architecture string `url:"architecture" json:"architecture" validate:"imageArchitecture"`
// Username for the image
// Required: false
Username string `url:"username,omitempty" json:"username,omitempty"`
// Password for the image
// Required: false
Password string `url:"password,omitempty" json:"password,omitempty"`
// Account ID to make the image exclusive
// Required: false
AccountID uint64 `url:"accountId,omitempty" json:"accountId,omitempty"`
// SEP ID
// Required: false
SepID uint64 `url:"sepId,omitempty" json:"sepId,omitempty"`
// Pool for image create
// Required: false
PoolName string `url:"poolName,omitempty" json:"poolName,omitempty"`
// List of types of compute suitable for image
// Example: [ "KVM_X86" ]
// Required: false
Drivers []string `url:"drivers" json:"drivers" validate:"min=1,max=2,imageDrivers"`
// Does this machine supports hot resize
// Required: false
HotResize bool `url:"hotresize" json:"hotresize"`
// Bootable image
// Required: true
Bootable bool `url:"bootable" json:"bootable"`
}
type wrapperFromPlatformDiskRequest struct {
FromPlatformDiskRequest
AsyncMode bool `url:"asyncMode"`
}
// FromPlatformDisk creates template from platform disk in sync mode.
// It returns id of created disk and error.
func (d Disks) FromPlatformDisk(ctx context.Context, req FromPlatformDiskRequest) (uint64, error) {
err := validators.ValidateRequest(req)
if err != nil {
return 0, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/disks/fromPlatformDisk"
reqWrapped := wrapperFromPlatformDiskRequest{
FromPlatformDiskRequest: req,
AsyncMode: false,
}
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
if err != nil {
return 0, err
}
result, err := strconv.ParseUint(string(res), 10, 64)
if err != nil {
return 0, err
}
return result, nil
}
// FromPlatformDiskAsync creates template from platform disk in async mode.
// It returns guid of task and error.
func (d Disks) FromPlatformDiskAsync(ctx context.Context, req FromPlatformDiskRequest) (string, error) {
err := validators.ValidateRequest(req)
if err != nil {
return "", validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/disks/fromPlatformDisk"
reqWrapped := wrapperFromPlatformDiskRequest{
FromPlatformDiskRequest: req,
AsyncMode: true,
}
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
if err != nil {
return "", err
}
result := strings.ReplaceAll(string(res), "\"", "")
return result, nil
}

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get list of disks
@ -48,6 +50,10 @@ type ListRequest struct {
// Required: false
Pool string `url:"pool,omitempty" json:"pool,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -59,6 +65,7 @@ type ListRequest struct {
// List gets list of the created disks belonging to an account as a ListDisks struct
func (d Disks) List(ctx context.Context, req ListRequest) (*ListDisks, error) {
res, err := d.ListRaw(ctx, req)
if err != nil {
return nil, err
@ -76,6 +83,11 @@ func (d Disks) List(ctx context.Context, req ListRequest) (*ListDisks, error) {
// ListRaw gets list of the created disks belonging to an account as an array of bytes
func (d Disks) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/disks/list"
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListDeletedRequest struct to get list of deleted disks
@ -36,6 +38,10 @@ type ListDeletedRequest struct {
// Required: false
Type string `url:"type,omitempty" json:"type,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -47,6 +53,11 @@ type ListDeletedRequest struct {
// ListDeleted gets list the deleted disks belonging to an account
func (d Disks) ListDeleted(ctx context.Context, req ListDeletedRequest) (*ListDisks, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/disks/listDeleted"
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -4,13 +4,19 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListTypesRequest struct to get list types of disks
type ListTypesRequest struct {
// Show detailed disk types by seps
// Required: true
Detailed bool `url:"detailed" json:"detailed" validate:"required"`
Detailed bool `url:"detailed" json:"detailed"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
@ -23,6 +29,11 @@ type ListTypesRequest struct {
// ListTypes gets list defined disk types
func (d Disks) ListTypes(ctx context.Context, req ListTypesRequest) (*ListTypes, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/disks/listTypes"
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListUnattachedRequest struct to get list of unattached disk
@ -40,6 +42,10 @@ type ListUnattachedRequest struct {
// Required: false
Pool string `url:"pool,omitempty" json:"pool,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -51,6 +57,11 @@ type ListUnattachedRequest struct {
// ListUnattached gets list of unattached disks
func (d Disks) ListUnattached(ctx context.Context, req ListUnattachedRequest) (*ListDisksUnattached, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/disks/listUnattached"
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -74,6 +74,9 @@ type ItemDisk struct {
// Purge time
PurgeTime uint64 `json:"purgeTime"`
// Replication
Replication interface{} `json:"replication"`
// Resource ID
ResID string `json:"resId"`
@ -403,6 +406,9 @@ type RecordDisk struct {
// Purge time
PurgeTime uint64 `json:"purgeTime"`
// Replication
Replication interface{} `json:"replication"`
// Resource ID
ResID string `json:"resId"`

@ -0,0 +1,52 @@
package disks
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ReplicateRequest struct to create an empty disk in chosen SEP and pool combination.
type ReplicateRequest struct {
// Id of the disk to replicate. This disk will become master in replication
// Required: true
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
// Name of replica disk to create
// Required: true
Name string `url:"name" json:"name" validate:"required"`
// ID of SEP to create slave disk
// Required: true
SepID uint64 `url:"sepId" json:"sepId" validate:"required"`
// Pool name to create slave disk in
// Required: true
PoolName string `url:"poolName" json:"poolName" validate:"required"`
}
// 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) {
err := validators.ValidateRequest(req)
if err != nil {
return 0, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/disks/replicate"
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return 0, err
}
result, err := strconv.ParseUint(string(res), 10, 64)
if err != nil {
return 0, err
}
return result, nil
}

@ -0,0 +1,38 @@
package disks
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ReplicationResume struct to resume suspended replication
type ReplicationResumeRequest struct {
// Id of the disk
// Required: true
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
}
// ReplicationResume resume suspended replication
func (d Disks) ReplicationResume(ctx context.Context, req ReplicationResumeRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
return false, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/disks/replicationResume"
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
}

@ -0,0 +1,38 @@
package disks
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ReplicationReverseRequest struct to change role between disks replications
type ReplicationReverseRequest struct {
// Id of the disk
// Required: true
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
}
// ReplicationReverse change role between disks replications
func (d Disks) ReplicationReverse(ctx context.Context, req ReplicationReverseRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
return false, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/disks/replicationReverse"
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
}

@ -0,0 +1,43 @@
package disks
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ReplicationStartRequest struct to starts replication between two chosen disks
type ReplicationStartRequest struct {
// Id of the disk to replicate. Primary disk in replication
// Required: true
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
// ID of target disk. Secondary disk in replication
// Required: true
TargetDiskID uint64 `url:"targetDiskId" json:"targetDiskId" validate:"required"`
}
// ReplicationStart starts replication between two chosen disks. It's required for both disks to have same size to avoid replication conflicts
// Note: Source disk's SEP and target SEP supported only of TATLIN type.
func (d Disks) ReplicationStart(ctx context.Context, req ReplicationStartRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
return false, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/disks/replicationStart"
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
}

@ -0,0 +1,37 @@
package disks
import (
"context"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ReplicationStatusRequest struct to get replication status
type ReplicationStatusRequest struct {
// Id of the disk
// Required: true
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
}
// ReplicationStatus get replication status
func (d Disks) ReplicationStatus(ctx context.Context, req ReplicationStatusRequest) (interface{}, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/disks/replicationStatus"
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
// result, err := strconv.ParseBool(string(res))
// if err != nil {
// return nil, err
// }
return res, nil
}

@ -0,0 +1,38 @@
package disks
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ReplicationStopRequest struct to remove replication between disks completely
type ReplicationStopRequest struct {
// Id of the disk
// Required: true
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
}
// ReplicationStop remove replication between disks completely
func (d Disks) ReplicationStop(ctx context.Context, req ReplicationStopRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
return false, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/disks/replicationStop"
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
}

@ -0,0 +1,38 @@
package disks
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ReplicationSuspendRequest struct to pause replication with possibility to resume from pause moment
type ReplicationSuspendRequest struct {
// Id of the disk
// Required: true
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
}
// ReplicationSuspend pause replication with possibility to resume from pause moment
func (d Disks) ReplicationSuspend(ctx context.Context, req ReplicationSuspendRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
return false, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/disks/replicationSuspend"
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
}

@ -18,6 +18,14 @@ type SearchRequest struct {
// If false, then disks having one of the statuses are not listed
// Required: false
ShowAll bool `url:"show_all,omitempty" json:"show_all,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"`
}
// Search searches disks

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get list of external network
@ -36,6 +38,10 @@ type ListRequest struct {
// Required: false
Status string `url:"status,omitempty" json:"status,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -47,6 +53,7 @@ type ListRequest struct {
// List gets list of all available external networks as a ListExtNets struct
func (e ExtNet) List(ctx context.Context, req ListRequest) (*ListExtNets, error) {
res, err := e.ListRaw(ctx, req)
if err != nil {
return nil, err
@ -64,6 +71,11 @@ func (e ExtNet) List(ctx context.Context, req ListRequest) (*ListExtNets, error)
// ListRaw gets list of all available external networks as an array of bytes
func (e ExtNet) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/extnet/list"
res, err := e.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -22,6 +22,10 @@ type ListComputesRequest struct {
// Required: false
ComputeID uint64 `url:"computeId,omitempty" json:"computeId,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -33,6 +37,7 @@ type ListComputesRequest struct {
// ListComputes gets computes from account with extnets
func (e ExtNet) ListComputes(ctx context.Context, req ListComputesRequest) (*ListExtNetComputes, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get list of FLIPGroup available to the current user
@ -28,6 +30,10 @@ type ListRequest struct {
// Required: false
ByIP string `url:"byIp,omitempty" json:"byIp,omitempty"`
// Find by accountId
// Required: false
AccountId uint64 `url:"accountId,omitempty" json:"accountId,omitempty"`
// Find by resource group ID
// Required: false
RGID uint64 `url:"rgId,omitempty" json:"rgId,omitempty"`
@ -43,10 +49,23 @@ type ListRequest struct {
// Page size
// Required: false
Size uint64 `url:"size,omitempty" json:"size,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Find by connId
// Required: false
ConnId uint64 `url:"connId,omitempty" json:"connId,omitempty"`
// Find by status
// Required: false
Status string `url:"status,omitempty" json:"status,omitempty"`
}
// List gets list of FLIPGroup managed cluster instances available to the current user as a ListFLIPGroups struct
func (f FLIPGroup) List(ctx context.Context, req ListRequest) (*ListFLIPGroups, error) {
res, err := f.ListRaw(ctx, req)
if err != nil {
return nil, err
@ -64,6 +83,11 @@ func (f FLIPGroup) List(ctx context.Context, req ListRequest) (*ListFLIPGroups,
// ListRaw gets list of FLIPGroup managed cluster instances available to the current user as an array of bytes
func (f FLIPGroup) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/flipgroup/list"
res, err := f.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -18,10 +18,6 @@ type CreateRequest struct {
// Required: true
URL string `url:"url" json:"url" validate:"required,url"`
// Grid (platform) ID where this template should be create in
// Required: true
GID uint64 `url:"gid" json:"gid" validate:"required"`
// Boot type of image bios or UEFI
// Required: true
BootType string `url:"boottype" json:"boottype" validate:"required,imageBootType"`
@ -34,6 +30,17 @@ type CreateRequest struct {
// Required: true
ImageType string `url:"imagetype" json:"imagetype" validate:"required,imageType"`
// Account ID to make the image exclusive
// Required: true
AccountID uint64 `url:"accountId" json:"accountId" validate:"required"`
// Select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming
// Should be:
// - eth
// - ens (default value)
// Required: false
NetworkInterfaceNaming string `url:"networkInterfaceNaming,omitempty" json:"networkInterfaceNaming,omitempty" validate:"omitempty,networkInterfaceNaming"`
// Does this machine supports hot resize
// Required: false
HotResize bool `url:"hotresize,omitempty" json:"hotresize,omitempty"`
@ -46,10 +53,6 @@ type CreateRequest struct {
// Required: false
Password string `url:"password,omitempty" json:"password,omitempty"`
// Account ID to make the image exclusive
// Required: false
AccountID uint64 `url:"accountId,omitempty" json:"accountId,omitempty"`
// Username for upload binary media
// Required: false
UsernameDL string `url:"usernameDL,omitempty" json:"usernameDL,omitempty"`

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get list of available images
@ -56,6 +58,10 @@ type ListRequest struct {
// Required: false
Bootable bool `url:"bootable,omitempty" json:"bootable,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -67,6 +73,7 @@ type ListRequest struct {
// List gets list of available images as a ListImages struct, optionally filtering by account ID
func (i Image) List(ctx context.Context, req ListRequest) (*ListImages, error) {
res, err := i.ListRaw(ctx, req)
if err != nil {
return nil, err
@ -84,6 +91,11 @@ func (i Image) List(ctx context.Context, req ListRequest) (*ListImages, error) {
// ListRaw gets list of available images as an array of bytes
func (i Image) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/image/list"
res, err := i.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -35,6 +35,9 @@ type ItemImage struct {
// Name
Name string `json:"name"`
// NetworkInterfaceNaming
NetworkInterfaceNaming string `json:"networkInterfaceNaming"`
// Pool
Pool string `json:"pool"`
@ -104,6 +107,9 @@ type RecordImage struct {
// Bootable
Bootable bool `json:"bootable"`
// CdPresentedTo
CdPresentedTo interface{} `json:"cdPresentedTo"`
// ComputeCI ID
ComputeCIID uint64 `json:"computeciId"`
@ -146,6 +152,9 @@ type RecordImage struct {
// Name
Name string `json:"name"`
// NetworkInterfaceNaming
NetworkInterfaceNaming string `json:"networkInterfaceNaming"`
// Password
Password string `json:"password"`

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get list of information about images
@ -36,6 +38,10 @@ type ListRequest struct {
// Required: false
IncludeDisabled bool `url:"includeDisabled,omitempty" json:"includeDisabled,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -47,6 +53,7 @@ type ListRequest struct {
// List gets list of all k8ci catalog items available to the current user as a ListK8CI struct
func (k K8CI) List(ctx context.Context, req ListRequest) (*ListK8CI, error) {
res, err := k.ListRaw(ctx, req)
if err != nil {
return nil, err
@ -64,6 +71,11 @@ func (k K8CI) List(ctx context.Context, req ListRequest) (*ListK8CI, error) {
// ListRaw gets list of all k8ci catalog items available to the current user as an array of bytes
func (k K8CI) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/k8ci/list"
res, err := k.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -4,9 +4,11 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListDeletedRequest struct to get list information about deleted images
// ListDeletedRequest struct to get list information about deleted k8ci items
type ListDeletedRequest struct {
// Find by ID
// Required: false
@ -28,6 +30,10 @@ type ListDeletedRequest struct {
// Required: false
NetworkPlugins string `url:"netPlugins,omitempty" json:"netPlugins,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -39,6 +45,11 @@ type ListDeletedRequest struct {
// ListDeleted gets list all deleted k8ci catalog items available to the current user
func (k K8CI) ListDeleted(ctx context.Context, req ListDeletedRequest) (*ListK8CI, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/k8ci/listDeleted"
res, err := k.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -8,8 +8,6 @@ import (
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// type Params []string
// CreateRequest struct to create kubernetes cluster
type CreateRequest struct {
// Name of Kubernetes cluster
@ -74,7 +72,7 @@ type CreateRequest struct {
// Master node RAM volume in MB
// Required: false
MasterRAM uint `url:"masterRam,omitempty" json:"masterRam,omitempty"`
MasterRAM uint64 `url:"masterRam,omitempty" json:"masterRam,omitempty"`
// Master node boot disk size in GB If 0 is specified, size is defined by the OS image size
// Required: false
@ -90,7 +88,7 @@ type CreateRequest struct {
// Worker node RAM volume in MB
// Required: false
WorkerRAM uint `url:"workerRam,omitempty" json:"workerRam,omitempty"`
WorkerRAM uint64 `url:"workerRam,omitempty" json:"workerRam,omitempty"`
// Worker node boot disk size in GB. If 0 is specified, size is defined by the OS image size
// Required: false
@ -111,7 +109,7 @@ type CreateRequest struct {
// Custom sysctl values for Load Balancer instance. Applied on boot
// Required: false
LbSysctlParams string `url:"lbSysctlParams,omitempty" json:"lbSysctlParams,omitempty"`
LbSysctlParams []map[string]interface{} `url:"lbSysctlParams,omitempty" json:"lbSysctlParams,omitempty"`
// Use Highly Available schema for LB deploy
// Required: false
@ -166,10 +164,16 @@ type CreateRequest struct {
OidcCertificate string `url:"oidcCertificate,omitempty" json:"oidcCertificate,omitempty"`
}
// type wrapperCreateRequest struct {
// CreateRequest
// Params []string `url:"lbSysctlParams,omitempty"`
// }
// GetRAM returns RAM field values
func (r CreateRequest) GetRAM() map[string]uint64 {
res := make(map[string]uint64, 2)
res["MasterRAM"] = r.MasterRAM
res["WorkerRAM"] = r.WorkerRAM
return res
}
// Create creates a new Kubernetes cluster in the specified Resource Group
func (k8s K8S) Create(ctx context.Context, req CreateRequest) (string, error) {
@ -178,28 +182,6 @@ func (k8s K8S) Create(ctx context.Context, req CreateRequest) (string, error) {
return "", validators.ValidationErrors(validators.GetErrors(err))
}
// var params []string
// if len(req.LbSysctlParams) != 0 {
// params = make([]string, 0, len(req.LbSysctlParams))
// for r := range req.LbSysctlParams {
// b, err := json.Marshal(req.LbSysctlParams[r])
// if err != nil {
// return "", err
// }
// params = append(params, string(b))
// }
// } else {
// params = []string{"[]"}
// }
// reqWrapped := wrapperCreateRequest{
// CreateRequest: req,
// Params: params,
// }
url := "/cloudapi/k8s/create"
res, err := k8s.client.DecortApiCallMP(ctx, http.MethodPost, url, req)

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get list information K8S
@ -44,6 +46,10 @@ type ListRequest struct {
// Required: false
IncludeDeleted bool `url:"includedeleted,omitempty" json:"includedeleted,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -55,6 +61,7 @@ type ListRequest struct {
// List gets list of all kubernetes clusters the user has access to as a ListK8SClusters
func (k8s K8S) List(ctx context.Context, req ListRequest) (*ListK8SClusters, error) {
res, err := k8s.ListRaw(ctx, req)
if err != nil {
return nil, err
@ -72,6 +79,11 @@ func (k8s K8S) List(ctx context.Context, req ListRequest) (*ListK8SClusters, err
// ListRaw gets list of all kubernetes clusters the user has access to as an array of bytes
func (k8s K8S) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/k8s/list"
res, err := k8s.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListDeletedRequest struct to get list of deleted kubernetes cluster
@ -36,6 +38,10 @@ type ListDeletedRequest struct {
// Required: false
TechStatus string `url:"techStatus,omitempty" json:"techStatus,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -47,6 +53,11 @@ type ListDeletedRequest struct {
// ListDeleted gets all deleted kubernetes clusters the user has access to
func (k8s K8S) ListDeleted(ctx context.Context, req ListDeletedRequest) (*ListK8SClusters, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/k8s/listDeleted"
res, err := k8s.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -62,6 +62,16 @@ type WorkersGroupAddRequest struct {
UserData string `url:"userData,omitempty" json:"userData,omitempty"`
}
// GetRAM returns RAM field values
func (r WorkersGroupAddRequest) GetRAM() map[string]uint64 {
res := make(map[string]uint64, 1)
res["WorkerRAM"] = r.WorkerRAM
return res
}
// WorkersGroupAdd adds workers group to Kubernetes cluster
func (k8s K8S) WorkersGroupAdd(ctx context.Context, req WorkersGroupAddRequest) (uint64, error) {
err := validators.ValidateRequest(req)

@ -26,6 +26,35 @@ type Interface struct {
IPAddr string `url:"ipAddr,omitempty" json:"ipAddr,omitempty"`
}
// DataDisk detailed struct for DataDisks field in CreateRequest and CreateBlankRequest
type DataDisk struct {
// Name for disk
// Required: true
DiskName string `url:"diskName" json:"diskName" validate:"required"`
// Disk size in GB
// Required: true
Size uint64 `url:"size" json:"size" validate:"required"`
// Storage endpoint provider ID
// By default the same with boot disk
// Required: false
SepID uint64 `url:"sepId,omitempty" json:"sepId,omitempty"`
// Pool name
// By default will be chosen automatically
// Required: false
Pool string `url:"pool,omitempty" json:"pool,omitempty"`
// Optional description
// Required: false
Description string `url:"desc,omitempty" json:"desc,omitempty"`
// Specify image id for create disk from template
// Required: false
ImageID uint64 `url:"imageId,omitempty" json:"imageId,omitempty"`
}
// CreateRequest struct to create KVM PowerPC VM
type CreateRequest struct {
// ID of the resource group, which will own this VM
@ -63,6 +92,12 @@ type CreateRequest struct {
// Required: false
Pool string `url:"pool,omitempty" json:"pool,omitempty"`
// Slice of structs with data disk description. Each disk has parameters: required - diskName, size; optional - sepId, pool, desc and imageId.
// If not specified, compute will be created without disks.
// To create compute without disks, pass initialized empty slice .
// Required: false
DataDisks []DataDisk `url:"-" json:"dataDisks,omitempty" validate:"omitempty,dive"`
// Slice of structs with net interface description.
// If not specified, compute will be created with default interface from RG.
// To create compute without interfaces, pass initialized empty slice .
@ -90,9 +125,20 @@ type CreateRequest struct {
IPAType string `url:"ipaType,omitempty" json:"ipaType,omitempty"`
}
// GetRAM returns RAM field values
func (r CreateRequest) GetRAM() map[string]uint64 {
res := make(map[string]uint64, 1)
res["RAM"] = r.RAM
return res
}
type wrapperCreateRequest struct {
CreateRequest
Interfaces []string `url:"interfaces,omitempty"`
DataDisks []string `url:"dataDisks,omitempty"`
}
// Create creates KVM PowerPC VM based on specified OS image
@ -119,9 +165,25 @@ func (k KVMPPC) Create(ctx context.Context, req CreateRequest) (uint64, error) {
interfaces = []string{"[]"}
}
var dataDisks []string
if req.DataDisks != nil && len(req.DataDisks) != 0 {
dataDisks = make([]string, 0, len(req.DataDisks))
for i := range req.DataDisks {
b, err := json.Marshal(req.DataDisks[i])
if err != nil {
return 0, err
}
dataDisks = append(dataDisks, string(b))
}
}
reqWrapped := wrapperCreateRequest{
CreateRequest: req,
Interfaces: interfaces,
DataDisks: dataDisks,
}
url := "/cloudapi/kvmppc/create"

@ -41,6 +41,12 @@ type CreateBlankRequest struct {
// Required: true
Pool string `url:"pool" json:"pool" validate:"required"`
// Slice of structs with data disk description. Each disk has parameters: required - diskName, size; optional - sepId, pool, desc and imageId.
// If not specified, compute will be created without disks.
// To create compute without disks, pass initialized empty slice .
// Required: false
DataDisks []DataDisk `url:"-" json:"dataDisks,omitempty" validate:"omitempty,dive"`
// Slice of structs with net interface description.
// If not specified, compute will be created with default interface from RG.
// To create compute without interfaces, pass initialized empty slice .
@ -52,9 +58,20 @@ type CreateBlankRequest struct {
Description string `url:"desc,omitempty" json:"desc,omitempty"`
}
// GetRAM returns RAM field values
func (r CreateBlankRequest) GetRAM() map[string]uint64 {
res := make(map[string]uint64, 1)
res["RAM"] = r.RAM
return res
}
type wrapperCreateBlankRequest struct {
CreateBlankRequest
Interfaces []string `url:"interfaces,omitempty"`
DataDisks []string `url:"dataDisks,omitempty"`
}
// CreateBlank creates KVM PowerPC VM from scratch
@ -81,9 +98,25 @@ func (k KVMPPC) CreateBlank(ctx context.Context, req CreateBlankRequest) (uint64
interfaces = []string{"[]"}
}
var dataDisks []string
if req.DataDisks != nil && len(req.DataDisks) != 0 {
dataDisks = make([]string, 0, len(req.DataDisks))
for i := range req.DataDisks {
b, err := json.Marshal(req.DataDisks[i])
if err != nil {
return 0, err
}
dataDisks = append(dataDisks, string(b))
}
}
reqWrapped := wrapperCreateBlankRequest{
CreateBlankRequest: req,
Interfaces: interfaces,
DataDisks: dataDisks,
}
url := "/cloudapi/kvmppc/createBlank"

@ -26,6 +26,35 @@ type Interface struct {
IPAddr string `url:"ipAddr,omitempty" json:"ipAddr,omitempty"`
}
// DataDisk detailed struct for DataDisks field in CreateRequest and CreateBlankRequest
type DataDisk struct {
// Name for disk
// Required: true
DiskName string `url:"diskName" json:"diskName" validate:"required"`
// Disk size in GB
// Required: true
Size uint64 `url:"size" json:"size" validate:"required"`
// Storage endpoint provider ID
// By default the same with boot disk
// Required: false
SepID uint64 `url:"sepId,omitempty" json:"sepId,omitempty"`
// Pool name
// By default will be chosen automatically
// Required: false
Pool string `url:"pool,omitempty" json:"pool,omitempty"`
// Optional description
// Required: false
Description string `url:"desc,omitempty" json:"desc,omitempty"`
// Specify image id for create disk from template
// Required: false
ImageID uint64 `url:"imageId,omitempty" json:"imageId,omitempty"`
}
// CreateRequest struct to create KVM x86 VM
type CreateRequest struct {
// ID of the resource group, which will own this VM
@ -63,6 +92,12 @@ type CreateRequest struct {
// Required: false
Pool string `url:"pool,omitempty" json:"pool,omitempty"`
// Slice of structs with data disk description. Each disk has parameters: required - diskName, size; optional - sepId, pool, desc and imageId.
// If not specified, compute will be created without disks.
// To create compute without disks, pass initialized empty slice .
// Required: false
DataDisks []DataDisk `url:"-" json:"dataDisks,omitempty" validate:"omitempty,dive"`
// Slice of structs with net interface description.
// If not specified, compute will be created with default interface from RG.
// To create compute without interfaces, pass initialized empty slice .
@ -98,9 +133,20 @@ type CreateRequest struct {
Driver string `url:"driver,omitempty" json:"driver,omitempty" validate:"omitempty,computeDriver"`
}
// GetRAM returns RAM field values
func (r CreateRequest) GetRAM() map[string]uint64 {
res := make(map[string]uint64, 1)
res["RAM"] = r.RAM
return res
}
type wrapperCreateRequest struct {
CreateRequest
Interfaces []string `url:"interfaces,omitempty"`
DataDisks []string `url:"dataDisks,omitempty"`
}
// Create creates KVM x86 VM based on specified OS image
@ -127,9 +173,25 @@ func (k KVMX86) Create(ctx context.Context, req CreateRequest) (uint64, error) {
interfaces = []string{"[]"}
}
var dataDisks []string
if req.DataDisks != nil && len(req.DataDisks) != 0 {
dataDisks = make([]string, 0, len(req.DataDisks))
for i := range req.DataDisks {
b, err := json.Marshal(req.DataDisks[i])
if err != nil {
return 0, err
}
dataDisks = append(dataDisks, string(b))
}
}
reqWrapped := wrapperCreateRequest{
CreateRequest: req,
Interfaces: interfaces,
DataDisks: dataDisks,
}
url := "/cloudapi/kvmx86/create"

@ -41,6 +41,12 @@ type CreateBlankRequest struct {
// Required: true
Pool string `url:"pool" json:"pool" validate:"required"`
// Slice of structs with data disk description. Each disk has parameters: required - diskName, size; optional - sepId, pool, desc and imageId.
// If not specified, compute will be created without disks.
// To create compute without disks, pass initialized empty slice .
// Required: false
DataDisks []DataDisk `url:"-" json:"dataDisks,omitempty" validate:"omitempty,dive"`
// Slice of structs with net interface description.
// If not specified, compute will be created with default interface from RG.
// To create compute without interfaces, pass initialized empty slice .
@ -56,9 +62,20 @@ type CreateBlankRequest struct {
Description string `url:"desc,omitempty" json:"desc,omitempty"`
}
// GetRAM returns RAM field values
func (r CreateBlankRequest) GetRAM() map[string]uint64 {
res := make(map[string]uint64, 1)
res["RAM"] = r.RAM
return res
}
type wrapperCreateBlankRequest struct {
CreateBlankRequest
Interfaces []string `url:"interfaces,omitempty"`
DataDisks []string `url:"dataDisks,omitempty"`
}
// CreateBlank creates KVM x86 VM from scratch
@ -85,9 +102,25 @@ func (k KVMX86) CreateBlank(ctx context.Context, req CreateBlankRequest) (uint64
interfaces = []string{"[]"}
}
var dataDisks []string
if req.DataDisks != nil && len(req.DataDisks) != 0 {
dataDisks = make([]string, 0, len(req.DataDisks))
for i := range req.DataDisks {
b, err := json.Marshal(req.DataDisks[i])
if err != nil {
return 0, err
}
dataDisks = append(dataDisks, string(b))
}
}
reqWrapped := wrapperCreateBlankRequest{
CreateBlankRequest: req,
Interfaces: interfaces,
DataDisks: dataDisks,
}
url := "/cloudapi/kvmx86/createBlank"

@ -10,8 +10,6 @@ import (
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
type Params []string
// CreateRequest struct to create load balancer
type CreateRequest struct {
// ID of the resource group where this load balancer instance will be located
@ -33,7 +31,7 @@ type CreateRequest struct {
// Custom sysctl values for Load Balancer instance. Applied on boot
// Required: false
SysctlParams Params `url:"-" json:"sysctlParams,omitempty" validate:"omitempty,dive"`
SysctlParams []map[string]interface{} `url:"-" json:"sysctlParams,omitempty" validate:"omitempty,dive"`
// Use Highly Available schema for LB deploy
// Required: false
@ -68,14 +66,12 @@ func (l LB) Create(ctx context.Context, req CreateRequest) (uint64, error) {
if len(req.SysctlParams) != 0 {
params = make([]string, 0, len(req.SysctlParams))
for r := range req.SysctlParams {
b, err := json.Marshal(req.SysctlParams[r])
for _, m := range req.SysctlParams {
encodeStr, err := json.Marshal(m)
if err != nil {
return 0, err
}
params = append(params, string(b))
params = append(params, string(encodeStr))
}
} else {
params = []string{}

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get list of load balancers
@ -44,6 +46,10 @@ type ListRequest struct {
// Required: false
IncludeDeleted bool `url:"includedeleted,omitempty" json:"includedeleted,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -55,6 +61,7 @@ type ListRequest struct {
// List gets list of all load balancers as a ListLB struct
func (l LB) List(ctx context.Context, req ListRequest) (*ListLB, error) {
res, err := l.ListRaw(ctx, req)
if err != nil {
return nil, err
@ -72,6 +79,11 @@ func (l LB) List(ctx context.Context, req ListRequest) (*ListLB, error) {
// ListRaw gets list of all load balancers as an array of bytes
func (l LB) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/lb/list"
res, err := l.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListDeletedRequest struct to get list of deleted load balancers
@ -18,7 +20,7 @@ type ListDeletedRequest struct {
// Find by account ID
// Required: false
AccountID uint64 `url:"accountID,omitempty" json:"accountID,omitempty"`
AccountID uint64 `url:"accountId,omitempty" json:"accountId,omitempty"`
// Find by resource group ID
// Required: false
@ -36,6 +38,10 @@ type ListDeletedRequest struct {
// Required: false
BackIP string `url:"backIp,omitempty" json:"backIp,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -47,6 +53,11 @@ type ListDeletedRequest struct {
// ListDeleted gets list of deleted load balancers
func (l LB) ListDeleted(ctx context.Context, req ListDeletedRequest) (*ListLB, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/lb/listDeleted"
res, err := l.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -50,6 +50,12 @@ type RecordLB struct {
// ID
ID uint64 `json:"id"`
// ManagerId
ManagerId uint64 `json:"managerId"`
// ManagerType
ManagerType string `json:"managerType"`
// Image ID
ImageID uint64 `json:"imageId"`
@ -89,6 +95,9 @@ type RecordLB struct {
// Updated time
UpdatedTime uint64 `json:"updatedTime"`
// UserManaged
UserManaged bool `json:"userManaged"`
// VINS ID
VINSID uint64 `json:"vinsId"`
}

@ -22,7 +22,7 @@ func (l LB) Stop(ctx context.Context, req StopRequest) (bool, error) {
return false, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/lb/start"
url := "/cloudapi/lb/stop"
res, err := l.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {

@ -17,7 +17,7 @@ type UpdateSysctParamsRequest struct {
// Custom sysctl values for Load Balancer instance. Applied on boot
// Required: true
SysctlParams Params `url:"-" json:"sysctlParams" validate:"required,dive"`
SysctlParams []map[string]interface{} `url:"-" json:"sysctlParams" validate:"required,dive"`
}
type wrapperUpdateSysctParamsRequest struct {
@ -26,7 +26,7 @@ type wrapperUpdateSysctParamsRequest struct {
}
// UpdateSysctParams updates sysct paarams for lb
func (l LB) UpdateSysctParams(ctx context.Context, req UpdateSysctParamsRequest) (bool, error) {
func (l LB) UpdateSysctlParams(ctx context.Context, req UpdateSysctParamsRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
return false, validators.ValidationErrors(validators.GetErrors(err))
@ -36,14 +36,12 @@ func (l LB) UpdateSysctParams(ctx context.Context, req UpdateSysctParamsRequest)
if len(req.SysctlParams) != 0 {
params = make([]string, 0, len(req.SysctlParams))
for r := range req.SysctlParams {
b, err := json.Marshal(req.SysctlParams[r])
for _, m := range req.SysctlParams {
encodeStr, err := json.Marshal(m)
if err != nil {
return false, err
}
params = append(params, string(b))
params = append(params, string(encodeStr))
}
} else {
params = []string{}
@ -54,7 +52,7 @@ func (l LB) UpdateSysctParams(ctx context.Context, req UpdateSysctParamsRequest)
Params: params,
}
url := "/cloudapi/lb/updateSysctParams"
url := "/cloudapi/lb/updateSysctlParams"
res, err := l.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
if err != nil {

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get list of locations
@ -31,10 +33,15 @@ type ListRequest struct {
// Find by code location
// Required: false
LocationCode string `url:"locationCode,omitempty" json:"locationCode,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
}
// List gets list of all locations as a ListLocations struct
func (l Locations) List(ctx context.Context, req ListRequest) (*ListLocations, error) {
res, err := l.ListRaw(ctx, req)
if err != nil {
return nil, err
@ -52,6 +59,11 @@ func (l Locations) List(ctx context.Context, req ListRequest) (*ListLocations, e
// ListRaw gets list of all locations as an array of bytes
func (l Locations) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/locations/list"
res, err := l.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -0,0 +1,8 @@
package cloudapi
import "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/pcidevice"
// Accessing the PCI Device method group
func (ca *CloudAPI) PCIDevice() *pcidevice.PCIDevice {
return pcidevice.New(ca.client)
}

@ -0,0 +1,10 @@
package pcidevice
// IDs gets array of PCIDeviceIDs from ListPCIDevices struct
func (lpd ListPCIDevices) IDs() []uint64 {
res := make([]uint64, 0, len(lpd.Data))
for _, lb := range lpd.Data {
res = append(res, lb.ID)
}
return res
}

@ -0,0 +1,76 @@
package pcidevice
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get list of pci devices
type ListRequest struct {
// Find by id
// Required: false
ByID uint64 `url:"by_id,omitempty" json:"by_id,omitempty"`
// Find by computeId
// Required: false
ComputeID uint64 `url:"computeId,omitempty" json:"computeId,omitempty"`
// Find by name
// Required: false
Name string `url:"name,omitempty" json:"name,omitempty"`
// Find by rgId
// Required: false
RGID uint64 `url:"rgId,omitempty" json:"rgId,omitempty"`
// Find by status
// Required: false
Status string `url:"status,omitempty" json:"status,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// 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 all pci devices as a ListPCIDevices struct
func (p PCIDevice) List(ctx context.Context, req ListRequest) (*ListPCIDevices, error) {
res, err := p.ListRaw(ctx, req)
if err != nil {
return nil, err
}
list := ListPCIDevices{}
err = json.Unmarshal(res, &list)
if err != nil {
return nil, err
}
return &list, nil
}
// ListRaw gets list of all pci devices as an array of bytes
func (p PCIDevice) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/pcidevice/list"
res, err := p.client.DecortApiCall(ctx, http.MethodPost, url, req)
return res, err
}

@ -0,0 +1,50 @@
package pcidevice
// Main information about PCI device
type ItemPCIDevice struct {
// CKey
CKey string `json:"_ckey"`
// Meta
Meta []interface{} `json:"_meta"`
// Compute ID
ComputeID uint64 `json:"computeId"`
// Description
Description string `json:"description"`
// GUID
GUID uint64 `json:"guid"`
// HwPath
HwPath string `json:"hwPath"`
// ID
ID uint64 `json:"id"`
// Name
Name string `json:"name"`
// Resource group ID
RGID uint64 `json:"rgId"`
// Stack ID
StackID uint64 `json:"stackId"`
// Status
Status string `json:"status"`
// System name
SystemName string `json:"systemName"`
}
// List PCI devices
type ListPCIDevices struct {
// Data
Data []ItemPCIDevice `json:"data"`
// Entry count
EntryCount uint64 `json:"entryCount"`
}

@ -0,0 +1,15 @@
package pcidevice
import "repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
// Structure for creating request to PCI device
type PCIDevice struct {
client interfaces.Caller
}
// Builder for PCI device endpoints
func New(client interfaces.Caller) *PCIDevice {
return &PCIDevice{
client: client,
}
}

@ -0,0 +1,42 @@
package pcidevice
import (
"encoding/json"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/serialization"
)
// Serialize returns JSON-serialized []byte. Used as a wrapper over json.Marshal and json.MarshalIndent functions.
//
// In order to serialize with indent make sure to follow these guidelines:
// - First argument -> prefix
// - Second argument -> indent
func (l ListPCIDevices) Serialize(params ...string) (serialization.Serialized, error) {
if len(l.Data) == 0 {
return []byte{}, nil
}
if len(params) > 1 {
prefix := params[0]
indent := params[1]
return json.MarshalIndent(l, prefix, indent)
}
return json.Marshal(l)
}
// Serialize returns JSON-serialized []byte. Used as a wrapper over json.Marshal and json.MarshalIndent functions.
//
// In order to serialize with indent make sure to follow these guidelines:
// - First argument -> prefix
// - Second argument -> indent
func (i ItemPCIDevice) Serialize(params ...string) (serialization.Serialized, error) {
if len(params) > 1 {
prefix := params[0]
indent := params[1]
return json.MarshalIndent(i, prefix, indent)
}
return json.Marshal(i)
}

@ -55,12 +55,10 @@ func (lrc ListResourceConsumption) IDs() []uint64 {
}
// IDs gets array of ResourceGroupIDs from ListAffinityGroup struct
func (lag ListAffinityGroups) IDs() []uint64 {
res := make([]uint64, 0, len(lag.Data))
for _, ag := range lag.Data {
for _, v := range ag {
res = append(res, v...)
}
func (lag ListAffinityGroup) IDs() []uint64 {
res := make([]uint64, 0, len(lag))
for _, ag := range lag {
res = append(res, ag.ID)
}
return res
}

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get list of resource groups
@ -44,6 +46,10 @@ type ListRequest struct {
// Required: false
IncludeDeleted bool `url:"includedeleted,omitempty" json:"includedeleted,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -55,6 +61,7 @@ type ListRequest struct {
// List gets list of all resource groups the user has access to as a ListResourceGroups struct
func (r RG) List(ctx context.Context, req ListRequest) (*ListResourceGroups, error) {
res, err := r.ListRaw(ctx, req)
if err != nil {
return nil, err
@ -72,6 +79,11 @@ func (r RG) List(ctx context.Context, req ListRequest) (*ListResourceGroups, err
// ListRaw gets list of all resource groups the user has access to as an array of bytes
func (r RG) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/rg/list"
res, err := r.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -46,6 +46,10 @@ type ListComputesRequest struct {
// Required: false
ExtNetID uint64 `url:"extNetId,omitempty" json:"extNetId,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -57,6 +61,7 @@ type ListComputesRequest struct {
// ListComputes gets list of all compute instances under specified resource group, accessible by the user
func (r RG) ListComputes(ctx context.Context, req ListComputesRequest) (*ListComputes, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListDeletedRequest struct to get list deleted resource groups
@ -36,6 +38,10 @@ type ListDeletedRequest struct {
// Required: false
LockStatus string `url:"lockStatus,omitempty" json:"lockStatus,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -47,6 +53,11 @@ type ListDeletedRequest struct {
// ListDeleted gets list all deleted resource groups the user has access to
func (r RG) ListDeleted(ctx context.Context, req ListDeletedRequest) (*ListResourceGroups, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/rg/listDeleted"
res, err := r.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -24,7 +24,7 @@ type ListLBRequest struct {
// Find by account ID
// Required: false
AccountID uint64 `url:"accountID,omitempty" json:"accountID,omitempty"`
AccountID uint64 `url:"accountId,omitempty" json:"accountId,omitempty"`
// Find by tech status
// Required: false
@ -42,6 +42,10 @@ type ListLBRequest struct {
// Required: false
BackIP string `url:"backIp,omitempty" json:"backIp,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -53,6 +57,7 @@ type ListLBRequest struct {
// ListLB gets list all load balancers in the specified resource group, accessible by the user
func (r RG) ListLB(ctx context.Context, req ListLBRequest) (*ListLB, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))

@ -17,6 +17,7 @@ type ListPFWRequest struct {
// ListPFW gets list port forward rules for the specified resource group
func (r RG) ListPFW(ctx context.Context, req ListPFWRequest) (*ListPortForwards, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))

@ -30,6 +30,10 @@ type ListVINSRequest struct {
// Required: false
VINSID uint64 `url:"vinsId,omitempty" json:"vinsId,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -41,6 +45,7 @@ type ListVINSRequest struct {
// ListVINS gets list all ViNSes under specified resource group, accessible by the user
func (r RG) ListVINS(ctx context.Context, req ListVINSRequest) (*ListVINS, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))

@ -77,6 +77,9 @@ type RecordResourceGroup struct {
// Access Control List
ACL ListACL `json:"acl"`
// Compute Features
ComputeFeatures []string `json:"computeFeatures"`
// CPU allocation parameter
CPUAllocationParameter string `json:"cpu_allocation_parameter"`
@ -170,6 +173,9 @@ type ItemResourceGroup struct {
// Access Control List
ACL ListACL `json:"acl"`
// Compute Features
ComputeFeatures []string `json:"computeFeatures"`
// CPU allocation parameter
CPUAllocationParameter string `json:"cpu_allocation_parameter"`
@ -331,10 +337,19 @@ type ItemAffinityGroupComputes struct {
// List of affinity groups
type ListAffinityGroupsComputes []ItemAffinityGroupComputes
// Main information about
type ItemAffinityGroup struct {
ID uint64 `json:"id"`
NodeID uint64 `json:"node_id"`
}
// List of affinity group
type ListAffinityGroup []ItemAffinityGroup
// List of affinity groups
type ListAffinityGroups struct {
// Data
Data []map[string][]uint64 `json:"data"`
Data []map[string]ListAffinityGroup `json:"data"`
// Entry count
EntryCount uint64 `json:"entryCount"`
@ -768,6 +783,12 @@ type ItemVINS struct {
// External IP
ExternalIP string `json:"externalIP"`
// Extnet ID
ExtnetId uint64 `json:"extnetId"`
// Free IPs
FreeIPs uint64 `json:"freeIPs"`
// ID
ID uint64 `json:"id"`

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct for list of the available flavors
@ -16,6 +18,10 @@ type ListRequest struct {
// Required: false
Location string `url:"location,omitempty" json:"location,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -27,6 +33,7 @@ type ListRequest struct {
// List gets list of the available flavors as a ListSizes struct, filtering can be based on the user which is doing the request
func (s Sizes) List(ctx context.Context, req ListRequest) (*ListSizes, error) {
res, err := s.ListRaw(ctx, req)
if err != nil {
return nil, err
@ -44,6 +51,11 @@ func (s Sizes) List(ctx context.Context, req ListRequest) (*ListSizes, error) {
// ListRaw gets list of the available flavors as an array of bytes
func (s Sizes) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/sizes/list"
res, err := s.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get list of stacks
@ -24,6 +26,10 @@ type ListRequest struct {
// Required: false
Status string `url:"status,omitempty" json:"status,omitempty"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
@ -35,6 +41,7 @@ type ListRequest struct {
// List gets list of stacks as a ListStacks struct
func (i Stack) List(ctx context.Context, req ListRequest) (*ListStacks, error) {
res, err := i.ListRaw(ctx, req)
if err != nil {
return nil, err
@ -52,6 +59,11 @@ func (i Stack) List(ctx context.Context, req ListRequest) (*ListStacks, error) {
// ListRaw gets list of stacks as an array of bytes
func (i Stack) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/stack/list"
res, err := i.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -4,21 +4,51 @@ import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get list of tasks
type ListRequest struct {
// Find by guId
// Required: false
TaskID string `url:"taskId,omitempty" json:"taskId,omitempty"`
// Find by status
// Required: false
Status string `url:"status,omitempty" json:"status,omitempty"`
// Find by completed True or False
// Default: false
// Required: false
Completed bool `url:"completed" json:"completed"`
// Sort by one of supported fields, format +|-(field)
// Required: false
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
// Find all tasks after point in time (unixtime)
// Required: false
UpdateTimeAt uint64 `url:"page,updateTimeAt" json:"updateTimeAt,omitempty"`
// Find all tasks before point in time (unixtime)
// Required: false
UpdateTimeTo uint64 `url:"page,updateTimeTo" json:"updateTimeTo,omitempty"`
// Page number
// Default: 0
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
// Page size
// Default: 0
// Required: false
Size uint64 `url:"size,omitempty" json:"size,omitempty"`
}
// List gets list of user API tasks with status PROCESSING as a ListTasks struct
func (t Tasks) List(ctx context.Context, req ListRequest) (*ListTasks, error) {
res, err := t.ListRaw(ctx, req)
if err != nil {
return nil, err
@ -36,6 +66,11 @@ func (t Tasks) List(ctx context.Context, req ListRequest) (*ListTasks, error) {
// ListRaw gets list of user API tasks with status PROCESSING as an array of bytes
func (t Tasks) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/tasks/list"
res, err := t.client.DecortApiCall(ctx, http.MethodPost, url, req)

@ -1,46 +1,13 @@
package tasks
import (
"encoding/json"
"errors"
"fmt"
"strconv"
)
// Global variable for converting field to desired data type
type TaskResult int
// Method for convert field
func (r *TaskResult) UnmarshalJSON(b []byte) error {
if b[0] == '"' {
b := b[1 : len(b)-1]
if len(b) == 0 {
*r = 0
return nil
}
n, err := strconv.Atoi(string(b))
if err != nil {
return err
}
*r = TaskResult(n)
} else if b[0] == '[' {
res := []interface{}{}
if err := json.Unmarshal(b, &res); err != nil {
return err
}
if n, ok := res[0].(float64); ok {
*r = TaskResult(n)
} else {
return fmt.Errorf("could not unmarshal %v into int", res[0])
}
} else {
n, err := strconv.Atoi(string(b))
if err != nil {
return err
}
*r = TaskResult(n)
}
return nil
// Result structure of the task to provide methods
type Result struct {
Result interface{} `json:"result"`
}
// Detailed information about task
@ -57,8 +24,8 @@ type RecordAsyncTask struct {
// List of logs
Log []string `json:"log"`
// Final result
Result TaskResult `json:"result"`
// Final Result
Result
// Stage
Stage string `json:"stage"`
@ -78,37 +45,102 @@ type RecordAsyncTask struct {
// Detailed information about task
type ItemAsyncTask struct {
// Audit ID
AuditID string `json:"auditId"`
RecordAsyncTask
// Completed
Completed bool `json:"completed"`
// GUID
GUID string `json:"guid"`
}
// Error
Error string `json:"error"`
// List of tasks
type ListTasks struct {
Data []ItemAsyncTask `json:"data"`
// List of logs
Log []string `json:"log"`
EntryCount uint64 `json:"entryCount"`
}
// Final result
Result TaskResult `json:"result"`
// ID returns ID of cluster or WG or any other resource successfully created as a Result of the task.
// It returns error if Result does not contain any resource ID.
func (r Result) ID() (int, error) {
// check id from cluster - it comes as slice, like [1234, "cluster-name"]
slice, ok := r.Result.([]interface{})
if ok {
if len(slice) == 0 {
return 0, fmt.Errorf("could not get ID from empty slice")
}
// Stage
Stage string `json:"stage"`
idFloat64, ok := slice[0].(float64)
if !ok {
return 0, fmt.Errorf("could not get ID from first slice element (%v)", slice[0])
}
// Status
Status string `json:"status"`
return int(idFloat64), nil
}
// Update time
UpdateTime uint64 `json:"updateTime"`
// check id from other resources - it comes as id
idFloat64, ok := r.Result.(float64)
if ok {
return int(idFloat64), nil
}
// Updated time
UpdatedTime uint64 `json:"updatedTime"`
return 0, errors.New("could not get ID because result is neither slice nor number (%v)")
}
// List of tasks
type ListTasks struct {
Data []ItemAsyncTask `json:"data"`
// Name returns name of cluster or WG successfully created as a Result of the task.
// It returns error if Result does not contain k8s name.
func (r Result) Name() (string, error) {
slice, ok := r.Result.([]interface{})
if !ok {
return "", fmt.Errorf("could not convert Result (%v) to slice", r.Result)
}
EntryCount uint64 `json:"entryCount"`
if len(slice) < 2 {
return "", fmt.Errorf("could not get name from second slice element")
}
var name string
name, ok = slice[1].(string)
if !ok {
return "", fmt.Errorf("could not get name from second slice element (%v)", slice[1])
}
return name, nil
}
// ToMaps converts Result to a slice of maps containing back-up information as a result of the task.
// It returns error if Result does not contain back-up information.
func (r Result) ToMaps() ([]map[string]interface{}, error) {
slice, ok := r.Result.([]interface{})
if !ok {
return nil, fmt.Errorf("could not convert Result (%v) to slice", r.Result)
}
if len(slice) == 0 {
return nil, fmt.Errorf("could not get maps from empty slice")
}
result := make([]map[string]interface{}, 0, len(slice))
for _, s := range slice {
elem, ok := s.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("could not get map[string]interface{} from slice element (%v)", s)
}
result = append(result, elem)
}
return result, nil
}
// ToString converts Result to non-empty string.
// It returns error if Result is not a string or is an empty string.
func (r Result) ToString() (string, error) {
status, ok := r.Result.(string)
if !ok {
return "", fmt.Errorf("could not convert Result (%v) to string", r.Result)
}
if status == "" {
return "", fmt.Errorf("info contains empty string")
}
return status, nil
}

@ -0,0 +1,7 @@
package cloudapi
import "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/user"
func (ca *CloudAPI) User() *user.User {
return user.New(ca.client)
}

@ -0,0 +1,41 @@
package user
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// APIListRequest struct for getting API list.
type APIListRequest struct {
// ID of the user.
// Required: true
UserID string `url:"userId" json:"userId" validate:"required"`
}
// APIList gets a list of all API functions that a given user has
// access to according to their apiaccess group membership.
func (u User) APIList(ctx context.Context, req APIListRequest) (*APIsEndpoints, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudapi/user/apiList"
info := APIsEndpoints{}
res, err := u.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save