Extend compute model attributes
This patch extends compute model attributes by adding new fields to Instance element. Values are populated by nova the collector, using the same nova list call, but requires a more recent compute API microversion. A new config option was added to allow users to enable or disable the extended attributes and it is disable by default. Configure prometheus-based jobs to run on newer version of nova api (2.96) and enables the extended attributes collection. Implements: bp/extend-compute-model-attributes Assisted-By: Cursor (claude-4-sonnet) Change-Id: Ibf31105d780dce510a59fc74241fa04e28529ade Signed-off-by: Douglas Viroel <viroel@gmail.com>
This commit is contained in:
@@ -471,13 +471,22 @@ class NovaModelBuilder(base.BaseModelBuilder):
|
||||
"state": getattr(instance, "OS-EXT-STS:vm_state"),
|
||||
"metadata": instance.metadata,
|
||||
"project_id": instance.tenant_id,
|
||||
"locked": instance.locked}
|
||||
"locked": instance.locked,
|
||||
# NOTE(dviroel): new attributes are updated if
|
||||
# extended feature is enabled
|
||||
"flavor_extra_specs": {},
|
||||
"pinned_az": "",
|
||||
}
|
||||
|
||||
if self.model.extended_attributes_enabled:
|
||||
instance_attributes.update({
|
||||
"flavor_extra_specs": flavor["extra_specs"],
|
||||
})
|
||||
if self.nova_helper.is_pinned_az_available():
|
||||
instance_attributes["pinned_az"] = (
|
||||
instance.pinned_availability_zone
|
||||
)
|
||||
|
||||
# node_attributes = dict()
|
||||
# node_attributes["layer"] = "virtual"
|
||||
# node_attributes["category"] = "compute"
|
||||
# node_attributes["type"] = "compute"
|
||||
# node_attributes["attributes"] = instance_attributes
|
||||
return element.Instance(**instance_attributes)
|
||||
|
||||
def _merge_compute_scope(self, compute_scope):
|
||||
|
||||
@@ -54,6 +54,9 @@ class Instance(compute_resource.ComputeResource):
|
||||
"metadata": wfields.JsonField(),
|
||||
"project_id": wfields.UUIDField(),
|
||||
"locked": wfields.BooleanField(default=False),
|
||||
# New fields for extended compute model
|
||||
"pinned_az": wfields.StringField(default=""),
|
||||
"flavor_extra_specs": wfields.JsonField(default={}),
|
||||
}
|
||||
|
||||
def accept(self, visitor):
|
||||
|
||||
@@ -17,9 +17,11 @@ Openstack implementation of the cluster graph.
|
||||
"""
|
||||
|
||||
import ast
|
||||
|
||||
from lxml import etree # nosec: B410
|
||||
import networkx as nx
|
||||
from oslo_concurrency import lockutils
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log
|
||||
|
||||
from watcher._i18n import _
|
||||
@@ -28,6 +30,7 @@ from watcher.decision_engine.model import base
|
||||
from watcher.decision_engine.model import element
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class ModelRoot(nx.DiGraph, base.Model):
|
||||
@@ -36,12 +39,24 @@ class ModelRoot(nx.DiGraph, base.Model):
|
||||
def __init__(self, stale=False):
|
||||
super(ModelRoot, self).__init__()
|
||||
self.stale = stale
|
||||
self._extended_attributes_enabled = None
|
||||
|
||||
def __nonzero__(self):
|
||||
return not self.stale
|
||||
|
||||
__bool__ = __nonzero__
|
||||
|
||||
@property
|
||||
def extended_attributes_enabled(self):
|
||||
if self._extended_attributes_enabled is None:
|
||||
self._extended_attributes_enabled = (
|
||||
CONF.compute_model.enable_extended_attributes)
|
||||
return self._extended_attributes_enabled
|
||||
|
||||
@extended_attributes_enabled.setter
|
||||
def extended_attributes_enabled(self, value):
|
||||
self._extended_attributes_enabled = value
|
||||
|
||||
@staticmethod
|
||||
def assert_node(obj):
|
||||
if not isinstance(obj, element.ComputeNode):
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from novaclient import api_versions
|
||||
import os_resource_classes as orc
|
||||
from oslo_log import log
|
||||
|
||||
from watcher.common import exception
|
||||
from watcher.common import nova_helper
|
||||
from watcher.common import placement_helper
|
||||
@@ -72,7 +74,7 @@ class NovaNotification(base.NotificationEndpoint):
|
||||
return instance
|
||||
|
||||
def update_instance(self, instance, data):
|
||||
n_version = float(data['nova_object.version'])
|
||||
n_version = api_versions.APIVersion(data['nova_object.version'])
|
||||
instance_data = data['nova_object.data']
|
||||
instance_flavor_data = instance_data['flavor']['nova_object.data']
|
||||
|
||||
@@ -91,12 +93,20 @@ class NovaNotification(base.NotificationEndpoint):
|
||||
'vcpus': num_cores,
|
||||
'disk': disk_gb,
|
||||
'metadata': instance_metadata,
|
||||
'project_id': instance_data['tenant_id']
|
||||
'project_id': instance_data['tenant_id'],
|
||||
})
|
||||
|
||||
# locked was added in nova notification payload version 1.1
|
||||
if n_version > 1.0:
|
||||
if n_version > api_versions.APIVersion(version_str='1.0'):
|
||||
instance.update({'locked': instance_data['locked']})
|
||||
|
||||
# NOTE(dviroel): extra_specs can change due to a resize operation.
|
||||
# 'extra_specs' was added in nova notification payload version 1.2
|
||||
if (n_version > api_versions.APIVersion(version_str='1.1') and
|
||||
self.cluster_data_model.extended_attributes_enabled):
|
||||
extra_specs = instance_flavor_data.get("extra_specs", {})
|
||||
instance.update({'flavor_extra_specs': extra_specs})
|
||||
|
||||
try:
|
||||
node = self.get_or_create_node(instance_data['host'])
|
||||
except exception.ComputeNodeNotFound as exc:
|
||||
|
||||
Reference in New Issue
Block a user