127 lines
3.8 KiB
Python
127 lines
3.8 KiB
Python
#!/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))
|