Example #1
0
def db_sync(version=None, init_version=INIT_VERSION, engine=None):
    if engine is None:
        engine = db_api.get_engine()

    current_db_version = get_backend().db_version(engine, MIGRATE_REPO_PATH,
                                                  init_version)

    if version and int(version) < current_db_version:
        msg = _('Database schema downgrade is not allowed.')
        raise exception.InvalidInput(reason=msg)

    if version and int(version) > db.MAX_INT:
        message = _(
            'Version should be less than or equal to %(max_version)d.') % {
                'max_version': db.MAX_INT
            }
        raise exception.InvalidInput(reason=message)

    try:
        return get_backend().db_sync(engine=engine,
                                     abs_path=MIGRATE_REPO_PATH,
                                     version=version,
                                     init_version=init_version)
    except oslo_exception.DBMigrationError as exc:
        raise exception.InvalidInput(reason=exc)
Example #2
0
    def __init__(self, name, loader=None, use_ssl=False, max_url_len=None):
        """Initialize, but do not start the WSGI server.

        :param name: The name of the WSGI server given to the loader.
        :param loader: Loads the WSGI application using the given name.
        :returns: None
        """
        self.name = name
        self.binary = 'masakari-%s' % name
        self.topic = None
        self.loader = loader or wsgi.Loader()
        self.app = self.loader.load_app(name)
        self.host = getattr(CONF, '%s_listen' % name, "0.0.0.0")
        self.port = getattr(CONF, '%s_listen_port' % name, 0)

        self.workers = (getattr(CONF, '%s_workers' % name, None)
                        or processutils.get_worker_count())

        if self.workers and self.workers < 1:
            worker_name = '%s_workers' % name
            msg = (_("%(worker_name)s value of %(workers)s is invalid, "
                     "must be greater than 0") % {
                         'worker_name': worker_name,
                         'workers': str(self.workers)
                     })
            raise exception.InvalidInput(msg)

        self.use_ssl = use_ssl
        self.server = wsgi.Server(name,
                                  self.app,
                                  host=self.host,
                                  port=self.port,
                                  use_ssl=self.use_ssl,
                                  max_url_len=max_url_len)
Example #3
0
    def test_host_create_exception(self, mock_get, mock_notify_about_host_api,
                                   mock_find_compute_service, mock_host_obj,
                                   mock_host_create):
        mock_get.return_value = self.failover_segment
        host_data = {
            "name": "host-1",
            "type": "fake-type",
            "reserved": False,
            "on_maintenance": False,
            "control_attributes": "fake-control_attributes"
        }

        e = exception.InvalidInput(reason="TEST")
        mock_host_obj.side_effect = e
        mock_notify_about_host_api.return_value = mock.Mock()

        self.assertRaises(exception.InvalidInput, self.host_api.create_host,
                          self.context, uuidsentinel.fake_segment1, host_data)
        action = fields.EventNotificationAction.HOST_CREATE
        phase_error = fields.EventNotificationPhase.ERROR
        notify_calls = [
            mock.call(self.context,
                      mock.ANY,
                      action=action,
                      phase=phase_error,
                      exception=e,
                      tb=mock.ANY)
        ]
        mock_notify_about_host_api.assert_has_calls(notify_calls)
        mock_find_compute_service.assert_called_once()
Example #4
0
    def test_segment_delete_exception(self, mock_get,
                                      mock_notify_about_segment_api,
                                      mock_segment_destroy,
                                      mock_is_under_recovery):
        mock_get.return_value = self.failover_segment
        mock_is_under_recovery.return_value = False
        e = exception.InvalidInput(reason="TEST")
        mock_segment_destroy.side_effect = e
        mock_notify_about_segment_api.return_value = mock.Mock()

        self.assertRaises(exception.InvalidInput,
                          self.segment_api.delete_segment, self.context,
                          uuidsentinel.fake_segment)

        action = fields.EventNotificationAction.SEGMENT_DELETE
        phase_error = fields.EventNotificationPhase.ERROR
        notify_calls = [
            mock.call(self.context,
                      mock.ANY,
                      action=action,
                      phase=phase_error,
                      exception=e,
                      tb=mock.ANY)
        ]
        mock_notify_about_segment_api.assert_has_calls(notify_calls)
