Esempio n. 1
0
def cascade_delete(resource, item):
    """Cascade DELETE.

    Hook to delete all objects, which have the 'cascade_delete' option set
    in the data_relation and relate to the object, which was just deleted.
    """
    domain = current_app.config['DOMAIN']
    deleted_id = item[domain[resource]['id_field']]

    for res, res_domain in domain.items():
        # Filter schema of `res` to get all fields containing references
        # to the resource of the deleted item
        relations = ((field, field_def['data_relation'])
                     for field, field_def in res_domain['schema'].items()
                     if 'data_relation' in field_def and
                     field_def['data_relation'].get('resource') == resource)
        for field, data_relation in relations:
            # All items in `res` with reference to the deleted item
            lookup = {field: deleted_id}
            with admin_permissions():
                try:
                    if data_relation.get('cascade_delete'):
                        # Delete the item as well
                        deleteitem_internal(res, concurrency_check=False,
                                            **lookup)
                    else:
                        # Don't delete, only remove reference
                        patch_internal(res, payload={field: None},
                                       concurrency_check=False,
                                       **lookup)
                except NotFound:
                    pass
    def on_updated_host(updates, original):
        """
        Called by EVE HOOK (app.on_updated_host)

        After host updated,
        if host is a template, report value of fields updated on host used this template
        if host is not template, add or remove services templates if _templates changed

        :param updates: modified fields
        :type updates: dict
        :param original: original fields
        :type original: dict
        :return: None
        """
        # pylint: disable=too-many-locals
        if g.get('ignore_hook_patch', False):
            g.ignore_hook_patch = False
            return
        if original['_is_template']:
            # We must update all host use this template
            host_db = current_app.data.driver.db['host']
            hosts = host_db.find({'_templates': original['_id']})
            for host in hosts:
                Template.update_host_use_template(host, updates)
        else:
            if '_templates'in updates and updates['_templates'] != original['_templates']:
                if original['_templates_with_services']:
                    service_db = current_app.data.driver.db['service']
                    # Get all services of this host
                    myservices = service_db.find({'_is_template': False,
                                                  'host': original['_id']})
                    myservices_template_id = []
                    myservices_bis = {}
                    for myservice in myservices:
                        myservices_template_id.append(myservice['_templates'][0])
                        myservices_bis[myservice['_templates'][0]] = myservice

                    services = {}
                    service_template_id = []
                    # loop on host templates and add into services the service are templates
                    for hostid in updates['_templates']:
                        services_template = service_db.find({'_is_template': True,
                                                             'host': hostid})
                        for srv in services_template:
                            services[srv['name']] = Template.prepare_service_to_post(srv,
                                                                                     original[
                                                                                         '_id'])
                            service_template_id.append(services[srv['name']]['_templates'][0])
                    services_to_add = list(set(service_template_id) - set(myservices_template_id))
                    services_to_del = list(set(myservices_template_id) - set(service_template_id))
                    for (_, service) in iteritems(services):
                        if service['_templates'][0] in services_to_add:
                            post_internal('service', [service])
                    for template_id in services_to_del:
                        if template_id in myservices_bis:
                            lookup = {"_id": myservices_bis[template_id]['_id']}
                            deleteitem_internal('service', False, False, **lookup)
Esempio n. 3
0
def post_devices(registers: list):
    """
    Main function for Register. For the given devices, POST the new ones. This method rollbacks the database when
    raising exceptions, like when no device has been POSTed.

    If the function is called by post_internal(), as the method keeps the reference of the passed in devices, the
    caller will see how their devices are replaced by the db versions, plus a 'new' property acting as a flag
    to indicate if the device is new or not.

    If a device exists, the input device is replaced by the version of the database, loosing any change the
    input device was introducing (except benchmarks, which are updated). See `_execute_register` for more info.

    :raise InnerRequestError: for any error provoked by a failure in the POST of a device (except if the device already
        existed). It carries the original error sent by the POST.
    :raise NoDevicesToProcess: Raised to avoid creating empty registers, that actually did not POST any device
    """
    log = []
    try:
        for register in registers:
            caller_device = register[
                'device']  # Keep the reference from where register['device'] points to
            _execute_register(caller_device, register.get('created'), log)
            register['device'] = caller_device['_id']
            if 'components' in register:
                caller_components = register['components']
                register['components'] = []
                for component in caller_components:
                    component['parent'] = caller_device['_id']
                    _execute_register(component, register.get('created'), log)
                    if component[
                            'new']:  # todo put new in g., don't use device
                        register['components'].append(component['_id'])
                if caller_device['new']:
                    set_components(register)
                elif not register['components']:
                    text = 'Device {} and components {} already exist.'.format(
                        register['device'], register['components'])
                    raise NoDevicesToProcess(text)
                else:
                    add_components([
                        register
                    ])  # The device is not new but we have new computers
                    # Note that we only need to copy a place from the parent if this already existed
                    if 'place' in caller_device:
                        inherit_place(caller_device['place'],
                                      register['device'],
                                      register['components'])
    except Exception as e:
        for device in reversed(log):  # Rollback
            deleteitem_internal(Naming.resource(device['@type']), device)
        raise e
    else:
        from ereuse_devicehub.resources.hooks import set_date
        set_date(None,
                 registers)  # Let's get the time AFTER creating the devices
