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:
commit
bf210b052e
13 changed files with 563 additions and 0 deletions
58
lib/fog/openstack/models/network/router.rb
Normal file
58
lib/fog/openstack/models/network/router.rb
Normal 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
|
34
lib/fog/openstack/models/network/routers.rb
Normal file
34
lib/fog/openstack/models/network/routers.rb
Normal 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
|
|
@ -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
|
||||
|
|
48
lib/fog/openstack/requests/network/add_router_interface.rb
Normal file
48
lib/fog/openstack/requests/network/add_router_interface.rb
Normal 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
|
58
lib/fog/openstack/requests/network/create_router.rb
Normal file
58
lib/fog/openstack/requests/network/create_router.rb
Normal 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
|
30
lib/fog/openstack/requests/network/delete_router.rb
Normal file
30
lib/fog/openstack/requests/network/delete_router.rb
Normal 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
|
41
lib/fog/openstack/requests/network/get_router.rb
Normal file
41
lib/fog/openstack/requests/network/get_router.rb
Normal 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
|
27
lib/fog/openstack/requests/network/list_routers.rb
Normal file
27
lib/fog/openstack/requests/network/list_routers.rb
Normal 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
|
|
@ -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
|
85
lib/fog/openstack/requests/network/update_router.rb
Normal file
85
lib/fog/openstack/requests/network/update_router.rb
Normal 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
|
38
tests/openstack/models/network/router_tests.rb
Normal file
38
tests/openstack/models/network/router_tests.rb
Normal 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
|
21
tests/openstack/models/network/routers_tests.rb
Normal file
21
tests/openstack/models/network/routers_tests.rb
Normal 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
|
75
tests/openstack/requests/network/router_tests.rb
Normal file
75
tests/openstack/requests/network/router_tests.rb
Normal 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
|
Loading…
Add table
Reference in a new issue