Beispiel #1
0
 def test_clear(self):
     pd = PersistentDict((x, True) for x in range(10))
     assert pd.has_key(2)
     pd.clear()
     assert not pd.has_key(2)
     assert list(pd.keys()) == []
Beispiel #2
0
 def clear(self):
     pd = PersistentDict((x, True) for x in range(10))
     assert pd.has_key(2)
     pd.clear()
     assert not pd.has_key(2)
     assert list(pd.keys()) == []
Beispiel #3
0
class NetworkDevice(OwnedPersistent):
	"""NetworkDevice([name])
This object is a persistent store object that represents a networked device as
a collection of interfaces. It has a name that is used for string conversion.
	"""
	# the following (class-level attributes) become the default values for
	# various methods. Set an instance attribute of the same name to override
	# these values.
	user = None # default user to log in as
	password = None # default password for default user
	prompt = "# " # default CLI prompt for interactive sessions
	accessmethod = "ssh" # default. Possible are: ssh, console, serial, telnet, snmp
	initialaccessmethod = "console" # how to access for initial (before accessmethod is available) access
	console_server = (None, None) # host and TCP port used to connect to device serial console
	power_controller = (None, None) # APC host and outlet number used to control power
	monitor_port = (None, None) # may contain tuple of (device, interface) of an etherswitch to monitor
	domain = None # default DNS domain of the device
	nameservers = []	   # default DNS server list to be configured
	ntpserver = None	   # default NTP server to configure
	sysObjectID = None # The SNMP object identifier for a (sub)class of device.
	snmpRoCommunity = "public"	   # default RO SNMP community to use
	snmpRwCommunity = "private"    # default RW SNMP community to use
	admin_interface = "eth0" # interface on administrative network. This interface is "invisible" to device methods.
	data_interfaces = ["eth0"] # the "business" interfaces that are in use.

	def __init__(self, name):
		super(NetworkDevice, self).__init__()
		self.name = self.hostname = str(name)
		self.INTERFACEMAP = PersistentDict()
		self._interfaces = PersistentDict()
		self.data_interfaces = PersistentList()
		self.admin_interface = None
		self.initialize() # subclass interface

	# a non-persistent dictionary to cache transient attributes from a device
	def _get_cache(self):
		try:
			return self.__dict__["_cache_"]
		except KeyError:
			import dictlib
			c = dictlib.AttrDict()
			self.__dict__["_cache_"] = c
			return c
	_cache = property(_get_cache)

	def __repr__(self):
		return "%s(%r)" % (self.__class__.__name__, self.name)

	def __str__(self):
		return self.name # don't change this or you will break a lot of things 

	def initialize(self):
		pass

	def interface_alias(self, name, alias=None):
		"""sets (or removes) an alias name for an interface."""
		if alias is not None:
			self.INTERFACEMAP[str(alias)] = str(name)
		else:
			del self.INTERFACEMAP[str(name)]

	def set_hostname(self, name):
		"""Sets the hostname (and alias "name" attribute)."""
		self.name = self.hostname = str(name)

	def add_interface(self, devname, address=None, mask=None, hostname=None, linktype=BROADCAST):
		"""add_interface(devname, [address, [mask, [hostname, [linktype]]]])
Adds a new network interface to the device. Supply its interface name, and its
address.
		"""
		devname = self.INTERFACEMAP.get(devname, devname)
		if self._interfaces.has_key(devname):
			return self._interfaces[devname].update(address, mask, hostname, linktype)
		if not address:
			try:
				address=ipv4.IPv4(self.hostname)
			except:
				address = None
		if not hostname:
			if address:
				try:
					hostname = address.hostname
				except:
					hostname = "%s_%s" % (self.hostname, devname)
			else:
				hostname = "%s_%s" % (self.hostname, devname)
		intf = Interface(devname, address, mask, hostname, linktype)
		self._interfaces[devname] = intf
		intf.owner = self
		self._p_note_change()
		return intf

	def update_interface(self, devname, address=None, mask=None, hostname=None, linktype=BROADCAST):
		devname = self.INTERFACEMAP.get(devname, devname)
		return self._interfaces[devname].update(address, mask, hostname, linktype)

	def get_interface(self, devname):
		"""Return an Interface object from the index. The index value may be an integer or a name.  """
		devname = self.INTERFACEMAP.get(devname, devname)
		return self._interfaces[devname]

	def set_interface(self, intf):
		if isinstance(intf, Interface):
			self._interfaces[intf.device] = intf
		else:
			raise ValueError, "interfaces: value must be Interface object."

	def del_interface(self, devname):
		"""Delete an interface given the name, or index as an integer."""
		devname = self.INTERFACEMAP.get(devname, devname)
		intf = self._interfaces[devname]
		del self._interfaces[devname]
		intf.owner = None

	def get_interfaces(self):
		return self._interfaces.copy()

	def del_interfaces(self):
		self._interfaces.clear()

	interfaces = property(get_interfaces, None, del_interfaces, "device interfaces")

	# return a list of IPv4 addresses used by the data interfaces of this device.
	def _get_ipv4(self):
		rv = []
		for name in self.data_interfaces:
			intf = self._interfaces[name]
			rv.append(intf.address)
		return rv
	addresses = property(_get_ipv4)

	def get_address(self, ifname):
		return self._interfaces[ifname].address

	def reset(self):
		self._interfaces.clear()
		self.set_hostname("")
		self.disown()

	def connect(self, ifname, network):
		"""Connect this device to a network object (the supplied parameter)."""
		assert isinstance(network, Network), "network parameter must be a Network object."
		ifname = self.INTERFACEMAP.get(ifname, ifname)
		try:
			intf = self._interfaces[ifname]
		except KeyError:
			intf = self.add_interface(ifname)
		intf.connect(network)
	
	def disconnect(self, ifname):
		"""disconnect the named interface from its network."""
		ifname = self.INTERFACEMAP.get(ifname, ifname)
		intf = self._interfaces[ifname]
		intf.disconnect()

	def connections(self, network=None):
		"""Return a list of interfaces connected to the given network object,
		or all connections if no network provided."""
		rv = []
		for intf in self._interfaces.values():
			if network is None and intf.network is not None:
				rv.append(intf)
			elif intf.network is network:
				rv.append(intf)
		return rv
Beispiel #4
0
class IPAssignments(OwnedPersistent):
	def __init__(self, name, *args):
		super(IPAssignments, self).__init__()
		self.name = name
		self._store = PersistentDict()
		for arg in args:
			self.add(arg)

	def __contains__(self, address):
		if isinstance(address, str):
			address = ipv4.IPv4(address)
		for ip in self._store.iterkeys():
			if address == ip:
				return True
		return False

	def __str__(self):
		s = []
		for address, disp in self._store.items():
			s.append("%s is %s\n" % (address.cidr(), IF(disp, "used.", "free.")))
		s.sort()
		return "".join(s)

	def __repr__(self):
		return "%s(%r, ...)" % (self.__class__.__name__, self.name)

	def __iter__(self):
		return self._store.iteritems()

	def get(self, ip):
		if isinstance(ip, str):
			ip = ipv4.IPv4(ip)
		return ip, self._store.get(ip)

	def add(self, arg):
		if isinstance(arg, str):
			arg = ipv4.IPv4(arg)
		if isinstance(arg, ipv4.IPRange):
			for ip in arg:
				self._store[ip] = False
		elif isinstance(arg, ipv4.IPv4):
			for ip in arg[1:-1]:
				self._store[ip] = False
		else:
			raise ValueError, "must be IP address or Range."

	# IPv4 used as a VLSM range here
	def add_net(self, ipnet):
		if isinstance(ipnet, str):
			ipnet = ipv4.IPv4(ipnet)
		if isinstance(ipnet, ipv4.IPv4):
			for ip in ipnet[1:-1]:
				self._store[ip] = False
		else:
			raise ValueError, "must add IPv4 network"
	add_network = add_net
	
	def add_range(self, addr1, addr2):
		rng = ipv4.IPRange(addr1, addr2)
		for ip in rng:
			self._store[ip] = False

	def remove(self, arg):
		if isinstance(arg, str):
			arg = ipv4.IPv4(arg)
		if isinstance(arg, ipv4.IPRange):
			for ip in arg:
				try:
					del self._store[ip]
				except KeyError:
					pass
		elif isinstance(arg, ipv4.IPv4):
			for ip in arg[1:-1]:
				try:
					del self._store[ip]
				except KeyError:
					pass
		else:
			raise ValueError, "must be IP address or Range."
	
	# removes the given range of IP. Useful for making "holes"
	def remove_range(self, addr1, addr2):
		rng = ipv4.IPRange(addr1, addr2)
		for ip in rng:
			try:
				del self._store[ip]
			except KeyError:
				pass
	
	def remove_net(self, ipnet):
		if isinstance(ipnet, str):
			ipnet = ipv4.IPv4(ipnet)
		if isinstance(ipnet, ipv4.IPv4):
			for ip in ipnet[1:-1]:
				try:
					del self._store[ip]
				except KeyError:
					pass
		else:
			raise ValueError, "must add IPv4 network"

	def allocate(self, address):
		if isinstance(address, str):
			address = ipv4.IPv4(address)
		self._store[address] = True
	
	def deallocate(self, address):
		if isinstance(address, str):
			address = ipv4.IPv4(address)
		try:
			self._store[address] = False
		except KeyError:
			pass
	
	def reset(self):
		"""deallocate all addressess"""
		for addr in self._store.iterkeys():
			self._store[addr] = False

	def clear(self):
		"""remove all addresses."""
		self._store.clear()

	# find next available IP address. Raise ValueError if exhausted.
	# If Network is supplied, only pick an IP in that network.
	def get_next(self, network=None):
		for addr, allocated in self._store.items():
			if allocated:
				continue
			if network is not None:
				if addr in network:
					self._store[addr] = True
					return addr
				else:
					continue
			else:
				self._store[addr] = True
				return addr
		raise ValueError, "No more addresses availiable in the assignment"
Beispiel #5
0
class IPAssignments(OwnedPersistent):
    def __init__(self, name, *args):
        super(IPAssignments, self).__init__()
        self.name = name
        self._store = PersistentDict()
        for arg in args:
            self.add(arg)

    def __contains__(self, address):
        if isinstance(address, str):
            address = ipv4.IPv4(address)
        for ip in self._store.iterkeys():
            if address == ip:
                return True
        return False

    def __str__(self):
        s = []
        for address, disp in self._store.items():
            s.append("%s is %s\n" %
                     (address.cidr(), IF(disp, "used.", "free.")))
        s.sort()
        return "".join(s)

    def __repr__(self):
        return "%s(%r, ...)" % (self.__class__.__name__, self.name)

    def __iter__(self):
        return self._store.iteritems()

    def get(self, ip):
        if isinstance(ip, str):
            ip = ipv4.IPv4(ip)
        return ip, self._store.get(ip)

    def add(self, arg):
        if isinstance(arg, str):
            arg = ipv4.IPv4(arg)
        if isinstance(arg, ipv4.IPRange):
            for ip in arg:
                self._store[ip] = False
        elif isinstance(arg, ipv4.IPv4):
            for ip in arg[1:-1]:
                self._store[ip] = False
        else:
            raise ValueError, "must be IP address or Range."

    # IPv4 used as a VLSM range here
    def add_net(self, ipnet):
        if isinstance(ipnet, str):
            ipnet = ipv4.IPv4(ipnet)
        if isinstance(ipnet, ipv4.IPv4):
            for ip in ipnet[1:-1]:
                self._store[ip] = False
        else:
            raise ValueError, "must add IPv4 network"

    add_network = add_net

    def add_range(self, addr1, addr2):
        rng = ipv4.IPRange(addr1, addr2)
        for ip in rng:
            self._store[ip] = False

    def remove(self, arg):
        if isinstance(arg, str):
            arg = ipv4.IPv4(arg)
        if isinstance(arg, ipv4.IPRange):
            for ip in arg:
                try:
                    del self._store[ip]
                except KeyError:
                    pass
        elif isinstance(arg, ipv4.IPv4):
            for ip in arg[1:-1]:
                try:
                    del self._store[ip]
                except KeyError:
                    pass
        else:
            raise ValueError, "must be IP address or Range."

    # removes the given range of IP. Useful for making "holes"
    def remove_range(self, addr1, addr2):
        rng = ipv4.IPRange(addr1, addr2)
        for ip in rng:
            try:
                del self._store[ip]
            except KeyError:
                pass

    def remove_net(self, ipnet):
        if isinstance(ipnet, str):
            ipnet = ipv4.IPv4(ipnet)
        if isinstance(ipnet, ipv4.IPv4):
            for ip in ipnet[1:-1]:
                try:
                    del self._store[ip]
                except KeyError:
                    pass
        else:
            raise ValueError, "must add IPv4 network"

    def allocate(self, address):
        if isinstance(address, str):
            address = ipv4.IPv4(address)
        self._store[address] = True

    def deallocate(self, address):
        if isinstance(address, str):
            address = ipv4.IPv4(address)
        try:
            self._store[address] = False
        except KeyError:
            pass

    def reset(self):
        """deallocate all addressess"""
        for addr in self._store.iterkeys():
            self._store[addr] = False

    def clear(self):
        """remove all addresses."""
        self._store.clear()

    # find next available IP address. Raise ValueError if exhausted.
    # If Network is supplied, only pick an IP in that network.
    def get_next(self, network=None):
        for addr, allocated in self._store.items():
            if allocated:
                continue
            if network is not None:
                if addr in network:
                    self._store[addr] = True
                    return addr
                else:
                    continue
            else:
                self._store[addr] = True
                return addr
        raise ValueError, "No more addresses availiable in the assignment"
Beispiel #6
0
class NetworkDevice(OwnedPersistent):
    """NetworkDevice([name])
This object is a persistent store object that represents a networked device as
a collection of interfaces. It has a name that is used for string conversion.
    """
    # the following (class-level attributes) become the default values for
    # various methods. Set an instance attribute of the same name to override
    # these values.
    user = None  # default user to log in as
    password = None  # default password for default user
    prompt = "# "  # default CLI prompt for interactive sessions
    accessmethod = "ssh"  # default. Possible are: ssh, console, serial, telnet, snmp
    initialaccessmethod = "console"  # how to access for initial (before accessmethod is available) access
    console_server = (
        None, None
    )  # host and TCP port used to connect to device serial console
    power_controller = (None, None
                        )  # APC host and outlet number used to control power
    monitor_port = (
        None, None
    )  # may contain tuple of (device, interface) of an etherswitch to monitor
    domain = None  # default DNS domain of the device
    nameservers = []  # default DNS server list to be configured
    ntpserver = None  # default NTP server to configure
    sysObjectID = None  # The SNMP object identifier for a (sub)class of device.
    snmpRoCommunity = "public"  # default RO SNMP community to use
    snmpRwCommunity = "private"  # default RW SNMP community to use
    admin_interface = "eth0"  # interface on administrative network. This interface is "invisible" to device methods.
    data_interfaces = ["eth0"]  # the "business" interfaces that are in use.

    def __init__(self, name):
        super(NetworkDevice, self).__init__()
        self.name = self.hostname = str(name)
        self.INTERFACEMAP = PersistentDict()
        self._interfaces = PersistentDict()
        self.data_interfaces = PersistentList()
        self.admin_interface = None
        self.initialize()  # subclass interface

    # a non-persistent dictionary to cache transient attributes from a device
    def _get_cache(self):
        try:
            return self.__dict__["_cache_"]
        except KeyError:
            from pycopia import dictlib
            c = dictlib.AttrDict()
            self.__dict__["_cache_"] = c
            return c

    _cache = property(_get_cache)

    def __repr__(self):
        return "%s(%r)" % (self.__class__.__name__, self.name)

    def __str__(self):
        return self.name  # don't change this or you will break a lot of things

    def initialize(self):
        pass

    def interface_alias(self, name, alias=None):
        """sets (or removes) an alias name for an interface."""
        if alias is not None:
            self.INTERFACEMAP[str(alias)] = str(name)
        else:
            del self.INTERFACEMAP[str(name)]

    def set_hostname(self, name):
        """Sets the hostname (and alias "name" attribute)."""
        self.name = self.hostname = str(name)

    def add_interface(self,
                      devname,
                      ipaddress=None,
                      mask=None,
                      hostname=None,
                      physaddress=None,
                      ifindex=None,
                      iftype=0):
        devname = self.INTERFACEMAP.get(devname, devname)
        if self._interfaces.has_key(devname):
            return
        if ipaddress is not None:
            ipaddress = ipv4.IPv4(ipaddress, mask)
        if not hostname:
            if ipaddress is not None:
                try:
                    hostname = ipaddress.hostname
                except:
                    hostname = self._get_ifname(devname)
                else:
                    if not hostname:
                        hostname = self._get_ifname(devname)
            else:
                hostname = self._get_ifname(devname)
        intf = Interface(devname, ipaddress, hostname, iftype, physaddress,
                         ifindex)
        self._interfaces[devname] = intf
        intf.owner = self
        self._p_note_change()
        return intf

    def _get_ifname(self, devname):
        return "%s_%s" % (self.hostname.split(".")[0], devname)

    def update_interface(self,
                         devname,
                         address=None,
                         mask=None,
                         hostname=None,
                         iftype=0):
        devname = self.INTERFACEMAP.get(devname, devname)
        return self._interfaces[devname].update(address, mask, hostname,
                                                iftype)

    def get_interface(self, devname):
        """Return an Interface object from the index. The index value may be an integer or a name.  """
        devname = self.INTERFACEMAP.get(devname, devname)
        return self._interfaces[devname]

    def set_interface(self, intf):
        if isinstance(intf, Interface):
            self._interfaces[intf.device] = intf
        else:
            raise ValueError, "interfaces: value must be Interface object."

    def del_interface(self, devname):
        """Delete an interface given the name, or index as an integer."""
        devname = self.INTERFACEMAP.get(devname, devname)
        intf = self._interfaces[devname]
        del self._interfaces[devname]
        intf.owner = None

    def get_interfaces(self):
        return self._interfaces.copy()

    def del_interfaces(self):
        self._interfaces.clear()

    interfaces = property(get_interfaces, None, del_interfaces,
                          "device interfaces")

    # return a list of IPv4 addresses used by the data interfaces of this device.
    def _get_ipv4(self):
        rv = []
        for name in self.data_interfaces:
            intf = self._interfaces[name]
            rv.append(intf.address)
        return rv

    addresses = property(_get_ipv4)

    def get_address(self, ifname):
        return self._interfaces[ifname].address

    def reset(self):
        self._interfaces.clear()
        self.set_hostname("")
        self.disown()

    def connect(self, ifname, network):
        """Connect this device to a network object (the supplied parameter)."""
        assert isinstance(
            network, Network), "network parameter must be a Network object."
        ifname = self.INTERFACEMAP.get(ifname, ifname)
        try:
            intf = self._interfaces[ifname]
        except KeyError:
            intf = self.add_interface(ifname)
        intf.connect(network)

    def disconnect(self, ifname):
        """disconnect the named interface from its network."""
        ifname = self.INTERFACEMAP.get(ifname, ifname)
        intf = self._interfaces[ifname]
        intf.disconnect()

    def connections(self, network=None):
        """Return a list of interfaces connected to the given network object,
        or all connections if no network provided."""
        rv = []
        for intf in self._interfaces.values():
            if network is None and intf.network is not None:
                rv.append(intf)
            elif intf.network is network:
                rv.append(intf)
        return rv