Esempio n. 4
0
    def on_deleted_item_service(item):
        """Called by EVE HOOK (app.on_deleted_item_service)

        After deleted a template service, we delete all services are linked to this template

        :param item: service dict
        :type item: dict
        :return: None
        """
        service_db = current_app.data.driver.db['service']
        if item['_is_template']:
            services = service_db.find({'_templates': item['_id']})
            for service in services:
                lookup = {"_id": service['_id']}
                deleteitem_internal('service', False, False, **lookup)
Esempio n. 5
0
def on_delete_signup(token):
    """Endpoint to delete signups via email"""
    try:
        s = Signer(get_token_secret())
        signup_id = ObjectId(s.unsign(token).decode('utf-8'))
    except BadSignature:
        return "Unknown token"

    deleteitem_internal('eventsignups', concurrency_check=False,
                        **{current_app.config['ID_FIELD']: signup_id})

    redirect_url = current_app.config.get('SIGNUP_DELETED_REDIRECT')
    if redirect_url:
        return redirect(redirect_url)
    else:
        return current_app.config['SIGNUP_DELETED_TEXT']
Esempio n. 6
0
def on_delete_confirmed(token):
    try:
        s = URLSafeSerializer(get_token_secret())
        signup_id = ObjectId(s.loads(token))

    except BadSignature:
        return "Unknown token"

    deleteitem_internal('eventsignups',
                        concurrency_check=False,
                        **{current_app.config['ID_FIELD']: signup_id})
    redirect_url = current_app.config.get('SIGNUP_DELETED_REDIRECT')
    if redirect_url:
        return redirect(redirect_url)
    else:
        return current_app.config['SIGNUP_DELETED_TEXT']
    def on_deleted_item_service(item):
        """
        Called by EVE HOOK (app.on_deleted_item_service)

        After deleted a template service, we delete all services are linked to this template

        :param item: service dict
        :type item: dict
        :return: None
        """
        service_db = current_app.data.driver.db['service']
        if item['_is_template']:
            services = service_db.find({'_templates': item['_id']})
            for service in services:
                lookup = {"_id": service['_id']}
                deleteitem_internal('service', False, False, **lookup)
Esempio n. 8
0
def create_user(username):
    melwin_user, _, _, status = getitem_internal(resource='melwin/users', **{'id': username})

    if melwin_user and status == 200:

        try:
            user_response, _, _, user_code, header = post_internal(resource=app.globals['auth']['users_collection'],
                                                                   payl={'id': username},
                                                                   skip_validation=True)
        except:
            app.logger.exception("503: Could not create (POST) new user %i" % username)
            return False

        try:
            auth_response, _, _, auth_code, header = post_internal(resource='users/auth',
                                                                   payl={'id': username,
                                                                         'user': user_response['_id'],
                                                                         'auth': {"token": "",
                                                                                  "valid": ""}},
                                                                   skip_validation=True)
        except:
            app.logger.exception("%i: Could not create (mongo insert) user %i auth item" % (auth_code, username))
            return False

        # Verify both post's response codes
        if user_code == 201 and auth_code == 201:
            return True
        else:
            try:
                from eve.methods.delete import deleteitem_internal
                if '_id' in user_response:
                    _, _, _, code = deleteitem_internal(resource=app.globals['auth']['users_collection'],
                                                        concurrency_check=False,
                                                        suppress_callbacks=True,
                                                        **{'_id': user_response['_id']})
                    app.logger.info("Deleted user from users")
                if '_id' in auth_response:
                    _, _, _, code = deleteitem_internal(resource='users/auth',
                                                        concurrency_check=False,
                                                        suppress_callbacks=True,
                                                        **{'_id': auth_response['_id']})
                    app.logger.info("Deleted user from users_auth")
            except:
                app.logger.exception("Delete operation of user %i from users and users_auth but failed" % username)

    return False
Esempio n. 9
0
    def test_deleteitem_internal(self):
        # test that deleteitem_internal is available and working properly.
        with self.app.test_request_context(self.item_id_url):
            r, _, _, status = deleteitem_internal(self.known_resource, concurrency_check=False, **{"_id": self.item_id})
        self.assert204(status)

        r = self.test_client.get(self.item_id_url)
        self.assert404(r.status_code)
Esempio n. 10
0
def on_deleted_item(resource_name, item):
    if resource_name == 'attendances_tutors':
        # r = {'id': item['attendance']}
        # attendance, *_ = deleteitem_internal( 'attendances', *r)
        try:
            other_attendances_tutors, *_ = getitem(
                'attendances_tutors', {'attendance': item['attendance']})
        except NotFound as e:
            attendance, *_ = deleteitem_internal('attendances',
                                                 id=item['attendance'])
Esempio n. 11
0
    def test_deleteitem_internal(self):
        # test that deleteitem_internal is available and working properly.
        with self.app.test_request_context(self.item_id_url):
            r, _, _, status = deleteitem_internal(self.known_resource,
                                                  concurrency_check=False,
                                                  **{'_id': self.item_id})
        self.assert204(status)

        r = self.test_client.get(self.item_id_url)
        self.assert404(r.status_code)
Esempio n. 12
0
def post_devices(registers: list):
    """
    Main function for Register. For the given devices, POST the new ones. This method rollbacks the database when
    raising exceptions, like when no device has been POSTed.

    If the function is called by post_internal(), as the method keeps the reference of the passed in devices, the
    caller will see how their devices are replaced by the db versions, plus a 'new' property acting as a flag
    to indicate if the device is new or not.

    If a device exists, the input device is replaced by the version of the database, loosing any change the
    input device was introducing (except benchmarks, which are updated). See `_execute_register` for more info.

    :raise InnerRequestError: for any error provoked by a failure in the POST of a device (except if the device already
        existed). It carries the original error sent by the POST.
    :raise NoDevicesToProcess: Raised to avoid creating empty registers, that actually did not POST any device
    """
    log = []
    try:
        for register in registers:
            caller_device = register['device']  # Keep the reference from where register['device'] points to
            _execute_register(caller_device, register.get('created'), log)
            register['device'] = caller_device['_id']
            if 'components' in register:
                caller_components = register['components']
                register['components'] = []
                for component in caller_components:
                    component['parent'] = caller_device['_id']
                    _execute_register(component, register.get('created'), log)
                    if component['new']:  # todo put new in g., don't use device
                        register['components'].append(component['_id'])
                if caller_device['new']:
                    set_components(register)
                elif not register['components']:
                    raise NoDevicesToProcess()
    except Exception as e:
        for device in reversed(log):  # Rollback
            deleteitem_internal(Naming.resource(device['@type']), device)
        raise e
    else:
        from ereuse_devicehub.resources.hooks import set_date
        set_date(None, registers)  # Let's get the time AFTER creating the devices
Esempio n. 13
0
    def test_deleteitem_internal(self):
        """Deleteitem internal should honor soft delete settings.
        """
        # test that deleteitem_internal is available and working properly.
        with self.app.test_request_context(self.item_id_url):
            r, _, _, status = deleteitem_internal(self.known_resource, concurrency_check=False, **{"_id": self.item_id})
        self.assert204(status)

        r = self.test_client.get(self.item_id_url)
        data, status = self.parse_response(r)
        self.assert404(status)
        self.assertEqual(data.get(self.deleted_field), True)
Esempio n. 14
0
    def test_deleteitem_internal(self):
        """Deleteitem internal should honor soft delete settings."""
        # test that deleteitem_internal is available and working properly.
        with self.app.test_request_context(self.item_id_url):
            r, _, _, status = deleteitem_internal(self.known_resource,
                                                  concurrency_check=False,
                                                  **{"_id": self.item_id})
        self.assert204(status)

        r = self.test_client.get(self.item_id_url)
        data, status = self.parse_response(r)
        self.assert404(status)
        self.assertEqual(data.get(self.deleted_field), True)
