Merge pull request #1014 from rjeffman/roles_ansible_lint

Fix ansible-test lint warnings in roles.
This commit is contained in:
Thomas Woerner
2023-01-16 18:20:49 +01:00
committed by GitHub
18 changed files with 209 additions and 200 deletions

View File

@@ -16,6 +16,11 @@ exclude_paths:
kinds:
- playbook: '**/tests/**/test_*.yml'
- playbook: '**/playbooks/**/*.yml'
- playbook: '**/tests/ca-less/install_*_without_ca.yml'
- playbook: '**/tests/ca-less/clean_up_certificates.yml'
- playbook: '**/tests/external-signed-ca-with-automatic-copy/install-server-with-external-ca-with-automatic-copy.yml'
- playbook: '**/tests/external-signed-ca-with-manual-copy/install-server-with-external-ca-with-manual-copy.yml'
- playbook: '**/tests/user/create_users_json.yml'
- tasks: '**/tasks_*.yml'
- tasks: '**/env_*.yml'

View File

@@ -6,15 +6,15 @@ galaxy_info:
description: A role to backup and restore an IPA server
company: Red Hat, Inc
license: GPLv3
min_ansible_version: 2.8
min_ansible_version: "2.8"
platforms:
- name: Fedora
versions:
- all
- name: EL
versions:
- 7
- 8
- "7"
- "8"
galaxy_tags:
- identity
- ipa

View File

@@ -5,15 +5,16 @@
ansible.builtin.shell: >
ipa-backup
{{ "--gpg" if ipabackup_gpg | bool else "" }}
{{ "--gpg-keyring="+ipabackup_gpg_keyring if ipabackup_gpg_keyring is defined else "" }}
{{ "--gpg-keyring=" + ipabackup_gpg_keyring if ipabackup_gpg_keyring is defined else "" }}
{{ "--data" if ipabackup_data | bool else "" }}
{{ "--logs" if ipabackup_logs | bool else "" }}
{{ "--online" if ipabackup_online | bool else "" }}
{{ "--disable-role-check" if ipabackup_disable_role_check | bool else "" }}
{{ "--log-file="+ipabackup_log_file if ipabackup_log_file is defined else "" }}
{{ "--log-file=" + ipabackup_log_file if ipabackup_log_file is defined else "" }}
register: result_ipabackup
- name: Handle backup
when: ipabackup_to_controller
block:
- name: Get ipabackup_item from stderr or stdout output
ansible.builtin.set_fact:
@@ -26,7 +27,8 @@
label: ""
- name: Fail on missing ipabackup_item
ansible.builtin.fail: msg="Failed to get ipabackup_item"
ansible.builtin.fail:
msg: "Failed to get ipabackup_item"
when: ipabackup_item is not defined
- name: Copy backup to controller
@@ -36,5 +38,3 @@
- name: Remove backup on server
ansible.builtin.include_tasks: "{{ role_path }}/tasks/remove_backup_from_server.yml"
when: not ipabackup_keep_on_server
when: ipabackup_to_controller

View File

@@ -1,6 +1,7 @@
---
- name: Fail on invalid ipabackup_item
ansible.builtin.fail: msg="ipabackup_item {{ ipabackup_item }} is not valid"
ansible.builtin.fail:
msg: "ipabackup_item {{ ipabackup_item }} is not valid"
when: ipabackup_item is not defined or
ipabackup_item | length < 1 or
(ipabackup_item.find("ipa-full-") == -1 and
@@ -8,8 +9,8 @@
- name: Set controller destination directory
ansible.builtin.set_fact:
ipabackup_controller_dir:
"{{ ipabackup_controller_path | default(lookup('env','PWD')) }}/{{
__derived_controller_dir:
"{{ ipabackup_controller_path | default(lookup('env', 'PWD')) }}/{{
ipabackup_name_prefix | default(ansible_facts['fqdn']) }}_{{
ipabackup_item }}/"
@@ -19,7 +20,8 @@
register: result_backup_stat
- name: Fail on missing backup directory
ansible.builtin.fail: msg="Unable to find backup {{ ipabackup_item }}"
ansible.builtin.fail:
msg: "Unable to find backup {{ ipabackup_item }}"
when: result_backup_stat.stat.isdir is not defined
- name: Get backup files to copy for "{{ ipabackup_item }}"
@@ -33,13 +35,13 @@
ansible.builtin.fetch:
flat: yes
src: "{{ ipabackup_dir }}/{{ ipabackup_item }}/{{ item }}"
dest: "{{ ipabackup_controller_dir }}"
dest: "{{ __derived_controller_dir }}"
with_items:
- "{{ result_find_backup_files.stdout_lines }}"
- name: Fix file modes for backup on controller
ansible.builtin.file:
dest: "{{ ipabackup_controller_dir }}"
dest: "{{ __derived_controller_dir }}"
mode: u=rwX,go=
recurse: yes
delegate_to: localhost

View File

@@ -1,6 +1,7 @@
---
- name: Fail on invalid ipabackup_name
ansible.builtin.fail: msg="ipabackup_name {{ ipabackup_name }} is not valid"
ansible.builtin.fail:
msg: "ipabackup_name {{ ipabackup_name }} is not valid"
when: ipabackup_name is not defined or
ipabackup_name | length < 1 or
(ipabackup_name.find("ipa-full-") == -1 and
@@ -8,35 +9,36 @@
- name: Set controller source directory
ansible.builtin.set_fact:
ipabackup_controller_dir:
"{{ ipabackup_controller_path | default(lookup('env','PWD')) }}"
__derived_controller_dir:
"{{ ipabackup_controller_path | default(lookup('env', 'PWD')) }}"
- name: Set ipabackup_item
ansible.builtin.set_fact:
ipabackup_item:
"{{ ipabackup_name | regex_search('.*_(ipa-.+)','\\1') | first }}"
__derived_item:
"{{ ipabackup_name | regex_search('.*_(ipa-.+)', '\\1') | first }}"
when: "'_ipa-' in ipabackup_name"
- name: Set ipabackup_item
ansible.builtin.set_fact:
ipabackup_item: "{{ ipabackup_name }}"
__derived_item: "{{ ipabackup_name }}"
when: "'_ipa-' not in ipabackup_name"
- name: Stat backup to copy
ansible.builtin.stat:
path: "{{ ipabackup_controller_dir }}/{{ ipabackup_name }}"
path: "{{ __derived_controller_dir }}/{{ ipabackup_name }}"
register: result_backup_stat
delegate_to: localhost
become: no
- name: Fail on missing backup to copy
ansible.builtin.fail: msg="Unable to find backup {{ ipabackup_name }}"
ansible.builtin.fail:
msg: "Unable to find backup {{ ipabackup_name }}"
when: result_backup_stat.stat.isdir is not defined
- name: Copy backup files to server for "{{ ipabackup_item }}"
- name: Copy backup files to server for "{{ __derived_item }}"
ansible.builtin.copy:
src: "{{ ipabackup_controller_dir }}/{{ ipabackup_name }}/"
dest: "{{ ipabackup_dir }}/{{ ipabackup_item }}"
src: "{{ __derived_controller_dir }}/{{ ipabackup_name }}/"
dest: "{{ ipabackup_dir }}/{{ __derived_item }}"
owner: root
group: root
mode: u=rw,go=r

View File

@@ -2,7 +2,8 @@
# tasks file for ipabackup
- name: Check for empty vars
ansible.builtin.fail: msg="Variable {{ item }} is empty"
ansible.builtin.fail:
msg: "Variable {{ item }} is empty"
when: "item in vars and not vars[item]"
with_items: "{{ ipabackup_empty_var_checks }}"
vars:
@@ -23,11 +24,13 @@
when: ipabackup_online | bool and not ipabackup_data | bool
- name: Fail if ipabackup_from_controller and ipabackup_to_controller are set
ansible.builtin.fail: msg="ipabackup_from_controller and ipabackup_to_controller are set"
ansible.builtin.fail:
msg: "ipabackup_from_controller and ipabackup_to_controller are set"
when: ipabackup_from_controller | bool and ipabackup_to_controller | bool
- name: Fail for given ipabackup_name if state is not copied, restored or absent
ansible.builtin.fail: msg="ipabackup_name is given and state is not copied, restored or absent"
ansible.builtin.fail:
msg: "ipabackup_name is given and state is not copied, restored or absent"
when: state is not defined or
(state != "copied" and state != "restored" and state != "absent") and
ipabackup_name is defined
@@ -40,12 +43,17 @@
when: state|default("present") == "present"
- name: Fail on missing ipabackup_name
ansible.builtin.fail: msg="ipabackup_name is not set"
ansible.builtin.fail:
msg: "ipabackup_name is not set"
when: (ipabackup_name is not defined or not ipabackup_name) and
state is defined and
(state == "copied" or state == "restored" or state == "absent")
- name: Get all backup names for copy to controller
when: state is defined and
((state == "copied" and ipabackup_to_controller) or
state == "absent") and
ipabackup_name is defined and ipabackup_name == "all"
block:
- name: Get list of all backups on IPA server
ansible.builtin.shell:
@@ -58,15 +66,12 @@
ansible.builtin.set_fact:
ipabackup_names: "{{ result_backup_find_backup_files.stdout_lines }}"
when: state is defined and
((state == "copied" and ipabackup_to_controller) or
state == "absent") and
ipabackup_name is defined and ipabackup_name == "all"
- name: Set ipabackup_names from ipabackup_name
when: ipabackup_names is not defined and ipabackup_name is defined
block:
- name: Fail on ipabackup_name all
ansible.builtin.fail: msg="ipabackup_name can not be all in this case"
ansible.builtin.fail:
msg: "ipabackup_name can not be all in this case"
when: ipabackup_name is defined and ipabackup_name == "all"
- name: Set ipabackup_names from ipabackup_name string
@@ -78,7 +83,6 @@
ansible.builtin.set_fact:
ipabackup_names: "{{ ipabackup_name }}"
when: ipabackup_name | type_debug == "list"
when: ipabackup_names is not defined and ipabackup_name is defined
- name: Set empty ipabackup_names if ipabackup_name is not defined
ansible.builtin.set_fact:
@@ -86,6 +90,8 @@
when: ipabackup_names is not defined and ipabackup_name is not defined
- name: Process "{{ ipabackup_names }}"
when: state is defined and
((state == "copied" and ipabackup_to_controller) or state == "absent")
block:
- name: Copy backup from IPA server
ansible.builtin.include_tasks: "{{ role_path }}/tasks/copy_backup_from_server.yml"
@@ -107,20 +113,22 @@
loop_var: main_item
when: state is defined and state == "absent"
when: state is defined and
((state == "copied" and ipabackup_to_controller) or state == "absent")
# Fail with more than one entry in ipabackup_names for copy to sever and
# restore.
- name: Fail to copy or restore more than one backup on the server
ansible.builtin.fail: msg="Only one backup can be copied to the server or restored"
ansible.builtin.fail:
msg: "Only one backup can be copied to the server or restored"
when: state is defined and (state == "copied" or state == "restored") and
ipabackup_from_controller | bool and ipabackup_names | length != 1
# Use only first item in ipabackup_names for copy to server and for restore.
- name: Process "{{ ipabackup_names[0] }}"
when: ipabackup_from_controller or
(state|default("present") == "copied" and not ipabackup_to_controller)
vars:
ipabackup_name: "{{ ipabackup_names[0] }}"
block:
- name: Copy backup to server
ansible.builtin.include_tasks: "{{ role_path }}/tasks/copy_backup_to_server.yml"
@@ -129,11 +137,6 @@
ansible.builtin.include_tasks: "{{ role_path }}/tasks/restore.yml"
when: state|default("present") == "restored"
vars:
ipabackup_name: "{{ ipabackup_names[0] }}"
when: ipabackup_from_controller or
(state|default("present") == "copied" and not ipabackup_to_controller)
- name: Restore IPA server
ansible.builtin.include_tasks: "{{ role_path }}/tasks/restore.yml"
vars:

View File

@@ -26,7 +26,8 @@
register: result_backup_stat
- name: Fail on missing backup directory
ansible.builtin.fail: msg="Unable to find backup {{ ipabackup_item }}"
ansible.builtin.fail:
msg: "Unable to find backup {{ ipabackup_item }}"
when: result_backup_stat.stat.isdir is not defined
- name: Stat header file in backup "{{ ipabackup_item }}"
@@ -35,7 +36,8 @@
register: result_backup_header_stat
- name: Fail on missing header file in backup
ansible.builtin.fail: msg="Unable to find backup {{ ipabackup_item }} header file"
ansible.builtin.fail:
msg: "Unable to find backup {{ ipabackup_item }} header file"
when: result_backup_header_stat.stat.isreg is not defined
- name: Get services from backup
@@ -53,6 +55,7 @@
### INSTALL PACKAGES
- name: Package installation
when: ipabackup_install_packages | bool
block:
- name: Ensure that IPA server packages are installed
ansible.builtin.package:
@@ -77,11 +80,10 @@
state: present
when: ipabackup_setup_firewalld | bool
when: ipabackup_install_packages | bool
### START FIREWALLD
- name: Firewall configuration
when: ipabackup_setup_firewalld | bool
block:
- name: Ensure that firewalld is running
ansible.builtin.systemd:
@@ -104,8 +106,6 @@
>/dev/null
when: ipabackup_firewalld_zone is defined
when: ipabackup_setup_firewalld | bool
### RESTORE
- name: Restore backup
@@ -114,13 +114,13 @@
ipa-restore
{{ ipabackup_item }}
--unattended
{{ "--password="+ipabackup_password if ipabackup_password is defined else "" }}
{{ "--password=" + ipabackup_password if ipabackup_password is defined else "" }}
{{ "--data" if ipabackup_data | bool else "" }}
{{ "--online" if ipabackup_online | bool else "" }}
{{ "--instance="+ipabackup_instance if ipabackup_instance is defined else "" }}
{{ "--backend="+ipabackup_backend if ipabackup_backend is defined else "" }}
{{ "--instance=" + ipabackup_instance if ipabackup_instance is defined else "" }}
{{ "--backend=" + ipabackup_backend if ipabackup_backend is defined else "" }}
{{ "--no-logs" if ipabackup_no_logs | bool else "" }}
{{ "--log-file="+ipabackup_log_file if ipabackup_log_file is defined else "" }}
{{ "--log-file=" + ipabackup_log_file if ipabackup_log_file is defined else "" }}
register: result_iparestore
ignore_errors: yes
@@ -136,7 +136,7 @@
ansible.builtin.command: >
firewall-cmd
--permanent
{{ "--zone="+ipabackup_firewalld_zone if ipabackup_firewalld_zone is defined else "" }}
{{ "--zone=" + ipabackup_firewalld_zone if ipabackup_firewalld_zone is defined else "" }}
--add-service=freeipa-ldap
--add-service=freeipa-ldaps
{{ "--add-service=freeipa-trust" if ipabackup_service_adtrust in ipabackup_services else "" }}
@@ -147,7 +147,7 @@
- name: Configure firewalld runtime
ansible.builtin.command: >
firewall-cmd
{{ "--zone="+ipabackup_firewalld_zone if ipabackup_firewalld_zone is defined else "" }}
{{ "--zone=" + ipabackup_firewalld_zone if ipabackup_firewalld_zone is defined else "" }}
--add-service=freeipa-ldap
--add-service=freeipa-ldaps
{{ "--add-service=freeipa-trust" if ipabackup_service_adtrust in ipabackup_services else "" }}

View File

@@ -6,15 +6,15 @@ galaxy_info:
description: A role to join a machine to an IPA domain
company: Red Hat, Inc
license: GPLv3
min_ansible_version: 2.8
min_ansible_version: "2.8"
platforms:
- name: Fedora
versions:
- all
- name: EL
versions:
- 7
- 8
- "7"
- "8"
galaxy_tags:
- identity
- ipa

View File

@@ -19,7 +19,8 @@
ipaclient_servers is not defined
- name: Install - Check that either password or keytab is set
ansible.builtin.fail: msg="ipaadmin_password and ipaadmin_keytab cannot be used together"
ansible.builtin.fail:
msg: "ipaadmin_password and ipaadmin_keytab cannot be used together"
when: ipaadmin_keytab is defined and ipaadmin_password is defined
- name: Install - Set default principal if no keytab is given
@@ -28,14 +29,18 @@
when: ipaadmin_principal is undefined and ipaclient_keytab is undefined
- name: Install - DNS resolver configuration
when: ipaclient_configure_dns_resolver | bool
and not ipaclient_on_master | bool
block:
- name: Install - Fail on missing ipaclient_domain and ipaserver_domain
ansible.builtin.fail: msg="ipaclient_domain or ipaserver_domain is required for ipaclient_configure_dns_resolver"
ansible.builtin.fail:
msg: "ipaclient_domain or ipaserver_domain is required for ipaclient_configure_dns_resolver"
when: ipaserver_domain is not defined and ipaclient_domain is not defined
- name: Install - Fail on missing ipaclient_servers
ansible.builtin.fail: msg="ipaclient_dns_servers is required for ipaclient_configure_dns_resolver"
ansible.builtin.fail:
msg: "ipaclient_dns_servers is required for ipaclient_configure_dns_resolver"
when: ipaclient_dns_servers is not defined
- name: Install - Configure DNS resolver
@@ -44,9 +49,6 @@
searchdomains: "{{ ipaserver_domain | default(ipaclient_domain) }}"
state: present
when: ipaclient_configure_dns_resolver | bool
and not ipaclient_on_master | bool
- name: Install - IPA client test
ipaclient_test:
### basic ###
@@ -73,6 +75,9 @@
register: result_ipaclient_test
- name: Install - Client deployment
when: not ansible_check_mode and
not (result_ipaclient_test.client_already_configured and
not ipaclient_allow_repair | bool and not ipaclient_force_join | bool)
block:
- name: Install - Cleanup leftover ccache
ansible.builtin.file:
@@ -127,10 +132,11 @@
# If a keytab is specified in the hostent, then the hostent will be disabled
# if ipaclient_use_otp is set.
- name: Install - Obtain OTP
when: ipaclient_use_otp | bool and ipaclient_otp is not defined
block:
- name: Install - Keytab or password is required for getting otp
ansible.builtin.fail:
msg: Keytab or password is required for getting otp
msg: "Keytab or password is required for getting otp"
when: ipaadmin_keytab is undefined and ipaadmin_password is undefined
- name: Install - Create temporary file for keytab
@@ -172,9 +178,6 @@
ipaadmin_orig_password: "{{ ipaadmin_password | default(omit) }}"
ipaadmin_password: "{{ result_ipaclient_get_otp.host.randompassword
if result_ipaclient_get_otp.host is defined }}"
when: ipaclient_use_otp | bool and ipaclient_otp is not defined
always:
- name: Install - Remove keytab temporary file
ansible.builtin.file:
@@ -191,21 +194,30 @@
when: ipaclient_otp is defined
- name: Install - Check keytab, principal and keytab
when: not ipaclient_on_master | bool
block:
# This block is executed only when
# not (not ipaclient_on_master | bool and
# not result_ipaclient_join.changed and
# not ipaclient_allow_repair | bool and
# (result_ipaclient_test_keytab.krb5_keytab_ok or
# (result_ipaclient_join.already_joined is defined and
# result_ipaclient_join.already_joined)))
- name: Install - Check if principal and keytab are set
ansible.builtin.fail: msg="Admin principal and client keytab cannot be used together"
ansible.builtin.fail:
msg: "Admin principal and client keytab cannot be used together"
when: ipaadmin_principal is defined and ipaclient_keytab is defined
- name: Install - Check if one of password or keytabs are set
ansible.builtin.fail: msg="At least one of password or keytabs must be specified"
ansible.builtin.fail:
msg: "At least one of password or keytabs must be specified"
when: not result_ipaclient_test_keytab.krb5_keytab_ok
and ipaadmin_password is undefined
and ipaadmin_keytab is undefined
and ipaclient_keytab is undefined
when: not ipaclient_on_master | bool
- name: Install - Purge {{ result_ipaclient_test.realm }} from host keytab
- name: "Install - From host keytab, purge {{ result_ipaclient_test.realm }}"
ansible.builtin.command: >
/usr/sbin/ipa-rmkeytab
-k /etc/krb5.keytab
@@ -249,16 +261,14 @@
ipaclient_force_join)
- name: Install - Allow repair checks
when: not ipaclient_on_master | bool and
not result_ipaclient_join.changed and
not ipaclient_allow_repair | bool and
(result_ipaclient_test_keytab.krb5_keytab_ok or
(result_ipaclient_join.already_joined is defined and
result_ipaclient_join.already_joined))
block:
# This block is executed only when
# not (not ipaclient_on_master | bool and
# not result_ipaclient_join.changed and
# not ipaclient_allow_repair | bool and
# (result_ipaclient_test_keytab.krb5_keytab_ok or
# (result_ipaclient_join.already_joined is defined and
# result_ipaclient_join.already_joined)))
- name: krb5 configuration not correct
- name: The krb5 configuration is not correct
ansible.builtin.fail:
msg: >
The krb5 configuration is not correct, please enable allow_repair
@@ -268,19 +278,19 @@
ansible.builtin.fail:
msg: "The IPA test failed, please enable allow_repair to fix this."
when: not result_ipaclient_test_keytab.ping_test_ok
- name: ca.crt file is missing
- name: Fail due to missing ca.crt file
ansible.builtin.fail:
msg: >
The ca.crt file is missing, please enable allow_repair to fix this.
when: not result_ipaclient_test_keytab.ca_crt_exists
when: not ipaclient_on_master | bool and
not result_ipaclient_join.changed and
not ipaclient_allow_repair | bool and
(result_ipaclient_test_keytab.krb5_keytab_ok or
(result_ipaclient_join.already_joined is defined and
result_ipaclient_join.already_joined))
- name: Install - Configuration
when: not (not ipaclient_on_master | bool and
not result_ipaclient_join.changed and
not ipaclient_allow_repair | bool
and (result_ipaclient_test_keytab.krb5_keytab_ok
or (result_ipaclient_join.already_joined is defined
and result_ipaclient_join.already_joined)))
block:
- name: Install - Configure IPA default.conf
ipaclient_ipa_conf:
@@ -402,18 +412,6 @@
domain: "{{ result_ipaclient_test.domain }}"
nisdomain: "{{ ipaclient_nisdomain | default(omit) }}"
when: not ipaclient_no_nisdomain | bool
when: not (not ipaclient_on_master | bool and
not result_ipaclient_join.changed and
not ipaclient_allow_repair | bool
and (result_ipaclient_test_keytab.krb5_keytab_ok
or (result_ipaclient_join.already_joined is defined
and result_ipaclient_join.already_joined)))
when: not ansible_check_mode and
not (result_ipaclient_test.client_already_configured and
not ipaclient_allow_repair | bool and not ipaclient_force_join | bool)
always:
- name: Install - Restore original admin password if overwritten by OTP
no_log: yes

View File

@@ -6,15 +6,15 @@ galaxy_info:
description: A role to setup an IPA domain replica
company: Red Hat, Inc
license: GPLv3
min_ansible_version: 2.8
min_ansible_version: "2.8"
platforms:
- name: Fedora
versions:
- all
- name: EL
versions:
- 7
- 8
- "7"
- "8"
galaxy_tags:
- identity
- ipa

View File

@@ -2,6 +2,7 @@
# tasks file for ipareplica
- name: Package installation
when: ipareplica_install_packages | bool
block:
- name: Install - Ensure IPA replica packages are installed
@@ -27,9 +28,8 @@
state: present
when: ipareplica_setup_firewalld | bool
when: ipareplica_install_packages | bool
- name: Firewall configuration
when: ipareplica_setup_firewalld | bool
block:
- name: Firewalld service - Ensure that firewalld is running
ansible.builtin.systemd:
@@ -52,8 +52,6 @@
>/dev/null
when: ipareplica_firewalld_zone is defined
when: ipareplica_setup_firewalld | bool
- name: Install - Set ipareplica_servers
ansible.builtin.set_fact:
ipareplica_servers: "{{ groups['ipaservers'] | list }}"
@@ -73,7 +71,7 @@
domain: "{{ ipareplica_domain | default(ipaserver_domain) |
default(omit) }}"
servers: "{{ ipareplica_servers | default(omit) }}"
realm: "{{ ipareplica_realm | default(ipaserver_realm) |default(omit) }}"
realm: "{{ ipareplica_realm | default(ipaserver_realm) | default(omit) }}"
hostname: "{{ ipareplica_hostname | default(ansible_facts['fqdn']) }}"
ca_cert_files: "{{ ipareplica_ca_cert_files | default([]) }}"
hidden_replica: "{{ ipareplica_hidden_replica }}"
@@ -104,6 +102,9 @@
register: result_ipareplica_test
- name: Install - Deploy replica
when: not ansible_check_mode and
not (result_ipareplica_test.client_already_configured is defined or
result_ipareplica_test.server_already_configured is defined)
block:
# This block is executed only when
# not ansible_check_mode and
@@ -226,7 +227,7 @@
- name: Install - Set dirman password
no_log: yes
ansible.builtin.set_fact:
ipareplica_dirman_password:
__derived_dirman_password:
"{{ result_ipareplica_master_password.password }}"
- name: Install - Setup certmonger
@@ -267,7 +268,7 @@
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
dirman_password: "{{ ipareplica_dirman_password }}"
dirman_password: "{{ __derived_dirman_password }}"
config_setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
config_master_host_name:
"{{ result_ipareplica_prepare.config_master_host_name }}"
@@ -305,13 +306,13 @@
ccache: "{{ result_ipareplica_prepare.ccache }}"
installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}"
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
_dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info if result_ipareplica_prepare._dirsrv_pkcs12_info != None else omit }}"
_dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info if result_ipareplica_prepare._dirsrv_pkcs12_info != None else omit }}"
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
dirman_password: "{{ ipareplica_dirman_password }}"
dirman_password: "{{ __derived_dirman_password }}"
config_setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
config_master_host_name:
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
@@ -355,7 +356,7 @@
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
dirman_password: "{{ ipareplica_dirman_password }}"
dirman_password: "{{ __derived_dirman_password }}"
setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
- name: Install - Setup KRB
@@ -370,9 +371,9 @@
config_master_host_name:
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
ccache: "{{ result_ipareplica_prepare.ccache }}"
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}"
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}"
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
dirman_password: "{{ ipareplica_dirman_password }}"
dirman_password: "{{ __derived_dirman_password }}"
# We need to point to the master in ipa default conf when certmonger
# asks for HTTP certificate in newer ipa versions. In these versions
@@ -413,7 +414,7 @@
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
dirman_password: "{{ ipareplica_dirman_password }}"
dirman_password: "{{ __derived_dirman_password }}"
setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
master:
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
@@ -437,7 +438,7 @@
_dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info if result_ipareplica_prepare._dirsrv_pkcs12_info != None else omit }}"
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}"
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
dirman_password: "{{ ipareplica_dirman_password }}"
dirman_password: "{{ __derived_dirman_password }}"
ds_ca_subject: "{{ result_ipareplica_setup_ds.ds_ca_subject }}"
- name: Install - Setup http
@@ -458,7 +459,7 @@
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
_http_pkcs12_info: "{{ result_ipareplica_prepare._http_pkcs12_info if result_ipareplica_prepare._http_pkcs12_info != None else omit }}"
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
dirman_password: "{{ ipareplica_dirman_password }}"
dirman_password: "{{ __derived_dirman_password }}"
# Need to point back to ourself after the cert for HTTP is obtained
- name: Install - Create original IPA conf again
@@ -497,7 +498,7 @@
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
dirman_password: "{{ ipareplica_dirman_password }}"
dirman_password: "{{ __derived_dirman_password }}"
setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
when: result_ipareplica_test.change_master_for_certmonger
@@ -516,7 +517,7 @@
ccache: "{{ result_ipareplica_prepare.ccache }}"
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
dirman_password: "{{ ipareplica_dirman_password }}"
dirman_password: "{{ __derived_dirman_password }}"
- name: Install - Setup custodia
ipareplica_setup_custodia:
@@ -537,7 +538,7 @@
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}"
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
dirman_password: "{{ ipareplica_dirman_password }}"
dirman_password: "{{ __derived_dirman_password }}"
- name: Install - Setup CA
ipareplica_setup_ca:
@@ -560,7 +561,7 @@
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}"
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
_random_serial_numbers: "{{ result_ipareplica_prepare._random_serial_numbers }}"
dirman_password: "{{ ipareplica_dirman_password }}"
dirman_password: "{{ __derived_dirman_password }}"
config_setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
config_master_host_name:
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
@@ -585,7 +586,7 @@
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}"
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
dirman_password: "{{ ipareplica_dirman_password }}"
dirman_password: "{{ __derived_dirman_password }}"
- name: Install - DS apply updates
ipareplica_ds_apply_updates:
@@ -605,7 +606,7 @@
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}"
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
dirman_password: "{{ ipareplica_dirman_password }}"
dirman_password: "{{ __derived_dirman_password }}"
ds_ca_subject: "{{ result_ipareplica_setup_ds.ds_ca_subject }}"
- name: Install - Setup kra
@@ -645,7 +646,7 @@
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
dirman_password: "{{ ipareplica_dirman_password }}"
dirman_password: "{{ __derived_dirman_password }}"
when: result_ipareplica_test.setup_kra
- name: Install - Restart KDC
@@ -663,7 +664,7 @@
ccache: "{{ result_ipareplica_prepare.ccache }}"
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
dirman_password: "{{ ipareplica_dirman_password }}"
dirman_password: "{{ __derived_dirman_password }}"
- name: Install - Custodia import dm password
ipareplica_custodia_import_dm_password:
@@ -684,7 +685,7 @@
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
_kra_host_name: "{{ result_ipareplica_prepare.config_kra_host_name }}"
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
dirman_password: "{{ ipareplica_dirman_password }}"
dirman_password: "{{ __derived_dirman_password }}"
config_setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
- name: Install - Promote SSSD
@@ -793,7 +794,3 @@
- "/etc/ipa/.tmp_pkcs12_dirsrv"
- "/etc/ipa/.tmp_pkcs12_http"
- "/etc/ipa/.tmp_pkcs12_pkinit"
when: not ansible_check_mode and
not (result_ipareplica_test.client_already_configured is defined or
result_ipareplica_test.server_already_configured is defined)

View File

@@ -6,15 +6,15 @@ galaxy_info:
description: A role to setup an iPA domain server
company: Red Hat, Inc
license: GPLv3
min_ansible_version: 2.8
min_ansible_version: "2.8"
platforms:
- name: Fedora
versions:
- all
- name: EL
versions:
- 7
- 8
- "7"
- "8"
galaxy_tags:
- identity
- ipa

View File

@@ -1,14 +1,18 @@
---
- name: Install - Initialize ipaserver_external_cert_files
ansible.builtin.set_fact:
ipaserver_external_cert_files: []
when: ipaserver_external_cert_files is undefined
- name: Install - Copy "{{ item }}" "{{ inventory_hostname }}':/root/'{{ item | basename }}"
ansible.builtin.copy:
src: "{{ item }}"
dest: "/root/{{ item | basename }}"
mode: preserve
force: yes
- name: Install - Extend ipaserver_external_cert_files with "/root/{{ item | basename }}"
ansible.builtin.set_fact:
ipaserver_external_cert_files: "{{ ipaserver_external_cert_files + [ '/root/' + (item | basename) ] }}"
- name: Copy external certificates
vars:
__item_basename: "{{ item | basename }}"
block:
- name: Install - Initialize ipaserver_external_cert_files
ansible.builtin.set_fact:
ipaserver_external_cert_files: []
when: ipaserver_external_cert_files is undefined
- name: Install - Copy "{{ item + " " + inventory_hostname + ':/root/' + __item_basename }}"
ansible.builtin.copy:
src: "{{ item }}"
dest: "/root/{{ __item_basename }}"
mode: preserve
force: yes
- name: Install - Extend ipaserver_external_cert_files with "/root/{{ __item_basename }}"
ansible.builtin.set_fact:
ipaserver_external_cert_files: "{{ ipaserver_external_cert_files + ['/root/' + (__item_basename)] }}"

View File

@@ -2,6 +2,7 @@
# tasks file for ipaserver
- name: Install - Package installation
when: ipaserver_install_packages | bool
block:
- name: Install - Ensure that IPA server packages are installed
ansible.builtin.package:
@@ -26,9 +27,9 @@
state: present
when: ipaserver_setup_firewalld | bool
when: ipaserver_install_packages | bool
- name: Install - Firewall configuration
when: ipaserver_setup_firewalld | bool
block:
- name: Firewalld service - Ensure that firewalld is running
ansible.builtin.systemd:
@@ -51,9 +52,7 @@
>/dev/null
when: ipaserver_firewalld_zone is defined
when: ipaserver_setup_firewalld | bool
- name: Include tasks "{{ role_path }}/tasks/copy_external_cert.yml"
- name: Copy external certs
ansible.builtin.include_tasks: "{{ role_path }}/tasks/copy_external_cert.yml"
with_items: "{{ ipaserver_external_cert_files_from_controller }}"
when: ipaserver_external_cert_files_from_controller is defined and
@@ -131,14 +130,13 @@
register: result_ipaserver_test
- name: Install - Deploy server
when: not ansible_check_mode and not
(not result_ipaserver_test.changed and
(result_ipaserver_test.client_already_configured is defined or
result_ipaserver_test.server_already_configured is defined))
block:
# This block is executed only when
# not ansible_check_mode and
# not (not result_ipaserver_test.changed and
# (result_ipaserver_test.client_already_configured is defined or
# result_ipaserver_test.server_already_configured is defined)
- name: Install - Obtain master password
when: ipaserver_master_password is undefined
block:
- name: Install - Master password creation
no_log: yes
@@ -150,10 +148,14 @@
- name: Install - Use new master password
no_log: yes
ansible.builtin.set_fact:
ipaserver_master_password:
__derived_master_password:
"{{ result_ipaserver_master_password.password }}"
when: ipaserver_master_password is undefined
- name: Use user defined master password, if provided
when: ipaserver_master_password is defined
no_log: yes
ansible.builtin.set_fact:
__derived_master_password: "{{ ipaserver_master_password }}"
- name: Install - Server preparation
ipaserver_prepare:
@@ -212,7 +214,7 @@
ipaserver_setup_ds:
dm_password: "{{ ipadm_password }}"
password: "{{ ipaadmin_password }}"
# master_password: "{{ ipaserver_master_password }}"
# master_password: "{{ __derived_master_password }}"
domain: "{{ result_ipaserver_test.domain }}"
realm: "{{ result_ipaserver_test.realm | default(omit) }}"
hostname: "{{ result_ipaserver_test.hostname }}"
@@ -241,7 +243,7 @@
ipaserver_setup_krb:
dm_password: "{{ ipadm_password }}"
password: "{{ ipaadmin_password }}"
master_password: "{{ ipaserver_master_password }}"
master_password: "{{ __derived_master_password }}"
domain: "{{ result_ipaserver_test.domain }}"
realm: "{{ result_ipaserver_test.realm }}"
hostname: "{{ result_ipaserver_test.hostname }}"
@@ -274,7 +276,7 @@
ipaserver_setup_ca:
dm_password: "{{ ipadm_password }}"
password: "{{ ipaadmin_password }}"
master_password: "{{ ipaserver_master_password }}"
master_password: "{{ __derived_master_password }}"
# ip_addresses: "{{ result_ipaserver_prepare.ip_addresses }}"
domain: "{{ result_ipaserver_test.domain }}"
realm: "{{ result_ipaserver_test.realm }}"
@@ -312,7 +314,7 @@
_http_ca_cert: "{{ result_ipaserver_test._http_ca_cert }}"
register: result_ipaserver_setup_ca
- name: Copy /root/ipa.csr to "{{ inventory_hostname }}-ipa.csr"
- name: Copy /root/ipa.csr to "{{ inventory_hostname + '-ipa.csr' }}"
ansible.builtin.fetch:
src: /root/ipa.csr
dest: "{{ inventory_hostname }}-ipa.csr"
@@ -321,6 +323,7 @@
ipaserver_copy_csr_to_controller | bool
- name: Install - Configure services
when: not result_ipaserver_setup_ca.csr_generated | bool
block:
- name: Install - Setup otpd
ipaserver_setup_otpd:
@@ -332,7 +335,7 @@
ipaserver_setup_http:
dm_password: "{{ ipadm_password }}"
password: "{{ ipaadmin_password }}"
master_password: "{{ ipaserver_master_password }}"
master_password: "{{ __derived_master_password }}"
domain: "{{ result_ipaserver_test.domain }}"
realm: "{{ result_ipaserver_test.realm }}"
hostname: "{{ result_ipaserver_test.hostname }}"
@@ -476,8 +479,6 @@
{{ "--add-service=ntp" if not ipaclient_no_ntp | bool else "" }}
when: ipaserver_setup_firewalld | bool
when: not result_ipaserver_setup_ca.csr_generated | bool
always:
- name: Cleanup temporary files
ansible.builtin.file:
@@ -487,8 +488,3 @@
- "/etc/ipa/.tmp_pkcs12_dirsrv"
- "/etc/ipa/.tmp_pkcs12_http"
- "/etc/ipa/.tmp_pkcs12_pkinit"
when: not ansible_check_mode and not
(not result_ipaserver_test.changed and
(result_ipaserver_test.client_already_configured is defined or
result_ipaserver_test.server_already_configured is defined))

View File

@@ -6,15 +6,15 @@ galaxy_info:
description: A role to setup IPA server(s) for Smart Card authentication
company: Red Hat, Inc
license: GPLv3
min_ansible_version: 2.8
min_ansible_version: "2.8"
platforms:
- name: Fedora
versions:
- all
- name: EL
versions:
- 7
- 8
- "7"
- "8"
galaxy_tags:
- identity
- ipa

View File

@@ -2,7 +2,8 @@
# tasks file for ipasmartcard_client role
- name: Uninstall smartcard client
ansible.builtin.fail: msg="Uninstalling smartcard for IPA is not supported"
ansible.builtin.fail:
msg: "Uninstalling smartcard for IPA is not supported"
when: state|default('present') == 'absent'
- name: Import variables specific to distribution
@@ -36,7 +37,8 @@
# Fail on empty "ipasmartcard_client_ca_certs"
- name: Fail on empty "ipasmartcard_client_ca_certs"
ansible.builtin.fail: msg="No CA certs given in 'ipasmartcard_client_ca_certs'"
ansible.builtin.fail:
msg: "No CA certs given in 'ipasmartcard_client_ca_certs'"
when: ipasmartcard_client_ca_certs is not defined or
ipasmartcard_client_ca_certs | length < 1
@@ -68,13 +70,13 @@
ipaadmin_principal: admin
when: ipaadmin_principal is undefined
- name: kinit using "{{ ipaadmin_principal }}" password
- name: Authenticate using kinit with password for "{{ ipaadmin_principal }}"
ansible.builtin.command: kinit "{{ ipaadmin_principal }}"
args:
stdin: "{{ ipaadmin_password }}"
when: ipaadmin_password is defined
- name: kinit using "{{ ipaadmin_principal }}" keytab
- name: Authenticate using kinit with keytab for "{{ ipaadmin_principal }}"
ansible.builtin.command: kinit -kt "{{ ipaadmin_keytab }}" "{{ ipaadmin_principal }}"
when: ipaadmin_keytab is defined
@@ -101,6 +103,7 @@
# Ensure /etc/sssd/pki exists
- name: Prepare for authselect
when: ipasmartcard_client_vars.USE_AUTHSELECT
block:
- name: Ensure /etc/sssd/pki exists
ansible.builtin.file:
@@ -113,8 +116,6 @@
path: /etc/sssd/pki/sssd_auth_ca_db.pem
state: absent
when: ipasmartcard_client_vars.USE_AUTHSELECT
# Upload smartcard CA certificates to systemwide db
- name: Upload smartcard CA certificates to systemwide db
@@ -171,5 +172,5 @@
### ALWAYS ###
always:
- name: kdestroy
- name: Destroy Kerberos tickets
ansible.builtin.command: kdestroy -A

