예제 #1
0
class ScCloudComputingInstanceReinstall:
    def __init__(self, endpoint, token, instance_id, name, region_id, image_id,
                 image_regexp, wait, update_interval, checkmode):
        self.api = ScApi(token, endpoint)
        self.instance = self.api.toolbox.find_instance(instance_id=instance_id,
                                                       instance_name=name,
                                                       region_id=region_id,
                                                       must=True)
        if not image_id and not image_regexp:
            self.image_id = self.instance['image_id']
        else:
            self.image_id = self.api.toolbox.find_image_id(
                image_id=image_id,
                image_regexp=image_regexp,
                region_id=region_id)
        self.wait = wait
        self.update_interval = update_interval
        self.checkmode = checkmode

    #  copypaste, refactor, TODO
    def wait_for_statuses(self, status_done, statuses_continue):
        start_time = time.time()
        if self.wait:
            time.sleep(self.update_interval)  # workaround around bug in APIs
        while self.instance['status'] not in statuses_continue + [status_done]:
            if not self.wait:
                break
            if time.time() > start_time + self.wait:
                raise WaitError(
                    msg=f"Timeout waiting instance {self.instance['id']} "
                    f"status {status_done} or {statuses_continue}. "
                    f"Last state was {self.instance['status']}",
                    timeout=time.time() - start_time)
            time.sleep(self.update_interval)
            self.instance = self.api.get_instances(self.instance['id'])
        if self.instance['status'] == status_done:
            return True
        else:
            if self.instance['status'] in statuses_continue:
                return False
            else:
                if self.wait:
                    raise WaitError(
                        msg=f"Timeout waiting instance {self.instance['id']} "
                        f"status {status_done}. "
                        f"Last state was {self.instance['status']}",
                        timeout=time.time() - start_time)

    def run(self):
        if self.checkmode:
            self.instance['changed'] = True
            return self.instance
        self.api.post_instances_reinstall(instance_id=self.instance['id'],
                                          image_id=self.image_id)
        self.wait_for_statuses(status_done='ACTIVE', statuses_continue=[])
        self.instance['changed'] = True
        return self.instance
예제 #2
0
class ScCloudComputingInstanceInfo():
    def __init__(self, endpoint, token, instance_id, name, region_id):
        self.api = ScApi(token, endpoint)
        self.instance_id = self.api.toolbox.find_instance(
            instance_id=instance_id,
            instance_name=name,
            region_id=region_id,
            must=True)['id']

    def run(self):
        result = self.api.get_instances(self.instance_id)
        result['changed'] = False
        return result
예제 #3
0
class ScCloudComputingInstanceState:
    def __init__(self, endpoint, token, state, instance_id, name, region_id,
                 image_id, image_regexp, wait, update_interval, checkmode):
        self.api = ScApi(token, endpoint)
        self.state = state
        self.instance_id = self.api.toolbox.find_instance(
            instance_id=instance_id,
            instance_name=name,
            region_id=region_id,
            must=True)['id']
        self.image_id = image_id
        self.image_regexp = image_regexp
        self.wait = wait
        self.update_interval = update_interval
        self.checkmode = checkmode

    def wait_for_statuses(self, status_done, statuses_continue):
        start_time = time.time()
        while self.instance['status'] not in statuses_continue + [status_done]:
            if not self.wait:
                break
            if time.time() > start_time + self.wait:
                raise WaitError(
                    msg=f"Timeout waiting instance {self.instance['id']} "
                    f"status {status_done} or {statuses_continue}. "
                    f"Last state was {self.instance['status']}",
                    timeout=time.time() - start_time)
            time.sleep(self.update_interval)
            self.instance = self.api.get_instances(self.instance_id)
        if self.instance['status'] == status_done:
            return True
        else:
            if self.instance['status'] in statuses_continue:
                return False
            else:
                if self.wait:
                    raise WaitError(
                        msg=f"Timeout waiting instance {self.instance['id']} "
                        f"status {status_done}. "
                        f"Last state was {self.instance['status']}",
                        timeout=time.time() - start_time)

    def shutdown(self):
        if self.instance['status'] == 'RESCUE':
            raise ModuleError('Shutdown is not supported in rescue mode.')
        if self.wait_for_statuses(status_done='SWITCHED_OFF',
                                  statuses_continue=['ACTIVE']):
            self.instance['changed'] = False
            return self.instance
        if self.checkmode:
            self.instance['changed'] = True
            return self.instance
        self.api.post_instance_switch_off(self.instance_id)
        self.wait_for_statuses(status_done='SWITCHED_OFF',
                               statuses_continue=[])
        self.instance = self.api.get_instances(self.instance_id)
        self.instance['changed'] = True
        return self.instance

    def normalize(self):
        if self.wait_for_statuses(status_done='ACTIVE',
                                  statuses_continue=['SWITCHED_OFF',
                                                     'RESCUE']):
            self.instance['changed'] = False
            return self.instance
        if self.checkmode:
            self.instance['changed'] = True
            return self.instance
        if self.instance['status'] == 'SWITCHED_OFF':
            self.api.post_instance_switch_on(self.instance_id)
        elif self.instance['status'] == 'RESCUE':
            self.api.post_instance_unrescue(self.instance_id)
        self.wait_for_statuses(status_done='ACTIVE', statuses_continue=[])
        self.instance = self.api.get_instances(self.instance_id)
        self.instance['changed'] = True
        return self.instance

    def rescue(self):
        if self.image_id or self.image_regexp:
            image_id = self.api.toolbox.find_image_id(
                image_id=self.image_id,
                image_regexp=self.image_regexp,
                region_id=self.instance['region_id'],
                must=True)
        else:
            image_id = None
        if self.wait_for_statuses(status_done='RESCUE',
                                  statuses_continue=['ACTIVE',
                                                     'SWITCHED_OFF']):
            self.instance['changed'] = False
            return self.instance
        if self.checkmode:
            self.instance['changed'] = True
            return self.instance
        self.api.post_instance_rescue(self.instance_id, image_id)
        self.wait_for_statuses(status_done='RESCUE', statuses_continue=[])
        self.instance = self.api.get_instances(self.instance_id)
        self.instance['changed'] = True
        return self.instance

    def reboot(self):
        raise NotImplementedError

    def run(self):
        self.instance = self.api.get_instances(self.instance_id)
        if self.state == 'shutdown':
            return self.shutdown()
        elif self.state == 'rescue':
            return self.rescue()
        elif self.state == 'rebooted':
            return self.reboot()
        elif self.state == 'normal':
            return self.normalize()
        else:
            raise ModuleError(f"Unknown state={self.state}")
