Instruction:
Write a Python 3 function for
making the HTTP request and return the body as python object.

Response:
def _http_request(url,
                  method='GET',
                  headers=None,
                  data=None):
    '''
    Make the HTTP request and return the body as python object.
    '''
    req = requests.request(method,
                           url,
                           headers=headers,
                           data=data)
    ret = _default_ret()
    ok_status = METHOD_OK_STATUS.get(method, 200)
    if req.status_code != ok_status:
        ret.update({
            'comment': req.json().get('error', '')
        })
        return ret
    ret.update({
        'result': True,
        'out': req.json() if method != 'DELETE' else None  # no body when DELETE
    })
    return ret


Instruction:
Here you have a function in Python 3, explain what it does
def retrieve(endpoint='incidents',
             api_url=None,
             page_id=None,
             api_key=None,
             api_version=None):
    '''
    Retrieve a specific endpoint from the Statuspage API.

    endpoint: incidents
        Request a specific endpoint.

    page_id
        Page ID. Can also be specified in the config file.

    api_key
        API key. Can also be specified in the config file.

    api_version: 1
        API version. Can also be specified in the config file.

    api_url
        Custom API URL in case the user has a StatusPage service running in a custom environment.

    CLI Example:

    .. code-block:: bash

        salt 'minion' statuspage.retrieve components

    Example output:

    .. code-block:: bash

        minion:
            ----------
            comment:
            out:
                |_
                  ----------
                  backfilled:
                      False
                  created_at:
                      2015-01-26T20:25:02.702Z
                  id:
                      kh2qwjbheqdc36
                  impact:
                      major
                  impact_override:
                      None
                  incident_updates:
                      |_
                        ----------
                        affected_components:
                            None
                        body:
                            We are currently investigating this issue.
                        created_at:
                            2015-01-26T20:25:02.849Z
                        display_at:
                            2015-01-26T20:25:02.849Z
                        id:
                            zvx7xz2z5skr
                        incident_id:
                            kh2qwjbheqdc36
                        status:
                            investigating
                        twitter_updated_at:
                            None
                        updated_at:
                            2015-01-26T20:25:02.849Z
                        wants_twitter_update:
                            False
                  monitoring_at:
                      None
                  name:
                      just testing some stuff
                  page_id:
                      ksdhgfyiuhaa
                  postmortem_body:
                      None
                  postmortem_body_last_updated_at:
                      None
                  postmortem_ignored:
                      False
                  postmortem_notified_subscribers:
                      False
                  postmortem_notified_twitter:
                      False
                  postmortem_published_at:
                      None
                  resolved_at:
                      None
                  scheduled_auto_completed:
                      False
                  scheduled_auto_in_progress:
                      False
                  scheduled_for:
                      None
                  scheduled_remind_prior:
                      False
                  scheduled_reminded_at:
                      None
                  scheduled_until:
                      None
                  shortlink:
                      http://stspg.io/voY
                  status:
                      investigating
                  updated_at:
                      2015-01-26T20:25:13.379Z
            result:
                True
    '''
    params = _get_api_params(api_url=api_url,
                             page_id=page_id,
                             api_key=api_key,
                             api_version=api_version)
    if not _validate_api_params(params):
        log.error('Invalid API params.')
        log.error(params)
        return {
            'result': False,
            'comment': 'Invalid API params. See log for details'
        }
    headers = _get_headers(params)
    retrieve_url = '{base_url}/v{version}/pages/{page_id}/{endpoint}.json'.format(
        base_url=params['api_url'],
        version=params['api_version'],
        page_id=params['api_page_id'],
        endpoint=endpoint
    )
    return _http_request(retrieve_url,
                         headers=headers)

Response: This function returns a list of components that are available to the Statuspage API.


Instruction:
Can you generate the documentation for the following Python 3 function
def update(endpoint='incidents',
           id=None,
           api_url=None,
           page_id=None,
           api_key=None,
           api_version=None,
           **kwargs):
    '''
    Update attribute(s) of a specific endpoint.

    id
        The unique ID of the enpoint entry.

    endpoint: incidents
        Endpoint name.

    page_id
        Page ID. Can also be specified in the config file.

    api_key
        API key. Can also be specified in the config file.

    api_version: 1
        API version. Can also be specified in the config file.

    api_url
        Custom API URL in case the user has a StatusPage service running in a custom environment.

    CLI Example:

    .. code-block:: bash

        salt 'minion' statuspage.update id=dz959yz2nd4l status=resolved

    Example output:

    .. code-block:: bash

        minion:
            ----------
            comment:
            out:
                ----------
                created_at:
                    2017-01-03T15:25:30.718Z
                description:
                    None
                group_id:
                    993vgplshj12
                id:
                    dz959yz2nd4l
                name:
                    Management Portal
                page_id:
                    xzwjjdw87vpf
                position:
                    11
                status:
                    resolved
                updated_at:
                    2017-01-05T15:34:27.676Z
            result:
                True
    '''
    endpoint_sg = endpoint[:-1]  # singular
    if not id:
        log.error('Invalid %s ID', endpoint_sg)
        return {
            'result': False,
            'comment': 'Please specify a valid {endpoint} ID'.format(endpoint=endpoint_sg)
        }
    params = _get_api_params(api_url=api_url,
                             page_id=page_id,
                             api_key=api_key,
                             api_version=api_version)
    if not _validate_api_params(params):
        log.error('Invalid API params.')
        log.error(params)
        return {
            'result': False,
            'comment': 'Invalid API params. See log for details'
        }
    headers = _get_headers(params)
    update_url = '{base_url}/v{version}/pages/{page_id}/{endpoint}/{id}.json'.format(
        base_url=params['api_url'],
        version=params['api_version'],
        page_id=params['api_page_id'],
        endpoint=endpoint,
        id=id
    )
    change_request = {}
    for karg, warg in six.iteritems(kwargs):
        if warg is None or karg.startswith('__') or karg in UPDATE_FORBIDDEN_FILEDS:
            continue
        change_request_key = '{endpoint_sg}[{karg}]'.format(
            endpoint_sg=endpoint_sg,
            karg=karg
        )
        change_request[change_request_key] = warg
    return _http_request(update_url,
                         method='PATCH',
                         headers=headers,
                         data=change_request)

Response: Update an enpoint entry.


Instruction:
Write a Python 3 function for
deleting an entry from an endpoint.

Response:
def delete(endpoint='incidents',
           id=None,
           api_url=None,
           page_id=None,
           api_key=None,
           api_version=None):
    '''
    Remove an entry from an endpoint.

    endpoint: incidents
        Request a specific endpoint.

    page_id
        Page ID. Can also be specified in the config file.

    api_key
        API key. Can also be specified in the config file.

    api_version: 1
        API version. Can also be specified in the config file.

    api_url
        Custom API URL in case the user has a StatusPage service running in a custom environment.

    CLI Example:

    .. code-block:: bash

        salt 'minion' statuspage.delete endpoint='components' id='ftgks51sfs2d'

    Example output:

    .. code-block:: bash

        minion:
            ----------
            comment:
            out:
                None
            result:
                True
    '''
    params = _get_api_params(api_url=api_url,
                             page_id=page_id,
                             api_key=api_key,
                             api_version=api_version)
    if not _validate_api_params(params):
        log.error('Invalid API params.')
        log.error(params)
        return {
            'result': False,
            'comment': 'Invalid API params. See log for details'
        }
    endpoint_sg = endpoint[:-1]  # singular
    if not id:
        log.error('Invalid %s ID', endpoint_sg)
        return {
            'result': False,
            'comment': 'Please specify a valid {endpoint} ID'.format(endpoint=endpoint_sg)
        }
    headers = _get_headers(params)
    delete_url = '{base_url}/v{version}/pages/{page_id}/{endpoint}/{id}.json'.format(
        base_url=params['api_url'],
        version=params['api_version'],
        page_id=params['api_page_id'],
        endpoint=endpoint,
        id=id
    )
    return _http_request(delete_url,
                         method='DELETE',
                         headers=headers)


Instruction:
Given the following Python 3 function, write the documentation
def _get_repo_options(fromrepo=None, packagesite=None):
    '''
    Return a list of tuples to seed the "env" list, which is used to set
    environment variables for any pkg_add commands that are spawned.

    If ``fromrepo`` or ``packagesite`` are None, then their corresponding
    config parameter will be looked up with config.get.

    If both ``fromrepo`` and ``packagesite`` are None, and neither
    freebsdpkg.PACKAGEROOT nor freebsdpkg.PACKAGESITE are specified, then an
    empty list is returned, and it is assumed that the system defaults (or
    environment variables) will be used.
    '''
    root = fromrepo if fromrepo is not None \
        else __salt__['config.get']('freebsdpkg.PACKAGEROOT', None)
    site = packagesite if packagesite is not None \
        else __salt__['config.get']('freebsdpkg.PACKAGESITE', None)
    ret = {}
    if root is not None:
        ret['PACKAGEROOT'] = root
    if site is not None:
        ret['PACKAGESITE'] = site
    return ret

