Ensure ports are open for a protocol, in a direction.
    e.g. - proto='tcp', direction='in' would set the values
    for TCP_IN in the csf.conf file.

    ports
        A list of ports that should be open.

    proto
        The protocol. May be one of 'tcp', 'udp',
        'tcp6', or 'udp6'.

    direction
        Choose 'in', 'out', or both to indicate the port
        should be opened for inbound traffic, outbound
        traffic, or both.

def ports_open(name, ports, proto='tcp', direction='in'):
    '''
    Ensure ports are open for a protocol, in a direction.
    e.g. - proto='tcp', direction='in' would set the values
    for TCP_IN in the csf.conf file.

    ports
        A list of ports that should be open.

    proto
        The protocol. May be one of 'tcp', 'udp',
        'tcp6', or 'udp6'.

    direction
        Choose 'in', 'out', or both to indicate the port
        should be opened for inbound traffic, outbound
        traffic, or both.
    '''

    ports = list(six.moves.map(six.text_type, ports))
    diff = False
    ret = {'name': ','.join(ports),
           'changes': {},
           'result': True,
           'comment': 'Ports open.'}

    current_ports = __salt__['csf.get_ports'](proto=proto, direction=direction)
    direction = direction.upper()
    directions = __salt__['csf.build_directions'](direction)
    for direction in directions:
        log.trace('current_ports[direction]: %s', current_ports[direction])
        log.trace('ports: %s', ports)
        if current_ports[direction] != ports:
            diff = True
    if diff:
        result = __salt__['csf.allow_ports'](ports, proto=proto, direction=direction)
        ret['changes']['Ports'] = 'Changed'
        ret['comment'] = result
    return ret