Exemple #1
0
def Rewrite(expr):
    """Returns the server side rewrite of a --filter expression.

  Args:
    expr: A client side --filter expression.

  Raises:
    resource_exceptions.ExpressionSyntaxError: Expression syntax error.
    ValueError: Invalid expression operands.

  Returns:
    The server side rewrite of a --filter expression, None if the expression is
    completely client side.
  """

    # Rewrite the expression.
    rewrite = resource_filter.Compile(expr, backend=_Backend()).Rewrite()

    # Add a project id restriction.
    if rewrite:
        rewrite += ' AND '
    else:
        rewrite = ''
    rewrite += 'projectId={0}'.format(genomics_util.GetProjectId())

    return rewrite
def TransformFilter(r, expression):
  """Selects elements of r that match the filter expression.

  Args:
    r: A JSON-serializable object.
    expression: The filter expression to apply to r.

  Returns:
    The elements of r that match the filter expression.

  Example:
    x.filter("key:val") selects elements of r that have 'key' fields containing
    'val'.
  """

  # import loop
  from googlecloudsdk.core.resource import resource_filter  # pylint: disable=g-import-not-at-top

  if not r:
    return r
  select = resource_filter.Compile(expression).Evaluate
  if not resource_property.IsListLike(r):
    return r if select(r) else ''
  transformed = []
  for item in r:
    if select(item):
      transformed.append(item)
  return transformed
  def Rewrite(self, expression, defaults=None):
    """Returns (frontend_expression, backend_expression) for expression.

    There are 3 outcomes:
      (None, backend) -- only need to apply the backend expression
      (frontend, None) -- only need to apply the frontend expression
      (frontend, backend) -- must apply both frontend and backend expressions

    Args:
      expression: The expression string to rewrite.
      defaults: resource_projection_spec.ProjectionSpec defaults.

    Returns:
      Returns (frontend_expression, backend_expression) for expression.
    """
    if defaults and defaults.symbols:
      conditionals = defaults.symbols.get(
          resource_transform.GetTypeDataName('conditionals'))
      if hasattr(conditionals, 'flatten') and conditionals.flatten:
        # If --flatten flag is presented we cannot do serverside filtering.
        return expression, None
    self.partial_rewrite = False
    defaults = resource_projection_spec.ProjectionSpec(defaults=defaults)
    defaults.symbols = _BelieveMe()
    backend_expression = resource_filter.Compile(
        expression, backend=self, defaults=defaults).Rewrite()
    frontend_expression = expression if self.partial_rewrite else None
    if frontend_expression and frontend_expression.isspace():
      frontend_expression = None
    return frontend_expression, backend_expression
 def Run(self, args):
     if args.json_file:
         with open(args.json_file, 'r') as f:
             resources = json.load(f)
     else:
         resources = json.load(sys.stdin)
     # TODO(gsfowler): Drop this if when the --aggregate global flag lands.
     if args.aggregate:
         key = resource_lex.Lexer(args.aggregate).Key()
         resources = Aggregator(resources, key)
     # TODO(gsfowler): Return resources here when the --filter global flag lands.
     if not args.format:
         args.format = 'json'
     if not args.filter:
         return resources
     select = resource_filter.Compile(args.filter).Evaluate
     filtered_resources = []
     if resource_property.IsListLike(resources):
         for resource in resources:
             if select(resource):
                 filtered_resources.append(resource)
     elif select(resources):
         # treat non-iterable resources as a list of length 1
         filtered_resources.append(resources)
     return filtered_resources
  def __init__(self, expression, defaults):
    """Constructor.

    Args:
      expression: The resource filter expression string.
      defaults: The resource format and filter default projection.
    """
    self._match = resource_filter.Compile(
        expression, defaults=defaults).Evaluate
