"Fossies" - the Fresh Open Source Software Archive

Member "horizon-20.1.2/openstack_dashboard/dashboards/project/instances/utils.py" (29 Apr 2022, 9900 Bytes) of package /linux/misc/openstack/horizon-20.1.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "utils.py": 20.1.1_vs_20.1.2.

    1 # Licensed under the Apache License, Version 2.0 (the "License"); you may
    2 # not use this file except in compliance with the License. You may obtain
    3 # a copy of the License at
    4 #
    5 #      http://www.apache.org/licenses/LICENSE-2.0
    6 #
    7 # Unless required by applicable law or agreed to in writing, software
    8 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    9 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   10 # License for the specific language governing permissions and limitations
   11 # under the License.
   12 
   13 from collections import namedtuple
   14 import logging
   15 from operator import itemgetter
   16 
   17 from django.conf import settings
   18 from django.utils.translation import ugettext_lazy as _
   19 
   20 from horizon import exceptions
   21 
   22 from openstack_dashboard import api
   23 
   24 LOG = logging.getLogger(__name__)
   25 
   26 
   27 def flavor_list(request):
   28     """Utility method to retrieve a list of flavors."""
   29     try:
   30         return api.nova.flavor_list(request)
   31     except Exception:
   32         exceptions.handle(request,
   33                           _('Unable to retrieve instance flavors.'))
   34         return []
   35 
   36 
   37 def sort_flavor_list(request, flavors, with_menu_label=True):
   38     """Utility method to sort a list of flavors.
   39 
   40     By default, returns the available flavors, sorted by RAM usage (ascending).
   41     Override these behaviours with a ``CREATE_INSTANCE_FLAVOR_SORT`` dict
   42     in ``local_settings.py``.
   43     """
   44     def get_key(flavor, sort_key):
   45         try:
   46             return getattr(flavor, sort_key)
   47         except AttributeError:
   48             LOG.warning('Could not find sort key "%s". Using the default '
   49                         '"ram" instead.', sort_key)
   50             return getattr(flavor, 'ram')
   51     try:
   52         flavor_sort = settings.CREATE_INSTANCE_FLAVOR_SORT
   53         sort_key = flavor_sort.get('key', 'ram')
   54         rev = flavor_sort.get('reverse', False)
   55         if not callable(sort_key):
   56             def key(flavor):
   57                 return get_key(flavor, sort_key)
   58         else:
   59             key = sort_key
   60 
   61         if with_menu_label:
   62             flavor_list = [(flavor.id, '%s' % flavor.name)
   63                            for flavor in sorted(flavors, key=key, reverse=rev)]
   64         else:
   65             flavor_list = sorted(flavors, key=key, reverse=rev)
   66         return flavor_list
   67     except Exception:
   68         exceptions.handle(request,
   69                           _('Unable to sort instance flavors.'))
   70         return []
   71 
   72 
   73 def server_group_list(request):
   74     """Utility method to retrieve a list of server groups."""
   75     try:
   76         return api.nova.server_group_list(request)
   77     except Exception:
   78         exceptions.handle(request,
   79                           _('Unable to retrieve Nova server groups.'))
   80         return []
   81 
   82 
   83 def network_field_data(request, include_empty_option=False, with_cidr=False,
   84                        for_launch=False):
   85     """Returns a list of tuples of all networks.
   86 
   87     Generates a list of networks available to the user (request). And returns
   88     a list of (id, name) tuples.
   89 
   90     :param request: django http request object
   91     :param include_empty_option: flag to include a empty tuple in the front of
   92          the list
   93     :param with_cidr: flag to include subnets cidr in field name
   94     :return: list of (id, name) tuples
   95     """
   96     tenant_id = request.user.tenant_id
   97     networks = []
   98     if api.base.is_service_enabled(request, 'network'):
   99         extra_params = {}
  100         if for_launch:
  101             extra_params['include_pre_auto_allocate'] = True
  102         try:
  103             networks = api.neutron.network_list_for_tenant(
  104                 request, tenant_id, **extra_params)
  105         except Exception:
  106             msg = _('Failed to get network list.')
  107             exceptions.handle(request, msg)
  108 
  109         _networks = []
  110         for n in networks:
  111             if not n['subnets']:
  112                 continue
  113             v = n.name_or_id
  114             if with_cidr:
  115                 cidrs = ([subnet.cidr for subnet in n['subnets']
  116                           if subnet.ip_version == 4] +
  117                          [subnet.cidr for subnet in n['subnets']
  118                           if subnet.ip_version == 6])
  119                 v += ' (%s)' % ', '.join(cidrs)
  120             _networks.append((n.id, v))
  121         networks = sorted(_networks, key=itemgetter(1))
  122 
  123     if not networks:
  124         if include_empty_option:
  125             return [("", _("No networks available")), ]
  126         return []
  127 
  128     if include_empty_option:
  129         return [("", _("Select Network")), ] + networks
  130     return networks
  131 
  132 
  133 def keypair_field_data(request, include_empty_option=False):
  134     """Returns a list of tuples of all keypairs.
  135 
  136     Generates a list of keypairs available to the user (request). And returns
  137     a list of (id, name) tuples.
  138 
  139     :param request: django http request object
  140     :param include_empty_option: flag to include a empty tuple in the front of
  141         the list
  142     :return: list of (id, name) tuples
  143     """
  144     keypair_list = []
  145     try:
  146         keypairs = api.nova.keypair_list(request)
  147         keypair_list = [(kp.name, kp.name) for kp in keypairs]
  148     except Exception:
  149         exceptions.handle(request, _('Unable to retrieve key pairs.'))
  150 
  151     if not keypair_list:
  152         if include_empty_option:
  153             return [("", _("No key pairs available")), ]
  154         return []
  155 
  156     if include_empty_option:
  157         return [("", _("Select a key pair")), ] + keypair_list
  158     return keypair_list
  159 
  160 
  161 def flavor_field_data(request, include_empty_option=False):
  162     """Returns a list of tuples of all image flavors.
  163 
  164     Generates a list of image flavors available. And returns a list of
  165     (id, name) tuples.
  166 
  167     :param request: django http request object
  168     :param include_empty_option: flag to include a empty tuple in the front of
  169         the list
  170     :return: list of (id, name) tuples
  171     """
  172     flavors = flavor_list(request)
  173     if flavors:
  174         flavors_list = sort_flavor_list(request, flavors)
  175         if include_empty_option:
  176             return [("", _("Select Flavor")), ] + flavors_list
  177         return flavors_list
  178 
  179     if include_empty_option:
  180         return [("", _("No flavors available")), ]
  181     return []
  182 
  183 
  184 def port_field_data(request, with_network=False):
  185     """Returns a list of tuples of all ports available for the tenant.
  186 
  187     Generates a list of ports that have no device_owner based on the networks
  188     available to the tenant doing the request.
  189 
  190     :param request: django http request object
  191     :param with_network: include network name in field name
  192     :return: list of (id, name) tuples
  193     """
  194 
  195     def add_more_info_port_name(port, network):
  196         # add more info to the port for the display
  197         port_name = "{} ({})".format(
  198             port.name_or_id, ",".join(
  199                 [ip['ip_address'] for ip in port['fixed_ips']]))
  200         if with_network and network:
  201             port_name += " - {}".format(network.name_or_id)
  202         return port_name
  203 
  204     ports = []
  205     if api.base.is_service_enabled(request, 'network'):
  206         network_list = api.neutron.network_list_for_tenant(
  207             request, request.user.tenant_id)
  208         for network in network_list:
  209             ports.extend(
  210                 [(port.id, add_more_info_port_name(port, network))
  211                  for port in api.neutron.port_list_with_trunk_types(
  212                      request, network_id=network.id,
  213                      tenant_id=request.user.tenant_id)
  214                  if (not port.device_owner and
  215                      not isinstance(port, api.neutron.PortTrunkSubport))])
  216     ports.sort(key=lambda obj: obj[1])
  217     return ports
  218 
  219 
  220 def server_group_field_data(request):
  221     """Returns a list of tuples of all server groups.
  222 
  223     Generates a list of server groups available. And returns a list of
  224     (id, name) tuples.
  225 
  226     :param request: django http request object
  227     :return: list of (id, name) tuples
  228     """
  229     server_groups = server_group_list(request)
  230     if server_groups:
  231         server_groups_list = [(sg.id, sg.name) for sg in server_groups]
  232         server_groups_list.sort(key=lambda obj: obj[1])
  233         return [("", _("Select Server Group")), ] + server_groups_list
  234 
  235     return [("", _("No server groups available")), ]
  236 
  237 
  238 def resolve_flavor(request, instance, flavors=None, **kwargs):
  239     """Resolves name of instance flavor independent of API microversion
  240 
  241     :param request: django http request object
  242     :param instance: api._nova.Server instance to resolve flavor
  243     :param flavors: dict of flavors already retrieved
  244     :param kwargs: flavor parameters to return if hit some flavor discrepancy
  245     :return: flavor name or default placeholder
  246     """
  247     def flavor_from_dict(flavor_dict):
  248         """Creates flavor-like objects from dictionary
  249 
  250         :param flavor_dict: dictionary contains vcpu, ram, name, etc. values
  251         :return: novaclient.v2.flavors.Flavor like object
  252         """
  253         return namedtuple('Flavor', flavor_dict.keys())(*flavor_dict.values())
  254 
  255     if flavors is None:
  256         flavors = {}
  257     flavor_id = instance.flavor.get('id')
  258     if flavor_id:  # Nova API <=2.46
  259         if flavor_id in flavors:
  260             return flavors[flavor_id]
  261         try:
  262             return api.nova.flavor_get(request, flavor_id)
  263         except Exception:
  264             msg = _('Unable to retrieve flavor information '
  265                     'for instance "%s".') % instance.id
  266             exceptions.handle(request, msg, ignore=True)
  267             fallback_flavor = {
  268                 'vcpus': 0, 'ram': 0, 'disk': 0, 'ephemeral': 0, 'swap': 0,
  269                 'name': _('Not available'),
  270                 'original_name': _('Not available'),
  271                 'extra_specs': {},
  272             }
  273             fallback_flavor.update(kwargs)
  274             return flavor_from_dict(fallback_flavor)
  275     else:
  276         instance.flavor['name'] = instance.flavor['original_name']
  277         return flavor_from_dict(instance.flavor)