def on_main(self, checkpoint, resource, context, parameters, **kwargs):
     original_volume_id = resource.id
     restore_name = parameters.get('restore_name',
                                   '%s@%s' % (checkpoint.id,
                                              original_volume_id))
     restore_description = parameters.get('restore_description', None)
     bank_section = checkpoint.get_resource_bank_section(original_volume_id)
     cinder_client = ClientFactory.create_client('cinder', context)
     glance_client = ClientFactory.create_client('glance', context)
     resource_metadata = bank_section.get_object('metadata')
     volume_size = int(resource_metadata['volume_size'])
     temporary_image = None
     try:
         temporary_image = self._create_temporary_image(
             bank_section, glance_client, original_volume_id
         )
         self._create_volume_from_image(cinder_client, temporary_image,
                                        restore_name, original_volume_id,
                                        volume_size, restore_description)
     finally:
         if temporary_image:
             try:
                 glance_client.images.delete(temporary_image.id)
             except Exception as e:
                 LOG.warning('Failed deleting temporary image: '
                             '%(temporary_image_id)s. '
                             'Reason: %(reason)s', {
                                 'temporary_image_id': temporary_image.id,
                                 'reason': e
                             })
     LOG.info("Finish restoring volume backup, volume_id: %s.",
              original_volume_id)
    def on_main(self, checkpoint, resource, context, parameters, **kwargs):
        original_volume_id = resource.id
        restore_name = parameters.get('restore_name',
                                      '%s@%s' % (checkpoint.id,
                                                 original_volume_id))
        restore_description = parameters.get('restore_description', None)
        bank_section = checkpoint.get_resource_bank_section(original_volume_id)
        cinder_client = ClientFactory.create_client('cinder', context)
        glance_client = ClientFactory.create_client('glance', context)
        resource_metadata = bank_section.get_object('metadata')
        volume_size = int(resource_metadata['volume_size'])
        temporary_image = None
        try:
            temporary_image = self._create_temporary_image(
                bank_section, glance_client, original_volume_id
            )
            volume_id = self._create_volume_from_image(
                cinder_client, temporary_image, restore_name, volume_size,
                restore_description
            )

            # check and update
            update_method = partial(
                utils.update_resource_restore_result,
                kwargs.get('restore'), resource.type, volume_id
            )

            update_method(constants.RESOURCE_STATUS_RESTORING)

            is_success = self._check_create_complete(cinder_client, volume_id)
            if is_success:
                update_method(constants.RESOURCE_STATUS_AVAILABLE)
                kwargs.get("new_resources")[original_volume_id] = volume_id
            else:
                LOG.error("Restore volume glance backup failed, so delete "
                          "the temporary volume: volume_id: %s.",
                          original_volume_id)
                cinder_client.volumes.delete(volume_id)
                raise exception.CreateResourceFailed(
                    name="Volume Glance Backup",
                    reason='Restored Volume is in erroneous state',
                    resource_id=volume_id,
                    resource_type=constants.VOLUME_RESOURCE_TYPE,
                )
        finally:
            if temporary_image:
                try:
                    glance_client.images.delete(temporary_image.id)
                except Exception as e:
                    LOG.warning('Failed deleting temporary image: '
                                '%(temporary_image_id)s. '
                                'Reason: %(reason)s', {
                                    'temporary_image_id': temporary_image.id,
                                    'reason': e
                                })
        LOG.info("Finish restoring volume backup, volume_id: %s.",
                 original_volume_id)
Example #3
0
    def on_complete(self, checkpoint, resource, context, parameters, **kwargs):
        original_server_id = resource.id
        LOG.info("Restoring server backup, server_id: %s.", original_server_id)

        update_method = None
        try:
            resource_definition = checkpoint.get_resource_bank_section(
                original_server_id).get_object("metadata")

            nova_client = ClientFactory.create_client("nova", context)
            new_resources = kwargs.get("new_resources")

            # restore server instance
            restore_net_id = parameters.get("restore_net_id", None)
            restore_flavor_id = parameters.get("restore_flavor_id", None)
            if restore_flavor_id:
                resource_definition["server_metadata"]['flavor'] = (
                    restore_flavor_id)
            new_server_id = self._restore_server_instance(
                nova_client, new_resources, original_server_id,
                parameters.get("restore_name", "karbor-restore-server"),
                restore_net_id, resource_definition)

            update_method = partial(utils.update_resource_restore_result,
                                    kwargs.get('restore'), resource.type,
                                    new_server_id)
            update_method(constants.RESOURCE_STATUS_RESTORING)
            self._wait_server_to_active(nova_client, new_server_id)

            # restore volume attachment
            self._restore_volume_attachment(
                nova_client, ClientFactory.create_client("cinder", context),
                new_resources, new_server_id, resource_definition)

            # restore floating ip association
            self._restore_floating_association(nova_client, new_server_id,
                                               resource_definition)

            new_resources[original_server_id] = new_server_id

            update_method(constants.RESOURCE_STATUS_AVAILABLE)

            LOG.info("Finish restore server, server_id: %s.",
                     original_server_id)

        except Exception as e:
            if update_method:
                update_method(constants.RESOURCE_STATUS_ERROR, str(e))
            LOG.exception("Restore server backup failed, server_id: %s.",
                          original_server_id)
            raise exception.RestoreResourceFailed(
                name="Server Backup",
                reason=e,
                resource_id=original_server_id,
                resource_type=constants.SERVER_RESOURCE_TYPE)
