Refactoring of NetworkSettings to extend NetworkConfig
[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
158 .. code:: python
159
160     from snaps.config.flavor import FlavorConfig
161     from snaps.openstack.create_flavor import OpenStackFlavor
162     flavor_settings = FlavorConfig(name='flavor-name', ram=4, disk=10, vcpus=2)
163     flavor_creator = OpenStackFlavor(os_creds, flavor_settings)
164     flavor_creator.create()
165
166     # Perform logic
167     ...
168
169     # Cleanup
170     flavor_creator.clean()
171
172 Create Image
173 ------------
174 -  Image - snaps.openstack.create\_image.OpenStackImage
175
176    -  snaps.config.image.ImageConfig
177
178       -  name - the image name (required)
179       -  image\_user - the default image user generally used by
180          OpenStackVMInstance class for obtaining an SSH connection
181          (required)
182       -  img\_format or format - the image's format (i.e. qcow2) (required)
183       -  url - the download URL to obtain the image file (this or
184          image\_file must be configured, not both)
185       -  image\_file - the location of the file to be sourced from the
186          local filesystem (this or url must be configured, not both)
187       -  extra\_properties - dict() object containing extra parameters to
188          pass when loading the image (i.e. ids of kernel and initramfs images)
189       -  nic\_config\_pb\_loc - the location of the ansible playbook
190          that can configure additional NICs. Floating IPs are required
191          to perform this operation. (optional and deprecated)
192       -  kernel\_image\_settings - the image settings for a kernel image (optional)
193       -  ramdisk\_image\_settings - the image settings for a ramdisk image (optional)
194       -  public - image will be created with public visibility when True (default = False)
195
196
197 .. code:: python
198
199     from snaps.openstack.create_image import OpenStackImage
200     from snaps.config.image import ImageConfig
201     image_settings = ImageConfig(name='image-name', image_user='ubuntu', img_format='qcow2',
202                                  url='http://uec-images.ubuntu.com/releases/trusty/14.04/ubuntu-14.04-server-cloudimg-amd64-disk1.img')
203     image_creator = OpenStackImage(os_creds, image_settings)
204     image_creator.create()
205
206     # Perform logic
207     ...
208
209     # Cleanup
210     image_creator.clean()
211
212 Create Keypair
213 --------------
214 -  Keypair - snaps.openstack.create\_keypair.OpenStackKeypair
215
216    -  snaps.openstack.keypair.KeypairConfig
217
218       -  name - the keypair name (required)
219       -  public\_filepath - the file location to where the public key is
220          to be written or currently resides (optional)
221       -  private\_filepath - the file location to where the private key
222          file is to be written or currently resides (optional but highly
223          recommended to leverage or the private key will be lost
224          forever)
225       -  key\_size - The number of bytes for the key size when it needs to
226          be generated (value must be >=512, default = 1024)
227       -  delete\_on\_clean - when True, the key files will be deleted when
228          OpenStackKeypair#clean() is called (default = False)
229
230 .. code:: python
231
232     from snaps.openstack.keypair.KeypairConfig
233     from snaps.openstack.create_keypairs import OpenStackKeypair
234     keypair_settings = KeypairConfig(name='kepair-name', private_filepath='/tmp/priv-kp')
235     keypair_creator = OpenStackKeypair(os_creds, keypair_settings)
236     keypair_creator.create()
237
238     # Perform logic
239     ...
240
241     # Cleanup
242     keypair_creator.clean()
243
244 Create Network
245 --------------
246
247 -  Network - snaps.openstack.create\_network.OpenStackNetwork
248
249    -  snaps.config_network.NetworkConfig
250
251       -  name - the name of the network (required)
252       -  admin\_state\_up - flag denoting the administrative status of
253          the network (True = up, False = down)
254       -  shared - flag indicating whether the network can be shared
255          across projects/tenants (default=True)
256       -  project\_name - the name of the project (optional - can only be
257          set by admin users)
258       -  external - flag determining if network has external access
259          (default=False)
260       -  network\_type - the type of network (i.e. vlan\|vxlan\|flat)
261       -  physical\_network - the name of the physical network (required
262          when network\_type is 'flat')
263       -  segmentation\_id - the id of the segmentation (required
264          when network\_type is 'vlan')
265       -  subnet\_settings (list of optional
266          snaps.config.network.SubnetConfig objects)
267
268          -  cidr - the subnet's CIDR (required)
269          -  ip\_version - 4 or 6 (default=4)
270          -  name - the subnet name (required)
271          -  project\_name - the name of the project (optional - can only
272             be set by admin users)
273          -  start - the start address for the allocation pools
274          -  end - the end address for the allocation pools
275          -  gateway\_ip - the gateway IP
276          -  enable\_dhcp - flag to determine whether or not to enable
277             DHCP (optional)
278          -  dns\_nameservers - a list of DNS nameservers
279          -  host\_routes - list of host route dictionaries for subnet
280             (optional, see pydoc and Neutron API for more details)
281          -  destination - the destination for static route (optional)
282          -  nexthop - the next hop for the destination (optional)
283          -  ipv6\_ra\_mode - valid values include: 'dhcpv6-stateful',
284             'dhcp6v-stateless', 'slaac' (optional)
285          -  ipvc\_address\_mode - valid values include:
286             'dhcpv6-stateful', 'dhcp6v-stateless', 'slaac' (optional)
287
288 .. code:: python
289
290     from snaps.config.network import NetworkConfig, SubnetConfig
291     from snaps.openstack.create_network import OpenStackNetwork
292
293     subnet_settings = SubnetConfig(name='subnet-name', cidr='10.0.0.0/24')
294     network_settings = NetworkConfig(name='network-name', subnet_settings=[subnet_settings])
295
296     network_creator = OpenStackNetwork(os_creds, network_settings)
297     network_creator.create()
298
299     # Perform logic
300     ...
301
302     # Cleanup
303     network_creator.clean()
304
305 Create Security Group
306 ---------------------
307
308 -  Security Group -
309    snaps.openstack.create\_security\_group.OpenStackSecurityGroup
310
311    -  snaps.openstack.create\_security\_group.SecurityGroupSettings
312
313       -  name - the security group's name (required)
314       -  description - the description (optional)
315       -  project\_name - the name of the project (optional - can only be
316          set by admin users)
317       -  rule\_settings (list of
318          optional snaps.openstack.create\_security\_group.SecurityGroupRuleSettings
319          objects)
320
321          -  sec\_grp\_name - the name of the associated security group
322             (required)
323          -  description - the description (optional)
324          -  direction - enum
325             snaps.openstack.create\_security\_group.Direction (required)
326          -  remote\_group\_id - the group ID to associate with this rule
327          -  protocol -
328             enum snaps.openstack.create\_security\_group.Protocol
329             (optional)
330          -  ethertype -
331             enum snaps.openstack.create\_security\_group.Ethertype
332             (optional)
333          -  port\_range\_min - the max port number in the range that is
334             matched by the security group rule (optional)
335          -  port\_range\_max - the min port number in the range that is
336             matched by the security group rule (optional)
337          -  sec\_grp\_rule - the rule object to a security group rule
338             object to associate (note: does not work currently)
339          -  remote\_ip\_prefix - the remote IP prefix to associate with
340             this metering rule packet (optional)
341
342 .. code:: python
343
344     from snaps.config.network import SubnetConfig
345     from snaps.config.rule import RuleConfig
346     from snaps.openstack.create_security_group import SecurityGroupSettings, SecurityGroupRuleSettings, Direction, OpenStackSecurityGroup
347
348     rule_settings = RuleConfig(name='subnet-name', cidr='10.0.0.0/24')
349     network_settings = SubnetConfig(name='network-name', subnet_settings=[subnet_settings])
350
351     sec_grp_name = 'sec-grp-name'
352     rule_settings = SecurityGroupRuleSettings(name=sec_grp_name, direction=Direction.ingress)
353     security_group_settings = SecurityGroupSettings(name=sec_grp_name, rule_settings=[rule_settings])
354
355     security_group_creator = OpenStackSecurityGroup(os_creds, security_group_settings)
356     security_group_creator.create()
357
358     # Perform logic
359     ...
360
361     # Cleanup
362     security_group_creator.clean()
363
364 Create Router
365 -------------
366
367 -  Router - snaps.openstack.create\_router.OpenStackRouter
368
369    -  snaps.openstack.router.RouterConfig
370
371       -  name - the router name (required)
372       -  project\_name - the name of the project (optional - can only be
373          set by admin users)
374       -  external\_gateway - the name of the external network (optional)
375       -  admin\_state\_up - flag to denote the administrative status of
376          the router (default=True)
377       -  external\_fixed\_ips - dictionary containing the IP address
378          parameters (parameter not tested)
379       -  internal\_subnets - list of subnet names to which this router
380          will connect (optional)
381       -  port\_settings (list of optional
382          snaps.config.network.PortConfig objects) - creates
383          custom ports to internal subnets (similar to internal\_subnets
384          with more control)
385
386          -  name - the port's display name
387          -  network\_name - the name of the network on which to create the port
388          -  admin\_state\_up - A boolean value denoting the administrative
389             status of the port (default = True)
390          -  project\_name - the name of the project (optional - can only
391             be set by admin users)
392          -  mac\_address - the port's MAC address to set (optional and
393             recommended not to set this configuration value)
394          -  ip\_addrs - list of dict() objects containing two keys 'subnet_name'
395             and 'ip' where the value of the 'ip' entry is the expected IP
396             address assigned. This value gets mapped to the fixed\_ips
397             attribute (optional)
398          -  fixed\_ips - dict() where the key is the subnet ID and value is the
399             associated IP address to assign to the port (optional)
400          -  security\_groups - list of security group IDs (not tested)
401          -  allowed\_address\_pairs - A dictionary containing a set of zero or
402             more allowed address pairs. An address pair contains an IP address
403             and MAC address (optional)
404          -  opt\_value - the extra DHCP option value (optional)
405          -  opt\_name - the extra DHCP option name (optional)
406          -  device\_owner - The ID of the entity that uses this port.
407             For example, a DHCP agent (optional)
408          -  device\_id - The ID of the device that uses this port.
409             For example, a virtual server (optional)
410
411 .. code:: python
412
413     from snaps.config.router import RouterConfig
414     from snaps.openstack.create_router import OpenStackRouter
415
416     router_settings = RouterConfig(name='router-name', external_gateway='external')
417     router_creator = OpenStackRouter(os_creds, router_settings)
418     router_creator.create()
419
420     # Perform logic
421     ...
422
423     # Cleanup
424     router_creator.clean()
425
426 Create QoS Spec
427 ---------------
428
429 -  Volume Type - snaps.openstack.create\_qos.OpenStackQoS
430
431    -  snaps.openstack.qos.QoSConfig
432
433       -  name - the volume type's name (required)
434       -  consumer - the qos's consumer type of the enum type Consumer (required)
435       -  specs - freeform dict() to be added as 'specs' (optional)
436
437 .. code:: python
438
439     from snaps.openstack.qos import QoSConfig
440     from snaps.openstack.create_qos import OpenStackQoS
441
442     qos_settings = QoSConfig(name='stack-name', consumer=Consumer.front-end)
443     qos_creator = OpenStackQoS(os_creds, vol_type_settings)
444     qos_creator.create()
445
446     # Perform logic
447     ...
448
449     # Cleanup
450     qos_creator.clean()
451
452 Create Volume Type
453 ------------------
454
455 -  Volume Type - snaps.openstack.create\_volume\_type.OpenStackVolumeType
456
457    -  snaps.config.volume\_type.VolumeTypeConfig
458
459       -  name - the volume type's name (required)
460       -  description - the volume type's description (optional)
461       -  encryption - instance or config for VolumeTypeEncryptionConfig (optional)
462       -  qos\_spec\_name - name of the QoS Spec to associate (optional)
463       -  public - instance or config for VolumeTypeEncryptionConfig (optional)
464
465 .. code:: python
466
467     from snaps.config.volume_type import VolumeTypeConfig
468     from snaps.openstack.create_volume_type import OpenStackVolumeType
469
470     vol_type_settings = VolumeTypeConfig(name='stack-name')
471     vol_type_creator = OpenStackHeatStack(os_creds, vol_type_settings)
472     vol_type_creator.create()
473
474     # Perform logic
475     ...
476
477     # Cleanup
478     vol_type_creator.clean()
479
480 Create Volume
481 -------------
482
483 -  Volume - snaps.openstack.create\_volume.OpenStackVolume
484
485    -  snaps.config.volume.VolumeConfig
486
487       -  name - the volume type's name (required)
488       -  description - the volume type's description (optional)
489       -  size - size of volume in GB (default = 1)
490       -  image_name - when a glance image is used for the image source (optional)
491       -  type\_name - the associated volume's type name (optional)
492       -  availability\_zone - the name of the compute server on which to
493          deploy the volume (optional)
494       -  multi_attach - when true, volume can be attached to more than one
495          server (default = False)
496
497 .. code:: python
498
499     from snaps.config.volume import VolumeConfig
500     from snaps.openstack.create\_volume import OpenStackVolume
501
502     vol_settings = VolumeConfig(name='stack-name')
503     vol_creator = OpenStackVolume(os_creds, vol_settings)
504     vol_creator.create()
505
506     # Perform logic
507     ...
508
509     # Cleanup
510     vol_type_creator.clean()
511
512 Create Heat Stack
513 -----------------
514
515 -  Heat Stack - snaps.openstack.create\_stack.OpenStackHeatStack
516
517    -  snaps.config.stack.StackConfig
518
519       -  name - the stack's name (required)
520       -  template - the heat template in dict() format (required when
521          template_path is None)
522       -  template\_path - the location of the heat template file (required
523          when template is None)
524       -  env\_values - dict() of strings for substitution of template
525          default values (optional)
526
527 .. code:: python
528
529     from snaps.config.stack import StackConfig
530     from snaps.openstack.create_stack import OpenStackHeatStack
531
532     stack_settings = StackConfig(name='stack-name', template_path='/tmp/template.yaml')
533     stack_creator = OpenStackHeatStack(os_creds, stack_settings)
534     stack_creator.create()
535
536     # Perform logic
537     ...
538
539     # Cleanup
540     stack_creator.clean()
541
542 Create VM Instance
543 ------------------
544
545 -  VM Instances - snaps.openstack.create\_instance.OpenStackVmInstance
546
547    -  snaps.openstack.create\_instance.VmInstanceSettings
548
549       -  name - the name of the VM (required)
550       -  flavor - the name of the flavor (required)
551       -  port\_settings - list of
552          snaps.config.network.PortConfig objects where each
553          denote a NIC (see above in create router section for details)
554          API does not require, but newer NFVIs now require VMs have at
555          least one network
556       -  security\_group\_names - a list of security group names to
557          apply to VM
558       -  floating\_ip\_settings (list of
559          snaps.openstack\_create\_instance.FloatingIpSettings objects)
560
561          -  name - a name to a floating IP for easy lookup 
562          -  port\_name - the name of the VM port on which the floating
563             IP should be applied (required)
564          -  router\_name - the name of the router to the external
565             network (required)
566          -  subnet\_name - the name of the subnet on which to attach the
567             floating IP (optional)
568          -  provisioning - when true, this floating IP will be used for
569             provisioning which will come into play once we are able to
570             get multiple floating IPs working.
571
572       -  sudo\_user - overrides the image\_settings.image\_user value
573          when attempting to connect via SSH
574       -  vm\_boot\_timeout - the number of seconds that the thread will
575          block when querying the VM's status when building (default=900)
576       -  vm\_delete\_timeout - the number of seconds that the thread
577          will block when querying the VM's status when deleting
578          (default=300)
579       -  ssh\_connect\_timeout - the number of seconds that the thread
580          will block when attempting to obtain an SSH connection
581          (default=180)
582       -  availability\_zone - the name of the compute server on which to
583          deploy the VM (optional must be admin)
584       -  userdata - the cloud-init script to execute after VM has been
585          started
586
587    -  image\_settings - see snaps.config.image.ImageConfig
588       above (required)
589    -  keypair\_settings - see
590       snaps.openstack.keypair.KeypairConfig above (optional)
591
592 .. code:: python
593
594     from snaps.openstack.create_instance import VmInstanceSettings, FloatingIpSettings, OpenStackVmInstance
595     from snaps.config.network import PortConfig
596
597     port_settings = PortConfig(name='port-name', network_name=network_settings.name)
598     floating_ip_settings = FloatingIpSettings(name='fip1', port_name=port_settings.name, router_name=router_settings.name)
599     instance_settings = VmInstanceSettings(name='vm-name', flavor='flavor_settings.name', port_settings=[port_settings],
600                                            floating_ip_settings=[floating_ip_settings])
601
602     instance_creator = OpenStackVmInstance(os_creds, instance_settings, image_settings, kepair_settings)
603     instance_creator.create()
604
605     # Perform logic
606     ...
607     ssh_client = instance_creator.ssh_client()
608     ...
609
610     # Cleanup
611     instance_creator.clean()
612
613 Ansible Provisioning
614 ====================
615
616 Being able to easily create OpenStack instances such as virtual networks
617 and VMs is a good start to the problem of NFV; however, an NFVI is
618 useless unless there is some software performing some function. This is
619 why we added Ansible playbook support to SNAPS-OO which can be located
620 in snaps.provisioning.ansible\_utils#apply\_playbook. See below for a
621 description of that function's parameters:
622
623 -  playbook\_path - the file location of the ansible playbook
624 -  hosts\_inv - a list of hosts/IP addresses to which the playbook will
625    be applied
626 -  host\_user - the user (preferably sudo) to use for applying the
627    playbook
628 -  ssh\_priv\_key\_file\_path - the location to the private key file
629    used for SSH
630 -  variables - a dict() of substitution values for Jinga2 templates
631    leveraged by Ansible
632 -  proxy\_setting - used to extract the SSH proxy command (optional)
633
634 Apply Ansible Playbook Utility
635 ------------------------------
636
637 .. code:: python
638
639     from snaps.provisioning import ansible_utils
640
641     ansible_utils.apply_playbook(playbook_path='provisioning/tests/playbooks/simple_playbook.yml',
642                                  hosts_inv=[ip], host_user=user, ssh_priv_key_file_path=priv_key,
643                                  proxy_setting=self.os_creds.proxy_settings)
644
645 OpenStack Utilities
646 ===================
647
648 For those who do like working procedurally, SNAPS-OO also leverages
649 utilitarian functions for nearly every query or request made to
650 OpenStack. This pattern will make it easier to deal with API version
651 changes as they would all be made in one place. (see keystone\_utils for
652 an example of this pattern as this is the only API where SNAPS is
653 supporting more than one version)
654
655 -  snaps.openstack.utils.keystone\_utils - for calls to the Keystone
656    APIs (support for versions 2 & 3)
657 -  snaps.openstack.utils.glance\_utils - for calls to the Glance APIs
658    (support for versions 1 & 2)
659 -  snaps.openstack.utils.neutron\_utils - for calls to the Neutron APIs
660    (version 2)
661 -  snaps.openstack.utils.nova\_utils - for calls to the Nova APIs (version 2)
662 -  snaps.openstack.utils.heat\_utils - for calls to the Heat APIs (version 1)
663 -  snaps.openstack.utils.cinder\_utils - for calls to the Cinder APIs
664    (support for versions 2 & 3)