Example #1
0
 def __init__(self):
     self.migration_utils = FilteringUtils()
     self.file_path = 'devlab/tests/scenarios/cold_migrate.yaml'
     self.main_folder = self.migration_utils.main_folder
     self.full_path = os.path.join(self.main_folder, self.file_path)
     self.exception_task = {'fail_migration': True}
     self.steps_list = []
Example #2
0
    def __init__(self, cloud_prefix='SRC'):
        self.filtering_utils = FilteringUtils()
        self.username = os.environ['%s_OS_USERNAME' % cloud_prefix]
        self.password = os.environ['%s_OS_PASSWORD' % cloud_prefix]
        self.tenant = os.environ['%s_OS_TENANT_NAME' % cloud_prefix]
        self.auth_url = os.environ['%s_OS_AUTH_URL' % cloud_prefix]
        self.image_endpoint = os.environ['%s_OS_IMAGE_ENDPOINT' % cloud_prefix]
        self.neutron_endpoint = os.environ['%s_OS_NEUTRON_ENDPOINT'
                                           % cloud_prefix]

        self.keystoneclient = keystone.Client(auth_url=self.auth_url,
                                              username=self.username,
                                              password=self.password,
                                              tenant_name=self.tenant)
        self.keystoneclient.authenticate()
        self.token = self.keystoneclient.auth_token

        self.novaclient = nova.Client(NOVA_CLIENT_VERSION,
                                      username=self.username,
                                      api_key=self.password,
                                      project_id=self.tenant,
                                      auth_url=self.auth_url)

        self.glanceclient = glance(GLANCE_CLIENT_VERSION,
                                   endpoint=self.image_endpoint,
                                   token=self.token)

        self.neutronclient = neutron.Client(NEUTRON_CLIENT_VERSION,
                                            endpoint_url=self.neutron_endpoint,
                                            token=self.token)

        self.cinderclient = cinder.Client(CINDER_CLIENT_VERSION, self.username,
                                          self.password, self.tenant,
                                          self.auth_url)
Example #3
0
    def __init__(self, config, cloud_prefix='SRC'):
        self.filtering_utils = FilteringUtils()
        self.config = config
        self.username = os.environ['%s_OS_USERNAME' % cloud_prefix]
        self.password = os.environ['%s_OS_PASSWORD' % cloud_prefix]
        self.tenant = os.environ['%s_OS_TENANT_NAME' % cloud_prefix]
        self.auth_url = os.environ['%s_OS_AUTH_URL' % cloud_prefix]
        self.image_endpoint = os.environ['%s_OS_IMAGE_ENDPOINT' % cloud_prefix]
        self.neutron_endpoint = os.environ['%s_OS_NEUTRON_ENDPOINT' %
                                           cloud_prefix]

        self.keystoneclient = keystone.Client(auth_url=self.auth_url,
                                              username=self.username,
                                              password=self.password,
                                              tenant_name=self.tenant)
        self.keystoneclient.authenticate()
        self.token = self.keystoneclient.auth_token

        self.novaclient = nova.Client(self.config.NOVA_CLIENT_VERSION,
                                      username=self.username,
                                      api_key=self.password,
                                      project_id=self.tenant,
                                      auth_url=self.auth_url)

        self.glanceclient = glance(self.config.GLANCE_CLIENT_VERSION,
                                   endpoint=self.image_endpoint,
                                   token=self.token)

        self.neutronclient = neutron.Client(self.config.NEUTRON_CLIENT_VERSION,
                                            endpoint_url=self.neutron_endpoint,
                                            token=self.token)

        self.cinderclient = cinder.Client(self.config.CINDER_CLIENT_VERSION,
                                          self.username, self.password,
                                          self.tenant, self.auth_url)
        # will be filled during create all networking step
        self.ext_net_id = None
 def setUp(self):
     self.migration_utils = FilteringUtils()
     self.src_cloud = Prerequisites(cloud_prefix='SRC')
     self.dst_cloud = Prerequisites(cloud_prefix='DST')
     src_vms = [x.__dict__ for x in
                self.src_cloud.novaclient.servers.list(
                    search_opts={'all_tenants': 1})]
     self.dst_vms = [x.__dict__ for x in
                     self.dst_cloud.novaclient.servers.list(
                         search_opts={'all_tenants': 1})]
     src_vms = [vm for vm in src_vms if vm['status'] != 'ERROR']
     self.dst_vm_indexes = []
     for vm in src_vms:
         if vm['name'] not in config.vms_not_in_filter:
             self.dst_vm_indexes.append([x['name'] for x in self.dst_vms].index(
                 vm['name']))
     with open('pre_migration_vm_states.json') as data_file:
         self.before_migr_states = json.load(data_file)
     self.filter_vms = self.migration_utils.filter_vms(src_vms)