Exemple #6
0
    def _ParseKey(self):
        """Parses a key and optional attributes from the expression.

    The parsed key is appended to the ordered list of keys via _AddKey().
    Transform functions and key attributes are also handled here.

    Raises:
      ExpressionSyntaxError: The expression has a syntax error.
    """
        key, attribute = self._lex.KeyWithAttribute()
        if self._lex.IsCharacter('(', eoi_ok=True):
            add_transform = self._lex.Transform(key.pop(),
                                                self._projection.active)
        else:
            add_transform = None
        if (not self.__key_attributes_only
                and attribute) or (self.__key_attributes_only and attribute
                                   and not key):
            # When a key is repeated in the format expression, we want to duplicate
            # the attribute and add transfrom to the key, as the previous behaviour
            # was. However _AddKey is also processed for attribute only keys; in this
            # case, we want to reference the same attribute if the attribute is
            # referenced by its label.
            attribute = copy.copy(attribute)
        else:
            attribute = self._Attribute(self._projection.PROJECT)
        if not attribute.transform:
            attribute.transform = add_transform
        elif add_transform:
            # Compose the alias attribute.transform with add_transforms.
            attribute.transform._transforms.extend(add_transform._transforms)  # pylint: disable=protected-access
        self._lex.SkipSpace()
        if self._lex.IsCharacter(':'):
            self._ParseKeyAttributes(key, attribute)
        if attribute.transform and attribute.transform.conditional:
            # Parse and evaluate if() transform conditional expression,
            conditionals = self._projection.symbols.get(
                resource_transform.GetTypeDataName('conditionals'))

            def EvalGlobalRestriction(unused_obj, restriction, unused_pattern):
                return getattr(conditionals, restriction, None)

            defaults = resource_projection_spec.ProjectionSpec(
                symbols={
                    resource_projection_spec.GLOBAL_RESTRICTION_NAME:
                    EvalGlobalRestriction
                })
            if not resource_filter.Compile(
                    attribute.transform.conditional,
                    defaults=defaults).Evaluate(conditionals):
                return
        if attribute.label is None and not key and attribute.transform:
            attribute.label = self._AngrySnakeCase(
                [attribute.transform.name] +
                attribute.transform._transforms[0].args)  # pylint: disable=protected-access
        self._AddKey(key, attribute)
Exemple #7
0
    def __init__(self, expression, defaults):
        """Constructor.

    Args:
      expression: The resource filter expression string.
      defaults: The resource format and filter default projection.
    """
        self._compiled_expression = resource_filter.Compile(expression,
                                                            defaults=defaults)
        self._missing_keys = resource_filter.GetAllKeys(
            self._compiled_expression)
Exemple #8
0
    def Rewrite(self, expression, defaults=None):
        """Returns the rewrite of expression.

    Args:
      expression: The expression string to rewrite.
      defaults: resource_projection_spec.ProjectionSpec defaults.

    Returns:
      The rewritten expression string, None if the rewrite collapses to nothing.
    """
        return resource_filter.Compile(expression,
                                       backend=self,
                                       defaults=defaults).Rewrite()
  def Run(self, args):
    query = resource_filter.Compile(self._GetInventoryFilterQuery(args))

    holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
    client = holder.client

    request_data = lister.ParseMultiScopeFlags(args, holder.resources)
    list_implementation = lister.MultiScopeLister(
        client,
        zonal_service=client.apitools_client.instances,
        aggregation_service=client.apitools_client.instances)

    instances_iterator = lister.Invoke(request_data, list_implementation)
    instances = list(instances_iterator)

    responses = self._GetAllGuestInventoryGuestAttributes(holder, instances)
    return self._GetInventoryFilteredInstances(instances, responses, query)
  def RunSubTest(self, expression, deprecated=False):

    def _Error(resource=None):
      """Always raises ValueError for testing.

      Args:
        resource: The resource object.

      Raises:
        ValueError: Always for testing.
      """
      _ = resource
      raise ValueError('Transform function value error.')

    default_symbols = {
        'date': resource_transform.TransformDate,
        'len': lambda r, x=None: resource_transform.TransformLen(x or r),
    }
    defaults = resource_projection_parser.Parse(
        '(compound.string:alias=s, floating:alias=f)',
        symbols=default_symbols,
        aliases=self._ALIASES)
    symbols = {
        'error': _Error,  # 'error' not a magic name.
    }
    defaults = resource_projection_spec.ProjectionSpec(
        defaults=defaults, symbols=symbols)
    evaluate = resource_filter.Compile(expression, defaults=defaults).Evaluate
    if isinstance(self.resource, list):
      results = []
      for r in self.resource:
        results.append(evaluate(r))
      return results
    actual = evaluate(self.resource)
    err = self.GetErr()
    self.ClearErr()
    warning = ('WARNING: --filter : operator evaluation is changing for '
               'consistency across Google APIs.')
    if err and not deprecated:
      self.fail('Error [%s] not expected.' % err)
    elif not err and deprecated:
      self.fail('Warning [%s] expected.' % warning)
    elif err and deprecated and warning not in err:
      self.fail('Warning [%s] expected but got [%s].' % (warning, err))
    return actual
