redfish_tools 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +0 -1
- data/lib/redfish_tools/server.rb +21 -0
- data/lib/redfish_tools/servlet.rb +76 -22
- data/lib/redfish_tools/version.rb +1 -1
- data/redfish_tools.gemspec +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d8e4fd83aeaa6c8af2e97fce4d2e92802cc97281
|
4
|
+
data.tar.gz: d2e92b0b838758132ba345a45ab6d8c4b423dcf3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8c3805f96c543a24c787edb52ec70a60ccf097b547e9a6ca87909219f810f091852479ba4237439c2ae146222536f9a30fdc2f814fd3b4491c1d9296ebbf184
|
7
|
+
data.tar.gz: f02fc22a3b4600a5b41621026bf26c98160f6c72665d23290b6df19dd538f209a267fca3ebfd2ece864e76e7840d16dc08f3a9013b5418631726a1bbfd678aa4
|
data/.travis.yml
CHANGED
data/lib/redfish_tools/server.rb
CHANGED
@@ -27,5 +27,26 @@ module RedfishTools
|
|
27
27
|
@basic_auth_header ||= "Basic " +
|
28
28
|
Base64.strict_encode64("#{username}:#{password}")
|
29
29
|
end
|
30
|
+
|
31
|
+
def system_actions
|
32
|
+
# Hash of action_id => system_id
|
33
|
+
@system_actions ||= load_all_system_actions
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def load_all_system_actions
|
39
|
+
systems_id = datastore.get("/redfish/v1").body["Systems"]["@odata.id"]
|
40
|
+
datastore.get(systems_id).body["Members"].reduce({}) do |acc, link|
|
41
|
+
acc.merge(load_system_actions(link["@odata.id"]))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def load_system_actions(id)
|
46
|
+
actions = datastore.get(id).body.dig("Actions") || {}
|
47
|
+
actions.each_with_object({}) do |(name, data), acc|
|
48
|
+
acc[data["target"]] = { name: name, system_id: id }
|
49
|
+
end
|
50
|
+
end
|
30
51
|
end
|
31
52
|
end
|
@@ -12,21 +12,38 @@ module RedfishTools
|
|
12
12
|
|
13
13
|
def_delegators :@server,
|
14
14
|
:datastore, :login_path, :username, :password,
|
15
|
-
:basic_auth_header
|
15
|
+
:basic_auth_header, :system_actions
|
16
16
|
|
17
17
|
BAD_HEADERS = Set.new(["connection", "content-length", "keep-alive"])
|
18
18
|
DEFAULT_HEADERS = {
|
19
19
|
"content-type" => "application/json"
|
20
20
|
}.freeze
|
21
|
+
TRANSITIONS = {
|
22
|
+
"On" => {
|
23
|
+
"GracefullShutdown" => "Off",
|
24
|
+
"ForceOff" => "Off",
|
25
|
+
"PushPowerButton" => "Off",
|
26
|
+
"Nmi" => "Off",
|
27
|
+
"GracefullRestart" => "On",
|
28
|
+
"ForceRestart" => "On",
|
29
|
+
"PowerCycle" => "On",
|
30
|
+
}.freeze,
|
31
|
+
"Off" => {
|
32
|
+
"On" => "On",
|
33
|
+
"ForceOn" => "On",
|
34
|
+
"PushPowerButton" => "On",
|
35
|
+
}.freeze,
|
36
|
+
}.freeze
|
21
37
|
|
22
38
|
def service(request, response)
|
23
39
|
return response.status = 401 unless authorized?(request)
|
24
|
-
return response.status = 404 unless datastore.get(request.path).body
|
25
40
|
|
26
41
|
super
|
27
42
|
end
|
28
43
|
|
29
44
|
def do_GET(request, response)
|
45
|
+
return response.status = 404 unless datastore.get(request.path).body
|
46
|
+
|
30
47
|
item = datastore.get(request.path)
|
31
48
|
response.status = 200
|
32
49
|
set_headers(response, item.headers)
|
@@ -34,18 +51,27 @@ module RedfishTools
|
|
34
51
|
end
|
35
52
|
|
36
53
|
def do_POST(request, response)
|
54
|
+
action = system_actions[request.path]
|
37
55
|
item = datastore.get(request.path)
|
38
|
-
return response.status =
|
56
|
+
return response.status = 404 unless action || item.body
|
57
|
+
return response.status = 405 if action.nil? && item.body["Members"].nil?
|
39
58
|
|
40
59
|
data = JSON.parse(request.body)
|
41
|
-
|
42
|
-
|
60
|
+
if action
|
61
|
+
body, headers, status = execute_action(action, data)
|
62
|
+
elsif login_path?(request.path)
|
63
|
+
body, headers, status = login(item, data)
|
64
|
+
else
|
65
|
+
body, headers, status = new_item(item, data)
|
66
|
+
end
|
43
67
|
|
44
|
-
response.status =
|
45
|
-
set_headers(response,
|
46
|
-
response.body =
|
68
|
+
response.status = status
|
69
|
+
set_headers(response, headers)
|
70
|
+
response.body = body.to_json
|
47
71
|
rescue JSON::ParserError
|
48
72
|
response.status = 400
|
73
|
+
set_headers(response)
|
74
|
+
response.body = error_body("Invalid JSON").to_json
|
49
75
|
end
|
50
76
|
|
51
77
|
def do_PUT(_request, response)
|
@@ -57,27 +83,54 @@ module RedfishTools
|
|
57
83
|
end
|
58
84
|
|
59
85
|
def do_DELETE(request, response)
|
60
|
-
|
86
|
+
item = datastore.get(request.path)
|
87
|
+
return response.status = 404 unless item.body
|
88
|
+
|
89
|
+
delete_item(item)
|
61
90
|
response.status = 204
|
62
91
|
end
|
63
92
|
|
64
93
|
private
|
65
94
|
|
66
|
-
def
|
67
|
-
|
95
|
+
def error_body(msg)
|
96
|
+
{ "error" => { "message" => msg } }
|
97
|
+
end
|
98
|
+
|
99
|
+
def execute_action(action, data)
|
100
|
+
# TODO(@tadeboro): This method currently only handles reset action.
|
101
|
+
system = datastore.get(action[:system_id]).body
|
102
|
+
action = system["Actions"][action[:name]]
|
103
|
+
reset = data["ResetType"]
|
104
|
+
|
105
|
+
unless action["ResetType@Redfish.AllowableValues"].include?(reset)
|
106
|
+
return error_body("Invalid reset type"), nill, 400
|
107
|
+
end
|
108
|
+
|
109
|
+
unless TRANSITIONS[system["PowerState"]].key?(reset)
|
110
|
+
return error_body("Invalid reset type for curent state"), nil, 400
|
111
|
+
end
|
112
|
+
|
113
|
+
# Simulate reset action
|
114
|
+
system["PowerState"] = TRANSITIONS[system["PowerState"]][reset]
|
115
|
+
|
116
|
+
[error_body("Success"), nil, 200]
|
117
|
+
end
|
118
|
+
|
119
|
+
def login_path?(path)
|
120
|
+
login_path == path.chomp("/")
|
68
121
|
end
|
69
122
|
|
70
123
|
def login(item, data)
|
71
124
|
user = data["UserName"]
|
72
|
-
|
73
|
-
|
125
|
+
unless username == user && password == data["Password"]
|
126
|
+
return error_body("Invalid username/password"), nil, 400
|
127
|
+
end
|
74
128
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
res
|
129
|
+
body, _, status = new_item(item,
|
130
|
+
"@odata.type" => "#Session.v1_1_0.Session",
|
131
|
+
"UserName" => user,
|
132
|
+
"Password" => nil)
|
133
|
+
[body, DEFAULT_HEADERS.merge("X-Auth-Token" => body["Id"]), status]
|
81
134
|
end
|
82
135
|
|
83
136
|
def new_item(item, data)
|
@@ -87,7 +140,8 @@ module RedfishTools
|
|
87
140
|
item.body["Members"].push("@odata.id" => oid)
|
88
141
|
|
89
142
|
base = { "@odata.id" => oid, "Id" => id, "Name" => id }
|
90
|
-
datastore.set(oid, base.merge(data), parent: item)
|
143
|
+
new_item = datastore.set(oid, base.merge(data), parent: item)
|
144
|
+
[new_item.body, nil, 201]
|
91
145
|
end
|
92
146
|
|
93
147
|
def delete_item(item)
|
@@ -105,7 +159,7 @@ module RedfishTools
|
|
105
159
|
always_allow?(request.path) || # Non-protected endpoints
|
106
160
|
authorized_basic?(request) ||
|
107
161
|
authorized_session?(request) ||
|
108
|
-
(request.request_method == "POST" && login_path?(request))
|
162
|
+
(request.request_method == "POST" && login_path?(request.path))
|
109
163
|
end
|
110
164
|
|
111
165
|
def always_allow?(path)
|
@@ -134,7 +188,7 @@ module RedfishTools
|
|
134
188
|
nil
|
135
189
|
end
|
136
190
|
|
137
|
-
def set_headers(response, headers)
|
191
|
+
def set_headers(response, headers = nil)
|
138
192
|
headers ||= DEFAULT_HEADERS
|
139
193
|
headers.each do |k, v|
|
140
194
|
response[k] = v unless BAD_HEADERS.member?(k.downcase)
|
data/redfish_tools.gemspec
CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.add_runtime_dependency "server_sent_events", "~> 0.1.1"
|
33
33
|
spec.add_runtime_dependency "thor", "~> 0.19"
|
34
34
|
|
35
|
-
spec.add_development_dependency "bundler"
|
35
|
+
spec.add_development_dependency "bundler"
|
36
36
|
spec.add_development_dependency "pry"
|
37
37
|
spec.add_development_dependency "rake", "~> 10.0"
|
38
38
|
spec.add_development_dependency "rspec", "~> 3.0"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redfish_tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tadej Borovšak
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redfish_client
|
@@ -56,16 +56,16 @@ dependencies:
|
|
56
56
|
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: pry
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -176,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
176
176
|
version: '0'
|
177
177
|
requirements: []
|
178
178
|
rubyforge_project:
|
179
|
-
rubygems_version: 2.
|
179
|
+
rubygems_version: 2.6.14
|
180
180
|
signing_key:
|
181
181
|
specification_version: 4
|
182
182
|
summary: Collection of tools for working with Redfish services.
|