redfish_tools 0.2.5 → 0.2.6
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.
- 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.
|