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.user.UserConfig
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.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()
103 # Retrieve OS creds for new user for creating other OpenStack instance
104 user_creds = user_creator.get_os_creds(os_creds.project_name)
114 - Project - snaps.openstack.create\_project.OpenStackProject
116 - snaps.openstack.project.ProjectConfig
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)
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()
137 project_creator.clean()
141 - Flavor - snaps.openstack.create\_flavor.OpenStackFlavor
143 - snaps.config.flavor.FlavorConfig
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)
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()
174 flavor_creator.clean()
178 - Image - snaps.openstack.create\_image.OpenStackImage
180 - snaps.config.image.ImageConfig
182 - name - the image name (required)
183 - image\_user - the default image user generally used by
184 OpenStackVMInstance class for obtaining an SSH connection
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)
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()
214 image_creator.clean()
218 - Keypair - snaps.openstack.create\_keypair.OpenStackKeypair
220 - snaps.openstack.keypair.KeypairConfig
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
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)
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()
246 keypair_creator.clean()
251 - Network - snaps.openstack.create\_network.OpenStackNetwork
253 - snaps.config_network.NetworkConfig
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
262 - external - flag determining if network has external access
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)
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
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)
294 from snaps.config.network import NetworkConfig, SubnetConfig
295 from snaps.openstack.create_network import OpenStackNetwork
297 subnet_settings = SubnetConfig(name='subnet-name', cidr='10.0.0.0/24')
298 network_settings = NetworkConfig(name='network-name', subnet_settings=[subnet_settings])
300 network_creator = OpenStackNetwork(os_creds, network_settings)
301 network_creator.create()
307 network_creator.clean()
309 Create Security Group
310 ---------------------
313 snaps.openstack.create\_security\_group.OpenStackSecurityGroup
315 - snaps.openstack.create\_security\_group.SecurityGroupSettings
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
321 - rule\_settings (list of
322 optional snaps.openstack.create\_security\_group.SecurityGroupRuleSettings
325 - sec\_grp\_name - the name of the associated security group
327 - description - the description (optional)
329 snaps.openstack.create\_security\_group.Direction (required)
330 - remote\_group\_id - the group ID to associate with this rule
332 enum snaps.openstack.create\_security\_group.Protocol
335 enum snaps.openstack.create\_security\_group.Ethertype
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)
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
352 rule_settings = RuleConfig(name='subnet-name', cidr='10.0.0.0/24')
353 network_settings = SubnetConfig(name='network-name', subnet_settings=[subnet_settings])
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])
359 security_group_creator = OpenStackSecurityGroup(os_creds, security_group_settings)
360 security_group_creator.create()
366 security_group_creator.clean()
371 - Router - snaps.openstack.create\_router.OpenStackRouter
373 - snaps.openstack.router.RouterConfig
375 - name - the router name (required)
376 - project\_name - the name of the project (optional - can only be
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
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
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)
417 from snaps.config.router import RouterConfig
418 from snaps.openstack.create_router import OpenStackRouter
420 router_settings = RouterConfig(name='router-name', external_gateway='external')
421 router_creator = OpenStackRouter(os_creds, router_settings)
422 router_creator.create()
428 router_creator.clean()
433 - Volume Type - snaps.openstack.create\_qos.OpenStackQoS
435 - snaps.openstack.qos.QoSConfig
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)
443 from snaps.openstack.qos import QoSConfig
444 from snaps.openstack.create_qos import OpenStackQoS
446 qos_settings = QoSConfig(name='stack-name', consumer=Consumer.front-end)
447 qos_creator = OpenStackQoS(os_creds, vol_type_settings)
459 - Volume Type - snaps.openstack.create\_volume\_type.OpenStackVolumeType
461 - snaps.config.volume\_type.VolumeTypeConfig
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)
471 from snaps.config.volume_type import VolumeTypeConfig
472 from snaps.openstack.create_volume_type import OpenStackVolumeType
474 vol_type_settings = VolumeTypeConfig(name='stack-name')
475 vol_type_creator = OpenStackHeatStack(os_creds, vol_type_settings)
476 vol_type_creator.create()
482 vol_type_creator.clean()
487 - Volume - snaps.openstack.create\_volume.OpenStackVolume
489 - snaps.config.volume.VolumeConfig
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)
503 from snaps.config.volume import VolumeConfig
504 from snaps.openstack.create\_volume import OpenStackVolume
506 vol_settings = VolumeConfig(name='stack-name')
507 vol_creator = OpenStackVolume(os_creds, vol_settings)
514 vol_type_creator.clean()
519 - Heat Stack - snaps.openstack.create\_stack.OpenStackHeatStack
521 - snaps.config.stack.StackConfig
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)
533 from snaps.config.stack import StackConfig
534 from snaps.openstack.create_stack import OpenStackHeatStack
536 stack_settings = StackConfig(name='stack-name', template_path='/tmp/template.yaml')
537 stack_creator = OpenStackHeatStack(os_creds, stack_settings)
538 stack_creator.create()
544 stack_creator.clean()
549 - VM Instances - snaps.openstack.create\_instance.OpenStackVmInstance
551 - snaps.openstack.create\_instance.VmInstanceSettings
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
560 - security\_group\_names - a list of security group names to
562 - floating\_ip\_settings (list of
563 snaps.openstack\_create\_instance.FloatingIpSettings objects)
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
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.
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
583 - ssh\_connect\_timeout - the number of seconds that the thread
584 will block when attempting to obtain an SSH connection
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
591 - image\_settings - see snaps.config.image.ImageConfig
593 - keypair\_settings - see
594 snaps.openstack.keypair.KeypairConfig above (optional)
598 from snaps.openstack.create_instance import VmInstanceSettings, FloatingIpSettings, OpenStackVmInstance
599 from snaps.config.network import PortConfig
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])
606 instance_creator = OpenStackVmInstance(os_creds, instance_settings, image_settings, kepair_settings)
607 instance_creator.create()
611 ssh_client = instance_creator.ssh_client()
615 instance_creator.clean()
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:
627 - playbook\_path - the file location of the ansible playbook
628 - hosts\_inv - a list of hosts/IP addresses to which the playbook will
630 - host\_user - the user (preferably sudo) to use for applying the
632 - ssh\_priv\_key\_file\_path - the location to the private key file
634 - variables - a dict() of substitution values for Jinga2 templates
636 - proxy\_setting - used to extract the SSH proxy command (optional)
638 Apply Ansible Playbook Utility
639 ------------------------------
643 from snaps.provisioning import ansible_utils
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)
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)
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
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)