misty 0.1.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +222 -1
- data/lib/misty.rb +8 -0
- data/lib/misty/auth.rb +60 -0
- data/lib/misty/auth/auth_v2.rb +46 -0
- data/lib/misty/auth/auth_v3.rb +58 -0
- data/lib/misty/autoload.rb +82 -0
- data/lib/misty/cloud.rb +133 -0
- data/lib/misty/http/client.rb +115 -0
- data/lib/misty/http/direct.rb +26 -0
- data/lib/misty/http/method_builder.rb +96 -0
- data/lib/misty/http/request.rb +75 -0
- data/lib/misty/misty.rb +51 -0
- data/lib/misty/openstack/aodh/aodh_v2.rb +12 -0
- data/lib/misty/openstack/aodh/v2.rb +20 -0
- data/lib/misty/openstack/ceilometer/ceilometer_v2.rb +13 -0
- data/lib/misty/openstack/ceilometer/v2.rb +20 -0
- data/lib/misty/openstack/cinder/cinder_v1.rb +35 -0
- data/lib/misty/openstack/cinder/cinder_v3.rb +148 -0
- data/lib/misty/openstack/cinder/v1.rb +24 -0
- data/lib/misty/openstack/cinder/v3.rb +24 -0
- data/lib/misty/openstack/designate/designate_v2.rb +69 -0
- data/lib/misty/openstack/designate/v2.rb +20 -0
- data/lib/misty/openstack/glance/glance_v1.rb +16 -0
- data/lib/misty/openstack/glance/glance_v2.rb +29 -0
- data/lib/misty/openstack/glance/v1.rb +20 -0
- data/lib/misty/openstack/glance/v2.rb +20 -0
- data/lib/misty/openstack/heat/heat_v1.rb +85 -0
- data/lib/misty/openstack/heat/v1.rb +24 -0
- data/lib/misty/openstack/ironic/ironic_v1.rb +71 -0
- data/lib/misty/openstack/ironic/v1.rb +26 -0
- data/lib/misty/openstack/karbor/karbor_v1.rb +32 -0
- data/lib/misty/openstack/karbor/v1.rb +20 -0
- data/lib/misty/openstack/keystone/keystone_v2_0.rb +11 -0
- data/lib/misty/openstack/keystone/keystone_v2_0_ext.rb +32 -0
- data/lib/misty/openstack/keystone/keystone_v3.rb +147 -0
- data/lib/misty/openstack/keystone/keystone_v3_ext.rb +124 -0
- data/lib/misty/openstack/keystone/v2_0.rb +23 -0
- data/lib/misty/openstack/keystone/v3.rb +23 -0
- data/lib/misty/openstack/magnum/magnum_v1.rb +41 -0
- data/lib/misty/openstack/magnum/v1.rb +26 -0
- data/lib/misty/openstack/manila/manila_v2.rb +143 -0
- data/lib/misty/openstack/manila/v2.rb +26 -0
- data/lib/misty/openstack/microversion.rb +62 -0
- data/lib/misty/openstack/neutron/neutron_v2_0.rb +205 -0
- data/lib/misty/openstack/neutron/v2_0.rb +20 -0
- data/lib/misty/openstack/nova/nova_v2_1.rb +269 -0
- data/lib/misty/openstack/nova/v2_1.rb +40 -0
- data/lib/misty/openstack/sahara/sahara_v1_1.rb +77 -0
- data/lib/misty/openstack/sahara/v1_1.rb +20 -0
- data/lib/misty/openstack/searchlight/searchlight_v1.rb +15 -0
- data/lib/misty/openstack/searchlight/v1.rb +20 -0
- data/lib/misty/openstack/senlin/senlin_v1.rb +66 -0
- data/lib/misty/openstack/senlin/v1.rb +20 -0
- data/lib/misty/openstack/swift/swift_v1.rb +23 -0
- data/lib/misty/openstack/swift/v1.rb +20 -0
- data/lib/misty/openstack/trove/trove_v1_0.rb +51 -0
- data/lib/misty/openstack/trove/v1_0.rb +20 -0
- data/lib/misty/openstack/zaqar/v2.rb +20 -0
- data/lib/misty/openstack/zaqar/zaqar_v2.rb +46 -0
- data/lib/misty/version.rb +2 -2
- data/test/integration/compute_test.rb +35 -0
- data/test/integration/network_test.rb +34 -0
- data/test/integration/orchestration_test.rb +92 -0
- data/test/integration/test_helper.rb +19 -0
- data/test/integration/vcr/compute_using_nova_v2_1.yml +1107 -0
- data/test/integration/vcr/network_using_neutron_v2_0.yml +1029 -0
- data/test/integration/vcr/orchestration_using_heat_v1.yml +1457 -0
- data/test/unit/auth_helper.rb +52 -0
- data/test/unit/auth_test.rb +99 -0
- data/test/unit/cloud/requests_test.rb +113 -0
- data/test/unit/cloud/services_test.rb +171 -0
- data/test/unit/cloud_test.rb +145 -0
- data/test/unit/http/client_test.rb +74 -0
- data/test/unit/http/direct_test.rb +103 -0
- data/test/unit/http/method_builder_test.rb +133 -0
- data/test/unit/http/request_test.rb +123 -0
- data/test/unit/misty_test.rb +36 -0
- data/test/unit/openstack/APIs_test.rb +40 -0
- data/test/unit/openstack/microversion_test.rb +70 -0
- data/test/unit/service_helper.rb +25 -0
- data/test/unit/test_helper.rb +8 -0
- metadata +170 -5
@@ -0,0 +1,52 @@
|
|
1
|
+
def auth_response_v3(type, name)
|
2
|
+
{ 'token' =>
|
3
|
+
{ 'methods' => ['password'],
|
4
|
+
'roles' => [{ 'id' => 'id_roles', 'name' => 'admin' }],
|
5
|
+
'expires_at' => '2016-11-29T07:45:29.908554Z',
|
6
|
+
'project' => { 'domain' => { 'id' => 'default', 'name' => 'Default' }, 'id' => 'id_project', 'name' => 'admin' },
|
7
|
+
'catalog' =>
|
8
|
+
[{ 'endpoints' =>
|
9
|
+
[{ 'region_id' => 'regionOne',
|
10
|
+
'url' => 'http://localhost',
|
11
|
+
'region' => 'regionOne',
|
12
|
+
'interface' => 'internal',
|
13
|
+
'id' => 'id_endpoint_internal' },
|
14
|
+
{ 'region_id' => 'regionOne',
|
15
|
+
'url' => 'http://localhost',
|
16
|
+
'region' => 'regionOne',
|
17
|
+
'interface' => 'public',
|
18
|
+
'id' => 'id_endpoint_public' },
|
19
|
+
{ 'region_id' => 'regionOne',
|
20
|
+
'url' => 'http://localhost',
|
21
|
+
'region' => 'regionOne',
|
22
|
+
'interface' => 'admin',
|
23
|
+
'id' => 'id_endpoint_admin' }],
|
24
|
+
'type' => type,
|
25
|
+
'id' => 'id_endpoints',
|
26
|
+
'name' => name }],
|
27
|
+
'user' => { 'domain' => { 'id' => 'default', 'name' => 'Default' }, 'id' => 'id_user', 'name' => 'admin' },
|
28
|
+
'audit_ids' => ['id_audits'],
|
29
|
+
'issued_at' => '2016-11-29T06:45:29.908578Z' } }
|
30
|
+
end
|
31
|
+
|
32
|
+
def auth_response_v2(type, name)
|
33
|
+
{ 'access' =>
|
34
|
+
{ 'token' =>
|
35
|
+
{ 'issued_at' => '2016-12-05T10:44:31.454741Z',
|
36
|
+
'expires' => '2016-12-05T11:44:31Z',
|
37
|
+
'id' => '4ae647d3a5294690a3c29bc658e17e26',
|
38
|
+
'tenant' => { 'description' => 'admin tenant', 'enabled' => true, 'id' => 'tenant_id', 'name' => 'admin' },
|
39
|
+
'audit_ids' => ['Ye0Rq1HzTk2ggUAg8nDGbQ'] },
|
40
|
+
'serviceCatalog' =>
|
41
|
+
[{ 'endpoints' =>
|
42
|
+
[{ 'adminURL' => 'http://localhost',
|
43
|
+
'region' => 'regionOne',
|
44
|
+
'internalURL' => 'http://localhost',
|
45
|
+
'id' => 'id_endpoints',
|
46
|
+
'publicURL' => 'http://localhost' }],
|
47
|
+
'endpoints_links' => [],
|
48
|
+
'type' => type,
|
49
|
+
'name' => name }],
|
50
|
+
'user' => { 'username' => 'admin', 'roles_links' => [], 'id' => 'user_id', 'roles' => [{ 'name' => 'admin' }], 'name' => 'admin' },
|
51
|
+
'metadata' => { 'is_admin' => 0, 'roles' => ['role_id'] } } }
|
52
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'auth_helper'
|
3
|
+
|
4
|
+
describe Misty::Auth do
|
5
|
+
describe ".new" do
|
6
|
+
let(:authv3_creds) do
|
7
|
+
{
|
8
|
+
:url => "http://localhost:5000",
|
9
|
+
:user => "admin",
|
10
|
+
:password => "secret",
|
11
|
+
:project => "admin",
|
12
|
+
:domain => "default"
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:authv2_creds) do
|
17
|
+
{
|
18
|
+
:url => "http://localhost:5000",
|
19
|
+
:user => "admin",
|
20
|
+
:password => "secret",
|
21
|
+
:tenant => "admin"
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
describe Misty::AuthV3 do
|
26
|
+
it "#new fails when missing credentials" do
|
27
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
28
|
+
to_return(:status => 200, :body => "{\"token\":{\"catalog\":[]}}", :headers => {"x-subject-token"=>"token_data"})
|
29
|
+
|
30
|
+
proc do
|
31
|
+
Misty::AuthV3.new({})
|
32
|
+
end.must_raise Misty::Auth::CredentialsError
|
33
|
+
end
|
34
|
+
|
35
|
+
it "#get_token" do
|
36
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
37
|
+
to_return(:status => 200, :body => "{\"token\":{\"catalog\":[\"catalog_data\"]}}", :headers => {"x-subject-token"=>"token_data"})
|
38
|
+
|
39
|
+
auth = Misty::AuthV3.new(authv3_creds)
|
40
|
+
auth.stub :expired?, false do
|
41
|
+
auth.get_token.must_equal "token_data"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "#catalog" do
|
46
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
47
|
+
to_return(:status => 200, :body => "{\"token\":{\"catalog\":[\"catalog_data\"]}}", :headers => {"x-subject-token"=>"token_data"})
|
48
|
+
|
49
|
+
auth = Misty::AuthV3.new(authv3_creds)
|
50
|
+
auth.catalog.must_equal ["catalog_data"]
|
51
|
+
end
|
52
|
+
|
53
|
+
it "#get_endpoint" do
|
54
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
55
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("identity", "keystone")), :headers => {"x-subject-token"=>"token_data"})
|
56
|
+
|
57
|
+
auth = Misty::AuthV3.new(authv3_creds)
|
58
|
+
auth.get_endpoint(%w{identity}, "regionOne", "public").must_equal "http://localhost"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe Misty::AuthV2 do
|
63
|
+
it "#new fails when missing credentials" do
|
64
|
+
stub_request(:post, "http://localhost:5000/v2.0/tokens").
|
65
|
+
to_return(:status => 200, :body => "{\"access\":{\"token\":{\"id\":\"token_data\"}}}", :headers => {})
|
66
|
+
|
67
|
+
proc do
|
68
|
+
Misty::AuthV2.new({})
|
69
|
+
end.must_raise Misty::Auth::CredentialsError
|
70
|
+
end
|
71
|
+
|
72
|
+
it "#get_token" do
|
73
|
+
stub_request(:post, "http://localhost:5000/v2.0/tokens").
|
74
|
+
to_return(:status => 200, :body => "{\"access\":{\"token\":{\"id\":\"token_data\"},\"serviceCatalog\":[\"catalog_data\"]}}", :headers => {})
|
75
|
+
|
76
|
+
auth = Misty::AuthV2.new(authv2_creds)
|
77
|
+
auth.stub :expired?, false do
|
78
|
+
auth.get_token.must_equal "token_data"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it "#catalog" do
|
83
|
+
stub_request(:post, "http://localhost:5000/v2.0/tokens").
|
84
|
+
to_return(:status => 200, :body => "{\"access\":{\"token\":{\"id\":\"token_data\"},\"serviceCatalog\":[\"catalog_data\"]}}", :headers => {})
|
85
|
+
|
86
|
+
auth = Misty::AuthV2.new(authv2_creds)
|
87
|
+
auth.catalog.must_equal ["catalog_data"]
|
88
|
+
end
|
89
|
+
|
90
|
+
it "#get_endpoint" do
|
91
|
+
stub_request(:post, "http://localhost:5000/v2.0/tokens").
|
92
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v2("identity", "keystone")), :headers => {"x-subject-token"=>"token_data"})
|
93
|
+
|
94
|
+
auth = Misty::AuthV2.new(authv2_creds)
|
95
|
+
auth.get_endpoint(%w{identity}, "regionOne", "public").must_equal "http://localhost"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'auth_helper'
|
3
|
+
|
4
|
+
describe Misty::Cloud do
|
5
|
+
let(:cloud) do
|
6
|
+
auth = {
|
7
|
+
:url => "http://localhost:5000",
|
8
|
+
:user => "admin",
|
9
|
+
:password => "secret",
|
10
|
+
:project => "admin",
|
11
|
+
:domain => "default"
|
12
|
+
}
|
13
|
+
|
14
|
+
Misty::Cloud.new(:auth => auth)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "GET request" do
|
18
|
+
it "success without elements in path" do
|
19
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
20
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("network", "neutron")), :headers => {"x-subject-token"=>"token_data"})
|
21
|
+
|
22
|
+
stub_request(:get, "http://localhost/v2.0/networks").
|
23
|
+
to_return(:status => 200, :body => "list of networks", :headers => {})
|
24
|
+
|
25
|
+
cloud.network.list_networks.response.must_be_kind_of Net::HTTPOK
|
26
|
+
end
|
27
|
+
|
28
|
+
it "success adds the query option in path" do
|
29
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
30
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("network", "neutron")), :headers => {"x-subject-token"=>"token_data"})
|
31
|
+
|
32
|
+
stub_request(:get, "http://localhost/v2.0/networks?name=value").
|
33
|
+
to_return(:status => 200, :body => "list of networks", :headers => {})
|
34
|
+
|
35
|
+
cloud.network.list_networks("name=value").response.must_be_kind_of Net::HTTPOK
|
36
|
+
end
|
37
|
+
|
38
|
+
it "successful whith elements in path" do
|
39
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
40
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("image", "glance")), :headers => {"x-subject-token"=>"token_data"})
|
41
|
+
|
42
|
+
stub_request(:get, "http://localhost/v2/images/id1/members/id2").
|
43
|
+
to_return(:status => 200, :body => "list of images", :headers => {})
|
44
|
+
|
45
|
+
cloud.image.show_image_member_details("id1", "id2").response.must_be_kind_of Net::HTTPOK
|
46
|
+
end
|
47
|
+
|
48
|
+
it "fails when not enough arguments" do
|
49
|
+
proc do
|
50
|
+
# "/v2/images/{image_id}/members/{member_id}"
|
51
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
52
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("image", "glance")), :headers => {"x-subject-token"=>"token_data"})
|
53
|
+
|
54
|
+
cloud.image.show_image_member_details("id1")
|
55
|
+
end.must_raise ArgumentError
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "POST request" do
|
60
|
+
it "successful without elements in path" do
|
61
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
62
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("identity", "keystone")), :headers => {"x-subject-token"=>"token_data"})
|
63
|
+
|
64
|
+
stub_request(:post, "http://localhost/v3/projects").
|
65
|
+
to_return(:status => 201, :body => "list of projects", :headers => {})
|
66
|
+
|
67
|
+
cloud.identity.create_project("{\"project\":{\"name\":\"value\"}}").response.must_be_kind_of Net::HTTPCreated
|
68
|
+
end
|
69
|
+
|
70
|
+
it "sucessful whith elements in pathwhith elements in path" do
|
71
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
72
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("orchestration", "heat")), :headers => {"x-subject-token"=>"token_data"})
|
73
|
+
|
74
|
+
stub_request(:post, "http://localhost/stacks/id1/id2/snapshots").
|
75
|
+
to_return(:status => 201, :body => "snapshots", :headers => {})
|
76
|
+
|
77
|
+
cloud.orchestration.snapshot_a_stack("id1", "id2", "{\"key\": \"value\"}").response.must_be_kind_of Net::HTTPCreated
|
78
|
+
end
|
79
|
+
|
80
|
+
it "fails when not enough arguments" do
|
81
|
+
proc do
|
82
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
83
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("orchestration", "heat")), :headers => {"x-subject-token"=>"token_data"})
|
84
|
+
|
85
|
+
cloud.orchestration.snapshot_a_stack("id1")
|
86
|
+
end.must_raise ArgumentError
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "DELETE request" do
|
91
|
+
it "success" do
|
92
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
93
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("identity", "keystone")), :headers => {"x-subject-token"=>"token_data"})
|
94
|
+
|
95
|
+
stub_request(:delete, "http://localhost/v3/projects/project_id").
|
96
|
+
to_return(:status => 204, :body => "list of projects", :headers => {})
|
97
|
+
|
98
|
+
cloud.identity.delete_project("project_id").response.must_be_kind_of Net::HTTPNoContent
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "PUT request" do
|
103
|
+
it "success" do
|
104
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
105
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("identity", "keystone")), :headers => {"x-subject-token"=>"token_data"})
|
106
|
+
|
107
|
+
stub_request(:put, "http://localhost/v3/domains/domain_id/groups/group_id/roles/roles_id").
|
108
|
+
to_return(:status => 200, :body => "list of group/role for a domain", :headers => {})
|
109
|
+
|
110
|
+
cloud.identity.assign_role_to_group_on_domain("domain_id", "group_id", "roles_id").response.must_be_kind_of Net::HTTPOK
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'auth_helper'
|
3
|
+
|
4
|
+
describe "Misty::Cloud" do
|
5
|
+
let(:cloud) do
|
6
|
+
auth = {
|
7
|
+
:url => "http://localhost:5000",
|
8
|
+
:user => "admin",
|
9
|
+
:password => "secret",
|
10
|
+
:project => "admin",
|
11
|
+
:domain => "default"
|
12
|
+
}
|
13
|
+
|
14
|
+
Misty::Cloud.new(:auth => auth)
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:auth_body) do
|
18
|
+
{ 'auth' => {
|
19
|
+
'identity' => {
|
20
|
+
'methods' => ['password'],
|
21
|
+
'password' => {
|
22
|
+
'user' => {
|
23
|
+
'name' => 'admin',
|
24
|
+
'domain' => { 'id' => 'default' },
|
25
|
+
'password' => 'secret'
|
26
|
+
}
|
27
|
+
}
|
28
|
+
},
|
29
|
+
'scope' => { 'project' => { 'name' => 'admin', 'domain' => { 'id' => 'default' } } }
|
30
|
+
} }
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:auth_headers) do
|
34
|
+
{ 'Accept' => 'application/json',
|
35
|
+
'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
|
36
|
+
'Content-Type' => 'application/json',
|
37
|
+
'User-Agent' => 'Ruby' }
|
38
|
+
end
|
39
|
+
|
40
|
+
let(:versions) do
|
41
|
+
{ 'versions' =>
|
42
|
+
[{ 'status' => 'SUPPORTED',
|
43
|
+
'updated' => '2011-01-21T11:33:21Z',
|
44
|
+
'links' => [{ 'href' => 'http://localhost/v2/', 'rel' => 'self' }],
|
45
|
+
'min_version' => '',
|
46
|
+
'version' => '',
|
47
|
+
'id' => 'v2.0' },
|
48
|
+
{ 'status' => 'CURRENT',
|
49
|
+
'updated' => '2013-07-23T11:33:21Z',
|
50
|
+
'links' => [{ 'href' => 'http://localhost/v2.1/', 'rel' => 'self' }],
|
51
|
+
'min_version' => '2.1',
|
52
|
+
'version' => '2.25',
|
53
|
+
'id' => 'v2.1' }] }
|
54
|
+
end
|
55
|
+
|
56
|
+
let(:token_header) { {"x-subject-token"=>"token_data"} }
|
57
|
+
|
58
|
+
it "fails when method is missing" do
|
59
|
+
proc do
|
60
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
61
|
+
with(:body => JSON.dump(auth_body), :headers => auth_headers).
|
62
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("compute", "nova")), :headers => token_header)
|
63
|
+
|
64
|
+
stub_request(:get, "http://localhost/").
|
65
|
+
with(:headers => auth_headers).
|
66
|
+
to_return(:status => 200, :body => JSON.dump(versions), :headers => {})
|
67
|
+
|
68
|
+
cloud.compute.undefined_method
|
69
|
+
end.must_raise NoMethodError
|
70
|
+
end
|
71
|
+
|
72
|
+
it "#baremetal" do
|
73
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
74
|
+
with(:body => JSON.dump(auth_body), :headers => auth_headers).
|
75
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("baremetal", "ironic")), :headers => token_header)
|
76
|
+
|
77
|
+
stub_request(:get, "http://localhost/").
|
78
|
+
with(:headers => auth_headers).
|
79
|
+
to_return(:status => 200, :body => JSON.dump(versions), :headers => {})
|
80
|
+
|
81
|
+
cloud.baremetal.must_be_kind_of Misty::Openstack::Ironic::V1
|
82
|
+
end
|
83
|
+
|
84
|
+
it "#blockStorage" do
|
85
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
86
|
+
with(:body => JSON.dump(auth_body), :headers => auth_headers).
|
87
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("volume", "cinder")), :headers => token_header)
|
88
|
+
|
89
|
+
cloud.block_storage.must_be_kind_of Misty::Openstack::Cinder::V3
|
90
|
+
end
|
91
|
+
|
92
|
+
it "#compute" do
|
93
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
94
|
+
with(:body => JSON.dump(auth_body), :headers => auth_headers).
|
95
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("compute", "nova")), :headers => token_header)
|
96
|
+
|
97
|
+
stub_request(:get, "http://localhost/").
|
98
|
+
with(:headers => auth_headers).
|
99
|
+
to_return(:status => 200, :body => JSON.dump(versions), :headers => {})
|
100
|
+
|
101
|
+
cloud.compute.must_be_kind_of Misty::Openstack::Nova::V2_1
|
102
|
+
end
|
103
|
+
|
104
|
+
it "#dataProcessing" do
|
105
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
106
|
+
with(:body => JSON.dump(auth_body), :headers => auth_headers).
|
107
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("data-processing", "sahara")), :headers => token_header)
|
108
|
+
|
109
|
+
cloud.data_processing.must_be_kind_of Misty::Openstack::Sahara::V1_1
|
110
|
+
end
|
111
|
+
|
112
|
+
it "#identity" do
|
113
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
114
|
+
with(:body => JSON.dump(auth_body), :headers => auth_headers).
|
115
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("identity", "keystone")), :headers => token_header)
|
116
|
+
|
117
|
+
cloud.identity.must_be_kind_of Misty::Openstack::Keystone::V3
|
118
|
+
end
|
119
|
+
|
120
|
+
it "#image" do
|
121
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
122
|
+
with(:body => JSON.dump(auth_body), :headers => auth_headers).
|
123
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("image", "glance")), :headers => token_header)
|
124
|
+
|
125
|
+
cloud.image.must_be_kind_of Misty::Openstack::Glance::V2
|
126
|
+
end
|
127
|
+
|
128
|
+
it "#network" do
|
129
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
130
|
+
with(:body => JSON.dump(auth_body), :headers => auth_headers).
|
131
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("network", "neutron")), :headers => token_header)
|
132
|
+
|
133
|
+
cloud.network.must_be_kind_of Misty::Openstack::Neutron::V2_0
|
134
|
+
end
|
135
|
+
|
136
|
+
it "#objectStorage" do
|
137
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
138
|
+
with(:body => JSON.dump(auth_body), :headers => auth_headers).
|
139
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("object-store", "swift")), :headers => token_header)
|
140
|
+
|
141
|
+
cloud.object_storage.must_be_kind_of Misty::Openstack::Swift::V1
|
142
|
+
end
|
143
|
+
|
144
|
+
it "#orchestration" do
|
145
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
146
|
+
with(:body => JSON.dump(auth_body), :headers => auth_headers).
|
147
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("orchestration", "heat")), :headers => token_header)
|
148
|
+
|
149
|
+
cloud.orchestration.must_be_kind_of Misty::Openstack::Heat::V1
|
150
|
+
end
|
151
|
+
|
152
|
+
it "#search" do
|
153
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
154
|
+
with(:body => JSON.dump(auth_body), :headers => auth_headers).
|
155
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("search", "searchlight")), :headers => token_header)
|
156
|
+
|
157
|
+
cloud.search.must_be_kind_of Misty::Openstack::Searchlight::V1
|
158
|
+
end
|
159
|
+
|
160
|
+
it "#sharedFileSystems" do
|
161
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
162
|
+
with(:body => JSON.dump(auth_body), :headers => auth_headers).
|
163
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("shared-file-systems", "manila")), :headers => token_header)
|
164
|
+
|
165
|
+
stub_request(:get, "http://localhost/").
|
166
|
+
with(:headers => auth_headers).
|
167
|
+
to_return(:status => 200, :body => JSON.dump(versions), :headers => {})
|
168
|
+
|
169
|
+
cloud.shared_file_systems.must_be_kind_of Misty::Openstack::Manila::V2
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'service_helper'
|
3
|
+
require 'auth_helper'
|
4
|
+
|
5
|
+
describe "#dot_to_underscore" do
|
6
|
+
it "returns a valid name" do
|
7
|
+
name = Misty::Cloud.dot_to_underscore("v20.90.01")
|
8
|
+
name.must_equal "v20_90_01"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe Misty::Cloud do
|
13
|
+
describe "A service" do
|
14
|
+
let(:auth) do
|
15
|
+
stub_request(:post, "http://localhost:5000/v3/auth/tokens").
|
16
|
+
with(:body => "{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"name\":\"admin\",\"domain\":{\"id\":\"default\"},\"password\":\"secret\"}}},\"scope\":{\"project\":{\"name\":\"admin\",\"domain\":{\"id\":\"default\"}}}}}",
|
17
|
+
:headers => {'Accept'=>'application/json', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}).
|
18
|
+
to_return(:status => 200, :body => JSON.dump(auth_response_v3("identity", "keystone")), :headers => {"x-subject-token"=>"token_data"})
|
19
|
+
|
20
|
+
auth = {
|
21
|
+
:url => "http://localhost:5000",
|
22
|
+
:user => "admin",
|
23
|
+
:password => "secret",
|
24
|
+
:project => "admin",
|
25
|
+
:domain => "default"
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
it "uses default version" do
|
30
|
+
cloud = Misty::Cloud.new(:auth => auth)
|
31
|
+
cloud.services[:identity].must_equal ({:keystone => "v3"})
|
32
|
+
end
|
33
|
+
|
34
|
+
it "uses provided version" do
|
35
|
+
cloud = Misty::Cloud.new(:auth => auth, :identity => {:api_version => "v2.0"})
|
36
|
+
cloud.services[:identity].must_equal ({:keystone => "v2.0"})
|
37
|
+
end
|
38
|
+
|
39
|
+
it "uses default version when provided version is out of range" do
|
40
|
+
cloud = Misty::Cloud.new(:auth => auth, :identity => {:api_version => "v1"})
|
41
|
+
cloud.services[:identity].must_equal ({:keystone => "v3"})
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "All SERVICES" do
|
46
|
+
it "have a method defined" do
|
47
|
+
Misty::SERVICES.each do |service|
|
48
|
+
method = Misty::Cloud.method_defined?(service.name)
|
49
|
+
method.must_equal true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#new" do
|
55
|
+
describe "fails" do
|
56
|
+
it "when no credentials" do
|
57
|
+
proc do
|
58
|
+
Misty::Cloud.new
|
59
|
+
end.must_raise Misty::Auth::CredentialsError
|
60
|
+
end
|
61
|
+
|
62
|
+
it "with empty credentials" do
|
63
|
+
proc do
|
64
|
+
Misty::Cloud.new(:auth => {})
|
65
|
+
end.must_raise Misty::Auth::CredentialsError
|
66
|
+
end
|
67
|
+
|
68
|
+
it "with incomplete credentials" do
|
69
|
+
proc do
|
70
|
+
Misty::Cloud.new(:auth => {:user => "user", :url => "http://localhost" })
|
71
|
+
end.must_raise Misty::Auth::CredentialsError
|
72
|
+
end
|
73
|
+
|
74
|
+
it "without url" do
|
75
|
+
authv3_data = {
|
76
|
+
:user => "admin",
|
77
|
+
:password => "secret",
|
78
|
+
:project => "admin",
|
79
|
+
:domain => "default"
|
80
|
+
}
|
81
|
+
|
82
|
+
proc do
|
83
|
+
Misty::Cloud.new(:auth => authv3_data)
|
84
|
+
end.must_raise Misty::Auth::URLError
|
85
|
+
end
|
86
|
+
|
87
|
+
it "with empty url" do
|
88
|
+
authv3_data = {
|
89
|
+
:url => "",
|
90
|
+
:user => "admin",
|
91
|
+
:password => "secret",
|
92
|
+
:project => "admin",
|
93
|
+
:domain => "default"
|
94
|
+
}
|
95
|
+
|
96
|
+
proc do
|
97
|
+
Misty::Cloud.new(:auth => authv3_data)
|
98
|
+
end.must_raise Misty::Auth::URLError
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "Authenticates" do
|
103
|
+
describe "with v2 credentials" do
|
104
|
+
let(:authv2_data) do
|
105
|
+
{
|
106
|
+
:url => "http://localhost:5000",
|
107
|
+
:user => "admin",
|
108
|
+
:password => "secret",
|
109
|
+
:tenant => "admin"
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
it "uses AuthV2" do
|
114
|
+
authv2 = Minitest::Mock.new
|
115
|
+
|
116
|
+
Misty::AuthV2.stub :new, authv2 do
|
117
|
+
cloud = Misty::Cloud.new(:auth => authv2_data)
|
118
|
+
authv2.verify
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "with v3 credentials" do
|
124
|
+
let(:authv3_data) do
|
125
|
+
{
|
126
|
+
:url => "http://localhost:5000",
|
127
|
+
:user => "admin",
|
128
|
+
:password => "secret",
|
129
|
+
:project => "admin",
|
130
|
+
:domain => "default"
|
131
|
+
}
|
132
|
+
end
|
133
|
+
|
134
|
+
it "uses AuthV3" do
|
135
|
+
authv3 = Minitest::Mock.new
|
136
|
+
|
137
|
+
Misty::AuthV3.stub :new, authv3 do
|
138
|
+
cloud = Misty::Cloud.new(:auth => authv3_data)
|
139
|
+
authv3.verify
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|