예제 #4
0
class ScCloudComputingInstanceCreate():
    def __init__(self, endpoint, token, region_id, name, image_id,
                 image_regexp, flavor_id, flavor_name, gpn_enabled,
                 ipv6_enabled, ssh_key_fingerprint, ssh_key_name,
                 backup_copies, wait, update_interval, checkmode):
        self.checkmode = checkmode
        self.api = ScApi(token, endpoint)
        if region_id is None:
            raise ModuleError("region_id is mandatory for state=present.")
        self.region_id = region_id
        if not name:
            raise ModuleError("Name is mandatory for state=present.")
        self.name = name
        self.instance_id = None
        self.flavor_id = self.get_flavor_id(flavor_id, flavor_name)
        self.image_id = self.api.toolbox.find_image_id(
            image_id=image_id,
            image_regexp=image_regexp,
            region_id=region_id,
            must=True)
        self.gpn_enabled = gpn_enabled
        self.ipv6_enabled = ipv6_enabled
        self.ssh_key_fingerprint = self.get_ssh_key_fingerprint(
            ssh_key_fingerprint, ssh_key_name)
        self.backup_copies = backup_copies
        self.wait = wait
        self.update_interval = update_interval
        self.checkmode = checkmode

    def get_ssh_key_fingerprint(self, ssh_key_fingerprint, ssh_key_name):
        if ssh_key_fingerprint:
            return ssh_key_fingerprint
        if ssh_key_name:
            for key in self.api.list_ssh_keys():
                if key['name'] == ssh_key_name:
                    return key['fingerprint']
            raise ModuleError(f"Unable to find ssh key {ssh_key_name}")
        return None

    def get_flavor_id(self, flavor_id, flavor_name):
        if flavor_id and flavor_name:
            raise ModuleError("Both flavor_id and flavor_name are present.")
        if not flavor_id and not flavor_name:
            raise ModuleError('Need either flavor_id or flavor_name.')
        if flavor_name:
            flavor_id = self.api.toolbox.find_cloud_flavor_id_by_name(
                flavor_name=flavor_name, region_id=self.region_id, must=True)
        return flavor_id

    def create_instance(self):
        instance = self.api.post_instance(
            region_id=self.region_id,
            name=self.name,
            flavor_id=self.flavor_id,
            image_id=self.image_id,
            gpn_enabled=self.image_id,
            ipv6_enabled=self.ipv6_enabled,
            ssh_key_fingerprint=self.ssh_key_fingerprint,
            backup_copies=self.backup_copies)
        return instance

    def wait_for(self, instance):
        start_time = time.time()
        instance = self.api.get_instances(instance['id'])
        if not self.wait:
            return instance
        while instance['status'] != 'ACTIVE':
            time.sleep(self.update_interval)
            elapsed = time.time() - start_time
            if elapsed > self.wait:
                raise WaitError(
                    msg=f"Timeout while waiting instance {instance['id']}"
                    f" to become ACTIVE. Last status was {instance['status']}",
                    timeout=elapsed)
            instance = self.api.get_instances(instance['id'])
        return instance

    def run(self):
        instance = self.api.toolbox.find_instance(self.instance_id,
                                                  self.name,
                                                  self.region_id,
                                                  must=False)
        if instance:
            instance['changed'] = NOT_CHANGED
        else:
            if not self.checkmode:
                instance = self.create_instance()
                instance = self.wait_for(instance)
            else:
                instance = {
                    'info':
                    'Instance shold be created, '
                    'but check_mode is activated. '
                    'no real instance was created.'
                }
            instance['changed'] = CHANGED
        return instance