Added --backends --servers orchestrate management command options
This commit is contained in:
parent
9903fffda3
commit
5d95e64965
|
@ -17,6 +17,7 @@ class Bind9MasterDomainBackend(ServiceController):
|
|||
('domains.Domain', 'origin'),
|
||||
)
|
||||
ignore_fields = ['serial']
|
||||
CONF_PATH = settings.DOMAINS_MASTERS_PATH
|
||||
|
||||
@classmethod
|
||||
def is_main(cls, obj):
|
||||
|
@ -27,6 +28,10 @@ class Bind9MasterDomainBackend(ServiceController):
|
|||
def save(self, domain):
|
||||
context = self.get_context(domain)
|
||||
domain.refresh_serial()
|
||||
self.update_zone(domain, context)
|
||||
self.update_conf(context)
|
||||
|
||||
def update_zone(self, domain, context):
|
||||
context['zone'] = ';; %(banner)s\n' % context
|
||||
context['zone'] += domain.render_zone().replace("'", '"')
|
||||
self.append(textwrap.dedent("""\
|
||||
|
@ -37,7 +42,6 @@ class Bind9MasterDomainBackend(ServiceController):
|
|||
mv %(zone_path)s.tmp %(zone_path)s
|
||||
""") % context
|
||||
)
|
||||
self.update_conf(context)
|
||||
|
||||
def update_conf(self, context):
|
||||
self.append(textwrap.dedent("""\
|
||||
|
@ -88,7 +92,9 @@ class Bind9MasterDomainBackend(ServiceController):
|
|||
return servers
|
||||
|
||||
def get_slaves(self, domain):
|
||||
return self.get_servers(domain, Bind9SlaveDomainBackend)
|
||||
return set(settings.DOMAINS_SLAVES).union(
|
||||
set(self.get_servers(domain, Bind9SlaveDomainBackend))
|
||||
)
|
||||
|
||||
def get_context(self, domain):
|
||||
slaves = self.get_slaves(domain)
|
||||
|
@ -99,7 +105,7 @@ class Bind9MasterDomainBackend(ServiceController):
|
|||
'banner': self.get_banner(),
|
||||
'slaves': '; '.join(slaves) or 'none',
|
||||
'also_notify': '; '.join(slaves) + ';' if slaves else '',
|
||||
'conf_path': settings.DOMAINS_MASTERS_PATH,
|
||||
'conf_path': self.CONF_PATH,
|
||||
}
|
||||
context['conf'] = textwrap.dedent("""
|
||||
zone "%(name)s" {
|
||||
|
@ -118,6 +124,7 @@ class Bind9SlaveDomainBackend(Bind9MasterDomainBackend):
|
|||
related_models = (
|
||||
('domains.Domain', 'origin'),
|
||||
)
|
||||
CONF_PATH = settings.DOMAINS_SLAVES_PATH
|
||||
|
||||
def save(self, domain):
|
||||
context = self.get_context(domain)
|
||||
|
@ -132,7 +139,9 @@ class Bind9SlaveDomainBackend(Bind9MasterDomainBackend):
|
|||
self.append('if [[ $UPDATED == 1 ]]; then { sleep 1 && service bind9 reload; } & fi')
|
||||
|
||||
def get_masters(self, domain):
|
||||
return self.get_servers(domain, Bind9MasterDomainBackend)
|
||||
return set(settings.DOMAINS_MASTERS).union(
|
||||
set(self.get_servers(domain, Bind9MasterDomainBackend))
|
||||
)
|
||||
|
||||
def get_context(self, domain):
|
||||
context = {
|
||||
|
@ -140,7 +149,7 @@ class Bind9SlaveDomainBackend(Bind9MasterDomainBackend):
|
|||
'banner': self.get_banner(),
|
||||
'subdomains': domain.subdomains.all(),
|
||||
'masters': '; '.join(self.get_masters(domain)) or 'none',
|
||||
'conf_path': settings.DOMAINS_SLAVES_PATH,
|
||||
'conf_path': self.CONF_PATH,
|
||||
}
|
||||
context['conf'] = textwrap.dedent("""
|
||||
zone "%(name)s" {
|
||||
|
|
|
@ -90,3 +90,15 @@ DOMAINS_FORBIDDEN = getattr(settings, 'DOMAINS_FORBIDDEN',
|
|||
# '%(site_dir)s/forbidden_domains.list')
|
||||
''
|
||||
)
|
||||
|
||||
|
||||
DOMAINS_MASTERS = getattr(settings, 'DOMAINS_MASTERS',
|
||||
# Additional master server ip addresses other than autodiscovered by router.get_servers()
|
||||
()
|
||||
)
|
||||
|
||||
|
||||
DOMAINS_SLAVES = getattr(settings, 'DOMAINS_SLAVES',
|
||||
# Additional slave server ip addresses other than autodiscovered by router.get_servers()
|
||||
()
|
||||
)
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import sys
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.db.models.loading import get_model
|
||||
|
||||
from orchestra.contrib.orchestration import manager
|
||||
from orchestra.contrib.orchestration import manager, Operation
|
||||
from orchestra.contrib.orchestration.models import Server
|
||||
from orchestra.contrib.orchestration.backends import ServiceBackend
|
||||
from orchestra.utils.python import import_class
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
|
@ -18,13 +21,28 @@ class Command(BaseCommand):
|
|||
help='Tells Django to NOT prompt the user for input of any kind.')
|
||||
parser.add_argument('--action', action='store', dest='action',
|
||||
default='save', help='Executes action. Defaults to "save".')
|
||||
parser.add_argument('--servers', action='store', dest='servers',
|
||||
default='save', help='Overrides route server resolution with the provided server.')
|
||||
parser.add_argument('--backends', action='store', dest='backends',
|
||||
default='save', help='Overrides backend.')
|
||||
parser.add_argument('--listbackends', action='store_true', dest='list_backends', default=False,
|
||||
help='List available baclends.')
|
||||
parser.add_argument('--dry-run', action='store_true', dest='dry', default=False,
|
||||
help='Only prints scrtipt.')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
list_backends = options.get('list_backends')
|
||||
if list_backends:
|
||||
for backend in ServiceBackend.get_backends():
|
||||
print(str(backend).split("'")[1])
|
||||
return
|
||||
model = get_model(*options['model'].split('.'))
|
||||
action = options.get('action')
|
||||
interactive = options.get('interactive')
|
||||
servers = options.get('servers', '').split(',')
|
||||
backends = options.get('backends', '').split(',')
|
||||
if (servers and not backends) or (not servers and backends):
|
||||
raise CommandError("--backends and --servers go in tandem.")
|
||||
dry = options.get('dry')
|
||||
kwargs = {}
|
||||
for comp in options.get('query', []):
|
||||
|
@ -34,8 +52,23 @@ class Command(BaseCommand):
|
|||
operations = []
|
||||
operations = set()
|
||||
route_cache = {}
|
||||
for instance in model.objects.filter(**kwargs):
|
||||
manager.collect(instance, action, operations=operations, route_cache=route_cache)
|
||||
if servers:
|
||||
server_objects = []
|
||||
# Get and create missing Servers
|
||||
for server in servers:
|
||||
try:
|
||||
server = Server.objects.get(address=server)
|
||||
except Server.DoesNotExist:
|
||||
server = Server.objects.create(name=server, address=server)
|
||||
server_objects.append(server)
|
||||
# Generate operations for the given backend
|
||||
for instance in model.objects.filter(**kwargs):
|
||||
for backend in backends:
|
||||
backend = import_class(backend)
|
||||
operations.add(Operation(backend, instance, action, servers=server_objects))
|
||||
else:
|
||||
for instance in model.objects.filter(**kwargs):
|
||||
manager.collect(instance, action, operations=operations, route_cache=route_cache)
|
||||
scripts, block = manager.generate(operations)
|
||||
servers = []
|
||||
# Print scripts
|
||||
|
@ -64,7 +97,7 @@ class Command(BaseCommand):
|
|||
if not dry:
|
||||
logs = manager.execute(scripts, block=block)
|
||||
for log in logs:
|
||||
print(log.stdout)
|
||||
sys.stderr.write(log.stderr)
|
||||
print(log.stdout.encode('utf8', errors='replace'))
|
||||
sys.stderr.write(log.stderr.encode('utf8', errors='replace'))
|
||||
for log in logs:
|
||||
print(log.backend, log.state)
|
||||
|
|
|
@ -120,6 +120,9 @@ def SSH(backend, log, server, cmds, async=False):
|
|||
logger.debug(log.traceback)
|
||||
log.save()
|
||||
finally:
|
||||
if log.state == log.STARTED:
|
||||
log.state = log.ABORTED
|
||||
log.save(update_fields=['state'])
|
||||
if channel is not None:
|
||||
channel.close()
|
||||
if ssh is not None:
|
||||
|
|
|
@ -52,6 +52,7 @@ class BackendLog(models.Model):
|
|||
FAILURE = 'FAILURE'
|
||||
ERROR = 'ERROR'
|
||||
REVOKED = 'REVOKED'
|
||||
ABORTED = 'ABORTED'
|
||||
# Special state for mocked backendlogs
|
||||
EXCEPTION = 'EXCEPTION'
|
||||
|
||||
|
@ -62,6 +63,7 @@ class BackendLog(models.Model):
|
|||
(SUCCESS, SUCCESS),
|
||||
(FAILURE, FAILURE),
|
||||
(ERROR, ERROR),
|
||||
(ABORTED, ABORTED),
|
||||
(REVOKED, REVOKED),
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in a new issue