Exemplo n.º 1
0
    def add_machine_wrapper(self, name, fail_on_error=True,
                            fail_on_invalid_params=True, monitoring=False,
                            **kwargs):
        """Wrapper around add_machine for kwargs backwards compatibity

        FIXME: This wrapper should be deprecated

        """

        # Sanitize params.
        rename_kwargs(kwargs, 'machine_ip', 'host')
        rename_kwargs(kwargs, 'machine_user', 'ssh_user')
        rename_kwargs(kwargs, 'machine_key', 'ssh_key')
        rename_kwargs(kwargs, 'machine_port', 'ssh_port')
        rename_kwargs(kwargs, 'remote_desktop_port', 'rdp_port')
        if kwargs.get('operating_system') == 'windows':
            kwargs['os_type'] = 'windows'
        else:
            kwargs['os_type'] = 'unix'
        kwargs.pop('operating_system', None)
        errors = {}
        for key in list(kwargs.keys()):
            if key not in ('host', 'ssh_user', 'ssh_port', 'ssh_key',
                           'os_type', 'rdp_port'):
                error = "Invalid parameter %s=%r." % (key, kwargs[key])
                if fail_on_invalid_params:
                    errors[key] = error
                else:
                    log.warning(error)
                    kwargs.pop(key)
        if 'host' not in kwargs:
            errors['host'] = "Required parameter host missing"
            log.error(errors['host'])

        if not name:
            name = kwargs['host']

        if errors:
            log.error("Invalid parameters %s." % list(errors.keys()))
            raise BadRequestError({
                'msg': "Invalid parameters %s." % list(errors.keys()),
                'errors': errors,
            })

        # Add the machine.
        machine = self.add_machine(name, fail_on_error=fail_on_error, **kwargs)

        # Enable monitoring.
        if monitoring:
            from mist.api.monitoring.methods import enable_monitoring
            from mist.api.machines.models import KeyMachineAssociation
            enable_monitoring(
                self.cloud.owner, self.cloud.id, machine.machine_id,
                no_ssh=not (machine.os_type == 'unix' and
                            KeyMachineAssociation.objects(
                                machine=machine).count())
            )

        return machine
Exemplo n.º 2
0
    def add(self, fail_on_error=True, fail_on_invalid_params=True, **kwargs):
        """Add new Cloud to the database

        This is only expected to be called by `Cloud.add` classmethod to create
        a cloud. Fields `owner` and `title` are already populated in
        `self.cloud`. The `self.cloud` model is not yet saved.

        Params:
        fail_on_error: If True, then a connection to the cloud will be
            established and if it fails, a `CloudUnavailableError` or
            `CloudUnauthorizedError` will be raised and the cloud will be
            deleted.
        fail_on_invalid_params: If True, then invalid keys in `kwargs` will
            raise an Error.

        Subclasses SHOULD NOT override or extend this method.

        If a subclass has to perform special parsing of `kwargs`, it can
        override `self._add__preparse_kwargs`.

        """
        # Transform params with extra underscores for compatibility.
        rename_kwargs(kwargs, 'api_key', 'apikey')
        rename_kwargs(kwargs, 'api_secret', 'apisecret')

        # Cloud specific argument preparsing cloud-wide argument
        self.cloud.dns_enabled = kwargs.pop('dns_enabled', False) is True
        self.cloud.observation_logs_enabled = True
        self.cloud.polling_interval = kwargs.pop('polling_interval', 30 * 60)

        # Cloud specific kwargs preparsing.
        try:
            self._add__preparse_kwargs(kwargs)
        except MistError as exc:
            log.error("Error while adding cloud %s: %r", self.cloud, exc)
            raise
        except Exception as exc:
            log.exception("Error while preparsing kwargs on add %s",
                          self.cloud)
            raise InternalServerError(exc=exc)

        try:
            self.update(fail_on_error=fail_on_error,
                        fail_on_invalid_params=fail_on_invalid_params,
                        **kwargs)
        except (CloudUnavailableError, CloudUnauthorizedError) as exc:
            # FIXME: Move this to top of the file once Machine model is
            # migrated.  The import statement is currently here to avoid
            # circular import issues.
            from mist.api.machines.models import Machine
            # Remove any machines created from check_connection performing a
            # list_machines.
            Machine.objects(cloud=self.cloud).delete()
            # Propagate original error.
            raise

        # Add relevant polling schedules.
        self.add_polling_schedules()
Exemplo n.º 3
0
 def _update__preparse_kwargs(self, kwargs):
     rename_kwargs(kwargs, 'auth_url', 'url')
     rename_kwargs(kwargs, 'tenant_name', 'tenant')
     url = kwargs.get('url', self.cloud.url)
     if url:
         if url.endswith('/v2.0/'):
             url = url.split('/v2.0/')[0]
         elif url.endswith('/v2.0'):
             url = url.split('/v2.0')[0]
         kwargs['url'] = url.rstrip('/')
         check_host(sanitize_host(kwargs['url']))
