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 terminate(self, inst_name, provider=None, network=None, tenant=None, subnet=None, vendor=None, itype=None, by_id=False): """Terminate instance. :: :param inst_name: name of the instance :type inst_name: str :param provider: provider of the instance :type provider: str :param network: name of cloud network :type network: str :param tenant: name of cloud tentant :type tenant: str :param subnet: name of cloud subnetwork :type subnet: str :param vendor: name of vendor :type vendor: str :param itype: type of instance - "Openstack" or "Amazon" :type itype: str :param by_id: name is instance id :type by_id: bool :return: id of the task created to terminate the instance :rtype: int """ if inst_name: instance = self.query(inst_name, provider, network, tenant, subnet, vendor, itype, by_id=by_id) if instance and type(instance) is list: log.abort("Multiple instances found." "Supply more options to narrow.") try: result = instance.action.terminate() log.info("Task to terminate {0} created: {1}".format( inst_name, result["task_id"])) return result["task_id"] except APIException as ex: log.abort('Unable to create a task: terminate instance: ' '{0}: {1}'.format(inst_name, ex)) else: log.abort('Set an instance to be terminated.')
def delete(self, vm_name, provider=None, vendor=None, vtype=None, by_id=False): """Delete. :: Delete the vm with the provided options. :param vm_name: name of the vm :type vm_name: str :param provider: name of the provider :type provider: str :param vendor: name of vendor :type vendor: str :param vtype: type of vm - "Openstack" or "Amazon" :type vtype: str :param by_id: name is vm id :type by_id: bool :return: id of a task that will delete the vm :rtype: int """ if vm_name: vm = self.query(vm_name, provider, vendor, vtype, by_id=by_id) if vm and type(vm) is list: log.abort("Multiple vms found." "Supply more options to narrow.") try: result = vm.action.delete() log.info("Task to delete {0} created: {1}".format( vm_name, result["task_id"])) return result["task_id"] except APIException as ex: log.abort('Unable to create a task: delete vm: ' '{0}: {1}'.format(vm_name, ex)) else: log.abort('Set a vm to be deleted.')
def create( self, method, payload, payload_file, ): """Create an automation request :: Builds the payload data for the request (performing all necessary id lookups) and then submits the automation request to the server. :param method: automation request to run :type method: str :param payload: json data in str format :type payload: str :param payload_file: file location of the payload :type payload_file: str :return: automation request ID :rtype: str """ _payload = None log.info("Attempt to create an automation request") # get the data from user input input_data = get_input_data(payload, payload_file) # RFE: make generic as possible, remove conditional if possible if method == AR.GENERIC: # generic request, default behavior passthrough payload data _payload = input_data elif method == AR.GEN_FIP: # set the floating ip if set by the user _payload = OSP_FIP_PAYLOAD if 'fip_pool' in input_data: # lookup cloud network resource to get the id # TODO: need to have user set the provider networks = Networks('OpenStack', self.api, 'public') _payload['parameters']['cloud_network_id'] = \ networks.get_id(input_data['fip_pool']) # lookup cloud tenant # TODO: need to have user set the provider tenant = Tenant('OpenStack', self.api) _payload['parameters']['cloud_tenant_id'] = \ tenant.get_id(input_data['tenant']) elif method == AR.RELEASE_FIP: _payload = OSP_FIP_PAYLOAD # release the floating_ip _payload["uri_parts"]["instance"] = "release_floating_ip" if 'floating_ip' in input_data: _payload['parameters']['floating_ip'] = \ input_data["floating_ip"] elif 'floating_ip_id' in input_data: _payload['parameters']['floating_ip_id'] = \ input_data["floating_ip_id"] else: log.abort('To release a floating ip, set floating_ip or ' 'floating_ip_id.') try: self.req_id = self.action(_payload) log.info('Automation request created: %s.' % self.req_id) return self.req_id except APIException as ex: log.abort('Unable to create automation request: %s' % 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 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 status(self, req_id): """Print the status for a provision request. :: Handles getting information for an existing provision request and displaying/returning back to the user. :param req_id: id of the provisioning request :type req_id: str :return: provision request object or list of provision request objects """ status = OrderedDict() query = BasicQuery(self.collection) if req_id: provision_requests = query(("id", "=", req_id)) if len(provision_requests) < 1: log.warning('Provision request id: %s not found!' % req_id) return None req = provision_requests[0] status['state'] = req.request_state status['status'] = req.status status['message'] = req.message log.info('-' * 50) log.info('Provision request'.center(50)) log.info('-' * 50) log.info(' * ID: %s' % req_id) log.info(' * VM: %s' % req.options['vm_name']) for key, value in status.items(): log.info(' * %s: %s' % (key.upper(), value)) log.info('-' * 50) return req else: provision_requests = query(("request_state", "!=", "finished")) if len(provision_requests) < 1: log.warning(' * No active provision requests at this time') return None log.info('-' * 50) log.info(' Active provision requests'.center(50)) log.info('-' * 50) for item in provision_requests: log.info(' * ID: %s\tINSTANCE: %s\tSTATE: %s\tSTATUS: %s' % (item.id, item.options['vm_name'], item.request_state, item.status)) log.info('-' * 50) return provision_requests
def cli(): """Print an info message""" miqcli_log.info(MESSAGE)
def query(self): """Query.""" zones = self.all log.info('-' * 50) log.info('Zones'.center(50)) log.info('-' * 50) for zone in zones: log.info(' * ID: %s' % zone['id']) log.info(' * Name: %s' % zone['name']) log.info(' * Description: %s' % zone['description']) log.info('-' * 50) return zones
def status(self, req_id): """Get the status for a request task. :: Handles getting information for an existing request and displaying/returning back to the user. :param req_id: id of the request :type req_id: str :return: request task object or list of request objects """ status = OrderedDict() query = BasicQuery(self.collection) if req_id: requests_tasks = query(("id", "=", req_id)) if len(requests_tasks) < 1: log.warning('Request id: %s not found!' % req_id) return None req = requests_tasks[0] status['state'] = req.state status['status'] = req.status status['message'] = req.message log.info('-' * 50) log.info('Request'.center(50)) log.info('-' * 50) log.info(' * ID: %s' % req_id) log.info(' * Description: %s' % req['description']) for key, value in status.items(): log.info(' * %s: %s' % (key.upper(), value)) log.info('-' * 50) return req else: requests_tasks = query(("state", "!=", "finished")) if len(requests_tasks) < 1: log.warning(' * No active requests tasks at this time') return None log.info('-' * 50) log.info(' Active requests'.center(50)) log.info('-' * 50) for item in requests_tasks: log.info(' * ID: %s\tDESCRIPTION: %s\tSTATE: %s\tSTATUS: %s' % (item.id, item.description, item.state, item.status)) log.info('-' * 50) return requests_tasks