def hosts(env=None, name=None): api = autoconfigure() if name: nodes = (node for node in Node.list() if name in Node(node).name) else: nodes = (node for node in Node.list() if Node(node).chef_environment == env) file = open("hosts", "w") file.write("[hosts]\n") map(lambda n: file.write("{0}\n".format(Node(n)['ipaddress'])), nodes)
def command(self): api = _get_chef_api(self.settings.get('chef.url'), toChefUsername(self.options.chef_username), self.options.chef_pem, self.settings.get('chef.ssl.verify'), self.settings.get('chef.version')) ou_name = 'ou_0' ou = self.create_root_ou(ou_name) for node_id in ChefNode.list(): try: node_mongo_id = register_or_updated_node(api, node_id, ou, self.db.nodes) except DuplicateKeyError: node_mongo_id = update_node(api, node_id, ou, self.db.nodes) if not node_mongo_id: print "%s does not exists" % node_id
def command(self): api = _get_chef_api(self.settings.get('chef.url'), toChefUsername(self.options.chef_username), self.options.chef_pem) ou_name = 'ou_0' ou = self.create_root_ou(ou_name) for node_id in ChefNode.list(): try: node_mongo_id = register_or_updated_node( api, node_id, ou, self.db.nodes) except DuplicateKeyError: node_mongo_id = update_node(api, node_id, ou, self.db.nodes) if not node_mongo_id: print "%s does not exists" % node_id
def get_node_attrs_from_chef(self): try: env_subnets_dict = {} node_attribute_dict = {} for organization in self.awshelper_obj.get_organizations(): node_attribute_dict = defaultdict(dict) node_list = Node.list(self.api) for environment in self.awshelper_obj.get_environments(organization): for region in self.awshelper_obj.get_regions(): vpc_list = self.awshelper_obj.get_vpc_in_region(region) if vpc_list: for vpc in self.awshelper_obj.get_vpc_in_region(region): env_subnets_dict = self.awshelper_obj.get_env_subnets(organization, region, vpc) for node in node_list: node_obj = Node(node, api=self.api) node_split = self.ah_obj.split_string(node, ["."]) if node_split is None or len(node_split)<=1: pass else: node_subnet = self.ah_obj.split_string(node, ['.'])[1] for key_tuple, environment in env_subnets_dict.iteritems(): if node_subnet in key_tuple: environment = env_subnets_dict[key_tuple] attribute_list = node_obj.attributes if 'ec2' in attribute_list: if 'instance_id' in node_obj.attributes.get_dotted('ec2'): instance_id = node_obj.attributes.get_dotted('ec2.instance_id') node_attribute_dict[instance_id]['node'] = node if 'os' in attribute_list: node_attribute_dict[instance_id]['os']=node_obj['os'] if 'os_version' in attribute_list: node_attribute_dict[instance_id]['os_version'] = node_obj['os_version'] if 'platform' in attribute_list: node_attribute_dict[instance_id]['platform'] = node_obj['platform'] if 'platform_version' in attribute_list: node_attribute_dict[instance_id]['platform_version'] = node_obj['platform_version'] if 'uptime' in attribute_list: node_attribute_dict[instance_id]['uptime'] = node_obj['uptime'] if 'idletime' in attribute_list: node_attribute_dict[instance_id]['idletime'] = node_obj['idletime'] return dict(node_attribute_dict) except Exception as exp_object: exc_type, exc_obj, exc_tb = sys.exc_info() self.ah_obj.print_exception("chef_helper.py", "get_node_attrs_from_chef1()", exp_object, exc_type, exc_obj, exc_tb) return {}
def lambda_handler(event, context): ec2c = boto3.client('ec2') api = chef.autoconfigure() chef_nodes = {} aws_is_running = [] nodes_to_remove = [] #Array of running ec2 instances - ip addresses for region in ec2c.describe_regions()['Regions']: ec2 = boto3.resource('ec2', region_name=region['RegionName']) for instance in ec2.instances.filter(Filters=[{'Name': 'instance-state-name', 'Values': ['running']}]): #print('Debug EC2 Instances: ', region['RegionName'], instance.private_ip_address) aws_is_running.append(instance.private_ip_address) #Dictionary of ip addresses (key) and Node objects (value) from Chef for name, nodeobj in Node.list().iteritems() : for key, value in nodeobj.attributes.iteritems(): if key == 'ipaddress' : #print('Debug Chef Nodes: ', value, nodeobj) chef_nodes.update({value : nodeobj}) #Calculating nodes to remove for key, node in chef_nodes.iteritems(): if key not in aws_is_running: nodes_to_remove.append(node) #Removing nodes in Chef that are no longer in AWS for node in nodes_to_remove: #print('Debug Nodes to Remove:', node['ipaddress']) node.delete() #So that the removed nodes are logged print 'Removed', [x['ipaddress'] for x in nodes_to_remove] return 'Removed', [x['ipaddress'] for x in nodes_to_remove]
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.')
def get_all_nodes(self): return Node.list().names
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 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 self.referenced_data_type = {} self.referenced_data_type['storage_can_view'] = 'storage' self.referenced_data_type['repository_can_view'] = 'repository' self.referenced_data_type['printer_can_view'] = 'printer' # Get all the policies structures logger.info('Getting all the policies structures from database...') dbpolicies = self.db.policies.find() self.policiesdata = {} self.slug_check = {} for policy in dbpolicies: logger.debug('Addig to dictionary: %s => %s'%(policy['_id'], json.dumps(policy['schema']))) self.policiesdata[str(policy['_id'])] = policy # Check policy slug field (must be unique) if policy['slug'] in self.slug_check: logger.error("There are more than one policy with '%s' slug!"%(policy['slug'])) else: self.slug_check[policy['slug']] = policy # Check policy serialization try: logger.debug('Serialized policy: %s'%(json.dumps(Policy().serialize(policy)))) except Exception as err: logger.error('Policy %s with slug %s can\'t be serialized: %s'%(policy['_id'], policy['slug'], str(err))) logger.info('Checking tree...') # Look for the root of the nodes tree root_nodes = self.db.nodes.find({"path" : "root"}) for root in root_nodes: self.check_node_and_subnodes(root) logger.info('Checking chef node references...') # Check the references to Chef nodes computers = self.db.nodes.find({"type" : "computer"}) for computer in computers: if "node_chef_id" in computer: # Check Chef node computer_node = ChefNode(computer['node_chef_id'], self.api) logger.info("Computer: %s Chef ID: %s"%(computer['name'], computer['node_chef_id'])) if not computer_node.exists: logger.error("No Chef node with ID %s!"%(computer['node_chef_id'])) else: logger.error("No Chef ID in '%s' computer!"%(computer['name'])) logger.info('Checking MongoDB computer references...') # Check the references to computer nodes for node_id in ChefNode.list(): found = False computers = self.db.nodes.find({"node_chef_id" : node_id}) for computer in computers: found = True if not found: pclabel = "(No OHAI-GECOS data in the node)" computer_node = ChefNode(node_id, self.api) try: pclabel = "(pclabel = %s)"%( computer_node.attributes.get_dotted('ohai_gecos.pclabel') ) except KeyError: pass logger.error("No computer node for Chef ID: '%s' %s!"%(node_id, pclabel)) logger.info('END ;)')
def command(self): # 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.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') return self.db = self.pyramid.db ous = [] groups = [] computers = [] # Get packages policy ID packages_policy = self.db.policies.find_one({"slug": "package_res"}) if packages_policy is None: logger.error('Can\'t detect "package_res" policy!') return if 'pkgs_to_remove' in packages_policy["schema"]["properties"]: logger.error("The 'package_res' policy in the system is deprecated, please update to new package policy!") return logger.info('Packages policy ID: %s'%(str(packages_policy['_id']))) # Get all nodes with old package policy data logger.info('Getting all nodes with old package policy data...') path_to_find = "policies.%s.pkgs_to_remove"%(str(packages_policy['_id'])) old_policy_nodes = self.db.nodes.find({ '$query': {path_to_find: { '$exists': True }}, '$orderby': { "path" : 1 }}) updated_nodes = [] for node in old_policy_nodes: logger.info('Updating node %s ...'%(str(node['_id']))) updated_nodes.append(str(node['_id'])) logger.debug('Packages to add: %s'%(str(node['policies'][str(packages_policy['_id'])]['package_list']))) logger.debug('Packages to remove: %s'%(str(node['policies'][str(packages_policy['_id'])]['pkgs_to_remove']))) # Join the lists package_list = [] for package_name in node['policies'][str(packages_policy['_id'])]['package_list']: package_list.append({'name': package_name, 'version': 'current', 'action': 'add'}) for package_name in node['policies'][str(packages_policy['_id'])]['pkgs_to_remove']: package_list.append({'name': package_name, 'version': 'current', 'action': 'remove'}) if 'pkgs_to_remove' in node['policies'][str(packages_policy['_id'])]: del node['policies'][str(packages_policy['_id'])]['pkgs_to_remove'] node['policies'][str(packages_policy['_id'])]['package_list'] = package_list # Update policies self.db.nodes.update({'_id': node['_id']}, {'$set': {'policies': node['policies']}}) logger.debug('Joined list: %s'%(str(node['policies'][str(packages_policy['_id'])]['package_list']))) if node['type'] == 'ou': ous.append(node) elif node['type'] == 'group': groups.append(node) elif node['type'] == 'computer': computers.append(node) logger.info('%s nodes were updated!'%(len(updated_nodes))) # 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 computer in computers: parents = [ObjectId(oid) for oid in computer['path'].split(',') if oid != 'root'] if any(o['_id'] in parents for o in ous): computers.remove(computer) elif any(computer['_id'] in group['members'] for group in groups): computers.remove(computer) # Recalculating policies for OU for ou in ous: old = deepcopy(ou) del old["policies"][str(packages_policy['_id'])] object_changed(self.auth_user, 'ou', ou, old) # Recalculating policies for GROUP for group in groups: old = deepcopy(group) del old["policies"][str(packages_policy['_id'])] object_changed(self.auth_user, 'group', group, old) # Recalculating policies for USER for computer in computers: old = deepcopy(computer) del old["policies"][str(packages_policy['_id'])] object_changed(self.auth_user, 'computer', computer, old) # Recalculate policies for Chef nodes for node_id in ChefNode.list(): node = ChefNode(node_id, self.api) logger.info('Checking node: %s'%(node_id)) if ("gecos_ws_mgmt" in node.attributes) and ("software_mgmt" in node.attributes["gecos_ws_mgmt"]) and ("package_res" in node.attributes["gecos_ws_mgmt"]["software_mgmt"]): if "pkgs_to_remove" in node.attributes["gecos_ws_mgmt"]["software_mgmt"]["package_res"]: logger.debug("Chef node %s contains a pkgs_to_remove value!"%(node_id)) # Remove pkgs_to_remove from mongodb node logger.info("Remove 'pkgs_to_remove' attribute!") try: del node.attributes["gecos_ws_mgmt"]["software_mgmt"]["package_res"]["pkgs_to_remove"] node.save() except: logger.warn("Problem deleting pkgs_to_remove value from node: %s"%(node_id)) if not "package_list" in node.attributes["gecos_ws_mgmt"]["software_mgmt"]["package_res"]: logger.error("Chef node %s doesn\'t contains a package_list value!"%(node_id)) continue package_list = node.attributes["gecos_ws_mgmt"]["software_mgmt"]["package_res"]["package_list"] for element in package_list: if not 'action' in element: logger.debug('Chef node: %s doesn\'t have an action value in package_res! (package_list:%s)'%(node_id, str(package_list))) break # Final check bad_nodes = Search('node', "pkgs_to_remove:*", rows=1000, start=0, api=self.api) for node in bad_nodes: logger.warn('Detected bad node: %s'%(node.object.name)) gecos_node = self.db.nodes.find_one({"node_chef_id": node.object.name}) if gecos_node is None: logger.warn('Can\'t find node in MongoDB for: %s'%(node.object.name)) else: logger.warn('For an unknown reason a computer called %s wasn\'t updated!'%(gecos_node['name'])) logger.info('END ;)')
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 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 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') return self.db = self.pyramid.db ous = [] groups = [] computers = [] # Get packages policy ID packages_policy = self.db.policies.find_one({"slug": "package_res"}) if packages_policy is None: logger.error('Can\'t detect "package_res" policy!') return if 'pkgs_to_remove' in packages_policy["schema"]["properties"]: logger.error( "The 'package_res' policy in the system is deprecated, please update to new package policy!" ) return logger.info('Packages policy ID: %s' % (str(packages_policy['_id']))) # Get all nodes with old package policy data logger.info('Getting all nodes with old package policy data...') path_to_find = "policies.%s.pkgs_to_remove" % (str( packages_policy['_id'])) old_policy_nodes = self.db.nodes.find({ '$query': { path_to_find: { '$exists': True } }, '$orderby': { "path": 1 } }) updated_nodes = [] for node in old_policy_nodes: logger.info('Updating node %s ...' % (str(node['_id']))) updated_nodes.append(str(node['_id'])) logger.debug('Packages to add: %s' % (str(node['policies'][str( packages_policy['_id'])]['package_list']))) logger.debug('Packages to remove: %s' % (str(node['policies'][str( packages_policy['_id'])]['pkgs_to_remove']))) # Join the lists package_list = [] for package_name in node['policies'][str( packages_policy['_id'])]['package_list']: package_list.append({ 'name': package_name, 'version': 'current', 'action': 'add' }) for package_name in node['policies'][str( packages_policy['_id'])]['pkgs_to_remove']: package_list.append({ 'name': package_name, 'version': 'current', 'action': 'remove' }) if 'pkgs_to_remove' in node['policies'][str( packages_policy['_id'])]: del node['policies'][str( packages_policy['_id'])]['pkgs_to_remove'] node['policies'][str( packages_policy['_id'])]['package_list'] = package_list # Update policies self.db.nodes.update({'_id': node['_id']}, {'$set': { 'policies': node['policies'] }}) logger.debug('Joined list: %s' % (str(node['policies'][str( packages_policy['_id'])]['package_list']))) if node['type'] == 'ou': ous.append(node) elif node['type'] == 'group': groups.append(node) elif node['type'] == 'computer': computers.append(node) logger.info('%s nodes were updated!' % (len(updated_nodes))) # 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 computer in computers: parents = [ ObjectId(oid) for oid in computer['path'].split(',') if oid != 'root' ] if any(o['_id'] in parents for o in ous): computers.remove(computer) elif any(computer['_id'] in group['members'] for group in groups): computers.remove(computer) # Recalculating policies for OU for ou in ous: old = deepcopy(ou) del old["policies"][str(packages_policy['_id'])] object_changed(self.auth_user, 'ou', ou, old) # Recalculating policies for GROUP for group in groups: old = deepcopy(group) del old["policies"][str(packages_policy['_id'])] object_changed(self.auth_user, 'group', group, old) # Recalculating policies for USER for computer in computers: old = deepcopy(computer) del old["policies"][str(packages_policy['_id'])] object_changed(self.auth_user, 'computer', computer, old) # Recalculate policies for Chef nodes for node_id in ChefNode.list(): node = ChefNode(node_id, self.api) logger.info('Checking node: %s' % (node_id)) if ("gecos_ws_mgmt" in node.attributes) and ( "software_mgmt" in node.attributes["gecos_ws_mgmt"]) and ( "package_res" in node.attributes["gecos_ws_mgmt"]["software_mgmt"]): if "pkgs_to_remove" in node.attributes["gecos_ws_mgmt"][ "software_mgmt"]["package_res"]: logger.debug( "Chef node %s contains a pkgs_to_remove value!" % (node_id)) # Remove pkgs_to_remove from mongodb node logger.info("Remove 'pkgs_to_remove' attribute!") try: del node.attributes["gecos_ws_mgmt"]["software_mgmt"][ "package_res"]["pkgs_to_remove"] node.save() except: logger.warn( "Problem deleting pkgs_to_remove value from node: %s" % (node_id)) if not "package_list" in node.attributes["gecos_ws_mgmt"][ "software_mgmt"]["package_res"]: logger.error( "Chef node %s doesn\'t contains a package_list value!" % (node_id)) continue package_list = node.attributes["gecos_ws_mgmt"][ "software_mgmt"]["package_res"]["package_list"] for element in package_list: if not 'action' in element: logger.debug( 'Chef node: %s doesn\'t have an action value in package_res! (package_list:%s)' % (node_id, str(package_list))) break # Final check bad_nodes = Search('node', "pkgs_to_remove:*", rows=1000, start=0, api=self.api) for node in bad_nodes: logger.warn('Detected bad node: %s' % (node.object.name)) gecos_node = self.db.nodes.find_one( {"node_chef_id": node.object.name}) if gecos_node is None: logger.warn('Can\'t find node in MongoDB for: %s' % (node.object.name)) else: logger.warn( 'For an unknown reason a computer called %s wasn\'t updated!' % (gecos_node['name'])) logger.info('END ;)')
def command(self): # 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 self.referenced_data_type = {} self.referenced_data_type['storage_can_view'] = 'storage' self.referenced_data_type['repository_can_view'] = 'repository' self.referenced_data_type['printer_can_view'] = 'printer' # Get gecos_ws_mgmt cookbook default data structure default_data_dotted_keys = {} default_data = self.get_default_data(default_data_dotted_keys) if default_data is None: logger.error("Can't find default data!") return # Get all the policies structures logger.info('Getting all the policies structures from database...') dbpolicies = self.db.policies.find() self.policiesdata = {} self.slug_check = {} for policy in dbpolicies: logger.debug('Adding to dictionary: %s => %s' % (policy['_id'], json.dumps(policy['schema']))) self.policiesdata[str(policy['_id'])] = policy # Check policy slug field (must be unique) if policy['slug'] in self.slug_check: logger.error("There are more than one policy with '%s' slug!" % (policy['slug'])) else: slug = policy['slug'] # The slug of the emitter policies is different from the others if slug == 'printer_can_view': slug = 'printers_res' elif slug == 'storage_can_view': slug = 'user_shared_folders_res' elif slug == 'repository_can_view': slug = 'software_sources_res' self.slug_check[slug] = policy # Check policy serialization try: logger.debug('Serialized policy: %s' % (json.dumps(Policy().serialize(policy)))) except Exception as err: logger.error( 'Policy %s with slug %s can\'t be serialized: %s' % (policy['_id'], policy['slug'], str(err))) logger.warn( 'Possible cause: New fields in models (Colander) but the import_policies command has not yet been executed to update schema.' ) if self.options.clean_inheritance: logger.info('Cleaning inheritance field...') self.db.nodes.update({"inheritance": { '$exists': True }}, {'$unset': { "inheritance": { '$exist': True } }}, multi=True) if self.options.clean_variables: logger.info('Cleaning variables data from Chef nodes') for node_id in ChefNode.list(): node = ChefNode(node_id, self.api) if node.normal.has_dotted('gecos_info'): del node.normal['gecos_info'] node.save() logger.info('Checking tree...') # Look for the root of the nodes tree root_nodes = self.db.nodes.find({"path": "root"}) for root in root_nodes: self.check_node_and_subnodes(root) logger.info( 'Checking nodes that are outside the tree (missing OUs in the PATH)...' ) # Check node path nodes = self.db.nodes.find({}) for node in nodes: if not 'path' in node: logger.error('Node with ID: %s has no "path" attribute!' % (str(node['_id']))) continue if not 'name' in node: logger.error('Node with ID: %s has no "name" attribute!' % (str(node['_id']))) continue if not 'type' in node: logger.error('Node with ID: %s has no "type" attribute!' % (str(node['_id']))) continue for ou_id in node['path'].split(','): if ou_id == 'root': continue ou = self.db.nodes.find_one({"_id": ObjectId(ou_id)}) if not ou: logger.error( 'Can\'t find OU %s that belongs to node path (node ID: %s NAME: %s)' % (str(ou_id), str(node['_id']), node['name'])) continue logger.info('Checking chef node references...') # Check the references to Chef nodes computers = self.db.nodes.find({"type": "computer"}) for computer in computers: if "node_chef_id" in computer: # Check Chef node computer_node = ChefNode(computer['node_chef_id'], self.api) logger.info("Computer: %s Chef ID: %s" % (computer['name'], computer['node_chef_id'])) if not computer_node.exists: logger.error("No Chef node with ID %s!" % (computer['node_chef_id'])) else: logger.error("No Chef ID in '%s' computer!" % (computer['name'])) logger.info( 'Checking MongoDB computer references and deprecated policies...') # Check the references to computer nodes for node_id in ChefNode.list(): found = False computers = self.db.nodes.find({"node_chef_id": node_id}) node_path = None for computer in computers: found = True node_path = computer['path'] computer_node = ChefNode(node_id, self.api) if not found: pclabel = "(No OHAI-GECOS data in the node)" try: pclabel = "(pclabel = %s)" % ( computer_node.attributes.get_dotted( 'ohai_gecos.pclabel')) except KeyError: pass logger.error("No computer node for Chef ID: '%s' %s!" % (node_id, pclabel)) logger.warn( "Possible cause: The node has been deleted in Gecos Control Center but not in Chef server, either because it was in use at that time or for another unknown reason." ) # Check default data for chef node if not computer_node.default.to_dict( ) or not computer_node.attributes.has_dotted('gecos_ws_mgmt'): logger.info( "FIXED: For an unknown reason Chef node: %s has no default attributes." % (node_id)) computer_node.default = default_data computer_node.save() # Check "updated_by" field attributes = computer_node.normal.to_dict() updated, updated_attributes = self.check_updated_by_field( node_id, None, attributes) if updated: computer_node.normal = updated_attributes computer_node.save() updated, updated_attributes = self.check_chef_node_policies( node_id, None, attributes) if updated: computer_node.normal = updated_attributes computer_node.save() if node_path is not None: # Check "gecos_path_ids" field if not computer_node.attributes.has_dotted( 'gecos_path_ids' ) or computer_node.attributes.get_dotted( 'gecos_path_ids') != node_path: logger.info( "FIXED: gecos_path_ids attribute in node: %s." % (node_id)) computer_node.attributes.set_dotted( 'gecos_path_ids', node_path) computer_node.save() # Check "gecos_path_names" field node_path_names = 'root' for elm in node_path.split(','): if elm == 'root': continue ou = self.db.nodes.find_one({'_id': ObjectId(elm)}) node_path_names += ',' + ou['name'] if not computer_node.attributes.has_dotted( 'gecos_path_names' ) or computer_node.attributes.get_dotted( 'gecos_path_names') != node_path_names: logger.info( "FIXED: gecos_path_names attribute in node: %s." % (node_id)) computer_node.attributes.set_dotted( 'gecos_path_names', node_path_names) computer_node.save() logger.info('END ;)')
def command(self): # 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 self.referenced_data_type = {} self.referenced_data_type['storage_can_view'] = 'storage' self.referenced_data_type['repository_can_view'] = 'repository' self.referenced_data_type['printer_can_view'] = 'printer' # Get gecos_ws_mgmt cookbook default data structure default_data_dotted_keys = {} default_data = self.get_default_data(default_data_dotted_keys) if default_data is None: logger.error("Can't find default data!") return # Get all the policies structures logger.info('Getting all the policies structures from database...') dbpolicies = self.db.policies.find() self.policiesdata = {} self.slug_check = {} for policy in dbpolicies: logger.debug('Addig to dictionary: %s => %s'%(policy['_id'], json.dumps(policy['schema']))) self.policiesdata[str(policy['_id'])] = policy # Check policy slug field (must be unique) if policy['slug'] in self.slug_check: logger.error("There are more than one policy with '%s' slug!"%(policy['slug'])) else: self.slug_check[policy['slug']] = policy # Check policy serialization try: logger.debug('Serialized policy: %s'%(json.dumps(Policy().serialize(policy)))) except Exception as err: logger.error('Policy %s with slug %s can\'t be serialized: %s'%(policy['_id'], policy['slug'], str(err))) logger.warn('Possible cause: New fields in models (Colander) but the import_policies command has not yet been executed to update schema.') if self.options.clean_inheritance: logger.info('Cleaning inheritance field...') self.db.nodes.update({"inheritance": { '$exists': True }}, { '$unset': { "inheritance": {'$exist': True } }}, multi=True) logger.info('Checking tree...') # Look for the root of the nodes tree root_nodes = self.db.nodes.find({"path" : "root"}) for root in root_nodes: self.check_node_and_subnodes(root) logger.info('Checking nodes that are outside the tree (missing OUs in the PATH)...') # Check node path nodes = self.db.nodes.find({}) for node in nodes: if not 'path' in node: logger.error('Node with ID: %s has no "path" attribute!'%(str(node['_id']))) continue if not 'name' in node: logger.error('Node with ID: %s has no "name" attribute!'%(str(node['_id']))) continue if not 'type' in node: logger.error('Node with ID: %s has no "type" attribute!'%(str(node['_id']))) continue for ou_id in node['path'].split(','): if ou_id == 'root': continue ou = self.db.nodes.find_one({ "_id" : ObjectId(ou_id) }) if not ou: logger.error('Can\'t find OU %s that belongs to node path (node ID: %s NAME: %s)'%(str(ou_id), str(node['_id']), node['name'])) continue logger.info('Checking chef node references...') # Check the references to Chef nodes computers = self.db.nodes.find({"type" : "computer"}) for computer in computers: if "node_chef_id" in computer: # Check Chef node computer_node = ChefNode(computer['node_chef_id'], self.api) logger.info("Computer: %s Chef ID: %s"%(computer['name'], computer['node_chef_id'])) if not computer_node.exists: logger.error("No Chef node with ID %s!"%(computer['node_chef_id'])) else: logger.error("No Chef ID in '%s' computer!"%(computer['name'])) logger.info('Checking MongoDB computer references...') # Check the references to computer nodes for node_id in ChefNode.list(): found = False computers = self.db.nodes.find({"node_chef_id" : node_id}) for computer in computers: found = True computer_node = ChefNode(node_id, self.api) if not found: pclabel = "(No OHAI-GECOS data in the node)" try: pclabel = "(pclabel = %s)"%( computer_node.attributes.get_dotted('ohai_gecos.pclabel') ) except KeyError: pass logger.error("No computer node for Chef ID: '%s' %s!"%(node_id, pclabel)) logger.warn("Possible cause: The node has been deleted in Gecos Control Center but not in Chef server, either because it was in use at that time or for another unknown reason.") # Check default data for chef node if not computer_node.default.to_dict() or not computer_node.attributes.has_dotted('gecos_ws_mgmt'): logger.info("FIXED: For an unknown reason Chef node: %s has no default attributes."%(node_id)) computer_node.default = default_data computer_node.save() # Check "updated_by" field atrributes = computer_node.normal.to_dict() updated, updated_attributes = self.check_updated_by_field(node_id, None, atrributes) if updated: computer_node.normal = atrributes computer_node.save() logger.info('END ;)')
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)