Example #4
0
    def on_main(self, checkpoint, resource, context, parameters, **kwargs):
        instance_id = resource.id
        bank_section = checkpoint.get_resource_bank_section(instance_id)
        trove_client = ClientFactory.create_client('trove', context)
        LOG.info('creating database instance backup, instance_id: %s',
                 instance_id)
        bank_section.update_object('status',
                                   constants.RESOURCE_STATUS_PROTECTING)
        instance_info = trove_client.instances.get(instance_id)
        if instance_info.status != "ACTIVE":
            is_success = utils.status_poll(
                partial(get_database_instance_status, trove_client,
                        instance_id),
                interval=self._interval,
                success_statuses={'ACTIVE'},
                failure_statuses=DATABASE_FAILURE_STATUSES,
                ignore_statuses=DATABASE_IGNORE_STATUSES,
            )
            if not is_success:
                bank_section.update_object('status',
                                           constants.RESOURCE_STATUS_ERROR)
                raise exception.CreateResourceFailed(
                    name="Database instance Backup",
                    reason='Database instance is in a error status.',
                    resource_id=instance_id,
                    resource_type=constants.DATABASE_RESOURCE_TYPE,
                )
        resource_metadata = {
            'instance_id': instance_id,
            'datastore': instance_info.datastore,
            'flavor': instance_info.flavor,
            'size': instance_info.volume['size'],
        }
        backup_name = parameters.get('backup_name', 'backup%s' % (instance_id))
        description = parameters.get('description', None)
        try:
            backup_id = self._create_backup(trove_client, instance_id,
                                            backup_name, description)
        except exception.CreateResourceFailed as e:
            LOG.error(
                'Error creating backup (instance_id: %(instance_id)s '
                ': %(reason)s', {
                    'instance_id': instance_id,
                    'reason': e
                })
            bank_section.update_object('status',
                                       constants.RESOURCE_STATUS_ERROR)
            raise

        resource_metadata['backup_id'] = backup_id

        bank_section.update_object('metadata', resource_metadata)
        bank_section.update_object('status',
                                   constants.RESOURCE_STATUS_AVAILABLE)
        LOG.info(
            'Backup database instance (instance_id: %(instance_id)s '
            'backup_id: %(backup_id)s ) successfully', {
                'instance_id': instance_id,
                'backup_id': backup_id
            })
Example #5
0
    def on_main(self, checkpoint, resource, context, parameters, **kwargs):
        volume_id = resource.id
        bank_section = checkpoint.get_resource_bank_section(volume_id)
        cinder_client = ClientFactory.create_client('cinder', context)
        LOG.info('Creating volume snapshot, volume_id: %s', volume_id)
        bank_section.update_object('status',
                                   constants.RESOURCE_STATUS_PROTECTING)
        volume_info = cinder_client.volumes.get(volume_id)
        is_success = utils.status_poll(
            partial(get_volume_status, cinder_client, volume_id),
            interval=self._interval,
            success_statuses={
                'available', 'in-use', 'error_extending', 'error_restoring'
            },
            failure_statuses=VOLUME_FAILURE_STATUSES,
            ignore_statuses=VOLUME_IGNORE_STATUSES,
        )
        if not is_success:
            bank_section.update_object('status',
                                       constants.RESOURCE_STATUS_ERROR)
            raise exception.CreateResourceFailed(
                name="Volume Snapshot",
                reason='Volume is in a error status.',
                resource_id=volume_id,
                resource_type=constants.VOLUME_RESOURCE_TYPE,
            )
        resource_metadata = {'volume_id': volume_id, 'size': volume_info.size}
        snapshot_name = parameters.get('snapshot_name', None)
        description = parameters.get('description', None)
        force = parameters.get('force', False)
        try:
            snapshot_id = self._create_snapshot(cinder_client, volume_id,
                                                snapshot_name, description,
                                                force)
        except Exception as e:
            LOG.error(
                'Error creating snapshot (volume_id: %(volume_id)s '
                ': %(reason)s', {
                    'volume_id': volume_id,
                    'reason': e
                })
            bank_section.update_object('status',
                                       constants.RESOURCE_STATUS_ERROR)
            raise exception.CreateResourceFailed(
                name="Volume Snapshot",
                reason=e,
                resource_id=volume_id,
                resource_type=constants.VOLUME_RESOURCE_TYPE,
            )

        resource_metadata['snapshot_id'] = snapshot_id
        bank_section.update_object('metadata', resource_metadata)
        bank_section.update_object('status',
                                   constants.RESOURCE_STATUS_AVAILABLE)
        LOG.info(
            'Snapshot volume (volume_id: %(volume_id)s snapshot_id: '
            '%(snapshot_id)s ) successfully', {
                'volume_id': volume_id,
                'snapshot_id': snapshot_id
            })
    def on_main(self, checkpoint, resource, context, parameters, **kwargs):
        resource_id = resource.id
        bank_section = checkpoint.get_resource_bank_section(resource_id)
        resource_metadata = bank_section.get_object('metadata')
        cinder_client = ClientFactory.create_client('cinder', context)
        LOG.info('Verifying the volume backup, volume_id: %s', resource_id)

        update_method = partial(
            utils.update_resource_verify_result,
            kwargs.get('verify'), resource.type, resource_id)

        backup_id = resource_metadata['backup_id']
        try:
            volume_backup = cinder_client.backups.get(backup_id)
            backup_status = volume_backup.status
        except Exception as ex:
            LOG.error('Error get volume backup (backup_id: %(backup_id)s): '
                      '%(reason)s', {'backup_id': backup_id, 'reason': ex})
            reason = 'Error getting volume backup.'
            update_method(constants.RESOURCE_STATUS_ERROR, reason)
            raise

        if backup_status == 'available':
            update_method(constants.RESOURCE_STATUS_AVAILABLE)
        else:
            reason = (
                'The status of volume backup status is %s.' % backup_status)
            update_method(backup_status, reason)
            raise exception.VerifyResourceFailed(
                name="Volume Backup",
                reason=reason,
                resource_id=resource_id,
                resource_type=resource.type
            )
Example #7
0
    def on_prepare_finish(self, checkpoint, resource, context, parameters,
                          **kwargs):
        volume_id = resource.id
        if not self._backup_from_snapshot:
            LOG.info(
                'Skipping taking snapshot of volume %s - backing up '
                'directly', volume_id)
            return

        LOG.info('Taking snapshot of volume %s', volume_id)
        bank_section = checkpoint.get_resource_bank_section(volume_id)
        bank_section.update_object('status',
                                   constants.RESOURCE_STATUS_PROTECTING)
        cinder_client = ClientFactory.create_client('cinder', context)
        try:
            self.snapshot_id = self._create_snapshot(cinder_client, volume_id)
        except Exception:
            bank_section.update_object('status',
                                       constants.RESOURCE_STATUS_ERROR)
            raise exception.CreateResourceFailed(
                name="Volume Backup",
                reason='Error creating snapshot for volume',
                resource_id=volume_id,
                resource_type=constants.VOLUME_RESOURCE_TYPE,
            )
