Пример #1
0
 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
Пример #2
0
 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)
Пример #3
0
    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)
Пример #4
0
    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)
Пример #5
0
    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
Пример #6
0
    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