| import base64 |
| import fnmatch |
| import os |
| import sys |
| import time |
| import traceback |
| from protos import utility_pb2 |
| from google.protobuf.empty_pb2 import Empty |
| |
| from importlib import import_module |
| from django.conf import settings
|
| SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
|
| |
| from django.contrib.auth import authenticate as django_authenticate |
| import django.apps |
| from django.db.models import F,Q |
| from core.models import * |
| from xos.exceptions import * |
| from apihelper import XOSAPIHelperMixin, translate_exceptions |
| |
| # The Tosca engine expects to be run from /opt/xos/tosca/ or equivalent. It |
| # needs some sys.path fixing up. |
| import inspect |
| currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) |
| toscadir = os.path.join(currentdir, "../tosca") |
| |
| def is_internal_model(model): |
| """ things to be excluded from the dirty_models endpoints """ |
| if 'django' in model.__module__: |
| return True |
| if 'cors' in model.__module__: |
| return True |
| if 'contenttypes' in model.__module__: |
| return True |
| if 'core.models.journal' in model.__module__: # why? |
| return True |
| if 'core.models.project' in model.__module__: # why? |
| return True |
| return False |
| |
| class UtilityService(utility_pb2.utilityServicer, XOSAPIHelperMixin): |
| def __init__(self, thread_pool): |
| self.thread_pool = thread_pool |
| |
| def stop(self): |
| pass |
| |
| @translate_exceptions |
| def Login(self, request, context): |
| if not request.username: |
| raise XOSNotAuthenticated("No username") |
| |
| u=django_authenticate(username=request.username, password=request.password) |
| if not u: |
| raise XOSNotAuthenticated("Failed to authenticate user %s" % request.username) |
| |
| session = SessionStore() |
| auth = {"username": request.username, "password": request.password} |
| session["auth"] = auth |
| session['_auth_user_id'] = u.pk |
| session['_auth_user_backend'] = u.backend |
| session.save() |
| |
| response = utility_pb2.LoginResponse() |
| response.sessionid = session.session_key |
| |
| return response |
| |
| @translate_exceptions |
| def Logout(self, request, context): |
| for (k, v) in context.invocation_metadata(): |
| if (k.lower()=="x-xossession"): |
| s = SessionStore(session_key=v) |
| if "_auth_user_id" in s: |
| del s["_auth_user_id"] |
| s.save() |
| return Empty() |
| |
| @translate_exceptions |
| def RunTosca(self, request, context): |
| user=self.authenticate(context, required=True) |
| |
| sys_path_save = sys.path |
| try: |
| sys.path.append(toscadir) |
| from tosca.engine import XOSTosca |
| xt = XOSTosca(request.recipe, parent_dir=toscadir, log_to_console=False) |
| xt.execute(user) |
| except: |
| response = utility_pb2.ToscaResponse() |
| response.status = response.ERROR |
| response.messages = traceback.format_exc() |
| return response |
| finally: |
| sys.path = sys_path_save |
| |
| response = utility_pb2.ToscaResponse() |
| response.status = response.SUCCESS |
| response.messages = "\n".join(xt.log_msgs) |
| |
| return response |
| |
| @translate_exceptions |
| def DestroyTosca(self, request, context): |
| user=self.authenticate(context, required=True) |
| |
| sys_path_save = sys.path |
| try: |
| sys.path.append(toscadir) |
| from tosca.engine import XOSTosca |
| xt = XOSTosca(request.recipe, parent_dir=toscadir, log_to_console=False) |
| xt.destroy(user) |
| except: |
| response = utility_pb2.ToscaResponse() |
| response.status = response.ERROR |
| response.messages = traceback.format_exc() |
| return response |
| finally: |
| sys.path = sys_path_save |
| |
| response = utility_pb2.ToscaResponse() |
| response.status = response.SUCCESS |
| response.messages = "\n".join(xt.log_msgs) |
| |
| return response |
| |
| @translate_exceptions |
| def NoOp(self, request, context): |
| return Empty() |
| |
| @translate_exceptions |
| def ListDirtyModels(self, request, context): |
| dirty_models = utility_pb2.ModelList() |
| |
| models = django.apps.apps.get_models() |
| for model in models: |
| if is_internal_model(model): |
| continue |
| fieldNames = [x.name for x in model._meta.fields] |
| if (not "enacted" in fieldNames) or (not "updated" in fieldNames): |
| continue |
| if (request.class_name) and (not fnmatch.fnmatch(model.__name__, request.class_name)): |
| continue |
| objs = model.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None)) |
| for obj in objs: |
| item = dirty_models.items.add() |
| item.class_name = model.__name__ |
| item.id = obj.id |
| |
| return dirty_models |
| |
| @translate_exceptions |
| def SetDirtyModels(self, request, context): |
| user=self.authenticate(context, required=True) |
| |
| dirty_models = utility_pb2.ModelList() |
| |
| models = django.apps.apps.get_models() |
| for model in models: |
| if is_internal_model(model): |
| continue |
| fieldNames = [x.name for x in model._meta.fields] |
| if (not "enacted" in fieldNames) or (not "updated" in fieldNames): |
| continue |
| if (request.class_name) and (not fnmatch.fnmatch(model.__name__, request.class_name)): |
| continue |
| objs = model.objects.all() |
| for obj in objs: |
| try: |
| obj.caller = user |
| obj.save() |
| except Exception, e: |
| item = dirty_models.items.add() |
| item.class_name = model.__name__ |
| item.id = obj.id |
| item.info = str(e) |
| |
| return dirty_models |
| |