예제 #1
0
    def execute(self, service_settings):
        logger.debug('About to connect service settings "%s" to all available customers' % service_settings.name)
        if not service_settings.shared:
            raise ValueError('It is impossible to connect non-shared settings')
        service_model = SupportedServices.get_service_models()[service_settings.type]['service']

        with transaction.atomic():
            for customer in models.Customer.objects.all():
                defaults = {'available_for_all': True}
                service, _ = service_model.objects.get_or_create(
                    customer=customer, settings=service_settings, defaults=defaults)

                service_project_link_model = service.projects.through
                for project in service.customer.projects.all():
                    service_project_link_model.objects.get_or_create(project=project, service=service)
        logger.info('Successfully connected service settings "%s" to all available customers' % service_settings.name)
예제 #2
0
    def get_queryset(self):
        queryset = models.DefaultPriceListItem.objects.all()
        service = self._find_service()
        if service:
            # Filter items by resource type
            resources = SupportedServices.get_related_models(service)['resources']
            content_types = ContentType.objects.get_for_models(*resources).values()
            queryset = queryset.filter(resource_content_type__in=content_types)

            # Attach service-specific items
            price_list_items = models.PriceListItem.objects.filter(service=service)
            prefetch = Prefetch(
                'pricelistitem_set', queryset=price_list_items, to_attr='service_item'
            )
            queryset = queryset.prefetch_related(prefetch)
        return queryset
예제 #3
0
    def _get_log_context(self, entity_name):
        context = super(ResourceMixin, self)._get_log_context(entity_name)
        # XXX: Add resource_full_name here, because event context does not support properties as fields
        context['resource_full_name'] = self.full_name
        # required for lookups in ElasticSearch by the client
        context['resource_type'] = SupportedServices.get_name_for_model(self)

        # XXX: a hack for IaaS / PaaS / SaaS tags
        # XXX: should be moved to itacloud assembly
        if self.tags.filter(name='IaaS').exists():
            context['resource_delivery_model'] = 'IaaS'
        elif self.tags.filter(name='PaaS').exists():
            context['resource_delivery_model'] = 'PaaS'
        elif self.tags.filter(name='SaaS').exists():
            context['resource_delivery_model'] = 'SaaS'

        return context
예제 #4
0
    def services(self, request, pk=None):
        settings = models.ServiceSettings.objects.get(id=pk)
        projects = {}

        spl_model = SupportedServices.get_related_models(settings)['service_project_link']
        for spl in spl_model.objects.filter(service__settings=settings):
            projects.setdefault(spl.project.id, {
                'name': six.text_type(spl.project),
                'url': get_admin_url(spl.project),
                'services': [],
            })
            projects[spl.project.id]['services'].append({
                'name': six.text_type(spl.service),
                'url': get_admin_url(spl.service),
            })

        return render(request, 'structure/service_settings_entities.html', {'projects': projects.values()})
예제 #5
0
 def get_resources_for_import(self):
     cur_droplets = models.Droplet.objects.all().values_list('backend_id', flat=True)
     statuses = ('active', 'off')
     droplets = self.get_all_droplets()
     return [
         {
             'id': droplet.id,
             'name': droplet.name,
             'created_at': droplet.created_at,
             'cores': droplet.vcpus,
             'ram': droplet.memory,
             'disk': self.gb2mb(droplet.disk),
             'flavor_name': droplet.size_slug,
             'resource_type': SupportedServices.get_name_for_model(models.Droplet),
         }
         for droplet in droplets
         if str(droplet.id) not in cur_droplets and droplet.status in statuses
     ]
예제 #6
0
def connect_customer_to_shared_service_settings(sender,
                                                instance,
                                                created=False,
                                                **kwargs):
    if not created:
        return
    customer = instance

    for shared_settings in ServiceSettings.objects.filter(shared=True):
        try:
            service_model = SupportedServices.get_service_models()[
                shared_settings.type]['service']
            service_model.objects.create(customer=customer,
                                         settings=shared_settings,
                                         available_for_all=True)
        except KeyError:
            logger.warning("Unregistered service of type %s" %
                           shared_settings.type)
예제 #7
0
    def run(self):
        date = datetime.now() - timedelta(days=1)
        start_date = date.replace(hour=0, minute=0, second=0, microsecond=0)
        end_date = start_date + timedelta(days=1, microseconds=-1)

        # XXX: it's just a placeholder, it doesn't work properly now nor implemented anyhow
        #      perhaps it should merely use price estimates..

        models = SupportedServices.get_resource_models().values()

        for model in models:
            resources = model.objects.filter(
                service_project_link__service__settings__shared=True)

            for resource in resources:
                try:
                    data = resource.get_cost(start_date, end_date)
                except NotImplementedError:
                    continue
                else:
                    resource.customer.debit_account(data['total_amount'])
예제 #8
0
def connect_shared_settings(service_settings):
    logger.debug(
        'About to connect service settings "%s" to all available customers' %
        service_settings.name)
    if not service_settings.shared:
        raise ValueError('It is impossible to connect non-shared settings')
    service_model = SupportedServices.get_service_models()[
        service_settings.type]['service']

    with transaction.atomic():
        for customer in structure_models.Customer.objects.all():
            defaults = {'available_for_all': True}
            try:
                service, _ = service_model.objects.get_or_create(
                    customer=customer,
                    settings=service_settings,
                    defaults=defaults)
            except QuotaValidationError:
                logger.warning(
                    'Unable to connect shared service '
                    'settings to customer because quota is exceeded. '
                    'Service settings ID: %s, customer ID: %s',
                    service_settings.id,
                    customer.id,
                )
                continue

            service_project_link_model = service.projects.through
            for project in service.customer.projects.all():
                try:
                    service_project_link_model.objects.get_or_create(
                        project=project, service=service)
                except QuotaValidationError:
                    logger.warning(
                        'Unable to connect shared service to project because '
                        'quota is exceeded. Service ID: %s, project ID: %s',
                        service.id,
                        project.id,
                    )
                    continue
예제 #9
0
 def _create_service(self, service_type, validated_data):
     """
     Marketplace offering model does not accept service_attributes field as is,
     therefore we should remove it from validated_data and create service settings object.
     Then we need to specify created object and offering's scope.
     """
     name = validated_data['name']
     service_attributes = validated_data.pop('service_attributes', {})
     if not service_attributes:
         raise ValidationError({
             'service_attributes': _('This field is required.')
         })
     payload = dict(
         name=name,
         # It is expected that customer URL is passed to the service settings serializer
         customer=self.initial_data['customer'],
         type=service_type,
         **service_attributes
     )
     serializer_class = SupportedServices.get_service_serializer_for_key(service_type)
     serializer = serializer_class(data=payload, context=self.context)
     serializer.is_valid(raise_exception=True)
     service = serializer.save()
     # Usually we don't allow users to create new shared service settings via REST API.
     # That's shared flag is marked as read-only in service settings serializer.
     # But shared offering should be created with shared service settings.
     # That's why we set it to shared only after service settings object is created.
     if validated_data.get('shared'):
         service.settings.shared = True
         service.settings.save()
         # Usually connect shared settings task is called when service is created.
         # But as we set shared flag after serializer has been executed,
         # we need to connect shared settings manually.
         connect_shared_settings(service.settings)
     validated_data['scope'] = service.settings
     return validated_data
예제 #10
0
 def filter_by_logged_object(self):
     return {
         'resource_uuid': self.uuid.hex,
         'resource_type': SupportedServices.get_name_for_model(self)
     }
예제 #11
0
 def test_get_service_serializer(self):
     self.assertEqual(ServiceSerializer,
                      SupportedServices.get_service_serializer(TestService))
예제 #12
0
 def full_name(self):
     return '%s %s' % (SupportedServices.get_name_for_model(self).replace('.', ' '), self.name)
예제 #13
0
    def ready(self):
        from waldur_core.structure import SupportedServices

        from .backend import AWSBackend

        SupportedServices.register_backend(AWSBackend)
예제 #14
0
 def test_model_key(self):
     self.assertEqual(TestConfig.service_name,
                      SupportedServices.get_model_key(TestNewInstance))
예제 #15
0
 def _get_log_context(self, entity_name):
     context = super(Service, self)._get_log_context(entity_name)
     context['service_type'] = SupportedServices.get_name_for_model(self)
     return context
예제 #16
0
 def get_type_display(self):
     return SupportedServices.get_name_for_type(self.type)
예제 #17
0
 def get_resource_type(self, obj):
     if isinstance(obj.resource, structure_models.ResourceMixin):
         return SupportedServices.get_name_for_model(obj.resource_content_type.model_class())
예제 #18
0
 def __init__(self, *args, **kwargs):
     super(ServiceSettingsAdminForm, self).__init__(*args, **kwargs)
     self.fields['type'] = ChoiceField(
         choices=SupportedServices.get_choices(), widget=RadioSelect)
예제 #19
0
 def lookups(self, request, model_admin):
     return SupportedServices.get_choices()
예제 #20
0
    def ready(self):
        from waldur_core.quotas.fields import QuotaField, CounterQuotaField
        from waldur_core.structure import SupportedServices
        from waldur_core.structure import models as structure_models
        from waldur_core.structure import signals as structure_signals
        from waldur_freeipa import models as freeipa_models

        from .backend import SlurmBackend
        from . import handlers, models, utils

        SupportedServices.register_backend(SlurmBackend)

        signals.post_save.connect(
            handlers.process_user_creation,
            sender=freeipa_models.Profile,
            dispatch_uid='waldur_slurm.handlers.process_user_creation',
        )

        signals.pre_delete.connect(
            handlers.process_user_deletion,
            sender=freeipa_models.Profile,
            dispatch_uid='waldur_slurm.handlers.process_user_deletion',
        )

        structure_models_with_roles = (structure_models.Customer,
                                       structure_models.Project)
        for model in structure_models_with_roles:
            structure_signals.structure_role_granted.connect(
                handlers.process_role_granted,
                sender=model,
                dispatch_uid='waldur_slurm.handlers.process_role_granted.%s' %
                model.__class__,
            )

            structure_signals.structure_role_revoked.connect(
                handlers.process_role_revoked,
                sender=model,
                dispatch_uid='waldur_slurm.handlers.process_role_revoked.%s' %
                model.__class__,
            )

        for quota in utils.QUOTA_NAMES:
            structure_models.Customer.add_quota_field(
                name=quota, quota_field=QuotaField(is_backend=True))

            structure_models.Project.add_quota_field(
                name=quota, quota_field=QuotaField(is_backend=True))

        structure_models.Project.add_quota_field(
            name='nc_allocation_count',
            quota_field=CounterQuotaField(
                target_models=lambda: [models.Allocation],
                path_to_scope='service_project_link.project',
            ))

        structure_models.Customer.add_quota_field(
            name='nc_allocation_count',
            quota_field=CounterQuotaField(
                target_models=lambda: [models.Allocation],
                path_to_scope='service_project_link.project.customer',
            ))

        signals.post_save.connect(
            handlers.update_quotas_on_allocation_usage_update,
            sender=models.Allocation,
            dispatch_uid=
            'waldur_slurm.handlers.update_quotas_on_allocation_usage_update',
        )
예제 #21
0
 def get_scope_type(cls):
     return SupportedServices.get_name_for_model(cls)
예제 #22
0

def get_marketplace_offering_uuid(serializer, scope):
    try:
        return models.Resource.objects.get(scope=scope).offering.uuid
    except ObjectDoesNotExist:
        return


def add_marketplace_offering(sender, fields, **kwargs):
    fields['marketplace_offering_uuid'] = serializers.SerializerMethodField()
    setattr(sender, 'get_marketplace_offering_uuid',
            get_marketplace_offering_uuid)


core_signals.pre_serializer_fields.connect(
    sender=structure_serializers.CustomerSerializer,
    receiver=add_service_provider,
)

core_signals.pre_serializer_fields.connect(
    sender=support_serializers.OfferingSerializer,
    receiver=add_marketplace_offering,
)

for resource_serializer in SupportedServices.get_resource_serializers():
    core_signals.pre_serializer_fields.connect(
        sender=resource_serializer,
        receiver=add_marketplace_offering,
    )
예제 #23
0
def validate_service_type(service_type):
    from django.core.exceptions import ValidationError
    if not SupportedServices.has_service_type(service_type):
        raise ValidationError(_('Invalid service type.'))
예제 #24
0
 def get_spl_model(self):
     """
     Get service project link model used by resource model using service registry.
     """
     return SupportedServices.get_related_models(
         self.get_resource_model())['service_project_link']
예제 #25
0
 def get_backend(self, **kwargs):
     return SupportedServices.get_service_backend(self.type)(self, **kwargs)
예제 #26
0
 def ready(self):
     SupportedServices.register_backend(TestBackend)
     SupportedServices.register_service(self.get_model('TestService'))
예제 #27
0
 def get_services(self):
     service_model = SupportedServices.get_service_models()[self.type]['service']
     return service_model.objects.filter(settings=self)
예제 #28
0
    def ready(self):
        from waldur_core.core import signals as core_signals
        from waldur_core.quotas import signals as quota_signals
        from waldur_core.structure import SupportedServices

        from . import (
            handlers,
            models,
            utils,
            signals as marketplace_signals,
            processors,
        )
        from .plugins import manager

        signals.post_save.connect(
            handlers.create_screenshot_thumbnail,
            sender=models.Screenshot,
            dispatch_uid=
            'waldur_mastermind.marketplace.create_screenshot_thumbnail',
        )

        signals.post_save.connect(
            handlers.log_order_events,
            sender=models.Order,
            dispatch_uid='waldur_mastermind.marketplace.log_order_events',
        )

        signals.post_save.connect(
            handlers.log_order_item_events,
            sender=models.OrderItem,
            dispatch_uid='waldur_mastermind.marketplace.log_order_item_events',
        )

        signals.post_save.connect(
            handlers.log_resource_events,
            sender=models.Resource,
            dispatch_uid='waldur_mastermind.marketplace.log_resource_events',
        )

        signals.post_save.connect(
            handlers.reject_order,
            sender=models.Order,
            dispatch_uid='waldur_mastermind.marketplace.reject_order',
        )

        signals.post_save.connect(
            handlers.complete_order_when_all_items_are_done,
            sender=models.OrderItem,
            dispatch_uid=
            'waldur_mastermind.marketplace.complete_order_when_all_items_are_done',
        )

        signals.post_save.connect(
            handlers.update_category_quota_when_offering_is_created,
            sender=models.Offering,
            dispatch_uid=
            'waldur_mastermind.marketplace.update_category_quota_when_offering_is_created',
        )

        signals.post_delete.connect(
            handlers.update_category_quota_when_offering_is_deleted,
            sender=models.Offering,
            dispatch_uid=
            'waldur_mastermind.marketplace.update_category_quota_when_offering_is_deleted',
        )

        quota_signals.recalculate_quotas.connect(
            handlers.update_category_offerings_count,
            dispatch_uid=
            'waldur_mastermind.marketplace.update_category_offerings_count',
        )

        signals.post_save.connect(
            handlers.update_aggregate_resources_count_when_resource_is_updated,
            sender=models.Resource,
            dispatch_uid='waldur_mastermind.marketplace.'
            'update_aggregate_resources_count_when_resource_is_updated',
        )

        quota_signals.recalculate_quotas.connect(
            handlers.update_aggregate_resources_count,
            dispatch_uid=
            'waldur_mastermind.marketplace.update_aggregate_resources_count',
        )

        signals.post_save.connect(
            handlers.close_resource_plan_period_when_resource_is_terminated,
            sender=models.Resource,
            dispatch_uid='waldur_mastermind.marketplace.'
            'close_resource_plan_period_when_resource_is_terminated',
        )

        marketplace_signals.limit_update_succeeded.connect(
            handlers.limit_update_succeeded,
            sender=models.Resource,
            dispatch_uid='waldur_mastermind.marketplace.limit_update_succeeded',
        )

        marketplace_signals.limit_update_failed.connect(
            handlers.limit_update_failed,
            sender=models.Resource,
            dispatch_uid='waldur_mastermind.marketplace.limit_update_failed',
        )

        for resource_serializer in SupportedServices.get_resource_serializers(
        ):
            core_signals.pre_serializer_fields.connect(
                sender=resource_serializer,
                receiver=utils.add_marketplace_offering,
            )

        signals.post_save.connect(
            handlers.add_component_usage,
            sender=models.ComponentUsage,
            dispatch_uid='waldur_mastermind.marketplace.add_component_usage',
        )

        manager.register(
            offering_type='Marketplace.Basic',
            create_resource_processor=processors.BasicCreateResourceProcessor,
            update_resource_processor=processors.BasicUpdateResourceProcessor,
            delete_resource_processor=processors.BasicDeleteResourceProcessor,
        )
예제 #29
0
 def filter(self, qs, value):
     value = SupportedServices.get_filter_mapping().get(value)
     return super(ServiceTypeFilter, self).filter(qs, value)
예제 #30
0
 def test_get_service_resources(self):
     self.assertEqual([TestNewInstance],
                      SupportedServices.get_service_resources(TestService))