Example #8
0
    def _get_dependent_resources_by_server(self, context, parent_resource):
        try:
            # get metadata about network from neutron
            net_client = self._neutron_client(context)
            network_infos = net_client.list_networks().get('networks')
            neutron_networks = {network["id"] for network in network_infos}

            # get interface info from server
            nova_networks = set()
            serverid = parent_resource.id
            nova_client = ClientFactory.create_client("nova", context)
            interface_list = nova_client.servers.interface_list(serverid)

            # check net_id in interface
            for iface in interface_list:
                net_id = iface.net_id
                if net_id not in nova_networks:
                    nova_networks.add(net_id)

            # get the exsited networks
            valid_networks = nova_networks.intersection(neutron_networks)
            if valid_networks:
                return [
                    resource.Resource(type=self._SUPPORT_RESOURCE_TYPE,
                                      id=self._get_network_id(),
                                      name="Network Topology")
                ]
            return []
        except Exception as e:
            LOG.exception("List all interfaces from nova failed.")
            raise exception.ListProtectableResourceFailed(
                type=self._SUPPORT_RESOURCE_TYPE, reason=six.text_type(e))
    def setUp(self):
        super(GlanceProtectionPluginTest, self).setUp()
        self.plugin = GlanceProtectionPlugin()
        cfg.CONF.set_default("glance_endpoint", "http://127.0.0.1:9292", "glance_client")

        self.cntxt = RequestContext(user_id="admin", project_id="abcd", auth_token="efgh")
        self.glance_client = ClientFactory.create_client("glance", self.cntxt)
        self.checkpoint = CheckpointCollection()
Example #10
0
    def on_main(self, checkpoint, resource, context, parameters, **kwargs):
        original_instance_id = resource.id
        bank_section = checkpoint.get_resource_bank_section(
            original_instance_id)
        trove_client = ClientFactory.create_client('trove', context)
        resource_metadata = bank_section.get_object('metadata')
        restore_name = parameters.get(
            'restore_name', '%s@%s' % (checkpoint.id, original_instance_id))
        flavor = resource_metadata['flavor']
        size = resource_metadata['size']
        backup_id = resource_metadata['backup_id']
        restore = kwargs.get('restore')
        LOG.info(
            "Restoring a database instance from backup, "
            "original_instance_id: %s.", original_instance_id)

        try:
            instance_info = trove_client.instances.create(
                restore_name,
                flavor["id"],
                volume={"size": size},
                restorePoint={"backupRef": backup_id})
            is_success = utils.status_poll(
                partial(get_database_instance_status, trove_client,
                        instance_info.id),
                interval=self._interval,
                success_statuses={'ACTIVE'},
                failure_statuses=DATABASE_FAILURE_STATUSES,
                ignore_statuses=DATABASE_IGNORE_STATUSES)
            if is_success is not True:
                LOG.error(
                    'The status of database instance is '
                    'invalid. status:%s', instance_info.status)
                restore.update_resource_status(
                    constants.DATABASE_RESOURCE_TYPE, instance_info.id,
                    instance_info.status, "Invalid status.")
                restore.save()
                raise exception.RestoreResourceFailed(
                    name="Database instance Backup",
                    reason="Invalid status.",
                    resource_id=original_instance_id,
                    resource_type=constants.DATABASE_RESOURCE_TYPE)
            restore.update_resource_status(constants.DATABASE_RESOURCE_TYPE,
                                           instance_info.id,
                                           instance_info.status)
            restore.save()
        except Exception as e:
            LOG.error(
                "Restore Database instance from backup "
                "failed, instance_id: %s.", original_instance_id)
            raise exception.RestoreResourceFailed(
                name="Database instance Backup",
                reason=e,
                resource_id=original_instance_id,
                resource_type=constants.DATABASE_RESOURCE_TYPE)
        LOG.info(
            "Finish restoring a Database instance from backup,"
            "instance_id: %s.", original_instance_id)
Example #11
0
 def _create_server_snapshot(self, context, glance_client, parameters,
                             resource, resource_definition, resource_id):
     server_id = resource.extra_info.get('server_id')
     resource_definition['resource_id'] = resource_id
     resource_definition['server_id'] = server_id
     nova_client = ClientFactory.create_client('nova', context)
     is_success = utils.status_poll(
         partial(get_server_status, nova_client, server_id),
         interval=self._interval,
         success_statuses={'ACTIVE', 'STOPPED', 'SUSPENDED', 'PAUSED'},
         failure_statuses={
             'DELETED', 'ERROR', 'RESIZED', 'SHELVED', 'SHELVED_OFFLOADED',
             'SOFT_DELETED', 'RESCUED', 'not-found'
         },
         ignore_statuses={'BUILDING'},
     )
     if not is_success:
         raise exception.CreateResourceFailed(
             name="Image Backup",
             reason='The parent server of the image is not in valid'
             ' status',
             resource_id=resource_id,
             resource_type=constants.IMAGE_RESOURCE_TYPE)
     temp_image_name = 'Temp_image_name_for_karbor' + server_id
     try:
         image_uuid = nova_client.servers.create_image(
             server_id, temp_image_name, parameters)
     except Exception as e:
         msg = "Failed to create the server snapshot: %s" % e
         LOG.exception(msg)
         raise exception.CreateResourceFailed(
             name="Image Backup",
             reason=msg,
             resource_id=resource_id,
             resource_type=constants.IMAGE_RESOURCE_TYPE)
     else:
         is_success = utils.status_poll(
             partial(get_image_status, glance_client, image_uuid),
             interval=self._interval,
             success_statuses={'active'},
             failure_statuses={
                 'killed', 'deleted', 'pending_delete', 'deactivated'
             },
             ignore_statuses={'queued', 'saving', 'uploading'})
         if not is_success:
             msg = "Image has been created, but fail to become " \
                   "active, so delete it and raise exception."
             LOG.error(msg)
             glance_client.images.delete(image_uuid)
             image_uuid = None
     if not image_uuid:
         raise exception.CreateResourceFailed(
             name="Image Backup",
             reason="Create parent server snapshot failed.",
             resource_id=resource_id,
             resource_type=constants.IMAGE_RESOURCE_TYPE)
     return image_uuid
