Fix an issue with product naming and swift policy names
Change-Id: Ib05c9c0302189c3d28ee10a6b789b8588d5a9d8c
This commit is contained in:
parent
1d0a81a1dd
commit
bdcb202736
@ -90,12 +90,6 @@ ODOO_OPTS = [
|
|||||||
help='Region name mappings between Keystone and Odoo. For '
|
help='Region name mappings between Keystone and Odoo. For '
|
||||||
'example, '
|
'example, '
|
||||||
'region_mapping=region1:RegionOne,region2:RegionTwo'),
|
'region_mapping=region1:RegionOne,region2:RegionTwo'),
|
||||||
cfg.StrOpt('object_storage_product_name',
|
|
||||||
default='NZ.o1.standard',
|
|
||||||
help='Product name in Odoo for object storage.'),
|
|
||||||
cfg.StrOpt('object_storage_service_name',
|
|
||||||
default='o1.standard',
|
|
||||||
help='Service name for object storage.'),
|
|
||||||
cfg.ListOpt('extra_product_category_list',
|
cfg.ListOpt('extra_product_category_list',
|
||||||
default=[],
|
default=[],
|
||||||
help='Additional product categories which should be easily '
|
help='Additional product categories which should be easily '
|
||||||
|
@ -157,41 +157,59 @@ class OdooDriver(driver.BaseDriver):
|
|||||||
|
|
||||||
prices[actual_region][category.lower()].append(
|
prices[actual_region][category.lower()].append(
|
||||||
{'name': name,
|
{'name': name,
|
||||||
|
'full_name': product['name_template'],
|
||||||
'rate': rate,
|
'rate': rate,
|
||||||
'unit': unit,
|
'unit': unit,
|
||||||
'description': desc}
|
'description': desc}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Handle object storage product that does not belong to any
|
# Handle object storage products
|
||||||
# region in odoo.
|
c = self.category.search([('name', '=', OBJECTSTORAGE_CATEGORY)])
|
||||||
obj_p_name = self.conf.odoo.object_storage_product_name
|
product_ids = self.product.search([('categ_id', 'in', c),
|
||||||
obj_s_name = self.conf.odoo.object_storage_service_name
|
|
||||||
|
|
||||||
obj_pids = self.product.search(
|
|
||||||
[('name_template', '=', obj_p_name),
|
|
||||||
('sale_ok', '=', True),
|
('sale_ok', '=', True),
|
||||||
('active', '=', True)]
|
('active', '=', True)])
|
||||||
)
|
products = self.product.read(product_ids, fields=product_fields)
|
||||||
|
|
||||||
if len(obj_pids) > 0:
|
for product in products:
|
||||||
obj_p = self.product.read(obj_pids[0],
|
product_region = None
|
||||||
fields=["lst_price", "default_code",
|
for region in odoo_regions:
|
||||||
"description"])
|
if region.upper() in product['name_template']:
|
||||||
self.product_category_mapping[obj_pids[0]] = \
|
product_region = region
|
||||||
OBJECTSTORAGE_CATEGORY
|
|
||||||
for region in regions:
|
category = product['categ_id'][1].split('/')[-1].strip()
|
||||||
# Ensure returned region name is same with what user see
|
|
||||||
# from Keystone.
|
name = product['name_template'].lower()
|
||||||
|
|
||||||
|
rate = round(product['lst_price'], constants.RATE_DIGITS)
|
||||||
|
# NOTE(flwang): default_code is Internal Reference on
|
||||||
|
# Odoo GUI
|
||||||
|
unit = product['default_code']
|
||||||
|
desc = product['description']
|
||||||
|
self.product_unit_mapping[product['id']] = unit
|
||||||
|
|
||||||
|
product_dict = {
|
||||||
|
'name': name,
|
||||||
|
'full_name': product['name_template'],
|
||||||
|
'rate': rate,
|
||||||
|
'unit': unit,
|
||||||
|
'description': desc
|
||||||
|
}
|
||||||
|
|
||||||
|
if product_region:
|
||||||
|
# add it to just the one region
|
||||||
|
actual_region = self.reverse_region_mapping.get(
|
||||||
|
product_region, product_region)
|
||||||
|
|
||||||
|
prices[actual_region][category.lower()].append(
|
||||||
|
product_dict)
|
||||||
|
else:
|
||||||
|
# add it to all regions
|
||||||
|
for region in odoo_regions:
|
||||||
actual_region = self.reverse_region_mapping.get(
|
actual_region = self.reverse_region_mapping.get(
|
||||||
region, region)
|
region, region)
|
||||||
|
|
||||||
prices[actual_region]['object storage'].append(
|
prices[actual_region][category.lower()].append(
|
||||||
{'name': obj_s_name,
|
product_dict)
|
||||||
'rate': round(obj_p["lst_price"],
|
|
||||||
constants.RATE_DIGITS),
|
|
||||||
'unit': obj_p["default_code"],
|
|
||||||
'description': obj_p["description"]}
|
|
||||||
)
|
|
||||||
except odoorpc.error.Error as e:
|
except odoorpc.error.Error as e:
|
||||||
LOG.exception(e)
|
LOG.exception(e)
|
||||||
return {}
|
return {}
|
||||||
@ -392,24 +410,50 @@ class OdooDriver(driver.BaseDriver):
|
|||||||
"""Get service price information from price definitions."""
|
"""Get service price information from price definitions."""
|
||||||
price = {'service_name': service_name}
|
price = {'service_name': service_name}
|
||||||
|
|
||||||
|
# NOTE(adriant): We do this to handle the object storage policy
|
||||||
|
# name to product translation
|
||||||
|
formatted_name = service_name.lower().replace("--", ".")
|
||||||
|
|
||||||
if service_type in products:
|
if service_type in products:
|
||||||
for s in products[service_type]:
|
for s in products[service_type]:
|
||||||
if s['name'] == service_name:
|
if s['name'] == formatted_name:
|
||||||
price.update({'rate': s['rate'], 'unit': s['unit']})
|
price.update({
|
||||||
|
'rate': s['rate'], 'unit': s['unit'],
|
||||||
|
'product_name': s['full_name']})
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
found = False
|
found = False
|
||||||
for category, services in products.items():
|
for category, services in products.items():
|
||||||
for s in services:
|
for s in services:
|
||||||
if s['name'] == service_name:
|
if s['name'] == formatted_name:
|
||||||
price.update({'rate': s['rate'], 'unit': s['unit']})
|
price.update({
|
||||||
|
'rate': s['rate'], 'unit': s['unit'],
|
||||||
|
'product_name': s['full_name']})
|
||||||
|
found = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if not found:
|
||||||
|
for category, services in products.items():
|
||||||
|
for s in services:
|
||||||
|
# NOTE(adriant): this will find a partial match like:
|
||||||
|
# 'o1.standard' in 'NZ.o1.standard'
|
||||||
|
if formatted_name in s['name']:
|
||||||
|
price.update({
|
||||||
|
'rate': s['rate'], 'unit': s['unit'],
|
||||||
|
'product_name': s['full_name']})
|
||||||
found = True
|
found = True
|
||||||
break
|
break
|
||||||
|
|
||||||
if not found:
|
if not found:
|
||||||
raise exceptions.NotFoundException(
|
raise exceptions.NotFoundException(
|
||||||
'Price not found, service name: %s, service type: %s' %
|
'Price not found, service name: %s, service type: %s' %
|
||||||
(service_name, service_type)
|
(formatted_name, service_type)
|
||||||
|
)
|
||||||
|
|
||||||
|
if 'unit' in price and not price['unit']:
|
||||||
|
raise exceptions.ERPException(
|
||||||
|
"Product: %s is missing 'unit' definition." %
|
||||||
|
formatted_name
|
||||||
)
|
)
|
||||||
|
|
||||||
return price
|
return price
|
||||||
@ -455,8 +499,6 @@ class OdooDriver(driver.BaseDriver):
|
|||||||
price_mapping = {}
|
price_mapping = {}
|
||||||
cost_details = {}
|
cost_details = {}
|
||||||
|
|
||||||
odoo_region = self.region_mapping.get(region, region).upper()
|
|
||||||
|
|
||||||
resources_info = {}
|
resources_info = {}
|
||||||
for row in resources:
|
for row in resources:
|
||||||
info = json.loads(row.info)
|
info = json.loads(row.info)
|
||||||
@ -517,14 +559,12 @@ class OdooDriver(driver.BaseDriver):
|
|||||||
total_cost += cost
|
total_cost += cost
|
||||||
|
|
||||||
if detailed:
|
if detailed:
|
||||||
odoo_service_name = "%s.%s" % (odoo_region, service_name)
|
|
||||||
|
|
||||||
cost_details[service_type]['total_cost'] = round(
|
cost_details[service_type]['total_cost'] = round(
|
||||||
(cost_details[service_type]['total_cost'] + cost),
|
(cost_details[service_type]['total_cost'] + cost),
|
||||||
constants.PRICE_DIGITS
|
constants.PRICE_DIGITS
|
||||||
)
|
)
|
||||||
cost_details[service_type]['breakdown'][
|
cost_details[service_type]['breakdown'][
|
||||||
odoo_service_name
|
price_spec['product_name']
|
||||||
].append(
|
].append(
|
||||||
{
|
{
|
||||||
"resource_name": resource.get('name', ''),
|
"resource_name": resource.get('name', ''),
|
||||||
|
@ -58,7 +58,7 @@ class TestOdooDriver(base.DistilTestCase):
|
|||||||
def test_get_products(self, mock_odoo):
|
def test_get_products(self, mock_odoo):
|
||||||
odoodriver = odoo.OdooDriver(self.conf)
|
odoodriver = odoo.OdooDriver(self.conf)
|
||||||
odoodriver.product.search.return_value = []
|
odoodriver.product.search.return_value = []
|
||||||
odoodriver.product.read.return_value = PRODUCTS
|
odoodriver.product.read.side_effect = [PRODUCTS, []]
|
||||||
|
|
||||||
products = odoodriver.get_products(regions=['nz_1'])
|
products = odoodriver.get_products(regions=['nz_1'])
|
||||||
|
|
||||||
@ -68,14 +68,17 @@ class TestOdooDriver(base.DistilTestCase):
|
|||||||
'block storage': [{'description': 'Block storage',
|
'block storage': [{'description': 'Block storage',
|
||||||
'rate': 0.00035,
|
'rate': 0.00035,
|
||||||
'name': 'b1.volume',
|
'name': 'b1.volume',
|
||||||
|
'full_name': 'NZ-1.b1.volume',
|
||||||
'unit': 'hour'}],
|
'unit': 'hour'}],
|
||||||
'compute': [{'description': '1 CPU, 1GB RAM',
|
'compute': [{'description': '1 CPU, 1GB RAM',
|
||||||
'rate': 0.00015,
|
'rate': 0.00015,
|
||||||
'name': 'c1.c1r1',
|
'name': 'c1.c1r1',
|
||||||
|
'full_name': 'NZ-1.c1.c1r1',
|
||||||
'unit': 'hour'}],
|
'unit': 'hour'}],
|
||||||
'network': [{'description': 'Router',
|
'network': [{'description': 'Router',
|
||||||
'rate': 0.00025,
|
'rate': 0.00025,
|
||||||
'name': 'n1.router',
|
'name': 'n1.router',
|
||||||
|
'full_name': 'NZ-1.n1.router',
|
||||||
'unit': 'hour'}]
|
'unit': 'hour'}]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -270,12 +273,14 @@ class TestOdooDriver(base.DistilTestCase):
|
|||||||
'Compute': [
|
'Compute': [
|
||||||
{
|
{
|
||||||
'name': 'c1.c2r16', 'description': 'c1.c2r16',
|
'name': 'c1.c2r16', 'description': 'c1.c2r16',
|
||||||
|
'full_name': 'NZ-1.c1.c2r16',
|
||||||
'rate': 0.01, 'unit': 'hour'
|
'rate': 0.01, 'unit': 'hour'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
'Block Storage': [
|
'Block Storage': [
|
||||||
{
|
{
|
||||||
'name': 'b1.standard', 'description': 'b1.standard',
|
'name': 'b1.standard', 'description': 'b1.standard',
|
||||||
|
'full_name': 'NZ-1.b1.standard',
|
||||||
'rate': 0.02, 'unit': 'gigabyte'
|
'rate': 0.02, 'unit': 'gigabyte'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -326,12 +331,14 @@ class TestOdooDriver(base.DistilTestCase):
|
|||||||
'Compute': [
|
'Compute': [
|
||||||
{
|
{
|
||||||
'name': 'c1.c2r16', 'description': 'c1.c2r16',
|
'name': 'c1.c2r16', 'description': 'c1.c2r16',
|
||||||
|
'full_name': 'NZ-1.c1.c2r16',
|
||||||
'rate': 0.01, 'unit': 'hour'
|
'rate': 0.01, 'unit': 'hour'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
'Block Storage': [
|
'Block Storage': [
|
||||||
{
|
{
|
||||||
'name': 'b1.standard', 'description': 'b1.standard',
|
'name': 'b1.standard', 'description': 'b1.standard',
|
||||||
|
'full_name': 'NZ-1.b1.standard',
|
||||||
'rate': 0.02, 'unit': 'gigabyte'
|
'rate': 0.02, 'unit': 'gigabyte'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -417,19 +424,23 @@ class TestOdooDriver(base.DistilTestCase):
|
|||||||
'Compute': [
|
'Compute': [
|
||||||
{
|
{
|
||||||
'name': 'c1.c2r16', 'description': 'c1.c2r16',
|
'name': 'c1.c2r16', 'description': 'c1.c2r16',
|
||||||
|
'full_name': 'NZ-1.c1.c2r16',
|
||||||
'rate': 0.01, 'unit': 'hour'
|
'rate': 0.01, 'unit': 'hour'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'c1.c4r32', 'description': 'c1.c4r32',
|
'name': 'c1.c4r32', 'description': 'c1.c4r32',
|
||||||
|
'full_name': 'NZ-1.c1.c4r32',
|
||||||
'rate': 0.04, 'unit': 'hour'
|
'rate': 0.04, 'unit': 'hour'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'c1.c2r16-windows',
|
'name': 'c1.c2r16-windows',
|
||||||
|
'full_name': 'NZ-1.c1.c2r16-windows',
|
||||||
'description': 'c1.c2r16-windows',
|
'description': 'c1.c2r16-windows',
|
||||||
'rate': 0.02, 'unit': 'hour'
|
'rate': 0.02, 'unit': 'hour'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'c1.c4r32-sql-server-standard-windows',
|
'name': 'c1.c4r32-sql-server-standard-windows',
|
||||||
|
'full_name': 'NZ-1.c1.c4r32-sql-server-standard-windows',
|
||||||
'description': 'c1.c4r32-sql-server-standard-windows',
|
'description': 'c1.c4r32-sql-server-standard-windows',
|
||||||
'rate': 0.04, 'unit': 'hour'
|
'rate': 0.04, 'unit': 'hour'
|
||||||
}
|
}
|
||||||
@ -437,6 +448,7 @@ class TestOdooDriver(base.DistilTestCase):
|
|||||||
'Block Storage': [
|
'Block Storage': [
|
||||||
{
|
{
|
||||||
'name': 'b1.standard', 'description': 'b1.standard',
|
'name': 'b1.standard', 'description': 'b1.standard',
|
||||||
|
'full_name': 'NZ-1.b1.standard',
|
||||||
'rate': 0.02, 'unit': 'gigabyte'
|
'rate': 0.02, 'unit': 'gigabyte'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user