This commit is contained in:
asteam
2025-11-14 17:38:59 +03:00
parent 562b6019d0
commit 0bf073da93
149 changed files with 11080 additions and 38 deletions

53
pkg/sdn/routers/create.go Normal file
View File

@@ -0,0 +1,53 @@
package routers
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// CreateRequest struct to create router
type CreateRequest struct {
// Access group ID
// Required: true
AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
// Description
// Required: true
Description string `url:"description" json:"description" validate:"required"`
// Name of acces group
// Required: true
DisplayName string `url:"display_name" json:"display_name" validate:"required"`
// Enabled True or False
// Required: true
Enabled interface{} `url:"enabled" json:"enabled" validate:"required,isBool"`
}
// Create creates a access groups
func (i Routers) Create(ctx context.Context, req CreateRequest) (*RoutersModel, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/sdn/router/create"
res, err := i.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
if err != nil {
return nil, err
}
info := RoutersModel{}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

42
pkg/sdn/routers/delete.go Normal file
View File

@@ -0,0 +1,42 @@
package routers
import (
"context"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// DeleteRequest struct for delete router
type DeleteRequest struct {
// ID of router
// Required: true
RouterID string `url:"router_id" json:"router_id" validate:"required"`
// ID of version
// Required: true
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
// Force delete
// Required: false
Force interface{} `url:"force,omitempty" json:"force,omitempty" validate:"omitempty,isBool"`
}
// Delete delete a router
func (e Routers) Delete(ctx context.Context, req DeleteRequest) error {
err := validators.ValidateRequest(req)
if err != nil {
return validators.ValidationErrors(validators.GetErrors(err))
}
url := "/sdn/router/delete"
_, err = e.client.DecortApiCallCtype(ctx, http.MethodDelete, url, constants.MIMEJSON, req)
if err != nil {
return err
}
return nil
}

42
pkg/sdn/routers/filter.go Normal file
View File

@@ -0,0 +1,42 @@
package routers
// FilterByID returns RoutersList with specified ID.
func (agl RoutersList) FilterByID(id string) RoutersList {
predicate := func(ia RoutersModel) bool {
return ia.ID == id
}
return agl.FilterFunc(predicate)
}
// FilterByName returns RoutersList with specified Name.
func (agl RoutersList) FilterByName(name string) RoutersList {
predicate := func(ia RoutersModel) bool {
return ia.DisplayName == name
}
return agl.FilterFunc(predicate)
}
// FilterFunc allows filtering RoutersList based on a user-specified predicate.
func (agl RoutersList) FilterFunc(predicate func(RoutersModel) bool) RoutersList {
var result RoutersList
for _, acc := range agl {
if predicate(acc) {
result = append(result, acc)
}
}
return result
}
// FindOne returns first element.
// If none was found, returns an empty struct.
func (agl RoutersList) FindOne() RoutersModel {
if len(agl) == 0 {
return RoutersModel{}
}
return agl[0]
}

View File

@@ -0,0 +1,309 @@
package routers
import (
"testing"
)
var testRoutersList = RoutersList{
{
ID: "router1",
DisplayName: "DevelopersRouter",
Description: "First router",
CreatedAt: "2023-01-01",
AccessGroupID: "group1",
AccessGroupName: "Developers",
Enabled: true,
GatewayPorts: []GatewayPort{
{
ID: "gateway1",
Description: "Gateway port 1",
SNATEnabled: true,
ExternalL4PortMin: 1000,
ExternalL4PortMax: 2000,
CreatedAt: "2023-01-01",
UpdatedAt: "2023-01-01",
VersionID: 1,
ExternalNetworkPort: ExternalNetworkPort{
IPv4: "192.168.1.1",
IPv6: "2001:db8::1",
},
},
},
Policies: []Policy{
{
ID: "policy1",
DisplayName: "Policy1",
Action: "allow",
Priority: 1,
Enabled: true,
},
},
Ports: []Port{
{
ID: "port1",
Description: "Port 1",
Enabled: true,
IPv4Address: "10.0.0.1",
},
},
Status: Status{
Common: "active",
},
VersionID: 1,
},
{
ID: "router2",
DisplayName: "AdminsRouter",
Description: "Second router",
CreatedAt: "2023-01-02",
AccessGroupID: "group2",
AccessGroupName: "Admins",
Enabled: true,
GatewayPorts: []GatewayPort{
{
ID: "gateway2",
Description: "Gateway port 2",
SNATEnabled: false,
ExternalL4PortMin: 3000,
ExternalL4PortMax: 4000,
CreatedAt: "2023-01-02",
UpdatedAt: "2023-01-02",
VersionID: 1,
ExternalNetworkPort: ExternalNetworkPort{
IPv4: "192.168.1.2",
IPv6: "2001:db8::2",
},
},
},
Policies: []Policy{
{
ID: "policy2",
DisplayName: "Policy2",
Action: "deny",
Priority: 2,
Enabled: true,
},
},
Ports: []Port{
{
ID: "port2",
Description: "Port 2",
Enabled: true,
IPv4Address: "10.0.0.2",
},
},
Status: Status{
Common: "active",
},
VersionID: 2,
},
{
ID: "router3",
DisplayName: "UsersRouter",
Description: "Third router",
CreatedAt: "2023-01-03",
AccessGroupID: "group3",
AccessGroupName: "Users",
Enabled: false,
GatewayPorts: []GatewayPort{
{
ID: "gateway3",
Description: "Gateway port 3",
SNATEnabled: true,
ExternalL4PortMin: 5000,
ExternalL4PortMax: 6000,
CreatedAt: "2023-01-03",
UpdatedAt: "2023-01-03",
VersionID: 1,
ExternalNetworkPort: ExternalNetworkPort{
IPv4: "192.168.1.3",
IPv6: "2001:db8::3",
},
},
},
Policies: []Policy{
{
ID: "policy3",
DisplayName: "Policy3",
Action: "allow",
Priority: 3,
Enabled: false,
},
},
Ports: []Port{
{
ID: "port3",
Description: "Port 3",
Enabled: false,
IPv4Address: "10.0.0.3",
},
},
Status: Status{
Common: "inactive",
},
VersionID: 3,
},
}
func TestFilterByID(t *testing.T) {
actual := testRoutersList.FilterByID("router2").FindOne()
if actual.ID != "router2" {
t.Fatal("actual:", actual.ID, "> expected: router2")
}
}
func TestFilterByName(t *testing.T) {
actual := testRoutersList.FilterByName("UsersRouter").FindOne()
if actual.DisplayName != "UsersRouter" {
t.Fatal("actual:", actual.DisplayName, ">> expected: UsersRouter")
}
}
func TestFilterFunc(t *testing.T) {
actual := testRoutersList.FilterFunc(func(rm RoutersModel) bool {
return rm.Description == "Second router"
})
if len(actual) != 1 || actual[0].ID != "router2" {
t.Fatal("Expected 1 router with description 'Second router', found:", len(actual))
}
}
func TestFindOneWithResults(t *testing.T) {
result := testRoutersList.FilterByID("router1").FindOne()
if result.ID != "router1" {
t.Fatal("Expected router1, got:", result.ID)
}
}
func TestFindOneEmpty(t *testing.T) {
emptyList := RoutersList{}
result := emptyList.FindOne()
if result.ID != "" || result.DisplayName != "" {
t.Fatal("Expected empty RoutersModel, got:", result)
}
}
func TestFilterByIDNotFound(t *testing.T) {
actual := testRoutersList.FilterByID("nonexistent")
if len(actual) != 0 {
t.Fatal("Expected 0 routers, found:", len(actual))
}
}
func TestFilterByNameNotFound(t *testing.T) {
actual := testRoutersList.FilterByName("Nonexistent Router")
if len(actual) != 0 {
t.Fatal("Expected 0 routers, found:", len(actual))
}
}
func TestFilterByEnabledStatus(t *testing.T) {
actual := testRoutersList.FilterFunc(func(rm RoutersModel) bool {
return rm.Enabled
})
if len(actual) != 2 {
t.Fatal("Expected 2 enabled routers, found:", len(actual))
}
}
func TestFilterByAccessGroup(t *testing.T) {
actual := testRoutersList.FilterFunc(func(rm RoutersModel) bool {
return rm.AccessGroupName == "Developers"
})
if len(actual) != 1 || actual[0].ID != "router1" {
t.Fatal("Expected 1 router with Developers access group, found:", len(actual))
}
}
func TestFilterByPolicyAction(t *testing.T) {
actual := testRoutersList.FilterFunc(func(rm RoutersModel) bool {
for _, policy := range rm.Policies {
if policy.Action == "deny" {
return true
}
}
return false
})
if len(actual) != 1 || actual[0].ID != "router2" {
t.Fatal("Expected 1 router with deny policy, found:", len(actual))
}
}
func TestFilterByGatewayPortRange(t *testing.T) {
actual := testRoutersList.FilterFunc(func(rm RoutersModel) bool {
for _, gateway := range rm.GatewayPorts {
if gateway.ExternalL4PortMin >= 3000 && gateway.ExternalL4PortMax <= 4000 {
return true
}
}
return false
})
if len(actual) != 1 || actual[0].ID != "router2" {
t.Fatal("Expected 1 router with gateway port range 3000-4000, found:", len(actual))
}
}
func TestFilterBySNATEnabled(t *testing.T) {
actual := testRoutersList.FilterFunc(func(rm RoutersModel) bool {
for _, gateway := range rm.GatewayPorts {
if gateway.SNATEnabled {
return true
}
}
return false
})
if len(actual) != 2 {
t.Fatal("Expected 2 routers with SNAT enabled, found:", len(actual))
}
}
func TestFilterByStatus(t *testing.T) {
actual := testRoutersList.FilterFunc(func(rm RoutersModel) bool {
return rm.Status.Common == "inactive"
})
if len(actual) != 1 || actual[0].ID != "router3" {
t.Fatal("Expected 1 router with inactive status, found:", len(actual))
}
}
func TestFilterByPortEnabled(t *testing.T) {
actual := testRoutersList.FilterFunc(func(rm RoutersModel) bool {
for _, port := range rm.Ports {
if port.Enabled {
return true
}
}
return false
})
if len(actual) != 2 {
t.Fatal("Expected 2 routers with enabled ports, found:", len(actual))
}
}
func TestFilterByPolicyPriority(t *testing.T) {
actual := testRoutersList.FilterFunc(func(rm RoutersModel) bool {
for _, policy := range rm.Policies {
if policy.Priority > 2 {
return true
}
}
return false
})
if len(actual) != 1 || actual[0].ID != "router3" {
t.Fatal("Expected 1 router with policy priority > 2, found:", len(actual))
}
}

View File

@@ -0,0 +1,10 @@
package routers
import (
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/routers/gwport"
)
// Accessing the routers gateway port method group
func (r *Routers) GWPort() *gwport.GWPort {
return gwport.New(r.client)
}

47
pkg/sdn/routers/get.go Normal file
View File

@@ -0,0 +1,47 @@
package routers
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// GetRequest struct to get information about router
type GetRequest struct {
// ID
// Required: true
ID string `url:"router_id" json:"router_id" validate:"required"`
}
// Get gets routers details as a RoutersModel struct
func (a Routers) Get(ctx context.Context, req GetRequest) (*RoutersModel, error) {
res, err := a.GetRaw(ctx, req)
if err != nil {
return nil, err
}
info := RoutersModel{}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}
// GetRaw gets routers details as an array of bytes
func (a Routers) GetRaw(ctx context.Context, req GetRequest) ([]byte, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/sdn/router/get"
res, err := a.client.DecortApiCall(ctx, http.MethodGet, url, req)
return res, err
}

View File

@@ -0,0 +1,57 @@
package gwport
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// CreateRequest struct to create gateway port
type CreateRequest struct {
// ID of router
// Required: true
RouterID string `url:"router_id" json:"router_id" validate:"required"`
// ID of version
// Required: true
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
// Detailed description of the external network
// Required: true
Description string `url:"description" json:"description" validate:"required"`
// External network port ID
// Required: true
ExternalNetworkPortID string `url:"external_network_port_id" json:"external_network_port_id" validate:"required"`
// Whether is enabled
// Required: true
Enabled bool `url:"snat_enabled" json:"snat_enabled"`
}
// Create creates a gateway port
func (i GWPort) Create(ctx context.Context, req CreateRequest) (*GatewayPort, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/sdn/router/gateway_port/create"
res, err := i.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
if err != nil {
return nil, err
}
info := GatewayPort{}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

View File

@@ -0,0 +1,46 @@
package gwport
import (
"context"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// DeleteRequest struct for delete router
type DeleteRequest struct {
// ID of router
// Required: true
RouterID string `url:"router_id" json:"router_id" validate:"required"`
// ID of gateway port
// Required: true
GatewayPortID string `url:"gateway_port_id" json:"gateway_port_id" validate:"required"`
// ID of version
// Required: true
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
// Force delete
// Required: false
Force interface{} `url:"force,omitempty" json:"force,omitempty" validate:"omitempty,isBool"`
}
// Delete delete a router
func (e GWPort) Delete(ctx context.Context, req DeleteRequest) error {
err := validators.ValidateRequest(req)
if err != nil {
return validators.ValidationErrors(validators.GetErrors(err))
}
url := "/sdn/router/gateway_port/delete"
_, err = e.client.DecortApiCallCtype(ctx, http.MethodDelete, url, constants.MIMEJSON, req)
if err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,19 @@
package gwport
// API Actor API for managing SDN routers gateway port
import (
"repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
)
// Structure for creating request to routers gateway port
type GWPort struct {
client interfaces.Caller
}
// Builder for routers gateway port endpoints
func New(client interfaces.Caller) *GWPort {
return &GWPort{
client,
}
}

View File

@@ -0,0 +1,51 @@
package gwport
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// GetRequest struct to get information about gateway port
type GetRequest struct {
// Router ID
// Required: true
RouterID string `url:"router_id" json:"router_id" validate:"required"`
// Gateway port ID
// Required: true
GatewayPortID string `url:"gateway_port_id" json:"gateway_port_id" validate:"required"`
}
// Get gets gateway port details as a GatewayPort struct
func (a GWPort) Get(ctx context.Context, req GetRequest) (*GatewayPort, error) {
res, err := a.GetRaw(ctx, req)
if err != nil {
return nil, err
}
info := GatewayPort{}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}
// GetRaw gets gateway port details as an array of bytes
func (a GWPort) GetRaw(ctx context.Context, req GetRequest) ([]byte, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/sdn/router/gateway_port/get"
res, err := a.client.DecortApiCall(ctx, http.MethodGet, url, req)
return res, err
}

View File

@@ -0,0 +1,47 @@
package gwport
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get list of gateway ports
type ListRequest struct {
// Router ID
// Required: true
RouterID string `url:"router_id" json:"router_id" validate:"required"`
}
// List gets gateway port list
func (a GWPort) List(ctx context.Context, req ListRequest) (GatewayPortsList, error) {
res, err := a.ListRaw(ctx, req)
if err != nil {
return nil, err
}
info := []GatewayPort{}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return info, nil
}
// GetRaw gets gateway port list as an array of bytes
func (a GWPort) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/sdn/router/gateway_port/list"
res, err := a.client.DecortApiCall(ctx, http.MethodGet, url, req)
return res, err
}

View File

@@ -0,0 +1,481 @@
package gwport
// List of ports
type GatewayPortsList []GatewayPort
// Gateway port information
type GatewayPort struct {
// Created time
CreatedAt string `json:"created_at"`
// Description
Description string `json:"description"`
// External L4 port maximum
ExternalL4PortMax int `json:"external_l4_port_max"`
// External L4 port minimum
ExternalL4PortMin int `json:"external_l4_port_min"`
// External network port
ExternalNetworkPort ExternalNetworkPort `json:"external_network_port"`
// ID
ID string `json:"id"`
// SNAT enabled flag
SNATEnabled bool `json:"snat_enabled"`
// Status information
Status Status `json:"status"`
// Updated time
UpdatedAt string `json:"updated_at"`
// Version ID
VersionID uint64 `json:"version_id"`
}
// External network port information
type ExternalNetworkPort struct {
// Access group ID
AccessGroupID string `json:"access_group_id"`
// Access group name
AccessGroupName string `json:"access_group_name"`
// Comment
Comment string `json:"comment"`
// Display name
DisplayName string `json:"display_name"`
// Enabled flag
Enabled bool `json:"enabled"`
// IPv4 address
IPv4 string `json:"ipv4"`
// IPv6 address
IPv6 string `json:"ipv6"`
// IPv6 configuration
IPv6Config IPv6Config `json:"ipv6_config"`
// MAC address
MAC string `json:"mac"`
// Router gateway port
RouterGatewayPort RouterGatewayPort `json:"router_gateway_port"`
// Floating IP
FloatingIP FloatingIP `json:"floating_ip"`
}
// IPv6 configuration information
type IPv6Config struct {
// Address mode
AddressMode string `json:"address_mode"`
// Enable periodic RA flag
EnablePeriodicRA bool `json:"enable_periodic_ra"`
// Interval RA
IntervalRA int `json:"interval_ra"`
// Router preference
RouterPreference string `json:"router_preference"`
}
// Router gateway port information
type RouterGatewayPort struct {
// Created time
CreatedAt string `json:"created_at"`
// Description
Description string `json:"description"`
// ID
ID string `json:"id"`
// Router display name
RouterDisplayName string `json:"router_display_name"`
// Router ID
RouterID string `json:"router_id"`
// SNAT enabled flag
SNATEnabled bool `json:"snat_enabled"`
// Updated time
UpdatedAt string `json:"updated_at"`
}
// Floating IP information
type FloatingIP 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"`
// External network port
ExternalNetworkPort string `json:"external_network_port"`
// ID
ID string `json:"id"`
// Logical port
LogicalPort LogicalPort `json:"logical_port"`
// Router
Router string `json:"router"`
// Updated time
UpdatedAt string `json:"updated_at"`
// Version ID
VersionID uint64 `json:"version_id"`
}
// Logical port information
type LogicalPort struct {
// ID
ID string `json:"id"`
// Access group ID
AccessGroupID string `json:"access_group_id"`
// Access group name
AccessGroupName string `json:"access_group_name"`
// Adapter MAC
AdapterMAC string `json:"adapter_mac"`
// Address detection flag
AddressDetection bool `json:"address_detection"`
// Description
Description string `json:"description"`
// Created time
CreatedAt string `json:"created_at"`
// Display name
DisplayName string `json:"display_name"`
// Enabled flag
Enabled bool `json:"enabled"`
// External network ID
ExternalNetworkID string `json:"external_network_id"`
// Hypervisor
Hypervisor string `json:"hypervisor"`
// Hypervisor display name
HypervisorDisplayName string `json:"hypervisor_display_name"`
// Live migration target HV
LiveMigrationTargetHV string `json:"live_migration_target_hv"`
// Status information
Status Status `json:"status"`
// Bindings information
Bindings Bindings `json:"bindings"`
// Unique identifier
UniqueIdentifier string `json:"unique_identifier"`
// Updated time
UpdatedAt string `json:"updated_at"`
// Version ID
VersionID uint64 `json:"version_id"`
}
// Status information
type Status struct {
// Common status
Common string `json:"common"`
// Hypervisors status list
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"`
// Synced at time
SyncedAt string `json:"synced_at"`
}
// Bindings information
type Bindings struct {
// ID
ID string `json:"id"`
// Segment display name
SegmentDisplayName string `json:"segment_display_name"`
// Segment ID
SegmentID string `json:"segment_id"`
// Port security flag
PortSecurity bool `json:"port_security"`
// 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"`
// Created time
CreatedAt string `json:"created_at"`
// Updated time
UpdatedAt string `json:"updated_at"`
// Logical port addresses list
LogicalPortAddresses []LogicalPortAddress `json:"logical_port_addresses"`
}
// Logical port address information
type LogicalPortAddress struct {
// IP address
IP string `json:"ip"`
// IP type
IPType string `json:"ip_type"`
// Is discovered flag
IsDiscovered bool `json:"is_discovered"`
// Is primary flag
IsPrimary bool `json:"is_primary"`
// MAC address
MAC string `json:"mac"`
// ID
ID string `json:"id"`
// Logical port ID
LogicalPortID string `json:"logical_port_id"`
// Assigned at time
AssignedAt string `json:"assigned_at"`
}
// Policy information
type Policy struct {
// Action
Action string `json:"action"`
// Created time
CreatedAt string `json:"created_at"`
// Display name
DisplayName string `json:"display_name"`
// Enabled flag
Enabled bool `json:"enabled"`
// ID
ID string `json:"id"`
// Match criteria
Match map[string]interface{} `json:"match"`
// Next IPv4 addresses list
NextIPv4Address []string `json:"next_ipv4_address"`
// Next IPv6 addresses list
NextIPv6Address []string `json:"next_ipv6_address"`
// Priority
Priority int `json:"priority"`
// Updated time
UpdatedAt string `json:"updated_at"`
// Version ID
VersionID uint64 `json:"version_id"`
}
// Port information
type Port struct {
// Created time
CreatedAt string `json:"created_at"`
// Description
Description string `json:"description"`
// Enabled flag
Enabled bool `json:"enabled"`
// ID
ID string `json:"id"`
// IPv4 address
IPv4Address string `json:"ipv4_address"`
// IPv6 address
IPv6Address string `json:"ipv6_address"`
// IPv6 configuration
IPv6Config IPv6Config `json:"ipv6_config"`
// MAC address
MAC string `json:"mac"`
// Segment information
Segment Segment `json:"segment"`
// Segment ID
SegmentID string `json:"segment_id"`
// Status information
Status Status `json:"status"`
// Updated time
UpdatedAt string `json:"updated_at"`
// Version ID
VersionID uint64 `json:"version_id"`
}
// Segment information
type Segment 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"`
// DHCPv4 configuration
DHCPv4 DHCPv4 `json:"dhcp_v4"`
// DHCPv6 configuration
DHCPv6 DHCPv6 `json:"dhcp_v6"`
// Display name
DisplayName string `json:"display_name"`
// Enabled flag
Enabled bool `json:"enabled"`
// ID
ID string `json:"id"`
// Logical ports info list
LogicalPortsInfo []LogicalPortInfo `json:"logical_ports_info"`
// Routers info list
RoutersInfo []RouterInfo `json:"routers_info"`
// Status information
Status Status `json:"status"`
// IPv4 subnet
SubnetV4 string `json:"subnet_v4"`
// IPv6 subnet
SubnetV6 string `json:"subnet_v6"`
// Updated time
UpdatedAt string `json:"updated_at"`
// Version ID
VersionID uint64 `json:"version_id"`
}
// DHCPv4 configuration
type DHCPv4 struct {
// DNS servers list
DNS []string `json:"dns"`
// Excluded address ranges list
ExcludedAddressRanges []string `json:"excluded_address_ranges"`
// Gateway address
Gateway string `json:"gateway"`
// ID
ID string `json:"id"`
// Lease time
LeaseTime int `json:"lease_time"`
// Server IP
ServerIP string `json:"server_ip"`
// Server MAC
ServerMAC string `json:"server_mac"`
// Enabled flag
Enabled bool `json:"enabled"`
}
// DHCPv6 configuration
type DHCPv6 struct {
// Address prefix
AddressPrefix string `json:"address_prefix"`
// DNS servers list
DNS []string `json:"dns"`
// ID
ID string `json:"id"`
// Lease time
LeaseTime int `json:"lease_time"`
// Server MAC
ServerMAC string `json:"server_mac"`
// Enabled flag
Enabled bool `json:"enabled"`
}
// Logical port info
type LogicalPortInfo struct {
// Display name
DisplayName string `json:"display_name"`
// ID
ID string `json:"id"`
}
// Router info
type RouterInfo struct {
// Display name
DisplayName string `json:"display_name"`
// ID
ID string `json:"id"`
}

View File

@@ -0,0 +1,61 @@
package gwport
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// UpdateRequest struct to update gateway port
type UpdateRequest struct {
// ID of router
// Required: true
RouterID string `url:"router_id" json:"router_id" validate:"required"`
// ID of gateway port
// Required: true
GatewayPortID string `url:"gateway_port_id" json:"gateway_port_id" validate:"required"`
// ID of version
// Required: true
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
// Detailed description of the external network
// Required: true
Description string `url:"description" json:"description" validate:"required"`
// External network port ID
// Required: true
ExternalNetworkPortID string `url:"external_network_port_id" json:"external_network_port_id" validate:"required"`
// Whether is enabled
// Required: true
Enabled bool `url:"snat_enabled" json:"snat_enabled"`
}
// Updated update a gateway port
func (i GWPort) Update(ctx context.Context, req UpdateRequest) (*GatewayPort, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/sdn/router/gateway_port/update"
res, err := i.client.DecortApiCallCtype(ctx, http.MethodPut, url, constants.MIMEJSON, req)
if err != nil {
return nil, err
}
info := GatewayPort{}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

10
pkg/sdn/routers/ids.go Normal file
View File

@@ -0,0 +1,10 @@
package routers
// IDs gets array of IDs from RoutersList struct
func (rl RoutersList) IDs() []string {
res := make([]string, 0, len(rl))
for _, c := range rl {
res = append(res, c.ID)
}
return res
}

90
pkg/sdn/routers/list.go Normal file
View File

@@ -0,0 +1,90 @@
package routers
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get a list of routers
type ListRequest struct {
// Filter by display name
// Required: false
DisplayName string `url:"display_name,omitempty" json:"display_name,omitempty"`
// Filter by enabled status
// Required: false
Enabled interface{} `url:"enabled,omitempty" json:"enabled,omitempty" validate:"omitempty,isBool"`
// Filter by access group ID
// Required: false
AccessGroupID string `url:"access_group_id,omitempty" json:"access_group_id,omitempty"`
// Filter by description
// Required: false
Description string `url:"description,omitempty" json:"description,omitempty"`
// Filter by create date from
// Required: false
CreatedFrom string `url:"created_from,omitempty" json:"created_from,omitempty"`
// Filter by create date to
// Required: false
CreatedTo string `url:"created_to,omitempty" json:"created_to,omitempty"`
// Filter by update date from
// Required: false
UpdatedFrom string `url:"updated_from,omitempty" json:"updated_from,omitempty"`
// Filter by update date to
// Required: false
UpdatedTo string `url:"updated_to,omitempty" json:"updated_to,omitempty"`
// Page number for pagination
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
// Number of results per page
// Required: false
PerPage uint64 `url:"per_page,omitempty" json:"per_page,omitempty"`
// Field to sort by (display_name, subnet, created_at, updated_at)
// Required: false
SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty" validate:"omitempty,oneof=display_name subnet created_at updated_at"`
// Sort order (asc/desc)
// Required: false
SortOrder string `url:"sort_order,omitempty" json:"sort_order,omitempty" validate:"omitempty,oneof=asc desc"`
}
// List of routers
func (i Routers) List(ctx context.Context, req ListRequest) (RoutersList, error) {
res, err := i.ListRaw(ctx, req)
if err != nil {
return nil, err
}
pools := []RoutersModel{}
err = json.Unmarshal(res, &pools)
if err != nil {
return nil, err
}
return pools, nil
}
// ListRaw gets a list of all routers as an array of bytes
func (a Routers) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/sdn/router/list"
res, err := a.client.DecortApiCall(ctx, http.MethodGet, url, req)
return res, err
}

523
pkg/sdn/routers/models.go Normal file
View File

@@ -0,0 +1,523 @@
package routers
// List of routers
type RoutersList []RoutersModel
// Main information about router
type RoutersModel 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"`
// Version ID
VersionID uint64 `json:"version_id"`
}
// Gateway port information
type GatewayPort struct {
// Created time
CreatedAt string `json:"created_at"`
// Description
Description string `json:"description"`
// External L4 port maximum
ExternalL4PortMax int `json:"external_l4_port_max"`
// External L4 port minimum
ExternalL4PortMin int `json:"external_l4_port_min"`
// External network port
ExternalNetworkPort ExternalNetworkPort `json:"external_network_port"`
// ID
ID string `json:"id"`
// SNAT enabled flag
SNATEnabled bool `json:"snat_enabled"`
// Status information
Status Status `json:"status"`
// Updated time
UpdatedAt string `json:"updated_at"`
// Version ID
VersionID uint64 `json:"version_id"`
}
// External network port information
type ExternalNetworkPort struct {
// Access group ID
AccessGroupID string `json:"access_group_id"`
// Access group name
AccessGroupName string `json:"access_group_name"`
// Comment
Comment string `json:"comment"`
// Display name
DisplayName string `json:"display_name"`
// Enabled flag
Enabled bool `json:"enabled"`
// IPv4 address
IPv4 string `json:"ipv4"`
// IPv6 address
IPv6 string `json:"ipv6"`
// IPv6 configuration
IPv6Config IPv6Config `json:"ipv6_config"`
// MAC address
MAC string `json:"mac"`
// Router gateway port
RouterGatewayPort RouterGatewayPort `json:"router_gateway_port"`
// Floating IP
FloatingIP FloatingIP `json:"floating_ip"`
}
// IPv6 configuration information
type IPv6Config struct {
// Address mode
AddressMode string `json:"address_mode"`
// Enable periodic RA flag
EnablePeriodicRA bool `json:"enable_periodic_ra"`
// Interval RA
IntervalRA int `json:"interval_ra"`
// Router preference
RouterPreference string `json:"router_preference"`
}
// Router gateway port information
type RouterGatewayPort struct {
// Created time
CreatedAt string `json:"created_at"`
// Description
Description string `json:"description"`
// ID
ID string `json:"id"`
// Router display name
RouterDisplayName string `json:"router_display_name"`
// Router ID
RouterID string `json:"router_id"`
// SNAT enabled flag
SNATEnabled bool `json:"snat_enabled"`
// Updated time
UpdatedAt string `json:"updated_at"`
}
// Floating IP information
type FloatingIP 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"`
// External network port
ExternalNetworkPort string `json:"external_network_port"`
// ID
ID string `json:"id"`
// Logical port
LogicalPort LogicalPort `json:"logical_port"`
// Router
Router string `json:"router"`
// Updated time
UpdatedAt string `json:"updated_at"`
// Version ID
VersionID uint64 `json:"version_id"`
}
// Logical port information
type LogicalPort struct {
// ID
ID string `json:"id"`
// Access group ID
AccessGroupID string `json:"access_group_id"`
// Access group name
AccessGroupName string `json:"access_group_name"`
// Adapter MAC
AdapterMAC string `json:"adapter_mac"`
// Address detection flag
AddressDetection bool `json:"address_detection"`
// Description
Description string `json:"description"`
// Created time
CreatedAt string `json:"created_at"`
// Display name
DisplayName string `json:"display_name"`
// Enabled flag
Enabled bool `json:"enabled"`
// External network ID
ExternalNetworkID string `json:"external_network_id"`
// Hypervisor
Hypervisor string `json:"hypervisor"`
// Hypervisor display name
HypervisorDisplayName string `json:"hypervisor_display_name"`
// Live migration target HV
LiveMigrationTargetHV string `json:"live_migration_target_hv"`
// Status information
Status Status `json:"status"`
// Bindings information
Bindings Bindings `json:"bindings"`
// Unique identifier
UniqueIdentifier string `json:"unique_identifier"`
// Updated time
UpdatedAt string `json:"updated_at"`
// Version ID
VersionID uint64 `json:"version_id"`
}
// Status information
type Status struct {
// Common status
Common string `json:"common"`
// Hypervisors status list
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"`
// Synced at time
SyncedAt string `json:"synced_at"`
}
// Bindings information
type Bindings struct {
// ID
ID string `json:"id"`
// Segment display name
SegmentDisplayName string `json:"segment_display_name"`
// Segment ID
SegmentID string `json:"segment_id"`
// Port security flag
PortSecurity bool `json:"port_security"`
// 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"`
// Created time
CreatedAt string `json:"created_at"`
// Updated time
UpdatedAt string `json:"updated_at"`
// Logical port addresses list
LogicalPortAddresses []LogicalPortAddress `json:"logical_port_addresses"`
}
// Logical port address information
type LogicalPortAddress struct {
// IP address
IP string `json:"ip"`
// IP type
IPType string `json:"ip_type"`
// Is discovered flag
IsDiscovered bool `json:"is_discovered"`
// Is primary flag
IsPrimary bool `json:"is_primary"`
// MAC address
MAC string `json:"mac"`
// ID
ID string `json:"id"`
// Logical port ID
LogicalPortID string `json:"logical_port_id"`
// Assigned at time
AssignedAt string `json:"assigned_at"`
}
// Policy information
type Policy struct {
// Action
Action string `json:"action"`
// Created time
CreatedAt string `json:"created_at"`
// Display name
DisplayName string `json:"display_name"`
// Enabled flag
Enabled bool `json:"enabled"`
// ID
ID string `json:"id"`
// Match criteria
Match map[string]interface{} `json:"match"`
// Next IPv4 addresses list
NextIPv4Address []string `json:"next_ipv4_address"`
// Next IPv6 addresses list
NextIPv6Address []string `json:"next_ipv6_address"`
// Priority
Priority int `json:"priority"`
// Updated time
UpdatedAt string `json:"updated_at"`
// Version ID
VersionID uint64 `json:"version_id"`
}
// Port information
type Port struct {
// Created time
CreatedAt string `json:"created_at"`
// Description
Description string `json:"description"`
// Enabled flag
Enabled bool `json:"enabled"`
// ID
ID string `json:"id"`
// IPv4 address
IPv4Address string `json:"ipv4_address"`
// IPv6 address
IPv6Address string `json:"ipv6_address"`
// IPv6 configuration
IPv6Config IPv6Config `json:"ipv6_config"`
// MAC address
MAC string `json:"mac"`
// Segment information
Segment Segment `json:"segment"`
// Segment ID
SegmentID string `json:"segment_id"`
// Status information
Status Status `json:"status"`
// Updated time
UpdatedAt string `json:"updated_at"`
// Version ID
VersionID uint64 `json:"version_id"`
}
// Segment information
type Segment 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"`
// DHCPv4 configuration
DHCPv4 DHCPv4 `json:"dhcp_v4"`
// DHCPv6 configuration
DHCPv6 DHCPv6 `json:"dhcp_v6"`
// Display name
DisplayName string `json:"display_name"`
// Enabled flag
Enabled bool `json:"enabled"`
// ID
ID string `json:"id"`
// Logical ports info list
LogicalPortsInfo []LogicalPortInfo `json:"logical_ports_info"`
// Routers info list
RoutersInfo []RouterInfo `json:"routers_info"`
// Status information
Status Status `json:"status"`
// IPv4 subnet
SubnetV4 string `json:"subnet_v4"`
// IPv6 subnet
SubnetV6 string `json:"subnet_v6"`
// Updated time
UpdatedAt string `json:"updated_at"`
// Version ID
VersionID uint64 `json:"version_id"`
}
// DHCPv4 configuration
type DHCPv4 struct {
// DNS servers list
DNS []string `json:"dns"`
// Excluded address ranges list
ExcludedAddressRanges []string `json:"excluded_address_ranges"`
// Gateway address
Gateway string `json:"gateway"`
// ID
ID string `json:"id"`
// Lease time
LeaseTime int `json:"lease_time"`
// Server IP
ServerIP string `json:"server_ip"`
// Server MAC
ServerMAC string `json:"server_mac"`
// Enabled flag
Enabled bool `json:"enabled"`
}
// DHCPv6 configuration
type DHCPv6 struct {
// Address prefix
AddressPrefix string `json:"address_prefix"`
// DNS servers list
DNS []string `json:"dns"`
// ID
ID string `json:"id"`
// Lease time
LeaseTime int `json:"lease_time"`
// Server MAC
ServerMAC string `json:"server_mac"`
// Enabled flag
Enabled bool `json:"enabled"`
}
// Logical port info
type LogicalPortInfo struct {
// Display name
DisplayName string `json:"display_name"`
// ID
ID string `json:"id"`
}
// Router info
type RouterInfo struct {
// Display name
DisplayName string `json:"display_name"`
// ID
ID string `json:"id"`
}

