From 3edb6b205bbafe0ad2f30d50520591329ca88bc7 Mon Sep 17 00:00:00 2001 From: Darren Hague Date: Thu, 16 Jul 2015 13:56:40 +0100 Subject: [PATCH] [openstack] Add test for subnet creation Initially the test failed because too many params are set to nil instead of just gateway_ip (see https://github.com/fog/fog/pull/3613) - in fact gateway_ip is the *only* parameter where a null value should be passed to OpenStack. --- Gemfile | 1 + lib/fog/openstack/identity_v3.rb | 14 +- .../requests/network/create_subnet.rb | 2 +- spec/fog/openstack/network/common_setup.yml | 131 ++++++++++++++++ spec/fog/openstack/network/subnets_crud.yml | 140 ++++++++++++++++++ spec/fog/openstack/network_spec.rb | 43 ++++++ spec/fog/openstack/shared_context.rb | 4 +- 7 files changed, 325 insertions(+), 10 deletions(-) create mode 100644 spec/fog/openstack/network/common_setup.yml create mode 100644 spec/fog/openstack/network/subnets_crud.yml create mode 100644 spec/fog/openstack/network_spec.rb diff --git a/Gemfile b/Gemfile index 23db6d7c7..db20c6fc1 100644 --- a/Gemfile +++ b/Gemfile @@ -4,6 +4,7 @@ group :development, :test do # This is here because gemspec doesn't support require: false gem "netrc", :require => false gem "octokit", :require => false + gem 'rspec', :require => false end gemspec diff --git a/lib/fog/openstack/identity_v3.rb b/lib/fog/openstack/identity_v3.rb index b8d5e3a59..6923f1840 100644 --- a/lib/fog/openstack/identity_v3.rb +++ b/lib/fog/openstack/identity_v3.rb @@ -182,13 +182,13 @@ module Fog retried = false begin response = @connection.request(params.merge({ - :headers => { - 'Content-Type' => 'application/json', - 'Accept' => 'application/json', - 'X-Auth-Token' => @auth_token - }.merge!(params[:headers] || {}), - :path => "#{@path}/#{params[:path]}" #, - })) + :headers => params.fetch(:headers,{}).merge({ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + 'X-Auth-Token' => @auth_token + }), + :path => "#{@path}/#{params[:path]}" + })) rescue Excon::Errors::Unauthorized => error raise if retried retried = true diff --git a/lib/fog/openstack/requests/network/create_subnet.rb b/lib/fog/openstack/requests/network/create_subnet.rb index 22fd522c4..db52ae3fd 100644 --- a/lib/fog/openstack/requests/network/create_subnet.rb +++ b/lib/fog/openstack/requests/network/create_subnet.rb @@ -14,7 +14,7 @@ module Fog vanilla_options = [:name, :gateway_ip, :allocation_pools, :dns_nameservers, :host_routes, :enable_dhcp, :tenant_id] - vanilla_options.each do |key| + vanilla_options.reject{ |o| options[o].nil? unless o == :gateway_ip }.each do |key| data['subnet'][key] = options[key] end diff --git a/spec/fog/openstack/network/common_setup.yml b/spec/fog/openstack/network/common_setup.yml new file mode 100644 index 000000000..c254baaee --- /dev/null +++ b/spec/fog/openstack/network/common_setup.yml @@ -0,0 +1,131 @@ +--- +http_interactions: +- request: + method: post + uri: http://devstack.openstack.stack:5000/v3/auth/tokens + body: + encoding: UTF-8 + string: ! '{"auth":{"identity":{"methods":["password"],"password":{"user":{"password":"password","domain":{"name":"Default"},"name":"admin"}}},"scope":{"project":{"name":"admin","domain":{"name":"Default"}}}}}' + headers: + User-Agent: + - fog-core/1.32.0 + Content-Type: + - application/json + response: + status: + code: 201 + message: '' + headers: + Date: + - Thu, 16 Jul 2015 13:30:01 GMT + Server: + - Apache/2.4.7 (Ubuntu) + X-Subject-Token: + - 0afbf49d007a4d82850b853b703025d7 + Vary: + - X-Auth-Token + X-Openstack-Request-Id: + - req-16fb6527-c6ed-48fc-908c-c4f02a44178a + Content-Length: + - '5409' + Content-Type: + - application/json + body: + encoding: US-ASCII + string: ! '{"token": {"methods": ["password"], "roles": [{"id": "c7fc2d49d2f546ab8de6a0901d4408a4", + "name": "admin"}], "expires_at": "2015-07-16T14:30:01.464420Z", "project": + {"domain": {"id": "default", "name": "Default"}, "id": "5b1c4e7218d94dc8879d542002ffbc48", + "name": "admin"}, "catalog": [{"endpoints": [{"region_id": "RegionOne", "url": + "http://devstack.openstack.stack:8773/", "region": "RegionOne", "interface": "admin", + "id": "2339b8aa02b3406887552369c5cd8419"}, {"region_id": "RegionOne", "url": + "http://devstack.openstack.stack:8773/", "region": "RegionOne", "interface": "internal", + "id": "4d53c32a49db4d8b96e2e51c43a46a1b"}, {"region_id": "RegionOne", "url": + "http://devstack.openstack.stack:8773/", "region": "RegionOne", "interface": "public", + "id": "cf5bc6fdc4ce416b818c79f45f29f081"}], "type": "ec2", "id": "1b844219e646400ca44176eac9186533", + "name": "ec2"}, {"endpoints": [{"region_id": "RegionOne", "url": "http://devstack.openstack.stack:5000/v2.0", + "region": "RegionOne", "interface": "public", "id": "28314fddad8543e0aa2a2d207d4018a9"}, + {"region_id": "RegionOne", "url": "http://devstack.openstack.stack:5000/v2.0", "region": + "RegionOne", "interface": "internal", "id": "7c4f7842298b4b8688cb2885cc4d8330"}, + {"region_id": "RegionOne", "url": "http://devstack.openstack.stack:35357/v2.0", "region": + "RegionOne", "interface": "admin", "id": "f745fca524c149ac934a0d8d392f86a6"}], + "type": "identity", "id": "24a331955813408d8676151549cd1b78", "name": "keystone"}, + {"endpoints": [{"region_id": "RegionOne", "url": "http://devstack.openstack.stack:8776/v1/5b1c4e7218d94dc8879d542002ffbc48", + "region": "RegionOne", "interface": "public", "id": "8ff1521affcb4ca3a335993769e9b8f0"}, + {"region_id": "RegionOne", "url": "http://devstack.openstack.stack:8776/v1/5b1c4e7218d94dc8879d542002ffbc48", + "region": "RegionOne", "interface": "internal", "id": "e9f7bda53a7d4649a2619ba1b2f10be5"}, + {"region_id": "RegionOne", "url": "http://devstack.openstack.stack:8776/v1/5b1c4e7218d94dc8879d542002ffbc48", + "region": "RegionOne", "interface": "admin", "id": "f9ff42e36283417ba05572496dfff99b"}], + "type": "volume", "id": "3f9c8198a2724d0ba97648cb8ae33f3d", "name": "cinder"}, + {"endpoints": [{"region_id": "RegionOne", "url": "http://devstack.openstack.stack:8774/v2.1/5b1c4e7218d94dc8879d542002ffbc48", + "region": "RegionOne", "interface": "public", "id": "015d9bdeec2c43adb181692fcb52cf3b"}, + {"region_id": "RegionOne", "url": "http://devstack.openstack.stack:8774/v2.1/5b1c4e7218d94dc8879d542002ffbc48", + "region": "RegionOne", "interface": "internal", "id": "e52097447df046cfabc33d6f38a0f9be"}, + {"region_id": "RegionOne", "url": "http://devstack.openstack.stack:8774/v2.1/5b1c4e7218d94dc8879d542002ffbc48", + "region": "RegionOne", "interface": "admin", "id": "fe3a8dbf55304123aff67e8344c07376"}], + "type": "computev21", "id": "407eeaefaca34073baf78c59f3c26dc3", "name": "novav21"}, + {"endpoints": [{"region_id": "RegionOne", "url": "http://devstack.openstack.stack:9292", + "region": "RegionOne", "interface": "public", "id": "12761b1c0f634f7581b986da5080b84a"}, + {"region_id": "RegionOne", "url": "http://devstack.openstack.stack:9292", "region": + "RegionOne", "interface": "internal", "id": "7968eace2b18475f877b040eec185987"}, + {"region_id": "RegionOne", "url": "http://devstack.openstack.stack:9292", "region": + "RegionOne", "interface": "admin", "id": "eda6b4b034d0431bb3fcd3229326c622"}], + "type": "image", "id": "48c8845a0eb243d6802b629dbed2dc79", "name": "glance"}, + {"endpoints": [{"region_id": "RegionOne", "url": "http://devstack.openstack.stack:8774/v2/5b1c4e7218d94dc8879d542002ffbc48", + "region": "RegionOne", "interface": "internal", "id": "00d4a072dd074a6398e5cd35dbbf6913"}, + {"region_id": "RegionOne", "url": "http://devstack.openstack.stack:8774/v2/5b1c4e7218d94dc8879d542002ffbc48", + "region": "RegionOne", "interface": "public", "id": "55f0c7b7f8b348c7b7de153ac3388ac8"}, + {"region_id": "RegionOne", "url": "http://devstack.openstack.stack:8774/v2/5b1c4e7218d94dc8879d542002ffbc48", + "region": "RegionOne", "interface": "admin", "id": "afcff3fbd3b04313be932785c50dc0ef"}], + "type": "compute", "id": "599e0e4ff2584630bc0fd242443af297", "name": "nova"}, + {"endpoints": [{"region_id": "RegionOne", "url": "http://devstack.openstack.stack:8776/v2/5b1c4e7218d94dc8879d542002ffbc48", + "region": "RegionOne", "interface": "admin", "id": "43c972f7af7f465cb3f49d91988427bf"}, + {"region_id": "RegionOne", "url": "http://devstack.openstack.stack:8776/v2/5b1c4e7218d94dc8879d542002ffbc48", + "region": "RegionOne", "interface": "internal", "id": "50c9a1fe06094aea908034e55c5e33fe"}, + {"region_id": "RegionOne", "url": "http://devstack.openstack.stack:8776/v2/5b1c4e7218d94dc8879d542002ffbc48", + "region": "RegionOne", "interface": "public", "id": "dfa345861e48478d8d05ae1d340e5cc9"}], + "type": "volumev2", "id": "6520c738495d4688a243d9883213259c", "name": "cinderv2"}, + {"endpoints": [{"region_id": "RegionOne", "url": "http://devstack.openstack.stack:9696/", + "region": "RegionOne", "interface": "public", "id": "84df3f19b54d46fdbf3c5ecbfb322b10"}, + {"region_id": "RegionOne", "url": "http://devstack.openstack.stack:9696/", "region": + "RegionOne", "interface": "admin", "id": "9bba82867f4641cfb175a4866f8a8293"}, + {"region_id": "RegionOne", "url": "http://devstack.openstack.stack:9696/", "region": + "RegionOne", "interface": "internal", "id": "e325c8d1fb0542ccb79dcf4b8a80eb49"}], + "type": "network", "id": "fcc46107290f4aa6bb38153ab0a3f63b", "name": "neutron"}], + "extras": {}, "user": {"domain": {"id": "default", "name": "Default"}, "id": + "3c3ae1c4f69e404282372fa02bf53cd6", "name": "admin"}, "audit_ids": ["v-kjH6JJTG6PzR3OTMmqfg"], + "issued_at": "2015-07-16T13:30:01.464477Z"}}' + http_version: + recorded_at: Thu, 16 Jul 2015 13:30:18 GMT +- request: + method: get + uri: http://devstack.openstack.stack:9696/ + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - fog-core/1.32.0 + Content-Type: + - application/json + Accept: + - application/json + X-Auth-Token: + - 0afbf49d007a4d82850b853b703025d7 + response: + status: + code: 200 + message: '' + headers: + Content-Type: + - application/json; charset=UTF-8 + Content-Length: + - '122' + Date: + - Thu, 16 Jul 2015 13:30:01 GMT + body: + encoding: US-ASCII + string: ! '{"versions": [{"status": "CURRENT", "id": "v2.0", "links": [{"href": + "http://devstack.openstack.stack:9696/v2.0", "rel": "self"}]}]}' + http_version: + recorded_at: Thu, 16 Jul 2015 13:30:18 GMT +recorded_with: VCR 2.9.3 diff --git a/spec/fog/openstack/network/subnets_crud.yml b/spec/fog/openstack/network/subnets_crud.yml new file mode 100644 index 000000000..df4a4d471 --- /dev/null +++ b/spec/fog/openstack/network/subnets_crud.yml @@ -0,0 +1,140 @@ +--- +http_interactions: +- request: + method: post + uri: http://devstack.openstack.stack:9696/v2.0/networks + body: + encoding: UTF-8 + string: ! '{"network":{"name":"foo-net12","shared":false}}' + headers: + User-Agent: + - fog-core/1.32.0 + Content-Type: + - application/json + Accept: + - application/json + X-Auth-Token: + - 0afbf49d007a4d82850b853b703025d7 + response: + status: + code: 201 + message: '' + headers: + Content-Type: + - application/json; charset=UTF-8 + Content-Length: + - '344' + X-Openstack-Request-Id: + - req-cc7677e6-9700-4215-b16d-d4a867db376b + Date: + - Thu, 16 Jul 2015 13:30:02 GMT + body: + encoding: US-ASCII + string: ! '{"network": {"status": "ACTIVE", "subnets": [], "name": "foo-net12", + "provider:physical_network": null, "router:external": false, "tenant_id": + "5b1c4e7218d94dc8879d542002ffbc48", "admin_state_up": true, "mtu": 0, "shared": + false, "provider:network_type": "vxlan", "id": "0629b827-668a-443c-b73e-1725359350fb", + "provider:segmentation_id": 1104}}' + http_version: + recorded_at: Thu, 16 Jul 2015 13:30:19 GMT +- request: + method: post + uri: http://devstack.openstack.stack:9696/v2.0/subnets + body: + encoding: UTF-8 + string: ! '{"subnet":{"network_id":"0629b827-668a-443c-b73e-1725359350fb","cidr":"172.16.0.0/16","ip_version":4,"name":"my-network","gateway_ip":null}}' + headers: + User-Agent: + - fog-core/1.32.0 + Content-Type: + - application/json + Accept: + - application/json + X-Auth-Token: + - 0afbf49d007a4d82850b853b703025d7 + response: + status: + code: 201 + message: '' + headers: + Content-Type: + - application/json; charset=UTF-8 + Content-Length: + - '452' + X-Openstack-Request-Id: + - req-295d5e91-514b-4980-85a4-adce351161a8 + Date: + - Thu, 16 Jul 2015 13:30:02 GMT + body: + encoding: US-ASCII + string: ! '{"subnet": {"name": "my-network", "enable_dhcp": true, "network_id": + "0629b827-668a-443c-b73e-1725359350fb", "tenant_id": "5b1c4e7218d94dc8879d542002ffbc48", + "dns_nameservers": [], "gateway_ip": null, "ipv6_ra_mode": null, "allocation_pools": + [{"start": "172.16.0.1", "end": "172.16.255.254"}], "host_routes": [], "ip_version": + 4, "ipv6_address_mode": null, "cidr": "172.16.0.0/16", "id": "11bef948-6df8-4fa3-8c21-3fbd3cc4ca6d", + "subnetpool_id": null}}' + http_version: + recorded_at: Thu, 16 Jul 2015 13:30:19 GMT +- request: + method: delete + uri: http://devstack.openstack.stack:9696/v2.0/subnets/11bef948-6df8-4fa3-8c21-3fbd3cc4ca6d + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - fog-core/1.32.0 + Content-Type: + - application/json + Accept: + - application/json + X-Auth-Token: + - 0afbf49d007a4d82850b853b703025d7 + response: + status: + code: 204 + message: '' + headers: + Content-Length: + - '0' + X-Openstack-Request-Id: + - req-5c4205db-8183-4eeb-a702-e6e156f82db1 + Date: + - Thu, 16 Jul 2015 13:30:03 GMT + body: + encoding: US-ASCII + string: '' + http_version: + recorded_at: Thu, 16 Jul 2015 13:30:20 GMT +- request: + method: delete + uri: http://devstack.openstack.stack:9696/v2.0/networks/0629b827-668a-443c-b73e-1725359350fb + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - fog-core/1.32.0 + Content-Type: + - application/json + Accept: + - application/json + X-Auth-Token: + - 0afbf49d007a4d82850b853b703025d7 + response: + status: + code: 204 + message: '' + headers: + Content-Length: + - '0' + X-Openstack-Request-Id: + - req-f21f4c07-2e64-4920-a53d-19f221af0c99 + Date: + - Thu, 16 Jul 2015 13:30:03 GMT + body: + encoding: US-ASCII + string: '' + http_version: + recorded_at: Thu, 16 Jul 2015 13:30:20 GMT +recorded_with: VCR 2.9.3 diff --git a/spec/fog/openstack/network_spec.rb b/spec/fog/openstack/network_spec.rb new file mode 100644 index 000000000..1ad2838b9 --- /dev/null +++ b/spec/fog/openstack/network_spec.rb @@ -0,0 +1,43 @@ +require 'fog/openstack/compute' +require 'fog/openstack/identity' +require 'fog/openstack/identity_v3' +require 'fog/openstack/network' + +if RUBY_VERSION =~ /1.8/ + require File.expand_path('../shared_context', __FILE__) +else + require_relative './shared_context' +end + +RSpec.describe Fog::Network::OpenStack do + + include_context 'OpenStack specs with VCR' + before :all do + setup_vcr_and_service( + :vcr_directory => 'spec/fog/openstack/network', + :service_class => Fog::Network::OpenStack + ) + end + + + it 'CRUD subnets' do + VCR.use_cassette('subnets_crud') do + begin + + foonet = @service.networks.create(:name => 'foo-net12', :shared => false) + + subnet = @service.subnets.create(:name => "my-network", :network_id => foonet.id, :cidr => '172.16.0.0/16', :ip_version => 4, :gateway_ip => nil) + + expect(subnet.name).to eq 'my-network' + + ensure + subnet.destroy if subnet + foonet.destroy if foonet + end + + end + end + + + +end diff --git a/spec/fog/openstack/shared_context.rb b/spec/fog/openstack/shared_context.rb index 88cb09bb9..2ec016002 100644 --- a/spec/fog/openstack/shared_context.rb +++ b/spec/fog/openstack/shared_context.rb @@ -37,7 +37,7 @@ RSpec.shared_context 'OpenStack specs with VCR' do Fog.interval = 0 # use an auth URL that matches our VCR recordings (IdentityV2 for most # services, but IdentityV3 test obviously needs IdentityV3 auth URL) - if @service_class == Fog::Identity::OpenStack::V3 + if [Fog::Identity::OpenStack::V3, Fog::Network::OpenStack].include? @service_class @os_auth_url = 'http://devstack.openstack.stack:5000/v3' else @os_auth_url = 'http://devstack.openstack.stack:5000/v2.0' @@ -67,7 +67,7 @@ RSpec.shared_context 'OpenStack specs with VCR' do # setup the service object VCR.use_cassette('common_setup') do - if @service_class == Fog::Identity::OpenStack::V3 + if @service_class == Fog::Identity::OpenStack::V3 || @os_auth_url.end_with?('/v3') options = { :openstack_auth_url => "#{@os_auth_url}/auth/tokens", :openstack_region => ENV['OS_REGION_NAME'] || 'RegionOne',