def create_vip_port(self, loadbalancer_id, project_id, vip_dictionary): vip_obj = driver_utils.provider_vip_dict_to_vip_obj(vip_dictionary) lb_obj = data_models.LoadBalancer(id=loadbalancer_id, project_id=project_id, vip=vip_obj) network_driver = utils.get_network_driver() vip_network = network_driver.get_network( vip_dictionary[lib_consts.VIP_NETWORK_ID]) if not vip_network.port_security_enabled: message = "Port security must be enabled on the VIP network." raise exceptions.DriverError(user_fault_string=message, operator_fault_string=message) try: vip = network_driver.allocate_vip(lb_obj) except network_base.AllocateVIPException as e: message = str(e) if getattr(e, 'orig_msg', None) is not None: message = e.orig_msg raise exceptions.DriverError(user_fault_string=message, operator_fault_string=message) LOG.info('Amphora provider created VIP port %s for load balancer %s.', vip.port_id, loadbalancer_id) return driver_utils.vip_dict_to_provider_dict(vip.to_dict())
def validate_flavor(self, flavor_dict): """Validates flavor profile data. This will validate a flavor profile dataset against the flavor settings the amphora driver supports. :param flavor_dict: The flavor dictionary to validate. :type flavor: dict :return: None :raises DriverError: An unexpected error occurred. :raises UnsupportedOptionError: If the driver does not support one of the flavor settings. """ try: validate(flavor_dict, flavor_schema.SUPPORTED_FLAVOR_SCHEMA) except js_exceptions.ValidationError as e: error_object = '' if e.relative_path: error_object = '{} '.format(e.relative_path[0]) raise exceptions.UnsupportedOptionError( user_fault_string='{0}{1}'.format(error_object, e.message), operator_fault_string=str(e)) except Exception as e: raise exceptions.DriverError( user_fault_string='Failed to validate the flavor metadata ' 'due to: {}'.format(str(e)), operator_fault_string='Failed to validate the flavor metadata ' 'due to: {}'.format(str(e))) compute_flavor = flavor_dict.get(consts.COMPUTE_FLAVOR, None) if compute_flavor: compute_driver = stevedore_driver.DriverManager( namespace='octavia.compute.drivers', name=CONF.controller_worker.compute_driver, invoke_on_load=True ).driver # TODO(johnsom) Fix this to raise a NotFound error # when the octavia-lib supports it. compute_driver.validate_flavor(compute_flavor) amp_image_tag = flavor_dict.get(consts.AMP_IMAGE_TAG, None) if amp_image_tag: image_driver = stevedore_driver.DriverManager( namespace='octavia.image.drivers', name=CONF.controller_worker.image_driver, invoke_on_load=True ).driver try: image_driver.get_image_id_by_tag( amp_image_tag, CONF.controller_worker.amp_image_owner_id) except Exception as e: raise exceptions.NotFound( user_fault_string='Failed to find an image with tag {} ' 'due to: {}'.format( amp_image_tag, str(e)), operator_fault_string='Failed to find an image with tag ' '{} due to: {}'.format( amp_image_tag, str(e)))
def _get_resource(self, resource, id): try: return self._send(self.get_socket, { constants.OBJECT: resource, constants.ID: id }) except driver_exceptions.DriverAgentTimeout: raise except Exception: raise driver_exceptions.DriverError()
def test_DriverError(self): driver_error = exceptions.DriverError( user_fault_string=self.user_fault_string, operator_fault_string=self.operator_fault_string) self.assertEqual(self.user_fault_string, driver_error.user_fault_string) self.assertEqual(self.operator_fault_string, driver_error.operator_fault_string) self.assertIsInstance(driver_error, Exception)
def validate_availability_zone(self, availability_zone_dict): """Validates availability zone profile data. This will validate an availability zone profile dataset against the availability zone settings the amphora driver supports. :param availability_zone_dict: The availability zone dict to validate. :type availability_zone_dict: dict :return: None :raises DriverError: An unexpected error occurred. :raises UnsupportedOptionError: If the driver does not support one of the availability zone settings. """ try: validate( availability_zone_dict, availability_zone_schema.SUPPORTED_AVAILABILITY_ZONE_SCHEMA) except js_exceptions.ValidationError as e: error_object = '' if e.relative_path: error_object = '{} '.format(e.relative_path[0]) raise exceptions.UnsupportedOptionError( user_fault_string='{0}{1}'.format(error_object, e.message), operator_fault_string=str(e)) except Exception as e: raise exceptions.DriverError( user_fault_string='Failed to validate the availability zone ' 'metadata due to: {}'.format(str(e)), operator_fault_string='Failed to validate the availability ' 'zone metadata due to: {}'.format(str(e)) ) compute_zone = availability_zone_dict.get(consts.COMPUTE_ZONE, None) if compute_zone: compute_driver = stevedore_driver.DriverManager( namespace='octavia.compute.drivers', name=CONF.controller_worker.compute_driver, invoke_on_load=True ).driver # TODO(johnsom) Fix this to raise a NotFound error # when the octavia-lib supports it. compute_driver.validate_availability_zone(compute_zone) check_nets = availability_zone_dict.get( consts.VALID_VIP_NETWORKS, []) management_net = availability_zone_dict.get( consts.MANAGEMENT_NETWORK, None) if management_net: check_nets.append(management_net) for check_net in check_nets: network_driver = utils.get_network_driver() # TODO(johnsom) Fix this to raise a NotFound error # when the octavia-lib supports it. network_driver.get_network(check_net)
def create_vip_port(self, loadbalancer_id, project_id, vip_dictionary): vip_obj = driver_utils.provider_vip_dict_to_vip_obj(vip_dictionary) lb_obj = data_models.LoadBalancer(id=loadbalancer_id, project_id=project_id, vip=vip_obj) network_driver = utils.get_network_driver() try: vip = network_driver.allocate_vip(lb_obj) except network_base.AllocateVIPException as e: raise exceptions.DriverError(user_fault_string=e.orig_msg, operator_fault_string=e.orig_msg) LOG.info('Amphora provider created VIP port %s for load balancer %s.', vip.port_id, loadbalancer_id) return driver_utils.vip_dict_to_provider_dict(vip.to_dict())
def create_vip_port(self, lb_id, project_id, vip_dict): try: port = self._ovn_helper.create_vip_port( project_id, lb_id, vip_dict)['port'] vip_dict[constants.VIP_PORT_ID] = port['id'] vip_dict[constants.VIP_ADDRESS] = ( port['fixed_ips'][0]['ip_address']) except Exception as e: kwargs = {} if hasattr(e, 'message'): kwargs = {'user_fault_string': e.message, 'operator_fault_string': e.message} raise driver_exceptions.DriverError( **kwargs) return vip_dict
def get_neutron_client(): try: return NeutronAuth( endpoint=CONF.neutron.endpoint, region=CONF.neutron.region_name, endpoint_type=CONF.neutron.endpoint_type, service_name=CONF.neutron.service_name, insecure=CONF.neutron.insecure, ca_cert=CONF.neutron.ca_certificates_file, ).neutron_client except n_exc.NeutronClientException as e: msg = _('Cannot inialize Neutron Client. Exception: %s. ' 'Please verify Neutron service configuration ' 'in Octavia API configuration.') % e raise driver_exceptions.DriverError( operator_fault_string=msg)
def get_supported_flavor_metadata(self): """Returns the valid flavor metadata keys and descriptions. This extracts the valid flavor metadata keys and descriptions from the JSON validation schema and returns it as a dictionary. :return: Dictionary of flavor metadata keys and descriptions. :raises DriverError: An unexpected error occurred. """ try: props = flavor_schema.SUPPORTED_FLAVOR_SCHEMA['properties'] return {k: v.get('description', '') for k, v in props.items()} except Exception as e: raise exceptions.DriverError( user_fault_string='Failed to get the supported flavor ' 'metadata due to: {}'.format(str(e)), operator_fault_string='Failed to get the supported flavor ' 'metadata due to: {}'.format(str(e)))
def get_supported_flavor_metadata(self): try: dict = {} for obj in flavor_schema.SUPPORTED_FLAVOR_SCHEMA['properties']: obj_v = flavor_schema.SUPPORTED_FLAVOR_SCHEMA['properties'][ obj] if 'description' in obj_v: dict[obj] = obj_v.get('description') if 'properties' in obj_v: props = obj_v['properties'] for k, v in props.items(): if 'description' in v: dict[obj + '.' + k] = v.get('description') return dict except Exception as e: raise exceptions.DriverError( user_fault_string='Failed to get the supported flavor ' 'metadata due to: {}'.format(str(e)), operator_fault_string='Failed to get the supported flavor ' 'metadata due to: {}'.format(str(e)))
def get_supported_availability_zone_metadata(self): """Returns the valid availability zone metadata keys and descriptions. This extracts the valid availability zone metadata keys and descriptions from the JSON validation schema and returns it as a dictionary. :return: Dictionary of availability zone metadata keys and descriptions :raises DriverError: An unexpected error occurred. """ try: props = (availability_zone_schema. SUPPORTED_AVAILABILITY_ZONE_SCHEMA['properties']) return {k: v.get('description', '') for k, v in props.items()} except Exception as e: raise exceptions.DriverError( user_fault_string='Failed to get the supported availability ' 'zone metadata due to: {}'.format(str(e)), operator_fault_string='Failed to get the supported ' 'availability zone metadata due to: ' '{}'.format(str(e)))
def validate_flavor(self, flavor_dict): try: validate(flavor_dict, flavor_schema.SUPPORTED_FLAVOR_SCHEMA) # validate flavor for slb objects if 'virtual-server' in flavor_dict: flavor = flavor_dict['virtual-server'] if 'name' in flavor: raise Exception('axapi key \'name\' is not allowed') if 'ip-address' in flavor: raise Exception( 'axapi key \'ip-address\' is not supported yet') self._validate_flavor_name_expressions(flavor) if 'virtual-port' in flavor_dict: flavor = flavor_dict['virtual-port'] if 'name' in flavor: raise Exception('axapi key \'name\' is not allowed') if 'port-number' in flavor: raise Exception('axapi key \'port-number\' is not allowed') if 'protocol' in flavor: raise Exception('axapi key \'protocol\' is not allowed') self._validate_flavor_name_expressions(flavor) if 'service-group' in flavor_dict: flavor = flavor_dict['service-group'] if 'name' in flavor: raise Exception('axapi key \'name\' is not allowed') self._validate_flavor_name_expressions(flavor) if 'server' in flavor_dict: flavor = flavor_dict['server'] if 'name' in flavor: raise Exception('axapi key \'name\' is not allowed') self._validate_flavor_name_expressions(flavor) if 'health-monitor' in flavor_dict: flavor = flavor_dict['health-monitor'] if 'name' in flavor: raise Exception('axapi key \'name\' is not allowed') self._validate_flavor_name_expressions(flavor) # validate nat-pool and nat-pool-list keys if 'nat-pool' in flavor_dict: nat = flavor_dict['nat-pool'] if 'pool-name' not in nat: raise Exception( 'pool-name is required for nat-pool flavor') if 'start-address' not in nat: raise Exception( 'start-address is required for nat-pool flavor') if 'end-address' not in nat: raise Exception( 'end-address is required for nat-pool flavor') if 'netmask' not in nat: raise Exception('netmask is required for nat-pool flavor') if 'nat-pool-list' in flavor_dict: for nat in flavor_dict['nat-pool-list']: if 'pool-name' not in nat: raise Exception( 'pool-name is required for nat-pool-list flavor') if 'start-address' not in nat: raise Exception( 'start-address is required for nat-pool-list flavor' ) if 'end-address' not in nat: raise Exception( 'end-address is required for nat-pool-list flavor') if 'netmask' not in nat: raise Exception( 'netmask is required for nat-pool-list flavor') if 'deployment' in flavor_dict: deployment = flavor_dict['deployment'] if ('dsr_type' in deployment and deployment['dsr_type'] not in ['l2dsr_transparent']): raise Exception( 'l2dsr_transparent is required value for dsr_type') except js_exceptions.ValidationError as e: error_object = '' if e.relative_path: error_object = '{} '.format(e.relative_path[0]) raise exceptions.UnsupportedOptionError( user_fault_string='{0}{1}'.format(error_object, e.message), operator_fault_string=str(e)) except Exception as e: raise exceptions.DriverError( user_fault_string='Failed to validate the flavor metadata ' 'due to: {}'.format(str(e)), operator_fault_string='Failed to validate the flavor metadata ' 'due to: {}'.format(str(e)))