mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
Rackspace neutron (networking) support
This commit is contained in:
parent
92b5d6d741
commit
19416c9342
23 changed files with 1157 additions and 0 deletions
|
@ -26,6 +26,8 @@ class Rackspace < Fog::Bin
|
|||
Fog::Rackspace::Monitoring
|
||||
when :queues
|
||||
Fog::Rackspace::Queues
|
||||
when :networking
|
||||
Fog::Rackspace::Networking
|
||||
else
|
||||
raise ArgumentError, "Unrecognized service: #{key}"
|
||||
end
|
||||
|
@ -63,6 +65,8 @@ class Rackspace < Fog::Bin
|
|||
Fog::Rackspace::Monitoring.new
|
||||
when :queues
|
||||
Fog::Rackspace::Queues.new
|
||||
when :networking
|
||||
Fog::Rackspace::Networking.new
|
||||
else
|
||||
raise ArgumentError, "Unrecognized service: #{key.inspect}"
|
||||
end
|
||||
|
|
|
@ -10,3 +10,4 @@ require 'fog/rackspace/load_balancers'
|
|||
require 'fog/rackspace/monitoring'
|
||||
require 'fog/rackspace/queues'
|
||||
require 'fog/rackspace/storage'
|
||||
require 'fog/rackspace/networking'
|
||||
|
|
|
@ -97,6 +97,7 @@ module Fog
|
|||
service(:databases, 'Databases')
|
||||
service(:monitoring, 'Monitoring')
|
||||
service(:queues, 'Queues')
|
||||
service(:networking, 'Networking')
|
||||
|
||||
def self.authenticate(options, connection_options = {})
|
||||
rackspace_auth_url = options[:rackspace_auth_url]
|
||||
|
|
315
lib/fog/rackspace/docs/networking.md
Normal file
315
lib/fog/rackspace/docs/networking.md
Normal file
|
@ -0,0 +1,315 @@
|
|||
#Networking (neutron)
|
||||
|
||||
This document explains how to get started using Networking with Fog. It assumes you have read the [Getting Started with Fog and the Rackspace Open Cloud](getting_started.md) document.
|
||||
|
||||
## Starting irb console
|
||||
|
||||
Start by executing the following command:
|
||||
|
||||
irb
|
||||
|
||||
Once `irb` has launched you need to require the Fog library.
|
||||
|
||||
If using Ruby 1.8.x execute:
|
||||
|
||||
require 'rubygems'
|
||||
require 'fog'
|
||||
|
||||
If using Ruby 1.9.x execute:
|
||||
|
||||
require 'fog'
|
||||
|
||||
## Create Service
|
||||
|
||||
Next, create a connection to Rackspace's Networking API:
|
||||
|
||||
Using a US-based account:
|
||||
|
||||
service = Fog::Rackspace::Networking.new({
|
||||
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
|
||||
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
|
||||
:rackspace_region => :ord, # Defaults to :dfw
|
||||
})
|
||||
|
||||
Using a UK-based account:
|
||||
|
||||
service = Fog::Compute.new({
|
||||
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
|
||||
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
|
||||
:rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT,
|
||||
:rackspace_region => :lon,
|
||||
})
|
||||
|
||||
To learn more about obtaining cloud credentials refer to the [Getting Started with Fog and the Rackspace Open Cloud](getting_started.md) document.
|
||||
|
||||
By default `Fog::Rackspace::Networking` will authenticate against the US authentication endpoint and connect to the DFW region. You can specify alternative authentication endpoints using the key `:rackspace_auth_url`. Please refer to [Alternate Authentication Endpoints](http://docs.rackspace.com/auth/api/v2.0/auth-client-devguide/content/Endpoints-d1e180.html) for a list of alternative Rackspace authentication endpoints.
|
||||
|
||||
Alternative regions are specified using the key `:rackspace_region `. A list of regions available for Cloud Servers can be found by executing the following:
|
||||
|
||||
identity_service = Fog::Identity({
|
||||
:provider => 'Rackspace', # Rackspace Fog provider
|
||||
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
|
||||
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
|
||||
:rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT # Not specified for US Cloud
|
||||
})
|
||||
|
||||
identity_service.service_catalog.display_service_regions :cloudServersOpenStack
|
||||
|
||||
### Optional Connection Parameters
|
||||
|
||||
Fog supports passing additional connection parameters to its underlying HTTP library (Excon) using the `:connection_options` parameter.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Key</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>:connect_timeout</td>
|
||||
<td>Connection timeout (default: 60 seconds)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>:read_timeout</td>
|
||||
<td>Read timeout for connection (default: 60 seconds)</td> </tr>
|
||||
<tr>
|
||||
<td>:write_timeout</td>
|
||||
<td>Write timeout for connection (default: 60 seconds)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>:proxy</td>
|
||||
<td>Proxy for HTTP and HTTPS connections</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>:ssl_ca_path</td>
|
||||
<td>Path to SSL certificate authorities</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>:ssl_ca_file</td>
|
||||
<td>SSL certificate authority file</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>:ssl_verify_peer</td>
|
||||
<td>SSL verify peer (default: true)</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
## Fog Abstractions
|
||||
|
||||
Fog provides both a **model** and **request** abstraction. The request abstraction provides the most efficient interface and the model abstraction wraps the request abstraction to provide a convenient `ActiveModel` like interface.
|
||||
|
||||
### Request Layer
|
||||
|
||||
The request abstraction maps directly to the [Networking API](http://docs.rackspace.com/networks/api/v2/cn-gettingstarted/content/ch_overview.html). It provides the most efficient interface to the Rackspace Networking
|
||||
|
||||
To see a list of requests supported by the service:
|
||||
|
||||
service.requests
|
||||
|
||||
This returns:
|
||||
|
||||
[:list_networks, :get_network, :create_network, :delete_network, :list_virtual_interfaces, :create_virtual_interface, :delete_virtual_interface]
|
||||
|
||||
#### Example Request
|
||||
|
||||
To request a list of flavors:
|
||||
|
||||
response = service.list_networks
|
||||
|
||||
This returns in the following `Excon::Response`:
|
||||
|
||||
<Excon::Response:0x0000010231acd8 @data={:body=>{"networks"=>[{"cidr"=>"192.168.0.0/24", "id"=>"08df79ae-b714-425c-ba25-91b0a8a78b9e", "label"=>"something"}, {"cidr"=>"192.168.0.0/24", "id"=>"eb3ed4b8-21d4-478e-9ae4-a35c0cc0437c", "label"=>"something"}, {"id"=>"00000000-0000-0000-0000-000000000000", "label"=>"public"}, {"id"=>"11111111-1111-1111-1111-111111111111", "label"=>"private"}]}, :headers=>{"Content-Type"=>"application/json", "Via"=>"1.1 Repose (Repose/2.12)", "Content-Length"=>"341", "Date"=>"Thu, 23 Oct 2014 20:53:41 GMT", "x-compute-request-id"=>"req-d34ab53c-45ed-433f-8a9d-b3341896b7e5", "Server"=>"Jetty(8.0.y.z-SNAPSHOT)"}, :status=>200, :remote_ip=>"162.209.116.128", :local_port=>60153, :local_address=>"192.168.1.65"}, @body="{\"networks\": [{\"cidr\": \"192.168.0.0/24\", \"id\": \"08df79ae-b714-425c-ba25-91b0a8a78b9e\", \"label\": \"something\"}, {\"cidr\": \"192.168.0.0/24\", \"id\": \"eb3ed4b8-21d4-478e-9ae4-a35c0cc0437c\", \"label\": \"something\"}, {\"id\": \"00000000-0000-0000-0000-000000000000\", \"label\": \"public\"}, {\"id\": \"11111111-1111-1111-1111-111111111111\", \"label\": \"private\"}]}", @headers={"Content-Type"=>"application/json", "Via"=>"1.1 Repose (Repose/2.12)", "Content-Length"=>"341", "Date"=>"Thu, 23 Oct 2014 20:53:41 GMT", "x-compute-request-id"=>"req-d34ab53c-45ed-433f-8a9d-b3341896b7e5", "Server"=>"Jetty(8.0.y.z-SNAPSHOT)"}, @status=200, @remote_ip="162.209.116.128", @local_port=60153, @local_address="192.168.1.65">
|
||||
|
||||
To view the status of the response:
|
||||
|
||||
response.status
|
||||
|
||||
**Note**: Fog is aware of valid HTTP response statuses for each request type. If an unexpected HTTP response status occurs, Fog will raise an exception.
|
||||
|
||||
To view response body:
|
||||
|
||||
response.body
|
||||
|
||||
This will return:
|
||||
|
||||
{"networks"=>[{"cidr"=>"192.168.0.0/24", "id"=>"08df79ae-b714-425c-ba25-91b0a8a78b9e", "label"=>"something"}, {"cidr"=>"192.168.0.0/24", "id"=>"eb3ed4b8-21d4-478e-9ae4-a35c0cc0437c", "label"=>"something"}, {"id"=>"00000000-0000-0000-0000-000000000000", "label"=>"public"}, {"id"=>"11111111-1111-1111-1111-111111111111", "label"=>"private"}]}
|
||||
|
||||
To learn more about Networking request methods refer to [rdoc](http://www.rubydoc.info/gems/fog/Fog/Rackspace/Networking/Real). To learn more about Excon refer to [Excon GitHub repo](https://github.com/geemus/excon).
|
||||
|
||||
### Model Layer
|
||||
|
||||
Fog models behave in a manner similar to `ActiveModel`. Models will generally respond to `create`, `save`, `persisted?`, `destroy`, `reload` and `attributes` methods. Additionally, fog will automatically create attribute accessors.
|
||||
|
||||
Here is a summary of common model methods:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Method</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>create</td>
|
||||
<td>
|
||||
Accepts hash of attributes and creates object.<br>
|
||||
Note: creation is a non-blocking call and you will be required to wait for a valid state before using resulting object.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>save</td>
|
||||
<td>Saves object.<br>
|
||||
Note: not all objects support updating object.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>persisted?</td>
|
||||
<td>Returns true if the object has been persisted.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>destroy</td>
|
||||
<td>
|
||||
Destroys object.<br>
|
||||
Note: this is a non-blocking call and object deletion might not be instantaneous.
|
||||
</td>
|
||||
<tr>
|
||||
<td>reload</td>
|
||||
<td>Updates object with latest state from service.</td>
|
||||
<tr>
|
||||
<td>ready?</td>
|
||||
<td>Returns true if object is in a ready state and able to perform actions. This method will raise an exception if object is in an error state.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>attributes</td>
|
||||
<td>Returns a hash containing the list of model attributes and values.</td>
|
||||
</tr>
|
||||
<td>identity</td>
|
||||
<td>
|
||||
Returns the identity of the object.<br>
|
||||
Note: This might not always be equal to object.id.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>wait_for</td>
|
||||
<td>This method periodically reloads model and then yields to specified block until block returns true or a timeout occurs.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
The remainder of this document details the model abstraction.
|
||||
|
||||
## List Networks
|
||||
|
||||
To retrieve a list of available networks:
|
||||
|
||||
service.networks
|
||||
|
||||
This returns a collection of `Fog::Rackspace::Networking::Network` models:
|
||||
|
||||
<Fog::Rackspace::Networking::Networks
|
||||
[
|
||||
<Fog::Rackspace::Networking::Network
|
||||
id="08df79ae-b714-425c-ba25-91b0a8a78b9e",
|
||||
label="something",
|
||||
cidr="192.168.0.0/24"
|
||||
>,
|
||||
<Fog::Rackspace::Networking::Network
|
||||
id="eb3ed4b8-21d4-478e-9ae4-a35c0cc0437c",
|
||||
label="something",
|
||||
cidr="192.168.0.0/24"
|
||||
>,
|
||||
<Fog::Rackspace::Networking::Network
|
||||
id="00000000-0000-0000-0000-000000000000",
|
||||
label="public",
|
||||
cidr=nil
|
||||
>,
|
||||
<Fog::Rackspace::Networking::Network
|
||||
id="11111111-1111-1111-1111-111111111111",
|
||||
label="private",
|
||||
cidr=nil
|
||||
>
|
||||
]
|
||||
>
|
||||
|
||||
## Create Network
|
||||
|
||||
Create a network:
|
||||
|
||||
service.networks.create(label: "new_network", cidr: "192.168.0.0/24")
|
||||
|
||||
|
||||
## Get Network
|
||||
|
||||
To retrieve individual network:
|
||||
|
||||
service.networks.get "8a3a9f96-b997-46fd-b7a8-a9e740796ffd"
|
||||
|
||||
This returns an `Fog::Rackspace::Networking::Network` instance:
|
||||
|
||||
<Fog::Rackspace::Networking::Network
|
||||
id="08df79ae-b714-425c-ba25-91b0a8a78b9e",
|
||||
label="new_network",
|
||||
cidr="192.168.0.0/24"
|
||||
>
|
||||
|
||||
## Delete Network
|
||||
|
||||
To delete a network:
|
||||
|
||||
network.destroy
|
||||
|
||||
**Note**: The network is not immediately destroyed, but it does occur shortly there after.
|
||||
|
||||
## List Virtual Interfaces
|
||||
|
||||
To retrieve a list of available virtual interfaces:
|
||||
|
||||
service.virtual_interfaces.all(server: <server obj, or server id>)
|
||||
|
||||
This returns a collection of `Fog::Rackspace::Networking::VirtualInterface` models:
|
||||
|
||||
<Fog::Rackspace::Networking::VirtualInterfaces
|
||||
[
|
||||
<Fog::Rackspace::Networking::VirtualInterface
|
||||
id="f063815f-e576-450e-92bd-ff3aeeeb11e0",
|
||||
mac_address="BC:76:4E:20:A9:16",
|
||||
ip_addresses=[{"network_id"=>"11111111-1111-1111-1111-111111111111", "network_label"=>"private", "address"=>"10.176.12.249"}]
|
||||
>,
|
||||
<Fog::Rackspace::Networking::VirtualInterface
|
||||
id="f8196e20-788b-4447-80a5-32ca8fc9622f",
|
||||
mac_address="BC:76:4E:20:A8:56",
|
||||
ip_addresses=[{"network_id"=>"08df79ae-b714-425c-ba25-91b0a8a78b9e", "network_label"=>"new_network", "address"=>"192.168.0.1"}]
|
||||
>
|
||||
]
|
||||
>
|
||||
|
||||
## Create Virtual Interface
|
||||
|
||||
Create a virtual interface:
|
||||
|
||||
service.virtual_interfaces.create(network: <network_id>, server: <server_id>)
|
||||
|
||||
## Delete Virtual Interface
|
||||
|
||||
To delete a virtual interface:
|
||||
|
||||
vis = service.virtual_interfaces.all(server: <server obj, or server id>)
|
||||
vis.first.destroy
|
||||
|
||||
**Note**: The virtual interface is not immediately destroyed, but it does occur shortly there after.
|
||||
|
||||
## Examples
|
||||
|
||||
Example code using Networking can be found [here](https://github.com/fog/fog/tree/master/lib/fog/rackspace/examples).
|
||||
|
||||
## Additional Resources
|
||||
|
||||
* [fog.io](http://fog.io/)
|
||||
* [Fog rdoc](http://rubydoc.info/gems/fog/)
|
||||
* [Fog Github repo](https://github.com/fog/fog)
|
||||
* [Fog Github Issues](https://github.com/fog/fog/issues)
|
||||
* [Excon Github repo](https://github.com/geemus/excon)
|
||||
* [Rackspace Networking API](http://docs.rackspace.com/networking/api/v2/cs-devguide/content/ch_preface.html)
|
||||
|
||||
## Support and Feedback
|
||||
|
||||
Your feedback is appreciated! If you have specific issues with the **fog** SDK, you should file an [issue via Github](https://github.com/fog/fog/issues).
|
||||
|
||||
For general feedback and support requests, send an email to: <sdk-support@rackspace.com>.
|
||||
|
27
lib/fog/rackspace/models/networking/network.rb
Normal file
27
lib/fog/rackspace/models/networking/network.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
module Fog
|
||||
module Rackspace
|
||||
class Networking
|
||||
class Network < Fog::Model
|
||||
identity :id
|
||||
|
||||
attribute :label
|
||||
attribute :cidr
|
||||
|
||||
def save
|
||||
requires :label, :cidr
|
||||
|
||||
data = service.create_network(label, cidr)
|
||||
merge_attributes(data.body['network'])
|
||||
true
|
||||
end
|
||||
|
||||
def destroy
|
||||
requires :identity
|
||||
|
||||
service.delete_network(identity)
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
23
lib/fog/rackspace/models/networking/networks.rb
Normal file
23
lib/fog/rackspace/models/networking/networks.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
require 'fog/rackspace/models/compute_v2/network'
|
||||
|
||||
module Fog
|
||||
module Rackspace
|
||||
class Networking
|
||||
class Networks < Fog::Collection
|
||||
model Fog::Rackspace::Networking::Network
|
||||
|
||||
def all
|
||||
data = service.list_networks.body['networks']
|
||||
load(data)
|
||||
end
|
||||
|
||||
def get(id)
|
||||
data = service.get_network(id).body['network']
|
||||
new(data)
|
||||
rescue Fog::Rackspace::Networking::NotFound
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
85
lib/fog/rackspace/models/networking/virtual_interface.rb
Normal file
85
lib/fog/rackspace/models/networking/virtual_interface.rb
Normal file
|
@ -0,0 +1,85 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/rackspace/models/networking/virtual_interface'
|
||||
|
||||
module Fog
|
||||
module Rackspace
|
||||
class Networking
|
||||
class VirtualInterface < Fog::Model
|
||||
# @!attribute [r] id
|
||||
# @return [String] The virtual interface id
|
||||
identity :id
|
||||
|
||||
# @!attribute [r] mac_address
|
||||
# @return [String] The Media Access Control (MAC) address for the virtual interface.
|
||||
# A MAC address is a unique identifier assigned to network interfaces for communications on the physical network segment.
|
||||
attribute :mac_address
|
||||
|
||||
# @!attribute [r] ip_addresses
|
||||
# @return [Array<Hash>] returns an array of hashes containing information about allocated ip addresses and their associated networks
|
||||
# @example
|
||||
# [
|
||||
# {
|
||||
# "address": "2001:4800:7810:0512:d87b:9cbc:ff04:850c",
|
||||
# "network_id": "ba122b32-dbcc-4c21-836e-b701996baeb3",
|
||||
# "network_label": "public"
|
||||
# },
|
||||
# {
|
||||
# "address": "64.49.226.149",
|
||||
# "network_id": "ba122b32-dbcc-4c21-836e-b701996baeb3",
|
||||
# "network_label": "public"
|
||||
# }
|
||||
# ]
|
||||
attribute :ip_addresses
|
||||
|
||||
# Saves the virtual interface.
|
||||
# This method can only create a virtual interface. Attempting to update interface will result an exception
|
||||
# @return [Boolean] true if virtual interface has been saved
|
||||
def save(attributes = {})
|
||||
if persisted?
|
||||
raise Fog::Errors::Error.new("This virtual interface has already been created and it cannot be updated")
|
||||
else
|
||||
create
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
# Creates Virtual interface for server
|
||||
# * requires attributes: :network
|
||||
# @return [Boolean] returns true if virtual network interface is being created
|
||||
# @raise [Fog::Rackspace::Networking::NotFound] - HTTP 404
|
||||
# @raise [Fog::Rackspace::Networking::BadRequest] - HTTP 400
|
||||
# @raise [Fog::Rackspace::Networking::InternalServerError] - HTTP 500
|
||||
# @raise [Fog::Rackspace::Networking::ServiceError]
|
||||
# @example To create a virtual interface;
|
||||
# my_server.virtual_interfaces.create :network => my_network
|
||||
# @see http://docs.rackspace.com/servers/api/v2/cn-devguide/content/api_create_virtual_interface.html
|
||||
def create
|
||||
data = service.create_virtual_interface(server_id, network_id)
|
||||
merge_attributes(data.body['virtual_interfaces'].first)
|
||||
end
|
||||
|
||||
# Destroy the virtual interface
|
||||
# @return [Boolean] returns true if virtual interface has been destroyed
|
||||
# @raise [Fog::Rackspace::Networking::NotFound] - HTTP 404
|
||||
# @raise [Fog::Rackspace::Networking::BadRequest] - HTTP 400
|
||||
# @raise [Fog::Rackspace::Networking::InternalServerError] - HTTP 500
|
||||
# @raise [Fog::Rackspace::Networking::ServiceError]
|
||||
# @see http://docs.rackspace.com/servers/api/v2/cn-devguide/content/delete_virt_interface_api.html
|
||||
def destroy
|
||||
service.delete_virtual_interface(server_id, id)
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def server_id
|
||||
attributes[:server].is_a?(Fog::Compute::RackspaceV2::Server) ? attributes[:server].id : attributes[:server]
|
||||
end
|
||||
|
||||
def network_id
|
||||
attributes[:network].is_a?(Network) ? attributes[:network].id : attributes[:network]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
45
lib/fog/rackspace/models/networking/virtual_interfaces.rb
Normal file
45
lib/fog/rackspace/models/networking/virtual_interfaces.rb
Normal file
|
@ -0,0 +1,45 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/rackspace/models/networking/virtual_interface'
|
||||
require 'fog/rackspace/models/compute_v2/server'
|
||||
|
||||
module Fog
|
||||
module Rackspace
|
||||
class Networking
|
||||
class VirtualInterfaces < Fog::Collection
|
||||
model Fog::Rackspace::Networking::VirtualInterface
|
||||
|
||||
# Returns list of virtual interfaces for a server
|
||||
# @return [Fog::Rackspace::Networking::Servers] Retrieves a list virtual interfaces for server.
|
||||
# @raise [Fog::Rackspace::Networking::NotFound] - HTTP 404
|
||||
# @raise [Fog::Rackspace::Networking::BadRequest] - HTTP 400
|
||||
# @raise [Fog::Rackspace::Networking::InternalServerError] - HTTP 500
|
||||
# @raise [Fog::Rackspace::Networking::ServiceError]
|
||||
# @note Fog's current implementation only returns 1000 servers
|
||||
# @note The filter parameter on the method is just to maintain compatability with other providers that support filtering.
|
||||
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/List_Servers-d1e2078.html
|
||||
# @see Fog::Rackspace::Networking::Server#virtual_interfaces
|
||||
def all(options={})
|
||||
server = server(options[:server])
|
||||
data = service.list_virtual_interfaces(server.id).body['virtual_interfaces']
|
||||
objects = load(data)
|
||||
objects.each{ |obj| obj.attributes[:server] = server }
|
||||
objects
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def server(obj)
|
||||
server = case obj.class.to_s
|
||||
when "Fog::Compute::RackspaceV2::Server" then obj
|
||||
when "String" then Fog::Compute::RackspaceV2::Server.new(:id => obj, :service => service)
|
||||
else raise "Please pass in :server (either id or Fog::Compute::RackspaceV2::Server)"
|
||||
end
|
||||
|
||||
raise "Server (#{server}) not found" unless server.present?
|
||||
|
||||
server
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
192
lib/fog/rackspace/networking.rb
Normal file
192
lib/fog/rackspace/networking.rb
Normal file
|
@ -0,0 +1,192 @@
|
|||
require 'fog/rackspace/core'
|
||||
|
||||
module Fog
|
||||
module Rackspace
|
||||
class Networking < Fog::Service
|
||||
include Fog::Rackspace::Errors
|
||||
|
||||
class ServiceError < Fog::Rackspace::Errors::ServiceError; end
|
||||
class InternalServerError < Fog::Rackspace::Errors::InternalServerError; end
|
||||
class BadRequest < Fog::Rackspace::Errors::BadRequest; end
|
||||
|
||||
class InvalidStateException < ::RuntimeError
|
||||
attr_reader :desired_state
|
||||
attr_reader :current_state
|
||||
|
||||
def initialize(desired_state, current_state)
|
||||
@desired_state = desired_state
|
||||
@current_state = current_state
|
||||
end
|
||||
end
|
||||
|
||||
class InvalidServerStateException < InvalidStateException
|
||||
def to_s
|
||||
"Server should have transitioned to '#{desired_state}' not '#{current_state}'"
|
||||
end
|
||||
end
|
||||
|
||||
class InvalidImageStateException < InvalidStateException
|
||||
def to_s
|
||||
"Image should have transitioned to '#{desired_state}' not '#{current_state}'"
|
||||
end
|
||||
end
|
||||
|
||||
DFW_ENDPOINT = 'https://dfw.servers.api.rackspacecloud.com/v2'
|
||||
ORD_ENDPOINT = 'https://ord.servers.api.rackspacecloud.com/v2'
|
||||
LON_ENDPOINT = 'https://lon.servers.api.rackspacecloud.com/v2'
|
||||
|
||||
requires :rackspace_username, :rackspace_api_key
|
||||
recognizes :rackspace_endpoint
|
||||
recognizes :rackspace_auth_url
|
||||
recognizes :rackspace_auth_token
|
||||
recognizes :rackspace_region
|
||||
recognizes :rackspace_compute_url
|
||||
|
||||
model_path 'fog/rackspace/models/networking'
|
||||
|
||||
model :network
|
||||
collection :networks
|
||||
|
||||
model :virtual_interface
|
||||
collection :virtual_interfaces
|
||||
|
||||
request_path 'fog/rackspace/requests/networking'
|
||||
request :list_networks
|
||||
request :get_network
|
||||
request :create_network
|
||||
request :delete_network
|
||||
|
||||
request :list_virtual_interfaces
|
||||
request :create_virtual_interface
|
||||
request :delete_virtual_interface
|
||||
|
||||
class Mock < Fog::Rackspace::Service
|
||||
include Fog::Rackspace::MockData
|
||||
|
||||
def initialize(options)
|
||||
@rackspace_api_key = options[:rackspace_api_key]
|
||||
end
|
||||
|
||||
def request(params)
|
||||
Fog::Mock.not_implemented
|
||||
end
|
||||
|
||||
def response(params={})
|
||||
body = params[:body] || {}
|
||||
status = params[:status] || 200
|
||||
headers = params[:headers] || {}
|
||||
|
||||
response = Excon::Response.new(:body => body, :headers => headers, :status => status)
|
||||
if params.key?(:expects) && ![*params[:expects]].include?(response.status)
|
||||
raise(Excon::Errors.status_error(params, response))
|
||||
else response
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Real < Fog::Rackspace::Service
|
||||
def initialize(options = {})
|
||||
@rackspace_api_key = options[:rackspace_api_key]
|
||||
@rackspace_username = options[:rackspace_username]
|
||||
@rackspace_auth_url = options[:rackspace_auth_url]
|
||||
setup_custom_endpoint(options)
|
||||
@rackspace_must_reauthenticate = false
|
||||
@connection_options = options[:connection_options] || {}
|
||||
|
||||
authenticate
|
||||
|
||||
deprecation_warnings(options)
|
||||
|
||||
@persistent = options[:persistent] || false
|
||||
@connection = Fog::Core::Connection.new(endpoint_uri.to_s, @persistent, @connection_options)
|
||||
end
|
||||
|
||||
def request(params, parse_json = true)
|
||||
super
|
||||
rescue Excon::Errors::NotFound => error
|
||||
raise NotFound.slurp(error, self)
|
||||
rescue Excon::Errors::BadRequest => error
|
||||
raise BadRequest.slurp(error, self)
|
||||
rescue Excon::Errors::InternalServerError => error
|
||||
raise InternalServerError.slurp(error, self)
|
||||
rescue Excon::Errors::HTTPStatusError => error
|
||||
raise ServiceError.slurp(error, self)
|
||||
end
|
||||
|
||||
def authenticate(options={})
|
||||
super({
|
||||
:rackspace_api_key => @rackspace_api_key,
|
||||
:rackspace_username => @rackspace_username,
|
||||
:rackspace_auth_url => @rackspace_auth_url,
|
||||
:connection_options => @connection_options
|
||||
})
|
||||
end
|
||||
|
||||
def service_name
|
||||
:cloudServersOpenStack
|
||||
end
|
||||
|
||||
def request_id_header
|
||||
"x-compute-request-id"
|
||||
end
|
||||
|
||||
def region
|
||||
@rackspace_region
|
||||
end
|
||||
|
||||
def endpoint_uri(service_endpoint_url=nil)
|
||||
@uri = super(@rackspace_endpoint || service_endpoint_url, :rackspace_compute_url)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def setup_custom_endpoint(options)
|
||||
@rackspace_endpoint = Fog::Rackspace.normalize_url(options[:rackspace_compute_url] || options[:rackspace_endpoint])
|
||||
|
||||
if v2_authentication?
|
||||
case @rackspace_endpoint
|
||||
when DFW_ENDPOINT
|
||||
@rackspace_endpoint = nil
|
||||
@rackspace_region = :dfw
|
||||
when ORD_ENDPOINT
|
||||
@rackspace_endpoint = nil
|
||||
@rackspace_region = :ord
|
||||
when LON_ENDPOINT
|
||||
@rackspace_endpoint = nil
|
||||
@rackspace_region = :lon
|
||||
else
|
||||
# we are actually using a custom endpoint
|
||||
@rackspace_region = options[:rackspace_region]
|
||||
end
|
||||
else
|
||||
#if we are using auth1 and the endpoint is not set, default to DFW_ENDPOINT for historical reasons
|
||||
@rackspace_endpoint ||= DFW_ENDPOINT
|
||||
end
|
||||
end
|
||||
|
||||
def deprecation_warnings(options)
|
||||
Fog::Logger.deprecation("The :rackspace_endpoint option is deprecated. Please use :rackspace_compute_url for custom endpoints") if options[:rackspace_endpoint]
|
||||
|
||||
if [DFW_ENDPOINT, ORD_ENDPOINT, LON_ENDPOINT].include?(@rackspace_endpoint) && v2_authentication?
|
||||
regions = @identity_service.service_catalog.display_service_regions(service_name)
|
||||
Fog::Logger.deprecation("Please specify region using :rackspace_region rather than :rackspace_endpoint. Valid regions for :rackspace_region are #{regions}.")
|
||||
end
|
||||
end
|
||||
|
||||
def append_tenant_v1(credentials)
|
||||
account_id = credentials['X-Server-Management-Url'].match(/.*\/([\d]+)$/)[1]
|
||||
|
||||
endpoint = @rackspace_endpoint || credentials['X-Server-Management-Url'] || DFW_ENDPOINT
|
||||
@uri = URI.parse(endpoint)
|
||||
@uri.path = "#{@uri.path}/#{account_id}"
|
||||
end
|
||||
|
||||
def authenticate_v1(options)
|
||||
credentials = Fog::Rackspace.authenticate(options, @connection_options)
|
||||
append_tenant_v1 credentials
|
||||
@auth_token = credentials['X-Auth-Token']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
36
lib/fog/rackspace/requests/networking/create_network.rb
Normal file
36
lib/fog/rackspace/requests/networking/create_network.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
module Fog
|
||||
module Rackspace
|
||||
class Networking
|
||||
class Real
|
||||
def create_network(label, cidr)
|
||||
data = {
|
||||
'network' => {
|
||||
'label' => label,
|
||||
'cidr' => cidr
|
||||
}
|
||||
}
|
||||
|
||||
request(
|
||||
:method => 'POST',
|
||||
:body => Fog::JSON.encode(data),
|
||||
:path => "os-networksv2",
|
||||
:expects => 200
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def create_network(label, cidr)
|
||||
network_id = Fog::Rackspace::MockData.uuid
|
||||
|
||||
self.data[:networks][network_id] = {
|
||||
'id' => network_id,
|
||||
'label' => label,
|
||||
'cidr' => cidr
|
||||
}
|
||||
response(:body => { 'network' => self.data[:networks][network_id] })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,30 @@
|
|||
module Fog
|
||||
module Rackspace
|
||||
class Networking
|
||||
class Real
|
||||
# Creates virtual interface for a server
|
||||
# @param [String] server_id The server id to create the virtual interface on
|
||||
# @param [String] network_id The network id to attach the virtual interface to
|
||||
# @raise [Fog::Rackspace::Networking::NotFound] - HTTP 404
|
||||
# @raise [Fog::Rackspace::Networking::BadRequest] - HTTP 400
|
||||
# @raise [Fog::Rackspace::Networking::InternalServerError] - HTTP 500
|
||||
# @raise [Fog::Rackspace::Networking::ServiceError]
|
||||
# @see http://docs.rackspace.com/servers/api/v2/cn-devguide/content/api_create_virtual_interface.html
|
||||
def create_virtual_interface(server_id, network_id)
|
||||
data = {
|
||||
:virtual_interface => {
|
||||
:network_id => network_id
|
||||
}
|
||||
}
|
||||
|
||||
request(
|
||||
:expects => [200],
|
||||
:method => 'POST',
|
||||
:path => "servers/#{server_id}/os-virtual-interfacesv2",
|
||||
:body => Fog::JSON.encode(data)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
21
lib/fog/rackspace/requests/networking/delete_network.rb
Normal file
21
lib/fog/rackspace/requests/networking/delete_network.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
module Fog
|
||||
module Rackspace
|
||||
class Networking
|
||||
class Real
|
||||
def delete_network(id)
|
||||
request(:method => 'DELETE', :path => "os-networksv2/#{id}", :expects => 202)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def delete_network(id)
|
||||
unless self.data[:networks].key?(id)
|
||||
raise Fog::Rackspace::Networking::NotFound
|
||||
end
|
||||
|
||||
response(:body => '', :status => 202)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
module Fog
|
||||
module Rackspace
|
||||
class Networking
|
||||
class Real
|
||||
# Deletes virtual interface from server
|
||||
# @param [String] server_id The server id that contains the virtual interface
|
||||
# @param [String] interface_id The id of the virtual interface
|
||||
# @raise [Fog::Rackspace::Networking::NotFound] - HTTP 404
|
||||
# @raise [Fog::Rackspace::Networking::BadRequest] - HTTP 400
|
||||
# @raise [Fog::Rackspace::Networking::InternalServerError] - HTTP 500
|
||||
# @raise [Fog::Rackspace::Networking::ServiceError]
|
||||
# @see http://docs.rackspace.com/servers/api/v2/cn-devguide/content/delete_virt_interface_api.html
|
||||
def delete_virtual_interface(server_id, interface_id)
|
||||
request(
|
||||
:expects => [200],
|
||||
:method => 'DELETE',
|
||||
:path => "servers/#{server_id}/os-virtual-interfacesv2/#{interface_id}"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
21
lib/fog/rackspace/requests/networking/get_network.rb
Normal file
21
lib/fog/rackspace/requests/networking/get_network.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
module Fog
|
||||
module Rackspace
|
||||
class Networking
|
||||
class Real
|
||||
def get_network(id)
|
||||
request(:method => 'GET', :path => "os-networksv2/#{id}", :expects => 200)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def get_network(id)
|
||||
unless self.data[:networks].key?(id)
|
||||
raise Fog::Rackspace::Networking::NotFound
|
||||
end
|
||||
|
||||
response(:body => { 'network' => self.data[:networks][id] })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
18
lib/fog/rackspace/requests/networking/list_networks.rb
Normal file
18
lib/fog/rackspace/requests/networking/list_networks.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
module Fog
|
||||
module Rackspace
|
||||
class Networking
|
||||
class Real
|
||||
def list_networks
|
||||
request(:method => 'GET', :path => 'os-networksv2', :expects => 200)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def list_networks
|
||||
networks = self.data[:networks].values
|
||||
response(:body => { 'networks' => networks })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,22 @@
|
|||
module Fog
|
||||
module Rackspace
|
||||
class Networking
|
||||
class Real
|
||||
# Lists virtual interfaces for a server
|
||||
# @param [String] server_id
|
||||
# @raise [Fog::Rackspace::Networking::NotFound] - HTTP 404
|
||||
# @raise [Fog::Rackspace::Networking::BadRequest] - HTTP 400
|
||||
# @raise [Fog::Rackspace::Networking::InternalServerError] - HTTP 500
|
||||
# @raise [Fog::Rackspace::Networking::ServiceError]
|
||||
# @see http://docs.rackspace.com/servers/api/v2/cn-devguide/content/list_virt_interfaces.html
|
||||
def list_virtual_interfaces(server_id)
|
||||
request(
|
||||
:expects => [200],
|
||||
:method => 'GET',
|
||||
:path => "servers/#{server_id}/os-virtual-interfacesv2"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
10
tests/rackspace/models/networking/network_tests.rb
Normal file
10
tests/rackspace/models/networking/network_tests.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
Shindo.tests('Fog::Rackspace::Networking | network', ['rackspace']) do
|
||||
service = Fog::Rackspace::Networking.new
|
||||
|
||||
options = {
|
||||
:label => "fog_network_#{Time.now.to_i.to_s}",
|
||||
:cidr => '192.168.0.0/24'
|
||||
}
|
||||
|
||||
model_tests(service.networks, options, true)
|
||||
end
|
10
tests/rackspace/models/networking/networks_tests.rb
Normal file
10
tests/rackspace/models/networking/networks_tests.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
Shindo.tests('Fog::Rackspace::Networking | networks', ['rackspace']) do
|
||||
service = Fog::Rackspace::Networking.new
|
||||
|
||||
options = {
|
||||
:label => "fog_network_#{Time.now.to_i.to_s}",
|
||||
:cidr => '192.168.0.0/24'
|
||||
}
|
||||
|
||||
collection_tests(service.networks, options, true)
|
||||
end
|
33
tests/rackspace/models/networking/virtual_interface_tests.rb
Normal file
33
tests/rackspace/models/networking/virtual_interface_tests.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
Shindo.tests('Fog::Rackspace::Networking | virtual_interface', ['rackspace']) do
|
||||
service = Fog::Rackspace::Networking.new
|
||||
|
||||
net_options = {
|
||||
:label => "fog_network_#{Time.now.to_i.to_s}",
|
||||
:cidr => '192.168.0.0/24'
|
||||
}
|
||||
|
||||
server_options = {
|
||||
:name => "fog_server_#{Time.now.to_i.to_s}",
|
||||
:flavor_id => rackspace_test_flavor_id(service),
|
||||
:image_id => rackspace_test_image_id(service)
|
||||
}
|
||||
|
||||
tests('virtual_interface') do
|
||||
pending if Fog.mocking?
|
||||
begin
|
||||
@server = service.servers.create server_options
|
||||
@network = service.networks.create net_options
|
||||
@server.wait_for { ready? }
|
||||
|
||||
model_tests(@server.virtual_interfaces, {:network => @network}, false)
|
||||
|
||||
ensure
|
||||
if @server
|
||||
@server.destroy
|
||||
# wait_for_server_deletion(@server) if @server
|
||||
delete_test_network(@network) if @network
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,24 @@
|
|||
Shindo.tests('Fog::Rackspace::Networking | virtual_interfaces', ['rackspace']) do
|
||||
service = Fog::Rackspace::Networking.new
|
||||
|
||||
options = {
|
||||
:name => "fog_server_#{Time.now.to_i.to_s}",
|
||||
:flavor_id => rackspace_test_flavor_id(service),
|
||||
:image_id => rackspace_test_image_id(service)
|
||||
}
|
||||
|
||||
tests('virtual_interfaces') do
|
||||
pending if Fog.mocking?
|
||||
begin
|
||||
@server = service.servers.create options
|
||||
@server.wait_for { ready? }
|
||||
|
||||
tests('#virtual_interfaces').succeeds do
|
||||
@server.virtual_interfaces.all
|
||||
end
|
||||
|
||||
ensure
|
||||
@server.destroy if @server
|
||||
end
|
||||
end
|
||||
end
|
118
tests/rackspace/networking_tests.rb
Normal file
118
tests/rackspace/networking_tests.rb
Normal file
|
@ -0,0 +1,118 @@
|
|||
Shindo.tests('Fog::Rackspace::Networking', ['rackspace']) do
|
||||
|
||||
def assert_method(url, method)
|
||||
@service.instance_variable_set "@rackspace_auth_url", url
|
||||
returns(method) { @service.send :authentication_method }
|
||||
end
|
||||
|
||||
tests('#authentication_method') do
|
||||
@service = Fog::Rackspace::Networking.new
|
||||
|
||||
assert_method nil, :authenticate_v2
|
||||
|
||||
assert_method 'auth.api.rackspacecloud.com', :authenticate_v1 # chef's default auth endpoint
|
||||
|
||||
assert_method 'https://identity.api.rackspacecloud.com', :authenticate_v1
|
||||
assert_method 'https://identity.api.rackspacecloud.com/v1', :authenticate_v1
|
||||
assert_method 'https://identity.api.rackspacecloud.com/v1.1', :authenticate_v1
|
||||
assert_method 'https://identity.api.rackspacecloud.com/v2.0', :authenticate_v2
|
||||
|
||||
assert_method 'https://lon.identity.api.rackspacecloud.com', :authenticate_v1
|
||||
assert_method 'https://lon.identity.api.rackspacecloud.com/v1', :authenticate_v1
|
||||
assert_method 'https://lon.identity.api.rackspacecloud.com/v1.1', :authenticate_v1
|
||||
assert_method 'https://lon.identity.api.rackspacecloud.com/v2.0', :authenticate_v2
|
||||
end
|
||||
|
||||
tests('legacy authentication') do
|
||||
pending if Fog.mocking?
|
||||
|
||||
tests('variables populated').succeeds do
|
||||
@service = Fog::Rackspace::Networking.new :rackspace_auth_url => 'https://identity.api.rackspacecloud.com/v1.0'
|
||||
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
|
||||
returns(false, "path populated") { @service.instance_variable_get("@uri").path.nil? }
|
||||
returns(true, "identity_service was not used") { @service.instance_variable_get("@identity_service").nil? }
|
||||
@service.list_flavors
|
||||
end
|
||||
|
||||
tests('custom endpoint') do
|
||||
@service = Fog::Rackspace::Networking.new :rackspace_auth_url => 'https://identity.api.rackspacecloud.com/v1.0',
|
||||
:rackspace_compute_url => 'https://my-custom-endpoint.com'
|
||||
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
|
||||
returns(true, "uses custom endpoint") { (@service.instance_variable_get("@uri").host =~ /my-custom-endpoint\.com/) != nil }
|
||||
end
|
||||
end
|
||||
|
||||
tests('current authentation') do
|
||||
pending if Fog.mocking?
|
||||
|
||||
tests('variables populated').succeeds do
|
||||
@service = Fog::Rackspace::Networking.new :rackspace_auth_url => 'https://identity.api.rackspacecloud.com/v2.0', :connection_options => {:ssl_verify_peer => true}
|
||||
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
|
||||
returns(false, "path populated") { @service.instance_variable_get("@uri").host.nil? }
|
||||
identity_service = @service.instance_variable_get("@identity_service")
|
||||
returns(false, "identity service was used") { identity_service.nil? }
|
||||
returns(true, "connection_options are passed") { identity_service.instance_variable_get("@connection_options").key?(:ssl_verify_peer) }
|
||||
@service.list_flavors
|
||||
end
|
||||
tests('dfw region').succeeds do
|
||||
@service = Fog::Rackspace::Networking.new :rackspace_auth_url => 'https://identity.api.rackspacecloud.com/v2.0', :rackspace_region => :dfw
|
||||
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
|
||||
returns(true) { (@service.instance_variable_get("@uri").host =~ /dfw/) != nil }
|
||||
@service.list_flavors
|
||||
end
|
||||
tests('ord region').succeeds do
|
||||
@service = Fog::Rackspace::Networking.new :rackspace_auth_url => 'https://identity.api.rackspacecloud.com/v2.0', :rackspace_region => :ord
|
||||
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
|
||||
returns(true) { (@service.instance_variable_get("@uri").host =~ /ord/) != nil }
|
||||
@service.list_flavors
|
||||
end
|
||||
tests('custom endpoint') do
|
||||
@service = Fog::Rackspace::Networking.new :rackspace_auth_url => 'https://identity.api.rackspacecloud.com/v2.0',
|
||||
:rackspace_compute_url => 'https://my-custom-endpoint.com'
|
||||
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
|
||||
returns(true, "uses custom endpoint") { (@service.instance_variable_get("@uri").host =~ /my-custom-endpoint\.com/) != nil }
|
||||
end
|
||||
end
|
||||
|
||||
tests('default auth') do
|
||||
pending if Fog.mocking?
|
||||
|
||||
tests('no params').succeeds do
|
||||
@service = Fog::Rackspace::Networking.new :rackspace_region => nil
|
||||
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
|
||||
returns(true) { (@service.instance_variable_get("@uri").host =~ /dfw/) != nil }
|
||||
@service.list_flavors
|
||||
end
|
||||
tests('specify old contstant style service endoint').succeeds do
|
||||
@service = Fog::Rackspace::Networking.new :rackspace_endpoint => Fog::Rackspace::Networking::ORD_ENDPOINT
|
||||
returns(true) { (@service.instance_variable_get("@uri").to_s =~ /#{Fog::Rackspace::Networking::ORD_ENDPOINT}/ ) != nil }
|
||||
@service.list_flavors
|
||||
end
|
||||
tests('specify region').succeeds do
|
||||
@service = Fog::Rackspace::Networking.new :rackspace_region => :ord
|
||||
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
|
||||
returns(true) { (@service.instance_variable_get("@uri").host =~ /ord/ ) != nil }
|
||||
@service.list_flavors
|
||||
end
|
||||
tests('custom endpoint') do
|
||||
@service = Fog::Rackspace::Networking.new :rackspace_compute_url => 'https://my-custom-endpoint.com'
|
||||
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
|
||||
returns(true, "uses custom endpoint") { (@service.instance_variable_get("@uri").host =~ /my-custom-endpoint\.com/) != nil }
|
||||
end
|
||||
end
|
||||
|
||||
tests('reauthentication') do
|
||||
pending if Fog.mocking?
|
||||
|
||||
tests('should reauth with valid credentials') do
|
||||
@service = Fog::Rackspace::Networking.new
|
||||
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
|
||||
@service.instance_variable_set("@auth_token", "bad_token")
|
||||
returns(true) { [200, 203].include? @service.list_flavors.status }
|
||||
end
|
||||
tests('should terminate with incorrect credentials') do
|
||||
raises(Excon::Errors::Unauthorized) { Fog::Rackspace::Networking.new :rackspace_api_key => 'bad_key' }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
49
tests/rackspace/requests/networking/network_tests.rb
Normal file
49
tests/rackspace/requests/networking/network_tests.rb
Normal file
|
@ -0,0 +1,49 @@
|
|||
Shindo.tests('Fog::Rackspace::Networking | network_tests', ['rackspace']) do
|
||||
service = Fog::Rackspace::Networking.new
|
||||
|
||||
network_format = {
|
||||
'id' => String,
|
||||
'label' => String,
|
||||
'cidr' => Fog::Nullable::String
|
||||
}
|
||||
|
||||
get_network_format = {
|
||||
'network' => network_format
|
||||
}
|
||||
|
||||
list_networks_format = {
|
||||
'networks' => [network_format]
|
||||
}
|
||||
|
||||
tests('success') do
|
||||
network_id = nil
|
||||
|
||||
tests('#create_network').formats(get_network_format) do
|
||||
service.create_network("fog_#{Time.now.to_i.to_s}", '192.168.0.0/24').body.tap do |r|
|
||||
network_id = r['network']['id']
|
||||
end
|
||||
end
|
||||
|
||||
tests('#list_networks').formats(list_networks_format) do
|
||||
service.list_networks.body
|
||||
end
|
||||
|
||||
tests('#get_network').formats(get_network_format) do
|
||||
service.get_network(network_id).body
|
||||
end
|
||||
|
||||
tests('#delete_network').succeeds do
|
||||
service.delete_network(network_id)
|
||||
end
|
||||
end
|
||||
|
||||
test('failure') do
|
||||
tests('#get_network').raises(Fog::Rackspace::Networking::NotFound) do
|
||||
service.get_network(0)
|
||||
end
|
||||
|
||||
tests('#delete_network').raises(Fog::Rackspace::Networking::NotFound) do
|
||||
service.delete_network(0)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,49 @@
|
|||
Shindo.tests('Fog::Rackspace::Networking | virtual_interface_tests', ['rackspace']) do
|
||||
@service = Fog::Rackspace::Networking.new
|
||||
|
||||
virtual_interface_format = {
|
||||
"virtual_interfaces"=> [{
|
||||
"ip_addresses"=> [{
|
||||
"network_id"=> String,
|
||||
"network_label"=> String,
|
||||
"address"=> String
|
||||
}],
|
||||
"id"=> String,
|
||||
"mac_address"=> String
|
||||
}]
|
||||
}
|
||||
|
||||
begin
|
||||
unless Fog.mocking?
|
||||
network_id = nil
|
||||
|
||||
@server = @service.servers.create(:name => "fog_virtual_interface_test_#{Time.now.to_i.to_s}",
|
||||
:flavor_id => rackspace_test_flavor_id(@service),
|
||||
:image_id => rackspace_test_image_id(@service))
|
||||
@server.wait_for { ready? }
|
||||
|
||||
@network = @service.networks.create(:label => "fog_#{Time.now.to_i.to_s}", :cidr => '192.168.0.0/24')
|
||||
end
|
||||
|
||||
tests('success') do
|
||||
pending if Fog.mocking?
|
||||
|
||||
tests('#create_virtual_interface').formats(virtual_interface_format) do
|
||||
response = @service.create_virtual_interface @server.id, @network.id
|
||||
body = response.body
|
||||
@virtual_network_interface_id = body["virtual_interfaces"].first["id"]
|
||||
body
|
||||
end
|
||||
tests('#list_virtual_interfaces').formats(virtual_interface_format) do
|
||||
@service.list_virtual_interfaces(@server.id).body
|
||||
end
|
||||
|
||||
tests('#delete_virtual_interfaces').succeeds do
|
||||
@service.delete_virtual_interface(@server.id, @virtual_network_interface_id)
|
||||
end
|
||||
end
|
||||
ensure
|
||||
@server.destroy if @server
|
||||
delete_test_network @network
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue