Example #1
0
    def ProcessCronNode(self, node):
        """Processes XML <cron> nodes into Cron objects.

    The following information is parsed out:
      description: Describing the purpose of the cron job.
      url: The location of the script.
      schedule: Written in groc; the schedule according to which the job is
        executed.
      timezone: The timezone that the schedule runs in.
      target: Which version of the app this applies to.

    Args:
      node: <cron> XML node in cron.xml.
    """
        tag = xml_parser_utils.GetTag(node)
        if tag != 'cron':
            self.errors.append('Unrecognized node: <%s>' % tag)
            return

        cron = Cron()
        cron.url = xml_parser_utils.GetChildNodeText(node, 'url')
        cron.timezone = xml_parser_utils.GetChildNodeText(node, 'timezone')
        cron.target = xml_parser_utils.GetChildNodeText(node, 'target')
        cron.description = xml_parser_utils.GetChildNodeText(
            node, 'description')
        cron.schedule = xml_parser_utils.GetChildNodeText(node, 'schedule')

        validation_error = self._ValidateCronEntry(cron)
        if validation_error:
            self.errors.append(validation_error)
        else:
            self.crons.append(cron)
    def ProcessBlacklistNode(self, node):
        """Processes XML <blacklist> nodes into BlacklistEntry objects.

    The following information is parsed out:
      subnet: The IP, in CIDR notation.
      description: (optional)
    If there are no errors, the data is loaded into a BlackListEntry object
    and added to a list. Upon error, a description of the error is added to
    a list and the method terminates.

    Args:
      node: <blacklist> XML node in dos.xml.
    """
        tag = xml_parser_utils.GetTag(node)
        if tag != 'blacklist':
            self.errors.append('Unrecognized node: <%s>' % tag)
            return

        entry = BlacklistEntry()
        entry.subnet = xml_parser_utils.GetChildNodeText(node, 'subnet')
        entry.description = xml_parser_utils.GetChildNodeText(
            node, 'description')

        validation = self._ValidateEntry(entry)
        if validation:
            self.errors.append(validation)
            return
        self.blacklist_entries.append(entry)
Example #3
0
 def ProcessBasicScalingNode(self, node):
     basic_scaling = BasicScaling()
     basic_scaling.max_instances = xml_parser_utils.GetChildNodeText(
         node, 'max-instances').strip()
     basic_scaling.idle_timeout = xml_parser_utils.GetChildNodeText(
         node, 'idle-timeout').strip()
     self.app_engine_web_xml.basic_scaling = basic_scaling
Example #4
0
    def ProcessDispatchNode(self, node):
        """Processes XML <dispatch> nodes into DispatchEntry objects.

    The following information is parsed out:
      url: The URL or URL pattern to route.
      module: The module to route it to.
    If there are no errors, the data is loaded into a DispatchEntry object
    and added to a list. Upon error, a description of the error is added to
    a list and the method terminates.

    Args:
      node: <dispatch> XML node in dos.xml.
    """
        tag = xml_parser_utils.GetTag(node)
        if tag != 'dispatch':
            self.errors.append('Unrecognized node: <%s>' % tag)
            return

        entry = DispatchEntry()
        entry.url = xml_parser_utils.GetChildNodeText(node, 'url')
        entry.module = xml_parser_utils.GetChildNodeText(node, 'module')

        validation = self._ValidateEntry(entry)
        if validation:
            self.errors.append(validation)
            return
        self.dispatch_entries.append(entry)
  def ProcessMimeMappingNode(self, node):
    extension = xml_parser_utils.GetChildNodeText(node, 'extension')
    mime_type = xml_parser_utils.GetChildNodeText(node, 'mime-type')

    if not extension:
      self.errors.append('<mime-type> without extension')
      return
    self.web_xml.mime_mappings[extension] = mime_type
    def ProcessBackendNode(self, node):
        """Processes XML nodes labeled 'backend' into a Backends object."""
        tag = xml_parser_utils.GetTag(node)
        if tag != 'backend':
            self.errors.append('Unrecognized node: <%s>' % tag)
            return

        backend = Backend()
        name = xml_parser_utils.GetAttribute(node, 'name')
        if not name:
            self.errors.append('All backends must have names')
            backend.name = '-'
        else:
            backend.name = name
        instance_class = xml_parser_utils.GetChildNodeText(node, 'class')
        if instance_class:
            backend.instance_class = instance_class
        instances = xml_parser_utils.GetChildNodeText(node, 'instances')
        if instances:
            try:
                backend.instances = int(instances)
            except ValueError:
                self.errors.append(
                    '<instances> must be an integer (bad value %s) in backend %s'
                    % (instances, backend.name))
        max_concurrent_requests = xml_parser_utils.GetChildNodeText(
            node, 'max-concurrent-requests')
        if max_concurrent_requests:
            try:
                backend.max_concurrent_requests = int(max_concurrent_requests)
            except ValueError:
                self.errors.append(
                    '<max-concurrent-requests> must be an integer '
                    '(bad value %s) in backend %s' %
                    (max_concurrent_requests, backend.name))

        options_node = xml_parser_utils.GetChild(node, 'options')
        if options_node is not None:
            for sub_node in options_node.getchildren():
                tag = xml_parser_utils.GetTag(sub_node)
                if tag not in ('fail-fast', 'dynamic', 'public'):
                    self.errors.append(
                        '<options> only supports values fail-fast, '
                        'dynamic, and public (bad value %s) in backend %s' %
                        (tag, backend.name))
                    continue
                tag = tag.replace('-', '')
                if xml_parser_utils.BooleanValue(sub_node.text):
                    backend.options.add(tag)
                else:
                    if tag in backend.options:
                        backend.options.remove(tag)

        self.backends.append(backend)