Example #5
0
    def test_segment_update_exception(self, mock_get,
                                      mock_notify_about_segment_api,
                                      mock_segment_update,
                                      mock_is_under_recovery):
        mock_get.return_value = self.failover_segment
        segment_data = {
            "name": "segment1",
            "service_type": "COMPUTE",
            "recovery_method": "auto",
            "description": "something"
        }
        e = exception.InvalidInput(reason="TEST")
        mock_segment_update.side_effect = e
        mock_is_under_recovery.return_value = False
        mock_notify_about_segment_api.return_value = mock.Mock()

        self.assertRaises(exception.InvalidInput,
                          self.segment_api.update_segment, self.context,
                          uuidsentinel.fake_segment, segment_data)
        action = fields.EventNotificationAction.SEGMENT_UPDATE
        phase_error = fields.EventNotificationPhase.ERROR
        notify_calls = [
            mock.call(self.context,
                      mock.ANY,
                      action=action,
                      phase=phase_error,
                      exception=e,
                      tb=mock.ANY)
        ]
        mock_notify_about_segment_api.assert_has_calls(notify_calls)
Example #6
0
    def test_host_update_exception(self, mock_segment_get, mock_get,
                                   mock_notify_about_host_api, mock_host_obj,
                                   mock_hypervisor_search,
                                   mock_is_under_recovery):
        mock_segment_get.return_value = self.failover_segment
        host_data = {"name": "host_1"}
        mock_get.return_value = self.host
        e = exception.InvalidInput(reason="TEST")
        mock_host_obj.side_effect = e
        mock_is_under_recovery.return_value = False
        mock_notify_about_host_api.return_value = mock.Mock()

        self.assertRaises(exception.InvalidInput, self.host_api.update_host,
                          self.context, uuidsentinel.fake_segment,
                          uuidsentinel.fake_host_1, host_data)
        action = fields.EventNotificationAction.HOST_UPDATE
        phase_error = fields.EventNotificationPhase.ERROR
        notify_calls = [
            mock.call(self.context,
                      mock.ANY,
                      action=action,
                      phase=phase_error,
                      exception=e,
                      tb=mock.ANY)
        ]
        mock_notify_about_host_api.assert_has_calls(notify_calls)
Example #7
0
    def test_get_all_invalid_sort_dir(self, mock_get_all):

        mock_get_all.side_effect = exception.InvalidInput(
            reason="Unknown sort direction, must be 'asc' or 'desc'")
        self.req = fakes.HTTPRequest.blank('/v1/notifications?sort_dir=abcd',
                                           use_admin_context=True)
        self.assertRaises(exception.InvalidInput,
                          self.notification_api.get_all, self.context,
                          self.req)
Example #8
0
    def test_get_all_invalid_sort_dir(self, mock_get_all):

        mock_get_all.side_effect = exception.InvalidInput(
            reason="Unknown sort direction, must be 'asc' or 'desc'")
        self.assertRaises(exception.InvalidInput,
                          self.segment_api.get_all,
                          self.context,
                          filters=None,
                          sort_keys=None,
                          sort_dirs=['abcd'],
                          limit=None,
                          marker=None)
Example #9
0
def validate_integer(value, name, min_value=None, max_value=None):
    """Make sure that value is a valid integer, potentially within range."""
    try:
        value = int(str(value))
    except (ValueError, UnicodeEncodeError):
        msg = _('%(value_name)s must be an integer')
        raise exception.InvalidInput(reason=(msg % {'value_name': name}))

    if min_value is not None:
        if value < min_value:
            msg = _('%(value_name)s must be >= %(min_value)d')
            raise exception.InvalidInput(reason=(msg % {
                'value_name': name,
                'min_value': min_value
            }))
    if max_value is not None:
        if value > max_value:
            msg = _('%(value_name)s must be <= %(max_value)d')
            raise exception.InvalidInput(reason=(msg % {
                'value_name': name,
                'max_value': max_value
            }))
    return value
