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
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()
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']))
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'])
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.")
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)
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)
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)
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()
def _create_subnet__prepare_args(self, subnet, kwargs): kwargs['vpc_id'] = subnet.network.network_id rename_kwargs(kwargs, 'cidr', 'cidr_block')
def _create_network__prepare_args(self, kwargs): rename_kwargs(kwargs, 'cidr', 'cidr_block')