예제 #1
0
파일: models.py 프로젝트: zimagi/zimagi
class Host(Model('host')):

    def api(self, options_callback = None, message_callback = None):
        return zimagi.Client(
            user = self.user,
            token = self.token,
            encryption_key = self.encryption_key if settings.ENCRYPT_COMMAND_API or settings.ENCRYPT_DATA_API else None,
            host = self.host,
            command_port = self.command_port,
            data_port = self.data_port,
            options_callback = options_callback,
            message_callback = message_callback
        )

    def command_api(self, options_callback = None, message_callback = None):
        return zimagi.command.Client(
            user = self.user,
            token = self.token,
            encryption_key = self.encryption_key if settings.ENCRYPT_COMMAND_API else None,
            host = self.host,
            port = self.command_port,
            options_callback = options_callback,
            message_callback = message_callback
        )

    def data_api(self, options_callback = None):
        return zimagi.data.Client(
            user = self.user,
            token = self.token,
            encryption_key = self.encryption_key if settings.ENCRYPT_DATA_API else None,
            host = self.host,
            port = self.data_port,
            options_callback = options_callback
        )
예제 #2
0
파일: auth.py 프로젝트: zimagi/zimagi
class APITokenAuthentication(authentication.TokenAuthentication):

    user_class = Model('user')
    api_type = None

    def get_auth_header(self, request):
        header = authentication.get_authorization_header(request)
        if header and isinstance(header, (bytes, bytearray)):
            header = header.decode('utf-8')
        return header

    def parse_token(self, token_text):
        auth_components = re.split(r'\s+', token_text)

        if len(auth_components) != 3:
            raise exceptions.AuthenticationFailed(
                "Invalid token. Required format: {} <user_name> <token>".
                format(self.keyword))
        if auth_components[0].lower() != self.keyword.lower():
            raise exceptions.AuthenticationFailed(
                "Authentication header required: 'Authorization: {} <user_name> <token>'"
                .format(self.keyword))

        try:
            user = self.user_class.facade.retrieve(auth_components[1])
            token = auth_components[2]

        except self.user_class.DoesNotExist:
            raise exceptions.AuthenticationFailed(
                'Invalid token: User not found')

        return (user, token)

    def authenticate(self, request):
        token_text = self.get_auth_header(request)
        if not token_text:
            return None

        user, token = self.parse_token(token_text)
        try:
            if self.api_type:
                token = Cipher.get(self.api_type,
                                   user=user.name).decrypt(token)

        except Exception as error:
            raise exceptions.AuthenticationFailed(
                'Invalid token header. Credentials can not be decrypted')

        if not user.is_active:
            raise exceptions.AuthenticationFailed(
                'User account is inactive. Contact administrator')
        if not user.check_password(token):
            raise exceptions.AuthenticationFailed(
                'Invalid token: User credentials are invalid')

        user.last_login = now()
        user.save()

        self.user_class.facade.set_active_user(user)
        return (user, token)
예제 #3
0
파일: middleware.py 프로젝트: zimagi/zimagi
    def process_response(self, request, response):
        if request.path != '/status':
            cache_entry = Model('cache').facade.get_or_create(
                request.build_absolute_uri())
            cache_entry.requests += 1
            cache_entry.save()

        if not (hasattr(request, '_cache_update_cache')
                and request._cache_update_cache):
            return response

        response['Object-Cache'] = 'MISS'

        if response.streaming or response.status_code not in (200, 304):
            return response

        if not request.COOKIES and response.cookies and has_vary_header(
                response, 'Cookie'):
            return response

        if 'private' in response.get('Cache-Control', ()):
            return response

        timeout = get_max_age(response)
        if timeout is None:
            timeout = self.cache_timeout
        elif timeout == 0:
            return response

        patch_response_headers(response, timeout)

        if timeout and response.status_code == 200:
            cache_key = learn_cache_key(request,
                                        response,
                                        timeout,
                                        self.key_prefix,
                                        cache=self.cache)
            if hasattr(response, 'render') and callable(response.render):
                response.add_post_render_callback(
                    lambda r: self.cache.set(cache_key, r, timeout))
            else:
                self.cache.set(cache_key, response, timeout)

        return response
예제 #4
0
파일: models.py 프로젝트: mbeacom/zimagi
class ScheduledTask(ScheduleModelMixin,
                    DerivedAbstractModel(celery_beat_models,
                                         'PeriodicTask',
                                         id=None,
                                         name=None,
                                         args=None,
                                         kwargs=None,
                                         interval=None,
                                         crontab=None,
                                         clocked=None,
                                         solar=None), Model('scheduled_task')):
    objects = celery_beat_managers.PeriodicTaskManager()
