Esempio n. 1
0
    def update_node_from_rules(self, rules, user, computer, obj_ui, obj, action, node, policy, rule_type, job_ids_by_computer):
        updated = updated_updated_by = False
        attributes_jobs_updated = []
        attributes_updated_by_updated = []
        for field_chef, field_ui in rules.items():
            if is_user_policy(field_chef) and 'user' not in computer:
                continue
            job_attr = '.'.join(field_chef.split('.')[:3]) + '.job_ids'
            updated_by_attr = self.get_updated_by_fieldname(field_chef, policy, obj, computer)
            priority_obj_ui = obj_ui
            obj_ui_field = None
            if (rule_type == 'policies' or not policy.get('is_emitter_policy', False)) and updated_by_attr not in attributes_updated_by_updated:
                updated_updated_by = updated_updated_by or self.update_node_updated_by(node, field_chef, obj, action, updated_by_attr, attributes_updated_by_updated)
            priority_obj = self.priority_object(node, updated_by_attr, obj, action)
            if priority_obj != obj:
                priority_obj_ui = self.get_object_ui(rule_type, priority_obj, node, policy)
            if priority_obj.get('_id', None) == obj.get('_id', None) or action == DELETED_POLICY_ACTION:
                if callable(field_ui):
                    if is_user_policy(field_chef):
                        priority_obj = computer['user']
                    obj_ui_field = field_ui(priority_obj_ui, obj=priority_obj, node=node, field_chef=field_chef)
                else:
                    obj_ui_field = priority_obj_ui.get(field_ui, None)

                if obj_ui_field is None and action != DELETED_POLICY_ACTION:
                    continue
                elif obj_ui_field is None and action == DELETED_POLICY_ACTION:
                    try:
                        obj_ui_field = delete_dotted(node.attributes, field_chef)
                        updated = True
                    except KeyError:
                        pass
                else:
                    try:
                        value_field_chef = node.attributes.get_dotted(field_chef)
                    except KeyError:
                        value_field_chef = None
                    if obj_ui_field != value_field_chef:
                        node.attributes.set_dotted(field_chef, obj_ui_field)
                        updated = True
            if job_attr not in attributes_jobs_updated:
                if updated:
                    self.update_node_job_id(user, obj, action, computer, node, policy, job_attr, attributes_jobs_updated, job_ids_by_computer)
        return (node, (updated or updated_updated_by))
Esempio n. 2
0
    def command(self):
        from gecoscc.api.chef_status import USERS_OLD, USERS_OHAI
        # Initialization
        self.api = _get_chef_api(self.settings.get('chef.url'),
                            toChefUsername(self.options.chef_username),
                            self.options.chef_pem, False, self.settings.get('chef.version'))

        self.db = self.pyramid.db

        # Check administrator user
        auth_user = self.db.adminusers.find_one({'username': self.options.chef_username})
        if auth_user is None:
            logger.error('The administrator user must exist in MongoDB')
            sys.exit(1)

        # Recorriendo todos los nodos 
        for node_id in ChefNode.list():
            node = ChefNode(node_id, self.api)
            logger.info('Checking node: %s'%(node_id))
            
            try:
                if node.attributes.get_dotted(USERS_OLD):
                    delete_dotted(node.attributes, USERS_OLD)
                    node.save()
            except KeyError:
                logger.warn("Not found attribute: %s"%(USERS_OLD))
            except:
                logger.warn("Problem deleting users_old attribute from node: %s"%(node_id))

            # Updating users list    
            computer = self.db.nodes.find_one({'node_chef_id': node_id, 'type':'computer'})
            if not computer:
                logger.error('This node does not exist (mongodb)')
                continue
 
            chef_node_usernames = set([d['username'] for d in  node.attributes.get_dotted(USERS_OHAI)])
            gcc_node_usernames  = set([d['name'] for d in self.db.nodes.find({
                                       'type':'user',
                                       'computers': {'$in': [computer['_id']]}
                                    },
                                    {'_id':0, 'name':1})
                                 ])


            users_recalculate_policies = []
            users_remove_policies = []

            # Users added/removed ?
            if set.symmetric_difference(chef_node_usernames, gcc_node_usernames):
                logger.info("Users added/removed found.")

                # Add users or vinculate user to computer if already exists
                addusers = set.difference(chef_node_usernames, gcc_node_usernames)
                for add in addusers:
                    logger.info("Added user: %s"%(add))
                    user = self.db.nodes.find_one({'name': add, 'type': 'user', 'path': get_filter_in_domain(computer)})

                    if not user:
                        user_model = User()
                        user = user_model.serialize({'name': add,
                                                     'path': computer.get('path', ''),
                                                     'type': 'user',
                                                     'lock': computer.get('lock', ''),
                                                     'source': computer.get('source', '')})

                        user = update_computers_of_user(self.db, user, self.api)

                        del user['_id']
                        user_id = self.db.nodes.insert(user)
                        user = self.db.nodes.find_one({'_id': user_id})
                        users_recalculate_policies.append(user)

                    else:
                        computers = user.get('computers', [])
                        if computer['_id'] not in computers:
                            computers.append(computer['_id'])
                            self.db.nodes.update({'_id': user['_id']}, {'$set': {'computers': computers}})
                            users_recalculate_policies.append(user)
                            add_computer_to_user(computer['_id'], user['_id'])

                # Removed users
                delusers = set.difference(gcc_node_usernames, chef_node_usernames)
                for delete in delusers:
                    logger.info("Deleted user: %s"%(delete))
                    user = self.db.nodes.find_one({'name': delete,
                                                   'type': 'user',
                                                   'path': get_filter_in_domain(computer)})
                    computers = user['computers'] if user else []
                    if computer['_id'] in computers:
                        users_remove_policies.append(deepcopy(user))
                        computers.remove(computer['_id'])
                        self.db.nodes.update({'_id': user['_id']}, {'$set': {'computers': computers}})

                for user in users_recalculate_policies:
                    apply_policies_to_user(self.db.nodes, user, auth_user)

                for user in users_remove_policies:
                    remove_policies_of_computer(user, computer, auth_user)
    def command(self):
        # Initialization
        logger.info("MIGRATION SCRIPT FOR USER_APPS_AUTOSTART POLICY")
        logger.info("###############################################")

        # Disabling InsecureRequestWarning Unverified HTTPS request
        requests.packages.urllib3.disable_warnings()

        sanitized = False
        ous = []
        groups = []
        users = []
        self.api = _get_chef_api(self.settings.get('chef.url'),
                                 toChefUsername(self.options.chef_username),
                                 self.options.chef_pem, False,
                                 self.settings.get('chef.version'))

        self.auth_user = self.db.adminusers.find_one(
            {'username': self.options.chef_username})
        if self.auth_user is None:
            logger.error('The administrator user must exist in MongoDB')
            sys.exit(1)

        self.db = self.pyramid.db

        # Get local_users (Users) policy
        logger.info('Getting policy schema (user_apps_autostart_res) ...')
        policy = self.db.policies.find_one({'slug': 'user_apps_autostart_res'})
        schema = policy['schema']
        policyId = policy['_id']

        logger.info('schema   = %s' % str(schema))
        logger.debug('policyId = %s' % str(policyId))

        # Searching nodes with the Local Administrators policy
        # Query Fields of an Embedded Document (Mongo documentation)
        # Example:
        # db.nodes.find({"policies.58c8122a0dfd425b0894d5b6":{$exists:true}})
        logger.info('Searching for nodes with applied policy...')
        field = 'policies.' + str(policyId)
        filters = {field: {'$exists': True}}
        nodes = self.db.nodes.find(filters)

        # Validating data and, where appropiate, fixing
        for node in nodes:
            instance = node['policies'][unicode(policyId)]
            logger.info("node = %s" % str(node))

            logger.info('-----------------------------------------------')
            logger.info('Node name = %s, mongo_id = %s' %
                        (node['name'], str(node['_id'])))
            logger.info('Instance of the policy on the node: %s' %
                        str(instance))
            while True:
                try:
                    validate(instance, schema)
                    break
                except ValidationError as e:
                    logger.warn('Validation error on instance = %s' %
                                str(e.message))
                    # Sanitize instance
                    self.sanitize(e, instance)
                    sanitized = True

            if sanitized:
                # Setting false sanitized for next iteration
                sanitized = False
                logger.info(
                    'Sanitized instance of the policy on the node AFTER calling the validate method: %s'
                    % str(instance))

                # Update mongo
                logger.info('Updating instance in database (mongo) ...')
                self.db.nodes.update({'_id': node['_id']},
                                     {'$set': {
                                         field: instance
                                     }})

                logger.info('Recalculating policies in the node.')
                # Affected nodes
                if node['type'] == 'ou':
                    ous.append(node)
                elif node['type'] == 'group':
                    groups.append(node)
                elif node['type'] == 'user':
                    users.append(node)

        # We only go through the highest level OUs.
        # Therefore, we eliminate intermediate OUs and
        # then do not recalculate the policies
        # for the same node several times.
        for ou in ous:
            parents = [
                ObjectId(oid) for oid in ou['path'].split(',') if oid != 'root'
            ]
            if any(o['_id'] in parents for o in ous):
                ous.remove(ou)

        # Users that are not under an OU or GROUP that have the migrated policy
        for user in users:
            parents = [
                ObjectId(oid) for oid in user['path'].split(',')
                if oid != 'root'
            ]
            if any(o['_id'] in parents for o in ous):
                users.remove(user)
            elif any(user['_id'] in group['members'] for group in groups):
                users.remove(user)

        # Recalculating policies for OU
        for ou in ous:
            old = deepcopy(ou)
            del old["policies"][str(policyId)]
            object_changed(self.auth_user, 'ou', ou, old)

        # Recalculating policies for GROUP
        for group in groups:
            old = deepcopy(group)
            del old["policies"][str(policyId)]
            object_changed(self.auth_user, 'group', group, old)

        # Recalculating policies for USER
        for user in users:
            old = deepcopy(user)
            del old["policies"][str(policyId)]
            object_changed(self.auth_user, 'user', user, old)

        # Removing unused desktops_to_remove attribute in chef nodes
        logger.info('\n')
        logger.info(
            'Removing unused desktops_to_remove attribute in chef nodes ...')
        for node_id in ChefNode.list():
            node = ChefNode(node_id, self.api)
            logger.info('Checking node: %s' % (node_id))
            field_chef = '%s.users' % policy['path']
            users = node.attributes.get_dotted(
                field_chef) if node.attributes.has_dotted(field_chef) else []
            for user in users:
                logger.debug("user = %s" % (user))
                attr_delete_path = '%s.%s.desktops_to_remove' % (field_chef,
                                                                 user)
                logger.debug('Atttribute dotted path: %s' % (attr_delete_path))
                if node.attributes.has_dotted(attr_delete_path):
                    logger.warn(
                        "Remove 'desktops_to_remove' attribute! for user %s" %
                        (user))
                    try:
                        delete_dotted(node.attributes, attr_delete_path)
                        node.save()
                    except:
                        logger.warn(
                            "Problem deleting desktops_to_remove value from node: %s"
                            % (node_id))
                        logger.warn(
                            "You may be trying to delete a default attribute instead normal attribute: %s"
                            % (node_id))

        logger.info('Finished.')
    def command(self):
        # Initialization
        sanitized = False
        computers = set()
        self.api = _get_chef_api(self.settings.get('chef.url'),
                                 toChefUsername(self.options.chef_username),
                                 self.options.chef_pem, False,
                                 self.settings.get('chef.version'))

        self.auth_user = self.db.adminusers.find_one(
            {'username': self.options.chef_username})
        if self.auth_user is None:
            logger.error('The administrator user must exist in MongoDB')
            sys.exit(1)

        self.db = self.pyramid.db

        # Get local_admin_users_res (Local Administrators) policy
        logger.info(
            'Getting Local Administrators (local_admin_users_res) policy ...')
        policy = self.db.policies.find_one({'slug': 'local_admin_users_res'})
        schema = policy['schema']
        policyId = policy['_id']

        logger.info('schema   = %s' % str(schema))
        logger.info('Id.policy = %s' % str(policyId))

        # Searching nodes with the Local Administrators policy
        # Query Fields of an Embedded Document (Mongo documentation)
        # Example:
        # db.nodes.find({"policies.58c8122a0dfd425b0894d5b6":{$exists:true}})
        logger.info('Searching nodes with the Local Administrators policy...')
        field = 'policies.' + str(policyId)
        filters = {field: {'$exists': True}}
        nodes = self.db.nodes.find(filters)

        # Validating data and, where appropiate, fixing
        for node in nodes:
            instance = node['policies'][unicode(policyId)]

            logger.info('Node name = %s, _id = %s' %
                        (node['name'], str(node['_id'])))
            logger.info('Instance before validate method: %s' % str(instance))
            while True:
                try:
                    validate(instance, schema)
                    break
                except ValidationError as e:
                    logger.warning('Validation error on instance = %s' %
                                   str(e.message))
                    # Sanitize instance
                    self.sanitize(e, instance)
                    sanitized = True

            if sanitized:
                # Setting false sanitized for next iteration
                sanitized = False
                logger.info('Sanitized instance: %s' % str(instance))

                # Update mongo
                self.db.nodes.update({'_id': node['_id']},
                                     {'$set': {
                                         field: instance
                                     }})

                # Affected nodes
                if node['type'] == 'ou':
                    result = list(
                        self.db.nodes.find(
                            {
                                'path': get_filter_nodes_belonging_ou(
                                    node['_id']),
                                'type': 'computer'
                            }, {'_id': 1}))
                    logger.info('OU computers = %s' % str(result))
                elif node['type'] == 'group':
                    result = list(
                        self.db.nodes.find(
                            {
                                '_id': {
                                    '$in': node['members']
                                },
                                'type': 'computer'
                            }, {'_id': 1}))
                    logger.info('GROUP computers = %s' % str(result))
                elif node['type'] == 'computer':
                    result = [node]
                    logger.info('COMPUTER computers = %s' % str(result))

                [computers.add(str(n['_id'])) for n in result]

        # Removing unused local_admin_remove_list attribute in chef nodes
        for node_id in ChefNode.list():
            node = ChefNode(node_id, self.api)
            logger.info('Checking node: %s' % (node_id))
            attr_dotted = policy['path'] + '.local_admin_remove_list'
            logger.info('Atttribute dotted path: %s' % (attr_dotted))
            if node.attributes.has_dotted(attr_dotted):
                logger.info("Remove 'local_admin_remove_list' attribute!")
                try:
                    logger.info(
                        "node.attributes = %s" %
                        str(node.attributes['gecos_ws_mgmt']['misc_mgmt']
                            ['local_admin_users_res'].to_dict()))
                    delete_dotted(node.attributes, attr_dotted)
                    node.save()
                except:
                    logger.warn(
                        "Problem deleting local_admin_remove_list value from node: %s"
                        % (node_id))
                    logger.warn(
                        "You may be trying to delete a default attribute instead normal attribute: %s"
                        % (node_id))

        for computer in computers:
            logger.info('computer = %s' % str(computer))
            computer = self.db.nodes.find_one({'_id': ObjectId(computer)})
            apply_policies_to_computer(self.db.nodes,
                                       computer,
                                       self.auth_user,
                                       api=self.api,
                                       initialize=False,
                                       use_celery=False)

        logger.info('Finished.')
