parent
562b6019d0
commit
0bf073da93
@ -0,0 +1,46 @@
|
||||
package acsgroups
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// GetGroupRequest struct to get an access group
|
||||
type GetGroupRequest struct {
|
||||
// ID of the access group
|
||||
// Required: true
|
||||
GroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
|
||||
}
|
||||
|
||||
// Info about access group
|
||||
func (i AccessGroups) Get(ctx context.Context, req GetGroupRequest) (*AccessGroup, error) {
|
||||
res, err := i.GetRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
group := AccessGroup{}
|
||||
|
||||
err = json.Unmarshal(res, &group)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &group, nil
|
||||
}
|
||||
|
||||
// GetRaw gets a details of group as an array of bytes
|
||||
func (a AccessGroups) GetRaw(ctx context.Context, req GetGroupRequest) ([]byte, error) {
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/access_group/get"
|
||||
|
||||
res, err := a.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
return res, err
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package sdn
|
||||
|
||||
import (
|
||||
ap "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/adrspools"
|
||||
)
|
||||
|
||||
// Accessing the SDN method group
|
||||
func (sdn *SDN) AddressPools() *ap.AddressPools {
|
||||
return ap.New(sdn.client)
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
// API Actor API for managing SDN adress pools
|
||||
package adrspools
|
||||
|
||||
import (
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
|
||||
)
|
||||
|
||||
// Structure for creating request to address pools
|
||||
type AddressPools struct {
|
||||
client interfaces.Caller
|
||||
}
|
||||
|
||||
// Builder for adress pools endpoints
|
||||
func New(client interfaces.Caller) *AddressPools {
|
||||
return &AddressPools{
|
||||
client,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,80 @@
|
||||
package adrspools
|
||||
|
||||
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 address pool
|
||||
type CreateRequest struct {
|
||||
// ID of the access group
|
||||
// Required: true
|
||||
AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
|
||||
|
||||
// Description of the network
|
||||
// Required: true
|
||||
Description string `url:"description" json:"description" validate:"required"`
|
||||
|
||||
// Name of the network
|
||||
// Required: true
|
||||
Name string `url:"name" json:"name" validate:"required"`
|
||||
|
||||
// Network address type
|
||||
// Required: true
|
||||
NetAddressType string `url:"net_address_type" json:"net_address_type" validate:"required,addressPoolNetTypeValidator"`
|
||||
|
||||
// List of network addresses
|
||||
// Required: false
|
||||
NetAddresses []NetAddress `url:"net_addresses,omitempty" json:"net_addresses,omitempty" validate:"dive"`
|
||||
}
|
||||
|
||||
// NetAddress struct representing network address
|
||||
type NetAddress struct {
|
||||
// Network address type
|
||||
// Required: true
|
||||
NetAddressType string `url:"net_address_type" json:"net_address_type" validate:"required,addressPoolNetTypeValidator"`
|
||||
|
||||
// IP address
|
||||
// Required: true
|
||||
IPAddr string `url:"ip_addr" json:"ip_addr" validate:"required"`
|
||||
|
||||
// End of IP address range
|
||||
// Required: false
|
||||
IPAddrRangeEnd string `url:"ip_addr_range_end,omitempty" json:"ip_addr_range_end,omitempty"`
|
||||
|
||||
// IP prefix
|
||||
// Required: false
|
||||
IPPrefix string `url:"ip_prefix,omitempty" json:"ip_prefix,omitempty"`
|
||||
|
||||
// MAC address
|
||||
// Required: false
|
||||
MACAddr string `url:"mac_addr,omitempty" json:"mac_addr,omitempty"`
|
||||
}
|
||||
|
||||
// Create creates a address pool
|
||||
func (i AddressPools) Create(ctx context.Context, req CreateRequest) (*NetworkAddressPool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/address_pool/create"
|
||||
|
||||
res, err := i.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := NetworkAddressPool{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package adrspools
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// DeleteRequest struct to delete address pool
|
||||
type DeleteRequest struct {
|
||||
// Address pool ID
|
||||
// Required: true
|
||||
AddressPoolID string `url:"address_pool_id" json:"address_pool_id" validate:"required"`
|
||||
|
||||
// Version ID
|
||||
// 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 an address pool
|
||||
func (i AddressPools) Delete(ctx context.Context, req DeleteRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/address_pool/delete"
|
||||
|
||||
res, err := i.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
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package adrspools
|
||||
|
||||
// FilterByID returns AddressPoolsList with specified ID.
|
||||
func (agl AddressPoolsList) FilterByID(id string) AddressPoolsList {
|
||||
predicate := func(ia NetworkAddressPool) bool {
|
||||
return ia.ID == id
|
||||
}
|
||||
|
||||
return agl.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterByName returns AddressPoolsList with specified Name.
|
||||
func (agl AddressPoolsList) FilterByName(name string) AddressPoolsList {
|
||||
predicate := func(ia NetworkAddressPool) bool {
|
||||
return ia.Name == name
|
||||
}
|
||||
|
||||
return agl.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterFunc allows filtering AddressPoolsList based on a user-specified predicate.
|
||||
func (agl AddressPoolsList) FilterFunc(predicate func(NetworkAddressPool) bool) AddressPoolsList {
|
||||
var result AddressPoolsList
|
||||
|
||||
for _, acc := range agl.Pools {
|
||||
if predicate(acc) {
|
||||
result.Pools = append(result.Pools, acc)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// FindOne returns first element.
|
||||
// If none was found, returns an empty struct.
|
||||
func (agl AddressPoolsList) FindOne() NetworkAddressPool {
|
||||
if len(agl.Pools) == 0 {
|
||||
return NetworkAddressPool{}
|
||||
}
|
||||
|
||||
return agl.Pools[0]
|
||||
}
|
||||
@ -0,0 +1,151 @@
|
||||
package adrspools
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var testAddressPools = AddressPoolsList{
|
||||
Pools: []NetworkAddressPool{
|
||||
{
|
||||
ID: "pool1",
|
||||
Name: "DevelopersPool",
|
||||
Description: "First pool",
|
||||
CreatedAt: "2023-01-01",
|
||||
AccessGroupID: "group1",
|
||||
AccessGroupName: "Developers",
|
||||
NetAddressType: "IPv4",
|
||||
NetAddresses: []NetworkAddress{
|
||||
{
|
||||
ID: "addr1",
|
||||
IPAddr: "192.168.1.1",
|
||||
NetAddressType: "IPv4",
|
||||
NetAddressPoolID: "pool1",
|
||||
},
|
||||
},
|
||||
PoolCounters: PoolCounters{
|
||||
SecurityRules: 5,
|
||||
},
|
||||
VersionID: 1,
|
||||
},
|
||||
{
|
||||
ID: "pool2",
|
||||
Name: "AdminsPool",
|
||||
Description: "Second pool",
|
||||
CreatedAt: "2023-01-02",
|
||||
AccessGroupID: "group2",
|
||||
AccessGroupName: "Admins",
|
||||
NetAddressType: "IPv4",
|
||||
NetAddresses: []NetworkAddress{
|
||||
{
|
||||
ID: "addr2",
|
||||
IPAddr: "192.168.1.2",
|
||||
NetAddressType: "IPv4",
|
||||
NetAddressPoolID: "pool2",
|
||||
},
|
||||
},
|
||||
PoolCounters: PoolCounters{
|
||||
SecurityRules: 3,
|
||||
},
|
||||
VersionID: 2,
|
||||
},
|
||||
{
|
||||
ID: "pool3",
|
||||
Name: "UsersPool",
|
||||
Description: "Third pool",
|
||||
CreatedAt: "2023-01-03",
|
||||
AccessGroupID: "group3",
|
||||
AccessGroupName: "Users",
|
||||
NetAddressType: "IPv6",
|
||||
NetAddresses: []NetworkAddress{
|
||||
{
|
||||
ID: "addr3",
|
||||
IPAddr: "2001:db8::1",
|
||||
NetAddressType: "IPv6",
|
||||
NetAddressPoolID: "pool3",
|
||||
},
|
||||
},
|
||||
PoolCounters: PoolCounters{
|
||||
SecurityRules: 7,
|
||||
},
|
||||
VersionID: 3,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestFilterByID(t *testing.T) {
|
||||
actual := testAddressPools.FilterByID("pool2").FindOne()
|
||||
|
||||
if actual.ID != "pool2" {
|
||||
t.Fatal("actual:", actual.ID, "> expected: pool2")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByName(t *testing.T) {
|
||||
actual := testAddressPools.FilterByName("UsersPool").FindOne()
|
||||
|
||||
if actual.Name != "UsersPool" {
|
||||
t.Fatal("actual:", actual.Name, ">> expected: UsersPool")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterFunc(t *testing.T) {
|
||||
actual := testAddressPools.FilterFunc(func(ap NetworkAddressPool) bool {
|
||||
return ap.Description == "Second pool"
|
||||
})
|
||||
|
||||
if len(actual.Pools) != 1 || actual.Pools[0].ID != "pool2" {
|
||||
t.Fatal("Expected 1 pool with description 'Second pool', found:", len(actual.Pools))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindOneWithResults(t *testing.T) {
|
||||
result := testAddressPools.FilterByID("pool1").FindOne()
|
||||
if result.ID != "pool1" {
|
||||
t.Fatal("Expected pool1, got:", result.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindOneEmpty(t *testing.T) {
|
||||
emptyList := AddressPoolsList{}
|
||||
result := emptyList.FindOne()
|
||||
|
||||
if result.ID != "" || result.Name != "" {
|
||||
t.Fatal("Expected empty NetworkAddressPool, got:", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByIDNotFound(t *testing.T) {
|
||||
actual := testAddressPools.FilterByID("nonexistent")
|
||||
|
||||
if len(actual.Pools) != 0 {
|
||||
t.Fatal("Expected 0 pools, found:", len(actual.Pools))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByNameNotFound(t *testing.T) {
|
||||
actual := testAddressPools.FilterByName("Nonexistent Pool")
|
||||
|
||||
if len(actual.Pools) != 0 {
|
||||
t.Fatal("Expected 0 pools, found:", len(actual.Pools))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByNetAddressType(t *testing.T) {
|
||||
actual := testAddressPools.FilterFunc(func(ap NetworkAddressPool) bool {
|
||||
return ap.NetAddressType == "IPv6"
|
||||
})
|
||||
|
||||
if len(actual.Pools) != 1 || actual.Pools[0].ID != "pool3" {
|
||||
t.Fatal("Expected 1 pool with IPv6 type, found:", len(actual.Pools))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterBySecurityRulesCount(t *testing.T) {
|
||||
actual := testAddressPools.FilterFunc(func(ap NetworkAddressPool) bool {
|
||||
return ap.PoolCounters.SecurityRules > 4
|
||||
})
|
||||
|
||||
if len(actual.Pools) != 2 {
|
||||
t.Fatal("Expected 2 pools with more than 4 security rules, found:", len(actual.Pools))
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package adrspools
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// GetRequest struct to get information about address group
|
||||
type GetRequest struct {
|
||||
// ID an address group
|
||||
// Required: true
|
||||
ID string `url:"address_pool_id" json:"address_pool_id" validate:"required"`
|
||||
}
|
||||
|
||||
// Get gets address pool details as a NetworkAddressPool struct
|
||||
func (a AddressPools) Get(ctx context.Context, req GetRequest) (*NetworkAddressPool, error) {
|
||||
res, err := a.GetRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := NetworkAddressPool{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
|
||||
}
|
||||
|
||||
// GetRaw gets address pool details as an array of bytes
|
||||
func (a AddressPools) GetRaw(ctx context.Context, req GetRequest) ([]byte, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/address_pool/get"
|
||||
|
||||
res, err := a.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
return res, err
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package adrspools
|
||||
|
||||
// IDs gets array of IDs from AddressPoolsList struct
|
||||
func (agl AddressPoolsList) IDs() []string {
|
||||
res := make([]string, 0, len(agl.Pools))
|
||||
for _, c := range agl.Pools {
|
||||
res = append(res, c.ID)
|
||||
}
|
||||
return res
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
package adrspools
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// ListAddressPoolsRequest struct to get a list of a groups
|
||||
type ListAddressPoolsRequest struct {
|
||||
// Filter by access group ID
|
||||
// Required: false
|
||||
AccessGroupID string `url:"access_group_id,omitempty" json:"access_group_id,omitempty"`
|
||||
|
||||
// Filter by name
|
||||
// Required: false
|
||||
Name string `url:"name,omitempty" json:"name,omitempty"`
|
||||
|
||||
// Filter by minimum address count (greater than or equal to)
|
||||
// Required: false
|
||||
AddrNumberMin uint64 `url:"addr_number_min,omitempty" json:"addr_number_min,omitempty"`
|
||||
|
||||
// Filter by maximum address count (less than)
|
||||
// Required: false
|
||||
AddrNumberMax uint64 `url:"addr_number_max,omitempty" json:"addr_number_max,omitempty"`
|
||||
|
||||
// Updated at lower bound (greater than or equal to)
|
||||
// Required: false
|
||||
UpdatedFrom string `url:"updated_from,omitempty" json:"updated_from,omitempty"`
|
||||
|
||||
// Updated at upper bound (less than)
|
||||
// Required: false
|
||||
UpdatedTo string `url:"updated_to,omitempty" json:"updated_to,omitempty"`
|
||||
|
||||
// Created at lower bound (greater than or equal to)
|
||||
// Required: false
|
||||
CreatedFrom string `url:"created_from,omitempty" json:"created_from,omitempty"`
|
||||
|
||||
// Created at upper bound (less than)
|
||||
// Required: false
|
||||
CreatedTo string `url:"created_to,omitempty" json:"created_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 (name, addr_count, created_at, updated_at)
|
||||
// Required: false
|
||||
SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty"`
|
||||
|
||||
// Sort order (asc/desc)
|
||||
// Required: false
|
||||
SortOrder string `url:"sort_order,omitempty" json:"sort_order,omitempty"`
|
||||
}
|
||||
|
||||
// List of address pools
|
||||
func (i AddressPools) List(ctx context.Context, req ListAddressPoolsRequest) (*AddressPoolsList, error) {
|
||||
res, err := i.ListRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pools := []NetworkAddressPool{}
|
||||
|
||||
err = json.Unmarshal(res, &pools)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := AddressPoolsList{Pools: pools}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// ListRaw gets a list of all address pools as an array of bytes
|
||||
func (a AddressPools) ListRaw(ctx context.Context, req ListAddressPoolsRequest) ([]byte, error) {
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/access_group/list"
|
||||
|
||||
res, err := a.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
return res, err
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
package adrspools
|
||||
|
||||
type AddressPoolsList struct {
|
||||
Pools []NetworkAddressPool
|
||||
}
|
||||
|
||||
// Main information about network address pool
|
||||
type NetworkAddressPool 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"`
|
||||
|
||||
// Updated time
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
|
||||
// Description
|
||||
Description string `json:"description"`
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Name
|
||||
Name string `json:"name"`
|
||||
|
||||
// Network address type
|
||||
NetAddressType string `json:"net_address_type"`
|
||||
|
||||
// List of network addresses
|
||||
NetAddresses []NetworkAddress `json:"net_addresses"`
|
||||
|
||||
// Pool counters
|
||||
PoolCounters PoolCounters `json:"pool_counters"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
// Network address information
|
||||
type NetworkAddress struct {
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// IP address
|
||||
IPAddr string `json:"ip_addr"`
|
||||
|
||||
// Network address type
|
||||
NetAddressType string `json:"net_address_type"`
|
||||
|
||||
// Network address pool ID
|
||||
NetAddressPoolID string `json:"net_address_pool_id"`
|
||||
}
|
||||
|
||||
// Pool counters information
|
||||
type PoolCounters struct {
|
||||
// Security rules count
|
||||
SecurityRules uint64 `json:"security_rules"`
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package adrspools
|
||||
|
||||
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 AddressPoolsList) Serialize(params ...string) (serialization.Serialized, error) {
|
||||
if len(la.Pools) == 0 {
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
if len(params) > 1 {
|
||||
prefix := params[0]
|
||||
indent := params[1]
|
||||
|
||||
return json.MarshalIndent(la, prefix, indent)
|
||||
}
|
||||
|
||||
return json.Marshal(la)
|
||||
}
|
||||
|
||||
// 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 (ia NetworkAddressPool) Serialize(params ...string) (serialization.Serialized, error) {
|
||||
if len(params) > 1 {
|
||||
prefix := params[0]
|
||||
indent := params[1]
|
||||
|
||||
return json.MarshalIndent(ia, prefix, indent)
|
||||
}
|
||||
|
||||
return json.Marshal(ia)
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
package adrspools
|
||||
|
||||
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 address pool
|
||||
type UpdateRequest struct {
|
||||
// ID of the address pool
|
||||
// Required: true
|
||||
AddressPoolID string `url:"address_pool_id" json:"address_pool_id" validate:"required"`
|
||||
|
||||
// ID of the version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// Description of the network
|
||||
// Required: true
|
||||
Description string `url:"description" json:"description" validate:"required"`
|
||||
|
||||
// Name of the network
|
||||
// Required: true
|
||||
Name string `url:"name" json:"name" validate:"required"`
|
||||
|
||||
// Network address type
|
||||
// Required: true
|
||||
NetAddressType string `url:"net_address_type" json:"net_address_type" validate:"required,addressPoolNetTypeValidator"`
|
||||
|
||||
// List of network addresses
|
||||
// Required: false
|
||||
NetAddresses []UpdateNetAddress `url:"net_addresses,omitempty" json:"net_addresses,omitempty" validate:"dive"`
|
||||
}
|
||||
|
||||
// UpdateNetAddress struct representing network address
|
||||
type UpdateNetAddress struct {
|
||||
// Network address type
|
||||
// Required: true
|
||||
NetAddressType string `url:"net_address_type" json:"net_address_type" validate:"required,addressPoolNetTypeValidator"`
|
||||
|
||||
// IP address
|
||||
// Required: true
|
||||
IPAddr string `url:"ip_addr" json:"ip_addr" validate:"required"`
|
||||
|
||||
// End of IP address range
|
||||
// Required: false
|
||||
IPAddrRangeEnd string `url:"ip_addr_range_end,omitempty" json:"ip_addr_range_end,omitempty"`
|
||||
|
||||
// IP prefix
|
||||
// Required: false
|
||||
IPPrefix string `url:"ip_prefix,omitempty" json:"ip_prefix,omitempty"`
|
||||
|
||||
// MAC address
|
||||
// Required: false
|
||||
MACAddr string `url:"mac_addr,omitempty" json:"mac_addr,omitempty"`
|
||||
}
|
||||
|
||||
// Update updates a address pool
|
||||
func (i AddressPools) Update(ctx context.Context, req UpdateRequest) (*NetworkAddressPool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/address_pool/update"
|
||||
|
||||
res, err := i.client.DecortApiCallCtype(ctx, http.MethodPut, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := NetworkAddressPool{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package sdn
|
||||
|
||||
import (
|
||||
dsp "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/defsecpolicies"
|
||||
)
|
||||
|
||||
// Accessing the SDN method group
|
||||
func (sdn *SDN) DefaultSecurityPolicies() *dsp.DefaultSecurityPolicies {
|
||||
return dsp.New(sdn.client)
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
// API Actor API for managing SDN default secirity policies
|
||||
package defsecpolicies
|
||||
|
||||
import (
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
|
||||
)
|
||||
|
||||
// Structure for creating request to default security policies
|
||||
type DefaultSecurityPolicies struct {
|
||||
client interfaces.Caller
|
||||
}
|
||||
|
||||
// Builder for adress pools endpoints
|
||||
func New(client interfaces.Caller) *DefaultSecurityPolicies {
|
||||
return &DefaultSecurityPolicies{
|
||||
client,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package defsecpolicies
|
||||
|
||||
// FilterByID returns SecurityPoliciesList with specified ID.
|
||||
func (agl SecurityPoliciesList) FilterByID(id string) SecurityPoliciesList {
|
||||
predicate := func(ia SecurityPolicy) bool {
|
||||
return ia.ID == id
|
||||
}
|
||||
|
||||
return agl.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterByName returns SecurityPoliciesList with specified Name.
|
||||
func (agl SecurityPoliciesList) FilterByName(name string) SecurityPoliciesList {
|
||||
predicate := func(ia SecurityPolicy) bool {
|
||||
return ia.DisplayName == name
|
||||
}
|
||||
|
||||
return agl.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterFunc allows filtering SecurityPoliciesList based on a user-specified predicate.
|
||||
func (agl SecurityPoliciesList) FilterFunc(predicate func(SecurityPolicy) bool) SecurityPoliciesList {
|
||||
var result SecurityPoliciesList
|
||||
|
||||
for _, acc := range agl.Policies {
|
||||
if predicate(acc) {
|
||||
result.Policies = append(result.Policies, acc)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// FindOne returns first element.
|
||||
// If none was found, returns an empty struct.
|
||||
func (agl SecurityPoliciesList) FindOne() SecurityPolicy {
|
||||
if len(agl.Policies) == 0 {
|
||||
return SecurityPolicy{}
|
||||
}
|
||||
|
||||
return agl.Policies[0]
|
||||
}
|
||||
@ -0,0 +1,268 @@
|
||||
package defsecpolicies
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var testSecurityPolicies = SecurityPoliciesList{
|
||||
Policies: []SecurityPolicy{
|
||||
{
|
||||
ID: "policy1",
|
||||
DisplayName: "DevelopersPolicy",
|
||||
Description: "First policy",
|
||||
CreatedAt: "2023-01-01T00:00:00Z",
|
||||
UpdatedAt: "2023-01-01T01:00:00Z",
|
||||
AccessGroupID: "group1",
|
||||
DefaultACLDrop: "DROP",
|
||||
DefaultOpenSessionDrop: true,
|
||||
SecurityRules: []SecurityRule{
|
||||
{
|
||||
ID: "rule1",
|
||||
DisplayName: "DevRule1",
|
||||
Action: "ALLOW",
|
||||
Direction: "INGRESS",
|
||||
Enabled: true,
|
||||
Priority: 100,
|
||||
SecurityPolicyID: "policy1",
|
||||
VersionID: 1,
|
||||
},
|
||||
},
|
||||
Status: Status{
|
||||
Common: "ACTIVE",
|
||||
Hypervisors: []HypervisorStatus{
|
||||
{
|
||||
Name: "hv1",
|
||||
DisplayName: "Hypervisor1",
|
||||
Status: "SYNCED",
|
||||
HypervisorStatus: "HEALTHY",
|
||||
SyncedAt: "2023-01-01T01:00:00Z",
|
||||
},
|
||||
},
|
||||
},
|
||||
VersionID: 1,
|
||||
},
|
||||
{
|
||||
ID: "policy2",
|
||||
DisplayName: "AdminsPolicy",
|
||||
Description: "Second policy",
|
||||
CreatedAt: "2023-01-02T00:00:00Z",
|
||||
UpdatedAt: "2023-01-02T01:00:00Z",
|
||||
AccessGroupID: "group2",
|
||||
DefaultACLDrop: "REJECT",
|
||||
DefaultOpenSessionDrop: false,
|
||||
SecurityRules: []SecurityRule{
|
||||
{
|
||||
ID: "rule2",
|
||||
DisplayName: "AdminRule1",
|
||||
Action: "DENY",
|
||||
Direction: "EGRESS",
|
||||
Enabled: true,
|
||||
Priority: 50,
|
||||
SecurityPolicyID: "policy2",
|
||||
VersionID: 1,
|
||||
},
|
||||
},
|
||||
Status: Status{
|
||||
Common: "ACTIVE",
|
||||
Hypervisors: []HypervisorStatus{
|
||||
{
|
||||
Name: "hv2",
|
||||
DisplayName: "Hypervisor2",
|
||||
Status: "SYNCED",
|
||||
HypervisorStatus: "HEALTHY",
|
||||
SyncedAt: "2023-01-02T01:00:00Z",
|
||||
},
|
||||
},
|
||||
},
|
||||
VersionID: 2,
|
||||
},
|
||||
{
|
||||
ID: "policy3",
|
||||
DisplayName: "UsersPolicy",
|
||||
Description: "Third policy",
|
||||
CreatedAt: "2023-01-03T00:00:00Z",
|
||||
UpdatedAt: "2023-01-03T01:00:00Z",
|
||||
AccessGroupID: "group3",
|
||||
DefaultACLDrop: "DROP",
|
||||
DefaultOpenSessionDrop: true,
|
||||
SecurityRules: []SecurityRule{
|
||||
{
|
||||
ID: "rule3",
|
||||
DisplayName: "UserRule1",
|
||||
Action: "ALLOW",
|
||||
Direction: "INGRESS",
|
||||
Enabled: false,
|
||||
Priority: 200,
|
||||
SecurityPolicyID: "policy3",
|
||||
VersionID: 1,
|
||||
},
|
||||
},
|
||||
Status: Status{
|
||||
Common: "PENDING",
|
||||
Hypervisors: []HypervisorStatus{
|
||||
{
|
||||
Name: "hv3",
|
||||
DisplayName: "Hypervisor3",
|
||||
Status: "SYNCING",
|
||||
HypervisorStatus: "HEALTHY",
|
||||
SyncedAt: "2023-01-03T01:00:00Z",
|
||||
},
|
||||
},
|
||||
},
|
||||
VersionID: 3,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestFilterByID(t *testing.T) {
|
||||
actual := testSecurityPolicies.FilterByID("policy2").FindOne()
|
||||
|
||||
if actual.ID != "policy2" {
|
||||
t.Fatal("actual:", actual.ID, "> expected: policy2")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByDisplayName(t *testing.T) {
|
||||
actual := testSecurityPolicies.FilterByName("UsersPolicy").FindOne()
|
||||
|
||||
if actual.DisplayName != "UsersPolicy" {
|
||||
t.Fatal("actual:", actual.DisplayName, ">> expected: UsersPolicy")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterFunc(t *testing.T) {
|
||||
actual := testSecurityPolicies.FilterFunc(func(sp SecurityPolicy) bool {
|
||||
return sp.Description == "Second policy"
|
||||
})
|
||||
|
||||
if len(actual.Policies) != 1 || actual.Policies[0].ID != "policy2" {
|
||||
t.Fatal("Expected 1 policy with description 'Second policy', found:", len(actual.Policies))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindOneWithResults(t *testing.T) {
|
||||
result := testSecurityPolicies.FilterByID("policy1").FindOne()
|
||||
if result.ID != "policy1" {
|
||||
t.Fatal("Expected policy1, got:", result.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindOneEmpty(t *testing.T) {
|
||||
emptyList := SecurityPoliciesList{}
|
||||
result := emptyList.FindOne()
|
||||
|
||||
if result.ID != "" || result.DisplayName != "" {
|
||||
t.Fatal("Expected empty SecurityPolicy, got:", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByIDNotFound(t *testing.T) {
|
||||
actual := testSecurityPolicies.FilterByID("nonexistent")
|
||||
|
||||
if len(actual.Policies) != 0 {
|
||||
t.Fatal("Expected 0 policies, found:", len(actual.Policies))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByDisplayNameNotFound(t *testing.T) {
|
||||
actual := testSecurityPolicies.FilterByName("Nonexistent Policy")
|
||||
|
||||
if len(actual.Policies) != 0 {
|
||||
t.Fatal("Expected 0 policies, found:", len(actual.Policies))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByDefaultACLDrop(t *testing.T) {
|
||||
actual := testSecurityPolicies.FilterFunc(func(sp SecurityPolicy) bool {
|
||||
return sp.DefaultACLDrop == "DROP"
|
||||
})
|
||||
|
||||
if len(actual.Policies) != 2 {
|
||||
t.Fatal("Expected 2 policies with DROP default ACL, found:", len(actual.Policies))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByDefaultOpenSessionDrop(t *testing.T) {
|
||||
actual := testSecurityPolicies.FilterFunc(func(sp SecurityPolicy) bool {
|
||||
return sp.DefaultOpenSessionDrop == true
|
||||
})
|
||||
|
||||
if len(actual.Policies) != 2 {
|
||||
t.Fatal("Expected 2 policies with default open session drop enabled, found:", len(actual.Policies))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByStatus(t *testing.T) {
|
||||
actual := testSecurityPolicies.FilterFunc(func(sp SecurityPolicy) bool {
|
||||
return sp.Status.Common == "ACTIVE"
|
||||
})
|
||||
|
||||
if len(actual.Policies) != 2 {
|
||||
t.Fatal("Expected 2 policies with ACTIVE status, found:", len(actual.Policies))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByAccessGroupID(t *testing.T) {
|
||||
actual := testSecurityPolicies.FilterFunc(func(sp SecurityPolicy) bool {
|
||||
return sp.AccessGroupID == "group1"
|
||||
})
|
||||
|
||||
if len(actual.Policies) != 1 || actual.Policies[0].ID != "policy1" {
|
||||
t.Fatal("Expected 1 policy with access group ID 'group1', found:", len(actual.Policies))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByRuleAction(t *testing.T) {
|
||||
actual := testSecurityPolicies.FilterFunc(func(sp SecurityPolicy) bool {
|
||||
for _, rule := range sp.SecurityRules {
|
||||
if rule.Action == "ALLOW" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
if len(actual.Policies) != 2 {
|
||||
t.Fatal("Expected 2 policies with ALLOW rules, found:", len(actual.Policies))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByRuleDirection(t *testing.T) {
|
||||
actual := testSecurityPolicies.FilterFunc(func(sp SecurityPolicy) bool {
|
||||
for _, rule := range sp.SecurityRules {
|
||||
if rule.Direction == "INGRESS" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
if len(actual.Policies) != 2 {
|
||||
t.Fatal("Expected 2 policies with INGRESS rules, found:", len(actual.Policies))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByRuleEnabled(t *testing.T) {
|
||||
actual := testSecurityPolicies.FilterFunc(func(sp SecurityPolicy) bool {
|
||||
for _, rule := range sp.SecurityRules {
|
||||
if rule.Enabled {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
if len(actual.Policies) != 2 {
|
||||
t.Fatal("Expected 2 policies with enabled rules, found:", len(actual.Policies))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByVersionID(t *testing.T) {
|
||||
actual := testSecurityPolicies.FilterFunc(func(sp SecurityPolicy) bool {
|
||||
return sp.VersionID > 1
|
||||
})
|
||||
|
||||
if len(actual.Policies) != 2 {
|
||||
t.Fatal("Expected 2 policies with version ID > 1, found:", len(actual.Policies))
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package defsecpolicies
|
||||
|
||||
// IDs gets array of IDs from SecurityPoliciesList struct
|
||||
func (spl SecurityPoliciesList) IDs() []string {
|
||||
res := make([]string, 0, len(spl.Policies))
|
||||
for _, c := range spl.Policies {
|
||||
res = append(res, c.ID)
|
||||
}
|
||||
return res
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
package defsecpolicies
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// ListRequest struct to get a list of default security group
|
||||
type ListRequest struct {
|
||||
// Filter by access group ID
|
||||
// Required: false
|
||||
AccessGroupID string `url:"access_group_id,omitempty" json:"access_group_id,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 (name, addr_count, created_at, updated_at)
|
||||
// Required: false
|
||||
SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty"`
|
||||
|
||||
// Sort order (asc/desc)
|
||||
// Required: false
|
||||
SortOrder string `url:"sort_order,omitempty" json:"sort_order,omitempty"`
|
||||
}
|
||||
|
||||
// List of default security policies
|
||||
func (i DefaultSecurityPolicies) List(ctx context.Context, req ListRequest) (*SecurityPoliciesList, error) {
|
||||
res, err := i.ListRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
policies := []SecurityPolicy{}
|
||||
|
||||
err = json.Unmarshal(res, &policies)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := SecurityPoliciesList{Policies: policies}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// ListRaw gets a list of all default security policies as an array of bytes
|
||||
func (a DefaultSecurityPolicies) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/default_security_policy/list"
|
||||
|
||||
res, err := a.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
return res, err
|
||||
}
|
||||
@ -0,0 +1,191 @@
|
||||
package defsecpolicies
|
||||
|
||||
type SecurityPoliciesList struct {
|
||||
Policies []SecurityPolicy `json:"policies"`
|
||||
}
|
||||
|
||||
// Main information about security policy
|
||||
type SecurityPolicy struct {
|
||||
// Access group ID
|
||||
AccessGroupID string `json:"access_group_id"`
|
||||
|
||||
// Created time
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// Default ACL drop behavior
|
||||
DefaultACLDrop string `json:"default_acl_drop"`
|
||||
|
||||
// Default open session drop flag
|
||||
DefaultOpenSessionDrop bool `json:"default_open_session_drop"`
|
||||
|
||||
// Description
|
||||
Description string `json:"description"`
|
||||
|
||||
// Display name
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Security rules
|
||||
SecurityRules []SecurityRule `json:"security_rules"`
|
||||
|
||||
// Locked time
|
||||
LockedAt string `json:"locked_at"`
|
||||
|
||||
// Status information
|
||||
Status Status `json:"status"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
|
||||
// Updated time
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
// Security rule information
|
||||
type SecurityRule struct {
|
||||
// Access group ID
|
||||
AccessGroupID string `json:"access_group_id"`
|
||||
|
||||
// Action
|
||||
Action string `json:"action"`
|
||||
|
||||
// Description
|
||||
Description string `json:"description"`
|
||||
|
||||
// Destination network object
|
||||
DestinationNetObject NetObject `json:"destination_net_object"`
|
||||
|
||||
// Direction
|
||||
Direction string `json:"direction"`
|
||||
|
||||
// Display name
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Enabled flag
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// Filter configuration
|
||||
Filter Filter `json:"filter"`
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Log enabled flag
|
||||
LogEnabled bool `json:"log_enabled"`
|
||||
|
||||
// Log name
|
||||
LogName string `json:"log_name"`
|
||||
|
||||
// Log severity
|
||||
LogSeverity string `json:"log_severity"`
|
||||
|
||||
// Priority
|
||||
Priority int `json:"priority"`
|
||||
|
||||
// Security policy ID
|
||||
SecurityPolicyID string `json:"security_policy_id"`
|
||||
|
||||
// Source network object
|
||||
SourceNetObject NetObject `json:"source_net_object"`
|
||||
|
||||
// Statistics enabled flag
|
||||
StatisticsEnabled bool `json:"statistics_enabled"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
// Network object information
|
||||
type NetObject struct {
|
||||
// Display name
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Network address pool ID
|
||||
NetAddressPoolID string `json:"net_address_pool_id"`
|
||||
|
||||
// Network object group ID
|
||||
NetObjectGroupID string `json:"net_object_group_id"`
|
||||
}
|
||||
|
||||
// Filter configuration
|
||||
type Filter struct {
|
||||
// Filter parameters
|
||||
Filters FilterParams `json:"filters"`
|
||||
|
||||
// Name
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// Filter parameters
|
||||
type FilterParams struct {
|
||||
// All protocols flag
|
||||
All bool `json:"all"`
|
||||
|
||||
// ARP protocol flag
|
||||
ARP bool `json:"arp"`
|
||||
|
||||
// DHCP protocol flag
|
||||
DHCP bool `json:"dhcp"`
|
||||
|
||||
// Filter expression
|
||||
Expression string `json:"expression"`
|
||||
|
||||
// ICMP protocol flag
|
||||
ICMP bool `json:"icmp"`
|
||||
|
||||
// IP protocol flag
|
||||
IP bool `json:"ip"`
|
||||
|
||||
// IPv4 protocol flag
|
||||
IPv4 bool `json:"ip_v4"`
|
||||
|
||||
// IPv6 protocol flag
|
||||
IPv6 bool `json:"ip_v6"`
|
||||
|
||||
// Keep opened sessions flag
|
||||
KeepOpenedSessions bool `json:"keep_opened_sessions"`
|
||||
|
||||
// ND protocol flag
|
||||
ND bool `json:"nd"`
|
||||
|
||||
// TCP protocol flag
|
||||
TCP bool `json:"tcp"`
|
||||
|
||||
// TCP destination ports
|
||||
TCPDstPorts []string `json:"tcp_dst_ports"`
|
||||
|
||||
// UDP protocol flag
|
||||
UDP bool `json:"udp"`
|
||||
|
||||
// UDP destination ports
|
||||
UDPDstPorts []string `json:"udp_dst_ports"`
|
||||
}
|
||||
|
||||
// Status information
|
||||
type Status struct {
|
||||
// Common status
|
||||
Common string `json:"common"`
|
||||
|
||||
// Hypervisor statuses
|
||||
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"`
|
||||
|
||||
// Last sync time
|
||||
SyncedAt string `json:"synced_at"`
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package defsecpolicies
|
||||
|
||||
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 SecurityPoliciesList) Serialize(params ...string) (serialization.Serialized, error) {
|
||||
if len(la.Policies) == 0 {
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
if len(params) > 1 {
|
||||
prefix := params[0]
|
||||
indent := params[1]
|
||||
|
||||
return json.MarshalIndent(la, prefix, indent)
|
||||
}
|
||||
|
||||
return json.Marshal(la)
|
||||
}
|
||||
|
||||
// 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 (ia SecurityPolicy) Serialize(params ...string) (serialization.Serialized, error) {
|
||||
if len(params) > 1 {
|
||||
prefix := params[0]
|
||||
indent := params[1]
|
||||
|
||||
return json.MarshalIndent(ia, prefix, indent)
|
||||
}
|
||||
|
||||
return json.Marshal(ia)
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
package defsecpolicies
|
||||
|
||||
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 default security policy
|
||||
type UpdateRequest struct {
|
||||
// ID of the access group
|
||||
// Required: true
|
||||
AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
|
||||
|
||||
// ID of the version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// Default ACL drop behavior
|
||||
// Required: false
|
||||
DefaultACLDrop string `url:"default_acl_drop,omitempty" json:"default_acl_drop,omitempty"`
|
||||
|
||||
// Default open session drop flag
|
||||
// Required: false
|
||||
DefaultOpenSessionDrop bool `url:"default_open_session_drop,omitempty" json:"default_open_session_drop,omitempty"`
|
||||
}
|
||||
|
||||
// Update updates a default security policy
|
||||
func (i DefaultSecurityPolicies) Update(ctx context.Context, req UpdateRequest) (*SecurityPolicy, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/default_security_policy/update"
|
||||
|
||||
res, err := i.client.DecortApiCallCtype(ctx, http.MethodPatch, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := SecurityPolicy{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package sdn
|
||||
|
||||
import (
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/extnet"
|
||||
)
|
||||
|
||||
// Accessing the ExtNet method group
|
||||
func (sdn *SDN) ExtNet() *extnet.ExtNet {
|
||||
return extnet.New(sdn.client)
|
||||
}
|
||||
@ -0,0 +1,729 @@
|
||||
package extnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// CreateRequest struct for creating account
|
||||
type CreateRequest struct {
|
||||
// Name of the bridge network
|
||||
// Required: true
|
||||
BridgeNetworkName string `url:"bridge_network_name" json:"bridge_network_name" 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"`
|
||||
|
||||
// List of hypervisor names
|
||||
// Required: true
|
||||
Hypervisors []string `url:"hypervisors" json:"hypervisors" validate:"required"`
|
||||
|
||||
// List of external network ports
|
||||
// Required: false
|
||||
ExternalNetworkPorts []ExternalNetworkPortRequest `url:"-" json:"external_network_ports,omitempty"`
|
||||
|
||||
// IPv4 default gateway address
|
||||
// Required: false
|
||||
DefaultGatewayIPv4 string `url:"default_gateway_ipv4,omitempty" json:"default_gateway_ipv4,omitempty"`
|
||||
|
||||
// IPv6 default gateway address
|
||||
// Required: false
|
||||
DefaultGatewayIPv6 string `url:"default_gateway_ipv6,omitempty" json:"default_gateway_ipv6,omitempty"`
|
||||
|
||||
// IPv4 subnet in CIDR notation (Either subnet_v4 or subnet_v6 must be specified)
|
||||
// Required: false
|
||||
SubnetV4 string `url:"subnet_v4,omitempty" json:"subnet_v4,omitempty"`
|
||||
|
||||
// IPv6 subnet in CIDR notation (Either subnet_v4 or subnet_v6 must be specified)
|
||||
// Required: false
|
||||
SubnetV6 string `url:"subnet_v6,omitempty" json:"subnet_v6,omitempty"`
|
||||
|
||||
// VLAN tag identifier
|
||||
// Required: false
|
||||
VLANTag string `url:"vlan_tag,omitempty" json:"vlan_tag,omitempty" validate:"omitempty,trunkTags"`
|
||||
}
|
||||
|
||||
type ExternalNetworkPortRequest struct {
|
||||
// Access group ID
|
||||
// Required: true
|
||||
AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
|
||||
|
||||
// Access group name
|
||||
// Required: false
|
||||
AccessGroupName string `url:"access_group_name,omitempty" json:"access_group_name,omitempty"`
|
||||
|
||||
// Comment for the external network port
|
||||
// Required: true
|
||||
Comment string `url:"comment" json:"comment" validate:"required"`
|
||||
|
||||
// User-friendly name for the external network port
|
||||
// Required: true
|
||||
DisplayName string `url:"display_name" json:"display_name" validate:"required"`
|
||||
|
||||
// Whether the network pork is enabled
|
||||
// Required: true
|
||||
Enabled bool `url:"enabled" json:"enabled"`
|
||||
|
||||
// IPv4
|
||||
// Required: false
|
||||
IPv4 string `url:"ipv4,omitempty" json:"ipv4,omitempty"`
|
||||
|
||||
// IPv6
|
||||
// Required: false
|
||||
IPv6 string `url:"ipv6,omitempty" json:"ipv6,omitempty"`
|
||||
|
||||
// IPv6 Config
|
||||
// Required: false
|
||||
IPv6Config *IPv6ConfigRequest `url:"-" json:"ipv6_config,omitempty"`
|
||||
|
||||
// MAC address
|
||||
// Required: true
|
||||
MAC string `url:"mac" json:"mac" validate:"required"`
|
||||
|
||||
// Router gateway port
|
||||
// Required: false
|
||||
RouterGatewayPort *RouterGatewayPortRequest `url:"-" json:"router_gateway_port,omitempty"`
|
||||
|
||||
// Floating IP
|
||||
// Required: false
|
||||
FloatingIP *FloatingIPRequest `url:"-" json:"floating_ip,omitempty"`
|
||||
}
|
||||
|
||||
type IPv6ConfigRequest struct {
|
||||
//Address Mode (Slaac or DhcpV6Stateful)
|
||||
// Required: true
|
||||
AddressMode string `url:"address_mode" json:"address_mode" validate:"required"`
|
||||
|
||||
// If true, the port will periodically send RA packets.
|
||||
// Required: true
|
||||
EnablePeriodicRa bool `url:"enable_periodic_ra" json:"enable_periodic_ra"`
|
||||
|
||||
// The number of waiting seconds between sending periodic RA
|
||||
// Required: true
|
||||
IntervalRa int64 `url:"interval_ra" json:"interval_ra" validate:"required"`
|
||||
|
||||
// The Default Router Preference (PRF) indicates whether this router should be preferred over other default routers.
|
||||
// high, low, medium
|
||||
// Required: true
|
||||
RouterPreference string `url:"router_preference" json:"router_preference" validate:"required"`
|
||||
}
|
||||
|
||||
type RouterGatewayPortRequest struct {
|
||||
// Created at
|
||||
// Required: true
|
||||
CreatedAt time.Time `url:"created_at" json:"created_at" validate:"required"`
|
||||
|
||||
// Description
|
||||
// Required: true
|
||||
Description string `url:"description" json:"description" validate:"required"`
|
||||
|
||||
// Port id
|
||||
// Required: true
|
||||
ID string `url:"id" json:"id" validate:"required"`
|
||||
|
||||
// User-friendly name for the external network port
|
||||
// Required: true
|
||||
RouterDisplayName string `url:"router_display_name" json:"router_display_name" validate:"required"`
|
||||
|
||||
// Router ID
|
||||
// Required: true
|
||||
RouterID string `url:"router_id" json:"router_id" validate:"required"`
|
||||
|
||||
// SNAT Enabled
|
||||
// Required: true
|
||||
SNATEnabled bool `url:"snat_enabled" json:"snat_enabled"`
|
||||
|
||||
// Updated at
|
||||
// Required: true
|
||||
UpdatedAt time.Time `url:"updated_at" json:"updated_at" validate:"required"`
|
||||
}
|
||||
|
||||
type FloatingIPRequest struct {
|
||||
// Access group ID
|
||||
// Required: true
|
||||
AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
|
||||
|
||||
// Access group name
|
||||
// Required: true
|
||||
AccessGroupName string `url:"access_group_name" json:"access_group_name" validate:"required"`
|
||||
|
||||
// Created at
|
||||
// Required: true
|
||||
CreatedAt time.Time `url:"created_at" json:"created_at" validate:"required"`
|
||||
|
||||
// External network port
|
||||
// Required: true
|
||||
ExternalNetworkPort string `url:"external_network_port" json:"external_network_port" validate:"required"`
|
||||
|
||||
// ID of the Floating IP
|
||||
// Required: true
|
||||
ID string `url:"id" json:"id" validate:"required"`
|
||||
|
||||
// Logical port
|
||||
// Required: false
|
||||
LogicalPort *LogicalPortRequest `url:"-" json:"logical_port,omitempty"`
|
||||
|
||||
// Router
|
||||
// Required: true
|
||||
Router *RouterRequest `url:"-" json:"router" validate:"required"`
|
||||
|
||||
// Updated at
|
||||
// Required: true
|
||||
UpdatedAt time.Time `url:"updated_at" json:"updated_at" validate:"required"`
|
||||
|
||||
// ID of version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
}
|
||||
|
||||
type LogicalPortRequest struct {
|
||||
// Logical Port ID
|
||||
// Required: true
|
||||
ID string `url:"id" json:"id" validate:"required"`
|
||||
|
||||
// Access group ID
|
||||
// Required: true
|
||||
AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
|
||||
|
||||
// Access group name
|
||||
// Required: true
|
||||
AccessGroupName string `url:"access_group_name" json:"access_group_name" validate:"required"`
|
||||
|
||||
// MAC of adapter
|
||||
// Required: true
|
||||
AdapterMAC string `url:"adapter_mac" json:"adapter_mac" validate:"required"`
|
||||
|
||||
// Address detection
|
||||
// Required: true
|
||||
AddressDetection bool `url:"address_detection" json:"address_detection" validate:"required"`
|
||||
|
||||
// Description
|
||||
// Required: true
|
||||
Description string `url:"description" json:"description" validate:"required"`
|
||||
|
||||
// Created at
|
||||
// Required: false
|
||||
CreatedAt time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
|
||||
|
||||
// User-friendly name for router
|
||||
// Required: true
|
||||
RouterDisplayName string `url:"router_display_name" json:"router_display_name" validate:"required"`
|
||||
|
||||
// Whether the logical pork is enabled
|
||||
// Required: true
|
||||
Enabled bool `url:"enabled" json:"enabled"`
|
||||
|
||||
// External Network ID
|
||||
// Required: false
|
||||
ExternalNetworkID string `url:"external_network_id,omitempty" json:"external_network_id,omitempty"`
|
||||
|
||||
// Hypervisor
|
||||
// Required: true
|
||||
Hypervisor string `url:"hypervisor" json:"hypervisor" validate:"required"`
|
||||
|
||||
// User-friendly name for hypervisor
|
||||
// Required: false
|
||||
HypervisorDisplayName string `url:"hypervisor_display_name,omitempty" json:"hypervisor_display_name,omitempty"`
|
||||
|
||||
// Live Migration Target Hv
|
||||
// Required: true
|
||||
LiveMigrationTargetHV string `url:"live_migration_target_hv" json:"live_migration_target_hv" validate:"required"`
|
||||
|
||||
// Status
|
||||
// Required: true
|
||||
Status *StatusRequest `url:"-" json:"status" validate:"required"`
|
||||
|
||||
// Port bindings
|
||||
// Required: true
|
||||
Bindings *PortBindingsRequest `url:"-" json:"bindings" validate:"required"`
|
||||
|
||||
// Unique Identifier
|
||||
// Required: true
|
||||
UniqueIDentifier string `url:"unique_identifier" json:"unique_identifier" validate:"required"`
|
||||
|
||||
// Updated at
|
||||
// Required: true
|
||||
UpdatedAt time.Time `url:"updated_at" json:"updated_at" validate:"required"`
|
||||
|
||||
// ID of version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
}
|
||||
|
||||
type StatusRequest struct {
|
||||
// Common
|
||||
// Required: true
|
||||
Common string `url:"common" json:"common" validate:"required"`
|
||||
|
||||
// Hypervisors status
|
||||
// Required: false
|
||||
Hypervisors []HypervisorStatusRequest `url:"-" json:"hypervisors,omitempty"`
|
||||
}
|
||||
|
||||
type PortBindingsRequest struct {
|
||||
// Binding ID
|
||||
// Required: true
|
||||
ID string `url:"id" json:"id" validate:"required"`
|
||||
|
||||
// User-friendly name for segment
|
||||
// Required: true
|
||||
SegmentDisplayName string `url:"segment_display_name" json:"segment_display_name" validate:"required"`
|
||||
|
||||
// Segment ID
|
||||
// Required: true
|
||||
SegmentID string `url:"segment_id" json:"segment_id" validate:"required"`
|
||||
|
||||
// Port security
|
||||
// Required: true
|
||||
PortSecurity bool `url:"port_security" json:"port_security" validate:"required"`
|
||||
|
||||
// Address detection
|
||||
// Required: true
|
||||
AddressDetection bool `url:"address_detection" json:"address_detection" validate:"required"`
|
||||
|
||||
// Is Exclude From Firewall
|
||||
// Required: true
|
||||
IsExcludedFromFirewall bool `url:"is_excluded_from_firewall" json:"is_excluded_from_firewall" validate:"required"`
|
||||
|
||||
// ID of version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// Created at
|
||||
// Required: true
|
||||
CreatedAt time.Time `url:"created_at" json:"created_at" validate:"required"`
|
||||
|
||||
// Updated at
|
||||
// Required: true
|
||||
UpdatedAt time.Time `url:"updated_at" json:"updated_at" validate:"required"`
|
||||
|
||||
// Logical port addresses
|
||||
// Required: true
|
||||
LogicalPortAddresses []LogicalPortAddressRequest `url:"-" json:"logical_port_addresses" validate:"required"`
|
||||
}
|
||||
|
||||
type HypervisorStatusRequest struct {
|
||||
// Status
|
||||
// Required: true
|
||||
Status string `url:"status" json:"status" validate:"required"`
|
||||
|
||||
// Name of hypervisor
|
||||
// Required: true
|
||||
Name string `url:"name" json:"name" validate:"required"`
|
||||
|
||||
// User-friendly name for the hypervisor
|
||||
// Required: true
|
||||
DisplayName string `url:"display_name" json:"display_name" validate:"required"`
|
||||
|
||||
// Hypervisor status
|
||||
// Required: true
|
||||
HypervisorStatus string `url:"hypervisor_status" json:"hypervisor_status" validate:"required"`
|
||||
|
||||
// Synced at
|
||||
// Required: true
|
||||
SyncedAt time.Time `url:"synced_at" json:"synced_at" validate:"required"`
|
||||
}
|
||||
|
||||
type LogicalPortAddressRequest struct {
|
||||
// IP of port
|
||||
// Required: true
|
||||
IP string `url:"ip" json:"ip" validate:"required"`
|
||||
|
||||
// IP type (IPv4 or IPv6)
|
||||
// Required: true
|
||||
IPType string `url:"ip_type" json:"ip_type" validate:"required"`
|
||||
|
||||
// Is discovered
|
||||
// Required: false
|
||||
IsDiscovered bool `url:"is_discovered,omitempty" json:"is_discovered,omitempty"`
|
||||
|
||||
// Is discovered
|
||||
// Required: true
|
||||
IsPrimary bool `url:"is_primary" json:"is_primary" validate:"required"`
|
||||
|
||||
// MAC
|
||||
// Required: false
|
||||
MAC string `url:"mac,omitempty" json:"mac,omitempty"`
|
||||
|
||||
// ID
|
||||
// Required: true
|
||||
ID string `url:"id" json:"id" validate:"required"`
|
||||
|
||||
// Logical port id
|
||||
// Required: true
|
||||
LogicalPortID string `url:"logical_port_id" json:"logical_port_id" validate:"required"`
|
||||
|
||||
// Assigned at
|
||||
// Required: false
|
||||
AssignedAt time.Time `url:"assigned_at,omitempty" json:"assigned_at,omitempty"`
|
||||
}
|
||||
|
||||
type RouterRequest struct {
|
||||
// Access group ID
|
||||
// Required: false
|
||||
AccessGroupID string `url:"access_group_id,omitempty" json:"access_group_id,omitempty"`
|
||||
|
||||
// Access group name
|
||||
// Required: false
|
||||
AccessGroupName string `url:"access_group_name,omitempty" json:"access_group_name,omitempty"`
|
||||
|
||||
// Created at
|
||||
// Required: false
|
||||
CreatedAt time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
|
||||
|
||||
// Detailed description of the router
|
||||
// Required: false
|
||||
Description string `url:"description,omitempty" json:"description,omitempty"`
|
||||
|
||||
// User-friendly name for the router
|
||||
// Required: true
|
||||
DisplayName string `url:"display_name" json:"display_name" validate:"required"`
|
||||
|
||||
// Whether the router is enabled
|
||||
// Required: false
|
||||
Enabled bool `url:"enabled,omitempty" json:"enabled,omitempty"`
|
||||
|
||||
// Gateway ports
|
||||
// Required: false
|
||||
GatewayPorts []GatewayPortRequest `url:"-" json:"gateway_ports,omitempty"`
|
||||
|
||||
// ID
|
||||
// Required: true
|
||||
ID string `url:"id" json:"id" validate:"required"`
|
||||
|
||||
// Policies
|
||||
// Required: false
|
||||
Policies []RouterPolicyRequest `url:"-" json:"policies,omitempty"`
|
||||
|
||||
// Ports
|
||||
// Required: false
|
||||
Ports []RouterPortRequest `url:"-" json:"ports,omitempty"`
|
||||
|
||||
// Status
|
||||
// Required: false
|
||||
Status *StatusRequest `url:"-" json:"status,omitempty"`
|
||||
|
||||
// Updated at
|
||||
// Required: false
|
||||
UpdatedAt time.Time `url:"updated_at,omitempty" json:"updated_at,omitempty"`
|
||||
|
||||
// ID of version
|
||||
// Required: false
|
||||
VersionID uint64 `url:"version_id,omitempty" json:"version_id,omitempty"`
|
||||
}
|
||||
|
||||
type GatewayPortRequest struct {
|
||||
// Created at
|
||||
// Required: true
|
||||
CreatedAt time.Time `url:"created_at" json:"created_at" validate:"required"`
|
||||
|
||||
// Description
|
||||
// Required: true
|
||||
Description string `url:"description" json:"description" validate:"required"`
|
||||
|
||||
// L4 port max
|
||||
// Required: false
|
||||
ExternalL4PortMax int64 `url:"external_l4_port_max,omitempty" json:"external_l4_port_max,omitempty"`
|
||||
|
||||
// L4 port min
|
||||
// Required: false
|
||||
ExternalL4PortMin int64 `url:"external_l4_port_min,omitempty" json:"external_l4_port_min,omitempty"`
|
||||
|
||||
// External network port
|
||||
// Required: true
|
||||
ExternalNetworkPort interface{} `url:"external_network_port" json:"external_network_port" validate:"required"`
|
||||
|
||||
// ID of port
|
||||
// Required: false
|
||||
ID string `url:"id,omitempty" json:"id,omitempty"`
|
||||
|
||||
// SNAT Enabled
|
||||
// Required: true
|
||||
SNATEnabled bool `url:"snat_enabled" json:"snat_enabled"`
|
||||
|
||||
// Status
|
||||
// Required: false
|
||||
Status *StatusRequest `url:"-" json:"status,omitempty"`
|
||||
|
||||
// Updated at
|
||||
// Required: true
|
||||
UpdatedAt time.Time `url:"updated_at" json:"updated_at" validate:"required"`
|
||||
|
||||
// ID of version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
}
|
||||
|
||||
type RouterPolicyRequest struct {
|
||||
// Action
|
||||
// Required: true
|
||||
Action string `url:"action" json:"action" validate:"required"`
|
||||
|
||||
// Created at
|
||||
// Required: true
|
||||
CreatedAt time.Time `url:"created_at" json:"created_at" validate:"required"`
|
||||
|
||||
// User-friendly name for the policy
|
||||
// Required: true
|
||||
DisplayName string `url:"display_name" json:"display_name" validate:"required"`
|
||||
|
||||
// Whether the policy is enabled
|
||||
// Required: false
|
||||
Enabled bool `url:"enabled,omitempty" json:"enabled,omitempty"`
|
||||
|
||||
// ID of port
|
||||
// Required: false
|
||||
ID string `url:"id,omitempty" json:"id,omitempty"`
|
||||
|
||||
// Match
|
||||
// Required: true
|
||||
Match interface{} `url:"match" json:"match" validate:"required"`
|
||||
|
||||
// Next IPv4 address
|
||||
// Required: true
|
||||
NextIPv4Address []string `url:"next_ipv4_address" json:"next_ipv4_address" validate:"required"`
|
||||
|
||||
// Next IPv6 address
|
||||
// Required: true
|
||||
NextIPv6Address []string `url:"next_ipv6_address" json:"next_ipv6_address" validate:"required"`
|
||||
|
||||
// Priority
|
||||
// Required: true
|
||||
Priority int64 `url:"priority" json:"priority" validate:"required"`
|
||||
|
||||
// Updated at
|
||||
// Required: true
|
||||
UpdatedAt time.Time `url:"updated_at" json:"updated_at" validate:"required"`
|
||||
|
||||
// ID of version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
}
|
||||
|
||||
type RouterPortRequest struct {
|
||||
// Created at
|
||||
// Required: true
|
||||
CreatedAt time.Time `url:"created_at" json:"created_at" validate:"required"`
|
||||
|
||||
// Detailed description of the router port
|
||||
// Required: true
|
||||
Description string `url:"description" json:"description" validate:"required"`
|
||||
|
||||
// Whether the router port is enabled
|
||||
// Required: true
|
||||
Enabled bool `url:"enabled" json:"enabled"`
|
||||
|
||||
// ID of port
|
||||
// Required: false
|
||||
ID string `url:"id,omitempty" json:"id,omitempty"`
|
||||
|
||||
// Next IPv4 address
|
||||
// Required: true
|
||||
NextIPv4Address []string `url:"next_ipv4_address" json:"next_ipv4_address" validate:"required"`
|
||||
|
||||
// Next IPv6 address
|
||||
// Required: true
|
||||
NextIPv6Address []string `url:"next_ipv6_address" json:"next_ipv6_address" validate:"required"`
|
||||
|
||||
// IPv6 Config
|
||||
// Required: true
|
||||
IPv6Config *IPv6ConfigRequest `url:"-" json:"ipv6_config" validate:"required"`
|
||||
|
||||
// MAC address
|
||||
// Required: true
|
||||
MAC string `url:"mac" json:"mac" validate:"required"`
|
||||
|
||||
// Segment
|
||||
// Required: true
|
||||
Segment *SegmentRequest `url:"-" json:"segment" validate:"required"`
|
||||
|
||||
// Segment ID
|
||||
// Required: true
|
||||
SegmentID string `url:"segment_id" json:"segment_id" validate:"required"`
|
||||
|
||||
// Status
|
||||
// Required: false
|
||||
Status *StatusRequest `url:"-" json:"status,omitempty"`
|
||||
|
||||
// Updated at
|
||||
// Required: true
|
||||
UpdatedAt time.Time `url:"updated_at" json:"updated_at" validate:"required"`
|
||||
|
||||
// ID of version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
}
|
||||
|
||||
type SegmentRequest struct {
|
||||
// Access group ID
|
||||
// Required: true
|
||||
AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
|
||||
|
||||
// Access group name
|
||||
// Required: false
|
||||
AccessGroupName string `url:"access_group_name,omitempty" json:"access_group_name,omitempty"`
|
||||
|
||||
// Created at
|
||||
// Required: true
|
||||
CreatedAt time.Time `url:"created_at" json:"created_at" validate:"required"`
|
||||
|
||||
// Detailed description of the router port
|
||||
// Required: true
|
||||
Description string `url:"description" json:"description" validate:"required"`
|
||||
|
||||
// DHCP IPv4
|
||||
// Required: false
|
||||
DHCPv4 *DHCPv4ConfigRequest `url:"-" json:"dhcp_v4,omitempty"`
|
||||
|
||||
// DHCP IPv6
|
||||
// Required: false
|
||||
DHCPv6 *DHCPv6ConfigRequest `url:"-" json:"dhcp_v6,omitempty"`
|
||||
|
||||
// User-friendly name for the segment
|
||||
// Required: true
|
||||
DisplayName string `url:"display_name" json:"display_name" validate:"required"`
|
||||
|
||||
// Whether the segment is enabled
|
||||
// Required: false
|
||||
Enabled bool `url:"enabled,omitempty" json:"enabled,omitempty"`
|
||||
|
||||
// ID of segment
|
||||
// Required: false
|
||||
ID string `url:"id,omitempty" json:"id,omitempty"`
|
||||
|
||||
// Logical ports info
|
||||
// Required: false
|
||||
LogicalPortsInfo []EntityInfoRequest `url:"-" json:"logical_ports_info,omitempty"`
|
||||
|
||||
// Routers info
|
||||
// Required: false
|
||||
RoutersInfo []EntityInfoRequest `url:"-" json:"routers_info,omitempty"`
|
||||
|
||||
// Status
|
||||
// Required: false
|
||||
Status *StatusRequest `url:"-" json:"status,omitempty"`
|
||||
|
||||
// IPv4 subnet in CIDR notation (Either subnet_v4 or subnet_v6 must be specified)
|
||||
// Required: false
|
||||
SubnetV4 string `url:"subnet_v4,omitempty" json:"subnet_v4,omitempty"`
|
||||
|
||||
// IPv6 subnet in CIDR notation (Either subnet_v4 or subnet_v6 must be specified)
|
||||
// Required: false
|
||||
SubnetV6 string `url:"subnet_v6,omitempty" json:"subnet_v6,omitempty"`
|
||||
|
||||
// Updated at
|
||||
// Required: true
|
||||
UpdatedAt time.Time `url:"updated_at" json:"updated_at" validate:"required"`
|
||||
|
||||
// ID of version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
}
|
||||
|
||||
type DHCPv4ConfigRequest struct {
|
||||
// DNS
|
||||
// Required: false
|
||||
DNS []string `url:"dns,omitempty" json:"dns,omitempty"`
|
||||
|
||||
// Excluded address ranges
|
||||
// Required: false
|
||||
ExcludedAddressRanges []string `url:"excluded_address_ranges,omitempty" json:"excluded_address_ranges,omitempty"`
|
||||
|
||||
// Gateway
|
||||
// Required: true
|
||||
Gateway string `url:"gateway" json:"gateway" validate:"required"`
|
||||
|
||||
// ID of config
|
||||
// Required: false
|
||||
ID string `url:"id,omitempty" json:"id,omitempty"`
|
||||
|
||||
// Lease time
|
||||
// Required: false
|
||||
LeaseTime int64 `url:"lease_time,omitempty" json:"lease_time,omitempty"`
|
||||
|
||||
// Server IP
|
||||
// Required: true
|
||||
ServerIP string `url:"server_ip" json:"server_ip" validate:"required"`
|
||||
|
||||
// Server MAC
|
||||
// Required: false
|
||||
ServerMAC string `url:"server_mac,omitempty" json:"server_mac,omitempty"`
|
||||
|
||||
// Whether the config is enabled
|
||||
// Required: true
|
||||
Enabled bool `url:"enabled" json:"enabled"`
|
||||
}
|
||||
|
||||
type DHCPv6ConfigRequest struct {
|
||||
// Address prefix
|
||||
// Required: true
|
||||
AddressPrefix string `url:"address_prefix" json:"address_prefix" validate:"required"`
|
||||
|
||||
// DNS
|
||||
// Required: false
|
||||
DNS []string `url:"dns,omitempty" json:"dns,omitempty"`
|
||||
|
||||
// ID of config
|
||||
// Required: false
|
||||
ID string `url:"id,omitempty" json:"id,omitempty"`
|
||||
|
||||
// Lease time
|
||||
// Required: true
|
||||
LeaseTime int64 `url:"lease_time" json:"lease_time" validate:"required"`
|
||||
|
||||
// Server MAC
|
||||
// Required: true
|
||||
ServerMAC string `url:"server_mac" json:"server_mac" validate:"required"`
|
||||
|
||||
// Whether the config is enabled
|
||||
// Required: true
|
||||
Enabled bool `url:"enabled" json:"enabled"`
|
||||
}
|
||||
|
||||
type EntityInfoRequest struct {
|
||||
// User-friendly name for the entity
|
||||
// Required: true
|
||||
DisplayName string `url:"display_name" json:"display_name" validate:"required"`
|
||||
|
||||
// ID of entity
|
||||
// Required: false
|
||||
ID string `url:"id,omitempty" json:"id,omitempty"`
|
||||
}
|
||||
|
||||
// Create creates extnet
|
||||
func (e ExtNet) Create(ctx context.Context, req CreateRequest) (*ExternalNetworkResponse, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/external_network/create"
|
||||
|
||||
res, err := e.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := ExternalNetworkResponse{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package extnet
|
||||
|
||||
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 extnet
|
||||
type DeleteRequest struct {
|
||||
// ID of external network
|
||||
// Required: true
|
||||
ExtNetID string `url:"external_network_id" json:"external_network_id" validate:"required"`
|
||||
|
||||
// ID of version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// Force delete
|
||||
// Required: false
|
||||
Force bool `url:"force,omitempty" json:"force,omitempty"`
|
||||
}
|
||||
|
||||
// Delete delete an external network
|
||||
func (e ExtNet) Delete(ctx context.Context, req DeleteRequest) error {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/external_network/delete"
|
||||
|
||||
_, err = e.client.DecortApiCallCtype(ctx, http.MethodDelete, url, constants.MIMEJSON, req)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
// API Actor API for managing SDN external networks
|
||||
package extnet
|
||||
|
||||
import (
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
|
||||
)
|
||||
|
||||
// Structure for creating request to external networks
|
||||
type ExtNet struct {
|
||||
client interfaces.Caller
|
||||
}
|
||||
|
||||
// Builder for external networks endpoints
|
||||
func New(client interfaces.Caller) *ExtNet {
|
||||
return &ExtNet{
|
||||
client,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
package extnet
|
||||
|
||||
// FilterByID returns ListExtNet with specified ID.
|
||||
func (eList ListExtNet) FilterByID(id string) ListExtNet {
|
||||
predicate := func(extNet ExternalNetworkResponse) bool {
|
||||
return extNet.ID == id
|
||||
}
|
||||
|
||||
return eList.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterByName returns ListExtNet with specified Bridge network name.
|
||||
func (eList ListExtNet) FilterByName(name string) ListExtNet {
|
||||
predicate := func(extNet ExternalNetworkResponse) bool {
|
||||
return extNet.BridgeNetworkName == name
|
||||
}
|
||||
|
||||
return eList.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterByIPv4 returns ListExtNet with specified default gateway IPv4.
|
||||
func (eList ListExtNet) FilterByIPv4(IPv4 string) ListExtNet {
|
||||
predicate := func(extNet ExternalNetworkResponse) bool {
|
||||
return extNet.DefaultGatewayIPv4 == IPv4
|
||||
}
|
||||
|
||||
return eList.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterByIPv6 returns ListExtNet with specified default gateway IPv6.
|
||||
func (eList ListExtNet) FilterByIPv6(IPv6 string) ListExtNet {
|
||||
predicate := func(extNet ExternalNetworkResponse) bool {
|
||||
return extNet.DefaultGatewayIPv6 == IPv6
|
||||
}
|
||||
|
||||
return eList.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterFunc allows filtering ListExtNet based on a user-specified predicate.
|
||||
func (eList ListExtNet) FilterFunc(predicate func(response ExternalNetworkResponse) bool) ListExtNet {
|
||||
var result ListExtNet
|
||||
|
||||
for _, item := range eList {
|
||||
if predicate(item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// FindOne returns first element.
|
||||
// If none was found, returns an empty struct.
|
||||
func (eList ListExtNet) FindOne() ExternalNetworkResponse {
|
||||
if len(eList) == 0 {
|
||||
return ExternalNetworkResponse{}
|
||||
}
|
||||
|
||||
return eList[0]
|
||||
}
|
||||
@ -0,0 +1,149 @@
|
||||
package extnet
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var testExtnetList = ListExtNet{
|
||||
{
|
||||
BridgeNetworkName: "br-ext-net-01",
|
||||
DefaultGatewayIPv4: "192.168.1.1",
|
||||
DefaultGatewayIPv6: "2001:db8::1",
|
||||
Description: "test1",
|
||||
Hypervisors: []string{
|
||||
"hv-node-01",
|
||||
},
|
||||
ID: "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
|
||||
VersionID: 1747141621952,
|
||||
SubnetV4: "192.168.1.0/24",
|
||||
SubnetV6: "2001:db8::/64",
|
||||
CreatedAt: time.Date(2025, 10, 21, 20, 34, 30, 641000000, time.UTC),
|
||||
UpdatedAt: time.Date(2025, 10, 21, 20, 34, 30, 641000000, time.UTC),
|
||||
VLANTag: 100,
|
||||
},
|
||||
{
|
||||
BridgeNetworkName: "br-backup-net-02",
|
||||
DefaultGatewayIPv4: "10.0.1.1",
|
||||
DefaultGatewayIPv6: "2001:db8:1::1",
|
||||
Description: "test2",
|
||||
Hypervisors: []string{
|
||||
"hv-node-02",
|
||||
},
|
||||
ID: "b2c3d4e5-f6g7-8901-bcde-f23456789012",
|
||||
VersionID: 1747141621953,
|
||||
SubnetV4: "10.0.1.0/24",
|
||||
SubnetV6: "2001:db8:1::/64",
|
||||
CreatedAt: time.Date(2025, 10, 21, 20, 34, 30, 641000000, time.UTC),
|
||||
UpdatedAt: time.Date(2025, 10, 21, 20, 34, 30, 641000000, time.UTC),
|
||||
VLANTag: 200,
|
||||
},
|
||||
{
|
||||
BridgeNetworkName: "br-test-net-03",
|
||||
DefaultGatewayIPv4: "172.16.1.1",
|
||||
DefaultGatewayIPv6: "2001:db8:2::1",
|
||||
Description: "test3",
|
||||
ExternalNetworkPorts: []ExternalNetworkPort{},
|
||||
Hypervisors: []string{
|
||||
"hv-node-05",
|
||||
"hv-node-06",
|
||||
},
|
||||
ID: "c3d4e5f6-g7h8-9012-cdef-345678901234",
|
||||
VersionID: 1747141621954,
|
||||
SubnetV4: "172.16.1.0/24",
|
||||
SubnetV6: "2001:db8:2::/64",
|
||||
CreatedAt: time.Date(2025, 10, 21, 20, 34, 30, 641000000, time.UTC),
|
||||
UpdatedAt: time.Date(2025, 10, 21, 20, 34, 30, 641000000, time.UTC),
|
||||
VLANTag: 300,
|
||||
},
|
||||
}
|
||||
|
||||
func TestFilterByID(t *testing.T) {
|
||||
actual := testExtnetList.FilterByID("a1b2c3d4-e5f6-7890-abcd-ef1234567890").FindOne()
|
||||
|
||||
if actual.ID != "a1b2c3d4-e5f6-7890-abcd-ef1234567890" {
|
||||
t.Fatal("actual:", actual.ID, "> expected: a1b2c3d4-e5f6-7890-abcd-ef1234567890")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByName(t *testing.T) {
|
||||
actual := testExtnetList.FilterByName("br-ext-net-01").FindOne()
|
||||
|
||||
if actual.BridgeNetworkName != "br-ext-net-01" {
|
||||
t.Fatal("actual:", actual.BridgeNetworkName, ">> expected: br-ext-net-01")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByIPv4(t *testing.T) {
|
||||
actual := testExtnetList.FilterByIPv4("192.168.1.1").FindOne()
|
||||
|
||||
if actual.DefaultGatewayIPv4 != "192.168.1.1" {
|
||||
t.Fatal("actual:", actual.DefaultGatewayIPv4, ">> expected: 192.168.1.1")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByIPv6(t *testing.T) {
|
||||
actual := testExtnetList.FilterByIPv6("2001:db8:1::1").FindOne()
|
||||
|
||||
if actual.DefaultGatewayIPv6 != "2001:db8:1::1" {
|
||||
t.Fatal("actual:", actual.DefaultGatewayIPv6, ">> expected: 2001:db8:1::1")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterFunc(t *testing.T) {
|
||||
actual := testExtnetList.FilterFunc(func(response ExternalNetworkResponse) bool {
|
||||
return response.BridgeNetworkName == "br-backup-net-02"
|
||||
})
|
||||
|
||||
if len(actual) != 1 || actual[0].ID != "b2c3d4e5-f6g7-8901-bcde-f23456789012" {
|
||||
t.Fatal("Expected 1 extnet with name 'br-backup-net-02', found:", len(actual))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindOneWithResults(t *testing.T) {
|
||||
result := testExtnetList.FilterByID("c3d4e5f6-g7h8-9012-cdef-345678901234").FindOne()
|
||||
if result.ID != "c3d4e5f6-g7h8-9012-cdef-345678901234" {
|
||||
t.Fatal("Expected c3d4e5f6-g7h8-9012-cdef-345678901234, got:", result.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindOneEmpty(t *testing.T) {
|
||||
emptyList := ListExtNet{}
|
||||
result := emptyList.FindOne()
|
||||
|
||||
if result.ID != "" || result.BridgeNetworkName != "" {
|
||||
t.Fatal("Expected empty extNet, got:", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByIDNotFound(t *testing.T) {
|
||||
actual := ListExtNet{}.FilterByID("nonexistent")
|
||||
|
||||
if len(actual) != 0 {
|
||||
t.Fatal("Expected 0 extNet, found:", len(actual))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByNameNotFound(t *testing.T) {
|
||||
actual := ListExtNet{}.FilterByName("Nonexistent")
|
||||
|
||||
if len(actual) != 0 {
|
||||
t.Fatal("Expected 0 extNet, found:", len(actual))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByIPv4NotFound(t *testing.T) {
|
||||
actual := testExtnetList.FilterByIPv4("nonexistent-ip")
|
||||
|
||||
if len(actual) != 0 {
|
||||
t.Fatal("Expected 0 extNet, found:", len(actual))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByIPv6NotFound(t *testing.T) {
|
||||
actual := testExtnetList.FilterByIPv6("nonexistent-ipv6")
|
||||
|
||||
if len(actual) != 0 {
|
||||
t.Fatal("Expected 0 extNet, found:", len(actual))
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package extnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// GetRequest struct to get information about external network
|
||||
type GetRequest struct {
|
||||
// ID of external network
|
||||
// Required: false
|
||||
ExtNetID string `url:"external_network_id" json:"external_network_id" validate:"required"`
|
||||
|
||||
// ID of access group
|
||||
// Required: false
|
||||
AccessGroupID string `url:"access_group_id,omitempty" json:"access_group_id,omitempty"`
|
||||
}
|
||||
|
||||
// Get gets external network details as a ExternalNetworkResponse struct
|
||||
func (e ExtNet) Get(ctx context.Context, req GetRequest) (*ExternalNetworkResponse, error) {
|
||||
res, err := e.GetRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := ExternalNetworkResponse{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
// GetRaw gets external network details as an array of bytes
|
||||
func (e ExtNet) GetRaw(ctx context.Context, req GetRequest) ([]byte, error) {
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/external_network/get"
|
||||
|
||||
res, err := e.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
return res, err
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package extnet
|
||||
|
||||
// IDs gets array of IDs from ListExtNet struct
|
||||
func (eList ListExtNet) IDs() []string {
|
||||
res := make([]string, 0, len(eList))
|
||||
for _, item := range eList {
|
||||
res = append(res, item.ID)
|
||||
}
|
||||
return res
|
||||
}
|
||||
@ -0,0 +1,114 @@
|
||||
package extnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// ListRequest struct to get a list of external networks
|
||||
type ListRequest struct {
|
||||
// Filter by access group ID
|
||||
// Required: false
|
||||
AccessGroupID string `url:"access_group_id,omitempty" json:"access_group_id,omitempty"`
|
||||
|
||||
// Filter by display name
|
||||
// Required: false
|
||||
DisplayName string `url:"display_name,omitempty" json:"display_name,omitempty"`
|
||||
|
||||
// Filter by IP version (v4 or v6)
|
||||
// Required: false
|
||||
Subnet string `url:"subnet,omitempty" json:"subnet,omitempty" validate:"omitempty,ipTypes"`
|
||||
|
||||
// Filter by IPv4 subnet (CIDR notation)
|
||||
// Required: false
|
||||
SubnetV4 string `url:"subnet_v4,omitempty" json:"subnet_v4,omitempty"`
|
||||
|
||||
// Filter by IPv4 subnet (CIDR notation)
|
||||
// Required: false
|
||||
SubnetV6 string `url:"subnet_v6,omitempty" json:"subnet_v6,omitempty"`
|
||||
|
||||
// Filter by exact bridge network name
|
||||
// Required: false
|
||||
BridgeNetworkName string `url:"bridge_network_name,omitempty" json:"bridge_network_name,omitempty"`
|
||||
|
||||
// Filter by VLAN tag
|
||||
// Required: false
|
||||
VLANTag string `url:"vlan_tag,omitempty" json:"vlan_tag,omitempty"`
|
||||
|
||||
// Filter by IPv4 default gateway
|
||||
// Required: false
|
||||
DefaultGatewayIPv4 string `url:"default_gateway_ipv4,omitempty" json:"default_gateway_ipv4,omitempty"`
|
||||
|
||||
// Filter by IPv6 default gateway
|
||||
// Required: false
|
||||
DefaultGatewayIPv6 string `url:"default_gateway_ipv6,omitempty" json:"default_gateway_ipv6,omitempty"`
|
||||
|
||||
// Filter by enabled status
|
||||
// Required: false
|
||||
Enabled interface{} `url:"enabled,omitempty" json:"enabled,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// Filter by update date from
|
||||
// Required: false
|
||||
UpdatedFrom string `url:"updated_from,omitempty" json:"updated_from,omitempty"`
|
||||
|
||||
// Filter lby update date to
|
||||
// Required: false
|
||||
UpdatedTo string `url:"updated_to,omitempty" json:"updated_to,omitempty"`
|
||||
|
||||
// Filter by create date from
|
||||
// Required: false
|
||||
CreatedFrom string `url:"created_from,omitempty" json:"created_from,omitempty"`
|
||||
|
||||
// Filter lby create date to
|
||||
// Required: false
|
||||
CreatedTo string `url:"created_to,omitempty" json:"created_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, created_at, updated_at, deleted_at, etc)
|
||||
// Required: false
|
||||
SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty"`
|
||||
|
||||
// Sort order (asc/desc)
|
||||
// Required: false
|
||||
SortOrder string `url:"sort_order,omitempty" json:"sort_order,omitempty"`
|
||||
}
|
||||
|
||||
// List gets list of all available external networks as a ListExtNet struct
|
||||
func (e ExtNet) List(ctx context.Context, req ListRequest) (ListExtNet, error) {
|
||||
res, err := e.ListRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list := ListExtNet{}
|
||||
|
||||
err = json.Unmarshal(res, &list)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// ListRaw gets list of all available external networks as an array of bytes
|
||||
func (e ExtNet) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/external_network/list"
|
||||
|
||||
res, err := e.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
return res, err
|
||||
}
|
||||
@ -0,0 +1,578 @@
|
||||
package extnet
|
||||
|
||||
import "time"
|
||||
|
||||
// List external networks
|
||||
type ListExtNet []ExternalNetworkResponse
|
||||
|
||||
type ExternalNetworkResponse struct {
|
||||
// Name of the bridge network
|
||||
BridgeNetworkName string `json:"bridge_network_name"`
|
||||
|
||||
// IPv4 default gateway address
|
||||
DefaultGatewayIPv4 string `json:"default_gateway_ipv4"`
|
||||
|
||||
// IPv6 default gateway address
|
||||
DefaultGatewayIPv6 string `json:"default_gateway_ipv6"`
|
||||
|
||||
// Detailed description of the external network
|
||||
Description string `json:"description"`
|
||||
|
||||
// List of external network ports
|
||||
ExternalNetworkPorts []ExternalNetworkPort `json:"external_network_ports"`
|
||||
|
||||
// List of hypervisor names
|
||||
Hypervisors []string `json:"hypervisors"`
|
||||
|
||||
// Extnet ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Status
|
||||
Status Status `json:"status"`
|
||||
|
||||
// ID of version
|
||||
VersionID uint64 `json:"version_id"`
|
||||
|
||||
// IPv4 subnet in CIDR notation
|
||||
SubnetV4 string `json:"subnet_v4"`
|
||||
|
||||
// IPv6 subnet in CIDR notation
|
||||
SubnetV6 string `json:"subnet_v6"`
|
||||
|
||||
// Creation time
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
||||
// Update time
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// VLAN tag identifier
|
||||
VLANTag int64 `json:"vlan_tag"`
|
||||
}
|
||||
|
||||
type ExternalNetworkPort struct {
|
||||
// Access group ID
|
||||
AccessGroupID string `json:"access_group_id"`
|
||||
|
||||
// Access group name
|
||||
AccessGroupName string `json:"access_group_name"`
|
||||
|
||||
// Comment for the external network port
|
||||
Comment string `json:"comment"`
|
||||
|
||||
// User-friendly name for the external network port
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Whether the network port is enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// IPv4
|
||||
IPv4 string `json:"ipv4"`
|
||||
|
||||
// IPv6
|
||||
IPv6 string `json:"ipv6"`
|
||||
|
||||
// IPv6 Config
|
||||
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"`
|
||||
}
|
||||
|
||||
type IPv6Config struct {
|
||||
// Address mode
|
||||
AddressMode string `json:"address_mode"`
|
||||
|
||||
// If true, the port will periodically send RA packets.
|
||||
EnablePeriodicRa bool `json:"enable_periodic_ra"`
|
||||
|
||||
// The number of waiting seconds between sending periodic RA
|
||||
IntervalRa int64 `json:"interval_ra"`
|
||||
|
||||
// The Default Router Preference (PRF) indicates whether this router should be preferred over other default routers.
|
||||
RouterPreference string `json:"router_preference"`
|
||||
}
|
||||
|
||||
type RouterGatewayPort struct {
|
||||
// Creation time
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
||||
// Description
|
||||
Description string `json:"description"`
|
||||
|
||||
// Port ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// User-friendly name for the external network port
|
||||
RouterDisplayName string `json:"router_display_name"`
|
||||
|
||||
// Router ID
|
||||
RouterID string `json:"router_id"`
|
||||
|
||||
// SNAT Enabled
|
||||
SNATEnabled bool `json:"snat_enabled"`
|
||||
|
||||
// Update time
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
type FloatingIP struct {
|
||||
// Access group ID
|
||||
AccessGroupID string `json:"access_group_id"`
|
||||
|
||||
// Access group name
|
||||
AccessGroupName string `json:"access_group_name"`
|
||||
|
||||
// Created time
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
||||
// External network port
|
||||
ExternalNetworkPort string `json:"external_network_port"`
|
||||
|
||||
// ID of floating IP
|
||||
ID string `json:"id"`
|
||||
|
||||
// Logical Port
|
||||
LogicalPort LogicalPort `json:"logical_port"`
|
||||
|
||||
// Router
|
||||
Router Router `json:"router"`
|
||||
|
||||
// Update time
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// ID of version
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
type LogicalPort struct {
|
||||
// Logical Port ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Access group ID
|
||||
AccessGroupID string `json:"access_group_id"`
|
||||
|
||||
// Access group name
|
||||
AccessGroupName string `json:"access_group_name"`
|
||||
|
||||
// MAC of adapter
|
||||
AdapterMAC string `json:"adapter_mac"`
|
||||
|
||||
// Address detection
|
||||
AddressDetection bool `json:"address_detection"`
|
||||
|
||||
// Description
|
||||
Description string `json:"description"`
|
||||
|
||||
// Created time
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
||||
// User-friendly name for router
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Whether the logical port is enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// External Network ID
|
||||
ExternalNetworkID string `json:"external_network_id"`
|
||||
|
||||
// Hypervisor name
|
||||
Hypervisor string `json:"hypervisor"`
|
||||
|
||||
// User-friendly name for hypervisor
|
||||
HypervisorDisplayName string `json:"hypervisor_display_name"`
|
||||
|
||||
// Live Migration Target Hv
|
||||
LiveMigrationTargetHV string `json:"live_migration_target_hv"`
|
||||
|
||||
// Status
|
||||
Status Status `json:"status"`
|
||||
|
||||
// Bindings struct
|
||||
Bindings PortBindings `json:"bindings"`
|
||||
|
||||
// Unique Identifier
|
||||
UniqueIDentifier string `json:"unique_identifier"`
|
||||
|
||||
// Updated time
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// ID of version
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
type PortBindings struct {
|
||||
// Binding ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// User-friendly name for segment
|
||||
SegmentDisplayName string `json:"segment_display_name"`
|
||||
|
||||
// Segment ID
|
||||
SegmentID string `json:"segment_id"`
|
||||
|
||||
// Port security
|
||||
PortSecurity bool `json:"port_security"`
|
||||
|
||||
// Address detection
|
||||
AddressDetection bool `json:"address_detection"`
|
||||
|
||||
// Is Exclude From Firewall
|
||||
IsExcludedFromFirewall bool `json:"is_excluded_from_firewall"`
|
||||
|
||||
// ID of version
|
||||
VersionID uint64 `json:"version_id"`
|
||||
|
||||
// Created time
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
||||
// Update time
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// Logical port addresses
|
||||
LogicalPortAddresses []LogicalPortAddress `json:"logical_port_addresses"`
|
||||
}
|
||||
|
||||
type LogicalPortAddress struct {
|
||||
// IP of port
|
||||
IP string `json:"ip"`
|
||||
|
||||
// IP type (IPv4 or IPv6)
|
||||
IPType string `json:"ip_type"`
|
||||
|
||||
// Is discovered
|
||||
IsDiscovered bool `json:"is_discovered"`
|
||||
|
||||
// Is primary
|
||||
IsPrimary bool `json:"is_primary"`
|
||||
|
||||
// MAC
|
||||
MAC string `json:"mac"`
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Logical port id
|
||||
LogicalPortID string `json:"logical_port_id"`
|
||||
|
||||
// Assigned time
|
||||
AssignedAt time.Time `json:"assigned_at"`
|
||||
}
|
||||
|
||||
type Router struct {
|
||||
// Access group ID
|
||||
AccessGroupID string `json:"access_group_id"`
|
||||
|
||||
// Access group name
|
||||
AccessGroupName string `json:"access_group_name"`
|
||||
|
||||
// Created time
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
||||
// Detailed description of the router
|
||||
Description string `json:"description"`
|
||||
|
||||
// User-friendly name for the router
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Whether the router is enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// Gateway ports
|
||||
GatewayPorts []GatewayPort `json:"gateway_ports"`
|
||||
|
||||
// ID of router
|
||||
ID string `json:"id"`
|
||||
|
||||
// Policies
|
||||
Policies []RouterPolicy `json:"policies"`
|
||||
|
||||
// Ports
|
||||
Ports []RouterPort `json:"ports"`
|
||||
|
||||
// Status
|
||||
Status Status `json:"status"`
|
||||
|
||||
// Update time
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// ID of version
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
type GatewayPort struct {
|
||||
// Created time
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
||||
// Description
|
||||
Description string `json:"description"`
|
||||
|
||||
// L4 port max
|
||||
ExternalL4PortMax int64 `json:"external_l4_port_max"`
|
||||
|
||||
// L4 port min
|
||||
ExternalL4PortMin int64 `json:"external_l4_port_min"`
|
||||
|
||||
// External network port
|
||||
ExternalNetworkPort interface{} `json:"external_network_port"`
|
||||
|
||||
// ID of port
|
||||
ID string `json:"id"`
|
||||
|
||||
// SNAT Enabled
|
||||
SNATEnabled bool `json:"snat_enabled"`
|
||||
|
||||
// Status
|
||||
Status Status `json:"status"`
|
||||
|
||||
// Update time
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// ID of version
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
type RouterPolicy struct {
|
||||
// Action
|
||||
Action string `json:"action"`
|
||||
|
||||
// Created time
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
||||
// User-friendly name for the policy
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Whether the policy is enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// ID of router policy
|
||||
ID string `json:"id"`
|
||||
|
||||
// Match
|
||||
Match interface{} `json:"match"`
|
||||
|
||||
// Next IPv4 address
|
||||
NextIPv4Address []string `json:"next_ipv4_address"`
|
||||
|
||||
// Next IPv6 address
|
||||
NextIPv6Address []string `json:"next_ipv6_address"`
|
||||
|
||||
// Priority number
|
||||
Priority int64 `json:"priority"`
|
||||
|
||||
// Update time
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// ID of version
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
type RouterPort struct {
|
||||
// Created at
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
||||
// Detailed description of the router port
|
||||
Description string `json:"description"`
|
||||
|
||||
// Whether the router port is enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// ID of router port
|
||||
ID string `json:"id"`
|
||||
|
||||
// Next IPv4 address
|
||||
IPv4Address string `json:"ipv4_address"`
|
||||
|
||||
// Next IPv6 address
|
||||
IPv6Address string `json:"ipv6_address"`
|
||||
|
||||
// IPv6 Config
|
||||
IPv6Config IPv6Config `json:"ipv6_config"`
|
||||
|
||||
// MAC address
|
||||
MAC string `json:"mac"`
|
||||
|
||||
// Segment
|
||||
Segment Segment `json:"segment"`
|
||||
|
||||
// Segment ID
|
||||
SegmentID string `json:"segment_id"`
|
||||
|
||||
// Status
|
||||
Status Status `json:"status"`
|
||||
|
||||
// Update time
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// ID of version
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
type Segment struct {
|
||||
// Access group ID
|
||||
AccessGroupID string `json:"access_group_id"`
|
||||
|
||||
// Access group name
|
||||
AccessGroupName string `json:"access_group_name"`
|
||||
|
||||
// Created time
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
||||
// Detailed description of the router port
|
||||
Description string `json:"description"`
|
||||
|
||||
// DHCP IPv4
|
||||
DHCPv4 DHCPv4Config `json:"dhcp_v4"`
|
||||
|
||||
// DHCP IPv6
|
||||
DHCPv6 DHCPv6Config `json:"dhcp_v6"`
|
||||
|
||||
// User-friendly name for the segment
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Whether the segment is enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// ID of segment
|
||||
ID string `json:"id"`
|
||||
|
||||
// Logical ports info
|
||||
LogicalPortsInfo []EntityInfo `json:"logical_ports_info"`
|
||||
|
||||
// Routers info
|
||||
RoutersInfo []EntityInfo `json:"routers_info"`
|
||||
|
||||
// Status
|
||||
Status Status `json:"status"`
|
||||
|
||||
// IPv4 subnet in CIDR notation
|
||||
SubnetV4 string `json:"subnet_v4"`
|
||||
|
||||
// IPv6 subnet in CIDR notation
|
||||
SubnetV6 string `json:"subnet_v6"`
|
||||
|
||||
// Update time
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// ID of version
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
type DHCPv4Config struct {
|
||||
// DNS
|
||||
DNS []string `json:"dns"`
|
||||
|
||||
// Excluded address ranges
|
||||
ExcludedAddressRanges []string `json:"excluded_address_ranges"`
|
||||
|
||||
// Gateway
|
||||
Gateway string `json:"gateway"`
|
||||
|
||||
// ID of config
|
||||
ID string `json:"id"`
|
||||
|
||||
// Lease time
|
||||
LeaseTime int64 `json:"lease_time"`
|
||||
|
||||
// Server IP
|
||||
ServerIP string `json:"server_ip"`
|
||||
|
||||
// Server MAC
|
||||
ServerMAC string `json:"server_mac"`
|
||||
|
||||
// Whether the config is enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
type DHCPv6Config struct {
|
||||
// Address prefix
|
||||
AddressPrefix string `json:"address_prefix"`
|
||||
|
||||
// DNS
|
||||
DNS []string `json:"dns"`
|
||||
|
||||
// ID of config
|
||||
ID string `json:"id"`
|
||||
|
||||
// Lease time
|
||||
LeaseTime int64 `json:"lease_time"`
|
||||
|
||||
// Server MAC
|
||||
ServerMAC string `json:"server_mac"`
|
||||
|
||||
// Whether the config is enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
type EntityInfo struct {
|
||||
// User-friendly name for the entity
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// ID of entity
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
type Status struct {
|
||||
// Common
|
||||
Common string `json:"common"`
|
||||
|
||||
// Hypervisors status
|
||||
Hypervisors []HypervisorStatus `json:"hypervisors"`
|
||||
}
|
||||
|
||||
type HypervisorStatus struct {
|
||||
// Status
|
||||
Status string `json:"status"`
|
||||
|
||||
// Name of hypervisor
|
||||
Name string `json:"name"`
|
||||
|
||||
// User-friendly name for the hypervisor
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Hypervisor status
|
||||
HypervisorStatus string `json:"hypervisor_status"`
|
||||
|
||||
// Synced time
|
||||
SyncedAt time.Time `json:"synced_at"`
|
||||
}
|
||||
|
||||
type ExternalNetworkAddPortsResponce struct {
|
||||
// ID of extnet port
|
||||
ID string `json:"id"`
|
||||
|
||||
// ID of extnet
|
||||
ExtNetID string `json:"external_network_id"`
|
||||
|
||||
// User-friendly name for the external network port
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Comment
|
||||
Comment string `json:"comment"`
|
||||
|
||||
// Mac
|
||||
MAC string `json:"mac"`
|
||||
|
||||
// IPv4 gateway address
|
||||
IPv4 string `json:"ipv4"`
|
||||
|
||||
// IPv6 gateway address
|
||||
IPv6 string `json:"ipv6"`
|
||||
|
||||
// IPv6 config
|
||||
IPv6Config IPv6Config `json:"ipv6_config"`
|
||||
|
||||
// Whether the network port is enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// ID of version
|
||||
VersionID uint64 `json:"version_id"`
|
||||
|
||||
// Router gateway port
|
||||
RouterGatewayPort RouterGatewayPort `json:"router_gateway_port"`
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
package extnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// PortAddRequest struct for add port to extnet
|
||||
type PortAddRequest struct {
|
||||
// ID of external network
|
||||
// Required: true
|
||||
ExtNetID string `url:"external_network_id" json:"external_network_id" validate:"required"`
|
||||
|
||||
// Access group ID
|
||||
// Required: true
|
||||
AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
|
||||
|
||||
// ID of version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// Description of the port addition operation
|
||||
// Required: true
|
||||
Comment string `url:"comment" json:"comment" 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"`
|
||||
|
||||
// IPv4
|
||||
// Required: false
|
||||
IPv4 string `url:"ipv4,omitempty" json:"ipv4,omitempty"`
|
||||
|
||||
// IPv6
|
||||
// Required: false
|
||||
IPv6 string `url:"ipv6,omitempty" json:"ipv6,omitempty"`
|
||||
|
||||
// IPv6 Config
|
||||
// Required: false
|
||||
IPv6Config *IPv6ConfigRequest `url:"-" json:"ipv6_config,omitempty"`
|
||||
|
||||
// MAC address
|
||||
// Required: false
|
||||
MAC string `url:"mac,omitempty" json:"mac,omitempty"`
|
||||
}
|
||||
|
||||
// AddPort added a port an external network
|
||||
func (e ExtNet) AddPort(ctx context.Context, req PortAddRequest) (*ExternalNetworkAddPortsResponce, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/external_network/port_add"
|
||||
|
||||
res, err := e.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := ExternalNetworkAddPortsResponce{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
package extnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// PortUpdateRequest struct for update port to extnet
|
||||
type PortUpdateRequest struct {
|
||||
// ID of external network
|
||||
// Required: true
|
||||
ExtNetID string `url:"external_network_id" json:"external_network_id" validate:"required"`
|
||||
|
||||
// Access group ID
|
||||
// Required: true
|
||||
AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
|
||||
|
||||
// Port ID
|
||||
// Required: true
|
||||
PortID string `url:"port_id" json:"port_id" validate:"required"`
|
||||
|
||||
// Port version ID
|
||||
// Required: true
|
||||
PortVersionID uint64 `url:"port_version_id" json:"port_version_id" validate:"required"`
|
||||
|
||||
// ID of version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// Description of the port addition operation
|
||||
// Required: true
|
||||
Comment string `url:"comment" json:"comment" 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"`
|
||||
|
||||
// IPv4
|
||||
// Required: false
|
||||
IPv4 string `url:"ipv4,omitempty" json:"ipv4,omitempty"`
|
||||
|
||||
// IPv6
|
||||
// Required: false
|
||||
IPv6 string `url:"ipv6,omitempty" json:"ipv6,omitempty"`
|
||||
|
||||
// IPv6 Config
|
||||
// Required: false
|
||||
IPv6Config *IPv6ConfigRequest `url:"-" json:"ipv6_config,omitempty"`
|
||||
|
||||
// MAC address
|
||||
// Required: false
|
||||
MAC string `url:"mac,omitempty" json:"mac,omitempty"`
|
||||
}
|
||||
|
||||
// UpdatePort updated a port an external network
|
||||
func (e ExtNet) UpdatePort(ctx context.Context, req PortUpdateRequest) (*ExternalNetworkResponse, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/external_network/port_update"
|
||||
|
||||
res, err := e.client.DecortApiCallCtype(ctx, http.MethodPut, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := ExternalNetworkResponse{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
package extnet
|
||||
|
||||
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 extnet
|
||||
type UpdateRequest struct {
|
||||
// ID of external network
|
||||
// Required: true
|
||||
ExtNetID string `url:"external_network_id" json:"external_network_id" validate:"required"`
|
||||
|
||||
// ID of version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// Bridge network name
|
||||
// Required: true
|
||||
BridgeNetworkName string `url:"bridge_network_name" json:"bridge_network_name" 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"`
|
||||
|
||||
// List of hypervisor names
|
||||
// Required: true
|
||||
Hypervisors []string `url:"hypervisors" json:"hypervisors" validate:"required"`
|
||||
|
||||
// Access group ID
|
||||
// Required: false
|
||||
AccessGroupID string `url:"access_group_id,omitempty" json:"access_group_id,omitempty"`
|
||||
|
||||
// IPv4 default gateway address
|
||||
// Required: false
|
||||
DefaultGatewayIPv4 string `url:"default_gateway_ipv4,omitempty" json:"default_gateway_ipv4,omitempty"`
|
||||
|
||||
// IPv6 default gateway address
|
||||
// Required: false
|
||||
DefaultGatewayIPv6 string `url:"default_gateway_ipv6,omitempty" json:"default_gateway_ipv6,omitempty"`
|
||||
|
||||
// Whether the network is enabled
|
||||
// Required: true
|
||||
Enabled bool `url:"enabled" json:"enabled"`
|
||||
|
||||
// IPv4 subnet in CIDR notation (Either subnet_v4 or subnet_v6 must be specified)
|
||||
// Required: false
|
||||
SubnetV4 string `url:"subnet_v4,omitempty" json:"subnet_v4,omitempty"`
|
||||
|
||||
// IPv6 subnet in CIDR notation (Either subnet_v4 or subnet_v6 must be specified)
|
||||
// Required: false
|
||||
SubnetV6 string `url:"subnet_v6,omitempty" json:"subnet_v6,omitempty"`
|
||||
|
||||
// VLAN tag identifier
|
||||
// Required: false
|
||||
VLANTag string `url:"vlan_tag,omitempty" json:"vlan_tag,omitempty" validate:"omitempty,trunkTags"`
|
||||
}
|
||||
|
||||
// Update updated an external network
|
||||
func (e ExtNet) Update(ctx context.Context, req UpdateRequest) (*ExternalNetworkResponse, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/external_network/update"
|
||||
|
||||
res, err := e.client.DecortApiCallCtype(ctx, http.MethodPut, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := ExternalNetworkResponse{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package sdn
|
||||
|
||||
import (
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/flips"
|
||||
)
|
||||
|
||||
// Accessing the SDN method group
|
||||
func (sdn *SDN) FloatingIPs() *flips.FloatingIPs {
|
||||
return flips.New(sdn.client)
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package flips
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
type CreateRequest struct {
|
||||
// Access Group ID
|
||||
// Required: true
|
||||
AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
|
||||
|
||||
// ID of an external network port
|
||||
// Required: true
|
||||
ExtNetPortID string `url:"external_network_port_id" json:"external_network_port_id" validate:"required"`
|
||||
|
||||
// ID of a logical network port
|
||||
// Required: true
|
||||
LogicalPortID string `url:"logical_port_id" json:"logical_port_id" validate:"required"`
|
||||
|
||||
// ID of a router
|
||||
// Required: true
|
||||
RouterID string `url:"router_id" json:"router_id" validate:"required"`
|
||||
}
|
||||
|
||||
// Create creates a floating ip
|
||||
func (fi FloatingIPs) Create(ctx context.Context, req CreateRequest) (*RecordFloatingIP, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/floating_ip/create"
|
||||
|
||||
res, err := fi.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := RecordFloatingIP{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package flips
|
||||
|
||||
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 floating ip
|
||||
type DeleteRequest struct {
|
||||
// ID of a floating IP
|
||||
// Required: true
|
||||
FloatingIPID string `url:"floating_ip_id" json:"floating_ip_id" validate:"required"`
|
||||
|
||||
// Version ID
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// Force delete
|
||||
// Required: false
|
||||
Force bool `url:"force,omitempty" json:"force,omitempty"`
|
||||
}
|
||||
|
||||
// Delete a floating ip
|
||||
func (fi FloatingIPs) Delete(ctx context.Context, req DeleteRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/floating_ip/delete"
|
||||
|
||||
res, err := fi.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
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package flips
|
||||
|
||||
// FilterByID returns FloatingIPsList with specified ID.
|
||||
func (fil FloatingIPsList) FilterByID(id string) FloatingIPsList {
|
||||
predicate := func(fi RecordFloatingIP) bool {
|
||||
return fi.ID == id
|
||||
}
|
||||
|
||||
return fil.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterByName returns FloatingIPsList with specified AccessGroupName.
|
||||
func (fil FloatingIPsList) FilterByAccessGroupName(name string) FloatingIPsList {
|
||||
predicate := func(fi RecordFloatingIP) bool {
|
||||
return fi.AccessGroupName == name
|
||||
}
|
||||
|
||||
return fil.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterFunc allows filtering FloatingIPsList based on a user-specified predicate.
|
||||
func (fil FloatingIPsList) FilterFunc(predicate func(fi RecordFloatingIP) bool) FloatingIPsList {
|
||||
var result FloatingIPsList
|
||||
|
||||
for _, acc := range fil.Objects {
|
||||
if predicate(acc) {
|
||||
result.Objects = append(result.Objects, acc)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// FindOne returns first element.
|
||||
// If none was found, returns an empty struct.
|
||||
func (fil FloatingIPsList) FindOne() RecordFloatingIP {
|
||||
if len(fil.Objects) == 0 {
|
||||
return RecordFloatingIP{}
|
||||
}
|
||||
|
||||
return fil.Objects[0]
|
||||
}
|
||||
@ -0,0 +1,196 @@
|
||||
package flips
|
||||
|
||||
import "testing"
|
||||
|
||||
var testFloatingIPs = FloatingIPsList{
|
||||
Objects: []RecordFloatingIP{
|
||||
{
|
||||
AccessGroupID: "testid",
|
||||
AccessGroupName: "testname",
|
||||
CreatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
ExternalNetworkPort: ExternalNetworkPort{
|
||||
AccessGroupID: "somegroup",
|
||||
AccessGroupName: "somename",
|
||||
Comment: "some comment",
|
||||
DisplayName: "some display name",
|
||||
Enabled: true,
|
||||
ExternalNetworkID: "someid",
|
||||
ID: "someid",
|
||||
IPv4: "someipv4",
|
||||
MAC: "somemac",
|
||||
VersionID: 1111111111111,
|
||||
},
|
||||
ID: "someid",
|
||||
LogicalPort: LogicalPort{
|
||||
ID: "someid",
|
||||
AccessGroupID: "someid",
|
||||
AccessGroupName: "somename",
|
||||
AdapterMAC: "somemac",
|
||||
AddressDetection: false,
|
||||
Description: "some description",
|
||||
DisplayName: "some display name",
|
||||
Enabled: true,
|
||||
Hypervisor: "hypervisor",
|
||||
HypervisorDisplayName: "hypervisor display name",
|
||||
UniqueIdentifier: "someid",
|
||||
VersionID: 1111111111111,
|
||||
CreatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
UpdatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
},
|
||||
Router: Router{
|
||||
ID: "someid",
|
||||
AccessGroupID: "someid",
|
||||
AccessGroupName: "somename",
|
||||
CreatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
DisplayName: "some display name",
|
||||
Enabled: true,
|
||||
UpdatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
VersionID: 1111111111111,
|
||||
},
|
||||
UpdatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
VersionID: 1111111111111,
|
||||
},
|
||||
{
|
||||
AccessGroupID: "testid3",
|
||||
AccessGroupName: "testname3",
|
||||
CreatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
ExternalNetworkPort: ExternalNetworkPort{
|
||||
AccessGroupID: "somegroup",
|
||||
AccessGroupName: "somename",
|
||||
Comment: "some comment",
|
||||
DisplayName: "some display name",
|
||||
Enabled: true,
|
||||
ExternalNetworkID: "someid2",
|
||||
ID: "someid",
|
||||
IPv4: "someipv4",
|
||||
MAC: "somemac",
|
||||
VersionID: 1111111111112,
|
||||
},
|
||||
ID: "someid2",
|
||||
LogicalPort: LogicalPort{
|
||||
ID: "someid2",
|
||||
AccessGroupID: "someid",
|
||||
AccessGroupName: "somename",
|
||||
AdapterMAC: "somemac",
|
||||
AddressDetection: false,
|
||||
Description: "some description",
|
||||
DisplayName: "some display name",
|
||||
Enabled: true,
|
||||
Hypervisor: "hypervisor",
|
||||
HypervisorDisplayName: "hypervisor display name",
|
||||
UniqueIdentifier: "someid",
|
||||
VersionID: 1111111111112,
|
||||
CreatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
UpdatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
},
|
||||
Router: Router{
|
||||
ID: "someid2",
|
||||
AccessGroupID: "someid",
|
||||
AccessGroupName: "somename",
|
||||
CreatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
DisplayName: "some display name",
|
||||
Enabled: true,
|
||||
UpdatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
VersionID: 1111111111112,
|
||||
},
|
||||
UpdatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
VersionID: 1111111111112,
|
||||
},
|
||||
{
|
||||
AccessGroupID: "testid3",
|
||||
AccessGroupName: "testname3",
|
||||
CreatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
ExternalNetworkPort: ExternalNetworkPort{
|
||||
AccessGroupID: "somegroup",
|
||||
AccessGroupName: "somename",
|
||||
Comment: "some comment",
|
||||
DisplayName: "some display name",
|
||||
Enabled: true,
|
||||
ExternalNetworkID: "someid3",
|
||||
ID: "someid3",
|
||||
IPv4: "someipv4",
|
||||
MAC: "somemac",
|
||||
VersionID: 1111111111113,
|
||||
},
|
||||
ID: "someid3",
|
||||
LogicalPort: LogicalPort{
|
||||
ID: "someid3",
|
||||
AccessGroupID: "someid",
|
||||
AccessGroupName: "somename",
|
||||
AdapterMAC: "somemac",
|
||||
AddressDetection: false,
|
||||
Description: "some description",
|
||||
DisplayName: "some display name",
|
||||
Enabled: true,
|
||||
Hypervisor: "hypervisor",
|
||||
HypervisorDisplayName: "hypervisor display name",
|
||||
UniqueIdentifier: "someid",
|
||||
VersionID: 1111111111113,
|
||||
CreatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
UpdatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
},
|
||||
Router: Router{
|
||||
ID: "someid3",
|
||||
AccessGroupID: "someid",
|
||||
AccessGroupName: "somename",
|
||||
CreatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
DisplayName: "some display name",
|
||||
Enabled: true,
|
||||
UpdatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
VersionID: 1111111111113,
|
||||
},
|
||||
UpdatedAt: "2025-09-23T08:05:59.271458Z",
|
||||
VersionID: 1111111111113,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestFilterByID(t *testing.T) {
|
||||
actual := testFloatingIPs.FilterByID("someid").FindOne()
|
||||
|
||||
if actual.ID != "someid" {
|
||||
t.Fatal("actual:", actual.ID, "> expected: someid")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByName(t *testing.T) {
|
||||
actual := testFloatingIPs.FilterByAccessGroupName("testname").FindOne()
|
||||
|
||||
if actual.AccessGroupName != "testname" {
|
||||
t.Fatal("actual:", actual.AccessGroupID, ">> expected: testname")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterFunc(t *testing.T) {
|
||||
actual := testFloatingIPs.FilterFunc(func(rfi RecordFloatingIP) bool {
|
||||
return rfi.VersionID == 1111111111111
|
||||
})
|
||||
|
||||
if len(actual.Objects) != 1 || actual.Objects[0].ID != "someid" {
|
||||
t.Fatal("Expected 1 policy with version ID 1111111111111, found:", len(actual.Objects))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindOneWithResults(t *testing.T) {
|
||||
result := testFloatingIPs.FilterByID("someid").FindOne()
|
||||
if result.ID != "someid" {
|
||||
t.Fatal("Expected someid, got:", result.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindOneEmpty(t *testing.T) {
|
||||
emptyList := FloatingIPsList{}
|
||||
result := emptyList.FindOne()
|
||||
|
||||
if result.ID != "" || result.AccessGroupID != "" {
|
||||
t.Fatal("Expected empty FloatingIP, got:", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByIDNotFound(t *testing.T) {
|
||||
actual := testFloatingIPs.FilterByID("nonex")
|
||||
|
||||
if len(actual.Objects) != 0 {
|
||||
t.Fatal("Expected 0 policies, found:", len(actual.Objects))
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
// API Actor API for managing SDN floating IPs
|
||||
package flips
|
||||
|
||||
import (
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
|
||||
)
|
||||
|
||||
// Structure for creating request to floating IPs
|
||||
type FloatingIPs struct {
|
||||
client interfaces.Caller
|
||||
}
|
||||
|
||||
// Builder for floating IPs endpoints
|
||||
func New(client interfaces.Caller) *FloatingIPs {
|
||||
return &FloatingIPs{
|
||||
client,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package flips
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
type GetRequest struct {
|
||||
// ID of a floating IP
|
||||
// Required: true
|
||||
FloatingIPID string `url:"floating_ip_id" json:"floating_ip_id" validate:"required"`
|
||||
}
|
||||
|
||||
// Get gets a floating ip details as a RecordFloatingIP struct
|
||||
func (fi FloatingIPs) Get(ctx context.Context, req GetRequest) (*RecordFloatingIP, error) {
|
||||
res, err := fi.GetRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := RecordFloatingIP{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
|
||||
}
|
||||
|
||||
// GetRaw gets a floating ip details as an array of bytes
|
||||
func (fi FloatingIPs) GetRaw(ctx context.Context, req GetRequest) ([]byte, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/floating_ip/get"
|
||||
|
||||
res, err := fi.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
return res, err
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
package flips
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// List of floating ips
|
||||
type ListRequest struct {
|
||||
// Filter by access group ID
|
||||
// Required: false
|
||||
AccessGroupID string `url:"access_group_id,omitempty" json:"access_group_id,omitempty"`
|
||||
|
||||
//Is the external network enabled
|
||||
// Required: false
|
||||
Enabled interface{} `url:"enabled,omitempty" json:"enabled,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// Filter by Pv4 of the associated external network port
|
||||
// Required: false
|
||||
ExternalNetworkPortIPv4 string `url:"external_network_port_ipv4,omitempty" json:"external_network_port_ipv4,omitempty"`
|
||||
|
||||
// Filter by IP of the associated logical port binding
|
||||
// Required: false
|
||||
LogicalPortBindingIP string `url:"logical_port_binding_ip,omitempty" json:"logical_port_binding_ip,omitempty"`
|
||||
|
||||
// Display name of the associated logical port
|
||||
// Required: false
|
||||
LogicalPortDisplayName string `url:"logical_port_display_name,omitempty" json:"logical_port_display_name,omitempty"`
|
||||
|
||||
// Filter by display name of the associated external network
|
||||
// Required: false
|
||||
ExternalNetworkDisplayName string `url:"external_network_display_name,omitempty" json:"external_network_display_name,omitempty"`
|
||||
|
||||
// Filter by display name of the associated router
|
||||
// Required: false
|
||||
RouterDisplayName string `url:"router_display_name,omitempty" json:"router_display_name,omitempty"`
|
||||
|
||||
// Updated at lower bound (greater than or equal to)
|
||||
// Required: false
|
||||
UpdatedFrom string `url:"updated_from,omitempty" json:"updated_from,omitempty"`
|
||||
|
||||
// Updated at upper bound (less than)
|
||||
// Required: false
|
||||
UpdatedTo string `url:"updated_to,omitempty" json:"updated_to,omitempty"`
|
||||
|
||||
// Created at lower bound (greater than or equal to)
|
||||
// Required: false
|
||||
CreatedFrom string `url:"created_from,omitempty" json:"created_from,omitempty"`
|
||||
|
||||
// Created at upper bound (less than)
|
||||
// Required: false
|
||||
CreatedTo string `url:"created_to,omitempty" json:"created_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 (enabled, created_at, updated_at, external_network_port_ipv4, logical_port_binding_ip, logical_port_display_name, external_network_display_name, router_display_name)
|
||||
// Required: false
|
||||
SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty"`
|
||||
|
||||
// Sort order (asc/desc)
|
||||
// Required: false
|
||||
SortOrder string `url:"sort_order,omitempty" json:"sort_order,omitempty"`
|
||||
}
|
||||
|
||||
// List of floating ips
|
||||
func (fi FloatingIPs) List(ctx context.Context, req ListRequest) (*FloatingIPsList, error) {
|
||||
res, err := fi.ListRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
objects := []RecordFloatingIP{}
|
||||
|
||||
err = json.Unmarshal(res, &objects)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := FloatingIPsList{Objects: objects}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// ListRaw gets a list of all floating ips as an array of bytes
|
||||
func (fi FloatingIPs) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/floating_ip/list"
|
||||
|
||||
res, err := fi.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
return res, err
|
||||
}
|
||||
@ -0,0 +1,145 @@
|
||||
package flips
|
||||
|
||||
// List of floating ips
|
||||
type FloatingIPsList struct {
|
||||
Objects []RecordFloatingIP
|
||||
}
|
||||
|
||||
// Main info about a floating ip
|
||||
type RecordFloatingIP struct {
|
||||
// Access group ID
|
||||
AccessGroupID string `json:"access_group_id"`
|
||||
|
||||
// Access group name
|
||||
AccessGroupName string `json:"access_group_name"`
|
||||
|
||||
// Created at
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// Details of an external network port
|
||||
ExternalNetworkPort ExternalNetworkPort `json:"external_network_port"`
|
||||
|
||||
// ID of a floating IP
|
||||
ID string `json:"id"`
|
||||
|
||||
// Details of a logical port
|
||||
LogicalPort LogicalPort `json:"logical_port"`
|
||||
|
||||
// Details of a router
|
||||
Router Router `json:"router"`
|
||||
|
||||
// Updated at
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
// Info about a router
|
||||
type Router struct {
|
||||
// Access group ID
|
||||
AccessGroupID string `json:"access_group_id"`
|
||||
|
||||
// Access group name
|
||||
AccessGroupName string `json:"access_group_name"`
|
||||
|
||||
// Created at
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// Description
|
||||
Description string `json:"description"`
|
||||
|
||||
// Display name
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Is a security policy enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Updated at
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
// Info about a logical port
|
||||
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"`
|
||||
|
||||
// Is address detected
|
||||
AddressDetection bool `json:"address_detection"`
|
||||
|
||||
// Description
|
||||
Description string `json:"description"`
|
||||
|
||||
// Created at
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// Display name
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Is a logical port enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// Hypervisor
|
||||
Hypervisor string `json:"hypervisor"`
|
||||
|
||||
// Hypervisor display name
|
||||
HypervisorDisplayName string `json:"hypervisor_display_name"`
|
||||
|
||||
// Unique identifier
|
||||
UniqueIdentifier string `json:"unique_identifier"`
|
||||
|
||||
// Updated at
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
// Details of external network ports
|
||||
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"`
|
||||
|
||||
// Is a security policy enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// External network ID
|
||||
ExternalNetworkID string `json:"external_network_id"`
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// IP v4
|
||||
IPv4 string `json:"ipv4"`
|
||||
|
||||
// MAC
|
||||
MAC string `json:"mac"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
package flips
|
||||
|
||||
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 a floating ip
|
||||
type UpdateRequest struct {
|
||||
// ID of a floating IP
|
||||
// Required: true
|
||||
FloatingIPID string `url:"floating_ip_id" json:"floating_ip_id" validate:"required"`
|
||||
|
||||
// Version ID
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// ID of an external network port
|
||||
// Required: true
|
||||
ExtNetPortID string `url:"external_network_port_id" json:"external_network_port_id" validate:"required"`
|
||||
|
||||
// ID of a logical network port
|
||||
// Required: true
|
||||
LogicalPortID string `url:"logical_port_id" json:"logical_port_id" validate:"required"`
|
||||
|
||||
// ID of a router
|
||||
// Required: true
|
||||
RouterID string `url:"router_id" json:"router_id" validate:"required"`
|
||||
}
|
||||
|
||||
// Update updates a floating ip
|
||||
func (fi FloatingIPs) Update(ctx context.Context, req UpdateRequest) (*RecordFloatingIP, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/floating_ip/update"
|
||||
|
||||
res, err := fi.client.DecortApiCallCtype(ctx, http.MethodPut, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := RecordFloatingIP{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package sdn
|
||||
|
||||
import (
|
||||
lp "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/logicalports"
|
||||
)
|
||||
|
||||
// Accessing the SDN method group
|
||||
func (sdn *SDN) LogicalPorts() *lp.LogicalPorts {
|
||||
return lp.New(sdn.client)
|
||||
}
|
||||
@ -0,0 +1,112 @@
|
||||
package logicalports
|
||||
|
||||
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 logical port
|
||||
type CreateRequest struct {
|
||||
// ID of the logical port
|
||||
// Required: true
|
||||
LogicalPortID string `url:"logical_port_id" json:"logical_port_id" validate:"required"`
|
||||
|
||||
// ID of the version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// ID of the access group
|
||||
// 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"`
|
||||
|
||||
// Display name
|
||||
// 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"`
|
||||
|
||||
// Is excluded from firewall. True or False
|
||||
// Required: true
|
||||
IsExcludedFromFirewall interface{} `url:"is_excluded_from_firewall" json:"is_excluded_from_firewall" validate:"required,isBool"`
|
||||
|
||||
// Hypervisor
|
||||
// Required: true
|
||||
Hypervisor string `url:"hypervisor" json:"hypervisor" validate:"required"`
|
||||
|
||||
// Port security. True or False
|
||||
// Required: true
|
||||
PortSecurity interface{} `url:"port_security" json:"port_security" validate:"required,isBool"`
|
||||
|
||||
// Segment ID
|
||||
// Required: true
|
||||
SegmentID string `url:"segment_id" json:"segment_id" validate:"required"`
|
||||
|
||||
// Adapter MAC
|
||||
// Required: false
|
||||
AdapterMAC string `url:"adapter_mac,omitempty" json:"adapter_mac,omitempty"`
|
||||
|
||||
// Unique identifier
|
||||
// Required: false
|
||||
UniqueIdentifier string `url:"unique_identifier,omitempty" json:"unique_identifier,omitempty"`
|
||||
|
||||
// Logical port addresses
|
||||
// Required: false
|
||||
LogicalPortAddresses []LogicalPortAddress `url:"logical_port_addresses,omitempty" json:"logical_port_addresses,omitempty" validate:"dive"`
|
||||
}
|
||||
|
||||
// LogicalPortAddressRequest struct representing logical port address
|
||||
type LogicalPortAddressRequest struct {
|
||||
// IP address
|
||||
// Required: true
|
||||
IP string `url:"ip" json:"ip" validate:"required"`
|
||||
|
||||
// IP type
|
||||
// Required: true
|
||||
IPType string `url:"ip_type" json:"ip_type" validate:"required,oneof=IPv4 IPv6"`
|
||||
|
||||
// Is primary. True or False
|
||||
// Required: true
|
||||
IsPrimary interface{} `url:"is_primary" json:"is_primary" validate:"required,isBool"`
|
||||
|
||||
// MAC address
|
||||
// Required: false
|
||||
MAC string `url:"mac,omitempty" json:"mac,omitempty"`
|
||||
|
||||
// Is discovered. True or False
|
||||
// Required: false
|
||||
IsDiscovered interface{} `url:"is_discovered,omitempty" json:"is_discovered,omitempty" validate:"omitempty,isBool"`
|
||||
}
|
||||
|
||||
// Create creates a logical port
|
||||
func (l LogicalPorts) Create(ctx context.Context, req CreateRequest) (*LogicalPort, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/logical_port/create"
|
||||
|
||||
res, err := l.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := LogicalPort{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package logicalports
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// DeleteRequest struct to delete logical port
|
||||
type DeleteRequest struct {
|
||||
// Port ID
|
||||
// Required: true
|
||||
ID string `url:"logical_port_id" json:"logical_port_id" validate:"required"`
|
||||
|
||||
// Version
|
||||
// Required: true
|
||||
Version uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// Force delete. True or false
|
||||
// Required: false
|
||||
Force interface{} `url:"force,omitempty" json:"force,omitempty" validate:"omitempty,isBool"`
|
||||
}
|
||||
|
||||
// Delete a logical port
|
||||
func (i LogicalPorts) Delete(ctx context.Context, req DeleteRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/logical_port/delete"
|
||||
|
||||
_, err = i.client.DecortApiCallCtype(ctx, http.MethodDelete, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package logicalports
|
||||
|
||||
// FilterByID returns LogicalPortsList with specified ID.
|
||||
func (agl LogicalPortsList) FilterByID(id string) LogicalPortsList {
|
||||
predicate := func(ia LogicalPort) bool {
|
||||
return ia.ID == id
|
||||
}
|
||||
|
||||
return agl.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterByName returns LogicalPortsList with specified Name.
|
||||
func (agl LogicalPortsList) FilterByName(name string) LogicalPortsList {
|
||||
predicate := func(ia LogicalPort) bool {
|
||||
return ia.DisplayName == name
|
||||
}
|
||||
|
||||
return agl.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterFunc allows filtering LogicalPortsList based on a user-specified predicate.
|
||||
func (agl LogicalPortsList) FilterFunc(predicate func(LogicalPort) bool) LogicalPortsList {
|
||||
var result LogicalPortsList
|
||||
|
||||
for _, acc := range agl.Ports {
|
||||
if predicate(acc) {
|
||||
result.Ports = append(result.Ports, acc)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// FindOne returns first element.
|
||||
// If none was found, returns an empty struct.
|
||||
func (agl LogicalPortsList) FindOne() LogicalPort {
|
||||
if len(agl.Ports) == 0 {
|
||||
return LogicalPort{}
|
||||
}
|
||||
|
||||
return agl.Ports[0]
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package logicalports
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// GetRequest struct to get information about logical port
|
||||
type GetRequest struct {
|
||||
// ID a logical port
|
||||
// Required: true
|
||||
ID string `url:"logical_port_id" json:"logical_port_id" validate:"required"`
|
||||
}
|
||||
|
||||
// Get gets logical port details as a LogicalPort struct
|
||||
func (a LogicalPorts) Get(ctx context.Context, req GetRequest) (*LogicalPort, error) {
|
||||
res, err := a.GetRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := LogicalPort{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
|
||||
}
|
||||
|
||||
// GetRaw gets logical port details as an array of bytes
|
||||
func (a LogicalPorts) GetRaw(ctx context.Context, req GetRequest) ([]byte, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/logical_port/get"
|
||||
|
||||
res, err := a.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
return res, err
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package logicalports
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// GetByUniqueIdentifierRequest struct to get information about logical port
|
||||
type GetByUniqueIdentifierRequest struct {
|
||||
// ID a logical port
|
||||
// Required: true
|
||||
ID string `url:"unique_identifier" json:"unique_identifier" validate:"required"`
|
||||
}
|
||||
|
||||
// GetByUniqueIdentifier gets logical port details as a LogicalPort struct
|
||||
func (a LogicalPorts) GetByUniqueIdentifier(ctx context.Context, req GetByUniqueIdentifierRequest) (*LogicalPort, error) {
|
||||
res, err := a.GetByUniqueIdentifierRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := LogicalPort{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
|
||||
}
|
||||
|
||||
// GetByUniqueIdentifier gets logical port details as an array of bytes
|
||||
func (a LogicalPorts) GetByUniqueIdentifierRaw(ctx context.Context, req GetByUniqueIdentifierRequest) ([]byte, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/logical_port/get_by_unique_identifier"
|
||||
|
||||
res, err := a.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
return res, err
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package logicalports
|
||||
|
||||
// IDs gets array of IDs from LogicalPortList struct
|
||||
func (pl LogicalPortsList) IDs() []string {
|
||||
res := make([]string, 0, len(pl.Ports))
|
||||
for _, c := range pl.Ports {
|
||||
res = append(res, c.ID)
|
||||
}
|
||||
return res
|
||||
}
|
||||
@ -0,0 +1,120 @@
|
||||
package logicalports
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// ListRequest struct to get a list of logical ports
|
||||
type ListRequest struct {
|
||||
// Find by access group ID
|
||||
// Required: false
|
||||
AccessGroupID string `url:"access_group_id,omitempty" json:"access_group_id,omitempty"`
|
||||
|
||||
// Find by segment ID
|
||||
// Required: false
|
||||
SegmentID string `url:"segment_id,omitempty" json:"segment_id,omitempty"`
|
||||
|
||||
// Find by segment display name
|
||||
// Required: false
|
||||
SegmentDisplayName string `url:"segment_display_name,omitempty" json:"segment_display_name,omitempty"`
|
||||
|
||||
// Find by external network ID
|
||||
// Required: false
|
||||
ExternalNetworkID string `url:"external_network_id,omitempty" json:"external_network_id,omitempty"`
|
||||
|
||||
// Find by unique identifier
|
||||
// Required: false
|
||||
UniqueIdentifier string `url:"unique_identifier,omitempty" json:"unique_identifier,omitempty"`
|
||||
|
||||
// Find by display name
|
||||
// Required: false
|
||||
DisplayName string `url:"display_name,omitempty" json:"display_name,omitempty"`
|
||||
|
||||
// Find by adapter MAC address
|
||||
// Required: false
|
||||
AdapterMAC string `url:"adapter_mac,omitempty" json:"adapter_mac,omitempty"`
|
||||
|
||||
// Find by hypervisor
|
||||
// Required: false
|
||||
Hypervisor string `url:"hypervisor,omitempty" json:"hypervisor,omitempty"`
|
||||
|
||||
// Find by hypervisor display name
|
||||
// Required: false
|
||||
HypervisorDisplayName string `url:"hypervisor_display_name,omitempty" json:"hypervisor_display_name,omitempty"`
|
||||
|
||||
// Find by live migration target hypervisor
|
||||
// Required: false
|
||||
LiveMigrationTargetHv string `url:"live_migration_target_hv,omitempty" json:"live_migration_target_hv,omitempty"`
|
||||
|
||||
// Find by port security status, true or false
|
||||
// Required: false
|
||||
PortSecurity interface{} `url:"port_security,omitempty" json:"port_security,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// Find by address detection status, true or false
|
||||
// Required: false
|
||||
AddressDetection interface{} `url:"address_detection,omitempty" json:"address_detection,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// Find by enabled status, true or false
|
||||
// Required: false
|
||||
Enabled interface{} `url:"enabled,omitempty" json:"enabled,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// Creation date lower bound (inclusive)
|
||||
// Required: false
|
||||
CreatedFrom string `url:"created_from,omitempty" json:"created_from,omitempty"`
|
||||
|
||||
// Creation date upper bound (inclusive)
|
||||
// Required: false
|
||||
CreatedTo string `url:"created_to,omitempty" json:"created_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, created_at, updated_at, deleted_at, segment_id, hypervisor, port_security, segment_display_name, primary_address, hypervisor_display_name)
|
||||
// Required: false
|
||||
SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty"`
|
||||
|
||||
// Sort order (asc/desc)
|
||||
// Required: false
|
||||
SortOrder string `url:"sort_order,omitempty" json:"sort_order,omitempty"`
|
||||
}
|
||||
|
||||
// List of logical portts
|
||||
func (i LogicalPorts) List(ctx context.Context, req ListRequest) (*LogicalPortsList, error) {
|
||||
res, err := i.ListRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
groups := []LogicalPort{}
|
||||
|
||||
err = json.Unmarshal(res, &groups)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := LogicalPortsList{Ports: groups}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// ListRaw gets a list of all logical portts as an array of bytes
|
||||
func (a LogicalPorts) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/logical_port/list"
|
||||
|
||||
res, err := a.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
return res, err
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
// API Actor API for managing SDN logical ports
|
||||
package logicalports
|
||||
|
||||
import (
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
|
||||
)
|
||||
|
||||
// Structure for creating request to logical ports
|
||||
type LogicalPorts struct {
|
||||
client interfaces.Caller
|
||||
}
|
||||
|
||||
// Builder for logical ports endpoints
|
||||
func New(client interfaces.Caller) *LogicalPorts {
|
||||
return &LogicalPorts{
|
||||
client,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package logicalports
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// MigrateCancelRequest struct to cancel migrate
|
||||
type MigrateCancelRequest struct {
|
||||
// ID of the logical port
|
||||
// Required: true
|
||||
LogicalPortID string `url:"logical_port_id" json:"logical_port_id" validate:"required"`
|
||||
|
||||
// ID of the version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
}
|
||||
|
||||
func (i LogicalPorts) CancelMigrate(ctx context.Context, req MigrateCancelRequest) (*MigrationStatus, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/logical_port/migration_cancel"
|
||||
|
||||
res, err := i.client.DecortApiCallCtype(ctx, http.MethodDelete, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := MigrationStatus{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package logicalports
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// MigrateStartRequest struct to start migrate
|
||||
type MigrateStartRequest struct {
|
||||
// ID of the logical port
|
||||
// Required: true
|
||||
LogicalPortID string `url:"logical_port_id" json:"logical_port_id" validate:"required"`
|
||||
|
||||
// ID of the version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// Hypervisor
|
||||
// Required: true
|
||||
TargetHypervisor string `url:"target_hypervisor" json:"target_hypervisor" validate:"required"`
|
||||
}
|
||||
|
||||
func (i LogicalPorts) StartMigrate(ctx context.Context, req MigrateStartRequest) (*MigrationStatus, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/logical_port/migration_start"
|
||||
|
||||
res, err := i.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := MigrationStatus{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,158 @@
|
||||
package logicalports
|
||||
|
||||
// LogicalPortsList represents a list of logical ports
|
||||
type LogicalPortsList struct {
|
||||
Ports []LogicalPort `json:"ports"`
|
||||
}
|
||||
|
||||
// Main information about logical port
|
||||
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
|
||||
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
|
||||
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 hypervisor
|
||||
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
|
||||
Hypervisors []HypervisorStatus `json:"hypervisors"`
|
||||
}
|
||||
|
||||
// HypervisorStatus 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 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
|
||||
PortSecurity bool `json:"port_security"`
|
||||
|
||||
// Address detection
|
||||
AddressDetection bool `json:"address_detection"`
|
||||
|
||||
// Is excluded from firewall
|
||||
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
|
||||
LogicalPortAddresses []LogicalPortAddress `json:"logical_port_addresses"`
|
||||
}
|
||||
|
||||
// LogicalPortAddress information
|
||||
type LogicalPortAddress struct {
|
||||
// IP address
|
||||
IP string `json:"ip"`
|
||||
|
||||
// IP type
|
||||
IPType string `json:"ip_type"`
|
||||
|
||||
// Is discovered
|
||||
IsDiscovered bool `json:"is_discovered"`
|
||||
|
||||
// Is primary
|
||||
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 time
|
||||
AssignedAt string `json:"assigned_at"`
|
||||
}
|
||||
|
||||
type MigrationStatus struct {
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package logicalports
|
||||
|
||||
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 LogicalPortsList) Serialize(params ...string) (serialization.Serialized, error) {
|
||||
if len(la.Ports) == 0 {
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
if len(params) > 1 {
|
||||
prefix := params[0]
|
||||
indent := params[1]
|
||||
|
||||
return json.MarshalIndent(la, prefix, indent)
|
||||
}
|
||||
|
||||
return json.Marshal(la)
|
||||
}
|
||||
|
||||
// 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 (ia LogicalPort) Serialize(params ...string) (serialization.Serialized, error) {
|
||||
if len(params) > 1 {
|
||||
prefix := params[0]
|
||||
indent := params[1]
|
||||
|
||||
return json.MarshalIndent(ia, prefix, indent)
|
||||
}
|
||||
|
||||
return json.Marshal(ia)
|
||||
}
|
||||
@ -0,0 +1,135 @@
|
||||
package logicalports
|
||||
|
||||
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 logical port
|
||||
type UpdateRequest struct {
|
||||
// ID of the logical port
|
||||
// Required: true
|
||||
LogicalPortID string `url:"logical_port_id" json:"logical_port_id" validate:"required"`
|
||||
|
||||
// ID of the version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// Adapter MAC
|
||||
// Required: true
|
||||
AdapterMAC string `url:"adapter_mac" json:"adapter_mac" validate:"required"`
|
||||
|
||||
// Description
|
||||
// Required: true
|
||||
Description string `url:"description" json:"description" validate:"required"`
|
||||
|
||||
// Display name
|
||||
// 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"`
|
||||
|
||||
// Remove addresses
|
||||
// Required: false
|
||||
RemoveAddresses []string `url:"remove_addresses,omitempty" json:"remove_addresses,omitempty"`
|
||||
|
||||
// Hypervisor
|
||||
// Required: true
|
||||
Hypervisor string `url:"hypervisor" json:"hypervisor" validate:"required"`
|
||||
|
||||
// Port security. True or False
|
||||
// Required: true
|
||||
PortSecurity interface{} `url:"port_security" json:"port_security" validate:"required,isBool"`
|
||||
|
||||
// Is excluded from firewall. True or False
|
||||
// Required: true
|
||||
IsExcludedFromFirewall interface{} `url:"is_excluded_from_firewall" json:"is_excluded_from_firewall" validate:"required,isBool"`
|
||||
|
||||
// Segment ID
|
||||
// Required: true
|
||||
SegmentID string `url:"segment_id" json:"segment_id" validate:"required"`
|
||||
|
||||
// Update addresses
|
||||
// Required: false
|
||||
UpdateAddresses []UpdateAddress `url:"update_addresses,omitempty" json:"update_addresses,omitempty" validate:"dive"`
|
||||
|
||||
// Add addresses
|
||||
// Required: false
|
||||
AddAddresses []AddAddress `url:"add_addresses,omitempty" json:"add_addresses,omitempty" validate:"dive"`
|
||||
}
|
||||
|
||||
// UpdateAddress struct representing update address
|
||||
type UpdateAddress struct {
|
||||
// IP address
|
||||
// Required: true
|
||||
IP string `url:"ip" json:"ip" validate:"required"`
|
||||
|
||||
// IP type
|
||||
// Required: true
|
||||
IPType string `url:"ip_type" json:"ip_type" validate:"required,oneof=IPv4 IPv6"`
|
||||
|
||||
// Is discovered. True or False
|
||||
// Required: false
|
||||
IsDiscovered interface{} `url:"is_discovered,omitempty" json:"is_discovered,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// Is primary. True or False
|
||||
// Required: true
|
||||
IsPrimary interface{} `url:"is_primary" json:"is_primary" validate:"required,isBool"`
|
||||
|
||||
// MAC address
|
||||
// Required: false
|
||||
MAC string `url:"mac,omitempty" json:"mac,omitempty"`
|
||||
}
|
||||
|
||||
// AddAddress struct representing add address
|
||||
type AddAddress struct {
|
||||
// IP address
|
||||
// Required: true
|
||||
IP string `url:"ip" json:"ip" validate:"required"`
|
||||
|
||||
// IP type
|
||||
// Required: true
|
||||
IPType string `url:"ip_type" json:"ip_type" validate:"required,oneof=IPv4 IPv6"`
|
||||
|
||||
// Is discovered. True or False
|
||||
// Required: false
|
||||
IsDiscovered interface{} `url:"is_discovered,omitempty" json:"is_discovered,omitempty" validate:"omitempty,isBool"`
|
||||
|
||||
// Is primary. True or False
|
||||
// Required: true
|
||||
IsPrimary interface{} `url:"is_primary" json:"is_primary" validate:"required,isBool"`
|
||||
|
||||
// MAC address
|
||||
// Required: false
|
||||
MAC string `url:"mac,omitempty" json:"mac,omitempty"`
|
||||
}
|
||||
|
||||
// Update updates a logical port
|
||||
func (i LogicalPorts) Update(ctx context.Context, req UpdateRequest) (*LogicalPort, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/logical_port/update"
|
||||
|
||||
res, err := i.client.DecortApiCallCtype(ctx, http.MethodPut, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := LogicalPort{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package netobjgroups
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// AttachExtNetPortsRequest struct to attach external network ports to a network object group
|
||||
type AttachExtNetPortsRequest struct {
|
||||
// ID of a network object group
|
||||
// Required: true
|
||||
ObjectGroupID string `url:"object_group_id" json:"object_group_id" validate:"required"`
|
||||
|
||||
// ID of an access group
|
||||
// Required: true
|
||||
AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
|
||||
|
||||
// IDs of external network ports to attach to a network object group
|
||||
// Required: true
|
||||
PortIDs []string `url:"port_ids" json:"port_ids" validate:"required"`
|
||||
}
|
||||
|
||||
// AttachExtNetPorts attaches external network ports to a network object group
|
||||
func (nog NetworkObjectGroups) AttachExtNetPorts(ctx context.Context, req AttachExtNetPortsRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/network_object_group/attach_external_network_ports"
|
||||
|
||||
_, err = nog.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package netobjgroups
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// AttachLogicalPortsRequest struct to attach logical ports to a network object group
|
||||
type AttachLogicalPortsRequest struct {
|
||||
// ID of a network object group
|
||||
// Required: true
|
||||
ObjectGroupID string `url:"object_group_id" json:"object_group_id" validate:"required"`
|
||||
|
||||
// ID of an access group
|
||||
// Required: true
|
||||
AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
|
||||
|
||||
// Version ID
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// Port Bindings
|
||||
// Required: true
|
||||
PortBindings []PortBindings `url:"port_bindings" json:"port_bindings" validate:"required,dive"`
|
||||
}
|
||||
type PortBindings struct {
|
||||
// ID of a logical port
|
||||
// Required: true
|
||||
PortID string `url:"port_id" json:"port_id" validate:"required"`
|
||||
|
||||
// Version of a logical port
|
||||
// Required: true
|
||||
PortVersion int64 `url:"port_version" json:"port_version" validate:"required"`
|
||||
}
|
||||
|
||||
// AttachLogicalPorts attaches logical ports to a network object group
|
||||
func (nog NetworkObjectGroups) AttachLogicalPorts(ctx context.Context, req AttachLogicalPortsRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/network_object_group/attach_logical_ports"
|
||||
|
||||
_, err = nog.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
package netobjgroups
|
||||
|
||||
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 a network object group
|
||||
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
|
||||
// Required: true
|
||||
Name string `url:"name" json:"name" validate:"required"`
|
||||
|
||||
// Logical ports bindings
|
||||
// Required: false
|
||||
LogicalPortsBindings []LogicalPortsBindings `url:"logical_ports_binding,omitempty" json:"logical_ports_bindings,omitempty" validate:"omitempty,dive"`
|
||||
}
|
||||
type LogicalPortsBindings struct {
|
||||
// Port ID
|
||||
// Required: true
|
||||
PortID string `url:"port_id" json:"port_id" validate:"required"`
|
||||
|
||||
// Port version
|
||||
// Required: true
|
||||
PortVersion int64 `url:"port_version" json:"port_version" validate:"required"`
|
||||
}
|
||||
|
||||
// Create creates a network object group
|
||||
func (nog NetworkObjectGroups) Create(ctx context.Context, req CreateRequest) (*RecordNetObjGroup, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/network_object_group/create"
|
||||
|
||||
res, err := nog.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := RecordNetObjGroup{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package netobjgroups
|
||||
|
||||
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 network object group
|
||||
type DeleteRequest struct {
|
||||
// ID of a network object group
|
||||
// Required: true
|
||||
ObjectGroupID string `url:"object_group_id" json:"object_group_id" validate:"required"`
|
||||
|
||||
// Version ID
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// Force delete
|
||||
// Required: false
|
||||
Force bool `url:"force,omitempty" json:"force,omitempty"`
|
||||
}
|
||||
|
||||
// Delete a network object group
|
||||
func (nog NetworkObjectGroups) Delete(ctx context.Context, req DeleteRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/network_object_group/delete"
|
||||
|
||||
res, err := nog.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
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
package netobjgroups
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// DetachExtNetPortsRequest struct to detach an external network port from a network object group
|
||||
type DetachExtNetPortsRequest struct {
|
||||
// ID of a network object group
|
||||
// Required: true
|
||||
ObjectGroupID string `url:"object_group_id" json:"object_group_id" validate:"required"`
|
||||
|
||||
// ID of an access group
|
||||
// Required: true
|
||||
AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
|
||||
|
||||
// ID of an external network port to detach from a network object group
|
||||
// Required: true
|
||||
ExternalNetworkPortID string `url:"external_network_port_id" json:"external_network_port_id" validate:"required"`
|
||||
}
|
||||
|
||||
// DetachExtNetlPorts detaches external network ports from a network object group
|
||||
func (nog NetworkObjectGroups) DetachExtNetPorts(ctx context.Context, req DetachExtNetPortsRequest) (*RecordVersion, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/network_object_group/detach_external_network_ports"
|
||||
|
||||
res, err := nog.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := RecordVersion{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
package netobjgroups
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// DetachLogicalPortsRequest struct to detach an logical port from a network object group
|
||||
type DetachLogicalPortsRequest struct {
|
||||
// ID of a network object group
|
||||
// Required: true
|
||||
ObjectGroupID string `url:"object_group_id" json:"object_group_id" validate:"required"`
|
||||
|
||||
// ID of an access group
|
||||
// Required: true
|
||||
AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
|
||||
|
||||
// Version ID
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// ID of a logical port
|
||||
// Required: true
|
||||
LogicalPortID string `url:"logical_port_id" json:"logical_port_id" validate:"required"`
|
||||
|
||||
// Version of a logical port
|
||||
// Required: true
|
||||
LogicalPortVersion uint64 `url:"logical_port_version" json:"logical_port_version" validate:"required"`
|
||||
}
|
||||
|
||||
// DetachLogicalPorts detaches logical ports from a network object group
|
||||
func (nog NetworkObjectGroups) DetachLogicalPorts(ctx context.Context, req DetachLogicalPortsRequest) (*RecordVersion, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/network_object_group/detach_logical_ports"
|
||||
|
||||
res, err := nog.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := RecordVersion{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package netobjgroups
|
||||
|
||||
// FilterByID returns NetObjGroupList with specified ID.
|
||||
func (nog NetObjGroupList) FilterByID(id string) NetObjGroupList {
|
||||
predicate := func(netobj RecordNetObjGroup) bool {
|
||||
return netobj.ID == id
|
||||
}
|
||||
|
||||
return nog.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterByName returns NetObjGroupList with specified Name.
|
||||
func (nog NetObjGroupList) FilterByName(name string) NetObjGroupList {
|
||||
predicate := func(netobj RecordNetObjGroup) bool {
|
||||
return netobj.Name == name
|
||||
}
|
||||
|
||||
return nog.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterFunc allows filtering NetObjGroupList based on a user-specified predicate.
|
||||
func (nog NetObjGroupList) FilterFunc(predicate func(group RecordNetObjGroup) bool) NetObjGroupList {
|
||||
var result NetObjGroupList
|
||||
|
||||
for _, acc := range nog.Objects {
|
||||
if predicate(acc) {
|
||||
result.Objects = append(result.Objects, acc)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// FindOne returns first element.
|
||||
// If none was found, returns an empty struct.
|
||||
func (nog NetObjGroupList) FindOne() RecordNetObjGroup {
|
||||
if len(nog.Objects) == 0 {
|
||||
return RecordNetObjGroup{}
|
||||
}
|
||||
|
||||
return nog.Objects[0]
|
||||
}
|
||||
@ -0,0 +1,111 @@
|
||||
package netobjgroups
|
||||
|
||||
import "testing"
|
||||
|
||||
var testNetObjGroups = NetObjGroupList{
|
||||
Objects: []RecordNetObjGroup{
|
||||
{
|
||||
AccessGroupID: "d85d4a08-3216-4240-a8bd-191cd9cc3bf3",
|
||||
AccessGroupName: "Test1",
|
||||
CreatedAt: "2025-09-04T13:18:14.412118Z",
|
||||
Description: "test descr",
|
||||
ID: "0b16493b-0a38-4c90-80a0-c19f898f593d",
|
||||
Name: "Test1",
|
||||
UpdatedAt: "2025-10-28T07:28:15.450717Z",
|
||||
VersionID: 1761636495441,
|
||||
Counters: Counter{
|
||||
LogicalPortsCount: 1,
|
||||
SecurityPoliciesCount: 2,
|
||||
SecurityRulesCount: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
AccessGroupID: "d85d4a08-3216-4240-a8bd-191cd9cc3bf3",
|
||||
AccessGroupName: "Test2",
|
||||
CreatedAt: "2025-09-04T13:18:14.412118Z",
|
||||
Description: "another descr",
|
||||
ID: "0b16493b-0a38-4c90-80a0-c19f898f593e",
|
||||
Name: "Test2",
|
||||
UpdatedAt: "2025-10-28T07:28:15.450717Z",
|
||||
VersionID: 1761636495442,
|
||||
Counters: Counter{
|
||||
LogicalPortsCount: 1,
|
||||
SecurityPoliciesCount: 2,
|
||||
SecurityRulesCount: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
AccessGroupID: "d85d4a08-3216-4240-a8bd-191cd9cc3bf3",
|
||||
AccessGroupName: "Test3",
|
||||
CreatedAt: "2025-09-04T13:18:14.412118Z",
|
||||
Description: "another descr",
|
||||
ID: "0b16493b-0a38-4c90-80a0-c19f898f593f",
|
||||
Name: "Test3",
|
||||
UpdatedAt: "2025-10-28T07:28:15.450717Z",
|
||||
VersionID: 1761636495443,
|
||||
Counters: Counter{
|
||||
LogicalPortsCount: 1,
|
||||
SecurityPoliciesCount: 2,
|
||||
SecurityRulesCount: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestFilterByID(t *testing.T) {
|
||||
actual := testNetObjGroups.FilterByID("0b16493b-0a38-4c90-80a0-c19f898f593d").FindOne()
|
||||
|
||||
if actual.ID != "0b16493b-0a38-4c90-80a0-c19f898f593d" {
|
||||
t.Fatal("actual:", actual.ID, "> expected: 0b16493b-0a38-4c90-80a0-c19f898f593d")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByName(t *testing.T) {
|
||||
actual := testNetObjGroups.FilterByName("Test1").FindOne()
|
||||
|
||||
if actual.Name != "Test1" {
|
||||
t.Fatal("actual:", actual.Name, ">> expected: Test1")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterFunc(t *testing.T) {
|
||||
actual := testNetObjGroups.FilterFunc(func(rnog RecordNetObjGroup) bool {
|
||||
return rnog.Description == "test descr"
|
||||
})
|
||||
|
||||
if len(actual.Objects) != 1 || actual.Objects[0].ID != "0b16493b-0a38-4c90-80a0-c19f898f593d" {
|
||||
t.Fatal("Expected 1 policy with description 'Second policy', found:", len(actual.Objects))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindOneWithResults(t *testing.T) {
|
||||
result := testNetObjGroups.FilterByID("0b16493b-0a38-4c90-80a0-c19f898f593d").FindOne()
|
||||
if result.ID != "0b16493b-0a38-4c90-80a0-c19f898f593d" {
|
||||
t.Fatal("Expected 0b16493b-0a38-4c90-80a0-c19f898f593d, got:", result.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindOneEmpty(t *testing.T) {
|
||||
emptyList := NetObjGroupList{}
|
||||
result := emptyList.FindOne()
|
||||
|
||||
if result.ID != "" || result.Name != "" {
|
||||
t.Fatal("Expected empty NetObjGroup, got:", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByIDNotFound(t *testing.T) {
|
||||
actual := testNetObjGroups.FilterByID("0b16493b-0a38-4c90-80a0-c19f898f593n")
|
||||
|
||||
if len(actual.Objects) != 0 {
|
||||
t.Fatal("Expected 0 policies, found:", len(actual.Objects))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByDisplayNameNotFound(t *testing.T) {
|
||||
actual := testNetObjGroups.FilterByName("Nonexistent Policy")
|
||||
|
||||
if len(actual.Objects) != 0 {
|
||||
t.Fatal("Expected 0 policies, found:", len(actual.Objects))
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package netobjgroups
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// GetRequest struct to get info about a network object group
|
||||
type GetRequest struct {
|
||||
// ID of a network object group
|
||||
// Required: true
|
||||
NetObjGroupID string `url:"object_group_id" json:"object_group_id" validate:"required"`
|
||||
}
|
||||
|
||||
// Get gets network object group details as a NetworkObjectGroups struct
|
||||
func (nog NetworkObjectGroups) Get(ctx context.Context, req GetRequest) (*RecordNetObjGroup, error) {
|
||||
res, err := nog.GetRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := RecordNetObjGroup{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
|
||||
}
|
||||
|
||||
// GetRaw gets network object group details as an array of bytes
|
||||
func (nog NetworkObjectGroups) GetRaw(ctx context.Context, req GetRequest) ([]byte, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/network_object_group/get"
|
||||
|
||||
res, err := nog.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
return res, err
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
package netobjgroups
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// ListRequest struct to get a list of network object groups
|
||||
type ListRequest struct {
|
||||
// Filter by name
|
||||
// Required: false
|
||||
Name string `url:"name,omitempty" json:"name,omitempty"`
|
||||
|
||||
// Filter by access group ID
|
||||
// Required: false
|
||||
AccessGroupID string `url:"access_group_id,omitempty" json:"access_group_id,omitempty"`
|
||||
|
||||
// Updated at lower bound (greater than or equal to)
|
||||
// Required: false
|
||||
UpdatedFrom string `url:"updated_from,omitempty" json:"updated_from,omitempty"`
|
||||
|
||||
// Updated at upper bound (less than)
|
||||
// Required: false
|
||||
UpdatedTo string `url:"updated_to,omitempty" json:"updated_to,omitempty"`
|
||||
|
||||
// Created at lower bound (greater than or equal to)
|
||||
// Required: false
|
||||
CreatedFrom string `url:"created_from,omitempty" json:"created_from,omitempty"`
|
||||
|
||||
// Created at upper bound (less than)
|
||||
// Required: false
|
||||
CreatedTo string `url:"created_to,omitempty" json:"created_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 (name, created_at, updated_at)
|
||||
// Required: false
|
||||
SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty"`
|
||||
|
||||
// Sort order (asc/desc)
|
||||
// Required: false
|
||||
SortOrder string `url:"sort_order,omitempty" json:"sort_order,omitempty"`
|
||||
}
|
||||
|
||||
// List of address pools
|
||||
func (nog NetworkObjectGroups) List(ctx context.Context, req ListRequest) (*NetObjGroupList, error) {
|
||||
res, err := nog.ListRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
objects := []RecordNetObjGroup{}
|
||||
|
||||
err = json.Unmarshal(res, &objects)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := NetObjGroupList{Objects: objects}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// ListRaw gets a list of all address pools as an array of bytes
|
||||
func (nog NetworkObjectGroups) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/network_object_group/list"
|
||||
|
||||
res, err := nog.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
return res, err
|
||||
}
|
||||
@ -0,0 +1,702 @@
|
||||
package netobjgroups
|
||||
|
||||
// Information about a version
|
||||
type RecordVersion struct {
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
// List of network object groups
|
||||
type NetObjGroupList struct {
|
||||
Objects []RecordNetObjGroup
|
||||
}
|
||||
|
||||
// Main info about a network object group
|
||||
type RecordNetObjGroup struct {
|
||||
// Access group ID
|
||||
AccessGroupID string `json:"access_group_id"`
|
||||
|
||||
// Access group name
|
||||
AccessGroupName string `json:"access_group_name"`
|
||||
|
||||
// Counters
|
||||
Counters Counter `json:"counters"`
|
||||
|
||||
// Created at
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// Updated at
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
|
||||
// Description
|
||||
Description string `json:"description"`
|
||||
|
||||
// External network ports attached to a network object group
|
||||
ExternalNetworkPorts ExternalNetworkPorts `json:"external_network_ports"`
|
||||
|
||||
// ID of a network object group
|
||||
ID string `json:"id"`
|
||||
|
||||
// Logical ports attached to a network object group
|
||||
LogicalPorts LogicalPorts `json:"logical_ports"`
|
||||
|
||||
// Name of a network object group
|
||||
Name string `json:"name"`
|
||||
|
||||
// Security policies of a network object group
|
||||
SecurityPolicies SecurityPolicies `json:"security_policies"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
// Info about counters
|
||||
type Counter struct {
|
||||
// Amount of logical ports
|
||||
LogicalPortsCount uint64 `json:"logical_ports_count"`
|
||||
|
||||
// Amount of security policies
|
||||
SecurityPoliciesCount uint64 `json:"security_policies_count"`
|
||||
|
||||
// Amount of security rules
|
||||
SecurityRulesCount uint64 `json:"security_rules_count"`
|
||||
}
|
||||
|
||||
// List of counters
|
||||
type Counters []Counter
|
||||
|
||||
// Info about an external network port
|
||||
type ExternalNetworkPort struct {
|
||||
// Bridge network name
|
||||
BridgeNetworkName string `json:"bridge_network_name"`
|
||||
|
||||
// Default gateaway for IPv4
|
||||
DefaultGateawayIPv4 string `json:"default_gateaway_ipv4"`
|
||||
|
||||
// Default gateaway for IPv6
|
||||
DefaultGateawayIPv6 string `json:"default_gateaway_ipv6"`
|
||||
|
||||
// Description
|
||||
Description string `json:"description"`
|
||||
|
||||
// Details of external network ports
|
||||
ExternalNetworkPorts ExternalNetworkPortsField `json:"external_network_ports"`
|
||||
|
||||
// Hypervisors
|
||||
Hypervisors []string `json:"hypervisors"`
|
||||
|
||||
// ID of an external network port
|
||||
ID string `json:"id"`
|
||||
|
||||
// Status
|
||||
Status Status `json:"status"`
|
||||
|
||||
// Version ID
|
||||
VersionID string `json:"version_id"`
|
||||
|
||||
// Subnet for V4
|
||||
SubnetV4 string `json:"subnet_v4"`
|
||||
|
||||
// Subnet for V6
|
||||
SubnetV6 string `json:"subnet_v6"`
|
||||
|
||||
// Created at
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// Updated at
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
|
||||
// VLAN Tag
|
||||
VLANTag string `json:"vlan_tag"`
|
||||
}
|
||||
|
||||
// List of external network ports
|
||||
type ExternalNetworkPorts []ExternalNetworkPort
|
||||
|
||||
// Info about a logical port
|
||||
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"`
|
||||
|
||||
// Is address detected
|
||||
AddressDetection bool `json:"address_detection"`
|
||||
|
||||
// Description
|
||||
Description string `json:"description"`
|
||||
|
||||
// Created at
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// Display name
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Is a logical port enabled
|
||||
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
|
||||
Status Status `json:"status"`
|
||||
|
||||
// Bindings
|
||||
Bindings Bindings `json:"bindings"`
|
||||
|
||||
// Unique identifier
|
||||
UniqueIdentifier string `json:"unique_identifier"`
|
||||
|
||||
// Updated at
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
// List a logical ports
|
||||
type LogicalPorts []LogicalPort
|
||||
|
||||
// Info about a security policy
|
||||
type SecurityPolicy struct {
|
||||
// Access group ID
|
||||
AccessGroupID string `json:"access_group_id"`
|
||||
|
||||
// Access group name
|
||||
AccessGroupName string `json:"access_group_name"`
|
||||
|
||||
// Applied to net object group ID
|
||||
AppliedToNetObjectGroupID string `json:"applied_to_net_object_group_id"`
|
||||
|
||||
// Created at
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// Description
|
||||
Description string `json:"description"`
|
||||
|
||||
// Display name
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Is a security policy enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// End priority
|
||||
EndPriority uint64 `json:"end_priority"`
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Security rules
|
||||
SecurityRules SecurityRules `json:"security_rules"`
|
||||
|
||||
// Start priority
|
||||
StartPriority uint64 `json:"start_priority"`
|
||||
|
||||
// Status
|
||||
Status Status `json:"status"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
|
||||
// Updated at
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
// List of security policies
|
||||
type SecurityPolicies []SecurityPolicy
|
||||
|
||||
// Details of external network ports field
|
||||
type ExternalNetworkPortField struct {
|
||||
// Access group ID
|
||||
AccessGroupID string `json:"access_group_id"`
|
||||
|
||||
// Access group name
|
||||
AccessGroupName string `json:"access_group_name"`
|
||||
|
||||
Comment string `json:"comment"`
|
||||
|
||||
// Display name
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Is a security policy enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// IP v4
|
||||
IPv4 string `json:"ipv4"`
|
||||
|
||||
// IP v6
|
||||
IPv6 string `json:"ipv6"`
|
||||
|
||||
// Config for IP v6
|
||||
IPv6Config IPv6Config `json:"ipv6_config"`
|
||||
|
||||
// MAC
|
||||
MAC string `json:"mac"`
|
||||
|
||||
// Info about a router gateaway port
|
||||
RouterGateawayPort RouterGateawayPort `json:"router_gateaway_port"`
|
||||
|
||||
// Info about a floating IP
|
||||
FloatingIP FloatingIP `json:"floating_ip"`
|
||||
}
|
||||
|
||||
// List of external network ports fields
|
||||
type ExternalNetworkPortsField []ExternalNetworkPortField
|
||||
|
||||
// Info about a status
|
||||
type Status struct {
|
||||
// Common
|
||||
Common string `json:"common"`
|
||||
|
||||
// Info about hypervisors
|
||||
Hypervisors HypervisorsInfo `json:"hypervisors"`
|
||||
}
|
||||
|
||||
// Config for IP v6
|
||||
type IPv6Config struct {
|
||||
// Address mode
|
||||
AddressMode string `json:"address_mode"`
|
||||
|
||||
// Is periodic RA enabled
|
||||
EnablePeriodicRA bool `json:"enable_periodic_ra"`
|
||||
|
||||
// Interval RA
|
||||
IntervalRA uint64 `json:"interval_ra"`
|
||||
|
||||
// Router preference
|
||||
RouterPreference string `json:"router_preference"`
|
||||
}
|
||||
|
||||
// Info about a router gateaway port
|
||||
type RouterGateawayPort struct {
|
||||
// Created at
|
||||
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"`
|
||||
|
||||
// Is SNAT enabled
|
||||
SNATEnabled bool `json:"snat_enabled"`
|
||||
|
||||
// Updated at
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
// Info about a floating IP
|
||||
type FloatingIP struct {
|
||||
// Access group ID
|
||||
AccessGroupID string `json:"access_group_id"`
|
||||
|
||||
// Access group name
|
||||
AccessGroupName string `json:"access_group_name"`
|
||||
|
||||
// Created at
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// External network port in floating IP
|
||||
ExternalNetworkPort ExternalNetworkPortFieldInFloatingIP `json:"external_network_port"`
|
||||
|
||||
// Logical port
|
||||
LogicalPort LogicalPort `json:"logical_port"`
|
||||
|
||||
// Router
|
||||
Router Router `json:"router"`
|
||||
|
||||
// Updated at
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
// TODO later
|
||||
type ExternalNetworkPortFieldInFloatingIP struct{}
|
||||
|
||||
// Info about a router
|
||||
type Router struct {
|
||||
// Access group ID
|
||||
AccessGroupID string `json:"access_group_id"`
|
||||
|
||||
// Access group name
|
||||
AccessGroupName string `json:"access_group_name"`
|
||||
|
||||
// Created at
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// Description
|
||||
Description string `json:"description"`
|
||||
|
||||
// Display name
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Is a security policy enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// Gateaway ports
|
||||
GateawayPorts GateawayPorts `json:"gateaway_ports"`
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Policies
|
||||
Policies Policies `json:"policies"`
|
||||
|
||||
// Port
|
||||
Port Ports `json:"ports"`
|
||||
|
||||
// Status
|
||||
Status Status `json:"status"`
|
||||
|
||||
// Updated at
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
// Info about bindings
|
||||
type Bindings struct {
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Segment display name
|
||||
SegmentDisplayName string `json:"segment_display_name"`
|
||||
|
||||
// Segment ID
|
||||
SegmentID string `json:"segment_id"`
|
||||
|
||||
// Is a port secured
|
||||
PortSecurity bool `json:"port_security"`
|
||||
|
||||
// Is an address detected
|
||||
AddressDetection bool `json:"address_detection"`
|
||||
|
||||
// Is excluded from firewall
|
||||
IsExcludedFromFirewall bool `json:"is_excluded_from_firewall"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
|
||||
// Created at
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// Updated at
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
|
||||
// Logical port addresses
|
||||
LogicalPortAddresses LogicalPortAddresses `json:"logical_port_addresses"`
|
||||
}
|
||||
|
||||
// Info about a gateaway port
|
||||
type GateawayPort struct {
|
||||
// Created at
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// Description
|
||||
Description string `json:"description"`
|
||||
|
||||
// Max external L4 port
|
||||
ExternalL4PortMax uint64 `json:"external_l4_port_max"`
|
||||
|
||||
// Min external L4 port
|
||||
ExternalL4PortMin uint64 `json:"external_l4_port_min"`
|
||||
|
||||
// External network port in floating IP
|
||||
ExternalNetworkPortFieldInFloatingIP ExternalNetworkPortFieldInFloatingIP `json:"external_network_port"` // to check
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Is SNAT enabled
|
||||
SNATEnabled bool `json:"snat_enabled"`
|
||||
|
||||
// Status
|
||||
Status Status `json:"status"`
|
||||
|
||||
// Updated at
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
// List of gateaway ports
|
||||
type GateawayPorts []GateawayPort
|
||||
|
||||
// Info about a policy
|
||||
type Policy struct {
|
||||
// Action
|
||||
Action string `json:"action"`
|
||||
|
||||
// Created at
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// Display name
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Is a security policy enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Match
|
||||
Match string `json:"match"`
|
||||
|
||||
// List of next IP v4 addresses
|
||||
NextIPv4Address []string `json:"next_ipv4_address"`
|
||||
|
||||
// List of next IP v6 addresses
|
||||
NextIPv6Address []string `json:"next_ipv6_address"`
|
||||
|
||||
// Priority
|
||||
Priority int `json:"priority"`
|
||||
|
||||
// Updated at
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
// List of policies
|
||||
type Policies []Policy
|
||||
|
||||
// Info about a port
|
||||
type Port struct {
|
||||
// Created at
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// Description
|
||||
Description string `json:"description"`
|
||||
|
||||
// Is a security policy enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// IPv4 address
|
||||
IPv4Address string `json:"ipv4_address"`
|
||||
|
||||
// IPv6 address
|
||||
IPv6Address string `json:"ipv6_address"`
|
||||
|
||||
// Config for IPv6
|
||||
IPv6Config IPv6Config `json:"ipv6_config"`
|
||||
|
||||
// MAC
|
||||
MAC string `json:"mac"`
|
||||
|
||||
// Segment
|
||||
Segment Segment `json:"segment"`
|
||||
|
||||
// Segment ID
|
||||
SegmentID string `json:"segment_id"`
|
||||
|
||||
// Status
|
||||
Status Status `json:"status"`
|
||||
|
||||
// Updated at
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
|
||||
// VersionID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
// List of ports
|
||||
type Ports []Port
|
||||
|
||||
// Info about a segment
|
||||
type Segment struct {
|
||||
// Access group ID
|
||||
AccessGroupID string `json:"access_group_id"`
|
||||
|
||||
// Access group name
|
||||
AccessGroupName string `json:"access_group_name"`
|
||||
|
||||
// Created at
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// Description
|
||||
Description string `json:"description"`
|
||||
|
||||
DHCPv4 DHCPv4 `json:"dhcp_v4"`
|
||||
DHCPv6 DHCPv6 `json:"dhcp_v6"`
|
||||
|
||||
// Display name
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// Is a security policy enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Info about logical ports
|
||||
LogicalPortsInfo LogicalPortsInfo `json:"logical_ports_info"`
|
||||
|
||||
// Info about routers
|
||||
RoutersInfo RoutersInfo `json:"routers_info"`
|
||||
|
||||
// Status
|
||||
Status Status `json:"status"`
|
||||
|
||||
// Subnet v4
|
||||
SubnetV4 string `json:"subnet_v4"`
|
||||
|
||||
// Subnet v6
|
||||
SubnetV6 string `json:"subnet_v6"`
|
||||
|
||||
// Updated at
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
|
||||
// Version ID
|
||||
VersionID uint64 `json:"version_id"`
|
||||
}
|
||||
|
||||
// Info about DHCP v4
|
||||
type DHCPv4 struct {
|
||||
// List of DNS
|
||||
DNS []string `json:"dns"`
|
||||
|
||||
// List of excluded address ranges
|
||||
ExcludedAddressRanges []string `json:"excluded_address_ranges"`
|
||||
|
||||
// Gateaway
|
||||
Gateaway string `json:"gateaway"`
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Lease time
|
||||
LeaseTime uint64 `json:"lease_time"`
|
||||
|
||||
// Server IP
|
||||
ServerIP string `json:"server_ip"`
|
||||
|
||||
// is there a server MAC
|
||||
ServerMAC bool `json:"server_mac"`
|
||||
|
||||
// Is a security policy enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
// Info about DHCP v6
|
||||
type DHCPv6 struct {
|
||||
// Address prefix
|
||||
AddressPrefix string `json:"address_prefix"`
|
||||
|
||||
// List of DNS
|
||||
DNS []string `json:"dns"`
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Lease time
|
||||
LeaseTime uint64 `json:"lease_time"`
|
||||
|
||||
// Server MAC
|
||||
ServerMAC string `json:"server_mac"`
|
||||
|
||||
// Is a security policy enabled
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
// Info about logical ports
|
||||
type LogicalPortsInfo struct {
|
||||
// Display name
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
// Info about routers
|
||||
type RoutersInfo struct {
|
||||
// Display name
|
||||
DisplayName string `json:"display_name"`
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
// Info about a hypervisor
|
||||
type HypervisorInfo 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
|
||||
SyncedAt string `json:"synced_at"`
|
||||
}
|
||||
|
||||
// List of hypervisors info
|
||||
type HypervisorsInfo []HypervisorInfo
|
||||
|
||||
type LogicalPortAddress struct {
|
||||
// IP
|
||||
IP string `json:"ip"`
|
||||
|
||||
// IP Type
|
||||
IPType string `json:"ip_type"`
|
||||
|
||||
// Is logical port address discovered
|
||||
IsDiscovered bool `json:"is_discovered"`
|
||||
|
||||
// Is logical port address primary
|
||||
IsPrimary bool `json:"is_primary"`
|
||||
|
||||
// MAC
|
||||
MAC string `json:"mac"`
|
||||
|
||||
// ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Logical port ID
|
||||
LogicalPortID string `json:"logical_port_id"`
|
||||
|
||||
// Assigned at
|
||||
AssignedAt string `json:"assigned_at"`
|
||||
}
|
||||
|
||||
// List of logical port addresses
|
||||
type LogicalPortAddresses []LogicalPortAddress
|
||||
|
||||
// TODO
|
||||
type SecurityRule struct{}
|
||||
|
||||
type SecurityRules []SecurityRule
|
||||
@ -0,0 +1,18 @@
|
||||
// API Actor API for managing SDN network object groups
|
||||
package netobjgroups
|
||||
|
||||
import (
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
|
||||
)
|
||||
|
||||
// Structure for creating request to network object groups
|
||||
type NetworkObjectGroups struct {
|
||||
client interfaces.Caller
|
||||
}
|
||||
|
||||
// Builder for external network object groups
|
||||
func New(client interfaces.Caller) *NetworkObjectGroups {
|
||||
return &NetworkObjectGroups{
|
||||
client,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
package netobjgroups
|
||||
|
||||
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 a network object group
|
||||
type UpdateRequest struct {
|
||||
// ID of the object group
|
||||
// Required: true
|
||||
ObjectGroupID string `url:"object_group_id" json:"object_group_id" validate:"required"`
|
||||
|
||||
// ID of the version
|
||||
// Required: true
|
||||
VersionID uint64 `url:"version_id" json:"version_id" validate:"required"`
|
||||
|
||||
// Access Group ID
|
||||
// Required: true
|
||||
AccessGroupID string `url:"access_group_id" json:"access_group_id" validate:"required"`
|
||||
|
||||
// Description of the network object group
|
||||
// Required: true
|
||||
Description string `url:"description" json:"description" validate:"required"`
|
||||
|
||||
// Name of the network object group
|
||||
// Required: true
|
||||
Name string `url:"name" json:"name" validate:"required"`
|
||||
}
|
||||
|
||||
// Update updates a network object group
|
||||
func (nog NetworkObjectGroups) Update(ctx context.Context, req UpdateRequest) (*RecordNetObjGroup, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/sdn/network_object_group/update"
|
||||
|
||||
res, err := nog.client.DecortApiCallCtype(ctx, http.MethodPut, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := RecordNetObjGroup{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package sdn
|
||||
|
||||
import (
|
||||
nog "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/netobjgroups"
|
||||
)
|
||||
|
||||
// Accessing the SDN method group
|
||||
func (sdn *SDN) NetworkObjectGroups() *nog.NetworkObjectGroups {
|
||||
return nog.New(sdn.client)
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package sdn
|
||||
|
||||
import (
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/routers"
|
||||
)
|
||||
|
||||
// Accessing the SDN method group
|
||||
func (sdn *SDN) Routers() *routers.Routers {
|
||||
return routers.New(sdn.client)
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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]
|
||||
}
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue