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()) == []
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()) == []
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
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"
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"
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