Esempio n. 1
0
 def test_funcs(self):
     resource = self._getTestResource()
     test1 = {"ref": ".name", "vars": {"a": None}}
     test2 = {"ref": "$b", "vars": {"b": 1}}
     test3 = {
         "ref": {
             "if": {"not": "$a"},
             "then": {"q": "expected"},
             "else": {"q": "unexpected"},
         },
         "vars": {"a": None},
     }
     result1 = Ref(test1).resolve_one(RefContext(resource))
     self.assertEqual("test", result1)
     result2 = Ref(test2).resolve_one(RefContext(resource))
     self.assertEqual(1, result2)
     result3 = Ref(test3).resolve_one(RefContext(resource))
     self.assertEqual("expected", result3)
     result4 = Ref(test3).resolve(RefContext(resource))
     self.assertEqual(["expected"], result4)
     test5 = {"ref": {"or": ["$a", "b"]}, "vars": {"a": None}}
     result5 = Ref(test5).resolve_one(RefContext(resource))
     assert all(not isinstance(i, Result) for i in result5)
     self.assertEqual(
         resource.attributes["b"], result5
     )  # this doesn't seem obvious!
Esempio n. 2
0
    def test_jinjaTemplate(self):
        resource = NodeInstance("test", attributes=dict(a1="hello"))
        ctx = RefContext(resource, {"foo": "hello"})

        self.assertEqual(applyTemplate(" {{ foo }} ", ctx), "hello")
        # test jinja2 native types
        self.assertEqual(applyTemplate(" {{[foo]}} ", ctx), ["hello"])

        self.assertEqual(applyTemplate(' {{ "::test::a1" | ref }} ', ctx),
                         u"hello")
        self.assertEqual(
            applyTemplate(' {{ lookup("unfurl", "::test::a1") }} ', ctx),
            u"hello")
        # ansible query() always returns a list
        self.assertEqual(
            applyTemplate('{{  query("unfurl", "::test::a1") }}', ctx),
            [u"hello"])

        os.environ["TEST_ENV"] = (
            "testEnv"
        )  # note: tox doesn't pass on environment variables so we need to set one now
        self.assertEqual(mapValue("{{ lookup('env', 'TEST_ENV') }}", resource),
                         "testEnv")

        # test that ref vars as can be used as template string vars
        exp = {"a": "{{ aVar }} world"}
        vars = {"aVar": "hello"}
        self.assertEqual(mapValue(exp, RefContext(resource, vars)),
                         {"a": "hello world"})

        vars = {"foo": {"bar": sensitive_str("sensitive")}}
        val = applyTemplate("{{ foo.bar }}", RefContext(resource,
                                                        vars,
                                                        trace=0))
        assert isinstance(val, sensitive_str), type(val)
Esempio n. 3
0
    def test_external(self):
        class ExternalTest(ExternalValue):
            def __init__(self):
                super(ExternalTest, self).__init__("ExternalTest", "test")

        singleton = ExternalTest()
        set_eval_func("externaltest", lambda arg, ctx: singleton)

        ctx = RefContext(self._getTestResource())
        expr = Ref({"eval": {"externaltest": None}})

        result = expr.resolve(ctx)
        self.assertEqual(result[0], "test")

        result = expr.resolve_one(ctx)
        self.assertEqual(result, "test")

        result = expr.resolve(ctx, wantList="result")
        self.assertIs(result.external, singleton)

        asTemplate = '{{ {"externaltest": none } | eval }}'
        result = map_value(asTemplate, ctx)
        assert isinstance(result, str)
        self.assertEqual(result, "test")

        ctx2 = ctx.copy(wantList="result")
        result = map_value(asTemplate, ctx2)
        self.assertIs(result.external, singleton)

        result = map_value("transformed " + asTemplate, ctx2)
        self.assertEqual(result, "transformed test")
