| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| from .utilities import bash |
| from .cloudException import CloudRuntimeException, CloudInternalException |
| import logging |
| import os |
| import re |
| import subprocess |
| |
| class networkConfig: |
| class devInfo: |
| def __init__(self, macAddr, ipAddr, netmask, gateway, type, name): |
| self.name = name |
| self.macAdrr = macAddr |
| self.ipAddr = ipAddr |
| self.netmask = netmask |
| self.gateway = gateway |
| self.type = type |
| self.name = name |
| #dhcp or static |
| self.method = None |
| |
| @staticmethod |
| def listNetworks(): |
| devs = os.listdir("/sys/class/net/") |
| devs = list(filter(networkConfig.isBridge, devs)) |
| return devs |
| @staticmethod |
| def getDefaultNetwork(): |
| cmd = bash("route -n|awk \'/^0.0.0.0/ {print $2,$8}\'") |
| if not cmd.isSuccess(): |
| logging.debug("Failed to get default route") |
| raise CloudRuntimeException("Failed to get default route") |
| |
| result = cmd.getStdout().split(" ") |
| gateway = result[0] |
| dev = result[1] |
| |
| pdi = networkConfig.getDevInfo(dev) |
| logging.debug("Found default network device:%s"%pdi.name) |
| pdi.gateway = gateway |
| return pdi |
| |
| @staticmethod |
| def createBridge(dev, brName): |
| if not networkConfig.isBridgeSupported(): |
| logging.debug("bridge is not supported") |
| return False |
| if networkConfig.isBridgeEnslavedWithDevices(brName): |
| logging.debug("bridge: %s has devices enslaved"%brName) |
| return False |
| |
| cmds = "" |
| if not networkConfig.isBridge(brName): |
| cmds = "ip link add name %s type bridge ;"%brName |
| |
| cmds += "ifconfig %s up;"%brName |
| cmds += "ip link set dev %s master %s"%(dev, brName) |
| return bash(cmds).isSuccess() |
| |
| @staticmethod |
| def isBridgeEnslavedWithDevices(brName): |
| if not networkConfig.isBridge(brName): |
| return False |
| |
| if not os.listdir("/sys/class/net/%s/brif"%brName): |
| return False |
| |
| return True |
| |
| @staticmethod |
| def isBridgeSupported(): |
| if os.path.exists("/proc/sys/net/bridge"): |
| return True |
| |
| return bash("modprobe -b bridge").isSuccess() |
| |
| @staticmethod |
| def isNetworkDev(devName): |
| return os.path.exists("/sys/class/net/%s" % devName) |
| |
| @staticmethod |
| def isBridgePort(devName): |
| return os.path.exists("/sys/class/net/%s/brport" % devName) |
| |
| @staticmethod |
| def isBridge(devName): |
| return os.path.exists("/sys/class/net/%s/bridge" % devName) |
| |
| @staticmethod |
| def isOvsBridge(devName): |
| cmd = bash("which ovs-vsctl") |
| if not cmd.isSuccess(): |
| return False |
| try: |
| return 0==subprocess.check_call(("ovs-vsctl", "br-exists", devName)) |
| except subprocess.CalledProcessError: |
| return False |
| |
| @staticmethod |
| def getBridge(devName): |
| bridgeName = None |
| if os.path.exists("/sys/class/net/%s/brport/bridge"%devName): |
| realPath = os.path.realpath("/sys/class/net/%s/brport/bridge"%devName) |
| bridgeName = realPath.split("/")[-1] |
| return bridgeName |
| |
| @staticmethod |
| def getEnslavedDev(br, brPort): |
| if not networkConfig.isBridgeEnslavedWithDevices(br): |
| return None |
| |
| for dev in os.listdir("/sys/class/net/%s/brif"%br): |
| br_port = int(open("/sys/class/net/%s/brif/%s/port_no"%(br,dev)).readline().strip("\n"), 16) |
| if br_port == brPort: |
| return dev |
| |
| return None |
| |
| @staticmethod |
| def getDevInfo(dev): |
| if not networkConfig.isNetworkDev(dev): |
| logging.debug("dev: " + dev + " is not a network device") |
| raise CloudInternalException("dev: " + dev + " is not a network device") |
| |
| netmask = None |
| ipAddr = None |
| macAddr = None |
| |
| cmd = bash("ifconfig " + dev) |
| if not cmd.isSuccess(): |
| logging.debug("Failed to get address from ifconfig") |
| raise CloudInternalException("Failed to get network info by ifconfig %s"%dev) |
| |
| for line in cmd.getLines(): |
| if line.find("HWaddr") != -1: |
| macAddr = line.split("HWaddr ")[1].strip(" ") |
| elif line.find("inet ") != -1: |
| m = re.search("addr:(.*)\ *Bcast:(.*)\ *Mask:(.*)", line) |
| if m is not None: |
| ipAddr = m.group(1).rstrip(" ") |
| netmask = m.group(3).rstrip(" ") |
| |
| if networkConfig.isBridgePort(dev): |
| type = "brport" |
| elif networkConfig.isBridge(dev) or networkConfig.isOvsBridge(dev): |
| type = "bridge" |
| else: |
| type = "dev" |
| |
| return networkConfig.devInfo(macAddr, ipAddr, netmask, None, type, dev) |
| |