def read_callback(): """ This function is regularly executed by collectd. It is important to minimize the execution time of the function which is why a lot of caching is performed using the environment objects. """ # Walk through the existing environments for name in ENVIRONMENT.keys(): env = ENVIRONMENT[name] collectd.info("read_callback: entering environment: " + name) context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) context.verify_mode = ssl.CERT_NONE # Connects to vCenter Server try: serviceInstance = SmartConnect(host=env["host"], user=env["username"], pwd=env["password"], sslContext=context) except TypeError: ssl._create_default_https_context = ssl._create_unverified_context serviceInstance = SmartConnect(host=env["host"], user=env["username"], pwd=env["password"]) performanceManager = serviceInstance.RetrieveServiceContent( ).perfManager # Walk through all Clusters of Datacenter for datacenter in serviceInstance.RetrieveServiceContent( ).rootFolder.childEntity: if datacenter._wsdlName == "Datacenter": for cluster in datacenter.hostFolder.childEntity: if cluster._wsdlName == "ClusterComputeResource": # Walk throug all hosts in cluster, collect its metrics and dispatch them collectd.info( "read_callback: found %d hosts in cluster %s" % (len(cluster.host), cluster.name)) colletMetricsForEntities(performanceManager, env['host_counter_ids'], cluster.host, cluster._moId) # Walk throug all vms in host, collect its metrics and dispatch them for host in cluster.host: if host._wsdlName == "HostSystem": collectd.info( "read_callback: found %d vms in host %s" % (len(host.vm), host.name)) colletMetricsForEntities( performanceManager, env['vm_counter_ids'], host.vm, cluster._moId)
def upgrade_vCenter_plugin( self, vc_ip, usernName, password, port, vcp_url, thumb_print): try: try: ssl._create_default_https_context = ssl._create_unverified_context except AttributeError: print 'Error ssl' context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context.verify_mode = ssl.CERT_NONE si = SmartConnect("https", vc_ip, int(port), usernName, password, sslContext=context) ext = self.get_extension(vcp_url, thumb_print) if isinstance(ext, vim.Extension): si.RetrieveServiceContent().extensionManager.UpdateExtension(ext) return True else: return ext except vim.fault.NoPermission as ex: return 'vCenter user has no permission to upgrade the plugin.' except Exception as ex: return str(ex).replace("'", "").replace("<", "").replace(">", "")
def find_plugin(self, vc_ip, usernName, password, port): try: try: ssl._create_default_https_context = ssl._create_unverified_context except AttributeError: print('Error ssl') context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context.verify_mode = ssl.CERT_NONE si = SmartConnect("https", vc_ip, int(port), usernName, password, sslContext=context) extkey = self.get_extensionKey() ext = si.RetrieveServiceContent().extensionManager.FindExtension( extkey) if ext is None: return False else: try: return 'TruNAS System : ' + ext.client[0].url.split('/')[2] except: return 'TruNAS System :' except vim.fault.NoPermission as ex: return 'vCenter user does not have permission to perform this operation.' except Exception as ex: return str(ex).replace("'", "").replace("<", "").replace(">", "")
def main(): global content global si context = None if sys.version_info[:3] > (2, 7, 8): context = ssl.create_default_context() context.check_hostname = False context.verify_mode = ssl.CERT_NONE args = GetArgs() if args.password: password = args.password else: password = getpass.getpass(prompt='Enter password for host %s and user %s: ' % (args.vc, args.user)) try: # connection string # connection string # si = connect.SmartConnectNoSSL(host=args.vc, # user=args.user, # pwd=password, # sslContext=context) si = SmartConnect(host=args.vc, user=args.user, pwd=password, sslContext=context) content = si.RetrieveServiceContent() # we close the vc connection atexit.register(Disconnect, si) print(content) # we close the vc connection cluster = si.content.rootFolder.childEntity[0].hostFolder.childEntity[0] print(cluster) # returns the moref for the cluster vcMos = vsanapiutils.GetVsanVcMos(si._stub, context=context) vccs = vcMos['vsan-cluster-config-system'] vsanCluster = vccs.VsanClusterGetConfig(cluster=cluster) print(vsanCluster) except Exception as err: print('Error in main(): ', err)
def uninstall_vCenter_plugin(self, vc_ip, usernName, password, port): try: try: ssl._create_default_https_context = ssl._create_unverified_context except AttributeError: print 'Error ssl' si = SmartConnect("https", vc_ip, int(port), usernName, password) extkey = self.get_extensionKey() si.RetrieveServiceContent().extensionManager.UnregisterExtension( extkey) return True except vim.fault.NoPermission as ex: return 'vCenter user has no permission to uninstall the plugin.' except Exception as ex: return str(ex).replace("'", "").replace("<", "").replace(">", "")
def setupManagedObject(): global config, host, user, password, si, ssl_context global content, perfManager, viewManager, propertyCollector, searchIndex, container # monitor.ini file로부터 설정 정보를 읽어 옴 readConfig() # vCenter 연결정보 section = 'vCenter' host = config[section]['host'] user = config[section]['user'] password = config[section]['password'] ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) ssl_context.verify_mode = ssl.CERT_NONE try: si = SmartConnect(host=host, user=user, pwd=password, sslContext=ssl_context) atexit.register(Disconnect, si) except IOError as e: pass if not si: raise SystemExit("unable to connect to host.") content = si.RetrieveServiceContent() # get PerformanceManager, ViewManager & PropertyCollector perfManager = content.perfManager viewManager = content.viewManager propertyCollector = content.propertyCollector searchIndex = content.searchIndex container = content.rootFolder # starting point for query
def create_environment(config): """ Creates a runtime environment from a given configuration block. As the structure of an environment is a bit complicates, this is the time to document it: A single environment is a dictionary that stores runtime information about the connection, metrics, etc for a single vCenter Server. This is the structure pattern: { 'host': <FQDN OR IP ADDRESS OF VCENTER SERVER>, 'username': <USER FOR LOGIN IN VCENTER SERVER>, 'password': <PASSWORD FOR LOGIN IN VCENTER SERVER>, # This is a dictionary that stores mappings of performance counter # names to their respective IDs in vCenter. 'lookup_host': { 'NAME': <ID>, # Example: 'cpu.usage': 2 ... }, # The same lookup dictionary must be available for virtual machines: 'lookup_vm': { 'NAME': <ID>, ... }, # This stores the IDs of the counter names passed via the # configuration block. We used the lookup tables above to fill in # the IDs. 'host_counter_ids': [<ID>, <ID>, ...], 'vm_counter_ids': [<ID>, <ID>, ...], } """ if not config.get('verify_cert'): ssl._create_default_https_context = ssl._create_unverified_context # Connect to vCenter Server service_instance = SmartConnect(host=config.get("host"), user=config.get("username"), pwd=config.get("password")) # If we could not connect abort here if not service_instance: print("Could not connect to the specified host using specified " "username and password") return -1 # Set up the environment. We fill in the rest afterwards. env = {} env["host"] = config.get("host") env["username"] = config.get("username") env["password"] = config.get("password") env['use_friendly_name'] = config.get('use_friendly_name') performance_manager = service_instance.RetrieveServiceContent().perfManager # We need at least one host and one virtual machine, which are poweredOn, in # the vCenter to be able to fetch the Counter IDs and establish the lookup # table. # Fetch the Counter IDs filtered_counter_ids = [] ids_counters_dict = {} for perf_counter in performance_manager.perfCounter: counter_key = \ perf_counter.groupInfo.key + "." + perf_counter.nameInfo.key ids_counters_dict[perf_counter.key] = counter_key host = None virtual_machine = None for child in service_instance \ .RetrieveServiceContent() \ .rootFolder.childEntity: if child._wsdlName == "Datacenter": for host_folder_child in convert_folder_tree_to_list( child.hostFolder.childEntity): host = host_folder_child.host[0] if ( (len(host_folder_child.host) != 0) and host_folder_child.host[0].summary.runtime.powerState == vim.HostSystem.PowerState.poweredOn) else host if virtual_machine is not None and host is None: break vm_list = child.vmFolder.childEntity for tmp in vm_list: if tmp._wsdlName == "VirtualMachine": if tmp.summary.runtime.powerState == \ vim.VirtualMachine.PowerState.poweredOn: virtual_machine = tmp if virtual_machine is not None and host is not None: break elif tmp._wsdlName == "Folder": vm_list += tmp.childEntity elif tmp._wsdlName == "VirtualApp": vm_list += tmp.vm if host is None: collectd.info("create_environment: vCenter " + config.get("name") + " does not contain any hosts. Cannot continue") return if virtual_machine is None: collectd.info("create_environment: vCenter " + config.get("name") + " does not contain any VMs. Cannot continue") return # Get all queryable aggregated and realtime metrics for an entity env['lookup_host'] = [] env['lookup_vm'] = [] if len(performance_manager.historicalInterval) is not 0: performance_interval = performance_manager.historicalInterval[0] samplingPeriod = performance_interval.samplingPeriod performance_interval.level = 2 # Update performance interval to get all rolluptypes performance_manager.UpdatePerfInterval(performance_interval) else: samplingPeriod = None # Query aggregated qureyable mertics for host and virtual_machine env['lookup_host'] += performance_manager.QueryAvailablePerfMetric( host, None, None, samplingPeriod) env['lookup_vm'] += performance_manager.QueryAvailablePerfMetric( virtual_machine, None, None, samplingPeriod) # Query aggregated realtime mertics for host and virtual_machine env['lookup_host'] += performance_manager.QueryAvailablePerfMetric( host, None, None, 20) env['lookup_vm'] += performance_manager.QueryAvailablePerfMetric( virtual_machine, None, None, 20) # Now use the lookup tables to find out the IDs of the counter names given # via the configuration and store them as an array in the environment. # If host_counters or vm_counters is empty, select all. env['host_counter_ids'] = [] if config['host_counters'] == "all": collectd.info( "create_environment: configured to grab all host counters") env['host_counter_ids'] = env['lookup_host'] else: for metric in env['lookup_host']: if ids_counters_dict[metric.counterId] in config['host_counters']: env['host_counter_ids'].append(metric) collectd.info("create_environment: configured to grab %d host counters" % (len(env['host_counter_ids']))) env['vm_counter_ids'] = [] if config['vm_counters'] == "all": env['vm_counter_ids'] = env['lookup_vm'] else: for metric in env['lookup_vm']: if ids_counters_dict[metric.counterId] in config['vm_counters']: env['vm_counter_ids'].append(metric) collectd.info( "create_environment: configured to grab %d virtual_machine counters" % (len(env['vm_counter_ids']))) Disconnect(service_instance) return env
class VcenterConnector(): """ vCenter connector class that gives service instance after connected successfully.By default it uses https connections. """ instance = [] def __init__(self, vcenter_object=None, **kwargs): """ Initiate vCenter connection object and service instance. service instance is a pointer of vcenter where User can iterate various data objects and apply appropriate methods to those objects. Args: :vcenter_object (object): vcenter object from YAML. or :username (str): vcenter username :ip (str): vcenter ip :password (str): vcenter password raises: :method_fault (fault): pyvmomi method fault. """ self.default_ssl_port = 443 if not vcenter_object: self.user = kwargs.get('username', None) self.vcenter_ip = kwargs.get('ip', None) self.vcenter_password = kwargs.get('password', None) else: self.user_object = vcenter_object.get_user() self.user = self.user_object.get("name") self.vcenter_ip = vcenter_object.get_mgmt_ip() self.vcenter_password = self.user_object.get("password") self._get_connection() def _get_connection(self): try: ssl._create_default_https_context = ssl._create_unverified_context context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context.verify_mode = ssl.CERT_NONE self._serviceInstance = SmartConnect(host=self.vcenter_ip, user=self.user, pwd=self.vcenter_password, port=self.default_ssl_port, sslContext=context) except vmodl.MethodFault as error: logger.error("Exception Raise : {}".format(error.msg)) try: atexit.register(Disconnect, self._serviceInstance) except AttributeError: raise VcenterObjectNotCreated finally: ssl._create_default_https_context = default_context def _wait_for_tasks(self, tasks, task_name=""): """ This method is used by inherited objects from this class as well as class objects itself_wait_for_task is yield till any operational task is complete.It checks given task is completed successfully or failed. It dose not return any value. Args: :task (list):list of tasks passed by inherited objects. Kwargs: :task_name (str):name of task passed by inherited objects.example, "vm poweron", "vm poweroff","vmotion vm" Raise: Task info error on task failure. """ # tasks = tasks self._test_connection() collection = self._serviceInstance.content.propertyCollector task_list = [str(task) for task in tasks] object_specification = [vmodl.query.PropertyCollector. ObjectSpec(obj=task) for task in tasks] task_pro_spec = vmodl.query.PropertyCollector.\ PropertySpec(type=vim.Task, pathSet=[], all=True) filter_spec = vmodl.query.PropertyCollector.FilterSpec() filter_spec.objectSet = object_specification filter_spec.propSet = [task_pro_spec] pcfilter = collection.CreateFilter(filter_spec, True) try: version, state = None, None while len(task_list): update = collection.WaitForUpdates(version) for filter_set in update.filterSet: for obj_set in filter_set.objectSet: task = obj_set.obj for change in obj_set.changeSet: if change.name == 'info': state = change.val.state elif change.name == 'info.state': state = change.val else: continue if not str(task) in task_list: continue if state == vim.TaskInfo.State.success: logger.info( "{} task completed successfully". format(task_name)) task_list.remove(str(task)) elif state == vim.TaskInfo.State.error: logger.info( "{} task was failed".format(task_name)) raise task.info.error version = update.version finally: if pcfilter: pcfilter.Destroy() def _get_content(self, type=None): """ This method is used by inherited objects of this class to get various vcenter managed object/objects.It returns a list that has a container of object/objects. Most of them are iterative and user can get data and apply appropriate method written https://github.com/vmware/pyvmomi that mapped to vcenter API. Args: :type (str): "host": for getting esxi host (vim.HostSystem) managed object from vcenter level. "vm" : for getting virtual machine (vim.VirtualMachine) managed object from vcenter level. "network":for getting network (vim.Network) managed object from vcenter level. "dvs" : for getting DVS switch object. "dvsportgroup": not implemented yet. "datastore":for getting datastore(vim.Datastore) managed object from vcenter level. "folder": for getting folder level object. Return: :list (list) : a list of objects represents managed objects by vcenter.(based on passed type value). """ self._test_connection() self.content = self._serviceInstance.RetrieveServiceContent() try: self.content.rootFolder.childEntity except vmodl.fault.MethodNotFound: self._get_connection() if type is not None: type = type.lower() if type == "host": self.host_view = self.content.viewManager. \ CreateContainerView(self.content.rootFolder, [ vim.HostSystem], True) self.host_obj_list = [host for host in self.host_view.view] self.host_view.Destroy() return self.host_obj_list elif type == "vm": self.vm_view = self.content.viewManager. \ CreateContainerView(self.content.rootFolder, [ vim.VirtualMachine], True) self.vm_obj_list = [vm for vm in self.vm_view.view] self.vm_view.Destroy() return self.vm_obj_list elif type == "network": self.network_view = self.content.viewManager. \ CreateContainerView(self.content.rootFolder, [ vim.Network], True) self.net_obj_list = [net for net in self.network_view.view] self.network_view.Destroy() return self.net_obj_list elif type == "cluster": self.cluster_view = self.content.viewManager. \ CreateContainerView( self.content.rootFolder,[vim.ClusterComputeResource], True) self.cluster_obj = self.cluster_view.view self.cluster_view.Destroy() return self.cluster_obj elif type == "dvs": self.dvs_view = self.content.viewManager. \ CreateContainerView(self.content.rootFolder, [ vim.dvs.DistributedVirtualPortgroup], True) self.dvs_obj_list = [dvs for dvs in self.dvs_view.view] self.dvs_view.Destroy() return self.dvs_obj_list elif type == "dvs_5": self.dvs_view = self.content.viewManager.\ CreateContainerView(self.content.rootFolder, [ vim.dvs.VmwareDistributedVirtualSwitch], True) self.dvs_obj_list = [dvs for dvs in self.dvs_view.view] self.dvs_view.Destroy() return self.dvs_obj_list elif type == "dvsportgroup": self.dvs_portgroup_view = self.content.viewManager.\ CreateContainerView(self.content.rootFolder, [ vim.dvs.DistributedVirtualPortgroup], True) self.dvs_portgroup_list = [dvs_portgroup for dvs_portgroup in self.dvs_portgroup_view.view] self.dvs_portgroup_view.Destroy() return self.dvs_portgroup_list elif type == "datastore": self.datastore_view = self.content.viewManager. \ CreateContainerView(self.content.rootFolder, [ vim.Datastore], True) self.datastore_obj_list = [ds for ds in self.datastore_view] self.datastore_view.Destroy() return self.datastore_obj_list elif type == "folder": self.folder_view = self.content.viewManager. \ CreateContainerView( self.content.rootFolder, [vim.Folder], True) self.folder_obj = self.folder_view.view self.folder_view.Destroy() return self.folder_obj elif type == "content": return self.content else: self.all_mob_view = self.content.viewManager.CreateContainerView( self.content.rootFolder, [vim.Network, vim.HostSystem, vim.VirtualMachine, vim.ResourcePool, vim.VirtualApp, vim.DistributedVirtualSwitch, vim.DistributedVirtualPortgroup, vim.Datastore, vim.ComputeResource], True) self.all_obj_list = [x.name for x in self.all_mob_view.view] return self.all_obj_list def _test_connection(self): content = self._serviceInstance.RetrieveServiceContent() try: content.rootFolder.childEntity except (vmodl.fault.MethodNotFound, HTTPException): self._get_connection()
def main(): supportedArgs = [ (["h:", "host="], "localhost", "Host name", "host"), (["u:", "user="******"root", "User name", "user"), (["p:", "pwd="], "ca$hc0w", "Password", "pwd"), (["d:", "domain="], "tesla.kozaboza.com", "AD domain", "domain"), (["x:", "aduser="******"administrator", "AD username", "aduser"), (["y:", "adpass="******"ca$hc0w", "Password for the AD user", "adpass"), (["z:", "adname="], "tesla", "AD domain name", "adname"), (["P:", "P="], "10.23.33.251", "IP of the domain controller", "ip"), (["i:", "numiter="], "1", "Number of iterations", "iter") ] supportedToggles = [(["usage", "help"], False, "Show usage information", "usage")] args = arguments.Arguments(sys.argv, supportedArgs, supportedToggles) if args.GetKeyValue("usage") == True: args.Usage() sys.exit(0) # Connect si = SmartConnect(host=args.GetKeyValue("host"), user=args.GetKeyValue("user"), pwd=args.GetKeyValue("pwd")) atexit.register(Disconnect, si) global status status = "PASS" # Set primary dns try: host = GetHostSystem(si) networkSystem = host.GetConfigManager().GetNetworkSystem() dnsConfig = networkSystem.dnsConfig ipAddress = args.GetKeyValue("ip") dnsAddress = dnsConfig.address if len(dnsAddress) > 0: dnsConfig.address[0] = ipAddress else: dnsConfig.address.append(ipAddress) networkSystem.UpdateDnsConfig(dnsConfig) except Exception as e: print("Can't change the primary dns of the host...") print("Caught exception: " + str(e)) status = "FAIL" return # Process command line numiter = int(args.GetKeyValue("iter")) for i in range(numiter): try: host = GetHostSystem(si) authMan = host.GetConfigManager().GetAuthenticationManager() stores = authMan.GetSupportedStore() ad = None for i in stores: if isinstance(i, Vim.Host.ActiveDirectoryAuthentication): ad = i if ad == None: print("Can't find the ActiveDirectoryAuthenticationManager...") status = "FAIL" return # # try to join the domain with invalid credentials, should fail # try: task = ad.JoinDomain(args.GetKeyValue("domain"), "qwerty", "uiop") WaitForTask(task) print("Joined a domain with wrong credentials...") status = "FAIL" return except Exception: pass # # try to join the domain with the supplied credentials, should succeed # try: task = ad.JoinDomain(args.GetKeyValue("domain"), args.GetKeyValue("aduser"), args.GetKeyValue("adpass")) WaitForTask(task) except Exception as e: print("Can't join the domain...") raise # # try to join the domain again, should fail # try: task = ad.JoinDomain(args.GetKeyValue("domain"), args.GetKeyValue("aduser"), args.GetKeyValue("adpass")) WaitForTask(task) print("Rejoining the domain should have failed...") status = "FAIL" return except Exception: pass # # try to lookup aduser in the user dir, there should be at least one match. # don't use exact match because it won't go through ldap, but through getpwnam_r. # ud = si.RetrieveServiceContent().GetUserDirectory() searchResults = \ ud.RetrieveUserGroups(args.GetKeyValue("domain"), # domain userGroup, None, # belongsToGroup None, # belongsToUser False, # exactMatch True, # findUsers True) # findGroups if len(searchResults) < 1: print("User search failed...") status = "FAIL" return # # give userGroup read only permissions # permission = Vim.AuthorizationManager.Permission() permission.group = True permission.principal = args.GetKeyValue( "adname") + "\\" + userGroup permission.propagate = True permission.roleId = -2 # ROLE_READONLY_ID permissionArr = [permission] am = si.RetrieveServiceContent().GetAuthorizationManager() rf = si.RetrieveServiceContent().GetRootFolder() am.SetEntityPermissions(rf, permissionArr) # # try to leave the domain with force=false, should fail # try: task = ad.LeaveCurrentDomain(False) WaitForTask(task) print("Leaving the domain should have failed...") status = "FAIL" return except Exception: pass # # try to leave the domain with force=true, should succeed # try: task = ad.LeaveCurrentDomain(True) WaitForTask(task) except Exception: print("Can't leave the domain...") raise except Exception as e: print("Caught exception : " + str(e)) status = "FAIL"