Example #12
0
    def on_main(self, checkpoint, resource, context, parameters, **kwargs):
        pod_id = resource.id
        pod_name = resource.name
        bank_section = checkpoint.get_resource_bank_section(pod_id)
        k8s_client = ClientFactory.create_client("k8s", context)
        resource_definition = {"resource_id": pod_id}

        LOG.info("Creating pod backup, id: %(pod_id)s) name: "
                 "%(pod_name)s.", {
                     "pod_id": pod_id,
                     "pod_name": pod_name
                 })
        try:
            bank_section.update_object("status",
                                       constants.RESOURCE_STATUS_PROTECTING)

            # get metadata about pod
            pod_namespace, k8s_pod_name = pod_name.split(":")
            pod = k8s_client.read_namespaced_pod(k8s_pod_name, pod_namespace)
            resource_definition["resource_name"] = pod_name
            resource_definition["namespace"] = pod_namespace

            mounted_volumes_list = self._get_mounted_volumes(
                k8s_client, pod, pod_namespace)
            containers_list = self._get_containers(pod)

            # save all pod's metadata
            pod_metadata = {
                'apiVersion': pod.api_version,
                'kind': pod.kind,
                'metadata': {
                    'labels': pod.metadata.labels,
                    'name': pod.metadata.name,
                    'namespace': pod.metadata.namespace,
                },
                'spec': {
                    'containers': containers_list,
                    'volumes': mounted_volumes_list,
                    'restartPolicy': pod.spec.restart_policy
                }
            }
            resource_definition["pod_metadata"] = pod_metadata
            LOG.debug("Creating pod backup, pod_metadata: %s.", pod_metadata)
            bank_section.update_object("metadata", resource_definition)
            bank_section.update_object("status",
                                       constants.RESOURCE_STATUS_AVAILABLE)
            LOG.info("Finish backup pod, pod_id: %s.", pod_id)
        except Exception as err:
            LOG.exception("Create pod backup failed, pod_id: %s.", pod_id)
            bank_section.update_object("status",
                                       constants.RESOURCE_STATUS_ERROR)
            raise exception.CreateResourceFailed(
                name="Pod Backup",
                reason=err,
                resource_id=pod_id,
                resource_type=constants.POD_RESOURCE_TYPE)
 def on_main(self, checkpoint, resource, context, parameters, **kwargs):
     original_share_id = resource.id
     bank_section = checkpoint.get_resource_bank_section(original_share_id)
     manila_client = ClientFactory.create_client('manila', context)
     resource_metadata = bank_section.get_object('metadata')
     restore_name = parameters.get(
         'restore_name', '%s@%s' % (checkpoint.id, original_share_id))
     restore_description = parameters.get('restore_description', None)
     snapshot_id = resource_metadata['snapshot_id']
     share_proto = resource_metadata['share_proto']
     size = resource_metadata['size']
     share_type = resource_metadata['share_type']
     share_network_id = resource_metadata['share_network_id']
     restore = kwargs.get('restore')
     LOG.info("Restoring a share from snapshot, "
              "original_share_id: %s.", original_share_id)
     try:
         share = manila_client.shares.create(
             share_proto,
             size,
             snapshot_id=snapshot_id,
             name=restore_name,
             description=restore_description,
             share_network=share_network_id,
             share_type=share_type)
         is_success = utils.status_poll(
             partial(get_share_status, manila_client, share.id),
             interval=self._interval,
             success_statuses={'available'},
             failure_statuses=SHARE_FAILURE_STATUSES,
             ignore_statuses=SHARE_IGNORE_STATUSES)
         if is_success is not True:
             LOG.error('The status of share is invalid. status:%s',
                       share.status)
             restore.update_resource_status(constants.SHARE_RESOURCE_TYPE,
                                            share.id, share.status,
                                            "Invalid status.")
             restore.save()
             raise exception.RestoreResourceFailed(
                 name="Share Snapshot",
                 reason="Invalid status.",
                 resource_id=original_share_id,
                 resource_type=constants.SHARE_RESOURCE_TYPE)
         restore.update_resource_status(constants.SHARE_RESOURCE_TYPE,
                                        share.id, share.status)
         restore.save()
     except Exception as e:
         LOG.error("Restore share from snapshot failed, share_id: %s.",
                   original_share_id)
         raise exception.RestoreResourceFailed(
             name="Share Snapshot",
             reason=e,
             resource_id=original_share_id,
             resource_type=constants.SHARE_RESOURCE_TYPE)
     LOG.info("Finish restoring a share from snapshot, share_id: %s.",
              original_share_id)
Example #14
0
 def on_main(self, checkpoint, resource, context, parameters, **kwargs):
     original_volume_id = resource.id
     bank_section = checkpoint.get_resource_bank_section(original_volume_id)
     cinder_client = ClientFactory.create_client('cinder', context)
     resource_metadata = bank_section.get_object('metadata')
     restore_name = parameters.get(
         'restore_name',
         'volume-%s@%s' % (checkpoint.id, original_volume_id))
     restore_description = parameters.get('restore_description', None)
     snapshot_id = resource_metadata['snapshot_id']
     size = resource_metadata['size']
     restore = kwargs.get('restore')
     LOG.info("Restoring a volume from snapshot, "
              "original_volume_id: %s", original_volume_id)
     try:
         volume = cinder_client.volumes.create(
             size,
             snapshot_id=snapshot_id,
             name=restore_name,
             description=restore_description)
         is_success = utils.status_poll(
             partial(get_volume_status, cinder_client, volume.id),
             interval=self._interval,
             success_statuses={
                 'available', 'in-use', 'error_extending', 'error_restoring'
             },
             failure_statuses=VOLUME_FAILURE_STATUSES,
             ignore_statuses=VOLUME_IGNORE_STATUSES,
         )
         volume = cinder_client.volumes.get(volume.id)
         if is_success is not True:
             LOG.error('The status of volume is invalid. status:%s',
                       volume.status)
             reason = 'Invalid status: %s' % volume.status
             restore.update_resource_status(constants.VOLUME_RESOURCE_TYPE,
                                            volume.id, volume.status,
                                            reason)
             restore.save()
             raise exception.RestoreResourceFailed(
                 name="Volume Snapshot",
                 resource_id=original_volume_id,
                 resource_type=constants.VOLUME_RESOURCE_TYPE)
         restore.update_resource_status(constants.VOLUME_RESOURCE_TYPE,
                                        volume.id, volume.status)
         restore.save()
     except Exception as e:
         LOG.error("Restore volume from snapshot failed, volume_id: %s",
                   original_volume_id)
         raise exception.RestoreResourceFailed(
             name="Volume Snapshot",
             reason=e,
             resource_id=original_volume_id,
             resource_type=constants.VOLUME_RESOURCE_TYPE)
     LOG.info("Finish restoring a volume from snapshot, volume_id: %s",
              original_volume_id)
    def setUp(self):
        super(GlanceProtectionPluginTest, self).setUp()
        self.plugin = GlanceProtectionPlugin()
        cfg.CONF.set_default('glance_endpoint', 'http://127.0.0.1:9292',
                             'glance_client')

        self.cntxt = RequestContext(user_id='admin',
                                    project_id='abcd',
                                    auth_token='efgh')
        self.glance_client = ClientFactory.create_client("glance", self.cntxt)
        self.checkpoint = CheckpointCollection()
