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): 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.')
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.')
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.')
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.')