getting_started.rst 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. Getting Started
  2. ===============
  3. This getting started guide will provide a quick tour of some CloudBridge
  4. features. For more details on individual features, see the
  5. `Using CloudBridge <topics/overview.html>`_ section or the
  6. `API reference <api_docs/ref.html>`_.
  7. Installation
  8. ------------
  9. CloudBridge is available on PyPI so to install the latest available version,
  10. run::
  11. pip install --upgrade cloudbridge
  12. For common issues during setup, check the following section:
  13. `Common Setup Issues <topics/troubleshooting.html>`
  14. Create a provider
  15. -----------------
  16. To start, you will need to create a reference to a provider object. The
  17. provider object identifies the cloud you want to work with and supplies your
  18. credentials. Each provider instance is tied to a particular zone.
  19. Refer to the `Setup page <topics/setup.html>`_ for more details information on
  20. provider configuration. Once a provider instance is created, the remainder of
  21. the code is the same for any provider.
  22. AWS:
  23. .. code-block:: python
  24. from cloudbridge.factory import CloudProviderFactory, ProviderList
  25. config = {'aws_access_key': 'AKIAJW2XCYO4AF55XFEQ',
  26. 'aws_secret_key': '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',
  27. 'aws_zone_name': 'us-east-1a'}
  28. provider = CloudProviderFactory().create_provider(ProviderList.AWS, config)
  29. image_id = 'ami-0885b1f6bd170450c' # Ubuntu 20.04 (HVM)
  30. OpenStack (with Keystone authentication v2):
  31. .. code-block:: python
  32. from cloudbridge.factory import CloudProviderFactory, ProviderList
  33. config = {'os_username': 'username',
  34. 'os_password': 'password',
  35. 'os_auth_url': 'authentication URL',
  36. 'os_region_name': 'region name',
  37. 'os_project_name': 'project name',
  38. 'os_zone_name': 'zone_name'}
  39. provider = CloudProviderFactory().create_provider(ProviderList.OPENSTACK,
  40. config)
  41. image_id = 'c1f4b7bc-a563-4feb-b439-a2e071d861aa' # Ubuntu 14.04 @ NeCTAR
  42. OpenStack (with Keystone authentication v3):
  43. .. code-block:: python
  44. from cloudbridge.factory import CloudProviderFactory, ProviderList
  45. config = {'os_username': 'username',
  46. 'os_password': 'password',
  47. 'os_auth_url': 'authentication URL',
  48. 'os_project_name': 'project name',
  49. 'os_project_domain_name': 'project domain name',
  50. 'os_user_domain_name': 'domain name',
  51. 'os_zone_name': 'zone_name'}
  52. provider = CloudProviderFactory().create_provider(ProviderList.OPENSTACK,
  53. config)
  54. image_id = '46794408-6a80-44b1-bf5a-405127753f43' # Ubuntu 20.04@Jetstream
  55. Azure:
  56. .. code-block:: python
  57. from cloudbridge.factory import CloudProviderFactory, ProviderList
  58. config = {'azure_subscription_id': 'REPLACE WITH ACTUAL VALUE',
  59. 'azure_client_id': 'REPLACE WITH ACTUAL VALUE',
  60. 'azure_secret': 'REPLACE WITH ACTUAL VALUE',
  61. 'azure_tenant': ' REPLACE WITH ACTUAL VALUE',
  62. 'azure_resource_group': 'REPLACE WITH ACTUAL VALUE',
  63. 'azure_zone_name': 'zone_name'}
  64. provider = CloudProviderFactory().create_provider(ProviderList.AZURE, config)
  65. image_id = 'Canonical:UbuntuServer:16.04.0-LTS:latest' # Ubuntu 16.04
  66. Google Compute Cloud:
  67. .. code-block:: python
  68. from cloudbridge.factory import CloudProviderFactory, ProviderList
  69. config = {'gcp_project_name': 'project name',
  70. 'gcp_service_creds_file': 'service_file.json',
  71. 'gcp_region_name': 'us-east1', # Use desired value
  72. 'gcp_zone_name': 'us-east1-b'} # Use desired value
  73. provider = CloudProviderFactory().create_provider(ProviderList.GCP, config)
  74. image_id = 'https://www.googleapis.com/compute/v1/projects/ubuntu-os-cloud/global/images/ubuntu-1804-bionic-v20181222'
  75. List some resources
  76. -------------------
  77. Once you have a reference to a provider, explore the cloud platform:
  78. .. code-block:: python
  79. provider.security.vm_firewalls.list()
  80. provider.compute.vm_types.list()
  81. provider.storage.snapshots.list()
  82. provider.storage.buckets.list()
  83. This will demonstrate the fact that the library was properly installed and your
  84. provider object is setup correctly. By itself, those commands are not very
  85. interesting so let's create a new instance we can ssh into using a key pair.
  86. Create a key pair
  87. -----------------
  88. We'll create a new key pair and save the private portion of the key to a file
  89. on disk as a read-only file.
  90. .. code-block:: python
  91. import os
  92. kp = provider.security.key_pairs.create('cb-keypair')
  93. with open('cloudbridge_intro.pem', 'wb') as f:
  94. f.write(kp.material)
  95. os.chmod('cloudbridge_intro.pem', 0o400)
  96. Create a network
  97. ----------------
  98. A cloudbridge instance should be launched into a private subnet. We'll create
  99. a private network and subnet, and make sure it has internet connectivity, by
  100. attaching an internet gateway to the subnet via a router.
  101. .. code-block:: python
  102. net = provider.networking.networks.create(cidr_block='10.0.0.0/16',
  103. label='cb-network')
  104. sn = net.subnets.create(
  105. cidr_block='10.0.0.0/28', label='cb-subnet')
  106. router = provider.networking.routers.create(network=net, label='cb-router')
  107. router.attach_subnet(sn)
  108. gateway = net.gateways.get_or_create()
  109. router.attach_gateway(gateway)
  110. Create a VM firewall
  111. --------------------
  112. Next, we need to create a VM firewall (also commonly known as a security group)
  113. and add a rule to allow ssh access. A VM firewall needs to be associated with
  114. a private network.
  115. .. code-block:: python
  116. from cloudbridge.interfaces.resources import TrafficDirection
  117. fw = provider.security.vm_firewalls.create(
  118. label='cb-firewall', description='A VM firewall used by
  119. CloudBridge', network=net)
  120. fw.rules.create(TrafficDirection.INBOUND, 'tcp', 22, 22, '0.0.0.0/0')
  121. Launch an instance
  122. ------------------
  123. We can now launch an instance using the created key pair and security group.
  124. We will launch an instance type that has at least 2 CPUs and 4GB RAM. We will
  125. also add the network interface as a launch argument.
  126. .. code-block:: python
  127. img = provider.compute.images.get(image_id)
  128. vm_type = sorted([t for t in provider.compute.vm_types
  129. if t.vcpus >= 2 and t.ram >= 4],
  130. key=lambda x: x.vcpus*x.ram)[0]
  131. inst = provider.compute.instances.create(
  132. image=img, vm_type=vm_type, label='cb-instance',
  133. subnet=sn, key_pair=kp, vm_firewalls=[fw])
  134. # Wait until ready
  135. inst.wait_till_ready() # This is a blocking call
  136. # Show instance state
  137. inst.state
  138. # 'running'
  139. .. note ::
  140. Note that we iterated through provider.compute.vm_types directly
  141. instead of calling provider.compute.vm_types.list(). This is
  142. because we need to iterate through all records in this case. The list()
  143. method may not always return all records, depending on the global limit
  144. for records, necessitating that additional records be paged in. See
  145. :doc:`topics/paging_and_iteration`.
  146. Assign a public IP address
  147. --------------------------
  148. To access the instance, let's assign a public IP address to the instance. For
  149. this step, we'll first need to allocate a floating IP address for our account
  150. and then associate it with the instance. Note that floating IPs are associated
  151. with an Internet Gateway so we allocate the IP under the gateway we dealt with
  152. earlier.
  153. .. code-block:: python
  154. if not inst.public_ips:
  155. fip = gateway.floating_ips.create()
  156. inst.add_floating_ip(fip)
  157. inst.refresh()
  158. inst.public_ips
  159. # [u'54.166.125.219']
  160. From the command prompt, you can now ssh into the instance
  161. ``ssh -i cloudbridge_intro.pem ubuntu@54.166.125.219``.
  162. Get a resource
  163. --------------
  164. When a resource already exists, a reference to it can be retrieved using either
  165. its ID, name, or label. It is important to note that while IDs and names are
  166. unique, multiple resources of the same type could use the same label, thus the
  167. `find` method always returns a list, while the `get` method returns a single
  168. object. While the methods are similar across resources, they are explicitly
  169. listed in order to help map each resource with the service that handles it.
  170. Note that labeled resources allow to find by label, while unlabeled
  171. resources find by name or their special properties (eg: public_ip for
  172. floating IPs). For more detailed information on the types of resources and
  173. their provider mappings, see :doc:`topics/resource_types_and_mapping`.
  174. .. code-block:: python
  175. # Key Pair
  176. kp = provider.security.key_pairs.get('keypair ID')
  177. kp = provider.security.key_pairs.find(name='cb-keypair')[0]
  178. # Floating IPs
  179. fip = gateway.floating_ips.get('FloatingIP ID')
  180. # Find using public IP address
  181. fip_list = gateway.floating_ips.find(public_ip='IP address')
  182. # Find using name (the behavior of the `name` property can be
  183. # cloud-dependent). More details can be found `here <topics/resource_types_and_mapping.html>`
  184. fip_list = gateway.floating_ips.find(name='cb-fip')[0]
  185. # Network
  186. net = provider.networking.networks.get('network ID')
  187. net_list = provider.networking.networks.find(label='my-network')
  188. net = net_list[0]
  189. # Subnet
  190. sn = provider.networking.subnets.get('subnet ID')
  191. # Unknown network
  192. sn_list = provider.networking.subnets.find(label='cb-subnet')
  193. # Known network
  194. sn_list = provider.networking.subnets.find(network=net.id,
  195. label='cb-subnet')
  196. sn = sn_list(0)
  197. # Router
  198. router = provider.networking.routers.get('router ID')
  199. router_list = provider.networking.routers.find(label='cb-router')
  200. router = router_list[0]
  201. # Gateway
  202. gateway = net.gateways.get_or_create()
  203. # Firewall
  204. fw = provider.security.vm_firewalls.get('firewall ID')
  205. fw_list = provider.security.vm_firewalls.find(label='cb-firewall')
  206. fw = fw_list[0]
  207. # Instance
  208. inst = provider.compute.instances.get('instance ID')
  209. inst_list = provider.compute.instances.list(label='cb-instance')
  210. inst = inst_list[0]
  211. Cleanup
  212. -------
  213. To wrap things up, let's clean up all the resources we have created
  214. .. code-block:: python
  215. from cloudbridge.interfaces import InstanceState
  216. inst.delete()
  217. inst.wait_for([InstanceState.DELETED, InstanceState.UNKNOWN],
  218. terminal_states=[InstanceState.ERROR]) # Blocking call
  219. fip.delete()
  220. fw.delete()
  221. kp.delete()
  222. os.remove('cloudbridge_intro.pem')
  223. router.detach_gateway(gateway)
  224. router.detach_subnet(sn)
  225. gateway.delete()
  226. router.delete()
  227. sn.delete()
  228. net.delete()
  229. And that's it - a full circle in a few lines of code. You can now try
  230. the same with a different provider. All you will need to change is the
  231. cloud-specific data, namely the provider setup and the image ID.