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

database: updated schema

Updated l2sm database schema and operator to go along with it. Now there are more constraints in the database and errors are handled accordingly, so the application is more robust against errors
parent 16f90fd5
No related branches found
No related tags found
1 merge request!2repo: added new directory where utils scripts will be
{
"version": "0.2.0",
"configurations": [
{
"name": "Kopf Run: l2sm-operator",
"type": "node-terminal",
"request": "launch",
"command": "kopf run ${workspaceFolder}/src/operator/l2sm-operator.py",
"env": {
"CONTROLLER_IP": "10.152.183.3",
"DATABASE_IP": "10.152.183.132",
"MYSQL_USER": "l2sm",
"MYSQL_PASSWORD": "l2sm",
"MYSQL_DATABASE": "l2sm"
}
}
]
}
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-schema
data:
init.sql: |
CREATE DATABASE IF NOT EXISTS l2sm;
USE l2sm;
CREATE TABLE networks (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
type ENUM('vlink', 'vnet', 'ext-vnet') NOT NULL,
UNIQUE KEY unique_network_name (name, type)
);
CREATE TABLE switches (
id INT PRIMARY KEY AUTO_INCREMENT,
node_name VARCHAR(255) NOT NULL,
openflowId TEXT,
ip VARCHAR(15)
);
CREATE TABLE neds (
id INT PRIMARY KEY AUTO_INCREMENT,
node_name VARCHAR(255) NOT NULL,
provider VARCHAR(255) NOT NULL,
openflowId TEXT,
ip VARCHAR(15)
);
CREATE TABLE interfaces (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255),
pod VARCHAR(255),
switch_id INT,
ned_id INT,
network_id INT,
FOREIGN KEY (switch_id) REFERENCES switches(id),
FOREIGN KEY (ned_id) REFERENCES neds(id),
FOREIGN KEY (network_id) REFERENCES networks(id)
);
-- Define the one-to-many relationship between switches and interfaces
ALTER TABLE interfaces
ADD CONSTRAINT fk_switch_interface
FOREIGN KEY (switch_id)
REFERENCES switches(id);
-- Define the one-to-many relationship between neds and interfaces
ALTER TABLE interfaces
ADD CONSTRAINT fk_ned_interface
FOREIGN KEY (ned_id)
REFERENCES neds(id);
-- Define the many-to-one relationship between networks and interfaces
ALTER TABLE interfaces
ADD CONSTRAINT fk_network_interface
FOREIGN KEY (network_id)
REFERENCES networks(id);
apiVersion: v1
kind: Pod
metadata:
name: mysql-development-pod
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
envFrom:
- secretRef:
name: mysql-secret
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
- name: initdb-volume
mountPath: /docker-entrypoint-initdb.d
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
- name: initdb-volume
configMap:
name: mysql-schema
items:
- key: init.sql
path: init.sql
nodeName: l2sm1
---
apiVersion: v1
kind: Service
metadata:
name: mysql-development-service
spec:
type: NodePort
ports:
- port: 3306
targetPort: 3306
nodePort: 30001
protocol: TCP
selector:
app: mysql
---
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: Opaque
data:
MYSQL_ROOT_PASSWORD: cGFzc3dvcmQ= # Base64 encoded "password"
MYSQL_USER: bDJzbQ== # Base64 encoded "l2sm"
MYSQL_PASSWORD: bDJzbQ== # Base64 encoded "l2sm"
MYSQL_DATABASE: bDJzbQ==
......@@ -16,9 +16,17 @@ 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):
database_ip = os.environ['DATABASE_IP']
database_username = os.environ['MYSQL_USER']
database_password = os.environ['MYSQL_PASSWORD']
database_name = os.environ['MYSQL_DATABASE']
base_controller_url = 'http://' + os.environ['CONTROLLER_IP'] + ':8181' + '/onos/v1'
print(base_controller_url)
print(database_ip)
def begin_session_controller(base_controller_url,username,password):
# Create a session with basic authentication
auth = HTTPBasicAuth(username, password)
......@@ -27,7 +35,7 @@ def beginSessionController(baseControllerUrl,username,password):
session.auth = auth
#Check if connection is possible
response = session.get(baseControllerUrl + '/l2sm/networks/status')
response = session.get(base_controller_url + '/l2sm/networks/status')
if response.status_code == 200:
# Successful request
print("Initialized session between operator and controller.")
......@@ -35,264 +43,354 @@ def beginSessionController(baseControllerUrl,username,password):
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()
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
session = begin_session_controller(base_controller_url,"karaf","karaf")
def get_openflow_id(node_name):
connection = pymysql.connect(host=database_ip,
user=database_username,
password=database_password,
database=database_name,
cursorclass=pymysql.cursors.DictCursor)
try:
with connection.cursor() as cursor:
switch_query = "SELECT id, openflowId, ip FROM switches WHERE node_name = %s"
cursor.execute(switch_query, (node_name,))
switch_record = cursor.fetchone()
print(switch_record)
if switch_record is not None:
switchId = switch_record['openflowId']
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(base_controller_url + '/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'] == switch_record['ip']:
openflowId = device['id']
switchId = openflowId
# Save the openflowId in the database
updateQuery = "UPDATE switches SET openflowId = %s WHERE id = %s"
cursor.execute(updateQuery, (openflowId, switch_record['id']))
connection.commit()
return switchId # Return the openflowId
connection.commit()
finally:
connection.close()
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': 'l2sm-switch'})
def build_db(body, logger, annotations, **kwargs):
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()
#MODIFY THE END VALUE TO ADD MORE INTERFACES
values = []
for i in range(1,11):
values.append(['veth'+str(i), body['spec']['nodeName'], '-1', ''])
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")
connection = pymysql.connect(host=database_ip,
user=database_username,
password=database_password,
database=database_name,
cursorclass=pymysql.cursors.DictCursor)
if 'spec' in body and 'nodeName' in body['spec']:
try:
with connection.cursor() as cursor:
# Step 1: Check if the switch already exists
select_switch_sql = "SELECT id FROM switches WHERE node_name = %s;"
cursor.execute(select_switch_sql, body['spec']['nodeName'])
result = cursor.fetchone()
if result:
# Switch exists, so update it (if needed)
switch_id = result['id']
# Example update (modify as needed)
# update_switch_sql = "UPDATE switches SET openflowId = %s, IP = %s WHERE id = %s;"
# cursor.execute(update_switch_sql, (newOpenflowId, newIP, switch_id))
else:
# Step 2: Insert a switch since it doesn't exist
insert_switch_sql = "INSERT INTO switches (node_name, openflowId, IP) VALUES (%s, NULL, NULL);"
cursor.execute(insert_switch_sql, body['spec']['nodeName'])
switch_id = cursor.lastrowid
# Step 3: Insert interfaces
for i in range(1, 11):
interface_name = f"veth{i}"
# Consider adding a check here to see if the interface already exists for the switch
insert_interface_sql = "INSERT INTO interfaces (name, switch_id) VALUES (%s, %s);"
cursor.execute(insert_interface_sql, (interface_name, switch_id))
# Commit the changes
connection.commit()
finally:
connection.close()
logger.info(f"Node {body['spec']['nodeName']} has been registered in the operator")
else:
raise kopf.TemporaryError("The Pod is not yet ready", delay=5)
@kopf.on.field('pods.v1', labels={'l2sm-component': 'l2sm-switch'}, field='status.podIP')
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', OpenFlowId = NULL WHERE node = '%s'" % (body['status']['podIP'], body['spec']['nodeName'])
cur.execute(updateQuery)
db.commit()
db.close()
connection = pymysql.connect(host=database_ip,
user=database_username,
password=database_password,
database=database_name,
cursorclass=pymysql.cursors.DictCursor)
try:
with connection.cursor() as cursor:
updateQuery = "UPDATE switches SET ip = '%s', OpenFlowId = NULL WHERE node_name = '%s'" % (body['status']['podIP'], body['spec']['nodeName'])
cursor.execute(updateQuery)
connection.commit()
finally:
connection.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
#UPDATE DATABASE WHEN NETWORK IS CREATED, I.E: IS A MULTUS CRD WITH OUR L2SM 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'])
@kopf.on.create('NetworkAttachmentDefinition', when=lambda spec, **_: '"type": "l2sm"' in spec['config'])
def create_vn(spec, name, namespace, logger, **kwargs):
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()
# 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")
# Database connection setup
connection = pymysql.connect(host=database_ip,
user=database_username,
password=database_password,
database=database_name,
cursorclass=pymysql.cursors.DictCursor)
try:
# Start database transaction
with connection.cursor() as cursor:
sql = "INSERT INTO networks (name, type) VALUES (%s, %s) ON DUPLICATE KEY UPDATE name = VALUES(name), type = VALUES(type)"
cursor.execute(sql, (name.strip(), "vnet"))
# Prepare data for the REST API call
data = {"networkId": name.strip()}
response = session.post(base_controller_url + '/l2sm/networks', json=data)
# Check the response status
if response.status_code == 204:
# Commit database changes only if the network is successfully created in the controller
connection.commit()
logger.info(f"Network '{name}' has been successfully created in both the database and the L2SM controller.")
else:
# Roll back the database transaction if the network creation in the controller fails
connection.rollback()
logger.error(f"Failed to create network '{name}' in the L2SM controller. Database transaction rolled back.")
except Exception as e:
# Roll back the database transaction in case of any error
connection.rollback()
logger.error(f"An error occurred: {e}. Rolled back the database transaction.")
finally:
# Ensure the database connection is closed
connection.close()
#ASSIGN POD TO NETWORK (TRIGGERS ONLY IF ANNOTATION IS PRESENT)
@kopf.on.create('pods.v1', annotations={'k8s.v1.cni.cncf.io/networks': kopf.PRESENT})
def pod_vn(body, name, namespace, logger, annotations, **kwargs):
#GET MULTUS INTERFACES IN THE DESCRIPTOR
#IN QUARANTINE: SLOWER THAN MULTUS!!!!!
time.sleep(random.uniform(0,0.8)) #Make sure the database is not consulted at the same time to avoid overlaping
multusInt = annotations.get('k8s.v1.cni.cncf.io/networks').split(",")
#VERIFY IF NETWORK IS PRESENT IN THE CLUSTER
api = client.CustomObjectsApi()
items = api.list_namespaced_custom_object('k8s.cni.cncf.io', 'v1', namespace, 'network-attachment-definitions').get('items')
resources = []
# NETWORK POSITION IN ANNOTATION
network = []
#FIND OUR NETWORKS IN MULTUS
for i in items:
if '"device": "l2sm-vNet"' in i['spec']['config']:
resources.append(i['metadata']['name'])
for k in range(len(multusInt)):
multusInt[k] = multusInt[k].strip()
if multusInt[k] in resources:
network.append(k)
#IF THERE ARE NO NETWORKS, LET MULTUS HANDLE THIS
if not network:
return
#CHECK IF NODE HAS FREE VIRTUAL INTERFACES LEFT
v1 = client.CoreV1Api()
ret = v1.read_namespaced_pod(name, namespace)
node = body['spec']['nodeName']
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)
data = cur.fetchall()
if not data or len(data)<len(network):
db.close()
raise kopf.PermanentError("l2sm could not deploy the pod: Node " + node.strip() + "has no free interfaces left")
#IF THERE IS ALREADY A MULTUS ANNOTATION, APPEND IT TO THE END.
interface_to_attach = []
network_array = []
j = 0
for interface in data[0:len(network)]:
network_array.append(multusInt[network[j]])
multusInt[network[j]] = interface[0].strip()
interface_to_attach.append(interface[0].strip())
j = j + 1
ret.metadata.annotations['k8s.v1.cni.cncf.io/networks'] = ', '.join(multusInt)
#GET NETWORK ID'S
#for j in items:
# if network in j['metadata']['name']:
# idsql = "SELECT id FROM networks WHERE network = '%s'" % (network.strip())
# cur.execute(idsql)
# retrieve = cur.fetchone()
# networkN = retrieve[0].strip()
# break
switchId = getSwitchId(cur, node) # TODO: diferenciar caso en el que es un veth el conectado y el de que es una red de vdd.
if switchId is None:
logger.info(f"The l2sm switch is not connected to controller. Not connecting the pod")
return
vethPattern = re.compile(r'\d+$')
portNumbers = [int(vethPattern.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])]
}
"""Assign Pod to a network if a specific annotation is present."""
response = session.post(baseControllerUrl + '/l2sm/networks/port', json=payload)
#PATCH NETWORK WITH ANNOTATION
v1.patch_namespaced_pod(name, namespace, ret)
db.commit()
db.close()
# Avoid database overlap by introducing a random sleep time
time.sleep(random.uniform(0, 0.8))
multus_networks = extract_multus_networks(annotations)
if not multus_networks:
logger.info("No Multus networks specified. Exiting.")
return
existing_networks = get_existing_networks(namespace)
target_networks = filter_target_networks(multus_networks, existing_networks)
if not target_networks:
logger.info("No target networks found. Letting Multus handle the network assignment.")
return
if 'spec' in body and 'nodeName' in body['spec']:
node_name = body['spec']['nodeName']
free_interfaces = get_free_interfaces(node_name)
if len(free_interfaces) < len(target_networks):
raise kopf.PermanentError(f"Node {node_name} has no free interfaces left")
openflow_id = get_openflow_id(node_name)
update_network_assignments(name, namespace, node_name, free_interfaces, target_networks, logger, openflow_id)
else:
raise kopf.TemporaryError("The Pod is not yet ready", delay=1)
# 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}")
def extract_multus_networks(annotations):
"""Extract and return Multus networks from annotations."""
return [network.strip() for network in annotations.get('k8s.v1.cni.cncf.io/networks').split(",")]
def get_existing_networks(namespace):
"""Return existing networks in the namespace."""
api = client.CustomObjectsApi()
networks = api.list_namespaced_custom_object('k8s.cni.cncf.io', 'v1', namespace, 'network-attachment-definitions').get('items')
return [network['metadata']['name'] for network in networks if '"type": "l2sm"' in network['spec']['config']]
def filter_target_networks(multus_networks, existing_networks):
"""Filter and return networks that are both requested and exist."""
return [network for network in multus_networks if network in existing_networks]
def get_free_interfaces(node_name):
"""Query the database for free interfaces on a node."""
connection = pymysql.connect(host=database_ip,
user=database_username,
password=database_password,
database=database_name,
cursorclass=pymysql.cursors.DictCursor)
try:
with connection.cursor() as cursor:
sql = """
SELECT i.id, i.name
FROM interfaces i
JOIN switches s ON i.switch_id = s.id
WHERE i.network_id IS NULL AND s.node_name = %s;
"""
cursor.execute(sql, (node_name.strip(),))
free_interfaces = cursor.fetchall()
finally:
connection.close()
return free_interfaces
def update_pod_annotation(pod_name, namespace, interfaces):
"""Update the Pod's annotation with assigned interfaces."""
v1 = client.CoreV1Api()
pod = v1.read_namespaced_pod(pod_name, namespace)
pod_annotations = pod.metadata.annotations or {}
pod_annotations['k8s.v1.cni.cncf.io/networks'] = ', '.join(interfaces)
v1.patch_namespaced_pod(pod_name, namespace, {'metadata': {'annotations': pod_annotations}})
def update_network_assignments(pod_name, namespace, node_name, free_interfaces, target_networks, logger, openflow_id):
"""Update the network assignments in the database and controller."""
connection = pymysql.connect(host=database_ip,
user=database_username,
password=database_password,
database=database_name,
cursorclass=pymysql.cursors.DictCursor)
try:
assigned_interfaces = []
with connection.cursor() as cursor:
for i, interface in enumerate(free_interfaces[:len(target_networks)]):
update_interface_assignment(cursor, interface['id'], target_networks[i], pod_name, node_name)
assigned_interfaces.append(interface['name'])
# Assuming function get_openflow_id and session.post logic are implemented elsewhere
if openflow_id:
port_number = extract_port_number(interface['name'])
post_network_assignment(openflow_id, port_number, target_networks[i])
update_pod_annotation(pod_name, namespace, assigned_interfaces)
connection.commit()
finally:
connection.close()
logger.info(f"Pod {pod_name} attached to networks {', '.join(target_networks)}")
# Assuming these functions are implemented as per original logic
def update_interface_assignment(cursor, interface_id, network_name, pod_name, node_name):
"""Update a single interface's network assignment in the database."""
# First, find the network_id from the network name
cursor.execute("SELECT id FROM networks WHERE name = %s", (network_name,))
network = cursor.fetchone()
if network is None:
raise ValueError(f"Network {network_name} does not exist")
network_id = network['id']
# Update the interface with the network_id and pod name
sql = """
UPDATE interfaces
SET pod = %s, network_id = %s
WHERE id = %s;
"""
cursor.execute(sql, (pod_name, network_id, interface_id))
def extract_port_number(interface_name):
"""Extract and return the port number from an interface name."""
return int(re.search(r'\d+$', interface_name).group())
def post_network_assignment(openflow_id, port_number, network_name):
"""Post network assignment to the controller."""
payload = {
"networkId": network_name,
"networkEndpoints": [f"{openflow_id}/{port_number}"]
}
response = session.post(f"{base_controller_url}/l2sm/networks/port", json=payload)
if response.status_code != 204:
raise Exception(f"Network assignment failed with status code: {response.status_code}")
#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=databaseIP,user="l2sm",password="l2sm;",db="L2SM")
cur = db.cursor()
sql = "UPDATE interfaces SET network = '-1', pod = '' WHERE pod = '%s'" % (name)
cur.execute(sql)
db.commit()
db.close()
logger.info(f"Pod {name} removed")
connection = pymysql.connect(host=database_ip,
user=database_username,
password=database_password,
database=database_name,
cursorclass=pymysql.cursors.DictCursor)
try:
with connection.cursor() as cursor:
sql = "UPDATE interfaces SET network_id = NULL, pod = NULL WHERE pod = '%s'" % (name)
cursor.execute(sql)
connection.commit()
finally:
connection.close()
logger.info(f"Pod {name} removed")
#UPDATE DATABASE WHEN NETWORK IS DELETED
@kopf.on.delete('NetworkAttachmentDefinition', when=lambda spec, **_: '"device": "l2sm-vNet"' in spec['config'])
@kopf.on.delete('NetworkAttachmentDefinition', when=lambda spec, **_: '"type": "l2sm"' in spec['config'])
def delete_vn(spec, name, logger, **kwargs):
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)
response = session.delete(baseControllerUrl + '/l2sm/networks/' + name)
connection = pymysql.connect(host=database_ip,
user=database_username,
password=database_password,
database=database_name,
cursorclass=pymysql.cursors.DictCursor)
try:
with connection.cursor() as cursor:
sql = "DELETE FROM networks WHERE name = '%s' AND type = 'vnet'" % (name)
cursor.execute(sql)
if response.status_code == 204:
# Successful request
logger.info(f"Network has been deleted")
db.commit()
else:
# Handle errors
logger.info(f"Error: {response.status_code}")
db.close()
response = session.delete(base_controller_url + '/l2sm/networks/' + name)
if response.status_code == 204:
# Successful request
logger.info(f"Network has been deleted")
connection.commit()
else:
# Handle errors
logger.info(f"Error: {response.status_code}")
finally:
connection.close()
logger.info(f"Pod {name} removed")
#DELETE DATABASE ENTRIES WHEN A NEW L2SM SWITCH IS DELETED (A NEW NODE GETS OUT OF THE CLUSTER)
@kopf.on.delete('pods.v1', labels={'l2sm-component': 'l2sm-switch'})
def remove_node(body, logger, annotations, **kwargs):
db = pymysql.connect(host=databaseIP,user="l2sm",password="l2sm;",db="L2SM")
cur = db.cursor()
sql = "DELETE FROM interfaces WHERE node = '%s'" % (body['spec']['nodeName'])
switchSql = "DELETE FROM switches WHERE node = '%s'" % (body['spec']['nodeName'])
cur.execute(sql)
cur.execute(switchSql)
db.commit()
db.close()
connection = pymysql.connect(host=database_ip,
user=database_username,
password=database_password,
database=database_name,
cursorclass=pymysql.cursors.DictCursor)
try:
with connection.cursor() as cursor:
sql = """
DELETE FROM interfaces
WHERE switch_id = (SELECT id FROM switches WHERE node_name = '%s');
"""
switchSql = "DELETE FROM switches WHERE node_name = '%s';"
cursor.execute(sql,body['spec']['nodeName'])
cursor.execute(switchSql,body['spec']['nodeName'])
connection.commit()
finally:
connection.close()
logger.info(f"Node {body['spec']['nodeName']} has been deleted from the cluster")
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