Response: Return a list of tuples to seed the env list for pkg_add commands that are spawned by pkg_add commands.


Instruction:
Given the following Python 3 function, write the documentation
def _match(names):
    '''
    Since pkg_delete requires the full "pkgname-version" string, this function
    will attempt to match the package name with its version. Returns a list of
    partial matches and package names that match the "pkgname-version" string
    required by pkg_delete, and a list of errors encountered.
    '''
    pkgs = list_pkgs(versions_as_list=True)
    errors = []

    # Look for full matches
    full_pkg_strings = []
    out = __salt__['cmd.run_stdout'](['pkg_info'],
                                     output_loglevel='trace',
                                     python_shell=False)
    for line in out.splitlines():
        try:
            full_pkg_strings.append(line.split()[0])
        except IndexError:
            continue
    full_matches = [x for x in names if x in full_pkg_strings]

    # Look for pkgname-only matches
    matches = []
    ambiguous = []
    for name in set(names) - set(full_matches):
        cver = pkgs.get(name)
        if cver is not None:
            if len(cver) == 1:
                matches.append('{0}-{1}'.format(name, cver[0]))
            else:
                ambiguous.append(name)
                errors.append(
                    'Ambiguous package \'{0}\'. Full name/version required. '
                    'Possible matches: {1}'.format(
                        name,
                        ', '.join(['{0}-{1}'.format(name, x) for x in cver])
                    )
                )

    # Find packages that did not match anything
    not_matched = \
        set(names) - set(matches) - set(full_matches) - set(ambiguous)
    for name in not_matched:
        errors.append('Package \'{0}\' not found'.format(name))

    return matches + full_matches, errors

Response: Returns a list of partial matches and package names that match the pkgname - version string.


Instruction:
Implement a Python 3 function for
listing the currently installed packages.

Response:
def list_pkgs(versions_as_list=False, with_origin=False, **kwargs):
    '''
    List the packages currently installed as a dict::

        {'<package_name>': '<version>'}

    with_origin : False
        Return a nested dictionary containing both the origin name and version
        for each installed package.

        .. versionadded:: 2014.1.0

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.list_pkgs
    '''
    versions_as_list = salt.utils.data.is_true(versions_as_list)
    # not yet implemented or not applicable
    if any([salt.utils.data.is_true(kwargs.get(x))
            for x in ('removed', 'purge_desired')]):
        return {}

    if 'pkg.list_pkgs' in __context__:
        ret = copy.deepcopy(__context__['pkg.list_pkgs'])
        if not versions_as_list:
            __salt__['pkg_resource.stringify'](ret)
        if salt.utils.data.is_true(with_origin):
            origins = __context__.get('pkg.origin', {})
            return dict([
                (x, {'origin': origins.get(x, ''), 'version': y})
                for x, y in six.iteritems(ret)
            ])
        return ret

    ret = {}
    origins = {}
    out = __salt__['cmd.run_stdout'](['pkg_info', '-ao'],
                                     output_loglevel='trace',
                                     python_shell=False)
    pkgs_re = re.compile(r'Information for ([^:]+):\s*Origin:\n([^\n]+)')
    for pkg, origin in pkgs_re.findall(out):
        if not pkg:
            continue
        try:
            pkgname, pkgver = pkg.rsplit('-', 1)
        except ValueError:
            continue
        __salt__['pkg_resource.add_pkg'](ret, pkgname, pkgver)
        origins[pkgname] = origin

    __salt__['pkg_resource.sort_pkglist'](ret)
    __context__['pkg.list_pkgs'] = copy.deepcopy(ret)
    __context__['pkg.origin'] = origins
    if not versions_as_list:
        __salt__['pkg_resource.stringify'](ret)
    if salt.utils.data.is_true(with_origin):
        return dict([
            (x, {'origin': origins.get(x, ''), 'version': y})
            for x, y in six.iteritems(ret)
        ])
    return ret


Instruction:
Can you tell what is the following Python 3 function doing
def install(name=None,
            refresh=False,
            fromrepo=None,
            pkgs=None,
            sources=None,
            **kwargs):
    '''
    Install package(s) using ``pkg_add(1)``

    name
        The name of the package to be installed.

    refresh
        Whether or not to refresh the package database before installing.

    fromrepo or packageroot
        Specify a package repository from which to install. Overrides the
        system default, as well as the PACKAGEROOT environment variable.

    packagesite
        Specify the exact directory from which to install the remote package.
        Overrides the PACKAGESITE environment variable, if present.

    Multiple Package Installation Options:

    pkgs
        A list of packages to install from a software repository. Must be
        passed as a python list.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install pkgs='["foo", "bar"]'

    sources
        A list of packages to install. Must be passed as a list of dicts,
        with the keys being package names, and the values being the source URI
        or local path to the package.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install sources='[{"foo": "salt://foo.deb"}, {"bar": "salt://bar.deb"}]'

    Return a dict containing the new package names and versions::

        {'<package>': {'old': '<old-version>',
                       'new': '<new-version>'}}

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.install <package name>
    '''
    try:
        pkg_params, pkg_type = __salt__['pkg_resource.parse_targets'](
            name, pkgs, sources, **kwargs
        )
    except MinionError as exc:
        raise CommandExecutionError(exc)

    if not pkg_params:
        return {}

    packageroot = kwargs.get('packageroot')
    if not fromrepo and packageroot:
        fromrepo = packageroot

    env = _get_repo_options(fromrepo, kwargs.get('packagesite'))
    args = []

    if pkg_type == 'repository':
        args.append('-r')  # use remote repo

    args.extend(pkg_params)

    old = list_pkgs()
    out = __salt__['cmd.run_all'](
        ['pkg_add'] + args,
        env=env,
        output_loglevel='trace',
        python_shell=False
    )
    if out['retcode'] != 0 and out['stderr']:
        errors = [out['stderr']]
    else:
        errors = []

    __context__.pop('pkg.list_pkgs', None)
    new = list_pkgs()
    _rehash()
    ret = salt.utils.data.compare_dicts(old, new)

    if errors:
        raise CommandExecutionError(
            'Problem encountered installing package(s)',
            info={'errors': errors, 'changes': ret}
        )

    return ret

Response: Installs a single package from a software repository.


Instruction:
Can you implement a function in Python 3 that
removes packages from the current node.

Response:
def remove(name=None, pkgs=None, **kwargs):
    '''
    Remove packages using ``pkg_delete(1)``

    name
        The name of the package to be deleted.

    Multiple Package Options:

    pkgs
        A list of packages to delete. Must be passed as a python list. The
        ``name`` parameter will be ignored if this option is passed.

    .. versionadded:: 0.16.0

    Returns a dict containing the changes.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.remove <package name>
        salt '*' pkg.remove <package1>,<package2>,<package3>
        salt '*' pkg.remove pkgs='["foo", "bar"]'
    '''
    try:
        pkg_params = __salt__['pkg_resource.parse_targets'](name, pkgs)[0]
    except MinionError as exc:
        raise CommandExecutionError(exc)

    old = list_pkgs()
    targets, errors = _match([x for x in pkg_params])
    for error in errors:
        log.error(error)
    if not targets:
        return {}

    out = __salt__['cmd.run_all'](
        ['pkg_delete'] + targets,
        output_loglevel='trace',
        python_shell=False
    )
    if out['retcode'] != 0 and out['stderr']:
        errors = [out['stderr']]
    else:
        errors = []

    __context__.pop('pkg.list_pkgs', None)
    new = list_pkgs()
    ret = salt.utils.data.compare_dicts(old, new)

    if errors:
        raise CommandExecutionError(
            'Problem encountered removing package(s)',
            info={'errors': errors, 'changes': ret}
        )

    return ret


Instruction:
Implement a function in Python 3 to
return a dict of all files in the system that belong to a package.

Response:
def file_dict(*packages, **kwargs):
    '''
    List the files that belong to a package, grouped by package. Not
    specifying any packages will return a list of _every_ file on the
    system's package database (not generally recommended).

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.file_list httpd
        salt '*' pkg.file_list httpd postfix
        salt '*' pkg.file_list
    '''
    errors = []
    files = {}

    if packages:
        match_pattern = '\'{0}-[0-9]*\''
        cmd = ['pkg_info', '-QL'] + [match_pattern.format(p) for p in packages]
    else:
        cmd = ['pkg_info', '-QLa']

    ret = __salt__['cmd.run_all'](cmd,
                                  output_loglevel='trace',
                                  python_shell=False)

    for line in ret['stderr'].splitlines():
        errors.append(line)

    pkg = None
    for line in ret['stdout'].splitlines():
        if pkg is not None and line.startswith('/'):
            files[pkg].append(line)
        elif ':/' in line:
            pkg, fn = line.split(':', 1)
            pkg, ver = pkg.rsplit('-', 1)
            files[pkg] = [fn]
        else:
            continue  # unexpected string

    return {'errors': errors, 'files': files}