Example #7
0
 def ProcessAutomaticScalingNode(self, node):
     """Sets automatic scaling settings."""
     automatic_scaling = AutomaticScaling()
     automatic_scaling.min_pending_latency = xml_parser_utils.GetChildNodeText(
         node, 'min-pending-latency').strip()
     automatic_scaling.max_pending_latency = xml_parser_utils.GetChildNodeText(
         node, 'max-pending-latency').strip()
     automatic_scaling.min_idle_instances = xml_parser_utils.GetChildNodeText(
         node, 'min-idle-instances').strip()
     automatic_scaling.max_idle_instances = xml_parser_utils.GetChildNodeText(
         node, 'max-idle-instances').strip()
     self.app_engine_web_xml.automatic_scaling = automatic_scaling
Example #8
0
    def ProcessXml(self, xml_str):
        """Parses XML string and returns object representation of relevant info.

    Args:
      xml_str: The XML string.
    Returns:
      A QueueXml object containing information about task queue
      specifications from the XML.
    Raises:
      AppEngineConfigException: In case of malformed XML or illegal inputs.
    """

        try:
            self.errors = []
            xml_root = ElementTree.fromstring(xml_str)

            if xml_parser_utils.GetTag(xml_root) != 'queue-entries':
                raise AppEngineConfigException(
                    'Root tag must be <queue-entries>')

            self.queue_xml = QueueXml()
            self.queue_xml.queues = []
            self.queue_xml.total_storage_limit = xml_parser_utils.GetChildNodeText(
                xml_root, 'total-storage-limit')
            for child in xml_parser_utils.GetNodes(xml_root, 'queue'):
                self.ProcessQueueNode(child)

            if self.errors:
                raise AppEngineConfigException('\n'.join(self.errors))

            return self.queue_xml

        except ElementTree.ParseError as e:
            raise AppEngineConfigException('Bad input -- not valid XML: %s' %
                                           e)
Example #9
0
    def ProcessSecurityConstraintNode(self, node):
        """Pulls data from the security constraint node and adds to WebXml object.

    Args:
      node: An ElementTree Xml node that looks something like the following:

        <security-constraint>
          <web-resource-collection>
            <url-pattern>/profile/*</url-pattern>
          </web-resource-collection>
          <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
          </user-data-constraint>
        </security-constraint>
    """
        security_constraint = SecurityConstraint()
        resources_node = xml_parser_utils.GetChild(node,
                                                   'web-resource-collection')
        security_constraint.patterns = [
            xml_parser_utils.GetNodeText(sub_node) for sub_node in
            xml_parser_utils.GetNodes(resources_node, 'url-pattern')
        ]
        constraint = xml_parser_utils.GetChild(node, 'auth-constraint')
        if constraint is not None:
            role_name = xml_parser_utils.GetChildNodeText(
                constraint, 'role-name').lower()
            if role_name:
                if role_name not in ('none', '*', 'admin'):
                    self.errors.append(
                        'Bad value for <role-name> (%s), must be none, '
                        '*, or admin' % role_name)
                security_constraint.required_role = role_name

        user_constraint = xml_parser_utils.GetChild(node,
                                                    'user-data-constraint')
        if user_constraint is not None:
            guarantee = xml_parser_utils.GetChildNodeText(
                user_constraint, 'transport-guarantee').lower()
            if guarantee not in ('none', 'integral', 'confidential'):
                self.errors.append(
                    'Bad value for <transport-guarantee> (%s), must be'
                    ' none, integral, or confidential' % guarantee)
            security_constraint.transport_guarantee = guarantee

        self.web_xml.security_constraints.append(security_constraint)
