Beispiel #1
0
def test_json_to_cel():
    """GIVEN JSON doc; WHEN json_to_cell(); THEN expected conversions applied."""
    doc = [
        {
            "bool": True
        },
        {
            "numbers": [2.71828, 42]
        },
        {
            "null": None
        },
        {
            "string": 'embedded "quote"'
        },
    ]
    actual = celpy.json_to_cel(doc)
    expected = celtypes.ListType([
        celtypes.MapType(
            {celtypes.StringType("bool"): celtypes.BoolType(True)}),
        celtypes.MapType({
            celtypes.StringType("numbers"):
            celtypes.ListType(
                [celtypes.DoubleType(2.71828),
                 celtypes.IntType(42)])
        }),
        celtypes.MapType({celtypes.StringType("null"): None}),
        celtypes.MapType({
            celtypes.StringType("string"):
            celtypes.StringType('embedded "quote"')
        }),
    ])
    assert actual == expected
Beispiel #2
0
def json_to_cel(document: JSON) -> celtypes.Value:
    """Convert parsed JSON object from Python to CEL to the extent possible.

    It's difficult to distinguish strings which should be timestamps or durations.

    ::

        >>> from pprint import pprint
        >>> from celpy.adapter import json_to_cel
        >>> doc = json.loads('["str", 42, 3.14, null, true, {"hello": "world"}]')
        >>> cel = json_to_cel(doc)
        >>> pprint(cel)
        ListType([StringType('str'), IntType(42), DoubleType(3.14), None, BoolType(True), \
MapType({StringType('hello'): StringType('world')})])
    """
    if isinstance(document, bool):
        return celtypes.BoolType(document)
    elif isinstance(document, float):
        return celtypes.DoubleType(document)
    elif isinstance(document, int):
        return celtypes.IntType(document)
    elif isinstance(document, str):
        return celtypes.StringType(document)
    elif document is None:
        return None
    elif isinstance(document, List):
        return celtypes.ListType([json_to_cel(item) for item in document])
    elif isinstance(document, Dict):
        return celtypes.MapType({
            json_to_cel(key): json_to_cel(value)
            for key, value in document.items()
        })
    else:
        raise ValueError(
            f"unexpected type {type(document)} in JSON structure {document!r}")
Beispiel #3
0
def jmes_path_map(source_data: celtypes.ListType,
                  path_source: celtypes.StringType) -> celtypes.ListType:
    """
    Apply JMESPath to a each object read from from a URL.
    This is for ndjson, nljson and jsonl files.
    """
    expression = jmespath.compile(path_source)
    return celtypes.ListType(
        [json_to_cel(expression.search(row)) for row in source_data])
Beispiel #4
0
def get_metrics(resource: celtypes.MapType,
                request: celtypes.MapType) -> celtypes.Value:
    """
    Reach into C7N and make a statistics request using the current C7N filter.

    This uses the module-global ``C7N`` namespace to access the original filter and policy.

    This builds a request object that is passed through to AWS via the :func:`get_raw_metrics`
    function.

    The ``request`` parameter is a Mapping with the following keys and values:

    ::

        Resource.get_metrics({"MetricName": "CPUUtilization", "Statistic": "Average",
            "StartTime": Now - duration("4d"), "EndTime": Now, "Period": duration("86400s")}
            ).exists(m, m < 30)

    The namespace is derived from the ``C7N.policy``. The dimensions are derived from
    the ``C7N.fiter.model``.

    ..  todo:: Refactor C7N

        Provide a :py:class:`MetricsAccess` mixin in a :py:class:`CELFilter` class.
        We want to have the metrics processing in the new :py:class:`CELFilter` instance.

    """
    dimension = celtypes.StringType(C7N.filter.manager.get_model().dimension)
    namespace = celtypes.StringType(C7N.filter.manager.resource_type)
    # TODO: Varies by resource/policy type. Each policy's model may have different dimensions.
    dimensions = json_to_cel([{
        'Name': dimension,
        'Value': resource.get(dimension)
    }])
    raw_metrics = cast(
        celtypes.ListType,
        get_raw_metrics(
            celtypes.MapType({
                celtypes.StringType("Namespace"):
                namespace,
                celtypes.StringType("MetricName"):
                request["MetricName"],
                celtypes.StringType("Dimensions"):
                dimensions,
                celtypes.StringType("Statistics"): [request["Statistic"]],
                celtypes.StringType("StartTime"):
                request["StartTime"],
                celtypes.StringType("EndTime"):
                request["EndTime"],
                celtypes.StringType("Period"):
                request["Period"],
            })))
    return celtypes.ListType([
        cast(celtypes.MapType, item).get(request["Statistic"])
        for item in raw_metrics
    ])
