Oracle Cloud Infrastructure Ruby SDK
Version 2.0.9
This topic describes how to install, configure, and use the Oracle Cloud Infrastructure Ruby SDK.
SDK Overview
The Ruby SDK supports the following services:
- Audit
- Core Services (which includes Networking Service, Compute Service, and Block Volume Service)
- Database Service
- Identity and Access Management Service
- Load Balancing Service
- Object Storage Service
- Domain Name System Service
- File Storage Service
- Email Service
Licensing: This SDK and sample is dual licensed under the Universal Permissive License 1.0 and the Apache License.
SDK Attributes
The following table provides details about some of the attributes of the SDK.
Requests | API methods expose required parameters as arguments and optional arguments as a hash (opts = {}). Create and update operations take request objects that mirror the properties of those objects. |
Responses | All API methods return a Response object, which contains an HTTP status (200, 204, etc), headers, and data, and also directly exposes some commonly used response headers such as opc-next_page , and opc-request_id . |
Models | Get, update, and create operations return first class objects of the corresponding type (such as User, Instance, etc) in Response.data. |
Errors | Unsuccessful requests will always raise an exception. ServiceError is raised when the service returns an error, and NetworkError is raised for network issues (such as failed host resolution). |
Signing | Requests made through the API classes are automatically signed, but you can also use the Signer directly to sign your own requests if needed. |
Automatic Paging | Response objects for lists support page enumeration. See example code later in this file. |
Waiters | Responses for get requests support waiting for a particular states using wait_until. See example code later in this file. |
HTTP Client | The Ruby SDK uses Net::HTTP for HTTP requests, if needed, options may be passed to each Net::HTTP by specifying them in ApiClient.request_option_overrides. Please check http://ruby-doc.org/stdlib-2.4.1/libdoc/net/http/rdoc/Net/HTTP.html#method-c-start for the supported options. |
Instance Principals Authentication | The Ruby SDK supports Instance Principals authentication via the use of the OCI::Auth::Signers::InstancePrincipalsSecurityTokenSigner class. An example of using Instance Principals authentication can be found in the examples folder of the Ruby SDK download |
Upload Manager |
The Object Storage service supports multipart uploads to make large object uploads easier by splitting the large object into parts. The Ruby SDK supports raw multipart upload operations for advanced use cases, as well as a higher-level upload class that uses the multipart upload APIs.
Managing Multipart Uploads provides links to the APIs used for raw multipart upload operations. Higher-level uploads can be performed using the OCI::ObjectStorage::Transfer::UploadManager. The UploadManager simplifies interaction with the Object Storage service by abstracting away the method used to upload objects and can handle uploading an entire object at once, or in multiple parts if it is of sufficient size (which is configurable via a OCI::ObjectStorage::Transfer::UploadManagerConfig object). In the latter case, the UploadManager will split a large object into parts for you, upload the parts in parallel, and then recombine and commit the parts as a single object in Object Storage. Examples of using the Upload Manager can be found in the examples folder of the Ruby SDK download |
SDK Requirements
To use the Ruby SDK, you must have:
- An Oracle Cloud Infrastructure account.
- A user created in that account, in a group with a policy that grants the desired permissions. This can be a user for yourself, or another person/system that needs to call the API. For an example of how to set up a new user, group, compartment, and policy, see Adding Users in the Getting Started Guide. For a list of typical policies you may want to use, see Common Policies in the User Guide.
- A keypair used for signing API requests, with the public key uploaded to Oracle. Only the user calling the API should be in possession of the private key. See the configuration information below.
- Ruby version 2.2 or later running on Mac, Linux or Windows.
Downloading and Installing the Gem File
Installing the SDK
Install from RubyGems:
gem install oci
You can also download the SDK as a zip file containing the gem file, examples, and documentation.
Install the gem with the following command:
gem install oci-*.gem
Troubleshooting an Installation
If you see "Unable to resolve dependencies”, you can install the dependencies manually:
gem install inifile
SDK modules and namespacing
The top level module name for the Ruby SDK is OCI
, however using OracleBMC
as the top level namespace is also supported. For example, you can reference the configuration object as both OCI::Config
and OracleBMC::Config
.
Using OCI
as the top level module name is preferred and it is also used in the SDK API Reference. Additionally, if you inspect the type of an SDK object it will always be reported as being under the OCI::
module.
Configuring the SDK
To use any of the APIs, you must supply a Config object. You can create the object directly in code, or you can create one in a config file. The configuration includes:
- Required credentials and settings: See SDK and Tool Configuration in the User Guide.
- Optional SDK-specific settings: See the Config object for the full list of config options.
Forward Compatibility
Some response fields are enum-typed. In the future, individual services may return values not covered by existing enums for that field. To address this possibility, every enum-type response field has an additional value named "UNKNOWN_ENUM_VALUE". If a service returns a value that is not recognized by your version of the SDK, then the response field will be set to this value. Please ensure that your code handles the "UNKNOWN_ENUM_VALUE" case if you have conditional logic based on an enum-typed field.
Writing Your First Ruby Program with the SDK
require 'oci'
# This will load the config file at the default location, and will
# use the tenancy from that config as the compartment in the
# call to list_users.
api = OCI::Identity::IdentityClient.new(region: OCI::Regions::REGION_US_PHOENIX_1)
response = api.list_users(OCI.config.tenancy)
response.data.each { |user| puts user.name }
Loading Alternate Configurations
You can also load a config file from a different location, and/or specify a different profile from the config file:
require 'oci'
my_config = OCI::ConfigFileLoader.load_config(config_file_location:'my_config', profile_name:'USER_TWO')
api = OCI::Identity::IdentityClient.new(config:my_config)
response = api.get_user(my_config.user)
puts 'User Name: ' + response.data.name
Or you can create a Config programmatically. Note that the global value OCI.config will always attempt to load the DEFAULT profile from the default config file location unless it has been explicitly set to another value.
The default config file location is ~/.oci/config
(on Windows C:\Users\{user}\.oci\config
).
Service Errors
Any operation resulting in a service error will cause an exception of type OCI::Errors::ServiceError to be thrown by the SDK. For information about common service errors returned by OCI, see API Errors.
Examples
The example code in this section shows how various parts of the Ruby SDK work. More examples can be found in the SDK download.
Management Operations on a User
The following example runs create, read, update, and delete (CRUD) operations on users.
require 'oci'
compartment = OCI.config.tenancy
api = OCI::Identity::IdentityClient.new
users = api.list_users(compartment_id = compartment).data
puts "There are currently " + users.length.to_s + " users."
# Create User
request = OCI::Identity::Models::CreateUserDetails.new
request.compartment_id = compartment
request.name = "userA"
request.description = "example user"
response = api.create_user(request)
puts "Created user " + response.data.name
user_id = response.data.id
users = api.list_users(compartment_id = compartment).data
puts "There are now " + users.length.to_s + " users."
# Get User
response = api.get_user(user_id = user_id)
# Update User (using a request object)
newDescription = "updated user description"
request = OCI::Identity::Models::UpdateUserDetails.new
request.description = "Updated description"
response = api.update_user(user_id, request)
puts "Updated description to:" + response.data.description
# Update User (using a hash)
newDescription = "updated without a request object"
response = api.update_user(user_id, { description: "Updated again, but using a hash instead of an object." })
# Delete User
api.delete_user(user_id)
users = api.list_users(compartment_id = compartment).data
puts "Back to " + users.length.to_s + " users."
Paging Through Results
The following example shows how to page through results. It also gives an example of supplying optional parameters.
require 'oci'
api = OCI::Identity::IdentityClient.new
compartment = OCI.config.tenancy
### Automatic paging:
api.list_users(compartment, limit:'3').each { |r| r.data.each { |user| puts user.name }}
### Manual paging:
request_number = 0
next_page = nil
loop do
response = api.list_users(compartment, {limit: '3', page: next_page})
puts "Page " + request_number.to_s
response.data.each { |user| puts user.name }
break unless response.has_next_page?
next_page = response.next_page
request_number += 1
end
Launching an Instance and Waiting for a State
The following example shows how to launch an instance (which assumes that you already have a subnet created), and then wait until the instance is running.
require 'oci'
ssh_public_key = File.open(File.(public_key_file), "rb").read
request = OCI::Core::Models::LaunchInstanceDetails.new
request.availability_domain = availability_domain # TODO: Set an availability domain, such as 'kIdk:PHX-AD-2'
request.compartment_id = compartment_id # TODO: set your compartment ID here
request.display_name = 'my_instance'
request.image_id = image_id # TODO: set your image ID here. You can see the available options with list_images.
request.shape = shape # TODO: set your instance shape. You can see the available options with list_shapes.
request.subnet_id = subnet_id # TODO: set your subnet ID here
request. = {'ssh_authorized_keys' => ssh_public_key}
api = OCI::Core::ComputeClient.new
response = api.launch_instance(request)
instance_id = response.data.id
response = api.get_instance(instance_id).wait_until(:lifecycle_state, OCI::Core::Models::Instance::LIFECYCLE_STATE_RUNNING)
Waiting for state using a proc/lambda
Instead of waiting until the attribute of a resource reaches a given state, the wait_until
method can also be passed a proc/lambda via its eval_proc
keyword argument.
Using eval_proc
may be useful in situations where logic other than checking if an attribute has a certain value is needed, for example checking
that an attribute is one of a possible set of values. eval_proc
should take a single argument, which is the raw response received from the service call, and its result
should be a truthy value if the waiter should stop waiting, and it should be falsey otherwise. If the eval_proc
is provided, then neither the property
nor state
parameters should be provided.
An example using a lambda is:
require 'oci'
request = OCI::Core::Models::CreateVcnDetails.new
request.cidr_block = '10.0.0.0/16'
request.display_name = 'my_test_vcn'
request.compartment_id = compartment_id # TODO: set your compartment ID here
api = OCI::Core::VirtualNetworkClient.new
response = api.create_vcn(request)
vcn_id = response.data.id
response = api.get_vcn(vcn.id).wait_until(eval_proc: lambda { |response| response.data.lifecycle_state == OCI::Core::Models::Vcn::LIFECYCLE_STATE_AVAILABLE })
An example using a proc is:
require 'oci'
request = OCI::Core::Models::CreateVcnDetails.new
request.cidr_block = '10.0.0.0/16'
request.display_name = 'my_test_vcn'
request.compartment_id = compartment_id # TODO: set your compartment ID here
api = OCI::Core::VirtualNetworkClient.new
response = api.create_vcn(request)
vcn_id = response.data.id
check_available_proc = Proc.new do |response|
[OCI::Core::Models::Vcn::LIFECYCLE_STATE_AVAILABLE].include?(response.data.lifecycle_state)
end
response = api.get_vcn(vcn.id).wait_until(eval_proc: check_available_proc)
Waiting on terminated/deleted resources
When waiting for a request to be terminated/deleted, there is a chance that doing a GET of that resource will return a 404 because the resource is no longer available. Instead of having to catch this, for example:
require 'oci'
api = OCI::Core::VirtualNetworkClient.new
api.delete_vcn(vcn.id)
begin
api.get_vcn(vcn.id).wait_until(:lifecycle_state, OCI::Core::Models::Vcn::LIFECYCLE_STATE_TERMINATED)
rescue OCI::Errors::ServiceError => e
raise unless e.status_code == 404
end
You can instruct the waiter to take care of this for you and consider that a 404 means success. For example:
require 'oci'
api = OCI::Core::VirtualNetworkClient.new
api.delete_vcn(vcn.id)
api.get_vcn(vcn.id).wait_until(:lifecycle_state, OCI::Core::Models::Vcn::LIFECYCLE_STATE_TERMINATED, succeed_on_not_found: true)
Using the succeed_on_not_found
keyword argument is likely only useful when waiting on temrinated/deleted resources.
Signing a Raw Request
The OCI::Signer can be used to sign arbitrary requests to the Oracle Cloud Infrastructure Services. The following example uses Net::HTTP to call the IAM service directly.
require 'oci'
require 'net/http'
config = OCI::ConfigFileLoader.load_config(config_file_location:my_config_file_location)
endpoint = OCI::Regions.get_service_endpoint(config.region, :IdentityClient)
uri = URI(endpoint + '/20160918/users/' + config.user)
request = Net::HTTP::Get.new(uri)
signer = OCI::Signer.new(config.user, config.fingerprint, config.tenancy, config.key_file, pass_phrase:my_private_key_pass_phrase)
signer.sign(:get, uri.to_s, request, nil)
result = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => true) {|http|
http.request(request)
}
puts result.body
Notifications
To be notified when a new version of the Ruby SDK is released, subscribe to the Atom feed.
Questions or Feedback?
Ways to get in touch:
- Stack Overflow: Please use the oracle-cloud-infrastructure and oci-ruby-sdk tags in your post
- Developer Tools section of the Oracle Cloud forums
- My Oracle Support