Пример #1
0
 def test_project_termination(self):
     """Terminated projects should remove its attributes."""
     entity_trait = EntityTrait(self._db)
     self.setup_project('del_me')
     eid = self._ou.entity_id
     self._ou.terminate()
     self.assertEqual(eid, self._ou.entity_id)
     # The OU object itself must remain, and its project ID and project name
     # No accounts:
     self.assertEqual(0, len(self._ac.list_accounts_by_type(
         ou_id=eid,
         filter_expired=False)))
     # No affiliated persons:
     self.assertEqual(0, len(self._pe.list_affiliations(
         ou_id=eid,
         include_deleted=True)))
     # Checking for different types of traits.
     # Are there any traits that should be left?
     # No groups:
     # list_traits returns an iterator instead of a list
     groups = tuple(self._gr.list_traits(
         code=self._co.trait_project_group, target_id=eid))
     self.assertEqual(0, len(groups))
     # No hosts:
     hosts = tuple(entity_trait.list_traits(
         target_id=eid, code=self._co.trait_project_host))
     self.assertEqual(0, len(hosts))
     # No subnets:
     subnets = tuple(entity_trait.list_traits(
         target_id=eid,
         code=(self._co.trait_project_subnet6,
               self._co.trait_project_subnet)))
     self.assertEqual(0, len(subnets))
def get_student_disks(db):
    """ Get disks tagged as student disks. """
    et = EntityTrait(db)
    co = Factory.get('Constants')(db)
    return set(
        t['entity_id']
        for t in et.list_traits(code=co.trait_student_disk))
def get_student_disks(db):
    """ Get disks tagged as student disks. """
    et = EntityTrait(db)
    co = Factory.get('Constants')(db)
    return set(
        t['entity_id']
        for t in et.list_traits(code=co.trait_student_disk))
Пример #4
0
    def populate(self, owner_entity_id):
        """Create a new VoipAddress in memory.

        FIXME: check that owner_entity_type is voip_service/person.
        FIXME: check that owner_entity_id does not own other voipAddresses.
        """
        EntityTrait.populate(self, self.const.entity_voip_address)
        try:
            if not self.__in_db:
                raise RuntimeError("populate() called multiple times.")
        except AttributeError:
            self.__in_db = False
        self.owner_entity_id = owner_entity_id
Пример #5
0
    def populate(self, description, service_type, ou_id):
        """Create a new VoipService instance in memory.
        """
        EntityTrait.populate(self, self.const.entity_voip_service)

        try:
            if not self.__in_db:
                raise RuntimeError("populate() called multiple times.")
        except AttributeError:
            self.__in_db = False

        self.description = description
        self.service_type = self.const.VoipServiceTypeCode(int(service_type))
        self.ou_id = int(ou_id)
Пример #6
0
    def populate(self, description, service_type, ou_id):
        """Create a new VoipService instance in memory.
        """
        EntityTrait.populate(self, self.const.entity_voip_service)

        try:
            if not self.__in_db:
                raise RuntimeError("populate() called multiple times.")
        except AttributeError:
            self.__in_db = False

        self.description = description
        self.service_type = self.const.VoipServiceTypeCode(int(service_type))
        self.ou_id = int(ou_id)
Пример #7
0
def get_default_host_quota(db, host_id):
    """
    Get default disk quota from host trait.

    :rtype: int
    :return:
        Returns the default disk quota set on the host, or None if no default
        quota is set.
    """
    et = EntityTrait(db)
    try:
        et.find(host_id)
        trait = et.get_trait(_Co.trait_host_disk_quota)
    except Errors.NotFoundError:
        trait = None
    trait = trait or {}
    return trait.get('numval')
Пример #8
0
def has_disk_quota(db, disk_id):
    """
    Check if disk has disk quotas enabled.

    Quotas are enabled/disabled by setting a disk quota trait on the disk.
    The trait may have no default disk quota.

    :rtype: bool
    :return:
        True if quota is enabled.
    """
    et = EntityTrait(db)
    try:
        et.find(disk_id)
    except Errors.NotFoundError:
        trait = None
    else:
        trait = et.get_trait(_Co.trait_disk_quota)
    return trait is not None
Пример #9
0
    def populate(self, voip_address_id, client_type, sip_enabled,
                 mac_address, client_info):
        """Create a new VoipClient in memory."""

        assert sip_enabled in (True, False)
        mac_address = self._normalize_mac_address(mac_address)
        EntityTrait.populate(self, self.const.entity_voip_client)

        try:
            if not self.__in_db:
                raise RuntimeError("populate() called multiple times.")
        except AttributeError:
            self.__in_db = False

        self.voip_address_id = int(voip_address_id)
        self.client_type = int(self.const.VoipClientTypeCode(client_type))
        self.sip_enabled = bool(sip_enabled)
        self.mac_address = mac_address
        self.client_info = int(self.const.VoipClientInfoCode(client_info))
        self._assert_mac_rules()
