001: #! /opt/quantum/python27/bin/python 002: 003: import requests 004: import argparse 005: import re 006: import sys 007: import urllib 008: from time import sleep 009: 010: global failures 011: failures = 0 012: global args 013: global username 014: global password 015: global verbose 016: 017: def check_job_status( ws_rsp): 018: global args 019: global failures 020: global verbose 021: 022: print "%s" % (ws_rsp,) 023: m = re.search( '"message" : "Job has been successfully submitted."', ws_rsp) 024: if m: 025: m = re.search( '"job" : "(\d+)"', ws_rsp) 026: if m: 027: jobno = m.group(1) 028: else: 029: print "job not found --------------------------------------------------" 030: return 031: ws_rsp2 = do_webservices_cmd( '/job/mover/info', 032: { 'job' : jobno } ) 033: print ws_rsp2 034: ws_rsp = do_webservices_cmd( '/job/info', 035: { 'job' : jobno } ) 036: count = 0 037: while re.search( 'RUNNING', ws_rsp): 038: sleep(1) 039: ws_rsp2 = do_webservices_cmd( '/job/mover/info', 040: { 'job' : jobno } ) 041: print ws_rsp2 042: ws_rsp = do_webservices_cmd( '/job/info', 043: { 'job' : jobno } ) 044: print ws_rsp 045: count += 1 046: ws_rsp2 = do_webservices_cmd( '/job/mover/info', 047: { 'job' : jobno } ) 048: print ws_rsp2 049: print "Checked for completion: %d times" % (count,) 050: print ws_rsp 051: if re.search( 'Status: ERROR', ws_rsp): 052: print "Job had error -----------------------------------------------------" 053: failures += 1 054: else: 055: print "Job not submitted correctly -----------------------------------------------------" 056: failures += 1 057: 058: 059: 060: def process_args(): 061: global args 062: global username 063: global password 064: global verbose 065: 066: parser = argparse.ArgumentParser() 067: parser.add_argument("--verbose", 068: action='store_true', 069: dest='verbose', 070: help=" Be verbose in output.") 071: parser.add_argument("--authenticate", 072: action='store', 073: dest='authenticate', 074: metavar='[authentication]', 075: default='', 076: help=" Authenticate all WS calls, value is 'username/password'.") 077: parser.add_argument("--protocol", 078: action='store', 079: dest='protocol', 080: metavar='[PROTOCOL]', 081: choices=['http', 'https'], 082: help=" The protocol to use.") 083: parser.add_argument("--format", 084: action='store', 085: dest='format', 086: choices=['text', 'json', 'xml'], 087: default='json', 088: help=" The format for response.") 089: parser.add_argument("--ip", 090: action='store', 091: dest='ip', 092: default='', 093: help=" The ip of the MDC.") 094: 095: # Parse the command-line 096: args = parser.parse_args() 097: 098: print "authenticate: %s" % (args.authenticate,) 099: print "format: %s" % (args.format,) 100: print "ip: %s" % (args.ip,) 101: print "protocol: %s" % (args.protocol,) 102: print "verbose: %s" % (args.verbose,) 103: verbose = args.verbose 104: 105: # check the ip, standard 4 numbers '.' separated 106: # 107: m = re.compile( '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$') 108: if not m.match( args.ip): 109: print "ip not in correct format: %s" % (args.ip,) 110: sys.exit(1) 111: 112: # check authentication 113: # 114: if args.authenticate == '': 115: username = '' 116: password = '' 117: elif '/' in args.authenticate: 118: username, password = args.authenticate.split( '/') 119: username = username + '_py' 120: password = password + '_py' 121: else: 122: print 'Authenticate argument must have '/' between the username and password:' 123: print "value: %s" % (args.authenticate,) 124: sys.exit(1) 125: 126: 127: def do_webservices_cmd( cmd, pieces={}): 128: global args 129: global failures 130: global username 131: global password 132: global verbose 133: 134: # set up the URL prefix 135: # 136: if 'wsconfig' in cmd: 137: prefix = "http://%s:81/sws/v2" % (args.ip,) 138: elif 'https' in args.protocol: 139: prefix = "https://%s:81/sws/v2" % (args.ip,) 140: else: 141: prefix = "http://%s:81/sws/v2" % (args.ip,) 142: 143: #? print "prefix: %s" % (prefix,) #? 144: 145: ws = prefix + cmd 146: 147: # if we do not already have a format parameter 148: # 149: if 'format' not in pieces: 150: #if 'job' not in cmd: 151: pieces['format'] = args.format 152: 153: # add login parameters if we need to authenticate 154: # 155: if args.authenticate != '': 156: pieces['username'] = username 157: pieces['password'] = password 158: 159: # all web-service URLs are lowercase 160: # 161: ws = ws.lower() 162: 163: response = requests.get( ws, pieces, verify=False) 164: if verbose: 165: print 166: print "WS: %s" % (urllib.unquote(response.url),) 167: 168: rsp = response.text 169: #? print "rsp; %s" % (rsp,) #? 170: if response.status_code == 200: 171: return rsp 172: else: 173: failures += 1 174: return "Fail: %s" % (rsp,) 175: 176: 177: if __name__ == '__main__': 178: global username 179: global password 180: 181: process_args() 182: 183: #Description of Web Services sample programs: 184: 185: # 0) Please turn on web-services using the StorNext GUI 186: # Also choose protocol and authentication through the SN GUI 187: 188: # 1) Do WS system info, returning TEXT, XML and JSON 189: # /sws/v2/system/info?format=text 190: 191: ws_rsp = do_webservices_cmd( '/system/info', 192: { 'format' : 'text' } ) 193: print ws_rsp 194: 195: # /sws/v2/system/info?format=xml 196: 197: ws_rsp = do_webservices_cmd( '/system/info', 198: { 'format' : 'xml' } ) 199: print ws_rsp 200: 201: # /sws/v2/system/info?format=json 202: 203: ws_rsp = do_webservices_cmd( '/system/info', 204: { 'format' : 'json' } ) 205: print ws_rsp 206: 207: # 2) Create a policy for a managed file system 208: 209: # 3) 3 directories should exist: 210: # a) Directory for single-file manipulation 211: 212: singles_path = '/stornext/snfs1/sample_dir_singles/py' 213: singles_paths_sync = [] 214: singles_paths_async = [] 215: 216: # b) Directory for directory manipulation 217: 218: dirs_path_sync = '/stornext/snfs1/sample_dir_dirs_sync/py' 219: dirs_paths_sync = [] 220: dirs_path_async = '/stornext/snfs1/sample_dir_dirs_async/py' 221: dirs_paths_async = [] 222: 223: # c) Directory for multi-file manipulation 224: 225: multi_path = '/stornext/snfs1/sample_dir_multi/py' 226: multi_paths_sync = [] 227: multi_paths_async = [] 228: 229: # 4) Create arrays with path names of both files in each of those directories 230: # for single and multi commands, files 0 and 1 are for sync, files 2 and 3 are for async 231: # for directory commands, there is a directory for sync and one for async 232: 233: for i in [0,1]: 234: filename = "file.%d" % (i,) 235: singles_paths_sync.append( "%s/%s" % (singles_path, filename)) 236: dirs_paths_sync.append( "%s/%s" % (dirs_path_sync, filename)) 237: dirs_paths_async.append( "%s/%s" % (dirs_path_async, filename)) 238: multi_paths_sync.append( "%s/%s" % (multi_path, filename)) 239: 240: for i in [2,3]: 241: filename = "file.%d" % (i,) 242: singles_paths_async.append( "%s/%s" % (singles_path, filename)) 243: multi_paths_async.append( "%s/%s" % (multi_path, filename)) 244: 245: 246: # 5-11) steps 5-11 use sync mode, steps 12-18 use async mode 247: 248: # 5) Use WS fsstore to save both files from the first directory to TAPE 249: # /sws/v2/file/fsstore?file=<filepath> 250: 251: for filepath in singles_paths_sync: 252: ws_rsp = do_webservices_cmd( '/file/fsstore', 253: { 'file' : filepath } ) 254: print ws_rsp 255: 256: # /sws/v2/file/fsfileinfo?file=<filepath> 257: 258: for filepath in singles_paths_sync: 259: ws_rsp = do_webservices_cmd( '/file/fsfileinfo', 260: { 'file' : filepath } ) 261: print ws_rsp 262: 263: # 6) Use WS fsstore to save the second directory to TAPE 264: # /sws/v2/file/fsstore?directory=<dirpath> 265: 266: ws_rsp = do_webservices_cmd( '/file/fsstore', 267: { 'directory' : dirs_path_sync } ) 268: print ws_rsp 269: 270: # /sws/v2/file/fsfileinfo?directory=<dirpath> 271: 272: ws_rsp = do_webservices_cmd( '/file/fsfileinfo', 273: { 'directory' : dirs_path_sync } ) 274: print ws_rsp 275: 276: # 7) Use WS fsstore to save both files from the third directory to TAPE 277: # /sws/v2/file/fsstore?file=<f1>&file=<f2> 278: 279: ws_rsp = do_webservices_cmd( '/file/fsstore', 280: { 'file' : [ multi_paths_sync[0], 281: multi_paths_sync[1] ] } ) 282: print ws_rsp 283: 284: 285: # /sws/v2/file/fsfileinfo?file=<f1>&file=<f2> 286: 287: ws_rsp = do_webservices_cmd( '/file/fsfileinfo', 288: { 'file' : [ multi_paths_sync[0], 289: multi_paths_sync[1] ] } ) 290: print ws_rsp 291: 292: 293: # 8) Use WS rmdiskcopy to truncate both files in each of 3 directories 294: # /sws/v2/file/fsrmdiskcopy 295: 296: for filepath in singles_paths_sync: 297: ws_rsp = do_webservices_cmd( '/file/fsrmdiskcopy', 298: { 'file' : filepath } ) 299: print ws_rsp 300: 301: for filepath in dirs_paths_sync: 302: ws_rsp = do_webservices_cmd( '/file/fsrmdiskcopy', 303: { 'file' : filepath } ) 304: print ws_rsp 305: 306: for filepath in multi_paths_sync: 307: ws_rsp = do_webservices_cmd( '/file/fsrmdiskcopy', 308: { 'file' : filepath } ) 309: print ws_rsp 310: 311: # 9) Use WS fsretrieve to restore both files to first directory from TAPE 312: # /sws/v2/file/fsretrieve?file=<filepath> 313: 314: for filepath in singles_paths_sync: 315: ws_rsp = do_webservices_cmd( '/file/fsretrieve', 316: { 'file' : filepath } ) 317: print ws_rsp 318: 319: # /sws/v2/file/fsfileinfo?file=<filepath> 320: 321: for filepath in singles_paths_sync: 322: ws_rsp = do_webservices_cmd( '/file/fsfileinfo', 323: { 'file' : filepath } ) 324: print ws_rsp 325: 326: # 10) Use WS fsretrieve to restore the second directory from TAPE 327: # /sws/v2/file/fsretrieve?directory=<dirpath> 328: 329: ws_rsp = do_webservices_cmd( '/file/fsretrieve', 330: { 'directory' : dirs_path_sync } ) 331: print ws_rsp 332: 333: # /sws/v2/file/fsfileinfo?directory=<dirpath> 334: 335: ws_rsp = do_webservices_cmd( '/file/fsfileinfo', 336: { 'directory' : dirs_path_sync } ) 337: print ws_rsp 338: 339: # 11) Use WS fsretrieve to restore both files in the third directory from TAPE 340: # /sws/v2/file/fsretrieve?file=<f1>&file=<f2> 341: 342: ws_rsp = do_webservices_cmd( '/file/fsretrieve', 343: { 'file' : [ multi_paths_sync[0], 344: multi_paths_sync[1] ] } ) 345: print ws_rsp 346: 347: 348: # /sws/v2/file/fsfileinfo?file=<f1>&file=<f2> 349: 350: ws_rsp = do_webservices_cmd( '/file/fsfileinfo', 351: { 'file' : [ multi_paths_sync[0], 352: multi_paths_sync[1] ] } ) 353: print ws_rsp 354: 355: 356: # 12-18) Repeat steps 5-11 using async mode 357: 358: # 12) Use WS fsstore to save both files from the first directory to TAPE 359: # /sws/v2/file/fsstore?file=<filepath> 360: 361: for filepath in singles_paths_async: 362: ws_rsp = do_webservices_cmd( '/file/fsstore', 363: { 'file' : filepath, 364: 'mode' : 'async' } ) 365: check_job_status( ws_rsp) 366: 367: # /sws/v2/file/fsfileinfo?file=<filepath> 368: 369: for filepath in singles_paths_async: 370: ws_rsp = do_webservices_cmd( '/file/fsfileinfo', 371: { 'file' : filepath } ) 372: print ws_rsp 373: 374: # 13) Use WS fsstore to save the second directory to TAPE 375: # /sws/v2/file/fsstore?directory=<dirpath> 376: 377: ws_rsp = do_webservices_cmd( '/file/fsstore', 378: { 'directory' : dirs_path_async, 379: 'mode' : 'async' } ) 380: check_job_status( ws_rsp) 381: 382: # /sws/v2/file/fsfileinfo?directory=<dirpath> 383: 384: ws_rsp = do_webservices_cmd( '/file/fsfileinfo', 385: { 'directory' : dirs_path_async } ) 386: print ws_rsp 387: 388: # 14) Use WS fsstore to save both files from the third directory to TAPE 389: # /sws/v2/file/fsstore?file=<f1>&file=<f2> 390: 391: ws_rsp = do_webservices_cmd( '/file/fsstore', 392: { 'file' : [ multi_paths_async[0], 393: multi_paths_async[1] ], 394: 'mode' : 'async' } ) 395: check_job_status( ws_rsp) 396: 397: # /sws/v2/file/fsfileinfo?file=<f1>&file=<f2> 398: 399: ws_rsp = do_webservices_cmd( '/file/fsfileinfo', 400: { 'file' : [ multi_paths_async[0], 401: multi_paths_async[1] ] } ) 402: print ws_rsp 403: 404: 405: # 15) Use WS rmdiskcopy to truncate both files in each of 3 directories 406: # /sws/v2/file/fsrmdiskcopy 407: 408: for filepath in singles_paths_async: 409: ws_rsp = do_webservices_cmd( '/file/fsrmdiskcopy', 410: { 'file' : filepath } ) 411: print ws_rsp 412: 413: for filepath in dirs_paths_async: 414: ws_rsp = do_webservices_cmd( '/file/fsrmdiskcopy', 415: { 'file' : filepath } ) 416: print ws_rsp 417: 418: for filepath in multi_paths_async: 419: ws_rsp = do_webservices_cmd( '/file/fsrmdiskcopy', 420: { 'file' : filepath } ) 421: print ws_rsp 422: 423: # 16) Use WS fsretrieve to restore both files to first directory from TAPE 424: # /sws/v2/file/fsretrieve?file=<filepath> 425: 426: for filepath in singles_paths_async: 427: ws_rsp = do_webservices_cmd( '/file/fsretrieve', 428: { 'file' : filepath, 429: 'mode' : 'async' } ) 430: check_job_status( ws_rsp) 431: 432: # /sws/v2/file/fsfileinfo?file=<filepath> 433: 434: for filepath in singles_paths_async: 435: ws_rsp = do_webservices_cmd( '/file/fsfileinfo', 436: { 'file' : filepath } ) 437: print ws_rsp 438: 439: # 17) Use WS fsretrieve to restore the second directory from TAPE 440: # /sws/v2/file/fsretrieve?directory=<dirpath> 441: 442: ws_rsp = do_webservices_cmd( '/file/fsretrieve', 443: { 'directory' : dirs_path_async, 444: 'mode' : 'async' } ) 445: check_job_status( ws_rsp) 446: 447: # /sws/v2/file/fsfileinfo?directory=<dirpath> 448: 449: ws_rsp = do_webservices_cmd( '/file/fsfileinfo', 450: { 'directory' : dirs_path_async } ) 451: print ws_rsp 452: 453: # 18) Use WS fsretrieve to restore both files in the third directory from TAPE 454: # /sws/v2/file/fsretrieve?file=<f1>&file=<f2> 455: 456: ws_rsp = do_webservices_cmd( '/file/fsretrieve', 457: { 'file' : [ multi_paths_async[0], 458: multi_paths_async[1] ], 459: 'mode' : 'async' } ) 460: check_job_status( ws_rsp) 461: 462: # /sws/v2/file/fsfileinfo?file=<f1>&file=<f2> 463: 464: ws_rsp = do_webservices_cmd( '/file/fsfileinfo', 465: { 'file' : [ multi_paths_async[0], 466: multi_paths_async[1] ] } ) 467: 468: # 19) Get policy information 469: 470: ws_rsp = do_webservices_cmd( '/policy/fsdirclass', 471: { 'directory' : dirs_path_async} ) 472: print ws_rsp 473: 474: ws_rsp = do_webservices_cmd( '/policy/fsclassinfo', 475: { 'policy' : 'policy_min_i' } ) 476: print ws_rsp 477: 478: print 479: print "Number of failures: %d" % (failures,) 480: 481: 482: # Copyright 2015 Quantum Corporation 483: # vim:ts=4:sw=4:et:ic:bg=dark: