aboutsummaryrefslogtreecommitdiffstats
path: root/robot/resources/openstack
diff options
context:
space:
mode:
Diffstat (limited to 'robot/resources/openstack')
-rw-r--r--robot/resources/openstack/cinder_interface.robot50
-rw-r--r--robot/resources/openstack/heat_interface.robot93
-rw-r--r--robot/resources/openstack/keystone_interface.robot49
-rw-r--r--robot/resources/openstack/neutron_interface.robot123
-rw-r--r--robot/resources/openstack/nova_interface.robot149
-rw-r--r--robot/resources/openstack/openstack_common.robot50
6 files changed, 514 insertions, 0 deletions
diff --git a/robot/resources/openstack/cinder_interface.robot b/robot/resources/openstack/cinder_interface.robot
new file mode 100644
index 00000000..ee1a253b
--- /dev/null
+++ b/robot/resources/openstack/cinder_interface.robot
@@ -0,0 +1,50 @@
+*** Settings ***
+Documentation The main interface for interacting with Openstack. It handles low level stuff like managing the authtoken and Openstack required fields
+Library OpenstackLibrary
+Library RequestsLibrary
+Library UUID
+Library OperatingSystem
+Resource ../global_properties.robot
+Resource ../json_templater.robot
+Resource openstack_common.robot
+
+
+*** Variables ***
+${OPENSTACK_CINDER_API_VERSION} /v1
+${OPENSTACK_CINDER_TYPES_PATH} /types
+${OPENSTACK_CINDER_VOLUMES_PATH} /volumes
+${OPENSTACK_CINDER_VOLUMES_ADD_BODY_FILE} robot/assets/templates/cinder_add_volume.template
+${OPENSTACK_CINDER_VOLUMES_TYPE} SSD
+${OPENSTACK_CINDER_AVAILABILITY_ZONE} nova
+
+*** Keywords ***
+Get Openstack Volume Types
+ [Documentation] Returns the openstack volume types information
+ [Arguments] ${alias}
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_CINDER_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_CINDER_TYPES_PATH}
+ [Return] ${resp.json()}
+
+Get Openstack Volume
+ [Documentation] Returns the openstack volume information for the passed in volume id
+ [Arguments] ${alias} ${volume_id}
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_CINDER_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_CINDER_VOLUMES_PATH} /${volume_id}
+ [Return] ${resp.json()}
+
+Add Openstack Volume
+ [Documentation] Runs an Openstack Request to add a volume and returns that volume id of the created volume
+ [Arguments] ${alias} ${name} ${size}
+ ${data_template}= OperatingSystem.Get File ${OPENSTACK_CINDER_VOLUMES_ADD_BODY_FILE}
+ ${uuid}= Generate UUID
+ ${arguments}= Create Dictionary name=${name} description=${GLOBAL_APPLICATION_ID}${uuid} size=${size} type=${OPENSTACK_CINDER_VOLUMES_TYPE} availability_zone=${OPENSTACK_CINDER_AVAILABILITY_ZONE}
+ ${data}= Fill JSON Template ${data_template} ${arguments}
+ ${resp}= Internal Post Openstack ${alias} ${GLOBAL_OPENSTACK_CINDER_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_CINDER_VOLUMES_PATH} data_path= data=${data}
+ Should Be Equal As Strings 200 ${resp.status_code}
+ [Return] ${resp.json()['volume']['id']}
+
+Delete Openstack Volume
+ [Documentation] Runs an Openstack Request to delete a volume
+ [Arguments] ${alias} ${volume_id}
+ ${resp}= Internal Delete Openstack ${alias} ${GLOBAL_OPENSTACK_CINDER_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_CINDER_VOLUMES_PATH} /${volume_id}
+ ${status_string}= Convert To String ${resp.status_code}
+ Should Match Regexp ${status_string} ^(204|200|404)$
+ [Return] ${resp.text} \ No newline at end of file
diff --git a/robot/resources/openstack/heat_interface.robot b/robot/resources/openstack/heat_interface.robot
new file mode 100644
index 00000000..74c7aac8
--- /dev/null
+++ b/robot/resources/openstack/heat_interface.robot
@@ -0,0 +1,93 @@
+*** Settings ***
+Documentation The interface for interacting with Openstack Heat API.
+Library OpenstackLibrary
+Library RequestsLibrary
+Library UUID
+Library OperatingSystem
+Library HEATUtils
+Library StringTemplater
+Library Collections
+Resource ../global_properties.robot
+Resource ../json_templater.robot
+Resource openstack_common.robot
+
+*** Variables ***
+${OPENSTACK_HEAT_API_VERSION} /v1
+${OPENSTACK_HEAT_STACK_PATH} /stacks
+${OPENSTACK_HEAT_ADD_STACK_TEMPLATE} robot/assets/templates/heat_add_stack.template
+
+
+*** Keywords ***
+Get Openstack Stacks
+ [Documentation] Returns the openstack stacks info
+ [Arguments] ${alias}
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_HEAT_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_HEAT_STACK_PATH}
+ [Return] ${resp.json()}
+
+Get Openstack Stack
+ [Documentation] Returns the openstack stacks info for the given stack name
+ [Arguments] ${alias} ${stack_name}
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_HEAT_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_HEAT_STACK_PATH} /${stack_name}
+ [Return] ${resp.json()}
+
+Create Openstack Stack
+ [Documentation] Takes an openstack heat yaml and returns the created stack
+ [Arguments] ${alias} ${request}
+ ${resp}= Internal Post Openstack ${alias} ${GLOBAL_OPENSTACK_HEAT_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_HEAT_STACK_PATH} data_path= data=${request}
+ [Return] ${resp.json()}
+
+Make Add Stack Request
+ [Documentation] Makes a JSON Add Stack Request from YAML template and env files
+ [Arguments] ${name} ${template} ${env}
+ ${templatedata}= Template Yaml To Json ${template}
+ ${envdata}= Env Yaml To Json ${env}
+ ${dict}= Create Dictionary template=${templatedata} parameters=${envdata} stack_name=${name}
+ ${resp}= OperatingSystem.Get File ${OPENSTACK_HEAT_ADD_STACK_TEMPLATE}
+ ${request}= Template String ${resp} ${dict}
+ Log $request
+ [Return] ${request}
+
+Delete Openstack Stack
+ [Documentation] Deletes and Openstack Stack for the passed name and id
+ [Arguments] ${alias} ${stack_name} ${stack_id}
+ ${data_path}= Catenate /${stack_name}/${stack_id}
+ ${resp}= Internal Delete Openstack ${alias} ${GLOBAL_OPENSTACK_HEAT_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_HEAT_STACK_PATH} data_path=${data_path}
+ Should Be Equal As Strings 204 ${resp.status_code}
+ [Return] ${resp}
+
+Get Stack Details
+ [Documentation] Gets all of the information necessary for tearing down an existing Openstack Stack
+ [Arguments] ${alias} ${stack_name}
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_HEAT_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_HEAT_STACK_PATH} /${stack_name}
+ ${result}= Stack Info Parse ${resp.json()}
+ [Return] ${result}
+
+Get Stack Template
+ [Documentation] Gets all of the template information of an existing Openstack Stack
+ [Arguments] ${alias} ${stack_name} ${stack_id}
+ ${data_path}= Catenate /${stack_name}/${stack_id}/template
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_HEAT_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_HEAT_STACK_PATH} ${data_path}
+ ${template}= Catenate ${resp.json()}
+ [Return] ${template}
+
+Get Stack Resources
+ [Documentation] Gets all of the resources of an existing Openstack Stack
+ [Arguments] ${alias} ${stack_name} ${stack_id}
+ ${data_path}= Catenate /${stack_name}/${stack_id}/resources
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_HEAT_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_HEAT_STACK_PATH} ${data_path}
+ [Return] ${resp.json()}
+
+Wait for Stack to Be Deployed
+ [Arguments] ${alias} ${stack_name} ${timeout}=600s
+ ${stack_info}= Wait Until Keyword Succeeds ${timeout} 30 sec Get Deployed Stack ${alias} ${stack_name}
+ ${status}= Get From Dictionary ${stack_info} stack_status
+ Should Be Equal ${status} CREATE_COMPLETE
+ [Return] ${stack_info}
+
+Get Deployed Stack
+ [Arguments] ${alias} ${stack_name}
+ ${stack_info}= Get Stack Details ${alias} ${stack_name}
+ ${status}= Get From Dictionary ${stack_info} stack_status
+ Should Not Be Equal ${status} CREATE_IN_PROGRESS
+ [Return] ${stack_info}
+ \ No newline at end of file
diff --git a/robot/resources/openstack/keystone_interface.robot b/robot/resources/openstack/keystone_interface.robot
new file mode 100644
index 00000000..928efbdd
--- /dev/null
+++ b/robot/resources/openstack/keystone_interface.robot
@@ -0,0 +1,49 @@
+*** Settings ***
+Documentation The main interface for interacting with Openstack Keystone API. It handles low level stuff like managing the authtoken and Openstack required fields
+Library OpenstackLibrary
+Library RequestsLibrary
+Library UUID
+Library OperatingSystem
+Resource ../global_properties.robot
+Resource ../json_templater.robot
+Resource openstack_common.robot
+
+*** Variables ***
+${OPENSTACK_KEYSTONE_API_VERSION} /v2.0
+${OPENSTACK_KEYSTONE_AUTH_PATH} /tokens
+${OPENSTACK_KEYSTONE_AUTH_BODY_FILE} robot/assets/templates/keystone_get_auth.template
+${OPENSTACK_KEYSTONE_TENANT_PATH} /tenants
+
+*** Keywords ***
+Run Openstack Auth Request
+ [Documentation] Runs an Openstack Auth Request and returns the token and service catalog. you need to include the token in future request's x-auth-token headers. Service catalog describes what can be called
+ [Arguments] ${alias} ${username}= ${password}=
+ ${username} ${password}= Set Openstack Credentials ${username} ${password}
+ ${session}= Create Session keystone ${GLOBAL_OPENSTACK_KEYSTONE_SERVER} verify=True
+ ${uuid}= Generate UUID
+ ${data_template}= OperatingSystem.Get File ${OPENSTACK_KEYSTONE_AUTH_BODY_FILE}
+ ${arguments}= Create Dictionary username=${username} password=${password}
+ ${data}= Fill JSON Template ${data_template} ${arguments}
+ ${data_path}= Catenate ${OPENSTACK_KEYSTONE_API_VERSION}${OPENSTACK_KEYSTONE_AUTH_PATH}
+ ${headers}= Create Dictionary Accept=application/json Content-Type=application/json X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid} X-FromAppId=${GLOBAL_APPLICATION_ID}
+ Log Sending authenticate post request ${data_path} with headers ${headers} and data ${data}
+ ${resp}= Post Request keystone ${data_path} data=${data} headers=${headers}
+ Save Openstack Auth ${alias} ${resp.text}
+ Log Received response from keystone ${resp.text}
+
+Get Openstack Tenants
+ [Documentation] Returns all the openstack tenant info
+ [Arguments] ${alias}
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_KEYSTONE_SERVICE_TYPE} region= url_ext=${OPENSTACK_KEYSTONE_TENANT_PATH} data_path=
+ [Return] ${resp.json()}
+
+Get Openstack Tenant
+ [Documentation] Returns the openstack tenant info for the specified tenantid
+ [Arguments] ${alias} ${tenant_id}
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_KEYSTONE_SERVICE_TYPE} region= url_ext=${OPENSTACK_KEYSTONE_TENANT_PATH} data_path=/${tenant_id}
+ [Return] ${resp.json()}
+
+Set Openstack Credentials
+ [Arguments] ${username} ${password}
+ Return From Keyword If '${username}' != '' ${username} ${password}
+ [Return] ${GLOBAL_VM_PROPERTIES['openstack_username']} ${GLOBAL_VM_PROPERTIES['openstack_password']} \ No newline at end of file
diff --git a/robot/resources/openstack/neutron_interface.robot b/robot/resources/openstack/neutron_interface.robot
new file mode 100644
index 00000000..77635cdd
--- /dev/null
+++ b/robot/resources/openstack/neutron_interface.robot
@@ -0,0 +1,123 @@
+*** Settings ***
+Documentation The main interface for interacting with Openstack. It handles low level stuff like managing the authtoken and Openstack required fields
+Library OpenstackLibrary
+Library RequestsLibrary
+Library UUID
+Library OperatingSystem
+Library Collections
+Resource ../global_properties.robot
+Resource ../json_templater.robot
+Resource openstack_common.robot
+
+*** Variables ***
+${OPENSTACK_NEUTRON_API_VERSION} /v2.0
+${OPENSTACK_NEUTRON_NETWORK_PATH} /networks
+${OPENSTACK_NEUTRON_NETWORK_ADD_BODY_FILE} robot/assets/templates/neutron_add_network.template
+${OPENSTACK_NEUTRON_SUBNET_PATH} /subnets
+${OPENSTACK_NEUTRON_SUBNET_ADD_BODY_FILE} robot/assets/templates/neutron_add_subnet.template
+${OPENSTACK_NEUTRON_PORT_PATH} /ports
+
+*** Keywords ***
+Get Openstack Network
+ [Documentation] Runs an Openstack Request and returns the network info
+ [Arguments] ${alias} ${network_id}
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NEUTRON_NETWORK_PATH} /${network_id}
+ [Return] ${resp.json()}
+
+Get Openstack Networks
+ [Documentation] Runs an Openstack Request and returns the network info
+ [Arguments] ${alias}
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NEUTRON_NETWORK_PATH}
+ [Return] ${resp.json()}
+
+Get Openstack Subnets
+ [Documentation] Runs an Openstack Request and returns the network info
+ [Arguments] ${alias}
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NEUTRON_SUBNET_PATH}
+ [Return] ${resp.json()}
+
+Get Openstack Ports
+ [Documentation] Runs an Openstack Request and returns the network info
+ [Arguments] ${alias}
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NEUTRON_PORT_PATH}
+ [Return] ${resp.json()}
+
+Add Openstack Network
+ [Documentation] Runs an Openstack Request to add a network and returns that network id of the created network
+ [Arguments] ${alias} ${name}
+ ${data_template}= OperatingSystem.Get File ${OPENSTACK_NEUTRON_NETWORK_ADD_BODY_FILE}
+ ${arguments}= Create Dictionary name=${name}
+ ${data}= Fill JSON Template ${data_template} ${arguments}
+ ${resp}= Internal Post Openstack ${alias} ${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NEUTRON_NETWORK_PATH} data_path= data=${data}
+ Should Be Equal As Strings 201 ${resp.status_code}
+ [Return] ${resp.json()['network']['id']}
+
+Delete Openstack Network
+ [Documentation] Runs an Openstack Request to delete a network
+ [Arguments] ${alias} ${network_id}
+ ${resp}= Internal Delete Openstack ${alias} ${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NEUTRON_NETWORK_PATH} /${network_id}
+ ${status_string}= Convert To String ${resp.status_code}
+ Should Match Regexp ${status_string} ^(204|200)$
+ [Return] ${resp.text}
+
+Add Openstack Network With Subnet If Not Exists
+ [Documentation] Runs an Openstack Request to add a network and returns that network id of the created network
+ [Arguments] ${alias} ${name} ${cidr}
+ ${network}= Get Openstack Subnet By Name ${alias} ${name} ${cidr}
+ ${pass} ${v}= Run Keyword and Ignore Error Dictionary Should Contain Key ${network} id
+ Run Keyword If '${pass}' == 'FAIL' Add Openstack Network With Subnet ${alias} ${name} ${cidr}
+ ${network}= Get Openstack Subnet By Name ${alias} ${name} ${cidr}
+ ${network_id}= Get From Dictionary ${network} id
+ [Return] ${network_id}
+
+
+Add Openstack Network With Subnet
+ [Documentation] Runs an Openstack Request to add a network and returns that network id of the created network
+ [Arguments] ${alias} ${name} ${cidr}
+ ${network_id}= Add Openstack Network ${alias} ${name}
+ ${data_template}= OperatingSystem.Get File ${OPENSTACK_NEUTRON_SUBNET_ADD_BODY_FILE}
+ ${arguments}= Create Dictionary network_id=${network_id} cidr=${cidr} subnet_name=${name}
+ ${data}= Fill JSON Template ${data_template} ${arguments}
+ ${resp}= Internal Post Openstack ${alias} ${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NEUTRON_SUBNET_PATH} data_path= data=${data}
+ Should Be Equal As Strings 201 ${resp.status_code}
+ [Return] ${network_id}
+
+Get Openstack Subnet By Name
+ [Documentation] Retrieve the subnet from openstack by it's name.
+ [Arguments] ${alias} ${network_name} ${network_cidr}
+ ${resp}= Get Openstack Subnets ${alias}
+ @{list}= Get From Dictionary ${resp} subnets
+ ${returnnet}= Set Variable
+ :for ${net} in @{list}
+ \ ${name}= Get From Dictionary ${net} name
+ \ ${cidr}= Get From Dictionary ${net} cidr
+ \ ${returnnet}= Set Variable ${net}
+ \ Exit For Loop If '${name}'=='${network_name}' and '${cidr}'=='${network_cidr}'
+ \ ${returnnet}= Create DIctionary
+ [Return] ${returnnet}
+
+Get Openstack IP By Name
+ [Arguments] ${alias} ${network_name} ${cidr} ${ip}
+ ${ports}= Get Openstack Ports For Subnet ${alias} ${network_name} ${cidr}
+ Log ${ports}
+ :for ${port} in @{ports}
+ \ Return From Keyword If '${port['fixed_ips'][0]['ip_address']}' == '${ip}' ${port}
+ [Return] None
+
+Get Openstack Ports For Subnet
+ [Arguments] ${alias} ${network_name} ${cidr}
+ ${net}= Get Openstack Subnet By Name ${alias} ${network_name} ${cidr}
+ ${ports}= Get Openstack Ports ${alias}
+ ${net_ports}= Create List
+ :for ${port} in @{ports['ports']}
+ \ Run Keyword If '${net['network_id']}' == '${port['network_id']}' Append To List ${net_ports} ${port}
+ [Return] ${net_ports}
+
+Delete Openstack Port
+ [Arguments] ${alias} ${port_id}
+ ${resp}= Internal Delete Openstack ${alias} ${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NEUTRON_PORT_PATH} /${port_id}
+ ${status_string}= Convert To String ${resp.status_code}
+ Should Match Regexp ${status_string} ^(204|200)$
+ [Return] ${resp.text}
+
+ \ No newline at end of file
diff --git a/robot/resources/openstack/nova_interface.robot b/robot/resources/openstack/nova_interface.robot
new file mode 100644
index 00000000..efee279a
--- /dev/null
+++ b/robot/resources/openstack/nova_interface.robot
@@ -0,0 +1,149 @@
+*** Settings ***
+Documentation The main interface for interacting with Openstack. It handles low level stuff like managing the authtoken and Openstack required fields
+Library OpenstackLibrary
+Library RequestsLibrary
+Library JSONUtils
+Library UUID
+Library OperatingSystem
+Library Collections
+Resource ../global_properties.robot
+Resource ../json_templater.robot
+Resource openstack_common.robot
+
+*** Variables ***
+${OPENSTACK_NOVA_API_VERSION} /v2
+${OPENSTACK_NOVA_KEYPAIR_PATH} /os-keypairs
+${OPENSTACK_NOVA_KEYPAIR_ADD_BODY_FILE} robot/assets/templates/nova_add_keypair.template
+${OPENSTACK_NOVA_KEYPAIR_SSH_KEY} robot/assets/keys/robot_ssh_public_key.txt
+${OPENSTACK_NOVA_FLAVORS_PATH} /flavors
+${OPENSTACK_NOVA_SERVERS_PATH} /servers
+${OPENSTACK_NOVA_IMAGES_PATH} /images
+${OPENSTACK_NOVA_SERVERS_REBOOT_BODY} {"reboot" : { "type" : "SOFT" }}
+${OPENSTACK_NOVA_SERVER_ADD_BODY_FILE} robot/assets/templates/nova_add_server.template
+
+
+*** Keywords ***
+Get Openstack Keypair
+ [Documentation] Runs an Openstack Request and returns the keypair info
+ [Arguments] ${alias} ${keypair_name}
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NOVA_KEYPAIR_PATH} /${keypair_name}
+ [Return] ${resp.json()}
+
+Add Openstack Keypair
+ [Documentation] Runs an Openstack Request to add a keypair and returns the keypair name
+ [Arguments] ${alias} ${name}
+ ${data_template}= OperatingSystem.Get File ${OPENSTACK_NOVA_KEYPAIR_ADD_BODY_FILE}
+ ${ssh_key}= OperatingSystem.Get File ${OPENSTACK_NOVA_KEYPAIR_SSH_KEY}
+ ${arguments}= Create Dictionary name=${name} publickey=${ssh_key}
+ ${data}= Fill JSON Template ${data_template} ${arguments}
+ ${resp}= Internal Post Openstack ${alias} ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NOVA_KEYPAIR_PATH} data_path= data=${data}
+ Should Be Equal As Strings 200 ${resp.status_code}
+ [Return] ${resp.json()['keypair']['name']}
+
+Delete Openstack Keypair
+ [Documentation] Runs an Openstack Request to delete a keypair
+ [Arguments] ${alias} ${keypair_name}
+ ${resp}= Internal Delete Openstack ${alias} ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NOVA_KEYPAIR_PATH} /${keypair_name}
+ ${status_string}= Convert To String ${resp.status_code}
+ Should Match Regexp ${status_string} ^(204|202|200)$
+ [Return] ${resp.text}
+
+
+Get Openstack Servers
+ [Documentation] Returns the list of servers as a dictionary by name
+ [Arguments] ${alias}
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NOVA_SERVERS_PATH} /detail
+ Log Returned from Internal Get Openstack
+ ${by_name}= Make List Into Dict ${resp.json()['servers']} name
+ Log got it
+ [Return] ${by_name}
+
+Get Openstack Server By Id
+ [Documentation] Returns the openstack stacks info for the given stack name
+ [Arguments] ${alias} ${server_id}
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NOVA_SERVERS_PATH} /${server_id}
+ [Return] ${resp}
+
+Get Openstack Flavors
+ [Documentation] Runs an Openstack Request and returns the flavor list
+ [Arguments] ${alias}
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NOVA_FLAVORS_PATH}
+ [Return] ${resp.json()}
+
+Get Openstack Images
+ [Documentation] Runs an Openstack Request and returns the flavor list
+ [Arguments] ${alias}
+ ${resp}= Internal Get Openstack ${alias} ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NOVA_IMAGES_PATH}
+ [Return] ${resp.json()}
+
+Reboot Server
+ [Documentation] Requests a reboot of the passed server id
+ [Arguments] ${alias} ${server_id}
+ ${resp}= Internal Post Openstack ${alias} ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NOVA_SERVERS_PATH} /${server_id}/action ${OPENSTACK_NOVA_SERVERS_REBOOT_BODY}
+ [Return] ${resp}
+
+Add Server
+ [Documentation] Adds a server for the passed if
+ [Arguments] ${alias} ${name} ${imageRef} ${flavorRef}
+ ${dict}= Create Dictionary name=${name} imageRef=${imageRef} flavorRef=${flavorRef}
+ ${data}= Fill JSON Template File ${OPENSTACK_NOVA_SERVER_ADD_BODY_FILE} ${dict}
+ ${resp}= Internal Post Openstack ${alias} ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NOVA_SERVERS_PATH} data_path= data=${data}
+ [Return] ${resp}
+
+Add Server For Image Name
+ [Documentation] Adds a server for the passed if
+ [Arguments] ${alias} ${name} ${imageName} ${flavorName}
+ ${images}= Get Openstack Images ${alias}
+ ${flavors}= Get Openstack Flavors ${alias}
+ ${images}= Get From Dictionary ${images} images
+ ${flavors}= Get From Dictionary ${flavors} flavors
+ ${imageRef}= Get Id For Name ${images} ${imageName}
+ ${flavorRef}= Get Id For Name ${flavors} ${flavorName}
+ ${dict}= Create Dictionary name=${name} imageRef=${imageRef} flavorRef=${flavorRef}
+ ${data}= Fill JSON Template File ${OPENSTACK_NOVA_SERVER_ADD_BODY_FILE} ${dict}
+ ${resp}= Internal Post Openstack ${alias} ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NOVA_SERVERS_PATH} data_path= data=${data}
+ ${status_string}= Convert To String ${resp.status_code}
+ Should Match Regexp ${status_string} ^(202)$
+ [Return] ${resp.json()}
+
+Wait for Server to Be Active
+ [Arguments] ${alias} ${server_id} ${timeout}=300s
+ ${server_info}= Wait Until Keyword Succeeds ${timeout} 10 sec Get Active Server ${alias} ${server_id}
+ ${status}= Get From Dictionary ${server_info} status
+ Should Be Equal ${status} ACTIVE
+ [Return] ${server_info}
+
+ Get Active Server
+ [Arguments] ${alias} ${server_id}
+ ${resp}= Get Openstack Server By Id ${alias} ${server_id}
+ Should Be Equal As Strings ${resp.status_code} 200
+ ${server_info}= Set Variable ${resp.json()}
+ ${server_info}= Get From Dictionary ${server_info} server
+ ${status}= Get From Dictionary ${server_info} status
+ Should Not Be Equal ${status} BUILD
+ [Return] ${server_info}
+
+Wait for Server to Be Deleted
+ [Arguments] ${alias} ${server_id}
+ Wait Until Keyword Succeeds 300s 10s Get Deleted Server ${alias} ${server_id}
+
+Get Deleted Server
+ [Arguments] ${alias} ${server_id}
+ ${resp}= Get Openstack Server By Id ${alias} ${server_id}
+ Should Be Equal As Strings ${resp.status_code} 404
+
+Delete Server
+ [Documentation] Runs an Openstack Request to delete a keypair
+ [Arguments] ${alias} ${server_id}
+ ${resp}= Internal Delete Openstack ${alias} ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE} ${GLOBAL_OPENSTACK_SERVICE_REGION} ${OPENSTACK_NOVA_SERVERS_PATH} /${server_id}
+ ${status_string}= Convert To String ${resp.status_code}
+ Should Match Regexp ${status_string} ^(204)$
+ [Return] ${resp.text}
+
+Get Id For Name
+ [Arguments] ${list} ${name}
+ :for ${item} in @{list}
+ \ ${id}= Get From Dictionary ${item} id
+ \ ${n}= Get From Dictionary ${item} name
+ \ Return from Keyword If '${n}' == '${name}' ${id}
+ [Return] None
diff --git a/robot/resources/openstack/openstack_common.robot b/robot/resources/openstack/openstack_common.robot
new file mode 100644
index 00000000..6a53ab63
--- /dev/null
+++ b/robot/resources/openstack/openstack_common.robot
@@ -0,0 +1,50 @@
+*** Settings ***
+Documentation The private interface for interacting with Openstack. It handles low level stuff like managing the authtoken and Openstack required fields
+
+Library OpenstackLibrary
+Library RequestsLibrary
+Library UUID
+Resource ../global_properties.robot
+
+*** Keywords ***
+Internal Get Openstack
+ [Documentation] Runs an Openstack Get Request and returns the response
+ [Arguments] ${alias} ${service_type} ${region} ${url_ext} ${data_path}=
+ Log Internal Get Openstack values alias=${alias} service_type=${service_type} region=${region} url_ext=${url_ext} data_path=${data_path}
+ ${url}= Get Openstack Service Url ${alias} ${service_type} ${region}
+ ${uuid}= Generate UUID
+ ${session_alias}= Catenate openstack-${uuid}
+ ${session}= Create Session ${session_alias} ${url}${url_ext} verify=True
+ ${token}= Get Openstack Token ${alias}
+ ${headers}= Create Dictionary Accept=application/json Content-Type=application/json X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid} X-FromAppId=${GLOBAL_APPLICATION_ID} X-Auth-Token=${token}
+ ${resp}= Get Request ${session_alias} ${data_path} headers=${headers}
+ Log Received response from openstack ${resp.text}
+ [Return] ${resp}
+
+Internal Post Openstack
+ [Documentation] Runs an Openstack Post Response and returns the response
+ [Arguments] ${alias} ${service_type} ${region} ${url_ext} ${data_path}= ${data}=
+ Log Internal Post Openstack values alias=${alias} service_type=${service_type} region=${region} url_ext=${url_ext} data_path=${data_path}
+ ${url}= Get Openstack Service Url ${alias} ${service_type} ${region}
+ ${uuid}= Generate UUID
+ ${session_alias}= Catenate openstack-${uuid}
+ ${session}= Create Session ${session_alias} ${url}${url_ext} verify=True
+ ${token}= Get Openstack Token ${alias}
+ ${headers}= Create Dictionary Accept=application/json Content-Type=application/json X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid} X-FromAppId=${GLOBAL_APPLICATION_ID} X-Auth-Token=${token}
+ ${resp}= Post Request ${session_alias} ${data_path} data=${data} headers=${headers}
+ Log Received response from openstack ${resp.text}
+ [Return] ${resp}
+
+Internal Delete Openstack
+ [Documentation] Runs an Openstack Delete Request and returns the response
+ [Arguments] ${alias} ${service_type} ${region} ${url_ext} ${data_path}=
+ Log Internal Post Openstack values alias=${alias} service_type=${service_type} region=${region} url_ext=${url_ext} data_path=${data_path}
+ ${url}= Get Openstack Service Url ${alias} ${service_type} ${region}
+ ${uuid}= Generate UUID
+ ${session_alias}= Catenate openstack-${uuid}
+ ${session}= Create Session ${session_alias} ${url}${url_ext} verify=True
+ ${token}= Get Openstack Token ${alias}
+ ${headers}= Create Dictionary Accept=application/json Content-Type=application/json X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid} X-FromAppId=${GLOBAL_APPLICATION_ID} X-Auth-Token=${token}
+ ${resp}= Delete Request ${session_alias} ${data_path} headers=${headers}
+ Log Received response from openstack ${resp.text}
+ [Return] ${resp} \ No newline at end of file