summaryrefslogtreecommitdiffstats
path: root/deployment/playbooks/library/vmware_folder.py
diff options
context:
space:
mode:
Diffstat (limited to 'deployment/playbooks/library/vmware_folder.py')
-rw-r--r--deployment/playbooks/library/vmware_folder.py253
1 files changed, 253 insertions, 0 deletions
diff --git a/deployment/playbooks/library/vmware_folder.py b/deployment/playbooks/library/vmware_folder.py
new file mode 100644
index 00000000..399f1d04
--- /dev/null
+++ b/deployment/playbooks/library/vmware_folder.py
@@ -0,0 +1,253 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# (c) 2017, Davis Phillips davis.phillips@gmail.com
+#
+# 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 <http://www.gnu.org/licenses/>.
+
+ANSIBLE_METADATA = {'status': ['preview'],
+ 'supported_by': 'community',
+ 'version': '1.0'}
+
+DOCUMENTATION = '''
+---
+module: vmware_folder
+short_description: Add/remove folders to/from vCenter
+description:
+ - This module can be used to add/remove a folder to/from vCenter
+version_added: 2.3
+author: "Davis Phillips (@dav1x)"
+notes:
+ - Tested on vSphere 6.5
+requirements:
+ - "python >= 2.6"
+ - PyVmomi
+options:
+ datacenter:
+ description:
+ - Name of the datacenter to add the host
+ required: True
+ cluster:
+ description:
+ - Name of the cluster to add the host
+ required: True
+ folder:
+ description:
+ - Folder name to manage
+ required: True
+ hostname:
+ description:
+ - ESXi hostname to manage
+ required: True
+ username:
+ description:
+ - ESXi username
+ required: True
+ password:
+ description:
+ - ESXi password
+ required: True
+ state:
+ description:
+ - Add or remove the folder
+ default: 'present'
+ choices:
+ - 'present'
+ - 'absent'
+extends_documentation_fragment: vmware.documentation
+'''
+
+EXAMPLES = '''
+# Create a folder
+ - name: Add a folder to vCenter
+ vmware_folder:
+ hostname: vcsa_host
+ username: vcsa_user
+ password: vcsa_pass
+ datacenter: datacenter
+ cluster: cluster
+ folder: folder
+ state: present
+'''
+
+RETURN = """
+instance:
+ descripton: metadata about the new folder
+ returned: always
+ type: dict
+ sample: None
+"""
+
+try:
+ from pyVmomi import vim, vmodl
+ HAS_PYVMOMI = True
+except ImportError:
+ HAS_PYVMOMI = False
+
+from ansible.module_utils.vmware import get_all_objs, connect_to_api, vmware_argument_spec, find_datacenter_by_name, \
+ find_cluster_by_name_datacenter, wait_for_task
+from ansible.module_utils.basic import AnsibleModule
+
+class VMwareFolder(object):
+ def __init__(self, module):
+ self.module = module
+ self.datacenter = module.params['datacenter']
+ self.cluster = module.params['cluster']
+ self.folder = module.params['folder']
+ self.hostname = module.params['hostname']
+ self.username = module.params['username']
+ self.password = module.params['password']
+ self.state = module.params['state']
+ self.dc_obj = None
+ self.cluster_obj = None
+ self.host_obj = None
+ self.folder_obj = None
+ self.folder_name = None
+ self.folder_expanded = None
+ self.folder_full_path = []
+ self.content = connect_to_api(module)
+
+ def find_host_by_cluster_datacenter(self):
+ self.dc_obj = find_datacenter_by_name(self.content, self.datacenter)
+ self.cluster_obj = find_cluster_by_name_datacenter(self.dc_obj, self.cluster)
+
+ for host in self.cluster_obj.host:
+ if host.name == self.hostname:
+ return host, self.cluster
+
+ return None, self.cluster
+
+ def select_folder(self, host):
+ fold_obj = None
+ self.folder_expanded = self.folder.split("/")
+ last_e = self.folder_expanded.pop()
+ fold_obj = self.get_obj([vim.Folder],last_e)
+ if fold_obj:
+ return fold_obj
+ if fold_obj is None:
+ return fold_obj
+
+ def get_obj(self, vimtype, name, return_all = False):
+ obj = list()
+ container = self.content.viewManager.CreateContainerView(
+ self.content.rootFolder, vimtype, True)
+
+ for c in container.view:
+ if name in [c.name, c._GetMoId()]:
+ if return_all is False:
+ return c
+ break
+ else:
+ obj.append(c)
+
+ if len(obj) > 0:
+ return obj
+ else:
+ # for backwards-compat
+ return None
+
+ def process_state(self):
+ try:
+ folder_states = {
+ 'absent': {
+ 'present': self.state_remove_folder,
+ 'absent': self.state_exit_unchanged,
+ },
+ 'present': {
+ 'present': self.state_exit_unchanged,
+ 'absent': self.state_add_folder,
+ }
+ }
+
+ folder_states[self.state][self.check_folder_state()]()
+
+ except vmodl.RuntimeFault as runtime_fault:
+ self.module.fail_json(msg = runtime_fault.msg)
+ except vmodl.MethodFault as method_fault:
+ self.module.fail_json(msg = method_fault.msg)
+ except Exception as e:
+ self.module.fail_json(msg = str(e))
+
+ def state_exit_unchanged(self):
+ self.module.exit_json(changed = False)
+
+ def state_remove_folder(self):
+ changed = True
+ result = None
+ self.folder_expanded = self.folder.split("/")
+ f = self.folder_expanded.pop()
+ task = self.get_obj([vim.Folder],f).Destroy()
+
+ try:
+ success, result = wait_for_task(task)
+
+ except:
+ self.module.fail_json(msg = "Failed to remove folder '%s' '%s'" % (self.folder,folder))
+
+ self.module.exit_json(changed = changed, result = str(result))
+
+ def state_add_folder(self):
+ changed = True
+ result = None
+
+ self.dc_obj = find_datacenter_by_name(self.content, self.datacenter)
+ self.cluster_obj = find_cluster_by_name_datacenter(self.dc_obj, self.cluster)
+ self.folder_expanded = self.folder.split("/")
+ index = 0
+ for f in self.folder_expanded:
+ if not self.get_obj([vim.Folder],f):
+ if index == 0:
+ #First object gets created on the datacenter
+ task = self.dc_obj.vmFolder.CreateFolder(name=f)
+ else:
+ parent_f = self.get_obj([vim.Folder],self.folder_expanded[index - 1])
+ task = parent_f.CreateFolder(name=f)
+ index = index + 1
+
+ self.module.exit_json(changed = changed)
+
+ def check_folder_state(self):
+
+ self.host_obj, self.cluster_obj = self.find_host_by_cluster_datacenter()
+ self.folder_obj = self.select_folder(self.host_obj)
+
+ if self.folder_obj is None:
+ return 'absent'
+ else:
+ return 'present'
+
+
+def main():
+ argument_spec = vmware_argument_spec()
+ argument_spec.update(dict(datacenter = dict(required = True, type = 'str'),
+ cluster = dict(required = True, type = 'str'),
+ folder = dict(required=True, type='str'),
+ hostname = dict(required = True, type = 'str'),
+ username = dict(required = True, type = 'str'),
+ password = dict(required = True, type = 'str', no_log = True),
+ state = dict(default = 'present', choices = ['present', 'absent'], type = 'str')))
+
+ module = AnsibleModule(argument_spec = argument_spec, supports_check_mode = True)
+
+ if not HAS_PYVMOMI:
+ module.fail_json(msg = 'pyvmomi is required for this module')
+
+ vmware_folder = VMwareFolder(module)
+ vmware_folder.process_state()
+
+
+if __name__ == '__main__':
+ main()