1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00

Merge pull request #1603 from jedipunkz/rubiojr-jedipunkz

@Rubiojr and  @jedipunkz enabled to operate routers with openstack.
This commit is contained in:
Sergio Rubio 2013-03-20 09:43:04 -07:00
commit bf210b052e
13 changed files with 563 additions and 0 deletions

View file

@ -0,0 +1,58 @@
require 'fog/core/model'
module Fog
module Network
class OpenStack
# The Layer-3 Networking Extensions (router)
#
# A logical entity for forwarding packets across internal
# subnets and NATting them on external networks through
# an appropriate external gateway.
#
# @see http://docs.openstack.org/api/openstack-network/2.0/content/router_ext.html
class Router < Fog::Model
identity :id
attribute :name
attribute :network_id
attribute :subnet_id
attribute :admin_state_up
attribute :tenant_id
attribute :external_gateway_info
attribute :status
def initialize(attributes)
# Old 'connection' is renamed as service and should be used instead
prepare_service_value(attributes)
super
end
def save
requires :name
identity ? update : create
end
def create
requires :name
merge_attributes(service.create_router(self.name,
self.attributes).body['router'])
self
end
def update
requires :id
merge_attributes(service.update_router(self.id,
self.attributes).body['router'])
self
end
def destroy
requires :id
service.delete_router(self.id)
true
end
end
end
end
end

View file

@ -0,0 +1,34 @@
require 'fog/core/collection'
require 'fog/openstack/models/network/router'
module Fog
module Network
class OpenStack
class Routers < Fog::Collection
attribute :filters
model Fog::Network::OpenStack::Router
def initialize(attributes)
self.filters ||= {}
super
end
def all(filters = filters)
self.filters = filters
load(service.list_routers(filters).body['routers'])
end
def get(router_id)
if router = service.get_router(router_id).body['router']
new(router)
end
rescue Fog::Network::OpenStack::NotFound
nil
end
end
end
end
end

View file

@ -21,6 +21,8 @@ module Fog
collection :subnets
model :floating_ip
collection :floating_ips
model :router
collection :routers
## REQUESTS
#
@ -55,6 +57,15 @@ module Fog
request :associate_floating_ip
request :disassociate_floating_ip
# Router CRUD
request :list_routers
request :create_router
request :delete_router
request :get_router
request :update_router
request :add_router_interface
request :remove_router_interface
# Tenant
request :set_tenant
@ -66,6 +77,7 @@ module Fog
:ports => {},
:subnets => {},
:floating_ips => {},
:routers => {},
}
end
end

View file

@ -0,0 +1,48 @@
module Fog
module Network
class OpenStack
class Real
def add_router_interface(router_id, subnet_id, options = {})
data = {
'subnet_id' => subnet_id,
}
request(
:body => Fog::JSON.encode(data),
:expects => [200],
:method => 'PUT',
:path => "routers/#{router_id}/add_router_interface"
)
end
end
class Mock
def add_router_interface(router_id, subnet_id, options = {})
response = Excon::Response.new
response.status = 201
data = {
'status' => 'ACTIVE',
'name' => '',
'admin_state_up' => true,
'network_id' => '5307648b-e836-4658-8f1a-ff7536870c64',
'tenant_id' => '6b96ff0cb17a4b859e1e575d221683d3',
'device_owner' => 'network:router_interface',
'mac_address' => 'fa:16:3e:f7:d1:9c',
'fixed_ips' => {
'subnet_id' => 'a2f1f29d-571b-4533-907f-5803ab96ead1',
'ip_address' => '10.1.1.1'
},
'id' => '3a44f4e5-1694-493a-a1fb-393881c673a4',
'device_id' => '7177abc4-5ae9-4bb7-b0d4-89e94a4abf3b'
}
self.data[:routers][data['router_id']] = data
response.body = { 'router' => data }
response
end
end
end
end
end

View file

@ -0,0 +1,58 @@
module Fog
module Network
class OpenStack
class Real
def create_router(name, options = {})
data = {
'router' => {
'name' => name,
}
}
vanilla_options = [
:admin_state_up,
:tenant_id,
:network_id,
:external_gateway_info,
:status,
:subnet_id
]
vanilla_options.reject{ |o| options[o].nil? }.each do |key|
data['router'][key] = options[key]
end
request(
:body => Fog::JSON.encode(data),
:expects => [201],
:method => 'POST',
:path => 'routers'
)
end
end
class Mock
def create_router(name, options = {})
response = Excon::Response.new
response.status = 201
data = {
'router' => {
'status' => 'ACTIVE',
'external_gateway_info' => nil,
'name' => 'another_router',
'admin_state_up' => true,
'tenant_id' => '6b96ff0cb17a4b859e1e575d221683d3',
'id' => '8604a0de-7f6b-409a-a47c-a1cc7bc77b2e'
}
}
self.data['routers'] ||= []
self.data['routers'] << data['router']
response.body = data
response
end
end
end
end
end

