def get_ports(cls, client_object):
        """
        Fetches all the ports on the switch along with attachment information
        for each port.

        @type client_object: BaseClient
        @param client_object: CLI client object that is used to execute
            commands on the relevant host.
        @rtype: dict
        @return: Returns dict of dicts  where the outer dict contains the
            port names as keys and the inner dict holds information for the
            uuid and the inner most dict has information about the uuid of each
            interface attached to the port keyed by interface name.
        """
        ret = collections.defaultdict(lambda: collections.defaultdict(dict))
        bridge = client_object.ovsdb.Bridge.get_one(search='name=%s' %
                                                    client_object.name)
        ports = client_object.ovsdb.Port.get_all()
        interfaces = client_object.ovsdb.Interface.get_all()
        port_uuids = utilities.as_list(bridge.ports)
        for port_uuid in port_uuids:
            for port in ports:
                if port.uuid == port_uuid:
                    ret[port.name]['uuid'] = port_uuid
                    port_iface_uuids = utilities.as_list(port.interfaces)
                    for port_iface_uuid in port_iface_uuids:
                        for iface in interfaces:
                            if iface.uuid == port_iface_uuid:
                                ret[port.name]['interfaces'][iface.name] = (
                                    iface.uuid)
        return ret
    def get_ports(cls, client_object):
        """
        Fetches all the ports on the switch along with attachment information
        for each port.

        @type client_object: BaseClient
        @param client_object: CLI client object that is used to execute
            commands on the relevant host.
        @rtype: dict
        @return: Returns dict of dicts  where the outer dict contains the
            port names as keys and the inner dict holds information for the
            uuid and the inner most dict has information about the uuid of each
            interface attached to the port keyed by interface name.
        """
        ret = collections.defaultdict(
            lambda: collections.defaultdict(dict))
        bridge = client_object.ovsdb.Bridge.get_one(search='name=%s' %
                                                    client_object.name)
        ports = client_object.ovsdb.Port.get_all()
        interfaces = client_object.ovsdb.Interface.get_all()
        port_uuids = utilities.as_list(bridge.ports)
        for port_uuid in port_uuids:
            for port in ports:
                if port.uuid == port_uuid:
                    ret[port.name]['uuid'] = port_uuid
                    port_iface_uuids = utilities.as_list(port.interfaces)
                    for port_iface_uuid in port_iface_uuids:
                        for iface in interfaces:
                            if iface.uuid == port_iface_uuid:
                                ret[port.name]['interfaces'][iface.name] = (
                                    iface.uuid)
        return ret
Beispiel #3
0
    def wget_files(cls,
                   client_object,
                   files=None,
                   directory=None,
                   accept=None,
                   timeout=None,
                   content_disposition=None):
        """
        Helper for getting files from the provided filess and storing
        them locally.

        @type client_object: BaseClient
        @param client_object: Used to pass commands to the host.
        @type files: list
        @param files: List of URLs to files or directories.
        @type directory: str
        @param directory: Target directory in which the files will be
            stored. Directory is created if not there already.
        @type accept: list
        @param accept: Specifies the list of file type/patterns to download
            from the remote url directory.
        @type timeout: int
        @param timeout: Time after which the attempt to configure package is
            aborted.
        @type content_disposition: bool
        @param content_disposition: Used to specify if the content_disposition
            is to be used in wget command.
        @rtype: str
        @return: Directory in which the files are stored.
        """
        date_and_time = utilities.current_date_time()
        files = utilities.as_list(files)
        if directory is None:
            # XXX(Salman): Needed the separator of the target host here.
            directory = os.sep.join([cls.get_temp_dir(), date_and_time])
        client_object.connection.request('mkdir -p %s' % directory)
        # XXX(Salman): This might need adjustment if the specified url does
        # not support HTTP(s)/FTP.
        fetch_cmd = [
            "%s -q -r -nH -nd -P %s --no-parent" % (cls.WGET, directory)
        ]
        if accept:
            accept = utilities.as_list(accept)
            pylogger.debug("Will only fetch packages matching %r" % accept)
            fetch_cmd.append("--accept %s" % ','.join(accept))
        if content_disposition:
            fetch_cmd.append("--content-disposition")
        fetch_cmd.append('%s')
        fetch_cmd = ' '.join(fetch_cmd)
        for package in files:
            client_object.connection.request(fetch_cmd % package,
                                             timeout=timeout)
        return directory
