misty 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +222 -1
  3. data/lib/misty.rb +8 -0
  4. data/lib/misty/auth.rb +60 -0
  5. data/lib/misty/auth/auth_v2.rb +46 -0
  6. data/lib/misty/auth/auth_v3.rb +58 -0
  7. data/lib/misty/autoload.rb +82 -0
  8. data/lib/misty/cloud.rb +133 -0
  9. data/lib/misty/http/client.rb +115 -0
  10. data/lib/misty/http/direct.rb +26 -0
  11. data/lib/misty/http/method_builder.rb +96 -0
  12. data/lib/misty/http/request.rb +75 -0
  13. data/lib/misty/misty.rb +51 -0
  14. data/lib/misty/openstack/aodh/aodh_v2.rb +12 -0
  15. data/lib/misty/openstack/aodh/v2.rb +20 -0
  16. data/lib/misty/openstack/ceilometer/ceilometer_v2.rb +13 -0
  17. data/lib/misty/openstack/ceilometer/v2.rb +20 -0
  18. data/lib/misty/openstack/cinder/cinder_v1.rb +35 -0
  19. data/lib/misty/openstack/cinder/cinder_v3.rb +148 -0
  20. data/lib/misty/openstack/cinder/v1.rb +24 -0
  21. data/lib/misty/openstack/cinder/v3.rb +24 -0
  22. data/lib/misty/openstack/designate/designate_v2.rb +69 -0
  23. data/lib/misty/openstack/designate/v2.rb +20 -0
  24. data/lib/misty/openstack/glance/glance_v1.rb +16 -0
  25. data/lib/misty/openstack/glance/glance_v2.rb +29 -0
  26. data/lib/misty/openstack/glance/v1.rb +20 -0
  27. data/lib/misty/openstack/glance/v2.rb +20 -0
  28. data/lib/misty/openstack/heat/heat_v1.rb +85 -0
  29. data/lib/misty/openstack/heat/v1.rb +24 -0
  30. data/lib/misty/openstack/ironic/ironic_v1.rb +71 -0
  31. data/lib/misty/openstack/ironic/v1.rb +26 -0
  32. data/lib/misty/openstack/karbor/karbor_v1.rb +32 -0
  33. data/lib/misty/openstack/karbor/v1.rb +20 -0
  34. data/lib/misty/openstack/keystone/keystone_v2_0.rb +11 -0
  35. data/lib/misty/openstack/keystone/keystone_v2_0_ext.rb +32 -0
  36. data/lib/misty/openstack/keystone/keystone_v3.rb +147 -0
  37. data/lib/misty/openstack/keystone/keystone_v3_ext.rb +124 -0
  38. data/lib/misty/openstack/keystone/v2_0.rb +23 -0
  39. data/lib/misty/openstack/keystone/v3.rb +23 -0
  40. data/lib/misty/openstack/magnum/magnum_v1.rb +41 -0
  41. data/lib/misty/openstack/magnum/v1.rb +26 -0
  42. data/lib/misty/openstack/manila/manila_v2.rb +143 -0
  43. data/lib/misty/openstack/manila/v2.rb +26 -0
  44. data/lib/misty/openstack/microversion.rb +62 -0
  45. data/lib/misty/openstack/neutron/neutron_v2_0.rb +205 -0
  46. data/lib/misty/openstack/neutron/v2_0.rb +20 -0
  47. data/lib/misty/openstack/nova/nova_v2_1.rb +269 -0
  48. data/lib/misty/openstack/nova/v2_1.rb +40 -0
  49. data/lib/misty/openstack/sahara/sahara_v1_1.rb +77 -0
  50. data/lib/misty/openstack/sahara/v1_1.rb +20 -0
  51. data/lib/misty/openstack/searchlight/searchlight_v1.rb +15 -0
  52. data/lib/misty/openstack/searchlight/v1.rb +20 -0
  53. data/lib/misty/openstack/senlin/senlin_v1.rb +66 -0
  54. data/lib/misty/openstack/senlin/v1.rb +20 -0
  55. data/lib/misty/openstack/swift/swift_v1.rb +23 -0
  56. data/lib/misty/openstack/swift/v1.rb +20 -0
  57. data/lib/misty/openstack/trove/trove_v1_0.rb +51 -0
  58. data/lib/misty/openstack/trove/v1_0.rb +20 -0
  59. data/lib/misty/openstack/zaqar/v2.rb +20 -0
  60. data/lib/misty/openstack/zaqar/zaqar_v2.rb +46 -0
  61. data/lib/misty/version.rb +2 -2
  62. data/test/integration/compute_test.rb +35 -0
  63. data/test/integration/network_test.rb +34 -0
  64. data/test/integration/orchestration_test.rb +92 -0
  65. data/test/integration/test_helper.rb +19 -0
  66. data/test/integration/vcr/compute_using_nova_v2_1.yml +1107 -0
  67. data/test/integration/vcr/network_using_neutron_v2_0.yml +1029 -0
  68. data/test/integration/vcr/orchestration_using_heat_v1.yml +1457 -0
  69. data/test/unit/auth_helper.rb +52 -0
  70. data/test/unit/auth_test.rb +99 -0
  71. data/test/unit/cloud/requests_test.rb +113 -0
  72. data/test/unit/cloud/services_test.rb +171 -0
  73. data/test/unit/cloud_test.rb +145 -0
  74. data/test/unit/http/client_test.rb +74 -0
  75. data/test/unit/http/direct_test.rb +103 -0
  76. data/test/unit/http/method_builder_test.rb +133 -0
  77. data/test/unit/http/request_test.rb +123 -0
  78. data/test/unit/misty_test.rb +36 -0
  79. data/test/unit/openstack/APIs_test.rb +40 -0
  80. data/test/unit/openstack/microversion_test.rb +70 -0
  81. data/test/unit/service_helper.rb +25 -0
  82. data/test/unit/test_helper.rb +8 -0
  83. metadata +170 -5
@@ -0,0 +1,74 @@
1
+ require 'test_helper'
2
+ require 'service_helper'
3
+ require 'misty/http/client'
4
+
5
+ describe Misty::HTTP::Client do
6
+ describe "#self.prefix_path_to_ignore" do
7
+ it "returns empty String when undefined in API's module" do
8
+ Misty::Openstack::Neutron::V2_0::prefix_path_to_ignore.must_be_empty
9
+ end
10
+
11
+ it "returns String when defined in API's module" do
12
+ Misty::Openstack::Cinder::V3.prefix_path_to_ignore.must_equal "/v3/{tenant_id}"
13
+ end
14
+ end
15
+
16
+ describe "#requests" do
17
+ it "returns list of requests" do
18
+ list = service.requests
19
+ list.must_be_kind_of Array
20
+ list.must_include :list_service_profiles
21
+ end
22
+ end
23
+
24
+ describe "#headers_default" do
25
+ it "returns hash" do
26
+ service.headers_default.must_be_kind_of Hash
27
+ end
28
+ end
29
+
30
+ describe "#headers" do
31
+ it "returns hash" do
32
+ service.headers.must_be_kind_of Hash
33
+ end
34
+ end
35
+
36
+ describe "#baseclass" do
37
+ it "returns base class name" do
38
+ service.send(:baseclass).must_equal "V2_0"
39
+ end
40
+ end
41
+
42
+ describe "#net_http" do
43
+ it "returns a Net/http instance" do
44
+ uri = URI.parse("http://localhost")
45
+ service.send(:net_http, uri).must_be_instance_of Net::HTTP
46
+ end
47
+ end
48
+
49
+ describe "#setup" do
50
+ it "sets default options" do
51
+ options = service.send(:setup, {})
52
+ options.must_be_kind_of Misty::HTTP::Client::Options
53
+ options.base_path.must_be_nil
54
+ options.base_url.must_be_nil
55
+ options.interface.must_equal "public"
56
+ options.region_id.must_equal "regionOne"
57
+ options.service_names.must_include "network"
58
+ options.ssl_verify_mode.must_equal true
59
+ options.version.must_equal "CURRENT"
60
+ end
61
+
62
+ it "fails with invalid interface" do
63
+ proc do
64
+ service.send(:setup, {:interface => "something"})
65
+ end.must_raise Misty::HTTP::Client::InvalidDataError
66
+ end
67
+
68
+ it "fails unless ssl_verify_mode is a boolean" do
69
+ proc do
70
+ service.send(:setup, {:ssl_verify_mode => "something"})
71
+ end.must_raise Misty::HTTP::Client::InvalidDataError
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,103 @@
1
+ require 'test_helper'
2
+ require 'service_helper'
3
+ require 'misty/http/request'
4
+ require 'misty/http/direct'
5
+
6
+ describe Misty::HTTP::Direct do
7
+ describe "#base_set" do
8
+ it "returns @base_set" do
9
+ service.base_set(nil).must_equal ""
10
+ end
11
+
12
+ it "returns parameter" do
13
+ service.base_set("/another-base").must_equal "/another-base"
14
+ end
15
+ end
16
+
17
+ describe "#delete" do
18
+ it "successful without providing a base url" do
19
+ stub_request(:delete, "http://localhost/resource/test").
20
+ with(:headers => request_header).
21
+ to_return(:status => 204, :body => '', :headers => {})
22
+
23
+ response = service.delete('/resource/test')
24
+ response.must_be_kind_of Net::HTTPNoContent
25
+ response.body.must_be_nil
26
+ end
27
+
28
+ it "successful with a base url" do
29
+ stub_request(:delete, "http://localhost/another-base/resource/test").
30
+ with(:headers => request_header).
31
+ to_return(:status => 204, :body => '', :headers => {})
32
+
33
+ response = service.delete('/resource/test', "/another-base")
34
+ response.must_be_kind_of Net::HTTPNoContent
35
+ response.body.must_be_nil
36
+ end
37
+ end
38
+
39
+ describe "#get" do
40
+ it "successful without providing a base url" do
41
+ stub_request(:get, "http://localhost/resource/test").
42
+ with(:headers => request_header).
43
+ to_return(:status => 200, :body => '', :headers => {})
44
+
45
+ response = service.get('/resource/test')
46
+ response.must_be_kind_of Net::HTTPOK
47
+ response.body.must_be_nil
48
+ end
49
+
50
+ it "successful with a base url" do
51
+ stub_request(:get, "http://localhost/another-base/resource/test").
52
+ with(:headers => request_header).
53
+ to_return(:status => 200, :body => '', :headers => {})
54
+
55
+ response = service.get('/resource/test', "/another-base")
56
+ response.must_be_kind_of Net::HTTPOK
57
+ response.body.must_be_nil
58
+ end
59
+ end
60
+
61
+ describe "#post" do
62
+ it "successful without providing a base url" do
63
+ stub_request(:post, "http://localhost/resource/test").
64
+ with(:body => "{\"data\":\"value\"}", :headers => request_header).
65
+ to_return(:status => 201, :body => '', :headers => {})
66
+
67
+ response = service.post('/resource/test', "data" => "value")
68
+ response.must_be_kind_of Net::HTTPCreated
69
+ response.body.must_be_nil
70
+ end
71
+
72
+ it "successful with a base url" do
73
+ stub_request(:post, "http://localhost/another-base/resource/test").
74
+ with(:body => "{\"data\":\"value\"}", :headers => request_header).
75
+ to_return(:status => 201, :body => '', :headers => {})
76
+ response = service.post('/resource/test', {"data" => "value"}, "/another-base")
77
+ response.must_be_kind_of Net::HTTPCreated
78
+ response.body.must_be_nil
79
+ end
80
+ end
81
+
82
+ describe "#put" do
83
+ it "successful without providing a base url" do
84
+ stub_request(:put, "http://localhost/resource/test").
85
+ with(:body => "{\"data\":\"value\"}", :headers => request_header).
86
+ to_return(:status => 200, :body => '', :headers => {})
87
+
88
+ response = service.put('/resource/test', "data" => "value")
89
+ response.must_be_kind_of Net::HTTPOK
90
+ response.body.must_be_nil
91
+ end
92
+
93
+ it "successful with a base url" do
94
+ stub_request(:put, "http://localhost/another-base/resource/test").
95
+ with(:body => "{\"data\":\"value\"}", :headers => request_header).
96
+ to_return(:status => 200, :body => '', :headers => {})
97
+
98
+ response = service.put('/resource/test', {"data" => "value"}, "/another-base")
99
+ response.must_be_kind_of Net::HTTPOK
100
+ response.body.must_be_nil
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,133 @@
1
+ require 'test_helper'
2
+ require 'misty/http/method_builder'
3
+
4
+ describe Misty::HTTP::MethodBuilder do
5
+ let(:service) do
6
+ class Service
7
+ include Misty::HTTP::MethodBuilder
8
+
9
+ def base_path=(val)
10
+ @base_path = val
11
+ end
12
+ end
13
+
14
+ Service.new
15
+ end
16
+
17
+ describe "#base_filter" do
18
+ it "return path with base_path" do
19
+ service.base_path = "/base_path"
20
+ service.send(:base_filter, true, "/abc/def/").must_equal "/base_path/abc/def/"
21
+ end
22
+
23
+ it "returns path only" do
24
+ service.base_path = "/base_path"
25
+ service.send(:base_filter, false, "/abc/def/").must_equal "/abc/def/"
26
+ end
27
+ end
28
+
29
+ describe "#count_path_params" do
30
+ it "returns number of path parameters from path" do
31
+ service.send(:count_path_params, "/servers/{element1}/config/{element2}/{element3}").must_equal 3
32
+ end
33
+
34
+ it "returns 0 when no parameters in path" do
35
+ service.send(:count_path_params, "/blah/bla").must_equal 0
36
+ end
37
+ end
38
+
39
+ describe "#get_method" do
40
+ class Service
41
+ def self.api
42
+ {
43
+ '/' => { GET: [:list_api_versions] },
44
+ '/v2.0/' => { GET: [:show_api_v2_details] },
45
+ '/v2.0/extensions' => { GET: [:list_extensions] },
46
+ '/v2.0/extensions/{alias}' => { GET: [:show_extension_details] },
47
+ '/v2.0/networks/{network_id}' => { GET: [:show_network_details], PUT: [:update_network], DELETE: [:delete_network] }
48
+ }
49
+ end
50
+ end
51
+
52
+ it "successful find a existing method" do
53
+ service.send(:get_method, :list_extensions).must_equal ({:path=>"/v2.0/extensions", :request=>:GET, :name=>:list_extensions})
54
+ end
55
+
56
+ it "returns nil when no method matches" do
57
+ service.send(:get_method, :incognito).must_be_nil
58
+ end
59
+ end
60
+
61
+ describe "#inject_elements" do
62
+ let(:path) { "/v3/domains/{domain_id}/groups/{group_id}/roles/{role_id}/projects" }
63
+
64
+ it "replaces elements" do
65
+ service.send(:inject_elements, path, ["id1", "id2", "id3"]).must_equal "/v3/domains/id1/groups/id2/roles/id3/projects"
66
+ end
67
+
68
+ it "fails when not enough arguments" do
69
+ proc do
70
+ service.send(:inject_elements, path, "id1", "id2")
71
+ end.must_raise ArgumentError
72
+ end
73
+
74
+ it "return path when no match" do
75
+ service.send(:inject_elements, "/v3/path", ["id1", "id2"]).must_equal "/v3/path"
76
+ end
77
+ end
78
+
79
+ describe "#prefixed_path" do
80
+ it "returns true and same path with empty prefix" do
81
+ class Service
82
+ def self.prefix_path_to_ignore
83
+ ""
84
+ end
85
+ end
86
+
87
+ path = "/v3/resources/type"
88
+ base, newpath = service.send(:prefixed_path, path)
89
+ base.must_equal true
90
+ newpath.must_equal path
91
+ end
92
+
93
+ it "returns false and same path when unmatched prefix" do
94
+ class Service
95
+ def self.prefix_path_to_ignore
96
+ "/v3/{project_id}"
97
+ end
98
+ end
99
+
100
+ path = "/v2/schemas/tasks"
101
+ base, newpath = service.send(:prefixed_path, path)
102
+ base.must_equal false
103
+ newpath.must_equal path
104
+ end
105
+
106
+ it "returns true and filtered path when matched prefix" do
107
+ class Service
108
+ def self.prefix_path_to_ignore
109
+ "/v3/{project_id}"
110
+ end
111
+ end
112
+
113
+ path = "/v3/{project_id}/backups/detail"
114
+ base, newpath = service.send(:prefixed_path, path)
115
+ base.must_equal true
116
+ newpath.must_equal "/backups/detail"
117
+ end
118
+ end
119
+
120
+ describe "#query_param" do
121
+ it "returns string when passing a String" do
122
+ service.send(:query_param, "name=foobar").must_equal "?name=foobar"
123
+ end
124
+
125
+ it "returns nil when passing an empty String" do
126
+ service.send(:query_param, "").must_be_nil
127
+ end
128
+
129
+ it "returns nil unless passing a String" do
130
+ service.send(:query_param, "name" => "foobar").must_be_nil
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,123 @@
1
+ require 'test_helper'
2
+ require 'service_helper'
3
+ require 'misty/http/request'
4
+
5
+ describe Misty::HTTP::Request do
6
+ let(:request_header) { {'Accept' => '*/*'} }
7
+
8
+ describe "#decode?" do
9
+ let(:response) do
10
+ uri = URI.parse("http://localhost/")
11
+ http = Net::HTTP.new(uri.host, uri.port)
12
+ request = Net::HTTP::Get.new("/resource", {})
13
+ http.request(request)
14
+ end
15
+
16
+ it "true when response has a body" do
17
+ stub_request(:get, "http://localhost/resource").
18
+ with(:headers => {'Accept' => '*/*'}).
19
+ to_return(:status => 200, :body => "{\"key\": \"value\"}", :headers => {'Content-Type' => 'application/json'})
20
+
21
+ service.decode?(response).must_equal true
22
+ end
23
+
24
+ it "false when response has no content" do
25
+ stub_request(:get, "http://localhost/resource").
26
+ with(:headers => {'Accept' => '*/*'}).
27
+ to_return(:status => 204, :body => nil, :headers => {'Content-Type' => 'application/json'})
28
+
29
+ service.decode?(response).must_be_nil
30
+ end
31
+
32
+ it "false when content_type is JSON" do
33
+ stub_request(:get, "http://localhost/resource").
34
+ with(:headers => request_header).
35
+ to_return(:status => 200, :body => "{\"blah\": \"bla\"}")
36
+
37
+ service(:json).decode?(response).must_be_nil
38
+ end
39
+ end
40
+
41
+ describe "http requests" do
42
+ it "#http_copy" do
43
+ stub_request(:copy, "http://localhost/resource").
44
+ with(:headers => request_header).
45
+ to_return(:status => 202, :body => "{\"key\": \"value\"}")
46
+
47
+ response = service.http_copy('/resource', {})
48
+ response.must_be_kind_of Net::HTTPAccepted
49
+ response.body.wont_be_nil
50
+ end
51
+
52
+ it "#http_delete" do
53
+ stub_request(:delete, "http://localhost/resource").
54
+ with(:headers => request_header).
55
+ to_return(:status => 204, :body => '')
56
+
57
+ response = service.http_delete('/resource', {})
58
+ response.must_be_kind_of Net::HTTPNoContent
59
+ response.body.must_be_nil
60
+ end
61
+
62
+ it "#http_get" do
63
+ stub_request(:get, "http://localhost/resource").
64
+ with(:headers => request_header).
65
+ to_return(:status => 200, :body => "{\"key\": \"value\"}")
66
+
67
+ response = service.http_get('/resource', {})
68
+ response.must_be_kind_of Net::HTTPOK
69
+ response.body.wont_be_empty
70
+ end
71
+
72
+ it "#http_head" do
73
+ stub_request(:head, "http://localhost/resource").
74
+ with(:headers => request_header).
75
+ to_return(:status => '200')
76
+
77
+ response = service.http_head('/resource', {})
78
+ response.must_be_kind_of Net::HTTPSuccess
79
+ response.body.must_be_nil
80
+ end
81
+
82
+ it "#http_options" do
83
+ stub_request(:options, "http://localhost/resource").
84
+ with(:headers => request_header).
85
+ to_return(:status => '200')
86
+
87
+ response = service.http_options('/resource', {})
88
+ response.must_be_kind_of Net::HTTPSuccess
89
+ end
90
+
91
+ it "#http_patch" do
92
+ stub_request(:patch, "http://localhost/resource").
93
+ with(:headers => request_header).
94
+ to_return(:status => 202, :body => "{\"key\": \"value\"}")
95
+
96
+ response = service.http_patch('/resource', {}, "data" => "value")
97
+ response.must_be_kind_of Net::HTTPAccepted
98
+ response.body.wont_be_nil
99
+ end
100
+
101
+ it "#http_post" do
102
+ stub_request(:post, "http://localhost/resource").
103
+ with(:headers => request_header).
104
+ to_return(:status => 201)
105
+
106
+ response = service.http_post('/resource', {}, "data" => "value")
107
+ response.must_be_kind_of Net::HTTPCreated
108
+ end
109
+
110
+ it "#http_put" do
111
+ stub_request(:put, "http://localhost/resource").
112
+ with(:headers => request_header).
113
+ to_return(:status => 200)
114
+
115
+ response = service.http_put('/resource', {}, "data" => "value")
116
+ response.must_be_kind_of Net::HTTPOK
117
+ end
118
+
119
+ it "#http_to_s" do
120
+ service.http_to_s('/resource', "headers", "data" => "value").must_equal "base_url='localhost:80', path='/resource', header=headers, data='{\"data\"=>\"value\"}'"
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+
3
+ describe Misty do
4
+ describe "SERVICES" do
5
+ it "has expected structure" do
6
+ Misty::SERVICES.each do |service|
7
+ service.name.must_be_kind_of Symbol
8
+ service.project.must_be_kind_of Symbol
9
+ service.versions.must_be_kind_of Array
10
+ service.versions.each do |version|
11
+ version.must_be_kind_of String
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ describe "#to_json" do
18
+ it "returns a JSON string when using a Ruby hash" do
19
+ Misty.to_json({"key" => "val"}).must_be_kind_of String
20
+ end
21
+
22
+ it "returns same string when using a string" do
23
+ data = "{\"key\": \"val\"}"
24
+ response = Misty.to_json(data)
25
+ response.must_be_kind_of String
26
+ response.must_equal data
27
+ end
28
+
29
+ it "fails when using a string with non JSON data" do
30
+ data = "key;val"
31
+ proc do
32
+ response = Misty.to_json(data)
33
+ end.must_raise JSON::ParserError
34
+ end
35
+ end
36
+ end