View file

@ -0,0 +1,30 @@
module Fog
module Network
class OpenStack
class Real
def delete_router(router_id)
request(
:expects => 204,
:method => 'DELETE',
:path => "routers/#{router_id}"
)
end
end
class Mock
def delete_router(router_id)
response = Excon::Response.new
if list_routers.body['routers'].map { |r| r['id'] }.include? router_id
self.data[:routers].delete(router_id)
response.status = 204
response
else
raise Fog::Network::OpenStack::NotFound
end
end
end
end
end
end

View file

@ -0,0 +1,41 @@
module Fog
module Network
class OpenStack
class Real
def get_router(router_id)
request(
:expects => [200],
:method => 'GET',
:path => "routers/#{router_id}"
)
end
end
class Mock
def get_router(router_id)
response = Excon::Response.new
if data = (self.data['routers'].find { |r| r['id'] == router_id })
response.status = 200
response.body = {
'router' => {
'status' => 'ACTIVE',
'external_gateway_info' => {
'network_id' => '3c5bcddd-6af9-4e6b-9c3e-c153e521cab8'
},
'name' => 'router1',
'admin_state_up' => true,
'tenant_id' => '33a40233088643acb66ff6eb0ebea679',
'id' => 'a9254bdb-2613-4a13-ac4c-adc581fba50d'
}
}
response
else
raise Fog::Network::OpenStack::NotFound
end
end
end
end
end
end

View file

@ -0,0 +1,27 @@
module Fog
module Network
class OpenStack
class Real
def list_routers(filters = {})
request(
:expects => 200,
:method => 'GET',
:path => 'routers',
:query => filters
)
end
end
class Mock
def list_routers(filters = {})
Excon::Response.new(
:body => { 'routers' => self.data['routers'] },
:status => 200
)
end
end
end
end
end

View file

@ -0,0 +1,36 @@
module Fog
module Network
class OpenStack
class Real
def remove_router_interface(router_id, subnet_id, options = {})
data = {
'subnet_id' => subnet_id,
}
request(
:body => Fog::JSON.encode(data),
:expects => [200],
:method => 'PUT',
:path => "routers/#{router_id}/remove_router_interface"
)
end
end
class Mock
def remove_router_interface(router_id, subnet_id, options = {})
response = Excon::Response.new
response.status = 201
data = {
'subnet_id' => 'a2f1f29d-571b-4533-907f-5803ab96ead1'
}
self.data[:routers][data['router_id']] = data
response.body = { 'router' => data }
response
end
end
end
end
end

View file

@ -0,0 +1,85 @@
module Fog
module Network
class OpenStack
class Real
# Update Router
#
# Beyond the name and the administrative state, the only
# parameter which can be updated with this operation is
# the external gateway.
#
# router = Fog::Network[:openstack].routers.first
# net = Fog::Network[:openstack].networks.first
#
# # :external_gateway_info can be either a
# # Fog::Network::OpenStack::Network or a Hash
# # like { 'network_id' => network.id }
# Fog::Network[:openstack].update_router router.id,
# :name => 'foo',
# :external_gateway_info => net,
# :admin_state_up => true
#
# @see http://docs.openstack.org/api/openstack-network/2.0/content/router_update.html
def update_router(router_id, options = {})
data = { 'router' => {} }
vanilla_options = [:name, :admin_state_up]
egi = options[:external_gateway_info]
if egi
if egi.is_a?(Fog::Network::OpenStack::Network)
data['router']['external_gateway_info'] = { 'network_id' => egi.id }
elsif egi.is_a?(Hash) and egi['network_id']
data['router']['external_gateway_info'] = egi
else
raise ArgumentError.new('Invalid external_gateway_info attribute')
end
end
vanilla_options.reject{ |o| options[o].nil? }.each do |key|
data['router'][key] = options[key]
end
request(
:body => Fog::JSON.encode(data),
:expects => 200,
:method => 'PUT',
:path => "routers/#{router_id}.json"
)
end
end
class Mock
def update_router(router_id, options = {})
router = self.data['routers'].find { |r| r['id'] == router_id }
raise Fog::Network::OpenStack::NotFound unless router
data = { 'router' => router }
vanilla_options = [:name, :admin_state_up]
egi = options[:external_gateway_info]
if egi
if egi.is_a?(Fog::Network::OpenStack::Network)
data['router']['external_gateway_info'] = { 'network_id' => egi.id }
elsif egi.is_a?(Hash) and egi['network_id']
data['router']['external_gateway_info'] = egi
else
raise ArgumentError.new('Invalid external_gateway_info attribute')
end
end
vanilla_options.reject{ |o| options[o].nil? }.each do |key|
data['router'][key] = options[key]
end
response = Excon::Response.new
response.status = 201
response.body = data
response
end
end
end
end
end