Esempio n. 15
0
    def delete_internal(self,
                        resource: str,
                        concurrency_check=False,
                        suppress_callbacks=False,
                        **lookup):
        """Workaround for Eve issue https://github.com/nicolaiarocci/eve/issues/810"""
        from eve.methods.delete import deleteitem_internal

        url = self.config['URLS'][resource]
        path = '%s/%s/%s' % (self.api_prefix, url, lookup['_id'])
        with self.__fake_request_url_rule('DELETE', path):
            return deleteitem_internal(resource,
                                       concurrency_check=concurrency_check,
                                       suppress_callbacks=suppress_callbacks,
                                       **lookup)[:4]
Esempio n. 16
0
def cron_timeseries():
    """
    Cron used to add perfdata from retention to timeseries databases

    :return: None
    """
    with app.test_request_context():
        timeseriesretention_db = current_app.data.driver.db[
            'timeseriesretention']
        if timeseriesretention_db.find().count() > 0:
            tsc = timeseriesretention_db.find({
                'for_graphite': True,
                'for_influxdb': False
            })
            for data in tsc:
                if not Timeseries.send_to_timeseries_graphite([data]):
                    break
                lookup = {"_id": data['_id']}
                deleteitem_internal('timeseriesretention', False, False,
                                    **lookup)
            tsc = timeseriesretention_db.find({
                'for_graphite': False,
                'for_influxdb': True
            })
            for data in tsc:
                if not Timeseries.send_to_timeseries_influxdb([data]):
                    break
                lookup = {"_id": data['_id']}
                deleteitem_internal('timeseriesretention', False, False,
                                    **lookup)
            tsc = timeseriesretention_db.find({
                'for_graphite': True,
                'for_influxdb': True
            })
            for data in tsc:
                graphite_serv = True
                influxdb_serv = True
                if not Timeseries.send_to_timeseries_graphite([data]):
                    graphite_serv = False
                if not Timeseries.send_to_timeseries_influxdb([data]):
                    influxdb_serv = False
                lookup = {"_id": data['_id']}
                if graphite_serv and influxdb_serv:
                    deleteitem_internal('timeseriesretention', False, False,
                                        **lookup)
                elif graphite_serv and not influxdb_serv:
                    patch_internal('timeseriesretention',
                                   {"for_graphite": False}, False, False,
                                   **lookup)
                elif influxdb_serv and not graphite_serv:
                    patch_internal('timeseriesretention',
                                   {"for_influxdb": False}, False, False,
                                   **lookup)
def cron_timeseries():
    """
    Cron used to add perfdata from retention to timeseries databases

    :return: None
    """
    with app.test_request_context():
        timeseriesretention_db = current_app.data.driver.db['timeseriesretention']
        if timeseriesretention_db.find().count() > 0:
            tsc = timeseriesretention_db.find({'for_graphite': True, 'for_influxdb': False})
            for data in tsc:
                if not Timeseries.send_to_timeseries_graphite([data]):
                    break
                lookup = {"_id": data['_id']}
                deleteitem_internal('timeseriesretention', False, False, **lookup)
            tsc = timeseriesretention_db.find({'for_graphite': False, 'for_influxdb': True})
            for data in tsc:
                if not Timeseries.send_to_timeseries_influxdb([data]):
                    break
                lookup = {"_id": data['_id']}
                deleteitem_internal('timeseriesretention', False, False, **lookup)
            tsc = timeseriesretention_db.find({'for_graphite': True, 'for_influxdb': True})
            for data in tsc:
                graphite_serv = True
                influxdb_serv = True
                if not Timeseries.send_to_timeseries_graphite([data]):
                    graphite_serv = False
                if not Timeseries.send_to_timeseries_influxdb([data]):
                    influxdb_serv = False
                lookup = {"_id": data['_id']}
                if graphite_serv and influxdb_serv:
                    deleteitem_internal('timeseriesretention', False, False, **lookup)
                elif graphite_serv and not influxdb_serv:
                    patch_internal('timeseriesretention', {"for_graphite": False}, False, False,
                                   **lookup)
                elif influxdb_serv and not graphite_serv:
                    patch_internal('timeseriesretention', {"for_influxdb": False}, False, False,
                                   **lookup)
