diff --git a/CHANGELOG.md b/CHANGELOG.md index a63a3ea..3e96cfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## Version 1.14.6 +## Version 1.14.7 Методы `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 и в следующих версиях будут удалены @@ -9,69 +9,12 @@ ### Добавлено -#### extnet +#### SDN Hypervisors | Идентификатор
задачи | Описание | | --- | --- | -| BGOS-825 | Опциональное поле `EnableSecGroups` в структуру запроса `CreateRequest` в cloudbroker/extnet | +| BGOS-518 | Группа методов Hypervisors | -#### grid +#### SDN Version | Идентификатор
задачи | Описание | | --- | --- | -| BGOS-828 | Вычисляемое поле `ZeroAccessEnabled` в структуру ответа `ItemLocation` в cloudbroker/grid | - -#### dpdknet -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-825 | Опциональное поле `EnableSecGroups` в структуру запроса `CreateRequest` в cloudbroker/dpdknet | - -### sep -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-832 | Метод `AddPoolAsync` в cloudbroker/sep | - -#### vins -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-825 | Опциональное поле `EnableSecGroups` в структуру запроса `CreateInAccountRequest` в cloudbroker/vins и cloudapi/vins | -| BGOS-825 | Опциональное поле `EnableSecGroups` в структуру запроса `CreateInRGRequest` в cloudbroker/vins и cloudapi/vins | - - -### Изменено - -#### compute -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-827 | Описание поля `EnableSecGroups` в структуре запроса `NetAttachRequest` в cloudapi/compute и в cloudbroker/compute | - -#### kvmx86 -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-827 | Описание поля `EnableSecGroups` в структуре `Interface` в структуре запроса `CreateRequest` и `CreateBlankRequest` в cloudapi/kvmx86 и в cloudbroker/kvmx86 | -| BGOS-827 | Описание поля `EnableSecGroups` в структуре `InterfaceMassCreate` в структурах запроса `MassCreateRequest` в cloudbroker/kvmx86 | - -#### lb -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-830 | Тип ответа метода `HighlyAvailable` в cloudapi/lb с uint64 на bool | - -#### sep -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-834 | Тип ответа метода `DelConsumerNodes` с bool на interface в cloudbroker/sep | - -#### sep -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-833 | Тип ответа метода `ConfigFieldEdit` с bool на структуру `RecordConfigFieldEdit` в cloudbroker/sep | - -### Удалено - -#### grid -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-826 | Структура запроса `AddRequest` и метод `Add` в cloudbroker/grid | - -#### sep -| Идентификатор
задачи | Описание | -| --- | --- | -| BGOS-832 | Опциональное поле `Sync` из структуры запроса `AddPoolRequest` в cloudbroker/sep | \ No newline at end of file +| BGOS-838 | Группа методов Version | diff --git a/README.md b/README.md index 5bb4c87..c6c916c 100644 --- a/README.md +++ b/README.md @@ -182,12 +182,14 @@ go get -u repository.basistech.ru/BASIS/decort-golang-sdk - `Address pool` - управление пулами адресов; - `DefaultSecurityPolicies` - управление политиками хранения по умолчанию; - `ExtNet` - управление виртуальными сетями, отвечающими за внешний доступ; +- `Hypervisors` - управление гипервизорами; - `FloatingIPs` - управление плавающими IP-адресами; - `Logical ports` - управление логическими портами; - `NetworkObjectGroups` - управление группами объектов сети; - `Routers` - управление роутерами; - `SecurityPolicies` - управление политиками хранения; - `Segments` - управление сегментами; +- `Version` - получение информации о версии SDN; ## Работа с библиотекой @@ -383,12 +385,14 @@ func main() { - `pkg/sdn/adrspools` - для `Address pool` - `pkg/sdn/defsecpolicies` - для `DefaultSecurityPolicies` - `pkg/sdn/external_networks` - для `ExtNet` + - `pkg/sdn/hypervisors` - для `Hypervisors` - `pkg/sdn/flips` - для `FloatingIPs` - `pkg/sdn/logicalports` - для `Logical ports` - `pkg/sdn/netobjgroups` - для `NetworkObjectGroups` - `pkg/sdn/routers` - для `Routers` - `pkg/sdn/secpolicies` - для `SecurityPolicies` - `pkg/sdn/segments` - для `Segments` + - `pkg/sdn/version` - для `Version` Все поля структуры имеют описание, в которых содержится: @@ -584,12 +588,14 @@ func main() { - `.AddressPool()` - для работы с `Addres pool` - `.DefaultSecurityPolicies()` - для работы с `DefaultSecurityPolicies` - `.ExtNet()` - для работы с `ExtNet` + - `.Hypervisors()` - для работы с `Hypervisors` - `.FloatingIPs()` - для работы с `FloatingIPs` - `.LogicalPorts()` - для работы с `Logical ports` - `.NetworkObjectGroups()` - для работы с `NetworkObjectGroups` - `.Routers()` - для работы с `Routers` - `.SecurityPolicies()` - для работы с `SecurityPolicies` - `.Segments()` - для работы с `Segments` + - `.Version()` - для работы с `Version` 3. Вызвать метод, отвечающий за выполнение запроса и передать в него: diff --git a/pkg/sdn/hypervisors.go b/pkg/sdn/hypervisors.go new file mode 100644 index 0000000..78b3984 --- /dev/null +++ b/pkg/sdn/hypervisors.go @@ -0,0 +1,10 @@ +package sdn + +import ( + hv "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/hypervisors" +) + +// Accessing the SDN method group +func (sdn *SDN) Hypervisors() *hv.Hypervisors { + return hv.New(sdn.client) +} diff --git a/pkg/sdn/hypervisors/connect_node.go b/pkg/sdn/hypervisors/connect_node.go new file mode 100644 index 0000000..604deb0 --- /dev/null +++ b/pkg/sdn/hypervisors/connect_node.go @@ -0,0 +1,30 @@ +package hypervisors + +import ( + "context" + "net/http" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants" + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// ConnectNodeRequest to connect a node +type ConnectNodeRequest struct { + // Node to connect + // Required: true + NodeID uint64 `url:"node_id" json:"node_id" validate:"required"` +} + +func (hv Hypervisors) ConnectNode(ctx context.Context, req ConnectNodeRequest) (string, error) { + err := validators.ValidateRequest(req) + if err != nil { + return "", validators.ValidationErrors(validators.GetErrors(err)) + } + url := "/sdn/hypervisor/connect_node" + result, err := hv.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req) + if err != nil { + return "", err + } + + return string(result), nil +} diff --git a/pkg/sdn/hypervisors/delete.go b/pkg/sdn/hypervisors/delete.go new file mode 100644 index 0000000..71cb463 --- /dev/null +++ b/pkg/sdn/hypervisors/delete.go @@ -0,0 +1,43 @@ +package hypervisors + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants" + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// DeleteRequest to delete a hypervisor +type DeleteRequest struct { + // Name of a hypervisor + // Required: true + Name string `url:"name" json:"name" validate:"required"` +} + +// Delete a hypervisor +func (hv Hypervisors) Delete(ctx context.Context, req DeleteRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + return false, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/sdn/hypervisor/delete" + + res, err := hv.client.DecortApiCallCtype(ctx, http.MethodDelete, url, constants.MIMEJSON, req) + if err != nil { + return false, err + } + + if string(res) == "" { + return true, nil + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/pkg/sdn/hypervisors/get.go b/pkg/sdn/hypervisors/get.go new file mode 100644 index 0000000..8f58723 --- /dev/null +++ b/pkg/sdn/hypervisors/get.go @@ -0,0 +1,50 @@ +package hypervisors + +import ( + "context" + "encoding/json" + "net/http" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// GetRequest struct to get information about hypervisor +type GetRequest struct { + // Name + // Required: true + Name string `url:"name" json:"name" validate:"required"` + + // Port info (available options: detailed, general) + // Required: false + PortInfo string `url:"port_info,omitempty" json:"port_info,omitempty"` +} + +// Get gets current configuration of a hypervisor as a RecordHypervisor +func (hv Hypervisors) Get(ctx context.Context, req GetRequest) (*RecordHypervisor, error) { + res, err := hv.GetRaw(ctx, req) + if err != nil { + return nil, err + } + + info := RecordHypervisor{} + + err = json.Unmarshal(res, &info) + if err != nil { + return nil, err + } + + return &info, nil +} + +// GetRaw gets information about a hypervisor as an array of bytes +func (hv Hypervisors) GetRaw(ctx context.Context, req GetRequest) ([]byte, error) { + err := validators.ValidateRequest(req) + if err != nil { + return nil, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/sdn/hypervisor/get" + + res, err := hv.client.DecortApiCall(ctx, http.MethodGet, url, req) + return res, err +} diff --git a/pkg/sdn/hypervisors/hypervisors.go b/pkg/sdn/hypervisors/hypervisors.go new file mode 100644 index 0000000..d1af86b --- /dev/null +++ b/pkg/sdn/hypervisors/hypervisors.go @@ -0,0 +1,17 @@ +package hypervisors + +import ( + "repository.basistech.ru/BASIS/decort-golang-sdk/interfaces" +) + +// Structure for creating request to hypervisors +type Hypervisors struct { + client interfaces.Caller +} + +// Builder for hypervisors endpoints +func New(client interfaces.Caller) *Hypervisors { + return &Hypervisors{ + client, + } +} diff --git a/pkg/sdn/hypervisors/list.go b/pkg/sdn/hypervisors/list.go new file mode 100644 index 0000000..295eeed --- /dev/null +++ b/pkg/sdn/hypervisors/list.go @@ -0,0 +1,90 @@ +package hypervisors + +import ( + "context" + "encoding/json" + "net/http" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// ListRequest struct to get a list of hypervisors +type ListRequest struct { + // Page + // Required: false + Page uint64 `url:"page,omitempty" json:"page,omitempty"` + + // Per page + // Required: false + PerPage uint64 `url:"per_page,omitempty" json:"per_page,omitempty"` + + // Sort by (available options: name, hostname, last_sync, display_name, ip, created_at, updated_at) + // Required: false + SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty"` + + // Sort order (available options: asc, desc) + // Required: false + SortOrder string `url:"sort_order,omitempty" json:"sort_order,omitempty"` + + // Port info (available options: detailed, general) + // Required: false + PortInfo string `url:"port_info,omitempty" json:"port_info,omitempty"` + + // Hostname + // Required: false + Hostname string `url:"hostname,omitempty" json:"hostname,omitempty"` + + // Display name + // Required: false + DisplayName string `url:"display_name,omitempty" json:"display_name,omitempty"` + + // IP + // Required: false + IP string `url:"ip,omitempty" json:"ip,omitempty"` + + // Created from + // Required: false + CreatedFrom string `url:"created_from,omitempty" json:"created_from,omitempty"` + + // Created to + // Required: false + CreatedTo string `url:"created_to,omitempty" json:"created_to,omitempty"` + + // Updated from + // Required: false + UpdatedFrom string `url:"updated_from,omitempty" json:"updated_from,omitempty"` + + // Updated to + // Required: false + UpdatedTo string `url:"updated_to,omitempty" json:"updated_to,omitempty"` +} + +// List of hypervisors +func (hv Hypervisors) List(ctx context.Context, req ListRequest) (HypervisorsList, error) { + res, err := hv.ListRaw(ctx, req) + if err != nil { + return nil, err + } + + hvs := HypervisorsList{} + + err = json.Unmarshal(res, &hvs) + if err != nil { + return nil, err + } + + return hvs, nil +} + +// ListRaw gets a list of all hypervisors as an array of bytes +func (hv Hypervisors) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) { + + if err := validators.ValidateRequest(req); err != nil { + return nil, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/sdn/hypervisor/list" + + res, err := hv.client.DecortApiCall(ctx, http.MethodGet, url, req) + return res, err +} diff --git a/pkg/sdn/hypervisors/models.go b/pkg/sdn/hypervisors/models.go new file mode 100644 index 0000000..897c10c --- /dev/null +++ b/pkg/sdn/hypervisors/models.go @@ -0,0 +1,31 @@ +package hypervisors + +// Main information about hypervisor +type RecordHypervisor struct { + // Created at + CreatedAt string `json:"created_at"` + + // Display name + DisplayName string `json:"display_name"` + + // Hostname + Hostname string `json:"hostname"` + + // IP + IP string `json:"ip"` + + // Synced at + SyncedAt string `json:"synced_at"` + + // Name + Name string `json:"name"` + + // Ports + Ports []string `json:"ports"` + + // Status + Status string `json:"status"` +} + +// List of hypervisors +type HypervisorsList []RecordHypervisor diff --git a/pkg/sdn/hypervisors/update_display_name.go b/pkg/sdn/hypervisors/update_display_name.go new file mode 100644 index 0000000..187dee3 --- /dev/null +++ b/pkg/sdn/hypervisors/update_display_name.go @@ -0,0 +1,50 @@ +package hypervisors + +import ( + "context" + "encoding/json" + "net/http" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// UpdateDisplayNameRequest struct to update display name for a hypervisor +type UpdateDisplayNameRequest struct { + // Current name of the hypervisor + // Required: true + Name string `url:"name" json:"name" validate:"required"` + + // New display name to set + // Required: true + DisplayName string `url:"display_name" json:"display_name" validate:"required"` +} + +// UpdateDisplayName updates display name for a hypervisor +func (hv Hypervisors) UpdateDisplayName(ctx context.Context, req UpdateDisplayNameRequest) (*RecordHypervisor, error) { + res, err := hv.UpdateDisplayNameRaw(ctx, req) + if err != nil { + return nil, err + } + + info := RecordHypervisor{} + + err = json.Unmarshal(res, &info) + if err != nil { + return nil, err + } + + return &info, nil +} + +// UpdateDisplayNameRaw update display name for a hypervisor and get its information as an array of bytes +func (hv Hypervisors) UpdateDisplayNameRaw(ctx context.Context, req UpdateDisplayNameRequest) ([]byte, error) { + err := validators.ValidateRequest(req) + if err != nil { + return nil, validators.ValidationErrors(validators.GetErrors(err)) + } + + url := "/sdn/hypervisor/update_display_name" + + res, err := hv.client.DecortApiCall(ctx, http.MethodPut, url, req) + return res, err +} diff --git a/pkg/sdn/version.go b/pkg/sdn/version.go new file mode 100644 index 0000000..7a7afe8 --- /dev/null +++ b/pkg/sdn/version.go @@ -0,0 +1,10 @@ +package sdn + +import ( + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/version" +) + +// Accessing the SDN method group +func (sdn *SDN) Version() *version.Version { + return version.New(sdn.client) +} diff --git a/pkg/sdn/version/get.go b/pkg/sdn/version/get.go new file mode 100644 index 0000000..bc07e57 --- /dev/null +++ b/pkg/sdn/version/get.go @@ -0,0 +1,33 @@ +package version + +import ( + "context" + "encoding/json" + "net/http" +) + +// Get gets SDN version info as a RecordVersion struct +func (v Version) Get(ctx context.Context) (*RecordVersion, error) { + res, err := v.GetRaw(ctx) + if err != nil { + return nil, err + } + + info := RecordVersion{} + + err = json.Unmarshal(res, &info) + if err != nil { + return nil, err + } + + return &info, nil +} + +// GetRaw gets SDN version info as an array of bytes +func (v Version) GetRaw(ctx context.Context) ([]byte, error) { + + url := "/sdn/version/get" + + res, err := v.client.DecortApiCall(ctx, http.MethodGet, url, nil) + return res, err +} diff --git a/pkg/sdn/version/models.go b/pkg/sdn/version/models.go new file mode 100644 index 0000000..6ca7cb0 --- /dev/null +++ b/pkg/sdn/version/models.go @@ -0,0 +1,25 @@ +package version + +// Version info of the SDN platform +type RecordVersion struct { + // Core component version info + Core ComponentVersion `json:"core"` + + // Director component version info + Director ComponentVersion `json:"director"` +} + +// Version info of a single component +type ComponentVersion struct { + // Branch name + Branch string `json:"branch"` + + // Build time + BuildTime string `json:"build_time"` + + // Commit hash + Commit string `json:"commit"` + + // Version string + Version string `json:"version"` +} diff --git a/pkg/sdn/version/version.go b/pkg/sdn/version/version.go new file mode 100644 index 0000000..6e52d81 --- /dev/null +++ b/pkg/sdn/version/version.go @@ -0,0 +1,18 @@ +// API Actor API for managing SDN version +package version + +import ( + "repository.basistech.ru/BASIS/decort-golang-sdk/interfaces" +) + +// Structure for creating request to version +type Version struct { + client interfaces.Caller +} + +// Builder for version endpoints +func New(client interfaces.Caller) *Version { + return &Version{ + client, + } +} diff --git a/tests/platform_upgrade/cloud_test.go b/tests/platform_upgrade/cloud_test.go index 3ec841d..e5c414b 100644 --- a/tests/platform_upgrade/cloud_test.go +++ b/tests/platform_upgrade/cloud_test.go @@ -27,6 +27,7 @@ import ( "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/acsgroups" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/adrspools" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/defsecpolicies" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/hypervisors" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/logicalports" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/routers" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/secpolicies" @@ -59,6 +60,7 @@ import ( extnet_sdn "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/extnet" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/flips" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/netobjgroups" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/version" ) // TestGetListCloudAPI tests platforms responses vs. json tags of golang structures in cloudapi get/list methods @@ -1025,6 +1027,26 @@ func TestGetListSDNAPI(t *testing.T) { t.Errorf("Can not test segments get because list is empty") } + // Hypervisors + // List + bytes, err = client.SDN().Hypervisors().ListRaw(context.Background(), hypervisors.ListRequest{}) + if err != nil { + t.Error(err) + } + getResult("Hypervisors list", bytes, hypervisors.HypervisorsList{}, t) + // Get + listHypervisors, _ := client.SDN().Hypervisors().List(context.Background(), hypervisors.ListRequest{}) + if len(listHypervisors) > 0 { + id := listHypervisors[0].Name + bytes, err = client.SDN().Hypervisors().GetRaw(context.Background(), hypervisors.GetRequest{Name: id}) + if err != nil { + t.Error(err) + } + getResult("Hypervisors get", bytes, hypervisors.RecordHypervisor{}, t) + } else { + t.Errorf("Can not test Hypervisors get because listHypervisors list is empty") + } + // FloatingIPs // List bytes, err = client.SDN().FloatingIPs().ListRaw(context.Background(), flips.ListRequest{}) @@ -1084,6 +1106,13 @@ func TestGetListSDNAPI(t *testing.T) { } else { t.Errorf("Can not test routers get because routerList list is empty") } + + // Version + bytes, err = client.SDN().Version().GetRaw(context.Background()) + if err != nil { + t.Error(err) + } + getResult("Version get", bytes, version.RecordVersion{}, t) } // TestRequestsCloudAPI tests platform requests vs. golang request structures in sdk for cloudapi requests diff --git a/tests/platform_upgrade/request_map.go b/tests/platform_upgrade/request_map.go index 897eb45..51361ff 100644 --- a/tests/platform_upgrade/request_map.go +++ b/tests/platform_upgrade/request_map.go @@ -72,6 +72,7 @@ import ( extnet_sdn "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/extnet" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/flips" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/hypervisors" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/netobjgroups" ) @@ -1167,6 +1168,13 @@ func getRequestsMapSDN() map[string]interface{} { "/restmachine/sdn/floating_ip/list": flips.ListRequest{}, "/restmachine/sdn/floating_ip/update": flips.UpdateRequest{}, + // hypervisors + "/restmachine/sdn/hypervisor/connect_node": hypervisors.ConnectNodeRequest{}, + "/restmachine/sdn/hypervisor/delete": hypervisors.DeleteRequest{}, + "/restmachine/sdn/hypervisor/get": hypervisors.GetRequest{}, + "/restmachine/sdn/hypervisor/list": hypervisors.ListRequest{}, + "/restmachine/sdn/hypervisor/update_display_name": hypervisors.UpdateDisplayNameRequest{}, + // network object groups "/restmachine/sdn/network_object_group/attach_external_network_ports": netobjgroups.AttachExtNetPortsRequest{}, "/restmachine/sdn/network_object_group/attach_logical_ports": netobjgroups.AttachLogicalPortsRequest{}, @@ -1210,5 +1218,8 @@ func getRequestsMapSDN() map[string]interface{} { "/restmachine/sdn/router/list": routers.ListRequest{}, "/restmachine/sdn/router/policies/list": policies.ListRequest{}, "/restmachine/sdn/router/update": routers.UpdateRequest{}, + + // version + "/restmachine/sdn/version/get": nil, } }