def home_dashboard(request): """ Tags: monitoring --- Return home monitoring dashboard """ auth_context_from_request(request) return copy.deepcopy(config.HOME_DASHBOARD_DEFAULT)
def delete_script(request): """ Delete script REMOVE permission required on script. --- script_id: in: path required: true type: string """ script_id = request.matchdict['script_id'] auth_context = auth_context_from_request(request) if not script_id: raise RequiredParameterMissingError('No script id provided') try: script = Script.objects.get(owner=auth_context.owner, id=script_id, deleted=None) except me.DoesNotExist: raise NotFoundError('Script id not found') # SEC require REMOVE permission on script auth_context.check_perm('script', 'remove', script_id) script.ctl.delete() return OK
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): """ 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 delete_dns_zone(request): """ Delete a specific DNS zone under a cloud. --- """ auth_context = auth_context_from_request(request) cloud_id = request.matchdict['cloud'] zone_id = request.matchdict['zone'] # Do we need the cloud here, now that the models have been created? try: cloud = Cloud.objects.get(owner=auth_context.owner, id=cloud_id) except me.DoesNotExist: raise CloudNotFoundError try: zone = Zone.objects.get(owner=auth_context.owner, id=zone_id) except Zone.DoesNotExist: raise NotFoundError('Zone does not exist') auth_context.check_perm("zone", "remove", zone_id) zone.ctl.delete_zone() # Schedule a UI update trigger_session_update(auth_context.owner, ['zones']) return OK
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 get_network_tags(request): """ Tags: tags --- Lists tags of a network. READ permission required on CLOUD. READ permission required on NETWORK --- cloud_id: in: path required: true type: string network_id: in: path required: true type: string """ auth_context = auth_context_from_request(request) network_id = request.matchdict["network_id"] cloud_id = request.params.get("cloud_id") auth_context.check_perm('cloud', 'read', cloud_id) # SEC require READ permission on network auth_context.check_perm('network', 'read', network_id) return resolve_id_and_get_tags(auth_context.owner, 'network', network_id, cloud_id=cloud_id)
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_default_key(request): """ Set default key Sets a new default key EDIT permission required on key. --- key: description: The key id in: path required: true type: string """ key_id = request.matchdict['key'] 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 id does not exist') auth_context.check_perm('key', 'edit', key.id) key.ctl.set_default() 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 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 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 delete_schedule(request): """ Tags: schedules --- Deletes a schedule entry of a user. REMOVE permission required on schedule --- schedule_id: type: string required: true """ schedule_id = request.matchdict['schedule_id'] auth_context = auth_context_from_request(request) if not schedule_id: raise RequiredParameterMissingError('No schedule id provided') # Check if entry exists try: schedule = Schedule.objects.get(id=schedule_id, deleted=None) except me.DoesNotExist: raise ScheduleTaskNotFound() # SEC auth_context.check_perm('schedule', 'remove', schedule_id) # NOTE: Do not perform an atomic operation when marking a schedule as # deleted, since we do not wish to bypass pre-save validation/cleaning. schedule.deleted = datetime.utcnow() schedule.save() trigger_session_update(auth_context.owner, ['schedules']) return OK
def show_schedule_entry(request): """ Tags: schedules --- Show details of schedule. READ permission required on schedule --- schedule_id: type: string required: true """ schedule_id = request.matchdict['schedule_id'] auth_context = auth_context_from_request(request) if not schedule_id: raise RequiredParameterMissingError('No schedule id provided') try: schedule = Schedule.objects.get(id=schedule_id, deleted=None, owner=auth_context.owner) except me.DoesNotExist: raise ScheduleTaskNotFound() # SEC require READ permission on schedule auth_context.check_perm('schedule', 'read', schedule_id) return schedule.as_dict()
def url_script(request): """ Returns to a mist authenticated user, a self-auth/signed url for fetching a script's file. READ permission required on script. --- script_id: in: path required: true type: string """ auth_context = auth_context_from_request(request) script_id = request.matchdict['script_id'] try: Script.objects.get(owner=auth_context.owner, id=script_id, deleted=None) except Script.DoesNotExist: raise NotFoundError('Script does not exist.') # SEC require READ permission on script auth_context.check_perm('script', 'read', script_id) # build HMAC and inject into the `curl` command hmac_params = {'action': 'fetch_script', 'object_id': script_id} expires_in = 60 * 15 mac_sign(hmac_params, expires_in) url = "%s/api/v1/fetch" % config.CORE_URI encode_params = urllib.urlencode(hmac_params) r_url = url + '?' + encode_params return r_url
def list_storage_classes(request): """ Tags: volumes --- List the volumes of a cloud. READ permission required on cloud. READ permission required on location. --- cloud: in: path required: true type: string """ auth_context = auth_context_from_request(request) cloud_id = request.matchdict.get('cloud') try: cloud = Cloud.objects.get(owner=auth_context.owner, id=cloud_id, deleted=None) except Cloud.DoesNotExist: raise CloudNotFoundError() if cloud.as_dict()['provider'] != 'kubevirt': raise BadRequestError('Only available for KubeVirt clouds') # SEC auth_context.check_perm('cloud', 'read', cloud_id) storage_classes = cloud.ctl.storage.list_storage_classes() return storage_classes
def toggle_ownership(request): """ Tags: ownership --- Toggle the Organization's `ownership_enabled` flag If set to True, then the ownership mappings will be taken into account when performing RBAC checks. If a user is a resource's owner, denoted in the `owned_by` field, then the user will have full access rights on that particular resource. This setting can be enabled/disabled ONLY by members of the Owners team. """ auth_context = auth_context_from_request(request) if not auth_context.is_owner(): raise UnauthorizedError('Available only to Owners') current_toggle = auth_context.owner.ownership_enabled auth_context.owner.ownership_enabled = not current_toggle auth_context.owner.save() trigger_session_update(auth_context.owner, 'org') return Response('OK', 200)
def get_private_key(request): """ Gets private key from key name. It is used in single key view when the user clicks the display private key button. READ_PRIVATE permission required on key. --- key: description: The key id in: path required: true type: string """ key_id = request.matchdict['key'] if not key_id: raise RequiredParameterMissingError("key_id") auth_context = auth_context_from_request(request) try: key = SSHKey.objects.get(owner=auth_context.owner, id=key_id, deleted=None) except me.DoesNotExist: raise NotFoundError('Key id does not exist') auth_context.check_perm('key', 'read_private', key.id) return key.private
def get_machine_tags(request): """ Tags: tags --- Lists tags of a machine. READ permission required on CLOUD. READ permission required on MACHINE --- cloud_id: in: path required: true type: string machine: in: path required: true type: string """ auth_context = auth_context_from_request(request) machine_id = request.matchdict["machine_id"] cloud_id = request.matchdict["cloud_id"] auth_context.check_perm("cloud", "read", cloud_id) auth_context.check_perm('cloud', 'read', cloud_id) # SEC auth_context.check_perm("machine", "read", machine_id) return resolve_id_and_get_tags(auth_context.owner, 'machine', machine_id, cloud_id=cloud_id)
def get_public_key(request): """ Get public key Gets public key from key name. READ permission required on key. --- key: description: The key id in: path required: true type: string """ key_id = request.matchdict['key'] if not key_id: raise RequiredParameterMissingError("key_id") auth_context = auth_context_from_request(request) try: key = SSHKey.objects.get(owner=auth_context.owner, id=key_id, deleted=None) except me.DoesNotExist: raise NotFoundError('Key id does not exist') auth_context.check_perm('key', 'read', key.id) return key.public
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 delete_key(request): """ Delete key Delete key. When a key gets deleted, it takes its associations with it so just need to remove from the server too. If the default key gets deleted, it sets the next one as default, provided that at least another key exists. It returns the list of all keys after the deletion, excluding the private keys (check also list_keys). REMOVE permission required on key. --- key: in: path required: true type: string """ auth_context = auth_context_from_request(request) key_id = request.matchdict.get('key') if not key_id: raise KeyParameterMissingError() try: key = Key.objects.get(owner=auth_context.owner, id=key_id, deleted=None) except me.DoesNotExist: raise NotFoundError('Key id does not exist') auth_context.check_perm('key', 'remove', key.id) m_delete_key(auth_context.owner, key_id) return list_keys(request)
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 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 delete_dns_record(request): """ Delete a specific DNS record under a zone. --- """ auth_context = auth_context_from_request(request) cloud_id = request.matchdict['cloud'] zone_id = request.matchdict['zone'] record_id = request.matchdict['record'] try: cloud = Cloud.objects.get(owner=auth_context.owner, id=cloud_id) except me.DoesNotExist: raise CloudNotFoundError try: zone = Zone.objects.get(owner=auth_context.owner, id=zone_id) except Zone.DoesNotExist: raise NotFoundError('Zone does not exist') try: record = Record.objects.get(zone=zone, id=record_id) except Record.DoesNotExist: raise NotFoundError('Record does not exist') auth_context.check_perm("record", "remove", record_id) record.ctl.delete_record() # Schedule a UI update trigger_session_update(auth_context.owner, ['zones']) return OK
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 list_sessions(request): """ Tags: sessions --- Lists active sessions --- """ auth_context = auth_context_from_request(request) session = request.environ['session'] # Get active sessions for the current user session_tokens = SessionToken.objects(user_id=auth_context.user.id, revoked=False) sessions_list = [] for token in session_tokens: if token.is_valid(): public_view = token.get_public_view() if isinstance(session, SessionToken) and session.id == token.id: public_view['active'] = True sessions_list.append(public_view) # If user is owner include all active sessions in the org context if auth_context.is_owner(): org_tokens = SessionToken.objects(org=auth_context.org, revoked=False) for token in org_tokens: if token.is_valid(): public_view = token.get_public_view() if isinstance(session, SessionToken) and \ session.id == token.id: public_view['active'] = True try: sessions_list.index(public_view) except ValueError: sessions_list.append(public_view) return sessions_list
def delete_network_tag(request): """ Delete a tag Delete tag in the db for specified resource_type. READ permission required on cloud. EDIT_TAGS permission required on network. --- tag_key: in: path required: true type: string cloud_id: in: path required: true type: string network_id: in: path required: true type: string """ auth_context = auth_context_from_request(request) cloud_id = request.matchdict["cloud_id"] network_id = request.matchdict["network_id"] tag_key = request.matchdict["tag_key"] auth_context.check_perm('cloud', 'read', cloud_id) # SEC require EDIT_TAGS permission on network auth_context.check_perm('network', 'edit_tags', network_id) if not delete_security_tag(auth_context, tag_key): raise auth_context._raise('network', 'edit_security_tags') return resolve_id_and_delete_tags(auth_context.owner, 'network', network_id, tags=[tag_key], cloud_id=cloud_id)
def list_tokens(request): """ Tags: api_tokens --- Lists user's api tokens --- """ # FIXME: should call an optimized methods.list_tokens auth_context = auth_context_from_request(request) api_tokens = ApiToken.objects(user_id=auth_context.user.id, revoked=False) tokens_list = [] for token in api_tokens: if token.is_valid(): token_view = token.get_public_view() if token_view['last_accessed_at'] == 'None': token_view['last_accessed_at'] = 'Never' tokens_list.append(token_view) # If user is owner also include all active tokens in the current org # context if auth_context.is_owner(): org_tokens = ApiToken.objects(org=auth_context.org, revoked=False) for token in org_tokens: if token.is_valid(): token_view = token.get_public_view() if token_view['last_accessed_at'] == 'None': token_view['last_accessed_at'] = 'Never' try: tokens_list.index(token_view) except ValueError: tokens_list.append(token_view) return tokens_list
def list_vnfs(request): """ Tags: networks --- List the virtual network functions of a cloud (KVM only) READ permission required on cloud --- cloud: in: path required: true type: string """ cloud_id = request.matchdict['cloud'] auth_context = auth_context_from_request(request) # SEC auth_context.check_perm('cloud', 'read', cloud_id) try: cloud = Cloud.objects.get(owner=auth_context.owner, id=cloud_id) except Cloud.DoesNotExist: raise CloudNotFoundError() try: return cloud.ctl.network.list_vnfs() except (AttributeError, NotImplementedError): raise MistNotImplementedError