Esempio n. 4
0
 def test_nodeTraversal2(self):
     root = NodeInstance("root", {"a": [{"ref": "::child"}, {"b": 2}]})
     child = NodeInstance("child", {"b": 1}, root)
     self.assertEqual(Ref(".ancestors").resolve(RefContext(child)), [[child, root]])
     # self.assertEqual(Ref('a::b').resolve(RefContext(root)), [1])
     self.assertEqual(Ref("a").resolve(RefContext(child)), [[child, {"b": 2}]])
     # a resolves to [child, dict] so a::b resolves to [child[b], [b]2]
     self.assertEqual(Ref("a::b").resolve(RefContext(child)), [1, 2])
Esempio n. 5
0
    def test_vars(self):
        # test dereferencing vars
        resource = self._getTestResource()
        query = {
            "eval": "$aDict",
            "vars": {"aDict": {"aRef": {"eval": "::test"}, "aTemplate": "{{ true }}"}},
        }
        result = Ref(query).resolve_one(RefContext(resource))
        self.assertEqual(result, {"aRef": resource, "aTemplate": True})

        query = {"eval": "$aRef", "vars": {"aRef": {"eval": "::test"}}}
        assert Ref.is_ref(query["vars"]["aRef"])
        result = Ref(query).resolve_one(RefContext(resource))
        self.assertEqual(result, resource)
Esempio n. 6
0
 def test_nodeTraversal1(self):
     root = NodeInstance(
         "r2",
         {
             "a": [dict(ref="::r1::a"), dict(ref="b")],
             "b": "r2"
         }  #'r1'  #'r2'
     )
     child = NodeInstance("r1", {"a": dict(ref="b"), "b": "r1"}, root)
     ctx = RefContext(root)
     x = [{"a": [{"c": 1}, {"c": 2}]}]
     assert x == ResultsList(x, ctx)
     self.assertEqual(Ref("b").resolve(RefContext(child)), ["r1"])
     self.assertEqual(Ref("a").resolve(RefContext(child)), ["r1"])
     self.assertEqual(Ref("a").resolve(RefContext(root)), [["r1", "r2"]])
Esempio n. 7
0
    def test_innerReferences(self):
        resourceDef = {
            "a": dict(b={"ref": "a::c"}, c={"e": 1}, d=["2", {"ref": "a::d::0"}])
        }
        resource = NodeInstance("test", attributes=resourceDef)
        assert not not resource.attributes
        self.assertEqual(len(resource.attributes), 1)

        expectedA = {"c": {"e": 1}, "b": {"e": 1}, "d": ["2", "2"]}
        self.assertEqual(resource.attributes["a"]["b"], expectedA["b"])
        self.assertEqual(resource.attributes["a"], expectedA)
        self.assertEqual(Ref("a").resolve(RefContext(resource)), [expectedA])
        self.assertEqual(Ref("a").resolve_one(RefContext(resource)), expectedA)

        expected = ["2"]
        self.assertEqual(Ref("a::d::0").resolve(RefContext(resource)), expected)
        self.assertEqual(Ref("a::d::1").resolve(RefContext(resource)), expected)

        # print('test_references', resource.attributes,
        #   'AAAA', resource.attributes['a'],
        #   'BBB', resource.attributes['a']['b'],
        # )
        self.assertEqual(resource.attributes["a"], expectedA)
        self.assertEqual(resource.attributes["a"]["d"][0], "2")
        self.assertEqual(resource.attributes["a"]["d"][1], "2")
        self.assertEqual(resource.attributes["a"]["b"]["e"], 1)

        self.assertEqual(Ref("a::b::e").resolve(RefContext(resource)), [1])

        # test again to make sure it still resolves correctly
        self.assertEqual(Ref("a::d::0").resolve(RefContext(resource)), expected)
        self.assertEqual(Ref("a::d::1").resolve(RefContext(resource)), expected)