Example #5
0
class Prerequisites():
    def __init__(self, cloud_prefix='SRC'):
        self.filtering_utils = FilteringUtils()
        self.username = os.environ['%s_OS_USERNAME' % cloud_prefix]
        self.password = os.environ['%s_OS_PASSWORD' % cloud_prefix]
        self.tenant = os.environ['%s_OS_TENANT_NAME' % cloud_prefix]
        self.auth_url = os.environ['%s_OS_AUTH_URL' % cloud_prefix]
        self.image_endpoint = os.environ['%s_OS_IMAGE_ENDPOINT' % cloud_prefix]
        self.neutron_endpoint = os.environ['%s_OS_NEUTRON_ENDPOINT'
                                           % cloud_prefix]

        self.keystoneclient = keystone.Client(auth_url=self.auth_url,
                                              username=self.username,
                                              password=self.password,
                                              tenant_name=self.tenant)
        self.keystoneclient.authenticate()
        self.token = self.keystoneclient.auth_token

        self.novaclient = nova.Client(NOVA_CLIENT_VERSION,
                                      username=self.username,
                                      api_key=self.password,
                                      project_id=self.tenant,
                                      auth_url=self.auth_url)

        self.glanceclient = glance(GLANCE_CLIENT_VERSION,
                                   endpoint=self.image_endpoint,
                                   token=self.token)

        self.neutronclient = neutron.Client(NEUTRON_CLIENT_VERSION,
                                            endpoint_url=self.neutron_endpoint,
                                            token=self.token)

        self.cinderclient = cinder.Client(CINDER_CLIENT_VERSION, self.username,
                                          self.password, self.tenant,
                                          self.auth_url)

    def get_tenant_id(self, tenant_name):
        tenants = self.keystoneclient.tenants.list()
        return [x for x in tenants if x.name == tenant_name][0].id

    def get_user_id(self, user_name):
        users = self.keystoneclient.users.list()
        return [x for x in users if x.name == user_name][0].id

    def get_router_id(self, router):
        return self.neutronclient.list_routers(name=router)['routers'][0]['id']

    def get_image_id(self, image_name):
        images = self.glanceclient.images.list()
        return [x for x in images if x.name == image_name][0].id

    def get_flavor_id(self, flavor_name):
        flavors = self.novaclient.flavors.list()
        return [x for x in flavors if x.name == flavor_name][0].id

    def get_vm_id(self, vm_name):
        vms = self.novaclient.servers.list(search_opts={'all_tenants': 1})
        return [x for x in vms if x.name == vm_name][0].id

    def get_role_id(self, role):
        roles = self.keystoneclient.roles.list()
        return [x for x in roles if x.name == role][0].id

    def get_net_id(self, net):
        return self.neutronclient.list_networks(
            name=net, all_tenants=True)['networks'][0]['id']

    def get_sg_id(self, sg):
        return self.neutronclient.list_security_groups(
            name=sg, all_tenants=True)['security_groups'][0]['id']

    def get_volume_id(self, volume_name):
        volumes = self.cinderclient.volumes.list(
            search_opts={'all_tenants': 1})
        return [x for x in volumes if x.display_name == volume_name][0].id

    def get_volume_snapshot_id(self, snapshot_name):
        snapshots = self.cinderclient.volume_snapshots.list(
            search_opts={'all_tenants': 1})
        return [x for x in snapshots if x.display_name == snapshot_name][0].id

    def check_vm_state(self, srv):
        while srv.status != 'ACTIVE':
                time.sleep(2)
                srv = self.novaclient.servers.get(srv.id)
                if srv.status == 'ERROR':
                    return None

    def wait_for_volume(self, volume_name):
        vlm = self.cinderclient.volumes.get(self.get_volume_id(volume_name))
        while vlm.status != 'available' and vlm.status != 'in-use':
            time.sleep(2)
            vlm = self.cinderclient.volumes.get(
                self.get_volume_id(volume_name))
            if vlm.status == 'error':
                    return None

    def switch_user(self, user, password, tenant):
        self.keystoneclient = keystone.Client(auth_url=self.auth_url,
                                              username=user,
                                              password=password,
                                              tenant_name=tenant)
        self.keystoneclient.authenticate()
        self.token = self.keystoneclient.auth_token
        self.novaclient = nova.Client(NOVA_CLIENT_VERSION, username=user,
                                      api_key=password, project_id=tenant,
                                      auth_url=self.auth_url)
        self.glanceclient = glance(GLANCE_CLIENT_VERSION,
                                   endpoint=self.image_endpoint,
                                   token=self.token)
        self.neutronclient = neutron.Client(
            NEUTRON_CLIENT_VERSION,
            endpoint_url=self.neutron_endpoint,
            token=self.token)
        self.cinderclient = cinder.Client(CINDER_CLIENT_VERSION, user,
                                          password, tenant, self.auth_url)

    def create_users(self):
        for user in config.users:
            self.keystoneclient.users.create(name=user['name'],
                                             password=user['password'],
                                             email=user['email'],
                                             enabled=user['enabled'],
                                             tenant_id=self.get_tenant_id(
                                                 user['tenant']))

    def create_roles(self):
        for role in config.roles:
            self.keystoneclient.roles.create(name=role['name'])

    def create_tenants(self):
        for tenant in config.tenants:
            self.keystoneclient.tenants.create(tenant_name=tenant['name'],
                                               description=tenant[
                                                   'description'],
                                               enabled=tenant['enabled'])
            self.keystoneclient.roles.add_user_role(
                self.get_user_id(self.username),
                self.get_role_id('admin'),
                self.get_tenant_id(tenant['name']))

    def create_keypairs(self):
        for user, keypair in zip(config.users, config.keypairs):
            self.switch_user(user=user['name'], password=user['password'],
                             tenant=user['tenant'])
            self.novaclient.keypairs.create(**keypair)
        self.switch_user(user=self.username, password=self.password,
                         tenant=self.tenant)

    def modify_quotas(self):
        for tenant in config.tenants:
            if 'quota' in tenant:
                self.novaclient.quotas.update(tenant_id=self.get_tenant_id(
                    tenant['name']), **tenant['quota'])

    def upload_image(self):
        for image in config.images:
            img = self.glanceclient.images.create(**image)
            while img.status != 'active':
                time.sleep(2)
                img = self.glanceclient.images.get(img.id)
        src_cloud = Prerequisites(cloud_prefix='SRC')
        src_img = [x.__dict__ for x in
                   src_cloud.glanceclient.images.list()]
        for image in src_img:
            if image['name'] in config.img_to_add_members:
                image_id = image['id']
                tenant_list = self.keystoneclient.tenants.list()
                for tenant in tenant_list:
                    tenant = tenant.__dict__
                    if tenant['name'] in config.members:
                        member_id = tenant['id']
                        self.glanceclient.image_members.create(image_id, member_id)

    def update_filtering_file(self):
        src_cloud = Prerequisites(cloud_prefix='SRC')
        src_img = [x.__dict__ for x in
                   src_cloud.glanceclient.images.list()]
        src_vms = [x.__dict__ for x in
                   src_cloud.novaclient.servers.list(
                       search_opts={'all_tenants': 1})]
        image_dict = {}
        for image in src_img:
            img_members = self.glanceclient.image_members.list(image['id'])
            if len(img_members) > 1:
                img_mem_list = []
                for img_member in img_members:
                    img_member = img_member.__dict__
                    img_mem_list.append(img_member['member_id'])
                image_dict[image['id']] = img_mem_list
        vm_id_list = []
        for vm in src_vms:
            vm_id = vm['id']
            vm_id_list.append(vm_id)
        loaded_data = self.filtering_utils.load_file()
        filter_dict = loaded_data[0]
        if filter_dict is None:
            filter_dict = {'images': {'images_list': {}}, 'instances': {'id': {}}}
        all_img_ids = []
        img_list = []
        not_incl_img = []
        vm_list = []
        for image in src_img:
            all_img_ids.append(image['id'])
        for img in config.images_not_included_in_filter:
            not_incl_img.append(self.get_image_id(img))
        for key in filter_dict.keys():
            if key == 'images':
                for img_id in all_img_ids:
                    if img_id not in not_incl_img:
                        img_list.append(img_id)
                filter_dict[key]['images_list'] = img_list
            elif key == 'instances':
                for vm in vm_id_list:
                    if vm != self.get_vm_id('not_in_filter'):
                        vm_list.append(vm)
                filter_dict[key]['id'] = vm_list
        file_path = loaded_data[1]
        with open(file_path, "w") as f:
            yaml.dump(filter_dict, f, default_flow_style=False)

    def create_flavors(self):
        for flavor in config.flavors:
            self.novaclient.flavors.create(**flavor)

    def create_vms(self):
        for vm in config.vms:
            vm['image'] = self.get_image_id(vm['image'])
            vm['flavor'] = self.get_flavor_id(vm['flavor'])
            self.check_vm_state(self.novaclient.servers.create(**vm))
        for tenant in config.tenants:
            if 'vms' in tenant:
                for user in config.users:
                    if user['tenant'] == tenant['name'] and user['enabled']:
                        self.switch_user(user=user['name'],
                                         password=user['password'],
                                         tenant=user['tenant'])
                for vm in tenant['vms']:
                    vm['image'] = self.get_image_id(vm['image'])
                    vm['flavor'] = self.get_flavor_id(vm['flavor'])
                    if 'nics' in vm:
                        for nic in vm['nics']:
                            nic['net-id'] = self.get_net_id(nic['net-id'])
                    self.check_vm_state(self.novaclient.servers.create(**vm))
                self.switch_user(user=self.username, password=self.password,
                                 tenant=tenant['name'])
        self.switch_user(user=self.username, password=self.password,
                         tenant=self.tenant)

    def create_vm_snapshots(self):
        for snapshot in config.snapshots:
            self.novaclient.servers.create_image(
                server=self.get_vm_id(snapshot['server']),
                image_name=snapshot['image_name'])

    def create_networks(self, network_list, subnet_list):
        for network, subnet in zip(network_list, subnet_list):
            net = self.neutronclient.create_network({'network': network})
            subnet['network_id'] = net['network']['id']
            self.neutronclient.create_subnet({'subnet': subnet})

    def create_router(self, router_list):
        for router in router_list:
            router['router']['external_gateway_info']['network_id'] = \
                self.get_net_id(
                    router['router']['external_gateway_info']['network_id'])
            self.neutronclient.create_router(router)

    def create_all_networking(self):
        self.create_networks(config.networks, config.subnets)
        ext_net_id = [self.get_net_id(net['name']) for net in config.networks
                      if 'router:external' in net and net['router:external']
                      ][0]
        for tenant in config.tenants:
            if tenant['networks']:
                self.switch_user(user=self.username, password=self.password,
                                 tenant=tenant['name'])
                self.create_networks(tenant['networks'], tenant['subnets'])
                self.neutronclient.create_floatingip(
                    {"floatingip": {"floating_network_id": ext_net_id}})
        self.switch_user(user=self.username, password=self.password,
                         tenant=self.tenant)
        self.create_router(config.routers)

    def create_security_group(self, sg_list):
        for security_group in sg_list:
            gid = self.novaclient.security_groups.create(
                name=security_group['name'],
                description=security_group['description']).id
            if 'rules' in security_group:
                for rule in security_group['rules']:
                    self.novaclient.security_group_rules.create(
                        gid,
                        ip_protocol=rule['ip_protocol'],
                        from_port=rule['from_port'], to_port=rule['to_port'],
                        cidr=rule['cidr'])

    def create_security_groups(self):
        for tenant in config.tenants:
            if 'security_groups' in tenant:
                self.switch_user(user=self.username, password=self.password,
                                 tenant=tenant['name'])
                self.create_security_group(tenant['security_groups'])
        self.switch_user(user=self.username, password=self.password,
                         tenant=self.tenant)

    def get_sec_group_id_by_tenant_id(self, tenant_id):
        sec_group_list = self.neutronclient.list_security_groups()
        return [i['id'] for i in sec_group_list['security_groups']
                if i['tenant_id'] == tenant_id]

    def create_security_group_rule(self, group_id, tenant_id, protocol='tcp',
                                   port_range_min=22, port_range_max=22,
                                   direction ='ingress'):
        sec_rule = {'security_group_rule':
                        {"security_group_id":group_id, "protocol":protocol,
                         "direction" : direction, 'tenant_id': tenant_id,
                         "port_range_min":port_range_min,
                         "port_range_max":port_range_max}}
        self.neutronclient.create_security_group_rule(sec_rule)

    def create_cinder_volumes(self, volumes_list):
        for volume in volumes_list:
            vlm = self.cinderclient.volumes.create(display_name=volume['name'],
                                                   size=volume['size'])
            self.wait_for_volume(volume['name'])
            if 'server_to_attach' in volume:
                self.novaclient.volumes.create_server_volume(
                    server_id=self.get_vm_id(volume['server_to_attach']),
                    volume_id=vlm.id,
                    device=volume['device'])
            self.wait_for_volume(volume['name'])

    def create_cinder_snapshots(self, snapshot_list):
        for snapshot in snapshot_list:
            self.cinderclient.volume_snapshots.create(**snapshot)

    def create_cinder_objects(self):
        self.create_cinder_volumes(config.cinder_volumes)
        self.create_cinder_snapshots(config.cinder_snapshots)
        for tenant in config.tenants:
            if 'cinder_volumes' in tenant:
                self.switch_user(user=self.username, password=self.password,
                                 tenant=tenant['name'])
                self.create_cinder_volumes(tenant['cinder_volumes'])
                if 'cinder_snapshots' in tenant:
                    self.create_cinder_snapshots(tenant['cinder_snapshots'])
        self.switch_user(user=self.username, password=self.password,
                         tenant=self.tenant)

    def emulate_vm_states(self):
        for vm_state in config.vm_states:
            # emulate error state:
            if vm_state['state'] == u'error':
                self.novaclient.servers.reset_state(
                    server=self.get_vm_id(vm_state['name']),
                    state=vm_state['state'])
            # emulate suspend state:
            elif vm_state['state'] == u'suspend':
                self.novaclient.servers.suspend(self.get_vm_id(vm_state['name']))
            # emulate resize state:
            elif vm_state['state'] == u'pause':
                self.novaclient.servers.pause(self.get_vm_id(vm_state['name']))
            # emulate stop/shutoff state:
            elif vm_state['state'] == u'stop':
                self.novaclient.servers.stop(self.get_vm_id(vm_state['name']))
            # emulate resize state:
            elif vm_state['state'] == u'resize':
                self.novaclient.servers.resize(self.get_vm_id(vm_state['name']),
                                               '1')

    def generate_vm_state_list(self):
        data = {}
        for vm in self.novaclient.servers.list():
            vm_name = vm.name
            index = self.novaclient.servers.list().index(vm)
            while self.novaclient.servers.list()[index].status == u'RESIZE':
                time.sleep(2)
            vm_state = self.novaclient.servers.list()[index].status
            data[vm_name] = vm_state
        file_name = 'pre_migration_vm_states.json'
        with open(file_name, 'w') as outfile:
            json.dump(data, outfile, sort_keys=True, indent=4, ensure_ascii=False)

    def delete_flavor(self, flavor='del_flvr'):
        """
        Method for flavor deletion.
        """
        try:
            self.novaclient.flavors.delete(
                self.get_flavor_id(flavor))
        except Exception as e:
            print "Flavor %s failed to delete: %s" % (flavor, repr(e))

    def modify_admin_tenant_quotas(self):
        for tenant in config.tenants:
            if 'quota' in tenant:
                self.novaclient.quotas.update(tenant_id=self.get_tenant_id(
                    'admin'), **tenant['quota'])
                break

    def run_preparation_scenario(self):
        print('>>> Creating tenants:')
        self.create_tenants()
        print('>>> Creating users:')
        self.create_users()
        print('>>> Creating roles:')
        self.create_roles()
        print('>>> Creating keypairs:')
        self.create_keypairs()
        print('>>> Modifying quotas:')
        self.modify_quotas()
        print('>>> Creating flavors:')
        self.create_flavors()
        print('>>> Uploading images:')
        self.upload_image()
        print('>>> Creating networking:')
        self.create_all_networking()
        print('>>> Creating vms:')
        self.create_vms()
        print('>>> Updating filtering:')
        self.update_filtering_file()
        print('>>> Creating vm snapshots:')
        self.create_vm_snapshots()
        print('>>> Creating security groups:')
        self.create_security_groups()
        print('>>> Creating cinder objects:')
        self.create_cinder_objects()
        print('>>> Emulating vm states:')
        self.emulate_vm_states()
        print('>>> Generating vm states list:')
        self.generate_vm_state_list()
        print('>>> Deleting flavor:')
        self.delete_flavor()
        print('>>> Modifying admin tenant quotas:')
        self.modify_admin_tenant_quotas()

    def clean_objects(self):
        for flavor in config.flavors:
            try:
                self.novaclient.flavors.delete(
                    self.get_flavor_id(flavor['name']))
            except Exception as e:
                print "Flavor %s failed to delete: %s" % (flavor['name'],
                                                          repr(e))
        vms = config.vms
        vms += itertools.chain(*[tenant['vms'] for tenant
                                 in config.tenants if tenant['vms']])
        for vm in vms:
            try:
                self.novaclient.servers.delete(self.get_vm_id(vm['name']))
            except Exception as e:
                print "VM %s failed to delete: %s" % (vm['name'], repr(e))
        for image in config.images:
            try:
                self.glanceclient.images.delete(
                    self.get_image_id(image['name']))
            except Exception as e:
                print "Image %s failed to delete: %s" % (image['name'],
                                                         repr(e))
        nets = config.networks
        nets += itertools.chain(*[tenant['networks'] for tenant
                                  in config.tenants if tenant['networks']])
        floatingips = self.neutronclient.list_floatingips()['floatingips']
        for ip in floatingips:
            try:
                self.neutronclient.delete_floatingip(ip['id'])
            except Exception as e:
                print "Ip %s failed to delete: %s" % (
                    ip['floating_ip_address'], repr(e))
        for router in config.routers:
            try:
                self.neutronclient.delete_router(self.get_router_id(
                    router['router']['name']))
            except Exception as e:
                print "Router failed to delete: %s" % repr(e)
        for network in nets:
            try:
                self.neutronclient.delete_network(self.get_net_id(
                    network['name']))
            except Exception as e:
                print "Network %s failed to delete: %s" % (network['name'],
                                                           repr(e))
        for snapshot in config.snapshots:
            try:
                self.glanceclient.images.delete(
                    self.get_image_id(snapshot['image_name']))
            except Exception as e:
                print "Image %s failed to delete: %s" % (
                    snapshot['image_name'], repr(e))
        for tenant in config.tenants:
            try:
                self.keystoneclient.tenants.delete(
                    self.get_tenant_id(tenant['name']))
            except Exception as e:
                print "Tenant %s failed to delete: %s" % (tenant['name'],
                                                          repr(e))
        sgs = self.neutronclient.list_security_groups()['security_groups']
        for sg in sgs:
            try:
                print "delete sg {}".format(sg['name'])
                self.neutronclient.delete_security_group(self.get_sg_id(
                                                         sg['name']))
            except Exception as e:
                print "Security group %s failed to delete: %s" % (sg['name'],
                                                                  repr(e))
        for user in config.users:
            try:
                self.keystoneclient.users.delete(
                    self.get_user_id(user['name']))
            except Exception as e:
                print "User %s failed to delete: %s" % (user['name'], repr(e))
        for role in config.roles:
            try:
                self.keystoneclient.roles.delete(self.get_role_id(
                    role['name']))
            except Exception as e:
                print "Role %s failed to delete: %s" % (role['name'], repr(e))
        snapshots = config.cinder_snapshots
        snapshots += itertools.chain(*[tenant['cinder_snapshots'] for tenant
                                       in config.tenants if 'cinder_snapshots'
                                       in tenant])
        for snapshot in snapshots:
            try:
                self.cinderclient.volume_snapshots.delete(
                    self.get_volume_snapshot_id(snapshot['display_name']))
            except Exception as e:
                print "Snapshot %s failed to delete: %s" % (
                    snapshot['display_name'], repr(e))
        volumes = config.cinder_volumes
        volumes += itertools.chain(*[tenant['cinder_volumes'] for tenant
                                     in config.tenants if 'cinder_volumes'
                                     in tenant])
        for volume in volumes:
            try:
                self.cinderclient.volumes.delete(
                    self.get_volume_id(volume['name']))
            except Exception as e:
                print "Volume %s failed to delete: %s" % (volume['name'],
                                                          repr(e))
Example #6
0
class RollbackScenarioGeneration(object):
    def __init__(self):
        self.migration_utils = FilteringUtils()
        self.file_path = 'devlab/tests/scenarios/cold_migrate.yaml'
        self.main_folder = self.migration_utils.main_folder
        self.full_path = os.path.join(self.main_folder, self.file_path)
        self.exception_task = {'fail_migration': True}
        self.steps_list = []

    def _read_migrationation_file(self):
        migration_data = self.migration_utils.load_file(self.file_path)[0]
        return migration_data

    @staticmethod
    def _dump_into_file(file_path, data):
        with open(file_path, "w") as f:
            yaml.dump(data, f, default_flow_style=False)

    @staticmethod
    def _verification(_step):
        if isinstance(_step, dict):
            if isinstance(_step.values()[0], bool) or \
                    isinstance(_step.values()[0], list) and \
                    len(_step.values()[0]) == 1:
                return True

    def _get_list_of_tasks(self, search_dict):
        for key, value in search_dict.iteritems():
            if self._verification(search_dict):
                self.steps_list.append(search_dict)
            elif isinstance(value, list):
                for item in value:
                    self._get_list_of_tasks(item)
            elif isinstance(value, dict):
                self._get_list_of_tasks(value)
        return self.steps_list

    def _insert_break_point(self, search_dict, field):
        for key, value in search_dict.iteritems():
            if isinstance(value, dict):
                if self._verification(value):
                    return
                else:
                    self._insert_break_point(value, field)
            elif isinstance(value, list):
                if field in value:
                    index = value.index(field) + 1
                    value.insert(index, self.exception_task)
                    return
                else:
                    for item in value:
                        if isinstance(item, dict):
                            self._insert_break_point(item, field)

    def _find_break_point(self, search_dict, field):
        fields_found = []
        for key, value in search_dict.iteritems():
            if key == field:
                fields_found.append(value)
            elif isinstance(value, dict):
                results = self._find_break_point(value, field)
                for result in results:
                    fields_found.append(result)
            elif isinstance(value, list):
                for item in value:
                    if isinstance(item, dict):
                        more_results = self._find_break_point(item, field)
                        for another_result in more_results:
                            fields_found.append(another_result)
        return fields_found

    def generate_exception_task_in_random_point(self):
        migration_data = self._read_migrationation_file()
        data = None
        for key, value in migration_data.iteritems():
            if key == 'process':
                data = {key: value}
        list_of_steps = self._get_list_of_tasks(data)
        random_step = random.choice(list_of_steps)
        self._insert_break_point(data, random_step)
        print('\n\nBreak point was set after:\n{}, index: {}\n\n'.format(
            random_step, list_of_steps.index(random_step)))
        try:
            assert(self._find_break_point(migration_data,
                                          self.exception_task.keys()[0])
                   == self.exception_task.values())
            self._dump_into_file(self.full_path, migration_data)
        except Exception as e:
            print('Integration of failure step into migration scenario failed '
                  'with following error: \n\n{}'.format(e))
Example #7
0
class Prerequisites(object):
    def __init__(self, config, cloud_prefix='SRC'):
        self.filtering_utils = FilteringUtils()
        self.config = config
        self.username = os.environ['%s_OS_USERNAME' % cloud_prefix]
        self.password = os.environ['%s_OS_PASSWORD' % cloud_prefix]
        self.tenant = os.environ['%s_OS_TENANT_NAME' % cloud_prefix]
        self.auth_url = os.environ['%s_OS_AUTH_URL' % cloud_prefix]
        self.image_endpoint = os.environ['%s_OS_IMAGE_ENDPOINT' % cloud_prefix]
        self.neutron_endpoint = os.environ['%s_OS_NEUTRON_ENDPOINT'
                                           % cloud_prefix]

        self.keystoneclient = keystone.Client(auth_url=self.auth_url,
                                              username=self.username,
                                              password=self.password,
                                              tenant_name=self.tenant)
        self.keystoneclient.authenticate()
        self.token = self.keystoneclient.auth_token

        self.novaclient = nova.Client(self.config.NOVA_CLIENT_VERSION,
                                      username=self.username,
                                      api_key=self.password,
                                      project_id=self.tenant,
                                      auth_url=self.auth_url)

        self.glanceclient = glance(self.config.GLANCE_CLIENT_VERSION,
                                   endpoint=self.image_endpoint,
                                   token=self.token)

        self.neutronclient = neutron.Client(self.config.NEUTRON_CLIENT_VERSION,
                                            endpoint_url=self.neutron_endpoint,
                                            token=self.token)

        self.cinderclient = cinder.Client(self.config.CINDER_CLIENT_VERSION,
                                          self.username, self.password,
                                          self.tenant, self.auth_url)
        # will be filled during create all networking step
        self.ext_net_id = None

    def get_tenant_id(self, tenant_name):
        tenants = self.keystoneclient.tenants.list()
        return [x for x in tenants if x.name == tenant_name][0].id

    def get_user_id(self, user_name):
        users = self.keystoneclient.users.list()
        return [x for x in users if x.name == user_name][0].id

    def get_router_id(self, router):
        return self.neutronclient.list_routers(name=router)['routers'][0]['id']

    def get_image_id(self, image_name):
        images = self.glanceclient.images.list()
        return [x for x in images if x.name == image_name][0].id

    def get_flavor_id(self, flavor_name):
        flavors = self.novaclient.flavors.list()
        return [x for x in flavors if x.name == flavor_name][0].id

    def get_vm_id(self, vm_name):
        vms = self.novaclient.servers.list(search_opts={'all_tenants': 1})
        return [x for x in vms if x.name == vm_name][0].id

    def get_role_id(self, role):
        roles = self.keystoneclient.roles.list()
        return [x for x in roles if x.name == role][0].id

    def get_net_id(self, net):
        return self.neutronclient.list_networks(
            name=net, all_tenants=True)['networks'][0]['id']

    def get_sg_id(self, sg):
        return self.neutronclient.list_security_groups(
            name=sg, all_tenants=True)['security_groups'][0]['id']

    def get_volume_id(self, volume_name):
        volumes = self.cinderclient.volumes.list(
            search_opts={'all_tenants': 1})
        return [x for x in volumes if x.display_name == volume_name][0].id

    def get_volume_snapshot_id(self, snapshot_name):
        snapshots = self.cinderclient.volume_snapshots.list(
            search_opts={'all_tenants': 1})
        return [x for x in snapshots if x.display_name == snapshot_name][0].id

    def get_user_tenant_roles(self, user):
        user_tenant_roles = []
        for tenant in self.keystoneclient.tenants.list():
            user_tenant_roles.extend(self.keystoneclient.roles.roles_for_user(
                user=self.get_user_id(user.name),
                tenant=self.get_tenant_id(tenant.name)))
        return user_tenant_roles

    def get_ext_routers(self):
        routers = self.neutronclient.list_routers()['routers']
        ext_routers = [router for router in routers
                       if router['external_gateway_info']]
        return ext_routers

    def check_vm_state(self, srv):
        srv = self.novaclient.servers.get(srv)
        return srv.status == 'ACTIVE'

    def switch_user(self, user, password, tenant):
        self.keystoneclient = keystone.Client(auth_url=self.auth_url,
                                              username=user,
                                              password=password,
                                              tenant_name=tenant)
        self.keystoneclient.authenticate()
        self.token = self.keystoneclient.auth_token
        self.novaclient = nova.Client(self.config.NOVA_CLIENT_VERSION,
                                      username=user,
                                      api_key=password, project_id=tenant,
                                      auth_url=self.auth_url)
        self.glanceclient = glance(self.config.GLANCE_CLIENT_VERSION,
                                   endpoint=self.image_endpoint,
                                   token=self.token)
        self.neutronclient = neutron.Client(
            self.config.NEUTRON_CLIENT_VERSION,
            endpoint_url=self.neutron_endpoint,
            token=self.token)
        self.cinderclient = cinder.Client(self.config.CINDER_CLIENT_VERSION,
                                          user, password, tenant,
                                          self.auth_url)

    def create_users(self):
        def get_params_for_user_creating(_user):
            if 'tenant' in _user:
                _user['tenant_id'] = self.get_tenant_id(_user['tenant'])
            params = ['name', 'password', 'email', 'enabled', 'tenant_id']
            return {param: _user[param] for param in params if param in _user}

        for user in self.config.users:
            self.keystoneclient.users.create(
                **get_params_for_user_creating(user))
            if not user.get('additional_tenants'):
                continue
            for tenant in user['additional_tenants']:
                self.keystoneclient.roles.add_user_role(
                    tenant=self.get_tenant_id(tenant['name']),
                    role=self.get_role_id(tenant['role']),
                    user=self.get_user_id(user['name']))
            # Next action for default sec group creation
            if not user['enabled'] or 'tenant' not in user:
                continue
            self.switch_user(user=user['name'], password=user['password'],
                             tenant=user['tenant'])
            self.novaclient.security_groups.list()
            self.switch_user(user=self.username, password=self.password,
                             tenant=self.tenant)

    def create_roles(self):
        for role in self.config.roles:
            self.keystoneclient.roles.create(name=role['name'])

    def create_tenants(self):
        for tenant in self.config.tenants:
            self.keystoneclient.tenants.create(tenant_name=tenant['name'],
                                               description=tenant[
                                                   'description'],
                                               enabled=tenant['enabled'])
            self.keystoneclient.roles.add_user_role(
                self.get_user_id(self.username),
                self.get_role_id('admin'),
                self.get_tenant_id(tenant['name']))

    def create_keypairs(self):
        for user, keypair in zip(self.config.users, self.config.keypairs):
            self.switch_user(user=user['name'], password=user['password'],
                             tenant=user['tenant'])
            self.novaclient.keypairs.create(**keypair)
        self.switch_user(user=self.username, password=self.password,
                         tenant=self.tenant)

    def modify_quotas(self):
        for tenant in self.config.tenants:
            if 'quota' in tenant:
                self.novaclient.quotas.update(tenant_id=self.get_tenant_id(
                    tenant['name']), **tenant['quota'])

    def upload_image(self):
        @retry_until_resources_created('image')
        def wait_until_images_created(image_ids):
            for img_id in image_ids[:]:
                img = self.glanceclient.images.get(img_id)
                if img.status == 'active':
                    image_ids.remove(img_id)
            return image_ids

        img_ids = []
        for tenant in self.config.tenants:
            if not tenant.get('images'):
                continue
            for image in tenant['images']:
                self.switch_user(user=self.username, password=self.password,
                                 tenant=tenant['name'])
                img = self.glanceclient.images.create(**image)
                img_ids.append(img.id)
        self.switch_user(user=self.username, password=self.password,
                         tenant=self.tenant)
        for image in self.config.images:
            img = self.glanceclient.images.create(**image)
            img_ids.append(img.id)
        wait_until_images_created(img_ids)
        src_cloud = Prerequisites(cloud_prefix='SRC', config=self.config)
        src_img = [x.__dict__ for x in
                   src_cloud.glanceclient.images.list()]
        for image in src_img:
            if image['name'] in self.config.img_to_add_members:
                image_id = image['id']
                tenant_list = self.keystoneclient.tenants.list()
                for tenant in tenant_list:
                    tenant = tenant.__dict__
                    if tenant['name'] in self.config.members:
                        member_id = tenant['id']
                        self.glanceclient.image_members.create(image_id,
                                                               member_id)

    def update_filtering_file(self):
        src_cloud = Prerequisites(cloud_prefix='SRC', config=self.config)
        src_img = [x.__dict__ for x in
                   src_cloud.glanceclient.images.list()]
        src_vms = [x.__dict__ for x in
                   src_cloud.novaclient.servers.list(
                       search_opts={'all_tenants': 1})]
        image_dict = {}
        for image in src_img:
            img_members = self.glanceclient.image_members.list(image['id'])
            if len(img_members) > 1:
                img_mem_list = []
                for img_member in img_members:
                    img_member = img_member.__dict__
                    img_mem_list.append(img_member['member_id'])
                image_dict[image['id']] = img_mem_list
        vm_id_list = []
        for vm in src_vms:
            vm_id = vm['id']
            vm_id_list.append(vm_id)
        loaded_data = self.filtering_utils.load_file('configs/filter.yaml')
        filter_dict = loaded_data[0]
        if filter_dict is None:
            filter_dict = {'images': {'images_list': {}},
                           'instances': {'id': {}}}
        all_img_ids = []
        img_list = []
        not_incl_img = []
        vm_list = []
        for image in src_img:
            all_img_ids.append(image['id'])
        for img in self.config.images_not_included_in_filter:
            not_incl_img.append(self.get_image_id(img))
        for key in filter_dict.keys():
            if key == 'images':
                for img_id in all_img_ids:
                    if img_id not in not_incl_img:
                        img_list.append(img_id)
                filter_dict[key]['images_list'] = img_list
            elif key == 'instances':
                for vm in vm_id_list:
                    if vm != self.get_vm_id('not_in_filter'):
                        vm_list.append(vm)
                filter_dict[key]['id'] = vm_list
        file_path = loaded_data[1]
        with open(file_path, "w") as f:
            yaml.dump(filter_dict, f, default_flow_style=False)

    def create_flavors(self):
        for flavor in self.config.flavors:
            self.novaclient.flavors.create(**flavor)

    def create_vms(self):
        def get_vm_nics(_vm):
            if 'nics' in _vm:
                for _nic in _vm['nics']:
                    _nic['net-id'] = self.get_net_id(_nic['net-id'])
                return _vm['nics']
            nets = self.neutronclient.list_networks()['networks']
            _t = self.keystoneclient.tenant_id
            nics = [{'net-id': net['id']} for net in nets
                    if not net['router:external'] and net['tenant_id'] == _t]
            return nics

        def get_parameters_for_vm_creating(_vm):
            return {'image': self.get_image_id(_vm['image']),
                    'flavor': self.get_flavor_id(_vm['flavor']),
                    'nics': get_vm_nics(_vm),
                    'name': _vm['name']
                    }

        def wait_vm_nic_created(vm_id):
            for i in range(TIMEOUT):
                srv = self.novaclient.servers.get(vm_id)
                if srv.networks:
                    break
            else:
                raise RuntimeError(
                    'NIC for vm with id {0} was not created'.format(vm_id))

        def wait_for_vm_creating():
            """ When limit for creating vms in nova is reached, we receive
                exception from nova: 'novaclient.exceptions.OverLimit:
                This request was rate-limited. (HTTP 413)'. To handle this we
                set limit for vm spawning.
            """
            for i in range(TIMEOUT):
                all_vms = self.novaclient.servers.list(
                    search_opts={'all_tenants': 1})
                spawning_vms = [vm.id for vm in all_vms
                                if vm.status == 'BUILD']
                if len(spawning_vms) >= VM_SPAWNING_LIMIT:
                    time.sleep(1)
                else:
                    break
            else:
                raise RuntimeError(
                    'VMs with ids {0} were in "BUILD" state more than {1} '
                    'seconds'.format(spawning_vms, TIMEOUT))

        def create_vms(vm_list):
            vm_ids = []
            for vm in vm_list:
                wait_for_vm_creating()
                _vm = self.novaclient.servers.create(
                    **get_parameters_for_vm_creating(vm))
                vm_ids.append(_vm.id)
                if not vm.get('fip'):
                    continue
                wait_vm_nic_created(_vm.id)
                fip = self.neutronclient.create_floatingip(
                    {"floatingip": {"floating_network_id": self.ext_net_id}})
                _vm.add_floating_ip(fip['floatingip']['floating_ip_address'])
            return vm_ids

        @retry_until_resources_created('vm')
        def wait_until_vms_created(vm_list):
            for vm in vm_list[:]:
                if self.check_vm_state(vm):
                    vms.remove(vm)
            return vms

        vms = create_vms(self.config.vms)
        for tenant in self.config.tenants:
            if not tenant.get('vms'):
                continue
            self.switch_user(user=self.username, password=self.password,
                             tenant=tenant['name'])
            vms.extend(create_vms(tenant['vms']))
        self.switch_user(user=self.username, password=self.password,
                         tenant=self.tenant)

        wait_until_vms_created(vms)

    def create_vm_snapshots(self):
        @retry_until_resources_created('vm_snapshot')
        def wait_until_vm_snapshots_created(snapshot_ids):
            for snp_id in snapshot_ids[:]:
                snp = self.glanceclient.images.get(snp_id)
                if snp.status == 'active':
                    snp_ids.remove(snp_id)
                elif snp.status == 'error':
                    msg = 'Snapshot with id {0} has become in error state'
                    raise RuntimeError(msg.format(snp_id))
            return snapshot_ids

        snp_ids = []
        for snapshot in self.config.snapshots:
            self.novaclient.servers.create_image(
                server=self.get_vm_id(snapshot['server']),
                image_name=snapshot['image_name'])
            snp = self.glanceclient.images.get(self.get_image_id(
                snapshot['image_name']))
            snp_ids.append(snp.id)
        wait_until_vm_snapshots_created(snp_ids)

    def create_networks(self, network_list, subnet_list):
        ext_router_id = self.get_router_id('ext_router')
        for network, subnet in zip(network_list, subnet_list):
            if network.get('router:external'):
                continue
            net = self.neutronclient.create_network({'network': network})
            subnet['network_id'] = net['network']['id']
            subnet = self.neutronclient.create_subnet({'subnet': subnet})
            self.neutronclient.add_interface_router(
                ext_router_id, {"subnet_id": subnet['subnet']['id']})

    def create_router(self, router_list):
        for router in router_list:
            router['router']['external_gateway_info']['network_id'] = \
                self.get_net_id(
                    router['router']['external_gateway_info']['network_id'])
            self.neutronclient.create_router(router)

    def create_external_network(self):
        for network in self.config.networks:
            if network.get('router:external'):
                net = self.neutronclient.create_network({'network': network})
                break
        else:
            raise RuntimeError('Please specify external network in config.py')
        for subnet in self.config.subnets:
            if subnet.get('name') == 'external_subnet':
                subnet['network_id'] = net['network']['id']
                self.neutronclient.create_subnet({'subnet': subnet})
                break
        else:
            raise RuntimeError('Please specify subnet for external network in '
                               'config.py (make sure subnet has field '
                               '"name": "external_subnet").')
        return net['network']['id']

    def create_all_networking(self):
        self.ext_net_id = self.create_external_network()
        self.create_router(self.config.routers)
        self.create_networks(self.config.networks, self.config.subnets)
        for tenant in self.config.tenants:
            if tenant.get('networks'):
                self.switch_user(user=self.username, password=self.password,
                                 tenant=tenant['name'])
                self.create_networks(tenant['networks'], tenant['subnets'])
            if tenant.get('unassociated_fip'):
                for i in range(tenant['unassociated_fip']):
                    self.neutronclient.create_floatingip(
                        {"floatingip": {"floating_network_id": self.ext_net_id}
                         })
        self.switch_user(user=self.username, password=self.password,
                         tenant=self.tenant)

    def create_security_group(self, sg_list):
        for security_group in sg_list:
            gid = self.novaclient.security_groups.create(
                name=security_group['name'],
                description=security_group['description']).id
            if 'rules' in security_group:
                for rule in security_group['rules']:
                    self.novaclient.security_group_rules.create(
                        gid,
                        ip_protocol=rule['ip_protocol'],
                        from_port=rule['from_port'], to_port=rule['to_port'],
                        cidr=rule['cidr'])

    def create_security_groups(self):
        for tenant in self.config.tenants:
            if 'security_groups' in tenant:
                self.switch_user(user=self.username, password=self.password,
                                 tenant=tenant['name'])
                self.create_security_group(tenant['security_groups'])
        self.switch_user(user=self.username, password=self.password,
                         tenant=self.tenant)

    def get_sec_group_id_by_tenant_id(self, tenant_id):
        sec_group_list = self.neutronclient.list_security_groups()
        return [i['id'] for i in sec_group_list['security_groups']
                if i['tenant_id'] == tenant_id]

    def create_security_group_rule(self, group_id, tenant_id, protocol='tcp',
                                   port_range_min=22, port_range_max=22,
                                   direction='ingress'):
        sec_rule = {'security_group_rule': {"security_group_id": group_id,
                                            "protocol": protocol,
                                            "direction": direction,
                                            'tenant_id': tenant_id,
                                            "port_range_min": port_range_min,
                                            "port_range_max": port_range_max}}
        self.neutronclient.create_security_group_rule(sec_rule)

    def create_cinder_volumes(self, volumes_list):

        @retry_until_resources_created('volume')
        def wait_for_volumes(volume_ids):
            for volume_id in volume_ids[:]:
                _vlm = self.cinderclient.volumes.get(volume_id)
                if _vlm.status == 'available' or _vlm.status == 'in-use':
                    volume_ids.remove(volume_id)
                elif _vlm.status == 'error':
                    msg = 'Volume with id {0} was created with error'
                    raise RuntimeError(msg.format(volume_id))
            return volume_ids

        vlm_ids = []
        for volume in volumes_list:
            if 'user' in volume:
                user = [u for u in self.config.users
                        if u['name'] == volume['user']][0]
                self.switch_user(user=user['name'], password=user['password'],
                                 tenant=user['tenant'])
            vlm = self.cinderclient.volumes.create(display_name=volume['name'],
                                                   size=volume['size'])
            vlm_ids.append(vlm.id)
        self.switch_user(user=self.username, password=self.password,
                         tenant=self.tenant)
        wait_for_volumes(vlm_ids)
        vlm_ids = []
        for volume in volumes_list:
            if 'server_to_attach' not in volume:
                continue
            vlm_id = self.get_volume_id(volume['name'])
            self.novaclient.volumes.create_server_volume(
                server_id=self.get_vm_id(volume['server_to_attach']),
                volume_id=vlm_id,
                device=volume['device'])
            vlm_ids.append(vlm_id)
        wait_for_volumes(vlm_ids)

    def create_cinder_snapshots(self, snapshot_list):
        for snapshot in snapshot_list:
            self.cinderclient.volume_snapshots.create(**snapshot)

    def create_cinder_objects(self):
        self.create_cinder_volumes(self.config.cinder_volumes)
        self.create_cinder_snapshots(self.config.cinder_snapshots)
        for tenant in self.config.tenants:
            if 'cinder_volumes' in tenant:
                self.switch_user(user=self.username, password=self.password,
                                 tenant=tenant['name'])
                self.create_cinder_volumes(tenant['cinder_volumes'])
                if 'cinder_snapshots' in tenant:
                    self.create_cinder_snapshots(tenant['cinder_snapshots'])
        self.switch_user(user=self.username, password=self.password,
                         tenant=self.tenant)

    def emulate_vm_states(self):
        for vm_state in self.config.vm_states:
            # emulate error state:
            if vm_state['state'] == u'error':
                self.novaclient.servers.reset_state(
                    server=self.get_vm_id(vm_state['name']),
                    state=vm_state['state'])
            # emulate suspend state:
            elif vm_state['state'] == u'suspend':
                self.novaclient.servers.suspend(self.get_vm_id(
                    vm_state['name']))
            # emulate resize state:
            elif vm_state['state'] == u'pause':
                self.novaclient.servers.pause(self.get_vm_id(vm_state['name']))
            # emulate stop/shutoff state:
            elif vm_state['state'] == u'stop':
                self.novaclient.servers.stop(self.get_vm_id(vm_state['name']))
            # emulate resize state:
            elif vm_state['state'] == u'resize':
                self.novaclient.servers.resize(
                    self.get_vm_id(vm_state['name']), '2')

    def generate_vm_state_list(self):
        data = {}
        for vm in self.novaclient.servers.list(search_opts={'all_tenants': 1}):
            for i in range(TIMEOUT):
                _vm = self.novaclient.servers.get(vm.id)
                if _vm.status != u'RESIZE':
                    break
                time.sleep(1)
            vm_state = self.novaclient.servers.get(vm.id).status
            data[vm.name] = vm_state

        file_name = 'pre_migration_vm_states.json'
        with open(file_name, 'w') as outfile:
            json.dump(data, outfile, sort_keys=True, indent=4,
                      ensure_ascii=False)

    def delete_flavor(self, flavor='del_flvr'):
        """
        Method for flavor deletion.
        """
        try:
            self.novaclient.flavors.delete(
                self.get_flavor_id(flavor))
        except Exception as e:
            print "Flavor %s failed to delete: %s" % (flavor, repr(e))

    def modify_admin_tenant_quotas(self):
        for tenant in self.config.tenants:
            if 'quota' in tenant:
                self.novaclient.quotas.update(tenant_id=self.get_tenant_id(
                    'admin'), **tenant['quota'])
                break

    def delete_users(self):
        for user in self.config.users:
            if user.get('deleted'):
                self.keystoneclient.users.delete(
                    self.get_user_id(user['name']))

    def delete_tenants(self):
        for tenant in self.config.tenants:
            if tenant.get('deleted'):
                self.keystoneclient.tenants.delete(
                    self.get_tenant_id(tenant['name']))

    def create_tenant_wo_sec_group_on_dst(self):
        """
        Method for check fixed issue, when on dst tenant does not have
        security group, even default, while on src this tenant has security
        group.
        """
        dst_cloud = Prerequisites(cloud_prefix='DST', config=self.config)
        for t in self.config.tenants:
            if 'deleted' in t and not t['deleted'] and t['enabled']:
                dst_cloud.keystoneclient.tenants.create(
                    tenant_name=t['name'], description=t['description'],
                    enabled=t['enabled'])

    def run_preparation_scenario(self):
        print('>>> Creating tenants:')
        self.create_tenants()
        print('>>> Creating users:')
        self.create_users()
        print('>>> Creating roles:')
        self.create_roles()
        print('>>> Creating keypairs:')
        self.create_keypairs()
        print('>>> Modifying quotas:')
        self.modify_quotas()
        print('>>> Creating flavors:')
        self.create_flavors()
        print('>>> Uploading images:')
        self.upload_image()
        print('>>> Creating networking:')
        self.create_all_networking()
        print('>>> Creating vms:')
        self.create_vms()
        print('>>> Updating filtering:')
        self.update_filtering_file()
        print('>>> Creating vm snapshots:')
        self.create_vm_snapshots()
        print('>>> Creating security groups:')
        self.create_security_groups()
        print('>>> Creating cinder objects:')
        self.create_cinder_objects()
        print('>>> Emulating vm states:')
        self.emulate_vm_states()
        print('>>> Generating vm states list:')
        self.generate_vm_state_list()
        print('>>> Deleting flavor:')
        self.delete_flavor()
        print('>>> Modifying admin tenant quotas:')
        self.modify_admin_tenant_quotas()
        print('>>> Delete users which should be deleted:')
        self.delete_users()
        print('>>> Delete tenants which should be deleted:')
        self.delete_tenants()
        print('>>> Create tenant on dst, without security group')
        self.create_tenant_wo_sec_group_on_dst()

    def clean_objects(self):
        def clean_router_ports(router_id):
            subnets = self.neutronclient.list_subnets()
            for subnet in subnets['subnets']:
                try:
                    self.neutronclient.remove_interface_router(
                        router_id, {'subnet_id': subnet['id']})
                except NeutronClientException:
                    pass

        def delete_user_keypairs(_user):
            if not _user.get('enabled'):
                return
            try:
                self.switch_user(user=_user['name'],
                                 password=_user['password'],
                                 tenant=_user['tenant'])
            except Unauthorized:
                return

            keypairs = [k.id for k in self.novaclient.keypairs.list()]
            if keypairs:
                map(self.novaclient.keypairs.delete, keypairs)
            self.switch_user(user=self.username, password=self.password,
                             tenant=self.tenant)

        def wait_until_vms_all_deleted():
            timeout = 120
            for i in range(timeout):
                servers = self.novaclient.servers.list(
                    search_opts={'all_tenants': 1})
                for server in servers:
                    if server.status != 'DELETED':
                        time.sleep(1)
                    try:
                        self.novaclient.servers.delete(server.id)
                    except NotFound:
                        pass
                else:
                    break
            else:
                raise RuntimeError('Next vms were not deleted')

        for flavor in self.config.flavors:
            try:
                self.novaclient.flavors.delete(
                    self.get_flavor_id(flavor['name']))
            except Exception as e:
                print "Flavor %s failed to delete: %s" % (flavor['name'],
                                                          repr(e))
        vms = self.config.vms
        vms += itertools.chain(*[tenant['vms'] for tenant
                                 in self.config.tenants if tenant.get('vms')])
        for vm in vms:
            try:
                self.novaclient.servers.delete(self.get_vm_id(vm['name']))
            except Exception as e:
                print "VM %s failed to delete: %s" % (vm['name'], repr(e))
        wait_until_vms_all_deleted()
        images = self.config.images
        images += itertools.chain(*[tenant['images'] for tenant
                                  in self.config.tenants
                                  if tenant.get('images')])
        for image in images:
            try:
                self.glanceclient.images.delete(
                    self.get_image_id(image['name']))
            except Exception as e:
                print "Image %s failed to delete: %s" % (image['name'],
                                                         repr(e))
        nets = self.config.networks
        nets += itertools.chain(*[tenant['networks'] for tenant
                                  in self.config.tenants
                                  if tenant.get('networks')])
        floatingips = self.neutronclient.list_floatingips()['floatingips']
        for ip in floatingips:
            try:
                self.neutronclient.delete_floatingip(ip['id'])
            except Exception as e:
                print "Ip %s failed to delete: %s" % (
                    ip['floating_ip_address'], repr(e))

        for router in self.config.routers:
            try:
                clean_router_ports(self.get_router_id(
                    router['router']['name']))
                self.neutronclient.delete_router(self.get_router_id(
                    router['router']['name']))
            except Exception as e:
                print "Router failed to delete: %s" % repr(e)

        ports = self.neutronclient.list_ports()['ports']
        ports = [port for port in ports[:]
                 if port['device_owner'] == 'network:dhcp']

        for port in ports:
            self.neutronclient.delete_port(port['id'])
        for network in nets:
            try:
                self.neutronclient.delete_network(self.get_net_id(
                    network['name']))
            except Exception as e:
                print "Network %s failed to delete: %s" % (network['name'],
                                                           repr(e))
        for snapshot in self.config.snapshots:
            try:
                self.glanceclient.images.delete(
                    self.get_image_id(snapshot['image_name']))
            except Exception as e:
                print "Image %s failed to delete: %s" % (
                    snapshot['image_name'], repr(e))

        sgs = self.neutronclient.list_security_groups()['security_groups']
        for sg in sgs:
            try:
                print "delete sg {}".format(sg['name'])
                self.neutronclient.delete_security_group(self.get_sg_id(
                                                         sg['name']))
            except NeutronClientException as e:
                print "Security group %s failed to delete: %s" % (sg['name'],
                                                                  repr(e))
        for user in self.config.users:
            delete_user_keypairs(user)
            try:
                self.keystoneclient.users.delete(
                    self.get_user_id(user['name']))
            except Exception as e:
                print "User %s failed to delete: %s" % (user['name'], repr(e))
        for role in self.config.roles:
            try:
                self.keystoneclient.roles.delete(self.get_role_id(
                    role['name']))
            except Exception as e:
                print "Role %s failed to delete: %s" % (role['name'], repr(e))
        snapshots = self.config.cinder_snapshots
        snapshots += itertools.chain(
            *[tenant['cinder_snapshots'] for tenant in self.config.tenants
              if 'cinder_snapshots' in tenant])
        for snapshot in snapshots:
            try:
                self.cinderclient.volume_snapshots.delete(
                    self.get_volume_snapshot_id(snapshot['display_name']))
            except Exception as e:
                print "Snapshot %s failed to delete: %s" % (
                    snapshot['display_name'], repr(e))

        for tenant in self.config.tenants:
            try:
                self.keystoneclient.tenants.delete(
                    self.get_tenant_id(tenant['name']))
            except Exception as e:
                print "Tenant %s failed to delete: %s" % (tenant['name'],
                                                          repr(e))
        volumes = self.config.cinder_volumes
        volumes += itertools.chain(*[tenant['cinder_volumes'] for tenant
                                     in self.config.tenants if 'cinder_volumes'
                                     in tenant])
        for volume in volumes:
            try:
                self.cinderclient.volumes.delete(
                    self.get_volume_id(volume['name']))
            except Exception as e:
                print "Volume %s failed to delete: %s" % (volume['name'],
                                                          repr(e))
Example #8
0
 def __init__(self, config):
     self.cloud_info = None
     self.migration_utils = FilteringUtils()
     self.main_folder = self.migration_utils.main_folder
     self.config = config
Example #9
0
class Prerequisites(object):
    def __init__(self, config, cloud_prefix='SRC'):
        self.filtering_utils = FilteringUtils()
        self.config = config
        self.username = os.environ['%s_OS_USERNAME' % cloud_prefix]
        self.password = os.environ['%s_OS_PASSWORD' % cloud_prefix]
        self.tenant = os.environ['%s_OS_TENANT_NAME' % cloud_prefix]
        self.auth_url = os.environ['%s_OS_AUTH_URL' % cloud_prefix]
        self.image_endpoint = os.environ['%s_OS_IMAGE_ENDPOINT' % cloud_prefix]
        self.neutron_endpoint = os.environ['%s_OS_NEUTRON_ENDPOINT' %
                                           cloud_prefix]

        self.keystoneclient = keystone.Client(auth_url=self.auth_url,
                                              username=self.username,
                                              password=self.password,
                                              tenant_name=self.tenant)
        self.keystoneclient.authenticate()
        self.token = self.keystoneclient.auth_token

        self.novaclient = nova.Client(self.config.NOVA_CLIENT_VERSION,
                                      username=self.username,
                                      api_key=self.password,
                                      project_id=self.tenant,
                                      auth_url=self.auth_url)

        self.glanceclient = glance(self.config.GLANCE_CLIENT_VERSION,
                                   endpoint=self.image_endpoint,
                                   token=self.token)

        self.neutronclient = neutron.Client(self.config.NEUTRON_CLIENT_VERSION,
                                            endpoint_url=self.neutron_endpoint,
                                            token=self.token)

        self.cinderclient = cinder.Client(self.config.CINDER_CLIENT_VERSION,
                                          self.username, self.password,
                                          self.tenant, self.auth_url)
        # will be filled during create all networking step
        self.ext_net_id = None

    def get_tenant_id(self, tenant_name):
        tenants = self.keystoneclient.tenants.list()
        return [x for x in tenants if x.name == tenant_name][0].id

    def get_user_id(self, user_name):
        users = self.keystoneclient.users.list()
        return [x for x in users if x.name == user_name][0].id

    def get_router_id(self, router):
        return self.neutronclient.list_routers(name=router)['routers'][0]['id']

    def get_image_id(self, image_name):
        images = self.glanceclient.images.list()
        return [x for x in images if x.name == image_name][0].id

    def get_flavor_id(self, flavor_name):
        flavors = self.novaclient.flavors.list()
        return [x for x in flavors if x.name == flavor_name][0].id

    def get_vm_id(self, vm_name):
        vms = self.novaclient.servers.list(search_opts={'all_tenants': 1})
        return [x for x in vms if x.name == vm_name][0].id

    def get_role_id(self, role):
        roles = self.keystoneclient.roles.list()
        return [x for x in roles if x.name == role][0].id

    def get_net_id(self, net):
        return self.neutronclient.list_networks(
            name=net, all_tenants=True)['networks'][0]['id']

    def get_sg_id(self, sg):
        return self.neutronclient.list_security_groups(
            name=sg, all_tenants=True)['security_groups'][0]['id']

    def get_volume_id(self, volume_name):
        volumes = self.cinderclient.volumes.list(
            search_opts={'all_tenants': 1})
        return [x for x in volumes if x.display_name == volume_name][0].id

    def get_volume_snapshot_id(self, snapshot_name):
        snapshots = self.cinderclient.volume_snapshots.list(
            search_opts={'all_tenants': 1})
        return [x for x in snapshots if x.display_name == snapshot_name][0].id

    def get_user_tenant_roles(self, user):
        user_tenant_roles = []
        for tenant in self.keystoneclient.tenants.list():
            user_tenant_roles.extend(
                self.keystoneclient.roles.roles_for_user(
                    user=self.get_user_id(user.name),
                    tenant=self.get_tenant_id(tenant.name)))
        return user_tenant_roles

    def get_ext_routers(self):
        routers = self.neutronclient.list_routers()['routers']
        ext_routers = [
            router for router in routers if router['external_gateway_info']
        ]
        return ext_routers

    def check_vm_state(self, srv):
        srv = self.novaclient.servers.get(srv)
        return srv.status == 'ACTIVE'

    def switch_user(self, user, password, tenant):
        self.keystoneclient = keystone.Client(auth_url=self.auth_url,
                                              username=user,
                                              password=password,
                                              tenant_name=tenant)
        self.keystoneclient.authenticate()
        self.token = self.keystoneclient.auth_token
        self.novaclient = nova.Client(self.config.NOVA_CLIENT_VERSION,
                                      username=user,
                                      api_key=password,
                                      project_id=tenant,
                                      auth_url=self.auth_url)
        self.glanceclient = glance(self.config.GLANCE_CLIENT_VERSION,
                                   endpoint=self.image_endpoint,
                                   token=self.token)
        self.neutronclient = neutron.Client(self.config.NEUTRON_CLIENT_VERSION,
                                            endpoint_url=self.neutron_endpoint,
                                            token=self.token)
        self.cinderclient = cinder.Client(self.config.CINDER_CLIENT_VERSION,
                                          user, password, tenant,
                                          self.auth_url)

    def create_users(self):
        for user in self.config.users:
            self.keystoneclient.users.create(name=user['name'],
                                             password=user['password'],
                                             email=user['email'],
                                             enabled=user['enabled'],
                                             tenant_id=self.get_tenant_id(
                                                 user['tenant']))
            if not user.get('additional_tenants'):
                continue
            for tenant in user['additional_tenants']:
                self.keystoneclient.roles.add_user_role(
                    tenant=self.get_tenant_id(tenant['name']),
                    role=self.get_role_id(tenant['role']),
                    user=self.get_user_id(user['name']))
            # Next action for default sec group creation
            if not user['enabled']:
                continue
            self.switch_user(user=user['name'],
                             password=user['password'],
                             tenant=user['tenant'])
            self.novaclient.security_groups.list()
            self.switch_user(user=self.username,
                             password=self.password,
                             tenant=self.tenant)

    def create_roles(self):
        for role in self.config.roles:
            self.keystoneclient.roles.create(name=role['name'])

    def create_tenants(self):
        for tenant in self.config.tenants:
            self.keystoneclient.tenants.create(
                tenant_name=tenant['name'],
                description=tenant['description'],
                enabled=tenant['enabled'])
            self.keystoneclient.roles.add_user_role(
                self.get_user_id(self.username), self.get_role_id('admin'),
                self.get_tenant_id(tenant['name']))

    def create_keypairs(self):
        for user, keypair in zip(self.config.users, self.config.keypairs):
            self.switch_user(user=user['name'],
                             password=user['password'],
                             tenant=user['tenant'])
            self.novaclient.keypairs.create(**keypair)
        self.switch_user(user=self.username,
                         password=self.password,
                         tenant=self.tenant)

    def modify_quotas(self):
        for tenant in self.config.tenants:
            if 'quota' in tenant:
                self.novaclient.quotas.update(tenant_id=self.get_tenant_id(
                    tenant['name']),
                                              **tenant['quota'])

    def upload_image(self):
        @retry_until_resources_created('image')
        def wait_until_images_created(image_ids):
            for img_id in image_ids[:]:
                img = self.glanceclient.images.get(img_id)
                if img.status == 'active':
                    image_ids.remove(img_id)
            return image_ids

        img_ids = []
        for tenant in self.config.tenants:
            if not tenant.get('images'):
                continue
            for image in tenant['images']:
                self.switch_user(user=self.username,
                                 password=self.password,
                                 tenant=tenant['name'])
                img = self.glanceclient.images.create(**image)
                img_ids.append(img.id)
        self.switch_user(user=self.username,
                         password=self.password,
                         tenant=self.tenant)
        for image in self.config.images:
            img = self.glanceclient.images.create(**image)
            img_ids.append(img.id)
        wait_until_images_created(img_ids)
        src_cloud = Prerequisites(cloud_prefix='SRC', config=self.config)
        src_img = [x.__dict__ for x in src_cloud.glanceclient.images.list()]
        for image in src_img:
            if image['name'] in self.config.img_to_add_members:
                image_id = image['id']
                tenant_list = self.keystoneclient.tenants.list()
                for tenant in tenant_list:
                    tenant = tenant.__dict__
                    if tenant['name'] in self.config.members:
                        member_id = tenant['id']
                        self.glanceclient.image_members.create(
                            image_id, member_id)

    def update_filtering_file(self):
        src_cloud = Prerequisites(cloud_prefix='SRC', config=self.config)
        src_img = [x.__dict__ for x in src_cloud.glanceclient.images.list()]
        src_vms = [
            x.__dict__ for x in src_cloud.novaclient.servers.list(
                search_opts={'all_tenants': 1})
        ]
        image_dict = {}
        for image in src_img:
            img_members = self.glanceclient.image_members.list(image['id'])
            if len(img_members) > 1:
                img_mem_list = []
                for img_member in img_members:
                    img_member = img_member.__dict__
                    img_mem_list.append(img_member['member_id'])
                image_dict[image['id']] = img_mem_list
        vm_id_list = []
        for vm in src_vms:
            vm_id = vm['id']
            vm_id_list.append(vm_id)
        loaded_data = self.filtering_utils.load_file('configs/filter.yaml')
        filter_dict = loaded_data[0]
        if filter_dict is None:
            filter_dict = {
                'images': {
                    'images_list': {}
                },
                'instances': {
                    'id': {}
                }
            }
        all_img_ids = []
        img_list = []
        not_incl_img = []
        vm_list = []
        for image in src_img:
            all_img_ids.append(image['id'])
        for img in self.config.images_not_included_in_filter:
            not_incl_img.append(self.get_image_id(img))
        for key in filter_dict.keys():
            if key == 'images':
                for img_id in all_img_ids:
                    if img_id not in not_incl_img:
                        img_list.append(img_id)
                filter_dict[key]['images_list'] = img_list
            elif key == 'instances':
                for vm in vm_id_list:
                    if vm != self.get_vm_id('not_in_filter'):
                        vm_list.append(vm)
                filter_dict[key]['id'] = vm_list
        file_path = loaded_data[1]
        with open(file_path, "w") as f:
            yaml.dump(filter_dict, f, default_flow_style=False)

    def create_flavors(self):
        for flavor in self.config.flavors:
            self.novaclient.flavors.create(**flavor)

    def create_vms(self):
        def get_vm_nics(_vm):
            if 'nics' in _vm:
                for _nic in _vm['nics']:
                    _nic['net-id'] = self.get_net_id(_nic['net-id'])
                return _vm['nics']
            nets = self.neutronclient.list_networks()['networks']
            _t = self.keystoneclient.tenant_id
            nics = [{
                'net-id': net['id']
            } for net in nets
                    if not net['router:external'] and net['tenant_id'] == _t]
            return nics

        def get_parameters_for_vm_creating(_vm):
            return {
                'image': self.get_image_id(_vm['image']),
                'flavor': self.get_flavor_id(_vm['flavor']),
                'nics': get_vm_nics(_vm),
                'name': _vm['name']
            }

        def wait_vm_nic_created(vm_id):
            for i in range(TIMEOUT):
                srv = self.novaclient.servers.get(vm_id)
                if srv.networks:
                    break
            else:
                raise RuntimeError(
                    'NIC for vm with id {0} was not created'.format(vm_id))

        def wait_for_vm_creating():
            """ When limit for creating vms in nova is reached, we receive
                exception from nova: 'novaclient.exceptions.OverLimit:
                This request was rate-limited. (HTTP 413)'. To handle this we
                set limit for vm spawning.
            """
            for i in range(TIMEOUT):
                all_vms = self.novaclient.servers.list(
                    search_opts={'all_tenants': 1})
                spawning_vms = [
                    vm.id for vm in all_vms if vm.status == 'BUILD'
                ]
                if len(spawning_vms) >= VM_SPAWNING_LIMIT:
                    time.sleep(1)
                else:
                    break
            else:
                raise RuntimeError(
                    'VMs with ids {0} were in "BUILD" state more than {1} '
                    'seconds'.format(spawning_vms, TIMEOUT))

        def create_vms(vm_list):
            vm_ids = []
            for vm in vm_list:
                wait_for_vm_creating()
                _vm = self.novaclient.servers.create(
                    **get_parameters_for_vm_creating(vm))
                vm_ids.append(_vm.id)
                if not vm.get('fip'):
                    continue
                wait_vm_nic_created(_vm.id)
                fip = self.neutronclient.create_floatingip(
                    {"floatingip": {
                        "floating_network_id": self.ext_net_id
                    }})
                _vm.add_floating_ip(fip['floatingip']['floating_ip_address'])
            return vm_ids

        @retry_until_resources_created('vm')
        def wait_until_vms_created(vm_list):
            for vm in vm_list[:]:
                if self.check_vm_state(vm):
                    vms.remove(vm)
            return vms

        vms = create_vms(self.config.vms)
        for tenant in self.config.tenants:
            if not tenant.get('vms'):
                continue
            self.switch_user(user=self.username,
                             password=self.password,
                             tenant=tenant['name'])
            vms.extend(create_vms(tenant['vms']))
        self.switch_user(user=self.username,
                         password=self.password,
                         tenant=self.tenant)

        wait_until_vms_created(vms)

    def create_vm_snapshots(self):
        @retry_until_resources_created('vm_snapshot')
        def wait_until_vm_snapshots_created(snapshot_ids):
            for snp_id in snapshot_ids[:]:
                snp = self.glanceclient.images.get(snp_id)
                if snp.status == 'active':
                    snp_ids.remove(snp_id)
                elif snp.status == 'error':
                    msg = 'Snapshot with id {0} has become in error state'
                    raise RuntimeError(msg.format(snp_id))
            return snapshot_ids

        snp_ids = []
        for snapshot in self.config.snapshots:
            self.novaclient.servers.create_image(
                server=self.get_vm_id(snapshot['server']),
                image_name=snapshot['image_name'])
            snp = self.glanceclient.images.get(
                self.get_image_id(snapshot['image_name']))
            snp_ids.append(snp.id)
        wait_until_vm_snapshots_created(snp_ids)

    def create_networks(self, network_list, subnet_list):
        ext_router_id = self.get_router_id('ext_router')
        for network, subnet in zip(network_list, subnet_list):
            if network.get('router:external'):
                continue
            net = self.neutronclient.create_network({'network': network})
            subnet['network_id'] = net['network']['id']
            subnet = self.neutronclient.create_subnet({'subnet': subnet})
            self.neutronclient.add_interface_router(
                ext_router_id, {"subnet_id": subnet['subnet']['id']})

    def create_router(self, router_list):
        for router in router_list:
            router['router']['external_gateway_info']['network_id'] = \
                self.get_net_id(
                    router['router']['external_gateway_info']['network_id'])
            self.neutronclient.create_router(router)

    def create_external_network(self):
        for network in self.config.networks:
            if network.get('router:external'):
                net = self.neutronclient.create_network({'network': network})
                break
        else:
            raise RuntimeError('Please specify external network in config.py')
        for subnet in self.config.subnets:
            if subnet.get('name') == 'external_subnet':
                subnet['network_id'] = net['network']['id']
                self.neutronclient.create_subnet({'subnet': subnet})
                break
        else:
            raise RuntimeError('Please specify subnet for external network in '
                               'config.py (make sure subnet has field '
                               '"name": "external_subnet").')
        return net['network']['id']

    def create_all_networking(self):
        self.ext_net_id = self.create_external_network()
        self.create_router(self.config.routers)
        self.create_networks(self.config.networks, self.config.subnets)
        for tenant in self.config.tenants:
            if tenant.get('networks'):
                self.switch_user(user=self.username,
                                 password=self.password,
                                 tenant=tenant['name'])
                self.create_networks(tenant['networks'], tenant['subnets'])
            if tenant.get('unassociated_fip'):
                for i in range(tenant['unassociated_fip']):
                    self.neutronclient.create_floatingip({
                        "floatingip": {
                            "floating_network_id": self.ext_net_id
                        }
                    })
        self.switch_user(user=self.username,
                         password=self.password,
                         tenant=self.tenant)

    def create_security_group(self, sg_list):
        for security_group in sg_list:
            gid = self.novaclient.security_groups.create(
                name=security_group['name'],
                description=security_group['description']).id
            if 'rules' in security_group:
                for rule in security_group['rules']:
                    self.novaclient.security_group_rules.create(
                        gid,
                        ip_protocol=rule['ip_protocol'],
                        from_port=rule['from_port'],
                        to_port=rule['to_port'],
                        cidr=rule['cidr'])

    def create_security_groups(self):
        for tenant in self.config.tenants:
            if 'security_groups' in tenant:
                self.switch_user(user=self.username,
                                 password=self.password,
                                 tenant=tenant['name'])
                self.create_security_group(tenant['security_groups'])
        self.switch_user(user=self.username,
                         password=self.password,
                         tenant=self.tenant)

    def get_sec_group_id_by_tenant_id(self, tenant_id):
        sec_group_list = self.neutronclient.list_security_groups()
        return [
            i['id'] for i in sec_group_list['security_groups']
            if i['tenant_id'] == tenant_id
        ]

    def create_security_group_rule(self,
                                   group_id,
                                   tenant_id,
                                   protocol='tcp',
                                   port_range_min=22,
                                   port_range_max=22,
                                   direction='ingress'):
        sec_rule = {
            'security_group_rule': {
                "security_group_id": group_id,
                "protocol": protocol,
                "direction": direction,
                'tenant_id': tenant_id,
                "port_range_min": port_range_min,
                "port_range_max": port_range_max
            }
        }
        self.neutronclient.create_security_group_rule(sec_rule)

    def create_cinder_volumes(self, volumes_list):
        @retry_until_resources_created('volume')
        def wait_for_volumes(volume_ids):
            for volume_id in volume_ids[:]:
                _vlm = self.cinderclient.volumes.get(volume_id)
                if _vlm.status == 'available' or _vlm.status == 'in-use':
                    volume_ids.remove(volume_id)
                elif _vlm.status == 'error':
                    msg = 'Volume with id {0} was created with error'
                    raise RuntimeError(msg.format(volume_id))
            return volume_ids

        vlm_ids = []
        for volume in volumes_list:
            if 'user' in volume:
                user = [
                    u for u in self.config.users if u['name'] == volume['user']
                ][0]
                self.switch_user(user=user['name'],
                                 password=user['password'],
                                 tenant=user['tenant'])
            vlm = self.cinderclient.volumes.create(display_name=volume['name'],
                                                   size=volume['size'])
            vlm_ids.append(vlm.id)
        self.switch_user(user=self.username,
                         password=self.password,
                         tenant=self.tenant)
        wait_for_volumes(vlm_ids)
        vlm_ids = []
        for volume in volumes_list:
            if 'server_to_attach' not in volume:
                continue
            vlm_id = self.get_volume_id(volume['name'])
            self.novaclient.volumes.create_server_volume(
                server_id=self.get_vm_id(volume['server_to_attach']),
                volume_id=vlm_id,
                device=volume['device'])
            vlm_ids.append(vlm_id)
        wait_for_volumes(vlm_ids)

    def create_cinder_snapshots(self, snapshot_list):
        for snapshot in snapshot_list:
            self.cinderclient.volume_snapshots.create(**snapshot)

    def create_cinder_objects(self):
        self.create_cinder_volumes(self.config.cinder_volumes)
        self.create_cinder_snapshots(self.config.cinder_snapshots)
        for tenant in self.config.tenants:
            if 'cinder_volumes' in tenant:
                self.switch_user(user=self.username,
                                 password=self.password,
                                 tenant=tenant['name'])
                self.create_cinder_volumes(tenant['cinder_volumes'])
                if 'cinder_snapshots' in tenant:
                    self.create_cinder_snapshots(tenant['cinder_snapshots'])
        self.switch_user(user=self.username,
                         password=self.password,
                         tenant=self.tenant)

    def emulate_vm_states(self):
        for vm_state in self.config.vm_states:
            # emulate error state:
            if vm_state['state'] == u'error':
                self.novaclient.servers.reset_state(server=self.get_vm_id(
                    vm_state['name']),
                                                    state=vm_state['state'])
            # emulate suspend state:
            elif vm_state['state'] == u'suspend':
                self.novaclient.servers.suspend(
                    self.get_vm_id(vm_state['name']))
            # emulate resize state:
            elif vm_state['state'] == u'pause':
                self.novaclient.servers.pause(self.get_vm_id(vm_state['name']))
            # emulate stop/shutoff state:
            elif vm_state['state'] == u'stop':
                self.novaclient.servers.stop(self.get_vm_id(vm_state['name']))
            # emulate resize state:
            elif vm_state['state'] == u'resize':
                self.novaclient.servers.resize(
                    self.get_vm_id(vm_state['name']), '2')

    def generate_vm_state_list(self):
        data = {}
        for vm in self.novaclient.servers.list(search_opts={'all_tenants': 1}):
            for i in range(TIMEOUT):
                _vm = self.novaclient.servers.get(vm.id)
                if _vm.status != u'RESIZE':
                    break
                time.sleep(1)
            vm_state = self.novaclient.servers.get(vm.id).status
            data[vm.name] = vm_state

        file_name = 'pre_migration_vm_states.json'
        with open(file_name, 'w') as outfile:
            json.dump(data,
                      outfile,
                      sort_keys=True,
                      indent=4,
                      ensure_ascii=False)

    def delete_flavor(self, flavor='del_flvr'):
        """
        Method for flavor deletion.
        """
        try:
            self.novaclient.flavors.delete(self.get_flavor_id(flavor))
        except Exception as e:
            print "Flavor %s failed to delete: %s" % (flavor, repr(e))

    def modify_admin_tenant_quotas(self):
        for tenant in self.config.tenants:
            if 'quota' in tenant:
                self.novaclient.quotas.update(
                    tenant_id=self.get_tenant_id('admin'), **tenant['quota'])
                break

    def delete_users(self):
        for user in self.config.users:
            if user.get('deleted'):
                self.keystoneclient.users.delete(self.get_user_id(
                    user['name']))

    def delete_tenants(self):
        for tenant in self.config.tenants:
            if tenant.get('deleted'):
                self.keystoneclient.tenants.delete(
                    self.get_tenant_id(tenant['name']))

    def create_tenant_wo_sec_group_on_dst(self):
        """
        Method for check fixed issue, when on dst tenant does not have
        security group, even default, while on src this tenant has security
        group.
        """
        dst_cloud = Prerequisites(cloud_prefix='DST', config=self.config)
        for t in self.config.tenants:
            if 'deleted' in t and not t['deleted'] and t['enabled']:
                dst_cloud.keystoneclient.tenants.create(
                    tenant_name=t['name'],
                    description=t['description'],
                    enabled=t['enabled'])

    def run_preparation_scenario(self):
        print('>>> Creating tenants:')
        self.create_tenants()
        print('>>> Creating users:')
        self.create_users()
        print('>>> Creating roles:')
        self.create_roles()
        print('>>> Creating keypairs:')
        self.create_keypairs()
        print('>>> Modifying quotas:')
        self.modify_quotas()
        print('>>> Creating flavors:')
        self.create_flavors()
        print('>>> Uploading images:')
        self.upload_image()
        print('>>> Creating networking:')
        self.create_all_networking()
        print('>>> Creating vms:')
        self.create_vms()
        print('>>> Updating filtering:')
        self.update_filtering_file()
        print('>>> Creating vm snapshots:')
        self.create_vm_snapshots()
        print('>>> Creating security groups:')
        self.create_security_groups()
        print('>>> Creating cinder objects:')
        self.create_cinder_objects()
        print('>>> Emulating vm states:')
        self.emulate_vm_states()
        print('>>> Generating vm states list:')
        self.generate_vm_state_list()
        print('>>> Deleting flavor:')
        self.delete_flavor()
        print('>>> Modifying admin tenant quotas:')
        self.modify_admin_tenant_quotas()
        print('>>> Delete users which should be deleted:')
        self.delete_users()
        print('>>> Delete tenants which should be deleted:')
        self.delete_tenants()
        print('>>> Create tenant on dst, without security group')
        self.create_tenant_wo_sec_group_on_dst()

    def clean_objects(self):
        def clean_router_ports(router_id):
            subnets = self.neutronclient.list_subnets()
            for subnet in subnets['subnets']:
                try:
                    self.neutronclient.remove_interface_router(
                        router_id, {'subnet_id': subnet['id']})
                except NeutronClientException:
                    pass

        def delete_user_keypairs(_user):
            if not _user.get('enabled'):
                return
            try:
                self.switch_user(user=_user['name'],
                                 password=_user['password'],
                                 tenant=_user['tenant'])
            except Unauthorized:
                return

            keypairs = [k.id for k in self.novaclient.keypairs.list()]
            if keypairs:
                map(self.novaclient.keypairs.delete, keypairs)
            self.switch_user(user=self.username,
                             password=self.password,
                             tenant=self.tenant)

        def wait_until_vms_all_deleted():
            timeout = 120
            for i in range(timeout):
                servers = self.novaclient.servers.list(
                    search_opts={'all_tenants': 1})
                for server in servers:
                    if server.status != 'DELETED':
                        time.sleep(1)
                    try:
                        self.novaclient.servers.delete(server.id)
                    except NotFound:
                        pass
                else:
                    break
            else:
                raise RuntimeError('Next vms were not deleted')

        for flavor in self.config.flavors:
            try:
                self.novaclient.flavors.delete(
                    self.get_flavor_id(flavor['name']))
            except Exception as e:
                print "Flavor %s failed to delete: %s" % (flavor['name'],
                                                          repr(e))
        vms = self.config.vms
        vms += itertools.chain(*[
            tenant['vms'] for tenant in self.config.tenants
            if tenant.get('vms')
        ])
        for vm in vms:
            try:
                self.novaclient.servers.delete(self.get_vm_id(vm['name']))
            except Exception as e:
                print "VM %s failed to delete: %s" % (vm['name'], repr(e))
        wait_until_vms_all_deleted()
        images = self.config.images
        images += itertools.chain(*[
            tenant['images'] for tenant in self.config.tenants
            if tenant.get('images')
        ])
        for image in images:
            try:
                self.glanceclient.images.delete(
                    self.get_image_id(image['name']))
            except Exception as e:
                print "Image %s failed to delete: %s" % (image['name'],
                                                         repr(e))
        nets = self.config.networks
        nets += itertools.chain(*[
            tenant['networks'] for tenant in self.config.tenants
            if tenant.get('networks')
        ])
        floatingips = self.neutronclient.list_floatingips()['floatingips']
        for ip in floatingips:
            try:
                self.neutronclient.delete_floatingip(ip['id'])
            except Exception as e:
                print "Ip %s failed to delete: %s" % (
                    ip['floating_ip_address'], repr(e))

        for router in self.config.routers:
            try:
                clean_router_ports(self.get_router_id(
                    router['router']['name']))
                self.neutronclient.delete_router(
                    self.get_router_id(router['router']['name']))
            except Exception as e:
                print "Router failed to delete: %s" % repr(e)

        ports = self.neutronclient.list_ports()['ports']
        ports = [
            port for port in ports[:] if port['device_owner'] == 'network:dhcp'
        ]

        for port in ports:
            self.neutronclient.delete_port(port['id'])
        for network in nets:
            try:
                self.neutronclient.delete_network(
                    self.get_net_id(network['name']))
            except Exception as e:
                print "Network %s failed to delete: %s" % (network['name'],
                                                           repr(e))
        for snapshot in self.config.snapshots:
            try:
                self.glanceclient.images.delete(
                    self.get_image_id(snapshot['image_name']))
            except Exception as e:
                print "Image %s failed to delete: %s" % (
                    snapshot['image_name'], repr(e))

        sgs = self.neutronclient.list_security_groups()['security_groups']
        for sg in sgs:
            try:
                print "delete sg {}".format(sg['name'])
                self.neutronclient.delete_security_group(
                    self.get_sg_id(sg['name']))
            except NeutronClientException as e:
                print "Security group %s failed to delete: %s" % (sg['name'],
                                                                  repr(e))
        for user in self.config.users:
            delete_user_keypairs(user)
            try:
                self.keystoneclient.users.delete(self.get_user_id(
                    user['name']))
            except Exception as e:
                print "User %s failed to delete: %s" % (user['name'], repr(e))
        for role in self.config.roles:
            try:
                self.keystoneclient.roles.delete(self.get_role_id(
                    role['name']))
            except Exception as e:
                print "Role %s failed to delete: %s" % (role['name'], repr(e))
        snapshots = self.config.cinder_snapshots
        snapshots += itertools.chain(*[
            tenant['cinder_snapshots'] for tenant in self.config.tenants
            if 'cinder_snapshots' in tenant
        ])
        for snapshot in snapshots:
            try:
                self.cinderclient.volume_snapshots.delete(
                    self.get_volume_snapshot_id(snapshot['display_name']))
            except Exception as e:
                print "Snapshot %s failed to delete: %s" % (
                    snapshot['display_name'], repr(e))

        for tenant in self.config.tenants:
            try:
                self.keystoneclient.tenants.delete(
                    self.get_tenant_id(tenant['name']))
            except Exception as e:
                print "Tenant %s failed to delete: %s" % (tenant['name'],
                                                          repr(e))
        volumes = self.config.cinder_volumes
        volumes += itertools.chain(*[
            tenant['cinder_volumes'] for tenant in self.config.tenants
            if 'cinder_volumes' in tenant
        ])
        for volume in volumes:
            try:
                self.cinderclient.volumes.delete(
                    self.get_volume_id(volume['name']))
            except Exception as e:
                print "Volume %s failed to delete: %s" % (volume['name'],
                                                          repr(e))
 def __init__(self, *args, **kwargs):
     super(FunctionalTest, self).__init__(*args, **kwargs)
     suppress_dependency_logging()
     self.src_cloud = Prerequisites(cloud_prefix='SRC', config=config)
     self.dst_cloud = Prerequisites(cloud_prefix='DST', config=config)
     self.filtering_utils = FilteringUtils()
