mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
[hp] Add documentation and examples for the provider for HP Cloud Services.
This commit is contained in:
parent
302cc7293e
commit
750ec6d852
13 changed files with 3635 additions and 61 deletions
57
lib/fog/hp/README.md
Executable file
57
lib/fog/hp/README.md
Executable file
|
@ -0,0 +1,57 @@
|
|||
# Getting Started with HP Cloud Extensions to Ruby Fog Bindings
|
||||
|
||||
[HP Cloud](http://www.hpcloud.com) has been creating and contributing bindings so
|
||||
that developers can work with Ruby Fog and the HP Cloud services based on
|
||||
[OpenStack](http://www.openstack.org/). By using the HP Cloud Extensions to Fog,
|
||||
developers can write applications using Ruby that interacts with the
|
||||
HP Cloud Services without having to deal with the underlying REST API or
|
||||
JSON/XML document formats. We have officially turned these bindings over to the
|
||||
Ruby Fog community where you can contribute and develop additional functionality
|
||||
around these bindings.
|
||||
|
||||
This section of documentation provides information, examples and articles for working with the different HP Cloud services such as Compute, Object Storage and others.
|
||||
|
||||
Please note that HP Cloud recently released version 13.5 which updates and adds functionality provided by OpenStack Havana. Some of our HP Ruby Fog examples are developed to work with earlier versions so please take note which HP Cloud version you are working with.
|
||||
|
||||
**Note:** The Networking service examples only work with version 13.5.
|
||||
|
||||
## Installation
|
||||
|
||||
To install and use HP Cloud Ruby bindings for Fog, please install the [latest release](http://fog.io/) of Fog.
|
||||
|
||||
Then follow the installation instructions for the operating system you are using and connect to the service:
|
||||
|
||||
* [Installation Instructions](https://github.com/fog/fog/blob/master/lib/fog/hp/docs/install.md)
|
||||
* [Connecting to the Service](https://github.com/fog/fog/blob/master/lib/fog/hp/docs/connect.md)
|
||||
|
||||
## Requirements
|
||||
|
||||
For working with the HP Cloud Extension to Fog, the following pre-requisites are needed:
|
||||
|
||||
* HP Cloud Services account. If you have not already signed up, please [sign up for your free trial](http://www.hpcloud.com/free-trial).
|
||||
* Ruby version 1.8.x or 1.9.x
|
||||
* `fog` gem
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
Apart from the overall [Fog documentation](http://fog.io), we have HP Cloud specific examples that will help you in using the Ruby Fog bindings with HP Cloud services.
|
||||
|
||||
[Examples for using Fog with HP Cloud Services](https://github.com/fog/fog/blob/master/lib/fog/hp/examples/getting_started_examples.md)
|
||||
|
||||
## Articles
|
||||
|
||||
In addition to the examples we have provided, for Compute, Object Storage, and other HP Cloud services, we wanted to give you a few additional tips and "how-tos' to make using your Ruby Fog bindings even easier. Take a look at the articles listed below to find out more!
|
||||
|
||||
* [Using authentication caching](https://github.com/fog/fog/blob/master/lib/fog/hp/articles/auth_caching.md)
|
||||
|
||||
## Additional Resources
|
||||
* [Fog cloud library](http://fog.io)
|
||||
* [Fog documentation](http://rubydoc.info/gems/fog)
|
||||
* [Fog Github repo](https://github.com/fog/fog)
|
||||
* [Fog Release Notes](https://github.com/fog/fog/blob/master/changelog.txt)
|
||||
|
||||
## Support and Feedback
|
||||
|
||||
Your feedback is essential to the maturity of the bindings and is highly appreciated! If you have specific issues with the HP Cloud Extensions to Fog bindings, please file an [issue via Github](https://github.com/fog/fog/issues).
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
= HP Cloud Extensions to Ruby Fog Library
|
||||
|
||||
HP contributed to the native Ruby library Fog, through an HP Cloud developed extension to Fog via
|
||||
the Object Storage, Compute and CDN providers. By using the HP Cloud Extensions to Fog, developers
|
||||
can write applications using Ruby that interacts with the HP Cloud Services without having to deal
|
||||
with the underlying REST API or JSON/XML document formats.
|
||||
|
||||
== Background
|
||||
|
||||
This library is an extension of Fog[https://github.com/fog/fog], a Ruby open-source cloud
|
||||
computing library. The code in this library, contains all HP-specific support and is being
|
||||
contributed back to the primary open-source library.
|
||||
|
||||
The HP Cloud Ruby library currently supports HP Cloud Object Storage, Compute, CDN, and
|
||||
support for other services will be added as available.
|
||||
|
||||
== Installation
|
||||
|
||||
sudo gem install fog
|
||||
|
||||
That's it! Try out the usage examples explained below to confirm your installation.
|
||||
|
||||
If you should ever need to remove the library:
|
||||
|
||||
sudo gem uninstall fog
|
||||
|
||||
== Usage
|
||||
|
||||
The Ruby Fog library is well documented on the community web site at {fog.io}[http://fog.io], but for specific examples
|
||||
using HP's extensions, see:
|
||||
|
||||
* {HP Cloud Fog library - Object Storage Examples}[https://docs.hpcloud.com/bindings/fog/object-storage]
|
||||
* {HP Cloud Fog library - Compute Examples}[https://docs.hpcloud.com/bindings/fog/compute]
|
||||
* {HP Cloud Fog library - CDN Examples}[https://docs.hpcloud.com/bindings/fog/cdn]
|
||||
* {HP Cloud Fog library - Block Storage Examples}[https://docs.hpcloud.com/bindings/fog/block-storage]
|
||||
|
||||
Having trouble? Get help over at the {Forums}[https://community.hpcloud.com/forum] or
|
||||
at the {Knowledge Base}[https://community.hpcloud.com/knowledge-base] areas.
|
||||
|
||||
|
||||
== Notice
|
||||
|
||||
The following notice applies to files included in the /lib/fog/hp directory and its sub-directories.
|
||||
|
||||
Copyright (c) 2011 Hewlett-Packard Development Company, L.P.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
23
lib/fog/hp/articles/auth_caching.md
Executable file
23
lib/fog/hp/articles/auth_caching.md
Executable file
|
@ -0,0 +1,23 @@
|
|||
#Using Authentication Caching for HP Cloud Services#
|
||||
|
||||
Your application can run up to 40% faster if you cache the authentication information. The authentication token is typically valid for a day or more and if you save it in a safe place, you can reuse it. If you pass the authentication information to Fog, it does not have to reauthenticate.
|
||||
|
||||
For example if you save your credentials:
|
||||
|
||||
@storage = Fog::Storage.new(options)
|
||||
@credentials = @storage.credentials
|
||||
|
||||
The next time you go to create a storage connection, pass in the credentials:
|
||||
|
||||
options[:credentials] = @credentials
|
||||
@storage = Fog::Storage.new(options)
|
||||
@credentials = @storage.credentials
|
||||
|
||||
It is best to always update your cached credentials. If they expire, they are automatically updated. When you create the new connection with the credentials, you should still pass in your normal authentication information in the options.
|
||||
|
||||
The contents of the credentials should be treated like a set of data. The contents of this object are likely to change in the future.
|
||||
|
||||
The same credentials may be used to create connections for Compute, Object Storage, CDN, Block Storage, and other services.
|
||||
|
||||
---------
|
||||
[Documentation Home]((https://github.com/fog/fog/blob/master/lib/fog/hp/README.md) | [Examples](https://github.com/fog/fog/blob/master/lib/fog/hp/examples/getting_started_examples.md)
|
152
lib/fog/hp/docs/connect.md
Executable file
152
lib/fog/hp/docs/connect.md
Executable file
|
@ -0,0 +1,152 @@
|
|||
# Connecting to HP Cloud Services using Ruby Fog Bindings
|
||||
|
||||
The HP Cloud uses OpenStack as the platform and you can connect and set up your HP Cloud using Ruby Fog. To begin, connect using the following instructions:
|
||||
|
||||
* [Initial Connection](#initial-connection)
|
||||
* [Availability Zones](#availability-zones)
|
||||
* [Optional Parameters](#optional-parameters)
|
||||
|
||||
## Initial Connection
|
||||
|
||||
To connect to the HP Cloud, follow these steps:
|
||||
|
||||
1. Enter IRB
|
||||
|
||||
irb
|
||||
|
||||
2. Require the Fog library and Rubygems:
|
||||
|
||||
require 'rubygems'
|
||||
require 'fog'
|
||||
|
||||
**Note**: If the `require 'rubygems'` command returns a value of `false`, enter IRB with the following command:
|
||||
|
||||
irb -r 'rubygems'
|
||||
|
||||
3. Establish a connection to the desired HP Cloud service
|
||||
|
||||
conn = Fog::<SERVICE-NAME>.new(
|
||||
:provider => "HP",
|
||||
:hp_access_key => "<your_ACCESS_KEY>",
|
||||
:hp_secret_key => "<your_SECRET_KEY>",
|
||||
:hp_auth_uri => "<IDENTITY_ENDPOINT_URL>",
|
||||
:hp_tenant_id => "<your_TENANT_ID>",
|
||||
:hp_avl_zone => "<your_AVAILABILITY_ZONE>",
|
||||
<other optional parameters>
|
||||
)
|
||||
|
||||
Where `SERVICE-NAME` can be [Compute](https://github.com/fog/fog/blob/master/lib/fog/hp/docs/compute.md), [Storage](https://github.com/fog/fog/blob/master/lib/fog/hp/docs/object_storage.md), [CDN](https://github.com/fog/fog/blob/master/lib/fog/hp/docs/cdn.md) or other services. Please surf on over to the [Block Storage](https://github.com/fog/fog/blob/master/lib/fog/hp/docs/block-storage.md) for the details on how to connect to that service.
|
||||
|
||||
**Note**: You must use the `:hp_access_key` parameter rather than the now-deprecated `:hp_account_id` parameter you might have used in previous versions of the HP Cloud Services Extensions to Ruby Fog.
|
||||
|
||||
You can find the values the access key, secret key, and other values by clicking the [`API Keys`](https://console.hpcloud.com/account/api_keys) button in the [Console Dashboard](https://console.hpcloud.com/dashboard).
|
||||
|
||||
|
||||
## Availability Zones
|
||||
|
||||
You cannot specify an availability zone if you have not activated it. To activate an availability zone, go to the [Management Console dashboard](https://console.hpcloud.com/) and click the `**Activate`** button. You are required to set an availability zone to establish a connection; there is no default availability zone value.
|
||||
|
||||
The current usable availability zones for the compute service:
|
||||
|
||||
* `az-1.region-a.geo-1`
|
||||
* `az-2.region-a.geo-1`
|
||||
* `az-3.region-a.geo-1`
|
||||
|
||||
The current usable availability zones for the storage service:
|
||||
|
||||
* `region-a.geo-1`
|
||||
* `region-b.geo-1`
|
||||
|
||||
The current usable availability zones for the CDN:
|
||||
|
||||
* `region-a.geo-1`
|
||||
* `region-b.geo-1`
|
||||
|
||||
The current usable availability zones for the block storage service:
|
||||
|
||||
* `az-1.region-a.geo-1`
|
||||
* `az-2.region-a.geo-1`
|
||||
* `az-3.region-a.geo-1`
|
||||
|
||||
## Optional Parameters
|
||||
|
||||
This section describes the optional parameters that you can use when connecting to any of the HP Cloud services. The examples below show the Compute service, but these optional parameters work with all of the HP Cloud services.
|
||||
|
||||
The `user_agent` parameter allows you to specify a string to pass as a `user_agent` header for the connection. You can use this to track the caller of the operations. You can set the `user_agent` parameter as follows:
|
||||
|
||||
conn = Fog::Compute.new(
|
||||
...
|
||||
...
|
||||
:user_agent => "MyApp/x.x.x")
|
||||
|
||||
This inserts a `user_agent` string such as `hpfog/x.x.x (MyApp/x.x.x)` into the header.
|
||||
|
||||
In addition to the `user_agent` parameter, there are several additional parameters you can set using the `connection_options` parameter. These options are provided by the Excon library and allow you to modify the underlying connection to a service. These options are [Instrumentation](#Instrumentation), [Timeouts](#Timeouts), [Proxy](#Proxy), and [HTTPS/SSL](#HTTPS).
|
||||
|
||||
### Instrumentation
|
||||
|
||||
Use this parameter for debugging purposes. When you use the default instrumentor `Excon::StandardInstrumentor`, all events are output to `stderr`. You can also designate your own instrumentor. You can set the default instrumentor as follows:
|
||||
|
||||
conn = Fog::Compute.new(
|
||||
...
|
||||
...
|
||||
:connection_options => {:instrumentor => Excon::StandardInstrumentor})
|
||||
|
||||
For convenience of debugging HTTP requests, we have created a custom instrumentor `Excon::SimpleHttpInstrumentor`. This instrumentor shows the HTTP calls in afashion which is similar to a `curl` output. You can set the custom `SimpleHttpInstrumentor` as follows:
|
||||
|
||||
conn = Fog::Compute.new(
|
||||
...
|
||||
...
|
||||
:connection_options => {:instrumentor => Excon::SimpleHttpInstrumentor, :instrumentor_name => 'SimpleHttp'})
|
||||
|
||||
### Timeouts
|
||||
|
||||
Use this parameter to set different timeout values. You can set the timeouts parameter as follows:
|
||||
|
||||
conn = Fog::Compute.new(
|
||||
...
|
||||
...
|
||||
:connection_options => {
|
||||
:connect_timeout => <time_in_secs>,
|
||||
:read_timeout => <time_in_secs>,
|
||||
:write_timeout => <time_in_secs>})
|
||||
|
||||
### Proxy
|
||||
|
||||
Use this parameter to specify a proxy URL for both HTTP and HTTPS connections. You can set the proxy parameter as follows:
|
||||
|
||||
conn = Fog::Compute.new(
|
||||
...
|
||||
...
|
||||
:connection_options => {:proxy => 'http://myproxyurl:4444'})
|
||||
|
||||
### HTTPS/SSL
|
||||
|
||||
By default, peer certificates are verified when you use secure socket layer (SSL) for HTTPS. Sometimes this does not work due to configurations in different operating systems, causing connection errors. To help avoid this, you can set HTTPS/SSL parameters. To set the path to the certificates:
|
||||
|
||||
conn = Fog::Compute.new(
|
||||
...
|
||||
...
|
||||
:connection_options => {:ssl_ca_path => "/path/to/certs"})
|
||||
|
||||
To set the path to a certificate file:
|
||||
|
||||
conn = Fog::Compute.new(
|
||||
...
|
||||
...
|
||||
:connection_options => {:ssl_ca_file => "/path/to/certificate_file"})
|
||||
|
||||
To set turn off peer verification:
|
||||
|
||||
conn = Fog::Compute.new(
|
||||
...
|
||||
...
|
||||
:connection_options => {:ssl_verify_peer => false})
|
||||
|
||||
**Note**: This makes your connection less secure.
|
||||
|
||||
For further information on these options, please see [the Excon documentation](http://github.com/geemus/excon).
|
||||
|
||||
|
||||
---------
|
||||
[Documentation Home](https://github.com/fog/fog/blob/master/lib/fog/hp/README.md) | [Examples](https://github.com/fog/fog/blob/master/lib/fog/hp/examples/getting_started_examples.md)
|
133
lib/fog/hp/docs/install.md
Executable file
133
lib/fog/hp/docs/install.md
Executable file
|
@ -0,0 +1,133 @@
|
|||
# Installing Ruby Fog Bindings for HP Cloud Services
|
||||
|
||||
Before you can begin working with the Ruby Fog bindings, you have to install them (of course!). This page provides you with the installation information for the following operating systems:
|
||||
|
||||
* [Ubuntu Installation](#ubuntu-installation)
|
||||
* [Mac OSX Installation](#mac-osx-installation)
|
||||
* [CentOS Installation](#centos-installation)
|
||||
* [Uninstalling](#uninstalling)
|
||||
|
||||
To install and use HP Cloud Ruby bindings for Fog, please install the [latest release](http://fog.io) of Fog.
|
||||
|
||||
|
||||
## Ubuntu Installation
|
||||
|
||||
If you plan on using the Ruby Fog binding on Ubuntu, we recommend you use Ubuntu versions 12.04 or 12.10. The Ruby Fog bindings may work on other versions, but are not supported.
|
||||
|
||||
To install the Ruby Fog bindings on the Ubuntu operating system, follow these steps while logged in as the root user:
|
||||
|
||||
1. Install Ruby and Ruby-dev:
|
||||
|
||||
apt-get install ruby1.8 ruby-dev
|
||||
|
||||
2. Install RubyGems:
|
||||
|
||||
apt-get install rubygems
|
||||
|
||||
3. Install the dependent libraries:
|
||||
|
||||
apt-get install libxml2 libxml2-dev libxslt1-dev libxslt1.1 sgml-base xml-core
|
||||
|
||||
4. Install the RDoc Ruby source documenation generator package:
|
||||
|
||||
gem install rdoc
|
||||
|
||||
5. Install the Fog gem:
|
||||
|
||||
gem install fog
|
||||
|
||||
|
||||
See the [Connecting to the Service](https://github.com/fog/fog/blob/master/lib/fog/hp/docs/connect.md) page for details on how to connect.
|
||||
|
||||
## MacOS X Installation
|
||||
|
||||
Some Ruby packages require C/C++ compiler support. On the MacOS, if you haven't already installed XCode, we recommend that you install it to provide the needed C/C++ compiler for your system.
|
||||
|
||||
To install the Ruby Fog bindings on MacOS X, follow these steps while logged in as the root user:
|
||||
|
||||
1. Download and install Xcode. You can [download the most recent version of XCode through the Mac App Store](https://itunes.apple.com/us/app/xcode/id497799835?ls=1&mt=12). If you want to install an earlier version of Xcode, go to the [Apple Developer](https://developer.apple.com/downloads/index.action) site and search for "Xcode". In the results list, select the version of Xcode that you want and install it. (Note that you need to be signed up as an "Apple Developer" to access the download. Sign-up is free.)
|
||||
|
||||
2. To make your installation process easier we recommend that you install [Homebrew](http://wiki.github.com/mxcl/homebrew/installation). Follow the instructions on the Homebrew page to install the package. After you have downloaded Homebrew, the CLI command to install it is:
|
||||
|
||||
homebrew install - ruby -e "$(curl -fsSkL raw.github.com/mxcl/homebrew/go)"
|
||||
|
||||
3. Add the Homebrew path to your $PATH environment variable. You can either do this via the CLI command line:
|
||||
|
||||
export PATH=:/usr/local/sbin:$PATH
|
||||
|
||||
(The default Homebrew installation location is the `/usr/local/sbin` directory.) Or you can add the Homebrew path (`/usr/local/sbin`) to your $PATH environment variable in your local `.profile` file.
|
||||
|
||||
4. Install RVM on your system:
|
||||
|
||||
curl -L get.rvm.io | bash -s stable
|
||||
|
||||
**Note**: You can also install RVM using [Jewelry Box](https://unfiniti.com/software/mac/jewelrybox), a RVM graphical user interface (GUI) for Mac OSX.
|
||||
|
||||
5. Install the packages required by RVM; the following command lists the required packages:
|
||||
|
||||
source ~/.rvm/scripts/rvm
|
||||
rvm requirements # install required packages
|
||||
|
||||
6. Install the required packages listed in Step 5:
|
||||
|
||||
brew install <packages>
|
||||
|
||||
Where `<packages>` are the packages that you need to install.
|
||||
|
||||
7. Install the `libksba` library:
|
||||
|
||||
brew install libksba
|
||||
|
||||
8. Install Ruby:
|
||||
|
||||
rvm user all
|
||||
rvm install ruby-1.9.2 --with-gcc=clang
|
||||
|
||||
9. Use the Ruby version and make it the default:
|
||||
|
||||
rvm use 1.9.2 --default
|
||||
|
||||
10. Install the Fog gem:
|
||||
|
||||
gem install fog
|
||||
|
||||
|
||||
See the [Connecting to the Service](https://github.com/fog/fog/blob/master/lib/fog/hp/docs/connect.md) page for details on how to connect.
|
||||
|
||||
## CentOS Installation
|
||||
|
||||
If you plan on using the Ruby Fog binding on CentOS, we recommend you use CentOS versions 6.2 or 6.3. The Ruby Fog bindings may work on other versions, but are not supported.
|
||||
|
||||
To install the Ruby Fog bindings on CentOS, follow these steps while logged in as the root user:
|
||||
|
||||
1. Install Ruby and Ruby Dev:
|
||||
|
||||
yum install -y ruby ruby-devel
|
||||
|
||||
2. Install Rubygems:
|
||||
|
||||
yum install -y rubygems
|
||||
|
||||
3. Install the dependent libraries:
|
||||
|
||||
yum install -y gcc make libxml2 libxml2-devel libxslt libxslt-devel
|
||||
|
||||
4. Install RDoc Ruby source documentation generator package:
|
||||
|
||||
gem install rdoc
|
||||
|
||||
5. Install the Fog gem:
|
||||
|
||||
gem install fog
|
||||
|
||||
|
||||
See the [Connecting to the Service](https://github.com/fog/fog/blob/master/lib/fog/hp/docs/connect.md) page for details on how to connect.
|
||||
|
||||
## Uninstalling
|
||||
|
||||
Its recommended that you uninstall a previous version prior to upgrading. To uninstall, execute the followin command while logged in as the root user:
|
||||
|
||||
gem uninstall fog
|
||||
|
||||
---------
|
||||
[Documentation Home]((https://github.com/fog/fog/blob/master/lib/fog/hp/README.md) | [Examples](https://github.com/fog/fog/blob/master/lib/fog/hp/examples/getting_started_examples.md)
|
296
lib/fog/hp/examples/block_storage.md
Executable file
296
lib/fog/hp/examples/block_storage.md
Executable file
|
@ -0,0 +1,296 @@
|
|||
#Examples for working with HP Cloud Block Storage Service v12.12
|
||||
|
||||
HP Cloud block storage provides support for volumes and snapshots. A volume can store boot images, user data or both. They provide customers with persistent and flexible permanent storage. You can think of it as list of USB devices, that can be plugged in anywhere at will. Volumes can be attached to server instances and mounted.
|
||||
|
||||
Snapshots are saved volume images at specific moments in time. You can take a snapshot of a volume and then use that snapshot to create a new volume.
|
||||
|
||||
The block storage provider has two abstractions: a model layer and a request layer. Both layers are detailed below. The following code snippets can be executed from within a Ruby console (IRB):
|
||||
|
||||
irb
|
||||
|
||||
This page discusses the following tasks:
|
||||
|
||||
* [Connecting to the Service](#connecting-to-the-service)
|
||||
|
||||
**Model Layer Examples**
|
||||
|
||||
* [Model Volume Operations](#model-volume-operations)
|
||||
* [Model Snapshot Operations](#model-snapshot-operations)
|
||||
|
||||
**Request Layer Examples**
|
||||
|
||||
* [Request Volume Operations](#request-volume-operations)
|
||||
* [Request Snapshot Operations](#request-snapshot-operations)
|
||||
|
||||
## Connecting to the Service
|
||||
|
||||
To connect to the HP Cloud Block Storage Service, follow these steps:
|
||||
|
||||
1. Enter IRB
|
||||
|
||||
irb
|
||||
|
||||
2. Require the Fog library
|
||||
|
||||
require 'fog'
|
||||
|
||||
3. Establish a connection to the HP Cloud BlockStorage service
|
||||
|
||||
conn = Fog::HP::BlockStorage.new(
|
||||
:hp_access_key => "<your_ACCESS_KEY>",
|
||||
:hp_secret_key => "<your_SECRET_KEY>",
|
||||
:hp_auth_uri => "<IDENTITY_ENDPOINT_URL>",
|
||||
:hp_tenant_id => "<your_TENANT_ID>",
|
||||
:hp_avl_zone => "<your_AVAILABILITY_ZONE>",
|
||||
<other optional parameters>
|
||||
)
|
||||
|
||||
**Note**: You must use the `:hp_access_key` parameter rather than the now-deprecated `:hp_account_id` parameter you might have used in previous Ruby Fog versions.
|
||||
|
||||
You can find the values the access key, secret key, and other values by clicking the [`API Keys`](https://console.hpcloud.com/account/api_keys) button in the [Console Dashboard](https://console.hpcloud.com/dashboard).
|
||||
|
||||
## Model Volume Operations
|
||||
|
||||
This section discusses the volume operations you can perform using the model abstraction.
|
||||
|
||||
1. List all available volumes for an account
|
||||
|
||||
volumes = conn.volumes
|
||||
volumes.size # returns no. of volumes
|
||||
# display volumes in a tabular format
|
||||
volumes.table([:id, :name, :status, :created_at])
|
||||
|
||||
2. Obtain the details of a particular volume
|
||||
|
||||
volume = conn.volumes.get(volume_id)
|
||||
volume.name # returns name of the volume
|
||||
volume.created_at # returns the date the volume was created
|
||||
volume.status # returns the state of the volume e.g. available, in-use
|
||||
|
||||
3. List all available bootable volumes for an account
|
||||
|
||||
bootable_volumes = conn.bootable_volumes
|
||||
bootable_volumes.size # returns no. of bootable volumes
|
||||
# display bootable volumes in a tabular format
|
||||
bootable_volumes.table([:id, :name, :state, :created_at])
|
||||
|
||||
4. Obtain the details of a particular bootable volume
|
||||
|
||||
volume = conn.bootable_volumes.get(volume_id)
|
||||
volume.name # returns name of the bootable volume
|
||||
volume.created_at # returns the date the bootable volume was created
|
||||
volume.status # returns the state of the bootable volume e.g. available, in-use
|
||||
|
||||
5. Create a new volume
|
||||
|
||||
new_volume = conn.volumes.create(
|
||||
:name => "TestVolume",
|
||||
:description => "My Test Volume",
|
||||
:size => 1)
|
||||
new_volume.id # returns the id of the volume
|
||||
new_volume.name # => "TestVolume"
|
||||
new_volume.status # returns the status of the volume e.g. creating, available
|
||||
|
||||
6. Create a new volume from an existing snapshot
|
||||
|
||||
new_volume = conn.volumes.create(
|
||||
:name => "TestVolume",
|
||||
:description => "My Test Volume",
|
||||
:snapshot_id => 1,
|
||||
:size => 1)
|
||||
new_volume.id # returns the id of the volume
|
||||
new_volume.snapshot_id # returns the snapshot_id of the volume
|
||||
new_volume.name # => "TestVolume"
|
||||
new_volume.status # returns the status of the volume e.g. creating, available
|
||||
**Note**: The size of the volume you create from a snapshot is the same as that of the snapshot. The `:size` parameter has no effect in this case.
|
||||
|
||||
7. Create a new bootable volume from an suitable single-part image
|
||||
|
||||
new_volume = conn.bootable_volumes.create(
|
||||
:name => "BootVolume",
|
||||
:description => "My Boot Volume",
|
||||
:image_id => 11111,
|
||||
:size => 10)
|
||||
new_volume.id # returns the id of the volume
|
||||
**Note**: You can use a bootable volume to create a persistent server instance.
|
||||
|
||||
8. Attach an existing volume to an existing server
|
||||
|
||||
volume = conn.volumes.get(volume_id)
|
||||
volume.attach(server_id, device)
|
||||
# => true
|
||||
**Note**: The device parameter is the mount point on the server instance to which the volume is attached (for example, `/dev/sdf`).
|
||||
|
||||
9. Detach an existing volume
|
||||
|
||||
volume = conn.volumes.get(volume_id)
|
||||
volume.detach
|
||||
# => true
|
||||
|
||||
10. Delete an existing volume
|
||||
|
||||
volume = conn.volumes.get(volume_id)
|
||||
volume.destroy
|
||||
# => true
|
||||
|
||||
## Model Snapshot Operations
|
||||
|
||||
This section discusses the snapshot operations you can perform using the model abstraction.
|
||||
|
||||
1. List all available snapshots for an account
|
||||
|
||||
snapshots = conn.snapshots
|
||||
snapshots.size # returns no. of snapshots
|
||||
# display snapshots in a tabular format
|
||||
conn.snapshots.table([:id, :name, :state, :created_at])
|
||||
|
||||
2. Obtain the details of a particular snapshot
|
||||
|
||||
snapshot = conn.snapshots.get(snapshot_id)
|
||||
snapshot.name # returns name of the volume
|
||||
snapshot.created_at # returns the date the volume was created
|
||||
snapshot.status # returns the state of the volume e.g. available
|
||||
|
||||
3. Create a new snapshot
|
||||
|
||||
new_snapshot = conn.snapshots.create(
|
||||
:name => "TestVolume",
|
||||
:description => "My Test Volume",
|
||||
:volume_id => 1)
|
||||
new_snapshot.id # returns the id of the volume
|
||||
new_snapshot.name # => "TestVolume"
|
||||
new_snapshot.volume_id # => 1
|
||||
new_snapshot.status # returns the status of the volume e.g. creating, available
|
||||
|
||||
4. Delete an existing snapshot
|
||||
|
||||
snapshot = conn.snapshots.get(snapshot_id)
|
||||
snapshot.destroy
|
||||
# => true
|
||||
|
||||
## Request Volume Operations
|
||||
|
||||
This section discusses the volume operations you can perform using the request abstraction.
|
||||
|
||||
1. List all available volumes for an account
|
||||
|
||||
response = conn.list_volumes
|
||||
response.body['volumes'] # returns an array of volume hashes
|
||||
response.headers # returns the headers
|
||||
response.body['volumes'][0]['displayName'] # returns the name of the volume
|
||||
|
||||
2. Obtain the details of a particular volume
|
||||
|
||||
response = conn.get_volume_details(volume_id)
|
||||
volume = response.body['volume']
|
||||
volume['displayName'] # returns the name of the volume
|
||||
volume['size'] # returns the size of the volume
|
||||
volume['status'] # returns the status of the volume e.g. available, in-use
|
||||
|
||||
3. List all available bootable volumes for an account
|
||||
|
||||
response = conn.list_bootable_volumes
|
||||
response.body['volumes'] # returns an array of bootable volume hashes
|
||||
response.headers # returns the headers
|
||||
response.body['volumes'][0]['displayName'] # returns the name of the bootable volume
|
||||
|
||||
4. Obtain the details of a particular bootable volume
|
||||
|
||||
response = conn.get_bootable_volume_details(volume_id)
|
||||
volume = response.body['volume']
|
||||
volume['displayName'] # returns the name of the bootable volume
|
||||
volume['size'] # returns the size of the bootable volume
|
||||
volume['status'] # returns the status of the bootable volume e.g. available, in-use
|
||||
|
||||
5. Create a new volume
|
||||
|
||||
response = conn.create_volume("demo-vol", "demo-vol-desc", 1)
|
||||
volume = response.body['volume']
|
||||
volume['id'] # returns the id of the new volume
|
||||
volume['displayName'] # => "demo-vol"
|
||||
volume['size'] # => 1
|
||||
volume['status'] # returns the status of the volume e.g. creating, available
|
||||
|
||||
6. Create a new volume from an existing snapshot
|
||||
|
||||
response = conn.create_volume("demo-vol", "demo-vol-desc", 1, {'snapshot_id' => 1})
|
||||
volume = response.body['volume']
|
||||
volume['id'] # returns the id of the new volume
|
||||
volume['displayName'] # => "demo-vol"
|
||||
volume['size'] # => 1
|
||||
volume['snapshot_id'] # => 1
|
||||
volume['status'] # returns the status of the volume e.g. creating, available
|
||||
**Note**: The size of the volume you create from a snapshot is the same as that of the snapshot. The third parameter (the size) has no effect in this case.
|
||||
|
||||
7. Create a new bootable volume from an suitable single-part image
|
||||
|
||||
new_volume = conn.create_volume("TestBootVol",
|
||||
"My Test Boot Volume",
|
||||
10,
|
||||
{"imageRef" => "1111111"}
|
||||
)
|
||||
new_volume.id # returns the id of the volume
|
||||
**Note**: You can use a bootable volume to create a persistent server instance.
|
||||
|
||||
8. Attach an existing volume to an existing server
|
||||
|
||||
response = conn.compute.attach_volume(server_id, volume_id, device)
|
||||
volume_attachment = response.body['volumeAttachment']
|
||||
volume_attachment['id'] # returns the id of the volume
|
||||
volume_attachment['volumeId'] # returns the id of the volume
|
||||
**Note**: The device parameter is the mount point on the server instance to which the volume is attached (for example, `/dev/sdf`)
|
||||
|
||||
9. List volumes attached to a server
|
||||
|
||||
response = conn.compute.list_server_volumes(server_id)
|
||||
volume_attachments = response.body['volumeAttachments']
|
||||
volume_attachment[0]['id'] # returns the id of the volume
|
||||
volume_attachment[0]['volumeId'] # returns the id of the volume
|
||||
volume_attachment[0]['device'] # returns the device of the volume
|
||||
|
||||
10. Detach an existing volume
|
||||
|
||||
conn.detach_volume(server_id, volume_id)
|
||||
|
||||
11. Delete an existing volume
|
||||
|
||||
conn.delete_volume(volume_id)
|
||||
|
||||
## Request Snapshot Operations
|
||||
|
||||
This section discusses the snapshot operations you can perform using the request abstraction.
|
||||
|
||||
1. List all available snapshots for an account
|
||||
|
||||
response = conn.list_snapshots
|
||||
response.body['snapshots'] # returns an array of snapshot hashes
|
||||
response.headers # returns the headers
|
||||
response.body['snapshots'][0]['displayName'] # returns the name of the snapshot
|
||||
response.body['snapshots'][0]['size'] # returns the size of the snapshot
|
||||
response.body['snapshots'][0]['volumeId'] # returns the volume id of the snapshot
|
||||
|
||||
2. Obtain the details of a particular snapshot
|
||||
|
||||
response = conn.get_snapshot_details(snapshot_id)
|
||||
snapshot = response.body['snapshot']
|
||||
snapshot['displayName'] # returns the name of the snapshot
|
||||
snapshot['size'] # returns the size of the snapshot
|
||||
snapshot['volumeId'] # returns the volume id of the snapshot
|
||||
snapshot['status'] # returns the status of the snapshot e.g. available, in-use
|
||||
|
||||
3. Create a new snapshot
|
||||
|
||||
response = conn.create_snapshot("demo-snap", "demo-snap-desc", 1)
|
||||
snapshot = response.body['snapshot']
|
||||
snapshot['id'] # returns the id of the new volume
|
||||
snapshot['displayName'] # => "demo-vol"
|
||||
snapshot['size'] # => 1
|
||||
snapshot['volumeId'] # returns the volume id of the snapshot
|
||||
snapshot['status'] # returns the status of the snapshot e.g. creating, available
|
||||
|
||||
4. Delete an existing snapshot
|
||||
|
||||
conn.delete_snapshot(snapshot_id)
|
||||
|
||||
---------
|
||||
[Documentation Home](https://github.com/fog/fog/blob/master/lib/fog/hp/README.md) | [Examples](https://github.com/fog/fog/blob/master/lib/fog/hp/examples/getting_started_examples.md)
|
446
lib/fog/hp/examples/block_storage_v2.md
Executable file
446
lib/fog/hp/examples/block_storage_v2.md
Executable file
|
@ -0,0 +1,446 @@
|
|||
#Examples for working with HP Cloud Block Storage Service v13.5
|
||||
|
||||
HP Cloud block storage provides support for volumes and snapshots. The latest HP Cloud deployment, version 13.5, takes advantage of more OpenStack functionality and the block storage service uses slightly different commands (often noted by *v2* in the commands) than the previous 12.12 version. Verify which version of HP Cloud you are working with.
|
||||
|
||||
A volume can store boot images, user data or both. They provide customers with persistent and flexible permanent storage. You can think of it as list of USB devices, that can be plugged in anywhere at will. Volumes can be attached to server instances and mounted.
|
||||
|
||||
Snapshots are saved volume images at specific moments in time. You can take a snapshot of a volume and then use that snapshot to create a new volume.
|
||||
|
||||
The block storage provider has two abstractions: [a model layer](#ModelLayer) and [a request layer](#RequestLayer). Both layers are detailed below. The following code snippets can be executed from within a Ruby console (IRB):
|
||||
|
||||
irb
|
||||
|
||||
This page discusses the following tasks:
|
||||
|
||||
* [Connecting to the Service](#connecting-to-the-service)
|
||||
|
||||
**Model Layer Examples**
|
||||
|
||||
* [Model Volume Operations](#model-volume-operations)
|
||||
* [Model Snapshot Operations](#model-snapshot-operations)
|
||||
* [Model Volume Backup Operations](#model-volume-backup-operations)
|
||||
|
||||
**Request Layer Examples**
|
||||
|
||||
* [Request Volume Operations](#request-volume-operations)
|
||||
* [Request Snapshot Operations](#request-snapshot-operations)
|
||||
* [Volume Operations (Request Layer)](#request-volume-backup-operations)
|
||||
|
||||
## Connecting to the Service
|
||||
|
||||
To connect to the HP Cloud Block Storage Service, follow these steps:
|
||||
|
||||
1. Enter IRB
|
||||
|
||||
irb
|
||||
|
||||
2. Require the Fog library
|
||||
|
||||
require 'fog'
|
||||
|
||||
3. Establish a connection to the HP Cloud Block Storage service
|
||||
|
||||
conn = Fog::HP::BlockStorageV2.new(
|
||||
:hp_access_key => "<your_ACCESS_KEY>",
|
||||
:hp_secret_key => "<your_SECRET_KEY>",
|
||||
:hp_auth_uri => "<IDENTITY_ENDPOINT_URL>",
|
||||
:hp_tenant_id => "<your_TENANT_ID>",
|
||||
:hp_avl_zone => "<your_AVAILABILITY_ZONE>",
|
||||
<other optional parameters>
|
||||
)
|
||||
|
||||
**Note**: You must use the `:hp_access_key` parameter rather than the now-deprecated `:hp_account_id` parameter you might have used in previous Ruby Fog versions.
|
||||
|
||||
You can find the values the access key, secret key, and other values by clicking the [`API Keys`](https://console.hpcloud.com/account/api_keys) button in the [Console Dashboard](https://console.hpcloud.com/dashboard).
|
||||
|
||||
## Model Volume Operations
|
||||
|
||||
This section discusses the volume operations you can perform using the model abstraction.
|
||||
|
||||
1. List all available volumes for an account:
|
||||
|
||||
volumes = conn.volumes
|
||||
volumes.size # returns no. of volumes
|
||||
# display volumes in a tabular format
|
||||
volumes.table([:id, :name, :status, :created_at])
|
||||
|
||||
2. Obtain the details of a volume by the volume ID:
|
||||
|
||||
volume = conn.volumes.get("<volume_id>")
|
||||
volume.name # returns name of the volume
|
||||
volume.created_at # returns the date the volume was created
|
||||
volume.status # returns the state of the volume e.g. available, in-use
|
||||
|
||||
3. List volume details using a filter:
|
||||
|
||||
volume = conn.volumes.all(:status => 'error')
|
||||
|
||||
4. Create a volume
|
||||
|
||||
new_volume = conn.volumes.create(
|
||||
:name => "TestVolume",
|
||||
:description => "My Test Volume",
|
||||
:size => 1)
|
||||
new_volume.id # returns the id of the volume
|
||||
new_volume.name # => "TestVolume"
|
||||
new_volume.status # returns the status of the volume e.g., creating, available
|
||||
|
||||
5. Create a new bootable volume from an suitable single-part image
|
||||
|
||||
new_volume = conn.volumes.create(
|
||||
:name => "BootVolume",
|
||||
:description => "My Boot Volume",
|
||||
:image_id => 11111,
|
||||
:size => 10)
|
||||
new_volume.id # returns the id of the volume
|
||||
**Note**: You can use a bootable volume to create a persistent server instance.
|
||||
**Note**: The size of the volume you create from an image is the same as that of the image. The `:size` parameter has no effect in this case.
|
||||
|
||||
6. Create a volume from a volume snapshot:
|
||||
|
||||
new_volume = conn.volumes.create(
|
||||
:name => 'VolumeFromSnapshot',
|
||||
:snapshot_id => "<snapshot_id>")
|
||||
**Note**: The size of the volume you create from a snapshot, is the same as that of the snapshot.
|
||||
|
||||
7. Create a volume from another source volume:
|
||||
|
||||
new_volume = conn.volumes.create(
|
||||
:name => 'VolumeClone',
|
||||
:source_volid => "<source_volid>")
|
||||
**Note**: The size of the volume you create from a source volume, is the same as that of the source volume.
|
||||
|
||||
8. Attach a volume to a server:
|
||||
|
||||
# assuming we have a server
|
||||
server.volume_attachments.create(
|
||||
:server_id => server.id,
|
||||
:volume_id => "<volume_id>",
|
||||
:device => "/dev/sdf")
|
||||
# => true
|
||||
**Note**: The device parameter is the mount point on the server instance to which the volume is attached (for example, `/dev/sdf`).
|
||||
|
||||
9. List the attached volumes for a server:
|
||||
|
||||
# assuming we have a server
|
||||
server.volume_attachments.all
|
||||
|
||||
10. Detach a volume from a server:
|
||||
|
||||
# assuming we have a server
|
||||
att_vol = server.volume_attachments.get("<volume_id>")
|
||||
att_vol.destroy
|
||||
# => true
|
||||
|
||||
11. Update a volume:
|
||||
|
||||
volume = conn.volumes.get("<volume_id>")
|
||||
vol.description = "from a source vol. in a diff. availability zone"
|
||||
=> "from a source vol. in a diff. availability zone"
|
||||
vol.save
|
||||
=> true
|
||||
|
||||
12. Delete a volume:
|
||||
|
||||
volume = conn.volumes.get("<volume_id>")
|
||||
volume.destroy
|
||||
# => true
|
||||
|
||||
## Model Snapshot Operations
|
||||
|
||||
This section discusses the snapshot operations you can perform using the model abstraction.
|
||||
|
||||
1. List all available snapshots for an account:
|
||||
|
||||
snapshot = conn.snapshots
|
||||
snapshots.size # returns no. of snapshots
|
||||
# display snapshots in a tabular format
|
||||
conn.snapshots.table([:id, :name, :state, :created_at])
|
||||
|
||||
2. List snapshots using a filter:
|
||||
|
||||
snapshot = conn.snapshots.all(:display_name => 'My Snapshot')
|
||||
snapshot.name # returns name of the snapshot
|
||||
snapshot.description # returns the description of the snapshot
|
||||
snapshot.created_at # returns the date the snapshot was created
|
||||
snapshot.status # returns the state of the snapshot e.g., available
|
||||
|
||||
3. Obtain the details of a snapshot by the ID:
|
||||
|
||||
snapshot = conn.snapshots.get("<snapshot_id>")
|
||||
snapshot.name # returns name of the volume
|
||||
snapshot.description # returns the description of the snapshot
|
||||
snapshot.status # returns the state of the snapshot e.g., available
|
||||
snapshot.created_at # returns the date the snapshot was created
|
||||
snapshot.volume_id # returns the volume ID
|
||||
|
||||
4. Create a snapshot:
|
||||
|
||||
snapshot = conn.snapshots.create(
|
||||
:volume_id => "<volume_id>",
|
||||
:name => "TestSnapshot",
|
||||
:description => "My Test Snapshot")
|
||||
|
||||
snapshot.id # returns the id of the volume
|
||||
snapshot.name # => "TestVolume"
|
||||
snapshot.description # returns the description of the snapshot
|
||||
snapshot.status # returns the status of the volume e.g., creating, available
|
||||
snapshot.created_at # returns the date the snapshot was created
|
||||
snapshot.volume_id # => 1
|
||||
|
||||
5. Update a snapshot
|
||||
|
||||
snapshot = conn.snapshots.get("<snapshot_id>")
|
||||
snapshot.name = "Snapshot 1"
|
||||
snapshot.save
|
||||
=> true
|
||||
|
||||
6. Delete an existing snapshot
|
||||
|
||||
conn.snapshots.get("<snapshot_id>").destroy
|
||||
=> true
|
||||
|
||||
## Model Volume Backup Operations
|
||||
|
||||
This section discusses the volume backup operations you can perform using the model abstraction.
|
||||
|
||||
1. List available volume backups for an account:
|
||||
|
||||
conn.volume_backups
|
||||
|
||||
2. List details of volume backups:
|
||||
|
||||
conn.volume_backups.all(:details => true)
|
||||
|
||||
3. Obtain the details of a volume backup by ID:
|
||||
|
||||
volume = conn.volume_backups.get("<volume_backup_id>")
|
||||
|
||||
volume.name # returns the name of the volume backup
|
||||
volume.status # provides the status of the volume backup e.g., available
|
||||
volume.created_at # provides the date the backup was created
|
||||
volume.volume_id # returns the id of the volume
|
||||
volume.container # returns the container holding the backup
|
||||
|
||||
4. Create a volume backup:
|
||||
|
||||
volume = conn.volume_backups.create(
|
||||
:name => "My Volume Backup",
|
||||
:volume_id => "<volume_id>")
|
||||
|
||||
5. Restore from a volume backup into a new volume:
|
||||
|
||||
# restore into a new volume
|
||||
backup = conn.volume_backups.get("<volume_backup_id>")
|
||||
backup.restore
|
||||
=> true
|
||||
|
||||
6. Restore from a volume backup into an existing volume:
|
||||
|
||||
# restore into an existing volume
|
||||
backup = conn.volume_backups.get("<volume_backup_id>")
|
||||
backup.restore("<existing_volume_id>")
|
||||
=> true
|
||||
|
||||
7. Delete a volume backup:
|
||||
|
||||
backup = conn.volume_backups.get("<volume_backup_id>")
|
||||
backup.destroy
|
||||
|
||||
## Request Volume Operations
|
||||
|
||||
This section discusses the volume operations you can perform using the request abstraction.
|
||||
|
||||
1. List all available volumes for an account:
|
||||
|
||||
response = conn.list_volumes
|
||||
response.body['volumes'] # returns an array of volume hashes
|
||||
response.headers # returns the headers
|
||||
response.body['volumes'][0]['display_name'] # returns the name of the volume
|
||||
|
||||
2. List available volumes using a filter:
|
||||
|
||||
conn.list_volumes(:limit => 2 )
|
||||
|
||||
3. List volumes with details:
|
||||
|
||||
response = conn.list_volumes_detail
|
||||
response.body['volumes'][0]['volume_image_metadata'] # returns volume image metadata
|
||||
|
||||
4. List volumes with details using a filter:
|
||||
|
||||
response = conn.list_volumes_detail(:display_name => "Test Volume")
|
||||
response.body['volumes'][0]['volume_image_metadata'] # returns volume image metadata
|
||||
|
||||
5. Obtain the details of a volume by ID:
|
||||
|
||||
response = conn.get_volume_details("<volume_id>")
|
||||
volume = response.body['volume']
|
||||
volume['display_name'] # returns the name of the volume
|
||||
volume['size'] # returns the size of the volume
|
||||
volume['status'] # returns the status of the volume e.g. available, in-use
|
||||
|
||||
6. Create a volume:
|
||||
|
||||
response = conn.create_volume('display_name' => 'Test Volume', 'size' => 10)
|
||||
volume = response.body['volume']
|
||||
volume['id'] # returns the id of the new volume
|
||||
volume['display_name'] # => "demo-vol"
|
||||
volume['size'] # => 10
|
||||
volume['status'] # returns the status of the volume e.g. creating, available
|
||||
|
||||
7. Create a new volume from an existing image:
|
||||
|
||||
conn.create_volume('display_name' => 'Test Volume 1',
|
||||
'display_description' => 'Test Volume from image',
|
||||
'size' => 10,
|
||||
'imageRef' => "<image_id>")
|
||||
|
||||
8. Create a new volume from an existing snapshot:
|
||||
|
||||
response = conn.create_volume(
|
||||
'display_name' => 'Test Volume 2',
|
||||
'display_description' => 'New Volume from Snapshot',
|
||||
'snapshot_id' => "<snapshot_id>")
|
||||
volume = response.body['volume']
|
||||
|
||||
volume['id'] # returns the id of the new volume
|
||||
volume['display_name'] # => "Test Volume 2"
|
||||
volume['size'] # => 1
|
||||
volume['snapshot_id'] # => 1
|
||||
volume['status'] # returns the status of the volume e.g. creating, available
|
||||
**Note**: The size of the volume you create from a snapshot is the same as that of the snapshot. The third parameter (the size) has no effect in this case.
|
||||
|
||||
9. Create a new volume from an existing volume:
|
||||
|
||||
conn.create_volume(
|
||||
'display_name' => 'Test Volume 3',
|
||||
'display_description' => 'Test volume from another image',
|
||||
'source_volid' => "<source_volid>")
|
||||
|
||||
10. Create a new bootable volume from an suitable single-part image:
|
||||
|
||||
conn.create_volume(
|
||||
'display_name' => "TestBootVol",
|
||||
'display_description' => "My Test Boot Volume",
|
||||
'size' => 10,
|
||||
'imageRef' => "<bootable_image_id>")
|
||||
**Note**: You can use a bootable volume to create a persistent server instance.
|
||||
|
||||
11. Attach an existing volume to an existing server:
|
||||
|
||||
response = conn.attach_volume("<server_id>", "<volume_id>", "/dev/sdf")
|
||||
volume_attachment = response.body['volumeAttachment']
|
||||
volume_attachment['id'] # returns the id of the volume
|
||||
volume_attachment['volumeId'] # returns the id of the volume
|
||||
volume_attachment['serverId'] # returns the id of the server
|
||||
volume_attachment['device'] # returns the device of the volume
|
||||
**Note**: The device parameter is the mount point on the server instance to which the volume is attached (for example, `/dev/sdf`)
|
||||
|
||||
12. List volumes attached to a server:
|
||||
|
||||
response = conn.list_server_volumes("<server_id>")
|
||||
volume_attachments = response.body['volumeAttachments']
|
||||
volume_attachment[0]['id'] # returns the id of the volume
|
||||
volume_attachment[0]['volumeId'] # returns the id of the volume
|
||||
volume_attachment[0]['serverId'] # returns the id of the volume
|
||||
volume_attachment[0]['device'] # returns the device of the volume
|
||||
|
||||
13. Detach an existing volume from a server:
|
||||
|
||||
conn.detach_volume("<server_id>", "<volume_id>")
|
||||
|
||||
14. Update a volume:
|
||||
|
||||
conn.update_volume("<volume_id>",
|
||||
{'display_name' => 'Test Volume Update'})
|
||||
|
||||
15. Delete an existing volume:
|
||||
|
||||
conn.delete_volume("<volume_id>")
|
||||
|
||||
## Request Snapshot Operations
|
||||
|
||||
This section discusses the snapshot operations you can perform using the request abstraction.
|
||||
|
||||
1. List all available snapshots for an account:
|
||||
|
||||
response = conn.list_snapshots
|
||||
response.body['snapshots'] # returns an array of snapshot hashes
|
||||
response.headers # returns the headers
|
||||
response.body['snapshots'][0]['display_name'] # returns the name of the snapshot
|
||||
response.body['snapshots'][0]['size'] # returns the size of the snapshot
|
||||
response.body['snapshots'][0]['volume_id'] # returns the volume id of the snapshot
|
||||
|
||||
2. List the details of all snapshots:
|
||||
|
||||
conn.list_snapshots_detail
|
||||
|
||||
3. List the details of a snapshot using a filter:
|
||||
|
||||
conn.list_snapshots_detail(:limit => 2)
|
||||
|
||||
4. Obtain the details of a snapshot by ID:
|
||||
|
||||
response = conn.get_snapshot_details("<snapshot_id>")
|
||||
snapshot = response.body['snapshot']
|
||||
snapshot['display_name'] # returns the name of the snapshot
|
||||
snapshot['size'] # returns the size of the snapshot
|
||||
snapshot['volume_id'] # returns the volume id of the snapshot
|
||||
snapshot['status'] # returns the status of the snapshot e.g. available, in-use
|
||||
|
||||
5. Create a new snapshot:
|
||||
|
||||
response = conn.create_snapshot("<volume_id>",
|
||||
'display_name' => 'Test Snapshot',
|
||||
'display_description' => 'Test Snapshot from Vol Test')
|
||||
snapshot = response.body['snapshot']
|
||||
snapshot['id'] # returns the id of the new volume
|
||||
snapshot['display_name'] # => "demo-vol"
|
||||
snapshot['size'] # => 1
|
||||
snapshot['volume_id'] # returns the volume id of the snapshot
|
||||
snapshot['status'] # returns the status of the snapshot e.g. creating, available
|
||||
|
||||
6. Update a snapshot:
|
||||
|
||||
conn.update_snapshot("<snapshot_id>", 'display_name' => "Test Snapshot 1 Update")
|
||||
|
||||
7. Delete a snapshot:
|
||||
|
||||
conn.delete_snapshot("<snapshot_id>")
|
||||
|
||||
## Request Volume Backup Operations
|
||||
|
||||
This section discusses the volume backup operations you can perform using the request abstraction.
|
||||
|
||||
1. List all available volume backups for an account:
|
||||
|
||||
conn.list_volume_backups
|
||||
|
||||
2. List details of all available volume backups:
|
||||
|
||||
conn.list_volume_backups_detail
|
||||
|
||||
3. Obtain the details of a volume backup by ID:
|
||||
|
||||
conn.get_volume_backup_details("<volume_backup_id>")
|
||||
|
||||
4. Create a volume backup:
|
||||
|
||||
conn.create_volume_backup("<volume_id>")
|
||||
|
||||
5. Restore into a new volume using a volume backup:
|
||||
|
||||
conn.restore_volume_backup("<volume_backup_id>")
|
||||
# creates a new volume that is a clone of the volume the backup was created from
|
||||
|
||||
6. Restore into an existing volume using a volume backup:
|
||||
|
||||
conn.restore_volume_backup("<volume_backup_id>", "<existing_volume_id>")
|
||||
|
||||
7. Delete a volume backup:
|
||||
|
||||
conn.delete_volume_backup("<volume_backup_id>")
|
||||
|
||||
---------
|
||||
[Documentation Home](https://github.com/fog/fog/blob/master/lib/fog/hp/README.md) | [Examples](https://github.com/fog/fog/blob/master/lib/fog/hp/examples/getting_started_examples.md)
|
54
lib/fog/hp/examples/cdn.md
Executable file
54
lib/fog/hp/examples/cdn.md
Executable file
|
@ -0,0 +1,54 @@
|
|||
# Examples for working with HP Cloud CDN Service
|
||||
|
||||
The HP Cloud services provides CDN support via the request layer abstraction. In the request abstraction, you can CDN-enable a container, get a list of the CDN-enabled containers, list the metadata for a CDN-enabled container, update the metadata for a CDN-enabled container, and CDN-disable a container.
|
||||
|
||||
The examples on this page can be executed from within a Ruby console (IRB):
|
||||
|
||||
irb
|
||||
|
||||
* [Connecting to the Service](https://github.com/fog/fog/blob/master/lib/fog/hp/docs/connect.md)
|
||||
|
||||
|
||||
## CDN-Enabling an Existing Container
|
||||
|
||||
To CDN-enable an existing container:
|
||||
|
||||
conn.put_container("fog-rocks")
|
||||
|
||||
## Listing CDN-Enabled Containers
|
||||
|
||||
To generate a list of CDN-enabled containers:
|
||||
|
||||
conn.get_containers
|
||||
|
||||
## Listing the Metadata for a CDN-Enabled Container
|
||||
|
||||
To list the metadata (or header information) for a CDN-enabled container:
|
||||
|
||||
conn.head_container("fog-rocks")
|
||||
|
||||
## Updating the Metadata for a CDN-Enabled Container
|
||||
|
||||
To update or modify the metadata for a CDN-enabled container, use the command
|
||||
|
||||
> conn.post_container("fog-rocks", {**option**})
|
||||
|
||||
Where _option_ can be any of the following:
|
||||
|
||||
* X-CDN-Enabled <Boolean> - cdn status for container
|
||||
* X-CDN-URI <String> - cdn url for this container
|
||||
* 'X-TTL'<~String> - integer seconds before data expires, defaults to 86400 (1 day), in 900 (15 min.) to 1577836800 (50 years)
|
||||
* X-Log-Retention <Boolean>
|
||||
|
||||
So for example, if you want to modify the X-TTL metadata information so that the value becomes 3600, the command would be:
|
||||
|
||||
conn.post_container("fog-rocks", {'X-Ttl' => 3600 })
|
||||
|
||||
## Disabling a CDN Container
|
||||
|
||||
To CDN-disable container:
|
||||
|
||||
conn.delete_container("fog-rocks")
|
||||
|
||||
---------
|
||||
[Documentation Home](https://github.com/fog/fog/blob/master/lib/fog/hp/README.md) | [Examples](https://github.com/fog/fog/blob/master/lib/fog/hp/examples/getting_started_examples.md)
|
794
lib/fog/hp/examples/compute.md
Executable file
794
lib/fog/hp/examples/compute.md
Executable file
|
@ -0,0 +1,794 @@
|
|||
# Examples for working with HP Cloud Compute Service v12.12
|
||||
|
||||
The HP Cloud Extensions to Ruby Fog libary provides Compute services support using two abstractions: a model layer and a request layer. Both layers are detailed below. The code samples on this page can be executed from within a Ruby console (IRB):
|
||||
|
||||
irb
|
||||
|
||||
This page discusses the following topics:
|
||||
|
||||
* [Connecting to the Service](https://github.com/fog/fog/blob/master/lib/fog/hp/docs/connect.md)
|
||||
|
||||
**Model Layer Examples**
|
||||
|
||||
* [Model Server Operations](#model-server-operations)
|
||||
* [Model Server Metadata Operations](#model-server-metadata-operations)
|
||||
* [Model Flavor Operations](#model-flavor-operations)
|
||||
* [Model Image Operations](#model-image-operations)
|
||||
* [Model Image Metadata Operations](#model-image-metadata-operations)
|
||||
* [Model Keypair Operations](#model-keypair-operations)
|
||||
* [Model Security Groups Operations](#model-security-groups-operations)
|
||||
* [Model Address Operations](#model-address-operations)
|
||||
|
||||
**Request Layer Examples**
|
||||
|
||||
* [Request Server Operations](#request-server-operations)
|
||||
* [Request Server Metadata Operations](#request-server-metadata-operations)
|
||||
* [Request Flavor Operations](#request-flavor-operations)
|
||||
* [Request Image Operations](#request-image-operations)
|
||||
* [Request Image Metadata Operations](#request-image-metadata-operations)
|
||||
* [Request Keypair Operations](#request-keypair-operations)
|
||||
* [Request Security Groups Operations](#request-security-groups-operations)
|
||||
* [Request Address Operations](#request-address-operations)
|
||||
|
||||
|
||||
## Model Server Operations
|
||||
|
||||
1. List all available servers for an account:
|
||||
|
||||
servers = conn.servers
|
||||
servers.size # returns no. of servers
|
||||
# display servers in a tabular format
|
||||
conn.servers.table([:id, :name, :state, :created_at])
|
||||
|
||||
2. Obtain the details of a particular server:
|
||||
|
||||
server = conn.servers.get(server_id)
|
||||
server.name # returns name of the server
|
||||
server.flavor_id # returns id of the flavor used to create the server
|
||||
server.image_id # returns id of the image used to create the server
|
||||
server.addresses # returns a hash of public and private IP addresses
|
||||
server.created_at # returns the date the server was created
|
||||
server.state # returns the state of the server e.g. ACTIVE, BUILD
|
||||
|
||||
3. Create a new server:
|
||||
|
||||
new_server = conn.servers.create(
|
||||
:name => "My Shiny Server",
|
||||
:flavor_id => 1,
|
||||
:image_id => 2,
|
||||
:key_name => "<key_name>",
|
||||
:security_groups => ["aaa"]
|
||||
)
|
||||
new_server.id # returns the id of the server
|
||||
new_server.name # => "My Shiny Server"
|
||||
new_server.state # returns the state of the server e.g. BUILD
|
||||
new_server.private_ip_address # returns the private ip address
|
||||
new_server.public_ip_address # returns the public ip address, if any assigned
|
||||
|
||||
4. Create a new Windows server instance and retrieve the encrypted password:
|
||||
|
||||
win_server = conn.servers.create(
|
||||
:name => "My Windows Server",
|
||||
:flavor_id => 1,
|
||||
:image_id => 3, # Make sure it is a Windows image
|
||||
:key_name => "<key_name>",
|
||||
:security_groups => ["aaa"]
|
||||
)
|
||||
win_server.id # returns the id of the server
|
||||
# Retrieve the encrypted password
|
||||
win_server.windows_password
|
||||
# => "Im6ZJ8auyMRnkJ24KKWQvTgWDug1s ... y0uY1BcHLJ5OrkEPHhQoQntIKOoQ=\n"
|
||||
**Note**: You must retrieve the Windows password immediately after you create the Windows instance. Also, make sure you have a security rule defined to open RDP port 3389 so that you can connect to the Windows server.
|
||||
|
||||
5. Create a new Linux-based persistent server with a bootable volume:
|
||||
|
||||
conn.servers.create(
|
||||
:flavor_id => 103,
|
||||
:name => "MyPersistentServer",
|
||||
:block_device_mapping =>
|
||||
[{ 'volume_size' => '', # ignored
|
||||
'volume_id' => "111111",
|
||||
'delete_on_termination' => '0',
|
||||
'device_name' => 'vda'
|
||||
}]
|
||||
)
|
||||
**Note**: In *block_device_mapping*, *volume_size* is ignored; it is automatically retrieved from the specified bootable volume. To delete the bootable volume after the server instance is killed you can set *delete_on_termination* to `1`. To preserve the bootable volume, set it to `0` as shown above.
|
||||
|
||||
6. Create a new Linux-based server with advanced personalization options:
|
||||
|
||||
new_server = conn.servers.create(
|
||||
:name => "My Personalized Server",
|
||||
:flavor_id => 1,
|
||||
:image_id => 2,
|
||||
:key_name => "<key_name>",
|
||||
:security_groups => ["aaa"],
|
||||
:config_drive => true,
|
||||
:user_data_encoded => ["This is some encoded user data"].pack('m'),
|
||||
:personality => [{
|
||||
'contents' => File.read("/path/to/sample.txt"),
|
||||
'path' => "/path/to/sample.txt"
|
||||
}]
|
||||
)
|
||||
new_server.id # returns the id of the server
|
||||
new_server.name # => "My Personalized Server"
|
||||
|
||||
# Note: that un-encoded user data can also be provided by setting the user_data property
|
||||
# although, encoding the data on the client is faster and efficient
|
||||
new_server = conn.servers.new(
|
||||
:name => "My Personalized Server",
|
||||
...
|
||||
...
|
||||
)
|
||||
new_server.user_data = "This is some un-encoded user data"
|
||||
new_server.save
|
||||
|
||||
The personalization options are:
|
||||
|
||||
*config_drive*
|
||||
: Disk accessible to the server that contains a FAT filesystem. If `config_drive` parameter is set to `true` at the time of server creation, the configuration drive is created.
|
||||
|
||||
*user_data_encoded* or *user_data*
|
||||
: Allows additional metadata to be inserted during server creation by supplying a Base64-encoded string in the `user_data_encoded` parameter, or by providing an unencoded string with the `user_data` attribute. Note that encoding the data on the client is faster and more efficient.
|
||||
|
||||
*personality*
|
||||
: Allows files to be injected into the server instance after its creation. The file `contents` are Base64 encoded and injected into the location specified by `path`.
|
||||
|
||||
**Note**: The above personalization options are not supported on Windows server instances.
|
||||
|
||||
7. Get console output:
|
||||
|
||||
server = conn.servers.get(server_id)
|
||||
server.console_output(5) # 5 lines of console output are returned
|
||||
|
||||
8. Get VNC console:
|
||||
|
||||
server = conn.servers.get(server_id)
|
||||
server.vnc_console_url('novnc') # URL to access the VNC console of a server from a browser
|
||||
|
||||
9. Reboot a server:
|
||||
|
||||
server = conn.servers.get(server_id)
|
||||
server.reboot # soft reboot by default
|
||||
|
||||
server.reboot("HARD") # hard reboot also possible
|
||||
|
||||
10. Change password for a server:
|
||||
|
||||
server = conn.servers.get(server_id)
|
||||
server.change_password("new_password")
|
||||
|
||||
11. Delete an existing server:
|
||||
|
||||
server = conn.servers.get(server_id)
|
||||
server.destroy
|
||||
|
||||
## Model Server Metadata Operations
|
||||
|
||||
1. Create a server with some metadata:
|
||||
|
||||
myserver = conn.servers.create(
|
||||
:flavor_id => 1,
|
||||
:image_id => 2,
|
||||
:name => "myserver",
|
||||
:metadata => {'Meta1' => 'MetaValue1', 'Meta2' => 'MetaValue2'}
|
||||
)
|
||||
|
||||
2. Get the metadata item:
|
||||
|
||||
myserver.metadata.get("Meta1")
|
||||
|
||||
3. Update the metadata:
|
||||
|
||||
myserver.metadata.update({"Meta2" => "MetaValue2"})
|
||||
|
||||
4. Set the metadata:
|
||||
|
||||
myserver.metadata.set({"Meta3" => "MetaValue3"})
|
||||
|
||||
5. Set the metadata explicitly:
|
||||
|
||||
m = myserver.metadata.new
|
||||
m.key = "Meta4"
|
||||
m.value = "Value4"
|
||||
m.save
|
||||
|
||||
6. Update the metadata:
|
||||
|
||||
m = myserver.metadata.get("Meta3")
|
||||
m.value = "UpdValue3"
|
||||
m.save
|
||||
|
||||
7. List metadata:
|
||||
|
||||
myserver.metadata.all
|
||||
|
||||
8. Delete metadata:
|
||||
|
||||
m = myserver.metadata.get("Meta3")
|
||||
m.destroy
|
||||
|
||||
## Model Flavor Operations
|
||||
|
||||
1. List all available flavors:
|
||||
|
||||
flavors = conn.flavors
|
||||
flavors.size # returns no. of flavors
|
||||
# display flavors in a tabular format
|
||||
conn.flavors.table([:id, :name, :ram, :disk])
|
||||
|
||||
2. Obtain the details of a particular flavor:
|
||||
|
||||
flavor = conn.flavors.get(flavor_id) # get the flavor
|
||||
flavor.name # returns the name of the flavor eg: m1.tiny, m1.small etc.
|
||||
flavor.ram # returns the ram memory in bytes for the flavor, eg: 4096
|
||||
flavor.disk # returns the disk size in GB for the flavor, eg: 80
|
||||
flavor.cores # returns no. of cores for the flavor, eg: 0.25
|
||||
|
||||
## Model Image Operations
|
||||
|
||||
1. List all available images:
|
||||
|
||||
images = conn.images
|
||||
images.size # returns no. of images
|
||||
# display images in a tabular format
|
||||
conn.images.table([:id, :name, :status, :created_at])
|
||||
|
||||
2. Obtain the details of a particular image:
|
||||
|
||||
image = conn.images.get(image_id) # get the image
|
||||
image.name # returns name of the image
|
||||
image.created_at # returns the date the image was created
|
||||
image.status # returns the state of the image e.g. ACTIVE
|
||||
|
||||
3. Create a new snapshot image based on an existing server:
|
||||
|
||||
myserver.create_image("My Image")
|
||||
|
||||
4. Delete an existing snapshot image:
|
||||
|
||||
image = conn.images.get(image_id)
|
||||
image.destroy
|
||||
|
||||
## Model Image Metadata Operations
|
||||
|
||||
1. Create an image snapshot with some metadata:
|
||||
|
||||
myserver.create_image("My Image", {"ImgMeta1" => "ImgMeta1Value"})
|
||||
|
||||
2. Get the metadata item:
|
||||
|
||||
myimage = conn.images.get(image_id)
|
||||
myimage.metadata.get("ImgMeta1")
|
||||
|
||||
3. Update the metadata:
|
||||
|
||||
myimage.metadata.update({"ImgMeta2" => "ImgMetaValue2"})
|
||||
|
||||
4. Set the metadata:
|
||||
|
||||
myimage.metadata.set({"ImgMeta3" => "ImgMetaValue3"})
|
||||
|
||||
5. Set the metadata explicitly:
|
||||
|
||||
m = myimage.metadata.new
|
||||
m.key = "ImgMeta4"
|
||||
m.value = "ImgMetaValue4"
|
||||
m.save
|
||||
|
||||
6. Update the metadata:
|
||||
|
||||
m = myimage.metadata.get("ImgMeta3")
|
||||
m.value = "ImgUpdValue3"
|
||||
m.save
|
||||
|
||||
7. List metadata:
|
||||
|
||||
myimage.metadata.all
|
||||
|
||||
8. Delete metadata:
|
||||
|
||||
m = myimage.metadata.get("ImgMeta3")
|
||||
m.destroy
|
||||
|
||||
## Model Keypair Operations
|
||||
|
||||
1. List all available keypairs:
|
||||
|
||||
keypairs = conn.key_pairs
|
||||
keypairs.size # returns no. of keypairs
|
||||
# display keypairs in a tabular format
|
||||
conn.key_pairs.table([:name, :public_key])
|
||||
|
||||
2. Obtain the details of a particular keypair:
|
||||
|
||||
keypair = conn.key_pairs.get(key_name) # get the keypair
|
||||
keypair.name # returns name of the keypair
|
||||
keypair.public_key # returns the public key of the keypair
|
||||
# NOTE: Due to security considerations, the private key is not available on subsequent gets
|
||||
keypair.private_key # => nil
|
||||
|
||||
3. Create a new keypair:
|
||||
|
||||
keypair = conn.key_pairs.create(:name => "mykey")
|
||||
keypair.name # returns name of the keypair
|
||||
keypair.public_key # returns the public key of the keypair
|
||||
keypair.private_key # returns the private key of the keypair
|
||||
|
||||
4. Export a keypair to a file:
|
||||
|
||||
keypair = conn.key_pairs.create(:name => "mykey2")
|
||||
keypair.write # => "Key file built: /Users/xxxxx/.ssh/mykey2.pem"
|
||||
|
||||
# Alternatively, you can pass in a path to export the key
|
||||
keypair.write("/Users/xxxxx/Downloads/mykey2.pem")
|
||||
|
||||
5. Import a public key to create a new keypair:
|
||||
|
||||
keypair = conn.key_pairs.create(:name => "mykey", :public_key => "public key material")
|
||||
keypair.name # returns name of the keypair
|
||||
|
||||
6. Delete an existing keypair:
|
||||
|
||||
keypair = conn.key_pairs.get(key_name)
|
||||
keypair.destroy
|
||||
|
||||
## Model Security Groups Operations
|
||||
|
||||
1. List all available security groups:
|
||||
|
||||
sgroups = conn.security_groups
|
||||
sgroups.size # returns no. of security groups
|
||||
# display security groups in a tabular format
|
||||
conn.security_groups.table([:id, :name, :description])
|
||||
|
||||
2. Obtain the details of a particular security group:
|
||||
|
||||
sgroup = conn.security_groups.get(sgroup_id) # get the security group
|
||||
sgroup.name # returns name of the security group
|
||||
sgroup.description # returns description of the security group
|
||||
|
||||
3. Create a new security group:
|
||||
|
||||
sgroup = conn.security_groups.create(:name => "mysgroup", :description => "my new sec group")
|
||||
sgroup.name # returns name of the security group
|
||||
|
||||
4. Create a rule for an existing security group:
|
||||
|
||||
sgroup = conn.security_groups.get(sgroup_id) # get the security group
|
||||
sgroup.create_rule(80..80) # allow port 80. defaults to protocol tcp at 0.0.0.0/0
|
||||
sgroup.create_rule(-1..-1, "icmp", "0.0.0.0/0") # allow icmp
|
||||
# show all rules
|
||||
sgroup = conn.security_groups.get(sgroup_id) # get the security group
|
||||
sgroup.rules
|
||||
|
||||
5. Delete a rule from an existing security group:
|
||||
|
||||
sgroup = conn.security_groups.get(sgroup_id) # get the security group
|
||||
sgroup.delete_rule(sgroup_rule_id)
|
||||
|
||||
6. Delete an existing security group:
|
||||
|
||||
sgroup = conn.security_groups.get(sgroup_id) # get the security group
|
||||
sgroup.destroy
|
||||
|
||||
## Model Address Operations
|
||||
|
||||
1. List all available floating IP addresses:
|
||||
|
||||
addresses = conn.addresses
|
||||
addresses.size # returns no. of addresses
|
||||
# display addresses in a tabular format
|
||||
conn.addresses.table([:id, :ip, :fixed_ip, :instance_id])
|
||||
|
||||
2. Obtain the details of a particular address:
|
||||
|
||||
address = conn.addresses.get(address_id) # get the address
|
||||
address.ip # returns the ip address
|
||||
|
||||
3. Create or allocating a new address:
|
||||
|
||||
address = conn.addresses.create # allocates an ip address from the pool
|
||||
address.ip # returns the ip address
|
||||
|
||||
4. Associate a server to an existing address:
|
||||
|
||||
address = conn.addresses.get(address_id) # get the address
|
||||
server = conn.servers.get(server_id) # get the server
|
||||
address.server = server # associate the server
|
||||
address.instance_id # returns the id of the server
|
||||
|
||||
5. Disassociate a server from an existing address:
|
||||
|
||||
address = conn.addresses.get(address_id) # get the address
|
||||
address.server = nil # disassociate the server
|
||||
address.instance_id # => nil
|
||||
|
||||
6. Delete (release) an existing address:
|
||||
|
||||
address = conn.addresses.get(address_id) # get the address
|
||||
address.destroy # releases the ip address to the pool
|
||||
|
||||
## Request Server Operations
|
||||
|
||||
1. List all available servers for an account:
|
||||
|
||||
response = conn.list_servers
|
||||
response.body['servers'] # returns an array of server hashes
|
||||
response.headers # returns the headers
|
||||
response.body['servers'][0]['name'] # returns the name of the server
|
||||
|
||||
2. List all available servers with additional details:
|
||||
|
||||
response = conn.list_servers_detail
|
||||
response.body['servers'] # returns an array of server hashes
|
||||
response.body['servers'][0]['name'] # returns the name of the server
|
||||
|
||||
3. Obtain the details of a particular server:
|
||||
|
||||
response = conn.get_server_details(server_id)
|
||||
server = response.body['server']
|
||||
server['name'] # returns the name of the server
|
||||
server['flavor'] # returns the flavor used to create the server
|
||||
server['image'] # returns the image used to create the server
|
||||
server['addresses'] # returns the public and private addresses
|
||||
server['status'] # returns the state of the server e.g. ACTIVE
|
||||
|
||||
4. Create a new server:
|
||||
|
||||
response = conn.create_server(
|
||||
"My Shiny Server",
|
||||
flavor_id,
|
||||
image_id,
|
||||
{
|
||||
'security_groups' => ["SecGroup1, SecGroup2"],
|
||||
'key_name' => "<key_name>"
|
||||
}
|
||||
)
|
||||
server = response.body['server']
|
||||
server['id'] # returns the id of the new server
|
||||
server['name'] # => "My Shiny Server"
|
||||
server['status'] # returns the state of the server e.g. BUILD
|
||||
|
||||
5. Create a new Windows server and retrieve the encrypted password:
|
||||
|
||||
# Make sure to use a Windows image
|
||||
response = conn.create_server("My Windows Server", flavor_id, image_id)
|
||||
win_server = response.body['server']
|
||||
server_id = win_server['id'] # returns the id of the new server
|
||||
# Retrieve the encrypted password
|
||||
conn.get_windows_password(server_id)
|
||||
# => "Im6ZJ8auyMRnkJ24KKWQvTgWDug1s ... y0uY1BcHLJ5OrkEPHhQoQntIKOoQ=\n"
|
||||
**Note**: You must retrieve the Windows password immediately after you create the Windows instance. Also, make sure you have a security rule defined to open RDP port 3389 so that you can connect to the Windows server.
|
||||
|
||||
6. Create a new Linux-based persistent server with a bootable volume
|
||||
|
||||
conn.create_persistent_server(
|
||||
"MyBootableServer",
|
||||
103,
|
||||
[{ "volume_size"=>"", # ignored
|
||||
"volume_id"=>"65904",
|
||||
"delete_on_termination"=>"0",
|
||||
"device_name"=>"vda"
|
||||
}] ,
|
||||
{
|
||||
'security_groups' => ["mysecgroup"],
|
||||
'key_name' => "<key_pair>"
|
||||
}
|
||||
)
|
||||
**Note**: In *block_device_mapping*, *volume_size* is ignored; it is automatically retrieved from the specified bootable volume. To delete the bootable volume after the server instance is killed you can set *delete_on_termination* to `1`. To preserve the bootable volume, set it to `0` as shown above.
|
||||
|
||||
7. Create a new Linux-based server with advanced personalisation options:
|
||||
|
||||
response = conn.create_server(
|
||||
"My Shiny Server",
|
||||
flavor_id,
|
||||
image_id,
|
||||
{
|
||||
'security_groups' => ["SecGroup1, SecGroup2"],
|
||||
'key_name' => "<key_name>",
|
||||
'config_drive' => true,
|
||||
'user_data_encoded' => ["This is some encoded user data"].pack('m'),
|
||||
'personality' => [{
|
||||
'contents' => File.read("/path/to/sample.txt"),
|
||||
'path' => "/path/to/sample.txt"
|
||||
}]
|
||||
}
|
||||
)
|
||||
server = response.body['server']
|
||||
server['id'] # returns the id of the new server
|
||||
|
||||
The personalization options are:
|
||||
|
||||
*config_drive*
|
||||
: Disk accessible to the server that contains a FAT filesystem. If `config_drive` parameter is set to `true` at the time of server creation, the configuration drive is created.
|
||||
|
||||
*user_data_encoded*
|
||||
: Allows additional metadata to be inserted during server creation by supplying a Base64-encoded string in the `user_data_encoded` parameter.
|
||||
|
||||
*personality*
|
||||
: Allows files to be injected into the server instance after its creation. The file `contents` are Base64 encoded and injected into the location specified by `path`.
|
||||
|
||||
**Note**: The above personalization options are not supported on Windows server instances.
|
||||
|
||||
8. Update the name for a server:
|
||||
|
||||
conn.update_server(server_id, {'name' => "My Cool Server"})
|
||||
response = conn.get_server_details(server_id)
|
||||
response.body['server']['name'] # => "My Cool Server"
|
||||
|
||||
9. Change the password for a server:
|
||||
|
||||
conn.change_password_server(server_id, "new_password")
|
||||
|
||||
10. List both public and private addresses of a particular server:
|
||||
|
||||
response = conn.list_server_addresses(server_id)
|
||||
|
||||
11. List all the private addresses of a particular server:
|
||||
|
||||
response = conn.list_server_private_addresses(server_id, "private") # where "private" is the network name
|
||||
|
||||
12. List all the public addresses of a particular server:
|
||||
|
||||
response = conn.list_server_public_addresses(server_id, "private") # where "private" is the network name
|
||||
|
||||
13. Get console output:
|
||||
|
||||
response = conn.get_console_output(server_id, 5)
|
||||
# => 5 lines of console output are returned
|
||||
|
||||
14. Get VNC console:
|
||||
|
||||
response = conn.get_vnc_console(server_id, 'novnc')
|
||||
# => Url to access the VNC console of a server from a browser
|
||||
|
||||
15. Reboot a server:
|
||||
|
||||
response = conn.reboot_server(server_id, 'HARD') # Hard reboot a server
|
||||
response = conn.reboot_server(server_id, 'SOFT') # Soft reboot a server
|
||||
|
||||
16. Delete an existing server:
|
||||
|
||||
conn.delete_server(server_id)
|
||||
|
||||
## Request Server Metadata Operations
|
||||
|
||||
1. Create a server and pass it some metadata at creation:
|
||||
|
||||
response = conn.create_server(
|
||||
"myserver", 1, 2,
|
||||
{'metadata' =>
|
||||
{'Meta1' => 'MetaValue1', 'Meta2' => 'MetaValue2'}
|
||||
}
|
||||
)
|
||||
response.body['server']['metadata']
|
||||
# => {"Meta1"=>"MetaValue1", "Meta2"=>"MetaValue2"}
|
||||
|
||||
2. List the existing metadata:
|
||||
|
||||
response = conn.list_metadata("servers", server_id)
|
||||
response.body['metadata']
|
||||
# => {"Meta1"=>"MetaValue1", "Meta2"=>"MetaValue2"}
|
||||
|
||||
3. Set new values to the existing metadata:
|
||||
|
||||
response = conn.set_metadata("servers", server_id, {"MetaNew1" => "MetaNewValue1"})
|
||||
response.body['metadata']
|
||||
# => {"MetaNew1"=>"MetaNewValue1"}
|
||||
|
||||
4. Update the existing metadata:
|
||||
|
||||
response = conn.update_metadata("servers", server_id, {"Meta2" => "MetaValue2"})
|
||||
response.body['metadata']
|
||||
# => {"Meta2"=>"MetaValue2"}
|
||||
|
||||
5. Get a metadata item:
|
||||
|
||||
response = conn.get_meta("servers", server_id, "Meta1")
|
||||
response.body['meta']
|
||||
# => {"Meta1"=>"MetaValue1"}
|
||||
|
||||
6. Set a new metadata item or update an existing metadata item:
|
||||
|
||||
response = conn.update_meta("servers", server_id, "Meta1", "MetaUpdated1")
|
||||
response.body['meta']
|
||||
# => {"Meta1"=>"MetaUpdated1"}
|
||||
|
||||
7. Delete a metadata item:
|
||||
|
||||
conn.delete_meta("servers", server_id, "Meta1")
|
||||
|
||||
## Request Flavor Operations
|
||||
|
||||
1. List all available flavors:
|
||||
|
||||
response = conn.list_flavors
|
||||
response.body['flavors'] # returns an array of flavor hashes
|
||||
response.headers # returns the headers for the flavors
|
||||
response.body['flavors'][0]['name'] # returns the name of the flavor
|
||||
|
||||
2. List all available flavors with additional details:
|
||||
|
||||
response = conn.list_flavors_detail
|
||||
response.body['flavors'] # returns an array of flavor hashes
|
||||
|
||||
3. Obtain the details of a particular flavor:
|
||||
|
||||
response = conn.get_flavor_details(flavor_id)
|
||||
flavor = response.body['flavor']
|
||||
flavor['name'] # returns the name of the flavor
|
||||
flavor['disk'] # returns the disk size of the flavor
|
||||
flavor['ram'] # returns the ram size of the flavor
|
||||
|
||||
## Request Image Operations
|
||||
|
||||
1. List all available images:
|
||||
|
||||
response = conn.list_images
|
||||
response.body['images'] # returns an array of image hashes
|
||||
response.headers # returns the headers for the images
|
||||
response.body['images'][0]['name'] # returns the name of the image
|
||||
|
||||
2. List all available images with additional details:
|
||||
|
||||
response = conn.list_images_detail
|
||||
response.body['images'] # returns an array of image hashes
|
||||
response.body['images'][0]['name'] # returns the name of the image
|
||||
|
||||
3. Obtain the details of a particular image:
|
||||
|
||||
response = conn.get_image_details(image_id)
|
||||
image = response.body['image']
|
||||
image['name'] # returns name of the image
|
||||
image['status'] # returns the state of the image e.g. ACTIVE
|
||||
image['created'] # returns the creation date of the image
|
||||
image['updated'] # returns the update date of the image
|
||||
|
||||
3. Create a new snapshot image based on an existing server:
|
||||
|
||||
conn.create_image(server_id, "My Image") # creates an snapshot image from the server referenced by "server_id"
|
||||
|
||||
4. Delete an existing snapshot image:
|
||||
|
||||
conn.delete_image(image_id)
|
||||
|
||||
## Request Image Metadata Operations
|
||||
|
||||
1. Create an image and pass it some metadata at creation:
|
||||
|
||||
conn.create_image(server_id, "myimage", {'Meta1' => 'MetaValue1', 'Meta2' => 'MetaValue2'})
|
||||
|
||||
2. List the existing metadata:
|
||||
|
||||
response = conn.list_metadata("images", image_id)
|
||||
response.body['metadata']
|
||||
# => {"Meta1"=>"MetaValue1", "Meta2"=>"MetaValue2"}
|
||||
|
||||
3. Set new values to the existing metadata:
|
||||
|
||||
response = conn.set_metadata("images", image_id, {"MetaNew1" => "MetaNewValue1"})
|
||||
response.body['metadata']
|
||||
# => {"MetaNew1"=>"MetaNewValue1"}
|
||||
|
||||
4. Update the existing metadata:
|
||||
|
||||
response = conn.update_metadata("images", image_id, {"Meta2" => "MetaValue2"})
|
||||
response.body['metadata']
|
||||
# => {"Meta2"=>"MetaValue2"}
|
||||
|
||||
5. Get a metadata item:
|
||||
|
||||
response = conn.get_meta("images", image_id, "Meta1")
|
||||
response.body['meta']
|
||||
# => {"Meta1"=>"MetaValue1"}
|
||||
|
||||
6. Update a metadata item:
|
||||
|
||||
response = conn.update_meta("images", image_id, "Meta1", "MetaUpdated1")
|
||||
response.body['meta']
|
||||
# => {"Meta1"=>"MetaUpdated1"}
|
||||
|
||||
7. Delete a metadata item:
|
||||
|
||||
conn.delete_meta("images", image_id, "Meta1")
|
||||
|
||||
## Request Keypair Operations
|
||||
|
||||
1. List all available keypairs:
|
||||
|
||||
response = conn.list_key_pairs
|
||||
response.body['keypairs'] # returns an array of keypair hashes
|
||||
response.headers # returns the headers
|
||||
response.body['keypairs'][0]['keypair']['name'] # returns the name of the keypair
|
||||
|
||||
2. Create a new keypair:
|
||||
|
||||
response = conn.create_key_pair("mykey")
|
||||
keypair = response.body['keypair']
|
||||
keypair['name'] # returns the name of the keypair
|
||||
keypair['public_key'] # returns the public key of the keypair
|
||||
keypair['private_key'] # returns the private key of the keypair
|
||||
|
||||
3. Import a public key to create a new keypair:
|
||||
|
||||
response = conn.create_key_pair("mykey", "public key material")
|
||||
keypair = response.body['keypair']
|
||||
keypair['name'] # returns the name of the keypair
|
||||
|
||||
4. Delete an existing keypair:
|
||||
|
||||
conn.delete_key_pair(key_name)
|
||||
|
||||
## Request Security Groups Operations
|
||||
|
||||
1. List all available security groups:
|
||||
|
||||
response = conn.list_security_groups
|
||||
response.body['security_groups'] # returns an array of security groups hashes
|
||||
response.headers # returns the headers
|
||||
response.body['security_groups'][0]['name'] # returns the name of the security group
|
||||
|
||||
2. Obtain the details of a particular security group:
|
||||
|
||||
response = conn.get_security_group(sgroup_id) # get the security group
|
||||
sgroup = response.body['security_group']
|
||||
sgroup['name'] # returns the name of the security group
|
||||
|
||||
3. Create a new security group:
|
||||
|
||||
response = conn.create_security_group("mysgroup", "my new sec group")
|
||||
sgroup = response.body['security_group']
|
||||
sgroup['name'] # => "mysgroup"
|
||||
|
||||
4. Create a rule for an existing security group:
|
||||
|
||||
response = create_security_group_rule(sgroup_id, "tcp", "80", "80", "0.0.0.0/0") # allow port 80, tcp at 0.0.0.0/0
|
||||
sg_rule = response.body['security_group_rule']
|
||||
sg_rule['id'] # returns the id of the security group rule
|
||||
sg_rule['parent_group_id'] # returns the id of the security group to which the rule belongs to
|
||||
sg_rule['from_port'] # => 80
|
||||
sg_rule['to_port'] # => 80
|
||||
sg_rule['ip_protocol'] # => tcp
|
||||
sg_rule['ip_range']['cidr'] # => 0.0.0.0/0
|
||||
|
||||
5. Delete an existing security group rule:
|
||||
|
||||
conn.delete_security_group_rule(sg_rule_id)
|
||||
|
||||
6. Delete an existing security group:
|
||||
|
||||
conn.delete_security_group(sgroup_id)
|
||||
|
||||
## Request Address Operations
|
||||
|
||||
1. List all available floating ip addresses:
|
||||
|
||||
response = conn.list_addresses
|
||||
response.body['addresses'] # returns an array of address hashes
|
||||
response.headers # returns the headers
|
||||
response.body['addresses'][0]['id'] # returns the id of the address
|
||||
|
||||
2. Obtain the details of a particular address:
|
||||
|
||||
response = conn.get_address(address_id) # get the address
|
||||
response.body['address']['ip'] # returns the ip address
|
||||
|
||||
3. Create (allocate) a new address:
|
||||
|
||||
response = conn.allocate_address # allocates an ip address from the pool
|
||||
response.body['address']['ip'] # returns the ip address
|
||||
|
||||
4. Associate a server to an existing address:
|
||||
|
||||
conn.associate_address(server_id, ip_address)
|
||||
|
||||
5. Disassociate a server from an existing address:
|
||||
|
||||
conn.disassociate_address(server_id, ip_address)
|
||||
|
||||
6. Delete (release) an existing address:
|
||||
|
||||
conn.release_address(address_id) # releases the ip address to the pool
|
||||
|
||||
---------
|
||||
[Documentation Home](https://github.com/fog/fog/blob/master/lib/fog/hp/README.md) | [Examples](https://github.com/fog/fog/blob/master/lib/fog/hp/examples/getting_started_examples.md)
|
820
lib/fog/hp/examples/compute_v2.md
Executable file
820
lib/fog/hp/examples/compute_v2.md
Executable file
|
@ -0,0 +1,820 @@
|
|||
# Examples for working with HP Cloud Compute Service v13.5
|
||||
|
||||
The latest HP Cloud deployment, version 13.5, takes advantage of more OpenStack functionality and the compute service uses slightly different commands (often noted by *v2* in the commands) than the previous 12.12 version. Verify which version of HP cloud you are working with.
|
||||
|
||||
The HP Cloud services provides compute support using two abstractions: [a model layer](#ModelLayer) and [a request layer](#RequestLayer). Both layers are detailed below. The code samples on this page can be executed from within a Ruby console (IRB):
|
||||
|
||||
irb
|
||||
|
||||
This page discusses the following topics:
|
||||
|
||||
* [Connecting to the Service](https://github.com/fog/fog/blob/master/lib/fog/hp/docs/connect.md)
|
||||
|
||||
**Model Layer Examples**
|
||||
|
||||
* [Model Server Operations](#model-server-operations)
|
||||
* [Model Server Volume Operations](#model-server-volume-operations)
|
||||
* [Model Server Metadata Operations](#model-server-metadata-operations)
|
||||
* [Model Flavor Operations](#model-flavor-operations)
|
||||
* [Model Image Operations](#model-image-operations)
|
||||
* [Model Image Metadata Operations](#model-image-metadata-operations)
|
||||
* [Model Keypair Operations](#model-keypair-operations)
|
||||
* [Model Address Operations](#model-address-operations)
|
||||
|
||||
**Request Layer Examples**
|
||||
|
||||
* [Request Server Operations](#request-server-operations)
|
||||
* [Request Server Metadata Operations](#request-server-metadata-operations)
|
||||
* [Request Flavor Operations](#request-flavor-operations)
|
||||
* [Request Image Operations](#request-image-operations)
|
||||
* [Request Image Metadata Operations](#request-image-metadata-operations)
|
||||
* [Request Keypair Operations](#request-keypair-operations)
|
||||
* [Request Address Operations](#request-address-operations)
|
||||
|
||||
|
||||
## Model Server Operations
|
||||
|
||||
1. List all available servers for an account:
|
||||
|
||||
servers = conn.servers
|
||||
servers.size # returns no. of servers
|
||||
# display servers in a tabular format
|
||||
conn.servers.table([:id, :name, :state, :created_at])
|
||||
|
||||
2. List servers using a filter:
|
||||
|
||||
servers = conn.servers.all(:name => 'My Shiny Server')
|
||||
|
||||
|
||||
3. Obtain the details of a particular server:
|
||||
|
||||
server = conn.servers.get("<server_id>")
|
||||
server.name # returns name of the server
|
||||
server.flavor_id # returns id of the flavor used to create the server
|
||||
server.image_id # returns id of the image used to create the server
|
||||
server.addresses # returns a hash of public and private IP addresses
|
||||
server.created_at # returns the date the server was created
|
||||
server.state # returns the state of the server e.g. ACTIVE, BUILD
|
||||
|
||||
4. Create a new server:
|
||||
|
||||
new_server = conn.servers.create(
|
||||
:name => "My Shiny Server",
|
||||
:flavor_id => 101,
|
||||
:image_id => "<server_id>"
|
||||
)
|
||||
new_server.id # returns the id of the server
|
||||
new_server.name # => "My Shiny Server"
|
||||
new_server.state # returns the state of the server e.g. BUILD
|
||||
new_server.private_ip_address # returns the private ip address
|
||||
new_server.public_ip_address # returns the public ip address, if any assigned
|
||||
|
||||
5. Create a server by passing in a keypair and security group:
|
||||
|
||||
new_server = conn.servers.create(
|
||||
:name=> "My Shiny Server",
|
||||
:flavor_id => 101,
|
||||
:image_id => "<image_id>",
|
||||
:key_name => "my_keypair",
|
||||
:security_groups => ["My Security Group"]
|
||||
)
|
||||
|
||||
6. Create a server by passing in a network_id:
|
||||
|
||||
new_server = conn.servers.create(
|
||||
:name=> "My Shiny Server",
|
||||
:flavor_id => 101,
|
||||
:image_id => "<image_id>",
|
||||
:key_name => "my_keypair",
|
||||
:security_groups => ["My Security Group"],
|
||||
:networks => ["<network_id>"]
|
||||
)
|
||||
|
||||
7. Create a Linux-based persistent server by passing in a bootable volume:
|
||||
|
||||
new_server = conn.servers.create(
|
||||
:name=> "My Sticky Server",
|
||||
:flavor_id => 104,
|
||||
:block_device_mapping => [{ 'volume_size' => '',
|
||||
'volume_id' => "<volume_id>",
|
||||
'delete_on_termination' => '0',
|
||||
'device_name' => 'vda'
|
||||
}]
|
||||
)
|
||||
**Note**: In *block_device_mapping*, *volume_size* is ignored; it is automatically retrieved from the specified bootable volume. To delete the bootable volume after the server instance is killed you can set *delete_on_termination* to `1`. To preserve the bootable volume, set it to `0` as shown above.
|
||||
|
||||
8. Create a new Linux-based server with advanced personalization options:
|
||||
|
||||
new_server = conn.servers.create(
|
||||
:name => "My Personalized Server",
|
||||
:flavor_id => 1,
|
||||
:image_id => 2,
|
||||
:key_name => "hpdefault",
|
||||
:security_groups => ["aaa"],
|
||||
:config_drive => true,
|
||||
:user_data_encoded => ["This is some encoded user data"].pack('m'),
|
||||
:personality => [{
|
||||
'contents' => File.read("/path/to/sample.txt"),
|
||||
'path' => "/path/to/sample.txt"
|
||||
}]
|
||||
)
|
||||
new_server.id # returns the id of the server
|
||||
new_server.name # => "My Personalised Server"
|
||||
|
||||
# Note: that un-encoded user data can also be provided by setting the user_data property
|
||||
# although, encoding the data on the client is faster and efficient
|
||||
new_server = conn.servers.new(
|
||||
:name => "My Personalized Server",
|
||||
...
|
||||
...
|
||||
)
|
||||
new_server.user_data = "This is some un-encoded user data"
|
||||
new_server.save
|
||||
|
||||
The personalization options are:
|
||||
|
||||
*config_drive*
|
||||
: Disk accessible to the server that contains a FAT filesystem. If `config_drive` parameter is set to `true` at the time of server creation, the configuration drive is created.
|
||||
|
||||
*user_data_encoded* or *user_data*
|
||||
: Allows additional metadata to be inserted during server creation by supplying a Base64-encoded string in the `user_data_encoded` parameter, or by providing an unencoded string with the `user_data` attribute. Note that encoding the data on the client is faster and more efficient.
|
||||
|
||||
*personality*
|
||||
: Allows files to be injected into the server instance after its creation. The file `contents` are Base64 encoded and injected into the location specified by `path`.
|
||||
|
||||
**Note**: The above personalization options are not supported on Windows server instances.
|
||||
|
||||
|
||||
9. Create a new Windows server instance and retrieve the encrypted password:
|
||||
|
||||
win_server = conn.servers.create(
|
||||
:name => "My Windows Server",
|
||||
:flavor_id => 1,
|
||||
:image_id => 3, # Make sure it is a Windows image
|
||||
:key_name => "<key_name>",
|
||||
:security_groups => ["<security_group_name>"]
|
||||
)
|
||||
win_server.id # returns the id of the server
|
||||
# Retrieve the encrypted password
|
||||
win_server.windows_password
|
||||
# => "Im6ZJ8auyMRnkJ24KKWQvTgWDug1s ... y0uY1BcHLJ5OrkEPHhQoQntIKOoQ=\n"
|
||||
**Note**: You must retrieve the Windows password immediately after you create the Windows instance. Also, make sure you have a security rule defined to open RDP port 3389 so that you can connect to the Windows server.
|
||||
|
||||
10. Get console output:
|
||||
|
||||
server = conn.servers.get("<server_id>")
|
||||
server.console_output(10) # returns 10 lines of console output
|
||||
|
||||
11. Get VNC console:
|
||||
|
||||
server = conn.servers.get("<server_id>")
|
||||
server.vnc_console_url('novnc') # URL to access the VNC console of a server from a browser
|
||||
|
||||
12. Update a server:
|
||||
|
||||
server = conn.servers.get("<server_id>")
|
||||
server.update_name("My Shiny Server Updated")
|
||||
|
||||
13. Reboot a server:
|
||||
|
||||
server = conn.servers.get("server_id>")
|
||||
server.reboot # soft reboot by default
|
||||
|
||||
server.reboot("HARD") # hard reboot also possible
|
||||
|
||||
14. Rebuild a server:
|
||||
|
||||
server = conn.servers.get("<server_id>")
|
||||
server.rebuild('server_id', 'My Shiny Server Rebuild')
|
||||
|
||||
15. Delete a server:
|
||||
|
||||
server = conn.servers.get("<server_id>").destroy
|
||||
|
||||
|
||||
## Model Server Volume Operations
|
||||
|
||||
1. Attach a volume to a server:
|
||||
|
||||
server = conn.servers.get("<server_id>")
|
||||
server.volume_attachments.create(
|
||||
:server_id => s.id,
|
||||
:volume_id => "<volume id>",
|
||||
:device => "/dev/sdf"
|
||||
)
|
||||
server.reload #reload the server
|
||||
server.volume_attachments.all #list the attachments
|
||||
|
||||
2. Obtain details for an volume attached to a server:
|
||||
|
||||
server = conn.servers.get("<server_id>")
|
||||
server.volume_attachements.get("<volume_id>")
|
||||
|
||||
3. List attached volumes for a server:
|
||||
|
||||
server = conn.servers.get("<server_id>")
|
||||
server.volume_attachments.all
|
||||
|
||||
4. Detach a volume from a server:
|
||||
|
||||
server = conn.servers.get("<server_id>")
|
||||
att_volume = server.volume_attachments.get("<volume_id>")
|
||||
att_volume.destroy # also aliased to att_volume.detach
|
||||
|
||||
## Model Server Metadata Operations
|
||||
|
||||
1. Create a server with some metadata:
|
||||
|
||||
server = conn.servers.create(
|
||||
:flavor_id => 1,
|
||||
:image_id => 2,
|
||||
:name => "myserver",
|
||||
:metadata => {'Meta1' => 'MetaValue1', 'Meta2' => 'MetaValue2'}
|
||||
)
|
||||
|
||||
2. Get the metadata item:
|
||||
|
||||
server.metadata.get("Meta1")
|
||||
|
||||
3. Update the metadata:
|
||||
|
||||
s.metadata.update({"Meta2" => "MetaValue2"})
|
||||
|
||||
4. Set the metadata:
|
||||
|
||||
s.metadata.set({"Meta3" => "MetaValue3"})
|
||||
|
||||
5. Set the metadata explicitly:
|
||||
|
||||
m = myserver.metadata.new
|
||||
m.key = "Meta4"
|
||||
m.value = "Value4"
|
||||
m.save
|
||||
|
||||
6. Update the metadata:
|
||||
|
||||
m = s.metadata.get("Meta1")
|
||||
m.value = "MetaUpdValue1"
|
||||
m.save
|
||||
|
||||
7. List metadata:
|
||||
|
||||
s.metadata.all
|
||||
|
||||
8. Delete metadata:
|
||||
|
||||
m = s.metadata.get("Meta3").destroy
|
||||
|
||||
## Model Flavor Operations
|
||||
|
||||
1. List all available flavors:
|
||||
|
||||
flavors = conn.flavors.all
|
||||
flavors.size # returns no. of flavors
|
||||
# display flavors in a tabular format
|
||||
conn.flavors.table([:id, :name, :ram, :disk])
|
||||
|
||||
2. List flavors using a filter:
|
||||
|
||||
flavors = conn.flavors.all(:limit => 2)
|
||||
|
||||
3. Obtain the details of a particular flavor:
|
||||
|
||||
flavor = conn.flavors.get("<flavor_id>") # get the flavor
|
||||
flavor.name # returns the name of the flavor eg: m1.tiny, m1.small etc.
|
||||
flavor.ram # returns the ram memory in bytes for the flavor, eg: 4096
|
||||
flavor.disk # returns the disk size in GB for the flavor, eg: 80
|
||||
flavor.cores # returns no. of cores for the flavor, eg: 0.25
|
||||
|
||||
## Model Image Operations
|
||||
|
||||
1. List all available images:
|
||||
|
||||
images = conn.images
|
||||
images.size # returns no. of images
|
||||
# display images in a tabular format
|
||||
conn.images.table([:id, :name, :status, :created_at])
|
||||
|
||||
2. Obtain the details of a particular image:
|
||||
|
||||
image = conn.images.get("<image_id>") # get the image
|
||||
image.name # returns name of the image
|
||||
image.created_at # returns the date the image was created
|
||||
image.status # returns the state of the image e.g. ACTIVE
|
||||
|
||||
3. Create a new snapshot image based on an existing server:
|
||||
|
||||
# first, get a server
|
||||
server = conn.servers.get("<server_id>")
|
||||
s.create_image("My Image")
|
||||
|
||||
4. Delete an existing snapshot image:
|
||||
|
||||
image = conn.images.get("<image_id>").destroy
|
||||
|
||||
## Model Image Metadata Operations
|
||||
|
||||
1. Create an image snapshot with some metadata:
|
||||
|
||||
myserver.create_image("My Image", {"ImgMeta1" => "ImgMeta1Value"})
|
||||
|
||||
2. Get the metadata item:
|
||||
|
||||
image = conn.images.get("<image_id>")
|
||||
image.metadata.set({"Meta3" => "MetaValue3"})
|
||||
|
||||
3. Update the metadata:
|
||||
|
||||
image.metadata.update({"Meta2" => "MetaValue2"})
|
||||
|
||||
4. Set the metadata:
|
||||
|
||||
image.metadata.set({"Meta3" => "MetaValue3"})
|
||||
|
||||
5. Set the metadata explicitly:
|
||||
|
||||
m = image.metadata.set("Meta1")
|
||||
m.value = "MetaUpValue1"
|
||||
m.save
|
||||
|
||||
6. Update the metadata:
|
||||
|
||||
m = myimage.metadata.get("ImgMeta3")
|
||||
m.value = "ImgUpdValue3"
|
||||
m.save
|
||||
|
||||
7. List metadata:
|
||||
|
||||
myimage.metadata.all
|
||||
|
||||
8. Delete metadata:
|
||||
|
||||
m = image.metadata.get("ImgMeta3").destroy
|
||||
|
||||
## Model Keypair Operations
|
||||
|
||||
1. List all available keypairs:
|
||||
|
||||
keypairs = conn.key_pairs
|
||||
keypairs.size # returns no. of keypairs
|
||||
# display keypairs in a tabular format
|
||||
conn.key_pairs.table([:name, :public_key])
|
||||
|
||||
2. Obtain the details of a particular keypair:
|
||||
|
||||
keypair = conn.key_pairs.get(key_name) # get the keypair
|
||||
keypair.name # returns name of the keypair
|
||||
keypair.public_key # returns the public key of the keypair
|
||||
# NOTE: Due to security considerations, the private key is not available on subsequent gets
|
||||
keypair.private_key # => nil
|
||||
|
||||
3. Create a new keypair:
|
||||
|
||||
keypair = conn.key_pairs.create(:name => "mykey")
|
||||
keypair.name # returns name of the keypair
|
||||
keypair.public_key # returns the public key of the keypair
|
||||
keypair.private_key # returns the private key of the keypair
|
||||
**Note**: Keypairs with a dot (.) are not allowed.
|
||||
|
||||
4. Export a keypair to a file:
|
||||
|
||||
keypair = conn.key_pairs.create(:name => "mykey2")
|
||||
keypair.write # => "Key file built: /Users/xxxxx/.ssh/mykey2.pem"
|
||||
|
||||
# Alternatively, you can pass in a path to export the key
|
||||
keypair.write("/Users/xxxxx/Downloads/mykey2.pem")
|
||||
|
||||
5. Import a public key to create a new keypair:
|
||||
|
||||
keypair = conn.key_pairs.create(:name => "mykey", :public_key => "public key material")
|
||||
keypair.name # returns name of the keypair
|
||||
|
||||
6. Delete an existing keypair:
|
||||
|
||||
keypair = conn.key_pairs.get(key_name)
|
||||
keypair.destroy
|
||||
|
||||
## Model Address Operations
|
||||
|
||||
1. List all public and private ip addresses for a server:
|
||||
|
||||
address = conn.addresses
|
||||
|
||||
2. Obtain the details of a particular address:
|
||||
|
||||
address = conn.addresses.get("<address_id>") # get the address
|
||||
address.ip # returns the ip address
|
||||
|
||||
3. Create or allocate a new address:
|
||||
|
||||
address = conn.addresses.create # allocates an ip address from the pool
|
||||
address.ip # returns the ip address
|
||||
|
||||
4. Associate a server to an existing address:
|
||||
|
||||
server = conn.servers.get("<server_id>") # get the server
|
||||
address = conn.addresses.get("<address_id>") # get the address
|
||||
address.server = server # associate the server
|
||||
address.reload
|
||||
|
||||
5. Disassociate a server from an existing address:
|
||||
|
||||
address = conn.addresses.get("<address_id>") # get the address
|
||||
address.server = nil # disassociate the server
|
||||
address.instance_id # => nil
|
||||
|
||||
6. Delete (release) an existing address:
|
||||
|
||||
server = conn.servers.get("<server_id>") # get the server
|
||||
address = conn.addresses.get("<address_id>") # get the address
|
||||
address.server = nil # disassociate the server
|
||||
address.reload
|
||||
|
||||
7. Release an address back into the IP pool:
|
||||
|
||||
address = conn.addresses.get("<address_id>").destroy
|
||||
=> true
|
||||
|
||||
## Request Server Operations
|
||||
|
||||
1. List all available servers for an account:
|
||||
|
||||
response = conn.list_servers
|
||||
response.body['servers'] # returns an array of server hashes
|
||||
response.headers # returns the headers
|
||||
response.body['servers'][0]['name'] # returns the name of the server
|
||||
|
||||
2. List all available servers using a filter:
|
||||
|
||||
response = conn.list_servers_detail(:name => 'My Shiny Server')
|
||||
|
||||
3. List all available servers with additional details:
|
||||
|
||||
response = conn.list_servers_detail
|
||||
response.body['servers'] # returns an array of server hashes
|
||||
response.body['servers'][0]['name'] # returns the name of the server
|
||||
|
||||
4. Obtain the details of a particular server:
|
||||
|
||||
response = conn.get_server_details("<server_id>")
|
||||
server = response.body['server']
|
||||
server['name'] # returns the name of the server
|
||||
server['flavor'] # returns the flavor used to create the server
|
||||
server['image'] # returns the image used to create the server
|
||||
server['addresses'] # returns the public and private addresses
|
||||
server['status'] # returns the state of the server e.g. ACTIVE
|
||||
|
||||
5. Create a new server:
|
||||
|
||||
response = conn.create_server(
|
||||
"My Shiny Server",
|
||||
flavor_id,
|
||||
image_id,
|
||||
{
|
||||
'availability_zone' => "az2"
|
||||
}
|
||||
{
|
||||
'security_groups' => ["SecGroup1, SecGroup2"],
|
||||
'key_name' => "MyKeyPair1"
|
||||
}
|
||||
)
|
||||
server = response.body['server']
|
||||
server['id'] # returns the id of the new server
|
||||
server['name'] # => "My Shiny Server"
|
||||
server['status'] # returns the state of the server e.g. BUILD
|
||||
|
||||
6. Create a server by passing in a keypair and security group:
|
||||
|
||||
response = conn.create_server(
|
||||
"My Shiny Server",
|
||||
101,
|
||||
image_id,
|
||||
{
|
||||
'key_name' => "MyKeyPair1",
|
||||
'security_groups' => ["SecGroup1, SecGroup2"],
|
||||
}
|
||||
)
|
||||
server = response.body['server']
|
||||
server['id'] # returns the id of the new server
|
||||
server['name'] # => "My Shiny Server"
|
||||
server['status'] # returns the state of the server e.g. BUILD
|
||||
|
||||
7. Create a server by passing in a network:
|
||||
|
||||
response = conn.create_server(
|
||||
"My Shiny Server",
|
||||
101,
|
||||
image_id,
|
||||
{
|
||||
'networks' => ["My Network"]
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
8. Create a new Windows server and retrieve the encrypted password:
|
||||
|
||||
# Make sure to use a Windows image
|
||||
response = conn.create_server("My Windows Server", "<flavor_id>", "<image_id>")
|
||||
win_server = response.body['server']
|
||||
server_id = win_server['id'] # returns the id of the new server
|
||||
# Retrieve the encrypted password
|
||||
conn.get_windows_password("<server_id>")
|
||||
# => "Im6ZJ8auyMRnkJ24KKWQvTgWDug1s ... y0uY1BcHLJ5OrkEPHhQoQntIKOoQ=\n"
|
||||
**Note**: You must retrieve the Windows password immediately after you create the Windows instance. Also, make sure you have a security rule defined to open RDP port 3389 so that you can connect to the Windows server.
|
||||
|
||||
9. Create a new Linux-based persistent server with a bootable volume
|
||||
|
||||
conn.create_persistent_server(
|
||||
"MyBootableServer",
|
||||
103,
|
||||
[{ "volume_size"=>"", # ignored
|
||||
"volume_id"=>"65904",
|
||||
"delete_on_termination"=>"0",
|
||||
"device_name"=>"vda"
|
||||
}] ,
|
||||
{
|
||||
'security_groups' => ["mysecgroup"],
|
||||
'key_name' => "mykey"
|
||||
}
|
||||
)
|
||||
**Note**: In *block_device_mapping*, *volume_size* is ignored; it is automatically retrieved from the specified bootable volume. To delete the bootable volume after the server instance is killed you can set *delete_on_termination* to `1`. To preserve the bootable volume, set it to `0` as shown above.
|
||||
|
||||
10. Create a new Linux-based server with advanced personalisation options:
|
||||
|
||||
response = conn.create_server(
|
||||
"My Shiny Server",
|
||||
flavor_id,
|
||||
image_id,
|
||||
{
|
||||
'security_groups' => ["SecGroup1, SecGroup2"],
|
||||
'key_name' => "MyKeyPair1",
|
||||
'config_drive' => true,
|
||||
'user_data_encoded' => ["This is some encoded user data"].pack('m'),
|
||||
'personality' => [{
|
||||
'contents' => File.read("/path/to/sample.txt"),
|
||||
'path' => "/path/to/sample.txt"
|
||||
}]
|
||||
}
|
||||
)
|
||||
server = response.body['server']
|
||||
server['id'] # returns the id of the new server
|
||||
|
||||
The personalization options are:
|
||||
|
||||
*config_drive*
|
||||
: Disk accessible to the server that contains a FAT filesystem. If `config_drive` parameter is set to `true` at the time of server creation, the configuration drive is created.
|
||||
|
||||
*user_data_encoded*
|
||||
: Allows additional metadata to be inserted during server creation by supplying a Base64-encoded string in the `user_data_encoded` parameter.
|
||||
|
||||
*personality*
|
||||
: Allows files to be injected into the server instance after its creation. The file `contents` are Base64 encoded and injected into the location specified by `path`.
|
||||
|
||||
**Note**: The above personalization options are not supported on Windows server instances.
|
||||
|
||||
11. Update the name for a server:
|
||||
|
||||
address = conn.update_server("<server_id>", {'name' => "My Cool Server"})
|
||||
response = conn.get_server_details("<server_id>")
|
||||
response.body['server']['name'] # => "My Cool Server"
|
||||
|
||||
12. Reboot a server (SOFT):
|
||||
|
||||
address = conn.reboot_server("<server_id>", "SOFT")
|
||||
|
||||
13. Reboot a server (HARD):
|
||||
|
||||
address = conn.rebuild_server("<server_id>", "HARD")
|
||||
|
||||
14. Rebuild a server:
|
||||
|
||||
address = conn.reboot_server("<server_id>", "MyRebuiltServer")
|
||||
|
||||
15. List both public and private addresses of a particular server:
|
||||
|
||||
response = conn.list_server_addresses("<server_id>")
|
||||
|
||||
13. Display console output:
|
||||
|
||||
response = conn.get_console_output("<server_id>", 10)
|
||||
# => 10 lines of console output are returned
|
||||
|
||||
14. Get the VNC console for a server:
|
||||
|
||||
response = conn.get_vnc_console("<server_id>")
|
||||
# => Url to access the VNC console of a server from a browser
|
||||
|
||||
16. Delete an existing server:
|
||||
|
||||
conn.delete_server("<server_id>")
|
||||
|
||||
## Request Server Metadata Operations
|
||||
|
||||
1. Create a server and pass it some metadata at creation:
|
||||
|
||||
response = conn.create_server(
|
||||
"myserver", 1, 2,
|
||||
{'metadata' =>
|
||||
{'Meta1' => 'MetaValue1', 'Meta2' => 'MetaValue2'}
|
||||
}
|
||||
)
|
||||
response.body['server']['metadata']
|
||||
# => {"Meta1"=>"MetaValue1", "Meta2"=>"MetaValue2"}
|
||||
|
||||
2. List the existing metadata:
|
||||
|
||||
response = conn.list_metadata("servers", "<server_id>")
|
||||
response.body['metadata']
|
||||
# => {"Meta1"=>"MetaValue1", "Meta2"=>"MetaValue2"}
|
||||
|
||||
3. Set new values to the existing metadata:
|
||||
|
||||
response = conn.set_metadata("servers", "<server_id>", {"MetaNew1" => "MetaNewValue1"})
|
||||
response.body['metadata']
|
||||
# => {"MetaNew1"=>"MetaNewValue1"}
|
||||
|
||||
4. Update the existing metadata:
|
||||
|
||||
response = conn.update_metadata("servers", "<server_id>", {"Meta2" => "MetaValue2"})
|
||||
response.body['metadata']
|
||||
# => {"Meta2"=>"MetaValue2"}
|
||||
|
||||
5. Get a metadata item:
|
||||
|
||||
response = conn.get_meta("servers", "<server_id>", "Meta1")
|
||||
response.body['meta']
|
||||
# => {"Meta1"=>"MetaValue1"}
|
||||
|
||||
6. Set a new metadata item or update an existing metadata item:
|
||||
|
||||
response = conn.update_meta("servers", "<server_id>", "Meta1", "MetaUpdated1")
|
||||
response.body['meta']
|
||||
# => {"Meta1"=>"MetaUpdated1"}
|
||||
|
||||
7. Delete a metadata item:
|
||||
|
||||
conn.delete_meta("servers", "<server_id>", "Meta1")
|
||||
|
||||
## Request Flavor Operations
|
||||
|
||||
1. List all available flavors:
|
||||
|
||||
response = conn.list_flavors
|
||||
response.body['flavors'] # returns an array of flavor hashes
|
||||
response.headers # returns the headers for the flavors
|
||||
response.body['flavors'][0]['name'] # returns the name of the flavor
|
||||
|
||||
2. List all available flavors with additional details:
|
||||
|
||||
response = conn.list_flavors_detail
|
||||
response.body['flavors'] # returns an array of flavor hashes
|
||||
|
||||
3. Obtain the details of a particular flavor:
|
||||
|
||||
response = conn.get_flavor_details("<flavor_id>")
|
||||
flavor = response.body['flavor']
|
||||
flavor['name'] # returns the name of the flavor
|
||||
flavor['disk'] # returns the disk size of the flavor
|
||||
flavor['ram'] # returns the ram size of the flavor
|
||||
|
||||
## Request Image Operations
|
||||
|
||||
1. List all available images:
|
||||
|
||||
response = conn.list_images
|
||||
response.body['images'] # returns an array of image hashes
|
||||
response.headers # returns the headers for the images
|
||||
response.body['images'][0]['name'] # returns the name of the image
|
||||
|
||||
2. List all available images with additional details:
|
||||
|
||||
response = conn.list_images_detail
|
||||
response.body['images'] # returns an array of image hashes
|
||||
response.body['images'][0]['name'] # returns the name of the image
|
||||
|
||||
3. Obtain the details of a particular image:
|
||||
|
||||
response = conn.get_image_details("<image_id>")
|
||||
image = response.body['image']
|
||||
image['name'] # returns name of the image
|
||||
image['status'] # returns the state of the image e.g. ACTIVE
|
||||
image['created'] # returns the creation date of the image
|
||||
image['updated'] # returns the update date of the image
|
||||
|
||||
3. Create a new snapshot image based on an existing server:
|
||||
|
||||
conn.create_image("<server_id>", "My Image") # creates an snapshot image from the server referenced by "server_id"
|
||||
|
||||
4. Delete an existing snapshot image:
|
||||
|
||||
conn.delete_image("<image_id>")
|
||||
|
||||
## Request Image Metadata Operations
|
||||
|
||||
1. Create an image and pass it some metadata at creation:
|
||||
|
||||
conn.create_image("<server_id>", "myimage", {'Meta1' => 'MetaValue1', 'Meta2' => 'MetaValue2'})
|
||||
|
||||
2. List the existing metadata:
|
||||
|
||||
response = conn.list_metadata("images", "<image_id>")
|
||||
response.body['metadata']
|
||||
# => {"Meta1"=>"MetaValue1", "Meta2"=>"MetaValue2"}
|
||||
|
||||
3. Set new values to the existing metadata:
|
||||
|
||||
response = conn.set_metadata("images", "<image_id>", {"MetaNew1" => "MetaNewValue1"})
|
||||
response.body['metadata']
|
||||
# => {"MetaNew1"=>"MetaNewValue1"}
|
||||
|
||||
4. Update the existing metadata:
|
||||
|
||||
response = conn.update_metadata("images", "<image_id>", {"Meta2" => "MetaValue2"})
|
||||
response.body['metadata']
|
||||
# => {"Meta2"=>"MetaValue2"}
|
||||
|
||||
5. Get a metadata item:
|
||||
|
||||
response = conn.get_meta("images", "<image_id>", "Meta1")
|
||||
response.body['meta']
|
||||
# => {"Meta1"=>"MetaValue1"}
|
||||
|
||||
6. Update a metadata item:
|
||||
|
||||
response = conn.update_meta("images", "<image_id>", "Meta1", "MetaUpdated1")
|
||||
response.body['meta']
|
||||
# => {"Meta1"=>"MetaUpdated1"}
|
||||
|
||||
7. Delete a metadata item:
|
||||
|
||||
conn.delete_meta("images", "<image_id>", "Meta1")
|
||||
|
||||
## Request Keypair Operations
|
||||
|
||||
1. List all available keypairs:
|
||||
|
||||
response = conn.list_key_pairs
|
||||
response.body['keypairs'] # returns an array of keypair hashes
|
||||
response.headers # returns the headers
|
||||
response.body['keypairs'][0]['keypair']['name'] # returns the name of the keypair
|
||||
|
||||
2. Create a new keypair:
|
||||
|
||||
response = conn.create_key_pair("mykey")
|
||||
keypair = response.body['keypair']
|
||||
keypair['name'] # returns the name of the keypair
|
||||
keypair['public_key'] # returns the public key of the keypair
|
||||
keypair['private_key'] # returns the private key of the keypair
|
||||
|
||||
3. Obtain a keypair:
|
||||
|
||||
response = conn.get_key_pair("mykey")
|
||||
|
||||
|
||||
4. Import a public key to create a new keypair:
|
||||
|
||||
response = conn.create_key_pair("mykey", "public key material")
|
||||
keypair = response.body['keypair']
|
||||
keypair['name'] # returns the name of the keypair
|
||||
|
||||
4. Delete an existing keypair:
|
||||
|
||||
conn.delete_key_pair("<key_name>")
|
||||
|
||||
## Request Address Operations
|
||||
|
||||
1. List all available floating IP addresses:
|
||||
|
||||
response = conn.list_server_addresses
|
||||
response.body['addresses'] # returns an array of address hashes
|
||||
response.headers # returns the headers
|
||||
response.body['addresses'][0]['id'] # returns the id of the address
|
||||
|
||||
2. List addresses by network for a server:
|
||||
|
||||
response = conn.list_server_addresses_by_network("<address_id>") # get the address
|
||||
|
||||
3. Obtain the details of a particular address:
|
||||
|
||||
response = conn.get_address("<address_id>") # get the address
|
||||
response.body['address']['ip'] # returns the ip address
|
||||
|
||||
3. Create (allocate) a new address:
|
||||
|
||||
response = conn.allocate_address # allocates an ip address from the pool
|
||||
response.body['address']['ip'] # returns the ip address
|
||||
|
||||
4. Associate a server to an existing address:
|
||||
|
||||
conn.associate_address("<server_id>", "<ip_address>")
|
||||
|
||||
5. Disassociate a server from an existing address:
|
||||
|
||||
conn.disassociate_address("<server_id>", "<ip_address>")
|
||||
|
||||
6. Delete (release) an existing address:
|
||||
|
||||
conn.release_address("<address_id>") # releases the ip address to the pool
|
||||
|
||||
---------
|
||||
[Documentation Home](https://github.com/fog/fog/blob/master/lib/fog/hp/README.md) | [Examples](https://github.com/fog/fog/blob/master/lib/fog/hp/examples/getting_started_examples.md)
|
28
lib/fog/hp/examples/getting_started_examples.md
Executable file
28
lib/fog/hp/examples/getting_started_examples.md
Executable file
|
@ -0,0 +1,28 @@
|
|||
#Ruby Fog Bindings Examples for use with HP Cloud Services
|
||||
|
||||
This section includes code examples for working with Ruby Fog bindings and HP Cloud. HP Cloud recently updated their service to version 13.5, so make sure you use the HP Cloud Compute 13.5 examples, HP Cloud Block Storage 13.5, and the HP Cloud Networking examples only with the the latest version. The CDN and object storage examples work in both 12.12 and 13.5.
|
||||
|
||||
Choose what you want to work with:
|
||||
|
||||
##Version 12.12 Extensions to Ruby Fog Binding
|
||||
|
||||
These examples currently supports HP Cloud Compute, HP Cloud Object Storage, HP Cloud CDN, and HP Cloud Block Storage. Support for other services will be added as they become available.
|
||||
|
||||
* [Installation Instructions](/bindings/fog/install)
|
||||
* [Connecting to the Service](/bindings/fog/connect)
|
||||
* [Compute Examples](/bindings/fog/compute)
|
||||
* [Object Storage Examples](/bindings/fog/object-storage)
|
||||
* [CDN Examples](/bindings/fog/cdn)
|
||||
* [Block Storage Examples](/bindings/fog/block-storage)
|
||||
* [Release Notes](/bindings/fog/release-notes)
|
||||
* [FAQ](/faq#RubyFogBindings)
|
||||
|
||||
##Version 13.5 Extensions to Ruby Fog Binding
|
||||
|
||||
For the release of HP Cloud v13.5, the HP Cloud Ruby library added new examples for HP Cloud Networking and changes were made to the HP Cloud Compute and HP Cloud Block Storage examples. All other examples are compatible with v13.5.
|
||||
|
||||
* [Compute v2.0 Examples](/v13/bindings/fog/compute)
|
||||
* [Block Storage v2.0 Examples](/v13/bindings/fog/block-storage)
|
||||
* [Networking Examples](/v13/bindings/fog/networking)
|
||||
* Load Balancer Examples (coming soon)
|
||||
* DNS Examples (coming soon)
|
445
lib/fog/hp/examples/networking.md
Executable file
445
lib/fog/hp/examples/networking.md
Executable file
|
@ -0,0 +1,445 @@
|
|||
#Examples for working with HP Cloud Networking Service
|
||||
The HP Cloud provides networking support using two abstractions: a model layer and a request layer. Both layers are detailed below.
|
||||
|
||||
**Note:** The networking functionality works with HP Cloud version 13.5 but is not available in version 12.12.
|
||||
|
||||
The code samples on this page can be executed from within a Ruby console (IRB):
|
||||
|
||||
irb
|
||||
|
||||
This page discusses the following topics:
|
||||
|
||||
* [Connecting to the Service](https://github.com/fog/fog/blob/master/lib/fog/hp/docs/connect.md)
|
||||
|
||||
**Model Layer Examples**
|
||||
|
||||
* [Model Network Operations](#model-network-operations)
|
||||
* [Model Subnet Operations](#model-subnet-operations)
|
||||
* [Model Port Operations](#model-port-operations)
|
||||
* [Model Router Operations](#model-router-operations)
|
||||
* [Model Security Group Operations](#model-security-group-operations)
|
||||
* [Model Security Group Rules](#model-security-group-rules-operations)
|
||||
* [Model Floating IPs](#model-floating-ips-operations)
|
||||
|
||||
**Request Layer Examples**
|
||||
|
||||
* [Request Network Operations](#request-network-operations)
|
||||
* [Request Subnet Operations](#request-subnet-operations)
|
||||
* [Request Port Operations](#request-port-operations)
|
||||
* [Request Router Operations](#request-router-operations)
|
||||
* [Request Security Group Operations](#request-security-group-operations)
|
||||
* [Request Security Group Rules Operations](#request-security-group-rules-operations)
|
||||
* [Request Floating IPs Operations](#request-floating-ips-operations)
|
||||
|
||||
## Model Network Operations
|
||||
|
||||
1. List networks:
|
||||
|
||||
conn.networks
|
||||
|
||||
2. List network using a filter:
|
||||
|
||||
conn.networks.all({"router:external"=>true})
|
||||
|
||||
3. Obtain a network by ID:
|
||||
|
||||
conn.networks.get("<network_id>")
|
||||
|
||||
4. Create a network:
|
||||
|
||||
conn.networks.create(:name => "My Slick Network")
|
||||
|
||||
5. Delete a network:
|
||||
|
||||
conn.networks.get("<network_id>").destroy
|
||||
|
||||
## Model Subnet Operations
|
||||
|
||||
1. List subnets:
|
||||
|
||||
conn.subnets
|
||||
|
||||
2. List subnets using a filter:
|
||||
|
||||
conn.subnets.all({:gateway_ip => "12.0.0.1"})
|
||||
|
||||
3. Create a subnet:
|
||||
|
||||
conn.subnets.create(
|
||||
:network_id => "<network_id>",
|
||||
:cidr => "12.0.3.0/24",
|
||||
:ip_version => 4,
|
||||
:name => "My Subnet Model 1"
|
||||
)
|
||||
|
||||
4. Obtain a subnet by ID:
|
||||
|
||||
conn.subnets.get("<subnet_id>")
|
||||
|
||||
5. Assign a DNS server to a subnet:
|
||||
|
||||
subnet = conn.subnets.get("<subnet_id>")
|
||||
subnet.dns_nameservers = ["dns_ip"]
|
||||
subnet.save
|
||||
|
||||
6. Delete a subnet:
|
||||
|
||||
conn.subnets.get("<subnet_id>").destroy
|
||||
|
||||
## Model Port Operations
|
||||
|
||||
1. List ports:
|
||||
|
||||
conn.ports
|
||||
|
||||
2. List ports using a filter:
|
||||
|
||||
conn.ports.all({:mac_address => "<mac_address>"})
|
||||
|
||||
|
||||
3. Obtain a port by ID:
|
||||
|
||||
conn.ports.get("<port_id>")
|
||||
|
||||
4. Create a port:
|
||||
|
||||
conn.ports.create(
|
||||
:name => "Port Model 1",
|
||||
:network_id => "<network_id>"
|
||||
)
|
||||
|
||||
5. Delete a port:
|
||||
|
||||
conn.ports.get("<port_id>").destroy
|
||||
|
||||
## Model Router Operations
|
||||
|
||||
1. List routers:
|
||||
|
||||
conn.routers
|
||||
|
||||
2. List routers using a filter:
|
||||
|
||||
conn.routers.all({:name => "Router 1"})
|
||||
|
||||
3. Obtain a router by ID:
|
||||
|
||||
router = conn.routers.get("<router_id>")
|
||||
|
||||
4. Create a router:
|
||||
|
||||
router = conn.routers.create(
|
||||
:name => "Router Model 1",
|
||||
:admin_state_up => true
|
||||
)
|
||||
|
||||
5. Add a router interface using a subnet:
|
||||
|
||||
router.add_interface("<subnet_id>", nil)
|
||||
conn.ports # If you look at the ports, note that a new port is auto. created, the device_id is assigned to the router id, and the device_owner is updated
|
||||
|
||||
6. Remove a router interface using a subnet:
|
||||
|
||||
router.remove_interface("<subnet_id>", nil)
|
||||
# Removing the interface also deletes the auto-created port
|
||||
|
||||
7. Add a router interface using a port:
|
||||
|
||||
# Add a router interface using the port you created
|
||||
network = router.add_interface(nil, "<port_id>")
|
||||
|
||||
# Port is updated with device_id and device_owner
|
||||
conn.ports.get("<port_id>")
|
||||
|
||||
8. Remove a router interface using a port:
|
||||
|
||||
router.remove_interface(nil, "<port_id>")
|
||||
# after removing the interface, the associated port is deleted
|
||||
|
||||
9. Delete a router:
|
||||
|
||||
conn.routers.get("<router_id>").destroy
|
||||
|
||||
## Model Security Group Operations
|
||||
|
||||
1. List security groups:
|
||||
|
||||
conn.security_groups
|
||||
|
||||
2. List security groups using a filter:
|
||||
|
||||
conn.security_groups.all({:name => "My Security Group"})
|
||||
|
||||
3. Obtain a security group by ID:
|
||||
|
||||
conn.security_groups.get("<SecurityGroup_id>")
|
||||
|
||||
4. Create a security group:
|
||||
|
||||
conn.security_groups.create(
|
||||
:name => 'MySecurityGroup',
|
||||
:description => 'my security group description'
|
||||
)
|
||||
**Note:** Two security group rules are created by default for every new security group that is created: one 'ingress' and one 'egress' rule.
|
||||
|
||||
5. Delete a security group:
|
||||
|
||||
conn.security_groups.get("<SecurityGroup_id>").destroy
|
||||
|
||||
## Model Security Group Rules Operations
|
||||
|
||||
1. List security group rules:
|
||||
|
||||
conn.security_group_rules
|
||||
|
||||
2. List security group rules using a filter:
|
||||
|
||||
conn.security_group_rules.all({:direction => "ingress"})
|
||||
|
||||
3. Obtain a security group by ID:
|
||||
|
||||
conn.security_group_rules.get("<SecurityGroupRule_id>")
|
||||
|
||||
4. Create a security group rule:
|
||||
|
||||
conn.security_group_rules.create(
|
||||
:security_group_id => "<SecurityGroup_id>",
|
||||
:direction => 'ingress',
|
||||
:protocol => 'tcp',
|
||||
:port_range_min => 22,
|
||||
:port_range_max => 22,
|
||||
:remote_ip_prefix => '0.0.0.0/0'
|
||||
)
|
||||
|
||||
5. Delete a security group rule:
|
||||
|
||||
conn.security_group_rules.get("<SecurityGroupRule_id>").destroy
|
||||
|
||||
## Model Floating IPs Operations
|
||||
|
||||
1. List floating IPs:
|
||||
|
||||
conn.floating_ips
|
||||
|
||||
2. List floating IPs using a filter:
|
||||
|
||||
conn.floating_ips.all("fixed_ip_address" => "<ip address>")
|
||||
|
||||
3. Obtain a floating IP by ID:
|
||||
|
||||
conn.floating_ips.get("<FloatingIp_id>")
|
||||
|
||||
4. Create a floating IP:
|
||||
|
||||
conn.floating_ips.create(
|
||||
:floating_network_id => "<network_id>"
|
||||
)
|
||||
|
||||
5. Delete a floating IP:
|
||||
|
||||
conn.floating_ips.get("<FloatingIp_id>").destroy
|
||||
|
||||
|
||||
## Request Network Operations
|
||||
|
||||
1. List networks:
|
||||
|
||||
conn.list_networks
|
||||
|
||||
2. List networks using a filter:
|
||||
|
||||
conn.list_networks({"router:external" => true})
|
||||
|
||||
3. Obtain a network by ID:
|
||||
|
||||
conn.get_network("<network_id>")
|
||||
|
||||
4. Create a network:
|
||||
|
||||
conn.create_network({:name => "Network 1"})
|
||||
|
||||
5. Update a network:
|
||||
|
||||
conn.update_network("<network_id>", {:name => "Network 1"})
|
||||
|
||||
6. Delete a network:
|
||||
|
||||
conn.delete_network("<network_id>")
|
||||
|
||||
## Request Subnet Operations
|
||||
|
||||
1. List subnets:
|
||||
|
||||
conn.list_subnets
|
||||
|
||||
2. List subnets using a filter:
|
||||
|
||||
conn.list_subnets({"name"=>"My Subnet"})
|
||||
|
||||
3. Create a subnet:
|
||||
|
||||
conn.create_subnet("<network_id>", "11.0.3.0/24", 4, {:name => "My Subnet"})
|
||||
|
||||
4. Obtain a subnet by ID:
|
||||
|
||||
conn.get_subnet("<subnet_id>")
|
||||
|
||||
5. Update a subnet:
|
||||
|
||||
conn.update_subnet("<subnet_id>", {:name => My Subnet Upd"})
|
||||
|
||||
6. Assign a DNS server to a subnet:
|
||||
|
||||
conn.update_subnet("<subnet_id>", {:dns_nameservers => ["15.185.9.24"]})
|
||||
|
||||
7. Delete a subnet:
|
||||
|
||||
conn.delete_subnet("<subnet_id>")
|
||||
|
||||
## Request Port Operations
|
||||
|
||||
1. List ports:
|
||||
|
||||
conn.list_ports
|
||||
|
||||
2. List ports using a filter:
|
||||
|
||||
conn.list_ports({"router_id" => "<router_id>"})
|
||||
|
||||
3. Obtain a port by ID:
|
||||
|
||||
conn.get_port("<port_id>")
|
||||
|
||||
4. Create a port:
|
||||
|
||||
conn.create_port("<network_id>", {:name => "myport"})
|
||||
|
||||
5. Update a port:
|
||||
|
||||
conn.update_port("<port_id>", {:name => "My Port Upd"})
|
||||
|
||||
6. Delete a port:
|
||||
|
||||
conn.delete_port("<port_id>")
|
||||
|
||||
## Request Router Operations
|
||||
|
||||
1. List routers:
|
||||
|
||||
conn.list_routers
|
||||
|
||||
2. List routers using a filter:
|
||||
|
||||
conn.list_routers({"name"=>"My Router"})
|
||||
|
||||
3. Obtain a router:
|
||||
|
||||
conn.get_router("<router_id>")
|
||||
|
||||
4. Create a router:
|
||||
|
||||
conn.create_router({:name => 'My Router'})
|
||||
|
||||
5. Update a router:
|
||||
|
||||
conn.update_router("<router_id>" {:name => 'My Router Updates'})
|
||||
|
||||
6. Add a router interface using a subnet:
|
||||
|
||||
conn.add_router_interface("<router_id>", "<subnet_id>")
|
||||
|
||||
7. Remove a router interface using a subnet:
|
||||
|
||||
conn.remove_router_interface("<router_id>", "<subnet_id>")
|
||||
# Removes a port with no name using the subnet_id
|
||||
|
||||
8. Add a router interface using a port:
|
||||
|
||||
conn.add_router_interface("<router_id>", nil, "<port_id>")
|
||||
|
||||
**Note:** Updates the router_id and device_owner for this port.
|
||||
|
||||
9. Remove a router interface using a port:
|
||||
|
||||
conn.remove_router_interface("router_id", nil, "port_id")
|
||||
|
||||
10. Delete a router:
|
||||
|
||||
conn.delete_router("<router_id>")
|
||||
|
||||
## Request Security Group Operations
|
||||
|
||||
1. List security groups:
|
||||
|
||||
conn.list_security_groups
|
||||
|
||||
2. List security groups using a filter:
|
||||
|
||||
conn.list_security_groups({:name => "My Security Group"})
|
||||
|
||||
3. Obtain a security group by ID:
|
||||
|
||||
conn.get_security_group("<security_group_id>")
|
||||
|
||||
4. Create a security group:
|
||||
|
||||
conn.create_security_group(
|
||||
:name => "My Security Group",
|
||||
:description => "What my security group does."
|
||||
)
|
||||
|
||||
5. Delete a security group:
|
||||
|
||||
conn.delete_security_group("<security_group_id>")
|
||||
|
||||
## Request Security Group Rules Operations
|
||||
|
||||
1. List security group rules:
|
||||
|
||||
conn.list_security_group_rules
|
||||
|
||||
2. List security group rules using a filter:
|
||||
|
||||
conn.list_security_group_rules({:direction => 'egress'})
|
||||
|
||||
3. Obtain a security group rule by ID:
|
||||
|
||||
conn.get_security_group_rule("<rule_id>")
|
||||
|
||||
4. Create a security group rule:
|
||||
|
||||
conn.create_security_group_rule("<security_group_id>", 'ingress',{
|
||||
:remote_ip_prefix => ""0.0.0.0/0",
|
||||
:protocol => "tcp",
|
||||
:port_range_min => 22,
|
||||
:port_range_max => 22
|
||||
})
|
||||
|
||||
5. Delete a security group rule:
|
||||
|
||||
conn.delete_security_group_rule("<rule_id>")
|
||||
|
||||
## Request Floating IPs Operations
|
||||
|
||||
1. List floating IPs:
|
||||
|
||||
conn.list_floating_ips
|
||||
|
||||
2. List floating IPs using a filter:
|
||||
|
||||
conn.list_floating_ips("fixed_ip_address" => "11.0.3.5")
|
||||
|
||||
3. Obtain a floating IP by ID:
|
||||
|
||||
conn.get_floating_ip("<FloatingIp_id>")
|
||||
|
||||
4. Create a floating IP:
|
||||
|
||||
conn.create_floating_ip("<FloatingIp_id>")
|
||||
|
||||
5. Delete a floating IP:
|
||||
|
||||
conn.delete_floating_IP("<FloatingIp_id>")
|
||||
|
||||
---------
|
||||
[Documentation Home](https://github.com/fog/fog/blob/master/lib/fog/hp/README.md) | [Examples](https://github.com/fog/fog/blob/master/lib/fog/hp/examples/getting_started_examples.md)
|
387
lib/fog/hp/examples/object_storage.md
Executable file
387
lib/fog/hp/examples/object_storage.md
Executable file
|
@ -0,0 +1,387 @@
|
|||
# Examples for working with HP Cloud Object Storage Service
|
||||
|
||||
The HP Cloud Extensions to Ruby Fog libary provides Object Storage services support using two abstractions: a model layer and a request layer. Executing commands in both layers are detailed in this page.
|
||||
|
||||
The examples on this page can be executed from within a Ruby console (IRB):
|
||||
|
||||
irb
|
||||
|
||||
This page discusses the following topics:
|
||||
|
||||
* [Connecting to the Service](https://github.com/fog/fog/blob/master/lib/fog/hp/docs/connect.md)
|
||||
* [Using the Model Abstraction](#using-the-model-abstraction)
|
||||
* [Using the Request Abstraction](#using-the-request-abstraction)
|
||||
|
||||
|
||||
## Using the Model Abstraction
|
||||
|
||||
1. List all directories/containers for the given account
|
||||
|
||||
dirs = conn.directories
|
||||
dirs.size # returns no. of directories
|
||||
|
||||
2. Create a new directory/container
|
||||
|
||||
conn.directories.create(:key => "fog-rocks")
|
||||
|
||||
3. View a directory/container
|
||||
|
||||
dir = conn.directories.get("fog-rocks")
|
||||
dir.key # => fog-rocks
|
||||
|
||||
4. Apply ACLs on an existing directory/container
|
||||
|
||||
dir = conn.directories.get("fog-rocks")
|
||||
dir.public = true
|
||||
dir.save
|
||||
dir.public? # => true
|
||||
dir.public = false # toggles between "private" and "public-read" acl on a directory
|
||||
dir.save
|
||||
dir.public? # => false
|
||||
|
||||
5. Create a new file/object into an existing directory/container
|
||||
|
||||
dir = conn.directories.get("fog-rocks")
|
||||
dir.files.create(:key => "sample.txt", :body => File.open("/path/to/sample.txt"))
|
||||
|
||||
6. View a file/object from an existing directory/container
|
||||
|
||||
dir = conn.directories.get("fog-rocks")
|
||||
file = dir.files.get("sample.txt")
|
||||
file.key # => sample.txt
|
||||
|
||||
7. Copy a file/object into an existing directory/container
|
||||
|
||||
file = conn.directories.get("fog-rocks").files.get("sample.txt")
|
||||
other_file = file.copy("fog-rocks", "another-sample.txt")
|
||||
other_file.key # => another-sample.txt
|
||||
|
||||
8. View the files/objects for a directory/container
|
||||
|
||||
dir = conn.directories.get("fog-rocks")
|
||||
files = dir.files
|
||||
files.directory.key # => fog-rocks
|
||||
files.size # returns no. of files
|
||||
files[0].key # key of the file in collection
|
||||
files[0].content_length # content length of file
|
||||
files[0].last_modified # last modified date in UTC
|
||||
|
||||
9. Generate a temporary URL for a file or object for sharing purposes
|
||||
|
||||
dir = conn.directories.get("fog-rocks")
|
||||
file = dir.files.get("sample.txt")
|
||||
# creates a TempUrl to access sample.txt and access expires in 240 secs
|
||||
file.temp_signed_url(240, "GET")
|
||||
|
||||
10. Delete a file/object from an existing directory/container
|
||||
|
||||
dir = conn.directories.get("fog-rocks")
|
||||
file = dir.files.get("sample.txt")
|
||||
file.destroy
|
||||
# chaining a series of calls to delete a file
|
||||
conn.directories.get("fog-rocks").files.get("another-sample.txt").destroy
|
||||
|
||||
11. Delete an existing directory/container
|
||||
|
||||
# Note: directory needs to be empty before it can be deleted!
|
||||
conn.directories.get("fog-rocks").destroy
|
||||
|
||||
**Note**: You cannot use the create, update, or delete operations on a shared container.
|
||||
|
||||
### About using object ACLs
|
||||
|
||||
Object ACLs allow you to share containers and objects with other registered HP Public Cloud users. The owner of a container or object can grant read, write, read/write access to other users. The shared containers and objects can then be accessed based on the permissions granted by the owner.
|
||||
|
||||
### Using the object ACLs to grant access
|
||||
|
||||
To grant access to an object or a container:
|
||||
|
||||
mydir = conn.directories.get('rgtest2') # grant uses username
|
||||
mydir.grant("rw", ["someuser"])
|
||||
mydir.save # share the url for access to container
|
||||
mydir.public_url
|
||||
# => "https://objects.xxxx.hpcloud.net:443/v1/1111111/rgtest2"
|
||||
|
||||
myfile = mydir.files.get("sample.txt") # share the url for access to object
|
||||
myfile.public_url
|
||||
# => "https://objects.xxxx.hpcloud.net:443/v1/1111111/rgtest2/sample.txt"
|
||||
|
||||
### Using the object ACLs to access shared objects
|
||||
|
||||
1. Use the shared URLs to get the contents of a shared container:
|
||||
|
||||
sd = conn.shared_directories.get(mydir.public_url)
|
||||
sd.url
|
||||
# => "https://objects.xxxx.hpcloud.net:443/v1/1111111/rgtest2"
|
||||
sd.files
|
||||
|
||||
**Note**: If the grantee does not have access, the system generates an exception of type `Fog::HP::Errors::Forbidden`.
|
||||
|
||||
2. Use the shared URLs to get the metadata for a container:
|
||||
|
||||
sd = conn.shared_directories.head(mydir.public_url)
|
||||
|
||||
**Note**: If the grantee does not have access, the system generates an exception of type `Fog::HP::Errors::Forbidden`.
|
||||
|
||||
3. Use the shared URLs to get the contents of a shared object:
|
||||
|
||||
sd = conn.shared_directories.get(mydir.public_url)
|
||||
sf = sd.files.get('sample.txt')
|
||||
|
||||
4. Use the shared URLs to get the metadata for a shared object:
|
||||
|
||||
sd = conn.shared_directories.get(mydir.public_url)
|
||||
sf = sd.files.head('sample.txt')
|
||||
|
||||
5. Use the shared URLs to put a new object or file into a shared container:
|
||||
|
||||
sd = conn.shared_directories.get(mydir.public_url)
|
||||
sf = sd.files.create(:key => 'tiny2.txt', :body => "This is another text file.")
|
||||
|
||||
**Note**: If the grantee does not have access, the system generates an exception of type `Fog::HP::Errors::Forbidden`.
|
||||
|
||||
6. Use the shared URLs to update an existing object or file in a shared container:
|
||||
|
||||
sd = conn.shared_directories.get(mydir.public_url)
|
||||
sf = sd.files.new(:key => 'sample.txt')
|
||||
sf.body = "This is another text file."
|
||||
sf.save
|
||||
|
||||
**Note**: If the grantee does not have access, the system generates an exception of type `Fog::HP::Errors::Forbidden`.
|
||||
|
||||
7. Use the shared URLs to delete an existing object or file from a shared container:
|
||||
|
||||
sd = conn.shared_directories.get(mydir.public_url)
|
||||
sd.destroy
|
||||
|
||||
### Synchronize containers across regions
|
||||
|
||||
Synchronizing containers creates a one-way association from containers to the sync objects. The sync operation is performed by a background process on the container server. You must perform a one-time setup to set the metadata on the containers for syncing.
|
||||
|
||||
1. One-Way sync of containers (from source to target only):
|
||||
|
||||
# create source and target containers
|
||||
conn.directories.create(:key => 'imp_stuff')
|
||||
conn.directories.create(:key => 'sync_archive')
|
||||
dir = conn.directories.get('imp_stuff')
|
||||
target_dir = conn.directories.get('sync_archive')
|
||||
|
||||
# create some objects in the source container
|
||||
dir.files.create(:key => 'imp_1.txt', :body => "This is a small file but it is very important.")
|
||||
dir.files.create(:key => 'imp_2.txt', :body => "This is another small file but it is very important as well.")
|
||||
|
||||
# sync the source -> target
|
||||
dir.sync(target_dir, "boogieman") # => true
|
||||
dir.save # => true
|
||||
|
||||
2. Two-Way sync of containers (from source to target and back):
|
||||
|
||||
# Now, lets do a two way sync between dir and target containers
|
||||
dir = conn.directories.get('imp_stuff')
|
||||
target_dir = conn.directories.get('sync_archive')
|
||||
|
||||
# sync the target -> source
|
||||
target_dir.sync(dir, "boogieman") # => true
|
||||
target_dir.save # => true
|
||||
|
||||
3. One and two-way sync of containers across regions:
|
||||
|
||||
# assuming source container exists in region-a
|
||||
dir_a = conn.directories.get('imp_stuff') # Note: conn points to region-a
|
||||
# assuming target container exists in region-a
|
||||
target_dir_b = conn2.directories.get('arch_imp_stuff') # Note: conn2 points to region-b
|
||||
|
||||
# sync the source -> target
|
||||
dir_a.sync(target_dir_b, "boogieman") # => true
|
||||
dir_a.save # => true
|
||||
|
||||
# sync the target -> source
|
||||
target_dir_b.sync(dir_a, "boogieman") # => true
|
||||
target_dir_b.save #=> true
|
||||
|
||||
|
||||
## Using the Request Abstraction
|
||||
|
||||
1. List all container for the given account:
|
||||
|
||||
response = conn.get_containers
|
||||
response.body # returns an array of container hash objects
|
||||
response.body[0]["name"] # returns the name of the container
|
||||
response.body[0]["count"] # returns the number of objects in the container
|
||||
response.body[0]["bytes"] # returns the total bytes for the objects in the container
|
||||
|
||||
2. Create a new container:
|
||||
|
||||
container = conn.put_container("fog-rocks") # creates the container
|
||||
container.headers # returns a hash of headers
|
||||
container.headers["Content-Length"] # returns the content-length
|
||||
|
||||
3. View a container:
|
||||
|
||||
container = conn.get_container("fog-rocks")
|
||||
container.body # returns an array of objects hash
|
||||
container.body[0]['name'] # returns the name of the object
|
||||
container.headers # returns a hash of headers
|
||||
container.headers["Content-Length"] # returns the content-length
|
||||
container.headers["Content-Type"] # returns the content-type
|
||||
container.headers["X-Container-Object-Count"] # returns the number of objects in the container
|
||||
container.headers["X-Container-Bytes-Used"] # returns the total bytes for the objects in the container
|
||||
container.status # HTTP status code for the operation
|
||||
|
||||
4. View the container's headers and metadata without getting the content:
|
||||
|
||||
container = conn.head_container("fog-rocks")
|
||||
container.body # returns an empty body
|
||||
container.headers # returns a hash of headers
|
||||
container.headers["Content-Length"] # returns the content-length
|
||||
container.headers["Content-Type"] # returns the content-type
|
||||
container.status # HTTP status code for the operation
|
||||
|
||||
5. Create a new file into an existing container:
|
||||
|
||||
file = conn.put_object("fog-rocks", "sample.txt", File.open('/path/to/file/sample.txt'))
|
||||
file.headers # returns a hash of headers
|
||||
file.headers["Content-Length"] # returns the content-length
|
||||
|
||||
6. View a file from an existing container:
|
||||
|
||||
file = conn.get_object("fog-rocks", "sample.txt")
|
||||
file.body # returns the contents of the file
|
||||
file.headers # returns a hash of headers
|
||||
file.headers["Content-Length"] # returns the content-length
|
||||
file.headers["Content-Type"] # returns the content-type
|
||||
file.status # HTTP status code for the operation
|
||||
|
||||
7. View the file's headers and metadata without getting the content:
|
||||
|
||||
file = conn.head_object("fog-rocks", "sample.txt")
|
||||
file.body # returns the empty body
|
||||
file.headers # returns a hash of headers
|
||||
file.headers["Content-Length"] # returns the content-length
|
||||
file.headers["Content-Type"] # returns the content-type
|
||||
file.status # HTTP status code for the operation
|
||||
|
||||
8. Copy a file within the same container:
|
||||
|
||||
# copy an object
|
||||
conn.put_object("fog-rocks", "another-sample.txt", nil, {'X-Copy-From' => "/fog-rocks/sample.txt" })
|
||||
# get the copied object
|
||||
other_file = conn.get_object("fog-rocks", "another-sample.txt")
|
||||
other_file.headers # returns a hash of headers
|
||||
other_file.headers["Content-Length"] # returns the content-length
|
||||
|
||||
9. Copy a file from one container to another container:
|
||||
|
||||
# create a new container
|
||||
conn.put_container("fog-rocks-2") # creates the other new container
|
||||
# copy the object
|
||||
conn.put_object("fog-rocks-2", "sample.txt", nil, {'X-Copy-From' => "/fog-rocks/sample.txt" })
|
||||
# get the copied object
|
||||
other_file = conn.get_object("fog-rocks-2", "sample.txt")
|
||||
other_file.headers # returns a hash of headers
|
||||
other_file.headers["Content-Length"] # returns the content-length
|
||||
|
||||
10. Generate a temporary URL for a file or object for sharing purposes:
|
||||
|
||||
# creates a TempUrl to access sample.txt and access expires in 240 secs
|
||||
conn.get_object_temp_url("fog-rocks", "sample.txt", 240, "GET")
|
||||
|
||||
11. Delete a file from an existing container:
|
||||
|
||||
conn.delete_object("fog-rocks", "sample.txt")
|
||||
conn.delete_object("fog-rocks", "another-sample.txt")
|
||||
|
||||
12. Delete an existing container:
|
||||
|
||||
# Note: a container needs to be empty before it can be deleted!
|
||||
conn.delete_container("fog-rocks")
|
||||
|
||||
### Using Object ACLs
|
||||
|
||||
To use object ACLs in the request abstraction layer, you need to have already been granted permission to access the objects or containers. (See the section on [Using Object ACLs](#UsingObjectACLsModelLayer) in the Model Layer section above for information on granting access.)
|
||||
|
||||
1. Use the shared URLs to get the contents of a shared container:
|
||||
|
||||
conn.get_shared_container(mydir.public_url)
|
||||
|
||||
**Note**: If the grantee does not have access, the system generates an exception of type `Fog::HP::Errors::Forbidden`.
|
||||
|
||||
2. Use the shared URLs to get the metadata of a shared container:
|
||||
|
||||
conn.head_shared_container(mydir.public_url)
|
||||
|
||||
**Note**: If the grantee does not have access, the system generates an exception of type `Fog::HP::Errors::Forbidden`.
|
||||
|
||||
3. Use the shared URLs to get the contents of a shared object:
|
||||
|
||||
conn.get_shared_object(myfile.public_url)
|
||||
|
||||
4. Use the shared URLs to get the metadata for a shared object
|
||||
|
||||
conn.head_shared_object(myfile.public_url)
|
||||
|
||||
5. Use the shared URLs to put a new object or file into a shared container:
|
||||
|
||||
conn.put_shared_object(mydir.public_url, 'tiny.txt', File.read('tiny.txt'))
|
||||
|
||||
**Note**: If the grantee does not have access, the system generates an exception of type `Fog::HP::Errors::Forbidden`.
|
||||
|
||||
6. Use the shared URLs to update an existing object or file in a shared container:
|
||||
|
||||
conn.put_shared_object(mydir.public_url, 'sample.txt', "This text needed some update.")
|
||||
|
||||
**Note**: If the grantee does not have access, the system generates an exception of type `Fog::HP::Errors::Forbidden`.
|
||||
|
||||
7. Use the shared URLs to delete an existing object or file from a shared container:
|
||||
|
||||
conn.delete_shared_object(myfile.public_url)
|
||||
|
||||
### Synchronize containers across regions
|
||||
|
||||
Synchronizing containers creates a one-way association from containers to the sync objects. The sync operation is performed by a background process on the container server. You must perform a one-time setup to set the metadata on the containers for syncing.
|
||||
|
||||
1. One-Way sync of containers (from source to target only):
|
||||
|
||||
# create source and target containers
|
||||
conn.put_container('imp_stuff')
|
||||
conn.put_container('sync_archive')
|
||||
|
||||
# create some objects in the source container
|
||||
conn.put_object('imp_stuff', 'imp_1.txt', "This is a small file but it is very important.")
|
||||
conn.put_object('imp_stuff', 'imp_2.txt', File.open('/path/to/file/imp_2.txt'))
|
||||
|
||||
# to sync we need to put some metadata on the source and target containers
|
||||
conn.put_container('imp_stuff',
|
||||
{'X-Container-Sync-To' => "/url/to/the/target/sync_archive",
|
||||
'X-Container-Sync-Key' => 'boogieman'})
|
||||
conn.put_container('sync_archive',
|
||||
{'X-Container-Sync-Key' => 'boogieman'})
|
||||
|
||||
2. Two-Way sync of containers (from source to target and visa-versa):
|
||||
|
||||
# Now, lets do a two way sync between dir and target containers
|
||||
# to sync we need to put some metadata on the source and target containers
|
||||
conn.put_container('imp_stuff',
|
||||
{'X-Container-Sync-To' => "/url/to/the/target/sync_archive",
|
||||
'X-Container-Sync-Key' => 'boogieman'})
|
||||
conn.put_container('sync_archive',
|
||||
{'X-Container-Sync-To' => "/url/to/the/source/imp_stuff",
|
||||
'X-Container-Sync-Key' => 'boogieman'})
|
||||
|
||||
3. One and two-way sync of containers across regions:
|
||||
|
||||
# assuming source container exists in region-a
|
||||
conn.get_container('imp_stuff') # Note: conn points to region-a
|
||||
# create a new container in region-b
|
||||
conn2.put_container('arch_imp_stuff') # Note: conn2 points to region-b
|
||||
|
||||
# to sync we need to put some metadata on the source and target containers
|
||||
conn.put_container('imp_stuff',
|
||||
{'X-Container-Sync-To' => "/region-b/url/to/the/target/arch_imp_stuff",
|
||||
'X-Container-Sync-Key' => 'boogieman'})
|
||||
conn2.put_container('arch_imp_stuff',
|
||||
{'X-Container-Sync-To' => "/region-a/url/to/the/source/imp_stuff",
|
||||
'X-Container-Sync-Key' => 'boogieman'})
|
||||
|
||||
---------
|
||||
[Documentation Home](https://github.com/fog/fog/blob/master/lib/fog/hp/README.md) | [Examples](https://github.com/fog/fog/blob/master/lib/fog/hp/examples/getting_started_examples.md)
|
Loading…
Add table
Reference in a new issue