Exemple #11
0
def GetReferencedKeyNames(filter_string=None,
                          format_string=None,
                          printer=None,
                          defaults=None):
    """Returns the set of key names referenced by filter / format expressions.

  NOTICE: OnePlatform is forgiving on filter and format key reference name
  spelling.  Use resource_property.GetMatchingIndex() when verifying against
  resource dictionaries to handle camel and snake case spellings.

  Args:
    filter_string: The resource filter expression string.
    format_string: The resource format expression string.
    printer: The parsed format_string.
    defaults: The resource format and filter default projection.

  Raises:
    ValueError: If both format_string and printer are specified.

  Returns:
    The set of key names referenced by filter / format expressions.
  """
    keys = set()

    # Add the format key references.
    if printer:
        if format_string:
            raise ValueError('Cannot specify both format_string and printer.')
    elif format_string:
        printer = resource_printer.Printer(format_string, defaults=defaults)
        defaults = printer.column_attributes
    if printer:
        for col in printer.column_attributes.Columns():
            keys.add(resource_lex.GetKeyName(col.key, omit_indices=True))

    # Add the filter key references.
    if filter_string:
        expr = resource_filter.Compile(filter_string,
                                       defaults=defaults,
                                       backend=resource_keys_expr.Backend())
        for key in expr.Evaluate(None):
            keys.add(resource_lex.GetKeyName(key, omit_indices=True))

    return keys
    def _ParseKey(self):
        """Parses a key and optional attributes from the expression.

    Transform functions and key attributes are also handled here.

    Raises:
      ExpressionSyntaxError: The expression has a syntax error.

    Returns:
      The parsed key.
    """
        key = self._lex.Key()
        attribute = self._Attribute(self._projection.PROJECT)
        if self._lex.IsCharacter('(', eoi_ok=True):
            func_name = key.pop()
            attribute.transform = self._lex.Transform(func_name,
                                                      self._projection.active)
            func_name = attribute.transform.name
        else:
            func_name = None
        self._lex.SkipSpace()
        if self._lex.IsCharacter(':'):
            self._ParseKeyAttributes(key, attribute)
        if attribute.transform and attribute.transform.conditional:
            # Parse and evaluate if() transform conditional expression,
            conditionals = self._projection.symbols.get(
                resource_transform.GetTypeDataName('conditionals'))

            def EvalGlobalRestriction(unused_obj, restriction, unused_pattern):
                return getattr(conditionals, restriction, None)

            defaults = resource_projection_spec.ProjectionSpec(
                symbols={
                    resource_projection_spec.GLOBAL_RESTRICTION_NAME:
                    EvalGlobalRestriction
                })
            if not resource_filter.Compile(
                    attribute.transform.conditional,
                    defaults=defaults).Evaluate(conditionals):
                return
        if func_name and attribute.label is None and not key:
            attribute.label = self._AngrySnakeCase([func_name])
        self._AddKey(key, attribute)
Exemple #13
0
    def Run(self, args):
        """Runs the command.

    Args:
      args: All the arguments that were provided to this command invocation.

    Returns:
      An iterator over Job messages.
    """
        if args.filter:
            filter_expr = resource_filter.Compile(args.filter)
            filter_pred = lambda x: filter_expr.Evaluate(x) and _JobFilter(args
                                                                           )(x)
        else:
            filter_pred = _JobFilter(args)

        project_id = properties.VALUES.core.project.Get(required=True)
        jobs = self._JobSummariesForProject(project_id, args, filter_pred)

        return [job_display.DisplayInfo(job) for job in jobs]
    def Rewrite(self, expression, defaults=None):
        """Returns (frontend_expression, backend_expression) for expression.

    There are 3 outcomes:
      (None, backend) -- only need to apply the backend expression
      (frontend, None) -- only need to apply the frontend expression
      (frontend, backend) -- must apply both frontend and backend expressions

    Args:
      expression: The expression string to rewrite.
      defaults: resource_projection_spec.ProjectionSpec defaults.

    Returns:
      Returns (frontend_expression, backend_expression) for expression.
    """
        self.partial_rewrite = False
        backend_expression = resource_filter.Compile(
            expression, backend=self, defaults=defaults).Rewrite()
        frontend_expression = expression if self.partial_rewrite else None
        return frontend_expression, backend_expression