Instruction:
Can you generate a brief explanation for the following Python 3 code
def namespaced_function(function, global_dict, defaults=None, preserve_context=False):
    '''
    Redefine (clone) a function under a different globals() namespace scope

        preserve_context:
            Allow keeping the context taken from orignal namespace,
            and extend it with globals() taken from
            new targetted namespace.
    '''
    if defaults is None:
        defaults = function.__defaults__

    if preserve_context:
        _global_dict = function.__globals__.copy()
        _global_dict.update(global_dict)
        global_dict = _global_dict
    new_namespaced_function = types.FunctionType(
        function.__code__,
        global_dict,
        name=function.__name__,
        argdefs=defaults,
        closure=function.__closure__
    )
    new_namespaced_function.__dict__.update(function.__dict__)
    return new_namespaced_function

Response: Returns a new function that is namespaced by the given function.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def alias_function(fun, name, doc=None):
    '''
    Copy a function
    '''
    alias_fun = types.FunctionType(fun.__code__,
                                   fun.__globals__,
                                   str(name),  # future lint: disable=blacklisted-function
                                   fun.__defaults__,
                                   fun.__closure__)
    alias_fun.__dict__.update(fun.__dict__)

    if doc and isinstance(doc, six.string_types):
        alias_fun.__doc__ = doc
    else:
        orig_name = fun.__name__
        alias_msg = ('\nThis function is an alias of '
                     '``{0}``.\n'.format(orig_name))
        alias_fun.__doc__ = alias_msg + (fun.__doc__ or '')

    return alias_fun

Response: Returns a copy of a function that is an alias of the given function.


Instruction:
How would you implement a function in Python 3 that
ensures that the specified DNS server list exists in the specified interface.

Response:
def dns_exists(name, servers=None, interface='Local Area Connection', replace=False):
    '''
    Configure the DNS server list in the specified interface

    Example:

    .. code-block:: yaml

        config_dns_servers:
          win_dns_client.dns_exists:
            - replace: True #remove any servers not in the "servers" list, default is False
            - servers:
              - 8.8.8.8
              - 8.8.8.9
    '''
    ret = {'name': name,
           'result': True,
           'changes': {'Servers Reordered': [], 'Servers Added': [], 'Servers Removed': []},
           'comment': ''}

    if __opts__['test']:
        ret['comment'] = 'DNS Servers are set to be updated'
        ret['result'] = None
    else:
        ret['comment'] = 'DNS Servers have been updated'

    # Validate syntax
    if not isinstance(servers, list):
        ret['result'] = False
        ret['comment'] = 'servers entry is not a list !'
        return ret

    # Do nothing is already configured
    configured_list = __salt__['win_dns_client.get_dns_servers'](interface)
    if configured_list == servers:
        ret['comment'] = '{0} are already configured'.format(servers)
        ret['changes'] = {}
        ret['result'] = True
        return ret

    # add the DNS servers
    for i, server in enumerate(servers):
        if __opts__['test']:
            if server in configured_list:
                if configured_list.index(server) != i:
                    ret['changes']['Servers Reordered'].append(server)
            else:
                ret['changes']['Servers Added'].append(server)
        else:
            if not __salt__['win_dns_client.add_dns'](server, interface, i + 1):
                ret['comment'] = (
                        'Failed to add {0} as DNS server number {1}'
                        ).format(server, i + 1)
                ret['result'] = False
                ret['changes'] = {}
                return ret
            else:
                if server in configured_list:
                    if configured_list.index(server) != i:
                        ret['changes']['Servers Reordered'].append(server)
                else:
                    ret['changes']['Servers Added'].append(server)

    # remove dns servers that weren't in our list
    if replace:
        for i, server in enumerate(configured_list):
            if server not in servers:
                if __opts__['test']:
                    ret['changes']['Servers Removed'].append(server)
                else:
                    if not __salt__['win_dns_client.rm_dns'](server, interface):
                        ret['comment'] = (
                                'Failed to remove {0} from DNS server list').format(server)
                        ret['result'] = False
                        return ret
                    else:
                        ret['changes']['Servers Removed'].append(server)

    return ret


Instruction:
Can you generate the documentation for the following Python 3 function
def dns_dhcp(name, interface='Local Area Connection'):
    '''
    Configure the DNS server list from DHCP Server
    '''
    ret = {'name': name,
           'result': True,
           'changes': {},
           'comment': ''}

    # Check the config
    config = __salt__['win_dns_client.get_dns_config'](interface)
    if config == 'dhcp':
        ret['comment'] = '{0} already configured with DNS from DHCP'.format(
                interface)
        return ret
    else:
        ret['changes'] = {'dns': 'configured from DHCP'}

    if __opts__['test']:
        ret['result'] = None
        return ret

    # change the configuration
    ret['result'] = __salt__['win_dns_client.dns_dhcp'](interface)
    if not ret['result']:
        ret['changes'] = {}
        ret['comment'] = (
                'Could not configure "{0}" DNS servers from DHCP'
                ).format(interface)

    return ret

Response: Configure the DNS server list from DHCP Server


Instruction:
Can you generate the documentation for the following Python 3 function
def primary_suffix(name,
        suffix=None,
        updates=False):
    '''
    .. versionadded:: 2014.7.0

    Configure the global primary DNS suffix of a DHCP client.

    suffix : None
        The suffix which is advertised for this client when acquiring a DHCP lease
        When none is set, the explicitly configured DNS suffix will be removed.

    updates : False
        Allow syncing the DNS suffix with the AD domain when the client's AD domain membership changes

    .. code-block:: yaml

        primary_dns_suffix:
            win_dns_client.primary_suffix:
                - suffix: sub.domain.tld
                - updates: True
    '''

    ret = {
            'name': name,
            'changes': {},
            'result': True,
            'comment': 'No changes needed'
    }

    suffix = str(suffix)

    if not isinstance(updates, bool):
        ret['result'] = False
        ret['comment'] = '\'updates\' must be a boolean value'
        return ret

    # TODO: waiting for an implementation of
    # https://github.com/saltstack/salt/issues/6792 to be able to handle the
    # requirement for a reboot to actually apply this state.
    # Until then, this method will only be able to verify that the required
    # value has been written to the registry and rebooting needs to be handled
    # manually

    reg_data = {
            'suffix': {
                'hive': 'HKEY_LOCAL_MACHINE',
                'key': r'SYSTEM\CurrentControlSet\services\Tcpip\Parameters',
                'vname':  'NV Domain',
                'vtype': 'REG_SZ',
                'old':  None,
                'new':  suffix
            },
            'updates': {
                'hive': 'HKEY_LOCAL_MACHINE',
                'key': r'SYSTEM\CurrentControlSet\services\Tcpip\Parameters',
                'vname':  'SyncDomainWithMembership',
                'vtype': 'REG_DWORD',
                'old':  None,
                'new':  updates
            }
    }

    reg_data['suffix']['old'] = __utils__['reg.read_value'](
            reg_data['suffix']['hive'],
            reg_data['suffix']['key'],
            reg_data['suffix']['vname'],)['vdata']

    reg_data['updates']['old'] = bool(__utils__['reg.read_value'](
            reg_data['updates']['hive'],
            reg_data['updates']['key'],
            reg_data['updates']['vname'],)['vdata'])

    updates_operation = 'enabled' if reg_data['updates']['new'] else 'disabled'

    # No changes to suffix needed
    if reg_data['suffix']['new'] == reg_data['suffix']['old']:
        # No changes to updates policy needed
        if reg_data['updates']['new'] == reg_data['updates']['old']:
            return ret
        # Changes to update policy needed
        else:
            ret['comment'] = '{0} suffix updates'.format(updates_operation)
            ret['changes'] = {
                    'old': {
                        'updates': reg_data['updates']['old']},
                    'new': {
                        'updates': reg_data['updates']['new']}}
    # Changes to suffix needed
    else:
        # Changes to updates policy needed
        if reg_data['updates']['new'] != reg_data['updates']['old']:
            ret['comment'] = 'Updated primary DNS suffix ({0}) and {1} suffix updates'.format(suffix, updates_operation)
            ret['changes'] = {
                    'old': {
                        'suffix': reg_data['suffix']['old'],
                        'updates': reg_data['updates']['old']},
                    'new': {
                        'suffix': reg_data['suffix']['new'],
                        'updates': reg_data['updates']['new']}}
        # No changes to updates policy needed
        else:
            ret['comment'] = 'Updated primary DNS suffix ({0})'.format(suffix)
            ret['changes'] = {
                    'old': {
                        'suffix': reg_data['suffix']['old']},
                    'new': {
                        'suffix': reg_data['suffix']['new']}}

    suffix_result = __utils__['reg.set_value'](
            reg_data['suffix']['hive'],
            reg_data['suffix']['key'],
            reg_data['suffix']['vname'],
            reg_data['suffix']['new'],
            reg_data['suffix']['vtype'])

    updates_result = __utils__['reg.set_value'](
            reg_data['updates']['hive'],
            reg_data['updates']['key'],
            reg_data['updates']['vname'],
            reg_data['updates']['new'],
            reg_data['updates']['vtype'])

    ret['result'] = suffix_result & updates_result

    return ret

Response: Configure the global primary DNS suffix of a DHCP client.


Instruction:
How would you code a function in Python 3 to
insert a new rule into a chain.

Response:
def insert(name, table='filter', family='ipv4', **kwargs):
    '''
    .. versionadded:: 2014.1.0

    Insert a rule into a chain

    name
        A user-defined name to call this rule by in another part of a state or
        formula. This should not be an actual rule.

    table
        The table that owns the chain that should be modified

    family
        Networking family, either ipv4 or ipv6

    position
        The numerical representation of where the rule should be inserted into
        the chain. Note that ``-1`` is not a supported position value.

    All other arguments are passed in with the same name as the long option
    that would normally be used for iptables, with one exception: ``--state`` is
    specified as `connstate` instead of `state` (not to be confused with
    `ctstate`).

    Jump options that doesn't take arguments should be passed in with an empty
    string.
    '''
    ret = {'name': name,
           'changes': {},
           'result': None,
           'comment': ''}

    if 'rules' in kwargs:
        ret['changes']['locale'] = []
        comments = []
        save = False
        for rule in kwargs['rules']:
            if 'rules' in rule:
                del rule['rules']
            if '__agg__' in rule:
                del rule['__agg__']
            if 'save' in rule and rule['save']:
                save = True
                if rule['save'] is not True:
                    save_file = rule['save']
                else:
                    save_file = True
                rule['save'] = False
            _ret = insert(**rule)
            if 'locale' in _ret['changes']:
                ret['changes']['locale'].append(_ret['changes']['locale'])
            comments.append(_ret['comment'])
            ret['result'] = _ret['result']
        if save:
            if save_file is True:
                save_file = None
            __salt__['iptables.save'](save_file, family=family)
        if not ret['changes']['locale']:
            del ret['changes']['locale']
        ret['comment'] = '\n'.join(comments)
        return ret

    for ignore in _STATE_INTERNAL_KEYWORDS:
        if ignore in kwargs:
            del kwargs[ignore]
    kwargs['name'] = name
    kwargs['table'] = table
    rule = __salt__['iptables.build_rule'](family=family, **kwargs)
    command = __salt__['iptables.build_rule'](full=True, family=family, command='I', **kwargs)
    if __salt__['iptables.check'](table,
                                  kwargs['chain'],
                                  rule,
                                  family) is True:
        ret['result'] = True
        ret['comment'] = 'iptables rule for {0} already set for {1} ({2})'.format(
            name,
            family,
            command.strip())
        if 'save' in kwargs and kwargs['save']:
            if kwargs['save'] is not True:
                filename = kwargs['save']
            else:
                filename = None
            saved_rules = __salt__['iptables.get_saved_rules'](family=family)
            _rules = __salt__['iptables.get_rules'](family=family)
            __rules = []
            for table in _rules:
                for chain in _rules[table]:
                    __rules.append(_rules[table][chain].get('rules'))
            __saved_rules = []
            for table in saved_rules:
                for chain in saved_rules[table]:
                    __saved_rules.append(saved_rules[table][chain].get('rules'))
            # Only save if rules in memory are different than saved rules
            if __rules != __saved_rules:
                out = __salt__['iptables.save'](filename, family=family)
                ret['comment'] += ('\nSaved iptables rule {0} for {1}\n'
                                   '{2}\n{3}').format(name, family, command.strip(), out)
        return ret
    if __opts__['test']:
        ret['comment'] = 'iptables rule for {0} needs to be set for {1} ({2})'.format(
            name,
            family,
            command.strip())
        return ret
    if not __salt__['iptables.insert'](table, kwargs['chain'], kwargs['position'], rule, family):
        ret['changes'] = {'locale': name}
        ret['result'] = True
        ret['comment'] = 'Set iptables rule for {0} to: {1} for {2}'.format(
            name,
            command.strip(),
            family)
        if 'save' in kwargs:
            if kwargs['save']:
                out = __salt__['iptables.save'](filename=None, family=family)
                ret['comment'] = ('Set and saved iptables rule {0} for {1}\n'
                                  '{2}\n{3}').format(name, family, command.strip(), out)
        return ret
    else:
        ret['result'] = False
        ret['comment'] = ('Failed to set iptables rule for {0}.\n'
                          'Attempted rule was {1}').format(
                              name,
                              command.strip())
        return ret


Instruction:
Can you generate the documentation for the following Python 3 function
def delete(name, table='filter', family='ipv4', **kwargs):
    '''
    .. versionadded:: 2014.1.0

    Delete a rule to a chain

    name
        A user-defined name to call this rule by in another part of a state or
        formula. This should not be an actual rule.

    table
        The table that owns the chain that should be modified

    family
        Networking family, either ipv4 or ipv6

    All other arguments are passed in with the same name as the long option
    that would normally be used for iptables, with one exception: ``--state`` is
    specified as `connstate` instead of `state` (not to be confused with
    `ctstate`).

    Jump options that doesn't take arguments should be passed in with an empty
    string.
    '''
    ret = {'name': name,
           'changes': {},
           'result': None,
           'comment': ''}

    if 'rules' in kwargs:
        ret['changes']['locale'] = []
        comments = []
        save = False
        for rule in kwargs['rules']:
            if 'rules' in rule:
                del rule['rules']
            if '__agg__' in rule:
                del rule['__agg__']
            if 'save' in rule and rule['save']:
                if rule['save'] is not True:
                    save_file = rule['save']
                else:
                    save_file = True
                rule['save'] = False
            _ret = delete(**rule)
            if 'locale' in _ret['changes']:
                ret['changes']['locale'].append(_ret['changes']['locale'])
            comments.append(_ret['comment'])
            ret['result'] = _ret['result']
        if save:
            if save_file is True:
                save_file = None
            __salt__['iptables.save'](save_file, family=family)
        if not ret['changes']['locale']:
            del ret['changes']['locale']
        ret['comment'] = '\n'.join(comments)
        return ret

    for ignore in _STATE_INTERNAL_KEYWORDS:
        if ignore in kwargs:
            del kwargs[ignore]
    kwargs['name'] = name
    kwargs['table'] = table
    rule = __salt__['iptables.build_rule'](family=family, **kwargs)
    command = __salt__['iptables.build_rule'](full=True, family=family, command='D', **kwargs)

    if not __salt__['iptables.check'](table,
                                      kwargs['chain'],
                                      rule,
                                      family) is True:
        if 'position' not in kwargs:
            ret['result'] = True
            ret['comment'] = 'iptables rule for {0} already absent for {1} ({2})'.format(
                name,
                family,
                command.strip())
            return ret
    if __opts__['test']:
        ret['comment'] = 'iptables rule for {0} needs to be deleted for {1} ({2})'.format(
            name,
            family,
            command.strip())
        return ret

    if 'position' in kwargs:
        result = __salt__['iptables.delete'](
                table,
                kwargs['chain'],
                family=family,
                position=kwargs['position'])
    else:
        result = __salt__['iptables.delete'](
                table,
                kwargs['chain'],
                family=family,
                rule=rule)

    if not result:
        ret['changes'] = {'locale': name}
        ret['result'] = True
        ret['comment'] = 'Delete iptables rule for {0} {1}'.format(
            name,
            command.strip())
        if 'save' in kwargs:
            if kwargs['save']:
                out = __salt__['iptables.save'](filename=None, family=family)
                ret['comment'] = ('Deleted and saved iptables rule {0} for {1}\n'
                                  '{2}\n{3}').format(name, family, command.strip(), out)
        return ret
    else:
        ret['result'] = False
        ret['comment'] = ('Failed to delete iptables rule for {0}.\n'
                          'Attempted rule was {1}').format(
                              name,
                              command.strip())
        return ret

Response: Delete a single rule from a chain.


Instruction:
How would you explain what the following Python 3 function does
def set_policy(name, table='filter', family='ipv4', **kwargs):
    '''
    .. versionadded:: 2014.1.0

    Sets the default policy for iptables firewall tables

    table
        The table that owns the chain that should be modified

    family
        Networking family, either ipv4 or ipv6

    policy
        The requested table policy

    '''
    ret = {'name': name,
        'changes': {},
        'result': None,
        'comment': ''}

    for ignore in _STATE_INTERNAL_KEYWORDS:
        if ignore in kwargs:
            del kwargs[ignore]

    if __salt__['iptables.get_policy'](
            table,
            kwargs['chain'],
            family) == kwargs['policy']:
        ret['result'] = True
        ret['comment'] = ('iptables default policy for chain {0} on table {1} for {2} already set to {3}'
                          .format(kwargs['chain'], table, family, kwargs['policy']))
        return ret
    if __opts__['test']:
        ret['comment'] = 'iptables default policy for chain {0} on table {1} for {2} needs to be set to {3}'.format(
            kwargs['chain'],
            table,
            family,
            kwargs['policy']
        )
        return ret
    if not __salt__['iptables.set_policy'](
            table,
            kwargs['chain'],
            kwargs['policy'],
            family):
        ret['changes'] = {'locale': name}
        ret['result'] = True
        ret['comment'] = 'Set default policy for {0} to {1} family {2}'.format(
            kwargs['chain'],
            kwargs['policy'],
            family
        )
        if 'save' in kwargs:
            if kwargs['save']:
                __salt__['iptables.save'](filename=None, family=family)
                ret['comment'] = 'Set and saved default policy for {0} to {1} family {2}'.format(
                    kwargs['chain'],
                    kwargs['policy'],
                    family
                )
        return ret
    else:
        ret['result'] = False
        ret['comment'] = 'Failed to set iptables default policy'
        return ret

