├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── BUG_REPORT.md │ └── FEATURE_REQUEST.md ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml └── workflows │ ├── app-installers-maintenance.yml │ ├── auto-merge-dependabot.yml │ ├── code-check-and-tests.yaml │ ├── codeql.yaml │ ├── dependancy-review.yml │ ├── docker-build-push-integration-tests.yml │ ├── generate-docs.yml │ ├── golangci-lint.yml │ ├── gosec-scan.yml │ ├── jamfpro-provider-integration-test-new.yml │ ├── jamfpro-provider-nightly-test-cleanup.yaml │ ├── pr-title-validation.yml │ ├── provider-release.yml │ └── release-please.yml ├── .gitignore ├── .golangci.yml ├── .goreleaser.yml ├── .terraform-docs.yml ├── CHANGELOG.md ├── GNUmakefile ├── LICENSE ├── README.md ├── docker └── integration_tests ├── docs ├── data-sources │ ├── account.md │ ├── account_group.md │ ├── advanced_computer_search.md │ ├── advanced_mobile_device_search.md │ ├── advanced_user_search.md │ ├── api_integration.md │ ├── api_role.md │ ├── app_installer.md │ ├── building.md │ ├── category.md │ ├── cloud_distribution_point.md │ ├── cloud_idp.md │ ├── computer_extension_attribute.md │ ├── computer_inventory.md │ ├── computer_prestage_enrollment.md │ ├── department.md │ ├── device_enrollments.md │ ├── device_enrollments_public_key.md │ ├── disk_encryption_configuration.md │ ├── dock_item.md │ ├── file_share_distribution_point.md │ ├── jamf_cloud_distribution_service.md │ ├── ldap_server.md │ ├── macos_configuration_profile_plist.md │ ├── mobile_device_configuration_profile_plist.md │ ├── mobile_device_prestage_enrollment.md │ ├── network_segment.md │ ├── package.md │ ├── policy.md │ ├── printer.md │ ├── restricted_software.md │ ├── script.md │ ├── site.md │ ├── smart_computer_group.md │ ├── smart_mobile_device_group.md │ ├── sso_certificate.md │ ├── sso_failover.md │ ├── static_computer_group.md │ ├── static_mobile_device_group.md │ ├── user_group.md │ ├── volume_purchasing_locations.md │ └── webhook.md ├── index.md └── resources │ ├── account.md │ ├── account_driven_user_enrollment_settings.md │ ├── account_group.md │ ├── activation_code.md │ ├── advanced_computer_search.md │ ├── advanced_mobile_device_search.md │ ├── advanced_user_search.md │ ├── allowed_file_extension.md │ ├── api_integration.md │ ├── api_role.md │ ├── app_installer.md │ ├── app_installer_global_settings.md │ ├── building.md │ ├── category.md │ ├── client_checkin.md │ ├── cloud_ldap.md │ ├── computer_extension_attribute.md │ ├── computer_inventory_collection_settings.md │ ├── computer_prestage_enrollment.md │ ├── department.md │ ├── device_communication_settings.md │ ├── device_enrollments.md │ ├── disk_encryption_configuration.md │ ├── dock_item.md │ ├── engage_settings.md │ ├── enrollment_customization.md │ ├── file_share_distribution_point.md │ ├── icon.md │ ├── jamf_connect.md │ ├── jamf_protect.md │ ├── ldap_server.md │ ├── local_admin_password_settings.md │ ├── macos_configuration_profile_plist.md │ ├── macos_configuration_profile_plist_generator.md │ ├── managed_software_update.md │ ├── managed_software_update_feature_toggle.md │ ├── mobile_device_configuration_profile_plist.md │ ├── mobile_device_extension_attribute.md │ ├── mobile_device_prestage_enrollment.md │ ├── network_segment.md │ ├── package.md │ ├── policy.md │ ├── printer.md │ ├── restricted_software.md │ ├── script.md │ ├── self_service_settings.md │ ├── site.md │ ├── smart_computer_group.md │ ├── smart_mobile_device_group.md │ ├── smtp_server.md │ ├── sso_certificate.md │ ├── sso_failover.md │ ├── sso_settings.md │ ├── static_computer_group.md │ ├── static_mobile_device_group.md │ ├── user_group.md │ ├── user_initiated_enrollment_settings.md │ ├── volume_purchasing_locations.md │ └── webhook.md ├── examples ├── README.md ├── USAGE.md ├── data-sources │ ├── jamfpro_account │ │ └── data-source.tf │ ├── jamfpro_account_group │ │ └── data-source.tf │ ├── jamfpro_api_integration │ │ └── data-source.tf │ ├── jamfpro_api_role │ │ └── data-source.tf │ ├── jamfpro_building │ │ └── data-source.tf │ ├── jamfpro_category │ │ └── data-source.tf │ ├── jamfpro_cloud_distribution_point │ │ └── data_source.tf │ ├── jamfpro_cloud_idp │ │ └── resource.tf │ ├── jamfpro_computer_extension_attribute │ │ └── data-source.tf │ ├── jamfpro_department │ │ └── data-source.tf │ ├── jamfpro_device_enrollments │ │ └── data-source.tf │ ├── jamfpro_device_enrollments_public_key │ │ └── data-source.tf │ ├── jamfpro_disk_encryption_configuration │ │ └── data-source.tf │ ├── jamfpro_dock_item │ │ └── data-source.tf │ ├── jamfpro_file_share_distribution_point │ │ └── data-source.tf │ ├── jamfpro_jamf_cloud_distribution_service │ │ └── data_source.tf │ ├── jamfpro_ldap_server │ │ └── data-source.tf │ ├── jamfpro_macos_configuration_profile_plist │ │ └── data-source.tf │ ├── jamfpro_macos_configuration_profile_plist_generator │ │ └── data-source.tf │ ├── jamfpro_mobile_device_configuration_profile_plist │ │ └── data-source.tf │ ├── jamfpro_mobile_device_extension_attribute │ │ └── data-source.tf │ ├── jamfpro_mobile_device_prestage_enrollment │ │ └── data-source.tf │ ├── jamfpro_package │ │ └── data-source.tf │ ├── jamfpro_policy │ │ ├── data-source.tf │ │ ├── policy_all.tf │ │ ├── policy_dockitems.tf │ │ ├── policy_files_processes.tf │ │ ├── policy_local_accounts.tf │ │ ├── policy_maintainence.tf │ │ ├── policy_management_account.tf │ │ ├── policy_packages.tf │ │ ├── policy_printers.tf │ │ ├── policy_reboot.tf │ │ └── policy_scripts.tf │ ├── jamfpro_printer │ │ └── data-source.tf │ ├── jamfpro_restricted_software │ │ └── data-source.tf │ ├── jamfpro_script │ │ └── data-source.tf │ ├── jamfpro_site │ │ └── data-source.tf │ ├── jamfpro_smart_computer_group │ │ └── data-source.tf │ ├── jamfpro_smart_mobile_device_group │ │ └── data-source.tf │ ├── jamfpro_sso_certificate │ │ └── data_source.tf │ ├── jamfpro_sso_failover │ │ └── data-source.tf │ ├── jamfpro_static_computer_group │ │ └── data-source.tf │ ├── jamfpro_static_mobile_device_group │ │ └── data-source.tf │ ├── jamfpro_user_group │ │ └── data-source.tf │ ├── jamfpro_volume_purchasing_locations │ │ └── data-source.tf │ └── jamfpro_webhook │ │ └── data-source.tf ├── provider │ └── provider.tf └── resources │ ├── jamfpro_account │ └── resource.tf │ ├── jamfpro_account_driven_user_enrollment_settings │ └── resource.tf │ ├── jamfpro_account_group │ └── resource.tf │ ├── jamfpro_activation_code │ └── resource.tf │ ├── jamfpro_advanced_computer_search │ └── resource.tf │ ├── jamfpro_advanced_mobile_device_search │ └── resource.tf │ ├── jamfpro_advanced_user_search │ └── resource.tf │ ├── jamfpro_allowed_file_extension │ └── resource.tf │ ├── jamfpro_api_integration │ └── resource.tf │ ├── jamfpro_api_role │ └── resource.tf │ ├── jamfpro_app_installer │ └── resource.tf │ ├── jamfpro_app_installer_global_settings │ └── resource.tf │ ├── jamfpro_building │ └── resource.tf │ ├── jamfpro_category │ └── resource.tf │ ├── jamfpro_client_checkin │ └── resource.tf │ ├── jamfpro_cloud_ldap │ └── resource.tf │ ├── jamfpro_computer_extension_attribute │ └── resource.tf │ ├── jamfpro_computer_inventory_collection_settings │ └── resource.tf │ ├── jamfpro_computer_prestage_enrollment │ └── resource.tf │ ├── jamfpro_department │ └── resource.tf │ ├── jamfpro_device_communication_settings │ └── resource.tf │ ├── jamfpro_device_enrollments │ └── resource.tf │ ├── jamfpro_disk_encryption_configuration │ └── resource.tf │ ├── jamfpro_dock_item │ └── resource.tf │ ├── jamfpro_engage_settings │ └── resource.tf │ ├── jamfpro_enrollment_customization │ └── resource.tf │ ├── jamfpro_file_share_distribution_point │ └── resource.tf │ ├── jamfpro_icon │ └── resource.tf │ ├── jamfpro_jamf_connect │ └── resource.tf │ ├── jamfpro_jamf_protect │ └── resource.tf │ ├── jamfpro_ldap_server │ └── resource.tf │ ├── jamfpro_local_admin_password_settings │ └── resource.tf │ ├── jamfpro_macos_configuration_profile_plist │ └── resource.tf │ ├── jamfpro_macos_configuration_profile_plist_generator │ └── resource.tf │ ├── jamfpro_managed_software_update_feature_toggle │ └── resource.tf │ ├── jamfpro_managed_software_updates │ └── resource.tf │ ├── jamfpro_mobile_device_configuration_profile_plist │ └── resource.tf │ ├── jamfpro_mobile_device_extension_attribute │ └── resource.tf │ ├── jamfpro_mobile_device_prestage_enrollment │ └── resource.tf │ ├── jamfpro_network_segment │ └── resource.tf │ ├── jamfpro_package │ └── resource.tf │ ├── jamfpro_policy │ └── resource.tf │ ├── jamfpro_printer │ └── resource.tf │ ├── jamfpro_restricted_software │ └── resource.tf │ ├── jamfpro_script │ └── resource.tf │ ├── jamfpro_self_service_settings │ └── resource.tf │ ├── jamfpro_site │ └── resource.tf │ ├── jamfpro_smart_computer_group │ └── resource.tf │ ├── jamfpro_smart_mobile_device_group │ └── resource.tf │ ├── jamfpro_smtp_server │ └── resource.tf │ ├── jamfpro_sso_certificate │ └── resource.tf │ ├── jamfpro_sso_failover │ └── resource.tf │ ├── jamfpro_sso_settings │ └── resource.tf │ ├── jamfpro_static_computer_group │ └── resource.tf │ ├── jamfpro_static_mobile_device_group │ └── resource.tf │ ├── jamfpro_user_group │ └── resource.tf │ ├── jamfpro_user_initiated_enrollment_settings │ └── resource.tf │ ├── jamfpro_volume_purchasing_locations │ └── resource.tf │ └── jamfpro_webhook │ └── resource.tf ├── go.mod ├── go.sum ├── internal ├── provider │ ├── provider.go │ └── timeouts.go └── resources │ ├── account │ ├── constructor.go │ ├── crud.go │ ├── data_customdiff.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── account_driven_user_enrollment_settings │ ├── constructor.go │ ├── crud.go │ ├── resource.go │ └── state.go │ ├── account_group │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── helpers.go │ ├── resource.go │ └── state.go │ ├── activation_code │ ├── constructor.go │ ├── crud.go │ ├── resource.go │ └── state.go │ ├── advanced_computer_search │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── advanced_mobile_device_search │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── advanced_user_search │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── allowed_file_extension │ ├── constructor.go │ ├── crud.go │ ├── resource.go │ └── state.go │ ├── api_integration │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── helpers.go │ ├── resource.go │ └── state.go │ ├── api_role │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── app_installer │ ├── app_catalog_app_installer_titles.json │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validation.go │ ├── helpers.go │ ├── resource.go │ └── state.go │ ├── app_installer_global_settings │ ├── constructor.go │ ├── crud.go │ ├── resource.go │ └── state.go │ ├── building │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── category │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── client_checkin │ ├── constructor.go │ ├── crud.go │ ├── data_validation.go │ ├── resource.go │ └── state.go │ ├── cloud_distribution_point │ └── data_source.go │ ├── cloud_ldap │ ├── constructor.go │ ├── crud.go │ ├── resource.go │ └── state.go │ ├── cloudidp │ ├── data_source.go │ └── state.go │ ├── common │ ├── configurationprofiles │ │ ├── datavalidators │ │ │ └── helpers.go │ │ └── plist │ │ │ ├── conversion-backup.go │ │ │ ├── conversion.go │ │ │ ├── diff_suppresion_test.go │ │ │ ├── diff_suppression.go │ │ │ ├── normalize_payload.go │ │ │ ├── shared.go │ │ │ ├── shared_test.go │ │ │ ├── test │ │ │ ├── encode │ │ │ │ └── encode.go │ │ │ ├── plistsanitizefortfstate │ │ │ │ └── plistsanitizefortfstate.go │ │ │ ├── removekeys │ │ │ │ └── removekeys.go │ │ │ └── sortkeys │ │ │ │ └── sortkeys.go │ │ │ ├── uuid_handling.go │ │ │ └── validate.go │ ├── constructors │ │ ├── helpers.go │ │ └── helpers_test.go │ ├── crud.go │ ├── file_handling.go │ ├── hash.go │ ├── image_resize.go │ ├── jamfprivileges │ │ ├── find_similar.go │ │ └── validate_account_privileges.go │ ├── redeployment.go │ ├── serialize_and_redact.go │ └── sharedschemas │ │ ├── category.go │ │ ├── computerscope.go │ │ ├── constructors.go │ │ ├── mobiledevicescope.go │ │ ├── site.go │ │ └── utilities.go │ ├── computer_extension_attribute │ ├── contructor.go │ ├── crud.go │ ├── data_source.go │ ├── diff_suppress.go │ ├── helpers.go │ ├── resource.go │ ├── state.go │ └── state_migration.go │ ├── computer_inventory_collection_settings │ ├── constructor.go │ ├── crud.go │ ├── resource.go │ └── state.go │ ├── computer_prestage_enrollment │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validator.go │ ├── resource.go │ └── state.go │ ├── computerinventory │ └── data_source.go │ ├── department │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── device_communication_settings │ ├── constructor.go │ ├── crud.go │ ├── resource.go │ └── state.go │ ├── device_enrollments │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── deviceenrollmentspublickey │ └── data_source.go │ ├── disk_encryption_configuration │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── dock_item │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── engage_settings │ ├── constructor.go │ ├── crud.go │ ├── resource.go │ └── state.go │ ├── enrollment_customization │ ├── construct.go │ ├── crud.go │ ├── data_validation.go │ ├── resource.go │ └── state.go │ ├── file_share_distribution_point │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validation.go │ ├── resource.go │ └── state.go │ ├── icon │ ├── constructor.go │ ├── crud.go │ ├── data_validate.go │ ├── resource.go │ └── state.go │ ├── jamf_cloud_distribution_service │ └── data_source.go │ ├── jamf_connect │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── jamf_protect │ ├── constructor.go │ ├── crud.go │ ├── resource.go │ └── state.go │ ├── ldap_server │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── local_admin_password_settings │ ├── constructor.go │ ├── crud.go │ ├── resource.go │ └── state.go │ ├── macos_configuration_profile_plist │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validator.go │ ├── helpers.go │ ├── payload_diff_suppress.go │ ├── payload_diff_suppress_test.go │ ├── resource.go │ └── state.go │ ├── macos_configuration_profile_plist_generator │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validator.go │ ├── diff_suppress.go │ ├── helpers.go │ ├── resource.go │ └── state.go │ ├── managed_software_update │ ├── constructor.go │ ├── crud.go │ ├── data_validator.go │ ├── helper.go │ ├── resource.go │ └── state.go │ ├── managed_software_update_feature_toggle │ ├── constructor.go │ ├── crud.go │ ├── resource.go │ └── state.go │ ├── mobile_device_configuration_profile_plist │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validator.go │ ├── payload_diff_suppress.go │ ├── resource.go │ └── state.go │ ├── mobile_device_extension_attribute │ ├── contructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validator.go │ ├── diff_suppress.go │ ├── resource.go │ └── state.go │ ├── mobile_device_prestage_enrollment │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validator.go │ ├── resource.go │ └── state.go │ ├── network_segment │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── package │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validator.go │ ├── helpers.go │ ├── resource.go │ └── state.go │ ├── policy │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validator.go │ ├── resource.go │ ├── schema_account_maintenance.go │ ├── schema_date_time_limitations.go │ ├── schema_disk_encryption.go │ ├── schema_dockitems.go │ ├── schema_files_processes.go │ ├── schema_maintenance.go │ ├── schema_network_limitations.go │ ├── schema_package_configuration.go │ ├── schema_payloads.go │ ├── schema_printer.go │ ├── schema_reboot.go │ ├── schema_script.go │ ├── schema_self_service.go │ ├── schema_user_interaction.go │ ├── state.go │ ├── state_general.go │ ├── state_migration.go │ ├── state_payloads.go │ ├── state_scope.go │ └── state_self_service.go │ ├── printer │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validator.go │ ├── resource.go │ └── state.go │ ├── restricted_software │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── script │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── self_service_settings │ ├── constructor.go │ ├── crud.go │ ├── resource.go │ └── state.go │ ├── site │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── smart_computer_group │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validator.go │ ├── resource.go │ └── state.go │ ├── smart_mobile_device_group │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validator.go │ ├── resource.go │ └── state.go │ ├── smtp_server │ ├── constructor.go │ ├── crud.go │ ├── data_validator.go │ ├── resource.go │ └── state.go │ ├── sso_certificate │ ├── crud.go │ ├── data_source.go │ ├── helpers.go │ ├── resource.go │ └── state.go │ ├── sso_failover │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ ├── sso_settings │ ├── constructor.go │ ├── crud.go │ ├── data_validator.go │ ├── resource.go │ └── state.go │ ├── static_computer_group │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validator.go │ ├── resource.go │ └── state.go │ ├── static_mobile_device_group │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validator.go │ ├── resource.go │ └── state.go │ ├── user_group │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validator.go │ ├── resource.go │ └── state.go │ ├── userinitiatedenrollment │ ├── constructor.go │ ├── crud.go │ ├── data_validator.go │ ├── helpers.go │ ├── resource.go │ └── state.go │ ├── volume_purchasing_locations │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── resource.go │ └── state.go │ └── webhook │ ├── constructor.go │ ├── crud.go │ ├── data_source.go │ ├── data_validator.go │ ├── resource.go │ └── state.go ├── main.go ├── scripts ├── check_pr_name.py ├── errcheck.sh ├── gofmtcheck.sh └── maintainence │ ├── GetJamfAPIPrivileges │ └── GetJamfAPIPrivileges.go │ ├── GetJamfAppCatalogAppInstallerTitles │ └── GetJamfAppCatalogAppInstallerTitles.go │ └── GetUserAccountPrivileges │ └── GetUserAccountPrivileges.go ├── templates ├── data-sources.md.tmpl ├── index.md.tmpl └── resources.md.tmpl ├── terraform-provider-jamfpro ├── terraform-registry-manifest.json ├── testing ├── README.md ├── action_scripts │ ├── cleanup.py │ ├── generate_test_directory.py │ ├── generate_test_targets.py │ ├── infinite_diff_check.sh │ ├── requirements.txt │ ├── scaffolding_static_group_computers.py │ └── start_test.sh ├── local │ ├── cleanup.sh │ └── run_local.sh ├── payloads │ ├── jamfpro_building │ │ ├── buildings.tf │ │ └── provider.tf │ ├── jamfpro_category │ │ ├── categories.tf │ │ └── provider.tf │ ├── jamfpro_computer_extension_attribute │ │ ├── computer_extension_attributes.tf │ │ └── provider.tf │ ├── jamfpro_department │ │ ├── departments.tf │ │ └── provider.tf │ ├── jamfpro_script │ │ ├── provider.tf │ │ └── scripts.tf │ └── jamfpro_static_computer_group │ │ ├── provider.tf │ │ └── static_computer_groups.tf ├── provider.tf └── testing │ └── accounts │ └── provider.tf └── tools └── tools.go /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # See for instructions on this file 2 | 3 | # These owners will be the default owners for everything in 4 | # the repo. Unless a later match takes precedence, 5 | # @global-owner1 and @global-owner2 will be requested for 6 | # review when someone opens a pull request. 7 | 8 | * @ShocOne 9 | 10 | .azuredevops/** @ShocOne 11 | .github/** @ShocOne 12 | .pipelines/** @ShocOne 13 | 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Feature request 🚀" 3 | about: Suggest an idea or improvement for this project 4 | title: 'Feature Request: [Short Description of Feature]' 5 | labels: feature 6 | assignees: '' 7 | --- 8 | 9 | 10 | 11 | ## Description 12 | 13 | Provide a clear and concise description of the feature or improvement you are requesting. Explain why this feature is important and how it would benefit users. 14 | 15 | ### Proposed Solution 16 | 17 | Describe how you think the feature should work. Include any details that might help in understanding the implementation. 18 | 19 | ### Use Case 20 | 21 | Explain the use case(s) for this feature. Why do you need it? How will it be used? 22 | 23 | ### Alternatives Considered 24 | 25 | If applicable, list any alternative solutions or features you have considered. Explain why these alternatives are not sufficient. 26 | 27 | ### Additional Context 28 | 29 | Add any other context, screenshots, or details that would help understand your request better. 30 | 31 | ### Priority 32 | 33 | How important is this feature to you? Choose one of the following: 34 | 35 | - Low (Nice to have, but not critical) 36 | - Medium (Important but not urgent) 37 | - High (Urgent, needs to be prioritized) 38 | 39 | ### Related Issues 40 | 41 | If this feature request is related to other issues or feature requests, please link them here. -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # See GitHub's documentation for more information on this file: 2 | # https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/configuration-options-for-dependency-updates 3 | version: 2 4 | updates: 5 | # Maintain dependencies for GitHub Actions 6 | - package-ecosystem: "github-actions" 7 | directory: "/" 8 | schedule: 9 | # Check for updates to GitHub Actions every week 10 | interval: "weekly" 11 | 12 | # Maintain dependencies for Go modules 13 | - package-ecosystem: "gomod" 14 | directory: "/" 15 | schedule: 16 | # Check for updates to Go modules every week 17 | interval: "weekly" -------------------------------------------------------------------------------- /.github/workflows/auto-merge-dependabot.yml: -------------------------------------------------------------------------------- 1 | name: Auto-Merge Dependabot 2 | 3 | on: 4 | pull_request: 5 | 6 | jobs: 7 | auto-merge: 8 | name: '🤖 Auto-Merge Dependabot' 9 | runs-on: ubuntu-latest 10 | if: github.actor == 'dependabot[bot]' 11 | steps: 12 | 13 | - name: Harden Runner 14 | uses: step-security/harden-runner@v2.12.0 15 | with: 16 | egress-policy: audit 17 | 18 | - uses: actions/checkout@v4.2.2 19 | with: 20 | fetch-depth: 0 21 | 22 | - uses: ahmadnassri/action-dependabot-auto-merge@v2.6.6 23 | with: 24 | target: minor 25 | github-token: ${{ secrets.DEPENDABOT_PAT }} -------------------------------------------------------------------------------- /.github/workflows/dependancy-review.yml: -------------------------------------------------------------------------------- 1 | name: 'Dependency Review' 2 | on: [pull_request] 3 | 4 | permissions: 5 | contents: read 6 | 7 | jobs: 8 | dependency-review: 9 | name: '🔎 Dependency Review' 10 | runs-on: ubuntu-latest 11 | steps: 12 | 13 | - name: Harden Runner 14 | uses: step-security/harden-runner@v2.12.0 15 | with: 16 | egress-policy: audit 17 | 18 | - name: 'Checkout Repository' 19 | uses: actions/checkout@v4.2.2 20 | with: 21 | fetch-depth: 0 22 | 23 | - name: 'Dependency Review' 24 | uses: actions/dependency-review-action@v4 -------------------------------------------------------------------------------- /.github/workflows/docker-build-push-integration-tests.yml: -------------------------------------------------------------------------------- 1 | name: Manual | Build New Python Docker Image | Integration Tests 2 | run-name: "Build New Python Docker Image | Integration Tests" 3 | 4 | on: 5 | workflow_dispatch: 6 | inputs: 7 | go_version: 8 | description: 'Go version to use' 9 | default: '1.24.0' 10 | required: false 11 | type: string 12 | terraform_version: 13 | description: 'Terraform version to use' 14 | default: '1.12.0' 15 | required: false 16 | type: string 17 | 18 | jobs: 19 | build-and-push: 20 | runs-on: ubuntu-latest 21 | steps: 22 | - uses: actions/checkout@v4 23 | 24 | - name: Login to GitHub Container Registry 25 | uses: docker/login-action@v3 26 | with: 27 | registry: ghcr.io 28 | username: ${{ github.actor }} 29 | password: ${{ secrets.GITHUB_TOKEN }} 30 | 31 | - name: Build and push 32 | uses: docker/build-push-action@v6 33 | with: 34 | context: . 35 | file: ./docker/integration_tests 36 | push: true 37 | tags: | 38 | ghcr.io/${{ github.repository }}/provider_testing:latest 39 | ghcr.io/${{ github.repository }}/provider_testing:${{ github.sha }} -------------------------------------------------------------------------------- /.github/workflows/golangci-lint.yml: -------------------------------------------------------------------------------- 1 | name: golangci-lint 2 | on: 3 | pull_request: 4 | branches: [main] 5 | 6 | permissions: 7 | contents: read 8 | 9 | jobs: 10 | golangci: 11 | name: lint 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | 16 | 17 | - uses: actions/setup-go@v5 18 | with: 19 | go-version: stable 20 | - name: golangci-lint 21 | uses: golangci/golangci-lint-action@v8 22 | with: 23 | version: v2.1 24 | only-new-issues: true -------------------------------------------------------------------------------- /.github/workflows/gosec-scan.yml: -------------------------------------------------------------------------------- 1 | name: "Code Scanning" 2 | 3 | # Run workflow each time code is pushed to your repository and on a schedule. 4 | # The scheduled workflow runs every at 00:00 on Sunday UTC time. 5 | on: 6 | push: 7 | branches: [ "main" ] 8 | pull_request: 9 | branches: [ "main" ] 10 | schedule: 11 | - cron: '0 0 * * 0' 12 | 13 | jobs: 14 | scan: 15 | name: '🛡️ Security Vulnerability Scan' 16 | runs-on: ubuntu-latest 17 | env: 18 | GO111MODULE: on 19 | steps: 20 | - name: Harden Runner 21 | uses: step-security/harden-runner@v2.12.0 22 | with: 23 | egress-policy: audit 24 | 25 | - uses: actions/checkout@v4.2.2 26 | with: 27 | fetch-depth: 0 28 | 29 | - name: Run Gosec Security Scanner 30 | uses: securego/gosec@v2.22.4 31 | with: 32 | # we let the report trigger content trigger a failure using the GitHub Security features. 33 | args: '-no-fail -fmt sarif -out results.sarif ./...' 34 | 35 | - name: Upload SARIF file 36 | uses: github/codeql-action/upload-sarif@v3 37 | with: 38 | # Path to SARIF file relative to the root of the repository 39 | sarif_file: results.sarif -------------------------------------------------------------------------------- /.github/workflows/jamfpro-provider-nightly-test-cleanup.yaml: -------------------------------------------------------------------------------- 1 | name: "Terraform Test Object Nightly Cleanup" 2 | run-name: "Terraform Test Object Nightly Cleanup" 3 | on: 4 | schedule: 5 | - cron: '59 23 * * *' 6 | workflow_dispatch: 7 | 8 | 9 | jobs: 10 | Run-Nightly-Cleanup: 11 | environment: provider-integration-testing-internal 12 | runs-on: ubuntu-latest 13 | env: 14 | CLIENT_ID: ${{ secrets.TESTING_CLIENT_ID }} 15 | CLIENT_SEC: ${{ secrets.TESTING_CLIENT_SECRET }} 16 | 17 | steps: 18 | - name: Checkout Terraform Repository 19 | uses: actions/checkout@v4 20 | with: 21 | repository: deploymenttheory/terraform-provider-jamfpro 22 | ref: main 23 | path: terraform-provider-jamfpro 24 | 25 | - name: Set up Python 26 | uses: actions/setup-python@v5.6.0 27 | 28 | - name: Set up Python Environment 29 | run: | 30 | pip install -r ./terraform-provider-jamfpro/testing/requirements.txt 31 | 32 | - name: Run full cleanup 33 | run: | 34 | cd ./terraform-provider-jamfpro/testing/jamfpy 35 | python clean_up.py -f -------------------------------------------------------------------------------- /.github/workflows/release-please.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | 6 | permissions: 7 | contents: write 8 | pull-requests: write 9 | 10 | name: release-please 11 | 12 | jobs: 13 | release-please: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/create-github-app-token@v2 17 | id: app-token 18 | with: 19 | app-id: ${{ vars.RP_APP_ID }} 20 | private-key: ${{ secrets.RP_APP_PRIVATE_KEY }} 21 | 22 | - uses: googleapis/release-please-action@v4 23 | with: 24 | token: ${{ steps.app-token.outputs.token }} 25 | release-type: terraform-module -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.dll 2 | *.exe 3 | .DS_Store 4 | example.tf 5 | terraform.tfplan 6 | terraform.tfstate 7 | bin/ 8 | dist/ 9 | modules-dev/ 10 | /pkg/ 11 | website/.vagrant 12 | website/.bundle 13 | website/build 14 | website/node_modules 15 | .vagrant/ 16 | *.backup 17 | ./*.tfstate 18 | .terraform/ 19 | *.log 20 | *.bak 21 | *~ 22 | .*.swp 23 | .idea 24 | *.iml 25 | *.test 26 | *.iml 27 | 28 | website/vendor 29 | 30 | # Test exclusions 31 | !command/test-fixtures/**/*.tfstate 32 | !command/test-fixtures/**/.terraform/ 33 | 34 | # Keep windows files with windows line endings 35 | *.winfile eol=crlf 36 | 37 | # local testing 38 | *auth.json 39 | .localtesting/ 40 | *terraform.tfvars 41 | .env 42 | 43 | *.venv 44 | testing/data_sources/* 45 | .terraform.lock.hcl 46 | golangci-lint-report.sarif 47 | -------------------------------------------------------------------------------- /.terraform-docs.yml: -------------------------------------------------------------------------------- 1 | formatter: markdown table 2 | sections: 3 | hide-all: true 4 | show: 5 | - inputs 6 | sort: 7 | enabled: true 8 | by: required 9 | settings: 10 | indent: 3 -------------------------------------------------------------------------------- /GNUmakefile: -------------------------------------------------------------------------------- 1 | DEV := deploymenttheory 2 | PROVIDER := jamfpro 3 | VERSION := $(shell git describe --abbrev=0 --tags --match "v*") 4 | PLUGINS := ${HOME}/bin/plugins/registry.terraform.io/${DEV}/${PROVIDER} 5 | BIN := terraform-provider-jamfpro_${VERSION} 6 | 7 | define TERRAFORMRC 8 | 9 | add the following config to ~/.terraformrc to enable override: 10 | ``` 11 | provider_installation { 12 | dev_overrides { 13 | "${DEV}/${PROVIDER}" = "${PLUGINS}" 14 | } 15 | } 16 | ``` 17 | endef 18 | 19 | default: testacc 20 | 21 | # Run acceptance tests 22 | .PHONY: testacc 23 | testacc: 24 | TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m 25 | 26 | # Run go build. Output to dist/. 27 | .PHONY: build 28 | build: 29 | @mkdir -p dist 30 | go build -o dist/${BIN} . 31 | 32 | # Run go build. Output to dist/. 33 | .PHONY: build_override 34 | build_override: build 35 | mkdir -p ${PLUGINS} 36 | mv dist/${BIN} ${PLUGINS}/${BIN} 37 | 38 | # Run go build. Move artifact to terraform plugins dir. Output override config for ~/.terraformrc 39 | .PHONY: install 40 | install: build_override 41 | $(info ${TERRAFORMRC}) 42 | -------------------------------------------------------------------------------- /docker/integration_tests: -------------------------------------------------------------------------------- 1 | FROM python:3.11-slim 2 | 3 | ARG GO_VERSION=1.24.0 4 | ARG TERRAFORM_VERSION=1.12.0 5 | 6 | ENV PATH="/usr/local/go/bin:$PATH" 7 | ENV GOPATH=/go 8 | ENV GOMODCACHE=/go/pkg/mod 9 | ENV PYTHONUNBUFFERED=1 10 | 11 | WORKDIR /app 12 | 13 | 14 | 15 | COPY ./testing/requirements.txt . 16 | 17 | RUN set -eux; \ 18 | apt-get update && \ 19 | apt-get install -y --no-install-recommends \ 20 | wget unzip git ca-certificates uuid-runtime && \ 21 | \ 22 | # Go 23 | wget -q https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz && \ 24 | tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz && \ 25 | rm go${GO_VERSION}.linux-amd64.tar.gz && \ 26 | \ 27 | # Terraform 28 | wget -q https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip && \ 29 | unzip -q terraform_${TERRAFORM_VERSION}_linux_amd64.zip -d /usr/local/bin && \ 30 | rm terraform_${TERRAFORM_VERSION}_linux_amd64.zip && \ 31 | \ 32 | # Python reqs 33 | pip install --no-cache-dir -r requirements.txt && \ 34 | \ 35 | # Clean up 36 | apt-get clean && \ 37 | rm -rf /var/lib/apt/lists/* 38 | 39 | COPY go.* . 40 | RUN go mod download -x -------------------------------------------------------------------------------- /docs/data-sources/account.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_account" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_account (Data Source) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | data "jamfpro_account" "jamfpro_account_001_data" { 13 | id = jamfpro_account.jamfpro_account_001.id 14 | } 15 | 16 | output "jamfpro_account_001_data_id" { 17 | value = data.jamfpro_account.jamfpro_account_001_data.id 18 | } 19 | 20 | output "jamfpro_account_001_data_name" { 21 | value = data.jamfpro_account.jamfpro_account_001_data.name 22 | } 23 | ``` 24 | 25 | 26 | ## Schema 27 | 28 | ### Required 29 | 30 | - `id` (String) The unique identifier of the jamf pro account. 31 | 32 | ### Optional 33 | 34 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 35 | 36 | ### Read-Only 37 | 38 | - `name` (String) The name of the jamf pro account. 39 | 40 | 41 | ### Nested Schema for `timeouts` 42 | 43 | Optional: 44 | 45 | - `read` (String) -------------------------------------------------------------------------------- /docs/data-sources/account_group.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_account_group" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_account_group (Data Source) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | data "jamfpro_account_group" "jamfpro_account_group_001_data" { 13 | id = jamfpro_account_group.jamfpro_account_group_001.id 14 | } 15 | 16 | output "jamfpro_jamfpro_account_group_001_id" { 17 | value = data.jamfpro_account_group.jamfpro_account_group_001_data.id 18 | } 19 | 20 | output "jamfpro_jamfpro_account_groups_001_name" { 21 | value = data.jamfpro_account_group.jamfpro_account_group_001_data.name 22 | } 23 | ``` 24 | 25 | 26 | ## Schema 27 | 28 | ### Required 29 | 30 | - `id` (String) The unique identifier of the account group. 31 | 32 | ### Optional 33 | 34 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 35 | 36 | ### Read-Only 37 | 38 | - `name` (String) The name of the account group. 39 | 40 | 41 | ### Nested Schema for `timeouts` 42 | 43 | Optional: 44 | 45 | - `read` (String) -------------------------------------------------------------------------------- /docs/data-sources/advanced_computer_search.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_advanced_computer_search" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_advanced_computer_search (Data Source) 8 | 9 | 10 | 11 | ## Schema 12 | 13 | ### Required 14 | 15 | - `id` (String) The unique identifier of the API integration. 16 | 17 | ### Read-Only 18 | 19 | - `name` (String) The unique name of the advanced computer search. -------------------------------------------------------------------------------- /docs/data-sources/advanced_mobile_device_search.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_advanced_mobile_device_search" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_advanced_mobile_device_search (Data Source) 8 | 9 | 10 | 11 | ## Schema 12 | 13 | ### Required 14 | 15 | - `id` (String) The unique identifier of the API integration. 16 | 17 | ### Read-Only 18 | 19 | - `name` (String) The unique name of the advanced mobile user search. -------------------------------------------------------------------------------- /docs/data-sources/advanced_user_search.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_advanced_user_search" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_advanced_user_search (Data Source) 8 | 9 | 10 | 11 | ## Schema 12 | 13 | ### Required 14 | 15 | - `id` (String) The unique identifier of the API integration. 16 | 17 | ### Read-Only 18 | 19 | - `name` (String) The unique name of the advanced mobile user search. -------------------------------------------------------------------------------- /docs/data-sources/api_integration.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_api_integration" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_api_integration (Data Source) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | data "jamfpro_api_integration" "jamfpro_api_integration_001_data" { 13 | id = jamfpro_api_integration.jamfpro_api_integration_001.id 14 | } 15 | 16 | output "jamfpro_api_integration_001_data_id" { 17 | value = data.jamfpro_api_integration.jamfpro_api_integration_001_data.id 18 | } 19 | 20 | output "jamfpro_api_integration_001_data_name" { 21 | value = data.jamfpro_api_integration.jamfpro_api_integration_001_data.name 22 | } 23 | ``` 24 | 25 | 26 | ## Schema 27 | 28 | ### Required 29 | 30 | - `id` (String) The unique identifier of the API integration. 31 | 32 | ### Read-Only 33 | 34 | - `client_id` (String) client id 35 | - `client_secret` (String) client secret 36 | - `display_name` (String) The display name of the API integration. -------------------------------------------------------------------------------- /docs/data-sources/category.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_category" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_category (Data Source) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | # Example 1: Look up by ID 13 | data "jamfpro_category" "by_id" { 14 | id = "1" 15 | } 16 | 17 | # Example 2: Look up by name 18 | data "jamfpro_category" "by_name" { 19 | name = "Applications" 20 | } 21 | 22 | # Example 3: Using variables 23 | variable "category_name" { 24 | type = string 25 | description = "Category to look up" 26 | default = "Applications" 27 | } 28 | 29 | data "jamfpro_category" "dynamic" { 30 | name = var.category_name 31 | } 32 | 33 | # Output examples 34 | output "category_details" { 35 | value = { 36 | id = data.jamfpro_category.by_name.id 37 | name = data.jamfpro_category.by_name.name 38 | priority = data.jamfpro_category.by_name.priority 39 | } 40 | } 41 | 42 | # Example 4: Using in another resource 43 | resource "jamfpro_policy" "app_policy" { 44 | name = "Application Install Policy" 45 | category_id = data.jamfpro_category.by_name.id 46 | } 47 | ``` 48 | 49 | 50 | ## Schema 51 | 52 | ### Optional 53 | 54 | - `id` (String) The unique identifier of the category. 55 | - `name` (String) The unique name of the category. 56 | 57 | ### Read-Only 58 | 59 | - `priority` (Number) The priority of the category. -------------------------------------------------------------------------------- /docs/data-sources/cloud_idp.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_cloud_idp" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_cloud_idp (Data Source) 8 | 9 | 10 | 11 | ## Schema 12 | 13 | ### Optional 14 | 15 | - `display_name` (String) The display name of the cloud identity provider. 16 | - `id` (String) The jamf pro unique identifier of the cloud identity provider. 17 | 18 | ### Read-Only 19 | 20 | - `enabled` (Boolean) Whether the cloud identity provider is enabled. 21 | - `provider_name` (String) The name of the cloud identity provider. e.g AZURE -------------------------------------------------------------------------------- /docs/data-sources/computer_prestage_enrollment.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_computer_prestage_enrollment" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_computer_prestage_enrollment (Data Source) 8 | 9 | 10 | 11 | ## Schema 12 | 13 | ### Required 14 | 15 | - `display_name` (String) The display name of the computer prestage. 16 | - `id` (String) The unique identifier of the computer prestage. 17 | 18 | ### Optional 19 | 20 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 21 | 22 | 23 | ### Nested Schema for `timeouts` 24 | 25 | Optional: 26 | 27 | - `read` (String) -------------------------------------------------------------------------------- /docs/data-sources/department.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_department" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_department (Data Source) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | # Create department resource 13 | resource "jamfpro_department" "test" { 14 | name = "Engineering" 15 | } 16 | 17 | # Test data source by ID 18 | data "jamfpro_department" "test_by_id" { 19 | id = jamfpro_department.test.id 20 | } 21 | 22 | # Test data source by name 23 | data "jamfpro_department" "test_by_name" { 24 | name = jamfpro_department.test.name 25 | } 26 | 27 | # Outputs to verify 28 | output "department_by_id" { 29 | value = { 30 | id = data.jamfpro_department.test_by_id.id 31 | name = data.jamfpro_department.test_by_id.name 32 | } 33 | } 34 | 35 | output "department_by_name" { 36 | value = { 37 | id = data.jamfpro_department.test_by_name.id 38 | name = data.jamfpro_department.test_by_name.name 39 | } 40 | } 41 | 42 | # Validation 43 | output "matching_ids" { 44 | value = data.jamfpro_department.test_by_id.id == data.jamfpro_department.test_by_name.id 45 | } 46 | ``` 47 | 48 | 49 | ## Schema 50 | 51 | ### Optional 52 | 53 | - `id` (String) The unique identifier of the department. 54 | - `name` (String) The unique name of the jamf pro department. -------------------------------------------------------------------------------- /docs/data-sources/device_enrollments_public_key.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_device_enrollments_public_key" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_device_enrollments_public_key (Data Source) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | data "jamfpro_device_enrollments_public_key" "current" {} 13 | 14 | output "device_enrollments_public_key" { 15 | value = data.jamfpro_device_enrollments_public_key.current.public_key 16 | } 17 | ``` 18 | 19 | 20 | ## Schema 21 | 22 | ### Read-Only 23 | 24 | - `id` (String) The ID of this resource. 25 | - `public_key` (String) The public key used for device enrollments. -------------------------------------------------------------------------------- /docs/data-sources/file_share_distribution_point.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_file_share_distribution_point" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_file_share_distribution_point (Data Source) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | data "jamfpro_file_share_distribution_point" "dp_example" { 13 | id = resource.jamfpro_file_share_distribution_point.dp_example.id 14 | } 15 | 16 | output "jamfpro_file_share_distribution_point_id" { 17 | value = data.jamfpro_file_share_distribution_point.dp_example.id 18 | } 19 | 20 | output "jamfpro_file_share_distribution_point_name" { 21 | value = data.jamfpro_file_share_distribution_point.dp_example.name 22 | } 23 | ``` 24 | 25 | 26 | ## Schema 27 | 28 | ### Required 29 | 30 | - `id` (String) The unique identifier of the distribution point. 31 | 32 | ### Optional 33 | 34 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 35 | 36 | ### Read-Only 37 | 38 | - `name` (String) The name of the distribution point. 39 | 40 | 41 | ### Nested Schema for `timeouts` 42 | 43 | Optional: 44 | 45 | - `read` (String) -------------------------------------------------------------------------------- /docs/data-sources/jamf_cloud_distribution_service.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_jamf_cloud_distribution_service" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_jamf_cloud_distribution_service (Data Source) 8 | 9 | 10 | 11 | ## Schema 12 | 13 | ### Optional 14 | 15 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 16 | 17 | ### Read-Only 18 | 19 | - `file_stream_endpoint_enabled` (Boolean) 20 | - `files` (List of Object) (see [below for nested schema](#nestedatt--files)) 21 | - `id` (String) The ID of this resource. 22 | - `jcds2_enabled` (Boolean) 23 | - `max_chunk_size` (Number) 24 | 25 | 26 | ### Nested Schema for `timeouts` 27 | 28 | Optional: 29 | 30 | - `read` (String) 31 | 32 | 33 | 34 | ### Nested Schema for `files` 35 | 36 | Read-Only: 37 | 38 | - `file_name` (String) 39 | - `length` (Number) 40 | - `md5` (String) 41 | - `region` (String) 42 | - `sha3` (String) -------------------------------------------------------------------------------- /docs/data-sources/mobile_device_prestage_enrollment.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_mobile_device_prestage_enrollment" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_mobile_device_prestage_enrollment (Data Source) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | data "jamfpro_mobile_device_prestage_enrollment" "example" { 13 | id = "1" 14 | } 15 | 16 | output "prestage_name" { 17 | value = data.jamfpro_mobile_device_prestage_enrollment.example.display_name 18 | } 19 | ``` 20 | 21 | 22 | ## Schema 23 | 24 | ### Optional 25 | 26 | - `display_name` (String) The display name of the mobile device prestage. 27 | - `id` (String) The unique identifier of the mobile device prestage. 28 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 29 | 30 | 31 | ### Nested Schema for `timeouts` 32 | 33 | Optional: 34 | 35 | - `read` (String) -------------------------------------------------------------------------------- /docs/data-sources/network_segment.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_network_segment" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_network_segment (Data Source) 8 | 9 | 10 | 11 | ## Schema 12 | 13 | ### Required 14 | 15 | - `id` (String) The unique identifier of the Jamf Pro resource. 16 | 17 | ### Optional 18 | 19 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 20 | 21 | ### Read-Only 22 | 23 | - `name` (String) The unique name of the Jamf Pro resource. 24 | 25 | 26 | ### Nested Schema for `timeouts` 27 | 28 | Optional: 29 | 30 | - `read` (String) -------------------------------------------------------------------------------- /docs/data-sources/policy.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_policy" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_policy (Data Source) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | data "jamfpro_policy" "jamfpro_policys_001_data" { 13 | id = jamfpro_policy.jamfpro_policys_001.id 14 | } 15 | 16 | output "jamfpro_jamfpro_policys_001_id" { 17 | value = data.jamfpro_policy.jamfpro_policys_001_data.id 18 | } 19 | 20 | output "jamfpro_jamfpro_policys_001_name" { 21 | value = data.jamfpro_policy.jamfpro_policys_001_data.name 22 | } 23 | ``` 24 | 25 | 26 | ## Schema 27 | 28 | ### Required 29 | 30 | - `id` (String) The unique identifier of the Jamf Pro site. 31 | 32 | ### Optional 33 | 34 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 35 | 36 | ### Read-Only 37 | 38 | - `name` (String) The unique name of the Jamf Pro site. 39 | 40 | 41 | ### Nested Schema for `timeouts` 42 | 43 | Optional: 44 | 45 | - `read` (String) -------------------------------------------------------------------------------- /docs/data-sources/printer.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_printer" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_printer (Data Source) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | data "jamfpro_printer" "jamfpro_printers_001_data" { 13 | id = jamfpro_printer.jamfpro_printers_001.id 14 | } 15 | 16 | output "jamfpro_jamfpro_printers_001_id" { 17 | value = data.jamfpro_printer.jamfpro_printers_001_data.id 18 | } 19 | 20 | output "jamfpro_jamfpro_printers_001_name" { 21 | value = data.jamfpro_printer.jamfpro_printers_001_data.name 22 | } 23 | ``` 24 | 25 | 26 | ## Schema 27 | 28 | ### Required 29 | 30 | - `id` (String) The unique identifier of the printer. 31 | 32 | ### Optional 33 | 34 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 35 | 36 | ### Read-Only 37 | 38 | - `name` (String) The name of the printer. 39 | 40 | 41 | ### Nested Schema for `timeouts` 42 | 43 | Optional: 44 | 45 | - `read` (String) -------------------------------------------------------------------------------- /docs/data-sources/restricted_software.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_restricted_software" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_restricted_software (Data Source) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | data "jamfpro_restricted_software" "restricted_software_001_data" { 13 | id = jamfpro_restricted_software.restricted_software_001.id 14 | } 15 | 16 | output "jamfpro_restricted_software_001_id" { 17 | value = data.jamfpro_restricted_software.restricted_software_001_data.id 18 | } 19 | 20 | output "jamfpro_restricted_software_001_name" { 21 | value = data.jamfpro_restricted_software.restricted_software_001_data.name 22 | } 23 | 24 | data "jamfpro_restricted_software" "restricted_software_002_data" { 25 | id = jamfpro_restricted_software.restricted_software_002.id 26 | } 27 | 28 | output "jamfpro_restricted_software_002_id" { 29 | value = data.jamfpro_restricted_software.restricted_software_002_data.id 30 | } 31 | 32 | output "jamfpro_restricted_software_002_name" { 33 | value = data.jamfpro_restricted_software.restricted_software_002_data.name 34 | } 35 | ``` 36 | 37 | 38 | ## Schema 39 | 40 | ### Required 41 | 42 | - `id` (String) The unique identifier of the Jamf Pro restricted software. 43 | 44 | ### Optional 45 | 46 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 47 | 48 | ### Read-Only 49 | 50 | - `name` (String) The unique name of the Jamf Pro restricted software. 51 | 52 | 53 | ### Nested Schema for `timeouts` 54 | 55 | Optional: 56 | 57 | - `read` (String) -------------------------------------------------------------------------------- /docs/data-sources/site.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_site" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_site (Data Source) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | data "jamfpro_site" "site_001_data" { 13 | id = jamfpro_site.site_001.id 14 | } 15 | 16 | output "jamfpro_site_001_id" { 17 | value = data.jamfpro_site.site_001_data.id 18 | } 19 | 20 | output "jamfpro_site_001_name" { 21 | value = data.jamfpro_site.site_001_data.name 22 | } 23 | 24 | data "jamfpro_sites" "site_002_data" { 25 | id = jamfpro_site.site_002.id 26 | } 27 | 28 | output "jamfpro_site_002_id" { 29 | value = data.jamfpro_site.site_002_data.id 30 | } 31 | 32 | output "jamfpro_site_002_name" { 33 | value = data.jamfpro_site.site_002_data.name 34 | } 35 | ``` 36 | 37 | 38 | ## Schema 39 | 40 | ### Required 41 | 42 | - `id` (String) The unique identifier of the Jamf Pro site. 43 | 44 | ### Optional 45 | 46 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 47 | 48 | ### Read-Only 49 | 50 | - `name` (String) The unique name of the Jamf Pro site. 51 | 52 | 53 | ### Nested Schema for `timeouts` 54 | 55 | Optional: 56 | 57 | - `read` (String) -------------------------------------------------------------------------------- /docs/data-sources/smart_mobile_device_group.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_smart_mobile_device_group" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_smart_mobile_device_group (Data Source) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | data "jamfpro_smart_mobile_device_group" "jamfpro_smart_mobile_device_group_001_data" { 13 | id = jamfpro_smart_mobile_device_group.jamfpro_smart_mobile_device_group_001.id 14 | } 15 | 16 | output "jamfpro_jamfpro_smart_mobile_device_group_001_id" { 17 | value = data.jamfpro_smart_mobile_device_group.jamfpro_smart_mobile_device_group_001_data.id 18 | } 19 | 20 | output "jamfpro_jamfpro_smart_mobile_device_groups_001_name" { 21 | value = data.jamfpro_smart_mobile_device_group.jamfpro_smart_mobile_device_group_001_data.name 22 | } 23 | ``` 24 | 25 | 26 | ## Schema 27 | 28 | ### Required 29 | 30 | - `id` (String) The unique identifier of the Jamf Pro Smart mobile group. 31 | 32 | ### Read-Only 33 | 34 | - `name` (String) The unique name of the Jamf Pro Smart mobile group. -------------------------------------------------------------------------------- /docs/data-sources/sso_certificate.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_sso_certificate" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_sso_certificate (Data Source) 8 | 9 | 10 | 11 | ## Schema 12 | 13 | ### Optional 14 | 15 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 16 | 17 | ### Read-Only 18 | 19 | - `id` (String) The ID of this resource. 20 | - `keystore` (List of Object) The keystore configuration for the SSO certificate (see [below for nested schema](#nestedatt--keystore)) 21 | - `keystore_details` (List of Object) Detailed information about the SSO certificate (see [below for nested schema](#nestedatt--keystore_details)) 22 | 23 | 24 | ### Nested Schema for `timeouts` 25 | 26 | Optional: 27 | 28 | - `read` (String) 29 | 30 | 31 | 32 | ### Nested Schema for `keystore` 33 | 34 | Read-Only: 35 | 36 | - `key` (String) 37 | - `keys` (List of Object) (see [below for nested schema](#nestedobjatt--keystore--keys)) 38 | - `keystore_file_name` (String) 39 | - `keystore_setup_type` (String) 40 | - `type` (String) 41 | 42 | 43 | ### Nested Schema for `keystore.keys` 44 | 45 | Read-Only: 46 | 47 | - `id` (String) 48 | - `valid` (Boolean) 49 | 50 | 51 | 52 | 53 | ### Nested Schema for `keystore_details` 54 | 55 | Read-Only: 56 | 57 | - `expiration` (String) 58 | - `issuer` (String) 59 | - `keys` (List of String) 60 | - `serial_number` (Number) 61 | - `subject` (String) -------------------------------------------------------------------------------- /docs/data-sources/sso_failover.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_sso_failover" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_sso_failover (Data Source) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | data "jamfpro_sso_failover" "current" {} 13 | 14 | output "current_failover_url" { 15 | value = data.jamfpro_sso_failover.current.failover_url 16 | sensitive = true 17 | } 18 | 19 | output "last_generation_time" { 20 | value = data.jamfpro_sso_failover.current.generation_time 21 | } 22 | ``` 23 | 24 | 25 | ## Schema 26 | 27 | ### Optional 28 | 29 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 30 | 31 | ### Read-Only 32 | 33 | - `failover_url` (String) The SSO failover URL for Jamf Pro 34 | - `generation_time` (Number) The timestamp when the failover URL was generated 35 | - `id` (String) The ID of this resource. 36 | 37 | 38 | ### Nested Schema for `timeouts` 39 | 40 | Optional: 41 | 42 | - `read` (String) -------------------------------------------------------------------------------- /docs/data-sources/user_group.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_user_group" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_user_group (Data Source) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | data "jamfpro_user_group" "usergroup_001_data" { 13 | id = jamfpro_user_group.jamfpro_user_group_001.id 14 | } 15 | 16 | output "jamfpro_user_group_001_id" { 17 | value = data.jamfpro_user_group.usergroup_001_data.id 18 | } 19 | 20 | output "jamfpro_user_group_001_name" { 21 | value = data.jamfpro_user_group.usergroup_001_data.name 22 | } 23 | 24 | data "jamfpro_user_group" "usergroup_002_data" { 25 | id = jamfpro_user_group.jamfpro_user_group_002.id 26 | } 27 | 28 | output "jamfpro_user_group_002_id" { 29 | value = data.jamfpro_user_group.usergroup_002_data.id 30 | } 31 | 32 | output "jamfpro_user_group_002_name" { 33 | value = data.jamfpro_user_group.usergroup_002_data.name 34 | } 35 | ``` 36 | 37 | 38 | ## Schema 39 | 40 | ### Required 41 | 42 | - `id` (String) The unique identifier of the Jamf Pro user group. 43 | 44 | ### Optional 45 | 46 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 47 | 48 | ### Read-Only 49 | 50 | - `name` (String) The unique name of the Jamf Pro user group. 51 | 52 | 53 | ### Nested Schema for `timeouts` 54 | 55 | Optional: 56 | 57 | - `read` (String) -------------------------------------------------------------------------------- /docs/data-sources/webhook.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_webhook" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_webhook (Data Source) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | // data source by id 13 | data "jamfpro_webhook" "webhook_001_data" { 14 | id = jamfpro_webhook.jamfpro_webhook_001.id 15 | } 16 | 17 | output "jamfpro_webhook_001_id" { 18 | value = data.jamfpro_webhook.webhook_001_data.id 19 | } 20 | 21 | output "jamfpro_webhook_001_name" { 22 | value = data.jamfpro_webhook.webhook_001_data.name 23 | } 24 | 25 | // data source list 26 | 27 | data "jamfpro_webhook_list" "example" {} 28 | 29 | output "webhook_ids" { 30 | value = data.jamfpro_webhook_list.example.ids 31 | } 32 | 33 | output "webhooks" { 34 | value = data.jamfpro_webhook_list.example.webhooks 35 | } 36 | ``` 37 | 38 | 39 | ## Schema 40 | 41 | ### Required 42 | 43 | - `id` (String) The unique identifier of the Jamf Pro Webhook. 44 | 45 | ### Optional 46 | 47 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 48 | 49 | ### Read-Only 50 | 51 | - `name` (String) The unique name of the Jamf Pro Webhook. 52 | 53 | 54 | ### Nested Schema for `timeouts` 55 | 56 | Optional: 57 | 58 | - `read` (String) -------------------------------------------------------------------------------- /docs/resources/activation_code.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_activation_code" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_activation_code (Resource) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | resource "jamfpro_activation_code" "activation_code_001" { 13 | organization_name = "your_organization_name" 14 | code = "UW5M-XXXX-CNAP-XXXX-CDTC-DNTV-ZAGT-XXXX" 15 | } 16 | ``` 17 | 18 | 19 | ## Schema 20 | 21 | ### Required 22 | 23 | - `code` (String, Sensitive) The activation code. 24 | - `organization_name` (String) The name of the organization associated with the activation code. 25 | 26 | ### Optional 27 | 28 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 29 | 30 | ### Read-Only 31 | 32 | - `id` (String) The ID of this resource. 33 | 34 | 35 | ### Nested Schema for `timeouts` 36 | 37 | Optional: 38 | 39 | - `create` (String) 40 | - `delete` (String) 41 | - `read` (String) 42 | - `update` (String) -------------------------------------------------------------------------------- /docs/resources/allowed_file_extension.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_allowed_file_extension" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_allowed_file_extension (Resource) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | resource "jamfpro_allowed_file_extension" "allowed_file_extension_001" { 13 | extension = ".thing1" 14 | } 15 | 16 | resource "jamfpro_allowed_file_extension" "allowed_file_extension_002" { 17 | extension = ".thing2" 18 | } 19 | ``` 20 | 21 | 22 | ## Schema 23 | 24 | ### Required 25 | 26 | - `extension` (String) 27 | 28 | ### Optional 29 | 30 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 31 | 32 | ### Read-Only 33 | 34 | - `id` (String) The ID of this resource. 35 | 36 | 37 | ### Nested Schema for `timeouts` 38 | 39 | Optional: 40 | 41 | - `create` (String) 42 | - `delete` (String) 43 | - `read` (String) 44 | - `update` (String) -------------------------------------------------------------------------------- /docs/resources/building.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_building" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_building (Resource) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | resource "jamfpro_building" "jamfpro_building_001" { 13 | name = "Apple Park" 14 | street_address1 = "The McIntosh Tree" 15 | street_address2 = "One Apple Park Way" 16 | city = "Cupertino" 17 | state_province = "California" 18 | zip_postal_code = "95014" 19 | country = "The United States of America" 20 | } 21 | ``` 22 | 23 | 24 | ## Schema 25 | 26 | ### Required 27 | 28 | - `name` (String) The name of the building. 29 | 30 | ### Optional 31 | 32 | - `city` (String) The city in which the building is located. 33 | - `country` (String) The country in which the building is located. 34 | - `state_province` (String) The state or province in which the building is located. 35 | - `street_address1` (String) The first line of the street address of the building. 36 | - `street_address2` (String) The second line of the street address of the building. 37 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 38 | - `zip_postal_code` (String) The ZIP or postal code of the building. 39 | 40 | ### Read-Only 41 | 42 | - `id` (String) The unique identifier of the building. 43 | 44 | 45 | ### Nested Schema for `timeouts` 46 | 47 | Optional: 48 | 49 | - `create` (String) 50 | - `delete` (String) 51 | - `read` (String) 52 | - `update` (String) -------------------------------------------------------------------------------- /docs/resources/category.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_category" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_category (Resource) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | resource "jamfpro_category" "example_category_1" { 13 | name = "tf-example-category-01" 14 | priority = 1 15 | } 16 | ``` 17 | 18 | 19 | ## Schema 20 | 21 | ### Required 22 | 23 | - `name` (String) The unique name of the Jamf Pro category. 24 | 25 | ### Optional 26 | 27 | - `priority` (Number) The priority of the Jamf Pro category. 28 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 29 | 30 | ### Read-Only 31 | 32 | - `id` (String) The unique identifier of the category. 33 | 34 | 35 | ### Nested Schema for `timeouts` 36 | 37 | Optional: 38 | 39 | - `create` (String) 40 | - `delete` (String) 41 | - `read` (String) 42 | - `update` (String) -------------------------------------------------------------------------------- /docs/resources/department.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_department" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_department (Resource) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | resource "jamfpro_department" "jamfpro_department_001" { 13 | name = "TF: Dept Test - 001" 14 | } 15 | ``` 16 | 17 | 18 | ## Schema 19 | 20 | ### Required 21 | 22 | - `name` (String) The unique name of the Jamf Pro department. 23 | 24 | ### Optional 25 | 26 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 27 | 28 | ### Read-Only 29 | 30 | - `id` (String) The unique identifier of the department. 31 | 32 | 33 | ### Nested Schema for `timeouts` 34 | 35 | Optional: 36 | 37 | - `create` (String) 38 | - `delete` (String) 39 | - `read` (String) 40 | - `update` (String) -------------------------------------------------------------------------------- /docs/resources/dock_item.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_dock_item" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_dock_item (Resource) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | // App Dock Item Example 13 | resource "jamfpro_dock_item" "dock_item_001" { 14 | name = "tf-example-dockItem-app-iTunes" 15 | type = "App" 16 | path = "file://localhost/Applications/iTunes.app/" 17 | } 18 | 19 | // File Dock Item Example 20 | resource "jamfpro_dock_item" "dock_item_002" { 21 | name = "tf-example-dockItem-file-hosts" 22 | type = "File" // App / File / Folder 23 | path = "/etc/hosts" 24 | } 25 | 26 | // Folder Dock Item Example 27 | resource "jamfpro_dock_item" "dock_item_003" { 28 | name = "tf-example-dockItem-folder-downloadsFolder" 29 | type = "Folder" // App / File / Folder 30 | path = "~/Downloads" 31 | } 32 | ``` 33 | 34 | 35 | ## Schema 36 | 37 | ### Required 38 | 39 | - `name` (String) The name of the dock item. 40 | - `path` (String) The path of the dock item. 41 | - `type` (String) The type of the dock item (App/File/Folder). 42 | 43 | ### Optional 44 | 45 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 46 | 47 | ### Read-Only 48 | 49 | - `contents` (String) Contents of the dock item. 50 | - `id` (String) The unique identifier of the dock item. 51 | 52 | 53 | ### Nested Schema for `timeouts` 54 | 55 | Optional: 56 | 57 | - `create` (String) 58 | - `delete` (String) 59 | - `read` (String) 60 | - `update` (String) -------------------------------------------------------------------------------- /docs/resources/engage_settings.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_engage_settings" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_engage_settings (Resource) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | resource "jamfpro_engage_settings" "example" { 13 | is_enabled = true 14 | } 15 | ``` 16 | 17 | 18 | ## Schema 19 | 20 | ### Required 21 | 22 | - `is_enabled` (Boolean) Whether the Engage settings are enabled or not. 23 | 24 | ### Optional 25 | 26 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 27 | 28 | ### Read-Only 29 | 30 | - `id` (String) The ID of this resource. 31 | 32 | 33 | ### Nested Schema for `timeouts` 34 | 35 | Optional: 36 | 37 | - `create` (String) 38 | - `delete` (String) 39 | - `read` (String) 40 | - `update` (String) -------------------------------------------------------------------------------- /docs/resources/icon.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_icon" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_icon (Resource) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | # Example using a local file 13 | resource "jamfpro_icon" "icon_from_local" { 14 | icon_file_path = "/Users/dafyddwatkins/localtesting/terraform/support_files/icons/firefox_logo_icon_170152.png" 15 | } 16 | 17 | # Example using a web source 18 | resource "jamfpro_icon" "icon_from_web" { 19 | icon_file_web_source = "https://upload.wikimedia.org/wikipedia/commons/1/16/Firefox_logo%2C_2017.png" 20 | } 21 | ``` 22 | 23 | 24 | ## Schema 25 | 26 | ### Optional 27 | 28 | - `icon_file_path` (String) The file path to the icon file (PNG) to be uploaded. 29 | - `icon_file_web_source` (String) The web location of the icon file, can be a http(s) URL 30 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 31 | 32 | ### Read-Only 33 | 34 | - `id` (String) The unique identifier of the icon. Returned by the Jamf Pro API. 35 | - `name` (String) The name of the icon. Returned by the Jamf Pro API. 36 | - `url` (String) 37 | 38 | 39 | ### Nested Schema for `timeouts` 40 | 41 | Optional: 42 | 43 | - `create` (String) 44 | - `delete` (String) 45 | - `read` (String) 46 | - `update` (String) -------------------------------------------------------------------------------- /docs/resources/managed_software_update_feature_toggle.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_managed_software_update_feature_toggle" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_managed_software_update_feature_toggle (Resource) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | resource "jamfpro_managed_software_update_feature_toggle" "example" { 13 | toggle = true 14 | } 15 | ``` 16 | 17 | 18 | ## Schema 19 | 20 | ### Required 21 | 22 | - `toggle` (Boolean) Whether the Managed Software Update Feature Toggle is enabled or not. 23 | 24 | ### Optional 25 | 26 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 27 | 28 | ### Read-Only 29 | 30 | - `id` (String) The ID of this resource. 31 | 32 | 33 | ### Nested Schema for `timeouts` 34 | 35 | Optional: 36 | 37 | - `create` (String) 38 | - `delete` (String) 39 | - `read` (String) 40 | - `update` (String) -------------------------------------------------------------------------------- /docs/resources/site.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_site" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_site (Resource) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | resource "jamfpro_site" "example_site_1" { 13 | name = "tf-example-site-01" 14 | } 15 | ``` 16 | 17 | 18 | ## Schema 19 | 20 | ### Required 21 | 22 | - `name` (String) The unique name of the Jamf Pro site. 23 | 24 | ### Optional 25 | 26 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 27 | 28 | ### Read-Only 29 | 30 | - `id` (String) The unique identifier of the site. 31 | 32 | 33 | ### Nested Schema for `timeouts` 34 | 35 | Optional: 36 | 37 | - `create` (String) 38 | - `delete` (String) 39 | - `read` (String) 40 | - `update` (String) -------------------------------------------------------------------------------- /docs/resources/sso_failover.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_sso_failover" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_sso_failover (Resource) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | resource "jamfpro_sso_failover" "current" {} 13 | 14 | output "failover_url" { 15 | value = jamfpro_sso_failover.current.failover_url 16 | sensitive = true 17 | } 18 | ``` 19 | 20 | 21 | ## Schema 22 | 23 | ### Optional 24 | 25 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 26 | 27 | ### Read-Only 28 | 29 | - `failover_url` (String, Sensitive) The SSO failover URL for Jamf Pro 30 | - `generation_time` (Number) The timestamp when the failover URL was generated 31 | - `id` (String) The ID of this resource. 32 | 33 | 34 | ### Nested Schema for `timeouts` 35 | 36 | Optional: 37 | 38 | - `create` (String) 39 | - `delete` (String) 40 | - `read` (String) -------------------------------------------------------------------------------- /docs/resources/static_computer_group.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_static_computer_group" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_static_computer_group (Resource) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | resource "jamfpro_static_computer_group" "jamfpro_static_computer_group_001" { 13 | name = "Example Static Computer Group" 14 | 15 | 16 | # Optional Block 17 | site_id = 1 18 | 19 | # Optional: Specify computers for static groups 20 | assigned_computer_ids = [1, 2, 3] 21 | } 22 | ``` 23 | 24 | 25 | ## Schema 26 | 27 | ### Required 28 | 29 | - `name` (String) The unique name of the Jamf Pro static computer group. 30 | 31 | ### Optional 32 | 33 | - `assigned_computer_ids` (List of Number) assigned computer by ids 34 | - `site_id` (Number) Jamf Pro Site-related settings of the policy. 35 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 36 | 37 | ### Read-Only 38 | 39 | - `id` (String) The unique identifier of the Jamf Pro static computer group. 40 | - `is_smart` (Boolean) Computed value indicating whether the computer group is smart or static. 41 | 42 | 43 | ### Nested Schema for `timeouts` 44 | 45 | Optional: 46 | 47 | - `create` (String) 48 | - `delete` (String) 49 | - `read` (String) 50 | - `update` (String) -------------------------------------------------------------------------------- /docs/resources/static_mobile_device_group.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "jamfpro_static_mobile_device_group" 3 | description: |- 4 | 5 | --- 6 | 7 | # jamfpro_static_mobile_device_group (Resource) 8 | 9 | 10 | ## Example Usage 11 | ```terraform 12 | resource "jamfpro_static_mobile_device_group" "jamfpro_static_mobile_device_group_001" { 13 | name = "Example Mobile Device Group" 14 | 15 | 16 | # Optional Block 17 | site_id = 1 18 | 19 | # Optional: Specify computers for static groups 20 | assigned_mobile_device_ids = [1, 2, 3] 21 | } 22 | ``` 23 | 24 | 25 | ## Schema 26 | 27 | ### Required 28 | 29 | - `name` (String) The unique name of the Jamf Pro static mobile device group. 30 | 31 | ### Optional 32 | 33 | - `assigned_mobile_device_ids` (List of Number) assigned mobile device by ids 34 | - `site_id` (Number) Jamf Pro Site-related settings of the policy. 35 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 36 | 37 | ### Read-Only 38 | 39 | - `id` (String) The unique identifier of the Jamf Pro static mobile device group. 40 | - `is_smart` (Boolean) Computed value indicating whether the mobile device group is smart or static. 41 | 42 | 43 | ### Nested Schema for `timeouts` 44 | 45 | Optional: 46 | 47 | - `create` (String) 48 | - `delete` (String) 49 | - `read` (String) 50 | - `update` (String) -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | This directory contains examples that are mostly used for documentation, but can also be run/tested manually via the Terraform CLI. 4 | 5 | The document generation tool looks for files in the following locations by default. All other *.tf files besides the ones mentioned below are ignored by the documentation tool. This is useful for creating examples that can run and/or ar testable even if some parts are not relevant for the documentation. 6 | 7 | * **provider/provider.tf** example file for the provider index page 8 | * **`full data source name`/data-source.tf** example file for the named data source page 9 | * **`full resource name`/resource.tf** example file for the named data source page 10 | -------------------------------------------------------------------------------- /examples/USAGE.md: -------------------------------------------------------------------------------- 1 | 2 | ### Providers 3 | 4 | No providers. 5 | 6 | ### Modules 7 | 8 | No modules. 9 | 10 | ### Resources 11 | 12 | No resources. 13 | 14 | ### Inputs 15 | 16 | No inputs. 17 | 18 | ### Outputs 19 | 20 | No outputs. 21 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_account/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_account" "jamfpro_account_001_data" { 2 | id = jamfpro_account.jamfpro_account_001.id 3 | } 4 | 5 | output "jamfpro_account_001_data_id" { 6 | value = data.jamfpro_account.jamfpro_account_001_data.id 7 | } 8 | 9 | output "jamfpro_account_001_data_name" { 10 | value = data.jamfpro_account.jamfpro_account_001_data.name 11 | } 12 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_account_group/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_account_group" "jamfpro_account_group_001_data" { 2 | id = jamfpro_account_group.jamfpro_account_group_001.id 3 | } 4 | 5 | output "jamfpro_jamfpro_account_group_001_id" { 6 | value = data.jamfpro_account_group.jamfpro_account_group_001_data.id 7 | } 8 | 9 | output "jamfpro_jamfpro_account_groups_001_name" { 10 | value = data.jamfpro_account_group.jamfpro_account_group_001_data.name 11 | } 12 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_api_integration/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_api_integration" "jamfpro_api_integration_001_data" { 2 | id = jamfpro_api_integration.jamfpro_api_integration_001.id 3 | } 4 | 5 | output "jamfpro_api_integration_001_data_id" { 6 | value = data.jamfpro_api_integration.jamfpro_api_integration_001_data.id 7 | } 8 | 9 | output "jamfpro_api_integration_001_data_name" { 10 | value = data.jamfpro_api_integration.jamfpro_api_integration_001_data.name 11 | } 12 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_api_role/data-source.tf: -------------------------------------------------------------------------------- 1 | # Example 1: Look up API role by ID 2 | data "jamfpro_api_role" "by_id" { 3 | id = "168" 4 | } 5 | 6 | # Output example for ID lookup 7 | output "role_privileges_by_id" { 8 | value = data.jamfpro_api_role.by_id.privileges 9 | } 10 | 11 | # Example 2: Look up API role by display name 12 | data "jamfpro_api_role" "by_name" { 13 | display_name = "tf-all-jss-actions-permissions-11.12" 14 | } 15 | 16 | # Output examples for name lookup 17 | output "role_id_by_name" { 18 | value = data.jamfpro_api_role.by_name.id 19 | } 20 | 21 | output "role_privileges_by_name" { 22 | value = data.jamfpro_api_role.by_name.privileges 23 | } 24 | 25 | # Example 3: Using the data source in another resource 26 | resource "jamfpro_some_resource" "example" { 27 | name = "Example Resource" 28 | role_id = data.jamfpro_api_role.by_name.id 29 | privileges = data.jamfpro_api_role.by_name.privileges 30 | } 31 | 32 | # Example 4: Using with variables 33 | variable "role_name" { 34 | type = string 35 | description = "The display name of the API role to look up" 36 | default = "Read Only Admin" 37 | } 38 | 39 | data "jamfpro_api_role" "dynamic" { 40 | display_name = var.role_name 41 | } -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_building/data-source.tf: -------------------------------------------------------------------------------- 1 | # Example 1: Look up building by ID 2 | data "jamfpro_building" "by_id" { 3 | id = "1" 4 | } 5 | 6 | # Example 2: Look up building by name 7 | data "jamfpro_building" "by_name" { 8 | name = "Corporate HQ" 9 | } 10 | 11 | # Output examples 12 | output "building_address" { 13 | value = "${data.jamfpro_building.by_name.street_address1}, ${data.jamfpro_building.by_name.city}" 14 | } 15 | 16 | output "building_details" { 17 | value = { 18 | name = data.jamfpro_building.by_name.name 19 | full_address = join("\n", [ 20 | data.jamfpro_building.by_name.street_address1, 21 | data.jamfpro_building.by_name.street_address2, 22 | data.jamfpro_building.by_name.city, 23 | data.jamfpro_building.by_name.state_province, 24 | data.jamfpro_building.by_name.zip_postal_code, 25 | data.jamfpro_building.by_name.country 26 | ]) 27 | } 28 | } 29 | 30 | # Example 3: Using with variables 31 | variable "building_name" { 32 | type = string 33 | description = "The name of the building to look up" 34 | default = "Corporate HQ" 35 | } 36 | 37 | data "jamfpro_building" "dynamic" { 38 | name = var.building_name 39 | } 40 | 41 | # Example 4: Using in another resource 42 | resource "jamfpro_computer" "office_computer" { 43 | name = "Office Workstation" 44 | building_id = data.jamfpro_building.by_name.id 45 | description = "Workstation located at ${data.jamfpro_building.by_name.name}" 46 | } -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_category/data-source.tf: -------------------------------------------------------------------------------- 1 | # Example 1: Look up by ID 2 | data "jamfpro_category" "by_id" { 3 | id = "1" 4 | } 5 | 6 | # Example 2: Look up by name 7 | data "jamfpro_category" "by_name" { 8 | name = "Applications" 9 | } 10 | 11 | # Example 3: Using variables 12 | variable "category_name" { 13 | type = string 14 | description = "Category to look up" 15 | default = "Applications" 16 | } 17 | 18 | data "jamfpro_category" "dynamic" { 19 | name = var.category_name 20 | } 21 | 22 | # Output examples 23 | output "category_details" { 24 | value = { 25 | id = data.jamfpro_category.by_name.id 26 | name = data.jamfpro_category.by_name.name 27 | priority = data.jamfpro_category.by_name.priority 28 | } 29 | } 30 | 31 | # Example 4: Using in another resource 32 | resource "jamfpro_policy" "app_policy" { 33 | name = "Application Install Policy" 34 | category_id = data.jamfpro_category.by_name.id 35 | } -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_cloud_distribution_point/data_source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_cloud_distribution_point" "current" {} 2 | 3 | output "cdn_type" { 4 | value = data.jamfpro_cloud_distribution_point.current.cdn_type 5 | } 6 | 7 | output "connection_status" { 8 | value = data.jamfpro_cloud_distribution_point.current.has_connection_succeeded 9 | } 10 | 11 | output "upload_capable" { 12 | value = data.jamfpro_cloud_distribution_point.current.direct_upload_capable 13 | } 14 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_computer_extension_attribute/data-source.tf: -------------------------------------------------------------------------------- 1 | // data source by id 2 | 3 | data "jamfpro_computer_extension_attribute" "jamfpro_computer_extension_attribute_001_data" { 4 | id = jamfpro_computer_extension_attribute.jamfpro_computer_extension_attribute_001.id 5 | } 6 | 7 | output "jamfpro_computer_extension_attribute_001_data_id" { 8 | value = data.jamfpro_computer_extension_attribute.jamfpro_computer_extension_attribute_001_data.id 9 | } 10 | 11 | output "jamfpro_computer_extension_attribute_001_data_name" { 12 | value = data.jamfpro_computer_extension_attribute.jamfpro_computer_extension_attribute_001_data.name 13 | } 14 | 15 | // data source list 16 | 17 | data "jamfpro_computer_extension_attributes_list" "example" {} 18 | 19 | output "attribute_ids" { 20 | value = data.jamfpro_computer_extension_attributes_list.example.ids 21 | } 22 | 23 | output "attributes" { 24 | value = data.jamfpro_computer_extension_attributes_list.example.attributes 25 | } -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_department/data-source.tf: -------------------------------------------------------------------------------- 1 | # Create department resource 2 | resource "jamfpro_department" "test" { 3 | name = "Engineering" 4 | } 5 | 6 | # Test data source by ID 7 | data "jamfpro_department" "test_by_id" { 8 | id = jamfpro_department.test.id 9 | } 10 | 11 | # Test data source by name 12 | data "jamfpro_department" "test_by_name" { 13 | name = jamfpro_department.test.name 14 | } 15 | 16 | # Outputs to verify 17 | output "department_by_id" { 18 | value = { 19 | id = data.jamfpro_department.test_by_id.id 20 | name = data.jamfpro_department.test_by_id.name 21 | } 22 | } 23 | 24 | output "department_by_name" { 25 | value = { 26 | id = data.jamfpro_department.test_by_name.id 27 | name = data.jamfpro_department.test_by_name.name 28 | } 29 | } 30 | 31 | # Validation 32 | output "matching_ids" { 33 | value = data.jamfpro_department.test_by_id.id == data.jamfpro_department.test_by_name.id 34 | } -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_device_enrollments_public_key/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_device_enrollments_public_key" "current" {} 2 | 3 | output "device_enrollments_public_key" { 4 | value = data.jamfpro_device_enrollments_public_key.current.public_key 5 | } 6 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_disk_encryption_configuration/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_disk_encryption_configuration" "jamfpro_disk_encryption_configuration_002_data" { 2 | id = jamfpro_disk_encryption_configuration.jamfpro_disk_encryption_configuration_002.id 3 | } 4 | 5 | output "jamfpro_disk_encryption_configuration_002_id" { 6 | value = data.jamfpro_disk_encryption_configuration.jamfpro_disk_encryption_configuration_002_data.id 7 | } 8 | 9 | output "jamfpro_disk_encryption_configuration_002_name" { 10 | value = data.jamfpro_disk_encryption_configuration.jamfpro_disk_encryption_configuration_002_data.name 11 | } -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_dock_item/data-source.tf: -------------------------------------------------------------------------------- 1 | # Test data source by ID 2 | data "jamfpro_dock_item" "test_by_id" { 3 | id = jamfpro_dock_item.test.id 4 | } 5 | 6 | # Test data source by name 7 | data "jamfpro_dock_item" "test_by_name" { 8 | name = jamfpro_dock_item.test.name 9 | } 10 | 11 | # Outputs 12 | output "dock_item_by_id" { 13 | value = { 14 | id = data.jamfpro_dock_item.test_by_id.id 15 | name = data.jamfpro_dock_item.test_by_id.name 16 | type = data.jamfpro_dock_item.test_by_id.type 17 | path = data.jamfpro_dock_item.test_by_id.path 18 | } 19 | } 20 | 21 | output "dock_item_by_name" { 22 | value = { 23 | id = data.jamfpro_dock_item.test_by_name.id 24 | name = data.jamfpro_dock_item.test_by_name.name 25 | type = data.jamfpro_dock_item.test_by_name.type 26 | path = data.jamfpro_dock_item.test_by_name.path 27 | } 28 | } 29 | 30 | output "dock_item_by_name" { 31 | value = { 32 | id = data.jamfpro_dock_item.test_by_name.id 33 | name = data.jamfpro_dock_item.test_by_name.name 34 | type = data.jamfpro_dock_item.test_by_name.type 35 | path = data.jamfpro_dock_item.test_by_name.path 36 | } 37 | } -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_file_share_distribution_point/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_file_share_distribution_point" "dp_example" { 2 | id = resource.jamfpro_file_share_distribution_point.dp_example.id 3 | } 4 | 5 | output "jamfpro_file_share_distribution_point_id" { 6 | value = data.jamfpro_file_share_distribution_point.dp_example.id 7 | } 8 | 9 | output "jamfpro_file_share_distribution_point_name" { 10 | value = data.jamfpro_file_share_distribution_point.dp_example.name 11 | } 12 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_jamf_cloud_distribution_service/data_source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_jamf_cloud_distribution_service" "current" {} 2 | 3 | output "jcds_file_stream_endpoint_enabled" { 4 | value = data.jamfpro_jamf_cloud_distribution_service.current.file_stream_endpoint_enabled 5 | } 6 | 7 | output "jcds2_enabled" { 8 | value = data.jamfpro_jamf_cloud_distribution_service.current.jcds2_enabled 9 | } 10 | 11 | output "jcds_files" { 12 | value = data.jamfpro_jamf_cloud_distribution_service.current.files 13 | } 14 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_macos_configuration_profile_plist_generator/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_macos_configuration_profile_plist_generator" "jamfpro_macos_configuration_profile_plist_generator_001_data" { 2 | id = jamfpro_macos_configuration_profile_plist_generator.jamfpro_macos_configuration_profile_plist_generator_001.id 3 | } 4 | 5 | output "jamfpro_macos_configuration_profile_plist_generator_001_data_id" { 6 | value = data.jamfpro_macos_configuration_profile_plist_generator.jamfpro_macos_configuration_profile_plist_generator_001_data.id 7 | } 8 | 9 | output "jamfpro_macos_configuration_profile_plist_generator_001_data_name" { 10 | value = data.jamfpro_macos_configuration_profile_plist_generator.jamfpro_macos_configuration_profile_plist_generator_001_data.name 11 | } -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_mobile_device_configuration_profile_plist/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_mobile_device_configuration_profile" "mobile_device_configuration_profile_001_data" { 2 | id = jamfpro_mobile_device_configuration_profile.mobile_device_configuration_profile_001.id 3 | } 4 | 5 | output "jamfpro_mobile_device_configuration_profile_001_id" { 6 | value = data.jamfpro_mobile_device_configuration_profile.mobile_device_configuration_profile_001_data.id 7 | } 8 | 9 | output "jamfpro_mobile_device_configuration_profile_001_name" { 10 | value = data.jamfpro_mobile_device_configuration_profile.mobile_device_configuration_profile_001_data.name 11 | } 12 | 13 | data "jamfpro_mobile_device_configuration_profile" "mobile_device_configuration_profile_002_data" { 14 | id = jamfpro_mobile_device_configuration_profile.mobile_device_configuration_profile_002.id 15 | } 16 | 17 | output "jamfpro_mobile_device_configuration_profile_002_id" { 18 | value = data.jamfpro_mobile_device_configuration_profile.mobile_device_configuration_profile_002_data.id 19 | } 20 | 21 | output "jamfpro_mobile_device_configuration_profile_002_name" { 22 | value = data.jamfpro_mobile_device_configuration_profile.mobile_device_configuration_profile_002_data.name 23 | } 24 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_mobile_device_extension_attribute/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_mobile_device_extension_attribute" "jamfpro_mobile_device_extension_attribute_001_data" { 2 | id = jamfpro_mobile_device_extension_attribute.jamfpro_mobile_device_extension_attribute_001.id 3 | } 4 | 5 | output "jamfpro_mobile_device_extension_attribute_001_data_id" { 6 | value = data.jamfpro_mobile_device_extension_attribute.jamfpro_mobile_device_extension_attribute_001_data.id 7 | } 8 | 9 | output "jamfpro_mobile_device_extension_attribute_001_data_name" { 10 | value = data.jamfpro_mobile_device_extension_attribute.jamfpro_mobile_device_extension_attribute_001_data.name 11 | } -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_mobile_device_prestage_enrollment/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_mobile_device_prestage_enrollment" "example" { 2 | id = "1" 3 | } 4 | 5 | output "prestage_name" { 6 | value = data.jamfpro_mobile_device_prestage_enrollment.example.display_name 7 | } 8 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_policy/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_policy" "jamfpro_policys_001_data" { 2 | id = jamfpro_policy.jamfpro_policys_001.id 3 | } 4 | 5 | output "jamfpro_jamfpro_policys_001_id" { 6 | value = data.jamfpro_policy.jamfpro_policys_001_data.id 7 | } 8 | 9 | output "jamfpro_jamfpro_policys_001_name" { 10 | value = data.jamfpro_policy.jamfpro_policys_001_data.name 11 | } 12 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_printer/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_printer" "jamfpro_printers_001_data" { 2 | id = jamfpro_printer.jamfpro_printers_001.id 3 | } 4 | 5 | output "jamfpro_jamfpro_printers_001_id" { 6 | value = data.jamfpro_printer.jamfpro_printers_001_data.id 7 | } 8 | 9 | output "jamfpro_jamfpro_printers_001_name" { 10 | value = data.jamfpro_printer.jamfpro_printers_001_data.name 11 | } 12 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_restricted_software/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_restricted_software" "restricted_software_001_data" { 2 | id = jamfpro_restricted_software.restricted_software_001.id 3 | } 4 | 5 | output "jamfpro_restricted_software_001_id" { 6 | value = data.jamfpro_restricted_software.restricted_software_001_data.id 7 | } 8 | 9 | output "jamfpro_restricted_software_001_name" { 10 | value = data.jamfpro_restricted_software.restricted_software_001_data.name 11 | } 12 | 13 | data "jamfpro_restricted_software" "restricted_software_002_data" { 14 | id = jamfpro_restricted_software.restricted_software_002.id 15 | } 16 | 17 | output "jamfpro_restricted_software_002_id" { 18 | value = data.jamfpro_restricted_software.restricted_software_002_data.id 19 | } 20 | 21 | output "jamfpro_restricted_software_002_name" { 22 | value = data.jamfpro_restricted_software.restricted_software_002_data.name 23 | } -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_site/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_site" "site_001_data" { 2 | id = jamfpro_site.site_001.id 3 | } 4 | 5 | output "jamfpro_site_001_id" { 6 | value = data.jamfpro_site.site_001_data.id 7 | } 8 | 9 | output "jamfpro_site_001_name" { 10 | value = data.jamfpro_site.site_001_data.name 11 | } 12 | 13 | data "jamfpro_sites" "site_002_data" { 14 | id = jamfpro_site.site_002.id 15 | } 16 | 17 | output "jamfpro_site_002_id" { 18 | value = data.jamfpro_site.site_002_data.id 19 | } 20 | 21 | output "jamfpro_site_002_name" { 22 | value = data.jamfpro_site.site_002_data.name 23 | } -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_smart_mobile_device_group/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_smart_mobile_device_group" "jamfpro_smart_mobile_device_group_001_data" { 2 | id = jamfpro_smart_mobile_device_group.jamfpro_smart_mobile_device_group_001.id 3 | } 4 | 5 | output "jamfpro_jamfpro_smart_mobile_device_group_001_id" { 6 | value = data.jamfpro_smart_mobile_device_group.jamfpro_smart_mobile_device_group_001_data.id 7 | } 8 | 9 | output "jamfpro_jamfpro_smart_mobile_device_groups_001_name" { 10 | value = data.jamfpro_smart_mobile_device_group.jamfpro_smart_mobile_device_group_001_data.name 11 | } 12 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_sso_certificate/data_source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_sso_certificate" "current" {} 2 | 3 | output "certificate_basic_info" { 4 | value = { 5 | type = data.jamfpro_sso_certificate.current.keystore[0].type 6 | keystore_filename = data.jamfpro_sso_certificate.current.keystore[0].keystore_file_name 7 | setup_type = data.jamfpro_sso_certificate.current.keystore[0].keystore_setup_type 8 | } 9 | } 10 | 11 | output "certificate_keys" { 12 | value = data.jamfpro_sso_certificate.current.keystore[0].keys 13 | } 14 | 15 | output "certificate_details" { 16 | value = { 17 | issuer = data.jamfpro_sso_certificate.current.keystore_details[0].issuer 18 | subject = data.jamfpro_sso_certificate.current.keystore_details[0].subject 19 | expiration = data.jamfpro_sso_certificate.current.keystore_details[0].expiration 20 | serial_number = data.jamfpro_sso_certificate.current.keystore_details[0].serial_number 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_sso_failover/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_sso_failover" "current" {} 2 | 3 | output "current_failover_url" { 4 | value = data.jamfpro_sso_failover.current.failover_url 5 | sensitive = true 6 | } 7 | 8 | output "last_generation_time" { 9 | value = data.jamfpro_sso_failover.current.generation_time 10 | } 11 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_static_computer_group/data-source.tf: -------------------------------------------------------------------------------- 1 | # Query group using ID 2 | data "jamfpro_static_computer_group" "by_id" { 3 | id = "1" 4 | } 5 | 6 | # Query using name 7 | data "jamfpro_static_computer_group" "by_name" { 8 | name = "Development Macs" 9 | } 10 | 11 | # Verify both lookups 12 | output "group_verification" { 13 | value = { 14 | by_id = { 15 | id = data.jamfpro_static_computer_group.by_id.id 16 | name = data.jamfpro_static_computer_group.by_id.name 17 | is_smart = data.jamfpro_static_computer_group.by_id.is_smart 18 | site_id = data.jamfpro_static_computer_group.by_id.site_id 19 | computers = data.jamfpro_static_computer_group.by_id.assigned_computer_ids 20 | } 21 | by_name = { 22 | id = data.jamfpro_static_computer_group.by_name.id 23 | name = data.jamfpro_static_computer_group.by_name.name 24 | is_smart = data.jamfpro_static_computer_group.by_name.is_smart 25 | site_id = data.jamfpro_static_computer_group.by_name.site_id 26 | computers = data.jamfpro_static_computer_group.by_name.assigned_computer_ids 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_static_mobile_device_group/data-source.tf: -------------------------------------------------------------------------------- 1 | # Query group using ID 2 | data "jamfpro_static_mobile_device_group" "by_id" { 3 | id = "1" 4 | } 5 | 6 | # Query using name 7 | data "jamfpro_static_mobile_device_group" "by_name" { 8 | name = "Development iPhones" 9 | } 10 | 11 | # Verify both lookups 12 | output "group_verification" { 13 | value = { 14 | by_id = { 15 | id = data.jamfpro_static_mobile_device_group.by_id.id 16 | name = data.jamfpro_static_mobile_device_group.by_id.name 17 | is_smart = data.jamfpro_static_mobile_device_group.by_id.is_smart 18 | site_id = data.jamfpro_static_mobile_device_group.by_id.site_id 19 | mobile_devices = data.jamfpro_static_mobile_device_group.by_id.assigned_mobile_device_ids 20 | } 21 | by_name = { 22 | id = data.jamfpro_static_mobile_device_group.by_name.id 23 | name = data.jamfpro_static_mobile_device_group.by_name.name 24 | is_smart = data.jamfpro_static_mobile_device_group.by_name.is_smart 25 | site_id = data.jamfpro_static_mobile_device_group.by_name.site_id 26 | mobile_devices = data.jamfpro_static_mobile_device_group.by_name.assigned_mobile_device_ids 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_user_group/data-source.tf: -------------------------------------------------------------------------------- 1 | data "jamfpro_user_group" "usergroup_001_data" { 2 | id = jamfpro_user_group.jamfpro_user_group_001.id 3 | } 4 | 5 | output "jamfpro_user_group_001_id" { 6 | value = data.jamfpro_user_group.usergroup_001_data.id 7 | } 8 | 9 | output "jamfpro_user_group_001_name" { 10 | value = data.jamfpro_user_group.usergroup_001_data.name 11 | } 12 | 13 | data "jamfpro_user_group" "usergroup_002_data" { 14 | id = jamfpro_user_group.jamfpro_user_group_002.id 15 | } 16 | 17 | output "jamfpro_user_group_002_id" { 18 | value = data.jamfpro_user_group.usergroup_002_data.id 19 | } 20 | 21 | output "jamfpro_user_group_002_name" { 22 | value = data.jamfpro_user_group.usergroup_002_data.name 23 | } 24 | -------------------------------------------------------------------------------- /examples/data-sources/jamfpro_webhook/data-source.tf: -------------------------------------------------------------------------------- 1 | // data source by id 2 | data "jamfpro_webhook" "webhook_001_data" { 3 | id = jamfpro_webhook.jamfpro_webhook_001.id 4 | } 5 | 6 | output "jamfpro_webhook_001_id" { 7 | value = data.jamfpro_webhook.webhook_001_data.id 8 | } 9 | 10 | output "jamfpro_webhook_001_name" { 11 | value = data.jamfpro_webhook.webhook_001_data.name 12 | } 13 | 14 | // data source list 15 | 16 | data "jamfpro_webhook_list" "example" {} 17 | 18 | output "webhook_ids" { 19 | value = data.jamfpro_webhook_list.example.ids 20 | } 21 | 22 | output "webhooks" { 23 | value = data.jamfpro_webhook_list.example.webhooks 24 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_account_driven_user_enrollment_settings/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_account_driven_user_enrollment_settings" "example" { 2 | enabled = true 3 | expiration_interval_days = 30 4 | # Optional - you can use days OR seconds, but not both 5 | expiration_interval_seconds = 2.592e+06 # 30 days in seconds. Must be in scienctific notation 6 | } 7 | 8 | # Output the configured settings 9 | output "adue_settings" { 10 | value = { 11 | enabled = jamfpro_account_driven_user_enrollment_settings.example.enabled 12 | expiration_days = jamfpro_account_driven_user_enrollment_settings.example.expiration_interval_days 13 | } 14 | description = "Account Driven User Enrollment Settings" 15 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_activation_code/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_activation_code" "activation_code_001" { 2 | organization_name = "your_organization_name" 3 | code = "UW5M-XXXX-CNAP-XXXX-CDTC-DNTV-ZAGT-XXXX" 4 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_advanced_computer_search/resource.tf: -------------------------------------------------------------------------------- 1 | 2 | resource "jamfpro_advanced_computer_search" "advanced_computer_search_001" { 3 | name = "tf - Example computer device Search" 4 | view_as = "Standard Web Page" 5 | 6 | sort1 = "Serial Number" 7 | sort2 = "Username" 8 | sort3 = "Department" 9 | 10 | criteria { 11 | name = "Building" 12 | priority = 0 13 | and_or = "and" 14 | search_type = "is" 15 | value = "square" 16 | opening_paren = true 17 | closing_paren = false 18 | } 19 | 20 | criteria { 21 | name = "Model" 22 | priority = 1 23 | and_or = "and" 24 | search_type = "is" 25 | value = "macbook air" 26 | opening_paren = false 27 | closing_paren = true 28 | } 29 | 30 | criteria { 31 | name = "Computer Name" 32 | priority = 2 33 | and_or = "or" 34 | search_type = "matches regex" 35 | value = "thing" 36 | opening_paren = true 37 | closing_paren = false 38 | } 39 | 40 | criteria { 41 | name = "Licensed Software" 42 | priority = 3 43 | and_or = "and" 44 | search_type = "has" 45 | value = "office" 46 | opening_paren = false 47 | closing_paren = true 48 | } 49 | 50 | site_id = "1" 51 | 52 | display_fields = [ 53 | "Activation Lock Manageable", 54 | "Apple Silicon", 55 | "Architecture Type", 56 | "Available RAM Slots" 57 | ] 58 | 59 | } 60 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_advanced_mobile_device_search/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_advanced_mobile_device_search" "advanced_mobile_device_search_001" { 2 | name = "tf - Example Advanced mobile device Search 2" 3 | site_id = "-1" # Optional, defaults to "-1" for None 4 | 5 | criteria { 6 | name = "Building" 7 | priority = 0 8 | and_or = "and" 9 | search_type = "is" 10 | value = "test" 11 | opening_paren = true 12 | closing_paren = false 13 | } 14 | 15 | criteria { 16 | name = "iTunes Store Account" 17 | priority = 0 18 | and_or = "and" 19 | search_type = "is" 20 | value = "Active" 21 | opening_paren = false 22 | closing_paren = true 23 | } 24 | 25 | display_fields = [ 26 | "Wi-Fi MAC Address", "Building", "iTunes Store Account", "Managed", "UDID"] 27 | } 28 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_advanced_user_search/resource.tf: -------------------------------------------------------------------------------- 1 | 2 | resource "jamfpro_advanced_user_search" "advanced_user_search_001" { 3 | name = "advanced search name" 4 | 5 | criteria { 6 | name = "Email Address" 7 | priority = 0 8 | and_or = "and" 9 | search_type = "like" 10 | value = "company.com" 11 | opening_paren = false 12 | closing_paren = false 13 | } 14 | 15 | display_fields = [ 16 | "Content ID", 17 | "Email Address", 18 | "Managed Apple ID", 19 | "Roster Class Display Name" 20 | ] 21 | 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_allowed_file_extension/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_allowed_file_extension" "allowed_file_extension_001" { 2 | extension = ".thing1" 3 | } 4 | 5 | resource "jamfpro_allowed_file_extension" "allowed_file_extension_002" { 6 | extension = ".thing2" 7 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_api_integration/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_api_integration" "jamfpro_api_integration_001" { 2 | display_name = "tf-localtest-api-integration-001" 3 | enabled = true 4 | access_token_lifetime_seconds = 7200 5 | authorization_scopes = [jamfpro_api_role.jamfpro_api_role_001.display_name] 6 | } 7 | 8 | resource "jamfpro_api_integration" "jamfpro_api_integration_002" { 9 | display_name = "tf-localtest-api-integration-002" 10 | enabled = true 11 | access_token_lifetime_seconds = 6000 12 | authorization_scopes = [jamfpro_api_role.jamfpro_api_role_002.display_name] 13 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_app_installer/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_app_installer" "jamfpro_app_installer_001" { 2 | name = "010 Editor" 3 | enabled = true 4 | deployment_type = "SELF_SERVICE" 5 | update_behavior = "AUTOMATIC" 6 | category_id = "-1" 7 | site_id = "-1" 8 | smart_group_id = "1" 9 | 10 | install_predefined_config_profiles = false 11 | trigger_admin_notifications = false 12 | 13 | notification_settings { 14 | notification_message = "A new update is available" 15 | notification_interval = 1 16 | deadline_message = "Update deadline approaching" 17 | deadline = 1 18 | quit_delay = 1 19 | complete_message = "Update completed successfully" 20 | relaunch = true 21 | suppress = false 22 | } 23 | 24 | self_service_settings { 25 | include_in_featured_category = true 26 | include_in_compliance_category = true 27 | force_view_description = true 28 | description = "This is an example app deployment" 29 | 30 | categories { 31 | id = "5" 32 | featured = true 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_app_installer_global_settings/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_app_installer_global_settings" "jamfpro_app_installer_singleton" { 2 | notification_message = "A new version of this app is ready to install." # This message is shown to users when an app update becomes available. 3 | notification_interval = 24 # Interval (in hours) between repeated user notifications about the update. 4 | deadline_message = "Please install the update to continue using the app." # Message displayed when the deadline to update has passed. 5 | deadline = 48 # Deadline (in hours) after which the app is forcibly quit and updated. 6 | quit_delay = 5 # Additional time (in minutes) for users to save their work before the app quits. 7 | complete_message = "Installation complete. You may now relaunch the app." # Message shown after successful installation. 8 | relaunch = true # If true, the app will automatically relaunch after installation. 9 | suppress = false # If true, no notifications will be shown to the end user. 10 | } 11 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_building/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_building" "jamfpro_building_001" { 2 | name = "Apple Park" 3 | street_address1 = "The McIntosh Tree" 4 | street_address2 = "One Apple Park Way" 5 | city = "Cupertino" 6 | state_province = "California" 7 | zip_postal_code = "95014" 8 | country = "The United States of America" 9 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_category/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_category" "example_category_1" { 2 | name = "tf-example-category-01" 3 | priority = 1 4 | } 5 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_client_checkin/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_client_checkin" "jamfpro_client_checkin" { 2 | check_in_frequency = 30 // Valid values: 5, 15, 30, 60 3 | create_startup_script = true 4 | startup_log = true // requires create_startup_script 5 | startup_ssh = true // requires create_startup_script 6 | startup_policies = true // requires create_startup_script 7 | create_hooks = true 8 | hook_log = true // requires create_hooks 9 | hook_policies = true // requires create_hooks 10 | enable_local_configuration_profiles = true 11 | allow_network_state_change_triggers = true 12 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_computer_extension_attribute/resource.tf: -------------------------------------------------------------------------------- 1 | # Pop-up Menu Example 2 | resource "jamfpro_computer_extension_attribute" "jamfpro_computer_extension_attribute_popup_menu_1" { 3 | name = "tf-ghatest-cexa-popup-menu-example" 4 | enabled = true 5 | description = "An attribute collected from a pop-up menu." 6 | input_type = "POPUP" 7 | popup_menu_choices = ["Option 1", "Option 2", "Option 3"] 8 | inventory_display_type = "USER_AND_LOCATION" 9 | data_type = "STRING" 10 | } 11 | 12 | # Text Field Example 13 | resource "jamfpro_computer_extension_attribute" "computer_extension_attribute_text_field_1" { 14 | name = "tf-example-cexa-text-field-example" 15 | enabled = true 16 | description = "An attribute collected from a text field." 17 | input_type = "TEXT" 18 | inventory_display_type = "HARDWARE" 19 | data_type = "STRING" 20 | } 21 | 22 | # Script Example 23 | resource "jamfpro_computer_extension_attribute" "computer_extension_attribute_script_1" { 24 | name = "tf-example-cexa-hello-world" 25 | enabled = true 26 | description = "An attribute collected via a script." 27 | input_type = "SCRIPT" 28 | script_contents = "#!/bin/bash\necho 'Hello, World!!!!! :)'" 29 | inventory_display_type = "GENERAL" 30 | data_type = "STRING" 31 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_department/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_department" "jamfpro_department_001" { 2 | name = "TF: Dept Test - 001" 3 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_device_communication_settings/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_device_communication_settings" "example" { 2 | auto_renew_mobile_device_mdm_profile_when_ca_renewed = true 3 | auto_renew_mobile_device_mdm_profile_when_device_identity_cert_expiring = true 4 | auto_renew_computer_mdm_profile_when_ca_renewed = true 5 | auto_renew_computer_mdm_profile_when_device_identity_cert_expiring = true 6 | mdm_profile_mobile_device_expiration_limit_in_days = 90 7 | mdm_profile_computer_expiration_limit_in_days = 90 8 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_device_enrollments/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_device_enrollments" "example" { 2 | name = "Test Device Enrollment" 3 | encoded_token = filebase64("/path/to/device_enrollment_token.p7m") 4 | 5 | # Optional fields 6 | supervision_identity_id = "-1" 7 | site_id = "-1" 8 | } 9 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_disk_encryption_configuration/resource.tf: -------------------------------------------------------------------------------- 1 | 2 | // jamfpro Institutional Recovery Key config tf example 3 | 4 | resource "jamfpro_disk_encryption_configuration" "disk_encryption_configuration_01" { 5 | name = "jamfpro-tf-example-InstitutionalRecoveryKey-config" 6 | key_type = "Institutional" # Or "Individual and Institutional" 7 | file_vault_enabled_users = "Management Account" # Or "Current or Next User" 8 | 9 | institutional_recovery_key { 10 | certificate_type = "PKCS12" # For .p12 certificate types 11 | password = "secretThing" 12 | data = filebase64("/Users/dafyddwatkins/localtesting/support_files/filevaultcertificate/FileVaultMaster-sdk.p12") 13 | } 14 | 15 | } 16 | 17 | // jamfpro Individual Recovery Key config tf example 18 | 19 | resource "jamfpro_disk_encryption_configuration" "disk_encryption_configuration_02" { 20 | name = "jamfpro-tf-example-IndividualRecoveryKey-config" 21 | key_type = "Individual" 22 | file_vault_enabled_users = "Management Account" # Or "Current or Next User" 23 | 24 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_dock_item/resource.tf: -------------------------------------------------------------------------------- 1 | 2 | // App Dock Item Example 3 | resource "jamfpro_dock_item" "dock_item_001" { 4 | name = "tf-example-dockItem-app-iTunes" 5 | type = "App" 6 | path = "file://localhost/Applications/iTunes.app/" 7 | } 8 | 9 | // File Dock Item Example 10 | resource "jamfpro_dock_item" "dock_item_002" { 11 | name = "tf-example-dockItem-file-hosts" 12 | type = "File" // App / File / Folder 13 | path = "/etc/hosts" 14 | } 15 | 16 | // Folder Dock Item Example 17 | resource "jamfpro_dock_item" "dock_item_003" { 18 | name = "tf-example-dockItem-folder-downloadsFolder" 19 | type = "Folder" // App / File / Folder 20 | path = "~/Downloads" 21 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_engage_settings/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_engage_settings" "example" { 2 | is_enabled = true 3 | } 4 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_file_share_distribution_point/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_file_share_distribution_points" "full_example" { 2 | // Page 1 3 | name = "tf-example-fileshare-distribution-point" 4 | ip_address = "ny.company.com" 5 | is_master = false 6 | failover_point = "Cloud Distribution Point" // Cloud Distribution Point / or any other dp defined with jamf pro 7 | enable_load_balancing = false 8 | // Page 2 9 | connection_type = "AFP" // SMB / AFP 10 | share_name = "FullExampleShareName" 11 | share_port = 445 12 | workgroup_or_domain = "EXAMPLEDOMAIN" 13 | read_only_username = "fullreadonlyuser" 14 | read_only_password = "funky_password_qwerty" 15 | read_write_username = "fullreadwriteuser" 16 | read_write_password = "funky_password_qwerty" 17 | no_authentication_required = false 18 | // page 3 19 | https_downloads_enabled = true 20 | https_port = 443 21 | https_share_path = "/contextpath" 22 | https_username_password_required = true 23 | https_username = "fullhttpuser" 24 | https_password = "funky_password_qwerty" 25 | 26 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_icon/resource.tf: -------------------------------------------------------------------------------- 1 | # Example using a local file 2 | resource "jamfpro_icon" "icon_from_local" { 3 | icon_file_path = "/Users/dafyddwatkins/localtesting/terraform/support_files/icons/firefox_logo_icon_170152.png" 4 | } 5 | 6 | # Example using a web source 7 | resource "jamfpro_icon" "icon_from_web" { 8 | icon_file_web_source = "https://upload.wikimedia.org/wikipedia/commons/1/16/Firefox_logo%2C_2017.png" 9 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_jamf_connect/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_jamf_connect" "example" { 2 | config_profile_uuid = "e9224719-906e-4879-b393-f302fa40e89d" # UUID of existing profile 3 | version = "2.43.0" # Version of Jamf Connect to deploy 4 | auto_deployment_type = "MINOR_AND_PATCH_UPDATES" 5 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_jamf_protect/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_jamf_protect" "settings" { 2 | protect_url = "https://myinstance.protect.jamfcloud.com/graphql" 3 | client_id = "supersecretclientid" 4 | password = "supersecretpassword" 5 | auto_install = true 6 | 7 | timeouts { 8 | create = "90s" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_local_admin_password_settings/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_local_admin_password_settings" "local_admin_password_settings_001" { 2 | auto_deploy_enabled = false 3 | password_rotation_time_seconds = 3600 4 | auto_rotate_enabled = false 5 | auto_rotate_expiration_time_seconds = 7776000 6 | } 7 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_managed_software_update_feature_toggle/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_managed_software_update_feature_toggle" "example" { 2 | toggle = true 3 | } 4 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_managed_software_updates/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_managed_software_update" "specific_version_update" { 2 | group { 3 | group_id = "2" 4 | object_type = "COMPUTER" 5 | } 6 | 7 | config { 8 | update_action = "DOWNLOAD_INSTALL_ALLOW_DEFERRAL" 9 | version_type = "SPECIFIC_VERSION" 10 | specific_version = "15.1" 11 | max_deferrals = 3 12 | } 13 | } 14 | 15 | resource "jamfpro_managed_software_update" "specific_version_update" { 16 | group { 17 | group_id = "2" 18 | object_type = "MOBILE_DEVICE" 19 | } 20 | 21 | config { 22 | update_action = "DOWNLOAD_INSTALL_ALLOW_DEFERRAL" 23 | version_type = "SPECIFIC_VERSION" 24 | specific_version = "15.1" 25 | max_deferrals = 3 26 | } 27 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_mobile_device_extension_attribute/resource.tf: -------------------------------------------------------------------------------- 1 | # Pop-up menu Example 2 | resource "jamfpro_mobile_device_extension_attribute" "popup_menu_example" { 3 | name = "Device Location" 4 | description = "The primary location where this device is used" 5 | data_type = "String" 6 | inventory_display = "User and Location" 7 | 8 | input_type { 9 | type = "Pop-up Menu" 10 | popup_choices = [ 11 | "Head Office", 12 | "Branch Office", 13 | "Home Office", 14 | "Client Site" 15 | ] 16 | } 17 | } 18 | 19 | # Text Field Example 20 | resource "jamfpro_mobile_device_extension_attribute" "text_field_example" { 21 | name = "User Department" 22 | description = "The department to which the device user belongs" 23 | data_type = "String" 24 | inventory_display = "General" 25 | 26 | input_type { 27 | type = "Text Field" 28 | } 29 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_network_segment/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_network_segment" "jamfpro_network_segment_001" { 2 | name = "Example Network Segment" 3 | starting_address = "192.168.1.1" 4 | ending_address = "192.168.1.254" 5 | distribution_server = "Example Distribution Server" 6 | distribution_point = "Example Distribution Point" 7 | url = "http://example.com" 8 | swu_server = "Example SWU Server" 9 | building = "Main Building" 10 | department = "IT Department" 11 | override_buildings = true 12 | override_departments = false 13 | } 14 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_printer/resource.tf: -------------------------------------------------------------------------------- 1 | // Specific printer ppd 2 | resource "jamfpro_printer" "jamfpro_printers_001" { 3 | name = "tf-example-printer-specific_ppd-01" 4 | category_name = "No category assigned" 5 | uri = "lpd://10.1.20.204/" 6 | cups_name = "HP_DesignJet_1050C_PS3" 7 | location = "string" 8 | model = "HP DesignJet 1050C PS3" 9 | info = "string" 10 | notes = "string" 11 | make_default = true 12 | use_generic = false 13 | ppd = "HP_DesignJet_1050C_PS3.ppd" 14 | ppd_path = "/somepath" 15 | ppd_contents = file("/Users/dafyddwatkins/localtesting/support_files/printerppd/HP_DesignJet_1050C_PS3.ppd") 16 | } 17 | 18 | // Generic printer ppd 19 | resource "jamfpro_printer" "jamfpro_printers_002" { 20 | name = "tf-example-printer-generic_ppd-01" 21 | category_name = "No category assigned" 22 | uri = "lpd://10.1.20.204/" 23 | cups_name = "HP_9th_Floor" 24 | location = "string" 25 | model = "HP LaserJet 500 color MFP M575" 26 | info = "string" 27 | notes = "string" 28 | make_default = false 29 | use_generic = true 30 | ppd = "" 31 | ppd_path = "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/PrintCore.framework/Resources/Generic.ppd" 32 | ppd_contents = "" 33 | } 34 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_restricted_software/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_restricted_software" "restricted_software_high_sierra" { 2 | name = "tf-localtest-restrict-high-sierra" 3 | process_name = "Install macOS High Sierra.app" 4 | match_exact_process_name = true 5 | send_notification = true 6 | kill_process = true 7 | delete_executable = true 8 | display_message = "This software is restricted and will be terminated." 9 | 10 | # optional 11 | site_id { 12 | id = -1 13 | } 14 | 15 | scope { 16 | all_computers = false 17 | computer_ids = ([23, 22]) 18 | computer_group_ids = ([13, 12]) 19 | building_ids = ([1536, 1534]) 20 | department_ids = ([37501, 37503]) 21 | exclusions { 22 | computer_ids = [14, 15] 23 | computer_group_ids = ([13, 12]) 24 | building_ids = ([1536, 1534]) 25 | department_ids = ([37501, 37503]) 26 | directory_service_or_local_usernames = ["Jane Smith", "John Doe"] 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_script/resource.tf: -------------------------------------------------------------------------------- 1 | 2 | // Script example an uploaded script taken from a file path with parameters 3 | resource "jamfpro_script" "scripts_0001" { 4 | name = "tf-example-script-fileupload" 5 | script_contents = file("support_files/scripts/Add or Remove Group Membership.zsh") 6 | category_id = 5 7 | os_requirements = "13" 8 | priority = "BEFORE" 9 | info = "Adds target user or group to specified group membership, or removes said membership." 10 | notes = "Jamf Pro script parameters 4 -> 7" 11 | parameter4 = "100" // targetID 12 | parameter5 = "group" // Target Type - Must be either "user" or "group" 13 | parameter6 = "someGroupName" // targetMembership 14 | parameter7 = "add" // Script Action - Must be either "add" or "remove" 15 | } 16 | 17 | // Script example with an inline script 18 | resource "jamfpro_script" "scripts_0002" { 19 | name = "tf-example-script-inline" 20 | script_contents = "hello world" 21 | os_requirements = "13.1" 22 | priority = "BEFORE" 23 | info = "Your script info here." 24 | notes = "" 25 | 26 | } 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_self_service_settings/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_self_service_settings" "example" { 2 | install_automatically = true 3 | install_location = "/Applications" 4 | user_login_level = "Anonymous" 5 | allow_remember_me = true 6 | use_fido2 = false 7 | auth_type = "Basic" 8 | notifications_enabled = true 9 | alert_user_approved_mdm = true 10 | default_landing_page = "HOME" 11 | default_home_category_id = -1 12 | bookmarks_name = "Bookmarks" 13 | } 14 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_site/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_site" "example_site_1" { 2 | name = "tf-example-site-01" 3 | } 4 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_smart_computer_group/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_smart_computer_group" "smart_example" { 2 | name = "Example Smart Computer Group" 3 | 4 | # Optional: Specify site details 5 | site_id = 5 6 | 7 | # Optional: Define criteria for Smart groups 8 | criteria { 9 | name = "Criterion Name #1" 10 | priority = 0 # 0 is the highest priority, 1 is the next highest, etc. 11 | and_or = "and" # or "or", defaults to "and" if not provided 12 | search_type = "is" # or any other supported search type 13 | value = "Criterion Value" 14 | opening_paren = false # true or false, defaults to false if not provided 15 | closing_paren = false # true or false, defaults to false if not provided 16 | } 17 | 18 | criteria { 19 | name = "Criterion Name #n+1 etc" 20 | priority = 1 21 | and_or = "and" # or "or", defaults to "and" if not provided 22 | search_type = "is" # or any other supported search type 23 | value = "Criterion Value" 24 | opening_paren = false # true or false, defaults to false if not provided 25 | closing_paren = false # true or false, defaults to false if not provided 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_smart_mobile_device_group/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_smart_mobile_device_group" "smart_example" { 2 | name = "Example Smart Mobile Device Group" 3 | 4 | # Optional: Specify site details 5 | site_id = 5 6 | 7 | # Optional: Define criteria for Smart groups 8 | criteria { 9 | name = "Criterion Name #1" 10 | priority = 0 # 0 is the highest priority, 1 is the next highest, etc. 11 | and_or = "and" # or "or", defaults to "and" if not provided 12 | search_type = "is" # or any other supported search type 13 | value = "Criterion Value" 14 | opening_paren = false # true or false, defaults to false if not provided 15 | closing_paren = false # true or false, defaults to false if not provided 16 | } 17 | 18 | criteria { 19 | name = "Criterion Name #n+1 etc" 20 | priority = 1 21 | and_or = "and" # or "or", defaults to "and" if not provided 22 | search_type = "is" # or any other supported search type 23 | value = "Criterion Value" 24 | opening_paren = false # true or false, defaults to false if not provided 25 | closing_paren = false # true or false, defaults to false if not provided 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_sso_certificate/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_sso_certificate" "currrent" {} 2 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_sso_failover/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_sso_failover" "current" {} 2 | 3 | output "failover_url" { 4 | value = jamfpro_sso_failover.current.failover_url 5 | sensitive = true 6 | } 7 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_static_computer_group/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_static_computer_group" "jamfpro_static_computer_group_001" { 2 | name = "Example Static Computer Group" 3 | 4 | 5 | # Optional Block 6 | site_id = 1 7 | 8 | # Optional: Specify computers for static groups 9 | assigned_computer_ids = [1, 2, 3] 10 | } -------------------------------------------------------------------------------- /examples/resources/jamfpro_static_mobile_device_group/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_static_mobile_device_group" "jamfpro_static_mobile_device_group_001" { 2 | name = "Example Mobile Device Group" 3 | 4 | 5 | # Optional Block 6 | site_id = 1 7 | 8 | # Optional: Specify computers for static groups 9 | assigned_mobile_device_ids = [1, 2, 3] 10 | } 11 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_volume_purchasing_locations/resource.tf: -------------------------------------------------------------------------------- 1 | resource "jamfpro_volume_purchasing_locations" "example" { 2 | name = "Company Apple Business Manager" 3 | service_token = "eyJleHBEYXRlIjo..." # Your base64 encoded service token 4 | automatically_populate_purchased_content = true 5 | send_notification_when_no_longer_assigned = false 6 | auto_register_managed_users = true 7 | site_id = "-1" # Default site 8 | } 9 | -------------------------------------------------------------------------------- /examples/resources/jamfpro_webhook/resource.tf: -------------------------------------------------------------------------------- 1 | // Webhook example 2 | resource "jamfpro_webhook" "jamfpro_webhook_001" { 3 | name = "ExampleWebhook" 4 | enabled = true 5 | url = "https://example.com/webhook" 6 | content_type = "application/json" 7 | event = "DeviceAddedToDEP" 8 | connection_timeout = 5 9 | read_timeout = 5 10 | authentication_type = "BASIC" 11 | username = "exampleUser" 12 | password = "examplePassword" 13 | 14 | } 15 | 16 | // Webhook example with smart group 17 | resource "jamfpro_webhook" "jamfpro_webhook_001" { 18 | name = "ExampleWebhook" 19 | enabled = true 20 | url = "https://example.com/webhook" 21 | content_type = "application/json" 22 | event = "SmartGroupComputerMembershipChange" 23 | connection_timeout = 5 24 | read_timeout = 5 25 | authentication_type = "BASIC" 26 | username = "exampleUser" 27 | password = "examplePassword" 28 | smart_group_id = jamfpro_smart_group.jamfpro_smart_group_001.id 29 | 30 | } -------------------------------------------------------------------------------- /internal/provider/timeouts.go: -------------------------------------------------------------------------------- 1 | package provider 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | const ( 8 | DefaultContextTimeout = 75 * time.Second 9 | LoadBalancedContextTimeout = 15 * time.Second 10 | ) 11 | 12 | // GetDefaultContextTimeoutCreate returns the appropriate timeout duration for resource creation. 13 | // If load balancer lock is enabled, it returns the LoadBalancedContextTimeoutCreate, 14 | // otherwise it returns the DefaultContextTimeoutCreate. 15 | func Timeout(load_balancer_lock_enabled bool) time.Duration { 16 | if load_balancer_lock_enabled { 17 | return LoadBalancedContextTimeout 18 | } 19 | return DefaultContextTimeout 20 | } 21 | 22 | // resourceTimeout holds timeouts, used in overrides 23 | type resourceTimeout struct { 24 | Create, Read, Update, Delete time.Duration 25 | } 26 | 27 | // Overrides returns a list of timeout overrides by their resource key 28 | func TimeoutOverrides(lb_lock bool) map[string]resourceTimeout { 29 | return map[string]resourceTimeout{ 30 | "jamfpro_package": { 31 | Create: 45 * time.Minute, 32 | Read: Timeout(lb_lock), 33 | Update: 45 * time.Minute, 34 | Delete: Timeout(lb_lock), 35 | }, 36 | "jamfpro_smart_computer_group": { 37 | Create: 75 * time.Second, 38 | Read: 75 * time.Second, 39 | Update: 75 * time.Second, 40 | Delete: 75 * time.Second, 41 | }, 42 | "jamfpro_static_computer_group": { 43 | Create: 75 * time.Second, 44 | Read: 75 * time.Second, 45 | Update: 75 * time.Second, 46 | Delete: 75 * time.Second, 47 | }, 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /internal/resources/account_driven_user_enrollment_settings/constructor.go: -------------------------------------------------------------------------------- 1 | package account_driven_user_enrollment_settings 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "log" 7 | 8 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 10 | ) 11 | 12 | // construct builds the request for UpdateADUESessionTokenSettings 13 | func construct(d *schema.ResourceData) (*jamfpro.ResourceADUETokenSettings, error) { 14 | resource := &jamfpro.ResourceADUETokenSettings{ 15 | Enabled: d.Get("enabled").(bool), 16 | } 17 | 18 | // Add optional fields if they exist in the schema 19 | if v, ok := d.GetOk("expiration_interval_days"); ok { 20 | resource.ExpirationIntervalDays = v.(int) 21 | } 22 | 23 | if v, ok := d.GetOk("expiration_interval_seconds"); ok { 24 | resource.ExpirationIntervalSeconds = v.(int) 25 | } 26 | 27 | resourceJSON, err := json.MarshalIndent(resource, "", " ") 28 | if err != nil { 29 | return nil, fmt.Errorf("failed to marshal Account Driven User Enrollment Settings to JSON: %v", err) 30 | } 31 | log.Printf("[DEBUG] Constructed Account Driven User Enrollment Settings resource:\n%s", string(resourceJSON)) 32 | 33 | return resource, nil 34 | } 35 | -------------------------------------------------------------------------------- /internal/resources/account_driven_user_enrollment_settings/state.go: -------------------------------------------------------------------------------- 1 | package account_driven_user_enrollment_settings 2 | 3 | import ( 4 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 5 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 7 | ) 8 | 9 | // updateState updates the Terraform state with the latest Account Driven User Enrollment Settings from the Jamf Pro API. 10 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceADUETokenSettings) diag.Diagnostics { 11 | var diags diag.Diagnostics 12 | 13 | if err := d.Set("enabled", resp.Enabled); err != nil { 14 | diags = append(diags, diag.FromErr(err)...) 15 | } 16 | 17 | if err := d.Set("expiration_interval_days", resp.ExpirationIntervalDays); err != nil { 18 | diags = append(diags, diag.FromErr(err)...) 19 | } 20 | 21 | if err := d.Set("expiration_interval_seconds", resp.ExpirationIntervalSeconds); err != nil { 22 | diags = append(diags, diag.FromErr(err)...) 23 | } 24 | 25 | return diags 26 | } 27 | -------------------------------------------------------------------------------- /internal/resources/account_group/helpers.go: -------------------------------------------------------------------------------- 1 | // accountgroups_data_handling.go 2 | package account_group 3 | 4 | import ( 5 | "context" 6 | "fmt" 7 | 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | ) 10 | 11 | // customDiffAccountGroups is a custom diff function for the Jamf Pro Account resource. 12 | // This function is used during the Terraform plan phase to apply custom validation rules 13 | // that are not covered by the basic schema validation. 14 | func customDiffAccountGroups(ctx context.Context, d *schema.ResourceDiff, meta interface{}) error { 15 | accessLevel := d.Get("access_level").(string) 16 | 17 | if accessLevel == "Site Access" { 18 | if _, ok := d.GetOk("site_id"); !ok { 19 | return fmt.Errorf("'site' must be set when 'access_level' is 'Site Access'") 20 | } 21 | } 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /internal/resources/activation_code/constructor.go: -------------------------------------------------------------------------------- 1 | // activationcode_object.go 2 | package activation_code 3 | 4 | import ( 5 | "encoding/xml" 6 | "fmt" 7 | "log" 8 | 9 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | ) 12 | 13 | // constructJamfProActivationCode constructs a ResourceActivationCode object from the provided schema data and logs its XML representation. 14 | func construct(d *schema.ResourceData) (*jamfpro.ResourceActivationCode, error) { 15 | resource := &jamfpro.ResourceActivationCode{ 16 | OrganizationName: d.Get("organization_name").(string), 17 | Code: d.Get("code").(string), 18 | } 19 | 20 | resourceXML, err := xml.MarshalIndent(resource, "", " ") 21 | if err != nil { 22 | return nil, fmt.Errorf("failed to marshal Jamf Pro Activation Code to XML: %v", err) 23 | } 24 | 25 | log.Printf("[DEBUG] Constructed Jamf Pro Activation Code XML:\n%s\n", string(resourceXML)) 26 | 27 | return resource, nil 28 | } 29 | -------------------------------------------------------------------------------- /internal/resources/activation_code/resource.go: -------------------------------------------------------------------------------- 1 | // activationcode_resource.go 2 | package activation_code 3 | 4 | import ( 5 | "time" 6 | 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // resourceJamfProActivationCode defines the schema and CRUD operations for managing Jamf Pro activation code configuration in Terraform. 11 | func ResourceJamfProActivationCode() *schema.Resource { 12 | return &schema.Resource{ 13 | CreateContext: create, 14 | ReadContext: read, 15 | UpdateContext: update, 16 | DeleteContext: delete, 17 | Timeouts: &schema.ResourceTimeout{ 18 | Create: schema.DefaultTimeout(70 * time.Second), 19 | Read: schema.DefaultTimeout(70 * time.Second), 20 | Update: schema.DefaultTimeout(70 * time.Second), 21 | Delete: schema.DefaultTimeout(70 * time.Second), 22 | }, 23 | Importer: &schema.ResourceImporter{ 24 | StateContext: schema.ImportStatePassthroughContext, 25 | }, 26 | Schema: map[string]*schema.Schema{ 27 | "organization_name": { 28 | Type: schema.TypeString, 29 | Required: true, 30 | Description: "The name of the organization associated with the activation code.", 31 | }, 32 | "code": { 33 | Type: schema.TypeString, 34 | Required: true, 35 | Sensitive: true, 36 | Description: "The activation code.", 37 | }, 38 | }, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /internal/resources/activation_code/state.go: -------------------------------------------------------------------------------- 1 | // activationcode_state.go 2 | package activation_code 3 | 4 | import ( 5 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // updateState updates the Terraform state with the latest Activation Code information from the Jamf Pro API. 11 | func updateState(d *schema.ResourceData, resource *jamfpro.ResourceActivationCode) diag.Diagnostics { 12 | var diags diag.Diagnostics 13 | var err error 14 | 15 | err = d.Set("organization_name", resource.OrganizationName) 16 | if err != nil { 17 | diags = append(diags, diag.FromErr(err)...) 18 | } 19 | 20 | err = d.Set("code", resource.Code) 21 | if err != nil { 22 | diags = append(diags, diag.FromErr(err)...) 23 | } 24 | 25 | return diags 26 | } 27 | -------------------------------------------------------------------------------- /internal/resources/allowed_file_extension/constructor.go: -------------------------------------------------------------------------------- 1 | // allowedfileextensions_object.go 2 | package allowed_file_extension 3 | 4 | import ( 5 | "encoding/xml" 6 | "fmt" 7 | "log" 8 | 9 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | ) 12 | 13 | // constructJamfProAllowedFileExtension creates a new ResourceAllowedFileExtension instance from Terraform data and serializes it to XML. 14 | func construct(d *schema.ResourceData) (*jamfpro.ResourceAllowedFileExtension, error) { 15 | resource := &jamfpro.ResourceAllowedFileExtension{ 16 | Extension: d.Get("extension").(string), 17 | } 18 | 19 | resourceXML, err := xml.MarshalIndent(resource, "", " ") 20 | if err != nil { 21 | return nil, fmt.Errorf("failed to marshal Jamf Pro Allowed File Extension '%s' to XML: %v", resource.Extension, err) 22 | } 23 | 24 | log.Printf("[DEBUG] Constructed Jamf Pro Allowed File Extension XML:\n%s\n", string(resourceXML)) 25 | 26 | return resource, nil 27 | } 28 | -------------------------------------------------------------------------------- /internal/resources/allowed_file_extension/resource.go: -------------------------------------------------------------------------------- 1 | // allowedfileextensions_resource.go 2 | package allowed_file_extension 3 | 4 | import ( 5 | "time" 6 | 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // resourceJamfProAllowedFileExtensions defines the schema and CRUD operations for managing AllowedFileExtentionss in Terraform. 11 | func ResourceJamfProAllowedFileExtensions() *schema.Resource { 12 | return &schema.Resource{ 13 | CreateContext: create, 14 | ReadContext: readWithCleanup, 15 | UpdateContext: update, 16 | DeleteContext: delete, 17 | Timeouts: &schema.ResourceTimeout{ 18 | Create: schema.DefaultTimeout(70 * time.Second), 19 | Read: schema.DefaultTimeout(70 * time.Second), 20 | Update: schema.DefaultTimeout(70 * time.Second), 21 | Delete: schema.DefaultTimeout(70 * time.Second), 22 | }, 23 | Importer: &schema.ResourceImporter{ 24 | StateContext: schema.ImportStatePassthroughContext, 25 | }, 26 | Schema: map[string]*schema.Schema{ 27 | "id": { 28 | Type: schema.TypeString, 29 | Computed: true, 30 | }, 31 | "extension": { 32 | Type: schema.TypeString, 33 | Required: true, 34 | }, 35 | }, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /internal/resources/allowed_file_extension/state.go: -------------------------------------------------------------------------------- 1 | // allowedfileextensions_state.go 2 | package allowed_file_extension 3 | 4 | import ( 5 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // updateState updates the Terraform state with the latest Allowed File Extension information from the Jamf Pro API. 11 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceAllowedFileExtension) diag.Diagnostics { 12 | var diags diag.Diagnostics 13 | 14 | if err := d.Set("extension", resp.Extension); err != nil { 15 | diags = append(diags, diag.FromErr(err)...) 16 | } 17 | 18 | return diags 19 | } 20 | -------------------------------------------------------------------------------- /internal/resources/api_integration/constructor.go: -------------------------------------------------------------------------------- 1 | // apiintegrations_data_object.go 2 | package api_integration 3 | 4 | import ( 5 | "encoding/json" 6 | "fmt" 7 | "log" 8 | 9 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | ) 12 | 13 | // constructJamfProApiIntegration constructs a ResourceApiIntegration object from the provided schema data and serializes it to JSON. 14 | func construct(d *schema.ResourceData) (*jamfpro.ResourceApiIntegration, error) { 15 | resource := &jamfpro.ResourceApiIntegration{ 16 | DisplayName: d.Get("display_name").(string), 17 | Enabled: d.Get("enabled").(bool), 18 | AccessTokenLifetimeSeconds: d.Get("access_token_lifetime_seconds").(int), 19 | } 20 | 21 | if v, ok := d.GetOk("authorization_scopes"); ok { 22 | scopesList := v.(*schema.Set).List() 23 | authorizationScopes := make([]string, len(scopesList)) 24 | for i, scope := range scopesList { 25 | scopeStr, ok := scope.(string) 26 | if !ok { 27 | return nil, fmt.Errorf("failed to assert authorization scope to string") 28 | } 29 | authorizationScopes[i] = scopeStr 30 | } 31 | resource.AuthorizationScopes = authorizationScopes 32 | } 33 | 34 | resourceJSON, err := json.MarshalIndent(resource, "", " ") 35 | if err != nil { 36 | return nil, fmt.Errorf("failed to marshal Jamf Pro Api Integration '%s' to JSON: %v", resource.DisplayName, err) 37 | } 38 | 39 | log.Printf("[DEBUG] Constructed Jamf Pro Api Integration JSON:\n%s\n", string(resourceJSON)) 40 | 41 | return resource, nil 42 | } 43 | -------------------------------------------------------------------------------- /internal/resources/api_integration/helpers.go: -------------------------------------------------------------------------------- 1 | // apiintegrations_data_validation.go 2 | package api_integration 3 | 4 | import ( 5 | "context" 6 | "fmt" 7 | 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | ) 10 | 11 | // validateResourceAPIIntegrationsDataFields ensures that the authorization_scopes attribute always contains at least one value. 12 | func validateResourceAPIIntegrationsDataFields(ctx context.Context, diff *schema.ResourceDiff, v interface{}) error { 13 | scopes, ok := diff.GetOk("authorization_scopes") 14 | if !ok { 15 | return fmt.Errorf("authorization_scopes must be provided") 16 | } 17 | 18 | scopesSet, ok := scopes.(*schema.Set) 19 | if !ok { 20 | return fmt.Errorf("authorization_scopes is not a valid set") 21 | } 22 | 23 | scopesList := scopesSet.List() 24 | if len(scopesList) == 0 { 25 | return fmt.Errorf("authorization_scopes must include at least one authorization scope") 26 | } 27 | 28 | return nil 29 | } 30 | -------------------------------------------------------------------------------- /internal/resources/api_integration/state.go: -------------------------------------------------------------------------------- 1 | // apiintegrations_state.go 2 | package api_integration 3 | 4 | import ( 5 | "fmt" 6 | 7 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 10 | ) 11 | 12 | // updateState updates the Terraform state with the latest API Integration information from the Jamf Pro API. 13 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceApiIntegration) diag.Diagnostics { 14 | var diags diag.Diagnostics 15 | 16 | apiIntegrationData := map[string]interface{}{ 17 | "display_name": resp.DisplayName, 18 | "enabled": resp.Enabled, 19 | "access_token_lifetime_seconds": resp.AccessTokenLifetimeSeconds, 20 | "app_type": resp.AppType, 21 | "authorization_scopes": resp.AuthorizationScopes, 22 | "client_id": resp.ClientID, 23 | } 24 | 25 | for key, val := range apiIntegrationData { 26 | if err := d.Set(key, val); err != nil { 27 | diags = append(diags, diag.FromErr(fmt.Errorf("failed to set '%s': %v", key, err))...) 28 | } 29 | } 30 | 31 | return diags 32 | 33 | } 34 | -------------------------------------------------------------------------------- /internal/resources/api_role/state.go: -------------------------------------------------------------------------------- 1 | // apiroles_state.go 2 | package api_role 3 | 4 | import ( 5 | "fmt" 6 | 7 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 10 | ) 11 | 12 | // updateState updates the Terraform state with the latest API Role information from the Jamf Pro API. 13 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceAPIRole) diag.Diagnostics { 14 | var diags diag.Diagnostics 15 | 16 | apiRoleData := map[string]interface{}{ 17 | "id": resp.ID, 18 | "display_name": resp.DisplayName, 19 | "privileges": resp.Privileges, 20 | } 21 | 22 | for key, val := range apiRoleData { 23 | if err := d.Set(key, val); err != nil { 24 | diags = append(diags, diag.FromErr(fmt.Errorf("failed to set '%s': %v", key, err))...) 25 | } 26 | } 27 | 28 | return diags 29 | } 30 | -------------------------------------------------------------------------------- /internal/resources/app_installer_global_settings/state.go: -------------------------------------------------------------------------------- 1 | package app_installer_global_settings 2 | 3 | import ( 4 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 5 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 7 | ) 8 | 9 | // updateState updates the Terraform state with the latest Client Check-In information from the Jamf Pro API. 10 | func updateState(d *schema.ResourceData, resp *jamfpro.ResponseJamfAppCatalogGlobalSettings) diag.Diagnostics { 11 | var diags diag.Diagnostics 12 | settings := resp.EndUserExperienceSettings 13 | 14 | stateData := map[string]interface{}{ 15 | "notification_message": settings.NotificationMessage, 16 | "notification_interval": settings.NotificationInterval, 17 | "deadline_message": settings.DeadlineMessage, 18 | "deadline": settings.Deadline, 19 | "quit_delay": settings.QuitDelay, 20 | "complete_message": settings.CompleteMessage, 21 | "relaunch": settings.Relaunch, 22 | "suppress": settings.Suppress, 23 | } 24 | 25 | for key, val := range stateData { 26 | if err := d.Set(key, val); err != nil { 27 | diags = append(diags, diag.FromErr(err)...) 28 | } 29 | } 30 | 31 | return diags 32 | } 33 | -------------------------------------------------------------------------------- /internal/resources/building/constructor.go: -------------------------------------------------------------------------------- 1 | // buildings_object.go 2 | package building 3 | 4 | import ( 5 | "encoding/json" 6 | "fmt" 7 | "log" 8 | 9 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | ) 12 | 13 | // constructJamfProBuilding constructs a Building object from the provided schema data. 14 | func construct(d *schema.ResourceData) (*jamfpro.ResourceBuilding, error) { 15 | resource := &jamfpro.ResourceBuilding{ 16 | Name: d.Get("name").(string), 17 | StreetAddress1: d.Get("street_address1").(string), 18 | StreetAddress2: d.Get("street_address2").(string), 19 | City: d.Get("city").(string), 20 | StateProvince: d.Get("state_province").(string), 21 | ZipPostalCode: d.Get("zip_postal_code").(string), 22 | Country: d.Get("country").(string), 23 | } 24 | 25 | // Serialize and pretty-print the Building object as JSON for logging 26 | resourceJSON, err := json.MarshalIndent(resource, "", " ") 27 | if err != nil { 28 | return nil, fmt.Errorf("failed to marshal Jamf Pro Building '%s' to JSON: %v", resource.Name, err) 29 | } 30 | 31 | log.Printf("[DEBUG] Constructed Jamf Pro Building JSON:\n%s\n", string(resourceJSON)) 32 | 33 | return resource, nil 34 | } 35 | -------------------------------------------------------------------------------- /internal/resources/building/state.go: -------------------------------------------------------------------------------- 1 | // state.go 2 | package building 3 | 4 | import ( 5 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // updateState updates the Terraform state with the latest Building information from the Jamf Pro API. 11 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceBuilding) diag.Diagnostics { 12 | var diags diag.Diagnostics 13 | 14 | buildingData := map[string]interface{}{ 15 | "name": resp.Name, 16 | "street_address1": resp.StreetAddress1, 17 | "street_address2": resp.StreetAddress2, 18 | "city": resp.City, 19 | "state_province": resp.StateProvince, 20 | "zip_postal_code": resp.ZipPostalCode, 21 | "country": resp.Country, 22 | } 23 | 24 | for key, val := range buildingData { 25 | if err := d.Set(key, val); err != nil { 26 | diags = append(diags, diag.FromErr(err)...) 27 | } 28 | } 29 | 30 | return diags 31 | 32 | } 33 | -------------------------------------------------------------------------------- /internal/resources/category/constructor.go: -------------------------------------------------------------------------------- 1 | // categories_data_object.go 2 | package category 3 | 4 | import ( 5 | "encoding/xml" 6 | "fmt" 7 | "log" 8 | 9 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | ) 12 | 13 | // constructJamfProCategory constructs a Jamf Pro Category struct from Terraform resource data. 14 | func construct(d *schema.ResourceData) (*jamfpro.ResourceCategory, error) { 15 | resource := &jamfpro.ResourceCategory{ 16 | Name: d.Get("name").(string), 17 | Priority: d.Get("priority").(int), 18 | } 19 | 20 | resourceXML, err := xml.MarshalIndent(resource, "", " ") 21 | if err != nil { 22 | return nil, fmt.Errorf("failed to marshal Jamf Pro Category '%s' to XML: %v", resource.Name, err) 23 | } 24 | 25 | log.Printf("[DEBUG] Constructed Jamf Pro Category XML:\n%s\n", string(resourceXML)) 26 | 27 | return resource, nil 28 | } 29 | -------------------------------------------------------------------------------- /internal/resources/category/resource.go: -------------------------------------------------------------------------------- 1 | // categories_resource.go 2 | package category 3 | 4 | import ( 5 | "time" 6 | 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // resourceJamfProCategories defines the schema and CRUD operations for managing Jamf Pro Categories in Terraform. 11 | func ResourceJamfProCategories() *schema.Resource { 12 | return &schema.Resource{ 13 | CreateContext: create, 14 | ReadContext: readWithCleanup, 15 | UpdateContext: update, 16 | DeleteContext: delete, 17 | Timeouts: &schema.ResourceTimeout{ 18 | Create: schema.DefaultTimeout(70 * time.Second), 19 | Read: schema.DefaultTimeout(70 * time.Second), 20 | Update: schema.DefaultTimeout(70 * time.Second), 21 | Delete: schema.DefaultTimeout(70 * time.Second), 22 | }, 23 | Importer: &schema.ResourceImporter{ 24 | StateContext: schema.ImportStatePassthroughContext, 25 | }, 26 | Schema: map[string]*schema.Schema{ 27 | "id": { 28 | Type: schema.TypeString, 29 | Computed: true, 30 | Description: "The unique identifier of the category.", 31 | }, 32 | "name": { 33 | Type: schema.TypeString, 34 | Required: true, 35 | Description: "The unique name of the Jamf Pro category.", 36 | }, 37 | "priority": { 38 | Type: schema.TypeInt, 39 | Optional: true, 40 | Default: 9, 41 | Description: "The priority of the Jamf Pro category.", 42 | }, 43 | }, 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /internal/resources/category/state.go: -------------------------------------------------------------------------------- 1 | // categories_state.go 2 | package category 3 | 4 | import ( 5 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // updateState updates the Terraform state with the latest Category information from the Jamf Pro API. 11 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceCategory) diag.Diagnostics { 12 | var diags diag.Diagnostics 13 | 14 | if err := d.Set("id", resp.Id); err != nil { 15 | diags = append(diags, diag.FromErr(err)...) 16 | } 17 | if err := d.Set("name", resp.Name); err != nil { 18 | diags = append(diags, diag.FromErr(err)...) 19 | } 20 | if err := d.Set("priority", resp.Priority); err != nil { 21 | diags = append(diags, diag.FromErr(err)...) 22 | } 23 | 24 | return diags 25 | } 26 | -------------------------------------------------------------------------------- /internal/resources/client_checkin/state.go: -------------------------------------------------------------------------------- 1 | package client_checkin 2 | 3 | import ( 4 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 5 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 7 | ) 8 | 9 | // updateState updates the Terraform state with the latest Client Check-In information from the Jamf Pro API. 10 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceClientCheckinSettings) diag.Diagnostics { 11 | var diags diag.Diagnostics 12 | 13 | checkinData := map[string]interface{}{ 14 | "check_in_frequency": resp.CheckInFrequency, 15 | "create_hooks": resp.CreateHooks, 16 | "hook_log": resp.HookLog, 17 | "hook_policies": resp.HookPolicies, 18 | "create_startup_script": resp.CreateStartupScript, 19 | "startup_log": resp.StartupLog, 20 | "startup_policies": resp.StartupPolicies, 21 | "startup_ssh": resp.StartupSsh, 22 | "enable_local_configuration_profiles": resp.EnableLocalConfigurationProfiles, 23 | } 24 | 25 | for key, val := range checkinData { 26 | if err := d.Set(key, val); err != nil { 27 | diags = append(diags, diag.FromErr(err)...) 28 | } 29 | } 30 | 31 | return diags 32 | } 33 | -------------------------------------------------------------------------------- /internal/resources/cloudidp/state.go: -------------------------------------------------------------------------------- 1 | // cloudidp_state.go 2 | package cloudidp 3 | 4 | import ( 5 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // updateState updates the Terraform state with the latest Cloud Identity Provider information from the Jamf Pro API. 11 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceCloudIdentityProvider) diag.Diagnostics { 12 | var diags diag.Diagnostics 13 | 14 | resourceData := map[string]interface{}{ 15 | "id": resp.ID, 16 | "display_name": resp.DisplayName, 17 | "enabled": resp.Enabled, 18 | "provider_name": resp.ProviderName, 19 | } 20 | 21 | for key, val := range resourceData { 22 | if err := d.Set(key, val); err != nil { 23 | return diag.FromErr(err) 24 | } 25 | } 26 | 27 | return diags 28 | } 29 | -------------------------------------------------------------------------------- /internal/resources/common/configurationprofiles/plist/validate.go: -------------------------------------------------------------------------------- 1 | // common/configurationprofiles/plist/validate.go 2 | package plist 3 | 4 | import ( 5 | "fmt" 6 | "reflect" 7 | "strings" 8 | ) 9 | 10 | // ValidatePayloadFields validates the mapstructure field tags of a ConfigurationProfile struct 11 | // and ensures that the required struct field tags are present and correctly populated. 12 | // It checks for specific validation rules, such as ensuring that required fields are not empty. 13 | // Additional custom validation rules can be added within this function to enforce other constraints 14 | // based on the `validate` tags associated with the struct fields. 15 | func ValidatePayloadFields(profile *ConfigurationProfile) []error { 16 | var errs []error 17 | 18 | // Iterate over struct fields to validate 'required' tags 19 | val := reflect.ValueOf(profile).Elem() 20 | typ := val.Type() 21 | for i := 0; i < val.NumField(); i++ { 22 | field := typ.Field(i) 23 | tag := field.Tag.Get("validate") 24 | if tag != "" { 25 | // Check for required fields 26 | if strings.Contains(tag, "required") { 27 | value := val.Field(i).Interface() 28 | if value == "" { 29 | errs = append(errs, fmt.Errorf("plist key '%s' is required", field.Name)) 30 | } 31 | } 32 | // Additional validation rules can be added here 33 | } 34 | } 35 | 36 | return errs 37 | } 38 | -------------------------------------------------------------------------------- /internal/resources/common/hash.go: -------------------------------------------------------------------------------- 1 | // hash.go 2 | // This package contains shared / common hash functions 3 | package common 4 | 5 | import ( 6 | "crypto/sha256" 7 | "fmt" 8 | "log" 9 | ) 10 | 11 | // HashString calculates the SHA-256 hash of a string and returns it as a hexadecimal string. 12 | func HashString(s string) string { 13 | h := sha256.New() 14 | h.Write([]byte(s)) 15 | hash := fmt.Sprintf("%x", h.Sum(nil)) 16 | log.Printf("Computed hash: %s", hash) 17 | return hash 18 | } 19 | -------------------------------------------------------------------------------- /internal/resources/common/redeployment.go: -------------------------------------------------------------------------------- 1 | // common/state/state.go 2 | // This package contains shared / common resource functions for stating 3 | 4 | package common 5 | 6 | import ( 7 | "strings" 8 | 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | ) 12 | 13 | // HandleResourceNotFoundError is a helper function to handle 404 and 410 errors and remove the resource from Terraform state 14 | func HandleResourceNotFoundError(err error, d *schema.ResourceData, cleanup bool) diag.Diagnostics { 15 | var diags diag.Diagnostics 16 | ErrorTypeIsNotFound := strings.Contains(err.Error(), "404") 17 | 18 | if cleanup && ErrorTypeIsNotFound { 19 | d.SetId("") 20 | diags = append(diags, diag.Diagnostic{ 21 | Severity: diag.Warning, 22 | Summary: "Resource not found and will be redeployed", 23 | }) 24 | 25 | } else { 26 | diags = append(diags, diag.FromErr(err)...) 27 | } 28 | 29 | return diags 30 | 31 | } 32 | -------------------------------------------------------------------------------- /internal/resources/common/sharedschemas/category.go: -------------------------------------------------------------------------------- 1 | package sharedschemas 2 | 3 | import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 4 | 5 | func GetSharedSchemaCategory() *schema.Schema { 6 | out := &schema.Schema{ 7 | Type: schema.TypeInt, 8 | Optional: true, 9 | Default: -1, 10 | Description: "Jamf Pro category-related settings of the policy.", 11 | } 12 | 13 | return out 14 | 15 | } 16 | -------------------------------------------------------------------------------- /internal/resources/common/sharedschemas/constructors.go: -------------------------------------------------------------------------------- 1 | // common/constructobject.go 2 | package sharedschemas 3 | 4 | import ( 5 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 6 | ) 7 | 8 | const ( 9 | // Values required to unset, not just empty values. 10 | EmptySiteName = "" 11 | EmptySiteId = -1 12 | EmptyCategoryName = "" 13 | EmptyCategoryId = 0 14 | ) 15 | 16 | // ConstructSharedResourceSite constructs a SharedResourceSite object from the provided schema data, 17 | func ConstructSharedResourceSite(siteId int) *jamfpro.SharedResourceSite { 18 | if siteId == 0 || siteId == -1 { 19 | return &jamfpro.SharedResourceSite{ 20 | ID: EmptySiteId, 21 | Name: EmptySiteName, 22 | } 23 | } 24 | 25 | return &jamfpro.SharedResourceSite{ID: siteId} 26 | } 27 | 28 | // ConstructSharedResourceCategory constructs a SharedResourceCategory object from the provided schema data, 29 | func ConstructSharedResourceCategory(categoryId int) *jamfpro.SharedResourceCategory { 30 | if categoryId == 0 || categoryId == -1 { 31 | return &jamfpro.SharedResourceCategory{ 32 | ID: EmptySiteId, 33 | Name: EmptySiteName, 34 | } 35 | } 36 | 37 | return &jamfpro.SharedResourceCategory{ID: categoryId} 38 | } 39 | -------------------------------------------------------------------------------- /internal/resources/common/sharedschemas/site.go: -------------------------------------------------------------------------------- 1 | package sharedschemas 2 | 3 | import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 4 | 5 | func GetSharedSchemaSite() *schema.Schema { 6 | out := &schema.Schema{ 7 | Type: schema.TypeInt, 8 | Optional: true, 9 | Default: -1, 10 | Description: "Jamf Pro Site-related settings of the policy.", 11 | } 12 | 13 | return out 14 | } 15 | -------------------------------------------------------------------------------- /internal/resources/computer_extension_attribute/diff_suppress.go: -------------------------------------------------------------------------------- 1 | package computer_extension_attribute 2 | 3 | import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 4 | 5 | // diffSuppressPopupMenuChoices is a custom diff suppression function for the popup_menu_choices attribute. 6 | // This attribute looks for matched values and ignores the order returned by the server. 7 | func diffSuppressPopupMenuChoices(k, old, new string, d *schema.ResourceData) bool { 8 | // Get the old and new values as interfaces 9 | oldRaw, newRaw := d.GetChange("popup_menu_choices") 10 | 11 | // Convert interfaces to []string 12 | oldList := make([]string, len(oldRaw.([]interface{}))) 13 | newList := make([]string, len(newRaw.([]interface{}))) 14 | 15 | for i, v := range oldRaw.([]interface{}) { 16 | oldList[i] = v.(string) 17 | } 18 | for i, v := range newRaw.([]interface{}) { 19 | newList[i] = v.(string) 20 | } 21 | 22 | // If lengths don't match, there's definitely a difference 23 | if len(oldList) != len(newList) { 24 | return false 25 | } 26 | 27 | // Create maps to track occurrences of each value 28 | oldMap := make(map[string]int) 29 | newMap := make(map[string]int) 30 | 31 | // Count occurrences in both lists 32 | for _, v := range oldList { 33 | oldMap[v]++ 34 | } 35 | for _, v := range newList { 36 | newMap[v]++ 37 | } 38 | 39 | // Compare maps 40 | if len(oldMap) != len(newMap) { 41 | return false 42 | } 43 | 44 | for k, v := range oldMap { 45 | if newMap[k] != v { 46 | return false 47 | } 48 | } 49 | 50 | return true 51 | } 52 | -------------------------------------------------------------------------------- /internal/resources/computer_extension_attribute/helpers.go: -------------------------------------------------------------------------------- 1 | package computer_extension_attribute 2 | 3 | import "strings" 4 | 5 | // normalizeScript normalizes a script by replacing all CRLF with LF and trimming trailing newlines 6 | func normalizeScript(script string) string { 7 | normalized := strings.Replace(script, "\r\n", "\n", -1) 8 | 9 | return strings.TrimRight(normalized, "\n") 10 | } 11 | -------------------------------------------------------------------------------- /internal/resources/department/constructor.go: -------------------------------------------------------------------------------- 1 | // department_data_object.go 2 | package department 3 | 4 | import ( 5 | "encoding/xml" 6 | "fmt" 7 | "log" 8 | 9 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | ) 12 | 13 | // constructJamfProDepartment constructs a Jamf Pro Department struct from Terraform resource data. 14 | func construct(d *schema.ResourceData) (*jamfpro.ResourceDepartment, error) { 15 | resource := &jamfpro.ResourceDepartment{ 16 | Name: d.Get("name").(string), 17 | } 18 | 19 | resourceXML, err := xml.MarshalIndent(resource, "", " ") 20 | if err != nil { 21 | return nil, fmt.Errorf("failed to marshal Jamf Pro Department '%s' to XML: %v", resource.Name, err) 22 | } 23 | 24 | log.Printf("[DEBUG] Constructed Jamf Pro Department XML:\n%s\n", string(resourceXML)) 25 | 26 | return resource, nil 27 | } 28 | -------------------------------------------------------------------------------- /internal/resources/department/resource.go: -------------------------------------------------------------------------------- 1 | // department_resource.go 2 | package department 3 | 4 | import ( 5 | "time" 6 | 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // resourceJamfProDepartments defines the schema and CRUD operations for managing Jamf Pro Departments in Terraform. 11 | func ResourceJamfProDepartments() *schema.Resource { 12 | return &schema.Resource{ 13 | CreateContext: create, 14 | ReadContext: readWithCleanup, 15 | UpdateContext: update, 16 | DeleteContext: delete, 17 | Timeouts: &schema.ResourceTimeout{ 18 | Create: schema.DefaultTimeout(70 * time.Second), 19 | Read: schema.DefaultTimeout(70 * time.Second), 20 | Update: schema.DefaultTimeout(70 * time.Second), 21 | Delete: schema.DefaultTimeout(70 * time.Second), 22 | }, 23 | Importer: &schema.ResourceImporter{ 24 | StateContext: schema.ImportStatePassthroughContext, 25 | }, 26 | Schema: map[string]*schema.Schema{ 27 | "id": { 28 | Type: schema.TypeString, 29 | Computed: true, 30 | Description: "The unique identifier of the department.", 31 | }, 32 | "name": { 33 | Type: schema.TypeString, 34 | Required: true, 35 | Description: "The unique name of the Jamf Pro department.", 36 | }, 37 | }, 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /internal/resources/department/state.go: -------------------------------------------------------------------------------- 1 | // department_state.go 2 | package department 3 | 4 | import ( 5 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // updateState updates the Terraform state with the latest Department information from the Jamf Pro API. 11 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceDepartment) diag.Diagnostics { 12 | var diags diag.Diagnostics 13 | 14 | if err := d.Set("id", resp.ID); err != nil { 15 | diags = append(diags, diag.FromErr(err)...) 16 | } 17 | 18 | if err := d.Set("name", resp.Name); err != nil { 19 | diags = append(diags, diag.FromErr(err)...) 20 | } 21 | 22 | return diags 23 | } 24 | -------------------------------------------------------------------------------- /internal/resources/device_communication_settings/state.go: -------------------------------------------------------------------------------- 1 | // State file (device_communication_settings_state.go) 2 | package device_communication_settings 3 | 4 | import ( 5 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceDeviceCommunicationSettings) diag.Diagnostics { 11 | var diags diag.Diagnostics 12 | 13 | settings := map[string]interface{}{ 14 | "auto_renew_mobile_device_mdm_profile_when_ca_renewed": resp.AutoRenewMobileDeviceMdmProfileWhenCaRenewed, 15 | "auto_renew_mobile_device_mdm_profile_when_device_identity_cert_expiring": resp.AutoRenewMobileDeviceMdmProfileWhenDeviceIdentityCertExpiring, 16 | "auto_renew_computer_mdm_profile_when_ca_renewed": resp.AutoRenewComputerMdmProfileWhenCaRenewed, 17 | "auto_renew_computer_mdm_profile_when_device_identity_cert_expiring": resp.AutoRenewComputerMdmProfileWhenDeviceIdentityCertExpiring, 18 | "mdm_profile_mobile_device_expiration_limit_in_days": resp.MdmProfileMobileDeviceExpirationLimitInDays, 19 | "mdm_profile_computer_expiration_limit_in_days": resp.MdmProfileComputerExpirationLimitInDays, 20 | } 21 | 22 | for key, val := range settings { 23 | if err := d.Set(key, val); err != nil { 24 | diags = append(diags, diag.FromErr(err)...) 25 | } 26 | } 27 | 28 | return diags 29 | } 30 | -------------------------------------------------------------------------------- /internal/resources/device_enrollments/constructor.go: -------------------------------------------------------------------------------- 1 | // deviceenrollments_object.go 2 | package device_enrollments 3 | 4 | import ( 5 | "encoding/json" 6 | "fmt" 7 | "log" 8 | 9 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | ) 12 | 13 | // construct constructs a ResourceDeviceEnrollment object from the provided schema data. 14 | func construct(d *schema.ResourceData) (*jamfpro.ResourceDeviceEnrollmentUpdate, error) { 15 | resource := &jamfpro.ResourceDeviceEnrollmentUpdate{ 16 | Name: d.Get("name").(string), 17 | SupervisionIdentityId: d.Get("supervision_identity_id").(string), 18 | SiteId: d.Get("site_id").(string), 19 | } 20 | 21 | resourceJSON, err := json.MarshalIndent(resource, "", " ") 22 | if err != nil { 23 | return nil, fmt.Errorf("failed to marshal Jamf Pro Device Enrollment '%s' to JSON: %v", resource.Name, err) 24 | } 25 | 26 | log.Printf("[DEBUG] Constructed Jamf Pro Device Enrollment JSON:\n%s\n", string(resourceJSON)) 27 | 28 | return resource, nil 29 | } 30 | -------------------------------------------------------------------------------- /internal/resources/device_enrollments/state.go: -------------------------------------------------------------------------------- 1 | // deviceenrollments_state.go 2 | package device_enrollments 3 | 4 | import ( 5 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // updateState updates the Terraform state with the latest Device Enrollment information from the Jamf Pro API. 11 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceDeviceEnrollment) diag.Diagnostics { 12 | var diags diag.Diagnostics 13 | 14 | resourceData := map[string]interface{}{ 15 | "id": resp.ID, 16 | "name": resp.Name, 17 | "supervision_identity_id": resp.SupervisionIdentityId, 18 | "site_id": resp.SiteId, 19 | "server_name": resp.ServerName, 20 | "server_uuid": resp.ServerUuid, 21 | "admin_id": resp.AdminId, 22 | "org_name": resp.OrgName, 23 | "org_email": resp.OrgEmail, 24 | "org_phone": resp.OrgPhone, 25 | "org_address": resp.OrgAddress, 26 | "token_expiration_date": resp.TokenExpirationDate, 27 | } 28 | 29 | for key, val := range resourceData { 30 | if err := d.Set(key, val); err != nil { 31 | return diag.FromErr(err) 32 | } 33 | } 34 | 35 | return diags 36 | } 37 | -------------------------------------------------------------------------------- /internal/resources/deviceenrollmentspublickey/data_source.go: -------------------------------------------------------------------------------- 1 | // deviceenrollments_public_key_data_source.go 2 | package deviceenrollmentspublickey 3 | 4 | import ( 5 | "context" 6 | "fmt" 7 | 8 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | ) 12 | 13 | // DataSourceJamfProDeviceEnrollmentsPublicKey provides the public key for device enrollments in Jamf Pro. 14 | func DataSourceJamfProDeviceEnrollmentsPublicKey() *schema.Resource { 15 | return &schema.Resource{ 16 | ReadContext: dataSourceRead, 17 | Schema: map[string]*schema.Schema{ 18 | "public_key": { 19 | Type: schema.TypeString, 20 | Computed: true, 21 | Description: "The public key used for device enrollments.", 22 | }, 23 | }, 24 | } 25 | } 26 | 27 | // dataSourcePublicKeyRead fetches the device enrollments public key from Jamf Pro. 28 | func dataSourceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { 29 | client := meta.(*jamfpro.Client) 30 | 31 | publicKey, err := client.GetDeviceEnrollmentsPublicKey() 32 | if err != nil { 33 | return diag.FromErr(fmt.Errorf("failed to fetch device enrollments public key: %v", err)) 34 | } 35 | 36 | d.SetId("jamfpro_device_enrollments_public_key_singleton") 37 | 38 | if err := d.Set("public_key", publicKey); err != nil { 39 | return diag.FromErr(fmt.Errorf("error setting public_key: %v", err)) 40 | } 41 | 42 | return diag.Diagnostics{} 43 | } 44 | -------------------------------------------------------------------------------- /internal/resources/dock_item/constructor.go: -------------------------------------------------------------------------------- 1 | // dockitems_data_object.go 2 | package dock_item 3 | 4 | import ( 5 | "encoding/xml" 6 | "fmt" 7 | "log" 8 | 9 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | ) 12 | 13 | // constructJamfProDockItem constructs a ResourceDockItem object from the provided schema data. 14 | func construct(d *schema.ResourceData) (*jamfpro.ResourceDockItem, error) { 15 | resource := &jamfpro.ResourceDockItem{ 16 | Name: d.Get("name").(string), 17 | Type: d.Get("type").(string), 18 | Path: d.Get("path").(string), 19 | Contents: (d.Get("contents").(string)), 20 | } 21 | 22 | resourceXML, err := xml.MarshalIndent(resource, "", " ") 23 | if err != nil { 24 | return nil, fmt.Errorf("failed to marshal Jamf Pro Dock Item '%s' to XML: %v", resource.Name, err) 25 | } 26 | 27 | log.Printf("[DEBUG] Constructed Jamf Pro Dock Item XML:\n%s\n", string(resourceXML)) 28 | 29 | return resource, nil 30 | } 31 | -------------------------------------------------------------------------------- /internal/resources/dock_item/state.go: -------------------------------------------------------------------------------- 1 | // dockitems_state.go 2 | package dock_item 3 | 4 | import ( 5 | "strconv" 6 | 7 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 10 | ) 11 | 12 | // updateState updates the Terraform state with the latest Dock Item information from the Jamf Pro API. 13 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceDockItem) diag.Diagnostics { 14 | var diags diag.Diagnostics 15 | 16 | resourceData := map[string]interface{}{ 17 | "id": strconv.Itoa(resp.ID), 18 | "name": resp.Name, 19 | "type": resp.Type, 20 | "path": resp.Path, 21 | "contents": resp.Contents, 22 | } 23 | 24 | for key, val := range resourceData { 25 | if err := d.Set(key, val); err != nil { 26 | diags = append(diags, diag.FromErr(err)...) 27 | } 28 | } 29 | 30 | return diags 31 | } 32 | -------------------------------------------------------------------------------- /internal/resources/engage_settings/constructor.go: -------------------------------------------------------------------------------- 1 | package engage_settings 2 | 3 | // engagesettings_resource.go 4 | // Package engagesettings provides the schema and CRUD operations for managing Jamf Pro Engage Settings in Terraform. 5 | // This package includes functions to create, read, update, and delete the Engage Settings configuration. 6 | // It also includes a function to construct the ResourceEngageSettings object from the schema data. 7 | 8 | import ( 9 | "encoding/json" 10 | "fmt" 11 | "log" 12 | 13 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 14 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 15 | ) 16 | 17 | // constructEngageSettings constructs a ResourceEngageSettings object from the provided schema data 18 | func constructEngageSettings(d *schema.ResourceData) (*jamfpro.ResourceEngageSettings, error) { 19 | resource := &jamfpro.ResourceEngageSettings{ 20 | IsEnabled: d.Get("is_enabled").(bool), 21 | } 22 | 23 | resourceJSON, err := json.MarshalIndent(resource, "", " ") 24 | if err != nil { 25 | return nil, fmt.Errorf("failed to marshal Jamf Pro Engage Settings to JSON: %v", err) 26 | } 27 | 28 | log.Printf("[DEBUG] Constructed Jamf Pro Engage Settings JSON:\n%s\n", string(resourceJSON)) 29 | 30 | return resource, nil 31 | } 32 | -------------------------------------------------------------------------------- /internal/resources/engage_settings/resource.go: -------------------------------------------------------------------------------- 1 | package engage_settings 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 7 | ) 8 | 9 | // resourceJamfProEngageSettings defines the schema and CRUD operations for managing Jamf Pro Engage settings configuration in Terraform. 10 | func ResourceEngageSettings() *schema.Resource { 11 | return &schema.Resource{ 12 | CreateContext: create, 13 | ReadContext: read, 14 | UpdateContext: update, 15 | DeleteContext: delete, 16 | Timeouts: &schema.ResourceTimeout{ 17 | Create: schema.DefaultTimeout(70 * time.Second), 18 | Read: schema.DefaultTimeout(70 * time.Second), 19 | Update: schema.DefaultTimeout(70 * time.Second), 20 | Delete: schema.DefaultTimeout(70 * time.Second), 21 | }, 22 | Importer: &schema.ResourceImporter{ 23 | StateContext: schema.ImportStatePassthroughContext, 24 | }, 25 | Schema: map[string]*schema.Schema{ 26 | "is_enabled": { 27 | Type: schema.TypeBool, 28 | Required: true, 29 | Description: "Whether the Engage settings are enabled or not.", 30 | }, 31 | }, 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /internal/resources/engage_settings/state.go: -------------------------------------------------------------------------------- 1 | package engage_settings 2 | 3 | import ( 4 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 5 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 7 | ) 8 | 9 | // updateState updates the Terraform state with the latest Engage settings information from the Jamf Pro API. 10 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceEngageSettings) diag.Diagnostics { 11 | var diags diag.Diagnostics 12 | 13 | engageSettingsConfig := map[string]interface{}{ 14 | "is_enabled": resp.IsEnabled, 15 | } 16 | 17 | for key, val := range engageSettingsConfig { 18 | if err := d.Set(key, val); err != nil { 19 | diags = append(diags, diag.FromErr(err)...) 20 | } 21 | } 22 | 23 | return diags 24 | } 25 | -------------------------------------------------------------------------------- /internal/resources/enrollment_customization/data_validation.go: -------------------------------------------------------------------------------- 1 | package enrollment_customization 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 7 | ) 8 | 9 | // validatePaneCombinations ensures that only valid combinations of pane types are configured 10 | func validatePaneCombinations(d *schema.ResourceData) error { 11 | hasSSO := len(d.Get("sso_pane").([]interface{})) > 0 12 | hasLDAP := len(d.Get("ldap_pane").([]interface{})) > 0 13 | 14 | if hasSSO && hasLDAP { 15 | return fmt.Errorf("invalid combination: SSO and LDAP panes cannot be used together") 16 | } 17 | 18 | return nil 19 | } 20 | 21 | // validateHexColor validates a hex color code without the # prefix 22 | func validateHexColor(val interface{}, key string) (warns []string, errs []error) { 23 | v := val.(string) 24 | 25 | // Check length (6 characters for hex without #) 26 | if len(v) != 6 { 27 | errs = append(errs, fmt.Errorf("%q must be exactly 6 characters (without #), got: %d characters", key, len(v))) 28 | return 29 | } 30 | 31 | // Check if all characters are valid hex 32 | for _, c := range v { 33 | if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { 34 | errs = append(errs, fmt.Errorf("%q contains invalid hex character: %c", key, c)) 35 | return 36 | } 37 | } 38 | 39 | return 40 | } 41 | -------------------------------------------------------------------------------- /internal/resources/icon/constructor.go: -------------------------------------------------------------------------------- 1 | // icons_object.go 2 | package icon 3 | 4 | import ( 5 | "fmt" 6 | 7 | "github.com/deploymenttheory/terraform-provider-jamfpro/internal/resources/common" 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | ) 10 | 11 | // construct constructs a ResourceIcon object from the provided schema data. 12 | func construct(d *schema.ResourceData) (string, error) { 13 | filePath := d.Get("icon_file_path").(string) 14 | webSource := d.Get("icon_file_web_source").(string) 15 | 16 | if filePath != "" && webSource != "" { 17 | return "", fmt.Errorf("cannot specify both icon_file_path and icon_file_web_source, choose one source only") 18 | } 19 | 20 | if filePath != "" { 21 | return filePath, nil 22 | } 23 | 24 | if webSource != "" { 25 | localPath, err := common.DownloadFile(webSource) 26 | if err != nil { 27 | return "", fmt.Errorf("failed to download icon from %s: %v", webSource, err) 28 | } 29 | return localPath, nil 30 | } 31 | return "", fmt.Errorf("either icon_file_path or icon_file_web_source must be specified") 32 | } 33 | -------------------------------------------------------------------------------- /internal/resources/icon/data_validate.go: -------------------------------------------------------------------------------- 1 | package icon 2 | 3 | import ( 4 | "fmt" 5 | "path/filepath" 6 | "regexp" 7 | 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 10 | ) 11 | 12 | // validateIconFilePath ensures the provided file path has a .png extension 13 | func validateIconFilePath() schema.SchemaValidateFunc { 14 | return validation.Any( 15 | validation.StringMatch( 16 | regexp.MustCompile(`^.*\.png$`), 17 | "Expected .png file, got .%s", 18 | ), 19 | func(i interface{}, k string) ([]string, []error) { 20 | v := i.(string) 21 | ext := filepath.Ext(v) 22 | if ext == "" { 23 | return nil, []error{fmt.Errorf("expected .png file, got no extension")} 24 | } 25 | return nil, []error{fmt.Errorf("expected .png file, got %s", ext)} 26 | }, 27 | ) 28 | } 29 | -------------------------------------------------------------------------------- /internal/resources/icon/state.go: -------------------------------------------------------------------------------- 1 | // icons_state.go 2 | package icon 3 | 4 | import ( 5 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // updateState updates the Terraform state with the latest Icon information from the Jamf Pro API. 11 | func updateState(d *schema.ResourceData, resp *jamfpro.ResponseIconUpload) diag.Diagnostics { 12 | var diags diag.Diagnostics 13 | 14 | iconData := map[string]interface{}{ 15 | "name": resp.Name, 16 | "url": resp.URL, 17 | "icon_file_path": d.Get("icon_file_path").(string), 18 | "icon_file_web_source": d.Get("icon_file_web_source").(string), 19 | } 20 | 21 | for key, val := range iconData { 22 | if err := d.Set(key, val); err != nil { 23 | diags = append(diags, diag.FromErr(err)...) 24 | } 25 | } 26 | 27 | return diags 28 | } 29 | -------------------------------------------------------------------------------- /internal/resources/jamf_connect/constructor.go: -------------------------------------------------------------------------------- 1 | package jamf_connect 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "log" 7 | 8 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 10 | ) 11 | 12 | // construct creates a ResourceJamfConnectConfigProfileUpdate from the provided schema data 13 | func construct(d *schema.ResourceData) (*jamfpro.ResourceJamfConnectConfigProfileUpdate, error) { 14 | resource := &jamfpro.ResourceJamfConnectConfigProfileUpdate{ 15 | JamfConnectVersion: d.Get("jamf_connect_version").(string), 16 | AutoDeploymentType: d.Get("auto_deployment_type").(string), 17 | } 18 | 19 | resourceJSON, err := json.MarshalIndent(resource, "", " ") 20 | if err != nil { 21 | return nil, fmt.Errorf("failed to marshal Jamf Connect Config Profile to JSON: %v", err) 22 | } 23 | 24 | log.Printf("[DEBUG] Constructed Jamf Connect Config Profile JSON:\n%s\n", string(resourceJSON)) 25 | 26 | return resource, nil 27 | } 28 | -------------------------------------------------------------------------------- /internal/resources/jamf_connect/state.go: -------------------------------------------------------------------------------- 1 | package jamf_connect 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | ) 10 | 11 | // updateState updates the Terraform state with the latest Computer Check-In information from the Jamf Pro API. 12 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceJamfConnectConfigProfile) diag.Diagnostics { 13 | var diags diag.Diagnostics 14 | 15 | profileData := map[string]interface{}{ 16 | "config_profile_uuid": resp.UUID, 17 | "profile_id": resp.ProfileID, 18 | "profile_name": resp.ProfileName, 19 | "scope_description": resp.ScopeDescription, 20 | "site_id": resp.SiteID, 21 | "jamf_connect_version": resp.Version, 22 | "auto_deployment_type": resp.AutoDeploymentType, 23 | } 24 | 25 | for key, val := range profileData { 26 | if err := d.Set(key, val); err != nil { 27 | diags = append(diags, diag.FromErr(fmt.Errorf("error setting %s: %v", key, err))...) 28 | } 29 | } 30 | 31 | return diags 32 | } 33 | -------------------------------------------------------------------------------- /internal/resources/jamf_protect/state.go: -------------------------------------------------------------------------------- 1 | package jamf_protect 2 | 3 | import ( 4 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 5 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 7 | ) 8 | 9 | // updateState updates the Terraform state with the current settings of the Jamf Protect integration. 10 | func updateState(d *schema.ResourceData, resp *jamfpro.ResponseJamfProtectSettings) diag.Diagnostics { 11 | var diags diag.Diagnostics 12 | 13 | settings := map[string]interface{}{ 14 | "client_id": resp.APIClientID, 15 | "protect_url": resp.ProtectURL, 16 | "auto_install": resp.AutoInstall, 17 | "sync_status": resp.SyncStatus, 18 | "api_client_name": resp.APIClientName, 19 | "last_sync_time": resp.LastSyncTime, 20 | "registration_id": resp.RegistrationID, 21 | } 22 | 23 | if d.HasChange("password") { 24 | settings["password"] = d.Get("password").(string) 25 | } 26 | 27 | for key, val := range settings { 28 | if err := d.Set(key, val); err != nil { 29 | diags = append(diags, diag.FromErr(err)...) 30 | } 31 | } 32 | 33 | return diags 34 | } 35 | -------------------------------------------------------------------------------- /internal/resources/local_admin_password_settings/state.go: -------------------------------------------------------------------------------- 1 | package local_admin_password_settings 2 | 3 | import ( 4 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 5 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 7 | ) 8 | 9 | // updateState updates the Terraform state with the latest local account password settings information from the Jamf Pro API. 10 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceLocalAdminPasswordSettings) diag.Diagnostics { 11 | var diags diag.Diagnostics 12 | 13 | localAdminPasswordSettingsConfig := map[string]interface{}{ 14 | "auto_deploy_enabled": resp.AutoDeployEnabled, 15 | "password_rotation_time_seconds": resp.PasswordRotationTime, 16 | "auto_rotate_enabled": resp.AutoRotateEnabled, 17 | "auto_rotate_expiration_time_seconds": resp.AutoRotateExpirationTime, 18 | } 19 | 20 | for key, val := range localAdminPasswordSettingsConfig { 21 | if err := d.Set(key, val); err != nil { 22 | diags = append(diags, diag.FromErr(err)...) 23 | } 24 | } 25 | 26 | return diags 27 | } 28 | -------------------------------------------------------------------------------- /internal/resources/macos_configuration_profile_plist_generator/diff_suppress.go: -------------------------------------------------------------------------------- 1 | // macosconfigurationprofilesplistgenerator_diff_suppress.go 2 | package macos_configuration_profile_plist_generator 3 | 4 | import ( 5 | "log" 6 | 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // DiffSuppressPayloads is a custom diff suppression function for the payloads attribute. 11 | func DiffSuppressPayloads(k, old, new string, d *schema.ResourceData) bool { 12 | // Suppress diff for specific keys 13 | if shouldSuppressKey(k) { 14 | log.Printf("Suppressing diff for key: %s", k) 15 | return true 16 | } 17 | return false 18 | } 19 | 20 | // shouldSuppressKey checks if a key should be suppressed in the diff. 21 | func shouldSuppressKey(key string) bool { 22 | keysToSuppress := []string{ 23 | "payload_identifier", 24 | "payload_uuid", 25 | "payload_version", 26 | "payload_organization", 27 | //"payload_enabled", 28 | //"payload_scope", 29 | "payload_display_name", 30 | } 31 | 32 | for _, suppressKey := range keysToSuppress { 33 | if keyContainsSuffix(key, suppressKey) { 34 | return true 35 | } 36 | } 37 | return false 38 | } 39 | 40 | // keyContainsSuffix checks if the key contains a specific suffix, accounting for Terraform's nested attribute syntax. 41 | func keyContainsSuffix(key, suffix string) bool { 42 | return len(key) >= len(suffix) && key[len(key)-len(suffix):] == suffix 43 | } 44 | -------------------------------------------------------------------------------- /internal/resources/managed_software_update_feature_toggle/constructor.go: -------------------------------------------------------------------------------- 1 | package managed_software_update_feature_toggle 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "log" 7 | 8 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 10 | ) 11 | 12 | // constructManagedSoftwareUpdateFeatureToggle constructs a Managed Software Update Feature Toggle object from the provided schema data 13 | func constrconstructManagedSoftwareUpdateFeatureToggle(d *schema.ResourceData) (*jamfpro.ResourceManagedSoftwareUpdateFeatureToggle, error) { 14 | resource := &jamfpro.ResourceManagedSoftwareUpdateFeatureToggle{ 15 | Toggle: d.Get("toggle").(bool), 16 | } 17 | 18 | resourceJSON, err := json.MarshalIndent(resource, "", " ") 19 | if err != nil { 20 | return nil, fmt.Errorf("failed to marshal Managed Software Update Feature Toggle to JSON: %v", err) 21 | } 22 | 23 | log.Printf("[DEBUG] Constructed Managed Software Update Feature Toggle JSON:\n%s\n", string(resourceJSON)) 24 | 25 | return resource, nil 26 | } 27 | -------------------------------------------------------------------------------- /internal/resources/managed_software_update_feature_toggle/resource.go: -------------------------------------------------------------------------------- 1 | package managed_software_update_feature_toggle 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 7 | ) 8 | 9 | // ResourceManagedSoftwareUpdateFeatureToggle defines the schema and CRUD operations for managing Jamf Pro Managed Software Update Feature Toggle configuration in Terraform. 10 | func ResourceManagedSoftwareUpdateFeatureToggle() *schema.Resource { 11 | return &schema.Resource{ 12 | CreateContext: create, 13 | ReadContext: readWithCleanup, 14 | UpdateContext: update, 15 | DeleteContext: delete, 16 | Timeouts: &schema.ResourceTimeout{ 17 | Create: schema.DefaultTimeout(1 * time.Minute), 18 | Read: schema.DefaultTimeout(1 * time.Minute), 19 | Update: schema.DefaultTimeout(1 * time.Minute), 20 | Delete: schema.DefaultTimeout(1 * time.Minute), 21 | }, 22 | Importer: &schema.ResourceImporter{ 23 | StateContext: schema.ImportStatePassthroughContext, 24 | }, 25 | Schema: map[string]*schema.Schema{ 26 | "toggle": { 27 | Type: schema.TypeBool, 28 | Required: true, 29 | Description: "Whether the Managed Software Update Feature Toggle is enabled or not.", 30 | }, 31 | }, 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /internal/resources/managed_software_update_feature_toggle/state.go: -------------------------------------------------------------------------------- 1 | package managed_software_update_feature_toggle 2 | 3 | import ( 4 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 5 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 7 | ) 8 | 9 | // updateState updates the Terraform state with the latest Managed Software Update Feature Toggle information from the Jamf Pro API. 10 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceManagedSoftwareUpdateFeatureToggle) diag.Diagnostics { 11 | var diags diag.Diagnostics 12 | 13 | if err := d.Set("toggle", resp.Toggle); err != nil { 14 | diags = append(diags, diag.FromErr(err)...) 15 | } 16 | 17 | return diags 18 | } 19 | -------------------------------------------------------------------------------- /internal/resources/mobile_device_extension_attribute/data_validator.go: -------------------------------------------------------------------------------- 1 | package mobile_device_extension_attribute 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 7 | ) 8 | 9 | // ValidateInputType ensures that the appropriate fields are set based on the input type 10 | func ValidateInputType(resource *jamfpro.ResourceMobileExtensionAttribute) error { 11 | // Check if InputType is empty 12 | if resource.InputType.Type == "" { 13 | return fmt.Errorf("input_type.type must be set") 14 | } 15 | 16 | switch resource.InputType.Type { 17 | case "Text Field": 18 | if len(resource.InputType.PopupChoices.Choice) > 0 { 19 | return fmt.Errorf("popup_choices should not be set when input_type is 'Text Field'") 20 | } 21 | case "Pop-up Menu": 22 | if len(resource.InputType.PopupChoices.Choice) == 0 { 23 | return fmt.Errorf("popup_choices must be set when input_type is 'Pop-up Menu'") 24 | } 25 | default: 26 | return fmt.Errorf("invalid input_type: %s", resource.InputType.Type) 27 | } 28 | 29 | return nil 30 | } 31 | -------------------------------------------------------------------------------- /internal/resources/mobile_device_extension_attribute/diff_suppress.go: -------------------------------------------------------------------------------- 1 | package mobile_device_extension_attribute 2 | 3 | import ( 4 | "reflect" 5 | "sort" 6 | 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // suppressPopupChoicesDiff is a diff suppression function that ignores the order of popup choices 11 | func suppressPopupChoicesDiff(k, old, new string, d *schema.ResourceData) bool { 12 | o, n := d.GetChange("input_type.0.popup_choices") 13 | if o == nil || n == nil { 14 | return false 15 | } 16 | oldChoices := o.([]interface{}) 17 | newChoices := n.([]interface{}) 18 | 19 | if len(oldChoices) != len(newChoices) { 20 | return false 21 | } 22 | 23 | oldStrings := make([]string, len(oldChoices)) 24 | newStrings := make([]string, len(newChoices)) 25 | 26 | for i, v := range oldChoices { 27 | oldStrings[i] = v.(string) 28 | } 29 | for i, v := range newChoices { 30 | newStrings[i] = v.(string) 31 | } 32 | 33 | sort.Strings(oldStrings) 34 | sort.Strings(newStrings) 35 | 36 | return reflect.DeepEqual(oldStrings, newStrings) 37 | } 38 | -------------------------------------------------------------------------------- /internal/resources/mobile_device_extension_attribute/state.go: -------------------------------------------------------------------------------- 1 | package mobile_device_extension_attribute 2 | 3 | import ( 4 | "strconv" 5 | 6 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | ) 10 | 11 | // updateState updates the Terraform state with the latest Mobile Device Extension Attribute information from the Jamf Pro API. 12 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceMobileExtensionAttribute) diag.Diagnostics { 13 | var diags diag.Diagnostics 14 | 15 | if err := d.Set("id", strconv.Itoa(resp.ID)); err != nil { 16 | return diag.FromErr(err) 17 | } 18 | if err := d.Set("name", resp.Name); err != nil { 19 | return diag.FromErr(err) 20 | } 21 | if err := d.Set("description", resp.Description); err != nil { 22 | return diag.FromErr(err) 23 | } 24 | if err := d.Set("data_type", resp.DataType); err != nil { 25 | return diag.FromErr(err) 26 | } 27 | if err := d.Set("inventory_display", resp.InventoryDisplay); err != nil { 28 | return diag.FromErr(err) 29 | } 30 | 31 | // Handle the nested input_type structure 32 | inputType := []map[string]interface{}{ 33 | { 34 | "type": resp.InputType.Type, 35 | "popup_choices": resp.InputType.PopupChoices.Choice, 36 | }, 37 | } 38 | if err := d.Set("input_type", inputType); err != nil { 39 | return diag.FromErr(err) 40 | } 41 | 42 | return diags 43 | } 44 | -------------------------------------------------------------------------------- /internal/resources/network_segment/state.go: -------------------------------------------------------------------------------- 1 | // networksegments_state.go 2 | package network_segment 3 | 4 | import ( 5 | "strconv" 6 | 7 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 10 | ) 11 | 12 | // updateState updates the Terraform state with the latest Network Segment information from the Jamf Pro API. 13 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceNetworkSegment) diag.Diagnostics { 14 | var diags diag.Diagnostics 15 | 16 | resourceData := map[string]interface{}{ 17 | "id": strconv.Itoa(resp.ID), 18 | "name": resp.Name, 19 | "starting_address": resp.StartingAddress, 20 | "ending_address": resp.EndingAddress, 21 | "distribution_server": resp.DistributionServer, 22 | "distribution_point": resp.DistributionPoint, 23 | "url": resp.URL, 24 | "swu_server": resp.SWUServer, 25 | "building": resp.Building, 26 | "department": resp.Department, 27 | "override_buildings": resp.OverrideBuildings, 28 | "override_departments": resp.OverrideDepartments, 29 | } 30 | 31 | for key, val := range resourceData { 32 | if err := d.Set(key, val); err != nil { 33 | return diag.FromErr(err) 34 | } 35 | } 36 | 37 | return diags 38 | } 39 | -------------------------------------------------------------------------------- /internal/resources/package/data_validator.go: -------------------------------------------------------------------------------- 1 | // packages_data_handling.go 2 | package packages 3 | 4 | import ( 5 | "context" 6 | "fmt" 7 | "strings" 8 | 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 10 | ) 11 | 12 | // customValidateFilePath is a custom validation function for the package_file_source field. 13 | // It ensures that the package_file_source field ends with .dmg if fill_user_template or fill_existing_users are set to true. 14 | func customValidateFilePath(ctx context.Context, d *schema.ResourceDiff, meta interface{}) error { 15 | filePath, ok := d.Get("package_file_source").(string) 16 | if !ok { 17 | return fmt.Errorf("invalid type for package_file_sourceh") 18 | } 19 | 20 | if strings.HasSuffix(filePath, ".dmg") { 21 | return nil 22 | } 23 | 24 | // If file path does not end with .dmg, ensure fill_user_template and fill_existing_users are not set to true 25 | fillUserTemplate, fillUserTemplateOk := d.GetOk("fill_user_template") 26 | fillExistingUsers, fillExistingUsersOk := d.GetOk("fill_existing_users") 27 | 28 | if fillUserTemplateOk && fillUserTemplate.(bool) { 29 | return fmt.Errorf("fill_user_template can only be set to true if the package defined in package_file_source ends with .dmg") 30 | } 31 | 32 | if fillExistingUsersOk && fillExistingUsers.(bool) { 33 | return fmt.Errorf("fill_existing_users can only be set to true if the package defined in package_file_source ends with .dmg") 34 | } 35 | 36 | return nil 37 | } 38 | -------------------------------------------------------------------------------- /internal/resources/policy/schema_dockitems.go: -------------------------------------------------------------------------------- 1 | package policy 2 | 3 | import ( 4 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 5 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 6 | ) 7 | 8 | func getPolicySchemaDockItems() *schema.Resource { 9 | out := &schema.Resource{ 10 | Schema: map[string]*schema.Schema{ 11 | "id": { 12 | Type: schema.TypeInt, 13 | Required: true, 14 | Description: "Unique identifier of the dock item.", 15 | }, 16 | "name": { // Name + ID required to successfully request. do not remove. 17 | Type: schema.TypeString, 18 | Description: "Name of the dock item.", 19 | Required: true, 20 | }, 21 | "action": { 22 | Type: schema.TypeString, 23 | Required: true, 24 | Description: "Action to be performed for the dock item (e.g., Add To Beginning, Add To End, Remove).", 25 | ValidateFunc: validation.StringInSlice([]string{"Add To Beginning", "Add To End", "Remove"}, false), 26 | }, 27 | }, 28 | } 29 | 30 | return out 31 | } 32 | -------------------------------------------------------------------------------- /internal/resources/policy/schema_network_limitations.go: -------------------------------------------------------------------------------- 1 | package policy 2 | 3 | import ( 4 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 5 | ) 6 | 7 | func getPolicySchemaNetworkLimitations() *schema.Resource { 8 | out := &schema.Resource{ 9 | Schema: map[string]*schema.Schema{ 10 | "minimum_network_connection": { 11 | Type: schema.TypeString, 12 | Optional: true, 13 | Description: "Minimum network connection required for the policy.", 14 | Default: "No Minimum", 15 | // ValidateFunc: validation.StringInSlice([]string{"No Minimum", "Ethernet"}, false), 16 | }, 17 | "any_ip_address": { // NOT IN THE UI 18 | Type: schema.TypeBool, 19 | Optional: true, 20 | Description: "Whether the policy applies to any IP address.", 21 | Default: true, 22 | }, 23 | // "network_segments": { // surely this has been moved to scope now? 24 | // Type: schema.TypeString, 25 | // Description: "Network segment limitations for the policy.", 26 | // Optional: true, 27 | // Default: "", 28 | // }, 29 | }, 30 | } 31 | 32 | return out 33 | } 34 | -------------------------------------------------------------------------------- /internal/resources/policy/schema_printer.go: -------------------------------------------------------------------------------- 1 | package policy 2 | 3 | import ( 4 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 5 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 6 | ) 7 | 8 | func getPolicySchemaPrinter() *schema.Resource { 9 | out := &schema.Resource{ 10 | Schema: map[string]*schema.Schema{ 11 | "id": { 12 | Type: schema.TypeInt, 13 | Required: true, 14 | Description: "Unique identifier of the printer.", 15 | }, 16 | "name": { // Name + ID required to successfully request. do not remove. 17 | Type: schema.TypeString, 18 | Required: true, 19 | Description: "Name of the printer.", 20 | }, 21 | "action": { 22 | Type: schema.TypeString, 23 | Required: true, 24 | Description: "Action to be performed for the printer (e.g., install, uninstall).", 25 | ValidateFunc: validation.StringInSlice([]string{"install", "uninstall"}, false), 26 | }, 27 | "make_default": { 28 | Type: schema.TypeBool, 29 | Optional: true, 30 | Default: false, 31 | Description: "Whether to set the printer as the default.", 32 | }, 33 | }, 34 | } 35 | 36 | return out 37 | } 38 | -------------------------------------------------------------------------------- /internal/resources/policy/state.go: -------------------------------------------------------------------------------- 1 | package policy 2 | 3 | import ( 4 | "strconv" 5 | 6 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | ) 10 | 11 | // Parent func for invdividual stating functions 12 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourcePolicy) diag.Diagnostics { 13 | var diags diag.Diagnostics 14 | 15 | if err := d.Set("id", strconv.Itoa(resp.General.ID)); err != nil { 16 | diags = append(diags, diag.FromErr(err)...) 17 | } 18 | 19 | // General/Root level 20 | stateGeneral(d, resp, &diags) 21 | 22 | // Scope 23 | stateScope(d, resp, &diags) 24 | 25 | // Self Service 26 | stateSelfService(d, resp, &diags) 27 | 28 | // Payloads 29 | statePayloads(d, resp, &diags) 30 | 31 | return diags 32 | } 33 | -------------------------------------------------------------------------------- /internal/resources/printer/constructor.go: -------------------------------------------------------------------------------- 1 | // printers_data_object.go 2 | package printer 3 | 4 | import ( 5 | "encoding/xml" 6 | "fmt" 7 | "log" 8 | 9 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | ) 12 | 13 | // constructJamfProPrinter constructs a ResourcePrinter object from the provided schema data. 14 | func construct(d *schema.ResourceData) (*jamfpro.ResourcePrinter, error) { 15 | resource := &jamfpro.ResourcePrinter{ 16 | Name: d.Get("name").(string), 17 | Category: d.Get("category_name").(string), 18 | URI: d.Get("uri").(string), 19 | CUPSName: d.Get("cups_name").(string), 20 | Location: d.Get("location").(string), 21 | Model: d.Get("model").(string), 22 | Info: d.Get("info").(string), 23 | Notes: d.Get("notes").(string), 24 | MakeDefault: d.Get("make_default").(bool), 25 | UseGeneric: d.Get("use_generic").(bool), 26 | PPD: d.Get("ppd").(string), 27 | PPDPath: d.Get("ppd_path").(string), 28 | PPDContents: d.Get("ppd_contents").(string), 29 | } 30 | 31 | resourceXML, err := xml.MarshalIndent(resource, "", " ") 32 | if err != nil { 33 | return nil, fmt.Errorf("failed to marshal Jamf Pro Printer '%s' to XML: %v", resource.Name, err) 34 | } 35 | 36 | log.Printf("[DEBUG] Constructed Jamf Pro Printer XML:\n%s\n", string(resourceXML)) 37 | 38 | return resource, nil 39 | } 40 | -------------------------------------------------------------------------------- /internal/resources/printer/state.go: -------------------------------------------------------------------------------- 1 | // printers_state.go 2 | package printer 3 | 4 | import ( 5 | "strconv" 6 | 7 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 10 | ) 11 | 12 | // updateState updates the Terraform state with the latest Printer information from the Jamf Pro API. 13 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourcePrinter) diag.Diagnostics { 14 | var diags diag.Diagnostics 15 | 16 | resourceData := map[string]interface{}{ 17 | "id": strconv.Itoa(resp.ID), 18 | "name": resp.Name, 19 | "category_name": resp.Category, 20 | "uri": resp.URI, 21 | "cups_name": resp.CUPSName, 22 | "location": resp.Location, 23 | "model": resp.Model, 24 | "info": resp.Info, 25 | "notes": resp.Notes, 26 | "make_default": resp.MakeDefault, 27 | "use_generic": resp.UseGeneric, 28 | "ppd": resp.PPD, 29 | "ppd_path": resp.PPDPath, 30 | "ppd_contents": resp.PPDContents, 31 | } 32 | 33 | for key, val := range resourceData { 34 | if err := d.Set(key, val); err != nil { 35 | return diag.FromErr(err) 36 | } 37 | } 38 | 39 | return diags 40 | } 41 | -------------------------------------------------------------------------------- /internal/resources/script/state.go: -------------------------------------------------------------------------------- 1 | // scripts_state.go 2 | package script 3 | 4 | import ( 5 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // updateState updates the Terraform state with the latest Script information from the Jamf Pro API. 11 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceScript) diag.Diagnostics { 12 | var diags diag.Diagnostics 13 | 14 | resourceData := map[string]interface{}{ 15 | "id": resp.ID, 16 | "name": resp.Name, 17 | "info": resp.Info, 18 | "notes": resp.Notes, 19 | "os_requirements": resp.OSRequirements, 20 | "category_id": resp.CategoryId, 21 | "priority": resp.Priority, 22 | "script_contents": resp.ScriptContents, 23 | "parameter4": resp.Parameter4, 24 | "parameter5": resp.Parameter5, 25 | "parameter6": resp.Parameter6, 26 | "parameter7": resp.Parameter7, 27 | "parameter8": resp.Parameter8, 28 | "parameter9": resp.Parameter9, 29 | "parameter10": resp.Parameter10, 30 | "parameter11": resp.Parameter11, 31 | } 32 | 33 | for key, val := range resourceData { 34 | if err := d.Set(key, val); err != nil { 35 | return diag.FromErr(err) 36 | } 37 | } 38 | 39 | return diags 40 | 41 | } 42 | -------------------------------------------------------------------------------- /internal/resources/self_service_settings/state.go: -------------------------------------------------------------------------------- 1 | package self_service_settings 2 | 3 | import ( 4 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 5 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 7 | ) 8 | 9 | // updateState updates the Terraform state with the latest Self Service settings information from the Jamf Pro API. 10 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceSelfServiceSettings) diag.Diagnostics { 11 | var diags diag.Diagnostics 12 | 13 | settings := map[string]interface{}{ 14 | "install_automatically": resp.InstallSettings.InstallAutomatically, 15 | "install_location": resp.InstallSettings.InstallLocation, 16 | "user_login_level": resp.LoginSettings.UserLoginLevel, 17 | "allow_remember_me": resp.LoginSettings.AllowRememberMe, 18 | "use_fido2": resp.LoginSettings.UseFido2, 19 | "auth_type": resp.LoginSettings.AuthType, 20 | "notifications_enabled": resp.ConfigurationSettings.NotificationsEnabled, 21 | "alert_user_approved_mdm": resp.ConfigurationSettings.AlertUserApprovedMdm, 22 | "default_landing_page": resp.ConfigurationSettings.DefaultLandingPage, 23 | "default_home_category_id": resp.ConfigurationSettings.DefaultHomeCategoryId, 24 | "bookmarks_name": resp.ConfigurationSettings.BookmarksName, 25 | } 26 | 27 | for key, val := range settings { 28 | if err := d.Set(key, val); err != nil { 29 | diags = append(diags, diag.FromErr(err)...) 30 | } 31 | } 32 | 33 | return diags 34 | } 35 | -------------------------------------------------------------------------------- /internal/resources/site/constructor.go: -------------------------------------------------------------------------------- 1 | // sites_data_object.go 2 | package site 3 | 4 | import ( 5 | "encoding/xml" 6 | "fmt" 7 | "log" 8 | 9 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | ) 12 | 13 | // constructJamfProSite constructs a SharedResourceSite object from the provided schema data. 14 | func construct(d *schema.ResourceData) (*jamfpro.SharedResourceSite, error) { 15 | resource := &jamfpro.SharedResourceSite{ 16 | Name: d.Get("name").(string), 17 | } 18 | 19 | // Serialize and pretty-print the Site object as XML for logging 20 | resourceXML, err := xml.MarshalIndent(resource, "", " ") 21 | if err != nil { 22 | return nil, fmt.Errorf("failed to marshal Jamf Pro Site '%s' to XML: %v", resource.Name, err) 23 | } 24 | 25 | log.Printf("[DEBUG] Constructed Jamf Pro Site XML:\n%s\n", string(resourceXML)) 26 | 27 | return resource, nil 28 | } 29 | -------------------------------------------------------------------------------- /internal/resources/site/resource.go: -------------------------------------------------------------------------------- 1 | // sites_resource.go 2 | package site 3 | 4 | import ( 5 | "time" 6 | 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // resourceJamfProSite defines the schema and CRUD operations for managing Jamf Pro Sites in Terraform. 11 | func ResourceJamfProSites() *schema.Resource { 12 | return &schema.Resource{ 13 | CreateContext: create, 14 | ReadContext: readWithCleanup, 15 | UpdateContext: update, 16 | DeleteContext: delete, 17 | Timeouts: &schema.ResourceTimeout{ 18 | Create: schema.DefaultTimeout(70 * time.Second), 19 | Read: schema.DefaultTimeout(70 * time.Second), 20 | Update: schema.DefaultTimeout(70 * time.Second), 21 | Delete: schema.DefaultTimeout(70 * time.Second), 22 | }, 23 | Importer: &schema.ResourceImporter{ 24 | StateContext: schema.ImportStatePassthroughContext, 25 | }, 26 | Schema: map[string]*schema.Schema{ 27 | "id": { 28 | Type: schema.TypeString, 29 | Computed: true, 30 | Description: "The unique identifier of the site.", 31 | }, 32 | "name": { 33 | Type: schema.TypeString, 34 | Required: true, 35 | Description: "The unique name of the Jamf Pro site.", 36 | }, 37 | }, 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /internal/resources/site/state.go: -------------------------------------------------------------------------------- 1 | // sites_state.go 2 | package site 3 | 4 | import ( 5 | "strconv" 6 | 7 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 10 | ) 11 | 12 | // updateState updates the Terraform state with the latest Site information from the Jamf Pro API. 13 | func updateState(d *schema.ResourceData, resp *jamfpro.SharedResourceSite) diag.Diagnostics { 14 | var diags diag.Diagnostics 15 | 16 | if err := d.Set("id", strconv.Itoa(resp.ID)); err != nil { 17 | diags = append(diags, diag.FromErr(err)...) 18 | } 19 | if err := d.Set("name", resp.Name); err != nil { 20 | diags = append(diags, diag.FromErr(err)...) 21 | } 22 | 23 | return diags 24 | 25 | } 26 | -------------------------------------------------------------------------------- /internal/resources/sso_failover/resource.go: -------------------------------------------------------------------------------- 1 | package sso_failover 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 7 | ) 8 | 9 | // ResourceJamfProSSOFailover defines the schema and CRUD operations for managing Jamf Pro SSO Failover configuration in Terraform. 10 | func ResourceJamfProSSOFailover() *schema.Resource { 11 | return &schema.Resource{ 12 | CreateContext: create, 13 | ReadContext: readWithCleanup, 14 | DeleteContext: delete, 15 | Timeouts: &schema.ResourceTimeout{ 16 | Create: schema.DefaultTimeout(1 * time.Minute), 17 | Read: schema.DefaultTimeout(1 * time.Minute), 18 | Delete: schema.DefaultTimeout(1 * time.Minute), 19 | }, 20 | Importer: &schema.ResourceImporter{ 21 | StateContext: schema.ImportStatePassthroughContext, 22 | }, 23 | Schema: map[string]*schema.Schema{ 24 | "failover_url": { 25 | Type: schema.TypeString, 26 | Computed: true, 27 | Sensitive: true, 28 | Description: "The SSO failover URL for Jamf Pro", 29 | }, 30 | "generation_time": { 31 | Type: schema.TypeInt, 32 | Computed: true, 33 | Description: "The timestamp when the failover URL was generated", 34 | }, 35 | }, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /internal/resources/sso_failover/state.go: -------------------------------------------------------------------------------- 1 | package sso_failover 2 | 3 | import ( 4 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 5 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 7 | ) 8 | 9 | // updateState updates the Terraform state with the values from the Jamf Pro SSO Failover response. 10 | func updateState(d *schema.ResourceData, resp *jamfpro.ResponseSSOFailover) diag.Diagnostics { 11 | var diags diag.Diagnostics 12 | 13 | oldURL, hasOldURL := d.GetOk("failover_url") 14 | oldTime, hasOldTime := d.GetOk("generation_time") 15 | 16 | if err := d.Set("failover_url", resp.FailoverURL); err != nil { 17 | return append(diags, diag.FromErr(err)...) 18 | } 19 | if err := d.Set("generation_time", resp.GenerationTime); err != nil { 20 | return append(diags, diag.FromErr(err)...) 21 | } 22 | 23 | if hasOldURL && hasOldTime && d.Id() != "" { 24 | if oldURL.(string) != resp.FailoverURL && 25 | oldTime.(int) != int(resp.GenerationTime) { 26 | d.SetId("") 27 | return diags 28 | } 29 | } 30 | 31 | d.SetId("jamfpro_sso_failover_singleton") 32 | return diags 33 | } 34 | -------------------------------------------------------------------------------- /internal/resources/static_computer_group/constructor.go: -------------------------------------------------------------------------------- 1 | // staticcomputergroup_object.go 2 | package static_computer_group 3 | 4 | import ( 5 | "encoding/xml" 6 | "fmt" 7 | "log" 8 | 9 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 10 | "github.com/deploymenttheory/terraform-provider-jamfpro/internal/resources/common/sharedschemas" 11 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 12 | ) 13 | 14 | // constructJamfProStaticComputerGroup constructs a ResourceComputerGroup object from the provided schema data. 15 | func construct(d *schema.ResourceData) (*jamfpro.ResourceComputerGroup, error) { 16 | resource := &jamfpro.ResourceComputerGroup{ 17 | Name: d.Get("name").(string), 18 | IsSmart: false, 19 | } 20 | 21 | resource.Site = sharedschemas.ConstructSharedResourceSite(d.Get("site_id").(int)) 22 | 23 | assignedComputers := d.Get("assigned_computer_ids").([]interface{}) 24 | if len(assignedComputers) > 0 { 25 | computers := []jamfpro.ComputerGroupSubsetComputer{} 26 | for _, v := range assignedComputers { 27 | computers = append(computers, jamfpro.ComputerGroupSubsetComputer{ 28 | ID: v.(int), 29 | }) 30 | } 31 | resource.Computers = &computers 32 | } 33 | 34 | resourceXML, err := xml.MarshalIndent(resource, "", " ") 35 | if err != nil { 36 | return nil, fmt.Errorf("failed to marshal Jamf Pro Computer Group '%s' to XML: %v", resource.Name, err) 37 | } 38 | 39 | log.Printf("[DEBUG] Constructed Jamf Pro Computer Group XML:\n%s\n", string(resourceXML)) 40 | 41 | return resource, nil 42 | } 43 | 44 | // Helper functions for nested structures 45 | -------------------------------------------------------------------------------- /internal/resources/static_computer_group/data_validator.go: -------------------------------------------------------------------------------- 1 | // staticcomputergroup_data_validator.go 2 | package static_computer_group 3 | -------------------------------------------------------------------------------- /internal/resources/static_computer_group/state.go: -------------------------------------------------------------------------------- 1 | // computergroup_state.go 2 | package static_computer_group 3 | 4 | import ( 5 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // updateState updates the Terraform state with the latest Computer Group information from the Jamf Pro API. 11 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceComputerGroup) diag.Diagnostics { 12 | var diags diag.Diagnostics 13 | 14 | if err := d.Set("name", resp.Name); err != nil { 15 | diags = append(diags, diag.FromErr(err)...) 16 | } 17 | if err := d.Set("is_smart", resp.IsSmart); err != nil { 18 | diags = append(diags, diag.FromErr(err)...) 19 | } 20 | 21 | d.Set("site_id", resp.Site.ID) 22 | 23 | var assignments []interface{} 24 | if resp.Computers != nil { 25 | for _, comp := range *resp.Computers { 26 | assignments = append(assignments, comp.ID) 27 | } 28 | 29 | if err := d.Set("assigned_computer_ids", assignments); err != nil { 30 | diags = append(diags, diag.FromErr(err)...) 31 | } 32 | } 33 | 34 | return diags 35 | } 36 | -------------------------------------------------------------------------------- /internal/resources/static_mobile_device_group/data_validator.go: -------------------------------------------------------------------------------- 1 | // staticmobiledevicegroup_data_validator.go 2 | package static_mobile_device_group 3 | -------------------------------------------------------------------------------- /internal/resources/static_mobile_device_group/state.go: -------------------------------------------------------------------------------- 1 | // mobiledevicegroup_state.go 2 | package static_mobile_device_group 3 | 4 | import ( 5 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 8 | ) 9 | 10 | // updateState updates the Terraform state with the latest Mobile Device Group information from the Jamf Pro API. 11 | func updateState(d *schema.ResourceData, resp *jamfpro.ResourceMobileDeviceGroup) diag.Diagnostics { 12 | var diags diag.Diagnostics 13 | 14 | if err := d.Set("name", resp.Name); err != nil { 15 | diags = append(diags, diag.FromErr(err)...) 16 | } 17 | if err := d.Set("is_smart", resp.IsSmart); err != nil { 18 | diags = append(diags, diag.FromErr(err)...) 19 | } 20 | 21 | d.Set("site_id", resp.Site.ID) 22 | 23 | var assignments []interface{} 24 | if resp.MobileDevices != nil { 25 | for _, comp := range resp.MobileDevices { 26 | assignments = append(assignments, comp.ID) 27 | } 28 | 29 | if err := d.Set("assigned_mobile_device_ids", assignments); err != nil { 30 | diags = append(diags, diag.FromErr(err)...) 31 | } 32 | } 33 | 34 | return diags 35 | } 36 | -------------------------------------------------------------------------------- /internal/resources/userinitiatedenrollment/helpers.go: -------------------------------------------------------------------------------- 1 | package userinitiatedenrollment 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "strings" 7 | 8 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 9 | ) 10 | 11 | // getLanguageCodesMap fetches language codes from the Jamf Pro API 12 | // processes each language code adds lowercase version for case-insensitive matching 13 | // and creates a map of language names to their codes 14 | func getLanguageCodesMap(client *jamfpro.Client) (map[string]string, error) { 15 | languageCodes, err := client.GetEnrollmentLanguageCodes() 16 | if err != nil { 17 | return nil, fmt.Errorf("failed to fetch language codes from Jamf Pro API: %v", err) 18 | } 19 | 20 | codeMap := make(map[string]string) 21 | 22 | for _, code := range languageCodes { 23 | if code.Name != "" && code.Value != "" { 24 | codeMap[strings.ToLower(strings.TrimSpace(code.Name))] = code.Value 25 | } 26 | } 27 | 28 | log.Printf("[DEBUG] Loaded %d language codes from Jamf Pro API", len(languageCodes)) 29 | return codeMap, nil 30 | } 31 | -------------------------------------------------------------------------------- /internal/resources/volume_purchasing_locations/constructor.go: -------------------------------------------------------------------------------- 1 | package volume_purchasing_locations 2 | 3 | import ( 4 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 5 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 6 | ) 7 | 8 | // construct creates a VolumePurchasingLocationCreateUpdateRequest from the provided schema data 9 | func construct(d *schema.ResourceData) (*jamfpro.VolumePurchasingLocationCreateUpdateRequest, error) { 10 | request := &jamfpro.VolumePurchasingLocationCreateUpdateRequest{ 11 | Name: d.Get("name").(string), 12 | ServiceToken: d.Get("service_token").(string), 13 | AutomaticallyPopulatePurchasedContent: d.Get("automatically_populate_purchased_content").(bool), 14 | SendNotificationWhenNoLongerAssigned: d.Get("send_notification_when_no_longer_assigned").(bool), 15 | AutoRegisterManagedUsers: d.Get("auto_register_managed_users").(bool), 16 | SiteID: d.Get("site_id").(string), 17 | } 18 | 19 | return request, nil 20 | } 21 | -------------------------------------------------------------------------------- /scripts/check_pr_name.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import sys 5 | 6 | VALID_PREFIXES = [ 7 | "feat:", 8 | "fix:", 9 | "chore:" 10 | ] 11 | 12 | 13 | def check_pr_name(pr_name: str): 14 | """ 15 | Process the input string argument. 16 | 17 | Args: 18 | input_string (str): The input string to process 19 | 20 | Returns: 21 | None 22 | """ 23 | if any(pr_name.lower().startswith(i) for i in VALID_PREFIXES): 24 | return 25 | 26 | print(f"PR Name has invalid prefix: {pr_name}, should be one of: {VALID_PREFIXES}") 27 | sys.exit(1) 28 | 29 | 30 | def main(): 31 | """Main entry point for the script.""" 32 | parser = argparse.ArgumentParser(description='Process a single string argument.') 33 | parser.add_argument('pr_name', type=str, help='Input string to process') 34 | 35 | pr_name = parser.parse_args().pr_name 36 | 37 | if not pr_name: 38 | print("Error: PR name is empty") 39 | sys.exit(1) 40 | 41 | check_pr_name(pr_name) 42 | 43 | if __name__ == "__main__": 44 | main() 45 | -------------------------------------------------------------------------------- /scripts/errcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Check gofmt 4 | echo "==> Checking for unchecked errors..." 5 | 6 | if ! which errcheck > /dev/null; then 7 | echo "==> Installing errcheck..." 8 | go get -u github.com/kisielk/errcheck 9 | fi 10 | 11 | err_files=$(errcheck -ignoretests \ 12 | -ignore 'github.com/hashicorp/terraform/helper/schema:Set' \ 13 | -ignore 'bytes:.*' \ 14 | -ignore 'io:Close|Write' \ 15 | $(go list ./...| grep -v /vendor/)) 16 | 17 | if [[ -n ${err_files} ]]; then 18 | echo 'Unchecked errors found in the following places:' 19 | echo "${err_files}" 20 | echo "Please handle returned errors. You can check directly with \`make errcheck\`" 21 | exit 1 22 | fi 23 | 24 | exit 0 -------------------------------------------------------------------------------- /scripts/gofmtcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Check gofmt 4 | echo "==> Checking that code complies with gofmt requirements..." 5 | gofmt_files=$(gofmt -l $(find . -name '*.go' | grep -v vendor)) 6 | if [[ -n ${gofmt_files} ]]; then 7 | echo 'gofmt needs running on the following files:' 8 | echo "${gofmt_files}" 9 | echo "You can use the command: 'make fmt' to reformat code." 10 | exit 1 11 | fi 12 | 13 | exit 0 14 | -------------------------------------------------------------------------------- /scripts/maintainence/GetJamfAPIPrivileges/GetJamfAPIPrivileges.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "log" 7 | "os" 8 | 9 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 10 | ) 11 | 12 | func main() { 13 | client, err := jamfpro.BuildClientWithEnv() 14 | if err != nil { 15 | log.Fatalf("Failed to initialize Jamf Pro client: %v", err) 16 | } 17 | 18 | appInstallers, err := client.GetJamfAPIPrivileges() 19 | if err != nil { 20 | log.Fatalf("Error fetching Jamf API Privileges list: %v", err) 21 | } 22 | 23 | apiPrivilegesJSON, err := json.MarshalIndent(appInstallers, "", " ") 24 | if err != nil { 25 | log.Fatalf("Error marshaling Jamf API Privileges list data: %v", err) 26 | } 27 | 28 | err = os.WriteFile("api_privileges.json", apiPrivilegesJSON, 0644) 29 | if err != nil { 30 | log.Fatalf("Error writing to file: %v", err) 31 | } 32 | 33 | fmt.Println("App Catalog data written to api_privileges.json") 34 | } 35 | -------------------------------------------------------------------------------- /scripts/maintainence/GetJamfAppCatalogAppInstallerTitles/GetJamfAppCatalogAppInstallerTitles.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "log" 7 | "os" 8 | 9 | "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" 10 | ) 11 | 12 | func main() { 13 | client, err := jamfpro.BuildClientWithEnv() 14 | if err != nil { 15 | log.Fatalf("Failed to initialize Jamf Pro client: %v", err) 16 | } 17 | 18 | appInstallers, err := client.GetJamfAppCatalogAppInstallerTitles(nil) 19 | if err != nil { 20 | log.Fatalf("Error fetching Jamf App Catalog App Installer list: %v", err) 21 | } 22 | 23 | appInstallerJSON, err := json.MarshalIndent(appInstallers, "", " ") 24 | if err != nil { 25 | log.Fatalf("Error marshaling Jamf App Catalog App Installer list data: %v", err) 26 | } 27 | 28 | err = os.WriteFile("app_catalog_app_installer_titles.json", appInstallerJSON, 0644) 29 | if err != nil { 30 | log.Fatalf("Error writing to file: %v", err) 31 | } 32 | 33 | fmt.Println("App Catalog data written to app_catalog_app_installer_titles.json") 34 | } 35 | -------------------------------------------------------------------------------- /templates/data-sources.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{ .Name }}" 3 | description: |- 4 | {{ .Description }} 5 | --- 6 | 7 | # {{ .Name }} (Data Source) 8 | {{ .Description }} 9 | {{ if eq .HasExample true }} 10 | ## Example Usage 11 | {{ tffile (printf "examples/data-sources/%s/data-source.tf" .Name) }} 12 | {{ end }} 13 | {{ .SchemaMarkdown | trimspace }} -------------------------------------------------------------------------------- /templates/index.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{ .ProviderShortName }} Terraform Provider" 3 | subcategory: "" 4 | description: |- 5 | The Jamf Pro provider is used to manage a Jamf Pro instance. 6 | --- 7 | 8 | # Jamf Pro Provider 9 | 10 | The Jamf Pro Terraform provider is a plugin for Terraform that allows for the 11 | management of [Jamf Pro](https://www.jamf.com/products/jamf-pro/) configuration and resources. 12 | ----- 13 | A typical provider configuration would look something like: 14 | {{ tffile "examples/provider/provider.tf" }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} -------------------------------------------------------------------------------- /templates/resources.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{ .Name }}" 3 | description: |- 4 | {{ .Description }} 5 | --- 6 | 7 | # {{ .Name }} (Resource) 8 | {{ .Description }} 9 | {{ if eq .HasExample true }} 10 | ## Example Usage 11 | {{ tffile (printf "examples/resources/%s/resource.tf" .Name) }} 12 | {{ end }} 13 | {{ .SchemaMarkdown | trimspace }} -------------------------------------------------------------------------------- /terraform-provider-jamfpro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deploymenttheory/terraform-provider-jamfpro/fb9fdf0d55794f928ddc103c5e6a20b6abea5b0f/terraform-provider-jamfpro -------------------------------------------------------------------------------- /terraform-registry-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "metadata": { 4 | "protocol_versions": ["5.0"] 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /testing/action_scripts/infinite_diff_check.sh: -------------------------------------------------------------------------------- 1 | 2 | terraform apply -auto-approve 3 | 4 | terraform_output=$(terraform plan -detailed-exitcode -out=tfplan_post 2>&1) 5 | 6 | diff_cascade=$(echo "$terraform_output" | grep 'Plan:' && echo true || echo false) 7 | 8 | terraform destroy -auto-approve 9 | 10 | if [[ $diff_cascade == "true" ]]; then 11 | echo "::error::Unexpected changes detected after apply" 12 | exit 1 13 | else 14 | echo "No changes detected after apply - infrastructure is consistent" 15 | fi -------------------------------------------------------------------------------- /testing/action_scripts/requirements.txt: -------------------------------------------------------------------------------- 1 | python-dotenv 2 | jamfpy @ git+https://github.com/thejoeker12/jamfpy-python-sdk-jamfpro@v2.1.0-rc 3 | bs4 4 | requests -------------------------------------------------------------------------------- /testing/action_scripts/start_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TARGETS="$1" 4 | UUID="$2" 5 | 6 | if [[ "$TARGETS" == *"jamfpro_static_computer_group"* ]] || [[ "$TARGETS" == "all" ]]; then 7 | echo running scaffolding 8 | python3 ./action_scripts/scaffolding_static_group_computers.py -r "$UUID" 9 | fi 10 | 11 | terraform init 12 | terraform fmt 13 | terraform validate 14 | terraform test -------------------------------------------------------------------------------- /testing/local/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | RUNID="" 3 | FORCE=false 4 | 5 | while getopts "r:f" opt; do 6 | case $opt in 7 | r) 8 | RUNID=$OPTARG 9 | ;; 10 | f) 11 | FORCE=true 12 | ;; 13 | \?) 14 | echo "Invalid option: -$OPTARG" >&2 15 | exit 1 16 | ;; 17 | esac 18 | done 19 | 20 | printf "\n##### BEGINNING CLEANUP #####\n" 21 | printf "Purging data source files in /data_sources...\n" 22 | rm -rf ../data_sources 23 | printf "purging resources in jamfpro...\n" 24 | 25 | if [ "$FORCE" = true ]; then 26 | python3 jamfpy/clean_up.py -f 27 | elif [ -n "$RUNID" ]; then 28 | python3 jamfpy/clean_up.py -r $RUNID 29 | else 30 | python3 jamfpy/clean_up.py 31 | fi 32 | -------------------------------------------------------------------------------- /testing/local/run_local.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Initial cleanup 3 | (cd ./setup && bash ./cleanup.sh) 4 | # Scaffolding 5 | (cd ./setup && bash ./scaffolding.sh) 6 | # Run tests 7 | terraform init 8 | terraform test 9 | # Post run cleanup 10 | (cd ./setup && bash ./cleanup.sh) 11 | -------------------------------------------------------------------------------- /testing/payloads/jamfpro_building/buildings.tf: -------------------------------------------------------------------------------- 1 | // ========================================================================== // 2 | // Buildings 3 | // ========================================================================== // 4 | 5 | // ========================================================================== // 6 | // Single buildings 7 | 8 | resource "jamfpro_building" "building_min" { 9 | name = "tf-testing-${var.testing_id}-min-${random_id.rng.hex}" 10 | } 11 | 12 | resource "jamfpro_building" "building_max" { 13 | name = "tf-testing-${var.testing_id}-max-${random_id.rng.hex}" 14 | 15 | street_address1 = "unit 1" 16 | street_address2 = "1 example drive" 17 | city = "Jamftown" 18 | state_province = "Jamfshire" 19 | zip_postal_code = "JM22 5AM" 20 | country = "Jamf Republic" 21 | } 22 | 23 | // ========================================================================== // 24 | // Multiple buildings 25 | resource "jamfpro_building" "building_multiple_max" { 26 | count = 100 27 | name = "tf-testing-${var.testing_id}-max-${count.index}-${random_id.rng.hex}" 28 | street_address1 = "unit 1" 29 | street_address2 = "1 example drive" 30 | city = "Jamftown" 31 | state_province = "Jamfshire" 32 | zip_postal_code = "JM22 5AM" 33 | country = "Jamf Republic" 34 | } 35 | 36 | resource "jamfpro_building" "building_multiple_min" { 37 | count = 100 38 | name = "tf-testing-${var.testing_id}-min-${count.index}-${random_id.rng.hex}" 39 | } -------------------------------------------------------------------------------- /testing/payloads/jamfpro_building/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /testing/payloads/jamfpro_category/categories.tf: -------------------------------------------------------------------------------- 1 | // ========================================================================== // 2 | // Categories 3 | // ========================================================================== // 4 | 5 | // ========================================================================== // 6 | // Single Categories 7 | 8 | resource "jamfpro_category" "category_min" { 9 | name = "tf-testing-${var.testing_id}-min-${random_id.rng.hex}" 10 | } 11 | 12 | resource "jamfpro_category" "category_max" { 13 | name = "tf-testing-${var.testing_id}-max-${random_id.rng.hex}" 14 | priority = 2 15 | } 16 | 17 | // ========================================================================== // 18 | // Multiple Categories 19 | 20 | resource "jamfpro_category" "category_min_multiple" { 21 | count = 100 22 | name = "tf-testing-${var.testing_id}-min-${count.index}-${random_id.rng.hex}" 23 | } 24 | 25 | resource "jamfpro_category" "category_max_multiple" { 26 | count = 100 27 | name = "tf-testing-${var.testing_id}-max-${count.index}-${random_id.rng.hex}" 28 | priority = 2 29 | } -------------------------------------------------------------------------------- /testing/payloads/jamfpro_category/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /testing/payloads/jamfpro_computer_extension_attribute/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /testing/payloads/jamfpro_department/departments.tf: -------------------------------------------------------------------------------- 1 | // ========================================================================== // 2 | // Departments 3 | // ========================================================================== // 4 | 5 | # Departments only consist of a name so cannot be min max tested. 6 | 7 | // ========================================================================== // 8 | // Single department 9 | 10 | resource "jamfpro_department" "department" { 11 | name = "tf-testing-${var.testing_id}-${random_id.rng.hex}" 12 | } 13 | 14 | // ========================================================================== // 15 | // Multiple departments 16 | 17 | resource "jamfpro_department" "multiple_departments" { 18 | count = 100 19 | name = "tf-testing-${var.testing_id}-${count.index}-${random_id.rng.hex}" 20 | } -------------------------------------------------------------------------------- /testing/payloads/jamfpro_department/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /testing/payloads/jamfpro_script/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /testing/payloads/jamfpro_static_computer_group/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /testing/payloads/jamfpro_static_computer_group/static_computer_groups.tf: -------------------------------------------------------------------------------- 1 | // ========================================================================== // 2 | // Static Computer Groups 3 | // ========================================================================== // 4 | 5 | data "local_file" "site_and_computer_ids" { 6 | filename = "testing/data_sources/site_and_computer_ids.json" 7 | } 8 | 9 | resource "jamfpro_static_computer_group" "name" { 10 | name = "tf-testing-${var.testing_id}-script-max-${random_id.rng.hex}" 11 | site_id = jsondecode(data.local_file.site_and_computer_ids.content).site 12 | assigned_computer_ids = jsondecode(data.local_file.site_and_computer_ids.content).computers 13 | } 14 | -------------------------------------------------------------------------------- /testing/testing/accounts/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /tools/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | 3 | package tools 4 | 5 | import ( 6 | // Documentation generation 7 | _ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs" 8 | ) 9 | --------------------------------------------------------------------------------