misty 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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