1#!/usr/bin/perl 2use strict; 3use warnings; 4 5use mrw::Targets; 6use mrw::Inventory; 7use mrw::Util; 8use Getopt::Long; # For parsing command line arguments 9use YAML::Tiny qw(LoadFile); 10# Globals 11my $serverwizFile = ""; 12my $debug = 0; 13my $outputFile = ""; 14my $metaDataFile = ""; 15my $skipBrokenMrw = 0; 16 17# Command line argument parsing 18GetOptions( 19"i=s" => \$serverwizFile, # string 20"m=s" => \$metaDataFile, # string 21"o=s" => \$outputFile, # string 22"skip-broken-mrw" => \$skipBrokenMrw, 23"d" => \$debug, 24) 25or printUsage(); 26 27if (($serverwizFile eq "") or ($outputFile eq "") or ($metaDataFile eq "")) 28{ 29 printUsage(); 30} 31 32my $targetObj = Targets->new; 33$targetObj->loadXML($serverwizFile); 34 35#open the mrw xml and the metaData file for the fru. 36#Fetch the FRU id,type,object path from the mrw. 37#Get the metadata for that fru from the metadata file. 38#Merge the data into the outputfile 39 40open(my $fh, '>', $outputFile) or die "Could not open file '$outputFile' $!"; 41my $fruTypeConfig = LoadFile($metaDataFile); 42 43my @interestedTypes = keys %{$fruTypeConfig}; 44my %types; 45@types{@interestedTypes} = (); 46 47my %entityInfoDict; 48 49my @allAssoTypes = getAllAssociatedTypes($fruTypeConfig); 50my %allAssoTypesHash; 51@allAssoTypesHash{@allAssoTypes} = (); 52 53my @inventory = Inventory::getInventory($targetObj); 54for my $item (@inventory) { 55 my $isFru = 0, my $fruID = 0, my $fruType = ""; 56 my $entityInstance = 1, my $entityID = 0; 57 58 #Fetch the FRUID. 59 if (!$targetObj->isBadAttribute($item->{TARGET}, "FRU_ID")) { 60 $fruID = $targetObj->getAttribute($item->{TARGET}, "FRU_ID"); 61 $isFru = 1; 62 } 63 #Fetch the FRU Type. 64 if (!$targetObj->isBadAttribute($item->{TARGET}, "TYPE")) { 65 $fruType = $targetObj->getAttribute($item->{TARGET}, "TYPE"); 66 } 67 68 #Skip if any one is true 69 #1) If not fru 70 #2) if the fru type is not there in the config file. 71 #3) if the fru type is in associated types. 72 #4) if FRU_ID is not defined for the target and we are asked to ignore such 73 # targets. 74 75 next if ($skipBrokenMrw and ($fruID eq "")); 76 77 next if (not $isFru or not exists $types{$fruType} or exists $allAssoTypesHash{$fruType}); 78 79 printDebug ("FRUID => $fruID, FRUType => $fruType, ObjectPath => $item->{OBMC_NAME}"); 80 81 print $fh $fruID.":"; 82 print $fh "\n"; 83 84 $entityID = $fruTypeConfig->{$fruType}->{'EntityID'}; 85 86 if (exists $entityInfoDict{$entityID}) { 87 $entityInstance = $entityInfoDict{$entityID} + 1; 88 } 89 90 printDebug("entityID => $entityID , entityInstance => $entityInstance"); 91 92 $entityInfoDict{$entityID} = $entityInstance; 93 94 writeToFile($fruType,$item->{OBMC_NAME},$fruTypeConfig,$fh); 95 96 #if the key(AssociatedTypes) exists and it is defined 97 #then make the association. 98 99 if (!defined $fruTypeConfig->{$fruType}->{'AssociatedTypes'}) { 100 next; 101 } 102 103 my $assoTypes = $fruTypeConfig->{$fruType}->{'AssociatedTypes'}; 104 for my $type (@$assoTypes) { 105 my @devices = Util::getDevicePath(\@inventory,$targetObj,$type); 106 for my $device (@devices) { 107 writeToFile($type,$device,$fruTypeConfig,$fh); 108 } 109 110 } 111 112} 113close $fh; 114 115#------------------------------------END OF MAIN----------------------- 116 117# Get all the associated types 118sub getAllAssociatedTypes 119{ 120 my $fruTypeConfig = $_[0]; 121 my @assoTypes; 122 while (my($key, $value) = each %$fruTypeConfig) { 123 #if the key exist and value is also there 124 if (defined $value->{'AssociatedTypes'}) { 125 my $assoTypes = $value->{'AssociatedTypes'}; 126 for my $type (@$assoTypes) { 127 push(@assoTypes,$type); 128 } 129 } 130 } 131 return @assoTypes; 132} 133 134#Get the metdata for the incoming frutype from the loaded config file. 135#Write the FRU data into the output file 136 137sub writeToFile 138{ 139 my $fruType = $_[0];#fru type 140 my $instancePath = $_[1];#instance Path 141 my $fruTypeConfig = $_[2];#loaded config file (frutypes) 142 my $fh = $_[3];#file Handle 143 #walk over all the fru types and match for the incoming type 144 145 print $fh " ".$instancePath.":"; 146 print $fh "\n"; 147 print $fh " "."entityID: ".$fruTypeConfig->{$fruType}->{'EntityID'}; 148 print $fh "\n"; 149 print $fh " "."entityInstance: "; 150 print $fh $entityInfoDict{$fruTypeConfig->{$fruType}->{'EntityID'}}; 151 print $fh "\n"; 152 print $fh " "."interfaces:"; 153 print $fh "\n"; 154 155 my $interfaces = $fruTypeConfig->{$fruType}->{'Interfaces'}; 156 157 #Walk over all the interfaces as it needs to be written 158 while ( my ($interface,$properties) = each %{$interfaces}) { 159 print $fh " ".$interface.":"; 160 print $fh "\n"; 161 #walk over all the properties as it needs to be written 162 while ( my ($dbusProperty,$metadata) = each %{$properties}) { 163 #will write property named "Property" first then 164 #other properties. 165 print $fh " ".$dbusProperty.":"; 166 print $fh "\n"; 167 for my $key (sort keys %{$metadata}) { 168 print $fh " $key: "."$metadata->{$key}"; 169 print $fh "\n"; 170 } 171 } 172 } 173} 174 175# Usage 176sub printUsage 177{ 178 print " 179 $0 -i [MRW filename] -m [MetaData filename] -o [Output filename] [OPTIONS] 180Options: 181 -d = debug mode 182 --skip-broken-mrw = Skip broken MRW targets 183 \n"; 184 exit(1); 185} 186 187# Helper function to put debug statements. 188sub printDebug 189{ 190 my $str = shift; 191 print "DEBUG: ", $str, "\n" if $debug; 192} 193 194