Beispiel #1
0
    def calculate_usage_cost(self, usages):
        from model import Service, Category, ServicePrice
        from task.notifications import notify_managers_about_new_service_in_tariff

        total_cost = Decimal()
        tariff = self.tariff
        if not tariff:
            raise Exception("Tariff is not set for customer %s" % self)

        services = tariff.services_as_dict(lower=True)
        for usage in usages:
            db.session.add(usage)
            service_id = usage.service_id.lower() if isinstance(usage.service_id, str) else str(usage.service_id)
            service_price = services.get(service_id)
            service = Service.get_by_id(service_id)

            usage.tariff_id = tariff.tariff_id
            usage.customer_mode = self.customer_mode

            if service is None:
                logbook.error("Not found declaration service {} during calculate usage for {}",
                              usage.service_id, self)
                continue

            usage_volume = service.calculate_volume_usage(usage)
            usage.usage_volume = usage_volume

            if service_price is None:
                if service.category_id == Category.VM:
                    if service.deleted:
                        logbook.error("Service {} not found in {} for {}. But this service is archived",
                                      service_id, tariff, self)
                    else:
                        service_price = ServicePrice(service_id=service_id, price=Decimal(0), need_changing=True)
                        self.tariff.services.append(service_price)
                        services = tariff.services_as_dict(lower=True)
                        flavor_name = Service.get_by_id(service_id).flavor.flavor_id
                        notify_managers_about_new_service_in_tariff.delay(self.customer_id, flavor_name)
                else:
                    logbook.warning("Service {} not found in {} for {}. Allowed services: {}",
                                    service_id, tariff, self, services.keys())

            if service_price:
                usage_cost = usage_volume * service_price.price / service.hours
            else:
                usage_cost = Decimal(0)
            total_cost += usage_cost
            usage.cost = usage_cost

        logbook.info("Found {} usages for customer {}. Total cost of used resources is: {}",
                     len(usages), self, total_cost)

        return total_cost
Beispiel #2
0
 def get_service(self, service_id):
     service = self.services.get(service_id)
     if not service:
         service = Service.get_by_id(service_id)
         if not service:
             raise ValueError("Service %s not found" % service_id)
     return service
Beispiel #3
0
    def test_for_nonexistent_flavor(self):
        """
        Tests that transformer doesn't stop when flavor.name isn't in database and creates fake entry in DB for that
        flavor.
        """
        state = [
            {'timestamp': testdata.t0, 'counter_volume': states['active'],
                'metadata': {'flavor.name': testdata.flavor}},
            {'timestamp': testdata.t0_30, 'counter_volume': states['active'],
                'metadata': {'flavor.name': testdata.fake_flavor}},
            {'timestamp': testdata.t1, 'counter_volume': states['active'],
                'metadata': {'flavor.name': testdata.fake_flavor}}
        ]

        with mock.patch('os_interfaces.openstack_wrapper.openstack.get_nova_flavor',
                        mock.MagicMock(side_effect=self.create_flavor_mock)):
            result = self._run_transform(state)

            result.sort(key=attrgetter("service_id"))

            flavor = Service.get_by_id(result[1].service_id).flavor

            self.assertEqual(flavor.flavor_id, testdata.fake_flavor)
            self.assertEqual(openstack.get_nova_flavor.call_count, 1)
            self.assertEqual(openstack.create_flavor.call_count, 10)
            self.assertEqual(result[1].end - result[1].start, datetime.timedelta(minutes=30, seconds=-1))
Beispiel #4
0
    def test_create_flavor(self):
        service_id = self.admin_client.service.create_vm(**self.new_flavor_info)['service_id']

        with self.expect_error(errors.ServiceAlreadyExisted):
            self.admin_client.service.create_vm(**self.new_flavor_info)

        self.new_flavor_info['localized_name'] = '{"ru": "Флавор Test Flavor", "en": "Flavor Test Flavor"}'

        with self.expect_error(errors.FlavorAlreadyExists):
            self.admin_client.service.create_vm(**self.new_flavor_info)

        self.assertEqual(openstack.create_flavor.call_count, 10)

        service = Service.get_by_id(service_id)

        service.mark_immutable()
        self.assertEqual(openstack.create_flavor.call_count, 11)

        self.new_flavor_info['localized_name'] = '{"ru": "Флавор TestFlavor1", "en": "Flavor TestFlavor1"}'
        self.new_flavor_info['flavor_id'] = "TestFlavor1"
        self.new_flavor_info.pop('network')

        service_id = self.admin_client.service.create_vm(**self.new_flavor_info)['service_id']
        service = Service.get_by_id(service_id)

        self.assertIsNone(service.flavor.network)

        with mock.patch('os_interfaces.openstack_wrapper.openstack.get_nova_flavor',
                        mock.MagicMock(side_effect=self.create_flavor_mock)):
            self.new_flavor_info['localized_name'] = '{"ru": "Флавор TestFlavor2", "en": "Flavor TestFlavor2"}'
            self.new_flavor_info['flavor_id'] = "TestFlavor2"

            with self.expect_error(errors.Conflict):
                service_id = self.admin_client.service.create_vm(**self.new_flavor_info)['service_id']

            self.new_flavor_info['disk'] = 30

            service_id = self.admin_client.service.create_vm(**self.new_flavor_info)['service_id']
            service = Service.get_by_id(service_id)

            self.assertFalse(service.mutable)
Beispiel #5
0
    def __call__(self, value):
        service_price_list = super().__call__(value)
        for service_price in service_price_list:
            service_id = service_price.get("service_id")
            service = Service.get_by_id(service_id)
            if not service:
                raise errors.ServiceNotFound()
            if service.deleted:
                raise errors.RemovedServiceInTariff()
            if service.mutable:
                raise errors.OnlyImmutableService()

        return service_price_list
Beispiel #6
0
    def __init__(self, service_id, customer, tariff):
        self.currency = tariff.currency
        self.service = Service.get_by_id(service_id)
        if self.service:
            self.name = self.service.get_localized_name(customer.locale_language())
            self.category = self.service.category.get_localized_name(customer.locale_language())
            self.measure = self.service.measure.get_localized_name(customer.locale_language())
            self.hours = self.service.hours
        else:
            self.name = str(service_id)
            self.category = ""
            self.measure = ""
            self.hours = 1

        self.price = tariff.service_price(service_id)
        self.service_id = service_id
        self.resources = {}
Beispiel #7
0
    def __init__(self, service_usage, customer, tariff):
        self.currency = tariff.currency
        service_id, tariff_id, total_cost, total_usage_volume = service_usage
        service = Service.get_by_id(service_id)
        if service:
            self.name = service.get_localized_name(customer.locale_language())
            self.category = service.category.get_localized_name(customer.locale_language())
            self.measure = service.measure.get_localized_name(customer.locale_language())
            self.hours = service.hours
        else:
            self.name = str(service_id)
            self.category = ""
            self.measure = ""
            self.hours = 1

        self.total_cost = total_cost or Decimal(0)
        self.total_usage_volume = total_usage_volume or 0
        self.price = tariff.service_price(service_id) or Decimal(0)
        self.service_id = service_id
Beispiel #8
0
    def get_service(self, service_id):
        """
        Return service description

        :param Id service_id: Service Id

        :return dict service_info: Dict with service parameters

        **Example**::

            {
              "service_info": {
                "service_id": "storage.volume",
                "measure": {
                  "measure_type": "time_quant",
                  "measure_id": "gigabyte*month",
                  "localized_name": {
                    "ru": "Гб*месяц",
                    "en": "Gb*month"
                  }
                },
                "category": {
                  "localized_name": {
                    "ru": "Хранение данных",
                    "en": "Storage"
                  },
                  "category_id": "storage"
                },
                "localized_name": {
                  "ru": "Диск",
                  "en": "Volume"
                }
              }
            }

        """

        service = Service.get_by_id(service_id)
        if not service:
            raise errors.ServiceNotFound()

        return {"service_info": display(service)}
Beispiel #9
0
    def get_service(self, service_id):
        """
        Return service description

        :param Id service_id: Service Id

        :return dict service_info: Dict with service parameters

        **Example**::

            {
              "service_info": {
                "service_id": "storage.volume",
                "measure": {
                  "measure_type": "time_quant",
                  "measure_id": "gigabyte*month",
                  "localized_name": {
                    "ru": "Гб*месяц",
                    "en": "Gb*month"
                  }
                },
                "category": {
                  "localized_name": {
                    "ru": "Хранение данных",
                    "en": "Storage"
                  },
                  "category_id": "storage"
                },
                "localized_name": {
                  "ru": "Диск",
                  "en": "Volume"
                }
              }
            }

        """

        service = Service.get_by_id(service_id)
        if not service:
            raise errors.ServiceNotFound()

        return {"service_info": display(service)}
Beispiel #10
0
    def __init__(self, service_id, customer, tariff):
        self.currency = tariff.currency
        self.service = Service.get_by_id(service_id)
        if self.service:
            self.name = self.service.get_localized_name(
                customer.locale_language())
            self.category = self.service.category.get_localized_name(
                customer.locale_language())
            self.measure = self.service.measure.get_localized_name(
                customer.locale_language())
            self.hours = self.service.hours
        else:
            self.name = str(service_id)
            self.category = ""
            self.measure = ""
            self.hours = 1

        self.price = tariff.service_price(service_id)
        self.service_id = service_id
        self.resources = {}
Beispiel #11
0
    def __init__(self, service_usage, customer, tariff):
        self.currency = tariff.currency
        service_id, tariff_id, total_cost, total_usage_volume = service_usage
        service = Service.get_by_id(service_id)
        if service:
            self.name = service.get_localized_name(customer.locale_language())
            self.category = service.category.get_localized_name(
                customer.locale_language())
            self.measure = service.measure.get_localized_name(
                customer.locale_language())
            self.hours = service.hours
        else:
            self.name = str(service_id)
            self.category = ""
            self.measure = ""
            self.hours = 1

        self.total_cost = total_cost or Decimal(0)
        self.total_usage_volume = total_usage_volume or 0
        self.price = tariff.service_price(service_id) or Decimal(0)
        self.service_id = service_id
Beispiel #12
0
    def test_for_nonexistent_flavor(self):
        """
        Tests that transformer doesn't stop when flavor.name isn't in database and creates fake entry in DB for that
        flavor.
        """
        state = [{
            'timestamp': testdata.t0,
            'counter_volume': states['active'],
            'metadata': {
                'flavor.name': testdata.flavor
            }
        }, {
            'timestamp': testdata.t0_30,
            'counter_volume': states['active'],
            'metadata': {
                'flavor.name': testdata.fake_flavor
            }
        }, {
            'timestamp': testdata.t1,
            'counter_volume': states['active'],
            'metadata': {
                'flavor.name': testdata.fake_flavor
            }
        }]

        with mock.patch(
                'os_interfaces.openstack_wrapper.openstack.get_nova_flavor',
                mock.MagicMock(side_effect=self.create_flavor_mock)):
            result = self._run_transform(state)

            result.sort(key=attrgetter("service_id"))

            flavor = Service.get_by_id(result[1].service_id).flavor

            self.assertEqual(flavor.flavor_id, testdata.fake_flavor)
            self.assertEqual(openstack.get_nova_flavor.call_count, 1)
            self.assertEqual(openstack.create_flavor.call_count, 10)
            self.assertEqual(result[1].end - result[1].start,
                             datetime.timedelta(minutes=30, seconds=-1))
Beispiel #13
0
 def service(self):
     # we can't do it by relationship, because some services
     # can be fixed services which are configured from config file
     return Service.get_by_id(self.service_id)
Beispiel #14
0
    def display(self, short=True):
        service = Service.get_by_id(self.service_id)

        return {"service": service.display(short), "price": decimal_to_string(self.price),
                "need_changing": self.need_changing}