17
17
# You should have received a copy of the GNU Affero General Public License
18
18
# along with this program. If not, see <https://www.gnu.org/licenses/>.
19
19
20
- import filecmp
21
20
import os
22
- import time
23
21
import logging
22
+ import time
24
23
from abc import ABC , abstractmethod
25
- from typing import Any , Dict
24
+ from typing import Any , Dict , Optional
26
25
27
26
from core .schains .config .directory import (
28
- upstreams_for_rotation_id_version ,
27
+ config_synced_with_upstream ,
29
28
get_schain_check_filepath ,
30
29
get_schain_config ,
30
+ get_upstream_config_filepath ,
31
31
schain_config_dir ,
32
- schain_config_filepath
32
+ schain_config_filepath ,
33
+ upstreams_for_rotation_id_version ,
33
34
)
34
35
from core .schains .config .helper import (
35
36
get_base_port_from_config ,
36
37
get_node_ips_from_config ,
37
38
get_own_ip_from_config ,
38
39
get_local_schain_http_endpoint
39
40
)
40
- from core .schains .config .main import (
41
- get_upstream_config_filepath ,
42
- get_rotation_ids_from_config_file
43
- )
41
+ from core .schains .config .main import get_config_rotations_ids , get_upstream_rotation_ids
44
42
from core .schains .dkg .utils import get_secret_key_share_filepath
45
43
from core .schains .firewall .types import IRuleController
46
44
from core .schains .process_manager_helper import is_monitor_process_alive
49
47
check_endpoint_blocks ,
50
48
get_endpoint_alive_check_timeout
51
49
)
50
+ from core .schains .external_config import ExternalConfig , ExternalState
52
51
from core .schains .runner import get_container_name
53
52
from core .schains .skaled_exit_codes import SkaledExitCodes
54
53
@@ -113,13 +112,17 @@ def __init__(
113
112
node_id : int ,
114
113
schain_record : SChainRecord ,
115
114
rotation_id : int ,
116
- stream_version : str
115
+ stream_version : str ,
116
+ estate : ExternalState ,
117
+ econfig : Optional [ExternalConfig ] = None
117
118
):
118
119
self .name = schain_name
119
120
self .node_id = node_id
120
121
self .schain_record = schain_record
121
122
self .rotation_id = rotation_id
122
123
self .stream_version = stream_version
124
+ self .estate = estate
125
+ self .econfig = econfig or ExternalConfig (schain_name )
123
126
124
127
def get_all (self , log = True , save = False , checks_filter = None ) -> Dict :
125
128
if checks_filter :
@@ -161,11 +164,18 @@ def upstream_config(self) -> CheckRes:
161
164
self .stream_version
162
165
)
163
166
logger .debug ('Upstream configs for %s: %s' , self .name , upstreams )
164
- return len (upstreams ) > 0 and self .schain_record .config_version == self .stream_version
167
+ return CheckRes (
168
+ len (upstreams ) > 0 and self .schain_record .config_version == self .stream_version
169
+ )
165
170
166
- def is_healthy (self ) -> bool :
167
- checks = self .get_all ()
168
- return False not in checks .values ()
171
+ @property
172
+ def external_state (self ) -> CheckRes :
173
+ actual_state = self .econfig .get ()
174
+ logger .debug (
175
+ 'Checking external config. Current %s. Saved %s' ,
176
+ self .estate , actual_state
177
+ )
178
+ return CheckRes (self .econfig .synced (self .estate ))
169
179
170
180
171
181
class SkaledChecks (IChecks ):
@@ -175,14 +185,14 @@ def __init__(
175
185
schain_record : SChainRecord ,
176
186
rule_controller : IRuleController ,
177
187
* ,
178
- ima_linked : bool = True ,
188
+ econfig : Optional [ ExternalConfig ] = None ,
179
189
dutils : DockerUtils = None
180
190
):
181
191
self .name = schain_name
182
192
self .schain_record = schain_record
183
193
self .dutils = dutils or DockerUtils ()
184
194
self .container_name = get_container_name (SCHAIN_CONTAINER , self .name )
185
- self .ima_linked = ima_linked
195
+ self .econfig = econfig or ExternalConfig ( name = schain_name )
186
196
self .rc = rule_controller
187
197
188
198
def get_all (self , log = True , save = False , checks_filter = None ) -> Dict :
@@ -210,27 +220,20 @@ def upstream_exists(self) -> CheckRes:
210
220
def rotation_id_updated (self ) -> int :
211
221
if not self .config :
212
222
return CheckRes (False )
213
- upstream_path = get_upstream_config_filepath (self .name )
214
- config_path = schain_config_filepath (self .name )
215
- upstream_rotations = get_rotation_ids_from_config_file (upstream_path )
216
- config_rotations = get_rotation_ids_from_config_file (config_path )
223
+ upstream_rotations = get_upstream_rotation_ids (self .name )
224
+ config_rotations = get_config_rotations_ids (self .name )
217
225
logger .debug (
218
- 'Comparing rotation_ids between upstream %s and %s' ,
219
- upstream_path ,
220
- config_path
226
+ 'Comparing rotation_ids. Upstream: %s. Config: %s' ,
227
+ upstream_rotations ,
228
+ config_rotations
221
229
)
222
230
return CheckRes (upstream_rotations == config_rotations )
223
231
224
232
@property
225
233
def config_updated (self ) -> CheckRes :
226
234
if not self .config :
227
235
return CheckRes (False )
228
- upstream_path = get_upstream_config_filepath (self .name )
229
- config_path = schain_config_filepath (self .name )
230
- logger .debug ('Checking if %s updated according to %s' , config_path , upstream_path )
231
- if not upstream_path :
232
- return CheckRes (True )
233
- return CheckRes (filecmp .cmp (upstream_path , config_path ))
236
+ return CheckRes (config_synced_with_upstream (self .name ))
234
237
235
238
@property
236
239
def config (self ) -> CheckRes :
@@ -251,12 +254,14 @@ def firewall_rules(self) -> CheckRes:
251
254
base_port = get_base_port_from_config (conf )
252
255
node_ips = get_node_ips_from_config (conf )
253
256
own_ip = get_own_ip_from_config (conf )
257
+ ranges = self .econfig .ranges
254
258
self .rc .configure (
255
259
base_port = base_port ,
256
260
own_ip = own_ip ,
257
- node_ips = node_ips
261
+ node_ips = node_ips ,
262
+ sync_ip_ranges = ranges
258
263
)
259
- logger .info (f'Rule controller { self .rc .expected_rules ()} ' )
264
+ logger .debug (f'Rule controller { self .rc .expected_rules ()} ' )
260
265
return CheckRes (self .rc .is_rules_synced ())
261
266
return CheckRes (False )
262
267
@@ -277,6 +282,8 @@ def exit_code_ok(self) -> CheckRes:
277
282
@property
278
283
def ima_container (self ) -> CheckRes :
279
284
"""Checks that IMA container is running"""
285
+ if not self .econfig .ima_linked :
286
+ return CheckRes (True )
280
287
name = get_container_name (IMA_CONTAINER , self .name )
281
288
return CheckRes (self .dutils .is_container_running (name ))
282
289
@@ -314,9 +321,10 @@ def __init__(
314
321
schain_record : SChainRecord ,
315
322
rule_controller : IRuleController ,
316
323
stream_version : str ,
324
+ estate : ExternalState ,
317
325
rotation_id : int = 0 ,
318
326
* ,
319
- ima_linked : bool = True ,
327
+ econfig : Optional [ ExternalConfig ] = None ,
320
328
dutils : DockerUtils = None
321
329
):
322
330
self ._subjects = [
@@ -325,13 +333,15 @@ def __init__(
325
333
node_id = node_id ,
326
334
schain_record = schain_record ,
327
335
rotation_id = rotation_id ,
328
- stream_version = stream_version
336
+ stream_version = stream_version ,
337
+ estate = estate ,
338
+ econfig = econfig
329
339
),
330
340
SkaledChecks (
331
341
schain_name = schain_name ,
332
342
schain_record = schain_record ,
333
343
rule_controller = rule_controller ,
334
- ima_linked = ima_linked ,
344
+ econfig = econfig ,
335
345
dutils = dutils
336
346
)
337
347
]
@@ -354,17 +364,16 @@ def get_all(self, log=True, save=False, checks_filter=None):
354
364
checks_filter = checks_filter
355
365
)
356
366
plain_checks .update (subj_checks )
367
+ if not self .estate .ima_linked :
368
+ if 'ima_container' in plain_checks :
369
+ del plain_checks ['ima_container' ]
357
370
358
371
if log :
359
372
log_checks_dict (self .name , plain_checks )
360
373
if save :
361
374
save_checks_dict (self .name , plain_checks )
362
375
return plain_checks
363
376
364
- def is_healthy (self ):
365
- checks = self .get_all ()
366
- return False not in checks .values ()
367
-
368
377
369
378
def save_checks_dict (schain_name , checks_dict ):
370
379
schain_check_path = get_schain_check_filepath (schain_name )
0 commit comments