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