Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse Physical Chassis #149

Merged
merged 1 commit into from
Apr 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ def parse_physical_switch(switch)
PhysicalSwitchParser.parse_physical_switch(switch)
end

def parse_physical_server(node, compliance, rack = nil)
PhysicalServerParser.parse_physical_server(node, compliance, rack)
def parse_physical_chassis(node, rack = nil)
PhysicalChassisParser.parse_physical_chassis(node, rack)
end

def parse_physical_server(node, compliance, rack = nil, chassis = nil)
PhysicalServerParser.parse_physical_server(node, compliance, rack, chassis)
end

def parse_config_pattern(config_pattern)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ class PhysicalInfraManager::Parser::ParserDictionaryConstants
}.freeze

MIQ_TYPES = {
"physical_server" => "ManageIQ::Providers::Lenovo::PhysicalInfraManager::PhysicalServer",
"physical_switch" => "ManageIQ::Providers::Lenovo::PhysicalInfraManager::PhysicalSwitch",
"template" => "ManageIQ::Providers::Lenovo::PhysicalInfraManager::Template",
"physical_server" => "ManageIQ::Providers::Lenovo::PhysicalInfraManager::PhysicalServer",
"physical_switch" => "ManageIQ::Providers::Lenovo::PhysicalInfraManager::PhysicalSwitch",
"physical_chassis" => "ManageIQ::Providers::Lenovo::PhysicalInfraManager::PhysicalChassis",
"template" => "ManageIQ::Providers::Lenovo::PhysicalInfraManager::Template",
}.freeze

PROPERTIES_MAP = {
Expand Down Expand Up @@ -63,6 +64,40 @@ class PhysicalInfraManager::Parser::ParserDictionaryConstants
:vlan_key => 'PVID',
}.freeze

PHYSICAL_CHASSIS = {
:name => 'name',
:uid_ems => 'uuid',
:ems_ref => 'uuid',
:overall_health_state => 'overallHealthState',
:management_module_slot_count => 'mmSlots',
:switch_slot_count => 'switchSlots',
:fan_slot_count => 'fanSlots',
:blade_slot_count => 'bladeSlots',
:powersupply_slot_count => 'powerSupplySlots',
:asset_detail => {
:product_name => 'productName',
:manufacturer => 'manufacturer',
:machine_type => 'machineType',
:model => 'model',
:serial_number => 'serialNumber',
:contact => 'contact',
:description => 'description',
:location => 'location.location',
:room => 'location.room',
:rack_name => 'location.rack',
:lowest_rack_unit => 'location.lowestRackUnit',
},
:computer_system => {
:hardware => {
:guest_devices => '',
},
},
}.freeze

PHYSICAL_CHASSIS_NETWORK = {
:ipaddress => 'mgmtProcIPaddress',
}.freeze

PHYSICAL_SERVER = {
:name => 'name',
:ems_ref => 'uuid',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
module ManageIQ::Providers::Lenovo
class PhysicalInfraManager::Parser::PhysicalChassisParser < PhysicalInfraManager::Parser::ComponentParser
class << self
#
# Parse a chassis hash to a hash with physical racks data
#
# @param [Hash] chassis_hash - hash containing physical chassis raw data
# @param [Hash] rack - parsed physical rack data
#
# @return [Hash] containing the physical server information
#
def parse_physical_chassis(chassis_hash, rack)
chassis = XClarityClient::Chassi.new(chassis_hash)
result = parse(chassis, parent::ParserDictionaryConstants::PHYSICAL_CHASSIS)

result[:physical_rack] = rack if rack
result[:vendor] = "lenovo"
result[:type] = parent::ParserDictionaryConstants::MIQ_TYPES["physical_chassis"]
result[:health_state] = parent::ParserDictionaryConstants::HEALTH_STATE_MAP[chassis.cmmHealthState.nil? ? chassis.cmmHealthState : chassis.cmmHealthState.downcase]
result[:location_led_state] = find_loc_led_state(chassis.leds)
result[:computer_system][:hardware] = get_hardwares(chassis)

return chassis.uuid, result
end

private

def find_loc_led_state(leds)
identification_led = leds.to_a.find { |led| parent::ParserDictionaryConstants::PROPERTIES_MAP[:led_identify_name].include?(led["name"]) }
identification_led.try(:[], "state")
end

def get_hardwares(chassis)
parsed_chassi_network = parse(chassis, parent::ParserDictionaryConstants::PHYSICAL_CHASSIS_NETWORK)

{
:guest_devices => [{
:device_type => "management",
:network => parsed_chassi_network
}]
}
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ class << self
# Parse a rack object to a hash with its data
#
# @param cab [XClarity::PhysicalRack] a rack object
# @param physical_servers [Hash] a already parsed physical_servers that belong to cab
#
# @return [Integer, Hash] PhysicalRack UUID and a parsed hash from PhysicalRack and every components inside it
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@ class << self
#
# parse a node object to a hash with physical servers data
#
# @param [XClarityClient::Node] node - object containing physical server data
# @param [Hash] node_hash - hash containing physical server raw data
# @param [Hash] rack - parsed physical rack data
# @param [Hash] chassis - parsed physical chassis data
#
# @return [Hash] containing the physical server information
#
def parse_physical_server(node, compliance, rack = nil)
def parse_physical_server(node_hash, compliance, rack = nil, chassis = nil)
node = XClarityClient::Node.new(node_hash)
result = parse(node, parent::ParserDictionaryConstants::PHYSICAL_SERVER)

# Keep track of the rack where this server is in, if it is in any rack
result[:physical_rack] = rack if rack

result[:physical_chassis] = chassis if chassis
result[:ems_compliance_name] = compliance[:policy_name]
result[:ems_compliance_status] = compliance[:status]
result[:vendor] = "lenovo"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module ManageIQ::Providers
class Lenovo::PhysicalInfraManager::PhysicalChassis < ::PhysicalChassis
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -48,68 +48,61 @@ def init_parser(connection)
# Retrieve all physical infrastructure that can be obtained from the LXCA (racks, chassis, servers, switches)
# as XClarity objects and add it to the +@data+ as a hash.
def get_all_physical_infra
cabinets = get_physical_racks

# Retrieve the standalone rack (mock of a rack) so it is possible to retrieve all components
# from it and associate with the provider instead a mock rack.
standalone = nil
cabinets.reverse_each do |cab|
if cab.UUID == 'STANDALONE_OBJECT_UUID'
standalone = cabinets.delete(cab)
break
@data[:physical_racks] = []
@data[:physical_chassis] = []
@data[:physical_servers] = []

racks = get_plain_physical_racks
racks.each do |rack|
parsed_rack = nil
# One of the API's racks is a mock to indicate physical chassis and servers that are not inside any rack.
# This rack has the UUID equals to 'STANDALONE_OBJECT_UUID'
if rack.UUID != 'STANDALONE_OBJECT_UUID'
_, parsed_rack = @parser.parse_physical_rack(rack)
@data[:physical_racks] << parsed_rack
end
end

physical_servers = []
process_collection(cabinets, :physical_racks) do |cab|
rack_uid, rack = @parser.parse_physical_rack(cab)

get_physical_servers(cab) do |node|
_, parsed = @parser.parse_physical_server(node, find_compliance(node), rack)
physical_servers << parsed
# Retrieve and parse the servers that are inside the rack, but not inside any chassis.
rack_servers = get_plain_physical_servers_inside_rack(rack)
rack_servers.each do |server|
_, parsed_server = @parser.parse_physical_server(server, find_compliance(server), parsed_rack)
@data[:physical_servers] << parsed_server
end

next rack_uid, rack
end

nodes = get_physical_servers(standalone)
process_collection(nodes, :physical_servers) do |node|
@parser.parse_physical_server(node, find_compliance(node))
# Retrieve and parse the chassis that are inside the rack.
rack_chassis = get_plain_physical_chassis_inside_rack(rack)
rack_chassis.each do |chassis|
_, parsed_chassis = @parser.parse_physical_chassis(chassis, parsed_rack)
@data[:physical_chassis] << parsed_chassis

# Retrieve and parse the servers that are inside the chassi.
chassis_servers = get_plain_physical_servers_inside_chassis(chassis)
chassis_servers.each do |server|
_, parsed_server = @parser.parse_physical_server(server, find_compliance(server), parsed_rack, parsed_chassis)
@data[:physical_servers] << parsed_server
end
end
end

@data[:physical_servers].concat(physical_servers)
end

# Returns all physical rack from the api.
def get_physical_racks
def get_plain_physical_racks
@connection.discover_cabinet(:status => "includestandalone")
end

# Create a XClarity Node object for every node in a rack.
#
# @param cabinet [PhysicalRack] The rack from where it will retrieve the physical servers.
#
# Yields a XClarity Node object.
# @return [Hash] a parsed hash for every PhysicalServer that belongs to the cabinet.
def get_physical_servers(cabinet)
return if cabinet.nil?
chassis = cabinet.chassisList

nodes_chassis = chassis.map do |chassi|
chassi["itemInventory"]["nodes"]
end.flatten
nodes_chassis = nodes_chassis.reject { |node| node["type"] == "SCU" }

nodes = cabinet.nodeList
nodes = nodes.map { |node| node["itemInventory"] }
# Returns physical servers that are inside a rack but not inside a chassis.
def get_plain_physical_servers_inside_rack(rack)
rack.nodeList.map { |node| node["itemInventory"] }
end

nodes += nodes_chassis
# Returns physical chassis that are inside a rack.
def get_plain_physical_chassis_inside_rack(rack)
rack.chassisList.map { |chassis| chassis["itemInventory"] }
end

nodes.map do |node|
xc_node = XClarityClient::Node.new(node)
yield(xc_node) if block_given?
xc_node
end
# Returns physical servers that are inside a chassis.
def get_plain_physical_servers_inside_chassis(chassis)
chassis["nodes"].reject { |node| node["type"] == "SCU" }
end

def get_physical_switches
Expand All @@ -123,7 +116,7 @@ def get_physical_switches
def find_compliance(node)
@compliance_policies ||= @connection.fetch_compliance_policies
@compliance_policies_parsed ||= @parser.parse_compliance_policy(@compliance_policies)
@compliance_policies_parsed[node.uuid] || create_default_compliance
@compliance_policies_parsed[node["uuid"]] || create_default_compliance
end

def create_default_compliance
Expand Down
Loading