Compare commits

...

1 Commits

Author SHA1 Message Date
bb90a2d511 v1.13.3 2025-12-29 14:16:28 +03:00
10 changed files with 99 additions and 64 deletions

View File

@@ -1,4 +1,4 @@
## Version 1.13.2
## Version 1.13.3
Методы `Audits` в cloudapi/compute, cloudbroker/compute, cloudapi/account, cloudbroker/account, cloudapi/vins, cloudbroker/vins, cloudapi/rg и cloudbroker/rg стали deprecated и в следующих версиях будут удалены, вместо них необходимо использовать метод `List` в cloudapi/audit и cloudbroker/audit с соответствующими фильтрами
Метод `ListNodes` в cloudbroker/image стал deprecated и в следующих версиях будет удалён
@@ -9,49 +9,38 @@
### Добавлено
#### audit
| Идентификатор<br>задачи | Описание |
| --- | ---|
| BGOS-706 | Поля `ResgroupID`, `AccountID`, `ComputeID` в структуру ответа `RecordAudit` в cloudbroker/audit |
#### compute
| Идентификатор<br>задачи | Описание |
| --- | --- |
| BGOS-703 | Опциональное поле `NetMask` в структуру запроса `NetAttachRequest` в cloudbroker/compute |
| BGOS-704 | Поле `SepID` в структуру ответа `InfoDisk` в cloudapi/compute и cloudbroker/compute |
#### kvmx86
| Идентификатор<br>задачи | Описание |
| --- | --- |
| BGOS-703 | Опциональное поле `NetMask` в структуры запросов `Interface` в cloudapi/kvmx86 и cloudbroker/kvmx86 |
| BGOS-713 | Опциональное поле `NetMap` в структуру запроса `StartMigrationOutRequest` в cloudbroker/compute |
#### sep
| Идентификатор<br>задачи | Описание |
| --- | ---|
| BGOS-704 | Опциональное поле `SepIDs` в структуре запроса `ListRequest` в cloudbroker/sep |
#### storage policy
| Идентификатор<br>задачи | Описание |
| --- | ---|
| BGOS-708 | Поле `SepTechStatus` в структуру запроса `ListRequest` в cloudapi/stpolicy и в cloudbroker/stpolicy |
| BGOS-710 | Обязательное поле `AccessSEPsPool` в структуру запроса `UpdateRequest` в cloudbroker/stpolicy |
#### trunk
| Идентификатор<br>задачи | Описание |
| --- | ---|
| BGOS-705 | Поле `MTU` в структуру ответа `ItemTrunk` в cloudapi/trunk и в cloudbroker/trunk |
| BGOS-705 | Опциональное поле `MTU` в структуры запроса`CreateRequest` и `UpdateRequest` в cloudbroker/trunk |
| --- | --- |
| BGOS-712 | Возвращаемый тип методов `AddConsumerNodes` и `AddProviderNodes` изменен с `bool` на `uint64` в cloudbroker/sep |
| BGOS-722 | Валидатор для поля `SEPType` в структуре запроса `CreateRequest` в cloudbroker/sep |
### Изменено
#### compute
| Идентификатор<br>задачи | Описание |
| --- | --- |
| BGOS-707 | Поле `Value` стало обязательным в структурах запроса `AntiAffinityRuleAddRequest`, `AntiAffinityRuleRemoveRequest`, `AffinityRuleAddRequest` и `AffinityRuleRemoveRequest` в cloudapi/compute и в cloudbroker/compute |
| BGOS-707 | Тип поля `StoragePolicyID` изменен с обязательного на опциональный в структуре запроса`CloneRequest` в cloudbroker/compute |
| BGOS-707 | Тип поля `ComputeID` с `uint64` на `string` в структуре запроса `GetCloneStatusRequest` в cloudbroker/compute |
| BGOS-721 | Тип поля `StoragePolicyID` изменен с опционального на обязательный в структуре запроса `CloneRequest` cloudbroker/compute |
#### node
#### grid
| Идентификатор<br>задачи | Описание |
| --- | --- |
| BGOS-709 | Поле `VFNum` заменено на поле `FNID` в структуре `VFParam` в структуре запроса `SetVFsParamsRequest` в cloudbroker/node |
| BGOS-719 | Поле `Age` в структуре запроса `PurgeLogsRequest` стало необязательным в cloudbroker/grid |
#### storage policy
| Идентификатор<br>задачи | Описание |
| --- | --- |
| BGOS-720 | Тип поля `AccessSEPsPools` изменен с обязательного на опциональный в структуре запроса `UpdateRequest` в cloudbroker/stpolicy |
### Удалено
#### sep
| Идентификатор<br>задачи | Описание |
| --- | --- |
| BGOS-712 | Поля `ProviderNIDs` и `ConsumerNIDs` удалены из структуры запроса `CreateRequest` в cloudbroker/sep |

