You are on page 1of 24

REST api

John Hardy
Product Manager
CloudForms Management BU!

Agenda!

Welcome!

About RESTapi!

Lab Setup!

Inventory!

Requests!

Provisioning !

Reference Material

http://manageiq.org/documentation/development/rest_api/reference/!
!

Technical Syntax
RestAPI Standard Syntax, All REST is URI based and the construct will always be Actions and
Resources.!
!
Get Return resource from a webservice.!
!
/api/services Returns the services.!
/api/hosts Returns the hosts.!
!
Put Change data in an existing resource.!
!
/api/services/1!
{!
"name" : "service_1",!
"description" : "This is an updated description for the first service"!
}!
!
Post Send a new resource to the webservice.!
!
/api/services/1!
{!
"action" : "edit",!
"resource" : {!
"name" : "service_1",!
"description" : "This is an updated description for the first service"!
}!
}!

Technical Syntax
!
Delete Delete a resource from a webservice.!
!
/api/services/<id> - Will remove the service from the system.!
!
Patch Change data in an existing resource.!
!
Supported attribute actions include, add, edit and remove.!
!
/api/services/1!
!
[!
{ "action" : "edit", "path" : "name", "value" : "service_001" },!
{ "action" : "remove", "path" : "description"}!
]!

Lab Setup
We will all share the same CloudForms appliance sitting within Amazon EC2.!
!
The CloudForms public IP address is x.x.x.x!
!
Login Details are!
!
Username = admin!
Password = smartvm!
!
You do not need to logon interactively to the appliance, we will do everything via RESTapi.!
!
You will need the ability to run RESTapi actions. I use RUBY scripting language to demonstrate,
however you can use anything that supports RESTapi, here are some others ways;!
!
CURL!
Python!
SOAPui!
Chrome (Postman plugin)!
!

SSL Problem
When running an example, depending on your OS configuration you might have SSL Cert Verification
errors as follows.!
require 'rest-client'!
require 'json'!
!
#get the inital set of VMS, but using filters for TAG and expanding the resources!
result = RestClient.get 'https://admin:smartvm@<CFME>/api/vms?expand=resources'!
items = JSON.parse(result)!
!

RUBY

#Process each vm in the returned hash of VMS!


items['resources'].each do |vm|!
puts "Processing VM #{vm['name']} --> vmID = #{vm['id']}"!
puts " flavor_id --> #{vm['flavor_id']}"!
puts " availability_zone_id --> #{vm['availability_zone_id']}"!
end!
!

v3 read server certificate B: certificate verify failed (RestClient::SSLCertificateNotVerified)!


