1#!/usr/bin/python 2# -*- coding: utf-8 -*- 3 4# Copyright: (c) 2018, Abhijeet Kasurde <akasurde@redhat.com> 5# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6 7from __future__ import absolute_import, division, print_function 8__metaclass__ = type 9 10ANSIBLE_METADATA = { 11 'metadata_version': '1.1', 12 'status': ['preview'], 13 'supported_by': 'community' 14} 15 16DOCUMENTATION = r''' 17--- 18module: vmware_host_lockdown 19short_description: Manage administrator permission for the local administrative account for the ESXi host 20description: 21- This module can be used to manage administrator permission for the local administrative account for the host when ESXi hostname is given. 22- All parameters and VMware objects values are case sensitive. 23- This module is destructive as administrator permission are managed using APIs used, please read options carefully and proceed. 24- Please specify C(hostname) as vCenter IP or hostname only, as lockdown operations are not possible from standalone ESXi server. 25version_added: '2.5' 26author: 27- Abhijeet Kasurde (@Akasurde) 28notes: 29- Tested on vSphere 6.5 30requirements: 31- python >= 2.6 32- PyVmomi 33options: 34 cluster_name: 35 description: 36 - Name of cluster. 37 - All host systems from given cluster used to manage lockdown. 38 - Required parameter, if C(esxi_hostname) is not set. 39 type: str 40 esxi_hostname: 41 description: 42 - List of ESXi hostname to manage lockdown. 43 - Required parameter, if C(cluster_name) is not set. 44 - See examples for specifications. 45 type: list 46 state: 47 description: 48 - State of hosts system 49 - If set to C(present), all host systems will be set in lockdown mode. 50 - If host system is already in lockdown mode and set to C(present), no action will be taken. 51 - If set to C(absent), all host systems will be removed from lockdown mode. 52 - If host system is already out of lockdown mode and set to C(absent), no action will be taken. 53 default: present 54 choices: [ present, absent ] 55 version_added: 2.5 56 type: str 57extends_documentation_fragment: vmware.documentation 58''' 59 60EXAMPLES = r''' 61- name: Enter host system into lockdown mode 62 vmware_host_lockdown: 63 hostname: '{{ vcenter_hostname }}' 64 username: '{{ vcenter_username }}' 65 password: '{{ vcenter_password }}' 66 esxi_hostname: '{{ esxi_hostname }}' 67 state: present 68 delegate_to: localhost 69 70- name: Exit host systems from lockdown mode 71 vmware_host_lockdown: 72 hostname: '{{ vcenter_hostname }}' 73 username: '{{ vcenter_username }}' 74 password: '{{ vcenter_password }}' 75 esxi_hostname: '{{ esxi_hostname }}' 76 state: absent 77 delegate_to: localhost 78 79- name: Enter host systems into lockdown mode 80 vmware_host_lockdown: 81 hostname: '{{ vcenter_hostname }}' 82 username: '{{ vcenter_username }}' 83 password: '{{ vcenter_password }}' 84 esxi_hostname: 85 - '{{ esxi_hostname_1 }}' 86 - '{{ esxi_hostname_2 }}' 87 state: present 88 delegate_to: localhost 89 90- name: Exit host systems from lockdown mode 91 vmware_host_lockdown: 92 hostname: '{{ vcenter_hostname }}' 93 username: '{{ vcenter_username }}' 94 password: '{{ vcenter_password }}' 95 esxi_hostname: 96 - '{{ esxi_hostname_1 }}' 97 - '{{ esxi_hostname_2 }}' 98 state: absent 99 delegate_to: localhost 100 101- name: Enter all host system from cluster into lockdown mode 102 vmware_host_lockdown: 103 hostname: '{{ vcenter_hostname }}' 104 username: '{{ vcenter_username }}' 105 password: '{{ vcenter_password }}' 106 cluster_name: '{{ cluster_name }}' 107 state: present 108 delegate_to: localhost 109''' 110 111RETURN = r''' 112results: 113 description: metadata about state of Host system lock down 114 returned: always 115 type: dict 116 sample: { 117 "host_lockdown_state": { 118 "DC0_C0": { 119 "current_state": "present", 120 "previous_state": "absent", 121 "desired_state": "present", 122 }, 123 } 124 } 125''' 126 127try: 128 from pyvmomi import vim 129except ImportError: 130 pass 131 132from ansible.module_utils.basic import AnsibleModule 133from ansible.module_utils.vmware import vmware_argument_spec, PyVmomi 134from ansible.module_utils._text import to_native 135 136 137class VmwareLockdownManager(PyVmomi): 138 def __init__(self, module): 139 super(VmwareLockdownManager, self).__init__(module) 140 if not self.is_vcenter(): 141 self.module.fail_json(msg="Lockdown operations are performed from vCenter only. " 142 "hostname %s is an ESXi server. Please specify hostname " 143 "as vCenter server." % self.module.params['hostname']) 144 cluster_name = self.params.get('cluster_name', None) 145 esxi_host_name = self.params.get('esxi_hostname', None) 146 self.hosts = self.get_all_host_objs(cluster_name=cluster_name, esxi_host_name=esxi_host_name) 147 148 def ensure(self): 149 """ 150 Function to manage internal state management 151 """ 152 results = dict(changed=False, host_lockdown_state=dict()) 153 change_list = [] 154 desired_state = self.params.get('state') 155 for host in self.hosts: 156 results['host_lockdown_state'][host.name] = dict(current_state='', 157 desired_state=desired_state, 158 previous_state='' 159 ) 160 changed = False 161 try: 162 if host.config.adminDisabled: 163 results['host_lockdown_state'][host.name]['previous_state'] = 'present' 164 if desired_state == 'absent': 165 host.ExitLockdownMode() 166 results['host_lockdown_state'][host.name]['current_state'] = 'absent' 167 changed = True 168 else: 169 results['host_lockdown_state'][host.name]['current_state'] = 'present' 170 elif not host.config.adminDisabled: 171 results['host_lockdown_state'][host.name]['previous_state'] = 'absent' 172 if desired_state == 'present': 173 host.EnterLockdownMode() 174 results['host_lockdown_state'][host.name]['current_state'] = 'present' 175 changed = True 176 else: 177 results['host_lockdown_state'][host.name]['current_state'] = 'absent' 178 except vim.fault.HostConfigFault as host_config_fault: 179 self.module.fail_json(msg="Failed to manage lockdown mode for esxi" 180 " hostname %s : %s" % (host.name, to_native(host_config_fault.msg))) 181 except vim.fault.AdminDisabled as admin_disabled: 182 self.module.fail_json(msg="Failed to manage lockdown mode as administrator " 183 "permission has been disabled for " 184 "esxi hostname %s : %s" % (host.name, to_native(admin_disabled.msg))) 185 except Exception as generic_exception: 186 self.module.fail_json(msg="Failed to manage lockdown mode due to generic exception for esxi " 187 "hostname %s : %s" % (host.name, to_native(generic_exception))) 188 change_list.append(changed) 189 190 if any(change_list): 191 results['changed'] = True 192 193 self.module.exit_json(**results) 194 195 196def main(): 197 argument_spec = vmware_argument_spec() 198 argument_spec.update( 199 cluster_name=dict(type='str', required=False), 200 esxi_hostname=dict(type='list', required=False), 201 state=dict(str='str', default='present', choices=['present', 'absent'], required=False), 202 ) 203 204 module = AnsibleModule( 205 argument_spec=argument_spec, 206 required_one_of=[ 207 ['cluster_name', 'esxi_hostname'], 208 ] 209 ) 210 211 vmware_lockdown_mgr = VmwareLockdownManager(module) 212 vmware_lockdown_mgr.ensure() 213 214 215if __name__ == "__main__": 216 main() 217