Skip to content

Commit

Permalink
Merge pull request #190 from civo/vlan
Browse files Browse the repository at this point in the history
VLAN Support in Network
  • Loading branch information
uzaxirr authored Mar 29, 2024
2 parents 80038af + 3e49b88 commit cb1158c
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 21 deletions.
36 changes: 36 additions & 0 deletions fake_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ type Clienter interface {
// Networks
GetDefaultNetwork() (*Network, error)
NewNetwork(label string) (*NetworkResult, error)
CreateNetwork(configs NetworkConfig) (*NetworkResult, error)
ListNetworks() ([]Network, error)
FindNetwork(search string) (*Network, error)
RenameNetwork(label, id string) (*NetworkResult, error)
Expand Down Expand Up @@ -907,6 +908,41 @@ func (c *FakeClient) NewNetwork(label string) (*NetworkResult, error) {

}

// CreateNetwork creates a new network within the FakeClient, including VLAN configurations
func (c *FakeClient) CreateNetwork(config NetworkConfig) (*NetworkResult, error) {
networkID := c.generateID()

// Prepare the new Network object
newNetwork := Network{
ID: networkID,
Name: config.Label,
Default: config.Default == "true",
CIDR: config.CIDRv4,
Label: config.Label,
IPv4Enabled: config.IPv4Enabled != nil && *config.IPv4Enabled,
}

// Handle VLAN configuration if present
if config.VLanConfig != nil {
newNetwork.VLAN.VlanID = config.VLanConfig.VlanID
newNetwork.VLAN.HardwareAddr = config.VLanConfig.HardwareAddr
newNetwork.VLAN.CIDRv4 = config.VLanConfig.CIDRv4
newNetwork.VLAN.GatewayIPv4 = config.VLanConfig.GatewayIPv4
newNetwork.VLAN.AllocationPoolV4Start = config.VLanConfig.AllocationPoolV4Start
newNetwork.VLAN.AllocationPoolV4Start = config.VLanConfig.AllocationPoolV4End
}

// Append the newly created network to the networks slice
c.Networks = append(c.Networks, newNetwork)

// Return a success result
return &NetworkResult{
ID: networkID,
Label: config.Label,
Result: "success",
}, nil
}

// ListNetworks implemented in a fake way for automated tests
func (c *FakeClient) ListNetworks() ([]Network, error) {
return c.Networks, nil
Expand Down
61 changes: 42 additions & 19 deletions network.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@ import (

// Network represents a private network for instances to connect to
type Network struct {
ID string `json:"id"`
Name string `json:"name,omitempty"`
Default bool `json:"default"`
CIDR string `json:"cidr,omitempty"`
CIDRV6 string `json:"cidr_v6,omitempty"`
Label string `json:"label,omitempty"`
Status string `json:"status,omitempty"`
IPv4Enabled bool `json:"ipv4_enabled,omitempty"`
IPv6Enabled bool `json:"ipv6_enabled,omitempty"`
NameserversV4 []string `json:"nameservers_v4,omitempty"`
NameserversV6 []string `json:"nameservers_v6,omitempty"`
ID string `json:"id"`
Name string `json:"name,omitempty"`
Default bool `json:"default"`
CIDR string `json:"cidr,omitempty"`
CIDRV6 string `json:"cidr_v6,omitempty"`
Label string `json:"label,omitempty"`
Status string `json:"status,omitempty"`
IPv4Enabled bool `json:"ipv4_enabled,omitempty"`
IPv6Enabled bool `json:"ipv6_enabled,omitempty"`
NameserversV4 []string `json:"nameservers_v4,omitempty"`
NameserversV6 []string `json:"nameservers_v6,omitempty"`
VLAN VLANConnectConfig `json:"vlan,omitempty"`
}

// Subnet represents a subnet within a private network
Expand Down Expand Up @@ -52,16 +53,38 @@ type CreateRoute struct {
ResourceType string `json:"resource_type"`
}

// VLANConnectConfig represents the connection of a network to a VLAN
type VLANConnectConfig struct {
// VLanID is the ID of the VLAN to connect to
VlanID int `json:"vlan_id" validate:"required" schema:"vlan_id"`

// HardwareAddr is the base interface(default: eth0) at which we want to setup VLAN.
HardwareAddr string `json:"hardware_addr,omitempty" schema:"hardware_addr"`

// CIDRv4 is the CIDR of the VLAN to connect to
CIDRv4 string `json:"cidr_v4" validate:"required" schema:"cidr_v4"`

// GatewayIP is the gateway IP address
GatewayIPv4 string `json:"gateway_ipv4" validate:"required" schema:"gateway_ipv4"`

// AllocationPoolV4Start address of the allocation pool
AllocationPoolV4Start string `json:"allocation_pool_v4_start" validate:"required" schema:"allocation_pool_v4_start"`

// AllocationPoolV4End address of the allocation pool
AllocationPoolV4End string `json:"allocation_pool_v4_end" validate:"required" schema:"allocation_pool_v4_end"`
}

// NetworkConfig contains incoming request parameters for the network object
type NetworkConfig struct {
Label string `json:"label" validate:"required" schema:"label"`
Default string `json:"default" schema:"default"`
IPv4Enabled *bool `json:"ipv4_enabled"`
NameserversV4 []string `json:"nameservers_v4"`
CIDRv4 string `json:"cidr_v4"`
IPv6Enabled *bool `json:"ipv6_enabled"`
NameserversV6 []string `json:"nameservers_v6"`
Region string `json:"region"`
Label string `json:"label" validate:"required" schema:"label"`
Default string `json:"default" schema:"default"`
IPv4Enabled *bool `json:"ipv4_enabled"`
NameserversV4 []string `json:"nameservers_v4"`
CIDRv4 string `json:"cidr_v4"`
IPv6Enabled *bool `json:"ipv6_enabled"`
NameserversV6 []string `json:"nameservers_v6"`
Region string `json:"region"`
VLanConfig *VLANConnectConfig `json:"vlan_connect,omitempty"`
}

// NetworkResult represents the result from a network create/update call
Expand Down
79 changes: 79 additions & 0 deletions network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,85 @@ func TestNewNetwork(t *testing.T) {
}
}

func TestCreateNetwork(t *testing.T) {
client, server, _ := NewClientForTesting(map[string]string{
"/v2/networks": `{
"id": "41e4b4f5-5be0-4ac1-8c62-7e58f14f9155",
"result": "success",
"label": "private-net"
}`,
})
defer server.Close()

configs := NetworkConfig{
Label: "private-net",
}
got, err := client.CreateNetwork(configs)
if err != nil {
t.Errorf("Request returned an error: %s", err)
return
}

expected := &NetworkResult{
ID: "41e4b4f5-5be0-4ac1-8c62-7e58f14f9155",
Label: "private-net",
Result: "success",
}

if !reflect.DeepEqual(got, expected) {
t.Errorf("Expected %+v, got %+v", expected, got)
}
}

func TestCreateNetworkWithVLAN(t *testing.T) {
client, server, _ := NewClientForTesting(map[string]string{
"/v2/networks": `{
"id": "76cc107f-fbef-4e2b-b97f-f5d34f4075d3",
"label": "private-net",
"result": "success",
"vlan_connect": {
"vlan_id": 1,
"hardware_addr": "ETH0",
"cidr_v4": "10.0.0.0/24",
"gateway_ipv4": "10.0.0.4",
"allocation_pool_v4_start": "10.0.0.0",
"allocation_pool_v4_end": "10.0.0.11"
}
}`,
})
defer server.Close()

vlanConnectConfig := VLANConnectConfig{
VlanID: 1,
HardwareAddr: "ETH0",
CIDRv4: "10.0.0.0/24",
GatewayIPv4: "10.0.0.4",
AllocationPoolV4Start: "10.0.0.0",
AllocationPoolV4End: "10.0.0.11",
}

nc := NetworkConfig{
Label: "private-net",
VLanConfig: &vlanConnectConfig,
}

got, err := client.CreateNetwork(nc)
if err != nil {
t.Errorf("Request returned an error: %s", err)
return
}

expected := &NetworkResult{
ID: "76cc107f-fbef-4e2b-b97f-f5d34f4075d3",
Label: "private-net",
Result: "success",
}

if !reflect.DeepEqual(got, expected) {
t.Errorf("Expected %+v, got %+v", expected, got)
}
}

func TestListNetworks(t *testing.T) {
client, server, _ := NewClientForTesting(map[string]string{
"/v2/networks": `[{
Expand Down
3 changes: 1 addition & 2 deletions pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import (
"bytes"
"encoding/json"
"fmt"
"strings"

corev1 "k8s.io/api/core/v1"
"strings"
)

// KubernetesClusterPoolUpdateConfig is used to create a new cluster pool
Expand Down

0 comments on commit cb1158c

Please sign in to comment.