summaryrefslogtreecommitdiff
path: root/ironic/db/sqlalchemy/api.py
diff options
context:
space:
mode:
authorJulia Kreger <juliaashleykreger@gmail.com>2022-04-29 16:48:43 -0700
committerJulia Kreger <juliaashleykreger@gmail.com>2022-09-20 06:47:38 -0700
commit9a8b1d149c738b7d06a93c39a29f43afeed7cc8a (patch)
tree5e847072114ec29ca9d880f81386bc038e55c050 /ironic/db/sqlalchemy/api.py
parentb9af8e4ef326314297efbef71418bedcf3b402a6 (diff)
downloadironic-9a8b1d149c738b7d06a93c39a29f43afeed7cc8a.tar.gz
Concurrent Distructive/Intensive ops limits
Provide the ability to limit resource intensive or potentially wide scale operations which could be a symptom of a highly distructive and unplanned operation in progress. The idea behind this change is to help guard the overall deployment to prevent an overall resource exhaustion situation, or prevent an attacker with valid credentials from putting an entire deployment into a potentially disasterous cleaning situation since ironic only other wise limits concurrency based upon running tasks by conductor. Story: 2010007 Task: 45140 Change-Id: I642452cd480e7674ff720b65ca32bce59a4a834a
Diffstat (limited to 'ironic/db/sqlalchemy/api.py')
-rw-r--r--ironic/db/sqlalchemy/api.py24
1 files changed, 24 insertions, 0 deletions
diff --git a/ironic/db/sqlalchemy/api.py b/ironic/db/sqlalchemy/api.py
index 05d5cc45e..c14719af8 100644
--- a/ironic/db/sqlalchemy/api.py
+++ b/ironic/db/sqlalchemy/api.py
@@ -30,6 +30,7 @@ from oslo_utils import timeutils
from oslo_utils import uuidutils
from osprofiler import sqlalchemy as osp_sqlalchemy
import sqlalchemy as sa
+from sqlalchemy import or_
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
from sqlalchemy.orm import joinedload
from sqlalchemy.orm import Load
@@ -2400,3 +2401,26 @@ class Connection(api.Connection):
).filter(
models.NodeHistory.id.in_(entries)
).delete(synchronize_session=False)
+
+ def count_nodes_in_provision_state(self, state):
+ if not isinstance(state, list):
+ state = [state]
+ with _session_for_read() as session:
+ # Intentionally does not use the full ORM model
+ # because that is de-duped by pkey, but we already
+ # have unique constraints on UUID/name, so... shouldn't
+ # be a big deal. #JuliaFamousLastWords.
+ # Anyway, intent here is to be as quick as possible and
+ # literally have the DB do *all* of the world, so no
+ # client side ops occur. The column is also indexed,
+ # which means this will be an index based response.
+ # TODO(TheJulia): This might need to be revised for
+ # SQLAlchemy 2.0 as it should be a scaler select and count
+ # instead.
+ return session.query(
+ models.Node.provision_state
+ ).filter(
+ or_(
+ models.Node.provision_state == v for v in state
+ )
+ ).count()