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
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:
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)
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>')
55 Create OS Credentials Object
56 ----------------------------
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)
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
80 - User - snaps.openstack.create\_user.OpenStackUser
82 - snaps.openstack.create\_user.UserSettings
84 - name - the username (required)
85 - password - the user's password (required)
86 - project\_name - the name of the project to associated to this
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)
97 from snaps.openstack.create_user import UserSettings, OpenStackUser
98 user_settings = UserSettings(name='username', password='password')
99 user_creator = OpenStackUser(os_creds, user_settings)
100 user_creator.create()
102 # Retrieve OS creds for new user for creating other OpenStack instance
103 user_creds = user_creator.get_os_creds(os_creds.project_name)
113 - Project - snaps.openstack.create\_project.OpenStackProject
115 - snaps.openstack.create\_project.ProjectSettings
117 - name - the project name (required)
118 - domain - the project's domain (default='default')
119 - description - the project's description (optional)
120 - enabled - flag to determine whether or not the project should
121 be enabled (default=True)
126 from snaps.openstack.create_project import ProjectSettings, OpenStackProject
127 project_settings = ProjectSettings(name='username', password='password')
128 project_creator = OpenStackProject(os_creds, project_settings)
129 project_creator.create()
135 project_creator.clean()
139 - Flavor - snaps.openstack.create\_flavor.OpenStackFlavor
141 - snaps.openstack.create\_flavor.FlavorSettings
143 - name - the flavor name (required)
144 - flavor\_id - the flavor's string ID (default='auto')
145 - ram - memory in MB to allocate to VM (required)
146 - disk - disk storage in GB (required)
147 - vcpus - the number of CPUs to allocate to VM (required)
148 - ephemeral - the size of the ephemeral disk in GB (default=0)
149 - swap - the size of the swap disk in GB (default=0)
150 - rxtx\_factor - the receive/transmit factor to be set on ports
151 if backend supports QoS extension (default=1.0)
152 - is\_public - flag that denotes whether or not other projects
153 can access image (default=True)
154 - metadata - freeform dict() for special metadata (optional)
158 from snaps.openstack.create_flavor import FlavorSettings, OpenStackFlavor
159 flavor_settings = FlavorSettings(name='flavor-name', ram=4, disk=10, vcpus=2)
160 flavor_creator = OpenStackFlavor(os_creds, flavor_settings)
161 flavor_creator.create()
167 flavor_creator.clean()
171 - Image - snaps.openstack.create\_image.OpenStackImage
173 - snaps.config.image.ImageConfig
175 - name - the image name (required)
176 - image\_user - the default image user generally used by
177 OpenStackVMInstance class for obtaining an SSH connection
179 - img\_format or format - the image's format (i.e. qcow2) (required)
180 - url - the download URL to obtain the image file (this or
181 image\_file must be configured, not both)
182 - image\_file - the location of the file to be sourced from the
183 local filesystem (this or url must be configured, not both)
184 - extra\_properties - dict() object containing extra parameters to
185 pass when loading the image (i.e. ids of kernel and initramfs images)
186 - nic\_config\_pb\_loc - the location of the ansible playbook
187 that can configure additional NICs. Floating IPs are required
188 to perform this operation. (optional and deprecated)
189 - kernel\_image\_settings - the image settings for a kernel image (optional)
190 - ramdisk\_image\_settings - the image settings for a ramdisk image (optional)
191 - public - image will be created with public visibility when True (default = False)
196 from snaps.openstack.create_image import OpenStackImage
197 from snaps.config.image import ImageConfig
198 image_settings = ImageConfig(name='image-name', image_user='ubuntu', img_format='qcow2',
199 url='http://uec-images.ubuntu.com/releases/trusty/14.04/ubuntu-14.04-server-cloudimg-amd64-disk1.img')
200 image_creator = OpenStackImage(os_creds, image_settings)
201 image_creator.create()
207 image_creator.clean()
211 - Keypair - snaps.openstack.create\_keypair.OpenStackKeypair
213 - snaps.openstack.create\_keypair.KeypairSettings
215 - name - the keypair name (required)
216 - public\_filepath - the file location to where the public key is
217 to be written or currently resides (optional)
218 - private\_filepath - the file location to where the private key
219 file is to be written or currently resides (optional but highly
220 recommended to leverage or the private key will be lost
222 - key\_size - The number of bytes for the key size when it needs to
223 be generated (value must be >=512, default = 1024)
224 - delete\_on\_clean - when True, the key files will be deleted when
225 OpenStackKeypair#clean() is called (default = False)
229 from snaps.openstack.create_keypairs import KeypairSettings, OpenStackKeypair
230 keypair_settings = KeypairSettings(name='kepair-name', private_filepath='/tmp/priv-kp')
231 keypair_creator = OpenStackKeypair(os_creds, keypair_settings)
232 keypair_creator.create()
238 keypair_creator.clean()
243 - Network - snaps.openstack.create\_network.OpenStackNetwork
245 - snaps.openstack.create\_network.NetworkSettings
247 - name - the name of the network (required)
248 - admin\_state\_up - flag denoting the administrative status of
249 the network (True = up, False = down)
250 - shared - flag indicating whether the network can be shared
251 across projects/tenants (default=True)
252 - project\_name - the name of the project (optional - can only be
254 - external - flag determining if network has external access
256 - network\_type - the type of network (i.e. vlan\|vxlan\|flat)
257 - physical\_network - the name of the physical network (required
258 when network\_type is 'flat')
259 - segmentation\_id - the id of the segmentation (required
260 when network\_type is 'vlan')
261 - subnet\_settings (list of optional
262 snaps.openstack.create\_network.SubnetSettings objects)
264 - cidr - the subnet's CIDR (required)
265 - ip\_version - 4 or 6 (default=4)
266 - name - the subnet name (required)
267 - project\_name - the name of the project (optional - can only
268 be set by admin users)
269 - start - the start address for the allocation pools
270 - end - the end address for the allocation pools
271 - gateway\_ip - the gateway IP
272 - enable\_dhcp - flag to determine whether or not to enable
274 - dns\_nameservers - a list of DNS nameservers
275 - host\_routes - list of host route dictionaries for subnet
276 (optional, see pydoc and Neutron API for more details)
277 - destination - the destination for static route (optional)
278 - nexthop - the next hop for the destination (optional)
279 - ipv6\_ra\_mode - valid values include: 'dhcpv6-stateful',
280 'dhcp6v-stateless', 'slaac' (optional)
281 - ipvc\_address\_mode - valid values include:
282 'dhcpv6-stateful', 'dhcp6v-stateless', 'slaac' (optional)
286 from snaps.openstack.create_network import NetworkSettings, SubnetSettings, OpenStackNetwork
288 subnet_settings = SubnetSettings(name='subnet-name', cidr='10.0.0.0/24')
289 network_settings = NetworkSettings(name='network-name', subnet_settings=[subnet_settings])
291 network_creator = OpenStackNetwork(os_creds, network_settings)
292 network_creator.create()
298 network_creator.clean()
300 Create Security Group
301 ---------------------
304 snaps.openstack.create\_security\_group.OpenStackSecurityGroup
306 - snaps.openstack.create\_security\_group.SecurityGroupSettings
308 - name - the security group's name (required)
309 - description - the description (optional)
310 - project\_name - the name of the project (optional - can only be
312 - rule\_settings (list of
313 optional snaps.openstack.create\_security\_group.SecurityGroupRuleSettings
316 - sec\_grp\_name - the name of the associated security group
318 - description - the description (optional)
320 snaps.openstack.create\_security\_group.Direction (required)
321 - remote\_group\_id - the group ID to associate with this rule
323 enum snaps.openstack.create\_security\_group.Protocol
326 enum snaps.openstack.create\_security\_group.Ethertype
328 - port\_range\_min - the max port number in the range that is
329 matched by the security group rule (optional)
330 - port\_range\_max - the min port number in the range that is
331 matched by the security group rule (optional)
332 - sec\_grp\_rule - the rule object to a security group rule
333 object to associate (note: does not work currently)
334 - remote\_ip\_prefix - the remote IP prefix to associate with
335 this metering rule packet (optional)
339 from snaps.openstack.create_security_group import SecurityGroupSettings, SecurityGroupRuleSettings, Direction, OpenStackSecurityGroup
341 rule_settings = SubnetSettings(name='subnet-name', cidr='10.0.0.0/24')
342 network_settings = NetworkSettings(name='network-name', subnet_settings=[subnet_settings])
344 sec_grp_name = 'sec-grp-name'
345 rule_settings = SecurityGroupRuleSettings(name=sec_grp_name, direction=Direction.ingress)
346 security_group_settings = SecurityGroupSettings(name=sec_grp_name, rule_settings=[rule_settings])
348 security_group_creator = OpenStackSecurityGroup(os_creds, security_group_settings)
349 security_group_creator.create()
355 security_group_creator.clean()
360 - Router - snaps.openstack.create\_router.OpenStackRouter
362 - snaps.openstack.create\_router.RouterSettings
364 - name - the router name (required)
365 - project\_name - the name of the project (optional - can only be
367 - external\_gateway - the name of the external network (optional)
368 - admin\_state\_up - flag to denote the administrative status of
369 the router (default=True)
370 - external\_fixed\_ips - dictionary containing the IP address
371 parameters (parameter not tested)
372 - internal\_subnets - list of subnet names to which this router
373 will connect (optional)
374 - port\_settings (list of optional
375 snaps.openstack.create\_router.PortSettings objects) - creates
376 custom ports to internal subnets (similar to internal\_subnets
379 - name - the port's display name
380 - network\_name - the name of the network on which to create the port
381 - admin\_state\_up - A boolean value denoting the administrative
382 status of the port (default = True)
383 - project\_name - the name of the project (optional - can only
384 be set by admin users)
385 - mac\_address - the port's MAC address to set (optional and
386 recommended not to set this configuration value)
387 - ip\_addrs - list of dict() objects containing two keys 'subnet_name'
388 and 'ip' where the value of the 'ip' entry is the expected IP
389 address assigned. This value gets mapped to the fixed\_ips
391 - fixed\_ips - dict() where the key is the subnet ID and value is the
392 associated IP address to assign to the port (optional)
393 - security\_groups - list of security group IDs (not tested)
394 - allowed\_address\_pairs - A dictionary containing a set of zero or
395 more allowed address pairs. An address pair contains an IP address
396 and MAC address (optional)
397 - opt\_value - the extra DHCP option value (optional)
398 - opt\_name - the extra DHCP option name (optional)
399 - device\_owner - The ID of the entity that uses this port.
400 For example, a DHCP agent (optional)
401 - device\_id - The ID of the device that uses this port.
402 For example, a virtual server (optional)
406 from snaps.openstack.create_router import RouterSettings, OpenStackRouter
408 router_settings = RouterSettings(name='router-name', external_gateway='external')
409 router_creator = OpenStackRouter(os_creds, router_settings)
410 router_creator.create()
416 router_creator.clean()
421 - Volume Type - snaps.openstack.create\_qos.OpenStackQoS
423 - snaps.openstack.create\_qos.QoSSettings
425 - name - the volume type's name (required)
426 - consumer - the qos's consumer type of the enum type Consumer (required)
427 - specs - freeform dict() to be added as 'specs' (optional)
431 from snaps.openstack.create_qos import QoSSettings, OpenStackQoS
433 qos_settings = QoSSettings(name='stack-name', consumer=Consumer.front-end)
434 qos_creator = OpenStackQoS(os_creds, vol_type_settings)
446 - Volume Type - snaps.openstack.create\_volume\_type.OpenStackVolumeType
448 - snaps.openstack.create\_volume\_type.VolumeTypeSettings
450 - name - the volume type's name (required)
451 - description - the volume type's description (optional)
452 - encryption - instance or config for VolumeTypeEncryptionSettings (optional)
453 - qos\_spec\_name - name of the QoS Spec to associate (optional)
454 - public - instance or config for VolumeTypeEncryptionSettings (optional)
458 from snaps.openstack.create_volume_type import VolumeTypeSettings, OpenStackVolumeType
460 vol_type_settings = VolumeTypeSettings(name='stack-name')
461 vol_type_creator = OpenStackHeatStack(os_creds, vol_type_settings)
462 vol_type_creator.create()
468 vol_type_creator.clean()
473 - Volume - snaps.openstack.create\_volume.OpenStackVolume
475 - snaps.openstack.create\_volume.VolumeSettings
477 - name - the volume type's name (required)
478 - description - the volume type's description (optional)
479 - size - size of volume in GB (default = 1)
480 - image_name - when a glance image is used for the image source (optional)
481 - type\_name - the associated volume's type name (optional)
482 - availability\_zone - the name of the compute server on which to
483 deploy the volume (optional)
484 - multi_attach - when true, volume can be attached to more than one
485 server (default = False)
489 from snaps.openstack.create\_volume import VolumeSettings, OpenStackVolume
491 vol_settings = VolumeSettings(name='stack-name')
492 vol_creator = OpenStackVolume(os_creds, vol_settings)
499 vol_type_creator.clean()
504 - Heat Stack - snaps.openstack.create\_stack.OpenStackHeatStack
506 - snaps.openstack.create\_stack.StackSettings
508 - name - the stack's name (required)
509 - template - the heat template in dict() format (required when
510 template_path is None)
511 - template\_path - the location of the heat template file (required
512 when template is None)
513 - env\_values - dict() of strings for substitution of template
514 default values (optional)
518 from snaps.openstack.create_stack import StackSettings, OpenStackHeatStack
520 stack_settings = StackSettings(name='stack-name', template_path='/tmp/template.yaml')
521 stack_creator = OpenStackHeatStack(os_creds, stack_settings)
522 stack_creator.create()
528 stack_creator.clean()
533 - VM Instances - snaps.openstack.create\_instance.OpenStackVmInstance
535 - snaps.openstack.create\_instance.VmInstanceSettings
537 - name - the name of the VM (required)
538 - flavor - the name of the flavor (required)
539 - port\_settings - list of
540 snaps.openstack.create\_network.PortSettings objects where each
541 denote a NIC (see above in create router section for details)
542 API does not require, but newer NFVIs now require VMs have at
544 - security\_group\_names - a list of security group names to
546 - floating\_ip\_settings (list of
547 snaps.openstack\_create\_instance.FloatingIpSettings objects)
549 - name - a name to a floating IP for easy lookup
550 - port\_name - the name of the VM port on which the floating
551 IP should be applied (required)
552 - router\_name - the name of the router to the external
554 - subnet\_name - the name of the subnet on which to attach the
555 floating IP (optional)
556 - provisioning - when true, this floating IP will be used for
557 provisioning which will come into play once we are able to
558 get multiple floating IPs working.
560 - sudo\_user - overrides the image\_settings.image\_user value
561 when attempting to connect via SSH
562 - vm\_boot\_timeout - the number of seconds that the thread will
563 block when querying the VM's status when building (default=900)
564 - vm\_delete\_timeout - the number of seconds that the thread
565 will block when querying the VM's status when deleting
567 - ssh\_connect\_timeout - the number of seconds that the thread
568 will block when attempting to obtain an SSH connection
570 - availability\_zone - the name of the compute server on which to
571 deploy the VM (optional must be admin)
572 - userdata - the cloud-init script to execute after VM has been
575 - image\_settings - see snaps.config.image.ImageConfig
577 - keypair\_settings - see
578 snaps.openstack.create\_keypairs.KeypairSettings above (optional)
582 from snaps.openstack.create_instance import VmInstanceSettings, FloatingIpSettings, OpenStackVmInstance
583 from snaps.openstack.create_network import PortSettings
585 port_settings = PortSettings(name='port-name', network_name=network_settings.name)
586 floating_ip_settings = FloatingIpSettings(name='fip1', port_name=port_settings.name, router_name=router_settings.name)
587 instance_settings = VmInstanceSettings(name='vm-name', flavor='flavor_settings.name', port_settings=[port_settings],
588 floating_ip_settings=[floating_ip_settings])
590 instance_creator = OpenStackVmInstance(os_creds, instance_settings, image_settings, kepair_settings)
591 instance_creator.create()
595 ssh_client = instance_creator.ssh_client()
599 instance_creator.clean()
604 Being able to easily create OpenStack instances such as virtual networks
605 and VMs is a good start to the problem of NFV; however, an NFVI is
606 useless unless there is some software performing some function. This is
607 why we added Ansible playbook support to SNAPS-OO which can be located
608 in snaps.provisioning.ansible\_utils#apply\_playbook. See below for a
609 description of that function's parameters:
611 - playbook\_path - the file location of the ansible playbook
612 - hosts\_inv - a list of hosts/IP addresses to which the playbook will
614 - host\_user - the user (preferably sudo) to use for applying the
616 - ssh\_priv\_key\_file\_path - the location to the private key file
618 - variables - a dict() of substitution values for Jinga2 templates
620 - proxy\_setting - used to extract the SSH proxy command (optional)
622 Apply Ansible Playbook Utility
623 ------------------------------
627 from snaps.provisioning import ansible_utils
629 ansible_utils.apply_playbook(playbook_path='provisioning/tests/playbooks/simple_playbook.yml',
630 hosts_inv=[ip], host_user=user, ssh_priv_key_file_path=priv_key,
631 proxy_setting=self.os_creds.proxy_settings)
636 For those who do like working procedurally, SNAPS-OO also leverages
637 utilitarian functions for nearly every query or request made to
638 OpenStack. This pattern will make it easier to deal with API version
639 changes as they would all be made in one place. (see keystone\_utils for
640 an example of this pattern as this is the only API where SNAPS is
641 supporting more than one version)
643 - snaps.openstack.utils.keystone\_utils - for calls to the Keystone
644 APIs (support for versions 2 & 3)
645 - snaps.openstack.utils.glance\_utils - for calls to the Glance APIs
646 (support for versions 1 & 2)
647 - snaps.openstack.utils.neutron\_utils - for calls to the Neutron APIs
649 - snaps.openstack.utils.nova\_utils - for calls to the Nova APIs (version 2)
650 - snaps.openstack.utils.heat\_utils - for calls to the Heat APIs (version 1)
651 - snaps.openstack.utils.cinder\_utils - for calls to the Cinder APIs
652 (support for versions 2 & 3)