Beispiel #5
0
def parse_text(source_text: celtypes.StringType,
               format: celtypes.StringType) -> celtypes.Value:
    """
    Parse raw text using a given format.
    """
    if format == "json":
        return json_to_cel(json.loads(source_text))
    elif format == "txt":
        return celtypes.ListType([
            celtypes.StringType(s.rstrip()) for s in source_text.splitlines()
        ])
    elif format in ("ldjson", "ndjson", "jsonl"):
        return celtypes.ListType(
            [json_to_cel(json.loads(s)) for s in source_text.splitlines()])
    elif format == "csv":
        return celtypes.ListType(
            [json_to_cel(row) for row in csv.reader(io.StringIO(source_text))])
    elif format == "csv2dict":
        return celtypes.ListType([
            json_to_cel(row)
            for row in csv.DictReader(io.StringIO(source_text))
        ])
    else:
        raise ValueError(f"Unsupported format: {format!r}")  # pragma: no cover
def test_decoder():
    json_text = (
        '{"bool": 1, "numbers": [2.71828, 42], "null": null, '
        '"string": "embedded \\"quote\\"", "bytes": "Ynl0ZXM=", '
        '"timestamp": "2009-02-13T23:31:30Z", "duration": "42s"}'
     )
    cel_obj = json.loads(json_text, cls=celpy.CELJSONDecoder)
    assert cel_obj == celtypes.MapType({
        celtypes.StringType('bool'): celtypes.IntType(1),
        celtypes.StringType('bytes'): celtypes.StringType('Ynl0ZXM='),
        celtypes.StringType('duration'): celtypes.StringType('42s'),
        celtypes.StringType('null'): None,
        celtypes.StringType('numbers'):
            celtypes.ListType([celtypes.DoubleType(2.71828), celtypes.IntType(42)]),
        celtypes.StringType('string'): celtypes.StringType('embedded "quote"'),
        celtypes.StringType('timestamp'): celtypes.StringType('2009-02-13T23:31:30Z'),
    })
def test_encoder():
    cel_obj = celtypes.MapType(
        {
            celtypes.StringType("bool"): celtypes.BoolType(True),
            celtypes.StringType("numbers"):
                celtypes.ListType([
                    celtypes.DoubleType(2.71828), celtypes.UintType(42)
                ]),
            celtypes.StringType("null"): None,
            celtypes.StringType("string"): celtypes.StringType('embedded "quote"'),
            celtypes.StringType("bytes"):
                celtypes.BytesType(bytes([0x62, 0x79, 0x74, 0x65, 0x73])),
            celtypes.StringType("timestamp"): celtypes.TimestampType('2009-02-13T23:31:30Z'),
            celtypes.StringType("duration"): celtypes.DurationType('42s'),
        }
    )
    json_text = json.dumps(cel_obj, cls=celpy.CELJSONEncoder)
    assert (
        json_text == '{"bool": true, "numbers": [2.71828, 42], "null": null, '
                     '"string": "embedded \\"quote\\"", "bytes": "Ynl0ZXM=", '
                     '"timestamp": "2009-02-13T23:31:30Z", "duration": "42s"}'
    )
Beispiel #8
0
from celpy.celparser import CELParseError
from celpy import celtypes

logger = logging.getLogger("celpy")

# For argument parsing purposes.
# Note the reliance on `ast.literal_eval` for ListType and MapType conversions.
# Other types convert strings directly. These types need some help.
CLI_ARG_TYPES: Dict[str, celtypes.CELType] = {
    "int": celtypes.IntType,
    "uint": celtypes.UintType,
    "double": celtypes.DoubleType,
    "bool": celtypes.BoolType,
    "string": celtypes.StringType,
    "bytes": celtypes.BytesType,
    "list": lambda arg: celtypes.ListType(ast.literal_eval(arg)),
    "map": lambda arg: celtypes.MapType(ast.literal_eval(arg)),
    "null_type": cast(Callable[[str], celtypes.Value], lambda x: None),
    "single_duration": celtypes.DurationType,
    "single_timestamp": celtypes.TimestampType,
    "int64_value": celtypes.IntType,
    "uint64_value": celtypes.UintType,
    "double_value": celtypes.DoubleType,
    "bool_value": celtypes.BoolType,
    "string_value": celtypes.StringType,
    "bytes_value": celtypes.BytesType,
    "number_value": celtypes.DoubleType,  # Ambiguous; can somtimes be integer.
    "null_value": cast(Callable[[str], celtypes.Value], lambda x: None),
}