feat(models): add resource utilization methods for hosts and workloads
Add get_resource_utilization to WorkloadHost to compute available and used resources dynamically from pooled resources and active workloads. Add get_resource_usage to Workload to return list of used resources for the workload. Fix minor typo in TODO comment and add SQLAlchemy func import.
This commit is contained in:
+56
-5
@@ -1,7 +1,7 @@
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from sqlalchemy import (
|
||||
Column, String, Boolean, DateTime, ForeignKey, Integer, Float, Text, Enum, event, inspect
|
||||
Column, String, Boolean, DateTime, ForeignKey, Integer, Float, Text, Enum, event, inspect, func
|
||||
)
|
||||
import sqlalchemy
|
||||
from sqlalchemy.dialects.mysql import LONGTEXT
|
||||
@@ -387,8 +387,46 @@ class WorkloadHost(BaseModel):
|
||||
"vni": port.network.vni,
|
||||
"workload_host_ip": port.workload.workload_host.ip_address_eastwest
|
||||
})
|
||||
|
||||
return sdn_payload
|
||||
|
||||
return sdn_payload
|
||||
|
||||
def get_resource_utilization(self):
|
||||
"""
|
||||
Computes resource utilization for this workload host.
|
||||
|
||||
Returns a dictionary with resource types as keys, containing available and used quantities.
|
||||
Dynamically based on WorkloadHostPooledResource entries for this host.
|
||||
"""
|
||||
resources = {}
|
||||
|
||||
# Get all pooled resources for this host
|
||||
pooled_resources = self.pooled_resources
|
||||
|
||||
for pooled in pooled_resources:
|
||||
resource_type = pooled.resource_type
|
||||
total_quantity = pooled.total_quantity
|
||||
|
||||
# Sum usage from non-deleted workloads on this host for this resource type
|
||||
used_query = db.session.query(
|
||||
func.sum(WorkloadResourceUsage.quantity).label('total_used')
|
||||
).outerjoin(
|
||||
Workload, Workload.id == WorkloadResourceUsage.workload_id
|
||||
).filter(
|
||||
WorkloadResourceUsage.resource_type == resource_type,
|
||||
Workload.workload_host_id == self.id,
|
||||
Workload.deleted == False
|
||||
)
|
||||
|
||||
quantity_in_use = used_query.scalar() or 0.0
|
||||
|
||||
resources[resource_type] = {
|
||||
'total_quantity': float(total_quantity),
|
||||
'quantity_in_use': float(quantity_in_use)
|
||||
}
|
||||
|
||||
return {
|
||||
'resources': resources
|
||||
}
|
||||
|
||||
class WorkloadHostAvailablePort(BaseModel):
|
||||
__tablename__ = "workload_host_available_ports"
|
||||
@@ -672,9 +710,9 @@ class Workload(BaseModel):
|
||||
Special handler for failed containers
|
||||
"""
|
||||
try:
|
||||
# TODO - What if this is a host failure? Do we just handle every container inviddually or should we aggregate
|
||||
# TODO - What if this is a host failure? Do we just handle every container inviddually or should we aggregate
|
||||
# the event into a host failure event and handle it more intelligently(Might be harder?)
|
||||
|
||||
|
||||
# Attempt to rebuild in place
|
||||
# container.rebuild_in_place()
|
||||
logger.warning("Rebuilding container in place after failure")
|
||||
@@ -697,6 +735,19 @@ class Workload(BaseModel):
|
||||
)
|
||||
raise
|
||||
|
||||
def get_resource_usage(self):
|
||||
"""
|
||||
Returns the resource usage for this workload as a list of dicts.
|
||||
"""
|
||||
usages = WorkloadResourceUsage.query.filter_by(workload_id=self.id).all()
|
||||
return [
|
||||
{
|
||||
"name": usage.resource_type,
|
||||
"used_amount": float(usage.quantity)
|
||||
}
|
||||
for usage in usages
|
||||
]
|
||||
|
||||
class WorkloadHostPortMapping(db.Model):
|
||||
"""
|
||||
Maps container internal ports to external ports on the workload host.
|
||||
|
||||
Reference in New Issue
Block a user