From 25fcd9c5aa4c360eff19ef08fc4e2bdff6147ffd Mon Sep 17 00:00:00 2001 From: Valerii Ponomarov Date: Thu, 7 Feb 2019 02:08:23 +0530 Subject: Add end-to-end OCP 'deployment' functionality Add end-to-end deployment tool of OpenShift and OpenShift Container Storage on top of VMWare. Added code is modified version of the 'reference-architecture/vmware-ansible' dir from the following repo: https://github.com/vponomaryov/openshift-ansible-contrib Read 'deployment/README.rst' file for more details about the deployment tool. Change-Id: Ic96f252ff786cc1ecf24d27f0ec47e324131e41b --- deployment/playbooks/library/vmware_folder.py | 253 ++++++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 deployment/playbooks/library/vmware_folder.py (limited to 'deployment/playbooks/library/vmware_folder.py') 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 . + +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() -- cgit