python 修改服務器網卡信息

import os
import re
import netifaces
import subprocess


class NetWorkConfig:

    def __init__(self):
        pass

    @staticmethod
    def check_network_isvalid(ip, netmask, gateway, dns):
        """
        判斷用戶輸入的網絡配置是否可用
        :param ip: str,IP地址
        :param netmask: str,子網掩碼
        :param gateway: str,網關
        :param dns: str,DNS
        :return: bool,True表示配置可用,False表示配置不可用
        """
        # 判斷IP地址是否合法
        if not re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", ip):
            return False

        # 判斷子網掩碼是否合法
        if not re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", netmask):
            return False

        # 判斷網關是否合法
        if not re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", gateway):
            return False

        # 判斷DNS是否合法
        if not re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", dns):
            return False

        # 判斷網絡是否可用
        cmd_ping = f"ping {gateway}"
        try:
            subprocess.check_call(cmd_ping, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        except subprocess.CalledProcessError:
            return False

        return True

    @staticmethod
    def get_network_config(physical=False):
        """
        獲取網卡配置信息
        :param physical: 是否僅獲取物理網卡
        :return: 返回服務器網卡配置
        """
        i_faces = netifaces.interfaces()
        configs = []
        for i in i_faces:
            if physical and not i.startswith("e"):
                continue
            addr_s = netifaces.ifaddresses(i)
            inet = addr_s.get(netifaces.AF_INET)
            if not inet:
                continue
            ip = inet[0].get("addr")
            netmask = inet[0].get("netmask")
            broadcast = inet[0].get("broadcast")
            gateway = netifaces.gateways().get("default", {}).get(netifaces.AF_INET, [])[0]
            dns = netifaces.gateways().get("default", {}).get(netifaces.AF_INET, [])[1]
            configs.append({
                "iface": i,
                "ip": ip,
                "netmask": netmask,
                "broadcast": broadcast,
                "gateway": gateway,
                "dns": dns,
            })
        return configs

    @staticmethod
    def _check_network_config(iface, ip_address, netmask, gateway, dns):
        """
        檢查IP地址和子網掩碼修改是否生效
        :param iface: 網卡
        :param ip_address: ip地址
        :param netmask: 子網掩碼
        :param gateway: 網關
        :param dns: DNS
        :return: 返回配置是否生效
        """
        # 檢查ip地址是否生效
        cmd = f"ifconfig {iface} | grep {ip_address}"
        output = subprocess.check_output(cmd, shell=True)
        if ip_address not in output.decode("utf-8"):
            return False

        # 檢查子網掩碼是否生效
        cmd = f"ifconfig {iface} | grep {netmask}"
        output = subprocess.check_output(cmd, shell=True)
        if netmask not in output.decode("utf-8"):
            return False

        # 檢查默認網關是否生效
        cmd = "route"
        output = subprocess.check_output(cmd, shell=True)
        pattern = rf"{gateway}\s.*\s{iface}"
        matches = re.findall(pattern, output.decode("utf-8"), re.MULTILINE)
        if not matches:
            return False

        # 檢查DNS是否生效
        with open("/etc/resolv.conf", "r") as f:
            content = f.read()
        if dns not in content:
            return False

        return True

    @staticmethod
    def _write_network_config_to_file(config, mode="w"):
        """
        配置信息寫入網卡
        """
        with open("/etc/network/interfaces", mode) as f:
            f.write(config)

    @staticmethod
    def _restart_network():
        """重啓網絡"""
        os.system("service networking restart")

    @staticmethod
    def _cp_config(cmd=None):
        """
        拷貝配置文件
        :param cmd: backup表示備份 rollback表示回滾
        """
        if cmd == "backup":
            os.system("cp /etc/network/interfaces /etc/network/interfaces.bak")
        if cmd == "rollback":
            os.system("cp /etc/network/interfaces.bak /etc/network/interfaces")

    def set_network_config(self, iface, ip_address, netmask, gateway, dns):
        """
        修改網絡配置
        :param iface: 網卡名稱
        :param ip_address: IP地址
        :param netmask: 子網掩碼
        :param gateway: 默認網關
        :param dns: DNS服務器
        :return: 是否修改成功
        """
        self._cp_config(cmd="backup")

        config = f"""
            auto {iface}
            iface {iface} inet static
            address {ip_address}
            netmask {netmask}
            gateway {gateway}
            dns-nameservers {dns}
        """

        self._write_network_config_to_file(config, "w")
        self._restart_network()
        if self._check_network_config(iface, ip_address, netmask, gateway, dns):
            return True
        else:
            self._cp_config(cmd="rollback")
            self._restart_network()
            return False

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章