from /usr/local/share/gems/gems/rest-client-1.7.2/lib/restclient/request.rb:350:in `transmit'!
from /usr/local/share/gems/gems/rest-client-1.7.2/lib/restclient/request.rb:176:in `execute'!
from /usr/local/share/gems/gems/rest-client-1.7.2/lib/restclient/request.rb:41:in `execute'!
from /usr/local/share/gems/gems/rest-client-1.7.2/lib/restclient.rb:65:in `get'!
from tets.rb:5:in `<main>'!

The presentation assumes you have an understanding of


SSL Certs, I will give you a NON-Production use
workaround. Sort your SSL Certs out properly!!

SSL Solution
Add to the top of each script!
!

require 'openssl'!
!
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE!
!
Example below!
require 'rest-client'!
require 'json!
!
#Hack to disable SSL verification!
require 'openssl
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
!

RUBY

#get the inital set of VMS, but using filters for TAG and expanding the resources!
result = RestClient.get 'https://admin:smartvm@<CFME>/api/vms?expand=resources'!
items = JSON.parse(result)!
!
#Process each vm in the returned hash of VMS!
items['resources'].each do |vm|!
puts "Processing VM #{vm['name']} --> vmID = #{vm['id']}"!
puts " flavor_id --> #{vm['flavor_id']}"!
puts " availability_zone_id --> #{vm['availability_zone_id']}"!
end!
!
WARNING: OpenSSL::SSL::VERIFY_PEER == OpenSSL::SSL::VERIFY_NONE!
This dangerous monkey patch leaves you open to MITM attacks!!
Try passing :verify_ssl => false instead.!
Processing VM Tester1 --> vmID = https://<CFME>/api/vms/1000000000157!
WARNING: OpenSSL::SSL::VERIFY_PEER == OpenSSL::SSL::VERIFY_NONE!
This dangerous monkey patch leaves you open to MITM attacks!!
Try passing :verify_ssl => false instead.!
---Processing TAG /managed/jonnyfive/not_here2!
---Processing TAG /managed/jonnyfive/is_here!
---Processing TAG /managed/function/database!

Querying Report a VMs Hardware


Using the RESTapi call into CloudForms and retrieve the flavor_id and availability_zone_id
configuration of the VM container. !
(if on Virtual Infrastructure the flavor_id and availability_zone_id can be replaced with
number_of_sockets and vm_memory)!

require 'rest-client'!
require 'json'!
!
#get the inital set of VMS, but using filters for TAG and expanding the resources!
result = RestClient.get 'https://admin:smartvm@<CFME>/api/vms?expand=resources'!
items = JSON.parse(result)!
!

RUBY

#Process each vm in the returned hash of VMS!


items['resources'].each do |vm|!
puts "Processing VM #{vm['name']} --> vmID = #{vm['id']}"!
puts " flavor_id --> #{vm['flavor_id']}"!
puts " availability_zone_id --> #{vm['availability_zone_id']}"!
end!
!

Processing VM First --> vmID = https://<CFME>/api/vms/1000000000156!


flavor_id --> 1000000000044!
availability_zone_id --> 1000000000007!
Processing VM Tester1 --> vmID = https://<CFME>/api/vms/1000000000157!
flavor_id --> 1000000000044!
availability_zone_id --> 1000000000007!

Repeat CURL - Querying Report a VMs


Hardware
I have repeated the previous slide, but using CURL in case you prefer to use something other
than RUBY. !
You can GREP the results you want from the return.!
You can also specify a query option of attributes=var1,var2 that can return only the attributes
you wish for, in this example that would be flavor_id and availability_zone_id, note that this
would need to be done against the actual VM resource not the collection.!

CURL

curl -k -u admin:smartvm -H "Content-Type: application/json" -X GET https://<CFME>/api/vms?expand=resources!

{"name":"vms","count":4,"subcount":4,"resources":[{"id":"https://<CFME>/api/vms/1000000000156","vendor":"amazon","name":"First","location":"ec2-54-65-22-200.apnortheast-1.compute.amazonaws.com","created_on":"2014-11-29T12:37:05Z","updated_on":"2014-11-29T12:37:05Z","guid":"6d0db864-77c4-11e4-95e9-0acdf3aaf2e8",
"ems_id":
1000000000002,"uid_ems":"i-0e3e61fc","power_state":"on","state_changed_on":"2014-11-29T12:37:05Z","template":false,"vdi":false,"type":"VmAmazon","ems_ref":"i-0e3e6
1fc","flavor_id":1000000000044,"availability_zone_id":1000000000007,"cloud":true,"cloud_network_id":1000000000003,"cloud_subnet_id":
1000000000004,"raw_power_state":"running"},{"id":"https://<CFME>/api/vms/1000000000157","vendor":"amazon","name":"Tester1","location":"ec2-54-65-67-1.apnortheast-1.compute.amazonaws.com","created_on":"2014-11-29T14:37:31Z","updated_on":"2014-11-29T14:37:31Z","guid":"401cc17c-77d5-11e4a11e-0acdf3aaf2e8","ems_id":1000000000002,"uid_ems":"ia1154b53","power_state":"on","state_changed_on":"2014-11-29T14:37:31Z","template":false,"vdi":false,"type":"VmAmazon","ems_ref":"i-a1154b53","flavor_id":
1000000000044,"availability_zone_id":1000000000007,"cloud":true,"cloud_network_id":1000000000003,"cloud_subnet_id":
1000000000004,"raw_power_state":"running"},{"id":"https://<CFME>/api/vms/1000000000158","vendor":"amazon","name":"restAPI","location":"ec2-54-65-147-172.apnortheast-1.compute.amazonaws.com","created_on":"2014-12-01T06:46:02Z","updated_on":"2014-12-01T06:46:10Z","guid":"b748cccc-7925-11e4a431-0acdf3aaf2e8","ems_id":
1000000000002,"uid_ems":"i-07df52f4","power_state":"on","state_changed_on":"2014-12-01T06:46:02Z","template":false,"vdi":false,"type":"VmAmazon","ems_ref":"i-07df5
2f4","flavor_id":1000000000062,"availability_zone_id":1000000000005,"cloud":true,"cloud_network_id":1000000000003,"cloud_subnet_id":
1000000000003,"raw_power_state":"running"},{"id":"https://<CFME>/api/vms/1000000000159","vendor":"amazon","name":"ProvTest","location":"ec2-54-65-141-103.apnortheast-1.compute.amazonaws.com","created_on":"2014-12-01T06:56:45Z","updated_on":"2014-12-01T06:56:55Z","guid":"36cde79c-7927-11e4a431-0acdf3aaf2e8","ems_id":
1000000000002,"uid_ems":"i-9c643d6e","power_state":"on","state_changed_on":"2014-12-01T06:56:45Z","template":false,"vdi":false,"type":"VmAmazon","ems_ref":"i-9c64
3d6e","flavor_id":1000000000062,"availability_zone_id":1000000000007,"cloud":true,"cloud_network_id":1000000000003,"cloud_subnet_id":
1000000000004,"raw_power_state":"running"}]}!

Querying Find a VM by Tag


Using the RESTapi call into CloudForms and retrieve a VM(s) based upon a tag !

Find the vm(s) that are tagged with the following!


!
Category = Function!
Tag = Database!
require 'rest-client'!
require 'json'!
!

#get the inital set of VMS, but using filters for TAG and expanding the resources!
result = RestClient.get 'https://admin:smartvm@<CFME>/api/vms?expand=resources&by_tag=/function/database'!
items = JSON.parse(result)!
!

#Process each vm in the returned hash of VMS!


items['resources'].each do |vm|!
puts "Processing VM #{vm['name']} --> vmID = #{vm['id']}"!
!

#quick hack to insert authentication, should use token oAuth for multiple transactions!
id = vm['id'].gsub("https://", "https://admin:smartvm@")!

RUBY
!

#Now fetch the tags for this VM!


tags = RestClient.get "#{id}/tags?expand=resources"!
items = JSON.parse(tags)!
!

#Now process each tag on the vm!


items['resources'].each do |tag|!
puts " ---Processing TAG #{tag['name']}"!
end!
end!
!

Processing VM Tester1 --> vmID = https://<CFME>/api/vms/1000000000157!


---Processing TAG /managed/function/database!

Note
The next task will be to call an AUTOMATION_REQUEST to
create a category & tag. !
!
This is a demonstration of how you can call *ANYTHING* within
CloudForms externally.!
!
It should be noted that at time of print, native TAGGING and
CATEGORY actions are NOT available in the RESTapi.!
!
When they do become available, then the actions for
CATEGORY and TAG management should be used for their
purposes.!
!

Request Create a NEW Category/Tag


Using the RESTapi call into CloudForms and execute a method that will create a new Category
and Tag from parameters you pass to an automation request.!

URI = /System/Request/createTAG!
Parameters :!
Category Your NAME!
Tag - Something!
require 'rest-client'!
require 'json'!
!

RUBY

puts RestClient.post 'https://admin:smartvm@<CFME>/api/automation_requests',!


{:version => "1.1",!
:uri_parts => [{!
:namespace => "System",!
:class => "Request",!
:instance => "createTAG",!
:message => "create"!
}],!
:parameters => [{!
:category => "jonnyfive",!
:tag => "is_here"!
}],!
}.to_json!

{"results":[{"approval_state":"pending_approval","created_on":"2014-12-01T05:41:19Z","description":"Automation Task","destination_id":null,"destination_type":null,"fulfilled_on":null,"id":
1000000000069,"message":null,"options":{"namespace":"SYSTEM","class_name":"PROCESS","instance_name":"AUTOMATION_REQUEST","user_id":1000000000001,"attrs":
{"userid":"admin"},"uri_parts_keeps":[{"namespace":"System","class":"Request","instance":"createTAG","message":"create"}],"parameters_keeps":
[{"category":"jonnyfive","tag":"is_here"}]},"request_state":"pending","request_type":"automation","requester_id":
1000000000001,"requester_name":"Administrator","source_id":null,"source_type":null,"status":"Ok","updated_on":"2014-12-01T05:41:19Z","userid":"admin"}]}!

Request Tag the VM


Using the RESTapi call into CloudForms and execute a method that will tag the VM, passing the
VM identifier, Category and Tag to the automation request. !

URI = /System/Request/createTAG!
Parameters :!
Category Your NAME!
Tag - Something!
require 'rest-client'!
require 'json'!
!

RUBY

puts RestClient.post 'https://admin:smartvm@<CFME>/api/automation_requests',!


{:version => "1.1",!
:uri_parts => [{!
:namespace => "System",!
:class => "Request",!
:instance => tagOBJ,!
:message => "create"!
}],!
:parameters => [{!
:category => "jonnyfive",!
:tag => "is_here!
:vmid => <VM ID>!
}],!
}.to_json!

{"results":[{"approval_state":"pending_approval","created_on":"2014-12-01T06:15:47Z","description":"Automation Task","destination_id":null,"destination_type":null,"fulfilled_on":null,"id":
1000000000080,"message":null,"options":{"namespace":"SYSTEM","class_name":"PROCESS","instance_name":"AUTOMATION_REQUEST","user_id":1000000000001,"attrs":
{"userid":"admin"},"uri_parts_keeps":[{"namespace":"System","class":"Request","instance":"tagOBJ","message":"create"}],"parameters_keeps":
[{"vmid":"1000000000157","category":"jonnyfive","tag":"not_here2"}]},"request_state":"pending","request_type":"automation","requester_id":
1000000000001,"requester_name":"Administrator","source_id":null,"source_type":null,"status":"Ok","updated_on":"2014-12-01T06:15:47Z","userid":"admin"}]}!

Query Return the VM Tags


Using the RESTapi call into CloudForms query the VM to see the new tag applied.!

require 'rest-client'!
require 'json'!
!
id = "https://admin:smartvm@<CFME>/api/vms/1000000000157"!
!

RUBY

#Now fetch the tags for this VM!


tags = RestClient.get "#{id}/tags?expand=resources"!
items = JSON.parse(tags)!
!
#Now process each tag on the vm!
items['resources'].each do |tag|!
puts " ---Processing TAG #{tag['name']}!
end!

---Processing TAG /managed/jonnyfive/not_here2!


---Processing TAG /managed/jonnyfive/is_here!
---Processing TAG /managed/function/database!

Querying Provision a New VM


Using the RESTapi call into CloudForms and provision a new VM!

The parameters passed depend on the provider. Here is a AMAZON


EC2 example. !
IMPORTANT - The parameters are dictated by the provisioning dialog
that will be used in the provisioning profile.!
require 'rest-client'!
require 'json'!
!

RUBY

puts RestClient.post 'https://admin:smartvm@<CFME>/api/provision_requests',!


{:version => "1.1",!
:template_fields => { :guid => "728ba4b0-76fa-11e4-a1d0-0acdf3aaf2e8" },!
:vm_fields => {!
:placement_availability_zone => "1000000000005",!
:security_groups => "1000000000015",!
:cloud_subnet => "1000000000003",!
:instance_type => "1000000000062",!
:guest_access_key_pair => "1000000000007",!
:vm_name => "ProvTest"!
!

},!
:requester => {!
:user_name => "admin",!
:owner_first_name => "John",!
:owner_last_name => "Hardy",!
:owner_email => "jhardy@redhat.com",!
:auto_approve => "true"!
}!
}.to_json!

{"results":[{"approval_state":"pending_approval","created_on":"2014-12-01T06:55:34Z","description":"Provision from [_QA] to [ProvTest]","destination_id":null,"destination_type":null,"fulfilled_on":null,"id":1000000000084,"message":"VM Provisioning - Request Created","options":


{"use_pre_dialog":false,"request_type":"template","miq_request_dialog_name":"miq_provision_amazon_dialogs_template","customize_enabled":
["disabled"],"owner_phone":null,"owner_country":null,"owner_phone_mobile":null,"owner_title":null,"owner_first_name":"John","owner_manager":null,"owner_address":null,"owner_company":null,"owner_last_name":"Hardy","owner_manager_mail":null,"owner_city":null,"owner_de
partment":null,"owner_load_ldap":null,"owner_manager_phone":null,"owner_state":null,"owner_office":null,"owner_zip":null,"owner_email":"jhardy@redhat.com","request_notes":null,"vm_tags":[],"placement_auto":[true,1],"placement_availability_zone":[null,null],"cloud_network":
[0,null],"cloud_subnet":[null,null],"security_groups":[null,null],"floating_ip_address":[0,null],"number_of_vms":[1,"1"],"vm_description":null,"vm_prefix":null,"src_vm_id":[1000000000051,"_QA"],"vm_name":"ProvTest","schedule_type":["immediately","Immediately on
Approval"],"schedule_time":"2014-12-02T01:55:34-05:00","retirement":[0,"Indefinite"],"retirement_warn":[604800,"1 Week"],"instance_type":1000000000062,"guest_access_key_pair":1000000000007,"monitoring":
["basic","Basic"],"dns_servers":null,"dns_suffixes":null,"addr_mode":["dhcp","DHCP"],"linux_host_name":null,"gateway":null,"linux_domain_name":null,"subnet_mask":null,"customization_template_script":null,"root_password":null,"hostname":null,"src_vm_nics":[],"src_vm_lans":
[],"src_ems_id":[1000000000002,"Tokyo"],"auto_approve":true,"ws_values":{},"ws_ems_custom_attributes":{},"ws_miq_custom_attributes":{},"delivered_on":null},"request_state":"pending","request_type":"template","requester_id":
1000000000001,"requester_name":"Administrator","source_id":1000000000051,"source_type":"template","status":"Ok","updated_on":"2014-12-01T06:55:35Z","userid":"admin"}]}!

Querying Status Check


Using the RESTapi call into CloudForms and query the status of the provisioning request.!

The output request ID from the provisioning request can be used to


query back to CloudForms the status of the job. !

require 'rest-client'!
require 'json'!
!
id = "https://admin:smartvm@<CFME>/api/provision_requests/1000000000083"!
!

RUBY

#Now fetch the tags for this VM!


request = RestClient.get "#{id}?expand=resources"!
item = JSON.parse(request)!
!
puts "Description --> #{item['description']}"!
puts "Approval State --> #{item['approval_state']}"!
puts "Created On
--> #{item['created_on']}"!
puts "State
--> #{item['request_state']}"!
puts "Message
--> #{item['message']}"!
puts "Status
--> #{item['status']}"!

Description --> Provision from [_TEST] to [restAPI]!


Approval State --> approved!
Created On
--> 2014-12-01T06:44:44Z!
State
--> finished!
Message
--> Vm Provisioned Successfully!
Status
--> Ok!

You might also like