From 3b9d389cbbffb91b10826e63cabbcab27faa710a Mon Sep 17 00:00:00 2001 From: Varun Lodaya Date: Tue, 11 Aug 2015 10:27:58 -0700 Subject: [PATCH] Allow custom configs with LBaaS Added key_value pair as a list of dict. Modified the behavior of pool-update, only support bulk-update for kvps. Incorporated Prakash's comments. Closes Bug: #1475393 Change-Id: Ib7381b30eba3fffd03e9a11e57510b04653e4ac3 Allow custom configs with LBaaS This fix checks if custom_attributes is not specified or not in the create config. If not specified, it skips Closes Bug: #1475393 Change-Id: I55d524586fb906e801922af137309bfcdedf9a89 --- .../extensions/loadbalancer.py | 56 +++++++++++++++++++ .../loadbalancer/loadbalancer_pool.py | 43 ++++++++++++-- .../opencontrail/loadbalancer/plugin.py | 2 +- 3 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 neutron_plugin_contrail/extensions/loadbalancer.py diff --git a/neutron_plugin_contrail/extensions/loadbalancer.py b/neutron_plugin_contrail/extensions/loadbalancer.py new file mode 100644 index 0000000..474da8b --- /dev/null +++ b/neutron_plugin_contrail/extensions/loadbalancer.py @@ -0,0 +1,56 @@ +from neutron.api.v2 import attributes as attr +from neutron.api import extensions + +def _validate_custom_attributes(data, valid_values=None): + if not isinstance(data, list): + msg = _("Invalid data format for custom_attributes: '%s'") % data + return msg + +def convert_none_to_empty_list(value): + return [] if value is None else value + +attr.validators['type:customattributes'] = _validate_custom_attributes + +# Extended_Attribute MAP +EXTENDED_ATTRIBUTES_2_0 = { + 'pools': { + 'custom_attributes': {'allow_post': True, 'allow_put': True, + 'convert_to': convert_none_to_empty_list, + 'default': attr.ATTR_NOT_SPECIFIED, + 'validate': {'type:customattributes': None}, + 'is_visible': True}, + } +} + +class Loadbalancer(object): + + @classmethod + def get_name(cls): + return "Loadbalancer as a Service" + + + @classmethod + def get_alias(cls): + return "extra_lbaas_opts" + + @classmethod + def get_description(cls): + return "Custom LBaaS attributes" + + @classmethod + def get_namespace(cls): + return "http://docs.openstack.org/TODO" + + @classmethod + def get_updated(cls): + return "2015-07-17T15:00:00-00:00" + + @classmethod + def get_extended_resources(self, version): + """Returns Ext Resources""" + if version == "2.0": + return EXTENDED_ATTRIBUTES_2_0 + else: + return {} + +#end class Loadbalancer diff --git a/neutron_plugin_contrail/plugins/opencontrail/loadbalancer/loadbalancer_pool.py b/neutron_plugin_contrail/plugins/opencontrail/loadbalancer/loadbalancer_pool.py index bd320e4..d6d77ad 100644 --- a/neutron_plugin_contrail/plugins/opencontrail/loadbalancer/loadbalancer_pool.py +++ b/neutron_plugin_contrail/plugins/opencontrail/loadbalancer/loadbalancer_pool.py @@ -6,12 +6,12 @@ from neutron.extensions import loadbalancer +from neutron.api.v2 import attributes as attr from neutron.plugins.common import constants from neutron.services import provider_configuration as pconf from neutron.openstack.common import uuidutils -from vnc_api.vnc_api import IdPermsType, NoIdError, HttpError -from vnc_api.vnc_api import LoadbalancerPool, LoadbalancerPoolType +from vnc_api.vnc_api import * from resource_manager import ResourceManager from resource_manager import LoadbalancerMethodInvalid @@ -36,6 +36,16 @@ def make_properties(self, pool): setattr(props, key, pool[mapping]) return props + def create_update_custom_attributes(self, custom_attributes, kvps): + kvp_array = [] + for custom_attribute in custom_attributes or []: + for key,value in custom_attribute.iteritems(): + kvp = KeyValuePair(key, value) + kvp_array.append(kvp) + + kvps.set_key_value_pair(kvp_array) + return True + def make_dict(self, pool, fields=None): res = { 'id': pool.uuid, @@ -51,6 +61,13 @@ def make_dict(self, pool, fields=None): if value is not None: res[mapping] = value + custom_attributes = [] + kvps = pool.get_loadbalancer_pool_custom_attributes() + if kvps: + custom_attributes = [{kvp.get_key(): kvp.get_value()} for kvp in kvps.get_key_value_pair() or []] + + res['custom_attributes'] = [custom_attributes] + res['provider'] = pool.get_loadbalancer_pool_provider() # vip_id @@ -151,12 +168,30 @@ def create(self, context, pool): pool.set_service_appliance_set(sas_obj) + # Custom attributes + if p['custom_attributes'] != attr.ATTR_NOT_SPECIFIED: + custom_attributes = KeyValuePairs() + self.create_update_custom_attributes(p['custom_attributes'], custom_attributes) + pool.set_loadbalancer_pool_custom_attributes(custom_attributes) + self._api.loadbalancer_pool_create(pool) return self.make_dict(pool) def update_properties(self, pool_db, id, p): props = pool_db.get_loadbalancer_pool_properties() + change = False if self.update_properties_subr(props, p): pool_db.set_loadbalancer_pool_properties(props) - return True - return False + change = True + + if 'custom_attributes' in p: + custom_attributes = pool_db.get_loadbalancer_pool_custom_attributes() + # Make sure to initialize custom_attributes + if not custom_attributes: + custom_attributes = KeyValuePairs() + + if self.create_update_custom_attributes(p['custom_attributes'], custom_attributes): + pool_db.set_loadbalancer_pool_custom_attributes(custom_attributes) + change = True + + return change diff --git a/neutron_plugin_contrail/plugins/opencontrail/loadbalancer/plugin.py b/neutron_plugin_contrail/plugins/opencontrail/loadbalancer/plugin.py index feb1518..07a1dea 100644 --- a/neutron_plugin_contrail/plugins/opencontrail/loadbalancer/plugin.py +++ b/neutron_plugin_contrail/plugins/opencontrail/loadbalancer/plugin.py @@ -4,7 +4,7 @@ from loadbalancer_db import LoadBalancerPluginDb class LoadBalancerPlugin(LoadBalancerPluginDb): - supported_extension_aliases = ["lbaas"] + supported_extension_aliases = ["lbaas", "extra_lbaas_opts"] def __init__(self): super(LoadBalancerPlugin, self).__init__()