Example #10
0
    def test_create_notification_exception(self, mock_host_obj,
                                           mock_notification_obj, mock_get_all,
                                           mock_notify_about_notification_api):
        fake_notification = fakes_data.create_fake_notification(
            type="COMPUTE_HOST",
            id=2,
            payload={
                'event': 'STARTED',
                'host_status': 'NORMAL',
                'cluster_status': 'ONLINE'
            },
            source_host_uuid=uuidsentinel.fake_host,
            generated_time=NOW,
            status="running",
            notification_uuid=uuidsentinel.fake_notification_2)
        fake_notification_list = [self.notification, fake_notification]
        mock_get_all.return_value = fake_notification_list
        notification_data = {
            "hostname": "fake_host",
            "payload": {
                "event": "STARTED",
                "host_status": "NORMAL",
                "cluster_status": "OFFLINE"
            },
            "type": "VM",
            "generated_time": "2016-10-13T09:11:21.656788"
        }
        mock_host_obj.return_value = self.host
        e = exception.InvalidInput(reason="TEST")
        mock_notification_obj.side_effect = e
        mock_notify_about_notification_api.return_value = mock.Mock()

        self.assertRaises(exception.InvalidInput,
                          self.notification_api.create_notification,
                          self.context, notification_data)

        action = fields.EventNotificationAction.NOTIFICATION_CREATE
        phase_error = fields.EventNotificationPhase.ERROR
        notify_calls = [
            mock.call(self.context,
                      mock.ANY,
                      action=action,
                      phase=phase_error,
                      exception=e,
                      tb=mock.ANY)
        ]
        mock_notify_about_notification_api.assert_has_calls(notify_calls)
Example #11
0
 def wrapper(self, ctx, *args, **kwargs):
     try:
         res = method(self, ctx, *args, **kwargs)
     except (request_exceptions.Timeout, nova_exception.CommandError,
             keystone_exception.ConnectionError) as exc:
         err_msg = encodeutils.exception_to_unicode(exc)
         _reraise(exception.MasakariException(reason=err_msg))
     except (keystone_exception.BadRequest,
             nova_exception.BadRequest) as exc:
         err_msg = encodeutils.exception_to_unicode(exc)
         _reraise(exception.InvalidInput(reason=err_msg))
     except (keystone_exception.Forbidden, nova_exception.Forbidden) as exc:
         err_msg = encodeutils.exception_to_unicode(exc)
         _reraise(exception.Forbidden(err_msg))
     except (nova_exception.NotFound) as exc:
         err_msg = encodeutils.exception_to_unicode(exc)
         _reraise(exception.NotFound(reason=err_msg))
     except nova_exception.Conflict as exc:
         err_msg = encodeutils.exception_to_unicode(exc)
         _reraise(exception.Conflict(reason=err_msg))
     return res
