Skip to content

Commit 29f7888

Browse files
Itxakammnelemane
authored andcommitted
Use host and port for rest server from the environment, fallback to localhost and default port
On node creation: - set the proper node+domain for the node object - set the node name to the short name - set the fqdn and domain name to the proper ones - set the uptime to avoid failure on node details UI - set the roles to just names so they are linked to the barclamps - set the product name, serial number so they are shown properly in the UI - set the disk key for removable so disks are shown properly on the UI - count all the memory and aggregate it to be shown on the UI - count the processors with an 0 index so they can be shown in the UI - allocate the node - set the node to ready status All the node creation changes also fix the node not being shown properly when going to the details as well as crowbar crashing when moving the node to a different group
1 parent 4f32630 commit 29f7888

File tree

3 files changed

+101
-161
lines changed

3 files changed

+101
-161
lines changed

crowbar_framework/app/controllers/intelrsd_controller.rb

Lines changed: 75 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,23 @@
1414
# limitations under the License.
1515
#
1616

17-
require 'json'
17+
require "json"
1818

1919
# An important note on interfacing with Redfish APIS:
2020
#
21-
# * Only specific top level URIs may be assumed, and even these
22-
# may be absent based on the implementation. (for ex: there
23-
# might be no /redfish/v1/Systems collection on something that
24-
# doesn't have compute nodes )
25-
# * The API will eventually be implemented on a system that breaks
26-
# any data model and hence the URIs must be dynamically discovered
27-
# * The data model represented here using @node_object_list prepares
28-
# a list of all the available Systems along with the properties
29-
# and IDs of available resources in each system. This data model
30-
# needs to be appropriately mapped to the Node object of the system
31-
# where the data model is employed.
32-
#
21+
# Only specific top level URIs may be assumed, and even these
22+
# may be absent based on the implementation. (for ex: there
23+
# might be no /redfish/v1/Systems collection on something that
24+
# doesn't have compute nodes )
25+
#
26+
# The API will eventually be implemented on a system that breaks
27+
# any data model and hence the URIs must be dynamically discovered
28+
# The data model represented here using @node_object_list prepares
29+
# a list of all the available Systems along with the properties
30+
# and IDs of available resources in each system. This data model
31+
# needs to be appropriately mapped to the Node object of the system
32+
# where the data model is employed.
33+
#
3334

3435
class RsdController < ApplicationController
3536
attr_reader :redfish_client, :logger
@@ -48,67 +49,33 @@ def show
4849
end
4950
end
5051

51-
def allocate
52-
all_sys_list = get_systems
53-
all_sys_list.each do |sys_id|
54-
next unless params[sys_id.to_s] == "1"
55-
node = get_crowbar_node_object(sys_id)
56-
node.allocate
57-
node.set_state("ready")
58-
end
59-
redirect_to rsd_show_path, notice: "Selected nodes allocated as compute nodes"
52+
def initialize
53+
host = ENV["CROWBAR_REDFISH_HOST"] || "localhost"
54+
port = ENV["CROWBAR_REDFISH_PORT"] || "8443"
55+
@redfish_client = RedfishHelper::RedfishClient.new(host, port)
56+
@node_object_list = []
6057
end
6158

6259
def get_system_resource_list(sys_id, resource)
6360
resource_list = []
6461
items = @redfish_client.get_resource("Systems/#{sys_id}/#{resource}")
65-
items["Members"].each do | item |
62+
items["Members"].each do |item|
6663
item_odata_id = item["@odata.id"]
67-
item_id = item_odata_id.split(/\//)[-1]
64+
item_id = item_odata_id.split("/")[-1]
6865
resource_item = @redfish_client.get_resource("Systems/#{sys_id}/#{resource}/#{item_id}")
6966
resource_list.push(resource_item)
7067
end
71-
return resource_list
68+
resource_list
7269
end
7370

7471
def make_node_object_for_system(sys_id)
75-
nodeobject = Hash.new()
72+
nodeobject = Hash.new
7673
nodeobject["System_Id"] = sys_id
77-
["Processors", "Memory", "MemoryChunks",
78-
"EthernetInterfaces", "Adapters"].each do | resource |
79-
nodeobject["#{resource}"] = get_system_resource_list(sys_id, resource)
80-
end
81-
return nodeobject
82-
end
83-
84-
def get_processors(sys_id)
85-
proc_list = get_system_resource_list(sys_id, "Processors")
86-
processors = []
87-
proc_list.each do |proc|
88-
proc_object = Hash.new
89-
proc_object["Model"] = proc["Model"]
90-
proc_object["Manufacturer"] = proc["Manufacturer"]
91-
proc_object["Architecture"] = proc["Architecture"]
92-
proc_object["TotalCores"] = proc["TotalCores"]
93-
proc_object["TotalThreads"] = proc["TotalThreads"]
94-
processors.push(proc_object)
95-
end
96-
processors
97-
end
98-
99-
def get_memory(sys_id)
100-
mem_list = get_system_resource_list(sys_id, "Memory")
101-
memories = []
102-
mem_list.each do |mem|
103-
mem_object = Hash.new
104-
mem_object["MemoryType"] = mem["MemoryType"]
105-
mem_object["CapacityMB"] = mem["CapacityMiB"]
106-
mem_object["Speed"] = mem["OperatingSpeedMHz"]
107-
mem_object["Size"] = mem["SizeMiB"]
108-
mem_object["Health"] = mem["Health"]
109-
memories.push(mem_object)
74+
["Processors", "Memory", "MemoryChunks",
75+
"EthernetInterfaces", "Adapters"].each do |resource|
76+
nodeobject[resource.to_s] = get_system_resource_list(sys_id, resource)
11077
end
111-
memories
78+
nodeobject
11279
end
11380

11481
def get_systems
@@ -117,75 +84,70 @@ def get_systems
11784

11885
@systems["Members"].each do |member|
11986
odata_id = member["@odata.id"]
120-
sys_id = odata_id.split(/\//)[-1]
87+
sys_id = odata_id.split("/")[-1]
12188
sys_list.push(sys_id)
12289
end
123-
return sys_list
90+
sys_list
12491
end
12592

12693
def get_system_data(sys_id)
12794
system_data = @redfish_client.get_resource("Systems/#{sys_id}")
12895
system_object = make_node_object_for_system(sys_id)
12996
["Processors", "Memory", "MemoryChunks",
130-
"EthernetInterfaces", "Adapters"].each do | resource |
131-
system_data["#{resource}"] = system_object["#{resource}"]
97+
"EthernetInterfaces", "Adapters"].each do |resource|
98+
system_data[resource.to_s] = system_object[resource.to_s]
13299
end
133-
return system_data
100+
system_data
134101
end
135102

136-
def get_all_systems
137-
sys_list = get_systems
138-
all_systems = []
139-
sys_list.each do |sys_id|
140-
sys_object = Hash.new
141-
sys_object["SystemId"] = sys_id
142-
sys_object["Processors"] = get_processors(sys_id)
143-
sys_object["Memory"] = get_memory(sys_id)
144-
all_systems.push(sys_object)
103+
def get_rsd_nodes
104+
system_list = get_systems
105+
system_list.each do |system|
106+
node_object = make_node_object_for_system(system)
107+
@node_object_list.push(node_object)
145108
end
146-
all_systems
109+
@node_object_list
110+
end
111+
112+
def reset_system(sys_id)
113+
post_action("Systems/#{sys_id}", action: "ComputerSystem.Reset")
147114
end
148115

149116
def get_crowbar_node_object(sys_id)
150117
system_object = get_system_data(sys_id)
151118
node_name_prefix = "d"
152-
node_name_prefix = "IRSD-" if system_object["Oem"].key?("Intel_RackScale")
119+
node_name_prefix = "IRSD" if system_object["Oem"].key?("Intel_RackScale")
153120

154121
# Pickin up the first IP address. This may not be always the correct address.
155122
# It must be revisited when testing with Rackscale hardware.
156123
eth_interface = system_object["EthernetInterfaces"].first
157-
node_name = node_name_prefix + eth_interface["MACAddress"].tr(":", "-") + "-#{sys_id}"
124+
node_name = node_name_prefix + eth_interface["MACAddress"].tr(":", "-")
158125

159126
node = NodeObject.create_new "#{node_name}.#{Crowbar::Settings.domain}".downcase
160127

161128
node.set["name"] = node_name
162-
# set a flag to identify this node as a rackscale one
163-
node.set["rackscale"] = true
164-
# track the rackscale id for this node
165-
node.set["rackscale_id"] = sys_id
166-
node.set["target_cpu"] = "x86_64"
129+
node.set["target_cpu"] = ""
167130
node.set["target_vendor"] = "suse"
168-
node.set["host_cpu"] = system_object["ProcessorSummary"]["Model"]
131+
node.set["host_cpu"] = ""
169132
node.set["host_vendor"] = "suse"
170133
node.set["kernel"] = "" # Kernel modules and configurations
171134
node.set["counters"] = "" # various network interfaces and other counters
172135
node.set["hostname"] = node_name
173136
node.set["fqdn"] = "#{node_name}.#{Crowbar::Settings.domain}"
174137
node.set["domain"] = Crowbar::Settings.domain
175-
176138
ipaddress_data = eth_interface["IPv4Addresses"].first
177-
node.set['ipaddress'] = ipaddress_data["Address"]
178-
node.set['macaddress'] = eth_interface["MACAddress"]
139+
node.set["ipaddress"] = ipaddress_data["Address"]
140+
node.set["macaddress"] = eth_interface["MACAddress"]
179141
ip6address_data = eth_interface["IPv6Addresses"].first
180-
node.set['ip6address'] = ip6address_data["Address"]
181-
#node.set['ohai_time'] = ""
182-
node.set['recipes'] = ""
142+
node.set["ip6address"] = ip6address_data["Address"]
143+
node.set["uptime"] = "1 minute"
144+
node.set["recipes"] = ""
183145

184146
# Add other roles as seen fit
185147
node.set["roles"] = []
186148
["deployer-config-default", "network-config-default", "dns-config-default",
187149
"logging-config-default", "ntp-config-default",
188-
"provisioner-base", "provisioner-config-default", "nova-compute"].each do |role_name|
150+
"provisioner-base", "provisioner-config-default"].each do |role_name|
189151
node["roles"] << role_name
190152
end
191153

@@ -197,15 +159,25 @@ def get_crowbar_node_object(sys_id)
197159
node.set["virtualization"]["role"] = "guest"
198160
node.set["platform"] = "suse"
199161
node.set["platform_version"] = "12.1"
162+
node.set["dmi"]["bios"]["all_records"] = ""
163+
node.set["dmi"]["bios"]["vendor"] = ""
200164
node.set["dmi"]["bios"]["version"] = system_object["BiosVersion"]
165+
node.set["dmi"]["bios"]["release_date"] = ""
166+
node.set["dmi"]["bios"]["address"] = ""
167+
node.set["dmi"]["bios"]["runtime_size"] = ""
168+
node.set["dmi"]["bios"]["rom_size"] = ""
169+
node.set["dmi"]["bios"]["bios_revision"] = ""
201170
node.set["dmi"]["system"]["product_name"] = system_object["Model"]
202-
node.set["dmi"]["system"]["manufacturer"] = system_object["Manufacturer"]
203-
node.set["dmi"]["system"]["serial_number"] = system_object["SerialNumber"]
204-
node.set["dmi"]["system"]["uuid"] = system_object["UUID"]
171+
node.set["dmi"]["system"]["manufacturer"] = ""
172+
node.set["dmi"]["system"]["serial_number"] = "Not Specified"
173+
node.set["dmi"]["system"]["uuid"] = ""
205174
node.set["dmi"]["system"]["wake_up_type"] = "Power Switch"
206175
node.set["dmi"]["system"]["sku_number"] = "Not Specified"
207176
node.set["dmi"]["system"]["family"] = "Not Specified"
208177
node.set["dmi"]["chassis"]["serial_number"] = system_object["SerialNumber"]
178+
node.set["dmi"]["chassis"]["all_records"] = ""
179+
node.set["dmi"]["chassis"]["manufacturer"] = ""
180+
node.set["dmi"]["chassis"]["all_records"] = ""
209181
node.set["dmi"]["chassis"]["boot_up_state"] = "Safe"
210182
node.set["dmi"]["chassis"]["power_supply_state"] = "Safe"
211183
# this is needed so its counted properly for the UI
@@ -229,6 +201,15 @@ def get_crowbar_node_object(sys_id)
229201

230202
node.set["filesystem"]["sysfs"] = ""
231203
node.save
232-
node
204+
node.allocate
205+
node.set_state("ready")
233206
end
234207
end
208+
209+
# run it on a thread to not block the UI at the start
210+
Thread.new do
211+
rsd_controller = IntelRSDController.new
212+
node_list = rsd_controller.get_systems
213+
first_node = node_list.first
214+
rsd_controller.get_crowbar_node_object(first_node)
215+
end

crowbar_framework/app/helpers/redfish_helper.rb

Lines changed: 25 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -14,104 +14,63 @@
1414
# limitations under the License.
1515
#
1616

17-
require 'json'
18-
require 'uri'
19-
require 'net/http'
20-
require 'rest-client'
17+
require "json"
18+
require "uri"
19+
require "net/http"
20+
require "rest-client"
2121

2222
module RedfishHelper
2323
class RedfishClient
2424
attr_reader :logger
25-
25+
2626
# Standard JSONRPC Error responses
2727
INVALID_JSON = -32700
2828
INVALID_REQUEST = -32600
2929
INVALID_PARAMS = -32602
3030
METHOD_NOT_FOUND = -32601
3131
INTERNAL_ERROR = -32603
32-
32+
3333
# RedFish-specific constants
34-
REDFISH_VERSION = "redfish/v1/"
35-
36-
def initialize(host, port, insecure=true, client_cert=false)
34+
REDFISH_VERSION = "redfish/v1/".freeze
35+
36+
def initialize(host, port, insecure = true, client_cert = false)
3737
@service_uri = "https://#{host}:#{port}/#{REDFISH_VERSION}"
3838
@verify_ssl = OpenSSL::SSL::VERIFY_NONE if insecure
3939
@ssl_client_cert = false unless client_cert
4040
end
41-
41+
4242
def handle_exception(json_rpc_error)
43-
logger.error(json_rpc_error[:message])
43+
Rails.logger.error(json_rpc_error[:message])
4444
end
45-
45+
4646
def post_action(resource, action:None, params: None)
4747
uri = @service_uri + resource
4848
uri += "/Actions/#{action}" if action
49-
49+
5050
begin
5151
response = RestClient::Request.execute(url: uri,
52-
method: :post,
53-
verify_ssl: @verify_ssl,
54-
ssl_client_cert: @ssl_client_cert)
52+
method: :post,
53+
verify_ssl: @verify_ssl,
54+
ssl_client_cert: @ssl_client_cert)
5555
rescue
5656
handle_exception(response)
5757
end
58-
return JSON.parse(response)
58+
JSON.parse(response)
5959
end
60-
60+
6161
def get_resource(resource)
6262
uri = @service_uri + resource
63-
p "QUERYING RESOURCE: #{uri}"
64-
63+
Rails.logger.debug("QUERYING RESOURCE: #{uri}")
64+
6565
begin
66-
response = RestClient::Request.execute(url: uri,
67-
method: :get,
68-
verify_ssl: @verify_ssl,
69-
ssl_client_cert: @ssl_client_cert)
66+
response = RestClient::Request.execute(url: uri,
67+
method: :get,
68+
verify_ssl: @verify_ssl,
69+
ssl_client_cert: @ssl_client_cert)
7070
rescue
7171
handle_exception(response)
7272
end
73-
74-
return JSON.parse(response)
73+
JSON.parse(response)
7574
end
7675
end
7776
end
78-
79-
# Usage Examples for this client library
80-
81-
# Create a client object
82-
redfish_client = RedfishHelper::RedfishClient.new("localhost", "8443")
83-
84-
# Check if the Redfish Service responds ( returns redfish/v1)
85-
api_resp = redfish_client.get_resource("")
86-
p api_resp
87-
88-
# Check one of the API responses
89-
systems = redfish_client.get_resource("Systems")
90-
p systems
91-
92-
sys_list = []
93-
94-
# Loop to run through all available systems and populate a node-object
95-
systems["Members"].each do |member|
96-
p "MEMBER DATA: #{member}"
97-
member_id= member["@odata.id"]
98-
p "MEMBER ID: #{member_id}"
99-
sys_id = member_id.split(/\//)[-1]
100-
p "SYSTEM ID: #{sys_id}"
101-
sys_data = Hash.new()
102-
sys_data["Systems"] = redfish_client.get_resource("Systems/#{sys_id}")
103-
p "SYSTEMS DATA: #{sys_data["Systems"]}"
104-
sys_data["Processors"] = redfish_client.get_resource("Systems/#{sys_id}/Processors/1")
105-
p "PROCESSORS DATA: #{sys_data["Processors"]}"
106-
sys_data["Memory"] = redfish_client.get_resource("Systems/#{sys_id}/Memory/1")
107-
p "MEMORY DATA: #{sys_data["Memory"]}"
108-
sys_data["MemoryChunks"] = redfish_client.get_resource("Systems/#{sys_id}/MemoryChunks/1")
109-
p "MEMORY CHUNKS DATA: #{sys_data["MemoryChunks"]}"
110-
sys_data["EthernetInterfaces"] = redfish_client.get_resource("Systems/#{sys_id}/EthernetInterfaces/1")
111-
p "ETHERNET DATA: #{sys_data["EthernetInterfaces"]}"
112-
sys_data["Adapters"] = redfish_client.get_resource("Systems/#{sys_id}/Adapters/1")
113-
p "ADAPTERS DATA: #{sys_data["Adapters"]}"
114-
sys_list.push(sys_data)
115-
end
116-
117-
p "NODE OBJECT From Redfish : #{sys_list}"

0 commit comments

Comments
 (0)