Beispiel #4
0
    def wget_files(cls, client_object, files=None, directory=None,
                   accept=None, timeout=None, content_disposition=None):
        """
        Helper for getting files from the provided filess and storing
        them locally.

        @type client_object: BaseClient
        @param client_object: Used to pass commands to the host.
        @type files: list
        @param files: List of URLs to files or directories.
        @type directory: str
        @param directory: Target directory in which the files will be
            stored. Directory is created if not there already.
        @type accept: list
        @param accept: Specifies the list of file type/patterns to download
            from the remote url directory.
        @type timeout: int
        @param timeout: Time after which the attempt to configure package is
            aborted.
        @type content_disposition: bool
        @param content_disposition: Used to specify if the content_disposition
            is to be used in wget command.
        @rtype: str
        @return: Directory in which the files are stored.
        """
        date_and_time = utilities.current_date_time()
        files = utilities.as_list(files)
        if directory is None:
            # XXX(Salman): Needed the separator of the target host here.
            directory = os.sep.join([cls.get_temp_dir(), date_and_time])
        client_object.connection.request('mkdir -p %s' % directory)
        # XXX(Salman): This might need adjustment if the specified url does
        # not support HTTP(s)/FTP.
        fetch_cmd = ["%s -q -r -nH -nd -P %s --no-parent" %
                     (cls.WGET, directory)]
        if accept:
            accept = utilities.as_list(accept)
            pylogger.debug("Will only fetch packages matching %r" % accept)
            fetch_cmd.append("--accept %s" % ','.join(accept))
        if content_disposition:
            fetch_cmd.append("--content-disposition")
        fetch_cmd.append('%s')
        fetch_cmd = ' '.join(fetch_cmd)
        for package in files:
            client_object.connection.request(fetch_cmd % package,
                                             timeout=timeout)
        return directory
 def enable_dhcp_server_on_interfaces(cls, client_object,
                                      adapter_interface=None):
     if adapter_interface is None:
         adapter_interface = []
     adapter_interface = utilities.as_list(adapter_interface)
     iface_cfg = ('%s%s ' % (cls.IFACE_REGEX, ' '.join(adapter_interface)))
     return client_object.replace_regex_in_file(
         path=cls.ISC_DHCP_SERVER_FILE, find=cls.IFACE_REGEX,
         replace=iface_cfg)
 def disable_dhcp_server_on_interfaces(cls, client_object,
                                       adapter_interface=None):
     if adapter_interface is None:
         adapter_interface = []
     adapter_interface = utilities.as_list(adapter_interface)
     for interface in adapter_interface:
         client_object.replace_regex_in_file(path=cls.ISC_DHCP_SERVER_FILE,
                                             find=('%s ') % interface,
                                             replace='')
     return cls.restart_dhcp_server(client_object)
Beispiel #7
0
 def enable_dhcp_server_on_interfaces(cls,
                                      client_object,
                                      adapter_interface=None):
     if adapter_interface is None:
         adapter_interface = []
     adapter_interface = utilities.as_list(adapter_interface)
     iface_cfg = ('%s%s ' % (cls.IFACE_REGEX, ' '.join(adapter_interface)))
     return client_object.replace_regex_in_file(
         path=cls.ISC_DHCP_SERVER_FILE,
         find=cls.IFACE_REGEX,
         replace=iface_cfg)