Exemplo n.º 4
0
    def add(self, fail_on_invalid_params=True, **kwargs):
        """Add an entry to the database

        This is only to be called by `Key.add` classmethod to create
        a key. Fields `owner` and `name` are already populated in
        `self.key`. The `self.key` is not yet saved.

        """
        from mist.api.keys.models import Key

        rename_kwargs(kwargs, 'priv', 'private')
        # Check for invalid `kwargs` keys.
        errors = {}
        for key in kwargs:
            if key not in self.key._key_specific_fields:
                error = "Invalid parameter %s=%r." % (key, kwargs[key])
                if fail_on_invalid_params:
                    errors[key] = error
                else:
                    log.warning(error)
                    kwargs.pop(key)
        if errors:
            log.error("Error adding %s: %s", self.key, errors)
            raise BadRequestError({
                'msg':
                "Invalid parameters %s." % errors.keys(),
                'errors':
                errors,
            })

        for key, value in kwargs.iteritems():
            setattr(self.key, key, value)

        if not Key.objects(owner=self.key.owner, default=True):
            self.key.default = True

        try:
            self.key.save()
        except me.ValidationError as exc:
            log.error("Error adding %s: %s", self.key.name, exc.to_dict())
            raise BadRequestError({
                'msg': exc.message,
                'errors': exc.to_dict()
            })
        except me.NotUniqueError as exc:
            log.error("Key %s not unique error: %s", self.key.name, exc)
            raise KeyExistsError()

        # SEC
        self.key.owner.mapper.update(self.key)

        log.info("Added key with name '%s'", self.key.name)
        trigger_session_update(self.key.owner, ['keys'])
Exemplo n.º 5
0
 def _add__preparse_kwargs(self, kwargs):
     rename_kwargs(kwargs, 'machine_hostname', 'host')
     rename_kwargs(kwargs, 'machine_name', 'alias')
     rename_kwargs(kwargs, 'machine_user', 'username')
     rename_kwargs(kwargs, 'machine_key', 'key')
     rename_kwargs(kwargs, 'ssh_port', 'port')
     if kwargs.get('host'):
         kwargs['host'] = sanitize_host(kwargs['host'])
         check_host(kwargs['host'])
     if kwargs.get('key'):
         try:
             kwargs['key'] = Key.objects.get(owner=self.cloud.owner,
                                             id=kwargs['key'],
                                             deleted=None)
         except Key.DoesNotExist:
             raise NotFoundError("Key does not exist.")
Exemplo n.º 6
0
 def _update__preparse_kwargs(self, kwargs):
     kwargs.pop('authentication', None)
     rename_kwargs(kwargs, 'docker_port', 'port')
     rename_kwargs(kwargs, 'docker_host', 'host')
     rename_kwargs(kwargs, 'auth_user', 'username')
     rename_kwargs(kwargs, 'auth_password', 'password')
     host = kwargs.get('host', self.cloud.host)
     if host:
         host = sanitize_host(host)
         check_host(host)
Exemplo n.º 7
0
def _log_alert(resource,
               rule,
               value,
               triggered,
               timestamp,
               incident_id,
               action='',
               **kwargs):
    """Create a log entry for the triggered rule. Any special pre-processing
    of the log entry, such as renaming dict keys, should be taken care of at
    this point."""
    # Get dict with alert details.
    info = _get_alert_details(resource, rule, incident_id, value, triggered,
                              timestamp, action)

    # Get the resource's type. This will be set to None for arbitrary rules.
    resource_type = info.pop('resource_type', None)

    # Set of keys to remove.
    for key in (
            'uri',
            'name',
            'time',
            'since',
            'action',
            'incident_id',
            'resource_repr',
            'machine_link',
    ):
        if key in info:
            info.pop(key)

    # Rename resource-agnostic keys, if applicable.
    if resource_type is not None:
        for key in list(info.keys()):
            if key.startswith('resource_'):
                rename_kwargs(info, key, key.replace('resource',
                                                     resource_type))

    # Rename arbitrary keys.
    rename_kwargs(info, 'curr_value', 'value')
    rename_kwargs(info, 'action', 'rule_action')

    # FIXME For backwards compability.
    if isinstance(resource, Machine):
        info['cloud_id'] = resource.cloud.id
        info['machine_id'] = resource.id
        info['external_id'] = resource.machine_id

    # Update info with additional kwargs.
    info.update(kwargs)
    info.pop('owner_id', None)
    # Log the alert.
    log_event(owner_id=rule.owner_id,
              event_type='incident',
              incident_id=incident_id,
              action='rule_triggered' if triggered else 'rule_untriggered',
              **info)