Esempio n. 8
0
    def test_nodeTraversal1(self):
        root = NodeInstance(
            "r2", {"a": [dict(ref="::r1::a"), dict(ref="b")], "b": "r2"}  #'r1'  #'r2'
        )
        child = NodeInstance("r1", {"a": dict(ref="b"), "b": "r1"}, root)
        ctx = RefContext(root)
        x = [{"a": [{"c": 1}, {"c": 2}]}]
        r1 = ResultsList(x, ctx)
        assert x == r1
        self.assertEqual(Ref("b").resolve(RefContext(child)), ["r1"])
        self.assertEqual(Ref("a").resolve(RefContext(child)), ["r1"])
        self.assertEqual(Ref("a").resolve(RefContext(root)), [["r1", "r2"]])

        assert not r1._haskey(1)
        r1.append("added")
        assert r1._haskey(1)
        r1[0]["a"][1] = "not c"
        assert r1[0]["a"][1] == "not c"
Esempio n. 9
0
    def test_forEach(self):
        resource = self._getTestResource()
        test1 = {"ref": ".", "foreach": {"value": {"content": {"ref": "b"}}}}
        expected0 = {"content": [1, 2, 3]}
        result0 = Ref(test1).resolve_one(RefContext(resource, trace=0))
        self.assertEqual(expected0, result0)
        # resolve has same result as resolveOne
        self.assertEqual([expected0], Ref(test1).resolve(RefContext(resource)))

        # add 'key' to make result a dict
        # test that template strings work
        # XXX fragile: key is base64 of __str__ of NodeInstance
        test1["foreach"]["key"] = "{{ item | ref | b64encode}}"
        result1 = Ref(test1).resolve_one(RefContext(resource))
        expected = {"Tm9kZUluc3RhbmNlKCd0ZXN0Jyk=": expected0}
        self.assertEqual(expected, result1, result1)
        result2 = Ref(test1).resolve(RefContext(resource))
        self.assertEqual([expected], result2)
Esempio n. 10
0
    def test_templateFunc(self):
        query = {
            "eval": {
                "template": "{%if testVar %}{{success}}{%else%}failed{%endif%}"
            },
            "vars": {
                "testVar": True,
                "success": dict(eval={
                    "if": "$true",
                    "then": ".name"
                }),
            },
        }
        resource = self._getTestResource({"aTemplate": query})
        self.assertEqual(mapValue(query, resource), "test")
        self.assertEqual(resource.attributes["aTemplate"], "test")

        template = """\
#jinja2: variable_start_string: '<%', variable_end_string: '%>'
{% filter from_yaml %}
a_dict:
    key1: "{{ extras.quoted }}" # shouldn't be evaluated
    key2: "<% extras.quoted %>" # will be evaluated to "{{ quoted }}  "
    key3: "original"
    <<: <% key4 | mapValue | to_json %>  # will merge into a_dict
{% endfilter %}
        """
        vars = {
            "extras": dict(key3="hello", quoted={"q": "{{ quoted }}  "}),
            "key4": dict(extra1={"a": 1}, extra2=[1, 3], key3="overwritten"),
            "key2": {
                "q": "{{ quoted2 }}  "
            },
        }
        query2 = {"eval": {"template": template}}
        expected = {
            "a_dict": {
                "key1": "{{ extras.quoted }}",
                "key2": "{{ quoted }}  ",
                "key3": "original",
                "extra1": {
                    "a": 1
                },
                "extra2": [1, 3],
            }
        }
        ctx = RefContext(resource, vars)
        result = applyTemplate(template, ctx)
        self.assertEqual(result, expected)
        result = mapValue(query2, ctx)
        self.assertEqual(result, expected)