Beispiel #8
0
 def disable_dhcp_server_on_interfaces(cls,
                                       client_object,
                                       adapter_interface=None):
     if adapter_interface is None:
         adapter_interface = []
     adapter_interface = utilities.as_list(adapter_interface)
     for interface in adapter_interface:
         client_object.replace_regex_in_file(path=cls.ISC_DHCP_SERVER_FILE,
                                             find=('%s ') % interface,
                                             replace='')
     return cls.restart_dhcp_server(client_object)
 def set_port_mtu(cls, client_object, ip_address=None, value=None,
                  adapter_name=None):
     """
     Sets the MTU on the provided OVS port as specified by the interface or
     the remote ip address of the remote host.
     """
     if adapter_name:
         set_mtu_cmd = OVS.set_column_of_record(OVS.INTERFACE, adapter_name,
                                                OVS.MTU, value)
         client_object.connection.request(set_mtu_cmd)
     if ip_address:
         tunnel_ports = utilities.as_list(
             cls._get_port_name_from_remote_ip(
                 client_object, ip_address=ip_address))
         for port in tunnel_ports:
             set_mtu_cmd = OVS.set_column_of_record(
                 OVS.INTERFACE, port, OVS.MTU, value)
             client_object.connection.request(set_mtu_cmd)
 def set_port_mtu(cls,
                  client_object,
                  ip_address=None,
                  value=None,
                  adapter_name=None):
     """
     Sets the MTU on the provided OVS port as specified by the interface or
     the remote ip address of the remote host.
     """
     if adapter_name:
         set_mtu_cmd = OVS.set_column_of_record(OVS.INTERFACE, adapter_name,
                                                OVS.MTU, value)
         client_object.connection.request(set_mtu_cmd)
     if ip_address:
         tunnel_ports = utilities.as_list(
             cls._get_port_name_from_remote_ip(client_object,
                                               ip_address=ip_address))
         for port in tunnel_ports:
             set_mtu_cmd = OVS.set_column_of_record(OVS.INTERFACE, port,
                                                    OVS.MTU, value)
             client_object.connection.request(set_mtu_cmd)
Beispiel #11
0
    def list_columns_in_table(cls, table, return_columns, format_type=None):
        """
        Returns a command to list the given columns in a table.

        @type table: str
        @param table: Name of the table (e.g. 'Port')
        @type return_columns: list
        @param return_columns: List of names of the columns.
        @rtype: str
        @return: OVS query command.
        @type format_type: str
        @param format_type: Name of the format type (e.g 'table')
        """
        return_columns = utilities.as_list(return_columns)
        if format_type:
            list_columns_cmd = ('%s --format %s --columns=%s list %s' %
                                (cls.VSCTL, format_type,
                                    ','.join(return_columns), table))
        else:
            list_columns_cmd = ('%s -- --columns=%s list %s' %
                                (cls.VSCTL, ','.join(return_columns), table))
        return list_columns_cmd
