def image_field_data(request, include_empty_option=False): """Returns a list of tuples of all images. Generates a sorted list of images available. And returns a list of (id, name) tuples. :param request: django http request object :param include_empty_option: flag to include a empty tuple in the front of the list :return: list of (id, name) tuples """ images = [] try: images = get_available_images(request, request.user.project_id) except Exception: exceptions.handle(request, _('Unable to retrieve images')) images.sort(key=lambda c: c.name) images_list = [('', _('Select Image'))] for image in images: image_label = u"{} ({})".format(image.name, filesizeformat(image.size)) images_list.append((image.id, image_label)) if not images: return [ ("", _("No images available")), ] return images_list
def server_group_list(request): """Utility method to retrieve a list of server groups.""" try: return api.nova.server_group_list(request) except Exception: exceptions.handle(request, _('Unable to retrieve Nova server groups.')) return []
def sort_flavor_list(request, flavors): """Utility method to sort a list of flavors. By default, returns the available flavors, sorted by RAM usage (ascending). Override these behaviours with a ``CREATE_INSTANCE_FLAVOR_SORT`` dict in ``local_settings.py``. """ def get_key(flavor, sort_key): try: return getattr(flavor, sort_key) except AttributeError: LOG.warning( 'Could not find sort key "%s". Using the default ' '"ram" instead.', sort_key) return getattr(flavor, 'ram') try: flavor_sort = getattr(settings, 'CREATE_INSTANCE_FLAVOR_SORT', {}) sort_key = flavor_sort.get('key', 'ram') rev = flavor_sort.get('reverse', False) if not callable(sort_key): key = lambda flavor: get_key(flavor, sort_key) else: key = sort_key flavor_list = [(flavor.id, '%s' % flavor.name) for flavor in sorted(flavors, key=key, reverse=rev)] return flavor_list except Exception: exceptions.handle(request, _('Unable to sort instance flavors.')) return []
def flavor_list(request): """Utility method to retrieve a list of flavors.""" try: return api.nova.flavor_list(request) except Exception: exceptions.handle(request, _('Unable to retrieve instance flavors.')) return []
def keypair_field_data(request, include_empty_option=False): """Returns a list of tuples of all keypairs. Generates a list of keypairs available to the user (request). And returns a list of (id, name) tuples. :param request: django http request object :param include_empty_option: flag to include a empty tuple in the front of the list :return: list of (id, name) tuples """ keypair_list = [] try: keypairs = api.nova.keypair_list(request) keypair_list = [(kp.name, kp.name) for kp in keypairs] except Exception: exceptions.handle(request, _('Unable to retrieve key pairs.')) if not keypair_list: if include_empty_option: return [ ("", _("No key pairs available")), ] return [] if include_empty_option: return [ ("", _("Select a key pair")), ] + keypair_list return keypair_list
def availability_zone_list(request): """Utility method to retrieve a list of availability zones.""" try: return api.nova.availability_zone_list(request) except Exception: exceptions.handle(request, _('Unable to retrieve Nova availability zones.')) return []
def network_field_data(request, include_empty_option=False, with_cidr=False): """Returns a list of tuples of all networks. Generates a list of networks available to the user (request). And returns a list of (id, name) tuples. :param request: django http request object :param include_empty_option: flag to include a empty tuple in the front of the list :param with_cidr: flag to include subnets cidr in field name :return: list of (id, name) tuples """ tenant_id = request.user.tenant_id networks = [] if api.base.is_service_enabled(request, 'network'): try: networks = api.neutron.network_list_for_tenant(request, tenant_id) except Exception as e: msg = _('Failed to get network list {0}').format(six.text_type(e)) exceptions.handle(request, msg) _networks = [] for n in networks: if not n['subnets']: continue v = n.name_or_id if with_cidr: cidrs = ([ subnet.cidr for subnet in n['subnets'] if subnet.ip_version == 4 ] + [ subnet.cidr for subnet in n['subnets'] if subnet.ip_version == 6 ]) v += ' (%s)' % ', '.join(cidrs) _networks.append((n.id, v)) networks = sorted(_networks, key=itemgetter(1)) if not networks: if include_empty_option: return [ ("", _("No networks available")), ] return [] if include_empty_option: return [ ("", _("Select Network")), ] + networks return networks
def post(self, request): instance_id = request.POST['instance_id'] try: instance = api.nova.server_get(request, instance_id) console_url = project_console.get_console(request, 'VNC', instance)[1] d = {} d["status"] = "success" d["console_url"] = console_url s = json.dumps(d) return HttpResponse(s, content_type='application/json') except Exception: redirect = reverse("openstack_netsec:listinstance") msg = 'Unable to get VNC console for instance "%s".' % instance_id exceptions.handle(request, msg, redirect=redirect)
def instancevnc(request, instance_id): try: instance = api.nova.server_get(request, instance_id) console_url = project_console.get_console(request, 'SPICE', instance)[1] # d = {} # d["status"] = "success" # d["console_url"] = console_url # s = json.dumps(d) # return HttpResponse(s, content_type='application/json') return console_url except Exception: redirect = reverse("openstack_netsec:listinstance") msg = 'Unable to get VNC console for instance "%s".' % instance_id exceptions.handle(request, msg, redirect=redirect)
def role_list(request, filters=None): """Returns a global list of available roles.""" manager = keystoneclient(request, admin=True).roles roles = [] kwargs = {} if filters is not None: kwargs.update(filters) if 'id' in kwargs: try: roles = [manager.get(kwargs['id'])] except keystone_exceptions.NotFound: roles = [] except Exception: exceptions.handle(request) else: roles = manager.list(**kwargs) return roles
def user_verify_admin_password(request, admin_password): # attempt to create a new client instance with admin password to # verify if it's correct. client = keystone_client_v2 if VERSIONS.active < 3 else keystone_client_v3 try: endpoint = _get_endpoint_url(request, 'internalURL') insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False) cacert = getattr(settings, 'OPENSTACK_SSL_CACERT', None) client.Client( username=request.user.username, password=admin_password, insecure=insecure, cacert=cacert, auth_url=endpoint) return True except Exception: exceptions.handle(request, ignore=True) return False
def user_update(request, user, **data): manager = keystoneclient(request, admin=True).users error = None if not keystone_can_edit_user(): raise keystone_exceptions.ClientException(405, _("Identity service does not allow editing user data.")) # The v2 API updates user model and default project separately if VERSIONS.active < 3: # Update user details try: user = manager.update(user, **data) except keystone_exceptions.Conflict: raise exceptions.Conflict() except Exception: error = exceptions.handle(request, ignore=True) if "project" in data: project = data.pop('project') # Update default tenant try: user_update_tenant(request, user, project) user.tenantId = project except Exception: error = exceptions.handle(request, ignore=True) # Check for existing roles # Show a warning if no role exists for the project user_roles = roles_for_user(request, user, project) if not user_roles: messages.warning(request, _('User %s has no role defined for ' 'that project.') % data.get('name', None)) if error is not None: raise error # v3 API is so much simpler... else: try: user = manager.update(user, **data) except keystone_exceptions.Conflict: raise exceptions.Conflict()
def get_default_role(request): """Gets the default role object from Keystone and saves it as a global. Since this is configured in settings and should not change from request to request. Supports lookup by name or id. """ global DEFAULT_ROLE default = getattr(settings, "OPENSTACK_KEYSTONE_DEFAULT_ROLE", None) if default and DEFAULT_ROLE is None: try: roles = keystoneclient(request, admin=True).roles.list() except Exception: roles = [] exceptions.handle(request) for role in roles: if role.id == default or role.name == default: DEFAULT_ROLE = role break return DEFAULT_ROLE
def tenant_list(request, paginate=False, marker=None, domain=None, user=None, admin=True, filters=None): manager = VERSIONS.get_project_manager(request, admin=admin) page_size = utils.get_page_size(request) tenants = [] limit = None if paginate: limit = page_size + 1 has_more_data = False # if requesting the projects for the current user, # return the list from the cache if user == request.user.id: tenants = request.user.authorized_tenants elif VERSIONS.active < 3: tenants = manager.list(limit, marker) if paginate and len(tenants) > page_size: tenants.pop(-1) has_more_data = True # V3 API else: domain_id = get_effective_domain_id(request) kwargs = {"domain": domain_id, "user": user} if filters is not None: kwargs.update(filters) if 'id' in kwargs: try: tenants = [tenant_get(request, kwargs['id'])] except keystone_exceptions.NotFound: tenants = [] except Exception: exceptions.handle(request) else: tenants = manager.list(**kwargs) return tenants, has_more_data
def get_available_images(request, project_id=None, images_cache=None): """Returns a list of available images Returns a list of images that are public, shared or owned by the given project_id. If project_id is not specified, only public images are returned. :param images_cache: An optional dict-like object in which to cache public and per-project id image metadata. """ if images_cache is None: images_cache = {} public_images = images_cache.get('public_images', []) images_by_project = images_cache.get('images_by_project', {}) shared_images = images_cache.get('shared_images', []) if 'public_images' not in images_cache: public = {"is_public": True, "status": "active"} try: images, _more, _prev = glance.image_list_detailed(request, filters=public) [public_images.append(image) for image in images] images_cache['public_images'] = public_images except Exception: exceptions.handle(request, _("Unable to retrieve public images.")) # Preempt if we don't have a project_id yet. if project_id is None: images_by_project[project_id] = [] if project_id not in images_by_project: owner = {"property-owner_id": project_id, "status": "active"} try: owned_images, _more, _prev = glance.image_list_detailed(request, filters=owner) images_by_project[project_id] = owned_images except Exception: owned_images = [] exceptions.handle(request, _("Unable to retrieve images for " "the current project.")) else: owned_images = images_by_project[project_id] if 'shared_images' not in images_cache: shared = {"visibility": "shared", "status": "active"} try: shared_images, _more, _prev = \ glance.image_list_detailed(request, filters=shared) images_cache['shared_images'] = shared_images except Exception: exceptions.handle(request, _("Unable to retrieve shared images.")) if 'images_by_project' not in images_cache: images_cache['images_by_project'] = images_by_project images = owned_images + public_images + shared_images image_ids = [] final_images = [] for image in images: if image.id not in image_ids and \ image.container_format not in ('aki', 'ari'): image_ids.append(image.id) final_images.append(image) return final_images
def post(self, request): context = {} projects = [] users = [] instance_para = {} def _is_allow(): """ 查看是否存在虚拟机 :return: """ try: tmp_instances, more = api.nova.server_list(self.request, search_opts=None) except Exception: return # if (len(tmp_instances) > 1): # return False return True def _task_get_instance_module(): """ 获取虚拟机模板文件 :return: """ try: instance_module = Lab.objects.get( pk=request.POST['lab_id']).instance_module # instance_module = request.POST['instance_module'] if instance_module == "": instance_module = "cirros" filename = instance_module + ".yaml" module_path = os.path.abspath( os.path.join(settings.MODULE_FILES_PATH, filename), ) fp = open(module_path) context_tmp = yaml.load(fp) except Exception: pass context.update(context_tmp) def _task_get_user_projects(): """ 获取项目列表和用户信息 :return: None """ try: projects_tmp = [(tenant.id, tenant.name) for tenant in request.user.authorized_tenants] users_tmp = [(request.user.id, request.user.username)] except Exception: pass projects.extend(projects_tmp) users.extend(users_tmp) def _task_get_image_id(): """ 获取镜像ID :return: None """ image_id_tmp = {} try: image = context.get('image', None) imagetype = context.get('imagetype', None) if image and imagetype: image_list = image_utils.get_available_images( request, projects[0][0], None) if imagetype == "snapshot": image_list_tmp = [ x for x in image_list if x.name == image and x.properties.get( "image_type", '') == "snapshot" ] else: image_list_tmp = [ x for x in image_list if x.name == image ] if image_list_tmp: image_id_tmp['image_id'] = image_list_tmp[0].id else: # 找不到配置文件中的image对应的镜像 raise exceptions else: # 配置文件中的没有填写image一项 raise exceptions except Exception: # 镜像获取异常 pass instance_para.update(image_id_tmp) def _task_get_flavor_list(): """ 虚拟机硬件配置选择 :return: None """ flavor_tmp = {} try: flavor_list = instance_utils.flavor_field_data(request, False) flavor_name = context.get('flavor', None) if flavor_name is None: # 设置一个默认值,当配置文件中没有flavor时 flavor_name = 'm1.small' for flavor in flavor_list: if flavor[1] == flavor_name: flavor_tmp['flavor'] = str(flavor[0]) break except Exception: pass instance_para.update(flavor_tmp) def _task_get_network_id(): """ 虚拟机网络选择 :return: None """ network_id_tmp = {} try: network_list = instance_utils.network_field_data(request) network_name = context.get("network_name", None) if network_name is not None: nics = [{ "net-id": netids[0], "v4-fixed-ip": "" } for netids in network_list if netids[1] in network_name] # 如果找不到配置文件中的网络,设置为none if len(nics) == 0: nics = None else: # 配置文件中没有网络的配置 nics = None network_id_tmp['nics'] = nics except Exception: pass instance_para.update(network_id_tmp) def _task_get_security_group_id(): """ 设置安全组规则 :return: """ security_group_tmp = {} try: security_group_id = context.get("security_group_id", None) security_group_list = api.neutron.security_group_list(request) security_group_list_tmp = [ x.get('id') for x in security_group_list if x.name_or_id in security_group_id ] # 如果查询不到配置文件中的设置,给定默认的设置 if security_group_list_tmp is None: security_group_list_tmp = [ x.get('id') for x in security_group_list if x.name_or_id == "default" ] security_group_tmp[ 'security_group_id'] = security_group_list_tmp except Exception: pass instance_para.update(security_group_tmp) def _task_get_other(): name_tmp = {} count_tmp = {} keypare_id_tmp = {} dev_mapping_1_tmp = {} dev_mapping_2_tmp = {} avail_zone_tmp = {} admin_pass_tmp = {} disk_config_tmp = {} config_drive_tmp = {} custom_script_tmp = {} scheduler_hints_tmp = {} nowtime = time.strftime("%y%m%d%H%M%S") if context.get('name', None): name_tmp['name'] = context.get( 'name') + '_' + nowtime + '_' + users[0][ 1] + '_' + request.POST["lab_id"] else: name_tmp['name'] = nowtime + '_' + users[0][ 1] + '_' + request.POST["lab_id"] if context.get("count", None): count_tmp["count"] = int(context.get("count")) else: count_tmp["count"] = int(1) if context.get("keypair_id", None): keypare_id_tmp["keypair_id"] = context.get("keypair_id") else: keypare_id_tmp["keypair_id"] = '' if context.get("dev_mapping_1", None): dev_mapping_1_tmp["dev_mapping_1"] = None else: dev_mapping_1_tmp["dev_mapping_1"] = None if context.get("dev_mapping_2", None): dev_mapping_2_tmp["dev_mapping_2"] = None else: dev_mapping_2_tmp["dev_mapping_2"] = None if context.get("avail_zone", None): avail_zone_tmp["avail_zone"] = context.get("avail_zone") else: avail_zone_tmp["avail_zone"] = 'nova' if context.get("admin_pass", None): admin_pass_tmp["admin_pass"] = context.get("admin_pass") else: admin_pass_tmp["admin_pass"] = '' if context.get("disk_config", None): disk_config_tmp["disk_config"] = context.get("disk_config") else: disk_config_tmp["disk_config"] = 'AUTO' if context.get("config_drive", None): config_drive_tmp["config_drive"] = context.get("config_drive") else: config_drive_tmp["config_drive"] = False if context.get("custom_script", None): custom_script_tmp["custom_script"] = context.get( "custom_script") else: custom_script_tmp["custom_script"] = '' if context.get("custom_script", None): custom_script_tmp["custom_script"] = context.get( "custom_script") else: custom_script_tmp["custom_script"] = '' if context.get("scheduler_hints", None): scheduler_hints_tmp["scheduler_hints"] = context.get( "scheduler_hints") else: scheduler_hints_tmp["scheduler_hints"] = {} instance_para.update(name_tmp) instance_para.update(count_tmp) instance_para.update(keypare_id_tmp) instance_para.update(dev_mapping_1_tmp) instance_para.update(dev_mapping_2_tmp) instance_para.update(avail_zone_tmp) instance_para.update(admin_pass_tmp) instance_para.update(disk_config_tmp) instance_para.update(config_drive_tmp) instance_para.update(custom_script_tmp) instance_para.update(scheduler_hints_tmp) if _is_allow(): _task_get_instance_module() _task_get_user_projects() _task_get_other() with futurist.ThreadPoolExecutor(max_workers=5) as e: e.submit(fn=_task_get_image_id) e.submit(fn=_task_get_flavor_list) e.submit(fn=_task_get_network_id) e.submit(fn=_task_get_security_group_id) try: api.nova.server_create( request, name=instance_para['name'], image=instance_para['image_id'], flavor=instance_para['flavor'], key_name=instance_para['keypair_id'], user_data=normalize_newlines( instance_para['custom_script']), security_groups=instance_para['security_group_id'], block_device_mapping=instance_para['dev_mapping_1'], block_device_mapping_v2=instance_para['dev_mapping_2'], nics=instance_para['nics'], availability_zone=instance_para['avail_zone'], instance_count=instance_para['count'], admin_pass=instance_para['admin_pass'], disk_config=instance_para['disk_config'], config_drive=instance_para['config_drive'], scheduler_hints=instance_para['scheduler_hints'], description=None) except Exception: exceptions.handle(request) d = {} d["status"] = "success" s = json.dumps(d) print(s) return HttpResponse(s, content_type='application/json') else: d = {} d["status"] = "fail" s = json.dumps(d) return HttpResponse(s, content_type='application/json')