def Add(self, ports, kind, allow_privileged=False, prohibited_host_ports=()):
    """Load port configurations and adds them to an internal dict.

    Args:
      ports: A list of strings or a CSV representing port forwarding.
      kind: what kind of port configuration this is, only used for error
        reporting.
      allow_privileged: Allow to bind to ports under 1024.
      prohibited_host_ports: A list of ports that are used outside of
        the container and may not be mapped to this port manager.

    Raises:
      InconsistentPortConfigurationError: If a port is configured to do
        two different conflicting things.
      IllegalPortConfigurationError: If the port is out of range or
        is not a number.

    Returns:
      A dictionary with forwarding rules as external_port => local_port.
    """
    if not ports:
      # Obviously nothing to do.
      return

    if isinstance(ports, int):
      ports = str(ports)
    if isinstance(ports, basestring):
      # split a csv
      ports = [port.strip() for port in ports.split(',')]
    port_translations = {'tcp': {}, 'udp': {}}
    for port in ports:
      try:
        if '/' in port:
          tmp = port.split('/')
          if len(tmp) != 2 or not re.match(PROTOCOL_RE, tmp[1].lower()):
            raise IllegalPortConfigurationError(
                '%r was not recognized as a valid port configuration.' % port)
          port = tmp[0]
          protocol = tmp[1].lower()
        else:
          protocol = 'tcp'  # This is the default.
        if ':' in port:
          host_port, docker_port = (int(p.strip()) for p in port.split(':'))
          port_translations[protocol][host_port] = docker_port
        else:
          host_port = int(port)
          docker_port = host_port
          port_translations[protocol][host_port] = host_port
        if host_port in prohibited_host_ports:
          raise InconsistentPortConfigurationError(
              'Configuration conflict, port %d cannot be used by the '
              'application.' % host_port)
        if (host_port in self.used_host_ports and
            self.used_host_ports[host_port] != docker_port):
          raise InconsistentPortConfigurationError(
              'Configuration conflict, port %d configured to forward '
              'differently.' % host_port)
        self.used_host_ports[host_port] = docker_port
        if (host_port < 1 or host_port > 65535 or
            docker_port < 1 or docker_port > 65535):
          raise IllegalPortConfigurationError(
              'Failed to load %s port configuration: invalid port %s'
              % (kind, port))
        if docker_port < 1024 and not allow_privileged:
          raise IllegalPortConfigurationError(
              'Cannot listen on port %d as it is priviliged, use a forwarding '
              'port.' % docker_port)
        if docker_port in RESERVED_DOCKER_PORTS:
          raise IllegalPortConfigurationError(
              'Cannot use port %d as it is reserved on the VM.'
              % docker_port)
        if host_port in RESERVED_HOST_PORTS:
          raise IllegalPortConfigurationError(
              'Cannot use port %d as it is reserved on the VM.'
              % host_port)
      except __HOLE__ as e:
        logging.exception('Bad port description')
        raise IllegalPortConfigurationError(
            'Failed to load %s port configuration: "%s" error: "%s"'
            % (kind, port, e))
    # At this point we know they are not destructive.
    self._port_mappings['tcp'].update(port_translations['tcp'])
    self._port_mappings['udp'].update(port_translations['udp'])
    # TODO: This is a bit of a hack.
    self._port_names[kind] = port_translations
    return port_translations
dataset/ETHPy150Open GoogleCloudPlatform/python-compat-runtime/appengine-compat/exported_appengine_sdk/google/appengine/client/services/port_manager.py/PortManager.Add