Beispiel #12
0
    def find_columns_in_table(cls, table, return_columns, match_column,
                              value, key=None, data_format=None):
        """
        Returns a command for getting columns of the record found in the given
        table that matches the key/value queried for the matched column.

        @type table: str
        @param table: Name of the table (e.g. 'Bridge')
        @type return_columns: str
        @param return_columns: Comma separated names of the columns that we
            want to retrieve for a given record.
        @type match_column: str
        @param match_column: Name of the column that will be used to find a
            record.
        @type value: str
        @param value: Value of the match_column that will be used to find the
            record we are interested in.
        @type key: str
        @param key: If the column that we are matching against consists of data
            in key/value format (e.g. external_ids column), then this option
            can be used to provide the key.
        @type data_format: str
        @param data_format: Determines the formatting of data of cells in the
            output of the table retrieved from OVSDB query. (e.g. 'bare',
            'json' etc.)
        """
        return_columns = utilities.as_list(return_columns)
        find_cmd = "--columns=%s find %s" % (','.join(return_columns), table)
        opts = []
        if data_format:
            opts = ["--data=%s" % data_format]
        get_columns_cmd = ["%s %s %s" % (cls.VSCTL, " ".join(opts), find_cmd)]
        if key:
            match_part = '%s:%s=%s' % (match_column, key, value)
        else:
            match_part = '%s=%s' % (match_column, value)
        get_columns_cmd.append(match_part)
        return ' '.join(get_columns_cmd)
    def _get_iptable_cmd(cls, table=None, chain_action=None, chain=None,
                         new_chain=None, rule_num=None, protocol=None,
                         protocol_options=None, source=None,
                         destination_ip=None, action=None, goto=None,
                         in_interface=None, out_interface=None, fragment=None,
                         set_counters=None, packets=None, bytes_=None,
                         match_extensions=None, target=None, opts=None):
        """
        Helper to get the iptables command.

        Arguments Notes:
            All arguments can be mapped one-one in arguments listed with
            commands in iptables man page. The only special options that can
            subsume other options in it are protocol_options and
            match_extensions.

            protocol_options only works when a protocol is specified. It is a
            map from the option related to that protocol and the value e.g.
            for protocol='tcp', protocol_options={'--dport': 5900} is valid.

            match_extensions is a map of maps, the key of the outer dict
            is the match extension module name e.g. 'comment' and 'icmp' etc.
            The keys of the inner dicts are the opts pertinent to that module
            and the corresponding value is the list of arguments that opt
            accepts.

        Note: The caller is responsible for passing in sane parameters and
        checking for any errors that may arise when executing the returned
        command.

        @type table: str
        @param table: Name of the table in which to insert the rule (e.g
            'filter', 'nat', 'mangle', 'raw', 'security'). Defaults to
            'filter'.
        @type chain_action: str
        @param aciton: Defines the chain_action to be performed on a chain
            (e.g. '-P' for setting a policy on the chain or '-E' to rename a
            chain)
        @type chain: str
        @param chain: Name of the chain on which chain_action will be
            performed (e.g. 'INPUT', 'FORWARD' or 'OUTPUT'). Defaults to
            'INPUT'.
        @type new_chain: str
        @param new_chain: New name for the chain, if chain is being renamed.
        @type rule_num: str
        @param rule_num: Rule number
        @type protocol: str
        @param protocol: Protocol of the rule or packet to be checked.
        @type protocol_options: dict
        @param protocol_options: Map from opt to value that can be used to
            configure a rule (e.g. for tcp protocol, we can use
            {'--dport': 9999})
        @type source: str
        @param source: Source IP address/mask for the rule.
        @type destination_ip: str
        @param destination_ip: Destination IP address/mask for the rule.
        @type action: str
        @param action: Decision for a matching packet (e.g. 'ACCEPT'). It can
            also be a user defined chain.
        @type goto: str
        @param goto: Name of the chain in which the processing should take
            place.
        @type in_interface: str
        @param in_interface: Name of the interface on which packet is received.
        @type out_interface: str
        @param out_interface: Name of the interface via which packet will be
            sent out.
        @type fragment: bool
        @param fragment: Creates rules for second and further packets for a
            fragmented packets.
        @type set_counters: bool
        @param set_counters: Flags if we need to set the counters.
        @type packets: int
        @param packets: The number to which packet counter needs to be set.
        @type bytes_: int
        @param bytes_: The number to which the byte counter needs to be set.
        @type match_extensions: dict
        @param match_extensions: Map of map, where the outer dict is used to
            index the extension module to load. The inner dict contains the
            key-value pair of options pertaining to that match extension
            module (e.g. {'comment': {'--comment': 'Doctest rule'})
        @type target: str
        @param target: The policy target for a chain.
        @type opts: list
        @param opts: List of extra options that user wants to pass.
        @rtype: str
        @return: Returns the formatted iptables command.
        """
        # TODO(Salman): Add support for negating the parameters.
        chain_action = utilities.get_default(chain_action, '-L')
        # Sanity checking.
        chain_actions = ('-A', '-D', '-I', '-R', '-P', '-E')
        new_chain_actions = ('-E',)
        rule_num_actions = ('-R',)
        not_rule_num_actions = ('-A', '-L', '-S', '-F')
        rule_spec_actions = ('-A',)
        not_rule_spec_actions = ('-L', '-S', '-F', '-Z',  '-N', '-X', '-P',
                                 '-E')
        rule_num_or_rule_spec_actions = ('-D',)
        all_actions = set(chain_actions + new_chain_actions + rule_num_actions
                          + not_rule_num_actions + rule_spec_actions +
                          not_rule_spec_actions +
                          rule_num_or_rule_spec_actions)
        rule_specifications = (protocol, source, destination_ip, action, goto,
                               in_interface, out_interface, set_counters,
                               protocol_options, match_extensions, target)
        rule_specified = filter(None, rule_specifications)
        if chain_action not in all_actions:
            raise ValueError('%r is not a valid chain_action' % chain_action)
        if chain_action in chain_actions and not chain:
            raise ValueError('Need to define a chain name with %r' %
                             chain_action)
        if chain_action in rule_num_actions and not rule_num:
            raise ValueError('Need to define a rule number with %r' %
                             chain_action)
        if chain_action in rule_spec_actions and not rule_specified:
            raise ValueError('Need to specify a rule with %r' % chain_action)
        rulenum_or_rule = ((rule_num and not rule_specified) or
                           (rule_specified and not rule_num))
        if ((chain_action in rule_num_or_rule_spec_actions and not
             rulenum_or_rule)):
            raise ValueError('Need to specify a rule number or rule '
                             'specification, not both, with %r' % chain_action)
        if chain_action in not_rule_num_actions and rule_num:
            raise ValueError('%r command does not accept rule number' %
                             chain_action)
        if chain_action in not_rule_spec_actions and rule_specified:
            raise ValueError('%r does not accept any rule specification, rule '
                             'specification provided: %r' %
                             (chain_action, rule_specifications))
        table = utilities.get_default(table, cls.IPTABLE_FILTER_TABLE)
        chain = utilities.get_default(chain, cls.IPTABLE_INPUT_CHAIN)
        protocol_options = utilities.get_default(protocol_options, {})
        cmd = ['iptables -t %s %s %s' % (table, chain_action, chain)]
        # Handle special cases where the second argument to be used with the
        # command can be different from rulenum and rule specifications.
        if chain_action == '-P':
            cmd.append(target)
            cmd.extend(opts)
            return ' '.join(cmd)
        if chain_action == '-E':
            cmd.append(new_chain)
            cmd.extend(opts)
            return ' '.join(cmd)
        if opts:
            cmd.extend(opts)
        if rule_num:
            cmd.append('%d' % rule_num)
        if protocol:
            cmd.append('-p %s' % protocol)
        if protocol_options and not protocol:
            protocol_options = {}
        if protocol_options:
            for opt, val in protocol_options.iteritems():
                if opt == 'destination_port':
                    cmd.append('--dport %s' % val)
                elif opt == 'source_port':
                    cmd.append('--sport %s' % val)
                else:
                    cmd.append('--%s %s' % (opt, val))
        if match_extensions:
            for match_ext in match_extensions:
                if not match_ext.endswith('_match_ext'):
                    raise ValueError('Need the match extension module names '
                                     'to end with "_match_ext", got %r' %
                                     match_ext)
                ext = ['-m %s' % match_ext.split("_match_ext")[0]]
                opts_dict = match_extensions[match_ext]
                opts_vals = [
                    '--%s "%s"' % (opt, ' '.join(utilities.as_list(val)))
                    for opt, val in opts_dict.iteritems()]
                cmd.extend(ext + opts_vals)
        if source:
            cmd.append('-s %s' % source)
        if destination_ip:
            cmd.append('-d %s' % destination_ip)
        if action:
            cmd.append('-j %s' % action)
        if goto:
            cmd.append('-g %s' % goto)
        if in_interface:
            cmd.append('-i %s' % in_interface)
        if out_interface:
            cmd.append('-o %s' % out_interface)
        if fragment:
            cmd.append('-f')
        if set_counters:
            if None in (packets, bytes_):
                raise ValueError('set_counters is set but packets or bytes '
                                 'have not been provided')
            cmd.append('-c %s %s' % (packets, bytes_))
        return ' '.join(cmd)