diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cdcafb..2cfa517 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## Version 1.15.0 +## Version 1.15.1 Методы `Audits` в cloudapi/compute, cloudbroker/compute, cloudapi/account, cloudbroker/account, cloudapi/vins, cloudbroker/vins, cloudapi/rg и cloudbroker/rg стали deprecated и в следующих версиях будут удалены, вместо них необходимо использовать метод `List` в cloudapi/audit и cloudbroker/audit с соответствующими фильтрами Методы `AccessGrant`, `AccessGrantToPool`, `AccessRevoke`, `AccessRevokeToPool` в cloudbroker/sep стали deprecated и в следующих версиях будут удалены @@ -7,193 +7,52 @@ Все методы группы `.SDN()` находятся в альфа-версии. - ### Добавлено -#### compute +#### Общее | Идентификатор задачи | Описание | | --- | --- | -| BGOS-864 | Методы `GetCPUAlignmentProfile`, `SetCPUAlignmentProfile` и `DeleteCPUAlignmentProfile` в cloudapi/compute и cloudbroker/compute | -| BGOS-864 | Структуры запросов `GetCPUAlignmentProfileRequest`, `SetCPUAlignmentProfileRequest` и `DeleteCPUAlignmentProfileRequest` в cloudapi/compute и cloudbroker/compute | -| BGOS-865 | Вычисляемое поле `CPUAlignmentProfile` в структуру ответа `RecordCompute` в cloudapi/compute и cloudbroker/compute | -| BGOS-865 | Вычисляемое поле `CPUAlignmentProfile` в структуру ответа `ItemCompute` в cloudapi/compute и cloudbroker/compute | -| BGOS-865 | Структура ответа `CPUAlignmentProfile` в cloudapi/compute и cloudbroker/compute | -| BGOS-872 | Опциональное поле `WithMemory` в структуру запроса `SnapshotCreateRequest` в cloudapi/compute и cloudbroker/compute | -| BGOS-872 | Опциональное поле `WithMemory` в структуру запроса `SnapshotRollbackRequest` в cloudapi/compute и cloudbroker/compute | -| BGOS-872 | Вычисляемые поля `MemoryDumpImage` и `Compute` в структуру ответа `ItemSnapshot` в cloudapi/compute и cloudbroker/compute | -| BGOS-872 | Методы `SnapshotCreateAsync`, `SnapshotRollbackAsync` и `AbortSharedSnapshotMergeAsync` в cloudapi/compute и cloudbroker/compute | -| BGOS-872 | Опциональное поле `NodeID` в структуру запроса `SnapshotRollbackRequest` в cloudbroker/compute | -| BGOS-877 | Опциональное поле `Clock` в структуру запроса `UpdateRequest` в cloudapi/compute и cloudbroker/compute | -| BGOS-877 | Вычисляемое поле `Clock` в структуры ответа `RecordCompute` и `ItemCompute` в cloudapi/compute| -| BGOS-877 | Вычисляемое поле `Clock` в структуры ответа `RecordCompute` и `InfoCompute` в cloudbroker/compute | -| BGOS-885 | Методы `CDEjectAsync`, `CDInsertAsync`, `ChangeIPAsync`, `ChangeLinkStateAsync`, `ChangeSecGroupsAsync`, `ChangeMTUAsync`, `CloneAsync`, `CreateTemplateAsync`, `DeleteAsync`, `DisableAsync`, `DiskAddAsync`, `DiskAttachAsync`, `DiskDelAsync`, `DiskDetachAsync`, `DiskQOSAsync`, `DiskResizeAsync`, `DiskSwitchToReplicationAsync`, `GuestAgentDisableAsync`, `GuestAgentEnableAsync`, `GuestAgentExecuteRequestAsync`, `GuestAgentFeatureUpdateAsync`, `MigrateToZoneAsync`, `MoveToRGAsync`, `NetAttachAsync`, `NetDetachAsync`, `PauseAsync`, `PFWAddAsync`, `PFWDelAsync`, `PinToNodeAsync`, `PowerCycleAsync`, `RebootAsync`, `RedeployAsync`, `ResetAsync`, `ResizeAsync`, `RestoreAsync`, `ResumeAsync`, `StartAsync`, `StopAsync`, `MassDeleteAsync`, `MassRebootAsync`, `MassStartAsync`, `MassStopAsync`, `MigrateAbortAsync`, `MigrateStorageAbortAsync`, `MigrateStorageCleanUpAsync`, `NetQOSAsync` и `RaiseDownAsync` в cloudbroker/compute | -| BGOS-885 | Методы `CDEjectAsync`, `CDInsertAsync`, `ChangeIPAsync`, `ChangeLinkStateAsync`, `ChangeMTUAsync`, `ChangeSecGroupsAsync`, `CloneAsync`, `DeleteAsync`, `DisableAsync`, `DiskAddAsync`, `DiskDelAsync`, `DiskAttachAsync`, `DiskDetachAsync`, `DiskQOSAsync`, `DiskResizeAsync`, `DiskSwitchToReplicationAsync`, `GuestAgentDisableAsync`, `GuestAgentEnableAsync`, `GuestAgentExecuteRequestAsync`, `GuestAgentFeatureUpdateAsync`, `MigrateToZoneAsync`, `MoveToRGAsync`, `NetAttachAsync`, `NetDetachAsync`, `PauseAsync`, `PFWAddAsync`, `PFWDelAsync`, `PinToNodeAsync`, `PowerCycleAsync`, `RebootAsync`, `RedeployAsync`, `ResetAsync`, `ResizeAsync`, `RestoreAsync`, `ResumeAsync`, `StartAsync` и `StopAsync` в cloudapi/compute | -| BGOS-894 | Опциональное поле `ReadOnly` в структуры запросов `DiskAddRequest` и `DiskAttachRequest` в cloudapi/compute и cloudbroker/compute | -| BGOS-894 | Опциональное поле `ReadOnly` в структуры ответа `InfoDisk` в cloudapi/compute и cloudbroker/compute | -| BGOS-894 | Опциональное поле `ReadOnly` в структуру ответа `ItemComputeDisk` в cloudapi/compute | -| BGOS-894 | Опциональное поле `ReadOnly` в структуру ответа `ItemDisk` в cloudbroker/compute | - -#### disks -| Идентификатор задачи | Описание | -| --- | --- | -| BGOS-895 | Вычисляемое поле `ComputesReadOnly` в структуру ответа `InfoDisk` в cloudbroker/disks | -| BGOS-895 | Вычисляемое поле `ComputesReadOnly` в структуры ответа `ItemDisk` и `RecordDisk` в cloudapi/disks | - -#### extnet -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-876 | Вычисляемое поле `FreeIPs` в структуру ответа `ItemExtNet` в cloudapi/extnet | - -#### grid -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-888 | Вычисляемые поля `CPUAllocationRatio`, `CPUAllocationRatioVM`, `CustomBackupPath`, `InterfaceGenerationScheme`, `MACAddressPrefix`, `NodeSelfStopTimerUptimeMonitor` и `NodeSelfStopUptimeMonitor` в структуру ответа `RecordSettingsGrid` в cloudbroker/grid | -| BGOS-888 | Вычисляемое поле `ZeroAccessEnabled` в структуру ответа `RecordGrid` в cloudbroker/grid | -| BGOS-888 | Вычисляемое поле `Policies` в структуру ответа `RecordResource` и структура ответа `PolicyUsage` в cloudbroker/grid | +| BGOS-899 | Добавлена валидация полей `ssoUrl` и `decortUrl` в конфигах `Config`, `BVSConfig` и `LegacyConfig`, а также поля `domain` в конфиге `BVSConfig` при вызове конструкторов `New`, `NewBVS`, `NewLegacy` | #### kvmx86 | Идентификатор задачи | Описание | | --- | --- | -| BGOS-865 | Опциональное поле `CPUAlignmentProfile` в структуры запросов `CreateRequest` и `CreateBlankRequest` в cloudapi/kvmx86 и cloudbroker/kvmx86 | -| BGOS-865 | Опциональное поле `CPUAlignmentProfile` в структуру запроса `MassCreateRequest` в cloudbroker/kvmx86 | -| BGOS-877 | Опциональное поле `Clock` в структуры запросов `CreateRequest` и `CreateBlankRequest` в cloudapi/kvmx86 и cloudbroker/kvmx86 | -| BGOS-877 | Опциональное поле `Clock` в структуру запроса `MassCreateRequest` в cloudbroker/kvmx86 | +| BGOS-903 | Структура ответа `MassCreateError` в cloudbroker/kvmx86 | -#### node -| Идентификатор
задачи | Описание | +#### node +| Идентификатор задачи | Описание | | --- | --- | -| BGOS-866 | Вычисляемые поля `OneGAvailable`, `OneGFree`, `OneGReserved`, `OneGUsed`, `OneGDPDKReserved`, `TwoMAvailable`, `TwoMFree`, `TwoMReserved` и `TwoMUsed` в структуру ответа `ItemMemory` в cloudbroker/node | -| BGOS-879 | Методы `GetPCIDevices`, `PCIDeviceDriverToVFIO` и `PCIDeviceDriverToKernel` в cloudbroker/node | -| BGOS-879 | Структуры запросов `GetPCIDevicesRequest`, `PCIDeviceDriverToVFIORequest` и `PCIDeviceDriverToKernelRequest` в cloudbroker/node | -| BGOS-879 | Структуры ответов `RecordPCIDeviceDriver`, `ListPCIDevices` и `ItemPCIDevice` в cloudbroker/node | -| BGOS-880 | Вычисляемое поле `PCIDevices` в структуру ответа `ItemNode` в cloudbroker/node | -| BGOS-882 | Метод `GetNetworkInfo` и структура запроса `GetNetworkInfoRequest` в cloudbroker/node | -| BGOS-882 | Структуры ответа `RecordNodeNetworkInfo`, `SystemNetworkInfo`, `OVSNetworkInfo`, `LibvirtNetworkInfo` и `NetworkTopology` в cloudbroker/node | -| BGOS-890 | Структура ответа `ItemNode` для методов `SetCpuAllocationRatio` и `SetMemAllocationRatio` в cloudbroker/node | - -#### sep -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-873 | Метод `Update` и структура запроса `UpdateRequest` в cloudbroker/sep | +| BGOS-906 | Метод `Install` и структура запроса `InstallRequest` в cloudbroker/node | #### zone | Идентификатор задачи | Описание | | --- | --- | -| BGOS-862 | Метод `AddCPUAlignmentProfile` и структура запроса `AddCPUAlignmentProfileRequest` в cloudbroker/zone | -| BGOS-862 | Метод `DeleteCPUAlignmentProfile` и структура запроса `DeleteCPUAlignmentProfileRequest` в cloudbroker/zone | -| BGOS-862 | Метод `GetCPUAlignmentProfile` и структура запроса `GetCPUAlignmentProfileRequest` в cloudbroker/zone | -| BGOS-862 | Метод `ListCPUAlignmentProfile` и структура запроса `ListCPUAlignmentProfileRequest` в cloudbroker/zone | -| BGOS-862 | Метод `TestCPUAlignmentProfile` и структура запроса `TestCPUAlignmentProfileRequest` в cloudbroker/zone | -| BGOS-862 | Структуры ответов `ListCPUAlignmentProfiles`, `ItemCPUAlignmentProfile`, `TestCPUAlignmentProfileResult` и `CpuAlignmentProfileCandidate` в cloudbroker/zone | -| BGOS-863 | Вычисляемое поле `CpuAlignmentProfiles` в структуры ответа `RecordZone` и `ItemZone` и структура `CpuAlignmentProfile` в cloudapi/zone и cloudbroker/zone | - -#### SDN logicalports -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-896 | Обязательное поле `ID` в структуру запроса `UpdateAddress` в sdn/logical_port | - -#### SDN netobjgroups -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-884 | Опциональное поле `Type` в структуру запроса `ListRequest` в sdn/netobjgroups | +| BGOS-902 | Вычисляемое поле `SupportedCpuModels` в структуру ответа `TestCPUAlignmentProfileResult` в cloudbroker/zone | +| BGOS-902 | Структура ответа `SupportedCpuModel` в cloudbroker/zone | ### Изменено -#### account -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-887 | Тип поля `CPUAllocationRatio` с `float64` на `uint64` в структуре ответа `RecordAccount` в cloudapi/account | -| BGOS-887 | Тип поля `CPUAllocationRatio` с `float64` на `uint64` в структуре ответа `InfoAccount` в cloudbroker/account | - #### compute +| Идентификатор задачи | Описание | +| --- | --- | +| BGOS-905 | Тип полей `Login` и `Password` с опциональных на обязательные в структуре `OSUser` в cloudbroker/compute | + +#### zone | Идентификатор
задачи | Описание | | --- | --- | -| BGOS-874 | Поле `StoragePolicyID` с обязательного на опциональное в структуре запроса `RedeployRequest` в cloudapi/compute и cloudbroker/compute | -| BGOS-870 | Тип поля `BLKDiscard` с `bool` на `string` и переименование в `Discard` в структуре ответа `ItemComputeDisk` в cloudapi/compute | -| BGOS-870 | Тип поля `BLKDiscard` с `bool` на `string` и переименование в `Discard` в структуре ответа `ItemDisk` в cloudbroker/compute| -| BGOS-870 | Тип поля `BLKDiscard` с `bool` на `string` и переименование в `Discard` в структуре запроса `DiskAddRequest` в cloudbroker/compute| -| BGOS-885 | Тип возвращаемого значения с `string` на `bool` в методе `Restore` в cloudapi/compute | -| BGOS-885 | Тип возвращаемого значения с `string` на `bool` в методе `MigrateStorageAbort` в cloudbroker/compute | -| BGOS-885 | Тип возвращаемого значения с `string` на `bool` в методе `MigrateStorageCleanUp` в cloudbroker/compute | -| BGOS-885 | Название метода с `Validate` на `MoveToRG` в cloudbroker/compute | -| BGOS-893 | Тип поля `SDNObjectGroupID` с `string` на `[]string` и переименование в `SDNObjectGroupIDs` в структуре запроса `NetAttachRequest` в cloudapi/compute и cloudbroker/compute | - - -#### disks -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-870 | Тип поля `BLKDiscard` с `bool` на `string` и переименование в `Discard` в структурах ответа `RecordDisk`, `ItemDisk` и `ItemDiskUnattached` в cloudapi/disks | -| BGOS-870 | Тип поля `BLKDiscard` с `bool` на `string` и переименование в `Discard` в структуре ответа `InfoDisk` в cloudbroker/disks | -| BGOS-870 | Тип поля `BLKDiscard` с `bool` на `string` и переименование в `Discard` в структурах запросов `CreateRequest` и `UpdateRequest` в cloudbroker/disks | -| BGOS-881 | Поле `StoragePolicyID` c опционального на обязательное в структуре запроса `MigrateRequest` в cloudbroker/disks | - -#### grid -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-888 | Тип поля `Ratio` с `float64` на `uint64` в структурах запросов `SetCPUAllocationRatioRequest`, `SetCPUAllocationRatioForVMRequest` и `SetMemAllocationRatioRequest` в cloudbroker/grid | - -#### image -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-860 | Тип ответа метода `MultiImageExport` со `string` на `uint64` в cloudbroker/image | -| BGOS-869 | Тип вычисляемого поля `AccountID` с опционального на обязательный в структуре `CreateVirtualRequest` в cloudapi/image | -| BGOS-878 | Тип поля `TypeImage` в структуре запроса `ListRequest` с `string` на `[]string` в cloudbroker/image и cloudapi/image | - -#### kvmx86 -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-870 | Тип поля `BLKDiscard` с `bool` на `string` и переименование в `Discard` в структуре ответа `DataDisk` в cloudbroker/kvmx86 | -| BGOS-870 | Тип поля `BootDiskBLKDiscard` с `bool` на `string` и переименование в `BootDiskDiscard` в структурах запросов `CreateRequest`, `CreateBlankRequest` и `MassCreateRequest` в cloudbroker/kvmx86 | -| BGOS-893 | Тип поля `SDNObjectGroupID` с `string` на `[]string` и переименование в `SDNObjectGroupIDs` в структуре `Interface` в cloudapi/kvmx86 и cloudbroker/kvmx86 | -| BGOS-893 | Тип поля `SDNObjectGroupID` с `string` на `[]string` и переименование в `SDNObjectGroupIDs` в структуре `InterfaceMassCreate` в cloudbroker/kvmx86 | - -#### node -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-867 | Тип обязательного поля `Ratio` с `float64` на `uint64` в структурах запросов `SetMemAllocationRatioRequest` и `SetCpuAllocationRatioRequest` в cloudbroker/node | -| BGOS-889 | Тип поля `VCPU` с `float64` на `uint64` в структуре ответа `FreeResourcesInfo` в cloudbroker/node | -| BGOS-889 | Тип полей `CPUAllocationRatio` и `MemAllocationRatio` с `float64` на `uint64` в структурах ответа `RecordNode` и `ItemNode` в cloudbroker/node | - -#### resmon -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-868 | Тип поля `EndTime` с обязательного на опциональное в структурах запроса `GetByNodeRequest`, `GetByNodesRequest` `GetByGRIDRequest`, `GetByComputeRequest` и `GetByComputesRequest` в cloudbroker/resmon | - -#### rg -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-886 | Тип поля `CPUAllocationRatio` с `float64` на `uint64` в структурах ответа `RecordResourceGroup` и `ItemResourceGroup` в cloudapi/rg | -| BGOS-886 | Тип поля `CPUAllocationRatio` с `float64` на `uint64` в структуре ответа `ItemRG` в cloudbroker/rg | -| BGOS-886 | Тип поля `Ratio` с `float64` на `uint64` в структуре запроса `SetCPUAllocationRatioRequest` в cloudbroker/rg | - -#### user -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-891 | Тип поля `Password` с опционального на обязательный в структуре запроса `CreateRequest` в cloudbroker/user | +| BGOS-902 | Тип поля `Percentage` с `uint64` на `float64` в структуре ответа `CpuAlignmentProfileCandidate` в cloudbroker/zone | #### SDN logicalports -| Идентификатор
задачи | Описание | +| Идентификатор задачи | Описание | | --- | --- | -| BGOS-896 | Тип полей `IsDiscovered` и `MAC` с опционального на обязательный в структурах запроса `UpdateAddress` и `AddAddress` в sdn/logical_port | -| BGOS-896 | Тип поля `IsDiscovered` с опционального на обязательный в структуре запроса `LogicalPortAddressRequest` в sdn/logical_port -| BGOS-896 | Тип полей `IsDiscovered`, `MAC` с `interface` на `bool` в структурах запроса `UpdateAddress`, `AddAddress`, `LogicalPortAddressRequest` в sdn/logical_port/update | +| BGOS-907 | Тип поля `MAC` с опционального на обязательное в структуре `AddAddress` в sdn/logicalports | -### Исправлено - -#### vfpool -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-871 | Тип поля `Config` в структуре запроса `wrapperUpdateRequest` с `[]string` на `string` в cloudbroker/vfpool | ### Удалено -#### grid -| Идентификатор
задачи | Описание | +#### compute +| Идентификатор задачи | Описание | | --- | --- | -| BGOS-888 | Вычисляемые поля `CKey` и `Meta` из структуры ответа `RecordGrid` в cloudbroker/grid | +| BGOS-904 | Опциональное поле `Force` из структуры запроса `MigrateRequest` в cloudbroker/compute | + -#### user -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-861 | Значение по умолчанию опционального поля `Password` в структуре запроса `CreateRequest` в cloudbroker/user | -| BGOS-875 | Опциональное поле `Password` из структуры ответа `ItemUser` в cloudbroker/user | diff --git a/client.go b/client.go index ff84226..c286da8 100644 --- a/client.go +++ b/client.go @@ -36,6 +36,10 @@ type DecortClient struct { // Сlient builder func New(cfg config.Config) *DecortClient { + if err := validators.ValidateConfig(cfg); err != nil { + panic(validators.ValidationErrors(validators.GetErrors(err))) + } + if cfg.Retries == 0 { cfg.Retries = 5 } diff --git a/client_bvs.go b/client_bvs.go index 05f353e..9c505bd 100644 --- a/client_bvs.go +++ b/client_bvs.go @@ -16,6 +16,7 @@ import ( "github.com/google/go-querystring/query" "repository.basistech.ru/BASIS/decort-golang-sdk/config" "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants" + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn" @@ -38,6 +39,10 @@ type tokenJSON struct { // Сlient builder func NewBVS(cfg config.BVSConfig) *BVSDecortClient { + if err := validators.ValidateConfig(cfg); err != nil { + panic(validators.ValidationErrors(validators.GetErrors(err))) + } + if cfg.Retries == 0 { cfg.Retries = 5 } diff --git a/legacy-client.go b/legacy-client.go index 64ed0e5..5292b9b 100644 --- a/legacy-client.go +++ b/legacy-client.go @@ -16,6 +16,7 @@ import ( "github.com/google/go-querystring/query" "repository.basistech.ru/BASIS/decort-golang-sdk/config" "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants" + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn" @@ -32,6 +33,10 @@ type LegacyDecortClient struct { // Legacy client builder func NewLegacy(cfg config.LegacyConfig) *LegacyDecortClient { + if err := validators.ValidateConfig(cfg); err != nil { + panic(validators.ValidationErrors(validators.GetErrors(err))) + } + if cfg.Retries == 0 { cfg.Retries = 5 } diff --git a/pkg/cloudapi/kvmx86/create.go b/pkg/cloudapi/kvmx86/create.go index af27baa..44d2674 100644 --- a/pkg/cloudapi/kvmx86/create.go +++ b/pkg/cloudapi/kvmx86/create.go @@ -2,10 +2,10 @@ package kvmx86 import ( "context" - "encoding/json" "net/http" "strconv" + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants" "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" ) @@ -231,7 +231,6 @@ type CreateRequest struct { // GetRAM returns RAM field values func (r CreateRequest) GetRAM() map[string]uint64 { - res := make(map[string]uint64, 1) res["RAM"] = r.RAM @@ -239,12 +238,6 @@ func (r CreateRequest) GetRAM() map[string]uint64 { return res } -type wrapperCreateRequest struct { - CreateRequest - Interfaces []string `url:"interfaces,omitempty"` - DataDisks []string `url:"dataDisks,omitempty"` -} - // Create creates KVM x86 VM based on specified OS image func (k KVMX86) Create(ctx context.Context, req CreateRequest) (uint64, error) { err := validators.ValidateRequest(req) @@ -252,55 +245,12 @@ func (k KVMX86) Create(ctx context.Context, req CreateRequest) (uint64, error) { return 0, validators.ValidationErrors(validators.GetErrors(err)) } - var interfaces []string - - if len(req.Interfaces) != 0 { - interfaces = make([]string, 0, len(req.Interfaces)) - - for i := range req.Interfaces { - b, err := json.Marshal(req.Interfaces[i]) - if err != nil { - return 0, err - } - - interfaces = append(interfaces, string(b)) - } - } else if req.Interfaces != nil && len(req.Interfaces) == 0 { - interfaces = []string{"[]"} - } - - var dataDisks []string - - if len(req.DataDisks) != 0 { - dataDisks = make([]string, 0, len(req.DataDisks)) - - for i := range req.DataDisks { - b, err := json.Marshal(req.DataDisks[i]) - if err != nil { - return 0, err - } - - dataDisks = append(dataDisks, string(b)) - } - } - - reqWrapped := wrapperCreateRequest{ - CreateRequest: req, - Interfaces: interfaces, - DataDisks: dataDisks, - } - url := "/cloudapi/kvmx86/create" - res, err := k.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped) + res, err := k.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req) if err != nil { return 0, err } - result, err := strconv.ParseUint(string(res), 10, 64) - if err != nil { - return 0, err - } - - return result, nil + return strconv.ParseUint(string(res), 10, 64) } diff --git a/pkg/cloudapi/kvmx86/create_blank.go b/pkg/cloudapi/kvmx86/create_blank.go index d39881d..1be5b9b 100644 --- a/pkg/cloudapi/kvmx86/create_blank.go +++ b/pkg/cloudapi/kvmx86/create_blank.go @@ -2,10 +2,10 @@ package kvmx86 import ( "context" - "encoding/json" "net/http" "strconv" + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants" "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" ) @@ -136,12 +136,6 @@ func (r CreateBlankRequest) GetRAM() map[string]uint64 { return res } -type wrapperCreateBlankRequest struct { - CreateBlankRequest - Interfaces []string `url:"interfaces,omitempty"` - DataDisks []string `url:"dataDisks,omitempty"` -} - // CreateBlank creates KVM x86 VM from scratch func (k KVMX86) CreateBlank(ctx context.Context, req CreateBlankRequest) (uint64, error) { err := validators.ValidateRequest(req) @@ -149,55 +143,12 @@ func (k KVMX86) CreateBlank(ctx context.Context, req CreateBlankRequest) (uint64 return 0, validators.ValidationErrors(validators.GetErrors(err)) } - var interfaces []string - - if len(req.Interfaces) != 0 { - interfaces = make([]string, 0, len(req.Interfaces)) - - for i := range req.Interfaces { - b, err := json.Marshal(req.Interfaces[i]) - if err != nil { - return 0, err - } - - interfaces = append(interfaces, string(b)) - } - } else if req.Interfaces != nil && len(req.Interfaces) == 0 { - interfaces = []string{"[]"} - } - - var dataDisks []string - - if len(req.DataDisks) != 0 { - dataDisks = make([]string, 0, len(req.DataDisks)) - - for i := range req.DataDisks { - b, err := json.Marshal(req.DataDisks[i]) - if err != nil { - return 0, err - } - - dataDisks = append(dataDisks, string(b)) - } - } - - reqWrapped := wrapperCreateBlankRequest{ - CreateBlankRequest: req, - Interfaces: interfaces, - DataDisks: dataDisks, - } - url := "/cloudapi/kvmx86/createBlank" - res, err := k.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped) + res, err := k.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req) if err != nil { return 0, err } - result, err := strconv.ParseUint(string(res), 10, 64) - if err != nil { - return 0, err - } - - return result, nil + return strconv.ParseUint(string(res), 10, 64) } diff --git a/pkg/cloudbroker/compute/migrate.go b/pkg/cloudbroker/compute/migrate.go index 500513e..74fed6d 100644 --- a/pkg/cloudbroker/compute/migrate.go +++ b/pkg/cloudbroker/compute/migrate.go @@ -18,11 +18,6 @@ type MigrateRequest struct { // Particular Node ID to migrate this compute to // Required: false TargetNodeID uint64 `url:"targetNodeId,omitempty" json:"targetNodeId,omitempty"` - - // If live migration fails, destroy compute - // on source node and recreate on the target - // Required: false - Force bool `url:"force,omitempty" json:"force,omitempty"` } type AsyncWrapperMigrateRequest struct { diff --git a/pkg/cloudbroker/compute/stop_migration_in.go b/pkg/cloudbroker/compute/stop_migration_in.go index 91cdf6c..9ae9600 100644 --- a/pkg/cloudbroker/compute/stop_migration_in.go +++ b/pkg/cloudbroker/compute/stop_migration_in.go @@ -12,15 +12,19 @@ import ( // Must be provided if NewVMUUID is provided. type OSUser struct { // Login of a user - Login string `url:"login,omitempty" json:"login,omitempty"` + // Required: true + Login string `url:"login" json:"login" validate:"required"` // Password of a user - Password string `url:"password,omitempty" json:"password,omitempty"` + // Required: true + Password string `url:"password" json:"password" validate:"required"` // GUID + // Required: false GUID string `url:"guid,omitempty" json:"guid,omitempty"` // Pubkey + // Required: false Pubkey string `url:"pubkey,omitempty" json:"pubkey,omitempty"` } @@ -36,7 +40,7 @@ type StopMigrationINRequest struct { // OS user data for Guest OS // Required: false - OSUsers []OSUser `url:"os_users,omitempty" json:"os_users,omitempty"` + OSUsers []OSUser `url:"os_users,omitempty" json:"os_users,omitempty" validate:"omitempty,dive"` } // StopMigrationIN stops compute for external migration in diff --git a/pkg/cloudbroker/kvmx86/create.go b/pkg/cloudbroker/kvmx86/create.go index c7c2f44..a80d834 100644 --- a/pkg/cloudbroker/kvmx86/create.go +++ b/pkg/cloudbroker/kvmx86/create.go @@ -2,10 +2,10 @@ package kvmx86 import ( "context" - "encoding/json" "net/http" "strconv" + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants" "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" ) @@ -254,7 +254,6 @@ type CreateRequest struct { // GetRAM returns RAM field values func (r CreateRequest) GetRAM() map[string]uint64 { - res := make(map[string]uint64, 1) res["RAM"] = r.RAM @@ -262,12 +261,6 @@ func (r CreateRequest) GetRAM() map[string]uint64 { return res } -type wrapperCreateRequest struct { - CreateRequest - Interfaces []string `url:"interfaces,omitempty"` - DataDisks []string `url:"dataDisks,omitempty"` -} - // Create creates KVM PowerPC VM based on specified OS image func (k KVMX86) Create(ctx context.Context, req CreateRequest) (uint64, error) { err := validators.ValidateRequest(req) @@ -275,55 +268,12 @@ func (k KVMX86) Create(ctx context.Context, req CreateRequest) (uint64, error) { return 0, validators.ValidationErrors(validators.GetErrors(err)) } - var interfaces []string - - if len(req.Interfaces) != 0 { - interfaces = make([]string, 0, len(req.Interfaces)) - - for i := range req.Interfaces { - b, err := json.Marshal(req.Interfaces[i]) - if err != nil { - return 0, err - } - - interfaces = append(interfaces, string(b)) - } - } else if req.Interfaces != nil && len(req.Interfaces) == 0 { - interfaces = []string{"[]"} - } - - var dataDisks []string - - if len(req.DataDisks) != 0 { - dataDisks = make([]string, 0, len(req.DataDisks)) - - for i := range req.DataDisks { - b, err := json.Marshal(req.DataDisks[i]) - if err != nil { - return 0, err - } - - dataDisks = append(dataDisks, string(b)) - } - } - - reqWrapped := wrapperCreateRequest{ - CreateRequest: req, - Interfaces: interfaces, - DataDisks: dataDisks, - } - url := "/cloudbroker/kvmx86/create" - res, err := k.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped) + res, err := k.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req) if err != nil { return 0, err } - result, err := strconv.ParseUint(string(res), 10, 64) - if err != nil { - return 0, err - } - - return result, nil + return strconv.ParseUint(string(res), 10, 64) } diff --git a/pkg/cloudbroker/kvmx86/create_blank.go b/pkg/cloudbroker/kvmx86/create_blank.go index 4d15bfa..99861ef 100644 --- a/pkg/cloudbroker/kvmx86/create_blank.go +++ b/pkg/cloudbroker/kvmx86/create_blank.go @@ -2,10 +2,10 @@ package kvmx86 import ( "context" - "encoding/json" "net/http" "strconv" + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants" "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" ) @@ -149,12 +149,6 @@ func (r CreateBlankRequest) GetRAM() map[string]uint64 { return res } -type wrapperCreateBlankRequest struct { - CreateBlankRequest - Interfaces []string `url:"interfaces,omitempty"` - DataDisks []string `url:"dataDisks,omitempty"` -} - // CreateBlank creates KVM x86 VM from scratch func (k KVMX86) CreateBlank(ctx context.Context, req CreateBlankRequest) (uint64, error) { err := validators.ValidateRequest(req) @@ -162,56 +156,12 @@ func (k KVMX86) CreateBlank(ctx context.Context, req CreateBlankRequest) (uint64 return 0, validators.ValidationErrors(validators.GetErrors(err)) } - var interfaces []string - - if len(req.Interfaces) != 0 { - interfaces = make([]string, 0, len(req.Interfaces)) - - for i := range req.Interfaces { - b, err := json.Marshal(req.Interfaces[i]) - if err != nil { - return 0, err - } - - interfaces = append(interfaces, string(b)) - } - } else if req.Interfaces != nil && len(req.Interfaces) == 0 { - interfaces = []string{"[]"} - } - - var dataDisks []string - - if len(req.DataDisks) != 0 { - dataDisks = make([]string, 0, len(req.DataDisks)) - - for i := range req.DataDisks { - b, err := json.Marshal(req.DataDisks[i]) - if err != nil { - return 0, err - } - - dataDisks = append(dataDisks, string(b)) - } - } - - reqWrapped := wrapperCreateBlankRequest{ - CreateBlankRequest: req, - Interfaces: interfaces, - DataDisks: dataDisks, - } - url := "/cloudbroker/kvmx86/createBlank" - res, err := k.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped) + res, err := k.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req) if err != nil { return 0, err } - result, err := strconv.ParseUint(string(res), 10, 64) - if err != nil { - return 0, err - } - - return result, nil - + return strconv.ParseUint(string(res), 10, 64) } diff --git a/pkg/cloudbroker/kvmx86/mass_create.go b/pkg/cloudbroker/kvmx86/mass_create.go index 11c0e30..405040b 100644 --- a/pkg/cloudbroker/kvmx86/mass_create.go +++ b/pkg/cloudbroker/kvmx86/mass_create.go @@ -3,8 +3,11 @@ package kvmx86 import ( "context" "encoding/json" + "errors" + "fmt" "net/http" + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants" "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" ) @@ -177,14 +180,8 @@ type MassCreateRequest struct { Clock string `url:"clock,omitempty" json:"clock,omitempty"` } -type asyncWrapperMassCreateRequest struct { - wrapperMassCreateRequest - AsyncMode bool `url:"asyncMode"` -} - // GetRAM returns RAM field values func (r MassCreateRequest) GetRAM() map[string]uint64 { - res := make(map[string]uint64, 1) res["RAM"] = r.RAM @@ -194,8 +191,24 @@ func (r MassCreateRequest) GetRAM() map[string]uint64 { type wrapperMassCreateRequest struct { MassCreateRequest - Interfaces []string `url:"interfaces,omitempty"` - DataDisks []string `url:"dataDisks,omitempty"` + AsyncMode bool `json:"asyncMode"` +} + +type massCreateResponse struct { + Created []uint64 `json:"created"` + Errors map[string]string `json:"errors"` +} + +type MassCreateError struct { + Errors map[string]string +} + +func (e *MassCreateError) Error() string { + errs := make([]error, 0, len(e.Errors)) + for k, v := range e.Errors { + errs = append(errs, fmt.Errorf("%s: %s", k, v)) + } + return errors.Join(errs...).Error() } // MassCreate creates KVM x86 computes based on specified OS image @@ -205,113 +218,42 @@ func (k KVMX86) MassCreate(ctx context.Context, req MassCreateRequest) ([]uint64 return nil, validators.ValidationErrors(validators.GetErrors(err)) } - var interfaces []string - - if len(req.Interfaces) != 0 { - interfaces = make([]string, 0, len(req.Interfaces)) - - for i := range req.Interfaces { - b, err := json.Marshal(req.Interfaces[i]) - if err != nil { - return nil, err - } - - interfaces = append(interfaces, string(b)) - } - } else if req.Interfaces != nil && len(req.Interfaces) == 0 { - interfaces = []string{"[]"} - } - - var dataDisks []string - - if len(req.DataDisks) != 0 { - dataDisks = make([]string, 0, len(req.DataDisks)) - - for i := range req.DataDisks { - b, err := json.Marshal(req.DataDisks[i]) - if err != nil { - return nil, err - } - - dataDisks = append(dataDisks, string(b)) - } - } - - reqWrapped := wrapperMassCreateRequest{ - MassCreateRequest: req, - Interfaces: interfaces, - DataDisks: dataDisks, - } - - finalReq := asyncWrapperMassCreateRequest{wrapperMassCreateRequest: reqWrapped, AsyncMode: false} - url := "/cloudbroker/kvmx86/massCreate" - res, err := k.client.DecortApiCall(ctx, http.MethodPost, url, finalReq) + res, err := k.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, wrapperMassCreateRequest{ + MassCreateRequest: req, + AsyncMode: false, + }) if err != nil { return nil, err } - computes := make([]uint64, 0) + var result massCreateResponse - err = json.Unmarshal(res, &computes) - if err != nil { + if err = json.Unmarshal(res, &result); err != nil { return nil, err } - return computes, nil + if len(result.Errors) > 0 { + return result.Created, &MassCreateError{Errors: result.Errors} + } + + return result.Created, nil } -// MassCreate creates KVM x86 computes based on specified OS image in async mode +// MassCreateAsync creates KVM x86 computes based on specified OS image in async mode func (k KVMX86) MassCreateAsync(ctx context.Context, req MassCreateRequest) (string, error) { err := validators.ValidateRequest(req) if err != nil { return "", validators.ValidationErrors(validators.GetErrors(err)) } - var interfaces []string - - if len(req.Interfaces) != 0 { - interfaces = make([]string, 0, len(req.Interfaces)) - - for i := range req.Interfaces { - b, err := json.Marshal(req.Interfaces[i]) - if err != nil { - return "", err - } - - interfaces = append(interfaces, string(b)) - } - } else if req.Interfaces != nil && len(req.Interfaces) == 0 { - interfaces = []string{"[]"} - } - - var dataDisks []string - - if len(req.DataDisks) != 0 { - dataDisks = make([]string, 0, len(req.DataDisks)) - - for i := range req.DataDisks { - b, err := json.Marshal(req.DataDisks[i]) - if err != nil { - return "", err - } - - dataDisks = append(dataDisks, string(b)) - } - } - - reqWrapped := wrapperMassCreateRequest{ - MassCreateRequest: req, - Interfaces: interfaces, - DataDisks: dataDisks, - } - - finalReq := asyncWrapperMassCreateRequest{wrapperMassCreateRequest: reqWrapped, AsyncMode: true} - url := "/cloudbroker/kvmx86/massCreate" - res, err := k.client.DecortApiCall(ctx, http.MethodPost, url, finalReq) + res, err := k.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, wrapperMassCreateRequest{ + MassCreateRequest: req, + AsyncMode: true, + }) if err != nil { return "", err } diff --git a/pkg/cloudbroker/node/install.go b/pkg/cloudbroker/node/install.go new file mode 100644 index 0000000..d421ba3 --- /dev/null +++ b/pkg/cloudbroker/node/install.go @@ -0,0 +1,76 @@ +package node + +import ( + "context" + "net/http" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// InstallRequest struct to install a node +type InstallRequest struct { + // Node name + // Required: true + Name string `url:"name" json:"name" validate:"required"` + + // Node roles + // Required: true + Roles []string `url:"roles" json:"roles" validate:"required"` + + // OS version + // Required: true + OSVersion string `url:"os_version" json:"os_version" validate:"required"` + + // OS user + // Required: false + OSUser string `url:"os_user,omitempty" json:"os_user,omitempty"` + + // OS user password + // Required: true + OSUserPassword string `url:"os_user_password" json:"os_user_password" validate:"required"` + + // Backplane IP address + // Required: true + BackplaneIP string `url:"backplane_ip" json:"backplane_ip" validate:"required"` + + // Management IP address + // Required: true + ManagementIP string `url:"management_ip" json:"management_ip" validate:"required"` + + // VX backend IP address + // Required: true + VXBackendIP string `url:"vxbackend_ip" json:"vxbackend_ip" validate:"required"` + + // Gateway management IP address + // Required: true + GWMgmtIP string `url:"gw_mgmt_ip" json:"gw_mgmt_ip" validate:"required"` + + // IPMI address + // Required: true + IPMIAddress string `url:"ipmi_address" json:"ipmi_address" validate:"required"` + + // IPMI user + // Required: true + IPMIUser string `url:"ipmi_user" json:"ipmi_user" validate:"required"` + + // IPMI password + // Required: true + IPMIPassword string `url:"ipmi_password" json:"ipmi_password" validate:"required"` +} + +// Install installs a node +func (n Node) Install(ctx context.Context, req InstallRequest) (string, error) { + err := validators.ValidateRequest(req) + if err != nil { + return "", validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/node/install" + + res, err := n.client.DecortApiCall(ctx, http.MethodPost, url, req) + if err != nil { + return "", err + } + + return string(res), nil +} diff --git a/pkg/cloudbroker/zone/models.go b/pkg/cloudbroker/zone/models.go index 306c608..50dc179 100644 --- a/pkg/cloudbroker/zone/models.go +++ b/pkg/cloudbroker/zone/models.go @@ -12,6 +12,21 @@ type CpuAlignmentProfile struct { Model string `json:"model"` } +// Supported CPU model +type SupportedCpuModel struct { + // Vendor + Vendor string `json:"vendor"` + + // Model + Model string `json:"model"` + + // Count + Count uint64 `json:"count"` + + // Percentage + Percentage float64 `json:"percentage"` +} + // CPU alignment profile candidate type CpuAlignmentProfileCandidate struct { // Profile name @@ -27,7 +42,7 @@ type CpuAlignmentProfileCandidate struct { Count uint64 `json:"count"` // Percentage - Percentage uint64 `json:"percentage"` + Percentage float64 `json:"percentage"` // Required count RequiredCount uint64 `json:"required_count"` @@ -40,6 +55,9 @@ type TestCPUAlignmentProfileResult struct { // Candidates Candidates []CpuAlignmentProfileCandidate `json:"candidates"` + + // Supported CPU models + SupportedCpuModels []SupportedCpuModel `json:"supported_cpu_models"` } // Item for list_cpu_alignment_profile response diff --git a/pkg/sdn/logicalports/update.go b/pkg/sdn/logicalports/update.go index a825fb4..ba8213f 100644 --- a/pkg/sdn/logicalports/update.go +++ b/pkg/sdn/logicalports/update.go @@ -116,8 +116,8 @@ type AddAddress struct { IsPrimary interface{} `url:"is_primary" json:"is_primary" validate:"required,isBool"` // MAC address - // Required: false - MAC string `url:"mac,omitempty" json:"mac,omitempty"` + // Required: true + MAC string `url:"mac" json:"mac" validate:"required"` } // Update updates a logical port diff --git a/tests/platform_upgrade/request_map.go b/tests/platform_upgrade/request_map.go index b487dd2..ca678c4 100644 --- a/tests/platform_upgrade/request_map.go +++ b/tests/platform_upgrade/request_map.go @@ -912,6 +912,7 @@ func getRequestsMapCloudbroker() map[string]interface{} { "/restmachine/cloudbroker/node/get_pci_devices": node_cb.GetPCIDevicesRequest{}, "/restmachine/cloudbroker/node/pci_device_driver_to_vfio": node_cb.PCIDeviceDriverToVFIORequest{}, "/restmachine/cloudbroker/node/pci_device_driver_to_kernel": node_cb.PCIDeviceDriverToKernelRequest{}, + "/restmachine/cloudbroker/node/install": node_cb.InstallRequest{}, // pcidevice "/restmachine/cloudbroker/pcidevice/create": pcidevice_cb.CreateRequest{},