Source code for csle_common.controllers.ovs_controller

import logging
import subprocess
import time
import csle_common.constants.constants as constants
from csle_common.dao.emulation_config.containers_config import ContainersConfig
from csle_common.dao.emulation_config.emulation_env_config import EmulationEnvConfig
from csle_common.util.emulation_util import EmulationUtil


[docs]class OVSController: """ Class that contains functionality for interacting and managing OVS bridges in CSLE """
[docs] @staticmethod def create_virtual_switches_on_container(containers_config: ContainersConfig, physical_server_ip: str, logger: logging.Logger) -> None: """ Sets up OVS switches on containers :param containers_config: the containers configuration :param physical_server_ip: the ip of the physical server :param logger: the logger to use for logging :return: None """ for c in containers_config.containers: if c.physical_host_ip != physical_server_ip: continue for ovs_image in constants.CONTAINER_IMAGES.OVS_IMAGES: if ovs_image in c.name: logger.info(f"Creating OVS bridge and ports " f"on container: {c.get_full_name()}") container_name = c.get_full_name() bridge_name = constants.OVS.DEFAULT_BRIDGE_NAME cmd = f"{constants.COMMANDS.DOCKER_EXEC_COMMAND} {container_name} {constants.OVS.OVS_VSCTL} " \ f"{constants.OVS.ADD_BR} {bridge_name}" logger.info(f"Running cmd: {cmd} on container: {c.get_full_name()}") subprocess.Popen(cmd, stdout=subprocess.DEVNULL, shell=True) time.sleep(0.2) cmd = f"{constants.COMMANDS.DOCKER_EXEC_COMMAND} {container_name} ifconfig {bridge_name} up" logger.info(f"Running cmd: {cmd} on container: {c.get_full_name()}") subprocess.Popen(cmd, stdout=subprocess.DEVNULL, shell=True) time.sleep(0.2) idx = 0 for ip_net in c.ips_and_networks: ip, net = ip_net cmd = f"{constants.COMMANDS.DOCKER_EXEC_COMMAND} {container_name} {constants.OVS.OVS_VSCTL} " \ f"{constants.OVS.ADD_PORT} {bridge_name} {net.interface}" logger.info(f"Running cmd: {cmd} on container: {c.get_full_name()}") subprocess.Popen(cmd, stdout=subprocess.DEVNULL, shell=True) time.sleep(0.2) cmd = f"{constants.COMMANDS.DOCKER_EXEC_COMMAND} {container_name} ifconfig {net.interface} 0" logger.info(f"Running cmd: {cmd} on container: {c.get_full_name()}") subprocess.Popen(cmd, stdout=subprocess.DEVNULL, shell=True) time.sleep(0.2) if idx == 0: bridge_intf = bridge_name else: bridge_intf = f"{bridge_name}:{idx}" cmd = f"{constants.COMMANDS.DOCKER_EXEC_COMMAND} {container_name} " \ f"ifconfig {bridge_intf} {ip} netmask {net.bitmask}" logger.info(f"Running cmd: {cmd} on container: {c.get_full_name()}") subprocess.Popen(cmd, stdout=subprocess.DEVNULL, shell=True) time.sleep(0.2) idx += 1
[docs] @staticmethod def apply_ovs_config(emulation_env_config: EmulationEnvConfig, physical_server_ip: str, logger: logging.Logger) -> None: """ Aplies the OVS configuration on the OVS switches :param emulation_env_config: the emulation env config :param physical_server_ip: ip of the physical server :param logger: the logger to use for logging :return: None """ for ovs_sw in emulation_env_config.ovs_config.switch_configs: if ovs_sw.physical_host_ip != physical_server_ip: logger.info(f"Wrong host IP of switch: {ovs_sw.container_name}, {ovs_sw.physical_host_ip}, " f"{physical_server_ip}") continue logger.info(f"Configuring OVS bridge on container: {ovs_sw.container_name}, " f"physical host: {ovs_sw.physical_host_ip}, gw ip: {ovs_sw.docker_gw_bridge_ip}") EmulationUtil.connect_admin(emulation_env_config=emulation_env_config, ip=ovs_sw.docker_gw_bridge_ip) bridge_name = constants.OVS.DEFAULT_BRIDGE_NAME cmd = f"{constants.COMMANDS.SUDO} {constants.OVS.OVS_VSCTL} set bridge {bridge_name} " \ f"protocols={','.join(ovs_sw.openflow_protocols)}" logger.info(f"Running cmd:{cmd} on container: {ovs_sw.container_name}") EmulationUtil.execute_ssh_cmd(cmd=cmd, conn=emulation_env_config.connections[ovs_sw.docker_gw_bridge_ip]) logger.info(f"Command: {cmd} completed") cmd = f"{constants.COMMANDS.SUDO} {constants.OVS.OVS_VSCTL} set-controller {bridge_name} " \ f"{ovs_sw.controller_transport_protocol}:{ovs_sw.controller_ip}:{ovs_sw.controller_port}" logger.info(f"Running cmd:{cmd} on container: {ovs_sw.container_name}") EmulationUtil.execute_ssh_cmd(cmd=cmd, conn=emulation_env_config.connections[ovs_sw.docker_gw_bridge_ip]) logger.info(f"Command: {cmd} completed")