From 86268ff2da2ec5db34f6703b3f453d28794dae9a Mon Sep 17 00:00:00 2001 From: uzair Date: Fri, 29 Mar 2024 12:11:10 +0530 Subject: [PATCH 1/2] VLAN Support in Network --- fake_client.go | 36 ++++++++++++++++++++++ kubernetes.go | 14 ++++----- network.go | 61 ++++++++++++++++++++++++++------------ network_test.go | 79 +++++++++++++++++++++++++++++++++++++++++++++++++ pool.go | 3 +- 5 files changed, 165 insertions(+), 28 deletions(-) diff --git a/fake_client.go b/fake_client.go index e694b2c..079b4b9 100644 --- a/fake_client.go +++ b/fake_client.go @@ -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) @@ -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, // Assuming Name maps to Label in NetworkConfig + 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 diff --git a/kubernetes.go b/kubernetes.go index 960deac..1226ed5 100644 --- a/kubernetes.go +++ b/kubernetes.go @@ -149,13 +149,13 @@ type KubernetesClusterConfig struct { // KubernetesClusterPoolConfig is used to create a new cluster pool type KubernetesClusterPoolConfig struct { - Region string `json:"region,omitempty"` - ID string `json:"id,omitempty"` - Count int `json:"count,omitempty"` - Size string `json:"size,omitempty"` - Labels map[string]string `json:"labels,omitempty"` - Taints []corev1.Taint `json:"taints"` - PublicIPNodePool bool `json:"public_ip_node_pool,omitempty"` + Region string `json:"region,omitempty"` + ID string `json:"id,omitempty"` + Count int `json:"count,omitempty"` + Size string `json:"size,omitempty"` + //Labels map[string]string `json:"labels,omitempty"` + //Taints []corev1.Taint `json:"taints"` + PublicIPNodePool bool `json:"public_ip_node_pool,omitempty"` } // KubernetesPlanConfiguration is a value within a configuration for diff --git a/network.go b/network.go index 859cdfb..9e0d2ad 100644 --- a/network.go +++ b/network.go @@ -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 @@ -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 diff --git a/network_test.go b/network_test.go index bde5975..b45d750 100644 --- a/network_test.go +++ b/network_test.go @@ -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": `[{ diff --git a/pool.go b/pool.go index e36ed88..7b8da5e 100644 --- a/pool.go +++ b/pool.go @@ -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 From 3e49b88bb93b9b63fcd8e4da6f8aced6fe720246 Mon Sep 17 00:00:00 2001 From: uzair Date: Fri, 29 Mar 2024 12:14:50 +0530 Subject: [PATCH 2/2] rm cmnts --- fake_client.go | 2 +- kubernetes.go | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/fake_client.go b/fake_client.go index 079b4b9..29a9c1e 100644 --- a/fake_client.go +++ b/fake_client.go @@ -915,7 +915,7 @@ func (c *FakeClient) CreateNetwork(config NetworkConfig) (*NetworkResult, error) // Prepare the new Network object newNetwork := Network{ ID: networkID, - Name: config.Label, // Assuming Name maps to Label in NetworkConfig + Name: config.Label, Default: config.Default == "true", CIDR: config.CIDRv4, Label: config.Label, diff --git a/kubernetes.go b/kubernetes.go index 1226ed5..960deac 100644 --- a/kubernetes.go +++ b/kubernetes.go @@ -149,13 +149,13 @@ type KubernetesClusterConfig struct { // KubernetesClusterPoolConfig is used to create a new cluster pool type KubernetesClusterPoolConfig struct { - Region string `json:"region,omitempty"` - ID string `json:"id,omitempty"` - Count int `json:"count,omitempty"` - Size string `json:"size,omitempty"` - //Labels map[string]string `json:"labels,omitempty"` - //Taints []corev1.Taint `json:"taints"` - PublicIPNodePool bool `json:"public_ip_node_pool,omitempty"` + Region string `json:"region,omitempty"` + ID string `json:"id,omitempty"` + Count int `json:"count,omitempty"` + Size string `json:"size,omitempty"` + Labels map[string]string `json:"labels,omitempty"` + Taints []corev1.Taint `json:"taints"` + PublicIPNodePool bool `json:"public_ip_node_pool,omitempty"` } // KubernetesPlanConfiguration is a value within a configuration for