yao 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/macos.yml +15 -0
- data/.github/workflows/ubuntu-rvm.yml +29 -0
- data/.github/workflows/ubuntu.yml +22 -0
- data/Gemfile +10 -2
- data/README.md +3 -3
- data/lib/yao/resources.rb +5 -0
- data/lib/yao/resources/action.rb +1 -1
- data/lib/yao/resources/compute_services.rb +46 -0
- data/lib/yao/resources/flavor.rb +1 -10
- data/lib/yao/resources/floating_ip.rb +6 -6
- data/lib/yao/resources/hypervisor.rb +6 -12
- data/lib/yao/resources/keypair.rb +22 -3
- data/lib/yao/resources/meter.rb +6 -7
- data/lib/yao/resources/network.rb +3 -1
- data/lib/yao/resources/network_associationable.rb +14 -0
- data/lib/yao/resources/old_sample.rb +5 -7
- data/lib/yao/resources/port.rb +6 -6
- data/lib/yao/resources/port_associationable.rb +14 -0
- data/lib/yao/resources/project.rb +16 -0
- data/lib/yao/resources/resource.rb +12 -7
- data/lib/yao/resources/restfully_accessible.rb +72 -35
- data/lib/yao/resources/role.rb +73 -18
- data/lib/yao/resources/router.rb +3 -1
- data/lib/yao/resources/sample.rb +1 -5
- data/lib/yao/resources/security_group.rb +3 -1
- data/lib/yao/resources/server.rb +4 -9
- data/lib/yao/resources/subnet.rb +5 -5
- data/lib/yao/resources/tenant.rb +1 -1
- data/lib/yao/resources/tenant_associationable.rb +17 -0
- data/lib/yao/resources/user.rb +15 -4
- data/lib/yao/resources/volume.rb +1 -10
- data/lib/yao/version.rb +1 -1
- data/test/config.rb +1 -0
- data/test/support/auth_stub.rb +1 -0
- data/test/support/test_yao_resource.rb +49 -0
- data/test/yao/resources/test_aggregates.rb +1 -4
- data/test/yao/resources/test_base.rb +1 -1
- data/test/yao/resources/test_compute_services.rb +118 -0
- data/test/yao/resources/test_flavor.rb +15 -9
- data/test/yao/resources/test_floating_ip.rb +24 -19
- data/test/yao/resources/test_host.rb +1 -1
- data/test/yao/resources/test_hypervisor.rb +17 -10
- data/test/yao/resources/test_image.rb +1 -1
- data/test/yao/resources/test_keypair.rb +3 -6
- data/test/yao/resources/test_loadbalancer.rb +1 -3
- data/test/yao/resources/test_loadbalancer_healthmonitor.rb +1 -3
- data/test/yao/resources/test_loadbalancer_listener.rb +1 -5
- data/test/yao/resources/test_loadbalancer_pool.rb +1 -3
- data/test/yao/resources/test_loadbalancer_pool_member.rb +1 -3
- data/test/yao/resources/test_meter.rb +13 -14
- data/test/yao/resources/test_network.rb +28 -1
- data/test/yao/resources/test_old_sample.rb +86 -0
- data/test/yao/resources/test_port.rb +29 -7
- data/test/yao/resources/test_project.rb +32 -0
- data/test/yao/resources/test_resource.rb +56 -0
- data/test/yao/resources/test_role.rb +255 -1
- data/test/yao/resources/test_role_assignment.rb +4 -6
- data/test/yao/resources/test_router.rb +26 -6
- data/test/yao/resources/test_sample.rb +61 -0
- data/test/yao/resources/test_security_group.rb +23 -1
- data/test/yao/resources/test_security_group_rule.rb +1 -1
- data/test/yao/resources/test_server.rb +34 -8
- data/test/yao/resources/test_subnet.rb +25 -6
- data/test/yao/resources/test_user.rb +73 -1
- data/test/yao/resources/test_volume.rb +31 -1
- data/test/yao/resources/test_volume_type.rb +1 -1
- data/test/yao/test_config.rb +21 -8
- data/test/yao/test_read_only.rb +3 -3
- data/yao.gemspec +0 -8
- metadata +22 -101
- data/.travis.yml +0 -28
@@ -0,0 +1,16 @@
|
|
1
|
+
module Yao::Resources
|
2
|
+
class Project < Base
|
3
|
+
friendly_attributes :id, :name, :description, :enabled, :parent_id, :domain_id
|
4
|
+
alias :enabled? :enabled
|
5
|
+
|
6
|
+
self.service = "identity"
|
7
|
+
self.resource_name = "project"
|
8
|
+
self.resources_name = "projects"
|
9
|
+
self.admin = true
|
10
|
+
|
11
|
+
def domain?
|
12
|
+
@data["is_domain"]
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'time'
|
2
2
|
module Yao::Resources
|
3
3
|
class Resource < Base
|
4
|
-
|
4
|
+
include TenantAssociationable
|
5
|
+
|
6
|
+
friendly_attributes :user_id, :resource_id,
|
5
7
|
:last_sample_timestamp, :first_sample_timestamp,
|
6
8
|
:metadata,
|
7
9
|
:links
|
@@ -10,10 +12,6 @@ module Yao::Resources
|
|
10
12
|
resource_id
|
11
13
|
end
|
12
14
|
|
13
|
-
def tenant
|
14
|
-
@tenant ||= Yao::User.get(project_id)
|
15
|
-
end
|
16
|
-
|
17
15
|
def user
|
18
16
|
@user ||= Yao::User.get(user_id)
|
19
17
|
end
|
@@ -42,12 +40,19 @@ module Yao::Resources
|
|
42
40
|
|
43
41
|
class << self
|
44
42
|
private
|
43
|
+
|
44
|
+
# override Yao::Resources::RestfullyAccessible.resource_from_json
|
45
|
+
# @param [Hash]
|
46
|
+
# @return [Yao::Resources::Resource]
|
45
47
|
def resource_from_json(json)
|
46
|
-
json
|
48
|
+
new(json)
|
47
49
|
end
|
48
50
|
|
51
|
+
# override Yao::Resources::RestfullyAccessible.resources_from_json
|
52
|
+
# @param [Hash]
|
53
|
+
# @return [Yao::Resources::Resource]
|
49
54
|
def resources_from_json(json)
|
50
|
-
json
|
55
|
+
new(json)
|
51
56
|
end
|
52
57
|
end
|
53
58
|
end
|
@@ -5,7 +5,7 @@ module Yao::Resources
|
|
5
5
|
def self.extended(base)
|
6
6
|
base.class_eval do
|
7
7
|
class << self
|
8
|
-
attr_accessor :resource_name, :resources_name
|
8
|
+
attr_accessor :resource_name, :resources_name, :resources_detail_available
|
9
9
|
|
10
10
|
extend Forwardable
|
11
11
|
%w(get post put delete).each do |method_name|
|
@@ -34,6 +34,10 @@ module Yao::Resources
|
|
34
34
|
@admin = bool
|
35
35
|
end
|
36
36
|
|
37
|
+
def return_single_on_querying
|
38
|
+
@return_single_on_querying
|
39
|
+
end
|
40
|
+
|
37
41
|
def return_single_on_querying=(bool)
|
38
42
|
@return_single_on_querying = bool
|
39
43
|
end
|
@@ -65,35 +69,49 @@ module Yao::Resources
|
|
65
69
|
end
|
66
70
|
end
|
67
71
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
@resources_path = original
|
72
|
+
# @param query [Hash]
|
73
|
+
# @return [Yao::Resources::*]
|
74
|
+
# @return [Array<Yao::Resources::*]
|
75
|
+
def list(query={})
|
73
76
|
|
74
|
-
|
75
|
-
|
77
|
+
url = if resources_detail_available
|
78
|
+
# If the resource has 'detail', #list tries to GET /${resourece}/detail
|
79
|
+
# For example.
|
80
|
+
#
|
81
|
+
# GET /servers/detail
|
82
|
+
# GET /flavors/detail
|
83
|
+
#
|
84
|
+
create_url('detail')
|
85
|
+
else
|
86
|
+
create_url
|
87
|
+
end
|
76
88
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
return_resource(resource_from_json(json))
|
89
|
+
json = GET(url, query).body
|
90
|
+
if return_single_on_querying && !query.empty?
|
91
|
+
# returns Yao::Resources::*
|
92
|
+
resource_from_json(json)
|
82
93
|
else
|
83
|
-
|
94
|
+
# returns Array of Yao::Resources::*
|
95
|
+
resources_from_json(json)
|
84
96
|
end
|
85
97
|
end
|
86
98
|
|
99
|
+
# @note .list is defined to keep backward compatibility and will be deprecated
|
100
|
+
alias :list_detail :list
|
101
|
+
|
102
|
+
# @param id_or_name_or_permalink [Stirng]
|
103
|
+
# @param query [Hash]
|
104
|
+
# @return [Yao::Resources::*]
|
87
105
|
def get(id_or_name_or_permalink, query={})
|
88
106
|
res = if id_or_name_or_permalink.start_with?("http://", "https://")
|
89
107
|
GET(id_or_name_or_permalink, query)
|
90
108
|
elsif uuid?(id_or_name_or_permalink)
|
91
|
-
GET(create_url(
|
109
|
+
GET(create_url(id_or_name_or_permalink), query)
|
92
110
|
else
|
93
111
|
get_by_name(id_or_name_or_permalink, query)
|
94
112
|
end
|
95
113
|
|
96
|
-
|
114
|
+
resource_from_json(res.body)
|
97
115
|
end
|
98
116
|
alias find get
|
99
117
|
|
@@ -101,74 +119,93 @@ module Yao::Resources
|
|
101
119
|
list(query.merge({"name" => name}))
|
102
120
|
end
|
103
121
|
|
122
|
+
# @param resource_params [Hash]
|
123
|
+
# @return [Yao::Resources::*]
|
104
124
|
def create(resource_params)
|
105
125
|
params = {
|
106
126
|
resource_name_in_json => resource_params
|
107
127
|
}
|
108
|
-
res = POST(create_url
|
128
|
+
res = POST(create_url) do |req|
|
109
129
|
req.body = params.to_json
|
110
130
|
req.headers['Content-Type'] = 'application/json'
|
111
131
|
end
|
112
|
-
|
132
|
+
resource_from_json(res.body)
|
113
133
|
end
|
114
134
|
|
135
|
+
# @param id [String]
|
136
|
+
# @return [Yao::Resources::*]
|
115
137
|
def update(id, resource_params)
|
116
138
|
params = {
|
117
139
|
resource_name_in_json => resource_params
|
118
140
|
}
|
119
|
-
res = PUT(create_url(
|
141
|
+
res = PUT(create_url(id)) do |req|
|
120
142
|
req.body = params.to_json
|
121
143
|
req.headers['Content-Type'] = 'application/json'
|
122
144
|
end
|
123
|
-
|
145
|
+
resource_from_json(res.body)
|
124
146
|
end
|
125
147
|
|
148
|
+
# @param id [String]
|
149
|
+
# @return [String]
|
126
150
|
def destroy(id)
|
127
|
-
res = DELETE(create_url(
|
151
|
+
res = DELETE(create_url(id))
|
128
152
|
res.body
|
129
153
|
end
|
130
154
|
|
131
155
|
private
|
132
|
-
|
156
|
+
|
157
|
+
# returns pathname of resource URL
|
158
|
+
# @param subpath [String]
|
159
|
+
# @return [String]
|
160
|
+
def create_url(subpath='')
|
161
|
+
paths = [ api_version, resources_path, subpath ]
|
133
162
|
paths.select{|s| s != ''}.join('/')
|
134
163
|
end
|
135
164
|
|
165
|
+
# @return [String]
|
136
166
|
def resource_name_in_json
|
137
167
|
@_resource_name_in_json ||= resource_name.sub(/^os-/, "").tr("-", "_")
|
138
168
|
end
|
139
169
|
|
140
|
-
|
141
|
-
|
142
|
-
end
|
143
|
-
|
144
|
-
def resources_from_json(json)
|
170
|
+
# @return [String]
|
171
|
+
def resources_name_in_json
|
145
172
|
@resources_name_in_json ||= resources_name.sub(/^os-/, "").tr("-", "_")
|
146
|
-
json[@resources_name_in_json]
|
147
173
|
end
|
148
174
|
|
149
|
-
|
150
|
-
|
175
|
+
# @param json [Hash]
|
176
|
+
# @return [Yao::Resources::*]
|
177
|
+
def resource_from_json(json)
|
178
|
+
attribute = json[resource_name_in_json]
|
179
|
+
new(attribute)
|
151
180
|
end
|
152
181
|
|
153
|
-
|
154
|
-
|
182
|
+
# @param json [Hash]
|
183
|
+
# @return [Array<Yao::Resources::*>]
|
184
|
+
def resources_from_json(json)
|
185
|
+
json[resources_name_in_json].map { |attribute|
|
186
|
+
new(attribute) # instance of Yao::Resources::*
|
187
|
+
}
|
155
188
|
end
|
156
189
|
|
157
190
|
def uuid?(str)
|
158
191
|
/^[\da-f]{8}-([\da-f]{4}-){3}[\da-f]{12}$/ === str
|
159
192
|
end
|
160
193
|
|
194
|
+
# At first, search by ID. If nothing is found, search by name.
|
195
|
+
# @param name [String]
|
196
|
+
# @param query [Hash]
|
197
|
+
# @return [Yao::Resources::*]
|
161
198
|
def get_by_name(name, query={})
|
162
|
-
|
199
|
+
|
163
200
|
begin
|
164
|
-
GET(create_url(
|
201
|
+
GET(create_url(name), query)
|
165
202
|
rescue => e
|
166
203
|
raise e unless e.class == Yao::ItemNotFound || e.class == Yao::NotFound
|
167
204
|
item = find_by_name(name)
|
168
205
|
if item.size > 1
|
169
206
|
raise Yao::TooManyItemFonud.new("More than one resource exists with the name '#{name}'")
|
170
207
|
end
|
171
|
-
GET(create_url(
|
208
|
+
GET(create_url(item.first.id), query)
|
172
209
|
end
|
173
210
|
end
|
174
211
|
end
|
data/lib/yao/resources/role.rb
CHANGED
@@ -5,43 +5,98 @@ module Yao::Resources
|
|
5
5
|
self.service = "identity"
|
6
6
|
self.resource_name = "role"
|
7
7
|
self.resources_name = "roles"
|
8
|
-
self.resources_path = "/OS-KSADM/roles"
|
9
8
|
self.admin = true
|
10
9
|
|
11
10
|
class << self
|
12
|
-
|
13
|
-
|
11
|
+
|
12
|
+
# override Yao::Resources::RestfullyAccessible#find_by_name
|
13
|
+
# This is workaround of keystone versioning v2.0/v3.
|
14
|
+
# @return [Array<Yao::Resources::Role>]
|
15
|
+
def find_by_name(name, query={})
|
16
|
+
if api_version_v2?
|
17
|
+
list.select{|r| r.name == name}
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# override Yao::Resources::RestfullyAccessible#resources_path
|
24
|
+
# This is workaround of keystone versioning v2.0/v3.
|
25
|
+
# @return [String]
|
26
|
+
def resources_path
|
27
|
+
if api_version_v2?
|
28
|
+
"OS-KSADM/roles"
|
29
|
+
else
|
30
|
+
resources_name
|
31
|
+
end
|
14
32
|
end
|
15
|
-
alias find_by_name get_by_name
|
16
33
|
|
34
|
+
# @param user_name [String]
|
35
|
+
# @param on [String]
|
36
|
+
# @return [Array<Yao::Resources::Role>]
|
17
37
|
def list_for_user(user_name, on:)
|
18
|
-
user = Yao::User.
|
19
|
-
tenant =
|
20
|
-
|
38
|
+
user = Yao::User.get(user_name)
|
39
|
+
tenant = if api_version_v2?
|
40
|
+
Yao::Tenant.find_by_name(on)
|
41
|
+
else
|
42
|
+
Yao::Project.get(on)
|
43
|
+
end
|
21
44
|
|
22
|
-
|
45
|
+
res = GET(path_for_role_resource(tenant, user))
|
46
|
+
resources_from_json(res.body)
|
23
47
|
end
|
24
48
|
|
49
|
+
# @param role_name [String]
|
50
|
+
# @param to: [String]
|
51
|
+
# @param on: [String]
|
52
|
+
# @return [Faraday::Response]
|
25
53
|
def grant(role_name, to:, on:)
|
26
|
-
role = Yao::Role.
|
27
|
-
user = Yao::User.
|
28
|
-
tenant =
|
54
|
+
role = Yao::Role.get(role_name)
|
55
|
+
user = Yao::User.get(to)
|
56
|
+
tenant = if api_version_v2?
|
57
|
+
Yao::Tenant.find_by_name(on)
|
58
|
+
else
|
59
|
+
Yao::Project.get(on)
|
60
|
+
end
|
29
61
|
|
30
|
-
|
62
|
+
# response is "204 Not Content"
|
63
|
+
PUT(path_for_role_resource(tenant, user, role))
|
31
64
|
end
|
32
65
|
|
66
|
+
# @param role_name [String]
|
67
|
+
# @param from: [String]
|
68
|
+
# @param on: [String]
|
69
|
+
# @return [Faraday::Response]
|
33
70
|
def revoke(role_name, from:, on:)
|
34
|
-
role = Yao::Role.
|
35
|
-
user = Yao::User.
|
36
|
-
tenant =
|
71
|
+
role = Yao::Role.get(role_name)
|
72
|
+
user = Yao::User.get(from)
|
73
|
+
tenant = if api_version_v2?
|
74
|
+
Yao::Tenant.find_by_name(on)
|
75
|
+
else
|
76
|
+
Yao::Project.get(on)
|
77
|
+
end
|
37
78
|
|
38
|
-
|
79
|
+
# response is "204 Not Content"
|
80
|
+
DELETE(path_for_role_resource(tenant, user, role))
|
39
81
|
end
|
40
82
|
|
41
83
|
private
|
42
84
|
|
43
|
-
|
44
|
-
|
85
|
+
# workaround of keystone versioning v2.0/v3
|
86
|
+
# @return [Bool]
|
87
|
+
def api_version_v2?
|
88
|
+
client.url_prefix.to_s =~ /v2\.0/
|
89
|
+
end
|
90
|
+
|
91
|
+
def path_for_role_resource(tenant, user, role = nil)
|
92
|
+
if api_version_v2?
|
93
|
+
paths = ["tenants", tenant.id, "users", user.id, "roles"]
|
94
|
+
paths += ["OS-KSADM", role.id] if role
|
95
|
+
else
|
96
|
+
paths = ["projects", tenant.id, "users", user.id, "roles"]
|
97
|
+
paths << role.id if role
|
98
|
+
end
|
99
|
+
paths.join("/")
|
45
100
|
end
|
46
101
|
end
|
47
102
|
end
|
data/lib/yao/resources/router.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Yao::Resources
|
2
2
|
class Router < Base
|
3
|
-
|
3
|
+
include TenantAssociationable
|
4
|
+
|
5
|
+
friendly_attributes :name, :description, :admin_state_up, :status, :external_gateway_info,
|
4
6
|
:network_id, :enable_snat, :external_fixed_ips, :routes, :destination, :nexthop, :distributed,
|
5
7
|
:ha, :availability_zone_hints, :availability_zones
|
6
8
|
|
data/lib/yao/resources/sample.rb
CHANGED
@@ -2,7 +2,7 @@ module Yao::Resources
|
|
2
2
|
class Sample < Base
|
3
3
|
friendly_attributes :id, :metadata, :meter,
|
4
4
|
:source, :type, :unit, :volume,
|
5
|
-
:
|
5
|
+
:resource_id, :user_id
|
6
6
|
|
7
7
|
def recorded_at
|
8
8
|
Time.parse(self["recorded_at"])
|
@@ -16,10 +16,6 @@ module Yao::Resources
|
|
16
16
|
@resource ||= Yao::Resource.get(resource_id)
|
17
17
|
end
|
18
18
|
|
19
|
-
def tenant
|
20
|
-
@tenant ||= Yao::Tenant.get(project_id)
|
21
|
-
end
|
22
|
-
|
23
19
|
def user
|
24
20
|
@user ||= Yao::User.get(user_id)
|
25
21
|
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'yao/resources/security_group_rule'
|
2
2
|
module Yao::Resources
|
3
3
|
class SecurityGroup < Base
|
4
|
-
|
4
|
+
include TenantAssociationable
|
5
|
+
|
6
|
+
friendly_attributes :name, :description
|
5
7
|
|
6
8
|
def rules
|
7
9
|
self[["rules", SecurityGroupRule].join("__")] ||= (case self.class.service
|
data/lib/yao/resources/server.rb
CHANGED
@@ -2,8 +2,10 @@ require 'yao/resources/metadata_available'
|
|
2
2
|
require 'yao/resources/action'
|
3
3
|
module Yao::Resources
|
4
4
|
class Server < Base
|
5
|
+
include TenantAssociationable
|
6
|
+
|
5
7
|
friendly_attributes :addresses, :metadata, :name, :progress,
|
6
|
-
:status, :
|
8
|
+
:status, :user_id, :key_name
|
7
9
|
map_attribute_to_attribute hostId: :host_id
|
8
10
|
map_attribute_to_resource flavor: Flavor
|
9
11
|
map_attribute_to_resource image: Image
|
@@ -21,6 +23,7 @@ module Yao::Resources
|
|
21
23
|
self.service = "compute"
|
22
24
|
self.resource_name = "server"
|
23
25
|
self.resources_name = "servers"
|
26
|
+
self.resources_detail_available = true
|
24
27
|
|
25
28
|
def old_samples(counter_name: nil, query: {})
|
26
29
|
Yao::OldSample.list(counter_name, query).select{|os| os.resource_metadata["instance_id"] == id}
|
@@ -52,14 +55,6 @@ module Yao::Resources
|
|
52
55
|
|
53
56
|
class << self
|
54
57
|
alias :stop :shutoff
|
55
|
-
|
56
|
-
def list_detail(query={})
|
57
|
-
return_resources(
|
58
|
-
resources_from_json(
|
59
|
-
GET([resources_path, "detail"].join("/"), query).body
|
60
|
-
)
|
61
|
-
)
|
62
|
-
end
|
63
58
|
end
|
64
59
|
|
65
60
|
extend MetadataAvailable
|