diff --git a/CHANGELOG.md b/CHANGELOG.md index c201b9c..d1b215c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 -| Идентификатор
задачи | Описание | -| --- | ---| -| BGOS-706 | Поля `ResgroupID`, `AccountID`, `ComputeID` в структуру ответа `RecordAudit` в cloudbroker/audit | - #### compute | Идентификатор
задачи | Описание | | --- | --- | -| BGOS-703 | Опциональное поле `NetMask` в структуру запроса `NetAttachRequest` в cloudbroker/compute | -| BGOS-704 | Поле `SepID` в структуру ответа `InfoDisk` в cloudapi/compute и cloudbroker/compute | - -#### kvmx86 -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-703 | Опциональное поле `NetMask` в структуры запросов `Interface` в cloudapi/kvmx86 и cloudbroker/kvmx86 | +| BGOS-713 | Опциональное поле `NetMap` в структуру запроса `StartMigrationOutRequest` в cloudbroker/compute | #### sep | Идентификатор
задачи | Описание | -| --- | ---| -| BGOS-704 | Опциональное поле `SepIDs` в структуре запроса `ListRequest` в cloudbroker/sep | - -#### storage policy -| Идентификатор
задачи | Описание | -| --- | ---| -| BGOS-708 | Поле `SepTechStatus` в структуру запроса `ListRequest` в cloudapi/stpolicy и в cloudbroker/stpolicy | -| BGOS-710 | Обязательное поле `AccessSEPsPool` в структуру запроса `UpdateRequest` в cloudbroker/stpolicy | - -#### trunk -| Идентификатор
задачи | Описание | -| --- | ---| -| 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 | Идентификатор
задачи | Описание | | --- | --- | -| 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 | Идентификатор
задачи | Описание | | --- | --- | -| BGOS-709 | Поле `VFNum` заменено на поле `FNID` в структуре `VFParam` в структуре запроса `SetVFsParamsRequest` в cloudbroker/node | \ No newline at end of file +| BGOS-719 | Поле `Age` в структуре запроса `PurgeLogsRequest` стало необязательным в cloudbroker/grid | + +#### storage policy +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-720 | Тип поля `AccessSEPsPools` изменен с обязательного на опциональный в структуре запроса `UpdateRequest` в cloudbroker/stpolicy | + + +### Удалено + +#### sep +| Идентификатор
задачи | Описание | +| --- | --- | +| BGOS-712 | Поля `ProviderNIDs` и `ConsumerNIDs` удалены из структуры запроса `CreateRequest` в cloudbroker/sep | diff --git a/internal/validators/values.go b/internal/validators/values.go index 5bf829c..4c91a39 100644 --- a/internal/validators/values.go +++ b/internal/validators/values.go @@ -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"} diff --git a/pkg/cloudbroker/compute/clone.go b/pkg/cloudbroker/compute/clone.go index e2a0dcf..bb10ae2 100644 --- a/pkg/cloudbroker/compute/clone.go +++ b/pkg/cloudbroker/compute/clone.go @@ -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 diff --git a/pkg/cloudbroker/compute/start_migration_out.go b/pkg/cloudbroker/compute/start_migration_out.go index 8ef10bc..dcf3926 100644 --- a/pkg/cloudbroker/compute/start_migration_out.go +++ b/pkg/cloudbroker/compute/start_migration_out.go @@ -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 diff --git a/pkg/cloudbroker/grid/purge_logs.go b/pkg/cloudbroker/grid/purge_logs.go index e793606..e9c3310 100644 --- a/pkg/cloudbroker/grid/purge_logs.go +++ b/pkg/cloudbroker/grid/purge_logs.go @@ -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. diff --git a/pkg/cloudbroker/sep/add_consumer_nodes.go b/pkg/cloudbroker/sep/add_consumer_nodes.go index 9fd4cd0..eb6e3e8 100644 --- a/pkg/cloudbroker/sep/add_consumer_nodes.go +++ b/pkg/cloudbroker/sep/add_consumer_nodes.go @@ -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 diff --git a/pkg/cloudbroker/sep/add_provider_nodes.go b/pkg/cloudbroker/sep/add_provider_nodes.go index d5c8371..acabd45 100644 --- a/pkg/cloudbroker/sep/add_provider_nodes.go +++ b/pkg/cloudbroker/sep/add_provider_nodes.go @@ -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 diff --git a/pkg/cloudbroker/sep/create.go b/pkg/cloudbroker/sep/create.go index 9101256..a27007b 100644 --- a/pkg/cloudbroker/sep/create.go +++ b/pkg/cloudbroker/sep/create.go @@ -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"` diff --git a/pkg/cloudbroker/stpolicy/update.go b/pkg/cloudbroker/stpolicy/update.go index 392e1af..9dbdba8 100644 --- a/pkg/cloudbroker/stpolicy/update.go +++ b/pkg/cloudbroker/stpolicy/update.go @@ -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 diff --git a/tests/platform_upgrade/utils_requests.go b/tests/platform_upgrade/utils_requests.go index 6367aac..1380204 100644 --- a/tests/platform_upgrade/utils_requests.go +++ b/tests/platform_upgrade/utils_requests.go @@ -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 + } + } + } + } } } }