View File

@@ -66,7 +66,7 @@ var (
loaderTypeValues = []string{"linux", "windows", "unknown"}
sepTypeValues = []string{"hitachi", "dorado", "tatlin", "shared", "local", "des"}
sepTypeValues = []string{"hitachi", "dorado", "tatlin", "shared", "local", "des", "ustor"}
languageValues = []string{"ru", "en"}

View File

@@ -19,8 +19,8 @@ type CloneRequest struct {
Name string `url:"name" json:"name" validate:"required"`
// ID of the Storage Policy
// Required: false
StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id"`
// Required: true
StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
// Timestamp of the parent's snapshot to create clone from
// Required: false

View File

@@ -33,7 +33,11 @@ type StartMigrationOutRequest struct {
// Mapping of guest disk target names to absolute paths on the destination host.
// Required: false
Diskmap map[string]string `url:"diskmap,omitempty" json:"diskmap,omitempty"`
DiskMap map[string]string `url:"diskmap,omitempty" json:"diskmap,omitempty"`
// Mapping of network interfaces
// Required: false
NetMap map[string]string `url:"netmap,omitempty" json:"netmap,omitempty"`
// Mapping for CD/DVD devices or their source paths to new ISO/device paths on the destination
// Required: false

View File

@@ -15,8 +15,8 @@ type PurgeLogsRequest struct {
GID uint64 `url:"gid" json:"gid" validate:"required"`
// Age of the records to remove, e.g. -1h for records older than 1 hour, -1w - one week, etc
// Required: true
Age string `url:"age" json:"age" validate:"required"`
// Required: false
Age string `url:"age,omitempty" json:"age,omitempty"`
}
// PurgeLogs clear Log and ECO records that are older than the specified age.

View File

@@ -20,22 +20,22 @@ type AddConsumerNodesRequest struct {
}
// AddConsumerNodes adds consumer nodes to SEP parameters
func (s SEP) AddConsumerNodes(ctx context.Context, req AddConsumerNodesRequest) (bool, error) {
func (s SEP) AddConsumerNodes(ctx context.Context, req AddConsumerNodesRequest) (uint64, error) {
err := validators.ValidateRequest(req)
if err != nil {
return false, validators.ValidationErrors(validators.GetErrors(err))
return 0, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudbroker/sep/addConsumerNodes"
res, err := s.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return false, err
return 0, err
}
result, err := strconv.ParseBool(string(res))
result, err := strconv.ParseUint(string(res), 10, 64)
if err != nil {
return false, err
return 0, err
}
return result, nil

View File

@@ -20,22 +20,22 @@ type AddProviderNodesRequest struct {
}
// AddProviderNodes adds provider nodes to SEP parameters
func (s SEP) AddProviderNodes(ctx context.Context, req AddProviderNodesRequest) (bool, error) {
func (s SEP) AddProviderNodes(ctx context.Context, req AddProviderNodesRequest) (uint64, error) {
err := validators.ValidateRequest(req)
if err != nil {
return false, validators.ValidationErrors(validators.GetErrors(err))
return 0, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/cloudbroker/sep/addProviderNodes"
res, err := s.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return false, err
return 0, err
}
result, err := strconv.ParseBool(string(res))
result, err := strconv.ParseUint(string(res), 10, 64)
if err != nil {
return false, err
return 0, err
}
return result, nil

View File

@@ -20,7 +20,7 @@ type CreateRequest struct {
// Type of storage
// Required: true
SEPType string `url:"sep_type" json:"sep_type" validate:"required"`
SEPType string `url:"sep_type" json:"sep_type" validate:"required,sepType"`
// SEP config
// Required: true
@@ -30,14 +30,6 @@ type CreateRequest struct {
// Required: false
Description string `url:"description,omitempty" json:"description,omitempty"`
// List of provider node IDs
// Required: false
ProviderNIDs []uint64 `url:"provider_nids,omitempty" json:"provider_nids,omitempty"`
// List of consumer node IDs
// Required: false
ConsumerNIDs []uint64 `url:"consumer_nids,omitempty" json:"consumer_nids,omitempty"`
// Enable SEP after creation
// Required: false
Enable bool `url:"enable,omitempty" json:"enable,omitempty"`

View File

@@ -15,8 +15,8 @@ type UpdateRequest struct {
StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
// List of storage endpoint access objects
// Required: true
AccessSEPsPools []AccessSEPsPool `url:"access_seps_pools" json:"access_seps_pools" validate:"required"`
// Required: false
AccessSEPsPools []AccessSEPsPool `url:"access_seps_pools,omitempty" json:"access_seps_pools,omitempty"`
// New name for the storage policy
// Required: false

View File

@@ -9,6 +9,31 @@ import (
"testing"
)
// extractTypeFromSchema extracts type from schema, handling oneOf cases
// When oneOf contains a type and null, it returns the non-null type
func extractTypeFromSchema(schema map[string]interface{}) string {
// Check for direct type
if paramType, ok := schema["type"].(string); ok {
return paramType
}
// Check for oneOf
if oneOf, ok := schema["oneOf"].([]interface{}); ok {
for _, item := range oneOf {
if itemMap, ok := item.(map[string]interface{}); ok {
if itemType, ok := itemMap["type"].(string); ok {
// Skip null type, return the first non-null type found
if itemType != "null" {
return itemType
}
}
}
}
}
return ""
}
func getParameters(input map[string]interface{}) []interface{} {
var emptySlice []interface{}
methods := []string{"get", "post", "put", "delete", "patch", "head", "options"}
@@ -35,7 +60,6 @@ func getParameters(input map[string]interface{}) []interface{} {
var result []interface{}
//Check for requestBody
if requestBody, ok := parameters["requestBody"].(map[string]interface{}); ok {
if content, ok := requestBody["content"].(map[string]interface{}); ok {
// Check for application/x-www-form-urlencoded, application/json, or multipart/form-data
@@ -76,13 +100,27 @@ func getParameters(input map[string]interface{}) []interface{} {
}
newParam := make(map[string]interface{})
newParam["name"] = name
if propType, ok := propMap["type"].(string); ok {
propType := extractTypeFromSchema(propMap)
if propType != "" {
newParam["type"] = propType
}
newParam["required"] = requiredFields[name]
if propType, ok := propMap["type"].(string); ok && propType == "array" {
if propType == "array" {
// Try to get items from propMap first
if items, ok := propMap["items"].(map[string]interface{}); ok {
newParam["items"] = items
} else if oneOf, ok := propMap["oneOf"].([]interface{}); ok {
// If items not in propMap, try to get from oneOf array element
for _, item := range oneOf {
if itemMap, ok := item.(map[string]interface{}); ok {
if itemType, ok := itemMap["type"].(string); ok && itemType == "array" {
if items, ok := itemMap["items"].(map[string]interface{}); ok {
newParam["items"] = items
break
}
}
}
}
}
}
result = append(result, newParam)
@@ -104,12 +142,24 @@ func getParameters(input map[string]interface{}) []interface{} {
newParam["name"] = name
}
if schema, ok := param["schema"].(map[string]interface{}); ok {
if paramType, ok := schema["type"].(string); ok {
paramType := extractTypeFromSchema(schema)
if paramType != "" {
newParam["type"] = paramType
}
if paramType, ok := schema["type"].(string); ok && paramType == "array" {
if paramType == "array" {
if items, ok := schema["items"].(map[string]interface{}); ok {
newParam["items"] = items
} else if oneOf, ok := schema["oneOf"].([]interface{}); ok {
for _, item := range oneOf {
if itemMap, ok := item.(map[string]interface{}); ok {
if itemType, ok := itemMap["type"].(string); ok && itemType == "array" {
if items, ok := itemMap["items"].(map[string]interface{}); ok {
newParam["items"] = items
break
}
}
}
}
}
}
}