Fixed docs build and examples
[snaps.git] / docs / how-to-use / LibraryUsage.rst
diff --git a/docs/how-to-use/LibraryUsage.rst b/docs/how-to-use/LibraryUsage.rst
new file mode 100644 (file)
index 0000000..6c84afd
--- /dev/null
@@ -0,0 +1,503 @@
+**********************
+SNAPS-OO Library Usage
+**********************
+
+The pattern used within the SNAPS-OO library for creating OpenStack
+instances have been made as consistent as possible amongst the different
+instance types. Each consists of a constructor that takes in a
+credentials object and generally takes in a single "settings"
+(configuration) object. The only exception to this rule is with the
+OpenStackVMInstance (creates an OpenStack Server) where it takes in the
+additional settings used for the associated image and SSH key-pairs
+credentials as those objects contain additional attributes required of
+SNAPS, primarily when one needs to obtain remote access. After
+instantiation, the create() method must be called to initiate all of the
+necessary remote API calls to OpenStack required for proper instance
+creation.
+
+SNAPS Credentials
+=================
+
+As communicating with OpenStack is performed via secure remote RESTful
+API calls, any function or method performing any type of query or CRUD
+operation must know how to connect to the NFVI. The class ***OSCreds***
+defined in *snaps.openstack.os\_credentials.py* contains everything
+required to connect to any Keystone v2.0 or v3 authorization server. The
+attributes are listed below:
+
+-  username
+-  password
+-  auth\_url
+-  project\_name (aka. tenant\_name)
+-  identity\_api\_version (for obtaining Keystone authorization token.
+   Versions 2.0 & v3 only validated.)
+-  image\_api\_version (Glance version 1 currently only validated)
+-  network\_api\_version (Neutron version 2 currently only validated)
+-  compute\_api\_version (Nova version 2 currently only validated)
+-  user\_domain\_id (default='default')
+-  project\_domain\_id (default='default')
+-  proxy\_settings
+
+   -  host (the HTTP proxy host)
+   -  port (the HTTP proxy port)
+   -  ssh\_proxy\_cmd (same as the value placed into ssh -o
+      ProxyCommand='<this config value>')
+
+Create OS Credentials Object
+----------------------------
+
+.. code:: python
+
+    from snaps.openstack.os_credentials import OSCreds
+    os_creds=OSCreds(username='admin', password`='admin'
+                     auth_url='http://localhost:5000/v3, project_name='admin',
+                     identity_api_version=3)
+
+SNAPS Object Creators
+=====================
+
+Each creator minimally requires an OSCreds object for connecting to the
+NFVI, associated \*Settings object for instance configuration, create()
+method to make the necessary remote API calls and create all of the
+necessary OpenStack instances required, and clean() method that is
+responsible for deleting all associated OpenStack instances. Please see
+the class diagram `here </display/SNAP/SNAPS-OO+Classes>`__. Below is a
+textual representation of the requirements of each creator classes with
+their associated setting classes and a sample code snippet on how to use
+the code.
+
+Create User
+-----------
+-  User - snaps.openstack.create\_user.OpenStackUser
+
+   -  snaps.openstack.create\_user.UserSettings
+
+      -  name - the username (required)
+      -  password - the user's password (required)
+      -  project\_name - the name of the project to associated to this
+         user (optional)
+      -  domain\_name - the user's domain (default='default')
+      -  email - the user's email address (optional)
+      -  enabled - flag to determine whether or not the user should be
+         enabled (default=True)
+
+.. code:: python
+
+    from snaps.openstack.create_user import UserSettings, OpenStackUser
+    user_settings = UserSettings(name='username', password='password)
+    user_creator = OpenStackUser(os_creds, user_settings)
+    user_creator.create()
+
+    # Retrieve OS creds for new user for creating other OpenStack instance
+    user_creds = user_creator.get_os_creds(os_creds.project_name)
+
+    # Perform logic
+    ...
+
+    # Cleanup
+    user_creator.clean()
+
+Create Project
+--------------
+-  Project - snaps.openstack.create\_project.OpenStackProject
+
+   -  snaps.openstack.create\_project.ProjectSettings
+
+      -  name - the project name (required)
+      -  domain - the project's domain (default='default')
+      -  description - the project's description (optional)
+      -  enables - flag to determine whether or not the project should
+         be enabled (default=True)
+
+.. code:: python
+
+    from snaps.openstack.create_project import ProjectSettings, OpenStackProject
+    project_settings = ProjectSettings(name='username', password='password)
+    project_creator = OpenStackProject(os_creds, project_settings)
+    project_creator.create()
+
+    # Perform logic
+    ...
+
+    # Cleanup
+    project_creator.clean()
+
+Create Flavor
+-------------
+-  Flavor - snaps.openstack.create\_flavor.OpenStackFlavor
+
+   -  snaps.openstack.create\_flavor.FlavorSettings
+
+      -  name - the flavor name (required)
+      -  flavor\_id - the flavor's string ID (default='auto')
+      -  ram - memory in MB to allocate to VM (required)
+      -  disk - disk storage in GB (required)
+      -  vcpus - the number of CPUs to allocate to VM (required)
+      -  ephemeral - the size of the ephemeral disk in GB (default=0)
+      -  swap - the size of the swap disk in GB (default=0)
+      -  rxtx\_factor - the receive/transmit factor to be set on ports
+         if backend supports QoS extension (default=1.0)
+      -  is\_public - flag that denotes whether or not other projects
+         can access image (default=True)
+
+.. code:: python
+
+    from snaps.openstack.create_flavor import FlavorSettings, OpenStackFlavor
+    flavor_settings = FlavorSettings(name='flavor-name', ram=4, disk=10, vcpus=2)
+    flavor_creator = OpenStackFlavor(os_creds, flavor_settings)
+    flavor_creator.create()
+
+    # Perform logic
+    ...
+
+    # Cleanup
+    flavor_creator.clean()
+
+Create Image
+------------
+-  Image - snaps.openstack.create\_image.OpenStackImage
+
+   -  snaps.openstack.create\_image.ImageSettings
+
+      -  name - the image name (required)
+      -  image\_user - the default image user generally used by
+         OpenStackVMInstance class for obtaining an SSH connection
+         (required)
+      -  img\_format - the image's format (i.e. qcow2) (required)
+      -  url - the download URL to obtain the image file (this or
+         image\_file must be configured, not both)
+      -  image\_file - the location of the file to be sourced from the
+         local filesystem (this or url must be configured, not both)
+      -  nic\_config\_pb\_loc - the location of the ansible playbook
+         that can configure additional NICs. Floating IPs are required
+         to perform this operation. (optional)
+
+
+.. code:: python
+
+    from snaps.openstack.create_image import ImageSettings, OpenStackImage
+    image_settings = ImageSettings(name='image-name', image_user='ubuntu', img_format='qcow2',
+                                   url='http://uec-images.ubuntu.com/releases/trusty/14.04/ubuntu-14.04-server-cloudimg-amd64-disk1.img')
+    image_creator = OpenStackImage(os_creds, image_settings)
+    image_creator.create()
+
+    # Perform logic
+    ...
+
+    # Cleanup
+    image_creator.clean()
+
+Create Keypair
+--------------
+-  Keypair - snaps.openstack.create\_keypair.OpenStackKeypair
+
+   -  snaps.openstack.create\_keypair.KeypairSettings
+
+      -  name - the keypair name (required)
+      -  public\_filepath - the file location to where the public key is
+         to be written or currently resides (optional)
+      -  private\_filepath - the file location to where the private key
+         file is to be written or currently resides (optional but highly
+         recommended to leverage or the private key will be lost
+         forever)
+
+.. code:: python
+
+    from snaps.openstack.create_keypair import KeypairSettings, OpenStackKeypair
+    keypair_settings = KeypairSettings(name='kepair-name', private_filepath='/tmp/priv-kp')
+    keypair_creator = OpenStackKeypair(os_creds, keypair_settings)
+    keypair_creator.create()
+
+    # Perform logic
+    ...
+
+    # Cleanup
+    keypair_creator.clean()
+
+Create Network
+--------------
+
+-  Network - snaps.openstack.create\_network.OpenStackNetwork
+
+   -  snaps.openstack.create\_network.NetworkSettings
+
+      -  name - the name of the network (required)
+      -  admin\_state\_up - flag denoting the administrative status of
+         the network (True = up, False = down)
+      -  shared - flag indicating whether the network can be shared
+         across projects/tenants (default=True)
+      -  project\_name - the name of the project (optional - can only be
+         set by admin users)
+      -  external - flag determining if network has external access
+         (default=False)
+      -  network\_type - the type of network (i.e. vlan\|vxlan\|flat)
+      -  physical\_network - the name of the physical network (required
+         when network\_type is 'flat')
+      -  subnet\_settings (list of optional
+         snaps.openstack.create\_network.SubnetSettings objects)
+
+         -  cidr - the subnet's CIDR (required)
+         -  ip\_version - 4 or 6 (default=4)
+         -  name - the subnet name (required)
+         -  project\_name - the name of the project (optional - can only
+            be set by admin users)
+         -  start - the start address for the allocation pools
+         -  end - the end address for the allocation pools
+         -  gateway\_ip - the gateway IP
+         -  enable\_dhcp - flag to determine whether or not to enable
+            DHCP (optional)
+         -  dns\_nameservers - a list of DNS nameservers
+         -  host\_routes - list of host route dictionaries for subnet
+            (optional, see pydoc and Neutron API for more details)
+         -  destination - the destination for static route (optional)
+         -  nexthop - the next hop for the destination (optional)
+         -  ipv6\_ra\_mode - valid values include: 'dhcpv6-stateful',
+            'dhcp6v-stateless', 'slaac' (optional)
+         -  ipvc\_address\_mode - valid values include:
+            'dhcpv6-stateful', 'dhcp6v-stateless', 'slaac' (optional)
+
+.. code:: python
+
+    from snaps.openstack.create_network import NetworkSettings, SubnetSettings, OpenStackNetwork
+
+    subnet_settings = SubnetSettings(name='subnet-name', cidr='10.0.0.0/24')
+    network_settings = NetworkSettings(name='network-name', subnet_settings=[subnet_settings])
+
+    network_creator = OpenStackNetwork(os_creds, network_settings)
+    network_creator.create()
+
+    # Perform logic
+    ...
+
+    # Cleanup
+    network_creator.clean()
+
+Create Security Group
+---------------------
+
+-  Security Group -
+   snaps.openstack.create\_security\_group.OpenStackSecurityGroup
+
+   -  snaps.openstack.create\_security\_group.SecurityGroupSettings
+
+      -  name - the security group's name (required)
+      -  description - the description (optional)
+      -  project\_name - the name of the project (optional - can only be
+         set by admin users)
+      -  rule\_settings (list of
+         optional snaps.openstack.create\_security\_group.SecurityGroupRuleSettings
+         objects)
+
+         -  sec\_grp\_name - the name of the associated security group
+            (required)
+         -  description - the description (optional)
+         -  direction - enum
+            snaps.openstack.create\_security\_group.Direction (required)
+         -  remote\_group\_id - the group ID to associate with this rule
+         -  protocol -
+            enum snaps.openstack.create\_security\_group.Protocol
+            (optional)
+         -  ethertype -
+            enum snaps.openstack.create\_security\_group.Ethertype
+            (optional)
+         -  port\_range\_min - the max port number in the range that is
+            matched by the security group rule (optional)
+         -  port\_range\_max - the min port number in the range that is
+            matched by the security group rule (optional)
+         -  sec\_grp\_rule - the rule object to a security group rule
+            object to associate (note: does not work currently)
+         -  remote\_ip\_prefix - the remote IP prefix to associate with
+            this metering rule packet (optional)
+
+.. code:: python
+
+    from snaps.openstack.create_security_group import SecurityGroupSettings, SecurityGroupRuleSettings, Direction,
+        OpenStackSecurityGroup
+
+    rule_settings = SubnetSettings(name='subnet-name', cidr='10.0.0.0/24')
+    network_settings = NetworkSettings(name='network-name', subnet_settings=[subnet_settings])
+
+    sec_grp_name = 'sec-grp-name'
+    rule_settings = SecurityGroupRuleSettings(name=sec_grp_name, direction=Direction.ingress)
+    security_group_settings = SecurityGroupSettings(name=sec_grp_name, rule_settings=[rule_settings])
+
+    security_group_creator = OpenStackSecurityGroup(os_creds, security_group_settings)
+    security_group_creator.create()
+
+    # Perform logic
+    ...
+
+    # Cleanup
+    security_group_creator.clean()
+
+Create Router
+-------------
+
+-  Router - snaps.openstack.create\_router.OpenStackRouter
+
+   -  snaps.openstack.create\_router.RouterSettings
+
+      -  name - the router name (required)
+      -  project\_name - the name of the project (optional - can only be
+         set by admin users)
+      -  external\_gateway - the name of the external network (optional)
+      -  admin\_state\_up - flag to denote the administrative status of
+         the router (default=True)
+      -  external\_fixed\_ips - dictionary containing the IP address
+         parameters (parameter not tested)
+      -  internal\_subnets - list of subnet names to which this router
+         will connect (optional)
+      -  port\_settings (list of optional
+         snaps.openstack.create\_router.PortSettings objects) - creates
+         custom ports to internal subnets (similar to internal\_subnets
+         with more control)
+
+         -  name
+         -  network\_name
+         -  admin\_state\_up
+         -  project\_name - the name of the project (optional - can only
+            be set by admin users)
+         -  mac\_address
+         -  ip\_addrs
+         -  fixed\_ips
+         -  security\_groups
+         -  allowed\_address\_pairs
+         -  opt\_value
+         -  opt\_name
+         -  device\_owner
+         -  device\_id
+
+.. code:: python
+
+    from snaps.openstack.create_router import RouterSettings, OpenStackRouter
+
+    router_settings = RouterSettings(name='router-name', external_gateway='external')
+    router_creator = OpenStackRouter(os_creds, router_settings)
+    router_creator.create()
+
+    # Perform logic
+    ...
+
+    # Cleanup
+    router_creator.clean()
+
+Create VM Instance
+------------------
+
+-  VM Instances - snaps.openstack.create\_instance.OpenStackVmInstance
+
+   -  snaps.openstack.create\_instance.VmInstanceSettings
+
+      -  name - the name of the VM (required)
+      -  flavor - the name of the flavor (required)
+      -  port\_settings - list of
+         snaps.openstack.create\_network.PortSettings objects where each
+         denote a NIC (see above in create router section for details)
+         API does not require, but newer NFVIs now require VMs have at
+         least one network
+      -  security\_group\_names - a list of security group names to
+         apply to VM
+      -  floating\_ip\_settings (list of
+         snaps.openstack\_create\_instance.FloatingIpSettings objects)
+
+         -  name - a name to a floating IP for easy lookup 
+         -  port\_name - the name of the VM port on which the floating
+            IP should be applied (required)
+         -  router\_name - the name of the router to the external
+            network (required)
+         -  subnet\_name - the name of the subnet on which to attach the
+            floating IP (optional)
+         -  provisioning - when true, this floating IP will be used for
+            provisioning which will come into play once we are able to
+            get multiple floating IPs working.
+
+      -  sudo\_user - overrides the image\_settings.image\_user value
+         when attempting to connect via SSH
+      -  vm\_boot\_timeout - the number of seconds that the thread will
+         block when querying the VM's status when building (default=900)
+      -  vm\_delete\_timeout - the number of seconds that the thread
+         will block when querying the VM's status when deleting
+         (default=300)
+      -  ssh\_connect\_timeout - the number of seconds that the thread
+         will block when attempting to obtain an SSH connection
+         (default=180)
+      -  availability\_zone - the name of the compute server on which to
+         deploy the VM (optional must be admin)
+      -  userdata - the cloud-init script to execute after VM has been
+         started
+
+   -  image\_settings - see snaps.openstack.create\_image.ImageSettings
+      above (required)
+   -  keypair\_settings - see
+      snaps.openstack.create\_keypairs.KeypairSettings above (optional)
+
+.. code:: python
+
+    from snaps.openstack.create_instance import VmInstanceSettings, FloatingIpSettings, OpenStackVmInstance
+    from snaps.openstack.create_network import PortSettings
+
+    port_settings = PortSettings(name='port-name', network_name=network_settings.name)
+    floating_ip_settings = FloatingIpSettings(name='fip1', port_name=port_settings.name, router_name=router_settings.name
+    instance_settings = VmInstanceSettings(name='vm-name', flavor='flavor_settings.name, port_settings=[port_settings],
+                                           floating_ip_settings=[floating_ip_settings]
+
+    instance_creator = OpenStackVmInstance(os_creds, instance_settings, image_settings, kepair_settings)
+    instance_creator.create()
+
+    # Perform logic
+    ...
+    ssh_client = instance_creator.ssh_client()
+    ...
+
+    # Cleanup
+    instance_creator.clean()
+
+Ansible Provisioning
+====================
+
+Being able to easily create OpenStack instances such as virtual networks
+and VMs is a good start to the problem of NFV; however, an NFVI is
+useless unless there is some software performing some function. This is
+why we added Ansible playbook support to SNAPS-OO which can be located
+in snaps.provisioning.ansible\_utils#apply\_playbook. See below for a
+description of that function's parameters:
+
+-  playbook\_path - the file location of the ansible playbook
+-  hosts\_inv - a list of hosts/IP addresses to which the playbook will
+   be applied
+-  host\_user - the user (preferably sudo) to use for applying the
+   playbook
+-  ssh\_priv\_key\_file\_path - the location to the private key file
+   used for SSH
+-  variables - a dict() of substitution values for Jinga2 templates
+   leveraged by Ansible
+-  proxy\_setting - used to extract the SSH proxy command (optional)
+
+Apply Ansible Playbook Utility
+------------------------------
+
+.. code:: python
+
+    from snaps.provisioning import ansible_utils
+
+    ansible_utils.apply_playbook(playbook_path='/tmp/playbook.yml',
+                                 hosts_inv=[instance_creator.get_port_ip(instance_settings.port_settings[0].name,
+                                 host_user=instance_creator.get_image_user(),
+                                 ssh_priv_key_file_path=instance_creator.keypair_settings.private_filepath)
+
+
+OpenStack Utilities
+=======================================
+
+For those who do like working procedurally, SNAPS-OO also leverages
+utilitarian functions for nearly every query or request made to
+OpenStack. This pattern will make it easier to deal with API version
+changes as they would all be made in one place. (see keystone\_utils for
+an example of this pattern as this is the only API where SNAPS is
+supporting more than one version)
+
+-  snaps.openstack.utils.keystone\_utils - for calls to the Keystone
+   APIs
+-  snaps.openstack.utils.glance\_utils - for calls to the Glance APIs
+-  snaps.openstack.utils.neutron\_utils - for calls to the Neutron APIs
+-  snaps.openstack.utils.nova\_utils - for calls to the Nova APIs