Like cap_add, cap_drop, etc., this option can be specified multiple times,
    and each time can be a port number or port range. Ultimately, the API
    expects a list, but elements in the list are ints when the port is TCP, and
    a tuple (port_num, 'udp') when the port is UDP.

def ports(val, **kwargs):  # pylint: disable=unused-argument
    '''
    Like cap_add, cap_drop, etc., this option can be specified multiple times,
    and each time can be a port number or port range. Ultimately, the API
    expects a list, but elements in the list are ints when the port is TCP, and
    a tuple (port_num, 'udp') when the port is UDP.
    '''
    if not isinstance(val, list):
        try:
            val = helpers.split(val)
        except AttributeError:
            if isinstance(val, six.integer_types):
                val = [val]
            else:
                raise SaltInvocationError(
                    '\'{0}\' is not a valid port definition'.format(val)
                )
    new_ports = set()
    for item in val:
        if isinstance(item, six.integer_types):
            new_ports.add(item)
            continue
        try:
            item, _, proto = item.partition('/')
        except AttributeError:
            raise SaltInvocationError(
                '\'{0}\' is not a valid port definition'.format(item)
            )
        try:
            range_start, range_end = \
                helpers.get_port_range(item)
        except ValueError as exc:
            # Using __str__() to avoid deprecation warning for using
            # the "message" attribute of the ValueError.
            raise SaltInvocationError(exc.__str__())
        new_ports.update([helpers.get_port_def(x, proto)
                          for x in range(range_start, range_end + 1)])
    return list(new_ports)