Merge "Implement mechanism for plugin node attributes"
This commit is contained in:
commit
1a8eddf49e
@ -292,3 +292,20 @@ class NodeAttributesHandler(BaseHandler):
|
||||
objects.Node.update_attributes(node, data)
|
||||
|
||||
return objects.Node.get_attributes(node)
|
||||
|
||||
|
||||
class NodeAttributesDefaultsHandler(BaseHandler):
|
||||
"""Node default attributes handler"""
|
||||
|
||||
@handle_errors
|
||||
@validate
|
||||
@serialize
|
||||
def GET(self, node_id):
|
||||
""":returns: JSONized Node default attributes.
|
||||
|
||||
:http: * 200 (OK)
|
||||
* 404 (node not found in db)
|
||||
"""
|
||||
node = self.get_object_or_404(objects.Node, node_id)
|
||||
|
||||
return objects.Node.get_default_attributes(node)
|
||||
|
@ -64,10 +64,12 @@ from nailgun.api.v1.handlers.logs import LogPackageHandler
|
||||
from nailgun.api.v1.handlers.logs import LogSourceByNodeCollectionHandler
|
||||
from nailgun.api.v1.handlers.logs import LogSourceCollectionHandler
|
||||
from nailgun.api.v1.handlers.logs import SnapshotDownloadHandler
|
||||
|
||||
from nailgun.api.v1.handlers.node_group import NodeGroupCollectionHandler
|
||||
from nailgun.api.v1.handlers.node_group import NodeGroupHandler
|
||||
|
||||
from nailgun.api.v1.handlers.node import NodeAgentHandler
|
||||
from nailgun.api.v1.handlers.node import NodeAttributesDefaultsHandler
|
||||
from nailgun.api.v1.handlers.node import NodeAttributesHandler
|
||||
from nailgun.api.v1.handlers.node import NodeCollectionHandler
|
||||
from nailgun.api.v1.handlers.node import NodeHandler
|
||||
@ -79,6 +81,7 @@ from nailgun.api.v1.handlers.plugin import \
|
||||
from nailgun.api.v1.handlers.plugin import PluginDeploymentGraphHandler
|
||||
from nailgun.api.v1.handlers.plugin import PluginHandler
|
||||
from nailgun.api.v1.handlers.plugin import PluginSyncHandler
|
||||
|
||||
from nailgun.api.v1.handlers.plugin_link import PluginLinkCollectionHandler
|
||||
from nailgun.api.v1.handlers.plugin_link import PluginLinkHandler
|
||||
|
||||
@ -117,13 +120,13 @@ from nailgun.api.v1.handlers.tag import TagOwnerHandler
|
||||
|
||||
from nailgun.api.v1.handlers.tasks import TaskCollectionHandler
|
||||
from nailgun.api.v1.handlers.tasks import TaskHandler
|
||||
|
||||
from nailgun.api.v1.handlers.transactions import TransactionClusterSettings
|
||||
from nailgun.api.v1.handlers.transactions import TransactionCollectionHandler
|
||||
from nailgun.api.v1.handlers.transactions import TransactionDeploymentInfo
|
||||
from nailgun.api.v1.handlers.transactions import TransactionHandler
|
||||
from nailgun.api.v1.handlers.transactions import TransactionNetworkSettings
|
||||
|
||||
|
||||
from nailgun.api.v1.handlers.version import VersionHandler
|
||||
|
||||
from nailgun.api.v1.handlers.vms import NodeVMsHandler
|
||||
@ -291,6 +294,8 @@ urls = (
|
||||
NodeHandler,
|
||||
r'/nodes/(?P<node_id>\d+)/attributes/?$',
|
||||
NodeAttributesHandler,
|
||||
r'/nodes/(?P<node_id>\d+)/attributes/defaults/?$',
|
||||
NodeAttributesDefaultsHandler,
|
||||
r'/nodes/allocation/stats/?$',
|
||||
NodesAllocationStatsHandler,
|
||||
r'/nodes/(?P<node_id>\d+)/tags/?$',
|
||||
|
@ -453,7 +453,7 @@ class NodeAttributesValidator(base.BasicAttributesValidator):
|
||||
data = cls.validate_json(data)
|
||||
full_data = utils.dict_merge(objects.Node.get_attributes(node), data)
|
||||
|
||||
models = objects.Cluster.get_restrictions_models(cluster)
|
||||
models = objects.Node.get_restrictions_models(node)
|
||||
|
||||
attrs = cls.validate_attributes(full_data, models=models)
|
||||
|
||||
|
@ -83,6 +83,7 @@ from nailgun.objects.node_group import NodeGroupCollection
|
||||
from nailgun.objects.plugin import Plugin
|
||||
from nailgun.objects.plugin import PluginCollection
|
||||
from nailgun.objects.plugin import ClusterPlugin
|
||||
from nailgun.objects.plugin import NodeClusterPlugin
|
||||
|
||||
from nailgun.objects.plugin_link import PluginLink
|
||||
from nailgun.objects.plugin_link import PluginLinkCollection
|
||||
|
@ -56,6 +56,7 @@ from nailgun.objects import Notification
|
||||
from nailgun.objects import Release
|
||||
from nailgun.objects.serializers.node import NodeSerializer
|
||||
from nailgun.objects import TagCollection
|
||||
from nailgun.plugins.manager import PluginManager
|
||||
from nailgun.policy import cpu_distribution
|
||||
from nailgun.policy import hugepages_distribution
|
||||
from nailgun.settings import settings
|
||||
@ -1248,6 +1249,17 @@ class Node(NailgunObject):
|
||||
hostname = 'node-{0}'.format(node.uuid)
|
||||
return hostname
|
||||
|
||||
@classmethod
|
||||
def get_restrictions_models(cls, instance):
|
||||
"""Return models which are used in restrictions mechanism
|
||||
|
||||
:param instance: nailgun.db.sqlalchemy.models.Node instance
|
||||
:return: dict with models
|
||||
"""
|
||||
models = {'node_attributes': cls.get_attributes(instance)}
|
||||
models.update(Cluster.get_restrictions_models(instance.cluster))
|
||||
return models
|
||||
|
||||
@classmethod
|
||||
def reset_vms_created_state(cls, node):
|
||||
if consts.VIRTUAL_NODE_TYPES.virt not in node.all_roles:
|
||||
@ -1269,6 +1281,7 @@ class Node(NailgunObject):
|
||||
instance.attributes = copy.deepcopy(
|
||||
instance.cluster.release.node_attributes)
|
||||
NodeAttributes.set_default_hugepages(instance)
|
||||
PluginManager.add_plugin_attributes_for_node(instance)
|
||||
|
||||
@classmethod
|
||||
def dpdk_enabled(cls, instance):
|
||||
@ -1286,12 +1299,37 @@ class Node(NailgunObject):
|
||||
|
||||
@classmethod
|
||||
def get_attributes(cls, instance):
|
||||
return copy.deepcopy(instance.attributes)
|
||||
attributes = copy.deepcopy(instance.attributes)
|
||||
attributes.update(PluginManager.get_plugin_node_attributes(instance))
|
||||
return attributes
|
||||
|
||||
@classmethod
|
||||
def update_attributes(cls, instance, attrs):
|
||||
PluginManager.update_plugin_node_attributes(attrs)
|
||||
instance.attributes = utils.dict_merge(instance.attributes, attrs)
|
||||
|
||||
@classmethod
|
||||
def get_default_attributes(cls, instance):
|
||||
"""Get default attributes for Node.
|
||||
|
||||
:param instance: Node instance
|
||||
:type instance: models.Node
|
||||
:returns: dict -- Dict object of Node attributes
|
||||
"""
|
||||
if not instance.cluster_id:
|
||||
logger.warning(
|
||||
u"Attempting to update attributes of node "
|
||||
u"'{0}' which isn't added to any cluster".format(
|
||||
instance.full_name))
|
||||
return {}
|
||||
|
||||
cluster = instance.cluster
|
||||
attributes = copy.deepcopy(instance.cluster.release.node_attributes)
|
||||
attributes.update(
|
||||
PluginManager.get_plugins_node_default_attributes(cluster))
|
||||
|
||||
return attributes
|
||||
|
||||
@classmethod
|
||||
def refresh_dpdk_properties(cls, instance):
|
||||
if not instance.cluster:
|
||||
|
@ -253,12 +253,15 @@ class ClusterPlugin(NailgunObject):
|
||||
plugin_attributes = dict(plugin.attributes_metadata)
|
||||
plugin_attributes.pop('metadata', None)
|
||||
for cluster in cls.get_compatible_clusters(plugin):
|
||||
cls.create({
|
||||
cluster_plugin = cls.create({
|
||||
'cluster_id': cluster.id,
|
||||
'plugin_id': plugin.id,
|
||||
'enabled': False,
|
||||
'attributes': plugin_attributes
|
||||
})
|
||||
NodeClusterPlugin.add_nodes_for_cluster_plugin(cluster_plugin)
|
||||
|
||||
db().flush()
|
||||
|
||||
@classmethod
|
||||
def set_attributes(cls, cluster_id, plugin_id, enabled=None, attrs=None):
|
||||
@ -372,3 +375,105 @@ class ClusterPlugin(NailgunObject):
|
||||
.filter(cls.model.enabled.is_(True))
|
||||
|
||||
return db().query(q.exists()).scalar()
|
||||
|
||||
|
||||
class BasicNodeClusterPlugin(NailgunObject):
|
||||
|
||||
@classmethod
|
||||
def set_attributes(cls, instance_id, attrs=None):
|
||||
"""Update plugin NIC|Bond|Node attributes
|
||||
|
||||
:param instance_id: NIC|Bond|Node instance id
|
||||
:type instance: int
|
||||
:returns: None
|
||||
"""
|
||||
if attrs:
|
||||
db().query(cls.model) \
|
||||
.filter_by(
|
||||
id=instance_id) \
|
||||
.update({'attributes': attrs}, synchronize_session='fetch')
|
||||
|
||||
db().flush()
|
||||
|
||||
|
||||
class NodeClusterPlugin(BasicNodeClusterPlugin):
|
||||
|
||||
model = models.NodeClusterPlugin
|
||||
|
||||
@classmethod
|
||||
def get_all_enabled_attributes_by_node(cls, node):
|
||||
"""Returns node attributes from enabled plugins
|
||||
|
||||
:param node: target node instance
|
||||
:type node: models.Node
|
||||
:returns: object with plugin Node attributes
|
||||
:rtype: dict
|
||||
"""
|
||||
node_attributes = {}
|
||||
node_plugin_attributes_query = db().query(
|
||||
cls.model.id,
|
||||
cls.model.attributes
|
||||
).join(
|
||||
models.ClusterPlugin,
|
||||
models.Plugin
|
||||
).filter(
|
||||
cls.model.node_id == node.id,
|
||||
models.ClusterPlugin.enabled.is_(True)
|
||||
)
|
||||
|
||||
for node_plugin_id, attributes in node_plugin_attributes_query:
|
||||
for section_name, section_attributes in six.iteritems(attributes):
|
||||
# TODO(apopovych): resolve conflicts of same attribute names
|
||||
# for different plugins
|
||||
section_attributes.setdefault('metadata', {}).update({
|
||||
'node_plugin_id': node_plugin_id,
|
||||
'class': 'plugin'
|
||||
})
|
||||
node_attributes[section_name] = section_attributes
|
||||
|
||||
return node_attributes
|
||||
|
||||
@classmethod
|
||||
def add_nodes_for_cluster_plugin(cls, cluster_plugin):
|
||||
"""Populates 'node_cluster_plugins' table with nodes.
|
||||
|
||||
:param cluster_plugin: ClusterPlugin instance
|
||||
:type cluster_plugin: models.ClusterPlugin
|
||||
:returns: None
|
||||
"""
|
||||
node_attributes = dict(
|
||||
cluster_plugin.plugin.node_attributes_metadata)
|
||||
for node in cluster_plugin.cluster.nodes:
|
||||
if node_attributes:
|
||||
cls.create({
|
||||
'cluster_plugin_id': cluster_plugin.id,
|
||||
'node_id': node.id,
|
||||
'attributes': node_attributes
|
||||
})
|
||||
|
||||
db().flush()
|
||||
|
||||
@classmethod
|
||||
def add_cluster_plugins_for_node(cls, node):
|
||||
"""Populates 'node_cluster_plugins' table.
|
||||
|
||||
:param node: target node instance
|
||||
:type node: models.Node
|
||||
"""
|
||||
node_cluster_plugin_ids = set(
|
||||
item.id for item in node.node_cluster_plugins)
|
||||
# TODO(ekosareva): rethink, move it in another place
|
||||
# remove old relations for nodes
|
||||
cls.bulk_delete(node_cluster_plugin_ids)
|
||||
|
||||
for cluster_plugin in node.cluster.cluster_plugins:
|
||||
node_attributes = dict(
|
||||
cluster_plugin.plugin.node_attributes_metadata)
|
||||
if node_attributes:
|
||||
cls.create({
|
||||
'cluster_plugin_id': cluster_plugin.id,
|
||||
'node_id': node.id,
|
||||
'attributes': node_attributes
|
||||
})
|
||||
|
||||
db().flush()
|
||||
|
@ -824,6 +824,21 @@ class DeploymentLCMSerializer(DeploymentHASerializer90):
|
||||
)
|
||||
utils.dict_update(data.setdefault('provision', {}), info)
|
||||
|
||||
@classmethod
|
||||
def serialize_node_for_node_list(cls, node, role):
|
||||
serialized_node = super(
|
||||
DeploymentLCMSerializer,
|
||||
cls).serialize_node_for_node_list(node, role)
|
||||
|
||||
for section_name, section_attributes in six.iteritems(
|
||||
plugins.manager.PluginManager.
|
||||
get_plugin_node_attributes(node)):
|
||||
section_attributes.pop('metadata', None)
|
||||
serialized_node[section_name] = {
|
||||
k: v.get('value') for k, v in six.iteritems(section_attributes)
|
||||
}
|
||||
return serialized_node
|
||||
|
||||
|
||||
def get_serializer_for_cluster(cluster):
|
||||
"""Returns a serializer depends on a given `cluster`.
|
||||
|
@ -28,6 +28,7 @@ from nailgun import consts
|
||||
from nailgun import errors
|
||||
from nailgun.logger import logger
|
||||
from nailgun.objects.plugin import ClusterPlugin
|
||||
from nailgun.objects.plugin import NodeClusterPlugin
|
||||
from nailgun.objects.plugin import Plugin
|
||||
from nailgun.objects.plugin import PluginCollection
|
||||
from nailgun.settings import settings
|
||||
@ -409,6 +410,69 @@ class PluginManager(object):
|
||||
|
||||
return components
|
||||
|
||||
@classmethod
|
||||
def get_plugins_node_default_attributes(cls, cluster):
|
||||
"""Get node attributes metadata for enabled plugins of the cluster.
|
||||
|
||||
:param cluster: A cluster instance
|
||||
:type cluster: models.Cluster
|
||||
:returns: dict -- Object with node attributes
|
||||
"""
|
||||
plugins_node_metadata = {}
|
||||
enabled_plugins = ClusterPlugin.get_enabled(cluster.id)
|
||||
for plugin_adapter in map(wrap_plugin, enabled_plugins):
|
||||
metadata = plugin_adapter.node_attributes_metadata
|
||||
# TODO(ekosareva): resolve conflicts of same attribute names
|
||||
# for different plugins
|
||||
plugins_node_metadata.update(metadata)
|
||||
|
||||
return plugins_node_metadata
|
||||
|
||||
@classmethod
|
||||
def get_plugin_node_attributes(cls, node):
|
||||
"""Return plugin related attributes for Node.
|
||||
|
||||
:param node: A Node instance
|
||||
:type node: models.Node
|
||||
:returns: dict object with plugin Node attributes
|
||||
"""
|
||||
return NodeClusterPlugin.get_all_enabled_attributes_by_node(node)
|
||||
|
||||
@classmethod
|
||||
def update_plugin_node_attributes(cls, attributes):
|
||||
"""Update plugin related node attributes.
|
||||
|
||||
:param attributes: new attributes data
|
||||
:type attributes: dict
|
||||
:returns: None
|
||||
"""
|
||||
plugins_attributes = {}
|
||||
for k in list(attributes):
|
||||
if cls.is_plugin_data(attributes[k]):
|
||||
attribute_data = attributes.pop(k)
|
||||
attribute_data['metadata'].pop('class')
|
||||
node_plugin_id = \
|
||||
attribute_data['metadata'].pop('node_plugin_id')
|
||||
plugins_attributes.setdefault(
|
||||
node_plugin_id, {}).update({k: attribute_data})
|
||||
|
||||
# TODO(ekosareva): think about changed metadata or sections set
|
||||
for plugin_id, plugin_attributes in six.iteritems(plugins_attributes):
|
||||
NodeClusterPlugin.set_attributes(
|
||||
plugin_id,
|
||||
plugin_attributes
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def add_plugin_attributes_for_node(cls, node):
|
||||
"""Add plugin related attributes for Node.
|
||||
|
||||
:param node: A Node instance
|
||||
:type node: models.Node
|
||||
:returns: None
|
||||
"""
|
||||
NodeClusterPlugin.add_cluster_plugins_for_node(node)
|
||||
|
||||
# ENTRY POINT
|
||||
@classmethod
|
||||
def sync_plugins_metadata(cls, plugin_ids=None):
|
||||
|
@ -803,12 +803,17 @@ class EnvironmentManager(object):
|
||||
|
||||
def get_default_plugin_node_config(self, **kwargs):
|
||||
node_attributes = {
|
||||
'plugin_name_text': {
|
||||
'value': 'value',
|
||||
'type': 'text',
|
||||
'description': 'Some description',
|
||||
'weight': 25,
|
||||
'label': 'label'
|
||||
'plugin_a_section': {
|
||||
'metadata': {
|
||||
'label': 'Plugin A Section'
|
||||
},
|
||||
'plugin_attr_key': {
|
||||
'value': 'plugin_attr_val',
|
||||
'type': 'text',
|
||||
'description': 'Some description',
|
||||
'weight': 25,
|
||||
'label': 'label'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -927,6 +932,10 @@ class EnvironmentManager(object):
|
||||
'version': 'mitaka-9.0', 'os': 'ubuntu',
|
||||
'mode': ['ha', 'multinode'],
|
||||
'deployment_scripts_path': 'deployment_scripts/'},
|
||||
{'repository_path': 'repositories/ubuntu',
|
||||
'version': 'newton-10.0', 'os': 'ubuntu',
|
||||
'mode': ['ha'],
|
||||
'deployment_scripts_path': 'deployment_scripts/'}
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -410,8 +410,8 @@ class TestHandlers(BaseIntegrationTest):
|
||||
if net['name'] == consts.NETWORKS.fuelweb_admin), None))
|
||||
|
||||
def test_get_node_attributes(self):
|
||||
node = self.env.create_node(api=False)
|
||||
fake_attributes = {
|
||||
fake_plugin_attributes = self.env.get_default_plugin_node_config()
|
||||
fake_release_attributes = {
|
||||
'group1': {
|
||||
'metadata': {},
|
||||
'comp1': {
|
||||
@ -419,17 +419,39 @@ class TestHandlers(BaseIntegrationTest):
|
||||
}
|
||||
}
|
||||
}
|
||||
node.attributes.update(fake_attributes)
|
||||
cluster = self.env.create(
|
||||
release_kwargs={
|
||||
'version': 'newton-10.0',
|
||||
'operating_system': 'Ubuntu',
|
||||
'node_attributes': fake_release_attributes
|
||||
},
|
||||
nodes_kwargs=[
|
||||
{'role': 'controller'}
|
||||
]
|
||||
)
|
||||
node = self.env.nodes[-1]
|
||||
plugin = self.env.create_plugin(
|
||||
name='plugin_a',
|
||||
cluster=cluster,
|
||||
package_version='5.0.0',
|
||||
node_attributes_metadata=fake_plugin_attributes)
|
||||
|
||||
resp = self.app.get(
|
||||
reverse('NodeAttributesHandler', kwargs={'node_id': node.id}),
|
||||
headers=self.default_headers)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertEqual(fake_attributes, resp.json_body)
|
||||
|
||||
fake_plugin_attributes['plugin_a_section']['metadata'].update({
|
||||
'class': 'plugin',
|
||||
'node_plugin_id': [
|
||||
item.id for item in node.node_cluster_plugins if
|
||||
item.cluster_plugin_id == plugin.cluster_plugins[0].id][0]
|
||||
})
|
||||
fake_release_attributes.update(fake_plugin_attributes)
|
||||
self.assertDictEqual(fake_release_attributes, resp.json_body)
|
||||
|
||||
def test_put_node_attributes(self):
|
||||
self.env.create(nodes_kwargs=[{}])
|
||||
node = self.env.nodes[-1]
|
||||
fake_attributes = {
|
||||
fake_release_attributes = {
|
||||
'group1': {
|
||||
'metadata': {},
|
||||
'comp1': {
|
||||
@ -451,20 +473,148 @@ class TestHandlers(BaseIntegrationTest):
|
||||
},
|
||||
},
|
||||
}
|
||||
node.attributes.update(fake_attributes)
|
||||
cluster = self.env.create(
|
||||
release_kwargs={
|
||||
'version': 'newton-10.0',
|
||||
'operating_system': 'Ubuntu',
|
||||
'node_attributes': fake_release_attributes
|
||||
},
|
||||
nodes_kwargs=[
|
||||
{'role': 'controller'}
|
||||
]
|
||||
)
|
||||
node = self.env.nodes[0]
|
||||
plugin = self.env.create_plugin(
|
||||
name='plugin_a',
|
||||
cluster=cluster,
|
||||
package_version='5.0.0',
|
||||
node_attributes_metadata={
|
||||
'plugin_a_section': {
|
||||
'metadata': {
|
||||
'label': 'Section A'
|
||||
},
|
||||
'plugin_attr_key_1': {
|
||||
'type': 'checkbox',
|
||||
'value': True
|
||||
},
|
||||
'plugin_attr_key_2': {
|
||||
'type': 'text',
|
||||
'value': 'plugin_attr_val',
|
||||
'restrictions': [{
|
||||
'condition': 'node_attributes:plugin_a_section.'
|
||||
'plugin_attr_key_2 == false',
|
||||
'action': 'hide'
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
node_cluster_plugin_id = [
|
||||
item.id for item in node.node_cluster_plugins if
|
||||
item.cluster_plugin_id == plugin.cluster_plugins[0].id][0]
|
||||
update_attributes = {
|
||||
'group1': {
|
||||
'comp1': {
|
||||
'type': 'text',
|
||||
'value': '41'
|
||||
}
|
||||
},
|
||||
'plugin_a_section': {
|
||||
'plugin_attr_key_1': {
|
||||
'type': 'checkbox',
|
||||
'value': True
|
||||
},
|
||||
'plugin_attr_key_2': {
|
||||
'type': 'text',
|
||||
'value': 'new_plugin_attr_val',
|
||||
'restrictions': [{
|
||||
'condition': 'node_attributes:plugin_a_section.'
|
||||
'plugin_attr_key_2 == false',
|
||||
'action': 'hide'
|
||||
}]
|
||||
},
|
||||
'metadata': {
|
||||
'class': 'plugin',
|
||||
'label': 'Section A',
|
||||
'node_plugin_id': node_cluster_plugin_id
|
||||
}
|
||||
}
|
||||
}
|
||||
resp = self.app.put(
|
||||
reverse('NodeAttributesHandler', kwargs={'node_id': node.id}),
|
||||
jsonutils.dumps(update_attributes),
|
||||
headers=self.default_headers)
|
||||
|
||||
fake_attributes['group1']['comp1']['value'] = '41'
|
||||
fake_release_attributes['group1']['comp1']['value'] = '41'
|
||||
fake_release_attributes['plugin_a_section'] = {
|
||||
'plugin_attr_key_1': {
|
||||
'type': 'checkbox',
|
||||
'value': True
|
||||
},
|
||||
'plugin_attr_key_2': {
|
||||
'type': 'text',
|
||||
'value': 'new_plugin_attr_val',
|
||||
'restrictions': [{
|
||||
'condition': 'node_attributes:plugin_a_section.'
|
||||
'plugin_attr_key_2 == false',
|
||||
'action': 'hide'
|
||||
}]
|
||||
},
|
||||
'metadata': {
|
||||
'class': 'plugin',
|
||||
'label': 'Section A',
|
||||
'node_plugin_id': node_cluster_plugin_id
|
||||
}
|
||||
}
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertEqual(fake_attributes, resp.json_body)
|
||||
self.assertDictEqual(fake_release_attributes, resp.json_body)
|
||||
|
||||
|
||||
class TestNodeAttributesDefaultsHandler(BaseIntegrationTest):
|
||||
|
||||
def setUp(self):
|
||||
super(TestNodeAttributesDefaultsHandler, self).setUp()
|
||||
self.node_attributes = {'test_attr_key': 'test_attr_val'}
|
||||
self.cluster = self.env.create(
|
||||
release_kwargs={
|
||||
'version': 'newton-10.0',
|
||||
'operating_system': 'Ubuntu',
|
||||
'node_attributes': self.node_attributes
|
||||
},
|
||||
nodes_kwargs=[
|
||||
{'role': 'controller'}
|
||||
]
|
||||
)
|
||||
self.node = self.env.nodes[0]
|
||||
|
||||
def test_get_node_default_attributes(self):
|
||||
resp = self.app.get(
|
||||
reverse(
|
||||
'NodeAttributesDefaultsHandler',
|
||||
kwargs={'node_id': self.node.id}),
|
||||
headers=self.default_headers)
|
||||
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertEqual(self.node_attributes, resp.json_body)
|
||||
|
||||
def test_get_node_default_attributes_with_enabled_plugin(self):
|
||||
self.env.create_plugin(
|
||||
name='plugin_a',
|
||||
cluster=self.cluster,
|
||||
package_version='5.0.0',
|
||||
node_attributes_metadata={
|
||||
'plugin_section': {'plugin_attr_key': 'plugin_attr_val'}
|
||||
})
|
||||
|
||||
resp = self.app.get(
|
||||
reverse(
|
||||
'NodeAttributesDefaultsHandler',
|
||||
kwargs={'node_id': self.node.id}),
|
||||
headers=self.default_headers)
|
||||
|
||||
expected_attributes = {
|
||||
'test_attr_key': 'test_attr_val',
|
||||
'plugin_section': {'plugin_attr_key': 'plugin_attr_val'}
|
||||
}
|
||||
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertDictEqual(expected_attributes, resp.json_body)
|
||||
|
@ -650,6 +650,40 @@ class TestDeploymentLCMSerialization90(
|
||||
if x['uid'] == self.node.uid)
|
||||
self.assertNotIn('deleted', node_info)
|
||||
|
||||
def test_plugin_node_attributes_serialization(self):
|
||||
node = self.env.create_node(
|
||||
cluster_id=self.cluster_db.id,
|
||||
roles=['compute']
|
||||
)
|
||||
self.env.create_plugin(
|
||||
name='test_plugin',
|
||||
package_version='5.0.0',
|
||||
cluster=self.cluster,
|
||||
node_attributes_metadata={
|
||||
'test_plugin_section': {
|
||||
'attribute_a': {
|
||||
'label': 'Node attribute A',
|
||||
'value': 'attribute_a_val'
|
||||
},
|
||||
'attribute_b': {
|
||||
'label': 'Node attribute B',
|
||||
'value': 'attribute_b_val'
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
objects.Cluster.prepare_for_deployment(self.cluster_db)
|
||||
serialized_for_astute = self.serializer.serialize(
|
||||
self.cluster_db, [node])['common']['nodes'][0]
|
||||
self.assertIn('test_plugin_section', serialized_for_astute)
|
||||
self.assertDictEqual(
|
||||
{
|
||||
'attribute_a': 'attribute_a_val',
|
||||
'attribute_b': 'attribute_b_val'
|
||||
},
|
||||
serialized_for_astute.get('test_plugin_section', {})
|
||||
)
|
||||
|
||||
|
||||
class TestDeploymentHASerializer90(
|
||||
TestSerializer90Mixin,
|
||||
|
@ -567,3 +567,148 @@ class TestClusterPluginIntegration(base.BaseTestCase):
|
||||
|
||||
enabled_plugins = ClusterPlugin.get_enabled(self.cluster.id)
|
||||
self.assertItemsEqual(enabled_plugins, [plugin_a])
|
||||
|
||||
|
||||
class TestNodeClusterPluginIntegration(base.BaseTestCase):
|
||||
def setUp(self):
|
||||
super(TestNodeClusterPluginIntegration, self).setUp()
|
||||
|
||||
self.cluster = self.env.create(
|
||||
release_kwargs={
|
||||
'version': 'newton-10.0',
|
||||
'operating_system': 'Ubuntu',
|
||||
},
|
||||
nodes_kwargs=[
|
||||
{'role': 'controller'}
|
||||
]
|
||||
)
|
||||
self.node = self.env.nodes[0]
|
||||
self.plugin = self.env.create_plugin(
|
||||
name='plugin_a',
|
||||
cluster=self.cluster,
|
||||
package_version='5.0.0',
|
||||
enabled=True,
|
||||
title='Plugin A Title',
|
||||
node_attributes_metadata={
|
||||
'plugin_a_section_1': {
|
||||
'metadata': {'label': 'Section 1 of Plugin A'},
|
||||
'attr_1': {'value': 'test_1'}
|
||||
},
|
||||
'plugin_a_section_2': {
|
||||
'attr_2': {'value': 'test_2'}
|
||||
}
|
||||
})
|
||||
|
||||
def test_get_node_default_attributes(self):
|
||||
self.env.create_plugin(
|
||||
name='plugin_b',
|
||||
cluster=self.cluster,
|
||||
enabled=True,
|
||||
package_version='5.0.0',
|
||||
node_attributes_metadata={
|
||||
'section_plugin_b': {
|
||||
'attr_b': {'value': 'test_b'}
|
||||
}
|
||||
})
|
||||
|
||||
self.env.create_plugin(
|
||||
name='plugin_c',
|
||||
cluster=self.cluster,
|
||||
enabled=False,
|
||||
package_version='5.0.0',
|
||||
node_attributes_metadata={
|
||||
'plugin_c_section': {
|
||||
'attr_c': {'value': 'test_c'}
|
||||
}
|
||||
})
|
||||
|
||||
for node_cluster_plugin in self.cluster.nodes[0].node_cluster_plugins:
|
||||
node_cluster_plugin.attributes = {}
|
||||
self.db.flush()
|
||||
|
||||
default_attributes = PluginManager.get_plugins_node_default_attributes(
|
||||
self.cluster)
|
||||
self.assertDictEqual(
|
||||
{
|
||||
'plugin_a_section_1': {
|
||||
'metadata': {'label': 'Section 1 of Plugin A'},
|
||||
'attr_1': {'value': 'test_1'}},
|
||||
'plugin_a_section_2': {
|
||||
'attr_2': {'value': 'test_2'}},
|
||||
'section_plugin_b': {
|
||||
'attr_b': {'value': 'test_b'}}
|
||||
},
|
||||
default_attributes
|
||||
)
|
||||
|
||||
def test_get_plugin_node_attributes(self):
|
||||
attributes = PluginManager.get_plugin_node_attributes(self.node)
|
||||
del attributes['plugin_a_section_1']['metadata']['node_plugin_id']
|
||||
del attributes['plugin_a_section_2']['metadata']['node_plugin_id']
|
||||
self.assertDictEqual(
|
||||
{
|
||||
'plugin_a_section_1': {
|
||||
'metadata': {'label': 'Section 1 of Plugin A',
|
||||
'class': 'plugin'},
|
||||
'attr_1': {'value': 'test_1'}},
|
||||
'plugin_a_section_2': {
|
||||
'metadata': {'class': 'plugin'},
|
||||
'attr_2': {'value': 'test_2'}}
|
||||
},
|
||||
attributes
|
||||
)
|
||||
|
||||
def test_update_plugin_node_attributes(self):
|
||||
self.env.create_plugin(
|
||||
name='plugin_b',
|
||||
cluster=self.cluster,
|
||||
enabled=True,
|
||||
package_version='5.0.0',
|
||||
node_attributes_metadata={
|
||||
'section_plugin_b': {
|
||||
'attr_b': {'value': 'test_b'}
|
||||
}
|
||||
})
|
||||
new_attrs = PluginManager.get_plugin_node_attributes(self.node)
|
||||
new_attrs['plugin_a_section_1']['attr_1']['value'] = 'new_test_1'
|
||||
new_attrs['section_plugin_b']['attr_b']['value'] = 'new_test_b'
|
||||
PluginManager.update_plugin_node_attributes(new_attrs)
|
||||
attributes = PluginManager.get_plugin_node_attributes(self.node)
|
||||
for attribute in attributes:
|
||||
del attributes[attribute]['metadata']['node_plugin_id']
|
||||
self.assertDictEqual(
|
||||
{
|
||||
'plugin_a_section_1': {
|
||||
'metadata': {'label': 'Section 1 of Plugin A',
|
||||
'class': 'plugin'},
|
||||
'attr_1': {'value': 'new_test_1'}},
|
||||
'plugin_a_section_2': {
|
||||
'metadata': {'class': 'plugin'},
|
||||
'attr_2': {'value': 'test_2'}},
|
||||
'section_plugin_b': {
|
||||
'metadata': {'class': 'plugin'},
|
||||
|
||||
'attr_b': {'value': 'new_test_b'}}
|
||||
},
|
||||
attributes
|
||||
)
|
||||
|
||||
def test_add_plugin_attributes_for_node(self):
|
||||
new_cluster_node = self.env.create_node(
|
||||
cluster_id=self.cluster.id,
|
||||
roles=['controller']
|
||||
)
|
||||
PluginManager.add_plugin_attributes_for_node(new_cluster_node)
|
||||
node_cluster_plugins = new_cluster_node.node_cluster_plugins
|
||||
self.assertEqual(len(node_cluster_plugins), 1)
|
||||
attributes = node_cluster_plugins[0].attributes
|
||||
self.assertDictEqual(
|
||||
{
|
||||
'plugin_a_section_1': {
|
||||
'metadata': {'label': 'Section 1 of Plugin A'},
|
||||
'attr_1': {'value': 'test_1'}},
|
||||
'plugin_a_section_2': {
|
||||
'attr_2': {'value': 'test_2'}}
|
||||
},
|
||||
attributes
|
||||
)
|
||||
|
@ -53,14 +53,15 @@ class TestNodeAttributes(base.BaseUnitTest):
|
||||
fake_numa_nodes, comp_entity, [0, 1])
|
||||
|
||||
def test_node_cpu_pinning_info(self):
|
||||
node = mock.Mock(attributes={
|
||||
'cpu_pinning': {
|
||||
'meta': {
|
||||
'some': 'info'},
|
||||
'comp1': {
|
||||
'value': 1},
|
||||
'comp2': {
|
||||
'value': 3}}})
|
||||
node = mock.Mock(
|
||||
id=1,
|
||||
attributes={
|
||||
'cpu_pinning': {
|
||||
'meta': {'some': 'info'},
|
||||
'comp1': {'value': 1},
|
||||
'comp2': {'value': 3}}
|
||||
}
|
||||
)
|
||||
self.assertEquals(
|
||||
{'total_required_cpus': 4,
|
||||
'components': {
|
||||
@ -72,6 +73,7 @@ class TestNodeAttributes(base.BaseUnitTest):
|
||||
|
||||
def test_total_hugepages(self):
|
||||
node = mock.Mock(
|
||||
id=1,
|
||||
attributes={
|
||||
'hugepages': {
|
||||
'comp1': {
|
||||
@ -92,6 +94,7 @@ class TestNodeAttributes(base.BaseUnitTest):
|
||||
|
||||
def test_hugepages_kernel_opts(self):
|
||||
node = mock.Mock(
|
||||
id=1,
|
||||
attributes={
|
||||
'hugepages': {
|
||||
'comp1': {
|
||||
@ -109,6 +112,7 @@ class TestNodeAttributes(base.BaseUnitTest):
|
||||
|
||||
def _make_hugepages_node(self):
|
||||
return mock.Mock(
|
||||
id=1,
|
||||
attributes={
|
||||
'hugepages': {
|
||||
'comp1': {
|
||||
@ -164,6 +168,7 @@ class TestNodeAttributes(base.BaseUnitTest):
|
||||
def test_set_default_hugepages(self):
|
||||
fake_hugepages = ['0', '1', '2', '3']
|
||||
node = mock.Mock(
|
||||
id=1,
|
||||
attributes={
|
||||
'hugepages': {
|
||||
'nova': {
|
||||
|
@ -82,7 +82,7 @@ class BaseNodeAttributeValidatorTest(base.BaseTestCase):
|
||||
}
|
||||
}
|
||||
}
|
||||
self.node = mock.Mock(meta=meta, attributes=attributes)
|
||||
self.node = mock.Mock(id=1, meta=meta, attributes=attributes)
|
||||
self.cluster = mock.Mock()
|
||||
|
||||
|
||||
|
@ -13,13 +13,19 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import uuid
|
||||
|
||||
import sqlalchemy as sa
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from nailgun import consts
|
||||
from nailgun.objects import ClusterPlugin
|
||||
from nailgun.objects import NodeClusterPlugin
|
||||
from nailgun.objects import Plugin
|
||||
from nailgun.objects import PluginCollection
|
||||
from nailgun.test import base
|
||||
import sqlalchemy as sa
|
||||
import uuid
|
||||
|
||||
|
||||
class ExtraFunctions(base.BaseTestCase):
|
||||
@ -168,3 +174,187 @@ class TestClusterPlugin(ExtraFunctions):
|
||||
self.assertFalse(ClusterPlugin.is_plugin_used(plugin.id))
|
||||
ClusterPlugin.set_attributes(cluster.id, plugin.id, enabled=True)
|
||||
self.assertTrue(ClusterPlugin.is_plugin_used(plugin.id))
|
||||
|
||||
|
||||
class TestNodeClusterPlugin(ExtraFunctions):
|
||||
def setUp(self):
|
||||
super(TestNodeClusterPlugin, self).setUp()
|
||||
self.node_attributes = self.env.get_default_plugin_node_config()
|
||||
self.cluster = self.env.create(
|
||||
release_kwargs={
|
||||
'version': 'newton-10.0',
|
||||
'operating_system': 'Ubuntu',
|
||||
},
|
||||
nodes_kwargs=[
|
||||
{'role': 'controller'}
|
||||
]
|
||||
)
|
||||
self.node = self.env.nodes[0]
|
||||
|
||||
def test_get_all_enabled_attributes_by_node(self):
|
||||
plugin_b_node_attributes = {
|
||||
'plugin_b_section_1': {
|
||||
'plugin_b_attr1_key': 'plugin_b_attr1_val',
|
||||
'metadata': {'group': 'plugin_group',
|
||||
'label': 'Plugin B Section 1'}
|
||||
},
|
||||
'plugin_b_section_2': {
|
||||
'plugin_b_attr2_key': 'plugin_b_attr2_val',
|
||||
'metadata': {'group': 'plugin_group',
|
||||
'label': 'Plugin B Section 2'}
|
||||
}
|
||||
}
|
||||
plugin_a = self.env.create_plugin(
|
||||
name='plugin_a_with_node_attributes',
|
||||
cluster=self.cluster,
|
||||
package_version='5.0.0',
|
||||
node_attributes_metadata=self.node_attributes)
|
||||
plugin_b = self.env.create_plugin(
|
||||
name='plugin_b_with_nic_attributes',
|
||||
cluster=self.cluster,
|
||||
package_version='5.0.0',
|
||||
node_attributes_metadata=plugin_b_node_attributes)
|
||||
|
||||
attributes = NodeClusterPlugin. \
|
||||
get_all_enabled_attributes_by_node(self.node)
|
||||
|
||||
node_cluster_plugin_a_id = [
|
||||
item.id for item in self.node.node_cluster_plugins if
|
||||
item.cluster_plugin_id == plugin_a.cluster_plugins[0].id][0]
|
||||
node_cluster_plugin_b_id = [
|
||||
item.id for item in self.node.node_cluster_plugins if
|
||||
item.cluster_plugin_id == plugin_b.cluster_plugins[0].id][0]
|
||||
|
||||
expected_attributes = self.node_attributes
|
||||
expected_attributes.update(plugin_b_node_attributes)
|
||||
expected_attributes['plugin_a_section']['metadata'].update({
|
||||
'node_plugin_id': node_cluster_plugin_a_id,
|
||||
'class': 'plugin'
|
||||
})
|
||||
expected_attributes['plugin_b_section_1']['metadata'].update({
|
||||
'node_plugin_id': node_cluster_plugin_b_id,
|
||||
'class': 'plugin'
|
||||
})
|
||||
expected_attributes['plugin_b_section_2']['metadata'].update({
|
||||
'node_plugin_id': node_cluster_plugin_b_id,
|
||||
'class': 'plugin'
|
||||
})
|
||||
self.assertDictEqual(expected_attributes, attributes)
|
||||
|
||||
def test_get_all_enabled_attributes_by_node_with_disabled_plugin(self):
|
||||
self.env.create_plugin(
|
||||
name='plugin_a_with_node_attributes',
|
||||
package_version='5.0.0',
|
||||
enabled=False,
|
||||
node_attributes_metadata=self.node_attributes)
|
||||
|
||||
attributes = NodeClusterPlugin. \
|
||||
get_all_enabled_attributes_by_node(self.node)
|
||||
|
||||
self.assertDictEqual({}, attributes)
|
||||
|
||||
def test_add_cluster_plugins_for_node(self):
|
||||
self.env.create_plugin(
|
||||
name='plugin_a_with_node_attributes',
|
||||
package_version='5.0.0',
|
||||
node_attributes_metadata=self.node_attributes)
|
||||
self.env.create_plugin(
|
||||
name='plugin_b_with_nic_attributes',
|
||||
package_version='5.0.0',
|
||||
node_attributes_metadata={})
|
||||
self.env.create_plugin(
|
||||
name='plugin_c_with_nic_attributes',
|
||||
package_version='5.0.0',
|
||||
node_attributes_metadata=self.node_attributes)
|
||||
|
||||
new_node = self.env.create_node(
|
||||
cluster_id=self.cluster.id,
|
||||
roles=['compute']
|
||||
)
|
||||
NodeClusterPlugin.add_cluster_plugins_for_node(new_node)
|
||||
|
||||
self.assertEqual(2, len(new_node.node_cluster_plugins))
|
||||
for item in new_node.node_cluster_plugins:
|
||||
self.assertDictEqual(self.node_attributes, item.attributes)
|
||||
|
||||
def test_add_nodes_for_cluster_plugin(self):
|
||||
meta = base.reflect_db_metadata()
|
||||
self.env.create_node(
|
||||
cluster_id=self.cluster.id,
|
||||
roles=['compute']
|
||||
)
|
||||
plugin = Plugin.create({
|
||||
'name': 'plugin_a_with_node_attributes',
|
||||
'title': 'Test Plugin',
|
||||
'package_version': '5.0.0',
|
||||
'version': '1.0.0',
|
||||
'node_attributes_metadata': self.node_attributes
|
||||
})
|
||||
cluster_plugin = ClusterPlugin.create({
|
||||
'cluster_id': self.cluster.id,
|
||||
'plugin_id': plugin.id,
|
||||
'enabled': False,
|
||||
'attributes': self.node_attributes
|
||||
})
|
||||
|
||||
NodeClusterPlugin.add_nodes_for_cluster_plugin(cluster_plugin)
|
||||
|
||||
node_cluster_plugins = self.db.execute(
|
||||
meta.tables['node_cluster_plugins'].select()
|
||||
).fetchall()
|
||||
|
||||
self.assertEqual(2, len(node_cluster_plugins))
|
||||
for item in node_cluster_plugins:
|
||||
self.assertDictEqual(self.node_attributes,
|
||||
jsonutils.loads(item.attributes))
|
||||
|
||||
def test_add_nodes_for_cluster_plugin_with_empty_attributes(self):
|
||||
meta = base.reflect_db_metadata()
|
||||
self.env.create_node(
|
||||
cluster_id=self.cluster.id,
|
||||
roles=['compute']
|
||||
)
|
||||
plugin = Plugin.create({
|
||||
'name': 'plugin_a_with_node_attributes',
|
||||
'title': 'Test Plugin',
|
||||
'package_version': '5.0.0',
|
||||
'version': '1.0.0',
|
||||
'node_attributes_metadata': {}
|
||||
})
|
||||
cluster_plugin = ClusterPlugin.create({
|
||||
'cluster_id': self.cluster.id,
|
||||
'plugin_id': plugin.id,
|
||||
'enabled': False,
|
||||
'attributes': plugin.node_attributes_metadata
|
||||
})
|
||||
|
||||
NodeClusterPlugin.add_nodes_for_cluster_plugin(cluster_plugin)
|
||||
|
||||
node_cluster_plugins = self.db.execute(
|
||||
meta.tables['node_cluster_plugins'].select()
|
||||
).fetchall()
|
||||
self.assertEqual(0, len(node_cluster_plugins))
|
||||
|
||||
def test_set_attributes(self):
|
||||
meta = base.reflect_db_metadata()
|
||||
self.env.create_plugin(
|
||||
cluster=self.cluster,
|
||||
name='plugin_a_with_node_attributes',
|
||||
package_version='5.0.0',
|
||||
node_attributes_metadata=self.node_attributes)
|
||||
|
||||
node_attributes_cluster_plugin = self.db.execute(
|
||||
meta.tables['node_cluster_plugins'].select()
|
||||
).fetchall()[0]
|
||||
|
||||
_id = node_attributes_cluster_plugin.id
|
||||
attributes = {'test_attr': 'a'}
|
||||
NodeClusterPlugin.set_attributes(_id, attributes)
|
||||
|
||||
node_attributes_cluster_plugin = self.db.execute(
|
||||
meta.tables['node_cluster_plugins'].select()
|
||||
).fetchall()[0]
|
||||
|
||||
self.assertDictEqual(
|
||||
attributes,
|
||||
jsonutils.loads(node_attributes_cluster_plugin[1]))
|
||||
|
@ -712,15 +712,21 @@ class TestNodeObject(BaseIntegrationTest):
|
||||
errors.CannotUpdate, objects.Node.update, node_0, data)
|
||||
|
||||
def test_get_attributes(self):
|
||||
node = self.env.create_node()
|
||||
|
||||
fake_attributes = {
|
||||
'fake_attributes': {'fake_key_1': 'fake_value_1',
|
||||
'fake_key_2': 'fake_value_2'}
|
||||
}
|
||||
node.attributes = fake_attributes
|
||||
self.assertDictEqual(fake_attributes,
|
||||
objects.Node.get_attributes(node))
|
||||
fake_plugin_attributes = {
|
||||
'plugin_a_section': {'plugin_attr_key': 'plugin_attr_val'}
|
||||
}
|
||||
node = self.env.create_node(attributes=fake_attributes)
|
||||
|
||||
with mock.patch('nailgun.plugins.manager.PluginManager.'
|
||||
'get_plugin_node_attributes',
|
||||
return_value=fake_plugin_attributes):
|
||||
fake_attributes.update(fake_plugin_attributes)
|
||||
self.assertDictEqual(fake_attributes,
|
||||
objects.Node.get_attributes(node))
|
||||
|
||||
def test_update_attributes(self):
|
||||
node = self.env.create_node()
|
||||
@ -732,8 +738,13 @@ class TestNodeObject(BaseIntegrationTest):
|
||||
objects.Node.update_attributes(
|
||||
node,
|
||||
{
|
||||
'fake_attributes':
|
||||
{'fake_key_1': {'key': 'new_value'}}
|
||||
'fake_attributes': {
|
||||
'fake_key_1': {'key': 'new_value'}
|
||||
},
|
||||
'plugin_a_section': {
|
||||
'plugin_attr_key': {'value': 'new_attr_val'},
|
||||
'metadata': {'class': 'plugin', 'node_plugin_id': 1}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@ -741,7 +752,37 @@ class TestNodeObject(BaseIntegrationTest):
|
||||
'fake_attributes': {'fake_key_1': {'key': 'new_value'},
|
||||
'fake_key_2': 'fake_value_2'}
|
||||
}
|
||||
self.assertEqual(expected_attributes, node.attributes)
|
||||
self.assertDictEqual(expected_attributes, node.attributes)
|
||||
|
||||
def test_get_default_attributes(self):
|
||||
release_node_attributes = {'release_attr_a': 'release_attr_a_val'}
|
||||
cluster = self.env.create(
|
||||
release_kwargs={
|
||||
'version': 'newton-10.0',
|
||||
'operating_system': 'Ubuntu',
|
||||
'node_attributes': release_node_attributes
|
||||
},
|
||||
nodes_kwargs=[
|
||||
{'role': 'controller'}
|
||||
]
|
||||
)
|
||||
plugin_node_attributes = self.env.get_default_plugin_node_config()
|
||||
self.env.create_plugin(
|
||||
name='plugin_a',
|
||||
cluster=cluster,
|
||||
package_version='5.0.0',
|
||||
node_attributes_metadata=plugin_node_attributes)
|
||||
|
||||
node = cluster.nodes[0]
|
||||
node.node_cluster_plugins[0].attributes = {}
|
||||
node.attributes = {}
|
||||
self.db.flush()
|
||||
|
||||
default_attributes = objects.Node.get_default_attributes(node)
|
||||
|
||||
expected_attributes = copy.deepcopy(plugin_node_attributes)
|
||||
expected_attributes.update(release_node_attributes)
|
||||
self.assertDictEqual(expected_attributes, default_attributes)
|
||||
|
||||
def test_update_tags(self):
|
||||
self.env.create(
|
||||
@ -772,6 +813,29 @@ class TestNodeObject(BaseIntegrationTest):
|
||||
objects.Node.update_roles(node, [])
|
||||
self.assertEquals(['test'], objects.Node.all_tags(node))
|
||||
|
||||
@mock.patch.object(objects.Cluster, 'get_editable_attributes')
|
||||
def test_get_restrictions_models(self, get_cluster_attributes):
|
||||
mocked_node_attributes = {
|
||||
'plugin_section_a': 'some_attributes',
|
||||
'cpu_pinning': {}
|
||||
}
|
||||
mocked_cluster_attributes = {'some': {'fake': 'attributes'}}
|
||||
get_cluster_attributes.return_value = mocked_cluster_attributes
|
||||
|
||||
cluster = mock.Mock()
|
||||
node = mock.Mock(cluster=cluster)
|
||||
with mock.patch.object(objects.Node, 'get_attributes',
|
||||
return_value=mocked_node_attributes):
|
||||
node_models = objects.Node.get_restrictions_models(node)
|
||||
expected_models = {
|
||||
'settings': mocked_cluster_attributes,
|
||||
'cluster': cluster,
|
||||
'version': settings.VERSION,
|
||||
'networking_parameters': cluster.network_config,
|
||||
'node_attributes': mocked_node_attributes
|
||||
}
|
||||
self.assertEqual(expected_models, node_models)
|
||||
|
||||
|
||||
class TestTaskObject(BaseIntegrationTest):
|
||||
|
||||
|
@ -83,7 +83,7 @@ class TestPluginBase(base.BaseTestCase):
|
||||
"""Should return set of all versions this plugin is applicable to"""
|
||||
self.assertEqual(
|
||||
self.plugin_adapter.plugin_release_versions,
|
||||
set(['2014.2-6.0', '2015.1-8.0', 'mitaka-9.0'])
|
||||
set(['2014.2-6.0', '2015.1-8.0', 'mitaka-9.0', 'newton-10.0'])
|
||||
)
|
||||
|
||||
def test_full_name(self):
|
||||
@ -552,7 +552,7 @@ class TestPluginV5(TestPluginBase):
|
||||
bond_attributes_metadata)
|
||||
self.assertEqual(
|
||||
self.plugin.node_attributes_metadata,
|
||||
bond_attributes_metadata)
|
||||
node_attributes_metadata)
|
||||
|
||||
# check custom graph
|
||||
dg = DeploymentGraph.get_for_model(
|
||||
|
Loading…
Reference in New Issue
Block a user