Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FileVaultConfig resources to Terraform export #772

Merged
merged 1 commit into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions tests/mdm/test_setup_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from django.urls import reverse
from django.utils.crypto import get_random_string
from accounts.models import User
from .utils import force_artifact, force_blueprint, force_blueprint_artifact
from .utils import force_artifact, force_blueprint, force_blueprint_artifact, force_filevault_config


@override_settings(STATICFILES_STORAGE='django.contrib.staticfiles.storage.StaticFilesStorage')
Expand Down Expand Up @@ -81,7 +81,9 @@ def test_terraform_export_permission_denied(self):

def test_terraform_export(self):
self._login("mdm.view_blueprint")
blueprint = force_blueprint()
fv_config1 = force_filevault_config()
fv_config2 = force_filevault_config()
blueprint = force_blueprint(filevault_config=fv_config1)
required_artifact, (required_profile_av,) = force_artifact()
rprofile = required_profile_av.profile
rprofile_filename = f"{required_artifact.name.lower()}_{rprofile.pk}_v1.mobileconfig"
Expand All @@ -92,11 +94,24 @@ def test_terraform_export(self):
response = self.client.get(reverse("mdm:terraform_export"))
self.assertEqual(response.status_code, 200)
with zipfile.ZipFile(io.BytesIO(response.content), mode="r") as zf:
with zf.open("mdm_filevault_configs.tf") as fctf:
self.assertEqual(
fctf.read().decode("utf-8"),
f'resource "zentral_mdm_filevault_config" "filevaultconfig{fv_config1.pk}" {{\n'
f' name = "{fv_config1.name}"\n'
f' escrow_location_display_name = "{fv_config1.escrow_location_display_name}"\n'
'}\n\n'
f'resource "zentral_mdm_filevault_config" "filevaultconfig{fv_config2.pk}" {{\n'
f' name = "{fv_config2.name}"\n'
f' escrow_location_display_name = "{fv_config2.escrow_location_display_name}"\n'
'}\n\n'
)
with zf.open("mdm_blueprints.tf") as btf:
self.assertEqual(
btf.read().decode("utf-8"),
f'resource "zentral_mdm_blueprint" "blueprint{blueprint.pk}" {{\n'
f' name = "{blueprint.name}"\n'
f' name = "{blueprint.name}"\n'
f' filevault_config_id = zentral_mdm_filevault_config.filevaultconfig{fv_config1.pk}.id\n'
'}\n\n'
f'resource "zentral_mdm_blueprint_artifact" "blueprintartifact{blueprint_artifact.pk}" {{\n'
f' blueprint_id = zentral_mdm_blueprint.blueprint{blueprint.pk}.id\n'
Expand Down
43 changes: 41 additions & 2 deletions tests/mdm/test_terraform.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
from zentral.contrib.mdm.models import Artifact, Blueprint
from zentral.contrib.mdm.terraform import (ArtifactResource,
BlueprintResource, BlueprintArtifactResource,
FileVaultConfigResource,
ProfileResource)
from .utils import force_artifact, force_blueprint, force_blueprint_artifact
from .utils import force_artifact, force_blueprint, force_blueprint_artifact, force_filevault_config


class MDMTerraformTestCase(TestCase):
Expand Down Expand Up @@ -98,6 +99,42 @@ def test_profile_resource_full(self):
'}'
)

# FileVault config

def test_filevault_config_resource_defaults(self):
filevault_config = force_filevault_config()
resource = FileVaultConfigResource(filevault_config)
self.assertEqual(
resource.to_representation(),
f'resource "zentral_mdm_filevault_config" "filevaultconfig{filevault_config.pk}" {{\n'
f' name = "{filevault_config.name}"\n'
f' escrow_location_display_name = "{filevault_config.escrow_location_display_name}"\n'
'}'
)

def test_filevault_config_resource_full(self):
filevault_config = force_filevault_config()
filevault_config.at_login_only = True
filevault_config.bypass_attempts = 1
filevault_config.show_recovery_key = True
filevault_config.destroy_key_on_standby = True
filevault_config.prk_rotation_interval_days = 90
filevault_config.save()