Exemple #15
0
            def _ResourceSearchList(limit=None,
                                    page_size=None,
                                    query=None,
                                    sort_by=None,
                                    uri=False):
                """resource_search.list mock."""

                del limit, page_size, sort_by, uri
                results = None
                select_resource = resource_filter.Compile(query).Evaluate
                for name, value in six.iteritems(search_resources):
                    if select_resource({'@type': name}):
                        if results is None:
                            results = []
                        results += value
                if results is None:
                    raise resource_search.CollectionNotIndexed(
                        'Collection [{}] not indexed for search.'.format(
                            query))
                return results
Exemple #16
0
  def GetReferencedKeyNames(self):
    """Returns the list of key names referenced by the command."""

    keys = set()

    # Add the format key references.
    self._InitPrinter()
    if self._printer:
      for col in self._printer.column_attributes.Columns():
        keys.add(resource_lex.GetKeyName(col.key))

    # Add the filter key references.
    filter_expression = self._GetFlag('filter')
    if filter_expression:
      expr = resource_filter.Compile(filter_expression,
                                     defaults=self._defaults,
                                     backend=resource_keys_expr.Backend())
      for key in expr.Evaluate(None):
        keys.add(resource_lex.GetKeyName(key))

    return keys
def GetAssetInventoryListInput(folder,
                               project,
                               org,
                               file_path=None,
                               asset_types_filter=None,
                               filter_expression=None,
                               krm_kind_filter=None):
  """Generate a AssetInventory export data set from api list call.


  Calls AssetInventory List API via shared api client (AssetListClient) and
  generates a list of exportable assets. If `asset_types_filter`,
  `gvk_kind_filter` or `filter_expression` is passed, it will filter out
  non-matching resources. If `file_path` is None list will be returned as a
  string otherwise it is written to disk at specified path.

  Args:
    folder: string, folder parent for resource export.
    project: string, project parent for resource export.
    org: string, organization parent for resource export.
    file_path: string, path to write AssetInventory export file to. If None,
      results are returned as string.
    asset_types_filter: [string], list of asset types to include in the output
      file.
    filter_expression: string, a valid gcloud filter expression. See `gcloud
      topic filter` for more details.
    krm_kind_filter: [string], list of KrmKinds corresponding to asset types to
      include in the output.

  Returns:
    string: file path where AssetInventory data has been written or raw data if
      `temp_file_path` is None. Returns None if no results returned from API.

  Raises:
    RequiredArgumentException: If none of folder, project or org is provided.
    ResourceNotFoundException: If no resources are found or returned from
      filtering.
    ClientException: Writing file to disk.
  """
  root_asset = asset_utils.GetParentNameForExport(
      organization=org, project=project, folder=folder)
  asset_client = client_util.AssetListClient(root_asset)
  filter_func = (
      resource_filter.Compile(filter_expression.strip()).Evaluate
      if filter_expression else None)
  asset_filter = asset_types_filter or []
  if krm_kind_filter:
    kind_filters = _BuildAssetTypeFilterFromKind(krm_kind_filter)
    if not kind_filters:
      raise ResourceNotFoundException(
          'No matching resource types found for {}'.format(krm_kind_filter))
    asset_filter.extend(kind_filters)

  args = ApiClientArgs(
      snapshot_time=None,
      limit=None,
      page_size=None,
      content_type=None,
      asset_types=sorted(asset_filter),
      parent=root_asset,
      filter_func=filter_func,
      relationship_types=[])
  asset_results = asset_client.List(args, do_filter=True)
  asset_string_array = []
  for item in asset_results:  # list of apitools Asset messages.
    item_str = encoding.MessageToJson(item)
    item_str = item_str.replace('"assetType"', '"asset_type"')
    asset_string_array.append(item_str)

  if not asset_string_array:
    if asset_types_filter:
      asset_msg = '\n With resource types in [{}].'.format(asset_types_filter)
    else:
      asset_msg = ''
    if filter_expression:
      filter_msg = '\n Matching provided filter [{}].'.format(filter_expression)
    else:
      filter_msg = ''
    raise ResourceNotFoundException(
        'No matching resources found for [{parent}] {assets} {filter}'.format(
            parent=root_asset, assets=asset_msg, filter=filter_msg))
  if not file_path:
    return '\n'.join(asset_string_array)
  else:
    try:
      files.WriteFileAtomically(file_path, '\n'.join(asset_string_array))
    except (ValueError, TypeError) as e:
      raise ClientException(e)  # pylint: disable=raise-missing-from
    return file_path