|
24 | 24 | # |
25 | 25 | # Author: Komal Thareja ([email protected]) |
26 | 26 | from datetime import datetime, timezone |
27 | | -from typing import List, Dict, Tuple |
| 27 | +from typing import List, Dict, Tuple, Union |
28 | 28 |
|
29 | 29 | from fim.slivers.maintenance_mode import MaintenanceInfo, MaintenanceState |
30 | 30 |
|
@@ -92,16 +92,56 @@ def is_worker_in_maintenance(self, *, worker: str) -> bool: |
92 | 92 | def __str__(self): |
93 | 93 | return f"Name: {self.name} MaintInfo: {self.maintenance_info} Properties: {self.properties}" |
94 | 94 |
|
| 95 | + def clone_maintenance_info(self) -> Union[MaintenanceInfo or None]: |
| 96 | + if self.maintenance_info is not None: |
| 97 | + return self.maintenance_info.copy() |
| 98 | + return None |
| 99 | + |
| 100 | + def update_maintenance_info(self, maint_info: MaintenanceInfo): |
| 101 | + self.maintenance_info = maint_info |
| 102 | + |
95 | 103 |
|
96 | 104 | class Maintenance: |
97 | 105 | @staticmethod |
98 | 106 | def update_maintenance_mode(*, database: ABCDatabase, properties: Dict[str, str], sites: List[Site] = None): |
| 107 | + """ |
| 108 | + Update Maintenance Mode at Testbed/Site/Worker Level |
| 109 | + - Tesbed level Maintenance - single Site object is passed with Name = ALL |
| 110 | + - Site level Maintenance - single Site object per site is passed with Name = SiteName |
| 111 | + - Worker level Maintenance - single Site object per site with one entry per worker |
| 112 | + @param database database |
| 113 | + @param properties properties container project ids/ user emails |
| 114 | + @param sites Maintenance information for the sites |
| 115 | + """ |
99 | 116 | for s in sites: |
| 117 | + # Set the list of allowed projects/users at the site level |
100 | 118 | if properties is not None: |
101 | 119 | s.set_properties(properties=properties) |
102 | 120 |
|
103 | | - if database.get_site(site_name=s.get_name()) is not None: |
104 | | - database.update_site(site=s) |
| 121 | + # Get Current Maintenance mode for the Site |
| 122 | + existing_site = database.get_site(site_name=s.get_name()) |
| 123 | + # Site entry exists |
| 124 | + if existing_site is not None: |
| 125 | + # Site level Maintenance Update |
| 126 | + if s.get_maintenance_info().get(s.get_name()) is not None: |
| 127 | + database.update_site(site=s) |
| 128 | + # Worker level Maintenance Update |
| 129 | + else: |
| 130 | + new_maint_info = existing_site.clone_maintenance_info() |
| 131 | + if new_maint_info.get(s.get_name()): |
| 132 | + new_maint_info.rem(s.get_name()) |
| 133 | + for worker_name, entry in s.get_maintenance_info().list_details(): |
| 134 | + # Remove existing entry |
| 135 | + if new_maint_info.get(worker_name): |
| 136 | + new_maint_info.rem(worker_name) |
| 137 | + |
| 138 | + # Add worker entry using the new information only if worker is in Maintenance |
| 139 | + if entry.state != MaintenanceState.Active: |
| 140 | + new_maint_info.add(worker_name, entry) |
| 141 | + new_maint_info.finalize() |
| 142 | + existing_site.update_maintenance_info(maint_info=new_maint_info) |
| 143 | + database.update_site(site=existing_site) |
| 144 | + # Adding Maintenance State First Time |
105 | 145 | else: |
106 | 146 | database.add_site(site=s) |
107 | 147 |
|
@@ -137,7 +177,7 @@ def is_sliver_provisioning_allowed(*, database: ABCDatabase, project: str, email |
137 | 177 | """ |
138 | 178 | status, site = Maintenance.is_site_in_maintenance(database=database, site_name=site) |
139 | 179 |
|
140 | | - if not status: |
| 180 | + if not status and site is None: |
141 | 181 | return True, None |
142 | 182 |
|
143 | 183 | projects = site.get_properties().get(Constants.PROJECT_ID) |
|
0 commit comments