resource = FileVaultConfigResource(filevault_config)
self.assertEqual(
resource.to_representation(),
f'resource "zentral_mdm_filevault_config" "filevaultconfig{filevault_config.pk}" {{\n'
f' name = "{filevault_config.name}"\n'
f' escrow_location_display_name = "{filevault_config.escrow_location_display_name}"\n'
' at_login_only = true\n'
' bypass_attempts = 1\n'
' show_recovery_key = true\n'
' destroy_key_on_standby = true\n'
' prk_rotation_interval_days = 90\n'
'}'
)

# blueprint

def test_blueprint_resource_defaults(self):
Expand All @@ -111,7 +148,8 @@ def test_blueprint_resource_defaults(self):
)

def test_blueprint_resource_full(self):
blueprint = force_blueprint()
filevault_config = force_filevault_config()
blueprint = force_blueprint(filevault_config=filevault_config)
blueprint.inventory_interval = 77777
blueprint.collect_apps = Blueprint.InventoryItemCollectionOption.MANAGED_ONLY
blueprint.collect_certificates = Blueprint.InventoryItemCollectionOption.ALL
Expand All @@ -126,6 +164,7 @@ def test_blueprint_resource_full(self):
' collect_apps = "MANAGED_ONLY"\n'
' collect_certificates = "ALL"\n'
' collect_profiles = "ALL"\n'
f' filevault_config_id = zentral_mdm_filevault_config.filevaultconfig{filevault_config.pk}.id\n'
'}'
)

Expand Down
30 changes: 25 additions & 5 deletions zentral/contrib/mdm/terraform.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .models import Artifact, Blueprint
from .models import Artifact, Blueprint, FileVaultConfig
from zentral.contrib.inventory.terraform import TagResource
from zentral.utils.terraform import BoolAttr, FileBase64Attr, IntAttr, MapAttr, RefAttr, Resource, StringAttr

Expand All @@ -18,6 +18,19 @@ class ArtifactResource(Resource):
requires = RefAttr("zentral.contrib.mdm.terraform.ArtifactResource", many=True, default=list)


class FileVaultConfigResource(Resource):
tf_type = "zentral_mdm_filevault_config"
tf_grouping_key = "mdm_filevault_configs"

name = StringAttr(required=True)
escrow_location_display_name = StringAttr(required=True)
at_login_only = BoolAttr(default=False)
bypass_attempts = IntAttr(default=-1)
show_recovery_key = BoolAttr(default=False)
destroy_key_on_standby = BoolAttr(default=False)
prk_rotation_interval_days = IntAttr(default=0)


class BlueprintResource(Resource):
tf_type = "zentral_mdm_blueprint"
tf_grouping_key = "mdm_blueprints"
Expand All @@ -30,6 +43,7 @@ class BlueprintResource(Resource):
source="get_collect_certificates_display")
collect_profiles = StringAttr(default=Blueprint.InventoryItemCollectionOption.NO.name,
source="get_collect_profiles_display")
filevault_config_id = RefAttr(FileVaultConfigResource)


# TODO: deduplicate Resource
Expand Down Expand Up @@ -92,13 +106,19 @@ def get_pk(self):


def iter_resources():
for blueprint in Blueprint.objects.prefetch_related("blueprintartifact_set__artifact",
"blueprintartifact_set__blueprint",
"blueprintartifact_set__excluded_tags",
"blueprintartifact_set__item_tags__tag").all():
for blueprint in (Blueprint.objects
.select_related("filevault_config")
.prefetch_related("blueprintartifact_set__artifact",
"blueprintartifact_set__blueprint",
"blueprintartifact_set__excluded_tags",
"blueprintartifact_set__item_tags__tag").all()):
yield BlueprintResource(blueprint)
if blueprint.filevault_config:
yield FileVaultConfigResource(blueprint.filevault_config)
for blueprint_artifact in blueprint.blueprintartifact_set.all():
yield BlueprintArtifactResource(blueprint_artifact)
for filevault_config in FileVaultConfig.objects.all():
yield FileVaultConfigResource(filevault_config)
for artifact in Artifact.objects.prefetch_related("requires").filter(type=Artifact.Type.PROFILE):
yield ArtifactResource(artifact)
for artifact_version in artifact.artifactversion_set.select_related("profile").order_by("-version"):
Expand Down