diff options
Diffstat (limited to 'ironic/db/sqlalchemy/models.py')
-rw-r--r-- | ironic/db/sqlalchemy/models.py | 74 |
1 files changed, 68 insertions, 6 deletions
diff --git a/ironic/db/sqlalchemy/models.py b/ironic/db/sqlalchemy/models.py index 8f3f6a564..342491417 100644 --- a/ironic/db/sqlalchemy/models.py +++ b/ironic/db/sqlalchemy/models.py @@ -19,16 +19,18 @@ SQLAlchemy models for baremetal data. """ from os import path +from typing import List from urllib import parse as urlparse from oslo_db import options as db_options from oslo_db.sqlalchemy import models from oslo_db.sqlalchemy import types as db_types +from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy import Boolean, Column, DateTime, false, Index from sqlalchemy import ForeignKey, Integer from sqlalchemy import schema, String, Text -from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import orm +from sqlalchemy.orm import declarative_base from ironic.common import exception from ironic.common.i18n import _ @@ -116,8 +118,8 @@ class ConductorHardwareInterfaces(Base): default = Column(Boolean, default=False, nullable=False) -class Node(Base): - """Represents a bare metal node.""" +class NodeBase(Base): + """Represents a base bare metal node.""" __tablename__ = 'nodes' __table_args__ = ( @@ -132,6 +134,7 @@ class Node(Base): Index('reservation_idx', 'reservation'), Index('conductor_group_idx', 'conductor_group'), Index('resource_class_idx', 'resource_class'), + Index('shard_idx', 'shard'), table_args()) id = Column(Integer, primary_key=True) uuid = Column(String(36)) @@ -212,6 +215,34 @@ class Node(Base): boot_mode = Column(String(16), nullable=True) secure_boot = Column(Boolean, nullable=True) + shard = Column(String(255), nullable=True) + + +class Node(NodeBase): + """Represents a bare metal node.""" + + # NOTE(TheJulia): The purpose of the delineation between NodeBase and Node + # is to facilitate a hard delineation for queries where we do not need to + # populate additional information needlessly which would normally populate + # from the access of the property. In this case, Traits and Tags. + # The other reason we do this, is because these are generally "joined" + # data structures, we cannot de-duplicate node objects with unhashable dict + # data structures. + + # NOTE(TheJulia): The choice of selectin lazy population is intentional + # as it causes a subselect to occur, skipping the need for deduplication + # in general. This puts a slightly higher query load on the DB server, but + # means *far* less gets shipped over the wire in the end. + traits: orm.Mapped[List['NodeTrait']] = orm.relationship( # noqa + "NodeTrait", + back_populates="node", + lazy="selectin") + + tags: orm.Mapped[List['NodeTag']] = orm.relationship( # noqa + "NodeTag", + back_populates="node", + lazy="selectin") + class Port(Base): """Represents a network port of a bare metal node.""" @@ -235,6 +266,15 @@ class Port(Base): is_smartnic = Column(Boolean, nullable=True, default=False) name = Column(String(255), nullable=True) + _node_uuid = orm.relationship( + "Node", + viewonly=True, + primaryjoin="(Node.id == Port.node_id)", + lazy="selectin", + ) + node_uuid = association_proxy( + "_node_uuid", "uuid", creator=lambda _i: Node(uuid=_i)) + class Portgroup(Base): """Represents a group of network ports of a bare metal node.""" @@ -256,6 +296,15 @@ class Portgroup(Base): mode = Column(String(255)) properties = Column(db_types.JsonEncodedDict) + _node_uuid = orm.relationship( + "Node", + viewonly=True, + primaryjoin="(Node.id == Portgroup.node_id)", + lazy="selectin", + ) + node_uuid = association_proxy( + "_node_uuid", "uuid", creator=lambda _i: Node(uuid=_i)) + class NodeTag(Base): """Represents a tag of a bare metal node.""" @@ -270,7 +319,6 @@ class NodeTag(Base): node = orm.relationship( "Node", - backref='tags', primaryjoin='and_(NodeTag.node_id == Node.id)', foreign_keys=node_id ) @@ -327,7 +375,6 @@ class NodeTrait(Base): trait = Column(String(255), primary_key=True, nullable=False) node = orm.relationship( "Node", - backref='traits', primaryjoin='and_(NodeTrait.node_id == Node.id)', foreign_keys=node_id ) @@ -389,6 +436,10 @@ class DeployTemplate(Base): uuid = Column(String(36)) name = Column(String(255), nullable=False) extra = Column(db_types.JsonEncodedDict) + steps: orm.Mapped[List['DeployTemplateStep']] = orm.relationship( # noqa + "DeployTemplateStep", + back_populates="deploy_template", + lazy="selectin") class DeployTemplateStep(Base): @@ -409,7 +460,6 @@ class DeployTemplateStep(Base): priority = Column(Integer, nullable=False) deploy_template = orm.relationship( "DeployTemplate", - backref='steps', primaryjoin=( 'and_(DeployTemplateStep.deploy_template_id == ' 'DeployTemplate.id)'), @@ -437,6 +487,18 @@ class NodeHistory(Base): node_id = Column(Integer, ForeignKey('nodes.id'), nullable=True) +class NodeInventory(Base): + """Represents an inventory of a baremetal node.""" + __tablename__ = 'node_inventory' + __table_args__ = ( + Index('inventory_node_id_idx', 'node_id'), + table_args()) + id = Column(Integer, primary_key=True) + inventory_data = Column(db_types.JsonEncodedDict(mysql_as_long=True)) + plugin_data = Column(db_types.JsonEncodedDict(mysql_as_long=True)) + node_id = Column(Integer, ForeignKey('nodes.id'), nullable=True) + + def get_class(model_name): """Returns the model class with the specified name. |