Esempio n. 5
0
    def update_node_from_rules(self, rules, user, computer, obj_ui, obj,
                               action, node, policy, rule_type,
                               job_ids_by_computer):
        updated = updated_updated_by = False
        attributes_jobs_updated = []
        attributes_updated_by_updated = []
        for field_chef, field_ui in rules.items():
            if is_user_policy(field_chef) and 'user' not in computer:
                continue
            job_attr = '.'.join(field_chef.split('.')[:3]) + '.job_ids'
            updated_by_attr = self.get_updated_by_fieldname(
                field_chef, policy, obj, computer)
            priority_obj_ui = obj_ui
            obj_ui_field = None
            if (rule_type == 'policies'
                    or not policy.get('is_emitter_policy', False)
                ) and updated_by_attr not in attributes_updated_by_updated:
                updated_updated_by = updated_updated_by or self.update_node_updated_by(
                    node, field_chef, obj, action, updated_by_attr,
                    attributes_updated_by_updated)
            priority_obj = self.priority_object(node, updated_by_attr, obj,
                                                action)
            if priority_obj != obj:
                priority_obj_ui = self.get_object_ui(rule_type, priority_obj,
                                                     node, policy)
            if priority_obj.get('_id', None) == obj.get(
                    '_id', None) or action == DELETED_POLICY_ACTION:
                if callable(field_ui):
                    if is_user_policy(field_chef):
                        priority_obj = computer['user']
                    obj_ui_field = field_ui(priority_obj_ui,
                                            obj=priority_obj,
                                            node=node,
                                            field_chef=field_chef)
                else:
                    obj_ui_field = priority_obj_ui.get(field_ui, None)

                if obj_ui_field is None and action != DELETED_POLICY_ACTION:
                    continue
                elif obj_ui_field is None and action == DELETED_POLICY_ACTION:
                    try:
                        obj_ui_field = delete_dotted(node.attributes,
                                                     field_chef)
                        updated = True
                    except KeyError:
                        pass
                else:
                    try:
                        value_field_chef = node.attributes.get_dotted(
                            field_chef)
                    except KeyError:
                        value_field_chef = None
                    if obj_ui_field != value_field_chef:
                        node.attributes.set_dotted(field_chef, obj_ui_field)
                        updated = True
            if job_attr not in attributes_jobs_updated:
                if updated:
                    self.update_node_job_id(user, obj, action, computer, node,
                                            policy, job_attr,
                                            attributes_jobs_updated,
                                            job_ids_by_computer)
        return (node, (updated or updated_updated_by))
    def command(self):
        # Initialization
        sanitized = False
        computers = set()
        self.api = _get_chef_api(self.settings.get('chef.url'),
                            toChefUsername(self.options.chef_username),
                            self.options.chef_pem, False, self.settings.get('chef.version'))

        self.auth_user = self.db.adminusers.find_one({'username': self.options.chef_username})
        if self.auth_user is None:
            logger.error('The administrator user must exist in MongoDB')
            sys.exit(1)

        self.db = self.pyramid.db
        
        # Get local_admin_users_res (Local Administrators) policy
        logger.info('Getting Local Administrators (local_admin_users_res) policy ...')
        policy   = self.db.policies.find_one({'slug':'local_admin_users_res'})
        schema   = policy['schema']
        policyId = policy['_id']
        
        logger.info('schema   = %s'%str(schema))
        logger.info('Id.policy = %s'%str(policyId))

        # Searching nodes with the Local Administrators policy
        # Query Fields of an Embedded Document (Mongo documentation)
        # Example:
        # db.nodes.find({"policies.58c8122a0dfd425b0894d5b6":{$exists:true}})
        logger.info('Searching nodes with the Local Administrators policy...')
        field = 'policies.' + str(policyId)
        filters  = {field:{'$exists':True}}
        nodes = self.db.nodes.find(filters)
  
        # Validating data and, where appropiate, fixing
        for node in nodes:
            instance = node['policies'][unicode(policyId)]

            logger.info('Node name = %s, _id = %s'%(node['name'],str(node['_id'])))
            logger.info('Instance before validate method: %s'%str(instance))
            while True:
                try:
                    validate(instance, schema)
                    break
                except ValidationError as e: 
                     logger.warning('Validation error on instance = %s'%str(e.message))
                     # Sanitize instance
                     self.sanitize(e, instance)
                     sanitized = True

            if sanitized:
                # Setting false sanitized for next iteration
                sanitized = False
                logger.info('Sanitized instance: %s'%str(instance))

                # Update mongo
                self.db.nodes.update({'_id': node['_id']},{'$set':{field:instance}})

                # Affected nodes
                if node['type'] == 'ou':
                    result = list(self.db.nodes.find({'path': get_filter_nodes_belonging_ou(node['_id']),'type': 'computer'},{'_id':1}))
                    logger.info('OU computers = %s'%str(result))
                elif node['type'] == 'group':
                    result = list(self.db.nodes.find({'_id':{'$in':node['members']},'type':'computer'},{'_id':1}))
                    logger.info('GROUP computers = %s'%str(result))
                elif node['type'] == 'computer':
                    result = [node]
                    logger.info('COMPUTER computers = %s'%str(result))

                [computers.add(str(n['_id'])) for n in result]


        # Removing unused local_admin_remove_list attribute in chef nodes
        for node_id in ChefNode.list():
            node = ChefNode(node_id, self.api)
            logger.info('Checking node: %s'%(node_id))
            attr_dotted = policy['path'] + '.local_admin_remove_list'
            logger.info('Atttribute dotted path: %s'%(attr_dotted))
            if node.attributes.has_dotted(attr_dotted):
                logger.info("Remove 'local_admin_remove_list' attribute!")
                try:
                    logger.info("node.attributes = %s" % str(node.attributes['gecos_ws_mgmt']['misc_mgmt']['local_admin_users_res'].to_dict()))
                    delete_dotted(node.attributes, attr_dotted)
                    node.save()
                except:
                    logger.warn("Problem deleting local_admin_remove_list value from node: %s"%(node_id))
                    logger.warn("You may be trying to delete a default attribute instead normal attribute: %s"%(node_id))

        for computer in computers:
            logger.info('computer = %s'%str(computer))
            computer = self.db.nodes.find_one({'_id': ObjectId(computer)})
            apply_policies_to_computer(self.db.nodes, computer, self.auth_user, api=self.api, initialize=False, use_celery=False)
                   
        logger.info('Finished.')
    def command(self):
        # Initialization
        logger.info("MIGRATION SCRIPT FOR FILES LIST POLICY")
        logger.info("######################################")

        # Disabling InsecureRequestWarning Unverified HTTPS request
        requests.packages.urllib3.disable_warnings()

        sanitized = False
        computers = set()                 
        self.api = _get_chef_api(self.settings.get('chef.url'),
                            toChefUsername(self.options.chef_username),
                            self.options.chef_pem, False, self.settings.get('chef.version'))

        self.auth_user = self.db.adminusers.find_one({'username': self.options.chef_username})
        if self.auth_user is None:
            logger.error('The administrator user must exist in MongoDB')
            sys.exit(1)

        self.db = self.pyramid.db
        
        # Get local_file (File list) policy
        logger.info('Getting policy schema (local_file_res) ...')
        policy   = self.db.policies.find_one({'slug':'local_file_res'})
        schema   = policy['schema']
        policyId = policy['_id']
        
        logger.info('schema   = %s'%str(schema))
        logger.debug('policyId = %s'%str(policyId))

        # Searching nodes with the File List policy
        # Query Fields of an Embedded Document (Mongo documentation)
        # Example:
        # db.nodes.find({"policies.58c8122a0dfd425b0894d5b6":{$exists:true}})
        logger.info('Searching for nodes with applied policy...')
        field = 'policies.' + str(policyId)
        filters  = {field:{'$exists':True}}
        nodes = self.db.nodes.find(filters)
  
        # Validating data and, where appropiate, fixing
        for node in nodes:
            instance = node['policies'][unicode(policyId)]
            logger.debug("node = %s" % str(node))

            logger.info('-----------------------------------------------')
            logger.info('Node name = %s, mongo_id = %s'%(node['name'],str(node['_id'])))
            logger.info('Instance of the policy on the node: %s'%str(instance))
            while True:
                try:
                    validate(instance, schema)
                    break
                except ValidationError as e:
                    logger.warn('Validation error on instance: instance = %s'%str(instance))
                    logger.warn('Validation error on instance: message error = %s'%str(e.message))
                    # Sanitize instance
                    self.sanitize(e, instance)
                    sanitized = True

            if sanitized:
                # Setting false sanitized for next iteration
                sanitized = False
                logger.info('Sanitized instance of the policy on the node AFTER calling the validate method: %s'%str(instance))

                # Update mongo
                logger.info('Updating instance in database (mongo) ...')
                self.db.nodes.update({'_id': node['_id']},{'$set':{field:instance}})

                logger.info('Recalculating policies in the node.')

                # Affected nodes
                if node['type'] == 'ou':
                    result = list(self.db.nodes.find({'path': get_filter_nodes_belonging_ou(node['_id']),'type': 'computer'},{'_id':1}))
                    logger.info('OU computers = %s'%str(result))
                elif node['type'] == 'group':
                    result = list(self.db.nodes.find({'_id':{'$in':node['members']},'type':'computer'},{'_id':1}))
                    logger.info('GROUP computers = %s'%str(result))
                elif node['type'] == 'computer':
                    result = [node]
                    logger.info('COMPUTER computers = %s'%str(result))

                [computers.add(str(n['_id'])) for n in result]

        for computer in computers:
            logger.info('Applying policies to COMPUTER. For more information, see "gecosccui-celery.log" file')
            computer = self.db.nodes.find_one({'_id': ObjectId(computer)})
            apply_policies_to_computer(self.db.nodes, computer, self.auth_user, api=self.api, initialize=False, use_celery=True)

        # Removing unused attributes (copy_files, delete_files) in chef nodes
        logger.info('\n')
        attrs = ["%s.copy_files" % (policy['path']), "%s.delete_files" % (policy['path'])]
        logger.info('Removing unused attributes %s in chef nodes ...' % attrs)
        logger.info('\n')        
        
        for node_id in ChefNode.list():
            node = ChefNode(node_id, self.api)
            logger.info('Checking node: %s'%(node_id))
            
            for attr in attrs:
                try:
                    if node.attributes.has_dotted(attr):
                        logger.warn("Remove %s attribute!" % attr)
                        delete_dotted(node.attributes, attr)

                    node.save()

                except:
                    logger.warn("Problem deleting attribute %s value from node: %s"%(attr, node_id))
                    logger.warn("You may be trying to delete a default attribute instead normal attribute: %s"%(node_id))

        logger.info('Finished.')
Esempio n. 8
0
    def command(self):
        # Initialization
        logger.info("MIGRATION SCRIPT FOR FILES LIST POLICY")
        logger.info("######################################")

        # Disabling InsecureRequestWarning Unverified HTTPS request
        requests.packages.urllib3.disable_warnings()

        sanitized = False
        computers = set()
        self.api = _get_chef_api(self.settings.get('chef.url'),
                                 toChefUsername(self.options.chef_username),
                                 self.options.chef_pem, False,
                                 self.settings.get('chef.version'))

        self.auth_user = self.db.adminusers.find_one(
            {'username': self.options.chef_username})
        if self.auth_user is None:
            logger.error('The administrator user must exist in MongoDB')
            sys.exit(1)

        self.db = self.pyramid.db

        # Get local_file (File list) policy
        logger.info('Getting policy schema (local_file_res) ...')
        policy = self.db.policies.find_one({'slug': 'local_file_res'})
        schema = policy['schema']
        policyId = policy['_id']

        logger.info('schema   = %s' % str(schema))
        logger.debug('policyId = %s' % str(policyId))

        # Searching nodes with the File List policy
        # Query Fields of an Embedded Document (Mongo documentation)
        # Example:
        # db.nodes.find({"policies.58c8122a0dfd425b0894d5b6":{$exists:true}})
        logger.info('Searching for nodes with applied policy...')
        field = 'policies.' + str(policyId)
        filters = {field: {'$exists': True}}
        nodes = self.db.nodes.find(filters)

        # Validating data and, where appropiate, fixing
        for node in nodes:
            instance = node['policies'][unicode(policyId)]
            logger.debug("node = %s" % str(node))

            logger.info('-----------------------------------------------')
            logger.info('Node name = %s, mongo_id = %s' %
                        (node['name'], str(node['_id'])))
            logger.info('Instance of the policy on the node: %s' %
                        str(instance))
            while True:
                try:
                    validate(instance, schema)
                    break
                except ValidationError as e:
                    logger.warn('Validation error on instance: instance = %s' %
                                str(instance))
                    logger.warn(
                        'Validation error on instance: message error = %s' %
                        str(e.message))
                    # Sanitize instance
                    self.sanitize(e, instance)
                    sanitized = True

            if sanitized:
                # Setting false sanitized for next iteration
                sanitized = False
                logger.info(
                    'Sanitized instance of the policy on the node AFTER calling the validate method: %s'
                    % str(instance))

                # Update mongo
                logger.info('Updating instance in database (mongo) ...')
                self.db.nodes.update({'_id': node['_id']},
                                     {'$set': {
                                         field: instance
                                     }})

                logger.info('Recalculating policies in the node.')

                # Affected nodes
                if node['type'] == 'ou':
                    result = list(
                        self.db.nodes.find(
                            {
                                'path': get_filter_nodes_belonging_ou(
                                    node['_id']),
                                'type': 'computer'
                            }, {'_id': 1}))
                    logger.info('OU computers = %s' % str(result))
                elif node['type'] == 'group':
                    result = list(
                        self.db.nodes.find(
                            {
                                '_id': {
                                    '$in': node['members']
                                },
                                'type': 'computer'
                            }, {'_id': 1}))
                    logger.info('GROUP computers = %s' % str(result))
                elif node['type'] == 'computer':
                    result = [node]
                    logger.info('COMPUTER computers = %s' % str(result))

                [computers.add(str(n['_id'])) for n in result]

        for computer in computers:
            logger.info(
                'Applying policies to COMPUTER. For more information, see "gecosccui-celery.log" file'
            )
            computer = self.db.nodes.find_one({'_id': ObjectId(computer)})
            apply_policies_to_computer(self.db.nodes,
                                       computer,
                                       self.auth_user,
                                       api=self.api,
                                       initialize=False,
                                       use_celery=True)

        # Removing unused attributes (copy_files, delete_files) in chef nodes
        logger.info('\n')
        attrs = [
            "%s.copy_files" % (policy['path']),
            "%s.delete_files" % (policy['path'])
        ]
        logger.info('Removing unused attributes %s in chef nodes ...' % attrs)
        logger.info('\n')

        for node_id in ChefNode.list():
            node = ChefNode(node_id, self.api)
            logger.info('Checking node: %s' % (node_id))

            for attr in attrs:
                try:
                    if node.attributes.has_dotted(attr):
                        logger.warn("Remove %s attribute!" % attr)
                        delete_dotted(node.attributes, attr)

                    node.save()

                except:
                    logger.warn(
                        "Problem deleting attribute %s value from node: %s" %
                        (attr, node_id))
                    logger.warn(
                        "You may be trying to delete a default attribute instead normal attribute: %s"
                        % (node_id))

        logger.info('Finished.')
