Overview
As I mentioned in the previous article, NetWorker 9 SP1 has introduced a REST API. I’ve never previously got around to playing with REST API interfaces, but as is always the case with programming, you either do it because you’re getting paid to or because it’s something that strikes you as interesting.
Accessing NetWorker via a REST API does indeed strike me as interesting. Even more so if I can do it using my favourite language, Perl.
This is by no means meant to be a programming tutorial, nor am I claiming to be the first to experiment with it. If you want to check out an in-development use of the REST API, check out Karsten Bott’s PowerShell work to date over at the NetWorker Community Page. This post covers just the process of bootstrapping myself to the point I have working code – the real fun and work comes next!
What you’ll need
For this to work, you’ll need a suitably recent Perl 5.x implementation. I’m practicing on my Mac laptop, running Perl 5.18.2.
You’ll also need the following modules:
- MIME::Base64
- REST::Client
- Data::Dumper
- JSON
And of course, you’ll need a NetWorker server running NetWorker 9, SP1.
Getting started
I’m getting old an crotchety when it comes to resolving dependencies. When I was younger I used to manually download each CPAN module I needed, try to compile, strike dependency requirements, recurse down those modules and keep going until I’d either solved all the dependencies or threw the computer out the window and became a monk.
So to get the above modules I invoked the cpan install function on my Mac as follows:
pmdg@ganymede$ cpan install MIME::Base64 pmdg@ganymede$ cpan install REST::Client pmdg@ganymede$ cpan install Data::Dumper pmdg@ganymede$ cpan install JSON
There was a little bit of an exception thrown in the REST::Client installation about packages that could be used for testing, but overall the CPAN based installer worked well and saved me a lot of headaches.
The code
The code itself is extremely simple – as I mentioned this is a proof of concept, not intended to be an interface as such. It’s from here I’ll start as I play around in greater detail. My goal for the code was as follows:
- Prompt for username and password
- Connect via REST API
- Retrieve a complete list of clients
- Dump out the data in a basic format to confirm it was successful
The actual code therefore is:
pmdg@ganymede$ cat tester.pl #!/usr/bin/perl -w use strict; use MIME::Base64(); use REST::Client; use Data::Dumper; use JSON; my $username = ""; my $password = ""; print "Username: "; $username = <>; chomp $username; print "Password: "; $password = <>; chomp $password; my $encoded = MIME::Base64::encode($username . ":" . $password); $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; my $client = REST::Client->new(); my $headers = { Accept => 'application/json', Authorization => 'Basic ' . $encoded}; $client->setHost('https://orilla.turbamentis.int:9090'); $client->GET('/nwrestapi/v1/global/clients',$headers); my $response = from_json($client->responseContent); print Dumper($response);
Notes on the Code
If you’re copying and pasting the code, about the only thing you should need to change is the hostname in the line starting $client->setHost.
It’s not particularly secure in the password prompt as Perl will automatically echo the password as you’re entering it. There are ways of disabling this echo, but they require the Term::Readkey library and that may not be readily available on all systems. So just keep this in mind…
The Results
Here’s the starting output for the code:
pmdg@ganymede$ ./tester.pl Username: administrator Password: MySuperSecretPassword $VAR1 = { 'clients' => [ { 'ndmpMultiStreamsEnabled' => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' ), 'ndmpVendorInformation' => [], 'protectionGroups' => [], 'resourceId' => { 'sequence' => 79, 'id' => '198.0.72.12.0.0.0.0.132.105.45.87.192.168.100.4' }, 'links' => [ { 'rel' => 'item', 'href' => 'https://orilla.turbamentis.int:9090/nwrestapi/v1/global/clients/198.0.72.12.0.0.0.0.132.105.45.87.192.168.100.4' } ], 'parallelSaveStreamsPerSaveSet' => $VAR1->{'clients'}[0]{'ndmpMultiStreamsEnabled'}, 'hostname' => 'archon.turbamentis.int',
And so on…
In Summary
The script isn’t pretty at the moment, but I wanted to get it out there as an example. As I hack around with it and get more functionality, I’ll provide updates.
Hopefully however you can see that it’s pretty straight-forward overall to access the REST API!
References
- REST API Getting Started Guide
- REST API Reference Guide
- Writing a REST Client in Perl – I basically used this as supplementary explanations to the CPAN documentation for the REST::Client module.
- Karsten’s PowerShell REST Interface
Hi Rick,
first of all a BIG thanks for the Code snippet.
But even with your Perl Code, I get the “unauthorized user or password” error
So the question is what LINUX OS do you use?
Mine is a SuSE SLES 11SP3
kind regards
Uwe
I performed my first test with curl as the EMC “getting started with rest api” guide states.
Encoding the username:password combination led to authentication issues at first as openssl encoding used also the newline for the encoding. The string used in the EMC example showed this as my own decoding did not generate the same base64 string as the guide. Once I encoded correctly, I was able to query for all defined NW clients with curl, exactly as stated in the guide.
EMC base64 encoded string:
$ base64 -d <<password encoder/decoder one can perform the base64 de- and encoding.
Hi barry,
you saved my day 🙂 !!!
Many thanks for this hint, I used the command line base64
like this
THIS IS WRONG : echo “administrator:password” | base64 –
If I use it like this
THIS is correct : echo -n “administrator:password” | base64 –
everything works fine
Hi Uwe,
My NetWorker server is running CentOS 6.5 but I do not see that should affect the authorisation.
The code itself is running on a Mac.
Cheers,
Preston.
something apparently happened when supplying my first comment about using the rest api as it seems to have truncated some of the output somewhat.
Intended to state the following together with full example:
I performed my first test with curl as the EMC “getting started with rest api” guide states.
Encoding the username:password combination led to authentication issues at first as openssl encoding used also the newline for the encoding. The string used in the EMC example showed this as my own decoding did not generate the same base64 string as the guide. Once I encoded correctly, I was able to query for all defined NW clients with curl, exactly as stated in the guide.
EMC base64 encoded string:
$ base64 -d <<< YWRtaW5pc3RyYXRvcjohNFUyYnVpbGQ=
administrator:!4U2build
My own base64 encode however generated a different base64 string (only last character differs):
$ openssl enc -base64 <<< 'administrator:!4U2build'
YWRtaW5pc3RyYXRvcjohNFUyYnVpbGQK
Ensuring there is no trailing newline resulted in the same base64 string as EMC example when using echo -n:
$ echo -n 'administrator:!4U2build' | openssl enc -base64
YWRtaW5pc3RyYXRvcjohNFUyYnVpbGQ=
I was also pointed to a opensource java rest client by a colleague, downloadable from https://github.com/wiztools/rest-client, which can used as a GUI (CLI also available) to perform all the requests and has the option to save requests. Also includes under "tools" a "password encoder/decoder" with which one can perform the base64 de- and encoding.
Had to add the following 3 headers to the rest client GUI:
Accept Application/json
Authorization Basic xxxxxxxxxxxxxxxxxx=
Content-Type application/json
Where the xxxxxxxxxxxxxx= strings needs to be replaced with the base64 encoded username:password string,
And under SSL I ticked the check boxes "Ignore cert errors" and "disable hostname verification".
I’m trying hard to make this work, but I’m hitting errors, is there a way to simply query the API with curl or wget to perform GET requests to confirm that we’re hitting the right URL?
I’m currently getting this error, how can I access the full error message?
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before “Can’t connect to ser…”) at ./tester.pl line 26.
You sure can! Check out the script referred to in this blog post for finding unprotected virtual machines via the REST API. You’ll see a curl reference in the script.