community.general/lib/ansible/modules/cloud/vmware/vmware_host_ntp.py
Dag Wieers e2cac8cc93 Fix all VMware examples to use delegate_to (#43426)
Some users have problems using the VMware modules because they use the
vCenter as target, and Ansible uses SSH to connect to the targets.

Eventually we need to update the VMware guide to explain how the modules
work, but the first fix is to update the examples.

(We should backport to v2.6 and v2.5 too)
2018-08-01 09:10:57 +05:30

205 lines
7.2 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2018, Abhijeet Kasurde <akasurde@redhat.com>
# 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: vmware_host_ntp
short_description: Manage NTP configurations about an ESXi host
description:
- This module can be used to manage NTP configuration information about an ESXi host.
- User can specify an ESXi hostname or Cluster name. In case of cluster name, all ESXi hosts are updated.
version_added: '2.5'
author:
- Abhijeet Kasurde (@Akasurde)
notes:
- Tested on vSphere 6.5
requirements:
- python >= 2.6
- PyVmomi
options:
cluster_name:
description:
- Name of the cluster.
- NTP settings are applied to every ESXi host system in the given cluster.
- If C(esxi_hostname) is not given, this parameter is required.
esxi_hostname:
description:
- ESXi hostname.
- NTP settings are applied to this ESXi host system.
- If C(cluster_name) is not given, this parameter is required.
ntp_servers:
description:
- "IP or FQDN of NTP server/s."
- This accepts a list of NTP servers. For multiple servers, please look at the examples.
required: True
state:
description:
- "present: Add NTP server/s, if it specified server/s are absent else do nothing."
- "absent: Remove NTP server/s, if specified server/s are present else do nothing."
default: present
choices: [ present, absent ]
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = r'''
- name: Set NTP setting for all ESXi Host in given Cluster
vmware_host_ntp:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_username }}'
password: '{{ vcenter_password }}'
cluster_name: cluster_name
state: present
ntp_servers:
- 0.pool.ntp.org
- 1.pool.ntp.org
delegate_to: localhost
- name: Set NTP setting for an ESXi Host
vmware_host_ntp:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_username }}'
password: '{{ vcenter_password }}'
esxi_hostname: '{{ esxi_hostname }}'
state: present
ntp_servers:
- 0.pool.ntp.org
- 1.pool.ntp.org
delegate_to: localhost
- name: Remove NTP setting for an ESXi Host
vmware_host_ntp:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_username }}'
password: '{{ vcenter_password }}'
esxi_hostname: '{{ esxi_hostname }}'
state: absent
ntp_servers:
- bad.server.ntp.org
delegate_to: localhost
'''
RETURN = r'''#
'''
try:
from pyVmomi import vim, vmodl
except ImportError:
pass
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.vmware import vmware_argument_spec, PyVmomi
from ansible.module_utils._text import to_native
class VmwareNtpConfigManager(PyVmomi):
def __init__(self, module):
super(VmwareNtpConfigManager, self).__init__(module)
cluster_name = self.params.get('cluster_name', None)
esxi_host_name = self.params.get('esxi_hostname', None)
self.ntp_servers = self.params.get('ntp_servers', list())
self.hosts = self.get_all_host_objs(cluster_name=cluster_name, esxi_host_name=esxi_host_name)
self.results = {}
self.desired_state = module.params['state']
def update_ntp_servers(self, host, ntp_servers, operation='add'):
changed = False
host_date_time_manager = host.configManager.dateTimeSystem
if host_date_time_manager:
available_ntp_servers = host_date_time_manager.dateTimeInfo.ntpConfig.server
if operation == 'add':
available_ntp_servers = available_ntp_servers + ntp_servers
elif operation == 'delete':
for server in ntp_servers:
if server in available_ntp_servers:
available_ntp_servers.remove(server)
ntp_config_spec = vim.host.NtpConfig()
ntp_config_spec.server = available_ntp_servers
date_config_spec = vim.host.DateTimeConfig()
date_config_spec.ntpConfig = ntp_config_spec
try:
host_date_time_manager.UpdateDateTimeConfig(date_config_spec)
self.results[host.name]['after_change_ntp_servers'] = host_date_time_manager.dateTimeInfo.ntpConfig.server
changed = True
except vim.fault.HostConfigFault as e:
self.results[host.name]['error'] = to_native(e.msg)
except Exception as e:
self.results[host.name]['error'] = to_native(e)
return changed
def check_host_state(self):
change_list = []
changed = False
for host in self.hosts:
ntp_servers_to_change = self.check_ntp_servers(host=host)
self.results[host.name].update(dict(
ntp_servers_to_change=ntp_servers_to_change,
desired_state=self.desired_state,
)
)
if not ntp_servers_to_change:
change_list.append(False)
self.results[host.name]['current_state'] = self.desired_state
elif ntp_servers_to_change:
if self.desired_state == 'present':
changed = self.update_ntp_servers(host=host, ntp_servers=ntp_servers_to_change)
change_list.append(changed)
elif self.desired_state == 'absent':
changed = self.update_ntp_servers(host=host, ntp_servers=ntp_servers_to_change, operation='delete')
change_list.append(changed)
self.results[host.name]['current_state'] = self.desired_state
if any(change_list):
changed = True
self.module.exit_json(changed=changed, results=self.results)
def check_ntp_servers(self, host):
update_ntp_list = []
host_datetime_system = host.configManager.dateTimeSystem
if host_datetime_system:
ntp_servers = host_datetime_system.dateTimeInfo.ntpConfig.server
self.results[host.name] = dict(available_ntp_servers=ntp_servers)
for ntp_server in self.ntp_servers:
if self.desired_state == 'present' and ntp_server not in ntp_servers:
update_ntp_list.append(ntp_server)
if self.desired_state == 'absent' and ntp_server in ntp_servers:
update_ntp_list.append(ntp_server)
return update_ntp_list
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(
cluster_name=dict(type='str', required=False),
esxi_hostname=dict(type='str', required=False),
ntp_servers=dict(type='list', required=True),
state=dict(type='str', default='present', choices=['absent', 'present']),
)
module = AnsibleModule(
argument_spec=argument_spec,
required_one_of=[
['cluster_name', 'esxi_hostname'],
]
)
vmware_host_ntp_config = VmwareNtpConfigManager(module)
vmware_host_ntp_config.check_host_state()
if __name__ == "__main__":
main()