def associate_tag(self, stub_config, name, tags): """Associates tags with specific VM.""" if not name or not tags: raise VmCLIException( 'Arguments name or tags are missing, cannot continue!') vm = self.get_vm_obj(name, fail_missing=True) # Get vmware ID representation in form 'vm-XXX' for later association vm_id = vm._GetMoId() vm_dynid = DynamicID(type='VirtualMachine', id=vm_id) # Create API services for Tag and TagAssociation backends tag_svc = Tag(stub_config) tag_asoc = TagAssociation(stub_config) # Search for tag object(s) tags_found = [] if ',' in tags: tags = tags.split(',') else: tags = [tags] for t in tag_svc.list(): tag = tag_svc.get(t) if tag.name in tags: tags_found.append(tag) if len(tags_found) != len(tags): raise VmCLIException('One or more tags were not found') # Asosociate tags with VM for tag in tags_found: tag_asoc.attach(tag_id=tag.id, object_id=vm_dynid) self.logger.info('All tags have been attached to the VM')
def associate_tag(self, stub_config, name, tags): """Associates tags with specific VM.""" if not name or not tags: raise VmCLIException('Arguments name or tags are missing, cannot continue!') vm = self.get_vm_obj(name, fail_missing=True) # Get vmware ID representation in form 'vm-XXX' for later association vm_id = vm._GetMoId() vm_dynid = DynamicID(type='VirtualMachine', id=vm_id) # Create API services for Tag and TagAssociation backends tag_svc = Tag(stub_config) tag_asoc = TagAssociation(stub_config) # Search for tag object(s) tags_found = [] if ',' in tags: tags = tags.split(',') else: tags = [tags] for t in tag_svc.list(): tag = tag_svc.get(t) if tag.name in tags: tags_found.append(tag) if len(tags_found) != len(tags): raise VmCLIException('One or more tags were not found') # Asosociate tags with VM for tag in tags_found: tag_asoc.attach(tag_id=tag.id, object_id=vm_dynid) self.logger.info('All tags have been attached to the VM')
def __init__(self, module): """ Constructor """ super(VmwareTagManager, self).__init__(module) self.pyv = PyVmomi(module=module) self.object_type = self.params.get('object_type') self.object_name = self.params.get('object_name') if self.object_type == 'VirtualMachine': self.managed_object = self.pyv.get_vm_or_template(self.object_name) self.dynamic_managed_object = DynamicID( type=self.object_type, id=self.managed_object._moId) if self.managed_object is None: self.module.fail_json( msg="Failed to find the managed object for %s with type %s" % (self.object_name, self.object_type)) self.tag_service = Tag(self.connect) self.category_service = Category(self.connect) self.tag_association_svc = TagAssociation(self.connect) self.tag_names = self.params.get('tag_names')
def __init__(self, module): super(VmwareTag, self).__init__(module) self.tag_service = Tag(self.connect) self.global_tags = dict() self.tag_name = self.params.get('tag_name') self.get_all_tags() self.category_service = Category(self.connect)
def _setup(self): if self.cluster_name is None: # for testing self.cluster_name = self.args.clustername assert self.cluster_name is not None print('Cluster Name: {0}'.format(self.cluster_name)) if self.category_name is None: self.category_name = self.args.categoryname assert self.category_name is not None print('Category Name: {0}'.format(self.category_name)) if self.category_desc is None: self.category_desc = self.args.categorydesc assert self.category_desc is not None print('Category Description: {0}'.format(self.category_desc)) if self.tag_name is None: self.tag_name = self.args.tagname assert self.tag_name is not None print('Tag Name: {0}'.format(self.tag_name)) if self.tag_desc is None: self.tag_desc = self.args.tagdesc assert self.tag_desc is not None print('Tag Description: {0}'.format(self.tag_desc)) if self.servicemanager is None: self.servicemanager = self.get_service_manager() self.category_svc = Category(self.servicemanager.stub_config) self.tag_svc = Tag(self.servicemanager.stub_config) self.tag_association = TagAssociation(self.servicemanager.stub_config)
def build_tags(self, debug=False): print() print("Building the service manager for the deployment...") self.service_manager = ServiceManagerFactory.get_service_manager( self.web_svcs_host, self.sso_user, self.sso_pass, True) self.sm_client = ClsApiClient(self.service_manager) self.sm_client_helper = ClsApiHelper(self.sm_client, skip_verification=True) self.tag_category_svc = Category(self.service_manager.stub_config) self.tag_svc = Tag(self.service_manager.stub_config) self.tag_association = TagAssociation(self.service_manager.stub_config) print('Searching the existing categories user has access to...') categories = self.tag_category_svc.list() category_id = None if len(categories) > 0: for category in categories: cat = self.tag_category_svc.get(category) if cat.name == 'Encryption Tags': category_id = cat.id print("Tag Category already exists!") if not category_id: try: category_id = self.create_tag_category( 'Encryption Tags', "This tag category contains tags regarding encryption automation", CategoryModel.Cardinality.MULTIPLE) except errors_client.AlreadyExists as e: print(e) print(' --> Tag category Id: {0}'.format(category_id)) print() tags = self.tag_svc.list() if len(tags) > 0: for tag in tags: tag_detail = self.tag_svc.get(tag) if tag_detail.name == 'Encrypted VM': self.vm_tag_id = tag_detail.id print(" --> Encrypted VM Tag already exists!") if tag_detail.name == 'HyTrust Key Management Server': self.kms_tag_id = tag_detail.id print(" --> KMS Server Tag already exists!") if not self.vm_tag_id: try: self.create_vm_tags(category_id) except errors_client.AlreadyExists as e: print(e) if not self.kms_tag_id: try: self.create_kms_tags(category_id) except errors_client.AlreadyExists as e: print(e)
class VmwareTag(VmwareRestClient): def __init__(self, module): super(VmwareTag, self).__init__(module) self.tag_service = Tag(self.connect) self.tag_association = TagAssociation(self.connect) self.global_tags = dict() self.tag_name = self.params.get('tag_name') # for id in Category(self.connect).list(): # cat = Category(self.connect).get(id) # logger.info(" \"%s\": %s" % (cat.name,id)) def apply_tags(self, vm, category_ids, tags): dynamic_id = DynamicID(type='VirtualMachine', id=vm) attached = [] for tag in self.tag_service.list(): tag_obj = self.tag_service.get(tag) self.global_tags[tag_obj.category_id + tag_obj.name.lower()] = dict( tag_description=tag_obj.description, tag_used_by=tag_obj.used_by, tag_category_id=tag_obj.category_id, tag_id=tag_obj.id) logger.info(len(self.global_tags)) for tag_id in self.tag_association.list_attached_tags(dynamic_id): attached.append(tag_id) for id in tags: key = category_ids[id] + tags[id].lower() if key not in self.global_tags: logger.info("Creating new tag: " + key) create_spec = self.tag_service.CreateSpec() create_spec.name = tags[id] create_spec.description = tags[id] create_spec.category_id = category_ids[id] tag = self.tag_service.create(create_spec) tag = self.global_tags[key] if tag['tag_id'] in attached: logger.info("Skipping " + id) else: logger.info( "Applying %s (%s)=%s (%s) on %s" % (id, category_ids[id], tags[id], tag['tag_id'], vm)) self.tag_association.attach(tag_id=tag['tag_id'], object_id=dynamic_id) for tag_id in self.tag_association.list_attached_tags(dynamic_id): attached.append(tag_id) return attached
def tagSvc(self): if self._tag_svc is not None: return self._tag_svc self._tag_svc = Tag(self._config) return self._tag_svc
def _setup(self): if self.cluster_name is None: # for testing self.cluster_name = self.args.clustername assert self.cluster_name is not None logger.info('Cluster Name: {0}'.format(self.cluster_name)) if self.category_name is None: self.category_name = self.args.categoryname assert self.category_name is not None logger.info('Category Name: {0}'.format(self.category_name)) if self.category_desc is None: self.category_desc = self.args.categorydesc assert self.category_desc is not None logger.info('Category Description: {0}'.format(self.category_desc)) if self.tag_name is None: self.tag_name = self.args.tagname assert self.tag_name is not None logger.info('Tag Name: {0}'.format(self.tag_name)) if self.tag_desc is None: self.tag_desc = self.args.tagdesc assert self.tag_desc is not None logger.info('Tag Description: {0}'.format(self.tag_desc)) if self.servicemanager is None: self.servicemanager = self.get_service_manager() self.category_svc = Category(self.servicemanager.stub_config) self.tag_svc = Tag(self.servicemanager.stub_config) self.tag_association = TagAssociation(self.servicemanager.stub_config)
def __init__(self, module): """ Constructor """ super(VmwareTagManager, self).__init__(module) self.pyv = PyVmomi(module=module) self.object_type = self.params.get('object_type') self.object_name = self.params.get('object_name') self.managed_object = None if self.object_type == 'VirtualMachine': self.managed_object = self.pyv.get_vm_or_template(self.object_name) if self.object_type == 'Datacenter': self.managed_object = self.pyv.find_datacenter_by_name(self.object_name) if self.object_type == 'ClusterComputeResource': self.managed_object = self.pyv.find_cluster_by_name(self.object_name) if self.object_type == 'HostSystem': self.managed_object = self.pyv.find_hostsystem_by_name(self.object_name) if self.object_type == 'DistributedVirtualSwitch': self.managed_object = find_dvs_by_name(self.pyv.content, self.object_name) self.object_type = 'VmwareDistributedVirtualSwitch' if self.object_type == 'DistributedVirtualPortgroup': dvs_name, pg_name = self.object_name.split(":", 1) dv_switch = find_dvs_by_name(self.pyv.content, dvs_name) if dv_switch is None: self.module.fail_json(msg="A distributed virtual switch with name %s does not exist" % dvs_name) self.managed_object = find_dvspg_by_name(dv_switch, pg_name) if self.managed_object is None: self.module.fail_json(msg="Failed to find the managed object for %s with type %s" % (self.object_name, self.object_type)) if not hasattr(self.managed_object, '_moId'): self.module.fail_json(msg="Unable to find managed object id for %s managed object" % self.object_name) self.dynamic_managed_object = DynamicID(type=self.object_type, id=self.managed_object._moId) self.tag_service = Tag(self.connect) self.category_service = Category(self.connect) self.tag_association_svc = TagAssociation(self.connect) self.tag_names = self.params.get('tag_names')
class VmTagFactManager(VmwareRestClient): def __init__(self, module): """Constructor.""" super(VmTagFactManager, self).__init__(module) self.tag_service = Tag(self.connect) self.global_tags = dict() def get_all_tags(self): """Function to retrieve all tag information.""" for tag in self.tag_service.list(): tag_obj = self.tag_service.get(tag) self.global_tags[tag_obj.name] = dict( tag_description=tag_obj.description, tag_used_by=tag_obj.used_by, tag_category_id=tag_obj.category_id, tag_id=tag_obj.id) self.module.exit_json(changed=False, tag_facts=self.global_tags)
class VmTagFactManager(VmwareRestClient): def __init__(self, module): """Constructor.""" super(VmTagFactManager, self).__init__(module) self.tag_service = Tag(self.connect) self.global_tags = dict() def get_all_tags(self): """Function to retrieve all tag information.""" for tag in self.tag_service.list(): tag_obj = self.tag_service.get(tag) self.global_tags[tag_obj.name] = dict( tag_description=tag_obj.description, tag_used_by=tag_obj.used_by, tag_category_id=tag_obj.category_id, tag_id=tag_obj.id ) self.module.exit_json(changed=False, tag_facts=self.global_tags)
def _setup(self): if self.cluster_name is None: # for testing self.cluster_name = self.args.clustername assert self.cluster_name is not None print('Cluster Name: {0}'.format(self.cluster_name)) if self.category_name is None: self.category_name = self.args.categoryname assert self.category_name is not None print('Category Name: {0}'.format(self.category_name)) if self.category_desc is None: self.category_desc = self.args.categorydesc assert self.category_desc is not None print('Category Description: {0}'.format(self.category_desc)) if self.tag_name is None: self.tag_name = self.args.tagname assert self.tag_name is not None print('Tag Name: {0}'.format(self.tag_name)) if self.tag_desc is None: self.tag_desc = self.args.tagdesc assert self.tag_desc is not None print('Tag Description: {0}'.format(self.tag_desc)) if self.servicemanager is None: self.servicemanager = self.get_service_manager() # Sample is not failing if Clustername passed is not valid # Validating if Cluster Name passed is Valid print('finding the cluster {0}'.format(self.cluster_name)) self.cluster_moid = get_cluster_id(service_manager=self.servicemanager, cluster_name=self.cluster_name) assert self.cluster_moid is not None print('Found cluster:{0} mo_id:{1}'.format(self.cluster_name, self.cluster_moid)) self.category_svc = Category(self.servicemanager.stub_config) self.tag_svc = Tag(self.servicemanager.stub_config) self.tag_association = TagAssociation(self.servicemanager.stub_config)
def get_tag_details(unique_tags, connectcis=connect_cis()): """Get the details for each unique tag""" from com.vmware.cis.tagging_client import Tag, Category result = {} for tagid in unique_tags: result[tagid] = {} tagdetails = Tag(connectcis).get(tagid) catname = Category(connectcis).get(tagdetails.category_id).name result[tagid]['name'] = tagdetails.name result[tagid]['cat'] = catname # servertags += str(catname)+":"+str(tagdetails.name)+";" return result
def execute(self): logger.info('Connecting to lookup service url: {0}'.format(self.lssoapurl)) lookupservicehelper = LookupServiceHelper(wsdl_url=self.lswsdlurl, soap_url=self.lssoapurl) lookupservicehelper.connect() if self.mgmtinstancename is None: self.mgmtinstancename, self.mgmtnodeid = lookupservicehelper.get_default_mgmt_node() elif self.mgmtnodeid is None: self.mgmtnodeid = lookupservicehelper.get_mgmt_node_id(self.mgmtinstancename) assert self.mgmtnodeid is not None self.vapiurl = lookupservicehelper.find_vapi_url(self.mgmtnodeid) logger.info('vapi_url: {0}'.format(self.vapiurl)) logger.info('Connecting to VAPI endpoint and preparing stub configuration...') connector = connect.get_connector('https', 'json', url=self.vapiurl) self.stub_config = StubConfigurationFactory.new_std_configuration(connector) sec_ctx = create_user_password_security_context(self.ssousername, self.ssopassword) connector.set_security_context(sec_ctx) self.stub_config = StubConfigurationFactory.new_std_configuration(connector) self.session = Session(self.stub_config) logger.info('Login to VAPI endpoint and get the session_id...') self.session_id = self.session.create() logger.info('Update the VAPI connection with session_id...') session_sec_ctx = create_session_security_context(self.session_id) connector.set_security_context(session_sec_ctx) # make sure you can access some of the VAPI services tag_svc = Tag(self.stub_config) logger.info('List all the existing tags user has access to...') tags = tag_svc.list() if len(tags) > 0: for tag in tags: logger.info('Found Tag: {0}'.format(tag)) else: logger.info('No Tag Found...')
class VmwareTag(VmwareRestClient): def __init__(self, module): super(VmwareTag, self).__init__(module) self.tag_service = Tag(self.connect) self.global_tags = dict() self.tag_name = self.params.get('tag_name') self.get_all_tags() self.category_service = Category(self.connect) def ensure_state(self): """ Manage internal states of tags """ desired_state = self.params.get('state') states = { 'present': { 'present': self.state_update_tag, 'absent': self.state_create_tag, }, 'absent': { 'present': self.state_delete_tag, 'absent': self.state_unchanged, } } states[desired_state][self.check_tag_status()]() def state_create_tag(self): """ Create tag """ tag_spec = self.tag_service.CreateSpec() tag_spec.name = self.tag_name tag_spec.description = self.params.get('tag_description') category_id = self.params.get('category_id', None) if category_id is None: self.module.fail_json(msg="'category_id' is required parameter while creating tag.") category_found = False for category in self.category_service.list(): category_obj = self.category_service.get(category) if category_id == category_obj.id: category_found = True break if not category_found: self.module.fail_json(msg="Unable to find category specified using 'category_id' - %s" % category_id) tag_spec.category_id = category_id tag_id = self.tag_service.create(tag_spec) if tag_id: self.module.exit_json(changed=True, results=dict(msg="Tag '%s' created." % tag_spec.name, tag_id=tag_id)) self.module.exit_json(changed=False, results=dict(msg="No tag created", tag_id='')) def state_unchanged(self): """ Return unchanged state """ self.module.exit_json(changed=False) def state_update_tag(self): """ Update tag """ changed = False tag_id = self.global_tags[self.tag_name]['tag_id'] results = dict(msg="Tag %s is unchanged." % self.tag_name, tag_id=tag_id) tag_update_spec = self.tag_service.UpdateSpec() tag_desc = self.global_tags[self.tag_name]['tag_description'] desired_tag_desc = self.params.get('tag_description') if tag_desc != desired_tag_desc: tag_update_spec.description = desired_tag_desc self.tag_service.update(tag_id, tag_update_spec) results['msg'] = 'Tag %s updated.' % self.tag_name changed = True self.module.exit_json(changed=changed, results=results) def state_delete_tag(self): """ Delete tag """ tag_id = self.global_tags[self.tag_name]['tag_id'] self.tag_service.delete(tag_id=tag_id) self.module.exit_json(changed=True, results=dict(msg="Tag '%s' deleted." % self.tag_name, tag_id=tag_id)) def check_tag_status(self): """ Check if tag exists or not Returns: 'present' if tag found, else 'absent' """ ret = 'present' if self.tag_name in self.global_tags else 'absent' return ret def get_all_tags(self): """ Retrieve all tag information """ for tag in self.tag_service.list(): tag_obj = self.tag_service.get(tag) self.global_tags[tag_obj.name] = dict(tag_description=tag_obj.description, tag_used_by=tag_obj.used_by, tag_category_id=tag_obj.category_id, tag_id=tag_obj.id )
def __init__(self, module): super(VmwareTag, self).__init__(module) self.tag_service = Tag(self.connect) self.tag_association_svc = TagAssociation(self.connect)
class VmwareTagManager(VmwareRestClient): def __init__(self, module): """ Constructor """ super(VmwareTagManager, self).__init__(module) self.pyv = PyVmomi(module=module) self.object_type = self.params.get('object_type') self.object_name = self.params.get('object_name') self.managed_object = None if self.object_type == 'VirtualMachine': self.managed_object = self.pyv.get_vm_or_template(self.object_name) if self.object_type == 'Datacenter': self.managed_object = self.pyv.find_datacenter_by_name(self.object_name) if self.object_type == 'ClusterComputeResource': self.managed_object = self.pyv.find_cluster_by_name(self.object_name) if self.object_type == 'HostSystem': self.managed_object = self.pyv.find_hostsystem_by_name(self.object_name) if self.object_type == 'DistributedVirtualSwitch': self.managed_object = find_dvs_by_name(self.pyv.content, self.object_name) self.object_type = 'VmwareDistributedVirtualSwitch' if self.object_type == 'DistributedVirtualPortgroup': dvs_name, pg_name = self.object_name.split(":", 1) dv_switch = find_dvs_by_name(self.pyv.content, dvs_name) if dv_switch is None: self.module.fail_json(msg="A distributed virtual switch with name %s does not exist" % dvs_name) self.managed_object = find_dvspg_by_name(dv_switch, pg_name) if self.managed_object is None: self.module.fail_json(msg="Failed to find the managed object for %s with type %s" % (self.object_name, self.object_type)) if not hasattr(self.managed_object, '_moId'): self.module.fail_json(msg="Unable to find managed object id for %s managed object" % self.object_name) self.dynamic_managed_object = DynamicID(type=self.object_type, id=self.managed_object._moId) self.tag_service = Tag(self.connect) self.category_service = Category(self.connect) self.tag_association_svc = TagAssociation(self.connect) self.tag_names = self.params.get('tag_names') def is_tag_category(self, cat_obj, tag_obj): for tag in self.tag_service.list_tags_for_category(cat_obj.id): if tag_obj.name == self.tag_service.get(tag).name: return True return False def ensure_state(self): """ Manage the internal state of tags """ results = dict( changed=False, tag_status=dict(), ) changed = False action = self.params.get('state') available_tag_obj = self.get_tags_for_object(tag_service=self.tag_service, tag_assoc_svc=self.tag_association_svc, dobj=self.dynamic_managed_object) # Already existing tags from the given object avail_tag_obj_name_list = [tag.name for tag in available_tag_obj] results['tag_status']['previous_tags'] = avail_tag_obj_name_list results['tag_status']['desired_tags'] = self.tag_names # Check if category and tag combination exists as per user request removed_tags_for_set = False for tag in self.tag_names: category_obj, category_name, tag_name = None, None, None if ":" in tag: # User specified category category_name, tag_name = tag.split(":", 1) category_obj = self.search_svc_object_by_name(self.category_service, category_name) if not category_obj: self.module.fail_json(msg="Unable to find the category %s" % category_name) else: # User specified only tag tag_name = tag tag_obj = self.search_svc_object_by_name(self.tag_service, tag_name) if not tag_obj: self.module.fail_json(msg="Unable to find the tag %s" % tag_name) if category_name and category_obj and not self.is_tag_category(category_obj, tag_obj): self.module.fail_json(msg="Category %s does not contain tag %s" % (category_name, tag_name)) if action in ('add', 'present'): if tag_obj not in available_tag_obj: # Tag is not already applied self.tag_association_svc.attach(tag_id=tag_obj.id, object_id=self.dynamic_managed_object) changed = True elif action == 'set': # Remove all tags first if not removed_tags_for_set: for av_tag in available_tag_obj: self.tag_association_svc.detach(tag_id=av_tag.id, object_id=self.dynamic_managed_object) removed_tags_for_set = True self.tag_association_svc.attach(tag_id=tag_obj.id, object_id=self.dynamic_managed_object) changed = True elif action in ('remove', 'absent'): if tag_obj in available_tag_obj: self.tag_association_svc.detach(tag_id=tag_obj.id, object_id=self.dynamic_managed_object) changed = True results['tag_status']['current_tags'] = [tag.name for tag in self.get_tags_for_object(self.tag_service, self.tag_association_svc, self.dynamic_managed_object)] results['changed'] = changed self.module.exit_json(**results)
class DeployKMIP(object): class kmipSpec(): name = None # the name (and hostname) of the node consolepw = None # the console password of the node secrootpw = None # the 'secroot' user password on this node ip = None # the IP address of the node subnet = None # the subnet mask of the node gateway = None # the gateway address of the node dns = None # the DNS servers of the node domain = None # the dns suffix of the node clusterpw = None # the password to use when joining the cluster on secondary nodes port = 5696 # the port number to use in the node primary_node = False # whether or not this node is the primary or a secondary def __init__(self, name=None, consolepw=None, secrootpw=None, ip=None, subnet=None, gateway=None, dns=None, domain=None, clusterpw=None, port=5676, primary=False): self.name = name self.consolepw = consolepw self.secrootpw = secrootpw self.ip = ip self.subnet = subnet self.gateway = gateway self.dns = dns self.domain = domain self.clusterpw = clusterpw self.port = port self.primary_node = primary def is_primary(self): return self.primary_node version = "0.1.0rc1" # the version number of this application psc_address = None # the fqdn or IP of the Platform Services Controller to login to sso_user = None # the username to use to login sso_pass = None # the password to use to login vcs = None # the VCS endpoint to connect to content_library_name = None # the name of the content library that houses a hytrust OVF deploy_to_cluster = None # the name of the cluster to deploy the KMIP nodes to kms_cluster_name = None # the name to use for the Cluster in the KMIP nodes kms_port = 5696 # the port number to use in the KMIP nodes secroot_pass = None # the password of the secroot user user_wsdl_url = None # the file:// uri path to the wsdl files in the sdk (lookupservice.wdsl, etc.) vcs_target = None # the full lookup service target (computed) lookup_service_helper = None # the LookupServiceHelper object instance service_manager = None # an instance of the ServiceManager object stub_config = None # the StubConfigurationFactory object instance web_svcs_host = None # the web services host discovered from LookupService service_instance_stub = None # the stub created from a ServiceInstance sm_client = None # an instance of the ServiceManager Client sm_client_helper = None # an instance of the ServiceManager Client Helper tag_category_svc = None # an instance of the TagCategory service tag_svc = None # an instance of the Tag service tag_association = None vcs_cluster_obj = None # an instance of the object representing a VCS Cluster kmip_cert_ca = None # the Certificate Auhority certificate issued by the Hytrust Cluster kmip_cert_user = None # the User certificate issued by the Hytrust Cluster selected_item = { } # the information about which content library item is deployed kms_tag_id = None # the ID of the kms server tag vm_tag_id = None # the ID of the encrypted vm tag primary_node_spec = None # an instance of the kmipSpec class to house the primary node info primary_node_id = None # the ID of the primary node primary_node_obj = None # an instance of the VM object representing the primary node (by moid) primary_node_ticket = None # a WebKMS ticket to auth to the primary node primary_node_vm = None # backup instance of the VM object representing the primary node (by uuid) secondary_node_spec = None # an instance of the kmipSpec class to house the secondary node info secondary_node_id = None # the ID of the secondary node secondary_node_obj = None # an instance of the VM object representing the secondary node (by moid) secondary_node_ticket = None # a WebKMS ticket to auth to the secondary node secondary_node_vm = None # backup instance of the VM object representing the secondary node (by uuid) def __init__(self, **kwargs): try: # Parse arguments, use file docstring as a parameter definition arguments = docopt.docopt(__doc__, version=self.version) # Pull the arguments our into local variables. self.primary_node_spec = DeployKMIP.kmipSpec( name=arguments['--node1name'], consolepw=arguments['--node1consolepw'], secrootpw=arguments['--secroot_pass'], ip=arguments['--node1ip'], subnet=arguments['--node1subnet'], gateway=arguments['--node1gw'], dns=arguments['--node1dns'], domain=arguments['--node1domain'], clusterpw=None, port=int(arguments['--kmsport']), primary=True) self.secondary_node_spec = DeployKMIP.kmipSpec( name=arguments['--node2name'], consolepw=arguments['--node2consolepw'], secrootpw=arguments['--secroot_pass'], ip=arguments['--node2ip'], subnet=arguments['--node2subnet'], gateway=arguments['--node2gw'], dns=arguments['--node2dns'], domain=arguments['--node2domain'], clusterpw=arguments['--node2clusterpw'], port=int(arguments['--kmsport']), primary=False) self.psc_address = arguments['--psc'] self.sso_user = arguments['--sso_user'] self.sso_pass = arguments['--sso_pass'] self.vcs = arguments['--vcs'] self.content_library_name = arguments['--clib'] self.deploy_to_cluster = arguments['--cluster'] self.kms_cluster_name = arguments['--kmsname'] self.user_wsdl_url = arguments['--wsdlurl'] # Get the target vCenter Server (with embedded PSC) self.vcs_target = 'https://%s/lookupservice/sdk' % self.psc_address # Handle invalid options except docopt.DocoptExit as e: print(e) sys.exit() @staticmethod def wait_for_task(task, action_name='job', hide_result=False): """ Waits and provides updates on a vSphere task """ while task.info.state == vim.TaskInfo.State.running: time.sleep(2) if task.info.state == vim.TaskInfo.State.success: if task.info.result is not None and not hide_result: out = '%s completed successfully, result: %s' % ( action_name, task.info.result) print(out) else: out = '%s completed successfully.' % action_name print(out) else: out = '%s did not complete successfully: %s' % (action_name, task.info.error) print(out) raise task.info.error return task.info.result def invoke_and_track(self, func, *args, **kw): try: task = func(*args, **kw) self.wait_for_task(task) except: raise def create_tag_category(self, name, description, cardinality): print("Creating Tag Category...") create_spec = self.tag_category_svc.CreateSpec() create_spec.name = name create_spec.description = description create_spec.cardinality = cardinality associable_types = set() create_spec.associable_types = associable_types return self.tag_category_svc.create(create_spec) def create_tag(self, name, description, category_id): """Creates a Tag""" create_spec = self.tag_svc.CreateSpec() create_spec.name = name create_spec.description = description create_spec.category_id = category_id return self.tag_svc.create(create_spec) def create_kms_tags(self, category_id): print("Creating KMS VM Tags...") return self.create_tag( "HyTrust Key Management Server", "This tag is assigned to HyTrust KMS Appliances", category_id) def create_vm_tags(self, category_id): print("Creating VM Tags...") return self.create_tag( "Encrypted VM", "This tag is assigned to VMs with Encryption enabled", category_id) def tag_vm(self, vm_id, tag_id): tag_attached = False dynamic_id = DynamicID(type='VirtualMachine', id=vm_id) self.tag_association.attach(tag_id=tag_id, object_id=dynamic_id) for tag_id in self.tag_association.list_attached_tags(dynamic_id): if tag_id == self.kms_tag_id: tag_attached = True break return tag_attached def encrypt_all_vms(self, vm_tag_id, si, session): content = self.service_instance_stub.RetrieveContent() for child in content.rootFolder.childEntity: if hasattr(child, 'vmFolder'): datacenter = child vm_folder = datacenter.vmFolder vm_list = vm_folder.childEntity for vm in vm_list: self.encrypt_vm(vm, vm_tag_id, session) def encrypt_vm(self, vm, tag_id, session, depth=1): maxdepth = 10 # if this is a group it will have children. if it does, recurse into them # and then return if hasattr(vm, 'childEntity'): if depth > maxdepth: return vm_list = vm.childEntity for c in vm_list: self.encrypt_vm(c, tag_id, depth + 1) return # if this is a vApp, it likely contains child VMs # (vApps can nest vApps, but it is hardly a common use case, so ignore that) if isinstance(vm, vim.VirtualApp): vm_list = vm.vm for c in vm_list: self.encrypt_vm(c, tag_id, depth + 1) return # Don't encrypt the KMIP nodes summary = vm.summary if summary.config.name == self.primary_node_spec.name or summary.config.name == self.secondary_node_spec.name: return # Don't encrypt the vcs nodes if summary.guest.hostName == self.vcs: return print("Tagging VM ({0}) with 'Encrypted VM' tag...".format( summary.guest.hostName)) self.tag_vm(vm._moId, tag_id) # TODO: Encrypt the VM by creating a CryptoSpec() and reconfiguring the VM def discover_environment(self, debug=False): # Connect to the lookup service to discover relevant information self.lookup_service_helper = LookupServiceHelper( wsdl_url=self.user_wsdl_url + '/lookupservice.wsdl', soap_url=self.vcs_target, skip_verification=True) self.lookup_service_helper.connect() # Print information obtained through the lookup service to the console if debug: print("SSO URL: " + str(self.lookup_service_helper.find_sso_url())) print("VAPI URL(s): " + str(self.lookup_service_helper.find_vapi_urls())) print("VIM URL: " + str(self.lookup_service_helper.find_vim_urls())) print("VIM PBM URL(s): " + str(self.lookup_service_helper.find_vim_pbm_urls())) print("MGMT Nodes: " + str(self.lookup_service_helper.find_mgmt_nodes())) print() print('Connecting to SSO Service : $s', str(self.lookup_service_helper.find_sso_url())) print(" - user: {}".format(self.sso_user)) # Use the SsoAuthenticator utility class to retrieve # a bearer SAML token from the vCenter Single Sign-On service. print() print("Retrieving SAML Token ::") authenticator = sso.SsoAuthenticator( str(self.lookup_service_helper.find_sso_url())) saml_token = authenticator.get_bearer_saml_assertion(self.sso_user, self.sso_pass, delegatable=True) print(">>> SAML Token Successfully Retrieved!") print() print("Generating vSphere Authentication Session via SAML Token ::") # Create a session object in the client. session = requests.Session() # For development environment only, suppress server certificate checking. print() print("Suppressing Server Certificate Checking...") session.verify = False disable_warnings(InsecureRequestWarning) print(">>> Server Certificate Checking Suppressed!") # Create a connection for the session. print() print("Creating the VAPI connection object...") vapi_url = str(self.lookup_service_helper.find_vapi_urls()).split()[1] vapi_url = vapi_url[:-1] if debug: print(" --> Endpoint: " + vapi_url) connector = get_requests_connector(session=session, url=vapi_url) # Add SAML token security context to the connector. saml_token_context = create_saml_bearer_security_context(saml_token) connector.set_security_context(saml_token_context) # Create a stub configuration by using the SAML token security context. self.stub_config = StubConfigurationFactory.new_std_configuration( connector) # Create a Session stub with SAML token security context. session_stub = Session(self.stub_config) # Use the create operation to create an authenticated session. session_id = session_stub.create() if debug: print(" --> vSphere Automation Session ID: ", session_id) # Create a session ID security context. session_id_context = create_session_security_context(session_id) # Update the stub configuration with the session ID security context. self.stub_config.connector.set_security_context(session_id_context) print() print("Generating Web Services Session Info via Lookup Service...") vim_url = str(self.lookup_service_helper.find_vim_urls()).split()[1] vim_url = vim_url[:-1] if debug: print(" --> Endpoint: " + vim_url) # Extract the hostname from the endpoint URL. url_scheme, url_host, url_path, url_params, url_query, url_fragment = \ urlparse(vim_url) pattern = '(?P<host>[^:/ ]+).?(?P<port>[0-9]*)' match = re.search(pattern, url_host) self.web_svcs_host = match.group('host') if debug: print(">>> Connecting to host: ", self.web_svcs_host) def retrieve_content_library_items(self, debug=False): print() print("Retrieving Content Libraries ::") print(">>> Searching for Library Name: ", self.content_library_name) # Create a FindSpec object to specify the search criteria. find_spec = content_client.Library.FindSpec() find_spec.name = self.content_library_name find_spec.type = content_client.LibraryModel.LibraryType.LOCAL # Invoke the find() function by using the FindSpec instance. library_stub = content_client.Library(self.stub_config) library_ids = library_stub.find(find_spec) libraries = library_stub.list() print() print("Listing all library identifiers:") for library_id in library_ids: library = library_stub.get(library_id) print(" --> Library ID {}: {}".format(library_id, library.name)) print() print( ">>> Retrieving a list of Hytrust Library Items from Library: {} ({})" .format(library.name, library_id)) # List the items in a published library. item_stub = library_client.Item(self.stub_config) item_ids = item_stub.list(library_id) # List the files uploaded to each library item and print their names and sizes if they contain Hytrust. file_stub = item_client.File(self.stub_config) for item_id in item_ids: if not self.selected_item: item = item_stub.get(item_id) if 'hytrust' in item.name.lower(): file_infos = file_stub.list(item_id) print( "Library item :: \n - Name: {}\n - ID: {} has file(s):" .format(item.name, item_id)) for file_info in file_infos: print(" +-- File: {} with a size of {} byte(s)". format(file_info.name, file_info.size)) print() deploy_this_ovf = input( " ----> Do you want to deploy this Item? [default: N] : " ) if (deploy_this_ovf.lower() == 'y') or (deploy_this_ovf.lower() == 'yes'): self.selected_item = { "id": item_id, "name": item.name } print( ">>> You have selected [{}] for deployment...". format(self.selected_item["name"])) break else: sys.exit() else: print(">>> No Hytrust OVF found! Exiting...") sys.exit() return self.selected_item def build_tags(self, debug=False): print() print("Building the service manager for the deployment...") self.service_manager = ServiceManagerFactory.get_service_manager( self.web_svcs_host, self.sso_user, self.sso_pass, True) self.sm_client = ClsApiClient(self.service_manager) self.sm_client_helper = ClsApiHelper(self.sm_client, skip_verification=True) self.tag_category_svc = Category(self.service_manager.stub_config) self.tag_svc = Tag(self.service_manager.stub_config) self.tag_association = TagAssociation(self.service_manager.stub_config) print('Searching the existing categories user has access to...') categories = self.tag_category_svc.list() category_id = None if len(categories) > 0: for category in categories: cat = self.tag_category_svc.get(category) if cat.name == 'Encryption Tags': category_id = cat.id print("Tag Category already exists!") if not category_id: try: category_id = self.create_tag_category( 'Encryption Tags', "This tag category contains tags regarding encryption automation", CategoryModel.Cardinality.MULTIPLE) except errors_client.AlreadyExists as e: print(e) print(' --> Tag category Id: {0}'.format(category_id)) print() tags = self.tag_svc.list() if len(tags) > 0: for tag in tags: tag_detail = self.tag_svc.get(tag) if tag_detail.name == 'Encrypted VM': self.vm_tag_id = tag_detail.id print(" --> Encrypted VM Tag already exists!") if tag_detail.name == 'HyTrust Key Management Server': self.kms_tag_id = tag_detail.id print(" --> KMS Server Tag already exists!") if not self.vm_tag_id: try: self.create_vm_tags(category_id) except errors_client.AlreadyExists as e: print(e) if not self.kms_tag_id: try: self.create_kms_tags(category_id) except errors_client.AlreadyExists as e: print(e) def deploy_kmip_node(self, spec, debug=False): # Check if we know about the deployment target yet if self.vcs_cluster_obj is None: # Find the cluster's resource pool moid print() print("Obtaining the cluster's resource pool moid...") self.vcs_cluster_obj = get_obj(self.service_manager.content, [vim.ClusterComputeResource], self.deploy_to_cluster) assert self.vcs_cluster_obj is not None if debug: print(" --> Cluster: {0}".format(self.vcs_cluster_obj)) # Get a deployment target resource pool from the Cluster Object deployment_target = LibraryItem.DeploymentTarget( resource_pool_id=self.vcs_cluster_obj.resourcePool._GetMoId()) if debug: print(" --> Resource Pool Moref: {0}".format( self.vcs_cluster_obj.resourcePool._GetMoId())) # Find lib item id from given item name find_spec = Item.FindSpec() find_spec.name = self.selected_item["name"] item_ids = self.sm_client.library_item_service.find(find_spec) assert (item_ids is not None and len(item_ids) > 0), ( 'No items found with name: {0}'.format(self.selected_item["name"])) lib_item_id = item_ids[0] ovf_summary = self.sm_client.ovf_lib_item_service.filter( ovf_library_item_id=lib_item_id, target=deployment_target) print() print('Deploying OVF template: {0} to cluster: {1}...'.format( ovf_summary.name, self.deploy_to_cluster)) # Build the deployment spec deployment_spec = LibraryItem.ResourcePoolDeploymentSpec( name=spec.name, annotation=ovf_summary.annotation, accept_all_eula=True, network_mappings=None, storage_mappings=None, storage_provisioning=None, storage_profile_id=None, locale=None, flags=None, additional_parameters=None, default_datastore_id=None) # Deploy the ovf template print("Deploying HyTrust OVF Template -- please wait...") print() result = self.sm_client.ovf_lib_item_service.deploy( lib_item_id, deployment_target, deployment_spec, client_token=generate_random_uuid()) # The type and ID of the target deployment is available in the deployment result. if result.succeeded: print('>>> Deployment successful.') if debug: print('Result resource: {0}, ID: {1}'.format( result.resource_id.type, result.resource_id.id)) error = result.error # if error is not None: # for warning in error.warnings: # print('OVF warning: {}'.format(warning.message)) # Get the vm object if spec.is_primary(): self.primary_node_id = result.resource_id.id self.primary_node_obj = get_obj_by_moId( self.service_manager.content, [vim.VirtualMachine], self.primary_node_id) assert self.primary_node_obj is not None vm_obj = self.primary_node_obj vm_id = self.primary_node_id else: self.secondary_node_id = result.resource_id.id self.secondary_node_obj = get_obj_by_moId( self.service_manager.content, [vim.VirtualMachine], self.secondary_node_id) assert self.secondary_node_obj is not None vm_obj = self.secondary_node_obj vm_id = self.secondary_node_id # Invoke the SmartConnect() method by supplying the host name, user name, and password. self.service_instance_stub = SmartConnect(host=self.web_svcs_host, user=self.sso_user, pwd=self.sso_pass) atexit.register(connect.Disconnect, self.service_instance_stub) content = self.service_instance_stub.RetrieveContent() if debug: print("VM UUID: {0}".format(vm_obj.summary.config.uuid)) if spec.is_primary(): self.primary_node_vm = content.searchIndex.FindByUuid( None, vm_obj.summary.config.uuid, True) vm = self.primary_node_vm else: self.secondary_node_vm = content.searchIndex.FindByUuid( None, vm_obj.summary.config.uuid, True) vm = self.secondary_node_vm print() print("Setting vApp Options on the VM...") vapp_spec_list = list() # Domain Name vapp_domainName = vim.vApp.PropertyInfo() vapp_domainName.key = 0 vapp_domainName.value = spec.domain vapp_spec1 = vim.vApp.PropertySpec() vapp_spec1.info = vapp_domainName vapp_spec1.operation = 'edit' vapp_spec_list.append(vapp_spec1) # Netmask vapp_netmask = vim.vApp.PropertyInfo() vapp_netmask.key = 1 vapp_netmask.value = spec.subnet vapp_spec2 = vim.vApp.PropertySpec() vapp_spec2.info = vapp_netmask vapp_spec2.operation = 'edit' vapp_spec_list.append(vapp_spec2) # KCMaster vapp_kcmaster = vim.vApp.PropertyInfo() vapp_kcmaster.key = 2 if spec.is_primary(): vapp_kcmaster.value = '' else: vapp_kcmaster.userConfigurable = True vapp_kcmaster.value = self.primary_node_spec.ip vapp_spec3 = vim.vApp.PropertySpec() vapp_spec3.info = vapp_kcmaster vapp_spec3.operation = 'edit' vapp_spec_list.append(vapp_spec3) # Console Password vapp_consolepw = vim.vApp.PropertyInfo() vapp_consolepw.key = 3 vapp_consolepw.userConfigurable = True vapp_consolepw.value = spec.consolepw vapp_spec4 = vim.vApp.PropertySpec() vapp_spec4.info = vapp_consolepw vapp_spec4.operation = 'edit' vapp_spec_list.append(vapp_spec4) # HTKC Hostname vapp_htkcHostname = vim.vApp.PropertyInfo() vapp_htkcHostname.key = 4 vapp_htkcHostname.value = spec.name vapp_spec5 = vim.vApp.PropertySpec() vapp_spec5.info = vapp_htkcHostname vapp_spec5.operation = 'edit' vapp_spec_list.append(vapp_spec5) # DNS Servers vapp_dns = vim.vApp.PropertyInfo() vapp_dns.key = 5 vapp_dns.value = spec.dns vapp_spec6 = vim.vApp.PropertySpec() vapp_spec6.info = vapp_dns vapp_spec6.operation = 'edit' vapp_spec_list.append(vapp_spec6) # HTKC IP Address vapp_htkcIP = vim.vApp.PropertyInfo() vapp_htkcIP.key = 6 vapp_htkcIP.value = spec.ip vapp_spec7 = vim.vApp.PropertySpec() vapp_spec7.info = vapp_htkcIP vapp_spec7.operation = 'edit' vapp_spec_list.append(vapp_spec7) # NTP Servers vapp_ntp = vim.vApp.PropertyInfo() vapp_ntp.key = 7 vapp_ntp.value = '0.us.pool.ntp.org, 1.us.pool.ntp.org' vapp_spec8 = vim.vApp.PropertySpec() vapp_spec8.info = vapp_ntp vapp_spec8.operation = 'edit' vapp_spec_list.append(vapp_spec8) # Gateway vapp_gateway = vim.vApp.PropertyInfo() vapp_gateway.key = 8 vapp_gateway.value = spec.gateway vapp_spec9 = vim.vApp.PropertySpec() vapp_spec9.info = vapp_gateway vapp_spec9.operation = 'edit' vapp_spec_list.append(vapp_spec9) # KC Cluster Password vapp_kcpw = vim.vApp.PropertyInfo() vapp_kcpw.key = 9 vapp_kcpw.userConfigurable = True vapp_kcpw.value = spec.clusterpw vapp_spec10 = vim.vApp.PropertySpec() vapp_spec10.info = vapp_kcpw vapp_spec10.operation = 'edit' vapp_spec_list.append(vapp_spec10) # Make the modifications config_spec = vim.vm.ConfigSpec() config_spec.vAppConfig = vim.vApp.VmConfigSpec() config_spec.vAppConfig.property = vapp_spec_list reconfig_task = vm.ReconfigVM_Task(config_spec) task.wait_for_task(reconfig_task) print("Successfully modified VM:[{0}] properties".format( spec.name)) # Add the KMS tag to the VM print() print('Tagging the KMS VM :: {0}...'.format(spec.name)) kms_tag_attached = self.tag_vm(vm_id, self.kms_tag_id) assert kms_tag_attached if debug: print('Tagged KMS vm: {0}'.format(vm_id)) # Power on the VM and wait for the power on operation to be completed print() print("Powering on the KMS Server: {0} ...".format(spec.name)) poweron_vm(self.service_manager.content, vm_obj) while vm.runtime.powerState != vim.VirtualMachinePowerState.poweredOn: print("Waiting for VM [{0}] to power on...".format(spec.name)) time.sleep(3) # Get a WebKMS ticket so we can manipulate the console if we need to if spec.is_primary(): self.primary_node_ticket = vm.AcquireTicket("webmks") ticket = self.primary_node_ticket else: self.secondary_node_ticket = vm.AcquireTicket("webmks") ticket = self.secondary_node_ticket print("WebMKS Ticket: {0}".format(ticket)) print("WMKS URL: wss://{0}:{1}/ticket/{2}".format( ticket.host, ticket.port, ticket.ticket)) else: print('Deployment failed.') for error in result.error.errors: print('OVF error: {}'.format(error.message)) def config_kmip_node(self, spec, debug=False): # Disable cert verification context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) context.verify_mode = ssl.CERT_NONE # Login to the API (secroot account) print("Logging into HyTrust Node [{0}]...".format(spec.name)) s = requests.session() login_body = json.dumps({ u'username': u'secroot', u'password': u'secroot' }) login_headers = {'content-type': 'application/json'} r = s.post("https://{0}/v4/kc/login/".format(spec.ip), data=login_body, headers=login_headers, verify=False) print(r.json()) token = r.json()['access_token'] print("HyTrust Node [{0}] : Access Token: {1}".format( spec.name, token)) # Change 'secroot' password print("Changing 'secroot' password on HyTrust Node [{0}]...".format( spec.name)) pwchange_body = json.dumps({ u'username': u'secroot', u'password': spec.secrootpw }) pwchange_headers = { 'content-type': 'application/json', u'Auth-Token': token } r = s.post("https://{0}/v4/login_edit/".format(spec.ip), data=pwchange_body, headers=pwchange_headers, verify=False) print(r.json()) # Changing the 'secroot' password invalidates the token. Re-login required... # Login to the API (secroot account) print("Logging into HyTrust Node [{0}]...".format(spec.name)) s = requests.session() login_body = json.dumps({ u'username': u'secroot', u'password': spec.secrootpw }) login_headers = {'content-type': 'application/json'} r = s.post("https://{0}/v4/kc/login/".format(spec.ip), data=login_body, headers=login_headers, verify=False) print(r.json()) token = r.json()['access_token'] print("HyTrust Node [{0}] : Access Token: {1}".format( spec.name, token)) # Enable KMIP Server print("Enabling KMIP Server on HyTrust Node [{0}]...".format( spec.name)) kmip_body = json.dumps({ u'cluster': u'ENABLED', u'host': spec.ip, u'loglevel': u'ALL', u'nbio': u'0', u'port': spec.port, u'protocol': u'0x1', u'reconnect': u'0', u'state': u'ENABLED', u'timeout': u'0', 'verify': u'yes' }) kmip_headers = { 'content-type': 'application/json', u'Auth-Token': token } r = s.patch("https://{0}/v4/system_settings/kmipsrv_info/".format( spec.ip), data=kmip_body, headers=kmip_headers, verify=False) print(r.json()) print("HyTrust Node [{0}] : KMIP Server Enabled...".format(spec.name)) # Create a new user to access vSphere (no password) kmip_user = '******' + ''.join( random.choice(string.ascii_uppercase + string.digits) for _ in range(6)) create_user_body = {u'expire': u'365', u'username': kmip_user} create_user_headers = { u'content-type': u'application/x-www-form-urlencoded', u'Auth-Token': token } print("Creating a new KMIP user account: {0}".format(kmip_user)) r = s.post("https://{0}/v4/kmipsrv_user/{1}/".format( spec.ip, kmip_user), data=create_user_body, headers=create_user_headers, verify=False) print("Create User Result: {0}".format(r.json())) # Get the user certificate print( "Download the User and CA Certificates to Memory from Hytrust...") print( "URL :: https://{0}/v4/kmipsrv-certs/{1}/?access_token={2}".format( spec.ip, kmip_user, token)) r = s.get("https://{0}/v4/kmipsrv-certs/{1}/?access_token={2}".format( spec.ip, kmip_user, token), verify=False) certZip = zipfile.ZipFile(io.BytesIO(r.content)) cert_names = {name: certZip.read(name) for name in certZip.namelist()} self.kmip_cert_user = certZip.open( '{0}.pem'.format(kmip_user)).read().decode("utf-8") self.kmip_cert_ca = certZip.open('cacert.pem').read().decode("utf-8") if debug: print("{0}.pem --------------\n{1}".format(kmip_user, self.kmip_cert_user)) print('- - - -') print("cacert.pem --------------\n{0}".format(self.kmip_cert_ca)) return {'token': token, 'session': s} def authorize_secondary_node(self, spec, session_info=None, debug=False): print("DEBUG :: {0}".format(session_info)) print("DEBUG :: https://{0}/v4/domains/?access_token={1}".format( spec.ip, session_info['token'])) # Get a list of the domains (there should only be one) so we can poll the details r = session_info['session'].get( "https://{0}/v4/domains/?access_token={1}".format( spec.ip, session_info['token']), verify=False) domain_list = r.json()['domains'] domain_id = domain_list[0]['id'] if debug: print() print("DEBUG :: Retrieved Domain ID: {0}".format(domain_id)) # Poll until it's joined node2joined = False while not node2joined: if debug: print( "\nDEBUG :: Polling for node-join via: https://{0}/v4/domains/{1}/?access_token={2}" .format(spec.ip, domain_id, session_info['token'])) try: r = session_info['session'].get( "https://{0}/v4/domains/{1}/?access_token={2}".format( spec.ip, domain_id, session_info['token']), verify=False) server_list = r.json()['servers'] except requests.exceptions.ConnectionError as e: # Connection lost, try and reconnect print() print("ERROR :: CONNECTION LOST: \n {0}".format(e)) print("Reconnecting to HyTrust Node [{0}]...".format( spec.name)) session_info['session'] = requests.session() login_body = json.dumps({ u'username': u'secroot', u'password': spec.secrootpw }) login_headers = {'content-type': 'application/json'} r = session_info['session'].post( "https://{0}/v4/kc/login/".format(spec.ip), data=login_body, headers=login_headers, verify=False) print(r.json()) session_info['token'] = r.json()['access_token'] print("HyTrust Node [{0}] : Access Token: {1}".format( spec.name, session_info['token'])) print() continue # Check to see if our second node is in there... if len(server_list) > 1: # If it is, authenticate it authenticate_node_body = { u'operation': u'authenticate', u'passphrase': spec.clusterpw } authenticate_node_headers = { u'content-type': u'application/x-www-form-urlencoded', u'Auth-Token': session_info['token'] } print("Authenticating Node Cluster-join: {0}".format( spec.name)) r = session_info['session'].post( "https://{0}/v4/servers/{1}/operation/".format( spec.ip, server_list[1]['id']), data=authenticate_node_body, headers=authenticate_node_headers, verify=False) print(">>> Node [{0}] authenticated to cluster...".format( spec.name)) print() node2joined = True else: # If not, wait 2 seconds and try again... print("-----> Server count currently: {0}".format( len(server_list))) print("\n >>> Waiting for 5 seconds...") time.sleep(5) def register2vcenter(self, debug=False): # Disable cert verification context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) context.verify_mode = ssl.CERT_NONE # VCenter --------------------------------------------- # Invoke the SmartConnect() method by supplying the host name, user name, and password. service_instance_stub = SmartConnect(host=self.web_svcs_host, user=self.sso_user, pwd=self.sso_pass, port=443, sslContext=context) atexit.register(connect.Disconnect, service_instance_stub) content = service_instance_stub.RetrieveContent() # Add KMS Cluster to vCenter (vSphere API - Web Services SDK) print("Starting to add Key Management Server: {0}".format( self.primary_node_spec.name)) kms_server_info = vim.encryption.KmipServerInfo() kms_server_info.name = self.primary_node_spec.name kms_server_info.address = self.primary_node_spec.ip kms_server_info.port = self.primary_node_spec.port # Set KMS Cluster Name provider_id = vim.encryption.KeyProviderId() provider_id.id = self.kms_cluster_name kmip_spec = vim.encryption.KmipServerSpec() kmip_spec.info = kms_server_info kmip_spec.clusterId = provider_id print("Registering KMS Cluster to vCenter Server...") crypto_manager = service_instance_stub.content.cryptoManager crypto_manager.RegisterKmipServer(kmip_spec) print( "Establishing trust between vCenter Server and the Key Management Server: {0}" .format(self.primary_node_spec.name)) if debug: print("DEBUG :: CA Certificate: \n{0}".format(self.kmip_cert_ca)) print("DEBUG :: User Certificate: \n{0}".format( self.kmip_cert_user)) crypto_manager.UploadClientCert(provider_id, self.kmip_cert_user, self.kmip_cert_user) crypto_manager.UploadKmipServerCert(provider_id, self.kmip_cert_ca) print("Marking [{0}] as default KMIP server...".format( self.primary_node_spec.name)) crypto_manager.MarkDefault(provider_id) print("Verifying KMS registration...")
# login to vAPI endpoint user_password_security_context = create_user_password_security_context( username, password) stub_config.connector.set_security_context(user_password_security_context) # Create the stub for the session service and login by creating a session. session_svc = Session(stub_config) session_id = session_svc.create() # Successful authentication. Store the session identifier in the security # context of the stub and use that for all subsequent remote requests session_security_context = create_session_security_context(session_id) stub_config.connector.set_security_context(session_security_context) # Create Tagging services tag_svc = Tag(stub_config) category_svc = Category(stub_config) tag_association = TagAssociation(stub_config) def get_vm_id(name): """Find vm id by given name using pyVmomi.""" context = None if hasattr(ssl, '_create_unverified_context'): context = ssl._create_unverified_context() si = connect.Connect(host=server, user=username, pwd=password, sslContext=context) content = si.content
class TaggingWorkflow(SampleBase): """ Demonstrates tagging CRUD operations Step 1: Create a Tag category. Step 2: Create a Tag under the category. Step 3: Retrieve the managed object id of an existing cluster from its name. Step 4: Assign the tag to the cluster. Additional steps when clearData flag is set to TRUE: Step 5: Detach the tag from the cluster. Step 6: Delete the tag. Step 7: Delete the tag category. Note: the sample needs an existing cluster """ def __init__(self): SampleBase.__init__(self, self.__doc__) self.servicemanager = None self.category_svc = None self.tag_svc = None self.tag_association = None self.category_name = None self.category_desc = None self.tag_name = None self.tag_desc = None self.cluster_name = None self.cluster_moid = None self.category_id = None self.tag_id = None self.tag_attached = False self.dynamic_id = None def _options(self): self.argparser.add_argument('-clustername', '--clustername', help='Name of the cluster to be tagged') self.argparser.add_argument('-categoryname', '--categoryname', help='Name of the Category to be created') self.argparser.add_argument( '-categorydesc', '--categorydesc', help='Description of the Category to be created') self.argparser.add_argument('-tagname', '--tagname', help='Name of the tag to be created') self.argparser.add_argument( '-tagdesc', '--tagdesc', help='Description of the tag to be created') def _setup(self): if self.cluster_name is None: # for testing self.cluster_name = self.args.clustername assert self.cluster_name is not None print('Cluster Name: {0}'.format(self.cluster_name)) if self.category_name is None: self.category_name = self.args.categoryname assert self.category_name is not None print('Category Name: {0}'.format(self.category_name)) if self.category_desc is None: self.category_desc = self.args.categorydesc assert self.category_desc is not None print('Category Description: {0}'.format(self.category_desc)) if self.tag_name is None: self.tag_name = self.args.tagname assert self.tag_name is not None print('Tag Name: {0}'.format(self.tag_name)) if self.tag_desc is None: self.tag_desc = self.args.tagdesc assert self.tag_desc is not None print('Tag Description: {0}'.format(self.tag_desc)) if self.servicemanager is None: self.servicemanager = self.get_service_manager() self.category_svc = Category(self.servicemanager.stub_config) self.tag_svc = Tag(self.servicemanager.stub_config) self.tag_association = TagAssociation(self.servicemanager.stub_config) def _execute(self): print('List all the existing categories user has access to...') categories = self.category_svc.list() if len(categories) > 0: for category in categories: print('Found Category: {0}'.format(category)) else: print('No Tag Category Found...') print('List all the existing tags user has access to...') tags = self.tag_svc.list() if len(tags) > 0: for tag in tags: print('Found Tag: {0}'.format(tag)) else: print('No Tag Found...') print('creating a new tag category...') self.category_id = self.create_tag_category( self.category_name, self.category_desc, CategoryModel.Cardinality.MULTIPLE) assert self.category_id is not None print('Tag category created; Id: {0}'.format(self.category_id)) print("creating a new Tag...") self.tag_id = self.create_tag(self.tag_name, self.tag_desc, self.category_id) assert self.tag_id is not None print('Tag created; Id: {0}'.format(self.tag_id)) print('updating the tag...') date_time = time.strftime('%d/%m/%Y %H:%M:%S') self.update_tag(self.tag_id, 'Server Tag updated at ' + date_time) print('Tag updated; Id: {0}'.format(self.tag_id)) print('finding the cluster {0}'.format(self.cluster_name)) self.cluster_moid = get_cluster_id(service_manager=self.servicemanager, cluster_name=self.cluster_name) assert self.cluster_moid is not None print('Found cluster:{0} mo_id:{1}'.format('vAPISDKCluster', self.cluster_moid)) print('Tagging the cluster {0}...'.format(self.cluster_name)) self.dynamic_id = DynamicID(type='ClusterComputeResource', id=self.cluster_moid) self.tag_association.attach(tag_id=self.tag_id, object_id=self.dynamic_id) for tag_id in self.tag_association.list_attached_tags(self.dynamic_id): if tag_id == self.tag_id: self.tag_attached = True break assert self.tag_attached print('Tagged cluster: {0}'.format(self.cluster_moid)) def _cleanup(self): try: if self.tag_attached: self.tag_association.detach(self.tag_id, self.dynamic_id) print('Removed tag from cluster: {0}'.format( self.cluster_moid)) if self.tag_id is not None: self.delete_tag(self.tag_id) print('Tag deleted; Id: {0}'.format(self.tag_id)) if self.category_id is not None: self.delete_tag_category(self.category_id) print('Tag category deleted; Id: {0}'.format(self.category_id)) except Exception as e: raise Exception(e) def create_tag_category(self, name, description, cardinality): """create a category. User who invokes this needs create category privilege.""" create_spec = self.category_svc.CreateSpec() create_spec.name = name create_spec.description = description create_spec.cardinality = cardinality associableTypes = set() create_spec.associable_types = associableTypes return self.category_svc.create(create_spec) def delete_tag_category(self, category_id): """Deletes an existing tag category; User who invokes this API needs delete privilege on the tag category. """ self.category_svc.delete(category_id) def create_tag(self, name, description, category_id): """Creates a Tag""" create_spec = self.tag_svc.CreateSpec() create_spec.name = name create_spec.description = description create_spec.category_id = category_id return self.tag_svc.create(create_spec) def update_tag(self, tag_id, description): """Update the description of an existing tag. User who invokes this API needs edit privilege on the tag. """ update_spec = self.tag_svc.UpdateSpec() update_spec.setDescription = description self.tag_svc.update(tag_id, update_spec) def delete_tag(self, tag_id): """Delete an existing tag. User who invokes this API needs delete privilege on the tag.""" self.tag_svc.delete(tag_id)
class VmwareTag(VmwareRestClient): def __init__(self, module): super(VmwareTag, self).__init__(module) self.tag_service = Tag(self.connect) self.global_tags = dict() self.tag_name = self.params.get('tag_name') self.get_all_tags() def ensure_state(self): """ Function to manage internal states of tags """ desired_state = self.params.get('state') states = { 'present': { 'present': self.state_update_tag, 'absent': self.state_create_tag, }, 'absent': { 'present': self.state_delete_tag, 'absent': self.state_unchanged, } } states[desired_state][self.check_tag_status()]() def state_create_tag(self): """ Function to create tag """ tag_spec = self.tag_service.CreateSpec() tag_spec.name = self.tag_name tag_spec.description = self.params.get('tag_description') category_id = self.params.get('category_id', None) if category_id is None: self.module.fail_json(msg="'category_id' is required parameter while creating tag.") tag_spec.category_id = category_id tag_id = self.tag_service.create(tag_spec) if tag_id: self.module.exit_json(changed=True, results=dict(msg="Tag '%s' created." % tag_spec.name, tag_id=tag_id)) self.module.exit_json(changed=False, results=dict(msg="No tag created", tag_id='')) def state_unchanged(self): """ Function to return unchanged state """ self.module.exit_json(changed=False) def state_update_tag(self): """ Function to update tag """ changed = False results = dict(msg="Tag %s is unchanged." % self.tag_name, tag_id=self.global_tags[self.tag_name]['tag_id']) tag_update_spec = self.tag_service.UpdateSpec() tag_desc = self.global_tags[self.tag_name]['tag_description'] desired_tag_desc = self.params.get('tag_description') if tag_desc != desired_tag_desc: tag_update_spec.setDescription = desired_tag_desc results['msg'] = 'Tag %s updated.' % self.tag_name changed = True self.module.exit_json(changed=changed, results=results) def state_delete_tag(self): """ Function to delete tag """ tag_id = self.global_tags[self.tag_name]['tag_id'] self.tag_service.delete(tag_id=tag_id) self.module.exit_json(changed=True, results=dict(msg="Tag '%s' deleted." % self.tag_name, tag_id=tag_id)) def check_tag_status(self): """ Function to check if tag exists or not Returns: 'present' if tag found, else 'absent' """ if self.tag_name in self.global_tags: return 'present' else: return 'absent' def get_all_tags(self): """ Function to retrieve all tag information """ for tag in self.tag_service.list(): tag_obj = self.tag_service.get(tag) self.global_tags[tag_obj.name] = dict(tag_description=tag_obj.description, tag_used_by=tag_obj.used_by, tag_category_id=tag_obj.category_id, tag_id=tag_obj.id )
def _populate_from_source(self, source_data, using_current_cache): """ Populate inventory data from direct source """ if using_current_cache: self._populate_from_cache(source_data) return source_data cacheable_results = {} hostvars = {} objects = self._get_managed_objects_properties( vim_type=vim.VirtualMachine, properties=['name']) if self.with_tags: tag_svc = Tag(self.rest_content) tag_association = TagAssociation(self.rest_content) tags_info = dict() tags = tag_svc.list() for tag in tags: tag_obj = tag_svc.get(tag) tags_info[tag_obj.id] = tag_obj.name if tag_obj.name not in cacheable_results: cacheable_results[tag_obj.name] = {'hosts': []} self.inventory.add_group(tag_obj.name) for temp_vm_object in objects: for temp_vm_object_property in temp_vm_object.propSet: # VMware does not provide a way to uniquely identify VM by its name # i.e. there can be two virtual machines with same name # Appending "_" and VMware UUID to make it unique current_host = temp_vm_object_property.val + "_" + temp_vm_object.obj.config.uuid if current_host not in hostvars: hostvars[current_host] = {} self.inventory.add_host(current_host) host_ip = temp_vm_object.obj.guest.ipAddress if host_ip: self.inventory.set_variable(current_host, 'ansible_host', host_ip) # Load VM properties in host_vars vm_properties = [ 'name', 'config.cpuHotAddEnabled', 'config.cpuHotRemoveEnabled', 'config.instanceUuid', 'config.hardware.numCPU', 'config.template', 'config.name', 'guest.hostName', 'guest.ipAddress', 'guest.guestId', 'guest.guestState', 'runtime.maxMemoryUsage', 'customValue', ] for vm_prop in vm_properties: vm_value = self._get_vm_prop(temp_vm_object.obj, vm_prop.split(".")) self.inventory.set_variable(current_host, vm_prop, vm_value) # Only gather facts related to tag if vCloud and vSphere is installed. if HAS_VCLOUD and HAS_VSPHERE and self.with_tags: # Add virtual machine to appropriate tag group vm_mo_id = temp_vm_object.obj._GetMoId() vm_dynamic_id = DynamicID(type='VirtualMachine', id=vm_mo_id) attached_tags = tag_association.list_attached_tags( vm_dynamic_id) for tag_id in attached_tags: self.inventory.add_child(tags_info[tag_id], current_host) cacheable_results[tags_info[tag_id]][ 'hosts'].append(current_host) # Based on power state of virtual machine vm_power = temp_vm_object.obj.summary.runtime.powerState if vm_power not in cacheable_results: cacheable_results[vm_power] = [] self.inventory.add_group(vm_power) cacheable_results[vm_power].append(current_host) self.inventory.add_child(vm_power, current_host) # Based on guest id vm_guest_id = temp_vm_object.obj.config.guestId if vm_guest_id and vm_guest_id not in cacheable_results: cacheable_results[vm_guest_id] = [] self.inventory.add_group(vm_guest_id) cacheable_results[vm_guest_id].append(current_host) self.inventory.add_child(vm_guest_id, current_host) return cacheable_results
def __init__(self, module): super(VmwareTag, self).__init__(module) self.tag_service = Tag(self.connect) self.tag_association = TagAssociation(self.connect) self.global_tags = dict() self.tag_name = self.params.get('tag_name')
def print_tags(self, stub_config): """Prints available tags for user.""" tag_svc = Tag(stub_config) for t in tag_svc.list(): tag = tag_svc.get(t) print(tag.name)
def __init__(self, module): """Constructor.""" super(VmTagFactManager, self).__init__(module) self.tag_service = Tag(self.connect) self.global_tags = dict()
class TaggingWorkflow(SampleBase): """ Demonstrates tagging CRUD operations Step 1: Create a Tag category. Step 2: Create a Tag under the category. Step 3: Retrieve the managed object id of an existing cluster from its name. Step 4: Assign the tag to the cluster. Additional steps when clearData flag is set to TRUE: Step 5: Detach the tag from the cluster. Step 6: Delete the tag. Step 7: Delete the tag category. Note: the sample needs an existing cluster """ def __init__(self, platformservicecontroller): SampleBase.__init__(self, self.__doc__, platformservicecontroller) self.servicemanager = None self.category_svc = None self.tag_svc = None self.tag_association = None self.category_name = None self.category_desc = None self.tag_name = None self.tag_desc = None self.cluster_name = None self.cluster_moid = None self.category_id = None self.tag_id = None self.tag_attached = False self.dynamic_id = None def _options(self): self.argparser.add_argument('-clustername', '--clustername', help='Name of the cluster to be tagged') self.argparser.add_argument('-categoryname', '--categoryname', help='Name of the Category to be created') self.argparser.add_argument('-categorydesc', '--categorydesc', help='Description of the Category to be created') self.argparser.add_argument('-tagname', '--tagname', help='Name of the tag to be created') self.argparser.add_argument('-tagdesc', '--tagdesc', help='Description of the tag to be created') def _setup(self): if self.cluster_name is None: # for testing self.cluster_name = self.args.clustername assert self.cluster_name is not None logger.info('Cluster Name: {0}'.format(self.cluster_name)) if self.category_name is None: self.category_name = self.args.categoryname assert self.category_name is not None logger.info('Category Name: {0}'.format(self.category_name)) if self.category_desc is None: self.category_desc = self.args.categorydesc assert self.category_desc is not None logger.info('Category Description: {0}'.format(self.category_desc)) if self.tag_name is None: self.tag_name = self.args.tagname assert self.tag_name is not None logger.info('Tag Name: {0}'.format(self.tag_name)) if self.tag_desc is None: self.tag_desc = self.args.tagdesc assert self.tag_desc is not None logger.info('Tag Description: {0}'.format(self.tag_desc)) if self.servicemanager is None: self.servicemanager = self.get_service_manager() self.category_svc = Category(self.servicemanager.stub_config) self.tag_svc = Tag(self.servicemanager.stub_config) self.tag_association = TagAssociation(self.servicemanager.stub_config) def _execute(self): logger.info('List all the existing categories user has access to...') categories = self.category_svc.list() if len(categories) > 0: for category in categories: logger.info('Found Category: {0}'.format(category)) else: logger.info('No Tag Category Found...') logger.info('List all the existing tags user has access to...') tags = self.tag_svc.list() if len(tags) > 0: for tag in tags: logger.info('Found Tag: {0}'.format(tag)) else: logger.info('No Tag Found...') logger.info('creating a new tag category...') self.category_id = self.create_tag_category(self.category_name, self.category_desc, CategoryModel.Cardinality.MULTIPLE) assert self.category_id is not None logger.info('Tag category created; Id: {0}'.format(self.category_id)) logger.info("creating a new Tag...") self.tag_id = self.create_tag(self.tag_name, self.tag_desc, self.category_id) assert self.tag_id is not None logger.info('Tag created; Id: {0}'.format(self.tag_id)) logger.info('updating the tag...') date_time = time.strftime('%d/%m/%Y %H:%M:%S') self.update_tag(self.tag_id, 'Server Tag updated at ' + date_time) logger.info('Tag updated; Id: {0}'.format(self.tag_id)) logger.info('finding the cluster {0}'.format(self.cluster_name)) self.cluster_moid = get_cluster_id(service_manager=self.servicemanager, cluster_name=self.cluster_name) assert self.cluster_moid is not None logger.info('Found cluster:{0} mo_id:{1}'.format('vAPISDKCluster', self.cluster_moid)) logger.info('Tagging the cluster {0}...'.format(self.cluster_name)) self.dynamic_id = DynamicID(type='ClusterComputeResource', id=self.cluster_moid) self.tag_association.attach(tag_id=self.tag_id, object_id=self.dynamic_id) for tag_id in self.tag_association.list_attached_tags(self.dynamic_id): if tag_id == self.tag_id: self.tag_attached = True break assert self.tag_attached logger.info('Tagged cluster: {0}'.format(self.cluster_moid)) def _cleanup(self): try: if self.tag_attached: self.tag_association.detach(self.tag_id, self.dynamic_id) logger.info('Removed tag from cluster: {0}'.format(self.cluster_moid)) if self.tag_id is not None: self.delete_tag(self.tag_id) logger.info('Tag deleted; Id: {0}'.format(self.tag_id)) if self.category_id is not None: self.delete_tag_category(self.category_id) logger.info('Tag category deleted; Id: {0}'.format(self.category_id)) except Exception as e: raise Exception(e) def create_tag_category(self, name, description, cardinality): """create a category. User who invokes this needs create category privilege.""" create_spec = self.category_svc.CreateSpec() create_spec.name = name create_spec.description = description create_spec.cardinality = cardinality associableTypes = set() create_spec.associable_types = associableTypes return self.category_svc.create(create_spec) def delete_tag_category(self, category_id): """Deletes an existing tag category; User who invokes this API needs delete privilege on the tag category. """ self.category_svc.delete(category_id) def create_tag(self, name, description, category_id): """Creates a Tag""" create_spec = self.tag_svc.CreateSpec() create_spec.name = name create_spec.description = description create_spec.category_id = category_id return self.tag_svc.create(create_spec) def update_tag(self, tag_id, description): """Update the description of an existing tag. User who invokes this API needs edit privilege on the tag. """ update_spec = self.tag_svc.UpdateSpec() update_spec.setDescription = description self.tag_svc.update(tag_id, update_spec) def delete_tag(self, tag_id): """Delete an existing tag. User who invokes this API needs delete privilege on the tag.""" self.tag_svc.delete(tag_id)
def __init__(self, module): super(VmwareTag, self).__init__(module) self.tag_service = Tag(self.connect) self.global_tags = dict() self.tag_name = self.params.get('tag_name') self.get_all_tags()
def _populate_from_source(self, source_data, using_current_cache): """ Populate inventory data from direct source """ if using_current_cache: self._populate_from_cache(source_data) return source_data cacheable_results = {'_meta': {'hostvars': {}}} hostvars = {} objects = self.pyv._get_managed_objects_properties(vim_type=vim.VirtualMachine, properties=['name']) if self.pyv.with_tags: tag_svc = Tag(self.pyv.rest_content) tag_association = TagAssociation(self.pyv.rest_content) tags_info = dict() tags = tag_svc.list() for tag in tags: tag_obj = tag_svc.get(tag) tags_info[tag_obj.id] = tag_obj.name if tag_obj.name not in cacheable_results: cacheable_results[tag_obj.name] = {'hosts': []} self.inventory.add_group(tag_obj.name) for vm_obj in objects: for vm_obj_property in vm_obj.propSet: # VMware does not provide a way to uniquely identify VM by its name # i.e. there can be two virtual machines with same name # Appending "_" and VMware UUID to make it unique current_host = vm_obj_property.val + "_" + vm_obj.obj.config.uuid if current_host not in hostvars: hostvars[current_host] = {} self.inventory.add_host(current_host) host_ip = vm_obj.obj.guest.ipAddress if host_ip: self.inventory.set_variable(current_host, 'ansible_host', host_ip) self._populate_host_properties(vm_obj, current_host) # Only gather facts related to tag if vCloud and vSphere is installed. if HAS_VCLOUD and HAS_VSPHERE and self.pyv.with_tags: # Add virtual machine to appropriate tag group vm_mo_id = vm_obj.obj._GetMoId() vm_dynamic_id = DynamicID(type='VirtualMachine', id=vm_mo_id) attached_tags = tag_association.list_attached_tags(vm_dynamic_id) for tag_id in attached_tags: self.inventory.add_child(tags_info[tag_id], current_host) cacheable_results[tags_info[tag_id]]['hosts'].append(current_host) # Based on power state of virtual machine vm_power = str(vm_obj.obj.summary.runtime.powerState) if vm_power not in cacheable_results: cacheable_results[vm_power] = {'hosts': []} self.inventory.add_group(vm_power) cacheable_results[vm_power]['hosts'].append(current_host) self.inventory.add_child(vm_power, current_host) # Based on guest id vm_guest_id = vm_obj.obj.config.guestId if vm_guest_id and vm_guest_id not in cacheable_results: cacheable_results[vm_guest_id] = {'hosts': []} self.inventory.add_group(vm_guest_id) cacheable_results[vm_guest_id]['hosts'].append(current_host) self.inventory.add_child(vm_guest_id, current_host) for host in hostvars: h = self.inventory.get_host(host) cacheable_results['_meta']['hostvars'][h.name] = h.vars return cacheable_results