mirror of
https://github.com/peeringdb/peeringdb.git
synced 2024-05-11 05:55:09 +00:00
* module docstrings * db schema graph * dev docs first pass * dev docs pass 2 * add generated notification to top of generated docs files * linting * regen docs Co-authored-by: Stefan Pratter <stefan@20c.com> Co-authored-by: Sunshine Buchholz <sunshine@20c.com>
172 lines
6.3 KiB
Python
172 lines
6.3 KiB
Python
"""
|
|
Merge facilities.
|
|
"""
|
|
import re
|
|
|
|
import reversion
|
|
from django.core.management.base import BaseCommand, CommandError
|
|
from django.db import transaction
|
|
|
|
import peeringdb_server.models as pdbm
|
|
from peeringdb_server.mail import mail_users_entity_merge
|
|
|
|
|
|
def soft_delete(fac, cmd):
|
|
# overriding
|
|
|
|
for k in fac._handleref.delete_cascade:
|
|
q = getattr(fac, k).exclude(status="deleted")
|
|
for c in q:
|
|
if c not in cmd.moved:
|
|
soft_delete(c, cmd)
|
|
|
|
cmd.log("soft deleting %s" % fac)
|
|
if cmd.commit:
|
|
fac.status = "deleted"
|
|
fac.save()
|
|
|
|
|
|
class Command(BaseCommand):
|
|
help = "merge facilities"
|
|
pretend = False
|
|
|
|
def add_arguments(self, parser):
|
|
parser.add_argument(
|
|
"--commit", action="store_true", help="will commit the fac merge"
|
|
)
|
|
parser.add_argument("--target", help="target of the merge (facility id)")
|
|
parser.add_argument("--ids", help="comma separated list of facility ids")
|
|
parser.add_argument(
|
|
"--match", help="all facs with matching names will be merged (regex)"
|
|
)
|
|
|
|
def log(self, msg):
|
|
if not self.commit:
|
|
self.stdout.write("%s [pretend]" % msg)
|
|
else:
|
|
self.stdout.write(msg)
|
|
|
|
@reversion.create_revision()
|
|
@transaction.atomic()
|
|
def handle(self, *args, **options):
|
|
self.commit = options.get("commit", False)
|
|
self.moved = []
|
|
|
|
self.target = options.get("target", 0)
|
|
if not self.target:
|
|
msg = "Target ID required (--target)"
|
|
self.log(msg)
|
|
raise CommandError(msg)
|
|
|
|
self.match = options.get("match", None)
|
|
self.ids = options.get("ids", "")
|
|
|
|
facs = []
|
|
moved = self.moved
|
|
|
|
if self.match:
|
|
if self.ids:
|
|
msg = "ids and match are mutually exclusive"
|
|
self.log(msg)
|
|
raise CommandError(msg)
|
|
|
|
self.log("Merging all facilities matching '%s'" % self.match)
|
|
for fac in pdbm.Facility.objects.exclude(status="deleted"):
|
|
if re.match(self.match, fac.name, re.IGNORECASE):
|
|
facs.append(fac)
|
|
|
|
elif self.ids:
|
|
self.ids = self.ids.split(",")
|
|
self.log(
|
|
"Merging facilities {} -> {}".format(", ".join(self.ids), self.target)
|
|
)
|
|
for fac in pdbm.Facility.objects.filter(id__in=self.ids):
|
|
facs.append(fac)
|
|
|
|
else:
|
|
msg = "IDs or match is required"
|
|
self.log(msg)
|
|
raise CommandError(msg)
|
|
|
|
self.target = pdbm.Facility.objects.get(id=self.target)
|
|
|
|
if self.target.status == "deleted":
|
|
self.target.status = "ok"
|
|
if self.commit:
|
|
self.target.save()
|
|
|
|
for fac in facs:
|
|
if fac.id == self.target.id:
|
|
continue
|
|
self.log("Merging %s (%d) .." % (fac, fac.id))
|
|
for netfac in pdbm.NetworkFacility.objects.filter(facility=fac).exclude(
|
|
status="deleted"
|
|
):
|
|
netfac_other = pdbm.NetworkFacility.objects.filter(
|
|
facility=self.target, network_id=netfac.network_id
|
|
)
|
|
# we check if the target fac already has a netfac to the same network (that is currently undeleted), if it does we skip it
|
|
if netfac_other.exclude(status="deleted").exists():
|
|
self.log(
|
|
" - netfac %s : connection already exists at target, skipping."
|
|
% netfac
|
|
)
|
|
continue
|
|
# if it exists but is currently delete, we simply undelete it
|
|
elif netfac_other.exists():
|
|
netfac_other = netfac_other.first()
|
|
netfac_other.local_asn = netfac.local_asn
|
|
netfac_other.avail_sonet = netfac.avail_sonet
|
|
netfac_other.avail_ethernet = netfac.avail_ethernet
|
|
netfac_other.avail_atm = netfac.avail_atm
|
|
netfac_other.status = "ok"
|
|
self.log(" - netfac %s (undeleting and updating)" % netfac_other)
|
|
moved.append(netfac_other)
|
|
if self.commit:
|
|
netfac_other.save()
|
|
# if it doesnt exist, we update the facility to the target facility and save
|
|
else:
|
|
self.log(" - netfac %s" % netfac)
|
|
netfac.facility = self.target
|
|
moved.append(netfac)
|
|
if self.commit:
|
|
netfac.save()
|
|
|
|
for ixfac in pdbm.InternetExchangeFacility.objects.filter(
|
|
facility=fac
|
|
).exclude(status="deleted"):
|
|
ixfac_other = pdbm.InternetExchangeFacility.objects.filter(
|
|
facility=self.target, ix=ixfac.ix
|
|
)
|
|
# we check if the target fac already has an ixfac to the same exchange (that is currently undeleted), if it does, we skip it
|
|
if ixfac_other.exclude(status="deleted").exists():
|
|
self.log(
|
|
" - ixfac %s : connection already exists at target, skipping."
|
|
% ixfac
|
|
)
|
|
continue
|
|
# if it exists but is currently deleted, we undelete and copy
|
|
elif ixfac_other.exists():
|
|
ixfac_other = ixfac_other.first()
|
|
ixfac_other.status = "ok"
|
|
moved.append(ixfac_other)
|
|
self.log(" - ixfac %s (undeleting and updating)" % ixfac_other)
|
|
if self.commit:
|
|
ixfac_other.save()
|
|
# if it doesnt exist, we update the facility to the target facility and save
|
|
else:
|
|
self.log(" - ixfac %s" % ixfac)
|
|
ixfac.facility = self.target
|
|
moved.append(ixfac)
|
|
if self.commit:
|
|
ixfac.save()
|
|
|
|
soft_delete(fac, self)
|
|
if self.commit:
|
|
mail_users_entity_merge(
|
|
fac.org.admin_usergroup.user_set.all(),
|
|
self.target.org.admin_usergroup.user_set.all(),
|
|
fac,
|
|
self.target,
|
|
)
|