Example #12
0
def _process_sort_params(sort_keys,
                         sort_dirs,
                         default_keys=['created_at', 'id'],
                         default_dir='desc'):
    """Process the sort parameters to include default keys.

    Creates a list of sort keys and a list of sort directions. Adds the default
    keys to the end of the list if they are not already included.

    When adding the default keys to the sort keys list, the associated
    direction is:
    1) The first element in the 'sort_dirs' list (if specified), else
    2) 'default_dir' value (Note that 'asc' is the default value since this is
    the default in sqlalchemy.utils.paginate_query)

    :param sort_keys: List of sort keys to include in the processed list
    :param sort_dirs: List of sort directions to include in the processed list
    :param default_keys: List of sort keys that need to be included in the
                         processed list, they are added at the end of the list
                         if not already specified.
    :param default_dir: Sort direction associated with each of the default
                        keys that are not supplied, used when they are added
                        to the processed list
    :returns: list of sort keys, list of sort directions
    :raise exception.InvalidInput: If more sort directions than sort keys
                                   are specified or if an invalid sort
                                   direction is specified
    """
    # Determine direction to use for when adding default keys
    default_dir_value = default_dir
    if sort_dirs and len(sort_dirs) != 0:
        default_dir_value = sort_dirs[0]

    # Create list of keys (do not modify the input list)
    result_keys = []
    if sort_keys:
        result_keys = list(sort_keys)

    # If a list of directions is not provided, use the default sort direction
    # for all provided keys
    if sort_dirs:
        result_dirs = []
        # Verify sort direction
        for sort_dir in sort_dirs:
            if sort_dir not in ('asc', 'desc'):
                msg = _("Unknown sort direction, must be 'asc' or 'desc'")
                raise exception.InvalidInput(reason=msg)
            result_dirs.append(sort_dir)
    else:
        result_dirs = [default_dir_value for _sort_key in result_keys]

    # Ensure that the key and direction length match
    while len(result_dirs) < len(result_keys):
        result_dirs.append(default_dir_value)
    # Unless more direction are specified, which is an error
    if len(result_dirs) > len(result_keys):
        msg = _("Sort direction size exceeds sort key size")
        raise exception.InvalidInput(reason=msg)

    # Ensure defaults are included
    for key in default_keys:
        if key not in result_keys:
            result_keys.append(key)
            result_dirs.append(default_dir_value)

    return result_keys, result_dirs
Example #13
0
    def __init__(self,
                 name,
                 app,
                 host='0.0.0.0',
                 port=0,
                 pool_size=None,
                 protocol=eventlet.wsgi.HttpProtocol,
                 backlog=128,
                 use_ssl=False,
                 max_url_len=None):
        """Initialize, but do not start, a WSGI server.

        :param name: Pretty name for logging.
        :param app: The WSGI application to serve.
        :param host: IP address to serve the application.
        :param port: Port number to server the application.
        :param pool_size: Maximum number of eventlets to spawn concurrently.
        :param backlog: Maximum number of queued connections.
        :param max_url_len: Maximum length of permitted URLs.
        :returns: None
        :raises: masakari.exception.InvalidInput
        """
        # Allow operators to customize http requests max header line size.
        eventlet.wsgi.MAX_HEADER_LINE = CONF.wsgi.max_header_line
        self.name = name
        self.app = app
        self._server = None
        self._protocol = protocol
        self.pool_size = pool_size or self.default_pool_size
        self._pool = eventlet.GreenPool(self.pool_size)
        self._logger = logging.getLogger("masakari.%s.wsgi.server" % self.name)
        self._use_ssl = use_ssl
        self._max_url_len = max_url_len

        self.client_socket_timeout = CONF.wsgi.client_socket_timeout or None

        if backlog < 1:
            raise exception.InvalidInput(
                reason=_('The backlog must be more than 0'))

        bind_addr = (host, port)
        try:
            info = socket.getaddrinfo(bind_addr[0], bind_addr[1],
                                      socket.AF_UNSPEC, socket.SOCK_STREAM)[0]
            family = info[0]
            bind_addr = info[-1]
        except Exception:
            family = socket.AF_INET

        try:
            self._socket = eventlet.listen(bind_addr, family, backlog=backlog)
        except EnvironmentError:
            LOG.error("Could not bind to %(host)s:%(port)d", {
                'host': host,
                'port': port
            })
            raise

        (self.host, self.port) = self._socket.getsockname()[0:2]
        LOG.info("%(name)s listening on %(host)s:%(port)d", {
            'name': self.name,
            'host': self.host,
            'port': self.port
        })
Example #14
0
def validate_integer(value, name, min_value=None, max_value=None):
    """Make sure that value is a valid integer, potentially within range."""
    try:
        return strutils.validate_integer(value, name, min_value, max_value)
    except ValueError as e:
        raise exception.InvalidInput(reason=e)