]> pere.pagekite.me Git - homepage.git/commitdiff
New blog post.
authorPetter Reinholdtsen <pere@hungry.com>
Sat, 28 Feb 2009 22:50:27 +0000 (22:50 +0000)
committerPetter Reinholdtsen <pere@hungry.com>
Sat, 28 Feb 2009 22:50:27 +0000 (22:50 +0000)
blog/data/2009-02-28-hw-support.txt [new file with mode: 0644]

diff --git a/blog/data/2009-02-28-hw-support.txt b/blog/data/2009-02-28-hw-support.txt
new file mode 100644 (file)
index 0000000..aeb42fd
--- /dev/null
@@ -0,0 +1,146 @@
+Title: Checking server hardware support status for Dell, HP and IBM servers
+Tags: english, nuug
+Date: 2009-02-28 23:50
+
+<p>At work, we have a few hundred Linux servers, and with that amount
+of hardware it is important to keep track of when the hardware support
+contract expire for each server.  We have a machine (and service)
+register, which until recently did not contain much useful besides the
+machine room location and contact information for the system owner for
+each machine.  To make it easier for us to track support contract
+status, I've recently spent time on extending the machine register to
+include information about when the support contract expire, and to tag
+machines with expired contracts to make it easy to get a list of such
+machines.  I extended a perl script already being used to import
+information about machines into the register, to also do some screen
+scraping off the sites of Dell, HP and IBM (our majority of machines
+are from these vendors), and automatically check the support status
+for the relevant machines.  This make the support status information
+easily available and I hope it will make it easier for the computer
+owner to know when to get new hardware or renew the support contract.
+The result of this work documented that 27% of the machines in the
+registry is without a support contract, and made it very easy to find
+them.  27% might seem like a lot, but I see it more as the case of us
+using machines a bit longer than the 3 years a normal support contract
+last, to have test machines and a platform for less important
+services.  After all, the machines without a contract are working fine
+at the moment and the lack of contract is only a problem if any of
+them break down.  When that happen, we can either fix it using spare
+parts from other machines or move the service to another old
+machine.</p>
+
+<p>I believe the code for screen scraping the Dell site was originally
+written by Trond Hasle Amundsen, and later adjusted by me and Morten
+Werner Forsbring.  The HP scraping was written by me after reading a
+nice article in ;login: about how to use WWW::Mechanize, and the IBM
+scraping was written by me based on the Dell code.  I know the HTML
+parsing could be done using nice libraries, but did not want to
+introduce more dependencies.  This is the current incarnation:</p>
+
+<p><pre>
+use LWP::Simple;
+use POSIX;
+use WWW::Mechanize;
+use Date::Parse;
+[...]
+sub get_support_info {
+    my ($machine, $model, $serial, $productnumber) = @_;
+    my $str;
+
+    if ( $model =~ m/^Dell / ) {
+        # fetch website from Dell support
+        my $url = "http://support.euro.dell.com/support/topics/topic.aspx/emea/shared/support/my_systems_info/no/details?c=no&cs=nodhs1&l=no&s=dhs&ServiceTag=$serial";
+        my $webpage = get($url);
+        return undef unless ($webpage);
+
+        my $daysleft = -1;
+        my @lines = split(/\n/, $webpage);
+        foreach my $line (@lines) {
+            next unless ($line =~ m/Beskrivelse/);
+            $line =~ s/<[^>]+?>/;/gm;
+            $line =~ m%;(\d{2})/(\d{2})/(\d{4});+(\d{2})/(\d{2})/(\d{4});%g;
+            my $start = "$3-$1-$2";
+            my $end = "$6-$4-$5";
+            $str = "$start -> $end";
+            my $today = POSIX::strftime("%Y-%m-%d", localtime(time));
+            tag_machine_unsupported($machine)
+                if ($end lt $today);
+        }
+    } elsif ( $model =~ m/^HP / ) {
+        my $mech = WWW::Mechanize->new();
+        my $url =
+            'http://www1.itrc.hp.com/service/ewarranty/warrantyInput.do';
+        $mech->get($url);
+        my $fields = {
+            'BODServiceID' => 'NA',
+            'RegisteredPurchaseDate' => '',
+            'country' => 'NO',
+            'productNumber' => $productnumber,
+            'serialNumber1' => $serial,
+        };
+        $mech->submit_form( form_number => 2,
+                            fields      => $fields );
+        # Next step is screen scraping
+        my $content = $mech->content();
+
+        $content =~ s/<[^>]+?>/;/gm;
+        $content =~ s/\s+/ /gm;
+        $content =~ s/;\s*;/;;/gm;
+        $content =~ s/;[\s;]+/;/gm;
+
+        my $today = POSIX::strftime("%Y-%m-%d", localtime(time));
+
+        while ($content =~ m/;Warranty Type;/) {
+            my ($type, $status, $startstr, $stopstr) = $content =~
+                m/;Warranty Type;([^;]+);.+?;Status;(\w+);Start Date;([^;]+);End Date;([^;]+);/;
+            $content =~ s/^.+?;Warranty Type;//;
+            my $start = POSIX::strftime("%Y-%m-%d",
+                                        localtime(str2time($startstr)));
+            my $end = POSIX::strftime("%Y-%m-%d",
+                                      localtime(str2time($stopstr)));
+
+            $str .= "$type ($status) $start -> $end ";
+
+            tag_machine_unsupported($machine)
+                if ($end lt $today);
+        }
+    } elsif ( $model =~ m/^IBM / ) {
+        my ($producttype) = $model =~ m/.*-\[(.{4}).+\]-/;
+        if ($producttype && $serial) {
+            my $content =
+                get("http://www-947.ibm.com/systems/support/supportsite.wss/warranty?action=warranty&brandind=5000008&Submit=Submit&type=$producttype&serial=$serial");
+            if ($content) {
+                $content =~ s/<[^>]+?>/;/gm;
+                $content =~ s/\s+/ /gm;
+                $content =~ s/;\s*;/;;/gm;
+                $content =~ s/;[\s;]+/;/gm;
+
+                $content =~ s/^.+?;Warranty status;//;
+                my ($status, $end) = $content =~ m/;Warranty status;([^;]+)\s*;Expiration date;(\S+) ;/;
+
+                $str .= "($status) -> $end ";
+
+                my $today = POSIX::strftime("%Y-%m-%d", localtime(time));
+                tag_machine_unsupported($machine)
+                    if ($end lt $today);
+            }
+        }
+    }
+    return $str;
+}
+</pre></p>
+
+<p>Here are some examples on how to use the function, using fake
+serial numbers.  The information passed in as arguments are fetched
+from dmidecode.</p>
+
+<p><pre>
+print get_support_info("hp.host", "HP ProLiant BL460c G1", "1234567890"
+                       "447707-B21");
+print get_support_info("dell.host", "Dell Inc. PowerEdge 2950", "1234567");
+print get_support_info("ibm.host", "IBM eserver xSeries 345 -[867061X]-",
+                       "1234567");
+</pre></p>
+
+<p>I would recommend this approach for tracking support contracts for
+everyone with more than a new computers to administer. :)</p>