From 3ffdbf2eff63246fb9cb5ea4452815ecaefa136b Mon Sep 17 00:00:00 2001 From: Itxaka Date: Wed, 5 Oct 2016 14:28:04 +0200 Subject: [PATCH] - Clean up. - Store 2 more items in the NodeObject to identify and track the rackscale instances - Rewrite the rest-client queries to protect and log http exceptions - Create several Power management shortcuts for the RedFish client - Create a handler for redfish commands - On power management actions, check for rackscale and execute the actions via rest calls --- .../app/controllers/intelrsd_controller.rb | 8 +-- .../app/helpers/redfish_helper.rb | 54 +++++++++++++++---- crowbar_framework/app/models/node_object.rb | 51 +++++++++++++++++- 3 files changed, 97 insertions(+), 16 deletions(-) diff --git a/crowbar_framework/app/controllers/intelrsd_controller.rb b/crowbar_framework/app/controllers/intelrsd_controller.rb index 1aeb09ba63..cba4841bb9 100644 --- a/crowbar_framework/app/controllers/intelrsd_controller.rb +++ b/crowbar_framework/app/controllers/intelrsd_controller.rb @@ -95,10 +95,6 @@ def get_rsd_nodes @node_object_list end - def reset_system(sys_id) - post_action("Systems/#{sys_id}", action: "ComputerSystem.Reset") - end - def get_crowbar_node_object(sys_id) system_object = get_system_data(sys_id) node_name_prefix = "d" @@ -110,6 +106,10 @@ def get_crowbar_node_object(sys_id) node = NodeObject.create_new "#{node_name}.#{Crowbar::Settings.domain}".downcase node.set["name"] = node_name + # set a flag to identify this node as a rackscale one + node.set["rackscale"] = true + # track the rackscale id for this node + node.set["rackscale_id"] = sys_id node.set["target_cpu"] = "" node.set["target_vendor"] = "suse" node.set["host_cpu"] = "" diff --git a/crowbar_framework/app/helpers/redfish_helper.rb b/crowbar_framework/app/helpers/redfish_helper.rb index 28d3167aee..3efecd676d 100644 --- a/crowbar_framework/app/helpers/redfish_helper.rb +++ b/crowbar_framework/app/helpers/redfish_helper.rb @@ -37,25 +37,56 @@ def initialize(host, port, insecure = true, client_cert = false) @service_uri = "https://#{host}:#{port}/#{REDFISH_VERSION}" @verify_ssl = OpenSSL::SSL::VERIFY_NONE if insecure @ssl_client_cert = false unless client_cert + @reset_action = "ComputerSystem.Reset".freeze end - def handle_exception(json_rpc_error) - Rails.logger.error(json_rpc_error[:message]) - end - - def post_action(resource, action:None, params: None) + def post_action(resource, action = nil, payload = nil) uri = @service_uri + resource uri += "/Actions/#{action}" if action + payload = {} unless payload begin response = RestClient::Request.execute(url: uri, method: :post, + payload: payload.to_json, + headers: { content_type: :json }, verify_ssl: @verify_ssl, ssl_client_cert: @ssl_client_cert) - rescue - handle_exception(response) + JSON.parse(response) + rescue RestClient::ExceptionWithResponse => e + Rails.logger.error("Error while trying to post #{payload} to #{uri}: #{e}") + false end - JSON.parse(response) + end + + def restart(resource) + post_action("Systems/#{resource}", + @reset_action, + "ResetType" => "GracefulRestart") + end + + def shutdown(resource) + post_action("Systems/#{resource}", + @reset_action, + "ResetType" => "GracefulShutdown") + end + + def poweron(resource) + post_action("Systems/#{resource}", + @reset_action, + "ResetType" => "On") + end + + def powercycle(resource) + post_action("Systems/#{resource}", + @reset_action, + "ResetType" => "ForceRestart") + end + + def poweroff(resource) + post_action("Systems/#{resource}", + @reset_action, + "ResetType" => "ForceOff") end def get_resource(resource) @@ -67,10 +98,11 @@ def get_resource(resource) method: :get, verify_ssl: @verify_ssl, ssl_client_cert: @ssl_client_cert) - rescue - handle_exception(response) + return JSON.parse(response) + rescue RestClient::ExceptionWithResponse => e + Rails.logger.error(e) + JSON.parse(e.response) end - JSON.parse(response) end end end diff --git a/crowbar_framework/app/models/node_object.rb b/crowbar_framework/app/models/node_object.rb index e92244d547..88e198079f 100644 --- a/crowbar_framework/app/models/node_object.rb +++ b/crowbar_framework/app/models/node_object.rb @@ -1111,6 +1111,43 @@ def bmc_cmd(cmd) [200, {}] end + def redfish_rest_cmd(cmd, rackscale_id) + host = ENV["CROWBAR_REDFISH_HOST"] || "localhost" + port = ENV["CROWBAR_REDFISH_PORT"] || "8443" + redfish_client = RedfishHelper::RedfishClient.new(host, port) + case cmd + when :reboot + unless redfish_client.restart(rackscale_id) + Rails.logger.warn("rackscale reboot rest cmd failed - node in unknown state") + [422, I18n.t("unknown_state", scope: "error")] + end + when :shutdown + unless redfish_client.shutdown(rackscale_id) + Rails.logger.warn("rackscale shutdown rest cmd failed - node in unknown state") + [422, I18n.t("unknown_state", scope: "error")] + end + when :poweron + unless redfish_client.poweron(rackscale_id) + Rails.logger.warn("rackscale poweron rest cmd failed - node in unknown state") + [422, I18n.t("unknown_state", scope: "error")] + end + when :powercycle + unless redfish_client.powercycle(rackscale_id) + Rails.logger.warn("rackscale powercycle rest cmd failed - node in unknown state") + [422, I18n.t("unknown_state", scope: "error")] + end + when :poweroff + unless redfish_client.poweroff(rackscale_id) + Rails.logger.warn("rackscale poweroff rest cmd failed - node in unknown state") + [422, I18n.t("unknown_state", scope: "error")] + end + else + Rails.logger.warn("Unknown command #{cmd} for #{@node.name}.") + [400, I18n.t("unknown_cmd", scope: "error", cmd: cmd)] + end + [200, {}] + end + def set_state(state) # use the real transition function for this cb = CrowbarService.new Rails.logger @@ -1211,6 +1248,8 @@ def reboot set_state("reboot") if @node[:platform_family] == "windows" net_rpc_cmd(:reboot) + elsif @node["rackscale"] + redfish_rest_cmd(:reboot, @node["rackscale_id"]) else ssh_cmd("/sbin/reboot") end @@ -1220,6 +1259,8 @@ def shutdown set_state("shutdown") if @node[:platform_family] == "windows" net_rpc_cmd(:shutdown) + elsif @node["rackscale"] + redfish_rest_cmd(:shutdown, @node["rackscale_id"]) else ssh_cmd("/sbin/poweroff") end @@ -1227,13 +1268,19 @@ def shutdown def poweron set_state("poweron") - bmc_cmd("power on") + if @node["rackscale"] + redfish_rest_cmd(:poweron, @node["rackscale_id"]) + else + bmc_cmd("power on") + end end def powercycle set_state("reboot") if @node[:platform_family] == "windows" net_rpc_cmd(:power_cycle) + elsif @node["rackscale"] + redfish_rest_cmd(:powercycle, @node["rackscale_id"]) else bmc_cmd("power cycle") end @@ -1243,6 +1290,8 @@ def poweroff set_state("shutdown") if @node[:platform_family] == "windows" net_rpc_cmd(:power_off) + elsif @node["rackscale"] + redfish_rest_cmd(:poweroff, @node["rackscale_id"]) else bmc_cmd("power off") end