Example #1
0
    def get(self):
        result = super(ComputerResource, self).get()
        node_collection = self.request.db.nodes
        
        if not result.get('node_chef_id', None):
            return result
        try:
            api = get_chef_api(self.request.registry.settings, self.request.user)
            computer_node = ChefNode(result['node_chef_id'], api)
            ohai = to_deep_dict(computer_node.attributes)
            nodeid = result.get('_id',None)
            usernames = [i['username'] for i in ohai.get('ohai_gecos', {}).get('users', [])]
            users = list(node_collection.find({
                "$and": [
                    { "$or": [{"name": {"$in": usernames}}] }, 
                    { "type":"user"},
                    { "computers": {"$elemMatch": {"$eq": ObjectId(nodeid)}}}
                 ]
            },{'_id':1,'name':1,'path':1}))
            # ObjectId to string for JSON serialize
            [d.update({'_id': str(d['_id'])}) for d in users]
            
            # Create a list of users that provides at least one user policy to this computer
            users_inheritance_pre = list(node_collection.find({
                "$and": [
                    { "$or": [{"name": {"$in": usernames}}] }, 
                    { "type":"user"},
                    { "computers": {"$elemMatch": {"$eq": ObjectId(nodeid)}}}
                 ]
            },{'_id':1,'name':1,'path':1, 'inheritance': 1}))
            [d.update({'_id': str(d['_id'])}) for d in users_inheritance_pre]

            users_inheritance = []
            for usr_inh in users_inheritance_pre:
                if 'inheritance' in usr_inh:
                    policies_list = get_inheritance_tree_policies_list(usr_inh['inheritance'], [])
                    if len(policies_list) > 0:
                        users_inheritance.append(usr_inh)
            
            
            cpu = ohai.get('cpu', {}).get('0', {})
            dmi = ohai.get('dmi', {})
            
            result.update({'ohai': ohai,
                           'users': users, # Users related with this computer
                           'users_inheritance': users_inheritance, # Users related with this computer that provides at least one user policy
                           'uptime': ohai.get('uptime', ''),
                           #'gcc_link': ohai.get('gcc_link',True),
                           'ipaddress': ohai.get('ipaddress', ''),
                           'cpu': '%s %s' % (cpu.get('vendor_id', ''), cpu.get('model_name', '')),
                           'product_name': dmi.get('system', {}).get('product_name', ''),
                           'manufacturer': dmi.get('system', {}).get('manufacturer', ''),
                           'ram': ohai.get('memory', {}).get('total', ''),
                           'lsb': ohai.get('lsb', {}),
                           'kernel': ohai.get('kernel', {}),
                           'filesystem': ohai.get('filesystem', {}),
                           })
        except (urllib2.URLError, ChefError, ChefServerError):
            pass
        return result
    def post(self):
        node_id = self.request.POST.get('node_id')
        if node_id is None:
            return {'ok': False, 'message': 'Missing node ID'}

        settings = get_current_registry().settings
        api = get_chef_api(settings, self.request.user)

        # create chef client
        chef_client = ChefClient(node_id, api)
        if chef_client.exists:
            return {'ok': False, 'message': 'This client already exists'}

        chef_client = ChefClient.create(node_id, api)
        
        # Prepare the API for this client
        chef_url = settings.get('chef.url')
        chef_version = settings.get('chef.version')
        chef_ssl_verify = settings.get('chef.ssl.verify')
        if chef_ssl_verify == 'False' or chef_ssl_verify == 'True':
            chef_ssl_verify = bool(chef_ssl_verify)
        api = ChefAPI(chef_url, chef_client.private_key.encode(), node_id, chef_version, ssl_verify = False)

 
        # create chef node
        chef_node = ChefNode(node_id, api)
        if chef_node.exists:
            return {'ok': False, 'message': 'This node already exists'}
        chef_node.save()

        return {'ok': True, 'message': 'Node and client have been added',
                'client_private_key': chef_client.private_key}
Example #3
0
 def object_moved(self, user, objnew, objold):
     api = get_chef_api(self.app.conf, user)
     try:
         func = globals()['apply_policies_to_%s' % objnew['type']]
     except KeyError:
         raise NotImplementedError
     func(self.db.nodes, objnew, user, api, initialize=True)
Example #4
0
    def post(self):
        ou_id = self.request.POST.get('ou_id')
        node_id = self.request.POST.get('node_id')
        ou = None
        if ou_id:
            ou = self.collection.find_one({'_id': ObjectId(ou_id), 'type': 'ou'})
        else:
            ou_availables = self.request.user.get('ou_availables')
            if isinstance(ou_availables, list) and len(ou_availables) > 0:
                ou = self.collection.find_one({'_id': {'$in': [ObjectId(ou_ava_id) for ou_ava_id in ou_availables]},
                                               'type': 'ou',
                                               'path': {'$ne': 'root'}})
        if not ou:
            return {'ok': False,
                    'message': 'Ou does not exists'}

        settings = get_current_registry().settings
        api = get_chef_api(settings, self.request.user)
        computer_id = register_node(api, node_id, ou, self.collection)
        if not computer_id:
            return {'ok': False,
                    'message': 'Node does not exist (in chef)'}
        elif computer_id == 'duplicated':
            return {'ok': False,
                    'message': 'There is another node with this name (in gcc)'}
        elif computer_id == 'duplicated-node-id':
            return {'ok': False,
                    'message': 'There is another node with this node chef id (in gcc)'}

        computer = self.collection.find_one({'_id': computer_id})
        apply_policies_to_computer(self.collection, computer, self.request.user)
        update_tree(computer['path'])
        return {'ok': True}
Example #5
0
    def put(self):
        """
        Reserve the Chef node before running the Chef client
        """
                
        # Check the parameters
        node_id = self.request.POST.get('node_id')
        username = self.request.POST.get('gcc_username')
        if not node_id:
            return {'ok': False,
                    'message': 'Please set a node id (node_id)'}
        if not username:
            return {'ok': False,
                    'message': 'Please set a admin username (gcc_username)'}
        self.request.user = self.request.db.adminusers.find_one({'username': username})
        if not self.request.user:
            return {'ok': False,
                    'message': 'The admin user %s does not exists' % username}
        
        logger.info("/chef-client/run/: Reserve chef node %s" % (str(node_id)))

        # Saving last agent run time 
        self.request.db.nodes.update({'node_chef_id': node_id},{'$set': {'last_agent_run_time': int(time.time())}})
        
        # Reserve the node
        settings = get_current_registry().settings
        api = get_chef_api(settings, self.request.user)
        node, is_busy = is_node_busy_and_reserve_it(node_id, api, 'client', attempts=3)
        if not node.attributes.to_dict():
            return {'ok': False,
                    'message': 'The node does not exists (in chef)'}
        if is_busy:
            return {'ok': False,
                    'message': 'The node is busy'}
        return {'ok': True}
Example #6
0
    def __call__(self, node, value):

        from iscompatible import iscompatible, string_to_tuple
        super(UpdateControlFileValidator, self).__call__(node,value)

        request = pyramid.threadlocal.get_current_request()
        controlfile = self.decompress + os.sep + 'control'

        settings = get_current_registry().settings
        api = get_chef_api(settings, request.user)
        cookbook = get_cookbook(api, settings.get('chef.cookbook_name'))

        if os.path.exists(controlfile):
            gecoscc_require = cookbook_require = None
            with open(controlfile,'r') as f:
                for line in f:
                    if line.startswith('gecoscc'):
                        gecoscc_require = line
                    elif line.startswith('cookbook'):
                        cookbook_require = line
                      
            if gecoscc_require and not iscompatible(gecoscc_require, string_to_tuple(request.VERSION)):
                node.raise_invalid(gettext(self.err_msg))
  
            if cookbook_require and not iscompatible(cookbook_require, string_to_tuple(cookbook['version'])):
                node.raise_invalid(gettext(self.err_msg))
    def post(self):
        node_id = self.request.POST.get('node_id')
        if node_id is None:
            return {'ok': False, 'message': 'Missing node ID'}

        settings = get_current_registry().settings
        api = get_chef_api(settings, self.request.user)

        # create chef client
        chef_client = ChefClient(node_id, api)
        if chef_client.exists:
            return {'ok': False, 'message': 'This client already exists'}

        chef_client = ChefClient.create(node_id, api)
        
        # Prepare the API for this client
        chef_url = settings.get('chef.url')
        chef_version = settings.get('chef.version')
        chef_ssl_verify = settings.get('chef.ssl.verify')
        if chef_ssl_verify == 'False' or chef_ssl_verify == 'True':
            chef_ssl_verify = bool(chef_ssl_verify)
        api = ChefAPI(chef_url, str(chef_client.private_key), node_id, chef_version, ssl_verify = False)

 
        # create chef node
        chef_node = ChefNode(node_id, api)
        if chef_node.exists:
            return {'ok': False, 'message': 'This node already exists'}
        chef_node.save()

        return {'ok': True, 'message': 'Node and client have been added',
                'client_private_key': chef_client.private_key}