Esempio n. 18
0
    def on_updated_host(updates, original):
        """
        Called by EVE HOOK (app.on_updated_host)

        After host updated,
        if host is a template, report value of fields updated on host used this template
        if host is not template, add or remove services templates if _templates changed

        :param updates: modified fields
        :type updates: dict
        :param original: original fields
        :type original: dict
        :return: None
        """
        # pylint: disable=too-many-locals
        if g.get('ignore_hook_patch', False):
            g.ignore_hook_patch = False
            return
        if original['_is_template']:
            # We must update all host use this template
            host_db = current_app.data.driver.db['host']
            hosts = host_db.find({'_templates': original['_id']})
            for host in hosts:
                Template.update_host_use_template(host, updates)
        else:
            if '_templates' in updates and updates['_templates'] != original[
                    '_templates']:
                if original['_templates_with_services']:
                    service_db = current_app.data.driver.db['service']
                    # Get all services of this host
                    myservices = service_db.find({
                        '_is_template': False,
                        'host': original['_id']
                    })
                    myservices_template_id = []
                    myservices_bis = {}
                    for myservice in myservices:
                        myservices_template_id.append(
                            myservice['_templates'][0])
                        myservices_bis[myservice['_templates'][0]] = myservice

                    services = {}
                    service_template_id = []
                    # loop on host templates and add into services the service are templates
                    for hostid in updates['_templates']:
                        services_template = service_db.find({
                            '_is_template': True,
                            'host': hostid
                        })
                        for srv in services_template:
                            services[srv[
                                'name']] = Template.prepare_service_to_post(
                                    srv, original['_id'])
                            service_template_id.append(
                                services[srv['name']]['_templates'][0])
                    services_to_add = list(
                        set(service_template_id) - set(myservices_template_id))
                    services_to_del = list(
                        set(myservices_template_id) - set(service_template_id))
                    for (_, service) in iteritems(services):
                        if service['_templates'][0] in services_to_add:
                            post_internal('service', [service])
                    for template_id in services_to_del:
                        if template_id in myservices_bis:
                            lookup = {
                                "_id": myservices_bis[template_id]['_id']
                            }
                            deleteitem_internal('service', False, False,
                                                **lookup)
Esempio n. 19
0
def execute_delete(resource: str, identifier):
    """Executes DELETE to the same DeviceHub with a new connection."""
    _, _, _, status = deleteitem_internal(resource, **{'_id': str(identifier)})
    if status != 204:
        raise InnerRequestError(status, {})
Esempio n. 20
0
    def on_updated_host(updates, original):
        """Called by EVE HOOK (app.on_updated_host)

        After host updated,
        if host is a template, report value of fields updated on host used this template
        if host is not template, add or remove services templates if _templates changed

        :param updates: modified fields
        :type updates: dict
        :param original: original fields
        :type original: dict
        :return: None
        """
        # pylint: disable=too-many-locals, too-many-nested-blocks
        if g.get('ignore_hook_patch', False):
            g.ignore_hook_patch = False
            return
        if original['_is_template']:
            # We must update all host using this template
            host_db = current_app.data.driver.db['host']
            hosts = host_db.find({'_templates': original['_id']})
            for host in hosts:
                Template.update_host_use_template(host, updates)
        else:
            if '_templates' in updates and updates['_templates'] != original[
                    '_templates']:
                if original['_templates_with_services']:
                    service_db = current_app.data.driver.db['service']

                    # Get all the real services of this host
                    myservices = service_db.find({
                        '_is_template': False,
                        'host': original['_id']
                    })
                    myservices_template_id = []
                    myservices_bis = {}
                    for myservice in myservices:
                        # Consider all the service templates... not only the first one!
                        for template_srv in myservice['_templates']:
                            myservices_template_id.append(template_srv)
                            myservices_bis[template_srv] = myservice

                    # Find services templates in the update
                    services = Template.get_host_template_services(
                        original, True, updates['_templates'])
                    service_template_id = []
                    for service_name in services:
                        service = services[service_name]
                        for template_srv_id in service['_templates']:
                            service_template_id.append(template_srv_id)

                    # Compare servies to add/delete
                    services_to_add = list(
                        set(service_template_id) - set(myservices_template_id))
                    services_to_del = list(
                        set(myservices_template_id) - set(service_template_id))
                    for service_name in services:
                        service = services[service_name]
                        for template_srv_id in service['_templates']:
                            if template_srv_id in services_to_add:
                                post_internal('service', [service])
                    for template_id in services_to_del:
                        if template_id in myservices_bis:
                            lookup = {
                                "_id": myservices_bis[template_id]['_id']
                            }
                            deleteitem_internal('service', False, False,
                                                **lookup)
Esempio n. 21
0
def execute_delete(resource: str, identifier):
    """Executes DELETE to the same DeviceHub with a new connection."""
    _, _, _, status = deleteitem_internal(resource, **{'_id': str(identifier)})
    if status != 204:
        raise InnerRequestError(status, {})