OpenStack Compute (Nova) Client
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

flavors.py 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. # Copyright 2010 Jacob Kaplan-Moss
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  4. # not use this file except in compliance with the License. You may obtain
  5. # a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. # License for the specific language governing permissions and limitations
  13. # under the License.
  14. """
  15. Flavor interface.
  16. """
  17. from oslo.utils import strutils
  18. from six.moves.urllib import parse
  19. from novaclient import base
  20. from novaclient import exceptions
  21. from novaclient.i18n import _
  22. from novaclient import utils
  23. class Flavor(base.Resource):
  24. """
  25. A flavor is an available hardware configuration for a server.
  26. """
  27. HUMAN_ID = True
  28. def __repr__(self):
  29. return "<Flavor: %s>" % self.name
  30. @property
  31. def ephemeral(self):
  32. """
  33. Provide a user-friendly accessor to OS-FLV-EXT-DATA:ephemeral
  34. """
  35. return self._info.get("OS-FLV-EXT-DATA:ephemeral", 'N/A')
  36. @property
  37. def is_public(self):
  38. """
  39. Provide a user-friendly accessor to os-flavor-access:is_public
  40. """
  41. return self._info.get("os-flavor-access:is_public", 'N/A')
  42. def get_keys(self):
  43. """
  44. Get extra specs from a flavor.
  45. :param flavor: The :class:`Flavor` to get extra specs from
  46. """
  47. _resp, body = self.manager.api.client.get(
  48. "/flavors/%s/os-extra_specs" % base.getid(self))
  49. return body["extra_specs"]
  50. def set_keys(self, metadata):
  51. """
  52. Set extra specs on a flavor.
  53. :param flavor: The :class:`Flavor` to set extra spec on
  54. :param metadata: A dict of key/value pairs to be set
  55. """
  56. utils.validate_flavor_metadata_keys(metadata.keys())
  57. body = {'extra_specs': metadata}
  58. return self.manager._create(
  59. "/flavors/%s/os-extra_specs" % base.getid(self), body,
  60. "extra_specs", return_raw=True)
  61. def unset_keys(self, keys):
  62. """
  63. Unset extra specs on a flavor.
  64. :param flavor: The :class:`Flavor` to unset extra spec on
  65. :param keys: A list of keys to be unset
  66. """
  67. for k in keys:
  68. self.manager._delete(
  69. "/flavors/%s/os-extra_specs/%s" % (base.getid(self), k))
  70. def delete(self):
  71. """
  72. Delete this flavor.
  73. """
  74. self.manager.delete(self)
  75. class FlavorManager(base.ManagerWithFind):
  76. """
  77. Manage :class:`Flavor` resources.
  78. """
  79. resource_class = Flavor
  80. is_alphanum_id_allowed = True
  81. def list(self, detailed=True, is_public=True):
  82. """
  83. Get a list of all flavors.
  84. :rtype: list of :class:`Flavor`.
  85. """
  86. qparams = {}
  87. # is_public is ternary - None means give all flavors.
  88. # By default Nova assumes True and gives admins public flavors
  89. # and flavors from their own projects only.
  90. if not is_public:
  91. qparams['is_public'] = is_public
  92. query_string = "?%s" % parse.urlencode(qparams) if qparams else ""
  93. detail = ""
  94. if detailed:
  95. detail = "/detail"
  96. return self._list("/flavors%s%s" % (detail, query_string), "flavors")
  97. def get(self, flavor):
  98. """
  99. Get a specific flavor.
  100. :param flavor: The ID of the :class:`Flavor` to get.
  101. :rtype: :class:`Flavor`
  102. """
  103. return self._get("/flavors/%s" % base.getid(flavor), "flavor")
  104. def delete(self, flavor):
  105. """
  106. Delete a specific flavor.
  107. :param flavor: The ID of the :class:`Flavor` to get.
  108. """
  109. self._delete("/flavors/%s" % base.getid(flavor))
  110. def _build_body(self, name, ram, vcpus, disk, id, swap,
  111. ephemeral, rxtx_factor, is_public):
  112. return {
  113. "flavor": {
  114. "name": name,
  115. "ram": ram,
  116. "vcpus": vcpus,
  117. "disk": disk,
  118. "id": id,
  119. "swap": swap,
  120. "OS-FLV-EXT-DATA:ephemeral": ephemeral,
  121. "rxtx_factor": rxtx_factor,
  122. "os-flavor-access:is_public": is_public,
  123. }
  124. }
  125. def create(self, name, ram, vcpus, disk, flavorid="auto",
  126. ephemeral=0, swap=0, rxtx_factor=1.0, is_public=True):
  127. """
  128. Create a flavor.
  129. :param name: Descriptive name of the flavor
  130. :param ram: Memory in MB for the flavor
  131. :param vcpus: Number of VCPUs for the flavor
  132. :param disk: Size of local disk in GB
  133. :param flavorid: ID for the flavor (optional). You can use the reserved
  134. value ``"auto"`` to have Nova generate a UUID for the
  135. flavor in cases where you cannot simply pass ``None``.
  136. :param swap: Swap space in MB
  137. :param rxtx_factor: RX/TX factor
  138. :rtype: :class:`Flavor`
  139. """
  140. try:
  141. ram = int(ram)
  142. except (TypeError, ValueError):
  143. raise exceptions.CommandError(_("Ram must be an integer."))
  144. try:
  145. vcpus = int(vcpus)
  146. except (TypeError, ValueError):
  147. raise exceptions.CommandError(_("VCPUs must be an integer."))
  148. try:
  149. disk = int(disk)
  150. except (TypeError, ValueError):
  151. raise exceptions.CommandError(_("Disk must be an integer."))
  152. if flavorid == "auto":
  153. flavorid = None
  154. try:
  155. swap = int(swap)
  156. except (TypeError, ValueError):
  157. raise exceptions.CommandError(_("Swap must be an integer."))
  158. try:
  159. ephemeral = int(ephemeral)
  160. except (TypeError, ValueError):
  161. raise exceptions.CommandError(_("Ephemeral must be an integer."))
  162. try:
  163. rxtx_factor = float(rxtx_factor)
  164. except (TypeError, ValueError):
  165. raise exceptions.CommandError(_("rxtx_factor must be a float."))
  166. try:
  167. is_public = strutils.bool_from_string(is_public, True)
  168. except Exception:
  169. raise exceptions.CommandError(_("is_public must be a boolean."))
  170. body = self._build_body(name, ram, vcpus, disk, flavorid, swap,
  171. ephemeral, rxtx_factor, is_public)
  172. return self._create("/flavors", body, "flavor")