import netaddr
import re
import shlex
from cobbler.cexceptions import CX
RE_OBJECT_NAME = re.compile(r'[a-zA-Z0-9_\-.:]*$')
RE_HOSTNAME = re.compile(r'^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$')
REPO_BREEDS = ["rsync", "rhn", "yum", "apt", "wget"]
VIRT_TYPES = ["<<inherit>>", "xenpv", "xenfv", "qemu", "kvm", "vmware", "openvz"]
VIRT_DISK_DRIVERS = ["<<inherit>>", "raw", "qcow2", "qed", "vdi", "vmdk"]
# blacklist invalid values to the repo statement in autoinsts
AUTOINSTALL_REPO_BLACKLIST = ['enabled', 'gpgcheck', 'gpgkey']
[docs]def object_name(name, parent):
"""
Validate the object name.
@param: str name (object name)
@param: str parent (parent object name)
@returns: str name or CX
"""
if not isinstance(name, str) or not isinstance(parent, str):
raise CX("Invalid input, name and parent must be strings")
else:
name = name.strip()
parent = parent.strip()
if name != "" and parent != "" and name == parent:
raise CX("Self parentage is not allowed")
if not RE_OBJECT_NAME.match(name):
raise CX("Invalid characters in name: '%s'" % name)
return name
[docs]def hostname(dnsname):
"""
Validate the dns name.
@param: str dnsname (hostname or fqdn)
@returns: str dnsname or CX
"""
if not isinstance(dnsname, str):
raise CX("Invalid input, dnsname must be a string")
else:
dnsname = dnsname.strip()
if dnsname == "":
# hostname is not required
return dnsname
if not RE_HOSTNAME.match(dnsname):
raise CX("Invalid hostname format (%s)" % dnsname)
return dnsname
[docs]def mac_address(mac, for_item=True):
"""
Validate as an Eternet mac address.
@param: str mac (mac address)
@returns: str mac or CX
"""
if not isinstance(mac, str):
raise CX("Invalid input, mac must be a string")
else:
mac = mac.lower().strip()
if for_item is True:
# this value has special meaning for items
if mac == "random":
return mac
if not netaddr.valid_mac(mac):
raise CX("Invalid mac address format (%s)" % mac)
return mac
[docs]def ipv4_address(addr):
"""
Validate an IPv4 address.
@param: str addr (ipv4 address)
@returns: str addr or CX
"""
if not isinstance(addr, str):
raise CX("Invalid input, addr must be a string")
else:
addr = addr.strip()
if addr == "":
return addr
if not netaddr.valid_ipv4(addr):
raise CX("Invalid IPv4 address format (%s)" % addr)
if netaddr.IPAddress(addr).is_netmask():
raise CX("Invalid IPv4 host address (%s)" % addr)
return addr
[docs]def ipv4_netmask(addr):
"""
Validate an IPv4 netmask.
@param: str addr (ipv4 netmask)
@returns: str addr or CX
"""
if not isinstance(addr, str):
raise CX("Invalid input, addr must be a string")
else:
addr = addr.strip()
if addr == "":
return addr
if not netaddr.valid_ipv4(addr):
raise CX("Invalid IPv4 address format (%s)" % addr)
if not netaddr.IPAddress(addr).is_netmask():
raise CX("Invalid IPv4 netmask (%s)" % addr)
return addr
[docs]def ipv6_address(addr):
"""
Validate an IPv6 address.
@param: str addr (ipv6 address)
@returns: str addr or CX
"""
if not isinstance(addr, str):
raise CX("Invalid input, addr must be a string")
else:
addr = addr.strip()
if addr == "":
return addr
if not netaddr.valid_ipv6(addr):
raise CX("Invalid IPv6 address format (%s)" % addr)
return addr
[docs]def name_servers(nameservers, for_item=True):
"""
Validate nameservers IP addresses, works for IPv4 and IPv6
@param: str/list nameservers (string or list of nameserver addresses)
@param: bool for_item (enable/disable special handling for Item objects)
"""
if isinstance(nameservers, str):
nameservers = nameservers.strip()
if for_item is True:
# special handling for Items
if nameservers in ["<<inherit>>", ""]:
return nameservers
# convert string to a list; do the real validation
# in the isinstance(list) code block below
nameservers = shlex.split(nameservers)
if isinstance(nameservers, list):
for ns in nameservers:
ip_version = netaddr.IPAddress(ns).version
if ip_version == 4:
ipv4_address(ns)
elif ip_version == 6:
ipv6_address(ns)
else:
raise CX("Invalid IP address format")
else:
raise CX("Invalid input type %s, expected str or list" % type(nameservers))
return nameservers
[docs]def name_servers_search(search, for_item=True):
"""
Validate nameservers search domains.
@param: str/list search (string or list of search domains)
@param: bool for_item (enable/disable special handling for Item objects)
"""
if isinstance(search, str):
search = search.strip()
if for_item is True:
# special handling for Items
if search in ["<<inherit>>", ""]:
return search
# convert string to a list; do the real validation
# in the isinstance(list) code block below
search = shlex.split(search)
if isinstance(search, list):
for sl in search:
hostname(sl)
else:
raise CX("Invalid input type %s, expected str or list" % type(search))
return search
# EOF