hobo/hobo/agent/hobo/management/commands/hobo_deploy.py

119 lines
5.9 KiB
Python

from django.contrib.contenttypes.models import ContentType
from django.utils.timezone import now
from tenant_schemas.utils import tenant_context
from hobo.agent.common.management.commands import hobo_deploy
from hobo.deploy.signals import notify_agents
from hobo.environment.models import AVAILABLE_SERVICES, Hobo, Variable
from hobo.multitenant.middleware import TenantMiddleware, TenantNotFound
from hobo.profile.models import AttributeDefinition
class Command(hobo_deploy.Command):
help = 'Deploy multitenant hobo service from hobo'
early_secondary_exit = False
def deploy_specifics(self, hobo_environment, tenant):
me = [x for x in hobo_environment.get('services') if x.get('this')][0]
if not me.get('secondary'):
super(Command, self).deploy_specifics(hobo_environment, tenant)
with tenant_context(tenant):
services = hobo_environment.get('services')
if me.get('secondary'):
# check we are currently processing the primary hobo, we don't
# want to create secondary services on every branches.
if Hobo.objects.filter(secondary=False).count() == 0:
return
for service_dict in services:
if service_dict.get('secondary'):
continue
if service_dict.get('base_url') == me['base_url']:
continue
for service_klass in AVAILABLE_SERVICES:
if service_klass.Extra.service_id == service_dict.get('service-id'):
break
else:
continue
if me.get('secondary') and service_dict.get('service-id') == 'hobo':
continue
if service_klass.objects.filter(secondary=False, base_url=service_dict['base_url']).count():
# make sure a real service is not secondaryed
continue
slug_prefix = '_interco_'
if me.get('secondary'):
# this is the primary hobo, receiving a notification
# because something changed in secondary hobo environment.
# mark services with ou-label/ou-slug
secondary_hobo = [x for x in services if x['service-id'] == 'hobo' and not x.get('secondary')][0]
slug_prefix = '_%s_' % hobo_environment['variables']['ou-slug']
service_slug = '%s%s' % (slug_prefix, service_dict['slug'])
service, created = service_klass.objects.get_or_create(
base_url=service_dict['base_url'],
secondary=True,
defaults={'title': service_dict['title'],
'slug': service_slug,
'secret_key': service_dict.get('secret_key')})
service.title = service_dict['title']
service.secret_key = service_dict.get('secret_key')
service.template_name = service_dict.get('template_name') or ''
service.slug = service_slug
service.use_as_idp_for_self = True
service.last_operational_check_timestamp = now()
service.last_operational_success_timestamp = service.last_operational_check_timestamp
service.save()
if me.get('secondary'):
# add variables to mark the service as a different
# organizational unit
service_type = ContentType.objects.get_for_model(service_klass)
variable, created = Variable.objects.get_or_create(
name='ou-label', auto=True,
service_type=service_type, service_pk=service.id)
variable.value = hobo_environment['variables']['ou-label']
variable.save()
variable, created = Variable.objects.get_or_create(
name='ou-slug', value=secondary_hobo.get('slug'), auto=True,
service_type=service_type, service_pk=service.id)
variable.value = hobo_environment['variables']['ou-slug']
variable.save()
if not me.get('secondary'):
# this is the secondary hobo, set service slug and label as
# global variables so they can later be used to identify
# this "organizational unit".
variable, created = Variable.objects.get_or_create(
name='ou-label', auto=True, service_pk=None)
variable.value = me['title']
variable.save()
variable, created = Variable.objects.get_or_create(
name='ou-slug', auto=True, service_pk=None)
variable.value = me['slug']
variable.save()
# and reproduce profile settings from primary
if 'profile' in hobo_environment:
seen = []
for i, field in enumerate(hobo_environment['profile']['fields']):
attribute, created = AttributeDefinition.objects.get_or_create(
name=field['name'],
defaults={'label': field['label']})
for k, v in field.items():
setattr(attribute, k, v)
attribute.order = i + 1
attribute.save()
seen.append(attribute.name)
AttributeDefinition.objects.exclude(name__in=seen).delete()
if me.get('secondary'):
# on the primary hobo, notify other primary services, this will
# get authentic to know about secondary services
notify_agents(None)