diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dbf850..9809185 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,202 @@ -## Version 1.10.2 +## Version 1.11 ### Добавлено +#### account +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-304 | Опциональное поле `Description` в структуру запроса `UpdateCreateRequest` в cloudapi/account | +| BGOS-304 | Опциональное поле `Description` в структуры запроса `CreateRequest`, `UpdateCreateRequest` в cloudbroker/account | +| BGOS-304 | Поле `Description` в структуры ответа `ItemRG`, `RecordAccount`, `ItemAccount` в cloudapi/account и cloudbroker/account | +| BGOS-316 | Опциональное поле `Reason` в структуру запроса `DisableEnableRequest` в cloudapi/account | +| BGOS-316 | Опциональное поле `Reason` в структуры запроса `RestoreRequest`, `DisableAccountsRequest`, `DisableRequest` в cloudbroker/account | + +#### apiaccess +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-306 | Метод `GetDefault` и структура ответа `ItemAPIAccessDefault` в cloudbroker/apiaccess | +| BGOS-309 | Обязательные поля `APIGroup`, `APIMethod`, `APIObject` в структуру запроса `APIFindRequest` в cloudbroker/apiaccess | +| BGOS-309 | Поле `DPDK` в структуры ответа `CloudAPIEndpoints` и `CloudBrokerEndpoints` в cloudbroker/apiaccess | + +#### audit +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-307 | Опциональное поле `RequestID` в структуру запроса `ListRequest` в cloudapi/audit | +| BGOS-337 | Поле `PhysicalNode` в структуру ответа `ItemLinkedJobs` в cloudbroker/audit | +| BGOS-395 | Поле `TTL` в структуру ответа `RecordAudit` в cloudbroker/audit | +| BGOS-395 | Поля `Args`, `Kwargs`, `RemoteAddr`, `Result`, `TimestampEnd`, `TTL` в структуру ответа `ItemAudit` в cloudbroker/audit | +| BGOS-340 | Поле `Tags` в структуре ответа `ItemAudit` в cloudbroker/audit | + +### bservice +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-317 | Опциональное поле `Chipset` в структуру запроса `GroupAddRequest` в cloudapi/bservice | +| BGOS-354 | Опциональное поле `Chipset` в структуру запроса `GroupResizeRequest` в cloudapi/bservice | +| BGOS-357 | Поле `Chipset` в структуру ответа `ItemGroupCompute` в cloudapi/bservice | + +#### compute +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-311 | Опциональное поле `StackName` в структуру запроса `ListRequest` в cloudbroker/list | +| BGOS-312 | Опциональные поля `LoaderType`, `BootType`, `NetworkInterfaceNaming`, `HotResize` в структуру запроса `UpdateRequest` в cloudapi/compute и cloudbroker/compute | +| BGOS-312 | Поля `LoaderType`, `BootType`, `NetworkInterfaceNaming`, `HotResize` в структуры ответа `InfoCompute`, `RecordCompute`, `ItemCompute` в cloudapi/compute и cloudbroker/compute | +| BGOS-348 | Полe `NID` в структуру ответа `ItemCompute` в cloudbroker/compute | +| BGOS-348 | Структуры ответов `ItemDeletedCompute`, `ListDeletedComputes` в cloudbroker/compute | +| BGOS-388 | Поля `UpdatedBy`, `SizeAvailable` в структуру ответа `ItemDisk` в cloudapi/compute | +| BGOS-388 | Поле `SizeAvailable` в структуру ответа `ItemDisk` в cloudbroker/compute | +| BGOS-392 | Метод `ChangeMAC` и структура запроса `ChangeMACRequest` в cloudapi/compute и cloudbroker/compute | +| BGOS-403 | Опциональное поле `MACAddr` в cloudapi/compute/netAttach и cloudbroker/compute/netAttach | + +#### disks +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-318 | Опциональное поле `Name` в структуру запроса `DeleteRequest` в cloudbroker/disks | +| BGOS-408 | Поля `DeletedBy`, `CreatedBy`, `MachineID`, `MachineName`, `UpdatedTime` и `Milestones` в структуру ответа `ItemDisk` и `RecordDisk` в cloudapi/disks | +| BGOS-408 | Поля `DeletedBy`, `CreatedBy`, `UpdatedTime` и `UpdatedBy` в структуру ответа `RecordDisk` в cloudbroker/disks | +| BGOS-401 | Поля `SizeAvailable` и `UpdatedBy` в структуру ответа `InfoDisk` в cloudbroker/disks | +| BGOS-401 | Поля `SizeAvailable` и `UpdatedBy` в структуры ответа `ItemDisk` и `RecordDisk` в cloudapi/disks | + +#### extnet +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-356 | Опциональное поле `OVSBridge` в структуру запроса `ListRequest` в cloudapi/extnet | +| BGOS-351 | Поле `NTP` в структуру ответа `RecordExtNet` в cloudapi/extnet и cloudbroker/extnet | + +#### image +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-315 | Поле `SnapshotID` в структуру ответа `RecordImage` в cloudapi/image | + +#### k8s +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-304 | Поле `Description` в структуру ответа `RecordK8S` в cloudapi/k8s и cloudbroker/k8s | + +#### kvmx86 +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-312 | Опциональные поля `LoaderType`, `BootType`, `NetworkInterfaceNaming`, `HotResize` в структуру запроса `CreateBlankRequest` в cloudapi/kvmx86 и cloudbroker/kvmx86 | +| BGOS-312 | Опциональное поле `MAC` в структуру запроса `Interface` в cloudapi/kvmx86 и cloudbroker/kvmx86 | + +#### node +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-397 | Метод `SetVFsParams` и структура запроса `SetVFsParamsRequest` в cloudbroker/node | + #### prometheus | Идентификатор
задачи | Описание | | --- | --- | -| BGOS-335 | Группа ручек cloudbroker/prometheus | +| BGOS-405 | Метод `Computes` структура запроса `ComputesRequest` и структура ответа `ComputesData` в cloudbroker/prometheus | + +#### resmon +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-341 | Поля `ID`, `SizeAvailable` в структуру ответа `ItemDisk` сloudbroker/resmon | + +#### sep +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-343 | Метод `GetTemplate` и структура запроса `GetTemplateRequest` в cloudbroker/sep | +| BGOS-301 | Метод `ListAvailableSEPAndPools` структура запроса `ListAvailableSEPAndPoolsRequest` и структура ответа `ListAvailableSEP` в cloudapi/sep и cloudbroker/sep | +| BGOS-299 | Обязательное поле `Force` в структуру запроса `DelConsumerNodesRequest` в cloudbroker/sep | + +#### stack +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-389 | Структура ответа `LibGuestFSTools` входящая в структуру ответа `Packages` в cloudbroker/stack | + +#### user +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-303 | Опциональное поле `SortBy` в структуру запроса `GetAuditRequest` cloudapi/user | + +#### vins +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-300 | Опциональное поле `Status` в структуру запроса `ListRequest` cloudapi/vins и cloudbroker/vins | + +### Удалено + +#### apiaccess +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-309 | Обязательное поле `APIName` из структуры запроса `APIFindRequest` в cloudbroker/apiacces | +| BGOS-309 | Метод `GetPreGroups` в cloudbroker/apiaccess | +| BGOS-309 | Опциональное поле `CreatedBy` из структуры запроса `ListRequest` в cloudbroker/apiaccess | +| BGOS-309 | Метод `ListDeletedRequest` и структура запроса `ListDeletedRequest` и в cloudbroker/apiaccess | +| BGOS-309 | Поля `CreatedBy`, `UpdatedBy`, `DeletedBy`, `Milestone` из структуры ответа `ItemAPIAccess` в cloudbroker/apiaccess | + +#### compute +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-338 | Опциональное поле `Depresent` из структуры запроса `StopRequest` в cloudbroker/compute | +| BGOS-344 | Методы `RepairBootFS`, `MassRepairBootFS`, `Registration` в cloudbroker/compute | +| BGOS-353 | Поля `PCISlot`, `BusNumber` из структуры ответа `InfoDisk` в cloudapi/compute и cloudbroker/compute | + +#### disks +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-298 | Опциональные поля `Type, SSDSize` из структуры запроса `CreateRequest` в cloudapi/disks и cloudbroker/disks | +| BGOS-338 | Обязательное поле `GID` из структуры запроса `CreateRequest` в cloudapi/disks и cloudbroker/disks | + +#### image +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-338 | Обязательное поле `GID` из структур запроса `CreateRequest`, `CreateCDROMImageRequest` в cloudbroker/image | + +#### node +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-308 | Опциональное поле `VDiskAction` из структуры запроса `MaintenanceRequest` в cloudbroker/node | + +#### rg +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-342 | Опциональное поле `RegisterComputes` из структур запроса `CreateRequest`, `UpdateRequest` в cloudapi/rg и cloudbroker/rg | + +### Исправлено + +#### apiaccess +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-308 | Изменены все теги `json` и `url` в структурах ответов и запросов с `CamelCase` на `snake_case` в cloudbroker/apiaccess | + +#### audit +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-346 | Изменены все теги `json` и `url` в структурах запросов с `CamelCase` на `snake_case` в cloudapi/audit и cloudbroker/audit | + +#### compute +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-314 | Измененен тип с `[]uint64` на `map[strint]uint64` полей `PresentTo` в структурах ответа `ItemComputeDisk`, `ItemDisk` в cloudapi/compute и cloudbroker/compute | +| BGOS-355 | Переименованны поля с `Pinned` на `PinnedToStack` в структурах ответа `InfoCompute, RecordCompute, ItemCompute` в cloudapi/compute и cloudbroker/compute | +| BGOS-355 | Изменен тип поля с `PinnedToStack` (ранее `Pinned`) с `bool` на `int` в структурах ответа `InfoCompute, RecordCompute` в cloudbroker/compute | +| BGOS-388 | Изменен json тег поля `PCISlot` с `pciSlot` на `pci_slot` в структурах ответа `ItemDisk` в cloudapi/compute и cloudbroker/compute | +| BGOS-392 | Изменены все теги `json` и `url` в структуре запроса `ChangeIPRequest` с `CamelCase` на `snake_case` в cloudapi/compute и cloudbroker/compute | + +#### disks +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-314 | Измененен тип с `[]uint64` на `map[strint]uint64` полей `PresentTo` в структурах ответа `ItemDiskUnattached`, `RecordDisk`, `ItemDisk`, `InfoDisk` в cloudapi/disks и cloudbroker/disks | +| BGOS-408 | Перенесены поля с `MachindeID` и `MachineName` из структуры ответа `ItemDisk` в `RecordDisk` в cloudbroker/disks | + +#### image +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-314 | Измененен тип с `[]uint64` на `map[strint]uint64` полей `PresentTo` в структурах ответа `ItemImage`, `RecordImage` в cloudapi/image и cloudbroker/image | + +#### image +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-305 | Изменен тип опционального поля `AccountIDs` c []uint64 на []int64 в моделях `GrantAccessRequest`, `RevokeAccessRequest` в cloudbroker/image | #### resmon | Идентификатор
задачи | Описание | | --- | --- | -| BGOS-336 | Группа ручек cloudbroker/resmon | \ No newline at end of file +| BGOS-341 | Изменен тип поле `SizeUsed`, `SizeMax` с int64 на float64 в структуре ответа `ItemDisk` сloudbroker/resmon | + +#### sep +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-398 | Обязательные поля `Trust` и `Spoofchk` заменены на `VFParams` в структуре запроса `SetVFsNumberRequest` в cloudbroker/node | diff --git a/README.md b/README.md index b0f39a1..8639945 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Decort SDK - это библиотека, написанная на языке G - Версия 1.8.х Decort-SDK соответствует 4.0.0 версии платформы - Версия 1.9.х Decort-SDK соответствует 4.1.0 версии платформы - Версия 1.10.х Decort-SDK соответствует 4.2.0 версии платформы + - Версия 1.11.х Decort-SDK соответствует 4.3.0 версии платформы ## Оглавление @@ -114,6 +115,7 @@ go get -u repository.basistech.ru/BASIS/decort-golang-sdk - `LB` - управление балансировщиками нагрузки; - `Locations` - получение информации о grid площадки; - `RG` - управление ресурсными группами аккаунта; +- `SEP` - управление storage endpoint (sep); - `Stack` - получение информации о вычислительных узлах; - `Tasks` - получение информации о ходе выполнения асинхронных задач (например, создание кластера); - `VFPool` - управление пулом виртуальных сетевых функций; @@ -298,6 +300,7 @@ func main() { - `pkg/cloudapi/lb` - для `LB` - `pkg/cloudapi/locations` - для `Locations` - `pkg/cloudapi/rg` - для `RG` + - `pkg/cloudbroker/sep` - для `SEP` - `pkg/cloudapi/stack` - для `Stack` - `pkg/cloudapi/tasks` - для `Tasks` - `pkg/cloudapi/vfpool` - для `VFPool` @@ -484,6 +487,7 @@ func main() { - `.LB()` - для работы с `LB` - `.Locations()` - для работы с `Locations` - `.RG()` - для работы с `RG` + - `.SEP()` - для работы с `SEP` - `.Stack()` - для работы с `Stack` - `.Tasks()` - для работы с `Tasks` - `.VFPool()` - для работы с `VFPool` diff --git a/internal/validators/custom.go b/internal/validators/custom.go index 56d190f..15e457d 100644 --- a/internal/validators/custom.go +++ b/internal/validators/custom.go @@ -27,6 +27,13 @@ func protoValidator(fe validator.FieldLevel) bool { return IsInSlice(fieldValue, protoValues) } +// apiGroupValidator is used to validate APIGroup fields +func apiGroupValidator(fe validator.FieldLevel) bool { + fieldValue := fe.Field().String() + + return IsInSlice(fieldValue, apiGroupValues) +} + // accessTypeValidator is used to validate AccessType fields. func accessTypeValidator(fe validator.FieldLevel) bool { fieldValue := fe.Field().String() @@ -393,6 +400,27 @@ func preferredCPUValidator(fe validator.FieldLevel) bool { return true } +// loaderTypeValidator is used to validate loaderType fields +func loaderTypeValidator(fe validator.FieldLevel) bool { + fieldValue := fe.Field().String() + + return IsInSlice(fieldValue, loaderTypeValues) +} + +// languageValidator is used to validate language fields +func languageValidator(fe validator.FieldLevel) bool { + fieldValue := fe.Field().String() + + return IsInSlice(fieldValue, languageValues) +} + +// sepTypeValidator is used to validate sepType fields +func sepTypeValidator(fe validator.FieldLevel) bool { + fieldValue := fe.Field().String() + + return IsInSlice(fieldValue, sepTypeValues) +} + // 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 { diff --git a/internal/validators/messages.go b/internal/validators/messages.go index 3ec169b..9f558ef 100644 --- a/internal/validators/messages.go +++ b/internal/validators/messages.go @@ -52,6 +52,13 @@ func errorMessage(fe validator.FieldError) string { fe.Field(), joinValues(protoValues)) + // apiGroup Validators + case "apiGroup": + return fmt.Sprintf("%s %s must be one of the following: %s", + prefix, + fe.Field(), + joinValues(apiGroupValues)) + // Account Validators case "accountCUType": return fmt.Sprintf("%s %s must be one of the following: %s", @@ -308,6 +315,24 @@ func errorMessage(fe validator.FieldError) string { prefix, fe.Field(), joinValues(chipsetValues)) + + case "loaderType": + return fmt.Sprintf("%s %s must be one of the following: %s", + prefix, + fe.Field(), + joinValues(loaderTypeValues)) + + case "language": + return fmt.Sprintf("%s %s must be one of the following: %s", + prefix, + fe.Field(), + joinValues(languageValues)) + + case "sepType": + return fmt.Sprintf("%s %s must be one of the following: %s", + prefix, + fe.Field(), + joinValues(sepTypeValues)) } return fe.Error() diff --git a/internal/validators/validator.go b/internal/validators/validator.go index 49f295a..c3a8795 100644 --- a/internal/validators/validator.go +++ b/internal/validators/validator.go @@ -36,6 +36,11 @@ func registerAllValidators(validate *validator.Validate) error { return err } + err = validate.RegisterValidation("apiGroup", apiGroupValidator) + if err != nil { + return err + } + err = validate.RegisterValidation("accessType", accessTypeValidator) if err != nil { return err @@ -266,5 +271,15 @@ func registerAllValidators(validate *validator.Validate) error { return err } + err = validate.RegisterValidation("language", languageValidator) + if err != nil { + return err + } + + err = validate.RegisterValidation("sepType", sepTypeValidator) + if err != nil { + return err + } + return nil } diff --git a/internal/validators/values.go b/internal/validators/values.go index 219fd52..1d30630 100644 --- a/internal/validators/values.go +++ b/internal/validators/values.go @@ -1,6 +1,8 @@ package validators var ( + apiGroupValues = []string{"cloudapi", "cloudbroker", "system"} + driverValues = []string{"KVM_X86"} accessTypeValues = []string{"R", "RCX", "ARCXDU"} resTypesValues = []string{"compute", "vins", "k8s", "openshift", "lb", "flipgroup"} @@ -35,7 +37,7 @@ var ( vinsTypeValues = []string{"DHCP", "VIP", "EXCLUDED"} imageBootTypeValues = []string{"uefi", "bios"} - imageTypeValues = []string{"windows", "linux", "other"} + imageTypeValues = []string{"windows", "linux", "unknown"} imageDriversValues = []string{"KVM_X86"} imageArchitectureValues = []string{"X86_64"} @@ -51,7 +53,7 @@ var ( vmActionValues = []string{"stop", "move"} - computeFeaturesValues = []string{"hugepages", "numa", "cpupin", "vfnic"} + computeFeaturesValues = []string{"hugepages", "numa", "cpupin", "vfnic", "dpdk", "changemac"} networkInterfaceNamingValues = []string{"eth", "ens"} @@ -64,6 +66,12 @@ var ( eventIDxValues = []string{"on", "off", "selected by hypervisor"} chipsetValues = []string{"i440fx", "Q35"} + + loaderTypeValues = []string{"linux", "windows", "unknown"} + + sepTypeValues = []string{"hitachi", "dorado", "tatlin", "shared", "local", "des"} + + languageValues = []string{"ru", "en"} ) const ( diff --git a/pkg/cloudapi/account/disable_enable.go b/pkg/cloudapi/account/disable_enable.go index 3eb98d4..09a0ace 100644 --- a/pkg/cloudapi/account/disable_enable.go +++ b/pkg/cloudapi/account/disable_enable.go @@ -13,6 +13,10 @@ type DisableEnableRequest struct { // ID of account // Required: true AccountID uint64 `url:"accountId" json:"accountId" validate:"required"` + + // Reason of disabling + // Required: false + Reason string `url:"reason,omitempty" json:"reason,omitempty"` } // Disable disables an account diff --git a/pkg/cloudapi/account/models.go b/pkg/cloudapi/account/models.go index f68b7e9..019058e 100644 --- a/pkg/cloudapi/account/models.go +++ b/pkg/cloudapi/account/models.go @@ -62,6 +62,9 @@ type ItemAccount struct { // Deleted time DeletedTime uint64 `json:"deletedTime"` + // Description + Description string `json:"desc"` + // ID ID uint64 `json:"id"` @@ -197,6 +200,9 @@ type RecordAccount struct { // Created time CreatedTime uint64 `json:"createdTime"` + // Description + Description string `json:"desc"` + // Deactivation time DeactivationTime float64 `json:"deactivationTime"` @@ -512,6 +518,9 @@ type ItemRG struct { // Deleted time DeletedTime uint64 `json:"deletedTime"` + // Description + Description string `json:"desc"` + // Resource group ID RGID uint64 `json:"id"` diff --git a/pkg/cloudapi/account/update.go b/pkg/cloudapi/account/update.go index 2d793fd..3215397 100644 --- a/pkg/cloudapi/account/update.go +++ b/pkg/cloudapi/account/update.go @@ -14,6 +14,10 @@ type UpdateRequest struct { // Required: true AccountID uint64 `url:"accountId" json:"accountId" validate:"required"` + // Description + // Required: false + Description string `url:"desc,omitempty" json:"desc,omitempty"` + // Name of the account // Required: false Name string `url:"name,omitempty" json:"name,omitempty"` diff --git a/pkg/cloudapi/audit/get.go b/pkg/cloudapi/audit/get.go index 9db2148..0f246bf 100644 --- a/pkg/cloudapi/audit/get.go +++ b/pkg/cloudapi/audit/get.go @@ -12,7 +12,7 @@ import ( type GetRequest struct { // Audit GUID // Required: true - AuditGuid string `url:"auditGuid" json:"auditGuid" validate:"required"` + AuditGuid string `url:"audit_guid" json:"audit_guid" validate:"required"` } // Get gets information about audit as a RecordAudit struct diff --git a/pkg/cloudapi/bservice/group_add.go b/pkg/cloudapi/bservice/group_add.go index 3ad6575..045ba46 100644 --- a/pkg/cloudapi/bservice/group_add.go +++ b/pkg/cloudapi/bservice/group_add.go @@ -71,6 +71,10 @@ type GroupAddRequest struct { // Meta data for working group computes, format YAML "user_data": 1111 // Required: false UserData string `url:"userData,omitempty" json:"userData,omitempty"` + + //Chipset "i440fx" or "Q35 + //Required: false + Chipset string `url:"chipset,omitempty" json:"chipset,omitempty" validate:"chipset"` } // GetRAM returns RAM field values diff --git a/pkg/cloudapi/bservice/group_resize.go b/pkg/cloudapi/bservice/group_resize.go index bd3d01b..6d4e785 100644 --- a/pkg/cloudapi/bservice/group_resize.go +++ b/pkg/cloudapi/bservice/group_resize.go @@ -22,6 +22,12 @@ type GroupResizeRequest struct { // Required: true Count int64 `url:"count" json:"count" validate:"required"` + //Chipset for new computes, either i440fx or Q35 (i440fx by default) + //Available values : i440fx, Q35 + //Default value : i440fx + //Required: true + Chipset string `url:"chipset" json:"chipset" validate:"required,chipset"` + // Either delta or absolute value of computes // Should be one of: // - ABSOLUTE diff --git a/pkg/cloudapi/bservice/models.go b/pkg/cloudapi/bservice/models.go index ab50f75..86e6416 100644 --- a/pkg/cloudapi/bservice/models.go +++ b/pkg/cloudapi/bservice/models.go @@ -295,6 +295,9 @@ type ItemGroupCompute struct { // List of information about OS Users OSUsers ListOSUsers `json:"osUsers"` + + //Chipset + Chipset string `json:"chipset"` } // List of Group Computes diff --git a/pkg/cloudapi/compute/change_ip.go b/pkg/cloudapi/compute/change_ip.go index 39dfa7f..cd9e992 100644 --- a/pkg/cloudapi/compute/change_ip.go +++ b/pkg/cloudapi/compute/change_ip.go @@ -12,23 +12,23 @@ import ( type ChangeIPRequest struct { // ID of compute instance // Required: true - ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"` + ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"` // Network type // 'EXTNET' for connect to external network directly // 'VINS' for connect to ViNS // Required: true - NetType string `url:"netType" json:"netType" validate:"computeNetType"` + NetType string `url:"net_type" json:"net_type" validate:"computeNetType"` // Network ID for connect to // For EXTNET - external network ID // For VINS - VINS ID // Required: true - NetID uint64 `url:"netId" json:"netId" validate:"required"` + NetID uint64 `url:"net_id" json:"net_id" validate:"required"` // IP address to which we will change the existing one, it must be from the same subnet // Required: true - IPAddr string `url:"ipAddr" json:"ipAddr" validate:"required"` + IPAddr string `url:"ip_addr" json:"ip_addr" validate:"required"` } // ChangeIP change reserved IP for compute instance diff --git a/pkg/cloudapi/compute/change_mac.go b/pkg/cloudapi/compute/change_mac.go new file mode 100644 index 0000000..e3c9d54 --- /dev/null +++ b/pkg/cloudapi/compute/change_mac.go @@ -0,0 +1,46 @@ +package compute + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// ChangeMACRequest struct to change MAC for network +type ChangeMACRequest struct { + // ID of compute instance + // Required: true + ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"` + + // Current mac address + // Required: true + СurrentMAC string `url:"current_mac_address" json:"current_mac_address" validate:"required"` + + // the MAC address to which we will change the existing one + // Required: true + NewMAC string `url:"new_mac_address" json:"new_mac_address" validate:"required"` +} + +// ChangeMAC change MAC for compute instance +func (c Compute) ChangeMAC(ctx context.Context, req ChangeMACRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + return false, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudapi/compute/changeMac" + + res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/pkg/cloudapi/compute/filter_test.go b/pkg/cloudapi/compute/filter_test.go index 7f2c1fe..513d2a9 100644 --- a/pkg/cloudapi/compute/filter_test.go +++ b/pkg/cloudapi/compute/filter_test.go @@ -48,8 +48,7 @@ var computes = ListComputes{ Devices: nil, Disks: []InfoDisk{ { - ID: 65191, - PCISlot: 6, + ID: 65191, }, }, Driver: "KVM_X86", @@ -64,7 +63,7 @@ var computes = ListComputes{ MigrationJob: 0, Milestones: 363500, Name: "test", - Pinned: false, + PinnedToStack: true, RAM: 4096, ReferenceID: "c7cb19ac-af4a-4067-852f-c5572949207e", Registered: true, @@ -111,8 +110,7 @@ var computes = ListComputes{ Devices: nil, Disks: []InfoDisk{ { - ID: 65248, - PCISlot: 6, + ID: 65248, }, }, Driver: "KVM_X86", @@ -127,10 +125,10 @@ var computes = ListComputes{ MigrationJob: 0, Milestones: 363853, Name: "compute_2", - Pinned: false, RAM: 4096, ReferenceID: "a542c449-5b1c-4f90-88c5-7bb5f8ae68ff", Registered: true, + PinnedToStack: true, ResName: "compute-48556", RGID: 79727, RGName: "sdk_negative_fields_test", diff --git a/pkg/cloudapi/compute/models.go b/pkg/cloudapi/compute/models.go index 0037ae7..2d260a2 100644 --- a/pkg/cloudapi/compute/models.go +++ b/pkg/cloudapi/compute/models.go @@ -308,6 +308,9 @@ type RecordCompute struct { // Boot order BootOrder []string `json:"bootOrder"` + // Boot type + BootType string `json:"bootType"` + // Boot disk size BootDiskSize uint64 `json:"bootdiskSize"` @@ -368,6 +371,9 @@ type RecordCompute struct { // HPBacked HPBacked bool `json:"hpBacked"` + // Hot resize + HotResize bool `json:"hotResize"` + // ID ID uint64 `json:"id"` @@ -380,6 +386,9 @@ type RecordCompute struct { // List interfaces Interfaces ListInterfaces `json:"interfaces"` + // Loader type + LoaderType string `json:"loaderType"` + // Lock status LockStatus string `json:"lockStatus"` @@ -401,6 +410,9 @@ type RecordCompute struct { // NeedReboot NeedReboot bool `json:"needReboot"` + // Network interface naming + NetworkInterfaceNaming string `json:"networkInterfaceNaming"` + // Numa Affinity NumaAffinity string `json:"numaAffinity"` @@ -425,8 +437,8 @@ type RecordCompute struct { // List OS Users OSUsers ListOSUser `json:"osUsers"` - // Pinned or not - Pinned bool `json:"pinned"` + // Pinned to stack + PinnedToStack bool `json:"pinnedToStack"` // PreferredCPU PreferredCPU []int64 `json:"preferredCpu"` @@ -712,13 +724,13 @@ type ItemComputeDisk struct { Passwd string `json:"passwd"` // PCI slot - PCISlot int64 `json:"pciSlot"` + PCISlot int64 `json:"pci_slot"` // Pool Pool string `json:"pool"` // Present to - PresentTo []uint64 `json:"presentTo"` + PresentTo map[string]uint64 `json:"presentTo"` // Purge time PurgeTime uint64 `json:"purgeTime"` @@ -741,6 +753,9 @@ type ItemComputeDisk struct { // Shareable Shareable bool `json:"shareable"` + // Size available + SizeAvailable uint64 `json:"sizeAvailable"` + // Size max SizeMax uint64 `json:"sizeMax"` @@ -759,6 +774,9 @@ type ItemComputeDisk struct { // Type Type string `json:"type"` + // Updated by + UpdatedBy uint64 `json:"updatedBy"` + // Virtual machine ID VMID uint64 `json:"vmid"` } @@ -884,6 +902,9 @@ type ItemCompute struct { // Boot order BootOrder []string `json:"bootOrder"` + // Boot type + BootType string `json:"bootType"` + // Boot disk size BootDiskSize uint64 `json:"bootdiskSize"` @@ -941,6 +962,9 @@ type ItemCompute struct { // GUID GUID uint64 `json:"guid"` + // Hot resize + HotResize bool `json:"hotResize"` + // HPBacked HPBacked bool `json:"hpBacked"` @@ -953,6 +977,9 @@ type ItemCompute struct { // List interfaces Interfaces ListInterfaces `json:"interfaces"` + // Loader type + LoaderType string `json:"loaderType"` + // Lock status LockStatus string `json:"lockStatus"` @@ -974,14 +1001,17 @@ type ItemCompute struct { // NeedReboot NeedReboot bool `json:"needReboot"` + // network interface naming + NetworkInterfaceNaming string `json:"networkInterfaceNaming"` + // Numa Affinity NumaAffinity string `json:"numaAffinity"` //NumaNodeId NumaNodeId int64 `json:"numaNodeId"` - // Pinned or not - Pinned bool `json:"pinned"` + // Pinned to stack + PinnedToStack bool `json:"pinnedToStack"` // PreferredCPU PreferredCPU []int64 `json:"preferredCpu"` @@ -1054,12 +1084,6 @@ type ListInfoDisks []InfoDisk type InfoDisk struct { // ID ID uint64 `json:"id"` - - // PCISlot - PCISlot int64 `json:"pciSlot"` - - // Bus number - BusNumber uint64 `json:"bus_number"` } // List information about computes diff --git a/pkg/cloudapi/compute/net_attach.go b/pkg/cloudapi/compute/net_attach.go index aa3768c..6e3d5f1 100644 --- a/pkg/cloudapi/compute/net_attach.go +++ b/pkg/cloudapi/compute/net_attach.go @@ -32,6 +32,10 @@ type NetAttachRequest struct { // Required: false IPAddr string `url:"ipAddr,omitempty" json:"ipAddr,omitempty"` + // MAC address + // Required: false + MACAddr string `url:"mac_addr,omitempty" json:"mac_addr,omitempty"` + // Used only for DPDK type, must be 1-9216 // Required: false MTU uint64 `url:"mtu,omitempty" json:"mtu,omitempty" validate:"omitempty,mtu"` diff --git a/pkg/cloudapi/compute/update.go b/pkg/cloudapi/compute/update.go index 4b7d464..21afc89 100644 --- a/pkg/cloudapi/compute/update.go +++ b/pkg/cloudapi/compute/update.go @@ -52,6 +52,22 @@ type UpdateRequest struct { // Recommended isolated CPUs. Field is ignored if compute.cpupin=False or compute.pinned=False // Required: false PreferredCPU []int64 `url:"preferredCpu,omitempty" json:"preferredCpu,omitempty" validate:"omitempty,preferredCPU"` + + // VM type linux, windows or unknown + // Required: false + LoaderType string `url:"loaderType,omitempty" json:"loaderType,omitempty" validate:"omitempty,loaderType"` + + // Boot type of image bios or uefi + // Required: false + BootType string `url:"bootType,omitempty" json:"bootType,omitempty" validate:"omitempty,imageBootType"` + + // Select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming. + // 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"` } // Update updates some properties of the compute diff --git a/pkg/cloudapi/disks/create.go b/pkg/cloudapi/disks/create.go index 7568e29..ab894cb 100644 --- a/pkg/cloudapi/disks/create.go +++ b/pkg/cloudapi/disks/create.go @@ -3,8 +3,9 @@ package disks import ( "context" "net/http" - "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" ) // CreateRequest struct to create disk @@ -13,10 +14,6 @@ type CreateRequest struct { // Required: true AccountID uint64 `url:"accountId" json:"accountId" validate:"required"` - // ID of the grid (platform) - // Required: true - GID uint64 `url:"gid" json:"gid" validate:"required"` - // Name of disk // Required: true Name string `url:"name" json:"name" validate:"required"` @@ -29,17 +26,6 @@ type CreateRequest struct { // Required: false Size uint64 `url:"size,omitempty" json:"size,omitempty"` - // Type of disk - // - B=Boot - // - D=Data - // - T=Temp - // Required: true - Type string `url:"type" json:"type" validate:"diskType"` - - // Size in GB default is 0 - // Required: false - SSDSize uint64 `url:"ssdSize,omitempty" json:"ssdSize,omitempty"` - // Max IOPS disk can perform defaults to 2000 // Required: false IOPS uint64 `url:"iops,omitempty" json:"iops,omitempty"` diff --git a/pkg/cloudapi/disks/filter_test.go b/pkg/cloudapi/disks/filter_test.go index 8b72929..9e46355 100644 --- a/pkg/cloudapi/disks/filter_test.go +++ b/pkg/cloudapi/disks/filter_test.go @@ -35,9 +35,9 @@ var disks = ListDisks{ ParentID: 0, PCISlot: 6, Pool: "vmstor", - PresentTo: []uint64{ - 27, - }, + //PresentTo: []uint64{ + // 27, + //}, PurgeTime: 0, ResID: "sample", ResName: "sample", @@ -78,10 +78,10 @@ var disks = ListDisks{ ParentID: 0, PCISlot: 6, Pool: "vmstor", - PresentTo: []uint64{ - 27, - 27, - }, + //PresentTo: []uint64{ + // 27, + // 27, + //}, PurgeTime: 0, ResID: "sample", ResName: "sample", @@ -211,9 +211,9 @@ var searchDisks = ListSearchDisks{ ParentID: 0, PCISlot: 6, Pool: "vmstor", - PresentTo: []uint64{ - 27, - }, + //PresentTo: []uint64{ + // 27, + //}, PurgeTime: 0, ResID: "sample", ResName: "sample", @@ -254,10 +254,10 @@ var searchDisks = ListSearchDisks{ ParentID: 0, PCISlot: 6, Pool: "vmstor", - PresentTo: []uint64{ - 27, - 27, - }, + //PresentTo: []uint64{ + // 27, + // 27, + //}, PurgeTime: 0, ResID: "sample", ResName: "sample", @@ -393,7 +393,7 @@ var unattachedDisks = ListDisksUnattached{ Password: "", PCISlot: -1, Pool: "data05", - PresentTo: []uint64{}, + PresentTo: map[string]uint64{}, PurgeAttempts: 0, PurgeTime: 0, RealityDeviceNumber: 0, @@ -445,10 +445,10 @@ var unattachedDisks = ListDisksUnattached{ Password: "", PCISlot: -1, Pool: "data05", - PresentTo: []uint64{ - 27, - 27, - }, + //PresentTo: []uint64{ + // 27, + // 27, + //}, PurgeAttempts: 0, PurgeTime: 0, RealityDeviceNumber: 0, diff --git a/pkg/cloudapi/disks/models.go b/pkg/cloudapi/disks/models.go index 2838b65..923c6b0 100644 --- a/pkg/cloudapi/disks/models.go +++ b/pkg/cloudapi/disks/models.go @@ -14,9 +14,15 @@ type ItemDisk struct { // Computes Computes map[string]string `json:"computes"` + //Created by + CreatedBy string `json:"createdBy"` + // Created time CreatedTime uint64 `json:"createdTime"` + // Deleted by + DeletedBy string `json:"deletedBy"` + // Deleted time DeletedTime uint64 `json:"deletedTime"` @@ -50,6 +56,9 @@ type ItemDisk struct { // Machine name MachineName string `json:"machineName"` + // Milestones + Milestones uint64 `json:"milestones"` + // Name Name string `json:"name"` @@ -69,7 +78,7 @@ type ItemDisk struct { Pool string `json:"pool"` // Present to - PresentTo []uint64 `json:"presentTo"` + PresentTo map[string]uint64 `json:"presentTo"` // Purge time PurgeTime uint64 `json:"purgeTime"` @@ -95,6 +104,9 @@ type ItemDisk struct { // SepID SepID uint64 `json:"sepId"` + // Size available + SizeAvailable uint64 `json:"sizeAvailable"` + // Size max SizeMax uint64 `json:"sizeMax"` @@ -115,6 +127,12 @@ type ItemDisk struct { // Virtual machine ID VMID uint64 `json:"vmid"` + + // Update time + UpdatedTime uint64 `json:"updatedTime"` + + // Updated by + UpdatedBy string `json:"updatedBy"` } type ItemDiskUnattached struct { @@ -200,7 +218,7 @@ type ItemDiskUnattached struct { Pool string `json:"pool"` // Present to - PresentTo []uint64 `json:"presentTo"` + PresentTo map[string]uint64 `json:"presentTo"` // Purge attempts PurgeAttempts uint64 `json:"purgeAttempts"` @@ -354,9 +372,15 @@ type RecordDisk struct { // Computes Computes map[string]string `json:"computes"` + // Created by + CreatedBy string `json:"createdBy"` + // Created time CreatedTime uint64 `json:"createdTime"` + // Deleted by + DeletedBy string `json:"deletedBy"` + // Deleted time DeletedTime uint64 `json:"deletedTime"` @@ -384,6 +408,15 @@ type RecordDisk struct { // IOTune IOTune IOTune `json:"iotune"` + // Machine ID + MachineID uint64 `json:"machineId"` + + // Machine name + MachineName string `json:"machineName"` + + // Milestones + Milestones uint64 `json:"milestones"` + // Name Name string `json:"name"` @@ -403,7 +436,7 @@ type RecordDisk struct { Pool string `json:"pool"` // Present to - PresentTo []uint64 `json:"presentTo"` + PresentTo map[string]uint64 `json:"presentTo"` // Purge time PurgeTime uint64 `json:"purgeTime"` @@ -429,6 +462,9 @@ type RecordDisk struct { // Shareable Shareable bool `json:"shareable"` + // Size available + SizeAvailable uint64 `json:"sizeAvailable"` + // Size max SizeMax uint64 `json:"sizeMax"` @@ -449,6 +485,12 @@ type RecordDisk struct { // Virtual machine ID VMID uint64 `json:"vmid"` + + // Update time + UpdatedTime uint64 `json:"updatedTime"` + + // Updated by + UpdatedBy string `json:"updatedBy"` } type ItemReplication struct { diff --git a/pkg/cloudapi/extnet/list.go b/pkg/cloudapi/extnet/list.go index 32ea7f9..e14d313 100644 --- a/pkg/cloudapi/extnet/list.go +++ b/pkg/cloudapi/extnet/list.go @@ -49,6 +49,10 @@ type ListRequest struct { // Page size // Required: false Size uint64 `url:"size,omitempty" json:"size,omitempty"` + + //openVswitch bridge name + //Required: false + OVSBridge string `url:"ovsBridge,omitempty" json:"ovsBridge,omitempty"` } // List gets list of all available external networks as a ListExtNets struct diff --git a/pkg/cloudapi/extnet/models.go b/pkg/cloudapi/extnet/models.go index cb52015..8911f61 100644 --- a/pkg/cloudapi/extnet/models.go +++ b/pkg/cloudapi/extnet/models.go @@ -202,6 +202,9 @@ type RecordExtNet struct { // Network ID NetworkID uint64 `json:"networkId"` + // NTP + NTP []string `json:"ntp"` + // OVS Bridge OVSBridge string `json:"ovsBridge"` diff --git a/pkg/cloudapi/image/models.go b/pkg/cloudapi/image/models.go index b04df24..fe455e2 100644 --- a/pkg/cloudapi/image/models.go +++ b/pkg/cloudapi/image/models.go @@ -162,7 +162,7 @@ type RecordImage struct { Pool string `json:"pool"` // Present to - PresentTo []uint64 `json:"presentTo"` + PresentTo map[string]uint64 `json:"presentTo"` // ProviderName ProviderName string `json:"provider_name"` @@ -185,6 +185,9 @@ type RecordImage struct { // Size Size uint64 `json:"size"` + // snapshot ID + SnapshotID string `json:"snapshotId"` + // Status Status string `json:"status"` diff --git a/pkg/cloudapi/k8s/models.go b/pkg/cloudapi/k8s/models.go index d6df394..d5eb418 100644 --- a/pkg/cloudapi/k8s/models.go +++ b/pkg/cloudapi/k8s/models.go @@ -89,6 +89,9 @@ type RecordK8S struct { // Deleted time DeletedTime uint64 `json:"deletedTime"` + // Description + Description string `json:"desc"` + // Only external network ExtnetOnly bool `json:"extnetOnly"` diff --git a/pkg/cloudapi/kvmx86/create.go b/pkg/cloudapi/kvmx86/create.go index 90ac936..b8fe7ce 100644 --- a/pkg/cloudapi/kvmx86/create.go +++ b/pkg/cloudapi/kvmx86/create.go @@ -31,6 +31,10 @@ type Interface struct { // Used only to DPDK net type // Required: false MTU uint64 `url:"mtu,omitempty" json:"mtu,omitempty" validate:"omitempty,mtu"` + + // MAC address to assign to this VM when connecting to the specified network + // Required: false + MAC string `url:"mac,omitempty" json:"mac,omitempty" validate:"omitempty"` } // DataDisk detailed struct for DataDisks field in CreateRequest and CreateBlankRequest diff --git a/pkg/cloudapi/kvmx86/create_blank.go b/pkg/cloudapi/kvmx86/create_blank.go index 892df50..b981eb8 100644 --- a/pkg/cloudapi/kvmx86/create_blank.go +++ b/pkg/cloudapi/kvmx86/create_blank.go @@ -72,6 +72,22 @@ type CreateBlankRequest struct { // Recommended isolated CPUs. Field is ignored if compute.cpupin=False or compute.pinned=False // Required: false PreferredCPU []int64 `url:"preferredCpu,omitempty" json:"preferredCpu,omitempty" validate:"omitempty,preferredCPU"` + + // VM type linux, windows or unknown + // Required: false + LoaderType string `url:"loaderType,omitempty" json:"loaderType,omitempty" validate:"omitempty,loaderType"` + + // Boot type of image bios or uefi + // Required: false + BootType string `url:"bootType,omitempty" json:"bootType,omitempty" validate:"omitempty,imageBootType"` + + // Select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming. + // 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"` } // GetRAM returns RAM field values diff --git a/pkg/cloudapi/rg/create.go b/pkg/cloudapi/rg/create.go index 26b6c02..a994500 100644 --- a/pkg/cloudapi/rg/create.go +++ b/pkg/cloudapi/rg/create.go @@ -71,10 +71,6 @@ type CreateRequest struct { // External IP address // Required: false ExtIP string `url:"extIp,omitempty" json:"extIp,omitempty"` - - // Register computes in registration system - // Required: false - RegisterComputes bool `url:"registerComputes,omitempty" json:"registerComputes,omitempty"` } // Create creates resource group diff --git a/pkg/cloudapi/rg/update.go b/pkg/cloudapi/rg/update.go index e80cab1..21448ac 100644 --- a/pkg/cloudapi/rg/update.go +++ b/pkg/cloudapi/rg/update.go @@ -42,10 +42,6 @@ type UpdateRequest struct { // Required: false MaxNumPublicIP int64 `url:"maxNumPublicIP,omitempty" json:"maxNumPublicIP,omitempty"` - // Register computes in registration system - // Required: false - RegisterComputes bool `url:"registerComputes,omitempty" json:"registerComputes,omitempty"` - // List of strings with pools i.e.: ["sep1_poolName1", "sep2_poolName2", etc] // Required: false UniqPools []string `url:"uniqPools,omitempty" json:"uniqPools,omitempty"` diff --git a/pkg/cloudapi/sep.go b/pkg/cloudapi/sep.go new file mode 100644 index 0000000..c0595ed --- /dev/null +++ b/pkg/cloudapi/sep.go @@ -0,0 +1,8 @@ +package cloudapi + +import "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/sep" + +// Accessing the SEP method group +func (cb *CloudAPI) SEP() *sep.SEP { + return sep.New(cb.client) +} diff --git a/pkg/cloudapi/sep/filter.go b/pkg/cloudapi/sep/filter.go new file mode 100644 index 0000000..b97bd45 --- /dev/null +++ b/pkg/cloudapi/sep/filter.go @@ -0,0 +1,83 @@ +package sep + +// FilterBySEPID returns ListAvailableSEP with the specified SEPID. +func (sl ListAvailableSEP) FilterBySEPID(sepID uint64) ListAvailableSEP { + predicate := func(sd SEPData) bool { + return sd.SEPID == sepID + } + + return sl.FilterFunc(predicate) +} + +// FilterBySEPName returns ListAvailableSEP with the specified SEPName. +func (sl ListAvailableSEP) FilterBySEPName(SEPName string) ListAvailableSEP { + predicate := func(sd SEPData) bool { + return sd.SEPName == SEPName + } + + return sl.FilterFunc(predicate) +} + +// FilterBySEPType returns ListAvailableSEP with the specified SEPType. +func (sl ListAvailableSEP) FilterBySEPType(SEPType string) ListAvailableSEP { + predicate := func(sd SEPData) bool { + return sd.SEPType == SEPType + } + + return sl.FilterFunc(predicate) +} + +// FilterByPoolType returns ListAvailableSEP where at least one pool has the specified type. +func (sl ListAvailableSEP) FilterByPoolType(poolType string) ListAvailableSEP { + predicate := func(sd SEPData) bool { + for _, pool := range sd.Pools { + for _, pt := range pool.Types { + if pt == poolType { + return true + } + } + } + return false + } + + return sl.FilterFunc(predicate) +} + +// FilterBySystemPool returns ListAvailableSEP where at least one pool is a system pool. +func (sl ListAvailableSEP) FilterBySystemPool(isSystem bool) ListAvailableSEP { + predicate := func(sd SEPData) bool { + for _, pool := range sd.Pools { + if pool.System == isSystem { + return true + } + } + return false + } + + return sl.FilterFunc(predicate) +} + +// FilterFunc allows filtering ListAvailableSEP based on a user-defined predicate. +func (sl ListAvailableSEP) FilterFunc(predicate func(SEPData) bool) ListAvailableSEP { + var result ListAvailableSEP + + for _, item := range sl.Data { + if predicate(item) { + result.Data = append(result.Data, item) + } + } + + result.EntryCount = uint64(len(result.Data)) + + return result +} + +// FindOne returns the first found SEPData. +// If nothing is found, returns an empty struct. +func (sl ListAvailableSEP) FindOne() SEPData { + if len(sl.Data) == 0 { + return SEPData{} + } + + return sl.Data[0] +} diff --git a/pkg/cloudapi/sep/filter_test.go b/pkg/cloudapi/sep/filter_test.go new file mode 100644 index 0000000..979f907 --- /dev/null +++ b/pkg/cloudapi/sep/filter_test.go @@ -0,0 +1,134 @@ +package sep + +import ( + "testing" +) + +var seps = ListAvailableSEP{ + EntryCount: 3, + Data: []SEPData{ + { + SEPID: 1, + SEPName: "sep_1", + SEPType: "TATLIN", + Pools: []Pool{ + { + Name: "pool_1", + Types: []string{"DES"}, + System: false, + }, + }, + }, + { + SEPID: 2, + SEPName: "sep_2", + SEPType: "SHARED", + Pools: []Pool{ + { + Name: "pool_2", + Types: []string{"DES"}, + System: true, + }, + }, + }, + { + SEPID: 3, + SEPName: "sep_3", + SEPType: "DES", + Pools: []Pool{ + { + Name: "pool_3", + Types: []string{"DES"}, + System: false, + }, + }, + }, + }, +} + +func TestFilterBySEPID(t *testing.T) { + actual := seps.FilterBySEPID(1).FindOne() + + if actual.SEPID != 1 { + t.Fatal("expected SEPID 1, found: ", actual.SEPID) + } +} + +func TestFilterBySEPName(t *testing.T) { + actual := seps.FilterBySEPName("sep_2").FindOne() + + if actual.SEPName != "sep_2" { + t.Fatal("expected SEPName 'sep_2', found: ", actual.SEPName) + } +} + +func TestFilterBySEPType(t *testing.T) { + actual := seps.FilterBySEPType("TATLIN").FindOne() + + if actual.SEPType != "TATLIN" { + t.Fatal("expected SEPType 'TATLIN', found: ", actual.SEPType) + } +} + +func TestFilterByPoolType(t *testing.T) { + actual := seps.FilterByPoolType("DES") + + if len(actual.Data) != 3 { + t.Fatal("expected 3 found, actual: ", len(actual.Data)) + } + + for _, item := range actual.Data { + found := false + for _, pool := range item.Pools { + for _, poolType := range pool.Types { + if poolType == "DES" { + found = true + break + } + } + if found { + break + } + } + if !found { + t.Fatal("expected Pool type 'DES', not found in SEP: ", item.SEPID) + } + } +} + +func TestFilterBySystemPool(t *testing.T) { + actual := seps.FilterBySystemPool(true) + + if len(actual.Data) != 1 { + t.Fatal("expected 1 found, actual: ", len(actual.Data)) + } + + for _, item := range actual.Data { + found := false + for _, pool := range item.Pools { + if pool.System { + found = true + break + } + } + if !found { + t.Fatal("expected System pool, not found in SEP: ", item.SEPID) + } + } +} + +func TestFilterFunc(t *testing.T) { + actual := seps.FilterFunc(func(sd SEPData) bool { + return len(sd.Pools) > 0 + }) + + if len(actual.Data) != 3 { + t.Fatal("expected 3 found, actual: ", len(actual.Data)) + } + + for _, item := range actual.Data { + if len(item.Pools) == 0 { + t.Fatal("expected Pools to contain at least 1 element, found: ", len(item.Pools)) + } + } +} diff --git a/pkg/cloudapi/sep/ids.go b/pkg/cloudapi/sep/ids.go new file mode 100644 index 0000000..aea3dea --- /dev/null +++ b/pkg/cloudapi/sep/ids.go @@ -0,0 +1,10 @@ +package sep + +// IDs gets array of SEPIDs from ListSEP struct +func (ls ListAvailableSEP) IDs() []uint64 { + res := make([]uint64, 0, len(ls.Data)) + for _, s := range ls.Data { + res = append(res, s.SEPID) + } + return res +} diff --git a/pkg/cloudapi/sep/list_available_sep_and_pools.go b/pkg/cloudapi/sep/list_available_sep_and_pools.go new file mode 100644 index 0000000..d38fe8d --- /dev/null +++ b/pkg/cloudapi/sep/list_available_sep_and_pools.go @@ -0,0 +1,52 @@ +package sep + +import ( + "context" + "encoding/json" + "net/http" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// ListAvailableSEPAndPoolsRequest struct to get dict with entry count and list of dict with SEPs and pools details accessible by the Account and RG +type ListAvailableSEPAndPoolsRequest struct { + // Account ID + // Required: true + AccountID uint64 `url:"account_id" json:"account_id" validate:"required"` + + // RG ID + // Required: false + RGID uint64 `url:"rg_id,omitempty" json:"rg_id,omitempty"` +} + +// ListAvailableSEPAndPools get dict with entry count and list of dict with SEPs and pools details accessible by the Account and RG +func (s SEP) ListAvailableSEPAndPools(ctx context.Context, req ListAvailableSEPAndPoolsRequest) (*ListAvailableSEP, error) { + + res, err := s.ListAvailableSEPAndPoolsRaw(ctx, req) + if err != nil { + return nil, err + } + + list := ListAvailableSEP{} + + err = json.Unmarshal(res, &list) + if err != nil { + return nil, err + } + + return &list, nil +} + +// ListRaw gets list as an array of bytes +func (s SEP) ListAvailableSEPAndPoolsRaw(ctx context.Context, req ListAvailableSEPAndPoolsRequest) ([]byte, error) { + + err := validators.ValidateRequest(req) + if err != nil { + return nil, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudapi/sep/listAvailableSepAndPools" + + res, err := s.client.DecortApiCall(ctx, http.MethodPost, url, req) + return res, err +} diff --git a/pkg/cloudapi/sep/models.go b/pkg/cloudapi/sep/models.go new file mode 100644 index 0000000..e32e540 --- /dev/null +++ b/pkg/cloudapi/sep/models.go @@ -0,0 +1,34 @@ +package sep + +type Pool struct { + // Pool name + Name string `json:"name"` + + // Pool types + Types []string `json:"types"` + + // System + System bool `json:"system"` +} + +type SEPData struct { + // SEP ID + SEPID uint64 `json:"sepId"` + + // SEP name + SEPName string `json:"sepName"` + + // Sep type + SEPType string `json:"sepType"` + + // Pools + Pools []Pool `json:"pools"` +} + +type ListAvailableSEP struct { + // Entry count + EntryCount uint64 `json:"entryCount"` + + // Data + Data []SEPData `json:"data"` +} diff --git a/pkg/cloudapi/sep/sep.go b/pkg/cloudapi/sep/sep.go new file mode 100644 index 0000000..aca77ef --- /dev/null +++ b/pkg/cloudapi/sep/sep.go @@ -0,0 +1,18 @@ +// Operator actions for handling interventions on a storage endpoint provider +package sep + +import ( + "repository.basistech.ru/BASIS/decort-golang-sdk/interfaces" +) + +// Structure for creating request to storage endpoint provider +type SEP struct { + client interfaces.Caller +} + +// Builder for SEP endpoints +func New(client interfaces.Caller) *SEP { + return &SEP{ + client: client, + } +} diff --git a/pkg/cloudapi/sep/serialize.go b/pkg/cloudapi/sep/serialize.go new file mode 100644 index 0000000..8c52672 --- /dev/null +++ b/pkg/cloudapi/sep/serialize.go @@ -0,0 +1,43 @@ +package sep + +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 (lsep ListAvailableSEP) Serialize(params ...string) (serialization.Serialized, error) { + if len(lsep.Data) == 0 { + return []byte{}, nil + } + + if len(params) > 1 { + prefix := params[0] + indent := params[1] + + return json.MarshalIndent(lsep, prefix, indent) + } + + return json.Marshal(lsep) +} + +// 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 (rsep SEPData) Serialize(params ...string) (serialization.Serialized, error) { + if len(params) > 1 { + prefix := params[0] + indent := params[1] + + return json.MarshalIndent(rsep, prefix, indent) + } + + return json.Marshal(rsep) +} diff --git a/pkg/cloudapi/user/get_audit.go b/pkg/cloudapi/user/get_audit.go index 43287dc..3253c88 100644 --- a/pkg/cloudapi/user/get_audit.go +++ b/pkg/cloudapi/user/get_audit.go @@ -28,6 +28,10 @@ type GetAuditRequest struct { // Required: false MinStatusCode uint64 `url:"minStatusCode,omitempty" json:"minStatusCode,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"` diff --git a/pkg/cloudapi/vins/list.go b/pkg/cloudapi/vins/list.go index a8e799b..631c40a 100644 --- a/pkg/cloudapi/vins/list.go +++ b/pkg/cloudapi/vins/list.go @@ -18,6 +18,10 @@ type ListRequest struct { // Required: false Name string `url:"name,omitempty" json:"name,omitempty"` + // Find by status + // Required: false + Status string `url:"status,omitempty" json:"status,omitempty"` + // Find by account ID // Required: false AccountID uint64 `url:"accountId,omitempty" json:"accountId,omitempty"` diff --git a/pkg/cloudbroker/account/create.go b/pkg/cloudbroker/account/create.go index 97e1530..6fca46f 100644 --- a/pkg/cloudbroker/account/create.go +++ b/pkg/cloudbroker/account/create.go @@ -14,6 +14,10 @@ type CreateRequest struct { // Required: true Name string `url:"name" json:"name" validate:"required"` + // Description + // Required: false + Description string `url:"desc,omitempty" json:"desc,omitempty"` + // Name of the account // Required: true Username string `url:"username" json:"username" validate:"required"` @@ -56,7 +60,7 @@ type CreateRequest struct { UniqPools []string `url:"uniqPools,omitempty" json:"uniqPools,omitempty"` // Advanced compute features, - // one of: hugepages, numa, cpupin, vfnic + // one of: hugepages, numa, cpupin, vfnic, dpdk, changemac // Required: false ComputeFeatures []string `url:"computeFeatures,omitempty" json:"computeFeatures,omitempty" validate:"omitempty,computeFeatures"` } diff --git a/pkg/cloudbroker/account/disable.go b/pkg/cloudbroker/account/disable.go index a4f62da..20a3ed4 100644 --- a/pkg/cloudbroker/account/disable.go +++ b/pkg/cloudbroker/account/disable.go @@ -13,6 +13,10 @@ type DisableRequest struct { // ID of account // Required: true AccountID uint64 `url:"accountId" json:"accountId" validate:"required"` + + // Reason of disabling + // Required: false + Reason string `url:"reason,omitempty" json:"reason,omitempty"` } // Disable disables an account diff --git a/pkg/cloudbroker/account/disable_accounts.go b/pkg/cloudbroker/account/disable_accounts.go index a5ee191..6b91b92 100644 --- a/pkg/cloudbroker/account/disable_accounts.go +++ b/pkg/cloudbroker/account/disable_accounts.go @@ -12,6 +12,10 @@ type DisableAccountsRequest struct { // IDs of accounts // Required: true AccountIDs []uint64 `url:"accountIds" json:"accountIds" validate:"min=1"` + + // Reason of disabling + // Required: false + Reason string `url:"reason,omitempty" json:"reason,omitempty"` } // DisableAccounts disables accounts diff --git a/pkg/cloudbroker/account/models.go b/pkg/cloudbroker/account/models.go index de03ff0..e506d2f 100644 --- a/pkg/cloudbroker/account/models.go +++ b/pkg/cloudbroker/account/models.go @@ -170,6 +170,9 @@ type InfoAccount struct { // Display name DisplayName string `json:"displayname"` + // Description + Description string `json:"desc"` + // GUID GUID uint64 `json:"guid"` @@ -476,6 +479,9 @@ type ItemRG struct { // Deleted time DeletedTime uint64 `json:"deletedTime"` + // Description + Description string `json:"desc"` + // ID ID uint64 `json:"id"` diff --git a/pkg/cloudbroker/account/restore.go b/pkg/cloudbroker/account/restore.go index c12834e..ec2e601 100644 --- a/pkg/cloudbroker/account/restore.go +++ b/pkg/cloudbroker/account/restore.go @@ -12,6 +12,10 @@ type RestoreRequest struct { // ID an account // Required: true AccountID uint64 `url:"accountId" json:"accountId" validate:"required"` + + // Reason of disabling + // Required: false + Reason string `url:"reason,omitempty" json:"reason,omitempty"` } // Restore restores a deleted account diff --git a/pkg/cloudbroker/account/update.go b/pkg/cloudbroker/account/update.go index d698745..9803f8c 100644 --- a/pkg/cloudbroker/account/update.go +++ b/pkg/cloudbroker/account/update.go @@ -14,6 +14,10 @@ type UpdateRequest struct { // Required: true AccountID uint64 `url:"accountId" json:"accountId" validate:"required"` + // Description + // Required: false + Description string `url:"desc,omitempty" json:"desc,omitempty"` + // Name of the account // Required: false Name string `url:"name" json:"name"` diff --git a/pkg/cloudbroker/account/update_compute_features.go b/pkg/cloudbroker/account/update_compute_features.go index 6bd659a..35e248d 100644 --- a/pkg/cloudbroker/account/update_compute_features.go +++ b/pkg/cloudbroker/account/update_compute_features.go @@ -15,7 +15,7 @@ type UpdateComputeFeaturesRequest struct { AccountID uint64 `url:"accountId" json:"accountId" validate:"required"` // Advanced compute features, - // one of: hugepages, numa, cpupin, vfnic + // one of: hugepages, numa, cpupin, vfnic, dpdk, changemac // Required: false ComputeFeatures []string `url:"computeFeatures,omitempty" json:"computeFeatures,omitempty" validate:"omitempty,computeFeatures"` } diff --git a/pkg/cloudbroker/apiaccess/api_find.go b/pkg/cloudbroker/apiaccess/api_find.go index e79ed90..e27dc8c 100644 --- a/pkg/cloudbroker/apiaccess/api_find.go +++ b/pkg/cloudbroker/apiaccess/api_find.go @@ -10,10 +10,20 @@ import ( // APIFindRequest struct for finding apiaccess groups. type APIFindRequest struct { - // API function to find - // Example: cloudbroker/k8s/create - // Required: true - APIName string `url:"apiName" json:"apiName" validate:"required"` + //API group to find (cloudbroker, cloudapi, etc) + //Available values : cloudapi, cloudbroker, system + //Required: true + APIGroup string `url:"api_group" json:"api_group" validate:"required,apiGroup"` + + //API object to find (compute, vins, etc ) + //Required: true + APIObject string `url:"api_object" json:"api_object" validate:"required"` + + //API endpoint to find (delete, create, etc) + //Required: true + APIMethod string `url:"api_method" json:"api_method" valudate:"required"` + + } // APIFind outputs a list of apiaccess groups that mention the specified API function. diff --git a/pkg/cloudbroker/apiaccess/apis_exclude.go b/pkg/cloudbroker/apiaccess/apis_exclude.go index ac141ee..f23949c 100644 --- a/pkg/cloudbroker/apiaccess/apis_exclude.go +++ b/pkg/cloudbroker/apiaccess/apis_exclude.go @@ -15,7 +15,7 @@ type APIString string type APIsExcludeRequest struct { // APIAccess group ID // Required: true - APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"` + APIAccessID uint64 `url:"apiaccess_id" json:"apiaccess_id" validate:"required"` // APIs to remove from APIAccess group // Required: true diff --git a/pkg/cloudbroker/apiaccess/apis_include.go b/pkg/cloudbroker/apiaccess/apis_include.go index 0f0af02..4cbef29 100644 --- a/pkg/cloudbroker/apiaccess/apis_include.go +++ b/pkg/cloudbroker/apiaccess/apis_include.go @@ -12,7 +12,7 @@ import ( type APIsIncludeRequest struct { // APIAccess group ID. // Required: true - APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"` + APIAccessID uint64 `url:"apiaccess_id" json:"apiaccess_id" validate:"required"` // APIs to add to APIAccess group. // Required: true diff --git a/pkg/cloudbroker/apiaccess/copy.go b/pkg/cloudbroker/apiaccess/copy.go index 551fefc..baff0ca 100644 --- a/pkg/cloudbroker/apiaccess/copy.go +++ b/pkg/cloudbroker/apiaccess/copy.go @@ -12,7 +12,7 @@ import ( type CopyRequest struct { // ID of the API access group to make copy from // Required: true - APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"` + APIAccessID uint64 `url:"apiaccess_id" json:"apiaccess_id" validate:"required"` // Name of the target API access group, which will be created on successful copy // Required: true diff --git a/pkg/cloudbroker/apiaccess/delete.go b/pkg/cloudbroker/apiaccess/delete.go index 2ee4d14..bcca061 100644 --- a/pkg/cloudbroker/apiaccess/delete.go +++ b/pkg/cloudbroker/apiaccess/delete.go @@ -12,7 +12,7 @@ import ( type DeleteRequest struct { // APIAccess group ID. // Required: true - APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"` + APIAccessID uint64 `url:"apiaccess_id" json:"apiaccess_id" validate:"required"` // Set True to delete apiaccess group with attached users. // Required: false diff --git a/pkg/cloudbroker/apiaccess/desc_update.go b/pkg/cloudbroker/apiaccess/desc_update.go index 081056f..1434aa9 100644 --- a/pkg/cloudbroker/apiaccess/desc_update.go +++ b/pkg/cloudbroker/apiaccess/desc_update.go @@ -12,7 +12,7 @@ import ( type DescUpdateRequest struct { // APIAccess group ID. // Required: true - APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"` + APIAccessID uint64 `url:"apiaccess_id" json:"apiaccess_id" validate:"required"` // New description to set for the apiaccess group. // Required: true diff --git a/pkg/cloudbroker/apiaccess/get.go b/pkg/cloudbroker/apiaccess/get.go index b225673..e0b52f3 100644 --- a/pkg/cloudbroker/apiaccess/get.go +++ b/pkg/cloudbroker/apiaccess/get.go @@ -12,7 +12,7 @@ import ( type GetRequest struct { // APIAccess group ID. // Required: true - APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"` + APIAccessID uint64 `url:"apiaccess_id" json:"apiaccess_id" validate:"required"` } // Get gets apiaccess group as an ItemAPIAccess struct diff --git a/pkg/cloudbroker/apiaccess/get_pre_groups.go b/pkg/cloudbroker/apiaccess/get_default.go similarity index 50% rename from pkg/cloudbroker/apiaccess/get_pre_groups.go rename to pkg/cloudbroker/apiaccess/get_default.go index 0315f4d..88254cd 100644 --- a/pkg/cloudbroker/apiaccess/get_pre_groups.go +++ b/pkg/cloudbroker/apiaccess/get_default.go @@ -6,11 +6,11 @@ import ( "net/http" ) -// GetPreGroups gets list of pre default groups from spec -func (a APIAccess) GetPreGroups(ctx context.Context) (map[string]APIsEndpoints, error) { - url := "/cloudbroker/apiaccess/getPreGroups" +// GetDefault gets default apiaccess group +func (a APIAccess) GetDefault(ctx context.Context) (*ItemAPIAccessDefault, error) { + url := "/cloudbroker/apiaccess/getDefault" - info := make(map[string]APIsEndpoints) + info := ItemAPIAccessDefault{} res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, nil) if err != nil { @@ -22,5 +22,5 @@ func (a APIAccess) GetPreGroups(ctx context.Context) (map[string]APIsEndpoints, return nil, err } - return info, nil + return &info, nil } diff --git a/pkg/cloudbroker/apiaccess/list.go b/pkg/cloudbroker/apiaccess/list.go index ee723bf..eee1a80 100644 --- a/pkg/cloudbroker/apiaccess/list.go +++ b/pkg/cloudbroker/apiaccess/list.go @@ -22,21 +22,18 @@ type ListRequest struct { // Required: false Status string `url:"status,omitempty" json:"status,omitempty"` - // Find by created actor - // Required: false - CreatedBy string `url:"createdBy,omitempty" json:"createdBy,omitempty"` // Find by created after time (unix timestamp) // Required: false - CreatedAfter uint64 `url:"createdAfter,omitempty" json:"createdAfter,omitempty"` + CreatedAfter uint64 `url:"created_after,omitempty" json:"created_after,omitempty"` // Find by created before time (unix timestamp) // Required: false - CreatedBefore uint64 `url:"createdBefore,omitempty" json:"createdBefore,omitempty"` + CreatedBefore uint64 `url:"created_before,omitempty" json:"created_before,omitempty"` // Sort by one of supported fields, format +|-(field) // Required: false - SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"` + SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty" validate:"omitempty,sortBy"` // Page number // Required: false diff --git a/pkg/cloudbroker/apiaccess/list_deleted.go b/pkg/cloudbroker/apiaccess/list_deleted.go deleted file mode 100644 index e93bf5c..0000000 --- a/pkg/cloudbroker/apiaccess/list_deleted.go +++ /dev/null @@ -1,48 +0,0 @@ -package apiaccess - -import ( - "context" - "encoding/json" - "net/http" - - "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" -) - -// ListDeletedRequest struct for getting list of all deleted apiaccess instances. -type ListDeletedRequest struct { - // 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"` -} - -// ListDeleted gets list of all deleted apiaccess instances. -func (a APIAccess) ListDeleted(ctx context.Context, req ListDeletedRequest) (*ListAPIAccess, error) { - - if err := validators.ValidateRequest(req); err != nil { - return nil, validators.ValidationErrors(validators.GetErrors(err)) - } - - url := "/cloudbroker/apiaccess/listDeleted" - - info := ListAPIAccess{} - - res, err := a.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 -} diff --git a/pkg/cloudbroker/apiaccess/models.go b/pkg/cloudbroker/apiaccess/models.go index 82b23da..4814f1e 100644 --- a/pkg/cloudbroker/apiaccess/models.go +++ b/pkg/cloudbroker/apiaccess/models.go @@ -4,23 +4,16 @@ type ItemAPIAccess struct { // APIs APIs APIsEndpoints `json:"apis"` - // Created by - CreatedBy string `json:"createdBy"` - - // Created time - CreatedTime uint64 `json:"createdTime"` + CreatedTime uint64 `json:"created_at"` // Is default Default bool `json:"default"` - // Deleted by - DeletedBy string `json:"deletedBy"` - // Deleted time - DeletedTime uint64 `json:"deletedTime"` + DeletedTime uint64 `json:"deleted_at"` // Description - Description string `json:"decs"` + Description string `json:"desc"` // GID GID uint64 `json:"gid"` @@ -31,9 +24,6 @@ type ItemAPIAccess struct { // ID ID uint64 `json:"id"` - // Milestones - Milestones uint64 `json:"milestones"` - // Name Name string `json:"name"` @@ -43,11 +33,46 @@ type ItemAPIAccess struct { // Status Status string `json:"status"` - //Updated by - UpdatedBy string `json:"updatedBy"` - // Updated time - UpdatedTime uint64 `json:"updatedTime"` + UpdatedTime uint64 `json:"updated_at"` +} + +type ItemAPIAccessDefault struct { + // APIs + APIs APIsEndpoints `json:"apis"` + + // Created at + CreatedAt uint64 `json:"created_at"` + + // Is default + Default bool `json:"default"` + + // Deleted at + DeletedAt uint64 `json:"deleted_at"` + + // Description + Description string `json:"decs"` + + // GID + GID uint64 `json:"gid"` + + // GUID + GUID uint64 `json:"guid"` + + // ID + ID uint64 `json:"id"` + + // Name + Name string `json:"name"` + + // Protected + Protected bool `json:"protected"` + + // Status + Status string `json:"status"` + + //Updated at + UpdatedAt uint64 `json:"updated_at"` } type ListAPIAccess struct { @@ -77,6 +102,7 @@ type CloudAPIEndpoints struct { Compute []string `json:"compute,omitempty"` ComputeCI []string `json:"computeci,omitempty"` Disks []string `json:"disks,omitempty"` + DPDK []string `json:"dpdk,omitempty"` ExtNet []string `json:"extnet,omitempty"` FLIPGroup []string `json:"flipgroup,omitempty"` GPU []string `json:"gpu,omitempty"` @@ -115,6 +141,7 @@ type CloudBrokerEndpoints struct { Desnode []string `json:"desnode,omitempty"` Diagnostics []string `json:"diagnostics,omitempty"` Disks []string `json:"disks,omitempty"` + DPDK []string `json:"dpdk,omitempty"` Eco []string `json:"eco,omitempty"` ExtNet []string `json:"extnet,omitempty"` FlIPgroup []string `json:"flipgroup,omitempty"` diff --git a/pkg/cloudbroker/apiaccess/set_default.go b/pkg/cloudbroker/apiaccess/set_default.go index 7f3f2ab..51ff84b 100644 --- a/pkg/cloudbroker/apiaccess/set_default.go +++ b/pkg/cloudbroker/apiaccess/set_default.go @@ -12,7 +12,7 @@ import ( type SetDefaultRequest struct { // APIAccess group ID // Required: true - APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"` + APIAccessID uint64 `url:"apiaccess_id" json:"apiaccess_id" validate:"required"` } // SetDefault sets current apiaccess group default. diff --git a/pkg/cloudbroker/apiaccess/subtract.go b/pkg/cloudbroker/apiaccess/subtract.go index 02780d2..1737a95 100644 --- a/pkg/cloudbroker/apiaccess/subtract.go +++ b/pkg/cloudbroker/apiaccess/subtract.go @@ -12,10 +12,10 @@ import ( // SubtractRequest struct for subtracting. type SubtractRequest struct { // ID of the API access group to subtract from. This group will contain the difference. - MinuendID uint64 `url:"minuendId" json:"minuendId" validate:"required"` + MinuendID uint64 `url:"minuend_group_id" json:"minuend_group_id" validate:"required"` // ID of the API access group which is subtracted. This group is unchanged. - SubtrahendID uint64 `url:"subtrahendId" json:"subtrahendId" validate:"required"` + SubtrahendID uint64 `url:"subtrahend_group_id" json:"subtrahend_group_id" validate:"required"` } // Subtract removes such APIs from MinuendID that match APIs from SubtrahendID. diff --git a/pkg/cloudbroker/apiaccess/union.go b/pkg/cloudbroker/apiaccess/union.go index e97160e..623c016 100644 --- a/pkg/cloudbroker/apiaccess/union.go +++ b/pkg/cloudbroker/apiaccess/union.go @@ -12,11 +12,11 @@ import ( type UnionRequest struct { // Recipient apiaccess group ID // Required: true - RecipientID uint64 `url:"recipientId" json:"recipientId" validate:"required"` + RecipientID uint64 `url:"recipient_group_id" json:"recipient_group_id" validate:"required"` // Donor apiaccess group ID // Required: true - DonorID uint64 `url:"donorId" json:"donorId" validate:"required"` + DonorID uint64 `url:"donor_group_id" json:"donor_group_id" validate:"required"` } // Union combines the API list of group #1 ("recipient") and group #2 ("donor"), diff --git a/pkg/cloudbroker/apiaccess/update.go b/pkg/cloudbroker/apiaccess/update.go index 533d9fa..2567537 100644 --- a/pkg/cloudbroker/apiaccess/update.go +++ b/pkg/cloudbroker/apiaccess/update.go @@ -13,7 +13,7 @@ import ( type UpdateRequest struct { // APIAccess group ID // Required: true - APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"` + APIAccessID uint64 `url:"apiaccess_id" json:"apiaccess_id" validate:"required"` // APIs to remove from APIAccess group // Required: false diff --git a/pkg/cloudbroker/apiaccess/user_list.go b/pkg/cloudbroker/apiaccess/user_list.go index f02e9bc..50b5da7 100644 --- a/pkg/cloudbroker/apiaccess/user_list.go +++ b/pkg/cloudbroker/apiaccess/user_list.go @@ -12,7 +12,7 @@ import ( type UserListRequest struct { // APIAccess group ID // Required: true - APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"` + APIAccessID uint64 `url:"apiaccess_id" json:"apiaccess_id" validate:"required"` // Page number // Required: false diff --git a/pkg/cloudbroker/audit/get.go b/pkg/cloudbroker/audit/get.go index 1894f85..d9ce5de 100644 --- a/pkg/cloudbroker/audit/get.go +++ b/pkg/cloudbroker/audit/get.go @@ -12,7 +12,7 @@ import ( type GetRequest struct { // Audit GUID // Required: true - AuditGuid string `url:"auditGuid" json:"auditGuid" validate:"required"` + AuditGuid string `url:"audit_guid" json:"audit_guid" validate:"required"` } // Get gets information about audit as a RecordAudit struct diff --git a/pkg/cloudbroker/audit/linked_jobs.go b/pkg/cloudbroker/audit/linked_jobs.go index ebf773e..457b2f1 100644 --- a/pkg/cloudbroker/audit/linked_jobs.go +++ b/pkg/cloudbroker/audit/linked_jobs.go @@ -12,7 +12,7 @@ import ( type LinkedJobsRequest struct { // Audit GUID // Required: true - AuditGuid string `url:"auditGuid" json:"auditGuid" validate:"required"` + AuditGuid string `url:"audit_guid" json:"audit_guid" validate:"required"` } // LinkedJobs gets information about Linked Jobs as a ListLinkedJobs struct @@ -43,4 +43,4 @@ func (a Audit) GetRawLinkedJobs(ctx context.Context, req LinkedJobsRequest) ([]b res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req) return res, err -} \ No newline at end of file +} diff --git a/pkg/cloudbroker/audit/list.go b/pkg/cloudbroker/audit/list.go index cf05fcb..26271ec 100644 --- a/pkg/cloudbroker/audit/list.go +++ b/pkg/cloudbroker/audit/list.go @@ -13,11 +13,11 @@ type ListRequest struct { // Find all audits after point in time (unixtime) // Required: false - TimestampAt uint64 `url:"timestampAt,omitempty" json:"timestampAt,omitempty"` + TimestampAt uint64 `url:"timestamp_at,omitempty" json:"timestamp_at,omitempty"` // Find all audits before point in time (unixtime) // Required: false - TimestampTo uint64 `url:"timestampTo,omitempty" json:"timestampTo,omitempty"` + TimestampTo uint64 `url:"timestamp_to,omitempty" json:"timestamp_to,omitempty"` // Find by user (Mongo RegExp supported) // Required: false @@ -27,17 +27,21 @@ type ListRequest struct { // Required: false Call string `url:"call,omitempty" json:"call,omitempty"` + // Find by request id + // Required: false + RequestID string `url:"request_id,omitempty" json:"request_id,omitempty"` + // Find by HTTP min status code // Required: false - MinStatusCode uint64 `url:"minStatusCode,omitempty" json:"minStatusCode,omitempty"` + MinStatusCode uint64 `url:"min_status_code,omitempty" json:"min_status_code,omitempty"` // Find by HTTP max status code // Required: false - MaxStatusCode uint64 `url:"maxStatusCode,omitempty" json:"maxStatusCode,omitempty"` + MaxStatusCode uint64 `url:"max_status_code,omitempty" json:"max_status_code,omitempty"` // Sort by one of supported fields, format +|-(field) // Required: false - SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"` + SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty" validate:"omitempty,sortBy"` // Page number // Required: false diff --git a/pkg/cloudbroker/audit/models.go b/pkg/cloudbroker/audit/models.go index adf0885..ef9599b 100644 --- a/pkg/cloudbroker/audit/models.go +++ b/pkg/cloudbroker/audit/models.go @@ -2,23 +2,44 @@ package audit // Main info about audit type ItemAudit struct { + // Args + Args string `json:"args"` + // Call Call string `json:"call"` // GUID GUID string `json:"guid"` + // Kwargs + Kwargs string `json:"kwargs"` + + // RemoteAddr + RemoteAddr string `json:"remote_addr"` + // Response time ResponseTime float64 `json:"responsetime"` + // Result + Result string `json:"result"` + // Status code StatusCode uint64 `json:"statuscode"` // Timestamp Timestamp float64 `json:"timestamp"` + // Timestamp End + TimestampEnd float64 `json:"timestampEnd"` + // User User string `json:"user"` + + // TTL + TTL string `json:"_ttl"` + + // Tags + Tags string `json:"tags"` } // List of audits @@ -68,6 +89,9 @@ type RecordAudit struct { // User User string `json:"user"` + + // TTL + TTL string `json:"_ttl"` } // List of Linked Jobs @@ -85,6 +109,9 @@ type ItemLinkedJobs struct { // NID NID uint64 `json:"nid"` + // Physical Node or not + PhysicalNode bool `json:"physicalNode"` + // state State string `json:"state"` diff --git a/pkg/cloudbroker/compute/change_ip.go b/pkg/cloudbroker/compute/change_ip.go index ef1017f..9fad21a 100644 --- a/pkg/cloudbroker/compute/change_ip.go +++ b/pkg/cloudbroker/compute/change_ip.go @@ -12,23 +12,23 @@ import ( type ChangeIPRequest struct { // ID of compute instance // Required: true - ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"` + ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"` // Network type // 'EXTNET' for connect to external network directly // 'VINS' for connect to ViNS // Required: true - NetType string `url:"netType" json:"netType" validate:"computeNetType"` + NetType string `url:"net_type" json:"net_type" validate:"computeNetType"` // Network ID for connect to // For EXTNET - external network ID // For VINS - VINS ID // Required: true - NetID uint64 `url:"netId" json:"netId" validate:"required"` + NetID uint64 `url:"net_id" json:"net_id" validate:"required"` // IP address to which we will change the existing one, it must be from the same subnet // Required: true - IPAddr string `url:"ipAddr" json:"ipAddr" validate:"required"` + IPAddr string `url:"ip_addr" json:"ip_addr" validate:"required"` } // ChangeIP change reserved IP for compute instance diff --git a/pkg/cloudbroker/compute/change_mac.go b/pkg/cloudbroker/compute/change_mac.go new file mode 100644 index 0000000..3389c66 --- /dev/null +++ b/pkg/cloudbroker/compute/change_mac.go @@ -0,0 +1,46 @@ +package compute + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// ChangeMACRequest struct to change MAC for network +type ChangeMACRequest struct { + // ID of compute instance + // Required: true + ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"` + + // Current mac address + // Required: true + СurrentMAC string `url:"current_mac_address" json:"current_mac_address" validate:"required"` + + // the MAC address to which we will change the existing one + // Required: true + NewMAC string `url:"new_mac_address" json:"new_mac_address" validate:"required"` +} + +// ChangeMAC change MAC for compute instance +func (c Compute) ChangeMAC(ctx context.Context, req ChangeMACRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + return false, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/compute/changeMac" + + res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/pkg/cloudbroker/compute/filter.go b/pkg/cloudbroker/compute/filter.go index 0de2d56..a38786b 100644 --- a/pkg/cloudbroker/compute/filter.go +++ b/pkg/cloudbroker/compute/filter.go @@ -168,3 +168,164 @@ func (lc ListComputes) FindOne() ItemCompute { return lc.Data[0] } + +// FilterByID returns ListDeletedComputes with specified ID. +func (lc ListDeletedComputes) FilterByID(id uint64) ListDeletedComputes { + predicate := func(ic ItemDeletedCompute) bool { + return ic.ID == id + } + + return lc.FilterFunc(predicate) +} + +// FilterByName returns ListDeletedComputes with specified Name. +func (lc ListDeletedComputes) FilterByName(name string) ListDeletedComputes { + predicate := func(ic ItemDeletedCompute) bool { + return ic.Name == name + } + + return lc.FilterFunc(predicate) +} + +// FilterByStatus returns ListDeletedComputes with specified Status. +func (lc ListDeletedComputes) FilterByStatus(status string) ListDeletedComputes { + predicate := func(ic ItemDeletedCompute) bool { + return ic.Status == status + } + + return lc.FilterFunc(predicate) +} + +// FilterByTechStatus returns ListDeletedComputes with specified TechStatus. +func (lc ListDeletedComputes) FilterByTechStatus(techStatus string) ListDeletedComputes { + predicate := func(ic ItemDeletedCompute) bool { + return ic.TechStatus == techStatus + } + + return lc.FilterFunc(predicate) +} + +// FilterByDiskID return ListDeletedComputes with specified DiskID. +func (lc ListDeletedComputes) FilterByDiskID(diskID uint64) ListDeletedComputes { + predicate := func(ic ItemDeletedCompute) bool { + for _, disk := range ic.Disks { + if disk.ID == diskID { + return true + } + } + return false + } + + return lc.FilterFunc(predicate) +} + +// FilterByK8SID returns master and worker nodes (ListDeletedComputes) inside specified K8S cluster. +func (lc ListDeletedComputes) FilterByK8SID(ctx context.Context, k8sID uint64, decortClient interfaces.Caller) (*ListDeletedComputes, error) { + caller := k8s.New(decortClient) + + req := k8s.GetRequest{ + K8SID: k8sID, + } + + cluster, err := caller.Get(ctx, req) + if err != nil { + return nil, err + } + + predicate := func(ic ItemDeletedCompute) bool { + for _, info := range cluster.K8SGroups.Masters.DetailedInfo { + if info.ID == ic.ID { + return true + } + } + + for _, worker := range cluster.K8SGroups.Workers { + for _, info := range worker.DetailedInfo { + if info.ID == ic.ID { + return true + } + } + } + + return false + } + + result := lc.FilterFunc(predicate) + + return &result, nil +} + +// K8SMasters is used to filter master nodes. Best used after FilterByK8SID function. +func (lc ListDeletedComputes) FilterByK8SMasters() ListDeletedComputes { + predicate := func(ic ItemDeletedCompute) bool { + for _, rule := range ic.AntiAffinityRules { + if rule.Value == "master" { + return true + } + } + return false + } + + return lc.FilterFunc(predicate) +} + +// K8SMasters is used to filter worker nodes. Best used after FilterByK8SID function. +func (lc ListDeletedComputes) FilterByK8SWorkers() ListDeletedComputes { + predicate := func(ic ItemDeletedCompute) bool { + for _, rule := range ic.AntiAffinityRules { + if rule.Value == "worker" { + return true + } + } + return false + } + + return lc.FilterFunc(predicate) +} + +// FilterByLBID is used to filter ListDeletedComputes used by specified Load Balancer. +func (lc ListDeletedComputes) FilterByLBID(ctx context.Context, lbID uint64, decortClient interfaces.Caller) (*ListDeletedComputes, error) { + caller := lb.New(decortClient) + + req := lb.GetRequest{ + LBID: lbID, + } + + foundLB, err := caller.Get(ctx, req) + if err != nil { + return nil, err + } + + predicate := func(ic ItemDeletedCompute) bool { + return ic.ID == foundLB.PrimaryNode.ComputeID || ic.ID == foundLB.SecondaryNode.ComputeID + } + + result := lc.FilterFunc(predicate) + + return &result, nil +} + +// FilterFunc allows filtering ListDeletedComputes based on a user-specified predicate. +func (lc ListDeletedComputes) FilterFunc(predicate func(ItemDeletedCompute) bool) ListDeletedComputes { + var result ListDeletedComputes + + for _, item := range lc.Data { + if predicate(item) { + result.Data = append(result.Data, item) + } + } + + result.EntryCount = uint64(len(result.Data)) + + return result +} + +// FindOne returns first found ItemDeletedCompute +// If none was found, returns an empty struct. +func (lc ListDeletedComputes) FindOne() ItemDeletedCompute { + if len(lc.Data) == 0 { + return ItemDeletedCompute{} + } + + return lc.Data[0] +} diff --git a/pkg/cloudbroker/compute/filter_test.go b/pkg/cloudbroker/compute/filter_test.go index ce76bd3..cca037f 100644 --- a/pkg/cloudbroker/compute/filter_test.go +++ b/pkg/cloudbroker/compute/filter_test.go @@ -9,8 +9,7 @@ var computes = ListComputes{ { Disks: []InfoDisk{ { - ID: 65191, - PCISlot: 6, + ID: 65191, }, }, InfoCompute: InfoCompute{ @@ -67,7 +66,7 @@ var computes = ListComputes{ MigrationJob: 0, Milestones: 363500, Name: "test", - Pinned: false, + PinnedToStack: 1, RAM: 4096, ReferenceID: "c7cb19ac-af4a-4067-852f-c5572949207e", Registered: true, @@ -92,8 +91,7 @@ var computes = ListComputes{ { Disks: []InfoDisk{ { - ID: 65248, - PCISlot: 6, + ID: 65248, }, }, InfoCompute: InfoCompute{ @@ -132,7 +130,7 @@ var computes = ListComputes{ MigrationJob: 0, Milestones: 363853, Name: "compute_2", - Pinned: false, + PinnedToStack: 1, RAM: 4096, ReferenceID: "a542c449-5b1c-4f90-88c5-7bb5f8ae68ff", Registered: true, @@ -248,3 +246,244 @@ func TestSortingByCPU(t *testing.T) { t.Fatal("expected 6 CPU cores, found: ", actual.Data[0].CPUs) } } + +var deleteComputes = ListDeletedComputes{ + Data: []ItemDeletedCompute{ + { + Disks: []InfoDisk{ + { + ID: 65191, + }, + }, + InfoCompute: InfoCompute{ + ACL: []interface{}{}, + AccountID: 132847, + AccountName: "std_2", + AffinityLabel: "", + AffinityRules: []ItemRule{ + { + GUID: "", + Key: "aff_key", + Mode: "ANY", + Policy: "RECOMMENDED", + Topology: "compute", + Value: "aff_val", + }, + }, + AffinityWeight: 0, + AntiAffinityRules: []ItemRule{ + { + GUID: "", + Key: "antiaff_key", + Mode: "ANY", + Policy: "RECOMMENDED", + Topology: "compute", + Value: "antiaff_val", + }, + }, + Arch: "X86_64", + BootOrder: []string{ + "hd", "cdrom", + }, + BootDiskSize: 0, + CloneReference: 0, + Clones: []uint64{}, + ComputeCIID: 0, + CPUs: 4, + CreatedBy: "timofey_tkachev_1@decs3o", + CreatedTime: 1676975175, + CustomFields: map[string]interface{}{}, + DeletedBy: "", + DeletedTime: 0, + Description: "", + Devices: nil, + Driver: "KVM_X86", + GID: 212, + GUID: 48500, + ID: 48500, + ImageID: 9884, + Interfaces: ListInterfaces{}, + LockStatus: "UNLOCKED", + ManagerID: 0, + ManagerType: "", + MigrationJob: 0, + Milestones: 363500, + Name: "test", + RAM: 4096, + ReferenceID: "c7cb19ac-af4a-4067-852f-c5572949207e", + Registered: true, + ResName: "compute-48500", + RGID: 79724, + RGName: "std_broker2", + SnapSets: ListSnapshots{}, + StatelessSEPID: 0, + StatelessSEPType: "", + Status: "ENABLED", + Tags: map[string]interface{}{}, + TechStatus: "STOPPED", + TotalDiskSize: 2, + UpdatedBy: "", + UpdatedTime: 1677058904, + UserManaged: true, + VGPUs: []uint64{}, + VINSConnected: 0, + VirtualImageID: 0, + }, + }, + { + Disks: []InfoDisk{ + { + ID: 65248, + }, + }, + InfoCompute: InfoCompute{ + ACL: []interface{}{}, + AccountID: 132848, + AccountName: "std_broker", + AffinityLabel: "", + AffinityRules: []ItemRule{}, + AffinityWeight: 0, + AntiAffinityRules: []ItemRule{}, + Arch: "X86_64", + BootOrder: []string{ + "hd", "cdrom", + }, + BootDiskSize: 0, + CloneReference: 0, + Clones: []uint64{}, + ComputeCIID: 0, + CPUs: 6, + CreatedBy: "timofey_tkachev_1@decs3o", + CreatedTime: 1677579436, + CustomFields: map[string]interface{}{}, + DeletedBy: "", + DeletedTime: 0, + Description: "", + Devices: nil, + Driver: "KVM_X86", + GID: 212, + GUID: 48556, + ID: 48556, + ImageID: 9884, + Interfaces: ListInterfaces{}, + LockStatus: "UNLOCKED", + ManagerID: 0, + ManagerType: "", + MigrationJob: 0, + Milestones: 363853, + Name: "compute_2", + RAM: 4096, + ReferenceID: "a542c449-5b1c-4f90-88c5-7bb5f8ae68ff", + Registered: true, + ResName: "compute-48556", + RGID: 79727, + RGName: "sdk_negative_fields_test", + SnapSets: ListSnapshots{}, + StatelessSEPID: 0, + StatelessSEPType: "", + Status: "ENABLED", + Tags: map[string]interface{}{}, + TechStatus: "STARTED", + TotalDiskSize: 1, + UpdatedBy: "", + UpdatedTime: 1677579436, + UserManaged: true, + VGPUs: []uint64{}, + VINSConnected: 0, + VirtualImageID: 0, + }, + }, + }, + EntryCount: 2, +} + +func TestFilterDeleteByID(t *testing.T) { + actual := deleteComputes.FilterByID(48500).FindOne() + + if actual.ID != 48500 { + t.Fatal("expected ID 48500, found: ", actual.ID) + } + + actualEmpty := deleteComputes.FilterByID(0) + + if len(actualEmpty.Data) != 0 { + t.Fatal("expected empty, actual: ", len(actualEmpty.Data)) + } +} + +func TestFilterDeleteByName(t *testing.T) { + actual := deleteComputes.FilterByName("compute_2").FindOne() + + if actual.Name != "compute_2" { + t.Fatal("expected compute with name 'test', found: ", actual.Name) + } +} + +func TestFilterDeleteByStatus(t *testing.T) { + actual := deleteComputes.FilterByStatus("ENABLED") + + for _, item := range actual.Data { + if item.Status != "ENABLED" { + t.Fatal("expected ENABLED status, found: ", item.Status) + } + } +} + +func TestFilterDeleteByTechStatus(t *testing.T) { + actual := deleteComputes.FilterByTechStatus("STARTED").FindOne() + + if actual.ID != 48556 { + t.Fatal("expected 48556 with STARTED techStatus, found: ", actual.ID) + } +} + +func TestFilterDeleteByDiskID(t *testing.T) { + actual := deleteComputes.FilterByDiskID(65248).FindOne() + + if actual.ID != 48556 { + t.Fatal("expected 48556 with DiskID 65248, found: ", actual.ID) + } +} + +func TestFilterDeleteFunc(t *testing.T) { + actual := deleteComputes.FilterFunc(func(ic ItemDeletedCompute) bool { + return ic.Registered == true + }) + + if len(actual.Data) != 2 { + t.Fatal("expected 2 elements found, actual: ", len(actual.Data)) + } + + for _, item := range actual.Data { + if item.Registered != true { + t.Fatal("expected Registered to be true, actual: ", item.Registered) + } + } +} + +func TestDeleteSortingByCreatedTime(t *testing.T) { + actual := deleteComputes.SortByCreatedTime(false) + + if actual.Data[0].Name != "test" { + t.Fatal("expected 'test', found: ", actual.Data[0].Name) + } + + actual = deleteComputes.SortByCreatedTime(true) + if actual.Data[0].Name != "compute_2" { + t.Fatal("expected 'compute_2', found: ", actual.Data[0].Name) + } +} + +func TestDeleteSortingByCPU(t *testing.T) { + actual := deleteComputes.SortByCPU(false) + + if actual.Data[0].CPUs != 4 { + t.Fatal("expected 4 CPU cores, found: ", actual.Data[0].CPUs) + } + + actual = deleteComputes.SortByCPU(true) + + if actual.Data[0].CPUs != 6 { + t.Fatal("expected 6 CPU cores, found: ", actual.Data[0].CPUs) + } +} diff --git a/pkg/cloudbroker/compute/list.go b/pkg/cloudbroker/compute/list.go index bc481b5..427245a 100644 --- a/pkg/cloudbroker/compute/list.go +++ b/pkg/cloudbroker/compute/list.go @@ -54,6 +54,10 @@ type ListRequest struct { // Required: false CDImageID uint64 `url:"cdImageId,omitempty" json:"cdImageId,omitempty"` + // Find by stack name + // Required: false + StackName string `url:"stackName,omitempty" json:"stackName,omitempty"` + // Find by external network name // Required: false ExtNetName string `url:"extNetName,omitempty" json:"extNetName,omitempty"` diff --git a/pkg/cloudbroker/compute/list_deleted.go b/pkg/cloudbroker/compute/list_deleted.go index f5d4696..95d35fd 100644 --- a/pkg/cloudbroker/compute/list_deleted.go +++ b/pkg/cloudbroker/compute/list_deleted.go @@ -60,7 +60,7 @@ type ListDeletedRequest struct { } // ListDeleted gets list all deleted computes -func (c Compute) ListDeleted(ctx context.Context, req ListDeletedRequest) (*ListComputes, error) { +func (c Compute) ListDeleted(ctx context.Context, req ListDeletedRequest) (*ListDeletedComputes, error) { if err := validators.ValidateRequest(req); err != nil { return nil, validators.ValidationErrors(validators.GetErrors(err)) @@ -73,7 +73,7 @@ func (c Compute) ListDeleted(ctx context.Context, req ListDeletedRequest) (*List return nil, err } - list := ListComputes{} + list := ListDeletedComputes{} err = json.Unmarshal(res, &list) if err != nil { diff --git a/pkg/cloudbroker/compute/mass_repair_boot_fs.go b/pkg/cloudbroker/compute/mass_repair_boot_fs.go deleted file mode 100644 index 5438545..0000000 --- a/pkg/cloudbroker/compute/mass_repair_boot_fs.go +++ /dev/null @@ -1,38 +0,0 @@ -package compute - -import ( - "context" - "net/http" - "strconv" - - "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" -) - -// MassRepairBootFSRequest struct to repair boot disk filesystem on several computes -type MassRepairBootFSRequest struct { - // IDs of compute instances which boot file systems will be repaired - // Required: true - ComputeIDs []uint64 `url:"computeIds" json:"computeIds" validate:"min=1"` -} - -// MassRepairBootFS repairs boot disk filesystem on several computes -func (c Compute) MassRepairBootFS(ctx context.Context, req MassRepairBootFSRequest) (bool, error) { - err := validators.ValidateRequest(req) - if err != nil { - return false, validators.ValidationErrors(validators.GetErrors(err)) - } - - url := "/cloudbroker/compute/massRepairBootFs" - - res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req) - if err != nil { - return false, err - } - - result, err := strconv.ParseBool(string(res)) - if err != nil { - return false, err - } - - return result, nil -} diff --git a/pkg/cloudbroker/compute/models.go b/pkg/cloudbroker/compute/models.go index a5f73cc..b97d8f9 100644 --- a/pkg/cloudbroker/compute/models.go +++ b/pkg/cloudbroker/compute/models.go @@ -425,13 +425,13 @@ type ItemDisk struct { Password string `json:"passwd"` // PCI slot - PCISlot int64 `json:"pciSlot"` + PCISlot int64 `json:"pci_slot"` // Pool Pool string `json:"pool"` // Present to - PresentTo []uint64 `json:"presentTo"` + PresentTo map[string]uint64 `json:"presentTo"` // Purge attempts PurgeAttempts uint64 `json:"purgeAttempts"` @@ -469,6 +469,9 @@ type ItemDisk struct { // Size used SizeUsed float64 `json:"sizeUsed"` + // Size available + SizeAvailable uint64 `json:"sizeAvailable"` + // List detailed snapshots Snapshots ListDetailedSnapshots `json:"snapshots"` @@ -482,7 +485,7 @@ type ItemDisk struct { Type string `json:"type"` // Updated by - UpdatedBy uint64 `json:"updatedBy,omitempty"` + UpdatedBy uint64 `json:"updatedBy"` // Virtual machine ID VMID uint64 `json:"vmid"` @@ -633,6 +636,9 @@ type InfoCompute struct { // Boot order BootOrder []string `json:"bootOrder"` + // Boot type + BootType string `json:"bootType"` + // Boot disk size BootDiskSize uint64 `json:"bootdiskSize"` @@ -690,6 +696,9 @@ type InfoCompute struct { // HPBacked HPBacked bool `json:"hpBacked"` + // Hot resize + HotResize bool `json:"hotResize"` + // ID ID uint64 `json:"id"` @@ -699,6 +708,9 @@ type InfoCompute struct { // List interfaces Interfaces ListInterfaces `json:"interfaces"` + // Loader type + LoaderType string `json:"loaderType"` + // Lock status LockStatus string `json:"lockStatus"` @@ -720,6 +732,9 @@ type InfoCompute struct { // Need reboot NeedReboot bool `json:"needReboot"` + // network interface naming + NetworkInterfaceNaming string `json:"networkInterfaceNaming"` + // Numa Affinity NumaAffinity string `json:"numaAffinity"` @@ -729,8 +744,8 @@ type InfoCompute struct { // List OS users OSUsers ListOSUsers `json:"osUsers"` - // Pinned - Pinned bool `json:"pinned"` + // Pinned to stack + PinnedToStack int64 `json:"pinnedToStack"` // PreferredCPU PreferredCPU []int64 `json:"preferredCpu"` @@ -861,6 +876,9 @@ type RecordCompute struct { // Boot order BootOrder []string `json:"bootOrder"` + // Boot type + BootType string `json:"bootType"` + // Boot disk size BootDiskSize uint64 `json:"bootdiskSize"` @@ -921,6 +939,9 @@ type RecordCompute struct { // HPBacked HPBacked bool `json:"hpBacked"` + // Hot resize + HotResize bool `json:"hotResize"` + // ID ID uint64 `json:"id"` @@ -933,6 +954,9 @@ type RecordCompute struct { // List interfaces Interfaces ListInterfaces `json:"interfaces"` + // Loader type + LoaderType string `json:"loaderType"` + // Lock status LockStatus string `json:"lockStatus"` @@ -972,6 +996,9 @@ type RecordCompute struct { // Need reboot NeedReboot bool `json:"needReboot"` + // network interface naming + NetworkInterfaceNaming string `json:"networkInterfaceNaming"` + // NumaAffinity NumaAffinity string `json:"numaAffinity"` @@ -981,8 +1008,8 @@ type RecordCompute struct { // List OS users OSUsers ListOSUsers `json:"osUsers"` - // Pinned - Pinned bool `json:"pinned"` + // Pinned to stack + PinnedToStack int64 `json:"pinnedToStack"` // PreferredCPU PreferredCPU []int64 `json:"preferredCpu"` @@ -1071,6 +1098,24 @@ type ItemCompute struct { // Main information about compute InfoCompute + // NID + NID uint64 `json:"nid"` + + // Total disk size + TotalDiskSize uint64 `json:"totalDisksSize"` + + // VINS connected + VINSConnected uint64 `json:"vinsConnected"` +} + +// Main information about compute for list +type ItemDeletedCompute struct { + // List of disk IDs + Disks ListInfoDisks `json:"disks"` + + // Main information about compute + InfoCompute + // Total disk size TotalDiskSize uint64 `json:"totalDisksSize"` @@ -1080,14 +1125,8 @@ type ItemCompute struct { // Information Disk type InfoDisk struct { - // Bus number - BusNumber uint64 `json:"bus_number"` - // ID ID uint64 `json:"id"` - - // PCISlot - PCISlot int64 `json:"pciSlot"` } // List computes @@ -1099,6 +1138,15 @@ type ListComputes struct { EntryCount uint64 `json:"entryCount"` } +// List computes +type ListDeletedComputes struct { + // Data + Data []ItemDeletedCompute `json:"data"` + + // EntryCount + EntryCount uint64 `json:"entryCount"` +} + // Short information about audit type ItemAudit struct { // Epoch diff --git a/pkg/cloudbroker/compute/net_attach.go b/pkg/cloudbroker/compute/net_attach.go index 17d3482..5b41d4b 100644 --- a/pkg/cloudbroker/compute/net_attach.go +++ b/pkg/cloudbroker/compute/net_attach.go @@ -32,6 +32,10 @@ type NetAttachRequest struct { // Required: true IPAddr string `url:"ipAddr,omitempty" json:"ipAddr,omitempty"` + // MAC address + // Required: false + MACAddr string `url:"mac_addr,omitempty" json:"mac_addr,omitempty"` + // Used only for DPDK type, must be 1-9216 // Required: false MTU uint64 `url:"mtu,omitempty" json:"mtu,omitempty" validate:"omitempty,mtu"` diff --git a/pkg/cloudbroker/compute/registration.go b/pkg/cloudbroker/compute/registration.go deleted file mode 100644 index f942b8a..0000000 --- a/pkg/cloudbroker/compute/registration.go +++ /dev/null @@ -1,42 +0,0 @@ -package compute - -import ( - "context" - "net/http" - "strconv" - - "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" -) - -// RegistrationRequest struct to set compute registered in RT -type RegistrationRequest struct { - // ID of the Compute - // Required: true - ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"` - - // Unique compute registration key - // Required: true - RegistrationKey string `url:"registrationKey" json:"registrationKey" validate:"required"` -} - -// Registration sets compute registered in RT -func (c Compute) Registration(ctx context.Context, req RegistrationRequest) (bool, error) { - err := validators.ValidateRequest(req) - if err != nil { - return false, validators.ValidationErrors(validators.GetErrors(err)) - } - - url := "/cloudbroker/compute/registration" - - res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req) - if err != nil { - return false, err - } - - result, err := strconv.ParseBool(string(res)) - if err != nil { - return false, err - } - - return result, nil -} diff --git a/pkg/cloudbroker/compute/repair_boot_fs.go b/pkg/cloudbroker/compute/repair_boot_fs.go deleted file mode 100644 index ae23097..0000000 --- a/pkg/cloudbroker/compute/repair_boot_fs.go +++ /dev/null @@ -1,38 +0,0 @@ -package compute - -import ( - "context" - "net/http" - "strconv" - - "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" -) - -// RepairBootFSRequest struct to repair filesystem -type RepairBootFSRequest struct { - // ID of compute instance - // Required: true - ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"` -} - -// RepairBootFS repairs compute boot disk filesystem -func (c Compute) RepairBootFS(ctx context.Context, req RepairBootFSRequest) (bool, error) { - err := validators.ValidateRequest(req) - if err != nil { - return false, validators.ValidationErrors(validators.GetErrors(err)) - } - - url := "/cloudbroker/compute/repairBootFs" - - res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req) - if err != nil { - return false, err - } - - result, err := strconv.ParseBool(string(res)) - if err != nil { - return false, err - } - - return result, nil -} diff --git a/pkg/cloudbroker/compute/sorting.go b/pkg/cloudbroker/compute/sorting.go index b244d55..e78e578 100644 --- a/pkg/cloudbroker/compute/sorting.go +++ b/pkg/cloudbroker/compute/sorting.go @@ -96,3 +96,98 @@ func (lc ListComputes) SortByDeletedTime(inverse bool) ListComputes { return lc } + +// SortByCPU sorts ListDeletedComputes by the CPU core amount in ascending order. +// +// If inverse param is set to true, the order is reversed. +func (lc ListDeletedComputes) SortByCPU(inverse bool) ListDeletedComputes { + if len(lc.Data) < 2 { + return lc + } + + sort.Slice(lc.Data, func(i, j int) bool { + if inverse { + return lc.Data[i].CPUs > lc.Data[j].CPUs + } + + return lc.Data[i].CPUs < lc.Data[j].CPUs + }) + + return lc +} + +// SortByRAM sorts ListDeletedComputes by the RAM amount in ascending order. +// +// If inverse param is set to true, the order is reversed. +func (lc ListDeletedComputes) SortByRAM(inverse bool) ListDeletedComputes { + if len(lc.Data) < 2 { + return lc + } + + sort.Slice(lc.Data, func(i, j int) bool { + if inverse { + return lc.Data[i].RAM > lc.Data[j].RAM + } + + return lc.Data[i].RAM < lc.Data[j].RAM + }) + + return lc +} + +// SortByCreatedTime sorts ListDeletedComputes by the CreatedTime field in ascending order. +// +// If inverse param is set to true, the order is reversed. +func (lc ListDeletedComputes) SortByCreatedTime(inverse bool) ListDeletedComputes { + if len(lc.Data) < 2 { + return lc + } + + sort.Slice(lc.Data, func(i, j int) bool { + if inverse { + return lc.Data[i].CreatedTime > lc.Data[j].CreatedTime + } + + return lc.Data[i].CreatedTime < lc.Data[j].CreatedTime + }) + + return lc +} + +// SortByUpdatedTime sorts ListDeletedComputes by the UpdatedTime field in ascending order. +// +// If inverse param is set to true, the order is reversed. +func (lc ListDeletedComputes) SortByUpdatedTime(inverse bool) ListDeletedComputes { + if len(lc.Data) < 2 { + return lc + } + + sort.Slice(lc.Data, func(i, j int) bool { + if inverse { + return lc.Data[i].UpdatedTime > lc.Data[j].UpdatedTime + } + + return lc.Data[i].UpdatedTime < lc.Data[j].UpdatedTime + }) + + return lc +} + +// SortByDeletedTime sorts ListDeletedComputes by the DeletedTime field in ascending order. +// +// If inverse param is set to true, the order is reversed. +func (lc ListDeletedComputes) SortByDeletedTime(inverse bool) ListDeletedComputes { + if len(lc.Data) < 2 { + return lc + } + + sort.Slice(lc.Data, func(i, j int) bool { + if inverse { + return lc.Data[i].DeletedTime > lc.Data[j].DeletedTime + } + + return lc.Data[i].DeletedTime < lc.Data[j].DeletedTime + }) + + return lc +} diff --git a/pkg/cloudbroker/compute/stop.go b/pkg/cloudbroker/compute/stop.go index cabc0c8..06b1d02 100644 --- a/pkg/cloudbroker/compute/stop.go +++ b/pkg/cloudbroker/compute/stop.go @@ -17,11 +17,6 @@ type StopRequest struct { // Force stop compute // Required: false Force bool `url:"force,omitempty" json:"force,omitempty"` - - // whether to depresent compute disks from node or not - // Default: true - // Required: false - Depresent bool `url:"depresent" json:"depresent"` } // Stop stops compute diff --git a/pkg/cloudbroker/compute/update.go b/pkg/cloudbroker/compute/update.go index 860ad58..dc3d428 100644 --- a/pkg/cloudbroker/compute/update.go +++ b/pkg/cloudbroker/compute/update.go @@ -52,6 +52,22 @@ type UpdateRequest struct { // Recommended isolated CPUs. Field is ignored if compute.cpupin=False or compute.pinned=False // Required: false PreferredCPU []int64 `url:"preferredCpu,omitempty" json:"preferredCpu,omitempty" validate:"omitempty,preferredCPU"` + + // VM type linux, windows or unknown + // Required: false + LoaderType string `url:"loaderType,omitempty" json:"loaderType,omitempty" validate:"omitempty,loaderType"` + + // Boot type of image bios or uefi + // Required: false + BootType string `url:"bootType,omitempty" json:"bootType,omitempty" validate:"omitempty,imageBootType"` + + // Select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming. + // 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"` } // Update updates some properties of the compute diff --git a/pkg/cloudbroker/disks/create.go b/pkg/cloudbroker/disks/create.go index 5265017..ae585fd 100644 --- a/pkg/cloudbroker/disks/create.go +++ b/pkg/cloudbroker/disks/create.go @@ -14,10 +14,6 @@ type CreateRequest struct { // Required: true AccountID uint64 `url:"accountId" json:"accountId" validate:"required"` - // ID of the grid (platform) - // Required: true - GID uint64 `url:"gid" json:"gid" validate:"required"` - // Name of disk // Required: true Name string `url:"name" json:"name" validate:"required"` @@ -30,17 +26,6 @@ type CreateRequest struct { // Required: false Size uint64 `url:"size,omitempty" json:"size,omitempty"` - // Type of disk - // - B=Boot - // - D=Data - // - T=Temp - // Required: true - Type string `url:"type" json:"type" validate:"diskType"` - - // Size in GB default is 0 - // Required: false - SSDSize uint64 `url:"ssdSize,omitempty" json:"ssdSize,omitempty"` - // Max IOPS disk can perform defaults to 2000 // Required: false IOPS uint64 `url:"iops,omitempty" json:"iops,omitempty"` diff --git a/pkg/cloudbroker/disks/delete.go b/pkg/cloudbroker/disks/delete.go index fcde710..6fff9b3 100644 --- a/pkg/cloudbroker/disks/delete.go +++ b/pkg/cloudbroker/disks/delete.go @@ -21,6 +21,10 @@ type DeleteRequest struct { // Whether to completely delete the disk, works only with non attached disks // Required: false Permanently bool `url:"permanently,omitempty" json:"permanently,omitempty"` + + // Name of disk to delete + // Required: false + Name string `url:"name,omitempty" json:"name,omitempty"` } // Delete deletes disk by ID diff --git a/pkg/cloudbroker/disks/filter_test.go b/pkg/cloudbroker/disks/filter_test.go index b84d636..09932ff 100644 --- a/pkg/cloudbroker/disks/filter_test.go +++ b/pkg/cloudbroker/disks/filter_test.go @@ -41,9 +41,9 @@ var disks = ListDisks{ Password: "", PCISlot: 6, Pool: "vmstor", - PresentTo: []uint64{ - 27, - }, + //PresentTo: []uint64{ + // 27, + //}, PurgeAttempts: 0, PurgeTime: 0, RealityDeviceNumber: 0, @@ -100,10 +100,10 @@ var disks = ListDisks{ Password: "", PCISlot: 6, Pool: "vmstor", - PresentTo: []uint64{ - 27, - 27, - }, + //PresentTo: []uint64{ + // 27, + // 27, + //}, PurgeAttempts: 0, PurgeTime: 0, RealityDeviceNumber: 0, diff --git a/pkg/cloudbroker/disks/models.go b/pkg/cloudbroker/disks/models.go index 6381751..57e7b62 100644 --- a/pkg/cloudbroker/disks/models.go +++ b/pkg/cloudbroker/disks/models.go @@ -123,7 +123,7 @@ type InfoDisk struct { Pool string `json:"pool"` // Present to - PresentTo []uint64 `json:"presentTo"` + PresentTo map[string]uint64 `json:"presentTo"` // Purge attempts PurgeAttempts uint64 `json:"purgeAttempts"` @@ -155,6 +155,9 @@ type InfoDisk struct { // Shareable Shareable bool `json:"shareable"` + // Size available + SizeAvailable uint64 `json:"sizeAvailable"` + // Size max SizeMax int64 `json:"sizeMax"` @@ -175,6 +178,9 @@ type InfoDisk struct { // Virtual machine ID VMID uint64 `json:"vmid"` + + // Updated by + UpdatedBy string `json:"updatedBy"` } type ItemReplication struct { @@ -199,23 +205,37 @@ type ItemReplication struct { // Detailed indormation about disk type RecordDisk struct { + + //Created by + CreatedBy string `json:"createdBy"` + + //Deleted by + DeletedBy string `json:"deletedBy"` + // Device name DeviceName string `json:"devicename"` // SEP type SEPType string `json:"sepType"` + // Machine ID + MachineID uint64 `json:"machineId"` + + // Machine name + MachineName string `json:"machineName"` + // Main information about disk InfoDisk + + //Updated by + UpdatedBy string `json:"updatedBy"` + + // Update time + UpdatedTime uint64 `json:"updatedTime"` } // Main information for list disks type ItemDisk struct { - // Machine ID - MachineID uint64 `json:"machineId"` - - // Machine name - MachineName string `json:"machineName"` // Detailed information about disk RecordDisk diff --git a/pkg/cloudbroker/extnet/models.go b/pkg/cloudbroker/extnet/models.go index 56885b9..645b5d4 100644 --- a/pkg/cloudbroker/extnet/models.go +++ b/pkg/cloudbroker/extnet/models.go @@ -184,6 +184,9 @@ type RecordExtNet struct { // Network ID NetworkID uint64 `json:"networkId"` + // NTP + NTP []string `json:"ntp"` + // OVSBridge OVSBridge string `json:"ovsBridge"` diff --git a/pkg/cloudbroker/image/create_cdrom_image.go b/pkg/cloudbroker/image/create_cdrom_image.go index ee5156a..a469be8 100644 --- a/pkg/cloudbroker/image/create_cdrom_image.go +++ b/pkg/cloudbroker/image/create_cdrom_image.go @@ -18,10 +18,6 @@ type CreateCDROMImageRequest struct { // Required: true URL string `url:"url" json:"url" validate:"required,url"` - // Grid (platform) ID where this CD-ROM image should be create in - // Required: true - GID uint64 `url:"gid" json:"gid" validate:"required"` - // Account ID to make the image exclusive // Required: false AccountID uint64 `url:"accountId,omitempty" json:"accountId,omitempty"` diff --git a/pkg/cloudbroker/image/create_image.go b/pkg/cloudbroker/image/create_image.go index ece1b48..f150e8d 100644 --- a/pkg/cloudbroker/image/create_image.go +++ b/pkg/cloudbroker/image/create_image.go @@ -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 // Should be one of: // - bios diff --git a/pkg/cloudbroker/image/filter_test.go b/pkg/cloudbroker/image/filter_test.go index 079bdcb..d02bcbc 100644 --- a/pkg/cloudbroker/image/filter_test.go +++ b/pkg/cloudbroker/image/filter_test.go @@ -29,7 +29,7 @@ var images = ListImages{ Name: "u16", Password: "", Pool: "vmstor", - PresentTo: []uint64{}, + PresentTo: map[string]uint64{}, ProviderName: "", PurgeAttempts: 0, ReferenceID: "sample_reference_id_u16", @@ -72,7 +72,7 @@ var images = ListImages{ Name: "alpine-virt-3.17", Password: "", Pool: "vmstor", - PresentTo: []uint64{}, + PresentTo: map[string]uint64{}, ProviderName: "", PurgeAttempts: 0, ReferenceID: "sample_reference_id_alpine", @@ -115,7 +115,7 @@ var images = ListImages{ Name: "test", Password: "", Pool: "vmstor", - PresentTo: []uint64{}, + PresentTo: map[string]uint64{}, ProviderName: "", PurgeAttempts: 0, ReferenceID: "sample_reference_id_test", diff --git a/pkg/cloudbroker/image/grant_access.go b/pkg/cloudbroker/image/grant_access.go index ce2971c..8699fd4 100644 --- a/pkg/cloudbroker/image/grant_access.go +++ b/pkg/cloudbroker/image/grant_access.go @@ -16,7 +16,7 @@ type GrantAccessRequest struct { // ID of the accounts for share image // Required: true - AccountIDs []uint64 `url:"accounts" json:"accounts" validate:"required"` + AccountIDs []int64 `url:"accounts" json:"accounts" validate:"required"` } // GrantAccess shares specified image with specified accounts diff --git a/pkg/cloudbroker/image/models.go b/pkg/cloudbroker/image/models.go index 22e0a39..6ace868 100644 --- a/pkg/cloudbroker/image/models.go +++ b/pkg/cloudbroker/image/models.go @@ -75,7 +75,7 @@ type RecordImage struct { Pool string `json:"pool"` // Present to - PresentTo []uint64 `json:"presentTo"` + PresentTo map[string]uint64 `json:"presentTo"` // Provider name ProviderName string `json:"provider_name"` @@ -201,7 +201,7 @@ type ItemImage struct { Pool string `json:"pool"` // Present to - PresentTo []uint64 `json:"presentTo"` + PresentTo map[string]uint64 `json:"presentTo"` // Provider name ProviderName string `json:"provider_name"` diff --git a/pkg/cloudbroker/image/revoke_access.go b/pkg/cloudbroker/image/revoke_access.go index 741f83e..f4c0e37 100644 --- a/pkg/cloudbroker/image/revoke_access.go +++ b/pkg/cloudbroker/image/revoke_access.go @@ -16,7 +16,7 @@ type RevokeAccessRequest struct { // ID of the accounts for unshare image // Required: true - AccountIDs []uint64 `url:"accounts" json:"accounts" validate:"required"` + AccountIDs []int64 `url:"accounts" json:"accounts" validate:"required"` } // RevokeAccess unshares specified image with specified accounts diff --git a/pkg/cloudbroker/k8s/models.go b/pkg/cloudbroker/k8s/models.go index ed063bb..ec180c1 100644 --- a/pkg/cloudbroker/k8s/models.go +++ b/pkg/cloudbroker/k8s/models.go @@ -89,6 +89,9 @@ type RecordK8S struct { // Deleted time DeletedTime uint64 `json:"deletedTime"` + // Description + Description string `json:"desc"` + // Only external network ExtnetOnly bool `json:"extnetOnly"` diff --git a/pkg/cloudbroker/kvmx86/create.go b/pkg/cloudbroker/kvmx86/create.go index 687610d..d7647f6 100644 --- a/pkg/cloudbroker/kvmx86/create.go +++ b/pkg/cloudbroker/kvmx86/create.go @@ -31,6 +31,10 @@ type Interface struct { // Used only to DPDK net type // Required: false MTU uint64 `url:"mtu,omitempty" json:"mtu,omitempty" validate:"omitempty,mtu"` + + // MAC address to assign to this VM when connecting to the specified network + // Required: false + MAC string `url:"mac,omitempty" json:"mac,omitempty" validate:"omitempty"` } // DataDisk detailed struct for DataDisks field in CreateRequest, CreateBlankRequest and MassCreateRequest diff --git a/pkg/cloudbroker/kvmx86/create_blank.go b/pkg/cloudbroker/kvmx86/create_blank.go index 084a197..a7261fe 100644 --- a/pkg/cloudbroker/kvmx86/create_blank.go +++ b/pkg/cloudbroker/kvmx86/create_blank.go @@ -72,6 +72,22 @@ type CreateBlankRequest struct { // Recommended isolated CPUs. Field is ignored if compute.cpupin=False or compute.pinned=False // Required: false PreferredCPU []int64 `url:"preferredCpu,omitempty" json:"preferredCpu,omitempty" validate:"omitempty,preferredCPU"` + + // VM type linux, windows or unknown + // Required: false + LoaderType string `url:"loaderType,omitempty" json:"loaderType,omitempty" validate:"omitempty,loaderType"` + + // Boot type of image bios or uefi + // Required: false + BootType string `url:"bootType,omitempty" json:"bootType,omitempty" validate:"omitempty,imageBootType"` + + // Select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming. + // 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"` } // GetRAM returns RAM field values diff --git a/pkg/cloudbroker/node/maintenance.go b/pkg/cloudbroker/node/maintenance.go index 4c1964c..5fbff7b 100644 --- a/pkg/cloudbroker/node/maintenance.go +++ b/pkg/cloudbroker/node/maintenance.go @@ -23,10 +23,6 @@ type MaintenanceRequest struct { // Required: false Offline bool `url:"offline" json:"offline"` - // VDiskAction - // Required: false - VDiskAction string `url:"vdiskaction,omitempty" json:"vdiskaction,omitempty"` - // Reason // Required: false Reason string `url:"reason,omitempty" json:"reason,omitempty"` diff --git a/pkg/cloudbroker/node/set_vfs_number.go b/pkg/cloudbroker/node/set_vfs_number.go index 6f0b25c..dc6b223 100644 --- a/pkg/cloudbroker/node/set_vfs_number.go +++ b/pkg/cloudbroker/node/set_vfs_number.go @@ -3,6 +3,7 @@ package node import ( "context" "net/http" + "strconv" "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" ) @@ -15,34 +16,36 @@ type SetVFsNumberRequest struct { // PCI address or NIC name // Required: true - NicID string `url:"nicId" json:"nicId" validate:"required"` + NICID string `url:"nicId" json:"nicId" validate:"required"` // Number of VF to assign // Required: true VFNum uint64 `url:"vfNum" json:"vfNum" validate:"required"` - // Trust - // Required: true - Trust bool `url:"trust" json:"trust" validate:"required"` - - // Enable spoof checking + // Number of VF to assign // Required: true - Spoofchk bool `url:"spoofchk" json:"spoofchk" validate:"required"` + VFParams []VFParam `url:"vfParams" json:"vfParams" validate:"required"` } // SetVFsNumber sets number of VFs for individual NIC on node -func (n Node) SetVFsNumber(ctx context.Context, req SetVFsNumberRequest) (string, error) { +func (n Node) SetVFsNumber(ctx context.Context, req SetVFsNumberRequest) (bool, error) { err := validators.ValidateRequest(req) if err != nil { - return "", validators.ValidationErrors(validators.GetErrors(err)) + return false, validators.ValidationErrors(validators.GetErrors(err)) } url := "/cloudbroker/node/setVFsNumber" res, err := n.client.DecortApiCall(ctx, http.MethodPost, url, req) + + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) if err != nil { - return "", err + return false, err } - return string(res), nil + return result, nil } diff --git a/pkg/cloudbroker/node/set_vfs_params.go b/pkg/cloudbroker/node/set_vfs_params.go new file mode 100644 index 0000000..47812bc --- /dev/null +++ b/pkg/cloudbroker/node/set_vfs_params.go @@ -0,0 +1,61 @@ +package node + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +type VFParam struct { + // Number of VF to assign + // Required: true + VFNum uint64 `url:"vfNum" json:"vfNum" validate:"required"` + + // Trust + // Required: true + Trust bool `url:"trust" json:"trust" validate:"required"` + + // Enable spoof checking + // Required: true + SpoofChk bool `url:"spoofchk" json:"spoofchk" validate:"required"` +} + +// SetVFsParamsRequest struct to set params of VFs for individual NIC on node +type SetVFsParamsRequest struct { + // Node ID + // Required: true + NID uint64 `url:"nid" json:"nid" validate:"required"` + + // PCI address or NIC name + // Required: true + NICID string `url:"nicId" json:"nicId" validate:"required"` + + // Number of VF to assign + // Required: true + VFParams []VFParam `url:"vfParams" json:"vfParams" validate:"required"` +} + +// SetVFsParams sets params of VFs for individual NIC on node +func (n Node) SetVFsParams(ctx context.Context, req SetVFsParamsRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + return false, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/node/setVFsParams" + + res, err := n.client.DecortApiCall(ctx, http.MethodPost, url, req) + + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/pkg/cloudbroker/prometheus/computes.go b/pkg/cloudbroker/prometheus/computes.go new file mode 100644 index 0000000..7b1b790 --- /dev/null +++ b/pkg/cloudbroker/prometheus/computes.go @@ -0,0 +1,77 @@ +package prometheus + +import ( + "context" + "encoding/json" + "net/http" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +const ( + ComputeCPULoad = "computeCPUload" + ComputeMemoryUsage = "computeMemoryUsage" + ComputeMemoryUsable = "computeMemoryUsable" + ComputeMemoryUnused = "computeMemoryUnused" + ComputeMemoryUsed = "computeMemoryUsed" + ComputeMemoryAvailable = "computeMemoryAvailable" + ComputeReadBytes = "computeReadBytes" + ComputeReadRequests = "computeReadRequests" + ComputeReceiveBytes = "computeReceiveBytes" + ComputeTransmitBytes = "computeTransmitBytes" + ComputeTransmitPackets = "computeTransmitPackets" + ComputeWriteBytes = "computeWriteBytes" + ComputeWriteRequests = "computeWriteRequests" +) + +type ComputesRequest struct { + // List of compute IDs to fetch metrics for + // Required: true + ComputeIDs []uint64 `url:"computeIds" json:"computeIds" validate:"required"` + + // List of compute IDs to fetch metrics for + // Required: true + MetricIDs []string `url:"metricIds" json:"metricIds" validate:"required"` + + // Time to loads of statistic in seconds + // Required: false + ForLast uint64 `url:"forLast,omitempty" json:"forLast,omitempty"` + + // The reading interval in seconds + // Required: true + Step uint64 `url:"step,omitempty" json:"step,omitempty"` + + // Number of zeros after the decimal point + // Required: true + DecimalPlaces uint64 `url:"decimalPlaces,omitempty" json:"decimalPlaces,omitempty"` +} + +// Get multiple metrics for multiple compute instances +func (p Prometheus) Computes(ctx context.Context, req ComputesRequest) (*ComputesData, error) { + res, err := p.ComputesRaw(ctx, req) + if err != nil { + return nil, err + } + + info := ComputesData{} + + err = json.Unmarshal(res, &info) + if err != nil { + return nil, err + } + + return &info, nil +} + +// GetRaw gets information about compute as an array of bytes +func (p Prometheus) ComputesRaw(ctx context.Context, req ComputesRequest) ([]byte, error) { + err := validators.ValidateRequest(req) + if err != nil { + return nil, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/prometheus/computes" + + res, err := p.client.DecortApiCall(ctx, http.MethodPost, url, req) + return res, err +} diff --git a/pkg/cloudbroker/prometheus/models.go b/pkg/cloudbroker/prometheus/models.go index 6ab647d..76ee3bc 100644 --- a/pkg/cloudbroker/prometheus/models.go +++ b/pkg/cloudbroker/prometheus/models.go @@ -11,3 +11,30 @@ type PrometheusPoint struct { // Timestamp the Unix timestamp. Timestamp uint64 `json:"timestamp"` } + +// ComputesData represents an array of data points for computes +type ComputesData []ItemCompute + +// ItemCompute represents a single data of compute +type ItemCompute struct { + // Compute ID + ComputeID uint64 `json:"computeId"` + + // Array of metrics + Metrics []ItemMetric `json:"metrics"` + + // Error + Error string `json:"error"` +} + +// ItemMetric represents a single data point of metric +type ItemMetric struct { + // Metric ID + MetricID string `json:"metricId"` + + // Data represents an array of data points + Data PrometheusData `json:"data"` + + // Error + Error string `json:"error"` +} diff --git a/pkg/cloudbroker/resmon/models.go b/pkg/cloudbroker/resmon/models.go index 5206bc8..399518a 100644 --- a/pkg/cloudbroker/resmon/models.go +++ b/pkg/cloudbroker/resmon/models.go @@ -28,10 +28,12 @@ type ComputeUsage struct { } type ItemDisk struct { - Pool string `json:"pool"` - ResID string `json:"resId"` - SizeUsed uint64 `json:"sizeUsed"` - SizeMax uint64 `json:"sizeMax"` + ID uint64 `json:"id"` + Pool string `json:"pool"` + ResID string `json:"resId"` + SizeUsed float64 `json:"sizeUsed"` + SizeAvailable float64 `json:"sizeAvailable"` + SizeMax float64 `json:"sizeMax"` } // GetByGRIDData represents an array of data points diff --git a/pkg/cloudbroker/rg/create.go b/pkg/cloudbroker/rg/create.go index 9d3a8dd..f1e1531 100644 --- a/pkg/cloudbroker/rg/create.go +++ b/pkg/cloudbroker/rg/create.go @@ -68,16 +68,12 @@ type CreateRequest struct { // Required: false ExtIP string `url:"extIp,omitempty" json:"extIp,omitempty"` - // Register computes in registration system - // Required: false - RegisterComputes bool `url:"registerComputes,omitempty" json:"registerComputes,omitempty"` - // List of strings with pools i.e.: ["sep1_poolName1", "sep2_poolName2"] // Required: false UniqPools []string `url:"uniqPools,omitempty" json:"uniqPools,omitempty"` // Advanced compute features, - // one of: hugepages, numa, cpupin, vfnic + // one of: hugepages, numa, cpupin, vfnic, dpdk, changemac // Required: false ComputeFeatures []string `url:"computeFeatures,omitempty" json:"computeFeatures,omitempty" validate:"omitempty,computeFeatures"` } diff --git a/pkg/cloudbroker/rg/update.go b/pkg/cloudbroker/rg/update.go index 77c71b5..3afce9c 100644 --- a/pkg/cloudbroker/rg/update.go +++ b/pkg/cloudbroker/rg/update.go @@ -42,10 +42,6 @@ type UpdateRequest struct { // Required: false MaxNumPublicIP int64 `url:"maxNumPublicIP,omitempty" json:"maxNumPublicIP,omitempty"` - // Register computes in registration system - // Required: false - RegisterComputes bool `url:"registerComputes,omitempty" json:"registerComputes,omitempty"` - // List of strings with pools i.e.: ["sep1_poolName1", "sep2_poolName2", etc] // Required: false UniqPools []string `url:"uniqPools,omitempty" json:"uniqPools,omitempty"` diff --git a/pkg/cloudbroker/rg/update_compute_features.go b/pkg/cloudbroker/rg/update_compute_features.go index 2a52013..d5811ae 100644 --- a/pkg/cloudbroker/rg/update_compute_features.go +++ b/pkg/cloudbroker/rg/update_compute_features.go @@ -15,7 +15,7 @@ type UpdateComputeFeaturesRequest struct { RGID uint64 `url:"rgId" json:"rgId" validate:"required"` // Advanced compute features, - // one of: hugepages, numa, cpupin, vfnic + // one of: hugepages, numa, cpupin, vfnic, dpdk, changemac // Required: false ComputeFeatures []string `url:"computeFeatures,omitempty" json:"computeFeatures,omitempty" validate:"omitempty,computeFeatures"` } diff --git a/pkg/cloudbroker/sep/del_consumer_nodes.go b/pkg/cloudbroker/sep/del_consumer_nodes.go index 8dcbd81..e33af62 100644 --- a/pkg/cloudbroker/sep/del_consumer_nodes.go +++ b/pkg/cloudbroker/sep/del_consumer_nodes.go @@ -17,6 +17,11 @@ type DelConsumerNodesRequest struct { // List of consumer node IDs // Required: true ConsumerNIDs []uint64 `url:"consumer_nids" json:"consumer_nids" validate:"min=1"` + + // The force flag must be set to true only if the node will never come back online + // Default: false + // Required: true + Force bool `url:"force" json:"force" validate:"required"` } // DelConsumerNodes excludes consumer nodes from SEP parameters diff --git a/pkg/cloudbroker/sep/filter.go b/pkg/cloudbroker/sep/filter.go index d3876fc..54d54c7 100644 --- a/pkg/cloudbroker/sep/filter.go +++ b/pkg/cloudbroker/sep/filter.go @@ -69,3 +69,85 @@ func (lsep ListSEP) FindOne() RecordSEP { return lsep.Data[0] } + +// FilterBySEPID returns ListAvailableSEP with the specified SEPID. +func (sl ListAvailableSEP) FilterBySEPID(sepID uint64) ListAvailableSEP { + predicate := func(sd SEPData) bool { + return sd.SEPID == sepID + } + + return sl.FilterFunc(predicate) +} + +// FilterBySEPName returns ListAvailableSEP with the specified SEPName. +func (sl ListAvailableSEP) FilterBySEPName(SEPName string) ListAvailableSEP { + predicate := func(sd SEPData) bool { + return sd.SEPName == SEPName + } + + return sl.FilterFunc(predicate) +} + +// FilterBySEPType returns ListAvailableSEP with the specified SEPType. +func (sl ListAvailableSEP) FilterBySEPType(SEPType string) ListAvailableSEP { + predicate := func(sd SEPData) bool { + return sd.SEPType == SEPType + } + + return sl.FilterFunc(predicate) +} + +// FilterByPoolType returns ListAvailableSEP where at least one pool has the specified type. +func (sl ListAvailableSEP) FilterByPoolType(poolType string) ListAvailableSEP { + predicate := func(sd SEPData) bool { + for _, pool := range sd.Pools { + for _, pt := range pool.Types { + if pt == poolType { + return true + } + } + } + return false + } + + return sl.FilterFunc(predicate) +} + +// FilterBySystemPool returns ListAvailableSEP where at least one pool is a system pool. +func (sl ListAvailableSEP) FilterBySystemPool(isSystem bool) ListAvailableSEP { + predicate := func(sd SEPData) bool { + for _, pool := range sd.Pools { + if pool.System == isSystem { + return true + } + } + return false + } + + return sl.FilterFunc(predicate) +} + +// FilterFunc allows filtering ListAvailableSEP based on a user-defined predicate. +func (sl ListAvailableSEP) FilterFunc(predicate func(SEPData) bool) ListAvailableSEP { + var result ListAvailableSEP + + for _, item := range sl.Data { + if predicate(item) { + result.Data = append(result.Data, item) + } + } + + result.EntryCount = uint64(len(result.Data)) + + return result +} + +// FindOne returns the first found SEPData. +// If nothing is found, returns an empty struct. +func (sl ListAvailableSEP) FindOne() SEPData { + if len(sl.Data) == 0 { + return SEPData{} + } + + return sl.Data[0] +} diff --git a/pkg/cloudbroker/sep/filter_test.go b/pkg/cloudbroker/sep/filter_test.go index 9ea2bd3..008c92a 100644 --- a/pkg/cloudbroker/sep/filter_test.go +++ b/pkg/cloudbroker/sep/filter_test.go @@ -5,13 +5,7 @@ import "testing" var seps = ListSEP{ Data: []RecordSEP{ { - CKey: "", - Meta: []interface{}{ - "osismodel", - "cloudbroker", - "sep", - 1, - }, + Config: map[string]interface{}{ "API_IPs": []string{ "10.212.3.61", @@ -39,13 +33,7 @@ var seps = ListSEP{ Type: "DES", }, { - CKey: "", - Meta: []interface{}{ - "osismodel", - "cloudbroker", - "sep", - 1, - }, + Config: map[string]interface{}{ "API_IPs": []string{ "10.212.3.64", @@ -74,13 +62,7 @@ var seps = ListSEP{ Type: "DES", }, { - CKey: "", - Meta: []interface{}{ - "osismodel", - "cloudbroker", - "sep", - 1, - }, + Config: map[string]interface{}{ "API_IPs": []string{ "10.212.3.67", @@ -185,3 +167,116 @@ func TestFilterFunc(t *testing.T) { } } } + +var availableSeps = ListAvailableSEP{ + EntryCount: 3, + Data: []SEPData{ + { + SEPID: 1, + SEPName: "sep_1", + SEPType: "TATLIN", + Pools: []Pool{ + { + Name: "pool_1", + Types: []string{"DES"}, + System: false, + }, + }, + }, + { + SEPID: 2, + SEPName: "sep_2", + SEPType: "SHARED", + Pools: []Pool{ + { + Name: "pool_2", + Types: []string{"DES"}, + System: true, + }, + }, + }, + { + SEPID: 3, + SEPName: "sep_3", + SEPType: "DES", + Pools: []Pool{ + { + Name: "pool_3", + Types: []string{"DES"}, + System: false, + }, + }, + }, + }, +} + +func TestFilterBySEPID(t *testing.T) { + actual := availableSeps.FilterBySEPID(1).FindOne() + + if actual.SEPID != 1 { + t.Fatal("expected SEPID 1, found: ", actual.SEPID) + } +} + +func TestFilterBySEPName(t *testing.T) { + actual := availableSeps.FilterBySEPName("sep_2").FindOne() + + if actual.SEPName != "sep_2" { + t.Fatal("expected SEPName 'sep_2', found: ", actual.SEPName) + } +} + +func TestFilterBySEPType(t *testing.T) { + actual := availableSeps.FilterBySEPType("TATLIN").FindOne() + + if actual.SEPType != "TATLIN" { + t.Fatal("expected SEPType 'TATLIN', found: ", actual.SEPType) + } +} + +func TestFilterByPoolType(t *testing.T) { + actual := availableSeps.FilterByPoolType("DES") + + if len(actual.Data) != 3 { + t.Fatal("expected 3 found, actual: ", len(actual.Data)) + } + + for _, item := range actual.Data { + found := false + for _, pool := range item.Pools { + for _, poolType := range pool.Types { + if poolType == "DES" { + found = true + break + } + } + if found { + break + } + } + if !found { + t.Fatal("expected Pool type 'DES', not found in SEP: ", item.SEPID) + } + } +} + +func TestFilterBySystemPool(t *testing.T) { + actual := availableSeps.FilterBySystemPool(true) + + if len(actual.Data) != 1 { + t.Fatal("expected 1 found, actual: ", len(actual.Data)) + } + + for _, item := range actual.Data { + found := false + for _, pool := range item.Pools { + if pool.System { + found = true + break + } + } + if !found { + t.Fatal("expected System pool, not found in SEP: ", item.SEPID) + } + } +} diff --git a/pkg/cloudbroker/sep/get_template.go b/pkg/cloudbroker/sep/get_template.go new file mode 100644 index 0000000..c868822 --- /dev/null +++ b/pkg/cloudbroker/sep/get_template.go @@ -0,0 +1,36 @@ +package sep + +import ( + "context" + "net/http" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// GetTemplateRequest struct to get template of SEP +type GetTemplateRequest struct { + // Type of SEP + // Required: true + SepType string `url:"sep_type" json:"sep_type" validate:"required,sepType"` + + // Language of template + // Required: true + Language string `url:"lang" json:"lang" validate:"required,language"` +} + +// GetTemplate gets data to sep template +func (s SEP) GetTemplate(ctx context.Context, req GetTemplateRequest) (string, error) { + err := validators.ValidateRequest(req) + if err != nil { + return "", validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/sep/getTemplate" + + res, err := s.client.DecortApiCall(ctx, http.MethodPost, url, req) + if err != nil { + return "", err + } + + return string(res), nil +} diff --git a/pkg/cloudbroker/sep/list_available_sep_and_pools.go b/pkg/cloudbroker/sep/list_available_sep_and_pools.go new file mode 100644 index 0000000..7daa7bc --- /dev/null +++ b/pkg/cloudbroker/sep/list_available_sep_and_pools.go @@ -0,0 +1,51 @@ +package sep + +import ( + "context" + "encoding/json" + "net/http" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// ListAvailableSEPAndPoolsRequest struct to get dict with entry count and list of dict with SEPs and pools details accessible by the Account and RG +type ListAvailableSEPAndPoolsRequest struct { + // Account ID + // Required: true + AccountID uint64 `url:"account_id" json:"account_id" validate:"required"` + + // RG ID + // Required: false + RGID uint64 `url:"rg_id,omitempty" json:"rg_id,omitempty"` +} + +// ListAvailableSEPAndPools get dict with entry count and list of dict with SEPs and pools details accessible by the Account and RG +func (s SEP) ListAvailableSEPAndPools(ctx context.Context, req ListAvailableSEPAndPoolsRequest) (*ListAvailableSEP, error) { + res, err := s.ListAvailableSEPAndPoolsRaw(ctx, req) + if err != nil { + return nil, err + } + + list := ListAvailableSEP{} + + err = json.Unmarshal(res, &list) + if err != nil { + return nil, err + } + + return &list, nil +} + +// ListRaw gets list as an array of bytes +func (s SEP) ListAvailableSEPAndPoolsRaw(ctx context.Context, req ListAvailableSEPAndPoolsRequest) ([]byte, error) { + + err := validators.ValidateRequest(req) + if err != nil { + return nil, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/sep/listAvailableSepAndPools" + + res, err := s.client.DecortApiCall(ctx, http.MethodPost, url, req) + return res, err +} diff --git a/pkg/cloudbroker/sep/models.go b/pkg/cloudbroker/sep/models.go index f22c31a..401b151 100644 --- a/pkg/cloudbroker/sep/models.go +++ b/pkg/cloudbroker/sep/models.go @@ -152,3 +152,36 @@ type ListSEP struct { // Entry count EntryCount uint64 `json:"entryCount"` } + +type Pool struct { + // Pool name + Name string `json:"name"` + + // Pool types + Types []string `json:"types"` + + // System + System bool `json:"system"` +} + +type SEPData struct { + // SEP ID + SEPID uint64 `json:"sepId"` + + // SEP name + SEPName string `json:"sepName"` + + // Sep type + SEPType string `json:"sepType"` + + // Pools + Pools []Pool `json:"pools"` +} + +type ListAvailableSEP struct { + // Entry count + EntryCount uint64 `json:"entryCount"` + + // Data + Data []SEPData `json:"data"` +} diff --git a/pkg/cloudbroker/sep/serialize.go b/pkg/cloudbroker/sep/serialize.go index 383e520..c3c74b7 100644 --- a/pkg/cloudbroker/sep/serialize.go +++ b/pkg/cloudbroker/sep/serialize.go @@ -41,3 +41,39 @@ func (rsep RecordSEP) Serialize(params ...string) (serialization.Serialized, err return json.Marshal(rsep) } + +// 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 (lsep ListAvailableSEP) Serialize(params ...string) (serialization.Serialized, error) { + if len(lsep.Data) == 0 { + return []byte{}, nil + } + + if len(params) > 1 { + prefix := params[0] + indent := params[1] + + return json.MarshalIndent(lsep, prefix, indent) + } + + return json.Marshal(lsep) +} + +// 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 (rsep SEPData) Serialize(params ...string) (serialization.Serialized, error) { + if len(params) > 1 { + prefix := params[0] + indent := params[1] + + return json.MarshalIndent(rsep, prefix, indent) + } + + return json.Marshal(rsep) +} diff --git a/pkg/cloudbroker/stack/models.go b/pkg/cloudbroker/stack/models.go index 3613ea1..d79decf 100644 --- a/pkg/cloudbroker/stack/models.go +++ b/pkg/cloudbroker/stack/models.go @@ -43,7 +43,7 @@ type InfoStack struct { // ID ID uint64 `json:"id"` - + // List image IDs Images []uint64 `json:"images"` @@ -83,6 +83,9 @@ type ListStacks struct { // Package type Packages struct { + // LibGuestFSTools + LibGuestFSTools LibGuestFSTools `json:"libguestfs-tools"` + // LibvirtBin LibvirtBin LibvirtBin `json:"libvirt-bin"` @@ -105,6 +108,15 @@ type Packages struct { Sanlock Sanlock `json:"sanlock"` } +// LibGuestFSTools +type LibGuestFSTools struct { + // InstalledSize + InstalledSize string `json:"installed_size"` + + // Version + Ver string `json:"ver"` +} + // LibvirtBin type LibvirtBin struct { // InstalledSize diff --git a/pkg/cloudbroker/vins/list.go b/pkg/cloudbroker/vins/list.go index b8d6f51..fe35a34 100644 --- a/pkg/cloudbroker/vins/list.go +++ b/pkg/cloudbroker/vins/list.go @@ -18,6 +18,10 @@ type ListRequest struct { // Required: false Name string `url:"name,omitempty" json:"name,omitempty"` + // Find by status + // Required: false + Status string `url:"status,omitempty" json:"status,omitempty"` + // Find by account ID // Required: false AccountID uint64 `url:"accountId,omitempty" json:"accountId,omitempty"` diff --git a/tests/platform_upgrade/cloud_test.go b/tests/platform_upgrade/cloud_test.go index 0cec216..c6e1e9a 100644 --- a/tests/platform_upgrade/cloud_test.go +++ b/tests/platform_upgrade/cloud_test.go @@ -17,19 +17,20 @@ import ( "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/sep" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/stack" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + disks_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + image_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" node_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/node" account_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" audit_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/audit" compute_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" - disks_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" extnet_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/extnet" flipgroup_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/flipgroup" grid_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid" - image_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" k8ci_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8ci" k8s_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s" lb_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" @@ -281,6 +282,14 @@ func TestGetListCloudAPI(t *testing.T) { t.Errorf("Can not test RG get because RG list is empty") } + // SEP + // List available sep and pools + bytes, err = client.CloudAPI().SEP().ListAvailableSEPAndPoolsRaw(context.Background(), sep.ListAvailableSEPAndPoolsRequest{AccountID: 1}) + if err != nil { + t.Error(err) + } + testLogs = append(testLogs, getResult("SEP list", bytes, sep.ListAvailableSEP{}, t)) + // Stack // List bytes, err = client.CloudAPI().Stack().ListRaw(context.Background(), stack.ListRequest{}) @@ -485,7 +494,7 @@ func TestGetListCloudbroker(t *testing.T) { } // Image - // List + //// List bytes, err = client.CloudBroker().Image().ListRaw(context.Background(), image_cb.ListRequest{}) if err != nil { t.Error(err) @@ -632,6 +641,12 @@ func TestGetListCloudbroker(t *testing.T) { t.Errorf("Can not test SEP get because SEP list is empty") } + bytes, err = client.CloudBroker().SEP().ListAvailableSEPAndPoolsRaw(context.Background(), sep_cb.ListAvailableSEPAndPoolsRequest{AccountID: 1}) + if err != nil { + t.Error(err) + } + testLogs = append(testLogs, getResult("SEP and pools list", bytes, sep_cb.ListAvailableSEP{}, t)) + // Stack // List bytes, err = client.CloudBroker().Stack().ListRaw(context.Background(), stack_cb.ListRequest{}) diff --git a/tests/platform_upgrade/request_map.go b/tests/platform_upgrade/request_map.go index 7f0749a..382089b 100644 --- a/tests/platform_upgrade/request_map.go +++ b/tests/platform_upgrade/request_map.go @@ -438,7 +438,6 @@ func getRequestsMapCloudbroker() map[string]interface{} { "/restmachine/cloudbroker/apiaccess/getFull": EmptyStruct{}, "/restmachine/cloudbroker/apiaccess/getPreGroups": EmptyStruct{}, "/restmachine/cloudbroker/apiaccess/list": apiaccess_cb.ListRequest{}, - "/restmachine/cloudbroker/apiaccess/listDeleted": apiaccess_cb.ListDeletedRequest{}, "/restmachine/cloudbroker/apiaccess/setDefault": apiaccess_cb.SetDefaultRequest{}, "/restmachine/cloudbroker/apiaccess/subtract": apiaccess_cb.SubtractRequest{}, "/restmachine/cloudbroker/apiaccess/union": apiaccess_cb.UnionRequest{}, @@ -510,7 +509,6 @@ func getRequestsMapCloudbroker() map[string]interface{} { "/restmachine/cloudbroker/compute/massStart": compute_cb.MassStartRequest{}, "/restmachine/cloudbroker/compute/massStop": compute_cb.MassStopRequest{}, "/restmachine/cloudbroker/compute/massReboot": compute_cb.MassRebootRequest{}, - "/restmachine/cloudbroker/compute/massRepairBootFs": compute_cb.MassRepairBootFSRequest{}, "/restmachine/cloudbroker/compute/migrate": compute_cb.MigrateRequest{}, "/restmachine/cloudbroker/compute/migrateStorage": compute_cb.MigrateStorageRequest{}, "/restmachine/cloudbroker/compute/migrateStorageAbort": compute_cb.MigrateStorageAbortRequest{}, @@ -529,8 +527,6 @@ func getRequestsMapCloudbroker() map[string]interface{} { "/restmachine/cloudbroker/compute/raiseDown": EmptyStruct{}, "/restmachine/cloudbroker/compute/reboot": compute_cb.RebootRequest{}, "/restmachine/cloudbroker/compute/redeploy": compute_cb.RedeployRequest{}, - "/restmachine/cloudbroker/compute/registration": compute_cb.RegistrationRequest{}, - "/restmachine/cloudbroker/compute/repairBootFs": compute_cb.RepairBootFSRequest{}, "/restmachine/cloudbroker/compute/reset": compute_cb.ResetRequest{}, "/restmachine/cloudbroker/compute/resize": compute_cb.ResizeRequest{}, "/restmachine/cloudbroker/compute/restore": compute_cb.RestoreRequest{},