View File

@@ -6,15 +6,15 @@ galaxy_info:
description: A role to setup IPA server(s) for Smart Card authentication
company: Red Hat, Inc
license: GPLv3
min_ansible_version: 2.8
min_ansible_version: "2.8"
platforms:
- name: Fedora
versions:
- all
- name: EL
versions:
- 7
- 8
- "7"
- "8"
galaxy_tags:
- identity
- ipa

View File

@@ -2,7 +2,8 @@
# tasks file for ipasmartcard_server role
- name: Uninstall smartcard server
ansible.builtin.fail: msg="Uninstalling smartcard for IPA is not supported"
ansible.builtin.fail:
msg: "Uninstalling smartcard for IPA is not supported"
when: state|default('present') == 'absent'
- name: Import variables specific to distribution
@@ -27,7 +28,8 @@
# Fail on empty "ipasmartcard_server_ca_certs"
- name: Fail on empty "ipasmartcard_server_ca_certs"
ansible.builtin.fail: msg="No CA certs given in 'ipasmartcard_server_ca_certs'"
ansible.builtin.fail:
msg: "No CA certs given in 'ipasmartcard_server_ca_certs'"
when: ipasmartcard_server_ca_certs is not defined or
ipasmartcard_server_ca_certs | length < 1
@@ -40,7 +42,7 @@
# INSTALL bind-utils
- name: Ensure {{ ipasmartcard_server_bindutils_packages }} are installed
- name: Ensure bind utilities packages are installed
ansible.builtin.package:
name: "{{ ipasmartcard_server_bindutils_packages }}"
state: present
@@ -53,13 +55,13 @@
ipaadmin_principal: admin
when: ipaadmin_principal is undefined
- name: kinit using "{{ ipaadmin_principal }}" password
- name: Athenticate with kinit and password for "{{ ipaadmin_principal }}"
ansible.builtin.command: kinit "{{ ipaadmin_principal }}"
args:
stdin: "{{ ipaadmin_password }}"
when: ipaadmin_password is defined
- name: kinit using "{{ ipaadmin_principal }}" keytab
- name: Authenticate with kinit and keytab for "{{ ipaadmin_principal }}"
ansible.builtin.command: kinit -kt "{{ ipaadmin_keytab }}" "{{ ipaadmin_principal }}"
when: ipaadmin_keytab is defined
@@ -70,12 +72,13 @@
register: result_ipa_server_show
- name: Fail if not an IPA server
ansible.builtin.fail: msg="Not an IPA server"
ansible.builtin.fail:
msg: "Not an IPA server"
when: result_ipa_server_show.failed
- name: Get Domain from server-find server name
ansible.builtin.set_fact:
ipaserver_domain: "{{ (result_ipa_server_show.stdout | regex_search('cn: (.+)', '\\1'))[0].split('.')[1:] | join ('.') }}"
ipaserver_domain: "{{ (result_ipa_server_show.stdout | regex_search('cn: (.+)', '\\1'))[0].split('.')[1:] | join('.') }}"
when: ipaserver_domain is not defined
- name: Get ipa-ca records
@@ -83,7 +86,8 @@
register: result_get_ipaca_records
- name: Fail if ipa-ca records are not resolvable
ansible.builtin.fail: msg="ipa-ca records are not resolvable"
ansible.builtin.fail:
msg: "ipa-ca records are not resolvable"
when: result_get_ipaca_records.failed or
result_get_ipaca_records.stdout | length == 0
@@ -164,10 +168,10 @@
# HTTPD IFP
- name: Allow HTTPD ifp
when: ipasmartcard_server_vars.allow_httpd_ifp
block:
# Allow Apache to access SSSD IFP
- name: Allow Apache to access SSSD IFP
ansible.builtin.command: "{{ ipasmartcard_server_vars.python_interpreter }}"
args:
@@ -188,11 +192,10 @@
name: sssd
state: restarted
when: ipasmartcard_server_vars.allow_httpd_ifp
# Ensure /etc/sssd/pki exists
- name: Prepare for authselect
when: ipasmartcard_server_vars.USE_AUTHSELECT
block:
- name: Ensure /etc/sssd/pki exists
ansible.builtin.file:
@@ -205,8 +208,6 @@
path: /etc/sssd/pki/sssd_auth_ca_db.pem
state: absent
when: ipasmartcard_server_vars.USE_AUTHSELECT
# Upload smartcard CA certificates to systemwide db
- name: Upload smartcard CA certificates to systemwide db
@@ -246,5 +247,5 @@
### ALWAYS ###
always:
- name: kdestroy
- name: Destroy Kereberos tickets
ansible.builtin.command: kdestroy -A