Response: Set the default policy for iptables firewall tables


Instruction:
Can you generate the documentation for the following Python 3 function
def flush(name, table='filter', family='ipv4', **kwargs):
    '''
    .. versionadded:: 2014.1.0

    Flush current iptables state

    table
        The table that owns the chain that should be modified

    family
        Networking family, either ipv4 or ipv6

    '''
    ret = {'name': name,
           'changes': {},
           'result': None,
           'comment': ''}

    for ignore in _STATE_INTERNAL_KEYWORDS:
        if ignore in kwargs:
            del kwargs[ignore]

    if 'chain' not in kwargs:
        kwargs['chain'] = ''
    if __opts__['test']:
        ret['comment'] = 'iptables rules in {0} table {1} chain {2} family needs to be flushed'.format(
            name,
            table,
            family)
        return ret
    if not __salt__['iptables.flush'](table, kwargs['chain'], family):
        ret['changes'] = {'locale': name}
        ret['result'] = True
        ret['comment'] = 'Flush iptables rules in {0} table {1} chain {2} family'.format(
            table,
            kwargs['chain'],
            family
        )
        return ret
    else:
        ret['result'] = False
        ret['comment'] = 'Failed to flush iptables rules'
        return ret

Response: Flush iptables rules in a specific table and family


Instruction:
Can you tell what is the following Python 3 function doing
def mod_aggregate(low, chunks, running):
    '''
    The mod_aggregate function which looks up all rules in the available
    low chunks and merges them into a single rules ref in the present low data
    '''
    rules = []
    agg_enabled = [
            'append',
            'insert',
    ]
    if low.get('fun') not in agg_enabled:
        return low
    for chunk in chunks:
        tag = __utils__['state.gen_tag'](chunk)
        if tag in running:
            # Already ran the iptables state, skip aggregation
            continue
        if chunk.get('state') == 'iptables':
            if '__agg__' in chunk:
                continue
            # Check for the same function
            if chunk.get('fun') != low.get('fun'):
                continue

            if chunk not in rules:
                rules.append(chunk)
                chunk['__agg__'] = True

    if rules:
        if 'rules' in low:
            low['rules'].extend(rules)
        else:
            low['rules'] = rules
    return low

Response: The mod_aggregate function which looks up all rules in the available low chunks and merges them into a single rule ref in the present low data.


Instruction:
Can you write a function in Python 3 where it
monitors the memory usage of the minion and emit a beacon

Response:
def beacon(config):
    '''
    Monitor the memory usage of the minion

    Specify thresholds for percent used and only emit a beacon
    if it is exceeded.

    .. code-block:: yaml

        beacons:
          memusage:
            - percent: 63%
    '''
    ret = []

    _config = {}
    list(map(_config.update, config))

    _current_usage = psutil.virtual_memory()

    current_usage = _current_usage.percent
    monitor_usage = _config['percent']
    if '%' in monitor_usage:
        monitor_usage = re.sub('%', '', monitor_usage)
    monitor_usage = float(monitor_usage)
    if current_usage >= monitor_usage:
        ret.append({'memusage': current_usage})
    return ret


Instruction:
Can you write a function in Python 3 where it
formats the function name

Response:
def format_name(self):
        '''
        Format the function name
        '''
        if not hasattr(self.module, '__func_alias__'):
            # Resume normal sphinx.ext.autodoc operation
            return super(FunctionDocumenter, self).format_name()

        if not self.objpath:
            # Resume normal sphinx.ext.autodoc operation
            return super(FunctionDocumenter, self).format_name()

        if len(self.objpath) > 1:
            # Resume normal sphinx.ext.autodoc operation
            return super(FunctionDocumenter, self).format_name()

        # Use the salt func aliased name instead of the real name
        return self.module.__func_alias__.get(self.objpath[0], self.objpath[0])


Instruction:
Create a Python 3 function to
manage NTP servers and set the NTP servers to the servers specified in servers

Response:
def managed(name, servers=None):
    '''
    Manage NTP servers

    servers
        A list of NTP servers
    '''
    ret = {'name': name,
           'changes': {},
           'result': True,
           'comment': 'NTP servers already configured as specified'}

    if not _check_servers(servers):
        ret['result'] = False
        ret['comment'] = 'NTP servers must be a list of strings'

    before_servers = _get_servers()
    desired_servers = set(servers)

    if before_servers == desired_servers:
        return ret

    if __opts__['test']:
        ret['result'] = None
        ret['comment'] = ('NTP servers will be updated to: {0}'
                          .format(', '.join(sorted(desired_servers))))
        return ret

    __salt__['ntp.set_servers'](*desired_servers)
    after_servers = _get_servers()

    if after_servers == desired_servers:
        ret['comment'] = 'NTP servers updated'
        ret['changes'] = {'old': sorted(before_servers),
                          'new': sorted(after_servers)}
    else:
        ret['result'] = False
        ret['comment'] = 'Failed to update NTP servers'
        if before_servers != after_servers:
            ret['changes'] = {'old': sorted(before_servers),
                              'new': sorted(after_servers)}

    return ret


Instruction:
How would you implement a function in Python 3 that
returns the command to use based on the family

Response:
def _iptables_cmd(family='ipv4'):
    '''
    Return correct command based on the family, e.g. ipv4 or ipv6
    '''
    if family == 'ipv6':
        return salt.utils.path.which('ip6tables')
    else:
        return salt.utils.path.which('iptables')


Instruction:
Given the following Python 3 function, write the documentation
def _has_option(option, family='ipv4'):
    '''
    Return truth of whether iptables has `option`.  For example:

    .. code-block:: python

        _has_option('--wait')
        _has_option('--check', family='ipv6')
    '''
    cmd = '{0} --help'.format(_iptables_cmd(family))
    if option in __salt__['cmd.run'](cmd, output_loglevel='quiet'):
        return True
    return False

Response: Return truth of whether iptables has option.


Instruction:
Can you generate the documentation for the following Python 3 function
def _conf(family='ipv4'):
    '''
    Some distros have a specific location for config files
    '''
    if __grains__['os_family'] == 'RedHat':
        if family == 'ipv6':
            return '/etc/sysconfig/ip6tables'
        else:
            return '/etc/sysconfig/iptables'
    elif __grains__['os_family'] == 'Arch':
        if family == 'ipv6':
            return '/etc/iptables/ip6tables.rules'
        else:
            return '/etc/iptables/iptables.rules'
    elif __grains__['os_family'] == 'Debian':
        if family == 'ipv6':
            return '/etc/iptables/rules.v6'
        else:
            return '/etc/iptables/rules.v4'
    elif __grains__['os_family'] == 'Gentoo':
        if family == 'ipv6':
            return '/var/lib/ip6tables/rules-save'
        else:
            return '/var/lib/iptables/rules-save'
    elif __grains__['os_family'] == 'Suse':
        # SuSE does not seem to use separate files for IPv4 and IPv6
        return '/etc/sysconfig/scripts/SuSEfirewall2-custom'
    elif __grains__['os_family'] == 'Void':
        if family == 'ipv4':
            return '/etc/iptables/iptables.rules'
        else:
            return '/etc/iptables/ip6tables.rules'
    elif __grains__['os'] == 'Alpine':
        if family == 'ipv6':
            return '/etc/iptables/rules6-save'
        else:
            return '/etc/iptables/rules-save'
    else:
        raise SaltException('Saving iptables to file is not' +
                            ' supported on {0}.'.format(__grains__['os']) +
                            ' Please file an issue with SaltStack')

Response: Return the config file for the given family


Instruction:
Implement a Python 3 function for
returning string with save_filter regex entries removed.

Response:
def _regex_iptables_save(cmd_output, filters=None):
    '''
    Return string with `save_filter` regex entries removed.  For example:

    If `filters` is not provided, it will be pulled from minion config,
    minion grains, minion pillar, or master config. Default return value
    if no filters found is the original cmd_output string.

    .. code-block:: python

        _regex_iptables_save(cmd_output, ['-A DOCKER*'])
    '''
    # grab RE compiled filters from context for performance
    if 'iptables.save_filters' not in __context__:
        __context__['iptables.save_filters'] = []
        for pattern in filters or _conf_save_filters():
            try:
                __context__['iptables.save_filters']\
                    .append(re.compile(pattern))
            except re.error as e:
                log.warning('Skipping regex rule: \'%s\': %s',
                            pattern, e)
                continue

    if __context__['iptables.save_filters']:
        # line by line get rid of any regex matches
        _filtered_cmd_output = \
            [line for line in cmd_output.splitlines(True)
             if not any(reg.search(line) for reg
                        in __context__['iptables.save_filters'])]
        return ''.join(_filtered_cmd_output)

    return cmd_output


