Extra changes on Flavor Config
[snaps.git] / docs / how-to-use / LibraryUsage.rst
1 **********************
2 SNAPS-OO Library Usage
3 **********************
4
5 The pattern used within the SNAPS-OO library for creating OpenStack
6 instances have been made as consistent as possible amongst the different
7 instance types. Each consists of a constructor that takes in a
8 credentials object and generally takes in a single "settings"
9 (configuration) object. The only exception to this rule is with the
10 OpenStackVMInstance (creates an OpenStack Server) where it takes in the
11 additional settings used for the associated image and SSH key-pairs
12 credentials as those objects contain additional attributes required of
13 SNAPS, primarily when one needs to obtain remote access. After
14 instantiation, the create() method must be called to initiate all of the
15 necessary remote API calls to OpenStack required for proper instance
16 creation.
17
18 SNAPS Credentials
19 =================
20
21 As communicating with OpenStack is performed via secure remote RESTful
22 API calls, any function or method performing any type of query or CRUD
23 operation must know how to connect to the NFVI. The class ***OSCreds***
24 defined in *snaps.openstack.os\_credentials.py* contains everything
25 required to connect to any Keystone v2.0 or v3 authorization server. The
26 attributes are listed below:
27
28 -  username
29 -  password
30 -  auth\_url
31 -  project\_name (aka. tenant\_name)
32 -  identity\_api\_version (for obtaining Keystone authorization token.
33    default = 2, Versions 2.0 & v3 only validated.)
34 -  image\_api\_version (default = 2, Glance version 1 & 2 only validated)
35 -  network\_api\_version (Neutron version 2 currently only validated)
36 -  compute\_api\_version (Nova version 2 currently only validated)
37 -  heat\_api\_version (Heat version 1 currently only validated)
38 -  volume\_api\_version (default = 2, Heat versions 2 & 3 currently only validated)
39 -  user\_domain\_id (default='default')
40 -  user\_domain\_name (default='Default')
41 -  project\_domain\_id (default='default')
42 -  project\_domain\_name (default='Default')
43 -  interface (default='admin', used to specify the endpoint type for keystone: public, admin, internal)
44 -  cacert (default=False, expected values T|F to denote server certificate verification, else value contains the path to an HTTPS certificate)
45 -  region_name (The region name default=None)
46 -  proxy\_settings
47
48    -  host (the HTTP proxy host)
49    -  port (the HTTP proxy port)
50    -  https\_host (the HTTPS proxy host, default value of host)
51    -  https\_port (the HTTPS proxy port, default value of port)
52    -  ssh\_proxy\_cmd (same as the value placed into ssh -o
53       ProxyCommand='<this config value>')
54
55 Create OS Credentials Object
56 ----------------------------
57
58 .. code:: python
59
60     from snaps.openstack.os_credentials import OSCreds
61     os_creds=OSCreds(username='admin', password='admin',
62                      auth_url='http://localhost:5000/v3', project_name='admin',
63                      identity_api_version=3)
64
65 SNAPS Object Creators
66 =====================
67
68 Each creator minimally requires an OSCreds object for connecting to the
69 NFVI, associated \*Settings object for instance configuration, create()
70 method to make the necessary remote API calls and create all of the
71 necessary OpenStack instances required, and clean() method that is
72 responsible for deleting all associated OpenStack instances. Please see
73 the class diagram `here </display/SNAP/SNAPS-OO+Classes>`__. Below is a
74 textual representation of the requirements of each creator classes with
75 their associated setting classes and a sample code snippet on how to use
76 the code.
77
78 Create User
79 -----------
80 -  User - snaps.openstack.create\_user.OpenStackUser
81
82    -  snaps.openstack.user.UserConfig
83
84       -  name - the username (required)
85       -  password - the user's password (required)
86       -  project\_name - the name of the project to associated to this
87          user (optional)
88       -  domain\_name - the user's domain (default='default')
89       -  email - the user's email address (optional)
90       -  enabled - flag to determine whether or not the user should be
91          enabled (default=True)
92       -  roles - dict where key is the role's name and value is the name
93          the project to associate with the role (optional)
94
95 .. code:: python
96
97     from snaps.config.user import UserConfig
98     from snaps.openstack.create_user import OpenStackUser
99     user_settings = UserConfig(name='username', password='password')
100     user_creator = OpenStackUser(os_creds, user_settings)
101     user_creator.create()
102
103     # Retrieve OS creds for new user for creating other OpenStack instance
104     user_creds = user_creator.get_os_creds(os_creds.project_name)
105
106     # Perform logic
107     ...
108
109     # Cleanup
110     user_creator.clean()
111
112 Create Project
113 --------------
114 -  Project - snaps.openstack.create\_project.OpenStackProject
115
116    -  snaps.openstack.project.ProjectConfig
117
118       -  name - the project name (required)
119       -  domain - the project's domain (default='default')
120       -  description - the project's description (optional)
121       -  enabled - flag to determine whether or not the project should
122          be enabled (default=True)
123
124
125 .. code:: python
126
127     from snaps.openstack.project import ProjectConfig
128     from snaps.openstack.create_project import OpenStackProject
129     project_settings = ProjectConfig(name='username', password='password')
130     project_creator = OpenStackProject(os_creds, project_settings)
131     project_creator.create()
132
133     # Perform logic
134     ...
135
136     # Cleanup
137     project_creator.clean()
138
139 Create Flavor
140 -------------
141 -  Flavor - snaps.openstack.create\_flavor.OpenStackFlavor
142
143    -  snaps.config.flavor.FlavorConfig
144
145       -  name - the flavor name (required)
146       -  flavor\_id - the flavor's string ID (default='auto')
147       -  ram - memory in MB to allocate to VM (required)
148       -  disk - disk storage in GB (required)
149       -  vcpus - the number of CPUs to allocate to VM (required)
150       -  ephemeral - the size of the ephemeral disk in GB (default=0)
151       -  swap - the size of the swap disk in GB (default=0)
152       -  rxtx\_factor - the receive/transmit factor to be set on ports
153          if backend supports QoS extension (default=1.0)
154       -  is\_public - flag that denotes whether or not other projects
155          can access image (default=True)
156       -  metadata - freeform dict() for special metadata (optional)
157                   - freeform dict() for values of basic elements
158                     (e.g. ram, vcpu, disk, etc) could be added.
159                     As result the hard coded values of those elements will be
160                     overwritten by the new ones (optional)
161
162 .. code:: python
163
164     from snaps.config.flavor import FlavorConfig
165     from snaps.openstack.create_flavor import OpenStackFlavor
166     flavor_settings = FlavorConfig(name='flavor-name', ram=4, disk=10, vcpus=2)
167     flavor_creator = OpenStackFlavor(os_creds, flavor_settings)
168     flavor_creator.create()
169
170     # Perform logic
171     ...
172
173     # Cleanup
174     flavor_creator.clean()
175
176 Create Image
177 ------------
178 -  Image - snaps.openstack.create\_image.OpenStackImage
179
180    -  snaps.config.image.ImageConfig
181
182       -  name - the image name (required)
183       -  image\_user - the default image user generally used by
184          OpenStackVMInstance class for obtaining an SSH connection
185          (required)
186       -  img\_format or format - the image's format (i.e. qcow2) (required)
187       -  url - the download URL to obtain the image file (this or
188          image\_file must be configured, not both)
189       -  image\_file - the location of the file to be sourced from the
190          local filesystem (this or url must be configured, not both)
191       -  extra\_properties - dict() object containing extra parameters to
192          pass when loading the image (i.e. ids of kernel and initramfs images)
193       -  nic\_config\_pb\_loc - the location of the ansible playbook
194          that can configure additional NICs. Floating IPs are required
195          to perform this operation. (optional and deprecated)
196       -  kernel\_image\_settings - the image settings for a kernel image (optional)
197       -  ramdisk\_image\_settings - the image settings for a ramdisk image (optional)
198       -  public - image will be created with public visibility when True (default = False)
199
200
201 .. code:: python
202
203     from snaps.openstack.create_image import OpenStackImage
204     from snaps.config.image import ImageConfig
205     image_settings = ImageConfig(name='image-name', image_user='ubuntu', img_format='qcow2',
206                                  url='http://uec-images.ubuntu.com/releases/trusty/14.04/ubuntu-14.04-server-cloudimg-amd64-disk1.img')
207     image_creator = OpenStackImage(os_creds, image_settings)
208     image_creator.create()
209
210     # Perform logic
211     ...
212
213     # Cleanup
214     image_creator.clean()
215
216 Create Keypair
217 --------------
218 -  Keypair - snaps.openstack.create\_keypair.OpenStackKeypair
219
220    -  snaps.openstack.keypair.KeypairConfig
221
222       -  name - the keypair name (required)
223       -  public\_filepath - the file location to where the public key is
224          to be written or currently resides (optional)
225       -  private\_filepath - the file location to where the private key
226          file is to be written or currently resides (optional but highly
227          recommended to leverage or the private key will be lost
228          forever)
229       -  key\_size - The number of bytes for the key size when it needs to
230          be generated (value must be >=512, default = 1024)
231       -  delete\_on\_clean - when True, the key files will be deleted when
232          OpenStackKeypair#clean() is called (default = False)
233
234 .. code:: python
235
236     from snaps.openstack.keypair.KeypairConfig
237     from snaps.openstack.create_keypairs import OpenStackKeypair
238     keypair_settings = KeypairConfig(name='kepair-name', private_filepath='/tmp/priv-kp')
239     keypair_creator = OpenStackKeypair(os_creds, keypair_settings)
240     keypair_creator.create()
241
242     # Perform logic
243     ...
244
245     # Cleanup
246     keypair_creator.clean()
247
248 Create Network
249 --------------
250
251 -  Network - snaps.openstack.create\_network.OpenStackNetwork
252
253    -  snaps.config_network.NetworkConfig
254
255       -  name - the name of the network (required)
256       -  admin\_state\_up - flag denoting the administrative status of
257          the network (True = up, False = down)
258       -  shared - flag indicating whether the network can be shared
259          across projects/tenants (default=True)
260       -  project\_name - the name of the project (optional - can only be
261          set by admin users)
262       -  external - flag determining if network has external access
263          (default=False)
264       -  network\_type - the type of network (i.e. vlan\|vxlan\|flat)
265       -  physical\_network - the name of the physical network (required
266          when network\_type is 'flat')
267       -  segmentation\_id - the id of the segmentation (required
268          when network\_type is 'vlan')
269       -  subnet\_settings (list of optional
270          snaps.config.network.SubnetConfig objects)
271
272          -  cidr - the subnet's CIDR (required)
273          -  ip\_version - 4 or 6 (default=4)
274          -  name - the subnet name (required)
275          -  project\_name - the name of the project (optional - can only
276             be set by admin users)
277          -  start - the start address for the allocation pools
278          -  end - the end address for the allocation pools
279          -  gateway\_ip - the gateway IP
280          -  enable\_dhcp - flag to determine whether or not to enable
281             DHCP (optional)
282          -  dns\_nameservers - a list of DNS nameservers
283          -  host\_routes - list of host route dictionaries for subnet
284             (optional, see pydoc and Neutron API for more details)
285          -  destination - the destination for static route (optional)
286          -  nexthop - the next hop for the destination (optional)
287          -  ipv6\_ra\_mode - valid values include: 'dhcpv6-stateful',
288             'dhcp6v-stateless', 'slaac' (optional)
289          -  ipvc\_address\_mode - valid values include:
290             'dhcpv6-stateful', 'dhcp6v-stateless', 'slaac' (optional)
291
292 .. code:: python
293
294     from snaps.config.network import NetworkConfig, SubnetConfig
295     from snaps.openstack.create_network import OpenStackNetwork
296
297     subnet_settings = SubnetConfig(name='subnet-name', cidr='10.0.0.0/24')
298     network_settings = NetworkConfig(name='network-name', subnet_settings=[subnet_settings])
299
300     network_creator = OpenStackNetwork(os_creds, network_settings)
301     network_creator.create()
302
303     # Perform logic
304     ...
305
306     # Cleanup
307     network_creator.clean()
308
309 Create Security Group
310 ---------------------
311
312 -  Security Group -
313    snaps.openstack.create\_security\_group.OpenStackSecurityGroup
314
315    -  snaps.openstack.create\_security\_group.SecurityGroupSettings
316
317       -  name - the security group's name (required)
318       -  description - the description (optional)
319       -  project\_name - the name of the project (optional - can only be
320          set by admin users)
321       -  rule\_settings (list of
322          optional snaps.openstack.create\_security\_group.SecurityGroupRuleSettings
323          objects)
324
325          -  sec\_grp\_name - the name of the associated security group
326             (required)
327          -  description - the description (optional)
328          -  direction - enum
329             snaps.openstack.create\_security\_group.Direction (required)
330          -  remote\_group\_id - the group ID to associate with this rule
331          -  protocol -
332             enum snaps.openstack.create\_security\_group.Protocol
333             (optional)
334          -  ethertype -
335             enum snaps.openstack.create\_security\_group.Ethertype
336             (optional)
337          -  port\_range\_min - the max port number in the range that is
338             matched by the security group rule (optional)
339          -  port\_range\_max - the min port number in the range that is
340             matched by the security group rule (optional)
341          -  sec\_grp\_rule - the rule object to a security group rule
342             object to associate (note: does not work currently)
343          -  remote\_ip\_prefix - the remote IP prefix to associate with
344             this metering rule packet (optional)
345
346 .. code:: python
347
348     from snaps.config.network import SubnetConfig
349     from snaps.config.rule import RuleConfig
350     from snaps.openstack.create_security_group import SecurityGroupSettings, SecurityGroupRuleSettings, Direction, OpenStackSecurityGroup
351
352     rule_settings = RuleConfig(name='subnet-name', cidr='10.0.0.0/24')
353     network_settings = SubnetConfig(name='network-name', subnet_settings=[subnet_settings])
354
355     sec_grp_name = 'sec-grp-name'
356     rule_settings = SecurityGroupRuleSettings(name=sec_grp_name, direction=Direction.ingress)
357     security_group_settings = SecurityGroupSettings(name=sec_grp_name, rule_settings=[rule_settings])
358
359     security_group_creator = OpenStackSecurityGroup(os_creds, security_group_settings)
360     security_group_creator.create()
361
362     # Perform logic
363     ...
364
365     # Cleanup
366     security_group_creator.clean()
367
368 Create Router
369 -------------
370
371 -  Router - snaps.openstack.create\_router.OpenStackRouter
372
373    -  snaps.openstack.router.RouterConfig
374
375       -  name - the router name (required)
376       -  project\_name - the name of the project (optional - can only be
377          set by admin users)
378       -  external\_gateway - the name of the external network (optional)
379       -  admin\_state\_up - flag to denote the administrative status of
380          the router (default=True)
381       -  external\_fixed\_ips - dictionary containing the IP address
382          parameters (parameter not tested)
383       -  internal\_subnets - list of subnet names to which this router
384          will connect (optional)
385       -  port\_settings (list of optional
386          snaps.config.network.PortConfig objects) - creates
387          custom ports to internal subnets (similar to internal\_subnets
388          with more control)
389
390          -  name - the port's display name
391          -  network\_name - the name of the network on which to create the port
392          -  admin\_state\_up - A boolean value denoting the administrative
393             status of the port (default = True)
394          -  project\_name - the name of the project (optional - can only
395             be set by admin users)
396          -  mac\_address - the port's MAC address to set (optional and
397             recommended not to set this configuration value)
398          -  ip\_addrs - list of dict() objects containing two keys 'subnet_name'
399             and 'ip' where the value of the 'ip' entry is the expected IP
400             address assigned. This value gets mapped to the fixed\_ips
401             attribute (optional)
402          -  fixed\_ips - dict() where the key is the subnet ID and value is the
403             associated IP address to assign to the port (optional)
404          -  security\_groups - list of security group IDs (not tested)
405          -  allowed\_address\_pairs - A dictionary containing a set of zero or
406             more allowed address pairs. An address pair contains an IP address
407             and MAC address (optional)
408          -  opt\_value - the extra DHCP option value (optional)
409          -  opt\_name - the extra DHCP option name (optional)
410          -  device\_owner - The ID of the entity that uses this port.
411             For example, a DHCP agent (optional)
412          -  device\_id - The ID of the device that uses this port.
413             For example, a virtual server (optional)
414
415 .. code:: python
416
417     from snaps.config.router import RouterConfig
418     from snaps.openstack.create_router import OpenStackRouter
419
420     router_settings = RouterConfig(name='router-name', external_gateway='external')
421     router_creator = OpenStackRouter(os_creds, router_settings)
422     router_creator.create()
423
424     # Perform logic
425     ...
426
427     # Cleanup
428     router_creator.clean()
429
430 Create QoS Spec
431 ---------------
432
433 -  Volume Type - snaps.openstack.create\_qos.OpenStackQoS
434
435    -  snaps.openstack.qos.QoSConfig
436
437       -  name - the volume type's name (required)
438       -  consumer - the qos's consumer type of the enum type Consumer (required)
439       -  specs - freeform dict() to be added as 'specs' (optional)
440
441 .. code:: python
442
443     from snaps.openstack.qos import QoSConfig
444     from snaps.openstack.create_qos import OpenStackQoS
445
446     qos_settings = QoSConfig(name='stack-name', consumer=Consumer.front-end)
447     qos_creator = OpenStackQoS(os_creds, vol_type_settings)
448     qos_creator.create()
449
450     # Perform logic
451     ...
452
453     # Cleanup
454     qos_creator.clean()
455
456 Create Volume Type
457 ------------------
458
459 -  Volume Type - snaps.openstack.create\_volume\_type.OpenStackVolumeType
460
461    -  snaps.config.volume\_type.VolumeTypeConfig
462
463       -  name - the volume type's name (required)
464       -  description - the volume type's description (optional)
465       -  encryption - instance or config for VolumeTypeEncryptionConfig (optional)
466       -  qos\_spec\_name - name of the QoS Spec to associate (optional)
467       -  public - instance or config for VolumeTypeEncryptionConfig (optional)
468
469 .. code:: python
470
471     from snaps.config.volume_type import VolumeTypeConfig
472     from snaps.openstack.create_volume_type import OpenStackVolumeType
473
474     vol_type_settings = VolumeTypeConfig(name='stack-name')
475     vol_type_creator = OpenStackHeatStack(os_creds, vol_type_settings)
476     vol_type_creator.create()
477
478     # Perform logic
479     ...
480
481     # Cleanup
482     vol_type_creator.clean()
483
484 Create Volume
485 -------------
486
487 -  Volume - snaps.openstack.create\_volume.OpenStackVolume
488
489    -  snaps.config.volume.VolumeConfig
490
491       -  name - the volume type's name (required)
492       -  description - the volume type's description (optional)
493       -  size - size of volume in GB (default = 1)
494       -  image_name - when a glance image is used for the image source (optional)
495       -  type\_name - the associated volume's type name (optional)
496       -  availability\_zone - the name of the compute server on which to
497          deploy the volume (optional)
498       -  multi_attach - when true, volume can be attached to more than one
499          server (default = False)
500
501 .. code:: python
502
503     from snaps.config.volume import VolumeConfig
504     from snaps.openstack.create\_volume import OpenStackVolume
505
506     vol_settings = VolumeConfig(name='stack-name')
507     vol_creator = OpenStackVolume(os_creds, vol_settings)
508     vol_creator.create()
509
510     # Perform logic
511     ...
512
513     # Cleanup
514     vol_type_creator.clean()
515
516 Create Heat Stack
517 -----------------
518
519 -  Heat Stack - snaps.openstack.create\_stack.OpenStackHeatStack
520
521    -  snaps.config.stack.StackConfig
522
523       -  name - the stack's name (required)
524       -  template - the heat template in dict() format (required when
525          template_path is None)
526       -  template\_path - the location of the heat template file (required
527          when template is None)
528       -  env\_values - dict() of strings for substitution of template
529          default values (optional)
530
531 .. code:: python
532
533     from snaps.config.stack import StackConfig
534     from snaps.openstack.create_stack import OpenStackHeatStack
535
536     stack_settings = StackConfig(name='stack-name', template_path='/tmp/template.yaml')
537     stack_creator = OpenStackHeatStack(os_creds, stack_settings)
538     stack_creator.create()
539
540     # Perform logic
541     ...
542
543     # Cleanup
544     stack_creator.clean()
545
546 Create VM Instance
547 ------------------
548
549 -  VM Instances - snaps.openstack.create\_instance.OpenStackVmInstance
550
551    -  snaps.openstack.create\_instance.VmInstanceSettings
552
553       -  name - the name of the VM (required)
554       -  flavor - the name of the flavor (required)
555       -  port\_settings - list of
556          snaps.config.network.PortConfig objects where each
557          denote a NIC (see above in create router section for details)
558          API does not require, but newer NFVIs now require VMs have at
559          least one network
560       -  security\_group\_names - a list of security group names to
561          apply to VM
562       -  floating\_ip\_settings (list of
563          snaps.openstack\_create\_instance.FloatingIpSettings objects)
564
565          -  name - a name to a floating IP for easy lookup 
566          -  port\_name - the name of the VM port on which the floating
567             IP should be applied (required)
568          -  router\_name - the name of the router to the external
569             network (required)
570          -  subnet\_name - the name of the subnet on which to attach the
571             floating IP (optional)
572          -  provisioning - when true, this floating IP will be used for
573             provisioning which will come into play once we are able to
574             get multiple floating IPs working.
575
576       -  sudo\_user - overrides the image\_settings.image\_user value
577          when attempting to connect via SSH
578       -  vm\_boot\_timeout - the number of seconds that the thread will
579          block when querying the VM's status when building (default=900)
580       -  vm\_delete\_timeout - the number of seconds that the thread
581          will block when querying the VM's status when deleting
582          (default=300)
583       -  ssh\_connect\_timeout - the number of seconds that the thread
584          will block when attempting to obtain an SSH connection
585          (default=180)
586       -  availability\_zone - the name of the compute server on which to
587          deploy the VM (optional must be admin)
588       -  userdata - the cloud-init script to execute after VM has been
589          started
590
591    -  image\_settings - see snaps.config.image.ImageConfig
592       above (required)
593    -  keypair\_settings - see
594       snaps.openstack.keypair.KeypairConfig above (optional)
595
596 .. code:: python
597
598     from snaps.openstack.create_instance import VmInstanceSettings, FloatingIpSettings, OpenStackVmInstance
599     from snaps.config.network import PortConfig
600
601     port_settings = PortConfig(name='port-name', network_name=network_settings.name)
602     floating_ip_settings = FloatingIpSettings(name='fip1', port_name=port_settings.name, router_name=router_settings.name)
603     instance_settings = VmInstanceSettings(name='vm-name', flavor='flavor_settings.name', port_settings=[port_settings],
604                                            floating_ip_settings=[floating_ip_settings])
605
606     instance_creator = OpenStackVmInstance(os_creds, instance_settings, image_settings, kepair_settings)
607     instance_creator.create()
608
609     # Perform logic
610     ...
611     ssh_client = instance_creator.ssh_client()
612     ...
613
614     # Cleanup
615     instance_creator.clean()
616
617 Ansible Provisioning
618 ====================
619
620 Being able to easily create OpenStack instances such as virtual networks
621 and VMs is a good start to the problem of NFV; however, an NFVI is
622 useless unless there is some software performing some function. This is
623 why we added Ansible playbook support to SNAPS-OO which can be located
624 in snaps.provisioning.ansible\_utils#apply\_playbook. See below for a
625 description of that function's parameters:
626
627 -  playbook\_path - the file location of the ansible playbook
628 -  hosts\_inv - a list of hosts/IP addresses to which the playbook will
629    be applied
630 -  host\_user - the user (preferably sudo) to use for applying the
631    playbook
632 -  ssh\_priv\_key\_file\_path - the location to the private key file
633    used for SSH
634 -  variables - a dict() of substitution values for Jinga2 templates
635    leveraged by Ansible
636 -  proxy\_setting - used to extract the SSH proxy command (optional)
637
638 Apply Ansible Playbook Utility
639 ------------------------------
640
641 .. code:: python
642
643     from snaps.provisioning import ansible_utils
644
645     ansible_utils.apply_playbook(playbook_path='provisioning/tests/playbooks/simple_playbook.yml',
646                                  hosts_inv=[ip], host_user=user, ssh_priv_key_file_path=priv_key,
647                                  proxy_setting=self.os_creds.proxy_settings)
648
649 OpenStack Utilities
650 ===================
651
652 For those who do like working procedurally, SNAPS-OO also leverages
653 utilitarian functions for nearly every query or request made to
654 OpenStack. This pattern will make it easier to deal with API version
655 changes as they would all be made in one place. (see keystone\_utils for
656 an example of this pattern as this is the only API where SNAPS is
657 supporting more than one version)
658
659 -  snaps.openstack.utils.keystone\_utils - for calls to the Keystone
660    APIs (support for versions 2 & 3)
661 -  snaps.openstack.utils.glance\_utils - for calls to the Glance APIs
662    (support for versions 1 & 2)
663 -  snaps.openstack.utils.neutron\_utils - for calls to the Neutron APIs
664    (version 2)
665 -  snaps.openstack.utils.nova\_utils - for calls to the Nova APIs (version 2)
666 -  snaps.openstack.utils.heat\_utils - for calls to the Heat APIs (version 1)
667 -  snaps.openstack.utils.cinder\_utils - for calls to the Cinder APIs
668    (support for versions 2 & 3)