Skip to content

Commit 0de8b11

Browse files
committed
Add Node.js code samples for calling Netbackup APIs of GET method
type Added support to store ca certificate on the local machine at temp location. Added Node.js modue for loginAPI, getHostDetails and getNBImages APIs Added sample client code to call above module.
1 parent c38dff8 commit 0de8b11

File tree

5 files changed

+344
-0
lines changed

5 files changed

+344
-0
lines changed

snippets/nodejs/README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
### NetBackup API Code Samples for Node.js
2+
3+
This directory contains code samples to invoke NetBackup REST APIs using node.js.
4+
5+
#### Disclaimer
6+
7+
These scripts are only meant to be used as a reference. If you intend to use them in production, use it at your own risk.
8+
9+
#### Pre-requisites:
10+
11+
- NetBackup 8.1.1 or higher
12+
- node.js v8.9.4 or higher
13+
- node.js modules: `https, fs, stdio, pem`
14+
- openssl and openssl path should be configured in system path.
15+
16+
* To install node.js module, Run `npm install <module_name>`.
17+
18+
#### Executing the snippets in Node.js
19+
20+
Before running API samples, run following command to store CA certificate.
21+
- `node get_ca_cert.js --nbmaster <master_server> [--port <port_number>] [--verbose]`
22+
or
23+
- `node get_ca_cert.js -n<master_server> [-pr <port_number>] [-v]`
24+
25+
Use the following commands to run the node.js samples.
26+
- `node get_nb_images.js --nbmaster <master_server> [--port <port_number>] --username <username> --password <password> [--domainname <domain_name>] [--domaintype <domain_type>] [--verbose]`
27+
or
28+
- `node get_nb_hosts.js -n<master_server> [-pr <port_number>] -u <username> -p <password> [-d <domain_name>] [-t <domain_type>] [-v]`

snippets/nodejs/get_ca_cert.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
var netbackup = require("./netbackup-module/netbackup.js");
2+
// including stdio just for creating help
3+
var stdio = require('stdio');
4+
var parms = stdio.getopt({
5+
'nbmaster' : { key: 'n', args: 1, description: 'Master server name', mandatory: true },
6+
'port' : { key: 'pr', args: 1, default: '1556', description: 'Port number' },
7+
'verbose' : { key: 'v', args: 1, description: 'Verbose statements' }
8+
});
9+
10+
var contentType = "application/vnd.netbackup+json;version=1.0";
11+
var verbose;
12+
13+
function main() {
14+
verbose = (parms.verbose === undefined) ? false: true;
15+
16+
netbackup.printOnConsole('\nDeploying CA certificate...', verbose);
17+
netbackup.getCACertificate(parms.nbmaster, parms.port, contentType, verbose);
18+
19+
}
20+
21+
main();

snippets/nodejs/get_nb_hosts.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
var netbackup = require("./netbackup-module/netbackup.js");
2+
// including stdio just for creating help
3+
var stdio = require('stdio');
4+
var parms = stdio.getopt({
5+
'nbmaster' : { key: 'n', args: 1, description: 'Master server name', mandatory: true },
6+
'port' : { key: 'pr', args: 1, default: '1556', description: 'Port number' },
7+
'username' : { key: 'u', args: 1, description: 'User name', mandatory: true },
8+
'password' : { key: 'p', args: 1, description: 'Password of a user', mandatory: true },
9+
'domainname' : { key: 'd', args: 1, default: '', description: 'Domain name (empty by default)' },
10+
'domaintype' : { key: 't', args: 1, default: '', description: 'Domain type (empty by default)' },
11+
'verbose' : { key: 'v', args: 1, description: 'Verbose statements' }
12+
});
13+
14+
var contentType = "application/vnd.netbackup+json;version=1.0";
15+
var jwt;
16+
var verbose;
17+
18+
function main() {
19+
verbose = (parms.verbose === undefined) ? false: true;
20+
21+
netbackup.printOnConsole('\nMaking call to login API...', verbose);
22+
netbackup.loginWithUser(parms.nbmaster, parms.port, parms.username, parms.password,
23+
parms.domainname, parms.domaintype, contentType, verbose, loginResponse);
24+
}
25+
26+
function loginResponse(data) {
27+
if (typeof data.errorCode != 'undefined') {
28+
console.info("\nError:\n " + JSON.stringify(data, null, 4));
29+
} else {
30+
netbackup.printOnConsole('\nLogin completed!', verbose);
31+
jwt = data.token;
32+
netbackup.printOnConsole('\nJWT token : ' + jwt, verbose);
33+
34+
netbackup.getHostDetails(parms.nbmaster, parms.port, jwt, contentType, verbose, hostsListResponse);
35+
}
36+
}
37+
38+
function hostsListResponse(data) {
39+
if (typeof data.errorCode != 'undefined') {
40+
console.info("\nError:\n " + JSON.stringify(data, null, 4));
41+
} else {
42+
console.info("\nHosts:\n " + JSON.stringify(data, null, 4));
43+
netbackup.printOnConsole('\nDone!!!');
44+
}
45+
}
46+
47+
main();