View file

@ -0,0 +1,38 @@
Shindo.tests("Fog::Network[:openstack] | router", ['openstack']) do
tests('success') do
tests('#create').succeeds do
@instance = Fog::Network[:openstack].routers.create(
:name => 'router_name',
:admin_state_up => true
)
!@instance.id.nil?
end
tests('#update') do
test 'router name' do
@instance.name = 'new_name'
@instance.update.name == 'new_name'
end
# Needs code from issue #1598
#test 'external_gateway_info' do
# net = Fog::Network[:openstack].networks.create(
# :name => 'net_name',
# :shared => false,
# :admin_state_up => true,
# :tenant_id => 'tenant_id',
# :router_external => true,
# )
# @instance.external_gateway_info = net
# @instance.update
#end
end
tests('#destroy').succeeds do
@instance.destroy == true
end
end
end

View file

@ -0,0 +1,21 @@
Shindo.tests("Fog::Network[:openstack] | routers", ['openstack']) do
@router = Fog::Network[:openstack].routers.create(
:name => 'router_name',
:admin_state_up => true
)
@routers = Fog::Network[:openstack].routers
tests('success') do
tests('#all').succeeds do
@routers.all
end
tests('#get').succeeds do
@routers.get @router.id
end
end
@router.destroy
end

View file

@ -0,0 +1,75 @@
Shindo.tests('Fog::Network[:openstack] | router requests', ['openstack']) do
@router_format = {
'id' => String,
'name' => String,
'status' => String,
'admin_state_up' => Fog::Boolean,
'tenant_id' => String,
'external_gateway_info' => Fog::Nullable::Hash,
}
tests('success') do
tests('#create_router').formats({'router' => @router_format}) do
attributes = {
:admin_state_up => true,
:tenant_id => 'tenant_id'
}
Fog::Network[:openstack].create_router('router_name', attributes).body
end
tests('#list_routers').formats({'routers' => [@router_format]}) do
Fog::Network[:openstack].list_routers.body
end
tests('#get_router').formats({'router' => @router_format}) do
router_id = Fog::Network[:openstack].routers.all.first.id
Fog::Network[:openstack].get_router(router_id).body
end
tests('#update_router').formats({'router' => @router_format}) do
router_id = Fog::Network[:openstack].routers.all.first.id
attributes = {}
{
:name => 'net_name',
:external_gateway_info => { :network_id => 'net_id' },
:status => 'ACTIVE',
:admin_state_up => 'true'
}
Fog::Network[:openstack].update_router(router_id, attributes).body
end
tests('#update_router_with_network').formats({'router' => @router_format}) do
router_id = Fog::Network[:openstack].routers.all.first.id
net = Fog::Network[:openstack].networks.first
attributes = {}
{
:name => 'net_name',
:external_gateway_info => net,
:status => 'ACTIVE',
:admin_state_up => 'true'
}
Fog::Network[:openstack].update_router(router_id, attributes).body
end
tests('#delete_router').succeeds do
router_id = Fog::Network[:openstack].routers.all.last.id
Fog::Network[:openstack].delete_router(router_id)
end
end
tests('failure') do
tests('#get_router').raises(Fog::Network::OpenStack::NotFound) do
Fog::Network[:openstack].get_router(0)
end
tests('#update_router').raises(Fog::Network::OpenStack::NotFound) do
Fog::Network[:openstack].update_router(0, {})
end
tests('#delete_router').raises(Fog::Network::OpenStack::NotFound) do
Fog::Network[:openstack].delete_router(0)
end
end
end