Example #16
0
    def setUp(self):
        super(CinderProtectionPluginTest, self).setUp()
        self.plugin = CinderProtectionPlugin()
        cfg.CONF.set_default('cinder_endpoint', 'http://127.0.0.1:8776/v2',
                             'cinder_client')

        self.cntxt = RequestContext(user_id='admin',
                                    project_id='abcd',
                                    auth_token='efgh')
        self.cinder_client = ClientFactory.create_client("cinder", self.cntxt)
        self.checkpoint = FakeCheckpoint()
    def setUp(self):
        super(CinderProtectionPluginTest, self).setUp()
        self.plugin = CinderProtectionPlugin()
        cfg.CONF.set_default('cinder_endpoint',
                             'http://127.0.0.1:8776/v2',
                             'cinder_client')

        self.cntxt = RequestContext(user_id='admin',
                                    project_id='abcd',
                                    auth_token='efgh')
        self.cinder_client = ClientFactory.create_client("cinder", self.cntxt)
        self.checkpoint = FakeCheckpoint()
Example #18
0
    def on_main(self, checkpoint, resource, context, parameters, **kwargs):
        image_id = resource.id
        bank_section = checkpoint.get_resource_bank_section(image_id)

        resource_definition = {"resource_id": image_id}
        glance_client = ClientFactory.create_client('glance', context)
        LOG.info("Creating image backup, image_id: %s.", image_id)
        try:
            bank_section.update_object("status",
                                       constants.RESOURCE_STATUS_PROTECTING)
            image_info = glance_client.images.get(image_id)
            if image_info.status != "active":
                is_success = utils.status_poll(
                    partial(get_image_status, glance_client, image_info.id),
                    interval=self._interval,
                    success_statuses={'active'},
                    ignore_statuses={'queued', 'saving'},
                    failure_statuses={
                        'killed', 'deleted', 'pending_delete', 'deactivated',
                        'NotFound'
                    })
                if is_success is not True:
                    LOG.error("The status of image (id: %s) is invalid.",
                              image_id)
                    raise exception.CreateResourceFailed(
                        name="Image Backup",
                        reason="The status of image is invalid.",
                        resource_id=image_id,
                        resource_type=constants.IMAGE_RESOURCE_TYPE)

            image_metadata = {
                "disk_format": image_info.disk_format,
                "container_format": image_info.container_format,
                "checksum": image_info.checksum
            }
            resource_definition["image_metadata"] = image_metadata

            bank_section.update_object("metadata", resource_definition)
        except Exception as err:
            LOG.error("Create image backup failed, image_id: %s.", image_id)
            bank_section.update_object("status",
                                       constants.RESOURCE_STATUS_ERROR)
            raise exception.CreateResourceFailed(
                name="Image Backup",
                reason=err,
                resource_id=image_id,
                resource_type=constants.IMAGE_RESOURCE_TYPE)
        self._create_backup(glance_client, bank_section, image_id)
Example #19
0
def get_flow(context, workflow_engine, operation_type, checkpoint, provider,
             restore, restore_auth):
    target = restore.get('restore_target', None)

    # TODO(luobin): create a heat_client
    # Initialize a heat client using current login tenant when the
    # restore_target and restore_auth is not provided.
    if target is not None:
        username = None
        password = None
        if restore_auth is not None:
            auth_type = restore_auth.get("type", None)
            if auth_type == "password":
                username = restore_auth["username"]
                password = restore_auth["password"]
        kwargs = {
            "auth_url": target,
            "username": username,
            "password": password
        }
    else:
        kwargs = {}
    heat_client = ClientFactory.create_client("heat",
                                              context=context,
                                              **kwargs)

    # TODO(luobin): create a heat_template
    heat_template = HeatTemplate()

    ctx = {
        'context': context,
        'checkpoint': checkpoint,
        'workflow_engine': workflow_engine,
        'operation_type': operation_type,
        'restore': restore,
        'heat_template': heat_template
    }

    flow_name = "create_restoration_" + checkpoint.id
    restoration_flow = workflow_engine.build_flow(flow_name, 'linear')
    result = provider.build_task_flow(ctx)
    resource_flow = result.get('task_flow')
    workflow_engine.add_tasks(
        restoration_flow, resource_flow,
        CreateStackTask(heat_client, heat_template),
        SyncStackStatusTask(checkpoint, heat_client, restore))
    flow_engine = workflow_engine.get_engine(restoration_flow)
    return flow_engine
Example #20
0
    def on_main(self, checkpoint, resource, context, parameters, **kwargs):
        resource_id = resource.id
        bank_section = checkpoint.get_resource_bank_section(resource_id)
        resource_metadata = bank_section.get_object('metadata')
        cinder_client = ClientFactory.create_client('cinder', context)

        # create volume
        volume_property = {
            'name':
            parameters.get('restore_name',
                           '%s@%s' % (checkpoint.id, resource_id))
        }
        if 'restore_description' in parameters:
            volume_property['description'] = parameters['restore_description']
        backup_id = resource_metadata['backup_id']
        try:
            volume_id = cinder_client.restores.restore(backup_id).volume_id
            cinder_client.volumes.update(volume_id, **volume_property)
        except Exception as ex:
            LOG.error(
                'Error creating volume (backup_id: %(backup_id)s): '
                '%(reason)s', {
                    'backup_id': backup_id,
                    'reason': ex
                })
            raise

        # check and update status
        update_method = partial(utils.update_resource_restore_result,
                                kwargs.get('restore'), resource.type,
                                volume_id)

        update_method(constants.RESOURCE_STATUS_RESTORING)

        is_success = self._check_create_complete(cinder_client, volume_id)
        if is_success:
            update_method(constants.RESOURCE_STATUS_AVAILABLE)
            kwargs.get("new_resources")[resource_id] = volume_id
        else:
            reason = 'Error creating volume'
            update_method(constants.RESOURCE_STATUS_ERROR, reason)

            raise exception.RestoreResourceFailed(name="Volume Backup",
                                                  reason=reason,
                                                  resource_id=resource_id,
                                                  resource_type=resource.type)
