def test_updateHardwareProfileTags(dbm):
    api = HardwareProfileDbApi()
    tags = {'tag1': 'tag1 value', 'tag2': 'tag2 value'}

    with dbm.session() as session:
        hwprofile = api.getHardwareProfile(session, 'notags')

        #
        # Set tags
        #
        hwprofile.setTags({'tag1': 'tag1 value', 'tag2': 'tag2 value'})
        api.updateHardwareProfile(session, hwprofile)
        session.commit()
        hwprofile = api.getHardwareProfile(session, 'notags')
        assert hwprofile.getTags() == tags

        #
        # Remove tags
        #
        hwprofile.setTags({})
        api.updateHardwareProfile(session, hwprofile)
        session.commit()
        hwprofile = api.getHardwareProfile(session, 'notags')
        assert hwprofile.getTags() == {}
Exemple #2
0
class UctagCli(TortugaCli):
    def __init__(self, *args, **kwargs):
        self._hwp_api = HardwareProfileDbApi()
        self._node_api = NodeDbApi()
        self._swp_api = SoftwareProfileDbApi()
        super().__init__(*args, **kwargs)

    def parseArgs(self, usage: Optional[str] = None):
        subparsers = self.getParser().add_subparsers(help='sub-command help',
                                                     dest='subparser_name')

        add_subparser = subparsers.add_parser('add')
        add_subparser.add_argument('--node', dest='nodespec')
        add_subparser.add_argument('--software-profile', metavar='NAME')
        add_subparser.add_argument('--hardware-profile', metavar='NAME')
        add_subparser.add_argument('--tags',
                                   action='append',
                                   dest='tags',
                                   metavar='key=value[,key=value]')
        add_subparser.set_defaults(func=self.add_tag)

        remove_subparser = subparsers.add_parser('remove')
        remove_subparser.add_argument('--node', dest='nodespec')
        remove_subparser.add_argument('--software-profile', metavar='NAME')
        remove_subparser.add_argument('--hardware-profile', metavar='NAME')
        remove_subparser.add_argument('--tags',
                                      action='append',
                                      dest='tags',
                                      metavar='key[,key]')
        remove_subparser.set_defaults(func=self.remove_tag)

        list_subparser = subparsers.add_parser('list')
        list_subparser.add_argument('--all-resources', action='store_true')
        list_subparser.add_argument('--nodes', action='store_true')
        list_subparser.add_argument('--software-profiles', action='store_true')
        list_subparser.add_argument('--hardware-profiles', action='store_true')
        list_subparser.set_defaults(func=self.list_tag)

        return super().parseArgs(usage=usage)

    def runCommand(self):
        args = self.parseArgs()

        with DbManager().session() as session:
            args.func(session, args)

    def add_tag(self, session: Session, args):
        if not args.nodespec and not args.software_profile and \
                not args.hardware_profile:
            sys.stderr.write('Error: must specify --nodes'
                             '/--software-profile/--hardware-profile\n')
            sys.stderr.flush()
            sys.exit(1)

        tags = parse_tags(args.tags)

        if args.nodespec:
            nodes = self._node_api.getNodesByNameFilter(session, args.nodespec)
            for node in nodes:
                node_tags = node.getTags()
                node_tags.update(tags)
                self._node_api.set_tags(session,
                                        node_id=node.getId(),
                                        tags=node_tags)
                print(node.getName(), node.getTags())

        if args.software_profile:
            for name in args.software_profile.split(','):
                swp = self._swp_api.getSoftwareProfile(session, name)
                swp_tags = swp.getTags()
                swp_tags.update(tags)
                swp.setTags(swp_tags)
                self._swp_api.updateSoftwareProfile(session, swp)

        if args.hardware_profile:
            for name in args.hardware_profile.split(','):
                hwp = self._hwp_api.getHardwareProfile(session, name)
                hwp_tags = hwp.getTags()
                hwp_tags.update(tags)
                hwp.setTags(hwp_tags)
                self._hwp_api.updateHardwareProfile(session, hwp)

        session.commit()

    def remove_tag(self, session: Session, args):
        if not args.nodespec and not args.software_profile and \
                not args.hardware_profile:
            sys.stderr.write('Error: must specify --nodes'
                             '/--software-profile/--hardware-profile\n')
            sys.stderr.flush()
            sys.exit(1)

        tag_keys = []
        for tag_string in args.tags:
            tag_keys.extend(tag_string.split(','))

        if args.nodespec:
            nodes = self._node_api.getNodesByNameFilter(session, args.nodespec)
            for node in nodes:
                node_tags = node.getTags()
                for key in tag_keys:
                    if key in node_tags.keys():
                        node_tags.pop(key)
                self._node_api.set_tags(session,
                                        node_id=node.getId(),
                                        tags=node_tags)
                print(node.getName(), node.getTags())

        if args.software_profile:
            for name in args.software_profile.split(','):
                swp = self._swp_api.getSoftwareProfile(session, name)
                swp_tags = swp.getTags()
                for key in tag_keys:
                    if key in swp_tags.keys():
                        swp_tags.pop(key)
                swp.setTags(swp_tags)
                self._swp_api.updateSoftwareProfile(session, swp)

        if args.hardware_profile:
            for name in args.hardware_profile.split(','):
                hwp = self._hwp_api.getHardwareProfile(session, name)
                hwp_tags = hwp.getTags()
                for key in tag_keys:
                    if key in hwp_tags.keys():
                        hwp_tags.pop(key)
                hwp.setTags(hwp_tags)
                self._hwp_api.updateHardwareProfile(session, hwp)

        session.commit()

    def list_tag(self, session: Session, args):
        report = TagReport()

        if args.all_resources or args.nodes:
            for node in self._node_api.getNodeList(session):
                for key, value in node.getTags().items():
                    report.add_node(key, value, node)

        if args.all_resources or args.software_profiles:
            for swp in self._swp_api.getSoftwareProfileList(session):
                for key, value in swp.getTags().items():
                    report.add_swp(key, value, swp)

        if args.all_resources or args.hardware_profiles:
            for hwp in self._hwp_api.getHardwareProfileList(session):
                for key, value in hwp.getTags().items():
                    report.add_hwp(key, value, hwp)

        for key, values in report.keys.items():
            for value, types in values.items():
                print('{} = {}:'.format(key, value))
                for type_, names in types.items():
                    print('  {}:'.format(type_))
                    for name in names:
                        print('    - {}'.format(name))
class HardwareProfileManager(TortugaObjectManager, Singleton):
    def __init__(self):
        super(HardwareProfileManager, self).__init__()

        self._hpDbApi = HardwareProfileDbApi()
        self._spDbApi = SoftwareProfileDbApi()
        self._networkDbApi = NetworkDbApi()
        self._globalParameterDbApi = GlobalParameterDbApi()
        self._nodeDbApi = NodeDbApi()

    def getHardwareProfileList(self, optionDict=None, tags=None):
        """
        Return all of the hardwareprofiles with referenced components
        in this hardwareprofile
        """

        return self._hpDbApi.getHardwareProfileList(optionDict=optionDict,
                                                    tags=tags)

    def setIdleSoftwareProfile(self,
                               hardwareProfileName,
                               softwareProfileName=None):
        """Set idle software profile"""

        return self._hpDbApi.setIdleSoftwareProfile(hardwareProfileName,
                                                    softwareProfileName)

    def getHardwareProfile(self, name, optionDict=None):
        return self._hpDbApi.getHardwareProfile(name, optionDict or {})

    def getHardwareProfileById(self, id_, optionDict=None):
        return self._hpDbApi.getHardwareProfileById(id_, optionDict or {})

    def addAdmin(self, hardwareProfileName, adminUsername):
        """
        Add an admin as an authorized user.

            Returns:
                None
            Throws:
                TortugaException
                AdminNotFound
                HardwareProfileNotFound
        """

        return self._hpDbApi.addAdmin(hardwareProfileName, adminUsername)

    def deleteAdmin(self, hardwareProfileName, adminUsername):
        """
        Remove an admin as an authorized user.

            Returns:
                None
            Throws:
                TortugaException
                AdminNotFound
                HardwareProfileNotFound
        """

        return self._hpDbApi.deleteAdmin(hardwareProfileName, adminUsername)

    def updateHardwareProfile(self, hardwareProfileObject):
        """
        Update a hardware profile in the database that matches the passed
        in hardware profile object.  The ID is used as the primary matching
        criteria.

            Returns:
                None
            Throws:
                TortugaException
                HardwareProfileNotFound
                InvalidArgument

        """

        self.getLogger().debug('Updating hardware profile [%s]' %
                               (hardwareProfileObject.getName()))

        try:
            # First get the object from the db we are updating...
            existingProfile = self.\
                getHardwareProfileById(hardwareProfileObject.getId())

            if hardwareProfileObject.getInstallType() and \
                hardwareProfileObject.getInstallType() != \
                    existingProfile.getInstallType():
                raise InvalidArgument(
                    'Hardware profile installation type cannot be'
                    ' changed' % (hardwareProfileObject.getName()))

            self._hpDbApi.updateHardwareProfile(hardwareProfileObject)
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % ex)
            raise TortugaException(exception=ex)

    def createHardwareProfile(self, hwProfileSpec, settingsDict=None):
        settingsDict = settingsDict or {}

        bUseDefaults = settingsDict['bUseDefaults'] \
            if 'bUseDefaults' in settingsDict else False

        osInfo = settingsDict['osInfo'] \
            if settingsDict and 'osInfo' in settingsDict else None

        validation.validateProfileName(hwProfileSpec.getName())

        if hwProfileSpec.getDescription() is None or \
                hwProfileSpec.getDescription() == '**DEFAULT**':
            hwProfileSpec.setDescription('%s Nodes' %
                                         (hwProfileSpec.getName()))

        installerNode = self._nodeDbApi.getNode(ConfigManager().getInstaller(),
                                                {'softwareprofile': True})

        if bUseDefaults:
            if not hwProfileSpec.getNetworks():
                # No <network>...</network> entries found in the template,
                # use the default provisioning interface from the primary
                # installer.

                # Find first provisioning network and use it
                for nic in installerNode.getNics():
                    network = nic.getNetwork()
                    if network.getType() == 'provision':
                        # for now set the default interface to be index 0
                        # with the same device
                        networkDevice = fixNetworkDeviceName(
                            nic.getNetworkDevice().getName())

                        network.setNetworkDevice(
                            NetworkDevice(name=networkDevice))

                        hwProfileSpec.getNetworks().append(network)

                        break
                else:
                    raise NetworkNotFound(
                        'Unable to find provisioning network')
            else:
                # Ensure network device is defined
                installerNic = None

                for network in hwProfileSpec.getNetworks():
                    for installerNic in installerNode.getNics():
                        installerNetwork = installerNic.getNetwork()

                        if network.getId() and \
                           network.getId() == installerNetwork.getId():
                            break
                        elif network.getAddress() and \
                            network.getAddress() == \
                            installerNetwork.getAddress() and \
                            network.getNetmask() and \
                            network.getNetmask() == \
                                installerNetwork.getNetmask():
                            break
                    else:
                        # Unable to find network matching specification in
                        # template.

                        raise NetworkNotFound(
                            'Unable to find provisioning network [%s]' %
                            (network))

                    networkDevice = fixNetworkDeviceName(
                        installerNic.getNetworkDevice().getName())

                    network.setNetworkDevice(NetworkDevice(name=networkDevice))

        if hwProfileSpec.getIdleSoftwareProfile():
            # <idleSoftwareProfileId>...</idleSoftwareProfileId> is always
            # contained within the output of get-hardwareprofile.  If the
            # command-line option '--idleSoftwareProfile' is specified, it
            # overrides the
            # <idleSoftwareProfileId>...</idleSoftwareProfileId> element
            idleSoftwareProfile = self._spDbApi.getSoftwareProfile(
                hwProfileSpec.getIdleSoftwareProfile().getName())

            hwProfileSpec.setIdleSoftwareProfileId(idleSoftwareProfile.getId())

        if not osInfo:
            osInfo = installerNode.getSoftwareProfile().getOsInfo()

        osObjFactory = osUtility.getOsObjectFactory(osInfo.getName())

        if not hwProfileSpec.getKernel():
            hwProfileSpec.setKernel(
                osObjFactory.getOsSysManager().getKernel(osInfo))

        if not hwProfileSpec.getInitrd():
            hwProfileSpec.setInitrd(
                osObjFactory.getOsSysManager().getInitrd(osInfo))

        self._hpDbApi.addHardwareProfile(hwProfileSpec)

        # Iterate over all networks in the newly defined hardware profile
        # and build assocations to provisioning NICs
        if bUseDefaults:
            for network in \
                [network for network in hwProfileSpec.getNetworks()
                 if network.getType() == 'provision']:
                # Get provisioning nic for network
                try:
                    provisioningNic = self.getProvisioningNicForNetwork(
                        network.getAddress(), network.getNetmask())
                except NicNotFound:
                    # There is currently no provisioning NIC defined for
                    # this network.  This is not a fatal error.
                    continue

                self.setProvisioningNic(hwProfileSpec.getName(),
                                        provisioningNic.getId())

    def deleteHardwareProfile(self, name):
        """Delete hardwareprofile by name."""

        self._hpDbApi.deleteHardwareProfile(name)

        self.getLogger().info('Deleted hardware profile [%s]' % (name))

    def updateSoftwareOverrideAllowed(self, hardwareProfileName, flag):
        self._hpDbApi.updateSoftwareOverrideAllowed(hardwareProfileName, flag)

    def getHypervisorNodes(self, hardwareProfileName):
        return self._hpDbApi.getHypervisorNodes(hardwareProfileName)

    def setProvisioningNic(self, hardwareProfileName, nicId):
        return self._hpDbApi.setProvisioningNic(hardwareProfileName, nicId)

    def getProvisioningNicForNetwork(self, network, netmask):
        return self._hpDbApi.getProvisioningNicForNetwork(network, netmask)

    def copyHardwareProfile(self, srcHardwareProfileName,
                            dstHardwareProfileName):
        validation.validateProfileName(dstHardwareProfileName)

        self.getLogger().info('Copying hardware profile [%s] to [%s]' %
                              (srcHardwareProfileName, dstHardwareProfileName))

        return self._hpDbApi.copyHardwareProfile(srcHardwareProfileName,
                                                 dstHardwareProfileName)

    def getNodeList(self, hardwareProfileName):
        return self._hpDbApi.getNodeList(hardwareProfileName)
Exemple #4
0
class HardwareProfileManager(TortugaObjectManager):
    def __init__(self):
        super(HardwareProfileManager, self).__init__()

        self._hpDbApi = HardwareProfileDbApi()
        self._spDbApi = SoftwareProfileDbApi()
        self._networkDbApi = NetworkDbApi()
        self._globalParameterDbApi = GlobalParameterDbApi()
        self._nodeDbApi = NodeDbApi()
        self._logger = logging.getLogger(HARDWARE_PROFILE_NAMESPACE)

    def getHardwareProfileList(self,
                               session: Session,
                               optionDict: Optional[Union[Dict[str, str],
                                                          None]] = None,
                               tags: Optional[Tags] = None):
        """
        Return all of the hardwareprofiles with referenced components
        in this hardwareprofile
        """

        return self._hpDbApi.getHardwareProfileList(session,
                                                    optionDict=optionDict,
                                                    tags=tags)

    def getHardwareProfile(self,
                           session: Session,
                           name: str,
                           optionDict: Optional[Union[dict, None]] = None):
        return self._hpDbApi.getHardwareProfile(session, name, optionDict)

    def getHardwareProfileById(self, session: Session, id_, optionDict=None):
        return self._hpDbApi.getHardwareProfileById(session, id_, optionDict)

    def addAdmin(self, session: Session, hardwareProfileName: str,
                 adminUsername: str):
        """
        Add an admin as an authorized user.

            Returns:
                None
            Throws:
                TortugaException
                AdminNotFound
                HardwareProfileNotFound
        """

        return self._hpDbApi.addAdmin(session, hardwareProfileName,
                                      adminUsername)

    def deleteAdmin(self, session: Session, hardwareProfileName: str,
                    adminUsername: str):
        """
        Remove an admin as an authorized user.

            Returns:
                None
            Throws:
                TortugaException
                AdminNotFound
                HardwareProfileNotFound
        """

        return self._hpDbApi.deleteAdmin(session, hardwareProfileName,
                                         adminUsername)

    def updateHardwareProfile(self, session: Session,
                              hardwareProfileObject: Any):
        """
        Update a hardware profile in the database that matches the passed
        in hardware profile object.  The ID is used as the primary matching
        criteria.

            Returns:
                None
            Throws:
                TortugaException
                HardwareProfileNotFound
                InvalidArgument

        """

        self._logger.debug('Updating hardware profile [%s]' %
                           (hardwareProfileObject.getName()))

        existing_hwp = self.getHardwareProfileById(
            session, hardwareProfileObject.getId())
        if hardwareProfileObject.getInstallType() and \
            hardwareProfileObject.getInstallType() != \
                existing_hwp.getInstallType():
            raise InvalidArgument(
                'Hardware profile installation type cannot be'
                ' changed' % (hardwareProfileObject.getName()))
        self._hpDbApi.updateHardwareProfile(session, hardwareProfileObject)

        #
        # Get the new version from the DB
        #
        new_hwp = self.getHardwareProfileById(session,
                                              hardwareProfileObject.getId())
        #
        # If the tags have changed, fire the tags changed event
        #
        if existing_hwp.getTags() != new_hwp.getTags():
            HardwareProfileTagsChanged.fire(
                hardwareprofile_id=str(new_hwp.getId()),
                hardwareprofile_name=new_hwp.getName(),
                tags=new_hwp.getTags(),
                previous_tags=existing_hwp.getTags())

    def createHardwareProfile(self,
                              session: Session,
                              hwProfileSpec: HardwareProfile,
                              settingsDict: Optional[Union[dict,
                                                           None]] = None):
        bUseDefaults = settingsDict['defaults'] \
            if settingsDict and 'defaults' in settingsDict else False

        osInfo = settingsDict['osInfo'] \
            if settingsDict and \
            settingsDict and 'osInfo' in settingsDict else None

        validation.validateProfileName(hwProfileSpec.getName())

        if hwProfileSpec.getDescription() is None:
            hwProfileSpec.setDescription('%s Nodes' %
                                         (hwProfileSpec.getName()))

        installerNode = self._nodeDbApi.getNode(session,
                                                ConfigManager().getInstaller(),
                                                {'softwareprofile': True})

        if bUseDefaults:
            if not hwProfileSpec.getNetworks():
                # No <network>...</network> entries found in the template,
                # use the default provisioning interface from the primary
                # installer.

                # Find first provisioning network and use it
                for nic in installerNode.getNics():
                    network = nic.getNetwork()
                    if network.getType() == 'provision':
                        # for now set the default interface to be index 0
                        # with the same device
                        networkDevice = fixNetworkDeviceName(
                            nic.getNetworkDevice().getName())

                        network.setNetworkDevice(
                            NetworkDevice(name=networkDevice))

                        hwProfileSpec.getNetworks().append(network)

                        break
                else:
                    raise NetworkNotFound(
                        'Unable to find provisioning network')
            else:
                # Ensure network device is defined
                installerNic = None

                for network in hwProfileSpec.getNetworks():
                    for installerNic in installerNode.getNics():
                        installerNetwork = installerNic.getNetwork()

                        if network.getId() and \
                           network.getId() == installerNetwork.getId():
                            break
                        elif network.getAddress() and \
                            network.getAddress() == \
                            installerNetwork.getAddress() and \
                            network.getNetmask() and \
                            network.getNetmask() == \
                                installerNetwork.getNetmask():
                            break
                    else:
                        # Unable to find network matching specification in
                        # template.

                        raise NetworkNotFound(
                            'Unable to find provisioning network [%s]' %
                            (network))

                    networkDevice = fixNetworkDeviceName(
                        installerNic.getNetworkDevice().getName())

                    network.setNetworkDevice(NetworkDevice(name=networkDevice))

        if not osInfo:
            osInfo = installerNode.getSoftwareProfile().getOsInfo()

        osObjFactory = osUtility.getOsObjectFactory(osInfo.getName())

        if not hwProfileSpec.getKernel():
            hwProfileSpec.setKernel(
                osObjFactory.getOsSysManager().getKernel(osInfo))

        if not hwProfileSpec.getInitrd():
            hwProfileSpec.setInitrd(
                osObjFactory.getOsSysManager().getInitrd(osInfo))

        self._hpDbApi.addHardwareProfile(session, hwProfileSpec)

        # Iterate over all networks in the newly defined hardware profile
        # and build assocations to provisioning NICs
        if bUseDefaults:
            for network in \
                [network for network in hwProfileSpec.getNetworks()
                 if network.getType() == 'provision']:
                # Get provisioning nic for network
                try:
                    provisioningNic = self.getProvisioningNicForNetwork(
                        session, network.getAddress(), network.getNetmask())
                except NicNotFound:
                    # There is currently no provisioning NIC defined for
                    # this network.  This is not a fatal error.
                    continue

                self.setProvisioningNic(session, hwProfileSpec.getName(),
                                        provisioningNic.getId())

        #
        # Fire the tags changed event for all creates that have tags
        #
        # Get the latest version from the db in case the create method
        # added some embellishments
        #
        hwp = self.getHardwareProfile(session, hwProfileSpec.getName())
        if hwp.getTags():
            HardwareProfileTagsChanged.fire(hardwareprofile_id=str(
                hwp.getId()),
                                            hardwareprofile_name=hwp.getName(),
                                            tags=hwp.getTags(),
                                            previous_tags={})

    def deleteHardwareProfile(self, session: Session, name: str) -> None:
        """
        Delete hardwareprofile by name.
        """

        self._hpDbApi.deleteHardwareProfile(session, name)

        self._logger.info('Deleted hardware profile [%s]' % (name))

    def updateSoftwareOverrideAllowed(self, session: Session,
                                      hardwareProfileName: str,
                                      flag: bool) -> None:
        self._hpDbApi.updateSoftwareOverrideAllowed(session,
                                                    hardwareProfileName, flag)

    def setProvisioningNic(self, session: Session, hardwareProfileName: str,
                           nicId: int):
        return self._hpDbApi.setProvisioningNic(session, hardwareProfileName,
                                                nicId)

    def getProvisioningNicForNetwork(self, session: Session, network: str,
                                     netmask: str):
        return self._hpDbApi.getProvisioningNicForNetwork(
            session, network, netmask)

    def copyHardwareProfile(self, session: Session,
                            srcHardwareProfileName: str,
                            dstHardwareProfileName: str):
        validation.validateProfileName(dstHardwareProfileName)
        self._logger.info('Copying hardware profile [%s] to [%s]' %
                          (srcHardwareProfileName, dstHardwareProfileName))
        self._hpDbApi.copyHardwareProfile(session, srcHardwareProfileName,
                                          dstHardwareProfileName)
        #
        # Fire the tags changed event for all copies that have tags
        #
        hwp = self.getHardwareProfile(session, dstHardwareProfileName)
        if hwp.getTags():
            HardwareProfileTagsChanged.fire(hardwareprofile_id=str(
                hwp.getId()),
                                            hardwareprofile_name=hwp.getName(),
                                            tags=hwp.getTags(),
                                            previous_tags={})

    def getNodeList(self, session: Session, hardwareProfileName: str):
        return self._hpDbApi.getNodeList(session, hardwareProfileName)