Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e2edf53a5 | ||
| 8f8a81eea4 | |||
|
|
d82ae52951 |
84
CHANGELOG.md
84
CHANGELOG.md
@@ -1,4 +1,4 @@
|
|||||||
## Version 14.8.0
|
## Version 14.11.0
|
||||||
|
|
||||||
Методы `Audits` в cloudapi/compute, cloudbroker/compute, cloudapi/account, cloudbroker/account, cloudapi/vins, cloudbroker/vins, cloudapi/rg и cloudbroker/rg стали deprecated и в следующих версиях будут удалены, вместо них необходимо использовать метод `List` в cloudapi/audit и cloudbroker/audit с соответствующими фильтрами
|
Методы `Audits` в cloudapi/compute, cloudbroker/compute, cloudapi/account, cloudbroker/account, cloudapi/vins, cloudbroker/vins, cloudapi/rg и cloudbroker/rg стали deprecated и в следующих версиях будут удалены, вместо них необходимо использовать метод `List` в cloudapi/audit и cloudbroker/audit с соответствующими фильтрами
|
||||||
Методы `AccessGrant`, `AccessGrantToPool`, `AccessRevoke`, `AccessRevokeToPool` в cloudbroker/sep стали deprecated и в следующих версиях будут удалены
|
Методы `AccessGrant`, `AccessGrantToPool`, `AccessRevoke`, `AccessRevokeToPool` в cloudbroker/sep стали deprecated и в следующих версиях будут удалены
|
||||||
@@ -7,88 +7,16 @@
|
|||||||
|
|
||||||
Все методы группы `.SDN()` находятся в альфа-версии.
|
Все методы группы `.SDN()` находятся в альфа-версии.
|
||||||
|
|
||||||
### Добавлено
|
### Изменено
|
||||||
|
|
||||||
#### resource optimizer
|
#### compute
|
||||||
| Идентификатор<br>задачи | Описание |
|
| Идентификатор<br>задачи | Описание |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| BGOS-842 | Опциональные поля `Username`, `Password`, `BroadcastAddr`, `PingAddr`, `SSLSkipVerify` и `Domain` в структуры запросов `DRSCreateRequest` и `DRSUpdateRequest` в `cloudbroker/resource_optimizer` |
|
| BGOS-874 | Поле `StoragePolicyID` с обязательного на опциональное в структуре запроса `RedeployRequest` в cloudapi/compute и cloudbroker/compute |
|
||||||
| BGOS-842 | Обязательное поле `SSOType` в структуры запросов `DRSCreateRequest` и `DRSUpdateRequest` в `cloudbroker/resource_optimizer` |
|
|
||||||
|
|
||||||
#### grid
|
|
||||||
| Идентификатор<br>задачи | Описание |
|
|
||||||
| --- | --- |
|
|
||||||
| BGOS-846 | Вычисляемое поле `BROEnabled` в структуры ответов `RecordGrid` и `ItemGridList` в cloudbroker/grid |
|
|
||||||
|
|
||||||
#### locations
|
|
||||||
| Идентификатор<br>задачи | Описание |
|
|
||||||
| --- | --- |
|
|
||||||
| BGOS-845 | Вычисляемое поле `BROEnabled` в структуру ответа `ItemLocation` в cloudapi/locations |
|
|
||||||
|
|
||||||
#### zone
|
|
||||||
| Идентификатор<br>задачи | Описание |
|
|
||||||
| --- | --- |
|
|
||||||
| BGOS-841 | Вычисляемые поля `PingAddr`, `BroadcastAddr`, `SSLSkipVerify` и `Domain` в структуры ответов `ItemZone` и `RecordZone` в cloudapi/zone и в cloudbroker/zone |
|
|
||||||
| BGOS-844 | Вычисляемое поле `SSOType` в структуры ответов `ItemZone` и `RecordZone` в cloudapi/zone и в cloudbroker/zone |
|
|
||||||
|
|
||||||
#### SDN segments
|
|
||||||
| Идентификатор<br>задачи | Описание |
|
|
||||||
| --- | --- |
|
|
||||||
| BGOS-798 | Опциональное поле `OperationStatus` в структуру запроса `ListRequest` в sdn/segments |
|
|
||||||
| BGOS-798 | Опциональные поля `Type` в структуры запросов `CreateRequest` и `UpdateRequest` в sdn/segments |
|
|
||||||
| BGOS-798 | Метод `GetFAA`, структура запроса `GetFAARequest` и структура ответа `GetFAAResponse` в sdn/segments |
|
|
||||||
| BGOS-798 | Вычисляемые поля `Type` и `L2ConnectionPort` в структуру ответа `SegmentResponse` в sdn/segments |
|
|
||||||
| BGOS-798 | Вычисляемое поле `OperationStatus` в структуры `Status` и `HypervisorStatus`, структуры `L2ConnectionPort` и `L2ExternalNetwork` в sdn/segments |
|
|
||||||
|
|
||||||
#### SDN network object groups
|
|
||||||
| Идентификатор<br>задачи | Описание |
|
|
||||||
| --- | --- |
|
|
||||||
| BGOS-837 | Опциональные поля `Addresses` и `L2ConnectionPortsBindings` в структуру запроса `CreateRequest` в sdn/netobjgroups |
|
|
||||||
| BGOS-837 | Опциональное поле `Addresses` в структуру запроса `UpdateRequest` в sdn/netobjgroups |
|
|
||||||
| BGOS-837 | Поле `PortBindings` и структура `DetachLogicalPortBinding` в структуру запроса `DetachLogicalPortsRequest` в sdn/netobjgroups |
|
|
||||||
| BGOS-837 | Поля `Purpose`, `Type`, `Addresses`, `L2ConnectionPorts` в структуру ответа `RecordNetObjGroup` в sdn/netobjgroups |
|
|
||||||
| BGOS-837 | Поля `AddressesCount`, `L2ConnectionPortsCount` в структуру ответа `Counter` в sdn/netobjgroups |
|
|
||||||
| BGOS-837 | Поля `Type`, `AppliedNetObjectGroups` в структуру ответа `SecurityPolicy` в sdn/netobjgroups |
|
|
||||||
| BGOS-837 | Поля `AccessGroupID`, `Action`, `Direction`, `DisplayName`, `Enabled`, `LogEnabled`, `LogSeverity`, `Priority`, `StatisticsEnabled`, `VersionID`, `Description`, `DestinationNetObject`, `Filter`, `ID`, `LogName`, `SecurityPolicyID`, `SourceNetObject` и `Type` в структуру ответа `SecurityRule` в sdn/netobjgroups |
|
|
||||||
| BGOS-837 | Поля `ExcludeFirewall`, `Labels` в структуру ответа `LogicalPort` в sdn/netobjgroups |
|
|
||||||
| BGOS-837 | Поля `AccessGroupID`, `AccessGroupName` в структуру ответа `ExternalNetworkPort` в sdn/netobjgroups |
|
|
||||||
|
|
||||||
### Исправлено
|
### Исправлено
|
||||||
|
|
||||||
#### SDN access groups
|
#### vfpool
|
||||||
| Идентификатор<br>задачи | Описание |
|
| Идентификатор<br>задачи | Описание |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| BGOS-836 | Тип возвращаемого значения с `bool` на `string` в методе `Delete` в sdn/acsgroups |
|
| BGOS-871 | Тип поля `Config` в структуре запроса `wrapperUpdateRequest` с `[]string` на `string` в cloudbroker/vfpool |
|
||||||
|
|
||||||
#### SDN hypervisors
|
|
||||||
| Идентификатор<br>задачи | Описание |
|
|
||||||
| --- | --- |
|
|
||||||
| BGOS-847 | Тип вычисляемого поля `Ports` с `[]string` на структуру `Ports` в структуре ответа `RecordHypervisor` в sdn/hypervisors |
|
|
||||||
|
|
||||||
#### SDN hetwork object groups
|
|
||||||
| Идентификатор<br>задачи | Описание |
|
|
||||||
| --- | --- |
|
|
||||||
| BGOS-837 | Тип ответа метода `AttachExtNetPorts` с `bool` на `*RecordVersion` в sdn/netobjgroups |
|
|
||||||
| BGOS-837 | Тип ответа метода `AttachLogicalPorts` с `bool` на `*RecordVersion` в sdn/netobjgroups |
|
|
||||||
| BGOS-837 | Поле `Common` на `OperationStatus` в структуре `Status` в sdn/netobjgroups |
|
|
||||||
| BGOS-837 | Поле `Status` на `OperationStatus` в структуре `HypervisorInfo` в sdn/netobjgroups |
|
|
||||||
| BGOS-837 | Тип поля `VersionID` со `string` на `uint64` в структуре `ExternalNetworkPort` в sdn/netobjgroups |
|
|
||||||
| BGOS-837 | Тип поля `VLANTag` со `string` на `int` в структуре `ExternalNetworkPort` в sdn/netobjgroups |
|
|
||||||
|
|
||||||
### Удалено
|
|
||||||
|
|
||||||
#### SDN access groups
|
|
||||||
| Идентификатор<br>задачи | Описание |
|
|
||||||
| --- | --- |
|
|
||||||
| BGOS-836 | Поля `CreatedBy` и `UpdatedBy` в структуре ответа `AccessGroup` в sdn/acsgroups |
|
|
||||||
|
|
||||||
#### SDN segments
|
|
||||||
| Идентификатор<br>задачи | Описание |
|
|
||||||
| --- | --- |
|
|
||||||
| BGOS-798 | Метод `GetStatus` и структура запроса `GetStatusRequest` в sdn/segments |
|
|
||||||
|
|
||||||
#### SDN network object groups
|
|
||||||
| Идентификатор<br>задачи | Описание |
|
|
||||||
| --- | --- |
|
|
||||||
| BGOS-837 | Поле `IsExcludedFromFirewall` из структуры `Bindings` в sdn/netobjgroups |
|
|
||||||
| BGOS-837 | Поле `AppliedToNetObjectGroupID` из структуры `SecurityPolicy` в sdn/netobjgroups |
|
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ go get -u repository.basistech.ru/BASIS/dynamix-golang-sdk/v14
|
|||||||
- `Trunk` - получение информации о транковых портах;
|
- `Trunk` - получение информации о транковых портах;
|
||||||
- `VFPool` - управление пулом виртуальных сетевых функций;
|
- `VFPool` - управление пулом виртуальных сетевых функций;
|
||||||
- `VINS` - управление виртуальными изолированными сетями;
|
- `VINS` - управление виртуальными изолированными сетями;
|
||||||
|
- `VGPU` - управление виртуальными графическими процессорами;
|
||||||
- `Zone` - управление зонами.
|
- `Zone` - управление зонами.
|
||||||
|
|
||||||
### Cloudbroker
|
### Cloudbroker
|
||||||
@@ -151,7 +152,6 @@ go get -u repository.basistech.ru/BASIS/dynamix-golang-sdk/v14
|
|||||||
- `PCIDevice` - управление устройствами;
|
- `PCIDevice` - управление устройствами;
|
||||||
- `Prometheus` - получение статистики prometheus;
|
- `Prometheus` - получение статистики prometheus;
|
||||||
- `Resmon` - получение статистики resource monitoring;
|
- `Resmon` - получение статистики resource monitoring;
|
||||||
- `ResourceOptimizer` - управление инструментом оптимизации ресурсов (DRS);
|
|
||||||
- `RG` - управление ресурсными группами аккаунта;
|
- `RG` - управление ресурсными группами аккаунта;
|
||||||
- `Security group` – управление группами безопасности;
|
- `Security group` – управление группами безопасности;
|
||||||
- `SEP` - управление storage endpoint (sep);
|
- `SEP` - управление storage endpoint (sep);
|
||||||
@@ -336,6 +336,7 @@ func main() {
|
|||||||
- `pkg/cloudapi/trunk` - для `Trunk`
|
- `pkg/cloudapi/trunk` - для `Trunk`
|
||||||
- `pkg/cloudapi/vfpool` - для `VFPool`
|
- `pkg/cloudapi/vfpool` - для `VFPool`
|
||||||
- `pkg/cloudapi/vins` - для `VINS`
|
- `pkg/cloudapi/vins` - для `VINS`
|
||||||
|
- `pkg/cloudapi/vgpu` - для `VGPU`
|
||||||
- `pkg/cloudapi/zone` - для `Zone`
|
- `pkg/cloudapi/zone` - для `Zone`
|
||||||
- **cloudbroker**:
|
- **cloudbroker**:
|
||||||
- `pkg/cloudbroker/account` - для `Account`
|
- `pkg/cloudbroker/account` - для `Account`
|
||||||
@@ -359,7 +360,6 @@ func main() {
|
|||||||
- `pkg/cloudbroker/pcidevice` - для `PCIDevice`
|
- `pkg/cloudbroker/pcidevice` - для `PCIDevice`
|
||||||
- `pkg/cloudbroker/prometheus` - для `Prometheus`
|
- `pkg/cloudbroker/prometheus` - для `Prometheus`
|
||||||
- `pkg/cloudbroker/resmon` - для `Resmon`
|
- `pkg/cloudbroker/resmon` - для `Resmon`
|
||||||
- `pkg/cloudbroker/resource_optimizer` - для `ResourceOptimizer`
|
|
||||||
- `pkg/cloudbroker/rg` - для `RG`
|
- `pkg/cloudbroker/rg` - для `RG`
|
||||||
- `pkg/cloudbroker/secgroup` - для `Security group`
|
- `pkg/cloudbroker/secgroup` - для `Security group`
|
||||||
- `pkg/cloudbroker/sep` - для `SEP`
|
- `pkg/cloudbroker/sep` - для `SEP`
|
||||||
@@ -535,6 +535,7 @@ func main() {
|
|||||||
- `.Trunk()` - для работы с `Trunk`
|
- `.Trunk()` - для работы с `Trunk`
|
||||||
- `.VFPool()` - для работы с `VFPool`
|
- `.VFPool()` - для работы с `VFPool`
|
||||||
- `.VINS()` - для работы с `VINS`
|
- `.VINS()` - для работы с `VINS`
|
||||||
|
- `.VGPU()` - для работы с `VGPU`
|
||||||
- `.Zone()` - для работы с `Zone`
|
- `.Zone()` - для работы с `Zone`
|
||||||
|
|
||||||
Доступные методы для `.CloudBroker()`:
|
Доступные методы для `.CloudBroker()`:
|
||||||
@@ -560,7 +561,6 @@ func main() {
|
|||||||
- `.PCIDevice()` - для работы с `PCIDevice`
|
- `.PCIDevice()` - для работы с `PCIDevice`
|
||||||
- `.Prometheus()` - для работы с `Prometheus`
|
- `.Prometheus()` - для работы с `Prometheus`
|
||||||
- `.Resmon()` - для работы с `Resmon`
|
- `.Resmon()` - для работы с `Resmon`
|
||||||
- `.ResourceOptimizer()` - для работы с `ResourceOptimizer`
|
|
||||||
- `.RG()` - для работы с `RG`
|
- `.RG()` - для работы с `RG`
|
||||||
- `.SecurityGroup()` - для работы с `Security Group`
|
- `.SecurityGroup()` - для работы с `Security Group`
|
||||||
- `.SEP()` - для работы с `SEP`
|
- `.SEP()` - для работы с `SEP`
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ type RedeployRequest struct {
|
|||||||
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
|
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
|
||||||
|
|
||||||
// Storage policy id of compute. The rules of the specified storage policy will be used.
|
// Storage policy id of compute. The rules of the specified storage policy will be used.
|
||||||
// Required: true
|
// Required: false
|
||||||
StoragePolicyID uint64 `url:"storage_policy_id,omitempty" json:"storage_policy_id,omitempty"`
|
StoragePolicyID uint64 `url:"storage_policy_id,omitempty" json:"storage_policy_id,omitempty"`
|
||||||
|
|
||||||
// ID of the new OS image, if image change is required
|
// ID of the new OS image, if image change is required
|
||||||
|
|||||||
8
pkg/cloudapi/vgpu.go
Normal file
8
pkg/cloudapi/vgpu.go
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package cloudapi
|
||||||
|
|
||||||
|
import "repository.basistech.ru/BASIS/dynamix-golang-sdk/v14/pkg/cloudapi/vgpu"
|
||||||
|
|
||||||
|
// Accessing the VGPU method group
|
||||||
|
func (ca *CloudAPI) VGPU() *vgpu.VGPU {
|
||||||
|
return vgpu.New(ca.client)
|
||||||
|
}
|
||||||
10
pkg/cloudapi/vgpu/ids.go
Normal file
10
pkg/cloudapi/vgpu/ids.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package vgpu
|
||||||
|
|
||||||
|
// IDs gets array of VGPU IDs from ListVGPU struct
|
||||||
|
func (l ListVGPU) IDs() []uint64 {
|
||||||
|
res := make([]uint64, 0, len(l.Data))
|
||||||
|
for _, v := range l.Data {
|
||||||
|
res = append(res, v.ID)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
88
pkg/cloudapi/vgpu/list.go
Normal file
88
pkg/cloudapi/vgpu/list.go
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
package vgpu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"repository.basistech.ru/BASIS/dynamix-golang-sdk/v14/internal/validators"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListRequest struct to get list of VGPU
|
||||||
|
type ListRequest struct {
|
||||||
|
// Find by id
|
||||||
|
// Required: false
|
||||||
|
ByID uint64 `url:"by_id,omitempty" json:"by_id,omitempty"`
|
||||||
|
|
||||||
|
// Find by vgpu status
|
||||||
|
// Required: false
|
||||||
|
Status string `url:"status,omitempty" json:"status,omitempty"`
|
||||||
|
|
||||||
|
// Find by vgpu type
|
||||||
|
// Required: false
|
||||||
|
Type string `url:"type,omitempty" json:"type,omitempty"`
|
||||||
|
|
||||||
|
// Find by vgpu mode
|
||||||
|
// Required: false
|
||||||
|
Mode string `url:"mode,omitempty" json:"mode,omitempty"`
|
||||||
|
|
||||||
|
// Find by id resgroup
|
||||||
|
// Required: false
|
||||||
|
RGID uint64 `url:"rgId,omitempty" json:"rgId,omitempty"`
|
||||||
|
|
||||||
|
// Find by account id
|
||||||
|
// Required: false
|
||||||
|
AccountID uint64 `url:"accountId,omitempty" json:"accountId,omitempty"`
|
||||||
|
|
||||||
|
// Find by compute id
|
||||||
|
// Required: false
|
||||||
|
ComputeID uint64 `url:"computeId,omitempty" json:"computeId,omitempty"`
|
||||||
|
|
||||||
|
// Find by pgpu id
|
||||||
|
// Required: false
|
||||||
|
PGPUID uint64 `url:"pgpuId,omitempty" json:"pgpuId,omitempty"`
|
||||||
|
|
||||||
|
// Sort by one of supported fields, format +|-(field)
|
||||||
|
// Required: false
|
||||||
|
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||||
|
|
||||||
|
// Page number
|
||||||
|
// Required: false
|
||||||
|
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||||
|
|
||||||
|
// Page size
|
||||||
|
// Required: false
|
||||||
|
Size uint64 `url:"size,omitempty" json:"size,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// List gets list of all VGPU as a ListVGPU struct
|
||||||
|
func (v VGPU) List(ctx context.Context, req ListRequest) (*ListVGPU, error) {
|
||||||
|
|
||||||
|
res, err := v.ListRaw(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
list := ListVGPU{}
|
||||||
|
|
||||||
|
err = json.Unmarshal(res, &list)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &list, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRaw gets list of all VGPU as an array of bytes
|
||||||
|
func (v VGPU) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
|
||||||
|
|
||||||
|
err := validators.ValidateRequest(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
url := "/cloudapi/vgpu/list"
|
||||||
|
|
||||||
|
res, err := v.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
69
pkg/cloudapi/vgpu/models.go
Normal file
69
pkg/cloudapi/vgpu/models.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package vgpu
|
||||||
|
|
||||||
|
type ItemVGPU struct {
|
||||||
|
// Account ID
|
||||||
|
AccountID uint64 `json:"accountId"`
|
||||||
|
|
||||||
|
// Created time
|
||||||
|
CreatedTime uint64 `json:"createdTime"`
|
||||||
|
|
||||||
|
// Deleted time
|
||||||
|
DeletedTime uint64 `json:"deletedTime"`
|
||||||
|
|
||||||
|
//Grid ID
|
||||||
|
GID uint64 `json:"gid"`
|
||||||
|
|
||||||
|
// GUID
|
||||||
|
GUID uint64 `json:"guid"`
|
||||||
|
|
||||||
|
// VGPU ID
|
||||||
|
ID uint64 `json:"id"`
|
||||||
|
|
||||||
|
// Last claimed by
|
||||||
|
LastClaimedBy uint64 `json:"lastClaimedBy"`
|
||||||
|
|
||||||
|
// Last update time
|
||||||
|
LastUpdateTime uint64 `json:"lastUpdateTime"`
|
||||||
|
|
||||||
|
// Mode
|
||||||
|
Mode string `json:"mode"`
|
||||||
|
|
||||||
|
// Bus number
|
||||||
|
BusNumber int `json:"bus_number"`
|
||||||
|
|
||||||
|
// PCI Slot
|
||||||
|
PCISlot int `json:"pciSlot"`
|
||||||
|
|
||||||
|
// PGPUID
|
||||||
|
PGPUID uint64 `json:"pgpuid"`
|
||||||
|
|
||||||
|
// Profile ID
|
||||||
|
ProfileID uint64 `json:"profileId"`
|
||||||
|
|
||||||
|
// RAM
|
||||||
|
RAM uint64 `json:"ram"`
|
||||||
|
|
||||||
|
// Reference ID
|
||||||
|
ReferenceID string `json:"referenceId"`
|
||||||
|
|
||||||
|
// RGID
|
||||||
|
RGID uint64 `json:"rgId"`
|
||||||
|
|
||||||
|
// Status
|
||||||
|
Status string `json:"status"`
|
||||||
|
|
||||||
|
// Type
|
||||||
|
Type string `json:"type"`
|
||||||
|
|
||||||
|
// VMID
|
||||||
|
VMID uint64 `json:"vmid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// List of VGPU
|
||||||
|
type ListVGPU struct {
|
||||||
|
// Data
|
||||||
|
Data []ItemVGPU `json:"data"`
|
||||||
|
|
||||||
|
// Entry count
|
||||||
|
EntryCount uint64 `json:"entryCount"`
|
||||||
|
}
|
||||||
43
pkg/cloudapi/vgpu/serialize.go
Normal file
43
pkg/cloudapi/vgpu/serialize.go
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package vgpu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"repository.basistech.ru/BASIS/dynamix-golang-sdk/v14/internal/serialization"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Serialize returns JSON-serialized []byte. Used as a wrapper over json.Marshal and json.MarshalIndent functions.
|
||||||
|
//
|
||||||
|
// In order to serialize with indent make sure to follow these guidelines:
|
||||||
|
// - First argument -> prefix
|
||||||
|
// - Second argument -> indent
|
||||||
|
func (l ListVGPU) Serialize(params ...string) (serialization.Serialized, error) {
|
||||||
|
if len(l.Data) == 0 {
|
||||||
|
return []byte{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(params) > 1 {
|
||||||
|
prefix := params[0]
|
||||||
|
indent := params[1]
|
||||||
|
|
||||||
|
return json.MarshalIndent(l, prefix, indent)
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.Marshal(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serialize returns JSON-serialized []byte. Used as a wrapper over json.Marshal and json.MarshalIndent functions.
|
||||||
|
//
|
||||||
|
// In order to serialize with indent make sure to follow these guidelines:
|
||||||
|
// - First argument -> prefix
|
||||||
|
// - Second argument -> indent
|
||||||
|
func (i ItemVGPU) Serialize(params ...string) (serialization.Serialized, error) {
|
||||||
|
if len(params) > 1 {
|
||||||
|
prefix := params[0]
|
||||||
|
indent := params[1]
|
||||||
|
|
||||||
|
return json.MarshalIndent(i, prefix, indent)
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.Marshal(i)
|
||||||
|
}
|
||||||
15
pkg/cloudapi/vgpu/vgpu.go
Normal file
15
pkg/cloudapi/vgpu/vgpu.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package vgpu
|
||||||
|
|
||||||
|
import "repository.basistech.ru/BASIS/dynamix-golang-sdk/v14/interfaces"
|
||||||
|
|
||||||
|
// Structure for creating request to VGPU
|
||||||
|
type VGPU struct {
|
||||||
|
client interfaces.Caller
|
||||||
|
}
|
||||||
|
|
||||||
|
// Builder for VGPU endpoints
|
||||||
|
func New(client interfaces.Caller) *VGPU {
|
||||||
|
return &VGPU{
|
||||||
|
client: client,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ type RedeployRequest struct {
|
|||||||
OSVersion string `url:"os_version,omitempty" json:"os_version,omitempty"`
|
OSVersion string `url:"os_version,omitempty" json:"os_version,omitempty"`
|
||||||
|
|
||||||
// Storage policy id of compute. The rules of the specified storage policy will be used.
|
// Storage policy id of compute. The rules of the specified storage policy will be used.
|
||||||
// Required: true
|
// Required: false
|
||||||
StoragePolicyID uint64 `url:"storage_policy_id,omitempty" json:"storage_policy_id,omitempty"`
|
StoragePolicyID uint64 `url:"storage_policy_id,omitempty" json:"storage_policy_id,omitempty"`
|
||||||
|
|
||||||
// New size for the boot disk in GB, if boot disk size change is required
|
// New size for the boot disk in GB, if boot disk size change is required
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
package cloudbroker
|
|
||||||
|
|
||||||
import (
|
|
||||||
"repository.basistech.ru/BASIS/dynamix-golang-sdk/v14/pkg/cloudbroker/resource_optimizer"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Accessing the ResourceOptimizer method group
|
|
||||||
func (cb *CloudBroker) ResourceOptimizer() *resource_optimizer.ResourceOptimizer {
|
|
||||||
return resource_optimizer.New(cb.client)
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package resource_optimizer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"repository.basistech.ru/BASIS/dynamix-golang-sdk/v14/internal/validators"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DRSAddNodesRequest struct to add nodes to DRS
|
|
||||||
type DRSAddNodesRequest struct {
|
|
||||||
// ID of the zone
|
|
||||||
// Required: true
|
|
||||||
ZoneID uint64 `url:"zone_id" json:"zone_id" validate:"required"`
|
|
||||||
|
|
||||||
// IDs of the nodes to add
|
|
||||||
// Required: true
|
|
||||||
NodeIDs []uint64 `url:"node_ids" json:"node_ids" validate:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DRSAddNodes adds nodes to DRS in the specified zone
|
|
||||||
func (ro ResourceOptimizer) DRSAddNodes(ctx context.Context, req DRSAddNodesRequest) (bool, error) {
|
|
||||||
err := validators.ValidateRequest(req)
|
|
||||||
if err != nil {
|
|
||||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
url := "/cloudbroker/resource_optimizer/drs_add_nodes"
|
|
||||||
|
|
||||||
res, err := ro.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
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
package resource_optimizer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"repository.basistech.ru/BASIS/dynamix-golang-sdk/v14/internal/validators"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DRSCreateRequest struct to create DRS
|
|
||||||
type DRSCreateRequest struct {
|
|
||||||
// ID of the zone
|
|
||||||
// Required: true
|
|
||||||
ZoneID uint64 `url:"zone_id" json:"zone_id" validate:"required"`
|
|
||||||
|
|
||||||
// SSO provider type
|
|
||||||
// Available values: bvs, decs3o
|
|
||||||
// Required: true
|
|
||||||
SSOType string `url:"sso_type" json:"sso_type" validate:"required,oneof=bvs decs3o"`
|
|
||||||
|
|
||||||
// Application ID
|
|
||||||
// Required: true
|
|
||||||
AppID string `url:"app_id" json:"app_id" validate:"required"`
|
|
||||||
|
|
||||||
// Application secret
|
|
||||||
// Required: true
|
|
||||||
AppSecret string `url:"app_secret" json:"app_secret" validate:"required"`
|
|
||||||
|
|
||||||
// Decort URL
|
|
||||||
// Required: true
|
|
||||||
DecortURL string `url:"decort_url" json:"decort_url" validate:"required"`
|
|
||||||
|
|
||||||
// SSO URL
|
|
||||||
// Required: true
|
|
||||||
SSOURL string `url:"sso_url" json:"sso_url" validate:"required"`
|
|
||||||
|
|
||||||
// DRS name
|
|
||||||
// Required: true
|
|
||||||
DRSName string `url:"drs_name" json:"drs_name" validate:"required"`
|
|
||||||
|
|
||||||
// Username
|
|
||||||
// Required: false
|
|
||||||
Username string `url:"username,omitempty" json:"username,omitempty"`
|
|
||||||
|
|
||||||
// Password
|
|
||||||
// Required: false
|
|
||||||
Password string `url:"password,omitempty" json:"password,omitempty"`
|
|
||||||
|
|
||||||
// Broadcast address
|
|
||||||
// Required: false
|
|
||||||
BroadcastAddr string `url:"broadcast_addr,omitempty" json:"broadcast_addr,omitempty"`
|
|
||||||
|
|
||||||
// Ping address
|
|
||||||
// Required: false
|
|
||||||
PingAddr string `url:"ping_addr,omitempty" json:"ping_addr,omitempty"`
|
|
||||||
|
|
||||||
// Skip SSL certificate verification
|
|
||||||
// Required: false
|
|
||||||
SSLSkipVerify interface{} `url:"ssl_skip_verify,omitempty" json:"ssl_skip_verify,omitempty"`
|
|
||||||
|
|
||||||
// Domain
|
|
||||||
// Required: false
|
|
||||||
Domain string `url:"domain,omitempty" json:"domain,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DRSCreate creates a new DRS in the specified zone
|
|
||||||
func (ro ResourceOptimizer) DRSCreate(ctx context.Context, req DRSCreateRequest) (bool, error) {
|
|
||||||
err := validators.ValidateRequest(req)
|
|
||||||
if err != nil {
|
|
||||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
url := "/cloudbroker/resource_optimizer/drs_create"
|
|
||||||
|
|
||||||
res, err := ro.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
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package resource_optimizer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"repository.basistech.ru/BASIS/dynamix-golang-sdk/v14/internal/validators"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DRSDelNodesRequest struct to delete nodes from DRS
|
|
||||||
type DRSDelNodesRequest struct {
|
|
||||||
// ID of the zone
|
|
||||||
// Required: true
|
|
||||||
ZoneID uint64 `url:"zone_id" json:"zone_id" validate:"required"`
|
|
||||||
|
|
||||||
// IDs of the nodes to delete
|
|
||||||
// Required: true
|
|
||||||
NodeIDs []uint64 `url:"node_ids" json:"node_ids" validate:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DRSDelNodes removes nodes from DRS in the specified zone
|
|
||||||
func (ro ResourceOptimizer) DRSDelNodes(ctx context.Context, req DRSDelNodesRequest) (bool, error) {
|
|
||||||
err := validators.ValidateRequest(req)
|
|
||||||
if err != nil {
|
|
||||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
url := "/cloudbroker/resource_optimizer/drs_del_nodes"
|
|
||||||
|
|
||||||
res, err := ro.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
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package resource_optimizer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"repository.basistech.ru/BASIS/dynamix-golang-sdk/v14/internal/validators"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DRSRemoveRequest struct to remove DRS
|
|
||||||
type DRSRemoveRequest struct {
|
|
||||||
// ID of the zone
|
|
||||||
// Required: true
|
|
||||||
ZoneID uint64 `url:"zone_id" json:"zone_id" validate:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DRSRemove removes DRS from the specified zone
|
|
||||||
func (ro ResourceOptimizer) DRSRemove(ctx context.Context, req DRSRemoveRequest) (bool, error) {
|
|
||||||
err := validators.ValidateRequest(req)
|
|
||||||
if err != nil {
|
|
||||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
url := "/cloudbroker/resource_optimizer/drs_remove"
|
|
||||||
|
|
||||||
res, err := ro.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
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package resource_optimizer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"repository.basistech.ru/BASIS/dynamix-golang-sdk/v14/internal/validators"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DRSStartRequest struct to start DRS
|
|
||||||
type DRSStartRequest struct {
|
|
||||||
// ID of the zone
|
|
||||||
// Required: true
|
|
||||||
ZoneID uint64 `url:"zone_id" json:"zone_id" validate:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DRSStart starts DRS in the specified zone
|
|
||||||
func (ro ResourceOptimizer) DRSStart(ctx context.Context, req DRSStartRequest) (bool, error) {
|
|
||||||
err := validators.ValidateRequest(req)
|
|
||||||
if err != nil {
|
|
||||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
url := "/cloudbroker/resource_optimizer/drs_start"
|
|
||||||
|
|
||||||
res, err := ro.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
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package resource_optimizer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"repository.basistech.ru/BASIS/dynamix-golang-sdk/v14/internal/validators"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DRSStopRequest struct to stop DRS
|
|
||||||
type DRSStopRequest struct {
|
|
||||||
// ID of the zone
|
|
||||||
// Required: true
|
|
||||||
ZoneID uint64 `url:"zone_id" json:"zone_id" validate:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DRSStop stops DRS in the specified zone
|
|
||||||
func (ro ResourceOptimizer) DRSStop(ctx context.Context, req DRSStopRequest) (bool, error) {
|
|
||||||
err := validators.ValidateRequest(req)
|
|
||||||
if err != nil {
|
|
||||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
url := "/cloudbroker/resource_optimizer/drs_stop"
|
|
||||||
|
|
||||||
res, err := ro.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
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
package resource_optimizer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"repository.basistech.ru/BASIS/dynamix-golang-sdk/v14/internal/validators"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DRSUpdateRequest struct to update DRS
|
|
||||||
type DRSUpdateRequest struct {
|
|
||||||
// ID of the zone
|
|
||||||
// Required: true
|
|
||||||
ZoneID uint64 `url:"zone_id" json:"zone_id" validate:"required"`
|
|
||||||
|
|
||||||
// SSO provider type
|
|
||||||
// Available values: bvs, decs3o
|
|
||||||
// Required: true
|
|
||||||
SSOType string `url:"sso_type" json:"sso_type" validate:"required,oneof=bvs decs3o"`
|
|
||||||
|
|
||||||
// Application ID
|
|
||||||
// Required: false
|
|
||||||
AppID string `url:"app_id,omitempty" json:"app_id,omitempty"`
|
|
||||||
|
|
||||||
// Application secret
|
|
||||||
// Required: false
|
|
||||||
AppSecret string `url:"app_secret,omitempty" json:"app_secret,omitempty"`
|
|
||||||
|
|
||||||
// Decort URL
|
|
||||||
// Required: false
|
|
||||||
DecortURL string `url:"decort_url,omitempty" json:"decort_url,omitempty"`
|
|
||||||
|
|
||||||
// SSO URL
|
|
||||||
// Required: false
|
|
||||||
SSOURL string `url:"sso_url,omitempty" json:"sso_url,omitempty"`
|
|
||||||
|
|
||||||
// DRS name
|
|
||||||
// Required: false
|
|
||||||
DRSName string `url:"drs_name,omitempty" json:"drs_name,omitempty"`
|
|
||||||
|
|
||||||
// Username
|
|
||||||
// Required: false
|
|
||||||
Username string `url:"username,omitempty" json:"username,omitempty"`
|
|
||||||
|
|
||||||
// Password
|
|
||||||
// Required: false
|
|
||||||
Password string `url:"password,omitempty" json:"password,omitempty"`
|
|
||||||
|
|
||||||
// Broadcast address
|
|
||||||
// Required: false
|
|
||||||
BroadcastAddr string `url:"broadcast_addr,omitempty" json:"broadcast_addr,omitempty"`
|
|
||||||
|
|
||||||
// Ping address
|
|
||||||
// Required: false
|
|
||||||
PingAddr string `url:"ping_addr,omitempty" json:"ping_addr,omitempty"`
|
|
||||||
|
|
||||||
// Skip SSL certificate verification
|
|
||||||
// Required: false
|
|
||||||
SSLSkipVerify interface{} `url:"ssl_skip_verify,omitempty" json:"ssl_skip_verify,omitempty"`
|
|
||||||
|
|
||||||
// Domain
|
|
||||||
// Required: false
|
|
||||||
Domain string `url:"domain,omitempty" json:"domain,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DRSUpdate updates DRS configuration in the specified zone
|
|
||||||
func (ro ResourceOptimizer) DRSUpdate(ctx context.Context, req DRSUpdateRequest) (bool, error) {
|
|
||||||
err := validators.ValidateRequest(req)
|
|
||||||
if err != nil {
|
|
||||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
url := "/cloudbroker/resource_optimizer/drs_update"
|
|
||||||
|
|
||||||
res, err := ro.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
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
// API Actor API for managing resource optimizer
|
|
||||||
package resource_optimizer
|
|
||||||
|
|
||||||
import "repository.basistech.ru/BASIS/dynamix-golang-sdk/v14/interfaces"
|
|
||||||
|
|
||||||
// Structure for creating request to resource_optimizer
|
|
||||||
type ResourceOptimizer struct {
|
|
||||||
client interfaces.Caller
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builder for resource_optimizer endpoints
|
|
||||||
func New(client interfaces.Caller) *ResourceOptimizer {
|
|
||||||
return &ResourceOptimizer{
|
|
||||||
client: client,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -38,7 +38,7 @@ type UpdateRequest struct {
|
|||||||
|
|
||||||
type wrapperUpdateRequest struct {
|
type wrapperUpdateRequest struct {
|
||||||
UpdateRequest
|
UpdateRequest
|
||||||
Config []string `url:"config,omitempty"`
|
Config string `url:"config,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update updates vfpool device
|
// Update updates vfpool device
|
||||||
@@ -48,21 +48,15 @@ func (v VFPool) Update(ctx context.Context, req UpdateRequest) (bool, error) {
|
|||||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
var config []string
|
var config string
|
||||||
|
|
||||||
if len(req.Config) != 0 {
|
if len(req.Config) != 0 {
|
||||||
config = make([]string, 0, len(req.Config))
|
b, err := json.Marshal(req.Config)
|
||||||
|
if err != nil {
|
||||||
for c := range req.Config {
|
return false, err
|
||||||
b, err := json.Marshal(req.Config[c])
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
config = append(config, string(b))
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
config = []string{}
|
config = string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
reqWrapped := wrapperUpdateRequest{
|
reqWrapped := wrapperUpdateRequest{
|
||||||
|
|||||||
@@ -11,21 +11,18 @@ var testAccessGroups = AccessGroupList{
|
|||||||
DisplayName: "Developers",
|
DisplayName: "Developers",
|
||||||
Comment: "First group",
|
Comment: "First group",
|
||||||
CreatedAt: "2023-01-01",
|
CreatedAt: "2023-01-01",
|
||||||
CreatedBy: "admin",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "group2",
|
ID: "group2",
|
||||||
DisplayName: "Admins",
|
DisplayName: "Admins",
|
||||||
Comment: "Second group",
|
Comment: "Second group",
|
||||||
CreatedAt: "2023-01-02",
|
CreatedAt: "2023-01-02",
|
||||||
CreatedBy: "admin",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "group3",
|
ID: "group3",
|
||||||
DisplayName: "Users",
|
DisplayName: "Users",
|
||||||
Comment: "Third group",
|
Comment: "Third group",
|
||||||
CreatedAt: "2023-01-03",
|
CreatedAt: "2023-01-03",
|
||||||
CreatedBy: "admin",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user