def refresh(self, name): """Refresh. :: Refresh an existing provider in manageiq. :param name: provider name :return: request id """ _api = getattr(self, 'api') # quit if provider given does not exists in manageiq if not self._provider_exist(name, _api): log.abort('Unable to process request to refresh provider: %s. ' 'The provider does not exist in manageiq.' % name) # get the provider id query = BasicQuery(getattr(_api.client.collections, 'providers')) query(('name', '=', name)) # okay good to go, lets create the payload # RFE: multiple resources? this only gives first index in list _payload = dict(id=query.resources.pop()['id']) log.debug('Payload:\n %s' % pformat(_payload)) try: self.req_id = getattr(self, 'action')(_payload) log.info('Successfully submitted request to refresh provider: %s.' '\nRequest ID: %s.' % (name, self.req_id)) return self.req_id except APIException as ex: log.abort('Request to refresh provider: %s failed!\n Error: %s' % (name, ex))
def delete(self, name): """Delete. :: Delete an existing provider in manageiq. :param name: provider name :return: request id """ _api = getattr(self, 'api') if not self._provider_exist(name, _api): log.abort('Unable to process request to delete provider: %s. ' 'The provider does not exist.' % name) # get the provider id query = BasicQuery(getattr(_api.client.collections, 'providers')) query(('name', '=', name)) # okay good to go, lets create the payload _payload = dict(id=query.resources.pop()['id']) log.debug('Payload:\n %s' % pformat(_payload)) try: self.req_id = getattr(self, 'action')(_payload) log.info('Successfully submitted request to delete provider: %s.\n' 'Request ID: %s.' % (name, self.req_id)) return self.req_id except APIException as ex: log.abort('Request to delete provider: %s failed!\n Error: %s' % (name, ex))
def status(self, req_id): """Print the status for a automation request. :: Handles getting information for an existing automation request and displaying/returning back to the user. :param req_id: id of the automation request :type req_id: str :return: automation request object or list of automation request objects """ status = OrderedDict() query = BasicQuery(self.collection) if req_id: automation_requests = query(("id", "=", req_id)) if len(automation_requests) < 1: log.warning('Automation request id: %s not found!' % req_id) return req = automation_requests[0] status['state'] = req.request_state status['status'] = req.status status['message'] = req.message log.info('-' * 50) log.info('Automation request'.center(50)) log.info('-' * 50) log.info(' * ID: %s' % req_id) for key, value in status.items(): log.info(' * %s: %s' % (key.upper(), value)) # if verbosity is set, get more info about the request log.debug('\n' + pformat(req.options, indent=4)) log.info('-' * 50) return req else: automation_requests = query(("request_state", "!=", "finished")) if len(automation_requests) < 1: log.warning('No active automation requests at this time.') return None log.info('-' * 50) log.info(' Active automation requests'.center(50)) log.info('-' * 50) for item in automation_requests: log.info( ' * ID: %s\tINSTANCE: %s\t STATE: %s\t STATUS: %s' % (item.id, item.options, item.request_state, item.status)) log.info('-' * 50) return automation_requests
def _provider_exist(name, api): """Determine whether the provider exists. :param name: provider name :param api: client api pointer """ provider = Provider(name, api) if provider.cloud_type: log.debug('Provider: %s exists in manageiq.' % name) found = True else: log.debug('Provider: %s does not exist in manageiq.' % name) found = False return found
def get_entity(self, ent_id, attributes): """Get the element based on the id given. :param ent_id: resource id :type ent_id: int :param attributes: List of attributes :type attributes: Comma seperated string :return: element or none :rtype: dict """ output = None try: output = self.collection.__call__(ent_id, attributes) except APIException as e: log.debug('Get entity failed: ID({0}): {1} error: {2}'.format( self.__collection_name__, ent_id, e)) return output
def from_yml(self, directory, filename): """Load configuration settings from yml file. :param directory: directory to scan for config file :type directory: str :param filename: config filename :type filename: str """ _cfg_file = None # verify directory is defined if not os.path.isdir(directory): if self._verbose: log.warning('Directory {0} is undefined.'.format(directory)) return # verify config file exists for entry in os.listdir(directory): _file = os.path.splitext(entry) if _file[0] == filename and _file[1] in CFG_FILE_EXT: _cfg_file = os.path.join(directory, entry) break if _cfg_file is None and self._verbose: log.warning('Config file at {0} is undefined.'.format(directory)) return if _cfg_file is None: return # load config try: with open(_cfg_file, mode='rb') as fp: config_data = yaml.load(fp) if isinstance(config_data, str): log.abort('Config file {0} formatted incorrectly.'.format( _cfg_file)) elif config_data is None: log.warning('Config file {0} is empty.'.format(_cfg_file)) else: for key, value in config_data.items(): self[key] = value except yaml.YAMLError as e: if self._verbose: log.debug('Standard error: {0}'.format(e)) log.abort('Error in config {0}.'.format(_cfg_file))
def create(self, name, hostname=None, port=None, region=None, zone=None, username=None, password=None): """Create. :: Create a new provider in manageiq. :param name: provider name :param hostname: provider server hostname :param port: provider port :param region: provider region :param zone: manageiq zone :param username: provider username :param password: provider password :return: request id """ _api = getattr(self, 'api') if self._provider_exist(name, _api): log.abort('Unable to process request to create provider: %s. ' 'The provider already exists.' % name) log.info('Create provider: %s.' % name) # okay good to go, lets create the payload _payload = dict( name=name, type=ProviderTypes().get(name), provider_region=region, hostname=hostname, port=port, zone=zone, credentials=[ dict( userid=username, password=password ) ] ) # zone requires href destination over string type if zone: query = BasicQuery(getattr(_api.client.collections, 'zones')) query(('name', '=', zone)) if query.resources: # RFE: remove using static position in list _payload.update(dict(zone=dict( href=getattr(query.resources[0], '_href').replace( 'zones', 'zone')))) log.debug('Payload:\n %s' % pformat(_payload)) try: self.req_id = getattr(self, 'action')(_payload) log.info('Successfully submitted request to create provider: %s.' % name) log.info('Create provider request ID: %s.' % self.req_id) return self.req_id except APIException as ex: log.abort('Request to create provider: %s failed!\n Error: %s' % (name, ex))
def query(self, vm_name, provider=None, vendor=None, vtype=None, attr=None, by_id=False): """Query vms. :: Allows querying vms based on name, provider and attributes :param vm_name: name of the vm :type vm_name: str :param provider: name of provider :type provider: str :param vendor: name of vendor :type vendor: str :param vtype: type of vm - "Openstack" or "Amazon" :type vtype: str :param attr: attribute :type attr: tuple :param by_id: name is vm id :type by_id: bool :return: vm object or list of vm objects """ vms = None # Query by ID if by_id: # ID given in name if vm_name: # query based on vm name as ID # all other options ignored except attr qs_by_id = ("id", "=", vm_name) query = BasicQuery(self.collection) vms = query(qs_by_id, attr) if len(vms) < 1: log.abort('Cannot find Vm with ID:%s in %s' % (vm_name, self.collection.name)) # Error no ID given else: log.abort('No Vm ID given') # Query by name and other options else: # Build query string qstr = [] if vm_name: qstr.append(("name", "=", vm_name)) if provider: qstr.append(("ext_management_system.name", "=", provider)) if vendor: qstr.append(("vendor", "=", vendor.lower())) if vtype: type_str = "ManageIQ::Providers::%s::CloudManager::Vm" % vtype qstr.append(("type", "=", type_str)) # Concat together and'ing statements qs = inject(qstr, "&") # query based on vm name and other options if len(qs) > 0: if len(qs) == 1: # Name only query = BasicQuery(self.collection) vms = query(qs[0], attr) else: # Mix of various options and name query = AdvancedQuery(self.collection) vms = query(qs, attr) if len(vms) < 1: log.abort('No Vm(s) found for given parameters') # general query on all vms else: # return vms that have the attribute passed set if attr: # scrub attr of base attributes opt_lists = self.collection.options() att_list = list(attr) for att in att_list: if att in opt_lists['attributes']: att_list.remove(att) clean_attr = tuple(att_list) vms = self.collection.all_include_attributes(clean_attr) # attribute not set, pass back all vms w/basic info else: vms = self.collection.all if vms: log.info('-' * 50) log.info('Vm Info'.center(50)) log.info('-' * 50) debug = click.get_current_context().find_root().params['verbose'] for e in vms: log.info(' * ID: %s' % e['id']) log.info(' * NAME: %s' % e['name']) if debug: for k, v in e['_data'].items(): if k == "id" or k == "name" or k in attr: continue try: log.debug(' * %s: %s' % (k.upper(), v)) except AttributeError: log.debug(' * %s: ' % k.upper()) if attr: for a in attr: try: log.info(' * %s: %s' % (a.upper(), e[a])) except AttributeError: log.info(' * %s: ' % a.upper()) log.info('-' * 50) if len(vms) == 1: return vms[0] else: return vms else: log.abort('No vm(s) found for given parameters')
def create(self, provider, payload, payload_file): """Create a provision request. :: Builds the payload data for the request (performing all necessary id lookups) and then submits the provision request to the server. :param provider: cloud provider to fulfill provision request into :type provider: str :param payload: json data in str format :type payload: str :param payload_file: file location of the payload :type payload_file: str :return: provision request ID :rtype: str """ # RFE: make generic as possible, remove conditional per provider if provider == "OpenStack": log.info("Attempt to create a provision request") # get the data from user input input_data = get_input_data(payload, payload_file) # verify all the required keys are set missing_data = [] for key in REQUIRED_OSP_KEYS: if key not in input_data or input_data[key] is None: missing_data.append(key) if missing_data: log.abort("Required key(s) missing: {0}, please set it in " "the payload".format(missing_data)) # Verified data is valid, update payload w/id lookups # set the email_address and vm name OSP_PAYLOAD["requester"]["owner_email"] = input_data["email"] OSP_PAYLOAD["vm_fields"]["vm_name"] = input_data["vm_name"] # lookup cloud tenant resource to get the id tenant = Tenant(provider, self.api) OSP_PAYLOAD['vm_fields']['cloud_tenant'] = tenant.get_id( input_data['tenant'] ) tenant_id = OSP_PAYLOAD['vm_fields']['cloud_tenant'] if 'floating_ip_id' in input_data: OSP_PAYLOAD['vm_fields']['floating_ip_address'] = \ input_data['floating_ip_id'] # lookup flavor resource to get the id flavors = Flavors(provider, self.api) OSP_PAYLOAD['vm_fields']['instance_type'] = flavors.get_id( input_data['flavor']) # lookup image resource to get the id templates = Templates(provider, self.api) OSP_PAYLOAD['template_fields']['guid'] = templates.get_id( input_data['image'] ) if 'security_group' in input_data and input_data['security_group']: # lookup security group resource to get the id sec_group = SecurityGroups(provider, self.api) OSP_PAYLOAD['vm_fields']['security_groups'] = sec_group.get_id( input_data['security_group'], tenant_id ) if 'key_pair' in input_data and input_data["key_pair"]: # lookup key pair resource to get the id key_pair = KeyPair(provider, self.api) OSP_PAYLOAD['vm_fields']['guest_access_key_pair'] = \ key_pair.get_id(input_data['key_pair']) # lookup cloud network resource to get the id network = Networks(provider, self.api, 'private') OSP_PAYLOAD['vm_fields']['cloud_network'] = network.get_id( input_data['network'], tenant_id ) log.debug("Payload for the provisioning request: {0}".format( pformat(OSP_PAYLOAD))) self.req_id = self.action(OSP_PAYLOAD) log.info("Provisioning request created: {0}".format(self.req_id)) return self.req_id # RFE: make generic as possible, remove conditional per provider if provider == "Amazon": log.info("Attempt to create a provision request") # get the data from user input input_data = get_input_data(payload, payload_file) # Set Required fields if 'auto_placement' in input_data and input_data['auto_placement']: REQUIRED_AWS_KEYS = REQUIRED_AWS_AUTO_PLACEMENT_KEYS else: REQUIRED_AWS_KEYS = REQUIRED_AWS_PLACEMENT_KEYS # verify all the required keys are set missing_data = [] for key in REQUIRED_AWS_KEYS: if key not in input_data or input_data[key] is None: missing_data.append(key) if missing_data: log.abort("Required key(s) missing: {0}, please set it in " "the payload".format(missing_data)) # Verified data is valid, update payload w/id lookups # set the email_address and vm name AWS_PAYLOAD["requester"]["owner_email"] = input_data["email"] AWS_PAYLOAD["vm_fields"]["vm_name"] = input_data["vm_name"] # lookup flavor resource to get the id flavors = Flavors(provider, self.api) AWS_PAYLOAD['vm_fields']['instance_type'] = flavors.get_id( input_data['flavor']) # lookup image resource to get the id templates = Templates(provider, self.api) AWS_PAYLOAD['template_fields']['guid'] = templates.get_id( input_data['image'] ) # lookup security group resource to get the id if 'security_group' in input_data and input_data['security_group']: sec_group = SecurityGroups(provider, self.api) AWS_PAYLOAD['vm_fields']['security_groups'] = \ sec_group.get_id(input_data['security_group']) # lookup key pair resource to get the id key_pair = KeyPair(provider, self.api) AWS_PAYLOAD['vm_fields']['guest_access_key_pair'] = \ key_pair.get_id(input_data['key_pair']) # lookup cloud network resource to get the id if 'network' in input_data and input_data['network']: network = Networks(provider, self.api) AWS_PAYLOAD['vm_fields']['cloud_network'] = network.get_id( input_data['network'] ) # lookup cloud_subnets attribute from cloud network entity # to get the id if 'subnet' in input_data and input_data['subnet']: out = network.get_attribute( AWS_PAYLOAD['vm_fields']['cloud_network'], 'cloud_subnets') # Get id for supplied Subnet subnet_id = None if isinstance(out, list): for att in out: if 'name' in att and att['name'] == \ input_data['subnet']: subnet_id = att['id'] elif isinstance(out, dict): if out and 'name' in out and out['name'] == \ input_data['subnet']: subnet_id = out['id'] if subnet_id is None: log.abort('Cannot obtain Cloud Subnet: {0} info, please ' 'check setting in the payload ' 'is correct'.format(input_data['subnet'])) log.info('Attribute: {0}'.format(out)) AWS_PAYLOAD['vm_fields']['cloud_subnet'] = subnet_id log.debug("Payload for the provisioning request: {0}".format( pformat(AWS_PAYLOAD))) self.req_id = self.action(AWS_PAYLOAD) log.info("Provisioning request created: {0}".format(self.req_id)) return self.req_id
def cli(verbose): """Print an info message""" miqcli_log.debug(MESSAGE)