def test_k8sConfig(self): os.environ["TEST_SECRET"] = "a secret" manifest = YamlManifest(manifestScript) job = Runner(manifest).run(JobOptions(add=True, startTime=1)) assert not job.unexpectedAbort assert job.status == Status.ok, job.summary() # print(job.summary()) # print(job.out.getvalue()) # verify secret contents isn't saved in config self.assertNotIn("a secret", job.out.getvalue()) self.assertNotIn("YSBzZWNyZXQ", job.out.getvalue()) # base64 of "a secret" # print (job.out.getvalue()) self.assertIn("<<REDACTED>>", job.out.getvalue()) assert not job.unexpectedAbort assert job.status == Status.ok, job.summary() manifest = YamlManifest(job.out.getvalue()) job2 = Runner(manifest).run( JobOptions(workflow="undeploy", startTime=2)) results = job2.jsonSummary() assert not job2.unexpectedAbort assert job2.status == Status.ok, job2.summary() assert len(results["tasks"]) == 1, results
def _runInputAndOutputs(self, manifest): job = Runner(manifest).run(JobOptions(add=True, startTime="time-to-test")) assert not job.unexpectedAbort, job.unexpectedAbort.get_stack_trace() my_server = manifest.get_root_resource().find_resource("my_server") assert my_server self.assertEqual( "10 GB", my_server.query({"get_property": ["SELF", "host", "disk_size"]}) ) assert my_server.attributes["test"] == "cpus: 2" assert my_server.attributes["concat2"] is None # print(job.out.getvalue()) testSensitive = manifest.get_root_resource().find_resource("testSensitive") for name, toscaType in ( ("access_token", "tosca.datatypes.Credential"), ("TEST_VAR", "unfurl.datatypes.EnvVar"), ): assert testSensitive.template.propertyDefs[name].schema["type"] == toscaType def t(datatype): return datatype.type == "unfurl.datatypes.EnvVar" envvars = set(testSensitive.template.find_props(testSensitive.attributes, t)) self.assertEqual(envvars, set([("TEST_VAR", "foo"), ("VAR1", "more")])) outputIp = job.get_outputs()["server_ip"] self.assertEqual(outputIp, "10.0.0.1") assert isinstance(outputIp, sensitive_str), type(outputIp) assert job.status == Status.ok, job.summary() self.assertEqual("RHEL", testSensitive.attributes["distribution"]) return outputIp, job
def test_import(self): foreign = ( """ apiVersion: %s kind: Manifest spec: service_template: node_types: test.nodes.AbstractTest: derived_from: tosca.nodes.Root properties: private_address: type: string required: false metadata: sensitive: true interfaces: Install: operations: check: implementation: SetAttribute instances: anInstance: template: type: test.nodes.AbstractTest """ % API_VERSION ) localConfig = """ apiVersion: unfurl/v1alpha1 kind: Project environments: defaults: repositories: in_context: url: file:. secrets: vault_secrets: default: a_password external: foreign: manifest: file: foreignmanifest.yaml instance: "*" # this is the default """ # import a node from a external manifest and have an abstract node template select it # check will be run on it each time mainManifest = ( """ apiVersion: %s kind: Manifest spec: service_template: imports: - file: foreignmanifest.yaml#/spec/service_template repository: in_context topology_template: outputs: server_ip: value: {eval: "::foreign:anInstance::private_address"} node_templates: anInstance: type: test.nodes.AbstractTest directives: - select """ % API_VERSION ) runner = CliRunner() # delete UNFURL_HOME try: UNFURL_HOME = os.environ.get("UNFURL_HOME") with runner.isolated_filesystem(): os.environ["UNFURL_HOME"] = "" with open("foreignmanifest.yaml", "w") as f: f.write(foreign) with open("unfurl.yaml", "w") as f: f.write(localConfig) with open("manifest.yaml", "w") as f: f.write(mainManifest) manifest = LocalEnv("manifest.yaml").get_manifest() assert manifest.manifest.vault and manifest.manifest.vault.secrets job = Runner(manifest).run( JobOptions(add=True, startTime="time-to-test") ) # print(job.out.getvalue()) # print(job.jsonSummary(True)) assert job.status == Status.ok, job.summary() self.assertEqual( [ { "operation": "check", "configurator": "tests.test_tosca.SetAttributeConfigurator", "changed": True, "priority": "required", "reason": "check", "status": "ok", "target": "foreign:anInstance", "targetStatus": "ok", "targetState": None, # "started", "template": "anInstance", "type": "test.nodes.AbstractTest", } ], job.json_summary()["tasks"], ) job.get_outputs() self.assertEqual(job.get_outputs()["server_ip"], "10.0.0.1") self.assertEqual( len(manifest.localEnv._manifests), 2, manifest.localEnv._manifests ) # print("output", job.out.getvalue()) assert "10.0.0.1" not in job.out.getvalue(), job.out.getvalue() vaultString1 = "server_ip: !vault |\n $ANSIBLE_VAULT;1.1;AES256" assert vaultString1 in job.out.getvalue() vaultString2 = ( "private_address: !vault |\n $ANSIBLE_VAULT;1.1;AES256" ) assert vaultString2 in job.out.getvalue() # reload: manifest2 = LocalEnv("manifest.yaml").get_manifest() assert manifest2.lastJob # test that restored manifest create a shadow instance for the foreign instance imported = manifest2.imports["foreign"].resource assert imported imported2 = manifest2.imports.find_import("foreign:anInstance") assert imported2 assert imported2.shadow self.assertIs(imported2.root, manifest2.get_root_resource()) self.assertEqual(imported2.attributes["private_address"], "10.0.0.1") self.assertIsNot(imported2.shadow.root, manifest2.get_root_resource()) finally: if UNFURL_HOME is not None: os.environ["UNFURL_HOME"] = UNFURL_HOME
def test_terraform(self): """ test that runner figures out the proper tasks to run """ runner = CliRunner() with runner.isolated_filesystem(): with open("unfurl.yaml", "w") as f: f.write(projectConfig) with open("ensemble.yaml", "w") as f: f.write(ensembleConfig) manifest = LocalEnv().getManifest() assert manifest.manifest.vault and manifest.manifest.vault.secrets assert not manifest.lastJob job = Runner(manifest).run(JobOptions(startTime=1, verbose=-1)) # print(job.out.getvalue()) # print(job.jsonSummary(True)) assert not job.unexpectedAbort, job.unexpectedAbort.getStackTrace() assert job.status == Status.ok, job.summary() example = job.rootResource.findResource("example") self.assertEqual(example.attributes["tags"], {"Name": "test"}) self.assertEqual(example.attributes["availability_zone"], "us-east-1a") self.assertEqual(type(example.attributes["availability_zone"]), sensitive_str) self.assertEqual( job.jsonSummary(), { "job": { "id": "A01110000000", "status": "ok", "total": 1, "ok": 1, "error": 0, "unknown": 0, "skipped": 0, "changed": 1, }, "outputs": {}, "tasks": [{ "status": "ok", "target": "example", "operation": "create", "template": "example", "type": "unfurl.nodes.Installer.Terraform", "targetStatus": "ok", "changed": True, "configurator": "unfurl.configurators.terraform.TerraformConfigurator", "priority": "required", "reason": "add", }], }, ) # reload and check manifest2 = LocalEnv().getManifest() assert manifest2.lastJob manifest2.rootResource.findResource("example") self.assertEqual(type(example.attributes["availability_zone"]), sensitive_str) job = Runner(manifest2).run( JobOptions(workflow="check", verbose=-1, startTime=2)) assert not job.unexpectedAbort, job.unexpectedAbort.getStackTrace() assert job.status == Status.ok, job.summary() self.assertEqual( job.jsonSummary(), { "job": { "id": "A01120000000", "status": "ok", "total": 1, "ok": 1, "error": 0, "unknown": 0, "skipped": 0, "changed": 0, }, "outputs": {}, "tasks": [{ "status": "ok", "target": "example", "operation": "check", "template": "example", "type": "unfurl.nodes.Installer.Terraform", "targetStatus": "ok", "changed": False, "configurator": "unfurl.configurators.terraform.TerraformConfigurator", "priority": "required", "reason": "check", }], }, ) # reload and undeploy: manifest3 = LocalEnv().getManifest() assert manifest3.lastJob manifest3.rootResource.findResource("example") self.assertEqual(type(example.attributes["availability_zone"]), sensitive_str) job = Runner(manifest2).run( JobOptions(workflow="undeploy", verbose=-1, startTime=3)) assert not job.unexpectedAbort, job.unexpectedAbort.getStackTrace() assert job.status == Status.ok, job.summary() self.assertEqual( job.jsonSummary(), { "job": { "id": "A01130000000", "status": "ok", "total": 1, "ok": 1, "error": 0, "unknown": 0, "skipped": 0, "changed": 1, }, "outputs": {}, "tasks": [{ "status": "ok", "target": "example", "operation": "delete", "template": "example", "type": "unfurl.nodes.Installer.Terraform", "targetStatus": "absent", "changed": True, "configurator": "unfurl.configurators.terraform.TerraformConfigurator", "priority": "required", "reason": "undeploy", }], }, )
def test_k8s_config(self): os.environ["TEST_SECRET"] = "a secret" manifest = YamlManifest(MANIFEST) job = Runner(manifest).run(JobOptions(add=True, startTime=1)) assert not job.unexpectedAbort assert job.status == Status.ok, job.summary() # print(job.summary()) # print(job.out.getvalue()) # verify secret contents isn't saved in config assert "a secret" not in job.out.getvalue() assert "YSBzZWNyZXQ" not in job.out.getvalue() # base64 of "a secret" # print (job.out.getvalue()) assert "<<REDACTED>>" in job.out.getvalue() assert not job.unexpectedAbort assert job.status == Status.ok, job.summary() manifest = YamlManifest(job.out.getvalue()) job2 = Runner(manifest).run( JobOptions(workflow="undeploy", startTime=2)) results = job2.json_summary() assert not job2.unexpectedAbort assert job2.status == Status.ok, job2.summary() assert results == { "job": { "id": "A01120000000", "status": "ok", "total": 2, "ok": 2, "error": 0, "unknown": 0, "skipped": 0, "changed": 2, }, "outputs": {}, "tasks": [ { "status": "ok", "target": "testSecret", "operation": "delete", "template": "testSecret", "type": "unfurl.nodes.K8sSecretResource", "targetStatus": "absent", "targetState": "deleted", "changed": True, "configurator": "unfurl.configurators.k8s.ResourceConfigurator", "priority": "required", "reason": "undeploy", }, { "status": "ok", "target": "k8sNamespace", "operation": "delete", "template": "k8sNamespace", "type": "unfurl.nodes.K8sNamespace", "targetStatus": "absent", "targetState": "deleted", "changed": True, "configurator": "unfurl.configurators.k8s.ResourceConfigurator", "priority": "required", "reason": "undeploy", }, ], } assert len(results["tasks"]) == 2, results
def test_import(self): foreign = ( """ apiVersion: %s kind: Manifest spec: instances: foreign: attributes: prop1: ok prop2: not-a-number """ % API_VERSION ) runner = CliRunner() with runner.isolated_filesystem(): with open("foreignmanifest.yaml", "w") as f: f.write(foreign) importer = ( """ apiVersion: %s kind: Manifest context: external: test: manifest: file: foreignmanifest.yaml instance: foreign # default is root # attributes: # queries into resource schema: # expected schema for attributes prop2: type: number prop3: type: string default: 'default' spec: instances: importer: service_template: topology_template: node_templates: importer: type: tosca.nodes.Root properties: test: eval: external: test mapped1: eval: external: test select: prop1 mapped2: eval: external: test select: prop2 mapped3: eval: external: test select: prop3 interfaces: Standard: create: ImportTest """ % API_VERSION ) manifest = YamlManifest(importer) root = manifest.getRootResource() importerResource = root.findResource("importer") # assert importing.attributes['test'] assert root.imports["test"] self.assertEqual(importerResource.attributes["mapped1"], "ok") with self.assertRaises(UnfurlValidationError) as err: importerResource.attributes["mapped2"] self.assertIn("schema validation failed", str(err.exception)) self.assertEqual(importerResource.attributes["mapped3"], "default") job = Runner(manifest).run(JobOptions(add=True, startTime="time-to-test")) assert job.status == Status.ok, job.summary()