Пример #10
0
    def affiliate_entity(self, entity):
        """Affiliate an entity with this project.

        :type entity: Group, DnsOwner, DnsSubnet, DnsSubnet6
        :param entity:
            An entity to affiliate with this project
        """
        trait_code = self._get_affiliate_trait(entity.entity_type)
        trait = EntityTrait(self._db)
        trait.find(entity.entity_id)
        trait.populate_trait(trait_code,
                             target_id=self.entity_id,
                             date=DateTime.now())
        trait.write_db()
Пример #11
0
    def is_affiliated_entity(self, entity):
        u""" Check if entity is affiliated with project.

        :param Entity entity:
            An entity to check

        :return bool:
            Returns True if entity is affiliated with project
        """
        try:
            trait_code = self._get_affiliate_trait(entity.entity_type)
        except Errors.CerebrumError:
            return False

        try:
            trait = EntityTrait(self._db)
            trait.find(entity.entity_id)
            return trait.get_trait(trait_code)['target_id'] == self.entity_id
        except Errors.NotFoundError:
            return False
        except TypeError:
            return False
Пример #12
0
    def is_affiliated_entity(self, entity):
        """Check if entity is affiliated with project.

        :param Entity entity:
            An entity to check

        :return bool:
            Returns True if entity is affiliated with project
        """
        try:
            trait_code = self._get_affiliate_trait(entity.entity_type)
        except Errors.CerebrumError:
            return False

        try:
            trait = EntityTrait(self._db)
            trait.find(entity.entity_id)
            return trait.get_trait(trait_code)['target_id'] == self.entity_id
        except Errors.NotFoundError:
            return False
        except TypeError:
            return False
Пример #13
0
def delete_common(entity_id, db):
    """Remove information from the database common to whichever entity we are
    deleting.
    """
    # Remove spreads
    # Remove traits
    # Remove all permissions
    # Remove from all groups
    # Remove change_log entries
    const = Factory.get("Constants")()
    logger.debug("Deleting common parts for entity %s (id=%s)",
                 fetch_name(entity_id, db), entity_id)

    es = EntitySpread(db)
    es.find(entity_id)
    logger.debug(
        "Deleting spreads: %s",
        ", ".join(str(const.Spread(x["spread"])) for x in es.get_spread()))
    for row in es.get_spread():
        es.delete_spread(row["spread"])

    et = EntityTrait(db)
    et.find(entity_id)
    logger.debug("Deleting traits: %s",
                 ", ".join(str(x) for x in et.get_traits()))
    # copy(), since delete_trait and get_traits work on the same dict. This is
    # so silly.
    for trait_code in et.get_traits().copy():
        et.delete_trait(trait_code)

    remove_target_permissions(entity_id, db)

    remove_permissions_on_target(entity_id, db)

    # Kill memberships
    group = Factory.get("Group")(db)
    for row in group.search(member_id=entity_id, filter_expired=False):
        group.clear()
        group.find(row["group_id"])
        logger.debug("Removing %s as member of %s (id=%s)", entity_id,
                     group.group_name, group.entity_id)
        group.remove_member(entity_id)

    # Kill change_log entries
    logger.debug("Cleaning change_log of references to %s", entity_id)
    # Kill change_log entries (this includes requests linked to this entity)
    for row in db.get_log_events(subject_entity=entity_id):
        db.remove_log_event(row["change_id"])
Пример #14
0
 def test_project_termination(self):
     """Terminated projects should remove its attributes."""
     entity_trait = EntityTrait(self._db)
     self.setup_project('del_me')
     eid = self._ou.entity_id
     self._ou.terminate()
     self.assertEqual(eid, self._ou.entity_id)
     # The OU object itself must remain, and its project ID and project name
     # No accounts:
     self.assertEqual(
         0,
         len(self._ac.list_accounts_by_type(ou_id=eid,
                                            filter_expired=False)))
     # No affiliated persons:
     self.assertEqual(
         0, len(self._pe.list_affiliations(ou_id=eid,
                                           include_deleted=True)))
     # Checking for different types of traits.
     # Are there any traits that should be left?
     # No groups:
     # list_traits returns an iterator instead of a list
     groups = tuple(
         self._gr.list_traits(code=self._co.trait_project_group,
                              target_id=eid))
     self.assertEqual(0, len(groups))
     # No hosts:
     hosts = tuple(
         entity_trait.list_traits(target_id=eid,
                                  code=self._co.trait_project_host))
     self.assertEqual(0, len(hosts))
     # No subnets:
     subnets = tuple(
         entity_trait.list_traits(target_id=eid,
                                  code=(self._co.trait_project_subnet6,
                                        self._co.trait_project_subnet)))
     self.assertEqual(0, len(subnets))
Пример #15
0
    def affiliate_entity(self, entity):
        """Affiliate an entity with this project.

        :type entity: Group, DnsOwner, DnsSubnet, DnsSubnet6
        :param entity:
            An entity to affiliate with this project
        """
        trait_code = self._get_affiliate_trait(entity.entity_type)
        trait = EntityTrait(self._db)
        trait.find(entity.entity_id)
        trait.populate_trait(trait_code,
                             target_id=self.entity_id,
                             date=DateTime.now())
        trait.write_db()
Пример #16
0
def delete_common(entity_id, db):
    """Remove information from the database common to whichever entity we are
    deleting.
    """
    # Remove spreads
    # Remove traits
    # Remove all permissions
    # Remove from all groups
    # Remove change_log entries
    const = Factory.get("Constants")()
    logger.debug("Deleting common parts for entity %s (id=%s)",
                 fetch_name(entity_id, db), entity_id)

    es = EntitySpread(db)
    es.find(entity_id)
    logger.debug("Deleting spreads: %s",
                 ", ".join(str(const.Spread(x["spread"]))
                           for x in es.get_spread()))
    for row in es.get_spread():
        es.delete_spread(row["spread"])

    et = EntityTrait(db)
    et.find(entity_id)
    logger.debug("Deleting traits: %s",
                 ", ".join(str(x) for x in et.get_traits()))
    # copy(), since delete_trait and get_traits work on the same dict. This is
    # so silly.
    for trait_code in et.get_traits().copy():
        et.delete_trait(trait_code)

    remove_target_permissions(entity_id, db)

    remove_permissions_on_target(entity_id, db)

    # Kill memberships
    group = Factory.get("Group")(db)
    for row in group.search(member_id=entity_id,
                            filter_expired=False):
        group.clear()
        group.find(row["group_id"])
        logger.debug("Removing %s as member of %s (id=%s)",
                     entity_id, group.group_name, group.entity_id)
        group.remove_member(entity_id)

    # Kill change_log entries
    logger.debug("Cleaning change_log of references to %s", entity_id)
    # Kill change_log entries (this includes requests linked to this entity)
    for row in db.get_log_events(subject_entity=entity_id):
        db.remove_log_event(row["change_id"])
Пример #17
0
    def terminate(self):
        """Remove all of a project, except its project ID and name (acronym).

        The project's entities are deleted by this method, so use with care!

        For the OU object, it does almost the same as L{delete} except from
        deleting the entity itself.
        """
        self.write_db()
        ent = EntityTrait(self._db)
        ac = Factory.get('Account')(self._db)
        pu = Factory.get('PosixUser')(self._db)
        # Delete PosixUsers
        for row in ac.list_accounts_by_type(ou_id=self.entity_id,
                                            filter_expired=False):
            try:
                pu.clear()
                pu.find(row['account_id'])
                pu.delete_posixuser()
            except Errors.NotFoundError:
                # not a PosixUser
                continue
        # Remove all project's groups
        gr = Factory.get('Group')(self._db)
        for row in gr.list_traits(code=self.const.trait_project_group,
                                  target_id=self.entity_id):
            gr.clear()
            gr.find(row['entity_id'])
            gr.delete()
        # Delete all users
        for row in ac.list_accounts_by_type(ou_id=self.entity_id):
            ac.clear()
            ac.find(row['account_id'])
            ac.delete()
        # Remove every trace of person affiliations to the project:
        pe = Factory.get('Person')(self._db)
        for row in pe.list_affiliations(ou_id=self.entity_id,
                                        include_deleted=True):
            pe.clear()
            pe.find(row['person_id'])
            pe.nuke_affiliation(ou_id=row['ou_id'],
                                affiliation=row['affiliation'],
                                source=row['source_system'],
                                status=row['status'])
            pe.write_db()
        # Remove all project's DnsOwners (hosts):
        dnsowner = DnsOwner.DnsOwner(self._db)
        policy = PolicyComponent(self._db)
        update_helper = IntegrityHelper.Updater(self._db)
        for row in ent.list_traits(code=self.const.trait_project_host,
                                   target_id=self.entity_id):
            # TODO: Could we instead update the Subnet classes to use
            # Factory.get('Entity'), and make use of EntityTrait there to
            # handle this?
            owner_id = row['entity_id']
            ent.clear()
            ent.find(owner_id)
            ent.delete_trait(row['code'])
            ent.write_db()
            # Remove the links to policies if hostpolicy is used
            for prow in policy.search_hostpolicies(dns_owner_id=owner_id):
                policy.clear()
                policy.find(prow['policy_id'])
                policy.remove_from_host(owner_id)
            # delete the DNS owner
            update_helper.full_remove_dns_owner(owner_id)
        # Delete all subnets
        subnet = Subnet.Subnet(self._db)
        subnet6 = IPv6Subnet.IPv6Subnet(self._db)
        for row in ent.list_traits(code=(self.const.trait_project_subnet6,
                                         self.const.trait_project_subnet),
                                   target_id=self.entity_id):
            ent.clear()
            ent.find(row['entity_id'])
            ent.delete_trait(row['code'])
            ent.write_db()
            if row['code'] == self.const.trait_project_subnet:
                subnet.clear()
                subnet.find(row['entity_id'])
                subnet.delete()
            if row['code'] == self.const.trait_project_subnet6:
                subnet6.clear()
                subnet6.find(row['entity_id'])
                subnet6.delete()
        # Remove all data from the OU except for:
        # The project ID and project name
        for tr in tuple(self.get_traits()):
            self.delete_trait(tr)
        for row in self.get_spread():
            self.delete_spread(row['spread'])
        for row in self.get_contact_info():
            self.delete_contact_info(row['source_system'],
                                     row['contact_type'])
        for row in self.get_entity_address():
            self.delete_entity_address(row['source_system'],
                                       row['address_type'])
        for row in self.search_name_with_language(entity_id=self.entity_id):
            # The project name must not be removed, to avoid reuse
            if row['name_variant'] == self.const.ou_name_acronym:
                continue
            self.delete_name_with_language(row['name_variant'])
        self.write_db()
Пример #18
0
class VirtHomeMiscConstants(Constants):
    """Miscellaneous VH constants.
    """

    virtaccount_type = Constants.Account("virtaccount",
                                         "Non-federated account in VirtHome")

    fedaccount_type = Constants.Account("fedaccount",
                                        "Federated account in VirtHome")

    system_virthome = Constants.AuthoritativeSystem('VH', "VirtHome")

    virthome_contact_email = Constants.ContactInfo(
        "VH-MAIL", "VirtHome accounts' e-mail address")

    human_first_name = Constants.ContactInfo(
        "HUMANFIRST", "VA/FA's human owner's first name")
    human_last_name = Constants.ContactInfo("HUMANLAST",
                                            "VA/FA's human owner's last name")
    human_full_name = Constants.ContactInfo("HUMANFULL",
                                            "VA/FA's human owner's full name")

    virthome_group_url = Constants.ContactInfo(
        "VH-GROUP-URL", "Group resource url in VirtHome")

    #
    # Bofhd requests
    #####
    va_pending_create = ChangeType(
        'e_account', 'pending_create',
        'waiting for creation confirmation on %(subject)s')

    va_email_change = ChangeType(
        'e_account', 'pending_email',
        'waiting for e-mail change confirmation on %(subject)s')

    va_group_invitation = ChangeType('e_group', 'pending_invitation',
                                     'issued invitation to join group')

    va_group_owner_swap = ChangeType('e_group', 'pending_owner_change',
                                     'waiting for a group owner change')

    va_group_moderator_add = ChangeType('e_group', 'pending_moderator_add',
                                        'waiting for a new group moderator')

    va_password_recover = ChangeType('e_account', 'password_recover',
                                     'a pending password recovery request')

    va_reset_expire_date = ChangeType(
        'e_account', 'reset_expire_date',
        "push VA/FA's expire date into the future")

    #
    # Various spreads ...
    spread_ldap_group = SpreadCode('group@ldap', Constants.entity_group,
                                   'Group is exported to LDAP')

    spread_ldap_account = SpreadCode('account@ldap', Constants.entity_account,
                                     'Account is exported to LDAP')

    #
    # Various quarantines ...
    quarantine_autopassword = QuarantineCode("autopassword",
                                             "Password is too old")
    quarantine_nologin = QuarantineCode("nologin", "Login not allowed")
    quarantine_pending = QuarantineCode("pending",
                                        "Account is pending confirmation")
    quarantine_disabled = QuarantineCode("disabled", "Account is disabled")

    trait_user_eula = EntityTrait("user_eula", Constants.entity_account,
                                  "Account acknowledged user EULA")

    trait_group_eula = EntityTrait("group_eula", Constants.entity_account,
                                   "Account acknowledged group EULA")

    trait_user_invited = EntityTrait(
        "user_invited", Constants.entity_account,
        "Account has been explicitly invited to join a group")

    trait_group_forward = EntityTrait(
        "group_forward", Constants.entity_group,
        "Redirect URL to use when a new member joins a group.")

    trait_user_retained = EntityTrait(
        "user_retained", Constants.entity_account,
        "Account have been retained from LDAP export.")

    trait_user_notified = EntityTrait(
        "user_notified", Constants.entity_account,
        """Account owner have been emailed (about
                                      LDAP export) """)
Пример #19
0
    def terminate(self):
        """Remove all of a project, except its project ID and name (acronym).

        The project's entities are deleted by this method, so use with care!

        For the OU object, it does almost the same as L{delete} except from
        deleting the entity itself.
        """
        self.write_db()
        ent = EntityTrait(self._db)
        ac = Factory.get('Account')(self._db)
        pu = Factory.get('PosixUser')(self._db)
        # Delete PosixUsers
        for row in ac.list_accounts_by_type(ou_id=self.entity_id,
                                            filter_expired=False):
            try:
                pu.clear()
                pu.find(row['account_id'])
                pu.delete_posixuser()
            except Errors.NotFoundError:
                # not a PosixUser
                continue
        # Remove all project's groups
        gr = Factory.get('Group')(self._db)
        for row in gr.list_traits(code=self.const.trait_project_group,
                                  target_id=self.entity_id):
            gr.clear()
            gr.find(row['entity_id'])
            gr.delete()
        # Delete all users
        for row in ac.list_accounts_by_type(ou_id=self.entity_id):
            ac.clear()
            ac.find(row['account_id'])
            ac.delete()
        # Remove every trace of person affiliations to the project:
        pe = Factory.get('Person')(self._db)
        for row in pe.list_affiliations(ou_id=self.entity_id,
                                        include_deleted=True):
            pe.clear()
            pe.find(row['person_id'])
            pe.nuke_affiliation(ou_id=row['ou_id'],
                                affiliation=row['affiliation'],
                                source=row['source_system'],
                                status=row['status'])
            pe.write_db()
        # Remove all project's DnsOwners (hosts):
        dnsowner = dns.DnsOwner.DnsOwner(self._db)
        policy = PolicyComponent(self._db)
        update_helper = dns.IntegrityHelper.Updater(self._db)
        for row in ent.list_traits(code=self.const.trait_project_host,
                                   target_id=self.entity_id):
            # TODO: Could we instead update the Subnet classes to use
            # Factory.get('Entity'), and make use of EntityTrait there to
            # handle this?
            owner_id = row['entity_id']
            ent.clear()
            ent.find(owner_id)
            ent.delete_trait(row['code'])
            ent.write_db()
            # Remove the links to policies if hostpolicy is used
            for prow in policy.search_hostpolicies(dns_owner_id=owner_id):
                policy.clear()
                policy.find(prow['policy_id'])
                policy.remove_from_host(owner_id)
            # delete the DNS owner
            update_helper.full_remove_dns_owner(owner_id)
        # Delete all subnets
        subnet = dns.Subnet.Subnet(self._db)
        subnet6 = dns.IPv6Subnet.IPv6Subnet(self._db)
        for row in ent.list_traits(code=(self.const.trait_project_subnet6,
                                         self.const.trait_project_subnet),
                                   target_id=self.entity_id):
            ent.clear()
            ent.find(row['entity_id'])
            ent.delete_trait(row['code'])
            ent.write_db()
            if row['code'] == self.const.trait_project_subnet:
                subnet.clear()
                subnet.find(row['entity_id'])
                subnet.delete()
            if row['code'] == self.const.trait_project_subnet6:
                subnet6.clear()
                subnet6.find(row['entity_id'])
                subnet6.delete()
        # Remove all data from the OU except for:
        # The project ID and project name
        for tr in tuple(self.get_traits()):
            self.delete_trait(tr)
        for row in self.get_spread():
            self.delete_spread(row['spread'])
        for row in self.get_contact_info():
            self.delete_contact_info(row['source_system'],
                                     row['contact_type'])
        for row in self.get_entity_address():
            self.delete_entity_address(row['source_system'],
                                       row['address_type'])
        for row in self.search_name_with_language(entity_id=self.entity_id):
            # The project name must not be removed, to avoid reuse
            if row['name_variant'] == self.const.ou_name_acronym:
                continue
            self.delete_name_with_language(row['name_variant'])
        self.write_db()