def test_type_checkers(self): # is_valid_ipv4_address self.assertTrue(Convert.is_valid_ipv4_address('192.168.16.2')) self.assertTrue(Convert.is_valid_ipv4_address('255.255.255.255')) self.assertFalse(Convert.is_valid_ipv4_address('192.168.16.')) self.assertFalse(Convert.is_valid_ipv4_address('.168.16.48')) self.assertFalse(Convert.is_valid_ipv4_address('test')) self.assertFalse(Convert.is_valid_ipv4_address('5')) self.assertFalse(Convert.is_valid_ipv4_address('1.1.1.1,2.2.2.2')) # is_valid_ipv6_address self.assertFalse(Convert.is_valid_ipv6_address('192.168.16.2')) self.assertTrue(Convert.is_valid_ipv6_address('::')) self.assertTrue(Convert.is_valid_ipv6_address('1::')) self.assertTrue(Convert.is_valid_ipv6_address('1::5')) self.assertTrue(Convert.is_valid_ipv6_address('1::5:5')) self.assertFalse(Convert.is_valid_ipv6_address('myhost.com')) self.assertFalse(Convert.is_valid_ipv6_address('test')) # is_valid_ip_address self.assertTrue(Convert.is_valid_ip_address('192.168.16.2')) self.assertTrue(Convert.is_valid_ip_address('1::5')) self.assertFalse(Convert.is_valid_ip_address('myhost.com')) # is_int_value self.assertTrue(Convert.is_int_value('-1')) self.assertTrue(Convert.is_int_value('0')) self.assertTrue(Convert.is_int_value('5000')) self.assertTrue(Convert.is_int_value('5000000000')) self.assertFalse(Convert.is_int_value('test')) self.assertFalse(Convert.is_int_value('5.5')) self.assertFalse(Convert.is_int_value('5,5'))
def add_ccap_cores(self, ccap_cores, port_master=GCPSessionDescriptor.DEFAULT_PORT_MASTER): """Create GCP descriptors based on addresses of CCAP cores received from DHCP server to orchestrator. :param ccap_cores: list of "interface;core ip" :type ccap_cores: list(string) :return: """ descriptors = [] for core_addr in ccap_cores: interface, core = core_addr.split(';') if not Convert.is_valid_ip_address(core): self.logger.warn("Malformed IP address received: %s", core) continue is_ipv6 = Convert.is_valid_ipv6_address(core) family = (AF_INET, AF_INET6)[is_ipv6] addr_local = SysTools.get_ip_address(str(interface), family) # TODO pass also local address to use specific interface descriptors.append( GCPSlaveDescriptor(core, port_master=port_master, addr_local=addr_local, interface_local=interface, addr_family=family)) self.orchestrator.add_sessions(descriptors)
def config_rsyslog(self, address): """Set address of remote log server,support rsyslog. - For now only one log-server(rsyslog) is supported (TCP is used) :param address: rsyslog server IP address (v4 or v6) or None to disable remotelogging feature :param logging_level: string or None :param rotate_size: rotatation size for log file :return: """ if None is address: # disable remote logging feature # restart rsyslog self.restart_rsyslog() return if not Convert.is_valid_ip_address(address): self.logger.warning( "Invalid IP address provided for remote logging: %s", address) return try: # enable remote logging feature self.config_rsyslog_remote(address) # restart rsyslogd self.restart_rsyslog() except (OSError, ValueError): self.logger.error("Failed remote logging configuration")
def _verify_dhcp_data(self): """Verify data from msg sent by DHCP client. Invalid or bad formatted data are removed. :return: """ for descr, value in self.dhcp_data.ListFields(): self.logger.info("%s = %s", descr.name, str(value)) if descr.name in ['CCAPCores', 'LogServers', 'TimeServers']: # Walk list of IP addresses and check one-by-one for ip_addr in value[:]: # Remove all invalid values if not Convert.is_valid_ip_address(ip_addr): self.logger.warn( "Unexpected format of value: " "%s = %s", descr.name, ip_addr) value.remove(ip_addr) elif descr.name == 'TimeOffset': # Nothing to be checked (int32) pass else: self.logger.error("Unknown value found: %s", descr.name) self.store_dhcp_data()
def main(): parser = argparse.ArgumentParser() parser.add_argument('--rpd-image', required=True, action='append') parser.add_argument('--server-image') parser.add_argument('--server-addr', help='IP address to be used for eth1') parser.add_argument('--disable-terminal', action='store_true') parser.add_argument('--destroy-before', action='store_true', help='Destroy all VMs and networks at the beginning') args = parser.parse_args() # Check arguments for image_path in args.rpd_image: if not os.path.exists(image_path): parser.error("RPD image file not found: {}".format(image_path)) if args.server_image is not None: if not os.path.exists(args.server_image): parser.error("Server image file not found: {}".format( args.server_image)) if args.server_addr is not None and \ not Convert.is_valid_ip_address(args.server_addr): parser.error("Server IP address is not valid: {}".format( args.server_addr)) # Create topology and start VMs topology = Topology() if args.destroy_before: topology.stop_all_force() if args.server_image is not None: topology.create_vm(args.server_image, name='server', start=False) for idx, image_path in enumerate(args.rpd_image): topology.create_vm(image_path, name='RPD' + str(idx + 1), start=False) topology.start_and_wait_for_all() # Assign server address if None not in (args.server_addr, args.server_image): topology.nodes['server'].change_eth1_ip_addr(args.server_addr) # Open terminals or print IP addresses for node in topology.nodes.values(): if not args.disable_terminal: node.open_terminal() else: print "VM: '{}': '{}'".format(node.name, node.ip_addresses[0]) print "Topology should be ready, press anything to kill it" raw_input() # Destroy topology and delete created files topology.cleanup() exit(EX_OK)
def change_eth1_ip_addr(self, ip_addr): """Change IP address on eth1 NOTE: Do not forget to restart services if already running. :param ip_addr: IP address to be assigned to eth1 interface. In format: 1.2.3.4. This is applicable only for 'external' images. RPD image requires DHCP managed eth1 interface. Support for mask and gateway change can be added in the future. :return: """ if not Convert.is_valid_ip_address(ip_addr): raise TypeError("Invalid IP address string provided: %s", ip_addr) is_ipv4 = Convert.is_valid_ipv4_address(ip_addr) if is_ipv4: self.ip_addresses = (self.ip_addresses[0], ip_addr) net_name = 'lan' else: self.ipv6_addresses = (self.ipv6_addresses[0], ip_addr) net_name = 'lanV6' # Check if protocol on eth1 is set to static (truth only on external) try: proto = self.run_command( "uci show network.{}.proto".format(net_name)) if proto[0].strip().split('=')[1] != '\'static\'': raise TypeError("IP address is not static - not server side?") # Configure IP address provided if is_ipv4: cmd = "uci set network.{net}.ipaddr={ip_addr}; " else: cmd = "uci set network.{net}.ip6addr={ip_addr}/64; " # Commit changes to network configuration cmd += "uci commit network; " # Apply config to interface cmd += "ifup {net}" self.run_command(cmd.format(net=net_name, ip_addr=ip_addr)) except subprocess.CalledProcessError as exception: self.logger.error( "Failed to set IP address to host: %s", exception.message) return
def verify_dhcp_data(self): """Verify data from msg sent by DHCP client, with invalid or ill formatted dataremoved.""" for descr, value in self.dhcp_data.ListFields(): self.logger.debug("%s = %s", descr.name, str(value)) if descr.name in ['CCAPCores', 'LogServers', 'TimeServers']: # Walk list of IP addresses and check one-by-one for ip_addr in value[:]: # Remove all invalid values if not Convert.is_valid_ip_address(ip_addr): self.logger.warn( "Unexpected format of value: " "%s = %s", descr.name, ip_addr) value.remove(ip_addr) elif descr.name in ['TimeOffset', 'Slaac']: # Nothing to be checked (int32) pass else: self.logger.warn("Unknown DHCP option found: %s, ignore it.", descr.name) self.store_dhcp_data()
def configure_remote_logging(self, address): # pragma: no cover """Set address of remote log server, - For now only one log-server is supported (UDP is used, so we don't have dependable confirmation, whether logging server is really there) :param address: Syslog IP address (v4 or v6) or None to disable remote logging feature :type address: string or None :return: """ if not (None is address or Convert.is_valid_ip_address(address)): self.logger.warning( "Invalid IP address provided for remote logging: %s", address) return try: call(["uci", "set", "system.@system[0].log_ip=" + (address or "")]) call(["uci", "commit", "system"]) call(["/etc/init.d/log", "reload"]) except (OSError, ValueError): self.logger.error("Failed remote logging configuration")