#!/usr/bin/python import sys,argparse,json,time import time sys.path.insert(0, './classes/') import cohesityAPI as cohesity def GetArgs(): parser = argparse.ArgumentParser(add_help=False) parser.add_argument('--source', '-s', type=str, action='store') parser.add_argument('--replica', '-r', type=str, action='store') parser.add_argument('--delete', '-del', type=str, action='store') return (parser.parse_args()) args = GetArgs() # Connect to the Cohesity cluster source_cluster = cohesity.API(args.source) source_token = source_cluster.GetAuthToken() source_cluster.UpdateHeaders(source_token['accessToken']) source_jobs = source_cluster.GetRequest("/public/protectionJobs") # Connect to the Replica cluster replica_cluster = cohesity.API(args.replica) replica_token = replica_cluster.GetAuthToken() replica_cluster.UpdateHeaders(replica_token['accessToken']) replica_jobs = replica_cluster.GetRequest("/public/protectionJobs") deleted_on_source=[] deleted_on_remote=[] source_only=[] remote_only=[] legal_holds_on_deleted_jobs=[] for s_job in source_jobs: if 'isDeleted' in s_job: if s_job['isDeleted'] == True: deleted_on_source.append(s_job) # Verify there aren't any orphaned snapshots due to legal holds p = s_job['policyId'].split(":") policy = str(p[0])+":"+str(p[1])+":"+str(s_job['id']) run_data = source_cluster.GetRequestV2("/data-protect/protection-groups/"+policy+"/runs?numRuns=1000") runs = run_data['runs'] for run in runs: if run['onLegalHold']: url = "https://{0}/protection/group/run/backup/{1}/{2}".format(args.source,run['protectionGroupId'],run['id']) legal_holds_on_deleted_jobs.append(url) continue is_on_both = False issource_only = False isremote_only = False for r_job in replica_jobs: if s_job['name'] == r_job['name']: is_on_both = True if is_on_both: continue else: source_only.append(s_job) for r_job in replica_jobs: is_on_both = False issource_only = False isremote_only = False if 'isDeleted' in r_job: if r_job['isDeleted'] == True: deleted_on_replica.append(r_job) # Verify there aren't any orphaned snapshots due to legal holds p = r_job['policyId'].split(":") policy = str(p[0])+":"+str(p[1])+":"+str(r_job['id']) run_data = replica_cluster.GetRequestV2("/data-protect/protection-groups/"+policy+"/runs?numRuns=1000") runs = run_data['runs'] for run in runs: if run['onLegalHold']: url = "https://{0}/protection/group/run/backup/{1}/{2}".format(args.replica,run['protectionGroupId'],run['id']) legal_holds_on_deleted_jobs.append(url) continue for s_job in source_jobs: if s_job['name'] == r_job['name']: is_on_both = True if is_on_both: continue else: remote_only.append(r_job) print("\nSource Only:") for src_val in source_only: #resp = source_cluster.DeleteJob("/public/protectionJobs/"+str(value['id'])) #print(resp.content) print(src_val['name']) print("\nRemote Only:") for repl_val in remote_only: print(repl_val['name']) if (args.delete): print("Deleting " + repl_val['name'] + " on replica") resp = replica_cluster.DeleteJob("/public/protectionJobs/"+str(value['id'])) print(resp.content) print("\nDeleted in Source:") for del_val in deleted_on_source: print(del_val['name']) print("\nDeleted on Replica:") for del_val in deleted_on_source: print(del_val['name']) print("\nDeleted Jobs with legal holds on snapshots:") for lh in legal_holds_on_deleted_jobs: print(json.dumps(lh,indent=2))