Пример #1
0
class IntegrationTest(UnitTest):
    """Base class for integration tests.

    Integration tests run with a connected client to the API, which is
    available under the "client" property.
    """

    pubkey = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDi3GUFtZA4WxysevYPPrp3G4' \
             'W3sehLJOyEp4vf5G/rLfoKwz1JXd3gqq8snoSwYefQSAW0PKPff6lxyaraFqq4' \
             '+vzNg4rAHJSdBhAHLWlcNWSh8UZOGD11vgGdOLrDBPZ8/jKJIZgcFiXjzulMzU' \
             'RKLGx0ZFbUZDfHYIqEpCscnlfG6kenrtWAdCrTkl4CP56xcOY91qx4s9Ll0Yvz' \
             'hyF2GiqgCe0eJqNflJkqX+d9e0A3BdIzM//UfYplzmUGimWgGN4vFFa4sspUzq' \
             'gwHV7yZYI7W+Ey5oOOiSpTt1PpkPHIBaUEmg37/7Pq6PuQxfs18QLPK1DuJz6g' \
             'UsCjFRFl testkey'

    def setUp(self):
        url = self.config.get('integration', 'url') or None
        username = self.config.get('integration', 'username')
        password = self.config.get('integration', 'password')
        self.client = RavelloClient()
        self.client.connect(url)
        self.client.login(username, password)

    def tearDown(self):
        self.client.logout()
        self.client.close()
Пример #2
0
class IntegrationTest(UnitTest):
    """Base class for integration tests.

    Integration tests run with a connected client to the API, which is
    available under the "client" property.
    """

    pubkey = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDi3GUFtZA4WxysevYPPrp3G4' \
             'W3sehLJOyEp4vf5G/rLfoKwz1JXd3gqq8snoSwYefQSAW0PKPff6lxyaraFqq4' \
             '+vzNg4rAHJSdBhAHLWlcNWSh8UZOGD11vgGdOLrDBPZ8/jKJIZgcFiXjzulMzU' \
             'RKLGx0ZFbUZDfHYIqEpCscnlfG6kenrtWAdCrTkl4CP56xcOY91qx4s9Ll0Yvz' \
             'hyF2GiqgCe0eJqNflJkqX+d9e0A3BdIzM//UfYplzmUGimWgGN4vFFa4sspUzq' \
             'gwHV7yZYI7W+Ey5oOOiSpTt1PpkPHIBaUEmg37/7Pq6PuQxfs18QLPK1DuJz6g' \
             'UsCjFRFl testkey'

    def setUp(self):
        url = self.config.get('integration', 'url') or None
        username = self.config.get('integration', 'username')
        password = self.config.get('integration', 'password')
        self.client = RavelloClient()
        self.client.connect(url)
        self.client.login(username, password)

    def tearDown(self):
        self.client.logout()
        self.client.close()
Пример #3
0
class RavelloBmc(bmc.Bmc):
    """Ravello IPMI virtual BMC."""
    def get_vm(self, application, name):
        """Get a VM by name."""
        vms = application.get(self._aspect, {}).get('vms', [])
        for vm in vms:
            if vm['name'] == name:
                return vm

        msg = 'vm not found: {0}'.format(name)
        logging.error(msg)
        raise ValueError(msg)

    def connect(self):
        """Connect to the Ravello API server with the given credentials."""
        try:
            self._client = RavelloClient()
            #self._client.login(self._username, self._password)
            self._client = RavelloClient(eph_token=self._password)
            c = self._client
            self._app = c.get_application_by_name(self._app_name,
                                                  aspect=self._aspect)
            self._vm = self.get_vm(self._app, self._vm_name)
            return True
        except Exception as e:
            msg = "Exception while connecting to API server:" + str(e)
            logging.error(msg)
            print(msg)
            return False

    def __init__(self, authdata, port, address, aspect, username, password,
                 app_name, vm_name):
        """Ravello virtual BMC constructor."""
        self._client = None
        super(RavelloBmc, self).__init__(authdata, address=address, port=port)
        self._aspect = aspect
        self._username = username
        self._password = password
        self._app_name = app_name
        self._vm_name = vm_name

    def disconnect(self):
        """Disconnect from the Ravello API server."""
        if not self._client:
            return

        self._client.logout()
        self._client.close()

    def __del__(self):
        """Ravello virtual BMC destructor."""
        self.disconnect()

    # Disable default BMC server implementations

    def cold_reset(self):
        """Cold reset reset the BMC so it's not implemented."""
        raise NotImplementedError

    def get_boot_device(self):
        """Get the boot device of a Ravello VM."""

        try:
            # query the vm again to have an updated device
            c = self._client
            self._app = c.get_application_by_name(self._app_name,
                                                  aspect=self._aspect)
            self._vm = self.get_vm(self._app, self._vm_name)

            if self._vm['bootOrder'][0] == "DISK":
                return 0x08
            elif self._vm['bootOrder'][0] == "CDROM":
                return 0x04
        except Exception as e:
            logging.error(self._vm_name + ' get_boot_device:' + str(e))
            return 0xce

        return 0x04

    def get_system_boot_options(self, request, session):
        logging.info(self._vm_name + " get boot options")
        if request['data'][0] == 5:  # boot flags
            try:
                bootdevice = self.get_boot_device()
                logging.info(self._vm_name + ' bootdevice = ' + bootdevice)
            except NotImplementedError:
                session.send_ipmi_response(data=[1, 5, 0, 0, 0, 0, 0])
            if (type(bootdevice) != int
                    and bootdevice in ipmicommand.boot_devices):
                bootdevice = ipmicommand.boot_devices[bootdevice]
            paramdata = [1, 5, 0b10000000, bootdevice, 0, 0, 0]
            return session.send_ipmi_response(data=paramdata)
        else:
            session.send_ipmi_response(code=0x80)

    def set_boot_device(self, bootdevice):
        try:
            # query the vm again to have an updated device
            c = self._client
            self._app = c.get_application_by_name(self._app_name)
            appid = self._app['id']
            for vm in self._app['design']['vms']:
                change = False
                if vm['name'] == self._vm_name:
                    logging.info(self._vm_name + " Boot device requested: " +
                                 str(bootdevice))
                    if bootdevice == "network":
                        vm['bootOrder'] = ["CDROM", "DISK"]
                        change = True
                    elif bootdevice == "hd":
                        vm['bootOrder'] = ["DISK", "CDROM"]
                        change = True
                if change == True:
                    #pprint (self._app)
                    logging.info("Updating app " + self._app_name + " vm " +
                                 self._vm_name + " with boot device " +
                                 str(bootdevice))
                    ap = self._client.update_application(self._app)
                    if ap['published']:
                        logging.info("Updating app " + str(appid))
                        self._client.publish_application_updates(appid)
        except Exception as e:
            logging.error(self._vm_name + ' set_boot_device:' + str(e))
            return 0xce

    def set_kg(self, kg):
        """Desactivated IPMI call."""
        raise NotImplementedError

    def set_system_boot_options(self, request, session):
        logging.info("set boot options vm:" + self._vm_name)
        if request['data'][0] in (0, 3, 4):
            logging.info("Ignored RAW option " + str(request['data']) +
                         " for: " + self._vm_name + "... Smile and wave.")
            # for now, just smile and nod at boot flag bit clearing
            # implementing it is a burden and implementing it does more to
            # confuse users than serve a useful purpose
            session.send_ipmi_response(code=0x00)
        elif request['data'][0] == 5:
            bootdevice = (request['data'][2] >> 2) & 0b1111
            logging.info("Got set boot device for " + self._vm_name + " to " +
                         str(request['data'][2]))
            try:
                bootdevice = ipmicommand.boot_devices[bootdevice]
                logging.info("Setting boot device for " + self._vm_name +
                             " to " + bootdevice)
            except KeyError:
                session.send_ipmi_response(code=0xcc)
                return
            self.set_boot_device(bootdevice)
            session.send_ipmi_response()
        else:
            raise NotImplementedError

    def power_reset(self):
        """Reset a VM."""
        # Shmulik wrote "Currently, limited to: "chassis power on/off/status"
        raise NotImplementedError

    # Implement power state BMC features
    def get_power_state(self):
        """Get the power state of a Ravello VM."""

        try:
            # query the vm again to have an updated status
            c = self._client
            self._app = c.get_application_by_name(self._app_name,
                                                  aspect=self._aspect)
            self._vm = self.get_vm(self._app, self._vm_name)

            if self._vm['state'] == 'STARTED' or self._vm[
                    'state'] == 'STARTING' or self._vm['state'] == 'STOPPING':
                logging.info('returning power state ON for vm ' +
                             self._vm_name)
                return "on"
            else:
                logging.info('returning power state OFF for vm ' +
                             self._vm_name)
                return "off"

        except Exception as e:
            logging.error(self._vm_name + ' get_power_state:' + str(e))
            return 0xce

        return "off"

    def power_off(self):
        """Cut the power without waiting for clean shutdown."""
        logging.info("Power OFF called for VM " + self._vm_name +
                     " with state: " + self._vm['state'])
        # query the vm again to have an updated status
        c = self._client
        self._app = c.get_application_by_name(self._app_name,
                                              aspect=self._aspect)
        self._vm = self.get_vm(self._app, self._vm_name)
        if self._vm['state'] == 'STARTED':
            try:
                #self._client.poweroff_vm(self._app, self._vm)
                self._client.stop_vm(self._app, self._vm)
            except Exception as e:
                logging.error(self._vm_name + ' power_off:' + str(e))
                return 0xce
        elif self._vm['state'] == 'STOPPING' or self._vm['state'] == 'STARTING':
            return 0xc0
        else:
            return 0xce

    def power_on(self):
        """Start a vm."""
        logging.info("Power ON called for VM " + self._vm_name +
                     " with state: " + self._vm['state'])
        # query the vm again to have an updated status
        c = self._client
        self._app = c.get_application_by_name(self._app_name,
                                              aspect=self._aspect)
        self._vm = self.get_vm(self._app, self._vm_name)
        if self._vm['state'] == 'STOPPED':
            try:
                self._client.start_vm(self._app, self._vm)
            except Exception as e:
                logging.error(self._vm_name + ' power_on:' + str(e))
                return 0xce
        elif self._vm['state'] == 'STOPPING' or self._vm['state'] == 'STARTING':
            return 0xc0
        else:
            return 0xce

    def power_shutdown(self):
        """Gently power off while waiting for clean shutdown."""
        logging.info("Power SHUTDOWN called for VM " + self._vm_name +
                     " with state: " + self._vm['state'])
        # query the vm again to have an updated status
        c = self._client
        self._app = c.get_application_by_name(self._app_name,
                                              aspect=self._aspect)
        self._vm = self.get_vm(self._app, self._vm_name)
        if self._vm['state'] == 'STARTED':
            try:
                self._client.stop_vm(self._app, self._vm)
            except Exception as e:
                logging.error(self._vm_name + ' power_shutdown:' + str(e))
                return 0xce
        elif self._vm['state'] == 'STOPPING' or self._vm['state'] == 'STARTING':
            return 0xc0
        else:
            return 0xce