def toggle_cloud(request): """ Tags: clouds --- Toggles cloud with given cloud id. EDIT permission required on cloud. --- cloud_id: in: path required: true type: string new_state: enum: - '0' - '1' required: true type: string """ auth_context = auth_context_from_request(request) cloud_id = request.matchdict['cloud'] try: cloud = Cloud.objects.get(owner=auth_context.owner, id=cloud_id, deleted=None) except Cloud.DoesNotExist: raise NotFoundError('Cloud does not exist') auth_context.check_perm('cloud', 'edit', cloud_id) new_state = params_from_request(request).get('new_state', None) dns_enabled = params_from_request(request).get('dns_enabled', None) if new_state == '1': cloud.ctl.enable() elif new_state == '0': cloud.ctl.disable() elif new_state: raise BadRequestError('Invalid cloud state') if dns_enabled == 1: cloud.ctl.dns_enable() elif dns_enabled == 0: cloud.ctl.dns_disable() elif dns_enabled: raise BadRequestError('Invalid DNS state') if new_state is None and dns_enabled is None: raise RequiredParameterMissingError('new_state or dns_enabled') trigger_session_update(auth_context.owner, ['clouds']) return OK
def get_stats(request): """ Tags: monitoring --- Request monitoring data for a machine --- machine: in: path type: string required: true start: in: query type: string default: now required: false description: time (eg. '10s') since when to fetch stats stop: in: query type: string required: false description: time until when to fetch stats step: in: query type: string required: false description: step to fetch stats, used in aggregations metrics: in: query type: string required: false request_id: in: query type: string required: false """ machine = _machine_from_matchdict(request) if not machine.monitoring.hasmonitoring: raise MethodNotAllowedError("Machine doesn't have monitoring enabled") # SEC require permission READ on machine auth_context = auth_context_from_request(request) auth_context.check_perm('machine', 'read', machine.id) params = params_from_request(request) start = params.get('start', '') stop = params.get('stop', '') step = params.get('step', '') try: metrics = params.getall('metrics') except: metrics = params.get('metrics') data = mist.api.monitoring.methods.get_stats(machine, start=start, stop=stop, step=step, metrics=metrics) data['request_id'] = params.get('request_id') return data
def rename_cloud(request): """ Rename a cloud Renames cloud with given cloud_id. EDIT permission required on cloud. --- cloud: in: path required: true type: string new_name: description: ' New name for the key (will also serve as the key''s id)' type: string """ auth_context = auth_context_from_request(request) cloud_id = request.matchdict['cloud'] try: Cloud.objects.get(owner=auth_context.owner, id=cloud_id, deleted=None) except Cloud.DoesNotExist: raise NotFoundError('Cloud does not exist') params = params_from_request(request) new_name = params.get('new_name', '') if not new_name: raise RequiredParameterMissingError('new_name') auth_context.check_perm('cloud', 'edit', cloud_id) m_rename_cloud(auth_context.owner, cloud_id, new_name) return OK
def su(request): """ Impersonate another user. This allows an admin to take the identity of any other user. It is meant to be used strictly for debugging. You can return to your regular user simply by logging out. This won't affect the last login time of the actual user. An email should be immediately sent out to the team, notifying of the 'su' action for security reasons. """ # SEC raise exception if user not admin user = user_from_request(request, admin=True) session = request.environ['session'] if isinstance(session, ApiToken): raise ForbiddenError('Cannot do su when authenticated with api token') real_email = user.email params = params_from_request(request) email = params.get('email') if not email: raise RequiredParameterMissingError('email') try: user = User.objects.get(email=email) except (UserNotFoundError, User.DoesNotExist): raise UserUnauthorizedError() reissue_cookie_session(request, real_email, su=user.id) # alert admins subject = "Some admin used su" body = "Admin: %s\nUser: %s\nServer: %s" % (real_email, user.email, config.CORE_URI) send_email(subject, body, config.NOTIFICATION_EMAIL['ops']) return HTTPFound('/')
def set_script_tags(request): """ Tags: tags --- Set tags to owner's script. EDIT_TAGS permission required on SCRIPT --- script: in: path required: true type: string tags: type: dict required: true """ auth_context = auth_context_from_request(request) params = params_from_request(request) script_id = request.matchdict["script_id"] # SEC require EDIT_TAGS permission on script auth_context.check_perm("script", "edit_tags", script_id) script = Script.objects.get(owner=auth_context.owner, id=script_id, deleted=None) tags = params.get("tags") if type(tags) != dict: raise BadRequestError('tags should be dictionary of tags') if not modify_security_tags(auth_context, tags, script): raise auth_context._raise('script', 'edit_security_tags') return add_tags_to_resource(auth_context.owner, script, list(tags.items()))
def list_cloud_machines(request): """ Tags: machines --- Lists machines on cloud along with their metadata. Check Permissions takes place in filter_list_machines. READ permission required on cloud. READ permission required on machine. --- cloud: in: path required: true type: string """ auth_context = auth_context_from_request(request) cloud_id = request.matchdict['cloud'] params = params_from_request(request) cached = bool(params.get('cached', False)) # SEC get filtered resources based on auth_context try: Cloud.objects.get(owner=auth_context.owner, id=cloud_id, deleted=None) except Cloud.DoesNotExist: raise NotFoundError('Cloud does not exist') machines = methods.filter_list_machines(auth_context, cloud_id, cached=cached) return machines
def set_machine_tags(request): """ Set tags on a machine Set tags for a machine, given the cloud and machine id. READ permission required on cloud. EDIT_TAGS permission required on machine. --- cloud_id: in: path required: true type: string machine_id: in: path required: true type: string tags: items: type: object type: array """ auth_context = auth_context_from_request(request) params = params_from_request(request) cloud_id = request.matchdict["cloud_id"] machine_id = request.matchdict["machine_id"] auth_context.check_perm("cloud", "read", cloud_id) try: machine = Machine.objects.get(cloud=cloud_id, machine_id=machine_id) except me.DoesNotExist: raise NotFoundError('Resource with that id does not exist') # SEC require EDIT_TAGS permission on machine auth_context.check_perm("machine", "edit_tags", machine.id) tags = params.get("tags") if type(tags) != dict: raise BadRequestError('tags should be dictionary of tags') if not modify_security_tags(auth_context, tags, machine): raise auth_context._raise('machine', 'edit_security_tags') # FIXME: This is f***** up! This method is utilized by the Ember UI in # order to update a machine's tags by providing the entire list of tags # to be re-set. However, `add_tags_to_resource` simply appends the new # tags without deleting any. old_tags = get_tags_for_resource(auth_context.owner, machine) add_tags_to_resource(auth_context.owner, machine, tags.items()) if config.MACHINE_PATCHES: new_tags = get_tags_for_resource(auth_context.owner, machine) patch = jsonpatch.JsonPatch.from_diff(old_tags, new_tags).patch for item in patch: item['path'] = '/%s-%s/tags%s' % (machine.id, machine.machine_id, item['path']) amqp_publish_user(auth_context.owner.id, routing_key='patch_machines', data={'cloud_id': cloud_id, 'patch': patch}) return {}
def set_key_tags(request): """ Set tags to owner's key EDIT_TAGS permission required on KEY --- key_id: in: path required: true type: string tags: type: dict required: true """ auth_context = auth_context_from_request(request) params = params_from_request(request) key_id = request.matchdict["key_id"] # SEC require EDIT_TAGS permission on key auth_context.check_perm("key", "edit_tags", key_id) try: key = Key.objects.get(owner=auth_context.owner, id=key_id, deleted=None) except Key.DoesNotExist: raise NotFoundError('Resource with that id does not exist') tags = params.get("tags") if type(tags) != dict: raise BadRequestError('tags should be dictionary of tags') if not modify_security_tags(auth_context, tags, key): raise auth_context._raise('key', 'edit_security_tags') return add_tags_to_resource(auth_context.owner, key, tags.items())
def delete_account(request): """ A user requests his account to be deleted. In order to verify the request the user's password should be included as a parameter. """ email = request.matchdict['email'] params = params_from_request(request) plaintext_password = params.get('password', None) if not email: raise ValueError('No email provided') if config.SSO_TEST_EMAIL == "": raise MethodNotAllowedError("Configuration error") # SEC only allow test user to self delete if email != config.SSO_TEST_EMAIL: raise MethodNotAllowedError("This method is only for the test user") try: user = User.objects.get(email=email) except UserNotFoundError: return OK if not user.check_password(password=plaintext_password): raise MethodNotAllowedError("Password is wrong!!") user.delete() return OK
def edit_key(request): """ Edit a key Edits a given key's name to new_name EDIT permission required on key. --- new_name: description: The new key name type: string key_id: description: The key id in: path required: true type: string """ key_id = request.matchdict['key'] params = params_from_request(request) new_name = params.get('new_name') if not new_name: raise RequiredParameterMissingError("new_name") auth_context = auth_context_from_request(request) try: key = Key.objects.get(owner=auth_context.owner, id=key_id, deleted=None) except me.DoesNotExist: raise NotFoundError('Key with that id does not exist') auth_context.check_perm('key', 'edit', key.id) key.ctl.rename(new_name) return {'new_name': new_name}
def delete_key_tag(request): """ Tags: tags --- Deletes a tag in the db for specified resource_type. EDIT_TAGS permission required on key. --- tag_key: required: true type: string key_id: in: path required: true type: string """ auth_context = auth_context_from_request(request) params = params_from_request(request) key_id = request.matchdict["key_id"] tag_key = params.get("tag_key") # SEC require EDIT_TAGS permission on key auth_context.check_perm('key', 'edit_tags', key_id) if not delete_security_tag(auth_context, tag_key): raise auth_context._raise('key', 'edit_security_tags') return resolve_id_and_delete_tags(auth_context.owner, 'key', key_id, tags=[tag_key])
def suppressed_emails(request): params = dict(params_from_request(request).copy()) try: mac_verify(params) except Exception as exc: raise BadRequestError(str(exc)) try: decrypted_str = decrypt(params['token']) decrypted_json = json.loads(decrypted_str) except Exception as exc: log.exception(repr(exc)) raise BadRequestError() if decrypted_json.get('key') != Portal.get_singleton().external_api_key: raise NotFoundError() action = decrypted_json.get('action') if not action: raise RequiredParameterMissingError('action') if action == 'delete': Notification.objects(suppressed=True).delete() elif action == 'unsuppress': Notification.objects.update(suppressed=False) else: raise BadRequestError('Action "%s" not supported' % action) return Response("OK", 200)
def transfer_ownership_to_user(request): """ Tags: ownership --- Transfer ownership of a resource If a resource isn't owned by the requesting user, then an UnauthorizedError error will be thrown, unless the requesting user is a member of the Owners team. """ auth_context = auth_context_from_request(request) params = params_from_request(request) if not params.get('user_id'): raise RequiredParameterMissingError('user_id') try: new_owner = User.objects.get(id=params['user_id']) except User.DoesNotExist: raise NotFoundError('User with id %s' % params['user_id']) for rtype, rids in params.get('resources', {}).iteritems(): Model = get_resource_model(rtype) for rid in rids: try: resource = Model.objects.get(owner=auth_context.owner, id=rid) resource.transfer_ownership(auth_context, new_owner) except Model.DoesNotExist: raise NotFoundError('%s with id %s' % (rtype, rid)) trigger_session_update(auth_context.owner) return Response('OK', 200)
def set_cloud_tags(request): """ Tags: tags --- Set tags to owner's cloud. EDIT_TAGS permission required on SCRIPT --- tags: type: dict required: true """ auth_context = auth_context_from_request(request) params = params_from_request(request) cloud_id = request.matchdict["cloud_id"] # SEC require EDIT_TAGS permission on cloud auth_context.check_perm("cloud", "edit_tags", cloud_id) try: cloud = Cloud.objects.get(owner=auth_context.owner, id=cloud_id, deleted=None) except me.DoesNotExist: raise NotFoundError('Resource with that id does not exist') tags = params.get("tags") if type(tags) != dict: raise BadRequestError('tags should be dictionary of tags') if not modify_security_tags(auth_context, tags, cloud): raise auth_context._raise('cloud', 'edit_security_tags') return add_tags_to_resource(auth_context.owner, cloud, list(tags.items()))
def disassociate_metric(request): """ Tags: monitoring --- Disassociate a metric from a machine. READ permission required on cloud. EDIT_GRAPHS permission required on machine --- machine: in: path type: string required: true metric_id: type: string required: true """ auth_context = auth_context_from_request(request) machine = _machine_from_matchdict(request) # SEC require permission EDIT_GRAPHS on machine auth_context.check_perm("machine", "edit_graphs", machine.id) params = params_from_request(request) metric_id = params.get('metric_id') if not metric_id: raise RequiredParameterMissingError('metric_id') mist.api.monitoring.methods.disassociate_metric(machine, metric_id) return {}
def revoke_session(request): """ Tags: sessions --- Revoke an active session --- id: description: Session ID """ auth_context = auth_context_from_request(request) params = params_from_request(request) auth_token_id = params.get("id") if not auth_token_id: raise RequiredParameterMissingError("No token id parameter provided") try: if auth_context.is_owner(): auth_token = AuthToken.objects.get(org=auth_context.org, id=auth_token_id) else: auth_token = AuthToken.objects.get( user_id=auth_context.user.get_id(), id=auth_token_id) if auth_token.is_valid(): auth_token.invalidate() auth_token.save() except me.DoesNotExist: raise NotFoundError('Session not found') return OK
def create_dns_zone(request): """ Tags: dns --- Creates a new DNS zone under the given cloud. CREATE_RESOURCES permission required on cloud. ADD permission required on zone. --- cloud: in: path required: true type: string """ auth_context = auth_context_from_request(request) cloud_id = request.matchdict['cloud'] auth_context.check_perm("cloud", "read", cloud_id) auth_context.check_perm("cloud", "create_resources", cloud_id) tags, _ = auth_context.check_perm("zone", "add", None) try: cloud = Cloud.objects.get(owner=auth_context.owner, id=cloud_id) except me.DoesNotExist: raise CloudNotFoundError params = params_from_request(request) new_zone = Zone.add(owner=cloud.owner, cloud=cloud, **params) new_zone.assign_to(auth_context.user) if tags: resolve_id_and_set_tags(auth_context.owner, 'zone', new_zone.id, tags, cloud_id=cloud_id) return new_zone.as_dict()
def create_dns_zone(request): """ Create a new DNS zone under a specific cloud. --- """ auth_context = auth_context_from_request(request) cloud_id = request.matchdict['cloud'] auth_context.check_perm("cloud", "read", cloud_id) auth_context.check_perm("cloud", "create_resources", cloud_id) tags = auth_context.check_perm("zone", "add", None) # Try to get the specific cloud for which we will create the zone. try: cloud = Cloud.objects.get(owner=auth_context.owner, id=cloud_id) except me.DoesNotExist: raise CloudNotFoundError params = params_from_request(request) new_zone = Zone.add(owner=cloud.owner, cloud=cloud, **params).as_dict() if tags: resolve_id_and_set_tags(auth_context.owner, 'zone', new_zone['id'], tags, cloud_id=cloud_id) # Schedule a UI update trigger_session_update(auth_context.owner, ['zones']) return new_zone
def list_machines(request): """ Tags: machines --- Gets machines and their metadata from all clouds. Check Permissions take place in filter_list_machines. READ permission required on cloud. READ permission required on location. READ permission required on machine. """ auth_context = auth_context_from_request(request) params = params_from_request(request) cached = not params.get('fresh', False) # return cached by default # to prevent iterate throw every cloud auth_context.check_perm("cloud", "read", None) clouds = filter_list_clouds(auth_context) machines = [] for cloud in clouds: if cloud.get('enabled'): try: cloud_machines = methods.filter_list_machines(auth_context, cloud.get('id'), cached=cached) machines.extend(cloud_machines) except (CloudUnavailableError, CloudUnauthorizedError): pass return machines
def associate_ip(request): """ Tags: networks --- Associates ip with the specific network and machine. READ permission required on cloud. EDIT permission required on cloud. --- parameters: - name: cloud in: path required: true schema: type: string - name: network in: path required: true schema: type: string requestBody: description: Foo required: true content: 'application/json': schema: type: object properties: assign: default: true type: boolean ip: type: string machine: type: string required: - ip - machine """ cloud_id = request.matchdict['cloud'] network_id = request.matchdict['network'] params = params_from_request(request) ip = params.get('ip') machine_id = params.get('machine') assign = params.get('assign', True) auth_context = auth_context_from_request(request) auth_context.check_perm("cloud", "read", cloud_id) try: machine = Machine.objects.get(cloud=cloud_id, machine_id=machine_id) machine_uuid = machine.id except me.DoesNotExist: machine_uuid = "" auth_context.check_perm("machine", "edit", machine_uuid) ret = associate_ip_method(auth_context.owner, cloud_id, network_id, ip, machine_id, assign) if ret: return OK else: return Response("Bad Request", 400)
def associate_key(request): """ Tags: keys --- Associates a key with a machine. If host is set it will also attempt to actually deploy it to the machine. To do that it requires another key (existing_key) that can connect to the machine. READ permission required on cloud. READ_PRIVATE permission required on key. ASSOCIATE_KEY permission required on machine. --- machine: in: path required: true type: string key: in: path required: true type: string port: default: 22 type: integer user: description: The ssh user type: string """ key_id = request.matchdict['key'] params = params_from_request(request) ssh_user = params.get('user', None) try: ssh_port = int(request.json_body.get('port', 22)) except: ssh_port = 22 auth_context = auth_context_from_request(request) try: key = Key.objects.get(owner=auth_context.owner, id=key_id, deleted=None) except Key.DoesNotExist: raise NotFoundError('Key id does not exist') auth_context.check_perm('key', 'read_private', key.id) machine_uuid = request.matchdict['machine_uuid'] try: machine = Machine.objects.get(id=machine_uuid, state__ne='terminated') # used by logging_view_decorator request.environ['machine_id'] = machine.machine_id request.environ['cloud_id'] = machine.cloud.id except Machine.DoesNotExist: raise NotFoundError("Machine %s doesn't exist" % machine_uuid) cloud_id = machine.cloud.id auth_context.check_perm("cloud", "read", cloud_id) auth_context.check_perm("machine", "associate_key", machine.id) return key.ctl.associate(machine, username=ssh_user, port=ssh_port)
def update_user_settings(request): """ Tags: users --- User related actions Edit name, Update password """ # SEC raise exception if not user user = user_from_request(request) auth_context = auth_context_from_request(request) params = params_from_request(request) action = params.get('action') actions = ['update_details', 'update_password'] if action not in actions: log.error("Update_user_settings bad action='%s'", action) raise BadRequestError('action') if action == 'update_details': avatar = params.get('avatar') if avatar: try: Avatar.objects.get(id=avatar) user.avatar = avatar except DoesNotExist: raise BadRequestError('Avatar does not exist') if params.get('first_name') or params.get('last_name'): user.first_name = params.get('first_name') user.last_name = params.get('last_name') elif params.get('name'): name_array = params.get('name').split(' ') if len(name_array) > 1: user.last_name = name_array[-1] user.first_name = ' '.join(name_array[:-1]) user.save() trigger_session_update(auth_context.owner, ['user']) return {} if action == 'update_password': current_password = params.get('current_password', '') password = params.get('password', '') # check if current_password provided if not current_password and (user.password and user.password != ''): raise RequiredParameterMissingError("Current password") # check if new password provided if not password: raise RequiredParameterMissingError("New password") # SEC check if current_password valid if not user.check_password(current_password): raise UnauthorizedError("Invalid current password") # set new password user.set_password(password) return {}
def create_network(request): """ Create network on a cloud Creates a new network. If subnet dict is specified, after creating the network it will use the new network's id to create a subnet. CREATE_RESOURCES permission required on cloud. --- cloud_id: in: path required: true description: The Cloud ID type: string network: required: true type: dict subnet: type: dict """ cloud_id = request.matchdict['cloud'] params = params_from_request(request) network_params = params.get('network') subnet_params = params.get('subnet') auth_context = auth_context_from_request(request) if not network_params: raise RequiredParameterMissingError('network') # TODO if not auth_context.is_owner(): raise PolicyUnauthorizedError() try: cloud = Cloud.objects.get(owner=auth_context.owner, id=cloud_id) except me.DoesNotExist: raise CloudNotFoundError network = methods.create_network(auth_context.owner, cloud, network_params) network_dict = network.as_dict() # Bundling Subnet creation in this call because it is required # for backwards compatibility with the current UI if subnet_params: try: subnet = create_subnet(auth_context.owner, cloud, network, subnet_params) except Exception as exc: # Cleaning up the network object in case subnet creation # fails for any reason network.ctl.delete() raise exc network_dict['subnet'] = subnet.as_dict() return network.as_dict()
def update_monitoring(request): """ Tags: monitoring --- Enable or disable monitoring for a machine --- machine: in: path type: string required: true action: enum: - enable - disable type: string required: true no_ssh: type: boolean default: false dry: type: boolean default: false """ auth_context = auth_context_from_request(request) params = params_from_request(request) no_ssh = bool(params.get('no_ssh')) dry = bool(params.get('dry')) action = params.get('action') if not action: raise RequiredParameterMissingError('action') if action == 'enable': machine = _machine_from_matchdict(request) elif action == 'disable': machine = _machine_from_matchdict(request, deleted=True) else: raise BadRequestError('Action must be one of (enable, disable)') # SEC require permission EDIT on machine auth_context.check_perm("machine", "edit", machine.id) if action == 'enable': return mist.api.monitoring.methods.enable_monitoring( owner=auth_context.owner, cloud_id=machine.cloud.id, machine_id=machine.machine_id, no_ssh=no_ssh, dry=dry) elif action == 'disable': return mist.api.monitoring.methods.disable_monitoring( owner=auth_context.owner, cloud_id=machine.cloud.id, machine_id=machine.machine_id, no_ssh=no_ssh)
def add_key(request): """ Tags: keys --- Adds key. ADD permission required on key. --- name: description: The key's name required: true type: string priv: description: The private key required: true type: string certificate: description: The signed public key, when using signed ssh keys type: string """ params = params_from_request(request) key_name = params.pop('name', None) private_key = params.get('priv', None) certificate = params.get('certificate', None) auth_context = auth_context_from_request(request) key_tags = auth_context.check_perm("key", "add", None) if not key_name: raise BadRequestError("Key name is not provided") if not private_key: raise RequiredParameterMissingError("Private key is not provided") if certificate: key = SignedSSHKey.add(auth_context.owner, key_name, **params) else: key = SSHKey.add(auth_context.owner, key_name, **params) # Set ownership. key.assign_to(auth_context.user) if key_tags: add_tags_to_resource(auth_context.owner, key, key_tags.items()) # since its a new key machines fields should be an empty list clouds = Cloud.objects(owner=auth_context.owner, deleted=None) machines = Machine.objects(cloud__in=clouds, key_associations__keypair__exact=key) assoc_machines = transform_key_machine_associations(machines, key) return { 'id': key.id, 'name': key.name, 'machines': assoc_machines, 'isDefault': key.default }
def create_dns_record(request): """ Tags: dns --- Creates a new record under a specific zone. CREATE_RESOURCES permission required on cloud. CREATE_RECORDS permission required on zone --- cloud: in: path required: true type: string zone: in: path required: true type: string """ auth_context = auth_context_from_request(request) cloud_id = request.matchdict['cloud'] try: cloud = Cloud.objects.get(owner=auth_context.owner, id=cloud_id) except me.DoesNotExist: raise CloudNotFoundError() zone_id = request.matchdict['zone'] try: zone = Zone.objects.get(owner=auth_context.owner, id=zone_id, cloud=cloud) except Zone.DoesNotExist: raise NotFoundError('Zone does not exist') auth_context.check_perm("cloud", "read", cloud_id) auth_context.check_perm("zone", "read", zone_id) auth_context.check_perm("zone", "create_records", zone_id) tags = auth_context.check_perm("record", "add", None) params = params_from_request(request) dns_cls = RECORDS[params['type']] rec = dns_cls.add(owner=auth_context.owner, zone=zone, **params) rec.assign_to(auth_context.user) if tags: resolve_id_and_set_tags(auth_context.owner, 'record', rec.id, tags, cloud_id=cloud_id, zone_id=zone_id) trigger_session_update(auth_context.owner, ['zones']) return rec.as_dict()
def get_load(request): """ Tags: monitoring --- Request load data for all monitored machines --- start: in: query type: string default: now required: false description: time (eg. '10s') since when to fetch stats stop: in: query type: string required: false description: time until when to fetch stats step: in: query type: string required: false description: step to fetch stats, used in aggregations request_id: in: query type: string required: false """ auth_context = auth_context_from_request(request) cloud_ids = [ cloud['id'] for cloud in filter_list_clouds(auth_context) if cloud['enabled'] ] uuids = [ machine.id for machine in Machine.objects( cloud__in=cloud_ids, monitoring__hasmonitoring=True, ).only('id') ] if not auth_context.is_owner(): allowed_uuids = auth_context.get_allowed_resources(rtype='machines') uuids = set(uuids) & set(allowed_uuids) params = params_from_request(request) start = params.get('start', '') stop = params.get('stop', '') step = params.get('step', '') data = mist.api.monitoring.methods.get_load(auth_context.owner, start=start, stop=stop, step=step, uuids=uuids) data['request_id'] = params.get('request_id') return data
def delete_keys(request): """ Tags: keys --- Deletes multiple keys. Provide a list of key ids to be deleted. The method will try to delete all of them and then return a json that describes for each key id whether or not it was deleted or not_found if the key id could not be located. If no key id was found then a 404(Not Found) response will be returned. REMOVE permission required on each key. --- key_ids: required: true type: array items: type: string """ auth_context = auth_context_from_request(request) params = params_from_request(request) key_ids = params.get('key_ids', []) if type(key_ids) != list or len(key_ids) == 0: raise RequiredParameterMissingError('No key ids provided') # remove duplicate ids if there are any key_ids = set(key_ids) report = {} for key_id in key_ids: try: key = Key.objects.get(owner=auth_context.owner, id=key_id, deleted=None) except me.DoesNotExist: report[key_id] = 'not_found' continue try: auth_context.check_perm('key', 'remove', key.id) except PolicyUnauthorizedError: report[key_id] = 'unauthorized' else: delete_key(auth_context.owner, key_id) report[key_id] = 'deleted' # if no key id was valid raise exception if len(filter(lambda key_id: report[key_id] == 'not_found', report)) == len(key_ids): raise NotFoundError('No valid key id provided') # if user was unauthorized for all keys if len(filter(lambda key_id: report[key_id] == 'unauthorized', report)) == len(key_ids): raise NotFoundError('Unauthorized to modify any of the keys') return report
def find_metrics(request): """ Tags: monitoring --- Get all metrics associated with specific machine. READ permission required on cloud. READ permission required on machine. --- resource_type: in: query required: false type: string id: in: query required: false type: string tags: in: query required: false type: string """ auth_context = auth_context_from_request(request) params = params_from_request(request) resource_type = params.get('resource_type', None) resource_id = params.get('resource_id', None) tags = params.get('tags', None) # Convert the tag list to a dict if tags: tags = dict( (key, value[0] if value else '') for key, *value in (pair.split(':') for pair in tags.split(','))) if resource_id: return mist.api.monitoring.methods.find_metrics_by_resource_id( auth_context, resource_id, resource_type) if resource_type: return mist.api.monitoring.methods.find_metrics_by_resource_type( auth_context, resource_type, tags) if tags: return mist.api.monitoring.methods.find_metrics_by_tags( auth_context, tags)
def create_subnet(request): """ Tags: networks --- Create subnet in a given network on a cloud ADD permission required on subnet READ permission required on cloud READ permission required on network CREATE_SUBNETS permission required on network CREATE_RESOURCES permission required on cloud --- cloud_id: in: path required: true description: The Cloud ID type: string network_id: in: path required: true description: The ID of the Network that will contain the new subnet type: string subnet: required: true type: object """ cloud_id = request.matchdict['cloud'] network_id = request.matchdict['network'] params = params_from_request(request) auth_context = auth_context_from_request(request) # SEC auth_context.check_perm('cloud', 'read', cloud_id) auth_context.check_perm('cloud', 'create_resources', cloud_id) auth_context.check_perm('network', 'read', network_id) auth_context.check_perm('network', 'edit_subnets', network_id) try: cloud = Cloud.objects.get(id=cloud_id, owner=auth_context.owner) except Cloud.DoesNotExist: raise CloudNotFoundError() try: network = Network.objects.get(id=network_id, cloud=cloud) except Network.DoesNotExist: raise NetworkNotFoundError() # Create subnet. subnet = SUBNETS[cloud.ctl.provider].add(network=network, **params) return subnet.as_dict()