summaryrefslogtreecommitdiff
path: root/ironic/db/sqlalchemy/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'ironic/db/sqlalchemy/models.py')
-rw-r--r--ironic/db/sqlalchemy/models.py74
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.