Example #21
0
    def on_main(self, checkpoint, resource, context, parameters, **kwargs):
        original_image_id = resource.id
        name = parameters.get("restore_name", "karbor-restore-image")
        LOG.info("Restoring image backup, image_id: %s.", original_image_id)

        glance_client = ClientFactory.create_client('glance', context)
        bank_section = checkpoint.get_resource_bank_section(original_image_id)
        image_info = None
        try:
            image_info = utils.restore_image_from_bank(glance_client,
                                                       bank_section, name)

            if image_info.status != "active":
                is_success = utils.status_poll(
                    partial(get_image_status, glance_client, image_info.id),
                    interval=self._interval,
                    success_statuses={'active'},
                    ignore_statuses={'queued', 'saving'},
                    failure_statuses={
                        'killed', 'deleted', 'pending_delete', 'deactivated',
                        'not-found'
                    })
                if is_success is not True:
                    LOG.error('The status of image is invalid. status:%s',
                              image_info.status)
                    raise exception.RestoreResourceFailed(
                        name="Image Backup",
                        resource_id=image_info.id,
                        resource_type=constants.IMAGE_RESOURCE_TYPE)

            kwargs.get("new_resources")[original_image_id] = image_info.id
        except Exception as e:
            LOG.error("Restore image backup failed, image_id: %s.",
                      original_image_id)
            if image_info is not None and hasattr(image_info, 'id'):
                LOG.info("Delete the failed image, image_id: %s.",
                         image_info.id)
                glance_client.images.delete(image_info.id)
            raise exception.RestoreResourceFailed(
                name="Image Backup",
                reason=e,
                resource_id=original_image_id,
                resource_type=constants.IMAGE_RESOURCE_TYPE)
        LOG.info("Finish restoring image backup, image_id: %s.",
                 original_image_id)
Example #22
0
    def on_complete(self, checkpoint, resource, context, parameters, **kwargs):
        original_pod_id = resource.id
        LOG.info("Restoring pod backup, pod_id: %s.", original_pod_id)

        update_method = None
        try:
            resource_definition = checkpoint.get_resource_bank_section(
                original_pod_id).get_object("metadata")

            LOG.debug("Restoring pod backup, metadata: %s.",
                      resource_definition)

            k8s_client = ClientFactory.create_client("k8s", context)
            new_resources = kwargs.get("new_resources")

            # restore pod
            new_pod_name = self._restore_pod_instance(
                k8s_client, new_resources, original_pod_id,
                parameters.get(
                    "restore_name",
                    "karbor-restored-pod-%s" % uuidutils.generate_uuid()),
                resource_definition)

            update_method = partial(utils.update_resource_restore_result,
                                    kwargs.get('restore'), resource.type,
                                    new_pod_name)
            update_method(constants.RESOURCE_STATUS_RESTORING)
            pod_namespace = resource_definition["namespace"]
            self._wait_pod_to_running(k8s_client, new_pod_name, pod_namespace)

            new_resources[original_pod_id] = new_pod_name
            update_method(constants.RESOURCE_STATUS_AVAILABLE)
            LOG.info("Finish restore pod, pod_id: %s.", original_pod_id)

        except Exception as e:
            if update_method:
                update_method(constants.RESOURCE_STATUS_ERROR, str(e))
            LOG.exception("Restore pod backup failed, pod_id: %s.",
                          original_pod_id)
            raise exception.RestoreResourceFailed(
                name="Pod Backup",
                reason=e,
                resource_id=original_pod_id,
                resource_type=constants.POD_RESOURCE_TYPE)
    def on_main(self, checkpoint, resource, context, parameters, **kwargs):
        network_id = get_network_id(context)
        backup_name = kwargs.get("backup_name", "karbor network backup")
        bank_section = checkpoint.get_resource_bank_section(network_id)
        neutron_client = ClientFactory.create_client("neutron", context)

        resource_definition = {"resource_id": network_id}
        resource_definition["backup_name"] = backup_name
        resource_definition["network_metadata"] = (
            self._get_resources_by_network(context, neutron_client))
        resource_definition["subnet_metadata"] = (
            self._get_resources_by_subnet(context, neutron_client))
        resource_definition["port_metadata"] = (
            self._get_resources_by_port(context, neutron_client))
        resource_definition["router_metadata"] = (
            self._get_resources_by_router(context, neutron_client))
        resource_definition["security-group_metadata"] = (
            self._get_resources_by_security_group(context, neutron_client))

        try:
            bank_section.update_object("status",
                                       constants.RESOURCE_STATUS_PROTECTING)

            # write resource_definition in bank
            bank_section.update_object("metadata", resource_definition)

            # update resource_definition backup_status
            bank_section.update_object("status",
                                       constants.CHECKPOINT_STATUS_AVAILABLE)
            LOG.info("finish backup network, network_id: %s.", network_id)
        except Exception as err:
            # update resource_definition backup_status
            LOG.error("create backup failed, network_id: %s.", network_id)
            bank_section.update_object("status",
                                       constants.CHECKPOINT_STATUS_ERROR)
            raise exception.CreateResourceFailed(
                name="Network Backup",
                reason=err,
                resource_id=network_id,
                resource_type=self._SUPPORT_RESOURCE_TYPES)
Example #24
0
 def on_main(self, checkpoint, resource, context, parameters, **kwargs):
     resource_id = resource.id
     bank_section = checkpoint.get_resource_bank_section(resource_id)
     backup_id = None
     try:
         bank_section.update_object('status',
                                    constants.RESOURCE_STATUS_DELETING)
         resource_metadata = bank_section.get_object('metadata')
         backup_id = resource_metadata['backup_id']
         trove_client = ClientFactory.create_client('trove', context)
         try:
             backup = trove_client.backups.get(backup_id)
             trove_client.backups.delete(backup)
         except trove_exc.NotFound:
             LOG.info('Backup id: %s not found. Assuming deleted',
                      backup_id)
         is_success = utils.status_poll(
             partial(get_backup_status, trove_client, backup_id),
             interval=self._interval,
             success_statuses={'not-found'},
             failure_statuses={'FAILED', 'DELETE_FAILED'},
             ignore_statuses={'COMPLETED'},
             ignore_unexpected=True
         )
         if not is_success:
             raise exception.NotFound()
         bank_section.delete_object('metadata')
         bank_section.update_object('status',
                                    constants.RESOURCE_STATUS_DELETED)
     except Exception as e:
         LOG.error('Delete Database instance Backup failed, backup_id: %s',
                   backup_id)
         bank_section.update_object('status',
                                    constants.RESOURCE_STATUS_ERROR)
         raise exception.DeleteResourceFailed(
             name="Database instance Backup",
             reason=six.text_type(e),
             resource_id=resource_id,
             resource_type=constants.DATABASE_RESOURCE_TYPE
         )
 def on_main(self, checkpoint, resource, context, parameters, **kwargs):
     resource_id = resource.id
     bank_section = checkpoint.get_resource_bank_section(resource_id)
     snapshot_id = None
     try:
         bank_section.update_object('status',
                                    constants.RESOURCE_STATUS_DELETING)
         resource_metadata = bank_section.get_object('metadata')
         snapshot_id = resource_metadata['snapshot_id']
         cinder_client = ClientFactory.create_client('cinder', context)
         try:
             snapshot = cinder_client.volume_snapshots.get(snapshot_id)
             cinder_client.volume_snapshots.delete(snapshot)
         except cinder_exc.NotFound:
             LOG.info('Snapshot id: %s not found. Assuming deleted',
                      snapshot_id)
         is_success = utils.status_poll(
             partial(get_snapshot_status, cinder_client, snapshot_id),
             interval=self._interval,
             success_statuses={'deleted', 'not-found'},
             failure_statuses={'error', 'error_deleting'},
             ignore_statuses={'deleting'},
             ignore_unexpected=True
         )
         if not is_success:
             raise exception.NotFound()
         bank_section.delete_object('metadata')
         bank_section.update_object('status',
                                    constants.RESOURCE_STATUS_DELETED)
     except Exception as e:
         LOG.error('Delete volume snapshot failed, snapshot_id: %s',
                   snapshot_id)
         bank_section.update_object('status',
                                    constants.RESOURCE_STATUS_ERROR)
         raise exception.DeleteResourceFailed(
             name="Volume Snapshot",
             reason=six.text_type(e),
             resource_id=resource_id,
             resource_type=constants.VOLUME_RESOURCE_TYPE
         )
Example #26
0
    def on_main(self, checkpoint, resource, context, parameters, **kwargs):
        original_volume_id = resource.id
        bank_section = checkpoint.get_resource_bank_section(original_volume_id)
        cinder_client = ClientFactory.create_client('cinder', context)
        resource_metadata = bank_section.get_object('metadata')
        LOG.info('Verifying the volume snapshot, volume_id: %s',
                 original_volume_id)

        update_method = partial(utils.update_resource_verify_result,
                                kwargs.get('verify'), resource.type,
                                original_volume_id)

        snapshot_id = resource_metadata['snapshot_id']
        try:
            volume_snapshot = cinder_client.volume_snapshots.get(snapshot_id)
            snapshot_status = volume_snapshot.status
        except Exception as ex:
            LOG.error(
                'Getting volume snapshot (snapshot_id: %(snapshot_id)s):'
                '%(reason)s fails', {
                    'snapshot_id': snapshot_id,
                    'reason': ex
                })
            reason = 'Getting volume backup fails.'
            update_method(constants.RESOURCE_STATUS_ERROR, reason)
            raise

        if snapshot_status == 'available':
            update_method(constants.RESOURCE_STATUS_AVAILABLE)
        else:
            reason = ('The status of volume snapshot status is %s.' %
                      snapshot_status)
            update_method(snapshot_status, reason)
            raise exception.VerifyResourceFailed(
                name="Volume snapshot",
                reason=reason,
                resource_id=original_volume_id,
                resource_type=resource.type)
Example #27
0
 def on_main(self, checkpoint, resource, context, parameters, **kwargs):
     resource_id = resource.id
     bank_section = checkpoint.get_resource_bank_section(resource_id)
     backup_id = None
     try:
         bank_section.update_object('status',
                                    constants.RESOURCE_STATUS_DELETING)
         resource_metadata = bank_section.get_object('metadata')
         backup_id = resource_metadata['backup_id']
         cinder_client = ClientFactory.create_client('cinder', context)
         try:
             backup = cinder_client.backups.get(backup_id)
             cinder_client.backups.delete(backup)
         except cinder_exc.NotFound:
             LOG.info('Backup id: %s not found. Assuming deleted',
                      backup_id)
         is_success = status_poll(
             partial(get_backup_status, cinder_client, backup_id),
             interval=self._interval,
             success_statuses={'deleted', 'not-found'},
             failure_statuses={'error', 'error_deleting'},
             ignore_statuses={'deleting'},
         )
         if not is_success:
             raise exception.NotFound()
         bank_section.delete_object('metadata')
         bank_section.update_object('status',
                                    constants.RESOURCE_STATUS_DELETED)
     except Exception as e:
         LOG.error('delete volume backup failed, backup_id: %s', backup_id)
         bank_section.update_object('status',
                                    constants.RESOURCE_STATUS_ERROR)
         raise exception.DeleteBackupFailed(
             reason=six.text_type(e),
             resource_id=resource_id,
             resource_type=constants.VOLUME_RESOURCE_TYPE)
Example #28
0
    def on_main(self, checkpoint, resource, context, parameters, **kwargs):
        original_instance_id = resource.id
        bank_section = checkpoint.get_resource_bank_section(
            original_instance_id)
        trove_client = ClientFactory.create_client('trove', context)
        resource_metadata = bank_section.get_object('metadata')
        LOG.info('Verifying the database instance, instance_id: %s',
                 original_instance_id)

        update_method = partial(
            utils.update_resource_verify_result,
            kwargs.get('verify'), resource.type, original_instance_id)

        backup_id = resource_metadata['backup_id']
        try:
            instance_backup = trove_client.backups.get(backup_id)
            backup_status = instance_backup.status
        except Exception as ex:
            LOG.error('Getting database backup (backup_id: %(backup_id)s):'
                      '%(reason)s fails',
                      {'backup_id': backup_id, 'reason': ex})
            reason = 'Getting database backup fails.'
            update_method(constants.RESOURCE_STATUS_ERROR, reason)
            raise

        if backup_status == 'COMPLETED':
            update_method(constants.RESOURCE_STATUS_AVAILABLE)
        else:
            reason = ('The status of database backup status is %s.'
                      % backup_status)
            update_method(backup_status, reason)
            raise exception.VerifyResourceFailed(
                name="Database backup",
                reason=reason,
                resource_id=original_instance_id,
                resource_type=resource.type)
Example #29
0
    def _k8s_client(self, context):
        self._k8s_client_instance = ClientFactory.create_client("k8s", context)

        return self._k8s_client_instance
Example #30
0
    def _client(self, context):
        self._client_instance = ClientFactory.create_client("cinder", context)

        return self._client_instance
Example #31
0
    def on_main(self, checkpoint, resource, context, parameters, **kwargs):
        server_id = resource.id
        bank_section = checkpoint.get_resource_bank_section(server_id)

        nova_client = ClientFactory.create_client("nova", context)
        cinder_client = ClientFactory.create_client("cinder", context)
        neutron_client = ClientFactory.create_client("neutron", context)

        resource_definition = {"resource_id": server_id}

        # get dependent resources
        server_child_nodes = []
        resources = checkpoint.resource_graph
        for resource_node in resources:
            resource = resource_node.value
            if resource.id == server_id:
                server_child_nodes = resource_node.child_nodes

        LOG.info("Creating server backup, server_id: %s. ", server_id)
        try:
            bank_section.update_object("status",
                                       constants.RESOURCE_STATUS_PROTECTING)

            # get attach_metadata about volume
            attach_metadata = {}
            for server_child_node in server_child_nodes:
                child_resource = server_child_node.value
                if child_resource.type == constants.VOLUME_RESOURCE_TYPE:
                    volume = cinder_client.volumes.get(child_resource.id)
                    attachments = getattr(volume, "attachments")
                    for attachment in attachments:
                        if attachment["server_id"] == server_id:
                            attachment["bootable"] = getattr(
                                volume, "bootable")
                            attach_metadata[child_resource.id] = attachment
            resource_definition["attach_metadata"] = attach_metadata

            # get metadata about AZ
            server = nova_client.servers.get(server_id)
            availability_zone = getattr(server, "OS-EXT-AZ:availability_zone")

            # get metadata about network, flavor, key_name, security_groups
            addresses = getattr(server, "addresses")
            networks = []
            floating_ips = []
            for network_infos in addresses.values():
                for network_info in network_infos:
                    addr = network_info.get("addr")
                    mac = network_info.get("OS-EXT-IPS-MAC:mac_addr")
                    network_type = network_info.get("OS-EXT-IPS:type")
                    if network_type == 'fixed':
                        port = neutron_client.list_ports(
                            mac_address=mac)["ports"][0]
                        if port["network_id"] not in networks:
                            networks.append(port["network_id"])
                    elif network_type == "floating":
                        floating_ips.append(addr)
            flavor = getattr(server, "flavor")["id"]
            key_name = getattr(server, "key_name", None)
            security_groups = getattr(server, "security_groups", None)

            # get metadata about boot device
            boot_metadata = {}
            image_info = getattr(server, "image", None)
            if image_info is not None and isinstance(image_info, dict):
                boot_metadata["boot_device_type"] = "image"
                boot_metadata["boot_image_id"] = image_info['id']
            else:
                boot_metadata["boot_device_type"] = "volume"
                volumes_attached = getattr(
                    server, "os-extended-volumes:volumes_attached", [])
                for volume_attached in volumes_attached:
                    volume_id = volume_attached["id"]
                    volume_attach_metadata = attach_metadata.get(
                        volume_id, None)
                    if volume_attach_metadata is not None and (
                            volume_attach_metadata["bootable"] == "true"):
                        boot_metadata["boot_volume_id"] = volume_id
                        boot_metadata["boot_attach_metadata"] = (
                            volume_attach_metadata)
            resource_definition["boot_metadata"] = boot_metadata

            # save all server's metadata
            server_metadata = {
                "availability_zone": availability_zone,
                "networks": networks,
                "floating_ips": floating_ips,
                "flavor": flavor,
                "key_name": key_name,
                "security_groups": security_groups,
            }
            resource_definition["server_metadata"] = server_metadata
            LOG.info("Creating server backup, resource_definition: %s.",
                     resource_definition)
            bank_section.update_object("metadata", resource_definition)

            # update resource_definition backup_status
            bank_section.update_object("status",
                                       constants.RESOURCE_STATUS_AVAILABLE)
            LOG.info("Finish backup server, server_id: %s.", server_id)
        except Exception as err:
            # update resource_definition backup_status
            LOG.exception("Create backup failed, server_id: %s.", server_id)
            bank_section.update_object("status",
                                       constants.RESOURCE_STATUS_ERROR)
            raise exception.CreateResourceFailed(
                name="Server Backup",
                reason=err,
                resource_id=server_id,
                resource_type=constants.SERVER_RESOURCE_TYPE)
Example #32
0
 def _nova_client(self, context):
     self._nova_client_instance = \
         ClientFactory.create_client('nova', context)
     return self._nova_client_instance
Example #33
0
 def _glance_client(self, context):
     self._glance_client_instance = \
         ClientFactory.create_client('glance', context)
     return self._glance_client_instance
 def _glance_client(self, cntxt):
     return ClientFactory.create_client("glance", cntxt)
Example #35
0
 def _neutron_client(self, cntxt):
     return ClientFactory.create_client("neutron", cntxt)
Example #36
0
 def _nova_client(self, cntxt):
     return ClientFactory.create_client("nova", cntxt)
Example #37
0
 def _cinder_client(self, cntxt):
     return ClientFactory.create_client("cinder", cntxt)
Example #38
0
 def _glance_client(self, cntxt):
     return ClientFactory.create_client("glance", cntxt)
Example #39
0
    def _client(self, context):
        self._client_instance = ClientFactory.create_client(
            "nova",
            context)

        return self._client_instance