From bb3494356aecbf0b37183da04eaf322996273771 Mon Sep 17 00:00:00 2001 From: Ansible Core Team Date: Mon, 9 Mar 2020 09:40:31 +0000 Subject: [PATCH] Migrated to community.windows --- lib/ansible/modules/commands/psexec.py | 520 -------- .../windows/win_audit_policy_system.ps1 | 143 --- .../windows/win_audit_policy_system.py | 73 -- .../modules/windows/win_audit_rule.ps1 | 193 --- lib/ansible/modules/windows/win_audit_rule.py | 142 --- .../modules/windows/win_auto_logon.ps1 | 403 ------ lib/ansible/modules/windows/win_auto_logon.py | 77 -- .../modules/windows/win_certificate_info.ps1 | 132 -- .../modules/windows/win_certificate_info.py | 236 ---- .../modules/windows/win_chocolatey.ps1 | 803 ------------ lib/ansible/modules/windows/win_chocolatey.py | 385 ------ .../modules/windows/win_chocolatey_config.ps1 | 122 -- .../modules/windows/win_chocolatey_config.py | 66 - .../modules/windows/win_chocolatey_facts.ps1 | 182 --- .../modules/windows/win_chocolatey_facts.py | 144 --- .../windows/win_chocolatey_feature.ps1 | 74 -- .../modules/windows/win_chocolatey_feature.py | 55 - .../modules/windows/win_chocolatey_source.ps1 | 306 ----- .../modules/windows/win_chocolatey_source.py | 128 -- .../windows/win_computer_description.ps1 | 54 - .../windows/win_computer_description.py | 75 -- .../modules/windows/win_credential.ps1 | 714 ----------- lib/ansible/modules/windows/win_credential.py | 209 --- .../windows/win_data_deduplication.ps1 | 129 -- .../modules/windows/win_data_deduplication.py | 87 -- lib/ansible/modules/windows/win_defrag.ps1 | 97 -- lib/ansible/modules/windows/win_defrag.py | 101 -- .../modules/windows/win_disk_facts.ps1 | 251 ---- lib/ansible/modules/windows/win_disk_facts.py | 891 ------------- .../modules/windows/win_disk_image.ps1 | 78 -- lib/ansible/modules/windows/win_disk_image.py | 67 - .../modules/windows/win_dns_record.ps1 | 149 --- lib/ansible/modules/windows/win_dns_record.py | 131 -- .../modules/windows/win_domain_computer.ps1 | 208 --- .../modules/windows/win_domain_computer.py | 123 -- .../modules/windows/win_domain_group.ps1 | 344 ----- .../modules/windows/win_domain_group.py | 242 ---- .../windows/win_domain_group_membership.ps1 | 131 -- .../windows/win_domain_group_membership.py | 130 -- .../windows/win_domain_object_info.ps1 | 271 ---- .../modules/windows/win_domain_object_info.py | 162 --- .../modules/windows/win_domain_user.ps1 | 384 ------ .../modules/windows/win_domain_user.py | 376 ------ .../modules/windows/win_dotnet_ngen.ps1 | 61 - .../modules/windows/win_dotnet_ngen.py | 88 -- lib/ansible/modules/windows/win_eventlog.ps1 | 287 ----- lib/ansible/modules/windows/win_eventlog.py | 166 --- .../modules/windows/win_eventlog_entry.ps1 | 106 -- .../modules/windows/win_eventlog_entry.py | 83 -- .../modules/windows/win_file_compression.ps1 | 118 -- .../modules/windows/win_file_compression.py | 100 -- .../modules/windows/win_file_version.ps1 | 63 - .../modules/windows/win_file_version.py | 78 -- lib/ansible/modules/windows/win_firewall.ps1 | 68 - lib/ansible/modules/windows/win_firewall.py | 75 -- .../modules/windows/win_firewall_rule.ps1 | 257 ---- .../modules/windows/win_firewall_rule.py | 192 --- lib/ansible/modules/windows/win_format.ps1 | 200 --- lib/ansible/modules/windows/win_format.py | 103 -- lib/ansible/modules/windows/win_hosts.ps1 | 257 ---- lib/ansible/modules/windows/win_hosts.py | 126 -- lib/ansible/modules/windows/win_hotfix.ps1 | 239 ---- lib/ansible/modules/windows/win_hotfix.py | 142 --- .../modules/windows/win_http_proxy.ps1 | 267 ---- lib/ansible/modules/windows/win_http_proxy.py | 103 -- .../windows/win_iis_virtualdirectory.ps1 | 99 -- .../windows/win_iis_virtualdirectory.py | 75 -- .../windows/win_iis_webapplication.ps1 | 138 -- .../modules/windows/win_iis_webapplication.py | 99 -- .../modules/windows/win_iis_webapppool.ps1 | 307 ----- .../modules/windows/win_iis_webapppool.py | 211 --- .../modules/windows/win_iis_webbinding.ps1 | 377 ------ .../modules/windows/win_iis_webbinding.py | 154 --- .../modules/windows/win_iis_website.ps1 | 180 --- .../modules/windows/win_iis_website.py | 121 -- .../modules/windows/win_inet_proxy.ps1 | 495 ------- lib/ansible/modules/windows/win_inet_proxy.py | 173 --- .../modules/windows/win_initialize_disk.ps1 | 151 --- .../modules/windows/win_initialize_disk.py | 88 -- .../modules/windows/win_lineinfile.ps1 | 450 ------- lib/ansible/modules/windows/win_lineinfile.py | 180 --- .../modules/windows/win_mapped_drive.ps1 | 444 ------- .../modules/windows/win_mapped_drive.py | 155 --- lib/ansible/modules/windows/win_msg.ps1 | 52 - lib/ansible/modules/windows/win_msg.py | 96 -- lib/ansible/modules/windows/win_netbios.ps1 | 72 -- lib/ansible/modules/windows/win_netbios.py | 80 -- lib/ansible/modules/windows/win_nssm.ps1 | 498 -------- lib/ansible/modules/windows/win_nssm.py | 217 ---- lib/ansible/modules/windows/win_pagefile.ps1 | 202 --- lib/ansible/modules/windows/win_pagefile.py | 139 -- lib/ansible/modules/windows/win_partition.ps1 | 326 ----- lib/ansible/modules/windows/win_partition.py | 117 -- lib/ansible/modules/windows/win_pester.ps1 | 116 -- lib/ansible/modules/windows/win_pester.py | 113 -- .../modules/windows/win_power_plan.ps1 | 207 --- lib/ansible/modules/windows/win_power_plan.py | 59 - .../modules/windows/win_product_facts.ps1 | 85 -- .../modules/windows/win_product_facts.py | 69 - lib/ansible/modules/windows/win_psexec.ps1 | 152 --- lib/ansible/modules/windows/win_psexec.py | 172 --- lib/ansible/modules/windows/win_psmodule.ps1 | 468 ------- lib/ansible/modules/windows/win_psmodule.py | 155 --- .../modules/windows/win_psrepository.ps1 | 68 - .../modules/windows/win_psrepository.py | 78 -- .../modules/windows/win_psrepository_info.ps1 | 68 - .../modules/windows/win_psrepository_info.py | 112 -- .../modules/windows/win_rabbitmq_plugin.ps1 | 157 --- .../modules/windows/win_rabbitmq_plugin.py | 63 - lib/ansible/modules/windows/win_rds_cap.ps1 | 357 ------ lib/ansible/modules/windows/win_rds_cap.py | 131 -- lib/ansible/modules/windows/win_rds_rap.ps1 | 282 ---- lib/ansible/modules/windows/win_rds_rap.py | 89 -- .../modules/windows/win_rds_settings.ps1 | 100 -- .../modules/windows/win_rds_settings.py | 62 - lib/ansible/modules/windows/win_region.ps1 | 365 ------ lib/ansible/modules/windows/win_region.py | 100 -- lib/ansible/modules/windows/win_regmerge.ps1 | 97 -- lib/ansible/modules/windows/win_regmerge.py | 82 -- lib/ansible/modules/windows/win_robocopy.ps1 | 145 --- lib/ansible/modules/windows/win_robocopy.py | 147 --- lib/ansible/modules/windows/win_route.ps1 | 104 -- lib/ansible/modules/windows/win_route.py | 70 - lib/ansible/modules/windows/win_say.ps1 | 95 -- lib/ansible/modules/windows/win_say.py | 116 -- .../modules/windows/win_scheduled_task.ps1 | 1133 ----------------- .../modules/windows/win_scheduled_task.py | 546 -------- .../windows/win_scheduled_task_stat.ps1 | 330 ----- .../windows/win_scheduled_task_stat.py | 379 ------ .../modules/windows/win_security_policy.ps1 | 196 --- .../modules/windows/win_security_policy.py | 126 -- lib/ansible/modules/windows/win_shortcut.ps1 | 374 ------ lib/ansible/modules/windows/win_shortcut.py | 123 -- lib/ansible/modules/windows/win_snmp.ps1 | 126 -- lib/ansible/modules/windows/win_snmp.py | 80 -- lib/ansible/modules/windows/win_timezone.ps1 | 70 - lib/ansible/modules/windows/win_timezone.py | 68 - lib/ansible/modules/windows/win_toast.ps1 | 90 -- lib/ansible/modules/windows/win_toast.py | 102 -- lib/ansible/modules/windows/win_unzip.ps1 | 178 --- lib/ansible/modules/windows/win_unzip.py | 113 -- .../modules/windows/win_user_profile.ps1 | 163 --- .../modules/windows/win_user_profile.py | 113 -- .../modules/windows/win_wait_for_process.ps1 | 176 --- .../modules/windows/win_wait_for_process.py | 134 -- lib/ansible/modules/windows/win_wakeonlan.ps1 | 52 - lib/ansible/modules/windows/win_wakeonlan.py | 62 - lib/ansible/modules/windows/win_webpicmd.ps1 | 116 -- lib/ansible/modules/windows/win_webpicmd.py | 42 - lib/ansible/modules/windows/win_xml.ps1 | 265 ---- lib/ansible/modules/windows/win_xml.py | 150 --- lib/ansible/plugins/lookup/laps_password.py | 358 ------ test/integration/targets/psexec/aliases | 3 - .../integration/targets/psexec/tasks/main.yml | 49 - .../targets/psexec/tasks/tests.yml | 231 ---- .../targets/win_audit_policy_system/aliases | 1 - .../win_audit_policy_system/defaults/main.yml | 3 - .../win_audit_policy_system/tasks/add.yml | 108 -- .../win_audit_policy_system/tasks/main.yml | 25 - .../win_audit_policy_system/tasks/remove.yml | 96 -- .../targets/win_audit_rule/aliases | 1 - .../targets/win_audit_rule/defaults/main.yml | 7 - .../library/test_get_audit_rule.ps1 | 98 -- .../targets/win_audit_rule/tasks/add.yml | 172 --- .../targets/win_audit_rule/tasks/main.yml | 33 - .../targets/win_audit_rule/tasks/modify.yml | 172 --- .../targets/win_audit_rule/tasks/remove.yml | 151 --- .../targets/win_auto_logon/aliases | 1 - .../targets/win_auto_logon/defaults/main.yml | 3 - .../library/test_autologon_info.ps1 | 214 ---- .../targets/win_auto_logon/tasks/main.yml | 42 - .../targets/win_auto_logon/tasks/tests.yml | 178 --- .../targets/win_certificate_info/aliases | 1 - .../win_certificate_info/defaults/main.yml | 3 - .../win_certificate_info/files/root-cert.pem | 20 - .../win_certificate_info/files/subj-cert.pem | 19 - .../win_certificate_info/meta/main.yml | 2 - .../win_certificate_info/tasks/main.yml | 88 -- .../win_certificate_info/tasks/tests.yml | 90 -- .../targets/win_chocolatey/aliases | 1 - .../targets/win_chocolatey/defaults/main.yml | 9 - .../win_chocolatey/files/package.nuspec | 13 - .../files/tools/chocolateyUninstall.ps1 | 9 - .../files/tools/chocolateyinstall.ps1 | 55 - .../targets/win_chocolatey/tasks/main.yml | 110 -- .../targets/win_chocolatey/tasks/tests.yml | 610 --------- .../targets/win_chocolatey_config/aliases | 1 - .../win_chocolatey_config/tasks/main.yml | 32 - .../win_chocolatey_config/tasks/tests.yml | 141 -- .../targets/win_chocolatey_facts/aliases | 1 - .../win_chocolatey_facts/tasks/main.yml | 69 - .../targets/win_chocolatey_feature/aliases | 1 - .../filter_plugins/choco_checksum_state.py | 14 - .../win_chocolatey_feature/tasks/main.yml | 20 - .../win_chocolatey_feature/tasks/tests.yml | 95 -- .../targets/win_chocolatey_source/aliases | 1 - .../win_chocolatey_source/defaults/main.yml | 3 - .../library/choco_source.ps1 | 65 - .../win_chocolatey_source/tasks/main.yml | 31 - .../win_chocolatey_source/tasks/tests.yml | 373 ------ .../targets/win_computer_description/aliases | 2 - .../defaults/main.yml | 6 - .../win_computer_description/tasks/main.yml | 200 --- .../targets/win_credential/aliases | 1 - .../targets/win_credential/defaults/main.yml | 19 - .../targets/win_credential/files/cert.pfx | Bin 2373 -> 0 bytes .../library/test_cred_facts.ps1 | 498 -------- .../targets/win_credential/meta/main.yml | 2 - .../targets/win_credential/tasks/main.yml | 64 - .../targets/win_credential/tasks/tests.yml | 638 ---------- .../targets/win_data_deduplication/aliases | 4 - .../win_data_deduplication/meta/main.yml | 2 - .../win_data_deduplication/tasks/main.yml | 2 - .../win_data_deduplication/tasks/pre_test.yml | 40 - .../win_data_deduplication/tasks/tests.yml | 47 - .../templates/partition_creation_script.j2 | 11 - .../templates/partition_deletion_script.j2 | 3 - .../targets/win_disk_facts/aliases | 3 - .../targets/win_disk_facts/tasks/main.yml | 13 - .../targets/win_disk_facts/tasks/tests.yml | 18 - .../targets/win_dns_record/aliases | 3 - .../targets/win_dns_record/defaults/main.yml | 3 - .../targets/win_dns_record/tasks/clean.yml | 17 - .../targets/win_dns_record/tasks/main.yml | 12 - .../targets/win_dns_record/tasks/tests-A.yml | 186 --- .../win_dns_record/tasks/tests-AAAA.yml | 186 --- .../win_dns_record/tasks/tests-CNAME.yml | 186 --- .../win_dns_record/tasks/tests-PTR.yml | 186 --- .../win_dns_record/tasks/tests-diff.yml | 63 - .../targets/win_dns_record/tasks/tests.yml | 32 - .../targets/win_domain_computer/aliases | 1 - .../win_domain_computer/tasks/main.yml | 71 -- .../targets/win_domain_group/aliases | 1 - .../win_domain_group/defaults/main.yml | 3 - .../targets/win_domain_group/tasks/main.yml | 353 ----- .../targets/win_domain_object_info/aliases | 1 - .../win_domain_object_info/handlers/main.yml | 5 - .../win_domain_object_info/tasks/main.yml | 125 -- .../targets/win_dotnet_ngen/aliases | 1 - .../targets/win_dotnet_ngen/tasks/main.yml | 20 - test/integration/targets/win_eventlog/aliases | 1 - .../targets/win_eventlog/tasks/main.yml | 10 - .../targets/win_eventlog/tasks/tests.yml | 447 ------- .../targets/win_eventlog_entry/aliases | 1 - .../win_eventlog_entry/defaults/main.yml | 6 - .../library/test_win_eventlog_entry.ps1 | 33 - .../targets/win_eventlog_entry/tasks/main.yml | 33 - .../win_eventlog_entry/tasks/tests.yml | 159 --- .../targets/win_file_compression/aliases | 1 - .../win_file_compression/defaults/main.yml | 5 - .../win_file_compression/meta/main.yml | 2 - .../win_file_compression/tasks/main.yml | 224 ---- test/integration/targets/win_firewall/aliases | 5 - .../targets/win_firewall/tasks/main.yml | 52 - .../targets/win_firewall/tasks/tests.yml | 185 --- .../targets/win_firewall_rule/aliases | 1 - .../targets/win_firewall_rule/tasks/main.yml | 474 ------- test/integration/targets/win_format/aliases | 3 - .../targets/win_format/meta/main.yml | 2 - .../targets/win_format/tasks/main.yml | 7 - .../targets/win_format/tasks/pre_test.yml | 21 - .../targets/win_format/tasks/tests.yml | 182 --- .../templates/partition_creation_script.j2 | 11 - .../templates/partition_deletion_script.j2 | 3 - test/integration/targets/win_hosts/aliases | 1 - .../targets/win_hosts/defaults/main.yml | 13 - .../targets/win_hosts/meta/main.yml | 2 - .../targets/win_hosts/tasks/main.yml | 17 - .../targets/win_hosts/tasks/tests.yml | 189 --- test/integration/targets/win_hotfix/aliases | 1 - .../targets/win_hotfix/defaults/main.yml | 13 - .../targets/win_hotfix/tasks/main.yml | 54 - .../targets/win_hotfix/tasks/tests.yml | 35 - .../targets/win_hotfix/tasks/tests_2012R2.yml | 253 ---- .../targets/win_http_proxy/aliases | 1 - .../targets/win_http_proxy/tasks/main.yml | 14 - .../targets/win_http_proxy/tasks/tests.yml | 265 ---- .../targets/win_iis_webapplication/aliases | 1 - .../win_iis_webapplication/defaults/main.yml | 11 - .../win_iis_webapplication/meta/main.yml | 3 - .../win_iis_webapplication/tasks/main.yml | 70 - .../win_iis_webapplication/tasks/tests.yml | 91 -- .../targets/win_iis_webapppool/aliases | 1 - .../win_iis_webapppool/defaults/main.yml | 1 - .../targets/win_iis_webapppool/tasks/main.yml | 43 - .../win_iis_webapppool/tasks/tests.yml | 424 ------ .../targets/win_iis_webbinding/aliases | 1 - .../win_iis_webbinding/defaults/main.yml | 30 - .../library/test_get_webbindings.ps1 | 113 -- .../win_iis_webbinding/tasks/failures.yml | 70 - .../targets/win_iis_webbinding/tasks/http.yml | 317 ----- .../win_iis_webbinding/tasks/https-ge6.2.yml | 459 ------- .../win_iis_webbinding/tasks/https-lt6.2.yml | 423 ------ .../targets/win_iis_webbinding/tasks/main.yml | 62 - .../win_iis_webbinding/tasks/setup.yml | 93 -- .../targets/win_inet_proxy/aliases | 1 - .../library/win_inet_proxy_info.ps1 | 275 ---- .../library/win_phonebook_entry.ps1 | 521 -------- .../targets/win_inet_proxy/tasks/main.yml | 16 - .../targets/win_inet_proxy/tasks/tests.yml | 308 ----- .../targets/win_initialize_disk/aliases | 3 - .../win_initialize_disk/defaults/main.yml | 1 - .../win_initialize_disk/tasks/main.yml | 28 - .../win_initialize_disk/tasks/tests.yml | 104 -- .../templates/vhdx_creation_script.j2 | 5 - .../templates/vhdx_deletion_script.j2 | 3 - .../targets/win_lineinfile/aliases | 2 - .../targets/win_lineinfile/files/test.txt | 5 - .../win_lineinfile/files/test_linebreak.txt | 0 .../win_lineinfile/files/test_quoting.txt | 0 .../win_lineinfile/files/testempty.txt | 0 .../win_lineinfile/files/testnoeof.txt | 2 - .../targets/win_lineinfile/meta/main.yml | 2 - .../targets/win_lineinfile/tasks/main.yml | 708 ---------- .../targets/win_mapped_drive/aliases | 1 - .../win_mapped_drive/defaults/main.yml | 9 - .../targets/win_mapped_drive/tasks/main.yml | 99 -- .../targets/win_mapped_drive/tasks/tests.yml | 344 ----- test/integration/targets/win_msg/aliases | 2 - .../targets/win_msg/tasks/main.yml | 33 - test/integration/targets/win_netbios/aliases | 1 - .../targets/win_netbios/meta/main.yml | 2 - .../targets/win_netbios/tasks/main.yml | 30 - .../targets/win_netbios/tasks/tests.yml | 159 --- test/integration/targets/win_nssm/aliases | 2 - .../targets/win_nssm/defaults/main.yml | 4 - .../targets/win_nssm/tasks/main.yml | 44 - .../targets/win_nssm/tasks/tests.yml | 406 ------ test/integration/targets/win_pagefile/aliases | 2 - .../targets/win_pagefile/tasks/main.yml | 235 ---- .../integration/targets/win_partition/aliases | 3 - .../targets/win_partition/defaults/main.yml | 1 - .../targets/win_partition/tasks/main.yml | 28 - .../targets/win_partition/tasks/tests.yml | 261 ---- .../templates/vhdx_creation_script.j2 | 7 - .../templates/vhdx_deletion_script.j2 | 3 - test/integration/targets/win_pester/aliases | 1 - .../targets/win_pester/defaults/main.yml | 3 - .../targets/win_pester/files/fail.ps1 | 2 - .../targets/win_pester/files/test01.tests.ps1 | 5 - .../targets/win_pester/files/test02.tests.ps1 | 5 - .../targets/win_pester/files/test03.tests.ps1 | 11 - .../targets/win_pester/files/test04.tests.ps1 | 18 - .../targets/win_pester/tasks/main.yml | 56 - .../targets/win_pester/tasks/test.yml | 134 -- .../targets/win_power_plan/aliases | 1 - .../targets/win_power_plan/tasks/main.yml | 64 - .../targets/win_product_facts/aliases | 1 - .../targets/win_product_facts/tasks/main.yml | 11 - test/integration/targets/win_psexec/aliases | 1 - .../targets/win_psexec/meta/main.yml | 2 - .../targets/win_psexec/tasks/main.yml | 80 -- test/integration/targets/win_psmodule/aliases | 1 - .../win_psmodule/files/module/template.nuspec | 14 - .../win_psmodule/files/module/template.psd1 | 17 - .../win_psmodule/files/module/template.psm1 | 10 - .../targets/win_psmodule/files/openssl.conf | 9 - .../targets/win_psmodule/files/setup_certs.sh | 19 - .../win_psmodule/files/setup_modules.ps1 | 81 -- .../targets/win_psmodule/handlers/main.yml | 34 - .../targets/win_psmodule/meta/main.yml | 3 - .../targets/win_psmodule/tasks/main.yml | 454 ------- .../targets/win_psmodule/tasks/setup.yml | 115 -- .../targets/win_psrepository/aliases | 1 - .../win_psrepository/defaults/main.yml | 4 - .../targets/win_psrepository/meta/main.yml | 3 - .../targets/win_psrepository/tasks/main.yml | 16 - .../targets/win_psrepository/tasks/tests.yml | 200 --- .../targets/win_psrepository_info/aliases | 1 - .../win_psrepository_info/defaults/main.yml | 10 - .../win_psrepository_info/meta/main.yml | 2 - .../tasks/contains_all_fields.yml | 21 - .../win_psrepository_info/tasks/empty.yml | 19 - .../win_psrepository_info/tasks/main.yml | 51 - .../win_psrepository_info/tasks/multiple.yml | 37 - .../win_psrepository_info/tasks/single.yml | 26 - .../targets/win_rabbitmq_plugin/aliases | 2 - .../win_rabbitmq_plugin/tasks/main.yml | 7 - .../win_rabbitmq_plugin/tasks/tests.yml | 134 -- test/integration/targets/win_rds/aliases | 6 - .../targets/win_rds/defaults/main.yml | 9 - .../targets/win_rds/tasks/main.yml | 73 -- .../targets/win_rds/tasks/win_rds_cap.yml | 9 - .../win_rds/tasks/win_rds_cap_tests.yml | 264 ---- .../targets/win_rds/tasks/win_rds_rap.yml | 9 - .../win_rds/tasks/win_rds_rap_tests.yml | 254 ---- .../win_rds/tasks/win_rds_settings.yml | 66 - .../win_rds/tasks/win_rds_settings_tests.yml | 89 -- .../win_rds/templates/rds_base_cfg.xml.j2 | 58 - test/integration/targets/win_region/aliases | 1 - .../targets/win_region/meta/main.yml | 2 - .../targets/win_region/tasks/main.yml | 252 ---- test/integration/targets/win_regmerge/aliases | 1 - .../targets/win_regmerge/files/settings1.reg | Bin 374 -> 0 bytes .../targets/win_regmerge/files/settings2.reg | Bin 760 -> 0 bytes .../targets/win_regmerge/files/settings3.reg | Bin 1926 -> 0 bytes .../targets/win_regmerge/meta/main.yml | 2 - .../targets/win_regmerge/tasks/main.yml | 133 -- .../win_regmerge/templates/win_line_ending.j2 | 4 - .../targets/win_regmerge/vars/main.yml | 1 - test/integration/targets/win_route/aliases | 1 - .../targets/win_route/defaults/main.yml | 3 - .../targets/win_route/tasks/main.yml | 29 - .../targets/win_route/tasks/tests.yml | 79 -- test/integration/targets/win_say/aliases | 1 - .../targets/win_say/tasks/main.yml | 44 - .../targets/win_scheduled_task/aliases | 1 - .../win_scheduled_task/defaults/main.yml | 5 - .../win_scheduled_task/tasks/clean.yml | 16 - .../win_scheduled_task/tasks/failures.yml | 149 --- .../targets/win_scheduled_task/tasks/main.yml | 24 - .../win_scheduled_task/tasks/principals.yml | 436 ------- .../win_scheduled_task/tasks/tests.yml | 440 ------- .../win_scheduled_task/tasks/triggers.yml | 818 ------------ .../targets/win_scheduled_task_stat/aliases | 1 - .../win_scheduled_task_stat/defaults/main.yml | 3 - .../win_scheduled_task_stat/tasks/main.yml | 176 --- .../targets/win_security_policy/aliases | 1 - .../library/test_win_security_policy.ps1 | 53 - .../win_security_policy/tasks/main.yml | 41 - .../win_security_policy/tasks/tests.yml | 186 --- test/integration/targets/win_shortcut/aliases | 1 - .../targets/win_shortcut/tasks/clean.yml | 37 - .../targets/win_shortcut/tasks/main.yml | 34 - .../targets/win_shortcut/tasks/tests.yml | 367 ------ test/integration/targets/win_snmp/aliases | 2 - .../targets/win_snmp/tasks/cleanup.yml | 16 - .../win_snmp/tasks/cleanup_using_module.yml | 26 - .../targets/win_snmp/tasks/main.yml | 8 - .../targets/win_snmp/tasks/output_only.yml | 24 - .../targets/win_snmp/tasks/snmp_community.yml | 165 --- .../targets/win_snmp/tasks/snmp_managers.yml | 158 --- .../targets/win_snmp/vars/main.yml | 3 - test/integration/targets/win_timezone/aliases | 1 - .../targets/win_timezone/tasks/main.yml | 19 - .../targets/win_timezone/tasks/tests.yml | 100 -- test/integration/targets/win_toast/aliases | 2 - .../targets/win_toast/tasks/main.yml | 13 - .../targets/win_toast/tasks/setup.yml | 27 - .../targets/win_toast/tasks/tests.yml | 106 -- test/integration/targets/win_unzip/aliases | 1 - .../targets/win_unzip/defaults/main.yml | 1 - .../files/create_crafty_zip_files.py | 65 - .../targets/win_unzip/files/create_zip.py | 28 - .../targets/win_unzip/meta/main.yml | 2 - .../targets/win_unzip/tasks/main.yml | 171 --- .../targets/win_user_profile/aliases | 1 - .../targets/win_user_profile/tasks/main.yml | 42 - .../targets/win_user_profile/tasks/tests.yml | 374 ------ .../targets/win_wait_for_process/aliases | 1 - .../win_wait_for_process/tasks/main.yml | 200 --- .../integration/targets/win_wakeonlan/aliases | 1 - .../targets/win_wakeonlan/tasks/main.yml | 9 - test/integration/targets/win_xml/aliases | 1 - .../targets/win_xml/files/books.xml | 10 - .../targets/win_xml/files/config.xml | 4 - .../targets/win_xml/files/log4j.xml | 49 - .../targets/win_xml/files/plane.zip | Bin 792 -> 0 bytes .../integration/targets/win_xml/meta/main.yml | 2 - .../targets/win_xml/tasks/main.yml | 307 ----- test/sanity/ignore.txt | 65 - .../plugins/lookup/test_laps_password.py | 519 -------- 462 files changed, 52092 deletions(-) delete mode 100644 lib/ansible/modules/commands/psexec.py delete mode 100644 lib/ansible/modules/windows/win_audit_policy_system.ps1 delete mode 100644 lib/ansible/modules/windows/win_audit_policy_system.py delete mode 100644 lib/ansible/modules/windows/win_audit_rule.ps1 delete mode 100644 lib/ansible/modules/windows/win_audit_rule.py delete mode 100644 lib/ansible/modules/windows/win_auto_logon.ps1 delete mode 100644 lib/ansible/modules/windows/win_auto_logon.py delete mode 100644 lib/ansible/modules/windows/win_certificate_info.ps1 delete mode 100644 lib/ansible/modules/windows/win_certificate_info.py delete mode 100644 lib/ansible/modules/windows/win_chocolatey.ps1 delete mode 100644 lib/ansible/modules/windows/win_chocolatey.py delete mode 100644 lib/ansible/modules/windows/win_chocolatey_config.ps1 delete mode 100644 lib/ansible/modules/windows/win_chocolatey_config.py delete mode 100644 lib/ansible/modules/windows/win_chocolatey_facts.ps1 delete mode 100644 lib/ansible/modules/windows/win_chocolatey_facts.py delete mode 100644 lib/ansible/modules/windows/win_chocolatey_feature.ps1 delete mode 100644 lib/ansible/modules/windows/win_chocolatey_feature.py delete mode 100644 lib/ansible/modules/windows/win_chocolatey_source.ps1 delete mode 100644 lib/ansible/modules/windows/win_chocolatey_source.py delete mode 100644 lib/ansible/modules/windows/win_computer_description.ps1 delete mode 100644 lib/ansible/modules/windows/win_computer_description.py delete mode 100644 lib/ansible/modules/windows/win_credential.ps1 delete mode 100644 lib/ansible/modules/windows/win_credential.py delete mode 100644 lib/ansible/modules/windows/win_data_deduplication.ps1 delete mode 100644 lib/ansible/modules/windows/win_data_deduplication.py delete mode 100644 lib/ansible/modules/windows/win_defrag.ps1 delete mode 100644 lib/ansible/modules/windows/win_defrag.py delete mode 100644 lib/ansible/modules/windows/win_disk_facts.ps1 delete mode 100644 lib/ansible/modules/windows/win_disk_facts.py delete mode 100644 lib/ansible/modules/windows/win_disk_image.ps1 delete mode 100644 lib/ansible/modules/windows/win_disk_image.py delete mode 100644 lib/ansible/modules/windows/win_dns_record.ps1 delete mode 100644 lib/ansible/modules/windows/win_dns_record.py delete mode 100644 lib/ansible/modules/windows/win_domain_computer.ps1 delete mode 100644 lib/ansible/modules/windows/win_domain_computer.py delete mode 100644 lib/ansible/modules/windows/win_domain_group.ps1 delete mode 100644 lib/ansible/modules/windows/win_domain_group.py delete mode 100644 lib/ansible/modules/windows/win_domain_group_membership.ps1 delete mode 100644 lib/ansible/modules/windows/win_domain_group_membership.py delete mode 100644 lib/ansible/modules/windows/win_domain_object_info.ps1 delete mode 100644 lib/ansible/modules/windows/win_domain_object_info.py delete mode 100644 lib/ansible/modules/windows/win_domain_user.ps1 delete mode 100644 lib/ansible/modules/windows/win_domain_user.py delete mode 100644 lib/ansible/modules/windows/win_dotnet_ngen.ps1 delete mode 100644 lib/ansible/modules/windows/win_dotnet_ngen.py delete mode 100644 lib/ansible/modules/windows/win_eventlog.ps1 delete mode 100644 lib/ansible/modules/windows/win_eventlog.py delete mode 100644 lib/ansible/modules/windows/win_eventlog_entry.ps1 delete mode 100644 lib/ansible/modules/windows/win_eventlog_entry.py delete mode 100644 lib/ansible/modules/windows/win_file_compression.ps1 delete mode 100644 lib/ansible/modules/windows/win_file_compression.py delete mode 100644 lib/ansible/modules/windows/win_file_version.ps1 delete mode 100644 lib/ansible/modules/windows/win_file_version.py delete mode 100644 lib/ansible/modules/windows/win_firewall.ps1 delete mode 100644 lib/ansible/modules/windows/win_firewall.py delete mode 100644 lib/ansible/modules/windows/win_firewall_rule.ps1 delete mode 100644 lib/ansible/modules/windows/win_firewall_rule.py delete mode 100644 lib/ansible/modules/windows/win_format.ps1 delete mode 100644 lib/ansible/modules/windows/win_format.py delete mode 100644 lib/ansible/modules/windows/win_hosts.ps1 delete mode 100644 lib/ansible/modules/windows/win_hosts.py delete mode 100644 lib/ansible/modules/windows/win_hotfix.ps1 delete mode 100644 lib/ansible/modules/windows/win_hotfix.py delete mode 100644 lib/ansible/modules/windows/win_http_proxy.ps1 delete mode 100644 lib/ansible/modules/windows/win_http_proxy.py delete mode 100644 lib/ansible/modules/windows/win_iis_virtualdirectory.ps1 delete mode 100644 lib/ansible/modules/windows/win_iis_virtualdirectory.py delete mode 100644 lib/ansible/modules/windows/win_iis_webapplication.ps1 delete mode 100644 lib/ansible/modules/windows/win_iis_webapplication.py delete mode 100644 lib/ansible/modules/windows/win_iis_webapppool.ps1 delete mode 100644 lib/ansible/modules/windows/win_iis_webapppool.py delete mode 100644 lib/ansible/modules/windows/win_iis_webbinding.ps1 delete mode 100644 lib/ansible/modules/windows/win_iis_webbinding.py delete mode 100644 lib/ansible/modules/windows/win_iis_website.ps1 delete mode 100644 lib/ansible/modules/windows/win_iis_website.py delete mode 100644 lib/ansible/modules/windows/win_inet_proxy.ps1 delete mode 100644 lib/ansible/modules/windows/win_inet_proxy.py delete mode 100644 lib/ansible/modules/windows/win_initialize_disk.ps1 delete mode 100644 lib/ansible/modules/windows/win_initialize_disk.py delete mode 100644 lib/ansible/modules/windows/win_lineinfile.ps1 delete mode 100644 lib/ansible/modules/windows/win_lineinfile.py delete mode 100644 lib/ansible/modules/windows/win_mapped_drive.ps1 delete mode 100644 lib/ansible/modules/windows/win_mapped_drive.py delete mode 100644 lib/ansible/modules/windows/win_msg.ps1 delete mode 100644 lib/ansible/modules/windows/win_msg.py delete mode 100644 lib/ansible/modules/windows/win_netbios.ps1 delete mode 100644 lib/ansible/modules/windows/win_netbios.py delete mode 100644 lib/ansible/modules/windows/win_nssm.ps1 delete mode 100644 lib/ansible/modules/windows/win_nssm.py delete mode 100644 lib/ansible/modules/windows/win_pagefile.ps1 delete mode 100644 lib/ansible/modules/windows/win_pagefile.py delete mode 100644 lib/ansible/modules/windows/win_partition.ps1 delete mode 100644 lib/ansible/modules/windows/win_partition.py delete mode 100644 lib/ansible/modules/windows/win_pester.ps1 delete mode 100644 lib/ansible/modules/windows/win_pester.py delete mode 100644 lib/ansible/modules/windows/win_power_plan.ps1 delete mode 100644 lib/ansible/modules/windows/win_power_plan.py delete mode 100644 lib/ansible/modules/windows/win_product_facts.ps1 delete mode 100644 lib/ansible/modules/windows/win_product_facts.py delete mode 100644 lib/ansible/modules/windows/win_psexec.ps1 delete mode 100644 lib/ansible/modules/windows/win_psexec.py delete mode 100644 lib/ansible/modules/windows/win_psmodule.ps1 delete mode 100644 lib/ansible/modules/windows/win_psmodule.py delete mode 100644 lib/ansible/modules/windows/win_psrepository.ps1 delete mode 100644 lib/ansible/modules/windows/win_psrepository.py delete mode 100644 lib/ansible/modules/windows/win_psrepository_info.ps1 delete mode 100644 lib/ansible/modules/windows/win_psrepository_info.py delete mode 100644 lib/ansible/modules/windows/win_rabbitmq_plugin.ps1 delete mode 100644 lib/ansible/modules/windows/win_rabbitmq_plugin.py delete mode 100644 lib/ansible/modules/windows/win_rds_cap.ps1 delete mode 100644 lib/ansible/modules/windows/win_rds_cap.py delete mode 100644 lib/ansible/modules/windows/win_rds_rap.ps1 delete mode 100644 lib/ansible/modules/windows/win_rds_rap.py delete mode 100644 lib/ansible/modules/windows/win_rds_settings.ps1 delete mode 100644 lib/ansible/modules/windows/win_rds_settings.py delete mode 100644 lib/ansible/modules/windows/win_region.ps1 delete mode 100644 lib/ansible/modules/windows/win_region.py delete mode 100644 lib/ansible/modules/windows/win_regmerge.ps1 delete mode 100644 lib/ansible/modules/windows/win_regmerge.py delete mode 100644 lib/ansible/modules/windows/win_robocopy.ps1 delete mode 100644 lib/ansible/modules/windows/win_robocopy.py delete mode 100644 lib/ansible/modules/windows/win_route.ps1 delete mode 100644 lib/ansible/modules/windows/win_route.py delete mode 100644 lib/ansible/modules/windows/win_say.ps1 delete mode 100644 lib/ansible/modules/windows/win_say.py delete mode 100644 lib/ansible/modules/windows/win_scheduled_task.ps1 delete mode 100644 lib/ansible/modules/windows/win_scheduled_task.py delete mode 100644 lib/ansible/modules/windows/win_scheduled_task_stat.ps1 delete mode 100644 lib/ansible/modules/windows/win_scheduled_task_stat.py delete mode 100644 lib/ansible/modules/windows/win_security_policy.ps1 delete mode 100644 lib/ansible/modules/windows/win_security_policy.py delete mode 100644 lib/ansible/modules/windows/win_shortcut.ps1 delete mode 100644 lib/ansible/modules/windows/win_shortcut.py delete mode 100644 lib/ansible/modules/windows/win_snmp.ps1 delete mode 100644 lib/ansible/modules/windows/win_snmp.py delete mode 100644 lib/ansible/modules/windows/win_timezone.ps1 delete mode 100644 lib/ansible/modules/windows/win_timezone.py delete mode 100644 lib/ansible/modules/windows/win_toast.ps1 delete mode 100644 lib/ansible/modules/windows/win_toast.py delete mode 100644 lib/ansible/modules/windows/win_unzip.ps1 delete mode 100644 lib/ansible/modules/windows/win_unzip.py delete mode 100644 lib/ansible/modules/windows/win_user_profile.ps1 delete mode 100644 lib/ansible/modules/windows/win_user_profile.py delete mode 100644 lib/ansible/modules/windows/win_wait_for_process.ps1 delete mode 100644 lib/ansible/modules/windows/win_wait_for_process.py delete mode 100644 lib/ansible/modules/windows/win_wakeonlan.ps1 delete mode 100644 lib/ansible/modules/windows/win_wakeonlan.py delete mode 100644 lib/ansible/modules/windows/win_webpicmd.ps1 delete mode 100644 lib/ansible/modules/windows/win_webpicmd.py delete mode 100644 lib/ansible/modules/windows/win_xml.ps1 delete mode 100644 lib/ansible/modules/windows/win_xml.py delete mode 100644 lib/ansible/plugins/lookup/laps_password.py delete mode 100644 test/integration/targets/psexec/aliases delete mode 100644 test/integration/targets/psexec/tasks/main.yml delete mode 100644 test/integration/targets/psexec/tasks/tests.yml delete mode 100644 test/integration/targets/win_audit_policy_system/aliases delete mode 100644 test/integration/targets/win_audit_policy_system/defaults/main.yml delete mode 100644 test/integration/targets/win_audit_policy_system/tasks/add.yml delete mode 100644 test/integration/targets/win_audit_policy_system/tasks/main.yml delete mode 100644 test/integration/targets/win_audit_policy_system/tasks/remove.yml delete mode 100644 test/integration/targets/win_audit_rule/aliases delete mode 100644 test/integration/targets/win_audit_rule/defaults/main.yml delete mode 100644 test/integration/targets/win_audit_rule/library/test_get_audit_rule.ps1 delete mode 100644 test/integration/targets/win_audit_rule/tasks/add.yml delete mode 100644 test/integration/targets/win_audit_rule/tasks/main.yml delete mode 100644 test/integration/targets/win_audit_rule/tasks/modify.yml delete mode 100644 test/integration/targets/win_audit_rule/tasks/remove.yml delete mode 100644 test/integration/targets/win_auto_logon/aliases delete mode 100644 test/integration/targets/win_auto_logon/defaults/main.yml delete mode 100644 test/integration/targets/win_auto_logon/library/test_autologon_info.ps1 delete mode 100644 test/integration/targets/win_auto_logon/tasks/main.yml delete mode 100644 test/integration/targets/win_auto_logon/tasks/tests.yml delete mode 100644 test/integration/targets/win_certificate_info/aliases delete mode 100644 test/integration/targets/win_certificate_info/defaults/main.yml delete mode 100644 test/integration/targets/win_certificate_info/files/root-cert.pem delete mode 100644 test/integration/targets/win_certificate_info/files/subj-cert.pem delete mode 100644 test/integration/targets/win_certificate_info/meta/main.yml delete mode 100644 test/integration/targets/win_certificate_info/tasks/main.yml delete mode 100644 test/integration/targets/win_certificate_info/tasks/tests.yml delete mode 100644 test/integration/targets/win_chocolatey/aliases delete mode 100644 test/integration/targets/win_chocolatey/defaults/main.yml delete mode 100644 test/integration/targets/win_chocolatey/files/package.nuspec delete mode 100644 test/integration/targets/win_chocolatey/files/tools/chocolateyUninstall.ps1 delete mode 100644 test/integration/targets/win_chocolatey/files/tools/chocolateyinstall.ps1 delete mode 100644 test/integration/targets/win_chocolatey/tasks/main.yml delete mode 100644 test/integration/targets/win_chocolatey/tasks/tests.yml delete mode 100644 test/integration/targets/win_chocolatey_config/aliases delete mode 100644 test/integration/targets/win_chocolatey_config/tasks/main.yml delete mode 100644 test/integration/targets/win_chocolatey_config/tasks/tests.yml delete mode 100644 test/integration/targets/win_chocolatey_facts/aliases delete mode 100644 test/integration/targets/win_chocolatey_facts/tasks/main.yml delete mode 100644 test/integration/targets/win_chocolatey_feature/aliases delete mode 100644 test/integration/targets/win_chocolatey_feature/filter_plugins/choco_checksum_state.py delete mode 100644 test/integration/targets/win_chocolatey_feature/tasks/main.yml delete mode 100644 test/integration/targets/win_chocolatey_feature/tasks/tests.yml delete mode 100644 test/integration/targets/win_chocolatey_source/aliases delete mode 100644 test/integration/targets/win_chocolatey_source/defaults/main.yml delete mode 100644 test/integration/targets/win_chocolatey_source/library/choco_source.ps1 delete mode 100644 test/integration/targets/win_chocolatey_source/tasks/main.yml delete mode 100644 test/integration/targets/win_chocolatey_source/tasks/tests.yml delete mode 100644 test/integration/targets/win_computer_description/aliases delete mode 100644 test/integration/targets/win_computer_description/defaults/main.yml delete mode 100644 test/integration/targets/win_computer_description/tasks/main.yml delete mode 100644 test/integration/targets/win_credential/aliases delete mode 100644 test/integration/targets/win_credential/defaults/main.yml delete mode 100644 test/integration/targets/win_credential/files/cert.pfx delete mode 100644 test/integration/targets/win_credential/library/test_cred_facts.ps1 delete mode 100644 test/integration/targets/win_credential/meta/main.yml delete mode 100644 test/integration/targets/win_credential/tasks/main.yml delete mode 100644 test/integration/targets/win_credential/tasks/tests.yml delete mode 100644 test/integration/targets/win_data_deduplication/aliases delete mode 100644 test/integration/targets/win_data_deduplication/meta/main.yml delete mode 100644 test/integration/targets/win_data_deduplication/tasks/main.yml delete mode 100644 test/integration/targets/win_data_deduplication/tasks/pre_test.yml delete mode 100644 test/integration/targets/win_data_deduplication/tasks/tests.yml delete mode 100644 test/integration/targets/win_data_deduplication/templates/partition_creation_script.j2 delete mode 100644 test/integration/targets/win_data_deduplication/templates/partition_deletion_script.j2 delete mode 100644 test/integration/targets/win_disk_facts/aliases delete mode 100644 test/integration/targets/win_disk_facts/tasks/main.yml delete mode 100644 test/integration/targets/win_disk_facts/tasks/tests.yml delete mode 100644 test/integration/targets/win_dns_record/aliases delete mode 100644 test/integration/targets/win_dns_record/defaults/main.yml delete mode 100644 test/integration/targets/win_dns_record/tasks/clean.yml delete mode 100644 test/integration/targets/win_dns_record/tasks/main.yml delete mode 100644 test/integration/targets/win_dns_record/tasks/tests-A.yml delete mode 100644 test/integration/targets/win_dns_record/tasks/tests-AAAA.yml delete mode 100644 test/integration/targets/win_dns_record/tasks/tests-CNAME.yml delete mode 100644 test/integration/targets/win_dns_record/tasks/tests-PTR.yml delete mode 100644 test/integration/targets/win_dns_record/tasks/tests-diff.yml delete mode 100644 test/integration/targets/win_dns_record/tasks/tests.yml delete mode 100644 test/integration/targets/win_domain_computer/aliases delete mode 100644 test/integration/targets/win_domain_computer/tasks/main.yml delete mode 100644 test/integration/targets/win_domain_group/aliases delete mode 100644 test/integration/targets/win_domain_group/defaults/main.yml delete mode 100644 test/integration/targets/win_domain_group/tasks/main.yml delete mode 100644 test/integration/targets/win_domain_object_info/aliases delete mode 100644 test/integration/targets/win_domain_object_info/handlers/main.yml delete mode 100644 test/integration/targets/win_domain_object_info/tasks/main.yml delete mode 100644 test/integration/targets/win_dotnet_ngen/aliases delete mode 100644 test/integration/targets/win_dotnet_ngen/tasks/main.yml delete mode 100644 test/integration/targets/win_eventlog/aliases delete mode 100644 test/integration/targets/win_eventlog/tasks/main.yml delete mode 100644 test/integration/targets/win_eventlog/tasks/tests.yml delete mode 100644 test/integration/targets/win_eventlog_entry/aliases delete mode 100644 test/integration/targets/win_eventlog_entry/defaults/main.yml delete mode 100644 test/integration/targets/win_eventlog_entry/library/test_win_eventlog_entry.ps1 delete mode 100644 test/integration/targets/win_eventlog_entry/tasks/main.yml delete mode 100644 test/integration/targets/win_eventlog_entry/tasks/tests.yml delete mode 100644 test/integration/targets/win_file_compression/aliases delete mode 100644 test/integration/targets/win_file_compression/defaults/main.yml delete mode 100644 test/integration/targets/win_file_compression/meta/main.yml delete mode 100644 test/integration/targets/win_file_compression/tasks/main.yml delete mode 100644 test/integration/targets/win_firewall/aliases delete mode 100644 test/integration/targets/win_firewall/tasks/main.yml delete mode 100644 test/integration/targets/win_firewall/tasks/tests.yml delete mode 100644 test/integration/targets/win_firewall_rule/aliases delete mode 100644 test/integration/targets/win_firewall_rule/tasks/main.yml delete mode 100644 test/integration/targets/win_format/aliases delete mode 100644 test/integration/targets/win_format/meta/main.yml delete mode 100644 test/integration/targets/win_format/tasks/main.yml delete mode 100644 test/integration/targets/win_format/tasks/pre_test.yml delete mode 100644 test/integration/targets/win_format/tasks/tests.yml delete mode 100644 test/integration/targets/win_format/templates/partition_creation_script.j2 delete mode 100644 test/integration/targets/win_format/templates/partition_deletion_script.j2 delete mode 100644 test/integration/targets/win_hosts/aliases delete mode 100644 test/integration/targets/win_hosts/defaults/main.yml delete mode 100644 test/integration/targets/win_hosts/meta/main.yml delete mode 100644 test/integration/targets/win_hosts/tasks/main.yml delete mode 100644 test/integration/targets/win_hosts/tasks/tests.yml delete mode 100644 test/integration/targets/win_hotfix/aliases delete mode 100644 test/integration/targets/win_hotfix/defaults/main.yml delete mode 100644 test/integration/targets/win_hotfix/tasks/main.yml delete mode 100644 test/integration/targets/win_hotfix/tasks/tests.yml delete mode 100644 test/integration/targets/win_hotfix/tasks/tests_2012R2.yml delete mode 100644 test/integration/targets/win_http_proxy/aliases delete mode 100644 test/integration/targets/win_http_proxy/tasks/main.yml delete mode 100644 test/integration/targets/win_http_proxy/tasks/tests.yml delete mode 100644 test/integration/targets/win_iis_webapplication/aliases delete mode 100644 test/integration/targets/win_iis_webapplication/defaults/main.yml delete mode 100644 test/integration/targets/win_iis_webapplication/meta/main.yml delete mode 100644 test/integration/targets/win_iis_webapplication/tasks/main.yml delete mode 100644 test/integration/targets/win_iis_webapplication/tasks/tests.yml delete mode 100644 test/integration/targets/win_iis_webapppool/aliases delete mode 100644 test/integration/targets/win_iis_webapppool/defaults/main.yml delete mode 100644 test/integration/targets/win_iis_webapppool/tasks/main.yml delete mode 100644 test/integration/targets/win_iis_webapppool/tasks/tests.yml delete mode 100644 test/integration/targets/win_iis_webbinding/aliases delete mode 100644 test/integration/targets/win_iis_webbinding/defaults/main.yml delete mode 100644 test/integration/targets/win_iis_webbinding/library/test_get_webbindings.ps1 delete mode 100644 test/integration/targets/win_iis_webbinding/tasks/failures.yml delete mode 100644 test/integration/targets/win_iis_webbinding/tasks/http.yml delete mode 100644 test/integration/targets/win_iis_webbinding/tasks/https-ge6.2.yml delete mode 100644 test/integration/targets/win_iis_webbinding/tasks/https-lt6.2.yml delete mode 100644 test/integration/targets/win_iis_webbinding/tasks/main.yml delete mode 100644 test/integration/targets/win_iis_webbinding/tasks/setup.yml delete mode 100644 test/integration/targets/win_inet_proxy/aliases delete mode 100644 test/integration/targets/win_inet_proxy/library/win_inet_proxy_info.ps1 delete mode 100644 test/integration/targets/win_inet_proxy/library/win_phonebook_entry.ps1 delete mode 100644 test/integration/targets/win_inet_proxy/tasks/main.yml delete mode 100644 test/integration/targets/win_inet_proxy/tasks/tests.yml delete mode 100644 test/integration/targets/win_initialize_disk/aliases delete mode 100644 test/integration/targets/win_initialize_disk/defaults/main.yml delete mode 100644 test/integration/targets/win_initialize_disk/tasks/main.yml delete mode 100644 test/integration/targets/win_initialize_disk/tasks/tests.yml delete mode 100644 test/integration/targets/win_initialize_disk/templates/vhdx_creation_script.j2 delete mode 100644 test/integration/targets/win_initialize_disk/templates/vhdx_deletion_script.j2 delete mode 100644 test/integration/targets/win_lineinfile/aliases delete mode 100644 test/integration/targets/win_lineinfile/files/test.txt delete mode 100644 test/integration/targets/win_lineinfile/files/test_linebreak.txt delete mode 100644 test/integration/targets/win_lineinfile/files/test_quoting.txt delete mode 100644 test/integration/targets/win_lineinfile/files/testempty.txt delete mode 100644 test/integration/targets/win_lineinfile/files/testnoeof.txt delete mode 100644 test/integration/targets/win_lineinfile/meta/main.yml delete mode 100644 test/integration/targets/win_lineinfile/tasks/main.yml delete mode 100644 test/integration/targets/win_mapped_drive/aliases delete mode 100644 test/integration/targets/win_mapped_drive/defaults/main.yml delete mode 100644 test/integration/targets/win_mapped_drive/tasks/main.yml delete mode 100644 test/integration/targets/win_mapped_drive/tasks/tests.yml delete mode 100644 test/integration/targets/win_msg/aliases delete mode 100644 test/integration/targets/win_msg/tasks/main.yml delete mode 100644 test/integration/targets/win_netbios/aliases delete mode 100644 test/integration/targets/win_netbios/meta/main.yml delete mode 100644 test/integration/targets/win_netbios/tasks/main.yml delete mode 100644 test/integration/targets/win_netbios/tasks/tests.yml delete mode 100644 test/integration/targets/win_nssm/aliases delete mode 100644 test/integration/targets/win_nssm/defaults/main.yml delete mode 100644 test/integration/targets/win_nssm/tasks/main.yml delete mode 100644 test/integration/targets/win_nssm/tasks/tests.yml delete mode 100644 test/integration/targets/win_pagefile/aliases delete mode 100644 test/integration/targets/win_pagefile/tasks/main.yml delete mode 100644 test/integration/targets/win_partition/aliases delete mode 100644 test/integration/targets/win_partition/defaults/main.yml delete mode 100644 test/integration/targets/win_partition/tasks/main.yml delete mode 100644 test/integration/targets/win_partition/tasks/tests.yml delete mode 100644 test/integration/targets/win_partition/templates/vhdx_creation_script.j2 delete mode 100644 test/integration/targets/win_partition/templates/vhdx_deletion_script.j2 delete mode 100644 test/integration/targets/win_pester/aliases delete mode 100644 test/integration/targets/win_pester/defaults/main.yml delete mode 100644 test/integration/targets/win_pester/files/fail.ps1 delete mode 100644 test/integration/targets/win_pester/files/test01.tests.ps1 delete mode 100644 test/integration/targets/win_pester/files/test02.tests.ps1 delete mode 100644 test/integration/targets/win_pester/files/test03.tests.ps1 delete mode 100644 test/integration/targets/win_pester/files/test04.tests.ps1 delete mode 100644 test/integration/targets/win_pester/tasks/main.yml delete mode 100644 test/integration/targets/win_pester/tasks/test.yml delete mode 100644 test/integration/targets/win_power_plan/aliases delete mode 100644 test/integration/targets/win_power_plan/tasks/main.yml delete mode 100644 test/integration/targets/win_product_facts/aliases delete mode 100644 test/integration/targets/win_product_facts/tasks/main.yml delete mode 100644 test/integration/targets/win_psexec/aliases delete mode 100644 test/integration/targets/win_psexec/meta/main.yml delete mode 100644 test/integration/targets/win_psexec/tasks/main.yml delete mode 100644 test/integration/targets/win_psmodule/aliases delete mode 100644 test/integration/targets/win_psmodule/files/module/template.nuspec delete mode 100644 test/integration/targets/win_psmodule/files/module/template.psd1 delete mode 100644 test/integration/targets/win_psmodule/files/module/template.psm1 delete mode 100644 test/integration/targets/win_psmodule/files/openssl.conf delete mode 100644 test/integration/targets/win_psmodule/files/setup_certs.sh delete mode 100644 test/integration/targets/win_psmodule/files/setup_modules.ps1 delete mode 100644 test/integration/targets/win_psmodule/handlers/main.yml delete mode 100644 test/integration/targets/win_psmodule/meta/main.yml delete mode 100644 test/integration/targets/win_psmodule/tasks/main.yml delete mode 100644 test/integration/targets/win_psmodule/tasks/setup.yml delete mode 100644 test/integration/targets/win_psrepository/aliases delete mode 100644 test/integration/targets/win_psrepository/defaults/main.yml delete mode 100644 test/integration/targets/win_psrepository/meta/main.yml delete mode 100644 test/integration/targets/win_psrepository/tasks/main.yml delete mode 100644 test/integration/targets/win_psrepository/tasks/tests.yml delete mode 100644 test/integration/targets/win_psrepository_info/aliases delete mode 100644 test/integration/targets/win_psrepository_info/defaults/main.yml delete mode 100644 test/integration/targets/win_psrepository_info/meta/main.yml delete mode 100644 test/integration/targets/win_psrepository_info/tasks/contains_all_fields.yml delete mode 100644 test/integration/targets/win_psrepository_info/tasks/empty.yml delete mode 100644 test/integration/targets/win_psrepository_info/tasks/main.yml delete mode 100644 test/integration/targets/win_psrepository_info/tasks/multiple.yml delete mode 100644 test/integration/targets/win_psrepository_info/tasks/single.yml delete mode 100644 test/integration/targets/win_rabbitmq_plugin/aliases delete mode 100644 test/integration/targets/win_rabbitmq_plugin/tasks/main.yml delete mode 100644 test/integration/targets/win_rabbitmq_plugin/tasks/tests.yml delete mode 100644 test/integration/targets/win_rds/aliases delete mode 100644 test/integration/targets/win_rds/defaults/main.yml delete mode 100644 test/integration/targets/win_rds/tasks/main.yml delete mode 100644 test/integration/targets/win_rds/tasks/win_rds_cap.yml delete mode 100644 test/integration/targets/win_rds/tasks/win_rds_cap_tests.yml delete mode 100644 test/integration/targets/win_rds/tasks/win_rds_rap.yml delete mode 100644 test/integration/targets/win_rds/tasks/win_rds_rap_tests.yml delete mode 100644 test/integration/targets/win_rds/tasks/win_rds_settings.yml delete mode 100644 test/integration/targets/win_rds/tasks/win_rds_settings_tests.yml delete mode 100644 test/integration/targets/win_rds/templates/rds_base_cfg.xml.j2 delete mode 100644 test/integration/targets/win_region/aliases delete mode 100644 test/integration/targets/win_region/meta/main.yml delete mode 100644 test/integration/targets/win_region/tasks/main.yml delete mode 100644 test/integration/targets/win_regmerge/aliases delete mode 100644 test/integration/targets/win_regmerge/files/settings1.reg delete mode 100644 test/integration/targets/win_regmerge/files/settings2.reg delete mode 100644 test/integration/targets/win_regmerge/files/settings3.reg delete mode 100644 test/integration/targets/win_regmerge/meta/main.yml delete mode 100644 test/integration/targets/win_regmerge/tasks/main.yml delete mode 100644 test/integration/targets/win_regmerge/templates/win_line_ending.j2 delete mode 100644 test/integration/targets/win_regmerge/vars/main.yml delete mode 100644 test/integration/targets/win_route/aliases delete mode 100644 test/integration/targets/win_route/defaults/main.yml delete mode 100644 test/integration/targets/win_route/tasks/main.yml delete mode 100644 test/integration/targets/win_route/tasks/tests.yml delete mode 100644 test/integration/targets/win_say/aliases delete mode 100644 test/integration/targets/win_say/tasks/main.yml delete mode 100644 test/integration/targets/win_scheduled_task/aliases delete mode 100644 test/integration/targets/win_scheduled_task/defaults/main.yml delete mode 100644 test/integration/targets/win_scheduled_task/tasks/clean.yml delete mode 100644 test/integration/targets/win_scheduled_task/tasks/failures.yml delete mode 100644 test/integration/targets/win_scheduled_task/tasks/main.yml delete mode 100644 test/integration/targets/win_scheduled_task/tasks/principals.yml delete mode 100644 test/integration/targets/win_scheduled_task/tasks/tests.yml delete mode 100644 test/integration/targets/win_scheduled_task/tasks/triggers.yml delete mode 100644 test/integration/targets/win_scheduled_task_stat/aliases delete mode 100644 test/integration/targets/win_scheduled_task_stat/defaults/main.yml delete mode 100644 test/integration/targets/win_scheduled_task_stat/tasks/main.yml delete mode 100644 test/integration/targets/win_security_policy/aliases delete mode 100644 test/integration/targets/win_security_policy/library/test_win_security_policy.ps1 delete mode 100644 test/integration/targets/win_security_policy/tasks/main.yml delete mode 100644 test/integration/targets/win_security_policy/tasks/tests.yml delete mode 100644 test/integration/targets/win_shortcut/aliases delete mode 100644 test/integration/targets/win_shortcut/tasks/clean.yml delete mode 100644 test/integration/targets/win_shortcut/tasks/main.yml delete mode 100644 test/integration/targets/win_shortcut/tasks/tests.yml delete mode 100644 test/integration/targets/win_snmp/aliases delete mode 100644 test/integration/targets/win_snmp/tasks/cleanup.yml delete mode 100644 test/integration/targets/win_snmp/tasks/cleanup_using_module.yml delete mode 100644 test/integration/targets/win_snmp/tasks/main.yml delete mode 100644 test/integration/targets/win_snmp/tasks/output_only.yml delete mode 100644 test/integration/targets/win_snmp/tasks/snmp_community.yml delete mode 100644 test/integration/targets/win_snmp/tasks/snmp_managers.yml delete mode 100644 test/integration/targets/win_snmp/vars/main.yml delete mode 100644 test/integration/targets/win_timezone/aliases delete mode 100644 test/integration/targets/win_timezone/tasks/main.yml delete mode 100644 test/integration/targets/win_timezone/tasks/tests.yml delete mode 100644 test/integration/targets/win_toast/aliases delete mode 100644 test/integration/targets/win_toast/tasks/main.yml delete mode 100644 test/integration/targets/win_toast/tasks/setup.yml delete mode 100644 test/integration/targets/win_toast/tasks/tests.yml delete mode 100644 test/integration/targets/win_unzip/aliases delete mode 100644 test/integration/targets/win_unzip/defaults/main.yml delete mode 100644 test/integration/targets/win_unzip/files/create_crafty_zip_files.py delete mode 100644 test/integration/targets/win_unzip/files/create_zip.py delete mode 100644 test/integration/targets/win_unzip/meta/main.yml delete mode 100644 test/integration/targets/win_unzip/tasks/main.yml delete mode 100644 test/integration/targets/win_user_profile/aliases delete mode 100644 test/integration/targets/win_user_profile/tasks/main.yml delete mode 100644 test/integration/targets/win_user_profile/tasks/tests.yml delete mode 100644 test/integration/targets/win_wait_for_process/aliases delete mode 100644 test/integration/targets/win_wait_for_process/tasks/main.yml delete mode 100644 test/integration/targets/win_wakeonlan/aliases delete mode 100644 test/integration/targets/win_wakeonlan/tasks/main.yml delete mode 100644 test/integration/targets/win_xml/aliases delete mode 100644 test/integration/targets/win_xml/files/books.xml delete mode 100644 test/integration/targets/win_xml/files/config.xml delete mode 100644 test/integration/targets/win_xml/files/log4j.xml delete mode 100644 test/integration/targets/win_xml/files/plane.zip delete mode 100644 test/integration/targets/win_xml/meta/main.yml delete mode 100644 test/integration/targets/win_xml/tasks/main.yml delete mode 100644 test/units/plugins/lookup/test_laps_password.py diff --git a/lib/ansible/modules/commands/psexec.py b/lib/ansible/modules/commands/psexec.py deleted file mode 100644 index 5751a642358..00000000000 --- a/lib/ansible/modules/commands/psexec.py +++ /dev/null @@ -1,520 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Jordan Borean -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -ANSIBLE_METADATA = { - 'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community' -} - - -DOCUMENTATION = r''' ---- -module: psexec -short_description: Runs commands on a remote Windows host based on the PsExec - model -version_added: "2.6" -description: -- Runs a remote command from a Linux host to a Windows host without WinRM being - set up. -- Can be run on the Ansible controller to bootstrap Windows hosts to get them - ready for WinRM. -options: - hostname: - description: - - The remote Windows host to connect to, can be either an IP address or a - hostname. - type: str - required: yes - connection_username: - description: - - The username to use when connecting to the remote Windows host. - - This user must be a member of the C(Administrators) group of the Windows - host. - - Required if the Kerberos requirements are not installed or the username - is a local account to the Windows host. - - Can be omitted to use the default Kerberos principal ticket in the - local credential cache if the Kerberos library is installed. - - If I(process_username) is not specified, then the remote process will run - under a Network Logon under this account. - type: str - connection_password: - description: - - The password for I(connection_user). - - Required if the Kerberos requirements are not installed or the username - is a local account to the Windows host. - - Can be omitted to use a Kerberos principal ticket for the principal set - by I(connection_user) if the Kerberos library is installed and the - ticket has already been retrieved with the C(kinit) command before. - type: str - port: - description: - - The port that the remote SMB service is listening on. - type: int - default: 445 - encrypt: - description: - - Will use SMB encryption to encrypt the SMB messages sent to and from the - host. - - This requires the SMB 3 protocol which is only supported from Windows - Server 2012 or Windows 8, older versions like Windows 7 or Windows Server - 2008 (R2) must set this to C(no) and use no encryption. - - When setting to C(no), the packets are in plaintext and can be seen by - anyone sniffing the network, any process options are included in this. - type: bool - default: yes - connection_timeout: - description: - - The timeout in seconds to wait when receiving the initial SMB negotiate - response from the server. - type: int - default: 60 - executable: - description: - - The executable to run on the Windows host. - type: str - required: yes - arguments: - description: - - Any arguments as a single string to use when running the executable. - type: str - working_directory: - description: - - Changes the working directory set when starting the process. - type: str - default: C:\Windows\System32 - asynchronous: - description: - - Will run the command as a detached process and the module returns - immediately after starting the process while the process continues to - run in the background. - - The I(stdout) and I(stderr) return values will be null when this is set - to C(yes). - - The I(stdin) option does not work with this type of process. - - The I(rc) return value is not set when this is C(yes) - type: bool - default: no - load_profile: - description: - - Runs the remote command with the user's profile loaded. - type: bool - default: yes - process_username: - description: - - The user to run the process as. - - This can be set to run the process under an Interactive logon of the - specified account which bypasses limitations of a Network logon used when - this isn't specified. - - If omitted then the process is run under the same account as - I(connection_username) with a Network logon. - - Set to C(System) to run as the builtin SYSTEM account, no password is - required with this account. - - If I(encrypt) is C(no), the username and password are sent as a simple - XOR scrambled byte string that is not encrypted. No special tools are - required to get the username and password just knowledge of the protocol. - type: str - process_password: - description: - - The password for I(process_username). - - Required if I(process_username) is defined and not C(System). - type: str - integrity_level: - description: - - The integrity level of the process when I(process_username) is defined - and is not equal to C(System). - - When C(default), the default integrity level based on the system setup. - - When C(elevated), the command will be run with Administrative rights. - - When C(limited), the command will be forced to run with - non-Administrative rights. - type: str - choices: - - limited - - default - - elevated - default: default - interactive: - description: - - Will run the process as an interactive process that shows a process - Window of the Windows session specified by I(interactive_session). - - The I(stdout) and I(stderr) return values will be null when this is set - to C(yes). - - The I(stdin) option does not work with this type of process. - type: bool - default: no - interactive_session: - description: - - The Windows session ID to use when displaying the interactive process on - the remote Windows host. - - This is only valid when I(interactive) is C(yes). - - The default is C(0) which is the console session of the Windows host. - type: int - default: 0 - priority: - description: - - Set the command's priority on the Windows host. - - See U(https://msdn.microsoft.com/en-us/library/windows/desktop/ms683211.aspx) - for more details. - type: str - choices: - - above_normal - - below_normal - - high - - idle - - normal - - realtime - default: normal - show_ui_on_logon_screen: - description: - - Shows the process UI on the Winlogon secure desktop when - I(process_username) is C(System). - type: bool - default: no - process_timeout: - description: - - The timeout in seconds that is placed upon the running process. - - A value of C(0) means no timeout. - type: int - default: 0 - stdin: - description: - - Data to send on the stdin pipe once the process has started. - - This option has no effect when I(interactive) or I(asynchronous) is - C(yes). - type: str -requirements: -- pypsexec -- smbprotocol[kerberos] for optional Kerberos authentication -notes: -- This module requires the Windows host to have SMB configured and enabled, - and port 445 opened on the firewall. -- This module will wait until the process is finished unless I(asynchronous) - is C(yes), ensure the process is run as a non-interactive command to avoid - infinite hangs waiting for input. -- The I(connection_username) must be a member of the local Administrator group - of the Windows host. For non-domain joined hosts, the - C(LocalAccountTokenFilterPolicy) should be set to C(1) to ensure this works, - see U(https://support.microsoft.com/en-us/help/951016/description-of-user-account-control-and-remote-restrictions-in-windows). -- For more information on this module and the various host requirements, see - U(https://github.com/jborean93/pypsexec). -seealso: -- module: raw -- module: win_command -- module: win_psexec -- module: win_shell -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Run a cmd.exe command - psexec: - hostname: server - connection_username: username - connection_password: password - executable: cmd.exe - arguments: /c echo Hello World - -- name: Run a PowerShell command - psexec: - hostname: server.domain.local - connection_username: username@DOMAIN.LOCAL - connection_password: password - executable: powershell.exe - arguments: Write-Host Hello World - -- name: Send data through stdin - psexec: - hostname: 192.168.1.2 - connection_username: username - connection_password: password - executable: powershell.exe - arguments: '-' - stdin: | - Write-Host Hello World - Write-Error Error Message - exit 0 - -- name: Run the process as a different user - psexec: - hostname: server - connection_user: username - connection_password: password - executable: whoami.exe - arguments: /all - process_username: anotheruser - process_password: anotherpassword - -- name: Run the process asynchronously - psexec: - hostname: server - connection_username: username - connection_password: password - executable: cmd.exe - arguments: /c rmdir C:\temp - asynchronous: yes - -- name: Use Kerberos authentication for the connection (requires smbprotocol[kerberos]) - psexec: - hostname: host.domain.local - connection_username: user@DOMAIN.LOCAL - executable: C:\some\path\to\executable.exe - arguments: /s - -- name: Disable encryption to work with WIndows 7/Server 2008 (R2) - psexec: - hostanme: windows-pc - connection_username: Administrator - connection_password: Password01 - encrypt: no - integrity_level: elevated - process_username: Administrator - process_password: Password01 - executable: powershell.exe - arguments: (New-Object -ComObject Microsoft.Update.Session).CreateUpdateInstaller().IsBusy - -- name: Download and run ConfigureRemotingForAnsible.ps1 to setup WinRM - psexec: - hostname: '{{ hostvars[inventory_hostname]["ansible_host"] | default(inventory_hostname) }}' - connection_username: '{{ ansible_user }}' - connection_password: '{{ ansible_password }}' - encrypt: yes - executable: powershell.exe - arguments: '-' - stdin: | - $ErrorActionPreference = "Stop" - $sec_protocols = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::SystemDefault - $sec_protocols = $sec_protocols -bor [Net.SecurityProtocolType]::Tls12 - [Net.ServicePointManager]::SecurityProtocol = $sec_protocols - $url = "https://github.com/ansible/ansible/raw/devel/examples/scripts/ConfigureRemotingForAnsible.ps1" - Invoke-Expression ((New-Object Net.WebClient).DownloadString($url)) - exit - delegate_to: localhost -''' - -RETURN = r''' -msg: - description: Any exception details when trying to run the process - returned: module failed - type: str - sample: 'Received exception from remote PAExec service: Failed to start "invalid.exe". The system cannot find the file specified. [Err=0x2, 2]' -stdout: - description: The stdout from the remote process - returned: success and interactive or asynchronous is 'no' - type: str - sample: Hello World -stderr: - description: The stderr from the remote process - returned: success and interactive or asynchronous is 'no' - type: str - sample: Error [10] running process -pid: - description: The process ID of the asynchronous process that was created - returned: success and asynchronous is 'yes' - type: int - sample: 719 -rc: - description: The return code of the remote process - returned: success and asynchronous is 'no' - type: int - sample: 0 -''' - -import traceback - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib -from ansible.module_utils._text import to_bytes, to_text - -PYPSEXEC_IMP_ERR = None -try: - from pypsexec import client - from pypsexec.exceptions import PypsexecException, PAExecException, \ - PDUException, SCMRException - from pypsexec.paexec import ProcessPriority - from smbprotocol.exceptions import SMBException, SMBAuthenticationError, \ - SMBResponseException - import socket - HAS_PYPSEXEC = True -except ImportError: - PYPSEXEC_IMP_ERR = traceback.format_exc() - HAS_PYPSEXEC = False - -KERBEROS_IMP_ERR = None -try: - import gssapi - # GSSAPI extension required for Kerberos Auth in SMB - from gssapi.raw import inquire_sec_context_by_oid - HAS_KERBEROS = True -except ImportError: - KERBEROS_IMP_ERR = traceback.format_exc() - HAS_KERBEROS = False - - -def remove_artifacts(module, client): - try: - client.remove_service() - except (SMBException, PypsexecException) as exc: - module.warn("Failed to cleanup PAExec service and executable: %s" - % to_text(exc)) - - -def main(): - module_args = dict( - hostname=dict(type='str', required=True), - connection_username=dict(type='str'), - connection_password=dict(type='str', no_log=True), - port=dict(type='int', required=False, default=445), - encrypt=dict(type='bool', default=True), - connection_timeout=dict(type='int', default=60), - executable=dict(type='str', required=True), - arguments=dict(type='str'), - working_directory=dict(type='str', default=r'C:\Windows\System32'), - asynchronous=dict(type='bool', default=False), - load_profile=dict(type='bool', default=True), - process_username=dict(type='str'), - process_password=dict(type='str', no_log=True), - integrity_level=dict(type='str', default='default', - choices=['default', 'elevated', 'limited']), - interactive=dict(type='bool', default=False), - interactive_session=dict(type='int', default=0), - priority=dict(type='str', default='normal', - choices=['above_normal', 'below_normal', 'high', - 'idle', 'normal', 'realtime']), - show_ui_on_logon_screen=dict(type='bool', default=False), - process_timeout=dict(type='int', default=0), - stdin=dict(type='str') - ) - result = dict( - changed=False, - ) - module = AnsibleModule( - argument_spec=module_args, - supports_check_mode=False, - ) - - process_username = module.params['process_username'] - process_password = module.params['process_password'] - use_system = False - if process_username is not None and process_username.lower() == "system": - use_system = True - process_username = None - process_password = None - - if process_username is not None and process_password is None: - module.fail_json(msg='parameters are required together when not ' - 'running as System: process_username, ' - 'process_password') - if not HAS_PYPSEXEC: - module.fail_json(msg=missing_required_lib("pypsexec"), - exception=PYPSEXEC_IMP_ERR) - - hostname = module.params['hostname'] - connection_username = module.params['connection_username'] - connection_password = module.params['connection_password'] - port = module.params['port'] - encrypt = module.params['encrypt'] - connection_timeout = module.params['connection_timeout'] - executable = module.params['executable'] - arguments = module.params['arguments'] - working_directory = module.params['working_directory'] - asynchronous = module.params['asynchronous'] - load_profile = module.params['load_profile'] - elevated = module.params['integrity_level'] == "elevated" - limited = module.params['integrity_level'] == "limited" - interactive = module.params['interactive'] - interactive_session = module.params['interactive_session'] - - priority = { - "above_normal": ProcessPriority.ABOVE_NORMAL_PRIORITY_CLASS, - "below_normal": ProcessPriority.BELOW_NORMAL_PRIORITY_CLASS, - "high": ProcessPriority.HIGH_PRIORITY_CLASS, - "idle": ProcessPriority.IDLE_PRIORITY_CLASS, - "normal": ProcessPriority.NORMAL_PRIORITY_CLASS, - "realtime": ProcessPriority.REALTIME_PRIORITY_CLASS - }[module.params['priority']] - show_ui_on_logon_screen = module.params['show_ui_on_logon_screen'] - - process_timeout = module.params['process_timeout'] - stdin = module.params['stdin'] - - if (connection_username is None or connection_password is None) and \ - not HAS_KERBEROS: - module.fail_json(msg=missing_required_lib("gssapi"), - execption=KERBEROS_IMP_ERR) - - win_client = client.Client(server=hostname, username=connection_username, - password=connection_password, port=port, - encrypt=encrypt) - - try: - win_client.connect(timeout=connection_timeout) - except SMBAuthenticationError as exc: - module.fail_json(msg='Failed to authenticate over SMB: %s' - % to_text(exc)) - except SMBResponseException as exc: - module.fail_json(msg='Received unexpected SMB response when opening ' - 'the connection: %s' % to_text(exc)) - except PDUException as exc: - module.fail_json(msg='Received an exception with RPC PDU message: %s' - % to_text(exc)) - except SCMRException as exc: - module.fail_json(msg='Received an exception when dealing with SCMR on ' - 'the Windows host: %s' % to_text(exc)) - except (SMBException, PypsexecException) as exc: - module.fail_json(msg=to_text(exc)) - except socket.error as exc: - module.fail_json(msg=to_text(exc)) - - # create PAExec service and run the process - result['changed'] = True - b_stdin = to_bytes(stdin, encoding='utf-8') if stdin else None - run_args = dict( - executable=executable, arguments=arguments, asynchronous=asynchronous, - load_profile=load_profile, interactive=interactive, - interactive_session=interactive_session, - run_elevated=elevated, run_limited=limited, - username=process_username, password=process_password, - use_system_account=use_system, working_dir=working_directory, - priority=priority, show_ui_on_win_logon=show_ui_on_logon_screen, - timeout_seconds=process_timeout, stdin=b_stdin - ) - try: - win_client.create_service() - except (SMBException, PypsexecException) as exc: - module.fail_json(msg='Failed to create PAExec service: %s' - % to_text(exc)) - - try: - proc_result = win_client.run_executable(**run_args) - except (SMBException, PypsexecException) as exc: - module.fail_json(msg='Received error when running remote process: %s' - % to_text(exc)) - finally: - remove_artifacts(module, win_client) - - if asynchronous: - result['pid'] = proc_result[2] - elif interactive: - result['rc'] = proc_result[2] - else: - result['stdout'] = proc_result[0] - result['stderr'] = proc_result[1] - result['rc'] = proc_result[2] - - # close the SMB connection - try: - win_client.disconnect() - except (SMBException, PypsexecException) as exc: - module.warn("Failed to close the SMB connection: %s" % to_text(exc)) - - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/windows/win_audit_policy_system.ps1 b/lib/ansible/modules/windows/win_audit_policy_system.ps1 deleted file mode 100644 index f21e63e7796..00000000000 --- a/lib/ansible/modules/windows/win_audit_policy_system.ps1 +++ /dev/null @@ -1,143 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Noah Sparks -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.CommandUtil - -$ErrorActionPreference = 'Stop' - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$results = @{ - changed = $false -} - -###################################### -### populate sets for -validateset ### -###################################### -$categories_rc = run-command -command 'auditpol /list /category /r' -$subcategories_rc = run-command -command 'auditpol /list /subcategory:* /r' - -If ($categories_rc.item('rc') -eq 0) -{ - $categories = ConvertFrom-Csv $categories_rc.item('stdout') | Select-Object -expand Category* -} -Else -{ - Fail-Json -obj $results -message "Failed to retrive audit policy categories. Please make sure the auditpol command is functional on - the system and that the account ansible is running under is able to retrieve them. $($_.Exception.Message)" -} - -If ($subcategories_rc.item('rc') -eq 0) -{ - $subcategories = ConvertFrom-Csv $subcategories_rc.item('stdout') | Select-Object -expand Category* | - Where-Object {$_ -notin $categories} -} -Else -{ - Fail-Json -obj $results -message "Failed to retrive audit policy subcategories. Please make sure the auditpol command is functional on - the system and that the account ansible is running under is able to retrieve them. $($_.Exception.Message)" -} - -###################### -### ansible params ### -###################### -$category = Get-AnsibleParam -obj $params -name "category" -type "str" -ValidateSet $categories -$subcategory = Get-AnsibleParam -obj $params -name "subcategory" -type "str" -ValidateSet $subcategories -$audit_type = Get-AnsibleParam -obj $params -name "audit_type" -type "list" -failifempty - - -######################## -### Start Processing ### -######################## -Function Get-AuditPolicy ($GetString) { - $auditpolcsv = Run-Command -command $GetString - If ($auditpolcsv.item('rc') -eq 0) - { - $Obj = ConvertFrom-CSV $auditpolcsv.item('stdout') | Select-Object @{n='subcategory';e={$_.Subcategory.ToLower()}}, - @{n='audit_type';e={$_."Inclusion Setting".ToLower()}} - } - Else { - return $auditpolcsv.item('stderr') - } - - $HT = @{} - Foreach ( $Item in $Obj ) - { - $HT.Add($Item.subcategory,$Item.audit_type) - } - $HT -} - -################ -### Validate ### -################ - -#make sure category and subcategory are valid -If (-Not $category -and -Not $subcategory) {Fail-Json -obj $results -message "You must provide either a Category or Subcategory parameter"} -If ($category -and $subcategory) {Fail-Json -obj $results -message "Must pick either a specific subcategory or category. You cannot define both"} - - -$possible_audit_types = 'success','failure','none' -$audit_type | ForEach-Object { - If ($_ -notin $possible_audit_types) - { - Fail-Json -obj $result -message "$_ is not a valid audit_type. Please choose from $($possible_audit_types -join ',')" - } -} - -############################################################# -### build lists for setting, getting, and comparing rules ### -############################################################# -$audit_type_string = $audit_type -join ' and ' - -$SetString = 'auditpol /set' -$GetString = 'auditpol /get /r' - -If ($category) {$SetString = "$SetString /category:`"$category`""; $GetString = "$GetString /category:`"$category`""} -If ($subcategory) {$SetString= "$SetString /subcategory:`"$subcategory`""; $GetString = "$GetString /subcategory:`"$subcategory`""} - - -Switch ($audit_type_string) -{ - 'success and failure' {$SetString = "$SetString /success:enable /failure:enable"; $audit_type_check = $audit_type_string} - 'failure' {$SetString = "$SetString /success:disable /failure:enable"; $audit_type_check = $audit_type_string} - 'success' {$SetString = "$SetString /success:enable /failure:disable"; $audit_type_check = $audit_type_string} - 'none' {$SetString = "$SetString /success:disable /failure:disable"; $audit_type_check = 'No Auditing'} - default {Fail-Json -obj $result -message "It seems you have specified an invalid combination of items for audit_type. Please review documentation"} -} - -######################### -### check Idempotence ### -######################### - -$CurrentRule = Get-AuditPolicy $GetString - -#exit if the audit_type is already set properly for the category -If (-not ($CurrentRule.Values | Where-Object {$_ -ne $audit_type_check}) ) -{ - $results.current_audit_policy = Get-AuditPolicy $GetString - Exit-Json -obj $results -} - -#################### -### Apply Change ### -#################### - -If (-not $check_mode) -{ - $ApplyPolicy = Run-Command -command $SetString - - If ($ApplyPolicy.Item('rc') -ne 0) - { - $results.current_audit_policy = Get-AuditPolicy $GetString - Fail-Json $results "Failed to set audit policy - $($_.Exception.Message)" - } -} - -$results.changed = $true -$results.current_audit_policy = Get-AuditPolicy $GetString -Exit-Json $results diff --git a/lib/ansible/modules/windows/win_audit_policy_system.py b/lib/ansible/modules/windows/win_audit_policy_system.py deleted file mode 100644 index bbcff6aad71..00000000000 --- a/lib/ansible/modules/windows/win_audit_policy_system.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Noah Sparks -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_audit_policy_system -short_description: Used to make changes to the system wide Audit Policy -description: - - Used to make changes to the system wide Audit Policy. -version_added: "2.5" -options: - category: - description: - - Single string value for the category you would like to adjust the policy on. - - Cannot be used with I(subcategory). You must define one or the other. - - Changing this setting causes all subcategories to be adjusted to the defined I(audit_type). - type: str - subcategory: - description: - - Single string value for the subcategory you would like to adjust the policy on. - - Cannot be used with I(category). You must define one or the other. - type: str - audit_type: - description: - - The type of event you would like to audit for. - - Accepts a list. See examples. - type: list - required: yes - choices: [ failure, none, success ] -notes: - - It is recommended to take a backup of the policies before adjusting them for the first time. - - See this page for in depth information U(https://technet.microsoft.com/en-us/library/cc766468.aspx). -seealso: -- module: win_audit_rule -author: - - Noah Sparks (@nwsparks) -''' - -EXAMPLES = r''' -- name: Enable failure auditing for the subcategory "File System" - win_audit_policy_system: - subcategory: File System - audit_type: failure - -- name: Enable all auditing types for the category "Account logon events" - win_audit_policy_system: - category: Account logon events - audit_type: success, failure - -- name: Disable auditing for the subcategory "File System" - win_audit_policy_system: - subcategory: File System - audit_type: none -''' - -RETURN = r''' -current_audit_policy: - description: details on the policy being targetted - returned: always - type: dict - sample: |- - { - "File Share":"failure" - } -''' diff --git a/lib/ansible/modules/windows/win_audit_rule.ps1 b/lib/ansible/modules/windows/win_audit_rule.ps1 deleted file mode 100644 index 0d3ebf57b38..00000000000 --- a/lib/ansible/modules/windows/win_audit_rule.ps1 +++ /dev/null @@ -1,193 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Noah Sparks -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.SID - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -# module parameters -$path = Get-AnsibleParam -obj $params -name "path" -type "path" -failifempty $true -aliases "destination","dest" -$user = Get-AnsibleParam -obj $params -name "user" -type "str" -failifempty $true -$rights = Get-AnsibleParam -obj $params -name "rights" -type "list" -$inheritance_flags = Get-AnsibleParam -obj $params -name "inheritance_flags" -type "list" -default 'ContainerInherit','ObjectInherit' -$propagation_flags = Get-AnsibleParam -obj $params -name "propagation_flags" -type "str" -default "none" -ValidateSet 'InheritOnly','None','NoPropagateInherit' -$audit_flags = Get-AnsibleParam -obj $params -name "audit_flags" -type "list" -default 'success' -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset 'present','absent' - -#Make sure target path is valid -If (-not (Test-Path -Path $path) ) -{ - Fail-Json -obj $result -message "defined path ($path) is not found/invalid" -} - -#function get current audit rules and convert to hashtable -Function Get-CurrentAuditRules ($path) { - Try { - $ACL = Get-Acl $path -Audit - } - Catch { - Return "Unable to retrieve the ACL on $Path" - } - - $HT = Foreach ($Obj in $ACL.Audit) - { - @{ - user = $Obj.IdentityReference.ToString() - rights = ($Obj | Select-Object -expand "*rights").ToString() - audit_flags = $Obj.AuditFlags.ToString() - is_inherited = $Obj.IsInherited.ToString() - inheritance_flags = $Obj.InheritanceFlags.ToString() - propagation_flags = $Obj.PropagationFlags.ToString() - } - } - - If (-Not $HT) - { - "No audit rules defined on $path" - } - Else {$HT} -} - -$result = @{ - changed = $false - current_audit_rules = Get-CurrentAuditRules $path -} - -#Make sure identity is valid and can be looked up -Try { - $SID = Convert-ToSid $user -} -Catch { - Fail-Json -obj $result -message "Failed to lookup the identity ($user) - $($_.exception.message)" -} - -#get the path type -$ItemType = (Get-Item $path).GetType() -switch ($ItemType) -{ - ([Microsoft.Win32.RegistryKey]) {$registry = $true; $result.path_type = 'registry'} - ([System.IO.FileInfo]) {$file = $true; $result.path_type = 'file'} - ([System.IO.DirectoryInfo]) {$result.path_type = 'directory'} -} - -#Get current acl/audit rules on the target -Try { - $ACL = Get-Acl $path -Audit -} -Catch { - Fail-Json -obj $result -message "Unable to retrieve the ACL on $Path - $($_.Exception.Message)" -} - -#configure acl object to remove the specified user -If ($state -eq 'absent') -{ - #Try and find an identity on the object that matches user - #We skip inherited items since we can't remove those - $ToRemove = ($ACL.Audit | Where-Object {$_.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]) -eq $SID -and - $_.IsInherited -eq $false}).IdentityReference - - #Exit with changed false if no identity is found - If (-Not $ToRemove) - { - $result.current_audit_rules = Get-CurrentAuditRules $path - Exit-Json -obj $result - } - - #update the ACL object if identity found - Try - { - $ToRemove | ForEach-Object { $ACL.PurgeAuditRules($_) } - } - Catch - { - $result.current_audit_rules = Get-CurrentAuditRules $path - Fail-Json -obj $result -message "Failed to remove audit rule: $($_.Exception.Message)" - } -} - -Else -{ - If ($registry) - { - $PossibleRights = [System.Enum]::GetNames([System.Security.AccessControl.RegistryRights]) - - Foreach ($right in $rights) - { - if ($right -notin $PossibleRights) - { - Fail-Json -obj $result -message "$right does not seem to be a valid REGISTRY right" - } - } - - $NewAccessRule = New-Object System.Security.AccessControl.RegistryAuditRule($user,$rights,$inheritance_flags,$propagation_flags,$audit_flags) - } - Else - { - $PossibleRights = [System.Enum]::GetNames([System.Security.AccessControl.FileSystemRights]) - - Foreach ($right in $rights) - { - if ($right -notin $PossibleRights) - { - Fail-Json -obj $result -message "$right does not seem to be a valid FILE SYSTEM right" - } - } - - If ($file -and $inheritance_flags -ne 'none') - { - Fail-Json -obj $result -message "The target type is a file. inheritance_flags must be changed to 'none'" - } - - $NewAccessRule = New-Object System.Security.AccessControl.FileSystemAuditRule($user,$rights,$inheritance_flags,$propagation_flags,$audit_flags) - } - - #exit here if any existing rule matches defined rule since no change is needed - #if we need to ignore inherited rules in the future, this would be where to do it - #Just filter out inherited rules from $ACL.Audit - Foreach ($group in $ACL.Audit | Where-Object {$_.IsInherited -eq $false}) - { - If ( - ($group | Select-Object -expand "*Rights") -eq ($NewAccessRule | Select-Object -expand "*Rights") -and - $group.AuditFlags -eq $NewAccessRule.AuditFlags -and - $group.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]) -eq $SID -and - $group.InheritanceFlags -eq $NewAccessRule.InheritanceFlags -and - $group.PropagationFlags -eq $NewAccessRule.PropagationFlags - ) - { - $result.current_audit_rules = Get-CurrentAuditRules $path - Exit-Json -obj $result - } - } - - #try and set the acl object. AddAuditRule allows for multiple entries to exist under the same - #identity...so if someone wanted success: write and failure: delete for example, that setup would be - #possible. The alternative is SetAuditRule which would instead modify an existing rule and not allow - #for setting the above example. - Try - { - $ACL.AddAuditRule($NewAccessRule) - } - Catch - { - Fail-Json -obj $result -message "Failed to set the audit rule: $($_.Exception.Message)" - } -} - - -#finally set the permissions -Try { - Set-Acl -Path $path -ACLObject $ACL -WhatIf:$check_mode -} -Catch { - $result.current_audit_rules = Get-CurrentAuditRules $path - Fail-Json -obj $result -message "Failed to apply audit change: $($_.Exception.Message)" -} - -#exit here after a change is applied -$result.current_audit_rules = Get-CurrentAuditRules $path -$result.changed = $true -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_audit_rule.py b/lib/ansible/modules/windows/win_audit_rule.py deleted file mode 100644 index d5687c120eb..00000000000 --- a/lib/ansible/modules/windows/win_audit_rule.py +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Noah Sparks -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_audit_rule -short_description: Adds an audit rule to files, folders, or registry keys -description: - - Used to apply audit rules to files, folders or registry keys. - - Once applied, it will begin recording the user who performed the operation defined into the Security - Log in the Event viewer. - - The behavior is designed to ignore inherited rules since those cannot be adjusted without first disabling - the inheritance behavior. It will still print inherited rules in the output though for debugging purposes. -version_added: "2.5" -options: - path: - description: - - Path to the file, folder, or registry key. - - Registry paths should be in Powershell format, beginning with an abbreviation for the root - such as, C(HKLM:\Software). - type: path - required: yes - aliases: [ dest, destination ] - user: - description: - - The user or group to adjust rules for. - type: str - required: yes - rights: - description: - - Comma separated list of the rights desired. Only required for adding a rule. - - If I(path) is a file or directory, rights can be any right under MSDN - FileSystemRights U(https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.filesystemrights.aspx). - - If I(path) is a registry key, rights can be any right under MSDN - RegistryRights U(https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.registryrights.aspx). - type: list - required: yes - inheritance_flags: - description: - - Defines what objects inside of a folder or registry key will inherit the settings. - - If you are setting a rule on a file, this value has to be changed to C(none). - - For more information on the choices see MSDN PropagationFlags enumeration - at U(https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.inheritanceflags.aspx). - type: list - choices: [ ContainerInherit, ObjectInherit ] - default: ContainerInherit,ObjectInherit - propagation_flags: - description: - - Propagation flag on the audit rules. - - This value is ignored when the path type is a file. - - For more information on the choices see MSDN PropagationFlags enumeration - at U(https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.propagationflags.aspx). - choices: [ None, InherityOnly, NoPropagateInherit ] - default: "None" - audit_flags: - description: - - Defines whether to log on failure, success, or both. - - To log both define as comma separated list "Success, Failure". - type: list - required: yes - choices: [ Failure, Success ] - state: - description: - - Whether the rule should be C(present) or C(absent). - - For absent, only I(path), I(user), and I(state) are required. - - Specifying C(absent) will remove all rules matching the defined I(user). - type: str - choices: [ absent, present ] - default: present -seealso: -- module: win_audit_policy_system -author: - - Noah Sparks (@nwsparks) -''' - -EXAMPLES = r''' -- name: Add filesystem audit rule for a folder - win_audit_rule: - path: C:\inetpub\wwwroot\website - user: BUILTIN\Users - rights: write,delete,changepermissions - audit_flags: success,failure - inheritance_flags: ContainerInherit,ObjectInherit - -- name: Add filesystem audit rule for a file - win_audit_rule: - path: C:\inetpub\wwwroot\website\web.config - user: BUILTIN\Users - rights: write,delete,changepermissions - audit_flags: success,failure - inheritance_flags: None - -- name: Add registry audit rule - win_audit_rule: - path: HKLM:\software - user: BUILTIN\Users - rights: delete - audit_flags: 'success' - -- name: Remove filesystem audit rule - win_audit_rule: - path: C:\inetpub\wwwroot\website - user: BUILTIN\Users - state: absent - -- name: Remove registry audit rule - win_audit_rule: - path: HKLM:\software - user: BUILTIN\Users - state: absent -''' - -RETURN = r''' -current_audit_rules: - description: - - The current rules on the defined I(path) - - Will return "No audit rules defined on I(path)" - returned: always - type: dict - sample: | - { - "audit_flags": "Success", - "user": "Everyone", - "inheritance_flags": "False", - "is_inherited": "False", - "propagation_flags": "None", - "rights": "Delete" - } -path_type: - description: - - The type of I(path) being targetted. - - Will be one of file, directory, registry. - returned: always - type: str -''' diff --git a/lib/ansible/modules/windows/win_auto_logon.ps1 b/lib/ansible/modules/windows/win_auto_logon.ps1 deleted file mode 100644 index 61b0d67f5a7..00000000000 --- a/lib/ansible/modules/windows/win_auto_logon.ps1 +++ /dev/null @@ -1,403 +0,0 @@ -#!powershell - -# Copyright: (c) 2019, Prasoon Karunan V (@prasoonkarunan) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# All helper methods are written in a binary module and has to be loaded for consuming them. -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.AddType - -Set-StrictMode -Version 2.0 - -$spec = @{ - options = @{ - logon_count = @{type = "int"} - password = @{type = "str"; no_log = $true} - state = @{type = "str"; choices = "absent", "present"; default = "present"} - username = @{type = "str"} - } - required_if = @( - ,@("state", "present", @("username", "password")) - ) - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$logonCount = $module.Params.logon_count -$password = $module.Params.password -$state = $module.Params.state -$username = $module.Params.username -$domain = $null - -if ($username) { - # Try and get the Netlogon form of the username specified. Translating to and from a SID gives us an NTAccount - # in the Netlogon form that we desire. - $ntAccount = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $username - try { - $accountSid = $ntAccount.Translate([System.Security.Principal.SecurityIdentifier]) - } catch [System.Security.Principal.IdentityNotMappedException] { - $module.FailJson("Failed to find a local or domain user with the name '$username'", $_) - } - $ntAccount = $accountSid.Translate([System.Security.Principal.NTAccount]) - - $domain, $username = $ntAccount.Value -split '\\' -} - -# Make sure $null regardless of any input value if state: absent -if ($state -eq 'absent') { - $password = $null -} - -Add-CSharpType -AnsibleModule $module -References @' -using Microsoft.Win32.SafeHandles; -using System; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; -using System.Text; - -namespace Ansible.WinAutoLogon -{ - internal class NativeHelpers - { - [StructLayout(LayoutKind.Sequential)] - public class LSA_OBJECT_ATTRIBUTES - { - public UInt32 Length = 0; - public IntPtr RootDirectory = IntPtr.Zero; - public IntPtr ObjectName = IntPtr.Zero; - public UInt32 Attributes = 0; - public IntPtr SecurityDescriptor = IntPtr.Zero; - public IntPtr SecurityQualityOfService = IntPtr.Zero; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct LSA_UNICODE_STRING - { - public UInt16 Length; - public UInt16 MaximumLength; - public IntPtr Buffer; - - public static explicit operator string(LSA_UNICODE_STRING s) - { - byte[] strBytes = new byte[s.Length]; - Marshal.Copy(s.Buffer, strBytes, 0, s.Length); - return Encoding.Unicode.GetString(strBytes); - } - - public static SafeMemoryBuffer CreateSafeBuffer(string s) - { - if (s == null) - return new SafeMemoryBuffer(IntPtr.Zero); - - byte[] stringBytes = Encoding.Unicode.GetBytes(s); - int structSize = Marshal.SizeOf(typeof(LSA_UNICODE_STRING)); - IntPtr buffer = Marshal.AllocHGlobal(structSize + stringBytes.Length); - try - { - LSA_UNICODE_STRING lsaString = new LSA_UNICODE_STRING() - { - Length = (UInt16)(stringBytes.Length), - MaximumLength = (UInt16)(stringBytes.Length), - Buffer = IntPtr.Add(buffer, structSize), - }; - Marshal.StructureToPtr(lsaString, buffer, false); - Marshal.Copy(stringBytes, 0, lsaString.Buffer, stringBytes.Length); - return new SafeMemoryBuffer(buffer); - } - catch - { - // Make sure we free the pointer before raising the exception. - Marshal.FreeHGlobal(buffer); - throw; - } - } - } - } - - internal class NativeMethods - { - [DllImport("Advapi32.dll")] - public static extern UInt32 LsaClose( - IntPtr ObjectHandle); - - [DllImport("Advapi32.dll")] - public static extern UInt32 LsaFreeMemory( - IntPtr Buffer); - - [DllImport("Advapi32.dll")] - internal static extern Int32 LsaNtStatusToWinError( - UInt32 Status); - - [DllImport("Advapi32.dll")] - public static extern UInt32 LsaOpenPolicy( - IntPtr SystemName, - NativeHelpers.LSA_OBJECT_ATTRIBUTES ObjectAttributes, - LsaPolicyAccessMask AccessMask, - out SafeLsaHandle PolicyHandle); - - [DllImport("Advapi32.dll")] - public static extern UInt32 LsaRetrievePrivateData( - SafeLsaHandle PolicyHandle, - SafeMemoryBuffer KeyName, - out SafeLsaMemory PrivateData); - - [DllImport("Advapi32.dll")] - public static extern UInt32 LsaStorePrivateData( - SafeLsaHandle PolicyHandle, - SafeMemoryBuffer KeyName, - SafeMemoryBuffer PrivateData); - } - - internal class SafeLsaMemory : SafeBuffer - { - internal SafeLsaMemory() : base(true) { } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - - protected override bool ReleaseHandle() - { - return NativeMethods.LsaFreeMemory(handle) == 0; - } - } - - internal class SafeMemoryBuffer : SafeBuffer - { - internal SafeMemoryBuffer() : base(true) { } - - internal SafeMemoryBuffer(IntPtr ptr) : base(true) - { - base.SetHandle(ptr); - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - - protected override bool ReleaseHandle() - { - if (handle != IntPtr.Zero) - Marshal.FreeHGlobal(handle); - return true; - } - } - - public class SafeLsaHandle : SafeHandleZeroOrMinusOneIsInvalid - { - internal SafeLsaHandle() : base(true) { } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - - protected override bool ReleaseHandle() - { - return NativeMethods.LsaClose(handle) == 0; - } - } - - public class Win32Exception : System.ComponentModel.Win32Exception - { - private string _exception_msg; - public Win32Exception(string message) : this(Marshal.GetLastWin32Error(), message) { } - public Win32Exception(int errorCode, string message) : base(errorCode) - { - _exception_msg = String.Format("{0} - {1} (Win32 Error Code {2}: 0x{3})", message, base.Message, errorCode, errorCode.ToString("X8")); - } - public override string Message { get { return _exception_msg; } } - public static explicit operator Win32Exception(string message) { return new Win32Exception(message); } - } - - [Flags] - public enum LsaPolicyAccessMask : uint - { - ViewLocalInformation = 0x00000001, - ViewAuditInformation = 0x00000002, - GetPrivateInformation = 0x00000004, - TrustAdmin = 0x00000008, - CreateAccount = 0x00000010, - CreateSecret = 0x00000020, - CreatePrivilege = 0x00000040, - SetDefaultQuotaLimits = 0x00000080, - SetAuditRequirements = 0x00000100, - AuditLogAdmin = 0x00000200, - ServerAdmin = 0x00000400, - LookupNames = 0x00000800, - Read = 0x00020006, - Write = 0x000207F8, - Execute = 0x00020801, - AllAccess = 0x000F0FFF, - } - - public class LsaUtil - { - public static SafeLsaHandle OpenPolicy(LsaPolicyAccessMask access) - { - NativeHelpers.LSA_OBJECT_ATTRIBUTES oa = new NativeHelpers.LSA_OBJECT_ATTRIBUTES(); - SafeLsaHandle lsaHandle; - UInt32 res = NativeMethods.LsaOpenPolicy(IntPtr.Zero, oa, access, out lsaHandle); - if (res != 0) - throw new Win32Exception(NativeMethods.LsaNtStatusToWinError(res), - String.Format("LsaOpenPolicy({0}) failed", access.ToString())); - return lsaHandle; - } - - public static string RetrievePrivateData(SafeLsaHandle handle, string key) - { - using (SafeMemoryBuffer keyBuffer = NativeHelpers.LSA_UNICODE_STRING.CreateSafeBuffer(key)) - { - SafeLsaMemory buffer; - UInt32 res = NativeMethods.LsaRetrievePrivateData(handle, keyBuffer, out buffer); - using (buffer) - { - if (res != 0) - { - // If the data object was not found we return null to indicate it isn't set. - if (res == 0xC0000034) // STATUS_OBJECT_NAME_NOT_FOUND - return null; - - throw new Win32Exception(NativeMethods.LsaNtStatusToWinError(res), - String.Format("LsaRetrievePrivateData({0}) failed", key)); - } - - NativeHelpers.LSA_UNICODE_STRING lsaString = (NativeHelpers.LSA_UNICODE_STRING) - Marshal.PtrToStructure(buffer.DangerousGetHandle(), - typeof(NativeHelpers.LSA_UNICODE_STRING)); - return (string)lsaString; - } - } - } - - public static void StorePrivateData(SafeLsaHandle handle, string key, string data) - { - using (SafeMemoryBuffer keyBuffer = NativeHelpers.LSA_UNICODE_STRING.CreateSafeBuffer(key)) - using (SafeMemoryBuffer dataBuffer = NativeHelpers.LSA_UNICODE_STRING.CreateSafeBuffer(data)) - { - UInt32 res = NativeMethods.LsaStorePrivateData(handle, keyBuffer, dataBuffer); - if (res != 0) - { - // When clearing the private data with null it may return this error which we can ignore. - if (data == null && res == 0xC0000034) // STATUS_OBJECT_NAME_NOT_FOUND - return; - - throw new Win32Exception(NativeMethods.LsaNtStatusToWinError(res), - String.Format("LsaStorePrivateData({0}) failed", key)); - } - } - } - } -} -'@ - -$autoLogonRegPath = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -$logonDetails = Get-ItemProperty -LiteralPath $autoLogonRegPath - -$before = @{ - state = 'absent' -} -if ('AutoAdminLogon' -in $logonDetails.PSObject.Properties.Name -and $logonDetails.AutoAdminLogon -eq 1) { - $before.state = 'present' -} - -$mapping = @{ - DefaultUserName = 'username' - DefaultDomainName = 'domain' - AutoLogonCount = 'logon_count' -} -foreach ($map_detail in $mapping.GetEnumerator()) { - if ($map_detail.Key -in $logonDetails.PSObject.Properties.Name) { - $before."$($map_detail.Value)" = $logonDetails."$($map_detail.Key)" - } -} - -$module.Diff.before = $before - -$propParams = @{ - LiteralPath = $autoLogonRegPath - WhatIf = $module.CheckMode - Force = $true -} - -# First set the registry information -# The DefaultPassword reg key should never be set, we use LSA to store the password in a more secure way. -if ('DefaultPassword' -in (Get-Item -LiteralPath $autoLogonRegPath).Property) { - # Bug on older Windows hosts where -WhatIf causes it fail to find the property - if (-not $module.CheckMode) { - Remove-ItemProperty -Name 'DefaultPassword' @propParams - } - $module.Result.changed = $true -} - -$autoLogonKeyList = @{ - DefaultUserName = @{ - before = if ($before.ContainsKey('username')) { $before.username } else { $null } - after = $username - } - DefaultDomainName = @{ - before = if ($before.ContainsKey('domain')) { $before.domain } else { $null } - after = $domain - } - AutoLogonCount = @{ - before = if ($before.ContainsKey('logon_count')) { $before.logon_count } else { $null } - after = $logonCount - } -} - -# Check AutoAdminLogon separately as it has different logic (key must exist) -if ($state -ne $before.state) { - $newValue = if ($state -eq 'present') { 1 } else { 0 } - $null = New-ItemProperty -Name 'AutoAdminLogon' -Value $newValue -PropertyType DWord @propParams - $module.Result.changed = $true -} - -foreach ($key in $autoLogonKeyList.GetEnumerator()) { - $beforeVal = $key.Value.before - $after = $key.Value.after - - if ($state -eq 'present' -and $beforeVal -cne $after) { - if ($null -ne $after) { - $null = New-ItemProperty -Name $key.Key -Value $after @propParams - } - elseif (-not $module.CheckMode) { - Remove-ItemProperty -Name $key.Key @propParams - } - $module.Result.changed = $true - } - elseif ($state -eq 'absent' -and $null -ne $beforeVal) { - if (-not $module.CheckMode) { - Remove-ItemProperty -Name $key.Key @propParams - } - $module.Result.changed = $true - } -} - -# Finally update the password in the LSA private store. -$lsaHandle = [Ansible.WinAutoLogon.LsaUtil]::OpenPolicy('CreateSecret, GetPrivateInformation') -try { - $beforePass = [Ansible.WinAutoLogon.LsaUtil]::RetrievePrivateData($lsaHandle, 'DefaultPassword') - - if ($beforePass -cne $password) { - # Due to .NET marshaling we need to pass in $null as NullString.Value so it's truly a null value. - if ($null -eq $password) { - $password = [NullString]::Value - } - if (-not $module.CheckMode) { - [Ansible.WinAutoLogon.LsaUtil]::StorePrivateData($lsaHandle, 'DefaultPassword', $password) - } - $module.Result.changed = $true - } -} -finally { - $lsaHandle.Dispose() -} - -# Need to manually craft the after diff in case we are running in check mode -$module.Diff.after = @{ - state = $state -} -if ($state -eq 'present') { - $module.Diff.after.username = $username - $module.Diff.after.domain = $domain - if ($null -ne $logonCount) { - $module.Diff.after.logon_count = $logonCount - } -} - -$module.ExitJson() - diff --git a/lib/ansible/modules/windows/win_auto_logon.py b/lib/ansible/modules/windows/win_auto_logon.py deleted file mode 100644 index c869361df92..00000000000 --- a/lib/ansible/modules/windows/win_auto_logon.py +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2019, Prasoon Karunan V (@prasoonkarunan) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_auto_logon -short_description: Adds or Sets auto logon registry keys. -description: - - Used to apply auto logon registry setting. -version_added: "2.10" -options: - logon_count: - description: - - The number of times to do an automatic logon. - - This count is deremented by Windows everytime an automatic logon is - performed. - - Once the count reaches C(0) then the automatic logon process is - disabled. - type: int - username: - description: - - Username to login automatically. - - Must be set when C(state=present). - - This can be the Netlogon or UPN of a domain account and is - automatically parsed to the C(DefaultUserName) and C(DefaultDomainName) - registry properties. - type: str - password: - description: - - Password to be used for automatic login. - - Must be set when C(state=present). - - Value of this input will be used as password for I(username). - - While this value is encrypted by LSA it is decryptable to any user who - is an Administrator on the remote host. - type: str - state: - description: - - Whether the registry key should be C(present) or C(absent). - type: str - choices: [ absent, present ] - default: present -author: - - Prasoon Karunan V (@prasoonkarunan) -''' - -EXAMPLES = r''' -- name: Set autologon for user1 - win_auto_logon: - username: User1 - password: str0ngp@ssword - -- name: Set autologon for abc.com\user1 - win_auto_logon: - username: abc.com\User1 - password: str0ngp@ssword - -- name: Remove autologon for user1 - win_auto_logon: - state: absent - -- name: Set autologon for user1 with a limited logon count - win_auto_logon: - username: User1 - password: str0ngp@ssword - logon_count: 5 -''' - -RETURN = r''' -# -''' diff --git a/lib/ansible/modules/windows/win_certificate_info.ps1 b/lib/ansible/modules/windows/win_certificate_info.ps1 deleted file mode 100644 index b1ff876479c..00000000000 --- a/lib/ansible/modules/windows/win_certificate_info.ps1 +++ /dev/null @@ -1,132 +0,0 @@ -#!powershell - -# Copyright: (c) 2019, Micah Hunsberger -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic - -function ConvertTo-Timestamp($start_date, $end_date) -{ - if ($start_date -and $end_date) - { - return (New-TimeSpan -Start $start_date -End $end_date).TotalSeconds - } -} - -function Format-Date([DateTime]$date) -{ - return $date.ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssK') -} - -function Get-CertificateInfo ($cert) -{ - $epoch_date = Get-Date -Date "01/01/1970" - - $cert_info = @{ extensions = @() } - $cert_info.friendly_name = $cert.FriendlyName - $cert_info.thumbprint = $cert.Thumbprint - $cert_info.subject = $cert.Subject - $cert_info.issuer = $cert.Issuer - $cert_info.valid_from = (ConvertTo-Timestamp -start_date $epoch_date -end_date $cert.NotBefore.ToUniversalTime()) - $cert_info.valid_from_iso8601 = Format-Date -date $cert.NotBefore - $cert_info.valid_to = (ConvertTo-Timestamp -start_date $epoch_date -end_date $cert.NotAfter.ToUniversalTime()) - $cert_info.valid_to_iso8601 = Format-Date -date $cert.NotAfter - $cert_info.serial_number = $cert.SerialNumber - $cert_info.archived = $cert.Archived - $cert_info.version = $cert.Version - $cert_info.has_private_key = $cert.HasPrivateKey - $cert_info.issued_by = $cert.GetNameInfo('SimpleName', $true) - $cert_info.issued_to = $cert.GetNameInfo('SimpleName', $false) - $cert_info.signature_algorithm = $cert.SignatureAlgorithm.FriendlyName - $cert_info.dns_names = [System.Collections.Generic.List`1[String]]@($cert_info.issued_to) - $cert_info.raw = [System.Convert]::ToBase64String($cert.GetRawCertData()) - $cert_info.public_key = [System.Convert]::ToBase64String($cert.GetPublicKey()) - if ($cert.Extensions.Count -gt 0) - { - [array]$cert_info.extensions = foreach ($extension in $cert.Extensions) - { - $extension_info = @{ - critical = $extension.Critical - field = $extension.Oid.FriendlyName - value = $extension.Format($false) - } - if ($extension -is [System.Security.Cryptography.X509Certificates.X509BasicConstraintsExtension]) - { - $cert_info.is_ca = $extension.CertificateAuthority - $cert_info.path_length_constraint = $extension.PathLengthConstraint - } - elseif ($extension -is [System.Security.Cryptography.X509Certificates.X509EnhancedKeyUsageExtension]) - { - $cert_info.intended_purposes = $extension.EnhancedKeyUsages.FriendlyName -as [string[]] - } - elseif ($extension -is [System.Security.Cryptography.X509Certificates.X509KeyUsageExtension]) - { - $cert_info.key_usages = $extension.KeyUsages.ToString().Split(',').Trim() -as [string[]] - } - elseif ($extension -is [System.Security.Cryptography.X509Certificates.X509SubjectKeyIdentifierExtension]) - { - $cert_info.ski = $extension.SubjectKeyIdentifier - } - elseif ($extension.Oid.value -eq '2.5.29.17') - { - $sans = $extension.Format($true).Split("`r`n", [System.StringSplitOptions]::RemoveEmptyEntries) - foreach ($san in $sans) - { - $san_parts = $san.Split("=") - if ($san_parts.Length -ge 2 -and $san_parts[0].Trim() -eq 'DNS Name') - { - $cert_info.dns_names.Add($san_parts[1].Trim()) - } - } - } - $extension_info - } - } - return $cert_info -} - -$store_location_values = ([System.Security.Cryptography.X509Certificates.StoreLocation]).GetEnumValues() | ForEach-Object { $_.ToString() } - -$spec = @{ - options = @{ - thumbprint = @{ type = "str"; required = $false } - store_name = @{ type = "str"; default = "My"; } - store_location = @{ type = "str"; default = "LocalMachine"; choices = $store_location_values; } - } -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$thumbprint = $module.Params.thumbprint -$store_name = $module.Params.store_name -$store_location = [System.Security.Cryptography.X509Certificates.Storelocation]"$($module.Params.store_location)" - -$store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $store_name, $store_location -$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly) - -$module.Result.exists = $false -$module.Result.certificates = @() - -try -{ - if ($null -ne $thumbprint) - { - $found_certs = $store.Certificates.Find([System.Security.Cryptography.X509Certificates.X509FindType]::FindByThumbprint, $thumbprint, $false) - } - else - { - $found_certs = $store.Certificates - } - - if ($found_certs.Count -gt 0) - { - $module.Result.exists = $true - [array]$module.Result.certificates = $found_certs | ForEach-Object { Get-CertificateInfo -cert $_ } | Sort-Object -Property { $_.thumbprint } - } -} -finally -{ - $store.Close() -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_certificate_info.py b/lib/ansible/modules/windows/win_certificate_info.py deleted file mode 100644 index c8a75731cac..00000000000 --- a/lib/ansible/modules/windows/win_certificate_info.py +++ /dev/null @@ -1,236 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2016, Ansible, inc -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_certificate_info -version_added: "2.10" -short_description: Get information on certificates from a Windows Certificate Store -description: -- Returns information about certificates in a Windows Certificate Store. -options: - thumbprint: - description: - - The thumbprint as a hex string of a certificate to find. - - When specified, filters the I(certificates) return value to a single certificate - - See the examples for how to format the thumbprint. - type: str - required: no - store_name: - description: - - The name of the store to search. - - See U(https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.storename) - for a list of built-in store names. - type: str - default: My - store_location: - description: - - The location of the store to search. - type: str - choices: [ CurrentUser, LocalMachine ] - default: LocalMachine -seealso: -- module: win_certificate_store -author: -- Micah Hunsberger (@mhunsber) -''' - -EXAMPLES = r''' -- name: Obtain information about a particular certificate in the computer's personal store - win_certificate_info: - thumbprint: BD7AF104CF1872BDB518D95C9534EA941665FD27 - register: mycert - -# thumbprint can also be lower case -- name: Obtain information about a particular certificate in the computer's personal store - win_certificate_info: - thumbprint: bd7af104cf1872bdb518d95c9534ea941665fd27 - register: mycert - -- name: Obtain information about all certificates in the root store - win_certificate_info: - store_name: Root - register: ca - -# Import a pfx and then get information on the certificates -- name: Import pfx certificate that is password protected - win_certificate_store: - path: C:\Temp\cert.pfx - state: present - password: VeryStrongPasswordHere! - become: yes - become_method: runas - register: mycert - -- name: Obtain information on each certificate that was touched - win_certificate_info: - thumbprint: "{{ item }}" - register: mycert_stats - loop: "{{ mycert.thumbprints }}" -''' - -RETURN = r''' -exists: - description: - - Whether any certificates were found in the store. - - When I(thumbprint) is specified, returns true only if the certificate mathing the thumbprint exists. - returned: success - type: bool - sample: true -certificates: - description: - - A list of information about certificates found in the store, sorted by thumbprint. - returned: success - type: list - elements: dict - contains: - archived: - description: Indicates that the certificate is archived. - type: bool - sample: false - dns_names: - description: Lists the registered dns names for the certificate. - type: list - elements: str - sample: [ '*.m.wikiquote.org', '*.wikipedia.org' ] - extensions: - description: The collection of the certificates extensions. - type: list - elements: dict - sample: [ - { - "critical": false, - "field": "Subject Key Identifier", - "value": "88 27 17 09 a9 b6 18 60 8b ec eb ba f6 47 59 c5 52 54 a3 b7" - }, - { - "critical": true, - "field": "Basic Constraints", - "value": "Subject Type=CA, Path Length Constraint=None" - }, - { - "critical": false, - "field": "Authority Key Identifier", - "value": "KeyID=2b d0 69 47 94 76 09 fe f4 6b 8d 2e 40 a6 f7 47 4d 7f 08 5e" - }, - { - "critical": false, - "field": "CRL Distribution Points", - "value": "[1]CRL Distribution Point: Distribution Point Name:Full Name:URL=http://crl.apple.com/root.crl" - }, - { - "critical": true, - "field": "Key Usage", - "value": "Digital Signature, Certificate Signing, Off-line CRL Signing, CRL Signing (86)" - }, - { - "critical": false, - "field": null, - "value": "05 00" - } - ] - friendly_name: - description: The associated alias for the certificate. - type: str - sample: Microsoft Root Authority - has_private_key: - description: Indicates that the certificate contains a private key. - type: bool - sample: false - intended_purposes: - description: lists the intended applications for the certificate. - returned: enhanced key usages extension exists. - type: list - sample: [ "Server Authentication" ] - is_ca: - description: Indicates that the certificate is a certificate authority (CA) certificate. - returned: basic constraints extension exists. - type: bool - sample: true - issued_by: - description: The certificate issuer's common name. - type: str - sample: Apple Root CA - issued_to: - description: The certificate's common name. - type: str - sample: Apple Worldwide Developer Relations Certification Authority - issuer: - description: The certificate issuer's distinguished name. - type: str - sample: 'CN=Apple Root CA, OU=Apple Certification Authority, O=Apple Inc., C=US' - key_usages: - description: - - Defines how the certificate key can be used. - - If this value is not defined, the key can be used for any purpose. - returned: key usages extension exists. - type: list - elements: str - sample: [ "CrlSign", "KeyCertSign", "DigitalSignature" ] - path_length_constraint: - description: - - The number of levels allowed in a certificates path. - - If this value is 0, the certificate does not have a restriction. - returned: basic constraints extension exists - type: int - sample: 0 - public_key: - description: The base64 encoded public key of the certificate. - type: str - cert_data: - description: The base64 encoded data of the entire certificate. - type: str - serial_number: - description: The serial number of the certificate represented as a hexadecimal string - type: str - sample: 01DEBCC4396DA010 - signature_algorithm: - description: The algorithm used to create the certificate's signature - type: str - sample: sha1RSA - ski: - description: The certificate's subject key identifier - returned: subject key identifier extension exists. - type: str - sample: 88271709A9B618608BECEBBAF64759C55254A3B7 - subject: - description: The certificate's distinguished name. - type: str - sample: 'CN=Apple Worldwide Developer Relations Certification Authority, OU=Apple Worldwide Developer Relations, O=Apple Inc., C=US' - thumbprint: - description: - - The thumbprint as a hex string of the certificate. - - The return format will always be upper case. - type: str - sample: FF6797793A3CD798DC5B2ABEF56F73EDC9F83A64 - valid_from: - description: The start date of the certificate represented in seconds since epoch. - type: float - sample: 1360255727 - valid_from_iso8601: - description: The start date of the certificate represented as an iso8601 formatted date. - type: str - sample: '2017-12-15T08:39:32Z' - valid_to: - description: The expiry date of the certificate represented in seconds since epoch. - type: float - sample: 1675788527 - valid_to_iso8601: - description: The expiry date of the certificate represented as an iso8601 formatted date. - type: str - sample: '2086-01-02T08:39:32Z' - version: - description: The x509 format version of the certificate - type: int - sample: 3 -''' diff --git a/lib/ansible/modules/windows/win_chocolatey.ps1 b/lib/ansible/modules/windows/win_chocolatey.ps1 deleted file mode 100644 index d5cb87f7c0c..00000000000 --- a/lib/ansible/modules/windows/win_chocolatey.ps1 +++ /dev/null @@ -1,803 +0,0 @@ -#!powershell - -# Copyright: (c) 2014, Trond Hindenes -# Copyright: (c) 2017, Dag Wieers -# Copyright: (c) 2018, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.ArgvParser -#Requires -Module Ansible.ModuleUtils.CommandUtil -#AnsibleRequires -CSharpUtil Ansible.Basic - -# As of chocolatey 0.9.10, non-zero success exit codes can be returned -# See https://github.com/chocolatey/choco/issues/512#issuecomment-214284461 -$successexitcodes = (0, 1605, 1614, 1641, 3010) - -$spec = @{ - options = @{ - allow_empty_checksums = @{ type = "bool"; default = $false } - allow_multiple = @{ type = "bool"; default = $false } - allow_prerelease = @{ type = "bool"; default = $false } - architecture = @{ type = "str"; default = "default"; choices = "default", "x86" } - force = @{ type = "bool"; default = $false } - ignore_checksums = @{ type = "bool"; default = $false } - ignore_dependencies = @{ type = "bool"; default = $false } - install_args = @{ type = "str" } - name = @{ type = "list"; elements = "str"; required = $true } - override_args = @{ type = "bool"; default = $false } - package_params = @{ type = "str"; aliases = @("params") } - pinned = @{ type = "bool" } - proxy_url = @{ type = "str" } - proxy_username = @{ type = "str" } - proxy_password = @{ type = "str"; no_log = $true } - skip_scripts = @{ type = "bool"; default = $false } - source = @{ type = "str" } - source_username = @{ type = "str" } - source_password = @{ type = "str"; no_log = $true } - state = @{ type = "str"; default = "present"; choices = "absent", "downgrade", "latest", "present", "reinstalled" } - timeout = @{ type = "int"; default = 2700; aliases = @("execution_timeout") } - validate_certs = @{ type = "bool"; default = $true } - version = @{ type = "str" } - } - supports_check_mode = $true -} -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$allow_empty_checksums = $module.Params.allow_empty_checksums -$allow_multiple = $module.Params.allow_multiple -$allow_prerelease = $module.Params.allow_prerelease -$architecture = $module.Params.architecture -$force = $module.Params.force -$ignore_checksums = $module.Params.ignore_checksums -$ignore_dependencies = $module.Params.ignore_dependencies -$install_args = $module.Params.install_args -$name = $module.Params.name -$override_args = $module.Params.override_args -$package_params = $module.Params.package_params -$pinned = $module.Params.pinned -$proxy_url = $module.Params.proxy_url -$proxy_username = $module.Params.proxy_username -$proxy_password = $module.Params.proxy_password -$skip_scripts = $module.Params.skip_scripts -$source = $module.Params.source -$source_username = $module.Params.source_username -$source_password = $module.Params.source_password -$state = $module.Params.state -$timeout = $module.Params.timeout -$validate_certs = $module.Params.validate_certs -$version = $module.Params.version - -$module.Result.rc = 0 - -if (-not $validate_certs) { - [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true } -} - -Function Get-CommonChocolateyArguments { - # uses global vars like check_mode and verbosity to control the common args - # run with Chocolatey - $arguments = [System.Collections.ArrayList]@("--yes", "--no-progress") - # global vars that control the arguments - if ($module.CheckMode) { - $arguments.Add("--what-if") > $null - } - if ($module.Verbosity -gt 4) { - $arguments.Add("--debug") > $null - $arguments.Add("--verbose") > $null - } elseif ($module.Verbosity -gt 3) { - $arguments.Add("--verbose") > $null - } else { - $arguments.Add("--limit-output") > $null - } - - return ,$arguments -} - -Function Get-InstallChocolateyArguments { - param( - [bool]$allow_downgrade, - [bool]$allow_empty_checksums, - [bool]$allow_multiple, - [bool]$allow_prerelease, - [String]$architecture, - [bool]$force, - [bool]$ignore_dependencies, - [String]$install_args, - [bool]$override_args, - [String]$package_params, - [String]$proxy_url, - [String]$proxy_username, - [String]$proxy_password, - [bool]$skip_scripts, - [String]$source, - [String]$source_usename, - [String]$source_password, - [int]$timeout, - [String]$version - ) - # returns an ArrayList of common arguments for install/updated a Chocolatey - # package - $arguments = [System.Collections.ArrayList]@("--fail-on-unfound") - $common_args = Get-CommonChocolateyArguments - $arguments.AddRange($common_args) - - if ($allow_downgrade) { - $arguments.Add("--allow-downgrade") > $null - } - if ($allow_empty_checksums) { - $arguments.Add("--allow-empty-checksums") > $null - } - if ($allow_multiple) { - $arguments.Add("--allow-multiple") > $null - } - if ($allow_prerelease) { - $arguments.Add("--prerelease") > $null - } - if ($architecture -eq "x86") { - $arguments.Add("--x86") > $null - } - if ($force) { - $arguments.Add("--force") > $null - } - if ($ignore_checksums) { - $arguments.Add("--ignore-checksums") > $null - } - if ($ignore_dependencies) { - $arguments.Add("--ignore-dependencies") > $null - } - if ($install_args) { - $arguments.Add("--install-arguments") > $null - $arguments.add($install_args) > $null - } - if ($override_args) { - $arguments.Add("--override-arguments") > $null - } - if ($package_params) { - $arguments.Add("--package-parameters") > $null - $arguments.Add($package_params) > $null - } - if ($proxy_url) { - $arguments.Add("--proxy") > $null - $arguments.Add($proxy_url) > $null - } - if ($proxy_username) { - $arguments.Add("--proxy-user") > $null - $arguments.Add($proxy_username) > $null - } - if ($proxy_password) { - $arguments.Add("--proxy-password") > $null - $arguments.Add($proxy_password) > $null - } - if ($skip_scripts) { - $arguments.Add("--skip-scripts") > $null - } - if ($source) { - $arguments.Add("--source") > $null - $arguments.Add($source) > $null - } - if ($source_username) { - $arguments.Add("--user") > $null - $arguments.Add($source_username) > $null - $arguments.Add("--password") > $null - $arguments.Add($source_password) > $null - } - if ($null -ne $timeout) { - $arguments.Add("--timeout") > $null - $arguments.Add($timeout) > $null - } - if ($version) { - $arguments.Add("--version") > $null - $arguments.Add($version) > $null - } - - return ,$arguments -} - -Function Install-Chocolatey { - param( - [String]$proxy_url, - [String]$proxy_username, - [String]$proxy_password, - [String]$source, - [String]$source_username, - [String]$source_password, - [String]$version - ) - - $choco_app = Get-Command -Name choco.exe -CommandType Application -ErrorAction SilentlyContinue - if ($null -eq $choco_app) { - # We need to install chocolatey - # Enable TLS1.1/TLS1.2 if they're available but disabled (eg. .NET 4.5) - $security_protocols = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::SystemDefault - if ([Net.SecurityProtocolType].GetMember("Tls11").Count -gt 0) { - $security_protocols = $security_protcols -bor [Net.SecurityProtocolType]::Tls11 - } - if ([Net.SecurityProtocolType].GetMember("Tls12").Count -gt 0) { - $security_protocols = $security_protcols -bor [Net.SecurityProtocolType]::Tls12 - } - [Net.ServicePointManager]::SecurityProtocol = $security_protocols - - $client = New-Object -TypeName System.Net.WebClient - $new_environment = @{} - if ($proxy_url) { - # the env values are used in the install.ps1 script when getting - # external dependencies - $new_environment.chocolateyProxyLocation = $proxy_url - $web_proxy = New-Object -TypeName System.Net.WebProxy -ArgumentList $proxy_url, $true - $client.Proxy = $web_proxy - if ($proxy_username -and $proxy_password) { - $new_environment.chocolateyProxyUser = $proxy_username - $new_environment.chocolateyProxyPassword = $proxy_password - $sec_proxy_password = ConvertTo-SecureString -String $proxy_password -AsPlainText -Force - $web_proxy.Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $proxy_username, $sec_proxy_password - } - } - if ($version) { - # Set the chocolateyVersion environment variable when bootstrapping Chocolatey to install that specific - # version. - $new_environment.chocolateyVersion = $version - } - - $environment = @{} - if ($new_environment.Count -gt 0) { - $environment = [Environment]::GetEnvironmentVariables() - $environment += $new_environment - } - - if ($source) { - # check if the URL already contains the path to PS script - if ($source.EndsWith(".ps1")) { - $script_url = $source - } else { - # chocolatey server automatically serves a script at - # http://host/install.ps1, we rely on this behaviour when a - # user specifies the choco source URL. If a custom URL or file - # path is desired, they should use win_get_url/win_shell - # manually - # we need to strip the path off the URL and append install.ps1 - $uri_info = [System.Uri]$source - $script_url = "$($uri_info.Scheme)://$($uri_info.Authority)/install.ps1" - } - if ($source_username) { - # while the choco-server does not require creds on install.ps1, - # Net.WebClient will only send the credentials if the initial - # req fails so we will add the creds in case the source URL - # is not choco-server and requires authentication - $sec_source_password = ConvertTo-SecureString -String $source_password -AsPlainText -Force - $client.Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $source_username, $sec_source_password - } - } else { - $script_url = "https://chocolatey.org/install.ps1" - } - - try { - $install_script = $client.DownloadString($script_url) - } catch { - $module.FailJson("Failed to download Chocolatey script from '$script_url'; $($_.Exception.Message)", $_) - } - if (-not $module.CheckMode) { - $res = Run-Command -command "powershell.exe -" -stdin $install_script -environment $environment - if ($res.rc -ne 0) { - $module.Result.rc = $res.rc - $module.Result.stdout = $res.stdout - $module.Result.stderr = $res.stderr - $module.FailJson("Chocolatey bootstrap installation failed.") - } - $module.Warn("Chocolatey was missing from this system, so it was installed during this task run.") - } - $module.Result.changed = $true - - # locate the newly installed choco.exe - $choco_app = Get-Command -Name choco.exe -CommandType Application -ErrorAction SilentlyContinue - if ($null -eq $choco_app) { - $choco_dir = $env:ChocolateyInstall - if ($null -eq $choco_dir) { - $choco_dir = "$env:SYSTEMDRIVE\ProgramData\Chocolatey" - } - $choco_app = Get-Command -Name "$choco_dir\bin\choco.exe" -CommandType Application -ErrorAction SilentlyContinue - } - } - - if ($module.CheckMode -and $null -eq $choco_app) { - $module.Result.skipped = $true - $module.Result.msg = "Skipped check mode run on win_chocolatey as choco.exe cannot be found on the system" - $module.ExitJson() - } - - if ($null -eq $choco_app -or -not (Test-Path -LiteralPath $choco_app.Path)) { - $module.FailJson("Failed to find choco.exe, make sure it is added to the PATH or the env var 'ChocolateyInstall' is set") - } - - $actual_version = (Get-ChocolateyPackageVersion -choco_path $choco_app.Path -name chocolatey)[0] - try { - # The Chocolatey version may not be in the strict form of major.minor.build and will fail to cast to - # System.Version. We want to warn if this is the case saying module behaviour may be incorrect. - $actual_version = [Version]$actual_version - } catch { - $module.Warn("Failed to parse Chocolatey version '$actual_version' for checking module requirements, module may not work correctly: $($_.Exception.Message)") - $actual_version = $null - } - if ($null -ne $actual_version -and $actual_version -lt [Version]"0.10.5") { - if ($module.CheckMode) { - $module.Result.skipped = $true - $module.Result.msg = "Skipped check mode run on win_chocolatey as choco.exe is too old, a real run would have upgraded the executable. Actual: '$actual_version', Minimum Version: '0.10.5'" - $module.ExitJson() - } - $module.Warn("Chocolatey was older than v0.10.5 so it was upgraded during this task run.") - Update-ChocolateyPackage -choco_path $choco_app.Path -packages @("chocolatey") ` - - -proxy_url $proxy_url -proxy_username $proxy_username ` - -proxy_password $proxy_password -source $source ` - -source_username $source_username -source_password $source_password - } - - return $choco_app.Path -} - -Function Get-ChocolateyPackageVersion { - Param ( - [Parameter(Mandatory=$true)] - [System.String] - $choco_path, - - [Parameter(Mandatory=$true, ValueFromPipeline=$true)] - [System.String] - $name - ) - - Begin { - # Due to https://github.com/chocolatey/choco/issues/1843, we get a list of all the installed packages and - # filter it ourselves. This has the added benefit of being quicker when dealing with multiple packages as we - # only call choco.exe once. - $command = Argv-ToString -arguments @($choco_path, 'list', '--local-only', '--limit-output', '--all-versions') - $res = Run-Command -command $command - - # Chocolatey v0.10.12 introduced enhanced exit codes, 2 means no results, e.g. no package - if ($res.rc -notin @(0, 2)) { - $module.Result.command = $command - $module.Result.rc = $res.rc - $module.Result.stdout = $res.stdout - $module.Result.stderr = $res.stderr - $module.FailJson('Error checking installation status for chocolatey packages') - } - - # Parse the stdout to get a list of all packages installed and their versions. - $installed_packages = $res.stdout.Trim().Split([System.Environment]::NewLine) | ForEach-Object -Process { - if ($_.Contains('|')) { # Sanity in case further output is added in the future. - $package_split = $_.Split('|', 2) - @{ Name = $package_split[0]; Version = $package_split[1] } - } - } - - # Create a hashtable that will store our package version info. - $installed_info = @{} - } - - Process { - if ($name -eq 'all') { - # All is a special package name that means all installed packages, we set a dummy version so absent, latest - # and downgrade will run with all. - $installed_info.'all' = @('0.0.0') - } else { - $package_info = $installed_packages | Where-Object { $_.Name -eq $name } - if ($null -eq $package_info) { - $installed_info.$name = $null - } else { - $installed_info.$name = @($package_info.Version) - } - } - } - - End { - return $installed_info - } -} - -Function Get-ChocolateyPin { - param( - [Parameter(Mandatory=$true)][String]$choco_path - ) - - $command = Argv-ToString -arguments @($choco_path, "pin", "list", "--limit-output") - $res = Run-Command -command $command - if ($res.rc -ne 0) { - $module.Result.command = $command - $module.Result.rc = $res.rc - $module.Result.stdout = $res.stdout - $module.Result.stderr = $res.stderr - $module.FailJson("Error getting list of pinned packages") - } - - $stdout = $res.stdout.Trim() - $pins = @{} - - $stdout.Split("`r`n", [System.StringSplitOptions]::RemoveEmptyEntries) | ForEach-Object { - $package = $_.Substring(0, $_.LastIndexOf("|")) - $version = $_.Substring($_.LastIndexOf("|") + 1) - - if ($pins.ContainsKey($package)) { - $pinned_versions = $pins.$package - } else { - $pinned_versions = [System.Collections.Generic.List`1[String]]@() - } - $pinned_versions.Add($version) - $pins.$package = $pinned_versions - } - return ,$pins -} - -Function Set-ChocolateyPin { - param( - [Parameter(Mandatory=$true)][String]$choco_path, - [Parameter(Mandatory=$true)][String]$name, - [Switch]$pin, - [String]$version - ) - if ($pin) { - $action = "add" - $err_msg = "Error pinning package '$name'" - } else { - $action = "remove" - $err_msg = "Error unpinning package '$name'" - } - - $arguments = [System.Collections.ArrayList]@($choco_path, "pin", $action, "--name", $name) - if ($version) { - $err_msg += " at '$version'" - $arguments.Add("--version") > $null - $arguments.Add($version) > $null - } - $common_args = Get-CommonChocolateyArguments - $arguments.AddRange($common_args) - - $command = Argv-ToString -arguments $arguments - $res = Run-Command -command $command - if ($res.rc -ne 0) { - $module.Result.command = $command - $module.Result.rc = $res.rc - $module.Result.stdout = $res.stdout - $module.Result.stderr = $res.stderr - $module.FailJson($err_msg) - } - $module.result.changed = $true -} - -Function Update-ChocolateyPackage { - param( - [Parameter(Mandatory=$true)][String]$choco_path, - [Parameter(Mandatory=$true)][String[]]$packages, - [bool]$allow_downgrade, - [bool]$allow_empty_checksums, - [bool]$allow_multiple, - [bool]$allow_prerelease, - [String]$architecture, - [bool]$force, - [bool]$ignore_checksums, - [bool]$ignore_dependencies, - [String]$install_args, - [bool]$override_args, - [String]$package_params, - [String]$proxy_url, - [String]$proxy_username, - [String]$proxy_password, - [bool]$skip_scripts, - [String]$source, - [String]$source_username, - [String]$source_password, - [int]$timeout, - [String]$version - ) - - $arguments = [System.Collections.ArrayList]@($choco_path, "upgrade") - $arguments.AddRange($packages) - - $common_params = @{ - allow_downgrade = $allow_downgrade - allow_empty_checksums = $allow_empty_checksums - allow_multiple = $allow_multiple - allow_prerelease = $allow_prerelease - architecture = $architecture - force = $force - ignore_checksums = $ignore_checksums - ignore_dependencies = $ignore_dependencies - install_args = $install_args - override_args = $override_args - package_params = $package_params - proxy_url = $proxy_url - proxy_username = $proxy_username - proxy_password = $proxy_password - skip_scripts = $skip_scripts - source = $source - source_username = $source_username - source_password = $source_password - timeout = $timeout - version = $version - } - $common_args = Get-InstallChocolateyArguments @common_params - $arguments.AddRange($common_args) - - $command = Argv-ToString -arguments $arguments - $res = Run-Command -command $command - $module.Result.rc = $res.rc - if ($res.rc -notin $successexitcodes) { - $module.Result.command = $command - $module.Result.stdout = $res.stdout - $module.Result.stderr = $res.stderr - $module.FailJson("Error updating package(s) '$($packages -join ", ")'") - } - - if ($module.Verbosity -gt 1) { - $module.Result.stdout = $res.stdout - } - - if ($res.stdout -match ' upgraded (\d+)/\d+ package') { - if ($Matches[1] -gt 0) { - $module.Result.changed = $true - } - } - # need to set to false in case the rc is not 0 and a failure didn't actually occur - $module.Result.failed = $false -} - -Function Install-ChocolateyPackage { - param( - [Parameter(Mandatory=$true)][String]$choco_path, - [Parameter(Mandatory=$true)][String[]]$packages, - [bool]$allow_downgrade, - [bool]$allow_empty_checksums, - [bool]$allow_multiple, - [bool]$allow_prerelease, - [String]$architecture, - [bool]$force, - [bool]$ignore_checksums, - [bool]$ignore_dependencies, - [String]$install_args, - [bool]$override_args, - [String]$package_params, - [String]$proxy_url, - [String]$proxy_username, - [String]$proxy_password, - [bool]$skip_scripts, - [String]$source, - [String]$source_username, - [String]$source_password, - [int]$timeout, - [String]$version - ) - - $arguments = [System.Collections.ArrayList]@($choco_path, "install") - $arguments.AddRange($packages) - $common_params = @{ - allow_downgrade = $allow_downgrade - allow_empty_checksums = $allow_empty_checksums - allow_multiple = $allow_multiple - allow_prerelease = $allow_prerelease - architecture = $architecture - force = $force - ignore_checksums = $ignore_checksums - ignore_dependencies = $ignore_dependencies - install_args = $install_args - override_args = $override_args - package_params = $package_params - proxy_url = $proxy_url - proxy_username = $proxy_username - proxy_password = $proxy_password - skip_scripts = $skip_scripts - source = $source - source_username = $source_username - source_password = $source_password - timeout = $timeout - version = $version - } - $common_args = Get-InstallChocolateyArguments @common_params - $arguments.AddRange($common_args) - - $command = Argv-ToString -arguments $arguments - $res = Run-Command -command $command - $module.Result.rc = $res.rc - if ($res.rc -notin $successexitcodes) { - $module.Result.command = $command - $module.Result.stdout = $res.stdout - $module.Result.stderr = $res.stderr - $module.FailJson("Error installing package(s) '$($packages -join ', ')'") - } - - if ($module.Verbosity -gt 1) { - $module.Result.stdout = $res.stdout - } - - $module.Result.changed = $true - # need to set to false in case the rc is not 0 and a failure didn't actually occur - $module.Result.failed = $false -} - -Function Uninstall-ChocolateyPackage { - param( - [Parameter(Mandatory=$true)][String]$choco_path, - [Parameter(Mandatory=$true)][String[]]$packages, - [bool]$force, - [String]$package_params, - [bool]$skip_scripts, - [int]$timeout, - [String]$version - ) - - $arguments = [System.Collections.ArrayList]@($choco_path, "uninstall") - $arguments.AddRange($packages) - $common_args = Get-CommonChocolateyArguments - $arguments.AddRange($common_args) - - if ($force) { - $arguments.Add("--force") > $null - } - if ($package_params) { - $arguments.Add("--package-params") > $null - $arguments.Add($package_params) > $null - } - if ($skip_scripts) { - $arguments.Add("--skip-scripts") > $null - } - if ($null -ne $timeout) { - $arguments.Add("--timeout") > $null - $arguments.Add($timeout) > $null - } - if ($version) { - # Need to set allow-multiple to make sure choco doesn't uninstall all versions - $arguments.Add("--allow-multiple") > $null - $arguments.Add("--version") > $null - $arguments.Add($version) > $null - } else { - $arguments.Add("--all-versions") > $null - } - - $command = Argv-ToString -arguments $arguments - $res = Run-Command -command $command - $module.Result.rc = $res.rc - if ($res.rc -notin $successexitcodes) { - $module.Result.command = $command - $module.Result.stdout = $res.stdout - $module.Result.stderr = $res.stderr - $module.FailJson("Error uninstalling package(s) '$($packages -join ", ")'") - } - - if ($module.Verbosity -gt 1) { - $module.Result.stdout = $res.stdout - } - $module.Result.changed = $true - # need to set to false in case the rc is not 0 and a failure didn't actually occur - $module.Result.failed = $false -} - -# get the full path to choco.exe, otherwise install/upgrade to at least 0.10.5 -$install_params = @{ - proxy_url = $proxy_url - proxy_username = $proxy_username - proxy_password = $proxy_password - source = $source - source_username = $source_username - source_password = $source_password -} -if ($version -and "chocolatey" -in $name) { - # If a version is set and chocolatey is in the package list, pass the chocolatey version to the bootstrapping - # process. - $install_params.version = $version -} -$choco_path = Install-Chocolatey @install_params - -if ('all' -in $name -and $state -in @('present', 'reinstalled')) { - $module.FailJson("Cannot specify the package name as 'all' when state=$state") -} - -# get the version of all specified packages -$package_info = $name | Get-ChocolateyPackageVersion -choco_path $choco_path - -if ($state -in "absent", "reinstalled") { - $installed_packages = ($package_info.GetEnumerator() | Where-Object { $null -ne $_.Value }).Key - if ($null -ne $installed_packages) { - Uninstall-ChocolateyPackage -choco_path $choco_path -packages $installed_packages ` - -force $force -package_params $package_params -skip_scripts $skip_scripts ` - -timeout $timeout -version $version - } - - # ensure the package info for the uninstalled versions has been removed - # so state=reinstall will install them in the next step - foreach ($package in $installed_packages) { - $package_info.$package = $null - } -} - -if ($state -in @("downgrade", "latest", "present", "reinstalled")) { - if ($state -eq "present" -and $force) { - # when present and force, we just run the install step with the packages specified - $missing_packages = $name - } else { - # otherwise only install the packages that are not installed - $missing_packages = [System.Collections.ArrayList]@() - foreach ($package in $package_info.GetEnumerator()) { - if ($null -eq $package.Value) { - $missing_packages.Add($package.Key) > $null - } - } - } - - # if version is specified and installed version does not match or not - # allow_multiple, throw error ignore this if force is set - if ($state -eq "present" -and $null -ne $version -and -not $force) { - foreach ($package in $name) { - $package_versions = [System.Collections.ArrayList]$package_info.$package - if ($package_versions.Count -gt 0) { - if (-not $package_versions.Contains($version) -and -not $allow_multiple) { - $module.FailJson("Chocolatey package '$package' is already installed with version(s) '$($package_versions -join "', '")' but was expecting '$version'. Either change the expected version, set state=latest, set allow_multiple=yes, or set force=yes to continue") - } elseif ($version -notin $package_versions -and $allow_multiple) { - # add the package back into the list of missing packages if installing multiple - $missing_packages.Add($package) > $null - } - } - } - } - $common_args = @{ - choco_path = $choco_path - allow_downgrade = ($state -eq "downgrade") - allow_empty_checksums = $allow_empty_checksums - allow_multiple = $allow_multiple - allow_prerelease = $allow_prerelease - architecture = $architecture - force = $force - ignore_checksums = $ignore_checksums - ignore_dependencies = $ignore_dependencies - install_args = $install_args - override_args = $override_args - package_params = $package_params - proxy_url = $proxy_url - proxy_username = $proxy_username - proxy_password = $proxy_password - skip_scripts = $skip_scripts - source = $source - source_username = $source_username - source_password = $source_password - timeout = $timeout - version = $version - } - - if ($missing_packages) { - Install-ChocolateyPackage -packages $missing_packages @common_args - } - - if ($state -eq "latest" -or ($state -eq "downgrade" -and $null -ne $version)) { - # when in a downgrade/latest situation, we want to run choco upgrade on - # the remaining packages that were already installed, don't run this if - # state=downgrade and a version isn't specified (this will actually - # upgrade a package) - $installed_packages = ($package_info.GetEnumerator() | Where-Object { $null -ne $_.Value }).Key - if ($null -ne $installed_packages) { - Update-ChocolateyPackage -packages $installed_packages @common_args - } - } - - # Now we want to pin/unpin any packages now that it has been installed/upgraded - if ($null -ne $pinned) { - $pins = Get-ChocolateyPin -choco_path $choco_path - - foreach ($package in $name) { - if ($pins.ContainsKey($package)) { - if (-not $pinned -and $null -eq $version) { - # No version is set and pinned=no, we want to remove all pins on the package. There is a bug in - # 'choco pin remove' with multiple versions where an older version might be pinned but - # 'choco pin remove' will still fail without an explicit version. Instead we take the literal - # interpretation that pinned=no and no version means the package has no pins at all - foreach ($v in $pins.$package) { - Set-ChocolateyPin -choco_path $choco_path -name $package -version $v - } - } elseif ($null -ne $version -and $pins.$package.Contains($version) -ne $pinned) { - Set-ChocolateyPin -choco_path $choco_path -name $package -pin:$pinned -version $version - } - } elseif ($pinned) { - # Package had no pins but pinned=yes is set. - Set-ChocolateyPin -choco_path $choco_path -name $package -pin -version $version - } - } - } -} - -$module.ExitJson() - diff --git a/lib/ansible/modules/windows/win_chocolatey.py b/lib/ansible/modules/windows/win_chocolatey.py deleted file mode 100644 index 6792f59a937..00000000000 --- a/lib/ansible/modules/windows/win_chocolatey.py +++ /dev/null @@ -1,385 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2014, Trond Hindenes -# Copyright: (c) 2018, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_chocolatey -version_added: '1.9' -short_description: Manage packages using chocolatey -description: -- Manage packages using Chocolatey. -- If Chocolatey is missing from the system, the module will install it. -requirements: -- chocolatey >= 0.10.5 (will be upgraded if older) -options: - allow_empty_checksums: - description: - - Allow empty checksums to be used for downloaded resource from non-secure - locations. - - Use M(win_chocolatey_feature) with the name C(allowEmptyChecksums) to - control this option globally. - type: bool - default: no - version_added: '2.2' - allow_multiple: - description: - - Allow the installation of multiple packages when I(version) is specified. - - Having multiple packages at different versions can cause issues if the - package doesn't support this. Use at your own risk. - type: bool - default: no - version_added: '2.8' - allow_prerelease: - description: - - Allow the installation of pre-release packages. - - If I(state) is C(latest), the latest pre-release package will be - installed. - type: bool - default: no - version_added: '2.6' - architecture: - description: - - Force Chocolatey to install the package of a specific process - architecture. - - When setting C(x86), will ensure Chocolatey installs the x86 package - even when on an x64 bit OS. - type: str - choices: [ default, x86 ] - default: default - version_added: '2.7' - force: - description: - - Forces the install of a package, even if it already is installed. - - Using I(force) will cause Ansible to always report that a change was - made. - type: bool - default: no - ignore_checksums: - description: - - Ignore the checksums provided by the package. - - Use M(win_chocolatey_feature) with the name C(checksumFiles) to control - this option globally. - type: bool - default: no - version_added: '2.2' - ignore_dependencies: - description: - - Ignore dependencies, only install/upgrade the package itself. - type: bool - default: no - version_added: '2.1' - install_args: - description: - - Arguments to pass to the native installer. - - These are arguments that are passed directly to the installer the - Chocolatey package runs, this is generally an advanced option. - type: str - version_added: '2.1' - name: - description: - - Name of the package(s) to be installed. - - Set to C(all) to run the action on all the installed packages. - type: list - required: yes - override_args: - description: - - Override arguments of native installer with arguments provided by user. - - Should install arguments be used exclusively without appending - to current package passed arguments. - type: bool - version_added: '2.10' - package_params: - description: - - Parameters to pass to the package. - - These are parameters specific to the Chocolatey package and are generally - documented by the package itself. - - Before Ansible 2.7, this option was just I(params). - type: str - version_added: '2.1' - aliases: [ params ] - pinned: - description: - - Whether to pin the Chocolatey package or not. - - If omitted then no checks on package pins are done. - - Will pin/unpin the specific version if I(version) is set. - - Will pin the latest version of a package if C(yes), I(version) is not set - and and no pin already exists. - - Will unpin all versions of a package if C(no) and I(version) is not set. - - This is ignored when C(state=absent). - type: bool - version_added: '2.8' - proxy_url: - description: - - Proxy URL used to install chocolatey and the package. - - Use M(win_chocolatey_config) with the name C(proxy) to control this - option globally. - type: str - version_added: '2.4' - proxy_username: - description: - - Proxy username used to install Chocolatey and the package. - - Before Ansible 2.7, users with double quote characters C(") would need to - be escaped with C(\) beforehand. This is no longer necessary. - - Use M(win_chocolatey_config) with the name C(proxyUser) to control this - option globally. - type: str - version_added: '2.4' - proxy_password: - description: - - Proxy password used to install Chocolatey and the package. - - This value is exposed as a command argument and any privileged account - can see this value when the module is running Chocolatey, define the - password on the global config level with M(win_chocolatey_config) with - name C(proxyPassword) to avoid this. - type: str - version_added: '2.4' - skip_scripts: - description: - - Do not run I(chocolateyInstall.ps1) or I(chocolateyUninstall.ps1) scripts - when installing a package. - type: bool - default: no - version_added: '2.4' - source: - description: - - Specify the source to retrieve the package from. - - Use M(win_chocolatey_source) to manage global sources. - - This value can either be the URL to a Chocolatey feed, a path to a folder - containing C(.nupkg) packages or the name of a source defined by - M(win_chocolatey_source). - - This value is also used when Chocolatey is not installed as the location - of the install.ps1 script and only supports URLs for this case. - type: str - source_username: - description: - - A username to use with I(source) when accessing a feed that requires - authentication. - - It is recommended you define the credentials on a source with - M(win_chocolatey_source) instead of passing it per task. - type: str - version_added: '2.7' - source_password: - description: - - The password for I(source_username). - - This value is exposed as a command argument and any privileged account - can see this value when the module is running Chocolatey, define the - credentials with a source with M(win_chocolatey_source) to avoid this. - type: str - version_added: '2.7' - state: - description: - - State of the package on the system. - - When C(absent), will ensure the package is not installed. - - When C(present), will ensure the package is installed. - - When C(downgrade), will allow Chocolatey to downgrade a package if - I(version) is older than the installed version. - - When C(latest), will ensure the package is installed to the latest - available version. - - When C(reinstalled), will uninstall and reinstall the package. - type: str - choices: [ absent, downgrade, latest, present, reinstalled ] - default: present - timeout: - description: - - The time to allow chocolatey to finish before timing out. - type: int - default: 2700 - version_added: '2.3' - aliases: [ execution_timeout ] - validate_certs: - description: - - Used when downloading the Chocolatey install script if Chocolatey is not - already installed, this does not affect the Chocolatey package install - process. - - When C(no), no SSL certificates will be validated. - - This should only be used on personally controlled sites using self-signed - certificate. - type: bool - default: yes - version_added: '2.7' - version: - description: - - Specific version of the package to be installed. - - When I(state) is set to C(absent), will uninstall the specific version - otherwise all versions of that package will be removed. - - If a different version of package is installed, I(state) must be C(latest) - or I(force) set to C(yes) to install the desired version. - - Provide as a string (e.g. C('6.1')), otherwise it is considered to be - a floating-point number and depending on the locale could become C(6,1), - which will cause a failure. - - If I(name) is set to C(chocolatey) and Chocolatey is not installed on the - host, this will be the version of Chocolatey that is installed. You can - also set the C(chocolateyVersion) environment var. - type: str -notes: -- This module will install or upgrade Chocolatey when needed. -- When using verbosity 2 or less (C(-vv)) the C(stdout) output will be restricted. - When using verbosity 4 (C(-vvvv)) the C(stdout) output will be more verbose. - When using verbosity 5 (C(-vvvvv)) the C(stdout) output will include debug output. -- Some packages, like hotfixes or updates need an interactive user logon in - order to install. You can use C(become) to achieve this, see - :ref:`become_windows`. - Even if you are connecting as local Administrator, using C(become) to - become Administrator will give you an interactive user logon, see examples - below. -- If C(become) is unavailable, use M(win_hotfix) to install hotfixes instead - of M(win_chocolatey) as M(win_hotfix) avoids using C(wusa.exe) which cannot - be run without C(become). -seealso: -- module: win_chocolatey_config -- module: win_chocolatey_facts -- module: win_chocolatey_feature -- module: win_chocolatey_source -- module: win_feature -- module: win_hotfix - description: Use when C(become) is unavailable, to avoid using C(wusa.exe). -- module: win_package -- module: win_updates -- name: Chocolatey website - description: More information about the Chocolatey tool. - link: http://chocolatey.org/ -- name: Chocolatey packages - description: An overview of the available Chocolatey packages. - link: http://chocolatey.org/packages -- ref: become_windows - description: Some packages, like hotfixes or updates need an interactive user logon - in order to install. You can use C(become) to achieve this. -author: -- Trond Hindenes (@trondhindenes) -- Peter Mounce (@petemounce) -- Pepe Barbe (@elventear) -- Adam Keech (@smadam813) -- Pierre Templier (@ptemplier) -- Jordan Borean (@jborean93) -''' - -# TODO: -# * Better parsing when a package has dependencies - currently fails -# * Time each item that is run -# * Support 'changed' with gems - would require shelling out to `gem list` first and parsing, kinda defeating the point of using chocolatey. -# * Version provided not as string might be translated to 6,6 depending on Locale (results in errors) - -EXAMPLES = r''' -- name: Install git - win_chocolatey: - name: git - state: present - -- name: Upgrade installed packages - win_chocolatey: - name: all - state: latest - -- name: Install notepadplusplus version 6.6 - win_chocolatey: - name: notepadplusplus - version: '6.6' - -- name: Install notepadplusplus 32 bit version - win_chocolatey: - name: notepadplusplus - architecture: x86 - -- name: Install git from specified repository - win_chocolatey: - name: git - source: https://someserver/api/v2/ - -- name: Install git from a pre configured source (win_chocolatey_source) - win_chocolatey: - name: git - source: internal_repo - -- name: Ensure Chocolatey itself is installed and use internal repo as source - win_chocolatey: - name: chocolatey - source: http://someserver/chocolatey - -- name: Uninstall git - win_chocolatey: - name: git - state: absent - -- name: Install multiple packages - win_chocolatey: - name: - - procexp - - putty - - windirstat - state: present - -- name: Install multiple packages sequentially - win_chocolatey: - name: '{{ item }}' - state: present - loop: - - procexp - - putty - - windirstat - -- name: Uninstall multiple packages - win_chocolatey: - name: - - procexp - - putty - - windirstat - state: absent - -- name: Install curl using proxy - win_chocolatey: - name: curl - proxy_url: http://proxy-server:8080/ - proxy_username: joe - proxy_password: p@ssw0rd - -- name: Install a package that requires 'become' - win_chocolatey: - name: officepro2013 - become: yes - become_user: Administrator - become_method: runas - -- name: install and pin Notepad++ at 7.6.3 - win_chocolatey: - name: notepadplusplus - version: 7.6.3 - pinned: yes - state: present - -- name: remove all pins for Notepad++ on all versions - win_chocolatey: - name: notepadplusplus - pinned: no - state: present -''' - -RETURN = r''' -command: - description: The full command used in the chocolatey task. - returned: changed - type: str - sample: choco.exe install -r --no-progress -y sysinternals --timeout 2700 --failonunfound -rc: - description: The return code from the chocolatey task. - returned: always - type: int - sample: 0 -stdout: - description: The stdout from the chocolatey task. The verbosity level of the - messages are affected by Ansible verbosity setting, see notes for more - details. - returned: changed - type: str - sample: Chocolatey upgraded 1/1 packages. -''' diff --git a/lib/ansible/modules/windows/win_chocolatey_config.ps1 b/lib/ansible/modules/windows/win_chocolatey_config.ps1 deleted file mode 100644 index 119b12648d0..00000000000 --- a/lib/ansible/modules/windows/win_chocolatey_config.ps1 +++ /dev/null @@ -1,122 +0,0 @@ -#!powershell - -# Copyright: (c) 2018, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.ArgvParser -#Requires -Module Ansible.ModuleUtils.CommandUtil -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "absent", "present" -$value = Get-AnsibleParam -obj $params -name "value" -type "str" -failifempty ($state -eq "present") - -$result = @{ - changed = $false -} -if ($diff) { - $result.diff = @{ - before = $null - after = $null - } -} - -if ($state -eq "present") { - if ($value -eq "") { - Fail-Json -obj $result -message "Cannot set Chocolatey config as an empty string when state=present, use state=absent instead" - } - # make sure bool values are lower case - if ($value -ceq "True" -or $value -ceq "False") { - $value = $value.ToLower() - } -} - -Function Get-ChocolateyConfig { - param($choco_app) - - # 'choco config list -r' does not display an easily parsable config entries - # It contains config/sources/feature in the one command, and is in the - # structure 'configKey = configValue | description', if the key or value - # contains a = or |, it will make it quite hard to easily parse it, - # compared to reading an XML file that already delimits these values - $choco_config_path = "$(Split-Path -Path (Split-Path -Path $choco_app.Path))\config\chocolatey.config" - if (-not (Test-Path -Path $choco_config_path)) { - Fail-Json -obj $result -message "Expecting Chocolatey config file to exist at '$choco_config_path'" - } - - try { - [xml]$choco_config = Get-Content -Path $choco_config_path - } catch { - Fail-Json -obj $result -message "Failed to parse Chocolatey config file at '$choco_config_path': $($_.Exception.Message)" - } - - $config_info = @{} - foreach ($config in $choco_config.chocolatey.config.GetEnumerator()) { - $config_info."$($config.key)" = $config.value - } - - return ,$config_info -} - -Function Remove-ChocolateyConfig { - param( - $choco_app, - $name - ) - $command = Argv-ToString -arguments @($choco_app.Path, "config", "unset", "--name", $name) - $res = Run-Command -command $command - if ($res.rc -ne 0) { - Fail-Json -obj $result -message "Failed to unset Chocolatey config for '$name': $($res.stderr)" - } -} - -Function Set-ChocolateyConfig { - param( - $choco_app, - $name, - $value - ) - $command = Argv-ToString -arguments @($choco_app.Path, "config", "set", "--name", $name, "--value", $value) - $res = Run-Command -command $command - if ($res.rc -ne 0) { - Fail-Json -obj $result -message "Failed to set Chocolatey config for '$name' to '$value': $($res.stderr)" - } -} - -$choco_app = Get-Command -Name choco.exe -CommandType Application -ErrorAction SilentlyContinue -if (-not $choco_app) { - Fail-Json -obj $result -message "Failed to find Chocolatey installation, make sure choco.exe is in the PATH env value" -} - -$config_info = Get-ChocolateyConfig -choco_app $choco_app -if ($name -notin $config_info.Keys) { - Fail-Json -obj $result -message "The Chocolatey config '$name' is not an existing config value, check the spelling. Valid config names: $($config_info.Keys -join ', ')" -} -if ($diff) { - $result.diff.before = $config_info.$name -} - -if ($state -eq "absent" -and $config_info.$name -ne "") { - if (-not $check_mode) { - Remove-ChocolateyConfig -choco_app $choco_app -name $name - } - $result.changed = $true -# choco.exe config set is not case sensitive, it won't make a change if the -# value is the same but doesn't match -} elseif ($state -eq "present" -and $config_info.$name -ne $value) { - if (-not $check_mode) { - Set-ChocolateyConfig -choco_app $choco_app -name $name -value $value - } - $result.changed = $true - if ($diff) { - $result.diff.after = $value - } -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_chocolatey_config.py b/lib/ansible/modules/windows/win_chocolatey_config.py deleted file mode 100644 index 1d20bab311f..00000000000 --- a/lib/ansible/modules/windows/win_chocolatey_config.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_chocolatey_config -version_added: '2.7' -short_description: Manages Chocolatey config settings -description: -- Used to manage Chocolatey config settings as well as unset the values. -options: - name: - description: - - The name of the config setting to manage. - - See U(https://chocolatey.org/docs/chocolatey-configuration) for a list of - valid configuration settings that can be changed. - - Any config values that contain encrypted values like a password are not - idempotent as the plaintext value cannot be read. - type: str - required: yes - state: - description: - - When C(absent), it will ensure the setting is unset or blank. - - When C(present), it will ensure the setting is set to the value of - I(value). - type: str - choices: [ absent, present ] - default: present - value: - description: - - Used when C(state=present) that contains the value to set for the config - setting. - - Cannot be null or an empty string, use C(state=absent) to unset a config - value instead. - type: str -seealso: -- module: win_chocolatey -- module: win_chocolatey_facts -- module: win_chocolatey_feature -- module: win_chocolatey_source -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Set the cache location - win_chocolatey_config: - name: cacheLocation - state: present - value: D:\chocolatey_temp - -- name: Unset the cache location - win_chocolatey_config: - name: cacheLocation - state: absent -''' - -RETURN = r''' -''' diff --git a/lib/ansible/modules/windows/win_chocolatey_facts.ps1 b/lib/ansible/modules/windows/win_chocolatey_facts.ps1 deleted file mode 100644 index fdbdc96725f..00000000000 --- a/lib/ansible/modules/windows/win_chocolatey_facts.ps1 +++ /dev/null @@ -1,182 +0,0 @@ -#!powershell - -# Copyright: (c) 2018, Ansible Project -# Copyright: (c) 2018, Simon Baerlocher -# Copyright: (c) 2018, ITIGO AG -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.ArgvParser -#Requires -Module Ansible.ModuleUtils.CommandUtil -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" -Set-StrictMode -Version 2.0 - -# Create a new result object -$result = @{ - changed = $false - ansible_facts = @{ - ansible_chocolatey = @{ - config = @{} - feature = @{} - sources = @() - packages = @() - } - } -} - -$choco_app = Get-Command -Name choco.exe -CommandType Application -ErrorAction SilentlyContinue -if (-not $choco_app) { - Fail-Json -obj $result -message "Failed to find Chocolatey installation, make sure choco.exe is in the PATH env value" -} - -Function Get-ChocolateyFeature { - - param($choco_app) - - $command = Argv-ToString -arguments $choco_app.Path, "feature", "list", "-r" - $res = Run-Command -command $command - if ($res.rc -ne 0) { - $result.stdout = $res.stdout - $result.stderr = $res.stderr - $result.rc = $res.rc - Fail-Json -obj $result -message "Failed to list Chocolatey features, see stderr" - } - - $feature_info = @{} - $res.stdout -split "`r`n" | Where-Object { $_ -ne "" } | ForEach-Object { - $feature_split = $_ -split "\|" - $feature_info."$($feature_split[0])" = $feature_split[1] -eq "Enabled" - } - $result.ansible_facts.ansible_chocolatey.feature = $feature_info -} - -Function Get-ChocolateyConfig { - - param($choco_app) - - $choco_config_path = "$(Split-Path -Path (Split-Path -Path $choco_app.Path))\config\chocolatey.config" - if (-not (Test-Path -Path $choco_config_path)) { - Fail-Json -obj $result -message "Expecting Chocolatey config file to exist at '$choco_config_path'" - } - - try { - [xml]$choco_config = Get-Content -Path $choco_config_path - } catch { - Fail-Json -obj $result -message "Failed to parse Chocolatey config file at '$choco_config_path': $($_.Exception.Message)" - } - - $config_info = @{} - foreach ($config in $choco_config.chocolatey.config.GetEnumerator()) { - # try and parse as a boot, then an int, fallback to string - try { - $value = [System.Boolean]::Parse($config.value) - } catch { - try { - $value = [System.Int32]::Parse($config.value) - } catch { - $value = $config.value - } - } - $config_info."$($config.key)" = $value - } - $result.ansible_facts.ansible_chocolatey.config = $config_info -} - -Function Get-ChocolateyPackages { - - param($choco_app) - - $command = Argv-ToString -arguments $choco_app.Path, "list", "--local-only", "--limit-output", "--all-versions" - $res = Run-Command -command $command - if ($res.rc -ne 0) { - $result.stdout = $res.stdout - $result.stderr = $res.stderr - $result.rc = $res.rc - Fail-Json -obj $result -message "Failed to list Chocolatey Packages, see stderr" - } - - $packages_info = [System.Collections.ArrayList]@() - $res.stdout.Split("`r`n", [System.StringSplitOptions]::RemoveEmptyEntries) | ForEach-Object { - $packages_split = $_ -split "\|" - $package_info = @{ - package = $packages_split[0] - version = $packages_split[1] - } - $packages_info.Add($package_info) > $null - } - $result.ansible_facts.ansible_chocolatey.packages = $packages_info -} - -Function Get-ChocolateySources { - param($choco_app) - - $choco_config_path = "$(Split-Path -Path (Split-Path -Path $choco_app.Path))\config\chocolatey.config" - if (-not (Test-Path -LiteralPath $choco_config_path)) { - Fail-Json -obj $result -message "Expecting Chocolatey config file to exist at '$choco_config_path'" - } - - try { - [xml]$choco_config = Get-Content -Path $choco_config_path - } catch { - Fail-Json -obj $result -message "Failed to parse Chocolatey config file at '$choco_config_path': $($_.Exception.Message)" - } - - $sources = [System.Collections.ArrayList]@() - foreach ($xml_source in $choco_config.chocolatey.sources.GetEnumerator()) { - $source_username = $xml_source.Attributes.GetNamedItem("user") - if ($null -ne $source_username) { - $source_username = $source_username.Value - } - - # 0.9.9.9+ - $priority = $xml_source.Attributes.GetNamedItem("priority") - if ($null -ne $priority) { - $priority = [int]$priority.Value - } - - # 0.9.10+ - $certificate = $xml_source.Attributes.GetNamedItem("certificate") - if ($null -ne $certificate) { - $certificate = $certificate.Value - } - - # 0.10.4+ - $bypass_proxy = $xml_source.Attributes.GetNamedItem("bypassProxy") - if ($null -ne $bypass_proxy) { - $bypass_proxy = [System.Convert]::ToBoolean($bypass_proxy.Value) - } - $allow_self_service = $xml_source.Attributes.GetNamedItem("selfService") - if ($null -ne $allow_self_service) { - $allow_self_service = [System.Convert]::ToBoolean($allow_self_service.Value) - } - - # 0.10.8+ - $admin_only = $xml_source.Attributes.GetNamedItem("adminOnly") - if ($null -ne $admin_only) { - $admin_only = [System.Convert]::ToBoolean($admin_only.Value) - } - - $source_info = @{ - name = $xml_source.id - source = $xml_source.value - disabled = [System.Convert]::ToBoolean($xml_source.disabled) - source_username = $source_username - priority = $priority - certificate = $certificate - bypass_proxy = $bypass_proxy - allow_self_service = $allow_self_service - admin_only = $admin_only - } - $sources.Add($source_info) > $null - } - $result.ansible_facts.ansible_chocolatey.sources = $sources -} - -Get-ChocolateyConfig -choco_app $choco_app -Get-ChocolateyFeature -choco_app $choco_app -Get-ChocolateyPackages -choco_app $choco_app -Get-ChocolateySources -choco_app $choco_app - -# Return result -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_chocolatey_facts.py b/lib/ansible/modules/windows/win_chocolatey_facts.py deleted file mode 100644 index d35f14d012a..00000000000 --- a/lib/ansible/modules/windows/win_chocolatey_facts.py +++ /dev/null @@ -1,144 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Ansible Project -# Copyright: (c) 2018, Simon Baerlocher -# Copyright: (c) 2018, ITIGO AG -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_chocolatey_facts -version_added: '2.8' -short_description: Create a facts collection for Chocolatey -description: -- This module shows information from Chocolatey, such as installed packages, configuration, feature and sources. -notes: -- Chocolatey must be installed beforehand, use M(win_chocolatey) to do this. -seealso: -- module: win_chocolatey -- module: win_chocolatey_config -- module: win_chocolatey_feature -- module: win_chocolatey_source -author: -- Simon Bärlocher (@sbaerlocher) -- ITIGO AG (@itigoag) -''' - -EXAMPLES = r''' -- name: Gather facts from chocolatey - win_chocolatey_facts: - -- name: Displays the Configuration - debug: - var: ansible_chocolatey.config - -- name: Displays the Feature - debug: - var: ansible_chocolatey.feature - -- name: Displays the Sources - debug: - var: ansible_chocolatey.sources - -- name: Displays the Packages - debug: - var: ansible_chocolatey.packages -''' - -RETURN = r''' -ansible_facts: - description: Detailed information about the Chocolatey installation - returned: always - type: complex - contains: - ansible_chocolatey: - description: Detailed information about the Chocolatey installation - returned: always - type: complex - contains: - config: - description: Detailed information about stored the configurations - returned: always - type: dict - sample: - commandExecutionTimeoutSeconds: 2700 - containsLegacyPackageInstalls: true - feature: - description: Detailed information about enabled and disabled features - returned: always - type: dict - sample: - allowEmptyCheckums: false - autoUninstaller: true - failOnAutoUninstaller: false - sources: - description: List of Chocolatey sources - returned: always - type: complex - contains: - admin_only: - description: Is the source visible to Administrators only - returned: always - type: bool - sample: false - allow_self_service: - description: Is the source allowed to be used with self-service - returned: always - type: bool - sample: false - bypass_proxy: - description: Can the source explicitly bypass configured proxies - returned: always - type: bool - sample: true - certificate: - description: Path to a PFX certificate for X509 authenticated feeds - returned: always - type: str - sample: C:\chocolatey\cert.pfx - disabled: - description: Is the source disabled - returned: always - type: bool - sample: false - name: - description: Name of the source - returned: always - type: str - sample: chocolatey - priority: - description: The priority order of this source, lower is better, 0 is no priority - returned: always - type: int - sample: 0 - source: - description: The source, can be a folder/file or an url - returned: always - type: str - sample: https://chocolatey.org/api/v2/ - source_username: - description: Username used to access authenticated feeds - returned: always - type: str - sample: username - packages: - description: List of installed Packages - returned: always - type: complex - contains: - package: - description: Name of the package - returned: always - type: str - sample: vscode - version: - description: Version of the package - returned: always - type: str - sample: '1.27.2' -''' diff --git a/lib/ansible/modules/windows/win_chocolatey_feature.ps1 b/lib/ansible/modules/windows/win_chocolatey_feature.ps1 deleted file mode 100644 index a33378cd6a7..00000000000 --- a/lib/ansible/modules/windows/win_chocolatey_feature.ps1 +++ /dev/null @@ -1,74 +0,0 @@ -#!powershell - -# Copyright: (c), 2018 Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.CommandUtil -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "enabled" -validateset "disabled", "enabled" - -$result = @{ - changed = $false -} - -Function Get-ChocolateyFeatures { - param($choco_app) - - $res = Run-Command -command "`"$($choco_app.Path)`" feature list -r" - if ($res.rc -ne 0) { - Fail-Json -obj $result -message "Failed to list Chocolatey features: $($res.stderr)" - } - $feature_info = @{} - $res.stdout -split "`r`n" | Where-Object { $_ -ne "" } | ForEach-Object { - $feature_split = $_ -split "\|" - $feature_info."$($feature_split[0])" = $feature_split[1] -eq "Enabled" - } - - return ,$feature_info -} - -Function Set-ChocolateyFeature { - param( - $choco_app, - $name, - $enabled - ) - - if ($enabled) { - $state_string = "enable" - } else { - $state_string = "disable" - } - $res = Run-Command -command "`"$($choco_app.Path)`" feature $state_string --name `"$name`"" - if ($res.rc -ne 0) { - Fail-Json -obj $result -message "Failed to set Chocolatey feature $name to $($state_string): $($res.stderr)" - } -} - -$choco_app = Get-Command -Name choco.exe -CommandType Application -ErrorAction SilentlyContinue -if (-not $choco_app) { - Fail-Json -obj $result -message "Failed to find Chocolatey installation, make sure choco.exe is in the PATH env value" -} - -$feature_info = Get-ChocolateyFeatures -choco_app $choco_app -if ($name -notin $feature_info.keys) { - Fail-Json -obj $result -message "Invalid feature name '$name' specified, valid features are: $($feature_info.keys -join ', ')" -} - -$expected_status = $state -eq "enabled" -$feature_status = $feature_info.$name -if ($feature_status -ne $expected_status) { - if (-not $check_mode) { - Set-ChocolateyFeature -choco_app $choco_app -name $name -enabled $expected_status - } - $result.changed = $true -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_chocolatey_feature.py b/lib/ansible/modules/windows/win_chocolatey_feature.py deleted file mode 100644 index 13358f4e1ee..00000000000 --- a/lib/ansible/modules/windows/win_chocolatey_feature.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_chocolatey_feature -version_added: '2.7' -short_description: Manages Chocolatey features -description: -- Used to enable or disable features in Chocolatey. -options: - name: - description: - - The name of the feature to manage. - - Run C(choco.exe feature list) to get a list of features that can be - managed. - type: str - required: yes - state: - description: - - When C(disabled) then the feature will be disabled. - - When C(enabled) then the feature will be enabled. - type: str - choices: [ disabled, enabled ] - default: enabled -seealso: -- module: win_chocolatey -- module: win_chocolatey_config -- module: win_chocolatey_facts -- module: win_chocolatey_source -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Disable file checksum matching - win_chocolatey_feature: - name: checksumFiles - state: disabled - -- name: Stop Chocolatey on the first package failure - win_chocolatey_feature: - name: stopOnFirstPackageFailure - state: enabled -''' - -RETURN = r''' -''' diff --git a/lib/ansible/modules/windows/win_chocolatey_source.ps1 b/lib/ansible/modules/windows/win_chocolatey_source.ps1 deleted file mode 100644 index c2360f153ab..00000000000 --- a/lib/ansible/modules/windows/win_chocolatey_source.ps1 +++ /dev/null @@ -1,306 +0,0 @@ -#!powershell - -# Copyright: (c) 2018, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.ArgvParser -#Requires -Module Ansible.ModuleUtils.CommandUtil -#Requires -Module Ansible.ModuleUtils.Legacy - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "absent", "disabled", "present" - -$admin_only = Get-AnsibleParam -obj $params -name "admin_only" -type "bool" -$allow_self_service = Get-AnsibleParam -obj $params -name "allow_self_service" -type "bool" -$bypass_proxy = Get-AnsibleParam -obj $params -name "bypass_proxy" -type "bool" -$certificate = Get-AnsibleParam -obj $params -name "certificate" -type "str" -$certificate_password = Get-AnsibleParam -obj $params -name "certificate_password" -type "str" -$priority = Get-AnsibleParam -obj $params -name "priority" -type "int" -$source = Get-AnsibleParam -obj $params -name "source" -type "str" -$source_username = Get-AnsibleParam -obj $params -name "source_username" -type "str" -$source_password = Get-AnsibleParam -obj $params -name "source_password" -type "str" -failifempty ($null -ne $source_username) -$update_password = Get-AnsibleParam -obj $params -name "update_password" -type "str" -default "always" -validateset "always", "on_create" - -$result = @{ - changed = $false -} -if ($diff) { - $result.diff = @{ - before = @{} - after = @{} - } -} - -Function Get-ChocolateySources { - param($choco_app) - - $choco_config_path = "$(Split-Path -Path (Split-Path -Path $choco_app.Path))\config\chocolatey.config" - if (-not (Test-Path -LiteralPath $choco_config_path)) { - Fail-Json -obj $result -message "Expecting Chocolatey config file to exist at '$choco_config_path'" - } - - # would prefer to enumerate the existing sources with an actual API but the - # only stable interface is choco.exe source list and that does not output - # the sources in an easily parsable list. Using -r will split each entry by - # | like a psv but does not quote values that have a | already in it making - # it inadequete for our tasks. Instead we will parse the chocolatey.config - # file and get the values from there - try { - [xml]$choco_config = Get-Content -Path $choco_config_path - } catch { - Fail-Json -obj $result -message "Failed to parse Chocolatey config file at '$choco_config_path': $($_.Exception.Message)" - } - - $sources = [System.Collections.ArrayList]@() - foreach ($xml_source in $choco_config.chocolatey.sources.GetEnumerator()) { - $source_username = $xml_source.Attributes.GetNamedItem("user") - if ($null -ne $source_username) { - $source_username = $source_username.Value - } - - # 0.9.9.9+ - $priority = $xml_source.Attributes.GetNamedItem("priority") - if ($null -ne $priority) { - $priority = [int]$priority.Value - } - - # 0.9.10+ - $certificate = $xml_source.Attributes.GetNamedItem("certificate") - if ($null -ne $certificate) { - $certificate = $certificate.Value - } - - # 0.10.4+ - $bypass_proxy = $xml_source.Attributes.GetNamedItem("bypassProxy") - if ($null -ne $bypass_proxy) { - $bypass_proxy = [System.Convert]::ToBoolean($bypass_proxy.Value) - } - $allow_self_service = $xml_source.Attributes.GetNamedItem("selfService") - if ($null -ne $allow_self_service) { - $allow_self_service = [System.Convert]::ToBoolean($allow_self_service.Value) - } - - # 0.10.8+ - $admin_only = $xml_source.Attributes.GetNamedItem("adminOnly") - if ($null -ne $admin_only) { - $admin_only = [System.Convert]::ToBoolean($admin_only.Value) - } - - $source_info = @{ - name = $xml_source.id - source = $xml_source.value - disabled = [System.Convert]::ToBoolean($xml_source.disabled) - source_username = $source_username - priority = $priority - certificate = $certificate - bypass_proxy = $bypass_proxy - allow_self_service = $allow_self_service - admin_only = $admin_only - } - $sources.Add($source_info) > $null - } - return ,$sources -} - -Function New-ChocolateySource { - param( - $choco_app, - $name, - $source, - $source_username, - $source_password, - $certificate, - $certificate_password, - $priority, - $bypass_proxy, - $allow_self_service, - $admin_only - ) - # build the base arguments - $arguments = [System.Collections.ArrayList]@($choco_app.Path, - "source", "add", "--name", $name, "--source", $source - ) - - # add optional arguments from user input - if ($null -ne $source_username) { - $arguments.Add("--user") > $null - $arguments.Add($source_username) > $null - $arguments.Add("--password") > $null - $arguments.Add($source_password) > $null - } - if ($null -ne $certificate) { - $arguments.Add("--cert") > $null - $arguments.Add($certificate) > $null - } - if ($null -ne $certificate_password) { - $arguments.Add("--certpassword") > $null - $arguments.Add($certificate_password) > $null - } - if ($null -ne $priority) { - $arguments.Add("--priority") > $null - $arguments.Add($priority) > $null - } else { - $priority = 0 - } - if ($bypass_proxy -eq $true) { - $arguments.Add("--bypass-proxy") > $null - } else { - $bypass_proxy = $false - } - if ($allow_self_service -eq $true) { - $arguments.Add("--allow-self-service") > $null - } else { - $allow_self_service = $false - } - if ($admin_only -eq $true) { - $arguments.Add("--admin-only") > $null - } else { - $admin_only = $false - } - - if ($check_mode) { - $arguments.Add("--what-if") > $null - } - - $command = Argv-ToString -arguments $arguments - $res = Run-Command -command $command - if ($res.rc -ne 0) { - Fail-Json -obj $result -message "Failed to add Chocolatey source '$name': $($res.stderr)" - } - - $source_info = @{ - name = $name - source = $source - disabled = $false - source_username = $source_username - priority = $priority - certificate = $certificate - bypass_proxy = $bypass_proxy - allow_self_service = $allow_self_service - admin_only = $admin_only - } - return ,$source_info -} - -Function Remove-ChocolateySource { - param( - $choco_app, - $name - ) - $arguments = [System.Collections.ArrayList]@($choco_app.Path, "source", "remove", "--name", $name) - if ($check_mode) { - $arguments.Add("--what-if") > $null - } - $command = Argv-ToString -arguments $arguments - $res = Run-Command -command $command - if ($res.rc -ne 0) { - Fail-Json -obj $result -message "Failed to remove Chocolatey source '$name': $($_.res.stderr)" - } -} - -$choco_app = Get-Command -Name choco.exe -CommandType Application -ErrorAction SilentlyContinue -if (-not $choco_app) { - Fail-Json -obj $result -message "Failed to find Chocolatey installation, make sure choco.exe is in the PATH env value" -} -$actual_sources = Get-ChocolateySources -choco_app $choco_app -$actual_source = $actual_sources | Where-Object { $_.name -eq $name } -if ($diff) { - if ($null -ne $actual_source) { - $before = $actual_source.Clone() - } else { - $before = @{} - } - $result.diff.before = $before -} - -if ($state -eq "absent" -and $null -ne $actual_source) { - Remove-ChocolateySource -choco_app $choco_app -name $name - $result.changed = $true -} elseif ($state -in ("disabled", "present")) { - $change = $false - if ($null -eq $actual_source) { - if ($null -eq $source) { - Fail-Json -obj $result -message "The source option must be set when creating a new source" - } - $change = $true - } else { - if ($null -ne $source -and $source -ne $actual_source.source) { - $change = $true - } - if ($null -ne $source_username -and $source_username -ne $actual_source.source_username) { - $change = $true - } - if ($null -ne $source_password -and $update_password -eq "always") { - $change = $true - } - if ($null -ne $certificate -and $certificate -ne $actual_source.certificate) { - $change = $true - } - if ($null -ne $certificate_password -and $update_password -eq "always") { - $change = $true - } - if ($null -ne $priority -and $priority -ne $actual_source.priority) { - $change = $true - } - if ($null -ne $bypass_proxy -and $bypass_proxy -ne $actual_source.bypass_proxy) { - $change = $true - } - if ($null -ne $allow_self_service -and $allow_self_service -ne $actual_source.allow_self_service) { - $change = $true - } - if ($null -ne $admin_only -and $admin_only -ne $actual_source.admin_only) { - $change = $true - } - - if ($change) { - Remove-ChocolateySource -choco_app $choco_app -name $name - $result.changed = $true - } - } - - if ($change) { - $actual_source = New-ChocolateySource -choco_app $choco_app -name $name -source $source ` - -source_username $source_username -source_password $source_password ` - -certificate $certificate -certificate_password $certificate_password ` - -priority $priority -bypass_proxy $bypass_proxy -allow_self_service $allow_self_service ` - -admin_only $admin_only - $result.changed = $true - } - - # enable/disable the source if necessary - $status_action = $null - if ($state -ne "disabled" -and $actual_source.disabled) { - $status_action = "enable" - } elseif ($state -eq "disabled" -and (-not $actual_source.disabled)) { - $status_action = "disable" - } - if ($null -ne $status_action) { - $arguments = [System.Collections.ArrayList]@($choco_app.Path, "source", $status_action, "--name", $name) - if ($check_mode) { - $arguments.Add("--what-if") > $null - } - $command = Argv-ToString -arguments $arguments - $res = Run-Command -command $command - if ($res.rc -ne 0) { - Fail-Json -obj $result -message "Failed to $status_action Chocolatey source '$name': $($res.stderr)" - } - $actual_source.disabled = ($status_action -eq "disable") - $result.changed = $true - } - - if ($diff) { - $after = $actual_source - $result.diff.after = $after - } -} - -# finally remove the diff if there was no change -if (-not $result.changed -and $diff) { - $result.diff = @{} -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_chocolatey_source.py b/lib/ansible/modules/windows/win_chocolatey_source.py deleted file mode 100644 index 0e1fc0f588e..00000000000 --- a/lib/ansible/modules/windows/win_chocolatey_source.py +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_chocolatey_source -version_added: '2.7' -short_description: Manages Chocolatey sources -description: -- Used to managed Chocolatey sources configured on the client. -- Requires Chocolatey to be already installed on the remote host. -options: - admin_only: - description: - - Makes the source visible to Administrators only. - - Requires Chocolatey >= 0.10.8. - - When creating a new source, this defaults to C(no). - type: bool - allow_self_service: - description: - - Allow the source to be used with self-service - - Requires Chocolatey >= 0.10.4. - - When creating a new source, this defaults to C(no). - type: bool - bypass_proxy: - description: - - Bypass the proxy when using this source. - - Requires Chocolatey >= 0.10.4. - - When creating a new source, this defaults to C(no). - type: bool - certificate: - description: - - The path to a .pfx file to use for X509 authenticated feeds. - - Requires Chocolatey >= 0.9.10. - type: str - certificate_password: - description: - - The password for I(certificate) if required. - - Requires Chocolatey >= 0.9.10. - name: - description: - - The name of the source to configure. - required: yes - priority: - description: - - The priority order of this source compared to other sources, lower is - better. - - All priorities above C(0) will be evaluated first, then zero-based values - will be evaluated in config file order. - - Requires Chocolatey >= 0.9.9.9. - - When creating a new source, this defaults to C(0). - type: int - source: - description: - - The file/folder/url of the source. - - Required when I(state) is C(present) or C(disabled) and the source does - not already exist. - source_username: - description: - - The username used to access I(source). - source_password: - description: - - The password for I(source_username). - - Required if I(source_username) is set. - state: - description: - - When C(absent), will remove the source. - - When C(disabled), will ensure the source exists but is disabled. - - When C(present), will ensure the source exists and is enabled. - choices: - - absent - - disabled - - present - default: present - update_password: - description: - - When C(always), the module will always set the password and report a - change if I(certificate_password) or I(source_password) is set. - - When C(on_create), the module will only set the password if the source - is being created. - choices: - - always - - on_create - default: always -seealso: -- module: win_chocolatey -- module: win_chocolatey_config -- module: win_chocolatey_facts -- module: win_chocolatey_feature -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Remove the default public source - win_chocolatey_source: - name: chocolatey - state: absent - -- name: Add new internal source - win_chocolatey_source: - name: internal repo - state: present - source: http://chocolatey-server/chocolatey - -- name: Create HTTP source with credentials - win_chocolatey_source: - name: internal repo - state: present - source: https://chocolatey-server/chocolatey - source_username: username - source_password: password - -- name: Disable Chocolatey source - win_chocolatey_source: - name: chocolatey - state: disabled -''' - -RETURN = r''' -''' diff --git a/lib/ansible/modules/windows/win_computer_description.ps1 b/lib/ansible/modules/windows/win_computer_description.ps1 deleted file mode 100644 index f1b75d1ab07..00000000000 --- a/lib/ansible/modules/windows/win_computer_description.ps1 +++ /dev/null @@ -1,54 +0,0 @@ -#!powershell - -# Copyright: (c) 2019, RusoSova -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#AnsibleRequires -OSVersion 6.1 - -$spec = @{ - options = @{ - owner = @{ type="str" } - organization = @{ type="str" } - description = @{ type="str" } - } - required_one_of = @( - ,@('owner', 'organization', 'description') - ) - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$owner = $module.Params.owner -$organization = $module.Params.organization -$description = $module.Params.description -$regPath="HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\" - -#Change description -if ($description -or $description -eq "") { - $descriptionObject=Get-CimInstance -class "Win32_OperatingSystem" - if ($description -cne $descriptionObject.description) { - Set-CimInstance -InputObject $descriptionObject -Property @{"Description"="$description"} -WhatIf:$module.CheckMode - $module.Result.changed = $true - } -} - -#Change owner -if ($owner -or $owner -eq "") { - $curentOwner=(Get-ItemProperty -LiteralPath $regPath -Name RegisteredOwner).RegisteredOwner - if ($curentOwner -cne $owner) { - Set-ItemProperty -LiteralPath $regPath -Name "RegisteredOwner" -Value $owner -WhatIf:$module.CheckMode - $module.Result.changed = $true - } -} - -#Change organization -if ($organization -or $organization -eq "") { - $curentOrganization=(Get-ItemProperty -LiteralPath $regPath -Name RegisteredOrganization).RegisteredOrganization - if ($curentOrganization -cne $organization) { - Set-ItemProperty -LiteralPath $regPath -Name "RegisteredOrganization" -Value $organization -WhatIf:$module.CheckMode - $module.Result.changed = $true - } -} -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_computer_description.py b/lib/ansible/modules/windows/win_computer_description.py deleted file mode 100644 index b8aa2761857..00000000000 --- a/lib/ansible/modules/windows/win_computer_description.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2019, RusoSova -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = { - 'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community' -} - -DOCUMENTATION = r''' ---- -module: win_computer_description -short_description: Set windows description, owner and organization -description: - - This module sets Windows description that is shown under My Computer properties. Module also sets - Windows license owner and organization. License information can be viewed by running winver commad. -options: - description: - description: - - String value to apply to Windows descripton. Specify value of "" to clear the value. - required: false - type: str - organization: - description: - - String value of organization that the Windows is licensed to. Specify value of "" to clear the value. - required: false - type: str - owner: - description: - - String value of the persona that the Windows is licensed to. Specify value of "" to clear the value. - required: false - type: str -version_added: '2.10' -author: - - RusoSova (@RusoSova) -''' - -EXAMPLES = r''' -- name: Set Windows description, owner and organization - win_computer_description: - description: Best Box - owner: RusoSova - organization: MyOrg - register: result - -- name: Set Windows description only - win_computer_description: - description: This is my Windows machine - register: result - -- name: Set organization and clear owner field - win_computer_description: - owner: '' - organization: Black Mesa - -- name: Clear organization, description and owner - win_computer_description: - organization: "" - owner: "" - description: "" - register: result -''' - -RETURN = r''' -# -''' diff --git a/lib/ansible/modules/windows/win_credential.ps1 b/lib/ansible/modules/windows/win_credential.ps1 deleted file mode 100644 index fdc83584f0f..00000000000 --- a/lib/ansible/modules/windows/win_credential.ps1 +++ /dev/null @@ -1,714 +0,0 @@ -#!powershell - -# Copyright: (c) 2018, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.AddType - -$spec = @{ - options = @{ - alias = @{ type = "str" } - attributes = @{ - type = "list" - elements = "dict" - options = @{ - name = @{ type = "str"; required = $true } - data = @{ type = "str" } - data_format = @{ type = "str"; default = "text"; choices = @("base64", "text") } - } - } - comment = @{ type = "str" } - name = @{ type = "str"; required = $true } - persistence = @{ type = "str"; default = "local"; choices = @("enterprise", "local") } - secret = @{ type = "str"; no_log = $true } - secret_format = @{ type = "str"; default = "text"; choices = @("base64", "text") } - state = @{ type = "str"; default = "present"; choices = @("absent", "present") } - type = @{ - type = "str" - required = $true - choices = @("domain_password", "domain_certificate", "generic_password", "generic_certificate") - } - update_secret = @{ type = "str"; default = "always"; choices = @("always", "on_create") } - username = @{ type = "str" } - } - required_if = @( - ,@("state", "present", @("username")) - ) - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$alias = $module.Params.alias -$attributes = $module.Params.attributes -$comment = $module.Params.comment -$name = $module.Params.name -$persistence = $module.Params.persistence -$secret = $module.Params.secret -$secret_format = $module.Params.secret_format -$state = $module.Params.state -$type = $module.Params.type -$update_secret = $module.Params.update_secret -$username = $module.Params.username - -$module.Diff.before = "" -$module.Diff.after = "" - -Add-CSharpType -AnsibleModule $module -References @' -using Microsoft.Win32.SafeHandles; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; -using System.Text; - -namespace Ansible.CredentialManager -{ - internal class NativeHelpers - { - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public class CREDENTIAL - { - public CredentialFlags Flags; - public CredentialType Type; - [MarshalAs(UnmanagedType.LPWStr)] public string TargetName; - [MarshalAs(UnmanagedType.LPWStr)] public string Comment; - public FILETIME LastWritten; - public UInt32 CredentialBlobSize; - public IntPtr CredentialBlob; - public CredentialPersist Persist; - public UInt32 AttributeCount; - public IntPtr Attributes; - [MarshalAs(UnmanagedType.LPWStr)] public string TargetAlias; - [MarshalAs(UnmanagedType.LPWStr)] public string UserName; - - public static explicit operator Credential(CREDENTIAL v) - { - byte[] secret = new byte[(int)v.CredentialBlobSize]; - if (v.CredentialBlob != IntPtr.Zero) - Marshal.Copy(v.CredentialBlob, secret, 0, secret.Length); - - List attributes = new List(); - if (v.AttributeCount > 0) - { - CREDENTIAL_ATTRIBUTE[] rawAttributes = new CREDENTIAL_ATTRIBUTE[v.AttributeCount]; - Credential.PtrToStructureArray(rawAttributes, v.Attributes); - attributes = rawAttributes.Select(x => (CredentialAttribute)x).ToList(); - } - - string userName = v.UserName; - if (v.Type == CredentialType.DomainCertificate || v.Type == CredentialType.GenericCertificate) - userName = Credential.UnmarshalCertificateCredential(userName); - - return new Credential - { - Type = v.Type, - TargetName = v.TargetName, - Comment = v.Comment, - LastWritten = (DateTimeOffset)v.LastWritten, - Secret = secret, - Persist = v.Persist, - Attributes = attributes, - TargetAlias = v.TargetAlias, - UserName = userName, - Loaded = true, - }; - } - } - - [StructLayout(LayoutKind.Sequential)] - public struct CREDENTIAL_ATTRIBUTE - { - [MarshalAs(UnmanagedType.LPWStr)] public string Keyword; - public UInt32 Flags; // Set to 0 and is reserved - public UInt32 ValueSize; - public IntPtr Value; - - public static explicit operator CredentialAttribute(CREDENTIAL_ATTRIBUTE v) - { - byte[] value = new byte[v.ValueSize]; - Marshal.Copy(v.Value, value, 0, (int)v.ValueSize); - - return new CredentialAttribute - { - Keyword = v.Keyword, - Flags = v.Flags, - Value = value, - }; - } - } - - [StructLayout(LayoutKind.Sequential)] - public struct FILETIME - { - internal UInt32 dwLowDateTime; - internal UInt32 dwHighDateTime; - - public static implicit operator long(FILETIME v) { return ((long)v.dwHighDateTime << 32) + v.dwLowDateTime; } - public static explicit operator DateTimeOffset(FILETIME v) { return DateTimeOffset.FromFileTime(v); } - public static explicit operator FILETIME(DateTimeOffset v) - { - return new FILETIME() - { - dwLowDateTime = (UInt32)v.ToFileTime(), - dwHighDateTime = ((UInt32)v.ToFileTime() >> 32), - }; - } - } - - [Flags] - public enum CredentialCreateFlags : uint - { - PreserveCredentialBlob = 1, - } - - [Flags] - public enum CredentialFlags - { - None = 0, - PromptNow = 2, - UsernameTarget = 4, - } - - public enum CredMarshalType : uint - { - CertCredential = 1, - UsernameTargetCredential, - BinaryBlobCredential, - UsernameForPackedCredential, - BinaryBlobForSystem, - } - } - - internal class NativeMethods - { - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool CredDeleteW( - [MarshalAs(UnmanagedType.LPWStr)] string TargetName, - CredentialType Type, - UInt32 Flags); - - [DllImport("advapi32.dll")] - public static extern void CredFree( - IntPtr Buffer); - - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool CredMarshalCredentialW( - NativeHelpers.CredMarshalType CredType, - SafeMemoryBuffer Credential, - out SafeCredentialBuffer MarshaledCredential); - - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool CredReadW( - [MarshalAs(UnmanagedType.LPWStr)] string TargetName, - CredentialType Type, - UInt32 Flags, - out SafeCredentialBuffer Credential); - - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool CredUnmarshalCredentialW( - [MarshalAs(UnmanagedType.LPWStr)] string MarshaledCredential, - out NativeHelpers.CredMarshalType CredType, - out SafeCredentialBuffer Credential); - - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool CredWriteW( - NativeHelpers.CREDENTIAL Credential, - NativeHelpers.CredentialCreateFlags Flags); - } - - internal class SafeCredentialBuffer : SafeHandleZeroOrMinusOneIsInvalid - { - public SafeCredentialBuffer() : base(true) { } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected override bool ReleaseHandle() - { - NativeMethods.CredFree(handle); - return true; - } - } - - internal class SafeMemoryBuffer : SafeHandleZeroOrMinusOneIsInvalid - { - public SafeMemoryBuffer() : base(true) { } - public SafeMemoryBuffer(int cb) : base(true) - { - base.SetHandle(Marshal.AllocHGlobal(cb)); - } - public SafeMemoryBuffer(IntPtr handle) : base(true) - { - base.SetHandle(handle); - } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected override bool ReleaseHandle() - { - Marshal.FreeHGlobal(handle); - return true; - } - } - - public class Win32Exception : System.ComponentModel.Win32Exception - { - private string _exception_msg; - public Win32Exception(string message) : this(Marshal.GetLastWin32Error(), message) { } - public Win32Exception(int errorCode, string message) : base(errorCode) - { - _exception_msg = String.Format("{0} - {1} (Win32 Error Code {2}: 0x{3})", message, base.Message, errorCode, errorCode.ToString("X8")); - } - public override string Message { get { return _exception_msg; } } - public static explicit operator Win32Exception(string message) { return new Win32Exception(message); } - } - - public enum CredentialPersist - { - Session = 1, - LocalMachine = 2, - Enterprise = 3, - } - - public enum CredentialType - { - Generic = 1, - DomainPassword = 2, - DomainCertificate = 3, - DomainVisiblePassword = 4, - GenericCertificate = 5, - DomainExtended = 6, - Maximum = 7, - MaximumEx = 1007, - } - - public class CredentialAttribute - { - public string Keyword; - public UInt32 Flags; - public byte[] Value; - } - - public class Credential - { - public CredentialType Type; - public string TargetName; - public string Comment; - public DateTimeOffset LastWritten; - public byte[] Secret; - public CredentialPersist Persist; - public List Attributes = new List(); - public string TargetAlias; - public string UserName; - - // Used to track whether the credential has been loaded into the store or not - public bool Loaded { get; internal set; } - - public void Delete() - { - if (!Loaded) - return; - - if (!NativeMethods.CredDeleteW(TargetName, Type, 0)) - throw new Win32Exception(String.Format("CredDeleteW({0}) failed", TargetName)); - Loaded = false; - } - - public void Write(bool preserveExisting) - { - string userName = UserName; - // Convert the certificate thumbprint to the string expected - if (Type == CredentialType.DomainCertificate || Type == CredentialType.GenericCertificate) - userName = Credential.MarshalCertificateCredential(userName); - - NativeHelpers.CREDENTIAL credential = new NativeHelpers.CREDENTIAL - { - Flags = NativeHelpers.CredentialFlags.None, - Type = Type, - TargetName = TargetName, - Comment = Comment, - LastWritten = new NativeHelpers.FILETIME(), - CredentialBlobSize = (UInt32)(Secret == null ? 0 : Secret.Length), - CredentialBlob = IntPtr.Zero, // Must be allocated and freed outside of this to ensure no memory leaks - Persist = Persist, - AttributeCount = (UInt32)(Attributes.Count), - Attributes = IntPtr.Zero, // Attributes must be allocated and freed outside of this to ensure no memory leaks - TargetAlias = TargetAlias, - UserName = userName, - }; - - using (SafeMemoryBuffer credentialBlob = new SafeMemoryBuffer((int)credential.CredentialBlobSize)) - { - if (Secret != null) - Marshal.Copy(Secret, 0, credentialBlob.DangerousGetHandle(), Secret.Length); - credential.CredentialBlob = credentialBlob.DangerousGetHandle(); - - // Store the CREDENTIAL_ATTRIBUTE value in a safe memory buffer and make sure we dispose in all cases - List attributeBuffers = new List(); - try - { - int attributeLength = Attributes.Sum(a => Marshal.SizeOf(typeof(NativeHelpers.CREDENTIAL_ATTRIBUTE))); - byte[] attributeBytes = new byte[attributeLength]; - int offset = 0; - foreach (CredentialAttribute attribute in Attributes) - { - SafeMemoryBuffer attributeBuffer = new SafeMemoryBuffer(attribute.Value.Length); - attributeBuffers.Add(attributeBuffer); - if (attribute.Value != null) - Marshal.Copy(attribute.Value, 0, attributeBuffer.DangerousGetHandle(), attribute.Value.Length); - - NativeHelpers.CREDENTIAL_ATTRIBUTE credentialAttribute = new NativeHelpers.CREDENTIAL_ATTRIBUTE - { - Keyword = attribute.Keyword, - Flags = attribute.Flags, - ValueSize = (UInt32)(attribute.Value == null ? 0 : attribute.Value.Length), - Value = attributeBuffer.DangerousGetHandle(), - }; - int attributeStructLength = Marshal.SizeOf(typeof(NativeHelpers.CREDENTIAL_ATTRIBUTE)); - - byte[] attrBytes = new byte[attributeStructLength]; - using (SafeMemoryBuffer tempBuffer = new SafeMemoryBuffer(attributeStructLength)) - { - Marshal.StructureToPtr(credentialAttribute, tempBuffer.DangerousGetHandle(), false); - Marshal.Copy(tempBuffer.DangerousGetHandle(), attrBytes, 0, attributeStructLength); - } - Buffer.BlockCopy(attrBytes, 0, attributeBytes, offset, attributeStructLength); - offset += attributeStructLength; - } - - using (SafeMemoryBuffer attributes = new SafeMemoryBuffer(attributeBytes.Length)) - { - if (attributeBytes.Length != 0) - { - Marshal.Copy(attributeBytes, 0, attributes.DangerousGetHandle(), attributeBytes.Length); - credential.Attributes = attributes.DangerousGetHandle(); - } - - NativeHelpers.CredentialCreateFlags createFlags = 0; - if (preserveExisting) - createFlags |= NativeHelpers.CredentialCreateFlags.PreserveCredentialBlob; - - if (!NativeMethods.CredWriteW(credential, createFlags)) - throw new Win32Exception(String.Format("CredWriteW({0}) failed", TargetName)); - } - } - finally - { - foreach (SafeMemoryBuffer attributeBuffer in attributeBuffers) - attributeBuffer.Dispose(); - } - } - Loaded = true; - } - - public static Credential GetCredential(string target, CredentialType type) - { - SafeCredentialBuffer buffer; - if (!NativeMethods.CredReadW(target, type, 0, out buffer)) - { - int lastErr = Marshal.GetLastWin32Error(); - - // Not running with Become so cannot manage the user's credentials - if (lastErr == 0x00000520) // ERROR_NO_SUCH_LOGON_SESSION - throw new InvalidOperationException("Failed to access the user's credential store, run the module with become"); - else if (lastErr == 0x00000490) // ERROR_NOT_FOUND - return null; - throw new Win32Exception(lastErr, "CredEnumerateW() failed"); - } - - using (buffer) - { - NativeHelpers.CREDENTIAL credential = (NativeHelpers.CREDENTIAL)Marshal.PtrToStructure( - buffer.DangerousGetHandle(), typeof(NativeHelpers.CREDENTIAL)); - return (Credential)credential; - } - } - - public static string MarshalCertificateCredential(string thumbprint) - { - // CredWriteW requires the UserName field to be the value of CredMarshalCredentialW() when writting a - // certificate auth. This converts the UserName property to the format required. - - // While CERT_CREDENTIAL_INFO is the correct structure, we manually marshal the data in order to - // support different cert hash lengths in the future. - // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/ns-wincred-_cert_credential_info - int hexLength = thumbprint.Length; - byte[] credInfo = new byte[sizeof(UInt32) + (hexLength / 2)]; - - // First field is cbSize which is a UInt32 value denoting the size of the total structure - Array.Copy(BitConverter.GetBytes((UInt32)credInfo.Length), credInfo, sizeof(UInt32)); - - // Now copy the byte representation of the thumbprint to the rest of the struct bytes - for (int i = 0; i < hexLength; i += 2) - credInfo[sizeof(UInt32) + (i / 2)] = Convert.ToByte(thumbprint.Substring(i, 2), 16); - - IntPtr pCredInfo = Marshal.AllocHGlobal(credInfo.Length); - Marshal.Copy(credInfo, 0, pCredInfo, credInfo.Length); - SafeMemoryBuffer pCredential = new SafeMemoryBuffer(pCredInfo); - - NativeHelpers.CredMarshalType marshalType = NativeHelpers.CredMarshalType.CertCredential; - using (pCredential) - { - SafeCredentialBuffer marshaledCredential; - if (!NativeMethods.CredMarshalCredentialW(marshalType, pCredential, out marshaledCredential)) - throw new Win32Exception("CredMarshalCredentialW() failed"); - using (marshaledCredential) - return Marshal.PtrToStringUni(marshaledCredential.DangerousGetHandle()); - } - } - - public static string UnmarshalCertificateCredential(string value) - { - NativeHelpers.CredMarshalType credType; - SafeCredentialBuffer pCredInfo; - if (!NativeMethods.CredUnmarshalCredentialW(value, out credType, out pCredInfo)) - throw new Win32Exception("CredUnmarshalCredentialW() failed"); - - using (pCredInfo) - { - if (credType != NativeHelpers.CredMarshalType.CertCredential) - throw new InvalidOperationException(String.Format("Expected unmarshalled cred type of CertCredential, received {0}", credType)); - - byte[] structSizeBytes = new byte[sizeof(UInt32)]; - Marshal.Copy(pCredInfo.DangerousGetHandle(), structSizeBytes, 0, sizeof(UInt32)); - UInt32 structSize = BitConverter.ToUInt32(structSizeBytes, 0); - - byte[] certInfoBytes = new byte[structSize]; - Marshal.Copy(pCredInfo.DangerousGetHandle(), certInfoBytes, 0, certInfoBytes.Length); - - StringBuilder hex = new StringBuilder((certInfoBytes.Length - sizeof(UInt32)) * 2); - for (int i = 4; i < certInfoBytes.Length; i++) - hex.AppendFormat("{0:x2}", certInfoBytes[i]); - - return hex.ToString().ToUpperInvariant(); - } - } - - internal static void PtrToStructureArray(T[] array, IntPtr ptr) - { - IntPtr ptrOffset = ptr; - for (int i = 0; i < array.Length; i++, ptrOffset = IntPtr.Add(ptrOffset, Marshal.SizeOf(typeof(T)))) - array[i] = (T)Marshal.PtrToStructure(ptrOffset, typeof(T)); - } - } -} -'@ - -Function ConvertTo-CredentialAttribute { - param($Attributes) - - $converted_attributes = [System.Collections.Generic.List`1[Ansible.CredentialManager.CredentialAttribute]]@() - foreach ($attribute in $Attributes) { - $new_attribute = New-Object -TypeName Ansible.CredentialManager.CredentialAttribute - $new_attribute.Keyword = $attribute.name - - if ($null -ne $attribute.data) { - if ($attribute.data_format -eq "base64") { - $new_attribute.Value = [System.Convert]::FromBase64String($attribute.data) - } else { - $new_attribute.Value = [System.Text.Encoding]::UTF8.GetBytes($attribute.data) - } - } - $converted_attributes.Add($new_attribute) > $null - } - - return ,$converted_attributes -} - -Function Get-DiffInfo { - param($AnsibleCredential) - - $diff = @{ - alias = $AnsibleCredential.TargetAlias - attributes = [System.Collections.ArrayList]@() - comment = $AnsibleCredential.Comment - name = $AnsibleCredential.TargetName - persistence = $AnsibleCredential.Persist.ToString() - type = $AnsibleCredential.Type.ToString() - username = $AnsibleCredential.UserName - } - - foreach ($attribute in $AnsibleCredential.Attributes) { - $attribute_info = @{ - name = $attribute.Keyword - data = $null - } - if ($null -ne $attribute.Value) { - $attribute_info.data = [System.Convert]::ToBase64String($attribute.Value) - } - $diff.attributes.Add($attribute_info) > $null - } - - return ,$diff -} - -# If the username is a certificate thumbprint, verify it's a valid cert in the CurrentUser/Personal store -if ($null -ne $username -and $type -in @("domain_certificate", "generic_certificate")) { - # Ensure the thumbprint is upper case with no spaces or hyphens - $username = $username.ToUpperInvariant().Replace(" ", "").Replace("-", "") - - $certificate = Get-Item -Path Cert:\CurrentUser\My\$username -ErrorAction SilentlyContinue - if ($null -eq $certificate) { - $module.FailJson("Failed to find certificate with the thumbprint $username in the CurrentUser\My store") - } -} - -# Convert the input secret to a byte array -if ($null -ne $secret) { - if ($secret_format -eq "base64") { - $secret = [System.Convert]::FromBase64String($secret) - } else { - $secret = [System.Text.Encoding]::Unicode.GetBytes($secret) - } -} - -$persistence = switch ($persistence) { - "local" { [Ansible.CredentialManager.CredentialPersist]::LocalMachine } - "enterprise" { [Ansible.CredentialManager.CredentialPersist]::Enterprise } -} - -$type = switch ($type) { - "domain_password" { [Ansible.CredentialManager.CredentialType]::DomainPassword } - "domain_certificate" { [Ansible.CredentialManager.CredentialType]::DomainCertificate } - "generic_password" { [Ansible.CredentialManager.CredentialType]::Generic } - "generic_certificate" { [Ansible.CredentialManager.CredentialType]::GenericCertificate } -} - -$existing_credential = [Ansible.CredentialManager.Credential]::GetCredential($name, $type) -if ($null -ne $existing_credential) { - $module.Diff.before = Get-DiffInfo -AnsibleCredential $existing_credential -} - -if ($state -eq "absent") { - if ($null -ne $existing_credential) { - if (-not $module.CheckMode) { - $existing_credential.Delete() - } - $module.Result.changed = $true - } -} else { - if ($null -eq $existing_credential) { - $new_credential = New-Object -TypeName Ansible.CredentialManager.Credential - $new_credential.Type = $type - $new_credential.TargetName = $name - $new_credential.Comment = if ($comment) { $comment } else { [NullString]::Value } - $new_credential.Secret = $secret - $new_credential.Persist = $persistence - $new_credential.TargetAlias = if ($alias) { $alias } else { [NullString]::Value } - $new_credential.UserName = $username - - if ($null -ne $attributes) { - $new_credential.Attributes = ConvertTo-CredentialAttribute -Attributes $attributes - } - - if (-not $module.CheckMode) { - $new_credential.Write($false) - } - $module.Result.changed = $true - } else { - $changed = $false - $preserve_blob = $false - - # make sure we do case comparison for the comment - if ($existing_credential.Comment -cne $comment) { - $existing_credential.Comment = $comment - $changed = $true - } - - if ($existing_credential.Persist -ne $persistence) { - $existing_credential.Persist = $persistence - $changed = $true - } - - if ($existing_credential.TargetAlias -ne $alias) { - $existing_credential.TargetAlias = $alias - $changed = $true - } - - if ($existing_credential.UserName -ne $username) { - $existing_credential.UserName = $username - $changed = $true - } - - if ($null -ne $attributes) { - $attribute_changed = $false - - $new_attributes = ConvertTo-CredentialAttribute -Attributes $attributes - if ($new_attributes.Count -ne $existing_credential.Attributes.Count) { - $attribute_changed = $true - } else { - for ($i = 0; $i -lt $new_attributes.Count; $i++) { - $new_keyword = $new_attributes[$i].Keyword - $new_value = $new_attributes[$i].Value - if ($null -eq $new_value) { - $new_value = "" - } else { - $new_value = [System.Convert]::ToBase64String($new_value) - } - - $existing_keyword = $existing_credential.Attributes[$i].Keyword - $existing_value = $existing_credential.Attributes[$i].Value - if ($null -eq $existing_value) { - $existing_value = "" - } else { - $existing_value = [System.Convert]::ToBase64String($existing_value) - } - - if (($new_keyword -cne $existing_keyword) -or ($new_value -ne $existing_value)) { - $attribute_changed = $true - break - } - } - } - - if ($attribute_changed) { - $existing_credential.Attributes = $new_attributes - $changed = $true - } - } - - if ($null -eq $secret) { - # If we haven't explicitly set a secret, tell Windows to preserve the existing blob - $preserve_blob = $true - $existing_credential.Secret = $null - } elseif ($update_secret -eq "always") { - # We should only set the password if we can't read the existing one or it doesn't match our secret - if ($existing_credential.Secret.Length -eq 0) { - # We cannot read the secret so don't know if its the configured secret - $existing_credential.Secret = $secret - $changed = $true - } else { - # We can read the secret so compare with our input - $input_secret_b64 = [System.Convert]::ToBase64String($secret) - $actual_secret_b64 = [System.Convert]::ToBase64String($existing_credential.Secret) - if ($input_secret_b64 -ne $actual_secret_b64) { - $existing_credential.Secret = $secret - $changed = $true - } - } - } - - if ($changed -and -not $module.CheckMode) { - $existing_credential.Write($preserve_blob) - } - $module.Result.changed = $changed - } - - if ($module.CheckMode) { - # We cannot reliably get the credential in check mode, set it based on the input - $module.Diff.after = @{ - alias = $alias - attributes = $attributes - comment = $comment - name = $name - persistence = $persistence.ToString() - type = $type.ToString() - username = $username - } - } else { - # Get a new copy of the credential and use that to set the after diff - $new_credential = [Ansible.CredentialManager.Credential]::GetCredential($name, $type) - $module.Diff.after = Get-DiffInfo -AnsibleCredential $new_credential - } -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_credential.py b/lib/ansible/modules/windows/win_credential.py deleted file mode 100644 index 57cbb483af7..00000000000 --- a/lib/ansible/modules/windows/win_credential.py +++ /dev/null @@ -1,209 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_credential -version_added: '2.8' -short_description: Manages Windows Credentials in the Credential Manager -description: -- Used to create and remove Windows Credentials in the Credential Manager. -- This module can manage both standard username/password credentials as well as - certificate credentials. -options: - alias: - description: - - Adds an alias for the credential. - - Typically this is the NetBIOS name of a host if I(name) is set to the DNS - name. - type: str - attributes: - description: - - A list of dicts that set application specific attributes for a - credential. - - When set, existing attributes will be compared to the list as a whole, - any differences means all attributes will be replaced. - suboptions: - name: - description: - - The key for the attribute. - - This is not a unique identifier as multiple attributes can have the - same key. - type: str - required: true - data: - description: - - The value for the attribute. - type: str - data_format: - description: - - Controls the input type for I(data). - - If C(text), I(data) is a text string that is UTF-16LE encoded to - bytes. - - If C(base64), I(data) is a base64 string that is base64 decoded to - bytes. - type: str - choices: [ base64, text ] - default: text - comment: - description: - - A user defined comment for the credential. - type: str - name: - description: - - The target that identifies the server or servers that the credential is - to be used for. - - If the value can be a NetBIOS name, DNS server name, DNS host name suffix - with a wildcard character (C(*)), a NetBIOS of DNS domain name that - contains a wildcard character sequence, or an asterisk. - - See C(TargetName) in U(https://docs.microsoft.com/en-us/windows/desktop/api/wincred/ns-wincred-_credentiala) - for more details on what this value can be. - - This is used with I(type) to produce a unique credential. - type: str - required: true - persistence: - description: - - Defines the persistence of the credential. - - If C(local), the credential will persist for all logons of the same user - on the same host. - - C(enterprise) is the same as C(local) but the credential is visible to - the same domain user when running on other hosts and not just localhost. - type: str - choices: [ enterprise, local ] - default: local - secret: - description: - - The secret for the credential. - - When omitted, then no secret is used for the credential if a new - credentials is created. - - When I(type) is a password type, this is the password for I(username). - - When I(type) is a certificate type, this is the pin for the certificate. - type: str - secret_format: - description: - - Controls the input type for I(secret). - - If C(text), I(secret) is a text string that is UTF-16LE encoded to bytes. - - If C(base64), I(secret) is a base64 string that is base64 decoded to - bytes. - type: str - choices: [ base64, text ] - default: text - state: - description: - - When C(absent), the credential specified by I(name) and I(type) is - removed. - - When C(present), the credential specified by I(name) and I(type) is - removed. - type: str - choices: [ absent, present ] - default: present - type: - description: - - The type of credential to store. - - This is used with I(name) to produce a unique credential. - - When the type is a C(domain) type, the credential is used by Microsoft - authentication packages like Negotiate. - - When the type is a C(generic) type, the credential is not used by any - particular authentication package. - - It is recommended to use a C(domain) type as only authentication - providers can access the secret. - type: str - required: true - choices: [ domain_certificate, domain_password, generic_certificate, generic_password ] - update_secret: - description: - - When C(always), the secret will always be updated if they differ. - - When C(on_create), the secret will only be checked/updated when it is - first created. - - If the secret cannot be retrieved and this is set to C(always), the - module will always result in a change. - type: str - choices: [ always, on_create ] - default: always - username: - description: - - When I(type) is a password type, then this is the username to store for - the credential. - - When I(type) is a credential type, then this is the thumbprint as a hex - string of the certificate to use. - - When C(type=domain_password), this should be in the form of a Netlogon - (DOMAIN\Username) or a UPN (username@DOMAIN). - - If using a certificate thumbprint, the certificate must exist in the - C(CurrentUser\My) certificate store for the executing user. - type: str -notes: -- This module requires to be run with C(become) so it can access the - user's credential store. -- There can only be one credential per host and type. if a second credential is - defined that uses the same host and type, then the original credential is - overwritten. -seealso: -- module: win_user_right -- module: win_whoami -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Create a local only credential - win_credential: - name: server.domain.com - type: domain_password - username: DOMAIN\username - secret: Password01 - state: present - -- name: Remove a credential - win_credential: - name: server.domain.com - type: domain_password - state: absent - -- name: Create a credential with full values - win_credential: - name: server.domain.com - type: domain_password - alias: server - username: username@DOMAIN.COM - secret: Password01 - comment: Credential for server.domain.com - persistence: enterprise - attributes: - - name: Source - data: Ansible - - name: Unique Identifier - data: Y3VzdG9tIGF0dHJpYnV0ZQ== - data_format: base64 - -- name: Create a certificate credential - win_credential: - name: '*.domain.com' - type: domain_certificate - username: 0074CC4F200D27DC3877C24A92BA8EA21E6C7AF4 - state: present - -- name: Create a generic credential - win_credential: - name: smbhost - type: generic_password - username: smbuser - secret: smbuser - state: present - -- name: Remove a generic credential - win_credential: - name: smbhost - type: generic_password - state: absent -''' - -RETURN = r''' -# -''' diff --git a/lib/ansible/modules/windows/win_data_deduplication.ps1 b/lib/ansible/modules/windows/win_data_deduplication.ps1 deleted file mode 100644 index 593ee763815..00000000000 --- a/lib/ansible/modules/windows/win_data_deduplication.ps1 +++ /dev/null @@ -1,129 +0,0 @@ -#!powershell - -# Copyright: 2019, rnsc(@rnsc) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt - -#AnsibleRequires -CSharpUtil Ansible.Basic -#AnsibleRequires -OSVersion 6.3 - -$spec = @{ - options = @{ - drive_letter = @{ type = "str"; required = $true } - state = @{ type = "str"; choices = "absent", "present"; default = "present"; } - settings = @{ - type = "dict" - required = $false - options = @{ - minimum_file_size = @{ type = "int"; default = 32768 } - minimum_file_age_days = @{ type = "int"; default = 2 } - no_compress = @{ type = "bool"; required = $false; default = $false } - optimize_in_use_files = @{ type = "bool"; required = $false; default = $false } - verify = @{ type = "bool"; required = $false; default = $false } - } - } - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$drive_letter = $module.Params.drive_letter -$state = $module.Params.state -$settings = $module.Params.settings - -$module.Result.changed = $false -$module.Result.reboot_required = $false -$module.Result.msg = "" - -function Set-DataDeduplication($volume, $state, $settings, $dedup_job) { - - $current_state = 'absent' - - try { - $dedup_info = Get-DedupVolume -Volume "$($volume.DriveLetter):" - } catch { - $dedup_info = $null - } - - if ($dedup_info.Enabled) { - $current_state = 'present' - } - - if ( $state -ne $current_state ) { - if( -not $module.CheckMode) { - if($state -eq 'present') { - # Enable-DedupVolume -Volume - Enable-DedupVolume -Volume "$($volume.DriveLetter):" - } elseif ($state -eq 'absent') { - Disable-DedupVolume -Volume "$($volume.DriveLetter):" - } - } - $module.Result.changed = $true - } - - if ($state -eq 'present') { - if ($null -ne $settings) { - Set-DataDedupJobSettings -volume $volume -settings $settings - } - } -} - -function Set-DataDedupJobSettings ($volume, $settings) { - - try { - $dedup_info = Get-DedupVolume -Volume "$($volume.DriveLetter):" - } catch { - $dedup_info = $null - } - - ForEach ($key in $settings.keys) { - - # See Microsoft documentation: - # https://docs.microsoft.com/en-us/powershell/module/deduplication/set-dedupvolume?view=win10-ps - - $update_key = $key - $update_value = $settings.$($key) - # Transform Ansible style options to Powershell params - $update_key = $update_key -replace('_', '') - - if ($update_key -eq "MinimumFileSize" -and $update_value -lt 32768) { - $update_value = 32768 - } - - $current_value = ($dedup_info | Select-Object -ExpandProperty $update_key) - - if ($update_value -ne $current_value) { - $command_param = @{ - $($update_key) = $update_value - } - - # Set-DedupVolume -Volume ` - # -NoCompress ` - # -MinimumFileAgeDays ` - # -MinimumFileSize (minimum 32768) - if( -not $module.CheckMode ) { - Set-DedupVolume -Volume "$($volume.DriveLetter):" @command_param - } - - $module.Result.changed = $true - } - } - -} - -# Install required feature -$feature_name = "FS-Data-Deduplication" -if( -not $module.CheckMode) { - $feature = Install-WindowsFeature -Name $feature_name - - if ($feature.RestartNeeded -eq 'Yes') { - $module.Result.reboot_required = $true - $module.FailJson("$feature_name was installed but requires Windows to be rebooted to work.") - } -} - -$volume = Get-Volume -DriveLetter $drive_letter - -Set-DataDeduplication -volume $volume -state $state -settings $settings -dedup_job $dedup_job - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_data_deduplication.py b/lib/ansible/modules/windows/win_data_deduplication.py deleted file mode 100644 index d320b9f7c2b..00000000000 --- a/lib/ansible/modules/windows/win_data_deduplication.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: 2019, rnsc(@rnsc) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_data_deduplication -version_added: "2.10" -short_description: Module to enable Data Deduplication on a volume. -description: -- This module can be used to enable Data Deduplication on a Windows volume. -- The module will install the FS-Data-Deduplication feature (a reboot will be necessary). -options: - drive_letter: - description: - - Windows drive letter on which to enable data deduplication. - required: yes - type: str - state: - description: - - Wether to enable or disable data deduplication on the selected volume. - default: present - type: str - choices: [ present, absent ] - settings: - description: - - Dictionary of settings to pass to the Set-DedupVolume powershell command. - type: dict - suboptions: - minimum_file_size: - description: - - Minimum file size you want to target for deduplication. - - It will default to 32768 if not defined or if the value is less than 32768. - type: int - default: 32768 - minimum_file_age_days: - description: - - Minimum file age you want to target for deduplication. - type: int - default: 2 - no_compress: - description: - - Wether you want to enabled filesystem compression or not. - type: bool - default: no - optimize_in_use_files: - description: - - Indicates that the server attempts to optimize currently open files. - type: bool - default: no - verify: - description: - - Indicates whether the deduplication engine performs a byte-for-byte verification for each duplicate chunk - that optimization creates, rather than relying on a cryptographically strong hash. - - This option is not recommend. - - Setting this parameter to True can degrade optimization performance. - type: bool - default: no -author: -- rnsc (@rnsc) -''' - -EXAMPLES = r''' -- name: Enable Data Deduplication on D - win_data_deduplication: - drive_letter: 'D' - state: present - -- name: Enable Data Deduplication on D - win_data_deduplication: - drive_letter: 'D' - state: present - settings: - no_compress: true - minimum_file_age_days: 1 - minimum_file_size: 0 -''' - -RETURN = r''' -# -''' diff --git a/lib/ansible/modules/windows/win_defrag.ps1 b/lib/ansible/modules/windows/win_defrag.ps1 deleted file mode 100644 index b88b4ef252f..00000000000 --- a/lib/ansible/modules/windows/win_defrag.ps1 +++ /dev/null @@ -1,97 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Dag Wieers (@dagwieers) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.ArgvParser -#Requires -Module Ansible.ModuleUtils.CommandUtil - -$spec = @{ - options = @{ - include_volumes = @{ type='list' } - exclude_volumes = @{ type='list' } - freespace_consolidation = @{ type='bool'; default=$false } - priority = @{ type='str'; default='low'; choices=@( 'low', 'normal') } - parallel = @{ type='bool'; default=$false } - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$include_volumes = $module.Params.include_volumes -$exclude_volumes = $module.Params.exclude_volumes -$freespace_consolidation = $module.Params.freespace_consolidation -$priority = $module.Params.priority -$parallel = $module.Params.parallel - -$module.Result.changed = $false - -$executable = "defrag.exe" - -if (-not (Get-Command -Name $executable -ErrorAction SilentlyContinue)) { - $module.FailJson("Command '$executable' not found in $env:PATH.") -} - -$arguments = @() - -if ($include_volumes) { - foreach ($volume in $include_volumes) { - if ($volume.Length -eq 1) { - $arguments += "$($volume):" - } else { - $arguments += $volume - } - } -} else { - $arguments += "/C" -} - -if ($exclude_volumes) { - $arguments += "/E" - foreach ($volume in $exclude_volumes) { - if ($volume.Length -eq 1) { - $arguments += "$($volume):" - } else { - $arguments += $volume - } - } -} - -if ($module.CheckMode) { - $arguments += "/A" -} elseif ($freespace_consolidation) { - $arguments += "/X" -} - -if ($priority -eq "normal") { - $arguments += "/H" -} - -if ($parallel) { - $arguments += "/M" -} - -$arguments += "/V" - -$argument_string = Argv-ToString -arguments $arguments - -$start_datetime = [DateTime]::UtcNow -$module.Result.cmd = "$executable $argument_string" - -$command_result = Run-Command -command "$executable $argument_string" - -$end_datetime = [DateTime]::UtcNow - -$module.Result.stdout = $command_result.stdout -$module.Result.stderr = $command_result.stderr -$module.Result.rc = $command_result.rc - -$module.Result.start = $start_datetime.ToString("yyyy-MM-dd hh:mm:ss.ffffff") -$module.Result.end = $end_datetime.ToString("yyyy-MM-dd hh:mm:ss.ffffff") -$module.Result.delta = $($end_datetime - $start_datetime).ToString("h\:mm\:ss\.ffffff") - -$module.Result.changed = $true - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_defrag.py b/lib/ansible/modules/windows/win_defrag.py deleted file mode 100644 index 6889dfb7dce..00000000000 --- a/lib/ansible/modules/windows/win_defrag.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: 2017, Dag Wieers (@dagwieers) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_defrag -version_added: '2.4' -short_description: Consolidate fragmented files on local volumes -description: -- Locates and consolidates fragmented files on local volumes to improve system performance. -- 'More information regarding C(win_defrag) is available from: U(https://technet.microsoft.com/en-us/library/cc731650(v=ws.11).aspx)' -requirements: -- defrag.exe -options: - include_volumes: - description: - - A list of drive letters or mount point paths of the volumes to be defragmented. - - If this parameter is omitted, all volumes (not excluded) will be fragmented. - type: list - exclude_volumes: - description: - - A list of drive letters or mount point paths to exclude from defragmentation. - type: list - freespace_consolidation: - description: - - Perform free space consolidation on the specified volumes. - type: bool - default: no - priority: - description: - - Run the operation at low or normal priority. - type: str - choices: [ low, normal ] - default: low - parallel: - description: - - Run the operation on each volume in parallel in the background. - type: bool - default: no -author: -- Dag Wieers (@dagwieers) -''' - -EXAMPLES = r''' -- name: Defragment all local volumes (in parallel) - win_defrag: - parallel: yes - -- name: 'Defragment all local volumes, except C: and D:' - win_defrag: - exclude_volumes: [ C, D ] - -- name: 'Defragment volume D: with normal priority' - win_defrag: - include_volumes: D - priority: normal - -- name: Consolidate free space (useful when reducing volumes) - win_defrag: - freespace_consolidation: yes -''' - -RETURN = r''' -cmd: - description: The complete command line used by the module. - returned: always - type: str - sample: defrag.exe /C /V -rc: - description: The return code for the command. - returned: always - type: int - sample: 0 -stdout: - description: The standard output from the command. - returned: always - type: str - sample: Success. -stderr: - description: The error output from the command. - returned: always - type: str - sample: -msg: - description: Possible error message on failure. - returned: failed - type: str - sample: Command 'defrag.exe' not found in $env:PATH. -changed: - description: Whether or not any changes were made. - returned: always - type: bool - sample: true -''' diff --git a/lib/ansible/modules/windows/win_disk_facts.ps1 b/lib/ansible/modules/windows/win_disk_facts.ps1 deleted file mode 100644 index 30bff60c143..00000000000 --- a/lib/ansible/modules/windows/win_disk_facts.ps1 +++ /dev/null @@ -1,251 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Marc Tschapek -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#AnsibleRequires -OSVersion 6.2 - -$ErrorActionPreference = "Stop" -Set-StrictMode -Version 2.0 - -# Functions -function Test-Admin { - $CurrentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent()) - $IsAdmin = $CurrentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) - - return $IsAdmin -} - -# Check admin rights -if (-not (Test-Admin)) { - Fail-Json -obj @{} -message "Module was not started with elevated rights" -} - -# Create a new result object -$result = @{ - changed = $false - ansible_facts = @{ - ansible_disks = @() - } -} - -# Search disks -try { - $disks = Get-Disk -} catch { - Fail-Json -obj $result -message "Failed to search the disks on the target: $($_.Exception.Message)" -} -foreach ($disk in $disks) { - $disk_info = @{} - $pdisk = Get-PhysicalDisk -ErrorAction SilentlyContinue | Where-Object { - $_.DeviceId -eq $disk.Number - } - if ($pdisk) { - $disk_info["physical_disk"] += @{ - size = $pdisk.Size - allocated_size = $pdisk.AllocatedSize - device_id = $pdisk.DeviceId - friendly_name = $pdisk.FriendlyName - operational_status = $pdisk.OperationalStatus - health_status = $pdisk.HealthStatus - bus_type = $pdisk.BusType - usage_type = $pdisk.Usage - supported_usages = $pdisk.SupportedUsages - spindle_speed = $pdisk.SpindleSpeed - firmware_version = $pdisk.FirmwareVersion - physical_location = $pdisk.PhysicalLocation - manufacturer = $pdisk.Manufacturer - model = $pdisk.Model - can_pool = $pdisk.CanPool - indication_enabled = $pdisk.IsIndicationEnabled - partial = $pdisk.IsPartial - serial_number = $pdisk.SerialNumber - object_id = $pdisk.ObjectId - unique_id = $pdisk.UniqueId - } - if ([single]"$([System.Environment]::OSVersion.Version.Major).$([System.Environment]::OSVersion.Version.Minor)" -ge 6.3) { - $disk_info.physical_disk.media_type = $pdisk.MediaType - } - if (-not $pdisk.CanPool) { - $disk_info.physical_disk.cannot_pool_reason = $pdisk.CannotPoolReason - } - $vdisk = Get-VirtualDisk -PhysicalDisk $pdisk -ErrorAction SilentlyContinue - if ($vdisk) { - $disk_info["virtual_disk"] += @{ - size = $vdisk.Size - allocated_size = $vdisk.AllocatedSize - footprint_on_pool = $vdisk.FootprintOnPool - name = $vdisk.name - friendly_name = $vdisk.FriendlyName - operational_status = $vdisk.OperationalStatus - health_status = $vdisk.HealthStatus - provisioning_type = $vdisk.ProvisioningType - allocation_unit_size = $vdisk.AllocationUnitSize - media_type = $vdisk.MediaType - parity_layout = $vdisk.ParityLayout - access = $vdisk.Access - detached_reason = $vdisk.DetachedReason - write_cache_size = $vdisk.WriteCacheSize - fault_domain_awareness = $vdisk.FaultDomainAwareness - inter_leave = $vdisk.InterLeave - deduplication_enabled = $vdisk.IsDeduplicationEnabled - enclosure_aware = $vdisk.IsEnclosureAware - manual_attach = $vdisk.IsManualAttach - snapshot = $vdisk.IsSnapshot - tiered = $vdisk.IsTiered - physical_sector_size = $vdisk.PhysicalSectorSize - logical_sector_size = $vdisk.LogicalSectorSize - available_copies = $vdisk.NumberOfAvailableCopies - columns = $vdisk.NumberOfColumns - groups = $vdisk.NumberOfGroups - physical_disk_redundancy = $vdisk.PhysicalDiskRedundancy - read_cache_size = $vdisk.ReadCacheSize - request_no_spof = $vdisk.RequestNoSinglePointOfFailure - resiliency_setting_name = $vdisk.ResiliencySettingName - object_id = $vdisk.ObjectId - unique_id_format = $vdisk.UniqueIdFormat - unique_id = $vdisk.UniqueId - } - } - } - $win32_disk_drive = Get-CimInstance -ClassName Win32_DiskDrive -ErrorAction SilentlyContinue | Where-Object { - if ($_.SerialNumber) { - $_.SerialNumber -eq $disk.SerialNumber - } elseif ($disk.UniqueIdFormat -eq 'Vendor Specific') { - $_.PNPDeviceID -eq $disk.UniqueId.split(':')[0] - } - } - if ($win32_disk_drive) { - $disk_info["win32_disk_drive"] += @{ - availability=$win32_disk_drive.Availability - bytes_per_sector=$win32_disk_drive.BytesPerSector - capabilities=$win32_disk_drive.Capabilities - capability_descriptions=$win32_disk_drive.CapabilityDescriptions - caption=$win32_disk_drive.Caption - compression_method=$win32_disk_drive.CompressionMethod - config_manager_error_code=$win32_disk_drive.ConfigManagerErrorCode - config_manager_user_config=$win32_disk_drive.ConfigManagerUserConfig - creation_class_name=$win32_disk_drive.CreationClassName - default_block_size=$win32_disk_drive.DefaultBlockSize - description=$win32_disk_drive.Description - device_id=$win32_disk_drive.DeviceID - error_cleared=$win32_disk_drive.ErrorCleared - error_description=$win32_disk_drive.ErrorDescription - error_methodology=$win32_disk_drive.ErrorMethodology - firmware_revision=$win32_disk_drive.FirmwareRevision - index=$win32_disk_drive.Index - install_date=$win32_disk_drive.InstallDate - interface_type=$win32_disk_drive.InterfaceType - last_error_code=$win32_disk_drive.LastErrorCode - manufacturer=$win32_disk_drive.Manufacturer - max_block_size=$win32_disk_drive.MaxBlockSize - max_media_size=$win32_disk_drive.MaxMediaSize - media_loaded=$win32_disk_drive.MediaLoaded - media_type=$win32_disk_drive.MediaType - min_block_size=$win32_disk_drive.MinBlockSize - model=$win32_disk_drive.Model - name=$win32_disk_drive.Name - needs_cleaning=$win32_disk_drive.NeedsCleaning - number_of_media_supported=$win32_disk_drive.NumberOfMediaSupported - partitions=$win32_disk_drive.Partitions - pnp_device_id=$win32_disk_drive.PNPDeviceID - power_management_capabilities=$win32_disk_drive.PowerManagementCapabilities - power_management_supported=$win32_disk_drive.PowerManagementSupported - scsi_bus=$win32_disk_drive.SCSIBus - scsi_logical_unit=$win32_disk_drive.SCSILogicalUnit - scsi_port=$win32_disk_drive.SCSIPort - scsi_target_id=$win32_disk_drive.SCSITargetId - sectors_per_track=$win32_disk_drive.SectorsPerTrack - serial_number=$win32_disk_drive.SerialNumber - signature=$win32_disk_drive.Signature - size=$win32_disk_drive.Size - status=$win32_disk_drive.status - status_info=$win32_disk_drive.StatusInfo - system_creation_class_name=$win32_disk_drive.SystemCreationClassName - system_name=$win32_disk_drive.SystemName - total_cylinders=$win32_disk_drive.TotalCylinders - total_heads=$win32_disk_drive.TotalHeads - total_sectors=$win32_disk_drive.TotalSectors - total_tracks=$win32_disk_drive.TotalTracks - tracks_per_cylinder=$win32_disk_drive.TracksPerCylinder - } - } - $disk_info.number = $disk.Number - $disk_info.size = $disk.Size - $disk_info.bus_type = $disk.BusType - $disk_info.friendly_name = $disk.FriendlyName - $disk_info.partition_style = $disk.PartitionStyle - $disk_info.partition_count = $disk.NumberOfPartitions - $disk_info.operational_status = $disk.OperationalStatus - $disk_info.sector_size = $disk.PhysicalSectorSize - $disk_info.read_only = $disk.IsReadOnly - $disk_info.bootable = $disk.IsBoot - $disk_info.system_disk = $disk.IsSystem - $disk_info.clustered = $disk.IsClustered - $disk_info.manufacturer = $disk.Manufacturer - $disk_info.model = $disk.Model - $disk_info.firmware_version = $disk.FirmwareVersion - $disk_info.location = $disk.Location - $disk_info.serial_number = $disk.SerialNumber - $disk_info.unique_id = $disk.UniqueId - $disk_info.guid = $disk.Guid - $disk_info.path = $disk.Path - $parts = Get-Partition -DiskNumber $($disk.Number) -ErrorAction SilentlyContinue - if ($parts) { - $disk_info["partitions"] += @() - foreach ($part in $parts) { - $partition_info = @{ - number = $part.PartitionNumber - size = $part.Size - type = $part.Type - drive_letter = $part.DriveLetter - transition_state = $part.TransitionState - offset = $part.Offset - hidden = $part.IsHidden - shadow_copy = $part.IsShadowCopy - guid = $part.Guid - access_paths = $part.AccessPaths - } - if ($disks.PartitionStyle -eq "GPT") { - $partition_info.gpt_type = $part.GptType - $partition_info.no_default_driveletter = $part.NoDefaultDriveLetter - } elseif ($disks.PartitionStyle -eq "MBR") { - $partition_info.mbr_type = $part.MbrType - $partition_info.active = $part.IsActive - } - $vols = Get-Volume -Partition $part -ErrorAction SilentlyContinue - if ($vols) { - $partition_info["volumes"] += @() - foreach ($vol in $vols) { - $volume_info = @{ - size = $vol.Size - size_remaining = $vol.SizeRemaining - type = $vol.FileSystem - label = $vol.FileSystemLabel - health_status = $vol.HealthStatus - drive_type = $vol.DriveType - object_id = $vol.ObjectId - path = $vol.Path - } - if ([System.Environment]::OSVersion.Version.Major -ge 10) { - $volume_info.allocation_unit_size = $vol.AllocationUnitSize - } else { - $volPath = ($vol.Path.TrimStart("\\?\")).TrimEnd("\") - $BlockSize = (Get-CimInstance -Query "SELECT BlockSize FROM Win32_Volume WHERE DeviceID like '%$volPath%'" -ErrorAction SilentlyContinue | Select-Object BlockSize).BlockSize - $volume_info.allocation_unit_size = $BlockSize - } - $partition_info.volumes += $volume_info - } - } - $disk_info.partitions += $partition_info - } - } - $result.ansible_facts.ansible_disks += $disk_info -} - -# Sort by disk number property -$result.ansible_facts.ansible_disks = @() + ($result.ansible_facts.ansible_disks | Sort-Object -Property {$_.Number}) - -# Return result -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_disk_facts.py b/lib/ansible/modules/windows/win_disk_facts.py deleted file mode 100644 index b203d79002b..00000000000 --- a/lib/ansible/modules/windows/win_disk_facts.py +++ /dev/null @@ -1,891 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Marc Tschapek -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_disk_facts -version_added: '2.5' -short_description: Show the attached disks and disk information of the target host -description: - - With the module you can retrieve and output detailed information about the attached disks of the target and - its volumes and partitions if existent. -requirements: - - Windows 8.1 / Windows 2012 (NT 6.2) -notes: - - In order to understand all the returned properties and values please visit the following site and open the respective MSFT class - U(https://msdn.microsoft.com/en-us/library/windows/desktop/hh830612.aspx) -author: - - Marc Tschapek (@marqelme) -''' - -EXAMPLES = r''' -- name: Get disk facts - win_disk_facts: - -- name: Output first disk size - debug: - var: ansible_facts.disks[0].size - -- name: Convert first system disk into various formats - debug: - msg: '{{ disksize_gib }} vs {{ disksize_gib_human }}' - vars: - # Get first system disk - disk: '{{ ansible_facts.disks|selectattr("system_disk")|first }}' - - # Show disk size in Gibibytes - disksize_gib_human: '{{ disk.size|filesizeformat(true) }}' # returns "223.6 GiB" (human readable) - disksize_gib: '{{ (disk.size/1024|pow(3))|round|int }} GiB' # returns "224 GiB" (value in GiB) - - # Show disk size in Gigabytes - disksize_gb_human: '{{ disk.size|filesizeformat }}' # returns "240.1 GB" (human readable) - disksize_gb: '{{ (disk.size/1000|pow(3))|round|int }} GB' # returns "240 GB" (value in GB) - -- name: Output second disk serial number - debug: - var: ansible_facts.disks[1].serial_number -''' - -RETURN = r''' -ansible_facts: - description: Dictionary containing all the detailed information about the disks of the target. - returned: always - type: complex - contains: - ansible_disks: - description: Detailed information about one particular disk. - returned: if disks were found - type: list - contains: - number: - description: Disk number of the particular disk. - returned: always - type: int - sample: 0 - size: - description: Size in bytes of the particular disk. - returned: always - type: int - sample: 227727638528 - bus_type: - description: Bus type of the particular disk. - returned: always - type: str - sample: "SCSI" - friendly_name: - description: Friendly name of the particular disk. - returned: always - type: str - sample: "Red Hat VirtIO SCSI Disk Device" - partition_style: - description: Partition style of the particular disk. - returned: always - type: str - sample: "MBR" - partition_count: - description: Number of partitions on the particular disk. - returned: always - type: int - sample: 4 - operational_status: - description: Operational status of the particular disk. - returned: always - type: str - sample: "Online" - sector_size: - description: Sector size in bytes of the particular disk. - returned: always - type: int - sample: 4096 - read_only: - description: Read only status of the particular disk. - returned: always - type: bool - sample: true - bootable: - description: Information whether the particular disk is a bootable disk. - returned: always - type: bool - sample: false - system_disk: - description: Information whether the particular disk is a system disk. - returned: always - type: bool - sample: true - clustered: - description: Information whether the particular disk is clustered (part of a failover cluster). - returned: always - type: bool - sample: false - manufacturer: - description: Manufacturer of the particular disk. - returned: always - type: str - sample: "Red Hat" - model: - description: Model specification of the particular disk. - returned: always - type: str - sample: "VirtIO" - firmware_version: - description: Firmware version of the particular disk. - returned: always - type: str - sample: "0001" - location: - description: Location of the particular disk on the target. - returned: always - type: str - sample: "PCIROOT(0)#PCI(0400)#SCSI(P00T00L00)" - serial_number: - description: Serial number of the particular disk on the target. - returned: always - type: str - sample: "b62beac80c3645e5877f" - unique_id: - description: Unique ID of the particular disk on the target. - returned: always - type: str - sample: "3141463431303031" - guid: - description: GUID of the particular disk on the target. - returned: if existent - type: str - sample: "{efa5f928-57b9-47fc-ae3e-902e85fbe77f}" - path: - description: Path of the particular disk on the target. - returned: always - type: str - sample: "\\\\?\\scsi#disk&ven_red_hat&prod_virtio#4&23208fd0&1&000000#{}" - partitions: - description: Detailed information about one particular partition on the specified disk. - returned: if existent - type: list - contains: - number: - description: Number of the particular partition. - returned: always - type: int - sample: 1 - size: - description: - - Size in bytes of the particular partition. - returned: always - type: int - sample: 838860800 - type: - description: Type of the particular partition. - returned: always - type: str - sample: "IFS" - gpt_type: - description: gpt type of the particular partition. - returned: if partition_style property of the particular disk has value "GPT" - type: str - sample: "{e3c9e316-0b5c-4db8-817d-f92df00215ae}" - no_default_driveletter: - description: Information whether the particular partition has a default drive letter or not. - returned: if partition_style property of the particular disk has value "GPT" - type: bool - sample: true - mbr_type: - description: mbr type of the particular partition. - returned: if partition_style property of the particular disk has value "MBR" - type: int - sample: 7 - active: - description: Information whether the particular partition is an active partition or not. - returned: if partition_style property of the particular disk has value "MBR" - type: bool - sample: true - drive_letter: - description: Drive letter of the particular partition. - returned: if existent - type: str - sample: "C" - transition_state: - description: Transition state of the particular partition. - returned: always - type: int - sample: 1 - offset: - description: Offset of the particular partition. - returned: always - type: int - sample: 368050176 - hidden: - description: Information whether the particular partition is hidden or not. - returned: always - type: bool - sample: true - shadow_copy: - description: Information whether the particular partition is a shadow copy of another partition. - returned: always - type: bool - sample: false - guid: - description: GUID of the particular partition. - returned: if existent - type: str - sample: "{302e475c-6e64-4674-a8e2-2f1c7018bf97}" - access_paths: - description: Access paths of the particular partition. - returned: if existent - type: str - sample: "\\\\?\\Volume{85bdc4a8-f8eb-11e6-80fa-806e6f6e6963}\\" - volumes: - description: Detailed information about one particular volume on the specified partition. - returned: if existent - type: list - contains: - size: - description: - - Size in bytes of the particular volume. - returned: always - type: int - sample: 838856704 - size_remaining: - description: - - Remaining size in bytes of the particular volume. - returned: always - type: int - sample: 395620352 - type: - description: File system type of the particular volume. - returned: always - type: str - sample: "NTFS" - label: - description: File system label of the particular volume. - returned: always - type: str - sample: "System Reserved" - health_status: - description: Health status of the particular volume. - returned: always - type: str - sample: "Healthy" - drive_type: - description: Drive type of the particular volume. - returned: always - type: str - sample: "Fixed" - allocation_unit_size: - description: Allocation unit size in bytes of the particular volume. - returned: always - type: int - sample: 4096 - object_id: - description: Object ID of the particular volume. - returned: always - type: str - sample: "\\\\?\\Volume{85bdc4a9-f8eb-11e6-80fa-806e6f6e6963}\\" - path: - description: Path of the particular volume. - returned: always - type: str - sample: "\\\\?\\Volume{85bdc4a9-f8eb-11e6-80fa-806e6f6e6963}\\" - physical_disk: - description: Detailed information about physical disk properties of the particular disk. - returned: if existent - type: complex - contains: - media_type: - description: Media type of the particular physical disk. - returned: always - type: str - sample: "UnSpecified" - size: - description: - - Size in bytes of the particular physical disk. - returned: always - type: int - sample: 240057409536 - allocated_size: - description: - - Allocated size in bytes of the particular physical disk. - returned: always - type: int - sample: 240057409536 - device_id: - description: Device ID of the particular physical disk. - returned: always - type: str - sample: "0" - friendly_name: - description: Friendly name of the particular physical disk. - returned: always - type: str - sample: "PhysicalDisk0" - operational_status: - description: Operational status of the particular physical disk. - returned: always - type: str - sample: "OK" - health_status: - description: Health status of the particular physical disk. - returned: always - type: str - sample: "Healthy" - bus_type: - description: Bus type of the particular physical disk. - returned: always - type: str - sample: "SCSI" - usage_type: - description: Usage type of the particular physical disk. - returned: always - type: str - sample: "Auto-Select" - supported_usages: - description: Supported usage types of the particular physical disk. - returned: always - type: complex - contains: - Count: - description: Count of supported usage types. - returned: always - type: int - sample: 5 - value: - description: List of supported usage types. - returned: always - type: str - sample: "Auto-Select, Hot Spare" - spindle_speed: - description: Spindle speed in rpm of the particular physical disk. - returned: always - type: int - sample: 4294967295 - physical_location: - description: Physical location of the particular physical disk. - returned: always - type: str - sample: "Integrated : Adapter 3 : Port 0 : Target 0 : LUN 0" - manufacturer: - description: Manufacturer of the particular physical disk. - returned: always - type: str - sample: "SUSE" - model: - description: Model of the particular physical disk. - returned: always - type: str - sample: "Xen Block" - can_pool: - description: Information whether the particular physical disk can be added to a storage pool. - returned: always - type: bool - sample: false - cannot_pool_reason: - description: Information why the particular physical disk can not be added to a storage pool. - returned: if can_pool property has value false - type: str - sample: "Insufficient Capacity" - indication_enabled: - description: Information whether indication is enabled for the particular physical disk. - returned: always - type: bool - sample: true - partial: - description: Information whether the particular physical disk is partial. - returned: always - type: bool - sample: false - serial_number: - description: Serial number of the particular physical disk. - returned: always - type: str - sample: "b62beac80c3645e5877f" - object_id: - description: Object ID of the particular physical disk. - returned: always - type: str - sample: '{1}\\\\HOST\\root/Microsoft/Windows/Storage/Providers_v2\\SPACES_PhysicalDisk.ObjectId=\"{}:PD:{}\"' - unique_id: - description: Unique ID of the particular physical disk. - returned: always - type: str - sample: "3141463431303031" - virtual_disk: - description: Detailed information about virtual disk properties of the particular disk. - returned: if existent - type: complex - contains: - size: - description: - - Size in bytes of the particular virtual disk. - returned: always - type: int - sample: 240057409536 - allocated_size: - description: - - Allocated size in bytes of the particular virtual disk. - returned: always - type: int - sample: 240057409536 - footprint_on_pool: - description: - - Footprint on pool in bytes of the particular virtual disk. - returned: always - type: int - sample: 240057409536 - name: - description: Name of the particular virtual disk. - returned: always - type: str - sample: "vDisk1" - friendly_name: - description: Friendly name of the particular virtual disk. - returned: always - type: str - sample: "Prod2 Virtual Disk" - operational_status: - description: Operational status of the particular virtual disk. - returned: always - type: str - sample: "OK" - health_status: - description: Health status of the particular virtual disk. - returned: always - type: str - sample: "Healthy" - provisioning_type: - description: Provisioning type of the particular virtual disk. - returned: always - type: str - sample: "Thin" - allocation_unit_size: - description: Allocation unit size in bytes of the particular virtual disk. - returned: always - type: int - sample: 4096 - media_type: - description: Media type of the particular virtual disk. - returned: always - type: str - sample: "Unspecified" - parity_layout: - description: Parity layout of the particular virtual disk. - returned: if existent - type: int - sample: 1 - access: - description: Access of the particular virtual disk. - returned: always - type: str - sample: "Read/Write" - detached_reason: - description: Detached reason of the particular virtual disk. - returned: always - type: str - sample: "None" - write_cache_size: - description: Write cache size in byte of the particular virtual disk. - returned: always - type: int - sample: 100 - fault_domain_awareness: - description: Fault domain awareness of the particular virtual disk. - returned: always - type: str - sample: "PhysicalDisk" - inter_leave: - description: - - Inter leave in bytes of the particular virtual disk. - returned: always - type: int - sample: 102400 - deduplication_enabled: - description: Information whether deduplication is enabled for the particular virtual disk. - returned: always - type: bool - sample: true - enclosure_aware: - description: Information whether the particular virtual disk is enclosure aware. - returned: always - type: bool - sample: false - manual_attach: - description: Information whether the particular virtual disk is manual attached. - returned: always - type: bool - sample: true - snapshot: - description: Information whether the particular virtual disk is a snapshot. - returned: always - type: bool - sample: false - tiered: - description: Information whether the particular virtual disk is tiered. - returned: always - type: bool - sample: true - physical_sector_size: - description: Physical sector size in bytes of the particular virtual disk. - returned: always - type: int - sample: 4096 - logical_sector_size: - description: Logical sector size in byte of the particular virtual disk. - returned: always - type: int - sample: 512 - available_copies: - description: Number of the available copies of the particular virtual disk. - returned: if existent - type: int - sample: 1 - columns: - description: Number of the columns of the particular virtual disk. - returned: always - type: int - sample: 2 - groups: - description: Number of the groups of the particular virtual disk. - returned: always - type: int - sample: 1 - physical_disk_redundancy: - description: Type of the physical disk redundancy of the particular virtual disk. - returned: always - type: int - sample: 1 - read_cache_size: - description: Read cache size in byte of the particular virtual disk. - returned: always - type: int - sample: 0 - request_no_spof: - description: Information whether the particular virtual disk requests no single point of failure. - returned: always - type: bool - sample: true - resiliency_setting_name: - description: Type of the physical disk redundancy of the particular virtual disk. - returned: always - type: int - sample: 1 - object_id: - description: Object ID of the particular virtual disk. - returned: always - type: str - sample: '{1}\\\\HOST\\root/Microsoft/Windows/Storage/Providers_v2\\SPACES_VirtualDisk.ObjectId=\"{}:VD:{}\"' - unique_id: - description: Unique ID of the particular virtual disk. - returned: always - type: str - sample: "260542E4C6B01D47A8FA7630FD90FFDE" - unique_id_format: - description: Unique ID format of the particular virtual disk. - returned: always - type: str - sample: "Vendor Specific" - win32_disk_drive: - description: Representation of the Win32_DiskDrive class. - returned: if existent - type: complex - contains: - availability: - description: Availability and status of the device. - returned: always - type: int - bytes_per_sector: - description: Number of bytes in each sector for the physical disk drive. - returned: always - type: int - sample: 512 - capabilities: - description: - - Array of capabilities of the media access device. - - For example, the device may support random access (3), removable media (7), and automatic cleaning (9). - returned: always - type: list - sample: - - 3 - - 4 - capability_descriptions: - description: - - List of more detailed explanations for any of the access device features indicated in the Capabilities array. - - Note, each entry of this array is related to the entry in the Capabilities array that is located at the same index. - returned: always - type: list - sample: - - Random Access - - Supports Writing - caption: - description: Short description of the object. - returned: always - type: str - sample: VMware Virtual disk SCSI Disk Device - compression_method: - description: Algorithm or tool used by the device to support compression. - returned: always - type: str - sample: Compressed - config_manager_error_code: - description: Windows Configuration Manager error code. - returned: always - type: int - sample: 0 - config_manager_user_config: - description: If True, the device is using a user-defined configuration. - returned: always - type: bool - sample: true - creation_class_name: - description: - - Name of the first concrete class to appear in the inheritance chain used in the creation of an instance. - - When used with the other key properties of the class, the property allows all instances of this class - - and its subclasses to be uniquely identified. - returned: always - type: str - sample: Win32_DiskDrive - default_block_size: - description: Default block size, in bytes, for this device. - returned: always - type: int - sample: 512 - description: - description: Description of the object. - returned: always - type: str - sample: Disk drive - device_id: - description: Unique identifier of the disk drive with other devices on the system. - returned: always - type: str - sample: "\\\\.\\PHYSICALDRIVE0" - error_cleared: - description: If True, the error reported in LastErrorCode is now cleared. - returned: always - type: bool - sample: true - error_description: - description: - - More information about the error recorded in LastErrorCode, - - and information on any corrective actions that may be taken. - returned: always - type: str - error_methodology: - description: Type of error detection and correction supported by this device. - returned: always - type: str - firmware_revision: - description: Revision for the disk drive firmware that is assigned by the manufacturer. - returned: always - type: str - sample: 1.0 - index: - description: - - Physical drive number of the given drive. - - This property is filled by the STORAGE_DEVICE_NUMBER structure returned from the IOCTL_STORAGE_GET_DEVICE_NUMBER control code - - A value of 0xffffffff indicates that the given drive does not map to a physical drive. - returned: always - type: int - sample: 0 - install_date: - description: Date and time the object was installed. This property does not need a value to indicate that the object is installed. - returned: always - type: str - interface_type: - description: Interface type of physical disk drive. - returned: always - type: str - sample: SCSI - last_error_code: - description: Last error code reported by the logical device. - returned: always - type: int - manufacturer: - description: Name of the disk drive manufacturer. - returned: always - type: str - sample: Seagate - max_block_size: - description: Maximum block size, in bytes, for media accessed by this device. - returned: always - type: int - max_media_size: - description: Maximum media size, in kilobytes, of media supported by this device. - returned: always - type: int - media_loaded: - description: - - If True, the media for a disk drive is loaded, which means that the device has a readable file system and is accessible. - - For fixed disk drives, this property will always be TRUE. - returned: always - type: bool - sample: true - media_type: - description: Type of media used or accessed by this device. - returned: always - type: str - sample: Fixed hard disk media - min_block_size: - description: Minimum block size, in bytes, for media accessed by this device. - returned: always - type: int - model: - description: Manufacturer's model number of the disk drive. - returned: always - type: str - sample: ST32171W - name: - description: Label by which the object is known. When subclassed, the property can be overridden to be a key property. - returned: always - type: str - sample: \\\\.\\PHYSICALDRIVE0 - needs_cleaning: - description: - - If True, the media access device needs cleaning. - - Whether manual or automatic cleaning is possible is indicated in the Capabilities property. - returned: always - type: bool - number_of_media_supported: - description: - - Maximum number of media which can be supported or inserted - - (when the media access device supports multiple individual media). - returned: always - type: int - partitions: - description: Number of partitions on this physical disk drive that are recognized by the operating system. - returned: always - type: int - sample: 3 - pnp_device_id: - description: Windows Plug and Play device identifier of the logical device. - returned: always - type: str - sample: "SCSI\\DISK&VEN_VMWARE&PROD_VIRTUAL_DISK\\5&1982005&0&000000" - power_management_capabilities: - description: Array of the specific power-related capabilities of a logical device. - returned: always - type: list - power_management_supported: - description: - - If True, the device can be power-managed (can be put into suspend mode, and so on). - - The property does not indicate that power management features are currently enabled, - - only that the logical device is capable of power management. - returned: always - type: bool - scsi_bus: - description: SCSI bus number of the disk drive. - returned: always - type: int - sample: 0 - scsi_logical_unit: - description: SCSI logical unit number (LUN) of the disk drive. - returned: always - type: int - sample: 0 - scsi_port: - description: SCSI port number of the disk drive. - returned: always - type: int - sample: 0 - scsi_target_id: - description: SCSI identifier number of the disk drive. - returned: always - type: int - sample: 0 - sectors_per_track: - description: Number of sectors in each track for this physical disk drive. - returned: always - type: int - sample: 63 - serial_number: - description: Number allocated by the manufacturer to identify the physical media. - returned: always - type: str - sample: 6000c298f34101b38cb2b2508926b9de - signature: - description: Disk identification. This property can be used to identify a shared resource. - returned: always - type: int - size: - description: - - Size of the disk drive. It is calculated by multiplying the total number of cylinders, tracks in each cylinder, - - sectors in each track, and bytes in each sector. - returned: always - type: int - sample: 53686402560 - status: - description: - - Current status of the object. Various operational and nonoperational statuses can be defined. - - 'Operational statuses include: "OK", "Degraded", and "Pred Fail"' - - (an element, such as a SMART-enabled hard disk drive, may be functioning properly but predicting a failure in the near future). - - 'Nonoperational statuses include: "Error", "Starting", "Stopping", and "Service".' - - '"Service", could apply during mirror-resilvering of a disk, reload of a user permissions list, or other administrative work.' - - Not all such work is online, yet the managed element is neither "OK" nor in one of the other states. - returned: always - type: str - sample: OK - status_info: - description: - - State of the logical device. If this property does not apply to the logical device, the value 5 (Not Applicable) should be used. - returned: always - type: int - system_creation_class_name: - description: Value of the scoping computer's CreationClassName property. - returned: always - type: str - sample: Win32_ComputerSystem - system_name: - description: Name of the scoping system. - returned: always - type: str - sample: WILMAR-TEST-123 - total_cylinders: - description: - - Total number of cylinders on the physical disk drive. - - 'Note: the value for this property is obtained through extended functions of BIOS interrupt 13h.' - - The value may be inaccurate if the drive uses a translation scheme to support high-capacity disk sizes. - - Consult the manufacturer for accurate drive specifications. - returned: always - type: int - sample: 6527 - total_heads: - description: - - Total number of heads on the disk drive. - - 'Note: the value for this property is obtained through extended functions of BIOS interrupt 13h.' - - The value may be inaccurate if the drive uses a translation scheme to support high-capacity disk sizes. - - Consult the manufacturer for accurate drive specifications. - returned: always - type: int - sample: 255 - total_sectors: - description: - - Total number of sectors on the physical disk drive. - - 'Note: the value for this property is obtained through extended functions of BIOS interrupt 13h.' - - The value may be inaccurate if the drive uses a translation scheme to support high-capacity disk sizes. - - Consult the manufacturer for accurate drive specifications. - returned: always - type: int - sample: 104856255 - total_tracks: - description: - - Total number of tracks on the physical disk drive. - - 'Note: the value for this property is obtained through extended functions of BIOS interrupt 13h.' - - The value may be inaccurate if the drive uses a translation scheme to support high-capacity disk sizes. - - Consult the manufacturer for accurate drive specifications. - returned: always - type: int - sample: 1664385 - tracks_per_cylinder: - description: - - Number of tracks in each cylinder on the physical disk drive. - - 'Note: the value for this property is obtained through extended functions of BIOS interrupt 13h.' - - The value may be inaccurate if the drive uses a translation scheme to support high-capacity disk sizes. - - Consult the manufacturer for accurate drive specifications. - returned: always - type: int - sample: 255 -''' diff --git a/lib/ansible/modules/windows/win_disk_image.ps1 b/lib/ansible/modules/windows/win_disk_image.ps1 deleted file mode 100644 index a5627fde538..00000000000 --- a/lib/ansible/modules/windows/win_disk_image.ps1 +++ /dev/null @@ -1,78 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Red Hat, Inc. -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" -Set-StrictMode -Version 2 - -If(-not (Get-Command Get-DiskImage -ErrorAction SilentlyContinue)) { - Fail-Json -message "win_disk_image requires Windows 8+ or Windows Server 2012+" -} - -$parsed_args = Parse-Args $args -supports_check_mode $true - -$result = @{changed=$false} - -$image_path = Get-AnsibleParam $parsed_args "image_path" -failifempty $result -$state = Get-AnsibleParam $parsed_args "state" -default "present" -validateset "present","absent" -$check_mode = Get-AnsibleParam $parsed_args "_ansible_check_mode" -default $false - -$di = Get-DiskImage $image_path - -If($state -eq "present") { - If(-not $di.Attached) { - $result.changed = $true - - If(-not $check_mode) { - $di = Mount-DiskImage $image_path -PassThru - - # the actual mount is async, so the CIMInstance result may not immediately contain the data we need - $retry_count = 0 - While(-not $di.Attached -and $retry_count -lt 5) { - Start-Sleep -Seconds 1 > $null - $di = $di | Get-DiskImage - $retry_count++ - } - - If(-not $di.Attached) { - Fail-Json $result -message "Timed out waiting for disk to attach" - } - } - } - - # FUTURE: detect/handle "ejected" ISOs - # FUTURE: support explicit drive letter and NTFS in-volume mountpoints. - # VHDs don't always auto-assign, and other system settings can prevent automatic assignment - - If($di.Attached) { # only try to get the mount_path if the disk is attached ( - If($di.StorageType -eq 1) { # ISO, we can get the mountpoint directly from Get-Volume - $drive_letters = ($di | Get-Volume).DriveLetter - } - ElseIf($di.StorageType -in @(2,3)) { # VHD/VHDX, need Get-Disk + Get-Partition to discover mountpoint - $drive_letters = ($di | Get-Disk | Get-Partition).DriveLetter - } - # remove any null entries (no drive letter) - $drive_letters = $drive_letters | Where-Object { $_ } - - If(-not $drive_letters) { - Fail-Json -message "Unable to retrieve drive letter from mounted image" - } - - # mount_path is deprecated and will be removed in 2.11, use mount_paths which contains all the partitions instead - $result.mount_path = $drive_letters[0] + ":\" - $result.mount_paths = @($drive_letters | ForEach-Object { "$($_):\" }) - } -} -ElseIf($state -eq "absent") { - If($di.Attached) { - $result.changed = $true - If(-not $check_mode) { - Dismount-DiskImage $image_path > $null - } - } -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_disk_image.py b/lib/ansible/modules/windows/win_disk_image.py deleted file mode 100644 index 9a83e49693f..00000000000 --- a/lib/ansible/modules/windows/win_disk_image.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Red Hat, Inc. -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' -module: win_disk_image -short_description: Manage ISO/VHD/VHDX mounts on Windows hosts -version_added: '2.3' -description: - - Manages mount behavior for a specified ISO, VHD, or VHDX image on a Windows host. When C(state) is C(present), - the image will be mounted under a system-assigned drive letter, which will be returned in the C(mount_path) value - of the module result. - - Requires Windows 8+ or Windows Server 2012+. -options: - image_path: - description: - - Path to an ISO, VHD, or VHDX image on the target Windows host (the file cannot reside on a network share) - type: str - required: yes - state: - description: - - Whether the image should be present as a drive-letter mount or not. - type: str - choices: [ absent, present ] - default: present -author: - - Matt Davis (@nitzmahone) -''' - -EXAMPLES = r''' -# Run installer from mounted ISO, then unmount -- name: Ensure an ISO is mounted - win_disk_image: - image_path: C:\install.iso - state: present - register: disk_image_out - -- name: Run installer from mounted ISO - win_package: - path: '{{ disk_image_out.mount_paths[0] }}setup\setup.exe' - product_id: 35a4e767-0161-46b0-979f-e61f282fee21 - state: present - -- name: Unmount ISO - win_disk_image: - image_path: C:\install.iso - state: absent -''' - -RETURN = r''' -mount_path: - description: Filesystem path where the target image is mounted, this has been deprecated in favour of C(mount_paths). - returned: when C(state) is C(present) - type: str - sample: F:\ -mount_paths: - description: A list of filesystem paths mounted from the target image. - returned: when C(state) is C(present) - type: list - sample: [ 'E:\', 'F:\' ] -''' diff --git a/lib/ansible/modules/windows/win_dns_record.ps1 b/lib/ansible/modules/windows/win_dns_record.ps1 deleted file mode 100644 index e3937dbad88..00000000000 --- a/lib/ansible/modules/windows/win_dns_record.ps1 +++ /dev/null @@ -1,149 +0,0 @@ -#!powershell - -# Copyright: (c) 2019, Hitachi ID Systems, Inc. -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic - -$spec = @{ - options = @{ - name = @{ type = "str"; required = $true } - state = @{ type = "str"; choices = "absent", "present"; default = "present" } - ttl = @{ type = "int"; default = "3600" } - type = @{ type = "str"; choices = "A","AAAA","CNAME","PTR"; required = $true } - value = @{ type = "list"; elements = "str"; default = @() ; aliases=@( 'values' )} - zone = @{ type = "str"; required = $true } - computer_name = @{ type = "str" } - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$name = $module.Params.name -$state = $module.Params.state -$ttl = $module.Params.ttl -$type = $module.Params.type -$values = $module.Params.value -$zone = $module.Params.zone -$dns_computer_name = $module.Params.computer_name - - -$extra_args = @{} -if ($null -ne $dns_computer_name) { - $extra_args.ComputerName = $dns_computer_name -} - -if ($state -eq 'present') { - if ($values.Count -eq 0) { - $module.FailJson("Parameter 'values' must be non-empty when state='present'") - } -} else { - if ($values.Count -ne 0) { - $module.FailJson("Parameter 'values' must be undefined or empty when state='absent'") - } -} - - -# TODO: add warning for forest minTTL override -- see https://docs.microsoft.com/en-us/windows/desktop/ad/configuration-of-ttl-limits -if ($ttl -lt 1 -or $ttl -gt 31557600) { - $module.FailJson("Parameter 'ttl' must be between 1 and 31557600") -} -$ttl = New-TimeSpan -Seconds $ttl - - -if (($type -eq 'CNAME' -or $type -eq 'PTR') -and $null -ne $values -and $values.Count -gt 0 -and $zone[-1] -ne '.') { - # CNAMEs and PTRs should be '.'-terminated, or record matching will fail - $values = $values | ForEach-Object { - if ($_ -Like "*.") { $_ } else { "$_." } - } -} - - -$record_argument_name = @{ - A = "IPv4Address"; - AAAA = "IPv6Address"; - CNAME = "HostNameAlias"; - # MX = "MailExchange"; - # NS = "NameServer"; - PTR = "PtrDomainName"; - # TXT = "DescriptiveText" -}[$type] - - -$changes = @{ - before = ""; - after = "" -} - - -$records = Get-DnsServerResourceRecord -ZoneName $zone -Name $name -RRType $type -Node -ErrorAction:Ignore @extra_args | Sort-Object -if ($null -ne $records) { - # We use [Hashtable]$required_values below as a set rather than a map. - # It provides quick lookup to test existing DNS record against. By removing - # items as each is processed, whatever remains at the end is missing - # content (that needs to be added). - $required_values = @{} - foreach ($value in $values) { - $required_values[$value.ToString()] = $null - } - - foreach ($record in $records) { - $record_value = $record.RecordData.$record_argument_name.ToString() - - if ($required_values.ContainsKey($record_value)) { - # This record matches one of the values; but does it match the TTL? - if ($record.TimeToLive -ne $ttl) { - $new_record = $record.Clone() - $new_record.TimeToLive = $ttl - Set-DnsServerResourceRecord -ZoneName $zone -OldInputObject $record -NewInputObject $new_record -WhatIf:$module.CheckMode @extra_args - - $changes.before += "[$zone] $($record.HostName) $($record.TimeToLive.TotalSeconds) IN $type $record_value`n" - $changes.after += "[$zone] $($record.HostName) $($ttl.TotalSeconds) IN $type $record_value`n" - $module.Result.changed = $true - } - - # Cross this one off the list, so we don't try adding it later - $required_values.Remove($record_value) - } else { - # This record doesn't match any of the values, and must be removed - $record | Remove-DnsServerResourceRecord -ZoneName $zone -Force -WhatIf:$module.CheckMode @extra_args - - $changes.before += "[$zone] $($record.HostName) $($record.TimeToLive.TotalSeconds) IN $type $record_value`n" - $module.Result.changed = $true - } - } - - # Whatever is left in $required_values needs to be added - $values = $required_values.Keys -} - - -if ($null -ne $values -and $values.Count -gt 0) { - foreach ($value in $values) { - $splat_args = @{ $type = $true; $record_argument_name = $value } - $module.Result.debug_splat_args = $splat_args - try { - Add-DnsServerResourceRecord -ZoneName $zone -Name $name -AllowUpdateAny -TimeToLive $ttl @splat_args -WhatIf:$module.CheckMode @extra_args - } catch { - $module.FailJson("Error adding DNS $type resource $name in zone $zone with value $value", $_) - } - $changes.after += "[$zone] $name $($ttl.TotalSeconds) IN $type $value`n" - } - - $module.Result.changed = $true -} - -if ($module.CheckMode) { - # Simulated changes - $module.Diff.before = $changes.before - $module.Diff.after = $changes.after -} else { - # Real changes - $records_end = Get-DnsServerResourceRecord -ZoneName $zone -Name $name -RRType $type -Node -ErrorAction:Ignore @extra_args | Sort-Object - - $module.Diff.before = @($records | ForEach-Object { "[$zone] $($_.HostName) $($_.TimeToLive.TotalSeconds) IN $type $($_.RecordData.$record_argument_name.ToString())`n" }) -join '' - $module.Diff.after = @($records_end | ForEach-Object { "[$zone] $($_.HostName) $($_.TimeToLive.TotalSeconds) IN $type $($_.RecordData.$record_argument_name.ToString())`n" }) -join '' -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_dns_record.py b/lib/ansible/modules/windows/win_dns_record.py deleted file mode 100644 index 0d5e631072d..00000000000 --- a/lib/ansible/modules/windows/win_dns_record.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2019, Hitachi ID Systems, Inc. -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# This is a windows documentation stub. The actual code lives in the .ps1 -# file of the same name. - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_dns_record -version_added: "2.8" -short_description: Manage Windows Server DNS records -description: -- Manage DNS records within an existing Windows Server DNS zone. -author: John Nelson (@johnboy2) -requirements: - - This module requires Windows 8, Server 2012, or newer. -options: - name: - description: - - The name of the record. - required: yes - type: str - state: - description: - - Whether the record should exist or not. - choices: [ absent, present ] - default: present - type: str - ttl: - description: - - The "time to live" of the record, in seconds. - - Ignored when C(state=absent). - - Valid range is 1 - 31557600. - - Note that an Active Directory forest can specify a minimum TTL, and will - dynamically "round up" other values to that minimum. - default: 3600 - type: int - type: - description: - - The type of DNS record to manage. - choices: [ A, AAAA, CNAME, PTR ] - required: yes - type: str - value: - description: - - The value(s) to specify. Required when C(state=present). - - When C(type=PTR) only the partial part of the IP should be given. - aliases: [ values ] - type: list - zone: - description: - - The name of the zone to manage (eg C(example.com)). - - The zone must already exist. - required: yes - type: str - computer_name: - description: - - Specifies a DNS server. - - You can specify an IP address or any value that resolves to an IP - address, such as a fully qualified domain name (FQDN), host name, or - NETBIOS name. - type: str -''' - -EXAMPLES = r''' -# Demonstrate creating a matching A and PTR record. - -- name: Create database server record - win_dns_record: - name: "cgyl1404p.amer.example.com" - type: "A" - value: "10.1.1.1" - zone: "amer.example.com" - -- name: Create matching PTR record - win_dns_record: - name: "1.1.1" - type: "PTR" - value: "db1" - zone: "10.in-addr.arpa" - -# Demonstrate replacing an A record with a CNAME - -- name: Remove static record - win_dns_record: - name: "db1" - type: "A" - state: absent - zone: "amer.example.com" - -- name: Create database server alias - win_dns_record: - name: "db1" - type: "CNAME" - value: "cgyl1404p.amer.example.com" - zone: "amer.example.com" - -# Demonstrate creating multiple A records for the same name - -- name: Create multiple A record values for www - win_dns_record: - name: "www" - type: "A" - values: - - 10.0.42.5 - - 10.0.42.6 - - 10.0.42.7 - zone: "example.com" - -# Demonstrates a partial update (replace some existing values with new ones) -# for a pre-existing name - -- name: Update www host with new addresses - win_dns_record: - name: "www" - type: "A" - values: - - 10.0.42.5 # this old value was kept (others removed) - - 10.0.42.12 # this new value was added - zone: "example.com" -''' - -RETURN = r''' -''' diff --git a/lib/ansible/modules/windows/win_domain_computer.ps1 b/lib/ansible/modules/windows/win_domain_computer.ps1 deleted file mode 100644 index 3da4a6f7854..00000000000 --- a/lib/ansible/modules/windows/win_domain_computer.ps1 +++ /dev/null @@ -1,208 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, AMTEGA - Xunta de Galicia -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - - -# ------------------------------------------------------------------------------ -$ErrorActionPreference = "Stop" - -# Preparing result -$result = @{} -$result.changed = $false - -# Parameter ingestion -$params = Parse-Args $args -supports_check_mode $true - -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff_support = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -failifempty $true -resultobj $result -$sam_account_name = Get-AnsibleParam -obj $params -name "sam_account_name" -default "$name$" -If (-not $sam_account_name.EndsWith("$")) { - Fail-Json -obj $result -message "sam_account_name must end in $" -} -$enabled = Get-AnsibleParam -obj $params -name "enabled" -type "bool" -default $true -$description = Get-AnsibleParam -obj $params -name "description" -default $null -$domain_username = Get-AnsibleParam -obj $params -name "domain_username" -type "str" -$domain_password = Get-AnsibleParam -obj $params -name "domain_password" -type "str" -failifempty ($null -ne $domain_username) -$domain_server = Get-AnsibleParam -obj $params -name "domain_server" -type "str" -$state = Get-AnsibleParam -obj $params -name "state" -ValidateSet "present","absent" -default "present" - -$extra_args = @{} -if ($null -ne $domain_username) { - $domain_password = ConvertTo-SecureString $domain_password -AsPlainText -Force - $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $domain_username, $domain_password - $extra_args.Credential = $credential -} -if ($null -ne $domain_server) { - $extra_args.Server = $domain_server -} - -If ($state -eq "present") { - $dns_hostname = Get-AnsibleParam -obj $params -name "dns_hostname" -failifempty $true -resultobj $result - $ou = Get-AnsibleParam -obj $params -name "ou" -failifempty $true -resultobj $result - $distinguished_name = "CN=$name,$ou" - - $desired_state = [ordered]@{ - name = $name - sam_account_name = $sam_account_name - dns_hostname = $dns_hostname - ou = $ou - distinguished_name = $distinguished_name - description = $description - enabled = $enabled - state = $state - } -} Else { - $desired_state = [ordered]@{ - name = $name - sam_account_name = $sam_account_name - state = $state - } -} - -# ------------------------------------------------------------------------------ -Function Get-InitialState($desired_state) { - # Test computer exists - $computer = Try { - Get-ADComputer ` - -Identity $desired_state.sam_account_name ` - -Properties DistinguishedName,DNSHostName,Enabled,Name,SamAccountName,Description,ObjectClass ` - @extra_args - } Catch { $null } - If ($computer) { - $initial_state = [ordered]@{ - name = $computer.Name - sam_account_name = $computer.SamAccountName - dns_hostname = $computer.DNSHostName - # Get OU from regexp that removes all characters to the first "," - ou = $computer.DistinguishedName -creplace "^[^,]*,","" - distinguished_name = $computer.DistinguishedName - description = $computer.Description - enabled = $computer.Enabled - state = "present" - } - } Else { - $initial_state = [ordered]@{ - name = $desired_state.name - sam_account_name = $desired_state.sam_account_name - state = "absent" - } - } - - return $initial_state -} - -# ------------------------------------------------------------------------------ -Function Set-ConstructedState($initial_state, $desired_state) { - Try { - Set-ADComputer ` - -Identity $desired_state.name ` - -SamAccountName $desired_state.name ` - -DNSHostName $desired_state.dns_hostname ` - -Enabled $desired_state.enabled ` - -Description $desired_state.description ` - -WhatIf:$check_mode ` - @extra_args - } Catch { - Fail-Json -obj $result -message "Failed to set the AD object $($desired_state.name): $($_.Exception.Message)" - } - - If ($initial_state.distinguished_name -cne $desired_state.distinguished_name) { - # Move computer to OU - Try { - Get-ADComputer -Identity $desired_state.sam_account_name @extra_args | - Move-ADObject ` - -TargetPath $desired_state.ou ` - -Confirm:$False ` - -WhatIf:$check_mode ` - @extra_args - } Catch { - Fail-Json -obj $result -message "Failed to move the AD object $($initial_state.distinguished_name) to $($desired_state.distinguished_name): $($_.Exception.Message)" - } - } - $result.changed = $true -} - -# ------------------------------------------------------------------------------ -Function Add-ConstructedState($desired_state) { - Try { - New-ADComputer ` - -Name $desired_state.name ` - -SamAccountName $desired_state.sam_account_name ` - -DNSHostName $desired_state.dns_hostname ` - -Path $desired_state.ou ` - -Enabled $desired_state.enabled ` - -Description $desired_state.description ` - -WhatIf:$check_mode ` - @extra_args - } Catch { - Fail-Json -obj $result -message "Failed to create the AD object $($desired_state.name): $($_.Exception.Message)" - } - - $result.changed = $true -} - -# ------------------------------------------------------------------------------ -Function Remove-ConstructedState($initial_state) { - Try { - Get-ADComputer -Identity $initial_state.sam_account_name @extra_args | - Remove-ADObject ` - -Recursive ` - -Confirm:$False ` - -WhatIf:$check_mode ` - @extra_args - } Catch { - Fail-Json -obj $result -message "Failed to remove the AD object $($desired_state.name): $($_.Exception.Message)" - } - - $result.changed = $true -} - -# ------------------------------------------------------------------------------ -Function are_hashtables_equal($x, $y) { - # Compare not nested HashTables - Foreach ($key in $x.Keys) { - If (($y.Keys -notcontains $key) -or ($x[$key] -cne $y[$key])) { - Return $false - } - } - foreach ($key in $y.Keys) { - if (($x.Keys -notcontains $key) -or ($x[$key] -cne $y[$key])) { - Return $false - } - } - Return $true -} - -# ------------------------------------------------------------------------------ -$initial_state = Get-InitialState($desired_state) - -If ($desired_state.state -eq "present") { - If ($initial_state.state -eq "present") { - $in_desired_state = are_hashtables_equal $initial_state $desired_state - - If (-not $in_desired_state) { - Set-ConstructedState $initial_state $desired_state - } - } Else { # $desired_state.state = "Present" & $initial_state.state = "Absent" - Add-ConstructedState($desired_state) - } - } Else { # $desired_state.state = "Absent" - If ($initial_state.state -eq "present") { - Remove-ConstructedState($initial_state) - } - } - -If ($diff_support) { - $diff = @{ - before = $initial_state - after = $desired_state - } - $result.diff = $diff -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_domain_computer.py b/lib/ansible/modules/windows/win_domain_computer.py deleted file mode 100644 index f95cc5cd72d..00000000000 --- a/lib/ansible/modules/windows/win_domain_computer.py +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, AMTEGA - Xunta de Galicia -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_domain_computer -short_description: Manage computers in Active Directory -description: - - Create, read, update and delete computers in Active Directory using a - windows bridge computer to launch New-ADComputer, Get-ADComputer, - Set-ADComputer, Remove-ADComputer and Move-ADObject powershell commands. -version_added: '2.6' -options: - name: - description: - - Specifies the name of the object. - - This parameter sets the Name property of the Active Directory object. - - The LDAP display name (ldapDisplayName) of this property is name. - type: str - required: true - sam_account_name: - description: - - Specifies the Security Account Manager (SAM) account name of the - computer. - - It maximum is 256 characters, 15 is advised for older - operating systems compatibility. - - The LDAP display name (ldapDisplayName) for this property is sAMAccountName. - - If ommitted the value is the same as C(name). - - Note that all computer SAMAccountNames need to end with a $. - type: str - enabled: - description: - - Specifies if an account is enabled. - - An enabled account requires a password. - - This parameter sets the Enabled property for an account object. - - This parameter also sets the ADS_UF_ACCOUNTDISABLE flag of the - Active Directory User Account Control (UAC) attribute. - type: bool - default: yes - ou: - description: - - Specifies the X.500 path of the Organizational Unit (OU) or container - where the new object is created. Required when I(state=present). - type: str - description: - description: - - Specifies a description of the object. - - This parameter sets the value of the Description property for the object. - - The LDAP display name (ldapDisplayName) for this property is description. - type: str - default: '' - dns_hostname: - description: - - Specifies the fully qualified domain name (FQDN) of the computer. - - This parameter sets the DNSHostName property for a computer object. - - The LDAP display name for this property is dNSHostName. - - Required when I(state=present). - type: str - domain_username: - description: - - The username to use when interacting with AD. - - If this is not set then the user Ansible used to log in with will be - used instead when using CredSSP or Kerberos with credential delegation. - type: str - version_added: '2.8' - domain_password: - description: - - The password for I(username). - type: str - version_added: '2.8' - domain_server: - description: - - Specifies the Active Directory Domain Services instance to connect to. - - Can be in the form of an FQDN or NetBIOS name. - - If not specified then the value is based on the domain of the computer - running PowerShell. - type: str - version_added: '2.8' - state: - description: - - Specified whether the computer should be C(present) or C(absent) in - Active Directory. - type: str - choices: [ absent, present ] - default: present -seealso: -- module: win_domain -- module: win_domain_controller -- module: win_domain_group -- module: win_domain_membership -- module: win_domain_user -author: -- Daniel Sánchez Fábregas (@Daniel-Sanchez-Fabregas) -''' - -EXAMPLES = r''' - - name: Add linux computer to Active Directory OU using a windows machine - win_domain_computer: - name: one_linux_server.my_org.local - sam_account_name: linux_server$ - dns_hostname: one_linux_server.my_org.local - ou: "OU=servers,DC=my_org,DC=local" - description: Example of linux server - enabled: yes - state: present - delegate_to: my_windows_bridge.my_org.local - - - name: Remove linux computer from Active Directory using a windows machine - win_domain_computer: - name: one_linux_server.my_org.local - state: absent - delegate_to: my_windows_bridge.my_org.local -''' - -RETURN = r''' -''' diff --git a/lib/ansible/modules/windows/win_domain_group.ps1 b/lib/ansible/modules/windows/win_domain_group.ps1 deleted file mode 100644 index b392c52c49e..00000000000 --- a/lib/ansible/modules/windows/win_domain_group.ps1 +++ /dev/null @@ -1,344 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Jordan Borean , and others -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff_mode = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$display_name = Get-AnsibleParam -obj $params -name "display_name" -type "str" -$domain_username = Get-AnsibleParam -obj $params -name "domain_username" -type "str" -$domain_password = Get-AnsibleParam -obj $params -name "domain_password" -type "str" -failifempty ($null -ne $domain_username) -$description = Get-AnsibleParam -obj $params -name "description" -type "str" -$category = Get-AnsibleParam -obj $params -name "category" -type "str" -validateset "distribution","security" -$scope = Get-AnsibleParam -obj $params -name "scope" -type "str" -validateset "domainlocal","global","universal" -$managed_by = Get-AnsibleParam -obj $params -name "managed_by" -type "str" -$attributes = Get-AnsibleParam -obj $params -name "attributes" -$organizational_unit = Get-AnsibleParam -obj $params -name "organizational_unit" -type "str" -aliases "ou","path" -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent" -$protect = Get-AnsibleParam -obj $params -name "protect" -type "bool" -$ignore_protection = Get-AnsibleParam -obj $params -name "ignore_protection" -type "bool" -default $false -$domain_server = Get-AnsibleParam -obj $params -name "domain_server" -type "str" - -$result = @{ - changed = $false - created = $false -} - -if ($diff_mode) { - $result.diff = @{} -} - -if (-not (Get-Module -Name ActiveDirectory -ListAvailable)) { - Fail-Json $result "win_domain_group requires the ActiveDirectory PS module to be installed" -} -Import-Module ActiveDirectory - -$extra_args = @{} -if ($null -ne $domain_username) { - $domain_password = ConvertTo-SecureString $domain_password -AsPlainText -Force - $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $domain_username, $domain_password - $extra_args.Credential = $credential -} -if ($null -ne $domain_server) { - $extra_args.Server = $domain_server -} - -try { - $group = Get-ADGroup -Identity $name -Properties * @extra_args -} catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { - $group = $null -} catch { - Fail-Json $result "failed to retrieve initial details for group $($name): $($_.Exception.Message)" -} -if ($state -eq "absent") { - if ($null -ne $group) { - if ($group.ProtectedFromAccidentalDeletion -eq $true -and $ignore_protection -eq $true) { - $group = $group | Set-ADObject -ProtectedFromAccidentalDeletion $false -WhatIf:$check_mode -PassThru @extra_args - } elseif ($group.ProtectedFromAccidentalDeletion -eq $true -and $ignore_protection -eq $false) { - Fail-Json $result "cannot delete group $name when ProtectedFromAccidentalDeletion is turned on, run this module with ignore_protection=true to override this" - } - - try { - $group | Remove-ADGroup -Confirm:$false -WhatIf:$check_mode @extra_args - } catch { - Fail-Json $result "failed to remove group $($name): $($_.Exception.Message)" - } - - $result.changed = $true - if ($diff_mode) { - $result.diff.prepared = "-[$name]" - } - } -} else { - # validate that path is an actual path - if ($null -ne $organizational_unit) { - try { - Get-ADObject -Identity $organizational_unit @extra_args | Out-Null - } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { - Fail-Json $result "the group path $organizational_unit does not exist, please specify a valid LDAP path" - } - } - - $diff_text = $null - if ($null -ne $group) { - # will be overridden later if no change actually occurs - $diff_text += "[$name]`n" - - # change the path of the group - if ($null -ne $organizational_unit) { - $group_cn = $group.CN - $existing_path = $group.DistinguishedName -replace "^CN=$group_cn,",'' - if ($existing_path -ne $organizational_unit) { - $protection_disabled = $false - if ($group.ProtectedFromAccidentalDeletion -eq $true -and $ignore_protection -eq $true) { - $group | Set-ADObject -ProtectedFromAccidentalDeletion $false -WhatIf:$check_mode -PassThru @extra_args | Out-Null - $protection_disabled = $true - } elseif ($group.ProtectedFromAccidentalDeletion -eq $true -and $ignore_protection -eq $false) { - Fail-Json $result "cannot move group $name when ProtectedFromAccidentalDeletion is turned on, run this module with ignore_protection=true to override this" - } - - try { - $group = $group | Move-ADObject -Targetpath $organizational_unit -WhatIf:$check_mode -PassThru @extra_args - } catch { - Fail-Json $result "failed to move group from $existing_path to $($organizational_unit): $($_.Exception.Message)" - } finally { - if ($protection_disabled -eq $true) { - $group | Set-ADObject -ProtectedFromAccidentalDeletion $true -WhatIf:$check_mode -PassThru @extra_args | Out-Null - } - } - - $result.changed = $true - $diff_text += "-DistinguishedName = CN=$group_cn,$existing_path`n+DistinguishedName = CN=$group_cn,$organizational_unit`n" - - if ($protection_disabled -eq $true) { - $group | Set-ADObject -ProtectedFromAccidentalDeletion $true -WhatIf:$check_mode @extra_args | Out-Null - } - # get the group again once we have moved it - $group = Get-ADGroup -Identity $name -Properties * @extra_args - } - } - - # change attributes of group - $extra_scope_change = $null - $run_change = $false - $set_args = $extra_args.Clone() - - if ($null -ne $scope) { - if ($group.GroupScope -ne $scope) { - # you cannot from from Global to DomainLocal and vice-versa, we - # need to change it to Universal and then finally to the target - # scope - if ($group.GroupScope -eq "global" -and $scope -eq "domainlocal") { - $set_args.GroupScope = "Universal" - $extra_scope_change = $scope - } elseif ($group.GroupScope -eq "domainlocal" -and $scope -eq "global") { - $set_args.GroupScope = "Universal" - $extra_scope_change = $scope - } else { - $set_args.GroupScope = $scope - } - $run_change = $true - $diff_text += "-GroupScope = $($group.GroupScope)`n+GroupScope = $scope`n" - } - } - - if ($null -ne $description -and $group.Description -cne $description) { - $set_args.Description = $description - $run_change = $true - $diff_text += "-Description = $($group.Description)`n+Description = $description`n" - } - - if ($null -ne $display_name -and $group.DisplayName -cne $display_name) { - $set_args.DisplayName = $display_name - $run_change = $true - $diff_text += "-DisplayName = $($group.DisplayName)`n+DisplayName = $display_name`n" - } - - if ($null -ne $category -and $group.GroupCategory -ne $category) { - $set_args.GroupCategory = $category - $run_change = $true - $diff_text += "-GroupCategory = $($group.GroupCategory)`n+GroupCategory = $category`n" - } - - if ($null -ne $managed_by) { - if ($null -eq $group.ManagedBy) { - $set_args.ManagedBy = $managed_by - $run_change = $true - $diff_text += "+ManagedBy = $managed_by`n" - } else { - try { - $managed_by_object = Get-ADGroup -Identity $managed_by @extra_args - } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { - try { - $managed_by_object = Get-ADUser -Identity $managed_by @extra_args - } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { - Fail-Json $result "failed to find managed_by user or group $managed_by to be used for comparison" - } - } - - if ($group.ManagedBy -ne $managed_by_object.DistinguishedName) { - $set_args.ManagedBy = $managed_by - $run_change = $true - $diff_text += "-ManagedBy = $($group.ManagedBy)`n+ManagedBy = $($managed_by_object.DistinguishedName)`n" - } - } - } - - if ($null -ne $attributes) { - $add_attributes = @{} - $replace_attributes = @{} - foreach ($attribute in $attributes.GetEnumerator()) { - $attribute_name = $attribute.Name - $attribute_value = $attribute.Value - - $valid_property = [bool]($group.PSobject.Properties.name -eq $attribute_name) - if ($valid_property) { - $existing_value = $group.$attribute_name - if ($existing_value -cne $attribute_value) { - $replace_attributes.$attribute_name = $attribute_value - $diff_text += "-$attribute_name = $existing_value`n+$attribute_name = $attribute_value`n" - } - } else { - $add_attributes.$attribute_name = $attribute_value - $diff_text += "+$attribute_name = $attribute_value`n" - } - } - if ($add_attributes.Count -gt 0) { - $set_args.Add = $add_attributes - $run_change = $true - } - if ($replace_attributes.Count -gt 0) { - $set_args.Replace = $replace_attributes - $run_change = $true - } - } - - if ($run_change) { - try { - $group = $group | Set-ADGroup -WhatIf:$check_mode -PassThru @set_args - } catch { - Fail-Json $result "failed to change group $($name): $($_.Exception.Message)" - } - $result.changed = $true - - if ($null -ne $extra_scope_change) { - try { - $group = $group | Set-ADGroup -GroupScope $extra_scope_change -WhatIf:$check_mode -PassThru @extra_args - } catch { - Fail-Json $result "failed to change scope of group $name to $($scope): $($_.Exception.Message)" - } - } - } - - # make sure our diff text is null if no change occurred - if ($result.changed -eq $false) { - $diff_text = $null - } - } else { - # validate if scope is set - if ($null -eq $scope) { - Fail-Json $result "scope must be set when state=present and the group doesn't exist" - } - - $diff_text += "+[$name]`n+Scope = $scope`n" - $add_args = $extra_args.Clone() - $add_args.Name = $name - $add_args.GroupScope = $scope - - if ($null -ne $description) { - $add_args.Description = $description - $diff_text += "+Description = $description`n" - } - - if ($null -ne $display_name) { - $add_args.DisplayName = $display_name - $diff_text += "+DisplayName = $display_name`n" - } - - if ($null -ne $category) { - $add_args.GroupCategory = $category - $diff_text += "+GroupCategory = $category`n" - } - - if ($null -ne $managed_by) { - $add_args.ManagedBy = $managed_by - $diff_text += "+ManagedBy = $managed_by`n" - } - - if ($null -ne $attributes) { - $add_args.OtherAttributes = $attributes - foreach ($attribute in $attributes.GetEnumerator()) { - $diff_text += "+$($attribute.Name) = $($attribute.Value)`n" - } - } - - if ($null -ne $organizational_unit) { - $add_args.Path = $organizational_unit - $diff_text += "+Path = $organizational_unit`n" - } - - try { - $group = New-AdGroup -WhatIf:$check_mode -PassThru @add_args - } catch { - Fail-Json $result "failed to create group $($name): $($_.Exception.Message)" - } - $result.changed = $true - $result.created = $true - } - - # set the protection value - if ($null -ne $protect) { - if (-not $check_mode) { - $group = Get-ADGroup -Identity $name -Properties * @extra_args - } - $existing_protection_value = $group.ProtectedFromAccidentalDeletion - if ($null -eq $existing_protection_value) { - $existing_protection_value = $false - } - if ($existing_protection_value -ne $protect) { - $diff_text += @" --ProtectedFromAccidentalDeletion = $existing_protection_value -+ProtectedFromAccidentalDeletion = $protect -"@ - - $group | Set-ADObject -ProtectedFromAccidentalDeletion $protect -WhatIf:$check_mode -PassThru @extra_args - $result.changed = $true - } - } - - if ($diff_mode -and $null -ne $diff_text) { - $result.diff.prepared = $diff_text - } - - if (-not $check_mode) { - $group = Get-ADGroup -Identity $name -Properties * @extra_args - $result.sid = $group.SID.Value - $result.description = $group.Description - $result.distinguished_name = $group.DistinguishedName - $result.display_name = $group.DisplayName - $result.name = $group.Name - $result.canonical_name = $group.CanonicalName - $result.guid = $group.ObjectGUID - $result.protected_from_accidental_deletion = $group.ProtectedFromAccidentalDeletion - $result.managed_by = $group.ManagedBy - $result.group_scope = ($group.GroupScope).ToString() - $result.category = ($group.GroupCategory).ToString() - - if ($null -ne $attributes) { - $result.attributes = @{} - foreach ($attribute in $attributes.GetEnumerator()) { - $attribute_name = $attribute.Name - $result.attributes.$attribute_name = $group.$attribute_name - } - } - } -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_domain_group.py b/lib/ansible/modules/windows/win_domain_group.py deleted file mode 100644 index 7a8792c1ade..00000000000 --- a/lib/ansible/modules/windows/win_domain_group.py +++ /dev/null @@ -1,242 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_domain_group -version_added: '2.4' -short_description: Creates, modifies or removes domain groups -description: -- Creates, modifies or removes groups in Active Directory. -- For local groups, use the M(win_group) module instead. -options: - attributes: - description: - - A dict of custom LDAP attributes to set on the group. - - This can be used to set custom attributes that are not exposed as module - parameters, e.g. C(mail). - - See the examples on how to format this parameter. - type: dict - category: - description: - - The category of the group, this is the value to assign to the LDAP - C(groupType) attribute. - - If a new group is created then C(security) will be used by default. - type: str - choices: [ distribution, security ] - description: - description: - - The value to be assigned to the LDAP C(description) attribute. - type: str - display_name: - description: - - The value to assign to the LDAP C(displayName) attribute. - type: str - domain_username: - description: - - The username to use when interacting with AD. - - If this is not set then the user Ansible used to log in with will be - used instead. - type: str - domain_password: - description: - - The password for C(username). - type: str - domain_server: - description: - - Specifies the Active Directory Domain Services instance to connect to. - - Can be in the form of an FQDN or NetBIOS name. - - If not specified then the value is based on the domain of the computer - running PowerShell. - type: str - version_added: '2.5' - ignore_protection: - description: - - Will ignore the C(ProtectedFromAccidentalDeletion) flag when deleting or - moving a group. - - The module will fail if one of these actions need to occur and this value - is set to C(no). - type: bool - default: no - managed_by: - description: - - The value to be assigned to the LDAP C(managedBy) attribute. - - This value can be in the forms C(Distinguished Name), C(objectGUID), - C(objectSid) or C(sAMAccountName), see examples for more details. - type: str - name: - description: - - The name of the group to create, modify or remove. - - This value can be in the forms C(Distinguished Name), C(objectGUID), - C(objectSid) or C(sAMAccountName), see examples for more details. - type: str - required: yes - organizational_unit: - description: - - The full LDAP path to create or move the group to. - - This should be the path to the parent object to create or move the group to. - - See examples for details of how this path is formed. - type: str - aliases: [ ou, path ] - protect: - description: - - Will set the C(ProtectedFromAccidentalDeletion) flag based on this value. - - This flag stops a user from deleting or moving a group to a different - path. - type: bool - scope: - description: - - The scope of the group. - - If C(state=present) and the group doesn't exist then this must be set. - type: str - choices: [domainlocal, global, universal] - state: - description: - - If C(state=present) this module will ensure the group is created and is - configured accordingly. - - If C(state=absent) this module will delete the group if it exists - type: str - choices: [ absent, present ] - default: present -notes: -- This must be run on a host that has the ActiveDirectory powershell module installed. -seealso: -- module: win_domain -- module: win_domain_controller -- module: win_domain_computer -- module: win_domain_membership -- module: win_domain_user -- module: win_group -- module: win_group_membership -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Ensure the group Cow exists using sAMAccountName - win_domain_group: - name: Cow - scope: global - path: OU=groups,DC=ansible,DC=local - -- name: Ensure the group Cow doesn't exist using the Distinguished Name - win_domain_group: - name: CN=Cow,OU=groups,DC=ansible,DC=local - state: absent - -- name: Delete group ignoring the protection flag - win_domain_group: - name: Cow - state: absent - ignore_protection: yes - -- name: Create group with delete protection enabled and custom attributes - win_domain_group: - name: Ansible Users - scope: domainlocal - category: security - attributes: - mail: helpdesk@ansible.com - wWWHomePage: www.ansible.com - ignore_protection: yes - -- name: Change the OU of a group using the SID and ignore the protection flag - win_domain_group: - name: S-1-5-21-2171456218-3732823212-122182344-1189 - scope: global - organizational_unit: OU=groups,DC=ansible,DC=local - ignore_protection: yes - -- name: Add managed_by user - win_domain_group: - name: Group Name Here - managed_by: Domain Admins - -- name: Add group and specify the AD domain services to use for the create - win_domain_group: - name: Test Group - domain_username: user@CORP.ANSIBLE.COM - domain_password: Password01! - domain_server: corp-DC12.corp.ansible.com - scope: domainlocal -''' - -RETURN = r''' -attributes: - description: Custom attributes that were set by the module. This does not - show all the custom attributes rather just the ones that were set by the - module. - returned: group exists and attributes are set on the module invocation - type: dict - sample: - mail: 'helpdesk@ansible.com' - wWWHomePage: 'www.ansible.com' -canonical_name: - description: The canonical name of the group. - returned: group exists - type: str - sample: ansible.local/groups/Cow -category: - description: The Group type value of the group, i.e. Security or Distribution. - returned: group exists - type: str - sample: Security -description: - description: The Description of the group. - returned: group exists - type: str - sample: Group Description -display_name: - description: The Display name of the group. - returned: group exists - type: str - sample: Users who connect through RDP -distinguished_name: - description: The full Distinguished Name of the group. - returned: group exists - type: str - sample: CN=Cow,OU=groups,DC=ansible,DC=local -group_scope: - description: The Group scope value of the group. - returned: group exists - type: str - sample: Universal -guid: - description: The guid of the group. - returned: group exists - type: str - sample: 512a9adb-3fc0-4a26-9df0-e6ea1740cf45 -managed_by: - description: The full Distinguished Name of the AD object that is set on the - managedBy attribute. - returned: group exists - type: str - sample: CN=Domain Admins,CN=Users,DC=ansible,DC=local -name: - description: The name of the group. - returned: group exists - type: str - sample: Cow -protected_from_accidental_deletion: - description: Whether the group is protected from accidental deletion. - returned: group exists - type: bool - sample: true -sid: - description: The Security ID of the group. - returned: group exists - type: str - sample: S-1-5-21-2171456218-3732823212-122182344-1189 -created: - description: Whether a group was created - returned: always - type: bool - sample: true -''' diff --git a/lib/ansible/modules/windows/win_domain_group_membership.ps1 b/lib/ansible/modules/windows/win_domain_group_membership.ps1 deleted file mode 100644 index 878b9fc6696..00000000000 --- a/lib/ansible/modules/windows/win_domain_group_membership.ps1 +++ /dev/null @@ -1,131 +0,0 @@ -#!powershell - -# Copyright: (c) 2019, Marius Rieder -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -try { - Import-Module ActiveDirectory -} -catch { - Fail-Json -obj @{} -message "win_domain_group_membership requires the ActiveDirectory PS module to be installed" -} - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff_mode = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false - -# Module control parameters -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent","pure" -$domain_username = Get-AnsibleParam -obj $params -name "domain_username" -type "str" -$domain_password = Get-AnsibleParam -obj $params -name "domain_password" -type "str" -failifempty ($null -ne $domain_username) -$domain_server = Get-AnsibleParam -obj $params -name "domain_server" -type "str" - -# Group Membership parameters -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$members = Get-AnsibleParam -obj $params -name "members" -type "list" -failifempty $true - -# Filter ADObjects by ObjectClass -$ad_object_class_filter = "(ObjectClass -eq 'user' -or ObjectClass -eq 'group' -or ObjectClass -eq 'computer' -or ObjectClass -eq 'msDS-ManagedServiceAccount')" - -$extra_args = @{} -if ($null -ne $domain_username) { - $domain_password = ConvertTo-SecureString $domain_password -AsPlainText -Force - $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $domain_username, $domain_password - $extra_args.Credential = $credential -} -if ($null -ne $domain_server) { - $extra_args.Server = $domain_server -} - -$ADGroup = Get-ADGroup -Identity $name @extra_args - -$result = @{ - changed = $false - added = [System.Collections.Generic.List`1[String]]@() - removed = [System.Collections.Generic.List`1[String]]@() -} -if ($diff_mode) { - $result.diff = @{} -} - -$members_before = Get-AdGroupMember -Identity $ADGroup @extra_args -$pure_members = [System.Collections.Generic.List`1[String]]@() - -foreach ($member in $members) { - $extra_member_args = $extra_args.Clone() - if ($member -match "\\"){ - $extra_member_args.Server = $member.Split("\")[0] - $member = $member.Split("\")[1] - } - $group_member = Get-ADObject -Filter "SamAccountName -eq '$member' -and $ad_object_class_filter" -Properties objectSid, sAMAccountName @extra_member_args - if (!$group_member) { - Fail-Json -obj $result "Could not find domain user, group, service account or computer named $member" - } - - if ($state -eq "pure") { - $pure_members.Add($group_member.objectSid) - } - - $user_in_group = $false - foreach ($current_member in $members_before) { - if ($current_member.sid -eq $group_member.objectSid) { - $user_in_group = $true - break - } - } - - if ($state -in @("present", "pure") -and !$user_in_group) { - Add-ADPrincipalGroupMembership -Identity $group_member -MemberOf $ADGroup -WhatIf:$check_mode @extra_member_args - $result.added.Add($group_member.SamAccountName) - $result.changed = $true - } elseif ($state -eq "absent" -and $user_in_group) { - Remove-ADPrincipalGroupMembership -Identity $group_member -MemberOf $ADGroup -WhatIf:$check_mode -Confirm:$False @extra_member_args - $result.removed.Add($group_member.SamAccountName) - $result.changed = $true - } -} - -if ($state -eq "pure") { - # Perform removals for existing group members not defined in $members - $current_members = Get-AdGroupMember -Identity $ADGroup @extra_args - - foreach ($current_member in $current_members) { - $user_to_remove = $true - foreach ($pure_member in $pure_members) { - if ($pure_member -eq $current_member.sid) { - $user_to_remove = $false - break - } - } - - if ($user_to_remove) { - Remove-ADPrincipalGroupMembership -Identity $current_member -MemberOf $ADGroup -WhatIf:$check_mode -Confirm:$False - $result.removed.Add($current_member.SamAccountName) - $result.changed = $true - } - } -} - -$final_members = Get-AdGroupMember -Identity $ADGroup @extra_args - -if ($final_members) { - $result.members = [Array]$final_members.SamAccountName -} else { - $result.members = @() -} - -if ($diff_mode -and $result.changed) { - $result.diff.before = $members_before.SamAccountName | Out-String - if (!$check_mode) { - $result.diff.after = [Array]$final_members.SamAccountName | Out-String - } else { - $after = [System.Collections.Generic.List`1[String]]$result.members - $result.removed | ForEach-Object { $after.Remove($_) > $null } - $after.AddRange($result.added) - $result.diff.after = $after | Out-String - } -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_domain_group_membership.py b/lib/ansible/modules/windows/win_domain_group_membership.py deleted file mode 100644 index be1b7f04af7..00000000000 --- a/lib/ansible/modules/windows/win_domain_group_membership.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Andrew Saraceni -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_domain_group_membership -version_added: "2.8" -short_description: Manage Windows domain group membership -description: - - Allows the addition and removal of domain users - and domain groups from/to a domain group. -options: - name: - description: - - Name of the domain group to manage membership on. - type: str - required: yes - members: - description: - - A list of members to ensure are present/absent from the group. - - The given names must be a SamAccountName of a user, group, service account, or computer. - - For computers, you must add "$" after the name; for example, to add "Mycomputer" to a group, use "Mycomputer$" as the member. - - If the member object is part of another domain in a multi-domain forest, you must add the domain and "\" in front of the name. - type: list - required: yes - state: - description: - - Desired state of the members in the group. - - When C(state) is C(pure), only the members specified will exist, - and all other existing members not specified are removed. - type: str - choices: [ absent, present, pure ] - default: present - domain_username: - description: - - The username to use when interacting with AD. - - If this is not set then the user Ansible used to log in with will be - used instead when using CredSSP or Kerberos with credential delegation. - type: str - domain_password: - description: - - The password for I(username). - type: str - domain_server: - description: - - Specifies the Active Directory Domain Services instance to connect to. - - Can be in the form of an FQDN or NetBIOS name. - - If not specified then the value is based on the domain of the computer - running PowerShell. - type: str -notes: -- This must be run on a host that has the ActiveDirectory powershell module installed. -seealso: -- module: win_domain_user -- module: win_domain_group -author: - - Marius Rieder (@jiuka) -''' - -EXAMPLES = r''' -- name: Add a domain user/group to a domain group - win_domain_group_membership: - name: Foo - members: - - Bar - state: present - -- name: Remove a domain user/group from a domain group - win_domain_group_membership: - name: Foo - members: - - Bar - state: absent - -- name: Ensure only a domain user/group exists in a domain group - win_domain_group_membership: - name: Foo - members: - - Bar - state: pure - -- name: Add a computer to a domain group - win_domain_group_membership: - name: Foo - members: - - DESKTOP$ - state: present - -- name: Add a domain user/group from another Domain in the multi-domain forest to a domain group - win_domain_group_membership: - domain_server: DomainAAA.cloud - name: GroupinDomainAAA - members: - - DomainBBB.cloud\UserInDomainBBB - state: Present - -''' - -RETURN = r''' -name: - description: The name of the target domain group. - returned: always - type: str - sample: Domain-Admins -added: - description: A list of members added when C(state) is C(present) or - C(pure); this is empty if no members are added. - returned: success and C(state) is C(present) or C(pure) - type: list - sample: ["UserName", "GroupName"] -removed: - description: A list of members removed when C(state) is C(absent) or - C(pure); this is empty if no members are removed. - returned: success and C(state) is C(absent) or C(pure) - type: list - sample: ["UserName", "GroupName"] -members: - description: A list of all domain group members at completion; this is empty - if the group contains no members. - returned: success - type: list - sample: ["UserName", "GroupName"] -''' diff --git a/lib/ansible/modules/windows/win_domain_object_info.ps1 b/lib/ansible/modules/windows/win_domain_object_info.ps1 deleted file mode 100644 index f8f6f6457bd..00000000000 --- a/lib/ansible/modules/windows/win_domain_object_info.ps1 +++ /dev/null @@ -1,271 +0,0 @@ -#!powershell - -# Copyright: (c) 2020, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.AddType - -$spec = @{ - options = @{ - domain_password = @{ type = 'str'; no_log = $true } - domain_server = @{ type = 'str' } - domain_username = @{ type = 'str' } - filter = @{ type = 'str' } - identity = @{ type = 'str' } - include_deleted = @{ type = 'bool'; default = $false } - ldap_filter = @{ type = 'str' } - properties = @{ type = 'list'; elements = 'str' } - search_base = @{ type = 'str' } - search_scope = @{ type = 'str'; choices = @('base', 'one_level', 'subtree') } - } - supports_check_mode = $true - mutually_exclusive = @( - @('filter', 'identity', 'ldap_filter'), - @('identity', 'search_base'), - @('identity', 'search_scope') - ) - required_one_of = @( - ,@('filter', 'identity', 'ldap_filter') - ) - required_together = @(,@('domain_username', 'domain_password')) -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$module.Result.objects = @() # Always ensure this is returned even in a failure. - -$domainServer = $module.Params.domain_server -$domainPassword = $module.Params.domain_password -$domainUsername = $module.Params.domain_username -$filter = $module.Params.filter -$identity = $module.Params.identity -$includeDeleted = $module.Params.include_deleted -$ldapFilter = $module.Params.ldap_filter -$properties = $module.Params.properties -$searchBase = $module.Params.search_base -$searchScope = $module.Params.search_scope - -$credential = $null -if ($domainUsername) { - $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList @( - $domainUsername, - (ConvertTo-SecureString -AsPlainText -Force -String $domainPassword) - ) -} - -Add-CSharpType -References @' -using System; - -namespace Ansible.WinDomainObjectInfo -{ - [Flags] - public enum UserAccountControl : int - { - ADS_UF_SCRIPT = 0x00000001, - ADS_UF_ACCOUNTDISABLE = 0x00000002, - ADS_UF_HOMEDIR_REQUIRED = 0x00000008, - ADS_UF_LOCKOUT = 0x00000010, - ADS_UF_PASSWD_NOTREQD = 0x00000020, - ADS_UF_PASSWD_CANT_CHANGE = 0x00000040, - ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x00000080, - ADS_UF_TEMP_DUPLICATE_ACCOUNT = 0x00000100, - ADS_UF_NORMAL_ACCOUNT = 0x00000200, - ADS_UF_INTERDOMAIN_TRUST_ACCOUNT = 0x00000800, - ADS_UF_WORKSTATION_TRUST_ACCOUNT = 0x00001000, - ADS_UF_SERVER_TRUST_ACCOUNT = 0x00002000, - ADS_UF_DONT_EXPIRE_PASSWD = 0x00010000, - ADS_UF_MNS_LOGON_ACCOUNT = 0x00020000, - ADS_UF_SMARTCARD_REQUIRED = 0x00040000, - ADS_UF_TRUSTED_FOR_DELEGATION = 0x00080000, - ADS_UF_NOT_DELEGATED = 0x00100000, - ADS_UF_USE_DES_KEY_ONLY = 0x00200000, - ADS_UF_DONT_REQUIRE_PREAUTH = 0x00400000, - ADS_UF_PASSWORD_EXPIRED = 0x00800000, - ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x01000000, - } - - public enum sAMAccountType : int - { - SAM_DOMAIN_OBJECT = 0x00000000, - SAM_GROUP_OBJECT = 0x10000000, - SAM_NON_SECURITY_GROUP_OBJECT = 0x10000001, - SAM_ALIAS_OBJECT = 0x20000000, - SAM_NON_SECURITY_ALIAS_OBJECT = 0x20000001, - SAM_USER_OBJECT = 0x30000000, - SAM_NORMAL_USER_ACCOUNT = 0x30000000, - SAM_MACHINE_ACCOUNT = 0x30000001, - SAM_TRUST_ACCOUNT = 0x30000002, - SAM_APP_BASIC_GROUP = 0x40000000, - SAM_APP_QUERY_GROUP = 0x40000001, - SAM_ACCOUNT_TYPE_MAX = 0x7fffffff, - } -} -'@ - -Function ConvertTo-OutputValue { - [CmdletBinding()] - Param ( - [Parameter(Mandatory=$true)] - [AllowNull()] - [Object] - $InputObject - ) - - if ($InputObject -is [System.Security.Principal.SecurityIdentifier]) { - # Syntax: SID - Only serialize the SID as a string and not the other metadata properties. - $sidInfo = @{ - Sid = $InputObject.Value - } - - # Try and map the SID to the account name, this may fail if the SID is invalid or not mappable. - try { - $sidInfo.Name = $InputObject.Translate([System.Security.Principal.NTAccount]).Value - } catch [System.Security.Principal.IdentityNotMappedException] { - $sidInfo.Name = $null - } - - $sidInfo - } elseif ($InputObject -is [Byte[]]) { - # Syntax: Octet String - By default will serialize as a list of decimal values per byte, instead return a - # Base64 string as Ansible can easily parse that. - [System.Convert]::ToBase64String($InputObject) - } elseif ($InputObject -is [DateTime]) { - # Syntax: UTC Coded Time - .NET DateTimes serialized as in the form "Date(FILETIME)" which isn't easily - # parsable by Ansible, instead return as an ISO 8601 string in the UTC timezone. - [TimeZoneInfo]::ConvertTimeToUtc($InputObject).ToString("o") - } elseif ($InputObject -is [System.Security.AccessControl.ObjectSecurity]) { - # Complex object which isn't easily serializable. Instead we should just return the SDDL string. If a user - # needs to parse this then they really need to reprocess the SDDL string and process their results on another - # win_shell task. - $InputObject.GetSecurityDescriptorSddlForm(([System.Security.AccessControl.AccessControlSections]::All)) - } else { - # Syntax: (All Others) - The default serialization handling of other syntaxes are fine, don't do anything. - $InputObject - } -} - -<# -Calling Get-ADObject that returns multiple objects with -Properties * will only return the properties that were set on -the first found object. To counter this problem we will first call Get-ADObject to list all the objects that match the -filter specified then get the properties on each object. -#> - -$commonParams = @{ - IncludeDeletedObjects = $includeDeleted -} - -if ($credential) { - $commonParams.Credential = $credential -} - -if ($domainServer) { - $commonParams.Server = $domainServer -} - -# First get the IDs for all the AD objects that match the filter specified. -$getParams = @{ - Properties = @('DistinguishedName', 'ObjectGUID') -} - -if ($filter) { - $getParams.Filter = $filter -} elseif ($identity) { - $getParams.Identity = $identity -} elseif ($ldapFilter) { - $getParams.LDAPFilter = $ldapFilter -} - -# Explicit check on $null as an empty string is different from not being set. -if ($null -ne $searchBase) { - $getParams.SearchBase = $searchbase -} - -if ($searchScope) { - $getParams.SearchScope = switch($searchScope) { - base { 'Base' } - one_level { 'OneLevel' } - subtree { 'Subtree' } - } -} - -try { - # We run this in a custom PowerShell pipeline so that users of this module can't use any of the variables defined - # above in their filter. While the cmdlet won't execute sub expressions we don't want anyone implicitly relying on - # a defined variable in this module in case we ever change the name or remove it. - $ps = [PowerShell]::Create() - $null = $ps.AddCommand('Get-ADObject').AddParameters($commonParams).AddParameters($getParams) - $null = $ps.AddCommand('Select-Object').AddParameter('Property', @('DistinguishedName', 'ObjectGUID')) - - $foundGuids = @($ps.Invoke()) -} catch { - # Because we ran in a pipeline we can't catch ADIdentityNotFoundException. Instead just get the base exception and - # do the error checking on that. - if ($_.Exception.GetBaseException() -is [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException]) { - $foundGuids = @() - } else { - # The exception is from the .Invoke() call, compare on the InnerException which was what was actually raised by - # the pipeline. - $innerException = $_.Exception.InnerException.InnerException - if ($innerException -is [Microsoft.ActiveDirectory.Management.ADServerDownException]) { - # Point users in the direction of the double hop problem as that is what is typically the cause of this. - $msg = "Failed to contact the AD server, this could be caused by the double hop problem over WinRM. " - $msg += "Try using the module with auth as Kerberos with credential delegation or CredSSP, become, or " - $msg += "defining the domain_username and domain_password module parameters." - $module.FailJson($msg, $innerException) - } else { - throw $innerException - } - } -} - -$getParams = @{} -if ($properties) { - $getParams.Properties = $properties -} -$module.Result.objects = @(foreach ($adId in $foundGuids) { - try { - $adObject = Get-ADObject @commonParams @getParams -Identity $adId.ObjectGUID - } catch { - $msg = "Failed to retrieve properties for AD Object '$($adId.DistinguishedName)': $($_.Exception.Message)" - $module.Warn($msg) - continue - } - - $propertyNames = $adObject.PropertyNames - $propertyNames += ($properties | Where-Object { $_ -ne '*' }) - - # Now process each property to an easy to represent string - $filteredObject = [Ordered]@{} - foreach ($name in ($propertyNames | Sort-Object)) { - # In the case of explicit properties that were asked for but weren't set, Get-ADObject won't actually return - # the property so this is a defensive check against that scenario. - if (-not $adObject.PSObject.Properties.Name.Contains($name)) { - $filteredObject.$name = $null - continue - } - - $value = $adObject.$name - if ($value -is [Microsoft.ActiveDirectory.Management.ADPropertyValueCollection]) { - $value = foreach ($v in $value) { - ConvertTo-OutputValue -InputObject $v - } - } else { - $value = ConvertTo-OutputValue -InputObject $value - } - $filteredObject.$name = $value - - # For these 2 properties, add an _AnsibleFlags attribute which contains the enum strings that are set. - if ($name -eq 'sAMAccountType') { - $enumValue = [Ansible.WinDomainObjectInfo.sAMAccountType]$value - $filteredObject.'sAMAccountType_AnsibleFlags' = $enumValue.ToString() -split ', ' - } elseif ($name -eq 'userAccountControl') { - $enumValue = [Ansible.WinDomainObjectInfo.UserAccountControl]$value - $filteredObject.'userAccountControl_AnsibleFlags' = $enumValue.ToString() -split ', ' - } - } - - $filteredObject -}) - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_domain_object_info.py b/lib/ansible/modules/windows/win_domain_object_info.py deleted file mode 100644 index 008b141b1bd..00000000000 --- a/lib/ansible/modules/windows/win_domain_object_info.py +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2020, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_domain_object_info -version_added: '2.10' -short_description: Gather information an Active Directory object -description: -- Gather information about multiple Active Directory object(s). -options: - domain_password: - description: - - The password for C(domain_username). - type: str - domain_server: - description: - - Specified the Active Directory Domain Services instance to connect to. - - Can be in the form of an FQDN or NetBIOS name. - - If not specified then the value is based on the default domain of the computer running PowerShell. - type: str - domain_username: - description: - - The username to use when interacting with AD. - - If this is not set then the user that is used for authentication will be the connection user. - - Ansible will be unable to use the connection user unless auth is Kerberos with credential delegation or CredSSP, - or become is used on the task. - type: str - filter: - description: - - Specifies a query string using the PowerShell Expression Language syntax. - - This follows the same rules and formatting as the C(-Filter) parameter for the PowerShell AD cmdlets exception - there is no variable substitutions. - - This is mutually exclusive with I(identity) and I(ldap_filter). - type: str - identity: - description: - - Specifies a single Active Directory object by its distinguished name or its object GUID. - - This is mutually exclusive with I(filter) and I(ldap_filter). - - This cannot be used with either the I(search_base) or I(search_scope) options. - type: str - include_deleted: - description: - - Also search for deleted Active Directory objects. - default: no - type: bool - ldap_filter: - description: - - Like I(filter) but this is a tradiitional LDAP query string to filter the objects to return. - - This is mutually exclusive with I(filter) and I(identity). - type: str - properties: - description: - - A list of properties to return. - - If a property is C(*), all properties that have a set value on the AD object will be returned. - - If a property is valid on the object but not set, it is only returned if defined explicitly in this option list. - - The properties C(DistinguishedName), C(Name), C(ObjectClass), and C(ObjectGUID) are always returned. - - Specifying multiple properties can have a performance impact, it is best to only return what is needed. - - If an invalid property is specified then the module will display a warning for each object it is invalid on. - type: list - elements: str - search_base: - description: - - Specify the Active Directory path to search for objects in. - - This cannot be set with I(identity). - - By default the search base is the default naming context of the target AD instance which is the DN returned by - "(Get-ADRootDSE).defaultNamingContext". - type: str - search_scope: - description: - - Specify the scope of when searching for an object in the C(search_base). - - C(base) will limit the search to the base object so the maximum number of objects returned is always one. This - will not search any objects inside a container.. - - C(one_level) will search the current path and any immediate objects in that path. - - C(subtree) will search the current path and all objects of that path recursively. - - This cannot be set with I(identity). - choices: - - base - - one_level - - subtree - type: str -notes: -- The C(sAMAccountType_AnsibleFlags) and C(userAccountControl_AnsibleFlags) return property is something set by the - module itself as an easy way to view what those flags represent. These properties cannot be used as part of the - I(filter) or I(ldap_filter) and are automatically added if those properties were requested. -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Get all properties for the specified account using its DistinguishedName - win_domain_object_info: - identity: CN=Username,CN=Users,DC=domain,DC=com - properties: '*' - -- name: Get the SID for all user accounts as a filter - win_domain_object_info: - filter: ObjectClass -eq 'user' -and objectCategory -eq 'Person' - properties: - - objectSid - -- name: Get the SID for all user accounts as a LDAP filter - win_domain_object_info: - ldap_filter: (&(objectClass=user)(objectCategory=Person)) - properties: - - objectSid - -- name: Search all computer accounts in a specific path that were added after February 1st - win_domain_object_info: - filter: objectClass -eq 'computer' -and whenCreated -gt '20200201000000.0Z' - properties: '*' - search_scope: one_level - search_base: CN=Computers,DC=domain,DC=com -''' - -RETURN = r''' -objects: - description: - - A list of dictionaries that are the Active Directory objects found and the properties requested. - - The dict's keys are the property name and the value is the value for the property. - - All date properties are return in the ISO 8601 format in the UTC timezone. - - All SID properties are returned as a dict with the keys C(Sid) as the SID string and C(Name) as the translated SID - account name. - - All byte properties are returned as a base64 string. - - All security descriptor properties are returned as the SDDL string of that descriptor. - - The properties C(DistinguishedName), C(Name), C(ObjectClass), and C(ObjectGUID) are always returned. - returned: always - type: list - elements: dict - sample: | - [{ - "accountExpires": 0, - "adminCount": 1, - "CanonicalName": "domain.com/Users/Administrator", - "CN": "Administrator", - "Created": "2020-01-13T09:03:22.0000000Z", - "Description": "Built-in account for administering computer/domain", - "DisplayName": null, - "DistinguishedName": "CN=Administrator,CN=Users,DC=domain,DC=com", - "memberOf": [ - "CN=Group Policy Creator Owners,CN=Users,DC=domain,DC=com", - "CN=Domain Admins",CN=Users,DC=domain,DC=com" - ], - "Name": "Administrator", - "nTSecurityDescriptor": "O:DAG:DAD:PAI(A;;LCRPLORC;;;AU)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;SY)(A;;CCDCLCSWRPWPLOCRSDRCWDWO;;;BA)", - "ObjectCategory": "CN=Person,CN=Schema,CN=Configuration,DC=domain,DC=com", - "ObjectClass": "user", - "ObjectGUID": "c8c6569e-4688-4f3c-8462-afc4ff60817b", - "objectSid": { - "Sid": "S-1-5-21-2959096244-3298113601-420842770-500", - "Name": "DOMAIN\Administrator" - }, - "sAMAccountName": "Administrator", - }] -''' diff --git a/lib/ansible/modules/windows/win_domain_user.ps1 b/lib/ansible/modules/windows/win_domain_user.ps1 deleted file mode 100644 index da690d7b161..00000000000 --- a/lib/ansible/modules/windows/win_domain_user.ps1 +++ /dev/null @@ -1,384 +0,0 @@ -#!powershell - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#AnsibleRequires -CSharpUtil Ansible.AccessToken - -Function Test-Credential { - param( - [String]$Username, - [String]$Password, - [String]$Domain = $null - ) - if (($Username.ToCharArray()) -contains [char]'@') { - # UserPrincipalName - $Domain = $null # force $Domain to be null, to prevent undefined behaviour, as a domain name is already included in the username - } elseif (($Username.ToCharArray()) -contains [char]'\') { - # Pre Win2k Account Name - $Username = ($Username -split '\')[0] - $Domain = ($Username -split '\')[1] - } else { - # No domain provided, so maybe local user, or domain specified separately. - } - - try { - $handle = [Ansible.AccessToken.TokenUtil]::LogonUser($Username, $Domain, $Password, "Network", "Default") - $handle.Dispose() - return $true - } catch [Ansible.AccessToken.Win32Exception] { - # following errors indicate the creds are correct but the user was - # unable to log on for other reasons, which we don't care about - $success_codes = @( - 0x0000052F, # ERROR_ACCOUNT_RESTRICTION - 0x00000530, # ERROR_INVALID_LOGON_HOURS - 0x00000531, # ERROR_INVALID_WORKSTATION - 0x00000569 # ERROR_LOGON_TYPE_GRANTED - ) - $failed_codes = @( - 0x0000052E, # ERROR_LOGON_FAILURE - 0x00000532 # ERROR_PASSWORD_EXPIRED - ) - - if ($_.Exception.NativeErrorCode -in $failed_codes) { - return $false - } elseif ($_.Exception.NativeErrorCode -in $success_codes) { - return $true - } else { - # an unknown failure, reraise exception - throw $_ - } - } -} - -try { - Import-Module ActiveDirectory - } - catch { - Fail-Json $result "Failed to import ActiveDirectory PowerShell module. This module should be run on a domain controller, and the ActiveDirectory module must be available." - } - -$result = @{ - changed = $false - created = $false - password_updated = $false -} - -$ErrorActionPreference = "Stop" - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -default $false - -# Module control parameters -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent","query" -$update_password = Get-AnsibleParam -obj $params -name "update_password" -type "str" -default "always" -validateset "always","on_create","when_changed" -$groups_action = Get-AnsibleParam -obj $params -name "groups_action" -type "str" -default "replace" -validateset "add","remove","replace" -$domain_username = Get-AnsibleParam -obj $params -name "domain_username" -type "str" -$domain_password = Get-AnsibleParam -obj $params -name "domain_password" -type "str" -failifempty ($null -ne $domain_username) -$domain_server = Get-AnsibleParam -obj $params -name "domain_server" -type "str" - -# User account parameters -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$identity = Get-AnsibleParam -obj $params -name "identity" -type "str" -default $name -$description = Get-AnsibleParam -obj $params -name "description" -type "str" -$password = Get-AnsibleParam -obj $params -name "password" -type "str" -$password_expired = Get-AnsibleParam -obj $params -name "password_expired" -type "bool" -$password_never_expires = Get-AnsibleParam -obj $params -name "password_never_expires" -type "bool" -$user_cannot_change_password = Get-AnsibleParam -obj $params -name "user_cannot_change_password" -type "bool" -$account_locked = Get-AnsibleParam -obj $params -name "account_locked" -type "bool" -$groups = Get-AnsibleParam -obj $params -name "groups" -type "list" -$enabled = Get-AnsibleParam -obj $params -name "enabled" -type "bool" -default $true -$path = Get-AnsibleParam -obj $params -name "path" -type "str" -$upn = Get-AnsibleParam -obj $params -name "upn" -type "str" - -# User informational parameters -$user_info = @{ - GivenName = Get-AnsibleParam -obj $params -name "firstname" -type "str" - Surname = Get-AnsibleParam -obj $params -name "surname" -type "str" - Company = Get-AnsibleParam -obj $params -name "company" -type "str" - EmailAddress = Get-AnsibleParam -obj $params -name "email" -type "str" - StreetAddress = Get-AnsibleParam -obj $params -name "street" -type "str" - City = Get-AnsibleParam -obj $params -name "city" -type "str" - State = Get-AnsibleParam -obj $params -name "state_province" -type "str" - PostalCode = Get-AnsibleParam -obj $params -name "postal_code" -type "str" - Country = Get-AnsibleParam -obj $params -name "country" -type "str" -} - -# Additional attributes -$attributes = Get-AnsibleParam -obj $params -name "attributes" - -# Parameter validation -If ($null -ne $account_locked -and $account_locked) { - Fail-Json $result "account_locked must be set to 'no' if provided" -} -If (($null -ne $password_expired) -and ($null -ne $password_never_expires)) { - Fail-Json $result "password_expired and password_never_expires are mutually exclusive but have both been set" -} - -$extra_args = @{} -if ($null -ne $domain_username) { - $domain_password = ConvertTo-SecureString $domain_password -AsPlainText -Force - $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $domain_username, $domain_password - $extra_args.Credential = $credential -} -if ($null -ne $domain_server) { - $extra_args.Server = $domain_server -} - -Function Get-PrincipalGroups { - Param ($identity, $args_extra) - try{ - $groups = Get-ADPrincipalGroupMembership -Identity $identity @args_extra -ErrorAction Stop - } catch { - Add-Warning -obj $result -message "Failed to enumerate user groups but continuing on.: $($_.Exception.Message)" - return @() - } - - $result_groups = foreach ($group in $groups) { - $group.DistinguishedName - } - return $result_groups -} - -try { - $user_obj = Get-ADUser -Identity $identity -Properties * @extra_args - $user_guid = $user_obj.ObjectGUID -} -catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { - $user_obj = $null - $user_guid = $null -} - -If ($state -eq 'present') { - # Ensure user exists - $new_user = $false - - # If the account does not exist, create it - If (-not $user_obj) { - $create_args = @{} - $create_args.Name = $name - If ($null -ne $path){ - $create_args.Path = $path - } - If ($null -ne $upn){ - $create_args.UserPrincipalName = $upn - $create_args.SamAccountName = $upn.Split('@')[0] - } - $user_obj = New-ADUser @create_args -WhatIf:$check_mode -PassThru @extra_args - $user_guid = $user_obj.ObjectGUID - $new_user = $true - $result.created = $true - $result.changed = $true - If ($check_mode) { - Exit-Json $result - } - $user_obj = Get-ADUser -Identity $user_guid -Properties * @extra_args - } - - If ($password) { - # Don't unnecessary check for working credentials. - # Set the password if we need to. - # For new_users there is also no difference between always and when_changed - # so we don't need to differentiate between this two states. - If ($new_user -or ($update_password -eq "always")) { - $set_new_credentials = $true - } elseif ($update_password -eq "when_changed") { - $set_new_credentials = -not (Test-Credential -Username $user_obj.UserPrincipalName -Password $password) - } else { - $set_new_credentials = $false - } - If ($set_new_credentials) { - $secure_password = ConvertTo-SecureString $password -AsPlainText -Force - Set-ADAccountPassword -Identity $user_guid -Reset:$true -Confirm:$false -NewPassword $secure_password -WhatIf:$check_mode @extra_args - $user_obj = Get-ADUser -Identity $user_guid -Properties * @extra_args - $result.password_updated = $true - $result.changed = $true - } - } - - # Configure password policies - If (($null -ne $password_never_expires) -and ($password_never_expires -ne $user_obj.PasswordNeverExpires)) { - Set-ADUser -Identity $user_guid -PasswordNeverExpires $password_never_expires -WhatIf:$check_mode @extra_args - $user_obj = Get-ADUser -Identity $user_guid -Properties * @extra_args - $result.changed = $true - } - If (($null -ne $password_expired) -and ($password_expired -ne $user_obj.PasswordExpired)) { - Set-ADUser -Identity $user_guid -ChangePasswordAtLogon $password_expired -WhatIf:$check_mode @extra_args - $user_obj = Get-ADUser -Identity $user_guid -Properties * @extra_args - $result.changed = $true - } - If (($null -ne $user_cannot_change_password) -and ($user_cannot_change_password -ne $user_obj.CannotChangePassword)) { - Set-ADUser -Identity $user_guid -CannotChangePassword $user_cannot_change_password -WhatIf:$check_mode @extra_args - $user_obj = Get-ADUser -Identity $user_guid -Properties * @extra_args - $result.changed = $true - } - - # Assign other account settings - If (($null -ne $upn) -and ($upn -ne $user_obj.UserPrincipalName)) { - Set-ADUser -Identity $user_guid -UserPrincipalName $upn -WhatIf:$check_mode @extra_args - $user_obj = Get-ADUser -Identity $user_guid -Properties * @extra_args - $result.changed = $true - } - If (($null -ne $description) -and ($description -ne $user_obj.Description)) { - Set-ADUser -Identity $user_guid -description $description -WhatIf:$check_mode @extra_args - $user_obj = Get-ADUser -Identity $user_guid -Properties * @extra_args - $result.changed = $true - } - If ($enabled -ne $user_obj.Enabled) { - Set-ADUser -Identity $user_guid -Enabled $enabled -WhatIf:$check_mode @extra_args - $user_obj = Get-ADUser -Identity $user_guid -Properties * @extra_args - $result.changed = $true - } - If ((-not $account_locked) -and ($user_obj.LockedOut -eq $true)) { - Unlock-ADAccount -Identity $user_guid -WhatIf:$check_mode @extra_args - $user_obj = Get-ADUser -Identity $user_guid -Properties * @extra_args - $result.changed = $true - } - - # Set user information - Foreach ($key in $user_info.Keys) { - If ($null -eq $user_info[$key]) { - continue - } - $value = $user_info[$key] - If ($value -ne $user_obj.$key) { - $set_args = $extra_args.Clone() - $set_args.$key = $value - Set-ADUser -Identity $user_guid -WhatIf:$check_mode @set_args - $result.changed = $true - $user_obj = Get-ADUser -Identity $user_guid -Properties * @extra_args - } - } - - # Set additional attributes - $set_args = $extra_args.Clone() - $run_change = $false - if ($null -ne $attributes) { - $add_attributes = @{} - $replace_attributes = @{} - foreach ($attribute in $attributes.GetEnumerator()) { - $attribute_name = $attribute.Name - $attribute_value = $attribute.Value - - $valid_property = [bool]($user_obj.PSobject.Properties.name -eq $attribute_name) - if ($valid_property) { - $existing_value = $user_obj.$attribute_name - if ($existing_value -cne $attribute_value) { - $replace_attributes.$attribute_name = $attribute_value - } - } else { - $add_attributes.$attribute_name = $attribute_value - } - } - if ($add_attributes.Count -gt 0) { - $set_args.Add = $add_attributes - $run_change = $true - } - if ($replace_attributes.Count -gt 0) { - $set_args.Replace = $replace_attributes - $run_change = $true - } - } - - if ($run_change) { - try { - $user_obj = $user_obj | Set-ADUser -WhatIf:$check_mode -PassThru @set_args - } catch { - Fail-Json $result "failed to change user $($name): $($_.Exception.Message)" - } - $result.changed = $true - } - - - # Configure group assignment - If ($null -ne $groups) { - $group_list = $groups - - $groups = @() - Foreach ($group in $group_list) { - $groups += (Get-ADGroup -Identity $group @extra_args).DistinguishedName - } - - $assigned_groups = Get-PrincipalGroups $user_guid $extra_args - - switch ($groups_action) { - "add" { - Foreach ($group in $groups) { - If (-not ($assigned_groups -Contains $group)) { - Add-ADGroupMember -Identity $group -Members $user_guid -WhatIf:$check_mode @extra_args - $user_obj = Get-ADUser -Identity $user_guid -Properties * @extra_args - $result.changed = $true - } - } - } - "remove" { - Foreach ($group in $groups) { - If ($assigned_groups -Contains $group) { - Remove-ADGroupMember -Identity $group -Members $user_guid -Confirm:$false -WhatIf:$check_mode @extra_args - $user_obj = Get-ADUser -Identity $user_guid -Properties * @extra_args - $result.changed = $true - } - } - } - "replace" { - Foreach ($group in $assigned_groups) { - If (($group -ne $user_obj.PrimaryGroup) -and -not ($groups -Contains $group)) { - Remove-ADGroupMember -Identity $group -Members $user_guid -Confirm:$false -WhatIf:$check_mode @extra_args - $user_obj = Get-ADUser -Identity $user_guid -Properties * @extra_args - $result.changed = $true - } - } - Foreach ($group in $groups) { - If (-not ($assigned_groups -Contains $group)) { - Add-ADGroupMember -Identity $group -Members $user_guid -WhatIf:$check_mode @extra_args - $user_obj = Get-ADUser -Identity $user_guid -Properties * @extra_args - $result.changed = $true - } - } - } - } - } -} ElseIf ($state -eq 'absent') { - # Ensure user does not exist - If ($user_obj) { - Remove-ADUser $user_obj -Confirm:$false -WhatIf:$check_mode @extra_args - $result.changed = $true - If ($check_mode) { - Exit-Json $result - } - $user_obj = $null - } -} - -If ($user_obj) { - $user_obj = Get-ADUser -Identity $user_guid -Properties * @extra_args - $result.name = $user_obj.Name - $result.firstname = $user_obj.GivenName - $result.surname = $user_obj.Surname - $result.enabled = $user_obj.Enabled - $result.company = $user_obj.Company - $result.street = $user_obj.StreetAddress - $result.email = $user_obj.EmailAddress - $result.city = $user_obj.City - $result.state_province = $user_obj.State - $result.country = $user_obj.Country - $result.postal_code = $user_obj.PostalCode - $result.distinguished_name = $user_obj.DistinguishedName - $result.description = $user_obj.Description - $result.password_expired = $user_obj.PasswordExpired - $result.password_never_expires = $user_obj.PasswordNeverExpires - $result.user_cannot_change_password = $user_obj.CannotChangePassword - $result.account_locked = $user_obj.LockedOut - $result.sid = [string]$user_obj.SID - $result.upn = $user_obj.UserPrincipalName - $result.groups = Get-PrincipalGroups $user_guid $extra_args - $result.msg = "User '$name' is present" - $result.state = "present" -} -Else { - $result.name = $name - $result.msg = "User '$name' is absent" - $result.state = "absent" -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_domain_user.py b/lib/ansible/modules/windows/win_domain_user.py deleted file mode 100644 index 1880ece176a..00000000000 --- a/lib/ansible/modules/windows/win_domain_user.py +++ /dev/null @@ -1,376 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_domain_user -version_added: '2.4' -short_description: Manages Windows Active Directory user accounts -description: - - Manages Windows Active Directory user accounts. -options: - name: - description: - - Name of the user to create, remove or modify. - type: str - required: true - identity: - description: - - Identity parameter used to find the User in the Active Directory. - - This value can be in the forms C(Distinguished Name), C(objectGUID), - C(objectSid) or C(sAMAccountName). - - Default to C(name) if not set. - type: str - version_added: '2.10' - state: - description: - - When C(present), creates or updates the user account. - - When C(absent), removes the user account if it exists. - - When C(query), retrieves the user account details without making any changes. - type: str - choices: [ absent, present, query ] - default: present - enabled: - description: - - C(yes) will enable the user account. - - C(no) will disable the account. - type: bool - default: yes - account_locked: - description: - - C(no) will unlock the user account if locked. - - Note that there is not a way to lock an account as an administrator. - - Accounts are locked due to user actions; as an admin, you may only unlock a locked account. - - If you wish to administratively disable an account, set I(enabled) to C(no). - choices: [ no ] - description: - description: - - Description of the user - type: str - groups: - description: - - Adds or removes the user from this list of groups, - depending on the value of I(groups_action). - - To remove all but the Principal Group, set C(groups=) and - I(groups_action=replace). - - Note that users cannot be removed from their principal group (for example, "Domain Users"). - type: list - groups_action: - description: - - If C(add), the user is added to each group in I(groups) where not already a member. - - If C(remove), the user is removed from each group in I(groups). - - If C(replace), the user is added as a member of each group in - I(groups) and removed from any other groups. - type: str - choices: [ add, remove, replace ] - default: replace - password: - description: - - Optionally set the user's password to this (plain text) value. - - To enable an account - I(enabled) - a password must already be - configured on the account, or you must provide a password here. - type: str - update_password: - description: - - C(always) will always update passwords. - - C(on_create) will only set the password for newly created users. - - C(when_changed) will only set the password when changed (added in ansible 2.9). - type: str - choices: [ always, on_create, when_changed ] - default: always - password_expired: - description: - - C(yes) will require the user to change their password at next login. - - C(no) will clear the expired password flag. - - This is mutually exclusive with I(password_never_expires). - type: bool - password_never_expires: - description: - - C(yes) will set the password to never expire. - - C(no) will allow the password to expire. - - This is mutually exclusive with I(password_expired). - type: bool - user_cannot_change_password: - description: - - C(yes) will prevent the user from changing their password. - - C(no) will allow the user to change their password. - type: bool - firstname: - description: - - Configures the user's first name (given name). - type: str - surname: - description: - - Configures the user's last name (surname). - type: str - company: - description: - - Configures the user's company name. - type: str - upn: - description: - - Configures the User Principal Name (UPN) for the account. - - This is not required, but is best practice to configure for modern - versions of Active Directory. - - The format is C(@). - type: str - email: - description: - - Configures the user's email address. - - This is a record in AD and does not do anything to configure any email - servers or systems. - type: str - street: - description: - - Configures the user's street address. - type: str - city: - description: - - Configures the user's city. - type: str - state_province: - description: - - Configures the user's state or province. - type: str - postal_code: - description: - - Configures the user's postal code / zip code. - type: str - country: - description: - - Configures the user's country code. - - Note that this is a two-character ISO 3166 code. - type: str - path: - description: - - Container or OU for the new user; if you do not specify this, the - user will be placed in the default container for users in the domain. - - Setting the path is only available when a new user is created; - if you specify a path on an existing user, the user's path will not - be updated - you must delete (e.g., C(state=absent)) the user and - then re-add the user with the appropriate path. - type: str - attributes: - description: - - A dict of custom LDAP attributes to set on the user. - - This can be used to set custom attributes that are not exposed as module - parameters, e.g. C(telephoneNumber). - - See the examples on how to format this parameter. - type: str - version_added: '2.5' - domain_username: - description: - - The username to use when interacting with AD. - - If this is not set then the user Ansible used to log in with will be - used instead when using CredSSP or Kerberos with credential delegation. - type: str - version_added: '2.5' - domain_password: - description: - - The password for I(username). - type: str - version_added: '2.5' - domain_server: - description: - - Specifies the Active Directory Domain Services instance to connect to. - - Can be in the form of an FQDN or NetBIOS name. - - If not specified then the value is based on the domain of the computer - running PowerShell. - type: str - version_added: '2.5' -notes: - - Works with Windows 2012R2 and newer. - - If running on a server that is not a Domain Controller, credential - delegation through CredSSP or Kerberos with delegation must be used or the - I(domain_username), I(domain_password) must be set. - - Note that some individuals have confirmed successful operation on Windows - 2008R2 servers with AD and AD Web Services enabled, but this has not - received the same degree of testing as Windows 2012R2. -seealso: -- module: win_domain -- module: win_domain_controller -- module: win_domain_computer -- module: win_domain_group -- module: win_domain_membership -- module: win_user -- module: win_user_profile -author: - - Nick Chandler (@nwchandler) -''' - -EXAMPLES = r''' -- name: Ensure user bob is present with address information - win_domain_user: - name: bob - firstname: Bob - surname: Smith - company: BobCo - password: B0bP4ssw0rd - state: present - groups: - - Domain Admins - street: 123 4th St. - city: Sometown - state_province: IN - postal_code: 12345 - country: US - attributes: - telephoneNumber: 555-123456 - -- name: Ensure user bob is created and use custom credentials to create the user - win_domain_user: - name: bob - firstname: Bob - surname: Smith - password: B0bP4ssw0rd - state: present - domain_username: DOMAIN\admin-account - domain_password: SomePas2w0rd - domain_server: domain@DOMAIN.COM - -- name: Ensure user bob is present in OU ou=test,dc=domain,dc=local - win_domain_user: - name: bob - password: B0bP4ssw0rd - state: present - path: ou=test,dc=domain,dc=local - groups: - - Domain Admins - -- name: Ensure user bob is absent - win_domain_user: - name: bob - state: absent -''' - -RETURN = r''' -account_locked: - description: true if the account is locked - returned: always - type: bool - sample: false -changed: - description: true if the account changed during execution - returned: always - type: bool - sample: false -city: - description: The user city - returned: always - type: str - sample: Indianapolis -company: - description: The user company - returned: always - type: str - sample: RedHat -country: - description: The user country - returned: always - type: str - sample: US -description: - description: A description of the account - returned: always - type: str - sample: Server Administrator -distinguished_name: - description: DN of the user account - returned: always - type: str - sample: CN=nick,OU=test,DC=domain,DC=local -email: - description: The user email address - returned: always - type: str - sample: nick@domain.local -enabled: - description: true if the account is enabled and false if disabled - returned: always - type: str - sample: true -firstname: - description: The user first name - returned: always - type: str - sample: Nick -groups: - description: AD Groups to which the account belongs - returned: always - type: list - sample: [ "Domain Admins", "Domain Users" ] -msg: - description: Summary message of whether the user is present or absent - returned: always - type: str - sample: User nick is present -name: - description: The username on the account - returned: always - type: str - sample: nick -password_expired: - description: true if the account password has expired - returned: always - type: bool - sample: false -password_updated: - description: true if the password changed during this execution - returned: always - type: bool - sample: true -postal_code: - description: The user postal code - returned: always - type: str - sample: 46033 -sid: - description: The SID of the account - returned: always - type: str - sample: S-1-5-21-2752426336-228313920-2202711348-1175 -state: - description: The state of the user account - returned: always - type: str - sample: present -state_province: - description: The user state or province - returned: always - type: str - sample: IN -street: - description: The user street address - returned: always - type: str - sample: 123 4th St. -surname: - description: The user last name - returned: always - type: str - sample: Doe -upn: - description: The User Principal Name of the account - returned: always - type: str - sample: nick@domain.local -user_cannot_change_password: - description: true if the user is not allowed to change password - returned: always - type: str - sample: false -created: - description: Whether a user was created - returned: always - type: bool - sample: true -''' diff --git a/lib/ansible/modules/windows/win_dotnet_ngen.ps1 b/lib/ansible/modules/windows/win_dotnet_ngen.ps1 deleted file mode 100644 index 8dfca6b1eea..00000000000 --- a/lib/ansible/modules/windows/win_dotnet_ngen.ps1 +++ /dev/null @@ -1,61 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Peter Mounce -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.CommandUtil - -$ErrorActionPreference = 'Stop' - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$result = @{ - changed = $false -} - -Function Invoke-Ngen($architecture="") { - $cmd = "$($env:windir)\Microsoft.NET\Framework$($architecture)\v4.0.30319\ngen.exe" - - if (Test-Path -Path $cmd) { - $arguments = "update /force" - if ($check_mode) { - $ngen_result = @{ - rc = 0 - stdout = "check mode output for $cmd $arguments" - } - } else { - try { - $ngen_result = Run-Command -command "$cmd $arguments" - } catch { - Fail-Json -obj $result -message "failed to execute '$cmd $arguments': $($_.Exception.Message)" - } - } - $result."dotnet_ngen$($architecture)_update_exit_code" = $ngen_result.rc - $result."dotnet_ngen$($architecture)_update_output" = $ngen_result.stdout - - $arguments = "executeQueuedItems" - if ($check_mode) { - $executed_queued_items = @{ - rc = 0 - stdout = "check mode output for $cmd $arguments" - } - } else { - try { - $executed_queued_items = Run-Command -command "$cmd $arguments" - } catch { - Fail-Json -obj $result -message "failed to execute '$cmd $arguments': $($_.Exception.Message)" - } - } - $result."dotnet_ngen$($architecture)_eqi_exit_code" = $executed_queued_items.rc - $result."dotnet_ngen$($architecture)_eqi_output" = $executed_queued_items.stdout - $result.changed = $true - } -} - -Invoke-Ngen -Invoke-Ngen -architecture "64" - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_dotnet_ngen.py b/lib/ansible/modules/windows/win_dotnet_ngen.py deleted file mode 100644 index db682c98ecf..00000000000 --- a/lib/ansible/modules/windows/win_dotnet_ngen.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Peter Mounce -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_dotnet_ngen -version_added: "2.0" -short_description: Runs ngen to recompile DLLs after .NET updates -description: - - After .NET framework is installed/updated, Windows will probably want to recompile things to optimise for the host. - - This happens via scheduled task, usually at some inopportune time. - - This module allows you to run this task on your own schedule, so you incur the CPU hit at some more convenient and controlled time. - - U(https://docs.microsoft.com/en-us/dotnet/framework/tools/ngen-exe-native-image-generator#native-image-service) - - U(http://blogs.msdn.com/b/dotnet/archive/2013/08/06/wondering-why-mscorsvw-exe-has-high-cpu-usage-you-can-speed-it-up.aspx) -options: {} -notes: - - There are in fact two scheduled tasks for ngen but they have no triggers so aren't a problem. - - There's no way to test if they've been completed. - - The stdout is quite likely to be several megabytes. -author: -- Peter Mounce (@petemounce) -''' - -EXAMPLES = r''' -- name: Run ngen tasks - win_dotnet_ngen: -''' - -RETURN = r''' -dotnet_ngen_update_exit_code: - description: The exit code after running the 32-bit ngen.exe update /force - command. - returned: 32-bit ngen executable exists - type: int - sample: 0 -dotnet_ngen_update_output: - description: The stdout after running the 32-bit ngen.exe update /force - command. - returned: 32-bit ngen executable exists - type: str - sample: sample output -dotnet_ngen_eqi_exit_code: - description: The exit code after running the 32-bit ngen.exe - executeQueuedItems command. - returned: 32-bit ngen executable exists - type: int - sample: 0 -dotnet_ngen_eqi_output: - description: The stdout after running the 32-bit ngen.exe executeQueuedItems - command. - returned: 32-bit ngen executable exists - type: str - sample: sample output -dotnet_ngen64_update_exit_code: - description: The exit code after running the 64-bit ngen.exe update /force - command. - returned: 64-bit ngen executable exists - type: int - sample: 0 -dotnet_ngen64_update_output: - description: The stdout after running the 64-bit ngen.exe update /force - command. - returned: 64-bit ngen executable exists - type: str - sample: sample output -dotnet_ngen64_eqi_exit_code: - description: The exit code after running the 64-bit ngen.exe - executeQueuedItems command. - returned: 64-bit ngen executable exists - type: int - sample: 0 -dotnet_ngen64_eqi_output: - description: The stdout after running the 64-bit ngen.exe executeQueuedItems - command. - returned: 64-bit ngen executable exists - type: str - sample: sample output -''' diff --git a/lib/ansible/modules/windows/win_eventlog.ps1 b/lib/ansible/modules/windows/win_eventlog.ps1 deleted file mode 100644 index c4f695ce224..00000000000 --- a/lib/ansible/modules/windows/win_eventlog.ps1 +++ /dev/null @@ -1,287 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Andrew Saraceni -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" - -function Get-EventLogDetail { - <# - .SYNOPSIS - Get details of an event log, sources, and associated attributes. - Used for comparison against passed-in option values to ensure idempotency. - #> - param( - [String]$LogName - ) - - $log_details = @{} - $log_details.name = $LogName - $log_details.exists = $false - $log = Get-EventLog -List | Where-Object {$_.Log -eq $LogName} - - if ($log) { - $log_details.exists = $true - $log_details.maximum_size_kb = $log.MaximumKilobytes - $log_details.overflow_action = $log.OverflowAction.ToString() - $log_details.retention_days = $log.MinimumRetentionDays - $log_details.entries = $log.Entries.Count - $log_details.sources = [Ordered]@{} - - # Retrieve existing sources and category/message/parameter file locations - # Associating file locations and sources with logs can only be done from the registry - - $root_key = "HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\{0}" -f $LogName - $log_root = Get-ChildItem -Path $root_key - - foreach ($child in $log_root) { - $source_name = $child.PSChildName - $log_details.sources.$source_name = @{} - $hash_cursor = $log_details.sources.$source_name - - $source_root = "{0}\{1}" -f $root_key, $source_name - $resource_files = Get-ItemProperty -Path $source_root - - $hash_cursor.category_file = $resource_files.CategoryMessageFile - $hash_cursor.message_file = $resource_files.EventMessageFile - $hash_cursor.parameter_file = $resource_files.ParameterMessageFile - } - } - - return $log_details -} - -function Test-SourceExistence { - <# - .SYNOPSIS - Get information on a source's existence. - Examine existence regarding the parent log it belongs to and its expected state. - #> - param( - [String]$LogName, - [String]$SourceName, - [Switch]$NoLogShouldExist - ) - - $source_exists = [System.Diagnostics.EventLog]::SourceExists($SourceName) - - if ($source_exists -and $NoLogShouldExist) { - Fail-Json -obj $result -message "Source $SourceName already exists and cannot be created" - } - elseif ($source_exists) { - $source_log = [System.Diagnostics.EventLog]::LogNameFromSourceName($SourceName, ".") - if ($source_log -ne $LogName) { - Fail-Json -obj $result -message "Source $SourceName does not belong to log $LogName and cannot be modified" - } - } - - return $source_exists -} - -function ConvertTo-MaximumSize { - <# - .SYNOPSIS - Convert a string KB/MB/GB value to common bytes and KB representations. - .NOTES - Size must be between 64KB and 4GB and divisible by 64KB, as per the MaximumSize parameter of Limit-EventLog. - #> - param( - [String]$Size - ) - - $parsed_size = @{ - bytes = $null - KB = $null - } - - $size_regex = "^\d+(\.\d+)?(KB|MB|GB)$" - if ($Size -notmatch $size_regex) { - Fail-Json -obj $result -message "Maximum size $Size is not properly specified" - } - - $size_upper = $Size.ToUpper() - $size_numeric = [Double]$Size.Substring(0, $Size.Length -2) - - if ($size_upper.EndsWith("GB")) { - $size_bytes = $size_numeric * 1GB - } - elseif ($size_upper.EndsWith("MB")) { - $size_bytes = $size_numeric * 1MB - } - elseif ($size_upper.EndsWith("KB")) { - $size_bytes = $size_numeric * 1KB - } - - if (($size_bytes -lt 64KB) -or ($size_bytes -ge 4GB)) { - Fail-Json -obj $result -message "Maximum size must be between 64KB and 4GB" - } - elseif (($size_bytes % 64KB) -ne 0) { - Fail-Json -obj $result -message "Maximum size must be divisible by 64KB" - } - - $parsed_size.bytes = $size_bytes - $parsed_size.KB = $size_bytes / 1KB - return $parsed_size -} - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","clear","absent" -$sources = Get-AnsibleParam -obj $params -name "sources" -type "list" -$category_file = Get-AnsibleParam -obj $params -name "category_file" -type "path" -$message_file = Get-AnsibleParam -obj $params -name "message_file" -type "path" -$parameter_file = Get-AnsibleParam -obj $params -name "parameter_file" -type "path" -$maximum_size = Get-AnsibleParam -obj $params -name "maximum_size" -type "str" -$overflow_action = Get-AnsibleParam -obj $params -name "overflow_action" -type "str" -validateset "OverwriteOlder","OverwriteAsNeeded","DoNotOverwrite" -$retention_days = Get-AnsibleParam -obj $params -name "retention_days" -type "int" - -$result = @{ - changed = $false - name = $name - sources_changed = @() -} - -$log_details = Get-EventLogDetail -LogName $name - -# Handle common error cases up front -if ($state -eq "present" -and !$log_details.exists -and !$sources) { - # When creating a log, one or more sources must be passed - Fail-Json -obj $result -message "You must specify one or more sources when creating a log for the first time" -} -elseif ($state -eq "present" -and $log_details.exists -and $name -in $sources -and ($category_file -or $message_file -or $parameter_file)) { - # After a default source of the same name is created, it cannot be modified without removing the log - Fail-Json -obj $result -message "Cannot modify default source $name of log $name - you must remove the log" -} -elseif ($state -eq "clear" -and !$log_details.exists) { - Fail-Json -obj $result -message "Cannot clear log $name as it does not exist" -} -elseif ($state -eq "absent" -and $name -in $sources) { - # You also cannot remove a default source for the log - you must remove the log itself - Fail-Json -obj $result -message "Cannot remove default source $name from log $name - you must remove the log" -} - -try { - switch ($state) { - "present" { - foreach ($source in $sources) { - if ($log_details.exists) { - $source_exists = Test-SourceExistence -LogName $name -SourceName $source - } - else { - $source_exists = Test-SourceExistence -LogName $name -SourceName $source -NoLogShouldExist - } - - if ($source_exists) { - $category_change = $category_file -and $log_details.sources.$source.category_file -ne $category_file - $message_change = $message_file -and $log_details.sources.$source.message_file -ne $message_file - $parameter_change = $parameter_file -and $log_details.sources.$source.parameter_file -ne $parameter_file - # Remove source and recreate later if any of the above are true - if ($category_change -or $message_change -or $parameter_change) { - Remove-EventLog -Source $source -WhatIf:$check_mode - } - else { - continue - } - } - - $new_params = @{ - LogName = $name - Source = $source - } - if ($category_file) { - $new_params.CategoryResourceFile = $category_file - } - if ($message_file) { - $new_params.MessageResourceFile = $message_file - } - if ($parameter_file) { - $new_params.ParameterResourceFile = $parameter_file - } - - if (!$check_mode) { - New-EventLog @new_params - $result.sources_changed += $source - } - $result.changed = $true - } - - if ($maximum_size) { - $converted_size = ConvertTo-MaximumSize -Size $maximum_size - } - - $size_change = $maximum_size -and $log_details.maximum_size_kb -ne $converted_size.KB - $overflow_change = $overflow_action -and $log_details.overflow_action -ne $overflow_action - $retention_change = $retention_days -and $log_details.retention_days -ne $retention_days - - if ($size_change -or $overflow_change -or $retention_change) { - $limit_params = @{ - LogName = $name - WhatIf = $check_mode - } - if ($maximum_size) { - $limit_params.MaximumSize = $converted_size.bytes - } - if ($overflow_action) { - $limit_params.OverflowAction = $overflow_action - } - if ($retention_days) { - $limit_params.RetentionDays = $retention_days - } - - Limit-EventLog @limit_params - $result.changed = $true - } - - } - "clear" { - if ($log_details.entries -gt 0) { - Clear-EventLog -LogName $name -WhatIf:$check_mode - $result.changed = $true - } - } - "absent" { - if ($sources -and $log_details.exists) { - # Since sources were passed, remove sources tied to event log - foreach ($source in $sources) { - $source_exists = Test-SourceExistence -LogName $name -SourceName $source - if ($source_exists) { - Remove-EventLog -Source $source -WhatIf:$check_mode - if (!$check_mode) { - $result.sources_changed += $source - } - $result.changed = $true - } - } - } - elseif ($log_details.exists) { - # Only name passed, so remove event log itself (which also removes contained sources) - Remove-EventLog -LogName $name -WhatIf:$check_mode - if (!$check_mode) { - $log_details.sources.GetEnumerator() | ForEach-Object { $result.sources_changed += $_.Name } - } - $result.changed = $true - } - } - } -} -catch { - Fail-Json -obj $result -message $_.Exception.Message -} - -$final_log_details = Get-EventLogDetail -LogName $name -foreach ($final_log_detail in $final_log_details.GetEnumerator()) { - if ($final_log_detail.Name -eq "sources") { - $sources = @() - $final_log_detail.Value.GetEnumerator() | ForEach-Object { $sources += $_.Name } - $result.$($final_log_detail.Name) = [Array]$sources - } - else { - $result.$($final_log_detail.Name) = $final_log_detail.Value - } -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_eventlog.py b/lib/ansible/modules/windows/win_eventlog.py deleted file mode 100644 index 85cb9487017..00000000000 --- a/lib/ansible/modules/windows/win_eventlog.py +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Andrew Saraceni -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_eventlog -version_added: "2.4" -short_description: Manage Windows event logs -description: - - Allows the addition, clearing and removal of local Windows event logs, - and the creation and removal of sources from a given event log. Also - allows the specification of settings per log and source. -options: - name: - description: - - Name of the event log to manage. - type: str - required: yes - state: - description: - - Desired state of the log and/or sources. - - When C(sources) is populated, state is checked for sources. - - When C(sources) is not populated, state is checked for the specified log itself. - - If C(state) is C(clear), event log entries are cleared for the target log. - type: str - choices: [ absent, clear, present ] - default: present - sources: - description: - - A list of one or more sources to ensure are present/absent in the log. - - When C(category_file), C(message_file) and/or C(parameter_file) are specified, - these values are applied across all sources. - type: list - category_file: - description: - - For one or more sources specified, the path to a custom category resource file. - type: path - message_file: - description: - - For one or more sources specified, the path to a custom event message resource file. - type: path - parameter_file: - description: - - For one or more sources specified, the path to a custom parameter resource file. - type: path - maximum_size: - description: - - The maximum size of the event log. - - Value must be between 64KB and 4GB, and divisible by 64KB. - - Size can be specified in KB, MB or GB (e.g. 128KB, 16MB, 2.5GB). - type: str - overflow_action: - description: - - The action for the log to take once it reaches its maximum size. - - For C(DoNotOverwrite), all existing entries are kept and new entries are not retained. - - For C(OverwriteAsNeeded), each new entry overwrites the oldest entry. - - For C(OverwriteOlder), new log entries overwrite those older than the C(retention_days) value. - type: str - choices: [ DoNotOverwrite, OverwriteAsNeeded, OverwriteOlder ] - retention_days: - description: - - The minimum number of days event entries must remain in the log. - - This option is only used when C(overflow_action) is C(OverwriteOlder). - type: int -seealso: -- module: win_eventlog_entry -author: - - Andrew Saraceni (@andrewsaraceni) -''' - -EXAMPLES = r''' -- name: Add a new event log with two custom sources - win_eventlog: - name: MyNewLog - sources: - - NewLogSource1 - - NewLogSource2 - state: present - -- name: Change the category and message resource files used for NewLogSource1 - win_eventlog: - name: MyNewLog - sources: - - NewLogSource1 - category_file: C:\NewApp\CustomCategories.dll - message_file: C:\NewApp\CustomMessages.dll - state: present - -- name: Change the maximum size and overflow action for MyNewLog - win_eventlog: - name: MyNewLog - maximum_size: 16MB - overflow_action: DoNotOverwrite - state: present - -- name: Clear event entries for MyNewLog - win_eventlog: - name: MyNewLog - state: clear - -- name: Remove NewLogSource2 from MyNewLog - win_eventlog: - name: MyNewLog - sources: - - NewLogSource2 - state: absent - -- name: Remove MyNewLog and all remaining sources - win_eventlog: - name: MyNewLog - state: absent -''' - -RETURN = r''' -name: - description: The name of the event log. - returned: always - type: str - sample: MyNewLog -exists: - description: Whether the event log exists or not. - returned: success - type: bool - sample: true -entries: - description: The count of entries present in the event log. - returned: success - type: int - sample: 50 -maximum_size_kb: - description: Maximum size of the log in KB. - returned: success - type: int - sample: 512 -overflow_action: - description: The action the log takes once it reaches its maximum size. - returned: success - type: str - sample: OverwriteOlder -retention_days: - description: The minimum number of days entries are retained in the log. - returned: success - type: int - sample: 7 -sources: - description: A list of the current sources for the log. - returned: success - type: list - sample: ["MyNewLog", "NewLogSource1", "NewLogSource2"] -sources_changed: - description: A list of sources changed (e.g. re/created, removed) for the log; - this is empty if no sources are changed. - returned: always - type: list - sample: ["NewLogSource2"] -''' diff --git a/lib/ansible/modules/windows/win_eventlog_entry.ps1 b/lib/ansible/modules/windows/win_eventlog_entry.ps1 deleted file mode 100644 index ddc4d1e1686..00000000000 --- a/lib/ansible/modules/windows/win_eventlog_entry.ps1 +++ /dev/null @@ -1,106 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Andrew Saraceni -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" - -function Test-LogExistence { - <# - .SYNOPSIS - Get information on a log's existence. - #> - param( - [String]$LogName - ) - - $log_exists = $false - $log = Get-EventLog -List | Where-Object {$_.Log -eq $LogName} - if ($log) { - $log_exists = $true - } - return $log_exists -} - -function Test-SourceExistence { - <# - .SYNOPSIS - Get information on a source's existence. - #> - param( - [String]$LogName, - [String]$SourceName - ) - - $source_exists = [System.Diagnostics.EventLog]::SourceExists($SourceName) - - if ($source_exists) { - $source_log = [System.Diagnostics.EventLog]::LogNameFromSourceName($SourceName, ".") - if ($source_log -ne $LogName) { - Fail-Json -obj $result -message "Source $SourceName does not belong to log $LogName and cannot be written to" - } - } - - return $source_exists -} - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$log = Get-AnsibleParam -obj $params -name "log" -type "str" -failifempty $true -$source = Get-AnsibleParam -obj $params -name "source" -type "str" -failifempty $true -$event_id = Get-AnsibleParam -obj $params -name "event_id" -type "int" -failifempty $true -$message = Get-AnsibleParam -obj $params -name "message" -type "str" -failifempty $true -$entry_type = Get-AnsibleParam -obj $params -name "entry_type" -type "str" -validateset "Error","FailureAudit","Information","SuccessAudit","Warning" -$category = Get-AnsibleParam -obj $params -name "category" -type "int" -$raw_data = Get-AnsibleParam -obj $params -name "raw_data" -type "str" - -$result = @{ - changed = $false -} - -$log_exists = Test-LogExistence -LogName $log -if (!$log_exists) { - Fail-Json -obj $result -message "Log $log does not exist and cannot be written to" -} - -$source_exists = Test-SourceExistence -LogName $log -SourceName $source -if (!$source_exists) { - Fail-Json -obj $result -message "Source $source does not exist" -} - -if ($event_id -lt 0 -or $event_id -gt 65535) { - Fail-Json -obj $result -message "Event ID must be between 0 and 65535" -} - -$write_params = @{ - LogName = $log - Source = $source - EventId = $event_id - Message = $message -} - -try { - if ($entry_type) { - $write_params.EntryType = $entry_type - } - if ($category) { - $write_params.Category = $category - } - if ($raw_data) { - $write_params.RawData = [Byte[]]($raw_data -split ",") - } - - if (!$check_mode) { - Write-EventLog @write_params - } - $result.changed = $true - $result.msg = "Entry added to log $log from source $source" -} -catch { - Fail-Json -obj $result -message $_.Exception.Message -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_eventlog_entry.py b/lib/ansible/modules/windows/win_eventlog_entry.py deleted file mode 100644 index 05652e9df53..00000000000 --- a/lib/ansible/modules/windows/win_eventlog_entry.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Andrew Saraceni -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_eventlog_entry -version_added: "2.4" -short_description: Write entries to Windows event logs -description: - - Write log entries to a given event log from a specified source. -options: - log: - description: - - Name of the event log to write an entry to. - type: str - required: yes - source: - description: - - Name of the log source to indicate where the entry is from. - type: str - required: yes - event_id: - description: - - The numeric event identifier for the entry. - - Value must be between 0 and 65535. - type: int - required: yes - message: - description: - - The message for the given log entry. - type: str - required: yes - entry_type: - description: - - Indicates the entry being written to the log is of a specific type. - type: str - choices: [ Error, FailureAudit, Information, SuccessAudit, Warning ] - category: - description: - - A numeric task category associated with the category message file for the log source. - type: int - raw_data: - description: - - Binary data associated with the log entry. - - Value must be a comma-separated array of 8-bit unsigned integers (0 to 255). - type: str -notes: - - This module will always report a change when writing an event entry. -seealso: -- module: win_eventlog -author: - - Andrew Saraceni (@andrewsaraceni) -''' - -EXAMPLES = r''' -- name: Write an entry to a Windows event log - win_eventlog_entry: - log: MyNewLog - source: NewLogSource1 - event_id: 1234 - message: This is a test log entry. - -- name: Write another entry to a different Windows event log - win_eventlog_entry: - log: AnotherLog - source: MyAppSource - event_id: 5000 - message: An error has occurred. - entry_type: Error - category: 5 - raw_data: 10,20 -''' - -RETURN = r''' -# Default return values -''' diff --git a/lib/ansible/modules/windows/win_file_compression.ps1 b/lib/ansible/modules/windows/win_file_compression.ps1 deleted file mode 100644 index 893cc502780..00000000000 --- a/lib/ansible/modules/windows/win_file_compression.ps1 +++ /dev/null @@ -1,118 +0,0 @@ -#!powershell - -# Copyright: (c) 2019, Micah Hunsberger -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic - -Set-StrictMode -Version 2 - -$spec = @{ - options = @{ - path = @{ type = 'path'; required = $true } - state = @{ type = 'str'; default = 'present'; choices = 'absent', 'present' } - recurse = @{ type = 'bool'; default = $false } - force = @{ type = 'bool'; default = $true } - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$path = $module.Params.path -$state = $module.Params.state -$recurse = $module.Params.recurse -$force = $module.Params.force - -$module.Result.rc = 0 - -if(-not (Test-Path -LiteralPath $path)) { - $module.FailJson("Path to item, $path, does not exist.") -} - -$item = Get-Item -LiteralPath $path -Force # Use -Force for hidden files -if (-not $item.PSIsContainer -and $recurse) { - $module.Warn("The recurse option has no effect when path is not a folder.") -} - -$cim_params = @{ - ClassName = 'Win32_LogicalDisk' - Filter = "DeviceId='$($item.PSDrive.Name):'" - Property = @('FileSystem', 'SupportsFileBasedCompression') -} -$drive_info = Get-CimInstance @cim_params -if ($drive_info.SupportsFileBasedCompression -eq $false) { - $module.FailJson("Path, $path, is not on a filesystemi '$($drive_info.FileSystem)' that supports file based compression.") -} - -function Get-ReturnCodeMessage { - param( - [int]$code - ) - switch ($code) { - 0 { return "The request was successful." } - 2 { return "Access was denied." } - 8 { return "An unspecified failure occurred." } - 9 { return "The name specified was not valid." } - 10 { return "The object specified already exists." } - 11 { return "The file system is not NTFS." } - 12 { return "The platform is not Windows." } - 13 { return "The drive is not the same." } - 14 { return "The directory is not empty." } - 15 { return "There has been a sharing violation." } - 16 { return "The start file specified was not valid." } - 17 { return "A privilege required for the operation is not held." } - 21 { return "A parameter specified is not valid." } - } -} - -function Get-EscapedFileName { - param( - [string]$FullName - ) - return $FullName.Replace("\","\\").Replace("'","\'") -} - -$is_compressed = ($item.Attributes -band [System.IO.FileAttributes]::Compressed) -eq [System.IO.FileAttributes]::Compressed -$needs_changed = $is_compressed -ne ($state -eq 'present') - -if($force -and $recurse -and $item.PSIsContainer) { - if (-not $needs_changed) { - # Check the subfolders and files - $entries_to_check = $item.EnumerateFileSystemInfos("*", [System.IO.SearchOption]::AllDirectories) - foreach ($entry in $entries_to_check) { - $is_compressed = ($entry.Attributes -band [System.IO.FileAttributes]::Compressed) -eq [System.IO.FileAttributes]::Compressed - if ($is_compressed -ne ($state -eq 'present')) { - $needs_changed = $true - break - } - } - } -} - -if($needs_changed) { - $module.Result.changed = $true - if ($item.PSIsContainer) { - $cim_obj = Get-CimInstance -ClassName 'Win32_Directory' -Filter "Name='$(Get-EscapedFileName -FullName $item.FullName)'" - } else { - $cim_obj = Get-CimInstance -ClassName 'CIM_LogicalFile' -Filter "Name='$(Get-EscapedFileName -FullName $item.FullName)'" - } - if($state -eq 'present') { - if(-not $module.CheckMode) { - $ret = Invoke-CimMethod -InputObject $cim_obj -MethodName 'CompressEx' -Arguments @{ Recursive = $recurse } - $module.Result.rc = $ret.ReturnValue - } - } else { - if(-not $module.CheckMode) { - $ret = $ret = Invoke-CimMethod -InputObject $cim_obj -MethodName 'UnCompressEx' -Arguments @{ Recursive = $recurse } - $module.Result.rc = $ret.ReturnValue - } - } -} - -$module.Result.msg = Get-ReturnCodeMessage -code $module.Result.rc -if($module.Result.rc -ne 0) { - $module.FailJson($module.Result.msg) -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_file_compression.py b/lib/ansible/modules/windows/win_file_compression.py deleted file mode 100644 index 3bc59cade0a..00000000000 --- a/lib/ansible/modules/windows/win_file_compression.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2019, Micah Hunsberger (@mhunsber) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_file_compression -version_added: '2.10' -short_description: Alters the compression of files and directories on NTFS partitions. -description: - - This module sets the compressed attribute for files and directories on a filesystem that supports it like NTFS. - - NTFS compression can be used to save disk space. -options: - path: - description: - - The full path of the file or directory to modify. - - The path must exist on file system that supports compression like NTFS. - required: yes - type: path - state: - description: - - Set to C(present) to ensure the I(path) is compressed. - - Set to C(absent) to ensure the I(path) is not compressed. - type: str - choices: - - absent - - present - default: present - recurse: - description: - - Whether to recursively apply changes to all subdirectories and files. - - This option only has an effect when I(path) is a directory. - - When set to C(false), only applies changes to I(path). - - When set to C(true), applies changes to I(path) and all subdirectories and files. - type: bool - default: false - force: - description: - - This option only has an effect when I(recurse) is C(true) - - If C(true), will check the compressed state of all subdirectories and files - and make a change if any are different from I(compressed). - - If C(false), will only make a change if the compressed state of I(path) is different from I(compressed). - - If the folder structure is complex or contains a lot of files, it is recommended to set this - option to C(false) so that not every file has to be checked. - type: bool - default: true -author: - - Micah Hunsberger (@mhunsber) -notes: - - C(win_file_compression) sets the file system's compression state, it does not create a zip archive file. - - For more about NTFS Compression, see U(http://www.ntfs.com/ntfs-compressed.htm) -''' - -EXAMPLES = r''' -- name: Compress log files directory - win_file_compression: - path: C:\Logs - state: present - -- name: Decompress log files directory - win_file_compression: - path: C:\Logs - state: absent - -- name: Compress reports directory and all subdirectories - win_file_compression: - path: C:\business\reports - state: present - recurse: yes - -# This will only check C:\business\reports for the compressed state -# If C:\business\reports is compressed, it will not make a change -# even if one of the child items is uncompressed - -- name: Compress reports directory and all subdirectories (quick) - win_file_compression: - path: C:\business\reports - compressed: yes - recurse: yes - force: no -''' - -RETURN = r''' -rc: - description: - - The return code of the compress/uncompress operation. - - If no changes are made or the operation is successful, rc is 0. - returned: always - sample: 0 - type: int -''' diff --git a/lib/ansible/modules/windows/win_file_version.ps1 b/lib/ansible/modules/windows/win_file_version.ps1 deleted file mode 100644 index 7fc6b557eff..00000000000 --- a/lib/ansible/modules/windows/win_file_version.ps1 +++ /dev/null @@ -1,63 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Sam Liu -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$params = Parse-Args $args -supports_check_mode $true - -$result = @{ - win_file_version = @{} - changed = $false -} - -$path = Get-AnsibleParam -obj $params -name "path" -type "path" -failifempty $true -resultobj $result - -If (-Not (Test-Path -Path $path -PathType Leaf)){ - Fail-Json $result "Specified path $path does not exist or is not a file." -} -$ext = [System.IO.Path]::GetExtension($path) -If ( $ext -notin '.exe', '.dll'){ - Fail-Json $result "Specified path $path is not a valid file type; must be DLL or EXE." -} - -Try { - $_version_fields = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($path) - $file_version = $_version_fields.FileVersion - If ($null -eq $file_version){ - $file_version = '' - } - $product_version = $_version_fields.ProductVersion - If ($null -eq $product_version){ - $product_version= '' - } - $file_major_part = $_version_fields.FileMajorPart - If ($null -eq $file_major_part){ - $file_major_part= '' - } - $file_minor_part = $_version_fields.FileMinorPart - If ($null -eq $file_minor_part){ - $file_minor_part= '' - } - $file_build_part = $_version_fields.FileBuildPart - If ($null -eq $file_build_part){ - $file_build_part = '' - } - $file_private_part = $_version_fields.FilePrivatePart - If ($null -eq $file_private_part){ - $file_private_part = '' - } -} -Catch{ - Fail-Json $result "Error: $_.Exception.Message" -} - -$result.win_file_version.path = $path.toString() -$result.win_file_version.file_version = $file_version.toString() -$result.win_file_version.product_version = $product_version.toString() -$result.win_file_version.file_major_part = $file_major_part.toString() -$result.win_file_version.file_minor_part = $file_minor_part.toString() -$result.win_file_version.file_build_part = $file_build_part.toString() -$result.win_file_version.file_private_part = $file_private_part.toString() -Exit-Json $result; diff --git a/lib/ansible/modules/windows/win_file_version.py b/lib/ansible/modules/windows/win_file_version.py deleted file mode 100644 index 390927821bf..00000000000 --- a/lib/ansible/modules/windows/win_file_version.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Sam Liu -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_file_version -version_added: "2.1" -short_description: Get DLL or EXE file build version -description: - - Get DLL or EXE file build version. -notes: - - This module will always return no change. -options: - path: - description: - - File to get version. - - Always provide absolute path. - type: path - required: yes -seealso: -- module: win_file -author: -- Sam Liu (@SamLiu79) -''' - -EXAMPLES = r''' -- name: Get acm instance version - win_file_version: - path: C:\Windows\System32\cmd.exe - register: exe_file_version - -- debug: - msg: '{{ exe_file_version }}' -''' - -RETURN = r''' -path: - description: file path - returned: always - type: str - -file_version: - description: File version number.. - returned: no error - type: str - -product_version: - description: The version of the product this file is distributed with. - returned: no error - type: str - -file_major_part: - description: the major part of the version number. - returned: no error - type: str - -file_minor_part: - description: the minor part of the version number of the file. - returned: no error - type: str - -file_build_part: - description: build number of the file. - returned: no error - type: str - -file_private_part: - description: file private part number. - returned: no error - type: str -''' diff --git a/lib/ansible/modules/windows/win_firewall.ps1 b/lib/ansible/modules/windows/win_firewall.ps1 deleted file mode 100644 index 2a628a35278..00000000000 --- a/lib/ansible/modules/windows/win_firewall.ps1 +++ /dev/null @@ -1,68 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Michael Eaton -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" -$firewall_profiles = @('Domain', 'Private', 'Public') - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$profiles = Get-AnsibleParam -obj $params -name "profiles" -type "list" -default @("Domain", "Private", "Public") -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -failifempty $true -validateset 'disabled','enabled' - -$result = @{ - changed = $false - profiles = $profiles - state = $state -} - -try { - get-command Get-NetFirewallProfile > $null - get-command Set-NetFirewallProfile > $null -} -catch { - Fail-Json $result "win_firewall requires Get-NetFirewallProfile and Set-NetFirewallProfile Cmdlets." -} - -Try { - - ForEach ($profile in $firewall_profiles) { - - $currentstate = (Get-NetFirewallProfile -Name $profile).Enabled - $result.$profile = @{ - enabled = ($currentstate -eq 1) - considered = ($profiles -contains $profile) - currentstate = $currentstate - } - - if ($profiles -notcontains $profile) { - continue - } - - if ($state -eq 'enabled') { - - if ($currentstate -eq $false) { - Set-NetFirewallProfile -name $profile -Enabled true -WhatIf:$check_mode - $result.changed = $true - $result.$profile.enabled = $true - } - - } else { - - if ($currentstate -eq $true) { - Set-NetFirewallProfile -name $profile -Enabled false -WhatIf:$check_mode - $result.changed = $true - $result.$profile.enabled = $false - } - - } - } -} Catch { - Fail-Json $result "an error occurred when attempting to change firewall status for profile $profile $($_.Exception.Message)" -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_firewall.py b/lib/ansible/modules/windows/win_firewall.py deleted file mode 100644 index 62556b49019..00000000000 --- a/lib/ansible/modules/windows/win_firewall.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Michael Eaton -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_firewall -version_added: '2.4' -short_description: Enable or disable the Windows Firewall -description: -- Enable or Disable Windows Firewall profiles. -requirements: - - This module requires Windows Management Framework 5 or later. -options: - profiles: - description: - - Specify one or more profiles to change. - type: list - choices: [ Domain, Private, Public ] - default: [ Domain, Private, Public ] - state: - description: - - Set state of firewall for given profile. - type: str - choices: [ disabled, enabled ] -seealso: -- module: win_firewall_rule -author: -- Michael Eaton (@michaeldeaton) -''' - -EXAMPLES = r''' -- name: Enable firewall for Domain, Public and Private profiles - win_firewall: - state: enabled - profiles: - - Domain - - Private - - Public - tags: enable_firewall - -- name: Disable Domain firewall - win_firewall: - state: disabled - profiles: - - Domain - tags: disable_firewall -''' - -RETURN = r''' -enabled: - description: Current firewall status for chosen profile (after any potential change). - returned: always - type: bool - sample: true -profiles: - description: Chosen profile. - returned: always - type: str - sample: Domain -state: - description: Desired state of the given firewall profile(s). - returned: always - type: list - sample: enabled -''' diff --git a/lib/ansible/modules/windows/win_firewall_rule.ps1 b/lib/ansible/modules/windows/win_firewall_rule.ps1 deleted file mode 100644 index 3e6544eac4c..00000000000 --- a/lib/ansible/modules/windows/win_firewall_rule.ps1 +++ /dev/null @@ -1,257 +0,0 @@ -#!powershell - -# Copyright: (c) 2014, Timothy Vandenbrande -# Copyright: (c) 2017, Artem Zinenko -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -function Parse-ProtocolType { - param($protocol) - - $protocolNumber = $protocol -as [int] - if ($protocolNumber -is [int]) { - return $protocolNumber - } - - switch -wildcard ($protocol) { - "tcp" { return [System.Net.Sockets.ProtocolType]::Tcp -as [int] } - "udp" { return [System.Net.Sockets.ProtocolType]::Udp -as [int] } - "icmpv4*" { return [System.Net.Sockets.ProtocolType]::Icmp -as [int] } - "icmpv6*" { return [System.Net.Sockets.ProtocolType]::IcmpV6 -as [int] } - default { throw "Unknown protocol '$protocol'." } - } -} - -# See 'Direction' constants here: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364724(v=vs.85).aspx -function Parse-Direction { - param($directionStr) - - switch ($directionStr) { - "in" { return 1 } - "out" { return 2 } - default { throw "Unknown direction '$directionStr'." } - } -} - -# See 'Action' constants here: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364724(v=vs.85).aspx -function Parse-Action { - param($actionStr) - - switch ($actionStr) { - "block" { return 0 } - "allow" { return 1 } - default { throw "Unknown action '$actionStr'." } - } -} - -# Profile enum values: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366303(v=vs.85).aspx -function Parse-Profiles -{ - param($profilesList) - - $profiles = ($profilesList | Select-Object -Unique | ForEach-Object { - switch ($_) { - "domain" { return 1 } - "private" { return 2 } - "public" { return 4 } - default { throw "Unknown profile '$_'." } - } - } | Measure-Object -Sum).Sum - - if ($profiles -eq 7) { return 0x7fffffff } - return $profiles -} - -function Parse-InterfaceTypes -{ - param($interfaceTypes) - - return ($interfaceTypes | Select-Object -Unique | ForEach-Object { - switch ($_) { - "wireless" { return "Wireless" } - "lan" { return "Lan" } - "ras" { return "RemoteAccess" } - default { throw "Unknown interface type '$_'." } - } - }) -Join "," -} - -function Parse-EdgeTraversalOptions -{ - param($edgeTraversalOptionsStr) - - switch ($edgeTraversalOptionsStr) { - "yes" { return 1 } - "deferapp" { return 2 } - "deferuser" { return 3 } - default { throw "Unknown edge traversal options '$edgeTraversalOptionsStr'." } - } -} - -function Parse-SecureFlags -{ - param($secureFlagsStr) - - switch ($secureFlagsStr) { - "authnoencap" { return 1 } - "authenticate" { return 2 } - "authdynenc" { return 3 } - "authenc" { return 4 } - default { throw "Unknown secure flags '$secureFlagsStr'." } - } -} - -$ErrorActionPreference = "Stop" - -$result = @{ - changed = $false -} - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff_support = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -failifempty $true -$description = Get-AnsibleParam -obj $params -name "description" -type "str" -$direction = Get-AnsibleParam -obj $params -name "direction" -type "str" -validateset "in","out" -$action = Get-AnsibleParam -obj $params -name "action" -type "str" -validateset "allow","block" -$program = Get-AnsibleParam -obj $params -name "program" -type "str" -$group = Get-AnsibleParam -obj $params -name "group" -type "str" -$service = Get-AnsibleParam -obj $params -name "service" -type "str" -$enabled = Get-AnsibleParam -obj $params -name "enabled" -type "bool" -aliases "enable" -$profiles = Get-AnsibleParam -obj $params -name "profiles" -type "list" -aliases "profile" -$localip = Get-AnsibleParam -obj $params -name "localip" -type "str" -$remoteip = Get-AnsibleParam -obj $params -name "remoteip" -type "str" -$localport = Get-AnsibleParam -obj $params -name "localport" -type "str" -$remoteport = Get-AnsibleParam -obj $params -name "remoteport" -type "str" -$protocol = Get-AnsibleParam -obj $params -name "protocol" -type "str" -$interfacetypes = Get-AnsibleParam -obj $params -name "interfacetypes" -type "list" -$edge = Get-AnsibleParam -obj $params -name "edge" -type "str" -validateset "no","yes","deferapp","deferuser" -$security = Get-AnsibleParam -obj $params -name "security" -type "str" -validateset "notrequired","authnoencap","authenticate","authdynenc","authenc" -$icmp_type_code = Get-AnsibleParam -obj $params -name "icmp_type_code" -type "list" - -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent" - -if ($diff_support) { - $result.diff = @{} - $result.diff.prepared = "" -} - -if ($null -ne $icmp_type_code) { - # COM representation is just ":,:" so we just join our list - $icmp_type_code = $icmp_type_code -join "," -} - -try { - $fw = New-Object -ComObject HNetCfg.FwPolicy2 - - $existingRule = $fw.Rules | Where-Object { $_.Name -eq $name } - - if ($existingRule -is [System.Array]) { - Fail-Json $result "Multiple firewall rules with name '$name' found." - } - - # INetFwRule interface description: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365344(v=vs.85).aspx - $new_rule = New-Object -ComObject HNetCfg.FWRule - $new_rule.Name = $name - # the default for enabled in module description is "true", but the actual COM object defaults to "false" when created - if ($null -ne $enabled) { $new_rule.Enabled = $enabled } else { $new_rule.Enabled = $true } - if ($null -ne $description) { $new_rule.Description = $description } - if ($null -ne $group) { $new_rule.Grouping = $group } - if ($null -ne $program -and $program -ne "any") { $new_rule.ApplicationName = [System.Environment]::ExpandEnvironmentVariables($program) } - if ($null -ne $service -and $program -ne "any") { $new_rule.ServiceName = $service } - if ($null -ne $protocol -and $protocol -ne "any") { $new_rule.Protocol = Parse-ProtocolType -protocol $protocol } - if ($null -ne $localport -and $localport -ne "any") { $new_rule.LocalPorts = $localport } - if ($null -ne $remoteport -and $remoteport -ne "any") { $new_rule.RemotePorts = $remoteport } - if ($null -ne $localip -and $localip -ne "any") { $new_rule.LocalAddresses = $localip } - if ($null -ne $remoteip -and $remoteip -ne "any") { $new_rule.RemoteAddresses = $remoteip } - if ($null -ne $icmp_type_code -and $icmp_type_code -ne "any") { $new_rule.IcmpTypesAndCodes = $icmp_type_code } - if ($null -ne $direction) { $new_rule.Direction = Parse-Direction -directionStr $direction } - if ($null -ne $action) { $new_rule.Action = Parse-Action -actionStr $action } - # Profiles value cannot be a uint32, but the "all profiles" value (0x7FFFFFFF) will often become a uint32, so must cast to [int] - if ($null -ne $profiles) { $new_rule.Profiles = [int](Parse-Profiles -profilesList $profiles) } - if ($null -ne $interfacetypes -and @(Compare-Object -ReferenceObject $interfacetypes -DifferenceObject @("any")).Count -ne 0) { $new_rule.InterfaceTypes = Parse-InterfaceTypes -interfaceTypes $interfacetypes } - if ($null -ne $edge -and $edge -ne "no") { - # EdgeTraversalOptions property exists only from Windows 7/Windows Server 2008 R2: https://msdn.microsoft.com/en-us/library/windows/desktop/dd607256(v=vs.85).aspx - if ($new_rule | Get-Member -Name 'EdgeTraversalOptions') { - $new_rule.EdgeTraversalOptions = Parse-EdgeTraversalOptions -edgeTraversalOptionsStr $edge - } - } - if ($null -ne $security -and $security -ne "notrequired") { - # SecureFlags property exists only from Windows 8/Windows Server 2012: https://msdn.microsoft.com/en-us/library/windows/desktop/hh447465(v=vs.85).aspx - if ($new_rule | Get-Member -Name 'SecureFlags') { - $new_rule.SecureFlags = Parse-SecureFlags -secureFlagsStr $security - } - } - - $fwPropertiesToCompare = @('Name','Description','Direction','Action','ApplicationName','Grouping','ServiceName','Enabled','Profiles','LocalAddresses','RemoteAddresses','LocalPorts','RemotePorts','Protocol','InterfaceTypes', 'EdgeTraversalOptions', 'SecureFlags','IcmpTypesAndCodes') - $userPassedArguments = @($name, $description, $direction, $action, $program, $group, $service, $enabled, $profiles, $localip, $remoteip, $localport, $remoteport, $protocol, $interfacetypes, $edge, $security, $icmp_type_code) - - if ($state -eq "absent") { - if ($null -eq $existingRule) { - $result.msg = "Firewall rule '$name' does not exist." - } else { - if ($diff_support) { - foreach ($prop in $fwPropertiesToCompare) { - $result.diff.prepared += "-[$($prop)='$($existingRule.$prop)']`n" - } - } - - if (-not $check_mode) { - $fw.Rules.Remove($existingRule.Name) - } - $result.changed = $true - $result.msg = "Firewall rule '$name' removed." - } - } elseif ($state -eq "present") { - if ($null -eq $existingRule) { - if ($diff_support) { - foreach ($prop in $fwPropertiesToCompare) { - $result.diff.prepared += "+[$($prop)='$($new_rule.$prop)']`n" - } - } - - if (-not $check_mode) { - $fw.Rules.Add($new_rule) - } - $result.changed = $true - $result.msg = "Firewall rule '$name' created." - } else { - for($i = 0; $i -lt $fwPropertiesToCompare.Length; $i++) { - $prop = $fwPropertiesToCompare[$i] - if($null -ne $userPassedArguments[$i]) { # only change values the user passes in task definition - if ($existingRule.$prop -ne $new_rule.$prop) { - if ($diff_support) { - $result.diff.prepared += "-[$($prop)='$($existingRule.$prop)']`n" - $result.diff.prepared += "+[$($prop)='$($new_rule.$prop)']`n" - } - - if (-not $check_mode) { - # Profiles value cannot be a uint32, but the "all profiles" value (0x7FFFFFFF) will often become a uint32, so must cast to [int] - # to prevent InvalidCastException under PS5+ - If($prop -eq 'Profiles') { - $existingRule.Profiles = [int] $new_rule.$prop - } - Else { - $existingRule.$prop = $new_rule.$prop - } - } - $result.changed = $true - } - } - } - if ($result.changed) { - $result.msg = "Firewall rule '$name' changed." - } else { - $result.msg = "Firewall rule '$name' already exists." - } - } - } -} catch [Exception] { - $ex = $_ - $result['exception'] = $($ex | Out-String) - Fail-Json $result $ex.Exception.Message -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_firewall_rule.py b/lib/ansible/modules/windows/win_firewall_rule.py deleted file mode 100644 index d25468d3625..00000000000 --- a/lib/ansible/modules/windows/win_firewall_rule.py +++ /dev/null @@ -1,192 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2014, Timothy Vandenbrande -# Copyright: (c) 2017, Artem Zinenko -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_firewall_rule -version_added: "2.0" -short_description: Windows firewall automation -description: - - Allows you to create/remove/update firewall rules. -options: - enabled: - description: - - Whether this firewall rule is enabled or disabled. - - Defaults to C(true) when creating a new rule. - type: bool - aliases: [ enable ] - state: - description: - - Should this rule be added or removed. - type: str - choices: [ absent, present ] - default: present - name: - description: - - The rule's display name. - type: str - required: yes - group: - description: - - The group name for the rule. - version_added: '2.9' - type: str - direction: - description: - - Whether this rule is for inbound or outbound traffic. - - Defaults to C(in) when creating a new rule. - type: str - choices: [ in, out ] - action: - description: - - What to do with the items this rule is for. - - Defaults to C(allow) when creating a new rule. - type: str - choices: [ allow, block ] - description: - description: - - Description for the firewall rule. - type: str - localip: - description: - - The local ip address this rule applies to. - - Set to C(any) to apply to all local ip addresses. - - Defaults to C(any) when creating a new rule. - type: str - remoteip: - description: - - The remote ip address/range this rule applies to. - - Set to C(any) to apply to all remote ip addresses. - - Defaults to C(any) when creating a new rule. - type: str - localport: - description: - - The local port this rule applies to. - - Set to C(any) to apply to all local ports. - - Defaults to C(any) when creating a new rule. - - Must have I(protocol) set - type: str - remoteport: - description: - - The remote port this rule applies to. - - Set to C(any) to apply to all remote ports. - - Defaults to C(any) when creating a new rule. - - Must have I(protocol) set - type: str - program: - description: - - The program this rule applies to. - - Set to C(any) to apply to all programs. - - Defaults to C(any) when creating a new rule. - type: str - service: - description: - - The service this rule applies to. - - Set to C(any) to apply to all services. - - Defaults to C(any) when creating a new rule. - type: str - protocol: - description: - - The protocol this rule applies to. - - Set to C(any) to apply to all services. - - Defaults to C(any) when creating a new rule. - type: str - profiles: - description: - - The profile this rule applies to. - - Defaults to C(domain,private,public) when creating a new rule. - type: list - aliases: [ profile ] - icmp_type_code: - description: - - The ICMP types and codes for the rule. - - This is only valid when I(protocol) is C(icmpv4) or C(icmpv6). - - Each entry follows the format C(type:code) where C(type) is the type - number and C(code) is the code number for that type or C(*) for all - codes. - - Set the value to just C(*) to apply the rule for all ICMP type codes. - - See U(https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml) - for a list of ICMP types and the codes that apply to them. - type: list - version_added: '2.10' -seealso: -- module: win_firewall -author: - - Artem Zinenko (@ar7z1) - - Timothy Vandenbrande (@TimothyVandenbrande) -''' - -EXAMPLES = r''' -- name: Firewall rule to allow SMTP on TCP port 25 - win_firewall_rule: - name: SMTP - localport: 25 - action: allow - direction: in - protocol: tcp - state: present - enabled: yes - -- name: Firewall rule to allow RDP on TCP port 3389 - win_firewall_rule: - name: Remote Desktop - localport: 3389 - action: allow - direction: in - protocol: tcp - profiles: private - state: present - enabled: yes - -- name: Firewall rule to be created for application group - win_firewall_rule: - name: SMTP - group: application - localport: 25 - action: allow - direction: in - protocol: tcp - state: present - enabled: yes - -- name: Firewall rule to allow port range - win_firewall_rule: - name: Sample port range - localport: 5000-5010 - action: allow - direction: in - protocol: tcp - state: present - enabled: yes - -- name: Firewall rule to allow ICMP v4 echo (ping) - win_firewall_rule: - name: ICMP Allow incoming V4 echo request - enabled: yes - state: present - profiles: private - action: allow - direction: in - protocol: icmpv4 - icmp_type_code: - - '8:*' - -- name: Firewall rule to alloc ICMP v4 on all type codes - win_firewall_rule: - name: ICMP Allow incoming V4 echo request - enabled: yes - state: present - profiles: private - action: allow - direction: in - protocol: icmpv4 - icmp_type_code: '*' -''' diff --git a/lib/ansible/modules/windows/win_format.ps1 b/lib/ansible/modules/windows/win_format.ps1 deleted file mode 100644 index b5fd3ae0380..00000000000 --- a/lib/ansible/modules/windows/win_format.ps1 +++ /dev/null @@ -1,200 +0,0 @@ -#!powershell - -# Copyright: (c) 2019, Varun Chopra (@chopraaa) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#AnsibleRequires -OSVersion 6.2 - -Set-StrictMode -Version 2 - -$ErrorActionPreference = "Stop" - -$spec = @{ - options = @{ - drive_letter = @{ type = "str" } - path = @{ type = "str" } - label = @{ type = "str" } - new_label = @{ type = "str" } - file_system = @{ type = "str"; choices = "ntfs", "refs", "exfat", "fat32", "fat" } - allocation_unit_size = @{ type = "int" } - large_frs = @{ type = "bool" } - full = @{ type = "bool"; default = $false } - compress = @{ type = "bool" } - integrity_streams = @{ type = "bool" } - force = @{ type = "bool"; default = $false } - } - mutually_exclusive = @( - ,@('drive_letter', 'path', 'label') - ) - required_one_of = @( - ,@('drive_letter', 'path', 'label') - ) - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$drive_letter = $module.Params.drive_letter -$path = $module.Params.path -$label = $module.Params.label -$new_label = $module.Params.new_label -$file_system = $module.Params.file_system -$allocation_unit_size = $module.Params.allocation_unit_size -$large_frs = $module.Params.large_frs -$full_format = $module.Params.full -$compress_volume = $module.Params.compress -$integrity_streams = $module.Params.integrity_streams -$force_format = $module.Params.force - -# Some pre-checks -if ($null -ne $drive_letter -and $drive_letter -notmatch "^[a-zA-Z]$") { - $module.FailJson("The parameter drive_letter should be a single character A-Z") -} -if ($integrity_streams -eq $true -and $file_system -ne "refs") { - $module.FailJson("Integrity streams can be enabled only on ReFS volumes. You specified: $($file_system)") -} -if ($compress_volume -eq $true) { - if ($file_system -eq "ntfs") { - if ($null -ne $allocation_unit_size -and $allocation_unit_size -gt 4096) { - $module.FailJson("NTFS compression is not supported for allocation unit sizes above 4096") - } - } - else { - $module.FailJson("Compression can be enabled only on NTFS volumes. You specified: $($file_system)") - } -} - -function Get-AnsibleVolume { - param( - $DriveLetter, - $Path, - $Label - ) - - if ($null -ne $DriveLetter) { - try { - $volume = Get-Volume -DriveLetter $DriveLetter - } catch { - $module.FailJson("There was an error retrieving the volume using drive_letter $($DriveLetter): $($_.Exception.Message)", $_) - } - } - elseif ($null -ne $Path) { - try { - $volume = Get-Volume -Path $Path - } catch { - $module.FailJson("There was an error retrieving the volume using path $($Path): $($_.Exception.Message)", $_) - } - } - elseif ($null -ne $Label) { - try { - $volume = Get-Volume -FileSystemLabel $Label - } catch { - $module.FailJson("There was an error retrieving the volume using label $($Label): $($_.Exception.Message)", $_) - } - } - else { - $module.FailJson("Unable to locate volume: drive_letter, path and label were not specified") - } - - return $volume -} - -function Format-AnsibleVolume { - param( - $Path, - $Label, - $FileSystem, - $Full, - $UseLargeFRS, - $Compress, - $SetIntegrityStreams, - $AllocationUnitSize - ) - $parameters = @{ - Path = $Path - Full = $Full - } - if ($null -ne $UseLargeFRS) { - $parameters.Add("UseLargeFRS", $UseLargeFRS) - } - if ($null -ne $SetIntegrityStreams) { - $parameters.Add("SetIntegrityStreams", $SetIntegrityStreams) - } - if ($null -ne $Compress){ - $parameters.Add("Compress", $Compress) - } - if ($null -ne $Label) { - $parameters.Add("NewFileSystemLabel", $Label) - } - if ($null -ne $FileSystem) { - $parameters.Add("FileSystem", $FileSystem) - } - if ($null -ne $AllocationUnitSize) { - $parameters.Add("AllocationUnitSize", $AllocationUnitSize) - } - - Format-Volume @parameters -Confirm:$false | Out-Null - -} - -$ansible_volume = Get-AnsibleVolume -DriveLetter $drive_letter -Path $path -Label $label -$ansible_file_system = $ansible_volume.FileSystem -$ansible_volume_size = $ansible_volume.Size -$ansible_volume_alu = (Get-CimInstance -ClassName Win32_Volume -Filter "DeviceId = '$($ansible_volume.path.replace('\','\\'))'" -Property BlockSize).BlockSize - -$ansible_partition = Get-Partition -Volume $ansible_volume - -if (-not $force_format -and $null -ne $allocation_unit_size -and $ansible_volume_alu -ne 0 -and $null -ne $ansible_volume_alu -and $allocation_unit_size -ne $ansible_volume_alu) { - $module.FailJson("Force format must be specified since target allocation unit size: $($allocation_unit_size) is different from the current allocation unit size of the volume: $($ansible_volume_alu)") -} - -foreach ($access_path in $ansible_partition.AccessPaths) { - if ($access_path -ne $Path) { - if ($null -ne $file_system -and - -not [string]::IsNullOrEmpty($ansible_file_system) -and - $file_system -ne $ansible_file_system) - { - if (-not $force_format) - { - $no_files_in_volume = (Get-ChildItem -LiteralPath $access_path -ErrorAction SilentlyContinue | Measure-Object).Count -eq 0 - if($no_files_in_volume) - { - $module.FailJson("Force format must be specified since target file system: $($file_system) is different from the current file system of the volume: $($ansible_file_system.ToLower())") - } - else - { - $module.FailJson("Force format must be specified to format non-pristine volumes") - } - } - } - else - { - $pristine = -not $force_format - } - } -} - -if ($force_format) { - if (-not $module.CheckMode) { - Format-AnsibleVolume -Path $ansible_volume.Path -Full $full_format -Label $new_label -FileSystem $file_system -SetIntegrityStreams $integrity_streams -UseLargeFRS $large_frs -Compress $compress_volume -AllocationUnitSize $allocation_unit_size - } - $module.Result.changed = $true -} -else { - if ($pristine) { - if ($null -eq $new_label) { - $new_label = $ansible_volume.FileSystemLabel - } - # Conditions for formatting - if ($ansible_volume_size -eq 0 -or - $ansible_volume.FileSystemLabel -ne $new_label) { - if (-not $module.CheckMode) { - Format-AnsibleVolume -Path $ansible_volume.Path -Full $full_format -Label $new_label -FileSystem $file_system -SetIntegrityStreams $integrity_streams -UseLargeFRS $large_frs -Compress $compress_volume -AllocationUnitSize $allocation_unit_size - } - $module.Result.changed = $true - } - } -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_format.py b/lib/ansible/modules/windows/win_format.py deleted file mode 100644 index f8f18ed7b77..00000000000 --- a/lib/ansible/modules/windows/win_format.py +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2019, Varun Chopra (@chopraaa) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = { - 'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community' -} - -DOCUMENTATION = r''' -module: win_format -version_added: '2.8' -short_description: Formats an existing volume or a new volume on an existing partition on Windows -description: - - The M(win_format) module formats an existing volume or a new volume on an existing partition on Windows -options: - drive_letter: - description: - - Used to specify the drive letter of the volume to be formatted. - type: str - path: - description: - - Used to specify the path to the volume to be formatted. - type: str - label: - description: - - Used to specify the label of the volume to be formatted. - type: str - new_label: - description: - - Used to specify the new file system label of the formatted volume. - type: str - file_system: - description: - - Used to specify the file system to be used when formatting the target volume. - type: str - choices: [ ntfs, refs, exfat, fat32, fat ] - allocation_unit_size: - description: - - Specifies the cluster size to use when formatting the volume. - - If no cluster size is specified when you format a partition, defaults are selected based on - the size of the partition. - - This value must be a multiple of the physical sector size of the disk. - type: int - large_frs: - description: - - Specifies that large File Record System (FRS) should be used. - type: bool - compress: - description: - - Enable compression on the resulting NTFS volume. - - NTFS compression is not supported where I(allocation_unit_size) is more than 4096. - type: bool - integrity_streams: - description: - - Enable integrity streams on the resulting ReFS volume. - type: bool - full: - description: - - A full format writes to every sector of the disk, takes much longer to perform than the - default (quick) format, and is not recommended on storage that is thinly provisioned. - - Specify C(true) for full format. - type: bool - force: - description: - - Specify if formatting should be forced for volumes that are not created from new partitions - or if the source and target file system are different. - type: bool -notes: - - Microsoft Windows Server 2012 or Microsoft Windows 8 or newer is required to use this module. To check if your system is compatible, see - U(https://docs.microsoft.com/en-us/windows/desktop/sysinfo/operating-system-version). - - One of three parameters (I(drive_letter), I(path) and I(label)) are mandatory to identify the target - volume but more than one cannot be specified at the same time. - - This module is idempotent if I(force) is not specified and file system labels remain preserved. - - For more information, see U(https://docs.microsoft.com/en-us/previous-versions/windows/desktop/stormgmt/format-msft-volume) -seealso: - - module: win_disk_facts - - module: win_partition -author: - - Varun Chopra (@chopraaa) -''' - -EXAMPLES = r''' -- name: Create a partition with drive letter D and size 5 GiB - win_partition: - drive_letter: D - partition_size: 5 GiB - disk_number: 1 - -- name: Full format the newly created partition as NTFS and label it - win_format: - drive_letter: D - file_system: NTFS - new_label: Formatted - full: True -''' - -RETURN = r''' -# -''' diff --git a/lib/ansible/modules/windows/win_hosts.ps1 b/lib/ansible/modules/windows/win_hosts.ps1 deleted file mode 100644 index 9e617c66643..00000000000 --- a/lib/ansible/modules/windows/win_hosts.ps1 +++ /dev/null @@ -1,257 +0,0 @@ -#!powershell - -# Copyright: (c) 2018, Micah Hunsberger (@mhunsber) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic - -Set-StrictMode -Version 2 -$ErrorActionPreference = "Stop" - -$spec = @{ - options = @{ - state = @{ type = "str"; choices = "absent", "present"; default = "present" } - aliases = @{ type = "list"; elements = "str" } - canonical_name = @{ type = "str" } - ip_address = @{ type = "str" } - action = @{ type = "str"; choices = "add", "remove", "set"; default = "set" } - } - required_if = @(,@( "state", "present", @("canonical_name", "ip_address"))) - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$state = $module.Params.state -$aliases = $module.Params.aliases -$canonical_name = $module.Params.canonical_name -$ip_address = $module.Params.ip_address -$action = $module.Params.action - -$tmp = [ipaddress]::None -if($ip_address -and -not [ipaddress]::TryParse($ip_address, [ref]$tmp)){ - $module.FailJson("win_hosts: Argument ip_address needs to be a valid ip address, but was $ip_address") -} -$ip_address_type = $tmp.AddressFamily - -$hosts_file = Get-Item -LiteralPath "$env:SystemRoot\System32\drivers\etc\hosts" - -Function Get-CommentIndex($line) { - $c_index = $line.IndexOf('#') - if($c_index -lt 0) { - $c_index = $line.Length - } - return $c_index -} - -Function Get-HostEntryParts($line) { - $success = $true - $c_index = Get-CommentIndex -line $line - $pure_line = $line.Substring(0,$c_index).Trim() - $bits = $pure_line -split "\s+" - if($bits.Length -lt 2){ - return @{ - success = $false - ip_address = "" - ip_type = "" - canonical_name = "" - aliases = @() - } - } - $ip_obj = [ipaddress]::None - if(-not [ipaddress]::TryParse($bits[0], [ref]$ip_obj) ){ - $success = $false - } - $cname = $bits[1] - $als = New-Object string[] ($bits.Length - 2) - [array]::Copy($bits, 2, $als, 0, $als.Length) - return @{ - success = $success - ip_address = $ip_obj.IPAddressToString - ip_type = $ip_obj.AddressFamily - canonical_name = $cname - aliases = $als - } -} - -Function Find-HostName($line, $name) { - $c_idx = Get-CommentIndex -line $line - $re = New-Object regex ("\s+$($name.Replace('.',"\."))(\s|$)", [System.Text.RegularExpressions.RegexOptions]::IgnoreCase) - $match = $re.Match($line, 0, $c_idx) - return $match -} - -Function Remove-HostEntry($list, $idx) { - $module.Result.changed = $true - $list.RemoveAt($idx) -} - -Function Add-HostEntry($list, $cname, $aliases, $ip) { - $module.Result.changed = $true - $line = "$ip $cname $($aliases -join ' ')" - $list.Add($line) | Out-Null -} - -Function Remove-HostnamesFromEntry($list, $idx, $aliases) { - $line = $list[$idx] - $line_removed = $false - - foreach($name in $aliases){ - $match = Find-HostName -line $line -name $name - if($match.Success){ - $line = $line.Remove($match.Index + 1, $match.Length -1) - # was this the last alias? (check for space characters after trimming) - if($line.Substring(0,(Get-CommentIndex -line $line)).Trim() -inotmatch "\s") { - $list.RemoveAt($idx) - $line_removed = $true - # we're done - return @{ - line_removed = $line_removed - } - } - } - } - if($line -ne $list[$idx]){ - $module.Result.changed = $true - $list[$idx] = $line - } - return @{ - line_removed = $line_removed - } -} - -Function Add-AliasesToEntry($list, $idx, $aliases) { - $line = $list[$idx] - foreach($name in $aliases){ - $match = Find-HostName -line $line -name $name - if(-not $match.Success) { - # just add the alias before the comment - $line = $line.Insert((Get-CommentIndex -line $line), " $name ") - } - } - if($line -ne $list[$idx]){ - $module.Result.changed = $true - $list[$idx] = $line - } -} - -$hosts_lines = New-Object System.Collections.ArrayList - -Get-Content -LiteralPath $hosts_file.FullName | ForEach-Object { $hosts_lines.Add($_) } | Out-Null -$module.Diff.before = ($hosts_lines -join "`n") + "`n" - -if ($state -eq 'absent') { - # go through and remove canonical_name and ip - for($idx = 0; $idx -lt $hosts_lines.Count; $idx++) { - $entry = $hosts_lines[$idx] - # skip comment lines - if(-not $entry.Trim().StartsWith('#')) { - $entry_parts = Get-HostEntryParts -line $entry - if($entry_parts.success) { - if(-not $ip_address -or $entry_parts.ip_address -eq $ip_address) { - if(-not $canonical_name -or $entry_parts.canonical_name -eq $canonical_name) { - if(Remove-HostEntry -list $hosts_lines -idx $idx){ - # keep index correct if we removed the line - $idx = $idx - 1 - } - } - } - } - } - } -} -if($state -eq 'present') { - $entry_idx = -1 - $aliases_to_keep = @() - # go through lines, find the entry and determine what to remove based on action - for($idx = 0; $idx -lt $hosts_lines.Count; $idx++) { - $entry = $hosts_lines[$idx] - # skip comment lines - if(-not $entry.Trim().StartsWith('#')) { - $entry_parts = Get-HostEntryParts -line $entry - if($entry_parts.success) { - $aliases_to_remove = @() - if($entry_parts.ip_address -eq $ip_address) { - if($entry_parts.canonical_name -eq $canonical_name) { - $entry_idx = $idx - - if($action -eq 'set') { - $aliases_to_remove = $entry_parts.aliases | Where-Object { $aliases -notcontains $_ } - } elseif($action -eq 'remove') { - $aliases_to_remove = $aliases - } - } else { - # this is the right ip_address, but not the cname we were looking for. - # we need to make sure none of aliases or canonical_name exist for this entry - # since the given canonical_name should be an A/AAAA record, - # and aliases should be cname records for the canonical_name. - $aliases_to_remove = $aliases + $canonical_name - } - } else { - # this is not the ip_address we are looking for - if ($ip_address_type -eq $entry_parts.ip_type) { - if ($entry_parts.canonical_name -eq $canonical_name) { - Remove-HostEntry -list $hosts_lines -idx $idx - $idx = $idx - 1 - if ($action -ne "set") { - # keep old aliases intact - $aliases_to_keep += $entry_parts.aliases | Where-Object { ($aliases + $aliases_to_keep + $canonical_name) -notcontains $_ } - } - } elseif ($action -eq "remove") { - $aliases_to_remove = $canonical_name - } elseif ($aliases -contains $entry_parts.canonical_name) { - Remove-HostEntry -list $hosts_lines -idx $idx - $idx = $idx - 1 - if ($action -eq "add") { - # keep old aliases intact - $aliases_to_keep += $entry_parts.aliases | Where-Object { ($aliases + $aliases_to_keep + $canonical_name) -notcontains $_ } - } - } else { - $aliases_to_remove = $aliases + $canonical_name - } - } else { - # TODO: Better ipv6 support. There is odd behavior for when an alias can be used for both ipv6 and ipv4 - } - } - - if($aliases_to_remove) { - if((Remove-HostnamesFromEntry -list $hosts_lines -idx $idx -aliases $aliases_to_remove).line_removed) { - $idx = $idx - 1 - } - } - } - } - } - - if($entry_idx -ge 0) { - $aliases_to_add = @() - $entry_parts = Get-HostEntryParts -line $hosts_lines[$entry_idx] - if($action -eq 'remove') { - $aliases_to_add = $aliases_to_keep | Where-Object { $entry_parts.aliases -notcontains $_ } - } else { - $aliases_to_add = ($aliases + $aliases_to_keep) | Where-Object { $entry_parts.aliases -notcontains $_ } - } - - if($aliases_to_add) { - Add-AliasesToEntry -list $hosts_lines -idx $entry_idx -aliases $aliases_to_add - } - } else { - # add the entry at the end - if($action -eq 'remove') { - if($aliases_to_keep) { - Add-HostEntry -list $hosts_lines -ip $ip_address -cname $canonical_name -aliases $aliases_to_keep - } else { - Add-HostEntry -list $hosts_lines -ip $ip_address -cname $canonical_name - } - } else { - Add-HostEntry -list $hosts_lines -ip $ip_address -cname $canonical_name -aliases ($aliases + $aliases_to_keep) - } - } -} - -$module.Diff.after = ($hosts_lines -join "`n") + "`n" -if( $module.Result.changed -and -not $module.CheckMode ) { - Set-Content -LiteralPath $hosts_file.FullName -Value $hosts_lines -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_hosts.py b/lib/ansible/modules/windows/win_hosts.py deleted file mode 100644 index 9fd2d1d10d2..00000000000 --- a/lib/ansible/modules/windows/win_hosts.py +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Micah Hunsberger (@mhunsber) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_hosts -version_added: '2.8' -short_description: Manages hosts file entries on Windows. -description: - - Manages hosts file entries on Windows. - - Maps IPv4 or IPv6 addresses to canonical names. - - Adds, removes, or sets cname records for ip and hostname pairs. - - Modifies %windir%\\system32\\drivers\\etc\\hosts. -options: - state: - description: - - Whether the entry should be present or absent. - - If only I(canonical_name) is provided when C(state=absent), then - all hosts entries with the canonical name of I(canonical_name) - will be removed. - - If only I(ip_address) is provided when C(state=absent), then all - hosts entries with the ip address of I(ip_address) will be removed. - - If I(ip_address) and I(canonical_name) are both omitted when - C(state=absent), then all hosts entries will be removed. - choices: - - absent - - present - default: present - type: str - canonical_name: - description: - - A canonical name for the host entry. - - required for C(state=present). - type: str - ip_address: - description: - - The ip address for the host entry. - - Can be either IPv4 (A record) or IPv6 (AAAA record). - - Required for C(state=present). - type: str - aliases: - description: - - A list of additional names (cname records) for the host entry. - - Only applicable when C(state=present). - type: list - action: - choices: - - add - - remove - - set - description: - - Controls the behavior of I(aliases). - - Only applicable when C(state=present). - - If C(add), each alias in I(aliases) will be added to the host entry. - - If C(set), each alias in I(aliases) will be added to the host entry, - and other aliases will be removed from the entry. - default: set - type: str -author: - - Micah Hunsberger (@mhunsber) -notes: - - Each canonical name can only be mapped to one IPv4 and one IPv6 address. - If I(canonical_name) is provided with C(state=present) and is found - to be mapped to another IP address that is the same type as, but unique - from I(ip_address), then I(canonical_name) and all I(aliases) will - be removed from the entry and added to an entry with the provided IP address. - - Each alias can only be mapped to one canonical name. If I(aliases) is provided - with C(state=present) and an alias is found to be mapped to another canonical - name, then the alias will be removed from the entry and either added to or removed - from (depending on I(action)) an entry with the provided canonical name. -seealso: - - module: win_template - - module: win_file - - module: win_copy -''' - -EXAMPLES = r''' -- name: Add 127.0.0.1 as an A record for localhost - win_hosts: - state: present - canonical_name: localhost - ip_address: 127.0.0.1 - -- name: Add ::1 as an AAAA record for localhost - win_hosts: - state: present - canonical_name: localhost - ip_address: '::1' - -- name: Remove 'bar' and 'zed' from the list of aliases for foo (192.168.1.100) - win_hosts: - state: present - canoncial_name: foo - ip_address: 192.168.1.100 - action: remove - aliases: - - bar - - zed - -- name: Remove hosts entries with canonical name 'bar' - win_hosts: - state: absent - canonical_name: bar - -- name: Remove 10.2.0.1 from the list of hosts - win_hosts: - state: absent - ip_address: 10.2.0.1 - -- name: Ensure all name resolution is handled by DNS - win_hosts: - state: absent -''' - -RETURN = r''' -''' diff --git a/lib/ansible/modules/windows/win_hotfix.ps1 b/lib/ansible/modules/windows/win_hotfix.ps1 deleted file mode 100644 index 1681763203f..00000000000 --- a/lib/ansible/modules/windows/win_hotfix.ps1 +++ /dev/null @@ -1,239 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$hotfix_kb = Get-AnsibleParam -obj $params -name "hotfix_kb" -type "str" -$hotfix_identifier = Get-AnsibleParam -obj $params -name "hotfix_identifier" -type "str" -$state = Get-AnsibleParam -obj $params -name "state" -type "state" -default "present" -validateset "absent","present" -$source = Get-AnsibleParam -obj $params -name "source" -type "path" - -$result = @{ - changed = $false - reboot_required = $false -} - -if (Get-Module -Name DISM -ListAvailable) { - Import-Module -Name DISM -} else { - # Server 2008 R2 doesn't have the DISM module installed on the path, check the Windows ADK path - $adk_root = [System.Environment]::ExpandEnvironmentVariables("%PROGRAMFILES(X86)%\Windows Kits\*\Assessment and Deployment Kit\Deployment Tools\amd64\DISM") - if (Test-Path -Path $adk_root) { - Import-Module -Name (Get-Item -Path $adk_root).FullName - } else { - Fail-Json $result "The DISM PS module needs to be installed, this can be done through the windows-adk chocolately package" - } -} - - -Function Extract-MSU($msu) { - $temp_path = [IO.Path]::GetTempPath() - $temp_foldername = [Guid]::NewGuid() - $output_path = Join-Path -Path $temp_path -ChildPath $temp_foldername - New-Item -Path $output_path -ItemType Directory | Out-Null - - $expand_args = @($msu, $output_path, "-F:*") - - try { - &expand.exe $expand_args | Out-NUll - } catch { - Fail-Json $result "failed to run expand.exe $($expand_args): $($_.Exception.Message)" - } - if ($LASTEXITCODE -ne 0) { - Fail-Json $result "failed to run expand.exe $($expand_args): RC = $LASTEXITCODE" - } - - return $output_path -} - -Function Get-HotfixMetadataFromName($name) { - try { - $dism_package_info = Get-WindowsPackage -Online -PackageName $name - } catch { - # build a basic stub for a missing result - $dism_package_info = @{ - PackageState = "NotPresent" - Description = "" - PackageName = $name - } - } - - if ($dism_package_info.Description -match "(KB\d*)") { - $hotfix_kb = $Matches[0] - } else { - $hotfix_kb = "UNKNOWN" - } - - $metadata = @{ - name = $dism_package_info.PackageName - state = $dism_package_info.PackageState - kb = $hotfix_kb - } - - return $metadata -} - -Function Get-HotfixMetadataFromFile($extract_path) { - # MSU contents https://support.microsoft.com/en-us/help/934307/description-of-the-windows-update-standalone-installer-in-windows - $metadata_path = Get-ChildItem -Path $extract_path | Where-Object { $_.Extension -eq ".xml" } - if ($null -eq $metadata_path) { - Fail-Json $result "failed to get metadata xml inside MSU file, cannot get hotfix metadata required for this task" - } - [xml]$xml = Get-Content -Path $metadata_path.FullName - - $cab_source_filename = $xml.unattend.servicing.package.source.GetAttribute("location") - $cab_source_filename = Split-Path -Path $cab_source_filename -Leaf - $cab_file = Join-Path -Path $extract_path -ChildPath $cab_source_filename - - try { - $dism_package_info = Get-WindowsPackage -Online -PackagePath $cab_file - } catch { - Fail-Json $result "failed to get DISM package metadata from path $($extract_path): $($_.Exception.Message)" - } - if ($dism_package_info.Applicable -eq $false) { - Fail-Json $result "hotfix package is not applicable for this server" - } - - $package_properties_path = Get-ChildItem -Path $extract_path | Where-Object { $_.Extension -eq ".txt" } - if ($null -eq $package_properties_path) { - $hotfix_kb = "UNKNOWN" - } else { - $package_ini = Get-Content -Path $package_properties_path.FullName - $entry = $package_ini | Where-Object { $_.StartsWith("KB Article Number") } - if ($null -eq $entry) { - $hotfix_kb = "UNKNOWN" - } else { - $hotfix_kb = ($entry -split '=')[-1] - $hotfix_kb = "KB$($hotfix_kb.Substring(1, $hotfix_kb.Length - 2))" - } - } - - $metadata = @{ - path = $cab_file - name = $dism_package_info.PackageName - state = $dism_package_info.PackageState - kb = $hotfix_kb - } - - return $metadata -} - -Function Get-HotfixMetadataFromKB($kb) { - # I really hate doing it this way - $packages = Get-WindowsPackage -Online - $identifier = $packages | Where-Object { $_.PackageName -like "*$kb*" } - - if ($null -eq $identifier) { - # still haven't found the KB, need to loop through the results and check the description - foreach ($package in $packages) { - $raw_metadata = Get-HotfixMetadataFromName -name $package.PackageName - if ($raw_metadata.kb -eq $kb) { - $identifier = $raw_metadata - break - } - } - - # if we still haven't found the package then we need to throw an error - if ($null -eq $metadata) { - Fail-Json $result "failed to get DISM package from KB, to continue specify hotfix_identifier instead" - } - } else { - $metadata = Get-HotfixMetadataFromName -name $identifier.PackageName - } - - return $metadata -} - -if ($state -eq "absent") { - # uninstall hotfix - # this is a pretty poor way of doing this, is there a better way? - - if ($null -ne $hotfix_identifier) { - $hotfix_metadata = Get-HotfixMetadataFromName -name $hotfix_identifier - } elseif ($null -ne $hotfix_kb) { - $hotfix_install_info = Get-Hotfix -Id $hotfix_kb -ErrorAction SilentlyContinue - if ($null -ne $hotfix_install_info) { - $hotfix_metadata = Get-HotfixMetadataFromKB -kb $hotfix_kb - } else { - $hotfix_metadata = @{state = "NotPresent"} - } - } else { - Fail-Json $result "either hotfix_identifier or hotfix_kb needs to be set when state=absent" - } - - # how do we want to deal with the other states? - if ($hotfix_metadata.state -eq "UninstallPending") { - $result.identifier = $hotfix_metadata.name - $result.kb = $hotfix_metadata.kb - $result.reboot_required = $true - } elseif ($hotfix_metadata.state -eq "Installed") { - $result.identifier = $hotfix_metadata.name - $result.kb = $hotfix_metadata.kb - - if (-not $check_mode) { - try { - $remove_result = Remove-WindowsPackage -Online -PackageName $hotfix_metadata.name -NoRestart - } catch { - Fail-Json $result "failed to remove package $($hotfix_metadata.name): $($_.Exception.Message)" - } - $result.reboot_required = $remove_Result.RestartNeeded - } - - $result.changed = $true - } -} else { - if ($null -eq $source) { - Fail-Json $result "source must be set when state=present" - } - if (-not (Test-Path -Path $source -PathType Leaf)) { - Fail-Json $result "the path set for source $source does not exist or is not a file" - } - - # while we do extract the file in check mode we need to do so for valid checking - $extract_path = Extract-MSU -msu $source - try { - $hotfix_metadata = Get-HotfixMetadataFromFile -extract_path $extract_path - - # validate the hotfix matches if the hotfix id has been passed in - if ($null -ne $hotfix_identifier) { - if ($hotfix_metadata.name -ne $hotfix_identifier) { - Fail-Json $result "the hotfix identifier $hotfix_identifier does not match with the source msu identifier $($hotfix_metadata.name), please omit or specify the correct identifier to continue" - } - } - if ($null -ne $hotfix_kb) { - if ($hotfix_metadata.kb -ne $hotfix_kb) { - Fail-Json $result "the hotfix KB $hotfix_kb does not match with the source msu KB $($hotfix_metadata.kb), please omit or specify the correct KB to continue" - } - } - - $result.identifier = $hotfix_metadata.name - $result.kb = $hotfix_metadata.kb - - # how do we want to deal with other states - if ($hotfix_metadata.state -eq "InstallPending") { - # return the reboot required flag, should we fail here instead - $result.reboot_required = $true - } elseif ($hotfix_metadata.state -ne "Installed") { - if (-not $check_mode) { - try { - $install_result = Add-WindowsPackage -Online -PackagePath $hotfix_metadata.path -NoRestart - } catch { - Fail-Json $result "failed to add windows package from path $($hotfix_metadata.path): $($_.Exception.Message)" - } - $result.reboot_required = $install_result.RestartNeeded - } - $result.changed = $true - } - } finally { - Remove-Item -Path $extract_path -Force -Recurse - } -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_hotfix.py b/lib/ansible/modules/windows/win_hotfix.py deleted file mode 100644 index f5f3bb9c05f..00000000000 --- a/lib/ansible/modules/windows/win_hotfix.py +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub, actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_hotfix -version_added: '2.4' -short_description: Install and uninstalls Windows hotfixes -description: -- Install, uninstall a Windows hotfix. -options: - hotfix_identifier: - description: - - The name of the hotfix as shown in DISM, see examples for details. - - This or C(hotfix_kb) MUST be set when C(state=absent). - - If C(state=present) then the hotfix at C(source) will be validated - against this value, if it does not match an error will occur. - - You can get the identifier by running - 'Get-WindowsPackage -Online -PackagePath path-to-cab-in-msu' after - expanding the msu file. - type: str - hotfix_kb: - description: - - The name of the KB the hotfix relates to, see examples for details. - - This or C(hotfix_identifier) MUST be set when C(state=absent). - - If C(state=present) then the hotfix at C(source) will be validated - against this value, if it does not match an error will occur. - - Because DISM uses the identifier as a key and doesn't refer to a KB in - all cases it is recommended to use C(hotfix_identifier) instead. - type: str - state: - description: - - Whether to install or uninstall the hotfix. - - When C(present), C(source) MUST be set. - - When C(absent), C(hotfix_identifier) or C(hotfix_kb) MUST be set. - type: str - default: present - choices: [ absent, present ] - source: - description: - - The path to the downloaded hotfix .msu file. - - This MUST be set if C(state=present) and MUST be a .msu hotfix file. - type: path -notes: -- This must be run on a host that has the DISM powershell module installed and - a Powershell version >= 4. -- This module is installed by default on Windows 8 and Server 2012 and newer. -- You can manually install this module on Windows 7 and Server 2008 R2 by - installing the Windows ADK - U(https://developer.microsoft.com/en-us/windows/hardware/windows-assessment-deployment-kit), - see examples to see how to do it with chocolatey. -- You can download hotfixes from U(https://www.catalog.update.microsoft.com/Home.aspx). -seealso: -- module: win_package -- module: win_updates -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Install Windows ADK with DISM for Server 2008 R2 - win_chocolatey: - name: windows-adk - version: 8.100.26866.0 - state: present - install_args: /features OptionId.DeploymentTools - -- name: Install hotfix without validating the KB and Identifier - win_hotfix: - source: C:\temp\windows8.1-kb3172729-x64_e8003822a7ef4705cbb65623b72fd3cec73fe222.msu - state: present - register: hotfix_install - -- win_reboot: - when: hotfix_install.reboot_required - -- name: Install hotfix validating KB - win_hotfix: - hotfix_kb: KB3172729 - source: C:\temp\windows8.1-kb3172729-x64_e8003822a7ef4705cbb65623b72fd3cec73fe222.msu - state: present - register: hotfix_install - -- win_reboot: - when: hotfix_install.reboot_required - -- name: Install hotfix validating Identifier - win_hotfix: - hotfix_identifier: Package_for_KB3172729~31bf3856ad364e35~amd64~~6.3.1.0 - source: C:\temp\windows8.1-kb3172729-x64_e8003822a7ef4705cbb65623b72fd3cec73fe222.msu - state: present - register: hotfix_install - -- win_reboot: - when: hotfix_install.reboot_required - -- name: Uninstall hotfix with Identifier - win_hotfix: - hotfix_identifier: Package_for_KB3172729~31bf3856ad364e35~amd64~~6.3.1.0 - state: absent - register: hotfix_uninstall - -- win_reboot: - when: hotfix_uninstall.reboot_required - -- name: Uninstall hotfix with KB (not recommended) - win_hotfix: - hotfix_kb: KB3172729 - state: absent - register: hotfix_uninstall - -- win_reboot: - when: hotfix_uninstall.reboot_required -''' - -RETURN = r''' -identifier: - description: The DISM identifier for the hotfix. - returned: success - type: str - sample: Package_for_KB3172729~31bf3856ad364e35~amd64~~6.3.1.0 -kb: - description: The KB the hotfix relates to. - returned: success - type: str - sample: KB3172729 -reboot_required: - description: Whether a reboot is required for the install or uninstall to - finalise. - returned: success - type: str - sample: true -''' diff --git a/lib/ansible/modules/windows/win_http_proxy.ps1 b/lib/ansible/modules/windows/win_http_proxy.ps1 deleted file mode 100644 index 04ea473b998..00000000000 --- a/lib/ansible/modules/windows/win_http_proxy.ps1 +++ /dev/null @@ -1,267 +0,0 @@ -#!powershell - -# Copyright: (c) 2019, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.AddType - -$spec = @{ - options = @{ - bypass = @{ type = "list" } - proxy = @{ type = "raw" } - source = @{ type = "str"; choices = @("ie") } - } - mutually_exclusive = @( - @("proxy", "source"), - @("bypass", "source") - ) - required_by = @{ - bypass = @("proxy") - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$proxy = $module.Params.proxy -$bypass = $module.Params.bypass -$source = $module.Params.source - -# Parse the raw value, it should be a Dictionary or String -if ($proxy -is [System.Collections.IDictionary]) { - $valid_keys = [System.Collections.Generic.List`1[String]]@("http", "https", "ftp", "socks") - # Check to make sure we don't have any invalid keys in the dict - $invalid_keys = [System.Collections.Generic.List`1[String]]@() - foreach ($k in $proxy.Keys) { - if ($k -notin $valid_keys) { - $invalid_keys.Add($k) - } - } - - if ($invalid_keys.Count -gt 0) { - $invalid_keys = $invalid_keys | Sort-Object # So our test assertion doesn't fail due to random ordering - $module.FailJson("Invalid keys found in proxy: $($invalid_keys -join ', '). Valid keys are $($valid_keys -join ', ').") - } - - # Build the proxy string in the form 'protocol=host;', the order of valid_keys is also important - $proxy_list = [System.Collections.Generic.List`1[String]]@() - foreach ($k in $valid_keys) { - if ($proxy.ContainsKey($k)) { - $proxy_list.Add("$k=$($proxy.$k)") - } - } - $proxy = $proxy_list -join ";" -} elseif ($null -ne $proxy) { - $proxy = $proxy.ToString() -} - -if ($bypass) { - if ([System.String]::IsNullOrEmpty($proxy)) { - $module.FailJson("missing parameter(s) required by ''bypass'': proxy") - } - $bypass = $bypass -join ';' -} - -$win_http_invoke = @' -using System; -using System.Runtime.InteropServices; - -namespace Ansible.WinHttpProxy -{ - internal class NativeHelpers - { - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public class WINHTTP_CURRENT_USER_IE_PROXY_CONFIG : IDisposable - { - public bool fAutoDetect; - public IntPtr lpszAutoConfigUrl; - public IntPtr lpszProxy; - public IntPtr lpszProxyBypass; - - public void Dispose() - { - if (lpszAutoConfigUrl != IntPtr.Zero) - Marshal.FreeHGlobal(lpszAutoConfigUrl); - if (lpszProxy != IntPtr.Zero) - Marshal.FreeHGlobal(lpszProxy); - if (lpszProxyBypass != IntPtr.Zero) - Marshal.FreeHGlobal(lpszProxyBypass); - GC.SuppressFinalize(this); - } - ~WINHTTP_CURRENT_USER_IE_PROXY_CONFIG() { this.Dispose(); } - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public class WINHTTP_PROXY_INFO : IDisposable - { - public UInt32 dwAccessType; - public IntPtr lpszProxy; - public IntPtr lpszProxyBypass; - - public void Dispose() - { - if (lpszProxy != IntPtr.Zero) - Marshal.FreeHGlobal(lpszProxy); - if (lpszProxyBypass != IntPtr.Zero) - Marshal.FreeHGlobal(lpszProxyBypass); - GC.SuppressFinalize(this); - } - ~WINHTTP_PROXY_INFO() { this.Dispose(); } - } - } - - internal class NativeMethods - { - [DllImport("Winhttp.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool WinHttpGetDefaultProxyConfiguration( - [Out] NativeHelpers.WINHTTP_PROXY_INFO pProxyInfo); - - [DllImport("Winhttp.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool WinHttpGetIEProxyConfigForCurrentUser( - [Out] NativeHelpers.WINHTTP_CURRENT_USER_IE_PROXY_CONFIG pProxyConfig); - - [DllImport("Winhttp.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool WinHttpSetDefaultProxyConfiguration( - NativeHelpers.WINHTTP_PROXY_INFO pProxyInfo); - } - - public class Win32Exception : System.ComponentModel.Win32Exception - { - private string _msg; - - public Win32Exception(string message) : this(Marshal.GetLastWin32Error(), message) { } - public Win32Exception(int errorCode, string message) : base(errorCode) - { - _msg = String.Format("{0} ({1}, Win32ErrorCode {2})", message, base.Message, errorCode); - } - - public override string Message { get { return _msg; } } - public static explicit operator Win32Exception(string message) { return new Win32Exception(message); } - } - - public class WinINetProxy - { - public bool AutoDetect; - public string AutoConfigUrl; - public string Proxy; - public string ProxyBypass; - } - - public class WinHttpProxy - { - public string Proxy; - public string ProxyBypass; - - public WinHttpProxy() - { - Refresh(); - } - - public void Set() - { - using (NativeHelpers.WINHTTP_PROXY_INFO proxyInfo = new NativeHelpers.WINHTTP_PROXY_INFO()) - { - if (String.IsNullOrEmpty(Proxy)) - proxyInfo.dwAccessType = 1; // WINHTTP_ACCESS_TYPE_NO_PROXY - else - { - proxyInfo.dwAccessType = 3; // WINHTTP_ACCESS_TYPE_NAMED_PROXY - proxyInfo.lpszProxy = Marshal.StringToHGlobalUni(Proxy); - - if (!String.IsNullOrEmpty(ProxyBypass)) - proxyInfo.lpszProxyBypass = Marshal.StringToHGlobalUni(ProxyBypass); - } - - if (!NativeMethods.WinHttpSetDefaultProxyConfiguration(proxyInfo)) - throw new Win32Exception("WinHttpSetDefaultProxyConfiguration() failed"); - } - } - - public void Refresh() - { - using (NativeHelpers.WINHTTP_PROXY_INFO proxyInfo = new NativeHelpers.WINHTTP_PROXY_INFO()) - { - if (!NativeMethods.WinHttpGetDefaultProxyConfiguration(proxyInfo)) - throw new Win32Exception("WinHttpGetDefaultProxyConfiguration() failed"); - - Proxy = Marshal.PtrToStringUni(proxyInfo.lpszProxy); - ProxyBypass = Marshal.PtrToStringUni(proxyInfo.lpszProxyBypass); - } - } - - public static WinINetProxy GetIEProxyConfig() - { - using (NativeHelpers.WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxy = new NativeHelpers.WINHTTP_CURRENT_USER_IE_PROXY_CONFIG()) - { - if (!NativeMethods.WinHttpGetIEProxyConfigForCurrentUser(ieProxy)) - throw new Win32Exception("WinHttpGetIEProxyConfigForCurrentUser() failed"); - - return new WinINetProxy - { - AutoDetect = ieProxy.fAutoDetect, - AutoConfigUrl = Marshal.PtrToStringUni(ieProxy.lpszAutoConfigUrl), - Proxy = Marshal.PtrToStringUni(ieProxy.lpszProxy), - ProxyBypass = Marshal.PtrToStringUni(ieProxy.lpszProxyBypass), - }; - } - } - } -} -'@ -Add-CSharpType -References $win_http_invoke -AnsibleModule $module - -$actual_proxy = New-Object -TypeName Ansible.WinHttpProxy.WinHttpProxy - -$module.Diff.before = @{ - proxy = $actual_proxy.Proxy - bypass = $actual_proxy.ProxyBypass -} - -if ($source -eq "ie") { - # If source=ie we need to get the server and bypass values from the IE configuration - $ie_proxy = [Ansible.WinHttpProxy.WinHttpProxy]::GetIEProxyConfig() - $proxy = $ie_proxy.Proxy - $bypass = $ie_proxy.ProxyBypass -} - -$previous_proxy = $actual_proxy.Proxy -$previous_bypass = $actual_proxy.ProxyBypass - -# Make sure an empty string is converted to $null for easier comparisons -if ([String]::IsNullOrEmpty($proxy)) { - $proxy = $null -} -if ([String]::IsNullOrEmpty($bypass)) { - $bypass = $null -} - -if ($previous_proxy -ne $proxy -or $previous_bypass -ne $bypass) { - $actual_proxy.Proxy = $proxy - $actual_proxy.ProxyBypass = $bypass - - if (-not $module.CheckMode) { - $actual_proxy.Set() - - # Validate that the change was made correctly and revert if it wasn't. The Set() method won't fail on invalid - # values so we need to check again to make sure all was good. - $actual_proxy.Refresh() - if ($actual_proxy.Proxy -ne $proxy -or $actual_proxy.ProxyBypass -ne $bypass) { - $actual_proxy.Proxy = $previous_proxy - $actual_proxy.ProxyBypass = $previous_bypass - $actual_proxy.Set() - - $module.FailJson("Unknown error when trying to set proxy '$proxy' or bypass '$bypass'") - } - } - - $module.Result.changed = $true -} - -$module.Diff.after = @{ - proxy = $proxy - bypass = $bypass -} - -$module.ExitJson() - diff --git a/lib/ansible/modules/windows/win_http_proxy.py b/lib/ansible/modules/windows/win_http_proxy.py deleted file mode 100644 index d9abb858e25..00000000000 --- a/lib/ansible/modules/windows/win_http_proxy.py +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2019, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_http_proxy -version_added: '2.8' -short_description: Manages proxy settings for WinHTTP -description: -- Used to set, remove, or import proxy settings for Windows HTTP Services - C(WinHTTP). -- WinHTTP is a framework used by applications or services, typically .NET - applications or non-interactive services, to make web requests. -options: - bypass: - description: - - A list of hosts that will bypass the set proxy when being accessed. - - Use C() to match hostnames that are not fully qualified domain - names. This is useful when needing to connect to intranet sites using - just the hostname. - - Omit, set to null or an empty string/list to remove the bypass list. - - If this is set then I(proxy) must also be set. - type: list - proxy: - description: - - A string or dict that specifies the proxy to be set. - - If setting a string, should be in the form C(hostname), C(hostname:port), - or C(protocol=hostname:port). - - If the port is undefined, the default port for the protocol in use is - used. - - If setting a dict, the keys should be the protocol and the values should - be the hostname and/or port for that protocol. - - Valid protocols are C(http), C(https), C(ftp), and C(socks). - - Omit, set to null or an empty string to remove the proxy settings. - source: - description: - - Instead of manually specifying the I(proxy) and/or I(bypass), set this to - import the proxy from a set source like Internet Explorer. - - Using C(ie) will import the Internet Explorer proxy settings for the - current active network connection of the current user. - - Only IE's proxy URL and bypass list will be imported into WinHTTP. - - This is like running C(netsh winhttp import proxy source=ie). - - The value is imported when the module runs and will not automatically - be updated if the IE configuration changes in the future. The module will - have to be run again to sync the latest changes. - choices: - - ie - type: str -notes: -- This is not the same as the proxy settings set in Internet Explorer, also - known as C(WinINet); use the M(win_inet_proxy) module to manage that instead. -- These settings are set system wide and not per user, it will require - Administrative privileges to run. -seealso: -- module: win_inet_proxy -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Set a proxy to use for all protocols - win_http_proxy: - proxy: hostname - -- name: Set a proxy with a specific port with a bypass list - win_http_proxy: - proxy: hostname:8080 - bypass: - - server1 - - server2 - - - -- name: Set the proxy based on the IE proxy settings - win_http_proxy: - source: ie - -- name: Set a proxy for specific protocols - win_http_proxy: - proxy: - http: hostname:8080 - https: hostname:8443 - -- name: Set a proxy for specific protocols using a string - win_http_proxy: - proxy: http=hostname:8080;https=hostname:8443 - bypass: server1,server2, - -- name: Remove any proxy settings - win_http_proxy: - proxy: '' - bypass: '' -''' - -RETURN = r''' -# -''' diff --git a/lib/ansible/modules/windows/win_iis_virtualdirectory.ps1 b/lib/ansible/modules/windows/win_iis_virtualdirectory.ps1 deleted file mode 100644 index 7d638979945..00000000000 --- a/lib/ansible/modules/windows/win_iis_virtualdirectory.ps1 +++ /dev/null @@ -1,99 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Henrik Wallström -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" - -$params = Parse-Args $args -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$site = Get-AnsibleParam -obj $params -name "site" -type "str" -failifempty $true -$application = Get-AnsibleParam -obj $params -name "application" -type "str" -$physical_path = Get-AnsibleParam -obj $params -name "physical_path" -type "str" -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "absent","present" - -# Ensure WebAdministration module is loaded -if ($null -eq (Get-Module "WebAdministration" -ErrorAction SilentlyContinue)) { - Import-Module WebAdministration -} - -# Result -$result = @{ - directory = @{} - changed = $false -}; - -# Construct path -$directory_path = if($application) { - "IIS:\Sites\$($site)\$($application)\$($name)" -} else { - "IIS:\Sites\$($site)\$($name)" -} - -# Directory info -$directory = if($application) { - Get-WebVirtualDirectory -Site $site -Name $name -Application $application -} else { - Get-WebVirtualDirectory -Site $site -Name $name -} - -try { - # Add directory - If(($state -eq 'present') -and (-not $directory)) { - If (-not $physical_path) { - Fail-Json -obj $result -message "missing required arguments: physical_path" - } - If (-not (Test-Path $physical_path)) { - Fail-Json -obj $result -message "specified folder must already exist: physical_path" - } - - $directory_parameters = @{ - Site = $site - Name = $name - PhysicalPath = $physical_path - } - - If ($application) { - $directory_parameters.Application = $application - } - - $directory = New-WebVirtualDirectory @directory_parameters -Force - $result.changed = $true - } - - # Remove directory - If ($state -eq 'absent' -and $directory) { - Remove-Item $directory_path -Recurse -Force - $result.changed = $true - } - - $directory = Get-WebVirtualDirectory -Site $site -Name $name - If($directory) { - - # Change Physical Path if needed - if($physical_path) { - If (-not (Test-Path $physical_path)) { - Fail-Json -obj $result -message "specified folder must already exist: physical_path" - } - - $vdir_folder = Get-Item $directory.PhysicalPath - $folder = Get-Item $physical_path - If($folder.FullName -ne $vdir_folder.FullName) { - Set-ItemProperty $directory_path -name physicalPath -value $physical_path - $result.changed = $true - } - } - } -} catch { - Fail-Json $result $_.Exception.Message -} - -# Result -$directory = Get-WebVirtualDirectory -Site $site -Name $name -$result.directory = @{ - PhysicalPath = $directory.PhysicalPath -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_iis_virtualdirectory.py b/lib/ansible/modules/windows/win_iis_virtualdirectory.py deleted file mode 100644 index a8cc49e0723..00000000000 --- a/lib/ansible/modules/windows/win_iis_virtualdirectory.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Henrik Wallström -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_iis_virtualdirectory -version_added: "2.0" -short_description: Configures a virtual directory in IIS -description: - - Creates, Removes and configures a virtual directory in IIS. -options: - name: - description: - - The name of the virtual directory to create or remove. - type: str - required: yes - state: - description: - - Whether to add or remove the specified virtual directory. - - Removing will remove the virtual directory and all under it (Recursively). - type: str - choices: [ absent, present ] - default: present - site: - description: - - The site name under which the virtual directory is created or exists. - type: str - required: yes - application: - description: - - The application under which the virtual directory is created or exists. - type: str - physical_path: - description: - - The physical path to the folder in which the new virtual directory is created. - - The specified folder must already exist. - type: str -seealso: -- module: win_iis_webapplication -- module: win_iis_webapppool -- module: win_iis_webbinding -- module: win_iis_website -author: -- Henrik Wallström (@henrikwallstrom) -''' - -EXAMPLES = r''' -- name: Create a virtual directory if it does not exist - win_iis_virtualdirectory: - name: somedirectory - site: somesite - state: present - physical_path: C:\virtualdirectory\some - -- name: Remove a virtual directory if it exists - win_iis_virtualdirectory: - name: somedirectory - site: somesite - state: absent - -- name: Create a virtual directory on an application if it does not exist - win_iis_virtualdirectory: - name: somedirectory - site: somesite - application: someapp - state: present - physical_path: C:\virtualdirectory\some -''' diff --git a/lib/ansible/modules/windows/win_iis_webapplication.ps1 b/lib/ansible/modules/windows/win_iis_webapplication.ps1 deleted file mode 100644 index 92fdbbd9e50..00000000000 --- a/lib/ansible/modules/windows/win_iis_webapplication.ps1 +++ /dev/null @@ -1,138 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Henrik Wallström -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$site = Get-AnsibleParam -obj $params -name "site" -type "str" -failifempty $true -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "absent","present" -$physical_path = Get-AnsibleParam -obj $params -name "physical_path" -type "str" -aliases "path" -$application_pool = Get-AnsibleParam -obj $params -name "application_pool" -type "str" -$connect_as = Get-AnsibleParam -obj $params -name 'connect_as' -type 'str' -validateset 'specific_user', 'pass_through' -$username = Get-AnsibleParam -obj $params -name "username" -type "str" -failifempty ($connect_as -eq 'specific_user') -$password = Get-AnsibleParam -obj $params -name "password" -type "str" -failifempty ($connect_as -eq 'specific_user') - -$result = @{ - application_pool = $application_pool - changed = $false - physical_path = $physical_path -} - -# Ensure WebAdministration module is loaded -if ($null -eq (Get-Module "WebAdministration" -ErrorAction SilentlyContinue)) { - Import-Module WebAdministration -} - -# Application info -$application = Get-WebApplication -Site $site -Name $name -$website = Get-Website -Name $site - -# Set ApplicationPool to current if not specified -if (!$application_pool) { - $application_pool = $website.applicationPool -} - -try { - # Add application - if (($state -eq 'present') -and (-not $application)) { - if (-not $physical_path) { - Fail-Json $result "missing required arguments: path" - } - if (-not (Test-Path -Path $physical_path)) { - Fail-Json $result "specified folder must already exist: path" - } - - $application_parameters = @{ - Name = $name - PhysicalPath = $physical_path - Site = $site - } - - if ($application_pool) { - $application_parameters.ApplicationPool = $application_pool - } - - if (-not $check_mode) { - $application = New-WebApplication @application_parameters -Force - } - $result.changed = $true - } - - # Remove application - if ($state -eq 'absent' -and $application) { - $application = Remove-WebApplication -Site $site -Name $name -WhatIf:$check_mode - $result.changed = $true - } - - $application = Get-WebApplication -Site $site -Name $name - if ($application) { - - # Change Physical Path if needed - if ($physical_path) { - if (-not (Test-Path -Path $physical_path)) { - Fail-Json $result "specified folder must already exist: path" - } - - $app_folder = Get-Item $application.PhysicalPath - $folder = Get-Item $physical_path - if ($folder.FullName -ne $app_folder.FullName) { - Set-ItemProperty "IIS:\Sites\$($site)\$($name)" -name physicalPath -value $physical_path -WhatIf:$check_mode - $result.changed = $true - } - } - - # Change Application Pool if needed - if ($application_pool) { - if ($application_pool -ne $application.applicationPool) { - Set-ItemProperty "IIS:\Sites\$($site)\$($name)" -name applicationPool -value $application_pool -WhatIf:$check_mode - $result.changed = $true - } - } - - # Change username and password if needed - $app_user = Get-ItemProperty -Path "IIS:\Sites\$($site)\$($name)" -Name 'userName' - $app_pass = Get-ItemProperty -Path "IIS:\Sites\$($site)\$($name)" -Name 'password' - if ($connect_as -eq 'pass_through') { - if ($app_user -ne '') { - Clear-ItemProperty -Path "IIS:\Sites\$($site)\$($name)" -Name 'userName' -WhatIf:$check_mode - $result.changed = $true - } - if ($app_pass -ne '') { - Clear-ItemProperty -Path "IIS:\Sites\$($site)\$($name)" -Name 'password' -WhatIf:$check_mode - $result.changed = $true - } - } elseif ($connect_as -eq 'specific_user') { - if ($app_user -ne $username) { - Set-ItemProperty -Path "IIS:\Sites\$($site)\$($name)" -Name 'userName' -Value $username -WhatIf:$check_mode - $result.changed = $true - } - if ($app_pass -ne $password) { - Set-ItemProperty -Path "IIS:\Sites\$($site)\$($name)" -Name 'password' -Value $password -WhatIf:$check_mode - $result.changed = $true - } - } - } -} catch { - Fail-Json $result $_.Exception.Message -} - -# When in check-mode or on removal, this may fail -$application = Get-WebApplication -Site $site -Name $name -if ($application) { - $app_user = Get-ItemProperty -Path "IIS:\Sites\$($site)\$($name)" -Name 'userName' - if ($app_user -eq '') { - $result.connect_as = 'pass_through' - } else { - $result.connect_as = 'specific_user' - } - - $result.physical_path = $application.PhysicalPath - $result.application_pool = $application.ApplicationPool -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_iis_webapplication.py b/lib/ansible/modules/windows/win_iis_webapplication.py deleted file mode 100644 index 2fad6a48072..00000000000 --- a/lib/ansible/modules/windows/win_iis_webapplication.py +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Henrik Wallström -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_iis_webapplication -version_added: "2.0" -short_description: Configures IIS web applications -description: -- Creates, removes, and configures IIS web applications. -options: - name: - description: - - Name of the web application. - type: str - required: yes - site: - description: - - Name of the site on which the application is created. - type: str - required: yes - state: - description: - - State of the web application. - type: str - choices: [ absent, present ] - default: present - physical_path: - description: - - The physical path on the remote host to use for the new application. - - The specified folder must already exist. - type: str - application_pool: - description: - - The application pool in which the new site executes. - - If not specified, the application pool of the current website will be used. - type: str - connect_as: - description: - - The type of authentication to use for this application. Either C(pass_through) or C(specific_user) - - If C(pass_through), IIS will use the identity of the user or application pool identity to access the file system or network. - - If C(specific_user), IIS will use the credentials provided in I(username) and I(password) to access the file system or network. - type: str - choices: [pass_through, specific_user] - version_added: '2.10' - username: - description: - - Specifies the user name of an account that can access configuration files and content for this application. - - Required when I(connect_as) is set to C(specific_user). - type: str - version_added: '2.10' - password: - description: - - The password associated with I(username). - - Required when I(connect_as) is set to C(specific_user). - type: str - version_added: '2.10' -seealso: -- module: win_iis_virtualdirectory -- module: win_iis_webapppool -- module: win_iis_webbinding -- module: win_iis_website -author: -- Henrik Wallström (@henrikwallstrom) -''' - -EXAMPLES = r''' -- name: Add ACME webapplication on IIS. - win_iis_webapplication: - name: api - site: acme - state: present - physical_path: C:\apps\acme\api -''' - -RETURN = r''' -application_pool: - description: The used/implemented application_pool value. - returned: success - type: str - sample: DefaultAppPool -physical_path: - description: The used/implemented physical_path value. - returned: success - type: str - sample: C:\apps\acme\api -connect_as: - description: How IIS will try to authenticate to the physical_path. - returned: when the application exists - type: str - sample: specific_user -''' diff --git a/lib/ansible/modules/windows/win_iis_webapppool.ps1 b/lib/ansible/modules/windows/win_iis_webapppool.ps1 deleted file mode 100644 index 79167ba02ea..00000000000 --- a/lib/ansible/modules/windows/win_iis_webapppool.ps1 +++ /dev/null @@ -1,307 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Henrik Wallström -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = 'Stop' - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateSet "started","restarted","stopped","absent","present" -$result = @{ - changed = $false - attributes = @{} - info = @{ - name = $name - state = $state - attributes = @{} - cpu = @{} - failure = @{} - processModel = @{} - recycling = @{ - periodicRestart = @{} - } - } -} - -# Stores the free form attributes for the module -$attributes = @{} -$input_attributes = Get-AnsibleParam -obj $params -name "attributes" -if ($input_attributes) { - if ($input_attributes -is [System.Collections.Hashtable]) { - # Uses dict style parameters, newer and recommended style - $attributes = $input_attributes - } else { - Fail-Json -obj $result -message "Using a string for the attributes parameter is not longer supported, please use a dict instead" - } -} -$result.attributes = $attributes - -Function Get-DotNetClassForAttribute($attribute_parent) { - switch ($attribute_parent) { - "attributes" { [Microsoft.Web.Administration.ApplicationPool] } - "cpu" { [Microsoft.Web.Administration.ApplicationPoolCpu] } - "failure" { [Microsoft.Web.Administration.ApplicationPoolFailure] } - "processModel" { [Microsoft.Web.Administration.ApplicationPoolProcessModel] } - "recycling" { [Microsoft.Web.Administration.ApplicationPoolRecycling] } - default { [Microsoft.Web.Administration.ApplicationPool] } - } -} - -Function Convert-CollectionToList($collection) { - $list = @() - - if ($collection -is [String]) { - $raw_list = $collection -split "," - foreach ($entry in $raw_list) { - $list += $entry.Trim() - } - } elseif ($collection -is [Microsoft.IIs.PowerShell.Framework.ConfigurationElement]) { - # the collection is the value from IIS itself, we need to conver accordingly - foreach ($entry in $collection.Collection) { - $list += $entry.Value.ToString() - } - } elseif ($collection -isnot [Array]) { - $list += $collection - } else { - $list = $collection - } - - return ,$list -} - -Function Compare-Values($current, $new) { - if ($null -eq $current) { - return $true - } - - if ($current -is [Array]) { - if ($new -isnot [Array]) { - return $true - } - - if ($current.Count -ne $new.Count) { - return $true - } - for ($i = 0; $i -lt $current.Count; $i++) { - if ($current[$i] -ne $new[$i]) { - return $true - } - } - } else { - if ($current -ne $new) { - return $true - } - } - return $false -} - -Function Convert-ToPropertyValue($pool, $attribute_key, $attribute_value) { - # Will convert the new value to the enum value expected and cast accordingly to the type - if ([bool]($attribute_value.PSobject.Properties -match "Value")) { - $attribute_value = $attribute_value.Value - } - $attribute_key_split = $attribute_key -split "\." - if ($attribute_key_split.Length -eq 1) { - $attribute_parent = "attributes" - $attribute_child = $attribute_key - $attribute_meta = $pool.Attributes | Where-Object { $_.Name -eq $attribute_child } - } elseif ($attribute_key_split.Length -gt 1) { - $attribute_parent = $attribute_key_split[0] - $attribute_key_split = $attribute_key_split[1..$($attribute_key_split.Length - 1)] - $parent = $pool.$attribute_parent - - foreach ($key in $attribute_key_split) { - $attribute_meta = $parent.Attributes | Where-Object { $_.Name -eq $key } - $parent = $parent.$key - if ($null -eq $attribute_meta) { - $attribute_meta = $parent - } - } - $attribute_child = $attribute_key_split[-1] - } - - if ($attribute_meta) { - if (($attribute_meta.PSObject.Properties.Name -eq "Collection").Count -gt 0) { - return ,(Convert-CollectionToList -collection $attribute_value) - } - $type = $attribute_meta.Schema.Type - $value = $attribute_value - if ($type -eq "enum") { - # Attempt to convert the value from human friendly to enum value - use existing value if we fail - $dot_net_class = Get-DotNetClassForAttribute -attribute_parent $attribute_parent - $enum_attribute_name = $attribute_child.Substring(0,1).ToUpper() + $attribute_child.Substring(1) - $enum = $dot_net_class.GetProperty($enum_attribute_name).PropertyType.FullName - if ($enum) { - $enum_values = [Enum]::GetValues($enum) - foreach ($enum_value in $enum_values) { - if ($attribute_value.GetType() -is $enum_value.GetType()) { - if ($enum_value -eq $attribute_value) { - $value = $enum_value - break - } - } else { - if ([System.String]$enum_value -eq [System.String]$attribute_value) { - $value = $enum_value - break - } - } - } - } - } - # Try and cast the variable using the chosen type, revert to the default if it fails - Set-Variable -Name casted_value -Value ($value -as ([type] $attribute_meta.TypeName)) - if ($null -eq $casted_value) { - $value - } else { - $casted_value - } - } else { - $attribute_value - } -} - -# Ensure WebAdministration module is loaded -if ($null -eq (Get-Module -Name "WebAdministration" -ErrorAction SilentlyContinue)) { - Import-Module WebAdministration - $web_admin_dll_path = Join-Path $env:SystemRoot system32\inetsrv\Microsoft.Web.Administration.dll - Add-Type -Path $web_admin_dll_path -} - -$pool = Get-Item -Path IIS:\AppPools\$name -ErrorAction SilentlyContinue -if ($state -eq "absent") { - # Remove pool if present - if ($pool) { - try { - Remove-WebAppPool -Name $name -WhatIf:$check_mode - } catch { - Fail-Json $result "Failed to remove Web App pool $($name): $($_.Exception.Message)" - } - $result.changed = $true - } -} else { - # Add pool if absent - if (-not $pool) { - if (-not $check_mode) { - try { - New-WebAppPool -Name $name > $null - } catch { - Fail-Json $result "Failed to create new Web App Pool $($name): $($_.Exception.Message)" - } - } - $result.changed = $true - # If in check mode this pool won't actually exists so skip it - if (-not $check_mode) { - $pool = Get-Item -Path IIS:\AppPools\$name - } - } - - # Cannot run the below in check mode if the pool did not always exist - if ($pool) { - # Modify pool based on parameters - foreach ($attribute in $attributes.GetEnumerator()) { - $attribute_key = $attribute.Name - $new_raw_value = $attribute.Value - $new_value = Convert-ToPropertyValue -pool $pool -attribute_key $attribute_key -attribute_value $new_raw_value - - $current_raw_value = Get-ItemProperty -Path IIS:\AppPools\$name -Name $attribute_key -ErrorAction SilentlyContinue - $current_value = Convert-ToPropertyValue -pool $pool -attribute_key $attribute_key -attribute_value $current_raw_value - - $changed = Compare-Values -current $current_value -new $new_value - if ($changed -eq $true) { - if ($new_value -is [Array]) { - try { - Clear-ItemProperty -Path IIS:\AppPools\$name -Name $attribute_key -WhatIf:$check_mode - } catch { - Fail-Json -obj $result -message "Failed to clear attribute to Web App Pool $name. Attribute: $attribute_key, Exception: $($_.Exception.Message)" - } - foreach ($value in $new_value) { - try { - New-ItemProperty -Path IIS:\AppPools\$name -Name $attribute_key -Value @{value=$value} -WhatIf:$check_mode > $null - } catch { - Fail-Json -obj $result -message "Failed to add new attribute to Web App Pool $name. Attribute: $attribute_key, Value: $value, Exception: $($_.Exception.Message)" - } - } - } else { - try { - Set-ItemProperty -Path IIS:\AppPools\$name -Name $attribute_key -Value $new_value -WhatIf:$check_mode - } catch { - Fail-Json $result "Failed to set attribute to Web App Pool $name. Attribute: $attribute_key, Value: $new_value, Exception: $($_.Exception.Message)" - } - } - $result.changed = $true - } - } - - # Set the state of the pool - if ($pool.State -eq "Stopped") { - if ($state -eq "started" -or $state -eq "restarted") { - if (-not $check_mode) { - try { - Start-WebAppPool -Name $name > $null - } catch { - Fail-Json $result "Failed to start Web App Pool $($name): $($_.Exception.Message)" - } - } - $result.changed = $true - } - } else { - if ($state -eq "stopped") { - if (-not $check_mode) { - try { - Stop-WebAppPool -Name $name > $null - } catch { - Fail-Json $result "Failed to stop Web App Pool $($name): $($_.Exception.Message)" - } - } - $result.changed = $true - } elseif ($state -eq "restarted") { - if (-not $check_mode) { - try { - Restart-WebAppPool -Name $name > $null - } catch { - Fail-Json $result "Failed to restart Web App Pool $($name): $($_.Exception.Message)" - } - } - $result.changed = $true - } - } - } -} - -# Get all the current attributes for the pool -$pool = Get-Item -Path IIS:\AppPools\$name -ErrorAction SilentlyContinue -$elements = @("attributes", "cpu", "failure", "processModel", "recycling") - -foreach ($element in $elements) { - if ($element -eq "attributes") { - $attribute_collection = $pool.Attributes - $attribute_parent = $pool - } else { - $attribute_collection = $pool.$element.Attributes - $attribute_parent = $pool.$element - } - - foreach ($attribute in $attribute_collection) { - $attribute_name = $attribute.Name - if ($attribute_name -notlike "*password*") { - $attribute_value = $attribute_parent.$attribute_name - - $result.info.$element.Add($attribute_name, $attribute_value) - } - } -} - -# Manually get the periodicRestart attributes in recycling -foreach ($attribute in $pool.recycling.periodicRestart.Attributes) { - $attribute_name = $attribute.Name - $attribute_value = $pool.recycling.periodicRestart.$attribute_name - $result.info.recycling.periodicRestart.Add($attribute_name, $attribute_value) -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_iis_webapppool.py b/lib/ansible/modules/windows/win_iis_webapppool.py deleted file mode 100644 index d5a79c7328c..00000000000 --- a/lib/ansible/modules/windows/win_iis_webapppool.py +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Henrik Wallström -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_iis_webapppool -version_added: "2.0" -short_description: Configure IIS Web Application Pools -description: - - Creates, removes and configures an IIS Web Application Pool. -options: - attributes: - description: - - This field is a free form dictionary value for the application pool - attributes. - - These attributes are based on the naming standard at - U(https://www.iis.net/configreference/system.applicationhost/applicationpools/add#005), - see the examples section for more details on how to set this. - - You can also set the attributes of child elements like cpu and - processModel, see the examples to see how it is done. - - While you can use the numeric values for enums it is recommended to use - the enum name itself, e.g. use SpecificUser instead of 3 for - processModel.identityType. - - managedPipelineMode may be either "Integrated" or "Classic". - - startMode may be either "OnDemand" or "AlwaysRunning". - - Use C(state) module parameter to modify the state of the app pool. - - When trying to set 'processModel.password' and you receive a 'Value - does fall within the expected range' error, you have a corrupted - keystore. Please follow - U(http://structuredsight.com/2014/10/26/im-out-of-range-youre-out-of-range/) - to help fix your host. - name: - description: - - Name of the application pool. - type: str - required: yes - state: - description: - - The state of the application pool. - - If C(absent) will ensure the app pool is removed. - - If C(present) will ensure the app pool is configured and exists. - - If C(restarted) will ensure the app pool exists and will restart, this - is never idempotent. - - If C(started) will ensure the app pool exists and is started. - - If C(stopped) will ensure the app pool exists and is stopped. - type: str - choices: [ absent, present, restarted, started, stopped ] - default: present -seealso: -- module: win_iis_virtualdirectory -- module: win_iis_webapplication -- module: win_iis_webbinding -- module: win_iis_website -author: -- Henrik Wallström (@henrikwallstrom) -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Return information about an existing application pool - win_iis_webapppool: - name: DefaultAppPool - state: present - -- name: Create a new application pool in 'Started' state - win_iis_webapppool: - name: AppPool - state: started - -- name: Stop an application pool - win_iis_webapppool: - name: AppPool - state: stopped - -- name: Restart an application pool (non-idempotent) - win_iis_webapppool: - name: AppPool - state: restarted - -- name: Change application pool attributes using new dict style - win_iis_webapppool: - name: AppPool - attributes: - managedRuntimeVersion: v4.0 - autoStart: no - -- name: Creates an application pool, sets attributes and starts it - win_iis_webapppool: - name: AnotherAppPool - state: started - attributes: - managedRuntimeVersion: v4.0 - autoStart: no - -# In the below example we are setting attributes in child element processModel -# https://www.iis.net/configreference/system.applicationhost/applicationpools/add/processmodel -- name: Manage child element and set identity of application pool - win_iis_webapppool: - name: IdentitiyAppPool - state: started - attributes: - managedPipelineMode: Classic - processModel.identityType: SpecificUser - processModel.userName: '{{ansible_user}}' - processModel.password: '{{ansible_password}}' - processModel.loadUserProfile: true - -- name: Manage a timespan attribute - win_iis_webapppool: - name: TimespanAppPool - state: started - attributes: - # Timespan with full string "day:hour:minute:second.millisecond" - recycling.periodicRestart.time: "00:00:05:00.000000" - recycling.periodicRestart.schedule: ["00:10:00", "05:30:00"] - # Shortened timespan "hour:minute:second" - processModel.pingResponseTime: "00:03:00" -''' - -RETURN = r''' -attributes: - description: Application Pool attributes that were set and processed by this - module invocation. - returned: success - type: dict - sample: - enable32BitAppOnWin64: "true" - managedRuntimeVersion: "v4.0" - managedPipelineMode: "Classic" -info: - description: Information on current state of the Application Pool. See - https://www.iis.net/configreference/system.applicationhost/applicationpools/add#005 - for the full list of return attributes based on your IIS version. - returned: success - type: complex - sample: - contains: - attributes: - description: Key value pairs showing the current Application Pool attributes. - returned: success - type: dict - sample: - autoStart: true - managedRuntimeLoader: "webengine4.dll" - managedPipelineMode: "Classic" - name: "DefaultAppPool" - CLRConfigFile: "" - passAnonymousToken: true - applicationPoolSid: "S-1-5-82-1352790163-598702362-1775843902-1923651883-1762956711" - queueLength: 1000 - managedRuntimeVersion: "v4.0" - state: "Started" - enableConfigurationOverride: true - startMode: "OnDemand" - enable32BitAppOnWin64: true - cpu: - description: Key value pairs showing the current Application Pool cpu attributes. - returned: success - type: dict - sample: - action: "NoAction" - limit: 0 - resetInterval: - Days: 0 - Hours: 0 - failure: - description: Key value pairs showing the current Application Pool failure attributes. - returned: success - type: dict - sample: - autoShutdownExe: "" - orphanActionExe: "" - rapidFailProtextionInterval: - Days: 0 - Hours: 0 - name: - description: Name of Application Pool that was processed by this module invocation. - returned: success - type: str - sample: "DefaultAppPool" - processModel: - description: Key value pairs showing the current Application Pool processModel attributes. - returned: success - type: dict - sample: - identityType: "ApplicationPoolIdentity" - logonType: "LogonBatch" - pingInterval: - Days: 0 - Hours: 0 - recycling: - description: Key value pairs showing the current Application Pool recycling attributes. - returned: success - type: dict - sample: - disallowOverlappingRotation: false - disallowRotationOnConfigChange: false - logEventOnRecycle: "Time,Requests,Schedule,Memory,IsapiUnhealthy,OnDemand,ConfigChange,PrivateMemory" - state: - description: Current runtime state of the pool as the module completed. - returned: success - type: str - sample: "Started" -''' diff --git a/lib/ansible/modules/windows/win_iis_webbinding.ps1 b/lib/ansible/modules/windows/win_iis_webbinding.ps1 deleted file mode 100644 index ffbd1866aea..00000000000 --- a/lib/ansible/modules/windows/win_iis_webbinding.ps1 +++ /dev/null @@ -1,377 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Noah Sparks -# Copyright: (c) 2015, Henrik Wallström -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$name = Get-AnsibleParam $params -name "name" -type str -failifempty $true -aliases 'website' -$state = Get-AnsibleParam $params "state" -default "present" -validateSet "present","absent" -$host_header = Get-AnsibleParam $params -name "host_header" -type str -$protocol = Get-AnsibleParam $params -name "protocol" -type str -default 'http' -$port = Get-AnsibleParam $params -name "port" -default '80' -$ip = Get-AnsibleParam $params -name "ip" -default '*' -$certificateHash = Get-AnsibleParam $params -name "certificate_hash" -type str -default ([string]::Empty) -$certificateStoreName = Get-AnsibleParam $params -name "certificate_store_name" -type str -default ([string]::Empty) -$sslFlags = Get-AnsibleParam $params -name "ssl_flags" -default '0' -ValidateSet '0','1','2','3' - -$result = @{ - changed = $false -} - -################# -### Functions ### -################# -function Create-BindingInfo { - $ht = @{ - 'bindingInformation' = $args[0].bindingInformation - 'ip' = $args[0].bindingInformation.split(':')[0] - 'port' = [int]$args[0].bindingInformation.split(':')[1] - 'hostheader' = $args[0].bindingInformation.split(':')[2] - #'isDsMapperEnabled' = $args[0].isDsMapperEnabled - 'protocol' = $args[0].protocol - 'certificateStoreName' = $args[0].certificateStoreName - 'certificateHash' = $args[0].certificateHash - } - - #handle sslflag support - If ([version][System.Environment]::OSVersion.Version -lt [version]'6.2') - { - $ht.sslFlags = 'not supported' - } - Else - { - $ht.sslFlags = [int]$args[0].sslFlags - } - - Return $ht -} - -# Used instead of get-webbinding to ensure we always return a single binding -# We can't filter properly with get-webbinding...ex get-webbinding ip * returns all bindings -# pass it $binding_parameters hashtable -function Get-SingleWebBinding { - - Try { - $site_bindings = get-webbinding -name $args[0].name - } - Catch { - # 2k8r2 throws this error when you run get-webbinding with no bindings in iis - If (-not $_.Exception.Message.CompareTo('Cannot process argument because the value of argument "obj" is null. Change the value of argument "obj" to a non-null value')) - { - Throw $_.Exception.Message - } - Else { return } - } - - Foreach ($binding in $site_bindings) - { - $splits = $binding.bindingInformation -split ':' - - if ( - $args[0].protocol -eq $binding.protocol -and - $args[0].ipaddress -eq $splits[0] -and - $args[0].port -eq $splits[1] -and - $args[0].hostheader -eq $splits[2] - ) - { - Return $binding - } - } -} - - -############################# -### Pre-Action Validation ### -############################# -$os_version = [version][System.Environment]::OSVersion.Version - -# Ensure WebAdministration module is loaded -If ($os_version -lt [version]'6.1') -{ - Try { - Add-PSSnapin WebAdministration - } - Catch { - Fail-Json -obj $result -message "The WebAdministration snap-in is not present. Please make sure it is installed." - } -} -Else -{ - Try { - Import-Module WebAdministration - } - Catch { - Fail-Json -obj $result -message "Failed to load WebAdministration module. Is IIS installed? $($_.Exception.Message)" - } -} - -# ensure website targetted exists. -Name filter doesn't work on 2k8r2 so do where-object instead -$website_check = get-website | Where-Object {$_.name -eq $name} -If (-not $website_check) -{ - Fail-Json -obj $result -message "Unable to retrieve website with name $Name. Make sure the website name is valid and exists." -} - -# if OS older than 2012 (6.2) and ssl flags are set, fail. Otherwise toggle sni_support -If ($os_version -lt [version]'6.2') -{ - If ($sslFlags -ne 0) - { - Fail-Json -obj $result -message "SNI and Certificate Store support is not available for systems older than 2012 (6.2)" - } - $sni_support = $false #will cause the sslflags check later to skip -} -Else -{ - $sni_support = $true -} - -# make sure ssl flags only specified with https protocol -If ($protocol -ne 'https' -and $sslFlags -gt 0) -{ - Fail-Json -obj $result -message "SSLFlags can only be set for HTTPS protocol" -} - -# validate certificate details if provided -# we don't do anything with cert on state: absent, so only validate present -If ($certificateHash -and $state -eq 'present') -{ - If ($protocol -ne 'https') - { - Fail-Json -obj $result -message "You can only provide a certificate thumbprint when protocol is set to https" - } - - #apply default for cert store name - If (-Not $certificateStoreName) - { - $certificateStoreName = 'my' - } - - #validate cert path - $cert_path = "cert:\LocalMachine\$certificateStoreName\$certificateHash" - If (-Not (Test-Path $cert_path) ) - { - Fail-Json -obj $result -message "Unable to locate certificate at $cert_path" - } -} - -# make sure binding info is valid for central cert store if sslflags -gt 1 -If ($sslFlags -gt 1 -and ($certificateHash -ne [string]::Empty -or $certificateStoreName -ne [string]::Empty)) -{ - Fail-Json -obj $result -message "You set sslFlags to $sslFlags. This indicates you wish to use the Central Certificate Store feature. - This cannot be used in combination with certficiate_hash and certificate_store_name. When using the Central Certificate Store feature, - the certificate is automatically retrieved from the store rather than manually assigned to the binding." -} - -# disallow host_header: '*' -If ($host_header -eq '*') -{ - Fail-Json -obj $result -message "To make or remove a catch-all binding, please omit the host_header parameter entirely rather than specify host_header *" -} - -########################## -### start action items ### -########################## - -# create binding search splat -$binding_parameters = @{ - Name = $name - Protocol = $protocol - Port = $port - IPAddress = $ip -} - -# insert host header to search if specified, otherwise it will return * (all bindings matching protocol/ip) -If ($host_header) -{ - $binding_parameters.HostHeader = $host_header -} -Else -{ - $binding_parameters.HostHeader = [string]::Empty -} - -# Get bindings matching parameters -Try { - $current_bindings = Get-SingleWebBinding $binding_parameters -} -Catch { - Fail-Json -obj $result -message "Failed to retrieve bindings with Get-SingleWebBinding - $($_.Exception.Message)" -} - -################################################ -### Remove binding or exit if already absent ### -################################################ -If ($current_bindings -and $state -eq 'absent') -{ - Try { - #there is a bug in this method that will result in all bindings being removed if the IP in $current_bindings is a * - #$current_bindings | Remove-WebBinding -verbose -WhatIf:$check_mode - - #another method that did not work. It kept failing to match on element and removed everything. - #$element = @{protocol="$protocol";bindingInformation="$ip`:$port`:$host_header"} - #Remove-WebconfigurationProperty -filter $current_bindings.ItemXPath -Name Bindings.collection -AtElement $element -WhatIf #:$check_mode - - #this method works - [array]$bindings = Get-WebconfigurationProperty -filter $current_bindings.ItemXPath -Name Bindings.collection - - $index = Foreach ($item in $bindings) { - If ( $protocol -eq $item.protocol -and $current_bindings.bindingInformation -eq $item.bindingInformation ) { - $bindings.indexof($item) - break - } - } - - Remove-WebconfigurationProperty -filter $current_bindings.ItemXPath -Name Bindings.collection -AtIndex $index -WhatIf:$check_mode - $result.changed = $true - } - - Catch { - Fail-Json -obj $result -message "Failed to remove the binding from IIS - $($_.Exception.Message)" - } - - # removing bindings from iis may not also remove them from iis:\sslbindings - - $result.operation_type = 'removed' - $result.binding_info = $current_bindings | ForEach-Object {Create-BindingInfo $_} - Exit-Json -obj $result -} -ElseIf (-Not $current_bindings -and $state -eq 'absent') -{ - # exit changed: false since it's already gone - Exit-Json -obj $result -} - - -################################ -### Modify existing bindings ### -################################ -<# -since we have already have the parameters available to get-webbinding, -we just need to check here for the ones that are not available which are the -ssl settings (hash, store, sslflags). If they aren't set we update here, or -exit with changed: false -#> -ElseIf ($current_bindings) -{ - #ran into a strange edge case in testing where I was able to retrieve bindings but not expand all the properties - #when adding a self-signed wildcard cert to a binding. it seemed to permanently break the binding. only removing it - #would cause the error to stop. - Try { - $null = $current_bindings | Select-Object * - } - Catch { - Fail-Json -obj $result -message "Found a matching binding, but failed to expand it's properties (get-binding | FL *). In testing, this was caused by using a self-signed wildcard certificate. $($_.Exception.Message)" - } - - # check if there is a match on the ssl parameters - If ( ($current_bindings.sslFlags -ne $sslFlags -and $sni_support) -or - $current_bindings.certificateHash -ne $certificateHash -or - $current_bindings.certificateStoreName -ne $certificateStoreName) - { - # match/update SNI - If ($current_bindings.sslFlags -ne $sslFlags -and $sni_support) - { - Try { - Set-WebBinding -Name $name -IPAddress $ip -Port $port -HostHeader $host_header -PropertyName sslFlags -value $sslFlags -whatif:$check_mode - $result.changed = $true - } - Catch { - Fail-Json -obj $result -message "Failed to update sslFlags on binding - $($_.Exception.Message)" - } - - # Refresh the binding object since it has been changed - Try { - $current_bindings = Get-SingleWebBinding $binding_parameters - } - Catch { - Fail-Json -obj $result -message "Failed to refresh bindings after setting sslFlags - $($_.Exception.Message)" - } - } - # match/update certificate - If ($current_bindings.certificateHash -ne $certificateHash -or $current_bindings.certificateStoreName -ne $certificateStoreName) - { - If (-Not $check_mode) - { - Try { - $current_bindings.AddSslCertificate($certificateHash,$certificateStoreName) - } - Catch { - Fail-Json -obj $result -message "Failed to set new SSL certificate - $($_.Exception.Message)" - } - } - } - $result.changed = $true - $result.operation_type = 'updated' - $result.website_state = (Get-Website | Where-Object {$_.Name -eq $Name}).State - $result.binding_info = Create-BindingInfo (Get-SingleWebBinding $binding_parameters) - Exit-Json -obj $result #exit changed true - } - Else - { - $result.operation_type = 'matched' - $result.website_state = (Get-Website | Where-Object {$_.Name -eq $Name}).State - $result.binding_info = Create-BindingInfo (Get-SingleWebBinding $binding_parameters) - Exit-Json -obj $result #exit changed false - } -} - -######################## -### Add new bindings ### -######################## -ElseIf (-not $current_bindings -and $state -eq 'present') -{ - # add binding. this creates the binding, but does not apply a certificate to it. - Try - { - If (-not $check_mode) - { - If ($sni_support) - { - New-WebBinding @binding_parameters -SslFlags $sslFlags -Force - } - Else - { - New-WebBinding @binding_parameters -Force - } - } - $result.changed = $true - } - Catch - { - $result.website_state = (Get-Website | Where-Object {$_.Name -eq $Name}).State - Fail-Json -obj $result -message "Failed at creating new binding (note: creating binding and adding ssl are separate steps) - $($_.Exception.Message)" - } - - # add certificate to binding - If ($certificateHash -and -not $check_mode) - { - Try { - #$new_binding = get-webbinding -Name $name -IPAddress $ip -port $port -Protocol $protocol -hostheader $host_header - $new_binding = Get-SingleWebBinding $binding_parameters - $new_binding.addsslcertificate($certificateHash,$certificateStoreName) - } - Catch { - $result.website_state = (Get-Website | Where-Object {$_.Name -eq $Name}).State - Fail-Json -obj $result -message "Failed to set new SSL certificate - $($_.Exception.Message)" - } - } - - $result.changed = $true - $result.operation_type = 'added' - $result.website_state = (Get-Website | Where-Object {$_.Name -eq $Name}).State - - # incase there are no bindings we do a check before calling Create-BindingInfo - $web_binding = Get-SingleWebBinding $binding_parameters - if ($web_binding) { - $result.binding_info = Create-BindingInfo $web_binding - } else { - $result.binding_info = $null - } - Exit-Json $result -} diff --git a/lib/ansible/modules/windows/win_iis_webbinding.py b/lib/ansible/modules/windows/win_iis_webbinding.py deleted file mode 100644 index 27fdd28f5cd..00000000000 --- a/lib/ansible/modules/windows/win_iis_webbinding.py +++ /dev/null @@ -1,154 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Noah Sparks -# Copyright: (c) 2017, Henrik Wallström -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_iis_webbinding -version_added: "2.0" -short_description: Configures a IIS Web site binding -description: - - Creates, removes and configures a binding to an existing IIS Web site. -options: - name: - description: - - Names of web site. - type: str - required: yes - aliases: [ website ] - state: - description: - - State of the binding. - type: str - choices: [ absent, present ] - default: present - port: - description: - - The port to bind to / use for the new site. - type: str - default: 80 - ip: - description: - - The IP address to bind to / use for the new site. - type: str - default: '*' - host_header: - description: - - The host header to bind to / use for the new site. - - If you are creating/removing a catch-all binding, omit this parameter rather than defining it as '*'. - type: str - protocol: - description: - - The protocol to be used for the Web binding (usually HTTP, HTTPS, or FTP). - type: str - default: http - certificate_hash: - description: - - Certificate hash (thumbprint) for the SSL binding. The certificate hash is the unique identifier for the certificate. - type: str - certificate_store_name: - description: - - Name of the certificate store where the certificate for the binding is located. - type: str - default: my - ssl_flags: - description: - - This parameter is only valid on Server 2012 and newer. - - Primarily used for enabling and disabling server name indication (SNI). - - Set to C(0) to disable SNI. - - Set to C(1) to enable SNI. - type: str - version_added: "2.5" -seealso: -- module: win_iis_virtualdirectory -- module: win_iis_webapplication -- module: win_iis_webapppool -- module: win_iis_website -author: - - Noah Sparks (@nwsparks) - - Henrik Wallström (@henrikwallstrom) -''' - -EXAMPLES = r''' -- name: Add a HTTP binding on port 9090 - win_iis_webbinding: - name: Default Web Site - port: 9090 - state: present - -- name: Remove the HTTP binding on port 9090 - win_iis_webbinding: - name: Default Web Site - port: 9090 - state: absent - -- name: Remove the default http binding - win_iis_webbinding: - name: Default Web Site - port: 80 - ip: '*' - state: absent - -- name: Add a HTTPS binding - win_iis_webbinding: - name: Default Web Site - protocol: https - port: 443 - ip: 127.0.0.1 - certificate_hash: B0D0FA8408FC67B230338FCA584D03792DA73F4C - state: present - -- name: Add a HTTPS binding with host header and SNI enabled - win_iis_webbinding: - name: Default Web Site - protocol: https - port: 443 - host_header: test.com - ssl_flags: 1 - certificate_hash: D1A3AF8988FD32D1A3AF8988FD323792DA73F4C - state: present -''' - -RETURN = r''' -website_state: - description: - - The state of the website being targetted - - Can be helpful in case you accidentally cause a binding collision - which can result in the targetted site being stopped - returned: always - type: str - sample: "Started" - version_added: "2.5" -operation_type: - description: - - The type of operation performed - - Can be removed, updated, matched, or added - returned: on success - type: str - sample: "removed" - version_added: "2.5" -binding_info: - description: - - Information on the binding being manipulated - returned: on success - type: dict - sample: |- - "binding_info": { - "bindingInformation": "127.0.0.1:443:", - "certificateHash": "FF3910CE089397F1B5A77EB7BAFDD8F44CDE77DD", - "certificateStoreName": "MY", - "hostheader": "", - "ip": "127.0.0.1", - "port": 443, - "protocol": "https", - "sslFlags": "not supported" - } - version_added: "2.5" -''' diff --git a/lib/ansible/modules/windows/win_iis_website.ps1 b/lib/ansible/modules/windows/win_iis_website.ps1 deleted file mode 100644 index e7b6cab8bf6..00000000000 --- a/lib/ansible/modules/windows/win_iis_website.ps1 +++ /dev/null @@ -1,180 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Henrik Wallström -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" - -$params = Parse-Args $args -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$application_pool = Get-AnsibleParam -obj $params -name "application_pool" -type "str" -$physical_path = Get-AnsibleParam -obj $params -name "physical_path" -type "str" -$site_id = Get-AnsibleParam -obj $params -name "site_id" -type "str" -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -validateset "absent","restarted","started","stopped" - -# Binding Parameters -$bind_port = Get-AnsibleParam -obj $params -name "port" -type "int" -$bind_ip = Get-AnsibleParam -obj $params -name "ip" -type "str" -$bind_hostname = Get-AnsibleParam -obj $params -name "hostname" -type "str" - -# Custom site Parameters from string where properties -# are separated by a pipe and property name/values by colon. -# Ex. "foo:1|bar:2" -$parameters = Get-AnsibleParam -obj $params -name "parameters" -type "str" -if($null -ne $parameters) { - $parameters = @($parameters -split '\|' | ForEach-Object { - return ,($_ -split "\:", 2); - }) -} - - -# Ensure WebAdministration module is loaded -if ($null -eq (Get-Module "WebAdministration" -ErrorAction SilentlyContinue)) { - Import-Module WebAdministration -} - -# Result -$result = @{ - site = @{} - changed = $false -} - -# Site info -$site = Get-Website | Where-Object { $_.Name -eq $name } - -Try { - # Add site - If(($state -ne 'absent') -and (-not $site)) { - If (-not $physical_path) { - Fail-Json -obj $result -message "missing required arguments: physical_path" - } - ElseIf (-not (Test-Path $physical_path)) { - Fail-Json -obj $result -message "specified folder must already exist: physical_path" - } - - $site_parameters = @{ - Name = $name - PhysicalPath = $physical_path - } - - If ($application_pool) { - $site_parameters.ApplicationPool = $application_pool - } - - If ($site_id) { - $site_parameters.ID = $site_id - } - - If ($bind_port) { - $site_parameters.Port = $bind_port - } - - If ($bind_ip) { - $site_parameters.IPAddress = $bind_ip - } - - If ($bind_hostname) { - $site_parameters.HostHeader = $bind_hostname - } - - # Fix for error "New-Item : Index was outside the bounds of the array." - # This is a bug in the New-WebSite commandlet. Apparently there must be at least one site configured in IIS otherwise New-WebSite crashes. - # For more details, see http://stackoverflow.com/questions/3573889/ps-c-new-website-blah-throws-index-was-outside-the-bounds-of-the-array - $sites_list = get-childitem -Path IIS:\sites - if ($null -eq $sites_list) { - if ($site_id) { - $site_parameters.ID = $site_id - } else { - $site_parameters.ID = 1 - } - } - - $site = New-Website @site_parameters -Force - $result.changed = $true - } - - # Remove site - If ($state -eq 'absent' -and $site) { - $site = Remove-Website -Name $name - $result.changed = $true - } - - $site = Get-Website | Where-Object { $_.Name -eq $name } - If($site) { - # Change Physical Path if needed - if($physical_path) { - If (-not (Test-Path $physical_path)) { - Fail-Json -obj $result -message "specified folder must already exist: physical_path" - } - - $folder = Get-Item $physical_path - If($folder.FullName -ne $site.PhysicalPath) { - Set-ItemProperty "IIS:\Sites\$($site.Name)" -name physicalPath -value $folder.FullName - $result.changed = $true - } - } - - # Change Application Pool if needed - if($application_pool) { - If($application_pool -ne $site.applicationPool) { - Set-ItemProperty "IIS:\Sites\$($site.Name)" -name applicationPool -value $application_pool - $result.changed = $true - } - } - - # Set properties - if($parameters) { - $parameters | ForEach-Object { - $property_value = Get-ItemProperty "IIS:\Sites\$($site.Name)" $_[0] - - switch ($property_value.GetType().Name) - { - "ConfigurationAttribute" { $parameter_value = $property_value.value } - "String" { $parameter_value = $property_value } - } - - if((-not $parameter_value) -or ($parameter_value) -ne $_[1]) { - Set-ItemProperty -LiteralPath "IIS:\Sites\$($site.Name)" $_[0] $_[1] - $result.changed = $true - } - } - } - - # Set run state - if ((($state -eq 'stopped') -or ($state -eq 'restarted')) -and ($site.State -eq 'Started')) - { - Stop-Website -Name $name -ErrorAction Stop - $result.changed = $true - } - if ((($state -eq 'started') -and ($site.State -eq 'Stopped')) -or ($state -eq 'restarted')) - { - Start-Website -Name $name -ErrorAction Stop - $result.changed = $true - } - } -} -Catch -{ - Fail-Json -obj $result -message $_.Exception.Message -} - -if ($state -ne 'absent') -{ - $site = Get-Website | Where-Object { $_.Name -eq $name } -} - -if ($site) -{ - $result.site = @{ - Name = $site.Name - ID = $site.ID - State = $site.State - PhysicalPath = $site.PhysicalPath - ApplicationPool = $site.applicationPool - Bindings = @($site.Bindings.Collection | ForEach-Object { $_.BindingInformation }) - } -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_iis_website.py b/lib/ansible/modules/windows/win_iis_website.py deleted file mode 100644 index c059b4171c8..00000000000 --- a/lib/ansible/modules/windows/win_iis_website.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Henrik Wallström -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_iis_website -version_added: "2.0" -short_description: Configures a IIS Web site -description: - - Creates, Removes and configures a IIS Web site. -options: - name: - description: - - Names of web site. - type: str - required: yes - site_id: - description: - - Explicitly set the IIS numeric ID for a site. - - Note that this value cannot be changed after the website has been created. - type: str - version_added: "2.1" - state: - description: - - State of the web site - type: str - choices: [ absent, started, stopped, restarted ] - physical_path: - description: - - The physical path on the remote host to use for the new site. - - The specified folder must already exist. - type: str - application_pool: - description: - - The application pool in which the new site executes. - type: str - port: - description: - - The port to bind to / use for the new site. - type: int - ip: - description: - - The IP address to bind to / use for the new site. - type: str - hostname: - description: - - The host header to bind to / use for the new site. - type: str - ssl: - description: - - Enables HTTPS binding on the site.. - type: str - parameters: - description: - - Custom site Parameters from string where properties are separated by a pipe and property name/values by colon Ex. "foo:1|bar:2" - type: str -seealso: -- module: win_iis_virtualdirectory -- module: win_iis_webapplication -- module: win_iis_webapppool -- module: win_iis_webbinding -author: -- Henrik Wallström (@henrikwallstrom) -''' - -EXAMPLES = r''' - -# Start a website - -- name: Acme IIS site - win_iis_website: - name: Acme - state: started - port: 80 - ip: 127.0.0.1 - hostname: acme.local - application_pool: acme - physical_path: C:\sites\acme - parameters: logfile.directory:C:\sites\logs - register: website - -# Remove Default Web Site and the standard port 80 binding -- name: Remove Default Web Site - win_iis_website: - name: "Default Web Site" - state: absent - -# Some commandline examples: - -# This return information about an existing host -# $ ansible -i vagrant-inventory -m win_iis_website -a "name='Default Web Site'" window -# host | success >> { -# "changed": false, -# "site": { -# "ApplicationPool": "DefaultAppPool", -# "Bindings": [ -# "*:80:" -# ], -# "ID": 1, -# "Name": "Default Web Site", -# "PhysicalPath": "%SystemDrive%\\inetpub\\wwwroot", -# "State": "Stopped" -# } -# } - -# This stops an existing site. -# $ ansible -i hosts -m win_iis_website -a "name='Default Web Site' state=stopped" host - -# This creates a new site. -# $ ansible -i hosts -m win_iis_website -a "name=acme physical_path=C:\\sites\\acme" host - -# Change logfile. -# $ ansible -i hosts -m win_iis_website -a "name=acme physical_path=C:\\sites\\acme" host -''' diff --git a/lib/ansible/modules/windows/win_inet_proxy.ps1 b/lib/ansible/modules/windows/win_inet_proxy.ps1 deleted file mode 100644 index 3b0420f6486..00000000000 --- a/lib/ansible/modules/windows/win_inet_proxy.ps1 +++ /dev/null @@ -1,495 +0,0 @@ -#!powershell - -# Copyright: (c) 2019, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.AddType - -$spec = @{ - options = @{ - auto_detect = @{ type = "bool"; default = $true } - auto_config_url = @{ type = "str" } - proxy = @{ type = "raw" } - bypass = @{ type = "list" } - connection = @{ type = "str" } - } - required_by = @{ - bypass = @("proxy") - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$auto_detect = $module.Params.auto_detect -$auto_config_url = $module.Params.auto_config_url -$proxy = $module.Params.proxy -$bypass = $module.Params.bypass -$connection = $module.Params.connection - -# Parse the raw value, it should be a Dictionary or String -if ($proxy -is [System.Collections.IDictionary]) { - $valid_keys = [System.Collections.Generic.List`1[String]]@("http", "https", "ftp", "socks") - # Check to make sure we don't have any invalid keys in the dict - $invalid_keys = [System.Collections.Generic.List`1[String]]@() - foreach ($k in $proxy.Keys) { - if ($k -notin $valid_keys) { - $invalid_keys.Add($k) - } - } - - if ($invalid_keys.Count -gt 0) { - $invalid_keys = $invalid_keys | Sort-Object # So our test assertion doesn't fail due to random ordering - $module.FailJson("Invalid keys found in proxy: $($invalid_keys -join ', '). Valid keys are $($valid_keys -join ', ').") - } - - # Build the proxy string in the form 'protocol=host;', the order of valid_keys is also important - $proxy_list = [System.Collections.Generic.List`1[String]]@() - foreach ($k in $valid_keys) { - if ($proxy.ContainsKey($k)) { - $proxy_list.Add("$k=$($proxy.$k)") - } - } - $proxy = $proxy_list -join ";" -} elseif ($null -ne $proxy) { - $proxy = $proxy.ToString() -} - -if ($bypass) { - if ([System.String]::IsNullOrEmpty($proxy)) { - $module.FailJson("missing parameter(s) required by ''bypass'': proxy") - } - $bypass = $bypass -join ';' -} - -$win_inet_invoke = @' -using Microsoft.Win32.SafeHandles; -using System; -using System.Collections.Generic; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; - -namespace Ansible.WinINetProxy -{ - internal class NativeHelpers - { - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public class INTERNET_PER_CONN_OPTION_LISTW : IDisposable - { - public UInt32 dwSize; - public IntPtr pszConnection; - public UInt32 dwOptionCount; - public UInt32 dwOptionError; - public IntPtr pOptions; - - public INTERNET_PER_CONN_OPTION_LISTW() - { - dwSize = (UInt32)Marshal.SizeOf(this); - } - - public void Dispose() - { - if (pszConnection != IntPtr.Zero) - Marshal.FreeHGlobal(pszConnection); - if (pOptions != IntPtr.Zero) - Marshal.FreeHGlobal(pOptions); - GC.SuppressFinalize(this); - } - ~INTERNET_PER_CONN_OPTION_LISTW() { this.Dispose(); } - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public class INTERNET_PER_CONN_OPTIONW : IDisposable - { - public INTERNET_PER_CONN_OPTION dwOption; - public ValueUnion Value; - - [StructLayout(LayoutKind.Explicit)] - public class ValueUnion - { - [FieldOffset(0)] - public UInt32 dwValue; - - [FieldOffset(0)] - public IntPtr pszValue; - - [FieldOffset(0)] - public System.Runtime.InteropServices.ComTypes.FILETIME ftValue; - } - - public void Dispose() - { - // We can't just check if Value.pszValue is not IntPtr.Zero as the union means it could be set even - // when the value is a UInt32 or FILETIME. We check against a known string option type and only free - // the value in those cases. - List stringOptions = new List - { - { INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_AUTOCONFIG_URL }, - { INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_PROXY_BYPASS }, - { INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_PROXY_SERVER } - }; - if (Value != null && Value.pszValue != IntPtr.Zero && stringOptions.Contains(dwOption)) - Marshal.FreeHGlobal(Value.pszValue); - GC.SuppressFinalize(this); - } - ~INTERNET_PER_CONN_OPTIONW() { this.Dispose(); } - } - - public enum INTERNET_OPTION : uint - { - INTERNET_OPTION_PER_CONNECTION_OPTION = 75, - INTERNET_OPTION_PROXY_SETTINGS_CHANGED = 95, - } - - public enum INTERNET_PER_CONN_OPTION : uint - { - INTERNET_PER_CONN_FLAGS = 1, - INTERNET_PER_CONN_PROXY_SERVER = 2, - INTERNET_PER_CONN_PROXY_BYPASS = 3, - INTERNET_PER_CONN_AUTOCONFIG_URL = 4, - INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5, - INTERNET_PER_CONN_FLAGS_UI = 10, // IE8+ - Included with Windows 7 and Server 2008 R2 - } - - [Flags] - public enum PER_CONN_FLAGS : uint - { - PROXY_TYPE_DIRECT = 0x00000001, - PROXY_TYPE_PROXY = 0x00000002, - PROXY_TYPE_AUTO_PROXY_URL = 0x00000004, - PROXY_TYPE_AUTO_DETECT = 0x00000008, - } - } - - internal class NativeMethods - { - [DllImport("Wininet.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool InternetQueryOptionW( - IntPtr hInternet, - NativeHelpers.INTERNET_OPTION dwOption, - SafeMemoryBuffer lpBuffer, - ref UInt32 lpdwBufferLength); - - [DllImport("Wininet.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool InternetSetOptionW( - IntPtr hInternet, - NativeHelpers.INTERNET_OPTION dwOption, - SafeMemoryBuffer lpBuffer, - UInt32 dwBufferLength); - - [DllImport("Rasapi32.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 RasValidateEntryNameW( - string lpszPhonebook, - string lpszEntry); - } - - internal class SafeMemoryBuffer : SafeHandleZeroOrMinusOneIsInvalid - { - public SafeMemoryBuffer() : base(true) { } - public SafeMemoryBuffer(int cb) : base(true) - { - base.SetHandle(Marshal.AllocHGlobal(cb)); - } - public SafeMemoryBuffer(IntPtr handle) : base(true) - { - base.SetHandle(handle); - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected override bool ReleaseHandle() - { - Marshal.FreeHGlobal(handle); - return true; - } - } - - public class Win32Exception : System.ComponentModel.Win32Exception - { - private string _msg; - - public Win32Exception(string message) : this(Marshal.GetLastWin32Error(), message) { } - public Win32Exception(int errorCode, string message) : base(errorCode) - { - _msg = String.Format("{0} ({1}, Win32ErrorCode {2})", message, base.Message, errorCode); - } - - public override string Message { get { return _msg; } } - public static explicit operator Win32Exception(string message) { return new Win32Exception(message); } - } - - public class WinINetProxy - { - private string Connection; - - public string AutoConfigUrl; - public bool AutoDetect; - public string Proxy; - public string ProxyBypass; - - public WinINetProxy(string connection) - { - Connection = connection; - Refresh(); - } - - public static bool IsValidConnection(string name) - { - // RasValidateEntryName is used to verify is a name can be a valid phonebook entry. It returns 0 if no - // entry exists and 183 if it already exists. We just need to check if it returns 183 to verify the - // connection name. - return NativeMethods.RasValidateEntryNameW(null, name) == 183; - } - - public void Refresh() - { - using (var connFlags = CreateConnOption(NativeHelpers.INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_FLAGS_UI)) - using (var autoConfigUrl = CreateConnOption(NativeHelpers.INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_AUTOCONFIG_URL)) - using (var server = CreateConnOption(NativeHelpers.INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_PROXY_SERVER)) - using (var bypass = CreateConnOption(NativeHelpers.INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_PROXY_BYPASS)) - { - NativeHelpers.INTERNET_PER_CONN_OPTIONW[] options = new NativeHelpers.INTERNET_PER_CONN_OPTIONW[] - { - connFlags, autoConfigUrl, server, bypass - }; - - try - { - QueryOption(options, Connection); - } - catch (Win32Exception e) - { - if (e.NativeErrorCode == 87) // ERROR_INVALID_PARAMETER - { - // INTERNET_PER_CONN_FLAGS_UI only works for IE8+, try the fallback in case we are still working - // with an ancient version. - connFlags.dwOption = NativeHelpers.INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_FLAGS; - QueryOption(options, Connection); - } - else - throw; - } - - NativeHelpers.PER_CONN_FLAGS flags = (NativeHelpers.PER_CONN_FLAGS)connFlags.Value.dwValue; - - AutoConfigUrl = flags.HasFlag(NativeHelpers.PER_CONN_FLAGS.PROXY_TYPE_AUTO_PROXY_URL) - ? Marshal.PtrToStringUni(autoConfigUrl.Value.pszValue) : null; - AutoDetect = flags.HasFlag(NativeHelpers.PER_CONN_FLAGS.PROXY_TYPE_AUTO_DETECT); - if (flags.HasFlag(NativeHelpers.PER_CONN_FLAGS.PROXY_TYPE_PROXY)) - { - Proxy = Marshal.PtrToStringUni(server.Value.pszValue); - ProxyBypass = Marshal.PtrToStringUni(bypass.Value.pszValue); - } - else - { - Proxy = null; - ProxyBypass = null; - } - } - } - - public void Set() - { - using (var connFlags = CreateConnOption(NativeHelpers.INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_FLAGS_UI)) - using (var autoConfigUrl = CreateConnOption(NativeHelpers.INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_AUTOCONFIG_URL)) - using (var server = CreateConnOption(NativeHelpers.INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_PROXY_SERVER)) - using (var bypass = CreateConnOption(NativeHelpers.INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_PROXY_BYPASS)) - { - List options = new List(); - - // PROXY_TYPE_DIRECT seems to always be set, need to verify - NativeHelpers.PER_CONN_FLAGS flags = NativeHelpers.PER_CONN_FLAGS.PROXY_TYPE_DIRECT; - if (AutoDetect) - flags |= NativeHelpers.PER_CONN_FLAGS.PROXY_TYPE_AUTO_DETECT; - - if (!String.IsNullOrEmpty(AutoConfigUrl)) - { - flags |= NativeHelpers.PER_CONN_FLAGS.PROXY_TYPE_AUTO_PROXY_URL; - autoConfigUrl.Value.pszValue = Marshal.StringToHGlobalUni(AutoConfigUrl); - } - options.Add(autoConfigUrl); - - if (!String.IsNullOrEmpty(Proxy)) - { - flags |= NativeHelpers.PER_CONN_FLAGS.PROXY_TYPE_PROXY; - server.Value.pszValue = Marshal.StringToHGlobalUni(Proxy); - } - options.Add(server); - - if (!String.IsNullOrEmpty(ProxyBypass)) - bypass.Value.pszValue = Marshal.StringToHGlobalUni(ProxyBypass); - options.Add(bypass); - - connFlags.Value.dwValue = (UInt32)flags; - options.Add(connFlags); - - SetOption(options.ToArray(), Connection); - - // Tell IE that the proxy settings have been changed. - if (!NativeMethods.InternetSetOptionW( - IntPtr.Zero, - NativeHelpers.INTERNET_OPTION.INTERNET_OPTION_PROXY_SETTINGS_CHANGED, - new SafeMemoryBuffer(IntPtr.Zero), - 0)) - { - throw new Win32Exception("InternetSetOptionW(INTERNET_OPTION_PROXY_SETTINGS_CHANGED) failed"); - } - } - } - - internal static NativeHelpers.INTERNET_PER_CONN_OPTIONW CreateConnOption(NativeHelpers.INTERNET_PER_CONN_OPTION option) - { - return new NativeHelpers.INTERNET_PER_CONN_OPTIONW - { - dwOption = option, - Value = new NativeHelpers.INTERNET_PER_CONN_OPTIONW.ValueUnion(), - }; - } - - internal static void QueryOption(NativeHelpers.INTERNET_PER_CONN_OPTIONW[] options, string connection = null) - { - using (NativeHelpers.INTERNET_PER_CONN_OPTION_LISTW optionList = new NativeHelpers.INTERNET_PER_CONN_OPTION_LISTW()) - using (SafeMemoryBuffer optionListPtr = MarshalOptionList(optionList, options, connection)) - { - UInt32 bufferSize = optionList.dwSize; - if (!NativeMethods.InternetQueryOptionW( - IntPtr.Zero, - NativeHelpers.INTERNET_OPTION.INTERNET_OPTION_PER_CONNECTION_OPTION, - optionListPtr, - ref bufferSize)) - { - throw new Win32Exception("InternetQueryOptionW(INTERNET_OPTION_PER_CONNECTION_OPTION) failed"); - } - - for (int i = 0; i < options.Length; i++) - { - IntPtr opt = IntPtr.Add(optionList.pOptions, i * Marshal.SizeOf(typeof(NativeHelpers.INTERNET_PER_CONN_OPTIONW))); - NativeHelpers.INTERNET_PER_CONN_OPTIONW option = (NativeHelpers.INTERNET_PER_CONN_OPTIONW)Marshal.PtrToStructure(opt, - typeof(NativeHelpers.INTERNET_PER_CONN_OPTIONW)); - options[i].Value = option.Value; - option.Value = null; // Stops the GC from freeing the same memory twice - } - } - } - - internal static void SetOption(NativeHelpers.INTERNET_PER_CONN_OPTIONW[] options, string connection = null) - { - using (NativeHelpers.INTERNET_PER_CONN_OPTION_LISTW optionList = new NativeHelpers.INTERNET_PER_CONN_OPTION_LISTW()) - using (SafeMemoryBuffer optionListPtr = MarshalOptionList(optionList, options, connection)) - { - if (!NativeMethods.InternetSetOptionW( - IntPtr.Zero, - NativeHelpers.INTERNET_OPTION.INTERNET_OPTION_PER_CONNECTION_OPTION, - optionListPtr, - optionList.dwSize)) - { - throw new Win32Exception("InternetSetOptionW(INTERNET_OPTION_PER_CONNECTION_OPTION) failed"); - } - } - } - - internal static SafeMemoryBuffer MarshalOptionList(NativeHelpers.INTERNET_PER_CONN_OPTION_LISTW optionList, - NativeHelpers.INTERNET_PER_CONN_OPTIONW[] options, string connection) - { - optionList.pszConnection = Marshal.StringToHGlobalUni(connection); - optionList.dwOptionCount = (UInt32)options.Length; - - int optionSize = Marshal.SizeOf(typeof(NativeHelpers.INTERNET_PER_CONN_OPTIONW)); - optionList.pOptions = Marshal.AllocHGlobal(optionSize * options.Length); - for (int i = 0; i < options.Length; i++) - { - IntPtr option = IntPtr.Add(optionList.pOptions, i * optionSize); - Marshal.StructureToPtr(options[i], option, false); - } - - SafeMemoryBuffer optionListPtr = new SafeMemoryBuffer((int)optionList.dwSize); - Marshal.StructureToPtr(optionList, optionListPtr.DangerousGetHandle(), false); - return optionListPtr; - } - } -} -'@ -Add-CSharpType -References $win_inet_invoke -AnsibleModule $module - -# We need to validate the connection because WinINet will just silently continue even if the connection does not -# already exist. -if ($null -ne $connection -and -not [Ansible.WinINetProxy.WinINetProxy]::IsValidConnection($connection)) { - $module.FailJson("The connection '$connection' does not exist.") -} - -$actual_proxy = New-Object -TypeName Ansible.WinINetProxy.WinINetProxy -ArgumentList @(,$connection) -$module.Diff.before = @{ - auto_config_url = $actual_proxy.AutoConfigUrl - auto_detect = $actual_proxy.AutoDetect - bypass = $actual_proxy.ProxyBypass - server = $actual_proxy.Proxy -} - -# Make sure an empty string is converted to $null for easier comparisons -if ([String]::IsNullOrEmpty($auto_config_url)) { - $auto_config_url = $null -} -if ([String]::IsNullOrEmpty($proxy)) { - $proxy = $null -} -if ([String]::IsNullOrEmpty($bypass)) { - $bypass = $null -} - -# Record the original values in case we need to revert on a failure -$previous_auto_config_url = $actual_proxy.AutoConfigUrl -$previous_auto_detect = $actual_proxy.AutoDetect -$previous_proxy = $actual_proxy.Proxy -$previous_bypass = $actual_proxy.ProxyBypass - -$changed = $false -if ($auto_config_url -ne $previous_auto_config_url) { - $actual_proxy.AutoConfigUrl = $auto_config_url - $changed = $true -} - -if ($auto_detect -ne $previous_auto_detect) { - $actual_proxy.AutoDetect = $auto_detect - $changed = $true -} - -if ($proxy -ne $previous_proxy) { - $actual_proxy.Proxy = $proxy - $changed = $true -} - -if ($bypass -ne $previous_bypass) { - $actual_proxy.ProxyBypass = $bypass - $changed = $true -} - -if ($changed -and -not $module.CheckMode) { - $actual_proxy.Set() - - # Validate that the change was made correctly and revert if it wasn't. THe Set() method won't fail on invalid - # values so we need to check again to make sure all was good - $actual_proxy.Refresh() - if ($actual_proxy.AutoConfigUrl -ne $auto_config_url -or - $actual_proxy.AutoDetect -ne $auto_detect -or - $actual_proxy.Proxy -ne $proxy -or - $actual_proxy.ProxyBypass -ne $bypass) { - - $actual_proxy.AutoConfigUrl = $previous_auto_config_url - $actual_proxy.AutoDetect = $previous_auto_detect - $actual_proxy.Proxy = $previous_proxy - $actual_proxy.ProxyBypass = $previous_bypass - $actual_proxy.Set() - - $module.FailJson("Unknown error when trying to set auto_config_url '$auto_config_url', proxy '$proxy', or bypass '$bypass'") - } -} -$module.Result.changed = $changed - -$module.Diff.after = @{ - auto_config_url = $auto_config_url - auto_detect = $auto_detect - bypass = $bypass - proxy = $proxy -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_inet_proxy.py b/lib/ansible/modules/windows/win_inet_proxy.py deleted file mode 100644 index 8a3449f3992..00000000000 --- a/lib/ansible/modules/windows/win_inet_proxy.py +++ /dev/null @@ -1,173 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2019, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_inet_proxy -version_added: '2.8' -short_description: Manages proxy settings for WinINet and Internet Explorer -description: -- Used to set or remove proxy settings for Windows INet which includes Internet - Explorer. -- WinINet is a framework used by interactive applications to submit web - requests through. -- The proxy settings can also be used by other applications like Firefox, - Chrome, and others but there is no definitive list. -options: - auto_detect: - description: - - Whether to configure WinINet to automatically detect proxy settings - through Web Proxy Auto-Detection C(WPAD). - - This corresponds to the checkbox I(Automatically detect settings) in the - connection settings window. - default: yes - type: bool - auto_config_url: - description: - - The URL of a proxy configuration script. - - Proxy configuration scripts are typically JavaScript files with the - C(.pac) extension that implement the C(FindProxyForURL(url, host) - function. - - Omit, set to null or an empty string to remove the auto config URL. - - This corresponds to the checkbox I(Use automatic configuration script) in - the connection settings window. - type: str - bypass: - description: - - A list of hosts that will bypass the set proxy when being accessed. - - Use C() to match hostnames that are not fully qualified domain - names. This is useful when needing to connect to intranet sites using - just the hostname. If defined, this should be the last entry in the - bypass list. - - Use C(<-loopback>) to stop automatically bypassing the proxy when - connecting through any loopback address like C(127.0.0.1), C(localhost), - or the local hostname. - - Omit, set to null or an empty string/list to remove the bypass list. - - If this is set then I(proxy) must also be set. - type: list - connection: - description: - - The name of the IE connection to set the proxy settings for. - - These are the connections under the I(Dial-up and Virtual Private Network) - header in the IE settings. - - When omitted, the default LAN connection is used. - type: str - proxy: - description: - - A string or dict that specifies the proxy to be set. - - If setting a string, should be in the form C(hostname), C(hostname:port), - or C(protocol=hostname:port). - - If the port is undefined, the default port for the protocol in use is - used. - - If setting a dict, the keys should be the protocol and the values should - be the hostname and/or port for that protocol. - - Valid protocols are C(http), C(https), C(ftp), and C(socks). - - Omit, set to null or an empty string to remove the proxy settings. -notes: -- This is not the same as the proxy settings set in WinHTTP through the - C(netsh) command. Use the M(win_http_proxy) module to manage that instead. -- These settings are by default set per user and not system wide. A registry - property must be set independently from this module if you wish to apply the - proxy for all users. See examples for more detail. -- If per user proxy settings are desired, use I(become) to become any local - user on the host. No password is needed to be set for this to work. -- If the proxy requires authentication, set the credentials using the - M(win_credential) module. This requires I(become) to be used so the - credential store can be accessed. -seealso: -- module: win_http_proxy -- module: win_credential -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -# This should be set before running the win_inet_proxy module -- name: Configure IE proxy settings to apply to all users - win_regedit: - path: HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings - name: ProxySettingsPerUser - data: 0 - type: dword - state: present - -# This should be set before running the win_inet_proxy module -- name: Configure IE proxy settings to apply per user - win_regedit: - path: HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings - name: ProxySettingsPerUser - data: 1 - type: dword - state: present - -- name: Configure IE proxy to use auto detected settings without an explicit proxy - win_inet_proxy: - auto_detect: yes - -- name: Configure IE proxy to use auto detected settings with a configuration script - win_inet_proxy: - auto_detect: yes - auto_config_url: http://proxy.ansible.com/proxy.pac - -- name: Configure IE to use explicit proxy host - win_inet_proxy: - auto_detect: yes - proxy: ansible.proxy - -- name: Configure IE to use explicit proxy host with port and without auto detection - win_inet_proxy: - auto_detect: no - proxy: ansible.proxy:8080 - -- name: Configure IE to use a specific proxy per protocol - win_inet_proxy: - proxy: - http: ansible.proxy:8080 - https: ansible.proxy:8443 - -- name: Configure IE to use a specific proxy per protocol using a string - win_inet_proxy: - proxy: http=ansible.proxy:8080;https=ansible.proxy:8443 - -- name: Set a proxy with a bypass list - win_inet_proxy: - proxy: ansible.proxy - bypass: - - server1 - - server2 - - <-loopback> - - - -- name: Remove any explicit proxies that are set - win_inet_proxy: - proxy: '' - bypass: '' - -# This should be done after setting the IE proxy with win_inet_proxy -- name: Import IE proxy configuration to WinHTTP - win_http_proxy: - source: ie - -# Explicit credentials can only be set per user and require become to work -- name: Set credential to use for proxy auth - win_credential: - name: ansible.proxy # The name should be the FQDN of the proxy host - type: generic_password - username: proxyuser - secret: proxypass - state: present - become: yes - become_user: '{{ ansible_user }}' - become_method: runas -''' - -RETURN = r''' -# -''' diff --git a/lib/ansible/modules/windows/win_initialize_disk.ps1 b/lib/ansible/modules/windows/win_initialize_disk.ps1 deleted file mode 100644 index 556c74b3725..00000000000 --- a/lib/ansible/modules/windows/win_initialize_disk.ps1 +++ /dev/null @@ -1,151 +0,0 @@ -#!powershell - -# Copyright: (c) 2019, Brant Evans -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#AnsibleRequires -OSVersion 6.2 - -Set-StrictMode -Version 2 - -$spec = @{ - options = @{ - disk_number = @{ type = "int" } - uniqueid = @{ type = "str" } - path = @{ type = "str" } - style = @{ type = "str"; choices = "gpt", "mbr"; default = "gpt" } - online = @{ type = "bool"; default = $true } - force = @{ type = "bool"; default = $false } - } - mutually_exclusive = @( - ,@('disk_number', 'uniqueid', 'path') - ) - required_one_of = @( - ,@('disk_number', 'uniqueid', 'path') - ) - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$disk_number = $module.Params.disk_number -$uniqueid = $module.Params.uniqueid -$path = $module.Params.path -$partition_style = $module.Params.style -$bring_online = $module.Params.online -$force_init = $module.Params.force - -function Get-AnsibleDisk { - param( - $DiskNumber, - $UniqueId, - $Path - ) - - if ($null -ne $DiskNumber) { - try { - $disk = Get-Disk -Number $DiskNumber - } catch { - $module.FailJson("There was an error retrieving the disk using disk_number $($DiskNumber): $($_.Exception.Message)") - } - } elseif ($null -ne $UniqueId) { - try { - $disk = Get-Disk -UniqueId $UniqueId - } catch { - $module.FailJson("There was an error retrieving the disk using id $($UniqueId): $($_.Exception.Message)") - } - } elseif ($null -ne $Path) { - try { - $disk = Get-Disk -Path $Path - } catch { - $module.FailJson("There was an error retrieving the disk using path $($Path): $($_.Exception.Message)") - } - } else { - $module.FailJson("Unable to retrieve disk: disk_number, id, or path was not specified") - } - - return $disk -} - -function Initialize-AnsibleDisk { - param( - $AnsibleDisk, - $PartitionStyle - ) - - if ($AnsibleDisk.IsReadOnly) { - $module.FailJson("Unable to initialize disk as it is read-only") - } - - $parameters = @{ - Number = $AnsibleDisk.Number - PartitionStyle = $PartitionStyle - } - - if (-Not $module.CheckMode) { - Initialize-Disk @parameters -Confirm:$false - } - - $module.Result.changed = $true -} - -function Clear-AnsibleDisk { - param( - $AnsibleDisk - ) - - $parameters = @{ - Number = $AnsibleDisk.Number - } - - if (-Not $module.CheckMode) { - Clear-Disk @parameters -RemoveData -RemoveOEM -Confirm:$false - } -} - -function Set-AnsibleDisk { - param( - $AnsibleDisk, - $BringOnline - ) - - $refresh_disk_status = $false - - if ($BringOnline) { - if (-Not $module.CheckMode) { - if ($AnsibleDisk.IsOffline) { - Set-Disk -Number $AnsibleDisk.Number -IsOffline:$false - $refresh_disk_status = $true - } - - if ($AnsibleDisk.IsReadOnly) { - Set-Disk -Number $AnsibleDisk.Number -IsReadOnly:$false - $refresh_disk_status = $true - } - } - } - - if ($refresh_disk_status) { - $AnsibleDisk = Get-AnsibleDisk -DiskNumber $AnsibleDisk.Number - } - - return $AnsibleDisk -} - -$ansible_disk = Get-AnsibleDisk -DiskNumber $disk_number -UniqueId $uniqueid -Path $path -$ansible_part_style = $ansible_disk.PartitionStyle - -if ("RAW" -eq $ansible_part_style) { - $ansible_disk = Set-AnsibleDisk -AnsibleDisk $ansible_disk -BringOnline $bring_online - Initialize-AnsibleDisk -AnsibleDisk $ansible_disk -PartitionStyle $partition_style -} else { - if (($ansible_part_style -ne $partition_style.ToUpper()) -And -Not $force_init) { - $module.FailJson("Force initialization must be specified since the target partition style: $($partition_style.ToLower()) is different from the current partition style: $($ansible_part_style.ToLower())") - } elseif ($force_init) { - $ansible_disk = Set-AnsibleDisk -AnsibleDisk $ansible_disk -BringOnline $bring_online - Clear-AnsibleDisk -AnsibleDisk $ansible_disk - Initialize-AnsibleDisk -AnsibleDisk $ansible_disk -PartitionStyle $partition_style - } -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_initialize_disk.py b/lib/ansible/modules/windows/win_initialize_disk.py deleted file mode 100644 index 8328bb0294a..00000000000 --- a/lib/ansible/modules/windows/win_initialize_disk.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/python - -# Copyright: (c) 2019, Brant Evans -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = { - 'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community' -} - -DOCUMENTATION = ''' ---- -module: win_initialize_disk - -short_description: Initializes disks on Windows Server - -version_added: "2.10" - -description: - - "The M(win_initialize_disk) module initializes disks" - -options: - disk_number: - description: - - Used to specify the disk number of the disk to be initialized. - type: int - uniqueid: - description: - - Used to specify the uniqueid of the disk to be initialized. - type: str - path: - description: - - Used to specify the path to the disk to be initialized. - type: str - style: - description: - - The partition style to use for the disk. Valid options are mbr or gpt. - type: str - choices: [ gpt, mbr ] - default: gpt - online: - description: - - If the disk is offline and/or readonly update the disk to be online and not readonly. - type: bool - default: true - force: - description: - - Specify if initializing should be forced for disks that are already initialized. - type: bool - -notes: - - One of three parameters (I(disk_number), I(uniqueid), and I(path)) are mandatory to identify the target disk, but - more than one cannot be specified at the same time. - - A minimum Operating System Version of Server 2012 or Windows 8 is required to use this module. - - This module is idempotent if I(force) is not specified. - -seealso: - - module: win_disk_facts - - module: win_partition - - module: win_format - -author: - - Brant Evans (@branic) -''' - -EXAMPLES = ''' -- name: Initialize a disk - win_initialize_disk: - disk_number: 1 - -- name: Initialize a disk with an MBR partition style - win_initialize_disk: - disk_number: 1 - style: mbr - -- name: Forcefully initiallize a disk - win_initialize_disk: - disk_number: 2 - force: yes -''' - -RETURN = ''' -# -''' diff --git a/lib/ansible/modules/windows/win_lineinfile.ps1 b/lib/ansible/modules/windows/win_lineinfile.ps1 deleted file mode 100644 index 38dd8b8bc09..00000000000 --- a/lib/ansible/modules/windows/win_lineinfile.ps1 +++ /dev/null @@ -1,450 +0,0 @@ -#!powershell - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.Backup - -function WriteLines($outlines, $path, $linesep, $encodingobj, $validate, $check_mode) { - Try { - $temppath = [System.IO.Path]::GetTempFileName(); - } - Catch { - Fail-Json @{} "Cannot create temporary file! ($($_.Exception.Message))"; - } - $joined = $outlines -join $linesep; - [System.IO.File]::WriteAllText($temppath, $joined, $encodingobj); - - If ($validate) { - - If (-not ($validate -like "*%s*")) { - Fail-Json @{} "validate must contain %s: $validate"; - } - - $validate = $validate.Replace("%s", $temppath); - - $parts = [System.Collections.ArrayList] $validate.Split(" "); - $cmdname = $parts[0]; - - $cmdargs = $validate.Substring($cmdname.Length + 1); - - $process = [Diagnostics.Process]::Start($cmdname, $cmdargs); - $process.WaitForExit(); - - If ($process.ExitCode -ne 0) { - [string] $output = $process.StandardOutput.ReadToEnd(); - [string] $error = $process.StandardError.ReadToEnd(); - Remove-Item $temppath -force; - Fail-Json @{} "failed to validate $cmdname $cmdargs with error: $output $error"; - } - - } - - # Commit changes to the path - $cleanpath = $path.Replace("/", "\"); - Try { - Copy-Item -Path $temppath -Destination $cleanpath -Force -WhatIf:$check_mode; - } - Catch { - Fail-Json @{} "Cannot write to: $cleanpath ($($_.Exception.Message))"; - } - - Try { - Remove-Item -Path $temppath -Force -WhatIf:$check_mode; - } - Catch { - Fail-Json @{} "Cannot remove temporary file: $temppath ($($_.Exception.Message))"; - } - - return $joined; - -} - - -# Implement the functionality for state == 'present' -function Present($path, $regex, $line, $insertafter, $insertbefore, $create, $backup, $backrefs, $validate, $encodingobj, $linesep, $check_mode, $diff_support) { - - # Note that we have to clean up the path because ansible wants to treat / and \ as - # interchangeable in windows pathnames, but .NET framework internals do not support that. - $cleanpath = $path.Replace("/", "\"); - - # Check if path exists. If it does not exist, either create it if create == "yes" - # was specified or fail with a reasonable error message. - If (-not (Test-Path -LiteralPath $path)) { - If (-not $create) { - Fail-Json @{} "Path $path does not exist !"; - } - # Create new empty file, using the specified encoding to write correct BOM - [System.IO.File]::WriteAllLines($cleanpath, "", $encodingobj); - } - - # Initialize result information - $result = @{ - backup = ""; - changed = $false; - msg = ""; - } - - # Read the dest file lines using the indicated encoding into a mutable ArrayList. - $before = [System.IO.File]::ReadAllLines($cleanpath, $encodingobj) - If ($null -eq $before) { - $lines = New-Object System.Collections.ArrayList; - } - Else { - $lines = [System.Collections.ArrayList] $before; - } - - if ($diff_support) { - $result.diff = @{ - before = $before -join $linesep; - } - } - - # Compile the regex specified, if provided - $mre = $null; - If ($regex) { - $mre = New-Object Regex $regex, 'Compiled'; - } - - # Compile the regex for insertafter or insertbefore, if provided - $insre = $null; - If ($insertafter -and $insertafter -ne "BOF" -and $insertafter -ne "EOF") { - $insre = New-Object Regex $insertafter, 'Compiled'; - } - ElseIf ($insertbefore -and $insertbefore -ne "BOF") { - $insre = New-Object Regex $insertbefore, 'Compiled'; - } - - # index[0] is the line num where regex has been found - # index[1] is the line num where insertafter/insertbefore has been found - $index = -1, -1; - $lineno = 0; - - # The latest match object and matched line - $matched_line = ""; - - # Iterate through the lines in the file looking for matches - Foreach ($cur_line in $lines) { - If ($regex) { - $m = $mre.Match($cur_line); - $match_found = $m.Success; - If ($match_found) { - $matched_line = $cur_line; - } - } - Else { - $match_found = $line -ceq $cur_line; - } - If ($match_found) { - $index[0] = $lineno; - } - ElseIf ($insre -and $insre.Match($cur_line).Success) { - If ($insertafter) { - $index[1] = $lineno + 1; - } - If ($insertbefore) { - $index[1] = $lineno; - } - } - $lineno = $lineno + 1; - } - - If ($index[0] -ne -1) { - If ($backrefs) { - $new_line = [regex]::Replace($matched_line, $regex, $line); - } - Else { - $new_line = $line; - } - If ($lines[$index[0]] -cne $new_line) { - $lines[$index[0]] = $new_line; - $result.changed = $true; - $result.msg = "line replaced"; - } - } - ElseIf ($backrefs) { - # No matches - no-op - } - ElseIf ($insertbefore -eq "BOF" -or $insertafter -eq "BOF") { - $lines.Insert(0, $line); - $result.changed = $true; - $result.msg = "line added"; - } - ElseIf ($insertafter -eq "EOF" -or $index[1] -eq -1) { - $lines.Add($line) > $null; - $result.changed = $true; - $result.msg = "line added"; - } - Else { - $lines.Insert($index[1], $line); - $result.changed = $true; - $result.msg = "line added"; - } - - # Write changes to the path if changes were made - If ($result.changed) { - - # Write backup file if backup == "yes" - If ($backup) { - $result.backup_file = Backup-File -path $path -WhatIf:$check_mode - # Ensure backward compatibility (deprecate in future) - $result.backup = $result.backup_file - } - - $writelines_params = @{ - outlines = $lines - path = $path - linesep = $linesep - encodingobj = $encodingobj - validate = $validate - check_mode = $check_mode - } - $after = WriteLines @writelines_params; - - if ($diff_support) { - $result.diff.after = $after; - } - } - - $result.encoding = $encodingobj.WebName; - - Exit-Json $result; -} - - -# Implement the functionality for state == 'absent' -function Absent($path, $regex, $line, $backup, $validate, $encodingobj, $linesep, $check_mode, $diff_support) { - - # Check if path exists. If it does not exist, fail with a reasonable error message. - If (-not (Test-Path -LiteralPath $path)) { - Fail-Json @{} "Path $path does not exist !"; - } - - # Initialize result information - $result = @{ - backup = ""; - changed = $false; - msg = ""; - } - - # Read the dest file lines using the indicated encoding into a mutable ArrayList. Note - # that we have to clean up the path because ansible wants to treat / and \ as - # interchangeable in windows pathnames, but .NET framework internals do not support that. - $cleanpath = $path.Replace("/", "\"); - $before = [System.IO.File]::ReadAllLines($cleanpath, $encodingobj); - If ($null -eq $before) { - $lines = New-Object System.Collections.ArrayList; - } - Else { - $lines = [System.Collections.ArrayList] $before; - } - - if ($diff_support) { - $result.diff = @{ - before = $before -join $linesep; - } - } - - # Compile the regex specified, if provided - $cre = $null; - If ($regex) { - $cre = New-Object Regex $regex, 'Compiled'; - } - - $found = New-Object System.Collections.ArrayList; - $left = New-Object System.Collections.ArrayList; - - Foreach ($cur_line in $lines) { - If ($regex) { - $m = $cre.Match($cur_line); - $match_found = $m.Success; - } - Else { - $match_found = $line -ceq $cur_line; - } - If ($match_found) { - $found.Add($cur_line) > $null; - $result.changed = $true; - } - Else { - $left.Add($cur_line) > $null; - } - } - - # Write changes to the path if changes were made - If ($result.changed) { - - # Write backup file if backup == "yes" - If ($backup) { - $result.backup_file = Backup-File -path $path -WhatIf:$check_mode - # Ensure backward compatibility (deprecate in future) - $result.backup = $result.backup_file - } - - $writelines_params = @{ - outlines = $left - path = $path - linesep = $linesep - encodingobj = $encodingobj - validate = $validate - check_mode = $check_mode - } - $after = WriteLines @writelines_params; - - if ($diff_support) { - $result.diff.after = $after; - } - } - - $result.encoding = $encodingobj.WebName; - $result.found = $found.Count; - $result.msg = "$($found.Count) line(s) removed"; - - Exit-Json $result; -} - - -# Parse the parameters file dropped by the Ansible machinery -$params = Parse-Args $args -supports_check_mode $true; -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false; -$diff_support = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false; - -# Initialize defaults for input parameters. -$path = Get-AnsibleParam -obj $params -name "path" -type "path" -failifempty $true -aliases "dest","destfile","name"; -$regex = Get-AnsibleParam -obj $params -name "regex" -type "str" -aliases "regexp"; -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent"; -$line = Get-AnsibleParam -obj $params -name "line" -type "str"; -$backrefs = Get-AnsibleParam -obj $params -name "backrefs" -type "bool" -default $false; -$insertafter = Get-AnsibleParam -obj $params -name "insertafter" -type "str"; -$insertbefore = Get-AnsibleParam -obj $params -name "insertbefore" -type "str"; -$create = Get-AnsibleParam -obj $params -name "create" -type "bool" -default $false; -$backup = Get-AnsibleParam -obj $params -name "backup" -type "bool" -default $false; -$validate = Get-AnsibleParam -obj $params -name "validate" -type "str"; -$encoding = Get-AnsibleParam -obj $params -name "encoding" -type "str" -default "auto"; -$newline = Get-AnsibleParam -obj $params -name "newline" -type "str" -default "windows" -validateset "unix","windows"; - -# Fail if the path is not a file -If (Test-Path -LiteralPath $path -PathType "container") { - Fail-Json @{} "Path $path is a directory"; -} - -# Default to windows line separator - probably most common -$linesep = "`r`n" -If ($newline -eq "unix") { - $linesep = "`n"; -} - -# Figure out the proper encoding to use for reading / writing the target file. - -# The default encoding is UTF-8 without BOM -$encodingobj = [System.Text.UTF8Encoding] $false; - -# If an explicit encoding is specified, use that instead -If ($encoding -ne "auto") { - $encodingobj = [System.Text.Encoding]::GetEncoding($encoding); -} - -# Otherwise see if we can determine the current encoding of the target file. -# If the file doesn't exist yet (create == 'yes') we use the default or -# explicitly specified encoding set above. -ElseIf (Test-Path -LiteralPath $path) { - - # Get a sorted list of encodings with preambles, longest first - $max_preamble_len = 0; - $sortedlist = New-Object System.Collections.SortedList; - Foreach ($encodinginfo in [System.Text.Encoding]::GetEncodings()) { - $encoding = $encodinginfo.GetEncoding(); - $plen = $encoding.GetPreamble().Length; - If ($plen -gt $max_preamble_len) { - $max_preamble_len = $plen; - } - If ($plen -gt 0) { - $sortedlist.Add(-($plen * 1000000 + $encoding.CodePage), $encoding) > $null; - } - } - - # Get the first N bytes from the file, where N is the max preamble length we saw - [Byte[]]$bom = Get-Content -Encoding Byte -ReadCount $max_preamble_len -TotalCount $max_preamble_len -LiteralPath $path; - - # Iterate through the sorted encodings, looking for a full match. - $found = $false; - Foreach ($encoding in $sortedlist.GetValueList()) { - $preamble = $encoding.GetPreamble(); - If ($preamble -and $bom) { - Foreach ($i in 0..($preamble.Length - 1)) { - If ($i -ge $bom.Length) { - break; - } - If ($preamble[$i] -ne $bom[$i]) { - break; - } - ElseIf ($i + 1 -eq $preamble.Length) { - $encodingobj = $encoding; - $found = $true; - } - } - If ($found) { - break; - } - } - } -} - - -# Main dispatch - based on the value of 'state', perform argument validation and -# call the appropriate handler function. -If ($state -eq "present") { - - If ($backrefs -and -not $regex) { - Fail-Json @{} "regexp= is required with backrefs=true"; - } - - If (-not $line) { - Fail-Json @{} "line= is required with state=present"; - } - - If ($insertbefore -and $insertafter) { - Add-Warning $result "Both insertbefore and insertafter parameters found, ignoring `"insertafter=$insertafter`"" - } - - If (-not $insertbefore -and -not $insertafter) { - $insertafter = "EOF"; - } - - $present_params = @{ - path = $path - regex = $regex - line = $line - insertafter = $insertafter - insertbefore = $insertbefore - create = $create - backup = $backup - backrefs = $backrefs - validate = $validate - encodingobj = $encodingobj - linesep = $linesep - check_mode = $check_mode - diff_support = $diff_support - } - Present @present_params; - -} -ElseIf ($state -eq "absent") { - - If (-not $regex -and -not $line) { - Fail-Json @{} "one of line= or regexp= is required with state=absent"; - } - - $absent_params = @{ - path = $path - regex = $regex - line = $line - backup = $backup - validate = $validate - encodingobj = $encodingobj - linesep = $linesep - check_mode = $check_mode - diff_support = $diff_support - } - Absent @absent_params; -} diff --git a/lib/ansible/modules/windows/win_lineinfile.py b/lib/ansible/modules/windows/win_lineinfile.py deleted file mode 100644 index f4fb7f5afa7..00000000000 --- a/lib/ansible/modules/windows/win_lineinfile.py +++ /dev/null @@ -1,180 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_lineinfile -short_description: Ensure a particular line is in a file, or replace an existing line using a back-referenced regular expression -description: - - This module will search a file for a line, and ensure that it is present or absent. - - This is primarily useful when you want to change a single line in a file only. -version_added: "2.0" -options: - path: - description: - - The path of the file to modify. - - Note that the Windows path delimiter C(\) must be escaped as C(\\) when the line is double quoted. - - Before Ansible 2.3 this option was only usable as I(dest), I(destfile) and I(name). - type: path - required: yes - aliases: [ dest, destfile, name ] - backup: - description: - - Determine whether a backup should be created. - - When set to C(yes), create a backup file including the timestamp information - so you can get the original file back if you somehow clobbered it incorrectly. - type: bool - default: no - regex: - description: - - The regular expression to look for in every line of the file. For C(state=present), the pattern to replace if found; only the last line found - will be replaced. For C(state=absent), the pattern of the line to remove. Uses .NET compatible regular expressions; - see U(https://msdn.microsoft.com/en-us/library/hs600312%28v=vs.110%29.aspx). - aliases: [ "regexp" ] - state: - description: - - Whether the line should be there or not. - type: str - choices: [ absent, present ] - default: present - line: - description: - - Required for C(state=present). The line to insert/replace into the file. If C(backrefs) is set, may contain backreferences that will get - expanded with the C(regexp) capture groups if the regexp matches. - - Be aware that the line is processed first on the controller and thus is dependent on yaml quoting rules. Any double quoted line - will have control characters, such as '\r\n', expanded. To print such characters literally, use single or no quotes. - type: str - backrefs: - description: - - Used with C(state=present). If set, line can contain backreferences (both positional and named) that will get populated if the C(regexp) - matches. This flag changes the operation of the module slightly; C(insertbefore) and C(insertafter) will be ignored, and if the C(regexp) - doesn't match anywhere in the file, the file will be left unchanged. - - If the C(regexp) does match, the last matching line will be replaced by the expanded line parameter. - type: bool - default: no - insertafter: - description: - - Used with C(state=present). If specified, the line will be inserted after the last match of specified regular expression. A special value is - available; C(EOF) for inserting the line at the end of the file. - - If specified regular expression has no matches, EOF will be used instead. May not be used with C(backrefs). - type: str - choices: [ EOF, '*regex*' ] - default: EOF - insertbefore: - description: - - Used with C(state=present). If specified, the line will be inserted before the last match of specified regular expression. A value is available; - C(BOF) for inserting the line at the beginning of the file. - - If specified regular expression has no matches, the line will be inserted at the end of the file. May not be used with C(backrefs). - type: str - choices: [ BOF, '*regex*' ] - create: - description: - - Used with C(state=present). If specified, the file will be created if it does not already exist. By default it will fail if the file is missing. - type: bool - default: no - validate: - description: - - Validation to run before copying into place. Use %s in the command to indicate the current file to validate. - - The command is passed securely so shell features like expansion and pipes won't work. - type: str - encoding: - description: - - Specifies the encoding of the source text file to operate on (and thus what the output encoding will be). The default of C(auto) will cause - the module to auto-detect the encoding of the source file and ensure that the modified file is written with the same encoding. - - An explicit encoding can be passed as a string that is a valid value to pass to the .NET framework System.Text.Encoding.GetEncoding() method - - see U(https://msdn.microsoft.com/en-us/library/system.text.encoding%28v=vs.110%29.aspx). - - This is mostly useful with C(create=yes) if you want to create a new file with a specific encoding. If C(create=yes) is specified without a - specific encoding, the default encoding (UTF-8, no BOM) will be used. - type: str - default: auto - newline: - description: - - Specifies the line separator style to use for the modified file. This defaults to the windows line separator (C(\r\n)). Note that the indicated - line separator will be used for file output regardless of the original line separator that appears in the input file. - type: str - choices: [ unix, windows ] - default: windows -notes: - - As of Ansible 2.3, the I(dest) option has been changed to I(path) as default, but I(dest) still works as well. -seealso: -- module: assemble -- module: lineinfile -author: -- Brian Lloyd (@brianlloyd) -''' - -EXAMPLES = r''' -# Before Ansible 2.3, option 'dest', 'destfile' or 'name' was used instead of 'path' -- name: Insert path without converting \r\n - win_lineinfile: - path: c:\file.txt - line: c:\return\new - -- win_lineinfile: - path: C:\Temp\example.conf - regex: '^name=' - line: 'name=JohnDoe' - -- win_lineinfile: - path: C:\Temp\example.conf - regex: '^name=' - state: absent - -- win_lineinfile: - path: C:\Temp\example.conf - regex: '^127\.0\.0\.1' - line: '127.0.0.1 localhost' - -- win_lineinfile: - path: C:\Temp\httpd.conf - regex: '^Listen ' - insertafter: '^#Listen ' - line: Listen 8080 - -- win_lineinfile: - path: C:\Temp\services - regex: '^# port for http' - insertbefore: '^www.*80/tcp' - line: '# port for http by default' - -- name: Create file if it doesn't exist with a specific encoding - win_lineinfile: - path: C:\Temp\utf16.txt - create: yes - encoding: utf-16 - line: This is a utf-16 encoded file - -- name: Add a line to a file and ensure the resulting file uses unix line separators - win_lineinfile: - path: C:\Temp\testfile.txt - line: Line added to file - newline: unix - -- name: Update a line using backrefs - win_lineinfile: - path: C:\Temp\example.conf - backrefs: yes - regex: '(^name=)' - line: '$1JohnDoe' -''' - -RETURN = r''' -backup: - description: - - Name of the backup file that was created. - - This is now deprecated, use C(backup_file) instead. - returned: if backup=yes - type: str - sample: C:\Path\To\File.txt.11540.20150212-220915.bak -backup_file: - description: Name of the backup file that was created. - returned: if backup=yes - type: str - sample: C:\Path\To\File.txt.11540.20150212-220915.bak -''' diff --git a/lib/ansible/modules/windows/win_mapped_drive.ps1 b/lib/ansible/modules/windows/win_mapped_drive.ps1 deleted file mode 100644 index aab65d455cd..00000000000 --- a/lib/ansible/modules/windows/win_mapped_drive.ps1 +++ /dev/null @@ -1,444 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.AccessToken -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.AddType - -$spec = @{ - options = @{ - letter = @{ type = "str"; required = $true } - path = @{ type = "path"; } - state = @{ type = "str"; default = "present"; choices = @("absent", "present") } - username = @{ type = "str" } - password = @{ type = "str"; no_log = $true } - } - required_if = @( - ,@("state", "present", @("path")) - ) - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$letter = $module.Params.letter -$path = $module.Params.path -$state = $module.Params.state -$username = $module.Params.username -$password = $module.Params.password - -if ($letter -notmatch "^[a-zA-z]{1}$") { - $module.FailJson("letter must be a single letter from A-Z, was: $letter") -} -$letter_root = "$($letter):" - -$module.Diff.before = "" -$module.Diff.after = "" - -Add-CSharpType -AnsibleModule $module -References @' -using Microsoft.Win32.SafeHandles; -using System; -using System.Collections.Generic; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; - -namespace Ansible.MappedDrive -{ - internal class NativeHelpers - { - public enum ResourceScope : uint - { - Connected = 0x00000001, - GlobalNet = 0x00000002, - Remembered = 0x00000003, - Recent = 0x00000004, - Context = 0x00000005, - } - - [Flags] - public enum ResourceType : uint - { - Any = 0x0000000, - Disk = 0x00000001, - Print = 0x00000002, - Reserved = 0x00000008, - Unknown = 0xFFFFFFFF, - } - - public enum CloseFlags : uint - { - None = 0x00000000, - UpdateProfile = 0x00000001, - } - - [Flags] - public enum AddFlags : uint - { - UpdateProfile = 0x00000001, - UpdateRecent = 0x00000002, - Temporary = 0x00000004, - Interactive = 0x00000008, - Prompt = 0x00000010, - Redirect = 0x00000080, - CurrentMedia = 0x00000200, - CommandLine = 0x00000800, - CmdSaveCred = 0x00001000, - CredReset = 0x00002000, - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct NETRESOURCEW - { - public ResourceScope dwScope; - public ResourceType dwType; - public UInt32 dwDisplayType; - public UInt32 dwUsage; - [MarshalAs(UnmanagedType.LPWStr)] public string lpLocalName; - [MarshalAs(UnmanagedType.LPWStr)] public string lpRemoteName; - [MarshalAs(UnmanagedType.LPWStr)] public string lpComment; - [MarshalAs(UnmanagedType.LPWStr)] public string lpProvider; - } - } - - internal class NativeMethods - { - [DllImport("kernel32.dll", SetLastError = true)] - public static extern bool CloseHandle( - IntPtr hObject); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern bool ImpersonateLoggedOnUser( - IntPtr hToken); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern bool RevertToSelf(); - - [DllImport("Mpr.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 WNetAddConnection2W( - NativeHelpers.NETRESOURCEW lpNetResource, - [MarshalAs(UnmanagedType.LPWStr)] string lpPassword, - [MarshalAs(UnmanagedType.LPWStr)] string lpUserName, - NativeHelpers.AddFlags dwFlags); - - [DllImport("Mpr.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 WNetCancelConnection2W( - [MarshalAs(UnmanagedType.LPWStr)] string lpName, - NativeHelpers.CloseFlags dwFlags, - bool fForce); - - [DllImport("Mpr.dll")] - public static extern UInt32 WNetCloseEnum( - IntPtr hEnum); - - [DllImport("Mpr.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 WNetEnumResourceW( - IntPtr hEnum, - ref Int32 lpcCount, - SafeMemoryBuffer lpBuffer, - ref UInt32 lpBufferSize); - - [DllImport("Mpr.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 WNetOpenEnumW( - NativeHelpers.ResourceScope dwScope, - NativeHelpers.ResourceType dwType, - UInt32 dwUsage, - IntPtr lpNetResource, - out IntPtr lphEnum); - } - - internal class SafeMemoryBuffer : SafeHandleZeroOrMinusOneIsInvalid - { - public SafeMemoryBuffer() : base(true) { } - public SafeMemoryBuffer(int cb) : base(true) - { - base.SetHandle(Marshal.AllocHGlobal(cb)); - } - public SafeMemoryBuffer(IntPtr handle) : base(true) - { - base.SetHandle(handle); - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected override bool ReleaseHandle() - { - Marshal.FreeHGlobal(handle); - return true; - } - } - - internal class Impersonation : IDisposable - { - private IntPtr hToken = IntPtr.Zero; - - public Impersonation(IntPtr token) - { - hToken = token; - if (token != IntPtr.Zero) - if (!NativeMethods.ImpersonateLoggedOnUser(hToken)) - throw new Win32Exception("Failed to impersonate token with ImpersonateLoggedOnUser()"); - } - - public void Dispose() - { - if (hToken != null) - NativeMethods.RevertToSelf(); - GC.SuppressFinalize(this); - } - ~Impersonation() { Dispose(); } - } - - public class DriveInfo - { - public string Drive; - public string Path; - } - - public class Win32Exception : System.ComponentModel.Win32Exception - { - private string _msg; - public Win32Exception(string message) : this(Marshal.GetLastWin32Error(), message) { } - public Win32Exception(int errorCode, string message) : base(errorCode) - { - _msg = String.Format("{0} ({1}, Win32ErrorCode {2})", message, base.Message, errorCode); - } - public override string Message { get { return _msg; } } - public static explicit operator Win32Exception(string message) { return new Win32Exception(message); } - } - - public class Utils - { - private const UInt32 ERROR_SUCCESS = 0x00000000; - private const UInt32 ERROR_NO_MORE_ITEMS = 0x0000103; - - public static void AddMappedDrive(string drive, string path, IntPtr iToken, string username = null, string password = null) - { - NativeHelpers.NETRESOURCEW resource = new NativeHelpers.NETRESOURCEW - { - dwType = NativeHelpers.ResourceType.Disk, - lpLocalName = drive, - lpRemoteName = path, - }; - NativeHelpers.AddFlags dwFlags = NativeHelpers.AddFlags.UpdateProfile; - // While WNetAddConnection2W supports user/pass, this is only used for the first connection and the - // password is not remembered. We will delete the username mapping afterwards as it interferes with - // the implicit credential cache used in Windows - using (Impersonation imp = new Impersonation(iToken)) - { - UInt32 res = NativeMethods.WNetAddConnection2W(resource, password, username, dwFlags); - if (res != ERROR_SUCCESS) - throw new Win32Exception((int)res, String.Format("Failed to map {0} to '{1}' with WNetAddConnection2W()", drive, path)); - } - } - - public static List GetMappedDrives(IntPtr iToken) - { - using (Impersonation imp = new Impersonation(iToken)) - { - IntPtr enumPtr = IntPtr.Zero; - UInt32 res = NativeMethods.WNetOpenEnumW(NativeHelpers.ResourceScope.Remembered, NativeHelpers.ResourceType.Disk, - 0, IntPtr.Zero, out enumPtr); - if (res != ERROR_SUCCESS) - throw new Win32Exception((int)res, "WNetOpenEnumW()"); - - List resources = new List(); - try - { - // MS recommend a buffer size of 16 KiB - UInt32 bufferSize = 16384; - int lpcCount = -1; - - // keep iterating the enum until ERROR_NO_MORE_ITEMS is returned - do - { - using (SafeMemoryBuffer buffer = new SafeMemoryBuffer((int)bufferSize)) - { - res = NativeMethods.WNetEnumResourceW(enumPtr, ref lpcCount, buffer, ref bufferSize); - if (res == ERROR_NO_MORE_ITEMS) - continue; - else if (res != ERROR_SUCCESS) - throw new Win32Exception((int)res, "WNetEnumResourceW()"); - lpcCount = lpcCount < 0 ? 0 : lpcCount; - - NativeHelpers.NETRESOURCEW[] rawResources = new NativeHelpers.NETRESOURCEW[lpcCount]; - PtrToStructureArray(rawResources, buffer.DangerousGetHandle()); - foreach (NativeHelpers.NETRESOURCEW resource in rawResources) - { - DriveInfo currentDrive = new DriveInfo - { - Drive = resource.lpLocalName, - Path = resource.lpRemoteName, - }; - resources.Add(currentDrive); - } - } - } - while (res != ERROR_NO_MORE_ITEMS); - } - finally - { - NativeMethods.WNetCloseEnum(enumPtr); - } - - return resources; - } - } - - public static void RemoveMappedDrive(string drive, IntPtr iToken) - { - using (Impersonation imp = new Impersonation(iToken)) - { - UInt32 res = NativeMethods.WNetCancelConnection2W(drive, NativeHelpers.CloseFlags.UpdateProfile, true); - if (res != ERROR_SUCCESS) - throw new Win32Exception((int)res, String.Format("Failed to remove mapped drive {0} with WNetCancelConnection2W()", drive)); - } - } - - private static void PtrToStructureArray(T[] array, IntPtr ptr) - { - IntPtr ptrOffset = ptr; - for (int i = 0; i < array.Length; i++, ptrOffset = IntPtr.Add(ptrOffset, Marshal.SizeOf(typeof(T)))) - array[i] = (T)Marshal.PtrToStructure(ptrOffset, typeof(T)); - } - } -} -'@ - -Function Get-LimitedToken { - $h_process = [Ansible.AccessToken.TokenUtil]::OpenProcess() - $h_token = [Ansible.AccessToken.TokenUtil]::OpenProcessToken($h_process, "Duplicate, Query") - - try { - # If we don't have a Full token, we don't need to get the limited one to set a mapped drive - $tet = [Ansible.AccessToken.TokenUtil]::GetTokenElevationType($h_token) - if ($tet -ne [Ansible.AccessToken.TokenElevationType]::Full) { - return - } - - foreach ($system_token in [Ansible.AccessToken.TokenUtil]::EnumerateUserTokens("S-1-5-18", "Duplicate")) { - # To get the TokenLinkedToken we need the SeTcbPrivilege, not all SYSTEM tokens have this assigned so - # we need to check before impersonating that token - $token_privileges = [Ansible.AccessToken.TokenUtil]::GetTokenPrivileges($system_token) - if ($null -eq ($token_privileges | Where-Object { $_.Name -eq "SeTcbPrivilege" })) { - continue - } - - [Ansible.AccessToken.TokenUtil]::ImpersonateToken($system_token) - try { - return [Ansible.AccessToken.TokenUtil]::GetTokenLinkedToken($h_token) - } finally { - [Ansible.AccessToken.TokenUtil]::RevertToSelf() - } - } - } finally { - $h_token.Dispose() - } -} - -<# -When we run with become and UAC is enabled, the become process will most likely be the Admin/Full token. This is -an issue with the WNetConnection APIs as the Full token is unable to add/enumerate/remove connections due to -Windows storing the connection details on each token session ID. Unless EnabledLinkedConnections (reg key) is -set to 1, the Full token is unable to manage connections in a persisted way whereas the Limited token is. This -is similar to running 'net use' normally and an admin process is unable to see those and vice versa. - -To overcome this problem, we attempt to get a handle on the Limited token for the current logon and impersonate -that before making any WNetConnection calls. If the token is not split, or we are already running on the Limited -token then no impersonatoin is used/required. This allows the module to run with become (required to access the -credential store) but still be able to manage the mapped connections. - -These are the following scenarios we have to handle; - - 1. Run without become - A network logon is usually not split so GetLimitedToken() will return $null and no impersonation is needed - 2. Run with become on admin user with admin priv - We will have a Full token, GetLimitedToken() will return the limited token and impersonation is used - 3. Run with become on admin user without admin priv - We are already running with a Limited token, GetLimitedToken() return $nul and no impersonation is needed - 4. Run with become on standard user - There's no split token, GetLimitedToken() will return $null and no impersonation is needed -#> -$impersonation_token = Get-LimitedToken - -try { - $i_token_ptr = [System.IntPtr]::Zero - if ($null -ne $impersonation_token) { - $i_token_ptr = $impersonation_token.DangerousGetHandle() - } - - $existing_targets = [Ansible.MappedDrive.Utils]::GetMappedDrives($i_token_ptr) - $existing_target = $existing_targets | Where-Object { $_.Drive -eq $letter_root } - - if ($existing_target) { - $module.Diff.before = @{ - letter = $letter - path = $existing_target.Path - } - } - - if ($state -eq "absent") { - if ($null -ne $existing_target) { - if ($null -ne $path -and $existing_target.Path -ne $path) { - $module.FailJson("did not delete mapped drive $letter, the target path is pointing to a different location at $( $existing_target.Path )") - } - if (-not $module.CheckMode) { - [Ansible.MappedDrive.Utils]::RemoveMappedDrive($letter_root, $i_token_ptr) - } - - $module.Result.changed = $true - } - } else { - $physical_drives = Get-PSDrive -PSProvider "FileSystem" - if ($letter -in $physical_drives.Name) { - $module.FailJson("failed to create mapped drive $letter, this letter is in use and is pointing to a non UNC path") - } - - # PowerShell converts a $null value to "" when crossing the .NET marshaler, we need to convert the input - # to a missing value so it uses the defaults. We also need to Invoke it with MethodInfo.Invoke so the defaults - # are still used - $input_username = $username - if ($null -eq $username) { - $input_username = [Type]::Missing - } - $input_password = $password - if ($null -eq $password) { - $input_password = [Type]::Missing - } - $add_method = [Ansible.MappedDrive.Utils].GetMethod("AddMappedDrive") - - if ($null -ne $existing_target) { - if ($existing_target.Path -ne $path) { - if (-not $module.CheckMode) { - [Ansible.MappedDrive.Utils]::RemoveMappedDrive($letter_root, $i_token_ptr) - $add_method.Invoke($null, [Object[]]@($letter_root, $path, $i_token_ptr, $input_username, $input_password)) - } - $module.Result.changed = $true - } - } else { - if (-not $module.CheckMode) { - $add_method.Invoke($null, [Object[]]@($letter_root, $path, $i_token_ptr, $input_username, $input_password)) - } - - $module.Result.changed = $true - } - - # If username was set and we made a change, remove the UserName value so Windows will continue to use the cred - # cache. If we don't do this then the drive will fail to map in the future as WNetAddConnection does not cache - # the password and relies on the credential store. - if ($null -ne $username -and $module.Result.changed -and -not $module.CheckMode) { - Set-ItemProperty -Path HKCU:\Network\$letter -Name UserName -Value "" -WhatIf:$module.CheckMode - } - - $module.Diff.after = @{ - letter = $letter - path = $path - } - } -} finally { - if ($null -ne $impersonation_token) { - $impersonation_token.Dispose() - } -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_mapped_drive.py b/lib/ansible/modules/windows/win_mapped_drive.py deleted file mode 100644 index 3b2a0f6372d..00000000000 --- a/lib/ansible/modules/windows/win_mapped_drive.py +++ /dev/null @@ -1,155 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub, actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_mapped_drive -version_added: '2.4' -short_description: Map network drives for users -description: -- Allows you to modify mapped network drives for individual users. -- Also support WebDAV endpoints in the UNC form. -options: - letter: - description: - - The letter of the network path to map to. - - This letter must not already be in use with Windows. - type: str - required: yes - password: - description: - - The password for C(username) that is used when testing the initial - connection. - - This is never saved with a mapped drive, use the M(win_credential) module - to persist a username and password for a host. - type: str - path: - description: - - The UNC path to map the drive to. - - If pointing to a WebDAV location this must still be in a UNC path in the - format C(\\hostname\path) and not a URL, see examples for more details. - - To specify a C(https) WebDAV path, add C(@SSL) after the hostname. To - specify a custom WebDAV port add C(@) after the C(@SSL) or - hostname portion of the UNC path, e.g. C(\\server@SSL@1234) or - C(\\server@1234). - - This is required if C(state=present). - - If C(state=absent) and I(path) is not set, the module will delete the - mapped drive regardless of the target. - - If C(state=absent) and the I(path) is set, the module will throw an error - if path does not match the target of the mapped drive. - type: path - state: - description: - - If C(present) will ensure the mapped drive exists. - - If C(absent) will ensure the mapped drive does not exist. - type: str - choices: [ absent, present ] - default: present - username: - description: - - The username that is used when testing the initial connection. - - This is never saved with a mapped drive, the M(win_credential) module - to persist a username and password for a host. - - This is required if the mapped drive requires authentication with - custom credentials and become, or CredSSP cannot be used. - - If become or CredSSP is used, any credentials saved with - M(win_credential) will automatically be used instead. - type: str -notes: -- You cannot use this module to access a mapped drive in another Ansible task, - drives mapped with this module are only accessible when logging in - interactively with the user through the console or RDP. -- It is recommend to run this module with become or CredSSP when the remote - path requires authentication. -- When using become or CredSSP, the task will have access to any local - credentials stored in the user's vault. -- If become or CredSSP is not available, the I(username) and I(password) - options can be used for the initial authentication but these are not - persisted. -- WebDAV paths must have the WebDAV client feature installed for this module to - map those paths. This is installed by default on desktop Windows editions but - Windows Server hosts need to install the C(WebDAV-Redirector) feature using - M(win_feature). -seealso: -- module: win_credential -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Create a mapped drive under Z - win_mapped_drive: - letter: Z - path: \\domain\appdata\accounting - -- name: Delete any mapped drives under Z - win_mapped_drive: - letter: Z - state: absent - -- name: Only delete the mapped drive Z if the paths match (error is thrown otherwise) - win_mapped_drive: - letter: Z - path: \\domain\appdata\accounting - state: absent - -- name: Create mapped drive with credentials and save the username and password - block: - - name: Save the network credentials required for the mapped drive - win_credential: - name: server - type: domain_password - username: username@DOMAIN - secret: Password01 - state: present - - - name: Create a mapped drive that requires authentication - win_mapped_drive: - letter: M - path: \\SERVER\C$ - state: present - vars: - # become is required to save and retrieve the credentials in the tasks - ansible_become: yes - ansible_become_method: runas - ansible_become_user: '{{ ansible_user }}' - ansible_become_pass: '{{ ansible_password }}' - -- name: Create mapped drive with credentials that do not persist on the next logon - win_mapped_drive: - letter: M - path: \\SERVER\C$ - state: present - username: '{{ ansible_user }}' - password: '{{ ansible_password }}' - -# This should only be required for Windows Server OS' -- name: Ensure WebDAV client feature is installed - win_feature: - name: WebDAV-Redirector - state: present - register: webdav_feature - -- name: Reboot after installing WebDAV client feature - win_reboot: - when: webdav_feature.reboot_required - -- name: Map the HTTPS WebDAV location - win_mapped_drive: - letter: W - path: \\live.sysinternals.com@SSL\tools # https://live.sysinternals.com/tools - state: present -''' - -RETURN = r''' -''' diff --git a/lib/ansible/modules/windows/win_msg.ps1 b/lib/ansible/modules/windows/win_msg.ps1 deleted file mode 100644 index 63fe6800240..00000000000 --- a/lib/ansible/modules/windows/win_msg.ps1 +++ /dev/null @@ -1,52 +0,0 @@ -#!powershell - -# Copyright: (c) 2016, Jon Hawkesworth (@jhawkesworth) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -# -$stopwatch = [system.diagnostics.stopwatch]::startNew() - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$display_seconds = Get-AnsibleParam -obj $params -name "display_seconds" -type "int" -default "10" -$msg = Get-AnsibleParam -obj $params -name "msg" -type "str" -default "Hello world!" -$to = Get-AnsibleParam -obj $params -name "to" -type "str" -default "*" -$wait = Get-AnsibleParam -obj $params -name "wait" -type "bool" -default $false - -$result = @{ - changed = $false - display_seconds = $display_seconds - msg = $msg - wait = $wait -} - -if ($msg.Length -gt 255) { - Fail-Json -obj $result -message "msg length must be less than 256 characters, current length: $($msg.Length)" -} - -$msg_args = @($to, "/TIME:$display_seconds") - -if ($wait) { - $msg_args += "/W" -} - -$msg_args += $msg -if (-not $check_mode) { - $output = & msg.exe $msg_args 2>&1 - $result.rc = $LASTEXITCODE -} - -$endsend_at = Get-Date| Out-String -$stopwatch.Stop() - -$result.changed = $true -$result.runtime_seconds = $stopwatch.Elapsed.TotalSeconds -$result.sent_localtime = $endsend_at.Trim() - -if ($result.rc -ne 0 ) { - Fail-Json -obj $result -message "$output" -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_msg.py b/lib/ansible/modules/windows/win_msg.py deleted file mode 100644 index 4f9ea959de6..00000000000 --- a/lib/ansible/modules/windows/win_msg.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Jon Hawkesworth (@jhawkesworth) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_msg -version_added: "2.3" -short_description: Sends a message to logged in users on Windows hosts -description: - - Wraps the msg.exe command in order to send messages to Windows hosts. -options: - to: - description: - - Who to send the message to. Can be a username, sessionname or sessionid. - type: str - default: '*' - display_seconds: - description: - - How long to wait for receiver to acknowledge message, in seconds. - type: int - default: 10 - wait: - description: - - Whether to wait for users to respond. Module will only wait for the number of seconds specified in display_seconds or 10 seconds if not specified. - However, if I(wait) is C(yes), the message is sent to each logged on user in turn, waiting for the user to either press 'ok' or for - the timeout to elapse before moving on to the next user. - type: bool - default: 'no' - msg: - description: - - The text of the message to be displayed. - - The message must be less than 256 characters. - type: str - default: Hello world! -notes: - - This module must run on a windows host, so ensure your play targets windows - hosts, or delegates to a windows host. - - Messages are only sent to the local host where the module is run. - - The module does not support sending to users listed in a file. - - Setting wait to C(yes) can result in long run times on systems with many logged in users. -seealso: -- module: win_say -- module: win_toast -author: -- Jon Hawkesworth (@jhawkesworth) -''' - -EXAMPLES = r''' -- name: Warn logged in users of impending upgrade - win_msg: - display_seconds: 60 - msg: Automated upgrade about to start. Please save your work and log off before {{ deployment_start_time }} -''' - -RETURN = r''' -msg: - description: Test of the message that was sent. - returned: changed - type: str - sample: Automated upgrade about to start. Please save your work and log off before 22 July 2016 18:00:00 -display_seconds: - description: Value of display_seconds module parameter. - returned: success - type: str - sample: 10 -rc: - description: The return code of the API call. - returned: always - type: int - sample: 0 -runtime_seconds: - description: How long the module took to run on the remote windows host. - returned: success - type: str - sample: 22 July 2016 17:45:51 -sent_localtime: - description: local time from windows host when the message was sent. - returned: success - type: str - sample: 22 July 2016 17:45:51 -wait: - description: Value of wait module parameter. - returned: success - type: bool - sample: false -''' diff --git a/lib/ansible/modules/windows/win_netbios.ps1 b/lib/ansible/modules/windows/win_netbios.ps1 deleted file mode 100644 index 0179a40260c..00000000000 --- a/lib/ansible/modules/windows/win_netbios.ps1 +++ /dev/null @@ -1,72 +0,0 @@ -#!powershell - -# Copyright: (c) 2019, Thomas Moore (@tmmruk) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic - -$spec = @{ - options = @{ - state = @{ type = "str"; choices = "enabled", "disabled", "default"; required = $true } - adapter_names = @{ type = "list"; required = $false } - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) -$module.Result.reboot_required = $false - -$state = $module.Params.state -$adapter_names = $module.Params.adapter_names - -switch ( $state ) -{ - 'default'{ $netbiosoption = 0 } - enabled { $netbiosoption = 1 } - disabled { $netbiosoption = 2 } -} - -if(-not $adapter_names) -{ - # Target all network adapters on the system - $get_params = @{ - ClassName = 'Win32_NetworkAdapterConfiguration' - Filter = 'IPEnabled=true' - Property = @('MacAddress', 'TcpipNetbiosOptions') - } - $target_adapters_config = Get-CimInstance @get_params -} -else -{ - $get_params = @{ - Class = 'Win32_NetworkAdapter' - Filter = ($adapter_names | ForEach-Object -Process { "NetConnectionId='$_'" }) -join " OR " - KeyOnly = $true - } - $target_adapters_config = Get-CimInstance @get_params | Get-CimAssociatedInstance -ResultClass 'Win32_NetworkAdapterConfiguration' - if(($target_adapters_config | Measure-Object).Count -ne $adapter_names.Count) - { - $module.FailJson("Not all of the target adapter names could be found on the system. No configuration changes have been made. $adapter_names") - } -} - -foreach($adapter in $target_adapters_config) -{ - if($adapter.TcpipNetbiosOptions -ne $netbiosoption) - { - if(-not $module.CheckMode) - { - $result = Invoke-CimMethod -InputObject $adapter -MethodName SetTcpipNetbios -Arguments @{TcpipNetbiosOptions=$netbiosoption} - switch ( $result.ReturnValue ) - { - 0 { <# Success no reboot required #> } - 1 { $module.Result.reboot_required = $true } - 100 { $module.Warn("DHCP not enabled on adapter $($adapter.MacAddress). Unable to set default. Try using disabled or enabled options instead.") } - default { $module.FailJson("An error occurred while setting TcpipNetbios options on adapter $($adapter.MacAddress). Return code $($result.ReturnValue).") } - } - } - $module.Result.changed = $true - } -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_netbios.py b/lib/ansible/modules/windows/win_netbios.py deleted file mode 100644 index a3bd0dfac00..00000000000 --- a/lib/ansible/modules/windows/win_netbios.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2019, Thomas Moore (@tmmruk) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_netbios -version_added: '2.9' -short_description: Manage NetBIOS over TCP/IP settings on Windows. -description: - - Enables or disables NetBIOS on Windows network adapters. - - Can be used to protect a system against NBT-NS poisoning and avoid NBNS broadcast storms. - - Settings can be applied system wide or per adapter. -options: - state: - description: - - Whether NetBIOS should be enabled, disabled, or default (use setting from DHCP server or if static IP address is assigned enable NetBIOS). - choices: - - enabled - - disabled - - default - required: yes - type: str - adapter_names: - description: - - List of adapter names for which to manage NetBIOS settings. If this option is omitted then configuration is applied to all adapters on the system. - - The adapter name used is the connection caption in the Network Control Panel or via C(Get-NetAdapter), eg C(Ethernet 2). - type: list - required: no - -author: - - Thomas Moore (@tmmruk) -notes: - - Changing NetBIOS settings does not usually require a reboot and will take effect immediately. - - UDP port 137/138/139 will no longer be listening once NetBIOS is disabled. -''' - -EXAMPLES = r''' -- name: Disable NetBIOS system wide - win_netbios: - state: disabled - -- name: Disable NetBIOS on Ethernet2 - win_netbios: - state: disabled - adapter_names: - - Ethernet2 - -- name: Enable NetBIOS on Public and Backup adapters - win_netbios: - state: enabled - adapter_names: - - Public - - Backup - -- name: Set NetBIOS to system default on all adapters - win_netbios: - state: default - -''' - -RETURN = r''' -reboot_required: - description: Boolean value stating whether a system reboot is required. - returned: always - type: bool - sample: true -''' diff --git a/lib/ansible/modules/windows/win_nssm.ps1 b/lib/ansible/modules/windows/win_nssm.ps1 deleted file mode 100644 index e351beebf5a..00000000000 --- a/lib/ansible/modules/windows/win_nssm.ps1 +++ /dev/null @@ -1,498 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, George Frank -# Copyright: (c) 2015, Adam Keech -# Copyright: (c) 2015, Hans-Joachim Kliemeck -# Copyright: (c) 2019, Kevin Subileau (@ksubileau) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.ArgvParser -#Requires -Module Ansible.ModuleUtils.CommandUtil - -$ErrorActionPreference = "Stop" - -$start_modes_map = @{ - "auto" = "SERVICE_AUTO_START" - "delayed" = "SERVICE_DELAYED_AUTO_START" - "manual" = "SERVICE_DEMAND_START" - "disabled" = "SERVICE_DISABLED" -} - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff_mode = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent","started","stopped","restarted" -resultobj $result -$display_name = Get-AnsibleParam -obj $params -name 'display_name' -type 'str' -$description = Get-AnsibleParam -obj $params -name 'description' -type 'str' - -$application = Get-AnsibleParam -obj $params -name "application" -type "path" -$appDirectory = Get-AnsibleParam -obj $params -name "working_directory" -aliases "app_directory","chdir" -type "path" -$appParameters = Get-AnsibleParam -obj $params -name "app_parameters" -$appArguments = Get-AnsibleParam -obj $params -name "arguments" -aliases "app_parameters_free_form" - -$stdoutFile = Get-AnsibleParam -obj $params -name "stdout_file" -type "path" -$stderrFile = Get-AnsibleParam -obj $params -name "stderr_file" -type "path" - -$executable = Get-AnsibleParam -obj $params -name "executable" -type "path" -default "nssm.exe" - -$app_rotate_bytes = Get-AnsibleParam -obj $params -name "app_rotate_bytes" -type "int" -default 104858 -$app_rotate_online = Get-AnsibleParam -obj $params -name "app_rotate_online" -type "int" -default 0 -validateset 0,1 -$app_stop_method_console = Get-AnsibleParam -obj $params -name "app_stop_method_console" -type "int" -$app_stop_method_skip = Get-AnsibleParam -obj $params -name "app_stop_method_skip" -type "int" -validateset 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 - -# Deprecated options since 2.8. Remove in 2.12 -$startMode = Get-AnsibleParam -obj $params -name "start_mode" -type "str" -default "auto" -validateset $start_modes_map.Keys -resultobj $result -$dependencies = Get-AnsibleParam -obj $params -name "dependencies" -type "list" -$user = Get-AnsibleParam -obj $params -name "user" -type "str" -$password = Get-AnsibleParam -obj $params -name "password" -type "str" - -$result = @{ - changed = $false -} -$diff_text = $null - -function Invoke-NssmCommand { - [CmdletBinding()] - param( - [Parameter(Mandatory=$true,ValueFromRemainingArguments=$true)] - [string[]]$arguments - ) - - $command = Argv-ToString -arguments (@($executable) + $arguments) - $result = Run-Command -command $command - - $result.arguments = $command - - return $result -} - -function Get-NssmServiceStatus { - [CmdletBinding()] - param( - [Parameter(Mandatory=$true)] - [string]$service - ) - - return Invoke-NssmCommand -arguments @("status", $service) -} - -function Get-NssmServiceParameter { - [CmdletBinding()] - param( - [Parameter(Mandatory=$true)] - [string]$service, - [Parameter(Mandatory=$true)] - [Alias("param")] - [string]$parameter, - [Parameter(Mandatory=$false)] - [string]$subparameter - ) - - $arguments = @("get", $service, $parameter) - if($subparameter -ne "") { - $arguments += $subparameter - } - return Invoke-NssmCommand -arguments $arguments -} - -function Set-NssmServiceParameter { - [CmdletBinding()] - param( - [Parameter(Mandatory=$true)] - [string]$service, - [Parameter(Mandatory=$true)] - [string]$parameter, - [Parameter(Mandatory=$true,ValueFromRemainingArguments=$true)] - [Alias("value")] - [string[]]$arguments - ) - - return Invoke-NssmCommand -arguments (@("set", $service, $parameter) + $arguments) -} - -function Reset-NssmServiceParameter { - [CmdletBinding()] - param( - [Parameter(Mandatory=$true)] - [string]$service, - [Parameter(Mandatory=$true)] - [Alias("param")] - [string]$parameter - ) - - return Invoke-NssmCommand -arguments @("reset", $service, $parameter) -} - -function Update-NssmServiceParameter { - <# - .SYNOPSIS - A generic cmdlet to idempotently set a nssm service parameter. - .PARAMETER service - [String] The service name - .PARAMETER parameter - [String] The name of the nssm parameter to set. - .PARAMETER arguments - [String[]] Target value (or list of value) or array of arguments to pass to the 'nssm set' command. - .PARAMETER compare - [scriptblock] An optionnal idempotency check scriptblock that must return true when - the current value is equal to the desired value. Usefull when 'nssm get' doesn't return - the same value as 'nssm set' takes in argument, like for the ObjectName parameter. - #> - [CmdletBinding(SupportsShouldProcess=$true)] - param( - [Parameter(Mandatory=$true)] - [string]$service, - - [Parameter(Mandatory=$true)] - [string]$parameter, - - [Parameter(Mandatory=$true,ValueFromRemainingArguments=$true)] - [AllowEmptyString()] - [AllowNull()] - [Alias("value")] - [string[]]$arguments, - - [Parameter()] - [scriptblock]$compare = {param($actual,$expected) @(Compare-Object -ReferenceObject $actual -DifferenceObject $expected).Length -eq 0} - ) - - if($null -eq $arguments) { return } - $arguments = @($arguments | Where-Object { $_ -ne '' }) - - $nssm_result = Get-NssmServiceParameter -service $service -parameter $parameter - - if ($nssm_result.rc -ne 0) { - $result.nssm_error_cmd = $nssm_result.arguments - $result.nssm_error_log = $nssm_result.stderr - Fail-Json -obj $result -message "Error retrieving $parameter for service ""$service""" - } - - $current_values = @($nssm_result.stdout.split("`n`r") | Where-Object { $_ -ne '' }) - - if (-not $compare.Invoke($current_values,$arguments)) { - if ($PSCmdlet.ShouldProcess($service, "Update '$parameter' parameter")) { - if($arguments.Count -gt 0) { - $nssm_result = Set-NssmServiceParameter -service $service -parameter $parameter -arguments $arguments - } - else { - $nssm_result = Reset-NssmServiceParameter -service $service -parameter $parameter - } - - if ($nssm_result.rc -ne 0) { - $result.nssm_error_cmd = $nssm_result.arguments - $result.nssm_error_log = $nssm_result.stderr - Fail-Json -obj $result -message "Error setting $parameter for service ""$service""" - } - } - - $script:diff_text += "-$parameter = $($current_values -join ', ')`n+$parameter = $($arguments -join ', ')`n" - $result.changed_by = $parameter - $result.changed = $true - } -} - -function Test-NssmServiceExists { - [CmdletBinding()] - param( - [Parameter(Mandatory=$true)] - [string]$service - ) - - return [bool](Get-Service -Name $service -ErrorAction SilentlyContinue) -} - -function Invoke-NssmStart { - [CmdletBinding()] - param( - [Parameter(Mandatory=$true)] - [string]$service - ) - - $nssm_result = Invoke-NssmCommand -arguments @("start", $service) - - if ($nssm_result.rc -ne 0) { - $result.nssm_error_cmd = $nssm_result.arguments - $result.nssm_error_log = $nssm_result.stderr - Fail-Json -obj $result -message "Error starting service ""$service""" - } -} - -function Invoke-NssmStop { - [CmdletBinding()] - param( - [Parameter(Mandatory=$true)] - [string]$service - ) - - $nssm_result = Invoke-NssmCommand -arguments @("stop", $service) - - if ($nssm_result.rc -ne 0) { - $result.nssm_error_cmd = $nssm_result.arguments - $result.nssm_error_log = $nssm_result.stderr - Fail-Json -obj $result -message "Error stopping service ""$service""" - } -} - -function Start-NssmService { - [CmdletBinding(SupportsShouldProcess=$true)] - param( - [Parameter(Mandatory=$true)] - [string]$service - ) - - $currentStatus = Get-NssmServiceStatus -service $service - - if ($currentStatus.rc -ne 0) { - $result.nssm_error_cmd = $currentStatus.arguments - $result.nssm_error_log = $currentStatus.stderr - Fail-Json -obj $result -message "Error starting service ""$service""" - } - - if ($currentStatus.stdout -notlike "*SERVICE_RUNNING*") { - if ($PSCmdlet.ShouldProcess($service, "Start service")) { - switch -wildcard ($currentStatus.stdout) { - "*SERVICE_STOPPED*" { Invoke-NssmStart -service $service } - - "*SERVICE_CONTINUE_PENDING*" { Invoke-NssmStop -service $service; Invoke-NssmStart -service $service } - "*SERVICE_PAUSE_PENDING*" { Invoke-NssmStop -service $service; Invoke-NssmStart -service $service } - "*SERVICE_PAUSED*" { Invoke-NssmStop -service $service; Invoke-NssmStart -service $service } - "*SERVICE_START_PENDING*" { Invoke-NssmStop -service $service; Invoke-NssmStart -service $service } - "*SERVICE_STOP_PENDING*" { Invoke-NssmStop -service $service; Invoke-NssmStart -service $service } - } - } - - $result.changed_by = "start_service" - $result.changed = $true - } -} - -function Stop-NssmService { - [CmdletBinding(SupportsShouldProcess=$true)] - param( - [Parameter(Mandatory=$true)] - [string]$service - ) - - $currentStatus = Get-NssmServiceStatus -service $service - - if ($currentStatus.rc -ne 0) { - $result.nssm_error_cmd = $currentStatus.arguments - $result.nssm_error_log = $currentStatus.stderr - Fail-Json -obj $result -message "Error stopping service ""$service""" - } - - if ($currentStatus.stdout -notlike "*SERVICE_STOPPED*") { - if ($PSCmdlet.ShouldProcess($service, "Stop service")) { - Invoke-NssmStop -service $service - } - - $result.changed_by = "stop_service" - $result.changed = $true - } -} - -if (($null -ne $appParameters) -and ($null -ne $appArguments)) { - Fail-Json $result "'app_parameters' and 'arguments' are mutually exclusive but have both been set." -} - -# Backward compatibility for old parameters style. Remove the block bellow in 2.12 -if ($null -ne $appParameters) { - Add-DeprecationWarning -obj $result -message "The parameter 'app_parameters' will be removed soon, use 'arguments' instead" -version 2.12 - - if ($appParameters -isnot [string]) { - Fail-Json -obj $result -message "The app_parameters parameter must be a string representing a dictionary." - } - - # Convert dict-as-string form to list - $escapedAppParameters = $appParameters.TrimStart("@").TrimStart("{").TrimEnd("}").Replace("; ","`n").Replace("\","\\") - $appParametersHash = ConvertFrom-StringData -StringData $escapedAppParameters - - $appParamsArray = @() - $appParametersHash.GetEnumerator() | Foreach-Object { - if ($_.Name -ne "_") { - $appParamsArray += $_.Name - } - $appParamsArray += $_.Value - } - $appArguments = @($appParamsArray) - - # The rest of the code should use only the new $appArguments variable -} - -if ($state -in @("started","stopped","restarted")) { - Add-DeprecationWarning -obj $result -message "The values 'started', 'stopped', and 'restarted' for 'state' will be removed soon, use the win_service module to start or stop the service instead" -version 2.12 -} -if ($params.ContainsKey('start_mode')) { - Add-DeprecationWarning -obj $result -message "The parameter 'start_mode' will be removed soon, use the win_service module instead" -version 2.12 -} -if ($null -ne $dependencies) { - Add-DeprecationWarning -obj $result -message "The parameter 'dependencies' will be removed soon, use the win_service module instead" -version 2.12 -} -if ($null -ne $user) { - Add-DeprecationWarning -obj $result -message "The parameter 'user' will be removed soon, use the win_service module instead" -version 2.12 -} -if ($null -ne $password) { - Add-DeprecationWarning -obj $result -message "The parameter 'password' will be removed soon, use the win_service module instead" -version 2.12 -} - -if ($state -ne 'absent') { - if ($null -eq $application) { - Fail-Json -obj $result -message "The application parameter must be defined when the state is not absent." - } - - if (-not (Test-Path -LiteralPath $application -PathType Leaf)) { - Fail-Json -obj $result -message "The application specified ""$application"" does not exist on the host." - } - - if($null -eq $appDirectory) { - $appDirectory = (Get-Item -LiteralPath $application).DirectoryName - } - - if ($user -and -not $password) { - Fail-Json -obj $result -message "User without password is informed for service ""$name""" - } -} - - -$service_exists = Test-NssmServiceExists -service $name - -if ($state -eq 'absent') { - if ($service_exists) { - if(-not $check_mode) { - if ((Get-Service -Name $name).Status -ne "Stopped") { - $nssm_result = Invoke-NssmStop -service $name - } - - $nssm_result = Invoke-NssmCommand -arguments @("remove", $name, "confirm") - - if ($nssm_result.rc -ne 0) { - $result.nssm_error_cmd = $nssm_result.arguments - $result.nssm_error_log = $nssm_result.stderr - Fail-Json -obj $result -message "Error removing service ""$name""" - } - } - - $diff_text += "-[$name]" - $result.changed_by = "remove_service" - $result.changed = $true - } -} else { - $diff_text_added_prefix = '' - if (-not $service_exists) { - if(-not $check_mode) { - $nssm_result = Invoke-NssmCommand -arguments @("install", $name, $application) - - if ($nssm_result.rc -ne 0) { - $result.nssm_error_cmd = $nssm_result.arguments - $result.nssm_error_log = $nssm_result.stderr - Fail-Json -obj $result -message "Error installing service ""$name""" - } - $service_exists = $true - } - - $diff_text_added_prefix = '+' - $result.changed_by = "install_service" - $result.changed = $true - } - - $diff_text += "$diff_text_added_prefix[$name]`n" - - # We cannot configure a service that was created above in check mode as it won't actually exist - if ($service_exists) { - $common_params = @{ - service = $name - WhatIf = $check_mode - } - - Update-NssmServiceParameter -parameter "Application" -value $application @common_params - Update-NssmServiceParameter -parameter "DisplayName" -value $display_name @common_params - Update-NssmServiceParameter -parameter "Description" -value $description @common_params - - Update-NssmServiceParameter -parameter "AppDirectory" -value $appDirectory @common_params - - - if ($null -ne $appArguments) { - $singleLineParams = "" - if ($appArguments -is [array]) { - $singleLineParams = Argv-ToString -arguments $appArguments - } else { - $singleLineParams = $appArguments.ToString() - } - - $result.nssm_app_parameters = $appArguments - $result.nssm_single_line_app_parameters = $singleLineParams - - Update-NssmServiceParameter -parameter "AppParameters" -value $singleLineParams @common_params - } - - - Update-NssmServiceParameter -parameter "AppStdout" -value $stdoutFile @common_params - Update-NssmServiceParameter -parameter "AppStderr" -value $stderrFile @common_params - - ### - # Setup file rotation so we don't accidentally consume too much disk - ### - - #set files to overwrite - Update-NssmServiceParameter -parameter "AppStdoutCreationDisposition" -value 2 @common_params - Update-NssmServiceParameter -parameter "AppStderrCreationDisposition" -value 2 @common_params - - #enable file rotation - Update-NssmServiceParameter -parameter "AppRotateFiles" -value 1 @common_params - - #don't rotate until the service restarts - Update-NssmServiceParameter -parameter "AppRotateOnline" -value $app_rotate_online @common_params - - #both of the below conditions must be met before rotation will happen - #minimum age before rotating - Update-NssmServiceParameter -parameter "AppRotateSeconds" -value 86400 @common_params - - #minimum size before rotating - Update-NssmServiceParameter -parameter "AppRotateBytes" -value $app_rotate_bytes @common_params - - - ############## DEPRECATED block since 2.8. Remove in 2.12 ############## - Update-NssmServiceParameter -parameter "DependOnService" -arguments $dependencies @common_params - if ($user) { - $fullUser = $user - if (-Not($user.contains("@")) -And ($user.Split("\").count -eq 1)) { - $fullUser = ".\" + $user - } - - # Use custom compare callback to test only the username (and not the password) - Update-NssmServiceParameter -parameter "ObjectName" -arguments @($fullUser, $password) -compare {param($actual,$expected) $actual[0] -eq $expected[0]} @common_params - } - $mappedMode = $start_modes_map.$startMode - Update-NssmServiceParameter -parameter "Start" -value $mappedMode @common_params - if ($state -in "stopped","restarted") { - Stop-NssmService @common_params - } - - if($state -in "started","restarted") { - Start-NssmService @common_params - } - ######################################################################## - - # Added per users` requests - if ($null -ne $app_stop_method_console) - { - Update-NssmServiceParameter -parameter "AppStopMethodConsole" -value $app_stop_method_console @common_params - } - - if ($null -ne $app_stop_method_skip) - { - Update-NssmServiceParameter -parameter "AppStopMethodSkip" -value $app_stop_method_skip @common_params - } - } -} - -if ($diff_mode -and $result.changed -eq $true) { - $result.diff = @{ - prepared = $diff_text - } -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_nssm.py b/lib/ansible/modules/windows/win_nssm.py deleted file mode 100644 index 1d15676e91e..00000000000 --- a/lib/ansible/modules/windows/win_nssm.py +++ /dev/null @@ -1,217 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Heyo -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_nssm -version_added: "2.0" -short_description: Install a service using NSSM -description: - - Install a Windows service using the NSSM wrapper. - - NSSM is a service helper which doesn't suck. See U(https://nssm.cc/) for more information. -requirements: - - "nssm >= 2.24.0 # (install via M(win_chocolatey)) C(win_chocolatey: name=nssm)" -options: - name: - description: - - Name of the service to operate on. - type: str - required: true - state: - description: - - State of the service on the system. - - Values C(started), C(stopped), and C(restarted) are deprecated since v2.8, - please use the M(win_service) module instead to start, stop or restart the service. - type: str - choices: [ absent, present, started, stopped, restarted ] - default: present - application: - description: - - The application binary to run as a service - - Required when I(state) is C(present), C(started), C(stopped), or C(restarted). - type: path - executable: - description: - - The location of the NSSM utility (in case it is not located in your PATH). - type: path - default: nssm.exe - version_added: "2.8.0" - description: - description: - - The description to set for the service. - type: str - version_added: "2.8.0" - display_name: - description: - - The display name to set for the service. - type: str - version_added: "2.8.0" - working_directory: - version_added: "2.8.0" - description: - - The working directory to run the service executable from (defaults to the directory containing the application binary) - type: path - aliases: [ app_directory, chdir ] - stdout_file: - description: - - Path to receive output. - type: path - stderr_file: - description: - - Path to receive error output. - type: path - app_parameters: - description: - - A string representing a dictionary of parameters to be passed to the application when it starts. - - DEPRECATED since v2.8, please use I(arguments) instead. - - This is mutually exclusive with I(arguments). - type: str - arguments: - description: - - Parameters to be passed to the application when it starts. - - This can be either a simple string or a list. - - This parameter was renamed from I(app_parameters_free_form) in 2.8. - - This is mutually exclusive with I(app_parameters). - aliases: [ app_parameters_free_form ] - type: str - version_added: "2.3" - dependencies: - description: - - Service dependencies that has to be started to trigger startup, separated by comma. - - DEPRECATED since v2.8, please use the M(win_service) module instead. - type: list - user: - description: - - User to be used for service startup. - - DEPRECATED since v2.8, please use the M(win_service) module instead. - type: str - password: - description: - - Password to be used for service startup. - - DEPRECATED since v2.8, please use the M(win_service) module instead. - type: str - start_mode: - description: - - If C(auto) is selected, the service will start at bootup. - - C(delayed) causes a delayed but automatic start after boot (added in version 2.5). - - C(manual) means that the service will start only when another service needs it. - - C(disabled) means that the service will stay off, regardless if it is needed or not. - - DEPRECATED since v2.8, please use the M(win_service) module instead. - type: str - choices: [ auto, delayed, disabled, manual ] - default: auto - app_rotate_bytes: - description: - - NSSM will not rotate any file which is smaller than the configured number of bytes. - type: int - default: 104858 - version_added: "2.10" - app_rotate_online: - description: - - If set to 1, nssm can rotate files which grow to the configured file size limit while the service is running. - type: int - choices: - - 0 - - 1 - default: 0 - version_added: "2.10" - app_stop_method_console: - description: - - Time to wait after sending Control-C. - type: int - version_added: "2.10" - app_stop_method_skip: - description: - - To disable service shutdown methods, set to the sum of one or more of the numbers - - 1 - Don't send Control-C to the console. - - 2 - Don't send WM_CLOSE to windows. - - 4 - Don't send WM_QUIT to threads. - - 8 - Don't call TerminateProcess(). - type: int - choices: - - 1 - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 - - 8 - - 9 - - 10 - - 11 - - 12 - - 13 - - 14 - - 15 - version_added: "2.10" -seealso: - - module: win_service -notes: - - The service will NOT be started after its creation when C(state=present). - - Once the service is created, you can use the M(win_service) module to start it or configure - some additionals properties, such as its startup type, dependencies, service account, and so on. -author: - - Adam Keech (@smadam813) - - George Frank (@georgefrank) - - Hans-Joachim Kliemeck (@h0nIg) - - Michael Wild (@themiwi) - - Kevin Subileau (@ksubileau) - - Shachaf Goldstein (@Shachaf92) -''' - -EXAMPLES = r''' -- name: Install the foo service - win_nssm: - name: foo - application: C:\windows\foo.exe - -# This will yield the following command: C:\windows\foo.exe bar "true" -- name: Install the Consul service with a list of parameters - win_nssm: - name: Consul - application: C:\consul\consul.exe - arguments: - - agent - - -config-dir=C:\consul\config - -# This is strictly equivalent to the previous example -- name: Install the Consul service with an arbitrary string of parameters - win_nssm: - name: Consul - application: C:\consul\consul.exe - arguments: agent -config-dir=C:\consul\config - - -# Install the foo service, and then configure and start it with win_service -- name: Install the foo service, redirecting stdout and stderr to the same file - win_nssm: - name: foo - application: C:\windows\foo.exe - stdout_file: C:\windows\foo.log - stderr_file: C:\windows\foo.log - -- name: Configure and start the foo service using win_service - win_service: - name: foo - dependencies: [ adf, tcpip ] - username: foouser - password: secret - start_mode: manual - state: started - -- name: Remove the foo service - win_nssm: - name: foo - state: absent -''' diff --git a/lib/ansible/modules/windows/win_pagefile.ps1 b/lib/ansible/modules/windows/win_pagefile.ps1 deleted file mode 100644 index 2c37f200c1b..00000000000 --- a/lib/ansible/modules/windows/win_pagefile.ps1 +++ /dev/null @@ -1,202 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Liran Nisanov -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -######## - -Function Remove-Pagefile($path, $whatif) -{ - Get-CIMInstance Win32_PageFileSetting | Where-Object { $_.Name -eq $path } | Remove-CIMInstance -WhatIf:$whatif -} - -Function Get-Pagefile($path) -{ - Get-CIMInstance Win32_PageFileSetting | Where-Object { $_.Name -eq $path } -} - -######## - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name '_ansible_check_mode' -type 'bool' -default $false - -$automatic = Get-AnsibleParam -obj $params -name "automatic" -type "bool" -$drive = Get-AnsibleParam -obj $params -name "drive" -type "str" -$fullPath = $drive + ":\pagefile.sys" -$initialSize = Get-AnsibleParam -obj $params -name "initial_size" -type "int" -$maximumSize = Get-AnsibleParam -obj $params -name "maximum_size" -type "int" -$override = Get-AnsibleParam -obj $params -name "override" -type "bool" -default $true -$removeAll = Get-AnsibleParam -obj $params -name "remove_all" -type "bool" -default $false -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "query" -validateset "present","absent","query" -$systemManaged = Get-AnsibleParam -obj $params -name "system_managed" -type "bool" -default $false -$testPath = Get-AnsibleParam -obj $params -name "test_path" -type "bool" -default $true - -$result = @{ - changed = $false -} - -if ($removeAll) { - $currentPageFiles = Get-CIMInstance Win32_PageFileSetting - if ($null -ne $currentPageFiles) { - $currentPageFiles | Remove-CIMInstance -WhatIf:$check_mode > $null - $result.changed = $true - } -} - -if ($null -ne $automatic) { - # change autmoatic managed pagefile - try { - $computerSystem = Get-CIMInstance -Class win32_computersystem - } catch { - Fail-Json $result "Failed to query WMI computer system object $($_.Exception.Message)" - } - if ($computerSystem.AutomaticManagedPagefile -ne $automatic) { - if (-not $check_mode) { - try { - $computerSystem | Set-CimInstance -Property @{automaticmanagedpagefile="$automatic"} > $null - } catch { - Fail-Json $result "Failed to set AutomaticManagedPagefile $($_.Exception.Message)" - } - } - $result.changed = $true - } -} - -if ($state -eq "absent") { - # Remove pagefile - if ($null -ne (Get-Pagefile $fullPath)) - { - try { - Remove-Pagefile $fullPath -whatif:$check_mode - } catch { - Fail-Json $result "Failed to remove pagefile $($_.Exception.Message)" - } - $result.changed = $true - } -} elseif ($state -eq "present") { - # Remove current pagefile - if ($override) { - if ($null -ne (Get-Pagefile $fullPath)) - { - try { - Remove-Pagefile $fullPath -whatif:$check_mode - } catch { - Fail-Json $result "Failed to remove current pagefile $($_.Exception.Message)" - } - $result.changed = $true - } - } - - # Make sure drive is accessible - if (($test_path) -and (-not (Test-Path "${drive}:"))) { - Fail-Json $result "Unable to access '${drive}:' drive" - } - - $curPagefile = Get-Pagefile $fullPath - - # Set pagefile - if ($null -eq $curPagefile) { - try { - $pagefile = New-CIMInstance -Class Win32_PageFileSetting -Arguments @{name = $fullPath;} -WhatIf:$check_mode - } catch { - Fail-Json $result "Failed to create pagefile $($_.Exception.Message)" - } - if (-not ($systemManaged -or $check_mode)) { - try { - $pagefile | Set-CimInstance -Property @{ InitialSize = $initialSize; MaximumSize = $maximumSize} - } catch { - $originalExceptionMessage = $($_.Exception.Message) - # Try workaround before failing - try { - Remove-Pagefile $fullPath -whatif:$check_mode - } catch { - Fail-Json $result "Failed to remove pagefile before workaround $($_.Exception.Message) Original exception: $originalExceptionMessage" - } - try { - $pagingFilesValues = (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management").PagingFiles - } catch { - Fail-Json $result "Failed to get pagefile settings from the registry for workaround $($_.Exception.Message) Original exception: $originalExceptionMessage" - } - $pagingFilesValues += "$fullPath $initialSize $maximumSize" - try { - Set-ItemProperty -LiteralPath "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" "PagingFiles" $pagingFilesValues - } catch { - Fail-Json $result "Failed to set pagefile settings to the registry for workaround $($_.Exception.Message) Original exception: $originalExceptionMessage" - } - } - } - $result.changed = $true - }else - { - $CurPageFileSystemManaged = (Get-CimInstance -ClassName win32_Pagefile -Property 'System' -Filter "name='$($fullPath.Replace('\','\\'))'").System - if ((-not $check_mode) -and - -not ($systemManaged -or $CurPageFileSystemManaged) -and - ( ($curPagefile.InitialSize -ne $initialSize) -or - ($curPagefile.maximumSize -ne $maximumSize))) - { - $curPagefile.InitialSize = $initialSize - $curPagefile.MaximumSize = $maximumSize - try { - $curPagefile.Put() | out-null - } catch { - $originalExceptionMessage = $($_.Exception.Message) - # Try workaround before failing - try { - Remove-Pagefile $fullPath -whatif:$check_mode - } catch { - Fail-Json $result "Failed to remove pagefile before workaround $($_.Exception.Message) Original exception: $originalExceptionMessage" - } - try { - $pagingFilesValues = (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management").PagingFiles - } catch { - Fail-Json $result "Failed to get pagefile settings from the registry for workaround $($_.Exception.Message) Original exception: $originalExceptionMessage" - } - $pagingFilesValues += "$fullPath $initialSize $maximumSize" - try { - Set-ItemProperty -LiteralPath "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "PagingFiles" -Value $pagingFilesValues - } catch { - Fail-Json $result "Failed to set pagefile settings to the registry for workaround $($_.Exception.Message) Original exception: $originalExceptionMessage" - } - } - $result.changed = $true - } - } -} elseif ($state -eq "query") { - $result.pagefiles = @() - - if ($null -eq $drive) { - try { - $pagefiles = Get-CIMInstance Win32_PageFileSetting - } catch { - Fail-Json $result "Failed to query all pagefiles $($_.Exception.Message)" - } - } else { - try { - $pagefiles = Get-Pagefile $fullPath - } catch { - Fail-Json $result "Failed to query specific pagefile $($_.Exception.Message)" - } - } - - # Get all pagefiles - foreach ($currentPagefile in $pagefiles) { - $currentPagefileObject = @{ - name = $currentPagefile.Name - initial_size = $currentPagefile.InitialSize - maximum_size = $currentPagefile.MaximumSize - caption = $currentPagefile.Caption - description = $currentPagefile.Description - } - $result.pagefiles += ,$currentPagefileObject - } - - # Get automatic managed pagefile state - try { - $result.automatic_managed_pagefiles = (Get-CIMInstance -Class win32_computersystem).AutomaticManagedPagefile - } catch { - Fail-Json $result "Failed to query automatic managed pagefile state $($_.Exception.Message)" - } -} -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_pagefile.py b/lib/ansible/modules/windows/win_pagefile.py deleted file mode 100644 index af65d97772d..00000000000 --- a/lib/ansible/modules/windows/win_pagefile.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Liran Nisanov -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_pagefile -version_added: "2.4" -short_description: Query or change pagefile configuration -description: - - Query current pagefile configuration. - - Enable/Disable AutomaticManagedPagefile. - - Create new or override pagefile configuration. -options: - drive: - description: - - The drive of the pagefile. - type: str - initial_size: - description: - - The initial size of the pagefile in megabytes. - type: int - maximum_size: - description: - - The maximum size of the pagefile in megabytes. - type: int - override: - description: - - Override the current pagefile on the drive. - type: bool - default: yes - system_managed: - description: - - Configures current pagefile to be managed by the system. - type: bool - default: no - automatic: - description: - - Configures AutomaticManagedPagefile for the entire system. - type: bool - remove_all: - description: - - Remove all pagefiles in the system, not including automatic managed. - type: bool - default: no - test_path: - description: - - Use Test-Path on the drive to make sure the drive is accessible before creating the pagefile. - type: bool - default: yes - state: - description: - - State of the pagefile. - type: str - choices: [ absent, present, query ] - default: query -notes: -- There is difference between automatic managed pagefiles that configured once for the entire system and system managed pagefile that configured per pagefile. -- InitialSize 0 and MaximumSize 0 means the pagefile is managed by the system. -- Value out of range exception may be caused by several different issues, two common problems - No such drive, Pagefile size is too small. -- Setting a pagefile when AutomaticManagedPagefile is on will disable the AutomaticManagedPagefile. -author: -- Liran Nisanov (@LiranNis) -''' - -EXAMPLES = r''' -- name: Query pagefiles configuration - win_pagefile: - -- name: Query C pagefile - win_pagefile: - drive: C - -- name: Set C pagefile, don't override if exists - win_pagefile: - drive: C - initial_size: 1024 - maximum_size: 1024 - override: no - state: present - -- name: Set C pagefile, override if exists - win_pagefile: - drive: C - initial_size: 1024 - maximum_size: 1024 - state: present - -- name: Remove C pagefile - win_pagefile: - drive: C - state: absent - -- name: Remove all current pagefiles, enable AutomaticManagedPagefile and query at the end - win_pagefile: - remove_all: yes - automatic: yes - -- name: Remove all pagefiles disable AutomaticManagedPagefile and set C pagefile - win_pagefile: - drive: C - initial_size: 2048 - maximum_size: 2048 - remove_all: yes - automatic: no - state: present - -- name: Set D pagefile, override if exists - win_pagefile: - drive: d - initial_size: 1024 - maximum_size: 1024 - state: present -''' - -RETURN = r''' -automatic_managed_pagefiles: - description: Whether the pagefiles is automatically managed. - returned: When state is query. - type: bool - sample: true -pagefiles: - description: Contains caption, description, initial_size, maximum_size and name for each pagefile in the system. - returned: When state is query. - type: list - sample: - [{"caption": "c:\\ 'pagefile.sys'", "description": "'pagefile.sys' @ c:\\", "initial_size": 2048, "maximum_size": 2048, "name": "c:\\pagefile.sys"}, - {"caption": "d:\\ 'pagefile.sys'", "description": "'pagefile.sys' @ d:\\", "initial_size": 1024, "maximum_size": 1024, "name": "d:\\pagefile.sys"}] - -''' diff --git a/lib/ansible/modules/windows/win_partition.ps1 b/lib/ansible/modules/windows/win_partition.ps1 deleted file mode 100644 index 2bd1ffc0d37..00000000000 --- a/lib/ansible/modules/windows/win_partition.ps1 +++ /dev/null @@ -1,326 +0,0 @@ -#!powershell - -# Copyright: (c) 2018, Varun Chopra (@chopraaa) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#AnsibleRequires -OSVersion 6.2 - -Set-StrictMode -Version 2 - -$ErrorActionPreference = "Stop" - -$spec = @{ - options = @{ - state = @{ type = "str"; choices = "absent", "present"; default = "present" } - drive_letter = @{ type = "str" } - disk_number = @{ type = "int" } - partition_number = @{ type = "int" } - partition_size = @{ type = "str" } - read_only = @{ type = "bool" } - active = @{ type = "bool" } - hidden = @{ type = "bool" } - offline = @{ type = "bool" } - mbr_type = @{ type = "str"; choices = "fat12", "fat16", "extended", "huge", "ifs", "fat32" } - gpt_type = @{ type = "str"; choices = "system_partition", "microsoft_reserved", "basic_data", "microsoft_recovery" } - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$state = $module.Params.state -$drive_letter = $module.Params.drive_letter -$disk_number = $module.Params.disk_number -$partition_number = $module.Params.partition_number -$partition_size = $module.Params.partition_size -$read_only = $module.Params.read_only -$active = $module.Params.active -$hidden = $module.Params.hidden -$offline = $module.Params.offline -$mbr_type = $module.Params.mbr_type -$gpt_type = $module.Params.gpt_type - -$size_is_maximum = $false -$ansible_partition = $false -$ansible_partition_size = $null -$partition_style = $null - -$gpt_styles = @{ - system_partition = "c12a7328-f81f-11d2-ba4b-00a0c93ec93b" - microsoft_reserved = "e3c9e316-0b5c-4db8-817d-f92df00215ae" - basic_data = "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" - microsoft_recovery = "de94bba4-06d1-4d40-a16a-bfd50179d6ac" -} - -$mbr_styles = @{ - fat12 = 1 - fat16 = 4 - extended = 5 - huge = 6 - ifs = 7 - fat32 = 12 -} - -function Convert-SizeToBytes { - param( - $Size, - $Units - ) - - switch ($Units) { - "B" { return $Size } - "KB" { return 1000 * $Size } - "KiB" { return 1024 * $Size } - "MB" { return [Math]::Pow(1000, 2) * $Size } - "MiB" { return [Math]::Pow(1024, 2) * $Size } - "GB" { return [Math]::Pow(1000, 3) * $Size } - "GiB" { return [Math]::Pow(1024, 3) * $Size } - "TB" { return [Math]::Pow(1000, 4) * $Size } - "TiB" { return [Math]::Pow(1024, 4) * $Size } - } -} - -if ($null -ne $partition_size) { - if ($partition_size -eq -1) { - $size_is_maximum = $true - } - elseif ($partition_size -match '^(?[0-9]+)[ ]*(?b|kb|kib|mb|mib|gb|gib|tb|tib)$') { - $ansible_partition_size = Convert-SizeToBytes -Size $Matches.Size -Units $Matches.Units - } - else { - $module.FailJson("Invalid partition size. B, KB, KiB, MB, MiB, GB, GiB, TB, TiB are valid partition size units") - } -} - -# If partition_exists, we can change or delete it; otherwise we only need the disk to create a new partition -if ($null -ne $disk_number -and $null -ne $partition_number) { - $ansible_partition = Get-Partition -DiskNumber $disk_number -PartitionNumber $partition_number -ErrorAction SilentlyContinue -} -# Check if drive_letter is either auto-assigned or a character from A-Z -elseif ($drive_letter -and -not ($disk_number -and $partition_number)) { - if ($drive_letter -eq "auto" -or $drive_letter -match "^[a-zA-Z]$") { - $ansible_partition = Get-Partition -DriveLetter $drive_letter -ErrorAction SilentlyContinue - } - else { - $module.FailJson("Incorrect usage of drive_letter: specify a drive letter from A-Z or use 'auto' to automatically assign a drive letter") - } -} -elseif ($disk_number) { - try { - Get-Disk -Number $disk_number | Out-Null - } catch { - $module.FailJson("Specified disk does not exist") - } -} -else { - $module.FailJson("You must provide disk_number, partition_number") -} - -# Partition can't have two partition styles -if ($null -ne $gpt_type -and $null -ne $mbr_type) { - $module.FailJson("Cannot specify both GPT and MBR partition styles. Check which partition style is supported by the disk") -} - -function New-AnsiblePartition { - param( - $DiskNumber, - $Letter, - $SizeMax, - $Size, - $MbrType, - $GptType, - $Style - ) - - $parameters = @{ - DiskNumber = $DiskNumber - } - - if ($null -ne $Letter) { - switch ($Letter) { - "auto" { - $parameters.Add("AssignDriveLetter", $True) - } - default { - $parameters.Add("DriveLetter", $Letter) - } - } - } - - if ($null -ne $Size) { - $parameters.Add("Size", $Size) - } - - if ($null -ne $MbrType) { - $parameters.Add("MbrType", $Style) - } - - if ($null -ne $GptType) { - $parameters.Add("GptType", $Style) - } - - try { - $new_partition = New-Partition @parameters - } catch { - $module.FailJson("Unable to create a new partition: $($_.Exception.Message)", $_) - } - - return $new_partition -} - - -function Set-AnsiblePartitionState { - param( - $hidden, - $read_only, - $active, - $partition - ) - - $parameters = @{ - DiskNumber = $partition.DiskNumber - PartitionNumber = $partition.PartitionNumber - } - - if ($hidden -NotIn ($null, $partition.IsHidden)) { - $parameters.Add("IsHidden", $hidden) - } - - if ($read_only -NotIn ($null, $partition.IsReadOnly)) { - $parameters.Add("IsReadOnly", $read_only) - } - - if ($active -NotIn ($null, $partition.IsActive)) { - $parameters.Add("IsActive", $active) - } - - try { - Set-Partition @parameters - } catch { - $module.FailJson("Error changing state of partition: $($_.Exception.Message)", $_) - } -} - - -if ($ansible_partition) { - if ($state -eq "absent") { - try { - Remove-Partition -DiskNumber $ansible_partition.DiskNumber -PartitionNumber $ansible_partition.PartitionNumber -Confirm:$false -WhatIf:$module.CheckMode - } catch { - $module.FailJson("There was an error removing the partition: $($_.Exception.Message)", $_) - } - $module.Result.changed = $true - } - else { - - if ($null -ne $gpt_type -and $gpt_styles.$gpt_type -ne $ansible_partition.GptType) { - $module.FailJson("gpt_type is not a valid parameter for existing partitions") - } - if ($null -ne $mbr_type -and $mbr_styles.$mbr_type -ne $ansible_partition.MbrType) { - $module.FailJson("mbr_type is not a valid parameter for existing partitions") - } - - if ($partition_size) { - try { - $max_supported_size = (Get-PartitionSupportedSize -DiskNumber $ansible_partition.DiskNumber -PartitionNumber $ansible_partition.PartitionNumber).SizeMax - } catch { - $module.FailJson("Unable to get maximum supported partition size: $($_.Exception.Message)", $_) - } - if ($size_is_maximum) { - $ansible_partition_size = $max_supported_size - } - if ($ansible_partition_size -ne $ansible_partition.Size -and ($ansible_partition_size - $ansible_partition.Size -gt 1049000 -or $ansible_partition.Size - $ansible_partition_size -gt 1049000)) { - if ($ansible_partition.IsReadOnly) { - $module.FailJson("Unable to resize partition: Partition is read only") - } else { - try { - Resize-Partition -DiskNumber $ansible_partition.DiskNumber -PartitionNumber $ansible_partition.PartitionNumber -Size $ansible_partition_size -WhatIf:$module.CheckMode - } catch { - $module.FailJson("Unable to change partition size: $($_.Exception.Message)", $_) - } - $module.Result.changed = $true - } - } elseif ($ansible_partition_size -gt $max_supported_size) { - $module.FailJson("Specified partition size exceeds size supported by the partition") - } - } - - if ($drive_letter -NotIn ("auto", $null, $ansible_partition.DriveLetter)) { - if (-not $module.CheckMode) { - try { - Set-Partition -DiskNumber $ansible_partition.DiskNumber -PartitionNumber $ansible_partition.PartitionNumber -NewDriveLetter $drive_letter - } catch { - $module.FailJson("Unable to change drive letter: $($_.Exception.Message)", $_) - } - } - $module.Result.changed = $true - } - } -} -else { - if ($state -eq "present") { - if ($null -eq $disk_number) { - $module.FailJson("Missing required parameter: disk_number") - } - if ($null -eq $ansible_partition_size -and -not $size_is_maximum){ - $module.FailJson("Missing required parameter: partition_size") - } - if (-not $size_is_maximum) { - try { - $max_supported_size = (Get-Disk -Number $disk_number).LargestFreeExtent - } catch { - $module.FailJson("Unable to get maximum size supported by disk: $($_.Exception.Message)", $_) - } - - if ($ansible_partition_size -gt $max_supported_size) { - $module.FailJson("Partition size is not supported by disk. Use partition_size: -1 to get maximum size") - } - } else { - $ansible_partition_size = (Get-Disk -Number $disk_number).LargestFreeExtent - } - - $supp_part_type = (Get-Disk -Number $disk_number).PartitionStyle - if ($null -ne $mbr_type) { - if ($supp_part_type -eq "MBR" -and $mbr_styles.ContainsKey($mbr_type)) { - $partition_style = $mbr_styles.$mbr_type - } else { - $module.FailJson("Incorrect partition style specified") - } - } - if ($null -ne $gpt_type) { - if ($supp_part_type -eq "GPT" -and $gpt_styles.ContainsKey($gpt_type)) { - $partition_style = $gpt_styles.$gpt_type - } else { - $module.FailJson("Incorrect partition style specified") - } - } - - if (-not $module.CheckMode) { - $ansible_partition = New-AnsiblePartition -DiskNumber $disk_number -Letter $drive_letter -Size $ansible_partition_size -MbrType $mbr_type -GptType $gpt_type -Style $partition_style - } - $module.Result.changed = $true - } -} - -if ($state -eq "present" -and $ansible_partition) { - if ($offline -NotIn ($null, $ansible_partition.IsOffline)) { - if (-not $module.CheckMode) { - try { - Set-Partition -DiskNumber $ansible_partition.DiskNumber -PartitionNumber $ansible_partition.PartitionNumber -IsOffline $offline - } catch { - $module.FailJson("Error setting partition offline: $($_.Exception.Message)", $_) - } - } - $module.Result.changed = $true - } - - if ($hidden -NotIn ($null, $ansible_partition.IsHidden) -or $read_only -NotIn ($null, $ansible_partition.IsReadOnly) -or $active -NotIn ($null, $ansible_partition.IsActive)) { - if (-not $module.CheckMode) { - Set-AnsiblePartitionState -hidden $hidden -read_only $read_only -active $active -partition $ansible_partition - } - $module.Result.changed = $true - } -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_partition.py b/lib/ansible/modules/windows/win_partition.py deleted file mode 100644 index 18d45282d4e..00000000000 --- a/lib/ansible/modules/windows/win_partition.py +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Varun Chopra (@chopraaa) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = { - 'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community' -} - -DOCUMENTATION = r''' ---- -module: win_partition -version_added: '2.8' -short_description: Creates, changes and removes partitions on Windows Server -description: - - The M(win_partition) module can create, modify or delete a partition on a disk -options: - state: - description: - - Used to specify the state of the partition. Use C(absent) to specify if a partition should be removed - and C(present) to specify if the partition should be created or updated. - type: str - choices: [ absent, present] - default: present - drive_letter: - description: - - Used for accessing partitions if I(disk_number) and I(partition_number) are not provided. - - Use C(auto) for automatically assigning a drive letter, or a letter A-Z for manually assigning a drive letter to a new partition. - If not specified, no drive letter is assigned when creating a new partition. - type: str - disk_number: - description: - - Disk number is mandatory for creating new partitions. - - A combination of I(disk_number) and I(partition_number) can be used to specify the partition instead of I(drive_letter) if required. - type: int - partition_number: - description: - - Used in conjunction with I(disk_number) to uniquely identify a partition. - type: int - partition_size: - description: - - Specify size of the partition in B, KB, KiB, MB, MiB, GB, GiB, TB or TiB. Use -1 to specify maximum supported size. - - Partition size is mandatory for creating a new partition but not for updating or deleting a partition. - - The decimal SI prefixes kilo, mega, giga, tera, etc., are powers of 10^3 = 1000. The binary prefixes kibi, mebi, gibi, tebi, etc. - respectively refer to the corresponding power of 2^10 = 1024. - Thus, a gigabyte (GB) is 1000000000 (1000^3) bytes while 1 gibibyte (GiB) is 1073741824 (1024^3) bytes. - type: str - read_only: - description: - - Make the partition read only, restricting changes from being made to the partition. - type: bool - active: - description: - - Specifies if the partition is active and can be used to start the system. This property is only valid when the disk's partition style is MBR. - type: bool - hidden: - description: - - Hides the target partition, making it undetectable by the mount manager. - type: bool - offline: - description: - - Sets the partition offline. - - Adding a mount point (such as a drive letter) will cause the partition to go online again. - type: bool - required: no - mbr_type: - description: - - Specify the partition's MBR type if the disk's partition style is MBR. - - This only applies to new partitions. - - This does not relate to the partitions file system formatting. - type: str - choices: [ fat12, fat16, extended, huge, ifs, fat32 ] - gpt_type: - description: - - Specify the partition's GPT type if the disk's partition style is GPT. - - This only applies to new partitions. - - This does not relate to the partitions file system formatting. - type: str - choices: [ system_partition, microsoft_reserved, basic_data, microsoft_recovery ] - -notes: - - A minimum Operating System Version of 6.2 is required to use this module. To check if your OS is compatible, see - U(https://docs.microsoft.com/en-us/windows/desktop/sysinfo/operating-system-version). - - This module cannot be used for removing the drive letter associated with a partition, initializing a disk or, file system formatting. - - Idempotence works only if you're specifying a drive letter or other unique attributes such as a combination of disk number and partition number. - - For more information, see U(https://msdn.microsoft.com/en-us/library/windows/desktop/hh830524.aspx). -author: - - Varun Chopra (@chopraaa) -''' - -EXAMPLES = r''' -- name: Create a partition with drive letter D and size 5 GiB - win_partition: - drive_letter: D - partition_size: 5 GiB - disk_number: 1 - -- name: Resize previously created partition to it's maximum size and change it's drive letter to E - win_partition: - drive_letter: E - partition_size: -1 - partition_number: 1 - disk_number: 1 - -- name: Delete partition - win_partition: - disk_number: 1 - partition_number: 1 - state: absent -''' - -RETURN = r''' -# -''' diff --git a/lib/ansible/modules/windows/win_pester.ps1 b/lib/ansible/modules/windows/win_pester.ps1 deleted file mode 100644 index f3f2ebdcedc..00000000000 --- a/lib/ansible/modules/windows/win_pester.ps1 +++ /dev/null @@ -1,116 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Erwan Quelin (@equelin) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic - -$spec = @{ - options = @{ - output_file = @{ type = "str" } - output_format = @{ type = "str"; default = "NunitXML" } - path = @{ type = "str"; required = $true } - tags = @{ type = "list"; elements = "str" } - test_parameters = @{ type = "dict" } - version = @{ type = "str"; aliases = @(,"minimum_version") } - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$output_file = $module.Params.output_file -$output_format = $module.Params.output_format -$path = $module.Params.path -$tags = $module.Params.tags -$test_parameters = $module.Params.test_parameters -$version = $module.Params.version - -Try { - $version = [version]$version -} -Catch { - $module.FailJson("Value '$version' for parameter 'minimum_version' is not a valid version format") -} - -# Make sure path is a real path -Try { - $path = $path.TrimEnd("\") - $path = (Get-item -LiteralPath $path).FullName -} -Catch { - $module.FailJson("Cannot find file or directory: '$path' as it does not exist") -} - -# Import Pester module if available -$Pester = 'Pester' - -If (-not (Get-Module -Name $Pester -ErrorAction SilentlyContinue)) { - If (Get-Module -Name $Pester -ListAvailable -ErrorAction SilentlyContinue) { - Import-Module $Pester - } else { - $module.FailJson("Cannot find module: $Pester. Check if pester is installed, and if it is not, install using win_psmodule or win_chocolatey.") - } -} - -# Add actual pester's module version in the ansible's result variable -$Pester_version = (Get-Module -Name $Pester).Version.ToString() -$module.Result.pester_version = $Pester_version - -# Test if the Pester module is available with a version greater or equal than the one specified in the $version parameter -If ((-not (Get-Module -Name $Pester -ErrorAction SilentlyContinue | Where-Object {$_.Version -ge $version})) -and ($version)) { - $module.FailJson("$Pester version is not greater or equal to $version") -} - -#Prepare Invoke-Pester parameters depending of the Pester's version. -#Invoke-Pester output deactivation behave differently depending on the Pester's version -If ($module.Result.pester_version -ge "4.0.0") { - $Parameters = @{ - "show" = "none" - "PassThru" = $True - } -} else { - $Parameters = @{ - "quiet" = $True - "PassThru" = $True - } -} - -if($tags.count){ - $Parameters.Tag = $tags -} - -if($output_file){ - $Parameters.OutputFile = $output_file - $Parameters.OutputFormat = $output_format -} - -# Run Pester tests -If (Test-Path -LiteralPath $path -PathType Leaf) { - $test_parameters_check_mode_msg = '' - if ($test_parameters.keys.count) { - $Parameters.Script = @{Path = $Path ; Parameters = $test_parameters } - $test_parameters_check_mode_msg = " with $($test_parameters.keys -join ',') parameters" - } - else { - $Parameters.Script = $Path - } - - if ($module.CheckMode) { - $module.Result.output = "Run pester test in the file: $path$test_parameters_check_mode_msg" - } else { - $module.Result.output = Invoke-Pester @Parameters - } -} else { - $Parameters.Script = $path - - if ($module.CheckMode) { - $module.Result.output = "Run Pester test(s): $path" - } else { - $module.Result.output = Invoke-Pester @Parameters - } -} - -$module.Result.changed = $true - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_pester.py b/lib/ansible/modules/windows/win_pester.py deleted file mode 100644 index c17009fb708..00000000000 --- a/lib/ansible/modules/windows/win_pester.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - - -DOCUMENTATION = r''' ---- -module: win_pester -short_description: Run Pester tests on Windows hosts -version_added: "2.6" -description: - - Run Pester tests on Windows hosts. - - Test files have to be available on the remote host. -requirements: - - Pester -options: - path: - description: - - Path to a pester test file or a folder where tests can be found. - - If the path is a folder, the module will consider all ps1 files as Pester tests. - type: str - required: true - tags: - description: - - Runs only tests in Describe blocks with specified Tags values. - - Accepts multiple comma separated tags. - type: list - version_added: '2.9' - output_file: - description: - - Generates an output test report. - type: str - version_added: '2.10' - output_format: - description: - - Format of the test report to be generated. - - This parameter is to be used with output_file option. - type: str - default: NunitXML - version_added: '2.10' - test_parameters: - description: - - Allows to specify parameters to the test script. - type: dict - version_added: '2.9' - version: - description: - - Minimum version of the pester module that has to be available on the remote host. - type: str - aliases: - - minimum_version -author: - - Erwan Quelin (@equelin) - - Prasoon Karunan V (@prasoonkarunan) -''' - -EXAMPLES = r''' -- name: Get facts - setup: - -- name: Add Pester module - action: - module_name: "{{ 'win_psmodule' if ansible_powershell_version >= 5 else 'win_chocolatey' }}" - name: Pester - state: present - -- name: Run the pester test provided in the path parameter. - win_pester: - path: C:\Pester - -- name: Run the pester tests only for the tags specified. - win_pester: - path: C:\Pester\TestScript.tests - tags: CI,UnitTests - -# Run pesters tests files that are present in the specified folder -# ensure that the pester module version available is greater or equal to the version parameter. -- name: Run the pester test present in a folder and check the Pester module version. - win_pester: - path: C:\Pester\test01.test.ps1 - version: 4.1.0 - -- name: Run the pester test present in a folder with given script parameters. - win_pester: - path: C:\Pester\test04.test.ps1 - test_parameters: - Process: lsass - Service: bits - -- name: Run the pester test present in a folder and generate NunitXML test result.. - win_pester: - path: C:\Pester\test04.test.ps1 - output_file: c:\Pester\resullt\testresult.xml -''' - -RETURN = r''' -pester_version: - description: Version of the pester module found on the remote host. - returned: always - type: str - sample: 4.3.1 -output: - description: Results of the Pester tests. - returned: success - type: list - sample: false -''' diff --git a/lib/ansible/modules/windows/win_power_plan.ps1 b/lib/ansible/modules/windows/win_power_plan.ps1 deleted file mode 100644 index 9c4a871c397..00000000000 --- a/lib/ansible/modules/windows/win_power_plan.ps1 +++ /dev/null @@ -1,207 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.AddType - -$spec = @{ - options = @{ - name = @{ type = "str"; required = $true } - } - supports_check_mode = $true -} -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$name = $module.Params.name - -$module.Result.power_plan_name = $name -$module.Result.power_plan_enabled = $null -$module.Result.all_available_plans = $null - -Add-CSharpType -References @" -using System; -using System.Runtime.InteropServices; - -namespace Ansible.WinPowerPlan -{ - public enum AccessFlags : uint - { - AccessScheme = 16, - AccessSubgroup = 17, - AccessIndividualSetting = 18 - } - - public class NativeMethods - { - [DllImport("Kernel32.dll", SetLastError = true)] - public static extern IntPtr LocalFree( - IntPtr hMen); - - [DllImport("PowrProf.dll")] - public static extern UInt32 PowerEnumerate( - IntPtr RootPowerKey, - IntPtr SchemeGuid, - IntPtr SubGroupOfPowerSettingsGuid, - AccessFlags AccessFlags, - UInt32 Index, - IntPtr Buffer, - ref UInt32 BufferSize); - - [DllImport("PowrProf.dll")] - public static extern UInt32 PowerGetActiveScheme( - IntPtr UserRootPowerKey, - out IntPtr ActivePolicyGuid); - - [DllImport("PowrProf.dll")] - public static extern UInt32 PowerReadFriendlyName( - IntPtr RootPowerKey, - Guid SchemeGuid, - IntPtr SubGroupOfPowerSettingsGuid, - IntPtr PowerSettingGuid, - IntPtr Buffer, - ref UInt32 BufferSize); - - [DllImport("PowrProf.dll")] - public static extern UInt32 PowerSetActiveScheme( - IntPtr UserRootPowerKey, - Guid SchemeGuid); - } -} -"@ - -Function Get-LastWin32ErrorMessage { - param([Int]$ErrorCode) - $exp = New-Object -TypeName System.ComponentModel.Win32Exception -ArgumentList $ErrorCode - $error_msg = "{0} - (Win32 Error Code {1} - 0x{1:X8})" -f $exp.Message, $ErrorCode - return $error_msg -} - -Function Get-PlanName { - param([Guid]$Plan) - - $buffer_size = 0 - $buffer = [IntPtr]::Zero - [Ansible.WinPowerPlan.NativeMethods]::PowerReadFriendlyName([IntPtr]::Zero, $Plan, [IntPtr]::Zero, [IntPtr]::Zero, - $buffer, [ref]$buffer_size) > $null - - $buffer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($buffer_size) - try { - $res = [Ansible.WinPowerPlan.NativeMethods]::PowerReadFriendlyName([IntPtr]::Zero, $Plan, [IntPtr]::Zero, - [IntPtr]::Zero, $buffer, [ref]$buffer_size) - - if ($res -ne 0) { - $err_msg = Get-LastWin32ErrorMessage -ErrorCode $res - $module.FailJson("Failed to get name for power scheme $Plan - $err_msg") - } - - return [System.Runtime.InteropServices.Marshal]::PtrToStringUni($buffer) - } finally { - [System.Runtime.InteropServices.Marshal]::FreeHGlobal($buffer) - } -} - -Function Get-PowerPlans { - $plans = @{} - - $i = 0 - while ($true) { - $buffer_size = 0 - $buffer = [IntPtr]::Zero - $res = [Ansible.WinPowerPlan.NativeMethods]::PowerEnumerate([IntPtr]::Zero, [IntPtr]::Zero, [IntPtr]::Zero, - [Ansible.WinPowerPlan.AccessFlags]::AccessScheme, $i, $buffer, [ref]$buffer_size) - - if ($res -eq 259) { - # 259 == ERROR_NO_MORE_ITEMS, there are no more power plans to enumerate - break - } elseif ($res -notin @(0, 234)) { - # 0 == ERROR_SUCCESS and 234 == ERROR_MORE_DATA - $err_msg = Get-LastWin32ErrorMessage -ErrorCode $res - $module.FailJson("Failed to get buffer size on local power schemes at index $i - $err_msg") - } - - $buffer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($buffer_size) - try { - $res = [Ansible.WinPowerPlan.NativeMethods]::PowerEnumerate([IntPtr]::Zero, [IntPtr]::Zero, [IntPtr]::Zero, - [Ansible.WinPowerPlan.AccessFlags]::AccessScheme, $i, $buffer, [ref]$buffer_size) - - if ($res -eq 259) { - # Server 2008 does not return 259 in the first call above so we do an additional check here - break - } elseif ($res -notin @(0, 234, 259)) { - $err_msg = Get-LastWin32ErrorMessage -ErrorCode $res - $module.FailJson("Failed to enumerate local power schemes at index $i - $err_msg") - } - $scheme_guid = [System.Runtime.InteropServices.Marshal]::PtrToStructure($buffer, [Type][Guid]) - } finally { - [System.Runtime.InteropServices.Marshal]::FreeHGlobal($buffer) - } - $scheme_name = Get-PlanName -Plan $scheme_guid - $plans.$scheme_name = $scheme_guid - - $i += 1 - } - - return $plans -} - -Function Get-ActivePowerPlan { - $buffer = [IntPtr]::Zero - $res = [Ansible.WinPowerPlan.NativeMethods]::PowerGetActiveScheme([IntPtr]::Zero, [ref]$buffer) - if ($res -ne 0) { - $err_msg = Get-LastWin32ErrorMessage -ErrorCode $res - $module.FailJson("Failed to get the active power plan - $err_msg") - } - - try { - $active_guid = [System.Runtime.InteropServices.Marshal]::PtrToStructure($buffer, [Type][Guid]) - } finally { - [Ansible.WinPowerPlan.NativeMethods]::LocalFree($buffer) > $null - } - - return $active_guid -} - -Function Set-ActivePowerPlan { - [CmdletBinding(SupportsShouldProcess=$true)] - param([Guid]$Plan) - - $res = 0 - if ($PSCmdlet.ShouldProcess($Plan, "Set Power Plan")) { - $res = [Ansible.WinPowerPlan.NativeMethods]::PowerSetActiveScheme([IntPtr]::Zero, $Plan) - } - - if ($res -ne 0) { - $err_msg = Get-LastWin32ErrorMessage -ErrorCode $res - $module.FailJson("Failed to set the active power plan to $Plan - $err_msg") - } -} - -# Get all local power plans and the current active plan -$plans = Get-PowerPlans -$active_plan = Get-ActivePowerPlan -$module.Result.all_available_plans = @{} -foreach ($plan_info in $plans.GetEnumerator()) { - $module.Result.all_available_plans.($plan_info.Key) = $plan_info.Value -eq $active_plan -} - -if ($name -notin $plans.Keys) { - $module.FailJson("Defined power_plan: ($name) is not available") -} -$plan_guid = $plans.$name -$is_active = $active_plan -eq $plans.$name -$module.Result.power_plan_enabled = $is_active - -if (-not $is_active) { - Set-ActivePowerPlan -Plan $plan_guid -WhatIf:$module.CheckMode - $module.Result.changed = $true - $module.Result.power_plan_enabled = $true - foreach ($plan_info in $plans.GetEnumerator()) { - $is_active = $plan_info.Value -eq $plan_guid - $module.Result.all_available_plans.($plan_info.Key) = $is_active - } -} - -$module.ExitJson() - diff --git a/lib/ansible/modules/windows/win_power_plan.py b/lib/ansible/modules/windows/win_power_plan.py deleted file mode 100644 index 6f358993cc0..00000000000 --- a/lib/ansible/modules/windows/win_power_plan.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_power_plan -short_description: Changes the power plan of a Windows system -description: - - This module will change the power plan of a Windows system to the defined string. - - Windows defaults to C(balanced) which will cause CPU throttling. In some cases it can be preferable - to change the mode to C(high performance) to increase CPU performance. -version_added: "2.4" -options: - name: - description: - - String value that indicates the desired power plan. - - The power plan must already be present on the system. - - Commonly there will be options for C(balanced) and C(high performance). - type: str - required: yes -author: - - Noah Sparks (@nwsparks) -''' - -EXAMPLES = r''' -- name: Change power plan to high performance - win_power_plan: - name: high performance -''' - -RETURN = r''' -power_plan_name: - description: Value of the intended power plan. - returned: always - type: str - sample: balanced -power_plan_enabled: - description: State of the intended power plan. - returned: success - type: bool - sample: true -all_available_plans: - description: The name and enabled state of all power plans. - returned: always - type: dict - sample: | - { - "High performance": false, - "Balanced": true, - "Power saver": false - } -''' diff --git a/lib/ansible/modules/windows/win_product_facts.ps1 b/lib/ansible/modules/windows/win_product_facts.ps1 deleted file mode 100644 index 2fbf3341190..00000000000 --- a/lib/ansible/modules/windows/win_product_facts.ps1 +++ /dev/null @@ -1,85 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Dag Wieers (@dagwieers) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic - -# This modules does not accept any options -$spec = @{ - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -# First try to find the product key from ACPI -try { - $product_key = (Get-CimInstance -Class SoftwareLicensingService).OA3xOriginalProductKey -} catch { - $product_key = $null -} - -if (-not $product_key) { - # Else try to get it from the registry instead - try { - $data = Get-ItemPropertyValue -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion" -Name DigitalProductId - } catch { - $data = $null - } - - # And for Windows 2008 R2 - if (-not $data) { - try { - $data = Get-ItemPropertyValue -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion" -Name DigitalProductId4 - } catch { - $data = $null - } - } - - if ($data) { - $product_key = $null - $hexdata = $data[52..66] - $chardata = "B","C","D","F","G","H","J","K","M","P","Q","R","T","V","W","X","Y","2","3","4","6","7","8","9" - - # Decode base24 binary data - for ($i = 24; $i -ge 0; $i--) { - $k = 0 - for ($j = 14; $j -ge 0; $j--) { - $k = $k * 256 -bxor $hexdata[$j] - $hexdata[$j] = [math]::truncate($k / 24) - $k = $k % 24 - } - $product_key = $chardata[$k] + $product_key - if (($i % 5 -eq 0) -and ($i -ne 0)) { - $product_key = "-" + $product_key - } - } - } -} - -# Retrieve license information -$license_info = Get-CimInstance SoftwareLicensingProduct | Where-Object PartialProductKey - -$winlicense_status = switch ($license_info.LicenseStatus) { - 0 { "Unlicensed" } - 1 { "Licensed" } - 2 { "OOBGrace" } - 3 { "OOTGrace" } - 4 { "NonGenuineGrace" } - 5 { "Notification" } - 6 { "ExtendedGrace" } - default { $null } -} - -$winlicense_edition = $license_info.Name -$winlicense_channel = $license_info.ProductKeyChannel - -$module.Result.ansible_facts = @{ - ansible_os_product_id = (Get-CimInstance Win32_OperatingSystem).SerialNumber - ansible_os_product_key = $product_key - ansible_os_license_edition = $winlicense_edition - ansible_os_license_channel = $winlicense_channel - ansible_os_license_status = $winlicense_status -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_product_facts.py b/lib/ansible/modules/windows/win_product_facts.py deleted file mode 100644 index a85ffe8dece..00000000000 --- a/lib/ansible/modules/windows/win_product_facts.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Dag Wieers (@dagwieers) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_product_facts -short_description: Provides Windows product and license information -description: -- Provides Windows product and license information. -version_added: '2.5' -author: -- Dag Wieers (@dagwieers) -''' - -EXAMPLES = r''' -- name: Get product id and product key - win_product_facts: - -- name: Display Windows edition - debug: - var: ansible_os_license_edition - -- name: Display Windows license status - debug: - var: ansible_os_license_status -''' - -RETURN = r''' -ansible_facts: - description: Dictionary containing all the detailed information about the Windows product and license. - returned: always - type: complex - contains: - ansible_os_license_channel: - description: The Windows license channel. - returned: always - type: str - sample: Volume:MAK - version_added: '2.8' - ansible_os_license_edition: - description: The Windows license edition. - returned: always - type: str - sample: Windows(R) ServerStandard edition - version_added: '2.8' - ansible_os_license_status: - description: The Windows license status. - returned: always - type: str - sample: Licensed - version_added: '2.8' - ansible_os_product_id: - description: The Windows product ID. - returned: always - type: str - sample: 00326-10000-00000-AA698 - ansible_os_product_key: - description: The Windows product key. - returned: always - type: str - sample: T49TD-6VFBW-VV7HY-B2PXY-MY47H -''' diff --git a/lib/ansible/modules/windows/win_psexec.ps1 b/lib/ansible/modules/windows/win_psexec.ps1 deleted file mode 100644 index 04a512706e1..00000000000 --- a/lib/ansible/modules/windows/win_psexec.ps1 +++ /dev/null @@ -1,152 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Dag Wieers (@dagwieers) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.ArgvParser -#Requires -Module Ansible.ModuleUtils.CommandUtil - -# See also: https://technet.microsoft.com/en-us/sysinternals/pxexec.aspx - -$spec = @{ - options = @{ - command = @{ type='str'; required=$true } - executable = @{ type='path'; default='psexec.exe' } - hostnames = @{ type='list' } - username = @{ type='str' } - password = @{ type='str'; no_log=$true } - chdir = @{ type='path' } - wait = @{ type='bool'; default=$true } - nobanner = @{ type='bool'; default=$false } - noprofile = @{ type='bool'; default=$false } - elevated = @{ type='bool'; default=$false } - limited = @{ type='bool'; default=$false } - system = @{ type='bool'; default=$false } - interactive = @{ type='bool'; default=$false } - session = @{ type='int' } - priority = @{ type='str'; choices=@( 'background', 'low', 'belownormal', 'abovenormal', 'high', 'realtime' ) } - timeout = @{ type='int' } - } -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$command = $module.Params.command -$executable = $module.Params.executable -$hostnames = $module.Params.hostnames -$username = $module.Params.username -$password = $module.Params.password -$chdir = $module.Params.chdir -$wait = $module.Params.wait -$nobanner = $module.Params.nobanner -$noprofile = $module.Params.noprofile -$elevated = $module.Params.elevated -$limited = $module.Params.limited -$system = $module.Params.system -$interactive = $module.Params.interactive -$session = $module.Params.session -$priority = $module.Params.Priority -$timeout = $module.Params.timeout - -$module.Result.changed = $true - -If (-Not (Get-Command $executable -ErrorAction SilentlyContinue)) { - $module.FailJson("Executable '$executable' was not found.") -} - -$arguments = [System.Collections.Generic.List`1[String]]@($executable) - -If ($nobanner -eq $true) { - $arguments.Add("-nobanner") -} - -# Support running on local system if no hostname is specified -If ($hostnames) { - $hostname_argument = ($hostnames | sort -Unique) -join ',' - $arguments.Add("\\$hostname_argument") -} - -# Username is optional -If ($null -ne $username) { - $arguments.Add("-u") - $arguments.Add($username) -} - -# Password is optional -If ($null -ne $password) { - $arguments.Add("-p") - $arguments.Add($password) -} - -If ($null -ne $chdir) { - $arguments.Add("-w") - $arguments.Add($chdir) -} - -If ($wait -eq $false) { - $arguments.Add("-d") -} - -If ($noprofile -eq $true) { - $arguments.Add("-e") -} - -If ($elevated -eq $true) { - $arguments.Add("-h") -} - -If ($system -eq $true) { - $arguments.Add("-s") -} - -If ($interactive -eq $true) { - $arguments.Add("-i") - If ($null -ne $session) { - $arguments.Add($session) - } -} - -If ($limited -eq $true) { - $arguments.Add("-l") -} - -If ($null -ne $priority) { - $arguments.Add("-$priority") -} - -If ($null -ne $timeout) { - $arguments.Add("-n") - $arguments.Add($timeout) -} - -$arguments.Add("-accepteula") - -$argument_string = Argv-ToString -arguments $arguments - -# Add the command at the end of the argument string, we don't want to escape -# that as psexec doesn't expect it to be one arg -$argument_string += " $command" - -$start_datetime = [DateTime]::UtcNow -$module.Result.psexec_command = $argument_string - -$command_result = Run-Command -command $argument_string - -$end_datetime = [DateTime]::UtcNow - -$module.Result.stdout = $command_result.stdout -$module.Result.stderr = $command_result.stderr - -If ($wait -eq $true) { - $module.Result.rc = $command_result.rc -} else { - $module.Result.rc = 0 - $module.Result.pid = $command_result.rc -} - -$module.Result.start = $start_datetime.ToString("yyyy-MM-dd hh:mm:ss.ffffff") -$module.Result.end = $end_datetime.ToString("yyyy-MM-dd hh:mm:ss.ffffff") -$module.Result.delta = $($end_datetime - $start_datetime).ToString("h\:mm\:ss\.ffffff") - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_psexec.py b/lib/ansible/modules/windows/win_psexec.py deleted file mode 100644 index c3fc37e4a60..00000000000 --- a/lib/ansible/modules/windows/win_psexec.py +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: 2017, Dag Wieers (@dagwieers) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_psexec -version_added: '2.3' -short_description: Runs commands (remotely) as another (privileged) user -description: -- Run commands (remotely) through the PsExec service. -- Run commands as another (domain) user (with elevated privileges). -requirements: -- Microsoft PsExec -options: - command: - description: - - The command line to run through PsExec (limited to 260 characters). - type: str - required: yes - executable: - description: - - The location of the PsExec utility (in case it is not located in your PATH). - type: path - default: psexec.exe - hostnames: - description: - - The hostnames to run the command. - - If not provided, the command is run locally. - type: list - username: - description: - - The (remote) user to run the command as. - - If not provided, the current user is used. - type: str - password: - description: - - The password for the (remote) user to run the command as. - - This is mandatory in order authenticate yourself. - type: str - chdir: - description: - - Run the command from this (remote) directory. - type: path - nobanner: - description: - - Do not display the startup banner and copyright message. - - This only works for specific versions of the PsExec binary. - type: bool - default: no - version_added: '2.4' - noprofile: - description: - - Run the command without loading the account's profile. - type: bool - default: no - elevated: - description: - - Run the command with elevated privileges. - type: bool - default: no - interactive: - description: - - Run the program so that it interacts with the desktop on the remote system. - type: bool - default: no - session: - description: - - Specifies the session ID to use. - - This parameter works in conjunction with I(interactive). - - It has no effect when I(interactive) is set to C(no). - type: int - version_added: '2.7' - limited: - description: - - Run the command as limited user (strips the Administrators group and allows only privileges assigned to the Users group). - type: bool - default: no - system: - description: - - Run the remote command in the System account. - type: bool - default: no - priority: - description: - - Used to run the command at a different priority. - choices: [ abovenormal, background, belownormal, high, low, realtime ] - timeout: - description: - - The connection timeout in seconds - type: int - wait: - description: - - Wait for the application to terminate. - - Only use for non-interactive applications. - type: bool - default: yes -notes: -- More information related to Microsoft PsExec is available from - U(https://technet.microsoft.com/en-us/sysinternals/bb897553.aspx) -seealso: -- module: psexec -- module: raw -- module: win_command -- module: win_shell -author: -- Dag Wieers (@dagwieers) -''' - -EXAMPLES = r''' -- name: Test the PsExec connection to the local system (target node) with your user - win_psexec: - command: whoami.exe - -- name: Run regedit.exe locally (on target node) as SYSTEM and interactively - win_psexec: - command: regedit.exe - interactive: yes - system: yes - -- name: Run the setup.exe installer on multiple servers using the Domain Administrator - win_psexec: - command: E:\setup.exe /i /IACCEPTEULA - hostnames: - - remote_server1 - - remote_server2 - username: DOMAIN\Administrator - password: some_password - priority: high - -- name: Run PsExec from custom location C:\Program Files\sysinternals\ - win_psexec: - command: netsh advfirewall set allprofiles state off - executable: C:\Program Files\sysinternals\psexec.exe - hostnames: [ remote_server ] - password: some_password - priority: low -''' - -RETURN = r''' -cmd: - description: The complete command line used by the module, including PsExec call and additional options. - returned: always - type: str - sample: psexec.exe -nobanner \\remote_server -u "DOMAIN\Administrator" -p "some_password" -accepteula E:\setup.exe -pid: - description: The PID of the async process created by PsExec. - returned: when C(wait=False) - type: int - sample: 1532 -rc: - description: The return code for the command. - returned: always - type: int - sample: 0 -stdout: - description: The standard output from the command. - returned: always - type: str - sample: Success. -stderr: - description: The error output from the command. - returned: always - type: str - sample: Error 15 running E:\setup.exe -''' diff --git a/lib/ansible/modules/windows/win_psmodule.ps1 b/lib/ansible/modules/windows/win_psmodule.ps1 deleted file mode 100644 index b24178e49ff..00000000000 --- a/lib/ansible/modules/windows/win_psmodule.ps1 +++ /dev/null @@ -1,468 +0,0 @@ -#!powershell - -# Copyright: (c) 2018, Wojciech Sciesinski -# Copyright: (c) 2017, Daniele Lazzari -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -# win_psmodule (Windows PowerShell modules Additions/Removals/Updates) - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$required_version = Get-AnsibleParam -obj $params -name "required_version" -type "str" -$minimum_version = Get-AnsibleParam -obj $params -name "minimum_version" -type "str" -$maximum_version = Get-AnsibleParam -obj $params -name "maximum_version" -type "str" -$repo = Get-AnsibleParam -obj $params -name "repository" -type "str" -$url = Get-AnsibleParam -obj $params -name "url" -type str -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present", "absent", "latest" -$allow_clobber = Get-AnsibleParam -obj $params -name "allow_clobber" -type "bool" -default $false -$skip_publisher_check = Get-AnsibleParam -obj $params -name "skip_publisher_check" -type "bool" -default $false -$allow_prerelease = Get-AnsibleParam -obj $params -name "allow_prerelease" -type "bool" -default $false - -$result = @{changed = $false - output = "" - nuget_changed = $false - repository_changed = $false} - -Function Install-NugetProvider { - Param( - [Bool]$CheckMode - ) - $PackageProvider = Get-PackageProvider -ListAvailable | Where-Object { ($_.name -eq 'Nuget') -and ($_.version -ge "2.8.5.201") } - if (-not($PackageProvider)){ - try { - Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -WhatIf:$CheckMode | out-null - $result.changed = $true - $result.nuget_changed = $true - } - catch [ System.Exception ] { - $ErrorMessage = "Problems adding package provider: $($_.Exception.Message)" - Fail-Json $result $ErrorMessage - } - } -} - -Function Install-PrereqModule { - Param( - [Switch]$TestInstallationOnly, - [Bool]$CheckMode - ) - - # Those are minimum required versions of modules. - $PrereqModules = @{ - PackageManagement = '1.1.7' - PowerShellGet = '1.6.0' - } - - [Bool]$PrereqModulesInstalled = $true - - ForEach ( $Name in $PrereqModules.Keys ) { - - $ExistingPrereqModule = Get-Module -ListAvailable | Where-Object { ($_.name -eq $Name) -and ($_.version -ge $PrereqModules[$Name]) } - - if ( -not $ExistingPrereqModule ) { - if ( $TestInstallationOnly ) { - $PrereqModulesInstalled = $false - } - else { - try { - $install_params = @{ - Name = $Name - MinimumVersion = $PrereqModules[$Name] - Force = $true - WhatIf = $CheckMode - } - if ((Get-Command -Name Install-Module).Parameters.ContainsKey('SkipPublisherCheck')) { - $install_params.SkipPublisherCheck = $true - } - - Install-Module @install_params > $null - - if ( $Name -eq 'PowerShellGet' ) { - # An order has to be reverted due to dependency - Remove-Module -Name PowerShellGet, PackageManagement -Force - Import-Module -Name PowerShellGet, PackageManagement -Force - } - - $result.changed = $true - } - catch [ System.Exception ] { - $ErrorMessage = "Problems adding a prerequisite module $Name $($_.Exception.Message)" - Fail-Json $result $ErrorMessage - } - } - } - } - - if ( $TestInstallationOnly ) { - $PrereqModulesInstalled - } -} - -Function Get-PsModule { - Param( - [Parameter(Mandatory=$true)] - [String]$Name, - [String]$RequiredVersion, - [String]$MinimumVersion, - [String]$MaximumVersion - ) - - $ExistingModule = @{ - Exists = $false - Version = "" - } - - $ExistingModules = Get-Module -Listavailable | Where-Object {($_.name -eq $Name)} - $ExistingModulesCount = $($ExistingModules | Measure-Object).Count - - if ( $ExistingModulesCount -gt 0 ) { - - $ExistingModules | Add-Member -MemberType ScriptProperty -Name FullVersion -Value { if ( $null -ne ( $this.PrivateData ) ) { [String]"$($this.Version)-$(($this | Select-Object -ExpandProperty PrivateData).PSData.Prerelease)".TrimEnd('-') } else { [String]"$($this.Version)" } } - - if ( -not ($RequiredVersion -or - $MinimumVersion -or - $MaximumVersion) ) { - - $ReturnedModule = $ExistingModules | Select-Object -First 1 - } - elseif ( $RequiredVersion ) { - $ReturnedModule = $ExistingModules | Where-Object -FilterScript { $_.FullVersion -eq $RequiredVersion } - } - elseif ( $MinimumVersion -and $MaximumVersion ) { - $ReturnedModule = $ExistingModules | Where-Object -FilterScript { $MinimumVersion -le $_.Version -and $MaximumVersion -ge $_.Version } | Select-Object -First 1 - } - elseif ( $MinimumVersion ) { - $ReturnedModule = $ExistingModules | Where-Object -FilterScript { $MinimumVersion -le $_.Version } | Select-Object -First 1 - } - elseif ( $MaximumVersion ) { - $ReturnedModule = $ExistingModules | Where-Object -FilterScript { $MaximumVersion -ge $_.Version } | Select-Object -First 1 - } - } - - $ReturnedModuleCount = ($ReturnedModule | Measure-Object).Count - - if ( $ReturnedModuleCount -eq 1 ) { - $ExistingModule.Exists = $true - $ExistingModule.Version = $ReturnedModule.FullVersion - } - - $ExistingModule -} - -Function Add-DefinedParameter { - Param ( - [Parameter(Mandatory=$true)] - [Hashtable]$Hashtable, - [Parameter(Mandatory=$true)] - [String[]]$ParametersNames - ) - - ForEach ($ParameterName in $ParametersNames) { - $ParameterVariable = Get-Variable -Name $ParameterName -ErrorAction Ignore - if ( $ParameterVariable.Value -and $Hashtable.Keys -notcontains $ParameterName ){ - $Hashtable.Add($ParameterName,$ParameterVariable.Value) - } - } - - $Hashtable -} - -Function Install-PsModule { - Param( - [Parameter(Mandatory=$true)] - [String]$Name, - [String]$RequiredVersion, - [String]$MinimumVersion, - [String]$MaximumVersion, - [String]$Repository, - [Bool]$AllowClobber, - [Bool]$SkipPublisherCheck, - [Bool]$AllowPrerelease, - [Bool]$CheckMode - ) - - $ExistingModuleBefore = Get-PsModule -Name $Name -RequiredVersion $RequiredVersion -MinimumVersion $MinimumVersion -MaximumVersion $MaximumVersion - - if ( -not $ExistingModuleBefore.Exists ) { - try { - # Install NuGet provider if needed. - Install-NugetProvider -CheckMode $CheckMode - - $ht = @{ - Name = $Name - WhatIf = $CheckMode - Force = $true - } - - [String[]]$ParametersNames = @("RequiredVersion","MinimumVersion","MaximumVersion","AllowPrerelease","AllowClobber","SkipPublisherCheck","Repository") - - $ht = Add-DefinedParameter -Hashtable $ht -ParametersNames $ParametersNames - - Install-Module @ht -ErrorVariable ErrorDetails | out-null - - $result.changed = $true - $result.output = "Module $($Name) installed" - } - catch [ System.Exception ] { - $ErrorMessage = "Problems installing $($Name) module: $($_.Exception.Message)" - Fail-Json $result $ErrorMessage - } - } - else { - $result.output = "Module $($Name) already present" - } -} - -Function Remove-PsModule { - Param( - [Parameter(Mandatory=$true)] - [String]$Name, - [String]$RequiredVersion, - [String]$MinimumVersion, - [String]$MaximumVersion, - [Bool]$CheckMode - ) - # If module is present, uninstalls it. - if (Get-Module -Listavailable | Where-Object {$_.name -eq $Name}) { - try { - $ht = @{ - Name = $Name - Confirm = $false - Force = $true - } - - $ExistingModuleBefore = Get-PsModule -Name $Name -RequiredVersion $RequiredVersion -MinimumVersion $MinimumVersion -MaximumVersion $MaximumVersion - - [String[]]$ParametersNames = @("RequiredVersion","MinimumVersion","MaximumVersion") - - $ht = Add-DefinedParameter -Hashtable $ht -ParametersNames $ParametersNames - - if ( -not ( $RequiredVersion -or $MinimumVersion -or $MaximumVersion ) ) { - $ht.Add("AllVersions", $true) - } - - if ( $ExistingModuleBefore.Exists) { - # The Force parameter overwrite the WhatIf parameter - if ( -not $CheckMode ) { - Uninstall-Module @ht -ErrorVariable ErrorDetails | out-null - } - $result.changed = $true - $result.output = "Module $($Name) removed" - } - } - catch [ System.Exception ] { - $ErrorMessage = "Problems uninstalling $($Name) module: $($_.Exception.Message)" - Fail-Json $result $ErrorMessage - } - } - else { - $result.output = "Module $($Name) removed" - } -} - -Function Find-LatestPsModule { - Param( - [Parameter(Mandatory=$true)] - [String]$Name, - [String]$Repository, - [Bool]$AllowPrerelease, - [Bool]$CheckMode - ) - - try { - $ht = @{ - Name = $Name - } - - [String[]]$ParametersNames = @("AllowPrerelease","Repository") - - $ht = Add-DefinedParameter -Hashtable $ht -ParametersNames $ParametersNames - - $LatestModule = Find-Module @ht - $LatestModuleVersion = $LatestModule.Version - } - catch [ System.Exception ] { - $ErrorMessage = "Cant find the module $($Name): $($_.Exception.Message)" - Fail-Json $result $ErrorMessage - } - - $LatestModuleVersion -} - -Function Install-Repository { - Param( - [Parameter(Mandatory=$true)] - [string]$Name, - [Parameter(Mandatory=$true)] - [string]$Url, - [bool]$CheckMode - ) - Add-DeprecationWarning -obj $result -message "Adding a repo with this module is deprecated, the repository parameter should only be used to select a repo. Use win_psrepository to manage repos" -version 2.12 - # Install NuGet provider if needed. - Install-NugetProvider -CheckMode $CheckMode - - $Repos = (Get-PSRepository).SourceLocation - - # If repository isn't already present, try to register it as trusted. - if ($Repos -notcontains $Url){ - try { - if ( -not ($CheckMode) ) { - Register-PSRepository -Name $Name -SourceLocation $Url -InstallationPolicy Trusted -ErrorAction Stop - } - $result.changed = $true - $result.repository_changed = $true - } - catch { - $ErrorMessage = "Problems registering $($Name) repository: $($_.Exception.Message)" - Fail-Json $result $ErrorMessage - } - } -} - -Function Remove-Repository{ - Param( - [Parameter(Mandatory=$true)] - [string]$Name, - [bool]$CheckMode - ) - Add-DeprecationWarning -obj $result -message "Removing a repo with this module is deprecated, use win_psrepository to manage repos" -version 2.12 - - $Repo = (Get-PSRepository).Name - - # Try to remove the repository - if ($Repo -contains $Name){ - try { - if ( -not ($CheckMode) ) { - Unregister-PSRepository -Name $Name -ErrorAction Stop - } - $result.changed = $true - $result.repository_changed = $true - } - catch [ System.Exception ] { - $ErrorMessage = "Problems unregistering $($Name)repository: $($_.Exception.Message)" - Fail-Json $result $ErrorMessage - } - } -} - -# Check PowerShell version, fail if < 5.0 and required modules are not installed -$PsVersion = $PSVersionTable.PSVersion -if ($PsVersion.Major -lt 5 ) { - $PrereqModulesInstalled = Install-PrereqModule -TestInstallationOnly - if ( -not $PrereqModulesInstalled ) { - $ErrorMessage = "Modules PowerShellGet and PackageManagement in versions 1.6.0 and 1.1.7 respectively have to be installed before using the win_psmodule." - Fail-Json $result $ErrorMessage - } -} - -if ( $required_version -and ( $minimum_version -or $maximum_version ) ) { - $ErrorMessage = "Parameters required_version and minimum/maximum_version are mutually exclusive." - Fail-Json $result $ErrorMessage -} - -if ( $allow_prerelease -and ( $minimum_version -or $maximum_version ) ) { - $ErrorMessage = "Parameters minimum_version, maximum_version can't be used with the parameter allow_prerelease." - Fail-Json $result $ErrorMessage -} - -if ( $allow_prerelease -and $state -eq "absent" ) { - $ErrorMessage = "The parameter allow_prerelease can't be used with state set to 'absent'." - Fail-Json $result $ErrorMessage -} - -if ( ($state -eq "latest") -and - ( $required_version -or $minimum_version -or $maximum_version ) ) { - $ErrorMessage = "When the parameter state is equal 'latest' you can use any of required_version, minimum_version, maximum_version." - Fail-Json $result $ErrorMessage -} - -if ( $repo -and (-not $url) ) { - $RepositoryExists = Get-PSRepository -Name $repo -ErrorAction Ignore - if ( $null -eq $RepositoryExists) { - $ErrorMessage = "The repository $repo doesn't exist." - Fail-Json $result $ErrorMessage - } - -} - -if ( ($allow_clobber -or $allow_prerelease -or $skip_publisher_check -or - $required_version -or $minimum_version -or $maximum_version) ) { - # Update the PowerShellGet and PackageManagement modules. - # It's required to support AllowClobber, AllowPrerelease parameters. - Install-PrereqModule -CheckMode $check_mode -} - -Import-Module -Name PackageManagement, PowerShellGet - -if ($state -eq "present") { - if (($repo) -and ($url)) { - Install-Repository -Name $repo -Url $url -CheckMode $check_mode - } - else { - $ErrorMessage = "Repository Name and Url are mandatory if you want to add a new repository" - } - - if ($name) { - $ht = @{ - Name = $name - RequiredVersion = $required_version - MinimumVersion = $minimum_version - MaximumVersion = $maximum_version - Repository = $repo - AllowClobber = $allow_clobber - SkipPublisherCheck = $skip_publisher_check - AllowPrerelease = $allow_prerelease - CheckMode = $check_mode - } - Install-PsModule @ht - } -} -elseif ($state -eq "absent") { - if ($repo) { - Remove-Repository -Name $repo -CheckMode $check_mode - } - - if ($name) { - $ht = @{ - Name = $Name - CheckMode = $check_mode - RequiredVersion = $required_version - MinimumVersion = $minimum_version - MaximumVersion = $maximum_version - } - Remove-PsModule @ht - } -} -elseif ( $state -eq "latest") { - - $ht = @{ - Name = $Name - AllowPrerelease = $allow_prerelease - Repository = $repo - CheckMode = $check_mode - } - - $LatestVersion = Find-LatestPsModule @ht - - $ExistingModule = Get-PsModule $Name - - if ( $LatestVersion.Version -ne $ExistingModule.Version ) { - - $ht = @{ - Name = $Name - RequiredVersion = $LatestVersion - Repository = $repo - AllowClobber = $allow_clobber - SkipPublisherCheck = $skip_publisher_check - AllowPrerelease = $allow_prerelease - CheckMode = $check_mode - } - Install-PsModule @ht - } -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_psmodule.py b/lib/ansible/modules/windows/win_psmodule.py deleted file mode 100644 index d779e99c9c1..00000000000 --- a/lib/ansible/modules/windows/win_psmodule.py +++ /dev/null @@ -1,155 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Wojciech Sciesinski -# Copyright: (c) 2017, Daniele Lazzari -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_psmodule -version_added: "2.4" -short_description: Adds or removes a Windows PowerShell module -description: - - This module helps to install Windows PowerShell modules and register custom modules repository on Windows-based systems. -options: - name: - description: - - Name of the Windows PowerShell module that has to be installed. - type: str - required: yes - state: - description: - - If C(present) a new module is installed. - - If C(absent) a module is removed. - - If C(latest) a module is updated to the newest version. This option was added in version 2.8. - type: str - choices: [ absent, latest, present ] - default: present - required_version: - description: - - The exact version of the PowerShell module that has to be installed. - type: str - version_added: "2.8" - minimum_version: - description: - - The minimum version of the PowerShell module that has to be installed. - type: str - version_added: "2.8" - maximum_version: - description: - - The maximum version of the PowerShell module that has to be installed. - type: str - version_added: "2.8" - allow_clobber: - description: - - If C(yes) allows install modules that contains commands those have the same names as commands that already exists. - type: bool - default: no - skip_publisher_check: - description: - - If C(yes), allows you to install a different version of a module that already exists on your computer in the case when a different one - is not digitally signed by a trusted publisher and the newest existing module is digitally signed by a trusted publisher. - type: bool - default: no - version_added: "2.8" - allow_prerelease: - description: - - If C(yes) installs modules marked as prereleases. - - It doesn't work with the parameters C(minimum_version) and/or C(maximum_version). - - It doesn't work with the C(state) set to absent. - type: bool - default: no - version_added: "2.8" - repository: - description: - - Name of the custom repository to use. - type: str - url: - description: - - URL of the custom repository to register. - - This option is deprecated and will be removed in Ansible 2.12. Use the - M(win_psrepository) module instead. - type: str -notes: - - PowerShell modules needed - - PowerShellGet >= 1.6.0 - - PackageManagement >= 1.1.7 - - PowerShell package provider needed - - NuGet >= 2.8.5.201 - - On PowerShell 5.x required modules and a package provider will be updated under the first run of the win_psmodule module. - - On PowerShell 3.x and 4.x you have to install them before using the win_psmodule. -seealso: -- module: win_psrepository -author: -- Wojciech Sciesinski (@it-praktyk) -- Daniele Lazzari (@dlazz) -''' - -EXAMPLES = r''' ---- -- name: Add a PowerShell module - win_psmodule: - name: PowerShellModule - state: present - -- name: Add an exact version of PowerShell module - win_psmodule: - name: PowerShellModule - required_version: "4.0.2" - state: present - -- name: Install or update an existing PowerShell module to the newest version - win_psmodule: - name: PowerShellModule - state: latest - -- name: Install newer version of built-in Windows module - win_psmodule: - name: Pester - skip_publisher_check: yes - state: present - -- name: Add a PowerShell module and register a repository - win_psmodule: - name: MyCustomModule - repository: MyRepository - state: present - -- name: Add a PowerShell module from a specific repository - win_psmodule: - name: PowerShellModule - repository: MyRepository - state: present - -- name: Remove a PowerShell module - win_psmodule: - name: PowerShellModule - state: absent -''' - -RETURN = r''' ---- -output: - description: A message describing the task result. - returned: always - sample: "Module PowerShellCookbook installed" - type: str -nuget_changed: - description: True when Nuget package provider is installed. - returned: always - type: bool - sample: true -repository_changed: - description: True when a custom repository is installed or removed. - returned: always - type: bool - sample: true -''' diff --git a/lib/ansible/modules/windows/win_psrepository.ps1 b/lib/ansible/modules/windows/win_psrepository.ps1 deleted file mode 100644 index da637f02ebe..00000000000 --- a/lib/ansible/modules/windows/win_psrepository.ps1 +++ /dev/null @@ -1,68 +0,0 @@ -#!powershell - -# Copyright: (c) 2018, Wojciech Sciesinski -# Copyright: (c) 2017, Daniele Lazzari -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -# win_psrepository (Windows PowerShell repositories Additions/Removals/Updates) - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$source = Get-AnsibleParam -obj $params -name "source" -type "str" -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present", "absent" -$installationpolicy = Get-AnsibleParam -obj $params -name "installation_policy" -type "str" -validateset "trusted", "untrusted" - -$result = @{"changed" = $false} - -Function Update-NuGetPackageProvider { - $PackageProvider = Get-PackageProvider -ListAvailable | Where-Object { ($_.name -eq 'Nuget') -and ($_.version -ge "2.8.5.201") } - if ($null -eq $PackageProvider) { - Find-PackageProvider -Name Nuget -ForceBootstrap -IncludeDependencies -Force | Out-Null - } -} - -$Repo = Get-PSRepository -Name $name -ErrorAction Ignore -if ($state -eq "present") { - if ($null -eq $Repo) { - if ($null -eq $installationpolicy) { - $installationpolicy = "trusted" - } - if (-not $check_mode) { - Update-NuGetPackageProvider - Register-PSRepository -Name $name -SourceLocation $source -InstallationPolicy $installationpolicy - } - $result.changed = $true - } - else { - $changed_properties = @{} - - if ($Repo.SourceLocation -ne $source) { - $changed_properties.SourceLocation = $source - } - - if ($null -ne $installationpolicy -and $Repo.InstallationPolicy -ne $installationpolicy) { - $changed_properties.InstallationPolicy = $installationpolicy - } - - if ($changed_properties.Count -gt 0) { - if (-not $check_mode) { - Update-NuGetPackageProvider - Set-PSRepository -Name $name @changed_properties - } - $result.changed = $true - } - } -} -elseif ($state -eq "absent" -and $null -ne $Repo) { - if (-not $check_mode) { - Update-NuGetPackageProvider - Unregister-PSRepository -Name $name - } - $result.changed = $true -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_psrepository.py b/lib/ansible/modules/windows/win_psrepository.py deleted file mode 100644 index a4faa1c6cf5..00000000000 --- a/lib/ansible/modules/windows/win_psrepository.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Wojciech Sciesinski -# Copyright: (c) 2017, Daniele Lazzari -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_psrepository -version_added: "2.8" -short_description: Adds, removes or updates a Windows PowerShell repository. -description: - - This module helps to add, remove and update Windows PowerShell repository on Windows-based systems. -options: - name: - description: - - Name of the repository to work with. - type: str - required: yes - source: - description: - - Specifies the URI for discovering and installing modules from this repository. - - A URI can be a NuGet server feed (most common situation), HTTP, HTTPS, FTP or file location. - type: str - state: - description: - - If C(present) a new repository is added or updated. - - If C(absent) a repository is removed. - type: str - choices: [ absent, present ] - default: present - installation_policy: - description: - - Sets the C(InstallationPolicy) of a repository. - - Will default to C(trusted) when creating a new repository. - type: str - choices: [ trusted, untrusted ] -notes: - - PowerShell modules needed - - PowerShellGet >= 1.6.0 - - PackageManagement >= 1.1.7 - - PowerShell package provider needed - - NuGet >= 2.8.5.201 - - See the examples on how to update the NuGet package provider. - - You can not use C(win_psrepository) to re-register (add) removed PSGallery, use the command C(Register-PSRepository -Default) instead. -seealso: -- module: win_psmodule -author: -- Wojciech Sciesinski (@it-praktyk) -''' - -EXAMPLES = ''' ---- -- name: Ensure the required NuGet package provider version is installed - win_shell: Find-PackageProvider -Name Nuget -ForceBootstrap -IncludeDependencies -Force - -- name: Add a PowerShell module and register a repository - win_psrepository: - name: MyRepository - source: https://myrepo.com - state: present - -- name: Remove a PowerShell repository - win_psrepository: - name: MyRepository - state: absent -''' - -RETURN = ''' -''' diff --git a/lib/ansible/modules/windows/win_psrepository_info.ps1 b/lib/ansible/modules/windows/win_psrepository_info.ps1 deleted file mode 100644 index 93e3585bef2..00000000000 --- a/lib/ansible/modules/windows/win_psrepository_info.ps1 +++ /dev/null @@ -1,68 +0,0 @@ -#!powershell - -# Copyright: (c) 2020, Brian Scholer <@briantist> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.CamelConversion -#Requires -Module PowerShellGet - -$spec = @{ - options = @{ - name = @{ type = 'str' ; default = '*' } - } - supports_check_mode = $true -} -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -function Convert-ObjectToSnakeCase { - <# - .SYNOPSIS - Converts an object with CamelCase properties to a dictionary with snake_case keys. - Works in the spirit of and depends on the existing CamelConversion module util. - #> - [CmdletBinding()] - param( - [Parameter(Mandatory=$true,ValueFromPipeline=$true)] - [OutputType([System.Collections.Specialized.OrderedDictionary])] - [Object] - $InputObject , - - [Parameter()] - [Switch] - $NoRecurse , - - [Parameter()] - [Switch] - $OmitNull - ) - - Process { - $result = [Ordered]@{} - foreach ($property in $InputObject.PSObject.Properties) { - $value = $property.Value - if (-not $NoRecurse -and $value -is [System.Collections.IDictionary]) { - $value = Convert-DictToSnakeCase -dict $value - } - elseif (-not $NoRecurse -and ($value -is [Array] -or $value -is [System.Collections.ArrayList])) { - $value = Convert-ListToSnakeCase -list $value - } - elseif ($null -eq $value) { - if ($OmitNull) { - continue - } - } - elseif (-not $NoRecurse -and $value -isnot [System.ValueType] -and $value -isnot [string]) { - $value = Convert-ObjectToSnakeCase -InputObject $value - } - - $name = Convert-StringToSnakeCase -string $property.Name - $result[$name] = $value - } - $result - } -} - -$module.Result.repositories = @(Get-PSRepository -Name $module.Params.name | Convert-ObjectToSnakeCase) - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_psrepository_info.py b/lib/ansible/modules/windows/win_psrepository_info.py deleted file mode 100644 index 1bcbee1bb5a..00000000000 --- a/lib/ansible/modules/windows/win_psrepository_info.py +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2020, Brian Scholer <@briantist> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_psrepository_info -version_added: '2.10' -short_description: Gather information about PSRepositories -description: - - Gather information about all or a specific PSRepository. -options: - name: - description: - - The name of the repository to retrieve. - - Supports any wildcard pattern supported by C(Get-PSRepository). - - If omitted then all repositories will returned. - type: str - default: '*' -requirements: - - C(PowerShellGet) module -seealso: - - module: win_psrepository -author: - - Brian Scholer (@briantist) -''' - -EXAMPLES = r''' -- name: Get info for a single repository - win_psrepository_info: - name: PSGallery - register: repo_info - -- name: Find all repositories that start with 'MyCompany' - win_psrepository_info: - name: MyCompany* - -- name: Get info for all repositories - win_psrepository_info: - register: repo_info - -- name: Remove all repositories that don't have a publish_location set - win_psrepository: - name: "{{ item }}" - state: absent - loop: "{{ repo_info.repositories | rejectattr('publish_location', 'none') | list }}" -''' - -RETURN = r''' -repositories: - description: - - A list of repositories (or an empty list is there are none). - returned: always - type: list - elements: dict - contains: - name: - description: - - The name of the repository. - type: str - sample: PSGallery - installation_policy: - description: - - The installation policy of the repository. The sample values are the only possible values. - type: str - sample: - - Trusted - - Untrusted - trusted: - description: - - A boolean flag reflecting the value of C(installation_policy) as to whether the repository is trusted. - type: bool - package_management_provider: - description: - - The name of the package management provider for this repository. - type: str - sample: NuGet - provider_options: - description: - - Provider-specific options for this repository. - type: dict - source_location: - description: - - The location used to find and retrieve modules. This should always have a value. - type: str - sample: https://www.powershellgallery.com/api/v2 - publish_location: - description: - - The location used to publish modules. - type: str - sample: https://www.powershellgallery.com/api/v2/package/ - script_source_location: - description: - - The location used to find and retrieve scripts. - type: str - sample: https://www.powershellgallery.com/api/v2/items/psscript - script_publish_location: - description: - - The location used to publish scripts. - type: str - sample: https://www.powershellgallery.com/api/v2/package/ - registered: - description: - - Whether the module is registered. Should always be C(True) - type: bool -''' diff --git a/lib/ansible/modules/windows/win_rabbitmq_plugin.ps1 b/lib/ansible/modules/windows/win_rabbitmq_plugin.ps1 deleted file mode 100644 index 1c79f0c41ed..00000000000 --- a/lib/ansible/modules/windows/win_rabbitmq_plugin.ps1 +++ /dev/null @@ -1,157 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -function Get-EnabledPlugins($rabbitmq_plugins_cmd) -{ - $list_plugins_cmd = "$rabbitmq_plugins_cmd list -E -m" - try { - $enabled_plugins = @(Invoke-Expression "& $list_plugins_cmd" | Where-Object { $_ }) - return ,$enabled_plugins - } - catch { - Fail-Json -obj $result -message "Can't execute `"$($list_plugins_cmd)`": $($_.Exception.Message)" - } -} - -function Enable-Plugin($rabbitmq_plugins_cmd, $plugin_name) -{ - $enable_plugin_cmd = "$rabbitmq_plugins_cmd enable $plugin_name" - try { - Invoke-Expression "& $enable_plugin_cmd" - } - catch { - Fail-Json -obj $result -message "Can't execute `"$($enable_plugin_cmd)`": $($_.Exception.Message)" - } -} - -function Disable-Plugin($rabbitmq_plugins_cmd, $plugin_name) -{ - $enable_plugin_cmd = "$rabbitmq_plugins_cmd disable $plugin_name" - try { - Invoke-Expression "& $enable_plugin_cmd" - } - catch { - Fail-Json -obj $result -message "Can't execute `"$($enable_plugin_cmd)`": $($_.Exception.Message)" - } -} - -function Get-RabbitmqPathFromRegistry -{ - $reg64Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\RabbitMQ" - $reg32Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\RabbitMQ" - - if (Test-Path $reg64Path) { - $regPath = $reg64Path - } elseif (Test-Path $reg32Path) { - $regPath = $reg32Path - } - - if ($regPath) { - $path = Split-Path -Parent (Get-ItemProperty $regPath "UninstallString").UninstallString - $version = (Get-ItemProperty $regPath "DisplayVersion").DisplayVersion - return "$path\rabbitmq_server-$version" - } -} - -function Get-RabbitmqBinPath($installation_path) -{ - $result = Join-Path -Path $installation_path -ChildPath 'bin' - if (Test-Path $result) { - return $result - } - - $result = Join-Path -Path $installation_path -ChildPath 'sbin' - if (Test-Path $result) { - return $result - } -} - -$ErrorActionPreference = "Stop" - -$result = @{ - changed = $false - enabled = @() - disabled = @() -} - -$params = Parse-Args $args -supports_check_mode $true; -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff_support = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false - -$names = Get-AnsibleParam -obj $params -name "names" -type "str" -failifempty $true -aliases "name" -$new_only = Get-AnsibleParam -obj $params -name "new_only" -type "bool" -default $false -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "enabled" -validateset "enabled","disabled" -$prefix = Get-AnsibleParam -obj $params -name "prefix" -type "str" - -if ($diff_support) { - $result.diff = @{} - $result.diff.prepared = "" -} - -$plugins = $names.Split(",") - -if ($prefix) { - $rabbitmq_bin_path = Get-RabbitmqBinPath -installation_path $prefix - if (-not $rabbitmq_bin_path) { - Fail-Json -obj $result -message "No binary folder in prefix `"$($prefix)`"" - } -} else { - $rabbitmq_reg_path = Get-RabbitmqPathFromRegistry - if ($rabbitmq_reg_path) { - $rabbitmq_bin_path = Get-RabbitmqBinPath -installation_path $rabbitmq_reg_path - } -} - -if ($rabbitmq_bin_path) { - $rabbitmq_plugins_cmd = "'$(Join-Path -Path $rabbitmq_bin_path -ChildPath "rabbitmq-plugins")'" -} else { - $rabbitmq_plugins_cmd = "rabbitmq-plugins" -} - -$enabled_plugins = Get-EnabledPlugins -rabbitmq_plugins_cmd $rabbitmq_plugins_cmd - -if ($state -eq "enabled") { - $plugins_to_enable = $plugins | Where-Object {-not ($enabled_plugins -contains $_)} - foreach ($plugin in $plugins_to_enable) { - if (-not $check_mode) { - Enable-Plugin -rabbitmq_plugins_cmd $rabbitmq_plugins_cmd -plugin_name $plugin - } - if ($diff_support) { - $result.diff.prepared += "+[$plugin]`n" - } - $result.enabled += $plugin - $result.changed = $true - } - - if (-not $new_only) { - $plugins_to_disable = $enabled_plugins | Where-Object {-not ($plugins -contains $_)} - foreach ($plugin in $plugins_to_disable) { - if (-not $check_mode) { - Disable-Plugin -rabbitmq_plugins_cmd $rabbitmq_plugins_cmd -plugin_name $plugin - } - if ($diff_support) { - $result.diff.prepared += "-[$plugin]`n" - } - $result.disabled += $plugin - $result.changed = $true - } - } -} else { - $plugins_to_disable = $enabled_plugins | Where-Object {$plugins -contains $_} - foreach ($plugin in $plugins_to_disable) { - if (-not $check_mode) { - Disable-Plugin -rabbitmq_plugins_cmd $rabbitmq_plugins_cmd -plugin_name $plugin - } - if ($diff_support) { - $result.diff.prepared += "-[$plugin]`n" - } - $result.disabled += $plugin - $result.changed = $true - } -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_rabbitmq_plugin.py b/lib/ansible/modules/windows/win_rabbitmq_plugin.py deleted file mode 100644 index 783559c5953..00000000000 --- a/lib/ansible/modules/windows/win_rabbitmq_plugin.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_rabbitmq_plugin -short_description: Manage RabbitMQ plugins -description: - - Manage RabbitMQ plugins. -version_added: "2.4" -options: - names: - description: - - Comma-separated list of plugin names. - type: str - required: yes - aliases: [ name ] - new_only: - description: - - Only enable missing plugins. - - Does not disable plugins that are not in the names list. - type: bool - default: no - state: - description: - - Specify if plugins are to be enabled or disabled. - type: str - choices: [ disabled, enabled ] - default: enabled - prefix: - description: - - Specify a custom install prefix to a Rabbit. - type: str -author: - - Artem Zinenko (@ar7z1) -''' - -EXAMPLES = r''' -- name: Enables the rabbitmq_management plugin - win_rabbitmq_plugin: - names: rabbitmq_management - state: enabled -''' - -RETURN = r''' -enabled: - description: List of plugins enabled during task run. - returned: always - type: list - sample: ["rabbitmq_management"] -disabled: - description: List of plugins disabled during task run. - returned: always - type: list - sample: ["rabbitmq_management"] -''' diff --git a/lib/ansible/modules/windows/win_rds_cap.ps1 b/lib/ansible/modules/windows/win_rds_cap.ps1 deleted file mode 100644 index 1bc61ce4758..00000000000 --- a/lib/ansible/modules/windows/win_rds_cap.ps1 +++ /dev/null @@ -1,357 +0,0 @@ -#!powershell - -# Copyright: (c) 2018, Kevin Subileau (@ksubileau) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.SID - -$ErrorActionPreference = "Stop" - -# List of authentication methods as string. Used for parameter validation and conversion to integer flag, so order is important! -$auth_methods_set = @("none", "password", "smartcard", "both") -# List of session timeout actions as string. Used for parameter validation and conversion to integer flag, so order is important! -$session_timeout_actions_set = @("disconnect", "reauth") - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff_mode = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "absent","present","enabled","disabled" -$auth_method = Get-AnsibleParam -obj $params -name "auth_method" -type "str" -validateset $auth_methods_set -$order = Get-AnsibleParam -obj $params -name "order" -type "int" -$session_timeout = Get-AnsibleParam -obj $params -name "session_timeout" -type "int" -$session_timeout_action = Get-AnsibleParam -obj $params -name "session_timeout_action" -type "str" -default "disconnect" -validateset $session_timeout_actions_set -$idle_timeout = Get-AnsibleParam -obj $params -name "idle_timeout" -type "int" -$allow_only_sdrts_servers = Get-AnsibleParam -obj $params -name "allow_only_sdrts_servers" -type "bool" -$user_groups = Get-AnsibleParam -obj $params -name "user_groups" -type "list" -$computer_groups = Get-AnsibleParam -obj $params -name "computer_groups" -type "list" - -# Device redirections -$redirect_clipboard = Get-AnsibleParam -obj $params -name "redirect_clipboard" -type "bool" -$redirect_drives = Get-AnsibleParam -obj $params -name "redirect_drives" -type "bool" -$redirect_printers = Get-AnsibleParam -obj $params -name "redirect_printers" -type "bool" -$redirect_serial = Get-AnsibleParam -obj $params -name "redirect_serial" -type "bool" -$redirect_pnp = Get-AnsibleParam -obj $params -name "redirect_pnp" -type "bool" - - -function Get-CAP([string] $name) { - $cap_path = "RDS:\GatewayServer\CAP\$name" - $cap = @{ - Name = $name - } - - # Fetch CAP properties - Get-ChildItem -Path $cap_path | ForEach-Object { $cap.Add($_.Name,$_.CurrentValue) } - # Convert boolean values - $cap.Enabled = $cap.Status -eq 1 - $cap.Remove("Status") - $cap.AllowOnlySDRTSServers = $cap.AllowOnlySDRTSServers -eq 1 - - # Convert multiple choices values - $cap.AuthMethod = $auth_methods_set[$cap.AuthMethod] - $cap.SessionTimeoutAction = $session_timeout_actions_set[$cap.SessionTimeoutAction] - - # Fetch CAP device redirection settings - $cap.DeviceRedirection = @{} - Get-ChildItem -Path "$cap_path\DeviceRedirection" | ForEach-Object { $cap.DeviceRedirection.Add($_.Name, ($_.CurrentValue -eq 1)) } - - # Fetch CAP user and computer groups in Down-Level Logon format - $cap.UserGroups = @( - Get-ChildItem -Path "$cap_path\UserGroups" | - Select-Object -ExpandProperty Name | - ForEach-Object { Convert-FromSID -sid (Convert-ToSID -account_name $_) } - ) - $cap.ComputerGroups = @( - Get-ChildItem -Path "$cap_path\ComputerGroups" | - Select-Object -ExpandProperty Name | - ForEach-Object { Convert-FromSID -sid (Convert-ToSID -account_name $_) } - ) - - return $cap -} - -function Set-CAPPropertyValue { - [CmdletBinding(SupportsShouldProcess=$true)] - param ( - [Parameter(Mandatory=$true)] - [string] $name, - [Parameter(Mandatory=$true)] - [string] $property, - [Parameter(Mandatory=$true)] - $value, - [Parameter()] - $resultobj = @{} - ) - - $cap_path = "RDS:\GatewayServer\CAP\$name" - - try { - Set-Item -Path "$cap_path\$property" -Value $value -ErrorAction Stop - } catch { - Fail-Json -obj $resultobj -message "Failed to set property $property of CAP ${name}: $($_.Exception.Message)" - } -} - -$result = @{ - changed = $false -} -$diff_text = $null - -# Validate CAP name -if ($name -match "[*/\\;:?`"<>|\t]+") { - Fail-Json -obj $result -message "Invalid character in CAP name." -} - -# Validate user groups -if ($null -ne $user_groups) { - if ($user_groups.Count -lt 1) { - Fail-Json -obj $result -message "Parameter 'user_groups' cannot be an empty list." - } - - $user_groups = $user_groups | ForEach-Object { - $group = $_ - # Test that the group is resolvable on the local machine - $sid = Convert-ToSID -account_name $group - if (!$sid) { - Fail-Json -obj $result -message "$group is not a valid user group on the host machine or domain" - } - - # Return the normalized group name in Down-Level Logon format - Convert-FromSID -sid $sid - } - $user_groups = @($user_groups) -} - -# Validate computer groups -if ($null -ne $computer_groups) { - $computer_groups = $computer_groups | ForEach-Object { - $group = $_ - # Test that the group is resolvable on the local machine - $sid = Convert-ToSID -account_name $group - if (!$sid) { - Fail-Json -obj $result -message "$group is not a valid computer group on the host machine or domain" - } - - # Return the normalized group name in Down-Level Logon format - Convert-FromSID -sid $sid - } - $computer_groups = @($computer_groups) -} - -# Validate order parameter -if ($null -ne $order -and $order -lt 1) { - Fail-Json -obj $result -message "Parameter 'order' must be a strictly positive integer." -} - -# Ensure RemoteDesktopServices module is loaded -if ($null -eq (Get-Module -Name RemoteDesktopServices -ErrorAction SilentlyContinue)) { - Import-Module -Name RemoteDesktopServices -} - -# Check if a CAP with the given name already exists -$cap_exist = Test-Path -Path "RDS:\GatewayServer\CAP\$name" - -if ($state -eq 'absent') { - if ($cap_exist) { - Remove-Item -Path "RDS:\GatewayServer\CAP\$name" -Recurse -WhatIf:$check_mode - $diff_text += "-[$name]" - $result.changed = $true - } -} else { - $diff_text_added_prefix = '' - if (-not $cap_exist) { - if ($null -eq $user_groups) { - Fail-Json -obj $result -message "User groups must be defined to create a new CAP." - } - - # Auth method is required when creating a new CAP. Set it to password by default. - if ($null -eq $auth_method) { - $auth_method = "password" - } - - # Create a new CAP - if (-not $check_mode) { - $CapArgs = @{ - Name = $name - UserGroupNames = $user_groups -join ';' - } - $return = Invoke-CimMethod -Namespace Root\CIMV2\TerminalServices -ClassName Win32_TSGatewayConnectionAuthorizationPolicy -MethodName Create -Arguments $CapArgs - if ($return.ReturnValue -ne 0) { - Fail-Json -obj $result -message "Failed to create CAP $name (code: $($return.ReturnValue))" - } - } - - $cap_exist = -not $check_mode - - $diff_text_added_prefix = '+' - $result.changed = $true - } - - $diff_text += "$diff_text_added_prefix[$name]`n" - - # We cannot configure a CAP that was created above in check mode as it won't actually exist - if($cap_exist) { - $cap = Get-CAP -Name $name - $wmi_cap = Get-CimInstance -ClassName Win32_TSGatewayConnectionAuthorizationPolicy -Namespace Root\CIMv2\TerminalServices -Filter "name='$($name)'" - - if ($state -in @('disabled', 'enabled')) { - $cap_enabled = $state -ne 'disabled' - if ($cap.Enabled -ne $cap_enabled) { - $diff_text += "-State = $(@('disabled', 'enabled')[[int]$cap.Enabled])`n+State = $state`n" - Set-CAPPropertyValue -Name $name -Property Status -Value ([int]$cap_enabled) -ResultObj $result -WhatIf:$check_mode - $result.changed = $true - } - } - - if ($null -ne $auth_method -and $auth_method -ne $cap.AuthMethod) { - $diff_text += "-AuthMethod = $($cap.AuthMethod)`n+AuthMethod = $auth_method`n" - Set-CAPPropertyValue -Name $name -Property AuthMethod -Value ([array]::IndexOf($auth_methods_set, $auth_method)) -ResultObj $result -WhatIf:$check_mode - $result.changed = $true - } - - if ($null -ne $order -and $order -ne $cap.EvaluationOrder) { - # Order cannot be greater than the total number of existing CAPs (InvalidArgument exception) - $cap_count = (Get-ChildItem -Path "RDS:\GatewayServer\CAP").Count - if($order -gt $cap_count) { - Add-Warning -obj $result -message "Given value '$order' for parameter 'order' is greater than the number of existing CAPs. The actual order will be capped to '$cap_count'." - $order = $cap_count - } - - $diff_text += "-Order = $($cap.EvaluationOrder)`n+Order = $order`n" - Set-CAPPropertyValue -Name $name -Property EvaluationOrder -Value $order -ResultObj $result -WhatIf:$check_mode - $result.changed = $true - } - - if ($null -ne $session_timeout -and ($session_timeout -ne $cap.SessionTimeout -or $session_timeout_action -ne $cap.SessionTimeoutAction)) { - try { - Set-Item -Path "RDS:\GatewayServer\CAP\$name\SessionTimeout" ` - -Value $session_timeout ` - -SessionTimeoutAction ([array]::IndexOf($session_timeout_actions_set, $session_timeout_action)) ` - -ErrorAction Stop ` - -WhatIf:$check_mode - } catch { - Fail-Json -obj $result -message "Failed to set property ComputerGroupType of RAP ${name}: $($_.Exception.Message)" - } - - $diff_text += "-SessionTimeoutAction = $($cap.SessionTimeoutAction)`n+SessionTimeoutAction = $session_timeout_action`n" - $diff_text += "-SessionTimeout = $($cap.SessionTimeout)`n+SessionTimeout = $session_timeout`n" - $result.changed = $true - } - - if ($null -ne $idle_timeout -and $idle_timeout -ne $cap.IdleTimeout) { - $diff_text += "-IdleTimeout = $($cap.IdleTimeout)`n+IdleTimeout = $idle_timeout`n" - Set-CAPPropertyValue -Name $name -Property IdleTimeout -Value $idle_timeout -ResultObj $result -WhatIf:$check_mode - $result.changed = $true - } - - if ($null -ne $allow_only_sdrts_servers -and $allow_only_sdrts_servers -ne $cap.AllowOnlySDRTSServers) { - $diff_text += "-AllowOnlySDRTSServers = $($cap.AllowOnlySDRTSServers)`n+AllowOnlySDRTSServers = $allow_only_sdrts_servers`n" - Set-CAPPropertyValue -Name $name -Property AllowOnlySDRTSServers -Value ([int]$allow_only_sdrts_servers) -ResultObj $result -WhatIf:$check_mode - $result.changed = $true - } - - if ($null -ne $redirect_clipboard -and $redirect_clipboard -ne $cap.DeviceRedirection.Clipboard) { - $diff_text += "-RedirectClipboard = $($cap.DeviceRedirection.Clipboard)`n+RedirectClipboard = $redirect_clipboard`n" - Set-CAPPropertyValue -Name $name -Property "DeviceRedirection\Clipboard" -Value ([int]$redirect_clipboard) -ResultObj $result -WhatIf:$check_mode - $result.changed = $true - } - - if ($null -ne $redirect_drives -and $redirect_drives -ne $cap.DeviceRedirection.DiskDrives) { - $diff_text += "-RedirectDrives = $($cap.DeviceRedirection.DiskDrives)`n+RedirectDrives = $redirect_drives`n" - Set-CAPPropertyValue -Name $name -Property "DeviceRedirection\DiskDrives" -Value ([int]$redirect_drives) -ResultObj $result -WhatIf:$check_mode - $result.changed = $true - } - - if ($null -ne $redirect_printers -and $redirect_printers -ne $cap.DeviceRedirection.Printers) { - $diff_text += "-RedirectPrinters = $($cap.DeviceRedirection.Printers)`n+RedirectPrinters = $redirect_printers`n" - Set-CAPPropertyValue -Name $name -Property "DeviceRedirection\Printers" -Value ([int]$redirect_printers) -ResultObj $result -WhatIf:$check_mode - $result.changed = $true - } - - if ($null -ne $redirect_serial -and $redirect_serial -ne $cap.DeviceRedirection.SerialPorts) { - $diff_text += "-RedirectSerial = $($cap.DeviceRedirection.SerialPorts)`n+RedirectSerial = $redirect_serial`n" - Set-CAPPropertyValue -Name $name -Property "DeviceRedirection\SerialPorts" -Value ([int]$redirect_serial) -ResultObj $result -WhatIf:$check_mode - $result.changed = $true - } - - if ($null -ne $redirect_pnp -and $redirect_pnp -ne $cap.DeviceRedirection.PlugAndPlayDevices) { - $diff_text += "-RedirectPnP = $($cap.DeviceRedirection.PlugAndPlayDevices)`n+RedirectPnP = $redirect_pnp`n" - Set-CAPPropertyValue -Name $name -Property "DeviceRedirection\PlugAndPlayDevices" -Value ([int]$redirect_pnp) -ResultObj $result -WhatIf:$check_mode - $result.changed = $true - } - - if ($null -ne $user_groups) { - $groups_to_remove = @($cap.UserGroups | Where-Object { $user_groups -notcontains $_ }) - $groups_to_add = @($user_groups | Where-Object { $cap.UserGroups -notcontains $_ }) - - $user_groups_diff = $null - foreach($group in $groups_to_add) { - if (-not $check_mode) { - $return = $wmi_cap | Invoke-CimMethod -MethodName AddUserGroupNames -Arguments @{ UserGroupNames = $group } - if ($return.ReturnValue -ne 0) { - Fail-Json -obj $result -message "Failed to add user group $($group) (code: $($return.ReturnValue))" - } - } - $user_groups_diff += " +$group`n" - $result.changed = $true - } - - foreach($group in $groups_to_remove) { - if (-not $check_mode) { - $return = $wmi_cap | Invoke-CimMethod -MethodName RemoveUserGroupNames -Arguments @{ UserGroupNames = $group } - if ($return.ReturnValue -ne 0) { - Fail-Json -obj $result -message "Failed to remove user group $($group) (code: $($return.ReturnValue))" - } - } - $user_groups_diff += " -$group`n" - $result.changed = $true - } - - if($user_groups_diff) { - $diff_text += "~UserGroups`n$user_groups_diff" - } - } - - if ($null -ne $computer_groups) { - $groups_to_remove = @($cap.ComputerGroups | Where-Object { $computer_groups -notcontains $_ }) - $groups_to_add = @($computer_groups | Where-Object { $cap.ComputerGroups -notcontains $_ }) - - $computer_groups_diff = $null - foreach($group in $groups_to_add) { - if (-not $check_mode) { - $return = $wmi_cap | Invoke-CimMethod -MethodName AddComputerGroupNames -Arguments @{ ComputerGroupNames = $group } - if ($return.ReturnValue -ne 0) { - Fail-Json -obj $result -message "Failed to add computer group $($group) (code: $($return.ReturnValue))" - } - } - $computer_groups_diff += " +$group`n" - $result.changed = $true - } - - foreach($group in $groups_to_remove) { - if (-not $check_mode) { - $return = $wmi_cap | Invoke-CimMethod -MethodName RemoveComputerGroupNames -Arguments @{ ComputerGroupNames = $group } - if ($return.ReturnValue -ne 0) { - Fail-Json -obj $result -message "Failed to remove computer group $($group) (code: $($return.ReturnValue))" - } - } - $computer_groups_diff += " -$group`n" - $result.changed = $true - } - - if($computer_groups_diff) { - $diff_text += "~ComputerGroups`n$computer_groups_diff" - } - } - } -} - -if ($diff_mode -and $result.changed -eq $true) { - $result.diff = @{ - prepared = $diff_text - } -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_rds_cap.py b/lib/ansible/modules/windows/win_rds_cap.py deleted file mode 100644 index 6f5c587a79b..00000000000 --- a/lib/ansible/modules/windows/win_rds_cap.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Kevin Subileau (@ksubileau) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_rds_cap -short_description: Manage Connection Authorization Policies (CAP) on a Remote Desktop Gateway server -description: - - Creates, removes and configures a Remote Desktop connection authorization policy (RD CAP). - - A RD CAP allows you to specify the users who can connect to a Remote Desktop Gateway server. -version_added: "2.8" -author: - - Kevin Subileau (@ksubileau) -options: - name: - description: - - Name of the connection authorization policy. - type: str - required: yes - state: - description: - - The state of connection authorization policy. - - If C(absent) will ensure the policy is removed. - - If C(present) will ensure the policy is configured and exists. - - If C(enabled) will ensure the policy is configured, exists and enabled. - - If C(disabled) will ensure the policy is configured, exists, but disabled. - type: str - choices: [ absent, enabled, disabled, present ] - default: present - auth_method: - description: - - Specifies how the RD Gateway server authenticates users. - - When a new CAP is created, the default value is C(password). - type: str - choices: [ both, none, password, smartcard ] - order: - description: - - Evaluation order of the policy. - - The CAP in which I(order) is set to a value of '1' is evaluated first. - - By default, a newly created CAP will take the first position. - - If the given value exceed the total number of existing policies, - the policy will take the last position but the evaluation order - will be capped to this number. - type: int - session_timeout: - description: - - The maximum time, in minutes, that a session can be idle. - - A value of zero disables session timeout. - type: int - session_timeout_action: - description: - - The action the server takes when a session times out. - - 'C(disconnect): disconnect the session.' - - 'C(reauth): silently reauthenticate and reauthorize the session.' - type: str - choices: [ disconnect, reauth ] - default: disconnect - idle_timeout: - description: - - Specifies the time interval, in minutes, after which an idle session is disconnected. - - A value of zero disables idle timeout. - type: int - allow_only_sdrts_servers: - description: - - Specifies whether connections are allowed only to Remote Desktop Session Host servers that - enforce Remote Desktop Gateway redirection policy. - type: bool - user_groups: - description: - - A list of user groups that is allowed to connect to the Remote Gateway server. - - Required when a new CAP is created. - type: list - computer_groups: - description: - - A list of computer groups that is allowed to connect to the Remote Gateway server. - type: list - redirect_clipboard: - description: - - Allow clipboard redirection. - type: bool - redirect_drives: - description: - - Allow disk drive redirection. - type: bool - redirect_printers: - description: - - Allow printers redirection. - type: bool - redirect_serial: - description: - - Allow serial port redirection. - type: bool - redirect_pnp: - description: - - Allow Plug and Play devices redirection. - type: bool -requirements: - - Windows Server 2008R2 (6.1) or higher. - - The Windows Feature "RDS-Gateway" must be enabled. -seealso: -- module: win_rds_cap -- module: win_rds_rap -- module: win_rds_settings -''' - -EXAMPLES = r''' -- name: Create a new RDS CAP with a 30 minutes timeout and clipboard redirection enabled - win_rds_cap: - name: My CAP - user_groups: - - BUILTIN\users - session_timeout: 30 - session_timeout_action: disconnect - allow_only_sdrts_servers: yes - redirect_clipboard: yes - redirect_drives: no - redirect_printers: no - redirect_serial: no - redirect_pnp: no - state: enabled -''' - -RETURN = r''' -''' diff --git a/lib/ansible/modules/windows/win_rds_rap.ps1 b/lib/ansible/modules/windows/win_rds_rap.ps1 deleted file mode 100644 index deb01a9c349..00000000000 --- a/lib/ansible/modules/windows/win_rds_rap.ps1 +++ /dev/null @@ -1,282 +0,0 @@ -#!powershell - -# Copyright: (c) 2018, Kevin Subileau (@ksubileau) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.SID - -$ErrorActionPreference = "Stop" - -# List of authentication methods as string. Used for parameter validation and conversion to integer flag, so order is important! -$computer_group_types = @("rdg_group", "ad_network_resource_group", "allow_any") -$computer_group_types_wmi = @{rdg_group = "RG"; ad_network_resource_group = "CG"; allow_any = "ALL"} - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff_mode = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$description = Get-AnsibleParam -obj $params -name "description" -type "str" -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "absent","present","enabled","disabled" -$computer_group_type = Get-AnsibleParam -obj $params -name "computer_group_type" -type "str" -validateset $computer_group_types -$computer_group = Get-AnsibleParam -obj $params -name "computer_group" -type "str" -failifempty ($computer_group_type -eq "ad_network_resource_group" -or $computer_group_type -eq "rdg_group") -$user_groups = Get-AnsibleParam -obj $params -name "user_groups" -type "list" -$allowed_ports = Get-AnsibleParam -obj $params -name "allowed_ports" -type "list" - - -function Get-RAP([string] $name) { - $rap_path = "RDS:\GatewayServer\RAP\$name" - $rap = @{ - Name = $name - } - - # Fetch RAP properties - Get-ChildItem -Path $rap_path | ForEach-Object { $rap.Add($_.Name,$_.CurrentValue) } - # Convert boolean values - $rap.Enabled = $rap.Status -eq 1 - $rap.Remove("Status") - - # Convert computer group name from UPN to Down-Level Logon format - if($rap.ComputerGroupType -ne 2) { - $rap.ComputerGroup = Convert-FromSID -sid (Convert-ToSID -account_name $rap.ComputerGroup) - } - - # Convert multiple choices values - $rap.ComputerGroupType = $computer_group_types[$rap.ComputerGroupType] - - # Convert allowed ports from string to list - if($rap.PortNumbers -eq '*') { - $rap.PortNumbers = @("any") - } else { - $rap.PortNumbers = @($rap.PortNumbers -split ',') - } - - # Fetch RAP user groups in Down-Level Logon format - $rap.UserGroups = @( - Get-ChildItem -Path "$rap_path\UserGroups" | - Select-Object -ExpandProperty Name | - ForEach-Object { Convert-FromSID -sid (Convert-ToSID -account_name $_) } - ) - - return $rap -} - -function Set-RAPPropertyValue { - [CmdletBinding(SupportsShouldProcess=$true)] - param ( - [Parameter(Mandatory=$true)] - [string] $name, - [Parameter(Mandatory=$true)] - [string] $property, - [Parameter(Mandatory=$true)] - $value, - [Parameter()] - $resultobj = @{} - ) - - $rap_path = "RDS:\GatewayServer\RAP\$name" - - try { - Set-Item -Path "$rap_path\$property" -Value $value -ErrorAction stop - } catch { - Fail-Json -obj $resultobj -message "Failed to set property $property of RAP ${name}: $($_.Exception.Message)" - } -} - -$result = @{ - changed = $false -} -$diff_text = $null - -# Validate RAP name -if ($name -match "[*/\\;:?`"<>|\t]+") { - Fail-Json -obj $result -message "Invalid character in RAP name." -} - -# Validate user groups -if ($null -ne $user_groups) { - if ($user_groups.Count -lt 1) { - Fail-Json -obj $result -message "Parameter 'user_groups' cannot be an empty list." - } - - $user_groups = $user_groups | ForEach-Object { - $group = $_ - # Test that the group is resolvable on the local machine - $sid = Convert-ToSID -account_name $group - if (!$sid) { - Fail-Json -obj $result -message "$group is not a valid user group on the host machine or domain." - } - - # Return the normalized group name in Down-Level Logon format - Convert-FromSID -sid $sid - } - $user_groups = @($user_groups) -} - -# Validate computer group parameter -if ($computer_group_type -eq "allow_any" -and $null -ne $computer_group) { - Add-Warning -obj $result -message "Parameter 'computer_group' ignored because the computer_group_type is set to allow_any." -} elseif ($computer_group_type -eq "rdg_group" -and -not (Test-Path -Path "RDS:\GatewayServer\GatewayManagedComputerGroups\$computer_group")) { - Fail-Json -obj $result -message "$computer_group is not a valid gateway managed computer group" -} elseif ($computer_group_type -eq "ad_network_resource_group") { - $sid = Convert-ToSID -account_name $computer_group - if (!$sid) { - Fail-Json -obj $result -message "$computer_group is not a valid computer group on the host machine or domain." - } - # Ensure the group name is in Down-Level Logon format - $computer_group = Convert-FromSID -sid $sid -} - -# Validate port numbers -if ($null -ne $allowed_ports) { - foreach ($port in $allowed_ports) { - if (-not ($port -eq "any" -or ($port -is [int] -and $port -ge 1 -and $port -le 65535))) { - Fail-Json -obj $result -message "$port is not a valid port number." - } - } -} - -# Ensure RemoteDesktopServices module is loaded -if ($null -eq (Get-Module -Name RemoteDesktopServices -ErrorAction SilentlyContinue)) { - Import-Module -Name RemoteDesktopServices -} - -# Check if a RAP with the given name already exists -$rap_exist = Test-Path -Path "RDS:\GatewayServer\RAP\$name" - -if ($state -eq 'absent') { - if ($rap_exist) { - Remove-Item -Path "RDS:\GatewayServer\RAP\$name" -Recurse -WhatIf:$check_mode - $diff_text += "-[$name]" - $result.changed = $true - } -} else { - $diff_text_added_prefix = '' - if (-not $rap_exist) { - if ($null -eq $user_groups) { - Fail-Json -obj $result -message "User groups must be defined to create a new RAP." - } - - # Computer group type is required when creating a new RAP. Set it to allow connect to any resource by default. - if ($null -eq $computer_group_type) { - $computer_group_type = "allow_any" - } - - # Create a new RAP - if (-not $check_mode) { - $RapArgs = @{ - Name = $name - ResourceGroupType = 'ALL' - UserGroupNames = $user_groups -join ';' - ProtocolNames = 'RDP' - PortNumbers = '*' - } - $return = Invoke-CimMethod -Namespace Root\CIMV2\TerminalServices -ClassName Win32_TSGatewayResourceAuthorizationPolicy -MethodName Create -Arguments $RapArgs - if ($return.ReturnValue -ne 0) { - Fail-Json -obj $result -message "Failed to create RAP $name (code: $($return.ReturnValue))" - } - } - $rap_exist = -not $check_mode - - $diff_text_added_prefix = '+' - $result.changed = $true - } - - $diff_text += "$diff_text_added_prefix[$name]`n" - - # We cannot configure a RAP that was created above in check mode as it won't actually exist - if($rap_exist) { - $rap = Get-RAP -Name $name - $wmi_rap = Get-CimInstance -ClassName Win32_TSGatewayResourceAuthorizationPolicy -Namespace Root\CIMv2\TerminalServices -Filter "name='$($name)'" - - if ($state -in @('disabled', 'enabled')) { - $rap_enabled = $state -ne 'disabled' - if ($rap.Enabled -ne $rap_enabled) { - $diff_text += "-State = $(@('disabled', 'enabled')[[int]$rap.Enabled])`n+State = $state`n" - Set-RAPPropertyValue -Name $name -Property Status -Value ([int]$rap_enabled) -ResultObj $result -WhatIf:$check_mode - $result.changed = $true - } - } - - if ($null -ne $description -and $description -ne $rap.Description) { - Set-RAPPropertyValue -Name $name -Property Description -Value $description -ResultObj $result -WhatIf:$check_mode - $diff_text += "-Description = $($rap.Description)`n+Description = $description`n" - $result.changed = $true - } - - if ($null -ne $allowed_ports -and @(Compare-Object $rap.PortNumbers $allowed_ports -SyncWindow 0).Count -ne 0) { - $diff_text += "-AllowedPorts = [$($rap.PortNumbers -join ',')]`n+AllowedPorts = [$($allowed_ports -join ',')]`n" - if ($allowed_ports -contains 'any') { $allowed_ports = '*' } - Set-RAPPropertyValue -Name $name -Property PortNumbers -Value $allowed_ports -ResultObj $result -WhatIf:$check_mode - $result.changed = $true - } - - if ($null -ne $computer_group_type -and $computer_group_type -ne $rap.ComputerGroupType) { - $diff_text += "-ComputerGroupType = $($rap.ComputerGroupType)`n+ComputerGroupType = $computer_group_type`n" - if ($computer_group_type -ne "allow_any") { - $diff_text += "+ComputerGroup = $computer_group`n" - } - $return = $wmi_rap | Invoke-CimMethod -MethodName SetResourceGroup -Arguments @{ - ResourceGroupName = $computer_group - ResourceGroupType = $computer_group_types_wmi.$($computer_group_type) - } - if ($return.ReturnValue -ne 0) { - Fail-Json -obj $result -message "Failed to set computer group type to $($computer_group_type) (code: $($return.ReturnValue))" - } - - $result.changed = $true - - } elseif ($null -ne $computer_group -and $computer_group -ne $rap.ComputerGroup) { - $diff_text += "-ComputerGroup = $($rap.ComputerGroup)`n+ComputerGroup = $computer_group`n" - $return = $wmi_rap | Invoke-CimMethod -MethodName SetResourceGroup -Arguments @{ - ResourceGroupName = $computer_group - ResourceGroupType = $computer_group_types_wmi.$($rap.ComputerGroupType) - } - if ($return.ReturnValue -ne 0) { - Fail-Json -obj $result -message "Failed to set computer group name to $($computer_group) (code: $($return.ReturnValue))" - } - $result.changed = $true - } - - if ($null -ne $user_groups) { - $groups_to_remove = @($rap.UserGroups | Where-Object { $user_groups -notcontains $_ }) - $groups_to_add = @($user_groups | Where-Object { $rap.UserGroups -notcontains $_ }) - - $user_groups_diff = $null - foreach($group in $groups_to_add) { - if (-not $check_mode) { - $return = $wmi_rap | Invoke-CimMethod -MethodName AddUserGroupNames -Arguments @{ UserGroupNames = $group } - if ($return.ReturnValue -ne 0) { - Fail-Json -obj $result -message "Failed to add user group $($group) (code: $($return.ReturnValue))" - } - } - $user_groups_diff += " +$group`n" - $result.changed = $true - } - - foreach($group in $groups_to_remove) { - if (-not $check_mode) { - $return = $wmi_rap | Invoke-CimMethod -MethodName RemoveUserGroupNames -Arguments @{ UserGroupNames = $group } - if ($return.ReturnValue -ne 0) { - Fail-Json -obj $result -message "Failed to remove user group $($group) (code: $($return.ReturnValue))" - } - } - $user_groups_diff += " -$group`n" - $result.changed = $true - } - - if($user_groups_diff) { - $diff_text += "~UserGroups`n$user_groups_diff" - } - } - } -} - -if ($diff_mode -and $result.changed -eq $true) { - $result.diff = @{ - prepared = $diff_text - } -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_rds_rap.py b/lib/ansible/modules/windows/win_rds_rap.py deleted file mode 100644 index c6e60be102a..00000000000 --- a/lib/ansible/modules/windows/win_rds_rap.py +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Kevin Subileau (@ksubileau) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_rds_rap -short_description: Manage Resource Authorization Policies (RAP) on a Remote Desktop Gateway server -description: - - Creates, removes and configures a Remote Desktop resource authorization policy (RD RAP). - - A RD RAP allows you to specify the network resources (computers) that users can connect - to remotely through a Remote Desktop Gateway server. -version_added: "2.8" -author: - - Kevin Subileau (@ksubileau) -options: - name: - description: - - Name of the resource authorization policy. - required: yes - state: - description: - - The state of resource authorization policy. - - If C(absent) will ensure the policy is removed. - - If C(present) will ensure the policy is configured and exists. - - If C(enabled) will ensure the policy is configured, exists and enabled. - - If C(disabled) will ensure the policy is configured, exists, but disabled. - type: str - choices: [ absent, disabled, enabled, present ] - default: present - description: - description: - - Optional description of the resource authorization policy. - type: str - user_groups: - description: - - List of user groups that are associated with this resource authorization policy (RAP). - A user must belong to one of these groups to access the RD Gateway server. - - Required when a new RAP is created. - type: list - allowed_ports: - description: - - List of port numbers through which connections are allowed for this policy. - - To allow connections through any port, specify 'any'. - type: list - computer_group_type: - description: - - 'The computer group type:' - - 'C(rdg_group): RD Gateway-managed group' - - 'C(ad_network_resource_group): Active Directory Domain Services network resource group' - - 'C(allow_any): Allow users to connect to any network resource.' - type: str - choices: [ rdg_group, ad_network_resource_group, allow_any ] - computer_group: - description: - - The computer group name that is associated with this resource authorization policy (RAP). - - This is required when I(computer_group_type) is C(rdg_group) or C(ad_network_resource_group). - type: str -requirements: - - Windows Server 2008R2 (6.1) or higher. - - The Windows Feature "RDS-Gateway" must be enabled. -seealso: -- module: win_rds_cap -- module: win_rds_rap -- module: win_rds_settings -''' - -EXAMPLES = r''' -- name: Create a new RDS RAP - win_rds_rap: - name: My RAP - description: Allow all users to connect to any resource through ports 3389 and 3390 - user_groups: - - BUILTIN\users - computer_group_type: allow_any - allowed_ports: - - 3389 - - 3390 - state: enabled -''' - -RETURN = r''' -''' diff --git a/lib/ansible/modules/windows/win_rds_settings.ps1 b/lib/ansible/modules/windows/win_rds_settings.ps1 deleted file mode 100644 index 7a31fe12757..00000000000 --- a/lib/ansible/modules/windows/win_rds_settings.ps1 +++ /dev/null @@ -1,100 +0,0 @@ -#!powershell - -# Copyright: (c) 2018, Kevin Subileau (@ksubileau) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" - -# List of ssl bridging methods as string. Used for parameter validation and conversion to integer flag, so order is important! -$ssl_bridging_methods = @("none", "https_http", "https_https") - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff_mode = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false - -$certificate = Get-AnsibleParam $params -name "certificate_hash" -type "str" -$max_connections = Get-AnsibleParam $params -name "max_connections" -type "int" -$ssl_bridging = Get-AnsibleParam -obj $params -name "ssl_bridging" -type "str" -validateset $ssl_bridging_methods -$enable_only_messaging_capable_clients = Get-AnsibleParam $params -name "enable_only_messaging_capable_clients" -type "bool" - -$result = @{ - changed = $false -} -$diff_text = $null - -# Ensure RemoteDesktopServices module is loaded -if ($null -eq (Get-Module -Name RemoteDesktopServices -ErrorAction SilentlyContinue)) { - Import-Module -Name RemoteDesktopServices -} - -if ($null -ne $certificate) -{ - # Validate cert path - $cert_path = "cert:\LocalMachine\My\$certificate" - If (-not (Test-Path $cert_path) ) - { - Fail-Json -obj $result -message "Unable to locate certificate at $cert_path" - } - - # Get current certificate hash - $current_cert = (Get-Item -Path "RDS:\GatewayServer\SSLCertificate\Thumbprint").CurrentValue - if ($current_cert -ne $certificate) { - Set-Item -Path "RDS:\GatewayServer\SSLCertificate\Thumbprint" -Value $certificate -WhatIf:$check_mode - $diff_text += "-Certificate = $current_cert`n+Certificate = $certificate`n" - $result.changed = $true - } -} - -if ($null -ne $max_connections) -{ - # Set the correct value for unlimited connections - # TODO Use a more explicit value, maybe a string (ex: "max", "none" or "unlimited") ? - If ($max_connections -eq -1) - { - $max_connections = (Get-Item -Path "RDS:\GatewayServer\MaxConnectionsAllowed").CurrentValue - } - - # Get current connections limit - $current_max_connections = (Get-Item -Path "RDS:\GatewayServer\MaxConnections").CurrentValue - if ($current_max_connections -ne $max_connections) { - Set-Item -Path "RDS:\GatewayServer\MaxConnections" -Value $max_connections -WhatIf:$check_mode - $diff_text += "-MaxConnections = $current_max_connections`n+MaxConnections = $max_connections`n" - $result.changed = $true - } -} - -if ($null -ne $ssl_bridging) -{ - $current_ssl_bridging = (Get-Item -Path "RDS:\GatewayServer\SSLBridging").CurrentValue - # Convert the integer value to its representative string - $current_ssl_bridging_str = $ssl_bridging_methods[$current_ssl_bridging] - - if ($current_ssl_bridging_str -ne $ssl_bridging) { - Set-Item -Path "RDS:\GatewayServer\SSLBridging" -Value ([array]::IndexOf($ssl_bridging_methods, $ssl_bridging)) -WhatIf:$check_mode - $diff_text += "-SSLBridging = $current_ssl_bridging_str`n+SSLBridging = $ssl_bridging`n" - $result.changed = $true - } -} - -if ($null -ne $enable_only_messaging_capable_clients) -{ - $current_enable_only_messaging_capable_clients = (Get-Item -Path "RDS:\GatewayServer\EnableOnlyMessagingCapableClients").CurrentValue - # Convert the integer value to boolean - $current_enable_only_messaging_capable_clients = $current_enable_only_messaging_capable_clients -eq 1 - - if ($current_enable_only_messaging_capable_clients -ne $enable_only_messaging_capable_clients) { - Set-Item -Path "RDS:\GatewayServer\EnableOnlyMessagingCapableClients" -Value ([int]$enable_only_messaging_capable_clients) -WhatIf:$check_mode - $diff_text += "-EnableOnlyMessagingCapableClients = $current_enable_only_messaging_capable_clients`n+EnableOnlyMessagingCapableClients = $enable_only_messaging_capable_clients`n" - $result.changed = $true - } -} - -if ($diff_mode -and $result.changed -eq $true) { - $result.diff = @{ - prepared = $diff_text - } -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_rds_settings.py b/lib/ansible/modules/windows/win_rds_settings.py deleted file mode 100644 index 5919a816e14..00000000000 --- a/lib/ansible/modules/windows/win_rds_settings.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Kevin Subileau (@ksubileau) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_rds_settings -short_description: Manage main settings of a Remote Desktop Gateway server -description: - - Configure general settings of a Remote Desktop Gateway server. -version_added: "2.8" -author: - - Kevin Subileau (@ksubileau) -options: - certificate_hash: - description: - - Certificate hash (thumbprint) for the Remote Desktop Gateway server. The certificate hash is the unique identifier for the certificate. - type: str - max_connections: - description: - - The maximum number of connections allowed. - - If set to C(0), no new connections are allowed. - - If set to C(-1), the number of connections is unlimited. - type: int - ssl_bridging: - description: - - Specifies whether to use SSL Bridging. - - 'C(none): no SSL bridging.' - - 'C(https_http): HTTPS-HTTP bridging.' - - 'C(https_https): HTTPS-HTTPS bridging.' - type: str - choices: [ https_http, https_https, none ] - enable_only_messaging_capable_clients: - description: - - If enabled, only clients that support logon messages and administrator messages can connect. - type: bool -requirements: - - Windows Server 2008R2 (6.1) or higher. - - The Windows Feature "RDS-Gateway" must be enabled. -seealso: -- module: win_rds_cap -- module: win_rds_rap -- module: win_rds_settings -''' - -EXAMPLES = r''' -- name: Configure the Remote Desktop Gateway - win_rds_settings: - certificate_hash: B0D0FA8408FC67B230338FCA584D03792DA73F4C - max_connections: 50 - notify: - - Restart TSGateway service -''' - -RETURN = r''' -''' diff --git a/lib/ansible/modules/windows/win_region.ps1 b/lib/ansible/modules/windows/win_region.ps1 deleted file mode 100644 index 7542a8b1d16..00000000000 --- a/lib/ansible/modules/windows/win_region.ps1 +++ /dev/null @@ -1,365 +0,0 @@ -#!powershell - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params "_ansible_check_mode" -type 'bool' -default $false -$_remote_tmp = Get-AnsibleParam $params "_ansible_remote_tmp" -type "path" -default $env:TMP - -$location = Get-AnsibleParam -obj $params -name 'location' -type 'str' -$format = Get-AnsibleParam -obj $params -name 'format' -type 'str' -$unicode_language = Get-AnsibleParam -obj $params -name 'unicode_language' -type 'str' -$copy_settings = Get-AnsibleParam -obj $params -name 'copy_settings' -type 'bool' -default $false - -$result = @{ - changed = $false - restart_required = $false -} - -# This is used to get the format values based on the LCType enum based through. When running Vista/7/2008/200R2 -$lctype_util = @" -using System; -using System.Text; -using System.Runtime.InteropServices; -using System.ComponentModel; - -namespace Ansible.WinRegion { - - public class NativeMethods - { - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern int GetLocaleInfoEx( - String lpLocaleName, - UInt32 LCType, - StringBuilder lpLCData, - int cchData); - - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern int GetSystemDefaultLocaleName( - IntPtr lpLocaleName, - int cchLocaleName); - - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern int GetUserDefaultLocaleName( - IntPtr lpLocaleName, - int cchLocaleName); - } - - public class LocaleHelper { - private String Locale; - - public LocaleHelper(String locale) { - Locale = locale; - } - - public String GetValueFromType(UInt32 LCType) { - StringBuilder data = new StringBuilder(500); - int result = NativeMethods.GetLocaleInfoEx(Locale, LCType, data, 500); - if (result == 0) - throw new Exception(String.Format("Error getting locale info with legacy method: {0}", new Win32Exception(Marshal.GetLastWin32Error()).Message)); - - return data.ToString(); - } - } -} -"@ -$original_tmp = $env:TMP -$env:TMP = $_remote_tmp -Add-Type -TypeDefinition $lctype_util -$env:TMP = $original_tmp - -Function Get-LastWin32ExceptionMessage { - param([int]$ErrorCode) - $exp = New-Object -TypeName System.ComponentModel.Win32Exception -ArgumentList $ErrorCode - $exp_msg = "{0} (Win32 ErrorCode {1} - 0x{1:X8})" -f $exp.Message, $ErrorCode - return $exp_msg -} - -Function Get-SystemLocaleName { - $max_length = 85 # LOCALE_NAME_MAX_LENGTH - $ptr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($max_length) - - try { - $res = [Ansible.WinRegion.NativeMethods]::GetSystemDefaultLocaleName($ptr, $max_length) - - if ($res -eq 0) { - $err_code = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() - $msg = Get-LastWin32ExceptionMessage -Error $err_code - Fail-Json -obj $result -message "Failed to get system locale: $msg" - } - - $system_locale = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr) - } finally { - [System.Runtime.InteropServices.Marshal]::FreeHGlobal($ptr) - } - - return $system_locale -} - -Function Get-UserLocaleName { - $max_length = 85 # LOCALE_NAME_MAX_LENGTH - $ptr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($max_length) - - try { - $res = [Ansible.WinRegion.NativeMethods]::GetUserDefaultLocaleName($ptr, $max_length) - - if ($res -eq 0) { - $err_code = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() - $msg = Get-LastWin32ExceptionMessage -Error $err_code - Fail-Json -obj $result -message "Failed to get user locale: $msg" - } - - $user_locale = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr) - } finally { - [System.Runtime.InteropServices.Marshal]::FreeHGlobal($ptr) - } - - return $user_locale -} - -Function Get-ValidGeoIds($cultures) { - $geo_ids = @() - foreach($culture in $cultures) { - try { - $geo_id = [System.Globalization.RegionInfo]$culture.Name - $geo_ids += $geo_id.GeoId - } catch {} - } - $geo_ids -} - -Function Test-RegistryProperty($reg_key, $property) { - $type = Get-ItemProperty $reg_key -Name $property -ErrorAction SilentlyContinue - if ($null -eq $type) { - $false - } else { - $true - } -} - -Function Copy-RegistryKey($source, $target) { - # Using Copy-Item -Recurse is giving me weird results, doing it recursively - Copy-Item -Path $source -Destination $target -WhatIf:$check_mode - - foreach($key in Get-ChildItem $source) { - $sourceKey = "$source\$($key.PSChildName)" - $targetKey = (Get-Item $source).PSChildName - Copy-RegistryKey -source "$sourceKey" -target "$target\$targetKey" - } -} - -Function Set-UserLocale($culture) { - $reg_key = 'HKCU:\Control Panel\International' - - $lookup = New-Object Ansible.WinRegion.LocaleHelper($culture) - # hex values are from http://www.pinvoke.net/default.aspx/kernel32/GetLocaleInfoEx.html - $wanted_values = @{ - Locale = '{0:x8}' -f ([System.Globalization.CultureInfo]$culture).LCID - LocaleName = $culture - s1159 = $lookup.GetValueFromType(0x00000028) - s2359 = $lookup.GetValueFromType(0x00000029) - sCountry = $lookup.GetValueFromType(0x00000006) - sCurrency = $lookup.GetValueFromType(0x00000014) - sDate = $lookup.GetValueFromType(0x0000001D) - sDecimal = $lookup.GetValueFromType(0x0000000E) - sGrouping = $lookup.GetValueFromType(0x00000010) - sLanguage = $lookup.GetValueFromType(0x00000003) # LOCALE_ABBREVLANGNAME - sList = $lookup.GetValueFromType(0x0000000C) - sLongDate = $lookup.GetValueFromType(0x00000020) - sMonDecimalSep = $lookup.GetValueFromType(0x00000016) - sMonGrouping = $lookup.GetValueFromType(0x00000018) - sMonThousandSep = $lookup.GetValueFromType(0x00000017) - sNativeDigits = $lookup.GetValueFromType(0x00000013) - sNegativeSign = $lookup.GetValueFromType(0x00000051) - sPositiveSign = $lookup.GetValueFromType(0x00000050) - sShortDate = $lookup.GetValueFromType(0x0000001F) - sThousand = $lookup.GetValueFromType(0x0000000F) - sTime = $lookup.GetValueFromType(0x0000001E) - sTimeFormat = $lookup.GetValueFromType(0x00001003) - sYearMonth = $lookup.GetValueFromType(0x00001006) - iCalendarType = $lookup.GetValueFromType(0x00001009) - iCountry = $lookup.GetValueFromType(0x00000005) - iCurrDigits = $lookup.GetValueFromType(0x00000019) - iCurrency = $lookup.GetValueFromType(0x0000001B) - iDate = $lookup.GetValueFromType(0x00000021) - iDigits = $lookup.GetValueFromType(0x00000011) - NumShape = $lookup.GetValueFromType(0x00001014) # LOCALE_IDIGITSUBSTITUTION - iFirstDayOfWeek = $lookup.GetValueFromType(0x0000100C) - iFirstWeekOfYear = $lookup.GetValueFromType(0x0000100D) - iLZero = $lookup.GetValueFromType(0x00000012) - iMeasure = $lookup.GetValueFromType(0x0000000D) - iNegCurr = $lookup.GetValueFromType(0x0000001C) - iNegNumber = $lookup.GetValueFromType(0x00001010) - iPaperSize = $lookup.GetValueFromType(0x0000100A) - iTime = $lookup.GetValueFromType(0x00000023) - iTimePrefix = $lookup.GetValueFromType(0x00001005) - iTLZero = $lookup.GetValueFromType(0x00000025) - } - - if (Test-RegistryProperty -reg_key $reg_key -property 'sShortTime') { - # sShortTime was added after Vista, will check anyway and add in the value if it exists - $wanted_values.sShortTime = $lookup.GetValueFromType(0x00000079) - } - - $properties = Get-ItemProperty $reg_key - foreach($property in $properties.PSObject.Properties) { - if (Test-RegistryProperty -reg_key $reg_key -property $property.Name) { - $name = $property.Name - $old_value = $property.Value - $new_value = $wanted_values.$name - - if ($new_value -ne $old_value) { - Set-ItemProperty -Path $reg_key -Name $name -Value $new_value -WhatIf:$check_mode - $result.changed = $true - } - } - } -} - -Function Set-SystemLocaleLegacy($unicode_language) { - # For when Get/Set-WinSystemLocale is not available (Pre Windows 8 and Server 2012) - $current_language_value = (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Language').Default - $wanted_language_value = '{0:x4}' -f ([System.Globalization.CultureInfo]$unicode_language).LCID - if ($current_language_value -ne $wanted_language_value) { - Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Language' -Name 'Default' -Value $wanted_language_value -WhatIf:$check_mode - $result.changed = $true - $result.restart_required = $true - } - - # This reads from the non registry (Default) key, the extra prop called (Default) see below for more details - $current_locale_value = (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Locale')."(Default)" - $wanted_locale_value = '{0:x8}' -f ([System.Globalization.CultureInfo]$unicode_language).LCID - if ($current_locale_value -ne $wanted_locale_value) { - # Need to use .net to write property value, Locale has 2 (Default) properties - # 1: The actual (Default) property, we don't want to change Set-ItemProperty writes to this value when using (Default) - # 2: A property called (Default), this is what we want to change and only .net SetValue can do this one - if (-not $check_mode) { - $hive = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine", $env:COMPUTERNAME) - $key = $hive.OpenSubKey("SYSTEM\CurrentControlSet\Control\Nls\Locale", $true) - $key.SetValue("(Default)", $wanted_locale_value, [Microsoft.Win32.RegistryValueKind]::String) - } - $result.changed = $true - $result.restart_required = $true - } - - $codepage_path = 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage' - $current_codepage_info = Get-ItemProperty $codepage_path - $wanted_codepage_info = ([System.Globalization.CultureInfo]::GetCultureInfo($unicode_language)).TextInfo - - $current_a_cp = $current_codepage_info.ACP - $current_oem_cp = $current_codepage_info.OEMCP - $current_mac_cp = $current_codepage_info.MACCP - $wanted_a_cp = $wanted_codepage_info.ANSICodePage - $wanted_oem_cp = $wanted_codepage_info.OEMCodePage - $wanted_mac_cp = $wanted_codepage_info.MacCodePage - - if ($current_a_cp -ne $wanted_a_cp) { - Set-ItemProperty -Path $codepage_path -Name 'ACP' -Value $wanted_a_cp -WhatIf:$check_mode - $result.changed = $true - $result.restart_required = $true - } - if ($current_oem_cp -ne $wanted_oem_cp) { - Set-ItemProperty -Path $codepage_path -Name 'OEMCP' -Value $wanted_oem_cp -WhatIf:$check_mode - $result.changed = $true - $result.restart_required = $true - } - if ($current_mac_cp -ne $wanted_mac_cp) { - Set-ItemProperty -Path $codepage_path -Name 'MACCP' -Value $wanted_mac_cp -WhatIf:$check_mode - $result.changed = $true - $result.restart_required = $true - } -} - -if ($null -eq $format -and $null -eq $location -and $null -eq $unicode_language) { - Fail-Json $result "An argument for 'format', 'location' or 'unicode_language' needs to be supplied" -} else { - $valid_cultures = [System.Globalization.CultureInfo]::GetCultures('InstalledWin32Cultures') - $valid_geoids = Get-ValidGeoIds -cultures $valid_cultures - - if ($null -ne $location) { - if ($valid_geoids -notcontains $location) { - Fail-Json $result "The argument location '$location' does not contain a valid Geo ID" - } - } - - if ($null -ne $format) { - if ($valid_cultures.Name -notcontains $format) { - Fail-Json $result "The argument format '$format' does not contain a valid Culture Name" - } - } - - if ($null -ne $unicode_language) { - if ($valid_cultures.Name -notcontains $unicode_language) { - Fail-Json $result "The argument unicode_language '$unicode_language' does not contain a valid Culture Name" - } - } -} - -if ($null -ne $location) { - # Get-WinHomeLocation was only added in Server 2012 and above - # Use legacy option if older - if (Get-Command 'Get-WinHomeLocation' -ErrorAction SilentlyContinue) { - $current_location = (Get-WinHomeLocation).GeoId - if ($current_location -ne $location) { - if (-not $check_mode) { - Set-WinHomeLocation -GeoId $location - } - $result.changed = $true - } - } else { - $current_location = (Get-ItemProperty -Path 'HKCU:\Control Panel\International\Geo').Nation - if ($current_location -ne $location) { - Set-ItemProperty -Path 'HKCU:\Control Panel\International\Geo' -Name 'Nation' -Value $location -WhatIf:$check_mode - $result.changed = $true - } - } -} - -if ($null -ne $format) { - # Cannot use Get/Set-Culture as that fails to get and set the culture when running in the PSRP runspace. - $current_format = Get-UserLocaleName - if ($current_format -ne $format) { - Set-UserLocale -culture $format - $result.changed = $true - } -} - -if ($null -ne $unicode_language) { - # Get/Set-WinSystemLocale was only added in Server 2012 and above, use legacy option if older - if (Get-Command 'Get-WinSystemLocale' -ErrorAction SilentlyContinue) { - $current_unicode_language = Get-SystemLocaleName - if ($current_unicode_language -ne $unicode_language) { - if (-not $check_mode) { - Set-WinSystemLocale -SystemLocale $unicode_language - } - $result.changed = $true - $result.restart_required = $true - } - } else { - Set-SystemLocaleLegacy -unicode_language $unicode_language - } -} - -if ($copy_settings -eq $true -and $result.changed -eq $true) { - if (-not $check_mode) { - $defaultHiveKey = 'HKU\TEMP' - reg load $defaultHiveKey 'C:\Users\Default\NTUSER.DAT' - New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS - - $sids = 'TEMP', '.DEFAULT', 'S-1-5-19', 'S-1-5-20' - foreach ($sid in $sids) { - Copy-RegistryKey -source "HKCU:\Keyboard Layout" -target "HKU:\$sid" - Copy-RegistryKey -source "HKCU:\Control Panel\International" -target "HKU:\$sid\Control Panel" - Copy-RegistryKey -source "HKCU:\Control Panel\Input Method" -target "HKU:\$sid\Control Panel" - } - - Remove-PSDrive HKU - [gc]::collect() - reg unload $defaultHiveKey - } - $result.changed = $true -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_region.py b/lib/ansible/modules/windows/win_region.py deleted file mode 100644 index 84ef3be0809..00000000000 --- a/lib/ansible/modules/windows/win_region.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2016, Ansible, inc -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' -module: win_region -version_added: "2.3" -short_description: Set the region and format settings -description: - - Set the location settings of a Windows Server. - - Set the format settings of a Windows Server. - - Set the unicode language settings of a Windows Server. - - Copy across these settings to the default profile. -options: - location: - description: - - The location to set for the current user, see - U(https://msdn.microsoft.com/en-us/library/dd374073.aspx) - for a list of GeoIDs you can use and what location it relates to. - - This needs to be set if C(format) or C(unicode_language) is not - set. - type: str - format: - description: - - The language format to set for the current user, see - U(https://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.aspx) - for a list of culture names to use. - - This needs to be set if C(location) or C(unicode_language) is not set. - type: str - unicode_language: - description: - - The unicode language format to set for all users, see - U(https://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.aspx) - for a list of culture names to use. - - This needs to be set if C(location) or C(format) is not set. After setting this - value a reboot is required for it to take effect. - type: str - copy_settings: - description: - - This will copy the current format and location values to new user - profiles and the welcome screen. This will only run if - C(location), C(format) or C(unicode_language) has resulted in a - change. If this process runs then it will always result in a - change. - type: bool - default: no -seealso: -- module: win_timezone -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Set the region format to English United States - win_region: - format: en-US - -- name: Set the region format to English Australia and copy settings to new profiles - win_region: - format: en-AU - copy_settings: yes - -- name: Set the location to United States - win_region: - location: 244 - -# Reboot when region settings change -- name: Set the unicode language to English Great Britain, reboot if required - win_region: - unicode_language: en-GB - register: result - -- win_reboot: - when: result.restart_required - -# Reboot when format, location or unicode has changed -- name: Set format, location and unicode to English Australia and copy settings, reboot if required - win_region: - location: 12 - format: en-AU - unicode_language: en-AU - register: result - -- win_reboot: - when: result.restart_required -''' - -RETURN = r''' -restart_required: - description: Whether a reboot is required for the change to take effect. - returned: success - type: bool - sample: true -''' diff --git a/lib/ansible/modules/windows/win_regmerge.ps1 b/lib/ansible/modules/windows/win_regmerge.ps1 deleted file mode 100644 index 44c3ae1b1e6..00000000000 --- a/lib/ansible/modules/windows/win_regmerge.ps1 +++ /dev/null @@ -1,97 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Jon Hawkesworth (@jhawkesworth) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.ArgvParser -#Requires -Module Ansible.ModuleUtils.CommandUtil -#Requires -Module Ansible.ModuleUtils.Legacy - -Function Convert-RegistryPath { - Param ( - [parameter(Mandatory=$True)] - [ValidateNotNullOrEmpty()]$Path - ) - - $output = $Path -replace "HKLM:", "HKLM" - $output = $output -replace "HKCU:", "HKCU" - - Return $output -} - -$result = @{ - changed = $false -} -$params = Parse-Args $args - -$path = Get-AnsibleParam -obj $params -name "path" -type "path" -failifempty $true -resultobj $result -$compare_to = Get-AnsibleParam -obj $params -name "compare_to" -type "str" -resultobj $result - -# check it looks like a reg key, warn if key not present - will happen first time -# only accepting PS-Drive style key names (starting with HKLM etc, not HKEY_LOCAL_MACHINE etc) - -$do_comparison = $False - -If ($compare_to) { - $compare_to_key = $params.compare_to.ToString() - If (Test-Path $compare_to_key -pathType container ) { - $do_comparison = $True - } Else { - $result.compare_to_key_found = $false - } -} - -If ( $do_comparison -eq $True ) { - $guid = [guid]::NewGuid() - $exported_path = $env:TEMP + "\" + $guid.ToString() + 'ansible_win_regmerge.reg' - - $expanded_compare_key = Convert-RegistryPath ($compare_to_key) - - # export from the reg key location to a file - $reg_args = Argv-ToString -Arguments @("reg.exe", "EXPORT", $expanded_compare_key, $exported_path) - $res = Run-Command -command $reg_args - if ($res.rc -ne 0) { - $result.rc = $res.rc - $result.stdout = $res.stdout - $result.stderr = $res.stderr - Fail-Json -obj $result -message "error exporting registry '$expanded_compare_key' to '$exported_path'" - } - - # compare the two files - $comparison_result = Compare-Object -ReferenceObject $(Get-Content $path) -DifferenceObject $(Get-Content $exported_path) - - If ($null -ne $comparison_result -and (Get-Member -InputObject $comparison_result -Name "count" -MemberType Properties )) - { - # Something is different, actually do reg merge - $reg_import_args = Argv-ToString -Arguments @("reg.exe", "IMPORT", $path) - $res = Run-Command -command $reg_import_args - if ($res.rc -ne 0) { - $result.rc = $res.rc - $result.stdout = $res.stdout - $result.stderr = $res.stderr - Fail-Json -obj $result -message "error importing registry values from '$path'" - } - $result.changed = $true - $result.difference_count = $comparison_result.count - } Else { - $result.difference_count = 0 - } - - Remove-Item $exported_path - $result.compared = $true - -} Else { - # not comparing, merge and report changed - $reg_import_args = Argv-ToString -Arguments @("reg.exe", "IMPORT", $path) - $res = Run-Command -command $reg_import_args - if ($res.rc -ne 0) { - $result.rc = $res.rc - $result.stdout = $res.stdout - $result.stderr = $res.stderr - Fail-Json -obj $result -message "error importing registry value from '$path'" - } - $result.changed = $true - $result.compared = $false -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_regmerge.py b/lib/ansible/modules/windows/win_regmerge.py deleted file mode 100644 index 1b5596f9454..00000000000 --- a/lib/ansible/modules/windows/win_regmerge.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Jon Hawkesworth (@jhawkesworth) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_regmerge -version_added: "2.1" -short_description: Merges the contents of a registry file into the Windows registry -description: - - Wraps the reg.exe command to import the contents of a registry file. - - Suitable for use with registry files created using M(win_template). - - Windows registry files have a specific format and must be constructed correctly with carriage return and line feed line endings otherwise they will not - be merged. - - Exported registry files often start with a Byte Order Mark which must be removed if the file is to templated using M(win_template). - - Registry file format is described at U(https://support.microsoft.com/en-us/kb/310516) - - See also M(win_template), M(win_regedit) -options: - path: - description: - - The full path including file name to the registry file on the remote machine to be merged - type: path - required: yes - compare_key: - description: - - The parent key to use when comparing the contents of the registry to the contents of the file. Needs to be in HKLM or HKCU part of registry. - Use a PS-Drive style path for example HKLM:\SOFTWARE not HKEY_LOCAL_MACHINE\SOFTWARE - If not supplied, or the registry key is not found, no comparison will be made, and the module will report changed. - type: str -notes: - - Organise your registry files so that they contain a single root registry - key if you want to use the compare_to functionality. - - This module does not force registry settings to be in the state - described in the file. If registry settings have been modified externally - the module will merge the contents of the file but continue to report - differences on subsequent runs. - - To force registry change, use M(win_regedit) with C(state=absent) before - using C(win_regmerge). -seealso: -- module: win_reg_stat -- module: win_regedit -author: -- Jon Hawkesworth (@jhawkesworth) -''' - -EXAMPLES = r''' -- name: Merge in a registry file without comparing to current registry - win_regmerge: - path: C:\autodeploy\myCompany-settings.reg - -- name: Compare and merge registry file - win_regmerge: - path: C:\autodeploy\myCompany-settings.reg - compare_to: HKLM:\SOFTWARE\myCompany -''' - -RETURN = r''' -compare_to_key_found: - description: whether the parent registry key has been found for comparison - returned: when comparison key not found in registry - type: bool - sample: false -difference_count: - description: number of differences between the registry and the file - returned: changed - type: int - sample: 1 -compared: - description: whether a comparison has taken place between the registry and the file - returned: when a comparison key has been supplied and comparison has been attempted - type: bool - sample: true -''' diff --git a/lib/ansible/modules/windows/win_robocopy.ps1 b/lib/ansible/modules/windows/win_robocopy.ps1 deleted file mode 100644 index 6ef83e299e2..00000000000 --- a/lib/ansible/modules/windows/win_robocopy.ps1 +++ /dev/null @@ -1,145 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Corwin Brown -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$src = Get-AnsibleParam -obj $params -name "src" -type "path" -failifempty $true -$dest = Get-AnsibleParam -obj $params -name "dest" -type "path" -failifempty $true -$purge = Get-AnsibleParam -obj $params -name "purge" -type "bool" -default $false -$recurse = Get-AnsibleParam -obj $params -name "recurse" -type "bool" -default $false -$flags = Get-AnsibleParam -obj $params -name "flags" -type "str" - -$result = @{ - changed = $false - dest = $dest - purge = $purge - recurse = $recurse - src = $src -} - -# Search for an Error Message -# Robocopy seems to display an error after 3 '-----' separator lines -Function SearchForError($cmd_output, $default_msg) { - $separator_count = 0 - $error_msg = $default_msg - ForEach ($line in $cmd_output) { - if (-not $line) { - continue - } - - if ($separator_count -ne 3) { - if (Select-String -InputObject $line -pattern "^(\s+)?(\-+)(\s+)?$") { - $separator_count += 1 - } - } else { - if (Select-String -InputObject $line -pattern "error") { - $error_msg = $line - break - } - } - } - - return $error_msg -} - -if (-not (Test-Path -Path $src)) { - Fail-Json $result "$src does not exist!" -} - -# Build Arguments -$robocopy_opts = @($src, $dest) - -if ($check_mode) { - $robocopy_opts += "/l" -} - -if ($null -eq $flags) { - if ($purge) { - $robocopy_opts += "/purge" - } - - if ($recurse) { - $robocopy_opts += "/e" - } -} else { - ForEach ($f in $flags.split(" ")) { - $robocopy_opts += $f - } -} - -$result.flags = $flags -$result.cmd = "$robocopy $robocopy_opts" - -Try { - $robocopy_output = &robocopy $robocopy_opts - $rc = $LASTEXITCODE -} Catch { - Fail-Json $result "Error synchronizing $src to $dest! Msg: $($_.Exception.Message)" -} - -$result.msg = "Success" -$result.output = $robocopy_output -$result.return_code = $rc # Backward compatibility -$result.rc = $rc - -switch ($rc) { - - 0 { - $result.msg = "No files copied." - } - 1 { - $result.msg = "Files copied successfully!" - $result.changed = $true - $result.failed = $false - } - 2 { - $result.msg = "Some Extra files or directories were detected. No files were copied." - Add-Warning $result $result.msg - $result.failed = $false - } - 3 { - $result.msg = "(2+1) Some files were copied. Additional files were present." - Add-Warning $result $result.msg - $result.changed = $true - $result.failed = $false - } - 4 { - $result.msg = "Some mismatched files or directories were detected. Housekeeping might be required!" - Add-Warning $result $result.msg - $result.changed = $true - $result.failed = $false - } - 5 { - $result.msg = "(4+1) Some files were copied. Some files were mismatched." - Add-Warning $result $result.msg - $result.changed = $true - $result.failed = $false - } - 6 { - $result.msg = "(4+2) Additional files and mismatched files exist. No files were copied." - $result.failed = $false - } - 7 { - $result.msg = "(4+1+2) Files were copied, a file mismatch was present, and additional files were present." - Add-Warning $result $result.msg - $result.changed = $true - $result.failed = $false - } - 8 { - Fail-Json $result (SearchForError $robocopy_output "Some files or directories could not be copied!") - } - { @(9, 10, 11, 12, 13, 14, 15) -contains $_ } { - Fail-Json $result (SearchForError $robocopy_output "Fatal error. Check log message!") - } - 16 { - Fail-Json $result (SearchForError $robocopy_output "Serious Error! No files were copied! Do you have permissions to access $src and $dest?") - } - -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_robocopy.py b/lib/ansible/modules/windows/win_robocopy.py deleted file mode 100644 index f652f151a3c..00000000000 --- a/lib/ansible/modules/windows/win_robocopy.py +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Corwin Brown -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_robocopy -version_added: '2.2' -short_description: Synchronizes the contents of two directories using Robocopy -description: -- Synchronizes the contents of files/directories from a source to destination. -- Under the hood this just calls out to RoboCopy, since that should be available - on most modern Windows systems. -options: - src: - description: - - Source file/directory to sync. - type: path - required: yes - dest: - description: - - Destination file/directory to sync (Will receive contents of src). - type: path - required: yes - recurse: - description: - - Includes all subdirectories (Toggles the C(/e) flag to RoboCopy). - - If C(flags) is set, this will be ignored. - type: bool - default: no - purge: - description: - - Deletes any files/directories found in the destination that do not exist in the source. - - Toggles the C(/purge) flag to RoboCopy. - - If C(flags) is set, this will be ignored. - type: bool - default: no - flags: - description: - - Directly supply Robocopy flags. - - If set, C(purge) and C(recurse) will be ignored. - type: str -notes: -- This is not a complete port of the M(synchronize) module. Unlike the M(synchronize) module this only performs the sync/copy on the remote machine, - not from the master to the remote machine. -- This module does not currently support all Robocopy flags. -seealso: -- module: synchronize -- module: win_copy -author: -- Corwin Brown (@blakfeld) -''' - -EXAMPLES = r''' -- name: Sync the contents of one directory to another - win_robocopy: - src: C:\DirectoryOne - dest: C:\DirectoryTwo - -- name: Sync the contents of one directory to another, including subdirectories - win_robocopy: - src: C:\DirectoryOne - dest: C:\DirectoryTwo - recurse: yes - -- name: Sync the contents of one directory to another, and remove any files/directories found in destination that do not exist in the source - win_robocopy: - src: C:\DirectoryOne - dest: C:\DirectoryTwo - purge: yes - -- name: Sync content in recursive mode, removing any files/directories found in destination that do not exist in the source - win_robocopy: - src: C:\DirectoryOne - dest: C:\DirectoryTwo - recurse: yes - purge: yes - -- name: Sync two directories in recursive and purging mode, specifying additional special flags - win_robocopy: - src: C:\DirectoryOne - dest: C:\DirectoryTwo - flags: /E /PURGE /XD SOME_DIR /XF SOME_FILE /MT:32 - -- name: Sync one file from a remote UNC path in recursive and purging mode, specifying additional special flags - win_robocopy: - src: \\Server1\Directory One - dest: C:\DirectoryTwo - flags: file.zip /E /PURGE /XD SOME_DIR /XF SOME_FILE /MT:32 -''' - -RETURN = r''' -cmd: - description: The used command line. - returned: always - type: str - sample: robocopy C:\DirectoryOne C:\DirectoryTwo /e /purge -src: - description: The Source file/directory of the sync. - returned: always - type: str - sample: C:\Some\Path -dest: - description: The Destination file/directory of the sync. - returned: always - type: str - sample: C:\Some\Path -recurse: - description: Whether or not the recurse flag was toggled. - returned: always - type: bool - sample: false -purge: - description: Whether or not the purge flag was toggled. - returned: always - type: bool - sample: false -flags: - description: Any flags passed in by the user. - returned: always - type: str - sample: /e /purge -rc: - description: The return code returned by robocopy. - returned: success - type: int - sample: 1 -output: - description: The output of running the robocopy command. - returned: success - type: str - sample: "------------------------------------\\n ROBOCOPY :: Robust File Copy for Windows \\n------------------------------------\\n " -msg: - description: Output interpreted into a concise message. - returned: always - type: str - sample: No files copied! -''' diff --git a/lib/ansible/modules/windows/win_route.ps1 b/lib/ansible/modules/windows/win_route.ps1 deleted file mode 100644 index f74d482be21..00000000000 --- a/lib/ansible/modules/windows/win_route.ps1 +++ /dev/null @@ -1,104 +0,0 @@ -#!powershell - -# Copyright: (c) 2016, Daniele Lazzari -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -# win_route (Add or remove a network static route) - -$params = Parse-Args $args -supports_check_mode $true - -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -default $false -$dest = Get-AnsibleParam -obj $params -name "destination" -type "str" -failifempty $true -$gateway = Get-AnsibleParam -obj $params -name "gateway" -type "str" -$metric = Get-AnsibleParam -obj $params -name "metric" -type "int" -default 1 -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateSet "present","absent" -$result = @{ - "changed" = $false - "output" = "" - } - -Function Add-Route { - Param ( - [Parameter(Mandatory=$true)] - [string]$Destination, - [Parameter(Mandatory=$true)] - [string]$Gateway, - [Parameter(Mandatory=$true)] - [int]$Metric, - [Parameter(Mandatory=$true)] - [bool]$CheckMode - ) - - - $IpAddress = $Destination.split('/')[0] - - # Check if the static route is already present - $Route = Get-CimInstance win32_ip4PersistedrouteTable -Filter "Destination = '$($IpAddress)'" - if (!($Route)){ - try { - # Find Interface Index - $InterfaceIndex = Find-NetRoute -RemoteIPAddress $Gateway | Select-Object -First 1 -ExpandProperty InterfaceIndex - - # Add network route - New-NetRoute -DestinationPrefix $Destination -NextHop $Gateway -InterfaceIndex $InterfaceIndex -RouteMetric $Metric -ErrorAction Stop -WhatIf:$CheckMode|out-null - $result.changed = $true - $result.output = "Route added" - - } - catch { - $ErrorMessage = $_.Exception.Message - Fail-Json $result $ErrorMessage - } - } - else { - $result.output = "Static route already exists" - } - -} - -Function Remove-Route { - Param ( - [Parameter(Mandatory=$true)] - [string]$Destination, - [bool]$CheckMode - ) - $IpAddress = $Destination.split('/')[0] - $Route = Get-CimInstance win32_ip4PersistedrouteTable -Filter "Destination = '$($IpAddress)'" - if ($Route){ - try { - - Remove-NetRoute -DestinationPrefix $Destination -Confirm:$false -ErrorAction Stop -WhatIf:$CheckMode - $result.changed = $true - $result.output = "Route removed" - } - catch { - $ErrorMessage = $_.Exception.Message - Fail-Json $result $ErrorMessage - } - } - else { - $result.output = "No route to remove" - } - -} - -# Set gateway if null -if(!($gateway)){ - $gateway = "0.0.0.0" -} - - -if ($state -eq "present"){ - - Add-Route -Destination $dest -Gateway $gateway -Metric $metric -CheckMode $check_mode - -} -else { - - Remove-Route -Destination $dest -CheckMode $check_mode - -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_route.py b/lib/ansible/modules/windows/win_route.py deleted file mode 100644 index 51e0366ad90..00000000000 --- a/lib/ansible/modules/windows/win_route.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Daniele Lazzari -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# This is a windows documentation stub. Actual code lives in the .ps1 -# file of the same name. - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_route -version_added: "2.4" -short_description: Add or remove a static route -description: - - Add or remove a static route. -options: - destination: - description: - - Destination IP address in CIDR format (ip address/prefix length). - type: str - required: yes - gateway: - description: - - The gateway used by the static route. - - If C(gateway) is not provided it will be set to C(0.0.0.0). - type: str - metric: - description: - - Metric used by the static route. - type: int - default: 1 - state: - description: - - If C(absent), it removes a network static route. - - If C(present), it adds a network static route. - type: str - choices: [ absent, present ] - default: present -notes: - - Works only with Windows 2012 R2 and newer. -author: -- Daniele Lazzari (@dlazz) -''' - -EXAMPLES = r''' ---- -- name: Add a network static route - win_route: - destination: 192.168.2.10/32 - gateway: 192.168.1.1 - metric: 1 - state: present - -- name: Remove a network static route - win_route: - destination: 192.168.2.10/32 - state: absent -''' -RETURN = r''' -output: - description: A message describing the task result. - returned: always - type: str - sample: "Route added" -''' diff --git a/lib/ansible/modules/windows/win_say.ps1 b/lib/ansible/modules/windows/win_say.ps1 deleted file mode 100644 index 253402b5ec6..00000000000 --- a/lib/ansible/modules/windows/win_say.ps1 +++ /dev/null @@ -1,95 +0,0 @@ -#!powershell - -# Copyright: (c) 2016, Jon Hawkesworth (@jhawkesworth) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic - -$spec = @{ - options = @{ - msg = @{ type = "str" } - msg_file = @{ type = "path" } - start_sound_path = @{ type = "path" } - end_sound_path = @{ type = "path" } - voice = @{ type = "str" } - speech_speed = @{ type = "int"; default = 0 } - } - mutually_exclusive = @( - ,@('msg', 'msg_file') - ) - required_one_of = @( - ,@('msg', 'msg_file', 'start_sound_path', 'end_sound_path') - ) - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - - -$msg = $module.Params.msg -$msg_file = $module.Params.msg_file -$start_sound_path = $module.Params.start_sound_path -$end_sound_path = $module.Params.end_sound_path -$voice = $module.Params.voice -$speech_speed = $module.Params.speech_speed - -if ($speech_speed -lt -10 -or $speech_speed -gt 10) { - $module.FailJson("speech_speed needs to be an integer in the range -10 to 10. The value $speech_speed is outside this range.") -} - -$words = $null - -if ($msg_file) { - if (-not (Test-Path -Path $msg_file)) { - $module.FailJson("Message file $msg_file could not be found or opened. Ensure you have specified the full path to the file, and the ansible windows user has permission to read the file.") - } - $words = Get-Content $msg_file | Out-String -} - -if ($msg) { - $words = $msg -} - -if ($start_sound_path) { - if (-not (Test-Path -Path $start_sound_path)) { - $module.FailJson("Start sound file $start_sound_path could not be found or opened. Ensure you have specified the full path to the file, and the ansible windows user has permission to read the file.") - } - if (-not $module.CheckMode) { - (new-object Media.SoundPlayer $start_sound_path).playSync() - } -} - -if ($words) { - Add-Type -AssemblyName System.speech - $tts = New-Object System.Speech.Synthesis.SpeechSynthesizer - if ($voice) { - try { - $tts.SelectVoice($voice) - } catch [System.Management.Automation.MethodInvocationException] { - $module.Result.voice_info = "Could not load voice '$voice', using system default voice." - $module.Warn("Could not load voice '$voice', using system default voice.") - } - } - - $module.Result.voice = $tts.Voice.Name - if ($speech_speed -ne 0) { - $tts.Rate = $speech_speed - } - if (-not $module.CheckMode) { - $tts.Speak($words) - } - $tts.Dispose() -} - -if ($end_sound_path) { - if (-not (Test-Path -Path $end_sound_path)) { - $module.FailJson("End sound file $start_sound_path could not be found or opened. Ensure you have specified the full path to the file, and the ansible windows user has permission to read the file.") - } - if (-not $module.CheckMode) { - (new-object Media.SoundPlayer $end_sound_path).playSync() - } -} - -$module.Result.message_text = $words.ToString() - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_say.py b/lib/ansible/modules/windows/win_say.py deleted file mode 100644 index 877fe4f9130..00000000000 --- a/lib/ansible/modules/windows/win_say.py +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2016, Jon Hawkesworth (@jhawkesworth) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_say -version_added: "2.3" -short_description: Text to speech module for Windows to speak messages and optionally play sounds -description: - - Uses .NET libraries to convert text to speech and optionally play .wav sounds. Audio Service needs to be running and some kind of speakers or - headphones need to be attached to the windows target(s) for the speech to be audible. -options: - msg: - description: - - The text to be spoken. - - Use either C(msg) or C(msg_file). - - Optional so that you can use this module just to play sounds. - type: str - msg_file: - description: - - Full path to a windows format text file containing the text to be spoken. - - Use either C(msg) or C(msg_file). - - Optional so that you can use this module just to play sounds. - type: path - voice: - description: - - Which voice to use. See notes for how to discover installed voices. - - If the requested voice is not available the default voice will be used. - Example voice names from Windows 10 are C(Microsoft Zira Desktop) and C(Microsoft Hazel Desktop). - type: str - speech_speed: - description: - - How fast or slow to speak the text. - - Must be an integer value in the range -10 to 10. - - -10 is slowest, 10 is fastest. - type: int - default: 0 - start_sound_path: - description: - - Full path to a C(.wav) file containing a sound to play before the text is spoken. - - Useful on conference calls to alert other speakers that ansible has something to say. - type: path - end_sound_path: - description: - - Full path to a C(.wav) file containing a sound to play after the text has been spoken. - - Useful on conference calls to alert other speakers that ansible has finished speaking. - type: path -notes: - - Needs speakers or headphones to do anything useful. - - | - To find which voices are installed, run the following Powershell commands. - - Add-Type -AssemblyName System.Speech - $speech = New-Object -TypeName System.Speech.Synthesis.SpeechSynthesizer - $speech.GetInstalledVoices() | ForEach-Object { $_.VoiceInfo } - $speech.Dispose() - - - Speech can be surprisingly slow, so it's best to keep message text short. -seealso: -- module: win_msg -- module: win_toast -author: -- Jon Hawkesworth (@jhawkesworth) -''' - -EXAMPLES = r''' -- name: Warn of impending deployment - win_say: - msg: Warning, deployment commencing in 5 minutes, please log out. - -- name: Using a different voice and a start sound - win_say: - start_sound_path: C:\Windows\Media\ding.wav - msg: Warning, deployment commencing in 5 minutes, please log out. - voice: Microsoft Hazel Desktop - -- name: With start and end sound - win_say: - start_sound_path: C:\Windows\Media\Windows Balloon.wav - msg: New software installed - end_sound_path: C:\Windows\Media\chimes.wav - -- name: Text from file example - win_say: - start_sound_path: C:\Windows\Media\Windows Balloon.wav - msg_file: AppData\Local\Temp\morning_report.txt - end_sound_path: C:\Windows\Media\chimes.wav -''' - -RETURN = r''' -message_text: - description: The text that the module attempted to speak. - returned: success - type: str - sample: "Warning, deployment commencing in 5 minutes." -voice: - description: The voice used to speak the text. - returned: success - type: str - sample: Microsoft Hazel Desktop -voice_info: - description: The voice used to speak the text. - returned: when requested voice could not be loaded - type: str - sample: Could not load voice TestVoice, using system default voice -''' diff --git a/lib/ansible/modules/windows/win_scheduled_task.ps1 b/lib/ansible/modules/windows/win_scheduled_task.ps1 deleted file mode 100644 index ac5938d2667..00000000000 --- a/lib/ansible/modules/windows/win_scheduled_task.ps1 +++ /dev/null @@ -1,1133 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Peter Mounce -# Copyright: (c) 2015, Michael Perzel -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.SID - -$ErrorActionPreference = "Stop" - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff_mode = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false -$_remote_tmp = Get-AnsibleParam $params "_ansible_remote_tmp" -type "path" -default $env:TMP - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$path = Get-AnsibleParam -obj $params -name "path" -type "str" -default "\" -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "absent", "present" - -# task actions, list of dicts [{path, arguments, working_directory}] -$actions = Get-AnsibleParam -obj $params -name "actions" -type "list" - -# task triggers, list of dicts [{ type, ... }] -$triggers = Get-AnsibleParam -obj $params -name "triggers" -type "list" - -# task Principal properties -$display_name = Get-AnsibleParam -obj $params -name "display_name" -type "str" -$group = Get-AnsibleParam -obj $params -name "group" -type "str" -$logon_type = Get-AnsibleParam -obj $params -name "logon_type" -type "str" -validateset "none","password","s4u","interactive_token","group","service_account","interactive_token_or_password" -$run_level = Get-AnsibleParam -obj $params -name "run_level" -type "str" -validateset "limited", "highest" -aliases "runlevel" -$username = Get-AnsibleParam -obj $params -name "username" -type "str" -aliases "user" -$password = Get-AnsibleParam -obj $params -name "password" -type "str" -$update_password = Get-AnsibleParam -obj $params -name "update_password" -type "bool" -default $true - -# task RegistrationInfo properties -$author = Get-AnsibleParam -obj $params -name "author" -type "str" -$date = Get-AnsibleParam -obj $params -name "date" -type "str" -$description = Get-AnsibleParam -obj $params -name "description" -type "str" -$source = Get-AnsibleParam -obj $params -name "source" -type "str" -$version = Get-AnsibleParam -obj $params -name "version" -type "str" - -# task Settings properties -$allow_demand_start = Get-AnsibleParam -obj $params -name "allow_demand_start" -type "bool" -$allow_hard_terminate = Get-AnsibleParam -obj $params -name "allow_hard_terminate" -type "bool" -$compatibility = Get-AnsibleParam -obj $params -name "compatibility" -type "int" # https://msdn.microsoft.com/en-us/library/windows/desktop/aa383486(v=vs.85).aspx -$delete_expired_task_after = Get-AnsibleParam -obj $params -name "delete_expired_task_after" -type "str" # time string PT... -$disallow_start_if_on_batteries = Get-AnsibleParam -obj $params -name "disallow_start_if_on_batteries" -type "bool" -$enabled = Get-AnsibleParam -obj $params -name "enabled" -type "bool" -$execution_time_limit = Get-AnsibleParam -obj $params -name "execution_time_limit" -type "str" # PT72H -$hidden = Get-AnsibleParam -obj $params -name "hidden" -type "bool" -# TODO: support for $idle_settings, needs to be created as a COM object -$multiple_instances = Get-AnsibleParam -obj $params -name "multiple_instances" -type "int" # https://msdn.microsoft.com/en-us/library/windows/desktop/aa383507(v=vs.85).aspx -# TODO: support for $network_settings, needs to be created as a COM object -$priority = Get-AnsibleParam -obj $params -name "priority" -type "int" # https://msdn.microsoft.com/en-us/library/windows/desktop/aa383512(v=vs.85).aspx -$restart_count = Get-AnsibleParam -obj $params -name "restart_count" -type "int" -$restart_interval = Get-AnsibleParam -obj $params -name "restart_interval" -type "str" # time string PT.. -$run_only_if_idle = Get-AnsibleParam -obj $params -name "run_only_if_idle" -type "bool" -$run_only_if_network_available = Get-AnsibleParam -obj $params -name "run_only_if_network_available" -type "bool" -$start_when_available = Get-AnsibleParam -obj $params -name "start_when_available" -type "bool" -$stop_if_going_on_batteries = Get-AnsibleParam -obj $params -name "stop_if_going_on_batteries" -type "bool" -$wake_to_run = Get-AnsibleParam -obj $params -name "wake_to_run" -type "bool" - -$result = @{ - changed = $false -} - -if ($diff_mode) { - $result.diff = @{} -} - -$task_enums = @" -public enum TASK_ACTION_TYPE // https://msdn.microsoft.com/en-us/library/windows/desktop/aa383553(v=vs.85).aspx -{ - TASK_ACTION_EXEC = 0, - // The below are not supported and are only kept for documentation purposes - TASK_ACTION_COM_HANDLER = 5, - TASK_ACTION_SEND_EMAIL = 6, - TASK_ACTION_SHOW_MESSAGE = 7 -} - -public enum TASK_CREATION // https://msdn.microsoft.com/en-us/library/windows/desktop/aa382538(v=vs.85).aspx -{ - TASK_VALIDATE_ONLY = 0x1, - TASK_CREATE = 0x2, - TASK_UPDATE = 0x4, - TASK_CREATE_OR_UPDATE = 0x6, - TASK_DISABLE = 0x8, - TASK_DONT_ADD_PRINCIPAL_ACE = 0x10, - TASK_IGNORE_REGISTRATION_TRIGGERS = 0x20 -} - -public enum TASK_LOGON_TYPE // https://msdn.microsoft.com/en-us/library/windows/desktop/aa383566(v=vs.85).aspx -{ - TASK_LOGON_NONE = 0, - TASK_LOGON_PASSWORD = 1, - TASK_LOGON_S4U = 2, - TASK_LOGON_INTERACTIVE_TOKEN = 3, - TASK_LOGON_GROUP = 4, - TASK_LOGON_SERVICE_ACCOUNT = 5, - TASK_LOGON_INTERACTIVE_TOKEN_OR_PASSWORD = 6 -} - -public enum TASK_RUN_LEVEL // https://msdn.microsoft.com/en-us/library/windows/desktop/aa380747(v=vs.85).aspx -{ - TASK_RUNLEVEL_LUA = 0, - TASK_RUNLEVEL_HIGHEST = 1 -} - -public enum TASK_TRIGGER_TYPE2 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa383915(v=vs.85).aspx -{ - TASK_TRIGGER_EVENT = 0, - TASK_TRIGGER_TIME = 1, - TASK_TRIGGER_DAILY = 2, - TASK_TRIGGER_WEEKLY = 3, - TASK_TRIGGER_MONTHLY = 4, - TASK_TRIGGER_MONTHLYDOW = 5, - TASK_TRIGGER_IDLE = 6, - TASK_TRIGGER_REGISTRATION = 7, - TASK_TRIGGER_BOOT = 8, - TASK_TRIGGER_LOGON = 9, - TASK_TRIGGER_SESSION_STATE_CHANGE = 11 -} -"@ - -$original_tmp = $env:TMP -$env:TMP = $_remote_tmp -Add-Type -TypeDefinition $task_enums -$env:TMP = $original_tmp - -######################## -### HELPER FUNCTIONS ### -######################## -Function Convert-SnakeToPascalCase($snake) { - # very basic function to convert snake_case to PascalCase for use in COM - # objects - [regex]$regex = "_(\w)" - $pascal_case = $regex.Replace($snake, { $args[0].Value.Substring(1).ToUpper() }) - $capitalised = $pascal_case.Substring(0, 1).ToUpper() + $pascal_case.Substring(1) - - return $capitalised -} - -Function Compare-Properties($property_name, $parent_property, $map, $enum_map=$null) { - $changes = [System.Collections.ArrayList]@() - - # loop through the passed in map and compare values - # Name = The name of property in the COM object - # Value = The new value to compare the existing value with - foreach ($entry in $map.GetEnumerator()) { - $new_value = $entry.Value - - if ($null -ne $new_value) { - $property_name = $entry.Name - $existing_value = $parent_property.$property_name - if ($existing_value -cne $new_value) { - try { - $parent_property.$property_name = $new_value - } catch { - Fail-Json -obj $result -message "failed to set $property_name property '$property_name' to '$new_value': $($_.Exception.Message)" - } - - if ($null -ne $enum_map -and $enum_map.ContainsKey($property_name)) { - $enum = [type]$enum_map.$property_name - $existing_value = [Enum]::ToObject($enum, $existing_value) - $new_value = [Enum]::ToObject($enum, $new_value) - } - [void]$changes.Add("-$property_name=$existing_value`n+$property_name=$new_value") - } - } - } - - return ,$changes -} - -Function Set-PropertyForComObject($com_object, $name, $arg, $value) { - $com_name = Convert-SnakeToPascalCase -snake $arg - try { - $com_object.$com_name = $value - } catch { - Fail-Json -obj $result -message "failed to set $name property '$com_name' to '$value': $($_.Exception.Message)" - } -} - -Function Compare-PropertyList { - Param( - $collection, # the collection COM object to manipulate, this must contains the Create method - [string]$property_name, # human friendly name of the property object, e.g. action/trigger - [Array]$new, # a list of new properties, passed in by Ansible - [Array]$existing, # a list of existing properties from the COM object collection - [Hashtable]$map, # metadata for the collection, see below for the structure - [string]$enum # the parent enum name for type value - ) - <## map metadata structure - { - collection type [TASK_ACTION_TYPE] for Actions or [TASK_TRIGGER_TYPE2] for Triggers { - mandatory = list of mandatory properties for this type, ansible input name not the COM name - optional = list of optional properties that could be set for this type - # maps the ansible input object name to the COM name, e.g. working_directory = WorkingDirectory - map = { - ansible input name = COM name - } - } - }##> - # used by both Actions and Triggers to compare the collections of that property - - $enum = [type]$enum - $changes = [System.Collections.ArrayList]@() - $new_count = $new.Count - $existing_count = $existing.Count - - for ($i = 0; $i -lt $new_count; $i++) { - if ($i -lt $existing_count) { - $existing_property = $existing[$i] - } else { - $existing_property = $null - } - $new_property = $new[$i] - - # get the type of the property, for action this is set automatically - if (-not $new_property.ContainsKey("type")) { - Fail-Json -obj $result -message "entry for $property_name must contain a type key" - } - $type = $new_property.type - $valid_types = $map.Keys - $property_map = $map.$type - - # now let's validate the args for the property - $mandatory_args = $property_map.mandatory - $optional_args = $property_map.optional - $total_args = $mandatory_args + $optional_args - - # validate the mandatory arguments - foreach ($mandatory_arg in $mandatory_args) { - if (-not $new_property.ContainsKey($mandatory_arg)) { - Fail-Json -obj $result -message "mandatory key '$mandatory_arg' for $($property_name) is not set, mandatory keys are '$($mandatory_args -join "', '")'" - } - } - # throw a warning if in invalid key was set - foreach ($entry in $new_property.GetEnumerator()) { - $key = $entry.Name - if ($key -notin $total_args -and $key -ne "type") { - Add-Warning -obj $result -message "key '$key' for $($property_name) entry is not valid and will be ignored, valid keys are '$($total_args -join "', '")'" - } - } - - # now we have validated the input and have gotten the metadata, let's - # get the diff string - if ($null -eq $existing_property) { - # we have more properties than before,just add to the new - # properties list - $diff_list = [System.Collections.ArrayList]@() - - foreach ($property_arg in $total_args) { - if ($new_property.ContainsKey($property_arg)) { - $com_name = Convert-SnakeToPascalCase -snake $property_arg - $property_value = $new_property.$property_arg - - if ($property_value -is [Hashtable]) { - foreach ($kv in $property_value.GetEnumerator()) { - $sub_com_name = Convert-SnakeToPascalCase -snake $kv.Key - $sub_property_value = $kv.Value - [void]$diff_list.Add("+$com_name.$sub_com_name=$sub_property_value") - } - } else { - [void]$diff_list.Add("+$com_name=$property_value") - } - } - } - - [void]$changes.Add("+$property_name[$i] = {`n +Type=$type`n $($diff_list -join ",`n ")`n+}") - } elseif ([Enum]::ToObject($enum, $existing_property.Type) -ne $type) { - # the types are different so we need to change - $diff_list = [System.Collections.ArrayList]@() - - if ($existing_property.Type -notin $valid_types) { - [void]$diff_list.Add("-UNKNOWN TYPE $($existing_property.Type)") - foreach ($property_args in $total_args) { - if ($new_property.ContainsKey($property_arg)) { - $com_name = Convert-SnakeToPascalCase -snake $property_arg - $property_value = $new_property.$property_arg - - if ($property_value -is [Hashtable]) { - foreach ($kv in $property_value.GetEnumerator()) { - $sub_com_name = Convert-SnakeToPascalCase -snake $kv.Key - $sub_property_value = $kv.Value - [void]$diff_list.Add("+$com_name.$sub_com_name=$sub_property_value") - } - } else { - [void]$diff_list.Add("+$com_name=$property_value") - } - } - } - } else { - # we know the types of the existing property - $existing_type = [Enum]::ToObject([TASK_TRIGGER_TYPE2], $existing_property.Type) - [void]$diff_list.Add("-Type=$existing_type") - [void]$diff_list.Add("+Type=$type") - foreach ($property_arg in $total_args) { - $com_name = Convert-SnakeToPascalCase -snake $property_arg - $property_value = $new_property.$property_arg - $existing_value = $existing_property.$com_name - - if ($property_value -is [Hashtable]) { - foreach ($kv in $property_value.GetEnumerator()) { - $sub_property_value = $kv.Value - $sub_com_name = Convert-SnakeToPascalCase -snake $kv.Key - $sub_existing_value = $existing_property.$com_name.$sub_com_name - - if ($null -ne $sub_property_value) { - [void]$diff_list.Add("+$com_name.$sub_com_name=$sub_property_value") - } - - if ($null -ne $sub_existing_value) { - [void]$diff_list.Add("-$com_name.$sub_com_name=$sub_existing_value") - } - } - } else { - if ($null -ne $property_value) { - [void]$diff_list.Add("+$com_name=$property_value") - } - - if ($null -ne $existing_value) { - [void]$diff_list.Add("-$com_name=$existing_value") - } - } - } - } - - [void]$changes.Add("$property_name[$i] = {`n $($diff_list -join ",`n ")`n}") - } else { - # compare the properties of existing and new - $diff_list = [System.Collections.ArrayList]@() - - foreach ($property_arg in $total_args) { - $com_name = Convert-SnakeToPascalCase -snake $property_arg - $property_value = $new_property.$property_arg - $existing_value = $existing_property.$com_name - - if ($property_value -is [Hashtable]) { - foreach ($kv in $property_value.GetEnumerator()) { - $sub_property_value = $kv.Value - - if ($null -ne $sub_property_value) { - $sub_com_name = Convert-SnakeToPascalCase -snake $kv.Key - $sub_existing_value = $existing_property.$com_name.$sub_com_name - - if ($sub_property_value -cne $sub_existing_value) { - [void]$diff_list.Add("-$com_name.$sub_com_name=$sub_existing_value") - [void]$diff_list.Add("+$com_name.$sub_com_name=$sub_property_value") - } - } - } - } elseif ($null -ne $property_value -and $property_value -cne $existing_value) { - [void]$diff_list.Add("-$com_name=$existing_value") - [void]$diff_list.Add("+$com_name=$property_value") - } - } - - if ($diff_list.Count -gt 0) { - [void]$changes.Add("$property_name[$i] = {`n $($diff_list -join ",`n ")`n}") - } - } - - # finally rebuild the new property collection - $new_object = $collection.Create($type) - foreach ($property_arg in $total_args) { - $new_value = $new_property.$property_arg - if ($new_value -is [Hashtable]) { - $com_name = Convert-SnakeToPascalCase -snake $property_arg - $new_object_property = $new_object.$com_name - - foreach ($kv in $new_value.GetEnumerator()) { - $value = $kv.Value - if ($null -ne $value) { - Set-PropertyForComObject -com_object $new_object_property -name $property_name -arg $kv.Key -value $value - } - } - } elseif ($null -ne $new_value) { - Set-PropertyForComObject -com_object $new_object -name $property_name -arg $property_arg -value $new_value - } - } - } - - # if there were any extra properties not in the new list, create diff str - if ($existing_count -gt $new_count) { - for ($i = $new_count; $i -lt $existing_count; $i++) { - $diff_list = [System.Collections.ArrayList]@() - $existing_property = $existing[$i] - $existing_type = [Enum]::ToObject($enum, $existing_property.Type) - - if ($map.ContainsKey($existing_type)) { - $property_map = $map.$existing_type - $property_args = $property_map.mandatory + $property_map.optional - - foreach ($property_arg in $property_args) { - $com_name = Convert-SnakeToPascalCase -snake $property_arg - $existing_value = $existing_property.$com_name - if ($null -ne $existing_value) { - [void]$diff_list.Add("-$com_name=$existing_value") - } - } - } else { - [void]$diff_list.Add("-UNKNOWN TYPE $existing_type") - } - - [void]$changes.Add("-$property_name[$i] = {`n $($diff_list -join ",`n ")`n-}") - } - } - - return ,$changes -} - -Function Compare-Actions($task_definition) { - # compares the Actions property and returns a list of list of changed - # actions for use in a diff string - # ActionCollection - https://msdn.microsoft.com/en-us/library/windows/desktop/aa446804(v=vs.85).aspx - # Action - https://msdn.microsoft.com/en-us/library/windows/desktop/aa446803(v=vs.85).aspx - if ($null -eq $actions) { - return ,[System.Collections.ArrayList]@() - } - - $task_actions = $task_definition.Actions - $existing_count = $task_actions.Count - - # because we clear the actions and re-add them to keep the order, we need - # to convert the existing actions to a new list. - # The Item property in actions starts at 1 - $existing_actions = [System.Collections.ArrayList]@() - for ($i = 1; $i -le $existing_count; $i++) { - [void]$existing_actions.Add($task_actions.Item($i)) - } - if ($existing_count -gt 0) { - $task_actions.Clear() - } - - $map = @{ - [TASK_ACTION_TYPE]::TASK_ACTION_EXEC = @{ - mandatory = @('path') - optional = @('arguments', 'working_directory') - } - } - $changes = Compare-PropertyList -collection $task_actions -property_name "action" -new $actions -existing $existing_actions -map $map -enum TASK_ACTION_TYPE - - return ,$changes -} - -Function Compare-Principal($task_definition, $task_definition_xml) { - # compares the Principal property and returns a list of changed objects for - # use in a diff string - # https://msdn.microsoft.com/en-us/library/windows/desktop/aa382071(v=vs.85).aspx - $principal_map = @{ - DisplayName = $display_name - LogonType = $logon_type - RunLevel = $run_level - } - $enum_map = @{ - LogonType = "TASK_LOGON_TYPE" - RunLevel = "TASK_RUN_LEVEL" - } - $task_principal = $task_definition.Principal - $changes = Compare-Properties -property_name "Principal" -parent_property $task_principal -map $principal_map -enum_map $enum_map - - # Principal.UserId and GroupId only returns the username portion of the - # username, skipping the domain or server name. This makes the - # comparison process useless so we need to parse the task XML to get - # the actual sid/username. Depending on OS version this could be the SID - # or it could be the username, we need to handle that accordingly - $principal_username_sid = $task_definition_xml.Task.Principals.Principal.UserId - if ($null -ne $principal_username_sid -and $principal_username_sid -notmatch "^S-\d-\d+(-\d+){1,14}(-\d+){0,1}$") { - $principal_username_sid = Convert-ToSID -account_name $principal_username_sid - } - $principal_group_sid = $task_definition_xml.Task.Principals.Principal.GroupId - if ($null -ne $principal_group_sid -and $principal_group_sid -notmatch "^S-\d-\d+(-\d+){1,14}(-\d+){0,1}$") { - $principal_group_sid = Convert-ToSID -account_name $principal_group_sid - } - - if ($null -ne $username_sid) { - $new_user_name = Convert-FromSid -sid $username_sid - if ($null -ne $principal_group_sid) { - $existing_account_name = Convert-FromSid -sid $principal_group_sid - [void]$changes.Add("-GroupId=$existing_account_name`n+UserId=$new_user_name") - $task_principal.UserId = $new_user_name - $task_principal.GroupId = $null - } elseif ($null -eq $principal_username_sid) { - [void]$changes.Add("+UserId=$new_user_name") - $task_principal.UserId = $new_user_name - } elseif ($principal_username_sid -ne $username_sid) { - $existing_account_name = Convert-FromSid -sid $principal_username_sid - [void]$changes.Add("-UserId=$existing_account_name`n+UserId=$new_user_name") - $task_principal.UserId = $new_user_name - } - } - if ($null -ne $group_sid) { - $new_group_name = Convert-FromSid -sid $group_sid - if ($null -ne $principal_username_sid) { - $existing_account_name = Convert-FromSid -sid $principal_username_sid - [void]$changes.Add("-UserId=$existing_account_name`n+GroupId=$new_group_name") - $task_principal.UserId = $null - $task_principal.GroupId = $new_group_name - } elseif ($null -eq $principal_group_sid) { - [void]$changes.Add("+GroupId=$new_group_name") - $task_principal.GroupId = $new_group_name - } elseif ($principal_group_sid -ne $group_sid) { - $existing_account_name = Convert-FromSid -sid $principal_group_sid - [void]$changes.Add("-GroupId=$existing_account_name`n+GroupId=$new_group_name") - $task_principal.GroupId = $new_group_name - } - } - - return ,$changes -} - -Function Compare-RegistrationInfo($task_definition) { - # compares the RegistrationInfo property and returns a list of changed - # objects for use in a diff string - # https://msdn.microsoft.com/en-us/library/windows/desktop/aa382100(v=vs.85).aspx - $reg_info_map = @{ - Author = $author - Date = $date - Description = $description - Source = $source - Version = $version - } - $changes = Compare-Properties -property_name "RegistrationInfo" -parent_property $task_definition.RegistrationInfo -map $reg_info_map - - return ,$changes -} - -Function Compare-Settings($task_definition) { - # compares the task Settings property and returns a list of changed objects - # for use in a diff string - # https://msdn.microsoft.com/en-us/library/windows/desktop/aa383480(v=vs.85).aspx - $settings_map = @{ - AllowDemandStart = $allow_demand_start - AllowHardTerminate = $allow_hard_terminate - Compatibility = $compatibility - DeleteExpiredTaskAfter = $delete_expired_task_after - DisallowStartIfOnBatteries = $disallow_start_if_on_batteries - ExecutionTimeLimit = $execution_time_limit - Enabled = $enabled - Hidden = $hidden - # IdleSettings = $idle_settings # TODO: this takes in a COM object - MultipleInstances = $multiple_instances - # NetworkSettings = $network_settings # TODO: this takes in a COM object - Priority = $priority - RestartCount = $restart_count - RestartInterval = $restart_interval - RunOnlyIfIdle = $run_only_if_idle - RunOnlyIfNetworkAvailable = $run_only_if_network_available - StartWhenAvailable = $start_when_available - StopIfGoingOnBatteries = $stop_if_going_on_batteries - WakeToRun = $wake_to_run - } - $changes = Compare-Properties -property_name "Settings" -parent_property $task_definition.Settings -map $settings_map - - return ,$changes -} - -Function Compare-Triggers($task_definition) { - # compares the task Triggers property and returns a list of changed objects - # for use in a diff string - # TriggerCollection - https://msdn.microsoft.com/en-us/library/windows/desktop/aa383875(v=vs.85).aspx - # Trigger - https://msdn.microsoft.com/en-us/library/windows/desktop/aa383868(v=vs.85).aspx - if ($null -eq $triggers) { - return ,[System.Collections.ArrayList]@() - } - - $task_triggers = $task_definition.Triggers - $existing_count = $task_triggers.Count - - # because we clear the actions and re-add them to keep the order, we need - # to convert the existing actions to a new list. - # The Item property in actions starts at 1 - $existing_triggers = [System.Collections.ArrayList]@() - for ($i = 1; $i -le $existing_count; $i++) { - [void]$existing_triggers.Add($task_triggers.Item($i)) - } - if ($existing_count -gt 0) { - $task_triggers.Clear() - } - - $map = @{ - [TASK_TRIGGER_TYPE2]::TASK_TRIGGER_BOOT = @{ - mandatory = @() - optional = @('delay', 'enabled', 'end_boundary', 'execution_time_limit', 'start_boundary', 'repetition') - } - [TASK_TRIGGER_TYPE2]::TASK_TRIGGER_DAILY = @{ - mandatory = @('start_boundary') - optional = @('days_interval', 'enabled', 'end_boundary', 'execution_time_limit', 'random_delay', 'repetition') - } - [TASK_TRIGGER_TYPE2]::TASK_TRIGGER_EVENT = @{ - mandatory = @('subscription') - # TODO: ValueQueries is a COM object - optional = @('delay', 'enabled', 'end_boundary', 'execution_time_limit', 'start_boundary', 'repetition') - } - [TASK_TRIGGER_TYPE2]::TASK_TRIGGER_IDLE = @{ - mandatory = @() - optional = @('enabled', 'end_boundary', 'execution_time_limit', 'start_boundary', 'repetition') - } - [TASK_TRIGGER_TYPE2]::TASK_TRIGGER_LOGON = @{ - mandatory = @() - optional = @('delay', 'enabled', 'end_boundary', 'execution_time_limit', 'start_boundary', 'user_id', 'repetition') - } - [TASK_TRIGGER_TYPE2]::TASK_TRIGGER_MONTHLYDOW = @{ - mandatory = @('start_boundary') - optional = @('days_of_week', 'enabled', 'end_boundary', 'execution_time_limit', 'months_of_year', 'random_delay', 'run_on_last_week_of_month', 'weeks_of_month', 'repetition') - } - [TASK_TRIGGER_TYPE2]::TASK_TRIGGER_MONTHLY = @{ - mandatory = @('days_of_month', 'start_boundary') - optional = @('enabled', 'end_boundary', 'execution_time_limit', 'months_of_year', 'random_delay', 'run_on_last_day_of_month', 'start_boundary', 'repetition') - } - [TASK_TRIGGER_TYPE2]::TASK_TRIGGER_REGISTRATION = @{ - mandatory = @() - optional = @('delay', 'enabled', 'end_boundary', 'execution_time_limit', 'start_boundary', 'repetition') - } - [TASK_TRIGGER_TYPE2]::TASK_TRIGGER_TIME = @{ - mandatory = @('start_boundary') - optional = @('enabled', 'end_boundary', 'execution_time_limit', 'random_delay', 'repetition') - } - [TASK_TRIGGER_TYPE2]::TASK_TRIGGER_WEEKLY = @{ - mandatory = @('days_of_week', 'start_boundary') - optional = @('enabled', 'end_boundary', 'execution_time_limit', 'random_delay', 'weeks_interval', 'repetition') - } - [TASK_TRIGGER_TYPE2]::TASK_TRIGGER_SESSION_STATE_CHANGE = @{ - mandatory = @('days_of_week', 'start_boundary') - optional = @('delay', 'enabled', 'end_boundary', 'execution_time_limit', 'state_change', 'user_id', 'repetition') - } - } - $changes = Compare-PropertyList -collection $task_triggers -property_name "trigger" -new $triggers -existing $existing_triggers -map $map -enum TASK_TRIGGER_TYPE2 - - return ,$changes -} - -Function Test-TaskExists($task_folder, $name) { - # checks if a task exists in the TaskFolder COM object, returns null if the - # task does not exist, otherwise returns the RegisteredTask object - $task = $null - if ($task_folder) { - $raw_tasks = $task_folder.GetTasks(1) # 1 = TASK_ENUM_HIDDEN - - for ($i = 1; $i -le $raw_tasks.Count; $i++) { - if ($raw_tasks.Item($i).Name -eq $name) { - $task = $raw_tasks.Item($i) - break - } - } - } - - return $task -} - -Function Test-XmlDurationFormat($key, $value) { - # validate value is in the Duration Data Type format - # PnYnMnDTnHnMnS - try { - $time_span = [System.Xml.XmlConvert]::ToTimeSpan($value) - return $time_span - } catch [System.FormatException] { - Fail-Json -obj $result -message "trigger option '$key' must be in the XML duration format but was '$value'" - } -} - -###################################### -### VALIDATION/BUILDING OF OPTIONS ### -###################################### -# convert username and group to SID if set -$username_sid = $null -if ($username) { - $username_sid = Convert-ToSID -account_name $username -} -$group_sid = $null -if ($group) { - $group_sid = Convert-ToSID -account_name $group -} - -# validate store_password and logon_type -if ($null -ne $logon_type) { - $full_enum_name = "TASK_LOGON_$($logon_type.ToUpper())" - $logon_type = [TASK_LOGON_TYPE]::$full_enum_name -} - -# now validate the logon_type option with the other parameters -if ($null -ne $username -and $null -ne $group) { - Fail-Json -obj $result -message "username and group can not be set at the same time" -} -if ($null -ne $logon_type) { - if ($logon_type -eq [TASK_LOGON_TYPE]::TASK_LOGON_S4U -and $null -eq $password) { - Fail-Json -obj $result -message "password must be set when logon_type=s4u" - } - - if ($logon_type -eq [TASK_LOGON_TYPE]::TASK_LOGON_GROUP -and $null -eq $group) { - Fail-Json -obj $result -message "group must be set when logon_type=group" - } - - # SIDs == Local System, Local Service and Network Service - if ($logon_type -eq [TASK_LOGON_TYPE]::TASK_LOGON_SERVICE_ACCOUNT -and $username_sid -notin @("S-1-5-18", "S-1-5-19", "S-1-5-20")) { - Fail-Json -obj $result -message "username must be SYSTEM, LOCAL SERVICE or NETWORK SERVICE when logon_type=service_account" - } -} - -# convert the run_level to enum value -if ($null -ne $run_level) { - if ($run_level -eq "limited") { - $run_level = [TASK_RUN_LEVEL]::TASK_RUNLEVEL_LUA - } else { - $run_level = [TASK_RUN_LEVEL]::TASK_RUNLEVEL_HIGHEST - } -} - -# manually add the only support action type for each action - also convert PSCustomObject to Hashtable -for ($i = 0; $i -lt $actions.Count; $i++) { - $action = $actions[$i] - $action.type = [TASK_ACTION_TYPE]::TASK_ACTION_EXEC - if (-not $action.ContainsKey("path")) { - Fail-Json -obj $result -message "action entry must contain the key 'path'" - } - $actions[$i] = $action -} - -# convert and validate the triggers - and convert PSCustomObject to Hashtable -for ($i = 0; $i -lt $triggers.Count; $i++) { - $trigger = $triggers[$i] - $valid_trigger_types = @('event', 'time', 'daily', 'weekly', 'monthly', 'monthlydow', 'idle', 'registration', 'boot', 'logon', 'session_state_change') - if (-not $trigger.ContainsKey("type")) { - Fail-Json -obj $result -message "a trigger entry must contain a key 'type' with a value of '$($valid_trigger_types -join "', '")'" - } - - $trigger_type = $trigger.type - if ($trigger_type -notin $valid_trigger_types) { - Fail-Json -obj $result -message "the specified trigger type '$trigger_type' is not valid, type must be a value of '$($valid_trigger_types -join "', '")'" - } - - $full_enum_name = "TASK_TRIGGER_$($trigger_type.ToUpper())" - $trigger_type = [TASK_TRIGGER_TYPE2]::$full_enum_name - $trigger.type = $trigger_type - - $date_properties = @('start_boundary', 'end_boundary') - foreach ($property_name in $date_properties) { - # validate the date is in the DateTime format - # yyyy-mm-ddThh:mm:ss - if ($trigger.ContainsKey($property_name)) { - $date_value = $trigger.$property_name - try { - $date = Get-Date -Date $date_value -Format "yyyy-MM-dd'T'HH:mm:ssK" - # make sure we convert it to the full string format - $trigger.$property_name = $date.ToString() - } catch [System.Management.Automation.ParameterBindingException] { - Fail-Json -obj $result -message "trigger option '$property_name' must be in the format 'YYYY-MM-DDThh:mm:ss' format but was '$date_value'" - } - } - } - - $time_properties = @('execution_time_limit', 'delay', 'random_delay') - foreach ($property_name in $time_properties) { - if ($trigger.ContainsKey($property_name)) { - $time_span = $trigger.$property_name - Test-XmlDurationFormat -key $property_name -value $time_span - } - } - - if ($trigger.ContainsKey("repetition")) { - if ($trigger.repetition -is [Array]) { - Add-DeprecationWarning -obj $result -message "repetition is a list, should be defined as a dict" -version "2.12" - $trigger.repetition = $trigger.repetition[0] - } - - $interval_timespan = $null - if ($trigger.repetition.ContainsKey("interval") -and $null -ne $trigger.repetition.interval) { - $interval_timespan = Test-XmlDurationFormat -key "interval" -value $trigger.repetition.interval - } - - $duration_timespan = $null - if ($trigger.repetition.ContainsKey("duration") -and $null -ne $trigger.repetition.duration) { - $duration_timespan = Test-XmlDurationFormat -key "duration" -value $trigger.repetition.duration - } - - if ($null -ne $interval_timespan -and $null -ne $duration_timespan -and $interval_timespan -gt $duration_timespan) { - Fail-Json -obj $result -message "trigger repetition option 'interval' value '$($trigger.repetition.interval)' must be less than or equal to 'duration' value '$($trigger.repetition.duration)'" - } - } - - # convert out human readble text to the hex values for these properties - if ($trigger.ContainsKey("days_of_week")) { - $days = $trigger.days_of_week - if ($days -is [String]) { - $days = $days.Split(",").Trim() - } elseif ($days -isnot [Array]) { - $days = @($days) - } - - $day_value = 0 - foreach ($day in $days) { - # https://msdn.microsoft.com/en-us/library/windows/desktop/aa382057(v=vs.85).aspx - switch ($day) { - sunday { $day_value = $day_value -bor 0x01 } - monday { $day_value = $day_value -bor 0x02 } - tuesday { $day_value = $day_value -bor 0x04 } - wednesday { $day_value = $day_value -bor 0x08 } - thursday { $day_value = $day_value -bor 0x10 } - friday { $day_value = $day_value -bor 0x20 } - saturday { $day_value = $day_value -bor 0x40 } - default { Fail-Json -obj $result -message "invalid day of week '$day', check the spelling matches the full day name" } - } - } - if ($day_value -eq 0) { - $day_value = $null - } - - $trigger.days_of_week = $day_value - } - if ($trigger.ContainsKey("days_of_month")) { - $days = $trigger.days_of_month - if ($days -is [String]) { - $days = $days.Split(",").Trim() - } elseif ($days -isnot [Array]) { - $days = @($days) - } - - $day_value = 0 - foreach ($day in $days) { - # https://msdn.microsoft.com/en-us/library/windows/desktop/aa382063(v=vs.85).aspx - switch ($day) { - 1 { $day_value = $day_value -bor 0x01 } - 2 { $day_value = $day_value -bor 0x02 } - 3 { $day_value = $day_value -bor 0x04 } - 4 { $day_value = $day_value -bor 0x08 } - 5 { $day_value = $day_value -bor 0x10 } - 6 { $day_value = $day_value -bor 0x20 } - 7 { $day_value = $day_value -bor 0x40 } - 8 { $day_value = $day_value -bor 0x80 } - 9 { $day_value = $day_value -bor 0x100 } - 10 { $day_value = $day_value -bor 0x200 } - 11 { $day_value = $day_value -bor 0x400 } - 12 { $day_value = $day_value -bor 0x800 } - 13 { $day_value = $day_value -bor 0x1000 } - 14 { $day_value = $day_value -bor 0x2000 } - 15 { $day_value = $day_value -bor 0x4000 } - 16 { $day_value = $day_value -bor 0x8000 } - 17 { $day_value = $day_value -bor 0x10000 } - 18 { $day_value = $day_value -bor 0x20000 } - 19 { $day_value = $day_value -bor 0x40000 } - 20 { $day_value = $day_value -bor 0x80000 } - 21 { $day_value = $day_value -bor 0x100000 } - 22 { $day_value = $day_value -bor 0x200000 } - 23 { $day_value = $day_value -bor 0x400000 } - 24 { $day_value = $day_value -bor 0x800000 } - 25 { $day_value = $day_value -bor 0x1000000 } - 26 { $day_value = $day_value -bor 0x2000000 } - 27 { $day_value = $day_value -bor 0x4000000 } - 28 { $day_value = $day_value -bor 0x8000000 } - 29 { $day_value = $day_value -bor 0x10000000 } - 30 { $day_value = $day_value -bor 0x20000000 } - 31 { $day_value = $day_value -bor 0x40000000 } - default { Fail-Json -obj $result -message "invalid day of month '$day', please specify numbers from 1-31" } - } - } - if ($day_value -eq 0) { - $day_value = $null - } - $trigger.days_of_month = $day_value - } - if ($trigger.ContainsKey("weeks_of_month")) { - $weeks = $trigger.weeks_of_month - if ($weeks -is [String]) { - $weeks = $weeks.Split(",").Trim() - } elseif ($weeks -isnot [Array]) { - $weeks = @($weeks) - } - - $week_value = 0 - foreach ($week in $weeks) { - # https://msdn.microsoft.com/en-us/library/windows/desktop/aa382061(v=vs.85).aspx - switch ($week) { - 1 { $week_value = $week_value -bor 0x01 } - 2 { $week_value = $week_value -bor 0x02 } - 3 { $week_value = $week_value -bor 0x04 } - 4 { $week_value = $week_value -bor 0x08 } - default { Fail-Json -obj $result -message "invalid week of month '$week', please specify weeks from 1-4" } - } - - } - if ($week_value -eq 0) { - $week_value = $null - } - $trigger.weeks_of_month = $week_value - } - if ($trigger.ContainsKey("months_of_year")) { - $months = $trigger.months_of_year - if ($months -is [String]) { - $months = $months.Split(",").Trim() - } elseif ($months -isnot [Array]) { - $months = @($months) - } - - $month_value = 0 - foreach ($month in $months) { - # https://msdn.microsoft.com/en-us/library/windows/desktop/aa382064(v=vs.85).aspx - switch ($month) { - january { $month_value = $month_value -bor 0x01 } - february { $month_value = $month_value -bor 0x02 } - march { $month_value = $month_value -bor 0x04 } - april { $month_value = $month_value -bor 0x08 } - may { $month_value = $month_value -bor 0x10 } - june { $month_value = $month_value -bor 0x20 } - july { $month_value = $month_value -bor 0x40 } - august { $month_value = $month_value -bor 0x80 } - september { $month_value = $month_value -bor 0x100 } - october { $month_value = $month_value -bor 0x200 } - november { $month_value = $month_value -bor 0x400 } - december { $month_value = $month_value -bor 0x800 } - default { Fail-Json -obj $result -message "invalid month name '$month', please specify full month name" } - } - } - if ($month_value -eq 0) { - $month_value = $null - } - $trigger.months_of_year = $month_value - } - $triggers[$i] = $trigger -} - -# add \ to start of path if it is not already there -if (-not $path.StartsWith("\")) { - $path = "\$path" -} -# ensure path does not end with \ if more than 1 char -if ($path.EndsWith("\") -and $path.Length -ne 1) { - $path = $path.Substring(0, $path.Length - 1) -} - -######################## -### START CODE BLOCK ### -######################## -$service = New-Object -ComObject Schedule.Service -try { - $service.Connect() -} catch { - Fail-Json -obj $result -message "failed to connect to the task scheduler service: $($_.Exception.Message)" -} - -# check that the path for the task set exists, create if need be -try { - $task_folder = $service.GetFolder($path) -} catch { - $task_folder = $null -} - -# try and get the task at the path -$task = Test-TaskExists -task_folder $task_folder -name $name -$task_path = Join-Path -Path $path -ChildPath $name - -if ($state -eq "absent") { - if ($null -ne $task) { - if (-not $check_mode) { - try { - $task_folder.DeleteTask($name, 0) - } catch { - Fail-Json -obj $result -message "failed to delete task '$name' at path '$path': $($_.Exception.Message)" - } - } - if ($diff_mode) { - $result.diff.prepared = "-[Task]`n-$task_path`n" - } - $result.changed = $true - - # check if current folder has any more tasks - $other_tasks = $task_folder.GetTasks(1) # 1 = TASK_ENUM_HIDDEN - if ($other_tasks.Count -eq 0 -and $task_folder.Name -ne "\") { - try { - $task_folder.DeleteFolder($null, $null) - } catch { - Fail-Json -obj $result -message "failed to delete empty task folder '$path' after task deletion: $($_.Exception.Message)" - } - } - } -} else { - if ($null -eq $task) { - $create_diff_string = "+[Task]`n+$task_path`n`n" - # to create a bare minimum task we need 1 action - if ($null -eq $actions -or $actions.Count -eq 0) { - Fail-Json -obj $result -message "cannot create a task with no actions, set at least one action with a path to an executable" - } - - # Create a bare minimum task here, further properties will be set later on - $task_definition = $service.NewTask(0) - - # Set Actions info - # https://msdn.microsoft.com/en-us/library/windows/desktop/aa446803(v=vs.85).aspx - $create_diff_string += "[Actions]`n" - $task_actions = $task_definition.Actions - foreach ($action in $actions) { - $create_diff_string += "+action[0] = {`n +Type=$([TASK_ACTION_TYPE]::TASK_ACTION_EXEC),`n +Path=$($action.path)`n" - $task_action = $task_actions.Create([TASK_ACTION_TYPE]::TASK_ACTION_EXEC) - $task_action.Path = $action.path - if ($null -ne $action.arguments) { - $create_diff_string += " +Arguments=$($action.arguments)`n" - $task_action.Arguments = $action.arguments - } - if ($null -ne $action.working_directory) { - $create_diff_string += " +WorkingDirectory=$($action.working_directory)`n" - $task_action.WorkingDirectory = $action.working_directory - } - $create_diff_string += "+}`n" - } - - # Register the new task - # https://msdn.microsoft.com/en-us/library/windows/desktop/aa382577(v=vs.85).aspx - if ($check_mode) { - # Only validate the task in check mode - $task_creation_flags = [TASK_CREATION]::TASK_VALIDATE_ONLY - } else { - # Create the task but do not fire it as we still need to configure it further below - $task_creation_flags = [TASK_CREATION]::TASK_CREATE -bor [TASK_CREATION]::TASK_IGNORE_REGISTRATION_TRIGGERS - } - - # folder doesn't exist, need to create - if ($null -eq $task_folder) { - $task_folder = $service.GetFolder("\") - try { - if (-not $check_mode) { - $task_folder = $task_folder.CreateFolder($path) - } - } catch { - Fail-Json -obj $result -message "failed to create new folder at path '$path': $($_.Exception.Message)" - } - } - - try { - $task = $task_folder.RegisterTaskDefinition($name, $task_definition, $task_creation_flags, $null, $null, $null) - } catch { - Fail-Json -obj $result -message "failed to register new task definition: $($_.Exception.Message)" - } - if ($diff_mode) { - $result.diff.prepared = $create_diff_string - } - - $result.changed = $true - } - - # we cannot configure a task that was created above in check mode as it - # won't actually exist - if ($task) { - $task_definition = $task.Definition - $task_definition_xml = [xml]$task_definition.XmlText - - $action_changes = Compare-Actions -task_definition $task_definition - $principal_changed = Compare-Principal -task_definition $task_definition -task_definition_xml $task_definition_xml - $reg_info_changed = Compare-RegistrationInfo -task_definition $task_definition - $settings_changed = Compare-Settings -task_definition $task_definition - $trigger_changes = Compare-Triggers -task_definition $task_definition - - # compile the diffs into one list with headers - $task_diff = [System.Collections.ArrayList]@() - if ($action_changes.Count -gt 0) { - [void]$task_diff.Add("[Actions]") - foreach ($action_change in $action_changes) { - [void]$task_diff.Add($action_change) - } - [void]$task_diff.Add("`n") - } - if ($principal_changed.Count -gt 0) { - [void]$task_diff.Add("[Principal]") - foreach ($principal_change in $principal_changed) { - [void]$task_diff.Add($principal_change) - } - [void]$task_diff.Add("`n") - } - if ($reg_info_changed.Count -gt 0) { - [void]$task_diff.Add("[Registration Info]") - foreach ($reg_info_change in $reg_info_changed) { - [void]$task_diff.Add($reg_info_change) - } - [void]$task_diff.Add("`n") - } - if ($settings_changed.Count -gt 0) { - [void]$task_diff.Add("[Settings]") - foreach ($settings_change in $settings_changed) { - [void]$task_diff.add($settings_change) - } - [void]$task_diff.Add("`n") - } - if ($trigger_changes.Count -gt 0) { - [void]$task_diff.Add("[Triggers]") - foreach ($trigger_change in $trigger_changes) { - [void]$task_diff.Add("$trigger_change") - } - [void]$task_diff.Add("`n") - } - - if ($null -ne $password -and (($update_password -eq $true) -or ($task_diff.Count -gt 0))) { - # because we can't compare the passwords we just need to reset it - $register_username = $username - $register_password = $password - $register_logon_type = $task_principal.LogonType - } else { - # will inherit from the Principal property values - $register_username = $null - $register_password = $null - $register_logon_type = $null - } - - if ($task_diff.Count -gt 0 -or $null -ne $register_password) { - if ($check_mode) { - # Only validate the task in check mode - $task_creation_flags = [TASK_CREATION]::TASK_VALIDATE_ONLY - } else { - # Create the task - $task_creation_flags = [TASK_CREATION]::TASK_CREATE_OR_UPDATE - } - try { - $task_folder.RegisterTaskDefinition($name, $task_definition, $task_creation_flags, $register_username, $register_password, $register_logon_type) | Out-Null - } catch { - Fail-Json -obj $result -message "failed to modify scheduled task: $($_.Exception.Message)" - } - - $result.changed = $true - - if ($diff_mode) { - $changed_diff_text = $task_diff -join "`n" - if ($null -ne $result.diff.prepared) { - $diff_text = "$($result.diff.prepared)`n$changed_diff_text" - } else { - $diff_text = $changed_diff_text - } - $result.diff.prepared = $diff_text.Trim() - } - } - } -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_scheduled_task.py b/lib/ansible/modules/windows/win_scheduled_task.py deleted file mode 100644 index 6e64738451a..00000000000 --- a/lib/ansible/modules/windows/win_scheduled_task.py +++ /dev/null @@ -1,546 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_scheduled_task -version_added: "2.0" -short_description: Manage scheduled tasks -description: -- Creates/modified or removes Windows scheduled tasks. -options: - # module definition options - name: - description: - - The name of the scheduled task without the path. - type: str - required: yes - path: - description: - - Task folder in which this task will be stored. - - Will create the folder when C(state=present) and the folder does not - already exist. - - Will remove the folder when C(state=absent) and there are no tasks left - in the folder. - type: str - default: \ - state: - description: - - When C(state=present) will ensure the task exists. - - When C(state=absent) will ensure the task does not exist. - type: str - choices: [ absent, present ] - default: present - - # Action options - actions: - description: - - A list of action to configure for the task. - - See suboptions for details on how to construct each list entry. - - When creating a task there MUST be at least one action but when deleting - a task this can be a null or an empty list. - - The ordering of this list is important, the module will ensure the order - is kept when modifying the task. - - This module only supports the C(ExecAction) type but can still delete the - older legacy types. - type: list - suboptions: - path: - description: - - The path to the executable for the ExecAction. - type: str - required: yes - arguments: - description: - - An argument string to supply for the executable. - type: str - working_directory: - description: - - The working directory to run the executable from. - type: str - version_added: '2.5' - - # Trigger options - triggers: - description: - - A list of triggers to configure for the task. - - See suboptions for details on how to construct each list entry. - - The ordering of this list is important, the module will ensure the order - is kept when modifying the task. - - There are multiple types of triggers, see U(https://msdn.microsoft.com/en-us/library/windows/desktop/aa383868.aspx) - for a list of trigger types and their options. - - The suboption options listed below are not required for all trigger - types, read the description for more details. - type: list - suboptions: - type: - description: - - The trigger type, this value controls what below options are - required. - type: str - required: yes - choices: [ boot, daily, event, idle, logon, monthlydow, monthly, registration, time, weekly, session_state_change ] - enabled: - description: - - Whether to set the trigger to enabled or disabled - - Used in all trigger types. - type: bool - start_boundary: - description: - - The start time for the task, even if the trigger meets the other - start criteria, it won't start until this time is met. - - If you wish to run a task at 9am on a day you still need to specify - the date on which the trigger is activated, you can set any date even - ones in the past. - - Required when C(type) is C(daily), C(monthlydow), C(monthly), - C(time), C(weekly), (session_state_change). - - Optional for the rest of the trigger types. - - This is in ISO 8601 DateTime format C(YYYY-MM-DDThh:mm:ss). - type: str - end_boundary: - description: - - The end time for when the trigger is deactivated. - - This is in ISO 8601 DateTime format C(YYYY-MM-DDThh:mm:ss). - type: str - execution_time_limit: - description: - - The maximum amount of time that the task is allowed to run for. - - Optional for all the trigger types. - - Is in the ISO 8601 Duration format C(P[n]Y[n]M[n]DT[n]H[n]M[n]S). - type: str - delay: - description: - - The time to delay the task from running once the trigger has been - fired. - - Optional when C(type) is C(boot), C(event), C(logon), - C(registration), C(session_state_change). - - Is in the ISO 8601 Duration format C(P[n]Y[n]M[n]DT[n]H[n]M[n]S). - type: str - random_delay: - description: - - The delay time that is randomly added to the start time of the - trigger. - - Optional when C(type) is C(daily), C(monthlydow), C(monthly), - C(time), C(weekly). - - Is in the ISO 8601 Duration format C(P[n]Y[n]M[n]DT[n]H[n]M[n]S). - type: str - subscription: - description: - - Only used and is required for C(type=event). - - The XML query string that identifies the event that fires the - trigger. - type: str - user_id: - description: - - The username that the trigger will target. - - Optional when C(type) is C(logon), C(session_state_change). - - Can be the username or SID of a user. - - When C(type=logon) and you want the trigger to fire when a user in a - group logs on, leave this as null and set C(group) to the group you - wish to trigger. - type: str - days_of_week: - description: - - The days of the week for the trigger. - - Can be a list or comma separated string of full day names e.g. monday - instead of mon. - - Required when C(type) is C(weekly), C(type=session_state_change). - - Optional when C(type=monthlydow). - type: str - days_of_month: - description: - - The days of the month from 1 to 31 for the triggers. - - If you wish to set the trigger for the last day of any month - use C(run_on_last_day_of_month). - - Can be a list or comma separated string of day numbers. - - Required when C(type=monthly). - type: str - weeks_of_month: - description: - - The weeks of the month for the trigger. - - Can be a list or comma separated string of the numbers 1 to 4 - representing the first to 4th week of the month. - - Optional when C(type=monthlydow). - type: str - months_of_year: - description: - - The months of the year for the trigger. - - Can be a list or comma separated string of full month names e.g. - march instead of mar. - - Optional when C(type) is C(monthlydow), C(monthly). - type: str - run_on_last_week_of_month: - description: - - Boolean value that sets whether the task runs on the last week of the - month. - - Optional when C(type) is C(monthlydow). - type: bool - run_on_last_day_of_month: - description: - - Boolean value that sets whether the task runs on the last day of the - month. - - Optional when C(type) is C(monthly). - type: bool - weeks_interval: - description: - - The interval of weeks to run on, e.g. C(1) means every week while - C(2) means every other week. - - Optional when C(type=weekly). - type: int - repetition: - description: - - Allows you to define the repetition action of the trigger that defines how often the task is run and how long the repetition pattern is repeated - after the task is started. - - It takes in the following keys, C(duration), C(interval), C(stop_at_duration_end) - suboptions: - duration: - description: - - Defines how long the pattern is repeated. - - The value is in the ISO 8601 Duration format C(P[n]Y[n]M[n]DT[n]H[n]M[n]S). - - By default this is not set which means it will repeat indefinitely. - type: str - interval: - description: - - The amount of time between each restart of the task. - - The value is written in the ISO 8601 Duration format C(P[n]Y[n]M[n]DT[n]H[n]M[n]S). - type: str - stop_at_duration_end: - description: - - Whether a running instance of the task is stopped at the end of the repetition pattern. - type: bool - version_added: '2.5' - - # Principal options - display_name: - description: - - The name of the user/group that is displayed in the Task Scheduler UI. - type: str - version_added: '2.5' - group: - description: - - The group that will run the task. - - C(group) and C(username) are exclusive to each other and cannot be set - at the same time. - - C(logon_type) can either be not set or equal C(group). - type: str - version_added: '2.5' - logon_type: - description: - - The logon method that the task will run with. - - C(password) means the password will be stored and the task has access - to network resources. - - C(s4u) means the existing token will be used to run the task and no - password will be stored with the task. Means no network or encrypted - files access. - - C(interactive_token) means the user must already be logged on - interactively and will run in an existing interactive session. - - C(group) means that the task will run as a group. - - C(service_account) means that a service account like System, Local - Service or Network Service will run the task. - type: str - choices: [ none, password, s4u, interactive_token, group, service_account, token_or_password ] - version_added: '2.5' - run_level: - description: - - The level of user rights used to run the task. - - If not specified the task will be created with limited rights. - type: str - choices: [ limited, highest ] - aliases: [ runlevel ] - version_added: '2.4' - username: - description: - - The user to run the scheduled task as. - - Will default to the current user under an interactive token if not - specified during creation. - - The user account specified must have the C(SeBatchLogonRight) logon right - which can be added with M(win_user_right). - type: str - aliases: [ user ] - password: - description: - - The password for the user account to run the scheduled task as. - - This is required when running a task without the user being logged in, - excluding the builtin service accounts and Group Managed Service Accounts (gMSA). - - If set, will always result in a change unless C(update_password) is set - to C(no) and no other changes are required for the service. - type: str - version_added: '2.4' - update_password: - description: - - Whether to update the password even when not other changes have occurred. - - When C(yes) will always result in a change when executing the module. - type: bool - default: yes - version_added: '2.5' - - # RegistrationInfo options - author: - description: - - The author of the task. - type: str - version_added: '2.5' - date: - description: - - The date when the task was registered. - type: str - version_added: '2.5' - description: - description: - - The description of the task. - type: str - version_added: '2.5' - source: - description: - - The source of the task. - type: str - version_added: '2.5' - version: - description: - - The version number of the task. - type: str - version_added: '2.5' - - # Settings options - allow_demand_start: - description: - - Whether the task can be started by using either the Run command or the - Context menu. - type: bool - version_added: '2.5' - allow_hard_terminate: - description: - - Whether the task can be terminated by using TerminateProcess. - type: bool - version_added: '2.5' - compatibility: - description: - - The integer value with indicates which version of Task Scheduler a task - is compatible with. - - C(0) means the task is compatible with the AT command. - - C(1) means the task is compatible with Task Scheduler 1.0. - - C(2) means the task is compatible with Task Scheduler 2.0. - type: int - choices: [ 0, 1, 2 ] - version_added: '2.5' - delete_expired_task_after: - description: - - The amount of time that the Task Scheduler will wait before deleting the - task after it expires. - - A task expires after the end_boundary has been exceeded for all triggers - associated with the task. - - This is in the ISO 8601 Duration format C(P[n]Y[n]M[n]DT[n]H[n]M[n]S). - type: str - version_added: '2.5' - disallow_start_if_on_batteries: - description: - - Whether the task will not be started if the computer is running on - battery power. - type: bool - version_added: '2.5' - enabled: - description: - - Whether the task is enabled, the task can only run when C(yes). - type: bool - version_added: '2.5' - execution_time_limit: - description: - - The amount of time allowed to complete the task. - - When set to `PT0S`, the time limit is infinite. - - When omitted, the default time limit is 72 hours. - - This is in the ISO 8601 Duration format C(P[n]Y[n]M[n]DT[n]H[n]M[n]S). - type: str - version_added: '2.5' - hidden: - description: - - Whether the task will be hidden in the UI. - type: bool - version_added: '2.5' - multiple_instances: - description: - - An integer that indicates the behaviour when starting a task that is - already running. - - C(0) will start a new instance in parallel with existing instances of - that task. - - C(1) will wait until other instances of that task to finish running - before starting itself. - - C(2) will not start a new instance if another is running. - - C(3) will stop other instances of the task and start the new one. - type: int - choices: [ 0, 1, 2, 3 ] - version_added: '2.5' - priority: - description: - - The priority level (0-10) of the task. - - When creating a new task the default is C(7). - - See U(https://msdn.microsoft.com/en-us/library/windows/desktop/aa383512.aspx) - for details on the priority levels. - type: int - version_added: '2.5' - restart_count: - description: - - The number of times that the Task Scheduler will attempt to restart the - task. - type: int - version_added: '2.5' - restart_interval: - description: - - How long the Task Scheduler will attempt to restart the task. - - If this is set then C(restart_count) must also be set. - - The maximum allowed time is 31 days. - - The minimum allowed time is 1 minute. - - This is in the ISO 8601 Duration format C(P[n]Y[n]M[n]DT[n]H[n]M[n]S). - type: str - version_added: '2.5' - run_only_if_idle: - description: - - Whether the task will run the task only if the computer is in an idle - state. - type: bool - version_added: '2.5' - run_only_if_network_available: - description: - - Whether the task will run only when a network is available. - type: bool - version_added: '2.5' - start_when_available: - description: - - Whether the task can start at any time after its scheduled time has - passed. - type: bool - version_added: '2.5' - stop_if_going_on_batteries: - description: - - Whether the task will be stopped if the computer begins to run on battery - power. - type: bool - version_added: '2.5' - wake_to_run: - description: - - Whether the task will wake the computer when it is time to run the task. - type: bool - version_added: '2.5' -notes: -- In Ansible 2.4 and earlier, this could only be run on Server 2012/Windows 8 - or newer. Since Ansible 2.5 this restriction has been lifted. -- The option names and structure for actions and triggers of a service follow - the C(RegisteredTask) naming standard and requirements, it would be useful to - read up on this guide if coming across any issues U(https://msdn.microsoft.com/en-us/library/windows/desktop/aa382542.aspx). -- A Group Managed Service Account (gMSA) can be used by setting C(logon_type) to C(password) - and omitting the password parameter. For more information on gMSAs, - see U(https://techcommunity.microsoft.com/t5/Core-Infrastructure-and-Security/Windows-Server-2012-Group-Managed-Service-Accounts/ba-p/255910) -seealso: -- module: win_scheduled_task_stat -- module: win_user_right -author: -- Peter Mounce (@petemounce) -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Create a task to open 2 command prompts as SYSTEM - win_scheduled_task: - name: TaskName - description: open command prompt - actions: - - path: cmd.exe - arguments: /c hostname - - path: cmd.exe - arguments: /c whoami - triggers: - - type: daily - start_boundary: '2017-10-09T09:00:00' - username: SYSTEM - state: present - enabled: yes - -- name: Create task to run a PS script as NETWORK service on boot - win_scheduled_task: - name: TaskName2 - description: Run a PowerShell script - actions: - - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - arguments: -ExecutionPolicy Unrestricted -NonInteractive -File C:\TestDir\Test.ps1 - triggers: - - type: boot - username: NETWORK SERVICE - run_level: highest - state: present - -- name: Update Local Security Policy to allow users to run scheduled tasks - win_user_right: - name: SeBatchLogonRight - users: - - LocalUser - - DOMAIN\NetworkUser - action: add - -- name: Change above task to run under a domain user account, storing the passwords - win_scheduled_task: - name: TaskName2 - username: DOMAIN\User - password: Password - logon_type: password - -- name: Change the above task again, choosing not to store the password - win_scheduled_task: - name: TaskName2 - username: DOMAIN\User - logon_type: s4u - -- name: Change above task to use a gMSA, where the password is managed automatically - win_scheduled_task: - name: TaskName2 - username: DOMAIN\gMsaSvcAcct$ - logon_type: password - -- name: Create task with multiple triggers - win_scheduled_task: - name: TriggerTask - path: \Custom - actions: - - path: cmd.exe - triggers: - - type: daily - - type: monthlydow - username: SYSTEM - -- name: Set logon type to password but don't force update the password - win_scheduled_task: - name: TriggerTask - path: \Custom - actions: - - path: cmd.exe - username: Administrator - password: password - update_password: no - -- name: Disable a task that already exists - win_scheduled_task: - name: TaskToDisable - enabled: no - -- name: Create a task that will be repeated every minute for five minutes - win_scheduled_task: - name: RepeatedTask - description: open command prompt - actions: - - path: cmd.exe - arguments: /c hostname - triggers: - - type: registration - repetition: - interval: PT1M - duration: PT5M - stop_at_duration_end: yes -''' - -RETURN = r''' -''' diff --git a/lib/ansible/modules/windows/win_scheduled_task_stat.ps1 b/lib/ansible/modules/windows/win_scheduled_task_stat.ps1 deleted file mode 100644 index 37bc78a2813..00000000000 --- a/lib/ansible/modules/windows/win_scheduled_task_stat.ps1 +++ /dev/null @@ -1,330 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.CamelConversion -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.SID - -$params = Parse-Args -arguments $args -$_remote_tmp = Get-AnsibleParam $params "_ansible_remote_tmp" -type "path" -default $env:TMP - -$path = Get-AnsibleParam -obj $params -name "path" -type "str" -default "\" -$name = Get-AnsibleParam -obj $params -name "name" -type "str" - -$result = @{ - changed = $false -} - -$task_enums = @" -public enum TASK_ACTION_TYPE -{ - TASK_ACTION_EXEC = 0, - // The below are not supported and are only kept for documentation purposes - TASK_ACTION_COM_HANDLER = 5, - TASK_ACTION_SEND_EMAIL = 6, - TASK_ACTION_SHOW_MESSAGE = 7 -} - -public enum TASK_LOGON_TYPE -{ - TASK_LOGON_NONE = 0, - TASK_LOGON_PASSWORD = 1, - TASK_LOGON_S4U = 2, - TASK_LOGON_INTERACTIVE_TOKEN = 3, - TASK_LOGON_GROUP = 4, - TASK_LOGON_SERVICE_ACCOUNT = 5, - TASK_LOGON_INTERACTIVE_TOKEN_OR_PASSWORD = 6 -} - -public enum TASK_RUN_LEVEL -{ - TASK_RUNLEVEL_LUA = 0, - TASK_RUNLEVEL_HIGHEST = 1 -} - -public enum TASK_STATE -{ - TASK_STATE_UNKNOWN = 0, - TASK_STATE_DISABLED = 1, - TASK_STATE_QUEUED = 2, - TASK_STATE_READY = 3, - TASK_STATE_RUNNING = 4 -} - -public enum TASK_TRIGGER_TYPE2 -{ - TASK_TRIGGER_EVENT = 0, - TASK_TRIGGER_TIME = 1, - TASK_TRIGGER_DAILY = 2, - TASK_TRIGGER_WEEKLY = 3, - TASK_TRIGGER_MONTHLY = 4, - TASK_TRIGGER_MONTHLYDOW = 5, - TASK_TRIGGER_IDLE = 6, - TASK_TRIGGER_REGISTRATION = 7, - TASK_TRIGGER_BOOT = 8, - TASK_TRIGGER_LOGON = 9, - TASK_TRIGGER_SESSION_STATE_CHANGE = 11 -} -"@ - -$original_tmp = $env:TMP -$env:TMP = $_remote_tmp -Add-Type -TypeDefinition $task_enums -$env:TMP = $original_tmp - -Function Get-PropertyValue($task_property, $com, $property) { - $raw_value = $com.$property - - if ($null -eq $raw_value) { - return $null - } elseif ($raw_value.GetType().Name -eq "__ComObject") { - $com_values = @{} - Get-Member -InputObject $raw_value -MemberType Property | ForEach-Object { - $com_value = Get-PropertyValue -task_property $property -com $raw_value -property $_.Name - $com_values.$($_.Name) = $com_value - } - - return ,$com_values - } - - switch ($property) { - DaysOfWeek { - $value_list = @() - $map = @( - @{ day = "sunday"; bitwise = 0x01 } - @{ day = "monday"; bitwise = 0x02 } - @{ day = "tuesday"; bitwise = 0x04 } - @{ day = "wednesday"; bitwise = 0x08 } - @{ day = "thursday"; bitwise = 0x10 } - @{ day = "friday"; bitwise = 0x20 } - @{ day = "saturday"; bitwise = 0x40 } - ) - foreach ($entry in $map) { - $day = $entry.day - $bitwise = $entry.bitwise - if ($raw_value -band $bitwise) { - $value_list += $day - } - } - - $value = $value_list -join "," - break - } - DaysOfMonth { - $value_list = @() - $map = @( - @{ day = "1"; bitwise = 0x01 } - @{ day = "2"; bitwise = 0x02 } - @{ day = "3"; bitwise = 0x04 } - @{ day = "4"; bitwise = 0x08 } - @{ day = "5"; bitwise = 0x10 } - @{ day = "6"; bitwise = 0x20 } - @{ day = "7"; bitwise = 0x40 } - @{ day = "8"; bitwise = 0x80 } - @{ day = "9"; bitwise = 0x100 } - @{ day = "10"; bitwise = 0x200 } - @{ day = "11"; bitwise = 0x400 } - @{ day = "12"; bitwise = 0x800 } - @{ day = "13"; bitwise = 0x1000 } - @{ day = "14"; bitwise = 0x2000 } - @{ day = "15"; bitwise = 0x4000 } - @{ day = "16"; bitwise = 0x8000 } - @{ day = "17"; bitwise = 0x10000 } - @{ day = "18"; bitwise = 0x20000 } - @{ day = "19"; bitwise = 0x40000 } - @{ day = "20"; bitwise = 0x80000 } - @{ day = "21"; bitwise = 0x100000 } - @{ day = "22"; bitwise = 0x200000 } - @{ day = "23"; bitwise = 0x400000 } - @{ day = "24"; bitwise = 0x800000 } - @{ day = "25"; bitwise = 0x1000000 } - @{ day = "26"; bitwise = 0x2000000 } - @{ day = "27"; bitwise = 0x4000000 } - @{ day = "28"; bitwise = 0x8000000 } - @{ day = "29"; bitwise = 0x10000000 } - @{ day = "30"; bitwise = 0x20000000 } - @{ day = "31"; bitwise = 0x40000000 } - ) - - foreach ($entry in $map) { - $day = $entry.day - $bitwise = $entry.bitwise - if ($raw_value -band $bitwise) { - $value_list += $day - } - } - - $value = $value_list -join "," - break - } - WeeksOfMonth { - $value_list = @() - $map = @( - @{ week = "1"; bitwise = 0x01 } - @{ week = "2"; bitwise = 0x02 } - @{ week = "3"; bitwise = 0x04 } - @{ week = "4"; bitwise = 0x04 } - ) - - foreach ($entry in $map) { - $week = $entry.week - $bitwise = $entry.bitwise - if ($raw_value -band $bitwise) { - $value_list += $week - } - } - - $value = $value_list -join "," - break - } - MonthsOfYear { - $value_list = @() - $map = @( - @{ month = "january"; bitwise = 0x01 } - @{ month = "february"; bitwise = 0x02 } - @{ month = "march"; bitwise = 0x04 } - @{ month = "april"; bitwise = 0x08 } - @{ month = "may"; bitwise = 0x10 } - @{ month = "june"; bitwise = 0x20 } - @{ month = "july"; bitwise = 0x40 } - @{ month = "august"; bitwise = 0x80 } - @{ month = "september"; bitwise = 0x100 } - @{ month = "october"; bitwise = 0x200 } - @{ month = "november"; bitwise = 0x400 } - @{ month = "december"; bitwise = 0x800 } - ) - - foreach ($entry in $map) { - $month = $entry.month - $bitwise = $entry.bitwise - if ($raw_value -band $bitwise) { - $value_list += $month - } - } - - $value = $value_list -join "," - break - } - Type { - if ($task_property -eq "actions") { - $value = [Enum]::ToObject([TASK_ACTION_TYPE], $raw_value).ToString() - } elseif ($task_property -eq "triggers") { - $value = [Enum]::ToObject([TASK_TRIGGER_TYPE2], $raw_value).ToString() - } - break - } - RunLevel { - $value = [Enum]::ToObject([TASK_RUN_LEVEL], $raw_value).ToString() - break - } - LogonType { - $value = [Enum]::ToObject([TASK_LOGON_TYPE], $raw_value).ToString() - break - } - UserId { - $sid = Convert-ToSID -account_name $raw_value - $value = Convert-FromSid -sid $sid - } - GroupId { - $sid = Convert-ToSID -account_name $raw_value - $value = Convert-FromSid -sid $sid - } - default { - $value = $raw_value - break - } - } - - return ,$value -} - -$service = New-Object -ComObject Schedule.Service -try { - $service.Connect() -} catch { - Fail-Json -obj $result -message "failed to connect to the task scheduler service: $($_.Exception.Message)" -} - -try { - $task_folder = $service.GetFolder($path) - $result.folder_exists = $true -} catch { - $result.folder_exists = $false - if ($null -ne $name) { - $result.task_exists = $false - } - Exit-Json -obj $result -} - -$folder_tasks = $task_folder.GetTasks(1) -$folder_task_names = @() -$folder_task_count = 0 -$task = $null -for ($i = 1; $i -le $folder_tasks.Count; $i++) { - $task_name = $folder_tasks.Item($i).Name - $folder_task_names += $task_name - $folder_task_count += 1 - - if ($null -ne $name -and $task_name -eq $name) { - $task = $folder_tasks.Item($i) - } -} -$result.folder_task_names = $folder_task_names -$result.folder_task_count = $folder_task_count - -if ($null -ne $name) { - if ($null -ne $task) { - $result.task_exists = $true - - # task state - $result.state = @{ - last_run_time = (Get-Date $task.LastRunTime -Format s) - last_task_result = $task.LastTaskResult - next_run_time = (Get-Date $task.NextRunTime -Format s) - number_of_missed_runs = $task.NumberOfMissedRuns - status = [Enum]::ToObject([TASK_STATE], $task.State).ToString() - } - - # task definition - $task_definition = $task.Definition - $ignored_properties = @("XmlText") - $properties = @("principal", "registration_info", "settings") - $collection_properties = @("actions", "triggers") - - foreach ($property in $properties) { - $property_name = $property -replace "_" - $result.$property = @{} - $values = $task_definition.$property_name - Get-Member -InputObject $values -MemberType Property | ForEach-Object { - if ($_.Name -notin $ignored_properties) { - $result.$property.$($_.Name) = (Get-PropertyValue -task_property $property -com $values -property $_.Name) - } - } - } - - foreach ($property in $collection_properties) { - $result.$property = @() - $collection = $task_definition.$property - $collection_count = $collection.Count - for ($i = 1; $i -le $collection_count; $i++) { - $item = $collection.Item($i) - $item_info = @{} - - Get-Member -InputObject $item -MemberType Property | ForEach-Object { - if ($_.Name -notin $ignored_properties) { - $item_info.$($_.Name) = (Get-PropertyValue -task_property $property -com $item -property $_.Name) - } - } - $result.$property += $item_info - } - } - } else { - $result.task_exists = $false - } -} - -$result = Convert-DictToSnakeCase -dict $result - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_scheduled_task_stat.py b/lib/ansible/modules/windows/win_scheduled_task_stat.py deleted file mode 100644 index 1c450c40401..00000000000 --- a/lib/ansible/modules/windows/win_scheduled_task_stat.py +++ /dev/null @@ -1,379 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_scheduled_task_stat -version_added: "2.5" -short_description: Get information about Windows Scheduled Tasks -description: -- Will return whether the folder and task exists. -- Returns the names of tasks in the folder specified. -- Use M(win_scheduled_task) to configure a scheduled task. -options: - path: - description: The folder path where the task lives. - type: str - default: \ - name: - description: - - The name of the scheduled task to get information for. - - If C(name) is set and exists, will return information on the task itself. - type: str -seealso: -- module: win_scheduled_task -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Get information about a folder - win_scheduled_task_stat: - path: \folder name - register: task_folder_stat - -- name: Get information about a task in the root folder - win_scheduled_task_stat: - name: task name - register: task_stat - -- name: Get information about a task in a custom folder - win_scheduled_task_stat: - path: \folder name - name: task name - register: task_stat -''' - -RETURN = r''' -actions: - description: A list of actions. - returned: name is specified and task exists - type: list - sample: [ - { - "Arguments": "/c echo hi", - "Id": null, - "Path": "cmd.exe", - "Type": "TASK_ACTION_EXEC", - "WorkingDirectory": null - } - ] -folder_exists: - description: Whether the folder set at path exists. - returned: always - type: bool - sample: true -folder_task_count: - description: The number of tasks that exist in the folder. - returned: always - type: int - sample: 2 -folder_task_names: - description: A list of tasks that exist in the folder. - returned: always - type: list - sample: [ 'Task 1', 'Task 2' ] -principal: - description: Details on the principal configured to run the task. - returned: name is specified and task exists - type: complex - contains: - display_name: - description: The name of the user/group that is displayed in the Task - Scheduler UI. - returned: '' - type: str - sample: Administrator - group_id: - description: The group that will run the task. - returned: '' - type: str - sample: BUILTIN\Administrators - id: - description: The ID for the principal. - returned: '' - type: str - sample: Author - logon_type: - description: The logon method that the task will run with. - returned: '' - type: str - sample: TASK_LOGON_INTERACTIVE_TOKEN - run_level: - description: The level of user rights used to run the task. - returned: '' - type: str - sample: TASK_RUNLEVEL_LUA - user_id: - description: The user that will run the task. - returned: '' - type: str - sample: SERVER\Administrator -registration_info: - description: Details on the task registration info. - returned: name is specified and task exists - type: complex - contains: - author: - description: The author os the task. - returned: '' - type: str - sample: SERVER\Administrator - date: - description: The date when the task was register. - returned: '' - type: str - sample: '2017-01-01T10:00:00' - description: - description: The description of the task. - returned: '' - type: str - sample: task description - documentation: - description: The documentation of the task. - returned: '' - type: str - sample: task documentation - security_descriptor: - description: The security descriptor of the task. - returned: '' - type: str - sample: security descriptor - source: - description: The source of the task. - returned: '' - type: str - sample: source - uri: - description: The URI/path of the task. - returned: '' - type: str - sample: \task\task name - version: - description: The version of the task. - returned: '' - type: str - sample: 1.0 -settings: - description: Details on the task settings. - returned: name is specified and task exists - type: complex - contains: - allow_demand_start: - description: Whether the task can be started by using either the Run - command of the Context menu. - returned: '' - type: bool - sample: true - allow_hard_terminate: - description: Whether the task can terminated by using TerminateProcess. - returned: '' - type: bool - sample: true - compatibility: - description: The compatibility level of the task - returned: '' - type: int - sample: 2 - delete_expired_task_after: - description: The amount of time the Task Scheduler will wait before - deleting the task after it expires. - returned: '' - type: str - sample: PT10M - disallow_start_if_on_batteries: - description: Whether the task will not be started if the computer is - running on battery power. - returned: '' - type: bool - sample: false - disallow_start_on_remote_app_session: - description: Whether the task will not be started when in a remote app - session. - returned: '' - type: bool - sample: true - enabled: - description: Whether the task is enabled. - returned: '' - type: bool - sample: true - execution_time_limit: - description: The amount of time allowed to complete the task. - returned: '' - type: str - sample: PT72H - hidden: - description: Whether the task is hidden in the UI. - returned: '' - type: bool - sample: false - idle_settings: - description: The idle settings of the task. - returned: '' - type: dict - sample: { - "idle_duration": "PT10M", - "restart_on_idle": false, - "stop_on_idle_end": true, - "wait_timeout": "PT1H" - } - maintenance_settings: - description: The maintenance settings of the task. - returned: '' - type: str - sample: null - mulitple_instances: - description: Indicates the behaviour when starting a task that is already - running. - returned: '' - type: int - sample: 2 - network_settings: - description: The network settings of the task. - returned: '' - type: dict - sample: { - "id": null, - "name": null - } - priority: - description: The priority level of the task. - returned: '' - type: int - sample: 7 - restart_count: - description: The number of times that the task will attempt to restart - on failures. - returned: '' - type: int - sample: 0 - restart_interval: - description: How long the Task Scheduler will attempt to restart the - task. - returned: '' - type: str - sample: PT15M - run_only_id_idle: - description: Whether the task will run if the computer is in an idle - state. - returned: '' - type: bool - sample: true - run_only_if_network_available: - description: Whether the task will run only when a network is available. - returned: '' - type: bool - sample: false - start_when_available: - description: Whether the task can start at any time after its scheduled - time has passed. - returned: '' - type: bool - sample: false - stop_if_going_on_batteries: - description: Whether the task will be stopped if the computer begins to - run on battery power. - returned: '' - type: bool - sample: true - use_unified_scheduling_engine: - description: Whether the task will use the unified scheduling engine. - returned: '' - type: bool - sample: false - volatile: - description: Whether the task is volatile. - returned: '' - type: bool - sample: false - wake_to_run: - description: Whether the task will wake the computer when it is time to - run the task. - returned: '' - type: bool - sample: false -state: - description: Details on the state of the task - returned: name is specified and task exists - type: complex - contains: - last_run_time: - description: The time the registered task was last run. - returned: '' - type: str - sample: '2017-09-20T20:50:00' - last_task_result: - description: The results that were returned the last time the task was - run. - returned: '' - type: int - sample: 267009 - next_run_time: - description: The time when the task is next scheduled to run. - returned: '' - type: str - sample: '2017-09-20T22:50:00' - number_of_missed_runs: - description: The number of times a task has missed a scheduled run. - returned: '' - type: int - sample: 1 - status: - description: The status of the task, whether it is running, stopped, etc. - returned: '' - type: str - sample: TASK_STATE_RUNNING -task_exists: - description: Whether the task at the folder exists. - returned: name is specified - type: bool - sample: true -triggers: - description: A list of triggers. - returned: name is specified and task exists - type: list - sample: [ - { - "delay": "PT15M", - "enabled": true, - "end_boundary": null, - "execution_time_limit": null, - "id": null, - "repetition": { - "duration": null, - "interval": null, - "stop_at_duration_end": false - }, - "start_boundary": null, - "type": "TASK_TRIGGER_BOOT" - }, - { - "days_of_month": "5,15,30", - "enabled": true, - "end_boundary": null, - "execution_time_limit": null, - "id": null, - "months_of_year": "june,december", - "random_delay": null, - "repetition": { - "duration": null, - "interval": null, - "stop_at_duration_end": false - }, - "run_on_last_day_of_month": true, - "start_boundary": "2017-09-20T03:44:38", - "type": "TASK_TRIGGER_MONTHLY" - } - ] -''' diff --git a/lib/ansible/modules/windows/win_security_policy.ps1 b/lib/ansible/modules/windows/win_security_policy.ps1 deleted file mode 100644 index 274204b6aaf..00000000000 --- a/lib/ansible/modules/windows/win_security_policy.ps1 +++ /dev/null @@ -1,196 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Jordan Borean -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = 'Stop' - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff_mode = Get-AnsibleParam -obj $Params -name "_ansible_diff" -type "bool" -default $false - -$section = Get-AnsibleParam -obj $params -name "section" -type "str" -failifempty $true -$key = Get-AnsibleParam -obj $params -name "key" -type "str" -failifempty $true -$value = Get-AnsibleParam -obj $params -name "value" -failifempty $true - -$result = @{ - changed = $false - section = $section - key = $key - value = $value -} - -if ($diff_mode) { - $result.diff = @{} -} - -Function Run-SecEdit($arguments) { - $stdout = $null - $stderr = $null - $log_path = [IO.Path]::GetTempFileName() - $arguments = $arguments + @("/log", $log_path) - - try { - $stdout = &SecEdit.exe $arguments | Out-String - } catch { - $stderr = $_.Exception.Message - } - $log = Get-Content -Path $log_path - Remove-Item -Path $log_path -Force - - $return = @{ - log = ($log -join "`n").Trim() - stdout = $stdout - stderr = $stderr - rc = $LASTEXITCODE - } - - return $return -} - -Function Export-SecEdit() { - $secedit_ini_path = [IO.Path]::GetTempFileName() - # while this will technically make a change to the system in check mode by - # creating a new file, we need these values to be able to do anything - # substantial in check mode - $export_result = Run-SecEdit -arguments @("/export", "/cfg", $secedit_ini_path, "/quiet") - - # check the return code and if the file has been populated, otherwise error out - if (($export_result.rc -ne 0) -or ((Get-Item -Path $secedit_ini_path).Length -eq 0)) { - Remove-Item -Path $secedit_ini_path -Force - $result.rc = $export_result.rc - $result.stdout = $export_result.stdout - $result.stderr = $export_result.stderr - Fail-Json $result "Failed to export secedit.ini file to $($secedit_ini_path)" - } - $secedit_ini = ConvertFrom-Ini -file_path $secedit_ini_path - - return $secedit_ini -} - -Function Import-SecEdit($ini) { - $secedit_ini_path = [IO.Path]::GetTempFileName() - $secedit_db_path = [IO.Path]::GetTempFileName() - Remove-Item -Path $secedit_db_path -Force # needs to be deleted for SecEdit.exe /import to work - - $ini_contents = ConvertTo-Ini -ini $ini - Set-Content -Path $secedit_ini_path -Value $ini_contents - $result.changed = $true - - $import_result = Run-SecEdit -arguments @("/configure", "/db", $secedit_db_path, "/cfg", $secedit_ini_path, "/quiet") - $result.import_log = $import_result.log - Remove-Item -Path $secedit_ini_path -Force - if ($import_result.rc -ne 0) { - $result.rc = $import_result.rc - $result.stdout = $import_result.stdout - $result.stderr = $import_result.stderr - Fail-Json $result "Failed to import secedit.ini file from $($secedit_ini_path)" - } -} - -Function ConvertTo-Ini($ini) { - $content = @() - foreach ($key in $ini.GetEnumerator()) { - $section = $key.Name - $values = $key.Value - - $content += "[$section]" - foreach ($value in $values.GetEnumerator()) { - $value_key = $value.Name - $value_value = $value.Value - - if ($null -ne $value_value) { - $content += "$value_key = $value_value" - } - } - } - - return $content -join "`r`n" -} - -Function ConvertFrom-Ini($file_path) { - $ini = @{} - switch -Regex -File $file_path { - "^\[(.+)\]" { - $section = $matches[1] - $ini.$section = @{} - } - "(.+?)\s*=(.*)" { - $name = $matches[1].Trim() - $value = $matches[2].Trim() - if ($value -match "^\d+$") { - $value = [int]$value - } elseif ($value.StartsWith('"') -and $value.EndsWith('"')) { - $value = $value.Substring(1, $value.Length - 2) - } - - $ini.$section.$name = $value - } - } - - return $ini -} - -if ($section -eq "Privilege Rights") { - Add-Warning -obj $result -message "Using this module to edit rights and privileges is error-prone, use the win_user_right module instead" -} - -$will_change = $false -$secedit_ini = Export-SecEdit -if (-not ($secedit_ini.ContainsKey($section))) { - Fail-Json $result "The section '$section' does not exist in SecEdit.exe output ini" -} - -if ($secedit_ini.$section.ContainsKey($key)) { - $current_value = $secedit_ini.$section.$key - - if ($current_value -cne $value) { - if ($diff_mode) { - $result.diff.prepared = @" -[$section] --$key = $current_value -+$key = $value -"@ - } - - $secedit_ini.$section.$key = $value - $will_change = $true - } -} elseif ([string]$value -eq "") { - # Value is requested to be removed, and has already been removed, do nothing -} else { - if ($diff_mode) { - $result.diff.prepared = @" -[$section] -+$key = $value -"@ - } - $secedit_ini.$section.$key = $value - $will_change = $true -} - -if ($will_change -eq $true) { - $result.changed = $true - if (-not $check_mode) { - Import-SecEdit -ini $secedit_ini - - # secedit doesn't error out on improper entries, re-export and verify - # the changes occurred - $verification_ini = Export-SecEdit - $new_section_values = $verification_ini.$section - if ($new_section_values.ContainsKey($key)) { - $new_value = $new_section_values.$key - if ($new_value -cne $value) { - Fail-Json $result "Failed to change the value for key '$key' in section '$section', the value is still $new_value" - } - } elseif ([string]$value -eq "") { - # Value was empty, so OK if no longer in the result - } else { - Fail-Json $result "The key '$key' in section '$section' is not a valid key, cannot set this value" - } - } -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_security_policy.py b/lib/ansible/modules/windows/win_security_policy.py deleted file mode 100644 index d582a532317..00000000000 --- a/lib/ansible/modules/windows/win_security_policy.py +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub, actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_security_policy -version_added: '2.4' -short_description: Change local security policy settings -description: -- Allows you to set the local security policies that are configured by - SecEdit.exe. -options: - section: - description: - - The ini section the key exists in. - - If the section does not exist then the module will return an error. - - Example sections to use are 'Account Policies', 'Local Policies', - 'Event Log', 'Restricted Groups', 'System Services', 'Registry' and - 'File System' - - If wanting to edit the C(Privilege Rights) section, use the - M(win_user_right) module instead. - type: str - required: yes - key: - description: - - The ini key of the section or policy name to modify. - - The module will return an error if this key is invalid. - type: str - required: yes - value: - description: - - The value for the ini key or policy name. - - If the key takes in a boolean value then 0 = False and 1 = True. - type: str - required: yes -notes: -- This module uses the SecEdit.exe tool to configure the values, more details - of the areas and keys that can be configured can be found here - U(https://msdn.microsoft.com/en-us/library/bb742512.aspx). -- If you are in a domain environment these policies may be set by a GPO policy, - this module can temporarily change these values but the GPO will override - it if the value differs. -- You can also run C(SecEdit.exe /export /cfg C:\temp\output.ini) to view the - current policies set on your system. -- When assigning user rights, use the M(win_user_right) module instead. -seealso: -- module: win_user_right -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Change the guest account name - win_security_policy: - section: System Access - key: NewGuestName - value: Guest Account - -- name: Set the maximum password age - win_security_policy: - section: System Access - key: MaximumPasswordAge - value: 15 - -- name: Do not store passwords using reversible encryption - win_security_policy: - section: System Access - key: ClearTextPassword - value: 0 - -- name: Enable system events - win_security_policy: - section: Event Audit - key: AuditSystemEvents - value: 1 -''' - -RETURN = r''' -rc: - description: The return code after a failure when running SecEdit.exe. - returned: failure with secedit calls - type: int - sample: -1 -stdout: - description: The output of the STDOUT buffer after a failure when running - SecEdit.exe. - returned: failure with secedit calls - type: str - sample: check log for error details -stderr: - description: The output of the STDERR buffer after a failure when running - SecEdit.exe. - returned: failure with secedit calls - type: str - sample: failed to import security policy -import_log: - description: The log of the SecEdit.exe /configure job that configured the - local policies. This is used for debugging purposes on failures. - returned: secedit.exe /import run and change occurred - type: str - sample: Completed 6 percent (0/15) \tProcess Privilege Rights area. -key: - description: The key in the section passed to the module to modify. - returned: success - type: str - sample: NewGuestName -section: - description: The section passed to the module to modify. - returned: success - type: str - sample: System Access -value: - description: The value passed to the module to modify to. - returned: success - type: str - sample: Guest Account -''' diff --git a/lib/ansible/modules/windows/win_shortcut.ps1 b/lib/ansible/modules/windows/win_shortcut.ps1 deleted file mode 100644 index 291f13cc80b..00000000000 --- a/lib/ansible/modules/windows/win_shortcut.ps1 +++ /dev/null @@ -1,374 +0,0 @@ -#!powershell - -# Copyright: (c) 2016, Dag Wieers (@dagwieers) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Based on: http://powershellblogger.com/2016/01/create-shortcuts-lnk-or-url-files-with-powershell/ - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.AddType - -$spec = @{ - options = @{ - src = @{ type='str' } - dest = @{ type='path'; required=$true } - state = @{ type='str'; default='present'; choices=@( 'absent', 'present' ) } - arguments = @{ type='str'; aliases=@( 'args' ) } - directory = @{ type='path' } - hotkey = @{ type='str' } - icon = @{ type='path' } - description = @{ type='str' } - windowstyle = @{ type='str'; choices=@( 'maximized', 'minimized', 'normal' ) } - run_as_admin = @{ type='bool'; default=$false } - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$src = $module.Params.src -$dest = $module.Params.dest -$state = $module.Params.state -$arguments = $module.Params.arguments # NOTE: Variable $args is a special variable -$directory = $module.Params.directory -$hotkey = $module.Params.hotkey -$icon = $module.Params.icon -$description = $module.Params.description -$windowstyle = $module.Params.windowstyle -$run_as_admin = $module.Params.run_as_admin - -# Expand environment variables on non-path types -if ($null -ne $src) { - $src = [System.Environment]::ExpandEnvironmentVariables($src) -} -if ($null -ne $arguments) { - $arguments = [System.Environment]::ExpandEnvironmentVariables($arguments) -} -if ($null -ne $description) { - $description = [System.Environment]::ExpandEnvironmentVariables($description) -} - -$module.Result.changed = $false -$module.Result.dest = $dest -$module.Result.state = $state - -# TODO: look at consolidating other COM actions into the C# class for future compatibility -Add-CSharpType -AnsibleModule $module -References @' -using System; -using System.Runtime.InteropServices; -using System.Runtime.InteropServices.ComTypes; -using System.Text; - -namespace Ansible.Shortcut -{ - [ComImport()] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - [Guid("000214F9-0000-0000-C000-000000000046")] - internal interface IShellLinkW - { - // We only care about GetPath and GetIDList, omit the other methods for now - void GetPath(StringBuilder pszFile, int cch, IntPtr pfd, UInt32 fFlags); - void GetIDList(out IntPtr ppidl); - } - - [ComImport()] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - [Guid("45E2b4AE-B1C3-11D0-B92F-00A0C90312E1")] - internal interface IShellLinkDataList - { - void AddDataBlock(IntPtr pDataBlock); - void CopyDataBlock(uint dwSig, out IntPtr ppDataBlock); - void RemoveDataBlock(uint dwSig); - void GetFlags(out ShellLinkFlags dwFlags); - void SetFlags(ShellLinkFlags dwFlags); - } - - internal class NativeHelpers - { - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct SHFILEINFO - { - public IntPtr hIcon; - public int iIcon; - public UInt32 dwAttributes; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 260)] public char[] szDisplayName; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] public char[] szTypeName; - } - } - - internal class NativeMethods - { - [DllImport("shell32.dll")] - public static extern void ILFree( - IntPtr pidl); - - [DllImport("shell32.dll")] - public static extern IntPtr SHGetFileInfoW( - IntPtr pszPath, - UInt32 dwFileAttributes, - ref NativeHelpers.SHFILEINFO psfi, - int sbFileInfo, - UInt32 uFlags); - - [DllImport("shell32.dll")] - public static extern int SHParseDisplayName( - [MarshalAs(UnmanagedType.LPWStr)] string pszName, - IntPtr pbc, - out IntPtr ppidl, - UInt32 sfagoIn, - out UInt32 psfgaoOut); - } - - [System.Flags] - public enum ShellLinkFlags : uint - { - Default = 0x00000000, - HasIdList = 0x00000001, - HasLinkInfo = 0x00000002, - HasName = 0x00000004, - HasRelPath = 0x00000008, - HasWorkingDir = 0x00000010, - HasArgs = 0x00000020, - HasIconLocation = 0x00000040, - Unicode = 0x00000080, - ForceNoLinkInfo = 0x00000100, - HasExpSz = 0x00000200, - RunInSeparate = 0x00000400, - HasLogo3Id = 0x00000800, - HasDarwinId = 0x00001000, - RunAsUser = 0x00002000, - HasExpIconSz = 0x00004000, - NoPidlAlias = 0x00008000, - ForceUncName = 0x00010000, - RunWithShimLayer = 0x00020000, - ForceNoLinkTrack = 0x00040000, - EnableTargetMetadata = 0x00080000, - DisableLinkPathTracking = 0x00100000, - DisableKnownFolderRelativeTracking = 0x00200000, - NoKfAlias = 0x00400000, - AllowLinkToLink = 0x00800000, - UnAliasOnSave = 0x01000000, - PreferEnvironmentPath = 0x02000000, - KeepLocalIdListForUncTarget = 0x04000000, - PersistVolumeIdToRelative = 0x08000000, - Valid = 0x0FFFF7FF, - Reserved = 0x80000000 - } - - public class ShellLink - { - private static Guid CLSID_ShellLink = new Guid("00021401-0000-0000-C000-000000000046"); - - public static ShellLinkFlags GetFlags(string path) - { - IShellLinkW link = InitialiseObj(path); - ShellLinkFlags dwFlags; - ((IShellLinkDataList)link).GetFlags(out dwFlags); - return dwFlags; - } - - public static void SetFlags(string path, ShellLinkFlags flags) - { - IShellLinkW link = InitialiseObj(path); - ((IShellLinkDataList)link).SetFlags(flags); - ((IPersistFile)link).Save(null, false); - } - - public static string GetTargetPath(string path) - { - IShellLinkW link = InitialiseObj(path); - - StringBuilder pathSb = new StringBuilder(260); - link.GetPath(pathSb, pathSb.Capacity, IntPtr.Zero, 0); - string linkPath = pathSb.ToString(); - - // If the path wasn't set, try and get the path from the ItemIDList - ShellLinkFlags flags = GetFlags(path); - if (String.IsNullOrEmpty(linkPath) && ((uint)flags & (uint)ShellLinkFlags.HasIdList) == (uint)ShellLinkFlags.HasIdList) - { - IntPtr idList = IntPtr.Zero; - try - { - link.GetIDList(out idList); - linkPath = GetDisplayNameFromPidl(idList); - } - finally - { - NativeMethods.ILFree(idList); - } - } - return linkPath; - } - - public static string GetDisplayNameFromPath(string path) - { - UInt32 sfgaoOut; - IntPtr pidl = IntPtr.Zero; - try - { - int res = NativeMethods.SHParseDisplayName(path, IntPtr.Zero, out pidl, 0, out sfgaoOut); - Marshal.ThrowExceptionForHR(res); - return GetDisplayNameFromPidl(pidl); - } - finally - { - NativeMethods.ILFree(pidl); - } - } - - private static string GetDisplayNameFromPidl(IntPtr pidl) - { - NativeHelpers.SHFILEINFO shFileInfo = new NativeHelpers.SHFILEINFO(); - UInt32 uFlags = 0x000000208; // SHGFI_DISPLAYNAME | SHGFI_PIDL - NativeMethods.SHGetFileInfoW(pidl, 0, ref shFileInfo, Marshal.SizeOf(typeof(NativeHelpers.SHFILEINFO)), uFlags); - return new string(shFileInfo.szDisplayName).TrimEnd('\0'); - } - - private static IShellLinkW InitialiseObj(string path) - { - IShellLinkW link = Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_ShellLink)) as IShellLinkW; - ((IPersistFile)link).Load(path, 0); - return link; - } - } -} -'@ - -# Convert from window style name to window style id -$windowstyles = @{ - normal = 1 - maximized = 3 - minimized = 7 -} - -# Convert from window style id to window style name -$windowstyleids = @( "", "normal", "", "maximized", "", "", "", "minimized" ) - -If ($state -eq "absent") { - If (Test-Path -Path $dest) { - # If the shortcut exists, try to remove it - Try { - Remove-Item -Path $dest -WhatIf:$module.CheckMode - } Catch { - # Report removal failure - $module.FailJson("Failed to remove shortcut '$dest'. ($($_.Exception.Message))", $_) - } - # Report removal success - $module.Result.changed = $true - } Else { - # Nothing to report, everything is fine already - } -} ElseIf ($state -eq "present") { - # Create an in-memory object based on the existing shortcut (if any) - $Shell = New-Object -ComObject ("WScript.Shell") - $ShortCut = $Shell.CreateShortcut($dest) - - # Compare existing values with new values, report as changed if required - - If ($null -ne $src) { - # Windows translates executables to absolute path, so do we - If (Get-Command -Name $src -Type Application -ErrorAction SilentlyContinue) { - $src = (Get-Command -Name $src -Type Application).Definition - } - If (-not (Test-Path -Path $src -IsValid)) { - If (-not (Split-Path -Path $src -IsAbsolute)) { - $module.FailJson("Source '$src' is not found in PATH and not a valid or absolute path.") - } - } - } - - # Determine if we have a WshShortcut or WshUrlShortcut by checking the Arguments property - # A WshUrlShortcut objects only consists of a TargetPath property - - $file_shortcut = $false - If (Get-Member -InputObject $ShortCut -Name Arguments) { - # File ShortCut, compare multiple properties - $file_shortcut = $true - - $target_path = $ShortCut.TargetPath - If (($null -ne $src) -and ($ShortCut.TargetPath -ne $src)) { - if ((Test-Path -Path $dest) -and (-not $ShortCut.TargetPath)) { - # If the shortcut already exists but not on the COM object, we - # are dealing with a shell path like 'shell:RecycleBinFolder'. - $expanded_src = [Ansible.Shortcut.ShellLink]::GetDisplayNameFromPath($src) - $actual_src = [Ansible.Shortcut.ShellLink]::GetTargetPath($dest) - if ($expanded_src -ne $actual_src) { - $module.Result.changed = $true - $ShortCut.TargetPath = $src - } - } else { - $module.Result.changed = $true - $ShortCut.TargetPath = $src - } - $target_path = $src - } - - # This is a full-featured application shortcut ! - If (($null -ne $arguments) -and ($ShortCut.Arguments -ne $arguments)) { - $module.Result.changed = $true - $ShortCut.Arguments = $arguments - } - $module.Result.args = $ShortCut.Arguments - - If (($null -ne $directory) -and ($ShortCut.WorkingDirectory -ne $directory)) { - $module.Result.changed = $true - $ShortCut.WorkingDirectory = $directory - } - $module.Result.directory = $ShortCut.WorkingDirectory - - # FIXME: Not all values are accepted here ! Improve docs too. - If (($null -ne $hotkey) -and ($ShortCut.Hotkey -ne $hotkey)) { - $module.Result.changed = $true - $ShortCut.Hotkey = $hotkey - } - $module.Result.hotkey = $ShortCut.Hotkey - - If (($null -ne $icon) -and ($ShortCut.IconLocation -ne $icon)) { - $module.Result.changed = $true - $ShortCut.IconLocation = $icon - } - $module.Result.icon = $ShortCut.IconLocation - - If (($null -ne $description) -and ($ShortCut.Description -ne $description)) { - $module.Result.changed = $true - $ShortCut.Description = $description - } - $module.Result.description = $ShortCut.Description - - If (($null -ne $windowstyle) -and ($ShortCut.WindowStyle -ne $windowstyles.$windowstyle)) { - $module.Result.changed = $true - $ShortCut.WindowStyle = $windowstyles.$windowstyle - } - $module.Result.windowstyle = $windowstyleids[$ShortCut.WindowStyle] - } else { - # URL Shortcut, just compare the TargetPath - if (($null -ne $src) -and ($ShortCut.TargetPath -ne $src)) { - $module.Result.changed = $true - $ShortCut.TargetPath = $src - } - $target_path = $ShortCut.TargetPath - } - $module.Result.src = $target_path - - If (($module.Result.changed -eq $true) -and ($module.CheckMode -ne $true)) { - Try { - $ShortCut.Save() - } Catch { - $module.FailJson("Failed to create shortcut '$dest'. ($($_.Exception.Message))", $_) - } - } - - if ((Test-Path -Path $dest) -and $file_shortcut) { - # Only control the run_as_admin flag if using a File Shortcut - $flags = [Ansible.Shortcut.ShellLink]::GetFlags($dest) - if ($run_as_admin -and (-not $flags.HasFlag([Ansible.Shortcut.ShellLinkFlags]::RunAsUser))) { - [Ansible.Shortcut.ShellLink]::SetFlags($dest, ($flags -bor [Ansible.Shortcut.ShellLinkFlags]::RunAsUser)) - $module.Result.changed = $true - } elseif (-not $run_as_admin -and ($flags.HasFlag([Ansible.Shortcut.ShellLinkFlags]::RunAsUser))) { - [Ansible.Shortcut.ShellLink]::SetFlags($dest, ($flags -bxor [Ansible.Shortcut.ShellLinkFlags]::RunAsUser)) - $module.Result.changed = $true - } - } -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_shortcut.py b/lib/ansible/modules/windows/win_shortcut.py deleted file mode 100644 index 2fe2ff42920..00000000000 --- a/lib/ansible/modules/windows/win_shortcut.py +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2016, Dag Wieers (@dagwieers) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_shortcut -version_added: '2.3' -short_description: Manage shortcuts on Windows -description: -- Create, manage and delete Windows shortcuts -options: - src: - description: - - Executable or URL the shortcut points to. - - The executable needs to be in your PATH, or has to be an absolute - path to the executable. - type: str - description: - description: - - Description for the shortcut. - - This is usually shown when hoovering the icon. - type: str - dest: - description: - - Destination file for the shortcuting file. - - File name should have a C(.lnk) or C(.url) extension. - type: path - required: yes - arguments: - description: - - Additional arguments for the executable defined in C(src). - - Was originally just C(args) but renamed in Ansible 2.8. - type: str - aliases: [ args ] - directory: - description: - - Working directory for executable defined in C(src). - type: path - icon: - description: - - Icon used for the shortcut. - - File name should have a C(.ico) extension. - - The file name is followed by a comma and the number in the library file (.dll) or use 0 for an image file. - type: path - hotkey: - description: - - Key combination for the shortcut. - - This is a combination of one or more modifiers and a key. - - Possible modifiers are Alt, Ctrl, Shift, Ext. - - Possible keys are [A-Z] and [0-9]. - type: str - windowstyle: - description: - - Influences how the application is displayed when it is launched. - type: str - choices: [ maximized, minimized, normal ] - state: - description: - - When C(absent), removes the shortcut if it exists. - - When C(present), creates or updates the shortcut. - type: str - choices: [ absent, present ] - default: present - run_as_admin: - description: - - When C(src) is an executable, this can control whether the shortcut will be opened as an administrator or not. - type: bool - default: no - version_added: '2.8' -notes: -- 'The following options can include Windows environment variables: C(dest), C(args), C(description), C(dest), C(directory), C(icon) C(src)' -- 'Windows has two types of shortcuts: Application and URL shortcuts. URL shortcuts only consists of C(dest) and C(src)' -seealso: -- module: win_file -author: -- Dag Wieers (@dagwieers) -''' - -EXAMPLES = r''' -- name: Create an application shortcut on the desktop - win_shortcut: - src: C:\Program Files\Mozilla Firefox\Firefox.exe - dest: C:\Users\Public\Desktop\Mozilla Firefox.lnk - icon: C:\Program Files\Mozilla Firefox\Firefox.exe,0 - -- name: Create the same shortcut using environment variables - win_shortcut: - description: The Mozilla Firefox web browser - src: '%ProgramFiles%\Mozilla Firefox\Firefox.exe' - dest: '%Public%\Desktop\Mozilla Firefox.lnk' - icon: '%ProgramFiles\Mozilla Firefox\Firefox.exe,0' - directory: '%ProgramFiles%\Mozilla Firefox' - hotkey: Ctrl+Alt+F - -- name: Create an application shortcut for an executable in PATH to your desktop - win_shortcut: - src: cmd.exe - dest: Desktop\Command prompt.lnk - -- name: Create an application shortcut for the Ansible website - win_shortcut: - src: '%ProgramFiles%\Google\Chrome\Application\chrome.exe' - dest: '%UserProfile%\Desktop\Ansible website.lnk' - arguments: --new-window https://ansible.com/ - directory: '%ProgramFiles%\Google\Chrome\Application' - icon: '%ProgramFiles%\Google\Chrome\Application\chrome.exe,0' - hotkey: Ctrl+Alt+A - -- name: Create a URL shortcut for the Ansible website - win_shortcut: - src: https://ansible.com/ - dest: '%Public%\Desktop\Ansible website.url' -''' - -RETURN = r''' -''' diff --git a/lib/ansible/modules/windows/win_snmp.ps1 b/lib/ansible/modules/windows/win_snmp.ps1 deleted file mode 100644 index 48e03253fee..00000000000 --- a/lib/ansible/modules/windows/win_snmp.ps1 +++ /dev/null @@ -1,126 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$params = Parse-Args -arguments $args -supports_check_mode $true; -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$managers = Get-AnsibleParam -obj $params -name "permitted_managers" -type "list" -default $null -$communities = Get-AnsibleParam -obj $params -name "community_strings" -type "list" -default $null -$action_in = Get-AnsibleParam -obj $params -name "action" -type "str" -default "set" -ValidateSet @("set", "add", "remove") -$action = $action_in.ToLower() - -$result = @{ - failed = $False - changed = $False - community_strings = [System.Collections.ArrayList]@() - permitted_managers = [System.Collections.ArrayList]@() -} - -# Make sure lists are modifyable -[System.Collections.ArrayList]$managers = $managers -[System.Collections.ArrayList]$communities = $communities -[System.Collections.ArrayList]$indexes = @() - -# Type checking -# You would think that "$null -ne $managers" would work, but it doesn't. -# A proper type check is required. If a user provides an empty list then $managers -# is still of the correct type. If a user provides no option then $managers is $null. -If ($managers -Is [System.Collections.ArrayList] -And $managers.Count -gt 0 -And $managers[0] -IsNot [String]) { - Fail-Json $result "Permitted managers must be an array of strings" -} - -If ($communities -Is [System.Collections.ArrayList] -And $communities.Count -gt 0 -And $communities[0] -IsNot [String]) { - Fail-Json $result "SNMP communities must be an array of strings" -} - -$Managers_reg_key = "HKLM:\System\CurrentControlSet\services\SNMP\Parameters\PermittedManagers" -$Communities_reg_key = "HKLM:\System\CurrentControlSet\services\SNMP\Parameters\ValidCommunities" - -ForEach ($idx in (Get-Item $Managers_reg_key).Property) { - $manager = (Get-ItemProperty $Managers_reg_key).$idx - If ($idx.ToLower() -eq '(default)') { - continue - } - - $remove = $False - If ($managers -Is [System.Collections.ArrayList] -And $managers.Contains($manager)) { - If ($action -eq "remove") { - $remove = $True - } Else { - # Remove manager from list to add since it already exists - $managers.Remove($manager) - } - } ElseIf ($action -eq "set" -And $managers -Is [System.Collections.ArrayList]) { - # Will remove this manager since it is not in the set list - $remove = $True - } - - If ($remove) { - $result.changed = $True - Remove-ItemProperty -Path $Managers_reg_key -Name $idx -WhatIf:$check_mode - } Else { - # Remember that this index is in use - $indexes.Add([int]$idx) | Out-Null - $result.permitted_managers.Add($manager) | Out-Null - } -} - -ForEach ($community in (Get-Item $Communities_reg_key).Property) { - If ($community.ToLower() -eq '(default)') { - continue - } - - $remove = $False - If ($communities -Is [System.Collections.ArrayList] -And $communities.Contains($community)) { - If ($action -eq "remove") { - $remove = $True - } Else { - # Remove community from list to add since it already exists - $communities.Remove($community) - } - } ElseIf ($action -eq "set" -And $communities -Is [System.Collections.ArrayList]) { - # Will remove this community since it is not in the set list - $remove = $True - } - - If ($remove) { - $result.changed = $True - Remove-ItemProperty -Path $Communities_reg_key -Name $community -WhatIf:$check_mode - } Else { - $result.community_strings.Add($community) | Out-Null - } -} - -If ($action -eq "remove") { - Exit-Json $result -} - -# Add managers that don't already exist -$next_index = 0 -If ($managers -Is [System.Collections.ArrayList]) { - ForEach ($manager in $managers) { - While ($True) { - $next_index = $next_index + 1 - If (-Not $indexes.Contains($next_index)) { - $result.changed = $True - New-ItemProperty -Path $Managers_reg_key -Name $next_index -Value "$manager" -WhatIf:$check_mode | Out-Null - $result.permitted_managers.Add($manager) | Out-Null - break - } - } - } -} - -# Add communities that don't already exist -If ($communities -Is [System.Collections.ArrayList]) { - ForEach ($community in $communities) { - $result.changed = $True - New-ItemProperty -Path $Communities_reg_key -Name $community -PropertyType DWord -Value 4 -WhatIf:$check_mode | Out-Null - $result.community_strings.Add($community) | Out-Null - } -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_snmp.py b/lib/ansible/modules/windows/win_snmp.py deleted file mode 100644 index df9a5770822..00000000000 --- a/lib/ansible/modules/windows/win_snmp.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Ansible, inc -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = { - 'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community' -} - -DOCUMENTATION = r''' ---- -module: win_snmp -version_added: '2.8' -short_description: Configures the Windows SNMP service -description: - - This module configures the Windows SNMP service. -options: - permitted_managers: - description: - - The list of permitted SNMP managers. - type: list - community_strings: - description: - - The list of read-only SNMP community strings. - type: list - action: - description: - - C(add) will add new SNMP community strings and/or SNMP managers - - C(set) will replace SNMP community strings and/or SNMP managers. An - empty list for either C(community_strings) or C(permitted_managers) - will result in the respective lists being removed entirely. - - C(remove) will remove SNMP community strings and/or SNMP managers - type: str - choices: [ add, set, remove ] - default: set -author: - - Michael Cassaniti (@mcassaniti) -''' - -EXAMPLES = r''' ---- - - hosts: Windows - tasks: - - name: Replace SNMP communities and managers - win_snmp: - community_strings: - - public - permitted_managers: - - 192.168.1.2 - action: set - - - hosts: Windows - tasks: - - name: Replace SNMP communities and clear managers - win_snmp: - community_strings: - - public - permitted_managers: [] - action: set -''' - -RETURN = r''' -community_strings: - description: The list of community strings for this machine. - type: list - returned: always - sample: - - public - - snmp-ro -permitted_managers: - description: The list of permitted managers for this machine. - type: list - returned: always - sample: - - 192.168.1.1 - - 192.168.1.2 -''' diff --git a/lib/ansible/modules/windows/win_timezone.ps1 b/lib/ansible/modules/windows/win_timezone.ps1 deleted file mode 100644 index f46a11c3ad3..00000000000 --- a/lib/ansible/modules/windows/win_timezone.ps1 +++ /dev/null @@ -1,70 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Phil Schwartz -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff_support = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false - -$timezone = Get-AnsibleParam -obj $params -name "timezone" -type "str" -failifempty $true - -$result = @{ - changed = $false - previous_timezone = $timezone - timezone = $timezone -} - -Try { - # Get the current timezone set - $result.previous_timezone = $(tzutil.exe /g) - If ($LASTEXITCODE -ne 0) { - Throw "An error occurred when getting the current machine's timezone setting." - } - - if ( $result.previous_timezone -eq $timezone ) { - Exit-Json $result "Timezone '$timezone' is already set on this machine" - } Else { - # Check that timezone is listed as an available timezone to the machine - $tzList = $(tzutil.exe /l).ToLower() - If ($LASTEXITCODE -ne 0) { - Throw "An error occurred when listing the available timezones." - } - - $tzExists = $tzList.Contains(($timezone -Replace '_dstoff').ToLower()) - if (-not $tzExists) { - Fail-Json $result "The specified timezone: $timezone isn't supported on the machine." - } - - if ($check_mode) { - $result.changed = $true - } else { - tzutil.exe /s "$timezone" - if ($LASTEXITCODE -ne 0) { - Throw "An error occurred when setting the specified timezone with tzutil." - } - - $new_timezone = $(tzutil.exe /g) - if ($LASTEXITCODE -ne 0) { - Throw "An error occurred when getting the current machine's timezone setting." - } - - if ($timezone -eq $new_timezone) { - $result.changed = $true - } - } - - if ($diff_support) { - $result.diff = @{ - before = "$($result.previous_timezone)`n" - after = "$timezone`n" - } - } - } -} Catch { - Fail-Json $result "Error setting timezone to: $timezone." -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_timezone.py b/lib/ansible/modules/windows/win_timezone.py deleted file mode 100644 index a3b66c9e56f..00000000000 --- a/lib/ansible/modules/windows/win_timezone.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Phil Schwartz -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_timezone -version_added: '2.1' -short_description: Sets Windows machine timezone -description: -- Sets machine time to the specified timezone. -options: - timezone: - description: - - Timezone to set to. - - 'Example: Central Standard Time' - - To disable Daylight Saving time, add the suffix C(_dstoff) on timezones that support this. - type: str - required: yes -notes: -- The module will check if the provided timezone is supported on the machine. -- A list of possible timezones is available from C(tzutil.exe /l) and from - U(https://msdn.microsoft.com/en-us/library/ms912391.aspx) -- If running on Server 2008 the hotfix - U(https://support.microsoft.com/en-us/help/2556308/tzutil-command-line-tool-is-added-to-windows-vista-and-to-windows-server-2008) - needs to be installed to be able to run this module. -seealso: -- module: win_region -author: -- Phil Schwartz (@schwartzmx) -''' - -EXAMPLES = r''' -- name: Set timezone to 'Romance Standard Time' (GMT+01:00) - win_timezone: - timezone: Romance Standard Time - -- name: Set timezone to 'GMT Standard Time' (GMT) - win_timezone: - timezone: GMT Standard Time - -- name: Set timezone to 'Central Standard Time' (GMT-06:00) - win_timezone: - timezone: Central Standard Time - -- name: Set timezime to Pacific Standard time and disable Daylight Saving time adjustments - win_timezone: - timezone: Pacific Standard Time_dstoff -''' - -RETURN = r''' -previous_timezone: - description: The previous timezone if it was changed, otherwise the existing timezone. - returned: success - type: str - sample: Central Standard Time -timezone: - description: The current timezone (possibly changed). - returned: success - type: str - sample: Central Standard Time -''' diff --git a/lib/ansible/modules/windows/win_toast.ps1 b/lib/ansible/modules/windows/win_toast.ps1 deleted file mode 100644 index e993651521f..00000000000 --- a/lib/ansible/modules/windows/win_toast.ps1 +++ /dev/null @@ -1,90 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Jon Hawkesworth (@jhawkesworth) -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" - -# version check -$osversion = [Environment]::OSVersion -$lowest_version = 10 -if ($osversion.Version.Major -lt $lowest_version ) { - Fail-Json -obj $result -message "Sorry, this version of windows, $osversion, does not support Toast notifications. Toast notifications are available from version $lowest_version" -} - -$stopwatch = [system.diagnostics.stopwatch]::startNew() -$now = [DateTime]::Now -$default_title = "Notification: " + $now.ToShortTimeString() - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$expire_seconds = Get-AnsibleParam -obj $params -name "expire" -type "int" -default 45 -$group = Get-AnsibleParam -obj $params -name "group" -type "str" -default "Powershell" -$msg = Get-AnsibleParam -obj $params -name "msg" -type "str" -default "Hello world!" -$popup = Get-AnsibleParam -obj $params -name "popup" -type "bool" -default $true -$tag = Get-AnsibleParam -obj $params -name "tag" -type "str" -default "Ansible" -$title = Get-AnsibleParam -obj $params -name "title" -type "str" -default $default_title - -$timespan = New-TimeSpan -Seconds $expire_seconds -$expire_at = $now + $timespan -$expire_at_utc = $($expire_at.ToUniversalTime()|Out-String).Trim() - -$result = @{ - changed = $false - expire_at = $expire_at.ToString() - expire_at_utc = $expire_at_utc - toast_sent = $false -} - -# If no logged in users, there is no notifications service, -# and no-one to read the message, so exit but do not fail -# if there are no logged in users to notify. - -if ((Get-Process -Name explorer -ErrorAction SilentlyContinue).Count -gt 0){ - - [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null - $template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText01) - - #Convert to .NET type for XML manipulation - $toastXml = [xml] $template.GetXml() - $toastXml.GetElementsByTagName("text").AppendChild($toastXml.CreateTextNode($title)) > $null - # TODO add subtitle - - #Convert back to WinRT type - $xml = New-Object Windows.Data.Xml.Dom.XmlDocument - $xml.LoadXml($toastXml.OuterXml) - - $toast = [Windows.UI.Notifications.ToastNotification]::new($xml) - $toast.Tag = $tag - $toast.Group = $group - $toast.ExpirationTime = $expire_at - $toast.SuppressPopup = -not $popup - - try { - $notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($msg) - if (-not $check_mode) { - $notifier.Show($toast) - $result.toast_sent = $true - Start-Sleep -Seconds $expire_seconds - } - } catch { - $excep = $_ - $result.exception = $excep.ScriptStackTrace - Fail-Json -obj $result -message "Failed to create toast notifier: $($excep.Exception.Message)" - } -} else { - $result.toast_sent = $false - $result.no_toast_sent_reason = 'No logged in users to notify' -} - -$endsend_at = Get-Date | Out-String -$stopwatch.Stop() - -$result.time_taken = $stopwatch.Elapsed.TotalSeconds -$result.sent_localtime = $endsend_at.Trim() - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_toast.py b/lib/ansible/modules/windows/win_toast.py deleted file mode 100644 index 5bb28c8ebb5..00000000000 --- a/lib/ansible/modules/windows/win_toast.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Jon Hawkesworth (@jhawkesworth) -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_toast -version_added: "2.4" -short_description: Sends Toast windows notification to logged in users on Windows 10 or later hosts -description: - - Sends alerts which appear in the Action Center area of the windows desktop. -options: - expire: - description: - - How long in seconds before the notification expires. - type: int - default: 45 - group: - description: - - Which notification group to add the notification to. - type: str - default: Powershell - msg: - description: - - The message to appear inside the notification. - - May include \n to format the message to appear within the Action Center. - type: str - default: Hello, World! - popup: - description: - - If C(no), the notification will not pop up and will only appear in the Action Center. - type: bool - default: yes - tag: - description: - - The tag to add to the notification. - type: str - default: Ansible - title: - description: - - The notification title, which appears in the pop up.. - type: str - default: Notification HH:mm -notes: - - This module must run on a windows 10 or Server 2016 host, so ensure your play targets windows hosts, or delegates to a windows host. - - The module does not fail if there are no logged in users to notify. - - Messages are only sent to the local host where the module is run. - - You must run this module with async, otherwise it will hang until the expire period has passed. -seealso: -- module: win_msg -- module: win_say -author: -- Jon Hawkesworth (@jhawkesworth) -''' - -EXAMPLES = r''' -- name: Warn logged in users of impending upgrade (note use of async to stop the module from waiting until notification expires). - win_toast: - expire: 60 - title: System Upgrade Notification - msg: Automated upgrade about to start. Please save your work and log off before {{ deployment_start_time }} - async: 60 - poll: 0 -''' - -RETURN = r''' -expire_at_utc: - description: Calculated utc date time when the notification expires. - returned: always - type: str - sample: 07 July 2017 04:50:54 -no_toast_sent_reason: - description: Text containing the reason why a notification was not sent. - returned: when no logged in users are detected - type: str - sample: No logged in users to notify -sent_localtime: - description: local date time when the notification was sent. - returned: always - type: str - sample: 07 July 2017 05:45:54 -time_taken: - description: How long the module took to run on the remote windows host in seconds. - returned: always - type: float - sample: 0.3706631999999997 -toast_sent: - description: Whether the module was able to send a toast notification or not. - returned: always - type: bool - sample: false -''' diff --git a/lib/ansible/modules/windows/win_unzip.ps1 b/lib/ansible/modules/windows/win_unzip.ps1 deleted file mode 100644 index b49e808845d..00000000000 --- a/lib/ansible/modules/windows/win_unzip.ps1 +++ /dev/null @@ -1,178 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Phil Schwartz -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -# TODO: This module is not idempotent (it will always unzip and report change) - -$ErrorActionPreference = "Stop" - -$pcx_extensions = @('.bz2', '.gz', '.msu', '.tar', '.zip') - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$src = Get-AnsibleParam -obj $params -name "src" -type "path" -failifempty $true -$dest = Get-AnsibleParam -obj $params -name "dest" -type "path" -failifempty $true -$creates = Get-AnsibleParam -obj $params -name "creates" -type "path" -$recurse = Get-AnsibleParam -obj $params -name "recurse" -type "bool" -default $false -$delete_archive = Get-AnsibleParam -obj $params -name "delete_archive" -type "bool" -default $false -aliases 'rm' - -# Fixes a fail error message (when the task actually succeeds) for a -# "Convert-ToJson: The converted JSON string is in bad format" -# This happens when JSON is parsing a string that ends with a "\", -# which is possible when specifying a directory to download to. -# This catches that possible error, before assigning the JSON $result -$result = @{ - changed = $false - dest = $dest -replace '\$','' - removed = $false - src = $src -replace '\$','' -} - -Function Extract-Zip($src, $dest) { - $archive = [System.IO.Compression.ZipFile]::Open($src, [System.IO.Compression.ZipArchiveMode]::Read, [System.Text.Encoding]::UTF8) - foreach ($entry in $archive.Entries) { - $archive_name = $entry.FullName - - $entry_target_path = [System.IO.Path]::Combine($dest, $archive_name) - $entry_dir = [System.IO.Path]::GetDirectoryName($entry_target_path) - - # Normalize paths for further evaluation - $full_target_path = [System.IO.Path]::GetFullPath($entry_target_path) - $full_dest_path = [System.IO.Path]::GetFullPath($dest + [System.IO.Path]::DirectorySeparatorChar) - - # Ensure file in the archive does not escape the extraction path - if (-not $full_target_path.StartsWith($full_dest_path)) { - Fail-Json -obj $result -message "Error unzipping '$src' to '$dest'! Filename contains relative paths which would extract outside the destination: $entry_target_path" - } - - if (-not (Test-Path -LiteralPath $entry_dir)) { - New-Item -Path $entry_dir -ItemType Directory -WhatIf:$check_mode | Out-Null - $result.changed = $true - } - - if ((-not ($entry_target_path.EndsWith("\") -or $entry_target_path.EndsWith("/"))) -and (-not $check_mode)) { - [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $entry_target_path, $true) - } - $result.changed = $true - } - $archive.Dispose() -} - -Function Extract-ZipLegacy($src, $dest) { - # [System.IO.Compression.ZipFile] was only added in .net 4.5, this is used - # when .net is older than that. - $shell = New-Object -ComObject Shell.Application - $zip = $shell.NameSpace([IO.Path]::GetFullPath($src)) - $dest_path = $shell.NameSpace([IO.Path]::GetFullPath($dest)) - - $shell = New-Object -ComObject Shell.Application - - if (-not $check_mode) { - # https://msdn.microsoft.com/en-us/library/windows/desktop/bb787866.aspx - # From Folder.CopyHere documentation, 1044 means: - # - 1024: do not display a user interface if an error occurs - # - 16: respond with "yes to all" for any dialog box that is displayed - # - 4: do not display a progress dialog box - $dest_path.CopyHere($zip.Items(), 1044) - } - $result.changed = $true -} - -If ($creates -and (Test-Path -LiteralPath $creates)) { - $result.skipped = $true - $result.msg = "The file or directory '$creates' already exists." - Exit-Json -obj $result -} - -If (-Not (Test-Path -LiteralPath $src)) { - Fail-Json -obj $result -message "File '$src' does not exist." -} - -$ext = [System.IO.Path]::GetExtension($src) - -If (-Not (Test-Path -LiteralPath $dest -PathType Container)){ - Try{ - New-Item -ItemType "directory" -path $dest -WhatIf:$check_mode | out-null - } Catch { - Fail-Json -obj $result -message "Error creating '$dest' directory! Msg: $($_.Exception.Message)" - } -} - -If ($ext -eq ".zip" -And $recurse -eq $false) { - # TODO: PS v5 supports zip extraction, use that if available - $use_legacy = $false - try { - # determines if .net 4.5 is available, if this fails we need to fall - # back to the legacy COM Shell.Application to extract the zip - Add-Type -AssemblyName System.IO.Compression.FileSystem | Out-Null - Add-Type -AssemblyName System.IO.Compression | Out-Null - } catch { - $use_legacy = $true - } - - if ($use_legacy) { - try { - Extract-ZipLegacy -src $src -dest $dest - } catch { - Fail-Json -obj $result -message "Error unzipping '$src' to '$dest'!. Method: COM Shell.Application, Exception: $($_.Exception.Message)" - } - } else { - try { - Extract-Zip -src $src -dest $dest - } catch { - Fail-Json -obj $result -message "Error unzipping '$src' to '$dest'!. Method: System.IO.Compression.ZipFile, Exception: $($_.Exception.Message)" - } - } -} Else { - # Check if PSCX is installed - $list = Get-Module -ListAvailable - - If (-Not ($list -match "PSCX")) { - Fail-Json -obj $result -message "PowerShellCommunityExtensions PowerShell Module (PSCX) is required for non-'.zip' compressed archive types." - } Else { - $result.pscx_status = "present" - } - - Try { - Import-Module PSCX - } - Catch { - Fail-Json $result "Error importing module PSCX" - } - - Try { - Expand-Archive -Path $src -OutputPath $dest -Force -WhatIf:$check_mode - } Catch { - Fail-Json -obj $result -message "Error expanding '$src' to '$dest'! Msg: $($_.Exception.Message)" - } - - If ($recurse) { - Get-ChildItem -LiteralPath $dest -recurse | Where-Object {$pcx_extensions -contains $_.extension} | ForEach-Object { - Try { - Expand-Archive $_.FullName -OutputPath $dest -Force -WhatIf:$check_mode - } Catch { - Fail-Json -obj $result -message "Error recursively expanding '$src' to '$dest'! Msg: $($_.Exception.Message)" - } - If ($delete_archive) { - Remove-Item -LiteralPath $_.FullName -Force -WhatIf:$check_mode - $result.removed = $true - } - } - } - - $result.changed = $true -} - -If ($delete_archive){ - try { - Remove-Item -LiteralPath $src -Recurse -Force -WhatIf:$check_mode - } catch { - Fail-Json -obj $result -message "failed to delete archive at '$src': $($_.Exception.Message)" - } - $result.removed = $true -} -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_unzip.py b/lib/ansible/modules/windows/win_unzip.py deleted file mode 100644 index 5830c61cd8b..00000000000 --- a/lib/ansible/modules/windows/win_unzip.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Phil Schwartz -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_unzip -version_added: "2.0" -short_description: Unzips compressed files and archives on the Windows node -description: -- Unzips compressed files and archives. -- Supports .zip files natively. -- Supports other formats supported by the Powershell Community Extensions (PSCX) module (basically everything 7zip supports). -- For non-Windows targets, use the M(unarchive) module instead. -requirements: -- PSCX -options: - src: - description: - - File to be unzipped (provide absolute path). - type: path - required: yes - dest: - description: - - Destination of zip file (provide absolute path of directory). If it does not exist, the directory will be created. - type: path - required: yes - delete_archive: - description: - - Remove the zip file, after unzipping. - type: bool - default: no - aliases: [ rm ] - recurse: - description: - - Recursively expand zipped files within the src file. - - Setting to a value of C(yes) requires the PSCX module to be installed. - type: bool - default: no - creates: - description: - - If this file or directory exists the specified src will not be extracted. - type: path -notes: -- This module is not really idempotent, it will extract the archive every time, and report a change. -- For extracting any compression types other than .zip, the PowerShellCommunityExtensions (PSCX) Module is required. This module (in conjunction with PSCX) - has the ability to recursively unzip files within the src zip file provided and also functionality for many other compression types. If the destination - directory does not exist, it will be created before unzipping the file. Specifying rm parameter will force removal of the src file after extraction. -seealso: -- module: unarchive -author: -- Phil Schwartz (@schwartzmx) -''' - -EXAMPLES = r''' -# This unzips a library that was downloaded with win_get_url, and removes the file after extraction -# $ ansible -i hosts -m win_unzip -a "src=C:\LibraryToUnzip.zip dest=C:\Lib remove=yes" all - -- name: Unzip a bz2 (BZip) file - win_unzip: - src: C:\Users\Phil\Logs.bz2 - dest: C:\Users\Phil\OldLogs - creates: C:\Users\Phil\OldLogs - -- name: Unzip gz log - win_unzip: - src: C:\Logs\application-error-logs.gz - dest: C:\ExtractedLogs\application-error-logs - -# Unzip .zip file, recursively decompresses the contained .gz files and removes all unneeded compressed files after completion. -- name: Unzip ApplicationLogs.zip and decompress all GZipped log files - hosts: all - gather_facts: no - tasks: - - name: Recursively decompress GZ files in ApplicationLogs.zip - win_unzip: - src: C:\Downloads\ApplicationLogs.zip - dest: C:\Application\Logs - recurse: yes - delete_archive: yes - -- name: Install PSCX - win_psmodule: - name: Pscx - state: present -''' - -RETURN = r''' -dest: - description: The provided destination path - returned: always - type: str - sample: C:\ExtractedLogs\application-error-logs -removed: - description: Whether the module did remove any files during task run - returned: always - type: bool - sample: true -src: - description: The provided source path - returned: always - type: str - sample: C:\Logs\application-error-logs.gz -''' diff --git a/lib/ansible/modules/windows/win_user_profile.ps1 b/lib/ansible/modules/windows/win_user_profile.ps1 deleted file mode 100644 index 111abf10efb..00000000000 --- a/lib/ansible/modules/windows/win_user_profile.ps1 +++ /dev/null @@ -1,163 +0,0 @@ -#!powershell - -# Copyright: (c) 2019, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic - -$spec = @{ - options = @{ - name = @{ type = "str" } - remove_multiple = @{ type = "bool"; default = $false } - state = @{ type = "str"; default = "present"; choices = @("absent", "present") } - username = @{ type = "sid"; } - } - required_if = @( - @("state", "present", @("username")), - @("state", "absent", @("name", "username"), $true) - ) - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) -$module.Result.path = $null - -$name = $module.Params.name -$remove_multiple = $module.Params.remove_multiple -$state = $module.Params.state -$username = $module.Params.username - -Add-CSharpType -AnsibleModule $module -References @' -using System; -using System.Runtime.InteropServices; -using System.Text; - -namespace Ansible.WinUserProfile -{ - public class NativeMethods - { - [DllImport("Userenv.dll", CharSet = CharSet.Unicode)] - public static extern int CreateProfile( - [MarshalAs(UnmanagedType.LPWStr)] string pszUserSid, - [MarshalAs(UnmanagedType.LPWStr)] string pszUserName, - [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszProfilePath, - UInt32 cchProfilePath); - - [DllImport("Userenv.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool DeleteProfileW( - [MarshalAs(UnmanagedType.LPWStr)] string lpSidString, - IntPtr lpProfile, - IntPtr lpComputerName); - - [DllImport("Userenv.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool GetProfilesDirectoryW( - [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpProfileDir, - ref UInt32 lpcchSize); - } -} -'@ - -Function Get-LastWin32ExceptionMessage { - param([int]$ErrorCode) - $exp = New-Object -TypeName System.ComponentModel.Win32Exception -ArgumentList $ErrorCode - $exp_msg = "{0} (Win32 ErrorCode {1} - 0x{1:X8})" -f $exp.Message, $ErrorCode - return $exp_msg -} - -Function Get-ExpectedProfilePath { - param([String]$BaseName) - - # Environment.GetFolderPath does not have an enumeration to get the base profile dir, use PInvoke instead - # and combine with the base name to return back to the user - best efforts - $profile_path_length = 0 - [Ansible.WinUserProfile.NativeMethods]::GetProfilesDirectoryW($null, - [ref]$profile_path_length) > $null - - $raw_profile_path = New-Object -TypeName System.Text.StringBuilder -ArgumentList $profile_path_length - $res = [Ansible.WinUserProfile.NativeMethods]::GetProfilesDirectoryW($raw_profile_path, - [ref]$profile_path_length) - - if ($res -eq $false) { - $msg = Get-LastWin32ExceptionMessage -Error ([System.Runtime.InteropServices.Marshal]::GetLastWin32Error()) - $module.FailJson("Failed to determine profile path with the base name '$BaseName': $msg") - } - $profile_path = Join-Path -Path $raw_profile_path.ToString() -ChildPath $BaseName - - return $profile_path -} - -$profiles = Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" - -if ($state -eq "absent") { - if ($null -ne $username) { - $user_profiles = $profiles | Where-Object { $_.PSChildName -eq $username.Value } - } else { - # If the username was not provided, or we are removing a profile for a deleted user, we need to try and find - # the correct SID to delete. We just verify that the path matches based on the name passed in - $expected_profile_path = Get-ExpectedProfilePath -BaseName $name - - $user_profiles = $profiles | Where-Object { - $profile_path = (Get-ItemProperty -Path $_.PSPath -Name ProfileImagePath).ProfileImagePath - $profile_path -eq $expected_profile_path - } - - if ($user_profiles.Length -gt 1 -and -not $remove_multiple) { - $module.FailJson("Found multiple profiles matching the path '$expected_profile_path', set 'remove_multiple=True' to remove all the profiles for this match") - } - } - - foreach ($user_profile in $user_profiles) { - $profile_path = (Get-ItemProperty -Path $user_profile.PSPath -Name ProfileImagePath).ProfileImagePath - if (-not $module.CheckMode) { - $res = [Ansible.WinUserProfile.NativeMethods]::DeleteProfileW($user_profile.PSChildName, [IntPtr]::Zero, - [IntPtr]::Zero) - if ($res -eq $false) { - $msg = Get-LastWin32ExceptionMessage -Error ([System.Runtime.InteropServices.Marshal]::GetLastWin32Error()) - $module.FailJson("Failed to delete the profile for $($user_profile.PSChildName): $msg") - } - } - - # While we may have multiple profiles when the name option was used, it will always be the same path due to - # how we match name to a profile so setting it mutliple time sis fine - $module.Result.path = $profile_path - $module.Result.changed = $true - } -} elseif ($state -eq "present") { - # Now we know the SID, see if the profile already exists - $user_profile = $profiles | Where-Object { $_.PSChildName -eq $username.Value } - if ($null -eq $user_profile) { - # In case a SID was set as the username we still need to make sure the SID is mapped to a valid local account - try { - $account_name = $username.Translate([System.Security.Principal.NTAccount]) - } catch [System.Security.Principal.IdentityNotMappedException] { - $module.FailJson("Fail to map the account '$($username.Value)' to a valid user") - } - - # If the basename was not provided, determine it from the actual username - if ($null -eq $name) { - $name = $account_name.Value.Split('\', 2)[-1] - } - - if ($module.CheckMode) { - $profile_path = Get-ExpectedProfilePath -BaseName $name - } else { - $raw_profile_path = New-Object -TypeName System.Text.StringBuilder -ArgumentList 260 - $res = [Ansible.WinUserProfile.NativeMethods]::CreateProfile($username.Value, $name, $raw_profile_path, - $raw_profile_path.Capacity) - - if ($res -ne 0) { - $exp = [System.Runtime.InteropServices.Marshal]::GetExceptionForHR($res) - $module.FailJson("Failed to create profile for user '$username': $($exp.Message)") - } - $profile_path = $raw_profile_path.ToString() - } - - $module.Result.changed = $true - $module.Result.path = $profile_path - } else { - $module.Result.path = (Get-ItemProperty -Path $user_profile.PSPath -Name ProfileImagePath).ProfileImagePath - } -} - -$module.ExitJson() - diff --git a/lib/ansible/modules/windows/win_user_profile.py b/lib/ansible/modules/windows/win_user_profile.py deleted file mode 100644 index 264392488c6..00000000000 --- a/lib/ansible/modules/windows/win_user_profile.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2019, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_user_profile -version_added: '2.8' -short_description: Manages the Windows user profiles. -description: -- Used to create or remove user profiles on a Windows host. -- This can be used to create a profile before a user logs on or delete a - profile when removing a user account. -- A profile can be created for both a local or domain account. -options: - name: - description: - - Specifies the base name for the profile path. - - When I(state) is C(present) this is used to create the profile for - I(username) at a specific path within the profile directory. - - This cannot be used to specify a path outside of the profile directory - but rather it specifies a folder(s) within this directory. - - If a profile for another user already exists at the same path, then a 3 - digit incremental number is appended by Windows automatically. - - When I(state) is C(absent) and I(username) is not set, then the module - will remove all profiles that point to the profile path derived by this - value. - - This is useful if the account no longer exists but the profile still - remains. - type: str - remove_multiple: - description: - - When I(state) is C(absent) and the value for I(name) matches multiple - profiles the module will fail. - - Set this value to C(yes) to force the module to delete all the profiles - found. - default: no - type: bool - state: - description: - - Will ensure the profile exists when set to C(present). - - When creating a profile the I(username) option must be set to a valid - account. - - Will remove the profile(s) when set to C(absent). - - When removing a profile either I(username) must be set to a valid - account, or I(name) is set to the profile's base name. - default: present - choices: - - absent - - present - type: str - username: - description: - - The account name of security identifier (SID) for the profile. - - This must be set when I(state) is C(present) and must be a valid account - or the SID of a valid account. - - When I(state) is C(absent) then this must still be a valid account number - but the SID can be a deleted user's SID. -seealso: -- module: win_user -- module: win_domain_user -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Create a profile for an account - win_user_profile: - username: ansible-account - state: present - -- name: Create a profile for an account at C:\Users\ansible - win_user_profile: - username: ansible-account - name: ansible - state: present - -- name: Remove a profile for a still valid account - win_user_profile: - username: ansible-account - state: absent - -- name: Remove a profile for a deleted account - win_user_profile: - name: ansible - state: absent - -- name: Remove a profile for a deleted account based on the SID - win_user_profile: - username: S-1-5-21-3233007181-2234767541-1895602582-1305 - state: absent - -- name: Remove multiple profiles that exist at the basename path - win_user_profile: - name: ansible - state: absent - remove_multiple: yes -''' - -RETURN = r''' -path: - description: The full path to the profile for the account. This will be null - if C(state=absent) and no profile was deleted. - returned: always - type: str - sample: C:\Users\ansible -''' diff --git a/lib/ansible/modules/windows/win_wait_for_process.ps1 b/lib/ansible/modules/windows/win_wait_for_process.ps1 deleted file mode 100644 index 70ff4bbba40..00000000000 --- a/lib/ansible/modules/windows/win_wait_for_process.ps1 +++ /dev/null @@ -1,176 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Ansible Project -# Copyright: (c) 2018, Dag Wieers (@dagwieers) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.SID - -$spec = @{ - options = @{ - process_name_exact = @{ type='list' } - process_name_pattern = @{ type='str' } - pid = @{ type='int'; default=0 } - owner = @{ type='str' } - sleep = @{ type='int'; default=1 } - pre_wait_delay = @{ type='int'; default=0 } - post_wait_delay = @{ type='int'; default=0 } - process_min_count = @{ type='int'; default=1 } - state = @{ type='str'; default='present'; choices=@( 'absent', 'present' ) } - timeout = @{ type='int'; default=300 } - } - mutually_exclusive = @( - @( 'pid', 'process_name_exact' ), - @( 'pid', 'process_name_pattern' ), - @( 'process_name_exact', 'process_name_pattern' ) - ) - required_one_of = @( - ,@( 'owner', 'pid', 'process_name_exact', 'process_name_pattern' ) - ) - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$process_name_exact = $module.Params.process_name_exact -$process_name_pattern = $module.Params.process_name_pattern -$process_id = $module.Params.pid # pid is a reserved variable in PowerShell, using process_id instead -$owner = $module.Params.owner -$sleep = $module.Params.sleep -$pre_wait_delay = $module.Params.pre_wait_delay -$post_wait_delay = $module.Params.post_wait_delay -$process_min_count = $module.Params.process_min_count -$state = $module.Params.state -$timeout = $module.Params.timeout - -$module.Result.changed = $false -$module.Result.elapsed = 0 -$module.Result.matched_processes = @() - -# Validate the input -if ($state -eq "absent" -and $sleep -ne 1) { - $module.Warn("Parameter 'sleep' has no effect when waiting for a process to stop.") -} - -if ($state -eq "absent" -and $process_min_count -ne 1) { - $module.Warn("Parameter 'process_min_count' has no effect when waiting for a process to stop.") -} - -if ($owner -and ("IncludeUserName" -notin (Get-Command -Name Get-Process).Parameters.Keys)) { - $module.FailJson("This version of Powershell does not support filtering processes by 'owner'.") -} - -Function Get-FilteredProcesses { - [cmdletbinding()] - Param( - [String] - $Owner, - $ProcessNameExact, - $ProcessNamePattern, - [int] - $ProcessId - ) - - $FilteredProcesses = @() - - try { - $Processes = Get-Process -IncludeUserName - $SupportsUserNames = $true - } catch [System.Management.Automation.ParameterBindingException] { - $Processes = Get-Process - $SupportsUserNames = $false - } - - foreach ($Process in $Processes) { - - # If a process name was specified in the filter, validate that here. - if ($ProcessNamePattern) { - if ($Process.ProcessName -notmatch $ProcessNamePattern) { - continue - } - } - - # If a process name was specified in the filter, validate that here. - if ($ProcessNameExact -is [Array]) { - if ($ProcessNameExact -notcontains $Process.ProcessName) { - continue - } - } elseif ($ProcessNameExact) { - if ($ProcessNameExact -ne $Process.ProcessName) { - continue - } - } - - # If a PID was specified in the filter, validate that here. - if ($ProcessId -and $ProcessId -ne 0) { - if ($ProcessId -ne $Process.Id) { - continue - } - } - - # If an owner was specified in the filter, validate that here. - if ($Owner) { - if (-not $Process.UserName) { - continue - } elseif ((Convert-ToSID($Owner)) -ne (Convert-ToSID($Process.UserName))) { # NOTE: This is rather expensive - continue - } - } - - if ($SupportsUserNames -eq $true) { - $FilteredProcesses += @{ name = $Process.ProcessName; pid = $Process.Id; owner = $Process.UserName } - } else { - $FilteredProcesses += @{ name = $Process.ProcessName; pid = $Process.Id } - } - } - - return ,$FilteredProcesses -} - -$module_start = Get-Date -Start-Sleep -Seconds $pre_wait_delay - -if ($state -eq "present" ) { - - # Wait for a process to start - do { - - $Processes = Get-FilteredProcesses -Owner $owner -ProcessNameExact $process_name_exact -ProcessNamePattern $process_name_pattern -ProcessId $process_id - $module.Result.matched_processes = $Processes - - if ($Processes.count -ge $process_min_count) { - break - } - - if (((Get-Date) - $module_start).TotalSeconds -gt $timeout) { - $module.Result.elapsed = ((Get-Date) - $module_start).TotalSeconds - $module.FailJson("Timed out while waiting for process(es) to start") - } - - Start-Sleep -Seconds $sleep - - } while ($true) - -} elseif ($state -eq "absent") { - - # Wait for a process to stop - $Processes = Get-FilteredProcesses -Owner $owner -ProcessNameExact $process_name_exact -ProcessNamePattern $process_name_pattern -ProcessId $process_id - $module.Result.matched_processes = $Processes - - if ($Processes.count -gt 0 ) { - try { - # This may randomly fail when used on specially protected processes (think: svchost) - Wait-Process -Id $Processes.pid -Timeout $timeout - } catch [System.TimeoutException] { - $module.Result.elapsed = ((Get-Date) - $module_start).TotalSeconds - $module.FailJson("Timeout while waiting for process(es) to stop") - } - } - -} - -Start-Sleep -Seconds $post_wait_delay -$module.Result.elapsed = ((Get-Date) - $module_start).TotalSeconds - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_wait_for_process.py b/lib/ansible/modules/windows/win_wait_for_process.py deleted file mode 100644 index a26e2be5fe3..00000000000 --- a/lib/ansible/modules/windows/win_wait_for_process.py +++ /dev/null @@ -1,134 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub, actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_wait_for_process -version_added: '2.7' -short_description: Waits for a process to exist or not exist before continuing. -description: -- Waiting for a process to start or stop. -- This is useful when Windows services behave poorly and do not enumerate external dependencies in their manifest. -options: - process_name_exact: - description: - - The name of the process(es) for which to wait. The name of the process(es) should not include the file extension suffix. - type: list - process_name_pattern: - description: - - RegEx pattern matching desired process(es). - type: str - sleep: - description: - - Number of seconds to sleep between checks. - - Only applies when waiting for a process to start. Waiting for a process to start - does not have a native non-polling mechanism. Waiting for a stop uses native PowerShell - and does not require polling. - type: int - default: 1 - process_min_count: - description: - - Minimum number of process matching the supplied pattern to satisfy C(present) condition. - - Only applies to C(present). - type: int - default: 1 - pid: - description: - - The PID of the process. - type: int - owner: - description: - - The owner of the process. - - Requires PowerShell version 4.0 or newer. - type: str - pre_wait_delay: - description: - - Seconds to wait before checking processes. - type: int - default: 0 - post_wait_delay: - description: - - Seconds to wait after checking for processes. - type: int - default: 0 - state: - description: - - When checking for a running process C(present) will block execution - until the process exists, or until the timeout has been reached. - C(absent) will block execution until the process no longer exists, - or until the timeout has been reached. - - When waiting for C(present), the module will return changed only if - the process was not present on the initial check but became present on - subsequent checks. - - If, while waiting for C(absent), new processes matching the supplied - pattern are started, these new processes will not be included in the - action. - type: str - default: present - choices: [ absent, present ] - timeout: - description: - - The maximum number of seconds to wait for a for a process to start or stop - before erroring out. - type: int - default: 300 -seealso: -- module: wait_for -- module: win_wait_for -author: -- Charles Crossan (@crossan007) -''' - -EXAMPLES = r''' -- name: Wait 300 seconds for all Oracle VirtualBox processes to stop. (VBoxHeadless, VirtualBox, VBoxSVC) - win_wait_for_process: - process_name_pattern: 'v(irtual)?box(headless|svc)?' - state: absent - timeout: 500 - -- name: Wait 300 seconds for 3 instances of cmd to start, waiting 5 seconds between each check - win_wait_for_process: - process_name_exact: cmd - state: present - timeout: 500 - sleep: 5 - process_min_count: 3 -''' - -RETURN = r''' -elapsed: - description: The elapsed seconds between the start of poll and the end of the module. - returned: always - type: float - sample: 3.14159265 -matched_processes: - description: List of matched processes (either stopped or started). - returned: always - type: complex - contains: - name: - description: The name of the matched process. - returned: always - type: str - sample: svchost - owner: - description: The owner of the matched process. - returned: when supported by PowerShell - type: str - sample: NT AUTHORITY\SYSTEM - pid: - description: The PID of the matched process. - returned: always - type: int - sample: 7908 -''' diff --git a/lib/ansible/modules/windows/win_wakeonlan.ps1 b/lib/ansible/modules/windows/win_wakeonlan.ps1 deleted file mode 100644 index f14889534d9..00000000000 --- a/lib/ansible/modules/windows/win_wakeonlan.ps1 +++ /dev/null @@ -1,52 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Dag Wieers (@dagwieers) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic - -$spec = @{ - options = @{ - mac = @{ type='str'; required=$true } - broadcast = @{ type='str'; default='255.255.255.255' } - port = @{ type='int'; default=7 } - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$module.Result.changed = $false - -$mac = $module.Params.mac -$mac_orig = $module.Params.mac -$broadcast = $module.Params.broadcast -$port = $module.Params.port - -$broadcast = [Net.IPAddress]::Parse($broadcast) - -# Remove possible separator from MAC address -if ($mac.Length -eq (12 + 5)) { - $mac = $mac.Replace($mac.Substring(2, 1), "") -} - -# If we don't end up with 12 hexadecimal characters, fail -if ($mac.Length -ne 12) { - $module.FailJson("Incorrect MAC address: $mac_orig") -} - -# Create payload for magic packet -# TODO: Catch possible conversion errors -$target = 0,2,4,6,8,10 | ForEach-Object { [convert]::ToByte($mac.Substring($_, 2), 16) } -$data = (,[byte]255 * 6) + ($target * 20) - -# Broadcast payload to network -$udpclient = new-Object System.Net.Sockets.UdpClient -if (-not $module.CheckMode) { - $udpclient.Connect($broadcast, $port) - [void] $udpclient.Send($data, 102) -} - -$module.Result.changed = $true - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_wakeonlan.py b/lib/ansible/modules/windows/win_wakeonlan.py deleted file mode 100644 index 60439624af8..00000000000 --- a/lib/ansible/modules/windows/win_wakeonlan.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Dag Wieers -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_wakeonlan -version_added: '2.4' -short_description: Send a magic Wake-on-LAN (WoL) broadcast packet -description: -- The C(win_wakeonlan) module sends magic Wake-on-LAN (WoL) broadcast packets. -- For non-Windows targets, use the M(wakeonlan) module instead. -options: - mac: - description: - - MAC address to send Wake-on-LAN broadcast packet for. - type: str - required: yes - broadcast: - description: - - Network broadcast address to use for broadcasting magic Wake-on-LAN packet. - type: str - default: 255.255.255.255 - port: - description: - - UDP port to use for magic Wake-on-LAN packet. - type: int - default: 7 -todo: -- Does not have SecureOn password support -notes: -- This module sends a magic packet, without knowing whether it worked. It always report a change. -- Only works if the target system was properly configured for Wake-on-LAN (in the BIOS and/or the OS). -- Some BIOSes have a different (configurable) Wake-on-LAN boot order (i.e. PXE first). -seealso: -- module: wakeonlan -author: -- Dag Wieers (@dagwieers) -''' - -EXAMPLES = r''' -- name: Send a magic Wake-on-LAN packet to 00:00:5E:00:53:66 - win_wakeonlan: - mac: 00:00:5E:00:53:66 - broadcast: 192.0.2.23 - -- name: Send a magic Wake-On-LAN packet on port 9 to 00-00-5E-00-53-66 - win_wakeonlan: - mac: 00-00-5E-00-53-66 - port: 9 - delegate_to: remote_system -''' - -RETURN = r''' -# Default return values -''' diff --git a/lib/ansible/modules/windows/win_webpicmd.ps1 b/lib/ansible/modules/windows/win_webpicmd.ps1 deleted file mode 100644 index c2d1b7ca716..00000000000 --- a/lib/ansible/modules/windows/win_webpicmd.ps1 +++ /dev/null @@ -1,116 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Peter Mounce -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" - -Function Find-Command -{ - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, Position=0)] [string] $command - ) - $installed = get-command $command -erroraction Ignore - write-verbose "$installed" - if ($installed) - { - return $installed - } - return $null -} - -Function Find-WebPiCmd -{ - [CmdletBinding()] - param() - $p = Find-Command "webpicmd.exe" - if ($null -ne $p) - { - return $p - } - $a = Find-Command "c:\programdata\chocolatey\bin\webpicmd.exe" - if ($null -ne $a) - { - return $a - } - Throw "webpicmd.exe is not installed. It must be installed (use chocolatey)" -} - -Function Test-IsInstalledFromWebPI -{ - [CmdletBinding()] - - param( - [Parameter(Mandatory=$true, Position=0)] - [string]$package - ) - - $cmd = "$executable /list /listoption:installed" - $results = invoke-expression $cmd - - if ($LastExitCode -ne 0) - { - $result.webpicmd_error_cmd = $cmd - $result.webpicmd_error_log = "$results" - - Throw "Error checking installation status for $package" - } - Write-Verbose "$results" - - if ($results -match "^$package\s+") - { - return $true - } - - return $false -} - -Function Install-WithWebPICmd -{ - [CmdletBinding()] - - param( - [Parameter(Mandatory=$true, Position=0)] - [string]$package - ) - - $cmd = "$executable /install /products:$package /accepteula /suppressreboot" - - $results = invoke-expression $cmd - - if ($LastExitCode -ne 0) - { - $result.webpicmd_error_cmd = $cmd - $result.webpicmd_error_log = "$results" - Throw "Error installing $package" - } - - write-verbose "$results" - - if ($results -match "Install of Products: SUCCESS") - { - $result.changed = $true - } -} - -$result = @{ - changed = $false -} - -$params = Parse-Args $args - -$package = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true - -Try { - $script:executable = Find-WebPiCmd - if ((Test-IsInstalledFromWebPI -package $package) -eq $false) { - Install-WithWebPICmd -package $package - } - - Exit-Json $result -} Catch { - Fail-Json $result $_.Exception.Message -} diff --git a/lib/ansible/modules/windows/win_webpicmd.py b/lib/ansible/modules/windows/win_webpicmd.py deleted file mode 100644 index fc0663b304d..00000000000 --- a/lib/ansible/modules/windows/win_webpicmd.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Peter Mounce -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_webpicmd -version_added: "2.0" -short_description: Installs packages using Web Platform Installer command-line -description: - - Installs packages using Web Platform Installer command-line - (U(http://www.iis.net/learn/install/web-platform-installer/web-platform-installer-v4-command-line-webpicmdexe-rtw-release)). - - Must be installed and present in PATH (see M(win_chocolatey) module; 'webpicmd' is the package name, and you must install 'lessmsi' first too)? - - Install IIS first (see M(win_feature) module). -notes: - - Accepts EULAs and suppresses reboot - you will need to check manage reboots yourself (see M(win_reboot) module) -options: - name: - description: - - Name of the package to be installed. - type: str - required: yes -seealso: -- module: win_package -author: -- Peter Mounce (@petemounce) -''' - -EXAMPLES = r''' -- name: Install URLRewrite2. - win_webpicmd: - name: URLRewrite2 -''' diff --git a/lib/ansible/modules/windows/win_xml.ps1 b/lib/ansible/modules/windows/win_xml.ps1 deleted file mode 100644 index d051a3f67dc..00000000000 --- a/lib/ansible/modules/windows/win_xml.ps1 +++ /dev/null @@ -1,265 +0,0 @@ -#!powershell - -# Copyright: (c) 2018, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.Backup - -Set-StrictMode -Version 2 - -function Copy-Xml($dest, $src, $xmlorig) { - if ($src.get_NodeType() -eq "Text") { - $dest.set_InnerText($src.get_InnerText()) - } - - if ($src.get_HasAttributes()) { - foreach ($attr in $src.get_Attributes()) { - $dest.SetAttribute($attr.get_Name(), $attr.get_Value()) - } - } - - if ($src.get_HasChildNodes()) { - foreach ($childnode in $src.get_ChildNodes()) { - if ($childnode.get_NodeType() -eq "Element") { - $newnode = $xmlorig.CreateElement($childnode.get_Name(), $xmlorig.get_DocumentElement().get_NamespaceURI()) - Copy-Xml -dest $newnode -src $childnode -xmlorig $xmlorig - $dest.AppendChild($newnode) | Out-Null - } elseif ($childnode.get_NodeType() -eq "Text") { - $dest.set_InnerText($childnode.get_InnerText()) - } - } - } -} - -function Compare-XmlDocs($actual, $expected) { - if ($actual.get_Name() -ne $expected.get_Name()) { - throw "Actual name not same as expected: actual=" + $actual.get_Name() + ", expected=" + $expected.get_Name() - } - ##attributes... - - if (($actual.get_NodeType() -eq "Element") -and ($expected.get_NodeType() -eq "Element")) { - if ($actual.get_HasAttributes() -and $expected.get_HasAttributes()) { - if ($actual.get_Attributes().Count -ne $expected.get_Attributes().Count) { - throw "attribute mismatch for actual=" + $actual.get_Name() - } - for ($i=0;$i -lt $expected.get_Attributes().Count; $i =$i+1) { - if ($expected.get_Attributes()[$i].get_Name() -ne $actual.get_Attributes()[$i].get_Name()) { - throw "attribute name mismatch for actual=" + $actual.get_Name() - } - if ($expected.get_Attributes()[$i].get_Value() -ne $actual.get_Attributes()[$i].get_Value()) { - throw "attribute value mismatch for actual=" + $actual.get_Name() - } - } - } - - if (($actual.get_HasAttributes() -and !$expected.get_HasAttributes()) -or (!$actual.get_HasAttributes() -and $expected.get_HasAttributes())) { - throw "attribute presence mismatch for actual=" + $actual.get_Name() - } - } - - ##children - if ($expected.get_ChildNodes().Count -ne $actual.get_ChildNodes().Count) { - throw "child node mismatch. for actual=" + $actual.get_Name() - } - - for ($i=0;$i -lt $expected.get_ChildNodes().Count; $i =$i+1) { - if (-not $actual.get_ChildNodes()[$i]) { - throw "actual missing child nodes. for actual=" + $actual.get_Name() - } - Compare-XmlDocs $expected.get_ChildNodes()[$i] $actual.get_ChildNodes()[$i] - } - - if ($expected.get_InnerText()) { - if ($expected.get_InnerText() -ne $actual.get_InnerText()) { - throw "inner text mismatch for actual=" + $actual.get_Name() - } - } - elseif ($actual.get_InnerText()) { - throw "actual has inner text but expected does not for actual=" + $actual.get_Name() - } -} - - -function Save-ChangedXml($xmlorig, $result, $message, $check_mode, $backup) { - $result.changed = $true - if (-Not $check_mode) { - if ($backup) { - $result.backup_file = Backup-File -path $dest -WhatIf:$check_mode - # Ensure backward compatibility (deprecate in future) - $result.backup = $result.backup_file - } - $xmlorig.Save($dest) - $result.msg = $message - } else { - $result.msg += " check mode" - } -} - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$debug_level = Get-AnsibleParam -obj $params -name "_ansible_verbosity" -type "int" -$debug = $debug_level -gt 2 - -$dest = Get-AnsibleParam $params "path" -type "path" -FailIfEmpty $true -aliases "dest", "file" -$fragment = Get-AnsibleParam $params "fragment" -type "str" -aliases "xmlstring" -$xpath = Get-AnsibleParam $params "xpath" -type "str" -FailIfEmpty $true -$backup = Get-AnsibleParam $params "backup" -type "bool" -Default $false -$type = Get-AnsibleParam $params "type" -type "str" -Default "element" -ValidateSet "element", "attribute", "text" -$attribute = Get-AnsibleParam $params "attribute" -type "str" -FailIfEmpty ($type -eq "attribute") -$state = Get-AnsibleParam $params "state" -type "str" -Default "present" -$count = Get-AnsibleParam $params "count" -type "bool" -Default $false - -$result = @{ - changed = $false -} - -If (-Not (Test-Path -Path $dest -PathType Leaf)){ - Fail-Json $result "Specified path $dest does not exist or is not a file." -} - -$xmlorig = New-Object -TypeName System.Xml.XmlDocument -$xmlorig.XmlResolver = $null -Try { - $xmlorig.Load($dest) -} -Catch { - Fail-Json $result "Failed to parse file at '$dest' as an XML document: $($_.Exception.Message)" -} - -$namespaceMgr = New-Object System.Xml.XmlNamespaceManager $xmlorig.NameTable -$namespace = $xmlorig.DocumentElement.NamespaceURI -$localname = $xmlorig.DocumentElement.LocalName - -$namespaceMgr.AddNamespace($xmlorig.$localname.SchemaInfo.Prefix, $namespace) - -$nodeList = $xmlorig.SelectNodes($xpath, $namespaceMgr) -$nodeListCount = $nodeList.get_Count() -if ($count) { - $result.count = $nodeListCount - if (-not $fragment) { - Exit-Json $result - } -} -## Exit early if xpath did not match any nodes -if ($nodeListCount -eq 0) { - $result.msg = "The supplied xpath did not match any nodes. If this is unexpected, check your xpath is valid for the xml file at supplied path." - Exit-Json $result -} - -$changed = $false -$result.msg = "not changed" - -if ($type -eq "element") { - if ($state -eq "absent") { - foreach ($node in $nodeList) { - # there are some nodes that match xpath, delete without comparing them to fragment - if (-Not $check_mode) { - $removedNode = $node.get_ParentNode().RemoveChild($node) - $changed = $true - if ($debug) { - $result.removed += $result.removed + $removedNode.get_OuterXml() - } - } - } - } else { # state -eq 'present' - $xmlfragment = $null - Try { - $xmlfragment = [xml]$fragment - } Catch { - Fail-Json $result "Failed to parse fragment as XML: $($_.Exception.Message)" - } - - foreach ($node in $nodeList) { - $candidate = $xmlorig.CreateElement($xmlfragment.get_DocumentElement().get_Name(), $xmlorig.get_DocumentElement().get_NamespaceURI()) - Copy-Xml -dest $candidate -src $xmlfragment.DocumentElement -xmlorig $xmlorig - - if ($node.get_NodeType() -eq "Document") { - $node = $node.get_DocumentElement() - } - $elements = $node.get_ChildNodes() - [bool]$present = $false - [bool]$changed = $false - $element_count = $elements.get_Count() - $nstatus = "node: " + $node.get_Value() + " element: " + $elements.get_OuterXml() + " Element count is $element_count" - Add-Warning $result $nstatus - if ($elements.get_Count()) { - if ($debug) { - $err = @() - $result.err = {$err}.Invoke() - } - foreach ($element in $elements) { - $estatus = "element is " + $element.get_OuterXml() - Add-Warning $result $estatus - try { - Compare-XmlDocs $candidate $element - $present = $true - break - } catch { - if ($debug) { - $result.err.Add($_.Exception.ToString()) - } - } - } - if (-Not $present -and ($state -eq "present")) { - [void]$node.AppendChild($candidate) - $result.msg = $result.msg + "xml added " - $changed = $true - } - } - } - } -} elseif ($type -eq "text") { - foreach ($node in $nodeList) { - if ($node.get_InnerText() -ne $fragment) { - $node.set_InnerText($fragment) - $changed = $true - } - } -} elseif ($type -eq "attribute") { - foreach ($node in $nodeList) { - if ($state -eq 'present') { - if ($node.NodeType -eq 'Attribute') { - if ($node.Name -eq $attribute -and $node.Value -ne $fragment ) { - # this is already the attribute with the right name, so just set its value to match fragment - $node.Value = $fragment - $changed = $true - } - } else { # assume NodeType is Element - if ($node.$attribute -ne $fragment) { - if (!$node.HasAttribute($attribute)) { # add attribute to Element if missing - $node.SetAttributeNode($attribute, $xmlorig.get_DocumentElement().get_NamespaceURI()) - } - #set the attribute into the element - $node.SetAttribute($attribute, $fragment) - $changed = $true - } - } - } elseif ($state -eq 'absent') { - if ($node.NodeType -eq 'Attribute') { - $attrNode = [System.Xml.XmlAttribute]$node - $parent = $attrNode.OwnerElement - $parent.RemoveAttribute($attribute) - $changed = $true - } else { # element node processing - if ($node.Name -eq $attribute ) { # note not caring about the state of 'fragment' at this point - $node.RemoveAttribute($attribute) - $changed = $true - } - } - } else { - Add-Warning $result "Unexpected state when processing attribute $($attribute), add was $add, state was $state" - } - } -} -if ($changed) { - if ($state -eq "absent") { - $summary = "$type removed" - } else { - $summary = "$type changed" - } - Save-ChangedXml -xmlorig $xmlorig -result $result -message $summary -check_mode $check_mode -backup $backup -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_xml.py b/lib/ansible/modules/windows/win_xml.py deleted file mode 100644 index a503df81d88..00000000000 --- a/lib/ansible/modules/windows/win_xml.py +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_xml -version_added: "2.7" -short_description: Manages XML file content on Windows hosts -description: - - Manages XML nodes, attributes and text, using xpath to select which xml nodes need to be managed. - - XML fragments, formatted as strings, are used to specify the desired state of a part or parts of XML files on remote Windows servers. - - For non-Windows targets, use the M(xml) module instead. -options: - attribute: - description: - - The attribute name if the type is 'attribute'. - - Required if C(type=attribute). - type: str - count: - description: - - When set to C(yes), return the number of nodes matched by I(xpath). - type: bool - default: false - version_added: 2.9 - backup: - description: - - Determine whether a backup should be created. - - When set to C(yes), create a backup file including the timestamp information - so you can get the original file back if you somehow clobbered it incorrectly. - type: bool - default: no - fragment: - description: - - The string representation of the XML fragment expected at xpath. Since ansible 2.9 not required when I(state=absent), or when I(count=yes). - type: str - required: false - aliases: [ xmlstring ] - path: - description: - - Path to the file to operate on. - type: path - required: true - aliases: [ dest, file ] - state: - description: - - Set or remove the nodes (or attributes) matched by I(xpath). - type: str - default: present - choices: [ present, absent ] - version_added: 2.9 - type: - description: - - The type of XML node you are working with. - type: str - required: yes - default: element - choices: [ attribute, element, text ] - xpath: - description: - - Xpath to select the node or nodes to operate on. - type: str - required: true -author: - - Richard Levenberg (@richardcs) - - Jon Hawkesworth (@jhawkesworth) -notes: - - Only supports operating on xml elements, attributes and text. - - Namespace, processing-instruction, command and document node types cannot be modified with this module. -seealso: - - module: xml - description: XML manipulation for Posix hosts. - - name: w3shools XPath tutorial - description: A useful tutorial on XPath - link: https://www.w3schools.com/xml/xpath_intro.asp -''' - -EXAMPLES = r''' -- name: Apply our filter to Tomcat web.xml - win_xml: - path: C:\apache-tomcat\webapps\myapp\WEB-INF\web.xml - fragment: 'MyFiltercom.example.MyFilter' - xpath: '/*' - -- name: Apply sslEnabledProtocols to Tomcat's server.xml - win_xml: - path: C:\Tomcat\conf\server.xml - xpath: '//Server/Service[@name="Catalina"]/Connector[@port="9443"]' - attribute: 'sslEnabledProtocols' - fragment: 'TLSv1,TLSv1.1,TLSv1.2' - type: attribute - -- name: remove debug configuration nodes from nlog.conf - win_xml: - path: C:\IISApplication\nlog.conf - xpath: /nlog/rules/logger[@name="debug"]/descendant::* - state: absent - -- name: count configured connectors in Tomcat's server.xml - win_xml: - path: C:\Tomcat\conf\server.xml - xpath: //Server/Service/Connector - count: yes - register: connector_count - -- name: show connector count - debug: - msg="Connector count is {{connector_count.count}}" - -- name: ensure all lang=en attributes to lang=nl - win_xml: - path: C:\Data\Books.xml - xpath: //@[lang="en"] - attribute: lang - fragment: nl - type: attribute - -''' - -RETURN = r''' -backup_file: - description: Name of the backup file that was created. - returned: if backup=yes - type: str - sample: C:\Path\To\File.txt.11540.20150212-220915.bak -count: - description: Number of nodes matched by xpath. - returned: if count=yes - type: int - sample: 33 -msg: - description: What was done. - returned: always - type: str - sample: "xml added" -err: - description: XML comparison exceptions. - returned: always, for type element and -vvv or more - type: list - sample: attribute mismatch for actual=string -''' diff --git a/lib/ansible/plugins/lookup/laps_password.py b/lib/ansible/plugins/lookup/laps_password.py deleted file mode 100644 index f48e76a06c7..00000000000 --- a/lib/ansible/plugins/lookup/laps_password.py +++ /dev/null @@ -1,358 +0,0 @@ -# (c) 2019 Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -DOCUMENTATION = """ -lookup: laps_password -author: Jordan Borean (@jborean93) -version_added: "2.8" -short_description: Retrieves the LAPS password for a server. -description: -- This lookup returns the LAPS password set for a server from the Active Directory database. -- See U(https://github.com/jborean93/ansible-lookup-laps_password) for more information around installing - pre-requisites and testing. -options: - _terms: - description: - - The host name to retrieve the LAPS password for. - - This is the C(Common Name (CN)) of the host. - required: True - type: str - allow_plaintext: - description: - - When set to C(yes), will allow traffic to be sent unencrypted. - - It is highly recommended to not touch this to avoid any credentials being exposed over the network. - - Use C(scheme=ldaps), C(auth=gssapi), or C(start_tls=yes) to ensure the traffic is encrypted. - default: no - type: bool - auth: - description: - - The type of authentication to use when connecting to the Active Directory server - - When using C(simple), the I(username) and I(password) options must be set. If not using C(scheme=ldaps) or - C(start_tls=True) then these credentials are exposed in plaintext in the network traffic. - - It is recommended ot use C(gssapi) as it will encrypt the traffic automatically. - - When using C(gssapi), run C(kinit) before running Ansible to get a valid Kerberos ticket. - - You cannot use C(gssapi) when either C(scheme=ldaps) or C(start_tls=True) is set. - choices: - - simple - - gssapi - default: gssapi - type: str - ca_cert: - description: - - The path to a CA certificate PEM file to use for certificate validation. - - Certificate validation is used when C(scheme=ldaps) or C(start_tls=yes). - - This may fail on hosts with an older OpenLDAP install like MacOS, this will have to be updated before - reinstalling python-ldap to get working again. - type: str - aliases: [ cacert_file ] - domain: - description: - - The domain to search in to retrieve the LAPS password. - - This could either be a Windows domain name visible to the Ansible controller from DNS or a specific domain - controller FQDN. - - Supports either just the domain/host name or an explicit LDAP URI with the domain/host already filled in. - - If the URI is set, I(port) and I(scheme) are ignored. - required: True - type: str - password: - description: - - The password for C(username). - - Required when C(username) is set. - type: str - port: - description: - - The LDAP port to communicate over. - - If I(kdc) is already an LDAP URI then this is ignored. - type: int - scheme: - description: - - The LDAP scheme to use. - - When using C(ldap), it is recommended to set C(auth=gssapi), or C(start_tls=yes), otherwise traffic will be in - plaintext. - - The Active Directory host must be configured for C(ldaps) with a certificate before it can be used. - - If I(kdc) is already an LDAP URI then this is ignored. - choices: - - ldap - - ldaps - default: ldap - search_base: - description: - - Changes the search base used when searching for the host in Active Directory. - - Will default to search in the C(defaultNamingContext) of the Active Directory server. - - If multiple matches are found then a more explicit search_base is required so only 1 host is found. - - If searching a larger Active Directory database, it is recommended to narrow the search_base for performance - reasons. - type: str - start_tls: - description: - - When C(scheme=ldap), will use the StartTLS extension to encrypt traffic sent over the wire. - - This requires the Active Directory to be set up with a certificate that supports StartTLS. - - This is ignored when C(scheme=ldaps) as the traffic is already encrypted. - type: bool - default: no - username: - description: - - Required when using C(auth=simple). - - The username to authenticate with. - - Recommended to use the username in the UPN format, e.g. C(username@DOMAIN.COM). - - This is required when C(auth=simple) and is not supported when C(auth=gssapi). - - Call C(kinit) outside of Ansible if C(auth=gssapi) is required. - type: str - validate_certs: - description: - - When using C(scheme=ldaps) or C(start_tls=yes), this controls the certificate validation behaviour. - - C(demand) will fail if no certificate or an invalid certificate is provided. - - C(try) will fail for invalid certificates but will continue if no certificate is provided. - - C(allow) will request and check a certificate but will continue even if it is invalid. - - C(never) will not request a certificate from the server so no validation occurs. - default: demand - choices: - - never - - allow - - try - - demand - type: str -requirements: -- python-ldap -notes: -- If a host was found but had no LAPS password attribute C(ms-Mcs-AdmPwd), the lookup will fail. -- Due to the sensitive nature of the data travelling across the network, it is highly recommended to run with either - C(auth=gssapi), C(scheme=ldaps), or C(start_tls=yes). -- Failing to run with one of the above settings will result in the account credentials as well as the LAPS password to - be sent in plaintext. -- Some scenarios may not work when running on a host with an older OpenLDAP install like MacOS. It is recommended to - install the latest OpenLDAP version and build python-ldap against this, see - U(https://keathmilligan.net/python-ldap-and-macos) for more information. -""" - -EXAMPLES = """ -# This isn't mandatory but it is a way to call kinit from within Ansible before calling the lookup -- name: call kinit to retrieve Kerberos token - expect: - command: kinit username@ANSIBLE.COM - responses: - (?i)password: SecretPass1 - no_log: True - -- name: Get the LAPS password using Kerberos auth, relies on kinit already being called - set_fact: - ansible_password: "{{ lookup('laps_password', 'SERVER', domain='dc01.ansible.com') }}" - -- name: Specific the domain host using an explicit LDAP URI - set_fact: - ansible_password: "{{ lookup('laps_password', 'SERVER', domain='ldap://ansible.com:389') }}" - -- name: Use Simple auth over LDAPS - set_fact: - ansible_password: "{{ lookup('laps_password', 'server', - domain='dc01.ansible.com', - auth='simple', - scheme='ldaps', - username='username@ANSIBLE.COM', - password='SuperSecret123') }}" - -- name: Use Simple auth with LDAP and StartTLS - set_fact: - ansible_password: "{{ lookup('laps_password', 'app01', - domain='dc01.ansible.com', - auth='simple', - start_tls=True, - username='username@ANSIBLE.COM', - password='SuperSecret123') }}" - -- name: Narrow down the search base to a an OU - set_fact: - ansible_password: "{{ lookup('laps_password', 'sql10', - domain='dc01.ansible.com', - search_base='OU=Databases,DC=ansible,DC=com') }}" - -- name: Set certificate file to use when validating the TLS certificate - set_fact: - ansible_password: "{{ lookup('laps_password', 'windows-pc', - domain='dc01.ansible.com', - start_tls=True, - ca_cert='/usr/local/share/certs/ad.pem') }}" -""" - -RETURN = """ -_raw: - description: - - The LAPS password(s) for the host(s) requested. - type: str -""" - -import os -import traceback - -from ansible.errors import AnsibleLookupError -from ansible.module_utils._text import to_bytes, to_native, to_text -from ansible.module_utils.basic import missing_required_lib -from ansible.plugins.lookup import LookupBase - -LDAP_IMP_ERR = None -try: - import ldap - import ldapurl - HAS_LDAP = True -except ImportError: - LDAP_IMP_ERR = traceback.format_exc() - HAS_LDAP = False - - -def get_laps_password(conn, cn, search_base): - search_filter = u"(&(objectClass=computer)(CN=%s))" % to_text(cn) - - ldap_results = conn.search_s(to_text(search_base), ldap.SCOPE_SUBTREE, search_filter, - attrlist=[u"distinguishedName", u"ms-Mcs-AdmPwd"]) - - # Filter out non server hosts, search_s seems to return 3 extra entries - # that are not computer classes, they do not have a distinguished name - # set in the returned results - valid_results = [attr for dn, attr in ldap_results if dn] - - if len(valid_results) == 0: - raise AnsibleLookupError("Failed to find the server '%s' in the base '%s'" % (cn, search_base)) - elif len(valid_results) > 1: - found_servers = [to_native(attr['distinguishedName'][0]) for attr in valid_results] - raise AnsibleLookupError("Found too many results for the server '%s' in the base '%s'. Specify a more " - "explicit search base for the server required. Found servers '%s'" - % (cn, search_base, "', '".join(found_servers))) - - password = valid_results[0].get('ms-Mcs-AdmPwd', None) - if not password: - distinguished_name = to_native(valid_results[0]['distinguishedName'][0]) - raise AnsibleLookupError("The server '%s' did not have the LAPS attribute 'ms-Mcs-AdmPwd'" % distinguished_name) - - return to_native(password[0]) - - -class LookupModule(LookupBase): - - def run(self, terms, variables=None, **kwargs): - if not HAS_LDAP: - msg = missing_required_lib("python-ldap", url="https://pypi.org/project/python-ldap/") - msg += ". Import Error: %s" % LDAP_IMP_ERR - raise AnsibleLookupError(msg) - - # Load the variables and direct args into the lookup options - self.set_options(var_options=variables, direct=kwargs) - domain = self.get_option('domain') - port = self.get_option('port') - scheme = self.get_option('scheme') - start_tls = self.get_option('start_tls') - validate_certs = self.get_option('validate_certs') - cacert_file = self.get_option('ca_cert') - search_base = self.get_option('search_base') - username = self.get_option('username') - password = self.get_option('password') - auth = self.get_option('auth') - allow_plaintext = self.get_option('allow_plaintext') - - # Validate and set input values - # https://www.openldap.org/lists/openldap-software/200202/msg00456.html - validate_certs_map = { - 'never': ldap.OPT_X_TLS_NEVER, - 'allow': ldap.OPT_X_TLS_ALLOW, - 'try': ldap.OPT_X_TLS_TRY, - 'demand': ldap.OPT_X_TLS_DEMAND, # Same as OPT_X_TLS_HARD - } - validate_certs_value = validate_certs_map.get(validate_certs, None) - if validate_certs_value is None: - valid_keys = list(validate_certs_map.keys()) - valid_keys.sort() - raise AnsibleLookupError("Invalid validate_certs value '%s': valid values are '%s'" - % (validate_certs, "', '".join(valid_keys))) - - if auth not in ['gssapi', 'simple']: - raise AnsibleLookupError("Invalid auth value '%s': expecting either 'gssapi', or 'simple'" % auth) - elif auth == 'gssapi': - if not ldap.SASL_AVAIL: - raise AnsibleLookupError("Cannot use auth=gssapi when SASL is not configured with the local LDAP " - "install") - if username or password: - raise AnsibleLookupError("Explicit credentials are not supported when auth='gssapi'. Call kinit " - "outside of Ansible") - elif auth == 'simple' and not (username and password): - raise AnsibleLookupError("The username and password values are required when auth=simple") - - if ldapurl.isLDAPUrl(domain): - ldap_url = ldapurl.LDAPUrl(ldapUrl=domain) - else: - port = port if port else 389 if scheme == 'ldap' else 636 - ldap_url = ldapurl.LDAPUrl(hostport="%s:%d" % (domain, port), urlscheme=scheme) - - # We have encryption if using LDAPS, or StartTLS is used, or we auth with SASL/GSSAPI - encrypted = ldap_url.urlscheme == 'ldaps' or start_tls or auth == 'gssapi' - if not encrypted and not allow_plaintext: - raise AnsibleLookupError("Current configuration will result in plaintext traffic exposing credentials. " - "Set auth=gssapi, scheme=ldaps, start_tls=True, or allow_plaintext=True to " - "continue") - - if ldap_url.urlscheme == 'ldaps' or start_tls: - # We cannot use conn.set_option as OPT_X_TLS_NEWCTX (required to use the new context) is not supported on - # older distros like EL7. Setting it on the ldap object works instead - if not ldap.TLS_AVAIL: - raise AnsibleLookupError("Cannot use TLS as the local LDAP installed has not been configured to support it") - - ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, validate_certs_value) - if cacert_file: - cacert_path = os.path.expanduser(os.path.expandvars(cacert_file)) - if not os.path.exists(to_bytes(cacert_path)): - raise AnsibleLookupError("The cacert_file specified '%s' does not exist" % to_native(cacert_path)) - - try: - # While this is a path, python-ldap expects a str/unicode and not bytes - ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, to_text(cacert_path)) - except ValueError: - # https://keathmilligan.net/python-ldap-and-macos/ - raise AnsibleLookupError("Failed to set path to cacert file, this is a known issue with older " - "OpenLDAP libraries on the host. Update OpenLDAP and reinstall " - "python-ldap to continue") - - conn_url = ldap_url.initializeUrl() - conn = ldap.initialize(conn_url, bytes_mode=False) - conn.set_option(ldap.OPT_PROTOCOL_VERSION, 3) - conn.set_option(ldap.OPT_REFERRALS, 0) # Allow us to search from the base - - # Make sure we run StartTLS before doing the bind to protect the credentials - if start_tls: - try: - conn.start_tls_s() - except ldap.LDAPError as err: - raise AnsibleLookupError("Failed to send StartTLS to LDAP host '%s': %s" - % (conn_url, to_native(err))) - - if auth == 'simple': - try: - conn.bind_s(to_text(username), to_text(password)) - except ldap.LDAPError as err: - raise AnsibleLookupError("Failed to simple bind against LDAP host '%s': %s" - % (conn_url, to_native(err))) - else: - try: - conn.sasl_gssapi_bind_s() - except ldap.AUTH_UNKNOWN as err: - # The SASL GSSAPI binding is not installed, e.g. cyrus-sasl-gssapi. Give a better error message than - # what python-ldap provides - raise AnsibleLookupError("Failed to do a sasl bind against LDAP host '%s', the GSSAPI mech is not " - "installed: %s" % (conn_url, to_native(err))) - except ldap.LDAPError as err: - raise AnsibleLookupError("Failed to do a sasl bind against LDAP host '%s': %s" - % (conn_url, to_native(err))) - - try: - if not search_base: - root_dse = conn.read_rootdse_s() - search_base = root_dse['defaultNamingContext'][0] - - ret = [] - # TODO: change method to search for all servers in 1 request instead of multiple requests - for server in terms: - ret.append(get_laps_password(conn, server, search_base)) - finally: - conn.unbind_s() - - return ret diff --git a/test/integration/targets/psexec/aliases b/test/integration/targets/psexec/aliases deleted file mode 100644 index 8642fd8fd49..00000000000 --- a/test/integration/targets/psexec/aliases +++ /dev/null @@ -1,3 +0,0 @@ -windows -shippable/windows/group1 - diff --git a/test/integration/targets/psexec/tasks/main.yml b/test/integration/targets/psexec/tasks/main.yml deleted file mode 100644 index c785d87175f..00000000000 --- a/test/integration/targets/psexec/tasks/main.yml +++ /dev/null @@ -1,49 +0,0 @@ ---- -- name: check whether the host supports encryption - win_shell: | - if ([System.Environment]::OSVersion.Version -lt [Version]"6.2") { - "false" - } else { - "true" - } - register: encryption_supported_raw - -- name: install pypsexec Python library for tests - pip: - name: pypsexec - state: latest - delegate_to: localhost - -- name: define psexec variables - set_fact: - psexec_hostname: '{{ansible_host}}' - psexec_username: '{{ansible_user}}' - psexec_password: '{{ansible_password}}' - psexec_encrypt: '{{encryption_supported_raw.stdout_lines[0]|bool}}' - -- name: create test rule to allow SMB traffic inbound - win_firewall_rule: - name: File and Printer Sharing (SMB-In) Test - direction: in - action: allow - localport: 445 - enabled: yes - protocol: tcp - program: System - profiles: - - domain - - private - - public - state: present - -- name: run tests - block: - - include_tasks: tests.yml - - always: - - name: remove test rule that allows SMB traffic inbound - win_firewall_rule: - name: File and Printer Sharing (SMB-In) Test - direction: in - action: allow - state: absent diff --git a/test/integration/targets/psexec/tasks/tests.yml b/test/integration/targets/psexec/tasks/tests.yml deleted file mode 100644 index e87c79a1e09..00000000000 --- a/test/integration/targets/psexec/tasks/tests.yml +++ /dev/null @@ -1,231 +0,0 @@ ---- -- name: fail when process_password is not set with process_username - psexec: - hostname: '{{psexec_hostname}}' - connection_username: '{{psexec_username}}' - connection_password: '{{psexec_password}}' - encrypt: '{{psexec_encrypt}}' - executable: hostname.exe - process_username: '{{psexec_username}}' - delegate_to: localhost - register: fail_no_process_pass - failed_when: 'fail_no_process_pass.msg != "parameters are required together when not running as System: process_username, process_password"' - -- name: get current host - win_command: hostname.exe - register: actual_hostname - -- name: run basic psexec command - psexec: - hostname: '{{psexec_hostname}}' - connection_username: '{{psexec_username}}' - connection_password: '{{psexec_password}}' - encrypt: '{{psexec_encrypt}}' - executable: hostname.exe - delegate_to: localhost - register: psexec_hostname_actual - -- name: assert basic psexec command matches expected output - assert: - that: - - psexec_hostname_actual is changed - - psexec_hostname_actual.rc == 0 - - psexec_hostname_actual.stderr == '' - - psexec_hostname_actual.stdout == actual_hostname.stdout - -- name: get output for executable with arguments - win_command: hostname.exe /? - register: actual_hostname_help - failed_when: actual_hostname_help.rc != 1 - -- name: run psexec command with arguments - psexec: - hostname: '{{psexec_hostname}}' - connection_username: '{{psexec_username}}' - connection_password: '{{psexec_password}}' - encrypt: '{{psexec_encrypt}}' - executable: hostname.exe - arguments: /? - delegate_to: localhost - register: psexec_hostname_help - failed_when: psexec_hostname_help.rc != 1 - -- name: assert basic pesexec command with arguments matches expected output - assert: - that: - - psexec_hostname_help is changed - - psexec_hostname_help.rc == 1 - - psexec_hostname_help.stderr == actual_hostname_help.stderr - - psexec_hostname_help.stdout == actual_hostname_help.stdout - -- name: run psexec command and send data through stdin - psexec: - hostname: '{{psexec_hostname}}' - connection_username: '{{psexec_username}}' - connection_password: '{{psexec_password}}' - encrypt: '{{psexec_encrypt}}' - executable: powershell.exe - arguments: '-' - stdin: | - Write-Host hello world - Write-Host this is another message - exit 0 - delegate_to: localhost - register: psexec_stdin - -- name: assert psexec ommand and send data through stdin - assert: - that: - - psexec_stdin is changed - - psexec_stdin.rc == 0 - - psexec_stdin.stderr == '' - - psexec_stdin.stdout == 'hello world\nthis is another message\n' - -- name: run psexec command with specific process username - psexec: - hostname: '{{psexec_hostname}}' - connection_username: '{{psexec_username}}' - connection_password: '{{psexec_password}}' - encrypt: '{{psexec_encrypt}}' - load_profile: no # on Azure, the profile does not exist yet so we don't load it for this task - executable: powershell.exe - arguments: '-' - stdin: | - ((Get-CimInstance Win32_Process -filter "processid = $pid") | Get-CimAssociatedInstance -Association Win32_SessionProcess).LogonType - exit 0 - process_username: '{{psexec_username}}' - process_password: '{{psexec_password}}' - delegate_to: localhost - register: psexec_process_username - -- name: assert psexec command with specific process username - assert: - that: - - psexec_process_username is changed - - psexec_process_username.rc == 0 - - psexec_process_username.stderr == '' - - psexec_process_username.stdout_lines[0] != '3' # 3 is Network Logon Type, we assert we are not a network logon with process credentials - -- name: run psexec command with both stderr and stdout - psexec: - hostname: '{{psexec_hostname}}' - connection_username: '{{psexec_username}}' - connection_password: '{{psexec_password}}' - encrypt: '{{psexec_encrypt}}' - executable: cmd.exe - arguments: /c echo first && echo second 1>&2 && echo third - delegate_to: localhost - register: psexec_process_stderr - -- name: assert psexec command with both stderr and stdout - assert: - that: - - psexec_process_stderr is changed - - psexec_process_stderr.rc == 0 - - psexec_process_stderr.stderr == 'second \r\n' - - psexec_process_stderr.stdout == 'first \r\nthird\r\n' - -- name: run process asynchronously - psexec: - hostname: '{{psexec_hostname}}' - connection_username: '{{psexec_username}}' - connection_password: '{{psexec_password}}' - encrypt: '{{psexec_encrypt}}' - executable: powershell.exe - arguments: Start-Sleep -Seconds 30 - asynchronous: yes - delegate_to: localhost - register: psexec_process_async - -- name: check if process is still running - win_shell: (Get-Process -ID {{psexec_process_async.pid}}).ProcessName - register: psexec_process_async_actual - -- name: assert run process asynchronously - assert: - that: - - psexec_process_async is changed - - psexec_process_async.rc is not defined - - psexec_process_async.pid is defined - - psexec_process_async.stdout is not defined - - psexec_process_async.stderr is not defined - - psexec_process_async_actual.stdout_lines[0] == 'powershell' - -- name: run process interactively - psexec: - hostname: '{{psexec_hostname}}' - connection_username: '{{psexec_username}}' - connection_password: '{{psexec_password}}' - encrypt: '{{psexec_encrypt}}' - executable: powershell.exe - arguments: Write-Host hi - interactive: yes - delegate_to: localhost - register: psexec_process_interactive - -- name: assert run process interactively - assert: - that: - - psexec_process_interactive is changed - - psexec_process_interactive.rc == 0 - - psexec_process_interactive.stdout is not defined - - psexec_process_interactive.stderr is not defined - -- name: run process with timeout - psexec: - hostname: '{{psexec_hostname}}' - connection_username: '{{psexec_username}}' - connection_password: '{{psexec_password}}' - encrypt: '{{psexec_encrypt}}' - executable: powershell.exe - arguments: Start-Sleep -Seconds 30 - process_timeout: 5 - delegate_to: localhost - register: psexec_process_timeout - failed_when: psexec_process_timeout.rc == 0 - -- name: assert psexec process with timeout - assert: - that: - - psexec_process_timeout.rc != 0 - - psexec_process_timeout.stdout == '' - - psexec_process_timeout.stderr == '' - -- name: run process as system - psexec: - hostname: '{{psexec_hostname}}' - connection_username: '{{psexec_username}}' - connection_password: '{{psexec_password}}' - encrypt: '{{psexec_encrypt}}' - executable: whoami.exe - process_username: System - delegate_to: localhost - register: psexec_process_system - -- name: assert run process as system - assert: - that: - - psexec_process_system is changed - - psexec_process_system.rc == 0 - - psexec_process_system.stderr == '' - - psexec_process_system.stdout == 'nt authority\system\r\n' - -- name: run process with different chdir - psexec: - hostname: '{{psexec_hostname}}' - connection_username: '{{psexec_username}}' - connection_password: '{{psexec_password}}' - encrypt: '{{psexec_encrypt}}' - executable: powershell.exe - arguments: (pwd).Path - working_directory: C:\Windows - delegate_to: localhost - register: psexec_process_working_dir - -- name: assert run process with different chdir - assert: - that: - - psexec_process_working_dir is changed - - psexec_process_working_dir.rc == 0 - - psexec_process_working_dir.stderr == '' - - psexec_process_working_dir.stdout == 'C:\Windows\r\n' diff --git a/test/integration/targets/win_audit_policy_system/aliases b/test/integration/targets/win_audit_policy_system/aliases deleted file mode 100644 index 423ce391085..00000000000 --- a/test/integration/targets/win_audit_policy_system/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group2 diff --git a/test/integration/targets/win_audit_policy_system/defaults/main.yml b/test/integration/targets/win_audit_policy_system/defaults/main.yml deleted file mode 100644 index 9e0d35c7774..00000000000 --- a/test/integration/targets/win_audit_policy_system/defaults/main.yml +++ /dev/null @@ -1,3 +0,0 @@ -#important that the subcategory is from a different category -category_name: detailed tracking -subcategory_name: file system diff --git a/test/integration/targets/win_audit_policy_system/tasks/add.yml b/test/integration/targets/win_audit_policy_system/tasks/add.yml deleted file mode 100644 index 75ea23045b5..00000000000 --- a/test/integration/targets/win_audit_policy_system/tasks/add.yml +++ /dev/null @@ -1,108 +0,0 @@ -######################## -### check mode apply ### -######################## -- name: check mode enable category - win_audit_policy_system: - category: "{{ category_name }}" - audit_type: success - check_mode: yes - register: category - -- name: check mode enable subcategory - win_audit_policy_system: - subcategory: "{{ subcategory_name }}" - audit_type: success, failure - check_mode: yes - register: subcategory - -- name: check mode assert that changed is true - assert: - that: - - category is changed - - subcategory is changed - -- name: check mode assert that audit_type is "no auditing" - assert: - that: - - item == "no auditing" - with_items: - - "{{ subcategory.current_audit_policy.values() | list }}" - - "{{ category.current_audit_policy.values() | list | unique }}" - -#alternative check for category...pretty noise and requires more lines -# - name: assert that audit_type is no auditing -# assert: -# that: item.value == "no auditing" -# with_dict: "{{ category.current_audit_policy }}" - -#################### -### apply change ### -#################### - -- name: enable category - win_audit_policy_system: - category: "{{ category_name }}" - audit_type: success - register: category - -- name: enable subcategory - win_audit_policy_system: - subcategory: "{{ subcategory_name }}" - audit_type: success, failure - register: subcategory - -- name: enable assert that changed is true - assert: - that: - - category is changed - - subcategory is changed - -- name: enable assert that audit_type is "success" for category - assert: - that: - - item == "success" - with_items: - - "{{ category.current_audit_policy.values() | list | unique }}" - -- name: enable assert that audit_type is "success and failure" for subcategory - assert: - that: - - item == "success and failure" - with_items: - - "{{ subcategory.current_audit_policy.values() | list }}" - -############################### -### idempotent apply change ### -############################### - -- name: idem enable category - win_audit_policy_system: - category: "{{ category_name }}" - audit_type: success - register: category - -- name: idem enable subcategory - win_audit_policy_system: - subcategory: "{{ subcategory_name }}" - audit_type: success, failure - register: subcategory - -- name: idem assert that changed is false - assert: - that: - - category is not changed - - subcategory is not changed - -- name: idem assert that audit_type is "success" for category - assert: - that: - - item == "success" - with_items: - - "{{ category.current_audit_policy.values() | list | unique }}" - -- name: idem assert that audit_type is "success and failure" for subcategory - assert: - that: - - item == "success and failure" - with_items: - - "{{ subcategory.current_audit_policy.values() | list }}" diff --git a/test/integration/targets/win_audit_policy_system/tasks/main.yml b/test/integration/targets/win_audit_policy_system/tasks/main.yml deleted file mode 100644 index c2e55accf5e..00000000000 --- a/test/integration/targets/win_audit_policy_system/tasks/main.yml +++ /dev/null @@ -1,25 +0,0 @@ -#turn off so then we can test changes occur on enable. Turning off for object access also -#covers our subcategory test for file system -- name: turn off auditing for category - win_audit_policy_system: - category: "{{ category_name }}" - audit_type: none - -- name: turn off auditing for subcategory - win_audit_policy_system: - subcategory: "{{ subcategory_name }}" - audit_type: none - -- block: - - include_tasks: add.yml - - include_tasks: remove.yml - always: - - name: CLEANUP turn "{{ category_name }}" back to no auditing - win_audit_policy_system: - category: "{{ category_name }}" - audit_type: none - - - name: CLEANUP turn "{{ subcategory_name }}" back to no auditing - win_audit_policy_system: - subcategory: "{{ subcategory_name }}" - audit_type: none diff --git a/test/integration/targets/win_audit_policy_system/tasks/remove.yml b/test/integration/targets/win_audit_policy_system/tasks/remove.yml deleted file mode 100644 index 1cd60b0ab45..00000000000 --- a/test/integration/targets/win_audit_policy_system/tasks/remove.yml +++ /dev/null @@ -1,96 +0,0 @@ -######################### -### check mode remove ### -######################### -- name: check mode disable category - win_audit_policy_system: - category: "{{ category_name }}" - audit_type: none - check_mode: yes - register: category - -- name: check mode disable subcategory - win_audit_policy_system: - subcategory: "{{ subcategory_name }}" - audit_type: none - check_mode: yes - register: subcategory - -- name: check mode assert that changed is true - assert: - that: - - category is changed - - subcategory is changed - -- name: check mode assert that audit_type is still "success" (old value) for category - assert: - that: - - item == "success" - with_items: - - "{{ category.current_audit_policy.values() | list | unique }}" - -- name: check mode assert that audit_type is still "success and failure" (old value) for subcategory - assert: - that: - - item == "success and failure" - with_items: - - "{{ subcategory.current_audit_policy.values() | list }}" - -###################### -### disable policy ### -###################### - -- name: disable category - win_audit_policy_system: - category: "{{ category_name }}" - audit_type: none - register: category - -- name: disable subcategory - win_audit_policy_system: - subcategory: "{{ subcategory_name }}" - audit_type: none - register: subcategory - -- name: assert that changed is true - assert: - that: - - category is changed - - subcategory is changed - -- name: assert that audit_type is "no auditing" - assert: - that: - - item == "no auditing" - with_items: - - "{{ subcategory.current_audit_policy.values() | list }}" - - "{{ category.current_audit_policy.values() | list | unique }}" - -########################## -### idempotent disable ### -########################## - -- name: idem disable category - win_audit_policy_system: - category: "{{ category_name }}" - audit_type: none - register: category - -- name: idem disable subcategory - win_audit_policy_system: - subcategory: "{{ subcategory_name }}" - audit_type: none - register: subcategory - -- name: idem assert that changed is false - assert: - that: - - category is not changed - - subcategory is not changed - -- name: assert that audit_type is "no auditing" - assert: - that: - - item == "no auditing" - with_items: - - "{{ subcategory.current_audit_policy.values() | list }}" - - "{{ category.current_audit_policy.values() | list | unique }}" diff --git a/test/integration/targets/win_audit_rule/aliases b/test/integration/targets/win_audit_rule/aliases deleted file mode 100644 index 3cf5b97e805..00000000000 --- a/test/integration/targets/win_audit_rule/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_audit_rule/defaults/main.yml b/test/integration/targets/win_audit_rule/defaults/main.yml deleted file mode 100644 index f0faa9a56c9..00000000000 --- a/test/integration/targets/win_audit_rule/defaults/main.yml +++ /dev/null @@ -1,7 +0,0 @@ -test_audit_rule_folder: c:\windows\temp\{{ 'ansible test win_audit_policy' | to_uuid }} -test_audit_rule_file: c:\windows\temp\{{ 'ansible test win_audit_policy' | to_uuid }}.txt -test_audit_rule_registry: HKCU:\{{ 'ansible test win_audit_policy' | to_uuid }} -test_audit_rule_rights: 'delete' -test_audit_rule_new_rights: 'delete,changepermissions' -test_audit_rule_user: 'everyone' -test_audit_rule_audit_flags: success diff --git a/test/integration/targets/win_audit_rule/library/test_get_audit_rule.ps1 b/test/integration/targets/win_audit_rule/library/test_get_audit_rule.ps1 deleted file mode 100644 index a2a5105f89d..00000000000 --- a/test/integration/targets/win_audit_rule/library/test_get_audit_rule.ps1 +++ /dev/null @@ -1,98 +0,0 @@ -#!powershell - -# Copyright (c) 2017 Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.SID - -$params = Parse-Args -arguments $args -supports_check_mode $true - -# these are your module parameters -$path = Get-AnsibleParam -obj $params -name "path" -type "path" -failifempty $true -aliases "destination","dest" -$user = Get-AnsibleParam -obj $params -name "user" -type "str" -failifempty $true -$rights = Get-AnsibleParam -obj $params -name "rights" -type "list" -$inheritance_flags = Get-AnsibleParam -obj $params -name "inheritance_flags" -type "list" -default 'ContainerInherit','ObjectInherit' # -validateset 'None','ContainerInherit','ObjectInherit' -$propagation_flags = Get-AnsibleParam -obj $params -name "propagation_flags" -type "str" -default "none" -ValidateSet 'InheritOnly','None','NoPropagateInherit' -$audit_flags = Get-AnsibleParam -obj $params -name "audit_flags" -type "list" -default "success" #-ValidateSet 'Success','Failure' -#$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset 'present','absent' - - -If (! (Test-Path $path) ) -{ - Fail-Json $result "Path not found ($path)" -} - -Function Get-CurrentAuditRules ($path) { - $ACL = Get-Acl -Path $path -Audit - - $HT = Foreach ($Obj in $ACL.Audit) - { - @{ - user = $Obj.IdentityReference.ToString() - rights = ($Obj | Select-Object -expand "*rights").ToString() - audit_flags = $Obj.AuditFlags.ToString() - is_inherited = $Obj.InheritanceFlags.ToString() - inheritance_flags = $Obj.IsInherited.ToString() - propagation_flags = $Obj.PropagationFlags.ToString() - } - } - - If (-Not $HT) - { - "No audit rules defined on $path" - } - Else {$HT} -} - - -$result = @{ - changed = $false - matching_rule_found = $false - current_audit_rules = Get-CurrentAuditRules $path -} - -$ACL = Get-ACL $Path -Audit -$SID = Convert-ToSid $user - -$ItemType = (Get-Item $path).GetType() -switch ($ItemType) -{ - ([Microsoft.Win32.RegistryKey]) { - $rights = [System.Security.AccessControl.RegistryRights]$rights - $result.path_type = 'registry' - } - ([System.IO.FileInfo]) { - $rights = [System.Security.AccessControl.FileSystemRights]$rights - $result.path_type = 'file' - } - ([System.IO.DirectoryInfo]) { - $rights = [System.Security.AccessControl.FileSystemRights]$rights - $result.path_type = 'directory' - } -} - -$flags = [System.Security.AccessControl.AuditFlags]$audit_flags -$inherit = [System.Security.AccessControl.InheritanceFlags]$inheritance_flags -$prop = [System.Security.AccessControl.PropagationFlags]$propagation_flags - -Foreach ($group in $ACL.Audit) -{ - #exit here if any existing rule matches defined rule, otherwise exit below - #with no matches - If ( - ($group | Select-Object -expand "*Rights") -eq $rights -and - $group.AuditFlags -eq $flags -and - $group.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]) -eq $SID -and - $group.InheritanceFlags -eq $inherit -and - $group.PropagationFlags -eq $prop - ) - { - $result.matching_rule_found = $true - $result.current_audit_rules = Get-CurrentAuditRules $path - Exit-Json $result - } -} - -$result.current_audit_rules = Get-CurrentAuditRules $path -Exit-Json $result diff --git a/test/integration/targets/win_audit_rule/tasks/add.yml b/test/integration/targets/win_audit_rule/tasks/add.yml deleted file mode 100644 index 2a059a88c94..00000000000 --- a/test/integration/targets/win_audit_rule/tasks/add.yml +++ /dev/null @@ -1,172 +0,0 @@ -###################### -### check mode add ### -###################### -- name: check mode ADD audit policy directory - win_audit_rule: - path: "{{ test_audit_rule_folder }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: directory - check_mode: yes - -- name: check mode ADD audit policy file - win_audit_rule: - path: "{{ test_audit_rule_file }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - inheritance_flags: none - register: file - check_mode: yes - -- name: check mode ADD audit policy registry - win_audit_rule: - path: "{{ test_audit_rule_registry }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: registry - check_mode: yes - -- name: check mode ADD get directory results - test_get_audit_rule: - path: "{{ test_audit_rule_folder }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: directory_results - -- name: check mode ADD get file results - test_get_audit_rule: - path: "{{ test_audit_rule_file }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - inheritance_flags: none - register: file_results - -- name: check mode ADD get REGISTRY results - test_get_audit_rule: - path: "{{ test_audit_rule_registry }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: registry_results - -- name: check mode ADD assert that a change is needed, but no change occurred to the audit rules - assert: - that: - - directory is changed - - file is changed - - registry is changed - - not directory_results.matching_rule_found and directory_results.path_type == 'directory' - - not file_results.matching_rule_found and file_results.path_type == 'file' - - not registry_results.matching_rule_found and registry_results.path_type == 'registry' - -################## -### add a rule ### -################## -- name: ADD audit policy directory - win_audit_rule: - path: "{{ test_audit_rule_folder }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: directory - -- name: ADD audit policy file - win_audit_rule: - path: "{{ test_audit_rule_file }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - inheritance_flags: none - register: file - -- name: ADD audit policy registry - win_audit_rule: - path: "{{ test_audit_rule_registry }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: registry - -- name: ADD get directory results - test_get_audit_rule: - path: "{{ test_audit_rule_folder }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: directory_results - -- name: ADD get file results - test_get_audit_rule: - path: "{{ test_audit_rule_file }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - inheritance_flags: none - register: file_results - -- name: ADD get REGISTRY results - test_get_audit_rule: - path: "{{ test_audit_rule_registry }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: registry_results - -- name: ADD assert that the rules were added and a change is detected - assert: - that: - - directory is changed - - file is changed - - registry is changed - - directory_results.matching_rule_found and directory_results.path_type == 'directory' - - file_results.matching_rule_found and file_results.path_type == 'file' - - registry_results.matching_rule_found and registry_results.path_type == 'registry' - -############################# -### idempotent add a rule ### -############################# -- name: idempotent ADD audit policy directory - win_audit_rule: - path: "{{ test_audit_rule_folder }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: directory - -- name: idempotent ADD audit policy file - win_audit_rule: - path: "{{ test_audit_rule_file }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - inheritance_flags: none - register: file - -- name: idempotent ADD audit policy registry idempotent - win_audit_rule: - path: "{{ test_audit_rule_registry }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: registry - -- name: idempotent ADD assert that a change did not occur - assert: - that: - - directory is not changed and directory.path_type == 'directory' - - file is not changed and file.path_type == 'file' - - registry is not changed and registry.path_type == 'registry' diff --git a/test/integration/targets/win_audit_rule/tasks/main.yml b/test/integration/targets/win_audit_rule/tasks/main.yml deleted file mode 100644 index 68fbca768a0..00000000000 --- a/test/integration/targets/win_audit_rule/tasks/main.yml +++ /dev/null @@ -1,33 +0,0 @@ -- name: create temporary folder to test with - win_file: - path: "{{ test_audit_rule_folder }}" - state: directory - -- name: create temporary file to test with - win_file: - path: "{{ test_audit_rule_file }}" - state: touch - -- name: create temporary registry key to test with - win_regedit: - path: "{{ test_audit_rule_registry }}" - -- block: - - include_tasks: add.yml - - include_tasks: modify.yml - - include_tasks: remove.yml - always: - - name: remove testing folder - win_file: - path: "{{ test_audit_rule_folder }}" - state: absent - - - name: remove testing file - win_file: - path: "{{ test_audit_rule_file }}" - state: absent - - - name: remove registry key - win_regedit: - path: "{{ test_audit_rule_registry }}" - state: absent diff --git a/test/integration/targets/win_audit_rule/tasks/modify.yml b/test/integration/targets/win_audit_rule/tasks/modify.yml deleted file mode 100644 index 1db07e2b4ae..00000000000 --- a/test/integration/targets/win_audit_rule/tasks/modify.yml +++ /dev/null @@ -1,172 +0,0 @@ -######################### -### modify check mode ### -######################### -- name: check mode modify audit policy directory - win_audit_rule: - path: "{{ test_audit_rule_folder }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: directory - check_mode: yes - -- name: check mode modify audit policy file - win_audit_rule: - path: "{{ test_audit_rule_file }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - inheritance_flags: none - register: file - check_mode: yes - -- name: check mode modify audit policy registry - win_audit_rule: - path: "{{ test_audit_rule_registry }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: registry - check_mode: yes - -- name: check mode modify get directory rule results - test_get_audit_rule: - path: "{{ test_audit_rule_folder }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: directory_results - -- name: check mode modify get file rule results - test_get_audit_rule: - path: "{{ test_audit_rule_file }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - inheritance_flags: none - register: file_results - -- name: check mode modify get REGISTRY rule results - test_get_audit_rule: - path: "{{ test_audit_rule_registry }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: registry_results - -- name: check mode modify assert that change is needed but rights still equal the original rights and not test_audit_rule_new_rights - assert: - that: - - directory is changed - - file is changed - - registry is changed - - not directory_results.matching_rule_found and directory_results.path_type == 'directory' - - not file_results.matching_rule_found and file_results.path_type == 'file' - - not registry_results.matching_rule_found and registry_results.path_type == 'registry' - -############## -### modify ### -############## -- name: modify audit policy directory - win_audit_rule: - path: "{{ test_audit_rule_folder }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: directory - -- name: modify audit policy file - win_audit_rule: - path: "{{ test_audit_rule_file }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - inheritance_flags: none - register: file - -- name: modify audit policy registry - win_audit_rule: - path: "{{ test_audit_rule_registry }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: registry - -- name: modify get directory rule results - test_get_audit_rule: - path: "{{ test_audit_rule_folder }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: directory_results - -- name: modify get file rule results - test_get_audit_rule: - path: "{{ test_audit_rule_file }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - inheritance_flags: none - register: file_results - -- name: modify get REGISTRY rule results - test_get_audit_rule: - path: "{{ test_audit_rule_registry }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: registry_results - -- name: modify assert that the rules were modified and a change is detected - assert: - that: - - directory is changed - - file is changed - - registry is changed - - directory_results.matching_rule_found and directory_results.path_type == 'directory' - - file_results.matching_rule_found and file_results.path_type == 'file' - - registry_results.matching_rule_found and registry_results.path_type == 'registry' - -##################################### -### idempotent test modify a rule ### -##################################### -- name: idempotent modify audit policy directory - win_audit_rule: - path: "{{ test_audit_rule_folder }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: directory - -- name: idempotent modify audit policy file - win_audit_rule: - path: "{{ test_audit_rule_file }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - inheritance_flags: none - register: file - -- name: idempotent modify audit policy registry - win_audit_rule: - path: "{{ test_audit_rule_registry }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - state: present - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: registry - -- name: idempotent modify assert that and a change is not detected - assert: - that: - - directory is not changed and directory.path_type == 'directory' - - file is not changed and file.path_type == 'file' - - registry is not changed and registry.path_type == 'registry' diff --git a/test/integration/targets/win_audit_rule/tasks/remove.yml b/test/integration/targets/win_audit_rule/tasks/remove.yml deleted file mode 100644 index 3102bc7487d..00000000000 --- a/test/integration/targets/win_audit_rule/tasks/remove.yml +++ /dev/null @@ -1,151 +0,0 @@ -################################ -### check mode remove a rule ### -################################ -- name: check mode remove directory rule - win_audit_rule: - path: "{{ test_audit_rule_folder }}" - user: "{{ test_audit_rule_user }}" - state: absent - register: directory - check_mode: yes - -- name: check mode remove file rule - win_audit_rule: - path: "{{ test_audit_rule_file }}" - user: "{{ test_audit_rule_user }}" - state: absent - register: file - check_mode: yes - -- name: check mode remove registry rule - win_audit_rule: - path: "{{ test_audit_rule_registry }}" - user: "{{ test_audit_rule_user }}" - state: absent - register: registry - check_mode: yes - -- name: check mode remove get directory rule results - test_get_audit_rule: - path: "{{ test_audit_rule_folder }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: directory_results - -- name: check mode remove get file rule results - test_get_audit_rule: - path: "{{ test_audit_rule_file }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - inheritance_flags: none - register: file_results - -- name: check mode remove get REGISTRY rule results - test_get_audit_rule: - path: "{{ test_audit_rule_registry }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: registry_results - -- name: check mode remove assert that change detected, but rule is still present - assert: - that: - - directory is changed - - file is changed - - registry is changed - - directory_results.matching_rule_found and directory_results.path_type == 'directory' - - file_results.matching_rule_found and file_results.path_type == 'file' - - registry_results.matching_rule_found and registry_results.path_type == 'registry' - -##################### -### remove a rule ### -##################### -- name: remove directory rule - win_audit_rule: - path: "{{ test_audit_rule_folder }}" - user: "{{ test_audit_rule_user }}" - state: absent - register: directory - -- name: remove file rule - win_audit_rule: - path: "{{ test_audit_rule_file }}" - user: "{{ test_audit_rule_user }}" - state: absent - register: file - -- name: remove registry rule - win_audit_rule: - path: "{{ test_audit_rule_registry }}" - user: "{{ test_audit_rule_user }}" - state: absent - register: registry - -- name: remove get directory rule results - test_get_audit_rule: - path: "{{ test_audit_rule_folder }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: directory_results - -- name: remove get file rule results - test_get_audit_rule: - path: "{{ test_audit_rule_file }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - inheritance_flags: none - register: file_results - -- name: remove get REGISTRY rule results - test_get_audit_rule: - path: "{{ test_audit_rule_registry }}" - user: "{{ test_audit_rule_user }}" - rights: "{{ test_audit_rule_new_rights }}" - audit_flags: "{{ test_audit_rule_audit_flags }}" - register: registry_results - -- name: remove assert that change detected and rule is gone - assert: - that: - - directory is changed - - file is changed - - registry is changed - - not directory_results.matching_rule_found and directory_results.path_type == 'directory' - - not file_results.matching_rule_found and file_results.path_type == 'file' - - not registry_results.matching_rule_found and registry_results.path_type == 'registry' - -################################ -### idempotent remove a rule ### -################################ -- name: idempotent remove directory rule - win_audit_rule: - path: "{{ test_audit_rule_folder }}" - user: "{{ test_audit_rule_user }}" - state: absent - register: directory - -- name: idempotent remove file rule - win_audit_rule: - path: "{{ test_audit_rule_file }}" - user: "{{ test_audit_rule_user }}" - state: absent - register: file - -- name: idempotent remove registry rule - win_audit_rule: - path: "{{ test_audit_rule_registry }}" - user: "{{ test_audit_rule_user }}" - state: absent - register: registry - -- name: idempotent remove assert that no change detected - assert: - that: - - directory is not changed and directory.path_type == 'directory' - - file is not changed and file.path_type == 'file' - - registry is not changed and registry.path_type == 'registry' diff --git a/test/integration/targets/win_auto_logon/aliases b/test/integration/targets/win_auto_logon/aliases deleted file mode 100644 index 4cd27b3cb2f..00000000000 --- a/test/integration/targets/win_auto_logon/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group1 diff --git a/test/integration/targets/win_auto_logon/defaults/main.yml b/test/integration/targets/win_auto_logon/defaults/main.yml deleted file mode 100644 index d5462bb6a35..00000000000 --- a/test/integration/targets/win_auto_logon/defaults/main.yml +++ /dev/null @@ -1,3 +0,0 @@ -# This doesn't have to be valid, just testing weird chars in the pass -test_logon_password: 'café - 💩' -test_logon_password2: '.ÅÑŚÌβŁÈ [$!@^&test(;)]' diff --git a/test/integration/targets/win_auto_logon/library/test_autologon_info.ps1 b/test/integration/targets/win_auto_logon/library/test_autologon_info.ps1 deleted file mode 100644 index ef4cf2d0f3e..00000000000 --- a/test/integration/targets/win_auto_logon/library/test_autologon_info.ps1 +++ /dev/null @@ -1,214 +0,0 @@ -#!powershell - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.AddType - -$module = [Ansible.Basic.AnsibleModule]::Create($args, @{}) - -Add-CSharpType -AnsibleModule $module -References @' -using Microsoft.Win32.SafeHandles; -using System; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; -using System.Text; - -namespace Ansible.TestAutoLogonInfo -{ - internal class NativeHelpers - { - [StructLayout(LayoutKind.Sequential)] - public class LSA_OBJECT_ATTRIBUTES - { - public UInt32 Length = 0; - public IntPtr RootDirectory = IntPtr.Zero; - public IntPtr ObjectName = IntPtr.Zero; - public UInt32 Attributes = 0; - public IntPtr SecurityDescriptor = IntPtr.Zero; - public IntPtr SecurityQualityOfService = IntPtr.Zero; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct LSA_UNICODE_STRING - { - public UInt16 Length; - public UInt16 MaximumLength; - public IntPtr Buffer; - - public static explicit operator string(LSA_UNICODE_STRING s) - { - byte[] strBytes = new byte[s.Length]; - Marshal.Copy(s.Buffer, strBytes, 0, s.Length); - return Encoding.Unicode.GetString(strBytes); - } - - public static SafeMemoryBuffer CreateSafeBuffer(string s) - { - if (s == null) - return new SafeMemoryBuffer(IntPtr.Zero); - - byte[] stringBytes = Encoding.Unicode.GetBytes(s); - int structSize = Marshal.SizeOf(typeof(LSA_UNICODE_STRING)); - IntPtr buffer = Marshal.AllocHGlobal(structSize + stringBytes.Length); - try - { - LSA_UNICODE_STRING lsaString = new LSA_UNICODE_STRING() - { - Length = (UInt16)(stringBytes.Length), - MaximumLength = (UInt16)(stringBytes.Length), - Buffer = IntPtr.Add(buffer, structSize), - }; - Marshal.StructureToPtr(lsaString, buffer, false); - Marshal.Copy(stringBytes, 0, lsaString.Buffer, stringBytes.Length); - return new SafeMemoryBuffer(buffer); - } - catch - { - // Make sure we free the pointer before raising the exception. - Marshal.FreeHGlobal(buffer); - throw; - } - } - } - } - - internal class NativeMethods - { - [DllImport("Advapi32.dll")] - public static extern UInt32 LsaClose( - IntPtr ObjectHandle); - - [DllImport("Advapi32.dll")] - public static extern UInt32 LsaFreeMemory( - IntPtr Buffer); - - [DllImport("Advapi32.dll")] - internal static extern Int32 LsaNtStatusToWinError( - UInt32 Status); - - [DllImport("Advapi32.dll")] - public static extern UInt32 LsaOpenPolicy( - IntPtr SystemName, - NativeHelpers.LSA_OBJECT_ATTRIBUTES ObjectAttributes, - UInt32 AccessMask, - out SafeLsaHandle PolicyHandle); - - [DllImport("Advapi32.dll")] - public static extern UInt32 LsaRetrievePrivateData( - SafeLsaHandle PolicyHandle, - SafeMemoryBuffer KeyName, - out SafeLsaMemory PrivateData); - } - - internal class SafeLsaMemory : SafeBuffer - { - internal SafeLsaMemory() : base(true) { } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - - protected override bool ReleaseHandle() - { - return NativeMethods.LsaFreeMemory(handle) == 0; - } - } - - internal class SafeMemoryBuffer : SafeBuffer - { - internal SafeMemoryBuffer() : base(true) { } - - internal SafeMemoryBuffer(IntPtr ptr) : base(true) - { - base.SetHandle(ptr); - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - - protected override bool ReleaseHandle() - { - if (handle != IntPtr.Zero) - Marshal.FreeHGlobal(handle); - return true; - } - } - - public class SafeLsaHandle : SafeHandleZeroOrMinusOneIsInvalid - { - internal SafeLsaHandle() : base(true) { } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - - protected override bool ReleaseHandle() - { - return NativeMethods.LsaClose(handle) == 0; - } - } - - public class Win32Exception : System.ComponentModel.Win32Exception - { - private string _exception_msg; - public Win32Exception(string message) : this(Marshal.GetLastWin32Error(), message) { } - public Win32Exception(int errorCode, string message) : base(errorCode) - { - _exception_msg = String.Format("{0} - {1} (Win32 Error Code {2}: 0x{3})", message, base.Message, errorCode, errorCode.ToString("X8")); - } - public override string Message { get { return _exception_msg; } } - public static explicit operator Win32Exception(string message) { return new Win32Exception(message); } - } - - public class LsaUtil - { - public static SafeLsaHandle OpenPolicy(UInt32 access) - { - NativeHelpers.LSA_OBJECT_ATTRIBUTES oa = new NativeHelpers.LSA_OBJECT_ATTRIBUTES(); - SafeLsaHandle lsaHandle; - UInt32 res = NativeMethods.LsaOpenPolicy(IntPtr.Zero, oa, access, out lsaHandle); - if (res != 0) - throw new Win32Exception(NativeMethods.LsaNtStatusToWinError(res), - String.Format("LsaOpenPolicy({0}) failed", access.ToString())); - return lsaHandle; - } - - public static string RetrievePrivateData(SafeLsaHandle handle, string key) - { - using (SafeMemoryBuffer keyBuffer = NativeHelpers.LSA_UNICODE_STRING.CreateSafeBuffer(key)) - { - SafeLsaMemory buffer; - UInt32 res = NativeMethods.LsaRetrievePrivateData(handle, keyBuffer, out buffer); - using (buffer) - { - if (res != 0) - { - // If the data object was not found we return null to indicate it isn't set. - if (res == 0xC0000034) // STATUS_OBJECT_NAME_NOT_FOUND - return null; - - throw new Win32Exception(NativeMethods.LsaNtStatusToWinError(res), - String.Format("LsaRetrievePrivateData({0}) failed", key)); - } - - NativeHelpers.LSA_UNICODE_STRING lsaString = (NativeHelpers.LSA_UNICODE_STRING) - Marshal.PtrToStructure(buffer.DangerousGetHandle(), - typeof(NativeHelpers.LSA_UNICODE_STRING)); - return (string)lsaString; - } - } - } - } -} -'@ - -$details = Get-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -$module.Result.AutoAdminLogon = $details.AutoAdminLogon -$module.Result.DefaultUserName = $details.DefaultUserName -$module.Result.DefaultDomainName = $details.DefaultDomainName -$module.Result.DefaultPassword = $details.DefaultPassword -$module.Result.AutoLogonCount = $details.AutoLogonCount - -$handle = [Ansible.TestAutoLogonInfo.LsaUtil]::OpenPolicy(0x00000004) -try { - $password = [Ansible.TestAutoLogonInfo.LsaUtil]::RetrievePrivateData($handle, 'DefaultPassword') - $module.Result.LsaPassword = $password -} finally { - $handle.Dispose() -} - -$module.ExitJson() diff --git a/test/integration/targets/win_auto_logon/tasks/main.yml b/test/integration/targets/win_auto_logon/tasks/main.yml deleted file mode 100644 index f8a8d01624f..00000000000 --- a/test/integration/targets/win_auto_logon/tasks/main.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- -- name: get user domain split for ansible_user - win_shell: | - $account = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList '{{ ansible_user }}' - $sid = $account.Translate([System.Security.Principal.SecurityIdentifier]) - $sid.Translate([System.Security.Principal.NTAccount]).Value -split '{{ "\\" }}' - changed_when: False - register: test_user_split - -- set_fact: - test_domain: '{{ test_user_split.stdout_lines[0] }}' - test_user: '{{ test_user_split.stdout_lines[1] }}' - -- name: ensure auto logon is cleared before test - win_auto_logon: - state: absent - -- name: ensure defaults are set - win_regedit: - path: HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon - name: '{{ item.name }}' - data: '{{ item.value }}' - type: '{{ item.type }}' - state: present - loop: - # We set the DefaultPassword to ensure win_auto_logon clears this out - - name: DefaultPassword - value: abc - type: string - # Ensures the host we test on has a baseline key to check against - - name: AutoAdminLogon - value: 0 - type: dword - -- block: - - name: run tests - include_tasks: tests.yml - - always: - - name: make sure the auto logon is cleared - win_auto_logon: - state: absent diff --git a/test/integration/targets/win_auto_logon/tasks/tests.yml b/test/integration/targets/win_auto_logon/tasks/tests.yml deleted file mode 100644 index c25e07709ba..00000000000 --- a/test/integration/targets/win_auto_logon/tasks/tests.yml +++ /dev/null @@ -1,178 +0,0 @@ -# Copyright: (c) 2019, Prasoon Karunan V (@prasoonkarunan) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) ---- -- name: set autologon registry keys (check mode) - win_auto_logon: - username: '{{ ansible_user }}' - password: '{{ test_logon_password }}' - state: present - register: set_check - check_mode: yes - -- name: get acutal of set autologon registry keys (check mode) - test_autologon_info: - register: set_actual_check - -- name: assert set autologon registry keys (check mode) - assert: - that: - - set_check is changed - - set_actual_check.AutoAdminLogon == 0 - - set_actual_check.AutoLogonCount == None - - set_actual_check.DefaultDomainName == None - - set_actual_check.DefaultPassword == 'abc' - - set_actual_check.DefaultUserName == None - - set_actual_check.LsaPassword == None - -- name: set autologon registry keys - win_auto_logon: - username: '{{ ansible_user }}' - password: '{{ test_logon_password }}' - state: present - register: set - -- name: get acutal of set autologon registry keys - test_autologon_info: - register: set_actual - -- name: assert set autologon registry keys - assert: - that: - - set is changed - - set_actual.AutoAdminLogon == 1 - - set_actual.AutoLogonCount == None - - set_actual.DefaultDomainName == test_domain - - set_actual.DefaultPassword == None - - set_actual.DefaultUserName == test_user - - set_actual.LsaPassword == test_logon_password - -- name: set autologon registry keys (idempotent) - win_auto_logon: - username: '{{ ansible_user }}' - password: '{{ test_logon_password }}' - state: present - register: set_again - -- name: assert set autologon registry keys (idempotent) - assert: - that: - - not set_again is changed - -- name: add logon count (check mode) - win_auto_logon: - username: '{{ ansible_user }}' - password: '{{ test_logon_password }}' - logon_count: 2 - state: present - register: logon_count_check - check_mode: yes - -- name: get result of add logon count (check mode) - test_autologon_info: - register: logon_count_actual_check - -- name: assert add logon count (check mode) - assert: - that: - - logon_count_check is changed - - logon_count_actual_check.AutoLogonCount == None - -- name: add logon count - win_auto_logon: - username: '{{ ansible_user }}' - password: '{{ test_logon_password }}' - logon_count: 2 - state: present - register: logon_count - -- name: get result of add logon count - test_autologon_info: - register: logon_count_actual - -- name: assert add logon count - assert: - that: - - logon_count is changed - - logon_count_actual.AutoLogonCount == 2 - -- name: change auto logon (check mode) - win_auto_logon: - username: '{{ ansible_user }}' - password: '{{ test_logon_password2 }}' - state: present - register: change_check - check_mode: yes - -- name: get reuslt of change auto logon (check mode) - test_autologon_info: - register: change_actual_check - -- name: assert change auto logon (check mode) - assert: - that: - - change_check is changed - - change_actual_check == logon_count_actual - -- name: change auto logon - win_auto_logon: - username: '{{ ansible_user }}' - password: '{{ test_logon_password2 }}' - state: present - register: change - -- name: get reuslt of change auto logon - test_autologon_info: - register: change_actual - -- name: assert change auto logon - assert: - that: - - change is changed - - change_actual.AutoLogonCount == None - - change_actual.LsaPassword == test_logon_password2 - -- name: remove autologon registry keys (check mode) - win_auto_logon: - state: absent - register: remove_check - check_mode: yes - -- name: get result of remove autologon registry keys (check mode) - test_autologon_info: - register: remove_actual_check - -- name: assert remove autologon registry keys (check mode) - assert: - that: - - remove_check is changed - - remove_actual_check == change_actual - -- name: remove autologon registry keys - win_auto_logon: - state: absent - register: remove - -- name: get result of remove autologon registry keys - test_autologon_info: - register: remove_actual - -- name: assert remove autologon registry keys - assert: - that: - - remove is changed - - remove_actual.AutoAdminLogon == 0 - - remove_actual.AutoLogonCount == None - - remove_actual.DefaultDomainName == None - - remove_actual.DefaultPassword == None - - remove_actual.DefaultUserName == None - - remove_actual.LsaPassword == None - -- name: remove autologon registry keys (idempotent) - win_auto_logon: - state: absent - register: remove_again - -- name: assert remove autologon registry keys (idempotent) - assert: - that: - - not remove_again is changed diff --git a/test/integration/targets/win_certificate_info/aliases b/test/integration/targets/win_certificate_info/aliases deleted file mode 100644 index 6036e173f1a..00000000000 --- a/test/integration/targets/win_certificate_info/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group7 diff --git a/test/integration/targets/win_certificate_info/defaults/main.yml b/test/integration/targets/win_certificate_info/defaults/main.yml deleted file mode 100644 index b8d5a0f90f2..00000000000 --- a/test/integration/targets/win_certificate_info/defaults/main.yml +++ /dev/null @@ -1,3 +0,0 @@ -win_cert_dir: '{{win_output_dir}}\win_certificate .ÅÑŚÌβŁÈ [$!@^&test(;)]' -subj_thumbprint: 'BD7AF104CF1872BDB518D95C9534EA941665FD27' -root_thumbprint: 'BC05633694E675449136679A658281F17A191087' diff --git a/test/integration/targets/win_certificate_info/files/root-cert.pem b/test/integration/targets/win_certificate_info/files/root-cert.pem deleted file mode 100644 index edbe6b86848..00000000000 --- a/test/integration/targets/win_certificate_info/files/root-cert.pem +++ /dev/null @@ -1,20 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDKDCCAhCgAwIBAgIJAP1vIdGgMJv/MA0GCSqGSIb3DQEBCwUAMCgxGTAXBgNV -BAMMEHJvb3QuYW5zaWJsZS5jb20xCzAJBgNVBAYTAlVTMCAXDTE3MTIxNTA4Mzkz -MloYDzIwODYwMTAyMDgzOTMyWjAoMRkwFwYDVQQDDBByb290LmFuc2libGUuY29t -MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMmq -YT8eZY6rFQKnmScUGnnUH1tLQ+3WQpfKiWygCUSb1CNqO3J1u3pGMEqYM58LK4Kr -Mpskv7K1tCV/EMZqGTqXAIfSLy9umlb/9C3AhL9thBPn5I9dam/EmrIZktI9/w5Y -wBXn4toe+OopA3QkMQh9BUjUCPb9fdOI+ir7OGFZMmxXmiM64+BEeywM2oSGsdZ9 -5hU378UBu2IX4+OAV8Fbr2l6VW+Fxg/tKIOo6Bs46Pa4EZgtemOqs3kxYBOltBTb -vFcLsLa4KYVu5Ge5YfB0Axfaem7PoP8IlMs8gxyojZ/r0o5hzxUcYlL/h8GeeoLW -PFFdiAS+UgxWINOqNXMCAwEAAaNTMFEwHQYDVR0OBBYEFLp9k4LmOnAR4ROrqhb+ -CFdbk2+oMB8GA1UdIwQYMBaAFLp9k4LmOnAR4ROrqhb+CFdbk2+oMA8GA1UdEwEB -/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAGksycHsjGbXfWfuhQh+CvXk/A2v -MoNgiHtNMTGliVNgoVp1B1rj4x9xyZ8YrO8GAmv8jaCwCShd0B5Ul4aZVk1wglVv -lFAwb4IAZN9jv9+fw5BRzQ2tLhkVWIEwx6pZkhGhhjBvMaplLN5JwBtsdZorFbm7 -wuKiUKcFAM28acoOhCmOhgyNNBZpZn5wXaQDY43AthJOhitAV7vph4MPUkwIJnOh -MA5GJXEqS58TE9z9pkhQnn9598G8tmOXyA2erAoM9JAXM3EYHxVpoHBb9QRj6WAw -XVBo6qRXkwjNEM5CbnD4hVIBsdkOGsDrgd4Q5izQZ3x+jFNkdL/zPsXjJFw= ------END CERTIFICATE----- - diff --git a/test/integration/targets/win_certificate_info/files/subj-cert.pem b/test/integration/targets/win_certificate_info/files/subj-cert.pem deleted file mode 100644 index 6d9ec39c734..00000000000 --- a/test/integration/targets/win_certificate_info/files/subj-cert.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIC0TCCAbkCCQC/MtOBa1UDpzANBgkqhkiG9w0BAQsFADAoMRkwFwYDVQQDDBBy -b290LmFuc2libGUuY29tMQswCQYDVQQGEwJVUzAgFw0xNzEyMTUwODU2MzBaGA8y -MDg2MDEwMjA4NTYzMFowKzEcMBoGA1UEAwwTc3ViamVjdC5hbnNpYmxlLmNvbTEL -MAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDszqdF -So3GlVP1xUnN4bSPrFRFiOl/Mqup0Zn5UJJUR9wLnRD+OLcq7kKin6hYqozSu7cC -+BnWQoq7vGSSNVqv7BqFMwzGJt9IBUQv0UqIQkA/duUdKdAiMn2PQRsNDnkWEbTj -4xsitItVNv84cDG0lkZBYyTgfyZlZLZWplkpUQkrZhoFCekZRJ+ODrqNW3W560rr -OUIh+HiQeBqocat6OdxgICBqpUh8EVo1iha3DXjGN08q5utg6gmbIl2VBaVJjfyd -wnUSqHylJwh6WCIEh+HXsn4ndfNWSN/fDqvi5I10V1j6Zos7yqQf8qAezUAm6eSq -hLgZz0odq9DsO4HHAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFK5mVIJ2D+kI0kk -sxnW4ibWFjzlYFYPYrZg+2JFIVTbKBg1YzyhuIKm0uztqRxQq5iLn/C/uponHoqF -7KDQI37KAJIQdgSva+mEuO9bZAXg/eegail2hN6np7HjOKlPu23s40dAbFrbcOWP -VbsBEPDP0HLv6OgbQWzNlE9HO1b7pX6ozk3q4ULO7IR85P6OHYsBBThL+qsOTzg/ -gVknuB9+n9hgNqZcAcXBLDetOM9aEmYJCGk0enYP5UGLYpseE+rTXFbRuHTPr1o6 -e8BetiSWS/wcrV4ZF5qr9NiYt5eD6JzTB5Rn5awxxj0FwMtrBu003lLQUWxsuTzz -35/RLY4= ------END CERTIFICATE----- - diff --git a/test/integration/targets/win_certificate_info/meta/main.yml b/test/integration/targets/win_certificate_info/meta/main.yml deleted file mode 100644 index bdea853d75a..00000000000 --- a/test/integration/targets/win_certificate_info/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: -- prepare_win_tests diff --git a/test/integration/targets/win_certificate_info/tasks/main.yml b/test/integration/targets/win_certificate_info/tasks/main.yml deleted file mode 100644 index 06bd6802c6a..00000000000 --- a/test/integration/targets/win_certificate_info/tasks/main.yml +++ /dev/null @@ -1,88 +0,0 @@ -### keys in files/ have been generated with -# generate root private key -# openssl genrsa -aes256 -out enckey.pem 2048 -# openssl rsa -in envkey.pem -out root-key.pem -# -# generate root certificate -# openssl req -x509 -key root-key.pem -days 24855 -out root-vert.pem -subj "/CN=root.ansible.com/C=US" -# -# generate subject private key -# openssl genrsa -aes256 -out enckey.pem 2048 -# openssl rsa -in enckey.pem -out subj-key.pem -# -# generate subject certificate -# openssl req -new -key subj-key.pem -out cert.csr -subj "/CN=subject.ansible.com/C=US" -# openssl x509 -req -in cert.csr -CA root-cert.pem -CAkey root-key.pem -CAcreateserial -out subj-cert.pem -days 24855 -### ---- -- name: ensure test dir is present - win_file: - path: '{{win_cert_dir}}\exported' - state: directory - -- name: copy across test cert files - win_copy: - src: files/ - dest: '{{win_cert_dir}}' - -- name: subject cert imported to personal store - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert.pem' - state: present - store_name: My - -- name: root certificate imported to trusted root - win_certificate_store: - path: '{{win_cert_dir}}\root-cert.pem' - store_name: Root - state: present - -- name: get raw root certificate - shell: 'cat root-cert.pem | grep "^[^-]"' - args: - chdir: '{{ role_path }}/files' - register: root_raw - delegate_to: localhost - -- name: get public key of root certificate - shell: 'openssl x509 -pubkey -noout -in root-cert.pem | grep "^[^-]"' - args: - chdir: '{{ role_path }}/files' - register: root_pub - delegate_to: localhost - -- name: get subject certificate - shell: 'cat subj-cert.pem | grep "^[^-]"' - args: - chdir: '{{ role_path }}/files' - register: subj_raw - delegate_to: localhost - -- name: get public key of subject certificate - shell: 'openssl x509 -pubkey -noout -in subj-cert.pem | grep "^[^-]"' - args: - chdir: '{{ role_path }}/files' - register: subj_pub - delegate_to: localhost - -- block: - - name: run tests - include_tasks: tests.yml - - always: - - name: ensure subject cert removed from personal store - win_certificate_store: - thumbprint: '{{subj_thumbprint}}' - state: absent - store_name: My - - - name: ensure root cert removed from trusted root - win_certificate_store: - thumbprint: '{{root_thumbprint}}' - state: absent - store_name: Root - - - name: ensure test dir is deleted - win_file: - path: '{{win_cert_dir}}' - state: absent diff --git a/test/integration/targets/win_certificate_info/tasks/tests.yml b/test/integration/targets/win_certificate_info/tasks/tests.yml deleted file mode 100644 index 90eb0870bf7..00000000000 --- a/test/integration/targets/win_certificate_info/tasks/tests.yml +++ /dev/null @@ -1,90 +0,0 @@ ---- - -- name: get stats on a store that doesn't exist - win_certificate_info: - store_name: teststore - register: test_store - -- name: ensure exists is false - assert: - that: - - test_store.exists == false - -- name: get stats on the root certificate store - win_certificate_info: - store_name: Root - register: root_store - -- name: at least one certificate is returned - assert: - that: - - "root_store.exists" - - "root_store.certificates | length > 0" - -- name: get stats on a certificate that doesn't exist - win_certificate_info: - thumbprint: ABC - register: actual - -- name: ensure exists is false - assert: - that: actual.exists == false - -- name: get stats on root certificate - win_certificate_info: - thumbprint: '{{ root_thumbprint }}' - store_name: Root - register: root_stats - -- name: root certificate stats returned are expected values - assert: - that: - - root_stats.exists - - root_stats.certificates[0].archived == false - - root_stats.certificates[0].dns_names == [ 'root.ansible.com' ] - - root_stats.certificates[0].extensions|count == 3 - - root_stats.certificates[0].has_private_key == false - - root_stats.certificates[0].issued_by == 'root.ansible.com' - - root_stats.certificates[0].issued_to == 'root.ansible.com' - - root_stats.certificates[0].issuer == 'C=US, CN=root.ansible.com' - - root_stats.certificates[0].path_length_constraint == 0 -# - root_stats.certificates[0].public_key == (root_pub.stdout_lines|join()) - - root_stats.certificates[0].raw == root_raw.stdout_lines|join() - - root_stats.certificates[0].serial_number == '00FD6F21D1A0309BFF' - - root_stats.certificates[0].signature_algorithm == 'sha256RSA' - - root_stats.certificates[0].ski == 'BA7D9382E63A7011E113ABAA16FE08575B936FA8' - - root_stats.certificates[0].subject == 'C=US, CN=root.ansible.com' - - root_stats.certificates[0].valid_from == 1513327172 - - root_stats.certificates[0].valid_from_iso8601 == '2017-12-15T08:39:32Z' - - root_stats.certificates[0].valid_to == 3660799172 - - root_stats.certificates[0].valid_to_iso8601 == '2086-01-02T08:39:32Z' - - root_stats.certificates[0].version == 3 - -- name: get stats on subject certificate - win_certificate_info: - thumbprint: '{{ subj_thumbprint }}' - register: subj_stats - -- name: subject certificate stats returned are expected values - assert: - that: - - subj_stats.exists - - subj_stats.certificates[0].archived == false - - subj_stats.certificates[0].dns_names == [ 'subject.ansible.com' ] - - subj_stats.certificates[0].extensions|count == 0 - - subj_stats.certificates[0].has_private_key == false - - subj_stats.certificates[0].issued_by == 'root.ansible.com' - - subj_stats.certificates[0].issued_to == 'subject.ansible.com' - - subj_stats.certificates[0].issuer == 'C=US, CN=root.ansible.com' - - subj_stats.certificates[0].path_length_constraint is undefined -# - subj_stats.certificates[0].public_key == subj_pub.stdout_lines|join() - - subj_stats.certificates[0].raw == subj_raw.stdout_lines|join() - - subj_stats.certificates[0].serial_number == '00BF32D3816B5503A7' - - subj_stats.certificates[0].signature_algorithm == 'sha256RSA' - - subj_stats.certificates[0].ski is undefined - - subj_stats.certificates[0].subject == 'C=US, CN=subject.ansible.com' - - subj_stats.certificates[0].valid_from == 1513328190 - - subj_stats.certificates[0].valid_from_iso8601 == '2017-12-15T08:56:30Z' - - subj_stats.certificates[0].valid_to == 3660800190 - - subj_stats.certificates[0].valid_to_iso8601 == '2086-01-02T08:56:30Z' - - subj_stats.certificates[0].version == 1 diff --git a/test/integration/targets/win_chocolatey/aliases b/test/integration/targets/win_chocolatey/aliases deleted file mode 100644 index 4f4664b6858..00000000000 --- a/test/integration/targets/win_chocolatey/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group5 diff --git a/test/integration/targets/win_chocolatey/defaults/main.yml b/test/integration/targets/win_chocolatey/defaults/main.yml deleted file mode 100644 index eb5289d35f3..00000000000 --- a/test/integration/targets/win_chocolatey/defaults/main.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -test_choco_path: '{{ win_output_dir }}\win_chocolatey' -test_choco_source: '{{ test_choco_path }}\packages' -test_choco_source2: '{{ test_choco_path }}\packages2' # used to verify source works with the source name and not just the path -test_choco_package1: ansible -test_choco_package2: ansible-test -test_choco_packages: -- '{{ test_choco_package1 }}' -- '{{ test_choco_package2 }}' diff --git a/test/integration/targets/win_chocolatey/files/package.nuspec b/test/integration/targets/win_chocolatey/files/package.nuspec deleted file mode 100644 index b5a3e409fec..00000000000 --- a/test/integration/targets/win_chocolatey/files/package.nuspec +++ /dev/null @@ -1,13 +0,0 @@ - - - - --- NAME --- - --- VERSION --- - --- NAME --- - Jordan Borean - Test for win_chocolatey module - - - - - diff --git a/test/integration/targets/win_chocolatey/files/tools/chocolateyUninstall.ps1 b/test/integration/targets/win_chocolatey/files/tools/chocolateyUninstall.ps1 deleted file mode 100644 index 8c49c11fb09..00000000000 --- a/test/integration/targets/win_chocolatey/files/tools/chocolateyUninstall.ps1 +++ /dev/null @@ -1,9 +0,0 @@ -$ErrorActionPreference = 'Stop' - -$package_name = $env:ChocolateyPackageName -$package_version = $env:ChocolateyPackageVersion -$install_path = "--- PATH ---\$package_name-$package_version.txt" - -if (Test-Path -Path $install_path) { - Remove-Item -Path $install_path -Force > $null -} diff --git a/test/integration/targets/win_chocolatey/files/tools/chocolateyinstall.ps1 b/test/integration/targets/win_chocolatey/files/tools/chocolateyinstall.ps1 deleted file mode 100644 index ee2c47f6c8e..00000000000 --- a/test/integration/targets/win_chocolatey/files/tools/chocolateyinstall.ps1 +++ /dev/null @@ -1,55 +0,0 @@ -$ErrorActionPreference = 'Stop' - -$package_name = $env:ChocolateyPackageName -$package_version = $env:ChocolateyPackageVersion -$install_path = "--- PATH ---\$package_name-$package_version.txt" -$source = "--- SOURCE ---" # used by the test to determine which source it was installed from - -if ($env:ChocolateyAllowEmptyChecksums) { - $allow_empty_checksums = $true -} else { - $allow_empty_checksums = $false -} -if ($env:ChocolateyIgnoreChecksums) { - $ignore_checksums = $true -} else { - $ignore_checksums = $false -} -if ($env:ChocolateyForce) { - $force = $true -} else { - $force = $false -} -if ($env:ChocolateyForceX86) { - $force_x86 = $true -} else { - $force_x86 = $false -} -if ($env:ChocolateyInstallOverride) { - $override_args = $true -} else { - $override_args = $false -} -#$process_env = Get-EnvironmentVariableNames -Scope Process -#$env_vars = @{} -#foreach ($name in $process_env) { -# $env_vars.$name = Get-EnvironmentVariable -Name $name -Scope Process -#} -$timeout = $env:chocolateyResponseTimeout - -$package_info = @{ - allow_empty_checksums = $allow_empty_checksums - #env_vars = $env_vars - force = $force - force_x86 = $force_x86 - ignore_checksums = $ignore_checksums - install_args = $env:ChocolateyInstallArguments - override_args = $override_args - package_params = Get-PackageParameters - proxy_url = $env:ChocolateyProxyLocation - source = $source - timeout = $timeout -} -$package_json = ConvertTo-Json -InputObject $package_info - -[System.IO.File]::WriteAllText($install_path, $package_json) diff --git a/test/integration/targets/win_chocolatey/tasks/main.yml b/test/integration/targets/win_chocolatey/tasks/main.yml deleted file mode 100644 index b50335a08b6..00000000000 --- a/test/integration/targets/win_chocolatey/tasks/main.yml +++ /dev/null @@ -1,110 +0,0 @@ ---- -- name: ensure test package is uninstalled - win_chocolatey: - name: '{{ test_choco_packages }}' - state: absent - -- name: ensure testing dir is cleaned - win_file: - path: '{{ test_choco_path }}' - state: '{{ item }}' - with_items: - - absent - - directory - -- name: copy template package files - win_copy: - src: files/ - dest: '{{ test_choco_path }}' - -# run the setup in 1 shell script to save on test time -- name: set up packages - win_shell: | - $ErrorActionPreference = "Stop" - $root_path = '{{ test_choco_path }}' - $packages_path = '{{ test_choco_source }}' - $packages_path_override = '{{ test_choco_source2 }}' - $packages = @( - @{ name = "ansible"; version = "0.0.1"; override = $false }, - @{ name = "ansible"; version = "0.1.0"; override = $false }, - @{ name = "ansible"; version = "0.1.0"; override = $true }, - @{ name = "ansible-test"; version = "1.0.0"; override = $false }, - @{ name = "ansible-test"; version = "1.0.1-beta1"; override = $false } - ) - $nuspec_src = "$root_path\package.nuspec" - $install_src = "$root_path\tools\chocolateyinstall.ps1" - $uninstall_src = "$root_path\tools\chocolateyUninstall.ps1" - - New-Item -Path $packages_path -ItemType Directory > $null - New-Item -Path $packages_path_override -ItemType Directory > $null - - foreach ($package in $packages) { - $package_dir = "$root_path\$($package.name)-$($package.version)" - New-Item -Path $package_dir -ItemType Directory > $null - New-Item -Path "$package_dir\tools" -ItemType Directory > $null - - if ($package.override) { - $out_path = $packages_path_override - $source_value = "override" - } else { - $out_path = $packages_path - $source_value = "normal" - } - - $nuspec_text = ([System.IO.File]::ReadAllLines($nuspec_src) -join "`r`n") - $nuspec_text = $nuspec_text.Replace('--- NAME ---', $package.name).Replace('--- VERSION ---', $package.version) - - $install_text = ([System.IO.File]::ReadAllLines($install_src) -join "`r`n") - $install_text = $install_text.Replace('--- PATH ---', $root_path).Replace('--- SOURCE ---', $source_value) - - $uninstall_text = ([System.IO.File]::ReadAllLines($uninstall_src) -join "`r`n") - $uninstall_text = $uninstall_text.Replace('--- PATH ---', $root_path) - - $utf8 = New-Object -TypeName System.Text.UTF8Encoding -ArgumentList $false - $utf8_bom = New-Object -TypeName System.Text.UTF8Encoding -ArgumentList $true - [System.IO.File]::WriteAllText("$package_dir\$($package.name).nuspec", $nuspec_text, $utf8) - [System.IO.File]::WriteAllText("$package_dir\tools\chocolateyinstall.ps1", $install_text, $utf8_bom) - [System.IO.File]::WriteAllText("$package_dir\tools\chocolateyUninstall.ps1", $uninstall_text, $utf8_bom) - - &choco.exe pack --out $out_path --no-progress --limit-output "$package_dir\$($package.name).nuspec" - Remove-Item -Path $package_dir -Force -Recurse > $null - } - Remove-Item -Path "$root_path\tools" -Force -Recurse > $null - Remove-Item -Path $nuspec_src > $null - -- name: set up Chocolatey sources - win_chocolatey_source: - name: '{{ item.name }}' - priority: '{{ item.priority }}' - source: '{{ item.src }}' - state: present - with_items: - - name: ansible-test - priority: 1 - src: '{{ test_choco_source }}' - - name: ansible-test-override - priority: 2 - src: '{{ test_choco_source2 }}' - -- block: - - name: run tests - include_tasks: tests.yml - - always: - - name: ensure test package is uninstalled after tests - win_chocolatey: - name: '{{ test_choco_packages }}' - state: absent - - - name: remove test sources - win_chocolatey_source: - name: '{{ item }}' - state: absent - with_items: - - ansible-test - - ansible-test-override - - - name: remove testing dir - win_file: - path: '{{ test_choco_path }}' - state: absent diff --git a/test/integration/targets/win_chocolatey/tasks/tests.yml b/test/integration/targets/win_chocolatey/tasks/tests.yml deleted file mode 100644 index 5eb20163405..00000000000 --- a/test/integration/targets/win_chocolatey/tasks/tests.yml +++ /dev/null @@ -1,610 +0,0 @@ ---- -- name: raise failure when state=present and name=all - win_chocolatey: - name: all - state: present - register: fail_all_present - failed_when: fail_all_present.msg != "Cannot specify the package name as 'all' when state=present" - -- name: raise failure when state=reinstalled and name=all - win_chocolatey: - name: all - state: reinstalled - register: fail_all_reinstalled - failed_when: fail_all_reinstalled.msg != "Cannot specify the package name as 'all' when state=reinstalled" - -- name: install package (check mode) - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: present - check_mode: yes - register: install_check - -- name: get result of install package (check mode) - win_command: choco.exe list --local-only --exact --limit-output {{ test_choco_package1|quote }} - register: install_actual_check - failed_when: not install_actual_check.rc in [0, 2] # v0.10.12+ returns 2 for no package - -- name: assert install package (check mode) - assert: - that: - - install_check is changed - - install_actual_check.stdout_lines == [] - -- name: install package - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: present - register: install - -- name: get result of install package - win_command: choco.exe list --local-only --exact --limit-output {{ test_choco_package1|quote }} - register: install_actual - -- name: get package info of install package - win_shell: Get-Content -Path '{{ test_choco_path }}\{{ test_choco_package1 }}-0.1.0.txt' -Raw - register: install_actual_info - -- name: assert install package - assert: - that: - - install is changed - - install_actual.stdout_lines == [test_choco_package1 + "|0.1.0"] - - (install_actual_info.stdout|from_json).allow_empty_checksums == False - - (install_actual_info.stdout|from_json).force == False - - (install_actual_info.stdout|from_json).force_x86 == False - - (install_actual_info.stdout|from_json).ignore_checksums == False - - (install_actual_info.stdout|from_json).install_args == None - - (install_actual_info.stdout|from_json).override_args == False - - (install_actual_info.stdout|from_json).package_params == {} - - (install_actual_info.stdout|from_json).proxy_url == None - - (install_actual_info.stdout|from_json).source == "normal" - - (install_actual_info.stdout|from_json).timeout == "2700000" - -- name: install package (idempotent) - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: present - register: install_again - -- name: assert install package (idempotent) - assert: - that: - - not install_again is changed - -- name: remove package (check mode) - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: absent - check_mode: yes - register: remove_check - -- name: get result of remove package (check mode) - win_command: choco.exe list --local-only --exact --limit-output {{ test_choco_package1|quote }} - register: remove_actual_check - -- name: assert remove package (check mode) - assert: - that: - - remove_check is changed - - remove_actual_check.stdout_lines == [test_choco_package1 + "|0.1.0"] - -- name: remove package - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: absent - register: remove - -- name: get result of remove package - win_command: choco.exe list --local-only --exact --limit-output {{ test_choco_package1|quote }} - register: remove_actual - failed_when: not remove_actual.rc in [0, 2] - -- name: check if removed package file still exists - win_stat: - path: '{{ test_choco_path }}\{{ test_choco_package1 }}-0.1.0.txt' - register: remove_actual_info - -- name: assert remove package - assert: - that: - - remove is changed - - remove_actual.stdout_lines == [] - - remove_actual_info.stat.exists == False - -- name: remove package (idempotent) - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: absent - register: remove_again - -- name: assert remove_package (idempotent) - assert: - that: - - not remove_again is changed - -- name: install multiple packages with timeout - win_chocolatey: - name: '{{ test_choco_packages }}' - state: present - timeout: 1000 - register: install_multiple - -- name: get list of installed packages with timeout - win_command: choco.exe list --local-only --limit-output ansible - register: install_multiple_actual - -- name: get info on package 1 - win_shell: Get-Content -Path '{{ test_choco_path }}\{{ test_choco_package1 }}-0.1.0.txt' -Raw - register: install_multiple_package1 - -- name: get info on package 2 - win_shell: Get-Content -Path '{{ test_choco_path }}\{{ test_choco_package2 }}-1.0.0.txt' -Raw - register: install_multiple_package2 - -- name: assert install multiple packages with timeout - assert: - that: - - install_multiple is changed - - install_multiple_actual.stdout_lines == [test_choco_package1 + "|0.1.0", test_choco_package2 + "|1.0.0"] - - (install_multiple_package1.stdout|from_json).allow_empty_checksums == False - - (install_multiple_package1.stdout|from_json).force == False - - (install_multiple_package1.stdout|from_json).force_x86 == False - - (install_multiple_package1.stdout|from_json).ignore_checksums == False - - (install_multiple_package1.stdout|from_json).install_args == None - - (install_multiple_package1.stdout|from_json).override_args == False - - (install_multiple_package1.stdout|from_json).package_params == {} - - (install_multiple_package1.stdout|from_json).proxy_url == None - - (install_multiple_package1.stdout|from_json).source == "normal" - - (install_multiple_package1.stdout|from_json).timeout == "1000000" - - (install_multiple_package2.stdout|from_json).allow_empty_checksums == False - - (install_multiple_package2.stdout|from_json).force == False - - (install_multiple_package2.stdout|from_json).force_x86 == False - - (install_multiple_package2.stdout|from_json).ignore_checksums == False - - (install_multiple_package2.stdout|from_json).install_args == None - - (install_multiple_package2.stdout|from_json).override_args == False - - (install_multiple_package2.stdout|from_json).package_params == {} - - (install_multiple_package2.stdout|from_json).proxy_url == None - - (install_multiple_package2.stdout|from_json).source == "normal" - - (install_multiple_package2.stdout|from_json).timeout == "1000000" - -- name: install multiple packages (idempotent) - win_chocolatey: - name: '{{ test_choco_packages }}' - state: present - register: install_multiple_again - -- name: assert install multiple packages (idempotent) - assert: - that: - - not install_multiple_again is changed - -- name: remove multiple packages - win_chocolatey: - name: '{{ test_choco_packages }}' - state: absent - register: remove_multiple - -- name: get list of installed packages after removal - win_command: choco.exe list --local-only --limit-output ansible - register: remove_multiple_actual - failed_when: not remove_multiple_actual.rc in [0, 2] - -- name: get info on package 1 - win_stat: - path: '{{ test_choco_path }}\{{ test_choco_package1 }}-0.1.0.txt' - register: remove_multiple_package1 - -- name: get info on package 2 - win_stat: - path: '{{ test_choco_path }}\{{ test_choco_package2 }}-1.0.0.txt' - register: remove_multiple_package2 - -- name: assert remove multiple packages - assert: - that: - - remove_multiple is changed - - remove_multiple_actual.stdout_lines == [] - - remove_multiple_package1.stat.exists == False - - remove_multiple_package2.stat.exists == False - -- name: remove multiple packages (idempotent) - win_chocolatey: - name: '{{ test_choco_packages }}' - state: absent - register: remove_multiple_again - -- name: assert remove multiple packages (idempotent) - assert: - that: - - not remove_multiple_again is changed - -- name: install package with params - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: present - install_args: /install_arg 1 /install_arg 2 - override_args: yes - package_params: /param1 /param2:value - allow_empty_checksums: yes - architecture: x86 - force: yes - ignore_checksums: yes - proxy_url: http://proxyhost - version: 0.0.1 - register: install_params - -- name: get result of install package with params - win_command: choco.exe list --local-only --limit-output --exact {{ test_choco_package1|quote }} - register: install_params_actual - -- name: get info of install package with params - win_shell: Get-Content -Path '{{ test_choco_path }}\{{ test_choco_package1 }}-0.0.1.txt' - register: install_params_info - -- name: assert install package with params - assert: - that: - - install_params is changed - - install_params_actual.stdout_lines == [test_choco_package1 + "|0.0.1"] - - (install_params_info.stdout|from_json).allow_empty_checksums == True - - (install_params_info.stdout|from_json).force == True - - (install_params_info.stdout|from_json).force_x86 == True - - (install_params_info.stdout|from_json).ignore_checksums == True - - (install_params_info.stdout|from_json).install_args == "/install_arg 1 /install_arg 2" - - (install_params_info.stdout|from_json).override_args == True - - (install_params_info.stdout|from_json).package_params.keys()|count == 2 - - (install_params_info.stdout|from_json).package_params.param1 == True - - (install_params_info.stdout|from_json).package_params.param2 == "value" - - (install_params_info.stdout|from_json).proxy_url == "http://proxyhost" - - (install_params_info.stdout|from_json).source == "normal" - - (install_params_info.stdout|from_json).timeout == "2700000" - -- name: install package with version (idempotent) - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: present - version: 0.0.1 - register: install_with_version - -- name: assert install package with version (idempotent) - assert: - that: - - not install_with_version is changed - -- name: fail to install side by side package - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: present - version: 0.1.0 - register: fail_multiple_versions - failed_when: fail_multiple_versions.msg != "Chocolatey package '" + test_choco_package1 + "' is already installed with version(s) '0.0.1' but was expecting '0.1.0'. Either change the expected version, set state=latest, set allow_multiple=yes, or set force=yes to continue" - -- name: force the upgrade of an existing version - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: present - version: 0.1.0 - force: yes - register: force_different_version - -- name: get result of force the upgrade of an existing version - win_command: choco.exe list --local-only --limit-output --exact {{ test_choco_package1|quote }} - register: force_different_version_actual - -- name: get result of forced package install file - win_stat: - path: '{{ test_choco_path }}\{{ test_choco_package1 }}-0.1.0.txt' - register: force_different_version_info - -- name: assert force the upgrade of an existing version - assert: - that: - - force_different_version is changed - - force_different_version_actual.stdout_lines == [test_choco_package1 + "|0.1.0"] - - force_different_version_info.stat.exists - -- name: remove package after force clobbered everything - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: absent - ignore_errors: yes # the mock package created doesn't really handle force well - -- name: install package with reference to source name - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: present - source: ansible-test-override - register: install_source_name - -- name: get result of install package with reference to source name - win_command: choco.exe list --local-only --limit-output --exact {{ test_choco_package1|quote }} - register: install_source_name_actual - -- name: get result fo installed package with reference to source name info - win_shell: Get-Content -Path '{{ test_choco_path }}\{{ test_choco_package1 }}-0.1.0.txt' -Raw - register: install_source_name_info - -- name: assert install package with reference to source name - assert: - that: - - install_source_name is changed - - install_source_name_actual.stdout_lines == [test_choco_package1 + "|0.1.0"] - - (install_source_name_info.stdout|from_json).source == "override" - -- name: reinstall package without source override - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: reinstalled - register: reinstalled_package - -- name: get result of reinstalled package without source override - win_shell: Get-Content -Path '{{ test_choco_path }}\{{ test_choco_package1 }}-0.1.0.txt' -Raw - register: reinstalled_package_info - -- name: assert reinstall package without source override - assert: - that: - - reinstalled_package is changed - - (reinstalled_package_info.stdout|from_json).source == "normal" - -- name: downgrade package - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: downgrade - version: 0.0.1 - register: downgraded_package - -- name: get result of downgrade package - win_command: choco.exe list --local-only --limit-output --exact {{ test_choco_package1|quote }} - register: downgraded_package_actual - -- name: assert downgrade package - assert: - that: - - downgraded_package is changed - - downgraded_package_actual.stdout_lines == [test_choco_package1 + "|0.0.1"] - -- name: downgrade package (idempotent) - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: downgrade - version: 0.0.1 - register: downgraded_package_again - -- name: assert downgrade package (idempotent) - assert: - that: - - not downgraded_package_again is changed - -- name: downgrade package without version specified - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: downgrade - register: downgrade_without_version - -- name: get result of downgrade without version - win_command: choco.exe list --local-only --limit-output --exact {{ test_choco_package1|quote }} - register: downgrade_without_version_actual - -- name: assert downgrade package without version specified - assert: - that: - - not downgrade_without_version is changed - - downgrade_without_version_actual.stdout_lines == [test_choco_package1 + "|0.0.1"] - -- name: upgrade package - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: latest - register: upgrade_package - -- name: get result of upgrade package - win_command: choco.exe list --local-only --limit-output --exact {{ test_choco_package1|quote }} - register: upgrade_package_actual - -- name: assert upgrade package - assert: - that: - - upgrade_package is changed - - upgrade_package_actual.stdout_lines == [test_choco_package1 + "|0.1.0"] - -- name: upgrade package (idempotent) - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: latest - register: upgrade_package_again - -- name: assert upgrade package (idempotent) - assert: - that: - - not upgrade_package_again is changed - -- name: install prerelease package - win_chocolatey: - name: '{{ test_choco_package2 }}' - state: present - allow_prerelease: yes - register: install_prerelease - -- name: get result of install prerelease package - win_command: choco.exe list --local-only --limit-output --exact {{ test_choco_package2|quote }} - register: install_prerelease_actual - -- name: assert install prerelease package - assert: - that: - - install_prerelease is changed - - install_prerelease_actual.stdout_lines == [test_choco_package2 + "|1.0.1-beta1"] - -- name: downgrade package - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: downgrade - version: 0.0.1 - -- name: upgrade all packages - win_chocolatey: - name: all - state: latest - register: all_latest - -- name: get result of upgrade all packages - win_command: choco.exe list --local-only --limit-output --exact {{ test_choco_package1|quote }} - register: all_latest_actual - -- name: assert upgrade all packages - assert: - that: - - all_latest is changed - - all_latest_actual.stdout_lines == [test_choco_package1 + "|0.1.0"] - -- name: install newer version of package - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: present - -- name: install older package with allow_multiple - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: present - allow_multiple: True - version: '0.0.1' - register: allow_multiple - -- name: get result of install older package with allow_multiple - win_command: choco.exe list --local-only --limit-output --all-versions - register: allow_multiple_actual - -- name: assert install older package with allow_multiple - assert: - that: - - allow_multiple is changed - - '"ansible|0.1.0" in allow_multiple_actual.stdout_lines' - - '"ansible|0.0.1" in allow_multiple_actual.stdout_lines' - -- name: pin 2 packages (check mode) - win_chocolatey: - name: - - '{{ test_choco_package1 }}' - - '{{ test_choco_package2 }}' - state: present - pinned: yes - register: pin_multiple_check - check_mode: True - -- name: get result of pin 2 packages (check mode) - win_command: choco.exe pin list --limit-output - register: pin_multiple_actual_check - -- name: assert pin 2 packages (check mode) - assert: - that: - - pin_multiple_check is changed - - pin_multiple_actual_check.stdout == "" - -- name: pin 2 packages - win_chocolatey: - name: - - '{{ test_choco_package1 }}' - - '{{ test_choco_package2 }}' - state: present - pinned: yes - register: pin_multiple - -- name: get result of pin 2 packages - win_command: choco.exe pin list --limit-output - register: pin_multiple_actual - -- name: assert pin 2 packages - assert: - that: - - pin_multiple is changed - - pin_multiple_actual.stdout_lines == ["ansible|0.1.0", "ansible-test|1.0.1-beta1"] - -- name: pin 2 packages (idempotent) - win_chocolatey: - name: - - '{{ test_choco_package1 }}' - - '{{ test_choco_package2 }}' - state: present - pinned: yes - register: pin_multiple_again - -- name: assert pin 2 packages (idempoent) - assert: - that: - - not pin_multiple_again is changed - -- name: pin specific older version - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: present - pinned: yes - version: '0.0.1' - register: pin_older - -- name: get result of pin specific older version - win_command: choco.exe pin list --limit-output - register: pin_older_actual - -- name: assert pin specific older version - assert: - that: - - pin_older is changed - - pin_older_actual.stdout_lines == ["ansible|0.1.0", "ansible|0.0.1", "ansible-test|1.0.1-beta1"] - -- name: unpin package at version - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: present - pinned: no - version: '0.1.0' - register: unpin_version - -- name: get result of unpin package at version - win_command: choco.exe pin list --limit-output - register: unpin_version_actual - -- name: assert unpin package at version - assert: - that: - - unpin_version is changed - - unpin_version_actual.stdout_lines == ["ansible|0.0.1", "ansible-test|1.0.1-beta1"] - -- name: unpin multiple packages without a version - win_chocolatey: - name: - - '{{ test_choco_package1 }}' - - '{{ test_choco_package2 }}' - state: present - pinned: no - register: unpin_multiple - -- name: get result of unpin multiple packages without a version - win_command: choco.exe pin list --limit-output - register: unpin_multiple_actual - -- name: assert unpin multiple packages without a version - assert: - that: - - unpin_multiple is changed - - unpin_multiple_actual.stdout == "" - -- name: uninstall specific version installed with allow_multiple - win_chocolatey: - name: '{{ test_choco_package1 }}' - state: absent - version: '0.0.1' - register: remove_multiple - -- name: get result of uninstall specific version installed with allow_multiple - win_command: choco.exe list --local-only --limit-output --all-versions - register: remove_multiple_actual - -- name: assert uninstall specific version installed with allow_multiple - assert: - that: - - remove_multiple is changed - - '"ansible|0.0.1" not in remove_multiple_actual.stdout_lines' - - '"ansible|0.1.0" in remove_multiple_actual.stdout_lines' diff --git a/test/integration/targets/win_chocolatey_config/aliases b/test/integration/targets/win_chocolatey_config/aliases deleted file mode 100644 index 4cd27b3cb2f..00000000000 --- a/test/integration/targets/win_chocolatey_config/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group1 diff --git a/test/integration/targets/win_chocolatey_config/tasks/main.yml b/test/integration/targets/win_chocolatey_config/tasks/main.yml deleted file mode 100644 index 046ed78a1e2..00000000000 --- a/test/integration/targets/win_chocolatey_config/tasks/main.yml +++ /dev/null @@ -1,32 +0,0 @@ ---- -- name: ensure Chocolatey is installed - win_chocolatey: - name: chocolatey - state: present - -- name: create a copy of the existing config file - win_copy: - src: C:\ProgramData\chocolatey\config\chocolatey.config - dest: C:\ProgramData\chocolatey\config\chocolatey.config.ansiblebak - remote_src: yes - -- name: unset config setting as baseline - win_chocolatey_config: - name: cacheLocation - state: absent - -- block: - - name: run tests - include_tasks: tests.yml - - always: - - name: restore config file - win_copy: - src: C:\ProgramData\chocolatey\config\chocolatey.config.ansiblebak - dest: C:\ProgramData\chocolatey\config\chocolatey.config - remote_src: yes - - - name: remove the backup config file - win_file: - path: C:\ProgramData\chocolatey\config\chocolatey.config.ansiblebak - state: absent diff --git a/test/integration/targets/win_chocolatey_config/tasks/tests.yml b/test/integration/targets/win_chocolatey_config/tasks/tests.yml deleted file mode 100644 index 3ed538e8381..00000000000 --- a/test/integration/targets/win_chocolatey_config/tasks/tests.yml +++ /dev/null @@ -1,141 +0,0 @@ ---- -- name: fail if value is not set and state=present - win_chocolatey_config: - name: cacheLocation - state: present - register: fail_no_value - failed_when: 'fail_no_value.msg != "Get-AnsibleParam: Missing required argument: value"' - -- name: fail to set invalid config name - win_chocolatey_config: - name: fake - state: present - value: value - register: fail_invalid_name - failed_when: '"The Chocolatey config ''fake'' is not an existing config value, check the spelling. Valid config names: " not in fail_invalid_name.msg' - -- name: set config setting (check mode) - win_chocolatey_config: - name: cacheLocation - state: present - value: C:\temp - check_mode: yes - register: set_check - -- name: get actual config setting (check mode) - win_command: choco.exe config get -r --name cacheLocation - register: set_actual_check - -- name: assert set config setting (check mode) - assert: - that: - - set_check is changed - - set_actual_check.stdout_lines == [""] - -- name: set config setting - win_chocolatey_config: - name: cacheLocation - state: present - value: C:\temp - register: set - -- name: get actual config setting - win_command: choco.exe config get -r --name cacheLocation - register: set_actual - -- name: assert set config setting - assert: - that: - - set is changed - - set_actual.stdout_lines == ["C:\\temp"] - -- name: change config value (check mode) - win_chocolatey_config: - name: cacheLocation - state: present - value: C:\temp2 - check_mode: yes - register: change_check - -- name: get actual config setting (check mode) - win_command: choco.exe config get -r --name cacheLocation - register: change_actual_check - -- name: assert change config value (check mode) - assert: - that: - - change_check is changed - - change_actual_check.stdout_lines == ["C:\\temp"] - -- name: change config value - win_chocolatey_config: - name: cacheLocation - state: present - value: C:\temp2 - register: change - -- name: get actual config setting - win_command: choco.exe config get -r --name cacheLocation - register: change_actual - -- name: assert change config value - assert: - that: - - change is changed - - change_actual.stdout_lines == ["C:\\temp2"] - -- name: change config value (idempotent) - win_chocolatey_config: - name: cacheLocation - state: present - value: C:\temp2 - register: change_again - -- name: assert change config value (idempotent) - assert: - that: - - not change_again is changed - -- name: unset config value (check mode) - win_chocolatey_config: - name: cacheLocation - state: absent - check_mode: yes - register: unset_check - -- name: get actual config setting (check mode) - win_command: choco.exe config get -r --name cacheLocation - register: unset_actual_check - -- name: assert unset config value (check mode) - assert: - that: - - unset_check is changed - - unset_actual_check.stdout_lines == ["C:\\temp2"] - -- name: unset config value - win_chocolatey_config: - name: cacheLocation - state: absent - register: unset - -- name: get actual config setting - win_command: choco.exe config get -r --name cacheLocation - register: unset_actual - -- name: assert unset config value - assert: - that: - - unset is changed - - unset_actual.stdout_lines == [""] - -- name: unset config value (idempotent) - win_chocolatey_config: - name: cacheLocation - state: absent - register: unset_again - -- name: assert unset config value (idempotent) - assert: - that: - - not unset_again is changed diff --git a/test/integration/targets/win_chocolatey_facts/aliases b/test/integration/targets/win_chocolatey_facts/aliases deleted file mode 100644 index 4c08975b17d..00000000000 --- a/test/integration/targets/win_chocolatey_facts/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group6 diff --git a/test/integration/targets/win_chocolatey_facts/tasks/main.yml b/test/integration/targets/win_chocolatey_facts/tasks/main.yml deleted file mode 100644 index 8f2b458034f..00000000000 --- a/test/integration/targets/win_chocolatey_facts/tasks/main.yml +++ /dev/null @@ -1,69 +0,0 @@ ---- -- name: ensure Chocolatey is installed - win_chocolatey: - name: chocolatey - state: present - -- name: create test source - win_chocolatey_source: - name: test|repo # use a pipe as that's a delimiter with Chocolatey, test edge case - state: disabled - admin_only: yes - allow_self_service: yes - bypass_proxy: yes - priority: 9 - source: http://test-server/chocolatey - source_username: test-user - source_password: password - certificate: C:\temp\cert.pfx - - -- name: set a config value - win_chocolatey_config: - name: proxyUser - state: present - value: test-user - -- block: - - name: Gather facts from chocolatey - win_chocolatey_facts: - - always: - - name: remove test source - win_chocolatey_source: - name: test|repo - state: absent - - - name: unset config value - win_chocolatey_config: - name: proxyUser - state: absent - -- name: assert facts from chocolatey - assert: - that: - - ansible_chocolatey is not changed - - ansible_chocolatey.config.commandExecutionTimeoutSeconds == 2700 - - ansible_chocolatey.config.proxyBypassOnLocal == True - - ansible_chocolatey.config.proxyUser == 'test-user' - - ansible_chocolatey.feature.checksumFiles == true - - ansible_chocolatey.packages[0].package == 'chocolatey' - - ansible_chocolatey.packages[0].version is defined - - ansible_chocolatey.sources[0].admin_only == False - - ansible_chocolatey.sources[0].allow_self_service == False - - ansible_chocolatey.sources[0].bypass_proxy == False - - ansible_chocolatey.sources[0].certificate == None - - ansible_chocolatey.sources[0].disabled == False - - ansible_chocolatey.sources[0].name == 'chocolatey' - - ansible_chocolatey.sources[0].priority == 0 - - ansible_chocolatey.sources[0].source == 'https://chocolatey.org/api/v2/' - - ansible_chocolatey.sources[0].source_username == None - - ansible_chocolatey.sources[1].admin_only == True - - ansible_chocolatey.sources[1].allow_self_service == True - - ansible_chocolatey.sources[1].bypass_proxy == True - - ansible_chocolatey.sources[1].certificate == 'C:\\temp\\cert.pfx' - - ansible_chocolatey.sources[1].disabled == True - - ansible_chocolatey.sources[1].name == 'test|repo' - - ansible_chocolatey.sources[1].priority == 9 - - ansible_chocolatey.sources[1].source == 'http://test-server/chocolatey' - - ansible_chocolatey.sources[1].source_username == 'test-user' diff --git a/test/integration/targets/win_chocolatey_feature/aliases b/test/integration/targets/win_chocolatey_feature/aliases deleted file mode 100644 index 4cd27b3cb2f..00000000000 --- a/test/integration/targets/win_chocolatey_feature/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group1 diff --git a/test/integration/targets/win_chocolatey_feature/filter_plugins/choco_checksum_state.py b/test/integration/targets/win_chocolatey_feature/filter_plugins/choco_checksum_state.py deleted file mode 100644 index 8dff044d1a3..00000000000 --- a/test/integration/targets/win_chocolatey_feature/filter_plugins/choco_checksum_state.py +++ /dev/null @@ -1,14 +0,0 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - - -def choco_checksum_state(value): - return [i for i in value if i.startswith("checksumFiles|")][0].split("|")[1] == "Enabled" - - -class FilterModule(object): - - def filters(self): - return { - 'choco_checksum_state': choco_checksum_state - } diff --git a/test/integration/targets/win_chocolatey_feature/tasks/main.yml b/test/integration/targets/win_chocolatey_feature/tasks/main.yml deleted file mode 100644 index c2100be01f8..00000000000 --- a/test/integration/targets/win_chocolatey_feature/tasks/main.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- -- name: ensure Chocolatey is installed - win_chocolatey: - name: chocolatey - state: present - -- name: ensure we start from a baseline for test feature - win_chocolatey_feature: - name: checksumFiles - state: disabled - -- block: - - name: run tests - include_tasks: tests.yml - - always: - - name: set feature back to enabled - win_chocolatey_feature: - name: checksumFiles - state: enabled diff --git a/test/integration/targets/win_chocolatey_feature/tasks/tests.yml b/test/integration/targets/win_chocolatey_feature/tasks/tests.yml deleted file mode 100644 index 94bbb7a9cef..00000000000 --- a/test/integration/targets/win_chocolatey_feature/tasks/tests.yml +++ /dev/null @@ -1,95 +0,0 @@ ---- -- name: fail on invalid feature - win_chocolatey_feature: - name: failFeature - state: enabled - register: fail_res - failed_when: '"Invalid feature name ''failFeature'' specified, valid features are: " not in fail_res.msg' - -- name: enable disabled feature (check mode) - win_chocolatey_feature: - name: checksumFiles - state: enabled - check_mode: yes - register: enable_check - -- name: get actual state of feature (check mode) - win_command: choco.exe feature list -r - register: enable_actual_check - -- name: assert enable disabled feature (check mode) - assert: - that: - - enable_check is changed - - enable_actual_check.stdout_lines|choco_checksum_state == False - -- name: enable disabled feature - win_chocolatey_feature: - name: checksumFiles - state: enabled - register: enable - -- name: get actual state of feature - win_command: choco.exe feature list -r - register: enable_actual - -- name: assert enable disabled feature - assert: - that: - - enable is changed - - enable_actual.stdout_lines|choco_checksum_state == True - -- name: enable disabled feature (idempotent) - win_chocolatey_feature: - name: checksumFiles - state: enabled - register: enable_again - -- name: assert enable disabled feature (idempotent) - assert: - that: - - not enable_again is changed - -- name: disable enabled feature (check mode) - win_chocolatey_feature: - name: checksumFiles - state: disabled - check_mode: yes - register: disable_check - -- name: get actual state of feature (check mode) - win_command: choco.exe feature list -r - register: disable_actual_check - -- name: assert disable enabled feature (check mode) - assert: - that: - - disable_check is changed - - disable_actual_check.stdout_lines|choco_checksum_state == True - -- name: disable enabled feature - win_chocolatey_feature: - name: checksumFiles - state: disabled - register: disable - -- name: get actual state of feature - win_command: choco.exe feature list -r - register: disable_actual - -- name: assert disable enabled feature - assert: - that: - - disable is changed - - disable_actual.stdout_lines|choco_checksum_state == False - -- name: disable enabled feature (idempotent) - win_chocolatey_feature: - name: checksumFiles - state: disabled - register: disable_again - -- name: assert disable enabled feature (idempotent) - assert: - that: - - not disable_again is changed diff --git a/test/integration/targets/win_chocolatey_source/aliases b/test/integration/targets/win_chocolatey_source/aliases deleted file mode 100644 index 4cd27b3cb2f..00000000000 --- a/test/integration/targets/win_chocolatey_source/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group1 diff --git a/test/integration/targets/win_chocolatey_source/defaults/main.yml b/test/integration/targets/win_chocolatey_source/defaults/main.yml deleted file mode 100644 index 0d8c67825e0..00000000000 --- a/test/integration/targets/win_chocolatey_source/defaults/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -# use some weird chars to test out the parser -test_chocolatey_name: test'|"source 123^ diff --git a/test/integration/targets/win_chocolatey_source/library/choco_source.ps1 b/test/integration/targets/win_chocolatey_source/library/choco_source.ps1 deleted file mode 100644 index 5724c6f0c2e..00000000000 --- a/test/integration/targets/win_chocolatey_source/library/choco_source.ps1 +++ /dev/null @@ -1,65 +0,0 @@ -#!powershell - -# Copyright: (c) 2019, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$result = @{ - changed = $false - sources = [System.Collections.Generic.List`1[System.Collections.Hashtable]]@() -} - -$choco_app = Get-Command -Name choco.exe -CommandType Application -$choco_config_path = "$(Split-Path -Path (Split-Path -Path $choco_app.Path))\config\chocolatey.config" - -[xml]$choco_config = Get-Content -LiteralPath $choco_config_path -foreach ($xml_source in $choco_config.chocolatey.sources.GetEnumerator()) { - $source_username = $xml_source.Attributes.GetNamedItem("user") - if ($null -ne $source_username) { - $source_username = $source_username.Value - } - - # 0.9.9.9+ - $priority = $xml_source.Attributes.GetNamedItem("priority") - if ($null -ne $priority) { - $priority = [int]$priority.Value - } - - # 0.9.10+ - $certificate = $xml_source.Attributes.GetNamedItem("certificate") - if ($null -ne $certificate) { - $certificate = $certificate.Value - } - - # 0.10.4+ - $bypass_proxy = $xml_source.Attributes.GetNamedItem("bypassProxy") - if ($null -ne $bypass_proxy) { - $bypass_proxy = [System.Convert]::ToBoolean($bypass_proxy.Value) - } - $allow_self_service = $xml_source.Attributes.GetNamedItem("selfService") - if ($null -ne $allow_self_service) { - $allow_self_service = [System.Convert]::ToBoolean($allow_self_service.Value) - } - - # 0.10.8+ - $admin_only = $xml_source.Attributes.GetNamedItem("adminOnly") - if ($null -ne $admin_only) { - $admin_only = [System.Convert]::ToBoolean($admin_only.Value) - } - - $source_info = @{ - name = $xml_source.id - source = $xml_source.value - disabled = [System.Convert]::ToBoolean($xml_source.disabled) - source_username = $source_username - priority = $priority - certificate = $certificate - bypass_proxy = $bypass_proxy - allow_self_service = $allow_self_service - admin_only = $admin_only - } - $result.sources.Add($source_info) -} - -Exit-Json -obj $result diff --git a/test/integration/targets/win_chocolatey_source/tasks/main.yml b/test/integration/targets/win_chocolatey_source/tasks/main.yml deleted file mode 100644 index 0b57cc55548..00000000000 --- a/test/integration/targets/win_chocolatey_source/tasks/main.yml +++ /dev/null @@ -1,31 +0,0 @@ ---- -- name: ensure Chocolatey is installed - win_chocolatey: - name: chocolatey - state: present - -- name: remove original Chocolatey source at the start of the test - win_chocolatey_source: - name: Chocolatey - state: absent - -- name: ensure test Chocolatey source is removed - win_chocolatey_source: - name: '{{ test_chocolatey_name }}' - state: absent - -- block: - - name: run tests - include_tasks: tests.yml - - always: - - name: ensure original Chocolatey source is re-added - win_chocolatey_source: - name: Chocolatey - source: https://chocolatey.org/api/v2/ - state: present - - - name: remove test Chocolatey source - win_chocolatey_source: - name: '{{ test_chocolatey_name }}' - state: absent diff --git a/test/integration/targets/win_chocolatey_source/tasks/tests.yml b/test/integration/targets/win_chocolatey_source/tasks/tests.yml deleted file mode 100644 index 0bf9763c425..00000000000 --- a/test/integration/targets/win_chocolatey_source/tasks/tests.yml +++ /dev/null @@ -1,373 +0,0 @@ ---- -- name: create source (check mode) - win_chocolatey_source: - name: chocolatey - source: https://chocolatey.org/api/v2/ - state: present - register: create_check - check_mode: yes - -- name: check if source exists (check mode) - choco_source: - register: create_actual_check - -- name: assert create source (check mode) - assert: - that: - - create_check is changed - - create_actual_check.sources == [] - -- name: create source - win_chocolatey_source: - name: chocolatey - source: https://chocolatey.org/api/v2/ - state: present - register: create - -- name: check if source exists - choco_source: - register: create_actual - -- name: assert create source - assert: - that: - - create is changed - - create_actual.sources|length == 1 - - create_actual.sources[0].name == 'chocolatey' - - create_actual.sources[0].source == 'https://chocolatey.org/api/v2/' - - create_actual.sources[0].disabled == False - - create_actual.sources[0].source_username == None - - create_actual.sources[0].priority == 0 - - create_actual.sources[0].certificate == None - - create_actual.sources[0].bypass_proxy == False - - create_actual.sources[0].allow_self_service == False - - create_actual.sources[0].admin_only == False - -- name: create source (idempotent) - win_chocolatey_source: - name: chocolatey - source: https://chocolatey.org/api/v2/ - state: present - register: create_again - -- name: assert create source (idempotent) - assert: - that: - - not create_again is changed - -- name: remove source (check mode) - win_chocolatey_source: - name: chocolatey - state: absent - register: remove_check - check_mode: yes - -- name: check if source is removed (check mode) - choco_source: - register: remove_actual_check - -- name: assert remove source (check mode) - assert: - that: - - remove_check is changed - - remove_actual_check.sources == create_actual.sources - -- name: remove source - win_chocolatey_source: - name: chocolatey - state: absent - register: remove - -- name: check if source is removed - choco_source: - register: remove_actual - -- name: assert remove source - assert: - that: - - remove is changed - - remove_actual.sources == [] - -- name: remove source (idempotent) - win_chocolatey_source: - name: chocolatey - state: absent - register: remove_again - -- name: assert remove source (idempotent) - assert: - that: - - not remove_again is changed - -- name: create a disabled service (check mode) - win_chocolatey_source: - name: '{{ test_chocolatey_name }}' - source: C:\chocolatey repos - source_username: username - source_password: password - certificate: C:\cert.pfx - certificate_password: password - bypass_proxy: yes - priority: 1 - state: disabled - register: create_special_check - check_mode: yes - -- name: check if source is created (check mode) - choco_source: - register: create_special_actual_check - -- name: assert create a disabled service (check mode) - assert: - that: - - create_special_check is changed - - create_special_actual_check.sources == [] - -- name: create a disabled service - win_chocolatey_source: - name: '{{ test_chocolatey_name }}' - source: C:\chocolatey repos - source_username: username - source_password: password - certificate: C:\cert.pfx - certificate_password: password - bypass_proxy: yes - priority: 1 - state: disabled - register: create_special - -- name: check if source is created - choco_source: - register: create_special_actual - -- name: assert create a disabled service - assert: - that: - - create_special is changed - - create_special_actual.sources|length == 1 - - create_special_actual.sources[0].name == test_chocolatey_name - - create_special_actual.sources[0].source == 'C:\\chocolatey repos' - - create_special_actual.sources[0].disabled == True - - create_special_actual.sources[0].source_username == 'username' - - create_special_actual.sources[0].priority == 1 - - create_special_actual.sources[0].certificate == 'C:\\cert.pfx' - - create_special_actual.sources[0].bypass_proxy == True - - create_special_actual.sources[0].allow_self_service == False - - create_special_actual.sources[0].admin_only == False - -- name: create a disabled service pass always update - win_chocolatey_source: - name: '{{ test_chocolatey_name }}' - source: C:\chocolatey repos - source_username: username - source_password: password - certificate: C:\cert.pfx - certificate_password: password - bypass_proxy: yes - priority: 1 - state: disabled - register: create_special_pass_always - -- name: assert create a disabled service pass always update - assert: - that: - - create_special_pass_always is changed - -- name: create a disabled service (idempotent) - win_chocolatey_source: - name: '{{ test_chocolatey_name }}' - source: C:\chocolatey repos - source_username: username - source_password: password - certificate: C:\cert.pfx - certificate_password: password - bypass_proxy: yes - priority: 1 - state: disabled - update_password: on_create - register: create_special_again - -- name: assert create a disabled service (idempotent) - assert: - that: - - not create_special_again is changed - -- name: edit an existing source (check mode) - win_chocolatey_source: - name: '{{ test_chocolatey_name }}' - source: C:\chocolatey repos2 - source_username: username2 - source_password: password2 - certificate: C:\cert2.pfx - priority: '5' - state: present - update_password: on_create - admin_only: yes - allow_self_service: yes - register: modify_source_check - check_mode: yes - -- name: check if source is changed (check mode) - choco_source: - register: modify_source_check_actual - -- name: assert edit an existing source (check mode) - assert: - that: - - modify_source_check is changed - - modify_source_check_actual.sources == create_special_actual.sources - -- name: edit an existing source - win_chocolatey_source: - name: '{{ test_chocolatey_name }}' - source: C:\chocolatey repos2 - source_username: username2 - source_password: password2 - certificate: C:\cert2.pfx - priority: '5' - state: present - update_password: on_create - admin_only: yes - allow_self_service: yes - register: modify_source - -- name: check if source is changed - choco_source: - register: modify_source_actual - -- name: assert edit an existing source - assert: - that: - - modify_source is changed - - modify_source_actual.sources[0].name == test_chocolatey_name - - modify_source_actual.sources[0].source == 'C:\\chocolatey repos2' - - modify_source_actual.sources[0].disabled == False - - modify_source_actual.sources[0].source_username == 'username2' - - modify_source_actual.sources[0].priority == 5 - - modify_source_actual.sources[0].certificate == 'C:\\cert2.pfx' - - modify_source_actual.sources[0].bypass_proxy == False - - modify_source_actual.sources[0].allow_self_service == True - - modify_source_actual.sources[0].admin_only == True - -- name: edit an existing source (idempotent) - win_chocolatey_source: - name: '{{ test_chocolatey_name }}' - source: C:\chocolatey repos2 - source_username: username2 - source_password: password2 - certificate: C:\cert2.pfx - priority: '5' - state: present - update_password: on_create - admin_only: yes - allow_self_service: yes - register: modify_source_again - -- name: assert edit an existing source (idempotent) - assert: - that: - - not modify_source_again is changed - -- name: disable source (check mode) - win_chocolatey_source: - name: '{{ test_chocolatey_name }}' - state: disabled - register: disable_source_check - check_mode: True - -- name: get result of disable source (check mode) - choco_source: - register: disable_source_actual_check - -- name: assert disable source (check mode) - assert: - that: - - disable_source_check is changed - - disable_source_actual_check.sources == modify_source_actual.sources - -- name: disable source - win_chocolatey_source: - name: '{{ test_chocolatey_name }}' - state: disabled - register: disable_source - -- name: get result of disable source - choco_source: - register: disable_source_actual - -- name: assert disable source - assert: - that: - - disable_source is changed - - disable_source_actual.sources[0].name == test_chocolatey_name - - disable_source_actual.sources[0].source == 'C:\\chocolatey repos2' - - disable_source_actual.sources[0].disabled == True - - disable_source_actual.sources[0].source_username == 'username2' - - disable_source_actual.sources[0].priority == 5 - - disable_source_actual.sources[0].certificate == 'C:\\cert2.pfx' - - disable_source_actual.sources[0].bypass_proxy == False - - disable_source_actual.sources[0].allow_self_service == True - - disable_source_actual.sources[0].admin_only == True - -- name: disable source (idempotent) - win_chocolatey_source: - name: '{{ test_chocolatey_name }}' - state: disabled - register: disable_source_again - -- name: assert disable source (idempotent) - assert: - that: - - not disable_source_again is changed - -- name: enable source (check mode) - win_chocolatey_source: - name: '{{ test_chocolatey_name }}' - state: present - register: enable_source_check - check_mode: True - -- name: get result of enable source (check mode) - choco_source: - register: enable_source_actual_check - -- name: assert enable source (check mode) - assert: - that: - - enable_source_check is changed - - enable_source_actual_check.sources == disable_source_actual.sources - -- name: enable source - win_chocolatey_source: - name: '{{ test_chocolatey_name }}' - state: present - register: enable_source - -- name: get result of enable source - choco_source: - register: enable_source_actual - -- name: assert enable source - assert: - that: - - enable_source is changed - - enable_source_actual.sources[0].name == test_chocolatey_name - - enable_source_actual.sources[0].source == 'C:\\chocolatey repos2' - - enable_source_actual.sources[0].disabled == False - - enable_source_actual.sources[0].source_username == 'username2' - - enable_source_actual.sources[0].priority == 5 - - enable_source_actual.sources[0].certificate == 'C:\\cert2.pfx' - - enable_source_actual.sources[0].bypass_proxy == False - - enable_source_actual.sources[0].allow_self_service == True - - enable_source_actual.sources[0].admin_only == True - -- name: enable source (idempotent) - win_chocolatey_source: - name: '{{ test_chocolatey_name }}' - state: present - register: enable_source_again - -- name: assert enable source (idempotent) - assert: - that: - - not enable_source_again is changed diff --git a/test/integration/targets/win_computer_description/aliases b/test/integration/targets/win_computer_description/aliases deleted file mode 100644 index eca3c7641ae..00000000000 --- a/test/integration/targets/win_computer_description/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group3 -skip/windows/2008 diff --git a/test/integration/targets/win_computer_description/defaults/main.yml b/test/integration/targets/win_computer_description/defaults/main.yml deleted file mode 100644 index 166a5248c22..00000000000 --- a/test/integration/targets/win_computer_description/defaults/main.yml +++ /dev/null @@ -1,6 +0,0 @@ -test_description: This is my computer -test_organization: iddqd -test_owner: BFG -test_description2: This is not my computer -test_organization2: idkfa -test_owner2: CACODEMON diff --git a/test/integration/targets/win_computer_description/tasks/main.yml b/test/integration/targets/win_computer_description/tasks/main.yml deleted file mode 100644 index 95e5deda8d6..00000000000 --- a/test/integration/targets/win_computer_description/tasks/main.yml +++ /dev/null @@ -1,200 +0,0 @@ ---- -- name: Blank out description, organization and owner - win_computer_description: - description: "" - organization: "" - owner: "" - register: blank_set - check_mode: no - -- name: Change description, organization and owner in check mode - win_computer_description: - description: "{{ test_description }}" - organization: "{{ test_organization }}" - owner: "{{ test_owner }}" - register: change1_checkmode - check_mode: yes - -- name: Change description, organization and owner - win_computer_description: - description: "{{ test_description }}" - organization: "{{ test_organization }}" - owner: "{{ test_owner }}" - register: change1_set - check_mode: no - -- name: Change description, organization and owner 2nd time, there should be no change happening - win_computer_description: - description: "{{ test_description }}" - organization: "{{ test_organization }}" - owner: "{{ test_owner }}" - register: change1_set2 - check_mode: no - -- name: Assert that the above tasks returned the expected results - assert: - that: - - change1_checkmode is changed - - change1_set is changed - - change1_set2 is not changed - -- name: Get machine description - win_shell: (Get-CimInstance -class "Win32_OperatingSystem").description - register: description1_changed - -- name: Get organization name - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion - name: RegisteredOrganization - register: organization1_changed - -- name: Get owner - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion - name: RegisteredOwner - register: owner1_changed - -- name: Assert that retrieved values are equal to the values provided in the variables - assert: - that: - - description1_changed.stdout == "{{ test_description }}\r\n" - - organization1_changed.value == "{{ test_organization }}" - - owner1_changed.value == "{{ test_owner }}" - -- name: Change description and owner only in check mode - win_computer_description: - description: "{{ test_description2 }}" - owner: "{{ test_owner2 }}" - register: change2_checkmode - check_mode: yes - -- name: Change description and owner only - win_computer_description: - description: "{{ test_description2 }}" - owner: "{{ test_owner2 }}" - register: change2_set - check_mode: no - -- name: Change description and owner only 2nd time, there should be no change happening - win_computer_description: - description: "{{ test_description2 }}" - owner: "{{ test_owner2 }}" - register: change2_set2 - check_mode: no - -- name: Assert that the above tasks returned the expected results - assert: - that: - - change2_checkmode is changed - - change2_set is changed - - change2_set2 is not changed - -- name: Get machine description - win_shell: (Get-CimInstance -class "Win32_OperatingSystem").description - register: description2_changed - -- name: Get organization name - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion - name: RegisteredOrganization - register: organization2_changed - -- name: Get owner - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion - name: RegisteredOwner - register: owner2_changed - -- name: Assert that retrieved values are equal to the desired values - assert: - that: - - description2_changed.stdout == "{{ test_description2 }}\r\n" - - organization2_changed.value == "{{ test_organization }}" - - owner2_changed.value == "{{ test_owner2 }}" - -- name: Change organization only in check mode - win_computer_description: - organization: "{{ test_organization2 }}" - register: change3_checkmode - check_mode: yes - -- name: Change organization only in check mode - win_computer_description: - organization: "{{ test_organization2 }}" - register: change3_set - check_mode: no - -- name: Change organization only in check mode - win_computer_description: - organization: "{{ test_organization2 }}" - register: change3_set2 - check_mode: no - -- name: Assert that the above tasks returned the expected results - assert: - that: - - change3_checkmode is changed - - change3_set is changed - - change3_set2 is not changed - -- name: Get machine description - win_shell: (Get-CimInstance -class "Win32_OperatingSystem").description - register: description3_changed - -- name: Get organization name - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion - name: RegisteredOrganization - register: organization3_changed - -- name: Get owner - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion - name: RegisteredOwner - register: owner3_changed - -- name: Assert that retrieved values are equal to the desired values - assert: - that: - - description3_changed.stdout == "{{ test_description2 }}\r\n" - - organization3_changed.value == "{{ test_organization2 }}" - - owner3_changed.value == "{{ test_owner2 }}" - -- name: Try to apply the same values again in check mode, there should be no change - win_computer_description: - description: "{{ test_description2 }}" - organization: "{{ test_organization2 }}" - owner: "{{ test_owner2 }}" - register: change4_checkmode - check_mode: yes - -- name: Try to apply the same values again, there should be no change - win_computer_description: - description: "{{ test_description2 }}" - organization: "{{ test_organization2 }}" - owner: "{{ test_owner2 }}" - register: change4_set - check_mode: no - -- name: Try to apply the same values again for 2nd time, there should be no change - win_computer_description: - description: "{{ test_description2 }}" - organization: "{{ test_organization2 }}" - owner: "{{ test_owner2 }}" - register: change4_set2 - check_mode: no - -- name: Assert that the above tasks returned the expected results - assert: - that: - - change4_checkmode is not changed - - change4_set is not changed - - change4_set2 is not changed - -- name: Blank the test values - win_computer_description: - description: '' - organization: '' - owner: '' - register: blank2_set - check_mode: no diff --git a/test/integration/targets/win_credential/aliases b/test/integration/targets/win_credential/aliases deleted file mode 100644 index 6036e173f1a..00000000000 --- a/test/integration/targets/win_credential/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group7 diff --git a/test/integration/targets/win_credential/defaults/main.yml b/test/integration/targets/win_credential/defaults/main.yml deleted file mode 100644 index c6dffc0a0f5..00000000000 --- a/test/integration/targets/win_credential/defaults/main.yml +++ /dev/null @@ -1,19 +0,0 @@ -# The certificate in files/cert.pfx was generated with the following commands -# -# cat > client.cnf <Hop}Xorr<0{1dOpLu62kx_}tt}(uqLS*Ca-9&tZ6aVbAwkK93K` zzedIbelF?^D4FItV9Y0PvRP1!cP(MilK}3ht6vkJG>b}2I31!RHtv*=*Qp9X;9l%2 zbv$q<7F*>C?A^jFL824UpIT;Csd_vqpUWD_RbHni(n_9_h}^e@zDuZnnCC_;MuP+O z`y>l};;X1dTwT=hLnHVjq;?0rRN^xFPI7JG+k}k}H{8vLb zS}*0eH;}kxxK~)x`>86|aq4{hib9=Ll;lU9n=1>$r9ssBt;vKzJkZ*3W9-E?eYjha zLUc3QNeI*gYpn8{

#JS~I2j4m>ga5JwgCD(Bi`Eu zyHtUI8_Vc_VjfTysr91QX`w7g8FMo^@sKAv;~689V+<^=zAHmLF>&My9ISY8VCs!tgB zeNBaNp(QrikP5)ObOJ#64icf!XzTbXNN}}pO#W!b_euKc%1Hy+$~uB&VTUmSY1_*R zk?(!rRHj%4c@fnx&yMSC8RVBrtd*IX`qOZ^_kZg}BR-EggHbsF2bN^H%wK<}^T-|6 z{+gJLg!-F#ZC@ABi}H`X;ZPV=XrG51ka@EtRuT$$o+^SyzQYIyJa6)E!vd$AiQ%2& zfDClK!Q0P%DFXnzQmTYsq(gl&uiH5iw|lSev~!&xC;1lKshwn5L}rzBA-&5f&|}V~TV(lLG{w5V<5OL)nAPjge5x4_GDOwPP0h|v82@4 zoEepSSSVkq=5mWUx1xuoPC4l>!bTRP#gLyni1}KbnHdyHXPn-3(9IhwJ~Gho_!rZz z0`=HkuinuOtueh4t8|UJd**TD4VJ|<;#pP5%zrF}LWUSmU?1;LFNz0w2tT7h*N;=* zS(DJNpb0FoFd^1_>&L zNQU2D^)|66tMv-C(Du_ghe z(@bav$CSe-+Fn9Ym1S@|IuM7+F3MdRW?dSsU&&=qP55>l{x%Zh0OoAGX!XNh^NPDa zFq6v-1B>TOCXbVFx7z6Y<~c#o$aG=V{(}bW=vjR1u*v%`MH_{=)`NmYi763YtT5$p z2(|`H*Vgbk`-= zV7*sDAS)>1E1xGDuQ6^ZzV<5h5orL*S%z5v8$%wmu69*GK5#^S4s^(6`@M#4+%xbb z9T#Ow8s?bbOCB&Kafa1J2@;$=9HhCJu*S<6GUTtuuAn81zn)8iuJOUCqztC88|fGl z>=y!ugs!gGs(cXix+HX-Wr^Lhf?5Kx9%x|Lb07;jwfnZ4o>Zj*#_7@3eK52s!q7&v zDGc!uQVsf*wZ>>*v>_!pD+#X$ECkC)3owB1_clqOw_r-F770Y3b5~7WmloZ3tW?li zmz#F5$BP^oqkab37d6=^Mr9@&Y=whpG zp2$41Dd!;Dzh@jm0X^u3;@fjI*pSZs?eNZo_3q}tmSS8}U(KULCWlFLa_iUHfAvKL zdGawOFe3&DDuzgg_YDCF6)_eB6jp>9uiY8f-$zT@B+wm*y?`a43NSG+AutIB1uG5% r0vZJX1Qbo#Sgm&8g-pvy$IG~H+`F>d6eI))aBl98 attributes = new List(); - if (v.AttributeCount > 0) - { - CREDENTIAL_ATTRIBUTE[] rawAttributes = new CREDENTIAL_ATTRIBUTE[v.AttributeCount]; - Credential.PtrToStructureArray(rawAttributes, v.Attributes); - attributes = rawAttributes.Select(x => (CredentialAttribute)x).ToList(); - } - - string userName = v.UserName; - if (v.Type == CredentialType.DomainCertificate || v.Type == CredentialType.GenericCertificate) - userName = Credential.UnmarshalCertificateCredential(userName); - - return new Credential - { - Type = v.Type, - TargetName = v.TargetName, - Comment = v.Comment, - LastWritten = (DateTimeOffset)v.LastWritten, - Secret = secret, - Persist = v.Persist, - Attributes = attributes, - TargetAlias = v.TargetAlias, - UserName = userName, - Loaded = true, - }; - } - } - - [StructLayout(LayoutKind.Sequential)] - public struct CREDENTIAL_ATTRIBUTE - { - [MarshalAs(UnmanagedType.LPWStr)] public string Keyword; - public UInt32 Flags; // Set to 0 and is reserved - public UInt32 ValueSize; - public IntPtr Value; - - public static explicit operator CredentialAttribute(CREDENTIAL_ATTRIBUTE v) - { - byte[] value = new byte[v.ValueSize]; - Marshal.Copy(v.Value, value, 0, (int)v.ValueSize); - - return new CredentialAttribute - { - Keyword = v.Keyword, - Flags = v.Flags, - Value = value, - }; - } - } - - [StructLayout(LayoutKind.Sequential)] - public struct FILETIME - { - internal UInt32 dwLowDateTime; - internal UInt32 dwHighDateTime; - - public static implicit operator long(FILETIME v) { return ((long)v.dwHighDateTime << 32) + v.dwLowDateTime; } - public static explicit operator DateTimeOffset(FILETIME v) { return DateTimeOffset.FromFileTime(v); } - public static explicit operator FILETIME(DateTimeOffset v) - { - return new FILETIME() - { - dwLowDateTime = (UInt32)v.ToFileTime(), - dwHighDateTime = ((UInt32)v.ToFileTime() >> 32), - }; - } - } - - [Flags] - public enum CredentialCreateFlags : uint - { - PreserveCredentialBlob = 1, - } - - [Flags] - public enum CredentialFlags - { - None = 0, - PromptNow = 2, - UsernameTarget = 4, - } - - public enum CredMarshalType : uint - { - CertCredential = 1, - UsernameTargetCredential, - BinaryBlobCredential, - UsernameForPackedCredential, - BinaryBlobForSystem, - } - } - - internal class NativeMethods - { - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool CredDeleteW( - [MarshalAs(UnmanagedType.LPWStr)] string TargetName, - CredentialType Type, - UInt32 Flags); - - [DllImport("advapi32.dll")] - public static extern void CredFree( - IntPtr Buffer); - - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool CredMarshalCredentialW( - NativeHelpers.CredMarshalType CredType, - SafeMemoryBuffer Credential, - out SafeCredentialBuffer MarshaledCredential); - - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool CredReadW( - [MarshalAs(UnmanagedType.LPWStr)] string TargetName, - CredentialType Type, - UInt32 Flags, - out SafeCredentialBuffer Credential); - - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool CredUnmarshalCredentialW( - [MarshalAs(UnmanagedType.LPWStr)] string MarshaledCredential, - out NativeHelpers.CredMarshalType CredType, - out SafeCredentialBuffer Credential); - - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool CredWriteW( - NativeHelpers.CREDENTIAL Credential, - NativeHelpers.CredentialCreateFlags Flags); - } - - internal class SafeCredentialBuffer : SafeHandleZeroOrMinusOneIsInvalid - { - public SafeCredentialBuffer() : base(true) { } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected override bool ReleaseHandle() - { - NativeMethods.CredFree(handle); - return true; - } - } - - internal class SafeMemoryBuffer : SafeHandleZeroOrMinusOneIsInvalid - { - public SafeMemoryBuffer() : base(true) { } - public SafeMemoryBuffer(int cb) : base(true) - { - base.SetHandle(Marshal.AllocHGlobal(cb)); - } - public SafeMemoryBuffer(IntPtr handle) : base(true) - { - base.SetHandle(handle); - } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected override bool ReleaseHandle() - { - Marshal.FreeHGlobal(handle); - return true; - } - } - - public class Win32Exception : System.ComponentModel.Win32Exception - { - private string _exception_msg; - public Win32Exception(string message) : this(Marshal.GetLastWin32Error(), message) { } - public Win32Exception(int errorCode, string message) : base(errorCode) - { - _exception_msg = String.Format("{0} - {1} (Win32 Error Code {2}: 0x{3})", message, base.Message, errorCode, errorCode.ToString("X8")); - } - public override string Message { get { return _exception_msg; } } - public static explicit operator Win32Exception(string message) { return new Win32Exception(message); } - } - - public enum CredentialPersist - { - Session = 1, - LocalMachine = 2, - Enterprise = 3, - } - - public enum CredentialType - { - Generic = 1, - DomainPassword = 2, - DomainCertificate = 3, - DomainVisiblePassword = 4, - GenericCertificate = 5, - DomainExtended = 6, - Maximum = 7, - MaximumEx = 1007, - } - - public class CredentialAttribute - { - public string Keyword; - public UInt32 Flags; - public byte[] Value; - } - - public class Credential - { - public CredentialType Type; - public string TargetName; - public string Comment; - public DateTimeOffset LastWritten; - public byte[] Secret; - public CredentialPersist Persist; - public List Attributes = new List(); - public string TargetAlias; - public string UserName; - - // Used to track whether the credential has been loaded into the store or not - public bool Loaded { get; internal set; } - - public void Delete() - { - if (!Loaded) - return; - - if (!NativeMethods.CredDeleteW(TargetName, Type, 0)) - throw new Win32Exception(String.Format("CredDeleteW({0}) failed", TargetName)); - Loaded = false; - } - - public void Write(bool preserveExisting) - { - string userName = UserName; - // Convert the certificate thumbprint to the string expected - if (Type == CredentialType.DomainCertificate || Type == CredentialType.GenericCertificate) - userName = Credential.MarshalCertificateCredential(userName); - - NativeHelpers.CREDENTIAL credential = new NativeHelpers.CREDENTIAL - { - Flags = NativeHelpers.CredentialFlags.None, - Type = Type, - TargetName = TargetName, - Comment = Comment, - LastWritten = new NativeHelpers.FILETIME(), - CredentialBlobSize = (UInt32)(Secret == null ? 0 : Secret.Length), - CredentialBlob = IntPtr.Zero, // Must be allocated and freed outside of this to ensure no memory leaks - Persist = Persist, - AttributeCount = (UInt32)(Attributes.Count), - Attributes = IntPtr.Zero, // Attributes must be allocated and freed outside of this to ensure no memory leaks - TargetAlias = TargetAlias, - UserName = userName, - }; - - using (SafeMemoryBuffer credentialBlob = new SafeMemoryBuffer((int)credential.CredentialBlobSize)) - { - if (Secret != null) - Marshal.Copy(Secret, 0, credentialBlob.DangerousGetHandle(), Secret.Length); - credential.CredentialBlob = credentialBlob.DangerousGetHandle(); - - // Store the CREDENTIAL_ATTRIBUTE value in a safe memory buffer and make sure we dispose in all cases - List attributeBuffers = new List(); - try - { - int attributeLength = Attributes.Sum(a => Marshal.SizeOf(typeof(NativeHelpers.CREDENTIAL_ATTRIBUTE))); - byte[] attributeBytes = new byte[attributeLength]; - int offset = 0; - foreach (CredentialAttribute attribute in Attributes) - { - SafeMemoryBuffer attributeBuffer = new SafeMemoryBuffer(attribute.Value.Length); - attributeBuffers.Add(attributeBuffer); - if (attribute.Value != null) - Marshal.Copy(attribute.Value, 0, attributeBuffer.DangerousGetHandle(), attribute.Value.Length); - - NativeHelpers.CREDENTIAL_ATTRIBUTE credentialAttribute = new NativeHelpers.CREDENTIAL_ATTRIBUTE - { - Keyword = attribute.Keyword, - Flags = attribute.Flags, - ValueSize = (UInt32)(attribute.Value == null ? 0 : attribute.Value.Length), - Value = attributeBuffer.DangerousGetHandle(), - }; - int attributeStructLength = Marshal.SizeOf(typeof(NativeHelpers.CREDENTIAL_ATTRIBUTE)); - - byte[] attrBytes = new byte[attributeStructLength]; - using (SafeMemoryBuffer tempBuffer = new SafeMemoryBuffer(attributeStructLength)) - { - Marshal.StructureToPtr(credentialAttribute, tempBuffer.DangerousGetHandle(), false); - Marshal.Copy(tempBuffer.DangerousGetHandle(), attrBytes, 0, attributeStructLength); - } - Buffer.BlockCopy(attrBytes, 0, attributeBytes, offset, attributeStructLength); - offset += attributeStructLength; - } - - using (SafeMemoryBuffer attributes = new SafeMemoryBuffer(attributeBytes.Length)) - { - if (attributeBytes.Length != 0) - Marshal.Copy(attributeBytes, 0, attributes.DangerousGetHandle(), attributeBytes.Length); - credential.Attributes = attributes.DangerousGetHandle(); - - NativeHelpers.CredentialCreateFlags createFlags = 0; - if (preserveExisting) - createFlags |= NativeHelpers.CredentialCreateFlags.PreserveCredentialBlob; - - if (!NativeMethods.CredWriteW(credential, createFlags)) - throw new Win32Exception(String.Format("CredWriteW({0}) failed", TargetName)); - } - } - finally - { - foreach (SafeMemoryBuffer attributeBuffer in attributeBuffers) - attributeBuffer.Dispose(); - } - } - Loaded = true; - } - - public static Credential GetCredential(string target, CredentialType type) - { - SafeCredentialBuffer buffer; - if (!NativeMethods.CredReadW(target, type, 0, out buffer)) - { - int lastErr = Marshal.GetLastWin32Error(); - - // Not running with CredSSP or Become so cannot manage the user's credentials - if (lastErr == 0x00000520) // ERROR_NO_SUCH_LOGON_SESSION - throw new InvalidOperationException("Failed to access the user's credential store, run the module with become or CredSSP"); - else if (lastErr == 0x00000490) // ERROR_NOT_FOUND - return null; - throw new Win32Exception(lastErr, "CredEnumerateW() failed"); - } - - using (buffer) - { - NativeHelpers.CREDENTIAL credential = (NativeHelpers.CREDENTIAL)Marshal.PtrToStructure( - buffer.DangerousGetHandle(), typeof(NativeHelpers.CREDENTIAL)); - return (Credential)credential; - } - } - - public static string MarshalCertificateCredential(string thumbprint) - { - // CredWriteW requires the UserName field to be the value of CredMarshalCredentialW() when writting a - // certificate auth. This converts the UserName property to the format required. - - // While CERT_CREDENTIAL_INFO is the correct structure, we manually marshal the data in order to - // support different cert hash lengths in the future. - // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/ns-wincred-_cert_credential_info - int hexLength = thumbprint.Length; - byte[] credInfo = new byte[sizeof(UInt32) + (hexLength / 2)]; - - // First field is cbSize which is a UInt32 value denoting the size of the total structure - Array.Copy(BitConverter.GetBytes((UInt32)credInfo.Length), credInfo, sizeof(UInt32)); - - // Now copy the byte representation of the thumbprint to the rest of the struct bytes - for (int i = 0; i < hexLength; i += 2) - credInfo[sizeof(UInt32) + (i / 2)] = Convert.ToByte(thumbprint.Substring(i, 2), 16); - - IntPtr pCredInfo = Marshal.AllocHGlobal(credInfo.Length); - Marshal.Copy(credInfo, 0, pCredInfo, credInfo.Length); - SafeMemoryBuffer pCredential = new SafeMemoryBuffer(pCredInfo); - - NativeHelpers.CredMarshalType marshalType = NativeHelpers.CredMarshalType.CertCredential; - using (pCredential) - { - SafeCredentialBuffer marshaledCredential; - if (!NativeMethods.CredMarshalCredentialW(marshalType, pCredential, out marshaledCredential)) - throw new Win32Exception("CredMarshalCredentialW() failed"); - using (marshaledCredential) - return Marshal.PtrToStringUni(marshaledCredential.DangerousGetHandle()); - } - } - - public static string UnmarshalCertificateCredential(string value) - { - NativeHelpers.CredMarshalType credType; - SafeCredentialBuffer pCredInfo; - if (!NativeMethods.CredUnmarshalCredentialW(value, out credType, out pCredInfo)) - throw new Win32Exception("CredUnmarshalCredentialW() failed"); - - using (pCredInfo) - { - if (credType != NativeHelpers.CredMarshalType.CertCredential) - throw new InvalidOperationException(String.Format("Expected unmarshalled cred type of CertCredential, received {0}", credType)); - - byte[] structSizeBytes = new byte[sizeof(UInt32)]; - Marshal.Copy(pCredInfo.DangerousGetHandle(), structSizeBytes, 0, sizeof(UInt32)); - UInt32 structSize = BitConverter.ToUInt32(structSizeBytes, 0); - - byte[] certInfoBytes = new byte[structSize]; - Marshal.Copy(pCredInfo.DangerousGetHandle(), certInfoBytes, 0, certInfoBytes.Length); - - StringBuilder hex = new StringBuilder((certInfoBytes.Length - sizeof(UInt32)) * 2); - for (int i = 4; i < certInfoBytes.Length; i++) - hex.AppendFormat("{0:x2}", certInfoBytes[i]); - - return hex.ToString().ToUpperInvariant(); - } - } - - internal static void PtrToStructureArray(T[] array, IntPtr ptr) - { - IntPtr ptrOffset = ptr; - for (int i = 0; i < array.Length; i++, ptrOffset = IntPtr.Add(ptrOffset, Marshal.SizeOf(typeof(T)))) - array[i] = (T)Marshal.PtrToStructure(ptrOffset, typeof(T)); - } - } -} -'@ - -$type = switch ($type) { - "domain_password" { [Ansible.CredentialManager.CredentialType]::DomainPassword } - "domain_certificate" { [Ansible.CredentialManager.CredentialType]::DomainCertificate } - "generic_password" { [Ansible.CredentialManager.CredentialType]::Generic } - "generic_certificate" { [Ansible.CredentialManager.CredentialType]::GenericCertificate } -} - -$credential = [Ansible.CredentialManager.Credential]::GetCredential($name, $type) -if ($null -ne $credential) { - $module.Result.exists = $true - $module.Result.alias = $credential.TargetAlias - $module.Result.attributes = [System.Collections.ArrayList]@() - $module.Result.comment = $credential.Comment - $module.Result.name = $credential.TargetName - $module.Result.persistence = $credential.Persist.ToString() - $module.Result.type = $credential.Type.ToString() - $module.Result.username = $credential.UserName - - if ($null -ne $credential.Secret) { - $module.Result.secret = [System.Convert]::ToBase64String($credential.Secret) - } else { - $module.Result.secret = $null - } - - foreach ($attribute in $credential.Attributes) { - $attribute_info = @{ - name = $attribute.Keyword - } - if ($null -ne $attribute.Value) { - $attribute_info.data = [System.Convert]::ToBase64String($attribute.Value) - } else { - $attribute_info.data = $null - } - $module.Result.attributes.Add($attribute_info) > $null - } -} else { - $module.Result.exists = $false -} - -$module.ExitJson() - diff --git a/test/integration/targets/win_credential/meta/main.yml b/test/integration/targets/win_credential/meta/main.yml deleted file mode 100644 index bdea853d75a..00000000000 --- a/test/integration/targets/win_credential/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: -- prepare_win_tests diff --git a/test/integration/targets/win_credential/tasks/main.yml b/test/integration/targets/win_credential/tasks/main.yml deleted file mode 100644 index 67f6b946f46..00000000000 --- a/test/integration/targets/win_credential/tasks/main.yml +++ /dev/null @@ -1,64 +0,0 @@ ---- -- name: ensure test dir is present - win_file: - path: '{{ test_credential_dir }}' - state: directory - -- name: copy the pfx certificate - win_copy: - src: cert.pfx - dest: '{{ test_credential_dir }}\cert.pfx' - -- name: import the pfx into the personal store - win_certificate_store: - path: '{{ test_credential_dir }}\cert.pfx' - state: present - store_location: CurrentUser - store_name: My - password: '{{ key_password }}' - vars: &become_vars - ansible_become: True - ansible_become_method: runas - ansible_become_user: '{{ ansible_user }}' - ansible_become_pass: '{{ ansible_password }}' - -- name: ensure test credentials are removed before testing - win_credential: - name: '{{ test_hostname }}' - type: '{{ item }}' - state: absent - vars: *become_vars - with_items: - - domain_password - - domain_certificate - - generic_password - - generic_certificate - -- block: - - name: run tests - include_tasks: tests.yml - - always: - - name: remove the pfx from the personal store - win_certificate_store: - state: absent - thumbprint: '{{ cert_thumbprint }}' - store_location: CurrentUser - store_name: My - - - name: remove test credentials - win_credential: - name: '{{ test_hostname }}' - type: '{{ item }}' - state: absent - vars: *become_vars - with_items: - - domain_password - - domain_certificate - - generic_password - - generic_certificate - - - name: remove test dir - win_file: - path: '{{ test_credential_dir }}' - state: absent diff --git a/test/integration/targets/win_credential/tasks/tests.yml b/test/integration/targets/win_credential/tasks/tests.yml deleted file mode 100644 index cec2cf0236e..00000000000 --- a/test/integration/targets/win_credential/tasks/tests.yml +++ /dev/null @@ -1,638 +0,0 @@ ---- -- name: fail to run the module without become - win_credential: - name: '{{ test_hostname }}' - type: domain_password - username: DOMAIN\username - secret: password - state: present - register: fail_no_become - failed_when: '"Failed to access the user''s credential store, run the module with become" not in fail_no_become.msg' - -- name: create domain user credential (check mode) - win_credential: - name: '{{ test_hostname }}' - type: domain_password - username: DOMAIN\username - secret: password - state: present - register: domain_user_check - check_mode: True - vars: &become_vars - ansible_become: True - ansible_become_method: runas - ansible_become_user: '{{ ansible_user }}' - ansible_become_pass: '{{ ansible_password }}' - -- name: get result of create domain user credential (check mode) - test_cred_facts: - name: '{{ test_hostname }}' - type: domain_password - register: domain_user_actual_check - vars: *become_vars - -- name: asset create domain user credential (check mode) - assert: - that: - - domain_user_check is changed - - not domain_user_actual_check.exists - -- name: create domain user credential - win_credential: - name: '{{ test_hostname }}' - type: domain_password - username: DOMAIN\username - secret: password - state: present - register: domain_user - vars: *become_vars - -- name: get result of create domain user credential - test_cred_facts: - name: '{{ test_hostname }}' - type: domain_password - register: domain_user_actual - vars: *become_vars - -- name: asset create domain user credential - assert: - that: - - domain_user is changed - - domain_user_actual.exists - - domain_user_actual.alias == None - - domain_user_actual.attributes == [] - - domain_user_actual.comment == None - - domain_user_actual.name == test_hostname - - domain_user_actual.persistence == "LocalMachine" - - domain_user_actual.secret == "" - - domain_user_actual.type == "DomainPassword" - - domain_user_actual.username == "DOMAIN\\username" - -- name: create domain user credential again always update - win_credential: - name: '{{ test_hostname }}' - type: domain_password - username: DOMAIN\username - secret: password - state: present - register: domain_user_again_always - vars: *become_vars - -- name: create domain user credential again on_create - win_credential: - name: '{{ test_hostname }}' - type: domain_password - username: DOMAIN\username - secret: password - update_secret: on_create - state: present - register: domain_user_again_on_create - vars: *become_vars - -- name: assert create domain user credential again - assert: - that: - - domain_user_again_always is changed - - not domain_user_again_on_create is changed - -- name: update credential (check mode) - win_credential: - name: '{{ test_hostname }}' - type: domain_password - username: DOMAIN\username2 - alias: ansible - attributes: - - name: attribute 1 - data: attribute 1 value - - name: attribute 2 - data: '{{ "attribute 2 value" | b64encode }}' - data_format: base64 - comment: Credential comment - persistence: enterprise - state: present - register: update_cred_check - check_mode: True - vars: *become_vars - -- name: get result of update credential (check mode) - test_cred_facts: - name: '{{ test_hostname }}' - type: domain_password - register: update_cred_actual_check - vars: *become_vars - -- name: assert update credential (check mode) - assert: - that: - - update_cred_check is changed - - update_cred_actual_check.exists - - update_cred_actual_check.alias == None - - update_cred_actual_check.attributes == [] - - update_cred_actual_check.comment == None - - update_cred_actual_check.name == test_hostname - - update_cred_actual_check.persistence == "LocalMachine" - - update_cred_actual_check.secret == "" - - update_cred_actual_check.type == "DomainPassword" - - update_cred_actual_check.username == "DOMAIN\\username" - -- name: update credential - win_credential: - name: '{{ test_hostname }}' - type: domain_password - username: DOMAIN\username2 - alias: ansible - attributes: - - name: attribute 1 - data: attribute 1 value - - name: attribute 2 - data: '{{ "attribute 2 value" | b64encode }}' - data_format: base64 - comment: Credential comment - persistence: enterprise - state: present - register: update_cred - vars: *become_vars - -- name: get result of update credential - test_cred_facts: - name: '{{ test_hostname }}' - type: domain_password - register: update_cred_actual - vars: *become_vars - -- name: assert update credential - assert: - that: - - update_cred is changed - - update_cred_actual.exists - - update_cred_actual.alias == "ansible" - - update_cred_actual.attributes|count == 2 - - update_cred_actual.attributes[0].name == "attribute 1" - - update_cred_actual.attributes[0].data == "attribute 1 value"|b64encode - - update_cred_actual.attributes[1].name == "attribute 2" - - update_cred_actual.attributes[1].data == "attribute 2 value"|b64encode - - update_cred_actual.comment == "Credential comment" - - update_cred_actual.name == test_hostname - - update_cred_actual.persistence == "Enterprise" - - update_cred_actual.secret == "" - - update_cred_actual.type == "DomainPassword" - - update_cred_actual.username == "DOMAIN\\username2" - -- name: update credential again - win_credential: - name: '{{ test_hostname }}' - type: domain_password - username: DOMAIN\username2 - alias: ansible - attributes: - - name: attribute 1 - data: attribute 1 value - - name: attribute 2 - data: '{{ "attribute 2 value" | b64encode }}' - data_format: base64 - comment: Credential comment - persistence: enterprise - state: present - register: update_cred_again - vars: *become_vars - -- name: assert update credential again - assert: - that: - - not update_cred_again is changed - -- name: add new attribute - win_credential: - name: '{{ test_hostname }}' - type: domain_password - username: DOMAIN\username2 - alias: ansible - attributes: - - name: attribute 1 - data: attribute 1 value - - name: attribute 2 - data: '{{ "attribute 2 value" | b64encode }}' - data_format: base64 - - name: attribute 3 - data: attribute 3 value - comment: Credential comment - persistence: enterprise - state: present - register: add_attribute - vars: *become_vars - -- name: get result of add new attribute - test_cred_facts: - name: '{{ test_hostname }}' - type: domain_password - register: add_attribute_actual - vars: *become_vars - -- name: assert add new attribute - assert: - that: - - add_attribute is changed - - add_attribute_actual.attributes|count == 3 - - add_attribute_actual.attributes[0].name == "attribute 1" - - add_attribute_actual.attributes[0].data == "attribute 1 value"|b64encode - - add_attribute_actual.attributes[1].name == "attribute 2" - - add_attribute_actual.attributes[1].data == "attribute 2 value"|b64encode - - add_attribute_actual.attributes[2].name == "attribute 3" - - add_attribute_actual.attributes[2].data == "attribute 3 value"|b64encode - -- name: remove attribute - win_credential: - name: '{{ test_hostname }}' - type: domain_password - username: DOMAIN\username2 - alias: ansible - attributes: - - name: attribute 1 - data: attribute 1 value - - name: attribute 2 - data: '{{ "attribute 2 value" | b64encode }}' - data_format: base64 - comment: Credential comment - persistence: enterprise - state: present - register: remove_attribute - vars: *become_vars - -- name: get result of remove attribute - test_cred_facts: - name: '{{ test_hostname }}' - type: domain_password - register: remove_attribute_actual - vars: *become_vars - -- name: assert remove attribute - assert: - that: - - remove_attribute is changed - - remove_attribute_actual.attributes|count == 2 - - remove_attribute_actual.attributes[0].name == "attribute 1" - - remove_attribute_actual.attributes[0].data == "attribute 1 value"|b64encode - - remove_attribute_actual.attributes[1].name == "attribute 2" - - remove_attribute_actual.attributes[1].data == "attribute 2 value"|b64encode - -- name: edit attribute - win_credential: - name: '{{ test_hostname }}' - type: domain_password - username: DOMAIN\username2 - alias: ansible - attributes: - - name: attribute 1 - data: attribute 1 value new - - name: attribute 2 - data: '{{ "attribute 2 value" | b64encode }}' - data_format: base64 - comment: Credential comment - persistence: enterprise - state: present - register: edit_attribute - vars: *become_vars - -- name: get result of edit attribute - test_cred_facts: - name: '{{ test_hostname }}' - type: domain_password - register: edit_attribute_actual - vars: *become_vars - -- name: assert remove attribute - assert: - that: - - edit_attribute is changed - - edit_attribute_actual.attributes|count == 2 - - edit_attribute_actual.attributes[0].name == "attribute 1" - - edit_attribute_actual.attributes[0].data == "attribute 1 value new"|b64encode - - edit_attribute_actual.attributes[1].name == "attribute 2" - - edit_attribute_actual.attributes[1].data == "attribute 2 value"|b64encode - -- name: remove credential (check mode) - win_credential: - name: '{{ test_hostname }}' - type: domain_password - state: absent - register: remove_cred_check - check_mode: True - vars: *become_vars - -- name: get result of remove credential (check mode) - test_cred_facts: - name: '{{ test_hostname }}' - type: domain_password - register: remove_cred_actual_check - vars: *become_vars - -- name: assert remove credential (check mode) - assert: - that: - - remove_cred_check is changed - - remove_cred_actual_check.exists - -- name: remove credential - win_credential: - name: '{{ test_hostname }}' - type: domain_password - state: absent - register: remove_cred - vars: *become_vars - -- name: get result of remove credential - test_cred_facts: - name: '{{ test_hostname }}' - type: domain_password - register: remove_cred_actual - vars: *become_vars - -- name: assert remove credential - assert: - that: - - remove_cred is changed - - not remove_cred_actual.exists - -- name: remove credential again - win_credential: - name: '{{ test_hostname }}' - type: domain_password - state: absent - register: remove_cred_again - vars: *become_vars - -- name: assert remove credential again - assert: - that: - - not remove_cred_again is changed - -# https://github.com/ansible/ansible/issues/67278 -- name: create credential with wildcard - win_credential: - name: '*.{{ test_hostname }}' - type: domain_password - username: DOMAIN\username - secret: password - state: present - persistence: enterprise - register: wildcard_cred - vars: *become_vars - -- name: get result of create credential with wildcard - test_cred_facts: - name: '*.{{ test_hostname }}' - type: domain_password - register: wildcard_cred_actual - vars: *become_vars - -- name: assert create credential with wildcard - assert: - that: - - wildcard_cred is changed - - wildcard_cred_actual.name == '*.' ~ test_hostname - -- name: remove credential with wildcard - win_credential: - name: '*.{{ test_hostname }}' - type: domain_password - state: absent - register: wildcard_remove - vars: *become_vars - -- name: get result of remove credential with wildcard - test_cred_facts: - name: '*.{{ test_hostname }}' - type: domain_password - register: wildcard_remove_actual - vars: *become_vars - -- name: assert remove credential with wildcard - assert: - that: - - wildcard_remove is changed - - not wildcard_remove_actual.exists - -- name: create generic password (check mode) - win_credential: - name: '{{ test_hostname }}' - type: generic_password - persistence: enterprise - username: genericuser - secret: genericpass - state: present - register: generic_password_check - check_mode: True - vars: *become_vars - -- name: get result of create generic password (check mode) - test_cred_facts: - name: '{{ test_hostname }}' - type: generic_password - register: generic_password_actual_check - vars: *become_vars - -- name: assert result of create generic password (check mode) - assert: - that: - - generic_password_check is changed - - not generic_password_actual_check.exists - -- name: create generic password - win_credential: - name: '{{ test_hostname }}' - type: generic_password - persistence: enterprise - username: genericuser - secret: genericpass - state: present - register: generic_password - vars: *become_vars - -- name: get result of create generic password - test_cred_facts: - name: '{{ test_hostname }}' - type: generic_password - register: generic_password_actual - vars: *become_vars - -- name: set encoded password result - set_fact: - encoded_pass: '{{ "genericpass" | string | b64encode(encoding="utf-16-le") }}' - -- name: assert create generic password - assert: - that: - - generic_password is changed - - generic_password_actual.exists - - generic_password_actual.alias == None - - generic_password_actual.attributes == [] - - generic_password_actual.comment == None - - generic_password_actual.name == test_hostname - - generic_password_actual.persistence == "Enterprise" - - generic_password_actual.secret == encoded_pass - - generic_password_actual.type == "Generic" - - generic_password_actual.username == "genericuser" - -- name: create generic password again - win_credential: - name: '{{ test_hostname }}' - type: generic_password - persistence: enterprise - username: genericuser - secret: genericpass - state: present - register: generic_password_again - vars: *become_vars - -- name: assert create generic password again - assert: - that: - - not generic_password_again is changed - -- name: fail to create certificate cred with invalid thumbprint - win_credential: - name: '{{ test_hostname }}' - type: domain_certificate - username: 00112233445566778899AABBCCDDEEFF00112233 - state: present - register: fail_invalid_cert - failed_when: fail_invalid_cert.msg != "Failed to find certificate with the thumbprint 00112233445566778899AABBCCDDEEFF00112233 in the CurrentUser\\My store" - vars: *become_vars - -- name: create domain certificate cred (check mode) - win_credential: - name: '{{ test_hostname }}' - type: domain_certificate - username: '{{ cert_thumbprint }}' - state: present - register: domain_cert_check - check_mode: True - vars: *become_vars - -- name: get result of create domain certificate cred (check mode) - test_cred_facts: - name: '{{ test_hostname }}' - type: domain_certificate - register: domain_cert_actual_check - vars: *become_vars - -- name: assert create domain certificate cred (check mode) - assert: - that: - - domain_cert_check is changed - - not domain_cert_actual_check.exists - -- name: create domain certificate cred - win_credential: - name: '{{ test_hostname }}' - type: domain_certificate - username: '{{ cert_thumbprint }}' - state: present - register: domain_cert - vars: *become_vars - -- name: get result of create domain certificate cred - test_cred_facts: - name: '{{ test_hostname }}' - type: domain_certificate - register: domain_cert_actual - vars: *become_vars - -- name: assert create domain certificate cred - assert: - that: - - domain_cert is changed - - domain_cert_actual.exists - - domain_cert_actual.alias == None - - domain_cert_actual.attributes == [] - - domain_cert_actual.comment == None - - domain_cert_actual.name == test_hostname - - domain_cert_actual.persistence == "LocalMachine" - - domain_cert_actual.secret == "" - - domain_cert_actual.type == "DomainCertificate" - - domain_cert_actual.username == cert_thumbprint - -- name: create domain certificate cred again - win_credential: - name: '{{ test_hostname }}' - type: domain_certificate - username: '{{ cert_thumbprint }}' - state: present - register: domain_cert_again - vars: *become_vars - -- name: assert create domain certificate cred again - assert: - that: - - not domain_cert_again is changed - -- name: create generic certificate cred (check mode) - win_credential: - name: '{{ test_hostname }}' - type: generic_certificate - username: '{{ cert_thumbprint }}' - secret: '{{ "pin code" | b64encode }}' - secret_format: base64 - state: present - register: generic_cert_check - check_mode: True - vars: *become_vars - -- name: get result of create generic certificate cred (check mode) - test_cred_facts: - name: '{{ test_hostname }}' - type: generic_certificate - register: generic_cert_actual_check - vars: *become_vars - -- name: assert create generic certificate cred (check mode) - assert: - that: - - generic_cert_check is changed - - not generic_cert_actual_check.exists - -- name: create generic certificate cred - win_credential: - name: '{{ test_hostname }}' - type: generic_certificate - username: '{{ cert_thumbprint }}' - secret: '{{ "pin code" | b64encode }}' - secret_format: base64 - state: present - register: generic_cert - vars: *become_vars - -- name: get result of create generic certificate cred - test_cred_facts: - name: '{{ test_hostname }}' - type: generic_certificate - register: generic_cert_actual - vars: *become_vars - -- name: assert create generic certificate cred - assert: - that: - - generic_cert is changed - - generic_cert_actual.exists - - generic_cert_actual.alias == None - - generic_cert_actual.attributes == [] - - generic_cert_actual.comment == None - - generic_cert_actual.name == test_hostname - - generic_cert_actual.persistence == "LocalMachine" - - generic_cert_actual.secret == "pin code" | b64encode - - generic_cert_actual.type == "GenericCertificate" - - generic_cert_actual.username == cert_thumbprint - -- name: create generic certificate cred again - win_credential: - name: '{{ test_hostname }}' - type: generic_certificate - username: '{{ cert_thumbprint }}' - state: present - register: generic_cert_again - vars: *become_vars - -- name: assert create generic certificate cred again - assert: - that: - - not generic_cert_again is changed diff --git a/test/integration/targets/win_data_deduplication/aliases b/test/integration/targets/win_data_deduplication/aliases deleted file mode 100644 index 5f7ed526d63..00000000000 --- a/test/integration/targets/win_data_deduplication/aliases +++ /dev/null @@ -1,4 +0,0 @@ -shippable/windows/group4 -skip/windows/2008 -skip/windows/2008-R2 -skip/windows/2012 diff --git a/test/integration/targets/win_data_deduplication/meta/main.yml b/test/integration/targets/win_data_deduplication/meta/main.yml deleted file mode 100644 index 9f37e96cd90..00000000000 --- a/test/integration/targets/win_data_deduplication/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: -- setup_remote_tmp_dir diff --git a/test/integration/targets/win_data_deduplication/tasks/main.yml b/test/integration/targets/win_data_deduplication/tasks/main.yml deleted file mode 100644 index ae6be90ecb9..00000000000 --- a/test/integration/targets/win_data_deduplication/tasks/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- include: pre_test.yml diff --git a/test/integration/targets/win_data_deduplication/tasks/pre_test.yml b/test/integration/targets/win_data_deduplication/tasks/pre_test.yml deleted file mode 100644 index f72955e46bf..00000000000 --- a/test/integration/targets/win_data_deduplication/tasks/pre_test.yml +++ /dev/null @@ -1,40 +0,0 @@ ---- -- set_fact: - AnsibleVhdx: '{{ remote_tmp_dir }}\AnsiblePart.vhdx' - -- name: Install FS-Data-Deduplication - win_feature: - name: FS-Data-Deduplication - include_sub_features: true - state: present - register: data_dedup_feat_reg - -- name: Reboot windows after the feature has been installed - win_reboot: - reboot_timeout: 3600 - when: - - data_dedup_feat_reg.success - - data_dedup_feat_reg.reboot_required - -- name: Copy VHDX scripts - win_template: - src: "{{ item.src }}" - dest: '{{ remote_tmp_dir }}\{{ item.dest }}' - loop: - - { src: partition_creation_script.j2, dest: partition_creation_script.txt } - - { src: partition_deletion_script.j2, dest: partition_deletion_script.txt } - -- name: Create partition - win_command: diskpart.exe /s {{ remote_tmp_dir }}\partition_creation_script.txt - -- name: Format T with NTFS - win_format: - drive_letter: T - file_system: ntfs - -- name: Run tests - block: - - include: tests.yml - always: - - name: Detach disk - win_command: diskpart.exe /s {{ remote_tmp_dir }}\partition_deletion_script.txt diff --git a/test/integration/targets/win_data_deduplication/tasks/tests.yml b/test/integration/targets/win_data_deduplication/tasks/tests.yml deleted file mode 100644 index 64a42927130..00000000000 --- a/test/integration/targets/win_data_deduplication/tasks/tests.yml +++ /dev/null @@ -1,47 +0,0 @@ ---- - -- name: Enable Data Deduplication on the T drive - check mode - win_data_deduplication: - drive_letter: "T" - state: present - settings: - no_compress: true - minimum_file_age_days: 2 - minimum_file_size: 0 - check_mode: yes - register: win_data_deduplication_enable_check_mode - -- name: Check that it was successful with a change - check mode - assert: - that: - - win_data_deduplication_enable_check_mode is changed - -- name: Enable Data Deduplication on the T drive - win_data_deduplication: - drive_letter: "T" - state: present - settings: - no_compress: true - minimum_file_age_days: 2 - minimum_file_size: 0 - register: win_data_deduplication_enable - -- name: Check that it was successful with a change - assert: - that: - - win_data_deduplication_enable is changed - -- name: Enable Data Deduplication on the T drive - win_data_deduplication: - drive_letter: "T" - state: present - settings: - no_compress: true - minimum_file_age_days: 2 - minimum_file_size: 0 - register: win_data_deduplication_enable_again - -- name: Check that it was successful without a change - assert: - that: - - win_data_deduplication_enable_again is not changed diff --git a/test/integration/targets/win_data_deduplication/templates/partition_creation_script.j2 b/test/integration/targets/win_data_deduplication/templates/partition_creation_script.j2 deleted file mode 100644 index 8e47fda95ba..00000000000 --- a/test/integration/targets/win_data_deduplication/templates/partition_creation_script.j2 +++ /dev/null @@ -1,11 +0,0 @@ -create vdisk file="{{ AnsibleVhdx }}" maximum=2000 type=fixed - -select vdisk file="{{ AnsibleVhdx }}" - -attach vdisk - -convert mbr - -create partition primary - -assign letter="T" diff --git a/test/integration/targets/win_data_deduplication/templates/partition_deletion_script.j2 b/test/integration/targets/win_data_deduplication/templates/partition_deletion_script.j2 deleted file mode 100644 index c2be9cd1446..00000000000 --- a/test/integration/targets/win_data_deduplication/templates/partition_deletion_script.j2 +++ /dev/null @@ -1,3 +0,0 @@ -select vdisk file="{{ AnsibleVhdx }}" - -detach vdisk diff --git a/test/integration/targets/win_disk_facts/aliases b/test/integration/targets/win_disk_facts/aliases deleted file mode 100644 index e4adbabbe27..00000000000 --- a/test/integration/targets/win_disk_facts/aliases +++ /dev/null @@ -1,3 +0,0 @@ -shippable/windows/group2 -skip/windows/2008 # The Storage PowerShell module was introduced in W2K12 -skip/windows/2008-R2 # The Storage PowerShell module was introduced in W2K12 diff --git a/test/integration/targets/win_disk_facts/tasks/main.yml b/test/integration/targets/win_disk_facts/tasks/main.yml deleted file mode 100644 index b4b4fecb94c..00000000000 --- a/test/integration/targets/win_disk_facts/tasks/main.yml +++ /dev/null @@ -1,13 +0,0 @@ -# NOTE: The win_disk_facts module only works on Win2012R2+ - -- name: check whether storage module is available (windows 2008 r2 or later) - win_shell: '(Get-Module -Name Storage -ListAvailable | Measure-Object).Count -eq 1' - register: win_feature_has_storage_module - changed_when: false - -- name: Only run tests when Windows is capable - when: win_feature_has_storage_module.stdout | trim | bool == True - block: - - - name: Test in normal mode - include: tests.yml diff --git a/test/integration/targets/win_disk_facts/tasks/tests.yml b/test/integration/targets/win_disk_facts/tasks/tests.yml deleted file mode 100644 index ca3fda82cb3..00000000000 --- a/test/integration/targets/win_disk_facts/tasks/tests.yml +++ /dev/null @@ -1,18 +0,0 @@ -- name: get disk facts on the target - win_disk_facts: - register: disks_found - -- name: assert disk facts - assert: - that: - - disks_found.changed == false - - disks_found.ansible_facts.ansible_disks[0].number is defined - - disks_found.ansible_facts.ansible_disks[0].guid is defined - - disks_found.ansible_facts.ansible_disks[0].location is defined - - disks_found.ansible_facts.ansible_disks[0].path is defined - - disks_found.ansible_facts.ansible_disks[0].read_only is defined - - disks_found.ansible_facts.ansible_disks[0].clustered is defined - - disks_found.ansible_facts.ansible_disks[0].bootable is defined - - disks_found.ansible_facts.ansible_disks[0].physical_disk.size is defined - - disks_found.ansible_facts.ansible_disks[0].physical_disk.operational_status is defined - - disks_found.ansible_facts.ansible_disks[0].win32_disk_drive is defined diff --git a/test/integration/targets/win_dns_record/aliases b/test/integration/targets/win_dns_record/aliases deleted file mode 100644 index 9ad549d4a68..00000000000 --- a/test/integration/targets/win_dns_record/aliases +++ /dev/null @@ -1,3 +0,0 @@ -shippable/windows/group2 -skip/windows/2008 -skip/windows/2008-R2 diff --git a/test/integration/targets/win_dns_record/defaults/main.yml b/test/integration/targets/win_dns_record/defaults/main.yml deleted file mode 100644 index 496102481c3..00000000000 --- a/test/integration/targets/win_dns_record/defaults/main.yml +++ /dev/null @@ -1,3 +0,0 @@ -win_dns_record_zone: test.ansible.local -win_dns_record_revzone: 0.0.255.in-addr.arpa -win_dns_record_revzone_network: 255.0.0.0/24 diff --git a/test/integration/targets/win_dns_record/tasks/clean.yml b/test/integration/targets/win_dns_record/tasks/clean.yml deleted file mode 100644 index db9431648e2..00000000000 --- a/test/integration/targets/win_dns_record/tasks/clean.yml +++ /dev/null @@ -1,17 +0,0 @@ -- name: Remove test zone, if present - win_shell: | - $zone = '{{ item }}' - $fail_on_missing = '{{ fail_on_missing | default(true) }}' - - Trap { If (-not $fail_on_missing) { continue } } - Remove-DnsServerZone -Name $zone -Force - - # win_file could also do this, but it would need to know where the - # SystemRoot is located via fact gathering, which we cannot assume. - Trap { If (-not $fail_on_missing) { continue } } - Remove-Item -Path $env:SystemRoot\system32\dns\$zone.dns - - $true # so pipeline exits cleanly if an error was ignored above - loop: - - '{{ win_dns_record_zone }}' - - '{{ win_dns_record_revzone }}' diff --git a/test/integration/targets/win_dns_record/tasks/main.yml b/test/integration/targets/win_dns_record/tasks/main.yml deleted file mode 100644 index 97375e44634..00000000000 --- a/test/integration/targets/win_dns_record/tasks/main.yml +++ /dev/null @@ -1,12 +0,0 @@ -# We do an explicit OS version check here *INSTEAD OF* the usual test for -# cmdlet existence. That's because a cmdlet test here won't work without first -# installing the DNS feature, but we don't want to install the feature on OS' -# that can't be supported anyway. Hence this fallback to an explicit OS version -# test. -- name: check OS version is supported - win_shell: 'if ([Environment]::OSVersion.Version -ge [Version]"6.2") { $true } else { $false }' - register: os_supported - -- name: run tests on supported hosts - include: tests.yml - when: os_supported.stdout | trim | bool diff --git a/test/integration/targets/win_dns_record/tasks/tests-A.yml b/test/integration/targets/win_dns_record/tasks/tests-A.yml deleted file mode 100644 index 05910c774c3..00000000000 --- a/test/integration/targets/win_dns_record/tasks/tests-A.yml +++ /dev/null @@ -1,186 +0,0 @@ -- name: 'TYPE=A - creation (check mode)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: 1.2.3.4, type: A} - register: cmd_result - check_mode: yes - -- name: 'TYPE=A - creation get results (check mode)' - win_command: powershell.exe "If (Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType A -Node -ErrorAction:Ignore) { 'exists' } else { 'absent' }" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=A - creation check results (check mode)' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'absent\r\n' - -- name: 'TYPE=A - creation' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: 1.2.3.4, type: A} - register: cmd_result - -- name: 'TYPE=A - creation get results' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType A -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty IPv4Address | Select -ExpandProperty IPAddressToString" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=A - creation check results' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == '1.2.3.4\r\n' - -- name: 'TYPE=A - creation (idempotent)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: 1.2.3.4, type: A} - register: cmd_result - -- name: 'TYPE=A - creation get results (idempotent)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType A -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty IPv4Address | Select -ExpandProperty IPAddressToString" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=A - creation check results (idempotent)' - assert: - that: - - cmd_result is not changed - - cmd_result_actual.stdout == '1.2.3.4\r\n' - - -- name: 'TYPE=A - update address (check mode)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: 5.6.7.8, type: A} - register: cmd_result - check_mode: yes - -- name: 'TYPE=A - update address get results (check mode)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType A -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty IPv4Address | Select -ExpandProperty IPAddressToString" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=A - update address check results (check mode)' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == '1.2.3.4\r\n' - -- name: 'TYPE=A - update address' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: 5.6.7.8, type: A} - register: cmd_result - -- name: 'TYPE=A - update address get results' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType A -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty IPv4Address | Select -ExpandProperty IPAddressToString" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=A - update address check results' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == '5.6.7.8\r\n' - -- name: 'TYPE=A - update address (idempotent)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: 5.6.7.8, type: A} - register: cmd_result - -- name: 'TYPE=A - update address get results (idempotent)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType A -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty IPv4Address | Select -ExpandProperty IPAddressToString" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=A - update address check results (idempotent)' - assert: - that: - - cmd_result is not changed - - cmd_result_actual.stdout == '5.6.7.8\r\n' - - -- name: 'TYPE=A - update TTL (check mode)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: 5.6.7.8, ttl: 7200, type: A} - register: cmd_result - check_mode: yes - -- name: 'TYPE=A - update TTL get results (check mode)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType A -Node -ErrorAction:Ignore | Select -ExpandProperty TimeToLive | Select -ExpandProperty TotalSeconds" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=A - update TTL check results (check mode)' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == '3600\r\n' - -- name: 'TYPE=A - update TTL' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: 5.6.7.8, ttl: 7200, type: A} - register: cmd_result - -- name: 'TYPE=A - update TTL get results' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType A -Node -ErrorAction:Ignore | Select -ExpandProperty TimeToLive | Select -ExpandProperty TotalSeconds" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=A - update TTL check results' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == '7200\r\n' - -- name: 'TYPE=A - update TTL (idempotent)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: 5.6.7.8, ttl: 7200, type: A} - register: cmd_result - -- name: 'TYPE=A - update TTL get results (idempotent)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType A -Node -ErrorAction:Ignore | Select -ExpandProperty TimeToLive | Select -ExpandProperty TotalSeconds" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=A - update TTL check results (idempotent)' - assert: - that: - - cmd_result is not changed - - cmd_result_actual.stdout == '7200\r\n' - - -- name: 'TYPE=A - remove record (check mode)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, type: A, state: absent} - register: cmd_result - check_mode: yes - -- name: 'TYPE=A - remove record get results (check mode)' - win_command: powershell.exe "If (Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType A -Node -ErrorAction:Ignore) { 'exists' } else { 'absent' }" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=A - remove record check results (check mode)' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'exists\r\n' - -- name: 'TYPE=A - remove record' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, type: A, state: absent} - register: cmd_result - -- name: 'TYPE=A - remove record get results' - win_command: powershell.exe "If (Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType A -Node -ErrorAction:Ignore) { 'exists' } else { 'absent' }" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=A - remove record check results' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'absent\r\n' - -- name: 'TYPE=A - remove record (idempotent)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, type: A, state: absent} - register: cmd_result - -- name: 'TYPE=A - remove record get results (idempotent)' - win_command: powershell.exe "If (Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType A -Node -ErrorAction:Ignore) { 'exists' } else { 'absent' }" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=A - remove record check results (idempotent)' - assert: - that: - - cmd_result is not changed - - cmd_result_actual.stdout == 'absent\r\n' diff --git a/test/integration/targets/win_dns_record/tasks/tests-AAAA.yml b/test/integration/targets/win_dns_record/tasks/tests-AAAA.yml deleted file mode 100644 index cb32a8296b5..00000000000 --- a/test/integration/targets/win_dns_record/tasks/tests-AAAA.yml +++ /dev/null @@ -1,186 +0,0 @@ -- name: 'TYPE=AAAA - creation (check mode)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: '2001:db8::1', type: AAAA} - register: cmd_result - check_mode: yes - -- name: 'TYPE=AAAA - creation get results (check mode)' - win_command: powershell.exe "If (Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType AAAA -Node -ErrorAction:Ignore) { 'exists' } else { 'absent' }" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=AAAA - creation check results (check mode)' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'absent\r\n' - -- name: 'TYPE=AAAA - creation' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: '2001:db8::1', type: AAAA} - register: cmd_result - -- name: 'TYPE=AAAA - creation get results' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType AAAA -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty IPv6Address | Select -ExpandProperty IPAddressToString" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=AAAA - creation check results' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == '2001:db8::1\r\n' - -- name: 'TYPE=AAAA - creation (idempotent)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: '2001:db8::1', type: AAAA} - register: cmd_result - -- name: 'TYPE=AAAA - creation get results (idempotent)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType AAAA -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty IPv6Address | Select -ExpandProperty IPAddressToString" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=AAAA - creation check results (idempotent)' - assert: - that: - - cmd_result is not changed - - cmd_result_actual.stdout == '2001:db8::1\r\n' - - -- name: 'TYPE=AAAA - update address (check mode)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: '2001:db8::2', type: AAAA} - register: cmd_result - check_mode: yes - -- name: 'TYPE=AAAA - update address get results (check mode)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType AAAA -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty IPv6Address | Select -ExpandProperty IPAddressToString" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=AAAA - update address check results (check mode)' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == '2001:db8::1\r\n' - -- name: 'TYPE=AAAA - update address' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: '2001:db8::2', type: AAAA} - register: cmd_result - -- name: 'TYPE=AAAA - update address get results' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType AAAA -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty IPv6Address | Select -ExpandProperty IPAddressToString" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=AAAA - update address check results' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == '2001:db8::2\r\n' - -- name: 'TYPE=AAAA - update address (idempotent)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: '2001:db8::2', type: AAAA} - register: cmd_result - -- name: 'TYPE=AAAA - update address get results (idempotent)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType AAAA -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty IPv6Address | Select -ExpandProperty IPAddressToString" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=AAAA - update address check results (idempotent)' - assert: - that: - - cmd_result is not changed - - cmd_result_actual.stdout == '2001:db8::2\r\n' - - -- name: 'TYPE=AAAA - update TTL (check mode)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: '2001:db8::2', ttl: 7200, type: AAAA} - register: cmd_result - check_mode: yes - -- name: 'TYPE=AAAA - update TTL get results (check mode)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType AAAA -Node -ErrorAction:Ignore | Select -ExpandProperty TimeToLive | Select -ExpandProperty TotalSeconds" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=AAAA - update TTL check results (check mode)' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == '3600\r\n' - -- name: 'TYPE=AAAA - update TTL' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: '2001:db8::2', ttl: 7200, type: AAAA} - register: cmd_result - -- name: 'TYPE=AAAA - update TTL get results' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType AAAA -Node -ErrorAction:Ignore | Select -ExpandProperty TimeToLive | Select -ExpandProperty TotalSeconds" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=AAAA - update TTL check results' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == '7200\r\n' - -- name: 'TYPE=AAAA - update address (idempotent)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: '2001:db8::2', ttl: 7200, type: AAAA} - register: cmd_result - -- name: 'TYPE=AAAA - update address get results (idempotent)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType AAAA -Node -ErrorAction:Ignore | Select -ExpandProperty TimeToLive | Select -ExpandProperty TotalSeconds" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=AAAA - update address check results (idempotent)' - assert: - that: - - cmd_result is not changed - - cmd_result_actual.stdout == '7200\r\n' - - -- name: 'TYPE=AAAA - remove record (check mode)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, type: AAAA, state: absent} - register: cmd_result - check_mode: yes - -- name: 'TYPE=AAAA - remove record get results (check mode)' - win_command: powershell.exe "If (Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType AAAA -Node -ErrorAction:Ignore) { 'exists' } else { 'absent' }" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=AAAA - remove record check results (check mode)' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'exists\r\n' - -- name: 'TYPE=AAAA - remove record' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, type: AAAA, state: absent} - register: cmd_result - -- name: 'TYPE=AAAA - remove record get results' - win_command: powershell.exe "If (Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType AAAA -Node -ErrorAction:Ignore) { 'exists' } else { 'absent' }" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=AAAA - remove record check results' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'absent\r\n' - -- name: 'TYPE=AAAA - remove record (idempotent)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, type: AAAA, state: absent} - register: cmd_result - -- name: 'TYPE=AAAA - remove record get results (idempotent)' - win_command: powershell.exe "If (Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType AAAA -Node -ErrorAction:Ignore) { 'exists' } else { 'absent' }" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=AAAA - remove record check results (idempotent)' - assert: - that: - - cmd_result is not changed - - cmd_result_actual.stdout == 'absent\r\n' diff --git a/test/integration/targets/win_dns_record/tasks/tests-CNAME.yml b/test/integration/targets/win_dns_record/tasks/tests-CNAME.yml deleted file mode 100644 index f75a176a08c..00000000000 --- a/test/integration/targets/win_dns_record/tasks/tests-CNAME.yml +++ /dev/null @@ -1,186 +0,0 @@ -- name: 'TYPE=CNAME - creation (check mode)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: www.ansible.com, type: CNAME} - register: cmd_result - check_mode: yes - -- name: 'TYPE=CNAME - creation get results (check mode)' - win_command: powershell.exe "If (Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType CNAME -Node -ErrorAction:Ignore) { 'exists' } else { 'absent' }" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=CNAME - creation check results (check mode)' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'absent\r\n' - -- name: 'TYPE=CNAME - creation' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: www.ansible.com, type: CNAME} - register: cmd_result - -- name: 'TYPE=CNAME - creation get results' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType CNAME -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty HostNameAlias" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=CNAME - creation check results' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'www.ansible.com.\r\n' - -- name: 'TYPE=CNAME - creation (idempotent)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: www.ansible.com, type: CNAME} - register: cmd_result - -- name: 'TYPE=CNAME - creation get results (idempotent)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType CNAME -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty HostNameAlias" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=CNAME - creation check results (idempotent)' - assert: - that: - - cmd_result is not changed - - cmd_result_actual.stdout == 'www.ansible.com.\r\n' - - -- name: 'TYPE=CNAME - update address (check mode)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: docs.ansible.com, type: CNAME} - register: cmd_result - check_mode: yes - -- name: 'TYPE=CNAME - update address get results (check mode)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType CNAME -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty HostNameAlias" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=CNAME - update address check results (check mode)' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'www.ansible.com.\r\n' - -- name: 'TYPE=CNAME - update address' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: docs.ansible.com, type: CNAME} - register: cmd_result - -- name: 'TYPE=CNAME - update address get results' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType CNAME -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty HostNameAlias" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=CNAME - update address check results' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'docs.ansible.com.\r\n' - -- name: 'TYPE=CNAME - update address (idempotent)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: docs.ansible.com, type: CNAME} - register: cmd_result - -- name: 'TYPE=CNAME - update address get results (idempotent)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType CNAME -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty HostNameAlias" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=CNAME - update address check results (idempotent)' - assert: - that: - - cmd_result is not changed - - cmd_result_actual.stdout == 'docs.ansible.com.\r\n' - - -- name: 'TYPE=CNAME - update TTL (check mode)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: docs.ansible.com, ttl: 7200, type: CNAME} - register: cmd_result - check_mode: yes - -- name: 'TYPE=CNAME - update TTL get results (check mode)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType CNAME -Node -ErrorAction:Ignore | Select -ExpandProperty TimeToLive | Select -ExpandProperty TotalSeconds" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=CNAME - update TTL check results (check mode)' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == '3600\r\n' - -- name: 'TYPE=CNAME - update TTL' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: docs.ansible.com, ttl: 7200, type: CNAME} - register: cmd_result - -- name: 'TYPE=CNAME - update TTL get results' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType CNAME -Node -ErrorAction:Ignore | Select -ExpandProperty TimeToLive | Select -ExpandProperty TotalSeconds" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=CNAME - update TTL check results' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == '7200\r\n' - -- name: 'TYPE=CNAME - update TTL (idempotent)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, value: docs.ansible.com, ttl: 7200, type: CNAME} - register: cmd_result - -- name: 'TYPE=CNAME - update TTL get results (idempotent)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType CNAME -Node -ErrorAction:Ignore | Select -ExpandProperty TimeToLive | Select -ExpandProperty TotalSeconds" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=CNAME - update TTL check results (idempotent)' - assert: - that: - - cmd_result is not changed - - cmd_result_actual.stdout == '7200\r\n' - - -- name: 'TYPE=CNAME - remove record (check mode)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, type: CNAME, state: absent} - register: cmd_result - check_mode: yes - -- name: 'TYPE=CNAME - remove record get results (check mode)' - win_command: powershell.exe "If (Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType CNAME -Node -ErrorAction:Ignore) { 'exists' } else { 'absent' }" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=CNAME - remove record check results (check mode)' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'exists\r\n' - -- name: 'TYPE=CNAME - remove record' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, type: CNAME, state: absent} - register: cmd_result - -- name: 'TYPE=CNAME - remove record get results' - win_command: powershell.exe "If (Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType CNAME -Node -ErrorAction:Ignore) { 'exists' } else { 'absent' }" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=CNAME - remove record check results' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'absent\r\n' - -- name: 'TYPE=CNAME - remove record (idempotent)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: test1, type: CNAME, state: absent} - register: cmd_result - -- name: 'TYPE=CNAME - remove record get results (idempotent)' - win_command: powershell.exe "If (Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_zone }}' -Name 'test1' -RRType CNAME -Node -ErrorAction:Ignore) { 'exists' } else { 'absent' }" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=CNAME - remove record check results (idempotent)' - assert: - that: - - cmd_result is not changed - - cmd_result_actual.stdout == 'absent\r\n' diff --git a/test/integration/targets/win_dns_record/tasks/tests-PTR.yml b/test/integration/targets/win_dns_record/tasks/tests-PTR.yml deleted file mode 100644 index 6f48ab8caea..00000000000 --- a/test/integration/targets/win_dns_record/tasks/tests-PTR.yml +++ /dev/null @@ -1,186 +0,0 @@ -- name: 'TYPE=PTR - creation (check mode)' - win_dns_record: {zone: '{{ win_dns_record_revzone }}', name: 7, value: ansible-mirror.example.com, type: PTR} - register: cmd_result - check_mode: yes - -- name: 'TYPE=PTR - creation get results (check mode)' - win_command: powershell.exe "If (Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_revzone }}' -Name '7' -RRType PTR -Node -ErrorAction:Ignore) { 'exists' } else { 'absent' }" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=PTR - creation check results (check mode)' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'absent\r\n' - -- name: 'TYPE=PTR - creation' - win_dns_record: {zone: '{{ win_dns_record_revzone }}', name: 7, value: ansible-mirror.example.com, type: PTR} - register: cmd_result - -- name: 'TYPE=PTR - creation get results' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_revzone }}' -Name '7' -RRType PTR -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty PtrDomainName" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=PTR - creation check results' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'ansible-mirror.example.com.\r\n' - -- name: 'TYPE=PTR - creation (idempotent)' - win_dns_record: {zone: '{{ win_dns_record_revzone }}', name: 7, value: ansible-mirror.example.com, type: PTR} - register: cmd_result - -- name: 'TYPE=PTR - creation get results (idempotent)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_revzone }}' -Name '7' -RRType PTR -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty PtrDomainName" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=PTR - creation check results (idempotent)' - assert: - that: - - cmd_result is not changed - - cmd_result_actual.stdout == 'ansible-mirror.example.com.\r\n' - - -- name: 'TYPE=PTR - update address (check mode)' - win_dns_record: {zone: '{{ win_dns_record_revzone }}', name: 7, value: ansible-altmirror.example.com, type: PTR} - register: cmd_result - check_mode: yes - -- name: 'TYPE=PTR - update address get results (check mode)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_revzone }}' -Name '7' -RRType PTR -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty PtrDomainName" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=PTR - update address check results (check mode)' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'ansible-mirror.example.com.\r\n' - -- name: 'TYPE=PTR - update address' - win_dns_record: {zone: '{{ win_dns_record_revzone }}', name: 7, value: ansible-altmirror.example.com, type: PTR} - register: cmd_result - -- name: 'TYPE=PTR - update address get results' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_revzone }}' -Name '7' -RRType PTR -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty PtrDomainName" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=PTR - update address check results' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'ansible-altmirror.example.com.\r\n' - -- name: 'TYPE=PTR - update address (idempotent)' - win_dns_record: {zone: '{{ win_dns_record_revzone }}', name: 7, value: ansible-altmirror.example.com, type: PTR} - register: cmd_result - -- name: 'TYPE=PTR - update address get results (idempotent)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_revzone }}' -Name '7' -RRType PTR -Node -ErrorAction:Ignore | Select -ExpandProperty RecordData | Select -ExpandProperty PtrDomainName" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=PTR - update address check results (idempotent)' - assert: - that: - - cmd_result is not changed - - cmd_result_actual.stdout == 'ansible-altmirror.example.com.\r\n' - - -- name: 'TYPE=PTR - update TTL (check mode)' - win_dns_record: {zone: '{{ win_dns_record_revzone }}', name: 7, value: ansible-altmirror.example.com, ttl: 7200, type: PTR} - register: cmd_result - check_mode: yes - -- name: 'TYPE=PTR - update TTL get results (check mode)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_revzone }}' -Name '7' -RRType PTR -Node -ErrorAction:Ignore | Select -ExpandProperty TimeToLive | Select -ExpandProperty TotalSeconds" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=PTR - update TTL check results (check mode)' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == '3600\r\n' - -- name: 'TYPE=PTR - update TTL' - win_dns_record: {zone: '{{ win_dns_record_revzone }}', name: 7, value: ansible-altmirror.example.com, ttl: 7200, type: PTR} - register: cmd_result - -- name: 'TYPE=PTR - update TTL get results' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_revzone }}' -Name '7' -RRType PTR -Node -ErrorAction:Ignore | Select -ExpandProperty TimeToLive | Select -ExpandProperty TotalSeconds" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=PTR - update TTL check results' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == '7200\r\n' - -- name: 'TYPE=PTR - update TTL (idempotent)' - win_dns_record: {zone: '{{ win_dns_record_revzone }}', name: 7, value: ansible-altmirror.example.com, ttl: 7200, type: PTR} - register: cmd_result - -- name: 'TYPE=PTR - update TTL get results (idempotent)' - win_command: powershell.exe "Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_revzone }}' -Name '7' -RRType PTR -Node -ErrorAction:Ignore | Select -ExpandProperty TimeToLive | Select -ExpandProperty TotalSeconds" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=PTR - update TTL check results (idempotent)' - assert: - that: - - cmd_result is not changed - - cmd_result_actual.stdout == '7200\r\n' - - -- name: 'TYPE=PTR - remove record (check mode)' - win_dns_record: {zone: '{{ win_dns_record_revzone }}', name: 7, type: PTR, state: absent} - register: cmd_result - check_mode: yes - -- name: 'TYPE=PTR - remove record get results (check mode)' - win_command: powershell.exe "If (Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_revzone }}' -Name '7' -RRType PTR -Node -ErrorAction:Ignore) { 'exists' } else { 'absent' }" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=PTR - remove record check results (check mode)' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'exists\r\n' - -- name: 'TYPE=PTR - remove record' - win_dns_record: {zone: '{{ win_dns_record_revzone }}', name: 7, type: PTR, state: absent} - register: cmd_result - -- name: 'TYPE=PTR - remove record get results' - win_command: powershell.exe "If (Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_revzone }}' -Name '7' -RRType PTR -Node -ErrorAction:Ignore) { 'exists' } else { 'absent' }" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=PTR - remove record check results' - assert: - that: - - cmd_result is changed - - cmd_result_actual.stdout == 'absent\r\n' - -- name: 'TYPE=PTR - remove record (idempotent)' - win_dns_record: {zone: '{{ win_dns_record_revzone }}', name: 7, type: PTR, state: absent} - register: cmd_result - -- name: 'TYPE=PTR - remove record get results (idempotent)' - win_command: powershell.exe "If (Get-DnsServerResourceRecord -ZoneName '{{ win_dns_record_revzone }}' -Name '7' -RRType PTR -Node -ErrorAction:Ignore) { 'exists' } else { 'absent' }" - register: cmd_result_actual - changed_when: false - -- name: 'TYPE=PTR - remove record check results (idempotent)' - assert: - that: - - cmd_result is not changed - - cmd_result_actual.stdout == 'absent\r\n' diff --git a/test/integration/targets/win_dns_record/tasks/tests-diff.yml b/test/integration/targets/win_dns_record/tasks/tests-diff.yml deleted file mode 100644 index f5adaf369ab..00000000000 --- a/test/integration/targets/win_dns_record/tasks/tests-diff.yml +++ /dev/null @@ -1,63 +0,0 @@ -# Diff tests are present because those records have to be created MANUALLY by -# the win_dns_record module when in check mode, as there is otherwise no way in -# Windows DNS to *simulate* a record or change. - - -- name: 'Diff test - creation (check mode)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: diff_host, value: 1.2.3.4, type: A} - register: create_check - check_mode: yes - diff: yes - -- name: 'Diff test - creation' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: diff_host, value: 1.2.3.4, type: A} - register: create_do - diff: yes - -- name: 'Diff test - creation check results' - assert: - that: - - create_check.diff.before == create_do.diff.before - - create_check.diff.before == '' - - create_check.diff.after == create_do.diff.after - - create_check.diff.after == "[{{ win_dns_record_zone }}] diff_host 3600 IN A 1.2.3.4\n" - - -- name: 'Diff test - update TTL (check mode)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: diff_host, value: 1.2.3.4, type: A, ttl: 7200} - register: update_check - check_mode: yes - diff: yes - -- name: 'Diff test - update TTL' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: diff_host, value: 1.2.3.4, type: A, ttl: 7200} - register: update_do - diff: yes - -- name: 'Diff test - update TTL check results' - assert: - that: - - update_check.diff.before == update_do.diff.before - - update_check.diff.before == "[{{ win_dns_record_zone }}] diff_host 3600 IN A 1.2.3.4\n" - - update_check.diff.after == update_do.diff.after - - update_check.diff.after == "[{{ win_dns_record_zone }}] diff_host 7200 IN A 1.2.3.4\n" - - -- name: 'Diff test - deletion (check mode)' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: diff_host, type: A, state: absent} - register: delete_check - check_mode: yes - diff: yes - -- name: 'Diff test - deletion' - win_dns_record: {zone: '{{ win_dns_record_zone }}', name: diff_host, type: A, state: absent} - register: delete_do - diff: yes - -- name: 'Diff test - deletion check results' - assert: - that: - - delete_check.diff.before == delete_do.diff.before - - delete_check.diff.before == "[{{ win_dns_record_zone }}] diff_host 7200 IN A 1.2.3.4\n" - - delete_check.diff.after == delete_do.diff.after - - delete_check.diff.after == '' diff --git a/test/integration/targets/win_dns_record/tasks/tests.yml b/test/integration/targets/win_dns_record/tasks/tests.yml deleted file mode 100644 index f2ed38f531d..00000000000 --- a/test/integration/targets/win_dns_record/tasks/tests.yml +++ /dev/null @@ -1,32 +0,0 @@ -- name: ensure DNS services are installed - win_feature: - name: DNS - state: present - register: dns_install - -- name: reboot server if needed - win_reboot: - when: dns_install.reboot_required - -- name: Clean slate - import_tasks: clean.yml - vars: - fail_on_missing: false - -- block: - - name: Create the forward zone - win_shell: Add-DnsServerPrimaryZone -Name '{{ win_dns_record_zone }}' -ZoneFile '{{ win_dns_record_zone}}.dns' - - name: Create the reverse zone - win_shell: Add-DnsServerPrimaryZone -NetworkID '{{ win_dns_record_revzone_network }}' -ZoneFile '{{ win_dns_record_revzone}}.dns' - - - import_tasks: tests-A.yml - - import_tasks: tests-AAAA.yml - - import_tasks: tests-CNAME.yml - - import_tasks: tests-PTR.yml - - import_tasks: tests-diff.yml - - always: - - name: Clean slate - import_tasks: clean.yml - vars: - fail_on_missing: true diff --git a/test/integration/targets/win_domain_computer/aliases b/test/integration/targets/win_domain_computer/aliases deleted file mode 100644 index ad7ccf7ada2..00000000000 --- a/test/integration/targets/win_domain_computer/aliases +++ /dev/null @@ -1 +0,0 @@ -unsupported diff --git a/test/integration/targets/win_domain_computer/tasks/main.yml b/test/integration/targets/win_domain_computer/tasks/main.yml deleted file mode 100644 index 98f18acac27..00000000000 --- a/test/integration/targets/win_domain_computer/tasks/main.yml +++ /dev/null @@ -1,71 +0,0 @@ -# this won't run in Ansible's integration tests until we get a domain set up -# these are here if someone wants to run the module tests locally on their own -# domain. -# Requirements: -# LDAP Base path set in defaults/main.yml like DC=ansible,DC=local -# Custom OU path set in defaults/main.yml like OU=ou1,DC=ansible,DC=local ---- -- name: run win_domain_users test - hosts: win_domain_computer_testing_host - vars: - test_win_domain_computer_ldap_base: "{{ test_ad_ou }}" - test_win_domain_computer_ou_path: "{{ test_ad_group_ou }}" - test_win_domain_computer_name: "test_computer.{{ test_domain_name }}" - tasks: - - - name: ensure the computer is deleted before the test - win_domain_computer: - name: '{{ test_win_domain_computer_name }}' - state: absent - - # -------------------------------------------------------------------------- - - - name: Test computer with long name and distinct sam_account_name - vars: - test_win_domain_computer_long_name: '{{ test_win_domain_computer_name }}_with_long_name' - test_win_domain_computer_sam_account_name: '{{ test_win_domain_computer_name }}$' - block: - - # ---------------------------------------------------------------------- - - name: create computer with long name and distinct sam_account_name - win_domain_computer: - name: '{{ test_win_domain_computer_long_name }}' - sam_account_name: '{{ test_win_domain_computer_sam_account_name }}' - enabled: yes - state: present - register: create_distinct_sam_account_name - check_mode: yes - - - name: get actual computer with long name and distinct sam_account_name - win_command: powershell.exe "Import-Module ActiveDirectory; Get-ADComputer -Identity '{{ test_win_domain_computer_sam_account_name }}'" - register: create_distinct_sam_account_name_check - ignore_errors: True - - - name: assert create computer with long name and distinct sam_account_name - assert: - that: - - create_distinct_sam_account_name is changed - - create_distinct_sam_account_name_check.rc == 1 - - - name: (Idempotence) create computer with long name and distinct sam_account_name - win_domain_computer: - name: '{{ test_win_domain_computer_long_name }}' - sam_account_name: '{{ test_win_domain_computer_sam_account_name }}' - enabled: yes - state: present - register: create_distinct_sam_account_name_idempotence - check_mode: yes - - - name: (Idempotence) assert create computer with long name and distinct sam_account_name - assert: - that: - - create_distinct_sam_account_name_idempotence is not changed - - - name: ensure the test group is deleted after the test - win_domain_computer: - name: '{{ test_win_domain_computer_long_name }}' - sam_account_name: '{{ test_win_domain_computer_sam_account_name }}' - state: absent - ignore_protection: True - - # ---------------------------------------------------------------------- diff --git a/test/integration/targets/win_domain_group/aliases b/test/integration/targets/win_domain_group/aliases deleted file mode 100644 index ad7ccf7ada2..00000000000 --- a/test/integration/targets/win_domain_group/aliases +++ /dev/null @@ -1 +0,0 @@ -unsupported diff --git a/test/integration/targets/win_domain_group/defaults/main.yml b/test/integration/targets/win_domain_group/defaults/main.yml deleted file mode 100644 index b02643ee0c0..00000000000 --- a/test/integration/targets/win_domain_group/defaults/main.yml +++ /dev/null @@ -1,3 +0,0 @@ -test_win_domain_group_ldap_base: DC=ansible,DC=local -test_win_domain_group_ou_path: OU=ou1,DC=ansible,DC=local -test_win_domain_group_name: Moo Cow diff --git a/test/integration/targets/win_domain_group/tasks/main.yml b/test/integration/targets/win_domain_group/tasks/main.yml deleted file mode 100644 index 663a59a1b81..00000000000 --- a/test/integration/targets/win_domain_group/tasks/main.yml +++ /dev/null @@ -1,353 +0,0 @@ -# this won't run in Ansible's integration tests until we get a domain set up -# these are here if someone wants to run the module tests locally on their own -# domain. -# Requirements: -# LDAP Base path set in defaults/main.yml like DC=ansible,DC=local -# Custom OU path set in defaults/main.yml like OU=ou1,DC=ansible,DC=local ---- -- name: ensure the test group is deleted before the test - win_domain_group: - name: '{{test_win_domain_group_name}}' - state: absent - ignore_protection: True - -- name: fail pass in an invalid path - win_domain_group: - name: '{{test_win_domain_group_name}}' - state: present - organizational_unit: OU=fakeou,{{test_win_domain_group_ldap_base}} - register: fail_invalid_path - failed_when: fail_invalid_path.msg != 'the group path OU=fakeou,' + test_win_domain_group_ldap_base + ' does not exist, please specify a valid LDAP path' - -- name: create group with defaults check - win_domain_group: - name: '{{test_win_domain_group_name}}' - scope: global - state: present - register: create_default_check - check_mode: yes - -- name: get actual group with defaults check - win_command: powershell.exe "Import-Module ActiveDirectory; Get-ADGroup -Identity '{{test_win_domain_group_name}}'" - register: create_default_actual_check - ignore_errors: True - -- name: assert create group with defaults checl - assert: - that: - - create_default_check is changed - - create_default_actual_check.rc == 1 - -- name: create group with defaults - win_domain_group: - name: '{{test_win_domain_group_name}}' - scope: global - state: present - register: create_default - -- name: get actual group with defaults - win_command: powershell.exe "Import-Module ActiveDirectory; Get-ADGroup -Identity '{{test_win_domain_group_name}}'" - register: create_default_actual - -- name: assert create group with defaults - assert: - that: - - create_default is created - - create_default is changed - - create_default.category == 'Security' - - create_default.description == None - - create_default.display_name == None - - create_default.distinguished_name == 'CN=' + test_win_domain_group_name + ',CN=Users,' + test_win_domain_group_ldap_base - - create_default.group_scope == 'Global' - - create_default.guid is defined - - create_default.managed_by == None - - create_default.name == test_win_domain_group_name - - create_default.protected_from_accidental_deletion == False - - create_default.sid is defined - - create_default_actual.rc == 0 - -- name: create group with defaults again - win_domain_group: - name: '{{test_win_domain_group_name}}' - scope: global - state: present - register: create_default_again - -- name: assert create group with defaults again - assert: - that: - - create_default_again is not changed - - create_default_again is not created - -- name: remove group check - win_domain_group: - name: '{{test_win_domain_group_name}}' - state: absent - register: remove_group_check - check_mode: yes - -- name: get actual remove group check - win_command: powershell.exe "Import-Module ActiveDirectory; Get-ADGroup -Identity '{{test_win_domain_group_name}}'" - register: remove_group_actual_check - -- name: assert remove group check - assert: - that: - - remove_group_check is changed - - remove_group_actual_check.rc == 0 - -- name: remove group - win_domain_group: - name: '{{test_win_domain_group_name}}' - state: absent - register: remove_group - -- name: get actual remove group - win_command: powershell.exe "Import-Module ActiveDirectory; Get-ADGroup -Identity '{{test_win_domain_group_name}}'" - register: remove_group_actual - ignore_errors: True - -- name: assert remove group - assert: - that: - - remove_group is changed - - remove_group is not created - - remove_group_actual.rc == 1 - -- name: remove group again - win_domain_group: - name: '{{test_win_domain_group_name}}' - state: absent - register: remove_group_again - -- name: assert remove group again - assert: - that: - - remove_group_again is not changed - - remove_group_again is not created - -- name: create non default group check - win_domain_group: - name: '{{test_win_domain_group_name}}' - state: present - description: Group Description - display_name: Group Display Name - managed_by: Domain Admins - organizational_unit: '{{test_win_domain_group_ou_path}}' - category: distribution - scope: domainlocal - attributes: - mail: test@email.com - wWWHomePage: www.google.com - protect: True - register: create_non_default_check - check_mode: yes - -- name: get actual create non default group check - win_command: powershell.exe "Import-Module ActiveDirectory; Get-ADGroup -Identity '{{test_win_domain_group_name}}'" - register: create_non_default_actual_check - ignore_errors: True - -- name: assert create non default group check - assert: - that: - - create_non_default_check is changed - - create_non_default_check is created - - create_non_default_actual_check.rc == 1 - -- name: create non default group - win_domain_group: - name: '{{test_win_domain_group_name}}' - state: present - description: Group Description - display_name: Group Display Name - managed_by: Domain Admins - organizational_unit: '{{test_win_domain_group_ou_path}}' - category: distribution - scope: domainlocal - attributes: - mail: test@email.com - wWWHomePage: www.google.com - protect: True - register: create_non_default - -- name: get actual create non default group - win_command: powershell.exe "Import-Module ActiveDirectory; Get-ADGroup -Identity '{{test_win_domain_group_name}}'" - register: create_non_default_actual - ignore_errors: True - -- name: assert create non default group - assert: - that: - - create_non_default is changed - - create_non_default is created - - create_non_default.category == 'Distribution' - - create_non_default.description == 'Group Description' - - create_non_default.display_name == 'Group Display Name' - - create_non_default.distinguished_name == 'CN=' + test_win_domain_group_name + ',' + test_win_domain_group_ou_path - - create_non_default.group_scope == 'DomainLocal' - - create_non_default.guid is defined - - create_non_default.managed_by == 'CN=Domain Admins,CN=Users,' + test_win_domain_group_ldap_base - - create_non_default.name == test_win_domain_group_name - - create_non_default.protected_from_accidental_deletion == True - - create_non_default.sid is defined - - create_non_default.attributes.mail == 'test@email.com' - - create_non_default.attributes.wWWHomePage == 'www.google.com' - - create_non_default_actual.rc == 0 - -- name: create non default group again - win_domain_group: - name: '{{test_win_domain_group_name}}' - state: present - description: Group Description - display_name: Group Display Name - managed_by: Domain Admins - organizational_unit: '{{test_win_domain_group_ou_path}}' - category: distribution - scope: domainlocal - attributes: - mail: test@email.com - wWWHomePage: www.google.com - register: create_non_default_again - -- name: assert create non default group again - assert: - that: - - create_non_default_again is not changed - - create_non_default_again is not created - -- name: try and move group with protection mode on - win_domain_group: - name: '{{test_win_domain_group_name}}' - state: present - organizational_unit: CN=Users,{{test_win_domain_group_ldap_base}} - register: fail_move_with_protection - failed_when: fail_move_with_protection.msg != 'cannot move group ' + test_win_domain_group_name + ' when ProtectedFromAccidentalDeletion is turned on, run this module with ignore_protection=true to override this' - -- name: modify existing group check - win_domain_group: - name: '{{test_win_domain_group_name}}' - state: present - description: New Description - display_name: New Display Name - managed_by: Administrator - organizational_unit: 'CN=Users,{{test_win_domain_group_ldap_base}}' - category: security - scope: global - attributes: - mail: anothertest@email.com - ignore_protection: True - register: modify_existing_check - check_mode: yes - -- name: get actual of modify existing group check - win_command: powershell.exe "Import-Module ActiveDirectory; (Get-ADGroup -Identity '{{test_win_domain_group_name}}').DistinguishedName" - register: modify_existing_actual_check - -- name: assert modify existing group check - assert: - that: - - modify_existing_check is changed - - modify_existing_check is not created - - modify_existing_actual_check.stdout == 'CN=' + test_win_domain_group_name + ',' + test_win_domain_group_ou_path + '\r\n' - -- name: modify existing group - win_domain_group: - name: '{{test_win_domain_group_name}}' - state: present - description: New Description - display_name: New Display Name - managed_by: Administrator - organizational_unit: CN=Users,{{test_win_domain_group_ldap_base}} - category: security - scope: global - attributes: - mail: anothertest@email.com - protect: True - ignore_protection: True - register: modify_existing - -- name: get actual of modify existing group - win_command: powershell.exe "Import-Module ActiveDirectory; (Get-ADGroup -Identity '{{test_win_domain_group_name}}').DistinguishedName" - register: modify_existing_actual - -- name: assert modify existing group - assert: - that: - - modify_existing is changed - - modify_existing is not created - - modify_existing.category == 'Security' - - modify_existing.description == 'New Description' - - modify_existing.display_name == 'New Display Name' - - modify_existing.distinguished_name == 'CN=' + test_win_domain_group_name + ',CN=Users,' + test_win_domain_group_ldap_base - - modify_existing.group_scope == 'Global' - - modify_existing.guid is defined - - modify_existing.managed_by == 'CN=Administrator,CN=Users,' + test_win_domain_group_ldap_base - - modify_existing.name == test_win_domain_group_name - - modify_existing.protected_from_accidental_deletion == True - - modify_existing.sid is defined - - modify_existing.attributes.mail == 'anothertest@email.com' - - modify_existing_actual.stdout == 'CN=' + test_win_domain_group_name + ',CN=Users,' + test_win_domain_group_ldap_base + '\r\n' - -- name: modify existing group again - win_domain_group: - name: '{{test_win_domain_group_name}}' - state: present - description: New Description - display_name: New Display Name - managed_by: Administrator - organizational_unit: CN=Users,{{test_win_domain_group_ldap_base}} - category: Security - scope: global - attributes: - mail: anothertest@email.com - protect: True - ignore_protection: True - register: modify_existing_again - -- name: assert modify existing group again - assert: - that: - - modify_existing_again is not changed - - modify_existing_again is not created - -- name: fail change managed_by to invalid user - win_domain_group: - name: '{{test_win_domain_group_name}}' - state: present - scope: global - managed_by: fake user - register: fail_invalid_managed_by_user - failed_when: fail_invalid_managed_by_user.msg != 'failed to find managed_by user or group fake user to be used for comparison' - -- name: fail delete group with protection mode on - win_domain_group: - name: '{{test_win_domain_group_name}}' - state: absent - register: fail_delete_with_protection - failed_when: fail_delete_with_protection.msg != 'cannot delete group ' + test_win_domain_group_name + ' when ProtectedFromAccidentalDeletion is turned on, run this module with ignore_protection=true to override this' - -- name: delete group with protection mode on - win_domain_group: - name: '{{test_win_domain_group_name}}' - state: absent - ignore_protection: True - register: delete_with_force - -- name: get actual delete group with protection mode on - win_command: powershell.exe "Import-Module ActiveDirectory; Get-ADGroup -Identity '{{test_win_domain_group_name}}'" - register: delete_with_force_actual - ignore_errors: True - -- name: assert delete group with protection mode on - assert: - that: - - delete_with_force is changed - - delete_with_force is not created - - delete_with_force_actual.rc == 1 - -- name: ensure the test group is deleted after the test - win_domain_group: - name: '{{test_win_domain_group_name}}' - state: absent - ignore_protection: True diff --git a/test/integration/targets/win_domain_object_info/aliases b/test/integration/targets/win_domain_object_info/aliases deleted file mode 100644 index ad7ccf7ada2..00000000000 --- a/test/integration/targets/win_domain_object_info/aliases +++ /dev/null @@ -1 +0,0 @@ -unsupported diff --git a/test/integration/targets/win_domain_object_info/handlers/main.yml b/test/integration/targets/win_domain_object_info/handlers/main.yml deleted file mode 100644 index 76a2a0f7627..00000000000 --- a/test/integration/targets/win_domain_object_info/handlers/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -- name: remove test domain user - win_domain_user: - name: '{{ test_user.distinguished_name }}' - state: absent diff --git a/test/integration/targets/win_domain_object_info/tasks/main.yml b/test/integration/targets/win_domain_object_info/tasks/main.yml deleted file mode 100644 index 54ea126aa9c..00000000000 --- a/test/integration/targets/win_domain_object_info/tasks/main.yml +++ /dev/null @@ -1,125 +0,0 @@ -# These tests can't run in CI, this is really just a basic smoke tests for local runs. ---- -- name: assert better error message on auth failure - win_domain_object_info: - identity: id - register: fail_auth - failed_when: '"Failed to contact the AD server, this could be caused by the double hop problem" not in fail_auth.msg' - vars: - ansible_winrm_transport: ntlm - ansible_psrp_auth: ntlm - -- name: create test ad user - win_domain_user: - name: Ansible Test - firstname: Ansible - surname: Test - company: Contoso R Us - password: Password01 - state: present - password_never_expires: yes - groups: - - Domain Users - enabled: false - register: test_user - notify: remove test domain user - -- name: set a binary attribute and return other useful info missing from above - win_shell: | - Set-ADUser -Identity '{{ test_user.sid }}' -Replace @{ audio = @([byte[]]@(1, 2, 3, 4), [byte[]]@(5, 6, 7, 8)) } - - $user = Get-ADUser -Identity '{{ test_user.sid }}' -Properties modifyTimestamp, ObjectGUID - - [TimeZoneInfo]::ConvertTimeToUtc($user.modifyTimestamp).ToString('o') - $user.ObjectGUID.ToString() - ([System.Security.Principal.SecurityIdentifier]'{{ test_user.sid }}').Translate([System.Security.Principal.NTAccount]).Value - register: test_user_extras - -- name: set other test info for easier access - set_fact: - test_user_mod_date: '{{ test_user_extras.stdout_lines[0] }}' - test_user_id: '{{ test_user_extras.stdout_lines[1] }}' - test_user_name: '{{ test_user_extras.stdout_lines[2] }}' - -- name: get properties for single user by DN - win_domain_object_info: - identity: '{{ test_user.distinguished_name }}' - register: by_identity - check_mode: yes # Just verifies it runs in check mode - -- name: assert get properties for single user by DN - assert: - that: - - not by_identity is changed - - by_identity.objects | length == 1 - - by_identity.objects[0].keys() | list | length == 4 - - by_identity.objects[0].DistinguishedName == test_user.distinguished_name - - by_identity.objects[0].Name == 'Ansible Test' - - by_identity.objects[0].ObjectClass == 'user' - - by_identity.objects[0].ObjectGUID == test_user_id - -- name: get specific properties by GUID - win_domain_object_info: - identity: '{{ test_user_id }}' - properties: - - audio # byte[] - - company # string - - department # not set - - logonCount # int - - modifyTimestamp # DateTime - - nTSecurityDescriptor # SecurityDescriptor as SDDL - - objectSID # SID - - ProtectedFromAccidentalDeletion # bool - - sAMAccountType # Test out the enum string attribute that we add - - userAccountControl # Test ou the enum string attribute that we add - register: by_guid_custom_props - -- name: assert get specific properties by GUID - assert: - that: - - not by_guid_custom_props is changed - - by_guid_custom_props.objects | length == 1 - - by_guid_custom_props.objects[0].DistinguishedName == test_user.distinguished_name - - by_guid_custom_props.objects[0].Name == 'Ansible Test' - - by_guid_custom_props.objects[0].ObjectClass == 'user' - - by_guid_custom_props.objects[0].ObjectGUID == test_user_id - - not by_guid_custom_props.objects[0].ProtectedFromAccidentalDeletion - - by_guid_custom_props.objects[0].audio == ['BQYHCA==', 'AQIDBA=='] - - by_guid_custom_props.objects[0].company == 'Contoso R Us' - - by_guid_custom_props.objects[0].department == None - - by_guid_custom_props.objects[0].logonCount == 0 - - by_guid_custom_props.objects[0].modifyTimestamp == test_user_mod_date - - by_guid_custom_props.objects[0].nTSecurityDescriptor.startswith('O:DAG:DAD:AI(') - - by_guid_custom_props.objects[0].objectSID.Name == test_user_name - - by_guid_custom_props.objects[0].objectSID.Sid == test_user.sid - - by_guid_custom_props.objects[0].sAMAccountType == 805306368 - - by_guid_custom_props.objects[0].sAMAccountType_AnsibleFlags == ['SAM_USER_OBJECT'] - - by_guid_custom_props.objects[0].userAccountControl == 66050 - - by_guid_custom_props.objects[0].userAccountControl_AnsibleFlags == ['ADS_UF_ACCOUNTDISABLE', 'ADS_UF_NORMAL_ACCOUNT', 'ADS_UF_DONT_EXPIRE_PASSWD'] - -- name: get invalid property - win_domain_object_info: - filter: sAMAccountName -eq 'Ansible Test' - properties: - - FakeProperty - register: invalid_prop_warning - -- name: assert get invalid property - assert: - that: - - not invalid_prop_warning is changed - - invalid_prop_warning.objects | length == 0 - - invalid_prop_warning.warnings | length == 1 - - '"Failed to retrieve properties for AD object" not in invalid_prop_warning.warnings[0]' - -- name: get by ldap filter returning multiple - win_domain_object_info: - ldap_filter: (&(objectClass=computer)(objectCategory=computer)) - properties: '*' - register: multiple_ldap - -- name: assert get by ldap filter returning multiple - assert: - that: - - not multiple_ldap is changed - - multiple_ldap.objects | length > 1 diff --git a/test/integration/targets/win_dotnet_ngen/aliases b/test/integration/targets/win_dotnet_ngen/aliases deleted file mode 100644 index 4c08975b17d..00000000000 --- a/test/integration/targets/win_dotnet_ngen/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group6 diff --git a/test/integration/targets/win_dotnet_ngen/tasks/main.yml b/test/integration/targets/win_dotnet_ngen/tasks/main.yml deleted file mode 100644 index 146eeb3c520..00000000000 --- a/test/integration/targets/win_dotnet_ngen/tasks/main.yml +++ /dev/null @@ -1,20 +0,0 @@ -# this only tests check mode as the full run can take several minutes to -# complete, this way we at least verify the script is parsable ---- -- name: run in check mode - win_dotnet_ngen: - register: result_check - check_mode: yes - -- name: assert run in check mode - assert: - that: - - result_check is changed - - result_check.dotnet_ngen_update_exit_code == 0 - - result_check.dotnet_ngen_update_output == "check mode output for C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\ngen.exe update /force" - - result_check.dotnet_ngen_eqi_exit_code == 0 - - result_check.dotnet_ngen_eqi_output == "check mode output for C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\ngen.exe executeQueuedItems" - - result_check.dotnet_ngen64_update_exit_code == 0 - - result_check.dotnet_ngen64_update_output == "check mode output for C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\ngen.exe update /force" - - result_check.dotnet_ngen64_eqi_exit_code == 0 - - result_check.dotnet_ngen64_eqi_output == "check mode output for C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\ngen.exe executeQueuedItems" diff --git a/test/integration/targets/win_eventlog/aliases b/test/integration/targets/win_eventlog/aliases deleted file mode 100644 index 423ce391085..00000000000 --- a/test/integration/targets/win_eventlog/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group2 diff --git a/test/integration/targets/win_eventlog/tasks/main.yml b/test/integration/targets/win_eventlog/tasks/main.yml deleted file mode 100644 index dcc075fcc89..00000000000 --- a/test/integration/targets/win_eventlog/tasks/main.yml +++ /dev/null @@ -1,10 +0,0 @@ -- name: Run tests for win_eventlog in normal mode - import_tasks: tests.yml - vars: - in_check_mode: no - -- name: Run tests for win_eventlog in check-mode - import_tasks: tests.yml - vars: - in_check_mode: yes - check_mode: yes diff --git a/test/integration/targets/win_eventlog/tasks/tests.yml b/test/integration/targets/win_eventlog/tasks/tests.yml deleted file mode 100644 index b369362ee15..00000000000 --- a/test/integration/targets/win_eventlog/tasks/tests.yml +++ /dev/null @@ -1,447 +0,0 @@ -# Test code for win_eventlog - -# (c) 2017, Andrew Saraceni -# -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -- name: Remove potentially leftover logs - win_eventlog: - name: "{{ item }}" - state: absent - with_items: - - WinEventLogTest - - NewWinEventLogTest - - -- name: Add log without sources - win_eventlog: - name: WinEventLogTest - state: present - register: add_log_without_sources - failed_when: add_log_without_sources.changed != false or add_log_without_sources.msg != "You must specify one or more sources when creating a log for the first time" - - -- name: Add log - win_eventlog: &wel_present - name: WinEventLogTest - sources: - - WinEventLogSource1 - - WinEventLogSource2 - state: present - register: add_log - -- name: Test add_log (normal mode) - assert: - that: - - add_log.changed == true - - add_log.exists == true - - add_log.sources == ["WinEventLogSource1", "WinEventLogSource2", "WinEventLogTest"] - - add_log.sources_changed == ["WinEventLogSource1", "WinEventLogSource2"] - when: not in_check_mode - -- name: Test add_log (check-mode) - assert: - that: - - add_log.changed == true - - add_log.exists == false - - add_log.sources_changed == [] - when: in_check_mode - - -- name: Add log (again) - win_eventlog: *wel_present - register: add_log_again - -- name: Test add_log_again (normal mode) - assert: - that: - - add_log_again.changed == false - - add_log_again.exists == true - - add_log_again.sources == ["WinEventLogSource1", "WinEventLogSource2", "WinEventLogTest"] - - add_log_again.sources_changed == [] - when: not in_check_mode - - -- name: Run tests for normal mode only (expects event log) - when: not in_check_mode - block: - - - name: Change default source - win_eventlog: - <<: *wel_present - sources: - - WinEventLogTest - category_file: C:\TestApp\AppCategories.dll - register: change_default_source - failed_when: change_default_source.changed != false or change_default_source.msg != "Cannot modify default source WinEventLogTest of log WinEventLogTest - you must remove the log" - - - - name: Change source category - win_eventlog: &welc_present - <<: *wel_present - sources: - - WinEventLogSource1 - category_file: C:\TestApp\AppCategories.dll - register: change_source_category - - - name: Test change_source_category - assert: - that: - - change_source_category.changed == true - - change_source_category.exists == true - - change_source_category.sources == ["WinEventLogSource1", "WinEventLogSource2", "WinEventLogTest"] - - change_source_category.sources_changed == ["WinEventLogSource1"] - - - - name: Change source category (again) - win_eventlog: *welc_present - register: change_source_category_again - - - name: Test change_source_category_again - assert: - that: - - change_source_category_again.changed == false - - change_source_category_again.exists == true - - change_source_category_again.sources == ["WinEventLogSource1", "WinEventLogSource2", "WinEventLogTest"] - - change_source_category_again.sources_changed == [] - - - - name: Change source message - win_eventlog: &welm_present - <<: *welc_present - message_file: C:\TestApp\AppMessages.dll - register: change_source_message - - - name: Test change_source_message - assert: - that: - - change_source_message.changed == true - - change_source_message.exists == true - - change_source_message.sources == ["WinEventLogSource1", "WinEventLogSource2", "WinEventLogTest"] - - change_source_message.sources_changed == ["WinEventLogSource1"] - - - - name: Change source message (again) - win_eventlog: *welm_present - register: change_source_message_again - - - name: Test change_source_message_again - assert: - that: - - change_source_message_again.changed == false - - change_source_message_again.exists == true - - change_source_message_again.sources == ["WinEventLogSource1", "WinEventLogSource2", "WinEventLogTest"] - - change_source_message_again.sources_changed == [] - - - - name: Change source parameter - win_eventlog: &welp_present - <<: *welm_present - parameter_file: C:\TestApp\AppParameters.dll - register: change_source_parameter - - - name: Test change_source_parameter - assert: - that: - - change_source_parameter.changed == true - - change_source_parameter.exists == true - - change_source_parameter.sources == ["WinEventLogSource1", "WinEventLogSource2", "WinEventLogTest"] - - change_source_parameter.sources_changed == ["WinEventLogSource1"] - - - - name: Change source parameter (again) - win_eventlog: *welp_present - register: change_source_parameter_again - - - name: Test change_source_parameter_again - assert: - that: - - change_source_parameter_again.changed == false - - change_source_parameter_again.exists == true - - change_source_parameter_again.sources == ["WinEventLogSource1", "WinEventLogSource2", "WinEventLogTest"] - - change_source_parameter_again.sources_changed == [] - - - - name: Change log maximum size - win_eventlog: &wels_present - <<: *wel_present - maximum_size: 256MB - register: change_log_maximum_size - - - name: Test change_log_maximum_size - assert: - that: - - change_log_maximum_size.changed == true - - change_log_maximum_size.exists == true - - change_log_maximum_size.maximum_size_kb == 262144 - - - - name: Change log maximum size (again) - win_eventlog: *wels_present - register: change_log_maximum_size_again - - - name: Test change_log_maximum_size_again - assert: - that: - - change_log_maximum_size_again.changed == false - - change_log_maximum_size_again.exists == true - - change_log_maximum_size_again.maximum_size_kb == 262144 - - - - name: Change log invalid maximum size 1 - win_eventlog: - <<: *wel_present - maximum_size: 256 MB - register: change_log_invalid_maximum_size_1 - failed_when: change_log_invalid_maximum_size_1.changed != false or change_log_invalid_maximum_size_1.msg != "Maximum size 256 MB is not properly specified" - - - - name: Change log invalid maximum size 2 - win_eventlog: - <<: *wel_present - maximum_size: 5GB - register: change_log_invalid_maximum_size_2 - failed_when: change_log_invalid_maximum_size_2.changed != false or change_log_invalid_maximum_size_2.msg != "Maximum size must be between 64KB and 4GB" - - - - name: Change log invalid maximum size 3 - win_eventlog: - <<: *wel_present - maximum_size: 129KB - register: change_log_invalid_maximum_size_3 - failed_when: change_log_invalid_maximum_size_3.changed != false or change_log_invalid_maximum_size_3.msg != "Maximum size must be divisible by 64KB" - - - - name: Change log retention days - win_eventlog: &welr_present - <<: *wels_present - retention_days: 128 - register: change_log_retention_days - - - name: Test change_log_retention_days - assert: - that: - - change_log_retention_days.changed == true - - change_log_retention_days.exists == true - - change_log_retention_days.retention_days == 128 - - - - name: Change log retention days (again) - win_eventlog: *welr_present - register: change_log_retention_days_again - - - name: Test change_log_retention_days_again - assert: - that: - - change_log_retention_days_again.changed == false - - change_log_retention_days_again.exists == true - - change_log_retention_days_again.retention_days == 128 - - - - name: Change log overflow action - win_eventlog: &welo_present - <<: *wels_present - overflow_action: OverwriteAsNeeded - register: change_log_overflow_action - - - name: Test change_log_overflow_action - assert: - that: - - change_log_overflow_action.changed == true - - change_log_overflow_action.exists == true - - change_log_overflow_action.overflow_action == "OverwriteAsNeeded" - - - - name: Change log overflow action (again) - win_eventlog: *welo_present - register: change_log_overflow_action_again - - - name: Test change_log_overflow_action_again - assert: - that: - - change_log_overflow_action_again.changed == false - - change_log_overflow_action_again.exists == true - - change_log_overflow_action_again.overflow_action == "OverwriteAsNeeded" - - - - name: Add log with existing source - win_eventlog: &wele_present - name: NewWinEventLogTest - sources: - - WinEventLogSource1 - state: present - register: add_log_with_existing_source - failed_when: add_log_with_existing_source.changed != false or add_log_with_existing_source.msg != "Source WinEventLogSource1 already exists and cannot be created" - - - - name: Add new log - win_eventlog: - <<: *wele_present - sources: - - NewWinEventLogSource1 - - - name: Change source for different log - win_eventlog: - <<: *wele_present - sources: - - WinEventLogSource1 - category_file: C:\TestApp\AppCategories.dll - register: change_source_for_different_log - failed_when: change_source_for_different_log.changed != false or change_source_for_different_log.msg != "Source WinEventLogSource1 does not belong to log NewWinEventLogTest and cannot be modified" - - - name: Remove new log - win_eventlog: - name: NewWinEventLogTest - state: absent - - - - name: Add entry to log - win_shell: Write-EventLog -LogName WinEventLogTest -Source WinEventLogSource1 -EntryType Information -EventId 12345 -Message "Test message" - - - name: Verify add entry - win_eventlog: - name: WinEventLogTest - state: present - register: verify_add_entry - - - name: Test verify_add_entry - assert: - that: - - verify_add_entry.changed == false - - verify_add_entry.exists == true - - verify_add_entry.entries == 1 - - - - name: Clear log - win_eventlog: &wel_clear - name: WinEventLogTest - state: clear - register: clear_log - - - name: Test clear_log - assert: - that: - - clear_log.changed == true - - clear_log.exists == true - - clear_log.entries == 0 - when: not in_check_mode - - - - name: Clear log (again) - win_eventlog: *wel_clear - register: clear_log_again - - - name: Test clear_log_again - assert: - that: - - clear_log_again.changed == false - - clear_log_again.exists == true - - clear_log_again.entries == 0 - when: in_check_mode - - -- name: Clear absent log - win_eventlog: - name: WinEventLogTest - state: clear - register: clear_absent_log - when: in_check_mode - failed_when: clear_absent_log.changed != false or clear_absent_log.msg != "Cannot clear log WinEventLogTest as it does not exist" - - -- name: Remove default source - win_eventlog: &weld_absent - name: WinEventLogTest - sources: - - WinEventLogTest - state: absent - register: remove_default_source - failed_when: remove_default_source.changed != false or remove_default_source.msg != "Cannot remove default source WinEventLogTest from log WinEventLogTest - you must remove the log" - - -- name: Remove source - win_eventlog: &wels_absent - <<: *weld_absent - sources: - - WinEventLogSource1 - register: remove_source - -- name: Test remove_source (normal mode) - assert: - that: - - remove_source.changed == true - - remove_source.exists == true - - remove_source.sources == ["WinEventLogSource2", "WinEventLogTest"] - - remove_source.sources_changed == ["WinEventLogSource1"] - when: not in_check_mode - -- name: Test remove_source (check-mode) - assert: - that: - - remove_source.changed == false - - remove_source.exists == false - - remove_source.sources_changed == [] - when: in_check_mode - - -- name: Remove source (again) - win_eventlog: *wels_absent - register: remove_source_again - -- name: Test remove_source_again (normal mode) - assert: - that: - - remove_source_again.changed == false - - remove_source_again.exists == true - - remove_source.sources == ["WinEventLogSource2", "WinEventLogTest"] - - remove_source_again.sources_changed == [] - when: not in_check_mode - - -- name: Remove log - win_eventlog: &wel_absent - name: WinEventLogTest - state: absent - register: remove_log - -- name: Test remove_log (normal mode) - assert: - that: - - remove_log.changed == true - - remove_log.exists == false - - remove_log.sources_changed == ["WinEventLogSource2", "WinEventLogTest"] - when: not in_check_mode - -- name: Test remove_log (check-mode) - assert: - that: - - remove_log.changed == false - - remove_log.exists == false - - remove_log.sources_changed == [] - when: in_check_mode - - -- name: Remove log (again) - win_eventlog: *wel_absent - register: remove_log_again - -- name: Test remove_log_again (normal mode) - assert: - that: - - remove_log_again.changed == false - - remove_log_again.exists == false - - remove_log_again.sources_changed == [] - when: not in_check_mode diff --git a/test/integration/targets/win_eventlog_entry/aliases b/test/integration/targets/win_eventlog_entry/aliases deleted file mode 100644 index 215e0b06920..00000000000 --- a/test/integration/targets/win_eventlog_entry/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group4 diff --git a/test/integration/targets/win_eventlog_entry/defaults/main.yml b/test/integration/targets/win_eventlog_entry/defaults/main.yml deleted file mode 100644 index 611d16ec0ef..00000000000 --- a/test/integration/targets/win_eventlog_entry/defaults/main.yml +++ /dev/null @@ -1,6 +0,0 @@ -win_test_log_source: - log: WinEventLogEntryTest - source: WinEventLogEntrySource -win_test_log_source_extra: - log: ExtraWinEventLogEntryTest - source: ExtraWinEventLogEntrySource diff --git a/test/integration/targets/win_eventlog_entry/library/test_win_eventlog_entry.ps1 b/test/integration/targets/win_eventlog_entry/library/test_win_eventlog_entry.ps1 deleted file mode 100644 index 2af179b5f66..00000000000 --- a/test/integration/targets/win_eventlog_entry/library/test_win_eventlog_entry.ps1 +++ /dev/null @@ -1,33 +0,0 @@ -#!powershell - -# (c) 2017, Andrew Saraceni -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -# Test module used to grab the latest entry from an event log and output its properties - -$ErrorActionPreference = "Stop" - -$params = Parse-Args $args -supports_check_mode $true -$log = Get-AnsibleParam -obj $params -name "log" -type "str" -failifempty $true - -$result = @{ - changed = $false -} - -try { - $log_entry = Get-EventLog -LogName $log | Select-Object -First 1 -Property * -} -catch { - Fail-Json -obj $result -message "Could not find any entries for log $log" -} - -$result.source = $log_entry.Source -$result.event_id = $log_entry.EventID -$result.message = $log_entry.Message -$result.entry_type = $log_entry.EntryType.ToString() -$result.category = $log_entry.CategoryNumber -$result.raw_data = $log_entry.Data -join "," - -Exit-Json -obj $result diff --git a/test/integration/targets/win_eventlog_entry/tasks/main.yml b/test/integration/targets/win_eventlog_entry/tasks/main.yml deleted file mode 100644 index 142a3897a6d..00000000000 --- a/test/integration/targets/win_eventlog_entry/tasks/main.yml +++ /dev/null @@ -1,33 +0,0 @@ -# win_shell invocations can eventually be replaced with win_eventlog -- name: Remove potentially leftover test logs and sources - win_shell: Remove-EventLog -LogName "{{ item.log }}" -ErrorAction SilentlyContinue - with_items: - - "{{ win_test_log_source }}" - - "{{ win_test_log_source_extra }}" - failed_when: no - -- name: Add new test logs and sources - win_shell: New-EventLog -LogName "{{ item.log }}" -Source "{{ item.source }}" - with_items: - - "{{ win_test_log_source }}" - - "{{ win_test_log_source_extra }}" - -- name: Run tests for win_eventlog_entry - block: - - - name: Test in normal mode - import_tasks: tests.yml - vars: - in_check_mode: no - - - name: Test in check-mode - import_tasks: tests.yml - vars: - in_check_mode: yes - check_mode: yes - -- name: Remove test logs and sources - win_shell: Remove-EventLog -LogName "{{ item.log }}" - with_items: - - "{{ win_test_log_source }}" - - "{{ win_test_log_source_extra }}" diff --git a/test/integration/targets/win_eventlog_entry/tasks/tests.yml b/test/integration/targets/win_eventlog_entry/tasks/tests.yml deleted file mode 100644 index 17b78eb0efd..00000000000 --- a/test/integration/targets/win_eventlog_entry/tasks/tests.yml +++ /dev/null @@ -1,159 +0,0 @@ -# Test code for win_eventlog_entry - -# (c) 2017, Andrew Saraceni -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Add entry to fake log - win_eventlog_entry: - log: FakeLogName - source: "{{ win_test_log_source.source }}" - event_id: 12345 - message: This is a test log entry message - register: add_entry_to_fake_log - failed_when: add_entry_to_fake_log.changed != false or add_entry_to_fake_log.msg != "Log FakeLogName does not exist and cannot be written to" - - -- name: Add entry from fake source - win_eventlog_entry: - log: "{{ win_test_log_source.log }}" - source: FakeSourceName - event_id: 12345 - message: This is a test log entry message - register: add_entry_from_fake_source - failed_when: add_entry_from_fake_source.changed != false or add_entry_from_fake_source.msg != "Source FakeSourceName does not exist" - - -- name: Add entry with invalid event_id - win_eventlog_entry: - log: "{{ win_test_log_source.log }}" - source: "{{ win_test_log_source.source }}" - event_id: 67000 - message: This is a test log entry message - register: add_entry_with_invalid_event_id - failed_when: add_entry_with_invalid_event_id.changed != false or add_entry_with_invalid_event_id.msg != "Event ID must be between 0 and 65535" - - -- name: Add entry from other log source - win_eventlog_entry: - log: "{{ win_test_log_source.log }}" - source: "{{ win_test_log_source_extra.source }}" - event_id: 12345 - message: This is a test log entry message - register: add_entry_from_other_log_source - failed_when: add_entry_from_other_log_source.changed != false or add_entry_from_other_log_source.msg != "Source {{ win_test_log_source_extra.source }} does not belong to log {{ win_test_log_source.log }} and cannot be written to" - - -- name: Add entry - win_eventlog_entry: &wele - log: "{{ win_test_log_source.log }}" - source: "{{ win_test_log_source.source }}" - event_id: 12345 - message: This is a test log entry message - register: add_entry - -- name: Test add_entry - assert: - that: - - add_entry.changed == true - - add_entry.msg == "Entry added to log {{ win_test_log_source.log }} from source {{ win_test_log_source.source }}" - -- name: Test add_entry count (normal mode) - win_shell: (Get-EventLog -LogName "{{ win_test_log_source.log }}").Count - register: add_entry_count - failed_when: add_entry_count.stdout_lines[0] != "1" - when: not in_check_mode - -- name: Test add_entry result (normal mode) - test_win_eventlog_entry: - log: "{{ win_test_log_source.log }}" - register: add_entry_result - when: not in_check_mode - -- name: Test add_entry_result (normal mode) - assert: - that: - - add_entry_result.source == win_test_log_source.source - - add_entry_result.event_id == 12345 - - add_entry_result.message == "This is a test log entry message" - when: not in_check_mode - - -- name: Add entry (again) - win_eventlog_entry: *wele - register: add_entry_again - -- name: Test add_entry_again (normal mode) - assert: - that: - - add_entry_again.changed == true - - add_entry_again.msg == "Entry added to log {{ win_test_log_source.log }} from source {{ win_test_log_source.source }}" - when: not in_check_mode - -- name: Test add_entry_again count (normal mode) - win_shell: (Get-EventLog -LogName "{{ win_test_log_source.log }}").Count - register: add_entry_again_count - failed_when: add_entry_again_count.stdout_lines[0] != "2" - when: not in_check_mode - - -- name: Add entry all options - win_eventlog_entry: &wele_ao - <<: *wele - event_id: 500 - message: This is a test error message - entry_type: Error - category: 5 - raw_data: 10,20 - register: add_entry_all_options - -- name: Test add_entry_all_options - assert: - that: - - add_entry_all_options.changed == true - - add_entry_all_options.msg == "Entry added to log {{ win_test_log_source.log }} from source {{ win_test_log_source.source }}" - -- name: Test add_entry_all_options count (normal mode) - win_shell: (Get-EventLog -LogName "{{ win_test_log_source.log }}").Count - register: add_entry_all_options_count - failed_when: add_entry_all_options_count.stdout_lines[0] != "3" - when: not in_check_mode - -- name: Test add_entry_all_options result (normal mode) - test_win_eventlog_entry: - log: "{{ win_test_log_source.log }}" - register: add_entry_all_options_result - when: not in_check_mode - -- name: Test add_entry_all_options_result (normal mode) - assert: - that: - - add_entry_all_options_result.source == win_test_log_source.source - - add_entry_all_options_result.event_id == 500 - - add_entry_all_options_result.message == "This is a test error message" - - add_entry_all_options_result.entry_type == "Error" - - add_entry_all_options_result.category == 5 - - add_entry_all_options_result.raw_data == "10,20" - when: not in_check_mode - - -- name: Add entry all options (again) - win_eventlog_entry: *wele_ao - register: add_entry_all_options_again - -- name: Test add_entry_all_options_again (normal mode) - assert: - that: - - add_entry_all_options_again.changed == true - - add_entry_all_options_again.msg == "Entry added to log {{ win_test_log_source.log }} from source {{ win_test_log_source.source }}" - when: not in_check_mode - -- name: Test add_entry_all_options_again count (normal mode) - win_shell: (Get-EventLog -LogName "{{ win_test_log_source.log }}").Count - register: add_entry_all_options_again_count - failed_when: add_entry_all_options_again_count.stdout_lines[0] != "4" - when: not in_check_mode - - -- name: Clear event log entries - win_shell: Clear-EventLog -LogName "{{ win_test_log_source.log }}" - when: not in_check_mode diff --git a/test/integration/targets/win_file_compression/aliases b/test/integration/targets/win_file_compression/aliases deleted file mode 100644 index 4c08975b17d..00000000000 --- a/test/integration/targets/win_file_compression/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group6 diff --git a/test/integration/targets/win_file_compression/defaults/main.yml b/test/integration/targets/win_file_compression/defaults/main.yml deleted file mode 100644 index ae24afe7c33..00000000000 --- a/test/integration/targets/win_file_compression/defaults/main.yml +++ /dev/null @@ -1,5 +0,0 @@ -test_win_file_compression_suffix: win_file_compression .ÅÑŚÌβŁÈ [$!@^&test(;)] -test_win_file_compression_sub_directories: - - 'a' - - 'b' -test_win_file_compression_filename: 'foo.bar' diff --git a/test/integration/targets/win_file_compression/meta/main.yml b/test/integration/targets/win_file_compression/meta/main.yml deleted file mode 100644 index 9f37e96cd90..00000000000 --- a/test/integration/targets/win_file_compression/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: -- setup_remote_tmp_dir diff --git a/test/integration/targets/win_file_compression/tasks/main.yml b/test/integration/targets/win_file_compression/tasks/main.yml deleted file mode 100644 index 9237c5e61a8..00000000000 --- a/test/integration/targets/win_file_compression/tasks/main.yml +++ /dev/null @@ -1,224 +0,0 @@ ---- -- name: set fact of special testing dir - set_fact: - test_directory: '{{ remote_tmp_dir }}\{{ test_win_file_compression_suffix }}' - -- name: create sub directories - win_file: - state: directory - path: "{{ test_directory }}\\{{ item }}" - loop: "{{ test_win_file_compression_sub_directories }}" - -- name: set main directory as hidden to test out edge cases - win_shell: (Get-Item -LiteralPath '{{ test_directory }}').Attributes = [System.IO.FileAttributes]::Hidden - -- name: Compress parent directory - win_file_compression: - path: "{{ test_directory }}" - state: present - register: result - -- name: Get actual attributes for parent directory - win_stat: - path: "{{ test_directory }}" - register: folder_info - -- assert: - that: - - "'Compressed' in folder_info.stat.attributes" - - "result.changed == true" - -- name: Get actual attributes for sub directories - win_stat: - path: "{{ test_directory }}\\{{ item }}" - register: subfolder_info - loop: "{{ test_win_file_compression_sub_directories }}" - -- assert: - that: - - "'Compressed' not in item.stat.attributes" - loop: "{{ subfolder_info.results }}" - -- name: Compress parent directory (idempotent) - win_file_compression: - path: "{{ test_directory }}" - state: present - register: result - -- assert: - that: - - "result.changed == false" - -- name: Compress parent directory and all subdirectories - win_file_compression: - path: "{{ test_directory }}" - state: present - recurse: yes - register: result - -- name: Get actual attributes for parent directory - win_stat: - path: "{{ test_directory }}" - register: folder_info - -- assert: - that: - - "'Compressed' in folder_info.stat.attributes" - - "result.changed == true" - -- name: Get actual attributes for sub directories - win_stat: - path: "{{ test_directory }}\\{{ item }}" - register: subfolder_info - loop: "{{ test_win_file_compression_sub_directories }}" - -- assert: - that: - - "'Compressed' in item.stat.attributes" - loop: "{{ subfolder_info.results }}" - -- name: Compress parent directory and all subdirectories (idempotent) - win_file_compression: - path: "{{ test_directory }}" - state: present - recurse: yes - register: result - -- assert: - that: - - "result.changed == false" - -- name: Uncompress parent directory - win_file_compression: - path: "{{ test_directory }}" - state: absent - recurse: no - register: result - -- name: Get actual attributes for parent directory - win_stat: - path: "{{ test_directory }}" - register: folder_info - -- assert: - that: - - "'Compressed' not in folder_info.stat.attributes" - - "result.changed == true" - -- name: Get actual attributes for sub directories - win_stat: - path: "{{ test_directory }}\\{{ item }}" - register: subfolder_info - loop: "{{ test_win_file_compression_sub_directories }}" - -- assert: - that: - - "'Compressed' in item.stat.attributes" - loop: "{{ subfolder_info.results }}" - -- name: Uncompress parent directory (idempotent) - win_file_compression: - path: "{{ test_directory }}" - state: absent - recurse: no - register: result - -- assert: - that: - - "result.changed == false" - -- name: Uncompress parent directory and all subdirectories - win_file_compression: - path: "{{ test_directory }}" - state: absent - recurse: yes - register: result - -- name: Get actual attributes for parent directory - win_stat: - path: "{{ test_directory }}" - register: folder_info - -- assert: - that: - - "'Compressed' not in folder_info.stat.attributes" - - "result.changed == true" - -- name: Get actual attributes for sub directories - win_stat: - path: "{{ test_directory }}\\{{ item }}" - register: subfolder_info - loop: "{{ test_win_file_compression_sub_directories }}" - -- assert: - that: - - "'Compressed' not in item.stat.attributes" - loop: "{{ subfolder_info.results }}" - -- name: Uncompress parent directory and all subdirectories (idempotent) - win_file_compression: - path: "{{ test_directory }}" - state: absent - recurse: yes - register: result - -- assert: - that: - - "result.changed == false" - -- name: Create test file - win_file: - state: touch - path: "{{ test_directory }}\\{{ test_win_file_compression_filename }}" - -- name: Compress specific file - win_file_compression: - path: "{{ test_directory }}\\{{ test_win_file_compression_filename }}" - state: present - register: result - -- name: Get actual attributes of file - win_stat: - path: "{{ test_directory }}\\{{ test_win_file_compression_filename }}" - register: testfile_info - -- assert: - that: - - "result.changed == true" - - "'Compressed' in testfile_info.stat.attributes" - -- name: Compress specific file (idempotent) - win_file_compression: - path: "{{ test_directory }}\\{{ test_win_file_compression_filename }}" - state: present - register: result - -- assert: - that: - - "result.changed == false" - -- name: Uncompress specific file - win_file_compression: - path: "{{ test_directory }}\\{{ test_win_file_compression_filename }}" - state: absent - register: result - -- name: Get actual attributes of file - win_stat: - path: "{{ test_directory }}\\{{ test_win_file_compression_filename }}" - register: testfile_info - -- assert: - that: - - "result.changed == true" - - "'Compressed' not in testfile_info.stat.attributes" - -- name: Uncompress specific file (idempotent) - win_file_compression: - path: "{{ test_directory }}\\{{ test_win_file_compression_filename }}" - state: absent - register: result - -- assert: - that: - - "result.changed == false" diff --git a/test/integration/targets/win_firewall/aliases b/test/integration/targets/win_firewall/aliases deleted file mode 100644 index 3ca843d7c3a..00000000000 --- a/test/integration/targets/win_firewall/aliases +++ /dev/null @@ -1,5 +0,0 @@ -shippable/windows/group2 -skip/windows/2008 -skip/windows/2008-R2 -skip/windows/2012 -skip/windows/2012-R2 diff --git a/test/integration/targets/win_firewall/tasks/main.yml b/test/integration/targets/win_firewall/tasks/main.yml deleted file mode 100644 index 522a5e59c96..00000000000 --- a/test/integration/targets/win_firewall/tasks/main.yml +++ /dev/null @@ -1,52 +0,0 @@ -# NOTE: The win_firewall module only works on WMF 5+ - -- setup: - -- name: Test Windows capabilities - raw: Get-Command Get-NetFirewallProfile -ErrorAction SilentlyContinue; return $? - failed_when: no - register: get_netfirewallprofile - -- name: Only run tests when Windows is capable - when: get_netfirewallprofile.rc == 0 and ansible_powershell_version >= 5 - block: - - name: Turn off Windows Firewall (begin) - win_firewall: - profiles: [ Domain, Private, Public ] - state: disabled - register: firewall_off - - - name: Test firewall_off - assert: - that: - - not firewall_off.Domain.enabled - - not firewall_off.Private.enabled - - not firewall_off.Public.enabled - - - - name: Test in normal mode - import_tasks: tests.yml - vars: - in_check_mode: no - - - - name: Test in check-mode - import_tasks: tests.yml - vars: - in_check_mode: yes - check_mode: yes - - - - name: Turn on Windows Firewall (end) - win_firewall: - profiles: [ Domain, Private, Public ] - state: enabled - register: firewall_on - - - name: Test firewall_on - assert: - that: - - firewall_on is changed - - firewall_on.Domain.enabled - - firewall_on.Private.enabled - - firewall_on.Public.enabled diff --git a/test/integration/targets/win_firewall/tasks/tests.yml b/test/integration/targets/win_firewall/tasks/tests.yml deleted file mode 100644 index ae5874ca5b1..00000000000 --- a/test/integration/targets/win_firewall/tasks/tests.yml +++ /dev/null @@ -1,185 +0,0 @@ -# We start with firewall turned off - -- name: Turn off Windows Firewall again - win_firewall: - profiles: [ Domain, Private, Public ] - state: disabled - register: firewall_off_again - -- name: Test firewall_off_again - assert: - that: - - firewall_off_again is not changed - - not firewall_off_again.Domain.enabled - - not firewall_off_again.Private.enabled - - not firewall_off_again.Public.enabled - -- name: Turn on Windows Firewall on Public - win_firewall: - profiles: [ Public ] - state: enabled - register: firewall_public_on - -- name: Test firewall_public_on - assert: - that: - - firewall_public_on is changed - - not firewall_public_on.Domain.enabled - - not firewall_public_on.Private.enabled - - firewall_public_on.Public.enabled - - -- name: Turn on Windows Firewall on Public again - win_firewall: - profiles: [ Public ] - state: enabled - register: firewall_public_on_again - -- name: Test firewall_public_on_again (normal mode) - assert: - that: - - firewall_public_on_again is not changed - - not firewall_public_on_again.Domain.enabled - - not firewall_public_on_again.Private.enabled - - firewall_public_on_again.Public.enabled - when: not in_check_mode - -- name: Test firewall_public_on_again (check-mode) - assert: - that: - - firewall_public_on_again is changed - - not firewall_public_on_again.Domain.enabled - - not firewall_public_on_again.Private.enabled - - firewall_public_on_again.Public.enabled - when: in_check_mode - - -# On purpose not a list -- name: Turn on Windows Firewall on Domain - win_firewall: - profiles: Domain - state: enabled - register: firewall_domain_on - -- name: Test firewall_domain_on (normal mode) - assert: - that: - - firewall_domain_on is changed - - firewall_domain_on.Domain.enabled - - not firewall_domain_on.Private.enabled - - firewall_domain_on.Public.enabled - when: not in_check_mode - -- name: Test firewall_domain_on (check-mode) - assert: - that: - - firewall_domain_on is changed - - firewall_domain_on.Domain.enabled - - not firewall_domain_on.Private.enabled - - not firewall_domain_on.Public.enabled - when: in_check_mode - - -- name: Turn on Windows Firewall on Domain again - win_firewall: - profiles: [ Domain ] - state: enabled - register: firewall_domain_on_again - -- name: Test firewall_domain_on_again (normal mode) - assert: - that: - - firewall_domain_on_again is not changed - - firewall_domain_on.Domain.enabled - - not firewall_domain_on.Private.enabled - - firewall_domain_on.Public.enabled - when: not in_check_mode - -- name: Test firewall_domain_on_again (check-mode) - assert: - that: - - firewall_domain_on_again is changed - - firewall_domain_on.Domain.enabled - - not firewall_domain_on.Private.enabled - - not firewall_domain_on.Public.enabled - when: in_check_mode - - -- name: Turn on Windows Firewall - win_firewall: - profiles: [ Domain, Private, Public ] - state: enabled - register: firewall_on - -- name: Test firewall_on - assert: - that: - - firewall_on is changed - - firewall_on.Domain.enabled - - firewall_on.Private.enabled - - firewall_on.Public.enabled - - -# On purpose no profiles added -- name: Turn on Windows Firewall again - win_firewall: - state: enabled - register: firewall_on_again - -- name: Test firewall_on_again (normal mode) - assert: - that: - - firewall_on_again is not changed - - firewall_on_again.Domain.enabled - - firewall_on_again.Private.enabled - - firewall_on_again.Public.enabled - when: not in_check_mode - -- name: Test firewall_on_again (check-mode) - assert: - that: - - firewall_on_again is changed - - firewall_on_again.Domain.enabled - - firewall_on_again.Private.enabled - - firewall_on_again.Public.enabled - when: in_check_mode - - -# On purpose no profiles added -- name: Turn off Windows Firewall - win_firewall: - state: disabled - register: firewall_off2 - -- name: Test firewall_off2 (normal mode) - assert: - that: - - firewall_off2 is changed - - not firewall_off2.Domain.enabled - - not firewall_off2.Private.enabled - - not firewall_off2.Public.enabled - when: not in_check_mode - -- name: Test firewall_off2 (check-mode) - assert: - that: - - firewall_off2 is not changed - - not firewall_off2.Domain.enabled - - not firewall_off2.Private.enabled - - not firewall_off2.Public.enabled - when: in_check_mode - - -- name: Turn off Windows Firewall again - win_firewall: - profiles: [ Domain, Private, Public ] - state: disabled - register: firewall_off2_again - -- name: Test firewall_off2_again (normal mode) - assert: - that: - - firewall_off2_again is not changed - - not firewall_off2_again.Domain.enabled - - not firewall_off2_again.Private.enabled - - not firewall_off2_again.Public.enabled diff --git a/test/integration/targets/win_firewall_rule/aliases b/test/integration/targets/win_firewall_rule/aliases deleted file mode 100644 index 215e0b06920..00000000000 --- a/test/integration/targets/win_firewall_rule/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group4 diff --git a/test/integration/targets/win_firewall_rule/tasks/main.yml b/test/integration/targets/win_firewall_rule/tasks/main.yml deleted file mode 100644 index fe0d1aa0883..00000000000 --- a/test/integration/targets/win_firewall_rule/tasks/main.yml +++ /dev/null @@ -1,474 +0,0 @@ -- name: Remove potentially leftover firewall rule - win_firewall_rule: - name: http - state: absent - action: allow - direction: in - -- name: Add firewall rule - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - action: allow - direction: in - protocol: tcp - register: add_firewall_rule - -- name: Check that creating new firewall rule succeeds with a change - assert: - that: - - add_firewall_rule.changed == true - -- name: Add same firewall rule (again) - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - action: allow - direction: in - protocol: tcp - register: add_firewall_rule_again - -- name: Check that creating same firewall rule succeeds without a change - assert: - that: - - add_firewall_rule_again.changed == false - -- name: Remove firewall rule - win_firewall_rule: - name: http - enabled: yes - state: absent - localport: 80 - action: allow - direction: in - protocol: tcp - register: remove_firewall_rule - -- name: Check that removing existing firewall rule succeeds with a change - assert: - that: - - remove_firewall_rule.changed == true - -- name: Remove absent firewall rule - win_firewall_rule: - name: http - enabled: yes - state: absent - localport: 80 - action: allow - direction: in - protocol: tcp - register: remove_absent_firewall_rule - -- name: Check that removing non existing firewall rule succeeds without a change - assert: - that: - - remove_absent_firewall_rule.changed == false - -- name: Add firewall rule - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - action: allow - direction: in - protocol: tcp - -- name: Change firewall rule - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - action: block - direction: in - protocol: tcp - register: change_firewall_rule - -- name: Check that changing firewall rule succeeds - assert: - that: - - change_firewall_rule.changed == true - -- name: Disable firewall rule - win_firewall_rule: - name: http - enabled: no - -- name: Get the actual values from the changed firewall rule - win_shell: '(New-Object -ComObject HNetCfg.FwPolicy2).Rules | Where-Object { $_.Name -eq "http" } | Foreach-Object { $_.LocalPorts; $_.Enabled; $_.Action; $_.Direction; $_.Protocol }' - register: firewall_rule_actual - -- name: Ensure that disabling the rule did not change the previous values - assert: - that: - - "firewall_rule_actual.stdout_lines[0] == '80'" # LocalPorts = 80 - - "firewall_rule_actual.stdout_lines[1] == 'False'" # Enabled = False - - "firewall_rule_actual.stdout_lines[2] == '0'" # Action = block - - "firewall_rule_actual.stdout_lines[3] == '1'" # Direction = in - - "firewall_rule_actual.stdout_lines[4] == '6'" # Protocol = tcp - -- name: Add firewall rule when remoteip is range - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - remoteip: 192.168.0.1-192.168.0.5 - action: allow - direction: in - protocol: tcp - -- name: Add same firewall rule when remoteip is range (again) - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - remoteip: 192.168.0.1-192.168.0.5 - action: allow - direction: in - protocol: tcp - register: add_firewall_rule_with_range_remoteip_again - -- name: Check that creating same firewall rule when remoteip is range succeeds without a change - assert: - that: - - add_firewall_rule_with_range_remoteip_again.changed == false - -- name: Add firewall rule when remoteip in CIDR notation - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - remoteip: 192.168.0.0/24 - action: allow - direction: in - protocol: tcp - -- name: Add same firewall rule when remoteip in CIDR notation (again) - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - remoteip: 192.168.0.0/24 - action: allow - direction: in - protocol: tcp - register: add_firewall_rule_with_cidr_remoteip_again - -- name: Check that creating same firewall rule succeeds without a change when remoteip in CIDR notation - assert: - that: - - add_firewall_rule_with_cidr_remoteip_again.changed == false - -- name: Add firewall rule when remoteip contains a netmask - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - remoteip: 192.168.1.0/255.255.255.0 - action: allow - direction: in - protocol: tcp - -- name: Add same firewall rule when remoteip contains a netmask (again) - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - remoteip: 192.168.1.0/255.255.255.0 - action: allow - direction: in - protocol: tcp - register: add_firewall_rule_remoteip_contains_netmask_again - -- name: Check that creating same firewall rule succeeds without a change when remoteip contains a netmask - assert: - that: - - add_firewall_rule_remoteip_contains_netmask_again.changed == false - -- name: Add firewall rule when remoteip is IPv4 - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - remoteip: 192.168.0.1 - action: allow - direction: in - protocol: tcp - -- name: Add same firewall rule when remoteip is IPv4 (again) - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - remoteip: 192.168.0.1 - action: allow - direction: in - protocol: tcp - register: add_firewall_rule_with_ipv4_remoteip_again - -- name: Check that creating same firewall rule when remoteip is IPv4 succeeds without a change - assert: - that: - - add_firewall_rule_with_ipv4_remoteip_again.changed == false - -- name: Add firewall rule when remoteip contains a netmask - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - remoteip: 192.168.2.0/255.255.255.0 - action: allow - direction: in - protocol: tcp - -- name: Add same firewall rule when remoteip in CIDR notation - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - remoteip: 192.168.2.0/24 - action: allow - direction: in - protocol: tcp - register: add_same_firewall_rule_with_cidr_remoteip - -- name: Check that creating same firewall rule succeeds without a change when remoteip contains a netmask or CIDR - assert: - that: - - add_same_firewall_rule_with_cidr_remoteip.changed == false - -- name: Add firewall rule with multiple ports - win_firewall_rule: - name: http - enabled: yes - state: present - localport: '80,81' - action: allow - direction: in - protocol: tcp - register: add_firewall_rule_with_multiple_ports - -- name: Check that creating firewall rule with multiple ports succeeds with a change - assert: - that: - - add_firewall_rule_with_multiple_ports.changed == true - -- name: Add firewall rule with interface types in string format - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - action: allow - direction: in - protocol: tcp - interfacetypes: 'ras,lan,wireless' - register: add_firewall_rule_with_string_interface_types - -- name: Check that creating firewall rule with interface types in string format succeeds with a change - assert: - that: - - add_firewall_rule_with_string_interface_types.changed == true - -- name: Add firewall rule with interface types in list format - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - action: allow - direction: in - protocol: tcp - interfacetypes: [ras, lan] - register: add_firewall_rule_with_list_interface_types - -- name: Check that creating firewall rule with interface types in list format succeeds with a change - assert: - that: - - add_firewall_rule_with_list_interface_types.changed == true - -- name: Add firewall rule with interface type 'any' - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - action: allow - direction: in - protocol: tcp - interfacetypes: any - register: add_firewall_rule_with_interface_type_any - -- name: Check that creating firewall rule with interface type 'any' succeeds with a change - assert: - that: - - add_firewall_rule_with_interface_type_any.changed == true - -- name: Add firewall rule with edge traversal option 'deferapp' - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - action: allow - direction: in - protocol: tcp - edge: deferapp - register: add_firewall_rule_with_edge_traversal - -# Setup action creates ansible_distribution_version variable -- action: setup - -- name: Check that creating firewall rule with enge traversal option 'deferapp' succeeds with a change - assert: - that: - - add_firewall_rule_with_edge_traversal.changed == true - # Works on windows >= Windows 7/Windows Server 2008 R2 - when: ansible_distribution_version is version('6.1', '>=') - -- name: Add firewall rule with 'authenticate' secure flag - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - action: allow - direction: in - protocol: tcp - security: authenticate - register: add_firewall_rule_with_secure_flags - -- name: Check that creating firewall rule with secure flag 'authenticate' succeeds with a change - assert: - that: - - add_firewall_rule_with_secure_flags.changed == true - # Works on windows >= Windows 8/Windows Server 2012 - when: ansible_distribution_version is version('6.2', '>=') - -- name: Add firewall rule with profiles in string format - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - action: allow - direction: in - protocol: tcp - profiles: 'domain,public' - register: add_firewall_rule_with_string_profiles - -- name: Check that creating firewall rule with profiles in string format succeeds with a change - assert: - that: - - add_firewall_rule_with_string_profiles.changed == true - -- name: Set firewall rule profile back to 'all' - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - action: allow - direction: in - protocol: tcp - profiles: [Domain, Public, Private] - register: add_firewall_rule_with_string_profiles - -- name: Check that setting firewall rule profile back to 'all' succeeds with a change - assert: - that: - - add_firewall_rule_with_string_profiles.changed == true - -- name: Add firewall rule with profiles in list format - win_firewall_rule: - name: http - enabled: yes - state: present - localport: 80 - action: allow - direction: in - protocol: tcp - profiles: [Domain, Private] - register: add_firewall_rule_with_list_profiles - -- name: Check that creating firewall rule with profiles in list format succeeds with a change - assert: - that: - - add_firewall_rule_with_list_profiles.changed == true - -# Test for variable expansion in the path -- name: Add rule with path that needs to be expanded - win_firewall_rule: - name: VarExpansionTest - enabled: yes - state: present - action: allow - direction: in - protocol: tcp - program: '%SystemRoot%\system32\svchost.exe' - -- name: Add same rule with path that needs to be expanded - win_firewall_rule: - name: VarExpansionTest - enabled: yes - state: present - action: allow - direction: in - protocol: tcp - program: '%SystemRoot%\system32\svchost.exe' - register: add_firewall_rule_with_var_expand_path - -- name: Check that creating same firewall rule with expanded vars identified - assert: - that: - - add_firewall_rule_with_var_expand_path.changed == false - -- name: Add firewall rule for application group - win_firewall_rule: - name: Rule for application group - enabled: yes - state: present - localport: 80 - action: allow - direction: in - protocol: tcp - group: application - register: add_firewall_rule_with_group - -- name: Check that creating firewall rule for application group succeeds with a change - assert: - that: - - add_firewall_rule_with_group.changed == true - -# Test icmptypecode -- name: Add rule with icmptypecode - win_firewall_rule: - name: icmptest - enabled: yes - state: present - action: allow - direction: in - protocol: icmpv4 - icmp_type_code: '8:*' - register: add_firewall_rule_with_icmptypecode - -- name: Check that creating same firewall rule with expanded vars identified - assert: - that: - - add_firewall_rule_with_icmptypecode.changed == true diff --git a/test/integration/targets/win_format/aliases b/test/integration/targets/win_format/aliases deleted file mode 100644 index 3aa71f86abd..00000000000 --- a/test/integration/targets/win_format/aliases +++ /dev/null @@ -1,3 +0,0 @@ -shippable/windows/group4 -skip/windows/2008 -skip/windows/2008-R2 diff --git a/test/integration/targets/win_format/meta/main.yml b/test/integration/targets/win_format/meta/main.yml deleted file mode 100644 index 9f37e96cd90..00000000000 --- a/test/integration/targets/win_format/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: -- setup_remote_tmp_dir diff --git a/test/integration/targets/win_format/tasks/main.yml b/test/integration/targets/win_format/tasks/main.yml deleted file mode 100644 index de773469df2..00000000000 --- a/test/integration/targets/win_format/tasks/main.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -- name: Check if Format-Volume is supported - win_shell: if (Get-Command -Name Format-Volume -ErrorAction SilentlyContinue) { $true } else { $false } - register: module_present - -- include: pre_test.yml - when: module_present.stdout | trim | bool diff --git a/test/integration/targets/win_format/tasks/pre_test.yml b/test/integration/targets/win_format/tasks/pre_test.yml deleted file mode 100644 index edc59ae52c5..00000000000 --- a/test/integration/targets/win_format/tasks/pre_test.yml +++ /dev/null @@ -1,21 +0,0 @@ ---- -- set_fact: - AnsibleVhdx: '{{ remote_tmp_dir }}\AnsiblePart.vhdx' - -- name: Copy VHDX scripts - win_template: - src: "{{ item.src }}" - dest: '{{ remote_tmp_dir }}\{{ item.dest }}' - loop: - - { src: partition_creation_script.j2, dest: partition_creation_script.txt } - - { src: partition_deletion_script.j2, dest: partition_deletion_script.txt } - -- name: Create partition - win_command: diskpart.exe /s {{ remote_tmp_dir }}\partition_creation_script.txt - -- name: Run tests - block: - - include: tests.yml - always: - - name: Detach disk - win_command: diskpart.exe /s {{ remote_tmp_dir }}\partition_deletion_script.txt diff --git a/test/integration/targets/win_format/tasks/tests.yml b/test/integration/targets/win_format/tasks/tests.yml deleted file mode 100644 index 5036164eab2..00000000000 --- a/test/integration/targets/win_format/tasks/tests.yml +++ /dev/null @@ -1,182 +0,0 @@ ---- -- win_shell: $AnsiPart = Get-Partition -DriveLetter T; $AnsiVol = Get-Volume -DriveLetter T; "$($AnsiPart.Size),$($AnsiVol.Size)" - register: shell_result - -- name: Assert volume size is 0 for pristine volume - assert: - that: - - shell_result.stdout | trim == "2096037888,0" - -- name: Get partition access path - win_shell: (Get-Partition -DriveLetter T).AccessPaths[1] - register: shell_partition_result - -- name: Try to format using mutually exclusive parameters - win_format: - drive_letter: T - path: "{{ shell_partition_result.stdout | trim }}" - register: format_mutex_result - ignore_errors: True - -- assert: - that: - - format_mutex_result is failed - - 'format_mutex_result.msg == "parameters are mutually exclusive: drive_letter, path, label"' - -- name: Fully format volume and assign label (check) - win_format: - drive_letter: T - new_label: Formatted - full: True - allocation_unit_size: 8192 - register: format_result_check - check_mode: True - -- win_shell: $AnsiPart = Get-Partition -DriveLetter T; $AnsiVol = Get-Volume -DriveLetter T; "$($AnsiPart.Size),$($AnsiVol.Size),$($AnsiVol.FileSystemLabel),$((Get-CimInstance -ClassName Win32_Volume -Filter "DriveLetter = 'T:'" -Property BlockSize).BlockSize)" - register: formatted_value_result_check - -- name: Fully format volume and assign label - win_format: - drive_letter: T - new_label: Formatted - full: True - allocation_unit_size: 8192 - register: format_result - -- win_shell: $AnsiPart = Get-Partition -DriveLetter T; $AnsiVol = Get-Volume -DriveLetter T; "$($AnsiPart.Size),$($AnsiVol.Size),$($AnsiVol.FileSystemLabel),$((Get-CimInstance -ClassName Win32_Volume -Filter "DriveLetter = 'T:'" -Property BlockSize).BlockSize)" - register: formatted_value_result - -- assert: - that: - - format_result_check is changed - - format_result is changed - - formatted_value_result_check.stdout | trim == "2096037888,0,," - - formatted_value_result.stdout | trim == "2096037888,2096029696,Formatted,8192" - -- name: Format NTFS volume with integrity streams enabled - win_format: - path: "{{ shell_partition_result.stdout | trim }}" - file_system: ntfs - integrity_streams: True - ignore_errors: True - register: ntfs_integrity_streams - -- assert: - that: - - ntfs_integrity_streams is failed - - 'ntfs_integrity_streams.msg == "Integrity streams can be enabled only on ReFS volumes. You specified: ntfs"' - -- name: Format volume (require force_format for specifying different file system) - win_format: - path: "{{ shell_partition_result.stdout | trim }}" - file_system: fat32 - ignore_errors: True - register: require_force_format - -- assert: - that: - - require_force_format is failed - - 'require_force_format.msg == "Force format must be specified since target file system: fat32 is different from the current file system of the volume: ntfs"' - -- name: Format volume (forced) (check) - win_format: - path: "{{ shell_partition_result.stdout | trim }}" - file_system: refs - force: True - check_mode: True - ignore_errors: True - register: not_pristine_forced_check - -- name: Format volume (forced) - win_format: - path: "{{ shell_partition_result.stdout | trim }}" - file_system: refs - force: True - register: not_pristine_forced - -- name: Format volume (forced) (idempotence will not work) - win_format: - path: "{{ shell_partition_result.stdout | trim }}" - file_system: refs - force: True - register: not_pristine_forced_idem_fails - -- name: Format volume (idempotence) - win_format: - path: "{{ shell_partition_result.stdout | trim }}" - file_system: refs - register: not_pristine_forced_idem - -- assert: - that: - - not_pristine_forced_check is changed - - not_pristine_forced is changed - - not_pristine_forced_idem_fails is changed - - not_pristine_forced_idem is not changed - -- name: Add a file - win_file: - path: T:\path\to\directory - state: directory - -- name: Format volume with file inside without force and same fs - win_format: - path: "{{ shell_partition_result.stdout | trim }}" - register: format_volume_without_force_same_fs - -- name: Format volume (forced) - to test case for files existing and a different fs - win_format: - path: "{{ shell_partition_result.stdout | trim }}" - file_system: ntfs - force: True - -- name: Add a file - win_file: - path: T:\path\to\directory - state: directory - register: add_file_to_volume - -- name: Format volume with file inside without force - win_format: - path: "{{ shell_partition_result.stdout | trim }}" - file_system: refs - register: format_volume_without_force - ignore_errors: True - -- name: Format volume with file inside with force - win_format: - path: "{{ shell_partition_result.stdout | trim }}" - force: True - register: format_volume_with_force - -- assert: - that: - - add_file_to_volume is changed - - format_volume_without_force is failed - - format_volume_without_force_same_fs is not changed - - 'format_volume_without_force.msg == "Force format must be specified to format non-pristine volumes"' - - format_volume_with_force is changed - -- name: Reformat using different alu without force format - win_format: - path: "{{ shell_partition_result.stdout | trim }}" - allocation_unit_size: 8192 - file_system: ntfs - register: reformat_using_alu_without_force - ignore_errors: True - -- assert: - that: - - reformat_using_alu_without_force is failed - -- name: Reformat using different alu using force format - win_format: - path: "{{ shell_partition_result.stdout | trim }}" - allocation_unit_size: 8192 - file_system: ntfs - force: True - register: reformat_using_alu_with_force - -- assert: - that: - - reformat_using_alu_with_force is changed diff --git a/test/integration/targets/win_format/templates/partition_creation_script.j2 b/test/integration/targets/win_format/templates/partition_creation_script.j2 deleted file mode 100644 index 8e47fda95ba..00000000000 --- a/test/integration/targets/win_format/templates/partition_creation_script.j2 +++ /dev/null @@ -1,11 +0,0 @@ -create vdisk file="{{ AnsibleVhdx }}" maximum=2000 type=fixed - -select vdisk file="{{ AnsibleVhdx }}" - -attach vdisk - -convert mbr - -create partition primary - -assign letter="T" diff --git a/test/integration/targets/win_format/templates/partition_deletion_script.j2 b/test/integration/targets/win_format/templates/partition_deletion_script.j2 deleted file mode 100644 index c2be9cd1446..00000000000 --- a/test/integration/targets/win_format/templates/partition_deletion_script.j2 +++ /dev/null @@ -1,3 +0,0 @@ -select vdisk file="{{ AnsibleVhdx }}" - -detach vdisk diff --git a/test/integration/targets/win_hosts/aliases b/test/integration/targets/win_hosts/aliases deleted file mode 100644 index 6036e173f1a..00000000000 --- a/test/integration/targets/win_hosts/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group7 diff --git a/test/integration/targets/win_hosts/defaults/main.yml b/test/integration/targets/win_hosts/defaults/main.yml deleted file mode 100644 index c6270216d68..00000000000 --- a/test/integration/targets/win_hosts/defaults/main.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- -test_win_hosts_cname: testhost -test_win_hosts_ip: 192.168.168.1 - -test_win_hosts_aliases_set: - - alias1 - - alias2 - - alias3 - - alias4 - -test_win_hosts_aliases_remove: - - alias3 - - alias4 diff --git a/test/integration/targets/win_hosts/meta/main.yml b/test/integration/targets/win_hosts/meta/main.yml deleted file mode 100644 index 9f37e96cd90..00000000000 --- a/test/integration/targets/win_hosts/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: -- setup_remote_tmp_dir diff --git a/test/integration/targets/win_hosts/tasks/main.yml b/test/integration/targets/win_hosts/tasks/main.yml deleted file mode 100644 index 0997375f9fd..00000000000 --- a/test/integration/targets/win_hosts/tasks/main.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- -- name: take a copy of the original hosts file - win_copy: - src: C:\Windows\System32\drivers\etc\hosts - dest: '{{ remote_tmp_dir }}\hosts' - remote_src: yes - -- block: - - name: run tests - include_tasks: tests.yml - - always: - - name: restore hosts file - win_copy: - src: '{{ remote_tmp_dir }}\hosts' - dest: C:\Windows\System32\drivers\etc\hosts - remote_src: yes diff --git a/test/integration/targets/win_hosts/tasks/tests.yml b/test/integration/targets/win_hosts/tasks/tests.yml deleted file mode 100644 index a29e01a708b..00000000000 --- a/test/integration/targets/win_hosts/tasks/tests.yml +++ /dev/null @@ -1,189 +0,0 @@ ---- - -- name: add a simple host with address - win_hosts: - state: present - ip_address: "{{ test_win_hosts_ip }}" - canonical_name: "{{ test_win_hosts_cname }}" - register: add_ip - -- assert: - that: - - "add_ip.changed == true" - -- name: get actual dns result - win_shell: "try{ [array]$t = [Net.DNS]::GetHostEntry('{{ test_win_hosts_cname }}') } catch { return 'false' } if ($t[0].HostName -eq '{{ test_win_hosts_cname }}' -and $t[0].AddressList[0].toString() -eq '{{ test_win_hosts_ip }}'){ return 'true' } else { return 'false' }" - register: add_ip_actual - -- assert: - that: - - "add_ip_actual.stdout_lines[0]|lower == 'true'" - -- name: add a simple host with ipv4 address (idempotent) - win_hosts: - state: present - ip_address: "{{ test_win_hosts_ip }}" - canonical_name: "{{ test_win_hosts_cname }}" - register: add_ip - -- assert: - that: - - "add_ip.changed == false" - -- name: remove simple host - win_hosts: - state: absent - ip_address: "{{ test_win_hosts_ip }}" - canonical_name: "{{ test_win_hosts_cname }}" - register: remove_ip - -- assert: - that: - - "remove_ip.changed == true" - -- name: get actual dns result - win_shell: "try{ [array]$t = [Net.DNS]::GetHostEntry('{{ test_win_hosts_cname}}') } catch { return 'false' } if ($t[0].HostName -eq '{{ test_win_hosts_cname }}' -and $t[0].AddressList[0].toString() -eq '{{ test_win_hosts_ip }}'){ return 'true' } else { return 'false' }" - register: remove_ip_actual - failed_when: "remove_ip_actual.rc == 0" - -- assert: - that: - - "remove_ip_actual.stdout_lines[0]|lower == 'false'" - -- name: remove simple host (idempotent) - win_hosts: - state: absent - ip_address: "{{ test_win_hosts_ip }}" - canonical_name: "{{ test_win_hosts_cname }}" - register: remove_ip - -- assert: - that: - - "remove_ip.changed == false" - -- name: add host and set aliases - win_hosts: - state: present - ip_address: "{{ test_win_hosts_ip }}" - canonical_name: "{{ test_win_hosts_cname }}" - aliases: "{{ test_win_hosts_aliases_set | union(test_win_hosts_aliases_remove) }}" - action: set - register: set_aliases - -- assert: - that: - - "set_aliases.changed == true" - -- name: get actual dns result for host - win_shell: "try{ [array]$t = [Net.DNS]::GetHostEntry('{{ test_win_hosts_cname }}') } catch { return 'false' } if ($t[0].HostName -eq '{{ test_win_hosts_cname }}' -and $t[0].AddressList[0].toString() -eq '{{ test_win_hosts_ip }}'){ return 'true' } else { return 'false' }" - register: set_aliases_actual_host - -- assert: - that: - - "set_aliases_actual_host.stdout_lines[0]|lower == 'true'" - -- name: get actual dns results for aliases - win_shell: "try{ [array]$t = [Net.DNS]::GetHostEntry('{{ item }}') } catch { return 'false' } if ($t[0].HostName -eq '{{ test_win_hosts_cname }}' -and $t[0].AddressList[0].toString() -eq '{{ test_win_hosts_ip }}'){ return 'true' } else { return 'false' }" - register: set_aliases_actual - with_items: "{{ test_win_hosts_aliases_set | union(test_win_hosts_aliases_remove) }}" - -- assert: - that: - - "item.stdout_lines[0]|lower == 'true'" - with_items: "{{ set_aliases_actual.results }}" - -- name: add host and set aliases (idempotent) - win_hosts: - state: present - ip_address: "{{ test_win_hosts_ip }}" - canonical_name: "{{ test_win_hosts_cname }}" - aliases: "{{ test_win_hosts_aliases_set | union(test_win_hosts_aliases_remove) }}" - action: set - register: set_aliases - -- assert: - that: - - "set_aliases.changed == false" - -- name: remove aliases from the list - win_hosts: - state: present - ip_address: "{{ test_win_hosts_ip }}" - canonical_name: "{{ test_win_hosts_cname }}" - aliases: "{{ test_win_hosts_aliases_remove }}" - action: remove - register: remove_aliases - -- assert: - that: - - "remove_aliases.changed == true" - -- name: get actual dns result for removed aliases - win_shell: "try{ [array]$t = [Net.DNS]::GetHostEntry('{{ item }}') } catch { return 'false' } if ($t[0].HostName -eq '{{ test_win_hosts_cname }}' -and $t[0].AddressList[0].toString() -eq '{{ test_win_hosts_ip }}'){ return 'true' } else { return 'false' }" - register: remove_aliases_removed_actual - failed_when: "remove_aliases_removed_actual.rc == 0" - with_items: "{{ test_win_hosts_aliases_remove }}" - -- assert: - that: - - "item.stdout_lines[0]|lower == 'false'" - with_items: "{{ remove_aliases_removed_actual.results }}" - -- name: get actual dns result for remaining aliases - win_shell: "try{ [array]$t = [Net.DNS]::GetHostEntry('{{ item }}') } catch { return 'false' } if ($t[0].HostName -eq '{{ test_win_hosts_cname }}' -and $t[0].AddressList[0].toString() -eq '{{ test_win_hosts_ip }}'){ return 'true' } else { return 'false' }" - register: remove_aliases_remain_actual - with_items: "{{ test_win_hosts_aliases_set | difference(test_win_hosts_aliases_remove) }}" - -- assert: - that: - - "item.stdout_lines[0]|lower == 'true'" - with_items: "{{ remove_aliases_remain_actual.results }}" - -- name: remove aliases from the list (idempotent) - win_hosts: - state: present - ip_address: "{{ test_win_hosts_ip }}" - canonical_name: "{{ test_win_hosts_cname }}" - aliases: "{{ test_win_hosts_aliases_remove }}" - action: remove - register: remove_aliases - -- assert: - that: - - "remove_aliases.changed == false" - -- name: add aliases back - win_hosts: - state: present - ip_address: "{{ test_win_hosts_ip }}" - canonical_name: "{{ test_win_hosts_cname }}" - aliases: "{{ test_win_hosts_aliases_remove }}" - action: add - register: add_aliases - -- assert: - that: - - "add_aliases.changed == true" - -- name: get actual dns results for aliases - win_shell: "try{ [array]$t = [Net.DNS]::GetHostEntry('{{ item }}') } catch { return 'false' } if ($t[0].HostName -eq '{{ test_win_hosts_cname }}' -and $t[0].AddressList[0].toString() -eq '{{ test_win_hosts_ip }}'){ return 'true' } else { return 'false' }" - register: add_aliases_actual - with_items: "{{ test_win_hosts_aliases_set | union(test_win_hosts_aliases_remove) }}" - -- assert: - that: - - "item.stdout_lines[0]|lower == 'true'" - with_items: "{{ add_aliases_actual.results }}" - -- name: add aliases back (idempotent) - win_hosts: - state: present - ip_address: "{{ test_win_hosts_ip }}" - canonical_name: "{{ test_win_hosts_cname }}" - aliases: "{{ test_win_hosts_aliases_remove }}" - action: add - register: add_aliases - -- assert: - that: - - "add_aliases.changed == false" diff --git a/test/integration/targets/win_hotfix/aliases b/test/integration/targets/win_hotfix/aliases deleted file mode 100644 index 423ce391085..00000000000 --- a/test/integration/targets/win_hotfix/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group2 diff --git a/test/integration/targets/win_hotfix/defaults/main.yml b/test/integration/targets/win_hotfix/defaults/main.yml deleted file mode 100644 index 22edea7c16f..00000000000 --- a/test/integration/targets/win_hotfix/defaults/main.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- -# these hotfixes, are for Hyper-V, there may be a chance the system already has them -# but in most cases for our CI purposes they wouldn't be present -test_win_hotfix_good_url: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/win_hotfix/windows8.1-kb3027108-v2-x64_66366c7be2d64d83b63cac42bc40c0a3c01bc70d.msu -test_win_hotfix_reboot_url: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/win_hotfix/windows8.1-kb2913659-v2-x64_963a4d890c9ff9cc83a97cf54305de6451038ba4.msu -test_win_hotfix_bad_url: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/win_hotfix/windows8-rt-kb3172729-x64_69cab4c7785b1faa3fc450f32bed4873d53bb96f.msu -test_win_hotfix_path: C:\ansible\win_hotfix - -test_win_hotfix_kb: KB3027108 -test_win_hotfix_identifier: Package_for_KB3027108~31bf3856ad364e35~amd64~~6.3.2.0 - -test_win_hotfix_reboot_kb: KB2913659 -test_win_hotfix_reboot_identifier: Package_for_KB2913659~31bf3856ad364e35~amd64~~6.3.2.0 diff --git a/test/integration/targets/win_hotfix/tasks/main.yml b/test/integration/targets/win_hotfix/tasks/main.yml deleted file mode 100644 index 8ae7a350031..00000000000 --- a/test/integration/targets/win_hotfix/tasks/main.yml +++ /dev/null @@ -1,54 +0,0 @@ ---- -- name: filter servers that can support DISM - win_command: powershell.exe "Import-Module -Name DISM" - register: eligable_servers - ignore_errors: True - -- name: fail to run module on servers that don't support DISM - win_hotfix: - path: fake - state: present - register: fail_no_dism - failed_when: fail_no_dism.msg != 'The DISM PS module needs to be installed, this can be done through the windows-adk chocolately package' - when: eligable_servers.rc != 0 - -- name: run tests on hosts that support DISM - include_tasks: tests.yml - when: eligable_servers.rc == 0 - -- name: set output to true if running Server 2012 R2 - win_command: powershell.exe "$version = [Environment]::OSVersion.Version; if ($version.Major -eq 6 -and $version.Minor -eq 3) { 'true' } else { 'false' }" - register: test_hotfix - -- block: - - name: ensure hotfixes are uninstalled before tests - win_hotfix: - hotfix_identifier: '{{item}}' - state: absent - register: pre_uninstall - with_items: - - '{{test_win_hotfix_identifier}}' - - '{{test_win_hotfix_reboot_identifier}}' - - - name: reboot after pre test uninstall if required - win_reboot: - when: pre_uninstall.results[0].reboot_required == True or pre_uninstall.results[1].reboot_required == True - - - name: run actual hotfix tests on Server 2012 R2 only - include_tasks: tests_2012R2.yml - - always: - - name: ensure hotfixes are uninstalled after tests - win_hotfix: - hotfix_identifier: '{{item}}' - state: absent - register: post_uninstall - with_items: - - '{{test_win_hotfix_identifier}}' - - '{{test_win_hotfix_reboot_identifier}}' - - - name: reboot after post test uninstall if required - win_reboot: - when: post_uninstall.results[0].reboot_required == True or post_uninstall.results[1].reboot_required == True - - when: test_hotfix.stdout_lines[0] == "true" diff --git a/test/integration/targets/win_hotfix/tasks/tests.yml b/test/integration/targets/win_hotfix/tasks/tests.yml deleted file mode 100644 index 8e7a7df379e..00000000000 --- a/test/integration/targets/win_hotfix/tasks/tests.yml +++ /dev/null @@ -1,35 +0,0 @@ -# only basic tests, doesn't actually install/uninstall and hotfixes ---- -- name: fail when source isn't set - win_hotfix: - state: present - register: fail_no_source - failed_when: fail_no_source.msg != 'source must be set when state=present' - -- name: fail when identifier or kb isn't set on absent - win_hotfix: - state: absent - register: fail_no_key - failed_when: fail_no_key.msg != 'either hotfix_identifier or hotfix_kb needs to be set when state=absent' - -- name: remove an identifier that isn't installed - win_hotfix: - hotfix_identifier: fake~identifier - state: absent - register: remove_missing_hotfix_identifier - -- name: assert remove an identifier that isn't installed - assert: - that: - - remove_missing_hotfix_identifier is not changed - -- name: remove a kb that isn't installed - win_hotfix: - hotfix_kb: KB123456 - state: absent - register: remove_missing_hotfix_kb - -- name: assert remove a kb that isn't installed - assert: - that: - - remove_missing_hotfix_kb is not changed diff --git a/test/integration/targets/win_hotfix/tasks/tests_2012R2.yml b/test/integration/targets/win_hotfix/tasks/tests_2012R2.yml deleted file mode 100644 index 2f04fd70a19..00000000000 --- a/test/integration/targets/win_hotfix/tasks/tests_2012R2.yml +++ /dev/null @@ -1,253 +0,0 @@ ---- -- name: create test staging folder - win_file: - path: '{{test_win_hotfix_path}}' - state: directory - -- name: download hotfix - win_get_url: - url: '{{test_win_hotfix_good_url}}' - dest: '{{test_win_hotfix_path}}\good.msu' - -- name: download reboot hotfix - win_get_url: - url: '{{test_win_hotfix_reboot_url}}' - dest: '{{test_win_hotfix_path}}\reboot.msu' - -- name: download bad hotfix - win_get_url: - url: '{{test_win_hotfix_bad_url}}' - dest: '{{test_win_hotfix_path}}\bad.msu' - -- name: fail install install hotfix where kb doesn't match - win_hotfix: - hotfix_kb: KB0000000 - source: '{{test_win_hotfix_path}}\good.msu' - state: present - register: fail_install_invalid_kb - failed_when: fail_install_invalid_kb.msg != 'the hotfix KB KB0000000 does not match with the source msu KB ' + test_win_hotfix_kb + ', please omit or specify the correct KB to continue' - -- name: fail install install hotfix where identifier doesn't match - win_hotfix: - hotfix_identifier: invalid - source: '{{test_win_hotfix_path}}\good.msu' - state: present - register: fail_install_invalid_identifier - failed_when: fail_install_invalid_identifier.msg != 'the hotfix identifier invalid does not match with the source msu identifier ' + test_win_hotfix_identifier + ', please omit or specify the correct identifier to continue' - -- name: fail install not applicable hotfix - win_hotfix: - source: '{{test_win_hotfix_path}}\bad.msu' - state: present - register: fail_install_not_applicable - failed_when: fail_install_not_applicable.msg != 'hotfix package is not applicable for this server' - -- name: install hotfix check - win_hotfix: - source: '{{test_win_hotfix_path}}\good.msu' - state: present - register: install_hotfix_check - check_mode: yes - -- name: get result of install hotfix check - win_command: powershell.exe Get-Hotfix -Id {{test_win_hotfix_kb}} - register: install_hotfix_actual_check - ignore_errors: True - -- name: assert install hotfix check - assert: - that: - - install_hotfix_check is changed - - install_hotfix_check.kb == test_win_hotfix_kb - - install_hotfix_check.identifier == test_win_hotfix_identifier - - install_hotfix_actual_check.rc != 0 - -- name: install hotfix - win_hotfix: - source: '{{test_win_hotfix_path}}\good.msu' - state: present - register: install_hotfix - -- name: get result of install hotfix - win_command: powershell.exe Get-Hotfix -Id {{test_win_hotfix_kb}} - register: install_hotfix_actual - -- name: assert install hotfix - assert: - that: - - install_hotfix is changed - - install_hotfix.kb == test_win_hotfix_kb - - install_hotfix.identifier == test_win_hotfix_identifier - - install_hotfix.reboot_required == False - - install_hotfix_actual.rc == 0 - -- name: install hotfix again - win_hotfix: - source: '{{test_win_hotfix_path}}\good.msu' - state: present - register: install_hotfix_again - -- name: assert install hotfix again - assert: - that: - - install_hotfix_again is not changed - - install_hotfix_again.kb == test_win_hotfix_kb - - install_hotfix_again.identifier == test_win_hotfix_identifier - - install_hotfix_again.reboot_required == False - -- name: uninstall hotfix check - win_hotfix: - hotfix_identifier: '{{test_win_hotfix_identifier}}' - state: absent - register: uninstall_hotfix_check - check_mode: yes - -- name: get result of uninstall hotfix check - win_command: powershell.exe Get-Hotfix -Id {{test_win_hotfix_kb}} - register: uninstall_hotfix_actual_check - -- name: assert uninstall hotfix check - assert: - that: - - uninstall_hotfix_check is changed - - uninstall_hotfix_check.kb == test_win_hotfix_kb - - uninstall_hotfix_check.identifier == test_win_hotfix_identifier - - uninstall_hotfix_actual_check.rc == 0 - -- name: uninstall hotfix - win_hotfix: - hotfix_identifier: '{{test_win_hotfix_identifier}}' - state: absent - register: uninstall_hotfix - -- name: get result of uninstall hotfix - win_command: powershell.exe Get-Hotfix -Id {{test_win_hotfix_kb}} - register: uninstall_hotfix_actual - ignore_errors: True - -- name: assert uninstall hotfix - assert: - that: - - uninstall_hotfix is changed - - uninstall_hotfix.kb == test_win_hotfix_kb - - uninstall_hotfix.identifier == test_win_hotfix_identifier - - uninstall_hotfix.reboot_required == False - - uninstall_hotfix_actual.rc != 0 - -- name: uninstall hotfix again - win_hotfix: - hotfix_identifier: '{{test_win_hotfix_identifier}}' - state: absent - register: uninstall_hotfix_again - -- name: assert uninstall hotfix again - assert: - that: - - uninstall_hotfix_again is not changed - - uninstall_hotfix_again.reboot_required == False - -- name: install reboot hotfix - win_hotfix: - hotfix_kb: '{{test_win_hotfix_reboot_kb}}' - source: '{{test_win_hotfix_path}}\reboot.msu' - state: present - register: install_reboot_hotfix - -- name: get result of install reboot hotfix - win_command: powershell.exe Get-Hotfix -Id {{test_win_hotfix_reboot_kb}} - register: install_hotfix_reboot_actual - -- name: assert install reboot hotfix - assert: - that: - - install_reboot_hotfix is changed - - install_reboot_hotfix.kb == test_win_hotfix_reboot_kb - - install_reboot_hotfix.identifier == test_win_hotfix_reboot_identifier - - install_reboot_hotfix.reboot_required == True - - install_hotfix_reboot_actual.rc == 0 - -- name: run install reboot again before rebooting - win_hotfix: - source: '{{test_win_hotfix_path}}\reboot.msu' - state: present - register: install_before_rebooting - -- name: assert install reboot again before rebooting - assert: - that: - - install_before_rebooting is not changed - - install_before_rebooting.reboot_required == True - -- win_reboot: - -- name: install reboot hotfix again - win_hotfix: - hotfix_identifier: '{{test_win_hotfix_reboot_identifier}}' - source: '{{test_win_hotfix_path}}\reboot.msu' - state: present - register: install_reboot_hotfix_again - -- name: assert install reboot hotfix again - assert: - that: - - install_reboot_hotfix_again is not changed - - install_reboot_hotfix_again.reboot_required == False - -- name: uninstall hotfix with kb check - win_hotfix: - hotfix_kb: '{{test_win_hotfix_reboot_kb}}' - state: absent - register: uninstall_hotfix_kb_check - check_mode: yes - -- name: get result of uninstall hotfix with kb check - win_command: powershell.exe Get-Hotfix -Id {{test_win_hotfix_reboot_kb}} - register: uninstall_hotfix_kb_actual_check - -- name: assert uninstall hotfix with kb check - assert: - that: - - uninstall_hotfix_kb_check is changed - - uninstall_hotfix_kb_check.kb == test_win_hotfix_reboot_kb - - uninstall_hotfix_kb_check.identifier == test_win_hotfix_reboot_identifier - - uninstall_hotfix_kb_check.reboot_required == False - - uninstall_hotfix_kb_actual_check.rc == 0 - -- name: uninstall hotfix with kb - win_hotfix: - hotfix_kb: '{{test_win_hotfix_reboot_kb}}' - state: absent - register: uninstall_hotfix_kb - -- name: get result of uninstall hotfix with kb - win_command: powershell.exe Get-Hotfix -Id {{test_win_hotfix_kb}} - register: uninstall_hotfix_kb_actual - ignore_errors: True - -- name: assert uninstall hotfix with kb - assert: - that: - - uninstall_hotfix_kb is changed - - uninstall_hotfix_kb.kb == test_win_hotfix_reboot_kb - - uninstall_hotfix_kb.identifier == test_win_hotfix_reboot_identifier - - uninstall_hotfix_kb.reboot_required == True - - uninstall_hotfix_kb_actual.rc != 0 - -- win_reboot: - -- name: uninstall hotfix with kb again - win_hotfix: - hotfix_kb: '{{test_win_hotfix_reboot_kb}}' - state: absent - register: uninstall_hotfix_kb_again - -- name: assert uninstall hotfix with kb again - assert: - that: - - uninstall_hotfix_kb_again is not changed - - uninstall_hotfix_kb_again.reboot_required == False - -- name: remove test staging folder - win_file: - path: '{{test_win_hotfix_path}}' - state: absent diff --git a/test/integration/targets/win_http_proxy/aliases b/test/integration/targets/win_http_proxy/aliases deleted file mode 100644 index 215e0b06920..00000000000 --- a/test/integration/targets/win_http_proxy/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group4 diff --git a/test/integration/targets/win_http_proxy/tasks/main.yml b/test/integration/targets/win_http_proxy/tasks/main.yml deleted file mode 100644 index 5da9aa7fecb..00000000000 --- a/test/integration/targets/win_http_proxy/tasks/main.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -- name: make sure we start the tests with no proxy set - win_http_proxy: - -- block: - - name: run tests - include_tasks: tests.yml - - always: - - name: remove any explicit proxy settings - win_http_proxy: - - - name: reset WinINet proxy settings - win_inet_proxy: diff --git a/test/integration/targets/win_http_proxy/tasks/tests.yml b/test/integration/targets/win_http_proxy/tasks/tests.yml deleted file mode 100644 index c68ea611b72..00000000000 --- a/test/integration/targets/win_http_proxy/tasks/tests.yml +++ /dev/null @@ -1,265 +0,0 @@ ---- -- name: ensure we fail when proxy is not set with bypass - win_http_proxy: - bypass: abc - register: fail_bypass - failed_when: 'fail_bypass.msg != "missing parameter(s) required by ''bypass'': proxy"' - -- name: ensure we fail when proxy and source is set - win_http_proxy: - proxy: proxy - source: ie - register: fail_source - failed_when: 'fail_source.msg != "parameters are mutually exclusive: proxy, source"' - -- name: ensure we fail if an invalid protocol is specified - win_http_proxy: - proxy: - fail1: fail - fail2: fail - register: fail_protocol - failed_when: 'fail_protocol.msg != "Invalid keys found in proxy: fail1, fail2. Valid keys are http, https, ftp, socks."' - -# WinHTTP does not validate on set, this ensures the module checks and revert any failed attempts at setting the proxy -# FIXME: Only certain hosts seem to have a strict winhttp definition, we can't run this in CI for now -#- name: ensure we fail if invalid value is set -# win_http_proxy: -# proxy: fake=proxy -# register: fail_invalid -# failed_when: fail_invalid.msg != "Unknown error when trying to set proxy 'fake=proxy' or bypass ''" -# -#- name: check proxy is still set to Direct access -# win_command: netsh winhttp show proxy -# register: fail_invalid_actual -# failed_when: fail_invalid_actual.stdout_lines[3]|trim != "Direct access (no proxy server)." - -- name: set a proxy using a string (check) - win_http_proxy: - proxy: proxyhost - register: proxy_str_check - check_mode: True - -- name: get result of set a proxy using a string (check) - win_command: netsh winhttp show proxy - register: proxy_str_actual_check - -- name: assert set a proxy using a string (check) - assert: - that: - - proxy_str_check is changed - - proxy_str_actual_check.stdout_lines[3]|trim == "Direct access (no proxy server)." - -- name: set a proxy using a string - win_http_proxy: - proxy: proxyhost - register: proxy_str - -- name: get result of set a proxy using a string - win_command: netsh winhttp show proxy - register: proxy_str_actual - -- name: assert set a proxy using a string - assert: - that: - - proxy_str is changed - - 'proxy_str_actual.stdout_lines[3]|trim == "Proxy Server(s) : proxyhost"' - - 'proxy_str_actual.stdout_lines[4]|trim == "Bypass List : (none)"' - -- name: set a proxy using a string (idempotent) - win_http_proxy: - proxy: proxyhost - register: proxy_str_again - -- name: assert set a proxy using a string (idempotent) - assert: - that: - - not proxy_str_again is changed - -- name: change a proxy and set bypass (check) - win_http_proxy: - proxy: proxyhost:8080 - bypass: - - abc - - def - - - register: change_proxy_check - check_mode: True - -- name: get result of change a proxy and set bypass (check) - win_command: netsh winhttp show proxy - register: change_proxy_actual_check - -- name: assert change a proxy and set bypass (check) - assert: - that: - - change_proxy_check is changed - - 'change_proxy_actual_check.stdout_lines[3]|trim == "Proxy Server(s) : proxyhost"' - - 'change_proxy_actual_check.stdout_lines[4]|trim == "Bypass List : (none)"' - -- name: change a proxy and set bypass - win_http_proxy: - proxy: proxyhost:8080 - bypass: - - abc - - def - - - register: change_proxy - -- name: get result of change a proxy and set bypass - win_command: netsh winhttp show proxy - register: change_proxy_actual - -- name: assert change a proxy and set bypass - assert: - that: - - change_proxy is changed - - 'change_proxy_actual.stdout_lines[3]|trim == "Proxy Server(s) : proxyhost:8080"' - - 'change_proxy_actual.stdout_lines[4]|trim == "Bypass List : abc;def;"' - -- name: change a proxy and set bypass (idempotent) - win_http_proxy: - proxy: proxyhost:8080 - bypass: abc,def, - register: change_proxy_again - -- name: assert change a proxy and set bypass (idempotent) - assert: - that: - - not change_proxy_again is changed - -- name: change bypass list - win_http_proxy: - proxy: proxyhost:8080 - bypass: - - abc - - <-loopback> - register: change_bypass - -- name: get result of change bypass list - win_command: netsh winhttp show proxy - register: change_bypass_actual - -- name: assert change bypass list - assert: - that: - - change_bypass is changed - - 'change_bypass_actual.stdout_lines[3]|trim == "Proxy Server(s) : proxyhost:8080"' - - 'change_bypass_actual.stdout_lines[4]|trim == "Bypass List : abc;<-loopback>"' - -- name: remove proxy without options (check) - win_http_proxy: - register: remove_proxy_check - check_mode: yes - -- name: get result of remove proxy without options (check) - win_command: netsh winhttp show proxy - register: remove_proxy_actual_check - -- name: assert remove proxy without options (check) - assert: - that: - - remove_proxy_check is changed - - 'remove_proxy_actual_check.stdout_lines[3]|trim == "Proxy Server(s) : proxyhost:8080"' - - 'remove_proxy_actual_check.stdout_lines[4]|trim == "Bypass List : abc;<-loopback>"' - -- name: remove proxy without options - win_http_proxy: - register: remove_proxy - -- name: get result of remove proxy without options - win_command: netsh winhttp show proxy - register: remove_proxy_actual - -- name: assert remove proxy without options - assert: - that: - - remove_proxy is changed - - remove_proxy_actual.stdout_lines[3]|trim == "Direct access (no proxy server)." - -- name: remove proxy without options (idempotent) - win_http_proxy: - register: remove_proxy_again - -- name: assert remove proxy without options (idempotent) - assert: - that: - - not remove_proxy_again is changed - -- name: set proxy with dictionary - win_http_proxy: - proxy: - http: proxy:8080 - https: proxy:8443 - ftp: proxy:821 - socks: proxy:888 - register: set_dict - -- name: get result of set proxy with dictionary - win_command: netsh winhttp show proxy - register: set_dict_actual - -- name: assert set proxy with dictionary - assert: - that: - - set_dict is changed - - 'set_dict_actual.stdout_lines[3]|trim == "Proxy Server(s) : http=proxy:8080;https=proxy:8443;ftp=proxy:821;socks=proxy:888"' - - 'set_dict_actual.stdout_lines[4]|trim == "Bypass List : (none)"' - -- name: set proxy protocol with str - win_http_proxy: - proxy: http=proxy:8080;https=proxy:8443;ftp=proxy:821;socks=proxy:888 - register: set_str_protocol - -- name: assert set proxy protocol with str - assert: - that: - - not set_str_protocol is changed - -- name: remove proxy with empty string - win_http_proxy: - proxy: '' - register: remove_empty_str - -- name: get result of remove proxy with empty string - win_command: netsh winhttp show proxy - register: remove_empty_str_actual - -- name: assert remove proxy with empty string - assert: - that: - - remove_empty_str is changed - - remove_empty_str_actual.stdout_lines[3]|trim == "Direct access (no proxy server)." - -- name: set explicit proxy for WinINet - win_inet_proxy: - proxy: proxyhost:8080 - bypass: - - abc - - def - - - -- name: import proxy from IE - win_http_proxy: - source: ie - register: import_ie - -- name: get result of import proxy from IE - win_command: netsh winhttp show proxy - register: import_ie_actual - -- name: assert import proxy from IE - assert: - that: - - import_ie is changed - - 'import_ie_actual.stdout_lines[3]|trim == "Proxy Server(s) : proxyhost:8080"' - - 'import_ie_actual.stdout_lines[4]|trim == "Bypass List : abc;def;"' - -- name: import proxy from IE (idempotent) - win_http_proxy: - source: ie - register: import_ie_again - -- name: assert import proxy from IE (idempotent) - assert: - that: - - not import_ie_again is changed diff --git a/test/integration/targets/win_iis_webapplication/aliases b/test/integration/targets/win_iis_webapplication/aliases deleted file mode 100644 index 3cf5b97e805..00000000000 --- a/test/integration/targets/win_iis_webapplication/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_iis_webapplication/defaults/main.yml b/test/integration/targets/win_iis_webapplication/defaults/main.yml deleted file mode 100644 index e5a582dee14..00000000000 --- a/test/integration/targets/win_iis_webapplication/defaults/main.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- - -test_app_name: TestApp - -test_site_name: 'Test Site' - -test_user: testuser -test_password: testpass - -test_physical_path: "{{ remote_tmp_dir }}" -test_apppool: 'testapppool' diff --git a/test/integration/targets/win_iis_webapplication/meta/main.yml b/test/integration/targets/win_iis_webapplication/meta/main.yml deleted file mode 100644 index e3dd5fb100d..00000000000 --- a/test/integration/targets/win_iis_webapplication/meta/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -dependencies: -- setup_remote_tmp_dir diff --git a/test/integration/targets/win_iis_webapplication/tasks/main.yml b/test/integration/targets/win_iis_webapplication/tasks/main.yml deleted file mode 100644 index 83614f17f30..00000000000 --- a/test/integration/targets/win_iis_webapplication/tasks/main.yml +++ /dev/null @@ -1,70 +0,0 @@ ---- -# Cannot use win_feature to install IIS on Server 2008. -# Run a brief check and skip hosts that don't support -# that operation - -# Run on Server 2012 and higher -- block: - - name: ensure IIS features are installed - win_feature: - name: Web-Server - state: present - include_management_tools: True - register: feature_install - - - name: reboot after feature install - win_reboot: - when: feature_install.reboot_required - - # may be possible that copy corrupts the file - - name: Get iis configuration checksum - win_stat: - path: '{{ ansible_env.SystemRoot }}\System32\inetsrv\config\applicationHost.config' - checksum_algorithm: sha1 - register: stat_result - - - name: take a copy of the original iis configuration - win_copy: - src: '{{ ansible_env.SystemRoot }}\System32\inetsrv\config\applicationHost.config' - dest: '{{ ansible_env.TEMP }}\applicationHost.config' - remote_src: yes - register: copy_result - - - assert: - that: - - "stat_result.stat.checksum == copy_result.checksum" - - # Tests - - name: run tests on hosts that support it - include_tasks: tests.yml - - always: - # Cleanup - - name: remove test application - win_iis_webapplication: - state: absent - site: "{{ test_site_name }}" - name: "{{ test_app_name }}" - - - name: remove test application pool - win_iis_webapppool: - name: "{{ test_apppool }}" - state: absent - - - name: remove test site - win_iis_website: - name: "{{ test_site_name }}" - state: absent - - - name: restore iis configuration - win_copy: - src: '{{ ansible_env.TEMP }}\applicationHost.config' - dest: '{{ ansible_env.SystemRoot }}\System32\inetsrv\config\applicationHost.config' - remote_src: yes - register: copy_result - - - assert: - that: - - "stat_result.stat.checksum == copy_result.checksum" - - when: ansible_distribution_version is version('6.2','ge') diff --git a/test/integration/targets/win_iis_webapplication/tasks/tests.yml b/test/integration/targets/win_iis_webapplication/tasks/tests.yml deleted file mode 100644 index 135cccfeca9..00000000000 --- a/test/integration/targets/win_iis_webapplication/tasks/tests.yml +++ /dev/null @@ -1,91 +0,0 @@ ---- -- name: test site exists, but stopped in case of duplicate web binding - win_iis_website: - name: "{{ test_site_name }}" - state: stopped - physical_path: 'C:\inetpub\wwwroot' - -- name: test app is absent (baseline) - win_iis_webapplication: - state: absent - site: "{{ test_site_name }}" - name: "{{ test_app_name }}" - -- name: create test app - win_iis_webapplication: - state: present - site: "{{ test_site_name }}" - name: "{{ test_app_name }}" - physical_path: "{{ test_physical_path }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.physical_path == test_physical_path' - -- name: create test app (idempotent) - win_iis_webapplication: - state: present - site: "{{ test_site_name }}" - name: "{{ test_app_name }}" - physical_path: "{{ test_physical_path }}" - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.physical_path == test_physical_path' - -- name: set test app credentials - win_iis_webapplication: - state: present - site: "{{ test_site_name }}" - name: "{{ test_app_name }}" - connect_as: specific_user - username: "{{ test_user }}" - password: "{{ test_password }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.physical_path == test_physical_path' - - "result.connect_as == 'specific_user'" - -- name: set test app credentials (idempotent) - win_iis_webapplication: - state: present - site: "{{ test_site_name }}" - name: "{{ test_app_name }}" - connect_as: specific_user - username: "{{ test_user }}" - password: "{{ test_password }}" - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.physical_path == test_physical_path' - - "result.connect_as == 'specific_user'" - -- name: create new test application pool - win_iis_webapppool: - name: "{{ test_apppool }}" - state: present - -- name: change app pool and use pass through authentication - win_iis_webapplication: - state: present - site: "{{ test_site_name }}" - name: "{{ test_app_name }}" - connect_as: pass_through - application_pool: "{{ test_apppool }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.physical_path == test_physical_path' - - "result.connect_as == 'pass_through'" - - "result.application_pool == test_apppool" diff --git a/test/integration/targets/win_iis_webapppool/aliases b/test/integration/targets/win_iis_webapppool/aliases deleted file mode 100644 index 3cf5b97e805..00000000000 --- a/test/integration/targets/win_iis_webapppool/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_iis_webapppool/defaults/main.yml b/test/integration/targets/win_iis_webapppool/defaults/main.yml deleted file mode 100644 index bd0f15c998e..00000000000 --- a/test/integration/targets/win_iis_webapppool/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ -test_iis_webapppool_name: TestPool \ No newline at end of file diff --git a/test/integration/targets/win_iis_webapppool/tasks/main.yml b/test/integration/targets/win_iis_webapppool/tasks/main.yml deleted file mode 100644 index ea30d7e5677..00000000000 --- a/test/integration/targets/win_iis_webapppool/tasks/main.yml +++ /dev/null @@ -1,43 +0,0 @@ ---- -# Cannot use win_feature to install IIS on Server 2008. -# Run a brief check and skip hosts that don't support -# that operation -- name: check if win_feature will work on test host - win_command: powershell.exe "Get-WindowsFeature" - register: module_available - failed_when: False - -# Run actual tests -- block: - - name: ensure IIS features are installed - win_feature: - name: Web-Server - state: present - include_management_tools: True - register: feature_install - - - name: reboot after feature install - win_reboot: - when: feature_install.reboot_required - - - name: set version of IIS for tests - win_file_version: - path: C:\Windows\System32\inetsrv\w3wp.exe - register: iis_version - - - name: ensure test pool is deleted as a baseline - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: absent - - # Tests - - name: run tests on hosts that support it - include_tasks: tests.yml - - always: - # Cleanup - - name: ensure test pool is deleted - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: absent - when: module_available.rc == 0 diff --git a/test/integration/targets/win_iis_webapppool/tasks/tests.yml b/test/integration/targets/win_iis_webapppool/tasks/tests.yml deleted file mode 100644 index e47f9f05c11..00000000000 --- a/test/integration/targets/win_iis_webapppool/tasks/tests.yml +++ /dev/null @@ -1,424 +0,0 @@ ---- -- name: create default pool check - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: started - register: create_default_check - check_mode: yes - -- name: get actual of create default pool check - win_command: powershell.exe "Import-Module WebAdministration; Get-Item -Path IIS:\AppPools\{{test_iis_webapppool_name}}" - register: create_default_actual_check - failed_when: False - -- name: assert create default pool check - assert: - that: - - create_default_check is changed - - create_default_actual_check.rc == 1 - -- name: create default pool - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: present - register: create_default - -- name: get actual of create default pool - win_command: powershell.exe "Import-Module WebAdministration; Get-Item -Path IIS:\AppPools\{{test_iis_webapppool_name}}" - register: create_default_actual - failed_when: False - -- name: assert create default pool - assert: - that: - - create_default is changed - - create_default.info.attributes.name == test_iis_webapppool_name - - create_default.info.attributes.startMode == 'OnDemand' - - create_default.info.attributes.state == 'Started' - - create_default_actual.rc == 0 - -- name: change attributes of pool check - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: present - attributes: - managedPipelineMode: 1 # Using an enum value - cpu.limit: 95 # Nested values - processModel.identityType: LocalSystem # Using an enum name - processModel.loadUserProfile: True - register: change_pool_attributes_check - check_mode: yes - -- name: assert change attributes of pool check - assert: - that: - - change_pool_attributes_check is changed - - change_pool_attributes_check.info == create_default.info - -- name: change attributes of pool - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: present - attributes: - managedPipelineMode: 1 # Using an enum value - cpu.limit: 95 # Nested values - processModel.identityType: LocalSystem # Using an enum name - processModel.loadUserProfile: True - test: True - register: change_pool_attributes - -- name: assert change attributes of pool - assert: - that: - - change_pool_attributes is changed - - change_pool_attributes.info.attributes.managedPipelineMode == 'Classic' - - change_pool_attributes.info.cpu.limit == 95 - - change_pool_attributes.info.processModel.identityType == 'LocalSystem' - - change_pool_attributes.info.processModel.loadUserProfile == True - -- name: change attributes of pool again - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: present - attributes: - managedPipelineMode: 1 # Using an enum value - cpu.limit: 95 # Nested values - processModel.identityType: LocalSystem # Using an enum name - processModel.loadUserProfile: True - register: change_pool_attributes_again - -- name: assert change attributes of pool again - assert: - that: - - change_pool_attributes_again is not changed - - change_pool_attributes_again.info == change_pool_attributes.info - -- name: change more complex variables check - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: present - attributes: - queueLength: 500 - recycling.periodicRestart.requests: 10 # Deeply nested attribute - recycling.periodicRestart.time: "00:00:05:00.000000" # Timespan with string - processModel.pingResponseTime: "00:03:00" # Timespan without days or milliseconds - register: change_complex_attributes_check - check_mode: yes - -- name: assert change more complex variables check - assert: - that: - - change_complex_attributes_check is changed - - change_complex_attributes_check.info == change_pool_attributes_again.info - -- name: change more complex variables - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: present - attributes: - queueLength: 500 - recycling.periodicRestart.requests: 10 # Deeply nested attribute - recycling.periodicRestart.time: "00:00:05:00.000000" # Timespan with string - processModel.pingResponseTime: "00:03:00" # Timespan without days or milliseconds - register: change_complex_attributes - -- name: assert change more complex variables - assert: - that: - - change_complex_attributes is changed - - change_complex_attributes.info.attributes.queueLength == 500 - - change_complex_attributes.info.recycling.periodicRestart.requests == 10 - - change_complex_attributes.info.recycling.periodicRestart.time.TotalSeconds == 300 - - change_complex_attributes.info.processModel.pingResponseTime.TotalSeconds == 180 - -- name: change more complex variables again - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: present - attributes: - queueLength: 500 - recycling.periodicRestart.requests: 10 # Deeply nested attribute - recycling.periodicRestart.time: "00:00:05:00.000000" # Timespan with string - processModel.pingResponseTime: "00:03:00" # Timespan without days or milliseconds - register: change_complex_attributes_again - -- name: assert change more complex variables again - assert: - that: - - change_complex_attributes_again is not changed - - change_complex_attributes_again.info == change_complex_attributes.info - -- name: stop web pool check - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: stopped - register: stop_pool_check - check_mode: yes - -- name: get actual status of pool check - win_command: powershell.exe "Import-Module WebAdministration; (Get-Item -Path IIS:\AppPools\{{test_iis_webapppool_name}}).state" - register: stop_pool_actual_check - -- name: assert stop web pool check - assert: - that: - - stop_pool_check is changed - - stop_pool_actual_check.stdout == 'Started\r\n' - -- name: stop web pool - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: stopped - register: stop_pool - -- name: get actual status of pool - win_command: powershell.exe "Import-Module WebAdministration; (Get-Item -Path IIS:\AppPools\{{test_iis_webapppool_name}}).state" - register: stop_pool_actual - -- name: assert stop web pool - assert: - that: - - stop_pool is changed - - stop_pool_actual.stdout == 'Stopped\r\n' - -- name: stop web pool again - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: stopped - register: stop_pool_again - -- name: get actual status of pool again - win_command: powershell.exe "Import-Module WebAdministration; (Get-Item -Path IIS:\AppPools\{{test_iis_webapppool_name}}).state" - register: stop_pool_actual_again - -- name: assert stop web pool again - assert: - that: - - stop_pool_again is not changed - - stop_pool_actual_again.stdout == 'Stopped\r\n' - -- name: start web pool check - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: started - register: start_pool_check - check_mode: yes - -- name: get actual status of pool check - win_command: powershell.exe "Import-Module WebAdministration; (Get-Item -Path IIS:\AppPools\{{test_iis_webapppool_name}}).state" - register: start_pool_actual_check - -- name: assert start web pool check - assert: - that: - - start_pool_check is changed - - start_pool_actual_check.stdout == 'Stopped\r\n' - -- name: start web pool - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: started - register: start_pool - -- name: get actual status of pool - win_command: powershell.exe "Import-Module WebAdministration; (Get-Item -Path IIS:\AppPools\{{test_iis_webapppool_name}}).state" - register: start_pool_actual - -- name: assert start web pool - assert: - that: - - start_pool is changed - - start_pool_actual.stdout == 'Started\r\n' - -- name: start web pool again - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: started - register: start_pool_again - -- name: get actual status of pool again - win_command: powershell.exe "Import-Module WebAdministration; (Get-Item -Path IIS:\AppPools\{{test_iis_webapppool_name}}).state" - register: start_pool_actual_again - -- name: assert start web pool again - assert: - that: - - start_pool_again is not changed - - start_pool_actual_again.stdout == 'Started\r\n' - -- name: restart web pool - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: restarted - register: restart_pool - -- name: get actual status of pool - win_command: powershell.exe "Import-Module WebAdministration; (Get-Item -Path IIS:\AppPools\{{test_iis_webapppool_name}}).state" - register: restart_pool_actual - -- name: assert restart web pool - assert: - that: - - restart_pool is changed - - restart_pool_actual.stdout == 'Started\r\n' - -- name: stop pool before restart on stop test - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: stopped - -- name: restart from stopped web pool check - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: restarted - register: restart_from_stop_pool_check - check_mode: yes - -- name: get actual status of pool check - win_command: powershell.exe "Import-Module WebAdministration; (Get-Item -Path IIS:\AppPools\{{test_iis_webapppool_name}}).state" - register: restart_from_stop_pool_actual_check - -- name: assert restart from stopped web pool check - assert: - that: - - restart_from_stop_pool_check is changed - - restart_from_stop_pool_actual_check.stdout == 'Stopped\r\n' - -- name: restart from stopped web pool - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: restarted - register: restart_from_stop_pool - -- name: get actual status of pool - win_command: powershell.exe "Import-Module WebAdministration; (Get-Item -Path IIS:\AppPools\{{test_iis_webapppool_name}}).state" - register: restart_from_stop_pool_actual - -- name: assert restart from stopped web pool - assert: - that: - - restart_from_stop_pool is changed - - restart_from_stop_pool_actual.stdout == 'Started\r\n' - -- name: set web pool attribute that is a collection (check mode) - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: present - attributes: - recycling.periodicRestart.schedule: "00:10:00,10:10:00" - register: collection_change_check - check_mode: yes - -- name: get result of set web pool attribute that is a collection (check mode) - win_shell: | - Import-Module WebAdministration - (Get-ItemProperty -Path "IIS:\AppPools\{{test_iis_webapppool_name}}" -Name recycling.periodicRestart.schedule).Collection | ForEach-Object { $_.value.ToString() } - register: collection_change_result_check - -- name: assert results of set web pool attribute that is a collection (check mode) - assert: - that: - - collection_change_check is changed - - collection_change_result_check.stdout == "" - -- name: set web pool attribute that is a collection - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: present - attributes: - recycling.periodicRestart.schedule: "00:10:00,10:10:00" - register: collection_change - -- name: get result of set web pool attribute that is a collection - win_shell: | - Import-Module WebAdministration - (Get-ItemProperty -Path "IIS:\AppPools\{{test_iis_webapppool_name}}" -Name recycling.periodicRestart.schedule).Collection | ForEach-Object { $_.value.ToString() } - register: collection_change_result - -- name: assert results of set web pool attribute that is a collection - assert: - that: - - collection_change is changed - - collection_change_result.stdout_lines == [ "00:10:00", "10:10:00" ] - -- name: set web pool attribute that is a collection (idempotent) - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: present - attributes: - recycling.periodicRestart.schedule: [ "00:10:00", "10:10:00" ] - register: collection_change_again - -- name: assert results of set web pool attribute that is a collection (idempotent) - assert: - that: - - collection_change_again is not changed - -# The following tests are only for IIS versions 8.0 or newer -- block: - - name: delete test pool - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: absent - - - name: create test pool - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: present - register: iis_attributes_blank - - - name: change attributes for newer IIS version check - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: present - attributes: - startMode: AlwaysRunning - processModel.identityType: SpecificUser - processModel.userName: '{{ansible_user}}' - processModel.password: '{{ansible_password}}' - register: iis_attributes_new_check - check_mode: yes - - - name: assert change attributes for newer IIS version check - assert: - that: - - iis_attributes_new_check is changed - - iis_attributes_new_check.info == iis_attributes_blank.info - - - name: change attributes for newer IIS version - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: present - attributes: - startMode: AlwaysRunning - processModel.identityType: SpecificUser - processModel.userName: '{{ansible_user}}' - processModel.password: '{{ansible_password}}' - register: iis_attributes_new - - - name: assert change attributes for newer IIS version - assert: - that: - - iis_attributes_new is changed - - iis_attributes_new.info.attributes.startMode == 'AlwaysRunning' - - iis_attributes_new.info.processModel.identityType == 'SpecificUser' - - iis_attributes_new.info.processModel.userName == ansible_user - - - name: change attributes for newer IIS version again - win_iis_webapppool: - name: '{{test_iis_webapppool_name}}' - state: present - attributes: - startMode: AlwaysRunning - processModel.identityType: 3 - processModel.userName: '{{ansible_user}}' - processModel.password: '{{ansible_password}}' - register: iis_attributes_new_again - - - name: assert change attributes for newer IIS version again - assert: - that: - - iis_attributes_new_again is not changed - - iis_attributes_new_again.info == iis_attributes_new.info - - when: iis_version.win_file_version.file_major_part|int > 7 diff --git a/test/integration/targets/win_iis_webbinding/aliases b/test/integration/targets/win_iis_webbinding/aliases deleted file mode 100644 index 4f4664b6858..00000000000 --- a/test/integration/targets/win_iis_webbinding/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group5 diff --git a/test/integration/targets/win_iis_webbinding/defaults/main.yml b/test/integration/targets/win_iis_webbinding/defaults/main.yml deleted file mode 100644 index 13f0bc333fa..00000000000 --- a/test/integration/targets/win_iis_webbinding/defaults/main.yml +++ /dev/null @@ -1,30 +0,0 @@ -test_iis_site_name: default web site - -http_vars: - protocol: http - port: 80 - ip: '*' - -http_header_vars: - protocol: http - port: 80 - ip: '*' - header: test.com - -https_vars: - protocol: https - port: 443 - ip: '*' - -https_header_vars: - protocol: https - port: 443 - ip: '*' - header: test.com - ssl_flags: 1 - -https_wc_vars: - protocol: https - port: 443 - ip: '127.0.0.1' - header: wc.test.com diff --git a/test/integration/targets/win_iis_webbinding/library/test_get_webbindings.ps1 b/test/integration/targets/win_iis_webbinding/library/test_get_webbindings.ps1 deleted file mode 100644 index 84ef10b75a9..00000000000 --- a/test/integration/targets/win_iis_webbinding/library/test_get_webbindings.ps1 +++ /dev/null @@ -1,113 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Noah Sparks -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$params = Parse-Args -arguments $args -supports_check_mode $true - -$name = Get-AnsibleParam $params -name "name" -type str -failifempty $true -aliases 'website' -$host_header = Get-AnsibleParam $params -name "host_header" -type str -$protocol = Get-AnsibleParam $params -name "protocol" -type str -default 'http' -$port = Get-AnsibleParam $params -name "port" -type int -default '80' -$ip = Get-AnsibleParam $params -name "ip" -default '*' - -$result = @{ - changed = $false -} -function Create-BindingInfo { - $ht = @{ - 'bindingInformation' = $args[0].bindingInformation - 'ip' = $args[0].bindingInformation.split(':')[0] - 'port' = [int]$args[0].bindingInformation.split(':')[1] - 'hostheader' = $args[0].bindingInformation.split(':')[2] - 'isDsMapperEnabled' = $args[0].isDsMapperEnabled - 'protocol' = $args[0].protocol - 'certificateStoreName' = $args[0].certificateStoreName - 'certificateHash' = $args[0].certificateHash - } - - #handle sslflag support - If ([version][System.Environment]::OSVersion.Version -lt [version]'6.2') - { - $ht.sslFlags = 'not supported' - } - Else - { - $ht.sslFlags = [int]$args[0].sslFlags - } - - Return $ht -} - -# Used instead of get-webbinding to ensure we always return a single binding -# pass it $binding_parameters hashtable -function Get-SingleWebBinding { - - Try { - $site_bindings = get-webbinding -name $args[0].name - } - Catch { - # 2k8r2 throws this error when you run get-webbinding with no bindings in iis - If (-not $_.Exception.Message.CompareTo('Cannot process argument because the value of argument "obj" is null. Change the value of argument "obj" to a non-null value')) - { - Throw $_.Exception.Message - } - Else { return } - } - - Foreach ($binding in $site_bindings) - { - $splits = $binding.bindingInformation -split ':' - - if ( - $args[0].protocol -eq $binding.protocol -and - $args[0].ipaddress -eq $splits[0] -and - $args[0].port -eq $splits[1] -and - $args[0].hostheader -eq $splits[2] - ) - { - Return $binding - } - } -} - -# create binding search splat -$binding_parameters = @{ - Name = $name - Protocol = $protocol - Port = $port - IPAddress = $ip -} - -# insert host header to search if specified, otherwise it will return * (all bindings matching protocol/ip) -If ($host_header) -{ - $binding_parameters.HostHeader = $host_header -} -Else -{ - $binding_parameters.HostHeader = [string]::Empty -} - -# Get bindings matching parameters -Try { - $current_bindings = Get-SingleWebBinding $binding_parameters -} -Catch { - Fail-Json -obj $result -message "Failed to retrieve bindings with Get-SingleWebBinding - $($_.Exception.Message)" -} - -If ($current_bindings) -{ - Try { - $binding_info = Create-BindingInfo $current_bindings - } - Catch { - Fail-Json -obj $result -message "Failed to create binding info - $($_.Exception.Message)" - } - - $result.binding = $binding_info -} -exit-json -obj $result \ No newline at end of file diff --git a/test/integration/targets/win_iis_webbinding/tasks/failures.yml b/test/integration/targets/win_iis_webbinding/tasks/failures.yml deleted file mode 100644 index 92736fe1bb3..00000000000 --- a/test/integration/targets/win_iis_webbinding/tasks/failures.yml +++ /dev/null @@ -1,70 +0,0 @@ -- name: failure check define * for host header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - host_header: '*' - protocol: http - ip: '*' - register: failure - failed_when: failure.msg != "To make or remove a catch-all binding, please omit the host_header parameter entirely rather than specify host_header *" - -- debug: - var: failure - verbosity: 1 - -- block: - - name: get all websites from server - raw: powershell.exe "(get-website).name" - register: existing_sites - - - name: ensure all sites are removed for clean testing - win_iis_website: - name: "{{ item }}" - state: absent - with_items: - - "{{ existing_sites.stdout_lines }}" - - - name: add testremove site - win_iis_website: - name: testremove - state: started - physical_path: c:\inetpub\wwwroot - - - name: add bindings to testremove - win_iis_webbinding: - name: testremove - ip: "{{ item.ip }}" - port: "{{ item.port }}" - with_items: - - {ip: 127.0.0.1, port: 80} - - {ip: '*', port: 80} - - - name: remove ip * binding from testremove - win_iis_webbinding: - name: testremove - state: absent - port: 80 - ip: '*' - - - name: get the remaining binding from testremove - test_get_webbindings: - name: testremove - port: 80 - ip: 127.0.0.1 - register: test_result - - - debug: - var: test_result - verbosity: 1 - - - name: assert that remove *:80 doesn't also remove 127.0.0.1:80 - assert: - that: - - test_result.binding.ip == '127.0.0.1' - - test_result.binding.port == 80 - - always: - - name: remove websites - win_iis_website: - name: testremove - state: absent diff --git a/test/integration/targets/win_iis_webbinding/tasks/http.yml b/test/integration/targets/win_iis_webbinding/tasks/http.yml deleted file mode 100644 index 34c4cc2c19f..00000000000 --- a/test/integration/targets/win_iis_webbinding/tasks/http.yml +++ /dev/null @@ -1,317 +0,0 @@ -#cm add -#changed true, check nothing present -- name: CM add http binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - protocol: "{{ http_vars.protocol }}" - ip: "{{ http_vars.ip }}" - port: "{{ http_vars.port }}" - register: http_no_header - check_mode: yes - -- name: CM get binding info no header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - protocol: "{{ http_vars.protocol }}" - ip: "{{ http_vars.ip }}" - port: "{{ http_vars.port }}" - register: get_http_no_header - changed_when: false - -- name: CM add http binding with header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - host_header: "{{ http_header_vars.header }}" - protocol: "{{ http_header_vars.protocol }}" - ip: "{{ http_header_vars.ip }}" - port: "{{ http_header_vars.port }}" - register: http_header - check_mode: yes - -- name: CM get binding info header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - host_header: "{{ http_header_vars.header }}" - protocol: "{{ http_header_vars.protocol }}" - ip: "{{ http_header_vars.ip }}" - port: "{{ http_header_vars.port }}" - register: get_http_header - changed_when: false - -- name: CM assert changed, but not added - assert: - that: - - http_no_header is changed - - http_no_header.binding_info is none - - get_http_no_header.binding is not defined - - http_header is changed - - http_header.binding_info is none - - get_http_header.binding is not defined - -#add -#changed true, new bindings present -- name: add http binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - protocol: "{{ http_vars.protocol }}" - ip: "{{ http_vars.ip }}" - port: "{{ http_vars.port }}" - register: http_no_header - -- name: get binding info no header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - protocol: "{{ http_vars.protocol }}" - ip: "{{ http_vars.ip }}" - port: "{{ http_vars.port }}" - register: get_http_no_header - changed_when: false - -- name: add http binding with header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - host_header: "{{ http_header_vars.header }}" - protocol: "{{ http_header_vars.protocol }}" - ip: "{{ http_header_vars.ip }}" - port: "{{ http_header_vars.port }}" - register: http_header - -- name: get binding info header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - host_header: "{{ http_header_vars.header }}" - protocol: "{{ http_header_vars.protocol }}" - ip: "{{ http_header_vars.ip }}" - port: "{{ http_header_vars.port }}" - register: get_http_header - changed_when: false - -- name: assert changed and added - assert: - that: - - http_no_header is changed - - http_no_header.binding_info is defined - - http_no_header.operation_type == 'added' - - http_no_header.binding_info.ip == "{{ http_vars.ip }}" - - http_no_header.binding_info.port == {{ http_vars.port }} - - http_no_header.binding_info.protocol == "{{ http_vars.protocol }}" - - http_header is changed - - http_header.binding_info is defined - - http_header.operation_type == 'added' - - http_header.binding_info.ip == "{{ http_header_vars.ip }}" - - http_header.binding_info.port == {{ http_header_vars.port }} - - http_header.binding_info.protocol == "{{ http_header_vars.protocol }}" - - http_header.binding_info.hostheader == "{{ http_header_vars.header }}" - -#add idem -#changed false -- name: idem add http binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - protocol: "{{ http_vars.protocol }}" - ip: "{{ http_vars.ip }}" - port: "{{ http_vars.port }}" - register: http_no_header - -- name: idem add http binding with header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - host_header: "{{ http_header_vars.header }}" - protocol: "{{ http_header_vars.protocol }}" - ip: "{{ http_header_vars.ip }}" - port: "{{ http_header_vars.port }}" - register: http_header - -- name: idem assert not changed - assert: - that: - - http_no_header is not changed - - http_header is not changed - -#modify -#can't test modify for http, it will add a new binding instead since -#there's no way to match existing bindings against the new parameters - -#cm remove -#changed true, bindings still present -- name: cm remove http binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: absent - protocol: "{{ http_vars.protocol }}" - ip: "{{ http_vars.ip }}" - port: "{{ http_vars.port }}" - register: http_no_header - check_mode: yes - -- name: get binding info no header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - protocol: "{{ http_vars.protocol }}" - ip: "{{ http_vars.ip }}" - port: "{{ http_vars.port }}" - register: get_http_no_header - changed_when: false - -- name: cm remove http binding with header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: absent - host_header: "{{ http_header_vars.header }}" - protocol: "{{ http_header_vars.protocol }}" - ip: "{{ http_header_vars.ip }}" - port: "{{ http_header_vars.port }}" - register: http_header - check_mode: yes - -- name: get binding info header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - host_header: "{{ http_header_vars.header }}" - protocol: "{{ http_header_vars.protocol }}" - ip: "{{ http_header_vars.ip }}" - port: "{{ http_header_vars.port }}" - register: get_http_header - changed_when: false - -- name: cm remove assert changed, but still present - assert: - that: - - http_no_header is changed - - http_no_header.binding_info is defined - - http_no_header.operation_type == 'removed' - - http_no_header.binding_info.ip == "{{ http_vars.ip }}" - - http_no_header.binding_info.port == {{ http_vars.port }} - - http_no_header.binding_info.protocol == "{{ http_vars.protocol }}" - - get_http_no_header.binding is defined - - get_http_no_header.binding.ip == "{{ http_vars.ip }}" - - get_http_no_header.binding.port == {{ http_vars.port }} - - get_http_no_header.binding.protocol == "{{ http_vars.protocol }}" - - http_header is changed - - http_header.binding_info is defined - - http_header.operation_type == 'removed' - - http_header.binding_info.ip == "{{ http_header_vars.ip }}" - - http_header.binding_info.port == {{ http_header_vars.port }} - - http_header.binding_info.protocol == "{{ http_header_vars.protocol }}" - - http_header.binding_info.hostheader == "{{ http_header_vars.header }}" - - get_http_header.binding is defined - - get_http_header.binding.ip == "{{ http_header_vars.ip }}" - - get_http_header.binding.port == {{ http_header_vars.port }} - - get_http_header.binding.protocol == "{{ http_header_vars.protocol }}" - - get_http_header.binding.hostheader == "{{ http_header_vars.header }}" - - -#remove -#changed true, bindings gone -- name: remove http binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: absent - protocol: "{{ http_vars.protocol }}" - ip: "{{ http_vars.ip }}" - port: "{{ http_vars.port }}" - register: http_no_header - -- name: get binding info no header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - protocol: "{{ http_vars.protocol }}" - ip: "{{ http_vars.ip }}" - port: "{{ http_vars.port }}" - register: get_http_no_header - changed_when: false - -- name: remove http binding with header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: absent - host_header: "{{ http_header_vars.header }}" - protocol: "{{ http_header_vars.protocol }}" - ip: "{{ http_header_vars.ip }}" - port: "{{ http_header_vars.port }}" - register: http_header - -- name: get binding info header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - host_header: "{{ http_header_vars.header }}" - protocol: "{{ http_header_vars.protocol }}" - ip: "{{ http_header_vars.ip }}" - port: "{{ http_header_vars.port }}" - register: get_http_header - changed_when: false - -- name: remove assert changed and gone - assert: - that: - - http_no_header is changed - - http_no_header.operation_type == 'removed' - - http_no_header.binding_info is defined - - http_no_header.binding_info.ip == "{{ http_vars.ip }}" - - http_no_header.binding_info.port == {{ http_vars.port }} - - http_no_header.binding_info.protocol == "{{ http_vars.protocol }}" - - get_http_no_header.binding is not defined - - http_header is changed - - http_header.binding_info is defined - - http_header.operation_type == 'removed' - - http_header.binding_info.ip == "{{ http_header_vars.ip }}" - - http_header.binding_info.port == {{ http_header_vars.port }} - - http_header.binding_info.protocol == "{{ http_header_vars.protocol }}" - - http_header.binding_info.hostheader == "{{ http_header_vars.header }}" - - get_http_header.binding is not defined - -#remove idem -#change false, bindings gone -- name: idem remove http binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: absent - protocol: "{{ http_vars.protocol }}" - ip: "{{ http_vars.ip }}" - port: "{{ http_vars.port }}" - register: http_no_header - -- name: get binding info no header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - protocol: "{{ http_vars.protocol }}" - ip: "{{ http_vars.ip }}" - port: "{{ http_vars.port }}" - register: get_http_no_header - changed_when: false - -- name: idem remove http binding with header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: absent - host_header: "{{ http_header_vars.header }}" - protocol: "{{ http_header_vars.protocol }}" - ip: "{{ http_header_vars.ip }}" - port: "{{ http_header_vars.port }}" - register: http_header - -- name: get binding info header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - host_header: "{{ http_header_vars.header }}" - protocol: "{{ http_header_vars.protocol }}" - ip: "{{ http_header_vars.ip }}" - port: "{{ http_header_vars.port }}" - register: get_http_header - changed_when: false - -- name: idem remove assert changed and gone - assert: - that: - - http_no_header is not changed - - http_no_header.binding_info is not defined - - get_http_no_header.binding is not defined - - http_header is not changed - - http_header.binding_info is not defined - - get_http_header.binding is not defined diff --git a/test/integration/targets/win_iis_webbinding/tasks/https-ge6.2.yml b/test/integration/targets/win_iis_webbinding/tasks/https-ge6.2.yml deleted file mode 100644 index f883c673ff0..00000000000 --- a/test/integration/targets/win_iis_webbinding/tasks/https-ge6.2.yml +++ /dev/null @@ -1,459 +0,0 @@ -############## -### CM Add ### -############## -#changed true, check nothing present -- name: CM add https binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - certificate_hash: "{{ thumbprint1.stdout_lines[0] }}" - register: https_no_header - check_mode: yes - -- name: CM get binding info no header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: get_https_no_header - changed_when: false - -- name: CM add https binding with header and SNI - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - host_header: "{{ https_header_vars.header }}" - protocol: "{{ https_header_vars.protocol }}" - ip: "{{ https_header_vars.ip }}" - port: "{{ https_header_vars.port }}" - ssl_flags: 1 - certificate_hash: "{{ thumbprint1.stdout_lines[0] }}" - register: https_header - check_mode: yes - -- name: CM get binding info header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - host_header: "{{ https_header_vars.header }}" - protocol: "{{ https_header_vars.protocol }}" - ip: "{{ https_header_vars.ip }}" - port: "{{ https_header_vars.port }}" - register: get_https_header - changed_when: false - -- name: CM assert changed, but not added - assert: - that: - - https_no_header is changed - - https_no_header.operation_type == 'added' - - https_no_header.binding_info is none - - get_https_no_header.binding is not defined - - https_header is changed - - https_header.operation_type == 'added' - - https_header.binding_info is none - - get_https_header.binding is not defined - -########### -### Add ### -########### -#changed true, new bindings present -- name: add https binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - certificate_hash: "{{ thumbprint1.stdout_lines[0] }}" - register: https_no_header - -- name: get binding info no header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: get_https_no_header - changed_when: false - -- name: add https binding with header SNI - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - host_header: "{{ https_header_vars.header }}" - protocol: "{{ https_header_vars.protocol }}" - ip: "{{ https_header_vars.ip }}" - port: "{{ https_header_vars.port }}" - ssl_flags: 1 - certificate_hash: "{{ thumbprint1.stdout_lines[0] }}" - register: https_header - -- name: get binding info header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - host_header: "{{ https_header_vars.header }}" - protocol: "{{ https_header_vars.protocol }}" - ip: "{{ https_header_vars.ip }}" - port: "{{ https_header_vars.port }}" - register: get_https_header - changed_when: false - -- name: assert changed and added - assert: - that: - - https_no_header is changed - - https_no_header.operation_type == 'added' - - https_no_header.binding_info is defined - - https_no_header.binding_info.protocol == "{{ https_vars.protocol }}" - - https_no_header.binding_info.ip == "{{ https_vars.ip }}" - - https_no_header.binding_info.port == {{ https_vars.port }} - - https_no_header.binding_info.hostheader == '' - - https_no_header.binding_info.certificateHash == "{{ thumbprint1.stdout_lines[0] }}" - - https_header is changed - - https_header.operation_type == 'added' - - https_header.binding_info is defined - - https_header.binding_info.hostheader == "{{ https_header_vars.header }}" - - https_header.binding_info.protocol == "{{ https_header_vars.protocol }}" - - https_header.binding_info.ip == "{{ https_header_vars.ip }}" - - https_header.binding_info.port == {{ https_header_vars.port }} - - https_header.binding_info.certificateHash == "{{ thumbprint1.stdout_lines[0] }}" - - https_header.binding_info.sslFlags == 1 - -################ -### Idem Add ### -################ -#changed false -- name: idem add https binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - protocol: https - ip: '*' - port: 443 - certificate_hash: "{{ thumbprint1.stdout_lines[0] }}" - register: https_no_header - -- name: idem add https binding with header and SNI - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - host_header: test.com - protocol: https - ip: '*' - port: 443 - ssl_flags: 1 - certificate_hash: "{{ thumbprint1.stdout_lines[0] }}" - register: https_header - -- name: idem assert not changed - assert: - that: - - https_no_header is not changed - - https_header is not changed - -################# -### CM Modify ### -################# -# changed true, verify no changes occurred - -#modify sni -- name: CM modify https binding with header, change cert - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - host_header: "{{ https_header_vars.header }}" - protocol: "{{ https_header_vars.protocol }}" - ip: "{{ https_header_vars.ip }}" - port: "{{ https_header_vars.port }}" - ssl_flags: 1 - certificate_hash: "{{ thumbprint2.stdout_lines[0] }}" - register: https_header - check_mode: yes - -- name: get binding info header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - host_header: "{{ https_header_vars.header }}" - protocol: "{{ https_header_vars.protocol }}" - ip: "{{ https_header_vars.ip }}" - port: "{{ https_header_vars.port }}" - register: get_https_header - changed_when: false - -- name: CM assert changed but old cert - assert: - that: - - https_header is changed - - https_header.operation_type == 'updated' - - https_header.binding_info is defined - - https_header.binding_info.ip == "{{ https_header_vars.ip }}" - - https_header.binding_info.port == {{ https_header_vars.port }} - - https_header.binding_info.protocol == "{{ https_header_vars.protocol }}" - - https_header.binding_info.hostheader == "{{ https_header_vars.header }}" - - https_header.binding_info.certificateHash == "{{ thumbprint1.stdout_lines[0] }}" - - https_header.binding_info.sslFlags == 1 - - get_https_header.binding is defined - - get_https_header.binding.ip == "{{ https_header_vars.ip }}" - - get_https_header.binding.port == {{ https_header_vars.port }} - - get_https_header.binding.protocol == "{{ https_header_vars.protocol }}" - - get_https_header.binding.hostheader == "{{ https_header_vars.header }}" - - get_https_header.binding.certificateHash == "{{ thumbprint1.stdout_lines[0] }}" - - get_https_header.binding.sslFlags == 1 - -############## -### Modify ### -############## -# modify ssl flags -- name: modify https binding with header, change cert - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - host_header: "{{ https_header_vars.header }}" - protocol: "{{ https_header_vars.protocol }}" - ip: "{{ https_header_vars.ip }}" - port: "{{ https_header_vars.port }}" - ssl_flags: 1 - certificate_hash: "{{ thumbprint2.stdout_lines[0] }}" - register: https_header - -- name: get binding info header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - host_header: "{{ https_header_vars.header }}" - protocol: "{{ https_header_vars.protocol }}" - ip: "{{ https_header_vars.ip }}" - port: "{{ https_header_vars.port }}" - register: get_https_header - changed_when: false - -- name: modify assert changed and new cert - assert: - that: - - https_header is changed - - https_header.operation_type == 'updated' - - https_header.binding_info is defined - - https_header.binding_info.ip == "{{ https_header_vars.ip }}" - - https_header.binding_info.port == {{ https_header_vars.port }} - - https_header.binding_info.protocol == "{{ https_header_vars.protocol }}" - - https_header.binding_info.hostheader == "{{ https_header_vars.header }}" - - https_header.binding_info.certificateHash == "{{ thumbprint2.stdout_lines[0] }}" - - https_header.binding_info.sslFlags == 1 - - get_https_header.binding is defined - - get_https_header.binding.ip == "{{ https_header_vars.ip }}" - - get_https_header.binding.port == {{ https_header_vars.port }} - - get_https_header.binding.protocol == "{{ https_header_vars.protocol }}" - - get_https_header.binding.hostheader == "{{ https_header_vars.header }}" - - get_https_header.binding.certificateHash == "{{ thumbprint2.stdout_lines[0] }}" - - get_https_header.binding.sslFlags == 1 - -################### -### Idem Modify ### -################### -#changed false - -#idem modify ssl flags -- name: idem modify https binding with header, enable SNI and change cert - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - host_header: "{{ https_header_vars.header }}" - protocol: "{{ https_header_vars.protocol }}" - ip: "{{ https_header_vars.ip }}" - port: "{{ https_header_vars.port }}" - ssl_flags: 1 - certificate_hash: "{{ thumbprint2.stdout_lines[0] }}" - register: https_header - -- name: idem assert not changed - assert: - that: - - https_header is not changed - -################# -### CM Remove ### -################# -#changed true, bindings still present -- name: cm remove https binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: absent - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: https_no_header - check_mode: yes - -- name: get binding info no header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: get_https_no_header - changed_when: false - -- name: cm remove https binding with header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: absent - host_header: "{{ https_header_vars.header }}" - protocol: "{{ https_header_vars.protocol }}" - ip: "{{ https_header_vars.ip }}" - port: "{{ https_header_vars.port }}" - register: https_header - check_mode: yes - -- name: get binding info header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - host_header: "{{ https_header_vars.header }}" - protocol: "{{ https_header_vars.protocol }}" - ip: "{{ https_header_vars.ip }}" - port: "{{ https_header_vars.port }}" - register: get_https_header - changed_when: false - -- name: cm remove assert changed, but still present - assert: - that: - - https_no_header is changed - - https_no_header.operation_type == 'removed' - - https_no_header.binding_info is defined - - https_no_header.binding_info.ip == "{{ https_vars.ip }}" - - https_no_header.binding_info.port == {{ https_vars.port }} - - https_no_header.binding_info.protocol == "{{ https_vars.protocol }}" - - get_https_no_header.binding is defined - - get_https_no_header.binding.ip == "{{ https_vars.ip }}" - - get_https_no_header.binding.port == {{ https_vars.port }} - - get_https_no_header.binding.protocol == "{{ https_vars.protocol }}" - - get_https_no_header.binding.certificateHash == "{{ thumbprint1.stdout_lines[0] }}" - - https_header is changed - - https_header.binding_info is defined - - https_header.operation_type == 'removed' - - https_header.binding_info.ip == "{{ https_header_vars.ip }}" - - https_header.binding_info.port == {{ https_header_vars.port }} - - https_header.binding_info.protocol == "{{ https_header_vars.protocol }}" - - https_header.binding_info.hostheader == "{{ https_header_vars.header }}" - - get_https_header.binding is defined - - get_https_header.binding.ip == "{{ https_header_vars.ip }}" - - get_https_header.binding.port == {{ https_header_vars.port }} - - get_https_header.binding.protocol == "{{ https_header_vars.protocol }}" - - get_https_header.binding.hostheader == "{{ https_header_vars.header }}" - - get_https_header.binding.certificateHash == "{{ thumbprint2.stdout_lines[0] }}" - -############## -### remove ### -############## -#changed true, bindings gone -- name: remove https binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: absent - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: https_no_header - -- name: get binding info no header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: get_https_no_header - changed_when: false - -- name: remove https binding with header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: absent - host_header: "{{ https_header_vars.header }}" - protocol: "{{ https_header_vars.protocol }}" - ip: "{{ https_header_vars.ip }}" - port: "{{ https_header_vars.port }}" - register: https_header - -- name: get binding info header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - host_header: "{{ https_header_vars.header }}" - protocol: "{{ https_header_vars.protocol }}" - ip: "{{ https_header_vars.ip }}" - port: "{{ https_header_vars.port }}" - register: get_https_header - changed_when: false - -- name: remove assert changed and gone - assert: - that: - - https_no_header is changed - - https_no_header.binding_info is defined - - https_no_header.operation_type == 'removed' - - https_no_header.binding_info.ip == "{{ https_vars.ip }}" - - https_no_header.binding_info.port == {{ https_vars.port }} - - https_no_header.binding_info.protocol == "{{ https_vars.protocol }}" - - get_https_no_header.binding is not defined - - https_header is changed - - https_header.binding_info is defined - - https_header.operation_type == 'removed' - - https_header.binding_info.ip == "{{ https_header_vars.ip }}" - - https_header.binding_info.port == {{ https_header_vars.port }} - - https_header.binding_info.protocol == "{{ https_header_vars.protocol }}" - - https_header.binding_info.hostheader == "{{ https_header_vars.header }}" - - get_https_header.binding is not defined - -################### -### remove idem ### -################### -#change false, bindings gone -- name: idem remove https binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: absent - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: https_no_header - -- name: get binding info no header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: get_https_no_header - changed_when: false - -- name: idem remove https binding with header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: absent - host_header: "{{ https_header_vars.header }}" - protocol: "{{ https_header_vars.protocol }}" - ip: "{{ https_header_vars.ip }}" - port: "{{ https_header_vars.port }}" - register: https_header - -- name: get binding info header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - host_header: "{{ https_header_vars.header }}" - protocol: "{{ https_header_vars.protocol }}" - ip: "{{ https_header_vars.ip }}" - port: "{{ https_header_vars.port }}" - register: get_https_header - changed_when: false - -- name: idem remove assert changed and gone - assert: - that: - - https_no_header is not changed - - https_no_header.binding_info is not defined - - get_https_no_header.binding is not defined - - https_header is not changed - - https_header.binding_info is not defined - - get_https_header.binding is not defined diff --git a/test/integration/targets/win_iis_webbinding/tasks/https-lt6.2.yml b/test/integration/targets/win_iis_webbinding/tasks/https-lt6.2.yml deleted file mode 100644 index 1950641e8dc..00000000000 --- a/test/integration/targets/win_iis_webbinding/tasks/https-lt6.2.yml +++ /dev/null @@ -1,423 +0,0 @@ -############## -### CM Add ### -############## -#changed true, check nothing present -- name: CM add https binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - certificate_hash: "{{ thumbprint1.stdout_lines[0] }}" - register: https_no_header - check_mode: yes - -- name: CM get binding info no header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: get_https_no_header - changed_when: false - -- name: CM assert changed, but not added - assert: - that: - - https_no_header is changed - - https_no_header.operation_type == 'added' - - https_no_header.binding_info is none - - get_https_no_header.binding is not defined - -########### -### Add ### -########### -#changed true, new bindings present -- name: add https binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - certificate_hash: "{{ thumbprint1.stdout_lines[0] }}" - register: https_no_header - -- name: assert changed and added - assert: - that: - - https_no_header is changed - - https_no_header.binding_info is defined - - https_no_header.operation_type == 'added' - - https_no_header.binding_info.ip == "{{ https_vars.ip }}" - - https_no_header.binding_info.port == {{ https_vars.port }} - - https_no_header.binding_info.protocol == "{{ https_vars.protocol }}" - - https_no_header.binding_info.hostheader == '' - - https_no_header.binding_info.certificateHash == "{{ thumbprint1.stdout_lines[0] }}" - -################ -### Idem Add ### -################ -#changed false -- name: idem add https binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - certificate_hash: "{{ thumbprint1.stdout_lines[0] }}" - register: https_no_header - -- name: idem assert not changed - assert: - that: - - https_no_header is not changed - -################# -### CM Modify ### -################# -# changed true, verify no changes occurred - -#modify sni -- name: CM modify https binding change cert - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - certificate_hash: "{{ thumbprint2.stdout_lines[0] }}" - register: https_no_header - check_mode: yes - -- name: get binding info header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: get_https_no_header - changed_when: false - -- name: CM assert changed but old cert - assert: - that: - - https_no_header is changed - - https_no_header.operation_type == 'updated' - - https_no_header.binding_info is defined - - https_no_header.binding_info.ip == "{{ https_vars.ip }}" - - https_no_header.binding_info.port == {{ https_vars.port }} - - https_no_header.binding_info.protocol == "{{ https_vars.protocol }}" - - https_no_header.binding_info.certificateHash == "{{ thumbprint1.stdout_lines[0] }}" - - get_https_no_header.binding is defined - - get_https_no_header.binding.ip == "{{ https_vars.ip }}" - - get_https_no_header.binding.port == {{ https_vars.port }} - - get_https_no_header.binding.protocol == "{{ https_vars.protocol }}" - - get_https_no_header.binding.certificateHash == "{{ thumbprint1.stdout_lines[0] }}" - -############## -### Modify ### -############## -# modify ssl flags -- name: modify https binding, change cert - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - certificate_hash: "{{ thumbprint2.stdout_lines[0] }}" - register: https_no_header - -- name: get binding info header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: get_https_no_header - changed_when: false - -- name: modify assert changed and new cert - assert: - that: - - https_no_header is changed - - https_no_header.operation_type == 'updated' - - https_no_header.binding_info is defined - - https_no_header.binding_info.ip == "{{ https_vars.ip }}" - - https_no_header.binding_info.port == {{ https_vars.port }} - - https_no_header.binding_info.protocol == "{{ https_vars.protocol }}" - - https_no_header.binding_info.certificateHash == "{{ thumbprint2.stdout_lines[0] }}" - - get_https_no_header.binding is defined - - get_https_no_header.binding.ip == "{{ https_vars.ip }}" - - get_https_no_header.binding.port == {{ https_vars.port }} - - get_https_no_header.binding.protocol == "{{ https_vars.protocol }}" - - get_https_no_header.binding.hostheader == '' - - get_https_no_header.binding.certificateHash == "{{ thumbprint2.stdout_lines[0] }}" - -################### -### Idem Modify ### -################### -#changed false - -#idem modify ssl flags -- name: idem modify https binding and change cert - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: present - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - certificate_hash: "{{ thumbprint2.stdout_lines[0] }}" - register: https_header - -- name: idem assert not changed - assert: - that: - - https_header is not changed - -################# -### CM Remove ### -################# -#changed true, bindings still present -- name: cm remove https binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: absent - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: https_no_header - check_mode: yes - -- name: get binding info no header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: get_https_no_header - changed_when: false - -- name: cm remove assert changed, but still present - assert: - that: - - https_no_header is changed - - https_no_header.operation_type == 'removed' - - https_no_header.binding_info is defined - - https_no_header.binding_info.ip == "{{ https_vars.ip }}" - - https_no_header.binding_info.port == {{ https_vars.port }} - - https_no_header.binding_info.protocol == "{{ https_vars.protocol }}" - - https_no_header.binding_info.certificateHash == "{{ thumbprint2.stdout_lines[0] }}" - - get_https_no_header.binding is defined - - get_https_no_header.binding.ip == "{{ https_vars.ip }}" - - get_https_no_header.binding.port == {{ https_vars.port }} - - get_https_no_header.binding.protocol == "{{ https_vars.protocol }}" - - get_https_no_header.binding.certificateHash == "{{ thumbprint2.stdout_lines[0] }}" - -############## -### remove ### -############## -#changed true, bindings gone -- name: remove https binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: absent - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: https_no_header - -- name: get binding info no header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: get_https_no_header - changed_when: false - -- name: remove assert changed and gone - assert: - that: - - https_no_header is changed - - https_no_header.operation_type == 'removed' - - https_no_header.binding_info is defined - - https_no_header.binding_info.ip == "{{ https_vars.ip }}" - - https_no_header.binding_info.port == {{ https_vars.port }} - - https_no_header.binding_info.protocol == "{{ https_vars.protocol }}" - - get_https_no_header.binding is not defined - -################### -### remove idem ### -################### -#change false, bindings gone -- name: idem remove https binding no header - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: absent - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: https_no_header - -- name: get binding info no header - test_get_webbindings: - name: "{{ test_iis_site_name }}" - protocol: "{{ https_vars.protocol }}" - ip: "{{ https_vars.ip }}" - port: "{{ https_vars.port }}" - register: get_https_no_header - changed_when: false - -- name: idem remove assert changed and gone - assert: - that: - - https_no_header is not changed - - https_no_header.binding_info is not defined - - get_https_no_header.binding is not defined - - -################## -### WC Testing ### -################## - -# Unfortunately this does not work due to some strange errors -# that are caused when using a self signed wildcard cert. -# I'm leaving this here in case someone finds a solution in the -# future. - -# - name: add https binding wildcard with header -# win_iis_webbinding: -# name: "{{ test_iis_site_name }}" -# state: present -# host_header: "{{ https_wc_vars.header }}" -# protocol: "{{ https_wc_vars.protocol }}" -# ip: "{{ https_wc_vars.ip }}" -# port: "{{ https_wc_vars.port }}" -# certificate_hash: "{{ thumbprint_wc.stdout_lines[0] }}" -# register: https_header - -# - name: assert changed and added -# assert: -# that: -# - https_header is changed -# - https_header.added is defined -# - https_header.added.ip == "{{ https_wc_vars.ip }}" -# - https_header.added.port == {{ https_wc_vars.port }} -# - https_header.added.protocol == "{{ https_wc_vars.protocol }}" -# - https_header.added.hostheader == "{{ https_wc_vars.header }}" -# - https_header.added.certificateHash == "{{ thumbprint_wc.stdout_lines[0] }}" - - -# - name: idem add https binding wildcard with header -# win_iis_webbinding: -# name: "{{ test_iis_site_name }}" -# state: present -# host_header: "{{ https_wc_vars.header }}" -# protocol: "{{ https_wc_vars.protocol }}" -# ip: "{{ https_wc_vars.ip }}" -# port: "{{ https_wc_vars.port }}" -# certificate_hash: "{{ thumbprint_wc.stdout_lines[0] }}" -# register: https_header - - -# - name: cm remove wildcard https binding -# win_iis_webbinding: -# name: "{{ test_iis_site_name }}" -# state: absent -# host_header: "{{ https_wc_vars.header }}" -# protocol: "{{ https_wc_vars.protocol }}" -# ip: "{{ https_wc_vars.ip }}" -# port: "{{ https_wc_vars.port }}" -# register: https_header -# check_mode: yes - -# - name: get binding info header -# test_get_webbindings: -# name: "{{ test_iis_site_name }}" -# host_header: "{{ https_wc_vars.header }}" -# protocol: "{{ https_wc_vars.protocol }}" -# ip: "{{ https_wc_vars.ip }}" -# port: "{{ https_wc_vars.port }}" -# register: get_https_header -# changed_when: false - -# - name: cm remove assert changed, but still present -# assert: -# that: -# - https_header is changed -# - https_header.removed is defined -# - https_header.removed.ip == "{{ https_wc_vars.ip }}" -# - https_header.removed.port == {{ https_wc_vars.port }} -# - https_header.removed.protocol == "{{ https_wc_vars.protocol }}" -# - https_header.removed.hostheader == "{{ https_wc_vars.header }}" -# - https_header.removed.certificateHash == "{{ thumbprint_wc.stdout_lines[0] }}" -# - get_https_header.binding is defined -# - get_https_header.removed.ip == "{{ https_wc_vars.ip }}" -# - get_https_header.removed.port == {{ https_wc_vars.port }} -# - get_https_header.removed.protocol == "{{ https_wc_vars.protocol }}" -# - get_https_header.removed.hostheader == "{{ https_wc_vars.header }}" -# - get_https_header.removed.certificateHash == "{{ thumbprint_wc.stdout_lines[0] }}" - -# - name: remove wildcard https binding -# win_iis_webbinding: -# name: "{{ test_iis_site_name }}" -# state: absent -# host_header: "{{ https_wc_vars.header }}" -# protocol: "{{ https_wc_vars.protocol }}" -# ip: "{{ https_wc_vars.ip }}" -# port: "{{ https_wc_vars.port }}" -# register: https_header - -# - name: get binding info header -# test_get_webbindings: -# name: "{{ test_iis_site_name }}" -# host_header: "{{ https_wc_vars.header }}" -# protocol: "{{ https_wc_vars.protocol }}" -# ip: "{{ https_wc_vars.ip }}" -# port: "{{ https_wc_vars.port }}" -# register: get_https_header -# changed_when: false - - -# - name: remove assert changed and gone -# assert: -# that: -# - https_header is changed -# - https_header.removed is defined -# - https_header.removed.ip == "{{ https_wc_vars.ip }}" -# - https_header.removed.port == {{ https_wc_vars.port }} -# - https_header.removed.protocol == "{{ https_wc_vars.protocol }}" -# - https_header.removed.hostheader == "{{ https_wc_vars.header }}" -# - https_header.removed.certificateHash == "{{ thumbprint_wc.stdout_lines[0] }}" -# - get_https_header.binding is not defined - -# - name: idem remove wildcard https binding -# win_iis_webbinding: -# name: "{{ test_iis_site_name }}" -# state: absent -# host_header: "{{ https_wc_vars.header }}" -# protocol: "{{ https_wc_vars.protocol }}" -# ip: "{{ https_wc_vars.ip }}" -# port: "{{ https_wc_vars.port }}" -# register: https_header - -# - name: get binding info header -# test_get_webbindings: -# name: "{{ test_iis_site_name }}" -# host_header: "{{ https_wc_vars.header }}" -# protocol: "{{ https_wc_vars.protocol }}" -# ip: "{{ https_wc_vars.ip }}" -# port: "{{ https_wc_vars.port }}" -# register: get_https_header -# changed_when: false - -# - name: idem remove assert changed and gone -# assert: -# that: -# - https_header is not changed -# - https_header.removed is not defined -# - get_https_header.binding is not defined diff --git a/test/integration/targets/win_iis_webbinding/tasks/main.yml b/test/integration/targets/win_iis_webbinding/tasks/main.yml deleted file mode 100644 index 3c918cb8263..00000000000 --- a/test/integration/targets/win_iis_webbinding/tasks/main.yml +++ /dev/null @@ -1,62 +0,0 @@ ---- -# Cannot use win_feature to install IIS on Server 2008. -# Run a brief check and skip hosts that don't support -# that operation -#seems "raw" is the only module that works on 2008 non-r2. win_command and win_shell both failed -- name: register os version (seems integration tests don't gather this fact) - raw: powershell.exe "gwmi Win32_OperatingSystem | select -expand version" - register: os_version - changed_when: False - -- block: - - include_tasks: setup.yml - - include_tasks: http.yml - - include_tasks: https-lt6.2.yml - when: os_version.stdout_lines[0] is version('6.2','lt') - - include_tasks: https-ge6.2.yml - when: os_version.stdout_lines[0] is version('6.2','ge') - - include_tasks: failures.yml - - always: - - name: get all websites from server - raw: powershell.exe "(get-website).name" - register: existing_sites - - - name: ensure all sites are removed for clean testing - win_iis_website: - name: "{{ item }}" - state: absent - with_items: - - "{{ existing_sites.stdout_lines }}" - - - name: cleanup certreq files - win_file: - path: "{{ item }}" - state: absent - with_items: - - c:\windows\temp\certreq1.txt - - c:\windows\temp\certreq2.txt - - c:\windows\temp\certreqwc.txt - - c:\windows\temp\certreqresp1.txt - - c:\windows\temp\certreqresp2.txt - - c:\windows\temp\certreqrespwc.txt - - - name: remove certs - raw: 'remove-item cert:\localmachine\my\{{ item }} -force -ea silentlycontinue' - with_items: - - "{{ thumbprint1.stdout_lines[0] }}" - - "{{ thumbprint2.stdout_lines[0] }}" - - "{{ thumbprint_wc.stdout_lines[0] }}" - - - name: remove IIS features after test - win_feature: - name: Web-Server - state: absent - includ_sub_features: True - include_management_tools: True - register: feature_uninstall - - - name: reboot after feature install - win_reboot: - when: feature_uninstall.reboot_required - when: os_version.stdout_lines[0] is version('6.1','gt') diff --git a/test/integration/targets/win_iis_webbinding/tasks/setup.yml b/test/integration/targets/win_iis_webbinding/tasks/setup.yml deleted file mode 100644 index 708f3edcf2d..00000000000 --- a/test/integration/targets/win_iis_webbinding/tasks/setup.yml +++ /dev/null @@ -1,93 +0,0 @@ -- name: reboot before feature install to ensure server is in clean state - win_reboot: - -- name: ensure IIS features are installed - win_feature: - name: Web-Server - state: present - includ_sub_features: True - include_management_tools: True - register: feature_install - -- name: reboot after feature install - win_reboot: - when: feature_install.reboot_required - -- name: get all websites from server - raw: powershell.exe "(get-website).name" - register: existing_sites - -- name: ensure all sites are removed for clean testing - win_iis_website: - name: "{{ item }}" - state: absent - with_items: - - "{{ existing_sites.stdout_lines }}" - -- name: add testing site {{ test_iis_site_name }} - win_iis_website: - name: "{{ test_iis_site_name }}" - physical_path: c:\inetpub\wwwroot - -- name: ensure all bindings are removed prior to starting testing - win_iis_webbinding: - name: "{{ test_iis_site_name }}" - state: absent - protocol: "{{ item.protocol }}" - port: "{{ item.port }}" - with_items: - - {protocol: http, port: 80} - - {protocol: https, port: 443} - -- name: copy certreq file - win_copy: - content: |- - [NewRequest] - Subject = "CN={{ item.name }}" - KeyLength = 2048 - KeyAlgorithm = RSA - MachineKeySet = true - RequestType = Cert - dest: "{{ item.dest }}" - with_items: - - {name: test.com, dest: 'c:\windows\temp\certreq1.txt'} - - {name: test1.com, dest: 'c:\windows\temp\certreq2.txt'} - - {name: '*.test.com', dest: 'c:\windows\temp\certreqwc.txt'} - -- name: make sure response files are absent - win_file: - path: "{{ item }}" - state: absent - with_items: - - 'c:\windows\temp\certreqresp1.txt' - - 'c:\windows\temp\certreqresp2.txt' - - 'c:\windows\temp\certreqrespwc.txt' - -- name: create self signed cert from certreq - win_command: certreq -new -machine {{ item.req }} {{ item.resp }} - with_items: - - {req: 'c:\windows\temp\certreq1.txt', resp: 'c:\windows\temp\certreqresp1.txt'} - - {req: 'c:\windows\temp\certreq2.txt', resp: 'c:\windows\temp\certreqresp2.txt'} - - {req: 'c:\windows\temp\certreqwc.txt', resp: 'c:\windows\temp\certreqrespwc.txt'} - -- name: register certificate thumbprint1 - raw: '(gci Cert:\LocalMachine\my | ? {$_.subject -eq "CN=test.com"})[0].Thumbprint' - register: thumbprint1 - -- name: register certificate thumbprint2 - raw: '(gci Cert:\LocalMachine\my | ? {$_.subject -eq "CN=test1.com"})[0].Thumbprint' - register: thumbprint2 - -- name: register certificate thumbprint_wc - raw: '(gci Cert:\LocalMachine\my | ? {$_.subject -eq "CN=*.test.com"})[0].Thumbprint' - register: thumbprint_wc - -- debug: - var: thumbprint1.stdout - verbosity: 1 -- debug: - var: thumbprint2.stdout - verbosity: 1 -- debug: - var: thumbprint_wc.stdout - verbosity: 1 diff --git a/test/integration/targets/win_inet_proxy/aliases b/test/integration/targets/win_inet_proxy/aliases deleted file mode 100644 index 215e0b06920..00000000000 --- a/test/integration/targets/win_inet_proxy/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group4 diff --git a/test/integration/targets/win_inet_proxy/library/win_inet_proxy_info.ps1 b/test/integration/targets/win_inet_proxy/library/win_inet_proxy_info.ps1 deleted file mode 100644 index d52b11d3ad3..00000000000 --- a/test/integration/targets/win_inet_proxy/library/win_inet_proxy_info.ps1 +++ /dev/null @@ -1,275 +0,0 @@ -#!powershell - -# Copyright: (c) 2019, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.AddType - -$spec = @{ - options = @{ - connection = @{ type = "str" } - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$connection = $module.Params.connection - -$win_inet_invoke = @' -using Microsoft.Win32.SafeHandles; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; - -namespace Ansible.WinINetProxyInfo -{ - internal class NativeHelpers - { - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public class INTERNET_PER_CONN_OPTION_LISTW : IDisposable - { - public UInt32 dwSize; - public IntPtr pszConnection; - public UInt32 dwOptionCount; - public UInt32 dwOptionError; - public IntPtr pOptions; - - public INTERNET_PER_CONN_OPTION_LISTW() - { - dwSize = (UInt32)Marshal.SizeOf(this); - } - - public void Dispose() - { - if (pszConnection != IntPtr.Zero) - Marshal.FreeHGlobal(pszConnection); - if (pOptions != IntPtr.Zero) - Marshal.FreeHGlobal(pOptions); - GC.SuppressFinalize(this); - } - ~INTERNET_PER_CONN_OPTION_LISTW() { this.Dispose(); } - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public class INTERNET_PER_CONN_OPTIONW : IDisposable - { - public INTERNET_PER_CONN_OPTION dwOption; - public ValueUnion Value; - - [StructLayout(LayoutKind.Explicit)] - public class ValueUnion - { - [FieldOffset(0)] - public UInt32 dwValue; - - [FieldOffset(0)] - public IntPtr pszValue; - - [FieldOffset(0)] - public System.Runtime.InteropServices.ComTypes.FILETIME ftValue; - } - - public void Dispose() - { - // We can't just check if Value.pszValue is not IntPtr.Zero as the union means it could be set even - // when the value is a UInt32 or FILETIME. We check against a known string option type and only free - // the value in those cases. - List stringOptions = new List - { - { INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_AUTOCONFIG_URL }, - { INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_PROXY_BYPASS }, - { INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_PROXY_SERVER } - }; - if (Value != null && Value.pszValue != IntPtr.Zero && stringOptions.Contains(dwOption)) - Marshal.FreeHGlobal(Value.pszValue); - GC.SuppressFinalize(this); - } - ~INTERNET_PER_CONN_OPTIONW() { this.Dispose(); } - } - - public enum INTERNET_OPTION : uint - { - INTERNET_OPTION_PER_CONNECTION_OPTION = 75, - } - - public enum INTERNET_PER_CONN_OPTION : uint - { - INTERNET_PER_CONN_FLAGS = 1, - INTERNET_PER_CONN_PROXY_SERVER = 2, - INTERNET_PER_CONN_PROXY_BYPASS = 3, - INTERNET_PER_CONN_AUTOCONFIG_URL = 4, - INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5, - INTERNET_PER_CONN_FLAGS_UI = 10, // IE8+ - Included with Windows 7 and Server 2008 R2 - } - - [Flags] - public enum PER_CONN_FLAGS : uint - { - PROXY_TYPE_DIRECT = 0x00000001, - PROXY_TYPE_PROXY = 0x00000002, - PROXY_TYPE_AUTO_PROXY_URL = 0x00000004, - PROXY_TYPE_AUTO_DETECT = 0x00000008, - } - } - - internal class NativeMethods - { - [DllImport("Wininet.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool InternetQueryOptionW( - IntPtr hInternet, - NativeHelpers.INTERNET_OPTION dwOption, - SafeMemoryBuffer lpBuffer, - ref UInt32 lpdwBufferLength); - } - - internal class SafeMemoryBuffer : SafeHandleZeroOrMinusOneIsInvalid - { - public SafeMemoryBuffer() : base(true) { } - public SafeMemoryBuffer(int cb) : base(true) - { - base.SetHandle(Marshal.AllocHGlobal(cb)); - } - public SafeMemoryBuffer(IntPtr handle) : base(true) - { - base.SetHandle(handle); - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected override bool ReleaseHandle() - { - Marshal.FreeHGlobal(handle); - return true; - } - } - - public class WinINetProxy - { - private string Connection; - - public string AutoConfigUrl; - public bool AutoDetect; - public string Proxy; - public string ProxyBypass; - - public WinINetProxy(string connection) - { - Connection = connection; - Refresh(); - } - - public void Refresh() - { - using (var connFlags = CreateConnOption(NativeHelpers.INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_FLAGS_UI)) - using (var autoConfigUrl = CreateConnOption(NativeHelpers.INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_AUTOCONFIG_URL)) - using (var server = CreateConnOption(NativeHelpers.INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_PROXY_SERVER)) - using (var bypass = CreateConnOption(NativeHelpers.INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_PROXY_BYPASS)) - { - NativeHelpers.INTERNET_PER_CONN_OPTIONW[] options = new NativeHelpers.INTERNET_PER_CONN_OPTIONW[] - { - connFlags, autoConfigUrl, server, bypass - }; - - try - { - QueryOption(options, Connection); - } - catch (Win32Exception e) - { - if (e.NativeErrorCode == 87) // ERROR_INVALID_PARAMETER - { - // INTERNET_PER_CONN_FLAGS_UI only works for IE8+, try the fallback in case we are still working - // with an ancient version. - connFlags.dwOption = NativeHelpers.INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_FLAGS; - QueryOption(options, Connection); - } - else - throw; - } - - NativeHelpers.PER_CONN_FLAGS flags = (NativeHelpers.PER_CONN_FLAGS)connFlags.Value.dwValue; - - AutoConfigUrl = flags.HasFlag(NativeHelpers.PER_CONN_FLAGS.PROXY_TYPE_AUTO_PROXY_URL) - ? Marshal.PtrToStringUni(autoConfigUrl.Value.pszValue) : null; - AutoDetect = flags.HasFlag(NativeHelpers.PER_CONN_FLAGS.PROXY_TYPE_AUTO_DETECT); - if (flags.HasFlag(NativeHelpers.PER_CONN_FLAGS.PROXY_TYPE_PROXY)) - { - Proxy = Marshal.PtrToStringUni(server.Value.pszValue); - ProxyBypass = Marshal.PtrToStringUni(bypass.Value.pszValue); - } - else - { - Proxy = null; - ProxyBypass = null; - } - } - } - - internal static NativeHelpers.INTERNET_PER_CONN_OPTIONW CreateConnOption(NativeHelpers.INTERNET_PER_CONN_OPTION option) - { - return new NativeHelpers.INTERNET_PER_CONN_OPTIONW - { - dwOption = option, - Value = new NativeHelpers.INTERNET_PER_CONN_OPTIONW.ValueUnion(), - }; - } - - internal static void QueryOption(NativeHelpers.INTERNET_PER_CONN_OPTIONW[] options, string connection = null) - { - using (NativeHelpers.INTERNET_PER_CONN_OPTION_LISTW optionList = new NativeHelpers.INTERNET_PER_CONN_OPTION_LISTW()) - using (SafeMemoryBuffer optionListPtr = MarshalOptionList(optionList, options, connection)) - { - UInt32 bufferSize = optionList.dwSize; - if (!NativeMethods.InternetQueryOptionW( - IntPtr.Zero, - NativeHelpers.INTERNET_OPTION.INTERNET_OPTION_PER_CONNECTION_OPTION, - optionListPtr, - ref bufferSize)) - { - throw new Win32Exception(); - } - - for (int i = 0; i < options.Length; i++) - { - IntPtr opt = IntPtr.Add(optionList.pOptions, i * Marshal.SizeOf(typeof(NativeHelpers.INTERNET_PER_CONN_OPTIONW))); - NativeHelpers.INTERNET_PER_CONN_OPTIONW option = (NativeHelpers.INTERNET_PER_CONN_OPTIONW)Marshal.PtrToStructure(opt, - typeof(NativeHelpers.INTERNET_PER_CONN_OPTIONW)); - options[i].Value = option.Value; - option.Value = null; // Stops the GC from freeing the same memory twice - } - } - } - - internal static SafeMemoryBuffer MarshalOptionList(NativeHelpers.INTERNET_PER_CONN_OPTION_LISTW optionList, - NativeHelpers.INTERNET_PER_CONN_OPTIONW[] options, string connection) - { - optionList.pszConnection = Marshal.StringToHGlobalUni(connection); - optionList.dwOptionCount = (UInt32)options.Length; - - int optionSize = Marshal.SizeOf(typeof(NativeHelpers.INTERNET_PER_CONN_OPTIONW)); - optionList.pOptions = Marshal.AllocHGlobal(optionSize * options.Length); - for (int i = 0; i < options.Length; i++) - { - IntPtr option = IntPtr.Add(optionList.pOptions, i * optionSize); - Marshal.StructureToPtr(options[i], option, false); - } - - SafeMemoryBuffer optionListPtr = new SafeMemoryBuffer((int)optionList.dwSize); - Marshal.StructureToPtr(optionList, optionListPtr.DangerousGetHandle(), false); - return optionListPtr; - } - } -} -'@ -Add-CSharpType -References $win_inet_invoke -AnsibleModule $module - -$proxy = New-Object -TypeName Ansible.WinINetProxyInfo.WinINetProxy -ArgumentList @(,$connection) -$module.Result.auto_config_url = $proxy.AutoConfigUrl -$module.Result.auto_detect = $proxy.AutoDetect -$module.Result.proxy = $proxy.Proxy -$module.Result.bypass = $proxy.ProxyBypass - -$module.ExitJson() diff --git a/test/integration/targets/win_inet_proxy/library/win_phonebook_entry.ps1 b/test/integration/targets/win_inet_proxy/library/win_phonebook_entry.ps1 deleted file mode 100644 index 1746921f6d7..00000000000 --- a/test/integration/targets/win_inet_proxy/library/win_phonebook_entry.ps1 +++ /dev/null @@ -1,521 +0,0 @@ -#!powershell - -# Copyright: (c) 2019, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.AddType - -# This is a very basic skeleton of a possible Windows module for managing RAS connections. It is mostly barebones -# to enable testing for win_inet_proxy but I've done a bit of extra work in the PInvoke space to possible expand -# sometime in the future. - -$spec = @{ - options = @{ - device_type = @{ - type = "str" - choices = @("atm", "framerelay", "generic", "rda", "isdn", "modem", "pad", - "parallel", "pppoe", "vpn", "serial", "sonet", "sw56", "x25") - } - device_name = @{ type = "str" } - framing_protocol = @{ type = "str"; choices = @("ppp", "ras", "slip") } - name = @{ type = "str"; required = $true } - options = @{ type = "list" } - state = @{ type = "str"; choices = @("absent", "present"); default = "present" } - type = @{ type = "str"; choices = @("broadband", "direct", "phone", "vpn")} - } - required_if = @( - ,@("state", "present", @("type", "device_name", "device_type", "framing_protocol")) - ) - supports_check_mode = $false -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$device_type = $module.Params.device_type -$device_name = $module.Params.device_name -$framing_protocol = $module.Params.framing_protocol -$name = $module.Params.name -$options = $module.Params.options -$state = $module.Params.state -$type = $module.Params.type - -$module.Result.guid = [System.Guid]::Empty - -$win_ras_invoke = @' -using System; -using System.Runtime.InteropServices; - -namespace Ansible.WinPhonebookEntry -{ - public class NativeHelpers - { - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public class RASENTRYW - { - public UInt32 dwSize; - public RasEntryOptions dwfOptions; - public UInt32 dwCountryId; - public UInt32 dwCountryCode; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)] public string szAreaCode; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 129)] public string szLocalPhoneNumber; - public UInt32 dwAlternateOffset; - public RASIPADDR ipaddr; - public RASIPADDR ipaddrDns; - public RASIPADDR ipaddrDnsAlt; - public RASIPADDR ipaddrWins; - public RASIPADDR ipaddrWinsAlt; - public UInt32 dwFrameSize; - public RasNetProtocols dwfNetProtocols; - public RasFramingProtocol dwFramingProtocol; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szScript; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szAutodialDll; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szAutodialFunc; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)] public string szDeviceType; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 129)] public string szDeviceName; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)] public string szX25PadType; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 201)] public string szX25Address; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 201)] public string szX25Facilities; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 201)] public string szX25UserData; - public UInt32 dwChannels; - public UInt32 dwReserved1; - public UInt32 dwReserved2; - public UInt32 dwSubEntries; - public RasDialMode dwDialMode; - public UInt32 dwDialExtraPercent; - public UInt32 dwDialExtraSampleSeconds; - public UInt32 dwHangUpExtraPercent; - public UInt32 dwHangUpExtraSampleSeconds; - public UInt32 dwIdleDisconnectSeconds; - public RasEntryTypes dwType; - public RasEntryEncryption dwEntryptionType; - public UInt32 dwCustomAuthKey; - public Guid guidId; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szCustomDialDll; - public RasVpnStrategy dwVpnStrategy; - public RasEntryOptions2 dwfOptions2; - public UInt32 dwfOptions3; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string szDnsSuffix; - public UInt32 dwTcpWindowSize; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szPrerequisitePbk; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 257)] public string szPrerequisiteEntry; - public UInt32 dwRedialCount; - public UInt32 dwRedialPause; - public RASIPV6ADDR ipv6addrDns; - public RASIPV6ADDR ipv6addrDnsAlt; - public UInt32 dwIPv4InterfaceMatrix; - public UInt32 dwIPv6InterfaceMatrix; - // Server 2008 R2 / Windows 7+ - // We cannot include these fields when running in Server 2008 as it will break the SizeOf calc of the struct -#if !LONGHORN - public RASIPV6ADDR ipv6addr; - public UInt32 dwIPv6PrefixLength; - public UInt32 dwNetworkOutageTime; -#endif - - public RASENTRYW() - { - this.dwSize = (UInt32)Marshal.SizeOf(this); - } - } - - [StructLayout(LayoutKind.Sequential)] - public struct RASIPADDR - { - public byte a; - public byte b; - public byte c; - public byte d; - } - - [StructLayout(LayoutKind.Sequential)] - public struct RASIPV6ADDR - { - byte a; - byte b; - byte c; - byte d; - byte e; - byte f; - byte g; - byte h; - byte i; - byte j; - byte k; - byte l; - byte m; - byte n; - byte o; - byte p; - } - - public enum RasDialMode : uint - { - RASEDM_DialAll = 1, - RASEDM_DialAsNeeded = 2, - } - - public enum RasEntryEncryption : uint - { - ET_None = 0, - ET_Require = 1, - ET_RequireMax = 2, - ET_Optional = 3 - } - - [Flags] - public enum RasEntryOptions : uint - { - RASEO_UseCountryAndAreaCodes = 0x00000001, - RASEO_SpecificIpAddr = 0x00000002, - RASEO_SpecificNameServers = 0x00000004, - RASEO_IpHeaderCompression = 0x00000008, - RASEO_RemoteDefaultGateway = 0x00000010, - RASEO_DisableLcpExtensions = 0x00000020, - RASEO_TerminalBeforeDial = 0x00000040, - RASEO_TerminalAfterDial = 0x00000080, - RASEO_ModemLights = 0x00000100, - RASEO_SwCompression = 0x00000200, - RASEO_RequireEncrptedPw = 0x00000400, - RASEO_RequireMsEncrptedPw = 0x00000800, - RASEO_RequireDataEncrption = 0x00001000, - RASEO_NetworkLogon = 0x00002000, - RASEO_UseLogonCredentials = 0x00004000, - RASEO_PromoteAlternates = 0x00008000, - RASEO_SecureLocalFiles = 0x00010000, - RASEO_RequireEAP = 0x00020000, - RASEO_RequirePAP = 0x00040000, - RASEO_RequireSPAP = 0x00080000, - RASEO_Custom = 0x00100000, - RASEO_PreviewPhoneNumber = 0x00200000, - RASEO_SharedPhoneNumbers = 0x00800000, - RASEO_PreviewUserPw = 0x01000000, - RASEO_PreviewDomain = 0x02000000, - RASEO_ShowDialingProgress = 0x04000000, - RASEO_RequireCHAP = 0x08000000, - RASEO_RequireMsCHAP = 0x10000000, - RASEO_RequireMsCHAP2 = 0x20000000, - RASEO_RequireW95MSCHAP = 0x40000000, - RASEO_CustomScript = 0x80000000, - } - - [Flags] - public enum RasEntryOptions2 : uint - { - RASEO2_None = 0x00000000, - RASEO2_SecureFileAndPrint = 0x00000001, - RASEO2_SecureClientForMSNet = 0x00000002, - RASEO2_DontNegotiateMultilink = 0x00000004, - RASEO2_DontUseRasCredentials = 0x00000008, - RASEO2_UsePreSharedKey = 0x00000010, - RASEO2_Internet = 0x00000020, - RASEO2_DisableNbtOverIP = 0x00000040, - RASEO2_UseGlobalDeviceSettings = 0x00000080, - RASEO2_ReconnectIfDropped = 0x00000100, - RASEO2_SharePhoneNumbers = 0x00000200, - RASEO2_SecureRoutingCompartment = 0x00000400, - RASEO2_UseTypicalSettings = 0x00000800, - RASEO2_IPv6SpecificNameServers = 0x00001000, - RASEO2_IPv6RemoteDefaultGateway = 0x00002000, - RASEO2_RegisterIpWithDNS = 0x00004000, - RASEO2_UseDNSSuffixForRegistration = 0x00008000, - RASEO2_IPv4ExplicitMetric = 0x00010000, - RASEO2_IPv6ExplicitMetric = 0x00020000, - RASEO2_DisableIKENameEkuCheck = 0x00040000, - // Server 2008 R2 / Windows 7+ - RASEO2_DisableClassBasedStaticRoute = 0x00800000, - RASEO2_SpecificIPv6Addr = 0x01000000, - RASEO2_DisableMobility = 0x02000000, - RASEO2_RequireMachineCertificates = 0x04000000, - // Server 2012 / Windows 8+ - RASEO2_UsePreSharedKeyForIkev2Initiator = 0x00800000, - RASEO2_UsePreSharedKeyForIkev2Responder = 0x01000000, - RASEO2_CacheCredentials = 0x02000000, - // Server 2012 R2 / Windows 8.1+ - RASEO2_AutoTriggerCapable = 0x04000000, - RASEO2_IsThirdPartyProfile = 0x08000000, - RASEO2_AuthTypeIsOtp = 0x10000000, - // Server 2016 / Windows 10+ - RASEO2_IsAlwaysOn = 0x20000000, - RASEO2_IsPrivateNetwork = 0x40000000, - } - - public enum RasEntryTypes : uint - { - RASET_Phone = 1, - RASET_Vpn = 2, - RASET_Direct = 3, - RASET_Internet = 4, - RASET_Broadband = 5, - } - - public enum RasFramingProtocol : uint - { - RASFP_Ppp = 0x00000001, - RASFP_Slip = 0x00000002, - RASFP_Ras = 0x00000004 - } - - [Flags] - public enum RasNetProtocols : uint - { - RASNP_NetBEUI = 0x00000001, - RASNP_Ipx = 0x00000002, - RASNP_Ip = 0x00000004, - RASNP_Ipv6 = 0x00000008 - } - - public enum RasVpnStrategy : uint - { - VS_Default = 0, - VS_PptpOnly = 1, - VS_PptpFirst = 2, - VS_L2tpOnly = 3, - VS_L2tpFirst = 4, - VS_SstpOnly = 5, - VS_SstpFirst = 6, - VS_Ikev2Only = 7, - VS_Ikev2First = 8, - VS_GREOnly = 9, - VS_PptpSstp = 12, - VS_L2tpSstp = 13, - VS_Ikev2Sstp = 14, - } - } - - internal class NativeMethods - { - [DllImport("Rasapi32.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 RasDeleteEntryW( - string lpszPhonebook, - string lpszEntry); - - [DllImport("Rasapi32.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 RasGetEntryPropertiesW( - string lpszPhonebook, - string lpszEntry, - [In, Out] NativeHelpers.RASENTRYW lpRasEntry, - ref UInt32 dwEntryInfoSize, - IntPtr lpbDeviceInfo, - ref UInt32 dwDeviceInfoSize); - - [DllImport("Rasapi32.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 RasSetEntryPropertiesW( - string lpszPhonebook, - string lpszEntry, - NativeHelpers.RASENTRYW lpRasEntry, - UInt32 dwEntryInfoSize, - IntPtr lpbDeviceInfo, - UInt32 dwDeviceInfoSize); - - [DllImport("Rasapi32.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 RasValidateEntryNameW( - string lpszPhonebook, - string lpszEntry); - } - - public class Phonebook - { - public static void CreateEntry(string entry, NativeHelpers.RASENTRYW details) - { - UInt32 res = NativeMethods.RasSetEntryPropertiesW(null, entry, details, - details.dwSize, IntPtr.Zero, 0); - - if (res != 0) - throw new Exception(String.Format("RasSetEntryPropertiesW({0}) failed {1}", entry, res)); - } - - public static void DeleteEntry(string entry) - { - UInt32 res = NativeMethods.RasDeleteEntryW(null, entry); - if (res != 0) - throw new Exception(String.Format("RasDeleteEntryW({0}) failed {1}", entry, res)); - } - - public static NativeHelpers.RASENTRYW GetEntry(string entry) - { - NativeHelpers.RASENTRYW details = new NativeHelpers.RASENTRYW(); - UInt32 dwEntryInfoSize = details.dwSize; - UInt32 dwDeviceInfoSize = 0; - - UInt32 res = NativeMethods.RasGetEntryPropertiesW(null, entry, details, ref dwEntryInfoSize, - IntPtr.Zero, ref dwDeviceInfoSize); - - if (res != 0) - throw new Exception(String.Format("RasGetEntryPropertiesW({0}) failed {1}", entry, res)); - - return details; - } - - public static bool IsValidEntry(string entry) - { - // 183 == ENTRY_ALREADY_EXISTS - return NativeMethods.RasValidateEntryNameW(null, entry) == 183; - } - } -} -'@ - -$add_type_params = @{ - Reference = $win_ras_invoke - AnsibleModule = $module -} -# We need to set a custom compile option when running on Server 2008 due to the change in the RASENTRYW structure -$os_version = [Version](Get-Item -LiteralPath $env:SystemRoot\System32\kernel32.dll).VersionInfo.ProductVersion -if ($os_version -lt [Version]"6.1") { - $add_type_params.CompileSymbols = @("LONGHORN") -} -Add-CSharpType @add_type_params - -$exists = [Ansible.WinPhonebookEntry.Phonebook]::IsValidEntry($name) -if ($exists) { - $entry = [Ansible.WinPhonebookEntry.Phonebook]::GetEntry($name) - $module.Result.guid = $entry.guidId -} - -if ($state -eq "present") { - # Convert the input values to enum values - $expected_type = switch ($type) { - "broadband" { [Ansible.WinPhonebookEntry.NativeHelpers+RasEntryTypes]::RASET_Broadband } - "direct" { [Ansible.WinPhonebookEntry.NativeHelpers+RasEntryTypes]::RASET_Direct } - "phone" { [Ansible.WinPhonebookEntry.NativeHelpers+RasEntryTypes]::RASET_Phone } - "vpn" { [Ansible.WinPhonebookEntry.NativeHelpers+RasEntryTypes]::RASET_Vpn } - } - - $expected_framing_protocol = switch ($framing_protocol) { - "ppp" { [Ansible.WinPhonebookEntry.NativeHelpers+RasFramingProtocol]::RASFP_Ppp } - "ras" { [Ansible.WinPhonebookEntry.NativeHelpers+RasFramingProtocol]::RASFP_Ras } - "slip" { [Ansible.WinPhonebookEntry.NativeHelpers+RasFramingProtocol]::RASFP_Slip } - } - - $expected_options1 = [System.Collections.Generic.List`1[String]]@() - $expected_options2 = [System.Collections.Generic.List`1[String]]@() - $invalid_options = [System.Collections.Generic.List`1[String]]@() - foreach ($option in $options) { - # See https://msdn.microsoft.com/en-us/25c46850-4fb7-47a9-9645-139f0e869559 for more info on the options - # TODO: some of these options are set to indicate entries in RASENTRYW, we should automatically add them - # based on the input values. - switch ($option) { - # dwfOptions - "use_country_and_area_codes" { $expected_options1.Add("RASEO_UseCountryAndAreaCode") } - "specific_ip_addr" { $expected_options1.Add("RASEO_SpecificIpAddr") } - "specific_name_servers" { $expected_options1.Add("RASEO_SpecificNameServers") } - "ip_header_compression" { $expected_options1.Add("RASEO_IpHeaderCompression") } - "remote_default_gateway" { $expected_options1.Add("RASEO_RemoteDefaultGateway") } - "disable_lcp_extensions" { $expected_options1.Add("RASEO_DisableLcpExtensions") } - "terminal_before_dial" { $expected_options1.Add("RASEO_TerminalBeforeDial") } - "terminal_after_dial" { $expected_options1.Add("RASEO_TerminalAfterDial") } - "modem_lights" { $expected_options1.Add("RASEO_ModemLights") } - "sw_compression" { $expected_options1.Add("RASEO_SwCompression") } - "require_encrypted_password" { $expected_options1.Add("RASEO_RequireEncrptedPw") } - "require_ms_encrypted_password" { $expected_options1.Add("RASEO_RequireMsEncrptedPw") } - "require_data_encryption" { $expected_options1.Add("RASEO_RequireDataEncrption") } - "network_logon" { $expected_options1.Add("RASEO_NetworkLogon") } - "use_logon_credentials" { $expected_options1.Add("RASEO_UseLogonCredentials") } - "promote_alternates" { $expected_options1.Add("RASEO_PromoteAlternates") } - "secure_local_files" { $expected_options1.Add("RASEO_SecureLocalFiles") } - "require_eap" { $expected_options1.Add("RASEO_RequireEAP") } - "require_pap" { $expected_options1.Add("RASEO_RequirePAP") } - "require_spap" { $expected_options1.Add("RASEO_RequireSPAP") } - "custom" { $expected_options1.Add("RASEO_Custom") } - "preview_phone_number" { $expected_options1.Add("RASEO_PreviewPhoneNumber") } - "shared_phone_numbers" { $expected_options1.Add("RASEO_SharedPhoneNumbers") } - "preview_user_password" { $expected_options1.Add("RASEO_PreviewUserPw") } - "preview_domain" { $expected_options1.Add("RASEO_PreviewDomain") } - "show_dialing_progress" { $expected_options1.Add("RASEO_ShowDialingProgress") } - "require_chap" { $expected_options1.Add("RASEO_RequireCHAP") } - "require_ms_chap" { $expected_options1.Add("RASEO_RequireMsCHAP") } - "require_ms_chap2" { $expected_options1.Add("RASEO_RequireMsCHAP2") } - "require_w95_ms_chap" { $expected_options1.Add("RASEO_RequireW95MSCHAP") } - "custom_script" { $expected_options1.Add("RASEO_CustomScript") } - # dwfOptions2 - "secure_file_and_print" { $expected_options2.Add("RASEO2_SecureFileAndPrint") } - "secure_client_for_ms_net" { $expected_options2.Add("RASEO2_SecureClientForMSNet") } - "dont_negotiate_multilink" { $expected_options2.Add("RASEO2_DontNegotiateMultilink") } - "dont_use_ras_credential" { $expected_options2.Add("RASEO2_DontUseRasCredentials") } - "use_pre_shared_key" { $expected_options2.Add("RASEO2_UsePreSharedKey") } - "internet" { $expected_options2.Add("RASEO2_Internet") } - "disable_nbt_over_ip" { $expected_options2.Add("RASEO2_DisableNbtOverIP") } - "use_global_device_settings" { $expected_options2.Add("RASEO2_UseGlobalDeviceSettings") } - "reconnect_if_dropped" { $expected_options2.Add("RASEO2_ReconnectIfDropped") } - "share_phone_numbers" { $expected_options2.Add("RASEO2_SharePhoneNumbers") } - "secure_routing_compartment" { $expected_options2.Add("RASEO2_SecureRoutingCompartment") } - "use_typical_settings" { $expected_options2.Add("RASEO2_UseTypicalSettings") } - "ipv6_specific_name_servers" { $expected_options2.Add("RASEO2_IPv6SpecificNameServers") } - "ipv6_remote_default_gateway" { $expected_options2.Add("RASEO2_IPv6RemoteDefaultGateway") } - "register_ip_with_dns" { $expected_options2.Add("RASEO2_RegisterIpWithDNS") } - "use_dns_suffix_for_registration" { $expected_options2.Add("RASEO2_UseDNSSuffixForRegistration") } - "ipv4_explicit_metric" { $expected_options2.Add("RASEO2_IPv4ExplicitMetric") } - "ipv6_explicit_metric" { $expected_options2.Add("RASEO2_IPv6ExplicitMetric") } - "disable_ike_name_eku_check" { $expected_options2.Add("RASEO2_DisableIKENameEkuCheck") } - # TODO: Version check for the below, OS Version >= 6.1 - "disable_class_based_static_route" { $expected_options2.Add("RASEO2_DisableClassBasedStaticRoute") } - "specific_ipv6_addr" { $expected_options2.Add("RASEO2_SpecificIPv6Addr") } - "disable_mobility" { $expected_options2.Add("RASEO2_DisableMobility") } - "require_machine_certificates" { $expected_options2.Add("RASEO2_RequireMachineCertificates") } - # TODO: Version check for the below, OS Version >= 6.2 - "use_pre_shared_key_for_ikev2_initiator" { $expected_options2.Add("RASEO2_UsePreSharedKeyForIkev2Initiator") } - "use_pre_shared_key_for_ikev2_responder" { $expected_options2.Add("RASEO2_UsePreSharedKeyForIkev2Responder") } - "cache_credentials" { $expected_options2.Add("RASEO2_CacheCredentials") } - # TODO: Version check for the below, OS Version >= 6.3 - "auto_trigger_capable" { $expected_options2.Add("RASEO2_AutoTriggerCapable") } - "is_third_party_profile" { $expected_options2.Add("RASEO2_IsThirdPartyProfile") } - "auth_type_is_otp" { $expected_options2.Add("RASEO2_AuthTypeIsOtp") } - # TODO: Version check for the below, OS Version >= 10.0 - "is_always_on" { $expected_options2.Add("RASEO2_IsAlwaysOn") } - "is_private_network" { $expected_options2.Add("RASEO2_IsPrivateNetwork") } - default { $invalid_options.Add($option) } - } - } - if ($invalid_options.Count -gt 0) { - $module.FailJson("Encountered invalid options: $($invalid_options -join ", ")") - } - $expected_options1 = [Ansible.WinPhonebookEntry.NativeHelpers+RasEntryOptions]($expected_options1 -join ", ") - $expected_options2 = [Ansible.WinPhonebookEntry.NativeHelpers+RasEntryOptions2]($expected_options2 -join ", ") - - $property_map = @{ - szDeviceName = $device_name - szDeviceType = $device_type - dwFramingProtocol = $expected_framing_protocol - dwfOptions = $expected_options1 - dwfOptions2 = $expected_options2 - dwType = $expected_type - } - - if (-not $exists) { - $entry = New-Object -TypeName Ansible.WinPhonebookEntry.NativeHelpers+RASENTRYW - foreach ($kvp in $property_map.GetEnumerator()) { - $entry."$($kvp.Key)" = $kvp.Value - } - - [Ansible.WinPhonebookEntry.Phonebook]::CreateEntry($name, $entry) - $module.Result.changed = $true - - # Once created we then get the entry object again to retrieve the unique GUID ID to return - $entry = [Ansible.WinPhonebookEntry.Phonebook]::GetEntry($name) - $module.Result.guid = $entry.guidId - } else { - $entry = [Ansible.WinPhonebookEntry.Phonebook]::GetEntry($name) - $changed = $false - foreach ($kvp in $property_map.GetEnumerator()) { - $key = $kvp.Key - $actual_value = $entry.$key - if ($actual_value -ne $kvp.Value) { - $entry.$key = $kvp.Value - $changed = $true - } - } - - if ($changed) { - [Ansible.WinPhonebookEntry.Phonebook]::CreateEntry($name, $entry) - $module.Result.changed = $true - } - } -} else { - if ($exists) { - [Ansible.WinPhonebookEntry.Phonebook]::DeleteEntry($name) - $module.Result.changed = $true - } -} - -$module.ExitJson() diff --git a/test/integration/targets/win_inet_proxy/tasks/main.yml b/test/integration/targets/win_inet_proxy/tasks/main.yml deleted file mode 100644 index f92a60eab57..00000000000 --- a/test/integration/targets/win_inet_proxy/tasks/main.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -- name: make sure we start the tests with the defaults - win_inet_proxy: - -- block: - - name: run tests - include_tasks: tests.yml - - always: - - name: reset proxy back to defaults - win_inet_proxy: - - - name: remove phonebook entry - win_phonebook_entry: - name: Ansible Test Dialup - state: absent diff --git a/test/integration/targets/win_inet_proxy/tasks/tests.yml b/test/integration/targets/win_inet_proxy/tasks/tests.yml deleted file mode 100644 index 47ddfbe2e80..00000000000 --- a/test/integration/targets/win_inet_proxy/tasks/tests.yml +++ /dev/null @@ -1,308 +0,0 @@ ---- -- name: ensure we fail when proxy is not set with bypass - win_inet_proxy: - bypass: abc - register: fail_bypass - failed_when: 'fail_bypass.msg != "missing parameter(s) required by ''bypass'': proxy"' - -- name: ensure we fail if an invalid protocol is specified - win_inet_proxy: - proxy: - fail1: fail - fail2: fail - register: fail_proxy - failed_when: 'fail_proxy.msg != "Invalid keys found in proxy: fail1, fail2. Valid keys are http, https, ftp, socks."' - -- name: ensure we fail if invalid value is set - win_inet_proxy: - proxy: fake=proxy - register: fail_invalid - failed_when: fail_invalid.msg != "Unknown error when trying to set auto_config_url '', proxy 'fake=proxy', or bypass ''" - -- name: ensure we fail if an invalid connection is set - win_inet_proxy: - connection: Fake Connection - register: fail_connection - failed_when: fail_connection.msg != "The connection 'Fake Connection' does not exist." - -- name: check proxy is still set to Direct access - win_inet_proxy_info: - register: fail_invalid_actual - failed_when: fail_invalid_actual.proxy == 'fake=proxy' - -- name: disable auto detect (check) - win_inet_proxy: - auto_detect: no - register: disable_auto_detect_check - check_mode: yes - -- name: get result of disable auto detect (check) - win_inet_proxy_info: - register: disable_auto_detect_actual_check - -- name: assert disable auto detect (check) - assert: - that: - - disable_auto_detect_check is changed - - disable_auto_detect_actual_check.auto_detect - -- name: disable auto detect - win_inet_proxy: - auto_detect: no - register: disable_auto_detect - -- name: get result of disable auto detect - win_inet_proxy_info: - register: disable_auto_detect_actual - -- name: assert disable auto detect - assert: - that: - - disable_auto_detect is changed - - not disable_auto_detect_actual.auto_detect - -- name: disable auto detect (idempotent) - win_inet_proxy: - auto_detect: no - register: disable_auto_detect_again - -- name: assert disable auto detect (idempotent) - assert: - that: - - not disable_auto_detect_again is changed - -- name: set auto config url - win_inet_proxy: - auto_config_url: http://ansible.com/proxy.pac - register: set_auto_url - -- name: get result of set auto config url - win_inet_proxy_info: - register: set_auto_url_actual - -- name: assert set auto config url - assert: - that: - - set_auto_url is changed - - set_auto_url_actual.auto_detect - - set_auto_url_actual.auto_config_url == 'http://ansible.com/proxy.pac' - -- name: set auto config url (idempotent) - win_inet_proxy: - auto_config_url: http://ansible.com/proxy.pac - register: set_auto_url_again - -- name: set auto config url (idempotent) - assert: - that: - - not set_auto_url_again is changed - -- name: set a proxy using a string - win_inet_proxy: - proxy: proxyhost - register: proxy_str - -- name: get result of set a proxy using a string - win_inet_proxy_info: - register: proxy_str_actual - -- name: assert set a proxy using a string - assert: - that: - - proxy_str is changed - - proxy_str_actual.auto_detect - - proxy_str_actual.auto_config_url == None - - proxy_str_actual.proxy == 'proxyhost' - -- name: set a proxy using a string (idempotent) - win_inet_proxy: - proxy: proxyhost - register: proxy_str_again - -- name: assert set a proxy using a string (idempotent) - assert: - that: - - not proxy_str_again is changed - -- name: change a proxy and set bypass - win_inet_proxy: - proxy: proxyhost:8080 - bypass: - - abc - - def - - - register: change_proxy - -- name: get result of change a proxy and set bypass - win_inet_proxy_info: - register: change_proxy_actual - -- name: assert change a proxy and set bypass - assert: - that: - - change_proxy is changed - - change_proxy_actual.proxy == 'proxyhost:8080' - - change_proxy_actual.bypass == 'abc;def;' - -- name: change a proxy and set bypass (idempotent) - win_inet_proxy: - proxy: proxyhost:8080 - bypass: abc,def, - register: change_proxy_again - -- name: assert change a proxy and set bypass (idempotent) - assert: - that: - - not change_proxy_again is changed - -- name: change bypass list - win_inet_proxy: - proxy: proxyhost:8080 - bypass: - - abc - - <-loopback> - register: change_bypass - -- name: get reuslt of change bypass list - win_inet_proxy_info: - register: change_bypass_actual - -- name: assert change bypass list - assert: - that: - - change_bypass is changed - - change_bypass_actual.proxy == 'proxyhost:8080' - - change_bypass_actual.bypass == 'abc;<-loopback>' - -- name: remove proxy without options - win_inet_proxy: - register: remove_proxy - -- name: get result of remove proxy without options - win_inet_proxy_info: - register: remove_proxy_actual - -- name: assert remove proxy without options - assert: - that: - - remove_proxy is changed - - remove_proxy_actual.auto_detect == True - - remove_proxy_actual.auto_config_url == None - - remove_proxy_actual.proxy == None - - remove_proxy_actual.bypass == None - -- name: remove proxy without options (idempotent) - win_inet_proxy: - register: remove_proxy_again - -- name: assert remove proxy without options (idempotent) - assert: - that: - - not remove_proxy_again is changed - -- name: set proxy with dictionary - win_inet_proxy: - proxy: - http: proxy:8080 - https: proxy:8443 - ftp: proxy:821 - socks: proxy:888 - register: set_dict - -- name: get result of set proxy with dictionary - win_inet_proxy_info: - register: set_dict_actual - -- name: assert set proxy with dictionary - assert: - that: - - set_dict is changed - - set_dict_actual.proxy == 'http=proxy:8080;https=proxy:8443;ftp=proxy:821;socks=proxy:888' - -- name: set proxy protocol with str - win_inet_proxy: - proxy: http=proxy:8080;https=proxy:8443;ftp=proxy:821;socks=proxy:888 - register: set_str_protocol - -- name: assert set proxy protocol with str - assert: - that: - - not set_str_protocol is changed - -- name: remove proxy with empty string - win_inet_proxy: - proxy: '' - register: remove_empty_str - -- name: get result of remove proxy with empty string - win_inet_proxy_info: - register: remove_empty_str_actual - -- name: assert remove proxy with empty string - assert: - that: - - remove_empty_str is changed - - remove_empty_str_actual.proxy == None - -- name: create test phonebook entry - win_phonebook_entry: - name: Ansible Test Dialup - device_type: pppoe - device_name: WAN Miniport (PPPOE) - framing_protocol: ppp - options: - - remote_default_gateway - - require_pap - - internet - type: broadband - state: present - -- name: set proxy for specific connection - win_inet_proxy: - connection: Ansible Test Dialup - auto_detect: no - auto_config_url: proxy.com - proxy: proxyhost:8080 - bypass: proxyhost - register: set_connection - -- name: get result for set proxy for specific connection - win_inet_proxy_info: - connection: Ansible Test Dialup - register: set_connection_actual - -- name: get result for LAN connection proxy - win_inet_proxy_info: - register: set_connection_lan_actual - -- name: assert set proxy for specific connection - assert: - that: - - set_connection is changed - - set_connection_actual.auto_detect == False - - set_connection_actual.auto_config_url == 'proxy.com' - - set_connection_actual.proxy == 'proxyhost:8080' - - set_connection_actual.bypass == 'proxyhost' - - set_connection_lan_actual.auto_detect == True - - set_connection_lan_actual.auto_config_url == None - - set_connection_lan_actual.proxy == None - - set_connection_lan_actual.bypass == None - -- name: remove proxy for specific connection - win_inet_proxy: - connection: Ansible Test Dialup - register: remove_connection - -- name: get result of remove proxy for specific connection - win_inet_proxy_info: - connection: Ansible Test Dialup - register: remove_connection_actual - -- name: assert remove proxy for specific connection - assert: - that: - - remove_connection is changed - - remove_connection_actual.auto_detect == True - - remove_connection_actual.auto_config_url == None - - remove_connection_actual.proxy == None - - remove_connection_actual.bypass == None diff --git a/test/integration/targets/win_initialize_disk/aliases b/test/integration/targets/win_initialize_disk/aliases deleted file mode 100644 index 3fac36743f2..00000000000 --- a/test/integration/targets/win_initialize_disk/aliases +++ /dev/null @@ -1,3 +0,0 @@ -shippable/windows/group6 -skip/windows/2008 -skip/windows/2008-R2 diff --git a/test/integration/targets/win_initialize_disk/defaults/main.yml b/test/integration/targets/win_initialize_disk/defaults/main.yml deleted file mode 100644 index 9cb54a30cd7..00000000000 --- a/test/integration/targets/win_initialize_disk/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ -AnsibleVhdx: C:\win_initialize_disk_tests\AnsiblePart.vhdx diff --git a/test/integration/targets/win_initialize_disk/tasks/main.yml b/test/integration/targets/win_initialize_disk/tasks/main.yml deleted file mode 100644 index f31c751392d..00000000000 --- a/test/integration/targets/win_initialize_disk/tasks/main.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- name: Create the temp directory - win_file: - path: C:\win_initialize_disk_tests - state: directory - -- name: Copy VHDX scripts - win_template: - src: "{{ item.src }}" - dest: C:\win_initialize_disk_tests\{{ item.dest }} - loop: - - { src: vhdx_creation_script.j2, dest: vhdx_creation_script.txt } - - { src: vhdx_deletion_script.j2, dest: vhdx_deletion_script.txt } - -- name: Create VHD - win_command: diskpart.exe /s C:\win_initialize_disk_tests\vhdx_creation_script.txt - -- name: Run tests - block: - - include: tests.yml - always: - - name: Detach disk - win_command: diskpart.exe /s C:\win_initialize_disk_tests\vhdx_deletion_script.txt - - - name: Cleanup files - win_file: - path: C:\win_initialize_disk_tests - state: absent diff --git a/test/integration/targets/win_initialize_disk/tasks/tests.yml b/test/integration/targets/win_initialize_disk/tasks/tests.yml deleted file mode 100644 index 41defd60621..00000000000 --- a/test/integration/targets/win_initialize_disk/tasks/tests.yml +++ /dev/null @@ -1,104 +0,0 @@ ---- -- name: Initialize the disk with the default partition style (check mode) - win_initialize_disk: - disk_number: 1 - register: default_part_style_check - check_mode: yes - -- name: Get result of default initialization (check mode) - win_command: powershell.exe "if ( (Get-Disk -Number 1).PartitionStyle -eq 'RAW' ) {'true'} else {'false'}" - register: default_part_style_actual_check - -- name: assert default initialization (check mode) - assert: - that: - - default_part_style_check is changed - - default_part_style_actual_check.stdout == 'true\r\n' - -- name: Initialize the disk with the default partition style - win_initialize_disk: - disk_number: 1 - register: default_part_style - -- name: Get result of default initialization - win_command: powershell.exe "if ( (Get-Disk -Number 1).PartitionStyle -eq 'GPT' ) {'true'} else {'false'}" - register: default_part_style_actual - -- name: assert default initialization - assert: - that: - - default_part_style is changed - - default_part_style_actual.stdout == 'true\r\n' - -- name: Initialize the disk with the default partition style (idempotence) - win_initialize_disk: - disk_number: 1 - register: default_part_style_idempotence - -- name: Get result of default initialization (idempotence) - win_command: powershell.exe "if ( (Get-Disk -Number 1).PartitionStyle -eq 'GPT' ) {'true'} else {'false'}" - register: default_part_style_actual_idempotence - -- name: assert default initialization (idempotence) - assert: - that: - - not default_part_style_idempotence is changed - - default_part_style_actual_idempotence.stdout == 'true\r\n' - -- name: Partition style change without force fails - win_initialize_disk: - disk_number: 1 - style: mbr - register: change_part_style - ignore_errors: True - -- name: assert failed partition style change - assert: - that: - - change_part_style is failed - -- name: Partition style change with force is successful (check mode) - win_initialize_disk: - disk_number: 1 - style: mbr - force: yes - register: change_part_style_forced_check - check_mode: yes - -- name: Get result of forced initialization (check mode) - win_command: powershell.exe "if ( (Get-Disk -Number 1).PartitionStyle -eq 'GPT' ) {'true'} else {'false'}" - register: change_part_style_forced_actual_check - -- name: assert forced initialization (check mode) - assert: - that: - - change_part_style_forced_check is changed - - change_part_style_forced_actual_check.stdout == 'true\r\n' - -- name: Partition style change with force is successful - win_initialize_disk: - disk_number: 1 - style: mbr - force: yes - register: change_part_style_forced - -- name: Get result of forced initialization - win_command: powershell.exe "if ( (Get-Disk -Number 1).PartitionStyle -eq 'MBR' ) {'true'} else {'false'}" - register: change_part_style_forced_actual - -- name: assert forced initialization - assert: - that: - - change_part_style_forced is changed - - change_part_style_forced_actual.stdout == 'true\r\n' - -- name: Unknown disk number fails - win_initialize_disk: - disk_number: 3 - register: unknown_disk_number - ignore_errors: True - -- name: assert unknown disk number fails - assert: - that: - - unknown_disk_number is failed diff --git a/test/integration/targets/win_initialize_disk/templates/vhdx_creation_script.j2 b/test/integration/targets/win_initialize_disk/templates/vhdx_creation_script.j2 deleted file mode 100644 index 4089bf379e9..00000000000 --- a/test/integration/targets/win_initialize_disk/templates/vhdx_creation_script.j2 +++ /dev/null @@ -1,5 +0,0 @@ -create vdisk file="{{ AnsibleVhdx }}" maximum=2000 type=fixed - -select vdisk file="{{ AnsibleVhdx }}" - -attach vdisk diff --git a/test/integration/targets/win_initialize_disk/templates/vhdx_deletion_script.j2 b/test/integration/targets/win_initialize_disk/templates/vhdx_deletion_script.j2 deleted file mode 100644 index c2be9cd1446..00000000000 --- a/test/integration/targets/win_initialize_disk/templates/vhdx_deletion_script.j2 +++ /dev/null @@ -1,3 +0,0 @@ -select vdisk file="{{ AnsibleVhdx }}" - -detach vdisk diff --git a/test/integration/targets/win_lineinfile/aliases b/test/integration/targets/win_lineinfile/aliases deleted file mode 100644 index 219895f4bc9..00000000000 --- a/test/integration/targets/win_lineinfile/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group2 -skip/windows/2016 # Host takes a while to run and module isn't OS dependent diff --git a/test/integration/targets/win_lineinfile/files/test.txt b/test/integration/targets/win_lineinfile/files/test.txt deleted file mode 100644 index 8187db9f029..00000000000 --- a/test/integration/targets/win_lineinfile/files/test.txt +++ /dev/null @@ -1,5 +0,0 @@ -This is line 1 -This is line 2 -REF this is a line for backrefs REF -This is line 4 -This is line 5 diff --git a/test/integration/targets/win_lineinfile/files/test_linebreak.txt b/test/integration/targets/win_lineinfile/files/test_linebreak.txt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/test/integration/targets/win_lineinfile/files/test_quoting.txt b/test/integration/targets/win_lineinfile/files/test_quoting.txt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/test/integration/targets/win_lineinfile/files/testempty.txt b/test/integration/targets/win_lineinfile/files/testempty.txt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/test/integration/targets/win_lineinfile/files/testnoeof.txt b/test/integration/targets/win_lineinfile/files/testnoeof.txt deleted file mode 100644 index 152780b9ff0..00000000000 --- a/test/integration/targets/win_lineinfile/files/testnoeof.txt +++ /dev/null @@ -1,2 +0,0 @@ -This is line 1 -This is line 2 \ No newline at end of file diff --git a/test/integration/targets/win_lineinfile/meta/main.yml b/test/integration/targets/win_lineinfile/meta/main.yml deleted file mode 100644 index d328716dfa4..00000000000 --- a/test/integration/targets/win_lineinfile/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_win_tests diff --git a/test/integration/targets/win_lineinfile/tasks/main.yml b/test/integration/targets/win_lineinfile/tasks/main.yml deleted file mode 100644 index e5f047bec30..00000000000 --- a/test/integration/targets/win_lineinfile/tasks/main.yml +++ /dev/null @@ -1,708 +0,0 @@ -# Test code for the win_lineinfile module, adapted from the standard lineinfile module tests -# -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - - -- name: deploy the test file for lineinfile - win_copy: src=test.txt dest={{win_output_dir}}/test.txt - register: result - -- name: assert that the test file was deployed - assert: - that: - - "result.changed == true" - -- name: stat the test file - win_stat: path={{win_output_dir}}/test.txt - register: result - -- name: check win_stat file result - assert: - that: - - "result.stat.exists" - - "not result.stat.isdir" - - "result.stat.checksum == '5feac65e442c91f557fc90069ce6efc4d346ab51'" - - "result is not failed" - - "result is not changed" - - -- name: insert a line at the beginning of the file, and back it up - win_lineinfile: dest={{win_output_dir}}/test.txt state=present line="New line at the beginning" insertbefore="BOF" backup=yes - register: result - -- name: check backup_file - win_stat: - path: '{{ result.backup_file }}' - register: backup_file - -- name: assert that the line was inserted at the head of the file - assert: - that: - - result.changed == true - - result.msg == 'line added' - - backup_file.stat.exists == true - -- name: stat the backup file - win_stat: path={{result.backup}} - register: result - -- name: assert the backup file matches the previous hash - assert: - that: - - "result.stat.checksum == '5feac65e442c91f557fc90069ce6efc4d346ab51'" - -- name: stat the test after the insert at the head - win_stat: path={{win_output_dir}}/test.txt - register: result - -- name: assert test hash is what we expect for the file with the insert at the head - assert: - that: - - "result.stat.checksum == 'b526e2e044defc64dfb0fad2f56e105178f317d8'" - -- name: insert a line at the end of the file - win_lineinfile: dest={{win_output_dir}}/test.txt state=present line="New line at the end" insertafter="EOF" - register: result - -- name: assert that the line was inserted at the end of the file - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - -- name: stat the test after the insert at the end - win_stat: path={{win_output_dir}}/test.txt - register: result - -- name: assert test checksum matches after the insert at the end - assert: - that: - - "result.stat.checksum == 'dd5e207e28ce694ab18e41c2b16deb74fde93b14'" - -- name: insert a line after the first line - win_lineinfile: dest={{win_output_dir}}/test.txt state=present line="New line after line 1" insertafter="^This is line 1$" - register: result - -- name: assert that the line was inserted after the first line - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - -- name: stat the test after insert after the first line - win_stat: path={{win_output_dir}}/test.txt - register: result - -- name: assert test checksum matches after the insert after the first line - assert: - that: - - "result.stat.checksum == '604b17405f2088e6868af9680b7834087acdc8f4'" - -- name: insert a line before the last line - win_lineinfile: dest={{win_output_dir}}/test.txt state=present line="New line before line 5" insertbefore="^This is line 5$" - register: result - -- name: assert that the line was inserted before the last line - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - -- name: stat the test after the insert before the last line - win_stat: path={{win_output_dir}}/test.txt - register: result - -- name: assert test checksum matches after the insert before the last line - assert: - that: - - "result.stat.checksum == '8f5b30e8f01578043d782e5a68d4c327e75a6e34'" - -- name: replace a line with backrefs - win_lineinfile: dest={{win_output_dir}}/test.txt state=present line="This is line 3" backrefs=yes regexp="^(REF).*$" - register: result - -- name: assert that the line with backrefs was changed - assert: - that: - - "result.changed == true" - - "result.msg == 'line replaced'" - -- name: stat the test after the backref line was replaced - win_stat: path={{win_output_dir}}/test.txt - register: result - -- name: assert test checksum matches after backref line was replaced - assert: - that: - - "result.stat.checksum == 'ef6b02645908511a2cfd2df29d50dd008897c580'" - -- name: remove the middle line - win_lineinfile: dest={{win_output_dir}}/test.txt state=absent regexp="^This is line 3$" - register: result - -- name: assert that the line was removed - assert: - that: - - "result.changed == true" - - "result.msg == '1 line(s) removed'" - -- name: stat the test after the middle line was removed - win_stat: path={{win_output_dir}}/test.txt - register: result - -- name: assert test checksum matches after the middle line was removed - assert: - that: - - "result.stat.checksum == '11695efa472be5c31c736bc43e055f8ac90eabdf'" - -- name: run a validation script that succeeds - win_lineinfile: dest={{win_output_dir}}/test.txt state=absent regexp="^This is line 5$" validate="sort.exe %s" - register: result - -- name: assert that the file validated after removing a line - assert: - that: - - "result.changed == true" - - "result.msg == '1 line(s) removed'" - -- name: stat the test after the validation succeeded - win_stat: path={{win_output_dir}}/test.txt - register: result - -- name: assert test checksum matches after the validation succeeded - assert: - that: - - "result.stat.checksum == '39c38a30aa6ac6af9ec41f54c7ed7683f1249347'" - -- name: run a validation script that fails - win_lineinfile: dest={{win_output_dir}}/test.txt state=absent regexp="^This is line 1$" validate="sort.exe %s.foo" - register: result - ignore_errors: yes - -- name: assert that the validate failed - assert: - that: - - "result.failed == true" - -- name: stat the test after the validation failed - win_stat: path={{win_output_dir}}/test.txt - register: result - -- name: assert test checksum matches the previous after the validation failed - assert: - that: - - "result.stat.checksum == '39c38a30aa6ac6af9ec41f54c7ed7683f1249347'" - -- name: use create=yes - win_lineinfile: dest={{win_output_dir}}/new_test.txt create=yes insertbefore=BOF state=present line="This is a new file" - register: result - -- name: assert that the new file was created - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - -- name: validate that the newly created file exists - win_stat: path={{win_output_dir}}/new_test.txt - register: result - ignore_errors: yes - -- name: assert the newly created test checksum matches - assert: - that: - - "result.stat.checksum == '84faac1183841c57434693752fc3debc91b9195d'" - -# Test EOF in cases where file has no newline at EOF -- name: testnoeof deploy the file for lineinfile - win_copy: src=testnoeof.txt dest={{win_output_dir}}/testnoeof.txt - register: result - -- name: testnoeof insert a line at the end of the file - win_lineinfile: dest={{win_output_dir}}/testnoeof.txt state=present line="New line at the end" insertafter="EOF" - register: result - -- name: testempty assert that the line was inserted at the end of the file - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - -- name: testnoeof stat the no newline EOF test after the insert at the end - win_stat: path={{win_output_dir}}/testnoeof.txt - register: result - -- name: testnoeof assert test checksum matches after the insert at the end - assert: - that: - - "result.stat.checksum == '229852b09f7e9921fbcbb0ee0166ba78f7f7f261'" - -- name: add multiple lines at the end of the file - win_lineinfile: dest={{win_output_dir}}/test.txt state=present line="This is a line\r\nwith newline character" insertafter="EOF" - register: result - -- name: assert that the multiple lines was inserted - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - -- name: stat file after adding multiple lines - win_stat: path={{win_output_dir}}/test.txt - register: result - -- name: assert test checksum matches after inserting multiple lines - assert: - that: - - "result.stat.checksum == '1401413cd4eac732be66cd6aceddd334c4240f86'" - - - -# Test EOF with empty file to make sure no unnecessary newline is added -- name: testempty deploy the testempty file for lineinfile - win_copy: src=testempty.txt dest={{win_output_dir}}/testempty.txt - register: result - -- name: testempty insert a line at the end of the file - win_lineinfile: dest={{win_output_dir}}/testempty.txt state=present line="New line at the end" insertafter="EOF" - register: result - -- name: testempty assert that the line was inserted at the end of the file - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - -- name: testempty stat the test after the insert at the end - win_stat: path={{win_output_dir}}/testempty.txt - register: result - -- name: testempty assert test checksum matches after the insert at the end - assert: - that: - - "result.stat.checksum == 'd3d34f11edda51be7ca5dcb0757cf3e1257c0bfe'" - - - -- name: replace a line with backrefs included in the line - win_lineinfile: dest={{win_output_dir}}/test.txt state=present line="New $1 created with the backref" backrefs=yes regexp="^This is (line 4)$" - register: result - -- name: assert that the line with backrefs was changed - assert: - that: - - "result.changed == true" - - "result.msg == 'line replaced'" - -- name: stat the test after the backref line was replaced - win_stat: path={{win_output_dir}}/test.txt - register: result - -- name: assert test checksum matches after backref line was replaced - assert: - that: - - "result.stat.checksum == 'e6ff42e926dac2274c93dff0b8a323e07ae09149'" - -################################################################### -# issue 8535 - -- name: create a new file for testing quoting issues - win_copy: src=test_quoting.txt dest={{win_output_dir}}/test_quoting.txt - register: result - -- name: assert the new file was created - assert: - that: - - result.changed - -- name: use with_items to add code-like strings to the quoting txt file - win_lineinfile: > - dest={{win_output_dir}}/test_quoting.txt - line="{{ item }}" - insertbefore="BOF" - with_items: - - "'foo'" - - "dotenv.load();" - - "var dotenv = require('dotenv');" - register: result - -- name: assert the quote test file was modified correctly - assert: - that: - - result.results|length == 3 - - result.results[0].changed - - result.results[0].item == "'foo'" - - result.results[1].changed - - result.results[1].item == "dotenv.load();" - - result.results[2].changed - - result.results[2].item == "var dotenv = require('dotenv');" - -- name: stat the quote test file - win_stat: path={{win_output_dir}}/test_quoting.txt - register: result - -- name: assert test checksum matches for quote test file - assert: - that: - - "result.stat.checksum == 'f3bccdbdfa1d7176c497ef87d04957af40ab48d2'" - -- name: append a line into the quoted file with a single quote - win_lineinfile: dest={{win_output_dir}}/test_quoting.txt line="import g'" - register: result - -- name: assert that the quoted file was changed - assert: - that: - - result.changed - -- name: stat the quote test file - win_stat: path={{win_output_dir}}/test_quoting.txt - register: result - -- name: assert test checksum matches adding line with single quote - assert: - that: - - "result.stat.checksum == 'dabf4cbe471e1797d8dcfc773b6b638c524d5237'" - -- name: insert a line into the quoted file with many double quotation strings - win_lineinfile: dest={{win_output_dir}}/test_quoting.txt line='"quote" and "unquote"' - register: result - -- name: assert that the quoted file was changed - assert: - that: - - result.changed - -- name: stat the quote test file - win_stat: path={{win_output_dir}}/test_quoting.txt - register: result - -- name: assert test checksum matches quoted line added - assert: - that: - - "result.stat.checksum == '9dc1fc1ff19942e2936564102ad37134fa83b91d'" - - -# Windows vs. Unix line separator test cases - -- name: Create windows test file with initial line - win_lineinfile: dest={{win_output_dir}}/test_windows_sep.txt create=yes insertbefore=BOF state=present line="This is a new file" - register: result - -- name: assert that the new file was created - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - -- name: validate that the newly created file exists - win_stat: path={{win_output_dir}}/test_windows_sep.txt - register: result - -- name: assert the newly created file checksum matches - assert: - that: - - "result.stat.checksum == '84faac1183841c57434693752fc3debc91b9195d'" - -- name: Test appending to the file using the default (windows) line separator - win_lineinfile: dest={{win_output_dir}}/test_windows_sep.txt insertbefore=EOF state=present line="This is the last line" - register: result - -- name: assert that the new line was added - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - -- name: stat the file - win_stat: path={{win_output_dir}}/test_windows_sep.txt - register: result - -- name: assert the file checksum matches expected checksum - assert: - that: - - "result.stat.checksum == '71a17ddd1d57ed7c7912e4fd11ecb2ead0b27033'" - - -- name: Create unix test file with initial line - win_lineinfile: dest={{win_output_dir}}/test_unix_sep.txt create=yes insertbefore=BOF state=present line="This is a new file" - register: result - -- name: assert that the new file was created - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - -- name: validate that the newly created file exists - win_stat: path={{win_output_dir}}/test_unix_sep.txt - register: result - -- name: assert the newly created file checksum matches - assert: - that: - - "result.stat.checksum == '84faac1183841c57434693752fc3debc91b9195d'" - -- name: Test appending to the file using unix line separator - win_lineinfile: dest={{win_output_dir}}/test_unix_sep.txt insertbefore=EOF state=present line="This is the last line" newline="unix" - register: result - -- name: assert that the new line was added - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - -- name: stat the file - win_stat: path={{win_output_dir}}/test_unix_sep.txt - register: result - -- name: assert the file checksum matches expected checksum - assert: - that: - - "result.stat.checksum == 'f1f634a37ab1c73efb77a71a5ad2cc87b61b17ae'" - - -# Encoding management test cases - -# Default (auto) encoding should use utf-8 with no BOM -- name: Test create file without explicit encoding results in utf-8 without BOM - win_lineinfile: dest={{win_output_dir}}/test_auto_utf8.txt create=yes insertbefore=BOF state=present line="This is a new utf-8 file" - register: result - -- name: assert that the new file was created - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - - "result.encoding == 'utf-8'" - -- name: validate that the newly created file exists - win_stat: path={{win_output_dir}}/test_auto_utf8.txt - register: result - -- name: assert the newly created file checksum matches - assert: - that: - - "result.stat.checksum == 'b69fcbacca8291a4668f57fba91d7c022f1c3dc7'" - -- name: Test appending to the utf-8 without BOM file - should autodetect UTF-8 no BOM - win_lineinfile: dest={{win_output_dir}}/test_auto_utf8.txt insertbefore=EOF state=present line="This is the last line" - register: result - -- name: assert that the new line was added and encoding did not change - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - - "result.encoding == 'utf-8'" - -- name: stat the file - win_stat: path={{win_output_dir}}/test_auto_utf8.txt - register: result - -- name: assert the file checksum matches - assert: - that: - - "result.stat.checksum == '64d747f1ebf8c9d793dbfd27126e4152d39a3848'" - - -# UTF-8 explicit (with BOM) -- name: Test create file with explicit utf-8 encoding results in utf-8 with a BOM - win_lineinfile: dest={{win_output_dir}}/test_utf8.txt create=yes encoding="utf-8" insertbefore=BOF state=present line="This is a new utf-8 file" - register: result - -- name: assert that the new file was created - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - - "result.encoding == 'utf-8'" - -- name: validate that the newly created file exists - win_stat: path={{win_output_dir}}/test_utf8.txt - register: result - -- name: assert the newly created file checksum matches - assert: - that: - - "result.stat.checksum == 'd45344b2b3bf1cf90eae851b40612f5f37a88bbb'" - -- name: Test appending to the utf-8 with BOM file - should autodetect utf-8 with BOM encoding - win_lineinfile: dest={{win_output_dir}}/test_utf8.txt insertbefore=EOF state=present line="This is the last line" - register: result - -- name: assert that the new line was added and encoding did not change - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - - "result.encoding == 'utf-8'" - -- name: stat the file - win_stat: path={{win_output_dir}}/test_utf8.txt - register: result - -- name: assert the file checksum matches - assert: - that: - - "result.stat.checksum == '9b84254489f40f258871a4c6573cacc65895ee1a'" - - -# UTF-16 explicit -- name: Test create file with explicit utf-16 encoding - win_lineinfile: dest={{win_output_dir}}/test_utf16.txt create=yes encoding="utf-16" insertbefore=BOF state=present line="This is a new utf-16 file" - register: result - -- name: assert that the new file was created - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - - "result.encoding == 'utf-16'" - -- name: validate that the newly created file exists - win_stat: path={{win_output_dir}}/test_utf16.txt - register: result - -- name: assert the newly created file checksum matches - assert: - that: - - "result.stat.checksum == '785b0693cec13b60e2c232782adeda2f8a967434'" - -- name: Test appending to the utf-16 file - should autodetect utf-16 encoding - win_lineinfile: dest={{win_output_dir}}/test_utf16.txt insertbefore=EOF state=present line="This is the last line" - register: result - -- name: assert that the new line was added and encoding did not change - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - - "result.encoding == 'utf-16'" - -- name: stat the file - win_stat: path={{win_output_dir}}/test_utf16.txt - register: result - -- name: assert the file checksum matches - assert: - that: - - "result.stat.checksum == '70e4eb3ba795e1ba94d262db47e4fd17c64b2e73'" - -# UTF-32 explicit -- name: Test create file with explicit utf-32 encoding - win_lineinfile: dest={{win_output_dir}}/test_utf32.txt create=yes encoding="utf-32" insertbefore=BOF state=present line="This is a new utf-32 file" - register: result - -- name: assert that the new file was created - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - - "result.encoding == 'utf-32'" - -- name: validate that the newly created file exists - win_stat: path={{win_output_dir}}/test_utf32.txt - register: result - -- name: assert the newly created file checksum matches - assert: - that: - - "result.stat.checksum == '7a6e3f3604c0def431aaa813173a4ddaa10fd1fb'" - -- name: Test appending to the utf-32 file - should autodetect utf-32 encoding - win_lineinfile: dest={{win_output_dir}}/test_utf32.txt insertbefore=EOF state=present line="This is the last line" - register: result - -- name: assert that the new line was added and encoding did not change - assert: - that: - - "result.changed == true" - - "result.msg == 'line added'" - - "result.encoding == 'utf-32'" - -- name: stat the file - win_stat: path={{win_output_dir}}/test_utf32.txt - register: result - -- name: assert the file checksum matches - assert: - that: - - "result.stat.checksum == '66a72e71f42c4775f4326da95cfe82c8830e5022'" - -######################################################################### -# issue #33858 -# \r\n causes line break instead of printing literally which breaks paths. - -- name: create testing file - win_copy: - src: test_linebreak.txt - dest: "{{win_output_dir}}/test_linebreak.txt" - -- name: stat the test file - win_stat: - path: "{{win_output_dir}}/test_linebreak.txt" - register: result - -# (Get-FileHash -path C:\ansible\test\integration\targets\win_lineinfile\files\test_linebreak.txt -Algorithm sha1).hash.tolower() -- name: check win_stat file result - assert: - that: - - result.stat.exists - - not result.stat.isdir - - result.stat.checksum == 'da39a3ee5e6b4b0d3255bfef95601890afd80709' - - result is not failed - - result is not changed - -- name: insert path c:\return\new to test file - win_lineinfile: - dest: "{{win_output_dir}}/test_linebreak.txt" - line: c:\return\new - register: result_literal - -- name: insert path "c:\return\new" to test file, will cause line breaks - win_lineinfile: - dest: "{{win_output_dir}}/test_linebreak.txt" - line: "c:\return\new" - register: result_expand - -- name: assert that the lines were inserted - assert: - that: - - result_literal.changed == true - - result_literal.msg == 'line added' - - result_expand.changed == true - - result_expand.msg == 'line added' - -- name: stat the test file - win_stat: - path: "{{win_output_dir}}/test_linebreak.txt" - register: result - -- debug: - var: result - verbosity: 1 - -# expect that the file looks like this: -# c:\return\new -# c: -# eturn -# ew #or c:eturnew on windows -- name: assert that one line is literal and the other has breaks - assert: - that: - - result.stat.checksum == 'd2dfd11bc70526ff13a91153c76a7ae5595a845b' diff --git a/test/integration/targets/win_mapped_drive/aliases b/test/integration/targets/win_mapped_drive/aliases deleted file mode 100644 index 4f4664b6858..00000000000 --- a/test/integration/targets/win_mapped_drive/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group5 diff --git a/test/integration/targets/win_mapped_drive/defaults/main.yml b/test/integration/targets/win_mapped_drive/defaults/main.yml deleted file mode 100644 index 6e8ed002edd..00000000000 --- a/test/integration/targets/win_mapped_drive/defaults/main.yml +++ /dev/null @@ -1,9 +0,0 @@ -test_win_mapped_drive_letter: M -test_win_mapped_drive_path: share1 -test_win_mapped_drive_path2: share2 - -test_win_mapped_drive_local_path: C:\ansible\win_mapped_drive\share1 -test_win_mapped_drive_local_path2: C:\ansible\win_mapped_drive\share2 - -test_win_mapped_drive_temp_user: TestMappedUser -test_win_mapped_drive_temp_password: aZ293jgkdslgj4 diff --git a/test/integration/targets/win_mapped_drive/tasks/main.yml b/test/integration/targets/win_mapped_drive/tasks/main.yml deleted file mode 100644 index 3e3455bef9b..00000000000 --- a/test/integration/targets/win_mapped_drive/tasks/main.yml +++ /dev/null @@ -1,99 +0,0 @@ ---- -# test setup -- name: gather facts required by the tests - setup: - gather_subset: platform - -- name: ensure mapped drive is deleted before test - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - state: absent - -- name: ensure temp mapped drive user exist - win_user: - name: '{{test_win_mapped_drive_temp_user}}' - password: '{{test_win_mapped_drive_temp_password}}' - state: present - groups: - - Administrators - -- name: ensure temp folders exist - win_file: - path: '{{item}}' - state: directory - with_items: - - '{{test_win_mapped_drive_local_path}}' - - '{{test_win_mapped_drive_local_path2}}' - -# can't use win_share as it doesnt't support Server 2008 and 2008 R2 -- name: ensure shares exist - win_shell: $share = Get-WmiObject -Class Win32_Share | Where-Object { $_.Name -eq '{{item.name}}' }; if (-not $share) { $share = [wmiClass]'Win32_Share'; $share.Create('{{item.path}}', '{{item.name}}', 0) } - with_items: - - { name: '{{test_win_mapped_drive_path}}', path: '{{test_win_mapped_drive_local_path}}' } - - { name: '{{test_win_mapped_drive_path2}}', path: '{{test_win_mapped_drive_local_path2}}' } - -# This ensures we test out the split token/become behaviour -- name: ensure builtin Administrator has a split token - win_regedit: - path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System - name: FilterAdministratorToken - data: 1 - type: dword - register: admin_uac - -- name: reboot to apply Admin approval mode setting - win_reboot: - when: admin_uac is changed - -- block: - # tests - - include_tasks: tests.yml - - # test cleanup - always: - - name: remove stored credential - win_credential: - name: '{{ ansible_hostname }}' - type: domain_password - state: absent - vars: - ansible_become: yes - ansible_become_method: runas - ansible_become_user: '{{ ansible_user }}' - ansible_become_pass: '{{ ansible_password }}' - - - name: ensure mapped drive is deleted at the end of the test - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - state: absent - - - name: ensure shares are removed - win_shell: $share = Get-WmiObject -Class Win32_Share | Where-Object { $_.Name -eq '{{item}}' }; if ($share) { $share.Delete() } - with_items: - - '{{test_win_mapped_drive_path}}' - - '{{test_win_mapped_drive_path2}}' - - - name: ensure temp folders are deleted - win_file: - path: '{{item}}' - state: absent - with_items: - - '{{test_win_mapped_drive_local_path}}' - - '{{test_win_mapped_drive_local_path2}}' - - - name: ensure temp mapped driver user is deleted - win_user: - name: '{{test_win_mapped_drive_temp_user}}' - state: absent - - - name: disable Admin approval mode if changed in test - win_regedit: - path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System - name: FilterAdministratorToken - data: 0 - type: dword - when: admin_uac is changed - - - name: reboot to apply Admin approval mode setting - win_reboot: - when: admin_uac is changed diff --git a/test/integration/targets/win_mapped_drive/tasks/tests.yml b/test/integration/targets/win_mapped_drive/tasks/tests.yml deleted file mode 100644 index c11b5348690..00000000000 --- a/test/integration/targets/win_mapped_drive/tasks/tests.yml +++ /dev/null @@ -1,344 +0,0 @@ ---- -- name: fail with invalid path - win_mapped_drive: - letter: invalid - state: absent - register: fail_invalid_letter - failed_when: "fail_invalid_letter.msg != 'letter must be a single letter from A-Z, was: invalid'" - -- name: fail without specify path when creating drive - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - state: present - register: fail_path_missing - failed_when: "fail_path_missing.msg != 'state is present but all of the following are missing: path'" - -- name: fail when specifying letter with existing physical path - win_mapped_drive: - letter: c - path: \\{{ansible_hostname}}\{{test_win_mapped_drive_path}} - state: present - register: fail_local_letter - failed_when: fail_local_letter.msg != 'failed to create mapped drive c, this letter is in use and is pointing to a non UNC path' - -- name: create mapped drive check - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - path: \\{{ansible_hostname}}\{{test_win_mapped_drive_path}} - state: present - register: create_drive_check - check_mode: yes - -- name: get actual of create mapped drive check - win_command: 'net use {{test_win_mapped_drive_letter}}:' # Get-PSDrive/Get-WmiObject/Get-CimInstance doesn't work over WinRM - register: create_drive_actual_check - failed_when: False - -- name: assert create mapped drive check - assert: - that: - - create_drive_check is changed - - create_drive_actual_check.rc == 2 # should fail with this error code when it isn't found - -- name: create mapped drive - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - path: \\{{ansible_hostname}}\{{test_win_mapped_drive_path}} - state: present - register: create_drive - -- name: get actual of create mapped drive - win_command: 'net use {{test_win_mapped_drive_letter}}:' - register: create_drive_actual - -- name: assert create mapped drive - assert: - that: - - create_drive is changed - - create_drive_actual.rc == 0 - - create_drive_actual.stdout_lines[1] == "Remote name \\\\{{ansible_hostname}}\\{{test_win_mapped_drive_path}}" - -- name: create mapped drive again - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - path: \\{{ansible_hostname}}\{{test_win_mapped_drive_path}} - state: present - register: create_drive_again - -- name: assert create mapped drive again - assert: - that: - - create_drive_again is not changed - -- name: change mapped drive target check - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - path: \\{{ansible_hostname}}\{{test_win_mapped_drive_path2}} - state: present - register: change_drive_target_check - check_mode: yes - -- name: get actual of change mapped drive target check - win_command: 'net use {{test_win_mapped_drive_letter}}:' - register: change_drive_target_actual_check - -- name: assert change mapped drive target check - assert: - that: - - change_drive_target_check is changed - - change_drive_target_actual_check.rc == 0 - - change_drive_target_actual_check.stdout_lines[1] == "Remote name \\\\{{ansible_hostname}}\\{{test_win_mapped_drive_path}}" - -- name: change mapped drive target - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - path: \\{{ansible_hostname}}\{{test_win_mapped_drive_path2}} - state: present - register: change_drive_target - -- name: get actual of change mapped drive target - win_command: 'net use {{test_win_mapped_drive_letter}}:' - register: change_drive_target_actual - -- name: assert change mapped drive target - assert: - that: - - change_drive_target is changed - - change_drive_target_actual.rc == 0 - - change_drive_target_actual.stdout_lines[1] == "Remote name \\\\{{ansible_hostname}}\\{{test_win_mapped_drive_path2}}" - -- name: fail to delete mapped drive if target doesn't match - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - path: \\{{ansible_hostname}}\{{test_win_mapped_drive_path}} - state: absent - register: fail_delete_incorrect_target - failed_when: fail_delete_incorrect_target.msg != 'did not delete mapped drive ' + test_win_mapped_drive_letter + ', the target path is pointing to a different location at \\\\' + ansible_hostname + '\\' + test_win_mapped_drive_path2 - -- name: delete mapped drive check - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - path: \\{{ansible_hostname}}\{{test_win_mapped_drive_path2}} - state: absent - register: delete_drive_check - check_mode: yes - -- name: get actual of delete mapped drive check - win_command: 'net use {{test_win_mapped_drive_letter}}:' - register: delete_drive_actual_check - -- name: assert delete mapped drive check - assert: - that: - - delete_drive_check is changed - - delete_drive_actual_check.rc == 0 - - delete_drive_actual_check.stdout_lines[1] == "Remote name \\\\{{ansible_hostname}}\\{{test_win_mapped_drive_path2}}" - -- name: delete mapped drive - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - path: \\{{ansible_hostname}}\{{test_win_mapped_drive_path2}} - state: absent - register: delete_drive - -- name: get actual of delete mapped drive - win_command: 'net use {{test_win_mapped_drive_letter}}:' - register: delete_drive_actual - failed_when: False - -- name: assert delete mapped drive - assert: - that: - - delete_drive is changed - - delete_drive_actual.rc == 2 - -- name: delete mapped drive again - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - path: \\{{ansible_hostname}}\{{test_win_mapped_drive_path2}} - state: absent - register: delete_drive_again - -- name: assert delete mapped drive again - assert: - that: - - delete_drive_again is not changed - -# not much we can do to test out the credentials except that it sets it, winrm -# makes it hard to actually test out we can still access the mapped drive -- name: map drive with current credentials check - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - path: \\{{ansible_hostname}}\{{test_win_mapped_drive_path}} - state: present - username: '{{ansible_hostname}}\{{test_win_mapped_drive_temp_user}}' - password: '{{test_win_mapped_drive_temp_password}}' - register: map_with_credentials_check - check_mode: yes - -- name: get actual of map drive with current credentials check - win_command: 'net use {{test_win_mapped_drive_letter}}:' - register: map_with_credentials_actual_check - failed_when: False - -- name: assert map drive with current credentials check - assert: - that: - - map_with_credentials_check is changed - - map_with_credentials_actual_check.rc == 2 - -- name: map drive with current credentials - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - path: \\{{ansible_hostname}}\{{test_win_mapped_drive_path}} - state: present - username: '{{ansible_hostname}}\{{test_win_mapped_drive_temp_user}}' - password: '{{test_win_mapped_drive_temp_password}}' - register: map_with_credentials - -- name: get actual of map drive with current credentials - win_command: 'net use {{test_win_mapped_drive_letter}}:' - register: map_with_credentials_actual - -- name: get username of mapped network drive with credentials - win_reg_stat: - path: HKCU:\Network\{{test_win_mapped_drive_letter}} - name: UserName - register: map_with_credential_actual_username - -- name: assert map drive with current credentials - assert: - that: - - map_with_credentials is changed - - map_with_credentials_actual.rc == 0 - - map_with_credential_actual_username.value == '' # we explicitly remove the username part in the module - -- name: map drive with current credentials again - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - path: \\{{ansible_hostname}}\{{test_win_mapped_drive_path}} - state: present - username: '{{ansible_hostname}}\{{test_win_mapped_drive_temp_user}}' - password: '{{test_win_mapped_drive_temp_password}}' - register: map_with_credentials_again - -- name: assert map drive with current credentials again - assert: - that: - - not map_with_credentials_again is changed - -- name: delete mapped drive without path check - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - state: absent - register: delete_without_path_check - check_mode: yes - -- name: get actual delete mapped drive without path check - win_command: 'net use {{test_win_mapped_drive_letter}}:' - register: delete_without_path_actual_check - -- name: assert delete mapped drive without path check - assert: - that: - - delete_without_path_check is changed - - delete_without_path_actual_check.rc == 0 - -- name: delete mapped drive without path - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - state: absent - register: delete_without_path - -- name: get actual delete mapped drive without path - win_command: 'net use {{test_win_mapped_drive_letter}}:' - register: delete_without_path_actual - failed_when: False - -- name: assert delete mapped drive without path check - assert: - that: - - delete_without_path is changed - - delete_without_path_actual.rc == 2 - -- name: delete mapped drive without path again - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - state: absent - register: delete_without_path_again - -- name: assert delete mapped drive without path check again - assert: - that: - - delete_without_path_again is not changed - -- name: store credential for test network account - win_credential: - name: '{{ ansible_hostname }}' - type: domain_password - username: '{{ test_win_mapped_drive_temp_user }}' - secret: '{{ test_win_mapped_drive_temp_password }}' - state: present - vars: &become_vars - ansible_become: yes - ansible_become_method: runas - ansible_become_user: '{{ ansible_user }}' - ansible_become_pass: '{{ ansible_password }}' - -- name: map drive with stored cred (check mode) - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - path: \\{{ansible_hostname}}\{{test_win_mapped_drive_path}} - state: present - check_mode: yes - vars: *become_vars - register: map_with_stored_cred_check - -- name: get actual of map drive with stored cred (check mode) - win_command: 'net use {{test_win_mapped_drive_letter}}:' - register: map_with_stored_cred_actual_check - failed_when: False - -- name: assert map drive with stored cred (check mode) - assert: - that: - - map_with_stored_cred_check is changed - - map_with_stored_cred_actual_check.rc == 2 - -- name: map drive with stored cred - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - path: \\{{ansible_hostname}}\{{test_win_mapped_drive_path}} - state: present - vars: *become_vars - register: map_with_stored_cred - -- name: get actual of map drive with stored cred - win_command: 'net use {{test_win_mapped_drive_letter}}:' - register: map_with_stored_cred_actual - -- name: get username of mapped network drive with stored cred - win_reg_stat: - path: HKCU:\Network\{{test_win_mapped_drive_letter}} - name: UserName - register: map_with_stored_cred_actual_username - -- name: assert map drive with stored cred - assert: - that: - - map_with_stored_cred is changed - - map_with_stored_cred_actual.rc == 0 - - map_with_stored_cred_actual_username.value == '' - -- name: map drive with stored cred again - win_mapped_drive: - letter: '{{test_win_mapped_drive_letter}}' - path: \\{{ansible_hostname}}\{{test_win_mapped_drive_path}} - state: present - vars: *become_vars - register: map_with_stored_cred_again - -- name: assert map drive with stored cred again - assert: - that: - - not map_with_stored_cred_again is changed diff --git a/test/integration/targets/win_msg/aliases b/test/integration/targets/win_msg/aliases deleted file mode 100644 index 98b74ac9877..00000000000 --- a/test/integration/targets/win_msg/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group2 -unstable diff --git a/test/integration/targets/win_msg/tasks/main.yml b/test/integration/targets/win_msg/tasks/main.yml deleted file mode 100644 index 17051239fac..00000000000 --- a/test/integration/targets/win_msg/tasks/main.yml +++ /dev/null @@ -1,33 +0,0 @@ -- name: Warn user - win_msg: - display_seconds: 10 - msg: Keep calm and carry on. - register: msg_result - -- name: Test msg_result - assert: - that: - - msg_result is not failed - - msg_result is changed - - msg_result.runtime_seconds < 10 - -- name: Warn user and wait for it - win_msg: - display_seconds: 5 - msg: Keep calm and carry on. - #to: '{{ ansible_user }}' - wait: yes - register: msg_wait_result - -- name: Test msg_wait_result - assert: - that: - - msg_wait_result is not failed - - msg_wait_result is changed - - msg_wait_result.runtime_seconds > 5 - -- name: fail to send a message > 255 characters - win_msg: - msg: "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456" - register: fail_too_long - failed_when: "fail_too_long.msg != 'msg length must be less than 256 characters, current length: 256'" diff --git a/test/integration/targets/win_netbios/aliases b/test/integration/targets/win_netbios/aliases deleted file mode 100644 index 4c08975b17d..00000000000 --- a/test/integration/targets/win_netbios/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group6 diff --git a/test/integration/targets/win_netbios/meta/main.yml b/test/integration/targets/win_netbios/meta/main.yml deleted file mode 100644 index e7f499ee343..00000000000 --- a/test/integration/targets/win_netbios/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: -- setup_win_device \ No newline at end of file diff --git a/test/integration/targets/win_netbios/tasks/main.yml b/test/integration/targets/win_netbios/tasks/main.yml deleted file mode 100644 index 2f96287bb00..00000000000 --- a/test/integration/targets/win_netbios/tasks/main.yml +++ /dev/null @@ -1,30 +0,0 @@ -# Test code for win_netbios module -# Copyright: (c) 2019, Thomas Moore - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -- name: ensure netbios is set to default to start with - win_netbios: - state: default - -- block: - - name: run tests - include_tasks: tests.yml - - always: - - name: set netbios back to default after tests - win_netbios: - state: default \ No newline at end of file diff --git a/test/integration/targets/win_netbios/tasks/tests.yml b/test/integration/targets/win_netbios/tasks/tests.yml deleted file mode 100644 index 961b91dc04d..00000000000 --- a/test/integration/targets/win_netbios/tasks/tests.yml +++ /dev/null @@ -1,159 +0,0 @@ -# Test code for win_netbios module -# Copyright: (c) 2019, Thomas Moore - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -- set_fact: - get_netbios_script: | - $adapter = Get-CimInstance -ClassName Win32_NetworkAdapter -Filter "NetConnectionID='{{ network_adapter_name }}'" - $config = Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter "Index=$($adapter.DeviceID)" - $config.TcpipNetbiosOptions - -- name: disable netbios single adapter (check mode) - win_netbios: - adapter_names: '{{ network_adapter_name }}' - state: disabled - register: set_single_check - check_mode: yes - -- name: get result of disable a single adapter test (check mode) - win_shell: '{{ get_netbios_script }}' - changed_when: no - register: set_single_actual_check - -- name: assert disable a single adapter (check mode) - assert: - that: - - set_single_check is changed - - set_single_actual_check.stdout_lines == ["0"] - -- name: disable netbios single adapter - win_netbios: - adapter_names: '{{ network_adapter_name }}' - state: disabled - register: set_single - -- name: get result of disable a single adapter test - win_shell: '{{ get_netbios_script }}' - changed_when: no - register: set_single_actual - -- name: assert disable a single adapter - assert: - that: - - set_single_check is changed - - set_single_actual.stdout_lines == ["2"] - -- name: fail with invalid network adapter name - win_netbios: - state: disabled - adapter_names: - - FakeAdapterName - register: invalid_adapter - failed_when: invalid_adapter.msg != "Not all of the target adapter names could be found on the system. No configuration changes have been made. FakeAdapterName" - -- name: disable netbios all adapters (check mode) - win_netbios: - state: disabled - check_mode: yes - register: disable_check - -- name: assert disable netbios (check mode) - assert: - that: - - disable_check.changed - -- name: disable netbios all adapters - win_netbios: - state: disabled - register: netbios_disable - -- name: assert netbios disabled - assert: - that: - - netbios_disable.changed - -- name: test disable idempotence - win_netbios: - state: disabled - register: netbios_disable - -- name: test disable idempotence - assert: - that: - - not netbios_disable.changed - -- name: enable netbios all adapters (check mode) - win_netbios: - state: enabled - check_mode: yes - register: enable_check - -- name: assert enable netbios all adapters (check mode) - assert: - that: - - enable_check.changed - -- name: enable netbios all adapters - win_netbios: - state: enabled - register: netbios_enable - -- name: assert netbios enabled - assert: - that: - - netbios_enable.changed - -- name: test enable idempotence - win_netbios: - state: enabled - register: netbios_enable - -- name: assert enable idempotence - assert: - that: - - not netbios_enable.changed - -- name: default netbios all adapters (check mode) - win_netbios: - state: default - check_mode: yes - register: default_check - -- name: assert default netbios (check mode) - assert: - that: - - default_check.changed - -- name: default netbios all adapters - win_netbios: - state: default - register: default_enable - -- name: assert netbios default all adapters - assert: - that: - - default_enable.changed - -- name: test default idempotence - win_netbios: - state: default - register: netbios_default - -- name: assert default idempotence - assert: - that: - - not netbios_default.changed \ No newline at end of file diff --git a/test/integration/targets/win_nssm/aliases b/test/integration/targets/win_nssm/aliases deleted file mode 100644 index 51c5d6aba11..00000000000 --- a/test/integration/targets/win_nssm/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group4 -skip/windows/2016 # Host takes a while to run and module isn't OS dependent diff --git a/test/integration/targets/win_nssm/defaults/main.yml b/test/integration/targets/win_nssm/defaults/main.yml deleted file mode 100644 index 6ebafb24a12..00000000000 --- a/test/integration/targets/win_nssm/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -test_service_name: ansible_nssm_test -test_win_nssm_path: '{{win_output_dir}}\win_nssm' -test_win_nssm_username: testnssmuser -test_win_nssm_password: Password123! \ No newline at end of file diff --git a/test/integration/targets/win_nssm/tasks/main.yml b/test/integration/targets/win_nssm/tasks/main.yml deleted file mode 100644 index 49368cf1a46..00000000000 --- a/test/integration/targets/win_nssm/tasks/main.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- -- name: install NSSM - win_chocolatey: - name: NSSM - state: present - -- name: ensure testing folder exists - win_file: - path: '{{test_win_nssm_path}}' - state: directory - -- name: create test user for service execution - win_user: - name: '{{test_win_nssm_username}}' - password: '{{test_win_nssm_password}}' - state: present - groups: - - Users - -# Run actual tests -- block: - - include_tasks: tests.yml - - always: - - name: ensure test service is absent - win_service: - name: '{{ test_service_name }}' - state: absent - - - name: remove test user - win_user: - name: '{{test_win_nssm_username}}' - state: absent - - - name: cleanup test folder - win_file: - path: '{{test_win_nssm_path}}' - state: absent - - - name: uninstall NSSM - win_chocolatey: - name: NSSM - state: absent - failed_when: false diff --git a/test/integration/targets/win_nssm/tasks/tests.yml b/test/integration/targets/win_nssm/tasks/tests.yml deleted file mode 100644 index d5d9d389ca7..00000000000 --- a/test/integration/targets/win_nssm/tasks/tests.yml +++ /dev/null @@ -1,406 +0,0 @@ ---- -- name: get register cmd that will get service info - set_fact: - test_service_cmd: | - $res = @{} - $srvobj = Get-WmiObject Win32_Service -Filter "Name=""$service""" | Select Name,DisplayName,Description,PathName,StartMode,StartName,State - if ($srvobj) { - $srvobj | Get-Member -MemberType *Property | % { $res.($_.name) = $srvobj.($_.name) } - $res.Exists = $true - $res.Dependencies = @(Get-WmiObject -Query "Associators of {Win32_Service.Name=""$service""} Where AssocClass=Win32_DependentService" | select -ExpandProperty Name) - $res.Parameters = @{} - $srvkey = "HKLM:\SYSTEM\CurrentControlSet\Services\$service\Parameters" - Get-Item "$srvkey" | Select-Object -ExpandProperty property | % { $res.Parameters.$_ = (Get-ItemProperty -Path "$srvkey" -Name $_).$_} - } else { - $res.Exists = $false - } - ConvertTo-Json -InputObject $res -Compress - -- name: install service (check mode) - win_nssm: - name: '{{ test_service_name }}' - application: C:\Windows\System32\cmd.exe - state: present - register: install_service_check - check_mode: yes - -- name: get result of install service (check mode) - win_shell: '$service = ''{{ test_service_name }}''; {{ test_service_cmd }}' - register: install_service_check_actual - -- name: assert results of install service (check mode) - assert: - that: - - install_service_check.changed == true - - (install_service_check_actual.stdout|from_json).Exists == false - -- name: install service - win_nssm: - name: '{{ test_service_name }}' - application: C:\Windows\System32\cmd.exe - state: present - register: install_service - -- name: get result of install service - win_shell: '$service = ''{{ test_service_name }}''; {{ test_service_cmd }}' - register: install_service_actual - -- name: assert results of install service - assert: - that: - - install_service.changed == true - - (install_service_actual.stdout|from_json).Exists == true - - (install_service_actual.stdout|from_json).State == 'Stopped' - - (install_service_actual.stdout|from_json).StartMode == 'Auto' - - (install_service_actual.stdout|from_json).Parameters.Application == "C:\Windows\System32\cmd.exe" - - (install_service_actual.stdout|from_json).Parameters.AppDirectory == "C:\Windows\System32" - -- name: test install service (idempotent) - win_nssm: - name: '{{ test_service_name }}' - application: C:\Windows\System32\cmd.exe - state: present - register: install_service_again - -- name: get result of install service (idempotent) - win_shell: '$service = ''{{ test_service_name }}''; {{ test_service_cmd }}' - register: install_service_again_actual - -- name: assert results of install service (idempotent) - assert: - that: - - install_service_again.changed == false - - (install_service_again_actual.stdout|from_json).Exists == true - - (install_service_again_actual.stdout|from_json).State == 'Stopped' - - (install_service_again_actual.stdout|from_json).StartMode == 'Auto' - - (install_service_again_actual.stdout|from_json).Parameters.Application == "C:\Windows\System32\cmd.exe" - - (install_service_again_actual.stdout|from_json).Parameters.AppDirectory == "C:\Windows\System32" - -- name: install and start service - win_nssm: - name: '{{ test_service_name }}' - application: C:\Windows\System32\cmd.exe - state: started - register: install_start_service - -- name: get result of install and start service - win_shell: '$service = ''{{ test_service_name }}''; {{ test_service_cmd }}' - register: install_start_service_actual - -- name: assert results of install and start service - assert: - that: - - install_start_service.changed == true - - (install_start_service_actual.stdout|from_json).Exists == true - - (install_start_service_actual.stdout|from_json).State == 'Running' - - (install_start_service_actual.stdout|from_json).StartMode == 'Auto' - - (install_start_service_actual.stdout|from_json).Parameters.Application == "C:\Windows\System32\cmd.exe" - - (install_start_service_actual.stdout|from_json).Parameters.AppDirectory == "C:\Windows\System32" - -- name: install and start service with more parameters (check mode) - win_nssm: - name: '{{ test_service_name }}' - display_name: Ansible testing - description: win_nssm test service - application: C:\Windows\System32\cmd.exe - start_mode: manual - working_directory: '{{ test_win_nssm_path }}' - dependencies: 'tcpip,dnscache' - user: '{{ test_win_nssm_username }}' - password: '{{ test_win_nssm_password }}' - stdout_file: '{{ test_win_nssm_path }}\log.txt' - stderr_file: '{{ test_win_nssm_path }}\error.txt' - state: started - register: install_service_complex_check - check_mode: yes - -- name: get result of install and start service with more parameters (check mode) - win_shell: '$service = ''{{ test_service_name }}''; {{ test_service_cmd }}' - register: install_service_complex_check_actual - -- name: assert results of install and start service with more parameters (check mode) - assert: - that: - - install_service_complex_check.changed == true - - (install_service_complex_check_actual.stdout|from_json).Exists == true - - (install_service_complex_check_actual.stdout|from_json).DisplayName == '{{ test_service_name }}' - - (install_service_complex_check_actual.stdout|from_json).Description is none - - (install_service_complex_check_actual.stdout|from_json).StartMode != 'Manual' - - (install_service_complex_check_actual.stdout|from_json).StartName != '.\\' + test_win_nssm_username - - (install_service_complex_check_actual.stdout|from_json).Parameters.Application == "C:\Windows\System32\cmd.exe" - - (install_service_complex_check_actual.stdout|from_json).Parameters.AppDirectory == "C:\Windows\System32" - - '"AppStdout" not in (install_service_complex_check_actual.stdout|from_json).Parameters' - - '"AppStderr" not in (install_service_complex_check_actual.stdout|from_json).Parameters' - - (install_service_complex_check_actual.stdout|from_json).Dependencies|length == 0 - -- name: install and start service with more parameters - win_nssm: - name: '{{ test_service_name }}' - display_name: Ansible testing - description: win_nssm test service - application: C:\Windows\System32\cmd.exe - start_mode: manual - working_directory: '{{ test_win_nssm_path }}' - dependencies: 'tcpip,dnscache' - user: '{{ test_win_nssm_username }}' - password: '{{ test_win_nssm_password }}' - stdout_file: '{{ test_win_nssm_path }}\log.txt' - stderr_file: '{{ test_win_nssm_path }}\error.txt' - state: started - register: install_service_complex - -- name: get result of install and start service with more parameters - win_shell: '$service = ''{{ test_service_name }}''; {{ test_service_cmd }}' - register: install_service_complex_actual - -- name: assert results of install and start service with more parameters - assert: - that: - - install_service_complex.changed == true - - (install_service_complex_actual.stdout|from_json).Exists == true - - (install_service_complex_actual.stdout|from_json).DisplayName == 'Ansible testing' - - (install_service_complex_actual.stdout|from_json).Description == 'win_nssm test service' - - (install_service_complex_actual.stdout|from_json).State == 'Running' - - (install_service_complex_actual.stdout|from_json).StartMode == 'Manual' - - (install_service_complex_actual.stdout|from_json).StartName == '.\\' + test_win_nssm_username - - (install_service_complex_actual.stdout|from_json).Parameters.Application == "C:\Windows\System32\cmd.exe" - - (install_service_complex_actual.stdout|from_json).Parameters.AppDirectory == test_win_nssm_path - - (install_service_complex_actual.stdout|from_json).Parameters.AppStdout == test_win_nssm_path + '\\log.txt' - - (install_service_complex_actual.stdout|from_json).Parameters.AppStderr == test_win_nssm_path + '\\error.txt' - - (install_service_complex_actual.stdout|from_json).Dependencies|length == 2 - - '"Tcpip" in (install_service_complex_actual.stdout|from_json).Dependencies' - - '"Dnscache" in (install_service_complex_actual.stdout|from_json).Dependencies' - -- name: install and start service with more parameters (idempotent) - win_nssm: - name: '{{ test_service_name }}' - display_name: Ansible testing - description: win_nssm test service - application: C:\Windows\System32\cmd.exe - start_mode: manual - working_directory: '{{ test_win_nssm_path }}' - # Dependencies order should not trigger a change - dependencies: 'dnscache,tcpip' - user: '{{ test_win_nssm_username }}' - password: '{{ test_win_nssm_password }}' - stdout_file: '{{ test_win_nssm_path }}\log.txt' - stderr_file: '{{ test_win_nssm_path }}\error.txt' - state: started - register: install_service_complex_again - -- name: get result of install and start service with more parameters (idempotent) - win_shell: '$service = ''{{ test_service_name }}''; {{ test_service_cmd }}' - register: install_service_complex_again_actual - -- name: assert results of install and start service with more parameters (idempotent) - assert: - that: - - install_service_complex_again.changed == false - - (install_service_complex_again_actual.stdout|from_json).Exists == true - - (install_service_complex_again_actual.stdout|from_json).DisplayName == 'Ansible testing' - - (install_service_complex_again_actual.stdout|from_json).Description == 'win_nssm test service' - - (install_service_complex_again_actual.stdout|from_json).State == 'Running' - - (install_service_complex_again_actual.stdout|from_json).StartMode == 'Manual' - - (install_service_complex_again_actual.stdout|from_json).StartName == '.\\' + test_win_nssm_username - - (install_service_complex_again_actual.stdout|from_json).Parameters.Application == "C:\Windows\System32\cmd.exe" - - (install_service_complex_again_actual.stdout|from_json).Parameters.AppDirectory == test_win_nssm_path - - (install_service_complex_again_actual.stdout|from_json).Parameters.AppStdout == test_win_nssm_path + '\\log.txt' - - (install_service_complex_again_actual.stdout|from_json).Parameters.AppStderr == test_win_nssm_path + '\\error.txt' - - (install_service_complex_again_actual.stdout|from_json).Dependencies|length == 2 - - '"Tcpip" in (install_service_complex_again_actual.stdout|from_json).Dependencies' - - '"Dnscache" in (install_service_complex_again_actual.stdout|from_json).Dependencies' - -- name: install service with string form parameters - win_nssm: - name: '{{ test_service_name }}' - application: C:\Windows\System32\cmd.exe - arguments: '-v -Dtest.str=value "C:\with space\\"' - state: present - register: str_params - -- name: get result of install service with string form parameters - win_shell: '$service = ''{{ test_service_name }}''; {{ test_service_cmd }}' - register: str_params_actual - -- name: assert results of install service with string form parameters - assert: - that: - - str_params.changed == true - - (str_params_actual.stdout|from_json).Exists == true - - (str_params_actual.stdout|from_json).Parameters.Application == "C:\Windows\System32\cmd.exe" - # Expected value: -v -Dtest.str=value "C:\with space\\" (backslashes doubled for jinja) - - (str_params_actual.stdout|from_json).Parameters.AppParameters == '-v -Dtest.str=value "C:\\with space\\\\"' - -- name: install service with string form parameters (idempotent) - win_nssm: - name: '{{ test_service_name }}' - application: C:\Windows\System32\cmd.exe - arguments: '-v -Dtest.str=value "C:\with space\\"' - state: present - register: str_params_again - -- name: get result of install service with string form parameters (idempotent) - win_shell: '$service = ''{{ test_service_name }}''; {{ test_service_cmd }}' - register: str_params_again_actual - -- name: assert results of install service with string form parameters (idempotent) - assert: - that: - - str_params_again.changed == false - - (str_params_again_actual.stdout|from_json).Exists == true - - (str_params_again_actual.stdout|from_json).Parameters.Application == "C:\Windows\System32\cmd.exe" - # Expected value: -v -Dtest.str=value "C:\with space\\" (backslashes doubled for jinja) - - (str_params_again_actual.stdout|from_json).Parameters.AppParameters == '-v -Dtest.str=value "C:\\with space\\\\"' - -# deprecated in 2.12 -- name: install service with dict-as-string parameters - win_nssm: - name: '{{ test_service_name }}' - application: C:\Windows\System32\cmd.exe - app_parameters: foo=true; -file.out=output.bat; -path=C:\with space\; -str=test"quotes; _=bar - register: mixed_params - -# deprecated in 2.12 -- name: get result of install service with dict-as-string parameters - win_shell: '$service = ''{{ test_service_name }}''; {{ test_service_cmd }}' - register: mixed_params_actual - -# deprecated in 2.12 -- name: assert results of install service with dict-as-string parameters - assert: - that: - - mixed_params.changed == true - - (mixed_params_actual.stdout|from_json).Exists == true - - (mixed_params_actual.stdout|from_json).Parameters.Application == "C:\Windows\System32\cmd.exe" - # Expected value: bar -file.out output.bat -str "test\"quotes" foo true -path "C:\with space\\" (backslashes doubled for jinja) - - (mixed_params_actual.stdout|from_json).Parameters.AppParameters == 'bar -file.out output.bat -str "test\\"quotes" foo true -path "C:\\with space\\\\"' - -# deprecated in 2.12 -- name: install service with dict-as-string parameters (idempotent) - win_nssm: - name: '{{ test_service_name }}' - application: C:\Windows\System32\cmd.exe - app_parameters: foo=true; -file.out=output.bat; -path=C:\with space\; -str=test"quotes; _=bar - register: mixed_params_again - -# deprecated in 2.12 -- name: get result of install service with dict-as-string parameters (idempotent) - win_shell: '$service = ''{{ test_service_name }}''; {{ test_service_cmd }}' - register: mixed_params_again_actual - -# deprecated in 2.12 -- name: assert results of install service with dict-as-string parameters (idempotent) - assert: - that: - - mixed_params_again.changed == false - - (mixed_params_again_actual.stdout|from_json).Exists == true - - (mixed_params_again_actual.stdout|from_json).Parameters.Application == "C:\Windows\System32\cmd.exe" - # Expected value: bar -file.out output.bat -str "test\"quotes" foo true -path "C:\with space\\" (backslashes doubled for jinja) - - (mixed_params_again_actual.stdout|from_json).Parameters.AppParameters == 'bar -file.out output.bat -str "test\\"quotes" foo true -path "C:\\with space\\\\"' - -- name: install service with list of parameters - win_nssm: - name: '{{ test_service_name }}' - application: C:\Windows\System32\cmd.exe - arguments: - - -foo=bar - - -day - # Test non-string value - - 14 - # Test if dot is not interpreted as separator (see #44079) - - -file.out - # Test if spaces are escaped - - C:\with space\output.bat - - -str - # Test if quotes and backslashes are escaped - - test"quotes\ - register: list_params - -- name: get result of install service with list of parameters - win_shell: '$service = ''{{ test_service_name }}''; {{ test_service_cmd }}' - register: list_params_actual - -- name: assert results of install service with list of parameters - assert: - that: - - list_params.changed == true - - (list_params_actual.stdout|from_json).Exists == true - - (list_params_actual.stdout|from_json).Parameters.Application == "C:\Windows\System32\cmd.exe" - # Expected value: -foo=bar -day 14 -file.out "C:\with space\output.bat" -str "test\"quotes\\" (backslashes doubled for jinja) - - (list_params_actual.stdout|from_json).Parameters.AppParameters == '-foo=bar -day 14 -file.out "C:\\with space\\output.bat" -str "test\\"quotes\\\\"' - -- name: install service with list of parameters (idempotent) - win_nssm: - name: '{{ test_service_name }}' - application: C:\Windows\System32\cmd.exe - arguments: - - -foo=bar - - -day - - 14 - - -file.out - - C:\with space\output.bat - - -str - - test"quotes\ - register: list_params_again - -- name: get result of install service with list of parameters (idempotent) - win_shell: '$service = ''{{ test_service_name }}''; {{ test_service_cmd }}' - register: list_params_again_actual - -- name: assert results of install service with list of parameters (idempotent) - assert: - that: - - list_params_again.changed == false - - (list_params_again_actual.stdout|from_json).Exists == true - - (list_params_again_actual.stdout|from_json).Parameters.Application == "C:\Windows\System32\cmd.exe" - # Expected value: -foo=bar -day 14 -file.out "C:\with space\output.bat" -str "test\"quotes\\" (backslashes doubled for jinja) - - (list_params_again_actual.stdout|from_json).Parameters.AppParameters == '-foo=bar -day 14 -file.out "C:\\with space\\output.bat" -str "test\\"quotes\\\\"' - -- name: remove service (check mode) - win_nssm: - name: '{{ test_service_name }}' - state: absent - register: remove_service_check - check_mode: yes - -- name: get result of remove service (check mode) - win_shell: '$service = ''{{ test_service_name }}''; {{ test_service_cmd }}' - register: remove_service_check_actual - -- name: assert results of remove service (check mode) - assert: - that: - - remove_service_check.changed == true - - (remove_service_check_actual.stdout|from_json).Exists == true - -- name: remove service - win_nssm: - name: '{{ test_service_name }}' - state: absent - register: remove_service - -- name: get result of remove service - win_shell: '$service = ''{{ test_service_name }}''; {{ test_service_cmd }}' - register: remove_service_actual - -- name: assert results of remove service - assert: - that: - - remove_service.changed == true - - (remove_service_actual.stdout|from_json).Exists == false - -- name: remove service (idempotent) - win_nssm: - name: '{{ test_service_name }}' - state: absent - register: remove_service_again - -- name: get result of remove service (idempotent) - win_shell: '$service = ''{{ test_service_name }}''; {{ test_service_cmd }}' - register: remove_service_again_actual - -- name: assert results of remove service (idempotent) - assert: - that: - - remove_service_again.changed == false - - (remove_service_again_actual.stdout|from_json).Exists == false \ No newline at end of file diff --git a/test/integration/targets/win_pagefile/aliases b/test/integration/targets/win_pagefile/aliases deleted file mode 100644 index a4da730eaa9..00000000000 --- a/test/integration/targets/win_pagefile/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group3 -unstable diff --git a/test/integration/targets/win_pagefile/tasks/main.yml b/test/integration/targets/win_pagefile/tasks/main.yml deleted file mode 100644 index 81da89d356a..00000000000 --- a/test/integration/targets/win_pagefile/tasks/main.yml +++ /dev/null @@ -1,235 +0,0 @@ ---- -# Get current pagefiles status -- name: Get original pagefile settings - win_pagefile: - state: query - register: original_pagefile_settings - -# Test 1: Set c pagefile with inital and maximum size -- name: Set C pagefile as 1024-2048MB - win_pagefile: - remove_all: yes - drive: C - initial_size: 1024 - maximum_size: 2048 - override: yes - state: present - register: c_pagefile - -- name: Test set c pagefile - assert: - that: - - c_pagefile.changed == true - -- name: Query all pagefiles - win_pagefile: - state: query - register: pagefiles_query - -- name: Set fact for pagefile expected result - set_fact: - expected: - pagefiles: - - caption: "C:\\ 'pagefile.sys'" - description: "'pagefile.sys' @ C:\\" - initial_size: 1024 - maximum_size: 2048 - name: "C:\\pagefile.sys" - -- name: Test query - c pagefile 1024-2048 - assert: - that: - - pagefiles_query.changed == false - - pagefiles_query.pagefiles == expected.pagefiles - - pagefiles_query.automatic_managed_pagefiles == false - - -# Test 2: Remove c pagefile -- name: Remove C pagefile - win_pagefile: - drive: C - state: absent - register: delete_c_pagefile - -- name: Test removal of c pagefile - assert: - that: - - delete_c_pagefile.changed == true - -- name: Query all pagefiles - win_pagefile: - state: query - register: pagefiles_query - -- name: Set fact for pagefile expected result - set_fact: - expected: - pagefiles: [] - -- name: Test query - no c pagefile - assert: - that: - - pagefiles_query.changed == false - - pagefiles_query.pagefiles == expected.pagefiles - - pagefiles_query.automatic_managed_pagefiles == false - - -# Test 3: Set automatic managed pagefile as true -- name: Set automatic managed pagefiles as true - win_pagefile: - automatic: yes - register: set_automatic_true - -- name: Test removal of c pagefile - assert: - that: - - set_automatic_true.changed == true - - set_automatic_true.automatic_managed_pagefiles == true - - -# Test 4: Set c pagefile as system managed pagefile -- name: Set c pagefile as system managed pagefile - win_pagefile: - drive: C - system_managed: yes - state: present - register: c_pagefile_system_managed - -- name: Test set c pagefile as system managed - assert: - that: - - c_pagefile_system_managed.changed == true - -- name: Query all pagefiles - win_pagefile: - state: query - register: pagefiles_query - -- name: Set fact for pagefile expected result - set_fact: - expected: - pagefiles: - - caption: "C:\\ 'pagefile.sys'" - description: "'pagefile.sys' @ C:\\" - initial_size: 0 - maximum_size: 0 - name: "C:\\pagefile.sys" - -- name: Test query - c pagefile 0-0 (system managed) - assert: - that: - - pagefiles_query.changed == false - - pagefiles_query.pagefiles == expected.pagefiles - - pagefiles_query.automatic_managed_pagefiles == false - -# Test 5: Test no override -- name: Set c pagefile 1024-1024, no override - win_pagefile: - drive: C - initial_size: 1024 - maximum_size: 1024 - override: no - state: present - register: c_pagefile_no_override - -- name: Test set c pagefile no override - assert: - that: - - c_pagefile_no_override.changed == false - -- name: Query all pagefiles - win_pagefile: - state: query - register: pagefiles_query - -- name: Test query - c pagefile unchanged - assert: - that: - - pagefiles_query.changed == false - - pagefiles_query.pagefiles == expected.pagefiles - - pagefiles_query.automatic_managed_pagefiles == false - - -# Test 6: Test override -- name: Set c pagefile 1024-1024, override - win_pagefile: - drive: C - initial_size: 1024 - maximum_size: 1024 - state: present - register: c_pagefile_override - -- name: Test set c pagefile no override - assert: - that: - - c_pagefile_override.changed == true - - # Test 7: Test idempotent -- name: Set c pagefile 1024-1024, idempotent - win_pagefile: - drive: C - initial_size: 1024 - maximum_size: 1024 - override: no - state: present - register: c_pagefile_idempotent - -- name: Test set c pagefile idempotent - assert: - that: - - c_pagefile_idempotent.changed == false - -- name: Query all pagefiles - win_pagefile: - state: query - register: pagefiles_query - -- name: Set fact for pagefile expected result - set_fact: - expected: - pagefiles: - - caption: "C:\\ 'pagefile.sys'" - description: "'pagefile.sys' @ C:\\" - initial_size: 1024 - maximum_size: 1024 - name: "C:\\pagefile.sys" - -- name: Test query - c pagefile 1024-1024 - assert: - that: - - pagefiles_query.changed == false - - pagefiles_query.pagefiles == expected.pagefiles - - pagefiles_query.automatic_managed_pagefiles == false - -# Test 7: Remove all pagefiles -- name: Remove all pagefiles - win_pagefile: - remove_all: true - register: remove_all_pagefiles - -- name: Set fact for pagefile expected result - set_fact: - expected: - pagefiles: [] - -- name: Test query - no pagefiles - assert: - that: - - remove_all_pagefiles.changed == true - - remove_all_pagefiles.pagefiles == expected.pagefiles - - pagefiles_query.automatic_managed_pagefiles == false - -# Return all pagefile settings to its original state -- name: Remove all pagefiles and return automatic to its original state - win_pagefile: - remove_all: yes - automatic: "{{ original_pagefile_settings.automatic_managed_pagefiles }}" - -- name: Return all previous pagefiles settings - win_pagefile: - drive: "{{ item.name[0] }}" - initial_size: "{{ item.initial_size }}" - maximum_size: "{{ item.maximum_size }}" - test_path: no - state: present - with_items: "{{ original_pagefile_settings.pagefiles }}" diff --git a/test/integration/targets/win_partition/aliases b/test/integration/targets/win_partition/aliases deleted file mode 100644 index 6f44e1916f7..00000000000 --- a/test/integration/targets/win_partition/aliases +++ /dev/null @@ -1,3 +0,0 @@ -shippable/windows/group7 -skip/windows/2008 -skip/windows/2008-R2 diff --git a/test/integration/targets/win_partition/defaults/main.yml b/test/integration/targets/win_partition/defaults/main.yml deleted file mode 100644 index 1d7722b5acf..00000000000 --- a/test/integration/targets/win_partition/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ -AnsibleVhdx: C:\win_partition_tests\AnsiblePart.vhdx diff --git a/test/integration/targets/win_partition/tasks/main.yml b/test/integration/targets/win_partition/tasks/main.yml deleted file mode 100644 index 46f804608b8..00000000000 --- a/test/integration/targets/win_partition/tasks/main.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- name: Create the temp directory - win_file: - path: C:\win_partition_tests - state: directory - -- name: Copy VHDX scripts - win_template: - src: "{{ item.src }}" - dest: C:\win_partition_tests\{{ item.dest }} - loop: - - { src: vhdx_creation_script.j2, dest: vhdx_creation_script.txt } - - { src: vhdx_deletion_script.j2, dest: vhdx_deletion_script.txt } - -- name: Create VHD - win_command: diskpart.exe /s C:\win_partition_tests\vhdx_creation_script.txt - -- name: Run tests - block: - - include: tests.yml - always: - - name: Detach disk - win_command: diskpart.exe /s C:\win_partition_tests\vhdx_deletion_script.txt - - - name: Cleanup files - win_file: - path: C:\win_partition_tests - state: absent diff --git a/test/integration/targets/win_partition/tasks/tests.yml b/test/integration/targets/win_partition/tasks/tests.yml deleted file mode 100644 index ebf4af81bc5..00000000000 --- a/test/integration/targets/win_partition/tasks/tests.yml +++ /dev/null @@ -1,261 +0,0 @@ ---- -- name: Since partition is not present, disk_number is required to create a new partition. - win_partition: - drive_letter: D - register: incorrect_attempt_1 - ignore_errors: True - -- assert: - that: - - incorrect_attempt_1 is failed - - '"Missing required parameter: disk_number" in incorrect_attempt_1.msg' - -- name: Added disk_number but size is still absent - win_partition: - drive_letter: D - disk_number: 0 - register: incorrect_attempt_2 - ignore_errors: True - -- assert: - that: - - incorrect_attempt_2 is failed - - '"Missing required parameter: partition_size" in incorrect_attempt_2.msg' - -- name: Added size but the disk we specified earlier doesn't have enough space - win_partition: - drive_letter: D - disk_number: 1 - partition_size: 20 GiB - register: incorrect_attempt_3 - ignore_errors: True - -- assert: - that: - - incorrect_attempt_3 is failed - - '"Partition size is not supported by disk" in incorrect_attempt_3.msg' - -- name: Create 1 gib partition using drive_letter and default (huge) mbr type (check mode) - win_partition: - drive_letter: D - state: present - partition_size: 1 GiB - disk_number: 1 - active: True - register: create_small_part_check - check_mode: True - -- name: Create 1 gib partition using drive_letter and default (huge) mbr type - win_partition: - drive_letter: D - state: present - partition_size: 1 GiB - disk_number: 1 - active: True - register: create_small_part - -- name: Create 1 gib partition using drive_letter and default (huge) mbr type (idempotence) - win_partition: - drive_letter: D - state: present - partition_size: 1 GiB - disk_number: 1 - active: True - register: create_small_part_idempotence - -- name: "Check if partition was created successfully" - win_shell: $AnsiPart = Get-Partition -DriveLetter D; "$($AnsiPart.DriveLetter),$($AnsiPart.Size),$($AnsiPart.IsActive),$($AnsiPart.MbrType)" - register: get_small_part - -- assert: - that: - - create_small_part_check is changed - - create_small_part is changed - - create_small_part_idempotence is not changed - - get_small_part.stdout | trim == "D,1073741824,True,6" - -- name: "Change drive letter, maximize partition size and set partition to read only (check mode)" - win_partition: - drive_letter: E - state: present - partition_size: -1 - disk_number: 1 - partition_number: 1 - read_only: True - register: upgrade_small_part_check - check_mode: True - -- name: "Change drive letter, maximize partition size and set partition to read only" - win_partition: - drive_letter: E - state: present - partition_size: -1 - disk_number: 1 - partition_number: 1 - read_only: True - register: upgrade_small_part - -- name: "Change drive letter, maximize partition size and set partition to read only (idempotence)" - win_partition: - drive_letter: E - state: present - partition_size: -1 - disk_number: 1 - partition_number: 1 - read_only: True - register: upgrade_small_part_idempotence - -- win_shell: $AnsiPart = Get-Partition -DriveLetter E; "$($AnsiPart.DriveLetter),$($AnsiPart.Size),$($AnsiPart.IsReadOnly)" - register: get_max_part - -- name: Check if creation and updation were successful - assert: - that: - - upgrade_small_part_check is changed - - upgrade_small_part is changed - - upgrade_small_part_idempotence is not changed - - get_max_part.stdout | trim == "E,2096037888,True" - -- name: "Changing size of a read only partition" - win_partition: - drive_letter: E - partition_size: 1 GiB - register: modify_read_only_partition - ignore_errors: True - -- assert: - that: - - modify_read_only_partition is failed - -- name: "Delete partition (check mode)" - win_partition: - disk_number: 1 - partition_number: 1 - state: absent - register: delete_partition_check - check_mode: True - -- name: "Delete partition" - win_partition: - disk_number: 1 - partition_number: 1 - state: absent - register: delete_partition - -- name: "Delete partition (idempotence)" - win_partition: - disk_number: 1 - partition_number: 1 - state: absent - register: delete_partition_idempotence - -- name: "Confirm that the partition is absent" - win_shell: Get-Partition -DiskNumber 1 -PartitionNumber 1 - register: confirm_partition_deletion - ignore_errors: True - -- assert: - that: - - delete_partition_check is changed - - delete_partition is changed - - delete_partition_idempotence is not changed - - '"No matching MSFT_Partition objects found" in confirm_partition_deletion.stderr' - -- name: "Create new partition without drive letter and ifs mbr type (check mode)" - win_partition: - disk_number: 1 - partition_size: -1 - mbr_type: ifs - offline: True - register: recreate_partition_check - check_mode: True - -- name: "Create new partition without drive letter and ifs mbr type" - win_partition: - disk_number: 1 - partition_size: -1 - mbr_type: ifs - offline: True - register: recreate_partition - -- name: "Create new partition without drive letter and ifs mbr type (idempotence failure)" # Disk is full now; no idempotence without drive letters - win_partition: - disk_number: 1 - partition_size: -1 - mbr_type: ifs - offline: True - register: recreate_partition_idempotence_failure - ignore_errors: True - -- name: "Confirm that new partition is created with maximum size, is offline and is IFS" - win_shell: $AnsiPart = Get-Partition -DiskNumber 1 -PartitionNumber 1; "$($AnsiPart.Size),$($AnsiPart.IsOffline),$($AnsiPart.MbrType)" - register: confirm_recreate_partition - -- assert: - that: - - recreate_partition_check is changed - - recreate_partition is changed - - recreate_partition_idempotence_failure is failed - - confirm_recreate_partition.stdout | trim == "2096037888,True,7" - -- name: "Adding a drive letter to our partition should bring it back online (check mode)" - win_partition: - drive_letter: D - disk_number: 1 - partition_number: 1 - register: add_drive_letter_check - ignore_errors: True - check_mode: True - -- name: "Adding a drive letter to our partition should bring it back online" - win_partition: - drive_letter: D - disk_number: 1 - partition_number: 1 - register: add_drive_letter - ignore_errors: True - -- name: "Adding a drive letter to our partition should bring it back online (idempotence)" - win_partition: - drive_letter: D - disk_number: 1 - partition_number: 1 - register: add_drive_letter_idempotence - ignore_errors: True - -- name: "Confirm that drive is back online" - win_shell: $AnsiPart = Get-Partition -DiskNumber 1 -PartitionNumber 1; "$($AnsiPart.DriveLetter),$($AnsiPart.IsOffline)" - register: confirm_add_drive_letter - ignore_errors: True - -- assert: - that: - - add_drive_letter_check is changed - - add_drive_letter is changed - - add_drive_letter_idempotence is not changed - - confirm_add_drive_letter.stdout | trim == "D,False" - -- name: "Remove partition again (check mode)" - win_partition: - drive_letter: D - state: absent - register: delete_partition_again_check - check_mode: True - -- name: "Remove partition again" - win_partition: - drive_letter: D - state: absent - register: delete_partition_again - -- name: "Remove partition again (idempotence)" - win_partition: - drive_letter: D - state: absent - register: delete_partition_again_idempotence - -- assert: - that: - - delete_partition_again_check is changed - - delete_partition_again is changed - - delete_partition_again_idempotence is not changed diff --git a/test/integration/targets/win_partition/templates/vhdx_creation_script.j2 b/test/integration/targets/win_partition/templates/vhdx_creation_script.j2 deleted file mode 100644 index 905373be1e1..00000000000 --- a/test/integration/targets/win_partition/templates/vhdx_creation_script.j2 +++ /dev/null @@ -1,7 +0,0 @@ -create vdisk file="{{ AnsibleVhdx }}" maximum=2000 type=fixed - -select vdisk file="{{ AnsibleVhdx }}" - -attach vdisk - -convert mbr diff --git a/test/integration/targets/win_partition/templates/vhdx_deletion_script.j2 b/test/integration/targets/win_partition/templates/vhdx_deletion_script.j2 deleted file mode 100644 index c2be9cd1446..00000000000 --- a/test/integration/targets/win_partition/templates/vhdx_deletion_script.j2 +++ /dev/null @@ -1,3 +0,0 @@ -select vdisk file="{{ AnsibleVhdx }}" - -detach vdisk diff --git a/test/integration/targets/win_pester/aliases b/test/integration/targets/win_pester/aliases deleted file mode 100644 index 423ce391085..00000000000 --- a/test/integration/targets/win_pester/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group2 diff --git a/test/integration/targets/win_pester/defaults/main.yml b/test/integration/targets/win_pester/defaults/main.yml deleted file mode 100644 index 3507a0fda98..00000000000 --- a/test/integration/targets/win_pester/defaults/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -test_win_pester_path: C:\ansible\win_pester -test_report_file: c:\ansible\win_pester\test_report.xml diff --git a/test/integration/targets/win_pester/files/fail.ps1 b/test/integration/targets/win_pester/files/fail.ps1 deleted file mode 100644 index 4bd20a601c3..00000000000 --- a/test/integration/targets/win_pester/files/fail.ps1 +++ /dev/null @@ -1,2 +0,0 @@ -# This makes sure that a file that does not end with *.test.ps1 does not run -throw "should never fail" diff --git a/test/integration/targets/win_pester/files/test01.tests.ps1 b/test/integration/targets/win_pester/files/test01.tests.ps1 deleted file mode 100644 index edba4db1f66..00000000000 --- a/test/integration/targets/win_pester/files/test01.tests.ps1 +++ /dev/null @@ -1,5 +0,0 @@ -Describe -Name 'Test01' { - It -name 'First Test' { - {Get-Service} | Should Not Throw - } -} \ No newline at end of file diff --git a/test/integration/targets/win_pester/files/test02.tests.ps1 b/test/integration/targets/win_pester/files/test02.tests.ps1 deleted file mode 100644 index 2ec2450a58c..00000000000 --- a/test/integration/targets/win_pester/files/test02.tests.ps1 +++ /dev/null @@ -1,5 +0,0 @@ -Describe -Name 'Test02' { - It -name 'Second Test' { - {Get-Service} | Should Throw - } -} \ No newline at end of file diff --git a/test/integration/targets/win_pester/files/test03.tests.ps1 b/test/integration/targets/win_pester/files/test03.tests.ps1 deleted file mode 100644 index 000155ccad0..00000000000 --- a/test/integration/targets/win_pester/files/test03.tests.ps1 +++ /dev/null @@ -1,11 +0,0 @@ -Describe -Name 'Test03 without tag' { - It -name 'Third Test without tag' { - {Get-Service} | Should Not Throw - } -} - -Describe -Name 'Test03 with tag' -Tag tag1 { - It -name 'Third Test with tag' { - {Get-Service} | Should Not Throw - } -} \ No newline at end of file diff --git a/test/integration/targets/win_pester/files/test04.tests.ps1 b/test/integration/targets/win_pester/files/test04.tests.ps1 deleted file mode 100644 index 07d1bd43c5c..00000000000 --- a/test/integration/targets/win_pester/files/test04.tests.ps1 +++ /dev/null @@ -1,18 +0,0 @@ -Param( - $Service, - $Process -) - -Describe "Process should exist" { - it "Process $Process should be running" -Skip:([String]::IsNullOrEmpty($Process)) { - Get-Process -Name $Process -ErrorAction SilentlyContinue | Should Not BeNullOrEmpty - } -} - - - -Describe "Service should exist" -tag Service { - it "Service $Service should exist" -Skip:([String]::IsNullOrEmpty($Service)) { - Get-Service -Name $Service -ErrorAction SilentlyContinue | Should Not BeNullOrEmpty - } -} diff --git a/test/integration/targets/win_pester/tasks/main.yml b/test/integration/targets/win_pester/tasks/main.yml deleted file mode 100644 index ca04a1fe5a2..00000000000 --- a/test/integration/targets/win_pester/tasks/main.yml +++ /dev/null @@ -1,56 +0,0 @@ ---- -- name: create test folder(s) - win_file: - path: '{{test_win_pester_path}}\{{item}}' - state: directory - with_items: - - Modules - - Tests - -- name: download Pester module from S3 bucket - win_get_url: - # this was downloaded straight off the Pester GitHub release page and uploaded to the S3 bucket - # https://github.com/pester/Pester/releases - url: 'https://ansible-ci-files.s3.amazonaws.com/test/integration/roles/test_win_pester/Pester-4.3.1.zip' - dest: '{{test_win_pester_path}}\Pester-4.3.1.zip' - -- name: unzip Pester module - win_unzip: - src: '{{test_win_pester_path}}\Pester-4.3.1.zip' - dest: '{{test_win_pester_path}}\Modules' - -- name: rename extracted zip to match module name - win_shell: Rename-Item -Path '{{test_win_pester_path}}\Modules\Pester-4.3.1' -NewName Pester - -- name: add custom Pester location to the PSModulePath - win_path: - name: PSModulePath - scope: machine - state: present - elements: - - '{{test_win_pester_path}}\Modules' - -- name: copy test files - win_copy: - src: files/ - dest: '{{test_win_pester_path}}\Tests' - -- block: - - name: run Pester tests - include_tasks: test.yml - vars: - test_path: '{{ test_win_pester_path }}\Tests' - - always: - - name: remove custom pester location on the PSModulePath - win_path: - name: PSModulePath - scope: machine - state: absent - elements: - - '{{test_win_pester_path}}\Modules' - - - name: delete test folder - win_file: - path: '{{test_win_pester_path}}' - state: absent diff --git a/test/integration/targets/win_pester/tasks/test.yml b/test/integration/targets/win_pester/tasks/test.yml deleted file mode 100644 index 6268633b27e..00000000000 --- a/test/integration/targets/win_pester/tasks/test.yml +++ /dev/null @@ -1,134 +0,0 @@ ---- -- name: Run Pester test(s) specifying a fake test file - win_pester: - path: '{{test_path}}\fakefile.ps1' - register: fake_file - failed_when: '"Cannot find file or directory: ''" + test_path + "\\fakefile.ps1'' as it does not exist" not in fake_file.msg' - -- name: Run Pester test(s) specifying a fake folder - win_pester: - path: '{{test_path }}\fakedir' - register: fake_folder - failed_when: '"Cannot find file or directory: ''" + test_path + "\\fakedir'' as it does not exist" not in fake_folder.msg' - -- name: Run Pester test(s) specifying a test file and a higher pester version - win_pester: - path: '{{test_path}}\test01.tests.ps1' - minimum_version: '6.0.0' - register: invalid_version - failed_when: '"Pester version is not greater or equal to 6.0.0" not in invalid_version.msg' - -- name: Run Pester test(s) specifying a test file - win_pester: - path: '{{test_path}}\test01.tests.ps1' - register: file_result - -- name: assert Run Pester test(s) specify a test file - assert: - that: - - file_result.changed - - not file_result.failed - - file_result.output.TotalCount == 1 - -- name: Run Pester test(s) specifying a test file and with a minimum mandatory Pester version - win_pester: - path: '{{test_path}}\test01.tests.ps1' - minimum_version: 3.0.0 - register: file_result_with_version - -- name: assert Run Pester test(s) specifying a test file and a minimum mandatory Pester version - assert: - that: - - file_result_with_version.changed - - not file_result_with_version.failed - - file_result_with_version.output.TotalCount == 1 - -- name: Run Pester test(s) located in a folder. Folder path end with '\' - win_pester: - path: '{{test_path}}\' - register: dir_with_ending_slash - -- name: assert Run Pester test(s) located in a folder. Folder path end with '\' - assert: - that: - - dir_with_ending_slash.changed - - not dir_with_ending_slash.failed - - dir_with_ending_slash.output.TotalCount == 6 - -- name: Run Pester test(s) located in a folder. Folder path does not end with '\' - win_pester: - path: '{{test_path}}' - register: dir_without_ending_slash - -- name: assert Run Pester test(s) located in a folder. Folder does not end with '\' - assert: - that: - - dir_without_ending_slash.changed - - not dir_without_ending_slash.failed - - dir_without_ending_slash.output.TotalCount == 6 - -- name: Run Pester test(s) located in a folder and with a minimum mandatory Pester version - win_pester: - path: '{{test_path}}' - minimum_version: 3.0.0 - register: dir_with_version - -- name: assert Run Pester test(s) located in a folder and with a minimum mandatory Pester version - assert: - that: - - dir_with_version.changed - - not dir_with_version.failed - - dir_with_version.output.TotalCount == 6 - -- name: Run Pester test(s) specifying a test file without specifying tag - win_pester: - path: '{{test_path}}\test03.tests.ps1' - register: test_no_tag - -- name: assert Run Pester test(s) specifying a test file and all tests executed - assert: - that: - - test_no_tag.changed - - test_no_tag.output.TotalCount == 2 - -- name: Run Pester test(s) specifying a test file with tag - win_pester: - path: '{{test_path}}\test03.tests.ps1' - tags: tag1 - register: test_with_tag - -- name: Run Pester test(s) specifying a test file and only test with sepecified tag executed - assert: - that: - - test_with_tag.changed - - test_with_tag.output.TotalCount == 1 - -- name: Run Pester test(s) specifying a test file with parameters - win_pester: - path: '{{test_path}}\test04.tests.ps1' - test_parameters: - Process: lsass - Service: bits - register: test_with_parameter - -- name: Run Pester test(s) specifying a test file with parameters - assert: - that: - - test_with_parameter.changed - - test_with_parameter.output.PassedCount == 2 - - test_with_parameter.output.TotalCount == 2 - -- name: Run Pester test(s) specifying a test file by generating test result xml - win_pester: - path: '{{test_path}}\test03.tests.ps1' - output_file: '{{test_report_file}}' - -- name: Checks if the output result file exists - win_stat: - path: '{{test_report_file}}' - register: test_output_file - -- name: Checks if the output result file exists - assert: - that: - - test_output_file.stat.exists diff --git a/test/integration/targets/win_power_plan/aliases b/test/integration/targets/win_power_plan/aliases deleted file mode 100644 index 423ce391085..00000000000 --- a/test/integration/targets/win_power_plan/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group2 diff --git a/test/integration/targets/win_power_plan/tasks/main.yml b/test/integration/targets/win_power_plan/tasks/main.yml deleted file mode 100644 index 000d8b1a662..00000000000 --- a/test/integration/targets/win_power_plan/tasks/main.yml +++ /dev/null @@ -1,64 +0,0 @@ -# I dislike this but 2008 doesn't support the Win32_PowerPlan WMI provider -- name: get current plan details - win_shell: | - $plan_info = powercfg.exe /list - ($plan_info | Select-String -Pattern '\(([\w\s]*)\) \*$').Matches.Groups[1].Value - ($plan_info | Select-String -Pattern '\(([\w\s]*)\)$').Matches.Groups[1].Value - register: plan_info - -- set_fact: - original_plan: '{{ plan_info.stdout_lines[0] }}' - name: '{{ plan_info.stdout_lines[1] }}' - -- block: - #Test that plan detects change is needed, but doesn't actually apply change - - name: set power plan (check mode) - win_power_plan: - name: "{{ name }}" - register: set_plan_check - check_mode: yes - - - name: get result of set power plan (check mode) - win_shell: (powercfg.exe /list | Select-String -Pattern '\({{ name }}\)').Line - register: set_plan_check_result - changed_when: False - - # verify that the powershell check is showing the plan as still inactive on the system - - name: assert setting plan (check mode) - assert: - that: - - set_plan_check is changed - - not set_plan_check_result.stdout_lines[0].endswith('*') - - #Test that setting plan and that change is applied - - name: set power plan - win_power_plan: - name: "{{ name }}" - register: set_plan - - - name: get result of set power plan - win_shell: (powercfg.exe /list | Select-String -Pattern '\({{ name }}\)').Line - register: set_plan_result - changed_when: False - - - name: assert setting plan - assert: - that: - - set_plan is changed - - set_plan_result.stdout_lines[0].endswith('*') - - #Test that plan doesn't apply change if it is already set - - name: set power plan (idempotent) - win_power_plan: - name: "{{ name }}" - register: set_plan_idempotent - - - name: assert setting plan (idempotent) - assert: - that: - - set_plan_idempotent is not changed - - always: - - name: always change back plan to the original when done testing - win_power_plan: - name: '{{ original_plan }}' diff --git a/test/integration/targets/win_product_facts/aliases b/test/integration/targets/win_product_facts/aliases deleted file mode 100644 index 3cf5b97e805..00000000000 --- a/test/integration/targets/win_product_facts/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_product_facts/tasks/main.yml b/test/integration/targets/win_product_facts/tasks/main.yml deleted file mode 100644 index b1427eeaa15..00000000000 --- a/test/integration/targets/win_product_facts/tasks/main.yml +++ /dev/null @@ -1,11 +0,0 @@ -# This file is part of Ansible - -# Copyright: (c) 2017, Dag Wieers (dagwieers) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- win_product_facts: - -- assert: - that: - - ansible_os_product_id is defined - - ansible_os_product_key is defined diff --git a/test/integration/targets/win_psexec/aliases b/test/integration/targets/win_psexec/aliases deleted file mode 100644 index 3cf5b97e805..00000000000 --- a/test/integration/targets/win_psexec/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_psexec/meta/main.yml b/test/integration/targets/win_psexec/meta/main.yml deleted file mode 100644 index 9f37e96cd90..00000000000 --- a/test/integration/targets/win_psexec/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: -- setup_remote_tmp_dir diff --git a/test/integration/targets/win_psexec/tasks/main.yml b/test/integration/targets/win_psexec/tasks/main.yml deleted file mode 100644 index 27783f9e62a..00000000000 --- a/test/integration/targets/win_psexec/tasks/main.yml +++ /dev/null @@ -1,80 +0,0 @@ -# Would use [] but this has troubles with PATH and trying to find the executable so just resort to keeping a space -- name: record special path for tests - set_fact: - testing_dir: '{{ remote_tmp_dir }}\ansible win_psexec' - -- name: create special path testing dir - win_file: - path: '{{ testing_dir }}' - state: directory - -- name: Download PsExec - win_get_url: - url: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/win_psexec/PsExec.exe - dest: '{{ testing_dir }}\PsExec.exe' - -- name: Get the existing PATH env var - win_shell: '$env:PATH' - register: system_path - changed_when: False - -- name: Run whoami - win_psexec: - command: whoami.exe - nobanner: true - register: whoami - environment: - PATH: '{{ testing_dir }};{{ system_path.stdout | trim }}' - -- name: Test whoami - assert: - that: - - whoami.rc == 0 - - whoami.stdout == '' - # FIXME: Standard output does not work or is truncated - #- whoami.stdout == '{{ ansible_hostname|lower }}' - -- name: Run whoami as SYSTEM - win_psexec: - command: whoami.exe - system: yes - nobanner: true - executable: '{{ testing_dir }}\PsExec.exe' - register: whoami_as_system - # Seems to be a bug with PsExec where the stdout can be empty, just retry the task to make this test a bit more stable - until: whoami_as_system.rc == 0 and whoami_as_system.stdout == 'nt authority\system' - retries: 3 - delay: 2 - -# FIXME: Behaviour is not consistent on all Windows systems -#- name: Run whoami as ELEVATED -# win_psexec: -# command: whoami.exe -# elevated: yes -# register: whoami_as_elevated -# -## Ensure we have basic facts -#- setup: -# -#- debug: -# msg: '{{ whoami_as_elevated.stdout|lower }} == {{ ansible_hostname|lower }}\{{ ansible_user_id|lower }}' -# -#- name: Test whoami -# assert: -# that: -# - whoami_as_elevated.rc == 0 -# - whoami_as_elevated.stdout|lower == '{{ ansible_hostname|lower }}\{{ ansible_user_id|lower }}' - -- name: Run command with multiple arguments - win_psexec: - command: powershell.exe -NonInteractive "exit 1" - ignore_errors: yes - register: whoami_multiple_args - environment: - PATH: '{{ testing_dir }};{{ system_path.stdout | trim }}' - -- name: Test command with multiple argumetns - assert: - that: - - whoami_multiple_args.rc == 1 - - whoami_multiple_args.psexec_command == "psexec.exe -accepteula powershell.exe -NonInteractive \"exit 1\"" diff --git a/test/integration/targets/win_psmodule/aliases b/test/integration/targets/win_psmodule/aliases deleted file mode 100644 index 4c08975b17d..00000000000 --- a/test/integration/targets/win_psmodule/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group6 diff --git a/test/integration/targets/win_psmodule/files/module/template.nuspec b/test/integration/targets/win_psmodule/files/module/template.nuspec deleted file mode 100644 index 49fc53210f7..00000000000 --- a/test/integration/targets/win_psmodule/files/module/template.nuspec +++ /dev/null @@ -1,14 +0,0 @@ - - - - --- NAME --- - --- VERSION --- - Ansible - Ansible - false - Test for Ansible win_ps* modules - - Copyright (c) 2019 Ansible, licensed under MIT. - PSModule PSIncludes_Function PSFunction_--- FUNCTION --- PSCommand_--- FUNCTION --- - - diff --git a/test/integration/targets/win_psmodule/files/module/template.psd1 b/test/integration/targets/win_psmodule/files/module/template.psd1 deleted file mode 100644 index cd6709722b4..00000000000 --- a/test/integration/targets/win_psmodule/files/module/template.psd1 +++ /dev/null @@ -1,17 +0,0 @@ -@{ - RootModule = '--- NAME ---.psm1' - ModuleVersion = '--- VERSION ---' - GUID = '--- GUID ---' - Author = 'Ansible' - Copyright = 'Copyright (c) 2019 Ansible, licensed under MIT.' - Description = "Test for Ansible win_ps* modules" - PowerShellVersion = '3.0' - FunctionsToExport = @( - "--- FUNCTION ---" - ) - PrivateData = @{ - PSData = @{ ---- PS_DATA --- - } - } -} diff --git a/test/integration/targets/win_psmodule/files/module/template.psm1 b/test/integration/targets/win_psmodule/files/module/template.psm1 deleted file mode 100644 index ac38fb5ed62..00000000000 --- a/test/integration/targets/win_psmodule/files/module/template.psm1 +++ /dev/null @@ -1,10 +0,0 @@ -Function --- FUNCTION --- { - return [PSCustomObject]@{ - Name = "--- NAME ---" - Version = "--- VERSION ---" - Repo = "--- REPO ---" - } -} - -Export-ModuleMember -Function --- FUNCTION --- - diff --git a/test/integration/targets/win_psmodule/files/openssl.conf b/test/integration/targets/win_psmodule/files/openssl.conf deleted file mode 100644 index 2b5685b432c..00000000000 --- a/test/integration/targets/win_psmodule/files/openssl.conf +++ /dev/null @@ -1,9 +0,0 @@ -distinguished_name = req_distinguished_name - -[req_distinguished_name] - -[req_sign] -subjectKeyIdentifier=hash -basicConstraints = CA:FALSE -keyUsage = digitalSignature -extendedKeyUsage = codeSigning diff --git a/test/integration/targets/win_psmodule/files/setup_certs.sh b/test/integration/targets/win_psmodule/files/setup_certs.sh deleted file mode 100644 index 25856731611..00000000000 --- a/test/integration/targets/win_psmodule/files/setup_certs.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -# Generate key used for CA cert -openssl genrsa -aes256 -out ca.key -passout pass:password 2048 - -# Generate CA certificate -openssl req -new -x509 -days 365 -key ca.key -out ca.pem -subj "/CN=Ansible Root" -passin pass:password - -# Generate key used for signing cert -openssl genrsa -aes256 -out sign.key -passout pass:password 2048 - -# Generate CSR for signing cert that includes CodeSiging extension -openssl req -new -key sign.key -out sign.csr -subj "/CN=Ansible Sign" -config openssl.conf -reqexts req_sign -passin pass:password - -# Generate signing certificate -openssl x509 -req -in sign.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out sign.pem -days 365 -extfile openssl.conf -extensions req_sign -passin pass:password - -# Create pfx that includes signing cert and cert with the pass 'password' -openssl pkcs12 -export -out sign.pfx -inkey sign.key -in sign.pem -passin pass:password -passout pass:password diff --git a/test/integration/targets/win_psmodule/files/setup_modules.ps1 b/test/integration/targets/win_psmodule/files/setup_modules.ps1 deleted file mode 100644 index dcd3bae443f..00000000000 --- a/test/integration/targets/win_psmodule/files/setup_modules.ps1 +++ /dev/null @@ -1,81 +0,0 @@ -$ErrorActionPreference = "Stop" - -$template_path = $args[0] -$template_manifest = Join-Path -Path $template_path -ChildPath template.psd1 -$template_script = Join-Path -Path $template_path -ChildPath template.psm1 -$template_nuspec = Join-Path -Path $template_path -ChildPath template.nuspec -$nuget_exe = Join-Path -Path $template_path -ChildPath nuget.exe -$sign_cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList @( - (Join-Path -Path $template_path -ChildPath sign.pfx), - 'password', - # We need to use MachineKeySet so we can load the pfx without using become - # EphemeralKeySet would be better but it is only available starting with .NET 4.7.2 - [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet -) - -$packages = @( - @{ name = "ansible-test1"; version = "1.0.0"; repo = "PSRepo 1"; function = "Get-AnsibleTest1" }, - @{ name = "ansible-test1"; version = "1.0.5"; repo = "PSRepo 1"; function = "Get-AnsibleTest1" }, - @{ name = "ansible-test1"; version = "1.1.0"; repo = "PSRepo 1"; function = "Get-AnsibleTest1" }, - @{ name = "ansible-test2"; version = "1.0.0"; repo = "PSRepo 1"; function = "Get-AnsibleTest2" }, - @{ name = "ansible-test2"; version = "1.0.0"; repo = "PSRepo 2"; function = "Get-AnsibleTest2" }, - @{ name = "ansible-test2"; version = "1.0.1"; repo = "PSRepo 1"; function = "Get-AnsibleTest2"; signed = $false }, - @{ name = "ansible-test2"; version = "1.1.0"; prerelease = "beta1"; repo = "PSRepo 1"; function = "Get-AnsibleTest2" }, - @{ name = "ansible-clobber"; version = "0.1.0"; repo = "PSRepo 1"; function = "Enable-PSTrace" } -) - -foreach ($package in $packages) { - $tmp_dir = Join-Path -Path $template_path -ChildPath $package.name - if (Test-Path -Path $tmp_dir) { - Remove-Item -Path $tmp_dir -Force -Recurse - } - New-Item -Path $tmp_dir -ItemType Directory > $null - - try { - if ($package.ContainsKey("prerelease")) { - $ps_data = "Prerelease = '$($package.prerelease)'" - $nuget_version = "$($package.version)-$($package.prerelease)" - } else { - $ps_data = "" - $nuget_version = $package.version - } - - $manifest = [System.IO.File]::ReadAllText($template_manifest) - $manifest = $manifest.Replace('--- NAME ---', $package.name).Replace('--- VERSION ---', $package.version) - $manifest = $manifest.Replace('--- GUID ---', [Guid]::NewGuid()).Replace('--- FUNCTION ---', $package.function) - - $manifest = $manifest.Replace('--- PS_DATA ---', $ps_data) - $manifest_path = Join-Path -Path $tmp_dir -ChildPath "$($package.name).psd1" - Set-Content -Path $manifest_path -Value $manifest - - $script = [System.IO.File]::ReadAllText($template_script) - $script = $script.Replace('--- NAME ---', $package.name).Replace('--- VERSION ---', $package.version) - $script = $script.Replace('--- REPO ---', $package.repo).Replace('--- FUNCTION ---', $package.function) - $script_path = Join-Path -Path $tmp_dir -ChildPath "$($package.name).psm1" - Set-Content -Path $script_path -Value $script - - $signed = if ($package.ContainsKey("signed")) { $package.signed } else { $true } - if ($signed) { - Set-AuthenticodeSignature -Certificate $sign_cert -LiteralPath $manifest_path > $null - Set-AuthenticodeSignature -Certificate $sign_cert -LiteralPath $script_path > $null - } - - # We should just be able to use Publish-Module but it fails when running over WinRM for older hosts and become - # does not fix this. It fails to respond to nuget.exe push errors when it canno find the .nupkg file. We will - # just manually do that ourselves. This also has the added benefit of being a lot quicker than Publish-Module - # which seems to take forever to publish the module. - $nuspec = [System.IO.File]::ReadAllText($template_nuspec) - $nuspec = $nuspec.Replace('--- NAME ---', $package.name).Replace('--- VERSION ---', $nuget_version) - $nuspec = $nuspec.Replace('--- FUNCTION ---', $package.function) - Set-Content -Path (Join-Path -Path $tmp_dir -ChildPath "$($package.name).nuspec") -Value $nuspec - - &$nuget_exe pack "$tmp_dir\$($package.name).nuspec" -outputdirectory $tmp_dir - - $repo_path = Join-Path -Path $template_path -ChildPath $package.repo - $nupkg_filename = "$($package.name).$($nuget_version).nupkg" - Copy-Item -Path (Join-Path -Path $tmp_dir -ChildPath $nupkg_filename) ` - -Destination (Join-Path -Path $repo_path -ChildPath $nupkg_filename) - } finally { - Remove-Item -Path $tmp_dir -Force -Recurse - } -} diff --git a/test/integration/targets/win_psmodule/handlers/main.yml b/test/integration/targets/win_psmodule/handlers/main.yml deleted file mode 100644 index a3fd646da5c..00000000000 --- a/test/integration/targets/win_psmodule/handlers/main.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -- name: re-add PSGallery repository - win_shell: Register-PSRepository -Default -InstallationPolicy Untrusted - -- name: remove registered repos - win_psrepository: - name: '{{ item }}' - state: absent - loop: - - PSRepo 1 - - PSRepo 2 - -- name: remove CA cert from trusted root store - win_certificate_store: - thumbprint: '{{ ca_cert_import.thumbprints[0] }}' - store_location: LocalMachine - store_name: Root - state: absent - -- name: remove signing key from trusted publisher store - win_certificate_store: - thumbprint: '{{ sign_cert_import.thumbprints[0] }}' - store_location: LocalMachine - store_name: TrustedPublisher - state: absent - -- name: remove test packages - win_psmodule: - name: '{{ item }}' - state: absent - loop: - - ansible-test1 - - ansible-test2 - - ansible-clobber \ No newline at end of file diff --git a/test/integration/targets/win_psmodule/meta/main.yml b/test/integration/targets/win_psmodule/meta/main.yml deleted file mode 100644 index f0920878aef..00000000000 --- a/test/integration/targets/win_psmodule/meta/main.yml +++ /dev/null @@ -1,3 +0,0 @@ -dependencies: -- setup_remote_tmp_dir -- setup_win_psget diff --git a/test/integration/targets/win_psmodule/tasks/main.yml b/test/integration/targets/win_psmodule/tasks/main.yml deleted file mode 100644 index 2d7c1843513..00000000000 --- a/test/integration/targets/win_psmodule/tasks/main.yml +++ /dev/null @@ -1,454 +0,0 @@ -# test code for the win_psmodule module when using winrm connection -# Copyright: (c) 2018, Wojciech Sciesinski -# Copyright: (c) 2017, Daniele Lazzari -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) ---- -- name: setup test repos and modules - import_tasks: setup.yml - -# Remove the below task in Ansible 2.12 -- name: ensure warning is fired when adding a repo - win_psmodule: - name: ansible-test1 - repository: some repo - url: '{{ remote_tmp_dir }}' - state: present - register: dep_repo_add - ignore_errors: yes # will fail because this repo doesn't actually have this module - check_mode: yes - -- name: assert warning is fired when adding a repo - assert: - that: - - dep_repo_add is changed - - dep_repo_add.deprecations|length == 1 - - dep_repo_add.deprecations[0].msg == 'Adding a repo with this module is deprecated, the repository parameter should only be used to select a repo. Use win_psrepository to manage repos' - - dep_repo_add.deprecations[0].version == 2.12 - -- name: install package (check mode) - win_psmodule: - name: ansible-test1 - state: present - register: install_check - check_mode: yes - -- name: get result of install package (check mode) - win_shell: (Get-Module -ListAvailable -Name ansible-test1 | Measure-Object).Count - register: install_actual_check - -- name: assert install package (check mode) - assert: - that: - - install_check is changed - - install_actual_check.stdout | trim | int == 0 - -- name: install package - win_psmodule: - name: ansible-test1 - state: present - register: install - -- name: get result of install package - win_shell: Import-Module -Name ansible-test1; Get-AnsibleTest1 | ConvertTo-Json - register: install_actual - -- name: assert install package - assert: - that: - - install is changed - - install_actual.stdout | from_json == {"Name":"ansible-test1","Version":"1.1.0","Repo":"PSRepo 1"} - -- name: install package (idempotent) - win_psmodule: - name: ansible-test1 - state: present - register: install_again - -- name: assert install package (idempotent) - assert: - that: - - not install_again is changed - -- name: remove package (check mode) - win_psmodule: - name: ansible-test1 - state: absent - register: remove_check - check_mode: yes - -- name: get result of remove package (check mode) - win_shell: (Get-Module -ListAvailable -Name ansible-test1 | Measure-Object).Count - register: remove_actual_check - -- name: remove package (check mode) - assert: - that: - - remove_check is changed - - remove_actual_check.stdout | trim | int == 1 - -- name: remove package - win_psmodule: - name: ansible-test1 - state: absent - register: remove - -- name: get result of remove package - win_shell: (Get-Module -ListAvailable -Name ansible-test1 | Measure-Object).Count - register: remove_actual - -- name: assert remove package - assert: - that: - - remove is changed - - remove_actual.stdout | trim | int == 0 - -- name: remove package (idempotent) - win_psmodule: - name: ansible-test1 - state: absent - register: remove_again - -- name: assert remove package (idempotent) - assert: - that: - - not remove_again is changed - -- name: fail to install module that exists in multiple repos - win_psmodule: - name: ansible-test2 - state: present - register: fail_multiple_pkg - failed_when: 'fail_multiple_pkg.msg != "Problems installing ansible-test2 module: Unable to install, multiple modules matched ''ansible-test2''. Please specify a single -Repository."' - -- name: install module with specific repository - win_psmodule: - name: ansible-test2 - repository: PSRepo 2 - state: present - register: install_repo - -- name: get result of install module with specific repository - win_shell: Import-Module -Name ansible-test2; Get-AnsibleTest2 | ConvertTo-Json - register: install_repo_actual - -- name: assert install module with specific repository - assert: - that: - - install_repo is changed - - install_repo_actual.stdout | from_json == {"Name":"ansible-test2","Version":"1.0.0","Repo":"PSRepo 2"} - -- name: install module with specific repository (idempotent) - win_psmodule: - name: ansible-test2 - repository: PSRepo 2 - state: present - register: install_repo_again - -- name: assert install module with specific repository (idempotent) - assert: - that: - - not install_repo_again is changed - -- name: remove package that was installed from specific repository - win_psmodule: - name: ansible-test2 - state: absent - register: remove_repo_without_source - -- name: get result of remove package that was installed from specific repository - win_shell: (Get-Module -ListAvailable -Name ansible-test2 | Measure-Object).Count - register: remove_repo_without_source_actual - -- name: assert remove package that was installed from specific repository - assert: - that: - - remove_repo_without_source is changed - - remove_repo_without_source_actual.stdout | trim | int == 0 - -- name: fail to install required version that is missing - win_psmodule: - name: ansible-test1 - required_version: 0.9.0 - state: present - register: fail_missing_req - failed_when: '"Problems installing ansible-test1 module: No match was found for the specified search criteria" not in fail_missing_req.msg' - -- name: install required version - win_psmodule: - name: ansible-test1 - required_version: 1.0.0 - state: present - register: install_req_version - -- name: get result of install required version - win_shell: Import-Module -Name ansible-test1; Get-AnsibleTest1 | ConvertTo-Json - register: install_req_version_actual - -- name: assert install required version - assert: - that: - - install_req_version is changed - - install_req_version_actual.stdout | from_json == {"Name":"ansible-test1","Version":"1.0.0","Repo":"PSRepo 1"} - -- name: install required version (idempotent) - win_psmodule: - name: ansible-test1 - required_version: 1.0.0 - state: present - register: install_req_version_again - -- name: assert install required version (idempotent) - assert: - that: - - not install_req_version_again is changed - -- name: remove required version - win_psmodule: - name: ansible-test1 - required_version: 1.0.0 - state: absent - register: remove_req_version - -- name: get result of remove required version - win_shell: (Get-Module -ListAvailable -Name ansible-test1 | Measure-Object).Count - register: remove_req_version_actual - -- name: assert remove required version - assert: - that: - - remove_req_version is changed - - remove_req_version_actual.stdout | trim | int == 0 - -- name: remove required version (idempotent) - win_psmodule: - name: ansible-test1 - required_version: 1.0.0 - state: absent - register: remove_req_version_again - -- name: assert remove required version (idempotent) - assert: - that: - - not remove_req_version_again is changed - -- name: install min max version - win_psmodule: - name: ansible-test1 - minimum_version: 1.0.1 - maximum_version: 1.0.9 - state: present - register: install_min_max - -- name: get result of install min max version - win_shell: Import-Module -Name ansible-test1; Get-AnsibleTest1 | ConvertTo-Json - register: install_min_max_actual - -- name: assert install min max version - assert: - that: - - install_min_max is changed - - install_min_max_actual.stdout | from_json == {"Name":"ansible-test1","Version":"1.0.5","Repo":"PSRepo 1"} - -- name: install min max version (idempotent) - win_psmodule: - name: ansible-test1 - minimum_version: 1.0.1 - maximum_version: 1.0.9 - state: present - register: install_min_max_again - -- name: assert install min max version (idempotent) - assert: - that: - - not install_min_max_again is changed - -- name: update package to latest version - win_psmodule: - name: ansible-test1 - state: latest - register: update_module - -- name: get result of update package to latest version - win_shell: Import-Module -Name ansible-test1; Get-AnsibleTest1 | ConvertTo-Json - register: update_module_actual - -- name: assert update package to latest version - assert: - that: - - update_module is changed - - update_module_actual.stdout | from_json == {"Name":"ansible-test1","Version":"1.1.0","Repo":"PSRepo 1"} - -- name: update package to latest version (idempotent) - win_psmodule: - name: ansible-test1 - state: latest - register: update_module_again - -- name: assert update package to latest version (idempotent) - assert: - that: - - not update_module_again is changed - -- name: remove package that does not match min version - win_psmodule: - name: ansible-test1 - minimum_version: 2.0.0 - state: absent - register: remove_min_no_change - -- name: assert remove package that does not match min version - assert: - that: - - not remove_min_no_change is changed - -- name: remove package that does not match max version - win_psmodule: - name: ansible-test1 - maximum_version: 0.9.0 - state: absent - register: remove_max_no_change - -- name: assert remove package that does not match max version - assert: - that: - - not remove_max_no_change is changed - -- name: uninstall package to clear tests - win_psmodule: - name: ansible-test1 - state: absent - -- name: install package with max version - win_psmodule: - name: ansible-test2 - maximum_version: 1.0.0 - repository: PSRepo 1 - state: present - register: install_max - -- name: get result of install package with max version - win_shell: Import-Module -Name ansible-test2; Get-AnsibleTest2 | ConvertTo-Json - register: install_max_actual - -- name: assert install package with max version - assert: - that: - - install_max is changed - - install_max_actual.stdout | from_json == {"Name":"ansible-test2","Version":"1.0.0","Repo":"PSRepo 1"} - -- name: fail to install updated package without skip publisher - win_psmodule: - name: ansible-test2 - required_version: 1.0.1 # This version has been pureposefully not been signed for testing - repository: PSRepo 1 - state: present - register: fail_skip_pub - failed_when: '"The version ''1.0.1'' of the module ''ansible-test2'' being installed is not catalog signed" not in fail_skip_pub.msg' - -- name: install updated package provider with skip publisher - win_psmodule: - name: ansible-test2 - required_version: 1.0.1 - repository: PSRepo 1 - state: present - skip_publisher_check: yes - register: install_skip_pub - -- name: get result of install updated package provider with skip publisher - win_shell: Import-Module -Name ansible-test2; Get-AnsibleTest2 | ConvertTo-Json - register: install_skip_pub_actual - -- name: assert install updated package provider with skip publisher - assert: - that: - - install_skip_pub is changed - - install_skip_pub_actual.stdout | from_json == {"Name":"ansible-test2","Version":"1.0.1","Repo":"PSRepo 1"} - -- name: remove test package 2 for clean test - win_psmodule: - name: ansible-test2 - state: absent - -- name: fail to install clobbered module - win_psmodule: - name: ansible-clobber - state: present - register: fail_clobbering_time - failed_when: '"If you still want to install this module ''ansible-clobber'', use -AllowClobber parameter." not in fail_clobbering_time.msg' - -- name: install clobbered module - win_psmodule: - name: ansible-clobber - allow_clobber: yes - state: present - register: install_clobber - -- name: get result of install clobbered module - win_shell: Import-Module -Name ansible-clobber; Enable-PSTrace | ConvertTo-Json - register: install_clobber_actual - -- name: assert install clobbered module - assert: - that: - - install_clobber is changed - - install_clobber_actual.stdout | from_json == {"Name":"ansible-clobber","Version":"0.1.0","Repo":"PSRepo 1"} - -- name: remove clobbered module - win_psmodule: - name: ansible-clobber - state: absent - register: remove_clobber - -- name: get result of remove clobbered module - win_shell: (Get-Module -ListAvailable -Name ansible-clobber | Measure-Object).Count - register: remove_clobber_actual - -- name: assert remove clobbered module - assert: - that: - - remove_clobber is changed - - remove_clobber_actual.stdout | trim | int == 0 - -- name: fail to install prerelese module - win_psmodule: - name: ansible-test2 - repository: PSRepo 1 - required_version: 1.1.0-beta1 - state: present - register: fail_install_prerelease - failed_when: '"The ''-AllowPrerelease'' parameter must be specified when using the Prerelease string" not in fail_install_prerelease.msg' - -- name: install prerelease module - win_psmodule: - name: ansible-test2 - repository: PSRepo 1 - required_version: 1.1.0-beta1 - allow_prerelease: yes - state: present - register: install_prerelease - -- name: get result of install prerelease module - win_shell: Import-Module -Name ansible-test2; Get-AnsibleTest2 | ConvertTo-Json - register: install_prerelease_actual - -- name: assert install prerelease module - assert: - that: - - install_prerelease is changed - - install_prerelease_actual.stdout | from_json == {"Name":"ansible-test2","Version":"1.1.0","Repo":"PSRepo 1"} - -- name: remove prerelease module - win_psmodule: - name: ansible-test2 - state: absent - register: remove_prerelease - -- name: get result of remove prerelease module - win_shell: (Get-Module -ListAvailable -Name ansible-test2 | Measure-Object).Count - register: remove_prerelease_actual - -- name: assert remove prerelease module - assert: - that: - - remove_prerelease is changed - - remove_prerelease_actual.stdout | trim | int == 0 diff --git a/test/integration/targets/win_psmodule/tasks/setup.yml b/test/integration/targets/win_psmodule/tasks/setup.yml deleted file mode 100644 index 128c69eb1d0..00000000000 --- a/test/integration/targets/win_psmodule/tasks/setup.yml +++ /dev/null @@ -1,115 +0,0 @@ -# Sets up 2 local repos that contains mock packages for testing. -# -# PSRepo 1 contains -# ansible-test1 - 1.0.0 -# ansible-test1 - 1.0.5 -# ansible-test1 - 1.1.0 -# ansible-test2 - 1.0.0 -# ansible-test2 - 1.0.1 (Not signed for skip_publisher tests) -# ansible-test2 - 1.1.0-beta1 -# ansible-clobber - 0.1.0 -# -# PSRepo 2 contains -# ansible-test2 - 1.0.0 -# -# These modules will have the following cmdlets -# ansible-test1 -# Get-AnsibleTest1 -# -# ansible-test2 -# Get-AnsibleTest2 -# -# ansible-clobber -# Enable-PSTrace (clobbers the Enable-PSTrace cmdlet) -# -# All cmdlets return -# [PSCustomObject]@{ -# Name = "the name of the module" -# Version = "the version of the module" -# Repo = "the repo where the module was sourced from" -# } ---- -- name: create test repo folders - win_file: - path: '{{ remote_tmp_dir }}\{{ item }}' - state: directory - loop: - - PSRepo 1 - - PSRepo 2 - -- name: register test repos - win_psrepository: - name: '{{ item.name }}' - source: '{{ remote_tmp_dir }}\{{ item.name }}' - installation_policy: '{{ item.policy }}' - notify: remove registered repos - loop: - - name: PSRepo 1 - policy: trusted - - name: PSRepo 2 - policy: untrusted - -- name: remove PSGallery repository - win_psrepository: - name: PSGallery - state: absent - notify: re-add PSGallery repository - -- name: create custom openssl conf - copy: - src: openssl.conf - dest: '{{ output_dir }}/openssl.conf' - delegate_to: localhost - -- name: get absolute path of output_dir for script - shell: echo {{ output_dir }} - delegate_to: localhost - register: output_dir_abs - -- name: create certificates for code signing - script: setup_certs.sh - args: - chdir: '{{ output_dir_abs.stdout }}' - delegate_to: localhost - -- name: copy the CA and sign certificates - win_copy: - src: '{{ output_dir }}/{{ item }}' - dest: '{{ remote_tmp_dir }}\' - loop: - - ca.pem - - sign.pem - - sign.pfx - -- name: import the CA key to the trusted root store - win_certificate_store: - path: '{{ remote_tmp_dir }}\ca.pem' - state: present - store_location: LocalMachine - store_name: Root - register: ca_cert_import - notify: remove CA cert from trusted root store - -- name: import the sign key to the trusted publisher store - win_certificate_store: - path: '{{ remote_tmp_dir }}\sign.pem' - state: present - store_location: LocalMachine - store_name: TrustedPublisher - register: sign_cert_import - notify: remove signing key from trusted publisher store - -- name: copy across module template files - win_copy: - src: module/ - dest: '{{ remote_tmp_dir }}' - -# Used in the script below to create the .nupkg for each test module -- name: download NuGet binary for module publishing - win_get_url: - url: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/win_psmodule/nuget.exe - dest: '{{ remote_tmp_dir }}' - -- name: create test PowerShell modules - script: setup_modules.ps1 "{{ remote_tmp_dir }}" - notify: remove test packages diff --git a/test/integration/targets/win_psrepository/aliases b/test/integration/targets/win_psrepository/aliases deleted file mode 100644 index 423ce391085..00000000000 --- a/test/integration/targets/win_psrepository/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group2 diff --git a/test/integration/targets/win_psrepository/defaults/main.yml b/test/integration/targets/win_psrepository/defaults/main.yml deleted file mode 100644 index 3b39aecb3f2..00000000000 --- a/test/integration/targets/win_psrepository/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -repository_name: My Get -repository_sourcelocation: https://www.myget.org/F/powershellgetdemo/api/v2 -repository_sourcelocation2: '{{ remote_tmp_dir }}' diff --git a/test/integration/targets/win_psrepository/meta/main.yml b/test/integration/targets/win_psrepository/meta/main.yml deleted file mode 100644 index f0920878aef..00000000000 --- a/test/integration/targets/win_psrepository/meta/main.yml +++ /dev/null @@ -1,3 +0,0 @@ -dependencies: -- setup_remote_tmp_dir -- setup_win_psget diff --git a/test/integration/targets/win_psrepository/tasks/main.yml b/test/integration/targets/win_psrepository/tasks/main.yml deleted file mode 100644 index 65cc278853a..00000000000 --- a/test/integration/targets/win_psrepository/tasks/main.yml +++ /dev/null @@ -1,16 +0,0 @@ -# This file is part of Ansible - -# Copyright: (c) 2018, Wojciech Sciesinski -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - ---- -- name: unregister the repository - win_shell: Unregister-PSRepository {{ repository_name | quote }} -ErrorAction Ignore - -- block: - - name: run all tests - include_tasks: tests.yml - - always: - - name: ensure test repo is unregistered - win_shell: Unregister-PSRepository {{ repository_name | quote }} -ErrorAction Ignore diff --git a/test/integration/targets/win_psrepository/tasks/tests.yml b/test/integration/targets/win_psrepository/tasks/tests.yml deleted file mode 100644 index 5dc80fa9af7..00000000000 --- a/test/integration/targets/win_psrepository/tasks/tests.yml +++ /dev/null @@ -1,200 +0,0 @@ -# This file is part of Ansible - -# Copyright: (c) 2018, Wojciech Sciesinski -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - ---- - -- name: check adding of repository defaults - check mode - win_psrepository: - name: "{{ repository_name }}" - source: "{{ repository_sourcelocation }}" - state: present - check_mode: True - register: adding_repository_check - -- name: get result of adding repository defaults - check mode - win_shell: (Get-PSRepository -Name {{ repository_name | quote }} -ErrorAction ignore | Measure-Object).Count - changed_when: false - register: result_adding_repository_check - -- name: test adding repository defaults - check mode - assert: - that: - - adding_repository_check is changed - - result_adding_repository_check.stdout_lines[0] == '0' - -- name: check adding repository defaults - win_psrepository: - name: "{{ repository_name }}" - source: "{{ repository_sourcelocation }}" - state: present - register: adding_repository - -- name: get result of adding repository defaults - win_shell: | - $repo = Get-PSRepository -Name {{ repository_name | quote }} - ($repo | Measure-Object).Count - $repo.SourceLocation - $repo.InstallationPolicy - register: result_adding_repository - -- name: test adding repository defaults - assert: - that: - - adding_repository is changed - - result_adding_repository.stdout_lines[0] == '1' - - result_adding_repository.stdout_lines[1] == repository_sourcelocation - - result_adding_repository.stdout_lines[2] == 'Trusted' - -- name: check adding repository defaults - idempotent - win_psrepository: - name: "{{ repository_name }}" - source: "{{ repository_sourcelocation }}" - state: present - register: adding_repository_again - -- name: test check adding repository defaults - idempotent - assert: - that: - - adding_repository_again is not changed - -- name: change InstallationPolicy - check mode - win_psrepository: - name: "{{ repository_name }}" - source: "{{ repository_sourcelocation }}" - installation_policy: untrusted - check_mode: True - register: change_installation_policy_check - -- name: get result of change InstallationPolicy - check mode - win_shell: '(Get-PSRepository -Name {{ repository_name | quote }}).InstallationPolicy' - changed_when: false - register: result_change_installation_policy_check - -- name: test change InstallationPolicy - check mode - assert: - that: - - change_installation_policy_check is changed - - result_change_installation_policy_check.stdout | trim == 'Trusted' - -- name: change InstallationPolicy - win_psrepository: - name: "{{ repository_name }}" - source: "{{ repository_sourcelocation }}" - installation_policy: untrusted - register: change_installation_policy - -- name: get result of change InstallationPolicy - win_shell: '(Get-PSRepository -Name {{ repository_name | quote }}).InstallationPolicy' - changed_when: false - register: result_change_installation_policy - -- name: test change InstallationPolicy - assert: - that: - - change_installation_policy is changed - - result_change_installation_policy.stdout | trim == 'Untrusted' - -- name: change InstallationPolicy - idempotent - win_psrepository: - name: "{{ repository_name }}" - source: "{{ repository_sourcelocation }}" - installation_policy: untrusted - register: change_installation_policy_again - -- name: test change InstallationPolicy - idempotent - assert: - that: - - change_installation_policy_again is not changed - -- name: change source - check mode - win_psrepository: - name: "{{ repository_name }}" - source: "{{ repository_sourcelocation2 }}" - state: present - check_mode: True - register: change_source_check - -- name: get result of change source - check mode - win_shell: | - $repo = Get-PSRepository -Name {{ repository_name | quote }} - $repo.SourceLocation - $repo.InstallationPolicy - changed_when: False - register: result_change_source_check - -- name: test change source - check mode - assert: - that: - - change_source_check is changed - - result_change_source_check.stdout_lines[0] == repository_sourcelocation - - result_change_source_check.stdout_lines[1] == 'Untrusted' - -- name: change source - win_psrepository: - name: "{{ repository_name }}" - source: "{{ repository_sourcelocation2 }}" - state: present - register: change_source - -- name: get result of change source - win_shell: | - $repo = Get-PSRepository -Name {{ repository_name | quote }} - $repo.SourceLocation - $repo.InstallationPolicy - changed_when: False - register: result_change_source - -- name: test change source - assert: - that: - - change_source is changed - - result_change_source.stdout_lines[0] == repository_sourcelocation2 - - result_change_source.stdout_lines[1] == 'Untrusted' - -- name: remove repository - check mode - win_psrepository: - name: "{{ repository_name }}" - state: absent - check_mode: True - register: removing_repository_check - -- name: get result of remove repository - check mode - win_shell: '(Get-PSRepository -Name {{ repository_name | quote }} -ErrorAction Ignore | Measure-Object).Count' - changed_when: false - register: result_removing_repository_check - -- name: test remove repository - check mode - assert: - that: - - removing_repository_check is changed - - result_removing_repository_check.stdout | trim == '1' - -- name: remove repository - win_psrepository: - name: "{{ repository_name }}" - state: absent - register: removing_repository - -- name: get result of remove repository - win_shell: '(Get-PSRepository -Name {{ repository_name | quote }} -ErrorAction Ignore | Measure-Object).Count' - changed_when: false - register: result_removing_repository - -- name: test remove repository - assert: - that: - - removing_repository is changed - - result_removing_repository.stdout | trim == '0' - -- name: remove repository - idempotent - win_psrepository: - name: "{{ repository_name }}" - state: absent - register: remove_repository_again - -- name: test remove repository - idempotent - assert: - that: - - remove_repository_again is not changed diff --git a/test/integration/targets/win_psrepository_info/aliases b/test/integration/targets/win_psrepository_info/aliases deleted file mode 100644 index 423ce391085..00000000000 --- a/test/integration/targets/win_psrepository_info/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group2 diff --git a/test/integration/targets/win_psrepository_info/defaults/main.yml b/test/integration/targets/win_psrepository_info/defaults/main.yml deleted file mode 100644 index e0270798759..00000000000 --- a/test/integration/targets/win_psrepository_info/defaults/main.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -run_check_mode: False -suffix: "{{ '(check mode)' if run_check_mode else '' }}" -default_repository_name: PSGallery - -second_repository_name: PowerShellGetDemo -second_repository_source_location: https://www.myget.org/F/powershellgetdemo/api/v2 - -third_repository_name: OtherRepo -third_repository_source_location: http://httpbin.org/get diff --git a/test/integration/targets/win_psrepository_info/meta/main.yml b/test/integration/targets/win_psrepository_info/meta/main.yml deleted file mode 100644 index 504d9eb7707..00000000000 --- a/test/integration/targets/win_psrepository_info/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - setup_win_psget diff --git a/test/integration/targets/win_psrepository_info/tasks/contains_all_fields.yml b/test/integration/targets/win_psrepository_info/tasks/contains_all_fields.yml deleted file mode 100644 index 6f3e6f50094..00000000000 --- a/test/integration/targets/win_psrepository_info/tasks/contains_all_fields.yml +++ /dev/null @@ -1,21 +0,0 @@ -# This file is part of Ansible - -# Copyright: (c) 2020, Brian Scholer <@briantist> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) ---- -- name: Check for key ('{{ key }}') in result - assert: - that: key in dict_to_check - loop_control: - loop_var: key - loop: - - name - - installation_policy - - package_management_provider - - provider_options - - publish_location - - source_location - - script_source_location - - script_publish_location - - registered - - trusted diff --git a/test/integration/targets/win_psrepository_info/tasks/empty.yml b/test/integration/targets/win_psrepository_info/tasks/empty.yml deleted file mode 100644 index 9bc6d4c644a..00000000000 --- a/test/integration/targets/win_psrepository_info/tasks/empty.yml +++ /dev/null @@ -1,19 +0,0 @@ -# This file is part of Ansible - -# Copyright: (c) 2020, Brian Scholer <@briantist> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) ---- -- name: Tests against the empty set of repositories - block: - - name: Get repository info {{ suffix }} - win_psrepository_info: - register: repo_info - - - name: Assert that the correct structure is returned {{ suffix }} - assert: - that: - - repo_info.repositories is defined - - repo_info.repositories is sequence() - - repo_info.repositories | length == 0 - # block - check_mode: "{{ run_check_mode }}" diff --git a/test/integration/targets/win_psrepository_info/tasks/main.yml b/test/integration/targets/win_psrepository_info/tasks/main.yml deleted file mode 100644 index 8e92dc63212..00000000000 --- a/test/integration/targets/win_psrepository_info/tasks/main.yml +++ /dev/null @@ -1,51 +0,0 @@ -# This file is part of Ansible - -# Copyright: (c) 2020, Brian Scholer <@briantist> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) ---- -- name: Unregister all repositories - win_shell: | - Get-PSRepository | Unregister-PSRepository - -- block: - - name: Run Empty Tests - import_tasks: empty.yml - - - name: Run Empty Tests (check mode) - import_tasks: empty.yml - vars: - run_check_mode: True - - - name: Add the default repository - win_shell: | - Register-PSRepository -Default - - - name: Single Repository Tests - import_tasks: single.yml - - - name: Single Repository Tests (check mode) - import_tasks: single.yml - vars: - run_check_mode: True - - - name: Add two more repositories - win_shell: | - Register-PSRepository -Name '{{ second_repository_name }}' -SourceLocation '{{ second_repository_source_location }}' - Register-PSRepository -Name '{{ third_repository_name }}' -SourceLocation '{{ third_repository_source_location }}' - - - name: Multi Repository Tests - import_tasks: multiple.yml - - - name: Multi Repository Tests (check mode) - import_tasks: multiple.yml - vars: - run_check_mode: True - - always: - - name: Unregister all repositories - win_shell: | - Get-PSRepository | Unregister-PSRepository - - - name: Ensure only the default repository remains - win_shell: | - Register-PSRepository -Default diff --git a/test/integration/targets/win_psrepository_info/tasks/multiple.yml b/test/integration/targets/win_psrepository_info/tasks/multiple.yml deleted file mode 100644 index 8c5b986e7a2..00000000000 --- a/test/integration/targets/win_psrepository_info/tasks/multiple.yml +++ /dev/null @@ -1,37 +0,0 @@ -# This file is part of Ansible - -# Copyright: (c) 2020, Brian Scholer <@briantist> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) ---- -- name: Tests against mutiple repositories - block: - - name: Get all repository info {{ suffix }} - win_psrepository_info: - register: repo_info - - - name: Assert that the correct structure is returned {{ suffix }} - assert: - that: - - repo_info.repositories is defined - - repo_info.repositories is sequence() - - repo_info.repositories | length == 3 - - - include_tasks: contains_all_fields.yml - vars: - dict_to_check: "{{ item }}" - loop: "{{ repo_info.repositories }}" - - - name: Get two repositories with a filter {{ suffix }} - win_psrepository_info: - name: P* - register: repo_info - - - name: Assert that the correct two repositories were returned {{ suffix }} - assert: - that: - - repo_info.repositories | length == 2 - - default_repository_name in (repo_info.repositories | map(attribute='name') | list) - - second_repository_name in (repo_info.repositories | map(attribute='name') | list) - - # block - check_mode: "{{ run_check_mode }}" diff --git a/test/integration/targets/win_psrepository_info/tasks/single.yml b/test/integration/targets/win_psrepository_info/tasks/single.yml deleted file mode 100644 index 00071ec556a..00000000000 --- a/test/integration/targets/win_psrepository_info/tasks/single.yml +++ /dev/null @@ -1,26 +0,0 @@ -# This file is part of Ansible - -# Copyright: (c) 2020, Brian Scholer <@briantist> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) ---- -- name: Tests against a single repository ({{ default_repository_name }}) - block: - - name: Get repository info {{ suffix }} - win_psrepository_info: - name: "{{ default_repository_name }}" - register: repo_info - - - name: Assert that the correct structure is returned {{ suffix }} - assert: - that: - - repo_info.repositories is defined - - repo_info.repositories is sequence() - - repo_info.repositories | length == 1 - - repo_info.repositories[0].name == default_repository_name - - - include_tasks: contains_all_fields.yml - vars: - dict_to_check: "{{ repo_info.repositories[0] }}" - - # block - check_mode: "{{ run_check_mode }}" diff --git a/test/integration/targets/win_rabbitmq_plugin/aliases b/test/integration/targets/win_rabbitmq_plugin/aliases deleted file mode 100644 index aefcbeb1b9a..00000000000 --- a/test/integration/targets/win_rabbitmq_plugin/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group3 -disabled diff --git a/test/integration/targets/win_rabbitmq_plugin/tasks/main.yml b/test/integration/targets/win_rabbitmq_plugin/tasks/main.yml deleted file mode 100644 index 70b04132be7..00000000000 --- a/test/integration/targets/win_rabbitmq_plugin/tasks/main.yml +++ /dev/null @@ -1,7 +0,0 @@ -# Setup action creates ansible_distribution_version variable -- action: setup - -- include_tasks: tasks/tests.yml - # Works on windows >= Windows 7/Windows Server 2008 R2 - # See https://github.com/ansible/ansible/pull/28118#issuecomment-323684042 for additional info. - when: ansible_distribution_version is version('6.1', '>=') diff --git a/test/integration/targets/win_rabbitmq_plugin/tasks/tests.yml b/test/integration/targets/win_rabbitmq_plugin/tasks/tests.yml deleted file mode 100644 index 3603a9cfbd6..00000000000 --- a/test/integration/targets/win_rabbitmq_plugin/tasks/tests.yml +++ /dev/null @@ -1,134 +0,0 @@ -- name: Ensure RabbitMQ installed - win_chocolatey: - name: rabbitmq - state: present - -- name: Ensure that rabbitmq_management plugin disabled - win_rabbitmq_plugin: - names: rabbitmq_management - state: disabled - -- name: Enable rabbitmq_management plugin in check mode - win_rabbitmq_plugin: - names: rabbitmq_management - state: enabled - check_mode: yes - register: enable_plugin_in_check_mode - -- name: Check that enabling plugin in check mode succeeds with a change - assert: - that: - - enable_plugin_in_check_mode.changed == true - -- name: Enable rabbitmq_management plugin in check mode again - win_rabbitmq_plugin: - names: rabbitmq_management - state: enabled - check_mode: yes - register: enable_plugin_in_check_mode_again - -- name: Check that enabling plugin in check mode does not make changes - assert: - that: - - enable_plugin_in_check_mode_again.changed == true - -- name: Enable rabbitmq_management plugin - win_rabbitmq_plugin: - names: rabbitmq_management - state: enabled - register: enable_plugin - -- name: Check that enabling plugin succeeds with a change - assert: - that: - - enable_plugin.changed == true - - enable_plugin.enabled == ['rabbitmq_management'] - -- name: Enable enabled rabbitmq_management plugin - win_rabbitmq_plugin: - names: rabbitmq_management - state: enabled - register: enable_plugin_again - -- name: Check that enabling enabled plugin succeeds without a change - assert: - that: - - enable_plugin_again.changed == false - - enable_plugin_again.enabled == [] - -- name: Enable new plugin when 'new_only' option is 'no' (by default) and there are installed plugins - win_rabbitmq_plugin: - names: rabbitmq_mqtt - state: enabled - check_mode: yes - register: enable_plugin_without_new_only - -- name: Check that 'new_only == no' option enables new plugin and disables the old one - assert: - that: - - enable_plugin_without_new_only.changed == true - - enable_plugin_without_new_only.enabled == ['rabbitmq_mqtt'] - - enable_plugin_without_new_only.disabled == ['rabbitmq_management'] - -- name: Enable new plugin when 'new_only' option is 'yes' and there are installed plugins - win_rabbitmq_plugin: - names: rabbitmq_mqtt - state: enabled - new_only: yes - check_mode: yes - register: enable_plugin_with_new_only - -- name: Check that 'new_only == yes' option just enables new plugin - assert: - that: - - enable_plugin_with_new_only.changed == true - - enable_plugin_with_new_only.enabled == ['rabbitmq_mqtt'] - - enable_plugin_with_new_only.disabled == [] - -- name: Disable rabbitmq_management plugin in check mode - win_rabbitmq_plugin: - names: rabbitmq_management - state: disabled - check_mode: yes - register: disable_plugin_in_check_mode - -- name: Check that disabling plugin in check mode succeeds with a change - assert: - that: - - disable_plugin_in_check_mode.changed == true - -- name: Disable rabbitmq_management plugin in check mode again - win_rabbitmq_plugin: - names: rabbitmq_management - state: disabled - check_mode: yes - register: disable_plugin_in_check_mode_again - -- name: Check that disabling plugin in check mode does not make changes - assert: - that: - - disable_plugin_in_check_mode_again.changed == true - -- name: Disable rabbitmq_management plugin - win_rabbitmq_plugin: - names: rabbitmq_management - state: disabled - register: disable_plugin - -- name: Check that disabling plugin succeeds with a change - assert: - that: - - disable_plugin.changed == true - - disable_plugin.disabled == ['rabbitmq_management'] - -- name: Disable disabled rabbitmq_management plugin - win_rabbitmq_plugin: - names: rabbitmq_management - state: disabled - register: disable_plugin_again - -- name: Check that disabling disabled plugin succeeds without a change - assert: - that: - - disable_plugin_again.changed == false - - disable_plugin_again.disabled == [] diff --git a/test/integration/targets/win_rds/aliases b/test/integration/targets/win_rds/aliases deleted file mode 100644 index 81b9f17ec61..00000000000 --- a/test/integration/targets/win_rds/aliases +++ /dev/null @@ -1,6 +0,0 @@ -shippable/windows/group6 -destructive -skip/windows/2008 # win_feature is required to install the RDS feature and that doesn't support 2008 -win_rds_cap -win_rds_rap -win_rds_settings diff --git a/test/integration/targets/win_rds/defaults/main.yml b/test/integration/targets/win_rds/defaults/main.yml deleted file mode 100644 index 4bc62eff127..00000000000 --- a/test/integration/targets/win_rds/defaults/main.yml +++ /dev/null @@ -1,9 +0,0 @@ -# win_rds_cap -test_win_rds_cap_name: Ansible Test CAP - -# win_rds_rap -test_win_rds_rap_name: Ansible Test RAP - -# win_rds_settings -test_win_rds_settings_path: '{{win_output_dir}}\win_rds_settings' -rds_cert_suject: rdg.test.com diff --git a/test/integration/targets/win_rds/tasks/main.yml b/test/integration/targets/win_rds/tasks/main.yml deleted file mode 100644 index 5510b8cda95..00000000000 --- a/test/integration/targets/win_rds/tasks/main.yml +++ /dev/null @@ -1,73 +0,0 @@ ---- -# Cannot use win_feature to install RDS on Server 2008 -- name: check if feature is availble - win_shell: if (Get-Command -Name Add-WindowsFeature -ErrorAction SilentlyContinue) { $true } else { $false } - changed_when: False - register: module_available - -- name: install Remote Desktop Gateway features - when: module_available.stdout | trim | bool - block: - - name: ensure Remote Desktop Gateway services are installed - win_feature: - name: - - RDS-Gateway - - RDS-Licensing - - RDS-RD-Server - state: present - register: rds_install - - - name: reboot server if needed - win_reboot: - when: rds_install.reboot_required - - # After a reboot Windows is still configuring the feature, this is a hack to wait until that is finished - - name: wait for component servicing to be finished - win_shell: | - $start = Get-Date - $path = "HKLM:\SYSTEM\CurrentControlSet\Control\Winlogon\Notifications\Components\TrustedInstaller" - $tries = 0 - while ((Get-ItemProperty -Path $path -Name Events).Events.Contains("CreateSession")) { - $tries += 1 - Start-Sleep -Seconds 5 - if (((Get-Date) - $start).TotalSeconds -gt 180) { - break - } - } - $tries - changed_when: False - - - name: run win_rds_cap integration tests - include_tasks: win_rds_cap.yml - - - name: run win_rds_rap integration tests - include_tasks: win_rds_rap.yml - - - name: run win_rds_settings integration tests - include_tasks: win_rds_settings.yml - - always: - # Server 2008 R2 requires us to remove this first before the other features - - name: remove the RDS-Gateway feature - win_feature: - name: RDS-Gateway - state: absent - register: rds_uninstall - - - name: reboot after removing RDS-Gateway feature - win_reboot: - when: rds_uninstall.reboot_required - - # Now remove the remaining features - - name: remove installed RDS feature - win_feature: - name: - - RDS-Licensing - - RDS-RD-Server - - Web-Server # not part of the initial feature install but RDS-Gateway requires this and it breaks httptester - state: absent - register: rds_uninstall2 - - - name: reboot after feature removal - win_reboot: - when: rds_uninstall2.reboot_required diff --git a/test/integration/targets/win_rds/tasks/win_rds_cap.yml b/test/integration/targets/win_rds/tasks/win_rds_cap.yml deleted file mode 100644 index 41ed2e6e4c8..00000000000 --- a/test/integration/targets/win_rds/tasks/win_rds_cap.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -- name: run tests with cleanup - block: - - name: run tests - include_tasks: win_rds_cap_tests.yml - - always: - - name: delete all CAPs - win_shell: Import-Module RemoteDesktopServices; Remove-Item -Path RDS:\GatewayServer\CAP\* -Recurse diff --git a/test/integration/targets/win_rds/tasks/win_rds_cap_tests.yml b/test/integration/targets/win_rds/tasks/win_rds_cap_tests.yml deleted file mode 100644 index 1c84cc8741a..00000000000 --- a/test/integration/targets/win_rds/tasks/win_rds_cap_tests.yml +++ /dev/null @@ -1,264 +0,0 @@ ---- -- name: test create a new CAP (check mode) - win_rds_cap: - name: '{{ test_win_rds_cap_name }}' - user_groups: - - administrators - - users@builtin - state: present - register: new_cap_check - check_mode: yes - -- name: get result of create a new CAP (check mode) - win_shell: Import-Module RemoteDesktopServices; Write-Host (Test-Path "RDS:\GatewayServer\CAP\{{ test_win_rds_cap_name }}") - register: new_cap_actual_check - -- name: assert results of create a new CAP (check mode) - assert: - that: - - new_cap_check.changed == true - - new_cap_actual_check.stdout_lines[0] == "False" - -- name: test create a new CAP - win_rds_cap: - name: '{{ test_win_rds_cap_name }}' - user_groups: - - administrators - - users@builtin - state: present - register: new_cap - -- name: get result of create a new CAP - win_shell: Import-Module RemoteDesktopServices; Write-Host (Test-Path "RDS:\GatewayServer\CAP\{{ test_win_rds_cap_name }}") - register: new_cap_actual - -- name: assert results of create a new CAP - assert: - that: - - new_cap.changed == true - - new_cap_actual.stdout_lines[0] == "True" - -- name: test create a new CAP (idempotent) - win_rds_cap: - name: '{{ test_win_rds_cap_name }}' - user_groups: - - administrators - - users@builtin - state: present - register: new_cap_again - -- name: get result of create a new CAP (idempotent) - win_shell: Import-Module RemoteDesktopServices; Write-Host (Test-Path "RDS:\GatewayServer\CAP\{{ test_win_rds_cap_name }}") - register: new_cap_actual_again - -- name: assert results of create a new CAP (idempotent) - assert: - that: - - new_cap_again.changed == false - - new_cap_actual_again.stdout_lines[0] == "True" - -- name: test edit a CAP - win_rds_cap: - name: '{{ test_win_rds_cap_name }}' - user_groups: - # Test with different group name formats - - users@builtin - - .\guests - computer_groups: - - administrators - auth_method: both - session_timeout: 20 - session_timeout_action: reauth - allow_only_sdrts_servers: true - idle_timeout: 10 - redirect_clipboard: false - redirect_drives: false - redirect_printers: false - redirect_serial: false - redirect_pnp: false - state: disabled - register: edit_cap - -- name: get result of edit a CAP - win_shell: | - Import-Module RemoteDesktopServices; - $cap_path = "RDS:\GatewayServer\CAP\{{ test_win_rds_cap_name }}" - $cap = @{} - Get-ChildItem -Path "$cap_path" | foreach { $cap.Add($_.Name,$_.CurrentValue) } - $cap.DeviceRedirection = @{} - Get-ChildItem -Path "$cap_path\DeviceRedirection" | foreach { $cap.DeviceRedirection.Add($_.Name, ($_.CurrentValue -eq 1)) } - $cap.UserGroups = @(Get-ChildItem -Path "$cap_path\UserGroups" | Select -ExpandProperty Name) - $cap.ComputerGroups = @(Get-ChildItem -Path "$cap_path\ComputerGroups" | Select -ExpandProperty Name) - $cap | ConvertTo-Json - register: edit_cap_actual_json - -- name: parse result of edit a CAP. - set_fact: - edit_cap_actual: '{{ edit_cap_actual_json.stdout | from_json }}' - -- name: assert results of edit a CAP - assert: - that: - - edit_cap.changed == true - - edit_cap_actual.Status == "0" - - edit_cap_actual.EvaluationOrder == "1" - - edit_cap_actual.AllowOnlySDRTSServers == "1" - - edit_cap_actual.AuthMethod == "3" - - edit_cap_actual.IdleTimeout == "10" - - edit_cap_actual.SessionTimeoutAction == "1" - - edit_cap_actual.SessionTimeout == "20" - - edit_cap_actual.DeviceRedirection.Clipboard == false - - edit_cap_actual.DeviceRedirection.DiskDrives == false - - edit_cap_actual.DeviceRedirection.PlugAndPlayDevices == false - - edit_cap_actual.DeviceRedirection.Printers == false - - edit_cap_actual.DeviceRedirection.SerialPorts == false - - edit_cap_actual.UserGroups | length == 2 - - edit_cap_actual.UserGroups[0] == "Users@BUILTIN" - - edit_cap_actual.UserGroups[1] == "Guests@BUILTIN" - - edit_cap_actual.ComputerGroups | length == 1 - - edit_cap_actual.ComputerGroups[0] == "Administrators@BUILTIN" - -- name: test remove all computer groups of CAP - win_rds_cap: - name: '{{ test_win_rds_cap_name }}' - computer_groups: [] - register: remove_computer_groups_cap - -- name: get result of remove all computer groups of CAP - win_shell: | - Import-Module RemoteDesktopServices; - $cap_path = "RDS:\GatewayServer\CAP\{{ test_win_rds_cap_name }}" - Write-Host @(Get-ChildItem -Path "$cap_path\ComputerGroups" | Select -ExpandProperty Name).Count - register: remove_computer_groups_cap_actual - -- name: assert results of remove all computer groups of CAP - assert: - that: - - remove_computer_groups_cap.changed == true - - remove_computer_groups_cap_actual.stdout_lines[0] == "0" - -- name: test create a CAP in second position - win_rds_cap: - name: '{{ test_win_rds_cap_name }} Second' - user_groups: - - users@builtin - order: 2 - state: present - register: second_cap - -- name: get result of create a CAP in second position - win_shell: Import-Module RemoteDesktopServices; Write-Host (Get-Item "RDS:\GatewayServer\CAP\{{ test_win_rds_cap_name }} Second\EvaluationOrder").CurrentValue - register: second_cap_actual - -- name: assert results of create a CAP in second position - assert: - that: - - second_cap.changed == true - - second_cap.warnings is not defined - - second_cap_actual.stdout_lines[0] == "2" - -- name: test create a CAP with order greater than existing CAP count - win_rds_cap: - name: '{{ test_win_rds_cap_name }} Last' - user_groups: - - users@builtin - order: 50 - state: present - register: cap_big_order - -- name: get result of create a CAP with order greater than existing CAP count - win_shell: Import-Module RemoteDesktopServices; Write-Host (Get-Item "RDS:\GatewayServer\CAP\{{ test_win_rds_cap_name }} Last\EvaluationOrder").CurrentValue - register: cap_big_order_actual - -- name: assert results of create a CAP with order greater than existing CAP count - assert: - that: - - cap_big_order.changed == true - - cap_big_order.warnings | length == 1 - - cap_big_order_actual.stdout_lines[0] == "3" - -- name: test remove CAP (check mode) - win_rds_cap: - name: '{{ test_win_rds_cap_name }}' - state: absent - register: remove_cap_check - check_mode: yes - -- name: get result of remove CAP (check mode) - win_shell: Import-Module RemoteDesktopServices; Write-Host (Test-Path "RDS:\GatewayServer\CAP\{{ test_win_rds_cap_name }}") - register: remove_cap_actual_check - -- name: assert results of remove CAP (check mode) - assert: - that: - - remove_cap_check.changed == true - - remove_cap_actual_check.stdout_lines[0] == "True" - -- name: test remove CAP - win_rds_cap: - name: '{{ test_win_rds_cap_name }}' - state: absent - register: remove_cap_check - -- name: get result of remove CAP - win_shell: Import-Module RemoteDesktopServices; Write-Host (Test-Path "RDS:\GatewayServer\CAP\{{ test_win_rds_cap_name }}") - register: remove_cap_actual_check - -- name: assert results of remove CAP - assert: - that: - - remove_cap_check.changed == true - - remove_cap_actual_check.stdout_lines[0] == "False" - -- name: test remove CAP (idempotent) - win_rds_cap: - name: '{{ test_win_rds_cap_name }}' - state: absent - register: remove_cap_check - -- name: get result of remove CAP (idempotent) - win_shell: Import-Module RemoteDesktopServices; Write-Host (Test-Path "RDS:\GatewayServer\CAP\{{ test_win_rds_cap_name }}") - register: remove_cap_actual_check - -- name: assert results of remove CAP (idempotent) - assert: - that: - - remove_cap_check.changed == false - - remove_cap_actual_check.stdout_lines[0] == "False" - -- name: fail when create a new CAP without user group - win_rds_cap: - name: '{{ test_win_rds_cap_name }}' - state: present - register: new_cap_without_group - check_mode: yes - failed_when: "new_cap_without_group.msg != 'User groups must be defined to create a new CAP.'" - -- name: fail when create a new CAP with an empty user group list - win_rds_cap: - name: '{{ test_win_rds_cap_name }}' - user_groups: [] - state: present - register: new_cap_empty_group_list - check_mode: yes - failed_when: "new_cap_empty_group_list.msg is not search('cannot be an empty list')" - -- name: fail when create a new CAP with an invalid user group - win_rds_cap: - name: '{{ test_win_rds_cap_name }}' - user_groups: - - fake_group - state: present - register: new_cap_invalid_user_group - check_mode: yes - failed_when: new_cap_invalid_user_group.changed != false or new_cap_invalid_user_group.msg is not search('is not a valid account') - -- name: fail when create a new CAP with an invalid computer group - win_rds_cap: - name: '{{ test_win_rds_cap_name }}' - computer_groups: - - fake_group - state: present - register: new_cap_invalid_computer_group - check_mode: yes - failed_when: new_cap_invalid_computer_group.changed != false or new_cap_invalid_computer_group.msg is not search('is not a valid account') diff --git a/test/integration/targets/win_rds/tasks/win_rds_rap.yml b/test/integration/targets/win_rds/tasks/win_rds_rap.yml deleted file mode 100644 index 561f6ead038..00000000000 --- a/test/integration/targets/win_rds/tasks/win_rds_rap.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -- name: run tests with cleanup - block: - - name: run tests - include_tasks: win_rds_rap_tests.yml - - always: - - name: delete all RAPs - win_shell: Import-Module RemoteDesktopServices; Remove-Item -Path RDS:\GatewayServer\RAP\* -Recurse diff --git a/test/integration/targets/win_rds/tasks/win_rds_rap_tests.yml b/test/integration/targets/win_rds/tasks/win_rds_rap_tests.yml deleted file mode 100644 index a8645965b79..00000000000 --- a/test/integration/targets/win_rds/tasks/win_rds_rap_tests.yml +++ /dev/null @@ -1,254 +0,0 @@ ---- -- name: test create a new RAP (check mode) - win_rds_rap: - name: '{{ test_win_rds_rap_name }}' - user_groups: - - administrators - - users@builtin - state: present - register: new_rap_check - check_mode: yes - -- name: get result of create a new RAP (check mode) - win_shell: Import-Module RemoteDesktopServices; Write-Host (Test-Path "RDS:\GatewayServer\RAP\{{ test_win_rds_rap_name }}") - register: new_rap_actual_check - -- name: assert results of create a new RAP (check mode) - assert: - that: - - new_rap_check.changed == true - - new_rap_actual_check.stdout_lines[0] == "False" - -- name: test create a new RAP - win_rds_rap: - name: '{{ test_win_rds_rap_name }}' - user_groups: - - administrators - - users@builtin - state: present - register: new_rap - -- name: get result of create a new RAP - win_shell: Import-Module RemoteDesktopServices; Write-Host (Test-Path "RDS:\GatewayServer\RAP\{{ test_win_rds_rap_name }}") - register: new_rap_actual - -- name: assert results of create a new RAP - assert: - that: - - new_rap.changed == true - - new_rap_actual.stdout_lines[0] == "True" - -- name: test create a new RAP (idempotent) - win_rds_rap: - name: '{{ test_win_rds_rap_name }}' - user_groups: - - administrators - - users@builtin - state: present - register: new_rap_again - -- name: get result of create a new RAP (idempotent) - win_shell: Import-Module RemoteDesktopServices; Write-Host (Test-Path "RDS:\GatewayServer\RAP\{{ test_win_rds_rap_name }}") - register: new_rap_actual_again - -- name: assert results of create a new RAP (idempotent) - assert: - that: - - new_rap_again.changed == false - - new_rap_actual_again.stdout_lines[0] == "True" - -- name: test edit a RAP - win_rds_rap: - name: '{{ test_win_rds_rap_name }}' - description: 'Description of {{ test_win_rds_rap_name }}' - user_groups: - # Test with different group name formats - - users@builtin - - .\guests - computer_group_type: ad_network_resource_group - computer_group: administrators - allowed_ports: - - 3389 - - 3390 - - 3391 - state: disabled - register: edit_rap - -- name: get result of edit a RAP - win_shell: | - Import-Module RemoteDesktopServices; - $rap_path = "RDS:\GatewayServer\RAP\{{ test_win_rds_rap_name }}" - $rap = @{} - Get-ChildItem -Path "$rap_path" | foreach { $rap.Add($_.Name,$_.CurrentValue) } - $rap.UserGroups = @(Get-ChildItem -Path "$rap_path\UserGroups" | Select -ExpandProperty Name) - $rap | ConvertTo-Json - register: edit_rap_actual_json - -- name: parse result of edit a RAP. - set_fact: - edit_rap_actual: '{{ edit_rap_actual_json.stdout | from_json }}' - -- name: assert results of edit a RAP - assert: - that: - - edit_rap.changed == true - - edit_rap_actual.Status == "0" - - edit_rap_actual.Description == "Description of {{ test_win_rds_rap_name }}" - - edit_rap_actual.PortNumbers == "3389,3390,3391" - - edit_rap_actual.UserGroups | length == 2 - - edit_rap_actual.UserGroups[0] == "Users@BUILTIN" - - edit_rap_actual.UserGroups[1] == "Guests@BUILTIN" - - edit_rap_actual.ComputerGroupType == "1" - - edit_rap_actual.ComputerGroup == "Administrators@BUILTIN" - -- name: test edit a RAP (indempotent) - win_rds_rap: - name: '{{ test_win_rds_rap_name }}' - description: 'Description of {{ test_win_rds_rap_name }}' - user_groups: - - users@builtin - - guests@builtin - computer_group_type: ad_network_resource_group - computer_group: Administrators@BUILTIN - allowed_ports: - - 3389 - - 3390 - - 3391 - state: disabled - register: edit_rap_again - -- name: assert results of edit a RAP (indempotent) - assert: - that: - - edit_rap_again.changed == false - -- name: test allow all ports - win_rds_rap: - name: '{{ test_win_rds_rap_name }}' - allowed_ports: any - register: edit_rap_allow_all_ports - -- name: get result of allow all ports - win_shell: Import-Module RemoteDesktopServices; Write-Host (Get-Item "RDS:\GatewayServer\RAP\{{ test_win_rds_rap_name }}\PortNumbers").CurrentValue - register: edit_rap_allow_all_ports_actual - -- name: assert results of allow all ports - assert: - that: - - edit_rap_allow_all_ports.changed == true - - edit_rap_allow_all_ports_actual.stdout_lines[0] == "*" - -- name: test remove RAP (check mode) - win_rds_rap: - name: '{{ test_win_rds_rap_name }}' - state: absent - register: remove_rap_check - check_mode: yes - -- name: get result of remove RAP (check mode) - win_shell: Import-Module RemoteDesktopServices; Write-Host (Test-Path "RDS:\GatewayServer\RAP\{{ test_win_rds_rap_name }}") - register: remove_rap_actual_check - -- name: assert results of remove RAP (check mode) - assert: - that: - - remove_rap_check.changed == true - - remove_rap_actual_check.stdout_lines[0] == "True" - -- name: test remove RAP - win_rds_rap: - name: '{{ test_win_rds_rap_name }}' - state: absent - register: remove_rap - -- name: get result of remove RAP - win_shell: Import-Module RemoteDesktopServices; Write-Host (Test-Path "RDS:\GatewayServer\RAP\{{ test_win_rds_rap_name }}") - register: remove_rap_actual - -- name: assert results of remove RAP - assert: - that: - - remove_rap.changed == true - - remove_rap_actual.stdout_lines[0] == "False" - -- name: test remove RAP (idempotent) - win_rds_rap: - name: '{{ test_win_rds_rap_name }}' - state: absent - register: remove_rap_again - -- name: get result of remove RAP (idempotent) - win_shell: Import-Module RemoteDesktopServices; Write-Host (Test-Path "RDS:\GatewayServer\RAP\{{ test_win_rds_rap_name }}") - register: remove_rap_actual_again - -- name: assert results of remove RAP (idempotent) - assert: - that: - - remove_rap_again.changed == false - - remove_rap_actual_again.stdout_lines[0] == "False" - -- name: fail when create a new RAP without user group - win_rds_rap: - name: '{{ test_win_rds_rap_name }}' - state: present - register: new_rap_without_group - check_mode: yes - failed_when: "new_rap_without_group.msg != 'User groups must be defined to create a new RAP.'" - -- name: fail when create a new RAP with an empty user group list - win_rds_rap: - name: '{{ test_win_rds_rap_name }}' - user_groups: [] - state: present - register: new_rap_empty_group_list - check_mode: yes - failed_when: "new_rap_empty_group_list.msg is not search('cannot be an empty list')" - -- name: fail when create a new RAP with an invalid user group - win_rds_rap: - name: '{{ test_win_rds_rap_name }}' - user_groups: - - fake_group - state: present - register: new_rap_invalid_group - check_mode: yes - failed_when: new_rap_invalid_group.changed != false or new_rap_invalid_group.msg is not search('is not a valid account') - -- name: fail when create a new RAP with an invalid AD computer group - win_rds_rap: - name: '{{ test_win_rds_rap_name }}' - user_groups: - - administrators - computer_group_type: ad_network_resource_group - computer_group: fake_ad_group - state: present - register: new_rap_invalid_ad_computer_group - check_mode: yes - failed_when: new_rap_invalid_ad_computer_group.changed != false or new_rap_invalid_ad_computer_group.msg is not search('is not a valid account') - -- name: fail when create a new RAP with an invalid gateway managed computer group - win_rds_rap: - name: '{{ test_win_rds_rap_name }}' - user_groups: - - administrators - computer_group_type: rdg_group - computer_group: fake_rdg_group - state: present - register: new_rap_invalid_rdg_computer_group - check_mode: yes - failed_when: new_rap_invalid_rdg_computer_group.changed != false or new_rap_invalid_rdg_computer_group.msg is not search('is not a valid gateway managed computer group') - -- name: fail when create a new RAP with invalid port numbers - win_rds_rap: - name: '{{ test_win_rds_rap_name }}' - user_groups: - - administrators - allowed_ports: - - '{{ item }}' - state: present - loop: - - invalid_port_number - - 65536 - register: new_rap_invalid_port - check_mode: yes - failed_when: new_rap_invalid_port.changed != false or new_rap_invalid_port.msg is not search('is not a valid port number') diff --git a/test/integration/targets/win_rds/tasks/win_rds_settings.yml b/test/integration/targets/win_rds/tasks/win_rds_settings.yml deleted file mode 100644 index 08e291fbca3..00000000000 --- a/test/integration/targets/win_rds/tasks/win_rds_settings.yml +++ /dev/null @@ -1,66 +0,0 @@ -- name: run tests with cleanup - block: - - name: gather facts - setup: - filter: ansible_hostname - - - name: ensure testing folders exists - win_file: - path: '{{test_win_rds_settings_path}}' - state: directory - - - name: deploy test artifacts - win_template: - src: '{{item}}.j2' - dest: '{{test_win_rds_settings_path}}\{{item | basename}}' - with_items: - - rds_base_cfg.xml - - - name: import RDS test configuration - win_shell: | - $ts = Get-WmiObject Win32_TSGatewayServer -namespace root\cimv2\TerminalServices - $import_xml = Get-Content {{test_win_rds_settings_path}}\rds_base_cfg.xml - $import_result = $ts.Import(45, $import_xml) - exit $import_result.ReturnValue - - - name: write certreq file - win_copy: - content: |- - [NewRequest] - Subject = "CN={{ rds_cert_suject }}" - KeyLength = 2048 - KeyAlgorithm = RSA - MachineKeySet = true - RequestType = Cert - KeyUsage = 0xA0 ; Digital Signature, Key Encipherment - [EnhancedKeyUsageExtension] - OID=1.3.6.1.5.5.7.3.1 ; Server Authentication - dest: '{{test_win_rds_settings_path}}\certreq.txt' - - - name: create self signed cert from certreq - win_command: certreq -new -machine {{test_win_rds_settings_path}}\certreq.txt {{test_win_rds_settings_path}}\certreqresp.txt - - - name: register certificate thumbprint - raw: '(gci Cert:\LocalMachine\my | ? {$_.subject -eq "CN={{ rds_cert_suject }}"})[0].Thumbprint' - register: rds_cert_thumbprint - - - name: run tests - include_tasks: win_rds_settings_tests.yml - - always: - - name: restore RDS base configuration - win_shell: | - $ts = Get-WmiObject Win32_TSGatewayServer -namespace root\cimv2\TerminalServices - $import_xml = Get-Content {{test_win_rds_settings_path}}\rds_base_cfg.xml - $import_result = $ts.Import(45, $import_xml) - exit $import_result.ReturnValue - - - name: remove certificate - raw: 'remove-item cert:\localmachine\my\{{ item }} -force -ea silentlycontinue' - with_items: - - "{{ rds_cert_thumbprint.stdout_lines[0] }}" - - - name: cleanup test artifacts - win_file: - path: '{{test_win_rds_settings_path}}' - state: absent diff --git a/test/integration/targets/win_rds/tasks/win_rds_settings_tests.yml b/test/integration/targets/win_rds/tasks/win_rds_settings_tests.yml deleted file mode 100644 index 63fa815003f..00000000000 --- a/test/integration/targets/win_rds/tasks/win_rds_settings_tests.yml +++ /dev/null @@ -1,89 +0,0 @@ ---- -- name: test change RDS settings (check mode) - win_rds_settings: - max_connections: 50 - certificate_hash: '{{rds_cert_thumbprint.stdout_lines[0]}}' - ssl_bridging: https_https - enable_only_messaging_capable_clients: yes - register: configure_rds_check - check_mode: yes - -- name: get result of change RDS settings (check mode) - win_shell: | - Import-Module RemoteDesktopServices - (Get-Item RDS:\GatewayServer\MaxConnections).CurrentValue - (Get-Item RDS:\GatewayServer\SSLCertificate\Thumbprint).CurrentValue - (Get-Item RDS:\GatewayServer\SSLBridging).CurrentValue - (Get-Item RDS:\GatewayServer\EnableOnlyMessagingCapableClients).CurrentValue - register: configure_rds_actual_check - -- name: assert results of change RDS settings (check mode) - assert: - that: - - configure_rds_check.changed == true - - configure_rds_actual_check.stdout_lines[0] != "50" - - configure_rds_actual_check.stdout_lines[1] != rds_cert_thumbprint.stdout_lines[0] - - configure_rds_actual_check.stdout_lines[2] == "0" - - configure_rds_actual_check.stdout_lines[3] == "0" - -- name: test change RDS settings - win_rds_settings: - max_connections: 50 - certificate_hash: '{{rds_cert_thumbprint.stdout_lines[0]}}' - ssl_bridging: https_https - enable_only_messaging_capable_clients: yes - register: configure_rds - -- name: get result of change RDS settings - win_shell: | - Import-Module RemoteDesktopServices - (Get-Item RDS:\GatewayServer\MaxConnections).CurrentValue - (Get-Item RDS:\GatewayServer\SSLCertificate\Thumbprint).CurrentValue - (Get-Item RDS:\GatewayServer\SSLBridging).CurrentValue - (Get-Item RDS:\GatewayServer\EnableOnlyMessagingCapableClients).CurrentValue - register: configure_rds_actual - -- name: assert results of change RDS settings - assert: - that: - - configure_rds.changed == true - - configure_rds_actual.stdout_lines[0] == "50" - - configure_rds_actual.stdout_lines[1] == rds_cert_thumbprint.stdout_lines[0] - - configure_rds_actual.stdout_lines[2] == "2" - - configure_rds_actual.stdout_lines[3] == "1" - -- name: test change RDS settings (idempotent) - win_rds_settings: - max_connections: 50 - certificate_hash: '{{rds_cert_thumbprint.stdout_lines[0]}}' - ssl_bridging: https_https - enable_only_messaging_capable_clients: yes - register: configure_rds_again - -- name: assert results of change RDS settings (idempotent) - assert: - that: - - configure_rds_again.changed == false - -- name: test disable connection limit - win_rds_settings: - max_connections: -1 - register: disable_limit - -- name: get result of disable connection limit - win_shell: | - Import-Module RemoteDesktopServices - (Get-Item RDS:\GatewayServer\MaxConnections).CurrentValue -eq (Get-Item RDS:\GatewayServer\MaxConnectionsAllowed).CurrentValue - register: disable_limit_actual - -- name: assert results of disable connection limit - assert: - that: - - disable_limit.changed == true - - disable_limit_actual.stdout_lines[0] == "True" - -- name: fail with invalid certificate thumbprint - win_rds_settings: - certificate_hash: 72E8BD0216FA14100192A3E8B7B150C65B4B0817 - register: fail_invalid_cert - failed_when: fail_invalid_cert.msg is not search('Unable to locate certificate') \ No newline at end of file diff --git a/test/integration/targets/win_rds/templates/rds_base_cfg.xml.j2 b/test/integration/targets/win_rds/templates/rds_base_cfg.xml.j2 deleted file mode 100644 index 5aa48ed84ff..00000000000 --- a/test/integration/targets/win_rds/templates/rds_base_cfg.xml.j2 +++ /dev/null @@ -1,58 +0,0 @@ - - - - {{ ansible_hostname }} - - 4294967295 - 1 - 0 - 0 - 0 - - - LogChannelDisconnect - 1 - - - LogFailureChannelConnect - 1 - - - LogFailureConnectionAuthorizationCheck - 1 - - - LogFailureResourceAuthorizationCheck - 1 - - - LogSuccessfulChannelConnect - 1 - - - LogSuccessfulConnectionAuthorizationCheck - 1 - - - LogSuccessfulResourceAuthorizationCheck - 1 - - - native - native - - - - - 0 - * - * - 443 - 3391 - 1 - 1 - - - - - \ No newline at end of file diff --git a/test/integration/targets/win_region/aliases b/test/integration/targets/win_region/aliases deleted file mode 100644 index 215e0b06920..00000000000 --- a/test/integration/targets/win_region/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group4 diff --git a/test/integration/targets/win_region/meta/main.yml b/test/integration/targets/win_region/meta/main.yml deleted file mode 100644 index d328716dfa4..00000000000 --- a/test/integration/targets/win_region/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_win_tests diff --git a/test/integration/targets/win_region/tasks/main.yml b/test/integration/targets/win_region/tasks/main.yml deleted file mode 100644 index 5600d23d3a4..00000000000 --- a/test/integration/targets/win_region/tasks/main.yml +++ /dev/null @@ -1,252 +0,0 @@ -# test code for the win_region module -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -- name: expect failure when only setting copy_settings - win_region: - copy_settings: False - register: actual - failed_when: actual.msg != "An argument for 'format', 'location' or 'unicode_language' needs to be supplied" - -- name: expect failure when using invalid geo id for the location - win_region: - location: 111111 - register: actual - failed_when: actual.msg != "The argument location '111111' does not contain a valid Geo ID" - -- name: expect failure when using invalid culture for format - win_region: - format: ab-CD - register: actual - failed_when: actual.msg != "The argument format 'ab-CD' does not contain a valid Culture Name" - -- name: expect failure when using invalid culture for unicode_language - win_region: - unicode_language: ab-CD - register: actual - failed_when: actual.msg != "The argument unicode_language 'ab-CD' does not contain a valid Culture Name" - -- name: set settings all to English Australia before tests for a baseline - win_region: - location: 12 - format: en-AU - unicode_language: en-AU - -- name: reboot server to set properties - win_reboot: - -- name: check that changing location in check mode works - win_region: - location: 244 - register: check_location - check_mode: yes - -- name: get current location value - win_command: powershell (Get-ItemProperty -Path 'HKCU:\Control Panel\International\Geo').Nation - register: actual_location - -- name: check assertion about location change in check mode - assert: - that: - - "actual_location.stdout_lines[0] == '12'" # Corresponds to en-AU - - "check_location is changed" - - "check_location.restart_required == False" - -- name: set location to United States - win_region: - location: 244 - register: location - -- name: get current location value - win_command: powershell (Get-ItemProperty -Path 'HKCU:\Control Panel\International\Geo').Nation - register: actual_location - -- name: check assertion about location change - assert: - that: - - "actual_location.stdout_lines[0] == '244'" # Corresponds to en-US - - "location is changed" - - "location.restart_required == False" - -- name: set location to United States again - win_region: - location: 244 - register: location_again - -- name: check that the result did not change - assert: - that: - - "location_again is not changed" - - "location_again.restart_required == False" - -- name: set format to English United States in check mode - win_region: - format: en-US - register: check_format - check_mode: yes - -- name: get actual format value from check mode - win_command: powershell (Get-Culture).Name - register: actual_format - -- name: check assertion about location change in check mode - assert: - that: - - "actual_format.stdout_lines[0] == 'en-AU'" - - "check_format is changed" - - "check_format.restart_required == False" - -- name: set format to English United States - win_region: - format: en-US - register: format - -- name: get actual format value - win_command: powershell (Get-Culture).Name - register: actual_format - -- name: check assertion about format change - assert: - that: - - "actual_format.stdout_lines[0] == 'en-US'" - - "format is changed" - - "format.restart_required == False" - -- name: set format to English United States again - win_region: - format: en-US - register: format_again - -- name: check that the result did not change - assert: - that: - - "format_again is not changed" - - "format_again.restart_required == False" - -- name: set unicode_language to English United States in check mode - win_region: - unicode_language: en-US - register: check_unicode - check_mode: yes - -- name: get actual unicode values - win_command: powershell (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Language').Default - register: actual_unicode - -- name: check assertion about unicode language change in check mode - assert: - that: - - "actual_unicode.stdout_lines[0] == '0c09'" - - "check_unicode is changed" - - "check_unicode.restart_required == True" - -- name: set unicode_language to English United States - win_region: - unicode_language: en-US - register: unicode - -- name: reboot the server after changing unicode language - action: win_reboot - when: unicode.restart_required - -- name: get actual unicode value - win_command: powershell (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Language').Default - register: actual_unicode - -- name: check assertion about unicode language change - assert: - that: - - "actual_unicode.stdout_lines[0] == '0409'" # corresponds to en-US - - "unicode is changed" - - "unicode.restart_required == True" - -- name: set unicode_language to English United States again - win_region: - unicode_language: en-US - register: unicode_again - -- name: check that the result did not change - assert: - that: - - "unicode_again is not changed" - - "unicode_again.restart_required == False" - -- name: copy settings when setting to the same format check mode - win_region: - format: en-US - copy_settings: True - register: check_copy_same - check_mode: yes - -- name: check that the result did not change in check mode - assert: - that: - - "check_copy_same is not changed" - - "check_copy_same.restart_required == False" - -- name: copy settings when setting to the same format - win_region: - format: en-US - copy_settings: True - register: copy_same - -- name: check that the result did not change - assert: - that: - - "copy_same is not changed" - - "copy_same.restart_required == False" - -- name: copy setting when setting to a different format - win_region: - format: en-GB - copy_settings: True - register: copy - -- name: get actual format value after copy_settings - win_command: powershell (Get-Culture).Name - register: actual_copy - -- name: get locale name for local service registry hive - win_command: powershell "New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS | Out-Null; (Get-ItemProperty 'HKU:\S-1-5-19\Control Panel\International').LocaleName" - register: actual_local - -- name: get locale name for network service registry hive - win_command: powershell "New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS | Out-Null; (Get-ItemProperty 'HKU:\S-1-5-20\Control Panel\International').LocaleName" - register: actual_network - -- name: load temp hive - win_command: reg load HKU\TEMP C:\Users\Default\NTUSER.DAT - -- name: get locale name for default registry hive - win_command: powershell "New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS | Out-Null; (Get-ItemProperty 'HKU:\TEMP\Control Panel\International').LocaleName" - register: actual_temp - -- name: unload temp hive - win_command: reg unload HKU\TEMP - -- name: get locale name for default registry hive - win_command: powershell "New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS | Out-Null; (Get-ItemProperty 'HKU:\.DEFAULT\Control Panel\International').LocaleName" - register: actual_default - -- name: check assertions about copy setting when setting to a different format - assert: - that: - - "actual_copy.stdout_lines[0] == 'en-GB'" - - "actual_local.stdout_lines[0] == 'en-GB'" - - "actual_network.stdout_lines[0] == 'en-GB'" - - "actual_temp.stdout_lines[0] == 'en-GB'" - - "actual_default.stdout_lines[0] == 'en-GB'" - - "copy is changed" - - "copy.restart_required == False" diff --git a/test/integration/targets/win_regmerge/aliases b/test/integration/targets/win_regmerge/aliases deleted file mode 100644 index 4cd27b3cb2f..00000000000 --- a/test/integration/targets/win_regmerge/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group1 diff --git a/test/integration/targets/win_regmerge/files/settings1.reg b/test/integration/targets/win_regmerge/files/settings1.reg deleted file mode 100644 index baec75b2af0ee7f806f7e51fc362da820d60e4f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 374 zcmZXQO-sX25Jk^g@IQpCbR*(N5y6E-gF&lOt3j-kQj3JvL{d@v=hc(Zojiu&e!O{i z-uG8YMa>fpA1p~2FymQn$r~*znN!tD)QA)A)LYd`T#NVFV%xLMTGRt)oO|bMLFPxxU)%PVB9Y>EBi>QjV;QL+6dSR&DgPOn7m}T>nCU_dgqaazKyG XaQ@HMrJF?ZTeIfQSp;gspGKY^4^lt~ diff --git a/test/integration/targets/win_regmerge/files/settings2.reg b/test/integration/targets/win_regmerge/files/settings2.reg deleted file mode 100644 index fc2612cb8a8a3937b72e36400b434bac8753e02f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 760 zcma))TT4Pw5QW!s(0@4iEaB}a1UQ|vi*tOJ!8``YvQpfg=? z=U#nXs;xxF?0vP^6MW~o!uzN$zEj<(2i|d{=Njs&sj3Q58F^D86UQUpbG?EzJ@*o} zf!>KRX4Buop6khV6o^VS0(sL5>O(}Aimb9!GZl2C38zmTqQ9;pv&`Bcdy$#?YUj15 z?om}(&0k`TQETTa>$(funXl21qrv*OnKNXt%q8b6>)APtEp{yd*~NTIhpb1Nyg^^Q zQW@AyW$Y>|t4srshSyW`Of|4KM?vA1Dpp)32BqOvpm0(fXeH|+etI^ZkiyQE*(Gpqx?6TVmV zQJ)wewBYkdRqfz&sAK(9LuGBU9;?n;##YlV)>ut!TWYDz{=VMo_P8zLR*6&R{z%`LWo_Ueb7nx6C+d*bSAD_q z_V{C}(V?%X+RTtBlR}`kq6d4H^p_{{8o$SO+j*{}T3(^grOOqR`a4)hyn7xKt{f diff --git a/test/integration/targets/win_regmerge/meta/main.yml b/test/integration/targets/win_regmerge/meta/main.yml deleted file mode 100644 index d328716dfa4..00000000000 --- a/test/integration/targets/win_regmerge/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_win_tests diff --git a/test/integration/targets/win_regmerge/tasks/main.yml b/test/integration/targets/win_regmerge/tasks/main.yml deleted file mode 100644 index 15c754de6db..00000000000 --- a/test/integration/targets/win_regmerge/tasks/main.yml +++ /dev/null @@ -1,133 +0,0 @@ -# test code for the win_regmerge module -# (c) 2014, Michael DeHaan - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -# clear the area of the registry we are using for tests -- name: remove setting - win_regedit: - key: 'HKLM:\SOFTWARE\Wow6432Node\Cow Corp' - state: absent - -# copy over some registry files to work with -- name: copy over some registry files to work with - win_copy: src={{item}} dest={{win_output_dir}}\\{{item}} - with_items: - - settings1.reg - - settings2.reg - - settings3.reg - -# test 1 - basic test of changed behaviour -# merge in REG_SZ -- name: test 1 merge in a setting - win_regmerge: - path: "{{win_output_dir}}\\settings1.reg" - register: merge11_result - -- assert: - that: - - "merge11_result.changed == true" - -# re run the merge -- name: test 1 merge in the setting again - win_regmerge: - path: "{{win_output_dir}}\\settings1.reg" - register: merge12_result - -# without a compare to key, should always report changed -- assert: - that: - - "merge12_result.changed == true" -# assert changed false - -# prune reg key -- name: test 1 remove setting - win_regedit: - key: 'HKLM:\SOFTWARE\Wow6432Node\Cow Corp' - state: absent - -# -# test 2, observe behaviour when compare_to param is set -# -- name: test 2 merge in a setting - win_regmerge: - path: "{{win_output_dir}}\\settings1.reg" - compare_to: 'HKLM:\SOFTWARE\Wow6432Node\Cow Corp\Moosic\ILikeToMooveIt' - register: merge21_result - -- assert: - that: - - "merge21_result.changed == true" - -# re run the merge -- name: test 2 merge in the setting again but with compare_key - win_regmerge: - path: "{{win_output_dir}}\\settings1.reg" - compare_to: 'HKLM:\SOFTWARE\Wow6432Node\Cow Corp\Moosic\ILikeToMooveIt' - register: merge22_result - -# with a compare to key, should now report not changed -- assert: - that: - - "merge22_result.changed == false" -# assert changed false - -# prune the contents of the registry from the parent of the compare key downwards -- name: test 2 clean up remove setting - win_regedit: - key: 'HKLM:\SOFTWARE\Wow6432Node\Cow Corp' - state: absent - -# test 3 merge in more complex settings -- name: test 3 merge in a setting - win_regmerge: - path: "{{win_output_dir}}\\settings3.reg" - compare_to: 'HKLM:\SOFTWARE\Wow6432Node\Cow Corp\Moo Monitor' - register: merge31_result - -- assert: - that: - - "merge31_result.changed == true" - -# re run the merge -- name: test 3 merge in the setting again but with compare_key check - win_regmerge: - path: "{{win_output_dir}}\\settings3.reg" - compare_to: 'HKLM:\SOFTWARE\Wow6432Node\Cow Corp\Moo Monitor' - register: merge32_result - -# with a compare to key, should now report not changed -- assert: - that: - - "merge32_result.changed == false" -# assert changed false - -# prune the contents of the registry from the compare key downwards -- name: test 3 clean up remove setting - win_regedit: - key: 'HKLM:\SOFTWARE\Wow6432Node\Cow Corp' - state: absent - -# clean up registry files - -- name: clean up registry files - win_file: path={{win_output_dir}}\\{{item}} state=absent - with_items: - - settings1.reg - - settings2.reg - - settings3.reg - -# END OF win_regmerge tests diff --git a/test/integration/targets/win_regmerge/templates/win_line_ending.j2 b/test/integration/targets/win_regmerge/templates/win_line_ending.j2 deleted file mode 100644 index d0cefd76f49..00000000000 --- a/test/integration/targets/win_regmerge/templates/win_line_ending.j2 +++ /dev/null @@ -1,4 +0,0 @@ -#jinja2: newline_sequence:'\r\n' -{{ templated_var }} -{{ templated_var }} -{{ templated_var }} diff --git a/test/integration/targets/win_regmerge/vars/main.yml b/test/integration/targets/win_regmerge/vars/main.yml deleted file mode 100644 index 1e8f64ccf44..00000000000 --- a/test/integration/targets/win_regmerge/vars/main.yml +++ /dev/null @@ -1 +0,0 @@ -templated_var: templated_var_loaded diff --git a/test/integration/targets/win_route/aliases b/test/integration/targets/win_route/aliases deleted file mode 100644 index 3cf5b97e805..00000000000 --- a/test/integration/targets/win_route/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_route/defaults/main.yml b/test/integration/targets/win_route/defaults/main.yml deleted file mode 100644 index a77ebc16cbb..00000000000 --- a/test/integration/targets/win_route/defaults/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -default_gateway: 192.168.1.1 -destination_ip_address: 192.168.2.10 diff --git a/test/integration/targets/win_route/tasks/main.yml b/test/integration/targets/win_route/tasks/main.yml deleted file mode 100644 index b0f40dd06c0..00000000000 --- a/test/integration/targets/win_route/tasks/main.yml +++ /dev/null @@ -1,29 +0,0 @@ ---- -# test code for the win_psmodule module when using winrm connection -# (c) 2017, Daniele Lazzari - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - - -- name: get os info - win_shell: '[Environment]::OSVersion.Version -ge [Version]"6.3"' - register: os - -- name: Perform with os Windows 2012R2 or newer - when: os.stdout_lines[0] == "True" - block: - - name: run all tasks - include: tests.yml diff --git a/test/integration/targets/win_route/tasks/tests.yml b/test/integration/targets/win_route/tasks/tests.yml deleted file mode 100644 index 0c365bef549..00000000000 --- a/test/integration/targets/win_route/tasks/tests.yml +++ /dev/null @@ -1,79 +0,0 @@ ---- -- name: add a static route - win_route: - destination: "{{ destination_ip_address }}/32" - gateway: "{{ default_gateway }}" - metric: 1 - state: present - register: route - -- name: check if route successfully added - win_shell: (Get-CimInstance win32_ip4PersistedrouteTable -Filter "Destination = '{{ destination_ip_address }}'").Caption - register: route_added - -- name: check route default gateway - win_shell: (Get-CimInstance win32_ip4PersistedrouteTable -Filter "Destination = '{{ destination_ip_address }}'").NextHop - register: route_gateway - -- name: test if route successfully added - assert: - that: - - route is changed - - route_added.stdout_lines[0] == "{{ destination_ip_address }}" - - route_gateway.stdout_lines[0] == "{{ default_gateway }}" - -- name: add a static route to test idempotency - win_route: - destination: "{{ destination_ip_address }}/32" - gateway: "{{ default_gateway }}" - metric: 1 - state: present - register: idempotent_route - -- name: test idempotency - assert: - that: - - idempotent_route is not changed - - idempotent_route.output == "Static route already exists" - -- name: remove route - win_route: - destination: "{{ destination_ip_address }}/32" - state: absent - register: route_removed - -- name: check route is removed - win_shell: Get-CimInstance win32_ip4PersistedrouteTable -Filter "Destination = '{{ destination_ip_address }}'" - register: check_route_removed - -- name: test route is removed - assert: - that: - - route_removed is changed - - check_route_removed.stdout == '' - -- name: remove static route to test idempotency - win_route: - destination: "{{ destination_ip_address }}/32" - state: absent - register: idempotent_route_removed - -- name: test idempotency - assert: - that: - - idempotent_route_removed is not changed - - idempotent_route_removed.output == "No route to remove" - -- name: add route to wrong ip address - win_route: - destination: "715.18.0.0/32" - gateway: "{{ default_gateway }}" - metric: 1 - state: present - ignore_errors: yes - register: wrong_ip - -- name: test route to wrong ip address - assert: - that: - - wrong_ip is failed diff --git a/test/integration/targets/win_say/aliases b/test/integration/targets/win_say/aliases deleted file mode 100644 index 4cd27b3cb2f..00000000000 --- a/test/integration/targets/win_say/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group1 diff --git a/test/integration/targets/win_say/tasks/main.yml b/test/integration/targets/win_say/tasks/main.yml deleted file mode 100644 index 71c9435cdb9..00000000000 --- a/test/integration/targets/win_say/tasks/main.yml +++ /dev/null @@ -1,44 +0,0 @@ -# CI hosts don't have a valid Speech package so we rely on check mode for basic -# sanity tests ---- -- name: Warn of impending deployment - win_say: - msg: Warning, deployment commencing in 5 minutes, please log out. - check_mode: "{{ win_say_check_mode |default('yes') }}" - -- name: Using a specified voice and a start sound - win_say: - msg: Warning, deployment commencing in 5 minutes, please log out. - start_sound_path: C:\Windows\Media\ding.wav - voice: Microsoft Hazel Desktop - check_mode: "{{ win_say_check_mode |default('yes') }}" - -- name: Example with start and end sound - win_say: - msg: New software installed - start_sound_path: C:\Windows\Media\Windows Balloon.wav - end_sound_path: C:\Windows\Media\chimes.wav - check_mode: "{{ win_say_check_mode |default('yes') }}" - -- name: Create message file - win_copy: - content: Stay calm and carry on - dest: C:\Windows\Temp\win_say_message.txt - -- name: Text from file example - win_say: - msg_file: C:\Windows\Temp\win_say_message.txt - start_sound_path: C:\Windows\Media\Windows Balloon.wav - end_sound_path: C:\Windows\Media\chimes.wav - check_mode: "{{ win_say_check_mode |default('yes') }}" - -- name: Remove message file - win_file: - path: C:\Windows\Temp\win_say_message.txt - state: absent - -- name: Different speech speed - win_say: - speech_speed: 5 - msg: Stay calm and proceed to the closest fire exit. - check_mode: "{{ win_say_check_mode |default('yes') }}" diff --git a/test/integration/targets/win_scheduled_task/aliases b/test/integration/targets/win_scheduled_task/aliases deleted file mode 100644 index 6036e173f1a..00000000000 --- a/test/integration/targets/win_scheduled_task/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group7 diff --git a/test/integration/targets/win_scheduled_task/defaults/main.yml b/test/integration/targets/win_scheduled_task/defaults/main.yml deleted file mode 100644 index f501c72fc50..00000000000 --- a/test/integration/targets/win_scheduled_task/defaults/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -test_scheduled_task_name: Ansible Test -test_scheduled_task_path: \Ansible Test Folder -test_scheduled_task_user: MooCow -test_scheduled_task_pass: Password01 diff --git a/test/integration/targets/win_scheduled_task/tasks/clean.yml b/test/integration/targets/win_scheduled_task/tasks/clean.yml deleted file mode 100644 index 635339bf34e..00000000000 --- a/test/integration/targets/win_scheduled_task/tasks/clean.yml +++ /dev/null @@ -1,16 +0,0 @@ -# cleans up each test to ensure a blank slate ---- -- win_scheduled_task: - name: '{{item.name}}' - path: '{{item.path|default(omit)}}' - state: absent - with_items: - - name: Task # old tests - path: \Path - - name: '{{test_scheduled_task_name}}' - - name: '{{test_scheduled_task_name}}' - path: '{{test_scheduled_task_path}}' - -- win_user: - name: '{{test_scheduled_task_user}}' - state: absent diff --git a/test/integration/targets/win_scheduled_task/tasks/failures.yml b/test/integration/targets/win_scheduled_task/tasks/failures.yml deleted file mode 100644 index 0642437436b..00000000000 --- a/test/integration/targets/win_scheduled_task/tasks/failures.yml +++ /dev/null @@ -1,149 +0,0 @@ -# test out the known failure cases to ensure we have decent error messages ---- -- name: fail create task without an action - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - register: fail_create_without_action - failed_when: fail_create_without_action.msg != 'cannot create a task with no actions, set at least one action with a path to an executable' - -- name: fail both username and group are set - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - username: '{{ansible_user}}' - group: '{{ansible_user}}' - register: fail_username_and_group - failed_when: fail_username_and_group.msg != 'username and group can not be set at the same time' - -- name: fail logon type s4u but no password set - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - logon_type: s4u - register: fail_lt_s4u_not_set - failed_when: fail_lt_s4u_not_set.msg != 'password must be set when logon_type=s4u' - -- name: fail logon type group but no group set - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - logon_type: group - register: fail_lt_group_not_set - failed_when: fail_lt_group_not_set.msg != 'group must be set when logon_type=group' - -- name: fail logon type service but non service user set - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - logon_type: service_account - username: '{{ansible_user}}' - register: fail_lt_service_invalid_user - failed_when: fail_lt_service_invalid_user.msg != 'username must be SYSTEM, LOCAL SERVICE or NETWORK SERVICE when logon_type=service_account' - -- name: fail trigger with no type - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - triggers: - - delay: test - register: fail_trigger_no_type - failed_when: fail_trigger_no_type.msg != "a trigger entry must contain a key 'type' with a value of 'event', 'time', 'daily', 'weekly', 'monthly', 'monthlydow', 'idle', 'registration', 'boot', 'logon', 'session_state_change'" - -- name: fail trigger with datetime in incorrect format - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - triggers: - - type: time - start_boundary: fake - register: fail_trigger_invalid_datetime - failed_when: fail_trigger_invalid_datetime.msg != "trigger option 'start_boundary' must be in the format 'YYYY-MM-DDThh:mm:ss' format but was 'fake'" - -- name: fail trigger with duration in incorrect format - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - triggers: - - type: boot - execution_time_limit: fake - register: fail_trigger_invalid_duration - failed_when: fail_trigger_invalid_duration.msg != "trigger option 'execution_time_limit' must be in the XML duration format but was 'fake'" - -- name: fail trigger option invalid day of the week - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - triggers: - - type: weekly - start_boundary: '2000-01-01T00:00:01' - days_of_week: fakeday - register: fail_trigger_invalid_day_of_week - failed_when: fail_trigger_invalid_day_of_week.msg != "invalid day of week 'fakeday', check the spelling matches the full day name" - -- name: fail trigger option invalid day of the month - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - triggers: - - type: monthly - start_boundary: '2000-01-01T00:00:01' - days_of_month: 35 - register: fail_trigger_invalid_day_of_month - failed_when: fail_trigger_invalid_day_of_month.msg != "invalid day of month '35', please specify numbers from 1-31" - -- name: fail trigger option invalid week of the month - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - triggers: - - type: monthlydow - start_boundary: '2000-01-01T00:00:01' - weeks_of_month: 5 - register: fail_trigger_invalid_week_of_month - failed_when: fail_trigger_invalid_week_of_month.msg != "invalid week of month '5', please specify weeks from 1-4" - -- name: fail trigger option invalid month of the year - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - triggers: - - type: monthlydow - start_boundary: '2000-01-01T00:00:01' - months_of_year: fakemonth - register: fail_trigger_invalid_month_of_year - failed_when: fail_trigger_invalid_month_of_year.msg != "invalid month name 'fakemonth', please specify full month name" - -- name: fail trigger repetition with duration in incorrect format - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - triggers: - - type: boot - repetition: - - duration: fake - register: fail_trigger_repetition_invalid_duration - failed_when: fail_trigger_repetition_invalid_duration.msg != "trigger option 'duration' must be in the XML duration format but was 'fake'" - -- name: fail trigger repetition with interval in incorrect format - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - triggers: - - type: boot - repetition: - - interval: fake - register: fail_trigger_repetition_invalid_interval - failed_when: fail_trigger_repetition_invalid_interval.msg != "trigger option 'interval' must be in the XML duration format but was 'fake'" - -- name: fail trigger repetition option interval greater than duration - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - triggers: - - type: boot - repetition: - - interval: PT5M - duration: PT1M - register: fail_trigger_repetition_interval_greater_than_duration - failed_when: fail_trigger_repetition_interval_greater_than_duration.msg != "trigger repetition option 'interval' value 'PT5M' must be less than or equal to 'duration' value 'PT1M'" diff --git a/test/integration/targets/win_scheduled_task/tasks/main.yml b/test/integration/targets/win_scheduled_task/tasks/main.yml deleted file mode 100644 index 53b062c0b0b..00000000000 --- a/test/integration/targets/win_scheduled_task/tasks/main.yml +++ /dev/null @@ -1,24 +0,0 @@ ---- -- name: remove test tasks before test - include_tasks: clean.yml - -- block: - - name: Test failure scenarios - include_tasks: failures.yml - - - name: Test normal scenarios - include_tasks: tests.yml - - - include_tasks: clean.yml - - - name: Test principals - include_tasks: principals.yml - - - include_tasks: clean.yml - - - name: Test triggers - include_tasks: triggers.yml - - always: - - name: remove test tasks after test - include_tasks: clean.yml diff --git a/test/integration/targets/win_scheduled_task/tasks/principals.yml b/test/integration/targets/win_scheduled_task/tasks/principals.yml deleted file mode 100644 index bc0b9e88ce0..00000000000 --- a/test/integration/targets/win_scheduled_task/tasks/principals.yml +++ /dev/null @@ -1,436 +0,0 @@ ---- -- name: create test user - win_user: - name: '{{test_scheduled_task_user}}' - password: '{{test_scheduled_task_pass}}' - state: present - groups: - - Administrators - -- name: task with password principal (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - username: '{{test_scheduled_task_user}}' - password: '{{test_scheduled_task_pass}}' - logon_type: password - update_password: no - actions: - - path: cmd.exe - register: task_with_password_check - check_mode: yes - -- name: get result of task with password principal (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: task_with_password_result_check - -- name: assert results of task with password principal (check mode) - assert: - that: - - task_with_password_check is changed - - task_with_password_result_check.task_exists == False - -- name: task with password principal - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - username: '{{test_scheduled_task_user}}' - password: '{{test_scheduled_task_pass}}' - logon_type: password - update_password: no - actions: - - path: cmd.exe - register: task_with_password - -- name: get result of task with password principal - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: task_with_password_result - -- name: assert results of task with password principal - assert: - that: - - task_with_password is changed - - task_with_password_result.task_exists == True - - task_with_password_result.principal.group_id == None - - task_with_password_result.principal.logon_type == "TASK_LOGON_PASSWORD" - - task_with_password_result.principal.run_level == "TASK_RUNLEVEL_LUA" - - task_with_password_result.principal.user_id.endswith(test_scheduled_task_user) - -- name: task with password principal (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - username: '{{test_scheduled_task_user}}' - password: '{{test_scheduled_task_pass}}' - logon_type: password - update_password: no - actions: - - path: cmd.exe - register: task_with_password_again - -- name: assert results of task with password principal (idempotent) - assert: - that: - - task_with_password_again is not changed - -- name: task with password principal force pass change - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - username: '{{test_scheduled_task_user}}' - password: '{{test_scheduled_task_pass}}' - logon_type: password - update_password: yes - actions: - - path: cmd.exe - register: task_with_password_force_update - -- name: assert results of task with password principal force pass change - assert: - that: - - task_with_password_force_update is changed - -- name: task with s4u principal (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - username: '{{test_scheduled_task_user}}' - password: '{{test_scheduled_task_pass}}' - logon_type: s4u - update_password: no - actions: - - path: cmd.exe - register: task_with_s4u_check - check_mode: yes - -- name: get result of task with s4u principal (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: task_with_s4u_result_check - -- name: assert results of task with s4u principal (check mode) - assert: - that: - - task_with_s4u_check is changed - - task_with_s4u_result_check.task_exists == True - - task_with_s4u_result_check.principal.group_id == None - - task_with_s4u_result_check.principal.logon_type == "TASK_LOGON_PASSWORD" - - task_with_s4u_result_check.principal.run_level == "TASK_RUNLEVEL_LUA" - - task_with_s4u_result_check.principal.user_id.endswith(test_scheduled_task_user) - -- name: task with s4u principal - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - username: '{{test_scheduled_task_user}}' - password: '{{test_scheduled_task_pass}}' - logon_type: s4u - update_password: no - actions: - - path: cmd.exe - register: task_with_s4u - -- name: get result of task with s4u principal - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: task_with_s4u_result - -- name: assert results of task with s4u principal - assert: - that: - - task_with_s4u is changed - - task_with_s4u_result.task_exists == True - - task_with_s4u_result.principal.group_id == None - - task_with_s4u_result.principal.logon_type == "TASK_LOGON_S4U" - - task_with_s4u_result.principal.run_level == "TASK_RUNLEVEL_LUA" - - task_with_s4u_result.principal.user_id.endswith(test_scheduled_task_user) - -- name: task with s4u principal (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - username: '{{test_scheduled_task_user}}' - password: '{{test_scheduled_task_pass}}' - logon_type: s4u - update_password: no - actions: - - path: cmd.exe - register: task_with_s4u_again - -- name: assert results of task with s4u principal (idempotent) - assert: - that: - - task_with_s4u_again is not changed - -- name: task with interactive principal (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - username: '{{test_scheduled_task_user}}' - logon_type: interactive_token - actions: - - path: cmd.exe - register: task_with_interactive_check - check_mode: yes - -- name: get result of task with interactive principal (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: task_with_interactive_result_check - -- name: assert results of task with interactive principal (check mode) - assert: - that: - - task_with_interactive_check is changed - - task_with_interactive_result_check.task_exists == True - - task_with_interactive_result_check.principal.group_id == None - - task_with_interactive_result_check.principal.logon_type == "TASK_LOGON_S4U" - - task_with_interactive_result_check.principal.run_level == "TASK_RUNLEVEL_LUA" - - task_with_interactive_result_check.principal.user_id.endswith(test_scheduled_task_user) - -- name: task with interactive principal - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - username: '{{test_scheduled_task_user}}' - logon_type: interactive_token - actions: - - path: cmd.exe - register: task_with_interactive - -- name: get result of task with interactive principal - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: task_with_interactive_result - -- name: assert results of task with interactive principal - assert: - that: - - task_with_interactive is changed - - task_with_interactive_result.task_exists == True - - task_with_interactive_result.principal.group_id == None - - task_with_interactive_result.principal.logon_type == "TASK_LOGON_INTERACTIVE_TOKEN" - - task_with_interactive_result.principal.run_level == "TASK_RUNLEVEL_LUA" - - task_with_interactive_result.principal.user_id.endswith(test_scheduled_task_user) - -- name: task with interactive principal (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - username: '{{test_scheduled_task_user}}' - logon_type: interactive_token - actions: - - path: cmd.exe - register: task_with_interactive_again - -- name: assert results of task with interactive principal (idempotent) - assert: - that: - - task_with_interactive_again is not changed - -- name: task with group principal (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - group: Administrators - logon_type: group - actions: - - path: cmd.exe - register: task_with_group_check - check_mode: yes - -- name: get result of task with group principal (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: task_with_group_result_check - -- name: assert results of task with group principal (check mode) - assert: - that: - - task_with_group_check is changed - - task_with_group_result_check.task_exists == True - - task_with_group_result_check.principal.group_id == None - - task_with_group_result_check.principal.logon_type == "TASK_LOGON_INTERACTIVE_TOKEN" - - task_with_group_result_check.principal.run_level == "TASK_RUNLEVEL_LUA" - - task_with_group_result_check.principal.user_id.endswith(test_scheduled_task_user) - -- name: task with group principal - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - group: Administrators - logon_type: group - actions: - - path: cmd.exe - register: task_with_group - -- name: get result of task with group principal - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: task_with_group_result - -- name: assert results of task with group principal - assert: - that: - - task_with_group is changed - - task_with_group_result.task_exists == True - - task_with_group_result.principal.group_id == "BUILTIN\\Administrators" - - task_with_group_result.principal.logon_type == "TASK_LOGON_GROUP" - - task_with_group_result.principal.run_level == "TASK_RUNLEVEL_LUA" - - task_with_group_result.principal.user_id == None - -- name: task with group principal (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - group: Administrators - logon_type: group - actions: - - path: cmd.exe - register: task_with_group_again - -- name: assert results of task with group principal (idempotent) - assert: - that: - - task_with_group_again is not changed - -- name: task with service account principal (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - username: System - logon_type: service_account - action: - - path: cmd.exe - register: task_with_service_check - check_mode: yes - -- name: get result of task with service account principal (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: task_with_service_result_check - -- name: assert results of task with service account principal (check mode) - assert: - that: - - task_with_service_check is changed - - task_with_service_result_check.task_exists == True - - task_with_service_result_check.principal.group_id == "BUILTIN\\Administrators" - - task_with_service_result_check.principal.logon_type == "TASK_LOGON_GROUP" - - task_with_service_result_check.principal.run_level == "TASK_RUNLEVEL_LUA" - - task_with_service_result_check.principal.user_id == None - -- name: task with service account principal - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - username: System - logon_type: service_account - action: - - path: cmd.exe - register: task_with_service - -- name: get result of task with service account principal - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: task_with_service_result - -- name: assert results of task with service account principal - assert: - that: - - task_with_service is changed - - task_with_service_result.task_exists == True - - task_with_service_result.principal.group_id == None - - task_with_service_result.principal.logon_type == "TASK_LOGON_SERVICE_ACCOUNT" - - task_with_service_result.principal.run_level == "TASK_RUNLEVEL_LUA" - - task_with_service_result.principal.user_id == "NT AUTHORITY\\SYSTEM" - -- name: task with service account principal (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - username: System - logon_type: service_account - action: - - path: cmd.exe - register: task_with_service_again - -- name: assert results of task with service account principal (idempotent) - assert: - that: - - task_with_service_again is not changed - -- name: task with highest privilege (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - run_level: highest - username: System - logon_type: service_account - action: - - path: cmd.exe - register: task_with_highest_privilege_check - check_mode: yes - -- name: get result of task with highest privilege (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: task_with_highest_privilege_result_check - -- name: assert results of task with highest privilege (check mode) - assert: - that: - - task_with_highest_privilege_check is changed - - task_with_highest_privilege_result_check.principal.run_level == "TASK_RUNLEVEL_LUA" - -- name: task with highest privilege - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - run_level: highest - username: System - logon_type: service_account - action: - - path: cmd.exe - register: task_with_highest_privilege - -- name: get result of task with highest privilege - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: task_with_highest_privilege_result - -- name: assert results of task with highest privilege - assert: - that: - - task_with_highest_privilege is changed - - task_with_highest_privilege_result.principal.run_level == "TASK_RUNLEVEL_HIGHEST" - -- name: task with highest privilege (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - run_level: highest - username: System - logon_type: service_account - action: - - path: cmd.exe - register: task_with_highest_privilege_again - -- name: assert results of task with highest privilege (idempotent) - assert: - that: - - task_with_highest_privilege_again is not changed diff --git a/test/integration/targets/win_scheduled_task/tasks/tests.yml b/test/integration/targets/win_scheduled_task/tasks/tests.yml deleted file mode 100644 index b4ed29e49f4..00000000000 --- a/test/integration/targets/win_scheduled_task/tasks/tests.yml +++ /dev/null @@ -1,440 +0,0 @@ ---- -- name: create task (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - arguments: /c echo hi - description: Original Description - register: create_task_check - check_mode: yes - -- name: get result of create task (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: create_task_result_check - -- name: assert results of create task (check mode) - assert: - that: - - create_task_check is changed - - create_task_result_check.task_exists == False - -- name: create task - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - arguments: /c echo hi - description: Original Description - register: create_task - -- name: get result of create task - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: create_task_result - -- name: assert results of create task - assert: - that: - - create_task is changed - - create_task_result.task_exists == True - - create_task_result.actions|count == 1 - - create_task_result.actions[0].path == "cmd.exe" - - create_task_result.actions[0].arguments == "/c echo hi" - - create_task_result.actions[0].working_directory == None - - create_task_result.registration_info.description == "Original Description" - - create_task_result.triggers|count == 0 - -- name: create task (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - arguments: /c echo hi - description: Original Description - register: create_task_again - -- name: assert results of create task (idempotent) - assert: - that: - - create_task_again is not changed - -- name: change task (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - author: Cow Inc. - description: Test for Ansible - allow_demand_start: no - restart_count: 5 - restart_interval: PT2H5M - register: change_task_check - check_mode: yes - -- name: get result of change task (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: change_task_result_check - -- name: assert results of change task (check mode) - assert: - that: - - change_task_check is changed - - change_task_result_check.actions|count == 1 - - change_task_result_check.registration_info.author == None - - change_task_result_check.registration_info.description == "Original Description" - - change_task_result_check.settings.allow_demand_start == true - - change_task_result_check.settings.restart_count == 0 - - change_task_result_check.settings.restart_interval == None - -- name: change task - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - author: Cow Inc. - description: Test for Ansible - allow_demand_start: no - restart_count: 5 - restart_interval: PT1M - register: change_task - -- name: get result of change task - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: change_task_result - -- name: assert results of change task - assert: - that: - - change_task is changed - - change_task_result.actions|count == 1 - - change_task_result.registration_info.author == "Cow Inc." - - change_task_result.registration_info.description == "Test for Ansible" - - change_task_result.settings.allow_demand_start == false - - change_task_result.settings.restart_count == 5 - - change_task_result.settings.restart_interval == "PT1M" - -- name: change task (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - author: Cow Inc. - description: Test for Ansible - allow_demand_start: no - restart_count: 5 - restart_interval: PT1M - register: change_task_again - -- name: assert results of change task (idempotent) - assert: - that: - - change_task_again is not changed - -- name: add task action (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - arguments: /c echo hi - - path: powershell.exe - arguments: -File C:\ansible\script.ps1 - working_directory: C:\ansible - register: add_task_action_check - check_mode: yes - -- name: get result of add task action (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: add_task_action_result_check - -- name: assert results of add task action (check mode) - assert: - that: - - add_task_action_check is changed - - add_task_action_result_check.actions|count == 1 - - add_task_action_result_check.actions[0].path == "cmd.exe" - - add_task_action_result_check.actions[0].arguments == "/c echo hi" - - add_task_action_result_check.actions[0].working_directory == None - -- name: add task action - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - arguments: /c echo hi - - path: powershell.exe - arguments: -File C:\ansible\script.ps1 - working_directory: C:\ansible - register: add_task_action - -- name: get result of add task action - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: add_task_action_result - -- name: assert results of add task action - assert: - that: - - add_task_action is changed - - add_task_action_result.actions|count == 2 - - add_task_action_result.actions[0].path == "cmd.exe" - - add_task_action_result.actions[0].arguments == "/c echo hi" - - add_task_action_result.actions[0].working_directory == None - - add_task_action_result.actions[1].path == "powershell.exe" - - add_task_action_result.actions[1].arguments == "-File C:\\ansible\\script.ps1" - - add_task_action_result.actions[1].working_directory == "C:\\ansible" - -- name: add task action (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - arguments: /c echo hi - - path: powershell.exe - arguments: -File C:\ansible\script.ps1 - working_directory: C:\ansible - register: add_task_action_again - -- name: assert results of add task action (idempotent) - assert: - that: - - add_task_action_again is not changed - -- name: remove task action (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: powershell.exe - arguments: -File C:\ansible\script.ps1 - working_directory: C:\ansible - register: remove_task_action_check - check_mode: yes - -- name: get result of remove task action (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: remove_task_action_result_check - -- name: assert results of remove task action (check mode) - assert: - that: - - remove_task_action_check is changed - - remove_task_action_result_check.actions|count == 2 - - remove_task_action_result_check.actions[0].path == "cmd.exe" - - remove_task_action_result_check.actions[0].arguments == "/c echo hi" - - remove_task_action_result_check.actions[0].working_directory == None - - remove_task_action_result_check.actions[1].path == "powershell.exe" - - remove_task_action_result_check.actions[1].arguments == "-File C:\\ansible\\script.ps1" - - remove_task_action_result_check.actions[1].working_directory == "C:\\ansible" - -- name: remove task action - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: powershell.exe - arguments: -File C:\ansible\script.ps1 - working_directory: C:\ansible - register: remove_task_action - -- name: get result of remove task action - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: remove_task_action_result - -- name: assert results of remove task action - assert: - that: - - remove_task_action is changed - - remove_task_action_result.actions|count == 1 - - remove_task_action_result.actions[0].path == "powershell.exe" - - remove_task_action_result.actions[0].arguments == "-File C:\\ansible\\script.ps1" - - remove_task_action_result.actions[0].working_directory == "C:\\ansible" - -- name: remove task action (idempontent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: powershell.exe - arguments: -File C:\ansible\script.ps1 - working_directory: C:\ansible - register: remove_task_action_again - -- name: assert results of remove task action (idempotent) - assert: - that: - - remove_task_action_again is not changed - -- name: remove task (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: absent - register: remove_task_check - check_mode: yes - -- name: get result of remove task (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: remove_task_result_check - -- name: assert results of remove task (check mode) - assert: - that: - - remove_task_check is changed - - remove_task_result_check.task_exists == True - -- name: remove task - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: absent - register: remove_task - -- name: get result of remove task - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: remove_task_result - -- name: assert results of remove task - assert: - that: - - remove_task is changed - - remove_task_result.task_exists == False - -- name: remove task (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: absent - register: remove_task_again - -- name: assert results of remove task (idempotent) - assert: - that: - - remove_task_again is not changed - -- name: create sole task in folder (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - path: '{{test_scheduled_task_path}}' - actions: - - path: cmd.exe - register: create_sole_task_check - check_mode: yes - -- name: get result of create sole task in folder (check mode) - win_scheduled_task_stat: - path: '{{test_scheduled_task_path}}' - name: '{{test_scheduled_task_name}}' - register: create_sole_task_result_check - -- name: assert results of create sole task in folder (check mode) - assert: - that: - - create_sole_task_check is changed - - create_sole_task_result_check.folder_exists == False - - create_sole_task_result_check.task_exists == False - -- name: create sole task in folder - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - path: '{{test_scheduled_task_path}}' - actions: - - path: cmd.exe - register: create_sole_task - -- name: get result of create sole task in folder - win_scheduled_task_stat: - path: '{{test_scheduled_task_path}}' - name: '{{test_scheduled_task_name}}' - register: create_sole_task_result - -- name: assert results of create sole task in folder - assert: - that: - - create_sole_task is changed - - create_sole_task_result.folder_exists == True - - create_sole_task_result.task_exists == True - -- name: create sole task in folder (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - path: '{{test_scheduled_task_path}}' - actions: - - path: cmd.exe - register: create_sole_task_again - -- name: assert results of create sole task in folder (idempotent) - assert: - that: - - create_sole_task_again is not changed - -- name: remove sole task in folder (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - path: '{{test_scheduled_task_path}}' - state: absent - register: remove_sole_task_check - check_mode: yes - -- name: get result of remove sole task in folder (check mode) - win_scheduled_task_stat: - path: '{{test_scheduled_task_path}}' - name: '{{test_scheduled_task_name}}' - register: remove_sole_task_result_check - -- name: assert results of remove sole task in folder (check mode) - assert: - that: - - remove_sole_task_check is changed - - remove_sole_task_result_check.folder_exists == True - - remove_sole_task_result_check.task_exists == True - -- name: remove sole task in folder - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - path: '{{test_scheduled_task_path}}' - state: absent - register: remove_sole_task - -- name: get result of remove sole task in folder - win_scheduled_task_stat: - path: '{{test_scheduled_task_path}}' - name: '{{test_scheduled_task_name}}' - register: remove_sole_task_result - -- name: assert results of remove sole task in folder - assert: - that: - - remove_sole_task is changed - - remove_sole_task_result.folder_exists == False - - remove_sole_task_result.task_exists == False - -- name: remove sole task in folder (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - path: '{{test_scheduled_task_path}}' - state: absent - register: remove_sole_task_again - -- name: assert results of remove sole task in folder (idempotent) - assert: - that: - - remove_sole_task_again is not changed diff --git a/test/integration/targets/win_scheduled_task/tasks/triggers.yml b/test/integration/targets/win_scheduled_task/tasks/triggers.yml deleted file mode 100644 index 15b274aede3..00000000000 --- a/test/integration/targets/win_scheduled_task/tasks/triggers.yml +++ /dev/null @@ -1,818 +0,0 @@ ---- -- name: create boot trigger (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: boot - register: trigger_boot_check - check_mode: yes - -- name: get result of create boot trigger (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: trigger_boot_result_check - -- name: assert results of create boot trigger (check mode) - assert: - that: - - trigger_boot_check is changed - - trigger_boot_result_check.task_exists == False - -- name: create boot trigger - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: boot - register: trigger_boot - -- name: get result of create boot trigger - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: trigger_boot_result - -- name: assert results of create boot trigger - assert: - that: - - trigger_boot is changed - - trigger_boot_result.task_exists == True - - trigger_boot_result.triggers|count == 1 - - trigger_boot_result.triggers[0].type == "TASK_TRIGGER_BOOT" - - trigger_boot_result.triggers[0].enabled == True - - trigger_boot_result.triggers[0].start_boundary == None - - trigger_boot_result.triggers[0].end_boundary == None - -- name: create boot trigger (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: boot - register: trigger_boot_again - -- name: assert results of create boot trigger (idempotent) - assert: - that: - - trigger_boot_again is not changed - -- name: create daily trigger (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: daily - start_boundary: '2000-01-01T00:00:01' - register: trigger_daily_check - check_mode: yes - -- name: get result of create daily trigger (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: trigger_daily_result_check - -- name: assert results of create daily trigger (check mode) - assert: - that: - - trigger_daily_check is changed - - trigger_daily_result_check.task_exists == True - - trigger_daily_result_check.triggers|count == 1 - - trigger_daily_result_check.triggers[0].type == "TASK_TRIGGER_BOOT" - - trigger_daily_result_check.triggers[0].enabled == True - - trigger_daily_result_check.triggers[0].start_boundary == None - - trigger_daily_result_check.triggers[0].end_boundary == None - -- name: create daily trigger - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: daily - start_boundary: '2000-01-01T00:00:01' - register: trigger_daily - -- name: get result of create daily trigger - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: trigger_daily_result - -- name: assert results of create daily trigger - assert: - that: - - trigger_daily is changed - - trigger_daily_result.task_exists == True - - trigger_daily_result.triggers|count == 1 - - trigger_daily_result.triggers[0].type == "TASK_TRIGGER_DAILY" - - trigger_daily_result.triggers[0].enabled == True - - trigger_daily_result.triggers[0].start_boundary == "2000-01-01T00:00:01" - - trigger_daily_result.triggers[0].end_boundary == None - -- name: create daily trigger (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: daily - start_boundary: '2000-01-01T00:00:01' - register: trigger_daily_again - -- name: assert results of create daily trigger (idempotent) - assert: - that: - - trigger_daily_again is not changed - -- name: create logon trigger (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: logon - register: trigger_logon_check - check_mode: yes - -- name: get result of create logon trigger (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: trigger_logon_result_check - -- name: assert results of create logon trigger - assert: - that: - - trigger_logon_check is changed - - trigger_logon_result_check.task_exists == True - - trigger_logon_result_check.triggers|count == 1 - - trigger_logon_result_check.triggers[0].type == "TASK_TRIGGER_DAILY" - - trigger_logon_result_check.triggers[0].enabled == True - - trigger_logon_result_check.triggers[0].start_boundary == "2000-01-01T00:00:01" - - trigger_logon_result_check.triggers[0].end_boundary == None - -- name: create logon trigger - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: logon - register: trigger_logon - -- name: get result of create logon trigger - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: trigger_logon_result - -- name: assert results of create logon trigger - assert: - that: - - trigger_logon is changed - - trigger_logon_result.task_exists == True - - trigger_logon_result.triggers|count == 1 - - trigger_logon_result.triggers[0].type == "TASK_TRIGGER_LOGON" - - trigger_logon_result.triggers[0].enabled == True - - trigger_logon_result.triggers[0].start_boundary == None - - trigger_logon_result.triggers[0].end_boundary == None - -- name: create logon trigger (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: logon - register: trigger_logon_again - -- name: assert results of create logon trigger (idempotent) - assert: - that: - - trigger_logon_again is not changed - -- name: create monthly dow trigger (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: monthlydow - start_boundary: '2000-01-01T00:00:01' - weeks_of_month: 1,2 - days_of_week: [ "monday", "wednesday" ] - register: trigger_monthlydow_check - check_mode: yes - -- name: get result of create monthly dow trigger (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: trigger_monthlydow_result_check - -- name: assert results of create monthly dow trigger (check mode) - assert: - that: - - trigger_monthlydow_check is changed - - trigger_monthlydow_result_check.task_exists == True - - trigger_monthlydow_result_check.triggers|count == 1 - - trigger_monthlydow_result_check.triggers[0].type == "TASK_TRIGGER_LOGON" - - trigger_monthlydow_result_check.triggers[0].enabled == True - - trigger_monthlydow_result_check.triggers[0].start_boundary == None - - trigger_monthlydow_result_check.triggers[0].end_boundary == None - -- name: create monthly dow trigger - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: monthlydow - start_boundary: '2000-01-01T00:00:01+03:00' - weeks_of_month: 1,2 - days_of_week: [ "monday", "wednesday" ] - register: trigger_monthlydow - -- name: get result of create monthly dow trigger - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: trigger_monthlydow_result - -- name: assert results of create monthly dow trigger - assert: - that: - - trigger_monthlydow is changed - - trigger_monthlydow_result.task_exists == True - - trigger_monthlydow_result.triggers|count == 1 - - trigger_monthlydow_result.triggers[0].type == "TASK_TRIGGER_MONTHLYDOW" - - trigger_monthlydow_result.triggers[0].enabled == True - - trigger_monthlydow_result.triggers[0].start_boundary == "1999-12-31T21:00:01+00:00" - - trigger_monthlydow_result.triggers[0].end_boundary == None - - trigger_monthlydow_result.triggers[0].weeks_of_month == "1,2" - - trigger_monthlydow_result.triggers[0].days_of_week == "monday,wednesday" - -- name: create monthly dow trigger (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: monthlydow - start_boundary: '2000-01-01T00:00:01+03:00' - weeks_of_month: 1,2 - days_of_week: [ "monday", "wednesday" ] - register: trigger_monthlydow_again - -- name: assert results of create monthly dow trigger (idempotent) - assert: - that: - - trigger_monthlydow_again is not changed - -- name: create trigger repetition (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: registration - repetition: - # TODO: change to dict in 2.12 as a list format is deprecated - - interval: PT1M - duration: PT5M - stop_at_duration_end: yes - register: create_trigger_repetition_check - check_mode: yes - -- name: get result of create trigger repetition (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: create_trigger_repetition_result_check - -- name: assert results of create trigger repetition (check mode) - assert: - that: - - create_trigger_repetition_check is changed - - create_trigger_repetition_check.deprecations|count == 1 - - create_trigger_repetition_check.deprecations[0].version == "2.12" - - create_trigger_repetition_check.deprecations[0].msg == "repetition is a list, should be defined as a dict" - - create_trigger_repetition_result_check.task_exists == True - - create_trigger_repetition_result_check.triggers|count == 1 - - create_trigger_repetition_result_check.triggers[0].type == "TASK_TRIGGER_MONTHLYDOW" - - create_trigger_repetition_result_check.triggers[0].enabled == True - - create_trigger_repetition_result_check.triggers[0].start_boundary == "1999-12-31T21:00:01+00:00" - - create_trigger_repetition_result_check.triggers[0].end_boundary == None - - create_trigger_repetition_result_check.triggers[0].weeks_of_month == "1,2" - - create_trigger_repetition_result_check.triggers[0].days_of_week == "monday,wednesday" - - create_trigger_repetition_result_check.triggers[0].repetition.interval == None - - create_trigger_repetition_result_check.triggers[0].repetition.duration == None - - create_trigger_repetition_result_check.triggers[0].repetition.stop_at_duration_end == False - -- name: create trigger repetition - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: registration - repetition: - interval: PT1M - duration: PT5M - stop_at_duration_end: yes - register: create_trigger_repetition - -- name: get result of create trigger repetition - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: create_trigger_repetition_result - -- name: assert results of create trigger repetition - assert: - that: - - create_trigger_repetition is changed - - create_trigger_repetition_result.task_exists == True - - create_trigger_repetition_result.triggers|count == 1 - - create_trigger_repetition_result.triggers[0].type == "TASK_TRIGGER_REGISTRATION" - - create_trigger_repetition_result.triggers[0].enabled == True - - create_trigger_repetition_result.triggers[0].start_boundary == None - - create_trigger_repetition_result.triggers[0].end_boundary == None - - create_trigger_repetition_result.triggers[0].repetition.interval == "PT1M" - - create_trigger_repetition_result.triggers[0].repetition.duration == "PT5M" - - create_trigger_repetition_result.triggers[0].repetition.stop_at_duration_end == True - -- name: create trigger repetition (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: registration - repetition: - interval: PT1M - duration: PT5M - stop_at_duration_end: yes - register: create_trigger_repetition_again - -- name: assert results of create trigger repetition (idempotent) - assert: - that: - - create_trigger_repetition_again is not changed - -- name: change trigger repetition (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: registration - repetition: - interval: PT10M - duration: PT20M - stop_at_duration_end: no - register: change_trigger_repetition_check - check_mode: yes - -- name: get result of change trigger repetition (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: change_trigger_repetition_result_check - -- name: assert results of change trigger repetition (check mode) - assert: - that: - - change_trigger_repetition_check is changed - - change_trigger_repetition_result_check.task_exists == True - - change_trigger_repetition_result_check.triggers|count == 1 - - change_trigger_repetition_result_check.triggers[0].type == "TASK_TRIGGER_REGISTRATION" - - change_trigger_repetition_result_check.triggers[0].enabled == True - - change_trigger_repetition_result_check.triggers[0].start_boundary == None - - change_trigger_repetition_result_check.triggers[0].end_boundary == None - - change_trigger_repetition_result_check.triggers[0].repetition.interval == "PT1M" - - change_trigger_repetition_result_check.triggers[0].repetition.duration == "PT5M" - - change_trigger_repetition_result_check.triggers[0].repetition.stop_at_duration_end == True - -- name: change trigger repetition - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: registration - repetition: - interval: PT10M - duration: PT20M - stop_at_duration_end: no - register: change_trigger_repetition - -- name: get result of change trigger repetition - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: change_trigger_repetition_result - -- name: assert results of change trigger repetition - assert: - that: - - change_trigger_repetition is changed - - change_trigger_repetition_result.task_exists == True - - change_trigger_repetition_result.triggers|count == 1 - - change_trigger_repetition_result.triggers[0].type == "TASK_TRIGGER_REGISTRATION" - - change_trigger_repetition_result.triggers[0].enabled == True - - change_trigger_repetition_result.triggers[0].start_boundary == None - - change_trigger_repetition_result.triggers[0].end_boundary == None - - change_trigger_repetition_result.triggers[0].repetition.interval == "PT10M" - - change_trigger_repetition_result.triggers[0].repetition.duration == "PT20M" - - change_trigger_repetition_result.triggers[0].repetition.stop_at_duration_end == False - -- name: change trigger repetition (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: registration - repetition: - interval: PT10M - duration: PT20M - stop_at_duration_end: no - register: change_trigger_repetition_again - -- name: assert results of change trigger repetition (idempotent) - assert: - that: - - change_trigger_repetition_again is not changed - -- name: create task with multiple triggers (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: monthly - days_of_month: 1,5,10,15,20,25,30 - run_on_last_day_of_month: true - start_boundary: '2000-01-01T00:00:01' - months_of_year: - - march - - may - - july - - type: time - start_boundary: '2000-01-01T00:00:01' - random_delay: PT10M5S - register: create_multiple_triggers_check - check_mode: yes - -- name: get result of create task with multiple triggers (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: create_multiple_triggers_result_check - -- name: assert results of create task with multiple triggers (check mode) - assert: - that: - - create_multiple_triggers_check is changed - - create_multiple_triggers_result_check.task_exists == True - - create_multiple_triggers_result_check.triggers|count == 1 - - create_multiple_triggers_result_check.triggers[0].type == "TASK_TRIGGER_REGISTRATION" - - create_multiple_triggers_result_check.triggers[0].enabled == True - - create_multiple_triggers_result_check.triggers[0].start_boundary == None - - create_multiple_triggers_result_check.triggers[0].end_boundary == None - - create_multiple_triggers_result_check.triggers[0].repetition.interval == "PT10M" - - create_multiple_triggers_result_check.triggers[0].repetition.duration == "PT20M" - - create_multiple_triggers_result_check.triggers[0].repetition.stop_at_duration_end == False - -- name: create task with multiple triggers - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: monthly - days_of_month: 1,5,10,15,20,25,30 - run_on_last_day_of_month: true - start_boundary: '2000-01-01T00:00:01' - months_of_year: - - march - - may - - july - - type: time - start_boundary: '2000-01-01T00:00:01' - random_delay: PT10M5S - register: create_multiple_triggers - -- name: get result of create task with multiple triggers - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: create_multiple_triggers_result - -- name: assert results of create task with multiple triggers - assert: - that: - - create_multiple_triggers is changed - - create_multiple_triggers_result.task_exists == True - - create_multiple_triggers_result.triggers|count == 2 - - create_multiple_triggers_result.triggers[0].type == "TASK_TRIGGER_MONTHLY" - - create_multiple_triggers_result.triggers[0].enabled == True - - create_multiple_triggers_result.triggers[0].start_boundary == "2000-01-01T00:00:01" - - create_multiple_triggers_result.triggers[0].end_boundary == None - - create_multiple_triggers_result.triggers[0].days_of_month == "1,5,10,15,20,25,30" - - create_multiple_triggers_result.triggers[0].months_of_year == "march,may,july" - - create_multiple_triggers_result.triggers[0].run_on_last_day_of_month == True - - create_multiple_triggers_result.triggers[1].type == "TASK_TRIGGER_TIME" - - create_multiple_triggers_result.triggers[1].enabled == True - - create_multiple_triggers_result.triggers[1].start_boundary == "2000-01-01T00:00:01" - - create_multiple_triggers_result.triggers[1].end_boundary == None - - create_multiple_triggers_result.triggers[1].random_delay == "PT10M5S" - -- name: create task with multiple triggers (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: monthly - days_of_month: 1,5,10,15,20,25,30 - run_on_last_day_of_month: true - start_boundary: '2000-01-01T00:00:01' - months_of_year: - - march - - may - - july - - type: time - start_boundary: '2000-01-01T00:00:01' - random_delay: PT10M5S - register: create_multiple_triggers_again - -- name: assert results of create task with multiple triggers (idempotent) - assert: - that: - - create_multiple_triggers_again is not changed - -- name: change task with multiple triggers (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: weekly - days_of_week: tuesday,friday - start_boundary: '2000-01-01T00:00:01' - - type: registration - enabled: no - register: change_multiple_triggers_check - check_mode: yes - -- name: get result of change task with multiple triggers (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: change_multiple_triggers_result_check - -- name: assert results of change task with multiple triggers (check mode) - assert: - that: - - change_multiple_triggers_check is changed - - change_multiple_triggers_result_check.task_exists == True - - change_multiple_triggers_result_check.triggers|count == 2 - - change_multiple_triggers_result_check.triggers[0].type == "TASK_TRIGGER_MONTHLY" - - change_multiple_triggers_result_check.triggers[0].enabled == True - - change_multiple_triggers_result_check.triggers[0].start_boundary == "2000-01-01T00:00:01" - - change_multiple_triggers_result_check.triggers[0].end_boundary == None - - change_multiple_triggers_result_check.triggers[0].days_of_month == "1,5,10,15,20,25,30" - - change_multiple_triggers_result_check.triggers[0].months_of_year == "march,may,july" - - change_multiple_triggers_result_check.triggers[0].run_on_last_day_of_month == True - - change_multiple_triggers_result_check.triggers[1].type == "TASK_TRIGGER_TIME" - - change_multiple_triggers_result_check.triggers[1].enabled == True - - change_multiple_triggers_result_check.triggers[1].start_boundary == "2000-01-01T00:00:01" - - change_multiple_triggers_result_check.triggers[1].end_boundary == None - - change_multiple_triggers_result_check.triggers[1].random_delay == "PT10M5S" - -- name: change task with multiple triggers - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: weekly - days_of_week: tuesday,friday - start_boundary: '2000-01-01T00:00:01' - - type: registration - enabled: no - register: change_multiple_triggers - -- name: get result of change task with multiple triggers - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: change_multiple_triggers_result - -- name: assert results of change task with multiple triggers - assert: - that: - - change_multiple_triggers is changed - - change_multiple_triggers_result.task_exists == True - - change_multiple_triggers_result.triggers|count == 2 - - change_multiple_triggers_result.triggers[0].type == "TASK_TRIGGER_WEEKLY" - - change_multiple_triggers_result.triggers[0].enabled == True - - change_multiple_triggers_result.triggers[0].start_boundary == "2000-01-01T00:00:01" - - change_multiple_triggers_result.triggers[0].end_boundary == None - - change_multiple_triggers_result.triggers[0].days_of_week == "tuesday,friday" - - change_multiple_triggers_result.triggers[1].type == "TASK_TRIGGER_REGISTRATION" - - change_multiple_triggers_result.triggers[1].enabled == False - - change_multiple_triggers_result.triggers[1].start_boundary == None - - change_multiple_triggers_result.triggers[1].end_boundary == None - -- name: change task with multiple triggers (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: weekly - days_of_week: tuesday,friday - start_boundary: '2000-01-01T00:00:01' - - type: registration - enabled: no - register: change_multiple_triggers_again - -- name: assert results of change task with multiple triggers (idempotent) - assert: - that: - - change_multiple_triggers_again is not changed - -- name: remove trigger from multiple triggers (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: registration - enabled: no - register: remove_single_trigger_check - check_mode: yes - -- name: get result of remove trigger from multiple triggers (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: remove_single_trigger_result_check - -- name: assert results of remove trigger from multiple triggers (check mode) - assert: - that: - - remove_single_trigger_check is changed - - remove_single_trigger_result_check.task_exists == True - - remove_single_trigger_result_check.triggers|count == 2 - - remove_single_trigger_result_check.triggers[0].type == "TASK_TRIGGER_WEEKLY" - - remove_single_trigger_result_check.triggers[0].enabled == True - - remove_single_trigger_result_check.triggers[0].start_boundary == "2000-01-01T00:00:01" - - remove_single_trigger_result_check.triggers[0].end_boundary == None - - remove_single_trigger_result_check.triggers[0].days_of_week == "tuesday,friday" - - remove_single_trigger_result_check.triggers[1].type == "TASK_TRIGGER_REGISTRATION" - - remove_single_trigger_result_check.triggers[1].enabled == False - - remove_single_trigger_result_check.triggers[1].start_boundary == None - - remove_single_trigger_result_check.triggers[1].end_boundary == None - -- name: remove trigger from multiple triggers - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: registration - enabled: no - register: remove_single_trigger - -- name: get result of remove trigger from multiple triggers - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: remove_single_trigger_result - -- name: assert results of remove trigger from multiple triggers - assert: - that: - - remove_single_trigger is changed - - remove_single_trigger_result.task_exists == True - - remove_single_trigger_result.triggers|count == 1 - - remove_single_trigger_result.triggers[0].type == "TASK_TRIGGER_REGISTRATION" - - remove_single_trigger_result.triggers[0].enabled == False - - remove_single_trigger_result.triggers[0].start_boundary == None - - remove_single_trigger_result.triggers[0].end_boundary == None - -- name: remove trigger from multiple triggers (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: - - type: registration - enabled: no - register: remove_single_trigger_again - -- name: assert results of remove trigger from multiple triggers (idempotent) - assert: - that: - - remove_single_trigger_again is not changed - -- name: remove all triggers (check mode) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: [] - register: remove_triggers_check - check_mode: yes - -- name: get result of remove all triggers (check mode) - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: remove_triggers_result_check - -- name: assert results of remove all triggers (check mode) - assert: - that: - - remove_triggers_check is changed - - remove_triggers_result_check.task_exists == True - - remove_triggers_result_check.triggers|count == 1 - - remove_triggers_result_check.triggers[0].type == "TASK_TRIGGER_REGISTRATION" - - remove_triggers_result_check.triggers[0].enabled == False - - remove_triggers_result_check.triggers[0].start_boundary == None - - remove_triggers_result_check.triggers[0].end_boundary == None - -- name: remove all triggers - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: [] - register: remove_triggers - -- name: get result of remove all triggers - win_scheduled_task_stat: - path: \ - name: '{{test_scheduled_task_name}}' - register: remove_triggers_result - -- name: assert results of remove all triggers - assert: - that: - - remove_triggers is changed - - remove_triggers_result.task_exists == True - - remove_triggers_result.triggers|count == 0 - -- name: remove all triggers (idempotent) - win_scheduled_task: - name: '{{test_scheduled_task_name}}' - state: present - actions: - - path: cmd.exe - triggers: [] - register: remove_triggers_again - -- name: assert results of remove all triggers (idempotent) - assert: - that: - - remove_triggers_again is not changed diff --git a/test/integration/targets/win_scheduled_task_stat/aliases b/test/integration/targets/win_scheduled_task_stat/aliases deleted file mode 100644 index 4cd27b3cb2f..00000000000 --- a/test/integration/targets/win_scheduled_task_stat/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group1 diff --git a/test/integration/targets/win_scheduled_task_stat/defaults/main.yml b/test/integration/targets/win_scheduled_task_stat/defaults/main.yml deleted file mode 100644 index 24efaf0de7e..00000000000 --- a/test/integration/targets/win_scheduled_task_stat/defaults/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -test_scheduled_task_stat_name: Test Task -test_scheduled_task_stat_path: \test path diff --git a/test/integration/targets/win_scheduled_task_stat/tasks/main.yml b/test/integration/targets/win_scheduled_task_stat/tasks/main.yml deleted file mode 100644 index ee78abb0c05..00000000000 --- a/test/integration/targets/win_scheduled_task_stat/tasks/main.yml +++ /dev/null @@ -1,176 +0,0 @@ ---- -- name: Look up built-in Administrator account name (-500 user whose domain == computer name) - raw: $machine_sid = (Get-CimInstance Win32_UserAccount -Filter "Domain='$env:COMPUTERNAME'")[0].SID -replace '(S-1-5-21-\d+-\d+-\d+)-\d+', '$1'; (Get-CimInstance Win32_UserAccount -Filter "SID='$machine_sid-500'").Name - check_mode: no - register: admin_account_result - -- set_fact: - admin_account_name: "{{ admin_account_result.stdout_lines[0] }}" - -- name: ensure task is deleted before test - win_scheduled_task: - name: '{{test_scheduled_task_stat_name}}' - path: '{{test_scheduled_task_stat_path}}' - state: absent - -# folder stat tests -- name: get stat of a folder that is missing - win_scheduled_task_stat: - path: '{{test_scheduled_task_stat_path}}' - register: stat_folder_missing - -- name: assert get stat of a folder that is missing - assert: - that: - - stat_folder_missing.folder_exists == False - -- name: get stat of existing folder - win_scheduled_task_stat: - path: \ - register: stat_folder_present - -- name: assert get stat of existing folder - assert: - that: - - stat_folder_present.folder_exists == True - - stat_folder_present.folder_task_count is defined - - stat_folder_present.folder_task_names is defined - -- name: create scheduled task in folder - win_scheduled_task: - path: '{{test_scheduled_task_stat_path}}' - name: '{{test_scheduled_task_stat_name}}' - state: present - logon_type: interactive_token - username: '{{ admin_account_name }}' - author: Ansible Author - description: Fake description - execution_time_limit: PT23H - disallow_start_if_on_batteries: false - restart_count: 3 - restart_interval: PT15M - actions: - - path: cmd.exe - - path: C:\temp\some.exe - arguments: --help - working_directory: C:\temp - triggers: - - type: boot - delay: PT15M - - type: monthly - days_of_month: 5,15,30 - months_of_year: june,december - run_on_last_day_of_month: true - start_boundary: '2017-09-20T03:44:38' - -- name: get stat of existing folder with task - win_scheduled_task_stat: - path: '{{test_scheduled_task_stat_path}}' - register: stat_folder_with_task - -- name: assert get stat of existing folder with task - assert: - that: - - stat_folder_with_task.folder_exists == True - - stat_folder_with_task.folder_task_count == 1 - - stat_folder_with_task.folder_task_names[0] == "Test Task" - - stat_folder_with_task.task_exists is not defined - -# task stat tests -- name: get stat of missing task with invalid folder - win_scheduled_task_stat: - path: fake path - name: fake task - register: stat_task_missing_folder - -- name: assert get stat of missing task with invalid folder - assert: - that: - - stat_task_missing_folder.folder_exists == False - - stat_task_missing_folder.task_exists == False - -- name: get stat of missing task - win_scheduled_task_stat: - path: '{{test_scheduled_task_stat_path}}' - name: fake task - register: stat_task_missing - -- name: assert get stat of missing task - assert: - that: - - stat_task_missing.task_exists == False - -- name: get stat of existing task - win_scheduled_task_stat: - path: '{{test_scheduled_task_stat_path}}' - name: '{{test_scheduled_task_stat_name}}' - register: stat_task_present - -- name: assert get stat of existing task - assert: - that: - - stat_task_present.task_exists == True - - stat_task_present.actions|count == 2 - - stat_task_present.actions[0].path == "cmd.exe" - - stat_task_present.actions[0].type == "TASK_ACTION_EXEC" - - stat_task_present.actions[0].working_directory == None - - stat_task_present.actions[1].arguments == "--help" - - stat_task_present.actions[1].path == "C:\\temp\some.exe" - - stat_task_present.actions[1].type == "TASK_ACTION_EXEC" - - stat_task_present.actions[1].working_directory == "C:\\temp" - - stat_task_present.principal.display_name == None - - stat_task_present.principal.group_id == None - - stat_task_present.principal.logon_type == "TASK_LOGON_INTERACTIVE_TOKEN" - - stat_task_present.principal.run_level == "TASK_RUNLEVEL_LUA" - - stat_task_present.principal.user_id.endswith(admin_account_name) - - stat_task_present.registration_info.author == "Ansible Author" - - stat_task_present.registration_info.date is defined - - stat_task_present.registration_info.description == "Fake description" - - stat_task_present.settings.disallow_start_if_on_batteries == False - - stat_task_present.settings.execution_time_limit == "PT23H" - - stat_task_present.settings.restart_count == 3 - - stat_task_present.settings.restart_interval == "PT15M" - - stat_task_present.state.status == "TASK_STATE_READY" - - stat_task_present.triggers|count == 2 - - stat_task_present.triggers[0].delay == "PT15M" - - stat_task_present.triggers[0].type == "TASK_TRIGGER_BOOT" - - stat_task_present.triggers[0].repetition.stop_at_duration_end == False - - stat_task_present.triggers[0].repetition.duration == None - - stat_task_present.triggers[0].repetition.interval == None - - stat_task_present.triggers[1].days_of_month == "5,15,30" - - stat_task_present.triggers[1].months_of_year == "june,december" - - stat_task_present.triggers[1].run_on_last_day_of_month == True - - stat_task_present.triggers[1].start_boundary == "2017-09-20T03:44:38" - - stat_task_present.triggers[1].type == "TASK_TRIGGER_MONTHLY" - - stat_task_present.triggers[1].repetition.stop_at_duration_end == False - - stat_task_present.triggers[1].repetition.duration == None - - stat_task_present.triggers[1].repetition.interval == None - -- name: change principal to system account so it will run in the next step - win_scheduled_task: - name: '{{test_scheduled_task_stat_name}}' - path: '{{test_scheduled_task_stat_path}}' - username: SYSTEM - -- name: start the scheduled task - win_command: schtasks.exe /Run /TN "{{test_scheduled_task_stat_path}}\{{test_scheduled_task_stat_name}}" - -- name: get stat of running task - win_scheduled_task_stat: - path: '{{test_scheduled_task_stat_path}}' - name: '{{test_scheduled_task_stat_name}}' - register: stat_task_running - -- name: assert stat of running task - assert: - that: - - stat_task_running.state.status == "TASK_STATE_RUNNING" - -- name: stop the scheduled task - win_command: schtasks.exe /End /TN "{{test_scheduled_task_stat_path}}\{{test_scheduled_task_stat_name}}" - -- name: ensure task is delete after test - win_scheduled_task: - name: '{{test_scheduled_task_stat_name}}' - path: '{{test_scheduled_task_stat_path}}' - state: absent diff --git a/test/integration/targets/win_security_policy/aliases b/test/integration/targets/win_security_policy/aliases deleted file mode 100644 index 423ce391085..00000000000 --- a/test/integration/targets/win_security_policy/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group2 diff --git a/test/integration/targets/win_security_policy/library/test_win_security_policy.ps1 b/test/integration/targets/win_security_policy/library/test_win_security_policy.ps1 deleted file mode 100644 index 5c83c1b5d0d..00000000000 --- a/test/integration/targets/win_security_policy/library/test_win_security_policy.ps1 +++ /dev/null @@ -1,53 +0,0 @@ -#!powershell - -# WANT_JSON -# POWERSHELL_COMMON - -# basic script to get the lsit of users in a particular right -# this is quite complex to put as a simple script so this is -# just a simple module - -$ErrorActionPreference = 'Stop' - -$params = Parse-Args $args -supports_check_mode $false -$section = Get-AnsibleParam -obj $params -name "section" -type "str" -failifempty $true -$key = Get-AnsibleParam -obj $params -name "key" -type "str" -failifempty $true - -$result = @{ - changed = $false -} - -Function ConvertFrom-Ini($file_path) { - $ini = @{} - switch -Regex -File $file_path { - "^\[(.+)\]" { - $section = $matches[1] - $ini.$section = @{} - } - "(.+?)\s*=(.*)" { - $name = $matches[1].Trim() - $value = $matches[2].Trim() - if ($value -match "^\d+$") { - $value = [int]$value - } elseif ($value.StartsWith('"') -and $value.EndsWith('"')) { - $value = $value.Substring(1, $value.Length - 2) - } - - $ini.$section.$name = $value - } - } - - $ini -} - -$secedit_ini_path = [IO.Path]::GetTempFileName() -&SecEdit.exe /export /cfg $secedit_ini_path /quiet -$secedit_ini = ConvertFrom-Ini -file_path $secedit_ini_path - -if ($secedit_ini.ContainsKey($section)) { - $result.value = $secedit_ini.$section.$key -} else { - $result.value = $null -} - -Exit-Json $result diff --git a/test/integration/targets/win_security_policy/tasks/main.yml b/test/integration/targets/win_security_policy/tasks/main.yml deleted file mode 100644 index 28fdb5ea094..00000000000 --- a/test/integration/targets/win_security_policy/tasks/main.yml +++ /dev/null @@ -1,41 +0,0 @@ ---- -- name: get current entry for audit - test_win_security_policy: - section: Event Audit - key: AuditSystemEvents - register: before_value_audit - -- name: get current entry for guest - test_win_security_policy: - section: System Access - key: NewGuestName - register: before_value_guest - -- block: - - name: set AuditSystemEvents entry before tests - win_security_policy: - section: Event Audit - key: AuditSystemEvents - value: 0 - - - name: set NewGuestName entry before tests - win_security_policy: - section: System Access - key: NewGuestName - value: Guest - - - name: run tests - include_tasks: tests.yml - - always: - - name: reset entries for AuditSystemEvents - win_security_policy: - section: Event Audit - key: AuditSystemEvents - value: "{{before_value_audit.value}}" - - - name: reset entries for NewGuestName - win_security_policy: - section: System Access - key: NewGuestName - value: "{{before_value_guest.value}}" diff --git a/test/integration/targets/win_security_policy/tasks/tests.yml b/test/integration/targets/win_security_policy/tasks/tests.yml deleted file mode 100644 index 724b6010a34..00000000000 --- a/test/integration/targets/win_security_policy/tasks/tests.yml +++ /dev/null @@ -1,186 +0,0 @@ ---- -- name: fail with invalid section name - win_security_policy: - section: This is not a valid section - key: KeyName - value: 0 - register: fail_invalid_section - failed_when: fail_invalid_section.msg != "The section 'This is not a valid section' does not exist in SecEdit.exe output ini" - -- name: fail with invalid key name - win_security_policy: - section: System Access - key: InvalidKey - value: 0 - register: fail_invalid_key - failed_when: fail_invalid_key.msg != "The key 'InvalidKey' in section 'System Access' is not a valid key, cannot set this value" - -- name: change existing key check - win_security_policy: - section: Event Audit - key: AuditSystemEvents - value: 1 - register: change_existing_check - check_mode: yes - -- name: get actual change existing key check - test_win_security_policy: - section: Event Audit - key: AuditSystemEvents - register: change_existing_actual_check - -- name: assert change existing key check - assert: - that: - - change_existing_check is changed - - change_existing_actual_check.value == 0 - -- name: change existing key - win_security_policy: - section: Event Audit - key: AuditSystemEvents - value: 1 - register: change_existing - -- name: get actual change existing key - test_win_security_policy: - section: Event Audit - key: AuditSystemEvents - register: change_existing_actual - -- name: assert change existing key - assert: - that: - - change_existing is changed - - change_existing_actual.value == 1 - -- name: change existing key again - win_security_policy: - section: Event Audit - key: AuditSystemEvents - value: 1 - register: change_existing_again - -- name: assert change existing key again - assert: - that: - - change_existing_again is not changed - - change_existing_again.value == 1 - -- name: change existing key with string type - win_security_policy: - section: Event Audit - key: AuditSystemEvents - value: "1" - register: change_existing_key_with_type - -- name: assert change existing key with string type - assert: - that: - - change_existing_key_with_type is not changed - - change_existing_key_with_type.value == "1" - -- name: change existing string key check - win_security_policy: - section: System Access - key: NewGuestName - value: New Guest - register: change_existing_string_check - check_mode: yes - -- name: get actual change existing string key check - test_win_security_policy: - section: System Access - key: NewGuestName - register: change_existing_string_actual_check - -- name: assert change existing string key check - assert: - that: - - change_existing_string_check is changed - - change_existing_string_actual_check.value == "Guest" - -- name: change existing string key - win_security_policy: - section: System Access - key: NewGuestName - value: New Guest - register: change_existing_string - -- name: get actual change existing string key - test_win_security_policy: - section: System Access - key: NewGuestName - register: change_existing_string_actual - -- name: assert change existing string key - assert: - that: - - change_existing_string is changed - - change_existing_string_actual.value == "New Guest" - -- name: change existing string key again - win_security_policy: - section: System Access - key: NewGuestName - value: New Guest - register: change_existing_string_again - -- name: assert change existing string key again - assert: - that: - - change_existing_string_again is not changed - - change_existing_string_again.value == "New Guest" - -- name: add policy setting - win_security_policy: - section: Privilege Rights - # following key is empty by default - key: SeCreateTokenPrivilege - # add Guests - value: '*S-1-5-32-546' - -- name: get actual policy setting - test_win_security_policy: - section: Privilege Rights - key: SeCreateTokenPrivilege - register: add_policy_setting_actual - -- name: assert add policy setting - assert: - that: - - add_policy_setting_actual.value == '*S-1-5-32-546' - -- name: remove policy setting - win_security_policy: - section: Privilege Rights - key: SeCreateTokenPrivilege - value: '' - diff: yes - register: remove_policy_setting - -- name: get actual policy setting - test_win_security_policy: - section: Privilege Rights - key: SeCreateTokenPrivilege - register: remove_policy_setting_actual - -- name: assert remove policy setting - assert: - that: - - remove_policy_setting is changed - - remove_policy_setting.diff.prepared == "[Privilege Rights]\n-SeCreateTokenPrivilege = *S-1-5-32-546\n+SeCreateTokenPrivilege = " - - remove_policy_setting_actual.value is none - -- name: remove policy setting again - win_security_policy: - section: Privilege Rights - key: SeCreateTokenPrivilege - value: '' - register: remove_policy_setting_again - -- name: assert remove policy setting again - assert: - that: - - remove_policy_setting_again is not changed - - remove_policy_setting_again.value == '' diff --git a/test/integration/targets/win_shortcut/aliases b/test/integration/targets/win_shortcut/aliases deleted file mode 100644 index 423ce391085..00000000000 --- a/test/integration/targets/win_shortcut/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group2 diff --git a/test/integration/targets/win_shortcut/tasks/clean.yml b/test/integration/targets/win_shortcut/tasks/clean.yml deleted file mode 100644 index 5fa892186b7..00000000000 --- a/test/integration/targets/win_shortcut/tasks/clean.yml +++ /dev/null @@ -1,37 +0,0 @@ -# Test code for the file module. -# (c) 2017, Dag Wieers - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -- name: Clean up Ansible website link - win_file: - path: '%UserProfile%\Desktop\Ansible website.url' - state: absent - -- name: Clean up Registry Editor shortcut - win_file: - path: '%Public%\Desktop\Registry Editor.lnk' - state: absent - -- name: Clean up Shell path shortcut - win_file: - path: '%Public%\bin.lnk' - state: absent - -- name: Clean up Executable shortcut - win_file: - path: '%Public%\Desktop\cmd.lnk' - state: absent diff --git a/test/integration/targets/win_shortcut/tasks/main.yml b/test/integration/targets/win_shortcut/tasks/main.yml deleted file mode 100644 index cf04ea3b5ba..00000000000 --- a/test/integration/targets/win_shortcut/tasks/main.yml +++ /dev/null @@ -1,34 +0,0 @@ -# Test code for the file module. -# (c) 2017, Dag Wieers - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -- name: Clean slate - import_tasks: clean.yml - -- name: Test in normal mode - import_tasks: tests.yml - vars: - in_check_mode: no - -- name: Clean slate - import_tasks: clean.yml - -- name: Test in check-mode - import_tasks: tests.yml - vars: - in_check_mode: yes - check_mode: yes diff --git a/test/integration/targets/win_shortcut/tasks/tests.yml b/test/integration/targets/win_shortcut/tasks/tests.yml deleted file mode 100644 index 2797598b43e..00000000000 --- a/test/integration/targets/win_shortcut/tasks/tests.yml +++ /dev/null @@ -1,367 +0,0 @@ -# Test code for the file module. -# (c) 2017, Dag Wieers - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -- name: get current user profile location - raw: $env:USERPROFILE - check_mode: no - register: profile_result - -- set_fact: - profile_dir: '{{ profile_result.stdout_lines[0] }}' - -- name: Add Ansible website link on the desktop - win_shortcut: - src: https://ansible.com/ - dest: '%UserProfile%\Desktop\Ansible website.url' - state: present - register: ansible_website_link_add - -- name: Check there was a change - assert: - that: - - ansible_website_link_add.changed == true - - ansible_website_link_add.dest == profile_dir + '\Desktop\Ansible website.url' - - ansible_website_link_add.src == 'https://ansible.com/' - -- name: Add Ansible website link on the desktop again - win_shortcut: - src: https://ansible.com/ - dest: '%UserProfile%\Desktop\Ansible website.url' - state: present - register: ansible_website_link_add_again - -- name: Check there was no change (normal mode) - assert: - that: - - ansible_website_link_add_again.changed == false - - ansible_website_link_add_again.dest == profile_dir + '\Desktop\Ansible website.url' - - ansible_website_link_add_again.src == 'https://ansible.com/' - when: not in_check_mode - -- name: Check there was a change (check-mode) - assert: - that: - - ansible_website_link_add_again.changed == true - - ansible_website_link_add_again.dest == profile_dir + '\Desktop\Ansible website.url' - - ansible_website_link_add_again.src == 'https://ansible.com/' - when: in_check_mode - -- name: Remove link - win_shortcut: - dest: '%UserProfile%\Desktop\Ansible website.url' - state: absent - register: ansible_website_link_remove - -- name: Check there was a change (normal mode) - assert: - that: - - ansible_website_link_remove.changed == true - - ansible_website_link_remove.dest == profile_dir + '\Desktop\Ansible website.url' - when: not in_check_mode - -- name: Check there was no change (check-mode) - assert: - that: - - ansible_website_link_remove.changed == false - - ansible_website_link_remove.dest == profile_dir + '\Desktop\Ansible website.url' - when: in_check_mode - -- name: Remove link again - win_shortcut: - dest: '%UserProfile%\Desktop\Ansible website.url' - state: absent - register: ansible_website_link_remove_again - -- name: Check there was no change - assert: - that: - - ansible_website_link_remove_again.changed == false - - ansible_website_link_remove_again.dest == profile_dir + '\Desktop\Ansible website.url' - -- name: Add a regedit shortcut on the desktop - win_shortcut: - description: "Registry Editor" - src: regedit.exe - dest: '%Public%\Desktop\Registry Editor.lnk' - state: present - register: regedit_shortcut_add - -- name: Check there was a change - assert: - that: - - regedit_shortcut_add.changed == true - - regedit_shortcut_add.description == 'Registry Editor' - - regedit_shortcut_add.dest == 'C:\\Users\\Public\\Desktop\\Registry Editor.lnk' - - regedit_shortcut_add.src == 'C:\\Windows\\regedit.exe' - -- name: Add a regedit shortcut on the desktop again - win_shortcut: - description: "Registry Editor" - src: regedit.exe - dest: '%Public%\Desktop\Registry Editor.lnk' - state: present - register: regedit_shortcut_add_again - -- name: Check there was no change (normal mode) - assert: - that: - - regedit_shortcut_add_again.changed == false - - regedit_shortcut_add_again.description == 'Registry Editor' - - regedit_shortcut_add_again.dest == 'C:\\Users\\Public\\Desktop\\Registry Editor.lnk' - - regedit_shortcut_add_again.src == 'C:\\Windows\\regedit.exe' - when: not in_check_mode - -- name: Check there was a change (check-mode) - assert: - that: - - regedit_shortcut_add_again.changed == true - - regedit_shortcut_add_again.description == 'Registry Editor' - - regedit_shortcut_add_again.dest == 'C:\\Users\\Public\\Desktop\\Registry Editor.lnk' - - regedit_shortcut_add_again.src == 'C:\\Windows\\regedit.exe' - when: in_check_mode - -- name: Update a regedit shortcut on the desktop - win_shortcut: - description: "Registry Editor" - src: C:\BogusPath\regedit.exe - dest: '%Public%\Desktop\Registry Editor.lnk' - state: present - register: regedit_shortcut_update - -- name: Check there was a change - assert: - that: - - regedit_shortcut_update.changed == true - - regedit_shortcut_update.description == 'Registry Editor' - - regedit_shortcut_update.dest == 'C:\\Users\\Public\\Desktop\\Registry Editor.lnk' - - regedit_shortcut_update.src == 'C:\\BogusPath\\regedit.exe' - -- name: Update a regedit shortcut on the desktop again - win_shortcut: - description: "Registry Editor" - src: C:\BogusPath\regedit.exe - dest: '%Public%\Desktop\Registry Editor.lnk' - state: present - register: regedit_shortcut_update_again - -- name: Check there was no change (normal mode) - assert: - that: - - regedit_shortcut_update_again.changed == false - - regedit_shortcut_update_again.description == 'Registry Editor' - - regedit_shortcut_update_again.dest == 'C:\\Users\\Public\\Desktop\\Registry Editor.lnk' - - regedit_shortcut_update_again.src == 'C:\\BogusPath\\regedit.exe' - when: not in_check_mode - -- name: Check there was a change (check-mode) - assert: - that: - - regedit_shortcut_update_again.changed == true - - regedit_shortcut_update_again.description == 'Registry Editor' - - regedit_shortcut_update_again.dest == 'C:\\Users\\Public\\Desktop\\Registry Editor.lnk' - - regedit_shortcut_update_again.src == 'C:\\BogusPath\\regedit.exe' - when: in_check_mode - -- name: Add an (explicit) icon - win_shortcut: - description: "Registry Editor" - src: C:\Windows\regedit.exe - dest: '%Public%\Desktop\Registry Editor.lnk' - icon: 'C:\Windows\regedit.exe,0' - state: present - register: regedit_shortcut_add_icon - -- name: Check there was a change - assert: - that: - - regedit_shortcut_add_icon.changed == true - - regedit_shortcut_add_icon.description == 'Registry Editor' - - regedit_shortcut_add_icon.dest == 'C:\\Users\\Public\\Desktop\\Registry Editor.lnk' - - regedit_shortcut_add_icon.icon == 'C:\\Windows\\regedit.exe,0' - - regedit_shortcut_add_icon.src == 'C:\\Windows\\regedit.exe' - -- name: Add an (explicit) icon again - win_shortcut: - description: "Registry Editor" - src: C:\Windows\regedit.exe - dest: '%Public%\Desktop\Registry Editor.lnk' - icon: 'C:\Windows\regedit.exe,0' - state: present - register: regedit_shortcut_add_icon_again - -- name: Check there was no change (normal mode) - assert: - that: - - regedit_shortcut_add_icon_again.changed == false - - regedit_shortcut_add_icon_again.description == 'Registry Editor' - - regedit_shortcut_add_icon_again.dest == 'C:\\Users\\Public\\Desktop\\Registry Editor.lnk' - - regedit_shortcut_add_icon_again.icon == 'C:\\Windows\\regedit.exe,0' - - regedit_shortcut_add_icon_again.src == 'C:\\Windows\\regedit.exe' - when: not in_check_mode - -- name: Check there was a change (check-mode) - assert: - that: - - regedit_shortcut_add_icon_again.changed == true - - regedit_shortcut_add_icon_again.description == 'Registry Editor' - - regedit_shortcut_add_icon_again.dest == 'C:\\Users\\Public\\Desktop\\Registry Editor.lnk' - - regedit_shortcut_add_icon_again.icon == 'C:\\Windows\\regedit.exe,0' - - regedit_shortcut_add_icon_again.src == 'C:\\Windows\\regedit.exe' - when: in_check_mode - -- name: Remove shortcut - win_shortcut: - dest: '%Public%\Desktop\Registry Editor.lnk' - state: absent - register: regedit_shortcut_remove - -- name: Check there was a change (normal mode) - assert: - that: - - regedit_shortcut_remove.changed == true - - regedit_shortcut_remove.dest == 'C:\\Users\\Public\\Desktop\\Registry Editor.lnk' - when: not in_check_mode - -- name: Check there was no change (check-mode) - assert: - that: - - regedit_shortcut_remove.changed == false - - regedit_shortcut_remove.dest == 'C:\\Users\\Public\\Desktop\\Registry Editor.lnk' - when: in_check_mode - -- name: Remove shortcut again - win_shortcut: - dest: '%Public%\Desktop\Registry Editor.lnk' - state: absent - register: regedit_shortcut_remove_again - -- name: Check there was no change - assert: - that: - - regedit_shortcut_remove_again.changed == false - - regedit_shortcut_remove_again.dest == 'C:\\Users\\Public\\Desktop\\Registry Editor.lnk' - -- name: Create shortcut to shell path - win_shortcut: - dest: '%Public%\bin.lnk' - src: shell:RecycleBinFolder - state: present - register: shell_add - -- name: Check there was a change - assert: - that: - - shell_add is changed - - shell_add.dest == 'C:\\Users\\Public\\bin.lnk' - - shell_add.src == 'shell:RecycleBinFolder' - -- name: Create shortcut to shell path again - win_shortcut: - dest: '%Public%\bin.lnk' - src: shell:RecycleBinFolder - state: present - register: shell_add_again - -- name: Check there was no change (normal mode) - assert: - that: - - not shell_add_again is changed - - shell_add_again.src == 'shell:RecycleBinFolder' - when: not in_check_mode - -- name: Check there was a change (check-mode) - assert: - that: - - shell_add_again is changed - when: in_check_mode - -- name: Change shortcut to another shell path - win_shortcut: - dest: '%Public%\bin.lnk' - src: shell:Start Menu - state: present - register: shell_change - -- name: Check there was a change - assert: - that: - - shell_change is changed - - shell_change.src == 'shell:Start Menu' - -- name: Create shortcut to an executable without run as admin - win_shortcut: - dest: '%Public%\Desktop\cmd.lnk' - src: '%SystemRoot%\System32\cmd.exe' - state: present - register: shell_exe_limited - -- name: Get run as admin flag state - win_shell: | - $shortcut = "$env:Public\Desktop\cmd.lnk" - $flags = [System.BitConverter]::ToUInt32([System.IO.FIle]::ReadAllBytes($shortcut), 20) - ($flags -band 0x00002000) -eq 0x00002000 - register: shell_exe_limited_actual - -- name: Check that run as admin flag wasn't set (normal mode) - assert: - that: - - shell_exe_limited is changed - - not shell_exe_limited_actual.stdout_lines[0]|bool - when: not in_check_mode - -- name: Check that exe shortcut results in a change (check-mode) - assert: - that: - - shell_exe_limited is changed - when: in_check_mode - -- name: Set shortcut to run as admin - win_shortcut: - dest: '%Public%\Desktop\cmd.lnk' - src: '%SystemRoot%\System32\cmd.exe' - run_as_admin: True - state: present - register: shell_exe_admin - -- name: Get run as admin flag state - win_shell: | - $shortcut = "$env:Public\Desktop\cmd.lnk" - $flags = [System.BitConverter]::ToUInt32([System.IO.FIle]::ReadAllBytes($shortcut), 20) - ($flags -band 0x00002000) -eq 0x00002000 - register: shell_exe_admin_actual - -- name: Check that run as admin flag was set (normal mode) - assert: - that: - - shell_exe_admin is changed - - shell_exe_admin_actual.stdout_lines[0]|bool - when: not in_check_mode - -- name: Set shortcut to run as admin again - win_shortcut: - dest: '%Public%\Desktop\cmd.lnk' - src: '%SystemRoot%\System32\cmd.exe' - run_as_admin: True - state: present - register: shell_exe_admin_again - -- name: Check that set run as admin wasn't changed (normal mode) - assert: - that: - - not shell_exe_admin_again is changed - when: not in_check_mode diff --git a/test/integration/targets/win_snmp/aliases b/test/integration/targets/win_snmp/aliases deleted file mode 100644 index 219895f4bc9..00000000000 --- a/test/integration/targets/win_snmp/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group2 -skip/windows/2016 # Host takes a while to run and module isn't OS dependent diff --git a/test/integration/targets/win_snmp/tasks/cleanup.yml b/test/integration/targets/win_snmp/tasks/cleanup.yml deleted file mode 100644 index 28d98debeae..00000000000 --- a/test/integration/targets/win_snmp/tasks/cleanup.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- - - name: Make sure there are no existing SNMP configuration settings - win_regedit: - path: "{{ item }}" - state: absent - loop: - - "{{ permitted_managers_key }}" - - "{{ valid_communities_key }}" - - - name: Create skeleton registry keys for SNMP - win_regedit: - path: "{{ item }}" - state: present - loop: - - "{{ permitted_managers_key }}" - - "{{ valid_communities_key }}" diff --git a/test/integration/targets/win_snmp/tasks/cleanup_using_module.yml b/test/integration/targets/win_snmp/tasks/cleanup_using_module.yml deleted file mode 100644 index 290de7fc1f2..00000000000 --- a/test/integration/targets/win_snmp/tasks/cleanup_using_module.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- - - name: Set no SNMP community or SNMP manager - register: snmp_cleanup - win_snmp: - action: set - community_strings: [] - permitted_managers: [] - - - name: Check registry for no SNMP community - register: snmp_cleanup_reg_community - win_reg_stat: - path: "{{ valid_communities_key }}" - name: snmp-cleanup - - - name: Check registry for no SNMP manager - register: snmp_cleanup_reg_manager - win_reg_stat: - path: "{{ permitted_managers_key }}" - name: 1 - - - name: Asset SNMP set operation results in no remaining SNMP details - assert: - that: - - snmp_cleanup.changed - - snmp_cleanup_reg_community.exists == false - - snmp_cleanup_reg_manager.exists == false diff --git a/test/integration/targets/win_snmp/tasks/main.yml b/test/integration/targets/win_snmp/tasks/main.yml deleted file mode 100644 index 09000d6e906..00000000000 --- a/test/integration/targets/win_snmp/tasks/main.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- - - include_tasks: cleanup.yml - - include_tasks: snmp_community.yml - - include_tasks: cleanup.yml - - include_tasks: snmp_managers.yml - - include_tasks: output_only.yml - - include_tasks: cleanup_using_module.yml - - include_tasks: cleanup.yml diff --git a/test/integration/targets/win_snmp/tasks/output_only.yml b/test/integration/targets/win_snmp/tasks/output_only.yml deleted file mode 100644 index 7115da45d20..00000000000 --- a/test/integration/targets/win_snmp/tasks/output_only.yml +++ /dev/null @@ -1,24 +0,0 @@ ---- - # Already tested - - name: Add an SNMP manager and an SNMP community - win_snmp: - action: add - community_strings: - - snmp-cleanup - permitted_managers: - - 192.168.1.1 - - - name: Run without options - register: snmp_no_options - win_snmp: - - - name: Assert no changes occurred when no options provided - assert: - that: - - not snmp_no_options.changed - - - name: Assert community strings and permitted managers are correctly returned - assert: - that: - - "'snmp-cleanup' in snmp_no_options.community_strings" - - "'192.168.1.1' in snmp_no_options.permitted_managers" diff --git a/test/integration/targets/win_snmp/tasks/snmp_community.yml b/test/integration/targets/win_snmp/tasks/snmp_community.yml deleted file mode 100644 index 47a06297f20..00000000000 --- a/test/integration/targets/win_snmp/tasks/snmp_community.yml +++ /dev/null @@ -1,165 +0,0 @@ ---- - - name: Add initial SNMP community - register: snmp_community - win_snmp: - action: add - community_strings: - - ansible-ro-test - - - name: Check initial SNMP community exists in registry - register: snmp_community_reg - win_reg_stat: - path: "{{ valid_communities_key }}" - name: ansible-ro-test - - - name: Assert initial SNMP community is correct - assert: - that: - - snmp_community is changed - - snmp_community_reg.exists - - snmp_community_reg.type == 'REG_DWORD' - - snmp_community_reg.value == 4 - - - name: Add initial SNMP community again - register: snmp_community_again - win_snmp: - action: add - community_strings: - - ansible-ro-test - - - name: Check no change occurred when adding SNMP community again - assert: - that: - - snmp_community_again is not changed - - - name: Add next SNMP community - register: snmp_community_next - win_snmp: - action: add - community_strings: - - ansible-ro-test-next - - - name: Check initial SNMP community still exists in registry - register: snmp_community_reg_orig - win_reg_stat: - path: "{{ valid_communities_key }}" - name: ansible-ro-test - - - name: Check next SNMP community exists in registry - register: snmp_community_reg_next - win_reg_stat: - path: "{{ valid_communities_key }}" - name: ansible-ro-test-next - - - name: Assert initial SNMP community still exists - assert: - that: - - snmp_community_reg_orig.exists - - snmp_community_reg_orig.type == 'REG_DWORD' - - snmp_community_reg_orig.value == 4 - - - name: Assert next SNMP community exists - assert: - that: - - snmp_community_next is changed - - snmp_community_reg_next.exists - - snmp_community_reg_next.type == 'REG_DWORD' - - snmp_community_reg_next.value == 4 - - - name: Replace SNMP community - register: snmp_community_replace - win_snmp: - action: set - community_strings: - - ansible-ro-test-replace - - - name: Check initial SNMP community does not exist in registry - register: snmp_community_reg_orig_replace - win_reg_stat: - path: "{{ valid_communities_key }}" - name: ansible-ro-test - - - name: Check next SNMP community does not exist in registry - register: snmp_community_reg_next_replace - win_reg_stat: - path: "{{ valid_communities_key }}" - name: ansible-ro-test-next - - - name: Check replace SNMP community exists in registry - register: snmp_community_reg_replace - win_reg_stat: - path: "{{ valid_communities_key }}" - name: ansible-ro-test-replace - - - name: Assert replace SNMP community exists and others are replaced - assert: - that: - - snmp_community_replace is changed - - snmp_community_reg_orig_replace.exists == false - - snmp_community_reg_next_replace.exists == false - - snmp_community_reg_replace.exists - - snmp_community_reg_replace.type == 'REG_DWORD' - - snmp_community_reg_replace.value == 4 - - # This task has already been tested - - name: Add another SNMP community before testing removal - win_snmp: - action: add - community_strings: - - ansible-ro-remove-add - - - name: Remove the replaced SNMP community - register: snmp_community_remove - win_snmp: - action: remove - community_strings: - - ansible-ro-test-replace - - - name: Check replace SNMP community is removed in registry - register: snmp_community_reg_remove - win_reg_stat: - path: "{{ valid_communities_key }}" - name: ansible-ro-test-replace - - - name: Check SNMP community that was added for testing removal exists in registry - register: snmp_community_reg_remove_add - win_reg_stat: - path: "{{ valid_communities_key }}" - name: ansible-ro-remove-add - - - name: Assert removal of SNMP community succeeded and next SNMP community remains - assert: - that: - - snmp_community_remove is changed - - snmp_community_reg_remove.exists == false - - snmp_community_reg_remove_add.exists - - snmp_community_reg_remove_add.type == 'REG_DWORD' - - snmp_community_reg_remove_add.value == 4 - - - name: Remove the replaced SNMP community (again) - register: snmp_community_remove - win_snmp: - action: remove - community_strings: - - ansible-ro-test-replace - - - name: Check replace SNMP community is removed in registry (again) - register: snmp_community_reg_remove - win_reg_stat: - path: "{{ valid_communities_key }}" - name: ansible-ro-test-replace - - - name: Check SNMP community that was added for testing removal exists in registry (again) - register: snmp_community_reg_remove_add - win_reg_stat: - path: "{{ valid_communities_key }}" - name: ansible-ro-remove-add - - - name: Assert removal of SNMP community succeeded and next SNMP community remains (again) - assert: - that: - - snmp_community_remove is not changed - - snmp_community_reg_remove.exists == false - - snmp_community_reg_remove_add.exists - - snmp_community_reg_remove_add.type == 'REG_DWORD' - - snmp_community_reg_remove_add.value == 4 diff --git a/test/integration/targets/win_snmp/tasks/snmp_managers.yml b/test/integration/targets/win_snmp/tasks/snmp_managers.yml deleted file mode 100644 index dedd0767f10..00000000000 --- a/test/integration/targets/win_snmp/tasks/snmp_managers.yml +++ /dev/null @@ -1,158 +0,0 @@ ---- - - name: Add initial SNMP manager - register: snmp_manager - win_snmp: - action: add - permitted_managers: - - 192.168.1.1 - - - name: Check initial SNMP manager exists in registry - register: snmp_manager_reg - win_reg_stat: - path: "{{ permitted_managers_key }}" - name: 1 - - - name: Assert initial SNMP manager is correct - assert: - that: - - snmp_manager is changed - - snmp_manager_reg.exists - - snmp_manager_reg.type == 'REG_SZ' - - snmp_manager_reg.value == '192.168.1.1' - - - name: Add initial SNMP manager again - register: snmp_manager_again - win_snmp: - action: add - permitted_managers: - - 192.168.1.1 - - - name: Check no change occurred when adding SNMP manager again - assert: - that: - - snmp_manager_again is not changed - - - name: Add next SNMP manager - register: snmp_manager_next - win_snmp: - action: add - permitted_managers: - - 192.168.1.2 - - - name: Check initial SNMP manager still exists in registry - register: snmp_manager_reg_orig - win_reg_stat: - path: "{{ permitted_managers_key }}" - name: 1 - - - name: Check next SNMP manager exists in registry - register: snmp_manager_reg_next - win_reg_stat: - path: "{{ permitted_managers_key }}" - name: 2 - - - name: Assert initial SNMP manager still exists - assert: - that: - - snmp_manager_reg_orig.exists - - snmp_manager_reg_orig.type == 'REG_SZ' - - snmp_manager_reg_orig.value == '192.168.1.1' - - - name: Assert next SNMP manager exists - assert: - that: - - snmp_manager_next is changed - - snmp_manager_reg_next.exists - - snmp_manager_reg_next.type == 'REG_SZ' - - snmp_manager_reg_next.value == '192.168.1.2' - - - name: Replace SNMP manager - register: snmp_manager_replace - win_snmp: - action: set - permitted_managers: - - 192.168.1.10 - - - name: Check next SNMP manager does not exist in registry - register: snmp_manager_reg_next_replace - win_reg_stat: - path: "{{ permitted_managers_key }}" - name: 2 - - - name: Check replace SNMP manager exists in registry (overrides original slot) - register: snmp_manager_reg_replace - win_reg_stat: - path: "{{ permitted_managers_key }}" - name: 1 - - - name: Assert replace SNMP manager exists and others are replaced - assert: - that: - - snmp_manager_replace is changed - - snmp_manager_reg_next_replace.exists == false - - snmp_manager_reg_replace.exists - - snmp_manager_reg_replace.type == 'REG_SZ' - - snmp_manager_reg_replace.value == '192.168.1.10' - - # This task has already been tested - - name: Add another SNMP manager before testing removal - win_snmp: - action: add - permitted_managers: - - 192.168.1.20 - - - name: Remove the replaced SNMP manager - register: snmp_manager_remove - win_snmp: - action: remove - permitted_managers: - - 192.168.1.10 - - - name: Check replace SNMP manager is removed in registry - register: snmp_manager_reg_remove - win_reg_stat: - path: "{{ permitted_managers_key }}" - name: 1 - - - name: Check SNMP manager that was added for testing removal exists in registry - register: snmp_manager_reg_remove_add - win_reg_stat: - path: "{{ permitted_managers_key }}" - name: 2 - - - name: Assert removal of SNMP manager succeeded and next SNMP manager remains - assert: - that: - - snmp_manager_remove is changed - - snmp_manager_reg_remove.exists == false - - snmp_manager_reg_remove_add.exists - - snmp_manager_reg_remove_add.type == 'REG_SZ' - - snmp_manager_reg_remove_add.value == '192.168.1.20' - - - name: Remove the replaced SNMP manager (again) - register: snmp_manager_remove - win_snmp: - action: remove - permitted_managers: - - 192.168.1.10 - - - name: Check replace SNMP manager is removed in registry (again) - register: snmp_manager_reg_remove - win_reg_stat: - path: "{{ permitted_managers_key }}" - name: 1 - - - name: Check SNMP manager that was added for testing removal exists in registry (again) - register: snmp_manager_reg_remove_add - win_reg_stat: - path: "{{ permitted_managers_key }}" - name: 2 - - - name: Assert removal of SNMP manager succeeded and next SNMP manager remains (again) - assert: - that: - - snmp_manager_remove is not changed - - snmp_manager_reg_remove.exists == false - - snmp_manager_reg_remove_add.exists - - snmp_manager_reg_remove_add.type == 'REG_SZ' - - snmp_manager_reg_remove_add.value == '192.168.1.20' diff --git a/test/integration/targets/win_snmp/vars/main.yml b/test/integration/targets/win_snmp/vars/main.yml deleted file mode 100644 index 610be839fcc..00000000000 --- a/test/integration/targets/win_snmp/vars/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- - permitted_managers_key: 'HKLM:\System\CurrentControlSet\services\SNMP\Parameters\PermittedManagers' - valid_communities_key: 'HKLM:\System\CurrentControlSet\services\SNMP\Parameters\ValidCommunities' diff --git a/test/integration/targets/win_timezone/aliases b/test/integration/targets/win_timezone/aliases deleted file mode 100644 index 3cf5b97e805..00000000000 --- a/test/integration/targets/win_timezone/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_timezone/tasks/main.yml b/test/integration/targets/win_timezone/tasks/main.yml deleted file mode 100644 index b7cd0c5624d..00000000000 --- a/test/integration/targets/win_timezone/tasks/main.yml +++ /dev/null @@ -1,19 +0,0 @@ -- name: Determine if server has tzutil.exe installed - win_command: tzutil.exe /l - register: tzutil - ignore_errors: yes - -- name: Only run tests if tzutil.exe is installed - when: tzutil.rc == 0 - block: - - - name: Test in normal mode - import_tasks: tests.yml - vars: - in_check_mode: no - - - name: Test in check-mode - import_tasks: tests.yml - vars: - in_check_mode: yes - check_mode: yes diff --git a/test/integration/targets/win_timezone/tasks/tests.yml b/test/integration/targets/win_timezone/tasks/tests.yml deleted file mode 100644 index da5109f7f5e..00000000000 --- a/test/integration/targets/win_timezone/tasks/tests.yml +++ /dev/null @@ -1,100 +0,0 @@ -# NOTE: Set to a known starting value, store original -- name: Change starting timezone to GMT - win_timezone: - timezone: GMT Standard Time - register: original - -# NOTE: We don't know if it changed, we don't care -- name: Test GMT timezone - assert: - that: - - original.timezone == 'GMT Standard Time' - -- name: Change timezone to GMT+1 - win_timezone: - timezone: Romance Standard Time - register: romance - -- name: Test GMT+1 timezone - assert: - that: - - romance is changed - - romance.previous_timezone == 'GMT Standard Time' - - romance.timezone == 'Romance Standard Time' - when: not in_check_mode - -- name: Test GMT+1 timezone - assert: - that: - - romance is changed - - romance.previous_timezone == original.timezone - - romance.timezone == 'Romance Standard Time' - when: in_check_mode - -- name: Change timezone to GMT+1 again - win_timezone: - timezone: Romance Standard Time - register: romance - -- name: Test GMT+1 timezone - assert: - that: - - romance is not changed - - romance.previous_timezone == 'Romance Standard Time' - - romance.timezone == 'Romance Standard Time' - when: not in_check_mode - -- name: Test GMT+1 timezone - assert: - that: - - romance is changed - - romance.previous_timezone == original.timezone - - romance.timezone == 'Romance Standard Time' - when: in_check_mode - -- name: Change timezone to GMT+6 - win_timezone: - timezone: Central Standard Time - register: central - -- name: Test GMT-6 timezone - assert: - that: - - central is changed - - central.previous_timezone == 'Romance Standard Time' - - central.timezone == 'Central Standard Time' - when: not in_check_mode - -- name: Test GMT+1 timezone - assert: - that: - - central is changed - - central.previous_timezone == original.timezone - - central.timezone == 'Central Standard Time' - when: in_check_mode - -- name: Change timezone to dstoff - win_timezone: - timezone: Eastern Standard Time_dstoff - register: dstoff_result - -- name: Test dstoff timezone - assert: - that: - - dstoff_result is changed - - dstoff_result.timezone == 'Eastern Standard Time_dstoff' - -- name: Change timezone to GMT+666 - win_timezone: - timezone: Dag's Standard Time - register: dag - ignore_errors: yes - -- name: Test GMT+666 timezone - assert: - that: - - dag is failed - -- name: Restore original timezone - win_timezone: - timezone: '{{ original.timezone }}' diff --git a/test/integration/targets/win_toast/aliases b/test/integration/targets/win_toast/aliases deleted file mode 100644 index ebd7be7463e..00000000000 --- a/test/integration/targets/win_toast/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group1 -disabled diff --git a/test/integration/targets/win_toast/tasks/main.yml b/test/integration/targets/win_toast/tasks/main.yml deleted file mode 100644 index 735d55b1a92..00000000000 --- a/test/integration/targets/win_toast/tasks/main.yml +++ /dev/null @@ -1,13 +0,0 @@ -- name: Set up tests - import_tasks: setup.yml - -- name: Test in normal mode - import_tasks: tests.yml - vars: - in_check_mode: no - -- name: Test in check mode - import_tasks: tests.yml - vars: - in_check_mode: yes - check_mode: yes diff --git a/test/integration/targets/win_toast/tasks/setup.yml b/test/integration/targets/win_toast/tasks/setup.yml deleted file mode 100644 index 1fe3a22da19..00000000000 --- a/test/integration/targets/win_toast/tasks/setup.yml +++ /dev/null @@ -1,27 +0,0 @@ -- name: Get OS version - win_shell: '[Environment]::OSVersion.Version.Major' - register: os_version - -- name: Get logged in user count (using explorer exe as a proxy) - win_shell: (get-process -name explorer -EA silentlyContinue).Count - register: user_count - -- name: debug os_version - debug: - var: os_version - verbosity: 2 - -- name: debug user_count - debug: - var: user_count - verbosity: 2 - -- name: Set fact if toast cannot be made - set_fact: - can_toast: False - when: os_version.stdout|int < 10 - -- name: Set fact if toast can be made - set_fact: - can_toast: True - when: os_version.stdout|int >= 10 diff --git a/test/integration/targets/win_toast/tasks/tests.yml b/test/integration/targets/win_toast/tasks/tests.yml deleted file mode 100644 index d1d4ece1071..00000000000 --- a/test/integration/targets/win_toast/tasks/tests.yml +++ /dev/null @@ -1,106 +0,0 @@ -- name: Warn user - win_toast: - expire: 10 - msg: Keep calm and carry on. - register: msg_result - ignore_errors: True - -- name: Test msg_result when can_toast is true (normal mode, users) - assert: - that: - - msg_result is not failed - - msg_result.time_taken > 10 - when: - - can_toast == True - - in_check_mode == False - - user_count.stdout|int > 0 - -- name: Test msg_result when can_toast is true (normal mode, no users) - assert: - that: - - msg_result is not failed - - msg_result.time_taken > 0.1 - - msg_result.toast_sent == False - when: - - can_toast == True - - in_check_mode == False - - user_count.stdout|int == 0 - -- name: Test msg_result when can_toast is true (check mode, users) - assert: - that: - - msg_result is not failed - - msg_result.time_taken > 0.1 - when: - - can_toast == True - - in_check_mode == True - -- name: Test msg_result when can_toast is true (check mode, no users) - assert: - that: - - msg_result is not failed - - msg_result.time_taken > 0.1 - - msg_result.toast_sent == False - when: - - can_toast == True - - in_check_mode == True - - user_count.stdout|int == 0 - -- name: Test msg_result when can_toast is false - assert: - that: - - msg_result is failed - when: can_toast == False - -- name: Warn user again - win_toast: - expire: 10 - msg: Keep calm and carry on. - register: msg_result2 - ignore_errors: True - -- name: Test msg_result2 when can_toast is true (normal mode, users) - assert: - that: - - msg_result2 is not failed - - msg_result2.time_taken > 10 - when: - - can_toast == True - - in_check_mode == False - - user_count.stdout|int > 0 - -- name: Test msg_result2 when can_toast is true (normal mode, no users) - assert: - that: - - msg_result2 is not failed - - msg_result2.time_taken > 0.1 - when: - - can_toast == True - - in_check_mode == False - - user_count.stdout|int == 0 - -- name: Test msg_result2 when can_toast is true (check mode, users) - assert: - that: - - msg_result2 is not failed - - msg_result2.time_taken > 0.1 - when: - - can_toast == True - - in_check_mode == False - - user_count.stdout|int > 0 - -- name: Test msg_result2 when can_toast is true (check mode, no users) - assert: - that: - - msg_result2 is not failed - - msg_result2.time_taken > 0.1 - when: - - can_toast == True - - in_check_mode == False - - user_count.stdout|int == 0 - -- name: Test msg_result2 when can_toast is false - assert: - that: - - msg_result2 is failed - when: can_toast == False diff --git a/test/integration/targets/win_unzip/aliases b/test/integration/targets/win_unzip/aliases deleted file mode 100644 index 423ce391085..00000000000 --- a/test/integration/targets/win_unzip/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group2 diff --git a/test/integration/targets/win_unzip/defaults/main.yml b/test/integration/targets/win_unzip/defaults/main.yml deleted file mode 100644 index 52d808d88c0..00000000000 --- a/test/integration/targets/win_unzip/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ -win_unzip_dir: '{{ remote_tmp_dir }}\win_unzip .ÅÑŚÌβŁÈ [$!@^&test(;)]' diff --git a/test/integration/targets/win_unzip/files/create_crafty_zip_files.py b/test/integration/targets/win_unzip/files/create_crafty_zip_files.py deleted file mode 100644 index 8845b486294..00000000000 --- a/test/integration/targets/win_unzip/files/create_crafty_zip_files.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Copyright (c) 2020 Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -import os -import shutil -import sys -import zipfile - -# Each key is a zip file and the vaule is the list of files that will be created -# and placed in the archive -zip_files = { - 'hat1': [r'hat/..\rabbit.txt'], - 'hat2': [r'hat/..\..\rabbit.txt'], - 'handcuffs': [r'..\..\houidini.txt'], - 'prison': [r'..\houidini.txt'], -} - -# Accept an argument of where to create the files, defaulting to -# the current working directory. -try: - output_dir = sys.argv[1] -except IndexError: - output_dir = os.getcwd() - -if not os.path.isdir(output_dir): - os.mkdir(output_dir) - -os.chdir(output_dir) - -for name, files in zip_files.items(): - # Create the files to go in the zip archive - for entry in files: - dirname = os.path.dirname(entry) - if dirname: - if os.path.isdir(dirname): - shutil.rmtree(dirname) - os.mkdir(dirname) - - with open(entry, 'w') as e: - e.write('escape!\n') - - # Create the zip archive with the files - filename = '%s.zip' % name - if os.path.isfile(filename): - os.unlink(filename) - - with zipfile.ZipFile(filename, 'w') as zf: - for entry in files: - zf.write(entry) - - # Cleanup - if dirname: - shutil.rmtree(dirname) - - for entry in files: - try: - os.unlink(entry) - except OSError: - pass diff --git a/test/integration/targets/win_unzip/files/create_zip.py b/test/integration/targets/win_unzip/files/create_zip.py deleted file mode 100644 index 41b6ff068b4..00000000000 --- a/test/integration/targets/win_unzip/files/create_zip.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2019, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import sys -import tempfile -import zipfile - - -def main(): - filename = b"caf\xc3\xa9.txt" - - with tempfile.NamedTemporaryFile() as temp: - with open(temp.name, mode="wb") as fd: - fd.write(filename) - - with open(sys.argv[1], mode="wb") as fd: - with zipfile.ZipFile(fd, "w") as zip: - zip.write(temp.name, filename.decode('utf-8')) - - -if __name__ == '__main__': - main() diff --git a/test/integration/targets/win_unzip/meta/main.yml b/test/integration/targets/win_unzip/meta/main.yml deleted file mode 100644 index 9f37e96cd90..00000000000 --- a/test/integration/targets/win_unzip/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: -- setup_remote_tmp_dir diff --git a/test/integration/targets/win_unzip/tasks/main.yml b/test/integration/targets/win_unzip/tasks/main.yml deleted file mode 100644 index a9b8f1ca229..00000000000 --- a/test/integration/targets/win_unzip/tasks/main.yml +++ /dev/null @@ -1,171 +0,0 @@ -- name: create test directory - win_file: - path: '{{ win_unzip_dir }}\output' - state: directory - -- name: create local zip file with non-ascii chars - script: create_zip.py {{ output_dir + '/win_unzip.zip' | quote }} - delegate_to: localhost - -- name: copy across zip to Windows host - win_copy: - src: '{{ output_dir }}/win_unzip.zip' - dest: '{{ win_unzip_dir }}\win_unzip.zip' - -- name: unarchive zip (check) - win_unzip: - src: '{{ win_unzip_dir }}\win_unzip.zip' - dest: '{{ win_unzip_dir }}\output' - register: unzip_check - check_mode: yes - -- name: get result of unarchive zip (check) - win_stat: - path: '{{ win_unzip_dir }}\output\café.txt' - register: unzip_actual_check - -- name: assert result of unarchive zip (check) - assert: - that: - - unzip_check is changed - - not unzip_check.removed - - not unzip_actual_check.stat.exists - -- name: unarchive zip - win_unzip: - src: '{{ win_unzip_dir }}\win_unzip.zip' - dest: '{{ win_unzip_dir }}\output' - register: unzip - -- name: get result of unarchive zip - slurp: - path: '{{ win_unzip_dir }}\output\café.txt' - register: unzip_actual - -- name: assert result of unarchive zip - assert: - that: - - unzip is changed - - not unzip.removed - - unzip_actual.content | b64decode == 'café.txt' - -# Module is not idempotent, will always change without creates -- name: unarchive zip again without creates - win_unzip: - src: '{{ win_unzip_dir }}\win_unzip.zip' - dest: '{{ win_unzip_dir }}\output' - register: unzip_again - -- name: assert unarchive zip again without creates - assert: - that: - - unzip_again is changed - - not unzip_again.removed - -- name: unarchive zip with creates - win_unzip: - src: '{{ win_unzip_dir }}\win_unzip.zip' - dest: '{{ win_unzip_dir }}\outout' - creates: '{{ win_unzip_dir }}\output\café.txt' - register: unzip_again_creates - -- name: assert unarchive zip with creates - assert: - that: - - not unzip_again_creates is changed - - not unzip_again_creates.removed - -- name: unarchive zip with delete (check) - win_unzip: - src: '{{ win_unzip_dir }}\win_unzip.zip' - dest: '{{ win_unzip_dir }}\output' - delete_archive: yes - register: unzip_delete_check - check_mode: yes - -- name: get result of unarchive zip with delete (check) - win_stat: - path: '{{ win_unzip_dir }}\win_unzip.zip' - register: unzip_delete_actual_check - -- name: assert unarchive zip with delete (check) - assert: - that: - - unzip_delete_check is changed - - unzip_delete_check.removed - - unzip_delete_actual_check.stat.exists - -- name: unarchive zip with delete - win_unzip: - src: '{{ win_unzip_dir }}\win_unzip.zip' - dest: '{{ win_unzip_dir }}\output' - delete_archive: yes - register: unzip_delete - -- name: get result of unarchive zip with delete - win_stat: - path: '{{ win_unzip_dir }}\win_unzip.zip' - register: unzip_delete_actual - -- name: assert unarchive zip with delete - assert: - that: - - unzip_delete is changed - - unzip_delete.removed - - not unzip_delete_actual.stat.exists - -# Path traversal tests (CVE-2020-1737) -- name: Create zip files - script: create_crafty_zip_files.py {{ output_dir }} - delegate_to: localhost - -- name: Copy zip files to Windows host - win_copy: - src: "{{ output_dir }}/{{ item }}.zip" - dest: "{{ win_unzip_dir }}/" - loop: - - hat1 - - hat2 - - handcuffs - - prison - -- name: Perform first trick - win_unzip: - src: '{{ win_unzip_dir }}\hat1.zip' - dest: '{{ win_unzip_dir }}\output' - register: hat_trick1 - -- name: Check for file - win_stat: - path: '{{ win_unzip_dir }}\output\rabbit.txt' - register: rabbit - -- name: Perform next tricks (which should all fail) - win_unzip: - src: '{{ win_unzip_dir }}\{{ item }}.zip' - dest: '{{ win_unzip_dir }}\output' - ignore_errors: yes - register: escape - loop: - - hat2 - - handcuffs - - prison - -- name: Search for files - win_find: - recurse: yes - paths: - - '{{ win_unzip_dir }}' - patterns: - - '*houdini.txt' - - '*rabbit.txt' - register: files - -- name: Check results - assert: - that: - - rabbit.stat.exists - - hat_trick1 is success - - escape.results | map(attribute='failed') | unique | list == [True] - - files.matched == 1 - - files.files[0]['filename'] == 'rabbit.txt' diff --git a/test/integration/targets/win_user_profile/aliases b/test/integration/targets/win_user_profile/aliases deleted file mode 100644 index 4f4664b6858..00000000000 --- a/test/integration/targets/win_user_profile/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group5 diff --git a/test/integration/targets/win_user_profile/tasks/main.yml b/test/integration/targets/win_user_profile/tasks/main.yml deleted file mode 100644 index c37d219df34..00000000000 --- a/test/integration/targets/win_user_profile/tasks/main.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- -- name: set custom user facts - set_fact: - test_username: ansible_test - test_password: '{{ "password123!" + lookup("password", "/dev/null chars=ascii_letters,digits length=9") }}' - -- name: create test account - win_user: - name: '{{ test_username }}' - password: '{{ test_password }}' - state: present - register: test_username_info - -- block: - - name: check if profile exists - win_stat: - path: C:\temp\{{ test_username }} - register: profile_path - - - name: assert that profile doesn't exist before the test - assert: - that: - - not profile_path.stat.exists - - - name: run tests - include_tasks: tests.yml - - always: - - name: remove test account - win_user: - name: '{{ test_username }}' - state: absent - - - name: remove test account profile - win_user_profile: - name: '{{ item }}' - state: absent - remove_multiple: True - with_items: - - '{{ test_username }}' - - '{{ test_username }}.000' - - test_username_profile diff --git a/test/integration/targets/win_user_profile/tasks/tests.yml b/test/integration/targets/win_user_profile/tasks/tests.yml deleted file mode 100644 index 3c787f32170..00000000000 --- a/test/integration/targets/win_user_profile/tasks/tests.yml +++ /dev/null @@ -1,374 +0,0 @@ ---- -- name: create profile (check mode) - win_user_profile: - username: '{{ test_username }}' - state: present - register: create_profile_check - check_mode: True - -- name: check if profile was created (check mode) - win_stat: - path: C:\Users\{{ test_username }} - register: create_profile_actual_check - -- name: assert create profile (check mode) - assert: - that: - - create_profile_check is changed - - create_profile_check.path|lower == "c:\\users\\" + test_username - - not create_profile_actual_check.stat.exists - -- name: create profile - win_user_profile: - username: '{{ test_username }}' - state: present - register: create_profile - -- name: check if profile was created - win_stat: - path: C:\Users\{{ test_username }} - register: create_profile_actual - -- name: assert create profile - assert: - that: - - create_profile is changed - - create_profile.path|lower == "c:\\users\\" + test_username - - create_profile_actual.stat.exists - -- name: create profile (idempotent) - win_user_profile: - username: '{{ test_username }}' - state: present - register: create_profile_again - -- name: assert create profile (idempotent) - assert: - that: - - not create_profile_again is changed - - create_profile_again.path|lower == "c:\\users\\" + test_username - -- name: remove profile (check mode) - win_user_profile: - username: '{{ test_username }}' - state: absent - register: remove_profile_check - check_mode: True - -- name: check if profile was removed (check mode) - win_stat: - path: C:\Users\{{ test_username }} - register: remove_profile_actual_check - -- name: assert remove profile (check mode) - assert: - that: - - remove_profile_check is changed - - remove_profile_check.path|lower == "c:\\users\\" + test_username - - remove_profile_actual_check.stat.exists - -- name: remove profile - win_user_profile: - username: '{{ test_username }}' - state: absent - register: remove_profile - -- name: check if profile was removed - win_stat: - path: C:\Users\{{ test_username }} - register: remove_profile_actual - -- name: assert remove profile - assert: - that: - - remove_profile is changed - - remove_profile.path|lower == "c:\\users\\" + test_username - - not remove_profile_actual.stat.exists - -- name: remove profile (idempotent) - win_user_profile: - username: '{{ test_username }}' - state: absent - register: remove_profile_again - -- name: assert remove profile (idempotent) - assert: - that: - - not remove_profile_again is changed - - remove_profile_again.path == None - -- name: create profile with specific base path - win_user_profile: - username: '{{ test_username }}' - name: test_username_profile - state: present - register: create_profile_basename - -- name: check if profile with specific base path was created - win_stat: - path: C:\Users\test_username_profile - register: create_profile_basename_actual - -- name: assert create profile with specific base path - assert: - that: - - create_profile_basename is changed - - create_profile_basename.path|lower == "c:\\users\\test_username_profile" - - create_profile_basename_actual.stat.exists - -- name: remove profile with specific base path - win_user_profile: - username: '{{ test_username }}' - state: absent - register: remove_profile_basename - -- name: check if profile with specific base path was removed - win_stat: - path: C:\Users\test_username_profile - register: remove_profile_basename_actual - -- name: assert remove profile with specific base path - assert: - that: - - remove_profile_basename is changed - - remove_profile_basename.path|lower == "c:\\users\\test_username_profile" - - not remove_profile_basename_actual.stat.exists - -- name: create dummy profile folder - win_file: - path: C:\Users\{{ test_username }} - state: directory - -- block: - - name: create profile folder with conflict (check mode) - win_user_profile: - username: '{{ test_username }}' - state: present - register: create_profile_conflict_check - check_mode: True - - - name: get result of create profile folder with conflict (check mode) - win_stat: - path: C:\Users\{{ test_username }}.000 - register: create_profile_conflict_actual_check - - - name: assert create profile folder with conflict (check mode) - assert: - that: - - create_profile_conflict_check is changed - # The check mode path calc is dumb, doesn't check for conflicts - - create_profile_conflict_check.path|lower == "c:\\users\\" + test_username - - not create_profile_conflict_actual_check.stat.exists - - - name: create profile folder with conflict - win_user_profile: - username: '{{ test_username }}' - state: present - register: create_profile_conflict - - - name: get result of create profile with conflict - win_stat: - path: C:\Users\{{ test_username }}.000 - register: create_profile_conflict_actual - - - name: assert create profile folder with conflict - assert: - that: - - create_profile_conflict is changed - - create_profile_conflict.path|lower == "c:\\users\\" + test_username + ".000" - - create_profile_conflict_actual.stat.exists - - - name: remove profile with conflict - win_user_profile: - username: '{{ test_username }}' - state: absent - register: remove_profile_conflict - - - name: get result of profile folder after remove - win_stat: - path: C:\Users\{{ test_username }}.000 - register: remove_profile_conflict_actual - - - name: get result of dummy folder after remove - win_stat: - path: C:\Users\{{ test_username }} - register: remove_profile_conflict_dummy - - - name: assert remove profile with conflict - assert: - that: - - remove_profile_conflict is changed - - remove_profile_conflict.path|lower == "c:\\users\\" + test_username + ".000" - - not remove_profile_conflict_actual.stat.exists - - remove_profile_conflict_dummy.stat.exists - - always: - - name: remove dummy profile folder - win_file: - path: C:\Users\{{ test_username }} - state: absent - -- name: create profile for deleted user by sid test - win_user_profile: - username: '{{ test_username_info.sid }}' - state: present - -- name: delete user for deleted user with sid test - win_user: - name: '{{ test_username }}' - state: absent - -- name: remove profile for remove profile by sid test - win_user_profile: - username: '{{ test_username_info.sid }}' - state: absent - register: remove_profile_deleted_sid - -- name: check if profile was deleted for deleted user using a SID - win_stat: - path: C:\Users\{{ test_username }} - register: remove_profile_deleted_sid_actual - -- name: assert remove profile for deleted user using a SID - assert: - that: - - remove_profile_deleted_sid is changed - - remove_profile_deleted_sid.path|lower == "c:\\users\\" + test_username - - not remove_profile_deleted_sid_actual.stat.exists - -- name: recreate user for deleted user by name test - win_user: - name: '{{ test_username }}' - password: '{{ test_password }}' - state: present - register: test_orphan_user1 - -- name: create profile for deleted user by name test - win_user_profile: - username: '{{ test_username }}' - state: present - -- name: delete user for remove profile by name test - win_user: - name: '{{ test_username }}' - state: absent - -- name: remove profile for deleted user using a name - win_user_profile: - name: '{{ test_username }}' - state: absent - register: remove_profile_deleted_name - -- name: check if profile was deleted for deleted user using a name - win_stat: - path: C:\Users\{{ test_username }} - register: remove_profile_deleted_name_actual - -- name: assert remove profile for deleted user using a name - assert: - that: - - remove_profile_deleted_name is changed - - remove_profile_deleted_name.path|lower == "c:\\users\\" + test_username - - not remove_profile_deleted_name_actual.stat.exists - -- name: remove profile for deleted user using a name (idempotent) - win_user_profile: - name: '{{ test_username }}' - state: absent - register: remove_profile_deleted_name_again - -- name: assert remove profile for deleted user using a name (idempotent) - assert: - that: - - not remove_profile_deleted_name_again is changed - -- name: recreate user for remove multiple user test - win_user: - name: '{{ test_username }}' - password: '{{ test_password }}' - state: present - register: test_orphan_user1 - -- name: create new profile for remove multiple user test - win_user_profile: - username: '{{ test_username }}' - state: present - register: orphan_user1_profile - -- name: remove user 1 for remove multiple user test - win_user: - name: '{{ test_username }}' - state: absent - -# win_file has issues with paths exceeding MAX_PATH, need to use rmdir instead -- name: remove profile folder for user 1 - win_shell: rmdir /S /Q {{ orphan_user1_profile.path}} - args: - executable: cmd.exe - -- name: create user 2 for remove multiple user test - win_user: - name: '{{ test_username }}' - password: '{{ test_password }}' - state: present - register: test_orphan_user2 - -- name: create new profile for orphan user 2 - win_user_profile: - username: '{{ test_username }}' - state: present - register: orphan_user2_profile - -- name: remove orphan user 2 for remove multiple user test - win_user: - name: '{{ test_username }}' - state: present - -- name: fail to remove multiple profiles without flag - win_user_profile: - name: '{{ test_username }}' - state: absent - register: fail_remove_multiple - ignore_errors: True - -- name: check if profile was removed - win_stat: - path: C:\Users\{{ test_username }} - register: fail_remove_multiple_actual - -- name: assert that profile was not actually deleted - assert: - that: - - fail_remove_multiple.msg == "Found multiple profiles matching the path 'C:\\Users\\" + test_username + "', set 'remove_multiple=True' to remove all the profiles for this match" - - fail_remove_multiple_actual.stat.exists - -- name: remove multiple profiles - win_user_profile: - name: '{{ test_username }}' - state: absent - remove_multiple: True - register: remove_multiple - -- name: get result of remove multiple profiles - win_stat: - path: C:\Users\{{ test_username }} - register: remove_multiple_actual - -- name: check that orphan user 1 reg profile has been removed - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\{{ test_orphan_user1.sid }} - register: remove_orphan1_actual - -- name: check that orphan user 2 reg profile has been removed - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\{{ test_orphan_user2.sid }} - register: remove_orphan2_actual - -- name: assert remove multiple profiles - assert: - that: - - remove_multiple is changed - - remove_multiple.path|lower == "c:\\users\\" + test_username - - not remove_multiple_actual.stat.exists - - not remove_orphan1_actual.exists - - not remove_orphan2_actual.exists diff --git a/test/integration/targets/win_wait_for_process/aliases b/test/integration/targets/win_wait_for_process/aliases deleted file mode 100644 index 215e0b06920..00000000000 --- a/test/integration/targets/win_wait_for_process/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group4 diff --git a/test/integration/targets/win_wait_for_process/tasks/main.yml b/test/integration/targets/win_wait_for_process/tasks/main.yml deleted file mode 100644 index c775001b8d4..00000000000 --- a/test/integration/targets/win_wait_for_process/tasks/main.yml +++ /dev/null @@ -1,200 +0,0 @@ ---- -- name: Get powershell version - win_shell: $PSVersionTable.PSVersion.Major - register: powershell_version - -- name: Ensure Spooler service is started - win_service: - name: Spooler - state: started - -- name: Wait for non-existing process to not exist - win_wait_for_process: - process_name_exact: - - ansible_foobar - timeout: 30 - state: absent - register: absent_nonexisting_process - -- assert: - that: - - absent_nonexisting_process is success - - absent_nonexisting_process is not changed - - absent_nonexisting_process.elapsed > 0 - - absent_nonexisting_process.elapsed < 30 - - absent_nonexisting_process.matched_processes|length == 0 - -- name: Wait for non-existing process until timeout - win_wait_for_process: - process_name_exact: ansible_foobar - timeout: 30 - state: present - ignore_errors: yes - register: present_nonexisting_process - -- assert: - that: - - present_nonexisting_process is failed - - present_nonexisting_process is not changed - - present_nonexisting_process.elapsed > 30 - - present_nonexisting_process.msg == 'Timed out while waiting for process(es) to start' - - present_nonexisting_process.matched_processes|length == 0 - -- name: Wait for existing process to exist - win_wait_for_process: - process_name_exact: spoolsv - timeout: 30 - state: present - register: present_existing_process - -- assert: - that: - - present_existing_process is success - - present_existing_process is not changed - - present_existing_process.elapsed > 0 - - present_existing_process.elapsed < 30 - - present_existing_process.matched_processes|length > 0 - -- name: Wait for existing process until timeout - win_wait_for_process: - process_name_exact: - - spoolsv - timeout: 30 - state: absent - ignore_errors: yes - register: absent_existing_process - -- assert: - that: - - absent_existing_process is failed - - absent_existing_process is not changed - - absent_existing_process.elapsed > 30 - - absent_existing_process.matched_processes|length > 0 - - absent_existing_process.msg == 'Timeout while waiting for process(es) to stop' - -- name: Wait for existing process to exist (using owner) - win_wait_for_process: - process_name_exact: spoolsv - owner: SYSTEM - timeout: 30 - state: present - ignore_errors: yes - register: present_existing_owner_process - -- assert: - that: - - present_existing_owner_process is success - - present_existing_owner_process is not changed - - present_existing_owner_process.elapsed > 0 - - present_existing_owner_process.elapsed < 30 - - present_existing_owner_process.matched_processes|length > 0 - when: powershell_version.stdout_lines[0]|int >= 4 - -- assert: - that: - - present_existing_owner_process is failed - - present_existing_owner_process is not changed - - present_existing_owner_process.elapsed == 0 - - present_existing_owner_process.matched_processes|length == 0 - - present_existing_owner_process.msg == "This version of Powershell does not support filtering processes by 'owner'." - when: powershell_version.stdout_lines[0]|int < 4 - -- name: Wait for Spooler service to stop - win_wait_for_process: - process_name_exact: - - spoolsv - timeout: 60 - state: absent - async: 30 - poll: 0 - register: spoolsv_process - -- name: Stop the Spooler service - win_service: - name: Spooler - force_dependent_services: yes - state: stopped - -- name: Check on async task - async_status: - jid: '{{ spoolsv_process.ansible_job_id }}' - until: absent_spoolsv_process is finished - retries: 20 - register: absent_spoolsv_process - -- assert: - that: - - absent_spoolsv_process is success - - absent_spoolsv_process is not changed - - absent_spoolsv_process is finished - - absent_spoolsv_process.elapsed > 0 - - absent_spoolsv_process.elapsed < 30 - - absent_spoolsv_process.matched_processes|length == 1 - -- name: Wait for Spooler service to start - win_wait_for_process: - process_name_exact: spoolsv - timeout: 60 - state: present - async: 60 - poll: 0 - register: spoolsv_process - -- name: Start the spooler service - win_service: - name: Spooler - force_dependent_services: yes - state: started - -- name: Check on async task - async_status: - jid: '{{ spoolsv_process.ansible_job_id }}' - until: present_spoolsv_process is finished - retries: 10 - register: present_spoolsv_process - -- assert: - that: - - present_spoolsv_process is success - - present_spoolsv_process is not changed - - present_spoolsv_process is finished - - present_spoolsv_process.elapsed > 0 - - present_spoolsv_process.elapsed < 60 - - present_spoolsv_process.matched_processes|length == 1 - -- name: Start a new long-running process - win_shell: | - Start-Sleep -Seconds 15 - async: 40 - poll: 0 - register: sleep_pid - -- name: Wait for PID to start - win_wait_for_process: - pid: '{{ sleep_pid.ansible_async_watchdog_pid }}' - timeout: 20 - state: present - register: present_sleep_pid - -- assert: - that: - - present_sleep_pid is success - - present_sleep_pid is not changed - - present_sleep_pid.elapsed > 0 - - present_sleep_pid.elapsed < 15 - - present_sleep_pid.matched_processes|length == 1 - -- name: Wait for PID to stop - win_wait_for_process: - pid: '{{ sleep_pid.ansible_async_watchdog_pid }}' - timeout: 20 - state: absent - register: absent_sleep_pid - -- assert: - that: - - absent_sleep_pid is success - - absent_sleep_pid is not changed - - absent_sleep_pid.elapsed > 0 - - absent_sleep_pid.elapsed < 15 - - absent_sleep_pid.matched_processes|length == 1 diff --git a/test/integration/targets/win_wakeonlan/aliases b/test/integration/targets/win_wakeonlan/aliases deleted file mode 100644 index 3cf5b97e805..00000000000 --- a/test/integration/targets/win_wakeonlan/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_wakeonlan/tasks/main.yml b/test/integration/targets/win_wakeonlan/tasks/main.yml deleted file mode 100644 index 169362b0027..00000000000 --- a/test/integration/targets/win_wakeonlan/tasks/main.yml +++ /dev/null @@ -1,9 +0,0 @@ -- name: Send a magic Wake-on-LAN packet to 00:00:5E:00:53:66 - win_wakeonlan: - mac: 00:00:5E:00:53:66 - broadcast: 192.0.2.255 - -- name: Send a magic Wake-On-LAN packet on port 9 to 00-00-5E-00-53-66 - win_wakeonlan: - mac: 00-00-5E-00-53-66 - port: 9 diff --git a/test/integration/targets/win_xml/aliases b/test/integration/targets/win_xml/aliases deleted file mode 100644 index 4cd27b3cb2f..00000000000 --- a/test/integration/targets/win_xml/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group1 diff --git a/test/integration/targets/win_xml/files/books.xml b/test/integration/targets/win_xml/files/books.xml deleted file mode 100644 index e38ee15d4e9..00000000000 --- a/test/integration/targets/win_xml/files/books.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - A Great Book - Best Book Ever - Worst Book Ever - Another Book - Worst Book Ever Two - - diff --git a/test/integration/targets/win_xml/files/config.xml b/test/integration/targets/win_xml/files/config.xml deleted file mode 100644 index 68a6cdca470..00000000000 --- a/test/integration/targets/win_xml/files/config.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - bar - diff --git a/test/integration/targets/win_xml/files/log4j.xml b/test/integration/targets/win_xml/files/log4j.xml deleted file mode 100644 index 54b76cf7f2e..00000000000 --- a/test/integration/targets/win_xml/files/log4j.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/integration/targets/win_xml/files/plane.zip b/test/integration/targets/win_xml/files/plane.zip deleted file mode 100644 index 8157182aaccca28cef24eaef6bd62ffbcfc6da9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 792 zcmWIWW@Zs#U|`^2u+FUZy|?Xh_huk3f{}qigF%L&ASW>|RkySx&Co07fzj8AfWQeV3Csj`gyU!)9>h0*BM zRLIID^Eb22%2;Apy`uHkhwvL5_8a%6YX^ACPmDWo-ef7$PuZ&zSx+5ZHr*zBm5bq) z;$0<6C3M~IKHO&IY`W*K(7Do?!dd5x?#F&M*PLm6PVg(^+nYa=zp<$w_I{IjcaHU0 zpYRzg%~o$Izwxd;FyrO^y!@l@@0}J8KnawkA#*l^0_7GEt04!91vo?!i*i%*G86Mi z2olvkLtu~yxK{faK4e%IawH{|E85zB!zmYz(@6}jQTa)YylNSXdfj%mJT~3aG<)ff zlmGvpRr&w@P2~oE(KiPAk9-b`#N?ZlF+cp!J4vdQnPHFHOz!+gzvo0|pAJ#eNQ)4O zDoQ&Xkglk;(c_gzSSO=d)TUD*)4D77^m#?B(rvn;7!nwxl+L_4J!+YTUHGnGXZ~Fm zxL0uRW4DsL@8sZKCH>VceZg!^>#UUz&-}BT!@K)`fHxzP95b$zA^{8<2-wyLqKQv8 utdMkrmS)gxLyZE6ZNMbTu&q%PNWpC*5FxniVr2ulnF$C%QLMoP;sF3 - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -- name: copy a test .xml file - win_copy: - src: config.xml - dest: "{{ win_output_dir }}\\config.xml" - -- name: add an element that only has a text child node - win_xml: - path: "{{ win_output_dir }}\\config.xml" - fragment: '42' - xpath: '/config' - register: element_add_result - -- name: check element add result - assert: - that: - - element_add_result is changed - -- name: try to add the element that only has a text child node again - win_xml: - path: "{{ win_output_dir }}\\config.xml" - fragment: '42' - xpath: '/config' - register: element_add_result_second - -- name: check element add result - assert: - that: - - not element_add_result_second is changed - -- name: copy a test log4j.xml - win_copy: - src: log4j.xml - dest: "{{ win_output_dir }}\\log4j.xml" - -- name: change an attribute to fatal logging - win_xml: - path: "{{ win_output_dir }}\\log4j.xml" - xpath: '/log4j:configuration/logger[@name="org.apache.commons.digester"]/level' - type: attribute - attribute: 'value' - fragment: 'FATAL' - -- name: try to change the attribute again - win_xml: - path: "{{ win_output_dir }}\\log4j.xml" - xpath: '/log4j:configuration/logger[@name="org.apache.commons.digester"]/level' - type: attribute - attribute: 'value' - fragment: 'FATAL' - register: attribute_changed_result - -- name: check attribute change result - assert: - that: - - attribute_changed_result is not changed - -# This testing is for https://github.com/ansible/ansible/issues/48471 -# The issue was that an .xml with no encoding declaration, but a UTF8 BOM -# with some UTF-8 characters was being written out with garbage characters. -# The characters added by win_xml were not UTF-8 characters. - -- name: copy test files (https://github.com/ansible/ansible/issues/48471) - win_copy: - src: plane.zip - dest: "{{ win_output_dir }}\\plane.zip" - -- name: unarchive the test files - win_unzip: - src: "{{ win_output_dir }}\\plane.zip" - dest: "{{ win_output_dir }}\\" - -- name: change a text value in a file with UTF8 BOM and armenian characters in the description - win_xml: - path: "{{ win_output_dir }}\\plane-utf8-bom-armenian-characters.xml" - xpath: '/plane/year' - type: text - fragment: '1988' - -- name: register the sha1 of the new file - win_stat: - path: "{{ win_output_dir }}\\plane-utf8-bom-armenian-characters.xml" - get_checksum: yes - register: sha1_checksum - -- name: verify the checksum - assert: - that: - - sha1_checksum.stat.checksum == 'e3e18c3066e1bfce9a5cf87c81353fa174440944' - -- name: change a text value in a file with UTF8 BOM and armenian characters in the description - win_xml: - path: "{{ win_output_dir }}\\plane-utf8-bom-armenian-characters.xml" - xpath: '/plane/year' - type: text - fragment: '1989' - backup: yes - register: test_backup - -- name: check backup_file - win_stat: - path: '{{ test_backup.backup_file }}' - register: backup_file - -- name: Check backup_file - assert: - that: - - test_backup is changed - - backup_file.stat.exists == true - -- name: change a text value in a file with UTF-16 BE BOM and Chinese characters in the description - win_xml: - path: "{{ win_output_dir }}\\plane-utf16be-bom-chinese-characters.xml" - xpath: '/plane/year' - type: text - fragment: '1988' - -- name: register the sha1 of the new file - win_stat: - path: "{{ win_output_dir}}\\plane-utf16be-bom-chinese-characters.xml" - get_checksum: yes - register: sha1_checksum - -- name: verify the checksum - assert: - that: - - sha1_checksum.stat.checksum == 'de86f79b409383447cf4cf112b20af8ffffcfdbf' - -# features added ansible 2.8 -# count - -- name: count logger nodes in log4j.xml - win_xml: - path: "{{ win_output_dir }}\\log4j.xml" - xpath: //logger - count: yes - register: logger_node_count - -- name: verify node count - assert: - that: - - logger_node_count.count == 5 - -# multiple attribute change -- name: ensure //logger/level value attributes are set to debug - win_xml: - path: "{{ win_output_dir }}\\log4j.xml" - xpath: '//logger/level[@value="error"]' - type: attribute - attribute: value - fragment: debug - count: yes - register: logger_level_value_attrs - -- name: verify //logger/level value attributes - assert: - that: - - logger_level_value_attrs.count == 4 - - logger_level_value_attrs.changed == true - - logger_level_value_attrs.msg == 'attribute changed' - -- name: ensure //logger/level value attributes are set to debug (idempotency) - win_xml: - path: "{{ win_output_dir }}\\log4j.xml" - xpath: '//logger/level[@value="error"]' - type: attribute - attribute: value - fragment: debug - count: yes - register: logger_level_value_attrs_again - -- name: verify //logger/level value attributes again (idempotency) - assert: - that: - - logger_level_value_attrs_again.count == 0 - - logger_level_value_attrs_again.changed == false - - logger_level_value_attrs_again.msg == 'The supplied xpath did not match any nodes. If this is unexpected, check your xpath is valid for the xml file at supplied path.' - -# multiple text nodes -- name: ensure test books.xml is present - win_copy: - src: books.xml - dest: '{{ win_output_dir }}\books.xml' - -- name: demonstrate multi text replace by replacing all title text elements - win_xml: - path: '{{ win_output_dir }}\books.xml' - xpath: //works/title - type: text - fragment: _TITLE_TEXT_REMOVED_BY_WIN_XML_MODULE_ - count: yes - register: multi_text - -- name: verify multi text change - assert: - that: - - multi_text.changed == true - - multi_text.count == 5 - - multi_text.msg == 'text changed' - -- name: demonstrate multi text replace by replacing all title text elements again (idempotency) - win_xml: - path: '{{ win_output_dir }}\books.xml' - xpath: //works/title - type: text - fragment: _TITLE_TEXT_REMOVED_BY_WIN_XML_MODULE_ - count: yes - register: multi_text_again - -- name: verify multi text again change (idempotency) - assert: - that: - - multi_text_again.changed == false - - multi_text_again.count == 5 - - multi_text_again.msg == 'not changed' - -# multiple element - -#- name: ensure a fresh test books.xml is present -# win_copy: -# src: books.xml -# dest: '{{ win_output_dir }}\books.xml' - -- name: demonstrate multi element should append new information element from fragment - win_xml: - path: '{{ win_output_dir }}\books.xml' - xpath: //works/title - type: element - fragment: This element added by ansible - count: yes - register: multi_element - -- name: verify multi element - assert: - that: - - multi_element.changed == true - - multi_element.count == 5 - - multi_element.msg == 'element changed' - -- name: demonstrate multi element unchanged (idempotency) - win_xml: - path: '{{ win_output_dir }}\books.xml' - xpath: //works/title - type: element - fragment: This element added by ansible - count: yes - register: multi_element_again - -- name: verify multi element again (idempotency) - assert: - that: - - multi_element_again.changed == false - - multi_element_again.count == 5 - - multi_element_again.msg == 'not changed' - -# multiple attributes on differing parent nodes - -- name: ensure all attribute lang=nl - win_xml: - path: '{{ win_output_dir }}\books.xml' - xpath: //@lang - type: attribute - attribute: lang - fragment: nl - count: yes - register: multi_attr - -- name: verify multi attribute - assert: - that: - - multi_attr.changed == true - - multi_attr.count == 6 - - multi_attr.msg == 'attribute changed' - -- name: ensure all attribute lang=nl (idempotency) - win_xml: - path: '{{ win_output_dir }}\books.xml' - xpath: //@lang - type: attribute - attribute: lang - fragment: nl - count: yes - register: multi_attr_again - -- name: verify multi attribute (idempotency) - assert: - that: - - multi_attr_again.changed == false - - multi_attr_again.count == 6 - - multi_attr_again.msg == 'not changed' diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt index a290c597a19..37c3182fdfa 100644 --- a/test/sanity/ignore.txt +++ b/test/sanity/ignore.txt @@ -3967,19 +3967,9 @@ lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py lib/ansible/modules/windows/async_status.ps1 pslint:PSCustomUseLiteralPath lib/ansible/modules/windows/setup.ps1 pslint:PSCustomUseLiteralPath lib/ansible/modules/windows/win_acl_inheritance.ps1 pslint:PSAvoidTrailingWhitespace -lib/ansible/modules/windows/win_audit_rule.ps1 pslint:PSCustomUseLiteralPath lib/ansible/modules/windows/win_certificate_store.ps1 validate-modules:parameter-type-not-in-doc -lib/ansible/modules/windows/win_chocolatey.ps1 validate-modules:doc-elements-mismatch -lib/ansible/modules/windows/win_chocolatey_config.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_chocolatey_facts.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_chocolatey_source.ps1 pslint:PSCustomUseLiteralPath lib/ansible/modules/windows/win_copy.ps1 pslint:PSUseApprovedVerbs -lib/ansible/modules/windows/win_credential.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_credential.ps1 validate-modules:doc-elements-mismatch -lib/ansible/modules/windows/win_credential.ps1 validate-modules:parameter-type-not-in-doc -lib/ansible/modules/windows/win_defrag.ps1 validate-modules:parameter-list-no-elements lib/ansible/modules/windows/win_dns_client.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_dns_record.ps1 validate-modules:doc-elements-mismatch lib/ansible/modules/windows/win_domain.ps1 pslint:PSAvoidUsingEmptyCatchBlock # Keep lib/ansible/modules/windows/win_domain.ps1 pslint:PSUseApprovedVerbs lib/ansible/modules/windows/win_domain_controller.ps1 pslint:PSAvoidGlobalVars # New PR @@ -3988,65 +3978,18 @@ lib/ansible/modules/windows/win_domain_controller.ps1 pslint:PSUseApprovedVerbs lib/ansible/modules/windows/win_domain_membership.ps1 pslint:PSAvoidGlobalVars # New PR lib/ansible/modules/windows/win_domain_membership.ps1 pslint:PSCustomUseLiteralPath lib/ansible/modules/windows/win_domain_membership.ps1 pslint:PSUseApprovedVerbs -lib/ansible/modules/windows/win_dotnet_ngen.ps1 pslint:PSCustomUseLiteralPath lib/ansible/modules/windows/win_dsc.ps1 pslint:PSAvoidUsingEmptyCatchBlock # Keep lib/ansible/modules/windows/win_dsc.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_eventlog.ps1 pslint:PSCustomUseLiteralPath lib/ansible/modules/windows/win_feature.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_file_version.ps1 pslint:PSCustomUseLiteralPath lib/ansible/modules/windows/win_find.ps1 pslint:PSAvoidUsingEmptyCatchBlock # Keep lib/ansible/modules/windows/win_find.ps1 validate-modules:doc-elements-mismatch -lib/ansible/modules/windows/win_firewall_rule.ps1 pslint:PSUseApprovedVerbs -lib/ansible/modules/windows/win_hosts.ps1 validate-modules:doc-elements-mismatch -lib/ansible/modules/windows/win_hotfix.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_hotfix.ps1 pslint:PSUseApprovedVerbs -lib/ansible/modules/windows/win_http_proxy.ps1 validate-modules:parameter-list-no-elements -lib/ansible/modules/windows/win_http_proxy.ps1 validate-modules:parameter-type-not-in-doc -lib/ansible/modules/windows/win_iis_virtualdirectory.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_iis_webapplication.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_iis_webapppool.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_iis_webbinding.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_iis_webbinding.ps1 pslint:PSUseApprovedVerbs -lib/ansible/modules/windows/win_iis_website.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_inet_proxy.ps1 validate-modules:parameter-list-no-elements -lib/ansible/modules/windows/win_inet_proxy.ps1 validate-modules:parameter-type-not-in-doc -lib/ansible/modules/windows/win_lineinfile.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_mapped_drive.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_netbios.ps1 validate-modules:parameter-list-no-elements lib/ansible/modules/windows/win_optional_feature.ps1 validate-modules:parameter-list-no-elements -lib/ansible/modules/windows/win_pagefile.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_pagefile.ps1 pslint:PSUseDeclaredVarsMoreThanAssignments # New PR - bug test_path should be testPath -lib/ansible/modules/windows/win_pagefile.ps1 pslint:PSUseSupportsShouldProcess -lib/ansible/modules/windows/win_pester.ps1 validate-modules:doc-elements-mismatch -lib/ansible/modules/windows/win_product_facts.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_psexec.ps1 validate-modules:parameter-list-no-elements -lib/ansible/modules/windows/win_psexec.ps1 validate-modules:parameter-type-not-in-doc -lib/ansible/modules/windows/win_rabbitmq_plugin.ps1 pslint:PSAvoidUsingInvokeExpression -lib/ansible/modules/windows/win_rabbitmq_plugin.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_rds_cap.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_rds_rap.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_rds_settings.ps1 pslint:PSCustomUseLiteralPath lib/ansible/modules/windows/win_regedit.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_region.ps1 pslint:PSAvoidUsingEmptyCatchBlock # Keep -lib/ansible/modules/windows/win_region.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_regmerge.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_robocopy.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_say.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_security_policy.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_security_policy.ps1 pslint:PSUseApprovedVerbs lib/ansible/modules/windows/win_share.ps1 pslint:PSCustomUseLiteralPath lib/ansible/modules/windows/win_shell.ps1 pslint:PSUseApprovedVerbs -lib/ansible/modules/windows/win_shortcut.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_snmp.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_unzip.ps1 pslint:PSUseApprovedVerbs lib/ansible/modules/windows/win_updates.ps1 pslint:PSCustomUseLiteralPath lib/ansible/modules/windows/win_uri.ps1 pslint:PSAvoidUsingEmptyCatchBlock # Keep -lib/ansible/modules/windows/win_user_profile.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_user_profile.ps1 validate-modules:parameter-type-not-in-doc lib/ansible/modules/windows/win_wait_for.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_wait_for_process.ps1 validate-modules:parameter-list-no-elements -lib/ansible/modules/windows/win_webpicmd.ps1 pslint:PSAvoidUsingInvokeExpression -lib/ansible/modules/windows/win_xml.ps1 pslint:PSCustomUseLiteralPath lib/ansible/parsing/vault/__init__.py pylint:blacklisted-name lib/ansible/playbook/base.py pylint:blacklisted-name lib/ansible/playbook/collectionsearch.py required-and-default-attributes # https://github.com/ansible/ansible/issues/61460 @@ -4248,24 +4191,16 @@ test/integration/targets/wait_for/files/testserver.py future-import-boilerplate test/integration/targets/wait_for/files/testserver.py metaclass-boilerplate test/integration/targets/want_json_modules_posix/library/helloworld.py future-import-boilerplate test/integration/targets/want_json_modules_posix/library/helloworld.py metaclass-boilerplate -test/integration/targets/win_audit_rule/library/test_get_audit_rule.ps1 pslint:PSCustomUseLiteralPath -test/integration/targets/win_chocolatey/files/tools/chocolateyUninstall.ps1 pslint:PSCustomUseLiteralPath -test/integration/targets/win_chocolatey_source/library/choco_source.ps1 pslint:PSCustomUseLiteralPath test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.psm1 pslint!skip test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1 pslint!skip test/integration/targets/win_dsc/files/xTestDsc/1.0.0/xTestDsc.psd1 pslint!skip test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1 pslint!skip test/integration/targets/win_dsc/files/xTestDsc/1.0.1/xTestDsc.psd1 pslint!skip test/integration/targets/win_exec_wrapper/library/test_fail.ps1 pslint:PSCustomUseLiteralPath -test/integration/targets/win_iis_webbinding/library/test_get_webbindings.ps1 pslint:PSUseApprovedVerbs test/integration/targets/win_module_utils/library/legacy_only_new_way_win_line_ending.ps1 line-endings # Explicitly tests that we still work with Windows line endings test/integration/targets/win_module_utils/library/legacy_only_old_way_win_line_ending.ps1 line-endings # Explicitly tests that we still work with Windows line endings test/integration/targets/win_ping/library/win_ping_syntax_error.ps1 pslint!skip -test/integration/targets/win_psmodule/files/module/template.psd1 pslint!skip -test/integration/targets/win_psmodule/files/module/template.psm1 pslint!skip -test/integration/targets/win_psmodule/files/setup_modules.ps1 pslint:PSCustomUseLiteralPath test/integration/targets/win_reboot/templates/post_reboot.ps1 pslint:PSCustomUseLiteralPath -test/integration/targets/win_regmerge/templates/win_line_ending.j2 line-endings test/integration/targets/win_script/files/test_script.ps1 pslint:PSAvoidUsingWriteHost # Keep test/integration/targets/win_script/files/test_script_creates_file.ps1 pslint:PSAvoidUsingCmdletAliases test/integration/targets/win_script/files/test_script_removes_file.ps1 pslint:PSCustomUseLiteralPath diff --git a/test/units/plugins/lookup/test_laps_password.py b/test/units/plugins/lookup/test_laps_password.py deleted file mode 100644 index af0664e6a68..00000000000 --- a/test/units/plugins/lookup/test_laps_password.py +++ /dev/null @@ -1,519 +0,0 @@ -# -*- coding: utf-8 -*- -# (c) 2019, Jordan Borean -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import os -import platform -import pytest -import sys - -from units.compat.mock import MagicMock - -from ansible.errors import AnsibleLookupError -from ansible.plugins.loader import lookup_loader - - -class FakeLDAPError(Exception): - pass - - -class FakeLDAPAuthUnknownError(Exception): - pass - - -class FakeLdap(object): - SASL_AVAIL = 1 - TLS_AVAIL = 1 - - SCOPE_SUBTREE = 2 - - OPT_PROTOCOL_VERSION = 17 - OPT_REFERRALS = 8 - - OPT_X_TLS_NEVER = 0 - OPT_X_TLS_DEMAND = 2 - OPT_X_TLS_ALLOW = 3 - OPT_X_TLS_TRY = 4 - - OPT_X_TLS_CACERTFILE = 24578 - OPT_X_TLS_REQUIRE_CERT = 24582 - - LDAPError = FakeLDAPError - AUTH_UNKNOWN = FakeLDAPAuthUnknownError - - @staticmethod - def initialize(uri, bytes_mode=None, **kwargs): - return MagicMock() - - @staticmethod - def set_option(option, invalue): - pass - - -class FakeLdapUrl(object): - - def __init__(self, ldapUrl=None, urlscheme='ldap', hostport='', **kwargs): - url = ldapUrl if ldapUrl else "%s://%s" % (urlscheme, hostport) - self.urlscheme = url.split('://', 2)[0].lower() - self._url = url - - def initializeUrl(self): - return self._url - - -def fake_is_ldap_url(s): - s_lower = s.lower() - return s_lower.startswith("ldap://") or s_lower.startswith("ldaps://") or s_lower.startswith("ldapi://") - - -@pytest.fixture(autouse=True) -def laps_password(): - """Imports and the laps_password lookup with a mocks laps module for testing""" - - # Build the fake ldap and ldapurl Python modules - fake_ldap_obj = FakeLdap() - fake_ldap_url_obj = MagicMock() - fake_ldap_url_obj.isLDAPUrl.side_effect = fake_is_ldap_url - fake_ldap_url_obj.LDAPUrl.side_effect = FakeLdapUrl - - # Take a snapshot of sys.modules before we manipulate it - orig_modules = sys.modules.copy() - try: - sys.modules["ldap"] = fake_ldap_obj - sys.modules["ldapurl"] = fake_ldap_url_obj - - from ansible.plugins.lookup import laps_password - - # ensure the changes to these globals aren't persisted after each test - orig_has_ldap = laps_password.HAS_LDAP - orig_ldap_imp_err = laps_password.LDAP_IMP_ERR - - yield laps_password - - laps_password.HAS_LDAP = orig_has_ldap - laps_password.LDAP_IMP_ERR = orig_ldap_imp_err - finally: - # Restore sys.modules back to our pre-shenanigans - sys.modules = orig_modules - - -def test_missing_ldap(laps_password): - laps_password.HAS_LDAP = False - laps_password.LDAP_IMP_ERR = "no import for you!" - - with pytest.raises(AnsibleLookupError) as err: - lookup_loader.get('laps_password').run(["host"], domain="test") - - assert str(err.value).startswith( - "Failed to import the required Python library (python-ldap) on %s's Python %s. See " - "https://pypi.org/project/python-ldap/ for more info. Please " - % (platform.node(), sys.executable) - ) - assert str(err.value).endswith(". Import Error: no import for you!") - - -def test_invalid_cert_mapping(): - with pytest.raises(AnsibleLookupError) as err: - lookup_loader.get('laps_password').run(["host"], domain="test", validate_certs="incorrect") - - assert str(err.value) == "Invalid validate_certs value 'incorrect': valid values are 'allow', 'demand', " \ - "'never', 'try'" - - -def test_invalid_auth(): - with pytest.raises(AnsibleLookupError) as err: - lookup_loader.get('laps_password').run(["host"], domain="test", auth="fail") - - assert str(err.value) == "Invalid auth value 'fail': expecting either 'gssapi', or 'simple'" - - -def test_gssapi_without_sasl(monkeypatch, ): - monkeypatch.setattr("ldap.SASL_AVAIL", 0) - - with pytest.raises(AnsibleLookupError) as err: - lookup_loader.get('laps_password').run(["host"], domain="test") - - assert str(err.value) == "Cannot use auth=gssapi when SASL is not configured with the local LDAP install" - - -def test_simple_auth_without_credentials(): - with pytest.raises(AnsibleLookupError) as err: - lookup_loader.get('laps_password').run(["host"], domain="test", auth="simple") - - assert str(err.value) == "The username and password values are required when auth=simple" - - -def test_gssapi_auth_with_credentials(): - with pytest.raises(AnsibleLookupError) as err: - lookup_loader.get('laps_password').run(["host"], domain="test", auth="gssapi", username="u", password="p") - - assert str(err.value) == "Explicit credentials are not supported when auth='gssapi'. Call kinit outside of Ansible" - - -def test_not_encrypted_without_override(): - with pytest.raises(AnsibleLookupError) as err: - lookup_loader.get('laps_password').run(["host"], domain="dc01", auth="simple", username="test", password="test") - - assert str(err.value) == "Current configuration will result in plaintext traffic exposing credentials. Set " \ - "auth=gssapi, scheme=ldaps, start_tls=True, or allow_plaintext=True to continue" - - -def test_ldaps_without_tls(monkeypatch, ): - monkeypatch.setattr("ldap.TLS_AVAIL", 0) - - with pytest.raises(AnsibleLookupError) as err: - lookup_loader.get('laps_password').run(["host"], domain="dc01", scheme="ldaps") - - assert str(err.value) == "Cannot use TLS as the local LDAP installed has not been configured to support it" - - -def test_start_tls_without_tls(monkeypatch, ): - monkeypatch.setattr("ldap.TLS_AVAIL", 0) - - with pytest.raises(AnsibleLookupError) as err: - lookup_loader.get('laps_password').run(["host"], domain="dc01", start_tls=True) - - assert str(err.value) == "Cannot use TLS as the local LDAP installed has not been configured to support it" - - -def test_normal_run(monkeypatch, laps_password): - def get_laps_password(conn, cn, search_base): - return "CN=%s,%s" % (cn, search_base) - - mock_ldap = MagicMock() - mock_ldap.return_value.read_rootdse_s.return_value = {"defaultNamingContext": ["DC=domain,DC=com"]} - monkeypatch.setattr("ldap.initialize", mock_ldap) - - mock_get_laps_password = MagicMock(side_effect=get_laps_password) - monkeypatch.setattr(laps_password, "get_laps_password", mock_get_laps_password) - - actual = lookup_loader.get('laps_password').run(["host1", "host2"], domain="dc01") - assert actual == ["CN=host1,DC=domain,DC=com", "CN=host2,DC=domain,DC=com"] - - # Verify the call count to get_laps_password - assert mock_get_laps_password.call_count == 2 - - # Verify the initialize() method call - assert mock_ldap.call_count == 1 - assert mock_ldap.call_args[0] == ("ldap://dc01:389",) - assert mock_ldap.call_args[1] == {"bytes_mode": False} - - # Verify the number of calls made to the mocked LDAP object - assert mock_ldap.mock_calls[1][0] == "().set_option" - assert mock_ldap.mock_calls[1][1] == (FakeLdap.OPT_PROTOCOL_VERSION, 3) - - assert mock_ldap.mock_calls[2][0] == "().set_option" - assert mock_ldap.mock_calls[2][1] == (FakeLdap.OPT_REFERRALS, 0) - - assert mock_ldap.mock_calls[3][0] == '().sasl_gssapi_bind_s' - assert mock_ldap.mock_calls[3][1] == () - - assert mock_ldap.mock_calls[4][0] == "().read_rootdse_s" - assert mock_ldap.mock_calls[4][1] == () - - assert mock_ldap.mock_calls[5][0] == "().unbind_s" - assert mock_ldap.mock_calls[5][1] == () - - -def test_run_with_simple_auth_and_search_base(monkeypatch, laps_password): - def get_laps_password(conn, cn, search_base): - return "CN=%s,%s" % (cn, search_base) - - mock_ldap = MagicMock() - monkeypatch.setattr("ldap.initialize", mock_ldap) - - mock_get_laps_password = MagicMock(side_effect=get_laps_password) - monkeypatch.setattr(laps_password, "get_laps_password", mock_get_laps_password) - - actual = lookup_loader.get('laps_password').run(["host1", "host2"], domain="dc01", auth="simple", username="user", - password="pass", allow_plaintext=True, - search_base="OU=Workstations,DC=domain,DC=com") - assert actual == ["CN=host1,OU=Workstations,DC=domain,DC=com", "CN=host2,OU=Workstations,DC=domain,DC=com"] - - # Verify the call count to get_laps_password - assert mock_get_laps_password.call_count == 2 - - # Verify the initialize() method call - assert mock_ldap.call_count == 1 - assert mock_ldap.call_args[0] == ("ldap://dc01:389",) - assert mock_ldap.call_args[1] == {"bytes_mode": False} - - # Verify the number of calls made to the mocked LDAP object - assert mock_ldap.mock_calls[1][0] == "().set_option" - assert mock_ldap.mock_calls[1][1] == (FakeLdap.OPT_PROTOCOL_VERSION, 3) - - assert mock_ldap.mock_calls[2][0] == "().set_option" - assert mock_ldap.mock_calls[2][1] == (FakeLdap.OPT_REFERRALS, 0) - - assert mock_ldap.mock_calls[3][0] == '().bind_s' - assert mock_ldap.mock_calls[3][1] == (u"user", u"pass") - - assert mock_ldap.mock_calls[4][0] == "().unbind_s" - assert mock_ldap.mock_calls[4][1] == () - - -@pytest.mark.parametrize("kwargs, expected", [ - [{"domain": "dc01"}, "ldap://dc01:389"], - [{"domain": "dc02", "port": 1234}, "ldap://dc02:1234"], - [{"domain": "dc03", "scheme": "ldaps"}, "ldaps://dc03:636"], - # Verifies that an explicit URI ignores port and scheme - [{"domain": "ldap://dc04", "port": 1234, "scheme": "ldaps"}, "ldap://dc04"], -]) -def test_uri_options(monkeypatch, kwargs, expected): - mock_ldap = MagicMock() - monkeypatch.setattr("ldap.initialize", mock_ldap) - - lookup_loader.get('laps_password').run([], **kwargs) - - assert mock_ldap.call_count == 1 - assert mock_ldap.call_args[0] == (expected,) - assert mock_ldap.call_args[1] == {"bytes_mode": False} - - -@pytest.mark.parametrize("validate, expected", [ - ["never", FakeLdap.OPT_X_TLS_NEVER], - ["allow", FakeLdap.OPT_X_TLS_ALLOW], - ["try", FakeLdap.OPT_X_TLS_TRY], - ["demand", FakeLdap.OPT_X_TLS_DEMAND], -]) -def test_certificate_validation(monkeypatch, validate, expected): - mock_ldap_option = MagicMock() - monkeypatch.setattr(FakeLdap, "set_option", mock_ldap_option) - - mock_ldap = MagicMock() - monkeypatch.setattr("ldap.initialize", mock_ldap) - - lookup_loader.get('laps_password').run([], domain="dc01", start_tls=True, validate_certs=validate) - - assert mock_ldap_option.mock_calls[0][1] == (FakeLdap.OPT_X_TLS_REQUIRE_CERT, expected) - - assert mock_ldap.mock_calls[3][0] == "().start_tls_s" - assert mock_ldap.mock_calls[3][1] == () - - assert mock_ldap.mock_calls[4][0] == "().sasl_gssapi_bind_s" - assert mock_ldap.mock_calls[4][1] == () - - -def test_certificate_validate_with_custom_cacert(monkeypatch): - mock_ldap_option = MagicMock() - monkeypatch.setattr(FakeLdap, "set_option", mock_ldap_option) - - mock_ldap = MagicMock() - monkeypatch.setattr("ldap.initialize", mock_ldap) - monkeypatch.setattr(os.path, 'exists', lambda x: True) - - lookup_loader.get('laps_password').run([], domain="dc01", scheme="ldaps", cacert_file="cacert.pem") - - assert mock_ldap_option.mock_calls[0][1] == (FakeLdap.OPT_X_TLS_REQUIRE_CERT, FakeLdap.OPT_X_TLS_DEMAND) - assert mock_ldap_option.mock_calls[1][1] == (FakeLdap.OPT_X_TLS_CACERTFILE, u"cacert.pem") - - assert mock_ldap.mock_calls[3][0] == "().sasl_gssapi_bind_s" - assert mock_ldap.mock_calls[3][1] == () - - -def test_certificate_validate_with_custom_cacert_fail(monkeypatch): - def set_option(self, key, value): - if key == FakeLdap.OPT_X_TLS_CACERTFILE: - raise ValueError("set_option() failed") - - monkeypatch.setattr(FakeLdap, "set_option", set_option) - monkeypatch.setattr(os.path, 'exists', lambda x: True) - - with pytest.raises(AnsibleLookupError) as err: - lookup_loader.get('laps_password').run([], domain="dc01", scheme="ldaps", cacert_file="cacert.pem") - - assert str(err.value) == "Failed to set path to cacert file, this is a known issue with older OpenLDAP " \ - "libraries on the host. Update OpenLDAP and reinstall python-ldap to continue" - - -@pytest.mark.parametrize("path", [ - "cacert.pem", - "~/.certs/cacert.pem", - "~/.certs/$USER/cacert.pem", -]) -def test_certificate_invalid_path(monkeypatch, path): - monkeypatch.setattr(os.path, 'exists', lambda x: False) - expected_path = os.path.expanduser(os.path.expandvars(path)) - - with pytest.raises(AnsibleLookupError) as err: - lookup_loader.get('laps_password').run([], domain="dc01", scheme="ldaps", cacert_file=path) - - assert str(err.value) == "The cacert_file specified '%s' does not exist" % expected_path - - -def test_simple_auth_with_ldaps(monkeypatch): - mock_ldap_option = MagicMock() - monkeypatch.setattr(FakeLdap, "set_option", mock_ldap_option) - - mock_ldap = MagicMock() - monkeypatch.setattr("ldap.initialize", mock_ldap) - - lookup_loader.get('laps_password').run([], domain="dc01", scheme="ldaps", auth="simple", username="user", - password="pass") - - assert mock_ldap_option.mock_calls[0][1] == (FakeLdap.OPT_X_TLS_REQUIRE_CERT, FakeLdap.OPT_X_TLS_DEMAND) - - assert mock_ldap.mock_calls[3][0] == '().bind_s' - assert mock_ldap.mock_calls[3][1] == (u"user", u"pass") - - assert mock_ldap.mock_calls[4][0] == "().read_rootdse_s" - assert mock_ldap.mock_calls[4][1] == () - - -def test_simple_auth_with_start_tls(monkeypatch): - mock_ldap_option = MagicMock() - monkeypatch.setattr(FakeLdap, "set_option", mock_ldap_option) - - mock_ldap = MagicMock() - monkeypatch.setattr("ldap.initialize", mock_ldap) - - lookup_loader.get('laps_password').run([], domain="dc01", start_tls=True, auth="simple", username="user", - password="pass") - - assert mock_ldap_option.mock_calls[0][1] == (FakeLdap.OPT_X_TLS_REQUIRE_CERT, FakeLdap.OPT_X_TLS_DEMAND) - - assert mock_ldap.mock_calls[3][0] == "().start_tls_s" - assert mock_ldap.mock_calls[3][1] == () - - assert mock_ldap.mock_calls[4][0] == '().bind_s' - assert mock_ldap.mock_calls[4][1] == (u"user", u"pass") - - assert mock_ldap.mock_calls[5][0] == "().read_rootdse_s" - assert mock_ldap.mock_calls[5][1] == () - - -def test_start_tls_ldap_error(monkeypatch): - mock_ldap = MagicMock() - mock_ldap.return_value.start_tls_s.side_effect = FakeLDAPError("fake error") - monkeypatch.setattr("ldap.initialize", mock_ldap) - - with pytest.raises(AnsibleLookupError) as err: - lookup_loader.get('laps_password').run([], domain="dc01", start_tls=True) - - assert str(err.value) == "Failed to send StartTLS to LDAP host 'ldap://dc01:389': fake error" - - -def test_simple_bind_ldap_error(monkeypatch): - mock_ldap = MagicMock() - mock_ldap.return_value.bind_s.side_effect = FakeLDAPError("fake error") - monkeypatch.setattr("ldap.initialize", mock_ldap) - - with pytest.raises(AnsibleLookupError) as err: - lookup_loader.get('laps_password').run([], domain="dc01", auth="simple", username="user", password="pass", - allow_plaintext=True) - - assert str(err.value) == "Failed to simple bind against LDAP host 'ldap://dc01:389': fake error" - - -def test_sasl_bind_ldap_error(monkeypatch): - mock_ldap = MagicMock() - mock_ldap.return_value.sasl_gssapi_bind_s.side_effect = FakeLDAPError("fake error") - monkeypatch.setattr("ldap.initialize", mock_ldap) - - with pytest.raises(AnsibleLookupError) as err: - lookup_loader.get('laps_password').run([], domain="dc01") - - assert str(err.value) == "Failed to do a sasl bind against LDAP host 'ldap://dc01:389': fake error" - - -def test_sasl_bind_ldap_no_mechs_error(monkeypatch): - mock_ldap = MagicMock() - mock_ldap.return_value.sasl_gssapi_bind_s.side_effect = FakeLDAPAuthUnknownError("no mechs") - monkeypatch.setattr("ldap.initialize", mock_ldap) - - with pytest.raises(AnsibleLookupError) as err: - lookup_loader.get('laps_password').run([], domain="dc01") - - assert str(err.value) == "Failed to do a sasl bind against LDAP host 'ldap://dc01:389', the GSSAPI mech is " \ - "not installed: no mechs" - - -def test_get_password_valid(laps_password): - mock_conn = MagicMock() - mock_conn.search_s.return_value = [ - ("CN=server,DC=domain,DC=local", - {"ms-Mcs-AdmPwd": ["pass"], "distinguishedName": ["CN=server,DC=domain,DC=local"]}), - # Replicates the 3 extra entries AD returns that aren't server objects - (None, ["ldap://ForestDnsZones.domain.com/DC=ForestDnsZones,DC=domain,DC=com"]), - (None, ["ldap://DomainDnsZones.domain.com/DC=DomainDnsZones,DC=domain,DC=com"]), - (None, ["ldap://domain.com/CN=Configuration,DC=domain,DC=com"]), - ] - - actual = laps_password.get_laps_password(mock_conn, "server", "DC=domain,DC=local") - assert actual == "pass" - - assert len(mock_conn.method_calls) == 1 - assert mock_conn.method_calls[0][0] == "search_s" - assert mock_conn.method_calls[0][1] == ("DC=domain,DC=local", FakeLdap.SCOPE_SUBTREE, - "(&(objectClass=computer)(CN=server))") - assert mock_conn.method_calls[0][2] == {"attrlist": ["distinguishedName", "ms-Mcs-AdmPwd"]} - - -def test_get_password_laps_not_configured(laps_password): - mock_conn = MagicMock() - mock_conn.search_s.return_value = [ - ("CN=server,DC=domain,DC=local", {"distinguishedName": ["CN=server,DC=domain,DC=local"]}), - (None, ["ldap://ForestDnsZones.domain.com/DC=ForestDnsZones,DC=domain,DC=com"]), - (None, ["ldap://DomainDnsZones.domain.com/DC=DomainDnsZones,DC=domain,DC=com"]), - (None, ["ldap://domain.com/CN=Configuration,DC=domain,DC=com"]), - ] - - with pytest.raises(AnsibleLookupError) as err: - laps_password.get_laps_password(mock_conn, "server2", "DC=test,DC=local") - assert str(err.value) == \ - "The server 'CN=server,DC=domain,DC=local' did not have the LAPS attribute 'ms-Mcs-AdmPwd'" - - assert len(mock_conn.method_calls) == 1 - assert mock_conn.method_calls[0][0] == "search_s" - assert mock_conn.method_calls[0][1] == ("DC=test,DC=local", FakeLdap.SCOPE_SUBTREE, - "(&(objectClass=computer)(CN=server2))") - assert mock_conn.method_calls[0][2] == {"attrlist": ["distinguishedName", "ms-Mcs-AdmPwd"]} - - -def test_get_password_no_results(laps_password): - mock_conn = MagicMock() - mock_conn.search_s.return_value = [ - (None, ["ldap://ForestDnsZones.domain.com/DC=ForestDnsZones,DC=domain,DC=com"]), - (None, ["ldap://DomainDnsZones.domain.com/DC=DomainDnsZones,DC=domain,DC=com"]), - (None, ["ldap://domain.com/CN=Configuration,DC=domain,DC=com"]), - ] - - with pytest.raises(AnsibleLookupError) as err: - laps_password.get_laps_password(mock_conn, "server", "DC=domain,DC=local") - assert str(err.value) == "Failed to find the server 'server' in the base 'DC=domain,DC=local'" - - assert len(mock_conn.method_calls) == 1 - assert mock_conn.method_calls[0][0] == "search_s" - assert mock_conn.method_calls[0][1] == ("DC=domain,DC=local", FakeLdap.SCOPE_SUBTREE, - "(&(objectClass=computer)(CN=server))") - assert mock_conn.method_calls[0][2] == {"attrlist": ["distinguishedName", "ms-Mcs-AdmPwd"]} - - -def test_get_password_multiple_results(laps_password): - mock_conn = MagicMock() - mock_conn.search_s.return_value = [ - ("CN=server,OU=Workstations,DC=domain,DC=local", - {"ms-Mcs-AdmPwd": ["pass"], "distinguishedName": ["CN=server,OU=Workstations,DC=domain,DC=local"]}), - ("CN=server,OU=Servers,DC=domain,DC=local", - {"ms-Mcs-AdmPwd": ["pass"], "distinguishedName": ["CN=server,OU=Servers,DC=domain,DC=local"]}), - (None, ["ldap://ForestDnsZones.domain.com/DC=ForestDnsZones,DC=domain,DC=com"]), - (None, ["ldap://DomainDnsZones.domain.com/DC=DomainDnsZones,DC=domain,DC=com"]), - (None, ["ldap://domain.com/CN=Configuration,DC=domain,DC=com"]), - ] - - with pytest.raises(AnsibleLookupError) as err: - laps_password.get_laps_password(mock_conn, "server", "DC=domain,DC=local") - assert str(err.value) == \ - "Found too many results for the server 'server' in the base 'DC=domain,DC=local'. Specify a more explicit " \ - "search base for the server required. Found servers 'CN=server,OU=Workstations,DC=domain,DC=local', " \ - "'CN=server,OU=Servers,DC=domain,DC=local'" - - assert len(mock_conn.method_calls) == 1 - assert mock_conn.method_calls[0][0] == "search_s" - assert mock_conn.method_calls[0][1] == ("DC=domain,DC=local", FakeLdap.SCOPE_SUBTREE, - "(&(objectClass=computer)(CN=server))") - assert mock_conn.method_calls[0][2] == {"attrlist": ["distinguishedName", "ms-Mcs-AdmPwd"]}