class VmMigration(functional_test.FunctionalTest):

    def setUp(self):
        self.migration_utils = FilteringUtils()
        self.src_cloud = Prerequisites(cloud_prefix='SRC')
        self.dst_cloud = Prerequisites(cloud_prefix='DST')
        src_vms = [x.__dict__ for x in
                   self.src_cloud.novaclient.servers.list(
                       search_opts={'all_tenants': 1})]
        self.dst_vms = [x.__dict__ for x in
                        self.dst_cloud.novaclient.servers.list(
                            search_opts={'all_tenants': 1})]
        src_vms = [vm for vm in src_vms if vm['status'] != 'ERROR']
        self.dst_vm_indexes = []
        for vm in src_vms:
            if vm['name'] not in config.vms_not_in_filter:
                self.dst_vm_indexes.append([x['name'] for x in self.dst_vms].index(
                    vm['name']))
        with open('pre_migration_vm_states.json') as data_file:
            self.before_migr_states = json.load(data_file)
        self.filter_vms = self.migration_utils.filter_vms(src_vms)

    def test_vms_not_in_filter_stay_active_on_src(self):
        filter_results = self.filter_vms
        vms_filtered_out = filter_results[1]
        original_states = self.before_migr_states
        for vm in vms_filtered_out:
            self.assertTrue(vm['status'] == original_states[vm['name']])

    def test_vm_not_in_filter_did_not_migrate(self):
        filter_results = self.filter_vms
        vms_filtered_out = filter_results[1]
        dst_vms = [x.__dict__['name'] for x in
                   self.dst_cloud.novaclient.servers.list(
                       search_opts={'all_tenants': 1})]
        for vm in vms_filtered_out:
            self.assertTrue(vm['name'] not in dst_vms, 'VM migrated despite '
                                                       'that it was not '
                                                       'included in filter, '
                                                       'VM info: \n{}'.format(vm))

    def test_cold_migrate_vm_state(self):
        original_states = self.before_migr_states
        for vm_name in original_states.keys():
            if vm_name in config.vms_not_in_filter:
                original_states.pop(vm_name)
        src_vms = self.filter_vms[0]
        for src_vm, vm_index in zip(src_vms, self.dst_vm_indexes):
            if src_vm['name'] in original_states.keys():
                if original_states[src_vm['name']] == 'ACTIVE' or \
                        original_states[src_vm['name']] == 'VERIFY_RESIZE':
                    self.assertTrue(src_vm['status'] == 'SHUTOFF' and
                                    self.dst_vms[vm_index]['status'] == 'ACTIVE')
                else:
                    self.assertTrue(src_vm['status'] == 'SHUTOFF' and
                                    self.dst_vms[vm_index]['status'] == 'SHUTOFF')
            else:
                self.assertTrue(src_vm['status'] == 'SHUTOFF' and
                                self.dst_vms[vm_index]['status'] == 'ACTIVE')

    def test_cold_migrate_vm_ip(self):
        src_vms = self.filter_vms[0]
        for src_vm, vm_index in zip(src_vms, self.dst_vm_indexes):
            for src_net in src_vm['addresses']:
                for src_net_addr, dst_net_addr in zip(src_vm['addresses']
                                                      [src_net],
                                                      self.dst_vms[vm_index]
                                                      ['addresses'][src_net]):
                    self.assertTrue(src_net_addr['addr'] ==
                                    dst_net_addr['addr'])

    def test_cold_migrate_vm_security_groups(self):
        src_vms = self.filter_vms[0]
        for src_vm, vm_index in zip(src_vms, self.dst_vm_indexes):
            dst_sec_group_names = [x['name'] for x in
                                   self.dst_vms[vm_index]['security_groups']]
            for security_group in src_vm['security_groups']:
                self.assertTrue(security_group['name'] in dst_sec_group_names)

    @unittest.skip("Temporarily disabled: image's id changes after migrating")
    def test_cold_migrate_vm_image_id(self):
        src_vms = self.filter_vms[0]
        for src_vm, vm_index in zip(src_vms, self.dst_vm_indexes):
            self.assertTrue(src_vm['image']['id'] ==
                            self.dst_vms[vm_index]['image']['id'])