Esempio n. 9
0
    def command(self):
        from gecoscc.api.chef_status import USERS_OLD, USERS_OHAI
        # Initialization
        self.api = _get_chef_api(self.settings.get('chef.url'),
                                 toChefUsername(self.options.chef_username),
                                 self.options.chef_pem, False,
                                 self.settings.get('chef.version'))

        self.db = self.pyramid.db

        # Check administrator user
        auth_user = self.db.adminusers.find_one(
            {'username': self.options.chef_username})
        if auth_user is None:
            logger.error('The administrator user must exist in MongoDB')
            sys.exit(1)

        # Recorriendo todos los nodos
        for node_id in ChefNode.list():
            node = ChefNode(node_id, self.api)
            logger.info('Checking node: %s' % (node_id))

            try:
                if node.attributes.get_dotted(USERS_OLD):
                    delete_dotted(node.attributes, USERS_OLD)
                    node.save()
            except KeyError:
                logger.warn("Not found attribute: %s" % (USERS_OLD))
            except:
                logger.warn(
                    "Problem deleting users_old attribute from node: %s" %
                    (node_id))

            # Updating users list
            computer = self.db.nodes.find_one({
                'node_chef_id': node_id,
                'type': 'computer'
            })
            if not computer:
                logger.error('This node does not exist (mongodb)')
                continue

            chef_node_usernames = set([
                d['username'] for d in node.attributes.get_dotted(USERS_OHAI)
            ])
            gcc_node_usernames = set([
                d['name'] for d in self.db.nodes.find(
                    {
                        'type': 'user',
                        'computers': {
                            '$in': [computer['_id']]
                        }
                    }, {
                        '_id': 0,
                        'name': 1
                    })
            ])

            users_recalculate_policies = []
            users_remove_policies = []

            # Users added/removed ?
            if set.symmetric_difference(chef_node_usernames,
                                        gcc_node_usernames):
                logger.info("Users added/removed found.")

                # Add users or vinculate user to computer if already exists
                addusers = set.difference(chef_node_usernames,
                                          gcc_node_usernames)
                for add in addusers:
                    logger.info("Added user: %s" % (add))
                    user = self.db.nodes.find_one({
                        'name':
                        add,
                        'type':
                        'user',
                        'path':
                        get_filter_in_domain(computer)
                    })

                    if not user:
                        user_model = User()
                        user = user_model.serialize({
                            'name':
                            add,
                            'path':
                            computer.get('path', ''),
                            'type':
                            'user',
                            'lock':
                            computer.get('lock', ''),
                            'source':
                            computer.get('source', '')
                        })

                        user = update_computers_of_user(
                            self.db, user, self.api)

                        del user['_id']
                        user_id = self.db.nodes.insert(user)
                        user = self.db.nodes.find_one({'_id': user_id})
                        users_recalculate_policies.append(user)

                    else:
                        computers = user.get('computers', [])
                        if computer['_id'] not in computers:
                            computers.append(computer['_id'])
                            self.db.nodes.update(
                                {'_id': user['_id']},
                                {'$set': {
                                    'computers': computers
                                }})
                            users_recalculate_policies.append(user)
                            add_computer_to_user(computer['_id'], user['_id'])

                # Removed users
                delusers = set.difference(gcc_node_usernames,
                                          chef_node_usernames)
                for delete in delusers:
                    logger.info("Deleted user: %s" % (delete))
                    user = self.db.nodes.find_one({
                        'name':
                        delete,
                        'type':
                        'user',
                        'path':
                        get_filter_in_domain(computer)
                    })
                    computers = user['computers'] if user else []
                    if computer['_id'] in computers:
                        users_remove_policies.append(deepcopy(user))
                        computers.remove(computer['_id'])
                        self.db.nodes.update(
                            {'_id': user['_id']},
                            {'$set': {
                                'computers': computers
                            }})

                for user in users_recalculate_policies:
                    apply_policies_to_user(self.db.nodes, user, auth_user)

                for user in users_remove_policies:
                    remove_policies_of_computer(user, computer, auth_user)
    def command(self):
        # Initialization
        logger.info("MIGRATION SCRIPT FOR USER_APPS_AUTOSTART POLICY")
        logger.info("###############################################")

        # Disabling InsecureRequestWarning Unverified HTTPS request
        requests.packages.urllib3.disable_warnings()

        sanitized = False
        ous = []
        groups = []
        users = []
        self.api = _get_chef_api(self.settings.get('chef.url'),
                            toChefUsername(self.options.chef_username),
                            self.options.chef_pem, False, self.settings.get('chef.version'))

        self.auth_user = self.db.adminusers.find_one({'username': self.options.chef_username})
        if self.auth_user is None:
            logger.error('The administrator user must exist in MongoDB')
            sys.exit(1)

        self.db = self.pyramid.db
        
        # Get local_users (Users) policy
        logger.info('Getting policy schema (user_apps_autostart_res) ...')
        policy   = self.db.policies.find_one({'slug':'user_apps_autostart_res'})
        schema   = policy['schema']
        policyId = policy['_id']
        
        logger.info('schema   = %s'%str(schema))
        logger.debug('policyId = %s'%str(policyId))

        # Searching nodes with the Local Administrators policy
        # Query Fields of an Embedded Document (Mongo documentation)
        # Example:
        # db.nodes.find({"policies.58c8122a0dfd425b0894d5b6":{$exists:true}})
        logger.info('Searching for nodes with applied policy...')
        field = 'policies.' + str(policyId)
        filters  = {field:{'$exists':True}}
        nodes = self.db.nodes.find(filters)
  
        # Validating data and, where appropiate, fixing
        for node in nodes:
            instance = node['policies'][unicode(policyId)]
            logger.info("node = %s" % str(node))

            logger.info('-----------------------------------------------')
            logger.info('Node name = %s, mongo_id = %s'%(node['name'],str(node['_id'])))
            logger.info('Instance of the policy on the node: %s'%str(instance))
            while True:
                try:
                    validate(instance, schema)
                    break
                except ValidationError as e: 
                     logger.warn('Validation error on instance = %s'%str(e.message))
                     # Sanitize instance
                     self.sanitize(e, instance)
                     sanitized = True

            if sanitized:
                # Setting false sanitized for next iteration
                sanitized = False
                logger.info('Sanitized instance of the policy on the node AFTER calling the validate method: %s'%str(instance))

                # Update mongo
                logger.info('Updating instance in database (mongo) ...')
                self.db.nodes.update({'_id': node['_id']},{'$set':{field:instance}})

                logger.info('Recalculating policies in the node.')
                # Affected nodes
                if   node['type'] == 'ou':
                    ous.append(node)                                    
                elif node['type'] == 'group':                                             
                    groups.append(node)
                elif node['type'] == 'user':
                    users.append(node)

        # We only go through the highest level OUs. 
        # Therefore, we eliminate intermediate OUs and 
        # then do not recalculate the policies
        # for the same node several times.
        for ou in ous:
            parents = [ObjectId(oid) for oid in ou['path'].split(',') if oid != 'root']
            if any(o['_id'] in parents for o in ous):
                ous.remove(ou)

        # Users that are not under an OU or GROUP that have the migrated policy
        for user in users:
            parents = [ObjectId(oid) for oid in user['path'].split(',') if oid != 'root'] 
            if any(o['_id'] in parents for o in ous):
                users.remove(user)
            elif any(user['_id'] in group['members'] for group in groups):
                users.remove(user)

        # Recalculating policies for OU
        for ou in ous: 
            old = deepcopy(ou)
            del old["policies"][str(policyId)]
            object_changed(self.auth_user, 'ou', ou, old)

        # Recalculating policies for GROUP
        for group in groups:
            old = deepcopy(group)
            del old["policies"][str(policyId)]
            object_changed(self.auth_user, 'group', group, old)

        # Recalculating policies for USER
        for user in users:
            old = deepcopy(user)
            del old["policies"][str(policyId)]
            object_changed(self.auth_user, 'user', user, old)

        # Removing unused desktops_to_remove attribute in chef nodes
        logger.info('\n')
        logger.info('Removing unused desktops_to_remove attribute in chef nodes ...')
        for node_id in ChefNode.list():
            node = ChefNode(node_id, self.api)
            logger.info('Checking node: %s'%(node_id))
            field_chef = '%s.users' % policy['path']
            users = node.attributes.get_dotted(field_chef) if node.attributes.has_dotted(field_chef) else []
            for user in users:
                logger.debug("user = %s" % (user))
                attr_delete_path = '%s.%s.desktops_to_remove' % (field_chef, user)
                logger.debug('Atttribute dotted path: %s'%(attr_delete_path))
                if node.attributes.has_dotted(attr_delete_path):
                    logger.warn("Remove 'desktops_to_remove' attribute! for user %s" % (user))
                    try:
                        delete_dotted(node.attributes, attr_delete_path)
                        node.save()
                    except:
                        logger.warn("Problem deleting desktops_to_remove value from node: %s"%(node_id))
                        logger.warn("You may be trying to delete a default attribute instead normal attribute: %s"%(node_id))

        logger.info('Finished.')