Esempio n. 11
0
    def test_binaryvault(self):
        import six
        from unfurl.support import AttributeManager
        from unfurl.yamlloader import make_yaml, sensitive_bytes, make_vault_lib

        # load a binary file then write it out as a temporary vault file
        fixture = os.path.join(
            os.path.dirname(__file__), "fixtures/helmrepo/mysql-1.6.4.tgz"
        )
        src = (
            """
          eval:
            tempfile:
                eval:
                  file: %s
                select: contents
            encoding: vault
        """
            % fixture
        )
        vault = make_vault_lib("password")
        yaml = make_yaml(vault)
        expr = yaml.load(six.StringIO(src))
        resource = self._getTestResource()
        resource.attributeManager = AttributeManager(yaml)
        resource._templar._loader.set_vault_secrets(vault.secrets)
        pickled = pickle.dumps(resource, -1)
        assert pickle.loads(pickled)

        filePath = map_value(expr, resource)
        with open(filePath, "rb") as vf:
            vaultContents = vf.read()
            assert vaultContents.startswith(b"$ANSIBLE_VAULT;")

        # decrypt the vault file, make sure it's a sensitive_bytes string that matches the original contents
        src = """
        eval:
          file:
            eval: $tempfile
          encoding: binary
        select: contents
        """
        expr = yaml.load(six.StringIO(src))
        contents = map_value(expr, RefContext(resource, vars=dict(tempfile=filePath)))
        assert isinstance(contents, sensitive_bytes), type(contents)
        with open(fixture, "rb") as tp:
            self.assertEqual(tp.read(), contents)
Esempio n. 12
0
 def test_to_env_set_environ(self):
     import six
     from unfurl.yamlloader import make_yaml
     src = """
       eval:
         to_env:
           ^PATH: /foo/bin
         update_os_environ: true
       """
     yaml = make_yaml()
     expr = yaml.load(six.StringIO(src))
     ctx = RefContext(self._getTestResource())
     path = os.environ['PATH']
     env = map_value(expr, ctx)
     new_path = "/foo/bin:"+path
     assert os.environ['PATH'] == new_path
     assert env == {'PATH': new_path}
Esempio n. 13
0
    def test_decorator(self):
        cliRunner = CliRunner()
        with cliRunner.isolated_filesystem():
            path = __file__ + "/../examples/decorators-ensemble.yaml"
            manifest = YamlManifest(path=path)

            ctx = RefContext(manifest.tosca.topology)
            result1 = Ref(
                "my_server::dependency::tosca.nodes.Compute").resolve(ctx)
            self.assertEqual("my_server2", result1[0].name)

            self.assertEqual(
                {"test": "annotated"},
                manifest.tosca.nodeTemplates["my_server2"].properties,
            )
            for name in ["anode", "anothernode"]:
                node = manifest.tosca.nodeTemplates[name]
                self.assertEqual(
                    {
                        "ports": [],
                        "private_address": "annotated",
                        "imported": "foo"
                    },
                    node.properties,
                )
            assert {
                "foo": "bar"
            } == (manifest.tosca.template.tpl["topology_template"]
                  ["node_templates"]["node3"]["requirements"][0]
                  ["a_connection"]["relationship"]["properties"])

            # run job so we generate instances
            # set out we don't save the file
            Runner(manifest).run(JobOptions(out=io.StringIO()))
            assert manifest.rootResource.instances

            result = manifest.rootResource.query(
                "::my_server::.sources::a_connection")
            assert result and result.name == "node3"
            result2 = manifest.rootResource.query(
                "::my_server::.targets::dependency")
            assert result2 and result2.name == "my_server2"
Esempio n. 14
0
    def test_inputAndOutputs(self):
        manifest = YamlManifest(manifestDoc)

        ctx = RefContext(manifest.tosca.topology)
        result1 = Ref("my_server::dependency::tosca.nodes.Compute").resolve(
            ctx)
        self.assertEqual("my_server", result1[0].name)

        self.assertEqual(
            {
                "foo": "bar",
                "test": "annotated"
            },
            manifest.tosca.nodeTemplates["my_server"].properties,
        )
        for name in ["anode", "anothernode"]:
            node = manifest.tosca.nodeTemplates[name]
            self.assertEqual({
                "ports": [],
                "private_address": "annotated"
            }, node.properties)