Instruction:
Can you tell what is the following Python 3 function doing
def version(family='ipv4'):
    '''
    Return version from iptables --version

    CLI Example:

    .. code-block:: bash

        salt '*' iptables.version

        IPv6:
        salt '*' iptables.version family=ipv6
    '''
    cmd = '{0} --version' . format(_iptables_cmd(family))
    out = __salt__['cmd.run'](cmd).split()
    return out[1]

Response: Return version from iptables


Instruction:
Create a Python 3 function for
building a well - formatted iptables rule.

Response:
def build_rule(table='filter', chain=None, command=None, position='', full=None, family='ipv4',
               **kwargs):
    '''
    Build a well-formatted iptables rule based on kwargs. A `table` and `chain`
    are not required, unless `full` is True.

    If `full` is `True`, then `table`, `chain` and `command` are required.
    `command` may be specified as either a short option ('I') or a long option
    (`--insert`). This will return the iptables command, exactly as it would
    be used from the command line.

    If a position is required (as with `-I` or `-D`), it may be specified as
    `position`. This will only be useful if `full` is True.

    If `state` is passed, it will be ignored, use `connstate`.
    If `connstate` is passed in, it will automatically be changed to `state`.

    To pass in jump options that doesn't take arguments, pass in an empty
    string.

    .. note::

        Whereas iptables will accept ``-p``, ``--proto[c[o[l]]]`` as synonyms
        of ``--protocol``, if ``--proto`` appears in an iptables command after
        the appearance of ``-m policy``, it is interpreted as the ``--proto``
        option of the policy extension (see the iptables-extensions(8) man
        page).

    CLI Examples:

    .. code-block:: bash

        salt '*' iptables.build_rule match=state \\
            connstate=RELATED,ESTABLISHED jump=ACCEPT

        salt '*' iptables.build_rule filter INPUT command=I position=3 \\
            full=True match=state connstate=RELATED,ESTABLISHED jump=ACCEPT

        salt '*' iptables.build_rule filter INPUT command=A \\
            full=True match=state connstate=RELATED,ESTABLISHED \\
            source='127.0.0.1' jump=ACCEPT

        .. Invert Rules
        salt '*' iptables.build_rule filter INPUT command=A \\
            full=True match=state connstate=RELATED,ESTABLISHED \\
            source='!127.0.0.1' jump=ACCEPT

        salt '*' iptables.build_rule filter INPUT command=A \\
            full=True match=state connstate=RELATED,ESTABLISHED \\
            destination='not 127.0.0.1' jump=ACCEPT

        IPv6:
        salt '*' iptables.build_rule match=state \\
            connstate=RELATED,ESTABLISHED jump=ACCEPT \\
            family=ipv6
        salt '*' iptables.build_rule filter INPUT command=I position=3 \\
            full=True match=state connstate=RELATED,ESTABLISHED jump=ACCEPT \\
            family=ipv6
    '''
    if 'target' in kwargs:
        kwargs['jump'] = kwargs.pop('target')

    # Ignore name and state for this function
    kwargs.pop('name', None)
    kwargs.pop('state', None)

    for ignore in list(_STATE_INTERNAL_KEYWORDS) + ['chain', 'save', 'table']:
        if ignore in kwargs:
            del kwargs[ignore]

    rule = []
    protocol = False
    bang_not_pat = re.compile(r'(!|not)\s?')

    def maybe_add_negation(arg):
        '''
        Will check if the defined argument is intended to be negated,
        (i.e. prefixed with '!' or 'not'), and add a '! ' to the rule.

        The prefix will be removed from the value in the kwargs dict.
        '''
        value = str(kwargs[arg])
        if value.startswith('!') or value.startswith('not'):
            kwargs[arg] = re.sub(bang_not_pat, '', value)
            return '! '
        return ''

    if 'if' in kwargs:
        rule.append('{0}-i {1}'.format(maybe_add_negation('if'), kwargs['if']))
        del kwargs['if']

    if 'of' in kwargs:
        rule.append('{0}-o {1}'.format(maybe_add_negation('of'), kwargs['of']))
        del kwargs['of']

    if 'proto' in kwargs and kwargs.get('match') != 'policy':
        kwargs['protocol'] = kwargs['proto']
        del kwargs['proto']
        # Handle the case 'proto' in kwargs and kwargs.get('match') == 'policy' below
    if 'protocol' in kwargs:
        if not protocol:
            rule.append('{0}-p {1}'.format(maybe_add_negation('protocol'), kwargs['protocol']))
            protocol = True
        del kwargs['protocol']

    if 'match' in kwargs:
        match_value = kwargs['match']
        if not isinstance(match_value, list):
            match_value = match_value.split(',')
        for match in match_value:
            rule.append('-m {0}'.format(match))
            if 'name_' in kwargs and match.strip() in ('pknock', 'quota2', 'recent'):
                rule.append('--name {0}'.format(kwargs['name_']))
                del kwargs['name_']
        if 'proto' in kwargs and kwargs.get('match') == 'policy':
            rule.append('{0}--proto {1}'.format(maybe_add_negation('proto'), kwargs['proto']))
            del kwargs['proto']
        del kwargs['match']

    if 'match-set' in kwargs:
        if isinstance(kwargs['match-set'], six.string_types):
            kwargs['match-set'] = [kwargs['match-set']]
        for match_set in kwargs['match-set']:
            negative_match_set = ''
            if match_set.startswith('!') or match_set.startswith('not'):
                negative_match_set = '! '
                match_set = re.sub(bang_not_pat, '', match_set)
            rule.append('-m set {0}--match-set {1}'.format(negative_match_set, match_set))
        del kwargs['match-set']

    if 'connstate' in kwargs:
        if '-m state' not in rule:
            rule.append('-m state')

        rule.append('{0}--state {1}'.format(maybe_add_negation('connstate'), kwargs['connstate']))

        del kwargs['connstate']

    if 'dport' in kwargs:
        rule.append('{0}--dport {1}'.format(maybe_add_negation('dport'), kwargs['dport']))
        del kwargs['dport']

    if 'sport' in kwargs:
        rule.append('{0}--sport {1}'.format(maybe_add_negation('sport'), kwargs['sport']))
        del kwargs['sport']

    for multiport_arg in ('dports', 'sports'):
        if multiport_arg in kwargs:
            if '-m multiport' not in rule:
                rule.append('-m multiport')
                if not protocol:
                    return 'Error: protocol must be specified'

            mp_value = kwargs[multiport_arg]
            if isinstance(mp_value, list):
                if any(i for i in mp_value if str(i).startswith('!') or str(i).startswith('not')):
                    mp_value = [re.sub(bang_not_pat, '', str(item)) for item in mp_value]
                    rule.append('!')
                dports = ','.join(str(i) for i in mp_value)
            else:
                if str(mp_value).startswith('!') or str(mp_value).startswith('not'):
                    dports = re.sub(bang_not_pat, '', mp_value)
                    rule.append('!')
                else:
                    dports = mp_value

            rule.append('--{0} {1}'.format(multiport_arg, dports))
            del kwargs[multiport_arg]

    if 'comment' in kwargs:
        if '-m comment' not in rule:
            rule.append('-m comment')

        rule.append('--comment "{0}"'.format(kwargs['comment']))
        del kwargs['comment']

    # --set in ipset is deprecated, works but returns error.
    # rewrite to --match-set if not empty, otherwise treat as recent option
    if 'set' in kwargs and kwargs['set']:
        rule.append('{0}--match-set {1}'.format(maybe_add_negation('set'), kwargs['set']))
        del kwargs['set']

    # Jumps should appear last, except for any arguments that are passed to
    # jumps, which of course need to follow.
    after_jump = []
    # All jump arguments as extracted from man iptables-extensions, man iptables,
    # man xtables-addons and http://www.iptables.info/en/iptables-targets-and-jumps.html
    after_jump_arguments = (
        'j',  # j and jump needs to be first
        'jump',

        # IPTABLES
        'add-set',
        'and-mark',
        'and-tos',
        'checksum-fill',
        'clamp-mss-to-pmtu',
        'clustermac',
        'ctevents',
        'ctmask',
        'del-set',
        'ecn-tcp-remove',
        'exist',
        'expevents',
        'gateway',
        'hash-init',
        'hashmode',
        'helper',
        'label',
        'local-node',
        'log-ip-options',
        'log-level',
        'log-prefix',
        'log-tcp-options',
        'log-tcp-sequence',
        'log-uid',
        'mask',
        'new',
        'nfmask',
        'nflog-group',
        'nflog-prefix',
        'nflog-range',
        'nflog-threshold',
        'nodst',
        'notrack',
        'on-ip',
        'on-port',
        'or-mark',
        'or-tos',
        'persistent',
        'queue-balance',
        'queue-bypass',
        'queue-num',
        'random',
        'rateest-ewmalog',
        'rateest-interval',
        'rateest-name',
        'reject-with',
        'restore',
        'restore-mark',
        #'save',  # no arg, problematic name: How do we avoid collision with this?
        'save-mark',
        'selctx',
        'set-class',
        'set-dscp',
        'set-dscp-class',
        'set-mark',
        'set-mss',
        'set-tos',
        'set-xmark',
        'strip-options',
        'timeout',
        'to',
        'to-destination',
        'to-ports',
        'to-source',
        'total-nodes',
        'tproxy-mark',
        'ttl-dec',
        'ttl-inc',
        'ttl-set',
        'type',
        'ulog-cprange',
        'ulog-nlgroup',
        'ulog-prefix',
        'ulog-qthreshold',
        'xor-mark',
        'xor-tos',
        'zone',

        # IPTABLES-EXTENSIONS
        'dst-pfx',
        'hl-dec',
        'hl-inc',
        'hl-set',
        'hmark-dport-mask',
        'hmark-dst-prefix',
        'hmark-mod',
        'hmark-offset',
        'hmark-proto-mask',
        'hmark-rnd',
        'hmark-spi-mask',
        'hmark-sport-mask',
        'hmark-src-prefix',
        'hmark-tuple',
        'led-always-blink',
        'led-delay',
        'led-trigger-id',
        'queue-cpu-fanout',
        'src-pfx',

        # WEB
        'to-port',

        # XTABLES
        'addr',
        'and-mask',
        'delude',
        'honeypot',
        'or-mask',
        'prefix',
        'reset',
        'reuse',
        'set-mac',
        'shift',
        'static',
        'tarpit',
        'tname',
        'ttl',
    )
    for after_jump_argument in after_jump_arguments:
        if after_jump_argument in kwargs:
            value = kwargs[after_jump_argument]
            if value in (None, ''):  # options without arguments
                after_jump.append('--{0}'.format(after_jump_argument))
            elif any(ws_char in str(value) for ws_char in string.whitespace):
                after_jump.append('--{0} "{1}"'.format(after_jump_argument, value))
            else:
                after_jump.append('--{0} {1}'.format(after_jump_argument, value))
            del kwargs[after_jump_argument]

    for key in kwargs:
        negation = maybe_add_negation(key)
        # don't use .items() since maybe_add_negation removes the prefix from
        # the value in the kwargs, thus we need to fetch it after that has run
        value = kwargs[key]
        flag = '-' if len(key) == 1 else '--'
        value = '' if value in (None, '') else ' {0}'.format(value)
        rule.append('{0}{1}{2}{3}'.format(negation, flag, key, value))

    rule += after_jump

    if full:
        if not table:
            return 'Error: Table needs to be specified'
        if not chain:
            return 'Error: Chain needs to be specified'
        if not command:
            return 'Error: Command needs to be specified'

        if command in 'ACDIRLSFZNXPE':
            flag = '-'
        else:
            flag = '--'

        wait = '--wait' if _has_option('--wait', family) else ''

        return '{0} {1} -t {2} {3}{4} {5} {6} {7}'.format(_iptables_cmd(family),
               wait, table, flag, command, chain, position, ' '.join(rule))

    return ' '.join(rule)


