diff --git a/CHANGELOG.md b/CHANGELOG.md index a0dadd8..143a530 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## Version 1.16.6 +## Version 1.16.7 ### Deprecated @@ -10,6 +10,14 @@ | `account/AddUser` | :heavy_check_mark: | :heavy_check_mark: | | `account/DeleteUser` | :heavy_check_mark: | :heavy_check_mark: | | `account/UpdateUser` | :heavy_check_mark: | :heavy_check_mark: | +| `compute/DiskQOS` | :heavy_check_mark: | :heavy_check_mark: | +| `compute/Migrate` | :x: | :heavy_check_mark: | +| `compute/MigrateAbort` | :x: | :heavy_check_mark: | +| `compute/MigrateStorage` | :x: | :heavy_check_mark: | +| `compute/MigrateStorageAbort` | :x: | :heavy_check_mark: | +| `compute/MigrateStorageCleanUp` | :x: | :heavy_check_mark: | +| `compute/MigrateStorageInfo` | :x: | :heavy_check_mark: | +| `compute/MigrateStorageList` | :x: | :heavy_check_mark: | | `compute/UserGrant` | :heavy_check_mark: | :heavy_check_mark: | | `compute/UserList` | :heavy_check_mark: | :heavy_check_mark: | | `compute/UserRevoke` | :heavy_check_mark: | :heavy_check_mark: | @@ -22,77 +30,248 @@ ### Добавлено -#### apiaccess +#### compute | Идентификатор задачи | Описание | | --- | --- | -| BGOS-1091 | Опциональное поле `UserID` в структуру запроса `ListRequest` в cloudbroker/apiaccess | +| BGOS-1111 | Опциональное поле `Planned` в структуру запроса `DiskSwitchToReplicationRequest` в cloudapi/compute | +| BGOS-1111 | Опциональное поле `Planned` в структуру запроса `DiskSwitchToReplicationRequest` в cloudbroker/compute | +| BGOS-1118 | Вычисляемое поле `CRTTracking` в структуру ответа `ItemComputeDisk` в cloudapi/compute | +| BGOS-1118 | Вычисляемое поле `CRTTracking` в структуру ответа `ItemDisk` в cloudbroker/compute | +| BGOS-1120 | Структура запроса `wrapperMigrateStorageRequest` и метод `MigrateStorageAsync` в cloudbroker/compute | -#### audit +#### disks | Идентификатор задачи | Описание | | --- | --- | -| BGOS-1088 | Опциональные поля `DiskID` и `VMFolderID` в структуру запроса `ListRequest` в cloudapi/audit | -| BGOS-1088 | Опциональные поля `DiskID` и `VMFolderID` в структуру запроса `ListRequest` в cloudbroker/audit | +| BGOS-1109 | Структура запроса `ReplicationManualSyncRequest` и метод `ReplicationManualSync` в cloudapi/disks | +| BGOS-1109 | Структура запроса `ReplicationSetScheduleRequest` и метод `ReplicationSetSchedule` в cloudapi/disks | +| BGOS-1109 | Структура запроса `ReplicationDisableScheduleRequest` и метод `ReplicationDisableSchedule` в cloudapi/disks | +| BGOS-1109 | Структура запроса `ReplicationSetCopyRateRequest` и метод `ReplicationSetCopyRate` в cloudapi/disks | +| BGOS-1109 | Структура запроса `ReplicationPromote` и методы `ReplicationPromote` и `ReplicationPromoteAsync` в cloudapi/disks | +| BGOS-1109 | Структура запроса `ReplicationSyncNowRequest` и метод `ReplicationSyncNow` в cloudbroker/disks | +| BGOS-1109 | Структура запроса `ReplicationEnableScheduleRequest` и метод `ReplicationEnableSchedule` в cloudbroker/disks | +| BGOS-1109 | Структура запроса `ReplicationDisableScheduleRequest` и метод `ReplicationDisableSchedule` в cloudbroker/disks | +| BGOS-1109 | Структура запроса `ReplicationSetCopyRateRequest` и метод `ReplicationSetCopyRate` в cloudbroker/disks | +| BGOS-1109 | Структура запроса `ReplicationPromote` и методы `ReplicationPromote` и `ReplicationPromoteAsync` в cloudbroker/disks | +| BGOS-1108 | Вычисляемое поле `CRTTracking` в структуру ответа `InfoDisk` в cloudbroker/disks | +| BGOS-1108 | Вычисляемое поле `CRTTracking` в структуры ответа `ItemDisk`, `ItemDiskUnattached` и `RecordDisk` в cloudapi/disks | +| BGOS-1110 | Опциональные поля `CopyRate` и `Schedule` в структуры запроса `ReplicateRequest` и `ReplicationStartRequest` в cloudbroker/disks | +| BGOS-1110 | Опциональное поле `Planned` в структуру запроса `ReplicationReverseRequest` в cloudbroker/disks | +| BGOS-1110 | Опциональные поля `CopyRate` и `Schedule` в структуры запроса `ReplicateRequest` и `ReplicationStartRequest` в cloudapi/disks | +| BGOS-1110 | Опциональное поле `Planned` в структуру запроса `ReplicationReverseRequest` в cloudapi/disks | +| BGOS-1113 | Опциональное поле `KeepCurrentIOTune` в структуру запроса `ChangeDiskStoragePolicyRequest` в cloudbroker/disks | +| BGOS-1113 | Опциональное поле `KeepCurrentIOTune` в структуру запроса `ChangeDiskStoragePolicyRequest` в cloudapi/disks | +| BGOS-1114 | Опциональные поля `TotalBytesSecMaxLength`, `ReadBytesSecMaxLength`, `WriteBytesSecMaxLength`, `TotalIOPSSecMaxLength`, `ReadIOPSSecMaxLength` и `WriteIOPSSecMaxLength` в структуру запроса `LimitIORequest` в cloudbroker/disks | +| BGOS-1114 | Опциональные поля `TotalBytesSecMaxLength`, `ReadBytesSecMaxLength`, `WriteBytesSecMaxLength`, `TotalIOPSSecMaxLength`, `ReadIOPSSecMaxLength` и `WriteIOPSSecMaxLength` в структуру запроса `LimitIORequest` в cloudapi/disks | -#### extnet +#### dpdknet | Идентификатор задачи | Описание | | --- | --- | -| BGOS-1092 | Метод `EnableAsync` в cloudbroker/extnet | +| BGOS-1116 | Опциональные поля `AccountAccess` и `RGAccess` в структуру запроса `ListRequest` в cloudapi/dpdknet | -#### node +#### pcidevice | Идентификатор задачи | Описание | | --- | --- | -| BGOS-1065 | Структура запроса `RemoveSSHIdentityRequest` и метод `RemoveSSHIdentity` в cloudbroker/node | -| BGOS-1101 | Вычисляемое поле `SharedLocks` в структуру ответа `ItemNode` в cloudbroker/node | -| BGOS-1086 | Вычисляемые поля `LinkState` и `LinkSpeed` в структуру ответа `ItemNicInfo` в cloudbroker/node | +| BGOS-1115 | Опциональное поле `NodeID` в структуру запроса `ListRequest` в cloudbroker/pcidevice | +| BGOS-1115 | Опциональное поле `NodeID` в структуру запроса `ListRequest` в cloudapi/pcidevice | -#### vins +#### SDN defsecpolicies | Идентификатор задачи | Описание | | --- | --- | -| BGOS-1102 | Вычисляемое поле `EnableDefaultGateway` в структуры ответа `VNFsConfig` и `ItemInterface` в cloudbroker/vins | -| BGOS-1102 | Вычисляемое поле `EnableDefaultGateway` в структуры ответа `RecordDHCPConfig` и `ItemVNFInterface` в cloudapi/vins | +| BGOS-1103 | Вычисляемое поле `AccessGroupName` в структуру ответа `SecurityPolicy` в sdn/defsecpolicies | +| BGOS-1103 | Вычисляемые поля `AppliedNetObjectGroups`, `DestinationNetObjectGroups`, `LoggingProfile`, `LoggingProfileID`, `SecurityRuleConditionGroups`, `SecurityRuleConditions`, `SourceNetObjectGroups` и `Type` в структуру ответа `SecurityRule` в sdn/defsecpolicies | +| BGOS-1103 | Вычисляемые поля `EthType`, `IPProto`, `TCPSrcPorts` и `UDPSrcPorts` в структуру ответа `FilterParams` в sdn/defsecpolicies | +| BGOS-1103 | Структуры ответа `AppliedNetObjectGroup`, `NetObjectGroup`, `LoggingProfile`, `SecurityRuleConditionGroup` и `SecurityRuleCondition` в sdn/defsecpolicies | + +#### SDN extnet +| Идентификатор задачи | Описание | +| --- | --- | +| BGOS-1105 | Вычисляемые поля `OperationStatus` и `HypervisorStatus` в структуру ответа `Status` в sdn/extnet | +| BGOS-1105 | Вычисляемое поле `OperationStatus` в структуру ответа `HypervisorStatus` в sdn/extnet | +| BGOS-1105 | Вычисляемые поля `ExternalNetworkID`, `ID` и `VersionID` в структуру ответа `ExternalNetworkPort` в sdn/extnet | +| BGOS-1105 | Вычисляемые поля `CreatedBy` и `UpdatedBy` в структуру ответа `FloatingIP` в sdn/extnet | +| BGOS-1105 | Вычисляемые поля `ExcludeFirewall` и `Labels` в структуру ответа `LogicalPort` в sdn/extnet | +| BGOS-1105 | Вычисляемые поля `L2ConnectionPort` и `Type` в структуру ответа `Segment` в sdn/extnet | +| BGOS-1105 | Обязательное поле `OperationStatus` в структуру запроса `StatusRequest` в sdn/extnet | +| BGOS-1105 | Обязательное поле `OperationStatus` в структуру запроса `HypervisorStatusRequest` в sdn/extnet | +| BGOS-1105 | Опциональные поля `CreatedBy` и `UpdatedBy` в структуру запроса `FloatingIPRequest` в sdn/extnet | +| BGOS-1105 | Обязательные поля `DisplayName` и `ExcludeFirewall` в структуру запроса `LogicalPortRequest` в sdn/extnet | +| BGOS-1105 | Опциональное поле `Labels` в структуру запроса `LogicalPortRequest` в sdn/extnet | +| BGOS-1105 | Обязательные поля `IPv4Address` и `IPv6Address` в структуру запроса `RouterPortRequest` в sdn/extnet | +| BGOS-1105 | Обязательное поле `Type` в структуру запроса `SegmentRequest` в sdn/extnet | +| BGOS-1105 | Опциональное поле `L2ConnectionPort` в структуру запроса `SegmentRequest` в sdn/extnet | + +#### SDN routers +| Идентификатор задачи | Описание | +| --- | --- | +| BGOS-1106 | Вычисляемое поле `OperationStatus` в структуру ответа `Status` в sdn/routers | +| BGOS-1106 | Вычисляемое поле `OperationStatus` в структуру ответа `Status` в sdn/routers/gwport | +| BGOS-1106 | Вычисляемое поле `OperationStatus` в структуру ответа `HypervisorStatus` в sdn/routers | +| BGOS-1106 | Вычисляемое поле `OperationStatus` в структуру ответа `HypervisorStatus` в sdn/routers/gwport | +| BGOS-1106 | Вычисляемые поля `ExternalNetworkID`, `ID` и `VersionID` в структуру ответа `ExternalNetworkPort` в sdn/routers | +| BGOS-1106 | Вычисляемые поля `ExternalNetworkID`, `ID` и `VersionID` в структуру ответа `ExternalNetworkPort` в sdn/routers/gwport | +| BGOS-1106 | Вычисляемые поля `CreatedBy` и `UpdatedBy` в структуру ответа `FloatingIP` в sdn/routers | +| BGOS-1106 | Вычисляемые поля `CreatedBy` и `UpdatedBy` в структуру ответа `FloatingIP` в sdn/routers/gwport | +| BGOS-1106 | Вычисляемые поля `ExcludeFirewall` и `Labels` в структуру ответа `LogicalPort` в sdn/routers | +| BGOS-1106 | Вычисляемые поля `ExcludeFirewall` и `Labels` в структуру ответа `LogicalPort` в sdn/routers/gwport | +| BGOS-1106 | Вычисляемые поля `L2ConnectionPort` и `Type` в структуру ответа `Segment` в sdn/routers | +| BGOS-1106 | Вычисляемые поля `L2ConnectionPort` и `Type` в структуру ответа `Segment` в sdn/routers/gwport | +| BGOS-1106 | Структуры ответа `ExcludeFirewall`, `Labels`, `L2ConnectionPort` и `L2ExternalNetwork` в sdn/routers | +| BGOS-1106 | Структуры ответа `ExcludeFirewall`, `Labels`, `L2ConnectionPort`, `L2ExternalNetwork` и `Router` в sdn/routers/gwport | +| BGOS-1106 | Опциональное поле `OperationStatus` в структуру запроса `ListRequest` в sdn/routers | + +#### SDN secpolicies +| Идентификатор задачи | Описание | +| --- | --- | +| BGOS-1104 | Вычисляемые поля `Type`, `EndDateTime`, `LockedAt`, `ScheduleCron` и `StartDateTime` в структуру ответа `SecurityPolicySummary` в sdn/secpolicies | +| BGOS-1104 | Структура ответа `AppliedNetObjectGroup` в sdn/secpolicies | +| BGOS-1104 | Вычисляемые поля `OperationStatus` и `HypervisorStatus` в структуру ответа `Status` в sdn/secpolicies | +| BGOS-1104 | Опциональное поле `SecurityRulesForCreate` в структуру запроса `CreateRequest` в sdn/secpolicies | +| BGOS-1104 | Структуры запроса `AppliedToNetObjectGroup`, `SecurityRuleForCreate`, `RuleNetObjectGroup` и `RuleFilter` в sdn/secpolicies | +| BGOS-1104 | Опциональные поля `OperationStatus` и `Type` в структуру запроса `ListRequest` в sdn/secpolicies | +| BGOS-1104 | Обязательное поле `AccessGroupID` в структуру запроса `UpdateRequest` в sdn/secpolicies | + +#### vgpu +| Идентификатор задачи | Описание | +| --- | --- | +| BGOS-1066 | Обязательное поле `Name` в структуру запроса `CreateRequest` в cloudbroker/vgpu | +| BGOS-1066 | Опциональное поле `Name` в структуру запроса `ListRequest` в cloudbroker/vgpu | +| BGOS-1066 | Вычисляемые поля `Name` и `NodeID` в структуру ответа `ItemVGPU` в cloudbroker/vgpu | +| BGOS-1066 | Опциональное поле `Name` в структуру запроса `ListRequest` в cloudapi/vgpu | +| BGOS-1066 | Вычисляемые поля `Name` и `NodeID` в структуру ответа `ItemVGPU` в cloudapi/vgpu | +| BGOS-1066 | Структура запроса `EditRequest` и метод `Edit` в cloudbroker/vgpu | +| BGOS-1066 | Методы `CreateAsync`, `EditAsync` и `DestroyAsync` в cloudbroker/vgpu | #### user | Идентификатор задачи | Описание | | --- | --- | -| BGOS-1064 | Опциональное поле `ServiceAccount` в структуру запроса `CreateRequest` в clooudbroker/user | -| BGOS-1064 | Структура запроса `UpdateServiceAccountRequest` и метод `UpdateServiceAccount` в clooudbroker/user | +| BGOS-1093 | Опциональное поле `APIAccessID` в структуру запроса `ListRequest` в cloudbroker/user | ### Изменено -#### apiaccess -| Идентификатор задачи | Описание | -| --- | --- | -| BGOS-1091 | Тип вычисляемых полей `Account`, `APIAccess`, `AuditCollector`, `Backup`, `BackupCreator`, `BService`, `Compute`, `Disks`, `DPDKNet`, `Eco`, `ExtNet`, `FlIPgroup`, `Grid`, `Group`, `Health`, `Image`, `K8CI`, `K8S`, `KVMX86`, `LB`, `Metering`, `Milestones`, `PCIDevice`, `PGPU`, `Prometheus`, `RG`, `SecurityGroup`, `Sep`, `StoragePolicy`, `Tasks`, `TLock`, `Trunk`, `User`, `VFPool`, `VGPU`, `VINS`, `VMFolder`, `VNFDev`, `ZeroAccess` и `Zone` со `string` на `interface{}` в структуре ответа `CloudBrokerEndpoints` в cloudbroker/apiaccess | - #### compute | Идентификатор задачи | Описание | | --- | --- | -| BGOS-1089 | Значение по умолчанию поля `MemoryBalloonMode` с `auto` на `none` в структуре запроса `UpdateRequest` в cloudapi/compute | -| BGOS-1089 | Значение по умолчанию поля `MemoryBalloonMode` с `auto` на `none` в структуре запроса `UpdateRequest` в cloudbroker/compute | +| BGOS-1120 | Поле `Async` с обязательного на опциональное в структуре запроса `MigrateStorageRequest` в cloudbroker/compute | +| BGOS-1120 | Тэги `url` и `json` поля `AsyncMode` с `asyncMode` на `async_mode` в структуре запроса `asyncWrapperSnapshotEvictDiskRequest` в cloudbroker/compute | -#### kvmx86 +#### SDN defsecpolicies | Идентификатор задачи | Описание | | --- | --- | -| BGOS-1089 | Значение по умолчанию поля `MemoryBalloonMode` с `auto` на `none` в структурах запроса `CreateRequest` и `CreateBlankRequest` в cloudapi/kvmx86 | -| BGOS-1089 | Значение по умолчанию поля `MemoryBalloonMode` с `auto` на `none` в структурах запроса `CreateRequest`, `CreateBlankRequest` и `MassCreateRequest` в cloudbroker/kvmx86 | +| BGOS-1103 | JSON-тэг вычисляемого поля `Filter` с `filter` на `filters` и его тип с `Filter` на `[]FilterParams` в структуре ответа `SecurityRule` в sdn/defsecpolicies | + +#### SDN extnet +| Идентификатор задачи | Описание | +| --- | --- | +| BGOS-1105 | Тип опционального поля `VLANTag` со `string` на `uint64` в структуре запроса `CreateRequest` в sdn/extnet | +| BGOS-1105 | Тип опционального поля `VLANTag` со `string` на `uint64` в структуре запроса `ListRequest` в sdn/extnet | +| BGOS-1105 | Тип опционального поля `VLANTag` со `string` на `uint64` в структуре запроса `UpdateRequest` в sdn/extnet | +| BGOS-1105 | Допустимый диапазон опционального поля `VLANTag` с 1–4095 на 1–4094 в структуре запроса `CreateRequest` в sdn/extnet | +| BGOS-1105 | Допустимый диапазон опционального поля `VLANTag` с 1–4095 на 1–4094 в структуре запроса `UpdateRequest` в sdn/extnet | +| BGOS-1105 | Проверка диапазона 1–4094 для опционального поля `VLANTag` в структуре запроса `ListRequest` в sdn/extnet | +| BGOS-1105 | Тип вычисляемого поля `ExternalNetworkPort` со `string` на `*ExternalNetworkPort` в структуре ответа `FloatingIP` в sdn/extnet | +| BGOS-1105 | Тип вычисляемого поля `ExternalNetworkPort` с `interface{}` на `*ExternalNetworkPort` в структуре ответа `GatewayPort` в sdn/extnet | +| BGOS-1105 | Тип обязательного поля `ExternalNetworkPort` со `string` на `*ExternalNetworkPortRequest` в структуре запроса `FloatingIPRequest` в sdn/extnet | +| BGOS-1105 | Тип обязательного поля `ExternalNetworkPort` с `interface{}` на `*ExternalNetworkPortRequest` в структуре запроса `GatewayPortRequest` в sdn/extnet | +| BGOS-1105 | Тип полей `AccessGroupName`, `IPv4`, `IPv6`, `IPv6Config`, `RouterGatewayPort` и `FloatingIP` с опционального на обязательный в структуре запроса `ExternalNetworkPortRequest` в sdn/extnet | +| BGOS-1105 | Тип поля `LogicalPort` с опционального на обязательный в структуре запроса `FloatingIPRequest` в sdn/extnet | +| BGOS-1105 | Тип поля `HypervisorDisplayName` с опционального на обязательный в структуре запроса `LogicalPortRequest` в sdn/extnet | +| BGOS-1105 | Тип полей `LiveMigrationTargetHV`, `Status`, `Bindings` и `UpdatedAt` с обязательного на опциональный в структуре запроса `LogicalPortRequest` в sdn/extnet | +| BGOS-1105 | Тип полей `SegmentDisplayName`, `SegmentID` и `LogicalPortAddresses` с обязательного на опциональный в структуре запроса `PortBindingsRequest` в sdn/extnet | +| BGOS-1105 | Тип полей `MAC` и `AssignedAt` с опционального на обязательный в структуре запроса `LogicalPortAddressRequest` в sdn/extnet | +| BGOS-1105 | Тип поля `IsPrimary` с обязательного на опциональный в структуре запроса `LogicalPortAddressRequest` в sdn/extnet | +| BGOS-1105 | Тип полей `AccessGroupID`, `AccessGroupName`, `CreatedAt`, `Description`, `Enabled`, `GatewayPorts`, `Policies`, `Ports`, `Status`, `UpdatedAt` и `VersionID` с опционального на обязательный в структуре запроса `RouterRequest` в sdn/extnet | +| BGOS-1105 | Тип полей `ExternalL4PortMax`, `ExternalL4PortMin`, `ID` и `Status` с опционального на обязательный в структуре запроса `GatewayPortRequest` в sdn/extnet | +| BGOS-1105 | Тип полей `Enabled` и `ID` с опционального на обязательный в структуре запроса `RouterPolicyRequest` в sdn/extnet | +| BGOS-1105 | Тип полей `ID` и `Status` с опционального на обязательный в структуре запроса `RouterPortRequest` в sdn/extnet | +| BGOS-1105 | Тип полей `Enabled` и `ID` с опционального на обязательный в структуре запроса `SegmentRequest` в sdn/extnet | +| BGOS-1105 | Тип полей `LeaseTime` и `ServerMAC` с обязательного на опциональный в структуре запроса `DHCPv6ConfigRequest` в sdn/extnet | +| BGOS-1105 | Тип поля `ID` с опционального на обязательный в структуре запроса `EntityInfoRequest` в sdn/extnet | + +#### SDN routers +| Идентификатор задачи | Описание | +| --- | --- | +| BGOS-1106 | Тип вычисляемого поля `ExternalNetworkPort` со `string` на `*ExternalNetworkPort` в структуре ответа `FloatingIP` в sdn/routers | +| BGOS-1106 | Тип вычисляемого поля `ExternalNetworkPort` со `string` на `*ExternalNetworkPort` в структуре ответа `FloatingIP` в sdn/routers/gwport | +| BGOS-1106 | Тип вычисляемого поля `Router` со `string` на `*RoutersModel` в структуре ответа `FloatingIP` в sdn/routers | +| BGOS-1106 | Тип вычисляемого поля `Router` со `string` на `*Router` в структуре ответа `FloatingIP` в sdn/routers/gwport | + +#### SDN secpolicies +| Идентификатор задачи | Описание | +| --- | --- | +| BGOS-1104 | Вычисляемое поле `AppliedToNetObjectGroupID` переименовано в `AppliedNetObjectGroups` в структуре ответа `SecurityPolicySummary` в sdn/secpolicies | +| BGOS-1104 | Тип вычисляемого поля `AppliedNetObjectGroups` со `string` на `[]AppliedNetObjectGroup` в структуре ответа `SecurityPolicySummary` в sdn/secpolicies | +| BGOS-1104 | JSON-тэг вычисляемого поля `AppliedNetObjectGroups` с `applied_to_net_object_group_id` на `applied_net_object_groups` в структуре ответа `SecurityPolicySummary` в sdn/secpolicies | +| BGOS-1104 | Вычисляемое поле `Status` переименовано в `OperationStatus` в структуре ответа `HypervisorStatus` в sdn/secpolicies | +| BGOS-1104 | JSON-тэг вычисляемого поля `OperationStatus` с `status` на `operation_status` в структуре ответа `HypervisorStatus` в sdn/secpolicies | +| BGOS-1104 | Тип поля `AppliedToNetObjectGroupID` со `string` на `[]AppliedToNetObjectGroup` в структуре запроса `CreateRequest` в sdn/secpolicies | +| BGOS-1104 | Тэги `url` и `json` поля `AppliedToNetObjectGroupID` с `applied_to_net_object_group_id` на `applied_to_net_object_group_ids` в структуре запроса `CreateRequest` в sdn/secpolicies | +| BGOS-1104 | Тип поля `AppliedToNetObjectGroupID` с обязательного на опциональный в структуре запроса `CreateRequest` в sdn/secpolicies | +| BGOS-1104 | Тип опционального поля `AppliedToNetObjectGroupID` со `string` на `[]string` в структуре запроса `ListRequest` в sdn/secpolicies | +| BGOS-1104 | Тэги `url` и `json` опционального поля `AppliedToNetObjectGroupID` с `applied_to_net_object_group_id` на `applied_to_net_object_group_ids` в структуре запроса `ListRequest` в sdn/secpolicies | +| BGOS-1104 | Поле `AppliedToNetObjectGroupID` переименовано в `AppliedNetObjectGroups` в структуре запроса `UpdateRequest` в sdn/secpolicies | +| BGOS-1104 | Тип поля `AppliedNetObjectGroups` со `string` на `[]AppliedToNetObjectGroup` в структуре запроса `UpdateRequest` в sdn/secpolicies | +| BGOS-1104 | Тэги `url` и `json` поля `AppliedNetObjectGroups` с `applied_to_net_object_group_id` на `applied_net_object_groups` в структуре запроса `UpdateRequest` в sdn/secpolicies | +| BGOS-1104 | Тип поля `AppliedNetObjectGroups` с обязательного на опциональный в структуре запроса `UpdateRequest` в sdn/secpolicies | +| BGOS-1104 | Тип полей `Description` и `DisplayName` с опционального на обязательный в структуре запроса `CreateRequest` в sdn/secpolicies | +| BGOS-1104 | Тип полей `Description` и `DisplayName` с опционального на обязательный в структуре запроса `UpdateRequest` в sdn/secpolicies | #### sep | Идентификатор задачи | Описание | | --- | --- | -| BGOS-1084 | Тэг `url` поля `AsyncMode` с `sync` на `async_mode` в структурах запроса `SharedLockStartRequest` и `SharedLockStopRequest` в cloudbroker/sep | +| BGOS-1121 | Тэги `url` и `json` поля `AsyncMode` с `asyncMode` на `async_mode` в структуре запроса `wrapperAddPoolRequest` в cloudbroker/sep | + +#### vins +| Идентификатор задачи | Описание | +| --- | --- | +| BGOS-1119 | Тэги `url` и `json` поля `AsyncMode` с `asyncMode` на `async_mode` в структурах запроса `asyncWrapperCreateInAccountRequest`, `asyncWrapperEnableRequest`, `asyncWrapperCreateInRgRequest`, `asyncWrapperVNFDevRedeployRequest` и `asyncWrapperVNFDevRestartRequest` в cloudapi/vins | +| BGOS-1119 | Тэги `url` и `json` `AsyncMode` с `asyncMode` на `async_mode` в структурах запроса `asyncWrapperCreateInAccountRequest`, `asyncWrapperCreateInRgRequest`, `asyncWrapperEnableRequest`, `asyncWrapperVNFDevRedeployRequest`, `asyncWrapperVNFDevRestartRequest` и `asyncWrapperVNFDevStartRequest` в cloudbroker/vins | ### Исправлено -#### session +#### SDN secpolicies | Идентификатор задачи | Описание | | --- | --- | -| BGOS-1085 | Тип опционального поля `SID` с `uint64` на `string` в cloudbroker/session | -| BGOS-1085 | Тэг опционального поля `SortBy` с `sortBy` на `sort_by` в cloudbroker/session | +| BGOS-1104 | URL метода `Get` с `/sdn/security_policies/get` на `/sdn/security_policy/get` в sdn/secpolicies | +| BGOS-1104 | Тип поля `InsertUp` с обязательного на опциональный в структуре запроса `MoveRequest` в sdn/secpolicies | ### Удалено -#### node +#### SDN defsecpolicies | Идентификатор задачи | Описание | | --- | --- | -| BGOS-1083 | Опциональное поле `Message` из структуры запроса `EnableRequest` в cloudbroker/node | +| BGOS-1103 | Вычисляемые поля `Description`, `LockedAt` и `Status` из структуры ответа `SecurityPolicy` в sdn/defsecpolicies | +| BGOS-1103 | Вычисляемые поля `Description`, `DestinationNetObject`, `LogName`, `LogSeverity`, `SecurityPolicyID` и `SourceNetObject` из структуры ответа `SecurityRule` в sdn/defsecpolicies | +| BGOS-1103 | Вычисляемое поле `DHCP` из структуры ответа `FilterParams` в sdn/defsecpolicies | +| BGOS-1103 | Структуры ответа `Filter`, `NetObject`, `Status` и `HypervisorStatus` в sdn/defsecpolicies | + +#### SDN extnet +| Идентификатор задачи | Описание | +| --- | --- | +| BGOS-1105 | Вычисляемое поле `Common` из структуры ответа `Status` в sdn/extnet | +| BGOS-1105 | Вычисляемое поле `Status` из структуры ответа `HypervisorStatus` в sdn/extnet | +| BGOS-1105 | Вычисляемое поле `IsExcludedFromFirewall` из структуры ответа `PortBindings` в sdn/extnet | +| BGOS-1105 | Обязательное поле `Common` из структуры запроса `StatusRequest` в sdn/extnet | +| BGOS-1105 | Обязательное поле `Status` из структуры запроса `HypervisorStatusRequest` в sdn/extnet | +| BGOS-1105 | Обязательное поле `RouterDisplayName` из структуры запроса `LogicalPortRequest` в sdn/extnet | +| BGOS-1105 | Обязательное поле `IsExcludedFromFirewall` из структуры запроса `PortBindingsRequest` в sdn/extnet | +| BGOS-1105 | Обязательные поля `NextIPv4Address` и `NextIPv6Address` из структуры запроса `RouterPortRequest` в sdn/extnet | + +#### SDN routers +| Идентификатор задачи | Описание | +| --- | --- | +| BGOS-1106 | Вычисляемое поле `Common` из структуры ответа `Status` в sdn/routers | +| BGOS-1106 | Вычисляемое поле `Common` из структуры ответа `Status` в sdn/routers/gwport | +| BGOS-1106 | Вычисляемое поле `Status` из структуры ответа `HypervisorStatus` в sdn/routers | +| BGOS-1106 | Вычисляемое поле `Status` из структуры ответа `HypervisorStatus` в sdn/routers/gwport | +| BGOS-1106 | Вычисляемое поле `IsExcludedFromFirewall` из структуры ответа `Bindings` в sdn/routers | +| BGOS-1106 | Вычисляемое поле `IsExcludedFromFirewall` из структуры ответа `Bindings` в sdn/routers/gwport | + +#### SDN secpolicies +| Идентификатор задачи | Описание | +| --- | --- | +| BGOS-1104 | Вычисляемое поле `SecurityRules` из структуры ответа `SecurityPolicySummary` в sdn/secpolicies | +| BGOS-1104 | Структуры ответа `SecurityRule` и `Filter` в sdn/secpolicies | +| BGOS-1104 | Вычисляемое поле `Common` из структуры ответа `Status` в sdn/secpolicies | +| BGOS-1104 | Опциональное поле `InsertUp` из структуры запроса `UpdateRequest` в sdn/secpolicies | + diff --git a/pkg/cloudapi/compute/disk_qos.go b/pkg/cloudapi/compute/disk_qos.go index e14dfb9..eb03eca 100644 --- a/pkg/cloudapi/compute/disk_qos.go +++ b/pkg/cloudapi/compute/disk_qos.go @@ -30,6 +30,8 @@ type wrapperDiskQOSRequest struct { } // DiskQOS change QoS of the disk +// +// Deprecated: will be removed in SDK v1.17 func (c Compute) DiskQOS(ctx context.Context, req DiskQOSRequest) (bool, error) { err := validators.ValidateRequest(req) if err != nil { @@ -57,6 +59,8 @@ func (c Compute) DiskQOS(ctx context.Context, req DiskQOSRequest) (bool, error) } // DiskQOSAsync changes QoS of the disk with AsyncMode +// +// Deprecated: will be removed in SDK v1.17 func (c Compute) DiskQOSAsync(ctx context.Context, req DiskQOSRequest) (string, error) { err := validators.ValidateRequest(req) if err != nil { diff --git a/pkg/cloudapi/compute/disk_switch_to_replication.go b/pkg/cloudapi/compute/disk_switch_to_replication.go index 7817a8d..0500cdc 100644 --- a/pkg/cloudapi/compute/disk_switch_to_replication.go +++ b/pkg/cloudapi/compute/disk_switch_to_replication.go @@ -20,7 +20,11 @@ type DiskSwitchToReplicationRequest struct { // Delete replication relationship // Required: false - StopReplication bool `url:"stopReplication" json:"stopReplication"` + StopReplication bool `url:"stopReplication,omitempty" json:"stopReplication,omitempty"` + + // Use planned failover for asynchronous replication + // Required: false + Planned interface{} `url:"planned,omitempty" json:"planned,omitempty" validate:"omitempty,isBool"` } type wrapperDiskSwitchToReplicationRequest struct { diff --git a/pkg/cloudapi/compute/models.go b/pkg/cloudapi/compute/models.go index 1d248f8..44bd334 100644 --- a/pkg/cloudapi/compute/models.go +++ b/pkg/cloudapi/compute/models.go @@ -1107,6 +1107,9 @@ type ItemComputeDisk struct { // Created time CreatedTime uint64 `json:"createdTime"` + // Whether CRT tracking is enabled + CRTTracking bool `json:"crt_tracking"` + // Device name DeviceName string `json:"devicename"` diff --git a/pkg/cloudapi/disks/change_disk_storage_policy.go b/pkg/cloudapi/disks/change_disk_storage_policy.go index 5f55f96..f103955 100644 --- a/pkg/cloudapi/disks/change_disk_storage_policy.go +++ b/pkg/cloudapi/disks/change_disk_storage_policy.go @@ -18,6 +18,11 @@ type ChangeDiskStoragePolicyRequest struct { // ID of the storage policy to which to connect for disk // Required: true StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"` + + // Keep current disk I/O tune settings in the domain XML + // Required: false + // Default: false + KeepCurrentIOTune interface{} `url:"keep_current_iot,omitempty" json:"keep_current_iot,omitempty" validate:"omitempty,isBool"` } type wrapperChangeDiskStoragePolicyRequest struct { diff --git a/pkg/cloudapi/disks/limitio.go b/pkg/cloudapi/disks/limitio.go index 1737c5f..7f2612a 100644 --- a/pkg/cloudapi/disks/limitio.go +++ b/pkg/cloudapi/disks/limitio.go @@ -67,6 +67,30 @@ type LimitIORequest struct { // Required: false WriteIOPSSecMax uint64 `url:"write_iops_sec_max,omitempty" json:"write_iops_sec_max,omitempty"` + // Duration in seconds of the total bytes burst. Requires TotalBytesSecMax + // Required: false + TotalBytesSecMaxLength uint64 `url:"total_bytes_sec_max_length,omitempty" json:"total_bytes_sec_max_length,omitempty"` + + // Duration in seconds of the read bytes burst. Requires ReadBytesSecMax + // Required: false + ReadBytesSecMaxLength uint64 `url:"read_bytes_sec_max_length,omitempty" json:"read_bytes_sec_max_length,omitempty"` + + // Duration in seconds of the write bytes burst. Requires WriteBytesSecMax + // Required: false + WriteBytesSecMaxLength uint64 `url:"write_bytes_sec_max_length,omitempty" json:"write_bytes_sec_max_length,omitempty"` + + // Duration in seconds of the total IOPS burst. Requires TotalIOPSSecMax + // Required: false + TotalIOPSSecMaxLength uint64 `url:"total_iops_sec_max_length,omitempty" json:"total_iops_sec_max_length,omitempty"` + + // Duration in seconds of the read IOPS burst. Requires ReadIOPSSecMax + // Required: false + ReadIOPSSecMaxLength uint64 `url:"read_iops_sec_max_length,omitempty" json:"read_iops_sec_max_length,omitempty"` + + // Duration in seconds of the write IOPS burst. Requires WriteIOPSSecMax + // Required: false + WriteIOPSSecMaxLength uint64 `url:"write_iops_sec_max_length,omitempty" json:"write_iops_sec_max_length,omitempty"` + // SizeIOPSSec // Required: false SizeIOPSSec uint64 `url:"size_iops_sec,omitempty" json:"size_iops_sec,omitempty"` diff --git a/pkg/cloudapi/disks/models.go b/pkg/cloudapi/disks/models.go index b40244e..84bf72a 100644 --- a/pkg/cloudapi/disks/models.go +++ b/pkg/cloudapi/disks/models.go @@ -154,6 +154,9 @@ type ItemDisk struct { // Cache mode of disk Cache string `json:"cache"` + + // Whether CRT is tracked + CRTTracking bool `json:"crt_tracking"` } type ItemDiskUnattached struct { @@ -300,6 +303,9 @@ type ItemDiskUnattached struct { // Virtual machine ID VMID uint64 `json:"vmid"` + + // Whether CRT is tracked + CRTTracking bool `json:"crt_tracking"` } // List of disks searched @@ -549,6 +555,9 @@ type RecordDisk struct { // Cache mode of disk Cache string `json:"cache"` + + // Whether CRT is tracked + CRTTracking bool `json:"crt_tracking"` } type ItemReplication struct { diff --git a/pkg/cloudapi/disks/replicate.go b/pkg/cloudapi/disks/replicate.go index d4cadf2..f8c6cb5 100644 --- a/pkg/cloudapi/disks/replicate.go +++ b/pkg/cloudapi/disks/replicate.go @@ -30,6 +30,14 @@ type ReplicateRequest struct { // ID of the storage policy under the disk will be created // Required: true StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"` + + // Copy rate for an asynchronous replication pair (in MB/s) + // Required: false + CopyRate uint64 `url:"copy_rate,omitempty" json:"copy_rate,omitempty"` + + // Name of the schedule from the replication profile + // Required: false + Schedule string `url:"schedule,omitempty" json:"schedule,omitempty"` } type wrapperReplicateRequest struct { diff --git a/pkg/cloudapi/disks/replication_disable_schedule.go b/pkg/cloudapi/disks/replication_disable_schedule.go new file mode 100644 index 0000000..d16d5e4 --- /dev/null +++ b/pkg/cloudapi/disks/replication_disable_schedule.go @@ -0,0 +1,38 @@ +package disks + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// ReplicationDisableScheduleRequest to remove the schedule from an asynchronous replication pair +type ReplicationDisableScheduleRequest struct { + // Disk ID + // Required: true + DiskID uint64 `url:"disk_id" json:"disk_id" validate:"required"` +} + +// ReplicationDisableScheduleRequest removes the schedule from an asynchronous replication pair +func (d Disks) ReplicationDisableSchedule(ctx context.Context, req ReplicationDisableScheduleRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + return false, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudapi/disks/replication_disable_schedule" + + res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/pkg/cloudapi/disks/replication_manual_sync.go b/pkg/cloudapi/disks/replication_manual_sync.go new file mode 100644 index 0000000..1ee1417 --- /dev/null +++ b/pkg/cloudapi/disks/replication_manual_sync.go @@ -0,0 +1,38 @@ +package disks + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// ReplicationManualSyncRequest to start manual synchronization of an asynchronous replication pair +type ReplicationManualSyncRequest struct { + // Disk ID + // Required: true + DiskID uint64 `url:"disk_id" json:"disk_id" validate:"required"` +} + +// ReplicationManualSync starts manual synchronization of an asynchronous replication pair +func (d Disks) ReplicationManualSync(ctx context.Context, req ReplicationManualSyncRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + return false, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudapi/disks/replication_manual_sync" + + res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/pkg/cloudapi/disks/replication_promote.go b/pkg/cloudapi/disks/replication_promote.go new file mode 100644 index 0000000..e4f8cca --- /dev/null +++ b/pkg/cloudapi/disks/replication_promote.go @@ -0,0 +1,78 @@ +package disks + +import ( + "context" + "encoding/json" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// ReplicationPromoteRequest to promote the primary side of an asynchronous replication pair +type ReplicationPromoteRequest struct { + // Disk ID + // Required: true + DiskID uint64 `url:"disk_id" json:"disk_id" validate:"required"` +} + +type wrapperReplicationPromoteRequest struct { + ReplicationPromoteRequest + AsyncMode bool `url:"async_mode" json:"async_mode"` +} + +// ReplicationPromote promotes the primary side of an asynchronous replication pair +func (d Disks) ReplicationPromote(ctx context.Context, req ReplicationPromoteRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + return false, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudapi/disks/replication_promote" + + aReq := wrapperReplicationPromoteRequest{ + ReplicationPromoteRequest: req, + AsyncMode: false, + } + + res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, aReq) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} + +// ReplicationPromoteAsync promotes the primary side of an asynchronous replication pair in async mode +func (d Disks) ReplicationPromoteAsync(ctx context.Context, req ReplicationPromoteRequest) (string, error) { + err := validators.ValidateRequest(req) + if err != nil { + return "", validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudapi/disks/replication_promote" + + aReq := wrapperReplicationPromoteRequest{ + ReplicationPromoteRequest: req, + AsyncMode: true, + } + + res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, aReq) + if err != nil { + return "", err + } + + var resp string + + err = json.Unmarshal(res, &resp) + if err != nil { + return "", err + } + + return resp, nil +} diff --git a/pkg/cloudapi/disks/replication_reverse.go b/pkg/cloudapi/disks/replication_reverse.go index 5cb9d86..1f67083 100644 --- a/pkg/cloudapi/disks/replication_reverse.go +++ b/pkg/cloudapi/disks/replication_reverse.go @@ -14,6 +14,10 @@ type ReplicationReverseRequest struct { // Id of the disk // Required: true DiskID uint64 `url:"diskId" json:"diskId" validate:"required"` + + // Use planned failover for asynchronous replication + // Required: false + Planned interface{} `url:"planned,omitempty" json:"planned,omitempty" validate:"omitempty,isBool"` } type wrapperReplicationReverseRequest struct { diff --git a/pkg/cloudapi/disks/replication_set_copy_rate.go b/pkg/cloudapi/disks/replication_set_copy_rate.go new file mode 100644 index 0000000..eb69798 --- /dev/null +++ b/pkg/cloudapi/disks/replication_set_copy_rate.go @@ -0,0 +1,42 @@ +package disks + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// ReplicationSetCopyRateRequest to set the copy rate of an asynchronous replication pair +type ReplicationSetCopyRateRequest struct { + // Disk ID + // Required: true + DiskID uint64 `url:"disk_id" json:"disk_id" validate:"required"` + + // Copy rate in MB/s + // Required: true + CopyRate uint64 `url:"copy_rate" json:"copy_rate" validate:"required"` +} + +// ReplicationSetCopyRate sets the copy rate of an asynchronous replication pair +func (d Disks) ReplicationSetCopyRate(ctx context.Context, req ReplicationSetCopyRateRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + return false, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudapi/disks/replication_set_copy_rate" + + res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/pkg/cloudapi/disks/replication_set_schedule.go b/pkg/cloudapi/disks/replication_set_schedule.go new file mode 100644 index 0000000..89af09d --- /dev/null +++ b/pkg/cloudapi/disks/replication_set_schedule.go @@ -0,0 +1,46 @@ +package disks + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// ReplicationSetScheduleRequest to apply a replication profile schedule to an asynchronous replication pair +type ReplicationSetScheduleRequest struct { + // Disk ID + // Required: true + DiskID uint64 `url:"disk_id" json:"disk_id" validate:"required"` + + // ID of the replication profile assigned to the pair + // Required: true + ProfileID uint64 `url:"profile_id" json:"profile_id" validate:"required"` + + // Name of the interval or calendar schedule from the profile + // Required: true + ScheduleName string `url:"schedule_name" json:"schedule_name" validate:"required"` +} + +// ReplicationSetSchedule applies a replication profile schedule to an asynchronous replication pair +func (d Disks) ReplicationSetSchedule(ctx context.Context, req ReplicationSetScheduleRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + return false, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudapi/disks/replication_set_schedule" + + res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/pkg/cloudapi/disks/replication_start.go b/pkg/cloudapi/disks/replication_start.go index 516feb2..bd648f8 100644 --- a/pkg/cloudapi/disks/replication_start.go +++ b/pkg/cloudapi/disks/replication_start.go @@ -18,6 +18,14 @@ type ReplicationStartRequest struct { // ID of target disk. Secondary disk in replication // Required: true TargetDiskID uint64 `url:"targetDiskId" json:"targetDiskId" validate:"required"` + + // Copy rate for an asynchronous replication pair (in MB/s) + // Required: false + CopyRate uint64 `url:"copy_rate,omitempty" json:"copy_rate,omitempty"` + + // Name of the schedule from the replication profile + // Required: false + Schedule string `url:"schedule,omitempty" json:"schedule,omitempty"` } type wrapperReplicationStartRequest struct { diff --git a/pkg/cloudapi/dpdknet/list.go b/pkg/cloudapi/dpdknet/list.go index 5e0c6c7..fc8cbcc 100644 --- a/pkg/cloudapi/dpdknet/list.go +++ b/pkg/cloudapi/dpdknet/list.go @@ -34,6 +34,14 @@ type ListRequest struct { // Required: false ComputeIDs []uint64 `url:"computeIds,omitempty" json:"computeIds,omitempty"` + // Find by account access + // Required: false + AccountAccess []uint64 `url:"accountAccess,omitempty" json:"accountAccess,omitempty"` + + // Find by resource group access + // Required: false + RGAccess []uint64 `url:"rgAccess,omitempty" json:"rgAccess,omitempty"` + // Sort by one of supported fields, format +|-(field) // Required: false SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"` diff --git a/pkg/cloudapi/pcidevice/list.go b/pkg/cloudapi/pcidevice/list.go index f702593..2811384 100644 --- a/pkg/cloudapi/pcidevice/list.go +++ b/pkg/cloudapi/pcidevice/list.go @@ -34,6 +34,10 @@ type ListRequest struct { // Required: false SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"` + // Sort by node ID + // Required: false + NodeID uint64 `url:"node_id,omitempty" json:"node_id,omitempty"` + // Page number // Required: false Page uint64 `url:"page,omitempty" json:"page,omitempty"` diff --git a/pkg/cloudapi/vgpu/list.go b/pkg/cloudapi/vgpu/list.go index f51facc..b2b09ec 100644 --- a/pkg/cloudapi/vgpu/list.go +++ b/pkg/cloudapi/vgpu/list.go @@ -42,6 +42,10 @@ type ListRequest struct { // Required: false SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty" validate:"omitempty,sortBy"` + // Sort by name + // Required: false + Name string `url:"name,omitempty" json:"name,omitempty"` + // Page number // Required: false Page uint64 `url:"page,omitempty" json:"page,omitempty"` diff --git a/pkg/cloudapi/vgpu/models.go b/pkg/cloudapi/vgpu/models.go index 4c9c11e..dad2bce 100644 --- a/pkg/cloudapi/vgpu/models.go +++ b/pkg/cloudapi/vgpu/models.go @@ -54,6 +54,12 @@ type ItemVGPU struct { // Status Status string `json:"status"` + + // Name + Name string `json:"name"` + + // Node ID + NodeID uint64 `json:"node_id"` } // List of VGPU diff --git a/pkg/cloudapi/vins/create_in_account.go b/pkg/cloudapi/vins/create_in_account.go index 47306fb..4a6987c 100644 --- a/pkg/cloudapi/vins/create_in_account.go +++ b/pkg/cloudapi/vins/create_in_account.go @@ -72,7 +72,7 @@ type CreateInAccountRequest struct { type asyncWrapperCreateInAccountRequest struct { CreateInAccountRequest - AsyncMode bool `url:"asyncMode" json:"asyncMode"` + AsyncMode bool `url:"async_mode" json:"async_mode"` } // CreateInAccount creates VINS in account level diff --git a/pkg/cloudapi/vins/create_in_rg.go b/pkg/cloudapi/vins/create_in_rg.go index db441c1..0a244b2 100644 --- a/pkg/cloudapi/vins/create_in_rg.go +++ b/pkg/cloudapi/vins/create_in_rg.go @@ -66,7 +66,7 @@ type CreateInRGRequest struct { type asyncWrapperCreateInRgRequest struct { CreateInRGRequest - AsyncMode bool `url:"asyncMode" json:"asyncMode"` + AsyncMode bool `url:"async_mode" json:"async_mode"` } // CreateInRG creates VINS in resource group level diff --git a/pkg/cloudapi/vins/enable.go b/pkg/cloudapi/vins/enable.go index 3a0830b..742d28a 100644 --- a/pkg/cloudapi/vins/enable.go +++ b/pkg/cloudapi/vins/enable.go @@ -18,7 +18,7 @@ type EnableRequest struct { type asyncWrapperEnableRequest struct { EnableRequest - AsyncMode bool `url:"asyncMode"` + AsyncMode bool `url:"async_mode"` } // Enable enables VINS diff --git a/pkg/cloudapi/vins/vnfdev_redeploy.go b/pkg/cloudapi/vins/vnfdev_redeploy.go index 716a521..ac8985e 100644 --- a/pkg/cloudapi/vins/vnfdev_redeploy.go +++ b/pkg/cloudapi/vins/vnfdev_redeploy.go @@ -18,7 +18,7 @@ type VNFDevRedeployRequest struct { type asyncWrapperVNFDevRedeployRequest struct { VNFDevRedeployRequest - AsyncMode bool `url:"asyncMode"` + AsyncMode bool `url:"async_mode"` } // VNFDevRedeploy redeploys VINS VNFDevs diff --git a/pkg/cloudapi/vins/vnfdev_restart.go b/pkg/cloudapi/vins/vnfdev_restart.go index 4e2b6ae..0d5e11a 100644 --- a/pkg/cloudapi/vins/vnfdev_restart.go +++ b/pkg/cloudapi/vins/vnfdev_restart.go @@ -18,7 +18,7 @@ type VNFDevRestartRequest struct { type asyncWrapperVNFDevRestartRequest struct { VNFDevRestartRequest - AsyncMode bool `url:"asyncMode"` + AsyncMode bool `url:"async_mode"` } // VNFDevRestart reboots VINSes primary VNF device diff --git a/pkg/cloudbroker/compute/disk_qos.go b/pkg/cloudbroker/compute/disk_qos.go index 8717b40..99ff2df 100644 --- a/pkg/cloudbroker/compute/disk_qos.go +++ b/pkg/cloudbroker/compute/disk_qos.go @@ -30,6 +30,8 @@ type wrapperDiskQOSRequest struct { } // DiskQOS changes QOS of the disk +// +// Deprecated: will be removed in SDK v1.17 func (c Compute) DiskQOS(ctx context.Context, req DiskQOSRequest) (bool, error) { err := validators.ValidateRequest(req) if err != nil { @@ -57,6 +59,8 @@ func (c Compute) DiskQOS(ctx context.Context, req DiskQOSRequest) (bool, error) } // DiskQOSAsync changes QOS of the disk with AsyncMode +// +// Deprecated: will be removed in SDK v1.17 func (c Compute) DiskQOSAsync(ctx context.Context, req DiskQOSRequest) (string, error) { err := validators.ValidateRequest(req) if err != nil { diff --git a/pkg/cloudbroker/compute/disk_switch_to_replication.go b/pkg/cloudbroker/compute/disk_switch_to_replication.go index 9465df9..9523d89 100644 --- a/pkg/cloudbroker/compute/disk_switch_to_replication.go +++ b/pkg/cloudbroker/compute/disk_switch_to_replication.go @@ -21,6 +21,10 @@ type DiskSwitchToReplicationRequest struct { // Delete replication relationship // Required: false StopReplication bool `url:"stopReplication" json:"stopReplication"` + + // Use planned failover for asynchronous replication + // Required: false + Planned interface{} `url:"planned,omitempty" json:"planned,omitempty" validate:"omitempty,isBool"` } type wrapperDiskSwitchToReplicationRequest struct { diff --git a/pkg/cloudbroker/compute/migrate.go b/pkg/cloudbroker/compute/migrate.go index 5ed7c6a..4ec4373 100644 --- a/pkg/cloudbroker/compute/migrate.go +++ b/pkg/cloudbroker/compute/migrate.go @@ -26,6 +26,8 @@ type AsyncWrapperMigrateRequest struct { } // Migrate migrates compute to another node +// +// Deprecated: will be removed in SDK v1.17 func (c Compute) Migrate(ctx context.Context, req MigrateRequest) (bool, error) { err := validators.ValidateRequest(req) if err != nil { @@ -50,6 +52,8 @@ func (c Compute) Migrate(ctx context.Context, req MigrateRequest) (bool, error) } // AsyncMigrate migrates compute to another node in async mode +// +// Deprecated: will be removed in SDK v1.17 func (c Compute) AsyncMigrate(ctx context.Context, req MigrateRequest) (string, error) { err := validators.ValidateRequest(req) if err != nil { diff --git a/pkg/cloudbroker/compute/migrate_abort.go b/pkg/cloudbroker/compute/migrate_abort.go index 1f8756e..fe89dbf 100644 --- a/pkg/cloudbroker/compute/migrate_abort.go +++ b/pkg/cloudbroker/compute/migrate_abort.go @@ -22,6 +22,8 @@ type wrapperMigrateAbortRequest struct { } // MigrateAbort aborts compute migration +// +// Deprecated: will be removed in SDK v1.17 func (c Compute) MigrateAbort(ctx context.Context, req MigrateAbortRequest) (string, error) { err := validators.ValidateRequest(req) if err != nil { @@ -46,6 +48,8 @@ func (c Compute) MigrateAbort(ctx context.Context, req MigrateAbortRequest) (str } // MigrateAbortAsync aborts compute migration with AsyncMode +// +// Deprecated: will be removed in SDK v1.17 func (c Compute) MigrateAbortAsync(ctx context.Context, req MigrateAbortRequest) (string, error) { err := validators.ValidateRequest(req) if err != nil { diff --git a/pkg/cloudbroker/compute/migrate_storage.go b/pkg/cloudbroker/compute/migrate_storage.go index 9ed5c2e..8cf1778 100644 --- a/pkg/cloudbroker/compute/migrate_storage.go +++ b/pkg/cloudbroker/compute/migrate_storage.go @@ -3,6 +3,7 @@ package compute import ( "context" "net/http" + "strconv" "strings" "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" @@ -25,17 +26,48 @@ type MigrateStorageRequest struct { // Target node ID // Required: true NodeID uint64 `url:"node_id" json:"node_id" validate:"required"` +} - // Async API call - // Required: true - Async interface{} `url:"async_mode" json:"async_mode" validate:"required,isBool"` +type wrapperMigrateStorageRequest struct { + MigrateStorageRequest + AsyncMode bool `url:"async_mode,omitempty"` } // MigrateStorage gets complex compute migration // Compute will be migrated to specified node, and compute disks will // be migrated to specified SEP to specified pool. // This action can take up to 84 hours -func (c Compute) MigrateStorage(ctx context.Context, req MigrateStorageRequest) (string, error) { +func (c Compute) MigrateStorage(ctx context.Context, req MigrateStorageRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + return false, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/compute/migrateStorage" + + aReq := wrapperMigrateStorageRequest{ + MigrateStorageRequest: req, + AsyncMode: false, + } + + res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, aReq) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} + +// MigrateStorageAsync gets complex compute migration in async mode +// Compute will be migrated to specified node, and compute disks will +// be migrated to specified SEP to specified pool. +// This action can take up to 84 hours +func (c Compute) MigrateStorageAsync(ctx context.Context, req MigrateStorageRequest) (string, error) { err := validators.ValidateRequest(req) if err != nil { return "", validators.ValidationErrors(validators.GetErrors(err)) @@ -43,7 +75,12 @@ func (c Compute) MigrateStorage(ctx context.Context, req MigrateStorageRequest) url := "/cloudbroker/compute/migrateStorage" - res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req) + aReq := wrapperMigrateStorageRequest{ + MigrateStorageRequest: req, + AsyncMode: true, + } + + res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, aReq) if err != nil { return "", err } diff --git a/pkg/cloudbroker/compute/migrate_storage_abort.go b/pkg/cloudbroker/compute/migrate_storage_abort.go index 454aed6..4c4c524 100644 --- a/pkg/cloudbroker/compute/migrate_storage_abort.go +++ b/pkg/cloudbroker/compute/migrate_storage_abort.go @@ -27,6 +27,8 @@ type wrapperMigrateStorageAbortRequest struct { } // MigrateStorageAbort aborts complex compute migration job +// +// Deprecated: will be removed in SDK v1.17 func (c Compute) MigrateStorageAbort(ctx context.Context, req MigrateStorageAbortRequest) (bool, error) { err := validators.ValidateRequest(req) if err != nil { @@ -54,6 +56,8 @@ func (c Compute) MigrateStorageAbort(ctx context.Context, req MigrateStorageAbor } // MigrateStorageAbortAsync aborts complex compute migration job with AsyncMode +// +// Deprecated: will be removed in SDK v1.17 func (c Compute) MigrateStorageAbortAsync(ctx context.Context, req MigrateStorageAbortRequest) (string, error) { err := validators.ValidateRequest(req) if err != nil { diff --git a/pkg/cloudbroker/compute/migrate_storage_clean_up.go b/pkg/cloudbroker/compute/migrate_storage_clean_up.go index a350488..101f379 100644 --- a/pkg/cloudbroker/compute/migrate_storage_clean_up.go +++ b/pkg/cloudbroker/compute/migrate_storage_clean_up.go @@ -24,6 +24,8 @@ type wrapperMigrateStorageCleanUpRequest struct { // MigrateStorageCleanUp cleanup resources after finished (success of failed) complex compute migration. // If the migration was successful, then old disks will be removed, else new (target) disks will be removed. // Do it wisely! +// +// Deprecated: will be removed in SDK v1.17 func (c Compute) MigrateStorageCleanUp(ctx context.Context, req MigrateStorageCleanUpRequest) (bool, error) { err := validators.ValidateRequest(req) if err != nil { @@ -51,6 +53,8 @@ func (c Compute) MigrateStorageCleanUp(ctx context.Context, req MigrateStorageCl } // MigrateStorageCleanUpAsync cleanup resources after finished migration with AsyncMode +// +// Deprecated: will be removed in SDK v1.17 func (c Compute) MigrateStorageCleanUpAsync(ctx context.Context, req MigrateStorageCleanUpRequest) (string, error) { err := validators.ValidateRequest(req) if err != nil { diff --git a/pkg/cloudbroker/compute/migrate_storage_info.go b/pkg/cloudbroker/compute/migrate_storage_info.go index 251cbef..5ec1290 100644 --- a/pkg/cloudbroker/compute/migrate_storage_info.go +++ b/pkg/cloudbroker/compute/migrate_storage_info.go @@ -16,6 +16,8 @@ type MigrateStorageInfoRequest struct { } // MigrateStorageInfo gets info about last (include ongoing) storage migration +// +// Deprecated: will be removed in SDK v1.17 func (c Compute) MigrateStorageInfo(ctx context.Context, req MigrateStorageInfoRequest) (*RecordMigrateStorageInfo, error) { res, err := c.MigrateStorageInfoRaw(ctx, req) if err != nil { @@ -33,6 +35,8 @@ func (c Compute) MigrateStorageInfo(ctx context.Context, req MigrateStorageInfoR } // MigrateStorageInfoRaw gets info about last (include ongoing) storage migration as an array of bytes +// +// Deprecated: will be removed in SDK v1.17 func (c Compute) MigrateStorageInfoRaw(ctx context.Context, req MigrateStorageInfoRequest) ([]byte, error) { err := validators.ValidateRequest(req) if err != nil { diff --git a/pkg/cloudbroker/compute/migrate_storage_list.go b/pkg/cloudbroker/compute/migrate_storage_list.go index 3c3861c..674af5c 100644 --- a/pkg/cloudbroker/compute/migrate_storage_list.go +++ b/pkg/cloudbroker/compute/migrate_storage_list.go @@ -32,6 +32,8 @@ type MigrateStorageListRequest struct { } // MigrateStorageList gets list of the jobs. +// +// Deprecated: will be removed in SDK v1.17 func (c Compute) MigrateStorageList(ctx context.Context, req MigrateStorageListRequest) (*ListMigrateStorage, error) { if err := validators.ValidateRequest(req); err != nil { return nil, validators.ValidationErrors(validators.GetErrors(err)) diff --git a/pkg/cloudbroker/compute/models.go b/pkg/cloudbroker/compute/models.go index a7d10aa..9e8e6b3 100644 --- a/pkg/cloudbroker/compute/models.go +++ b/pkg/cloudbroker/compute/models.go @@ -424,6 +424,9 @@ type ItemDisk struct { // Created time CreatedTime uint64 `json:"createdTime"` + // Whether CRT tracking is enabled + CRTTracking bool `json:"crt_tracking"` + // Device name DeviceName string `json:"devicename"` diff --git a/pkg/cloudbroker/compute/snapshot_evict_disk.go b/pkg/cloudbroker/compute/snapshot_evict_disk.go index f91d29f..32197ec 100644 --- a/pkg/cloudbroker/compute/snapshot_evict_disk.go +++ b/pkg/cloudbroker/compute/snapshot_evict_disk.go @@ -18,15 +18,11 @@ type SnapshotEvictDiskRequest struct { // ID of the disk instance // Required: true DiskID uint64 `url:"diskId" json:"diskId" validate:"required"` - - // Is mode async - // Required: false - AsyncMode interface{} `url:"async_mode,omitempty" json:"async_mode,omitempty" validate:"omitempty,isBool"` } type asyncWrapperSnapshotEvictDiskRequest struct { SnapshotEvictDiskRequest - AsyncMode bool `url:"asyncMode" json:"asyncMode"` + AsyncMode bool `url:"async_mode,omitempty" json:"async_mode,omitempty"` } // SnapshotEvictDisk evicts specified disk from all snapshots of a compute instance diff --git a/pkg/cloudbroker/disks/change_disk_storage_policy.go b/pkg/cloudbroker/disks/change_disk_storage_policy.go index 769142c..e41fb46 100644 --- a/pkg/cloudbroker/disks/change_disk_storage_policy.go +++ b/pkg/cloudbroker/disks/change_disk_storage_policy.go @@ -18,6 +18,11 @@ type ChangeDiskStoragePolicyRequest struct { // ID of the storage policy to which to connect account // Required: true StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"` + + // Keep current disk I/O tune settings in the domain XML + // Required: false + // Default: false + KeepCurrentIOTune interface{} `url:"keep_current_iot,omitempty" json:"keep_current_iot,omitempty" validate:"omitempty,isBool"` } type wrapperChangeDiskStoragePolicyRequest struct { diff --git a/pkg/cloudbroker/disks/limit_io.go b/pkg/cloudbroker/disks/limit_io.go index d25ed68..af4f6c9 100644 --- a/pkg/cloudbroker/disks/limit_io.go +++ b/pkg/cloudbroker/disks/limit_io.go @@ -67,6 +67,30 @@ type LimitIORequest struct { // Required: false WriteIOPSSecMax uint64 `url:"write_iops_sec_max,omitempty" json:"write_iops_sec_max,omitempty"` + // Duration in seconds of the total bytes burst. Requires TotalBytesSecMax + // Required: false + TotalBytesSecMaxLength uint64 `url:"total_bytes_sec_max_length,omitempty" json:"total_bytes_sec_max_length,omitempty"` + + // Duration in seconds of the read bytes burst. Requires ReadBytesSecMax + // Required: false + ReadBytesSecMaxLength uint64 `url:"read_bytes_sec_max_length,omitempty" json:"read_bytes_sec_max_length,omitempty"` + + // Duration in seconds of the write bytes burst. Requires WriteBytesSecMax + // Required: false + WriteBytesSecMaxLength uint64 `url:"write_bytes_sec_max_length,omitempty" json:"write_bytes_sec_max_length,omitempty"` + + // Duration in seconds of the total IOPS burst. Requires TotalIOPSSecMax + // Required: false + TotalIOPSSecMaxLength uint64 `url:"total_iops_sec_max_length,omitempty" json:"total_iops_sec_max_length,omitempty"` + + // Duration in seconds of the read IOPS burst. Requires ReadIOPSSecMax + // Required: false + ReadIOPSSecMaxLength uint64 `url:"read_iops_sec_max_length,omitempty" json:"read_iops_sec_max_length,omitempty"` + + // Duration in seconds of the write IOPS burst. Requires WriteIOPSSecMax + // Required: false + WriteIOPSSecMaxLength uint64 `url:"write_iops_sec_max_length,omitempty" json:"write_iops_sec_max_length,omitempty"` + // SizeIOPSSec // Required: false SizeIOPSSec uint64 `url:"size_iops_sec,omitempty" json:"size_iops_sec,omitempty"` diff --git a/pkg/cloudbroker/disks/models.go b/pkg/cloudbroker/disks/models.go index d4865ac..cac127c 100644 --- a/pkg/cloudbroker/disks/models.go +++ b/pkg/cloudbroker/disks/models.go @@ -199,6 +199,9 @@ type InfoDisk struct { // Cache mode of disk Cache string `json:"cache"` + + // Whether CRT is tracked + CRTTracking bool `json:"crt_tracking"` } type ItemReplication struct { diff --git a/pkg/cloudbroker/disks/replicate.go b/pkg/cloudbroker/disks/replicate.go index 596ef34..effeeff 100644 --- a/pkg/cloudbroker/disks/replicate.go +++ b/pkg/cloudbroker/disks/replicate.go @@ -30,6 +30,14 @@ type ReplicateRequest struct { // ID of the storage policy under the disk will be created // Required: true StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"` + + // Copy rate for an asynchronous replication pair (in MB/s) + // Required: false + CopyRate uint64 `url:"copy_rate,omitempty" json:"copy_rate,omitempty"` + + // Name of the schedule from the replication profile + // Required: false + Schedule string `url:"schedule,omitempty" json:"schedule,omitempty"` } type wrapperReplicateRequest struct { diff --git a/pkg/cloudbroker/disks/replication_disable_schedule.go b/pkg/cloudbroker/disks/replication_disable_schedule.go new file mode 100644 index 0000000..43c961d --- /dev/null +++ b/pkg/cloudbroker/disks/replication_disable_schedule.go @@ -0,0 +1,38 @@ +package disks + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// ReplicationDisableScheduleRequest to remove the schedule from an asynchronous replication pair +type ReplicationDisableScheduleRequest struct { + // Disk ID + // Required: true + DiskID uint64 `url:"disk_id" json:"disk_id" validate:"required"` +} + +// ReplicationDisableSchedule removes the schedule from an asynchronous replication pair +func (d Disks) ReplicationDisableSchedule(ctx context.Context, req ReplicationDisableScheduleRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + return false, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/disks/replication_disable_schedule" + + res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/pkg/cloudbroker/disks/replication_enable_schedule.go b/pkg/cloudbroker/disks/replication_enable_schedule.go new file mode 100644 index 0000000..8a06451 --- /dev/null +++ b/pkg/cloudbroker/disks/replication_enable_schedule.go @@ -0,0 +1,46 @@ +package disks + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// ReplicationEnableScheduleRequest to apply a replication profile schedule to an asynchronous replication pair +type ReplicationEnableScheduleRequest struct { + // Disk ID + // Required: true + DiskID uint64 `url:"disk_id" json:"disk_id" validate:"required"` + + // ID of the replication profile assigned to the pair + // Required: true + ProfileID uint64 `url:"profile_id" json:"profile_id" validate:"required"` + + // Name of the interval or calendar schedule from the profile + // Required: true + ScheduleName string `url:"schedule_name" json:"schedule_name" validate:"required"` +} + +// ReplicationEnableSchedule applies a replication profile schedule to an asynchronous replication pair +func (d Disks) ReplicationEnableSchedule(ctx context.Context, req ReplicationEnableScheduleRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + return false, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/disks/replication_enable_schedule" + + res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/pkg/cloudbroker/disks/replication_promote.go b/pkg/cloudbroker/disks/replication_promote.go new file mode 100644 index 0000000..f341017 --- /dev/null +++ b/pkg/cloudbroker/disks/replication_promote.go @@ -0,0 +1,78 @@ +package disks + +import ( + "context" + "encoding/json" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// ReplicationPromoteRequest to promote the primary side of an asynchronous replication pair +type ReplicationPromoteRequest struct { + // Disk ID + // Required: true + DiskID uint64 `url:"disk_id" json:"disk_id" validate:"required"` +} + +type wrapperReplicationPromoteRequest struct { + ReplicationPromoteRequest + AsyncMode bool `url:"async_mode" json:"async_mode"` +} + +// ReplicationPromote promotes the primary side of an asynchronous replication pair +func (d Disks) ReplicationPromote(ctx context.Context, req ReplicationPromoteRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + return false, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/disks/replication_promote" + + aReq := wrapperReplicationPromoteRequest{ + ReplicationPromoteRequest: req, + AsyncMode: false, + } + + res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, aReq) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} + +// ReplicationPromoteAsync promotes the primary side of an asynchronous replication pair in async mode +func (d Disks) ReplicationPromoteAsync(ctx context.Context, req ReplicationPromoteRequest) (string, error) { + err := validators.ValidateRequest(req) + if err != nil { + return "", validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/disks/replication_promote" + + aReq := wrapperReplicationPromoteRequest{ + ReplicationPromoteRequest: req, + AsyncMode: true, + } + + res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, aReq) + if err != nil { + return "", err + } + + var resp string + + err = json.Unmarshal(res, &resp) + if err != nil { + return "", err + } + + return resp, nil +} diff --git a/pkg/cloudbroker/disks/replication_reverse.go b/pkg/cloudbroker/disks/replication_reverse.go index 527d14a..6827c66 100644 --- a/pkg/cloudbroker/disks/replication_reverse.go +++ b/pkg/cloudbroker/disks/replication_reverse.go @@ -14,6 +14,11 @@ type ReplicationReverseRequest struct { // Id of the disk // Required: true DiskID uint64 `url:"diskId" json:"diskId" validate:"required"` + + // Use planned failover for asynchronous replication + // Required: false + // Default: true + Planned interface{} `url:"planned,omitempty" json:"planned,omitempty" validate:"omitempty,isBool"` } type wrapperReplicationReverseRequest struct { diff --git a/pkg/cloudbroker/disks/replication_set_copy_rate.go b/pkg/cloudbroker/disks/replication_set_copy_rate.go new file mode 100644 index 0000000..3a02830 --- /dev/null +++ b/pkg/cloudbroker/disks/replication_set_copy_rate.go @@ -0,0 +1,42 @@ +package disks + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// ReplicationSetCopyRateRequest to set the copy rate of an asynchronous replication pair +type ReplicationSetCopyRateRequest struct { + // Disk ID + // Required: true + DiskID uint64 `url:"disk_id" json:"disk_id" validate:"required"` + + // Copy rate in MB/s + // Required: true + CopyRate uint64 `url:"copy_rate" json:"copy_rate" validate:"required"` +} + +// ReplicationSetCopyRate sets the copy rate of an asynchronous replication pair +func (d Disks) ReplicationSetCopyRate(ctx context.Context, req ReplicationSetCopyRateRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + return false, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/disks/replication_set_copy_rate" + + res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/pkg/cloudbroker/disks/replication_start.go b/pkg/cloudbroker/disks/replication_start.go index 0ef7517..2cef3a8 100644 --- a/pkg/cloudbroker/disks/replication_start.go +++ b/pkg/cloudbroker/disks/replication_start.go @@ -18,6 +18,14 @@ type ReplicationStartRequest struct { // ID of target disk. Secondary disk in replication // Required: true TargetDiskID uint64 `url:"targetDiskId" json:"targetDiskId" validate:"required"` + + // Copy rate for an asynchronous replication pair (in MB/s) + // Required: false + CopyRate uint64 `url:"copy_rate,omitempty" json:"copy_rate,omitempty"` + + // Name of the schedule from the replication profile + // Required: false + Schedule string `url:"schedule,omitempty" json:"schedule,omitempty"` } type wrapperReplicationStartRequest struct { diff --git a/pkg/cloudbroker/disks/replication_sync_now.go b/pkg/cloudbroker/disks/replication_sync_now.go new file mode 100644 index 0000000..ea62dfc --- /dev/null +++ b/pkg/cloudbroker/disks/replication_sync_now.go @@ -0,0 +1,38 @@ +package disks + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// ReplicationSyncNowRequest to start manual synchronization of an asynchronous replication pair +type ReplicationSyncNowRequest struct { + // Disk ID + // Required: true + DiskID uint64 `url:"disk_id" json:"disk_id" validate:"required"` +} + +// ReplicationSyncNow starts manual synchronization of an asynchronous replication pair +func (d Disks) ReplicationSyncNow(ctx context.Context, req ReplicationSyncNowRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + return false, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/disks/replication_sync_now" + + res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/pkg/cloudbroker/pcidevice/list.go b/pkg/cloudbroker/pcidevice/list.go index b1d57b6..be922e7 100644 --- a/pkg/cloudbroker/pcidevice/list.go +++ b/pkg/cloudbroker/pcidevice/list.go @@ -34,6 +34,10 @@ type ListRequest struct { // Required: false SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"` + // Sort by node ID + // Required: false + NodeID uint64 `url:"node_id,omitempty" json:"node_id,omitempty"` + // Page number // Required: false Page uint64 `url:"page,omitempty" json:"page,omitempty"` diff --git a/pkg/cloudbroker/sep/add_pool.go b/pkg/cloudbroker/sep/add_pool.go index f7c1dc3..7bef494 100644 --- a/pkg/cloudbroker/sep/add_pool.go +++ b/pkg/cloudbroker/sep/add_pool.go @@ -23,7 +23,7 @@ type AddPoolRequest struct { type wrapperAddPoolRequest struct { AddPoolRequest - AsyncMode bool `url:"asyncMode"` + AsyncMode bool `url:"async_mode"` } // AddPool adds pool to SEP in sync mode. diff --git a/pkg/cloudbroker/user/list.go b/pkg/cloudbroker/user/list.go index 53baa73..e746934 100644 --- a/pkg/cloudbroker/user/list.go +++ b/pkg/cloudbroker/user/list.go @@ -30,6 +30,10 @@ type ListRequest struct { // Required: false SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"` + // API access ID + // Required: false + APIAccessID uint64 `url:"apiaccess_id,omitempty" json:"apiaccess_id,omitempty"` + // Page number. // Required: false Page uint64 `url:"page,omitempty" json:"page,omitempty"` diff --git a/pkg/cloudbroker/vgpu/create.go b/pkg/cloudbroker/vgpu/create.go index b0b8967..32ede1e 100644 --- a/pkg/cloudbroker/vgpu/create.go +++ b/pkg/cloudbroker/vgpu/create.go @@ -2,6 +2,7 @@ package vgpu import ( "context" + "encoding/json" "net/http" "strconv" @@ -14,6 +15,10 @@ type CreateRequest struct { // Required: true PGPUID uint64 `url:"pgpu_id" json:"pgpu_id" validate:"required"` + // Name + // Required: true + Name string `url:"name" json:"name" validate:"required"` + // Virtual profile id // Required: false ProfileID string `url:"profile_id,omitempty" json:"profile_id,omitempty"` @@ -31,6 +36,11 @@ type CreateRequest struct { AccountIDs []uint64 `url:"account_ids,omitempty" json:"account_ids,omitempty"` } +type asyncWrapperCreateRequest struct { + CreateRequest + AsyncMode bool `url:"async_mode"` +} + // Create creates VGPU func (v VGPU) Create(ctx context.Context, req CreateRequest) (uint64, error) { err := validators.ValidateRequest(req) @@ -40,7 +50,12 @@ func (v VGPU) Create(ctx context.Context, req CreateRequest) (uint64, error) { url := "/cloudbroker/vgpu/create" - res, err := v.client.DecortApiCall(ctx, http.MethodPost, url, req) + aReq := asyncWrapperCreateRequest{ + CreateRequest: req, + AsyncMode: false, + } + + res, err := v.client.DecortApiCall(ctx, http.MethodPost, url, aReq) if err != nil { return 0, err } @@ -52,3 +67,33 @@ func (v VGPU) Create(ctx context.Context, req CreateRequest) (uint64, error) { return result, nil } + +// CreateAsync creates VGPU in async mode +func (v VGPU) CreateAsync(ctx context.Context, req CreateRequest) (string, error) { + err := validators.ValidateRequest(req) + if err != nil { + return "", validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/vgpu/create" + + aReq := asyncWrapperCreateRequest{ + CreateRequest: req, + AsyncMode: true, + } + + res, err := v.client.DecortApiCall(ctx, http.MethodPost, url, aReq) + if err != nil { + return "", err + } + + var resp string + + err = json.Unmarshal(res, &resp) + if err != nil { + return "", err + } + + return resp, nil + +} diff --git a/pkg/cloudbroker/vgpu/destroy.go b/pkg/cloudbroker/vgpu/destroy.go index 8564538..a808319 100644 --- a/pkg/cloudbroker/vgpu/destroy.go +++ b/pkg/cloudbroker/vgpu/destroy.go @@ -2,6 +2,7 @@ package vgpu import ( "context" + "encoding/json" "net/http" "strconv" @@ -15,6 +16,11 @@ type DestroyRequest struct { VGPUID uint64 `url:"vgpu_id" json:"vgpu_id" validate:"required"` } +type asyncWrapperDestroyRequest struct { + DestroyRequest + AsyncMode bool `url:"async_mode"` +} + // Destroy destroys VGPU func (v VGPU) Destroy(ctx context.Context, req DestroyRequest) (bool, error) { err := validators.ValidateRequest(req) @@ -24,7 +30,12 @@ func (v VGPU) Destroy(ctx context.Context, req DestroyRequest) (bool, error) { url := "/cloudbroker/vgpu/destroy" - res, err := v.client.DecortApiCall(ctx, http.MethodPost, url, req) + aReq := asyncWrapperDestroyRequest{ + DestroyRequest: req, + AsyncMode: false, + } + + res, err := v.client.DecortApiCall(ctx, http.MethodPost, url, aReq) if err != nil { return false, err } @@ -36,3 +47,32 @@ func (v VGPU) Destroy(ctx context.Context, req DestroyRequest) (bool, error) { return result, nil } + +// Destroy destroys VGPU in async mode +func (v VGPU) DestroyAsync(ctx context.Context, req DestroyRequest) (string, error) { + err := validators.ValidateRequest(req) + if err != nil { + return "", validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/vgpu/destroy" + + aReq := asyncWrapperDestroyRequest{ + DestroyRequest: req, + AsyncMode: true, + } + + res, err := v.client.DecortApiCall(ctx, http.MethodPost, url, aReq) + if err != nil { + return "", err + } + + var resp string + + err = json.Unmarshal(res, &resp) + if err != nil { + return "", err + } + + return resp, nil +} diff --git a/pkg/cloudbroker/vgpu/edit.go b/pkg/cloudbroker/vgpu/edit.go new file mode 100644 index 0000000..51836ca --- /dev/null +++ b/pkg/cloudbroker/vgpu/edit.go @@ -0,0 +1,82 @@ +package vgpu + +import ( + "context" + "encoding/json" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// EditRequest to edit the name +type EditRequest struct { + // VGPU ID + // Required: true + VGPUID uint64 `url:"vgpu_id" json:"vgpu_id" validate:"required"` + + // New name + // Required: false + Name string `url:"name,omitempty" json:"name,omitempty"` +} + +type asyncWrapperEditRequest struct { + EditRequest + AsyncMode bool `url:"async_mode"` +} + +// Edit edits the name +func (v VGPU) Edit(ctx context.Context, req EditRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + return false, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/vgpu/edit" + + aReq := asyncWrapperEditRequest{ + EditRequest: req, + AsyncMode: false, + } + + res, err := v.client.DecortApiCall(ctx, http.MethodPost, url, aReq) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} + +// Edit Async edits the name in async mode +func (v VGPU) EditAsync(ctx context.Context, req EditRequest) (string, error) { + err := validators.ValidateRequest(req) + if err != nil { + return "", validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/cloudbroker/vgpu/edit" + + aReq := asyncWrapperEditRequest{ + EditRequest: req, + AsyncMode: true, + } + + res, err := v.client.DecortApiCall(ctx, http.MethodPost, url, aReq) + if err != nil { + return "", err + } + + var resp string + + err = json.Unmarshal(res, &resp) + if err != nil { + return "", err + } + + return resp, nil +} diff --git a/pkg/cloudbroker/vgpu/list.go b/pkg/cloudbroker/vgpu/list.go index fbccd47..69632c8 100644 --- a/pkg/cloudbroker/vgpu/list.go +++ b/pkg/cloudbroker/vgpu/list.go @@ -42,6 +42,10 @@ type ListRequest struct { // Required: false SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty" validate:"omitempty,sortBy"` + // Sort by name + // Required: false + Name string `url:"name,omitempty" json:"name,omitempty"` + // Page number // Required: false Page uint64 `url:"page,omitempty" json:"page,omitempty"` diff --git a/pkg/cloudbroker/vgpu/models.go b/pkg/cloudbroker/vgpu/models.go index 17baa11..f56bb4a 100644 --- a/pkg/cloudbroker/vgpu/models.go +++ b/pkg/cloudbroker/vgpu/models.go @@ -60,6 +60,12 @@ type ItemVGPU struct { // Status Status string `json:"status"` + + // Name + Name string `json:"name"` + + // Node ID + NodeID uint64 `json:"node_id"` } // List of VGPU diff --git a/pkg/cloudbroker/vins/create_in_account.go b/pkg/cloudbroker/vins/create_in_account.go index 6bf4a46..333988d 100644 --- a/pkg/cloudbroker/vins/create_in_account.go +++ b/pkg/cloudbroker/vins/create_in_account.go @@ -72,7 +72,7 @@ type CreateInAccountRequest struct { type asyncWrapperCreateInAccountRequest struct { CreateInAccountRequest - AsyncMode bool `url:"asyncMode" json:"asyncMode"` + AsyncMode bool `url:"async_mode" json:"async_mode"` } // CreateInAccount creates VINS in account level diff --git a/pkg/cloudbroker/vins/create_in_rg.go b/pkg/cloudbroker/vins/create_in_rg.go index 5ecb6ea..b985ff0 100644 --- a/pkg/cloudbroker/vins/create_in_rg.go +++ b/pkg/cloudbroker/vins/create_in_rg.go @@ -66,7 +66,7 @@ type CreateInRGRequest struct { type asyncWrapperCreateInRgRequest struct { CreateInRGRequest - AsyncMode bool `url:"asyncMode" json:"asyncMode"` + AsyncMode bool `url:"async_mode" json:"async_mode"` } // CreateInRG creates VINS in resource group level diff --git a/pkg/cloudbroker/vins/enable.go b/pkg/cloudbroker/vins/enable.go index 02e3760..5658eb5 100644 --- a/pkg/cloudbroker/vins/enable.go +++ b/pkg/cloudbroker/vins/enable.go @@ -18,7 +18,7 @@ type EnableRequest struct { type asyncWrapperEnableRequest struct { EnableRequest - AsyncMode bool `url:"asyncMode"` + AsyncMode bool `url:"async_mode"` } // Enable enables VINS by ID diff --git a/pkg/cloudbroker/vins/vnfdev_redeploy.go b/pkg/cloudbroker/vins/vnfdev_redeploy.go index 7b3f556..9d78817 100644 --- a/pkg/cloudbroker/vins/vnfdev_redeploy.go +++ b/pkg/cloudbroker/vins/vnfdev_redeploy.go @@ -18,7 +18,7 @@ type VNFDevRedeployRequest struct { type asyncWrapperVNFDevRedeployRequest struct { VNFDevRedeployRequest - AsyncMode bool `url:"asyncMode"` + AsyncMode bool `url:"async_mode"` } // VNFDevRedeploy redeploys VINS VNFDevs diff --git a/pkg/cloudbroker/vins/vnfdev_restart.go b/pkg/cloudbroker/vins/vnfdev_restart.go index 9099eb1..f9c9f3c 100644 --- a/pkg/cloudbroker/vins/vnfdev_restart.go +++ b/pkg/cloudbroker/vins/vnfdev_restart.go @@ -18,7 +18,7 @@ type VNFDevRestartRequest struct { type asyncWrapperVNFDevRestartRequest struct { VNFDevRestartRequest - AsyncMode bool `url:"asyncMode"` + AsyncMode bool `url:"async_mode"` } // VNFDevRestart reboots VINSes primary VNF device diff --git a/pkg/cloudbroker/vins/vnfdev_start.go b/pkg/cloudbroker/vins/vnfdev_start.go index 38b2620..35bd562 100644 --- a/pkg/cloudbroker/vins/vnfdev_start.go +++ b/pkg/cloudbroker/vins/vnfdev_start.go @@ -18,7 +18,7 @@ type VNFDevStartRequest struct { type asyncWrapperVNFDevStartRequest struct { VNFDevStartRequest - AsyncMode bool `url:"asyncMode"` + AsyncMode bool `url:"async_mode"` } // VNFDevStart starts VINSes primary VNF device diff --git a/pkg/sdn/defsecpolicies/filter_test.go b/pkg/sdn/defsecpolicies/filter_test.go index df89ba7..de2d41b 100644 --- a/pkg/sdn/defsecpolicies/filter_test.go +++ b/pkg/sdn/defsecpolicies/filter_test.go @@ -9,7 +9,7 @@ var testSecurityPolicies = SecurityPoliciesList{ { ID: "policy1", DisplayName: "DevelopersPolicy", - Description: "First policy", + AccessGroupName: "DevelopersGroup", CreatedAt: "2023-01-01T00:00:00Z", UpdatedAt: "2023-01-01T01:00:00Z", AccessGroupID: "group1", @@ -17,26 +17,14 @@ var testSecurityPolicies = SecurityPoliciesList{ DefaultOpenSessionDrop: true, SecurityRules: []SecurityRule{ { - ID: "rule1", - DisplayName: "DevRule1", - Action: "ALLOW", - Direction: "INGRESS", - Enabled: true, - Priority: 100, - SecurityPolicyID: "policy1", - VersionID: 1, - }, - }, - Status: Status{ - Common: "ACTIVE", - Hypervisors: []HypervisorStatus{ - { - Name: "hv1", - DisplayName: "Hypervisor1", - Status: "SYNCED", - HypervisorStatus: "HEALTHY", - SyncedAt: "2023-01-01T01:00:00Z", - }, + ID: "rule1", + DisplayName: "DevRule1", + Action: "ALLOW", + Direction: "INGRESS", + Enabled: true, + Priority: 100, + Type: "System", + VersionID: 1, }, }, VersionID: 1, @@ -44,7 +32,7 @@ var testSecurityPolicies = SecurityPoliciesList{ { ID: "policy2", DisplayName: "AdminsPolicy", - Description: "Second policy", + AccessGroupName: "AdminsGroup", CreatedAt: "2023-01-02T00:00:00Z", UpdatedAt: "2023-01-02T01:00:00Z", AccessGroupID: "group2", @@ -52,26 +40,14 @@ var testSecurityPolicies = SecurityPoliciesList{ DefaultOpenSessionDrop: false, SecurityRules: []SecurityRule{ { - ID: "rule2", - DisplayName: "AdminRule1", - Action: "DENY", - Direction: "EGRESS", - Enabled: true, - Priority: 50, - SecurityPolicyID: "policy2", - VersionID: 1, - }, - }, - Status: Status{ - Common: "ACTIVE", - Hypervisors: []HypervisorStatus{ - { - Name: "hv2", - DisplayName: "Hypervisor2", - Status: "SYNCED", - HypervisorStatus: "HEALTHY", - SyncedAt: "2023-01-02T01:00:00Z", - }, + ID: "rule2", + DisplayName: "AdminRule1", + Action: "DENY", + Direction: "EGRESS", + Enabled: true, + Priority: 50, + Type: "System", + VersionID: 1, }, }, VersionID: 2, @@ -79,7 +55,7 @@ var testSecurityPolicies = SecurityPoliciesList{ { ID: "policy3", DisplayName: "UsersPolicy", - Description: "Third policy", + AccessGroupName: "UsersGroup", CreatedAt: "2023-01-03T00:00:00Z", UpdatedAt: "2023-01-03T01:00:00Z", AccessGroupID: "group3", @@ -87,26 +63,14 @@ var testSecurityPolicies = SecurityPoliciesList{ DefaultOpenSessionDrop: true, SecurityRules: []SecurityRule{ { - ID: "rule3", - DisplayName: "UserRule1", - Action: "ALLOW", - Direction: "INGRESS", - Enabled: false, - Priority: 200, - SecurityPolicyID: "policy3", - VersionID: 1, - }, - }, - Status: Status{ - Common: "PENDING", - Hypervisors: []HypervisorStatus{ - { - Name: "hv3", - DisplayName: "Hypervisor3", - Status: "SYNCING", - HypervisorStatus: "HEALTHY", - SyncedAt: "2023-01-03T01:00:00Z", - }, + ID: "rule3", + DisplayName: "UserRule1", + Action: "ALLOW", + Direction: "INGRESS", + Enabled: false, + Priority: 200, + Type: "User", + VersionID: 1, }, }, VersionID: 3, @@ -132,11 +96,11 @@ func TestFilterByDisplayName(t *testing.T) { func TestFilterFunc(t *testing.T) { actual := testSecurityPolicies.FilterFunc(func(sp SecurityPolicy) bool { - return sp.Description == "Second policy" + return sp.AccessGroupName == "AdminsGroup" }) if len(actual.Policies) != 1 || actual.Policies[0].ID != "policy2" { - t.Fatal("Expected 1 policy with description 'Second policy', found:", len(actual.Policies)) + t.Fatal("Expected 1 policy with access group name 'AdminsGroup', found:", len(actual.Policies)) } } @@ -192,13 +156,18 @@ func TestFilterByDefaultOpenSessionDrop(t *testing.T) { } } -func TestFilterByStatus(t *testing.T) { +func TestFilterByRuleType(t *testing.T) { actual := testSecurityPolicies.FilterFunc(func(sp SecurityPolicy) bool { - return sp.Status.Common == "ACTIVE" + for _, rule := range sp.SecurityRules { + if rule.Type == "System" { + return true + } + } + return false }) if len(actual.Policies) != 2 { - t.Fatal("Expected 2 policies with ACTIVE status, found:", len(actual.Policies)) + t.Fatal("Expected 2 policies with System rules, found:", len(actual.Policies)) } } diff --git a/pkg/sdn/defsecpolicies/models.go b/pkg/sdn/defsecpolicies/models.go index c356562..e3f4502 100644 --- a/pkg/sdn/defsecpolicies/models.go +++ b/pkg/sdn/defsecpolicies/models.go @@ -9,6 +9,9 @@ type SecurityPolicy struct { // Access group ID AccessGroupID string `json:"access_group_id"` + // Access group name + AccessGroupName string `json:"access_group_name"` + // Created time CreatedAt string `json:"created_at"` @@ -18,9 +21,6 @@ type SecurityPolicy struct { // Default open session drop flag DefaultOpenSessionDrop bool `json:"default_open_session_drop"` - // Description - Description string `json:"description"` - // Display name DisplayName string `json:"display_name"` @@ -30,12 +30,6 @@ type SecurityPolicy struct { // Security rules SecurityRules []SecurityRule `json:"security_rules"` - // Locked time - LockedAt string `json:"locked_at"` - - // Status information - Status Status `json:"status"` - // Version ID VersionID uint64 `json:"version_id"` @@ -51,11 +45,11 @@ type SecurityRule struct { // Action Action string `json:"action"` - // Description - Description string `json:"description"` + // Applied network object groups + AppliedNetObjectGroups []AppliedNetObjectGroup `json:"applied_net_object_groups"` - // Destination network object - DestinationNetObject NetObject `json:"destination_net_object"` + // Destination network object groups + DestinationNetObjectGroups []NetObjectGroup `json:"destination_net_object_groups"` // Direction Direction string `json:"direction"` @@ -66,8 +60,8 @@ type SecurityRule struct { // Enabled flag Enabled bool `json:"enabled"` - // Filter configuration - Filter Filter `json:"filter"` + // Filters configuration + Filter []FilterParams `json:"filters"` // ID ID string `json:"id"` @@ -75,47 +69,152 @@ type SecurityRule struct { // Log enabled flag LogEnabled bool `json:"log_enabled"` - // Log name - LogName string `json:"log_name"` + // Logging profile + LoggingProfile LoggingProfile `json:"logging_profile"` - // Log severity - LogSeverity string `json:"log_severity"` + // Logging profile ID + LoggingProfileID string `json:"logging_profile_id"` // Priority Priority int `json:"priority"` - // Security policy ID - SecurityPolicyID string `json:"security_policy_id"` + // Security rule condition groups + SecurityRuleConditionGroups []SecurityRuleConditionGroup `json:"security_rule_condition_groups"` - // Source network object - SourceNetObject NetObject `json:"source_net_object"` + // Security rule conditions + SecurityRuleConditions []SecurityRuleCondition `json:"security_rule_conditions"` + + // Source network object groups + SourceNetObjectGroups []NetObjectGroup `json:"source_net_object_groups"` // Statistics enabled flag StatisticsEnabled bool `json:"statistics_enabled"` + // Type + Type string `json:"type"` + // Version ID VersionID uint64 `json:"version_id"` } -// Network object information -type NetObject struct { - // Display name - DisplayName string `json:"display_name"` - - // Network address pool ID - NetAddressPoolID string `json:"net_address_pool_id"` - - // Network object group ID - NetObjectGroupID string `json:"net_object_group_id"` -} - -// Filter configuration -type Filter struct { - // Filter parameters - Filters FilterParams `json:"filters"` +// Applied network object group information +type AppliedNetObjectGroup struct { + // ID + ID string `json:"id"` // Name Name string `json:"name"` + + // Version ID + VersionID uint64 `json:"version_id"` +} + +// Network object group information +type NetObjectGroup struct { + // ID + ID string `json:"id"` + + // Is positive flag + IsPositive bool `json:"is_positive"` + + // Name + Name string `json:"name"` + + // Version ID + VersionID uint64 `json:"version_id"` +} + +// Logging profile information +type LoggingProfile struct { + // Access group ID + AccessGroupID string `json:"access_group_id"` + + // Access group name + AccessGroupName string `json:"access_group_name"` + + // Created time + CreatedAt string `json:"created_at"` + + // Direction + Direction string `json:"direction"` + + // ID + ID string `json:"id"` + + // Name + Name string `json:"name"` + + // Security rules count + SecurityRulesCount uint64 `json:"security_rules_count"` + + // Session established sample rate + SessionEstablishedSampleRate float64 `json:"session_established_sample_rate"` + + // Session new sample rate + SessionNewSampleRate float64 `json:"session_new_sample_rate"` + + // Updated time + UpdatedAt string `json:"updated_at"` + + // Version ID + VersionID uint64 `json:"version_id"` +} + +// Security rule condition group information +type SecurityRuleConditionGroup struct { + // Access group ID + AccessGroupID string `json:"access_group_id"` + + // Access group name + AccessGroupName string `json:"access_group_name"` + + // Created time + CreatedAt string `json:"created_at"` + + // ID + ID string `json:"id"` + + // Name + Name string `json:"name"` + + // Security rule conditions + SecurityRuleConditions []SecurityRuleCondition `json:"security_rule_conditions"` + + // Security rules count + SecurityRulesCount uint64 `json:"security_rules_count"` + + // Updated time + UpdatedAt string `json:"updated_at"` +} + +// Security rule condition information +type SecurityRuleCondition struct { + // Access group ID + AccessGroupID string `json:"access_group_id"` + + // Created time + CreatedAt string `json:"created_at"` + + // Filters configuration + Filters []FilterParams `json:"filters"` + + // ID + ID string `json:"id"` + + // Name + Name string `json:"name"` + + // Read only flag + ReadOnly bool `json:"read_only"` + + // Security rule condition groups + SecurityRuleConditionGroups []interface{} `json:"security_rule_condition_groups"` + + // Security rules + SecurityRules []interface{} `json:"security_rules"` + + // Updated time + UpdatedAt string `json:"updated_at"` } // Filter parameters @@ -126,8 +225,8 @@ type FilterParams struct { // ARP protocol flag ARP bool `json:"arp"` - // DHCP protocol flag - DHCP bool `json:"dhcp"` + // Ethernet type + EthType string `json:"eth_type"` // Filter expression Expression string `json:"expression"` @@ -138,6 +237,9 @@ type FilterParams struct { // IP protocol flag IP bool `json:"ip"` + // IP protocol number + IPProto uint64 `json:"ip_proto"` + // IPv4 protocol flag IPv4 bool `json:"ip_v4"` @@ -156,36 +258,15 @@ type FilterParams struct { // TCP destination ports TCPDstPorts []string `json:"tcp_dst_ports"` + // TCP source ports + TCPSrcPorts []string `json:"tcp_src_ports"` + // UDP protocol flag UDP bool `json:"udp"` // UDP destination ports UDPDstPorts []string `json:"udp_dst_ports"` -} - -// Status information -type Status struct { - // Common status - Common string `json:"common"` - - // Hypervisor statuses - Hypervisors []HypervisorStatus `json:"hypervisors"` -} - -// Hypervisor status information -type HypervisorStatus struct { - // Status - Status string `json:"status"` - - // Name - Name string `json:"name"` - - // Display name - DisplayName string `json:"display_name"` - - // Hypervisor status - HypervisorStatus string `json:"hypervisor_status"` - - // Last sync time - SyncedAt string `json:"synced_at"` + + // UDP source ports + UDPSrcPorts []string `json:"udp_src_ports"` } diff --git a/pkg/sdn/extnet/create.go b/pkg/sdn/extnet/create.go index 1813a65..c58861f 100644 --- a/pkg/sdn/extnet/create.go +++ b/pkg/sdn/extnet/create.go @@ -54,7 +54,7 @@ type CreateRequest struct { // VLAN tag identifier // Required: false - VLANTag string `url:"vlan_tag,omitempty" json:"vlan_tag,omitempty" validate:"omitempty,trunkTags"` + VLANTag uint64 `url:"vlan_tag,omitempty" json:"vlan_tag,omitempty" validate:"omitempty,min=1,max=4094"` } type ExternalNetworkPortRequest struct { @@ -63,8 +63,8 @@ type ExternalNetworkPortRequest struct { AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"` // Access group name - // Required: false - AccessGroupName string `url:"access_group_name,omitempty" json:"access_group_name,omitempty"` + // Required: true + AccessGroupName string `url:"access_group_name" json:"access_group_name" validate:"required"` // Comment for the external network port // Required: true @@ -79,28 +79,28 @@ type ExternalNetworkPortRequest struct { Enabled bool `url:"enabled" json:"enabled"` // IPv4 - // Required: false - IPv4 string `url:"ipv4,omitempty" json:"ipv4,omitempty"` + // Required: true + IPv4 string `url:"ipv4" json:"ipv4" validate:"required"` // IPv6 - // Required: false - IPv6 string `url:"ipv6,omitempty" json:"ipv6,omitempty"` + // Required: true + IPv6 string `url:"ipv6" json:"ipv6" validate:"required"` // IPv6 Config - // Required: false - IPv6Config *IPv6ConfigRequest `url:"-" json:"ipv6_config,omitempty"` + // Required: true + IPv6Config *IPv6ConfigRequest `url:"-" json:"ipv6_config" validate:"required"` // MAC address // Required: true MAC string `url:"mac" json:"mac" validate:"required"` // Router gateway port - // Required: false - RouterGatewayPort *RouterGatewayPortRequest `url:"-" json:"router_gateway_port,omitempty"` + // Required: true + RouterGatewayPort *RouterGatewayPortRequest `url:"-" json:"router_gateway_port" validate:"required"` // Floating IP - // Required: false - FloatingIP *FloatingIPRequest `url:"-" json:"floating_ip,omitempty"` + // Required: true + FloatingIP *FloatingIPRequest `url:"-" json:"floating_ip" validate:"required"` } type IPv6ConfigRequest struct { @@ -167,15 +167,15 @@ type FloatingIPRequest struct { // External network port // Required: true - ExternalNetworkPort string `url:"external_network_port" json:"external_network_port" validate:"required"` + ExternalNetworkPort *ExternalNetworkPortRequest `url:"-" json:"external_network_port" validate:"required"` // ID of the Floating IP // Required: true ID string `url:"id" json:"id" validate:"required"` // Logical port - // Required: false - LogicalPort *LogicalPortRequest `url:"-" json:"logical_port,omitempty"` + // Required: true + LogicalPort *LogicalPortRequest `url:"-" json:"logical_port" validate:"required"` // Router // Required: true @@ -185,6 +185,14 @@ type FloatingIPRequest struct { // Required: true UpdatedAt time.Time `url:"updated_at" json:"updated_at" validate:"required"` + // ID of the user who created the floating IP + // Required: false + CreatedBy string `url:"created_by,omitempty" json:"created_by,omitempty"` + + // ID of the user who last updated the floating IP + // Required: false + UpdatedBy string `url:"updated_by,omitempty" json:"updated_by,omitempty"` + // ID of version // Required: true VersionID uint64 `url:"version_id" json:"version_id" validate:"required"` @@ -209,7 +217,7 @@ type LogicalPortRequest struct { // Address detection // Required: true - AddressDetection bool `url:"address_detection" json:"address_detection" validate:"required"` + AddressDetection bool `url:"address_detection" json:"address_detection"` // Description // Required: true @@ -219,14 +227,18 @@ type LogicalPortRequest struct { // Required: false CreatedAt time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` - // User-friendly name for router + // User-friendly name for logical port // Required: true - RouterDisplayName string `url:"router_display_name" json:"router_display_name" validate:"required"` + DisplayName string `url:"display_name" json:"display_name" validate:"required"` // Whether the logical pork is enabled // Required: true Enabled bool `url:"enabled" json:"enabled"` + // Exclude firewall information + // Required: true + ExcludeFirewall *ExcludeFirewallRequest `url:"-" json:"exclude_firewall" validate:"required"` + // External Network ID // Required: false ExternalNetworkID string `url:"external_network_id,omitempty" json:"external_network_id,omitempty"` @@ -236,38 +248,66 @@ type LogicalPortRequest struct { Hypervisor string `url:"hypervisor" json:"hypervisor" validate:"required"` // User-friendly name for hypervisor + // Required: true + HypervisorDisplayName string `url:"hypervisor_display_name" json:"hypervisor_display_name" validate:"required"` + + // Labels // Required: false - HypervisorDisplayName string `url:"hypervisor_display_name,omitempty" json:"hypervisor_display_name,omitempty"` + Labels *LabelsRequest `url:"-" json:"labels,omitempty"` // Live Migration Target Hv - // Required: true - LiveMigrationTargetHV string `url:"live_migration_target_hv" json:"live_migration_target_hv" validate:"required"` + // Required: false + LiveMigrationTargetHV string `url:"live_migration_target_hv,omitempty" json:"live_migration_target_hv,omitempty"` // Status - // Required: true - Status *StatusRequest `url:"-" json:"status" validate:"required"` + // Required: false + Status *StatusRequest `url:"-" json:"status,omitempty"` // Port bindings - // Required: true - Bindings *PortBindingsRequest `url:"-" json:"bindings" validate:"required"` + // Required: false + Bindings *PortBindingsRequest `url:"-" json:"bindings,omitempty"` // Unique Identifier // Required: true UniqueIDentifier string `url:"unique_identifier" json:"unique_identifier" validate:"required"` // Updated at - // Required: true - UpdatedAt time.Time `url:"updated_at" json:"updated_at" validate:"required"` + // Required: false + UpdatedAt time.Time `url:"updated_at,omitempty" json:"updated_at,omitempty"` // ID of version // Required: true VersionID uint64 `url:"version_id" json:"version_id" validate:"required"` } -type StatusRequest struct { - // Common +type ExcludeFirewallRequest struct { + // Exclusion reason + // Required: false + ExclusionReason string `url:"exclusion_reason,omitempty" json:"exclusion_reason,omitempty"` + + // Whether logical port addresses are excluded from firewall + // Required: false + LogicalPortAddressesExcluded bool `url:"logical_port_addresses_excluded,omitempty" json:"logical_port_addresses_excluded,omitempty"` + + // Whether logical port is excluded from firewall // Required: true - Common string `url:"common" json:"common" validate:"required"` + LogicalPortExcluded bool `url:"logical_port_excluded" json:"logical_port_excluded"` +} + +type LabelsRequest struct { + // VM ID + // Required: true + VMID string `url:"vm_id" json:"vm_id" validate:"required"` + + // VM name + // Required: false + VMName string `url:"vm_name,omitempty" json:"vm_name,omitempty"` +} + +type StatusRequest struct { + // Operation status + // Required: true + OperationStatus string `url:"operation_status" json:"operation_status" validate:"required"` // Hypervisors status // Required: false @@ -280,24 +320,20 @@ type PortBindingsRequest struct { ID string `url:"id" json:"id" validate:"required"` // User-friendly name for segment - // Required: true - SegmentDisplayName string `url:"segment_display_name" json:"segment_display_name" validate:"required"` + // Required: false + SegmentDisplayName string `url:"segment_display_name,omitempty" json:"segment_display_name,omitempty"` // Segment ID - // Required: true - SegmentID string `url:"segment_id" json:"segment_id" validate:"required"` + // Required: false + SegmentID string `url:"segment_id,omitempty" json:"segment_id,omitempty"` // Port security // Required: true - PortSecurity bool `url:"port_security" json:"port_security" validate:"required"` + PortSecurity bool `url:"port_security" json:"port_security"` // Address detection // Required: true - AddressDetection bool `url:"address_detection" json:"address_detection" validate:"required"` - - // Is Exclude From Firewall - // Required: true - IsExcludedFromFirewall bool `url:"is_excluded_from_firewall" json:"is_excluded_from_firewall" validate:"required"` + AddressDetection bool `url:"address_detection" json:"address_detection"` // ID of version // Required: true @@ -312,14 +348,14 @@ type PortBindingsRequest struct { UpdatedAt time.Time `url:"updated_at" json:"updated_at" validate:"required"` // Logical port addresses - // Required: true - LogicalPortAddresses []LogicalPortAddressRequest `url:"-" json:"logical_port_addresses" validate:"required"` + // Required: false + LogicalPortAddresses []LogicalPortAddressRequest `url:"-" json:"logical_port_addresses,omitempty"` } type HypervisorStatusRequest struct { - // Status + // Operation status // Required: true - Status string `url:"status" json:"status" validate:"required"` + OperationStatus string `url:"operation_status" json:"operation_status" validate:"required"` // Name of hypervisor // Required: true @@ -351,13 +387,13 @@ type LogicalPortAddressRequest struct { // Required: false IsDiscovered bool `url:"is_discovered,omitempty" json:"is_discovered,omitempty"` - // Is discovered - // Required: true - IsPrimary bool `url:"is_primary" json:"is_primary" validate:"required"` + // Is primary + // Required: false + IsPrimary bool `url:"is_primary,omitempty" json:"is_primary,omitempty"` // MAC - // Required: false - MAC string `url:"mac,omitempty" json:"mac,omitempty"` + // Required: true + MAC string `url:"mac" json:"mac" validate:"required"` // ID // Required: true @@ -368,62 +404,62 @@ type LogicalPortAddressRequest struct { LogicalPortID string `url:"logical_port_id" json:"logical_port_id" validate:"required"` // Assigned at - // Required: false - AssignedAt time.Time `url:"assigned_at,omitempty" json:"assigned_at,omitempty"` + // Required: true + AssignedAt time.Time `url:"assigned_at" json:"assigned_at" validate:"required"` } type RouterRequest struct { // Access group ID - // Required: false - AccessGroupID string `url:"access_group_id,omitempty" json:"access_group_id,omitempty"` + // Required: true + AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"` // Access group name - // Required: false - AccessGroupName string `url:"access_group_name,omitempty" json:"access_group_name,omitempty"` + // Required: true + AccessGroupName string `url:"access_group_name" json:"access_group_name" validate:"required"` // Created at - // Required: false - CreatedAt time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` + // Required: true + CreatedAt time.Time `url:"created_at" json:"created_at" validate:"required"` // Detailed description of the router - // Required: false - Description string `url:"description,omitempty" json:"description,omitempty"` + // Required: true + Description string `url:"description" json:"description" validate:"required"` // User-friendly name for the router // Required: true DisplayName string `url:"display_name" json:"display_name" validate:"required"` // Whether the router is enabled - // Required: false - Enabled bool `url:"enabled,omitempty" json:"enabled,omitempty"` + // Required: true + Enabled bool `url:"enabled" json:"enabled"` // Gateway ports - // Required: false - GatewayPorts []GatewayPortRequest `url:"-" json:"gateway_ports,omitempty"` + // Required: true + GatewayPorts []GatewayPortRequest `url:"-" json:"gateway_ports" validate:"required"` // ID // Required: true ID string `url:"id" json:"id" validate:"required"` // Policies - // Required: false - Policies []RouterPolicyRequest `url:"-" json:"policies,omitempty"` + // Required: true + Policies []RouterPolicyRequest `url:"-" json:"policies" validate:"required"` // Ports - // Required: false - Ports []RouterPortRequest `url:"-" json:"ports,omitempty"` + // Required: true + Ports []RouterPortRequest `url:"-" json:"ports" validate:"required"` // Status - // Required: false - Status *StatusRequest `url:"-" json:"status,omitempty"` + // Required: true + Status *StatusRequest `url:"-" json:"status" validate:"required"` // Updated at - // Required: false - UpdatedAt time.Time `url:"updated_at,omitempty" json:"updated_at,omitempty"` + // Required: true + UpdatedAt time.Time `url:"updated_at" json:"updated_at" validate:"required"` // ID of version - // Required: false - VersionID uint64 `url:"version_id,omitempty" json:"version_id,omitempty"` + // Required: true + VersionID uint64 `url:"version_id" json:"version_id" validate:"required"` } type GatewayPortRequest struct { @@ -436,28 +472,28 @@ type GatewayPortRequest struct { Description string `url:"description" json:"description" validate:"required"` // L4 port max - // Required: false - ExternalL4PortMax int64 `url:"external_l4_port_max,omitempty" json:"external_l4_port_max,omitempty"` + // Required: true + ExternalL4PortMax int64 `url:"external_l4_port_max" json:"external_l4_port_max" validate:"required"` // L4 port min - // Required: false - ExternalL4PortMin int64 `url:"external_l4_port_min,omitempty" json:"external_l4_port_min,omitempty"` + // Required: true + ExternalL4PortMin int64 `url:"external_l4_port_min" json:"external_l4_port_min" validate:"required"` // External network port // Required: true - ExternalNetworkPort interface{} `url:"external_network_port" json:"external_network_port" validate:"required"` + ExternalNetworkPort *ExternalNetworkPortRequest `url:"-" json:"external_network_port" validate:"required"` // ID of port - // Required: false - ID string `url:"id,omitempty" json:"id,omitempty"` + // Required: true + ID string `url:"id" json:"id" validate:"required"` // SNAT Enabled // Required: true SNATEnabled bool `url:"snat_enabled" json:"snat_enabled"` // Status - // Required: false - Status *StatusRequest `url:"-" json:"status,omitempty"` + // Required: true + Status *StatusRequest `url:"-" json:"status" validate:"required"` // Updated at // Required: true @@ -482,12 +518,12 @@ type RouterPolicyRequest struct { DisplayName string `url:"display_name" json:"display_name" validate:"required"` // Whether the policy is enabled - // Required: false - Enabled bool `url:"enabled,omitempty" json:"enabled,omitempty"` + // Required: true + Enabled bool `url:"enabled" json:"enabled"` // ID of port - // Required: false - ID string `url:"id,omitempty" json:"id,omitempty"` + // Required: true + ID string `url:"id" json:"id" validate:"required"` // Match // Required: true @@ -528,16 +564,16 @@ type RouterPortRequest struct { Enabled bool `url:"enabled" json:"enabled"` // ID of port - // Required: false - ID string `url:"id,omitempty" json:"id,omitempty"` - - // Next IPv4 address // Required: true - NextIPv4Address []string `url:"next_ipv4_address" json:"next_ipv4_address" validate:"required"` + ID string `url:"id" json:"id" validate:"required"` - // Next IPv6 address + // IPv4 address // Required: true - NextIPv6Address []string `url:"next_ipv6_address" json:"next_ipv6_address" validate:"required"` + IPv4Address string `url:"ipv4_address" json:"ipv4_address" validate:"required"` + + // IPv6 address + // Required: true + IPv6Address string `url:"ipv6_address" json:"ipv6_address" validate:"required"` // IPv6 Config // Required: true @@ -556,8 +592,8 @@ type RouterPortRequest struct { SegmentID string `url:"segment_id" json:"segment_id" validate:"required"` // Status - // Required: false - Status *StatusRequest `url:"-" json:"status,omitempty"` + // Required: true + Status *StatusRequest `url:"-" json:"status" validate:"required"` // Updated at // Required: true @@ -598,12 +634,16 @@ type SegmentRequest struct { DisplayName string `url:"display_name" json:"display_name" validate:"required"` // Whether the segment is enabled - // Required: false - Enabled bool `url:"enabled,omitempty" json:"enabled,omitempty"` + // Required: true + Enabled bool `url:"enabled" json:"enabled"` // ID of segment + // Required: true + ID string `url:"id" json:"id" validate:"required"` + + // L2 connection port // Required: false - ID string `url:"id,omitempty" json:"id,omitempty"` + L2ConnectionPort *L2ConnectionPortRequest `url:"-" json:"l2_connection_port,omitempty"` // Logical ports info // Required: false @@ -625,6 +665,10 @@ type SegmentRequest struct { // Required: false SubnetV6 string `url:"subnet_v6,omitempty" json:"subnet_v6,omitempty"` + // Type of segment + // Required: true + Type string `url:"type" json:"type" validate:"required"` + // Updated at // Required: true UpdatedAt time.Time `url:"updated_at" json:"updated_at" validate:"required"` @@ -634,6 +678,86 @@ type SegmentRequest struct { VersionID uint64 `url:"version_id" json:"version_id" validate:"required"` } +type L2ConnectionPortRequest struct { + // Access group ID + // Required: true + AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"` + + // Created at + // Required: true + CreatedAt time.Time `url:"created_at" json:"created_at" validate:"required"` + + // ID of the L2 connection port + // Required: true + ID string `url:"id" json:"id" validate:"required"` + + // L2 external network details + // Required: false + L2ExternalNetwork *L2ExternalNetworkRequest `url:"-" json:"l2_external_network,omitempty"` + + // Updated at + // Required: true + UpdatedAt time.Time `url:"updated_at" json:"updated_at" validate:"required"` + + // ID of the user who last updated the port + // Required: false + UpdatedBy string `url:"updated_by,omitempty" json:"updated_by,omitempty"` + + // ID of the user who created the port + // Required: false + CreatedBy string `url:"created_by,omitempty" json:"created_by,omitempty"` + + // ID of version + // Required: true + VersionID uint64 `url:"version_id" json:"version_id" validate:"required"` +} + +type L2ExternalNetworkRequest struct { + // Bridge network name + // Required: true + BridgeNetworkName string `url:"bridge_network_name" json:"bridge_network_name" validate:"required"` + + // Created at + // Required: true + CreatedAt time.Time `url:"created_at" json:"created_at" validate:"required"` + + // Detailed description of the network + // Required: true + Description string `url:"description" json:"description" validate:"required"` + + // User-friendly name for the network + // Required: true + DisplayName string `url:"display_name" json:"display_name" validate:"required"` + + // List of hypervisor IDs attached to the network + // Required: true + Hypervisors []string `url:"hypervisors" json:"hypervisors" validate:"required"` + + // ID of the network + // Required: true + ID string `url:"id" json:"id" validate:"required"` + + // Updated at + // Required: true + UpdatedAt time.Time `url:"updated_at" json:"updated_at" validate:"required"` + + // ID of version + // Required: true + VersionID uint64 `url:"version_id" json:"version_id" validate:"required"` + + // VLAN tag + // Required: false + VLANTag uint64 `url:"vlan_tag,omitempty" json:"vlan_tag,omitempty"` + + // ID of the user who last updated the network + // Required: false + UpdatedBy string `url:"updated_by,omitempty" json:"updated_by,omitempty"` + + // ID of the user who created the network + // Required: false + CreatedBy string `url:"created_by,omitempty" json:"created_by,omitempty"` +} + type DHCPv4ConfigRequest struct { // DNS // Required: false @@ -682,12 +806,12 @@ type DHCPv6ConfigRequest struct { ID string `url:"id,omitempty" json:"id,omitempty"` // Lease time - // Required: true - LeaseTime int64 `url:"lease_time" json:"lease_time" validate:"required"` + // Required: false + LeaseTime int64 `url:"lease_time,omitempty" json:"lease_time,omitempty"` // Server MAC - // Required: true - ServerMAC string `url:"server_mac" json:"server_mac" validate:"required"` + // Required: false + ServerMAC string `url:"server_mac,omitempty" json:"server_mac,omitempty"` // Whether the config is enabled // Required: true @@ -700,8 +824,8 @@ type EntityInfoRequest struct { DisplayName string `url:"display_name" json:"display_name" validate:"required"` // ID of entity - // Required: false - ID string `url:"id,omitempty" json:"id,omitempty"` + // Required: true + ID string `url:"id" json:"id" validate:"required"` } // Create creates extnet diff --git a/pkg/sdn/extnet/get.go b/pkg/sdn/extnet/get.go index a7ff6a4..d46c47f 100644 --- a/pkg/sdn/extnet/get.go +++ b/pkg/sdn/extnet/get.go @@ -11,7 +11,7 @@ import ( // GetRequest struct to get information about external network type GetRequest struct { // ID of external network - // Required: false + // Required: true ExtNetID string `url:"external_network_id" json:"external_network_id" validate:"required"` // ID of access group diff --git a/pkg/sdn/extnet/list.go b/pkg/sdn/extnet/list.go index 663c4cc..104c2e4 100644 --- a/pkg/sdn/extnet/list.go +++ b/pkg/sdn/extnet/list.go @@ -36,7 +36,7 @@ type ListRequest struct { // Filter by VLAN tag // Required: false - VLANTag string `url:"vlan_tag,omitempty" json:"vlan_tag,omitempty"` + VLANTag uint64 `url:"vlan_tag,omitempty" json:"vlan_tag,omitempty" validate:"omitempty,min=1,max=4094"` // Filter by IPv4 default gateway // Required: false diff --git a/pkg/sdn/extnet/models.go b/pkg/sdn/extnet/models.go index 2886442..f8dfa06 100644 --- a/pkg/sdn/extnet/models.go +++ b/pkg/sdn/extnet/models.go @@ -82,6 +82,15 @@ type ExternalNetworkPort struct { // Floating IP FloatingIP FloatingIP `json:"floating_ip"` + + // ID of external network + ExternalNetworkID string `json:"external_network_id"` + + // ID of external network port + ID string `json:"id"` + + // ID of version + VersionID uint64 `json:"version_id"` } type IPv6Config struct { @@ -132,7 +141,7 @@ type FloatingIP struct { CreatedAt time.Time `json:"created_at"` // External network port - ExternalNetworkPort string `json:"external_network_port"` + ExternalNetworkPort *ExternalNetworkPort `json:"external_network_port"` // ID of floating IP ID string `json:"id"` @@ -146,6 +155,12 @@ type FloatingIP struct { // Update time UpdatedAt time.Time `json:"updated_at"` + // ID of the user who created the floating IP + CreatedBy string `json:"created_by"` + + // ID of the user who last updated the floating IP + UpdatedBy string `json:"updated_by"` + // ID of version VersionID uint64 `json:"version_id"` } @@ -178,6 +193,9 @@ type LogicalPort struct { // Whether the logical port is enabled Enabled bool `json:"enabled"` + // Exclude firewall information + ExcludeFirewall ExcludeFirewall `json:"exclude_firewall"` + // External Network ID ExternalNetworkID string `json:"external_network_id"` @@ -187,6 +205,9 @@ type LogicalPort struct { // User-friendly name for hypervisor HypervisorDisplayName string `json:"hypervisor_display_name"` + // Labels + Labels Labels `json:"labels"` + // Live Migration Target Hv LiveMigrationTargetHV string `json:"live_migration_target_hv"` @@ -206,6 +227,25 @@ type LogicalPort struct { VersionID uint64 `json:"version_id"` } +type ExcludeFirewall struct { + // Exclusion reason + ExclusionReason string `json:"exclusion_reason"` + + // Whether logical port addresses are excluded from firewall + LogicalPortAddressesExcluded bool `json:"logical_port_addresses_excluded"` + + // Whether logical port is excluded from firewall + LogicalPortExcluded bool `json:"logical_port_excluded"` +} + +type Labels struct { + // VM ID + VMID string `json:"vm_id"` + + // VM name + VMName string `json:"vm_name"` +} + type PortBindings struct { // Binding ID ID string `json:"id"` @@ -222,9 +262,6 @@ type PortBindings struct { // Address detection AddressDetection bool `json:"address_detection"` - // Is Exclude From Firewall - IsExcludedFromFirewall bool `json:"is_excluded_from_firewall"` - // ID of version VersionID uint64 `json:"version_id"` @@ -319,7 +356,7 @@ type GatewayPort struct { ExternalL4PortMin int64 `json:"external_l4_port_min"` // External network port - ExternalNetworkPort interface{} `json:"external_network_port"` + ExternalNetworkPort *ExternalNetworkPort `json:"external_network_port"` // ID of port ID string `json:"id"` @@ -441,6 +478,9 @@ type Segment struct { // ID of segment ID string `json:"id"` + // L2 connection port info + L2ConnectionPort *L2ConnectionPort `json:"l2_connection_port,omitempty"` + // Logical ports info LogicalPortsInfo []EntityInfo `json:"logical_ports_info"` @@ -456,6 +496,9 @@ type Segment struct { // IPv6 subnet in CIDR notation SubnetV6 string `json:"subnet_v6"` + // Type of segment + Type string `json:"type"` + // Update time UpdatedAt time.Time `json:"updated_at"` @@ -463,6 +506,69 @@ type Segment struct { VersionID uint64 `json:"version_id"` } +// L2ConnectionPort holds information about the L2 connection port of a segment +type L2ConnectionPort struct { + // ID of the L2 connection port + ID string `json:"id"` + + // Access group ID + AccessGroupID string `json:"access_group_id"` + + // ID of version + VersionID uint64 `json:"version_id"` + + // L2 external network details + L2ExternalNetwork L2ExternalNetwork `json:"l2_external_network"` + + // Created time + CreatedAt time.Time `json:"created_at"` + + // ID of the user who created the port + CreatedBy string `json:"created_by"` + + // Updated time + UpdatedAt time.Time `json:"updated_at"` + + // ID of the user who last updated the port + UpdatedBy string `json:"updated_by"` +} + +// L2ExternalNetwork holds information about an L2 external network +type L2ExternalNetwork struct { + // ID of the network + ID string `json:"id"` + + // User-friendly name for the network + DisplayName string `json:"display_name"` + + // Detailed description of the network + Description string `json:"description"` + + // Bridge network name + BridgeNetworkName string `json:"bridge_network_name"` + + // List of hypervisor IDs attached to the network + Hypervisors []string `json:"hypervisors"` + + // VLAN tag + VLANTag uint64 `json:"vlan_tag"` + + // ID of version + VersionID uint64 `json:"version_id"` + + // Created time + CreatedAt time.Time `json:"created_at"` + + // ID of the user who created the network + CreatedBy string `json:"created_by"` + + // Updated time + UpdatedAt time.Time `json:"updated_at"` + + // ID of the user who last updated the network + UpdatedBy string `json:"updated_by"` +} + type DHCPv4Config struct { // DNS DNS []string `json:"dns"` @@ -518,16 +624,19 @@ type EntityInfo struct { } type Status struct { - // Common - Common string `json:"common"` + // Operation status + OperationStatus string `json:"operation_status"` // Hypervisors status Hypervisors []HypervisorStatus `json:"hypervisors"` + + // Hypervisor status + HypervisorStatus string `json:"hypervisor_status"` } type HypervisorStatus struct { - // Status - Status string `json:"status"` + // Operation status + OperationStatus string `json:"operation_status"` // Name of hypervisor Name string `json:"name"` diff --git a/pkg/sdn/extnet/update.go b/pkg/sdn/extnet/update.go index 695b8db..debe358 100644 --- a/pkg/sdn/extnet/update.go +++ b/pkg/sdn/extnet/update.go @@ -61,7 +61,7 @@ type UpdateRequest struct { // VLAN tag identifier // Required: false - VLANTag string `url:"vlan_tag,omitempty" json:"vlan_tag,omitempty" validate:"omitempty,trunkTags"` + VLANTag uint64 `url:"vlan_tag,omitempty" json:"vlan_tag,omitempty" validate:"omitempty,min=1,max=4094"` } // Update updated an external network diff --git a/pkg/sdn/routers/filter_test.go b/pkg/sdn/routers/filter_test.go index 8dff8a6..1e8e740 100644 --- a/pkg/sdn/routers/filter_test.go +++ b/pkg/sdn/routers/filter_test.go @@ -47,7 +47,7 @@ var testRoutersList = RoutersList{ }, }, Status: Status{ - Common: "active", + OperationStatus: "Synchronized", }, VersionID: 1, }, @@ -93,7 +93,7 @@ var testRoutersList = RoutersList{ }, }, Status: Status{ - Common: "active", + OperationStatus: "Synchronized", }, VersionID: 2, }, @@ -139,7 +139,7 @@ var testRoutersList = RoutersList{ }, }, Status: Status{ - Common: "inactive", + OperationStatus: "FailedAtCore", }, VersionID: 3, }, @@ -270,7 +270,7 @@ func TestFilterBySNATEnabled(t *testing.T) { func TestFilterByStatus(t *testing.T) { actual := testRoutersList.FilterFunc(func(rm RoutersModel) bool { - return rm.Status.Common == "inactive" + return rm.Status.OperationStatus == "FailedAtCore" }) if len(actual) != 1 || actual[0].ID != "router3" { diff --git a/pkg/sdn/routers/gwport/models.go b/pkg/sdn/routers/gwport/models.go index 1ebcf66..c5b0f25 100644 --- a/pkg/sdn/routers/gwport/models.go +++ b/pkg/sdn/routers/gwport/models.go @@ -70,6 +70,15 @@ type ExternalNetworkPort struct { // Floating IP FloatingIP FloatingIP `json:"floating_ip"` + + // External network ID + ExternalNetworkID string `json:"external_network_id"` + + // ID + ID string `json:"id"` + + // Version ID + VersionID uint64 `json:"version_id"` } // IPv6 configuration information @@ -123,7 +132,7 @@ type FloatingIP struct { CreatedAt string `json:"created_at"` // External network port - ExternalNetworkPort string `json:"external_network_port"` + ExternalNetworkPort *ExternalNetworkPort `json:"external_network_port"` // ID ID string `json:"id"` @@ -132,7 +141,55 @@ type FloatingIP struct { LogicalPort LogicalPort `json:"logical_port"` // Router - Router string `json:"router"` + Router *Router `json:"router"` + + // Updated time + UpdatedAt string `json:"updated_at"` + + // Created by + CreatedBy string `json:"created_by"` + + // Updated by + UpdatedBy string `json:"updated_by"` + + // Version ID + VersionID uint64 `json:"version_id"` +} + +// Router information +type Router struct { + // Access group ID + AccessGroupID string `json:"access_group_id"` + + // Access group name + AccessGroupName string `json:"access_group_name"` + + // Created time + CreatedAt string `json:"created_at"` + + // Description + Description string `json:"description"` + + // Display name + DisplayName string `json:"display_name"` + + // Enabled flag + Enabled bool `json:"enabled"` + + // List of gateway ports + GatewayPorts []GatewayPort `json:"gateway_ports"` + + // ID + ID string `json:"id"` + + // List of policies + Policies []Policy `json:"policies"` + + // List of ports + Ports []Port `json:"ports"` + + // Status information + Status Status `json:"status"` // Updated time UpdatedAt string `json:"updated_at"` @@ -170,6 +227,9 @@ type LogicalPort struct { // Enabled flag Enabled bool `json:"enabled"` + // Exclude firewall information + ExcludeFirewall ExcludeFirewall `json:"exclude_firewall"` + // External network ID ExternalNetworkID string `json:"external_network_id"` @@ -179,6 +239,9 @@ type LogicalPort struct { // Hypervisor display name HypervisorDisplayName string `json:"hypervisor_display_name"` + // Labels + Labels Labels `json:"labels"` + // Live migration target HV LiveMigrationTargetHV string `json:"live_migration_target_hv"` @@ -200,8 +263,8 @@ type LogicalPort struct { // Status information type Status struct { - // Common status - Common string `json:"common"` + // Operation status + OperationStatus string `json:"operation_status"` // Hypervisors status list Hypervisors []HypervisorStatus `json:"hypervisors"` @@ -209,8 +272,8 @@ type Status struct { // Hypervisor status information type HypervisorStatus struct { - // Status - Status string `json:"status"` + // Operation status + OperationStatus string `json:"operation_status"` // Name Name string `json:"name"` @@ -225,6 +288,27 @@ type HypervisorStatus struct { SyncedAt string `json:"synced_at"` } +// Exclude firewall information +type ExcludeFirewall struct { + // Exclusion reason + ExclusionReason string `json:"exclusion_reason"` + + // Logical port addresses excluded flag + LogicalPortAddressesExcluded bool `json:"logical_port_addresses_excluded"` + + // Logical port excluded flag + LogicalPortExcluded bool `json:"logical_port_excluded"` +} + +// Labels information +type Labels struct { + // VM ID + VMID string `json:"vm_id"` + + // VM name + VMName string `json:"vm_name"` +} + // Bindings information type Bindings struct { // ID @@ -242,9 +326,6 @@ type Bindings struct { // Address detection flag AddressDetection bool `json:"address_detection"` - // Is excluded from firewall flag - IsExcludedFromFirewall bool `json:"is_excluded_from_firewall"` - // Version ID VersionID uint64 `json:"version_id"` @@ -395,6 +476,9 @@ type Segment struct { // Logical ports info list LogicalPortsInfo []LogicalPortInfo `json:"logical_ports_info"` + // L2 connection port information + L2ConnectionPort *L2ConnectionPort `json:"l2_connection_port,omitempty"` + // Routers info list RoutersInfo []RouterInfo `json:"routers_info"` @@ -407,6 +491,9 @@ type Segment struct { // IPv6 subnet SubnetV6 string `json:"subnet_v6"` + // Type + Type string `json:"type"` + // Updated time UpdatedAt string `json:"updated_at"` @@ -479,3 +566,66 @@ type RouterInfo struct { // ID ID string `json:"id"` } + +// L2 connection port information +type L2ConnectionPort struct { + // Access group ID + AccessGroupID string `json:"access_group_id"` + + // Created time + CreatedAt string `json:"created_at"` + + // Created by + CreatedBy string `json:"created_by"` + + // ID + ID string `json:"id"` + + // L2 external network information + L2ExternalNetwork L2ExternalNetwork `json:"l2_external_network"` + + // Updated time + UpdatedAt string `json:"updated_at"` + + // Updated by + UpdatedBy string `json:"updated_by"` + + // Version ID + VersionID uint64 `json:"version_id"` +} + +// L2 external network information +type L2ExternalNetwork struct { + // ID + ID string `json:"id"` + + // Display name + DisplayName string `json:"display_name"` + + // Description + Description string `json:"description"` + + // Bridge network name + BridgeNetworkName string `json:"bridge_network_name"` + + // Hypervisors list + Hypervisors []string `json:"hypervisors"` + + // VLAN tag + VLANTag uint64 `json:"vlan_tag"` + + // Created time + CreatedAt string `json:"created_at"` + + // Created by + CreatedBy string `json:"created_by"` + + // Updated time + UpdatedAt string `json:"updated_at"` + + // Updated by + UpdatedBy string `json:"updated_by"` + + // Version ID + VersionID uint64 `json:"version_id"` +} diff --git a/pkg/sdn/routers/list.go b/pkg/sdn/routers/list.go index a50a81d..1f4f4a8 100644 --- a/pkg/sdn/routers/list.go +++ b/pkg/sdn/routers/list.go @@ -57,6 +57,10 @@ type ListRequest struct { // Sort order (asc/desc) // Required: false SortOrder string `url:"sort_order,omitempty" json:"sort_order,omitempty" validate:"omitempty,oneof=asc desc"` + + // Filter by operation status + // Required: false + OperationStatus string `url:"operation_status,omitempty" json:"operation_status,omitempty"` } // List of routers diff --git a/pkg/sdn/routers/models.go b/pkg/sdn/routers/models.go index 9e36b9a..6a63344 100644 --- a/pkg/sdn/routers/models.go +++ b/pkg/sdn/routers/models.go @@ -112,6 +112,15 @@ type ExternalNetworkPort struct { // Floating IP FloatingIP FloatingIP `json:"floating_ip"` + + // External network ID + ExternalNetworkID string `json:"external_network_id"` + + // ID + ID string `json:"id"` + + // Version ID + VersionID uint64 `json:"version_id"` } // IPv6 configuration information @@ -165,7 +174,7 @@ type FloatingIP struct { CreatedAt string `json:"created_at"` // External network port - ExternalNetworkPort string `json:"external_network_port"` + ExternalNetworkPort *ExternalNetworkPort `json:"external_network_port"` // ID ID string `json:"id"` @@ -174,11 +183,17 @@ type FloatingIP struct { LogicalPort LogicalPort `json:"logical_port"` // Router - Router string `json:"router"` + Router *RoutersModel `json:"router"` // Updated time UpdatedAt string `json:"updated_at"` + // Created by + CreatedBy string `json:"created_by"` + + // Updated by + UpdatedBy string `json:"updated_by"` + // Version ID VersionID uint64 `json:"version_id"` } @@ -212,6 +227,9 @@ type LogicalPort struct { // Enabled flag Enabled bool `json:"enabled"` + // Exclude firewall information + ExcludeFirewall ExcludeFirewall `json:"exclude_firewall"` + // External network ID ExternalNetworkID string `json:"external_network_id"` @@ -221,6 +239,9 @@ type LogicalPort struct { // Hypervisor display name HypervisorDisplayName string `json:"hypervisor_display_name"` + // Labels + Labels Labels `json:"labels"` + // Live migration target HV LiveMigrationTargetHV string `json:"live_migration_target_hv"` @@ -242,8 +263,8 @@ type LogicalPort struct { // Status information type Status struct { - // Common status - Common string `json:"common"` + // Operation status + OperationStatus string `json:"operation_status"` // Hypervisors status list Hypervisors []HypervisorStatus `json:"hypervisors"` @@ -251,8 +272,8 @@ type Status struct { // Hypervisor status information type HypervisorStatus struct { - // Status - Status string `json:"status"` + // Operation status + OperationStatus string `json:"operation_status"` // Name Name string `json:"name"` @@ -267,6 +288,27 @@ type HypervisorStatus struct { SyncedAt string `json:"synced_at"` } +// Exclude firewall information +type ExcludeFirewall struct { + // Exclusion reason + ExclusionReason string `json:"exclusion_reason"` + + // Logical port addresses excluded flag + LogicalPortAddressesExcluded bool `json:"logical_port_addresses_excluded"` + + // Logical port excluded flag + LogicalPortExcluded bool `json:"logical_port_excluded"` +} + +// Labels information +type Labels struct { + // VM ID + VMID string `json:"vm_id"` + + // VM name + VMName string `json:"vm_name"` +} + // Bindings information type Bindings struct { // ID @@ -284,9 +326,6 @@ type Bindings struct { // Address detection flag AddressDetection bool `json:"address_detection"` - // Is excluded from firewall flag - IsExcludedFromFirewall bool `json:"is_excluded_from_firewall"` - // Version ID VersionID uint64 `json:"version_id"` @@ -437,6 +476,9 @@ type Segment struct { // Logical ports info list LogicalPortsInfo []LogicalPortInfo `json:"logical_ports_info"` + // L2 connection port information + L2ConnectionPort *L2ConnectionPort `json:"l2_connection_port,omitempty"` + // Routers info list RoutersInfo []RouterInfo `json:"routers_info"` @@ -449,6 +491,9 @@ type Segment struct { // IPv6 subnet SubnetV6 string `json:"subnet_v6"` + // Type + Type string `json:"type"` + // Updated time UpdatedAt string `json:"updated_at"` @@ -521,3 +566,66 @@ type RouterInfo struct { // ID ID string `json:"id"` } + +// L2 connection port information +type L2ConnectionPort struct { + // Access group ID + AccessGroupID string `json:"access_group_id"` + + // Created time + CreatedAt string `json:"created_at"` + + // Created by + CreatedBy string `json:"created_by"` + + // ID + ID string `json:"id"` + + // L2 external network information + L2ExternalNetwork L2ExternalNetwork `json:"l2_external_network"` + + // Updated time + UpdatedAt string `json:"updated_at"` + + // Updated by + UpdatedBy string `json:"updated_by"` + + // Version ID + VersionID uint64 `json:"version_id"` +} + +// L2 external network information +type L2ExternalNetwork struct { + // ID + ID string `json:"id"` + + // Display name + DisplayName string `json:"display_name"` + + // Description + Description string `json:"description"` + + // Bridge network name + BridgeNetworkName string `json:"bridge_network_name"` + + // Hypervisors list + Hypervisors []string `json:"hypervisors"` + + // VLAN tag + VLANTag uint64 `json:"vlan_tag"` + + // Created time + CreatedAt string `json:"created_at"` + + // Created by + CreatedBy string `json:"created_by"` + + // Updated time + UpdatedAt string `json:"updated_at"` + + // Updated by + UpdatedBy string `json:"updated_by"` + + // Version ID + VersionID uint64 `json:"version_id"` +} diff --git a/pkg/sdn/routers/policies/list.go b/pkg/sdn/routers/policies/list.go index ec5174e..8554e09 100644 --- a/pkg/sdn/routers/policies/list.go +++ b/pkg/sdn/routers/policies/list.go @@ -26,9 +26,9 @@ type ListRequest struct { // Required: false PerPage uint64 `url:"per_page,omitempty" json:"per_page,omitempty"` - // Field to sort by (display_name, subnet, created_at, updated_at) + // Field to sort by (created_at, updated_at, priority) // Required: false - SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty" validate:"omitempty,oneof=display_name subnet created_at updated_at"` + SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty" validate:"omitempty,oneof=created_at updated_at priority"` // Sort order (asc/desc) // Required: false diff --git a/pkg/sdn/secpolicies/create.go b/pkg/sdn/secpolicies/create.go index 0233026..f4d9c14 100644 --- a/pkg/sdn/secpolicies/create.go +++ b/pkg/sdn/secpolicies/create.go @@ -15,17 +15,17 @@ type CreateRequest struct { // Required: true AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"` - // Applied to net object group ID - // Required: true - AppliedToNetObjectGroupID string `url:"applied_to_net_object_group_id" json:"applied_to_net_object_group_id" validate:"required"` + // Applied to net object groups + // Required: false + AppliedToNetObjectGroupID []AppliedToNetObjectGroup `url:"applied_to_net_object_group_ids,omitempty" json:"applied_to_net_object_group_ids,omitempty" validate:"omitempty,dive"` // Description of the schedule rule // Required: true - Description string `url:"description" json:"description"` + Description string `url:"description" json:"description" validate:"required"` // Display name of the schedule rule // Required: true - DisplayName string `url:"display_name" json:"display_name"` + DisplayName string `url:"display_name" json:"display_name" validate:"required"` // Enabled status of the schedule rule // Required: true @@ -47,11 +47,175 @@ type CreateRequest struct { // Required: false ScheduleCron string `url:"schedule_cron,omitempty" json:"schedule_cron,omitempty"` + // Security rules to create in the security policy + // Required: false + SecurityRulesForCreate []SecurityRuleForCreate `url:"security_rules_for_create,omitempty" json:"security_rules_for_create,omitempty" validate:"omitempty,dive"` + // Start date and time for the schedule rule // Required: false StartDateTime string `url:"start_date_time,omitempty" json:"start_date_time,omitempty"` } +// AppliedToNetObjectGroup struct of network object group to apply the security policy (rule) to +type AppliedToNetObjectGroup struct { + // Network object group ID + // Required: true + ID string `url:"id" json:"id" validate:"required"` + + // Network object group version ID + // Required: true + VersionID uint64 `url:"version_id" json:"version_id" validate:"required"` +} + +// SecurityRuleForCreate struct of security rule to create in the security policy +type SecurityRuleForCreate struct { + // Action to take (Allow, Deny, etc.) + // Required: true + Action string `url:"action" json:"action" validate:"required"` + + // Applied to net object groups + // Required: false + AppliedNetObjectGroups []AppliedToNetObjectGroup `url:"applied_net_object_groups,omitempty" json:"applied_net_object_groups,omitempty" validate:"omitempty,dive"` + + // Description + // Required: false + Description string `url:"description,omitempty" json:"description,omitempty"` + + // Destination net object groups + // Required: false + DestinationNetObjectGroups []RuleNetObjectGroup `url:"destination_net_object_groups,omitempty" json:"destination_net_object_groups,omitempty" validate:"omitempty,dive"` + + // Traffic direction (Ingress, Egress) + // Required: true + Direction string `url:"direction" json:"direction" validate:"required"` + + // Display name + // Required: true + DisplayName string `url:"display_name" json:"display_name" validate:"required"` + + // Enabled flag + // Required: true + Enabled bool `url:"enabled" json:"enabled"` + + // Filter criteria + // Required: false + Filters []RuleFilter `url:"filters,omitempty" json:"filters,omitempty"` + + // ID of the rule above which to insert this rule + // Required: false + InsertUpRuleID string `url:"insert_up_rule_id,omitempty" json:"insert_up_rule_id,omitempty"` + + // Log enabled flag + // Required: true + LogEnabled bool `url:"log_enabled" json:"log_enabled"` + + // Logging profile ID + // Required: false + LoggingProfileID string `url:"logging_profile_id,omitempty" json:"logging_profile_id,omitempty"` + + // Security rule condition group IDs + // Required: false + SecurityRuleConditionGroupIDs []string `url:"security_rule_condition_group_ids,omitempty" json:"security_rule_condition_group_ids,omitempty"` + + // Security rule condition IDs + // Required: false + SecurityRuleConditionIDs []string `url:"security_rule_condition_ids,omitempty" json:"security_rule_condition_ids,omitempty"` + + // Source net object groups + // Required: false + SourceNetObjectGroups []RuleNetObjectGroup `url:"source_net_object_groups,omitempty" json:"source_net_object_groups,omitempty" validate:"omitempty,dive"` + + // Statistics enabled flag + // Required: true + StatisticsEnabled bool `url:"statistics_enabled" json:"statistics_enabled"` +} + +// RuleNetObjectGroup struct of source or destination network object group of the security rule +type RuleNetObjectGroup struct { + // Network object group ID + // Required: true + ID string `url:"id" json:"id" validate:"required"` + + // Is positive flag + // Required: true + IsPositive bool `url:"is_positive" json:"is_positive"` + + // Network object group version ID + // Required: true + VersionID uint64 `url:"version_id" json:"version_id" validate:"required"` +} + +// RuleFilter struct of filter criteria of the security rule +type RuleFilter struct { + // All traffic + // Required: false + All bool `url:"all,omitempty" json:"all,omitempty"` + + // ARP traffic + // Required: false + ARP bool `url:"arp,omitempty" json:"arp,omitempty"` + + // Ethernet type + // Required: false + EthType string `url:"eth_type,omitempty" json:"eth_type,omitempty"` + + // Filter expression + // Required: false + Expression string `url:"expression,omitempty" json:"expression,omitempty"` + + // ICMP traffic + // Required: false + ICMP bool `url:"icmp,omitempty" json:"icmp,omitempty"` + + // IP traffic + // Required: false + IP bool `url:"ip,omitempty" json:"ip,omitempty"` + + // IP protocol number + // Required: false + IPProto uint64 `url:"ip_proto,omitempty" json:"ip_proto,omitempty"` + + // IPv4 traffic + // Required: false + IPv4 bool `url:"ip_v4,omitempty" json:"ip_v4,omitempty"` + + // IPv6 traffic + // Required: false + IPv6 bool `url:"ip_v6,omitempty" json:"ip_v6,omitempty"` + + // Keep opened sessions + // Required: false + KeepOpenedSessions bool `url:"keep_opened_sessions,omitempty" json:"keep_opened_sessions,omitempty"` + + // ND traffic + // Required: false + ND bool `url:"nd,omitempty" json:"nd,omitempty"` + + // TCP traffic + // Required: false + TCP bool `url:"tcp,omitempty" json:"tcp,omitempty"` + + // TCP source ports + // Required: false + TCPSrcPorts []string `url:"tcp_src_ports,omitempty" json:"tcp_src_ports,omitempty"` + + // TCP destination ports + // Required: false + TCPDstPorts []string `url:"tcp_dst_ports,omitempty" json:"tcp_dst_ports,omitempty"` + + // UDP traffic + // Required: false + UDP bool `url:"udp,omitempty" json:"udp,omitempty"` + + // UDP source ports + // Required: false + UDPSrcPorts []string `url:"udp_src_ports,omitempty" json:"udp_src_ports,omitempty"` + + // UDP destination ports + // Required: false + UDPDstPorts []string `url:"udp_dst_ports,omitempty" json:"udp_dst_ports,omitempty"` +} + // Create creates a security policy func (i SecurityPolicies) Create(ctx context.Context, req CreateRequest) (*SecurityPolicySummary, error) { err := validators.ValidateRequest(req) diff --git a/pkg/sdn/secpolicies/filter_test.go b/pkg/sdn/secpolicies/filter_test.go index c4020ac..fbf3674 100644 --- a/pkg/sdn/secpolicies/filter_test.go +++ b/pkg/sdn/secpolicies/filter_test.go @@ -6,148 +6,103 @@ import ( var testSecurityPolicies = SecurityPolicyList{ { - ID: "policy1", - DisplayName: "DevelopersPolicy", - Description: "First policy", - CreatedAt: "2023-01-01", - UpdatedAt: "2023-01-10", - AccessGroupID: "group1", - AccessGroupName: "Developers", - AppliedToNetObjectGroupID: "netgroup1", - Enabled: true, - StartPriority: 1, - EndPriority: 100, - VersionID: 1, + ID: "policy1", + DisplayName: "DevelopersPolicy", + Description: "First policy", + CreatedAt: "2023-01-01", + UpdatedAt: "2023-01-10", + AccessGroupID: "group1", + AccessGroupName: "Developers", + AppliedNetObjectGroups: []AppliedNetObjectGroup{ + { + ID: "netgroup1", + Name: "NetGroup1", + VersionID: 11, + }, + }, + Type: "User", + Enabled: true, + StartPriority: 1, + EndPriority: 100, + VersionID: 1, Status: Status{ - Common: "active", + OperationStatus: "Synchronized", Hypervisors: []HypervisorStatus{ { Name: "hyp1", DisplayName: "Hypervisor1", - Status: "synced", + OperationStatus: "Synchronized", HypervisorStatus: "healthy", SyncedAt: "2023-01-10T10:00:00Z", }, }, }, - SecurityRules: []SecurityRule{ - { - ID: "rule1", - DisplayName: "AllowHTTP", - Description: "Allow HTTP traffic", - Action: "Allow", - Direction: "Ingress", - Enabled: true, - Priority: 10, - SecurityPolicyID: "policy1", - LogEnabled: true, - LogSeverity: "medium", - StatisticsEnabled: true, - VersionID: 1, - Filter: Filter{ - Filters: map[string]interface{}{ - "protocol": "tcp", - "port": float64(80), - }, - }, - }, - }, }, { - ID: "policy2", - DisplayName: "AdminsPolicy", - Description: "Second policy", - CreatedAt: "2023-01-02", - UpdatedAt: "2023-01-11", - AccessGroupID: "group2", - AccessGroupName: "Admins", - AppliedToNetObjectGroupID: "netgroup2", - Enabled: false, - StartPriority: 101, - EndPriority: 200, - VersionID: 2, + ID: "policy2", + DisplayName: "AdminsPolicy", + Description: "Second policy", + CreatedAt: "2023-01-02", + UpdatedAt: "2023-01-11", + AccessGroupID: "group2", + AccessGroupName: "Admins", + AppliedNetObjectGroups: []AppliedNetObjectGroup{ + { + ID: "netgroup2", + Name: "NetGroup2", + VersionID: 12, + }, + }, + Type: "System", + Enabled: false, + StartPriority: 101, + EndPriority: 200, + VersionID: 2, Status: Status{ - Common: "inactive", + OperationStatus: "Idle", Hypervisors: []HypervisorStatus{ { Name: "hyp2", DisplayName: "Hypervisor2", - Status: "pending", + OperationStatus: "Idle", HypervisorStatus: "syncing", SyncedAt: "2023-01-11T10:00:00Z", }, }, }, - SecurityRules: []SecurityRule{ - { - ID: "rule2", - DisplayName: "DenySSH", - Description: "Deny SSH traffic", - Action: "Deny", - Direction: "Ingress", - Enabled: true, - Priority: 20, - SecurityPolicyID: "policy2", - LogEnabled: false, - LogSeverity: "high", - StatisticsEnabled: false, - VersionID: 1, - Filter: Filter{ - Filters: map[string]interface{}{ - "protocol": "tcp", - "port": float64(22), - }, - }, - }, - }, }, { - ID: "policy3", - DisplayName: "UsersPolicy", - Description: "Third policy", - CreatedAt: "2023-01-03", - UpdatedAt: "2023-01-12", - AccessGroupID: "group3", - AccessGroupName: "Users", - AppliedToNetObjectGroupID: "netgroup3", - Enabled: true, - StartPriority: 201, - EndPriority: 300, - VersionID: 3, + ID: "policy3", + DisplayName: "UsersPolicy", + Description: "Third policy", + CreatedAt: "2023-01-03", + UpdatedAt: "2023-01-12", + AccessGroupID: "group3", + AccessGroupName: "Users", + AppliedNetObjectGroups: []AppliedNetObjectGroup{ + { + ID: "netgroup3", + Name: "NetGroup3", + VersionID: 13, + }, + }, + Type: "User", + Enabled: true, + StartPriority: 201, + EndPriority: 300, + VersionID: 3, Status: Status{ - Common: "active", + OperationStatus: "Synchronized", Hypervisors: []HypervisorStatus{ { Name: "hyp3", DisplayName: "Hypervisor3", - Status: "synced", + OperationStatus: "Synchronized", HypervisorStatus: "healthy", SyncedAt: "2023-01-12T10:00:00Z", }, }, }, - SecurityRules: []SecurityRule{ - { - ID: "rule3", - DisplayName: "AllowHTTPS", - Description: "Allow HTTPS traffic", - Action: "Allow", - Direction: "Egress", - Enabled: true, - Priority: 30, - SecurityPolicyID: "policy3", - LogEnabled: true, - LogSeverity: "low", - StatisticsEnabled: true, - VersionID: 1, - Filter: Filter{ - Filters: map[string]interface{}{ - "protocol": "tcp", - "port": float64(443), - }, - }, - }, - }, }, } @@ -231,7 +186,7 @@ func TestFilterByAccessGroup(t *testing.T) { func TestFilterByStatus(t *testing.T) { actual := testSecurityPolicies.FilterFunc(func(sp SecurityPolicySummary) bool { - return sp.Status.Common == "active" + return sp.Status.OperationStatus == "Synchronized" }) if len(actual) != 2 { @@ -249,25 +204,20 @@ func TestFilterByPriorityRange(t *testing.T) { } } -func TestFilterByRuleAction(t *testing.T) { +func TestFilterByType(t *testing.T) { actual := testSecurityPolicies.FilterFunc(func(sp SecurityPolicySummary) bool { - for _, rule := range sp.SecurityRules { - if rule.Action == "Deny" { - return true - } - } - return false + return sp.Type == "System" }) if len(actual) != 1 || actual[0].ID != "policy2" { - t.Fatal("Expected 1 policy with Deny rule, found:", len(actual)) + t.Fatal("Expected 1 System policy, found:", len(actual)) } } -func TestFilterByRuleDirection(t *testing.T) { +func TestFilterByAppliedNetObjectGroup(t *testing.T) { actual := testSecurityPolicies.FilterFunc(func(sp SecurityPolicySummary) bool { - for _, rule := range sp.SecurityRules { - if rule.Direction == "Egress" { + for _, group := range sp.AppliedNetObjectGroups { + if group.ID == "netgroup3" { return true } } @@ -275,21 +225,6 @@ func TestFilterByRuleDirection(t *testing.T) { }) if len(actual) != 1 || actual[0].ID != "policy3" { - t.Fatal("Expected 1 policy with Egress rule, found:", len(actual)) - } -} - -func TestFilterByLogEnabled(t *testing.T) { - actual := testSecurityPolicies.FilterFunc(func(sp SecurityPolicySummary) bool { - for _, rule := range sp.SecurityRules { - if rule.LogEnabled { - return true - } - } - return false - }) - - if len(actual) != 2 { - t.Fatal("Expected 2 policies with log enabled rules, found:", len(actual)) + t.Fatal("Expected 1 policy applied to netgroup3, found:", len(actual)) } } diff --git a/pkg/sdn/secpolicies/get.go b/pkg/sdn/secpolicies/get.go index d7dae83..f24c827 100644 --- a/pkg/sdn/secpolicies/get.go +++ b/pkg/sdn/secpolicies/get.go @@ -40,7 +40,7 @@ func (a SecurityPolicies) GetRaw(ctx context.Context, req GetRequest) ([]byte, e return nil, validators.ValidationErrors(validators.GetErrors(err)) } - url := "/sdn/security_policies/get" + url := "/sdn/security_policy/get" res, err := a.client.DecortApiCall(ctx, http.MethodGet, url, req) return res, err diff --git a/pkg/sdn/secpolicies/list.go b/pkg/sdn/secpolicies/list.go index b339a8f..6953261 100644 --- a/pkg/sdn/secpolicies/list.go +++ b/pkg/sdn/secpolicies/list.go @@ -22,9 +22,17 @@ type ListRequest struct { // Required: false AccessGroupID string `url:"access_group_id,omitempty" json:"access_group_id,omitempty"` - // Filter by applied to net object group ID + // Filter by applied to net object group IDs // Required: false - AppliedToNetObjectGroupID string `url:"applied_to_net_object_group_id,omitempty" json:"applied_to_net_object_group_id,omitempty"` + AppliedToNetObjectGroupID []string `url:"applied_to_net_object_group_ids,omitempty" json:"applied_to_net_object_group_ids,omitempty"` + + // Filter by operation status + // Required: false + OperationStatus string `url:"operation_status,omitempty" json:"operation_status,omitempty"` + + // Filter by type (User, System) + // Required: false + Type string `url:"type,omitempty" json:"type,omitempty"` // Page number for pagination // Required: false diff --git a/pkg/sdn/secpolicies/models.go b/pkg/sdn/secpolicies/models.go index f746425..201c35e 100644 --- a/pkg/sdn/secpolicies/models.go +++ b/pkg/sdn/secpolicies/models.go @@ -10,8 +10,8 @@ type SecurityPolicySummary struct { // Access group name AccessGroupName string `json:"access_group_name"` - // Applied to network object group ID - AppliedToNetObjectGroupID string `json:"applied_to_net_object_group_id"` + // Applied network object groups + AppliedNetObjectGroups []AppliedNetObjectGroup `json:"applied_net_object_groups"` // Created time CreatedAt string `json:"created_at"` @@ -25,14 +25,23 @@ type SecurityPolicySummary struct { // Enabled flag Enabled bool `json:"enabled"` + // End date and time + EndDateTime string `json:"end_date_time"` + // End priority EndPriority int `json:"end_priority"` // ID ID string `json:"id"` - // Security rules - SecurityRules []SecurityRule `json:"security_rules"` + // Locked at timestamp + LockedAt string `json:"locked_at"` + + // Schedule cron expression + ScheduleCron string `json:"schedule_cron"` + + // Start date and time + StartDateTime string `json:"start_date_time"` // Start priority StartPriority int `json:"start_priority"` @@ -40,6 +49,9 @@ type SecurityPolicySummary struct { // Status information Status Status `json:"status"` + // Type + Type string `json:"type"` + // Version ID VersionID uint64 `json:"version_id"` @@ -47,10 +59,25 @@ type SecurityPolicySummary struct { UpdatedAt string `json:"updated_at"` } +// AppliedNetObjectGroup information about network object group the security policy is applied to +type AppliedNetObjectGroup struct { + // ID + ID string `json:"id"` + + // Name + Name string `json:"name"` + + // Version ID + VersionID uint64 `json:"version_id"` +} + // Status information type Status struct { - // Common status - Common string `json:"common"` + // Operation status + OperationStatus string `json:"operation_status"` + + // Hypervisor status + HypervisorStatus string `json:"hypervisor_status"` // Hypervisor statuses Hypervisors []HypervisorStatus `json:"hypervisors"` @@ -58,8 +85,8 @@ type Status struct { // HypervisorStatus information type HypervisorStatus struct { - // Status - Status string `json:"status"` + // Operation status + OperationStatus string `json:"operation_status"` // Name Name string `json:"name"` @@ -73,54 +100,3 @@ type HypervisorStatus struct { // Last sync time SyncedAt string `json:"synced_at"` } - -// Security rules -type SecurityRule struct { - // Access group ID - AccessGroupID string `json:"access_group_id"` - - // Action to take (Allow, Deny, etc.) - Action string `json:"action"` - - // Description - Description string `json:"description"` - - // Traffic direction (Ingress, Egress) - Direction string `json:"direction"` - - // Display name - DisplayName string `json:"display_name"` - - // Enabled flag - Enabled bool `json:"enabled"` - - // Filter criteria - Filter Filter `json:"filter"` - - // ID - ID string `json:"id"` - - // Log enabled flag - LogEnabled bool `json:"log_enabled"` - - // Log severity level - LogSeverity string `json:"log_severity"` - - // Priority - Priority int `json:"priority"` - - // Security policy ID - SecurityPolicyID string `json:"security_policy_id"` - - // Statistics enabled flag - StatisticsEnabled bool `json:"statistics_enabled"` - - // Version ID - VersionID uint64 `json:"version_id"` -} - -// Filter represents the filter criteria for the security rule -type Filter struct { - // Filters map - Filters map[string]interface{} `json:"filters"` -} diff --git a/pkg/sdn/secpolicies/move.go b/pkg/sdn/secpolicies/move.go index d1ca872..13eb143 100644 --- a/pkg/sdn/secpolicies/move.go +++ b/pkg/sdn/secpolicies/move.go @@ -19,9 +19,9 @@ type MoveRequest struct { // Required: true VersionID uint64 `url:"version_id" json:"version_id" validate:"required"` - // Security policy ID - // Required: true - InsertUp string `url:"insert_up" json:"insert_up" validate:"required"` + // ID of the security policy above which to insert the policy. Empty value inserts to the top + // Required: false + InsertUp string `url:"insert_up,omitempty" json:"insert_up,omitempty"` } // Move a security policy diff --git a/pkg/sdn/secpolicies/update.go b/pkg/sdn/secpolicies/update.go index ddcd0d0..1523097 100644 --- a/pkg/sdn/secpolicies/update.go +++ b/pkg/sdn/secpolicies/update.go @@ -18,17 +18,21 @@ type UpdateRequest struct { // Required: true VersionID uint64 `url:"version_id" json:"version_id" validate:"required"` - // Applied to net object group ID + // Access group ID // Required: true - AppliedToNetObjectGroupID string `url:"applied_to_net_object_group_id" json:"applied_to_net_object_group_id" validate:"required"` + AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"` + + // Applied net object groups + // Required: false + AppliedNetObjectGroups []AppliedToNetObjectGroup `url:"applied_net_object_groups,omitempty" json:"applied_net_object_groups,omitempty" validate:"omitempty,dive"` // Description of the schedule rule // Required: true - Description string `url:"description" json:"description"` + Description string `url:"description" json:"description" validate:"required"` // Display name of the schedule rule // Required: true - DisplayName string `url:"display_name" json:"display_name"` + DisplayName string `url:"display_name" json:"display_name" validate:"required"` // Enabled status of the schedule rule // Required: true @@ -38,10 +42,6 @@ type UpdateRequest struct { // Required: false EndDateTime string `url:"end_date_time,omitempty" json:"end_date_time,omitempty"` - // Insert up reference - // Required: false - InsertUp string `url:"insert_up,omitempty" json:"insert_up,omitempty"` - // Locked at timestamp // Required: false LockedAt string `url:"locked_at,omitempty" json:"locked_at,omitempty"` diff --git a/tests/platform_upgrade/request_map.go b/tests/platform_upgrade/request_map.go index a610798..9f14d1a 100644 --- a/tests/platform_upgrade/request_map.go +++ b/tests/platform_upgrade/request_map.go @@ -234,31 +234,36 @@ func getRequestsMapCloudAPI() map[string]interface{} { "/restmachine/cloudapi/compute/migrateToZone": compute.MigrateToZoneRequest{}, // disks - "/restmachine/cloudapi/disks/change_disk_storage_policy": disks.ChangeDiskStoragePolicyRequest{}, - "/restmachine/cloudapi/disks/create": disks.CreateRequest{}, - "/restmachine/cloudapi/disks/delete": disks.DeleteRequest{}, - "/restmachine/cloudapi/disks/deleteDisks": disks.DisksDeleteRequest{}, - "/restmachine/cloudapi/disks/fromPlatformDisk": disks.FromPlatformDiskRequest{}, - "/restmachine/cloudapi/disks/get": disks.GetRequest{}, - "/restmachine/cloudapi/disks/limitIO": disks.LimitIORequest{}, - "/restmachine/cloudapi/disks/list": disks.ListRequest{}, - "/restmachine/cloudapi/disks/listDeleted": disks.ListDeletedRequest{}, - "/restmachine/cloudapi/disks/listUnattached": disks.ListUnattachedRequest{}, - "/restmachine/cloudapi/disks/rename": disks.RenameRequest{}, - "/restmachine/cloudapi/disks/replicate": disks.ReplicateRequest{}, - "/restmachine/cloudapi/disks/replicationResume": disks.ReplicationResumeRequest{}, - "/restmachine/cloudapi/disks/replicationReverse": disks.ReplicationReverseRequest{}, - "/restmachine/cloudapi/disks/replicationStart": disks.ReplicationStartRequest{}, - "/restmachine/cloudapi/disks/replicationStatus": disks.ReplicationStatusRequest{}, - "/restmachine/cloudapi/disks/replicationStop": disks.ReplicationStopRequest{}, - "/restmachine/cloudapi/disks/replicationSuspend": disks.ReplicationSuspendRequest{}, - "/restmachine/cloudapi/disks/resize2": disks.ResizeRequest{}, - "/restmachine/cloudapi/disks/restore": disks.RestoreRequest{}, - "/restmachine/cloudapi/disks/search": disks.SearchRequest{}, - "/restmachine/cloudapi/disks/share": disks.ShareRequest{}, - "/restmachine/cloudapi/disks/snapshotDelete": disks.SnapshotDeleteRequest{}, - "/restmachine/cloudapi/disks/snapshotRollback": disks.SnapshotRollbackRequest{}, - "/restmachine/cloudapi/disks/unshare": disks.UnshareRequest{}, + "/restmachine/cloudapi/disks/change_disk_storage_policy": disks.ChangeDiskStoragePolicyRequest{}, + "/restmachine/cloudapi/disks/create": disks.CreateRequest{}, + "/restmachine/cloudapi/disks/delete": disks.DeleteRequest{}, + "/restmachine/cloudapi/disks/deleteDisks": disks.DisksDeleteRequest{}, + "/restmachine/cloudapi/disks/fromPlatformDisk": disks.FromPlatformDiskRequest{}, + "/restmachine/cloudapi/disks/get": disks.GetRequest{}, + "/restmachine/cloudapi/disks/limitIO": disks.LimitIORequest{}, + "/restmachine/cloudapi/disks/list": disks.ListRequest{}, + "/restmachine/cloudapi/disks/listDeleted": disks.ListDeletedRequest{}, + "/restmachine/cloudapi/disks/listUnattached": disks.ListUnattachedRequest{}, + "/restmachine/cloudapi/disks/rename": disks.RenameRequest{}, + "/restmachine/cloudapi/disks/replicate": disks.ReplicateRequest{}, + "/restmachine/cloudapi/disks/replicationResume": disks.ReplicationResumeRequest{}, + "/restmachine/cloudapi/disks/replicationReverse": disks.ReplicationReverseRequest{}, + "/restmachine/cloudapi/disks/replicationStart": disks.ReplicationStartRequest{}, + "/restmachine/cloudapi/disks/replicationStatus": disks.ReplicationStatusRequest{}, + "/restmachine/cloudapi/disks/replicationStop": disks.ReplicationStopRequest{}, + "/restmachine/cloudapi/disks/replicationSuspend": disks.ReplicationSuspendRequest{}, + "/restmachine/cloudapi/disks/resize2": disks.ResizeRequest{}, + "/restmachine/cloudapi/disks/restore": disks.RestoreRequest{}, + "/restmachine/cloudapi/disks/search": disks.SearchRequest{}, + "/restmachine/cloudapi/disks/share": disks.ShareRequest{}, + "/restmachine/cloudapi/disks/snapshotDelete": disks.SnapshotDeleteRequest{}, + "/restmachine/cloudapi/disks/snapshotRollback": disks.SnapshotRollbackRequest{}, + "/restmachine/cloudapi/disks/unshare": disks.UnshareRequest{}, + "/restmachine/cloudapi/disks/replication_manual_sync": disks.ReplicationManualSyncRequest{}, + "/restmachine/cloudapi/disks/replication_set_schedule": disks.ReplicationSetScheduleRequest{}, + "/restmachine/cloudapi/disks/replication_disable_schedule": disks.ReplicationDisableScheduleRequest{}, + "/restmachine/cloudapi/disks/replication_set_copy_rate": disks.ReplicationSetCopyRateRequest{}, + "/restmachine/cloudapi/disks/replication_promote": disks.ReplicationPromoteRequest{}, //dpdknet "/restmachine/cloudapi/dpdknet/get": dpdknet.GetRequest{}, @@ -702,37 +707,42 @@ func getRequestsMapCloudbroker() map[string]interface{} { "/restmachine/cloudbroker/compute/migrate_v2": compute_cb.MigrateV2Request{}, // disks - "/restmachine/cloudbroker/disks/change_disk_storage_policy": disks_cb.ChangeDiskStoragePolicyRequest{}, - "/restmachine/cloudbroker/disks/create": disks_cb.CreateRequest{}, - "/restmachine/cloudbroker/disks/delete": disks_cb.DeleteRequest{}, - "/restmachine/cloudbroker/disks/deleteDisks": disks_cb.DeleteDisksRequest{}, - "/restmachine/cloudbroker/disks/depresent": disks_cb.DepresentRequest{}, - "/restmachine/cloudbroker/disks/fromPlatformDisk": disks_cb.FromPlatformDiskRequest{}, - "/restmachine/cloudbroker/disks/get": disks_cb.GetRequest{}, - "/restmachine/cloudbroker/disks/limitIO": disks_cb.LimitIORequest{}, - "/restmachine/cloudbroker/disks/list": disks_cb.ListRequest{}, - "/restmachine/cloudbroker/disks/listDeleted": disks_cb.ListDeletedRequest{}, - "/restmachine/cloudbroker/disks/listUnattached": disks_cb.ListUnattachedRequest{}, - "/restmachine/cloudbroker/disks/rename": disks_cb.RenameRequest{}, - "/restmachine/cloudbroker/disks/present": disks_cb.PresentRequest{}, - "/restmachine/cloudbroker/disks/replicate": disks_cb.ReplicateRequest{}, - "/restmachine/cloudbroker/disks/replicationResume": disks_cb.ReplicationResumeRequest{}, - "/restmachine/cloudbroker/disks/replicationReverse": disks_cb.ReplicationReverseRequest{}, - "/restmachine/cloudbroker/disks/replicationStart": disks_cb.ReplicationStartRequest{}, - "/restmachine/cloudbroker/disks/replicationStatus": disks_cb.ReplicationStatusRequest{}, - "/restmachine/cloudbroker/disks/replicationStop": disks_cb.ReplicationStopRequest{}, - "/restmachine/cloudbroker/disks/replicationSuspend": disks_cb.ReplicationSuspendRequest{}, - "/restmachine/cloudbroker/disks/resize2": disks_cb.ResizeRequest{}, - "/restmachine/cloudbroker/disks/restore": disks_cb.RestoreRequest{}, - "/restmachine/cloudbroker/disks/search": disks_cb.SearchRequest{}, - "/restmachine/cloudbroker/disks/share": disks_cb.ShareRequest{}, - "/restmachine/cloudbroker/disks/snapshotDelete": disks_cb.SnapshotDeleteRequest{}, - "/restmachine/cloudbroker/disks/snapshotRollback": disks_cb.SnapshotRollbackRequest{}, - "/restmachine/cloudbroker/disks/unshare": disks_cb.UnshareRequest{}, - "/restmachine/cloudbroker/disks/migrate": disks_cb.MigrateRequest{}, - "/restmachine/cloudbroker/disks/migrate_abort": disks_cb.MigrateAbortRequest{}, - "/restmachine/cloudbroker/disks/migrate_status": disks_cb.GetMigrateStatusRequest{}, - "/restmachine/cloudbroker/disks/update": disks_cb.UpdateRequest{}, + "/restmachine/cloudbroker/disks/change_disk_storage_policy": disks_cb.ChangeDiskStoragePolicyRequest{}, + "/restmachine/cloudbroker/disks/create": disks_cb.CreateRequest{}, + "/restmachine/cloudbroker/disks/delete": disks_cb.DeleteRequest{}, + "/restmachine/cloudbroker/disks/deleteDisks": disks_cb.DeleteDisksRequest{}, + "/restmachine/cloudbroker/disks/depresent": disks_cb.DepresentRequest{}, + "/restmachine/cloudbroker/disks/fromPlatformDisk": disks_cb.FromPlatformDiskRequest{}, + "/restmachine/cloudbroker/disks/get": disks_cb.GetRequest{}, + "/restmachine/cloudbroker/disks/limitIO": disks_cb.LimitIORequest{}, + "/restmachine/cloudbroker/disks/list": disks_cb.ListRequest{}, + "/restmachine/cloudbroker/disks/listDeleted": disks_cb.ListDeletedRequest{}, + "/restmachine/cloudbroker/disks/listUnattached": disks_cb.ListUnattachedRequest{}, + "/restmachine/cloudbroker/disks/rename": disks_cb.RenameRequest{}, + "/restmachine/cloudbroker/disks/present": disks_cb.PresentRequest{}, + "/restmachine/cloudbroker/disks/replicate": disks_cb.ReplicateRequest{}, + "/restmachine/cloudbroker/disks/replicationResume": disks_cb.ReplicationResumeRequest{}, + "/restmachine/cloudbroker/disks/replicationReverse": disks_cb.ReplicationReverseRequest{}, + "/restmachine/cloudbroker/disks/replicationStart": disks_cb.ReplicationStartRequest{}, + "/restmachine/cloudbroker/disks/replicationStatus": disks_cb.ReplicationStatusRequest{}, + "/restmachine/cloudbroker/disks/replicationStop": disks_cb.ReplicationStopRequest{}, + "/restmachine/cloudbroker/disks/replicationSuspend": disks_cb.ReplicationSuspendRequest{}, + "/restmachine/cloudbroker/disks/resize2": disks_cb.ResizeRequest{}, + "/restmachine/cloudbroker/disks/restore": disks_cb.RestoreRequest{}, + "/restmachine/cloudbroker/disks/search": disks_cb.SearchRequest{}, + "/restmachine/cloudbroker/disks/share": disks_cb.ShareRequest{}, + "/restmachine/cloudbroker/disks/snapshotDelete": disks_cb.SnapshotDeleteRequest{}, + "/restmachine/cloudbroker/disks/snapshotRollback": disks_cb.SnapshotRollbackRequest{}, + "/restmachine/cloudbroker/disks/unshare": disks_cb.UnshareRequest{}, + "/restmachine/cloudbroker/disks/migrate": disks_cb.MigrateRequest{}, + "/restmachine/cloudbroker/disks/migrate_abort": disks_cb.MigrateAbortRequest{}, + "/restmachine/cloudbroker/disks/migrate_status": disks_cb.GetMigrateStatusRequest{}, + "/restmachine/cloudbroker/disks/update": disks_cb.UpdateRequest{}, + "/restmachine/cloudbroker/disks/replication_sync_now": disks_cb.ReplicationSyncNowRequest{}, + "/restmachine/cloudbroker/disks/replication_enable_schedule": disks_cb.ReplicationEnableScheduleRequest{}, + "/restmachine/cloudbroker/disks/replication_disable_schedule": disks_cb.ReplicationDisableScheduleRequest{}, + "/restmachine/cloudbroker/disks/replication_set_copy_rate": disks_cb.ReplicationSetCopyRateRequest{}, + "/restmachine/cloudbroker/disks/replication_promote": disks_cb.ReplicationPromoteRequest{}, // dpdknet "/restmachine/cloudbroker/dpdknet/get": dpdknet_cb.GetRequest{}, @@ -1113,6 +1123,7 @@ func getRequestsMapCloudbroker() map[string]interface{} { "/restmachine/cloudbroker/vgpu/create": vgpu_cb.CreateRequest{}, "/restmachine/cloudbroker/vgpu/destroy": vgpu_cb.DestroyRequest{}, "/restmachine/cloudbroker/vgpu/list": vgpu_cb.ListRequest{}, + "/restmachine/cloudbroker/vgpu/edit": vgpu_cb.EditRequest{}, // vins "/restmachine/cloudbroker/vins/createInAccount": vins_cb.CreateInAccountRequest{}, @@ -1275,7 +1286,7 @@ func getRequestsMapSDN() map[string]interface{} { // routers "/restmachine/sdn/router/create": routers.CreateRequest{}, - "/restmachine/sdn/router/delete": extnet_sdn.DeleteRequest{}, + "/restmachine/sdn/router/delete": routers.DeleteRequest{}, "/restmachine/sdn/router/gateway_port/create": gwport.CreateRequest{}, "/restmachine/sdn/router/gateway_port/delete": gwport.DeleteRequest{}, "/restmachine/sdn/router/gateway_port/get": gwport.GetRequest{},