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 Versions 2.0 & v3 only validated.)
34 - image\_api\_version (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 - user\_domain\_id (default='default')
39 - project\_domain\_id (default='default')
40 - interface (default='admin', used to specify the endpoint type for keystone: public, admin, internal)
41 - cacert (default=False, expected values T|F to denote server certificate verification, else value contains the path to an HTTPS certificate)
42 - region_name (The region name default=None)
45 - host (the HTTP proxy host)
46 - port (the HTTP proxy port)
47 - https\_host (the HTTPS proxy host, default value of host)
48 - https\_port (the HTTPS proxy port, default value of port)
49 - ssh\_proxy\_cmd (same as the value placed into ssh -o
50 ProxyCommand='<this config value>')
52 Create OS Credentials Object
53 ----------------------------
57 from snaps.openstack.os_credentials import OSCreds
58 os_creds=OSCreds(username='admin', password='admin',
59 auth_url='http://localhost:5000/v3', project_name='admin',
60 identity_api_version=3)
65 Each creator minimally requires an OSCreds object for connecting to the
66 NFVI, associated \*Settings object for instance configuration, create()
67 method to make the necessary remote API calls and create all of the
68 necessary OpenStack instances required, and clean() method that is
69 responsible for deleting all associated OpenStack instances. Please see
70 the class diagram `here </display/SNAP/SNAPS-OO+Classes>`__. Below is a
71 textual representation of the requirements of each creator classes with
72 their associated setting classes and a sample code snippet on how to use
77 - User - snaps.openstack.create\_user.OpenStackUser
79 - snaps.openstack.create\_user.UserSettings
81 - name - the username (required)
82 - password - the user's password (required)
83 - project\_name - the name of the project to associated to this
85 - domain\_name - the user's domain (default='default')
86 - email - the user's email address (optional)
87 - enabled - flag to determine whether or not the user should be
88 enabled (default=True)
92 from snaps.openstack.create_user import UserSettings, OpenStackUser
93 user_settings = UserSettings(name='username', password='password')
94 user_creator = OpenStackUser(os_creds, user_settings)
97 # Retrieve OS creds for new user for creating other OpenStack instance
98 user_creds = user_creator.get_os_creds(os_creds.project_name)
108 - Project - snaps.openstack.create\_project.OpenStackProject
110 - snaps.openstack.create\_project.ProjectSettings
112 - name - the project name (required)
113 - domain - the project's domain (default='default')
114 - description - the project's description (optional)
115 - enables - flag to determine whether or not the project should
116 be enabled (default=True)
121 from snaps.openstack.create_project import ProjectSettings, OpenStackProject
122 project_settings = ProjectSettings(name='username', password='password')
123 project_creator = OpenStackProject(os_creds, project_settings)
124 project_creator.create()
130 project_creator.clean()
134 - Flavor - snaps.openstack.create\_flavor.OpenStackFlavor
136 - snaps.openstack.create\_flavor.FlavorSettings
138 - name - the flavor name (required)
139 - flavor\_id - the flavor's string ID (default='auto')
140 - ram - memory in MB to allocate to VM (required)
141 - disk - disk storage in GB (required)
142 - vcpus - the number of CPUs to allocate to VM (required)
143 - ephemeral - the size of the ephemeral disk in GB (default=0)
144 - swap - the size of the swap disk in GB (default=0)
145 - rxtx\_factor - the receive/transmit factor to be set on ports
146 if backend supports QoS extension (default=1.0)
147 - is\_public - flag that denotes whether or not other projects
148 can access image (default=True)
152 from snaps.openstack.create_flavor import FlavorSettings, OpenStackFlavor
153 flavor_settings = FlavorSettings(name='flavor-name', ram=4, disk=10, vcpus=2)
154 flavor_creator = OpenStackFlavor(os_creds, flavor_settings)
155 flavor_creator.create()
161 flavor_creator.clean()
165 - Image - snaps.openstack.create\_image.OpenStackImage
167 - snaps.openstack.create\_image.ImageSettings
169 - name - the image name (required)
170 - image\_user - the default image user generally used by
171 OpenStackVMInstance class for obtaining an SSH connection
173 - img\_format - the image's format (i.e. qcow2) (required)
174 - url - the download URL to obtain the image file (this or
175 image\_file must be configured, not both)
176 - image\_file - the location of the file to be sourced from the
177 local filesystem (this or url must be configured, not both)
178 - nic\_config\_pb\_loc - the location of the ansible playbook
179 that can configure additional NICs. Floating IPs are required
180 to perform this operation. (optional)
185 from snaps.openstack.create_image import ImageSettings, OpenStackImage
186 image_settings = ImageSettings(name='image-name', image_user='ubuntu', img_format='qcow2',
187 url='http://uec-images.ubuntu.com/releases/trusty/14.04/ubuntu-14.04-server-cloudimg-amd64-disk1.img')
188 image_creator = OpenStackImage(os_creds, image_settings)
189 image_creator.create()
195 image_creator.clean()
199 - Keypair - snaps.openstack.create\_keypair.OpenStackKeypair
201 - snaps.openstack.create\_keypair.KeypairSettings
203 - name - the keypair name (required)
204 - public\_filepath - the file location to where the public key is
205 to be written or currently resides (optional)
206 - private\_filepath - the file location to where the private key
207 file is to be written or currently resides (optional but highly
208 recommended to leverage or the private key will be lost
213 from snaps.openstack.create_keypairs import KeypairSettings, OpenStackKeypair
214 keypair_settings = KeypairSettings(name='kepair-name', private_filepath='/tmp/priv-kp')
215 keypair_creator = OpenStackKeypair(os_creds, keypair_settings)
216 keypair_creator.create()
222 keypair_creator.clean()
227 - Network - snaps.openstack.create\_network.OpenStackNetwork
229 - snaps.openstack.create\_network.NetworkSettings
231 - name - the name of the network (required)
232 - admin\_state\_up - flag denoting the administrative status of
233 the network (True = up, False = down)
234 - shared - flag indicating whether the network can be shared
235 across projects/tenants (default=True)
236 - project\_name - the name of the project (optional - can only be
238 - external - flag determining if network has external access
240 - network\_type - the type of network (i.e. vlan\|vxlan\|flat)
241 - physical\_network - the name of the physical network (required
242 when network\_type is 'flat')
243 - subnet\_settings (list of optional
244 snaps.openstack.create\_network.SubnetSettings objects)
246 - cidr - the subnet's CIDR (required)
247 - ip\_version - 4 or 6 (default=4)
248 - name - the subnet name (required)
249 - project\_name - the name of the project (optional - can only
250 be set by admin users)
251 - start - the start address for the allocation pools
252 - end - the end address for the allocation pools
253 - gateway\_ip - the gateway IP
254 - enable\_dhcp - flag to determine whether or not to enable
256 - dns\_nameservers - a list of DNS nameservers
257 - host\_routes - list of host route dictionaries for subnet
258 (optional, see pydoc and Neutron API for more details)
259 - destination - the destination for static route (optional)
260 - nexthop - the next hop for the destination (optional)
261 - ipv6\_ra\_mode - valid values include: 'dhcpv6-stateful',
262 'dhcp6v-stateless', 'slaac' (optional)
263 - ipvc\_address\_mode - valid values include:
264 'dhcpv6-stateful', 'dhcp6v-stateless', 'slaac' (optional)
268 from snaps.openstack.create_network import NetworkSettings, SubnetSettings, OpenStackNetwork
270 subnet_settings = SubnetSettings(name='subnet-name', cidr='10.0.0.0/24')
271 network_settings = NetworkSettings(name='network-name', subnet_settings=[subnet_settings])
273 network_creator = OpenStackNetwork(os_creds, network_settings)
274 network_creator.create()
280 network_creator.clean()
282 Create Security Group
283 ---------------------
286 snaps.openstack.create\_security\_group.OpenStackSecurityGroup
288 - snaps.openstack.create\_security\_group.SecurityGroupSettings
290 - name - the security group's name (required)
291 - description - the description (optional)
292 - project\_name - the name of the project (optional - can only be
294 - rule\_settings (list of
295 optional snaps.openstack.create\_security\_group.SecurityGroupRuleSettings
298 - sec\_grp\_name - the name of the associated security group
300 - description - the description (optional)
302 snaps.openstack.create\_security\_group.Direction (required)
303 - remote\_group\_id - the group ID to associate with this rule
305 enum snaps.openstack.create\_security\_group.Protocol
308 enum snaps.openstack.create\_security\_group.Ethertype
310 - port\_range\_min - the max port number in the range that is
311 matched by the security group rule (optional)
312 - port\_range\_max - the min port number in the range that is
313 matched by the security group rule (optional)
314 - sec\_grp\_rule - the rule object to a security group rule
315 object to associate (note: does not work currently)
316 - remote\_ip\_prefix - the remote IP prefix to associate with
317 this metering rule packet (optional)
321 from snaps.openstack.create_security_group import SecurityGroupSettings, SecurityGroupRuleSettings, Direction, OpenStackSecurityGroup
323 rule_settings = SubnetSettings(name='subnet-name', cidr='10.0.0.0/24')
324 network_settings = NetworkSettings(name='network-name', subnet_settings=[subnet_settings])
326 sec_grp_name = 'sec-grp-name'
327 rule_settings = SecurityGroupRuleSettings(name=sec_grp_name, direction=Direction.ingress)
328 security_group_settings = SecurityGroupSettings(name=sec_grp_name, rule_settings=[rule_settings])
330 security_group_creator = OpenStackSecurityGroup(os_creds, security_group_settings)
331 security_group_creator.create()
337 security_group_creator.clean()
342 - Router - snaps.openstack.create\_router.OpenStackRouter
344 - snaps.openstack.create\_router.RouterSettings
346 - name - the router name (required)
347 - project\_name - the name of the project (optional - can only be
349 - external\_gateway - the name of the external network (optional)
350 - admin\_state\_up - flag to denote the administrative status of
351 the router (default=True)
352 - external\_fixed\_ips - dictionary containing the IP address
353 parameters (parameter not tested)
354 - internal\_subnets - list of subnet names to which this router
355 will connect (optional)
356 - port\_settings (list of optional
357 snaps.openstack.create\_router.PortSettings objects) - creates
358 custom ports to internal subnets (similar to internal\_subnets
364 - project\_name - the name of the project (optional - can only
365 be set by admin users)
370 - allowed\_address\_pairs
378 from snaps.openstack.create_router import RouterSettings, OpenStackRouter
380 router_settings = RouterSettings(name='router-name', external_gateway='external')
381 router_creator = OpenStackRouter(os_creds, router_settings)
382 router_creator.create()
388 router_creator.clean()
393 - VM Instances - snaps.openstack.create\_instance.OpenStackVmInstance
395 - snaps.openstack.create\_instance.VmInstanceSettings
397 - name - the name of the VM (required)
398 - flavor - the name of the flavor (required)
399 - port\_settings - list of
400 snaps.openstack.create\_network.PortSettings objects where each
401 denote a NIC (see above in create router section for details)
402 API does not require, but newer NFVIs now require VMs have at
404 - security\_group\_names - a list of security group names to
406 - floating\_ip\_settings (list of
407 snaps.openstack\_create\_instance.FloatingIpSettings objects)
409 - name - a name to a floating IP for easy lookup
410 - port\_name - the name of the VM port on which the floating
411 IP should be applied (required)
412 - router\_name - the name of the router to the external
414 - subnet\_name - the name of the subnet on which to attach the
415 floating IP (optional)
416 - provisioning - when true, this floating IP will be used for
417 provisioning which will come into play once we are able to
418 get multiple floating IPs working.
420 - sudo\_user - overrides the image\_settings.image\_user value
421 when attempting to connect via SSH
422 - vm\_boot\_timeout - the number of seconds that the thread will
423 block when querying the VM's status when building (default=900)
424 - vm\_delete\_timeout - the number of seconds that the thread
425 will block when querying the VM's status when deleting
427 - ssh\_connect\_timeout - the number of seconds that the thread
428 will block when attempting to obtain an SSH connection
430 - availability\_zone - the name of the compute server on which to
431 deploy the VM (optional must be admin)
432 - userdata - the cloud-init script to execute after VM has been
435 - image\_settings - see snaps.openstack.create\_image.ImageSettings
437 - keypair\_settings - see
438 snaps.openstack.create\_keypairs.KeypairSettings above (optional)
442 from snaps.openstack.create_instance import VmInstanceSettings, FloatingIpSettings, OpenStackVmInstance
443 from snaps.openstack.create_network import PortSettings
445 port_settings = PortSettings(name='port-name', network_name=network_settings.name)
446 floating_ip_settings = FloatingIpSettings(name='fip1', port_name=port_settings.name, router_name=router_settings.name)
447 instance_settings = VmInstanceSettings(name='vm-name', flavor='flavor_settings.name', port_settings=[port_settings],
448 floating_ip_settings=[floating_ip_settings])
450 instance_creator = OpenStackVmInstance(os_creds, instance_settings, image_settings, kepair_settings)
451 instance_creator.create()
455 ssh_client = instance_creator.ssh_client()
459 instance_creator.clean()
464 Being able to easily create OpenStack instances such as virtual networks
465 and VMs is a good start to the problem of NFV; however, an NFVI is
466 useless unless there is some software performing some function. This is
467 why we added Ansible playbook support to SNAPS-OO which can be located
468 in snaps.provisioning.ansible\_utils#apply\_playbook. See below for a
469 description of that function's parameters:
471 - playbook\_path - the file location of the ansible playbook
472 - hosts\_inv - a list of hosts/IP addresses to which the playbook will
474 - host\_user - the user (preferably sudo) to use for applying the
476 - ssh\_priv\_key\_file\_path - the location to the private key file
478 - variables - a dict() of substitution values for Jinga2 templates
480 - proxy\_setting - used to extract the SSH proxy command (optional)
482 Apply Ansible Playbook Utility
483 ------------------------------
487 from snaps.provisioning import ansible_utils
489 ansible_utils.apply_playbook(playbook_path='provisioning/tests/playbooks/simple_playbook.yml',
490 hosts_inv=[ip], host_user=user, ssh_priv_key_file_path=priv_key,
491 proxy_setting=self.os_creds.proxy_settings)
496 For those who do like working procedurally, SNAPS-OO also leverages
497 utilitarian functions for nearly every query or request made to
498 OpenStack. This pattern will make it easier to deal with API version
499 changes as they would all be made in one place. (see keystone\_utils for
500 an example of this pattern as this is the only API where SNAPS is
501 supporting more than one version)
503 - snaps.openstack.utils.keystone\_utils - for calls to the Keystone
505 - snaps.openstack.utils.glance\_utils - for calls to the Glance APIs
506 - snaps.openstack.utils.neutron\_utils - for calls to the Neutron APIs
507 - snaps.openstack.utils.nova\_utils - for calls to the Nova APIs