diff --git a/.gitignore b/.gitignore index 678b390..d64087a 100644 --- a/.gitignore +++ b/.gitignore @@ -159,3 +159,7 @@ override.tf.json # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan # example: *tfplan* + +# Ignore IDE configuration files +**/.idea/* +**/.vscode/* diff --git a/test/fixtures/plan_output.json b/test/fixtures/plan_output.json index 7eed0c8..65cbbcc 100644 --- a/test/fixtures/plan_output.json +++ b/test/fixtures/plan_output.json @@ -95,7 +95,25 @@ }, "prior_state": { "format_version": "0.1", - "terraform_version": "0.12.6" + "terraform_version": "0.12.6", + "values": { + "root_module": { + "resources": [ + { + "address": "data.google_client_config.current", + "mode": "data", + "type": "google_client_config", + "name": "current", + "provider_name": "registry.terraform.io/hashicorp/google", + "schema_version": 0, + "values": { + "description": "foo-value" + }, + "sensitive_values": {} + } + ] + } + } }, "configuration": { "provider_config": { diff --git a/test/fixtures/plan_output_no_prior.json b/test/fixtures/plan_output_no_prior.json new file mode 100644 index 0000000..79e826e --- /dev/null +++ b/test/fixtures/plan_output_no_prior.json @@ -0,0 +1,103 @@ +{ + "format_version": "0.1", + "terraform_version": "0.12.6", + "variables": { + "foo": { + "value": "bar" + } + }, + "planned_values": { + "outputs": { + "spam": { + "sensitive": false, + "value": "baz" + } + }, + "root_module": { + "resources": [ + { + "address": "spam.somespam", + "mode": "managed", + "type": "spam", + "name": "somespam", + "provider_name": "dummy", + "schema_version": 0, + "values": { + "spam-value": "spam" + } + } + ], + "child_modules": [ + { + "address": "module.parent", + "resources": [ + { + "address": "module.parent.foo.somefoo", + "type": "foo", + "name": "somefoo", + "provider_name": "dummy", + "values": { + "foo-value": "foo" + } + } + ], + "child_modules": [ + { + "address": "module.parent.module.child", + "resources": [ + { + "address": "module.parent.module.child.eggs.someeggs", + "type": "eggs", + "name": "someeggs", + "provider_name": "dummy", + "values": { + "eggs-value": "eggs" + } + } + ] + } + ] + } + ] + } + }, + "resource_changes": [ + { + "address": "module.resource-change.foo_resource.somefoo", + "module_address": "module.resource-change", + "mode": "managed", + "type": "foo-resource", + "name": "somefoo", + "provider_name": "dummy", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "foo": "foo-value" + }, + "after_unknown": { + "eggs": true + } + } + } + ], + "output_changes": { + "spam": { + "actions": [ + "create" + ], + "before": null, + "after": "bar", + "after_unknown": false + } + }, + "configuration": { + "provider_config": { + "google": { + "name": "google" + } + } + } +} \ No newline at end of file diff --git a/test/test_plan.py b/test/test_plan.py index 5f6eaa9..a509efd 100644 --- a/test/test_plan.py +++ b/test/test_plan.py @@ -4,7 +4,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, @@ -25,6 +25,13 @@ def plan_out(fixtures_dir): return tftest.TerraformPlanOutput(json.load(fp)) +@pytest.fixture(scope="module") +def plan_out_no_prior(fixtures_dir): + import json + with open('%s/plan_output_no_prior.json' % fixtures_dir) as fp: + return tftest.TerraformPlanOutput(json.load(fp)) + + def test_output_attributes(plan_out): assert plan_out.format_version == "0.1" assert plan_out.terraform_version == "0.12.6" @@ -86,3 +93,15 @@ def test_plan_stdout(fixtures_dir): tf = tftest.TerraformTest('plan_no_resource_changes', fixtures_dir) result = tf.plan(output=False) assert 'just_an_output = "Hello, plan!"' in result + + +def test_plan_prior_state(plan_out): + prior_resources = plan_out.prior_resources() + assert len(prior_resources) == 1 + assert prior_resources['data.google_client_config.current']['type'] == 'google_client_config' + assert prior_resources['data.google_client_config.current']['values']['description'] == 'foo-value' + + +def test_plan_no_prior_state(plan_out_no_prior): + prior_resources = plan_out_no_prior.prior_resources() + assert not prior_resources diff --git a/tftest.py b/tftest.py index a7767c7..0bdafd0 100644 --- a/tftest.py +++ b/tftest.py @@ -242,6 +242,9 @@ def __init__(self, raw): # there might be no variables defined self.variables = TerraformValueDict(raw.get('variables', {})) + prior_state = raw.get('prior_state', {}) + values = prior_state.get('values', {}) + self.prior_root_module = TerraformPlanModule(values.get('root_module', {})) @property def resources(self): return self.root_module.resources @@ -250,6 +253,9 @@ def resources(self): def modules(self): return self.root_module.child_modules + def prior_resources(self): + return self.prior_root_module.resources + def __getattr__(self, name): return self._raw[name]