Esempio n. 15
0
 def test_to_env(self):
     import six
     from unfurl.yamlloader import make_yaml
     src = """
       eval:
         to_env:
           FOO: 1 # get converted to string
           BAR: false # get converted to empty string
           BAZ: true # get converted to string
           NUL: null # key gets excluded
           QUU: # redacted when serialized into yaml
             eval:
               sensitive: "passw0rd"
       """
     yaml = make_yaml()
     expr = yaml.load(six.StringIO(src))
     ctx = RefContext(self._getTestResource())
     env = map_value(expr, ctx)
     assert env == {'FOO': '1', 'BAR': '', 'BAZ': 'true', 'QUU': 'passw0rd'}
     out=six.StringIO()
     yaml.dump(serialize_value(env), out)
     assert out.getvalue() == '''\
Esempio n. 16
0
 def test_refPaths(self):
     resource = self._getTestResource()
     for (exp, expected) in [
         ["x?::a[c=4]", [[{"c": 3}, {"c": 4}, {"l": ["l3"]}, {"l": ["l4"]}]]],
         [
             "x::a[c]?",
             [[{"c": 1}, {"c": 2}, {"b": "exists"}, {"l": ["l1"]}, {"l": ["l2"]}]],
         ],
         ["x::a::[c]", [{"c": 1}, {"c": 2}, {"c": 3}, {"c": 4}]],
         ["x::a?::[c]", [{"c": 1}, {"c": 2}]],
         ["a", ["test"]],
         ["b", [[1, 2, 3]]],
         ["b::0", [1]],
         ["b?::2", [3]],
         ["[b::2]::b::2", [3]],
         ["b::1", [2]],
         ["s::b", [[1, 2, 3]]],
         ["s::b::1", [2]],
         ["s::s::b::1", [2]],
         ["n::n::n", ["n"]],
         ["d[a=va]", [{"a": "va", "b": "vb"}]],
         ["d[a=vb]", []],
         ["b[1=2]", [[1, 2, 3]]],
         ["b[1=1]", []],
         ["a[=test]", ["test"]],
         ["a[!=test]", []],
         ["a[key]", []],
         ["d[a=va][b=vb]", [{"a": "va", "b": "vb"}]],
         ["d[a=va][a=vb]", []],
         ["d[a=va][a!=vb]", [{"a": "va", "b": "vb"}]],
         ["d[a=va]::b", ["vb"]],
         ["x::a::c", [1, 2, 3, 4]],
         ["x::c", [5, 6]],
         ["x::[c]", [{"c": 5}, {"c": 6}]],
         ["x::[c=5]", [{"c": 5}]],
         ["x::a[b]::c", [1, 2]],
         ["x::a[!b]::c", [3, 4]],
         ["x::a::l", [["l1"], ["l2"], ["l3"], ["l4"]]],
         [{"ref": "a[=$yes]", "vars": {"yes": "test"}}, ["test"]],
         [{"ref": "a[=$no]", "vars": {"no": None}}, []],
         ["[a]", [resource]],
         ["[=blah]", []],
         ["[blah]", []],
         ["[!blah]", [resource]],
         [".[!=blah]", [resource]],
         ["[!a]", []],
         ["::test", [resource]],
         ["d::*", set(["va", "vb"])],
         ["e::*::b2", ["v2"]],
         ["*", []],
         ["f", [{"a": 1, "b": 1}]],
         ["::*", [resource]],
         ["::*::.template::type", ["tosca.nodes.Root"]],
         # [{"q": "{{ foo }}"}, ["{{ foo }}"]]
         # XXX test nested ['.[k[d=3]=4]']
     ]:
         ref = Ref(exp)
         # print ('eval', ref.source, ref)
         result = ref.resolve(RefContext(resource, trace=0))
         assert all(not isinstance(i, Result) for i in result)
         if isinstance(expected, set):
             # for results where order isn't guaranteed in python2.7
             self.assertEqual(
                 set(result),
                 expected,
                 "expr was: " + ref.source,
             )
         else:
             self.assertEqual(
                 result,
                 expected,
                 "expr was: " + ref.source,
             )
Esempio n. 17
0
 def test_templateNodes(self):
     resource = self._getTestResource()
     NODES = TopologyMap(resource)
     assert resource.attributes is NODES["test"]
     ctx = RefContext(resource, dict(NODES=NODES))
     self.assertEqual("va", apply_template("{{ NODES.test.d.a }}", ctx))