Add a new inbound or outbound rule to the firewall policy

    Args:

        name (str): The name of the rule. Must be unique and cannot be "all".
            Required.

        localport (int): The port the rule applies to. Must be a number between
            0 and 65535. Can be a range. Can specify multiple ports separated by
            commas. Required.

        protocol (Optional[str]): The protocol. Can be any of the following:

            - A number between 0 and 255
            - icmpv4
            - icmpv6
            - tcp
            - udp
            - any

        action (Optional[str]): The action the rule performs. Can be any of the
            following:

            - allow
            - block
            - bypass

        dir (Optional[str]): The direction. Can be ``in`` or ``out``.

        remoteip (Optional [str]): The remote IP. Can be any of the following:

            - any
            - localsubnet
            - dns
            - dhcp
            - wins
            - defaultgateway
            - Any valid IPv4 address (192.168.0.12)
            - Any valid IPv6 address (2002:9b3b:1a31:4:208:74ff:fe39:6c43)
            - Any valid subnet (192.168.1.0/24)
            - Any valid range of IP addresses (192.168.0.1-192.168.0.12)
            - A list of valid IP addresses

            Can be combinations of the above separated by commas.

            .. versionadded:: 2016.11.6

    Example:

    .. code-block:: yaml

        open_smb_port:
          win_firewall.add_rule:
            - name: SMB (445)
            - localport: 445
            - protocol: tcp
            - action: allow

def add_rule(name,
             localport,
             protocol='tcp',
             action='allow',
             dir='in',
             remoteip='any'):
    '''
    Add a new inbound or outbound rule to the firewall policy

    Args:

        name (str): The name of the rule. Must be unique and cannot be "all".
            Required.

        localport (int): The port the rule applies to. Must be a number between
            0 and 65535. Can be a range. Can specify multiple ports separated by
            commas. Required.

        protocol (Optional[str]): The protocol. Can be any of the following:

            - A number between 0 and 255
            - icmpv4
            - icmpv6
            - tcp
            - udp
            - any

        action (Optional[str]): The action the rule performs. Can be any of the
            following:

            - allow
            - block
            - bypass

        dir (Optional[str]): The direction. Can be ``in`` or ``out``.

        remoteip (Optional [str]): The remote IP. Can be any of the following:

            - any
            - localsubnet
            - dns
            - dhcp
            - wins
            - defaultgateway
            - Any valid IPv4 address (192.168.0.12)
            - Any valid IPv6 address (2002:9b3b:1a31:4:208:74ff:fe39:6c43)
            - Any valid subnet (192.168.1.0/24)
            - Any valid range of IP addresses (192.168.0.1-192.168.0.12)
            - A list of valid IP addresses

            Can be combinations of the above separated by commas.

            .. versionadded:: 2016.11.6

    Example:

    .. code-block:: yaml

        open_smb_port:
          win_firewall.add_rule:
            - name: SMB (445)
            - localport: 445
            - protocol: tcp
            - action: allow
    '''
    ret = {'name': name,
           'result': True,
           'changes': {},
           'comment': ''}

    # Check if rule exists
    if not __salt__['firewall.rule_exists'](name):
        ret['changes'] = {'new rule': name}
    else:
        ret['comment'] = 'A rule with that name already exists'
        return ret

    if __opts__['test']:
        ret['result'] = not ret['changes'] or None
        ret['comment'] = ret['changes']
        ret['changes'] = {}
        return ret

    # Add rule
    try:
        __salt__['firewall.add_rule'](
            name, localport, protocol, action, dir, remoteip)
    except CommandExecutionError:
        ret['comment'] = 'Could not add rule'

    return ret