def wait_for_completion(resp): activejobses = client.SppAPI(session, 'ngpapp').get( url=resp['response']['links']['activejobsessions']['href']) time.sleep(3) if (len(activejobses['sessions']) < 1): logger.warning( "Something went wrong, please check restore logs on SPP appliance") session.logout() sys.exit(8) jobses = activejobses['sessions'][0] jobsesurl = jobses['links']['self']['href'] logsurl = jobses['links']['log'][ 'href'] + "&pageSize=50000&sort=%5B%7B%22property%22:%22logTime%22,%22direction%22:%22ASC%22%7D%5D" currlogtime = 0 while jobses['status'] == "RUNNING": logs = client.SppAPI(session, 'ngpapp').get(url=logsurl)['logs'] for log in logs: if (log['logTime'] >= currlogtime): # some logs have same timestamp down to ms timestring = datetime.datetime.fromtimestamp( int(log['logTime'] / 1000)).strftime('%Y-%m-%d %H:%M:%S') print(timestring + " " + log['type'] + " " + log['message']) currlogtime = log['logTime'] jobses = client.SppAPI(session, 'ngpapp').get(url=jobsesurl) currlogtime += 1 # prevent double prints if we are waiting on same timestamp time.sleep(10) print("Job ended with status: " + jobses['status'])
def find_db(): searchdata = {"name": options.db} dbsearch = client.SppAPI(session, 'apiapp').post( path="/search?resourceType=database&applicationType=sql&from=hlo", data=searchdata)['databases'] if not dbsearch: logger.warning("Did not find db " + options.db) session.logout() sys.exit(2) for founddb in dbsearch: if founddb['name'] == options.db: if options.inst is not None: inst = client.SppAPI( session, 'apiapp').get(url=founddb['links']['instance']['href']) if options.inst.upper() in inst['name']: return founddb elif options.ag is not None: dag = client.SppAPI(session, 'apiapp').get( url=founddb['links']['databaseGroup']['href']) if options.ag.upper() in dag['name']: return founddb else: return founddb logger.warning("Did not find db " + options.db) session.logout() sys.exit(3)
def build_db_version(db): #find for datetime window only if(options.start is not None and options.site is None): start = int(datetime.datetime.strptime(options.start, '%m/%d/%Y %H:%M').timestamp())*1000 end = int(datetime.datetime.strptime(options.end, '%m/%d/%Y %H:%M').timestamp())*1000 dbcpurl = db['links']['copies']['href'] dbcopies = client.SppAPI(session, 'apiapp').get(url=dbcpurl)['copies'] for copy in dbcopies: prottime = int(copy['protectionInfo']['protectionTime']) if (start < prottime and prottime < end): version = {} version['href'] = copy['links']['version']['href'] version['copy'] = {} version['copy']['href'] = copy['links']['self']['href'] version['metadata'] = {} version['metadata']['useLatest'] = False version['metadata']['protectionTime'] = prottime return version #find for site only elif(options.start is None and options.site is not None): dbcpurl = db['links']['copies']['href'] dbcopies = client.SppAPI(session, 'apiapp').get(url=dbcpurl)['copies'] site = find_site_by_name(options.site) for copy in dbcopies: prottime = int(copy['protectionInfo']['protectionTime']) if (copy['siteId'] == site['id']): version = {} version['href'] = copy['links']['version']['href'] version['copy'] = {} version['copy']['href'] = copy['links']['self']['href'] version['metadata'] = {} version['metadata']['useLatest'] = False version['metadata']['protectionTime'] = prottime return version #find copy for both elif(options.start is not None and options.site is not None): start = int(datetime.datetime.strptime(options.start, '%m/%d/%Y %H:%M').timestamp())*1000 end = int(datetime.datetime.strptime(options.end, '%m/%d/%Y %H:%M').timestamp())*1000 dbcpurl = db['links']['copies']['href'] dbcopies = client.SppAPI(session, 'apiapp').get(url=dbcpurl)['copies'] site = find_site_by_name(options.site) for copy in dbcopies: prottime = int(copy['protectionInfo']['protectionTime']) if (start < prottime and prottime < end and copy['siteId'] == site['id']): version = {} version['href'] = copy['links']['version']['href'] version['copy'] = {} version['copy']['href'] = copy['links']['self']['href'] version['metadata'] = {} version['metadata']['useLatest'] = False version['metadata']['protectionTime'] = prottime return version logger.warning("No specified versions found in date range and/or specified site for " + db['name']) session.logout() sys.exit(3)
def run_job(job): jobrunpath = "job/" + job['id'] + "?action=start&actionname=start" postdata = None if "schema" in job['links']['start']: postdata = get_action_name(job) try: if postdata: response = client.SppAPI(session, 'endeavour').post(path=jobrunpath, data=postdata) else: response = client.SppAPI(session, 'endeavour').post(path=jobrunpath) print("Running job " + job['name']) except client.requests.exceptions.HTTPError as err: print(err.response.content) session.logout() sys.exit(5)
def register_hypervisor(hvinfo): try: response = client.SppAPI(session, 'spphv').post(data=hvinfo) print(options.hvhost + " is registered") except client.requests.exceptions.HTTPError as err: errmsg = json.loads(err.response.content) print(errmsg['response']['description'])
def get_vm_versions(versurl): try: versions = client.SppAPI(session, 'endeavour').get(url=versurl) return versions['contents'] except Exception as e: print("Error getting backup count " + e) sys.exit(6)
def restore_file(): foundfile = search_for_file() versions = get_versions_of_file(foundfile) version = get_version_for_restore(foundfile, versions) restorejob = build_restore_job(version) restore = client.SppAPI(session, 'spphv').post(path="?action=restorefile", data=restorejob)
def create_sla_policy(slainfo): try: response = client.SppAPI(session, 'sppsla').post(data=slainfo) logger.info("SLA Policy " + options.slaname + " is created") except client.requests.exceptions.HTTPError as err: errmsg = json.loads(err.response.content) logger.error(errmsg['response'])
def build_db_source(dbinfo): source = [] dbdata = {} dbdata['href'] = dbinfo['links']['self']['href'] dbmd = {} dbmd['name'] = dbinfo['name'] instanceinfo = client.SppAPI( session, 'apiapp').get(url=dbinfo['links']['instance']['href']) dbmd['instanceVersion'] = instanceinfo['version'] dbmd['instanceId'] = instanceinfo['id'] dbdata['metadata'] = dbmd dbdata['resourceType'] = "database" dbdata['id'] = dbinfo['id'] dbdata['include'] = True if (options.start is not None and options.end is not None and options.pit is None): dbdata['version'] = build_db_version(dbinfo) elif (options.site is not None and options.pit is None): dbdata['version'] = build_db_version(dbinfo) else: dbdata['version'] = {} dbdata['version']['href'] = dbinfo['links']['latestversion']['href'] dbdata['version']['metadata'] = {'useLatest': True} dbdata['metadata']['useLatest'] = True logger.info("Adding db " + dbdata['metadata']['name'] + " to restore job") if (options.pit is not None): dbdata['pointInTime'] = int( datetime.datetime.strptime(options.pit, '%m/%d/%Y %H:%M:%S').timestamp()) * 1000 source.append(copy.deepcopy(dbdata)) return source
def get_alerts(session): try: ''' the dictionary qsp contains the filters, sort statements and others like pageSize''' qsp = {} if options.sort is not None: if options.sort.upper() == "DESC": qsp['sort'] = '[{"property": "last", "direction": "DESC"}]' else: qsp['sort'] = '[{"property": "last", "direction": "ASC"}]' else: qsp['sort'] = '[{"property": "last", "direction": "ASC"}]' qsp['pageSize'] = 10000 # if set too small the number of returned results is incorrect and does not match the timeframe queryResult = client.SppAPI(session, '').get( path='/api/endeavour/alert/message', params=qsp) #queryResult = client.SppAPI(session, '').get(path='/api/endeavour/alert/message') except requests.exceptions.HTTPError as err: print("HTTP Error: {0}".format(err)) spputil.get_error_details(err) print("exiting ...") sys.exit(1) except: print("other ERROR: ", traceback.print_exc()) print("exiting ...") sys.exit(1) return queryResult
def backup_vm(): vm = find_vm() backup = {} backup['resource'] = [] backup['resource'].append(vm['links']['self']['href']) backup['subtype'] = "vmware" if len(vm['storageProfiles']) < 1: logger.warning("VM is not assigned to an SLA policy") session.logout() sys.exit(4) if options.sla is not None: for sp in vm['storageProfiles']: if sp.upper() == options.sla.upper(): backup['slaPolicyName'] = sp else: backup['slaPolicyName'] = vm['storageProfiles'][0] if 'slaPolicyName' not in backup: logger.warning("Provided SLA policy was not found assigned to this vm") session.logout() sys.exit(5) try: response = client.SppAPI(session, 'spphv').post(path='?action=adhoc', data=backup) logger.info("Running backup job for vm " + options.vm) except: logger.warning( "Error running backup job, please see appliance logs for details, note that concurrent runs for the same job is not supported." )
def get_successful_vm_info(): try: path = "/catalog/recovery/hypervisorvm?embed=%28children%28properties%29%29" info = client.SppAPI(session, 'endeavour').get(path=path) return info['children'] except Exception as e: print("Error getting success VM info " + e) sys.exit(3)
def show_copies(): db = find_db() sites = client.SppAPI(session, 'coresite').get()['sites'] dbcpurl = db['links']['copies']['href'] dbcopies = client.SppAPI(session, 'apiapp').get(url=dbcpurl)['copies'] print('{:25.25s} {:25.25s} {:12.12s} {:10.10s}'.format( "SLA Policy", "Backup Time", "Site", "Type")) for copy in dbcopies: butime = datetime.datetime.fromtimestamp( copy['copyTime'] / 1000).strftime('%Y-%m-%d %H:%M:%S') sitename = "Not Found" for site in sites: if (site['id'] == copy['siteId']): sitename = site['name'] print('{:25.25s} {:25.25s} {:12.12s} {:10.10s}'.format( copy['protectionInfo']['policyName'], butime, sitename, copy['mappings'][0]['storageType']))
def find_site_by_name(): sites = client.SppAPI(session, 'coresite').get()['sites'] for site in sites: if(site['name'].upper() == options.sitename.upper()): return site['id'] logger.error("Site name not found") session.logout() sys.exit(2)
def find_site_by_name(sitename): sites = client.SppAPI(session, 'coresite').get()['sites'] for site in sites: if (site['name'].upper() == options.site.upper()): return site logger.warning("Site " + site['name'] + " not found") session.logout() sys.exit(3)
def delete_site(): siteid = find_site_by_name() try: response = client.SppAPI(session, 'coresite').delete(resid=siteid) print(options.sitename + " is deleted") except client.requests.exceptions.HTTPError as err: errmsg = json.loads(err.response.content) print(errmsg['response'])
def assign_vms_to_sla(): assigndata = {} slainfo = get_sla_info() dbinfo = get_db_info() assigndata['subtype'] = options.type assigndata['version'] = "1.0" assigndata['resources'] = dbinfo assigndata['slapolicies'] = slainfo if (slainfo == ""): assigndata['slapolicies'] = [] client.SppAPI(session, 'ngpapp').post(path='?action=applySLAPolicies', data=assigndata) logger.info("dbs are now unassigned") else: resp = client.SppAPI(session, 'ngpapp').post(path='?action=applySLAPolicies', data=assigndata) logger.info("dbs are now assigned")
def assign_vms_to_sla(): assigndata = {} slainfo = get_sla_info() vminfo = get_vm_info() assigndata['subtype'] = "vmware" assigndata['version'] = "1.0" assigndata['resources'] = vminfo assigndata['slapolicies'] = slainfo if (slainfo == ""): assigndata['slapolicies'] = [] client.SppAPI(session, 'spphv').post(path='?action=applySLAPolicies', data=assigndata) logger.info("VMs are now unassigned") else: resp = client.SppAPI(session, 'spphv').post(path='?action=applySLAPolicies', data=assigndata) logger.info("VMs are now assigned")
def get_job_list(): print('{:35.35s} {:20.20s} {:20.20s} {:20.20s}'.format("Job Name", "Status", "Last Run Time", "Last Run Status")) jobs = client.SppAPI(session, 'job').get(path='?pageSize=10000')['jobs'] for job in jobs: if job['lastrun']['start'] > 0: lastruntime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(job['lastrun']['start']/1000)) else: lastruntime = "Never" job['lastSessionStatus'] = "N/A" print('{:35.35s} {:20.20s} {:20.20s} {:20.20s}'.format(job['name'], job['status'], lastruntime, job['lastrun']['status']))
def create_site(): siteinfo = {} siteinfo['name'] = options.sitename siteinfo['description'] = options.sitedesc siteinfo['defaultSite'] = False try: response = client.SppAPI(session, 'coresite').post(data=siteinfo) print(options.sitename + " is created") except client.requests.exceptions.HTTPError as err: errmsg = json.loads(err.response.content) print(errmsg['response'])
def restore_vms(): restore = {} sourceinfo = build_vm_source() subpolicy = build_subpolicy() restore['subType'] = "vmware" restore['spec'] = {} restore['spec']['source'] = sourceinfo restore['spec']['subpolicy'] = subpolicy #prettyprint(restore) resp = client.SppAPI(session, 'spphv').post(path='?action=restore', data=restore) logger.info("VMs are now being restored")
def build_target_instance(): instances = client.SppAPI(session, 'apiapp').get(path='/sql/instance?from=hlo')['instances'] for instance in instances: if(instance['name'] == options.tinst): target = {} target['href'] = instance['links']['self']['href'] target['resourceType'] = instance['resourceType'] return target logger.warning("No target instance found named " + options.tinst) session.logout() sys.exit(6)
def get_vsnap_status(): try: storages = client.SppAPI(session, 'corestorage').get()['storages'] if (len(storages) < 1): print("No vSnap storage providers found") session.logout() sys.exit(2) for storage in storages: if (storage['type'] == "vsnap"): print("vSnap provider " + storage['name'] + " is " + storage['initializeStatus']) except: print("Error connecting to SPP host")
def get_vm_version_info(vm): vmbuinfo = [] urlpath = vm['config']['hypervisorKey'] + "/vm/" + vm[ 'id'] + "/version?from=hlo" versions = client.SppAPI(session, 'corehv').get(path=urlpath)['versions'] for version in versions: data = {} data['slaname'] = version['protectionInfo']['storageProfileName'] data['jobname'] = version['protectionInfo']['policyName'] data['butime'] = time.ctime( version['protectionInfo']['protectionTime'] / 1000)[4:].replace( " ", " ") vmbuinfo.append(data) return vmbuinfo
def find_job_from_name(): try: response = client.SppAPI(session, 'endeavour').get(path='job') joblist = response['jobs'] for job in joblist: if(job['name'].upper() == options.jobname.upper()): return job print("No job with provided name found.") session.logout() sys.exit(2) except client.requests.exceptions.HTTPError as err: print(err.response.content) session.logout() sys.exit(3)
def register_vsnap(): vsnapinfo = {} vsnapinfo['siteId'] = find_site_by_name() vsnapinfo['hostAddress'] = options.vshost vsnapinfo['username'] = options.vsuser vsnapinfo['password'] = options.vspass vsnapinfo['portNumber'] = "8900" vsnapinfo['sslConnection'] = True vsnapinfo['type'] = "vsnap" try: response = client.SppAPI(session, 'storage').post(data=vsnapinfo) print(options.vshost + " is registered") except client.requests.exceptions.HTTPError as err: errmsg = json.loads(err.response.content) print(errmsg['response']['description'])
def get_vm_backup_info(): buinfo = {} for vm in options.vms: searchdata = {"name": vm, "hypervisorType": "*"} vmsearch = client.SppAPI(session, 'corehv').post( path="/search?resourceType=vm&from=hlo", data=searchdata)['vms'] if not vmsearch: logger.warning("Did not find VM " + vm) break for foundvm in vmsearch: if (foundvm['name'] == vm): vmbudata = get_vm_version_info(foundvm) buinfo[foundvm['name']] = vmbudata prettyprint(buinfo) return buinfo
def get_action_name(job): try: response = client.SppAPI(session, 'endeavour').get(url=job['links']['start']['schema']) schemalist = response['parameter']['actionname']['values'] if options.action is None: print("This job requires an action parameter, available are:") for schema in schemalist: print(schema['name']) session.logout() sys.exit(4) for schema in schemalist: if schema['name'].upper() == options.action.upper(): return {'actionname':schema['value']} except client.requests.exceptions.HTTPError as err: print(err.response.content) session.logout() sys.exit(4)
def find_target_vm(version): searchdata = { "name": options.destvm, "hypervisorType": version['summary']['hypervisorType'] } vmsearch = client.SppAPI(session, 'corehv').post( path="/search?resourceType=vm&from=hlo", data=searchdata)['vms'] if not vmsearch: logger.warning("Did not find VM " + options.destvm) session.delete('endeavour/session/') sys.exit(2) for vm in vmsearch: if (vm['name'].upper() == options.destvm.upper()): return vm logger.warning("Did not find VM " + options.destvm) session.delete('endeavour/session/') sys.exit(2)
def query_endpoint(path = None): try: myQueryResult = client.SppAPI(session, '').get(path=path) except requests.exceptions.HTTPError as err: print("HTTP Error: {0}".format(err)) spputil.get_error_details(err) print("exiting ...") sys.exit(1) #return except: print("unknown ERROR: ", sys.exc_info()[0]) print(err) print("exiting ...") sys.exit(1) return myQueryResult