in source/idea/idea-virtual-desktop-controller/src/ideavirtualdesktopcontroller/app/api/virtual_desktop_api.py [0:0]
def validate_create_session_request(self, session: VirtualDesktopSession) -> (VirtualDesktopSession, bool):
if Utils.is_empty(session.project) or Utils.is_empty(session.project.project_id):
session.failure_reason = 'missing session.project.project_id'
return session, False
# validate if the user belongs to this project
is_user_part_of_project = False
user_projects = self.get_user_projects(username=session.owner)
for project in user_projects:
if project.project_id == session.project.project_id:
is_user_part_of_project = True
session.project = project
break
if not is_user_part_of_project:
session.failure_reason = f'User {session.owner} does not belong in the selected project.'
return session, False
# Validate Software Stack Object
if Utils.is_empty(session.software_stack):
session.failure_reason = 'missing session.software_stack'
return session, False
# Missing information in Software Stack
if Utils.is_empty(session.software_stack.stack_id) or Utils.is_empty(session.software_stack.base_os):
session.failure_reason = 'missing session.software_stack.stack_id and/or session.software_stack.base_os'
return session, False
try:
software_stack_dict = software_stacks.get_software_stack(stack_id=session.software_stack.stack_id, base_os=session.software_stack.base_os)
software_stack = self.software_stack_db.convert_db_dict_to_software_stack_object(software_stack_dict)
except SoftwareStackNotFound:
session.failure_reason = f'Invalid session.software_stack.stack_id: {session.software_stack.stack_id} and/or session.software_stack.base_os: {session.software_stack.base_os}'
return session, False
# validate software stack part of the same project
is_software_stack_part_of_project = False
for project in software_stack.projects:
if project.project_id == session.project.project_id:
is_software_stack_part_of_project = True
break
if not is_software_stack_part_of_project:
session.failure_reason = f'session.software_stack.stack_id: {session.software_stack.stack_id} is not part of session.project.project_id: {session.project.project_id}'
return session, False
# Check the Project budget if we are enabled for budget enforcement
if self.context.config().get_bool('vdc.controller.enforce_project_budgets', default=True):
self._logger.info(f"eVDI Project budgets is enabled. Checking budgets.")
if not session.project.is_budgets_enabled():
self._logger.info(f"Project budget disabled or not configured for {session.project.name}")
else:
project_budget_name = Utils.get_as_string(session.project.budget.budget_name, default=None)
if project_budget_name:
self._logger.debug(f"Found Budget name: {project_budget_name}")
project_budget = self.context.aws_util().budgets_get_budget(budget_name=project_budget_name)
if Utils.is_not_empty(project_budget):
self._logger.debug(f"Budget details: {project_budget}")
if project_budget.actual_spend > project_budget.budget_limit:
self._logger.error(f"Budget exceeded. Denying session request")
session.failure_reason = f"Project {project_budget_name} budget has been exceeded. Unable to start session. Contact your Administrator."
return session, False
else:
self._logger.debug(f"Budget usage is acceptable. Proceeding")
else:
self._logger.info(f"VDI Project budgets are disabled (vdc.controller.enforce_project_budgets). Not checking budgets.")
session.software_stack = software_stack
# Validate hibernation value
if Utils.is_empty(session.hibernation_enabled):
session.failure_reason = 'missing session.hibernation_enabled'
return session, False
# Instance Type validation
if Utils.is_empty(session.server) or Utils.is_empty(session.server.instance_type):
session.failure_reason = 'missing session.server.instance_type'
return session, False
is_instance_type_valid = False
allowed_instance_types = self.controller_utils.get_valid_instance_types_by_software_stack(session.hibernation_enabled, session.software_stack)
for allowed_instance_type in allowed_instance_types:
is_instance_type_valid = session.server.instance_type == Utils.get_value_as_string('InstanceType', allowed_instance_type, '')
if is_instance_type_valid:
break
if not is_instance_type_valid:
session.failure_reason = f'Invalid session.server.instance_type: {session.server.instance_type}. Not allowed for current configuration'
return session, False
# Technical Validation for Hibernation.
if session.hibernation_enabled and session.software_stack.base_os is VirtualDesktopBaseOS.WINDOWS:
ram = self.controller_utils.get_instance_ram(session.server.instance_type).as_unit(SocaMemoryUnit.GiB)
if ram.value > 16:
session.failure_reason = f'OS {session.software_stack.base_os} does not support Instance Hibernation for instances with RAM greater than 16GiB.'
return session, False
else:
pass
# Technical Validations for Session Type
# // https://docs.aws.amazon.com/dcv/latest/adminguide/servers.html - AMD GPU, Windows support Console sessions only
if session.type is VirtualDesktopSessionType.VIRTUAL and session.software_stack.base_os is VirtualDesktopBaseOS.WINDOWS:
session.failure_reason = f'{session.software_stack.base_os} does not support Virtual Sessions'
return session, False
gpu_manufacturer = self.controller_utils.get_gpu_manufacturer(session.server.instance_type)
if session.type is VirtualDesktopSessionType.VIRTUAL and gpu_manufacturer is VirtualDesktopGPU.AMD:
session.failure_reason = f'Instance type: {session.server.instance_type} with GPU {gpu_manufacturer} does not support Virtual Sessions'
return session, False
if session.software_stack.placement and session.software_stack.placement.tenancy == VirtualDesktopTenancy.HOST and not self.controller_utils.dedicated_hosts_supported(session.server.instance_type):
session.failure_reason = f'Instance type: {session.server.instance_type} does not support Dedicated Hosts tenancy'
return session, False
architecture = self.controller_utils.get_architecture(session.server.instance_type)
if session.type is VirtualDesktopSessionType.CONSOLE and architecture is VirtualDesktopArchitecture.ARM64:
session.failure_reason = f'Instance type: {session.server.instance_type} does not support Console Sessions'
return session, False
# Validate Root Volume Size
if Utils.is_empty(session.server) or Utils.is_empty(session.server.root_volume_size):
session.failure_reason = 'missing session.server.root_volume_size'
return session, False
# Business Validation for MAX Root Volume
max_root_volume_size = self.context.config().get_int('virtual-desktop-controller.dcv_session.max_root_volume_memory', required=True)
if session.server.root_volume_size > max_root_volume_size:
session.failure_reason = f'root volume size: {session.server.root_volume_size} is greater than maximum allowed root volume size: {max_root_volume_size}GB.'
return session, False
# Technical Validation for Root Volume
min_root_volume: SocaMemory = software_stack.min_storage
if session.hibernation_enabled:
min_root_volume = software_stack.min_storage + self.controller_utils.get_instance_ram(session.server.instance_type)
if session.server.root_volume_size < min_root_volume:
session.failure_reason = f'root volume size: {session.server.root_volume_size} is less than the minimum required root volume size: {min_root_volume} when hibernation is {"enabled" if session.hibernation_enabled else "disabled"}.'
return session, False
return session, True