예제 #5
0
파일: models.py 프로젝트: zimagi/zimagi
class ScheduledTask(
    ScheduleModelMixin,
    DerivedAbstractModel(celery_beat_models, 'PeriodicTask',
        id = None,
        name = None,
        args = None,
        kwargs = None,
        interval = None,
        crontab = None,
        clocked = None,
        solar = None
    ),
    Model('scheduled_task')
):
    objects = celery_beat_managers.PeriodicTaskManager()

    def validate_unique(self, *args, **kwargs):
        super(celery_beat_models.PeriodicTask, self).validate_unique(*args, **kwargs)

        schedule_types = ['interval', 'crontab', 'clocked']
        selected_schedule_types = [s for s in schedule_types
                                   if getattr(self, s)]

        if len(selected_schedule_types) == 0:
            raise ValidationError(
                'One of clocked, interval, crontab, or solar '
                'must be set.'
            )

        err_msg = 'Only one of clocked, interval, crontab, '\
            'or solar must be set'
        if len(selected_schedule_types) > 1:
            error_info = {}
            for selected_schedule_type in selected_schedule_types:
                error_info[selected_schedule_type] = [err_msg]
            raise ValidationError(error_info)

        # clocked must be one off task
        if self.clocked and not self.one_off:
            err_msg = 'clocked must be one off, one_off must set True'
            raise ValidationError(err_msg)

    def save(self, *args, **kwargs):
        self.exchange = self.exchange or None
        self.routing_key = self.routing_key or None
        self.queue = self.queue or None
        self.headers = self.headers or None
        if not self.enabled:
            self.last_run_at = None
        self._clean_expires()
        self.validate_unique()
        super(celery_beat_models.PeriodicTask, self).save(*args, **kwargs)
예제 #6
0
class User(AbstractBaseUser, Model('user')):
    USERNAME_FIELD = 'name'

    objects = UserManager()

    def save(self, *args, **kwargs):
        if not self.password and self.name == settings.ADMIN_USER:
            self.set_password(settings.DEFAULT_ADMIN_TOKEN)
        super().save(*args, **kwargs)

    @property
    def env_groups(self, **filters):
        filters['environment_id'] = Model('environment').facade.get_env()
        return self.groups.filter(**filters)
예제 #7
0
파일: auth.py 프로젝트: mbeacom/zimagi
class APITokenAuthentication(authentication.TokenAuthentication):

    user_class = Model('user')

    def get_auth_header(self, request):
        return authentication.get_authorization_header(request)

    def validate_token_header(self, auth):
        if len(auth) == 1:
            msg = 'Invalid token header. No credentials provided.'
            logger.warning(msg)
            raise exceptions.AuthenticationFailed(msg)

        elif len(auth) > 2:
            msg = 'Invalid token header. Token string should not contain spaces.'
            logger.warning(msg)
            raise exceptions.AuthenticationFailed(msg)

    def authenticate_credentials(self, auth):
        self.validate_token_header(auth)

        components = auth[1].split('++')

        if len(components) != 2:
            raise exceptions.AuthenticationFailed(
                'Invalid token. Required format: Token user++token')
        try:
            user = self.user_class.facade.retrieve(components[0])
            token = components[1]

        except self.user_class.DoesNotExist:
            raise exceptions.AuthenticationFailed(
                'Invalid token: User not found')

        if not user.is_active:
            raise exceptions.AuthenticationFailed(
                'User account is inactive. Contact administrator')

        if not user.check_password(token):
            raise exceptions.AuthenticationFailed(
                'Invalid token: User credentials are invalid')

        user.last_login = now()
        user.save()

        self.user_class.facade.set_active_user(user)
        return (user, token)
예제 #8
0
class User(AbstractBaseUser, Model('user')):
    USERNAME_FIELD = 'name'

    objects = UserManager()

    def save(self, *args, **kwargs):
        if not self.password and self.name == settings.ADMIN_USER:
            self.set_password(settings.DEFAULT_ADMIN_TOKEN)

        if not self.encryption_key or self.encryption_key == '<generate>':
            self.encryption_key = Cipher.get_provider_class(
                'user_api_key').generate_key()

        super().save(*args, **kwargs)

    @property
    def env_groups(self, **filters):
        return self.groups.filter(**filters)
예제 #9
0
파일: models.py 프로젝트: mbeacom/zimagi
class Module(Model('module')):

    STATUS_VALID = 'valid'
    STATUS_INVALID = 'invalid'


    @property
    def status(self):
        path = self.provider.module_path(self.name, ensure = False)
        zimagi_path = os.path.join(path, 'zimagi.yml')

        if self.provider.check_system() or os.path.isfile(zimagi_path):
            return self.STATUS_VALID
        return self.STATUS_INVALID


    def save(self, *args, **kwargs):
        try:
            caches[settings.CACHE_MIDDLEWARE_ALIAS].clear()
            caches[settings.CACHE_MIDDLEWARE_ALIAS].close()
        except Exception:
            pass

        super().save(*args, **kwargs)
        self.save_deploy_modules()


    @classmethod
    def save_deploy_modules(cls):
        config_facade = model_index().get_facade_index()['config']
        deploy_modules = []
        for module in cls.facade.all():
            if module.remote:
                deploy_modules.append({
                    'remote': module.remote,
                    'reference': module.reference,
                    'config': module.config
                })
        config_facade.store('deploy_modules',
            value = serialized_token() + serialize(deploy_modules),
            value_type = 'str'
        )
예제 #10
0
class Environment(Model('environment')):

    @property
    def is_active(self):
        return True if self.name == self.facade.get_env() else False


    def save(self, *args, **kwargs):
        env_name = Runtime.get_env()
        if self.name == env_name:
            image = self.base_image
            if self.runtime_image:
                image = self.runtime_image

            Runtime.set_env(
                self.name,
                self.repo,
                image
        )
        super().save(*args, **kwargs)
예제 #11
0
class Log(Model('log')):

    STATUS_QUEUED = 'queued'
    STATUS_RUNNING = 'running'
    STATUS_SUCCESS = 'success'
    STATUS_FAILED = 'failed'
    STATUS_ABORTED = 'aborted'
    STATUS_UNTRACKED = 'untracked'

    def save(self, *args, **kwargs):
        if not self.name:
            self.name = "{}{}x".format(now().strftime("%Y%m%d%H%M%S"),
                                       self.facade.generate_token(5))
        super().save(*args, **kwargs)

    def success(self):
        return self.status == self.STATUS_SUCCESS

    def failed(self):
        return self.status == self.STATUS_FAILED

    def aborted(self):
        return self.status == self.STATUS_ABORTED

    def running(self):
        return self.status == self.STATUS_RUNNING

    def queued(self):
        return self.status == self.STATUS_QUEUED

    def untracked(self):
        return self.status == self.STATUS_UNTRACKED

    def set_status(self, status):
        if isinstance(status, bool):
            self.status = self.STATUS_SUCCESS if status else self.STATUS_FAILED
        else:
            self.status = status
예제 #12
0
 def env_groups(self, **filters):
     filters['environment_id'] = Model('environment').facade.get_env()
     return self.groups.filter(**filters)
예제 #13
0
class Config(Model('config')):
    def save(self, *args, **kwargs):
        self.value = data.format_value(self.value_type, self.value)
        super().save(*args, **kwargs)
예제 #14
0
class LogMessage(Model('log_message')):
    def __str__(self):
        return "{} ({})".format(self.log.command, self.data)
예제 #15
0
파일: models.py 프로젝트: mbeacom/zimagi
class TaskDatetime(ScheduleModelMixin,
                   DerivedAbstractModel(celery_beat_models,
                                        'ClockedSchedule',
                                        id=None), Model('task_datetime')):
    pass
예제 #16
0
파일: models.py 프로젝트: mbeacom/zimagi
class TaskCrontab(ScheduleModelMixin,
                  DerivedAbstractModel(celery_beat_models,
                                       'CrontabSchedule',
                                       id=None), Model('task_crontab')):
    pass
예제 #17
0
 def get_base_scope(self):
     return {'environment_id': Model('environment').facade.get_env()}
예제 #18
0
파일: models.py 프로젝트: mbeacom/zimagi
class Group(Model('group')):

    def __str__(self):
        if self.parent:
            return "{} ({})".format(self.name, self.parent)
        return self.name
예제 #19
0
파일: models.py 프로젝트: mbeacom/zimagi
class TaskInterval(ScheduleModelMixin,
                   DerivedAbstractModel(celery_beat_models,
                                        'IntervalSchedule',
                                        id=None), Model('task_interval')):
    pass