Instruction:
Can you tell what is the following Python 3 function doing
def get_saved_policy(table='filter', chain=None, conf_file=None, family='ipv4'):
    '''
    Return the current policy for the specified table/chain

    CLI Examples:

    .. code-block:: bash

        salt '*' iptables.get_saved_policy filter INPUT
        salt '*' iptables.get_saved_policy filter INPUT \\
            conf_file=/etc/iptables.saved

        IPv6:
        salt '*' iptables.get_saved_policy filter INPUT family=ipv6
        salt '*' iptables.get_saved_policy filter INPUT \\
            conf_file=/etc/iptables.saved family=ipv6

    '''
    if not chain:
        return 'Error: Chain needs to be specified'

    rules = _parse_conf(conf_file, family=family)
    try:
        return rules[table][chain]['policy']
    except KeyError:
        return None

Response: Get the current policy for the specified table and chain


Instruction:
Here you have a function in Python 3, explain what it does
def get_policy(table='filter', chain=None, family='ipv4'):
    '''
    Return the current policy for the specified table/chain

    CLI Example:

    .. code-block:: bash

        salt '*' iptables.get_policy filter INPUT

        IPv6:
        salt '*' iptables.get_policy filter INPUT family=ipv6
    '''
    if not chain:
        return 'Error: Chain needs to be specified'

    rules = _parse_conf(in_mem=True, family=family)
    try:
        return rules[table][chain]['policy']
    except KeyError:
        return None

Response: Get the current policy for the specified table chain


Instruction:
Make a summary of the following Python 3 code
def set_policy(table='filter', chain=None, policy=None, family='ipv4'):
    '''
    Set the current policy for the specified table/chain

    CLI Example:

    .. code-block:: bash

        salt '*' iptables.set_policy filter INPUT ACCEPT

        IPv6:
        salt '*' iptables.set_policy filter INPUT ACCEPT family=ipv6
    '''
    if not chain:
        return 'Error: Chain needs to be specified'
    if not policy:
        return 'Error: Policy needs to be specified'

    wait = '--wait' if _has_option('--wait', family) else ''
    cmd = '{0} {1} -t {2} -P {3} {4}'.format(
            _iptables_cmd(family), wait, table, chain, policy)
    out = __salt__['cmd.run'](cmd)
    return out

Response: Set the current policy for the specified table chain and family


Instruction:
Can you tell what is the following Python 3 function doing
def save(filename=None, family='ipv4'):
    '''
    Save the current in-memory rules to disk

    CLI Example:

    .. code-block:: bash

        salt '*' iptables.save /etc/sysconfig/iptables

        IPv6:
        salt '*' iptables.save /etc/sysconfig/iptables family=ipv6
    '''
    if _conf() and not filename:
        filename = _conf(family)

    log.debug('Saving rules to %s', filename)

    parent_dir = os.path.dirname(filename)
    if not os.path.isdir(parent_dir):
        os.makedirs(parent_dir)
    cmd = '{0}-save'.format(_iptables_cmd(family))
    ipt = __salt__['cmd.run'](cmd)

    # regex out the output if configured with filters
    if _conf_save_filters():
        ipt = _regex_iptables_save(ipt)

    out = __salt__['file.write'](filename, ipt)
    return out

Response: Save the current in - memory rules to disk


Instruction:
Write a Python 3 function for
checking for the existence of a rule in a table and chain

Response:
def check(table='filter', chain=None, rule=None, family='ipv4'):
    '''
    Check for the existence of a rule in the table and chain

    This function accepts a rule in a standard iptables command format,
        starting with the chain. Trying to force users to adapt to a new
        method of creating rules would be irritating at best, and we
        already have a parser that can handle it.

    CLI Example:

    .. code-block:: bash

        salt '*' iptables.check filter INPUT \\
            rule='-m state --state RELATED,ESTABLISHED -j ACCEPT'

        IPv6:
        salt '*' iptables.check filter INPUT \\
            rule='-m state --state RELATED,ESTABLISHED -j ACCEPT' \\
            family=ipv6
    '''
    if not chain:
        return 'Error: Chain needs to be specified'
    if not rule:
        return 'Error: Rule needs to be specified'
    ipt_cmd = _iptables_cmd(family)

    if _has_option('--check', family):
        cmd = '{0} -t {1} -C {2} {3}'.format(ipt_cmd, table, chain, rule)
        out = __salt__['cmd.run'](cmd, output_loglevel='quiet')
    else:
        _chain_name = hex(uuid.getnode())

        # Create temporary table
        __salt__['cmd.run']('{0} -t {1} -N {2}'.format(ipt_cmd, table, _chain_name))
        __salt__['cmd.run']('{0} -t {1} -A {2} {3}'.format(ipt_cmd, table, _chain_name, rule))

        out = __salt__['cmd.run']('{0}-save'.format(ipt_cmd))

        # Clean up temporary table
        __salt__['cmd.run']('{0} -t {1} -F {2}'.format(ipt_cmd, table, _chain_name))
        __salt__['cmd.run']('{0} -t {1} -X {2}'.format(ipt_cmd, table, _chain_name))

        for i in out.splitlines():
            if i.startswith('-A {0}'.format(_chain_name)):
                if i.replace(_chain_name, chain) in out.splitlines():
                    return True

        return False

    if not out:
        return True
    return out


Instruction:
Write a Python 3 function for
checking if the existence of a chain in a table