snippets/nodejs/get_nb_images.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
var netbackup = require("./netbackup-module/netbackup.js");
2+
// including stdio just for creating help
3+
var stdio = require('stdio');
4+
var parms = stdio.getopt({
5+
'nbmaster' : { key: 'n', args: 1, description: 'Master server name', mandatory: true },
6+
'port' : { key: 'pr', args: 1, default: '1556', description: 'Port number' },
7+
'username' : { key: 'u', args: 1, description: 'User name', mandatory: true },
8+
'password' : { key: 'p', args: 1, description: 'Password of a user', mandatory: true },
9+
'domainname' : { key: 'd', args: 1, default: '', description: 'Domain name (empty by default)' },
10+
'domaintype' : { key: 't', args: 1, default: '', description: 'Domain type (empty by default)' },
11+
'verbose' : { key: 'v', args: 1, description: 'Verbose statements' }
12+
});
13+
14+
var contentType = "application/vnd.netbackup+json;version=1.0";
15+
var jwt;
16+
var verbose;
17+
18+
function main() {
19+
verbose = (parms.verbose === undefined) ? false: true;
20+
21+
netbackup.printOnConsole('\nMaking call to login API...', verbose);
22+
netbackup.loginWithUser(parms.nbmaster, parms.port, parms.username, parms.password,
23+
parms.domainname, parms.domaintype, contentType, verbose, loginResponse);
24+
}
25+
26+
function loginResponse(data) {
27+
if (typeof data.errorCode != 'undefined') {
28+
console.info("\nError:\n "+ JSON.stringify(data, null, 4));
29+
} else {
30+
netbackup.printOnConsole('\nLogin completed!', verbose);
31+
jwt = data.token;
32+
netbackup.printOnConsole('\nJWT token : ' + jwt, verbose);
33+
34+
netbackup.getNBImages(parms.nbmaster, parms.port, jwt, contentType, verbose, nbImages);
35+
}
36+
}
37+
38+
function nbImages(data) {
39+
if (typeof data.errorCode != 'undefined') {
40+
console.info("\nError:\n "+ JSON.stringify(data, null, 4));
41+
} else {
42+
console.info("\nNB Images:\n "+ JSON.stringify(data, null, 4));
43+
netbackup.printOnConsole('\nDone!!!');
44+
}
45+
}
46+
47+
main();
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
// =============================================================
2+
// @module netbackup
3+
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4+
// This file contains modules to call NetBackup APIs.
5+
// =============================================================
6+
7+
var fs = require('fs');
8+
var https = require('https');
9+
var pem = require('pem');
10+
var stdio = require('stdio');
11+
12+
var exportedMethod = {};
13+
14+
// To disable certificate/ssl verification, uncomment following line
15+
// process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
16+
17+
var CA_CERT_PATH
18+
= isWindows() ? "C:\\temp\\cacert.pem" : "\temp\cacert.pem";
19+
20+
exportedMethod.getCACertificate = function (server, port, contentType, verbose) {
21+
var getCAURI = "/netbackup/security/cacert";
22+
23+
var optionsForCACert = {
24+
method: "GET",
25+
hostname: server,
26+
port: port,
27+
path: getCAURI,
28+
rejectUnauthorized: false // To avoid an error, because the cert is unauthorized
29+
};
30+
31+
if (fs.existsSync(CA_CERT_PATH)) {
32+
stdio.question('CA certificate is already present, Do you want to override certificate? ', ['y', 'n'], function (err, answer) {
33+
if (answer === 'y') {
34+
deployCACertificate(optionsForCACert, verbose);
35+
} else {
36+
return;
37+
}
38+
});
39+
} else {
40+
deployCACertificate(optionsForCACert, verbose);
41+
}
42+
} // End of Get CA Certificate API
43+
44+
exportedMethod.loginWithUser = function (server, port, username, password, domainname, domaintype, contentType, verbose, returnedRes) {
45+
46+
if (!fs.existsSync(CA_CERT_PATH)) {
47+
var error = {errorCode:404, errorMessage:'Login Failed: CA certificate is not present. Please run get_ca_cert.js.'};
48+
returnedRes(error);
49+
return;
50+
}
51+
52+
var loginURI = "/netbackup/login";
53+
54+
// create the JSON object
55+
loginPayload = JSON.stringify({
56+
"userName": username,
57+
"password": password,
58+
"domainName": domainname,
59+
"domainType": domaintype
60+
});
61+
printOnConsole('\nLogin payload: ' + loginPayload, verbose);
62+
63+
var optionForLoginURI = {
64+
method: 'POST',
65+
host: server,
66+
port: port,
67+
path: loginURI,
68+
ca: [fs.readFileSync(CA_CERT_PATH, { encoding: 'utf-8' })],
69+
rejectUnauthorized: true,
70+
requestCert: true,
71+
agent: false,
72+
"headers": {
73+
'content-type': contentType,
74+
'Content-Length': loginPayload.length
75+
}
76+
};
77+
78+
printOnConsole('\nWaiting for Login request to complete...', verbose);
79+
performRequest(optionForLoginURI, loginPayload, verbose, returnedRes);
80+
81+
} // End of Login API
82+
83+
exportedMethod.getHostDetails = function (server, port, jwt, contentType, verbose, returnedRes) {
84+
var hostsListURI = "/netbackup/config/hosts/hostmappings";
85+
86+
if (!fs.existsSync(CA_CERT_PATH)) {
87+
var error = {errorCode:404, errorMessage:'Get Host List Failed: CA certificate is not present. Please run get_ca_cert.js.'};
88+
returnedRes(error);
89+
return;
90+
}
91+
92+
var optionForHostsListURI = {
93+
method: 'GET',
94+
host: server,
95+
port: port,
96+
path: hostsListURI,
97+
ca: [fs.readFileSync(CA_CERT_PATH, { encoding: 'utf-8' })],
98+
rejectUnauthorized: true,
99+
requestCert: true,
100+
agent: false,
101+
"headers": {
102+
'content-type': contentType,
103+
'authorization': jwt
104+
}
105+
};
106+
107+
printOnConsole("\nFetching hosts...", verbose);
108+
performRequest(optionForHostsListURI, null, verbose, returnedRes);
109+
110+
} // END of getHostDetails
111+
112+
exportedMethod.getNBImages = function (server, port, jwt, contentType, verbose, returnedRes) {
113+
var hostsListURI = "/netbackup/catalog/images";
114+
115+
if (!fs.existsSync(CA_CERT_PATH)) {
116+
var error = {errorCode:404, errorMessage:'Get NB Images Failed: CA certificate is not present. Please run get_ca_cert.js.'};
117+
returnedRes(error);
118+
return;
119+
}
120+
121+
var optionForHostsListURI = {
122+
method: 'GET',
123+
host: server,
124+
port: port,
125+
path: hostsListURI,
126+
ca: [fs.readFileSync(CA_CERT_PATH, { encoding: 'utf-8' })],
127+
rejectUnauthorized: true,
128+
requestCert: true,
129+
agent: false,
130+
"headers": {
131+
'content-type': contentType,
132+
'authorization': jwt
133+
}
134+
};
135+
printOnConsole("\nFetching NB Images...", verbose);
136+
performRequest(optionForHostsListURI, null, verbose, returnedRes);
137+
138+
} // END of getNBImages
139+
140+
exportedMethod.printOnConsole = function (stmt, verbose) {
141+
printOnConsole(stmt, verbose);
142+
}
143+
144+
function deployCACertificate(option, verbose) {
145+
printOnConsole("Deploying CA Certificate...", verbose);
146+
performRequest(option, null, verbose, saveCACertificate);
147+
}
148+
149+
function saveCACertificate(data) {
150+
var answer = pem.getFingerprint(data.webRootCert, 'sha1', function (err, result) {
151+
console.info(result.fingerprint);
152+
stdio.question('Do you want to trust this fingerprint? ', ['y', 'n'], function (err, answer) {
153+
if (answer === 'y') {
154+
fs.writeFileSync(CA_CERT_PATH, data.webRootCert);
155+
console.info("CA Certificate is saved successfully.");
156+
} else {
157+
console.info("CA Certificate operation failed.");
158+
}
159+
});
160+
} );
161+
}
162+
163+
function performRequest(option, payload, verbose, returnedRes) {
164+
var req = https.request(option, function (response) {
165+
printOnConsole('\nStatusCode: ' + response.statusCode, verbose);
166+
response.setEncoding('utf-8');
167+
var data;
168+
response.on('data', function (resBody) {
169+
printOnConsole("\nRaw response body: " + resBody, verbose);
170+
data = JSON.parse(resBody);
171+
});
172+
response.on('end', function () {
173+
returnedRes(data);
174+
});
175+
});
176+
177+
if(payload !=null) {
178+
req.write(payload);
179+
}
180+
req.end();
181+
req.on('error', function (errorData) {
182+
console.info('Error ocuured : \n');
183+
console.error(errorData);
184+
});
185+
}
186+
187+
function isWindows(){
188+
if (/^win/i.test(process.platform)) {
189+
return true;
190+
} else {
191+
return false;
192+
}
193+
}
194+
195+
function printOnConsole(stmt, verbose) {
196+
if (verbose) {
197+
console.info(stmt);
198+
}
199+
}
200+
201+
module.exports = exportedMethod;

0 commit comments

Comments
 (0)