Example #8
0
 def get(self):
     result = super(ComputerResource, self).get()
     if not result.get('node_chef_id', None):
         return result
     try:
         api = get_chef_api(self.request.registry.settings, self.request.user)
         computer_node = ChefNode(result['node_chef_id'], api)
         ohai = to_deep_dict(computer_node.attributes)
         cpu = ohai.get('cpu', {}).get('0', {})
         dmi = ohai.get('dmi', {})
         result.update({'ohai': ohai,
                        'users': ','.join([i['username'] for i in ohai.get('ohai_gecos', {}).get('users', [])]),
                        'uptime': ohai.get('uptime', ''),
                        'ipaddress': ohai.get('ipaddress', ''),
                        'cpu': '%s %s' % (cpu.get('vendor_id', ''), cpu.get('model_name', '')),
                        'product_name': dmi.get('system', {}).get('product_name', ''),
                        'manufacturer': dmi.get('system', {}).get('manufacturer', ''),
                        'ram': ohai.get('memory', {}).get('total', ''),
                        'lsb': ohai.get('lsb', {}),
                        'kernel': ohai.get('kernel', {}),
                        'filesystem': ohai.get('filesystem', {}),
                        })
     except (urllib2.URLError, ChefError, ChefServerError):
         pass
     return result
Example #9
0
 def object_moved(self, user, objnew, objold):
     api = get_chef_api(self.app.conf, user)
     try:
         func = globals()['apply_policies_to_%s' % objnew['type']]
     except KeyError:
         raise NotImplementedError
     func(self.db.nodes, objnew, user, api, initialize=True)
Example #10
0
    def __call__(self, node, value):

        from iscompatible import iscompatible, string_to_tuple
        super(UpdateControlFileValidator, self).__call__(node,value)

        request = pyramid.threadlocal.get_current_request()
        controlfile = self.decompress + os.sep + 'control'

        settings = get_current_registry().settings
        api = get_chef_api(settings, request.user)
        cookbook = get_cookbook(api, settings.get('chef.cookbook_name'))

        if os.path.exists(controlfile):
            gecoscc_require = cookbook_require = None
            with open(controlfile,'r') as f:
                for line in f:
                    if line.startswith('gecoscc'):
                        gecoscc_require = line
                    elif line.startswith('cookbook'):
                        cookbook_require = line
                      
            if gecoscc_require and not iscompatible(gecoscc_require, string_to_tuple(request.VERSION)):
                node.raise_invalid(gettext(self.err_msg))
  
            if cookbook_require and not iscompatible(cookbook_require, string_to_tuple(cookbook['version'])):
                node.raise_invalid(gettext(self.err_msg))
Example #11
0
 def computer_deleted(self, user, obj, computers=None):
     node_chef_id = obj.get('node_chef_id', None)
     if node_chef_id:
         api = get_chef_api(self.app.conf, user)
         node = Node(node_chef_id, api)
         node.delete()
         client = Client(node_chef_id, api=api)
         client.delete()
     self.log_action('deleted', 'Computer', obj)
Example #12
0
 def computer_deleted(self, user, obj, computers=None):
     node_chef_id = obj.get('node_chef_id', None)
     if node_chef_id:
         api = get_chef_api(self.app.conf, user)
         node = Node(node_chef_id, api)
         node.delete()
         client = Client(node_chef_id, api=api)
         client.delete()
     self.log_action('deleted', 'Computer', obj)
    def command(self):
        '''
        This command recalculate the policies of the selected nodes
        These nodes are receiving as command arguments
        '''
        db = self.pyramid.db
        computers = self.get_computers()
        admin_user = db.adminusers.find_one({'username': self.options.administrator})
        if not admin_user:
            sys.stdout.write('Administrator does not exists\n')
            sys.exit(1)
        elif not admin_user.get('is_superuser', None):
            sys.stdout.write('Administrator should be super user\n')
            sys.exit(1)
        api = get_chef_api(self.settings, admin_user)
        cookbook_name = self.settings['chef.cookbook_name']
        num_computers = computers.count()
        # It is not really the max dots, because the integer division.
        max_optimal_dots = 80
        total_dots = min(num_computers, max_optimal_dots)

        if total_dots == num_computers:
            step = 1
        else:
            step = num_computers / total_dots
            total_dots = int(math.ceil(float(num_computers) / step))

        sys.stdout.write('%s 100%%\n' % ('.' * total_dots))
        sys.stdout.flush()
        results_error = {}
        results_succes = {}
        for i, comp in enumerate(computers):
            if i % step == 0:
                sys.stdout.write('.')
                sys.stdout.flush()
            recalculated, reason = recalc_node_policies(db.nodes, db.jobs,
                                                        comp, admin_user,
                                                        cookbook_name, api)
            if recalculated:
                results_succes[comp['name']] = reason
            else:
                results_error[comp['name']] = reason

        sys.stdout.write('\n\n\n*********** Success ********** \n')

        for name, reason in results_succes.items():
            sys.stdout.write('%s: %s \n' % (name, reason))

        sys.stdout.write('\n\n\n*********** Errors ********** \n')

        for name, reason in results_error.items():
            sys.stdout.write('%s: %s \n' % (name, reason))

        sys.stdout.flush()
    def post(self):
        ou_id = self.request.POST.get('ou_id')
        node_id = self.request.POST.get('node_id')
        ou = None
        if ou_id:
            ou = self.collection.find_one({
                '_id': ObjectId(ou_id),
                'type': 'ou'
            })
        else:
            ou_availables = self.request.user.get('ou_availables')
            if isinstance(ou_availables, list) and len(ou_availables) > 0:
                ou = self.collection.find_one({
                    '_id': {
                        '$in':
                        [ObjectId(ou_ava_id) for ou_ava_id in ou_availables]
                    },
                    'type': 'ou',
                    'path': {
                        '$ne': 'root'
                    }
                })
        if not ou:
            return {'ok': False, 'message': 'Ou does not exists'}

        settings = get_current_registry().settings
        api = get_chef_api(settings, self.request.user)
        computer_id = register_node(api, node_id, ou, self.collection)
        if not computer_id:
            return {'ok': False, 'message': 'Node does not exist (in chef)'}
        elif computer_id == 'duplicated':
            return {
                'ok': False,
                'message': 'There is another node with this name (in gcc)'
            }
        elif computer_id == 'duplicated-node-id':
            return {
                'ok': False,
                'message':
                'There is another node with this node chef id (in gcc)'
            }
        elif computer_id == 'path-err':
            return {
                'ok': False,
                'message':
                'Unable to add gecos path ids and names to chef node'
            }

        computer = self.collection.find_one({'_id': computer_id})
        apply_policies_to_computer(self.collection, computer,
                                   self.request.user)
        update_tree(computer['path'])
        return {'ok': True}
Example #15
0
def _check_if_user_belongs_to_admin_group(request, organization, username):
    chefusername = toChefUsername(username)
    settings = get_current_registry().settings
    api = get_chef_api(settings, request.user)

    admins_group = api['/organizations/%s/groups/admins' % (organization)]
    if not chefusername in admins_group:
        # Check if exists an association request for this user
        assoc_requests = None
        try:
            assoc_requests = api['/organizations/%s/association_requests' %
                                 (organization)]
        except ChefServerNotFoundError:
            pass

        association_id = None
        for req in assoc_requests:
            if req["username"] == chefusername:
                association_id = req["id"]

        if association_id is None:
            # Set an association request for the user in that organization
            try:
                data = {"user": chefusername}
                response = api.api_request(
                    'POST',
                    '/organizations/%s/association_requests' % (organization),
                    data=data)
                association_id = response["uri"].split("/")[-1]
            except ChefServerError:
                # Association already exists?
                pass

        if association_id is not None:
            # Accept the association request
            logger.info('Adding %s user to default organization' % (username))
            api.api_request('PUT',
                            '/users/%s/association_requests/%s' %
                            (chefusername, association_id),
                            data={"response": 'accept'})

        # Add the user to the group
        logger.info('Adding %s user to admins group' % (username))
        admins_group['users'].append(chefusername)
        api.api_request('PUT',
                        '/organizations/%s/groups/admins' % (organization),
                        data={
                            "groupname": admins_group["groupname"],
                            "actors": {
                                "users": admins_group['users'],
                                "groups": admins_group["groups"]
                            }
                        })
    def get(self):
        node_id = self.request.GET.get('node_id')
        if node_id is None:
            return {'ok': False, 'message': 'Missing node ID'}
        
        settings = get_current_registry().settings
        api = get_chef_api(settings, self.request.user)

        chef_node = ChefNode(node_id, api)
        if not chef_node.exists:
            return {'ok': False, 'message': 'This node does not exists'}
        else:
            return {'ok': True, 'message': 'This node does exists'}
    def get(self):
        node_id = self.request.GET.get('node_id')
        if node_id is None:
            return {'ok': False, 'message': 'Missing node ID'}
        
        settings = get_current_registry().settings
        api = get_chef_api(settings, self.request.user)

        chef_node = ChefNode(node_id, api)
        if not chef_node.exists:
            return {'ok': False, 'message': 'This node does not exists'}
        else:
            return {'ok': True, 'message': 'This node does exists'}
Example #18
0
def admin_delete(context, request):
    if request.method != 'DELETE':
        raise HTTPMethodNotAllowed("Only delete method is accepted")
    username = request.GET.get('username')
    if request.session['auth.userid'] == username:
        forget(request)
    settings = get_current_registry().settings
    api = get_chef_api(settings, request.user)
    success_remove_chef = delete_chef_admin_user(api, username)
    if not success_remove_chef:
        messages.created_msg(request, _('User deleted unsuccessfully from chef'), 'danger')
    request.userdb.delete_users({'username': username})
    messages.created_msg(request, _('User deleted successfully'), 'success')
    return {'ok': 'ok'}
Example #19
0
    def put(self):
        node_id = self.request.POST.get('node_id')
        username = self.request.POST.get('gcc_username')
        if not node_id:
            return {'ok': False,
                    'message': 'Please set a node id (node_id)'}
        if not username:
            return {'ok': False,
                    'message': 'Please set a admin username (gcc_username)'}
        self.request.user = self.request.db.adminusers.find_one({'username': username})
        if not self.request.user:
            return {'ok': False,
                    'message': 'The admin user %s does not exists' % username}
        settings = get_current_registry().settings
        api = get_chef_api(settings, self.request.user)
        node = Node(node_id, api)
        job_status = node.attributes.get('job_status')
        reserve_node = False
        if job_status:
            node = reserve_node_or_raise(node_id, api, 'gcc-chef-status-%s' % random.random(), attempts=3)
            reserve_node = True
            chef_client_error = False

            for job_id, job_status in job_status.to_dict().items():
                job = self.collection.find_one({'_id': ObjectId(job_id)})
                if not job:
                    continue
                if job_status['status'] == 0:
                    self.collection.update({'_id': job['_id']},
                                           {'$set': {'status': 'finished',
                                                     'last_update': datetime.datetime.utcnow()}})
                else:
                    chef_client_error = True
                    self.collection.update({'_id': job['_id']},
                                           {'$set': {'status': 'errors',
                                                     'message': job_status.get('message', 'Error'),
                                                     'last_update': datetime.datetime.utcnow()}})
            self.request.db.nodes.update({'node_chef_id': node_id}, {'$set': {'error_last_chef_client': chef_client_error}})
            invalidate_jobs(self.request)
            node.attributes.set_dotted('job_status', {})

        users_old = self.get_attr(node, USERS_OLD)
        users = self.get_attr(node, USERS_OHAI)
        if not users_old or users_old != users:
            if not reserve_node:
                node = reserve_node_or_raise(node_id, api, 'gcc-chef-status-%s' % random.random(), attempts=3)
            return self.check_users(node)
        if job_status:
            save_node_and_free(node)
        return {'ok': True}
Example #20
0
 def save(self, admin_user):
     self.collection.insert(admin_user)
     admin_user['plain_password'] = self.cstruct['password']
     settings = get_current_registry().settings
     user = self.request.user
     api = get_chef_api(settings, user)
     try:
         create_chef_admin_user(api, settings, admin_user['username'])
         self.created_msg(_('User created successfully'))
         return True
     except ChefServerError as e:
         self.created_msg(e.message, 'danger')
         self.collection.remove({'username': admin_user['username']})
         raise e
Example #21
0
 def save(self, admin_user):
     self.collection.insert(admin_user)
     admin_user['plain_password'] = self.cstruct['password']
     settings = get_current_registry().settings
     user = self.request.user
     api = get_chef_api(settings, user)
     try:
         create_chef_admin_user(api, settings, admin_user['username'])
         self.created_msg(_('User created successfully'))
         return True
     except ChefServerError as e:
         self.created_msg(e.message, 'danger')
         self.collection.remove({'username': admin_user['username']})
         raise e
Example #22
0
 def object_action(self, user, obj, objold=None, action=None, computers=None):
     api = get_chef_api(self.app.conf, user)
     cookbook = get_cookbook(api, self.app.conf.get('chef.cookbook_name'))
     computers = computers or self.get_related_computers(obj)
     are_new_jobs = False
     for computer in computers:
         try:
             job_ids_by_computer = []
             node_chef_id = computer.get('node_chef_id', None)
             node = reserve_node_or_raise(node_chef_id, api, 'gcc-tasks-%s-%s' % (obj['_id'], random.random()), 10)
             if not node.get(self.app.conf.get('chef.cookbook_name')):
                 raise NodeNotLinked("Node %s is not linked" % node_chef_id)
             error_last_saved = computer.get('error_last_saved', False)
             error_last_chef_client = computer.get('error_last_chef_client', False)
             force_update = error_last_saved or error_last_chef_client
             node, updated = self.update_node(user, computer, obj, objold, node, action, job_ids_by_computer, force_update)
             if not updated:
                 save_node_and_free(node)
                 continue
             are_new_jobs = True
             self.validate_data(node, cookbook, api)
             save_node_and_free(node)
             if error_last_saved:
                 self.db.nodes.update({'_id': computer['_id']},
                                      {'$set': {'error_last_saved': False}})
         except NodeNotLinked as e:
             self.report_node_not_linked(computer, user, obj, action)
             are_new_jobs = True
             save_node_and_free(node, api, refresh=True)
         except NodeBusyException as e:
             self.report_node_busy(computer, user, obj, action)
             are_new_jobs = True
         except ValidationError as e:
             if not job_ids_by_computer:
                 self.report_unknown_error(e, user, obj, action, computer)
             self.report_error(e, job_ids_by_computer, computer, 'Validation error: ')
             save_node_and_free(node, api, refresh=True)
             are_new_jobs = True
         except Exception as e:
             if not job_ids_by_computer:
                 self.report_unknown_error(e, user, obj, action, computer)
             self.report_error(e, job_ids_by_computer, computer)
             try:
                 save_node_and_free(node, api, refresh=True)
             except:
                 pass
             are_new_jobs = True
     if are_new_jobs:
         invalidate_jobs(self.request, user)
Example #23
0
def admin_delete(context, request):
    if request.method != 'DELETE':
        raise HTTPMethodNotAllowed("Only delete method is accepted")
    username = request.GET.get('username')
    if request.session['auth.userid'] == username:
        forget(request)
    settings = get_current_registry().settings
    api = get_chef_api(settings, request.user)
    success_remove_chef = delete_chef_admin_user(api, username)
    if not success_remove_chef:
        messages.created_msg(request,
                             _('User deleted unsuccessfully from chef'),
                             'danger')
    request.userdb.delete_user({'username': username})
    messages.created_msg(request, _('User deleted successfully'), 'success')
    return {'ok': 'ok'}
Example #24
0
    def put(self):
        """
        Reserve the Chef node before running the Chef client
        """

        # Check the parameters
        node_id = self.request.POST.get('node_id')
        username = self.request.POST.get('gcc_username')
        if not node_id:
            return {'ok': False, 'message': 'Please set a node id (node_id)'}
        if not username:
            return {
                'ok': False,
                'message': 'Please set a admin username (gcc_username)'
            }
        self.request.user = self.request.db.adminusers.find_one(
            {'username': username})
        if not self.request.user:
            return {
                'ok': False,
                'message': 'The admin user %s does not exists' % username
            }

        logger.info("/chef-client/run/: Reserve chef node %s" % (str(node_id)))

        # Saving last agent run time
        self.request.db.nodes.update(
            {'node_chef_id': node_id},
            {'$set': {
                'last_agent_run_time': int(time.time())
            }})

        # Reserve the node
        settings = get_current_registry().settings
        api = get_chef_api(settings, self.request.user)
        node, is_busy = is_node_busy_and_reserve_it(node_id,
                                                    api,
                                                    'client',
                                                    attempts=3)
        if not node.attributes.to_dict():
            return {
                'ok': False,
                'message': 'The node does not exists (in chef)'
            }
        if is_busy:
            return {'ok': False, 'message': 'The node is busy'}
        return {'ok': True}
Example #25
0
 def check_computers(self, ou, admin, policy):
     db = self.pyramid.db
     ou_path = '%s,%s' % (ou['path'], unicode(ou['_id']))
     computers = db.nodes.find({'path': ou_path, 'type': 'computer'})
     api = get_chef_api(self.settings, admin)
     computers_error = {}
     policy_attr_to_check = self.get_policy_attr_to_check(policy)
     for computer in computers:
         node_id = computer.get('node_chef_id', None)
         if not node_id:
             computers_error[computer['name']] = 'does not node_chef_id'
         node = ChefNode(node_id, api)
         if self.check_node(policy_attr_to_check, node):
             print '%s ok' % computer['name']
         else:
             computers_error[computer['name']] = self.error
     return computers_error
    def put(self):
        # implements "knife client reregister"
        node_id = self.request.POST.get('node_id')
        if node_id is None:
            return {'ok': False, 'message': 'Missing node ID'}
            
        settings = get_current_registry().settings
        api = get_chef_api(settings, self.request.user)

        # remove current node's client
        chef_client = ChefClient(node_id, api)
        if not chef_client.exists:
            return {'ok': False, 'message': 'This client does not exists'}

        chef_client.rekey(api)

        return {'ok': True, 'message': "Chef node's client has been update",
                'client_private_key': chef_client.private_key}
    def put(self):
        # implements "knife client reregister"
        node_id = self.request.POST.get('node_id')
        if node_id is None:
            return {'ok': False, 'message': 'Missing node ID'}
            
        settings = get_current_registry().settings
        api = get_chef_api(settings, self.request.user)

        # remove current node's client
        chef_client = ChefClient(node_id, api)
        if not chef_client.exists:
            return {'ok': False, 'message': 'This client does not exists'}

        chef_client.rekey(api)

        return {'ok': True, 'message': "Chef node's client has been update",
                'client_private_key': chef_client.private_key}
Example #28
0
def _check_if_user_belongs_to_admin_group(request, organization, username):
    chefusername = toChefUsername(username)
    settings = get_current_registry().settings
    api = get_chef_api(settings, request.user)
    
    admins_group = api['/organizations/%s/groups/admins'%(organization)]
    if not chefusername in admins_group:
        # Check if exists an association request for this user
        assoc_requests = None
        try:
            assoc_requests = api['/organizations/%s/association_requests'%(organization)]
        except ChefServerNotFoundError:
            pass                    
        
        association_id = None
        for req in assoc_requests:
            if req["username"] == chefusername:
                association_id = req["id"]
        
        if association_id is None:
            # Set an association request for the user in that organization
            try:
                data = {"user": chefusername}
                response = api.api_request('POST', '/organizations/%s/association_requests'%(organization), data=data) 
                association_id = response["uri"].split("/")[-1]
            except ChefServerError:
                # Association already exists?
                pass                    

        if association_id is not None:
            # Accept the association request
            logger.info('Adding %s user to default organization'%(username))
            api.api_request('PUT', '/users/%s/association_requests/%s'%(chefusername, association_id),  data={ "response": 'accept' }) 

        # Add the user to the group
        logger.info('Adding %s user to admins group'%(username))
        admins_group['users'].append(chefusername)
        api.api_request('PUT', '/organizations/%s/groups/admins'%(organization), data={ "groupname": admins_group["groupname"], 
            "actors": {
                "users": admins_group['users'],
                "groups": admins_group["groups"]
            }
            })         
Example #29
0
 def check_computers(self, ou, admin, policy):
     db = self.pyramid.db
     ou_path = '%s,%s' % (ou['path'], unicode(ou['_id']))
     computers = db.nodes.find({'path': ou_path,
                                'type': 'computer'})
     api = get_chef_api(self.settings,
                        admin)
     computers_error = {}
     policy_attr_to_check = self.get_policy_attr_to_check(policy)
     for computer in computers:
         node_id = computer.get('node_chef_id', None)
         if not node_id:
             computers_error[computer['name']] = 'does not node_chef_id'
         node = ChefNode(node_id, api)
         if self.check_node(policy_attr_to_check, node):
             print '%s ok' % computer['name']
         else:
             computers_error[computer['name']] = self.error
     return computers_error
    def delete(self):
        node_id = self.request.GET.get('node_id')
        if node_id is None:
            return {'ok': False, 'message': 'Missing node ID'}
        
        settings = get_current_registry().settings
        api = get_chef_api(settings, self.request.user)

        chef_node = ChefNode(node_id, api)
        if not chef_node.exists:
            return {'ok': False, 'message': 'This node does not exists'}
        chef_node.delete()

        chef_client = ChefClient(node_id, api)
        if not chef_client.exists:
            return {'ok': False, 'message': 'This client does not exists'}
        chef_client.delete()

        return {'ok': True, 'message': 'Node and client have been deleted'}
    def delete(self):
        node_id = self.request.GET.get('node_id')
        if node_id is None:
            return {'ok': False, 'message': 'Missing node ID'}
        
        settings = get_current_registry().settings
        api = get_chef_api(settings, self.request.user)

        chef_node = ChefNode(node_id, api)
        if not chef_node.exists:
            return {'ok': False, 'message': 'This node does not exists'}
        chef_node.delete()

        chef_client = ChefClient(node_id, api)
        if not chef_client.exists:
            return {'ok': False, 'message': 'This client does not exists'}
        chef_client.delete()

        return {'ok': True, 'message': 'Node and client have been deleted'}
Example #32
0
 def get(self):
     result = super(ComputerResource, self).get()
     if not result.get('node_chef_id', None):
         return result
     try:
         api = get_chef_api(self.request.registry.settings,
                            self.request.user)
         computer_node = ChefNode(result['node_chef_id'], api)
         ohai = to_deep_dict(computer_node.attributes)
         cpu = ohai.get('cpu', {}).get('0', {})
         dmi = ohai.get('dmi', {})
         result.update({
             'ohai':
             ohai,
             'users':
             ','.join([
                 i['username']
                 for i in ohai.get('ohai_gecos', {}).get('users', [])
             ]),
             'uptime':
             ohai.get('uptime', ''),
             'ipaddress':
             ohai.get('ipaddress', ''),
             'cpu':
             '%s %s' %
             (cpu.get('vendor_id', ''), cpu.get('model_name', '')),
             'product_name':
             dmi.get('system', {}).get('product_name', ''),
             'manufacturer':
             dmi.get('system', {}).get('manufacturer', ''),
             'ram':
             ohai.get('memory', {}).get('total', ''),
             'lsb':
             ohai.get('lsb', {}),
             'kernel':
             ohai.get('kernel', {}),
             'filesystem':
             ohai.get('filesystem', {}),
         })
     except (urllib2.URLError, ChefError, ChefServerError):
         pass
     return result
Example #33
0
 def check_users(self, ou, admin, policy):
     db = self.pyramid.db
     ou_path = '%s,%s' % (ou['path'], text_type(ou['_id']))
     users = db.nodes.find({'path': ou_path, 'type': 'user'})
     computers_error = {}
     api = get_chef_api(self.settings, admin)
     for user in users:
         computers_ids = user.get('computers', [])
         computers = db.nodes.find({'_id': {'$in': computers_ids}})
         policy_attr_to_check = self.get_policy_attr_to_check(policy, user)
         for computer in computers:
             node_id = computer.get('node_chef_id', None)
             if not node_id:
                 computers_error[computer['name']] = 'does not node_chef_id'
             node = ChefNode(node_id, api)
             if self.check_node(policy_attr_to_check, node):
                 print('%s ok' % computer['name'])
             else:
                 computers_error[
                     computer['name']] = self.error % (user['name'])
     return computers_error
Example #34
0
 def put(self):
     node_id = self.request.POST.get('node_id')
     username = self.request.POST.get('gcc_username')
     if not node_id:
         return {'ok': False,
                 'message': 'Please set a node id (node_id)'}
     if not username:
         return {'ok': False,
                 'message': 'Please set a admin username (gcc_username)'}
     self.request.user = self.request.db.adminusers.find_one({'username': username})
     if not self.request.user:
         return {'ok': False,
                 'message': 'The admin user %s does not exists' % username}
     settings = get_current_registry().settings
     api = get_chef_api(settings, self.request.user)
     node, is_busy = is_node_busy_and_reserve_it(node_id, api, 'client', attempts=3)
     if not node.attributes.to_dict():
         return {'ok': False,
                 'message': 'The node does not exists (in chef)'}
     if is_busy:
         return {'ok': False,
                 'message': 'The node is busy'}
     return {'ok': True}
Example #35
0
def server_status(context, request):
    # Delete a non existent server?
    server_name = request.GET.get('delete', None)
    if server_name:
        request.db.servers.delete_one({"name": server_name})
    
    
    # Calculate server status list
    server_list = request.db.servers.find().sort('name')
    server_status = []
    
    # Get status of each server
    for server in server_list:
        status = getServerStatus(server['address'])
        if status is None:
            status = {}
            status['cpu'] = {}
            status['cpu']['load'] = 0
            status['cpu']['name'] = 'UNKNOWN'
            status['cpu']['ncores'] = 0
            
            status['ram'] = {}
            status['ram']['total'] = 0
            status['ram']['used'] = 0
            
            status['disk'] = {}
            status['disk']['mountpoints'] = []
            status['disk']['total'] = 0
            status['disk']['used'] = 0
            
        else:
            for mpt in status['disk']['mountpoints']:
                factor = 1
                factor_text = 'byte'
                
                if int(mpt['size']) > 1024:
                    factor = 1024
                    factor_text = 'Kbyte'
                    
                if int(mpt['size']) > (1024*1024):
                    factor = (1024*1024)
                    factor_text = 'Mbyte'

                if int(mpt['size']) > (1024*1024*1024):
                    factor = (1024*1024*1024)
                    factor_text = 'Gbyte'
                    
                if int(mpt['size']) > (1024*1024*1024*1024):
                    factor = (1024*1024*1024*1024)
                    factor_text = 'Tbyte'
                    
                mpt['factor'] = factor
                mpt['factor_text'] = factor_text
            
        status['name'] = server['name']
        status['address'] = server['address']
        # Check if the address is actually an IP address
        if not re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", 
                        status['address']):
            try:
                # Try to resolve the IP address
                status['address'] = socket.gethostbyname(status['address'])
            except Exception as e:
                logger.warning("server_status: Couldn't resolve IP address from hostname: %s: %s"%(status['address'], str(e)))
                status['address'] = 'X.X.X.X'            
            
        server_status.append(status)


    # Get cookbook info
    settings = get_current_registry().settings
    api = get_chef_api(settings, request.user)
    organization = 'default'

    cookbook_info = []
    try:
        cookbook_info = api['/organizations/%s/cookbooks'%(organization)]

    except Exception as e:
        logger.error("server_status: error getting cookbook info: %s"%(str(e)))

    return {'server_status': server_status, 'cookbook_info': cookbook_info}
Example #36
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
Example #37
0
 def object_action(self,
                   user,
                   obj,
                   objold=None,
                   action=None,
                   computers=None):
     api = get_chef_api(self.app.conf, user)
     cookbook = get_cookbook(api, self.app.conf.get('chef.cookbook_name'))
     computers = computers or self.get_related_computers(obj)
     are_new_jobs = False
     for computer in computers:
         try:
             job_ids_by_computer = []
             node_chef_id = computer.get('node_chef_id', None)
             node = reserve_node_or_raise(
                 node_chef_id, api,
                 'gcc-tasks-%s-%s' % (obj['_id'], random.random()), 10)
             if not node.get(self.app.conf.get('chef.cookbook_name')):
                 raise NodeNotLinked("Node %s is not linked" % node_chef_id)
             error_last_saved = computer.get('error_last_saved', False)
             error_last_chef_client = computer.get('error_last_chef_client',
                                                   False)
             force_update = error_last_saved or error_last_chef_client
             node, updated = self.update_node(user, computer, obj, objold,
                                              node, action,
                                              job_ids_by_computer,
                                              force_update)
             if not updated:
                 save_node_and_free(node)
                 continue
             are_new_jobs = True
             self.validate_data(node, cookbook, api)
             save_node_and_free(node)
             if error_last_saved:
                 self.db.nodes.update({'_id': computer['_id']},
                                      {'$set': {
                                          'error_last_saved': False
                                      }})
         except NodeNotLinked as e:
             self.report_node_not_linked(computer, user, obj, action)
             are_new_jobs = True
             save_node_and_free(node, api, refresh=True)
         except NodeBusyException as e:
             self.report_node_busy(computer, user, obj, action)
             are_new_jobs = True
         except ValidationError as e:
             if not job_ids_by_computer:
                 self.report_unknown_error(e, user, obj, action, computer)
             self.report_error(e, job_ids_by_computer, computer,
                               'Validation error: ')
             save_node_and_free(node, api, refresh=True)
             are_new_jobs = True
         except Exception as e:
             if not job_ids_by_computer:
                 self.report_unknown_error(e, user, obj, action, computer)
             self.report_error(e, job_ids_by_computer, computer)
             try:
                 save_node_and_free(node, api, refresh=True)
             except:
                 pass
             are_new_jobs = True
     if are_new_jobs:
         invalidate_jobs(self.request, user)
Example #38
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
Example #39
0
    def get(self):
        result = super(ComputerResource, self).get()
        node_collection = self.request.db.nodes

        if not result.get('node_chef_id', None):
            return result

        logger.info("/api/computers/: node_chef_id: %s" %
                    (str(result.get('node_chef_id', None))))

        try:
            api = get_chef_api(self.request.registry.settings,
                               self.request.user)
            computer_node = ChefNode(result['node_chef_id'], api)
            ohai = to_deep_dict(computer_node.attributes)
            nodeid = result.get('_id', None)
            usernames = [
                i['username']
                for i in ohai.get('ohai_gecos', {}).get('users', [])
            ]
            users = list(
                node_collection.find(
                    {
                        "$and": [{
                            "$or": [{
                                "name": {
                                    "$in": usernames
                                }
                            }]
                        }, {
                            "type": "user"
                        }, {
                            "computers": {
                                "$elemMatch": {
                                    "$eq": ObjectId(nodeid)
                                }
                            }
                        }]
                    }, {
                        '_id': 1,
                        'name': 1,
                        'path': 1
                    }))
            # ObjectId to string for JSON serialize
            [d.update({'_id': str(d['_id'])}) for d in users]

            # Create a list of users that provides at least one user policy to this computer
            users_inheritance_pre = list(
                node_collection.find(
                    {
                        "$and": [{
                            "$or": [{
                                "name": {
                                    "$in": usernames
                                }
                            }]
                        }, {
                            "type": "user"
                        }, {
                            "computers": {
                                "$elemMatch": {
                                    "$eq": ObjectId(nodeid)
                                }
                            }
                        }]
                    }, {
                        '_id': 1,
                        'name': 1,
                        'path': 1,
                        'inheritance': 1
                    }))
            [d.update({'_id': str(d['_id'])}) for d in users_inheritance_pre]

            users_inheritance = []
            for usr_inh in users_inheritance_pre:
                if 'inheritance' in usr_inh:
                    policies_list = get_inheritance_tree_policies_list(
                        usr_inh['inheritance'], [])
                    if len(policies_list) > 0:
                        users_inheritance.append(usr_inh)

            cpu = ohai.get('cpu', {}).get('0', {})
            dmi = ohai.get('dmi', {})

            # debug_mode flag for logs tab
            debug_mode = False
            try:
                debug_mode = computer_node.attributes.get_dotted(
                    DEBUG_MODE_ENABLE_ATTR_PATH)
            except KeyError:
                pass

            # Get logs info
            logs_data = node_collection.find_one(
                {
                    "type": "computer",
                    "_id": ObjectId(nodeid)
                }, {"logs": True})
            logs = {}
            if logs_data is not None and 'logs' in logs_data:
                logs_data = logs_data['logs']

                date_format = locale.nl_langinfo(locale.D_T_FMT)
                date = datetime.datetime(
                    *map(int,
                         re.split('[^\d]', logs_data['date'])[:-1]))
                localename = locale.normalize(
                    get_current_request().locale_name + '.UTF-8')
                logger.debug("/api/computers/: localename: %s" %
                             (str(localename)))
                locale.setlocale(locale.LC_TIME, localename)
                logs['date'] = date.strftime(date_format)
                logger.debug("/api/computers/: date: %s" % (str(logs['date'])))

                logs['files'] = logs_data['files']
                for filedata in logs_data['files']:
                    # Do not send file contents
                    del filedata['content']

            # Get Help Channel info
            help_channel_enabled = True
            helpchannel_data = self.request.db.helpchannel.find({
                "computer_node_id":
                result['node_chef_id']
            }).sort([("last_modified", pymongo.DESCENDING)]).limit(6)
            helpchannel = {}
            helpchannel['current'] = None
            helpchannel['last'] = []
            if helpchannel_data is not None:
                c = 0
                for hcdata in helpchannel_data:
                    # Format date
                    date_format = locale.nl_langinfo(locale.D_T_FMT)
                    logger.info("last_modified: {0}".format(
                        hcdata['last_modified']))
                    last_mod = re.split('[^\d]', str(hcdata['last_modified']))
                    logger.info("last_mod: {0}".format(last_mod))

                    date = datetime.datetime(*map(int, last_mod[:-2]))
                    localename = locale.normalize(
                        get_current_request().locale_name + '.UTF-8')
                    logger.debug("/api/computers/: localename: %s" %
                                 (str(localename)))
                    locale.setlocale(locale.LC_TIME, localename)
                    hcdata['last_modified'] = date.strftime(date_format)

                    if hcdata['user_node_id']:
                        # Format user
                        user_data = node_collection.find_one({
                            "type":
                            "user",
                            "_id":
                            ObjectId(hcdata['user_node_id'])
                        })
                        if user_data:
                            hcdata['user'] = user_data['name']
                        else:
                            logger.error("User not found: {0}".format(
                                hcdata['user_node_id']))
                    else:
                        hcdata['user'] = ''

                    if hcdata['adminuser_id']:
                        # Format user
                        user_data = self.request.db.adminusers.find_one(
                            {"_id": ObjectId(hcdata['adminuser_id'])})
                        if user_data:
                            hcdata['admin'] = user_data['username']
                        else:
                            logger.error("Admin user not found: {0}".format(
                                hcdata['adminuser_id']))
                    else:
                        hcdata['admin'] = ''

                    # Translate status info
                    hcdata['status'] = _('Unknown status')
                    if hcdata['action'] == 'request':
                        hcdata['status'] = _('User is requesting support')
                    elif hcdata['action'] == 'accepted':
                        hcdata['status'] = _('User is requesting support')
                    elif hcdata['action'] == 'finished user':
                        hcdata['status'] = _('Terminated by user')
                    elif hcdata['action'] == 'finished tech':
                        hcdata['status'] = _('Terminated by technician')
                    elif hcdata['action'] == 'finished error':
                        hcdata['status'] = _(
                            'Terminated because of a communication error')
                    elif hcdata['action'] == 'giving support':
                        hcdata['status'] = _(
                            'The technician is giving support to the user')

                    hcdata['_id'] = str(hcdata['_id'])

                    if (c == 0 and hcdata['action'] == 'accepted'):
                        helpchannel['current'] = hcdata
                    else:
                        helpchannel['last'].append(hcdata)

                    c = c + 1

            result.update({
                'ohai':
                ohai,
                'users':
                users,  # Users related with this computer
                'users_inheritance':
                users_inheritance,  # Users related with this computer that provides at least one user policy
                'uptime':
                ohai.get('uptime', ''),
                #'gcc_link': ohai.get('gcc_link',True),
                'ipaddress':
                ohai.get('ipaddress', ''),
                'cpu':
                '%s %s' %
                (cpu.get('vendor_id', ''), cpu.get('model_name', '')),
                'product_name':
                dmi.get('system', {}).get('product_name', ''),
                'manufacturer':
                dmi.get('system', {}).get('manufacturer', ''),
                'ram':
                ohai.get('memory', {}).get('total', ''),
                'lsb':
                ohai.get('lsb', {}),
                'kernel':
                ohai.get('kernel', {}),
                'filesystem':
                ohai.get('filesystem', {}),
                'debug_mode':
                debug_mode,
                'logs':
                logs,
                'helpchannel':
                helpchannel,
                'help_channel_enabled':
                help_channel_enabled
            })
        except (urllib2.URLError, ChefError, ChefServerError):
            logger.error(
                "/api/computers/: error getting data: node_chef_id: %s " %
                (str(result.get('node_chef_id', None))))
            logger.error(traceback.format_exc())

        return result
Example #40
0
    def get(self):
        result = super(ComputerResource, self).get()
        node_collection = self.request.db.nodes
        
        if not result.get('node_chef_id', None):
            return result
        
        logger.info("/api/computers/: node_chef_id: %s" % (str(result.get('node_chef_id', None))))

        try:
            api = get_chef_api(self.request.registry.settings, self.request.user)
            computer_node = ChefNode(result['node_chef_id'], api)
            ohai = to_deep_dict(computer_node.attributes)
            nodeid = result.get('_id',None)
            usernames = [i['username'] for i in ohai.get('ohai_gecos', {}).get('users', [])]
            users = list(node_collection.find({
                "$and": [
                    { "$or": [{"name": {"$in": usernames}}] }, 
                    { "type":"user"},
                    { "computers": {"$elemMatch": {"$eq": ObjectId(nodeid)}}}
                 ]
            },{'_id':1,'name':1,'path':1}))
            # ObjectId to string for JSON serialize
            [d.update({'_id': str(d['_id'])}) for d in users]
            
            # Create a list of users that provides at least one user policy to this computer
            users_inheritance_pre = list(node_collection.find({
                "$and": [
                    { "$or": [{"name": {"$in": usernames}}] }, 
                    { "type":"user"},
                    { "computers": {"$elemMatch": {"$eq": ObjectId(nodeid)}}}
                 ]
            },{'_id':1,'name':1,'path':1, 'inheritance': 1}))
            [d.update({'_id': str(d['_id'])}) for d in users_inheritance_pre]

            users_inheritance = []
            for usr_inh in users_inheritance_pre:
                if 'inheritance' in usr_inh:
                    policies_list = get_inheritance_tree_policies_list(usr_inh['inheritance'], [])
                    if len(policies_list) > 0:
                        users_inheritance.append(usr_inh)
            
            
            cpu = ohai.get('cpu', {}).get('0', {})
            dmi = ohai.get('dmi', {})
            
            # debug_mode flag for logs tab
            debug_mode = False
            try:
                debug_mode = computer_node.attributes.get_dotted(DEBUG_MODE_ENABLE_ATTR_PATH)
            except KeyError:
                pass
            
            # Get logs info
            logs_data = node_collection.find_one({"type": "computer", "_id": ObjectId(nodeid)}, {"logs": True})
            logs = {}
            if logs_data is not None and 'logs' in logs_data:
                logs_data = logs_data['logs']
                
                date_format = locale.nl_langinfo(locale.D_T_FMT)
                date = datetime.datetime(*map(int, re.split('[^\d]', logs_data['date'])[:-1]))
                localename = locale.normalize(get_current_request().locale_name+'.UTF-8')
                logger.debug("/api/computers/: localename: %s" % (str(localename)))
                locale.setlocale(locale.LC_TIME, localename)
                logs['date'] = date.strftime(date_format)
                logger.debug("/api/computers/: date: %s" % (str(logs['date'])))
                
                logs['files'] = logs_data['files']
                for filedata in logs_data['files']:
                    # Do not send file contents
                    del filedata['content']
            
            # Get Help Channel info
            help_channel_enabled = True
            helpchannel_data = self.request.db.helpchannel.find(
                {"computer_node_id" : result['node_chef_id']}).sort(
                    [("last_modified", pymongo.DESCENDING)]).limit(6)
            helpchannel = {}
            helpchannel['current'] = None
            helpchannel['last'] = []
            if helpchannel_data is not None:
                c = 0
                for hcdata in helpchannel_data:
                    # Format date
                    date_format = locale.nl_langinfo(locale.D_T_FMT)
                    logger.info("last_modified: {0}".format( hcdata['last_modified']))
                    last_mod = re.split('[^\d]', str(hcdata['last_modified']))
                    logger.info("last_mod: {0}".format(last_mod))

                    date = datetime.datetime(*map(int, last_mod[:-2]))
                    localename = locale.normalize(get_current_request().locale_name+'.UTF-8')
                    logger.debug("/api/computers/: localename: %s" % (str(localename)))
                    locale.setlocale(locale.LC_TIME, localename)
                    hcdata['last_modified'] = date.strftime(date_format)
                    
                    if hcdata['user_node_id']:
                        # Format user
                        user_data = node_collection.find_one({"type": "user", "_id": ObjectId(hcdata['user_node_id'])})
                        if user_data:
                            hcdata['user'] = user_data['name']
                        else:
                            logger.error("User not found: {0}".format(hcdata['user_node_id']))
                    else:
                        hcdata['user'] = ''
                    
                    if hcdata['adminuser_id']:
                        # Format user
                        user_data = self.request.db.adminusers.find_one({"_id": ObjectId(hcdata['adminuser_id'])})
                        if user_data:
                            hcdata['admin'] = user_data['username']
                        else:
                            logger.error("Admin user not found: {0}".format(hcdata['adminuser_id']))
                    else:
                        hcdata['admin'] = ''
                        
                    # Translate status info
                    hcdata['status'] = _('Unknown status')
                    if hcdata['action'] == 'request':
                        hcdata['status'] = _('User is requesting support')
                    elif hcdata['action'] == 'accepted':
                        hcdata['status'] = _('User is requesting support')
                    elif hcdata['action'] == 'finished user':
                        hcdata['status'] = _('Terminated by user')
                    elif hcdata['action'] == 'finished tech':
                        hcdata['status'] = _('Terminated by technician')
                    elif hcdata['action'] == 'finished error':
                        hcdata['status'] = _('Terminated because of a communication error')
                    elif hcdata['action'] == 'giving support':
                        hcdata['status'] = _('The technician is giving support to the user')
                        
                        
                    hcdata['_id'] = str(hcdata['_id'])                
                    
                    if (c==0 and hcdata['action']=='accepted'):
                        helpchannel['current'] = hcdata
                    else:
                        helpchannel['last'].append(hcdata)
                    
                    c = c + 1
           
            
            result.update({'ohai': ohai,
                           'users': users, # Users related with this computer
                           'users_inheritance': users_inheritance, # Users related with this computer that provides at least one user policy
                           'uptime': ohai.get('uptime', ''),
                           #'gcc_link': ohai.get('gcc_link',True),
                           'ipaddress': ohai.get('ipaddress', ''),
                           'cpu': '%s %s' % (cpu.get('vendor_id', ''), cpu.get('model_name', '')),
                           'product_name': dmi.get('system', {}).get('product_name', ''),
                           'manufacturer': dmi.get('system', {}).get('manufacturer', ''),
                           'ram': ohai.get('memory', {}).get('total', ''),
                           'lsb': ohai.get('lsb', {}),
                           'kernel': ohai.get('kernel', {}),
                           'filesystem': ohai.get('filesystem', {}),
                           'debug_mode': debug_mode,
                           'logs': logs,
                           'helpchannel': helpchannel,
                           'help_channel_enabled': help_channel_enabled
                           })
        except (urllib2.URLError, ChefError, ChefServerError):
            pass
        return result
Example #41
0
    def command(self):
        '''
        This command recalculate the policies of the selected nodes
        These nodes are receiving as command arguments
        '''
        db = self.pyramid.db
        computers, num_computers = self.get_computers()
        admin_user = db.adminusers.find_one(
            {'username': self.options.administrator})
        if not admin_user:
            sys.stdout.write('Administrator does not exists\n')
            sys.exit(1)
        elif not admin_user.get('is_superuser', None):
            sys.stdout.write('Administrator should be super user\n')
            sys.exit(1)
        api = get_chef_api(self.settings, admin_user)
        cookbook_name = self.settings['chef.cookbook_name']
        # It is not really the max dots, because the integer division.
        max_optimal_dots = 80
        total_dots = min(num_computers, max_optimal_dots)

        if total_dots == num_computers:
            step = 1
        else:
            step = old_div(num_computers, total_dots)
            total_dots = int(math.ceil(float(num_computers) / step))

        sys.stdout.write('%s 100%%\n' % ('.' * total_dots))
        sys.stdout.flush()
        results_error = {}
        results_succes = {}
        # Get the cookbook
        cookbook = get_cookbook(api, cookbook_name)
        schema = cookbook['metadata']['attributes']['json_schema']['object']

        # Validate the cookbook schema
        validator = validator_for(schema)
        validator.check_schema(schema)

        for i, comp in enumerate(list(computers)):
            if i % step == 0:
                sys.stdout.write('.')
                sys.stdout.flush()
            recalculated, reason = recalc_node_policies(
                db.nodes, db.jobs, comp, admin_user, cookbook_name, api,
                cookbook, validator)
            if recalculated:
                results_succes[comp['name']] = reason
            else:
                results_error[comp['name']] = reason

        sys.stdout.write('\n\n\n*********** Success ********** \n')

        for name, reason in list(results_succes.items()):
            sys.stdout.write('%s: %s \n' % (name, reason))

        sys.stdout.write('\n\n\n*********** Errors ********** \n')

        for name, reason in list(results_error.items()):
            sys.stdout.write('%s: %s \n' % (name, reason))

        sys.stdout.flush()
Example #42
0
    def command(self):
        db = self.pyramid.db
        ou = db.nodes.find_one({'_id': ObjectId(self.options.ou_id)})
        if not ou:
            print 'Error OU does not exists'
            return
        comp = db.nodes.find_one({'_id': ObjectId(self.options.comp_id)})
        if not comp:
            print 'Error computer does not exists'
            return
        node_id = comp.get('node_chef_id', None)
        if not comp:
            print 'Error this computer has not node_chef_id'
            return
        policies = comp.get('policies', None)
        if policies != {}:
            print 'Error this computer should not have any policies'
            return
        admin = db.adminusers.find_one({'username': self.options.gcc_username})
        if not admin:
            print 'Error this admin does not exists'
            return
        elif not admin.get('is_superuser', None):
            print 'You need a super admin'
            return
        number_nodes = int(self.options.number)
        api = get_chef_api(self.settings,
                           admin)
        node = ChefNode(node_id, api)
        for i in range(number_nodes):
            new_node_name = '%s-%s' % (self.options.prefix, i)
            new_node = ChefNode(new_node_name, api)
            for attr in node.to_dict().keys():
                if hasattr(node, attr) and attr != 'name':
                    if attr == 'automatic':
                        automatic_dict = node.automatic.to_dict()
                        automatic_dict['ohai_gecos']['pclabel'] = new_node_name
                        user1 = 'user.name-%s-1' % new_node_name
                        user2 = 'user.name-%s-2' % new_node_name
                        automatic_dict['ohai_gecos']['users'] = [{'username': user1,
                                                                  'home': '/home/%s' % user1,
                                                                  'gid': 1000,
                                                                  'sudo': False,
                                                                  'uid': 1000},
                                                                 {'username': user2,
                                                                  'home': '/home/%s' % user2,
                                                                  'gid': 1000,
                                                                  'sudo': False,
                                                                  'uid': 1001}]

                        automatic = NodeAttributes(automatic_dict)
                        setattr(new_node, attr, automatic)
                    elif attr == 'normal':
                        node.normal.set_dotted('ohai_gecos', {})
                    else:
                        setattr(new_node, attr, getattr(node, attr))
            new_node.save()
            print 'Created %s at chef' % new_node_name
            res = requests.post('%s/register/computer/' % self.options.gcc_url,
                                {'ou_id': self.options.ou_id, 'node_id': new_node_name},
                                auth=(self.options.gcc_username, self.options.gcc_password))
            if res.ok and res.json()['ok']:
                print 'Created %s at gcc' % new_node_name
            elif res.ok and not res.json()['ok']:
                print 'Error %s at gcc' % new_node_name
                print '\t %s' % res.json()['message']
            else:
                print 'Unknow error %s at gcc' % new_node_name

            res = requests.put('%s/chef/status/' % self.options.gcc_url,
                               {'node_id': new_node_name,
                                'gcc_username': self.options.gcc_username})

            if res.ok and res.json()['ok']:
                print 'Chef client %s' % new_node_name
            elif res.ok and not res.json()['ok']:
                print 'Error %s at chef client' % new_node_name
                print '\t %s' % res.json()['message']
            else:
                print 'Unknow error %s at chef client' % new_node_name

        waiting_to_celery(db)
    def post(self):
        logger.debug('/help-channel-client/login START')

        # Default known message
        known_message = 'En un lugar de la Mancha, de cuyo nombre no quiero'\
            ' acordarme, no ha mucho tiempo que vivía un hidalgo de los de'\
            ' lanza en astillero, adarga antigua, rocín flaco y galgo corredor.'

        # Check the parameters
        node_id = self.request.POST.get('node_id')
        if not node_id:
            logger.error('/help-channel-client/login - No node ID')
            return {'ok': False, 'message': 'Please set a node id'}

        username = self.request.POST.get('username')
        if not username:
            logger.error('/help-channel-client/login - No username')
            return {'ok': False, 'message': 'Please set a username'}

        secret = self.request.POST.get('secret')
        if not secret:
            logger.error('/help-channel-client/login - No secret')
            return {'ok': False, 'message': 'Please set a secret'}

        hc_server = self.request.POST.get('hc_server')
        if not hc_server:
            logger.error('/help-channel-client/login - No server')
            return {'ok': False, 'message': 'Please set a Help Channel Server'}

        gcc_username = self.request.POST.get('gcc_username')
        if not gcc_username:
            logger.error('/help-channel-client/login - No admin username')
            return {
                'ok': False,
                'message': 'Please set a GCC administrator username'
            }

        self.request.user = self.request.db.adminusers.find_one(
            {'username': gcc_username})
        if not self.request.user:
            return {
                'ok': False,
                'message': 'The admin user %s does not exists' % gcc_username
            }

        logger.debug('/help-channel-client/login node_id=%s' % (node_id))
        logger.debug('/help-channel-client/login username=%s' % (username))
        logger.debug('/help-channel-client/login secret=%s' % (secret))
        logger.debug('/help-channel-client/login hc_server=%s' % (hc_server))
        logger.debug('/help-channel-client/login gccusername=%s' %
                     (gcc_username))

        gcc_node = self.request.db.nodes.find_one({'node_chef_id': node_id})
        if not gcc_node:
            logger.error('/help-channel-client/login - Node not found')
            return {'ok': False, 'message': 'Node not found in database'}

        can_access_to_this_path(self.request,
                                self.request.db.nodes,
                                gcc_node,
                                ou_type='ou_remote')  # Remote OUs

        gcc_user = self.request.db.nodes.find_one({
            'type': 'user',
            'name': username
        })
        if not gcc_user:
            logger.error('/help-channel-client/login - User not found')
            return {'ok': False, 'message': 'User not found in database'}

        try:
            # Check the secret message
            api = get_chef_api(self.request.registry.settings,
                               self.request.user)
            chef_client = ChefClient(node_id, api)
            if not chef_client.exists:
                logger.error('/help-channel-client/login - Client not found')
                return {'ok': False, 'message': 'This client does not exists'}

            chef_node = ChefNode(node_id, api)
            if not chef_node.exists:
                logger.error(
                    '/help-channel-client/login - Chef node not found')
                return {
                    'ok': False,
                    'message': 'This chef node does not exists'
                }

            client_certificate = chef_client.certificate
            public_key = RSA.importKey(client_certificate)

            decrypted = public_key.encrypt(bytes.fromhex(secret), 0)[0]
            decrypted = decrypted.decode("utf-8")

            known_message_setting = self.request.registry.settings.get(
                'helpchannel.known_message')
            if known_message_setting is not None:
                known_message = known_message_setting

            if decrypted != known_message:
                logger.error('/help-channel-client/login - Bad secret')
                return {'ok': False, 'message': 'Bad secret'}

            # Login successful, generate the token!
            server_address = self.request.registry.settings.get(
                'server_address', 'UNKNOWN')

            if server_address == 'UNKNOWN':
                server_address = os.getenv('HOSTNAME', 'UNKNOWN')

            # - Token generation
            min_char = 8
            max_char = 12
            allchar = string.ascii_letters + string.digits
            token = ''.join(
                choice(allchar) for _ in range(randint(min_char, max_char)))

            self.request.db.helpchannel.insert_one({
                'last_modified':
                datetime.datetime.utcnow(),
                'action':
                'request',
                'computer_node_id':
                node_id,
                'computer_node_path':
                gcc_node['path'],
                'user_node_id':
                str(gcc_user['_id']),
                'user_node_path':
                gcc_user['path'],
                'adminuser_id':
                False,
                'adminuser_ou_managed':
                False,
                'adminuser_is_superuser':
                False,
                'gecos_cc_server':
                server_address,
                'helpchannel_server':
                hc_server,
                'token':
                token
            })

            logger.info('/help-channel-client/login - token: %s' % (token))
            return {'ok': True, 'token': token}

        except (urllib.error.URLError, ChefError, ChefServerError):
            pass

        logger.error('/help-channel-client/login - UNKNOWN')
        return {'ok': False, 'message': 'Unknown error'}
Example #44
0
def server_status(context, request):
    # Delete a non existent server?
    server_name = request.GET.get('delete', None)
    if server_name:
        request.db.servers.remove({"name": server_name})
    
    
    # Calculate server status list
    server_list = request.db.servers.find().sort('name')
    server_status = []
    
    # Get status of each server
    for server in server_list:
        status = getServerStatus(server['address'])
        if status is None:
            status = {}
            status['cpu'] = {}
            status['cpu']['load'] = 0
            status['cpu']['name'] = 'UNKNOWN'
            status['cpu']['ncores'] = 0
            
            status['ram'] = {}
            status['ram']['total'] = 0
            status['ram']['used'] = 0
            
            status['disk'] = {}
            status['disk']['mountpoints'] = []
            status['disk']['total'] = 0
            status['disk']['used'] = 0
            
        else:
            for mpt in status['disk']['mountpoints']:
                factor = 1
                factor_text = 'byte'
                
                if int(mpt['size']) > 1024:
                    factor = 1024
                    factor_text = 'Kbyte'
                    
                if int(mpt['size']) > (1024*1024):
                    factor = (1024*1024)
                    factor_text = 'Mbyte'

                if int(mpt['size']) > (1024*1024*1024):
                    factor = (1024*1024*1024)
                    factor_text = 'Gbyte'
                    
                if int(mpt['size']) > (1024*1024*1024*1024):
                    factor = (1024*1024*1024*1024)
                    factor_text = 'Tbyte'
                    
                mpt['factor'] = factor
                mpt['factor_text'] = factor_text
            
        status['name'] = server['name']
        status['address'] = server['address']
        # Check if the address is actually an IP address
        if not re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", 
                        status['address']):
            # Try to resolve the IP address
            status['address'] = socket.gethostbyname(status['address'])
            
        server_status.append(status)


    # Get cookbook info
    settings = get_current_registry().settings
    api = get_chef_api(settings, request.user)
    organization = 'default'

    cookbook_info = []
    try:
        cookbook_info = api['/organizations/%s/cookbooks'%(organization)]

    except Exception as e:
        logger.error("server_status: error getting cookbook info: %s"%(str(e)))

    return {'server_status': server_status, 'cookbook_info': cookbook_info}
Example #45
0
    def put(self):
        node_id = self.request.POST.get('node_id')
        username = self.request.POST.get('gcc_username')
        if not node_id:
            return {'ok': False,
                    'message': 'Please set a node id (node_id)'}
        if not username:
            return {'ok': False,
                    'message': 'Please set a admin username (gcc_username)'}
        self.request.user = self.request.db.adminusers.find_one({'username': username})
        if not self.request.user:
            return {'ok': False,
                    'message': 'The admin user %s does not exists' % username}
        settings = get_current_registry().settings
        api = get_chef_api(settings, self.request.user)
        node = Node(node_id, api)
        job_status = node.attributes.get('job_status')

        # After chef-client run, a report handler calls /api/chef_status
        # Previously, gcc_link attribute of chef node is updated by network policies
        gcc_link = node.attributes.get('gcc_link')
        self.request.db.nodes.update({'node_chef_id':node_id},{'$set': {'gcc_link':gcc_link}})

        reserve_node = False
        if job_status:
            node = reserve_node_or_raise(node_id, api, 'gcc-chef-status-%s' % random.random(), attempts=3)
            reserve_node = True
            chef_client_error = False

            for job_id, job_status in job_status.to_dict().items():
                job = self.collection.find_one({'_id': ObjectId(job_id)})
                if not job:
                    continue
                # Parent
                macrojob = self.collection.find_one({'_id': ObjectId(job['parent'])}) if 'parent' in job else None
                if job_status['status'] == 0:
                    self.collection.update({'_id': job['_id']},
                                           {'$set': {'status': 'finished',
                                                     'last_update': datetime.datetime.utcnow()}})
                    # Decrement number of children in parent
                    if macrojob and 'counter' in macrojob:
                        macrojob['counter'] -= 1
                elif job_status['status'] == 2:
                    self.collection.update({'_id': job['_id']},
                                           {'$set': {'status': 'warnings',
                                                     'message': job_status.get('message', 'Warning'),
                                                     'last_update': datetime.datetime.utcnow()}})
                    if macrojob:                                
                        macrojob['status'] = 'warnings'
                else:
                    chef_client_error = True
                    self.collection.update({'_id': job['_id']},
                                           {'$set': {'status': 'errors',
                                                     'message': job_status.get('message', 'Error'),
                                                     'last_update': datetime.datetime.utcnow()}})
                    if macrojob:                                
                        macrojob['status'] = 'errors'
                # Update parent                                 
                if macrojob:
                    self.collection.update({'_id': macrojob['_id']},                                                                
                                           {'$set': {'counter': macrojob['counter'],
                                                     'message': self._("Pending: %d") % macrojob['counter'],
                                                     'status': 'finished' if macrojob['counter'] == 0 else macrojob['status']}})
            self.request.db.nodes.update({'node_chef_id': node_id}, {'$set': {'error_last_chef_client': chef_client_error}})
            invalidate_jobs(self.request)
            node.attributes.set_dotted('job_status', {})

        users_old = self.get_attr(node, USERS_OLD)
        users = self.get_attr(node, USERS_OHAI)
        if not users_old or users_old != users:
            if not reserve_node:
                node = reserve_node_or_raise(node_id, api, 'gcc-chef-status-%s' % random.random(), attempts=3)
            return self.check_users(node, api)
        if job_status:
            save_node_and_free(node)
        return {'ok': True}