View File

@@ -0,0 +1,10 @@
package routers
import (
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/routers/policies"
)
// Accessing the routers policies method group
func (r *Routers) Policies() *policies.Policies {
return policies.New(r.client)
}

View File

@@ -0,0 +1,66 @@
package policies
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// ListRequest struct to get a list of policies
type ListRequest struct {
// Router ID
// Required: true
RouterID string `url:"router_id" json:"router_id" validate:"required"`
// Filter by display name
// Required: false
DisplayName string `url:"display_name,omitempty" json:"display_name,omitempty"`
// Page number for pagination
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
// Number of results per page
// Required: false
PerPage uint64 `url:"per_page,omitempty" json:"per_page,omitempty"`
// Field to sort by (display_name, subnet, created_at, updated_at)
// Required: false
SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty" validate:"omitempty,oneof=display_name subnet created_at updated_at"`
// Sort order (asc/desc)
// Required: false
SortOrder string `url:"sort_order,omitempty" json:"sort_order,omitempty" validate:"omitempty,oneof=asc desc"`
}
// List of policies
func (i Policies) List(ctx context.Context, req ListRequest) (PoliciesList, error) {
res, err := i.ListRaw(ctx, req)
if err != nil {
return nil, err
}
pools := []Policy{}
err = json.Unmarshal(res, &pools)
if err != nil {
return nil, err
}
return pools, nil
}
// ListRaw gets a list of all policies as an array of bytes
func (a Policies) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
if err := validators.ValidateRequest(req); err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/sdn/router/policies/list"
res, err := a.client.DecortApiCall(ctx, http.MethodGet, url, req)
return res, err
}

