def delete_nic(self): vm = self.get_vm() nics = self.params.get('nics') vm_name = self.params.get('vm_name') response = dict() response['msg'] = list() response['changed'] = False # check if VM is powered off if not vm.is_powered_off(): msg = "VM {0} is powered on. Cant remove nics in the current state" raise OperationNotSupportedException(msg.format(vm_name)) for nic in nics: try: nic_id = nic.get('nic_id') delete_nic_task = vm.delete_nic(nic_id) self.execute_task(delete_nic_task) msg = 'VM nic {0} has been deleted'.format(nic_id) response['changed'] = True except (InvalidParameterException, EntityNotFoundException) as error: msg = 'Nic {0} throws following error: {1}' msg = msg.format(nic_id, error.__str__()) response['msg'].append(msg) return response
def _perform_power_operation(self, rel, operation_name, media_type=None, contents=None): """Perform a power operation on the vApp. Perform one of the following power operations on the vApp. Power on, Power off, Deploy, Undeploy, Shutdown, Reboot, Power reset. :param pyvcloud.vcd.client.RelationType rel: relation of the link in the vApp resource that will be triggered for the power operation. :param str operation_name: name of the power operation to perform. This value will be used while logging error messages (if any). :param str media_type: media type of the link in the vApp resource that will be triggered for the power operation. :param lxml.objectify.ObjectifiedElement contents: payload for the linked operation. :return: an object containing EntityType.TASK XML data which represents the asynchronous task that is tracking the power operation on the vApp. :rtype: lxml.objectify.ObjectifiedElement :raises OperationNotSupportedException: if the power operation can't be performed on the vApp. """ vapp_resource = self.get_resource() try: return self.client.post_linked_resource( vapp_resource, rel, media_type, contents) except OperationNotSupportedException as e: power_state = self.get_power_state(vapp_resource) raise OperationNotSupportedException( 'Can\'t ' + operation_name + ' vApp. Current state of vApp:' + VCLOUD_STATUS_MAP[power_state])
def resize_cluster(self, cluster_entity: models.ClusterEntity): """Resize the existing Kubernetes cluster. :param models.ClusterEntity cluster_entity: native cluster entity :return: (json) A parsed json object describing the requested cluster. """ msg = "Operation not supported; Under implementation" raise OperationNotSupportedException(msg)
def get_linked_resource(self, resource, rel, media_type): """Gets the content of the resource link. Gets the contents of the resource referenced by the link with the specified rel and mediaType in the specified resource. """ try: return self.get_resource(find_link(resource, rel, media_type).href) except MissingLinkException as e: raise OperationNotSupportedException( "Operation is not supported").with_traceback(e.__traceback__)
def get_cluster_info(self, name, org=None, vdc=None, **kwargs): """Get cluster information using DEF API. :param str vdc: name of vdc :param str org: name of org :param kwargs: *filter (dict): keys,values for DEF API query filter :return: cluster information :rtype: dict """ # method = RequestMethod.GET msg = "Operation not supported; Under implementation" raise OperationNotSupportedException(msg)
def _get_extension_record(self, name, namespace=None, format=QueryResultFormat.ID_RECORDS): """Fetch info about a particular API extension service as a record. :param str name: the name of the extension service whose info we want to retrieve. :param str namespace: the namespace of the extension service. If omitted, all extension services matching the given name will be retrieved and that would lead to a MultipleRecordsException. :param format QueryResultFormat: dictates whether id or href should be part of the returned record. By default id is returned. :return: the extension service record. :rtype: generator object that returns lxml.objectify.ObjectifiedElement object containing AdminServiceRecord XML data representing the service. :raises MissingRecordException: if a service with the given name and namespace couldn't be found. :raise MultipleRecordsException: if more than one service with the given name and namespace are found. """ qfilter = 'name==%s' % urllib.parse.quote_plus(name) if namespace is not None: qfilter += ';namespace==%s' % urllib.parse.quote_plus(namespace) try: ext = self.client.get_typed_query( ResourceType.ADMIN_SERVICE.value, qfilter=qfilter, query_result_format=format).find_unique() except OperationNotSupportedException as e: msg = 'User doesn\'t have permission to interact with extensions.' raise OperationNotSupportedException(msg) except MissingRecordException as e: msg = 'API Extension service (name:' + name if namespace is not None: msg += ', namespace:' + namespace msg += ') not found.' raise MissingRecordException(msg) except MultipleRecordsException as e: msg = 'Found multiple API Extension service with (name:' + name if namespace is not None: msg += ', namespace:' + namespace + ').' else: msg += '). Consider providing value for the namespace.' raise MultipleRecordsException(msg) return ext
def list_extensions(self): """Fetch the API extension services defined in the system. :return: all the registered API extension services in the system. :rtype: list """ try: records = self.client.get_typed_query( ResourceType.ADMIN_SERVICE.value, query_result_format=QueryResultFormat.ID_RECORDS).execute() except OperationNotSupportedException as e: msg = 'User doesn\'t have permission to view extensions.' raise OperationNotSupportedException(msg) return [to_dict(r, self.ATTRIBUTES) for r in records]
def __init__(self, client): """Initialize ComputePolicyManager Object. :param pyvcloud.vcd.client client: :raises: OperationNotSupportedException: If cloudapi endpoint is not found in session. :raises: ValueError: If non sys admin client is passed during initialization. """ if not client.is_sysadmin(): raise ValueError("Only Sys admin clients should be used to " "initialize ComputePolicyManager.") self._vcd_client = client token = self._vcd_client.get_access_token() is_jwt_token = True if not token: token = self._vcd_client.get_xvcloud_authorization_token() is_jwt_token = False self._session = self._vcd_client.get_vcloud_session() try: self._cloudapi_client = CloudApiClient( base_url=self._vcd_client.get_cloudapi_uri(), token=token, is_jwt_token=is_jwt_token, api_version=self._vcd_client.get_api_version(), verify_ssl=self._vcd_client._verify_ssl_certs) # Since the /cloudapi endpoint was added before the compute policy # endpoint. Mere presence of the /cloudapi uri is not enough, we # need to make sure that this cloud api client will be of actual # use to us. self._cloudapi_client.do_request( method=RequestMethod.GET, cloudapi_version=CLOUDAPI_VERSION_1_0_0, resource_url_relative_path=f"{CloudApiResource.VDC_COMPUTE_POLICIES}") # noqa: E501 except requests.exceptions.HTTPError as err: LOGGER.error(err) raise OperationNotSupportedException( "Cloudapi endpoint unavailable at current api version.")
def get_api_filters(self, service_id): """Fetch the API filters defined for the service. :param str service_id: the id of the extension service. :return: API filters registered for the API extension. :rtype: generator object """ try: records = self.client.get_typed_query( ResourceType.API_FILTER.value, equality_filter=('service', service_id), query_result_format=QueryResultFormat.ID_RECORDS).execute() except OperationNotSupportedException as e: msg = 'User doesn\'t have permission to view api filters.' raise OperationNotSupportedException(msg) return records
def delete_nic(self): vm = self.get_vm() vapp = self.params.get('vapp') nic_ids = self.params.get('nic_ids') vm_name = self.params.get('vm_name') response = dict() response['changed'] = False if not vm.is_powered_off(): msg = "VM {0} is powered on. Cant remove nics in the current state" raise OperationNotSupportedException(msg.format(vm_name)) for nic_id in nic_ids: try: delete_nic_task = vm.delete_nic(nic_id) self.execute_task(delete_nic_task) response['changed'] = True except InvalidParameterException as error: response['msg'] = error.__str__() else: response['msg'] = 'VM nic(s) has been deleted' return response
def remove_static_ip_pool(self, ip_range_param): """Remove static IP pool of org vdc network. :param str ip_range_param: ip range. For ex: 2.3.3.2-2.3.3.10 :return: object containing EntityType.TASK XML data representing the asynchronous task. :rtype: lxml.objectify.ObjectifiedElement """ vdc_network = self.get_resource() ip_scope = vdc_network.Configuration.IpScopes.IpScope if not hasattr(ip_scope, 'IpRanges'): raise OperationNotSupportedException('No IP range found.') for ip_range in ip_scope.IpRanges.IpRange: if (ip_range.StartAddress + '-' + ip_range.EndAddress) == ip_range_param: ip_scope.IpRanges.remove(ip_range) return self.client.put_linked_resource( self.resource, RelationType.EDIT, EntityType.ORG_VDC_NETWORK.value, vdc_network)
def __init__(self, client): """Initialize ComputePolicyManager Object. :param pyvcloud.vcd.client client: :raises: OperationNotSupportedException: If cloudapi endpoint is not found in session. :raises: ValueError: If non sys admin client is passed during initialization. """ if not client.is_sysadmin(): raise ValueError("Only Sys admin clients should be used to " "initialize ComputePolicyManager.") self._vcd_client = client # TODO: pyvcloud should expose methods to grab the session and token # from a client object. auth_token = \ self._vcd_client._session.headers['x-vcloud-authorization'] # pyvcloud doesn't store the vCD session response in client. So we need # to get it from vCD. session = self._vcd_client.rehydrate_from_token(auth_token) # Ideally this information should be fetched from # client._session_endpoints. However pyvcloud client doesn't store # the cloudapi link, so we have to find it manually. try: link = find_link(session, RelationType.OPEN_API, EntityType.APPLICATION_JSON) except MissingLinkException: raise OperationNotSupportedException( "Cloudapi endpoint unavailable at current api version.") self._cloudapi_client = CloudApiClient( base_url=link.href, auth_token=auth_token, verify_ssl=self._vcd_client._verify_ssl_certs)
def modify_static_ip_pool(self, ip_range_param, new_ip_range_param): """Modify static IP pool of org vdc network. :param str ip_range_param: ip range. For ex: 2.3.3.2-2.3.3.10 :param str new_ip_range_param: new ip range. For ex: 2.3.3.11-2.3.3.20 :return: object containing EntityType.TASK XML data representing the asynchronous task. :rtype: lxml.objectify.ObjectifiedElement """ vdc_network = self.get_resource() ip_scope = vdc_network.Configuration.IpScopes.IpScope if not hasattr(ip_scope, 'IpRanges'): raise OperationNotSupportedException('No IP range found.') ip_ranges_list = ip_scope.IpRanges.IpRange for ip_range in ip_ranges_list: ip_range_arr = ip_range_param.split('-') new_ip_range_arr = new_ip_range_param.split('-') if len(ip_range_arr) <= 1 or len(new_ip_range_arr) <= 1: raise InvalidParameterException('Input params should be in ' 'x.x.x.x-y.y.y.y') if (ip_range.StartAddress + '-' + ip_range.EndAddress) != \ ip_range_param: continue new_start_address = new_ip_range_arr[0] new_end_address = new_ip_range_arr[1] ip_range.StartAddress = E.StartAddress(new_start_address) ip_range.EndAddress = E.StartAddress(new_end_address) return self.client.put_linked_resource( self.resource, RelationType.EDIT, EntityType.ORG_VDC_NETWORK.value, vdc_network)
def _raise_error_if_not_supported(self): """Raise exception if operation is not supported.""" if not self._is_operation_supported: msg = "Cloudapi endpoint unavailable at current api version." logger.SERVER_LOGGER.error(msg) raise OperationNotSupportedException(msg)
def __getattr__(self, name): msg = "Operation not supported; Under implementation" raise OperationNotSupportedException(msg)
def apply(self, cluster_config_file_path): uri = f"{self._uri}/clusters" msg = f"Operation not supported; Implementation in progress for {uri}" raise (OperationNotSupportedException(msg))