Example #10
0
    def ProcessQueueNode(self, node):
        """Processes XML <queue> nodes into Queue objects.

    The following information is parsed out:
      name
      mode: can be either push or pull
      retry-parameters:
        task-retry-limit
    ---- push queues only ----
        task-age-limit
        min-backoff-seconds
        max-back-off-seconds
        max-doubling
      bucket-size
      max-concurrent-requests
      rate: how often tasks are processed on this queue.
      target: version of application on which tasks on this queue will be
        invoked.
    ---- pull queues only ----
      acl: access control list - lists user and writer email addresses.

    Args:
      node: Current <queue> XML node being processed.
    """

        name = xml_parser_utils.GetChildNodeText(node, 'name')
        if not name:
            self.errors.append('Must specify a name for each <queue> entry')
            return

        mode = xml_parser_utils.GetChildNodeText(node, 'mode', 'push')

        if mode not in ('push', 'pull'):
            self.errors.append(BAD_MODE_ERROR_MESSAGE % (mode, name))
            return
        if mode == 'pull':
            queue = PullQueue()
            queue.name = name
            self._ProcessPullQueueNode(node, queue)
        else:
            queue = PushQueue()
            queue.name = name
            self._ProcessPushQueueNode(node, queue)

        self.queue_xml.queues.append(queue)
Example #11
0
 def _ProcessPushQueueNode(self, node, queue):
     if xml_parser_utils.GetChild(node, 'acl') is not None:
         self.errors.append('The element <acl> is not defined for push '
                            "queues; bad <queue> entry with name '%s'" %
                            queue.name)
     for tag in PUSH_QUEUE_TAGS:
         field_name = tag.replace('-', '_')
         setattr(queue, field_name,
                 xml_parser_utils.GetChildNodeText(node, tag))
     self._ProcessRetryParametersNode(node, queue)
Example #12
0
def _ProcessRetryParametersNode(node, cron):
    """Converts <retry-parameters> in node to cron.retry_parameters."""

    retry_parameters_node = xml_parser_utils.GetChild(node, 'retry-parameters')
    if retry_parameters_node is None:
        cron.retry_parameters = None
        return

    retry_parameters = _RetryParameters()
    cron.retry_parameters = retry_parameters
    for tag in _RETRY_PARAMETER_TAGS:
        if xml_parser_utils.GetChild(retry_parameters_node, tag) is not None:
            setattr(
                retry_parameters, tag.replace('-', '_'),
                xml_parser_utils.GetChildNodeText(retry_parameters_node, tag))
Example #13
0
    def _ProcessRetryParametersNode(self, node, queue):
        """Pulls information out of <retry-parameters> node."""
        retry_parameters_node = xml_parser_utils.GetChild(
            node, 'retry-parameters')
        if retry_parameters_node is None:
            queue.retry_parameters = None
            return
        retry_parameters = RetryParameters()
        queue.retry_parameters = retry_parameters
        retry_parameters.task_retry_limit = xml_parser_utils.GetChildNodeText(
            retry_parameters_node, 'task-retry-limit')

        for tag in PUSH_QUEUE_RETRY_PARAMS:

            if xml_parser_utils.GetChild(retry_parameters_node,
                                         tag) is not None:
                if isinstance(queue, PullQueue):
                    self.errors.append(RETRY_PARAM_ERROR_MESSAGE %
                                       (tag, queue.name))
                else:
                    setattr(
                        retry_parameters, tag.replace('-', '_'),
                        xml_parser_utils.GetChildNodeText(
                            retry_parameters_node, tag))
  def ProcessErrorPageNode(self, node):
    """Process error page specifications.

    If one of the supplied error codes is 404, allow fall through to runtime.

    Args:
      node: An ElementTreeNode which looks something like the following.
        <error-page>
          <error-code>500</error-code>
          <location>/errors/servererror.jsp</location>
        </error-page>
    """

    error_code = xml_parser_utils.GetChildNodeText(node, 'error-code')
    if error_code == '404':
      self.web_xml.fall_through_to_runtime = True
Example #15
0
 def ProcessManualScalingNode(self, node):
     manual_scaling = ManualScaling()
     manual_scaling.instances = xml_parser_utils.GetChildNodeText(
         node, 'instances').strip()
     self.app_engine_web_xml.manual_scaling = manual_scaling
 def ProcessVpcAccessConnectorNode(self, node):
     """Sets vpc access connector settings."""
     vpc_access_connector = VpcAccessConnector()
     vpc_access_connector.name = xml_parser_utils.GetChildNodeText(
         node, 'name').strip()
     self.app_engine_web_xml.vpc_access_connector = vpc_access_connector