使用IP地址模块进行异常处理

时间:2017-06-15 18:46:06

标签: python-3.x rest api ip-address

我不是贸易软件工程师(网络安全工程师),我正在学习更多的自动化技术和编码。我确信我在代码中遗漏了一些非常明显的东西,任何帮助都会受到赞赏。

我正在运行一个输入脚本,要求用户输入CIDR中的IP地址或IPv4 / v6格式的主机IP到输入框(Tkinter内)。我有两个独立的编码脚本来执行这些功能(CIDR和主机IP)。我正在尝试将代码组合在一起,因此只需要运行一个应用程序。

使用ipaddress模块​​时,如果输入的格式不正确(使用ip_address(对于主机地址)或ip_network(对于CIDR地址)),则会抛出Value错误。这就是我想要的,因为我正在处理这些例外。

问题是我需要将CIDR和IP主机添加到REST API调用的单独列表中(因为需要不同的调用格式)。当我的下面的代码处理时,如果文本框中的条目是CIDR格式,它将抛出Value错误(因为IP Host是第一个语句,这就是它抛出错误的原因)。

我已经能够同时处理ipaddress输入,并使用以下代码替换第二个elif语句(第一个只是空输入的故障保护):

if self.ip == str(ipaddress.ip_network(self.e1.get())) or self.ip == str(ipaddress.ip_address(self.e1.get())):

上述陈述的问题是我无法解密self.ip并将其附加到适当的列表(一个用于CIDR,一个用于IP主机)。

我的主要代码的主要问题,如前所述,如果输入是CIDR,它将抛出值错误,因为第二个elif块将ipaddress.ip_address作为第一个输入,并且一旦遇到错误它不会继续代码。

也许这是一个结构问题,或者我没有问正确的问题......但是我的代码中的任何帮助都允许某人输入主机IP地址或CIDR格式的子网,如果代码输入值错误,这两个人都没有进入。同时将每个附加到适当的列表将不胜感激。

主要代码(仅供参考:e1变量是输入文本框):

  def add_ip(self):
    self.hostiplist = []
    self.cidriplist = []
    try:
      if not self.e1.get():# empty! (empty string is false value)
        messagebox.showerror(title='Error', message='Ooops, Please enter an acceptible host or network IP Address.')
        self.e1.delete(0,END)
      elif self.e1.get() == " ":
        messagebox.showerror(title='Error', message='Ooops, Please enter an acceptible host or network IP Address.')
        self.e1.delete(0,END)
      else:
        self.ip = self.e1.get()
        if self.ip == str(ipaddress.ip_address(self.e1.get())):
          self.hostiplist.append(self.ip)
          print("IP Host staged for deployment: %s" % (self.ip))
          print("")
          self.e1.delete(0,END)
        elif self.ip == str(ipaddress.ip_network(self.e1.get())):
          self.cidriplist.append(self.ip)
          print("IP Network staged for deployment: %s" % (self.ip))
          print("")
          self.e1.delete(0,END)
        else:
          print("Didn't enter valid entry")

    except ValueError as e:
      messagebox.showerror(title='Error', message='Ooops,' + str(e) + '.' + ' Please enter an acceptible host or network IP Address.')
      self.e1.delete(0,END)
      return 'Value'    
    except TypeError:
      messagebox.showerror(title='Error', message='Ooops,' + str(e) + '.' + ' Please enter an acceptible host or network IP Address.')
      self.e1.delete(0,END)
      return 'Type'

这是我的单一功能脚本,可以处理错误处理(如果输入的是CIDR格式,则会收到值错误):

def add_ip_network():
   #IPv4 & v6 Address Handling.  Nothing but those formats can be entered.
  try:
    ip = ipaddress.ip_network(e1.get())
    nonsubnethostsList.append(ip)
    print("IP Network staged for deployment: %s" % (ip))
    print("")
    e1.delete(0,END)
  except ValueError:
    print('Incorrect entry, please use IPv4 or IPv6 CIDR Formats')
    e1.delete(0,END)
    return 'Value'
  except TypeError:
    print('Incorrect entry, please use IPv4 or IPv6 CIDR Formats')
    e1.delete(0,END)
    return 'Type'

此致

编辑:
我也尝试调整我的主代码以匹配我的工作单格式脚本。 由此:

if self.ip == str(ipaddress.ip_address(self.e1.get()))

对此:

ip = ipaddress.ip_network(e1.get())

它给了我相同的值错误,所以我尝试将字符串与If语句进行比较。

1 个答案:

答案 0 :(得分:0)

我从用户Dagger0得到了关于Reddit / Python的上述问题的答案(谢谢!)。

所以基本上你需要做的是......弄清楚字符串是IP还是带有CIDR掩码的网络?好像你可以测试" /"。

# Presumably set these in __init__ or something, you don't
# want to be clearing them each time you add an entry.
self.hostiplist = []
self.cidriplist = []

def add_ip(self):
    input = self.e1.get()
    try:
        if "/" in input:
            ip = ipaddress.ip_address(input)
            # Append to self.hostiplist.
        else:
            network = ipaddress.ip_network(input)
            # Append to self.cidriplist.
    except (ValueError, TypeError) as e:
        msg = 'Ooops: %s. Please enter an acceptable host or network IP Address.' % str(e)
        messagebox.showerror(title='Error', message=msg)
        self.e1.delete(0, END)
        raise e # If you want the caller to get an exception too. Although in that case maybe the
                # whole try/except business should be in the caller, like in the bottom code block.

(完全未经测试。)

我删除了""和" "在此基础上,ipaddress.ip_address()可能会抛出这些输入的异常,所以我们也可以只使用一个异常处理程序。我不知道它是否真的如此。

你的一般问题是你在ipaddress.ip_address()抛出之后不想尝试ipaddress.ip_network()(但在这种情况下碰巧有另一种方法可以区分这两种输入)。

你也可以这样做:

try:
    ipaddress.ip_address(input)
    # It's an IP.
except (ValueError, TypeError):
    ipaddress.ip_network(input)
    # It's a network.

可能导致像这样的代码结构:

def add_ip(self, input):
    try:
        ipaddress.ip_address(input)
        # It's an IP.
    except (ValueError, TypeError):
        ipaddress.ip_network(input)
        # It's a network.

def on_button_press(self):
    try:
        self.add_ip(self.e1.get())
    except (ValueError, TypeError):
        # Neither.
        self.e1.delete(0, END)

我测试了底部的两个功能,它们完美无缺!希望这有助于其他人。