Skip to content
Snippets Groups Projects
Commit c8d5124a authored by Alex ubuntu vm's avatar Alex ubuntu vm
Browse files

switches: restructured the file that defines the topology

parent 7e4645bf
No related branches found
No related tags found
1 merge request!2repo: added new directory where utils scripts will be
{
"Nodes": [
{"name": "l2sm1", "nodeIP": "10.1.14.29"},{"name": "l2sm2", "nodeIP": "10.1.72.109"}
],
"Links": [
{"endpointA": "l2sm1", "endpointB": "l2sm2"}
]
}
[
{
"name": "<NODE_SWITCH_1>",
"nodeIP": "<IP_SWITCH_1>",
"neighborNodes": ["<NODE_SWITCH_2>"]
"name": "l2sm1",
"nodeIP": "10.1.14.34",
"neighborNodes": ["l2sm2"]
},
{
"name": "<NODE_SWITCH_2>",
"nodeIP": "<IP_SWITCH_2>",
"neighborNodes": ["<NODE_SWITCH_1>"]
"name": "l2sm2",
"nodeIP": "10.1.72.84",
"neighborNodes": ["l2sm1"]
}
]
{
"Nodes": [
{"name": "l2sm1", "nodeIP": "10.1.14.29"},{"name": "l2sm2", "nodeIP": "10.1.72.109"}
],
"Links": [
{"endpointA": "l2sm1", "endpointB": "l2sm2"}
]
}
......@@ -5,15 +5,24 @@ import (
"errors"
"flag"
"fmt"
"io/ioutil"
"os"
"ovs-switch/pkg/ovs"
)
type Node struct {
Name string `json:"name"`
NodeIP string `json:"nodeIP"`
NeighborNodes []Node `json:"neighborNodes"`
Name string `json:"name"`
NodeIP string `json:"nodeIP"`
NeighborNodes []string `json:"neighborNodes"`
}
type Link struct {
EndpointNodeA string `json:"endpointA"`
EndpointNodeB string `json:"endpointB"`
}
type Topology struct {
Nodes []Node `json:"Nodes"`
Links []Link `json:"Links"`
}
// Script that takes two required arguments:
......@@ -21,6 +30,8 @@ type Node struct {
// the second one is the path to the configuration file, in reference to the code.
func main() {
//configDir, _, fileType, err := takeArguments()
configDir, nodeName, fileType, err := takeArguments()
bridge := ovs.FromName("brtun")
......@@ -30,14 +41,30 @@ func main() {
return
}
nodes, err := readFile(configDir)
switch fileType {
case "topology":
err = createTopology(bridge, nodes, nodeName)
var topology Topology
err = readFile(configDir, &topology)
if err != nil {
fmt.Println("Error with the provided file. Error:", err)
return
}
fmt.Println(topology)
err = createTopology(bridge, topology, nodeName)
case "neighbors":
err = connectToNeighbors(bridge, nodes[0])
var node Node
err := readFile(configDir, &node)
if err != nil {
fmt.Println("Error with the provided file. Error:", err)
return
}
err = connectToNeighbors(bridge, node)
}
if err != nil {
......@@ -58,7 +85,7 @@ func takeArguments() (string, string, string, error) {
switch {
case *nodeName == "":
return "", "", "", errors.New("node name is not defined")
case *fileType != "topology" || *fileType != "neighbors":
case *fileType != "topology" && *fileType != "neighbors":
return "", "", "", errors.New("file type not supported. Available types: 'topology' and 'neighbors'")
case configDir == "":
return "", "", "", errors.New("config directory is not defined")
......@@ -67,47 +94,97 @@ func takeArguments() (string, string, string, error) {
return configDir, *nodeName, *fileType, nil
}
func createTopology(bridge ovs.Bridge, nodes []Node, nodeName string) error {
/**
Example:
{
"Nodes": [
{
"name": "l2sm1",
"nodeIP": "10.1.14.53"
},
{
"name": "l2sm2",
"nodeIP": "10.1.14.90"
}
],
"Links": [
{
"endpointA": "l2sm1",
"endpointB": "l2sm2"
}
]
}
// Search for the corresponding node in the configuration, according to the first passed parameter.
// Once the node is found, create a bridge for every neighbour node defined.
// The bridge is created with the nodeIp and neighborNodeIP and VNI. The VNI is generated in the l2sm-controller thats why its set to 'flow'.
for _, node := range nodes {
if node.Name == nodeName {
//nodeIP := strings.TrimSpace(node.NodeIP)
connectToNeighbors(bridge, node)
*/
func createTopology(bridge ovs.Bridge, topology Topology, nodeName string) error {
nodeMap := make(map[string]string)
for _, node := range topology.Nodes {
nodeMap[node.Name] = node.NodeIP
}
localIp := nodeMap[nodeName]
for vxlanNumber, link := range topology.Links {
vxlanId := fmt.Sprintf("vxlan%d", vxlanNumber)
var remoteIp string
switch nodeName {
case link.EndpointNodeA:
remoteIp = nodeMap[link.EndpointNodeB]
case link.EndpointNodeB:
remoteIp = nodeMap[link.EndpointNodeA]
default:
break
}
err := bridge.CreateVxlan(ovs.Vxlan{VxlanId: vxlanId, LocalIp: localIp, RemoteIp: remoteIp, UdpPort: "7000"})
if err != nil {
return fmt.Errorf("could not create vxlan between node %s and node %s", link.EndpointNodeA, link.EndpointNodeB)
} else {
fmt.Printf("Created vxlan between node %s and node %s.\n", link.EndpointNodeA, link.EndpointNodeB)
}
}
return nil
}
func readFile(configDir string) ([]Node, error) {
func readFile(configDir string, dataStruct interface{}) error {
/// Read file and save in memory the JSON info
data, err := ioutil.ReadFile(configDir)
data, err := os.ReadFile(configDir)
if err != nil {
fmt.Println("No input file was found.", err)
return nil, err
return err
}
var nodes []Node
err = json.Unmarshal(data, &nodes)
err = json.Unmarshal(data, &dataStruct)
if err != nil {
return nil, err
return err
}
return nodes, nil
return nil
}
/**
Example:
{
"Name": "l2sm1",
"nodeIP": "10.1.14.53",
"neighborNodes":["10.4.2.3","10.4.2.5"]
}
*/
func connectToNeighbors(bridge ovs.Bridge, node Node) error {
for vxlanNumber, neighbor := range node.NeighborNodes {
for vxlanNumber, neighborIp := range node.NeighborNodes {
vxlanId := fmt.Sprintf("vxlan%d", vxlanNumber)
err := bridge.CreateVxlan(ovs.Vxlan{VxlanId: vxlanId, LocalIp: node.NodeIP, RemoteIp: neighbor.NodeIP, UdpPort: "7000"})
err := bridge.CreateVxlan(ovs.Vxlan{VxlanId: vxlanId, LocalIp: node.NodeIP, RemoteIp: neighborIp, UdpPort: "7000"})
if err != nil {
return fmt.Errorf("could not create vxlan between node %s and node %s", node.Name, neighbor)
return fmt.Errorf("could not create vxlan with neighbor %s", neighborIp)
} else {
fmt.Printf("Created vxlan between node %s and node %s.\n", node.Name, neighbor)
fmt.Printf("Created vxlan with neighbor %s", neighborIp)
}
}
return nil
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment