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