View File

@@ -0,0 +1,39 @@
package policies
type PoliciesList []Policy
// Policy information
type Policy struct {
// Action
Action string `json:"action"`
// Created time
CreatedAt string `json:"created_at"`
// Display name
DisplayName string `json:"display_name"`
// Enabled flag
Enabled bool `json:"enabled"`
// ID
ID string `json:"id"`
// Match criteria
Match map[string]interface{} `json:"match"`
// Next IPv4 addresses list
NextIPv4Address []string `json:"next_ipv4_address"`
// Next IPv6 addresses list
NextIPv6Address []string `json:"next_ipv6_address"`
// Priority
Priority int `json:"priority"`
// Updated time
UpdatedAt string `json:"updated_at"`
// Version ID
VersionID uint64 `json:"version_id"`
}

View File

@@ -0,0 +1,18 @@
// API Actor API for managing SDN routers policies
package policies
import (
"repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
)
// Structure for creating request to routers policies
type Policies struct {
client interfaces.Caller
}
// Builder for routers policies endpoints
func New(client interfaces.Caller) *Policies {
return &Policies{
client,
}
}

View File

@@ -0,0 +1,18 @@
// API Actor API for managing SDN routers
package routers
import (
"repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
)
// Structure for creating request to routers
type Routers struct {
client interfaces.Caller
}
// Builder for routers endpoints
func New(client interfaces.Caller) *Routers {
return &Routers{
client,
}
}

View File

@@ -0,0 +1,27 @@
package routers
import (
"encoding/json"
"repository.basistech.ru/BASIS/decort-golang-sdk/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 (la RoutersList) Serialize(params ...string) (serialization.Serialized, error) {
if len(la) == 0 {
return []byte{}, nil
}
if len(params) > 1 {
prefix := params[0]
indent := params[1]
return json.MarshalIndent(la, prefix, indent)
}
return json.Marshal(la)
}

57
pkg/sdn/routers/update.go Normal file
View File

@@ -0,0 +1,57 @@
package routers
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// UpdateRequest struct for update router
type UpdateRequest struct {
// ID of router
// Required: true
RouterID string `url:"router_id" json:"router_id" validate:"required"`
// ID of version
// Required: true
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
// Detailed description of the external network
// Required: true
Description string `url:"description" json:"description" validate:"required"`
// User-friendly name for the external network
// Required: true
DisplayName string `url:"display_name" json:"display_name" validate:"required"`
// Whether the network is enabled
// Required: true
Enabled bool `url:"enabled" json:"enabled"`
}
// Update updated a router
func (e Routers) Update(ctx context.Context, req UpdateRequest) (*RoutersModel, error) {
err := validators.ValidateRequest(req)
if err != nil {
return nil, validators.ValidationErrors(validators.GetErrors(err))
}
url := "/sdn/router/update"
res, err := e.client.DecortApiCallCtype(ctx, http.MethodPut, url, constants.MIMEJSON, req)
if err != nil {
return nil, err
}
info := RoutersModel{}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}