Exemplo n.º 8
0
    def add_machine_wrapper(self, name, fail_on_error=True,
                            fail_on_invalid_params=True, **kwargs):
        """Wrapper around add_machine for kwargs backwards compatibity

        FIXME: This wrapper should be deprecated

        """
        # Sanitize params.
        rename_kwargs(kwargs, 'machine_ip', 'host')
        rename_kwargs(kwargs, 'machine_user', 'ssh_user')
        rename_kwargs(kwargs, 'machine_key', 'ssh_key')
        rename_kwargs(kwargs, 'machine_port', 'ssh_port')
        rename_kwargs(kwargs, 'remote_desktop_port', 'rdp_port')
        if kwargs.get('operating_system') == 'windows':
            kwargs['os_type'] = 'windows'
        else:
            kwargs['os_type'] = 'unix'
        kwargs.pop('operating_system', None)
        errors = {}
        for key in kwargs.keys():
            if key not in ('host', 'ssh_user', 'ssh_port', 'ssh_key',
                           'os_type', 'rdp_port'):
                error = "Invalid parameter %s=%r." % (key, kwargs[key])
                if fail_on_invalid_params:
                    errors[key] = error
                else:
                    log.warning(error)
                    kwargs.pop(key)
        if errors:
            raise BadRequestError({
                'msg': "Invalid parameters %s." % errors.keys(),
                'errors': errors,
            })

        # Add machine.
        return self.add_machine(name, fail_on_error=fail_on_error,
                                **kwargs)
Exemplo n.º 9
0
    def update(self,
               fail_on_error=True,
               fail_on_invalid_params=True,
               **kwargs):
        """Edit an existing Cloud

        Params:
        fail_on_error: If True, then a connection to the cloud will be
            established and if it fails, a `CloudUnavailableError` or
            `CloudUnauthorizedError` will be raised and the cloud changes will
            not be saved.
        fail_on_invalid_params: If True, then invalid keys in `kwargs` will
            raise an Error.

        Subclasses SHOULD NOT override or extend this method.

        If a subclass has to perform special parsing of `kwargs`, it can
        override `self._update__preparse_kwargs`.

        """

        # Close previous connection.
        self.disconnect()

        # Transform params with extra underscores for compatibility.
        rename_kwargs(kwargs, 'api_key', 'apikey')
        rename_kwargs(kwargs, 'api_secret', 'apisecret')

        # Cloud specific kwargs preparsing.
        try:
            self._update__preparse_kwargs(kwargs)
        except MistError as exc:
            log.error("Error while updating cloud %s: %r", self.cloud, exc)
            raise
        except Exception as exc:
            log.exception("Error while preparsing kwargs on update %s",
                          self.cloud)
            raise InternalServerError(exc=exc)

        # Check for invalid `kwargs` keys.
        errors = {}
        for key in list(kwargs.keys()):
            if key not in self.cloud._cloud_specific_fields:
                error = "Invalid parameter %s=%r." % (key, kwargs[key])
                if fail_on_invalid_params:
                    errors[key] = error
                else:
                    log.warning(error)
                    kwargs.pop(key)
        if errors:
            log.error("Error updating %s: %s", self.cloud, errors)
            raise BadRequestError({
                'msg':
                "Invalid parameters %s." % list(errors.keys()),
                'errors':
                errors,
            })

        # Set fields to cloud model and perform early validation.
        for key, value in kwargs.items():
            setattr(self.cloud, key, value)
        try:
            self.cloud.validate(clean=True)
        except me.ValidationError as exc:
            log.error("Error updating %s: %s", self.cloud, exc.to_dict())
            raise BadRequestError({'msg': str(exc), 'errors': exc.to_dict()})

        # Try to connect to cloud.
        if fail_on_error:
            try:
                self.compute.check_connection()
            except (CloudUnavailableError, CloudUnauthorizedError,
                    SSLError) as exc:
                log.error(
                    "Will not update cloud %s because "
                    "we couldn't connect: %r", self.cloud, exc)
                raise
            except Exception as exc:
                log.exception(
                    "Will not update cloud %s because "
                    "we couldn't connect.", self.cloud)
                raise CloudUnavailableError(exc=exc)

        # Attempt to save.
        try:
            self.cloud.save()
        except me.ValidationError as exc:
            log.error("Error updating %s: %s", self.cloud, exc.to_dict())
            raise BadRequestError({'msg': str(exc), 'errors': exc.to_dict()})
        except me.NotUniqueError as exc:
            log.error("Cloud %s not unique error: %s", self.cloud, exc)
            raise CloudExistsError()
Exemplo n.º 10
0
 def _create_subnet__prepare_args(self, subnet, kwargs):
     kwargs['vpc_id'] = subnet.network.network_id
     rename_kwargs(kwargs, 'cidr', 'cidr_block')
Exemplo n.º 11
0
 def _create_network__prepare_args(self, kwargs):
     rename_kwargs(kwargs, 'cidr', 'cidr_block')