diff --git a/operator/daemonset/l2-ps-amd64.yaml b/operator/daemonset/l2-ps-amd64.yaml index ba5d2c1ea68b01c2e1da04ef4d0690e97d96481d..75f94797bfee051fd3b23efeadbfe17c7bc52580 100644 --- a/operator/daemonset/l2-ps-amd64.yaml +++ b/operator/daemonset/l2-ps-amd64.yaml @@ -1,18 +1,18 @@ apiVersion: apps/v1 kind: DaemonSet metadata: - name: l2-ps + name: l2sm-switch #namespace: kube-system labels: - l2sm-component: l2-ps + l2sm-component: l2sm-switch spec: selector: matchLabels: - l2sm-component: l2-ps + l2sm-component: l2sm-switch template: metadata: labels: - l2sm-component: l2-ps + l2sm-component: l2sm-switch annotations: k8s.v1.cni.cncf.io/networks: vhost1@vhost1, vhost2@vhost2, vhost3@vhost3, vhost4@vhost4, vhost5@vhost5, vhost6@vhost6, vhost7@vhost7, vhost8@vhost8, vhost9@vhost9, vhost10@vhost10 spec: @@ -23,7 +23,7 @@ spec: operator: Exists effect: NoSchedule containers: - - name: l2-ps + - name: l2sm-switch image: alexdecb/l2sm-ovs:test command: ["sleep","infinity"] env: diff --git a/operator/deploy/controller/deployController.yaml b/operator/deploy/controller/deployController.yaml index b9408b20f1c21604af9d506719751c146534f8c2..596091ce275630a3e348aec43544bc3d459e7c7c 100644 --- a/operator/deploy/controller/deployController.yaml +++ b/operator/deploy/controller/deployController.yaml @@ -1,7 +1,7 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: l2sm-controller-deployment + name: l2sm-controller spec: replicas: 1 selector: diff --git a/operator/deploy/deployOperator.yaml b/operator/deploy/deployOperator.yaml index 5169979f7624d5581c34a5d1177d4b3405e741b6..7afe40d099ae3235cdc846f902d4e0b0145fc7e2 100644 --- a/operator/deploy/deployOperator.yaml +++ b/operator/deploy/deployOperator.yaml @@ -1,7 +1,7 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: l2sm-operator-deployment + name: l2sm-operator spec: replicas: 1 strategy: @@ -16,8 +16,12 @@ spec: spec: serviceAccountName: l2sm-operator containers: - - image: lewisfelix24/l2sm-operator:latest + - image: alexdecb/l2sm-operator:latest name: l2sm-opt-pod + env: + - name: CONTROLLER_IP + value: l2sm-controller-service + #command: ["sleep","infinity"] - image: mysql/mysql-server:5.7 name: mysql env: diff --git a/operator/src/controller/idco/Dockerfile b/operator/src/controller/Dockerfile similarity index 80% rename from operator/src/controller/idco/Dockerfile rename to operator/src/controller/Dockerfile index ab610527de746cf5b102f9be78fe6d106ddfacc9..c75bec1e61c1478f225ffee8efcfab2b30667d4c 100644 --- a/operator/src/controller/idco/Dockerfile +++ b/operator/src/controller/Dockerfile @@ -1,4 +1,4 @@ -FROM onosproject/onos:2.7.0 +FROM onosproject/onos:2.7-latest COPY . ./ diff --git a/operator/src/controller/api/go.mod b/operator/src/controller/api/go.mod deleted file mode 100644 index 06106f30e1ee8ce2eb92f3b5b848c9d40c0cd12f..0000000000000000000000000000000000000000 --- a/operator/src/controller/api/go.mod +++ /dev/null @@ -1,13 +0,0 @@ -module l2sm_controller_api - -go 1.18 - -require ( - github.com/hashicorp/errwrap v1.0.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/helloyi/go-sshclient v1.2.0 // indirect - github.com/kr/fs v0.1.0 // indirect - github.com/pkg/sftp v1.13.5 // indirect - golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d // indirect - golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 // indirect -) diff --git a/operator/src/controller/api/go.sum b/operator/src/controller/api/go.sum deleted file mode 100644 index 2313e5b3f693e36ed96a7c81b1edc582d539f066..0000000000000000000000000000000000000000 --- a/operator/src/controller/api/go.sum +++ /dev/null @@ -1,44 +0,0 @@ -github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/helloyi/go-sshclient v1.2.0 h1:36YOcHjtb3QhtZPTFthb0kvDlfQqVHErwfObVq6omck= -github.com/helloyi/go-sshclient v1.2.0/go.mod h1:L2+lPFL4TshqEu5fl5FHqtojNDzUtPFIjHXgaZYMX0Q= -github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/pkg/sftp v1.13.5 h1:a3RLUqkyjYRtBTZJZ1VRrKbN3zhuPLlUc3sphVz81go= -github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d h1:3qF+Z8Hkrw9sOhrFHti9TlB1Hkac1x+DNRkv0XQiFjo= -golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 h1:UiNENfZ8gDvpiWw7IpOMQ27spWmThO1RwwdQVbJahJM= -golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/operator/src/controller/api/main.go b/operator/src/controller/api/main.go deleted file mode 100644 index ce76639a7904e3087b35bcea0b1c2f05ebce3faf..0000000000000000000000000000000000000000 --- a/operator/src/controller/api/main.go +++ /dev/null @@ -1,119 +0,0 @@ -package main - -import ( - "bytes" - "encoding/json" - "fmt" - "log" - "net/http" - - "golang.org/x/crypto/ssh" -) - -type Network struct { - Name string `json:"name"` - Ports []string `json:"ports"` -} - -func main() { - - //var hostKey ssh.PublicKey - // An SSH client is represented with a ClientConn. - // - // To authenticate with the remote server you must pass at least one - // implementation of AuthMethod via the Auth field in ClientConfig, - // and provide a HostKeyCallback. - config := &ssh.ClientConfig{ - User: "root", - Auth: []ssh.AuthMethod{ - ssh.Password("root123"), - }, - HostKeyCallback: ssh.InsecureIgnoreHostKey(), - } - client, err := ssh.Dial("tcp", "172.17.0.2:22", config) - if err != nil { - log.Fatal("Failed to dial: ", err) - } - defer client.Close() - - // Each ClientConn can support multiple interactive sessions, - // represented by a Session. - session, err := client.NewSession() - if err != nil { - log.Fatal("Failed to create session: ", err) - } - defer session.Close() - - // Once a Session is created, you can execute a single command on - // the remote side using the Run method. - var b bytes.Buffer - session.Stdout = &b - if err := session.Run("/usr/bin/whoami"); err != nil { - log.Fatal("Failed to run: " + err.Error()) - } - fmt.Println(b.String()) - - http.HandleFunc("/network", func(w http.ResponseWriter, r *http.Request) { - switch r.Method { - case "GET": - getNetwork(w, r) - case "POST": - createNetwork(w, r) - case "PUT": - updateNetwork(w, r) - default: - http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) - } - }) - - fmt.Println("Server is running on port 8080...") - http.ListenAndServe(":8080", nil) - -} - -func getNetwork(w http.ResponseWriter, r *http.Request) { - //var network Network - queryValues := r.URL.Query() - name := queryValues.Get("name") - //network = l2sm-get-network Name - - //json.NewEncoder(w).Encode(&network) - fmt.Printf("GET %s", name) -} - -func createNetwork(w http.ResponseWriter, r *http.Request) { - var network Network - if err := json.NewDecoder(r.Body).Decode(&network); err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - //l2sm-create-network network.Name - w.WriteHeader(http.StatusCreated) - fmt.Printf("POST") - -} - -func updateNetwork(w http.ResponseWriter, r *http.Request) { - var network Network - - // l2sm-add-port network.Port - // if err := json.NewDecoder(r.Body).Decode(&network); err != nil { - // http.Error(w, err.Error(), http.StatusBadRequest) - // return - // } - // params := r.URL.Query() - // name := params.Get("name") - // port := params.Get("port") - - // for i, net := range networks { - // if net.Name == name { - // networks[i].Ports = append(networks[i].Ports, port) - // w.WriteHeader(http.StatusOK) - // return - // } - // } - - // http.Error(w, "Network not found", http.StatusNotFound) - fmt.Printf("UPDATE") - -} diff --git a/operator/src/controller/idco/idco-app-1.0.oar b/operator/src/controller/idco/idco-app-1.0.oar deleted file mode 100644 index 8c9ed2f5692f6e4e07fe91fd8c80289e0c8439cb..0000000000000000000000000000000000000000 Binary files a/operator/src/controller/idco/idco-app-1.0.oar and /dev/null differ diff --git a/operator/src/controller/l2sm-controller-app-1.0.oar b/operator/src/controller/l2sm-controller-app-1.0.oar new file mode 100644 index 0000000000000000000000000000000000000000..bf5c8c35a6e611a10927b02791cbbf7a0c6cf935 Binary files /dev/null and b/operator/src/controller/l2sm-controller-app-1.0.oar differ diff --git a/operator/src/controller/idco/setup_controller.sh b/operator/src/controller/setup_controller.sh similarity index 88% rename from operator/src/controller/idco/setup_controller.sh rename to operator/src/controller/setup_controller.sh index d39ed1199c3b3feab28226e6d9d23752b6499d7d..52c25de53937b3c943707ba01adc617439eb742f 100644 --- a/operator/src/controller/idco/setup_controller.sh +++ b/operator/src/controller/setup_controller.sh @@ -22,12 +22,12 @@ done # Start the configuration -./bin/onos-app localhost install idco-app-1.0.oar -./bin/onos-app localhost activate org.idco.app + ./bin/onos-app localhost activate org.onosproject.drivers ./bin/onos-app localhost activate org.onosproject.lldpprovider ./bin/onos-app localhost activate org.onosproject.openflow-base ./bin/onos-app localhost activate org.onosproject.optical-model +./bin/onos-app localhost install! l2sm-controller-app-1.0.oar diff --git a/operator/src/operator/Dockerfile b/operator/src/operator/Dockerfile index bde2d1d115347a0e2d1e84baaa3d5ddb37cbc373..20b735d9f6c5eadee9a69e9142d6b10b0284ca07 100644 --- a/operator/src/operator/Dockerfile +++ b/operator/src/operator/Dockerfile @@ -1,4 +1,4 @@ FROM python:3.7 -RUN pip install kopf kubernetes PyMySQL cryptography +RUN pip install kopf kubernetes PyMySQL cryptography requests COPY l2sm-operator.py /l2sm-operator.py CMD kopf run --standalone --all-namespaces /l2sm-operator.py diff --git a/operator/src/operator/l2sm-operator.py b/operator/src/operator/l2sm-operator.py index 00fe838ba92ee8a3ca91f998bae84f6834b6ed9c..d0970fbd18782116bd69f3d2177bf68d8a8d3440 100644 --- a/operator/src/operator/l2sm-operator.py +++ b/operator/src/operator/l2sm-operator.py @@ -11,42 +11,138 @@ from kubernetes import client, config import pymysql import random import time +import requests +import re +import sys +from requests.auth import HTTPBasicAuth + +databaseIP = "127.0.0.1" +baseControllerUrl = 'http://' + os.environ['CONTROLLER_IP'] + ':8181' + '/onos/v1' +def beginSessionController(baseControllerUrl,username,password): + + # Create a session with basic authentication + auth = HTTPBasicAuth(username, password) + + session = requests.Session() + session.auth = auth + + #Check if connection is possible + response = session.get(baseControllerUrl + '/l2sm/networks/status') + if response.status_code == 200: + # Successful request + print("Initialized session between operator and controller.") + return session + else: + print("Could not initialize session with l2sm-controller") + sys.exit() + return None + + + +session = beginSessionController(baseControllerUrl,"karaf","karaf") + +def getSwitchId(cur, node): + switchQuery = "SELECT * FROM switches WHERE node = '%s'" % (node) + cur.execute(switchQuery) + switchRecord = cur.fetchone() -ip = "127.0.0.1" + if switchRecord is not None: + switchId = switchRecord[0] + if switchId is not None: + return switchId # If openflowId is already set, return it + + # If openflowId is not set, make a request to get the information from the API + response = session.get(baseControllerUrl + '/devices') + devices = response.json().get('devices', []) + + for device in devices: + if 'id' in device and 'annotations' in device and 'managementAddress' in device['annotations']: + if device['annotations']['managementAddress'] == switchRecord[1]: + openflowId = device['id'] + switchId = openflowId + + # Save the openflowId in the database + updateQuery = "UPDATE switches SET openflowId = '%s' WHERE node = '%s'" % (switchId, node) + cur.execute(updateQuery) + + return switchId # Return the openflowId + return None # Return None if no matching device is found + #POPULATE DATABASE ENTRIES WHEN A NEW L2SM POD IS CREATED (A NEW NODE APPEARS) -@kopf.on.create('pods.v1', labels={'l2sm-component': 'l2-ps'}) +@kopf.on.create('pods.v1', labels={'l2sm-component': 'l2sm-switch'}) def build_db(body, logger, annotations, **kwargs): - db = pymysql.connect(host=ip,user="l2sm",password="l2sm;",db="L2SM") + db = pymysql.connect(host=databaseIP,user="l2sm",password="l2sm;",db="L2SM") cur = db.cursor() + #CREATE TABLES IF THEY DO NOT EXIST table1 = "CREATE TABLE IF NOT EXISTS networks (network TEXT NOT NULL, id TEXT NOT NULL);" table2 = "CREATE TABLE IF NOT EXISTS interfaces (interface TEXT NOT NULL, node TEXT NOT NULL, network TEXT, pod TEXT);" + table3 = "CREATE TABLE IF NOT EXISTS switches (openflowId TEXT, ip TEXT, node TEXT NOT NULL);" cur.execute(table1) cur.execute(table2) + cur.execute(table3) db.commit() - values = [] + #MODIFY THE END VALUE TO ADD MORE INTERFACES + values = [] for i in range(1,11): values.append(['vpod'+str(i), body['spec']['nodeName'], '-1', '']) - sql = "INSERT INTO interfaces (interface, node, network, pod) VALUES (%s, %s, %s, %s)" - cur.executemany(sql, values) + sqlInterfaces = "INSERT INTO interfaces (interface, node, network, pod) VALUES (%s, %s, %s, %s)" + cur.executemany(sqlInterfaces, values) + db.commit() + + #ADD The switch identification to the database, without the of13 id yet, as it may not be connected yet. + sqlSwitch = "INSERT INTO switches (node) VALUES ('" + body['spec']['nodeName'] + "')" + cur.execute(sqlSwitch) db.commit() + db.close() logger.info(f"Node {body['spec']['nodeName']} has been registered in the operator") +@kopf.on.update('pods.v1', labels={'l2sm-component': 'l2sm-switch'}) +def update_db(body, logger, annotations, **kwargs): + if 'status' in body and 'podIP' in body['status']: + db = pymysql.connect(host=databaseIP,user="l2sm",password="l2sm;",db="L2SM") + cur = db.cursor() + updateQuery = "UPDATE switches SET ip = '%s' WHERE node = '%s'" % (body['status']['podIP'], body['spec']['nodeName']) + cur.execute(updateQuery) + db.commit() + db.close() + logger.info(f"Updated switch ip") + + #UPDATE DATABASE WHEN NETWORK IS CREATED, I.E: IS A MULTUS CRD WITH OUR DUMMY INTERFACE PRESENT IN ITS CONFIG #@kopf.on.create('NetworkAttachmentDefinition', field="spec.config['device']", value='l2sm-vNet') @kopf.on.create('NetworkAttachmentDefinition', when=lambda spec, **_: '"device": "l2sm-vNet"' in spec['config']) def create_vn(spec, name, namespace, logger, **kwargs): - db = pymysql.connect(host=ip,user="l2sm",password="l2sm;",db="L2SM") + + db = pymysql.connect(host=databaseIP,user="l2sm",password="l2sm;",db="L2SM") cur = db.cursor() id = secrets.token_hex(32) sql = "INSERT INTO networks (network, id) VALUES ('%s', '%s')" % (name.strip(), id.strip()) cur.execute(sql) db.commit() db.close() - logger.info(f"Network has been created") + + # Create the network in the controller, using a post request + data = { + "networkId": name.strip() + } + # json_payload = { + # "Content-Type": "application/json", + # "data": payload + # } + response = session.post(baseControllerUrl + '/l2sm/networks', json=data) + + # Check the response status + if response.status_code == 204: + logger.info(f"Network has been created") + #print("Response:", response.json()) + else: + # Handle errors + logger.info(f"Network could not be created, check controller status") + #ASSIGN POD TO NETWORK (TRIGGERS ONLY IF ANNOTATION IS PRESENT) @@ -83,7 +179,7 @@ def pod_vn(body, name, namespace, logger, annotations, **kwargs): ret = v1.read_namespaced_pod(name, namespace) node = body['spec']['nodeName'] - db = pymysql.connect(host=ip,user="l2sm",password="l2sm;",db="L2SM") + db = pymysql.connect(host=databaseIP,user="l2sm",password="l2sm;",db="L2SM") nsql = "SELECT * FROM interfaces WHERE node = '%s' AND network = '-1'" % (node.strip()) cur = db.cursor() cur.execute(nsql) @@ -116,20 +212,50 @@ def pod_vn(body, name, namespace, logger, annotations, **kwargs): # networkN = retrieve[0].strip() # break + switchId = getSwitchId(cur, node) + + if switchId is None: + logger.info(f"The l2sm switch is not connected to controller. Not connecting the pod") + return + vpodPattern = re.compile(r'\d+$') + portNumbers = [int(vpodPattern.search(interface).group()) for interface in interface_to_attach] + for m in range(len(network)): sql = "UPDATE interfaces SET network = '%s', pod = '%s' WHERE interface = '%s' AND node = '%s'" % (network_array[m], name, interface_to_attach[m], node) cur.execute(sql) + payload = { + "networkId": network_array[m], + "networkEndpoints": [switchId + '/' + str(portNumbers[m])] + } + + + + response = session.post(baseControllerUrl + '/l2sm/networks/port', json=payload) + + + db.commit() db.close() - #HERE GOES SDN, THIS IS WHERE THE FUN BEGINS + + + + + + # Check the response status + if response.status_code == 200: + # Successful request + print("Request successful!") + else: + # Handle errors + print(f"Error: {response.status_code}") logger.info(f"Pod {name} attached to network {network_array}") #UPDATE DATABASE WHEN POD IS DELETED @kopf.on.delete('pods.v1', annotations={'k8s.v1.cni.cncf.io/networks': kopf.PRESENT}) def dpod_vn(name, logger, **kwargs): - db = pymysql.connect(host=ip,user="l2sm",password="l2sm;",db="L2SM") + db = pymysql.connect(host=databaseIP,user="l2sm",password="l2sm;",db="L2SM") cur = db.cursor() sql = "UPDATE interfaces SET network = '-1', pod = '' WHERE pod = '%s'" % (name) cur.execute(sql) @@ -140,7 +266,7 @@ def dpod_vn(name, logger, **kwargs): #UPDATE DATABASE WHEN NETWORK IS DELETED @kopf.on.delete('NetworkAttachmentDefinition', when=lambda spec, **_: '"device": "l2sm-vNet"' in spec['config']) def delete_vn(spec, name, logger, **kwargs): - db = pymysql.connect(host=ip,user="l2sm",password="l2sm;",db="L2SM") + db = pymysql.connect(host=databaseIP,user="l2sm",password="l2sm;",db="L2SM") cur = db.cursor() sql = "DELETE FROM networks WHERE network = '%s'" % (name) cur.execute(sql) @@ -149,9 +275,9 @@ def delete_vn(spec, name, logger, **kwargs): logger.info(f"Network has been deleted") #DELETE DATABASE ENTRIES WHEN A NEW L2SM POD IS DELETED (A NEW NODE GETS OUT OF THE CLUSTER) -@kopf.on.delete('pods.v1', labels={'l2sm-component': 'l2-ps'}) +@kopf.on.delete('pods.v1', labels={'l2sm-component': 'l2sm-switch'}) def remove_node(body, logger, annotations, **kwargs): - db = pymysql.connect(host=ip,user="l2sm",password="l2sm;",db="L2SM") + db = pymysql.connect(host=databaseIP,user="l2sm",password="l2sm;",db="L2SM") cur = db.cursor() sql = "DELETE FROM interfaces WHERE node = '%s'" % (body['spec']['nodeName']) cur.execute(sql) diff --git a/operator/src/switch/sampleFile.json b/operator/src/switch/sampleFile.json index 5eff2da0487904b76516db3051b13fa75593f5d9..a586b87bda29d5876c2148b6e1a895d1e797f6d9 100644 --- a/operator/src/switch/sampleFile.json +++ b/operator/src/switch/sampleFile.json @@ -1,12 +1,12 @@ [ { "name": "l2sm1", - "nodeIP": "10.1.14.45", + "nodeIP": "10.1.14.50", "neighborNodes": ["l2sm2"] }, { "name": "l2sm2", - "nodeIP": "10.1.72.79", + "nodeIP": "10.1.72.69", "neighborNodes": ["l2sm1"] } ] \ No newline at end of file