resources.py 75 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606
  1. """
  2. Specifications for data objects exposed through a ``provider`` or ``service``.
  3. """
  4. from __future__ import annotations
  5. from abc import ABCMeta
  6. from abc import abstractmethod
  7. from abc import abstractproperty
  8. from collections.abc import Iterable
  9. from datetime import datetime
  10. from enum import Enum
  11. from typing import Any
  12. from typing import Generic
  13. from typing import IO
  14. from typing import Iterator
  15. from typing import TYPE_CHECKING
  16. from typing import TypeVar
  17. if TYPE_CHECKING:
  18. from cloudbridge.interfaces.provider import CloudProvider
  19. from cloudbridge.interfaces.subservices import BucketObjectSubService
  20. from cloudbridge.interfaces.subservices import DnsRecordSubService
  21. from cloudbridge.interfaces.subservices import FloatingIPSubService
  22. from cloudbridge.interfaces.subservices import GatewaySubService
  23. from cloudbridge.interfaces.subservices import SubnetSubService
  24. from cloudbridge.interfaces.subservices import VMFirewallRuleSubService
  25. # Element type for pageable collections (services and ResultList). Every such
  26. # element is a CloudResource, so the bound lets paging code read `.id` without
  27. # casting.
  28. T = TypeVar("T", bound="CloudResource")
  29. class CloudServiceType(object):
  30. """
  31. Defines possible service types that are offered by providers.
  32. Providers can implement the ``has_service`` method and clients can check
  33. for the availability of a service with::
  34. if (provider.has_service(CloudServiceTypes.BUCKET))
  35. ...
  36. """
  37. COMPUTE = 'compute'
  38. IMAGE = 'image'
  39. SECURITY = 'security'
  40. VOLUME = 'storage.volumes'
  41. BUCKET = 'storage.buckets'
  42. DNS = 'dns'
  43. class CloudResource(object):
  44. """
  45. Base interface for any Resource supported by a provider.
  46. This interface has a _provider property that can be used to access the
  47. provider associated with the resource, which is only intended for use by
  48. subclasses. Every CloudBridge resource also has an id, a name and a
  49. label property. The id property is a unique identifier for the resource.
  50. The name is a more user-friendly version of an id, suitable for
  51. display to an end-user. However, it cannot be used in place of id. See
  52. @name documentation. The label property is a user-assignable
  53. identifier for the resource.
  54. """
  55. __metaclass__ = ABCMeta
  56. @abstractproperty
  57. def _provider(self) -> CloudProvider:
  58. """
  59. Returns the provider instance associated with this resource.
  60. Intended for use by subclasses only.
  61. :rtype: :class:`.CloudProvider`
  62. :return: a CloudProvider object
  63. """
  64. pass
  65. @abstractproperty
  66. def id(self) -> str:
  67. """
  68. Get the resource identifier.
  69. The id property is used to uniquely identify the resource, and is an
  70. opaque value which should not be interpreted by CloudBridge clients,
  71. and is a value meaningful to the underlying cloud provider.
  72. :rtype: ``str``
  73. :return: ID for this resource as returned by the cloud middleware.
  74. """
  75. pass
  76. @abstractproperty
  77. def name(self) -> str:
  78. """
  79. Get the name id for the resource.
  80. The name property is typically a user-friendly id value for the
  81. resource. The name is different from the id property in the following
  82. ways:
  83. 1. The name property is often a more user-friendly value to
  84. display to the user than the id property.
  85. 2. The name may sometimes be the same as the id, but should never
  86. be used in place of the id.
  87. 3. The id is what will uniquely identify a resource, and will be used
  88. internally by CloudBridge for all get operations etc.
  89. 4. All resources have a name.
  90. 5. The name is read-only.
  91. 6. However, the name may not necessarily be unique, which is the
  92. reason why it should not be used for uniquely identifying a
  93. resource.
  94. Example:
  95. The AWS machine image name maps to a CloudBridge name. It is not
  96. editable and is a user friendly name such as 'Ubuntu 18.04' and
  97. corresponds to the ami-name. It is distinct from the ami-id, which
  98. maps to CloudBridge's id property. The ami-name cannot be edited, and
  99. is set at creation time. It is not necessarily unique.
  100. In Azure, the machine image's name corresponds to CloudBridge's name
  101. property. In Azure, it also happens to be the same as the id property.
  102. The name property and the label property share the same character
  103. restrictions. See :py:attr:`~LabeledCloudResource.label`.
  104. """
  105. pass
  106. @abstractmethod
  107. def to_json(self) -> dict[str, Any]:
  108. """
  109. Returns a JSON representation of the CloudResource object.
  110. """
  111. pass
  112. class LabeledCloudResource(CloudResource):
  113. @abstractproperty
  114. def label(self) -> str | None:
  115. """
  116. Get the resource label.
  117. The label property is a user-defined, editable identifier for a
  118. resource. It will often correspond to a user editable resource label
  119. in the underlying cloud provider, or be simulated through tags/labels.
  120. The label property adheres to the following restrictions:
  121. * Must be at least 3 characters in length.
  122. * Cannot be longer than 63 characters.
  123. * May only contain ASCII characters comprising of lowercase letters,
  124. numeric characters, and dashes.
  125. * Must begin with an alphanumeric character and end with one
  126. (i.e. cannot begin or end with a dash)
  127. Some resources may not support labels, in which case, a
  128. ``NotImplementedError`` will be thrown.
  129. :rtype: ``str``
  130. :return: Label for this resource as returned by the cloud middleware.
  131. :raise: ``NotImplementedError`` if this resource does not support
  132. labels.
  133. """
  134. pass
  135. class Configuration(dict[str, Any]):
  136. """
  137. Represents a CloudBridge configuration object
  138. """
  139. @abstractproperty
  140. def default_result_limit(self) -> int:
  141. """
  142. Get the default maximum number of results to return for a list method.
  143. The default limit will be applied to most ``list()`` and ``find()``
  144. methods whenever an explicit limit is not specified.
  145. :rtype: ``int``
  146. :return: The maximum number of results to return
  147. """
  148. pass
  149. @abstractproperty
  150. def default_wait_timeout(self) -> int:
  151. """
  152. Get the default wait timeout for ``LifeCycleObjects``.
  153. The default wait timeout is applied in ``wait_for()`` and
  154. ``wait_till_ready()`` methods if no explicit timeout is specified.
  155. :rtype: ``int``
  156. :return: The maximum length of time (in seconds) to wait for the object
  157. to change to desired state.
  158. """
  159. pass
  160. @abstractproperty
  161. def default_wait_interval(self) -> int:
  162. """
  163. Get the default wait interval for ``LifeCycleObjects``.
  164. The default wait interval is applied in ``wait_for()`` and
  165. ``wait_till_ready()`` methods if no explicit interval is specified.
  166. :rtype: ``int``
  167. :return: How frequently to poll the object's state.
  168. """
  169. pass
  170. @abstractproperty
  171. def debug_mode(self) -> bool:
  172. """
  173. A flag indicating whether CloudBridge is in debug mode.
  174. Setting this to ``True`` will cause the underlying provider's debug
  175. output to be turned on. The flag can be toggled by sending in the
  176. ``cb_debug`` value via the config dictionary, or setting the
  177. ``CB_DEBUG`` environment variable.
  178. :rtype: ``bool``
  179. :return: Whether debug mode is on.
  180. """
  181. class ObjectLifeCycleMixin(object):
  182. """
  183. A mixin for an object with a defined life-cycle.
  184. Object examples include an Instance, Volume, Image, or Snapshot. An object
  185. that supports ObjectLifeCycleMixin will always have a state, defining which
  186. point in its life cycle it is currently at.
  187. It also defines a ``wait_till_ready`` operation, which indicates that the
  188. object is in a state in its life cycle where it is ready to be used by an
  189. end-user.
  190. A ``refresh`` operation allows the object to synchronize its state with the
  191. service provider.
  192. """
  193. __metaclass__ = ABCMeta
  194. @abstractproperty
  195. def _provider(self) -> CloudProvider:
  196. """
  197. Obtain the provider associated with this object.
  198. This property is used internally to access the provider config and get
  199. default timeouts/intervals.
  200. :rtype: :class:`.CloudProvider` :return: The provider associated with
  201. this Resource
  202. """
  203. pass
  204. @abstractproperty
  205. def state(self) -> str:
  206. """
  207. Get the current state of this object.
  208. :rtype: ``str``
  209. :return: The current state as a string.
  210. """
  211. pass
  212. @abstractmethod
  213. def refresh(self) -> None:
  214. """
  215. Refresh this object's state and synchronize it with the provider.
  216. """
  217. pass
  218. @abstractmethod
  219. def wait_for(self, target_states: list[str],
  220. terminal_states: list[str] | None = None,
  221. timeout: int | None = None,
  222. interval: int | None = None) -> bool:
  223. """
  224. Wait for for an object to reach a one of desired target states.
  225. If the object does not reach the desired state within the specified
  226. timeout, a ``WaitStateException`` will be raised. The optional
  227. ``terminal_states`` property can be used to specify an additional set
  228. of states which, should the object reach one, the object thereafter
  229. will not transition into the desired target state. Should this happen,
  230. a ``WaitStateException`` will be raised.
  231. Example:
  232. .. code-block:: python
  233. instance.wait_for(
  234. [InstanceState.DELETED, InstanceState.UNKNOWN],
  235. terminal_states=[InstanceState.ERROR])
  236. :type target_states: ``list`` of states
  237. :param target_states: The list of target states to wait for.
  238. :type terminal_states: ``list`` of states
  239. :param terminal_states: A list of terminal states after which the
  240. object will not transition into a target state.
  241. A WaitStateException will be raised if the
  242. object transition into a terminal state.
  243. :type timeout: ``int``
  244. :param timeout: The maximum length of time (in seconds) to wait for the
  245. object to changed to desired state. If no timeout is
  246. specified, the global default_wait_timeout defined in
  247. the provider config will apply.
  248. :type interval: ``int``
  249. :param interval: How frequently to poll the object's state (in
  250. seconds). If no interval is specified, the global
  251. default_wait_interval defined in the provider config
  252. will apply.
  253. :rtype: ``True``
  254. :return: Returns ``True`` if successful. A ``WaitStateException``
  255. exception may be thrown by the underlying service if the
  256. object cannot get into a ready state (e.g. if the object
  257. is in an error state).
  258. """
  259. pass
  260. @abstractmethod
  261. def wait_till_ready(self, timeout: int | None = None,
  262. interval: int | None = None) -> None:
  263. """
  264. Wait till the current object reaches its ready state.
  265. An object's ready state is any state where the end-user can
  266. successfully interact with the object. Will throw a
  267. ``WaitStateException`` if the object is not ready within the specified
  268. timeout.
  269. :type timeout: ``int``
  270. :param timeout: The maximum length of time (in seconds) to wait for the
  271. object to become ready.
  272. :type interval: ``int``
  273. :param interval: How frequently to poll the object's ready state (in
  274. seconds).
  275. :rtype: ``True``
  276. :return: Returns ``True`` if successful. A ``WaitStateException``
  277. exception may be thrown by the underlying service if the
  278. object cannot get into a ready state (e.g. if the object
  279. is in an error state).
  280. """
  281. pass
  282. class PageableObjectMixin(Generic[T]):
  283. """
  284. A marker interface for objects which support paged iteration.
  285. The list of objects can be iterated over using the ``list(limit, marker)``
  286. method.
  287. """
  288. @abstractmethod
  289. def __iter__(self) -> Iterator[T]:
  290. """
  291. Enables iteration through this object.
  292. Typically, an implementation will call the ``list(limit, marker)``
  293. method to transparently page additional objects in as iteration
  294. progresses.
  295. """
  296. pass
  297. @abstractmethod
  298. def list(self, limit: int | None = None,
  299. marker: str | None = None) -> ResultList[T]:
  300. """
  301. Returns a list of objects up to a maximum limit.
  302. If a limit and marker are specified, the records will be fetched up to
  303. the limit starting from the marker onwards. The returned list is a list
  304. of class ResultList, which has extra properties like is_truncated,
  305. supports_total and total_records to provide extra information
  306. about record availability.
  307. If limit is not specified, the limit will default to the underlying
  308. provider's default limit. Therefore, you need to check the is_truncated
  309. property to determine whether more records are available.
  310. The total number of results can be determined through the total_results
  311. property. Not all provides will support returning the total_results
  312. property, so the supports_total property can be used to determine
  313. whether a total is supported.
  314. To iterate through all the records, it will be easier to iterate
  315. directly through the instances using __iter__ instead of calling
  316. the list method. The __iter__ method will automatically call the list
  317. method to fetch a batch of records at a time.
  318. Example:
  319. .. code-block:: python
  320. # get first page of results
  321. instlist = provider.compute.instances.list(limit=50)
  322. for instance in instlist:
  323. print("Instance Data: {0}", instance)
  324. if instlist.supports_total:
  325. print("Total results: {0}".format(instlist.total_results))
  326. else:
  327. print("Total records unknown,"
  328. "but has more data?: {0}".format(instlist.is_truncated))
  329. # Page to next set of results
  330. if (instlist.is_truncated)
  331. instlist = provider.compute.instances.list(limit=100,
  332. marker=instlist.marker)
  333. # Alternative: iterate through every available record
  334. for instance in provider.compute.instances:
  335. print(instance)
  336. """
  337. pass
  338. class ResultList(list[T]):
  339. """
  340. Provide extra properties to aid with paging through a many results.
  341. This is a wrapper class around a standard Python :py:class:`list` class.
  342. Example:
  343. .. code-block:: python
  344. # get first page of results
  345. rl = provider.compute.instances.list(limit=50)
  346. for result in rl:
  347. print("Instance Data: {0}", result)
  348. if rl.supports_total:
  349. print("Total results: {0}".format(rl.total_results))
  350. else:
  351. print("Total records unknown,"
  352. "but has more data?: {0}."format(rl.is_truncated))
  353. # Page to next set of results
  354. if (rl.is_truncated)
  355. rl = provider.compute.instances.list(limit=100,
  356. marker=rl.marker)
  357. """
  358. __metaclass__ = ABCMeta
  359. @abstractproperty
  360. def marker(self) -> str | None:
  361. """
  362. An opaque identifier used in paging through very long lists of objects.
  363. This marker can be provided to the list method to get the next set of
  364. results.
  365. """
  366. pass
  367. @abstractproperty
  368. def is_truncated(self) -> bool:
  369. """
  370. Indicate whether this result list has more results that can be paged.
  371. """
  372. pass
  373. @abstractproperty
  374. def supports_total(self) -> bool:
  375. """
  376. Indicate whether can obtain the total number of available results.
  377. The ``supports_total`` property should be checked before accessing the
  378. ``total_results`` property. This is a provider-specific property.
  379. """
  380. pass
  381. @abstractproperty
  382. def total_results(self) -> int:
  383. """
  384. Indicate the total number of results for a particular query.
  385. The ``supports_total`` property should be used to check whether the
  386. provider supports returning the total number of results, before
  387. accessing this property, or the behavior is indeterminate.
  388. """
  389. pass
  390. @abstractproperty
  391. def supports_server_paging(self) -> bool:
  392. """
  393. Indicate whether this ``ResultList`` supports server side paging.
  394. If server side paging is not supported, the result will use client side
  395. paging and the data property provides direct access to all available
  396. data.
  397. """
  398. pass
  399. @abstractproperty
  400. def data(self) -> list[T]:
  401. pass
  402. class InstanceState(object):
  403. """
  404. Standard states for an instance.
  405. :cvar UNKNOWN: Instance state unknown.
  406. :cvar PENDING: Instance is pending
  407. :cvar CONFIGURING: Instance is being reconfigured in some way.
  408. :cvar RUNNING: Instance is running.
  409. :cvar REBOOTING: Instance is rebooting.
  410. :cvar DELETED: Instance is deleted. No further operations possible.
  411. :cvar STOPPED: Instance is stopped. Instance can be resumed.
  412. :cvar ERROR: Instance is in an error state. No further operations possible.
  413. """
  414. UNKNOWN = "unknown"
  415. PENDING = "pending"
  416. CONFIGURING = "configuring"
  417. RUNNING = "running"
  418. REBOOTING = "rebooting"
  419. DELETED = "deleted"
  420. STOPPED = "stopped"
  421. ERROR = "error"
  422. class Instance(ObjectLifeCycleMixin, LabeledCloudResource):
  423. __metaclass__ = ABCMeta
  424. @LabeledCloudResource.label.setter # type: ignore[attr-defined]
  425. @abstractmethod
  426. def label(self, value: str) -> None:
  427. """
  428. Set the instance label.
  429. :type value: ``str``
  430. :param value: The value to set the label to.
  431. """
  432. pass
  433. @abstractproperty
  434. def public_ips(self) -> list[str]:
  435. """
  436. Get all the public IP addresses for this instance.
  437. :rtype: ``list``
  438. :return: A list of public IP addresses associated with this instance.
  439. """
  440. pass
  441. @abstractproperty
  442. def private_ips(self) -> list[str]:
  443. """
  444. Get all the private IP addresses for this instance.
  445. :rtype: ``list``
  446. :return: A list of private IP addresses associated with this instance.
  447. """
  448. pass
  449. @abstractproperty
  450. def vm_type_id(self) -> str:
  451. """
  452. Get the VM type id for this instance.
  453. This will typically be a string value like 'm1.large'. On OpenStack,
  454. this may be a number or UUID. To get the full :class:``.VMType``
  455. object, you can use the ``instance.vm_type`` property instead.
  456. :rtype: ``str``
  457. :return: VM type id for this instance (e.g., ``m1.large``)
  458. """
  459. pass
  460. @abstractproperty
  461. def vm_type(self) -> VMType:
  462. """
  463. Retrieve full VM type information for this instance.
  464. :rtype: :class:`.VMType`
  465. :return: VM type for this instance
  466. """
  467. pass
  468. @abstractproperty
  469. def create_time(self) -> str | datetime:
  470. """
  471. Get the creation data and time for this instance.
  472. :rtype: ``DateTime``
  473. :return: Creation time for this instance as returned by the cloud
  474. middleware.
  475. """
  476. pass
  477. @abstractmethod
  478. def reboot(self) -> None:
  479. """
  480. Reboot this instance (using the cloud middleware API).
  481. :rtype: ``bool``
  482. :return: ``True`` if the reboot was successful; ``False`` otherwise.
  483. """
  484. pass
  485. @abstractmethod
  486. def start(self) -> None:
  487. """
  488. Start this instance (using the cloud middleware API)
  489. """
  490. pass
  491. @abstractmethod
  492. def stop(self) -> None:
  493. """
  494. Stop this instance (using the cloud middleware API)
  495. """
  496. pass
  497. @abstractmethod
  498. def delete(self) -> None:
  499. """
  500. Permanently delete this instance.
  501. """
  502. pass
  503. @abstractproperty
  504. def image_id(self) -> str:
  505. """
  506. Get the image ID for this instance.
  507. :rtype: ``str``
  508. :return: Image ID (i.e., AMI) this instance is using.
  509. """
  510. pass
  511. @abstractproperty
  512. def zone_id(self) -> str:
  513. """
  514. Get the placement zone ID where this instance is running.
  515. :rtype: ``str``
  516. :return: Region/zone/placement where this instance is running.
  517. """
  518. pass
  519. @abstractproperty
  520. def subnet_id(self) -> str:
  521. """
  522. Get the subnet ID where this instance is placed.
  523. :rtype: ``str``
  524. :return: Subnet ID to which this instance is connected.
  525. """
  526. pass
  527. # @abstractproperty
  528. # def mac_address(self):
  529. # """
  530. # Get the MAC address for this instance.
  531. #
  532. # :rtype: str
  533. # :return: MAC address for ths instance.
  534. # """
  535. # pass
  536. @abstractproperty
  537. def vm_firewalls(self) -> list[VMFirewall]:
  538. """
  539. Get the firewalls (security groups) associated with this instance.
  540. :rtype: list or :class:`.VMFirewall` objects
  541. :return: A list of VMFirewall objects associated with this instance.
  542. """
  543. pass
  544. @abstractproperty
  545. def vm_firewall_ids(self) -> list[str]:
  546. """
  547. Get the IDs of the VM firewalls associated with this instance.
  548. :rtype: list or :class:``str``
  549. :return: A list of the VMFirewall IDs associated with this instance.
  550. """
  551. pass
  552. @abstractproperty
  553. def key_pair_id(self) -> str | None:
  554. """
  555. Get the id of the key pair associated with this instance.
  556. :rtype: ``str``
  557. :return: Id of the ssh key pair associated with this instance.
  558. """
  559. pass
  560. @abstractmethod
  561. def create_image(self, label: str) -> MachineImage:
  562. """
  563. Create a new image based on this instance.
  564. :rtype: :class:``.Image``
  565. :return: an Image object
  566. """
  567. pass
  568. @abstractmethod
  569. def add_floating_ip(self, floating_ip: FloatingIP | str) -> None:
  570. """
  571. Add a public IP address to this instance.
  572. :type floating_ip: :class:``.FloatingIP`` or floating IP ID
  573. :param floating_ip: The FloatingIP object to associate with the
  574. instance. Note that is not the actual public IP
  575. address but the CloudBridge object encapsulating
  576. the IP or the respective provider ID that
  577. identifies the address.
  578. """
  579. pass
  580. @abstractmethod
  581. def remove_floating_ip(self, floating_ip: FloatingIP | str) -> None:
  582. """
  583. Remove a public IP address from this instance.
  584. :type floating_ip: :class:``.FloatingIP`` or floating IP ID
  585. :param floating_ip: The FloatingIP object to remove from the
  586. instance. Note that is not the actual public IP
  587. address but the CloudBridge object encapsulating
  588. the IP or the respective provider ID that
  589. identifies the address.
  590. """
  591. pass
  592. @abstractmethod
  593. def add_vm_firewall(self, firewall: VMFirewall) -> None:
  594. """
  595. Add a VM firewall to this instance
  596. :type firewall: :class:``.VMFirewall``
  597. :param firewall: The VMFirewall to associate with the instance.
  598. """
  599. pass
  600. @abstractmethod
  601. def remove_vm_firewall(self, firewall: VMFirewall) -> None:
  602. """
  603. Remove a VM firewall from this instance
  604. :type firewall: ``VMFirewall``
  605. :param firewall: The VMFirewall to associate with the instance.
  606. """
  607. pass
  608. class MachineImageState(object):
  609. """
  610. Standard states for a machine image
  611. :cvar UNKNOWN: Image state unknown.
  612. :cvar PENDING: Image is pending
  613. :cvar AVAILABLE: Image is available
  614. :cvar ERROR: Image is in an error state. Not recoverable.
  615. """
  616. UNKNOWN = "unknown"
  617. PENDING = "pending"
  618. AVAILABLE = "available"
  619. ERROR = "error"
  620. class LaunchConfig(object):
  621. """
  622. Represents an advanced launch configuration object.
  623. This object can contain information such as ``BlockDeviceMappings``
  624. configurations and other advanced options, which may be useful when
  625. launching an instance.
  626. Example:
  627. .. code-block:: python
  628. lc = provider.compute.instances.create_launch_config()
  629. lc.add_block_device(...)
  630. inst = provider.compute.instances.create(
  631. 'MyVM', image, vm_type, subnet, launch_config=lc)
  632. """
  633. @abstractmethod
  634. def add_ephemeral_device(self) -> None:
  635. """
  636. Add a new ephemeral block device mapping to the boot configuration.
  637. This can be used to add existing ephemeral devices to the instance
  638. (the total number of ephemeral devices available for a particular
  639. ``VMType`` can be determined by querying the ``VMType`` service).
  640. Note that on some providers, such as AWS, ephemeral devices must be
  641. added in as a device mapping at instance creation time and cannot be
  642. added afterwards.
  643. Note that the device name, such as */dev/sda1*, cannot be selected at
  644. present, since this tends to be provider and VM type specific.
  645. However, the order of device addition coupled with device type will
  646. generally determine naming order, with devices added first getting
  647. lower letters than instances added later.
  648. Example:
  649. .. code-block:: python
  650. lc = provider.compute.instances.create_launch_config()
  651. # 1. Add all available ephemeral devices
  652. vm_type = provider.compute.vm_types.find(name='m1.tiny')[0]
  653. for i in range(vm_type.num_ephemeral_disks):
  654. lc.add_ephemeral_device()
  655. """
  656. pass
  657. @abstractmethod
  658. def add_volume_device(self, source: Volume | Snapshot | MachineImage | None = None,
  659. is_root: bool | None = None, size: int | None = None,
  660. delete_on_terminate: bool | None = None) -> None:
  661. """
  662. Add a new volume based block device mapping to the boot configuration.
  663. The volume can be based on a snapshot, image, existing volume or
  664. be a blank new volume, and is specified by the source parameter.
  665. The property ``is_root`` can be set to ``True`` to override any
  666. existing root device mappings. Otherwise, the default behavior is to
  667. add new block devices to the instance.
  668. Note that the device name, such as */dev/sda1*, cannot be selected at
  669. present since this tends to be provider and VM type specific. However,
  670. the order of device addition coupled with device type will generally
  671. determine naming order, with devices added first getting lower letters
  672. than instances added later (except when ``is_root`` is set).
  673. Example:
  674. .. code-block:: python
  675. lc = provider.compute.instances.create_launch_config()
  676. # 1. Create and attach an empty volume of size 100GB
  677. lc.add_volume_device(size=100, delete_on_terminate=True)
  678. # 2. Create and attach a volume based on a snapshot
  679. snap = provider.storage.snapshots.get('<my_snapshot_id>')
  680. lc.add_volume_device(source=snap)
  681. # 3. Create+attach a volume based on an image and set it as root
  682. img = provider.compute.images.get('<my_image_id>')
  683. lc.add_volume_device(source=img, size=100, is_root=True)
  684. :type source: ``Volume``, ``Snapshot``, ``Image`` or None.
  685. :param source: The source ``block_device`` to add. If ``Volume``, the
  686. volume will be attached directly to the instance.
  687. If ``Snapshot``, a volume will be created based on the
  688. Snapshot and attached to the instance. If ``Image``,
  689. a volume based on the Image will be attached to the
  690. instance. If ``None``, the source is assumed to be
  691. a blank volume.
  692. :type is_root: ``bool``
  693. :param is_root: Determines which device will serve as the root device.
  694. If more than one device is defined as root, an
  695. ``InvalidConfigurationException`` will be thrown.
  696. :type size: ``int``
  697. :param size: The size of the volume to create. An implementation may
  698. ignore this parameter for certain sources like 'Volume'.
  699. :type delete_on_terminate: ``bool``
  700. :param delete_on_terminate: Determines whether to delete or keep the
  701. volume on instance termination.
  702. """
  703. pass
  704. class MachineImage(ObjectLifeCycleMixin, LabeledCloudResource):
  705. __metaclass__ = ABCMeta
  706. @abstractproperty
  707. def description(self) -> str | None:
  708. """
  709. Get the image description.
  710. :rtype: ``str``
  711. :return: Description for this image as returned by the cloud
  712. middleware.
  713. """
  714. pass
  715. @abstractproperty
  716. def min_disk(self) -> int | None:
  717. """
  718. Return the minimum size of the disk that's required to boot this image.
  719. Value returned is in gigabytes.
  720. :rtype: ``int``
  721. :return: The minimum disk size needed by this image.
  722. """
  723. pass
  724. @abstractmethod
  725. def delete(self) -> None:
  726. """
  727. Delete this image.
  728. :rtype: ``bool``
  729. :return: ``True`` if the operation succeeded.
  730. """
  731. pass
  732. class NetworkState(object):
  733. """
  734. Standard states for a network.
  735. :cvar UNKNOWN: Network state unknown.
  736. :cvar PENDING: Network is being created.
  737. :cvar AVAILABLE: Network is available.
  738. :cvar DOWN: Network is not operational.
  739. :cvar ERROR: Network is in error state.
  740. """
  741. UNKNOWN = "unknown"
  742. PENDING = "pending"
  743. AVAILABLE = "available"
  744. DOWN = "down"
  745. ERROR = "error"
  746. class Network(ObjectLifeCycleMixin, LabeledCloudResource):
  747. """
  748. Represents a software-defined network, like the Virtual Private Cloud.
  749. """
  750. __metaclass__ = ABCMeta
  751. @LabeledCloudResource.label.setter # type: ignore[attr-defined]
  752. @abstractmethod
  753. def label(self, value: str) -> None:
  754. """
  755. Set the resource label.
  756. :type value: ``str``
  757. :param value: The value to set the label to.
  758. """
  759. pass
  760. @abstractproperty
  761. def external(self) -> bool:
  762. """
  763. A flag to indicate if this network is capable of Internet-connectivity.
  764. :rtype: ``bool``
  765. :return: ``True`` if the network can be connected to the Internet.
  766. """
  767. pass
  768. @abstractproperty
  769. def state(self) -> str:
  770. """
  771. The state of the network.
  772. :rtype: ``str``
  773. :return: One of ``unknown``, ``pending``, ``available``, ``down`` or
  774. ``error``.
  775. """
  776. pass
  777. @abstractproperty
  778. def cidr_block(self) -> str:
  779. """
  780. A CIDR block for this network.
  781. .. note:: OpenStack does not define a CIDR block for networks.
  782. :rtype: ``str``
  783. :return: A CIDR block string.
  784. """
  785. pass
  786. @abstractmethod
  787. def delete(self) -> None:
  788. """
  789. Delete this network.
  790. :rtype: ``bool``
  791. :return: ``True`` if successful.
  792. """
  793. pass
  794. @abstractproperty
  795. def subnets(self) -> SubnetSubService:
  796. """
  797. The associated subnets.
  798. :rtype: ``list`` of :class:`.Subnet`
  799. :return: List of subnets associated with this network.
  800. """
  801. pass
  802. @abstractproperty
  803. def gateways(self) -> GatewaySubService:
  804. """
  805. Provides access to the internet gateways attached to this network.
  806. :rtype: :class:`.GatewaySubService`
  807. :return: A GatewaySubService object
  808. """
  809. pass
  810. class SubnetState(object):
  811. """
  812. Standard states for a subnet.
  813. :cvar UNKNOWN: Subnet state unknown.
  814. :cvar PENDING: Subnet is being created.
  815. :cvar AVAILABLE: Subnet is available.
  816. :cvar DOWN: Subnet is not operational.
  817. :cvar ERROR: Subnet is in error state.
  818. """
  819. UNKNOWN = "unknown"
  820. PENDING = "pending"
  821. AVAILABLE = "available"
  822. DOWN = "down"
  823. ERROR = "error"
  824. class Subnet(ObjectLifeCycleMixin, LabeledCloudResource):
  825. """
  826. Represents a subnet, as part of a Network.
  827. """
  828. __metaclass__ = ABCMeta
  829. @LabeledCloudResource.label.setter # type: ignore[attr-defined]
  830. @abstractmethod
  831. def label(self, value: str) -> None:
  832. """
  833. Set the resource label.
  834. :type value: ``str``
  835. :param value: The value to set the label to.
  836. """
  837. pass
  838. @abstractproperty
  839. def cidr_block(self) -> str:
  840. """
  841. A CIDR block for this subnet.
  842. :rtype: ``str``
  843. :return: A CIDR block string.
  844. """
  845. pass
  846. @abstractproperty
  847. def network_id(self) -> str:
  848. """
  849. ID of the network associated with this this subnet.
  850. :rtype: ``str``
  851. :return: Network ID.
  852. """
  853. pass
  854. @abstractproperty
  855. def network(self) -> Network:
  856. """
  857. The parent network object associated with this this subnet.
  858. :rtype: ``Network``
  859. :return: `Network` object
  860. """
  861. pass
  862. @abstractproperty
  863. def zone(self) -> PlacementZone | None:
  864. """
  865. Placement zone of the subnet.
  866. If the provider does not support subnet placement, return ``None``.
  867. :rtype: :class:`.PlacementZone` object
  868. :return: Placement zone of the subnet, or ``None`` if not defined.
  869. """
  870. pass
  871. @abstractmethod
  872. def delete(self) -> None:
  873. """
  874. Delete this subnet.
  875. :rtype: ``bool``
  876. :return: ``True`` if successful.
  877. """
  878. pass
  879. class FloatingIpState(object):
  880. """
  881. Standard states for a floating ip.
  882. :cvar UNKNOWN: Floating IP state unknown.
  883. :cvar AVAILABLE: Floating IP is available.
  884. :cvar IN_USE: Floating IP is attached to a device.
  885. :cvar ERROR: Floating IP is in an error state.
  886. """
  887. UNKNOWN = "unknown"
  888. AVAILABLE = "available"
  889. IN_USE = "in_use"
  890. ERROR = "error"
  891. class FloatingIP(ObjectLifeCycleMixin, CloudResource):
  892. """
  893. Represents a floating (i.e., static) IP address.
  894. """
  895. __metaclass__ = ABCMeta
  896. @abstractproperty
  897. def public_ip(self) -> str:
  898. """
  899. Public IP address.
  900. :rtype: ``str``
  901. :return: IP address.
  902. """
  903. pass
  904. @abstractproperty
  905. def private_ip(self) -> str | None:
  906. """
  907. Private IP address this address is attached to.
  908. :rtype: ``str``
  909. :return: IP address or ``None``.
  910. """
  911. pass
  912. @abstractproperty
  913. def in_use(self) -> bool:
  914. """
  915. Whether the address is in use or not.
  916. :rtype: ``bool``
  917. :return: ``True`` if the address is attached to an instance.
  918. """
  919. pass
  920. @abstractmethod
  921. def delete(self) -> None:
  922. """
  923. Delete this address.
  924. :rtype: ``bool``
  925. :return: ``True`` if successful.
  926. """
  927. pass
  928. class RouterState(object):
  929. """
  930. Standard states for a router.
  931. :cvar UNKNOWN: Router state unknown.
  932. :cvar ATTACHED: Router is attached to a network and should be operational.
  933. :cvar DETACHED: Router is detached from a network.
  934. """
  935. UNKNOWN = "unknown"
  936. ATTACHED = "attached"
  937. DETACHED = "detached"
  938. class Router(LabeledCloudResource):
  939. """
  940. Represents a private network router.
  941. This logical router is meant to roughly mimic the properties of a physical
  942. router. Therefore, attaching a subnet can be thought of as plugging in a
  943. network cable to enable routing to/from that subnet. Attaching a gateway
  944. can be thought of as plugging in an upstream link.
  945. """
  946. __metaclass__ = ABCMeta
  947. @LabeledCloudResource.label.setter # type: ignore[attr-defined]
  948. @abstractmethod
  949. def label(self, value: str) -> None:
  950. """
  951. Set the resource label.
  952. :type value: ``str``
  953. :param value: The value to set the label to.
  954. """
  955. pass
  956. @abstractproperty
  957. def state(self) -> str:
  958. """
  959. Router state: attached or detached to a network.
  960. :rtype: ``str``
  961. :return: ``attached`` or ``detached``.
  962. """
  963. pass
  964. @abstractproperty
  965. def network_id(self) -> str | None:
  966. """
  967. ID of the network to which the router is attached.
  968. :rtype: ``str``
  969. :return: ID for the attached network or ``None``.
  970. """
  971. pass
  972. @abstractmethod
  973. def delete(self) -> None:
  974. """
  975. Delete this router.
  976. :rtype: ``bool``
  977. :return: ``True`` if successful.
  978. """
  979. pass
  980. @abstractmethod
  981. def attach_subnet(self, subnet: Subnet | str) -> None:
  982. """
  983. Attach this router to a subnet.
  984. :type subnet: ``Subnet`` or ``str``
  985. :param subnet: The subnet to which to attach this router.
  986. :rtype: ``bool``
  987. :return: ``True`` if successful.
  988. """
  989. pass
  990. @abstractmethod
  991. def detach_subnet(self, subnet: Subnet | str) -> None:
  992. """
  993. Detach this subnet from a network.
  994. :type subnet: ``Subnet`` or ``str``
  995. :param subnet: The subnet to detach from this router.
  996. :rtype: ``bool``
  997. :return: ``True`` if successful.
  998. """
  999. pass
  1000. @abstractproperty
  1001. def subnets(self) -> Iterable[Subnet]:
  1002. """
  1003. List of subnets attached to this router.
  1004. :rtype: ``list`` of :class:`.Subnet` objects
  1005. :return: A list of subnets associated with this router.
  1006. """
  1007. pass
  1008. @abstractmethod
  1009. def attach_gateway(self, gateway: Gateway) -> None:
  1010. """
  1011. Attach a gateway to this router.
  1012. :type gateway: ``Gateway``
  1013. :param gateway: The Gateway to attach to this router.
  1014. :rtype: ``bool``
  1015. :return: ``True`` if successful.
  1016. """
  1017. pass
  1018. @abstractmethod
  1019. def detach_gateway(self, gateway: Gateway) -> None:
  1020. """
  1021. Detach this router from a gateway.
  1022. :rtype: ``bool``
  1023. :return: ``True`` if successful.
  1024. """
  1025. pass
  1026. class GatewayState(object):
  1027. """
  1028. Standard states for a gateway.
  1029. :cvar UNKNOWN: Gateway state unknown.
  1030. :cvar CONFIGURING: Gateway is being configured
  1031. :cvar AVAILABLE: Gateway is ready
  1032. :cvar ERROR: Gateway is ready
  1033. """
  1034. UNKNOWN = "unknown"
  1035. CONFIGURING = "configuring"
  1036. AVAILABLE = "available"
  1037. ERROR = "error"
  1038. class Gateway(CloudResource):
  1039. """
  1040. Represents a gateway resource.
  1041. """
  1042. __metaclass__ = ABCMeta
  1043. @abstractproperty
  1044. def network_id(self) -> str | None:
  1045. """
  1046. ID of the network to which the gateway is attached.
  1047. :rtype: ``str``
  1048. :return: ID for the attached network or ``None``.
  1049. """
  1050. pass
  1051. @abstractmethod
  1052. def delete(self) -> None:
  1053. """
  1054. Delete this gateway. On some providers, if the gateway
  1055. is public/a singleton, this operation will do nothing.
  1056. """
  1057. pass
  1058. @abstractproperty
  1059. def floating_ips(self) -> FloatingIPSubService:
  1060. """
  1061. Provides access to floating IPs connected to this internet gateway.
  1062. :rtype: :class:`.FloatingIPSubService`
  1063. :return: A FloatingIPSubService object
  1064. """
  1065. pass
  1066. class InternetGateway(ObjectLifeCycleMixin, Gateway):
  1067. """
  1068. Represents an Internet gateway resource.
  1069. """
  1070. __metaclass__ = ABCMeta
  1071. class DnsZone(CloudResource):
  1072. """
  1073. Represents a dns host zone.
  1074. A host zone represents a top level domain (e.g. cloudve.org) in which
  1075. multiple dns records (e.g. A, CNAME. MX etc.) are contained.
  1076. """
  1077. __metaclass__ = ABCMeta
  1078. @abstractproperty
  1079. def admin_email(self) -> str | None:
  1080. """
  1081. Email address of this zone's administrator. Some cloud providers do not
  1082. support this field, and therefore, it may be stored in an extra field
  1083. such as description or not supported at all. (This field is mandatory
  1084. in OpenStack)
  1085. :return: Administrator's email as a string
  1086. """
  1087. pass
  1088. @abstractmethod
  1089. def delete(self) -> None:
  1090. """
  1091. Delete this zone.
  1092. """
  1093. pass
  1094. @abstractproperty
  1095. def records(self) -> DnsRecordSubService:
  1096. """
  1097. List of DNS records in this zone.
  1098. :rtype: ``list`` of :class:`.DnsRecord` objects
  1099. :return: A list of DnsRecords associated with this zone.
  1100. """
  1101. pass
  1102. class DnsRecordType(object):
  1103. """
  1104. DNS record types.
  1105. """
  1106. A = 'A'
  1107. AAAA = 'AAAA'
  1108. CNAME = 'CNAME'
  1109. MX = 'MX'
  1110. NS = 'NS'
  1111. PTR = 'PTR'
  1112. SPF = 'SPF'
  1113. SRV = 'SRV'
  1114. SSHFP = 'SSHFP'
  1115. TXT = 'TXT'
  1116. class DnsRecord(CloudResource):
  1117. """
  1118. Represents a dns record.
  1119. A dns record belongs to a host zone and can contain
  1120. records of varous types such as A, CNAME. MX etc.
  1121. """
  1122. __metaclass__ = ABCMeta
  1123. @abstractproperty
  1124. def zone_id(self) -> str:
  1125. """
  1126. The containing zone for this dns record
  1127. :rtype: ``str``
  1128. :return: The ID of the zone for this dns record
  1129. """
  1130. pass
  1131. @abstractproperty
  1132. def type(self) -> str:
  1133. """
  1134. Dns Record type which could be A, CNAME, MX, AAAA, PTR
  1135. :rtype: ``DnsRecordType``
  1136. :return: An enum representing the DNS record type.
  1137. """
  1138. pass
  1139. @abstractproperty
  1140. def data(self) -> list[str]:
  1141. """
  1142. Dns Record data
  1143. :rtype: ``str``
  1144. :return: A string containing this DNS record's data.
  1145. """
  1146. pass
  1147. @abstractproperty
  1148. def ttl(self) -> int:
  1149. """
  1150. ttl for this record
  1151. :rtype: ``int``
  1152. :return: The ttl (in seconds) for this record.
  1153. """
  1154. pass
  1155. class AttachmentInfo(object):
  1156. """
  1157. Contains attachment information for a volume.
  1158. """
  1159. @abstractproperty
  1160. def volume(self) -> Volume:
  1161. """
  1162. Get the volume instance related to this attachment.
  1163. :rtype: ``Volume``
  1164. :return: Volume object that this attachment info belongs to
  1165. """
  1166. pass
  1167. @abstractproperty
  1168. def instance_id(self) -> str:
  1169. """
  1170. Get the instance_id related to this attachment.
  1171. :rtype: ``str``
  1172. :return: Instance id that this attachment info belongs to
  1173. """
  1174. pass
  1175. @abstractproperty
  1176. def device(self) -> str | None:
  1177. """
  1178. Get the device the volume is mapped as.
  1179. :rtype: ``str``
  1180. :return: Device that the volume is mapped as
  1181. """
  1182. pass
  1183. class VolumeState(object):
  1184. """
  1185. Standard states for a volume
  1186. :cvar UNKNOWN: Volume state unknown.
  1187. :cvar CREATING: Volume is being created.
  1188. :cvar CONFIGURING: Volume is being configured in some way.
  1189. :cvar AVAILABLE: Volume is available and can be attached to an instance.
  1190. :cvar IN_USE: Volume is attached and in-use.
  1191. :cvar DELETED: Volume has been deleted. No further operations possible.
  1192. :cvar ERROR: Volume is in an error state. No further operations possible.
  1193. """
  1194. UNKNOWN = "unknown"
  1195. CREATING = "creating"
  1196. CONFIGURING = "configuring"
  1197. AVAILABLE = "available"
  1198. IN_USE = "in-use"
  1199. DELETED = "deleted"
  1200. ERROR = "error"
  1201. class Volume(ObjectLifeCycleMixin, LabeledCloudResource):
  1202. """
  1203. Represents a block storage device (aka volume).
  1204. """
  1205. __metaclass__ = ABCMeta
  1206. @LabeledCloudResource.label.setter # type: ignore[attr-defined]
  1207. @abstractmethod
  1208. def label(self, value: str) -> None:
  1209. """
  1210. Set the volume label.
  1211. """
  1212. pass
  1213. @abstractproperty
  1214. def description(self) -> str:
  1215. """
  1216. Get the volume description.
  1217. Some cloud providers may not support this property, and will return the
  1218. volume label instead.
  1219. :rtype: ``str``
  1220. :return: Description for this volume as returned by the cloud
  1221. middleware.
  1222. """
  1223. pass
  1224. @description.setter
  1225. @abstractmethod
  1226. def description(self, value: str) -> None:
  1227. """
  1228. Set the volume description.
  1229. Some cloud providers may not support this property, and setting the
  1230. description may have no effect (providers that do not support this
  1231. property will always return the volume label as the description).
  1232. """
  1233. pass
  1234. @abstractproperty
  1235. def size(self) -> int:
  1236. """
  1237. Get the volume size (in GB).
  1238. :rtype: ``int``
  1239. :return: Size for this volume as returned by the cloud middleware.
  1240. """
  1241. pass
  1242. @abstractproperty
  1243. def create_time(self) -> str | datetime:
  1244. """
  1245. Get the creation data and time for this volume.
  1246. :rtype: ``DateTime``
  1247. :return: Creation time for this volume as returned by the cloud
  1248. middleware.
  1249. """
  1250. pass
  1251. @abstractproperty
  1252. def zone_id(self) -> str:
  1253. """
  1254. Get the placement zone id that this volume belongs to.
  1255. :rtype: ``str``
  1256. :return: PlacementZone for this volume as returned by the cloud
  1257. middleware.
  1258. """
  1259. pass
  1260. @abstractproperty
  1261. def source(self) -> Snapshot | MachineImage | None:
  1262. """
  1263. If available, get the source that this volume is based on.
  1264. This can be a ``Snapshot``, an ``Image``, or ``None`` if no source.
  1265. :rtype: ``Snapshot``, ``Image``, or ``None``
  1266. :return: Snapshot or Image source for this volume as returned by the
  1267. cloud middleware.
  1268. """
  1269. pass
  1270. @abstractproperty
  1271. def attachments(self) -> AttachmentInfo | None:
  1272. """
  1273. Get attachment information for this volume.
  1274. :rtype: ``AttachmentInfo``
  1275. :return: Returns an AttachmentInfo object.
  1276. """
  1277. pass
  1278. @abstractmethod
  1279. def attach(self, instance: str | Instance, device: str) -> None:
  1280. """
  1281. Attach this volume to an instance.
  1282. :type instance: ``str`` or :class:`.Instance` object
  1283. :param instance: The ID of an instance or an ``Instance`` object to
  1284. which this volume will be attached.
  1285. :type device: ``str``
  1286. :param device: The device on the instance through which the
  1287. volume will be exposed (e.g. /dev/sdh).
  1288. :rtype: ``bool``
  1289. :return: ``True`` if successful.
  1290. """
  1291. pass
  1292. @abstractmethod
  1293. def detach(self, force: bool = False) -> None:
  1294. """
  1295. Detach this volume from an instance.
  1296. :type force: ``bool``
  1297. :param force: Forces detachment if the previous detachment attempt
  1298. did not occur cleanly. This option is supported on select
  1299. clouds only. This option can lead to data loss or a
  1300. corrupted file system. Use this option only as a last
  1301. resort to detach a volume from a failed instance. The
  1302. instance will not have an opportunity to flush file
  1303. system caches nor file system meta data. If you
  1304. use this option, you must perform file system check and
  1305. repair procedures.
  1306. :rtype: ``bool``
  1307. :return: ``True`` if successful.
  1308. """
  1309. pass
  1310. @abstractmethod
  1311. def create_snapshot(self, label: str,
  1312. description: str | None = None) -> Snapshot:
  1313. """
  1314. Create a snapshot of this Volume.
  1315. :type label: ``str``
  1316. :param label: The label for this snapshot.
  1317. :type description: ``str``
  1318. :param description: A description of the snapshot.
  1319. Limited to 256 characters.
  1320. :rtype: :class:`.Snapshot`
  1321. :return: The created Snapshot object.
  1322. """
  1323. pass
  1324. @abstractmethod
  1325. def delete(self) -> None:
  1326. """
  1327. Delete this volume.
  1328. :rtype: ``bool``
  1329. :return: ``True`` if successful.
  1330. """
  1331. pass
  1332. class SnapshotState(object):
  1333. """
  1334. Standard states for a snapshot
  1335. :cvar UNKNOWN: Snapshot state unknown.
  1336. :cvar PENDING: Snapshot is pending.
  1337. :cvar CONFIGURING: Snapshot is being configured in some way.
  1338. :cvar AVAILABLE: Snapshot has been completed and is ready for use.
  1339. :cvar ERROR: Snapshot is in an error state. No further operations possible.
  1340. """
  1341. UNKNOWN = "unknown"
  1342. PENDING = "pending"
  1343. CONFIGURING = "configuring"
  1344. AVAILABLE = "available"
  1345. ERROR = "error"
  1346. class Snapshot(ObjectLifeCycleMixin, LabeledCloudResource):
  1347. """
  1348. Represents a snapshot of a block storage device.
  1349. """
  1350. __metaclass__ = ABCMeta
  1351. @LabeledCloudResource.label.setter # type: ignore[attr-defined]
  1352. @abstractmethod
  1353. def label(self, value: str) -> None:
  1354. """
  1355. Set the snapshot label.
  1356. """
  1357. pass
  1358. @abstractproperty
  1359. def description(self) -> str:
  1360. """
  1361. Get the snapshot description.
  1362. Some cloud providers may not support this property, and will return the
  1363. snapshot label instead.
  1364. :rtype: ``str``
  1365. :return: Description for this snapshot as returned by the cloud
  1366. middleware.
  1367. """
  1368. pass
  1369. @description.setter
  1370. @abstractmethod
  1371. def description(self, value: str) -> None:
  1372. """
  1373. Set the snapshot description.
  1374. Some cloud providers may not support this property, and setting the
  1375. description may have no effect (providers that do not support this
  1376. property will always return the snapshot label as the description).
  1377. :type value: ``str``
  1378. :param value: The value for the snapshot description.
  1379. """
  1380. pass
  1381. @abstractproperty
  1382. def size(self) -> int:
  1383. """
  1384. Get the snapshot size (in GB).
  1385. :rtype: ``int``
  1386. :return: Size for this snapshot as returned by the cloud middleware.
  1387. """
  1388. pass
  1389. @abstractproperty
  1390. def volume_id(self) -> str | None:
  1391. """
  1392. Get the id of the volume that this snapshot is based on.
  1393. This method may return ``None`` if the source volume no longer exists.
  1394. :rtype: ``int``
  1395. :return: Id of the volume that this snapshot is based on
  1396. """
  1397. pass
  1398. @abstractproperty
  1399. def create_time(self) -> str | datetime:
  1400. """
  1401. Get the creation data and time for this snapshot.
  1402. :rtype: ``DateTime``
  1403. :return: Creation time for this snapshot as returned by the cloud
  1404. middleware.
  1405. """
  1406. pass
  1407. @abstractmethod
  1408. def create_volume(self, size: int | None = None,
  1409. volume_type: str | None = None,
  1410. iops: int | None = None) -> Volume:
  1411. """
  1412. Create a new Volume from this Snapshot.
  1413. :type size: ``int``
  1414. :param size: The size of the new volume, in GiB (optional). Defaults to
  1415. the size of the snapshot.
  1416. :type volume_type: ``str``
  1417. :param volume_type: The type of the volume (optional). Availability and
  1418. valid values depend on the provider.
  1419. :type iops: ``int``
  1420. :param iops: The provisioned IOPs you want to associate with
  1421. this volume (optional). Availability depends on the
  1422. provider.
  1423. :rtype: :class:`.Volume`
  1424. :return: An instance of the created Volume.
  1425. """
  1426. pass
  1427. # @abstractmethod
  1428. # def share(self, user_ids=None):
  1429. # """
  1430. # Share this Snapshot.
  1431. #
  1432. # :type user_ids: list of strings
  1433. # :param user_ids: A list of cloud provider compatible user IDs. If no
  1434. # IDs are specified, the snapshot is made public.
  1435. #
  1436. # :rtype: bool
  1437. # :return: ``True`` if successful.
  1438. # """
  1439. # pass
  1440. #
  1441. # @abstractmethod
  1442. # def unshare(self, user_ids=None):
  1443. # """
  1444. # Unshare this Snapshot.
  1445. #
  1446. # :type user_ids: list of strings
  1447. # :param user_ids: A list of cloud provider compatible user IDs. If no
  1448. # IDs are specified, the snapshot is made private.
  1449. #
  1450. # :rtype: bool
  1451. # :return: ``True`` if successful.
  1452. # """
  1453. # pass
  1454. @abstractmethod
  1455. def delete(self) -> None:
  1456. """
  1457. Delete this snapshot.
  1458. :rtype: ``bool``
  1459. :return: ``True`` if successful.
  1460. """
  1461. pass
  1462. class KeyPair(CloudResource):
  1463. """
  1464. Represents an ssh key pair.
  1465. """
  1466. __metaclass__ = ABCMeta
  1467. @abstractproperty
  1468. def material(self) -> str | None:
  1469. """
  1470. Unencrypted private key.
  1471. :rtype: ``str``
  1472. :return: Unencrypted private key or ``None`` if not available.
  1473. """
  1474. pass
  1475. @abstractmethod
  1476. def delete(self) -> None:
  1477. """
  1478. Delete this key pair.
  1479. :rtype: ``bool``
  1480. :return: ``True`` if successful.
  1481. """
  1482. pass
  1483. class Region(CloudResource):
  1484. """
  1485. Represents a cloud region.
  1486. A cloud region is typically a separate geographic area and will contain at
  1487. least one placement zone.
  1488. """
  1489. __metaclass__ = ABCMeta
  1490. @abstractproperty
  1491. def zones(self) -> Iterable[PlacementZone]:
  1492. """
  1493. Access information about placement zones within this region.
  1494. :rtype: Iterable
  1495. :return: Iterable of available placement zones in this region.
  1496. """
  1497. pass
  1498. @abstractproperty
  1499. def default_zone(self) -> PlacementZone:
  1500. """
  1501. Access the default placement zone for this region.
  1502. :rtype: :class:`.PlacementZone`
  1503. :return: The default placement zone for this region.
  1504. """
  1505. pass
  1506. class PlacementZone(CloudResource):
  1507. """
  1508. Represents a placement zone.
  1509. A placement zone is contained within a Region.
  1510. """
  1511. __metaclass__ = ABCMeta
  1512. @abstractproperty
  1513. def region_name(self) -> str:
  1514. """
  1515. A region this placement zone is associated with.
  1516. :rtype: ``str``
  1517. :return: The id of the region the zone is associated with.
  1518. """
  1519. pass
  1520. class VMType(CloudResource):
  1521. """
  1522. A VM type object.
  1523. """
  1524. __metaclass__ = ABCMeta
  1525. @abstractproperty
  1526. def family(self) -> str | None:
  1527. """
  1528. The family/group that this VM type belongs to.
  1529. For example, General Purpose Instances or High-Memory Instances. If
  1530. the provider does not support such a grouping, it may return ``None``.
  1531. :rtype: ``str``
  1532. :return: Name of the instance family or ``None``.
  1533. """
  1534. pass
  1535. @abstractproperty
  1536. def vcpus(self) -> int:
  1537. """
  1538. The number of VCPUs supported by this VM type.
  1539. :rtype: ``int``
  1540. :return: Number of VCPUs.
  1541. """
  1542. pass
  1543. @abstractproperty
  1544. def ram(self) -> float:
  1545. """
  1546. The amount of RAM (in GB) supported by this VM type.
  1547. :rtype: ``float``
  1548. :return: Total RAM (in GB).
  1549. """
  1550. pass
  1551. @abstractproperty
  1552. def size_root_disk(self) -> int:
  1553. """
  1554. The size of this VM types's root disk (in GB).
  1555. :rtype: ``int``
  1556. :return: Size of root disk (in GB).
  1557. """
  1558. pass
  1559. @abstractproperty
  1560. def size_ephemeral_disks(self) -> int:
  1561. """
  1562. The size of this VM types's total ephemeral storage (in GB).
  1563. :rtype: ``int``
  1564. :return: Size of ephemeral disks (in GB).
  1565. """
  1566. pass
  1567. @abstractproperty
  1568. def num_ephemeral_disks(self) -> int:
  1569. """
  1570. The total number of ephemeral disks on this VM type.
  1571. :rtype: ``int``
  1572. :return: Number of ephemeral disks available.
  1573. """
  1574. pass
  1575. @abstractproperty
  1576. def size_total_disk(self) -> int:
  1577. """
  1578. The total disk space available on this VM type
  1579. (root_disk + ephemeral).
  1580. :rtype: ``int``
  1581. :return: Size of total disk space (in GB).
  1582. """
  1583. pass
  1584. @abstractproperty
  1585. def extra_data(self) -> dict[str, Any]:
  1586. """
  1587. A dictionary of extra data about this instance. May contain
  1588. nested dictionaries, but all key value pairs are strings or integers.
  1589. :rtype: ``dict``
  1590. :return: Extra attributes for this VM type.
  1591. """
  1592. pass
  1593. class VMFirewall(LabeledCloudResource):
  1594. """
  1595. Represents a firewall resource applied to virtual machines.
  1596. This is in contrast to a firewall for a network, for example.
  1597. """
  1598. __metaclass__ = ABCMeta
  1599. @LabeledCloudResource.label.setter # type: ignore[attr-defined]
  1600. @abstractmethod
  1601. def label(self, value: str) -> None:
  1602. """
  1603. Set the resource label.
  1604. """
  1605. pass
  1606. @abstractproperty
  1607. def description(self) -> str | None:
  1608. """
  1609. Return the description of this VM firewall.
  1610. :rtype: ``str``
  1611. :return: A description of this VM firewall, or ``None``.
  1612. """
  1613. pass
  1614. @abstractproperty
  1615. def network_id(self) -> str | None:
  1616. """
  1617. Network ID with which this VM firewall is associated.
  1618. :rtype: ``str``
  1619. :return: Provider-supplied network ID or ``None`` is not available.
  1620. """
  1621. pass
  1622. @abstractproperty
  1623. def rules(self) -> VMFirewallRuleSubService:
  1624. """
  1625. Get access to the rules belonging to this VM firewall.
  1626. This object can be used for further operations on rules, such as get,
  1627. list, create, etc.
  1628. :rtype: An object of :class:`.VMFirewallRuleSubService`
  1629. :return: A VMFirewallRuleSubService for further operations
  1630. """
  1631. pass
  1632. class TrafficDirection(Enum):
  1633. """
  1634. Direction of data flow in a firewall.
  1635. """
  1636. INBOUND = 'inbound'
  1637. OUTBOUND = 'outbound'
  1638. class VMFirewallRule(CloudResource):
  1639. """
  1640. Represents a VM firewall rule.
  1641. """
  1642. __metaclass__ = ABCMeta
  1643. @abstractproperty
  1644. def direction(self) -> TrafficDirection:
  1645. """
  1646. Direction of traffic to which this rule applies.
  1647. Either ``TrafficDirection.INBOUND`` or ``TrafficDirection.OUTBOUND``.
  1648. :rtype: :class:`.TrafficDirection`
  1649. :return: Direction of traffic to which this rule applies.
  1650. """
  1651. pass
  1652. @abstractproperty
  1653. def protocol(self) -> str | None:
  1654. """
  1655. IP protocol used. Either ``tcp`` | ``udp`` | ``icmp``.
  1656. :rtype: ``str``
  1657. :return: Active protocol.
  1658. """
  1659. pass
  1660. @abstractproperty
  1661. def from_port(self) -> int:
  1662. """
  1663. Lowest port number opened as part of this rule.
  1664. :rtype: ``int``
  1665. :return: Lowest port number or 0 if not set.
  1666. """
  1667. pass
  1668. @abstractproperty
  1669. def to_port(self) -> int:
  1670. """
  1671. Highest port number opened as part of this rule.
  1672. :rtype: ``int``
  1673. :return: Highest port number or 0 if not set.
  1674. """
  1675. pass
  1676. @abstractproperty
  1677. def cidr(self) -> str | None:
  1678. """
  1679. CIDR block this VM firewall is providing access to.
  1680. :rtype: ``str``
  1681. :return: CIDR block.
  1682. """
  1683. pass
  1684. @abstractproperty
  1685. def src_dest_fw_id(self) -> str | None:
  1686. """
  1687. VM firewall id given access permissions by this rule.
  1688. :rtype: ``str``
  1689. :return: The VM firewall granted access.
  1690. """
  1691. pass
  1692. @abstractproperty
  1693. def src_dest_fw(self) -> VMFirewall | None:
  1694. """
  1695. VM firewall given access permissions by this rule.
  1696. :rtype: :class:``.VMFirewall``
  1697. :return: The VM firewall granted access.
  1698. """
  1699. pass
  1700. @abstractmethod
  1701. def delete(self) -> None:
  1702. """
  1703. Delete this rule.
  1704. """
  1705. pass
  1706. class TransferConfig(object):
  1707. """
  1708. Provider-agnostic, per-call tuning for an object transfer in either
  1709. direction.
  1710. Passed optionally to :meth:`.BucketObject.upload`,
  1711. :meth:`.BucketObject.upload_from_file` and
  1712. :meth:`.BucketObject.download_to_file`. Any field left as ``None`` falls
  1713. back to the provider/global configuration (the ``CB_MULTIPART_*``
  1714. settings). Each provider maps these fields onto its native transfer
  1715. mechanism. To tune uploads and downloads differently, pass a different
  1716. instance to each call.
  1717. """
  1718. def __init__(self, threshold: int | None = None,
  1719. part_size: int | None = None,
  1720. max_concurrency: int | None = None) -> None:
  1721. """
  1722. :type threshold: ``int``
  1723. :param threshold: Size in bytes above which the transfer is split
  1724. into multiple parts.
  1725. :type part_size: ``int``
  1726. :param part_size: Size in bytes of each part. For uploads this must
  1727. be at least the provider minimum (5 MiB on S3) for all but the
  1728. final part; downloads have no minimum.
  1729. :type max_concurrency: ``int``
  1730. :param max_concurrency: Maximum number of parts to transfer in
  1731. parallel.
  1732. """
  1733. self.threshold = threshold
  1734. self.part_size = part_size
  1735. self.max_concurrency = max_concurrency
  1736. def __repr__(self) -> str:
  1737. return ("<CB-TransferConfig: threshold={0}, part_size={1}, "
  1738. "max_concurrency={2}>".format(
  1739. self.threshold, self.part_size, self.max_concurrency))
  1740. class UploadPart(object):
  1741. """
  1742. A handle for a single part uploaded as part of a multipart upload.
  1743. Returned by :meth:`.MultipartUpload.upload_part`. Callers must retain the
  1744. parts they receive and pass them to :meth:`.MultipartUpload.complete`.
  1745. The handle is a simple, serializable value object so that parts may be
  1746. collected across threads or processes when uploading in parallel.
  1747. """
  1748. __metaclass__ = ABCMeta
  1749. @abstractproperty
  1750. def part_number(self) -> int:
  1751. """
  1752. The 1-based index of this part within the upload.
  1753. :rtype: ``int``
  1754. :return: The part number supplied to ``upload_part``.
  1755. """
  1756. pass
  1757. @abstractproperty
  1758. def etag(self) -> object:
  1759. """
  1760. Opaque provider handle identifying the stored part.
  1761. Its concrete form varies by provider (e.g. an S3 ETag, an Azure block
  1762. id, a GCS temp-object name, or a Swift segment descriptor) and should
  1763. not be interpreted by clients.
  1764. :rtype: ``object``
  1765. :return: The provider-specific part handle.
  1766. """
  1767. pass
  1768. class MultipartUpload(CloudResource):
  1769. """
  1770. Represents an in-progress, multi-part upload to a :class:`.BucketObject`.
  1771. Created via :meth:`.BucketObject.create_multipart_upload`. Parts are
  1772. uploaded with :meth:`upload_part` (in any order, optionally in parallel)
  1773. and the upload is finalized with :meth:`complete` or cancelled with
  1774. :meth:`abort`.
  1775. """
  1776. __metaclass__ = ABCMeta
  1777. @abstractproperty
  1778. def bucket(self) -> Bucket:
  1779. """
  1780. The bucket this upload targets.
  1781. :rtype: :class:`.Bucket`
  1782. :return: The target Bucket.
  1783. """
  1784. pass
  1785. @abstractproperty
  1786. def object_name(self) -> str:
  1787. """
  1788. The key of the object being uploaded.
  1789. :rtype: ``str``
  1790. :return: The target object name.
  1791. """
  1792. pass
  1793. @abstractmethod
  1794. def upload_part(self, part_number: int,
  1795. data: bytes | IO[bytes]) -> UploadPart:
  1796. """
  1797. Upload a single part of this multipart upload.
  1798. :type part_number: ``int``
  1799. :param part_number: 1-based index that determines the part's position
  1800. in the final object. Part numbers must be unique within an upload.
  1801. :type data: ``bytes`` or file-like object
  1802. :param data: The part payload. Every part except the last must be at
  1803. least the provider minimum part size (5 MiB on S3).
  1804. :rtype: :class:`.UploadPart`
  1805. :return: A part handle that MUST be retained and passed to
  1806. :meth:`complete`.
  1807. """
  1808. pass
  1809. @abstractmethod
  1810. def complete(self, parts: list[UploadPart]) -> BucketObject:
  1811. """
  1812. Finalize the upload, assembling parts in ascending ``part_number``.
  1813. :type parts: ``list`` of :class:`.UploadPart`
  1814. :param parts: The handles returned by :meth:`upload_part`. They may be
  1815. supplied in any order.
  1816. :rtype: :class:`.BucketObject`
  1817. :return: The completed object.
  1818. """
  1819. pass
  1820. @abstractmethod
  1821. def abort(self) -> None:
  1822. """
  1823. Cancel the upload, releasing any staged parts or temporary objects.
  1824. ``abort`` is idempotent and safe to call after a partial upload. On
  1825. Azure it is best-effort: there is no server-side cancel, so uncommitted
  1826. blocks are left to expire (after ~7 days) rather than being deleted.
  1827. """
  1828. pass
  1829. class BucketObject(CloudResource):
  1830. """
  1831. Represents an object stored within a bucket.
  1832. """
  1833. __metaclass__ = ABCMeta
  1834. @abstractproperty
  1835. def name(self) -> str:
  1836. """
  1837. Retrieve the name of the current object.
  1838. The bucket object name adheres to a naming requirement that is more
  1839. relaxed than the naming requirement enforced across CloudBridge. More
  1840. details are available here: http://docs.aws.amazon.com/AmazonS3/latest/
  1841. dev/UsingMetadata.html#object-key-guidelines
  1842. :rtype: ``str``
  1843. :return: Name for this object as returned by the cloud middleware.
  1844. """
  1845. pass
  1846. @abstractproperty
  1847. def size(self) -> int:
  1848. """
  1849. Get this object's size.
  1850. :rtype: ``int``
  1851. :return: Size of this object in bytes.
  1852. """
  1853. pass
  1854. @abstractproperty
  1855. def last_modified(self) -> str:
  1856. """
  1857. Get the date and time this object was last modified.
  1858. :rtype: ``str``
  1859. :return: Date and time formatted string %Y-%m-%dT%H:%M:%S.%f
  1860. """
  1861. pass
  1862. @abstractmethod
  1863. def iter_content(self, chunk_size: int | None = None) -> Iterable[bytes]:
  1864. """
  1865. Returns this object's content as an iterable of byte chunks.
  1866. The object is streamed rather than held in memory, so this is safe
  1867. for objects of any size. Chunks are sized by ``chunk_size``, never by
  1868. the content itself - binary data is never split on newlines - and
  1869. only the final chunk may be shorter.
  1870. ``chunk_size`` trades per-chunk overhead against memory and latency.
  1871. Each chunk costs a read from the provider plus whatever the caller
  1872. does per chunk, so small values are expensive over a large object;
  1873. conversely a chunk is buffered in full before it is yielded, so large
  1874. values cost memory per concurrent stream and delay the first chunk.
  1875. The default suits most callers.
  1876. :type chunk_size: ``int``
  1877. :param chunk_size: Maximum size in bytes of each chunk yielded. If
  1878. ``None``, falls back to the provider/global configuration
  1879. (``iter_chunk_size`` / the ``CB_ITER_CHUNK_SIZE`` setting,
  1880. 1 MiB by default). Must be positive.
  1881. :rtype: Iterable
  1882. :return: An iterable of the file contents
  1883. :raise: ``InvalidValueException`` if ``chunk_size`` is not positive.
  1884. """
  1885. pass
  1886. @abstractmethod
  1887. def save_content(self, target_stream: IO[bytes],
  1888. chunk_size: int | None = None) -> None:
  1889. """
  1890. Save this object and write its contents to the ``target_stream``.
  1891. The object is streamed through ``iter_content``, so ``chunk_size``
  1892. means what it does there.
  1893. :type target_stream: ``IO[bytes]``
  1894. :param target_stream: A writable binary stream to write to.
  1895. :type chunk_size: ``int``
  1896. :param chunk_size: Maximum size in bytes of each chunk read from the
  1897. provider. See :meth:`.iter_content`.
  1898. :raise: ``InvalidValueException`` if ``chunk_size`` is not positive.
  1899. """
  1900. pass
  1901. @abstractmethod
  1902. def download_to_file(self, path: str,
  1903. config: TransferConfig | None = None) -> None:
  1904. """
  1905. Download this object's content to a local file.
  1906. Objects larger than the configured transfer threshold are fetched as
  1907. ranged reads of ``part_size`` bytes, up to ``max_concurrency`` parts
  1908. in parallel, so large downloads are not bound to a single connection
  1909. (and the whole object is never held in memory). Smaller objects are
  1910. streamed in a single request. ``iter_content``/``save_content``
  1911. remain single-stream alternatives for arbitrary target streams.
  1912. :type path: ``str``
  1913. :param path: Local path to write the object's content to. The object
  1914. is assembled out of the way and moved into place once complete,
  1915. so ``path`` never holds a partial object: an existing file is
  1916. replaced atomically, and a failed transfer leaves it untouched.
  1917. Concurrent downloads to one path are therefore safe, with the
  1918. last to complete winning.
  1919. :type config: :class:`.TransferConfig`
  1920. :param config: Optional per-call transfer tuning (threshold, part
  1921. size, concurrency). Any field left unset falls back to the
  1922. provider/global configuration.
  1923. """
  1924. pass
  1925. @abstractmethod
  1926. def upload(self, source_stream: IO[bytes],
  1927. config: TransferConfig | None = None) -> BucketObject | None:
  1928. """
  1929. Set the contents of the object to the data read from the source stream.
  1930. :type config: :class:`.TransferConfig`
  1931. :param config: Optional per-call upload tuning (multipart threshold,
  1932. part size, concurrency). Any field left unset falls back to the
  1933. provider/global configuration.
  1934. :rtype: ``bool``
  1935. :return: ``True`` if successful.
  1936. """
  1937. pass
  1938. @abstractmethod
  1939. def upload_from_file(self, path: str,
  1940. config: TransferConfig | None = None) -> BucketObject | None:
  1941. """
  1942. Store the contents of the file pointed by the "path" variable.
  1943. Files larger than the configured multipart threshold are streamed to
  1944. the provider in parts, so the whole file is never held in memory.
  1945. :type path: ``str``
  1946. :param path: Absolute path to the file to be uploaded to S3.
  1947. :type config: :class:`.TransferConfig`
  1948. :param config: Optional per-call upload tuning (multipart threshold,
  1949. part size, concurrency). Any field left unset falls back to the
  1950. provider/global configuration.
  1951. """
  1952. pass
  1953. @abstractmethod
  1954. def create_multipart_upload(self) -> MultipartUpload:
  1955. """
  1956. Begin an explicit, multi-part upload to this object.
  1957. Returns a :class:`.MultipartUpload` handle whose lifecycle is::
  1958. upload = obj.create_multipart_upload()
  1959. parts = [upload.upload_part(n, chunk) for n, chunk in ...]
  1960. upload.complete(parts) # or upload.abort()
  1961. Parts may be uploaded in any order and in parallel; every part except
  1962. the last must be at least the provider minimum part size (5 MiB on
  1963. S3). :meth:`.MultipartUpload.complete` assembles them in ascending
  1964. ``part_number`` order.
  1965. :rtype: :class:`.MultipartUpload`
  1966. :return: An in-progress multipart upload handle for this object.
  1967. """
  1968. pass
  1969. @abstractmethod
  1970. def delete(self) -> None:
  1971. """
  1972. Delete this object.
  1973. :rtype: ``bool``
  1974. :return: ``True`` if successful.
  1975. """
  1976. pass
  1977. @abstractmethod
  1978. def generate_url(self, expires_in: int, writable: bool = False,
  1979. content_disposition: str | None = None,
  1980. content_type: str | None = None) -> str:
  1981. """
  1982. Generate a signed URL to this object.
  1983. A signed URL associated with an object gives time-limited read access
  1984. to that specific object. Anyone in possession of the URL has the access
  1985. granted by the URL.
  1986. :type expires_in: ``int``
  1987. :param expires_in: Time to live of the generated URL in seconds.
  1988. :type writable: ``bool``
  1989. :param writable: Write permission for this signed URL. Users with the URL
  1990. will be able to upload to this object, but they will NOT be able to
  1991. read from it.
  1992. :type content_disposition: ``str``
  1993. :param content_disposition: When set, ask the backing store to serve
  1994. the object with this ``Content-Disposition`` response header on
  1995. GET (e.g. ``attachment; filename="data.txt"``). This is a
  1996. response-serving hint: every provider accepts it and honors it
  1997. where the backing store supports response-header overrides (AWS,
  1998. Azure and GCP fully; OpenStack Swift honors the filename portion
  1999. via its tempurl ``filename`` parameter). Ignored when
  2000. ``writable`` is ``True``.
  2001. :type content_type: ``str``
  2002. :param content_type: When set, ask the backing store to serve the
  2003. object with this ``Content-Type`` response header on GET. Honored
  2004. by AWS, Azure and GCP; OpenStack Swift cannot override the
  2005. content type. Ignored when ``writable`` is ``True``.
  2006. :rtype: ``str``
  2007. :return: A URL to access the object.
  2008. """
  2009. pass
  2010. @abstractmethod
  2011. def refresh(self) -> None:
  2012. """
  2013. Refresh this object's state and synchronize it with the underlying
  2014. service provider.
  2015. """
  2016. pass
  2017. class Bucket(CloudResource):
  2018. """
  2019. Represents a namespace for objects (eg, object store bucket or container).
  2020. """
  2021. __metaclass__ = ABCMeta
  2022. @abstractproperty
  2023. def name(self) -> str:
  2024. """
  2025. Retrieve the name of the current bucket.
  2026. :rtype: ``str``
  2027. :return: Name for this instance as returned by the cloud middleware.
  2028. """
  2029. pass
  2030. @abstractproperty
  2031. def objects(self) -> BucketObjectSubService:
  2032. """
  2033. Get a container for the objects belonging to this Bucket.
  2034. This object can be used to iterate through bucket objects, as well as
  2035. perform further operations on buckets, such as ``get``, ``list``,
  2036. ``create``, etc.
  2037. .. code-block:: python
  2038. # Show all objects in bucket
  2039. print(list(bucket.objects))
  2040. # Find an object by name
  2041. print(bucket.objects.find(name='my_obj.txt'))
  2042. # Get first page of bucket list
  2043. print(bucket.objects.list())
  2044. # Create a new object within this bucket
  2045. obj = bucket.objects.create('my_obj.txt')
  2046. :rtype: :class:`.BucketContainer`
  2047. :return: A BucketContainer for further operations.
  2048. """
  2049. pass
  2050. @abstractmethod
  2051. def delete(self, delete_contents: bool = False) -> None:
  2052. """
  2053. Delete this bucket.
  2054. :type delete_contents: ``bool``
  2055. :param delete_contents: If ``True``, all objects within the bucket
  2056. will be deleted.
  2057. :rtype: ``bool``
  2058. :return: ``True`` if successful.
  2059. """
  2060. pass