Response:
def check_chain(table='filter', chain=None, family='ipv4'):
    '''
    .. versionadded:: 2014.1.0

    Check for the existence of a chain in the table

    CLI Example:

    .. code-block:: bash

        salt '*' iptables.check_chain filter INPUT

        IPv6:
        salt '*' iptables.check_chain filter INPUT family=ipv6
    '''

    if not chain:
        return 'Error: Chain needs to be specified'

    cmd = '{0}-save -t {1}'.format(_iptables_cmd(family), table)
    out = __salt__['cmd.run'](cmd).find(':{0} '.format(chain))

    if out != -1:
        out = True
    else:
        out = False

    return out


Instruction:
Here you have a function in Python 3, explain what it does
def new_chain(table='filter', chain=None, family='ipv4'):
    '''
    .. versionadded:: 2014.1.0

    Create new custom chain to the specified table.

    CLI Example:

    .. code-block:: bash

        salt '*' iptables.new_chain filter CUSTOM_CHAIN

        IPv6:
        salt '*' iptables.new_chain filter CUSTOM_CHAIN family=ipv6
    '''

    if not chain:
        return 'Error: Chain needs to be specified'

    wait = '--wait' if _has_option('--wait', family) else ''
    cmd = '{0} {1} -t {2} -N {3}'.format(
            _iptables_cmd(family), wait, table, chain)
    out = __salt__['cmd.run'](cmd)

    if not out:
        out = True
    return out

Response: Create a new custom chain to the specified table.


Instruction:
Write a Python 3 function for
appending a rule to a table in a chain.

Response:
def append(table='filter', chain=None, rule=None, family='ipv4'):
    '''
    Append a rule to the specified table/chain.

    This function accepts a rule in a standard iptables command format,
        starting with the chain. Trying to force users to adapt to a new
        method of creating rules would be irritating at best, and we
        already have a parser that can handle it.

    CLI Example:

    .. code-block:: bash

        salt '*' iptables.append filter INPUT \\
            rule='-m state --state RELATED,ESTABLISHED -j ACCEPT'

        IPv6:
        salt '*' iptables.append filter INPUT \\
            rule='-m state --state RELATED,ESTABLISHED -j ACCEPT' \\
            family=ipv6
    '''
    if not chain:
        return 'Error: Chain needs to be specified'
    if not rule:
        return 'Error: Rule needs to be specified'

    wait = '--wait' if _has_option('--wait', family) else ''
    returnCheck = check(table, chain, rule, family)
    if isinstance(returnCheck, bool) and returnCheck:
        return False
    cmd = '{0} {1} -t {2} -A {3} {4}'.format(
            _iptables_cmd(family), wait, table, chain, rule)
    out = __salt__['cmd.run'](cmd)
    return not out


Instruction:
Can you generate the documentation for the following Python 3 function
def insert(table='filter', chain=None, position=None, rule=None, family='ipv4'):
    '''
    Insert a rule into the specified table/chain, at the specified position.

    This function accepts a rule in a standard iptables command format,
        starting with the chain. Trying to force users to adapt to a new
        method of creating rules would be irritating at best, and we
        already have a parser that can handle it.

    If the position specified is a negative number, then the insert will be
        performed counting from the end of the list. For instance, a position
        of -1 will insert the rule as the second to last rule. To insert a rule
        in the last position, use the append function instead.

    CLI Examples:

    .. code-block:: bash

        salt '*' iptables.insert filter INPUT position=3 \\
            rule='-m state --state RELATED,ESTABLISHED -j ACCEPT'

        IPv6:
        salt '*' iptables.insert filter INPUT position=3 \\
            rule='-m state --state RELATED,ESTABLISHED -j ACCEPT' \\
            family=ipv6
    '''
    if not chain:
        return 'Error: Chain needs to be specified'
    if not position:
        return 'Error: Position needs to be specified or use append (-A)'
    if not rule:
        return 'Error: Rule needs to be specified'

    if position < 0:
        rules = get_rules(family=family)
        size = len(rules[table][chain]['rules'])
        position = (size + position) + 1
        if position is 0:
            position = 1

    wait = '--wait' if _has_option('--wait', family) else ''
    returnCheck = check(table, chain, rule, family)
    if isinstance(returnCheck, bool) and returnCheck:
        return False
    cmd = '{0} {1} -t {2} -I {3} {4} {5}'.format(
            _iptables_cmd(family), wait, table, chain, position, rule)
    out = __salt__['cmd.run'](cmd)
    return out

Response: Insert a rule into the specified table or chain at the specified position.


Instruction:
Implement a Python 3 function for
deleting a rule from the specified table chain and position.

Response:
def delete(table, chain=None, position=None, rule=None, family='ipv4'):
    '''
    Delete a rule from the specified table/chain, specifying either the rule
        in its entirety, or the rule's position in the chain.

    This function accepts a rule in a standard iptables command format,
        starting with the chain. Trying to force users to adapt to a new
        method of creating rules would be irritating at best, and we
        already have a parser that can handle it.

    CLI Examples:

    .. code-block:: bash

        salt '*' iptables.delete filter INPUT position=3
        salt '*' iptables.delete filter INPUT \\
            rule='-m state --state RELATED,ESTABLISHED -j ACCEPT'

        IPv6:
        salt '*' iptables.delete filter INPUT position=3 family=ipv6
        salt '*' iptables.delete filter INPUT \\
            rule='-m state --state RELATED,ESTABLISHED -j ACCEPT' \\
            family=ipv6
    '''

    if position and rule:
        return 'Error: Only specify a position or a rule, not both'

    if position:
        rule = position

    wait = '--wait' if _has_option('--wait', family) else ''
    cmd = '{0} {1} -t {2} -D {3} {4}'.format(
            _iptables_cmd(family), wait, table, chain, rule)
    out = __salt__['cmd.run'](cmd)
    return out


Instruction:
Create a Python 3 function for
flushing all chains in the specified chain in the specified table.

Response:
def flush(table='filter', chain='', family='ipv4'):
    '''
    Flush the chain in the specified table, flush all chains in the specified
    table if not specified chain.

    CLI Example:

    .. code-block:: bash

        salt '*' iptables.flush filter INPUT

        IPv6:
        salt '*' iptables.flush filter INPUT family=ipv6
    '''

    wait = '--wait' if _has_option('--wait', family) else ''
    cmd = '{0} {1} -t {2} -F {3}'.format(_iptables_cmd(family), wait, table, chain)
    out = __salt__['cmd.run'](cmd)
    return out


Instruction:
Write a Python 3 script to
parse the configuration file and return a dict of the rules and table names.

Response:
def _parse_conf(conf_file=None, in_mem=False, family='ipv4'):
    '''
    If a file is not passed in, and the correct one for this OS is not
    detected, return False
    '''
    if _conf() and not conf_file and not in_mem:
        conf_file = _conf(family)

    rules = ''
    if conf_file:
        with salt.utils.files.fopen(conf_file, 'r') as ifile:
            rules = ifile.read()
    elif in_mem:
        cmd = '{0}-save' . format(_iptables_cmd(family))
        rules = __salt__['cmd.run'](cmd)
    else:
        raise SaltException('A file was not found to parse')

    ret = {}
    table = ''
    parser = _parser()
    for line in rules.splitlines():
        line = salt.utils.stringutils.to_unicode(line)
        if line.startswith('*'):
            table = line.replace('*', '')
            ret[table] = {}
        elif line.startswith(':'):
            comps = line.split()
            chain = comps[0].replace(':', '')
            ret[table][chain] = {}
            ret[table][chain]['policy'] = comps[1]
            counters = comps[2].replace('[', '').replace(']', '')
            (pcount, bcount) = counters.split(':')
            ret[table][chain]['packet count'] = pcount
            ret[table][chain]['byte count'] = bcount
            ret[table][chain]['rules'] = []
            ret[table][chain]['rules_comment'] = {}
        elif line.startswith('-A'):
            args = salt.utils.args.shlex_split(line)
            index = 0
            while index + 1 < len(args):
                swap = args[index] == '!' and args[index + 1].startswith('-')
                if swap:
                    args[index], args[index + 1] = args[index + 1], args[index]
                if args[index].startswith('-'):
                    index += 1
                    if args[index].startswith('-') or (args[index] == '!' and
                                                       not swap):
                        args.insert(index, '')
                    else:
                        while (index + 1 < len(args) and
                               args[index + 1] != '!' and
                               not args[index + 1].startswith('-')):
                            args[index] += ' {0}'.format(args.pop(index + 1))
                index += 1
            if args[-1].startswith('-'):
                args.append('')
            parsed_args = []
            opts, _ = parser.parse_known_args(args)
            parsed_args = vars(opts)
            ret_args = {}
            chain = parsed_args['append']
            for arg in parsed_args:
                if parsed_args[arg] and arg is not 'append':
                    ret_args[arg] = parsed_args[arg]
            if parsed_args['comment'] is not None:
                comment = parsed_args['comment'][0].strip('"')
                ret[table][chain[0]]['rules_comment'][comment] = ret_args
            ret[table][chain[0]]['rules'].append(ret_args)
    return ret