def get_computers(self): ''' Get the computers from the command arguments. ''' db = self.pyramid.db filters = {'type': 'computer'} if self.options.domain: domain = db.nodes.find_one({'_id': ObjectId(self.options.domain)}) filters['path'] = get_filter_this_domain(domain) elif self.options.computer: filters['$or'] = [{'_id': ObjectId(c)} for c in self.options.computer] computers = db.nodes.find(filters) return computers
def get_computers(self): ''' Get the computers from the command arguments. ''' db = self.pyramid.db filters = {'type': 'computer'} if self.options.domain: domain = db.nodes.find_one({'_id': ObjectId(self.options.domain)}) filters['path'] = get_filter_this_domain(domain) elif self.options.computer: filters['$or'] = [{ '_id': ObjectId(c) } for c in self.options.computer] computers = db.nodes.find(filters) return computers, db.nodes.count_documents(filters)
def _fixDuplicateName(self, mongoObjects, mongoType, newObj, domain): """ Fix duplicate name append an _counter to the name """ contador = 0 m = re.match(ur'^(.+)(_\d+)$', newObj['name']) if m: nombreBase = m.group(1) else: nombreBase = newObj['name'] # Each object to import if mongoObjects is not None: for mongoObject in mongoObjects.values(): m = re.match(ur'({0})(_\d+)?'.format(nombreBase), mongoObject['name']) if m and m.group(2): nuevoContador = int(m.group(2)[1:]) + 1 if (nuevoContador > contador): contador = nuevoContador elif m and 1 > contador: contador = 1 # Each object already in database collection = self.collection.find( { 'name': { '$regex': u'{0}(_\d+)?'.format(nombreBase) }, 'type': mongoType, 'path': get_filter_this_domain(domain) }, {'name': 1}) for mongoObject in collection: m = re.match(ur'({0})(_\d+)?'.format(nombreBase), mongoObject['name']) if m and m.group(2): nuevoContador = int(m.group(2)[1:]) + 1 if (nuevoContador > contador): contador = nuevoContador elif m and 1 > contador: contador = 1 if contador > 0: newObj['name'] = u'{0}_{1}'.format(nombreBase, contador)
def _fixDuplicateName(self, mongoObjects, mongoType, newObj, domain): """ Fix duplicate name append an _counter to the name """ contador = 0 m = re.match(ur'^(.+)(_\d+)$', newObj['name']) if m: nombreBase = m.group(1) else: nombreBase = newObj['name'] # Each object to import if mongoObjects is not None: for mongoObject in mongoObjects.values(): m = re.match(ur'({0})(_\d+)?'.format(nombreBase), mongoObject['name']) if m and m.group(2): nuevoContador = int(m.group(2)[1:]) + 1 if (nuevoContador > contador): contador = nuevoContador elif m and 1 > contador: contador = 1 # Each object already in database collection = self.collection.find({ 'name': { '$regex': u'{0}(_\d+)?'.format(nombreBase) }, 'type': mongoType, 'path': get_filter_this_domain(domain)}, { 'name': 1 }) for mongoObject in collection: m = re.match(ur'({0})(_\d+)?'.format(nombreBase), mongoObject['name']) if m and m.group(2): nuevoContador = int(m.group(2)[1:]) + 1 if (nuevoContador > contador): contador = nuevoContador elif m and 1 > contador: contador = 1 if contador > 0: newObj['name'] = u'{0}_{1}'.format(nombreBase, contador)
def post(self): try: # Initialize report report = {'inserted': 0, 'updated': 0, 'total': 0, 'warnings': {}} objects_apply_policy = {'computer': [], 'user': []} db = self.request.db # Read GZIP data postedfile = self.request.POST['media'].file xmldata = GzipFile('', 'r', 9, StringIO(postedfile.read())).read() # Read XML data xmldoc = minidom.parseString(xmldata) # Get the root domain xmlDomain = xmldoc.getElementsByTagName('Domain')[0] is_ad_master = self.request.POST['master'] == 'True' domain = self._get_domain(self.importSchema[0], xmlDomain, is_ad_master, report) # Convert from AD objects to MongoDB objects mongoObjects = {} mongoObjectsPath = {} for objSchema in self.importSchema: objs = xmldoc.getElementsByTagName(objSchema['adName']) for adObj in objs: if not adObj.hasAttribute('ObjectGUID'): raise Exception('An Active Directory object must has "ObjectGUID" attrib.') mongoObject, is_saving = self._convertADObjectToMongoObject(domain, mongoObjects, objSchema, adObj, is_ad_master, report, objects_apply_policy) report['total'] += 1 if is_saving: mongoObjects[mongoObject['adDistinguishedName']] = mongoObject mongoObjectsPath[mongoObject['adDistinguishedName']] = mongoObject # Order mongoObjects by dependences if mongoObjects: mongoObjects[domain['adDistinguishedName']] = domain mongoObjectsPath[domain['adDistinguishedName']] = domain mongoObjects = self._orderByDependencesMongoObjects(mongoObjects, domain) # Save each MongoDB objects properRootDomainADDN = domain['adDistinguishedName'] for index, mongoObject in mongoObjects.items(): if index == properRootDomainADDN: continue # Get the proper path ("root,{0}._id,{1}._id,{2}._id...") listPath = re.findall(ur'([^, ]+=(?:(?:\\,)|[^,])+)', index) nodePath = ','.join(listPath[1:]) # Find parent mongoObjectParent = mongoObjectsPath[nodePath] mongoObjectParent = self.collection.find_one({'_id': mongoObjectParent['_id']}) path = '{0},{1}'.format(mongoObjectParent['path'], str(mongoObjectParent['_id'])) mongoObject['path'] = path # Save mongoObject self._saveMongoObject(mongoObject) # AD Fixes admin_user = self.request.user chef_server_api = get_chef_api(get_current_registry().settings, admin_user) if is_ad_master: for index, mongoObject in mongoObjects.items(): if mongoObject['type'] == 'group': if mongoObject['members'] != []: mongoObject['members'] = [] self._saveMongoObject(mongoObject) for index, mongoObject in mongoObjects.items(): updateMongoObject = False # MemberOf if mongoObject['type'] in ('user', 'computer'): if 'memberof' not in mongoObject or is_ad_master: mongoObject['memberof'] = [] if 'adPrimaryGroup' in mongoObject and mongoObject['adPrimaryGroup']: group = mongoObjects[mongoObject['adPrimaryGroup']] if is_visible_group(db, group['_id'], mongoObject): if not mongoObject['_id'] in group['members']: group['members'].append(mongoObject['_id']) self._saveMongoObject(group) if mongoObjects[mongoObject['adPrimaryGroup']]['_id'] not in mongoObject['memberof']: mongoObject['memberof'].append(mongoObjects[mongoObject['adPrimaryGroup']]['_id']) else: self._warningGroup(group, mongoObject, report) updateMongoObject = True del mongoObject['adPrimaryGroup'] if 'adMemberOf' in mongoObject and mongoObject['adMemberOf']: for group_id in mongoObject['adMemberOf']: group = mongoObjects[group_id] if is_visible_group(db, group['_id'], mongoObject): if not mongoObject['_id'] in group['members']: group['members'].append(mongoObject['_id']) self._saveMongoObject(group) if mongoObjects[group_id]['_id'] not in mongoObject['memberof']: mongoObject['memberof'].append(mongoObjects[group_id]['_id']) else: self._warningGroup(group, mongoObject, report) updateMongoObject = True del mongoObject['adMemberOf'] # Create Chef-Server Nodes if mongoObject['type'] == 'computer': chef_server_node = reserve_node_or_raise(mongoObject['name'], chef_server_api, 'gcc-ad-import-%s' % random.random(), attempts=3) ohai_gecos_in_runlist = self.RECIPE_NAME_OHAI_GECOS in chef_server_node.run_list gecos_ws_mgmt_in_runlist = self.RECIPE_NAME_GECOS_WS_MGMT in chef_server_node.run_list if not ohai_gecos_in_runlist and not gecos_ws_mgmt_in_runlist: chef_server_node.run_list.append(self.RECIPE_NAME_OHAI_GECOS) chef_server_node.run_list.append(self.RECIPE_NAME_GECOS_WS_MGMT) elif not ohai_gecos_in_runlist and gecos_ws_mgmt_in_runlist: chef_server_node.run_list.insert(chef_server_node.run_list.index(self.RECIPE_NAME_GECOS_WS_MGMT), self.RECIPE_NAME_OHAI_GECOS) elif ohai_gecos_in_runlist and not gecos_ws_mgmt_in_runlist: chef_server_node.run_list.insert(chef_server_node.run_list.index(self.RECIPE_NAME_OHAI_GECOS) + 1, self.RECIPE_NAME_GECOS_WS_MGMT) save_node_and_free(chef_server_node) chef_server_client = Client(mongoObject['name'], api=chef_server_api) if not chef_server_client.exists: chef_server_client.save() mongoObject['node_chef_id'] = mongoObject['name'] updateMongoObject = True # Save changes if updateMongoObject: self._saveMongoObject(mongoObject) # apply policies to new objects for node_type, node_names in objects_apply_policy.items(): nodes = self.collection.find({'name': {'$in': node_names}, 'path': get_filter_this_domain(domain), 'type': node_type}) for node in nodes: apply_policies_function = globals()['apply_policies_to_%s' % node['type']] apply_policies_function(self.collection, node, admin_user, api=chef_server_api) # Return result status = '{0} inserted, {1} updated of {2} objects imported successfully.'.format(report['inserted'], report['updated'], report['total']) response = {'status': status, 'ok': True} except Exception as e: logger.exception(e) response = {'status': u'{0}'.format(e), 'ok': False} warnings = report.get('warnings', []) if warnings: response['warnings'] = warnings return response
def post(self): try: # Initialize report report = {'inserted': 0, 'updated': 0, 'total': 0, 'warnings': {}} objects_apply_policy = {'computer': [], 'user': []} db = self.request.db # Read GZIP data postedfile = self.request.POST['media'].file xmldata = GzipFile('', 'r', 9, StringIO(postedfile.read())).read() # Read XML data xmldoc = minidom.parseString(xmldata) # Get the root domain xmlDomain = xmldoc.getElementsByTagName('Domain')[0] is_ad_master = self.request.POST['master'] == 'True' domain = self._get_domain(self.importSchema[0], xmlDomain, is_ad_master, report) # Convert from AD objects to MongoDB objects mongoObjects = {} mongoObjectsPath = {} for objSchema in self.importSchema: objs = xmldoc.getElementsByTagName(objSchema['adName']) for adObj in objs: if not adObj.hasAttribute('ObjectGUID'): raise Exception( 'An Active Directory object must has "ObjectGUID" attrib.' ) mongoObject, is_saving = self._convertADObjectToMongoObject( domain, mongoObjects, objSchema, adObj, is_ad_master, report, objects_apply_policy) report['total'] += 1 if is_saving: mongoObjects[ mongoObject['adDistinguishedName']] = mongoObject mongoObjectsPath[ mongoObject['adDistinguishedName']] = mongoObject # Order mongoObjects by dependences if mongoObjects: mongoObjects[domain['adDistinguishedName']] = domain mongoObjectsPath[domain['adDistinguishedName']] = domain mongoObjects = self._orderByDependencesMongoObjects( mongoObjects, domain) # Save each MongoDB objects properRootDomainADDN = domain['adDistinguishedName'] for index, mongoObject in mongoObjects.items(): if index == properRootDomainADDN: continue # Get the proper path ("root,{0}._id,{1}._id,{2}._id...") listPath = re.findall(ur'([^, ]+=(?:(?:\\,)|[^,])+)', index) nodePath = ','.join(listPath[1:]) # Find parent mongoObjectParent = mongoObjectsPath[nodePath] mongoObjectParent = self.collection.find_one( {'_id': mongoObjectParent['_id']}) path = '{0},{1}'.format(mongoObjectParent['path'], str(mongoObjectParent['_id'])) mongoObject['path'] = path # Save mongoObject self._saveMongoObject(mongoObject) # AD Fixes admin_user = self.request.user chef_server_api = get_chef_api(get_current_registry().settings, admin_user) if is_ad_master: for index, mongoObject in mongoObjects.items(): if mongoObject['type'] == 'group': if mongoObject['members'] != []: mongoObject['members'] = [] self._saveMongoObject(mongoObject) for index, mongoObject in mongoObjects.items(): updateMongoObject = False # MemberOf if mongoObject['type'] in ('user', 'computer'): if 'memberof' not in mongoObject or is_ad_master: mongoObject['memberof'] = [] if 'adPrimaryGroup' in mongoObject and mongoObject[ 'adPrimaryGroup']: group = mongoObjects[mongoObject['adPrimaryGroup']] if is_visible_group(db, group['_id'], mongoObject): if not mongoObject['_id'] in group['members']: group['members'].append(mongoObject['_id']) self._saveMongoObject(group) if mongoObjects[mongoObject['adPrimaryGroup']][ '_id'] not in mongoObject['memberof']: mongoObject['memberof'].append(mongoObjects[ mongoObject['adPrimaryGroup']]['_id']) else: self._warningGroup(group, mongoObject, report) updateMongoObject = True del mongoObject['adPrimaryGroup'] if 'adMemberOf' in mongoObject and mongoObject[ 'adMemberOf']: for group_id in mongoObject['adMemberOf']: group = mongoObjects[group_id] if is_visible_group(db, group['_id'], mongoObject): if not mongoObject['_id'] in group['members']: group['members'].append(mongoObject['_id']) self._saveMongoObject(group) if mongoObjects[group_id][ '_id'] not in mongoObject['memberof']: mongoObject['memberof'].append( mongoObjects[group_id]['_id']) else: self._warningGroup(group, mongoObject, report) updateMongoObject = True del mongoObject['adMemberOf'] # Create Chef-Server Nodes if mongoObject['type'] == 'computer': chef_server_node = reserve_node_or_raise( mongoObject['name'], chef_server_api, 'gcc-ad-import-%s' % random.random(), attempts=3) ohai_gecos_in_runlist = self.RECIPE_NAME_OHAI_GECOS in chef_server_node.run_list gecos_ws_mgmt_in_runlist = self.RECIPE_NAME_GECOS_WS_MGMT in chef_server_node.run_list if not ohai_gecos_in_runlist and not gecos_ws_mgmt_in_runlist: chef_server_node.run_list.append( self.RECIPE_NAME_OHAI_GECOS) chef_server_node.run_list.append( self.RECIPE_NAME_GECOS_WS_MGMT) elif not ohai_gecos_in_runlist and gecos_ws_mgmt_in_runlist: chef_server_node.run_list.insert( chef_server_node.run_list.index( self.RECIPE_NAME_GECOS_WS_MGMT), self.RECIPE_NAME_OHAI_GECOS) elif ohai_gecos_in_runlist and not gecos_ws_mgmt_in_runlist: chef_server_node.run_list.insert( chef_server_node.run_list.index( self.RECIPE_NAME_OHAI_GECOS) + 1, self.RECIPE_NAME_GECOS_WS_MGMT) save_node_and_free(chef_server_node) chef_server_client = Client(mongoObject['name'], api=chef_server_api) if not chef_server_client.exists: chef_server_client.save() mongoObject['node_chef_id'] = mongoObject['name'] updateMongoObject = True # Save changes if updateMongoObject: self._saveMongoObject(mongoObject) # apply policies to new objects for node_type, node_names in objects_apply_policy.items(): nodes = self.collection.find({ 'name': { '$in': node_names }, 'path': get_filter_this_domain(domain), 'type': node_type }) for node in nodes: apply_policies_function = globals()['apply_policies_to_%s' % node['type']] apply_policies_function(self.collection, node, admin_user, api=chef_server_api) # Return result status = '{0} inserted, {1} updated of {2} objects imported successfully.'.format( report['inserted'], report['updated'], report['total']) response = {'status': status, 'ok': True} except Exception as e: logger.exception(e) response = {'status': u'{0}'.format(e), 'ok': False} warnings = report.get('warnings', []) if warnings: response['warnings'] = warnings return response