コード例 #1
0
    def test_sync_altered_groups(self, mock_add_or_update):
        """Test the sync_altered accounts function"""
        mock_client = mock.MagicMock()
        test_group = mkGroup(test_vo_1)
        mock_client.allgroups.modified[1].get.return_value = (200, [test_vo_1])
        mock_client.vo[test_group.vsc_id].get.return_value = (200, test_vo_1)

        mock_add_or_update.return_value = UPDATED
        ldapsyncer = LdapSyncer(mock_client)
        groups = ldapsyncer.sync_altered_groups(1)
        self.assertEqual(groups, {'error': set([]), 'new': set([]), 'updated': set([test_group.vsc_id])})

        ldap_attrs = {'status': ['active'], 'scratchDirectory': ['/user/scratch/gent/gvo000/gvo00003'],
                      'dataDirectory': ['/user/data/gent/gvo000/gvo00003'], 'cn': 'gvo00003', 'institute': ['gent'],
                      'memberUid': ['vsc40075'], 'moderator': ['vsc40075'], 'gidNumber': ['2640010'],
                      'fairshare': ['100'], 'description': ['VO']}
        mock_add_or_update.assert_called_with(VscLdapGroup, test_group.vsc_id, ldap_attrs, True)

        #  raise a 404 error on getting the VO to trigger a non vo group add instead of a vo add as above
        test_group = mkGroup(test_usergroup_1)
        mock_client.allgroups.modified[1].get.return_value = (200, [test_usergroup_1])
        mock_client.vo[test_group.vsc_id].get.side_effect = HTTPError("mock_url", 404, "Not Found", "mock_headers", None)
        groups = ldapsyncer.sync_altered_groups(1)
        self.assertEqual(groups, {'error': set([]), 'new': set([]), 'updated': set([test_group.vsc_id])})
        ldap_attrs =  {'status': ['active'], 'cn': 'vsc40075', 'institute': ['gent'], 'memberUid': ['vsc40075'],
                       'moderator': ['vsc40075'], 'gidNumber': ['2540075']}
        mock_add_or_update.assert_called_with(VscLdapGroup, test_group.vsc_id, ldap_attrs, True)
コード例 #2
0
    def test_usergroup_instantiation(self):

        mock_client = mock.MagicMock()
        test_account = mkVscAccount(test_account_1)
        mock_client.account[test_account.vsc_id] = mock.MagicMock()
        mock_client.account[test_account.vsc_id].get.return_value = (
            200, test_account_1)
        mock_client.account[test_account.vsc_id].usergroup.get.return_value = (
            200, test_usergroup_1)

        accountpageuser = user.VscAccountPageUser(test_account.vsc_id,
                                                  rest_client=mock_client)

        self.assertEqual(accountpageuser.usergroup,
                         mkUserGroup(test_usergroup_1))

        mock_client.account[test_account.vsc_id].get.return_value = (
            200, test_account_2)
        mock_client.group[test_account_2].get.return_value = (
            200, test_admin_group_1)
        accountpageuser = user.VscAccountPageUser(test_account.vsc_id,
                                                  mock_client)

        self.assertEqual(accountpageuser.usergroup,
                         mkGroup(test_admin_group_1))
コード例 #3
0
    def test_sync_group_without_moderators(self, mock_add_or_update):
        """Test the synchronisation of the group without active mods."""
        mock_client = mock.MagicMock()
        test_group = mkGroup(test_group_1)
        mock_client.allgroups.modified[1].get.return_value = (200,
                                                              [test_group_1])
        mock_client.vo[test_group.vsc_id].get.side_effect = HTTPError(
            None, 404, 'not found', None, None)

        mock_add_or_update.return_value = UPDATED

        ldapsyncer = LdapSyncer(mock_client)
        groups = ldapsyncer.sync_altered_groups(1)
        self.assertEqual(groups, {
            'error': set([]),
            'new': set([]),
            'updated': set([test_group.vsc_id])
        })

        ldap_attrs = {
            'status': ['inactive'],
            'cn': 'gtestgroup',
            'institute': ['gent'],
            'memberUid': ['vsc40075'],
            'moderator': ['vsc40003'],
            'gidNumber': ['2640011'],
        }
        mock_add_or_update.assert_called_with(VscLdapGroup, test_group.vsc_id,
                                              ldap_attrs, True)
コード例 #4
0
ファイル: user.py プロジェクト: wpoely86/vsc-administration
    def usergroup(self):
        if not self._cache['usergroup']:
            if self.person.institute_login in ('x_admin', 'admin', 'voadmin'):
                # TODO to be removed when magic site admin usergroups are purged from code
                self._cache['usergroup'] = mkGroup((self.rest_client.group[self.user_id].get())[1])
            else:
                self._cache['usergroup'] = mkUserGroup((self.rest_client.account[self.user_id].usergroup.get()[1]))

        return self._cache['usergroup']
コード例 #5
0
    def sync_altered_groups(self, last, dry_run=True):
        """
        Synchronise altered groups back to LDAP.
        This also includes usergroups
        """
        changed_groups = [
            mkGroup(a) for a in self.client.allgroups.modified[last].get()[1]
        ]

        logging.info("Found %d modified groups in the range %s until %s" %
                     (len(changed_groups),
                      datetime.fromtimestamp(last).strftime("%Y%m%d%H%M%SZ"),
                      self.now.strftime("%Y%m%d%H%M%SZ")))
        logging.debug("Modified groups: %s",
                      [g.vsc_id for g in changed_groups])
        groups = {
            NEW: set(),
            UPDATED: set(),
            ERROR: set(),
        }

        for group in changed_groups:
            vo = False
            try:
                vo = mkVo(self.client.vo[group.vsc_id].get()[1])
            except HTTPError as err:
                # if a 404 occured, the group is not an VO, so we skip this. Otherwise something else went wrong.
                if err.code != 404:
                    raise
            ldap_attributes = {
                'cn': str(group.vsc_id),
                'institute': [str(group.institute['site'])],
                'gidNumber': ["%d" % (group.vsc_id_number, )],
                'moderator': [str(m) for m in group.moderators],
                'memberUid': [str(a) for a in group.members],
                'status': [str(group.status)],
            }
            if vo:
                ldap_attributes['fairshare'] = ["%d" % (vo.fairshare, )]
                ldap_attributes['description'] = [str(vo.description)]
                ldap_attributes['dataDirectory'] = [str(vo.data_path)]
                ldap_attributes['scratchDirectory'] = [str(vo.scratch_path)]
                # vsc40024 is moderator for all institute vo's
                if vo.vsc_id in INSTITUTE_VOS_GENT.values():
                    ldap_attributes['moderator'] = ['vsc40024']

            logging.debug("Proposed changes for group %s: %s", group.vsc_id,
                          ldap_attributes)

            result = self.add_or_update(VscLdapGroup, group.vsc_id,
                                        ldap_attributes, dry_run)
            groups[result].add(group.vsc_id)

        return groups
コード例 #6
0
    def sync_altered_groups(self, last, dry_run=True):
        """
        Synchronise altered groups back to LDAP.
        This also includes usergroups
        """
        changed_groups = [
            mkGroup(a) for a in self.client.allgroups.modified[last].get()[1]
        ]

        logging.info("Found %d modified groups in the range %s until %s" %
                     (len(changed_groups),
                      datetime.fromtimestamp(last).strftime("%Y%m%d%H%M%SZ"),
                      self.now.strftime("%Y%m%d%H%M%SZ")))
        logging.debug("Modified groups: %s",
                      [g.vsc_id for g in changed_groups])
        groups = {
            NEW: set(),
            UPDATED: set(),
            ERROR: set(),
        }

        for group in changed_groups:
            # General group attributes
            group_moderators = [str(m) for m in group.moderators]
            institute_name = str(group.institute['name'])

            ldap_attributes = {
                'cn': str(group.vsc_id),
                'institute': [institute_name],
                'gidNumber': ["%d" % (group.vsc_id_number, )],
                'moderator': group_moderators,
                'status': [str(group.status)],
            }

            # Only set memberUid if there are actually any members in the group
            # Addition of new group records in LDAP will fail with empty memberUid
            # Existing LDAP records of groups that become empty will lose memberUid
            # ldap.modlist.modifyModlist (vsc-ldap) will delete any attributes that are missing in the new record
            if group.members:
                ldap_attributes['memberUid'] = [str(a) for a in group.members]

            # VO attributes
            try:
                vo = mkVo(self.client.vo[group.vsc_id].get()[1])
            except HTTPError as err:
                # if a 404 occured, the group is not an VO, so we skip this. Otherwise something else went wrong.
                if err.code != 404:
                    logging.raiseException(
                        "Retrieval of group VO failed for unexpected reasons")
            else:
                # Group is a VO
                ldap_attributes['fairshare'] = ["%d" % (vo.fairshare, )]
                ldap_attributes['description'] = [str(vo.description)]
                ldap_attributes['dataDirectory'] = [str(vo.data_path)]
                ldap_attributes['scratchDirectory'] = [str(vo.scratch_path)]
                # Set institute moderator for main VOs
                if vo.vsc_id in DEFAULT_VOS_ALL:
                    ldap_attributes['moderator'] = [
                        VSC_CONFIG.vo_group_mods[group.institute['name']]
                    ]
                    logging.info("Using VO moderator %s for VO %s",
                                 ldap_attributes['moderator'], group.vsc_id)

            if not ldap_attributes['moderator']:
                ldap_attributes['moderator'] = [
                    str(VSC_CONFIG.backup_group_mods[group.institute['name']])
                ]
                logging.info("Using backup moderator %s for group %s",
                             ldap_attributes['moderator'], group.vsc_id)

            logging.debug("Proposed changes for group %s: %s", group.vsc_id,
                          ldap_attributes)

            result = self.add_or_update(VscLdapGroup, group.vsc_id,
                                        ldap_attributes, dry_run)
            groups[result].add(group.vsc_id)

        return groups
コード例 #7
0
    def sync_altered_accounts(self, last, dry_run=True):
        """
        Add new users to the LDAP and update altered users. This does not include usergroups.

        this does include pubkeys
        @type last: datetime
        @return: tuple (new, updated, error) that indicates what accounts were new, changed or could not be altered.
        """
        sync_accounts = [
            mkVscAccount(a)
            for a in self.client.account.modified[last].get()[1]
        ]
        accounts = {
            NEW: set(),
            UPDATED: set(),
            ERROR: set(),
        }

        logging.info("Found %d modified accounts in the range %s until %s" %
                     (len(sync_accounts),
                      datetime.fromtimestamp(last).strftime("%Y%m%d%H%M%SZ"),
                      self.now.strftime("%Y%m%d%H%M%SZ")))
        logging.debug("Modified accounts: %s",
                      [a.vsc_id for a in sync_accounts])

        for account in sync_accounts:
            try:
                if account.person.institute_login in ('x_admin', 'admin',
                                                      'voadmin'):
                    # TODO to be removed when magic site admin usergroups are purged from code
                    usergroup = mkGroup(
                        (self.client.group[account.vsc_id].get())[1])
                else:
                    usergroup = mkUserGroup(
                        self.client.account[account.vsc_id].usergroup.get()[1])
            except HTTPError:
                logging.error("No corresponding UserGroup for user %s" %
                              (account.vsc_id, ))
                continue
            gecos = ensure_ascii_string(account.person.gecos)

            logging.debug('fetching public key')
            public_keys = [
                ensure_ascii_string(x.pubkey)
                for x in self.client.get_public_keys(account.vsc_id)
            ]

            if not public_keys:
                public_keys = [ACCOUNT_WITHOUT_PUBLIC_KEYS_MAGIC_STRING]

            LDAP_STATE_MAPPER = {'forceinactive': 'inactive'}

            ldap_attributes = {
                'cn':
                str(account.vsc_id),
                'uidNumber': ["%s" % (account.vsc_id_number, )],
                'gecos': [gecos],
                'mail': [str(account.email)],
                'institute': [str(account.person.institute['name'])],
                'instituteLogin': [str(account.person.institute_login)],
                'uid': [str(account.vsc_id)],
                'homeDirectory': [str(account.home_directory)],
                'dataDirectory': [str(account.data_directory)],
                'scratchDirectory': [str(account.scratch_directory)],
                'pubkey':
                public_keys,
                'gidNumber': [str(usergroup.vsc_id_number)],
                'loginShell': [str(account.login_shell)],
                'researchField': [str(account.research_field[0])],
                'status': [
                    LDAP_STATE_MAPPER.get(str(account.status),
                                          str(account.status))
                ],
                'homeQuota': ["1"],
                'dataQuota': ["1"],
                'scratchQuota': ["1"],
            }
            logging.debug('fetching quota')
            quotas = self.client.account[account.vsc_id].quota.get()[1]
            for quota in quotas:
                for stype in ['home', 'data', 'scratch']:
                    # only gent sets filesets for vo's, so not gvo is user. (other institutes is empty or "None"
                    if quota['storage']['storage_type'] == stype and not quota[
                            'fileset'].startswith('gvo'):
                        ldap_attributes['%sQuota' %
                                        stype] = ["%d" % quota["hard"]]

            result = self.add_or_update(VscLdapUser, account.vsc_id,
                                        ldap_attributes, dry_run)
            accounts[result].add(account.vsc_id)

        return accounts