def network_allowed_by_config(network_id): if CONF.networking.valid_vip_networks: valid_networks = map(str.lower, CONF.networking.valid_vip_networks) if network_id not in valid_networks: raise exceptions.ValidationException(detail=_( 'Supplied VIP network_id is not allowed by the configuration ' 'of this deployment.'))
def check_port_in_use(port): """Raise an exception when a port is used.""" if port.device_id: raise exceptions.ValidationException(detail=_( "Port %(port_id)s is already used by device %(device_id)s ") % {'port_id': port.id, 'device_id': port.device_id}) return False
class OctaviaException(Exception): """Base Octavia Exception. To correctly use this class, inherit from it and define a 'message' property. That message will get printf'd with the keyword arguments provided to the constructor. """ message = _("An unknown exception occurred.") orig_msg = None orig_code = None def __init__(self, *args, **kwargs): try: if args: self.message = args[0] self.orig_msg = kwargs.get('orig_msg') self.orig_code = kwargs.get('orig_code') super(OctaviaException, self).__init__(self.message % kwargs) self.msg = self.message % kwargs except Exception: with excutils.save_and_reraise_exception() as ctxt: if not self.use_fatal_exceptions(): ctxt.reraise = False # at least get the core message out if something happened super(OctaviaException, self).__init__(self.message) def __unicode__(self): return six.text_type(self.msg) @staticmethod def use_fatal_exceptions(): return False
def call_provider(provider, driver_method, *args, **kwargs): """Wrap calls to the provider driver to handle driver errors. This allows Octavia to return user friendly errors when a provider driver has an issue. :param driver_method: Method in the driver to call. :raises ProviderDriverError: Catch all driver error. :raises ProviderNotImplementedError: The driver doesn't support this action. :raises ProviderUnsupportedOptionError: The driver doesn't support a provided option. """ try: return driver_method(*args, **kwargs) except (driver_exceptions.DriverError, lib_exceptions.DriverError) as e: LOG.exception("Provider '%s' raised a driver error: %s", provider, e.operator_fault_string) raise exceptions.ProviderDriverError(prov=provider, user_msg=e.user_fault_string) except (driver_exceptions.NotImplementedError, lib_exceptions.NotImplementedError, NotImplementedError) as e: op_fault_string = ( e.operator_fault_string if hasattr(e, "operator_fault_string") else _("This feature is not implemented by this provider.")) usr_fault_string = ( e.user_fault_string if hasattr(e, "user_fault_string") else _("This feature is not implemented by the provider.")) LOG.info("Provider '%s' raised a not implemented error: %s", provider, op_fault_string) raise exceptions.ProviderNotImplementedError(prov=provider, user_msg=usr_fault_string) except (driver_exceptions.UnsupportedOptionError, lib_exceptions.UnsupportedOptionError) as e: LOG.info("Provider '%s' raised an unsupported option error: " "%s", provider, e.operator_fault_string) raise exceptions.ProviderUnsupportedOptionError( prov=provider, user_msg=e.user_fault_string) except Exception as e: LOG.exception("Provider '%s' raised an unknown error: %s", provider, e) raise exceptions.ProviderDriverError(prov=provider, user_msg=e)
def check_session_persistence(SP_dict): try: if SP_dict['cookie_name']: if SP_dict['type'] != constants.SESSION_PERSISTENCE_APP_COOKIE: raise exceptions.ValidationException(detail=_( 'Field "cookie_name" can only be specified with session ' 'persistence of type "APP_COOKIE".')) bad_cookie_name = re.compile(r'[\x00-\x20\x22\x28-\x29\x2c\x2f' r'\x3a-\x40\x5b-\x5d\x7b\x7d\x7f]+') valid_chars = re.compile(r'[\x00-\xff]+') if (bad_cookie_name.search(SP_dict['cookie_name']) or not valid_chars.search(SP_dict['cookie_name'])): raise exceptions.ValidationException(detail=_( 'Supplied "cookie_name" is invalid.')) if (SP_dict['type'] == constants.SESSION_PERSISTENCE_APP_COOKIE and not SP_dict['cookie_name']): raise exceptions.ValidationException(detail=_( 'Field "cookie_name" must be specified when using the ' '"APP_COOKIE" session persistence type.')) except exceptions.ValidationException: raise except Exception: raise exceptions.ValidationException(detail=_( 'Invalid session_persistence provided.'))
class AmphoraDriverError(Exception): message = _("A super class for all other exceptions and the catch.") def __init__(self, **kwargs): try: super(AmphoraDriverError, self).__init__(self.message % kwargs) self.msg = self.message % kwargs except Exception: with excutils.save_and_reraise_exception() as ctxt: if not self.use_fatal_exceptions(): ctxt.reraise = False # at least get the core message out if something happened super(AmphoraDriverError, self).__init__(self.message) def __unicode__(self): return six.text_type(self.msg) @staticmethod def use_fatal_exceptions(): """Return True if use fatal exceptions by raising them.""" return False
class SuspendFailed(AmphoraDriverError): message = _('this load balancer couldn\'t be suspended')
class TimeOutException(AmphoraDriverError): message = _('contacting the amphora timed out')
class DeleteFailed(AmphoraDriverError): message = _('this load balancer couldn\'t be deleted')
class UnauthorizedException(AmphoraDriverError): message = _('the driver can\'t access the amphora')
class StatisticsException(AmphoraDriverError): message = _('gathering statistics failed')
class ProvisioningErrors(AmphoraDriverError): message = _('Super class for provisioning amphora errors')
def l7rule_data(l7rule): """Raises an error if the l7rule given is invalid in some way.""" if not l7rule.value: raise exceptions.InvalidL7Rule(msg=_('L7 rule type requires a value')) if l7rule.type == constants.L7RULE_TYPE_HEADER: if not l7rule.key: raise exceptions.InvalidL7Rule(msg='L7 rule type requires a key') header_name(l7rule.key, what='key') if l7rule.compare_type == constants.L7RULE_COMPARE_TYPE_REGEX: regex(l7rule.value) elif l7rule.compare_type in ( constants.L7RULE_COMPARE_TYPE_STARTS_WITH, constants.L7RULE_COMPARE_TYPE_ENDS_WITH, constants.L7RULE_COMPARE_TYPE_CONTAINS, constants.L7RULE_COMPARE_TYPE_EQUAL_TO): header_value_string(l7rule.value, what='header value') else: raise exceptions.InvalidL7Rule(msg='invalid comparison type ' 'for rule type') elif l7rule.type == constants.L7RULE_TYPE_COOKIE: if not l7rule.key: raise exceptions.InvalidL7Rule(msg='L7 rule type requires a key') header_name(l7rule.key, what='key') if l7rule.compare_type == constants.L7RULE_COMPARE_TYPE_REGEX: regex(l7rule.value) elif l7rule.compare_type in ( constants.L7RULE_COMPARE_TYPE_STARTS_WITH, constants.L7RULE_COMPARE_TYPE_ENDS_WITH, constants.L7RULE_COMPARE_TYPE_CONTAINS, constants.L7RULE_COMPARE_TYPE_EQUAL_TO): cookie_value_string(l7rule.value, what='cookie value') else: raise exceptions.InvalidL7Rule(msg='invalid comparison type ' 'for rule type') elif l7rule.type in (constants.L7RULE_TYPE_HOST_NAME, constants.L7RULE_TYPE_PATH): if l7rule.compare_type in ( constants.L7RULE_COMPARE_TYPE_STARTS_WITH, constants.L7RULE_COMPARE_TYPE_ENDS_WITH, constants.L7RULE_COMPARE_TYPE_CONTAINS, constants.L7RULE_COMPARE_TYPE_EQUAL_TO): header_value_string(l7rule.value, what='comparison value') elif l7rule.compare_type == constants.L7RULE_COMPARE_TYPE_REGEX: regex(l7rule.value) else: raise exceptions.InvalidL7Rule(msg='invalid comparison type ' 'for rule type') elif l7rule.type == constants.L7RULE_TYPE_FILE_TYPE: if l7rule.compare_type == constants.L7RULE_COMPARE_TYPE_REGEX: regex(l7rule.value) elif l7rule.compare_type == constants.L7RULE_COMPARE_TYPE_EQUAL_TO: header_value_string(l7rule.value, what='comparison value') else: raise exceptions.InvalidL7Rule(msg='invalid comparison type ' 'for rule type') elif l7rule.type in [constants.L7RULE_TYPE_SSL_CONN_HAS_CERT, constants.L7RULE_TYPE_SSL_VERIFY_RESULT, constants.L7RULE_TYPE_SSL_DN_FIELD]: validate_l7rule_ssl_types(l7rule) else: raise exceptions.InvalidL7Rule(msg='invalid rule type') return True
class LoadBalancerProvisoningError(ProvisioningErrors): message = _('couldn\'t provision LoadBalancer')
class NodeProvisioningError(ProvisioningErrors): message = _('couldn\'t provision Node')
class AmpDriverNotImplementedError(AmphoraDriverError): message = _('Amphora does not implement this feature.')
class AmpConnectionRetry(AmphoraDriverError): message = _('Could not connect to amphora, exception caught: ' '%(exception)s')
class DisabledOption(APIException): msg = _("The selected %(option)s is not allowed in this deployment: " "%(value)s") code = 400
def listener_dict_to_provider_dict(listener_dict, for_delete=False): new_listener_dict = _base_to_provider_dict(listener_dict, include_project_id=True) new_listener_dict['listener_id'] = new_listener_dict.pop('id') if 'load_balancer_id' in new_listener_dict: new_listener_dict['loadbalancer_id'] = new_listener_dict.pop( 'load_balancer_id') # Pull the certs out of the certificate manager to pass to the provider if 'tls_certificate_id' in new_listener_dict: new_listener_dict['default_tls_container_ref'] = new_listener_dict.pop( 'tls_certificate_id') if 'sni_containers' in new_listener_dict: sni_refs = [] sni_containers = new_listener_dict.pop('sni_containers') for sni in sni_containers: if 'tls_container_id' in sni: sni_refs.append(sni['tls_container_id']) else: raise exceptions.ValidationException( detail=_('Invalid SNI container on listener')) new_listener_dict['sni_container_refs'] = sni_refs if 'sni_container_refs' in listener_dict: listener_dict['sni_containers'] = listener_dict.pop( 'sni_container_refs') if 'client_ca_tls_certificate_id' in new_listener_dict: new_listener_dict['client_ca_tls_container_ref'] = ( new_listener_dict.pop('client_ca_tls_certificate_id')) if 'client_crl_container_id' in new_listener_dict: new_listener_dict['client_crl_container_ref'] = ( new_listener_dict.pop('client_crl_container_id')) listener_obj = data_models.Listener(**listener_dict) if (listener_obj.tls_certificate_id or listener_obj.sni_containers or listener_obj.client_ca_tls_certificate_id): SNI_objs = [] for sni in listener_obj.sni_containers: if isinstance(sni, dict): if 'listener' in sni: del sni['listener'] sni_obj = data_models.SNI(**sni) SNI_objs.append(sni_obj) elif isinstance(sni, six.string_types): sni_obj = data_models.SNI(tls_container_id=sni) SNI_objs.append(sni_obj) else: raise exceptions.ValidationException( detail=_('Invalid SNI container on listener')) listener_obj.sni_containers = SNI_objs cert_manager = stevedore_driver.DriverManager( namespace='octavia.cert_manager', name=CONF.certificates.cert_manager, invoke_on_load=True, ).driver try: cert_dict = cert_parser.load_certificates_data( cert_manager, listener_obj) except Exception as e: with excutils.save_and_reraise_exception() as ctxt: LOG.warning('Unable to retrieve certificate(s) due to %s.', str(e)) if for_delete: ctxt.reraise = False cert_dict = {} if 'tls_cert' in cert_dict and cert_dict['tls_cert']: new_listener_dict['default_tls_container_data'] = ( cert_dict['tls_cert'].to_dict(recurse=True)) if 'sni_certs' in cert_dict and cert_dict['sni_certs']: sni_data_list = [] for sni in cert_dict['sni_certs']: sni_data_list.append(sni.to_dict(recurse=True)) new_listener_dict['sni_container_data'] = sni_data_list if listener_obj.client_ca_tls_certificate_id: cert = _get_secret_data(cert_manager, listener_obj.project_id, listener_obj.client_ca_tls_certificate_id) new_listener_dict['client_ca_tls_container_data'] = cert if listener_obj.client_crl_container_id: crl_file = _get_secret_data(cert_manager, listener_obj.project_id, listener_obj.client_crl_container_id) new_listener_dict['client_crl_container_data'] = crl_file # Format the allowed_cidrs if ('allowed_cidrs' in new_listener_dict and new_listener_dict['allowed_cidrs'] and 'cidr' in new_listener_dict['allowed_cidrs'][0]): cidrs_dict_list = new_listener_dict.pop('allowed_cidrs') new_listener_dict['allowed_cidrs'] = [ cidr_dict['cidr'] for cidr_dict in cidrs_dict_list ] # Remove the DB back references if 'load_balancer' in new_listener_dict: del new_listener_dict['load_balancer'] if 'peer_port' in new_listener_dict: del new_listener_dict['peer_port'] if 'pools' in new_listener_dict: del new_listener_dict['pools'] if 'stats' in new_listener_dict: del new_listener_dict['stats'] if ('default_pool' in new_listener_dict and new_listener_dict['default_pool']): pool = new_listener_dict.pop('default_pool') new_listener_dict['default_pool'] = pool_dict_to_provider_dict( pool, for_delete=for_delete) provider_l7policies = [] if 'l7policies' in new_listener_dict: l7policies = new_listener_dict.pop('l7policies') or [] for l7policy in l7policies: provider_l7policy = l7policy_dict_to_provider_dict(l7policy) provider_l7policies.append(provider_l7policy) new_listener_dict['l7policies'] = provider_l7policies return new_listener_dict
class L7RuleValidation(APIException): msg = _("Error parsing L7Rule: %(error)s") code = 400
class EnableFailed(AmphoraDriverError): message = _('this load balancer couldn\'t be enabled')
class InvalidOption(APIException): msg = _("%(value)s is not a valid option for %(option)s") code = 400
class ArchiveException(AmphoraDriverError): message = _('couldn\'t archive the logs')
class MetricsException(AmphoraDriverError): message = _('gathering metrics failed')
class ListenerProvisioningError(ProvisioningErrors): message = _('couldn\'t provision Listener')
def qos_extension_enabled(network_driver): if not network_driver.qos_enabled(): raise exceptions.ValidationException(detail=_( "VIP QoS policy is not allowed in this deployment."))
class HealthMonitorProvisioningError(ProvisioningErrors): message = _('couldn\'t provision HealthMonitor')
class NotFoundError(AmphoraDriverError): message = _('this amphora couldn\'t be found')
LOG = logging.getLogger(__name__) EXTRA_LOG_LEVEL_DEFAULTS = [ 'neutronclient.v2_0.client=INFO', ] TLS_PROTOCOL_CHOICES = [ p[9:].replace('_', '.') for p in ssl._PROTOCOL_NAMES.values() ] core_opts = [ cfg.HostnameOpt('host', default=utils.get_hostname(), sample_default='<server-hostname.example.com>', help=_("The hostname Octavia is running on")), cfg.StrOpt('octavia_plugins', default='hot_plug_plugin', help=_("Name of the controller plugin to use")), ] api_opts = [ cfg.IPOpt('bind_host', default='127.0.0.1', help=_("The host IP to bind to")), cfg.PortOpt('bind_port', default=9876, help=_("The port to bind to")), cfg.StrOpt( 'auth_strategy', default=constants.KEYSTONE, choices=[constants.NOAUTH, constants.KEYSTONE, constants.TESTING], help=_("The auth strategy for API requests.")),
class InfoException(AmphoraDriverError): message = _('gathering information about this amphora failed')