python-rac 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pyrac/v8311.py ADDED
@@ -0,0 +1,1400 @@
1
+ import datetime
2
+ import struct
3
+ import io
4
+ import asyncio
5
+ import uuid
6
+ import argparse
7
+ from enum import Enum
8
+ from pprint import pp
9
+
10
+ # 1C 8.3.11 cluster administration endpoint (wire protocol 10.0).
11
+ SERVICE_VERSION = b'10.0'
12
+
13
+
14
+ def main(argv=None):
15
+ # Preserve the original CLI block and its exact argparse surface.
16
+ import runpy
17
+ import sys
18
+ previous = sys.argv
19
+ try:
20
+ sys.argv = [previous[0], *(argv if argv is not None else previous[1:])]
21
+ runpy.run_path(__file__, run_name='__main__')
22
+ finally:
23
+ sys.argv = previous
24
+
25
+
26
+ class MessageException(BaseException):
27
+ def __init__(self, service_id, message):
28
+ self.service_id = service_id
29
+ self.message = message
30
+ super().__init__(self.service_id + ": " + self.message)
31
+
32
+
33
+ class PacketType(Enum):
34
+ NEGOTIATE = b'\x00'
35
+ CONNECT = b'\x01'
36
+ CONNECT_ACK = b'\x02'
37
+ DISCONNECT = b'\x04'
38
+ ENDPOINT_OPEN = b'\x0b'
39
+ ENDPOINT_OPEN_ACK = b'\x0c'
40
+ ENDPOINT_CLOSE = b'\x0d'
41
+ ENDPOINT_MESSAGE = b'\x0e'
42
+ ENDPOINT_FAILURE = b'\x0f'
43
+ KEEP_ALIVE = b'\x10'
44
+
45
+
46
+ class ParamType(Enum):
47
+ UNKNOWN_TYPE = b'\x00'
48
+ BOOLEAN = b'\x01'
49
+ BYTE = b'\x02'
50
+ SHORT = b'\x03'
51
+ INT = b'\x04'
52
+ LONG = b'\x05'
53
+ FLOAT = b'\x06'
54
+ DOUBLE = b'\x07'
55
+ SIZE = b'\x08'
56
+ NULLABLE_SIZE = b'\x09'
57
+ STRING = b'\x0a'
58
+ UUID = b'\x0b'
59
+ TYPE = b'\x0c'
60
+ ENDPOINT_ID = b'\x0d'
61
+
62
+
63
+ class EndpointDataType(Enum):
64
+ VOID_MESSAGE = b'\x00'
65
+ MESSAGE = b'\x01'
66
+ EXCEPTION = b'\xff'
67
+
68
+
69
+ class MessageType(Enum):
70
+ GET_AGENT_ADMINS_REQUEST = chr(0).encode()
71
+ GET_AGENT_ADMINS_RESPONSE = chr(1).encode()
72
+ GET_CLUSTER_ADMINS_REQUEST = chr(2).encode()
73
+ GET_CLUSTER_ADMINS_RESPONSE = chr(3).encode()
74
+ REG_AGENT_ADMIN_REQUEST = chr(4).encode()
75
+ REG_CLUSTER_ADMIN_REQUEST = chr(5).encode()
76
+ UNREG_AGENT_ADMIN_REQUEST = chr(6).encode()
77
+ UNREG_CLUSTER_ADMIN_REQUEST = chr(7).encode()
78
+ AUTHENTICATE_AGENT_REQUEST = chr(8).encode() # Auth on agent
79
+ AUTHENTICATE_REQUEST = chr(9).encode() # Auth on cluster
80
+ ADD_AUTHENTICATION_REQUEST = chr(10).encode() # Auth on infobase
81
+ GET_CLUSTERS_REQUEST = chr(11).encode()
82
+ GET_CLUSTERS_RESPONSE = chr(12).encode()
83
+ GET_CLUSTER_INFO_REQUEST = chr(13).encode()
84
+ GET_CLUSTER_INFO_RESPONSE = chr(14).encode()
85
+ REG_CLUSTER_REQUEST = chr(15).encode()
86
+ REG_CLUSTER_RESPONSE = chr(16).encode()
87
+ UNREG_CLUSTER_REQUEST = chr(17).encode()
88
+ GET_CLUSTER_MANAGERS_REQUEST = chr(18).encode()
89
+ GET_CLUSTER_MANAGERS_RESPONSE = chr(19).encode()
90
+ GET_CLUSTER_MANAGER_INFO_REQUEST = chr(20).encode()
91
+ GET_CLUSTER_MANAGER_INFO_RESPONSE = chr(21).encode()
92
+ GET_WORKING_SERVERS_REQUEST = chr(22).encode()
93
+ GET_WORKING_SERVERS_RESPONSE = chr(23).encode()
94
+ GET_WORKING_SERVER_INFO_REQUEST = chr(24).encode()
95
+ GET_WORKING_SERVER_INFO_RESPONSE = chr(25).encode()
96
+ REG_WORKING_SERVER_REQUEST = chr(26).encode()
97
+ REG_WORKING_SERVER_RESPONSE = chr(27).encode()
98
+ UNREG_WORKING_SERVER_REQUEST = chr(28).encode()
99
+ GET_WORKING_PROCESSES_REQUEST = chr(29).encode()
100
+ GET_WORKING_PROCESSES_RESPONSE = chr(30).encode()
101
+ GET_WORKING_PROCESS_INFO_REQUEST = chr(31).encode()
102
+ GET_WORKING_PROCESS_INFO_RESPONSE = chr(32).encode()
103
+ GET_SERVER_WORKING_PROCESSES_REQUEST = chr(33).encode()
104
+ GET_SERVER_WORKING_PROCESSES_RESPONSE = chr(34).encode()
105
+ GET_CLUSTER_SERVICES_REQUEST = chr(35).encode()
106
+ GET_CLUSTER_SERVICES_RESPONSE = chr(36).encode()
107
+ CREATE_INFOBASE_REQUEST = chr(37).encode()
108
+ CREATE_INFOBASE_RESPONSE = chr(38).encode()
109
+ UPDATE_INFOBASE_SHORT_REQUEST = chr(39).encode()
110
+ UPDATE_INFOBASE_REQUEST = chr(40).encode()
111
+ DROP_INFOBASE_REQUEST = chr(41).encode()
112
+ GET_INFOBASES_SHORT_REQUEST = chr(42).encode()
113
+ GET_INFOBASES_SHORT_RESPONSE = chr(43).encode()
114
+ GET_INFOBASES_REQUEST = chr(44).encode()
115
+ GET_INFOBASES_RESPONSE = chr(45).encode()
116
+ GET_INFOBASE_SHORT_INFO_REQUEST = chr(46).encode()
117
+ GET_INFOBASE_SHORT_INFO_RESPONSE = chr(47).encode()
118
+ GET_INFOBASE_INFO_REQUEST = chr(48).encode()
119
+ GET_INFOBASE_INFO_RESPONSE = chr(49).encode()
120
+ GET_CONNECTIONS_SHORT_REQUEST = chr(50).encode()
121
+ GET_CONNECTIONS_SHORT_RESPONSE = chr(51).encode()
122
+ GET_INFOBASE_CONNECTIONS_SHORT_REQUEST = chr(52).encode()
123
+ GET_INFOBASE_CONNECTIONS_SHORT_RESPONSE = chr(53).encode()
124
+ GET_CONNECTION_INFO_SHORT_REQUEST = chr(54).encode()
125
+ GET_CONNECTION_INFO_SHORT_RESPONSE = chr(55).encode()
126
+ GET_INFOBASE_CONNECTIONS_REQUEST = chr(56).encode()
127
+ GET_INFOBASE_CONNECTIONS_RESPONSE = chr(57).encode()
128
+ # reserved 58 to 63 # Unknown messages types
129
+ DISCONNECT_REQUEST = chr(64).encode()
130
+ GET_SESSIONS_REQUEST = chr(65).encode()
131
+ GET_SESSIONS_RESPONSE = chr(66).encode()
132
+ GET_INFOBASE_SESSIONS_REQUEST = chr(67).encode()
133
+ GET_INFOBASE_SESSIONS_RESPONSE = chr(68).encode()
134
+ GET_SESSION_INFO_REQUEST = chr(69).encode()
135
+ GET_SESSION_INFO_RESPONSE = chr(70).encode()
136
+ TERMINATE_SESSION_REQUEST = chr(71).encode()
137
+ GET_LOCKS_REQUEST = chr(72).encode()
138
+ GET_LOCKS_RESPONSE = chr(73).encode()
139
+ GET_INFOBASE_LOCKS_REQUEST = chr(74).encode()
140
+ GET_INFOBASE_LOCKS_RESPONSE = chr(75).encode()
141
+ GET_CONNECTION_LOCKS_REQUEST = chr(76).encode()
142
+ GET_CONNECTION_LOCKS_RESPONSE = chr(77).encode()
143
+ GET_SESSION_LOCKS_REQUEST = chr(78).encode()
144
+ GET_SESSION_LOCKS_RESPONSE = chr(79).encode()
145
+ # reserved 80 # Unknown messages type
146
+ APPLY_ASSIGNMENT_RULES_REQUEST = chr(81).encode()
147
+ REG_ASSIGNMENT_RULE_REQUEST = chr(82).encode()
148
+ REG_ASSIGNMENT_RULE_RESPONSE = chr(83).encode()
149
+ UNREG_ASSIGNMENT_RULE_REQUEST = chr(84).encode()
150
+ GET_ASSIGNMENT_RULES_REQUEST = chr(85).encode()
151
+ GET_ASSIGNMENT_RULES_RESPONSE = chr(86).encode()
152
+ GET_ASSIGNMENT_RULE_INFO_REQUEST = chr(87).encode()
153
+ GET_ASSIGNMENT_RULE_INFO_RESPONSE = chr(88).encode()
154
+ GET_SECURITY_PROFILES_REQUEST = chr(89).encode()
155
+ GET_SECURITY_PROFILES_RESPONSE = chr(90).encode()
156
+ CREATE_SECURITY_PROFILE_REQUEST = chr(91).encode()
157
+ DROP_SECURITY_PROFILE_REQUEST = chr(92).encode()
158
+ GET_VIRTUAL_DIRECTORIES_REQUEST = chr(93).encode()
159
+ GET_VIRTUAL_DIRECTORIES_RESPONSE = chr(94).encode()
160
+ CREATE_VIRTUAL_DIRECTORY_REQUEST = chr(95).encode()
161
+ DROP_VIRTUAL_DIRECTORY_REQUEST = chr(96).encode()
162
+ GET_COM_CLASSES_REQUEST = chr(97).encode()
163
+ GET_COM_CLASSES_RESPONSE = chr(98).encode()
164
+ CREATE_COM_CLASS_REQUEST = chr(99).encode()
165
+ DROP_COM_CLASS_REQUEST = chr(100).encode()
166
+ GET_ALLOWED_ADDINS_REQUEST = chr(101).encode()
167
+ GET_ALLOWED_ADDINS_RESPONSE = chr(102).encode()
168
+ CREATE_ALLOWED_ADDIN_REQUEST = chr(103).encode()
169
+ DROP_ALLOWED_ADDIN_REQUEST = chr(104).encode()
170
+ GET_EXTERNAL_MODULES_REQUEST = chr(105).encode()
171
+ GET_EXTERNAL_MODULES_RESPONSE = chr(106).encode()
172
+ CREATE_EXTERNAL_MODULE_REQUEST = chr(107).encode()
173
+ DROP_EXTERNAL_MODULE_REQUEST = chr(108).encode()
174
+ GET_ALLOWED_APPLICATIONS_REQUEST = chr(109).encode()
175
+ GET_ALLOWED_APPLICATIONS_RESPONSE = chr(110).encode()
176
+ CREATE_ALLOWED_APPLICATION_REQUEST = chr(111).encode()
177
+ DROP_ALLOWED_APPLICATION_REQUEST = chr(112).encode()
178
+ GET_INTERNET_RESOURCES_REQUEST = chr(113).encode()
179
+ GET_INTERNET_RESOURCES_RESPONSE = chr(114).encode()
180
+ CREATE_INTERNET_RESOURCE_REQUEST = chr(115).encode()
181
+ DROP_INTERNET_RESOURCE_REQUEST = chr(116).encode()
182
+ INTERRUPT_SESSION_CURRENT_SERVER_CALL_REQUEST = chr(117).encode()
183
+ GET_RESOURCE_COUNTERS_REQUEST = chr(118).encode()
184
+ GET_RESOURCE_COUNTERS_RESPONSE = chr(119).encode()
185
+ GET_RESOURCE_COUNTER_INFO_REQUEST = chr(120).encode()
186
+ GET_RESOURCE_COUNTER_INFO_RESPONSE = chr(121).encode()
187
+ REG_RESOURCE_COUNTER_REQUEST = chr(122).encode()
188
+ UNREG_RESOURCE_COUNTER_REQUEST = chr(123).encode()
189
+ GET_RESOURCE_LIMITS_REQUEST = chr(124).encode()
190
+ GET_RESOURCE_LIMITS_RESPONSE = chr(125).encode()
191
+ GET_RESOURCE_LIMIT_INFO_REQUEST = chr(126).encode()
192
+ GET_RESOURCE_LIMIT_INFO_RESPONSE = chr(127).encode()
193
+ REG_RESOURCE_LIMIT_REQUEST = chr(128).encode()
194
+ UNREG_RESOURCE_LIMIT_REQUEST = chr(129).encode()
195
+ GET_COUNTER_VALUES_REQUEST = chr(130).encode()
196
+ GET_COUNTER_VALUES_RESPONSE = chr(131).encode()
197
+ CLEAR_COUNTER_VALUE_REQUEST = chr(132).encode()
198
+ GET_COUNTER_ACCUMULATED_VALUES_REQUEST = chr(133).encode()
199
+ GET_COUNTER_ACCUMULATED_VALUES_RESPONSE = chr(134).encode()
200
+ GET_AGENT_VERSION_REQUEST = chr(135).encode()
201
+ GET_AGENT_VERSION_RESPONSE = chr(136).encode()
202
+
203
+
204
+ def pack_varint_base64(val):
205
+ total = b''
206
+ while val >= 0x40:
207
+ bits = val & 0x3F
208
+ val >>= 6
209
+ total += struct.pack('B', (0x40 | bits))
210
+ bits = val & 0x3F
211
+ total += struct.pack('B', bits)
212
+ return total
213
+
214
+
215
+ def pack_varint_base128(val):
216
+ total = b''
217
+ while val >= 0x80:
218
+ bits = val & 0x7F
219
+ val >>= 7
220
+ total += struct.pack('B', (0x80 | bits))
221
+ bits = val & 0x7F
222
+ total += struct.pack('B', bits)
223
+ return total
224
+
225
+
226
+ async def unpack_varint_base64(stream):
227
+ total = 0
228
+ for shift in (0, 6, 12, 18):
229
+ if type(stream) is io.BytesIO:
230
+ data = stream.read(1)
231
+ else:
232
+ data = await stream.read(1)
233
+ if data == b'':
234
+ return None
235
+ val = data[0]
236
+ total |= ((val & 0x3F) << shift)
237
+ if not val & 0x40:
238
+ if shift and val == 0:
239
+ raise ValueError('Invalid varint')
240
+ return total
241
+ raise ValueError('Invalid varint')
242
+
243
+
244
+ async def unpack_varint_base128(stream):
245
+ total = 0
246
+ for shift in (0, 7, 14, 21):
247
+ if type(stream) is io.BytesIO:
248
+ data = stream.read(1)
249
+ else:
250
+ data = await stream.read(1)
251
+ if data == b'':
252
+ return None
253
+ val = data[0]
254
+ total |= ((val & 0x7F) << shift)
255
+ if not val & 0x80:
256
+ if shift and val == 0:
257
+ raise ValueError('Invalid varint')
258
+ return total
259
+ raise ValueError('Invalid varint')
260
+
261
+
262
+ def varint_prefixed_data_base64(data):
263
+ return pack_varint_base64(len(data)) + data
264
+
265
+
266
+ def read_uuid(reader):
267
+ return uuid.UUID(bytes=reader.read(16))
268
+
269
+
270
+ def read_uint16(reader):
271
+ return struct.unpack('>H', reader.read(2))[0]
272
+
273
+
274
+ def write_uint16(value):
275
+ return struct.pack('>H', value)
276
+
277
+
278
+ def read_int32(reader):
279
+ return struct.unpack('>i', reader.read(4))[0]
280
+
281
+
282
+ def write_int32(value):
283
+ return struct.pack('>i', value)
284
+
285
+
286
+ def read_int64(reader):
287
+ return struct.unpack('>q', reader.read(8))[0]
288
+
289
+
290
+ def write_int64(value):
291
+ return struct.pack('>q', value)
292
+
293
+
294
+ async def read_bytes(reader):
295
+ length = await unpack_varint_base64(reader)
296
+ if length is None or length > 4_000_000:
297
+ raise ValueError('Invalid field length')
298
+ data = reader.read(length)
299
+ if len(data) != length:
300
+ raise ValueError('Truncated field')
301
+ return data
302
+
303
+
304
+ async def read_string(reader):
305
+ return (await read_bytes(reader)).decode()
306
+
307
+
308
+ def read_bool(reader):
309
+ value = reader.read(1)
310
+ if value not in (b'\x00', b'\x01'):
311
+ raise ValueError('Invalid boolean')
312
+ return value == b'\x01'
313
+
314
+
315
+ def write_bool(value):
316
+ return b'\x01' if value == 1 or value is True else b'\x00'
317
+
318
+
319
+ def read_double(reader):
320
+ return struct.unpack('>d', reader.read(8))[0]
321
+
322
+
323
+ def write_double(value):
324
+ return struct.pack('>d', value)
325
+
326
+
327
+ def age_delta():
328
+ return 621355968000000
329
+
330
+
331
+ def date_from_int64(value):
332
+ if not value:
333
+ return None
334
+ return datetime.datetime.fromtimestamp((value - age_delta()) / 10000, datetime.timezone.utc)
335
+
336
+
337
+ def date_to_int64(value):
338
+ if not value:
339
+ return 0
340
+ return int(value.timestamp() * 10000 + age_delta())
341
+
342
+
343
+ class Packet:
344
+ def __init__(self, packet_type, message_type=None):
345
+ self.data = []
346
+ self.type = packet_type
347
+ if packet_type == PacketType.ENDPOINT_MESSAGE:
348
+ self.append_header()
349
+ self.append_raw(message_type.value)
350
+
351
+ def append(self, element):
352
+ self.data.append(varint_prefixed_data_base64(element))
353
+
354
+ def append_raw(self, element):
355
+ self.data.append(element)
356
+
357
+ def append_header(self):
358
+ self.append_raw(b'\x01\x00\x00\x01')
359
+
360
+ def get_parts(self):
361
+ body = b''.join(self.data)
362
+ if self.type != PacketType.ENDPOINT_MESSAGE:
363
+ body += b'\x80'
364
+ packet_length = pack_varint_base128(len(body))
365
+ header = self.type.value + packet_length
366
+ return header, body
367
+
368
+
369
+ async def read_cluster(packet):
370
+ cluster = {}
371
+ cluster['cluster'] = read_uuid(packet)
372
+ cluster['expiration-timeout'] = read_int32(packet)
373
+ cluster['host'] = await read_string(packet)
374
+ cluster['lifetime-limit'] = read_int32(packet)
375
+ cluster['port'] = read_uint16(packet)
376
+ cluster['max-memory-size'] = read_int32(packet) # deprecated
377
+ cluster['max-memory-time-limit'] = read_int32(packet) # deprecated
378
+ cluster['name'] = await read_string(packet)
379
+ cluster['security-level'] = read_int32(packet)
380
+ cluster['session-fault-tolerance-level'] = read_int32(packet)
381
+ cluster['load-balancing-mode'] = 'performance' if read_int32(packet) == 0 else 'memory'
382
+ cluster['errors-count-threshold'] = read_int32(packet) # deprecated
383
+ cluster['kill-problem-processes'] = int(read_bool(packet))
384
+ cluster['kill-by-memory-with-dump'] = int(read_bool(packet))
385
+ return cluster
386
+
387
+
388
+ def write_cluster(cluster, packet):
389
+ packet.append_raw(cluster['cluster'].bytes)
390
+ packet.append_raw(write_int32(cluster['expiration-timeout']))
391
+ packet.append(cluster['host'].encode())
392
+ packet.append_raw(write_int32(cluster['lifetime-limit']))
393
+ packet.append_raw(write_uint16(cluster['port']))
394
+ packet.append_raw(write_int32(cluster['max-memory-size']))
395
+ packet.append_raw(write_int32(cluster['max-memory-time-limit']))
396
+ packet.append(cluster['name'].encode())
397
+ packet.append_raw(write_int32(cluster['security-level']))
398
+ packet.append_raw(write_int32(cluster['session-fault-tolerance-level']))
399
+ packet.append_raw(write_int32(0 if cluster['load-balancing-mode'] == 'performance' else 1))
400
+ packet.append_raw(write_int32(cluster['errors-count-threshold']))
401
+ packet.append_raw(write_bool(cluster['kill-problem-processes']))
402
+ packet.append_raw(write_bool(cluster['kill-by-memory-with-dump']))
403
+
404
+
405
+ async def read_infobase(packet):
406
+ infobase = {}
407
+ infobase['infobase'] = read_uuid(packet)
408
+ infobase['date_offset'] = read_int32(packet)
409
+ infobase['dbms'] = await read_string(packet)
410
+ infobase['db_name'] = await read_string(packet)
411
+ infobase['db_password'] = await read_bytes(packet)
412
+ infobase['db_server_name'] = await read_string(packet)
413
+ infobase['db_user'] = await read_string(packet)
414
+ infobase['denied_from'] = date_from_int64(read_int64(packet))
415
+ infobase['denied_message'] = await read_string(packet)
416
+ infobase['denied_parameter'] = await read_string(packet)
417
+ infobase['denied_to'] = date_from_int64(read_int64(packet))
418
+ infobase['descr'] = await read_string(packet)
419
+ infobase['locale'] = await read_string(packet)
420
+ infobase['name'] = await read_string(packet)
421
+ infobase['permission_code'] = await read_string(packet)
422
+ infobase['scheduled_jobs_denied'] = read_bool(packet)
423
+ infobase['security_level'] = read_int32(packet)
424
+ infobase['sessions_denied'] = read_bool(packet)
425
+ infobase['license_distribution'] = read_int32(packet)
426
+ infobase['external_connection_string'] = await read_string(packet)
427
+ infobase['external_session_manager_required'] = read_bool(packet)
428
+ infobase['securirty_profile'] = await read_string(packet)
429
+ infobase['safe_mode_securirty_profile'] = await read_string(packet)
430
+ infobase['reserve_working_processes'] = read_bool(packet)
431
+ return infobase
432
+
433
+
434
+ def write_infobase(infobase, packet):
435
+ packet.append_raw(infobase['infobase'].bytes)
436
+ packet.append_raw(write_int32(infobase['date_offset']))
437
+ packet.append(infobase['dbms'].encode())
438
+ packet.append(infobase['db_name'].encode())
439
+ packet.append(infobase['db_password'])
440
+ packet.append(infobase['db_server_name'].encode())
441
+ packet.append(infobase['db_user'].encode())
442
+ packet.append_raw(write_int64(date_to_int64(infobase['denied_from'])))
443
+ packet.append(infobase['denied_message'].encode())
444
+ packet.append(infobase['denied_parameter'].encode())
445
+ packet.append_raw(write_int64(date_to_int64(infobase['denied_to'])))
446
+ packet.append(infobase['descr'].encode())
447
+ packet.append(infobase['locale'].encode())
448
+ packet.append(infobase['name'].encode())
449
+ packet.append(infobase['permission_code'].encode())
450
+ packet.append_raw(write_bool(infobase['scheduled_jobs_denied']))
451
+ packet.append_raw(write_int32(infobase['security_level']))
452
+ packet.append_raw(write_bool(infobase['sessions_denied']))
453
+ packet.append_raw(write_int32(infobase['license_distribution']))
454
+ packet.append(infobase['external_connection_string'].encode())
455
+ packet.append_raw(write_bool(infobase['external_session_manager_required']))
456
+ packet.append(infobase['securirty_profile'].encode())
457
+ packet.append(infobase['safe_mode_securirty_profile'].encode())
458
+ packet.append_raw(write_bool(infobase['reserve_working_processes']))
459
+
460
+
461
+ async def read_infobase_short(packet):
462
+ infobase = {}
463
+ infobase['infobase'] = read_uuid(packet)
464
+ infobase['descr'] = await read_string(packet)
465
+ infobase['name'] = await read_string(packet)
466
+ return infobase
467
+
468
+
469
+ async def read_session(packet):
470
+ session = {}
471
+ session['session_id'] = read_uuid(packet)
472
+ session['app_id'] = await read_string(packet)
473
+ session['blocked_by_dbms'] = read_int32(packet)
474
+ session['blocked_by_ls'] = read_int32(packet)
475
+ session['bytes_all'] = read_int64(packet)
476
+ session['bytes_last5min'] = read_int64(packet)
477
+ session['calls_all'] = read_int32(packet)
478
+ session['calls_last5min'] = read_int64(packet)
479
+ session['connection_id'] = read_uuid(packet)
480
+ session['dbms_bytes_all'] = read_int64(packet)
481
+ session['dbms_bytes_last5min'] = read_int64(packet)
482
+ session['db_proc_info'] = await read_string(packet)
483
+ session['db_proc_took'] = read_int32(packet)
484
+ session['db_proc_took_at'] = read_int64(packet)
485
+ session['duration_all'] = read_int32(packet)
486
+ session['duration_all_dbms'] = read_int32(packet)
487
+ session['duration_current'] = read_int32(packet)
488
+ session['duration_current_dbms'] = read_int32(packet)
489
+ session['duration_last_5_min'] = read_int64(packet)
490
+ session['duration_last_5_min_dbms'] = read_int64(packet)
491
+ session['host'] = await read_string(packet)
492
+ session['infobase_id'] = read_uuid(packet)
493
+ session['last_active_at'] = read_int64(packet)
494
+ session['hibernate'] = read_bool(packet)
495
+ session['passive_session_hibernate_time'] = read_int32(packet)
496
+ session['hibernate_session_terminate_time'] = read_int32(packet)
497
+ session['licenses'] = []
498
+ lic_count = await unpack_varint_base64(packet)
499
+ if lic_count is None or lic_count > 1000:
500
+ raise ValueError('Invalid license count')
501
+ for lic_number in range(lic_count):
502
+ lic = {}
503
+ lic['full_name'] = await read_string(packet)
504
+ lic['full_presentation'] = await read_string(packet)
505
+ lic['issued_by_server'] = read_bool(packet)
506
+ lic['license_type'] = read_int32(packet)
507
+ lic['max_users_all'] = read_int32(packet)
508
+ lic['max_users_cur'] = read_int32(packet)
509
+ lic['net'] = read_bool(packet)
510
+ lic['rmngr_address'] = await read_string(packet)
511
+ lic['rmngr_pid'] = await read_string(packet)
512
+ lic['rmngr_port'] = read_int32(packet)
513
+ lic['series'] = await read_string(packet)
514
+ lic['short_presentation'] = await read_string(packet)
515
+ session['licenses'].append(lic)
516
+ session['locale'] = await read_string(packet)
517
+ session['process_id'] = read_uuid(packet)
518
+ session['id'] = read_int32(packet)
519
+ session['started_at'] = read_int64(packet)
520
+ session['user_name'] = await read_string(packet)
521
+ # version >= 4
522
+ session['memory_current'] = read_int64(packet)
523
+ session['memory_last5min'] = read_int64(packet)
524
+ session['memory_total'] = read_int64(packet)
525
+ session['read_current'] = read_int64(packet)
526
+ session['read_last5min'] = read_int64(packet)
527
+ session['read_total'] = read_int64(packet)
528
+ session['write_current'] = read_int64(packet)
529
+ session['write_last5min'] = read_int64(packet)
530
+ session['write_total'] = read_int64(packet)
531
+ # version >= 5
532
+ session['duration_current_service'] = read_int32(packet)
533
+ session['duration_last5min_service'] = read_int64(packet)
534
+ session['duration_all_service'] = read_int32(packet)
535
+ session['current_service_name'] = await read_string(packet)
536
+ # version >= 6
537
+ session['cpu_time_current'] = read_int64(packet)
538
+ session['cpu_time_last5min'] = read_int64(packet)
539
+ session['cpu_time_total'] = read_int64(packet)
540
+ # version >= 7
541
+ session['data_separation'] = await read_string(packet)
542
+ # version >= 10
543
+ session['client_ip_address'] = await read_string(packet)
544
+ return session
545
+
546
+
547
+ async def read_user(packet):
548
+ user = {}
549
+ user['name'] = await read_string(packet)
550
+ user['descr'] = await read_string(packet)
551
+ user['password'] = await read_bytes(packet)
552
+ user['password_auth_allowed'] = read_bool(packet)
553
+ user['sys_auth_allowed'] = read_bool(packet)
554
+ user['sys_user_name'] = await read_string(packet)
555
+ return user
556
+
557
+
558
+ def write_user(user, packet):
559
+ packet.append(user['name'].encode())
560
+ packet.append(user['descr'].encode())
561
+ packet.append(user['password'].encode())
562
+ packet.append_raw(write_bool(user['password_auth_allowed']))
563
+ packet.append_raw(write_bool(user['sys_auth_allowed']))
564
+ packet.append(user['sys_user_name'].encode())
565
+
566
+
567
+ async def read_server(packet):
568
+ server = {}
569
+ server['working_server_id'] = read_uuid(packet)
570
+ server['host_name'] = await read_string(packet)
571
+ server['main_port'] = read_uint16(packet)
572
+ server['name'] = await read_string(packet)
573
+ server['main_server'] = read_bool(packet)
574
+ server['safe_working_processes_memory_limit'] = read_int64(packet)
575
+ server['safe_call_memory_limit'] = read_int64(packet)
576
+ server['infobases_per_working_process_limit'] = read_int32(packet)
577
+ server['working_process_memory_limit'] = read_int64(packet)
578
+ server['connections_per_working_process_limit'] = read_int32(packet)
579
+ server['cluster_main_port'] = read_uint16(packet)
580
+ server['dedicated_managers'] = read_bool(packet)
581
+ server['port_ranges'] = await read_port_ranges(packet)
582
+ # version >= 8
583
+ server['critical_processes_total_memory'] = read_int64(packet)
584
+ server['temporary_allowed_processes_total_memory'] = read_int64(packet)
585
+ server['temporary_allowed_processes_total_memory_time_limit'] = read_int64(packet)
586
+ return server
587
+
588
+
589
+ async def read_port_ranges(packet):
590
+ ranges_array = []
591
+ ras_data_count = await unpack_varint_base128(packet)
592
+ if ras_data_count is None or ras_data_count > 1000:
593
+ raise ValueError('Invalid port range count')
594
+ for ras_data_number in range(ras_data_count):
595
+ port_max = read_uint16(packet)
596
+ port_min = read_uint16(packet)
597
+ ranges_array.append((port_min, port_max))
598
+ return ranges_array
599
+
600
+
601
+ def write_server(server, packet):
602
+ packet.append_raw(server['working_server_id'].bytes)
603
+ packet.append(server['host_name'].encode())
604
+ packet.append_raw(write_uint16(server['main_port']))
605
+ packet.append(server['name'].encode())
606
+ packet.append_raw(write_bool(server['main_server']))
607
+ packet.append_raw(write_int64(server['safe_working_processes_memory_limit']))
608
+ packet.append_raw(write_int64(server['safe_call_memory_limit']))
609
+ packet.append_raw(write_int32(server['infobases_per_working_process_limit']))
610
+ packet.append_raw(write_int64(server['working_process_memory_limit']))
611
+ packet.append_raw(write_int32(server['connections_per_working_process_limit']))
612
+ packet.append_raw(write_uint16(server['cluster_main_port']))
613
+ packet.append_raw(write_bool(server['dedicated_managers']))
614
+ write_port_ranges(server['port_ranges'], packet)
615
+ # version >= 8
616
+ packet.append_raw(write_int64(server['critical_processes_total_memory']))
617
+ packet.append_raw(write_int64(server['temporary_allowed_processes_total_memory']))
618
+ packet.append_raw(write_int64(server['temporary_allowed_processes_total_memory_time_limit']))
619
+
620
+
621
+ def write_port_ranges(ranges_array, packet):
622
+ packet.append_raw(pack_varint_base128(len(ranges_array)))
623
+ for port_range in ranges_array:
624
+ packet.append_raw(write_uint16(port_range[1]))
625
+ packet.append_raw(write_uint16(port_range[0]))
626
+
627
+
628
+ async def read_packet(reader):
629
+ packet_type = PacketType(await reader.readexactly(1))
630
+ packet_size = 0
631
+ for shift in (0, 7, 14, 21):
632
+ byte = (await reader.readexactly(1))[0]
633
+ packet_size |= (byte & 0x7f) << shift
634
+ if packet_size > 4_000_000:
635
+ raise ValueError('Invalid frame length')
636
+ if not byte & 0x80:
637
+ if shift and byte == 0:
638
+ raise ValueError('Invalid frame length')
639
+ break
640
+ else:
641
+ raise ValueError('Invalid frame length')
642
+ packet_data = await reader.readexactly(packet_size)
643
+ packet = io.BytesIO(packet_data)
644
+ packet_array = []
645
+ if packet_type == PacketType.CONNECT_ACK:
646
+ if packet_data != b'\x80':
647
+ raise ValueError('Invalid connection acknowledgement')
648
+ elif packet_type == PacketType.ENDPOINT_OPEN_ACK:
649
+ packet_array.append(await read_bytes(packet))
650
+ packet_array.append(await read_bytes(packet))
651
+ endpoint_id = await unpack_varint_base64(packet)
652
+ if endpoint_id is None or packet.read() != b'\x80':
653
+ raise ValueError('Invalid endpoint acknowledgement')
654
+ packet_array.append(endpoint_id)
655
+ elif packet_type == PacketType.ENDPOINT_FAILURE:
656
+ service_id = await read_string(packet)
657
+ version = await read_string(packet)
658
+ endpoint_id = await unpack_varint_base128(packet)
659
+ class_cause = await read_bytes(packet)
660
+ message = await read_string(packet)
661
+ if packet.read(1):
662
+ raise ValueError('Trailing endpoint data')
663
+ raise MessageException(service_id, message)
664
+ elif packet_type == PacketType.ENDPOINT_MESSAGE:
665
+ endpoint_id = await unpack_varint_base128(packet)
666
+ endpoint_format = packet.read(2)
667
+ if endpoint_id is None or endpoint_format != b'\x00\x00':
668
+ raise ValueError('Invalid endpoint message header')
669
+ raw_data_type = packet.read(1)
670
+ if len(raw_data_type) != 1:
671
+ raise ValueError('Invalid endpoint message header')
672
+ endpoint_data_type = EndpointDataType(raw_data_type)
673
+ if endpoint_data_type == EndpointDataType.EXCEPTION:
674
+ service_id = await read_string(packet)
675
+ message = await read_string(packet)
676
+ if packet.read(1):
677
+ raise ValueError('Trailing endpoint data')
678
+ raise MessageException(service_id, message)
679
+ if endpoint_data_type == EndpointDataType.MESSAGE:
680
+ raw_ras_data_type = packet.read(1)
681
+ ras_data_type = MessageType(raw_ras_data_type)
682
+ if ras_data_type == MessageType.GET_CLUSTER_INFO_RESPONSE:
683
+ cluster = await read_cluster(packet)
684
+ packet_array.append(cluster)
685
+ elif ras_data_type == MessageType.GET_INFOBASE_INFO_RESPONSE:
686
+ infobase = await read_infobase(packet)
687
+ packet_array.append(infobase)
688
+ elif ras_data_type == MessageType.GET_WORKING_SERVER_INFO_RESPONSE:
689
+ server = await read_server(packet)
690
+ packet_array.append(server)
691
+ elif ras_data_type in [MessageType.CREATE_INFOBASE_RESPONSE, MessageType.REG_WORKING_SERVER_RESPONSE]:
692
+ packet_array.append(read_uuid(packet))
693
+ else:
694
+ supported_lists = (MessageType.GET_CLUSTERS_RESPONSE,
695
+ MessageType.GET_INFOBASES_SHORT_RESPONSE,
696
+ MessageType.GET_INFOBASE_SESSIONS_RESPONSE,
697
+ MessageType.GET_SESSIONS_RESPONSE,
698
+ MessageType.GET_CLUSTER_ADMINS_RESPONSE,
699
+ MessageType.GET_AGENT_ADMINS_RESPONSE,
700
+ MessageType.GET_WORKING_SERVERS_RESPONSE)
701
+ if ras_data_type not in supported_lists:
702
+ raise ValueError('Unsupported endpoint response')
703
+ ras_data_count = await unpack_varint_base128(packet)
704
+ if ras_data_count is None or ras_data_count > 1000:
705
+ raise ValueError('Invalid record count')
706
+ for ras_data_number in range(ras_data_count):
707
+ if ras_data_type == MessageType.GET_CLUSTERS_RESPONSE:
708
+ cluster = await read_cluster(packet)
709
+ packet_array.append(cluster)
710
+ elif ras_data_type == MessageType.GET_INFOBASES_SHORT_RESPONSE:
711
+ infobase = await read_infobase_short(packet)
712
+ packet_array.append(infobase)
713
+ elif ras_data_type in [MessageType.GET_INFOBASE_SESSIONS_RESPONSE,
714
+ MessageType.GET_SESSIONS_RESPONSE]:
715
+ session = await read_session(packet)
716
+ packet_array.append(session)
717
+ elif ras_data_type in [MessageType.GET_CLUSTER_ADMINS_RESPONSE,
718
+ MessageType.GET_AGENT_ADMINS_RESPONSE]:
719
+ user = await read_user(packet)
720
+ packet_array.append(user)
721
+ elif ras_data_type == MessageType.GET_WORKING_SERVERS_RESPONSE:
722
+ server = await read_server(packet)
723
+ packet_array.append(server)
724
+ if packet.read(1):
725
+ raise ValueError('Trailing endpoint data')
726
+
727
+ return packet_type, packet_array
728
+
729
+
730
+ def send_packet(writer, packet):
731
+ header, body = packet.get_parts()
732
+ writer.write(header)
733
+ writer.write(body)
734
+
735
+
736
+ def validate_endpoint_response(packet_type):
737
+ if packet_type != PacketType.ENDPOINT_MESSAGE:
738
+ raise ValueError('Invalid endpoint response')
739
+
740
+
741
+ async def ras_command(ras_args):
742
+ reader, writer = await asyncio.open_connection(ras_args.ras_host, ras_args.ras_port)
743
+ try:
744
+ return await _ras_command_connected(ras_args, reader, writer)
745
+ finally:
746
+ writer.close()
747
+ try:
748
+ async with asyncio.timeout(1):
749
+ await writer.wait_closed()
750
+ except (OSError, TimeoutError):
751
+ # Never replace the request failure with a stalled socket shutdown.
752
+ pass
753
+
754
+
755
+ async def _ras_command_connected(ras_args, reader, writer):
756
+ data = struct.pack(">ihh", 475223888, 256, 256) # magic numbers voodoo numbers
757
+ writer.write(data)
758
+ packet = Packet(PacketType.CONNECT)
759
+ packet.append_raw(b'\x01')
760
+ packet.append(b'connect.timeout')
761
+ packet.append_raw(ParamType.INT.value + struct.pack(">i", 2000))
762
+ send_packet(writer, packet)
763
+ packet_type, packet_array = await read_packet(reader)
764
+ if packet_type != PacketType.CONNECT_ACK or packet_array != []:
765
+ raise ValueError('Invalid connection acknowledgement')
766
+
767
+ packet = Packet(PacketType.ENDPOINT_OPEN)
768
+ packet.append(b'v8.service.Admin.Cluster')
769
+ packet.append(SERVICE_VERSION)
770
+ send_packet(writer, packet)
771
+ packet_type, packet_array = await read_packet(reader)
772
+ if (packet_type != PacketType.ENDPOINT_OPEN_ACK or len(packet_array) != 3
773
+ or packet_array[0] != b'v8.service.Admin.Cluster'
774
+ or packet_array[1] != SERVICE_VERSION):
775
+ raise ValueError('Invalid endpoint acknowledgement')
776
+ endpoint_id = packet_array[2]
777
+
778
+ if (hasattr(ras_args, 'agent_user') and hasattr(ras_args, 'agent_pwd')
779
+ and ras_args.agent_user is not None and ras_args.agent_pwd is not None):
780
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.AUTHENTICATE_AGENT_REQUEST)
781
+ packet.append(ras_args.agent_user.encode())
782
+ packet.append(ras_args.agent_pwd.encode())
783
+ send_packet(writer, packet)
784
+ packet_type, packet_array = await read_packet(reader)
785
+ validate_endpoint_response(packet_type)
786
+
787
+ if (hasattr(ras_args, 'cluster_user') and hasattr(ras_args, 'cluster_pwd')
788
+ and ras_args.cluster_user is not None and ras_args.cluster_pwd is not None):
789
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.AUTHENTICATE_REQUEST)
790
+ packet.append_raw(uuid.UUID(ras_args.cluster).bytes)
791
+ packet.append(ras_args.cluster_user.encode())
792
+ packet.append(ras_args.cluster_pwd.encode())
793
+ send_packet(writer, packet)
794
+ packet_type, packet_array = await read_packet(reader)
795
+ validate_endpoint_response(packet_type)
796
+
797
+ if ras_args.command == 'agent':
798
+ if ras_args.subcommand1 == 'admin':
799
+ if ras_args.subcommand2 == 'list':
800
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.GET_AGENT_ADMINS_REQUEST)
801
+ send_packet(writer, packet)
802
+ packet_type, packet_array = await read_packet(reader)
803
+ validate_endpoint_response(packet_type)
804
+ pp(packet_array)
805
+ elif ras_args.subcommand2 == 'register':
806
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.REG_AGENT_ADMIN_REQUEST)
807
+ user = {}
808
+ user['name'] = ras_args.name
809
+ user['descr'] = ras_args.descr
810
+ user['password'] = ras_args.pwd
811
+ user['password_auth_allowed'] = "pwd" in ras_args.auth
812
+ user['sys_auth_allowed'] = "os" in ras_args.auth
813
+ user['sys_user_name'] = ras_args.os_user
814
+ write_user(user, packet)
815
+ send_packet(writer, packet)
816
+ packet_type, packet_array = await read_packet(reader)
817
+ validate_endpoint_response(packet_type)
818
+ elif ras_args.subcommand2 == 'remove':
819
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.UNREG_AGENT_ADMIN_REQUEST)
820
+ packet.append(ras_args.name.encode())
821
+ send_packet(writer, packet)
822
+ packet_type, packet_array = await read_packet(reader)
823
+ validate_endpoint_response(packet_type)
824
+
825
+ if ras_args.command == 'cluster':
826
+ if ras_args.subcommand1 == 'list':
827
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.GET_CLUSTERS_REQUEST)
828
+ send_packet(writer, packet)
829
+ packet_type, packet_array = await read_packet(reader)
830
+ validate_endpoint_response(packet_type)
831
+ pp(packet_array)
832
+ elif ras_args.subcommand1 == 'info' or ras_args.subcommand1 == 'update':
833
+ cluster_id = uuid.UUID(ras_args.cluster).bytes
834
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.GET_CLUSTER_INFO_REQUEST)
835
+ packet.append_raw(cluster_id)
836
+ send_packet(writer, packet)
837
+ packet_type, packet_array = await read_packet(reader)
838
+ validate_endpoint_response(packet_type)
839
+ if ras_args.subcommand1 == 'info':
840
+ pp(packet_array)
841
+ else:
842
+ cluster = packet_array[0]
843
+ if ras_args.lifetime_limit is not None:
844
+ cluster['lifetime-limit'] = ras_args.lifetime_limit
845
+ if ras_args.expiration_timeout is not None:
846
+ cluster['expiration-timeout'] = ras_args.expiration_timeout
847
+ if ras_args.name is not None:
848
+ cluster['name'] = ras_args.name
849
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.REG_CLUSTER_REQUEST)
850
+ write_cluster(cluster, packet)
851
+ send_packet(writer, packet)
852
+ packet_type, packet_array = await read_packet(reader)
853
+ validate_endpoint_response(packet_type)
854
+ elif ras_args.subcommand1 == 'admin':
855
+ if ras_args.subcommand2 == 'list':
856
+ cluster_id = uuid.UUID(ras_args.cluster).bytes
857
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.GET_CLUSTER_ADMINS_REQUEST)
858
+ packet.append_raw(cluster_id)
859
+ send_packet(writer, packet)
860
+ packet_type, packet_array = await read_packet(reader)
861
+ validate_endpoint_response(packet_type)
862
+ pp(packet_array)
863
+ elif ras_args.subcommand2 == 'register':
864
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.REG_CLUSTER_ADMIN_REQUEST)
865
+ packet.append_raw(uuid.UUID(ras_args.cluster).bytes)
866
+ user = {}
867
+ user['name'] = ras_args.name
868
+ user['descr'] = ras_args.descr
869
+ user['password'] = ras_args.pwd
870
+ user['password_auth_allowed'] = "pwd" in ras_args.auth
871
+ user['sys_auth_allowed'] = "os" in ras_args.auth
872
+ user['sys_user_name'] = ras_args.os_user
873
+ write_user(user, packet)
874
+ send_packet(writer, packet)
875
+ packet_type, packet_array = await read_packet(reader)
876
+ validate_endpoint_response(packet_type)
877
+ elif ras_args.subcommand2 == 'remove':
878
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.UNREG_CLUSTER_ADMIN_REQUEST)
879
+ packet.append_raw(uuid.UUID(ras_args.cluster).bytes)
880
+ packet.append(ras_args.name.encode())
881
+ send_packet(writer, packet)
882
+ packet_type, packet_array = await read_packet(reader)
883
+ validate_endpoint_response(packet_type)
884
+
885
+ if ras_args.command == 'infobase':
886
+ cluster_id = uuid.UUID(ras_args.cluster).bytes
887
+ if ras_args.subcommand1 == 'summary' and ras_args.subcommand2 == 'list':
888
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.GET_INFOBASES_SHORT_REQUEST)
889
+ packet.append_raw(cluster_id)
890
+ send_packet(writer, packet)
891
+ packet_type, packet_array = await read_packet(reader)
892
+ validate_endpoint_response(packet_type)
893
+ pp(packet_array)
894
+
895
+ if hasattr(ras_args, 'infobase_user') and hasattr(ras_args,
896
+ 'infobase_pwd') and ras_args.infobase_user is not None and ras_args.infobase_pwd is not None:
897
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.ADD_AUTHENTICATION_REQUEST)
898
+ packet.append_raw(cluster_id)
899
+ packet.append(ras_args.infobase_user.encode())
900
+ packet.append(ras_args.infobase_pwd.encode())
901
+ send_packet(writer, packet)
902
+ packet_type, packet_array = await read_packet(reader)
903
+ validate_endpoint_response(packet_type)
904
+
905
+ if ras_args.subcommand1 == 'create':
906
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.CREATE_INFOBASE_REQUEST)
907
+ packet.append_raw(cluster_id)
908
+ infobase = {}
909
+ infobase['infobase'] = uuid.UUID(int=0)
910
+ infobase['date_offset'] = ras_args.date_offset
911
+ infobase['dbms'] = ras_args.dbms
912
+ infobase['db_name'] = ras_args.db_name
913
+ infobase['db_password'] = ras_args.db_pwd.encode()
914
+ infobase['db_server_name'] = ras_args.db_server
915
+ infobase['db_user'] = ras_args.db_user
916
+ infobase['denied_from'] = None
917
+ infobase['denied_message'] = ''
918
+ infobase['denied_parameter'] = ''
919
+ infobase['denied_to'] = None
920
+ infobase['descr'] = ras_args.descr
921
+ infobase['locale'] = ras_args.locale
922
+ infobase['name'] = ras_args.name
923
+ infobase['permission_code'] = ''
924
+ infobase['scheduled_jobs_denied'] = ras_args.scheduled_jobs_deny == 'on'
925
+ infobase['security_level'] = ras_args.security_level
926
+ infobase['sessions_denied'] = False
927
+ infobase['license_distribution'] = int(ras_args.license_distribution == 'allow')
928
+ infobase['external_connection_string'] = ""
929
+ infobase['external_session_manager_required'] = False
930
+ infobase['securirty_profile'] = ""
931
+ infobase['safe_mode_securirty_profile'] = ""
932
+ infobase['reserve_working_processes'] = False
933
+ write_infobase(infobase, packet)
934
+ packet.append_raw(write_int32(int(ras_args.create_database)))
935
+ send_packet(writer, packet)
936
+ packet_type, packet_array = await read_packet(reader)
937
+ validate_endpoint_response(packet_type)
938
+ pp(packet_array)
939
+
940
+ if ras_args.subcommand1 == 'drop':
941
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.DROP_INFOBASE_REQUEST)
942
+ packet.append_raw(cluster_id)
943
+ packet.append_raw(uuid.UUID(ras_args.infobase).bytes)
944
+ mode = 0
945
+ if ras_args.drop_database:
946
+ mode = 1
947
+ elif ras_args.clear_database:
948
+ mode = 2
949
+ packet.append_raw(write_int32(mode))
950
+ send_packet(writer, packet)
951
+ packet_type, packet_array = await read_packet(reader)
952
+ validate_endpoint_response(packet_type)
953
+
954
+ if ras_args.subcommand1 == 'info' or ras_args.subcommand1 == 'update':
955
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.GET_INFOBASE_INFO_REQUEST)
956
+ packet.append_raw(cluster_id)
957
+ packet.append_raw(uuid.UUID(ras_args.infobase).bytes)
958
+ send_packet(writer, packet)
959
+ packet_type, packet_array = await read_packet(reader)
960
+ validate_endpoint_response(packet_type)
961
+ if ras_args.subcommand1 == 'update':
962
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.UPDATE_INFOBASE_REQUEST)
963
+ packet.append_raw(cluster_id)
964
+ infobase = packet_array[0]
965
+ if ras_args.descr is not None:
966
+ infobase['descr'] = ras_args.descr
967
+ if ras_args.denied_message is not None:
968
+ infobase['denied_message'] = ras_args.denied_message
969
+ if ras_args.permission_code is not None:
970
+ infobase['permission_code'] = ras_args.permission_code
971
+ if ras_args.sessions_deny in ['on', 'off']:
972
+ infobase['sessions_denied'] = ras_args.sessions_deny == 'on'
973
+ if ras_args.scheduled_jobs_deny in ['on', 'off']:
974
+ infobase['scheduled_jobs_denied'] = ras_args.scheduled_jobs_deny == 'on'
975
+ if ras_args.denied_from is not None:
976
+ infobase['denied_from'] = ras_args.denied_from
977
+ if ras_args.denied_to is not None:
978
+ infobase['denied_to'] = ras_args.denied_to
979
+ write_infobase(infobase, packet)
980
+ send_packet(writer, packet)
981
+ packet_type, packet_array = await read_packet(reader)
982
+ validate_endpoint_response(packet_type)
983
+ else:
984
+ pp(packet_array)
985
+
986
+ if ras_args.command == 'session':
987
+ cluster_id = uuid.UUID(ras_args.cluster).bytes
988
+ session_ids = []
989
+ session_info = {}
990
+ if ras_args.subcommand1 == 'list' or (ras_args.subcommand1 == 'terminate' and not ras_args.session):
991
+ if hasattr(ras_args, 'infobase') and ras_args.infobase:
992
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.GET_INFOBASE_SESSIONS_REQUEST)
993
+ packet.append_raw(cluster_id)
994
+ packet.append_raw(uuid.UUID(ras_args.infobase).bytes)
995
+ send_packet(writer, packet)
996
+ packet_type, packet_array = await read_packet(reader)
997
+ validate_endpoint_response(packet_type)
998
+ if ras_args.subcommand1 == 'list':
999
+ pp(packet_array)
1000
+ else:
1001
+ session_ids.extend(
1002
+ [session['session_id'].bytes for session in packet_array if session['app_id'] != 'RAS'])
1003
+ session_info.update({session['session_id'].bytes: session for session in packet_array})
1004
+ else:
1005
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.GET_SESSIONS_REQUEST)
1006
+ packet.append_raw(cluster_id)
1007
+ send_packet(writer, packet)
1008
+ packet_type, packet_array = await read_packet(reader)
1009
+ validate_endpoint_response(packet_type)
1010
+ if ras_args.subcommand1 == 'list':
1011
+ pp(packet_array)
1012
+ else:
1013
+ session_ids.extend(
1014
+ [session['session_id'].bytes for session in packet_array if session['app_id'] != 'RAS'])
1015
+ session_info.update({session['session_id'].bytes: session for session in packet_array})
1016
+ if ras_args.subcommand1 == 'terminate':
1017
+ if ras_args.session:
1018
+ session_id = uuid.UUID(ras_args.session).bytes
1019
+ session_ids.append(session_id)
1020
+ for session_id in session_ids:
1021
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.TERMINATE_SESSION_REQUEST)
1022
+ packet.append_raw(cluster_id)
1023
+ packet.append_raw(session_id)
1024
+ if hasattr(ras_args, 'error_message') and ras_args.error_message:
1025
+ packet.append(ras_args.error_message.encode())
1026
+ else:
1027
+ packet.append(b'Session terminated by admin')
1028
+ send_packet(writer, packet)
1029
+ try:
1030
+ packet_type, packet_array = await read_packet(reader)
1031
+ validate_endpoint_response(packet_type)
1032
+ if session_id in session_info.keys():
1033
+ print("Terminated session", uuid.UUID(bytes=session_id), session_info[session_id]['app_id'])
1034
+ else:
1035
+ print("Terminated session", uuid.UUID(bytes=session_id))
1036
+ except MessageException as e:
1037
+ print("Can't terminate session", uuid.UUID(bytes=session_id), "-", e)
1038
+
1039
+ if ras_args.command == 'server':
1040
+ cluster_id = uuid.UUID(ras_args.cluster).bytes
1041
+ if ras_args.subcommand1 == 'list':
1042
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.GET_WORKING_SERVERS_REQUEST)
1043
+ packet.append_raw(cluster_id)
1044
+ send_packet(writer, packet)
1045
+ packet_type, packet_array = await read_packet(reader)
1046
+ validate_endpoint_response(packet_type)
1047
+ pp(packet_array)
1048
+ elif ras_args.subcommand1 == 'info':
1049
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.GET_WORKING_SERVER_INFO_REQUEST)
1050
+ packet.append_raw(cluster_id)
1051
+ packet.append_raw(uuid.UUID(ras_args.server).bytes)
1052
+ send_packet(writer, packet)
1053
+ packet_type, packet_array = await read_packet(reader)
1054
+ validate_endpoint_response(packet_type)
1055
+ pp(packet_array)
1056
+ elif ras_args.subcommand1 == 'remove':
1057
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.UNREG_WORKING_SERVER_REQUEST)
1058
+ packet.append_raw(cluster_id)
1059
+ packet.append_raw(uuid.UUID(ras_args.server).bytes)
1060
+ send_packet(writer, packet)
1061
+ packet_type, packet_array = await read_packet(reader)
1062
+ validate_endpoint_response(packet_type)
1063
+ pp(packet_array)
1064
+ elif ras_args.subcommand1 == 'insert':
1065
+ packet = Packet(PacketType.ENDPOINT_MESSAGE, MessageType.REG_WORKING_SERVER_REQUEST)
1066
+ packet.append_raw(cluster_id)
1067
+ server = {}
1068
+ server['working_server_id'] = uuid.UUID(int=0)
1069
+ server['host_name'] = ras_args.agent_host
1070
+ server['main_port'] = ras_args.agent_port
1071
+ server['name'] = ras_args.name
1072
+ server['main_server'] = ras_args.using == 'main'
1073
+ server['safe_working_processes_memory_limit'] = ras_args.safe_working_processes_memory_limit
1074
+ server['safe_call_memory_limit'] = ras_args.safe_call_memory_limit
1075
+ server['infobases_per_working_process_limit'] = ras_args.infobases_limit
1076
+ server['working_process_memory_limit'] = ras_args.memory_limit
1077
+ server['connections_per_working_process_limit'] = ras_args.connections_limit
1078
+ server['cluster_main_port'] = ras_args.cluster_port
1079
+ server['dedicated_managers'] = ras_args.dedicate_managers == 'all'
1080
+ server['port_ranges'] = [(int(v.split(':')[0]), int(v.split(':')[1])) for v in ras_args.port_range]
1081
+ # version >= 8
1082
+ server['critical_processes_total_memory'] = ras_args.critical_total_memory
1083
+ server['temporary_allowed_processes_total_memory'] = ras_args.temporary_allowed_total_memory
1084
+ server['temporary_allowed_processes_total_memory_time_limit'] = ras_args.temporary_allowed_total_memory_time_limit
1085
+ write_server(server, packet)
1086
+ send_packet(writer, packet)
1087
+ packet_type, packet_array = await read_packet(reader)
1088
+ validate_endpoint_response(packet_type)
1089
+ pp(packet_array)
1090
+
1091
+ packet = Packet(PacketType.ENDPOINT_CLOSE)
1092
+ packet.append(pack_varint_base64(endpoint_id))
1093
+ send_packet(writer, packet)
1094
+ packet = Packet(PacketType.DISCONNECT)
1095
+ send_packet(writer, packet)
1096
+
1097
+
1098
+ if __name__ == '__main__':
1099
+ parser = argparse.ArgumentParser()
1100
+ parser.add_argument('--ras-host', default='localhost',
1101
+ help='адрес сервера администрирования (по-умолчанию: localhost)')
1102
+ parser.add_argument('--ras-port', default=1545, type=int,
1103
+ help='порт сервера администрирования (по-умолчанию: 1545)')
1104
+
1105
+ sub_parsers = parser.add_subparsers(help='Группы команд', dest='command', required=True)
1106
+
1107
+ parser_agent = sub_parsers.add_parser('agent', help='Режим администрирования агента кластера серверов')
1108
+ parser_agent.add_argument('--agent-user',
1109
+ help='имя администратора агента кластера', required=False)
1110
+ parser_agent.add_argument('--agent-pwd',
1111
+ help='пароль администратора агента кластера', required=False)
1112
+ agent_sub_parsers = parser_agent.add_subparsers(help='Команды администрирования агента кластера серверов',
1113
+ required=True, dest='subcommand1')
1114
+ agent_admin = agent_sub_parsers.add_parser('admin',
1115
+ help='управление администраторами кластера')
1116
+ agent_admin_sub_parsers = agent_admin.add_subparsers(help='Дополнительные команды', required=True,
1117
+ dest='subcommand2')
1118
+ parser_agent_admin_list = agent_admin_sub_parsers.add_parser('list',
1119
+ help='получение списка администраторов агента кластера')
1120
+ parser_agent_admin_register = agent_admin_sub_parsers.add_parser('register',
1121
+ help='добавление нового администратора агента кластера')
1122
+ parser_agent_admin_register.add_argument('--name',
1123
+ help='имя администратора', required=True)
1124
+ parser_agent_admin_register.add_argument('--pwd', default="",
1125
+ help='пароль администратора, в случае аутентификации паролем',
1126
+ required=False)
1127
+ parser_agent_admin_register.add_argument('--descr', default="",
1128
+ help='описание администратора', required=False)
1129
+ parser_agent_admin_register.add_argument('--auth', choices=['pwd', 'os'], nargs="+", default=[],
1130
+ help="""доступные способы аутентификации:
1131
+ pwd - при помощи имени пользователя и пароля
1132
+ os - аутентификация средствами ОС""", required=False)
1133
+ parser_agent_admin_register.add_argument('--os-user', default="",
1134
+ help='имя пользователя операционной системы', required=False)
1135
+ parser_cluster_admin_remove = agent_admin_sub_parsers.add_parser('remove',
1136
+ help='удаление администратора агента кластера')
1137
+ parser_cluster_admin_remove.add_argument('--name',
1138
+ help='имя администратора', required=True)
1139
+
1140
+ parser_cluster = sub_parsers.add_parser('cluster', help='Режим администрирования кластера серверов')
1141
+ cluster_sub_parsers = parser_cluster.add_subparsers(help='Команды администрирования кластера серверов',
1142
+ required=True, dest='subcommand1')
1143
+ parser_cluster_list = cluster_sub_parsers.add_parser('list', help='получение списка информации о кластерах')
1144
+ parser_cluster_info = cluster_sub_parsers.add_parser('info', help='получение информации о кластере')
1145
+ parser_cluster_info.add_argument('--cluster',
1146
+ help='идентификатор кластера серверов', required=True)
1147
+ parser_cluster_update = cluster_sub_parsers.add_parser('update', help='обновление параметров кластера')
1148
+ parser_cluster_update.add_argument('--cluster',
1149
+ help='идентификатор кластера серверов', required=True)
1150
+ parser_cluster_update.add_argument('--lifetime-limit', type=int,
1151
+ help='период перезапуска рабочих процессов кластера (в секундах)',
1152
+ required=False)
1153
+ parser_cluster_update.add_argument('--expiration-timeout', type=int,
1154
+ help='период принудительного завершения (в секундах)', required=False)
1155
+ parser_cluster_update.add_argument('--name',
1156
+ help='имя (представление) кластера',
1157
+ required=False)
1158
+
1159
+ parser_cluster_admin = cluster_sub_parsers.add_parser('admin',
1160
+ help='управление администраторами кластера')
1161
+ parser_cluster_admin.add_argument('--cluster',
1162
+ help='идентификатор кластера серверов', required=True)
1163
+ parser_cluster_admin.add_argument('--cluster-user',
1164
+ help='имя администратора кластера', required=False)
1165
+ parser_cluster_admin.add_argument('--cluster-pwd',
1166
+ help='пароль администратора кластера', required=False)
1167
+ cluster_admin_sub_parsers = parser_cluster_admin.add_subparsers(help='Дополнительные команды', required=True,
1168
+ dest='subcommand2')
1169
+ parser_cluster_admin_list = cluster_admin_sub_parsers.add_parser('list',
1170
+ help='получение списка администраторов кластера')
1171
+ parser_cluster_admin_register = cluster_admin_sub_parsers.add_parser('register',
1172
+ help='добавление нового администратора кластера')
1173
+ parser_cluster_admin_register.add_argument('--name',
1174
+ help='имя администратора', required=True)
1175
+ parser_cluster_admin_register.add_argument('--pwd', default="",
1176
+ help='пароль администратора, в случае аутентификации паролем',
1177
+ required=False)
1178
+ parser_cluster_admin_register.add_argument('--descr', default="",
1179
+ help='описание администратора', required=False)
1180
+ parser_cluster_admin_register.add_argument('--auth', choices=['pwd', 'os'], nargs="+", default=[],
1181
+ help="""доступные способы аутентификации:
1182
+ pwd - при помощи имени пользователя и пароля
1183
+ os - аутентификация средствами ОС""", required=False)
1184
+ parser_cluster_admin_register.add_argument('--os-user', default="",
1185
+ help='имя пользователя операционной системы', required=False)
1186
+ parser_cluster_admin_register.add_argument('--agent-user',
1187
+ help='имя администратора агента кластера', required=False)
1188
+ parser_cluster_admin_register.add_argument('--agent-pwd',
1189
+ help='пароль администратора агента кластера', required=False)
1190
+ parser_cluster_admin_remove = cluster_admin_sub_parsers.add_parser('remove',
1191
+ help='удаление администратора кластера')
1192
+ parser_cluster_admin_remove.add_argument('--name',
1193
+ help='имя администратора', required=True)
1194
+
1195
+ parser_infobase = sub_parsers.add_parser('infobase', help='Режим администрирования информационных баз')
1196
+ parser_infobase.add_argument('--cluster',
1197
+ help='идентификатор кластера серверов', required=True)
1198
+ parser_infobase.add_argument('--cluster-user',
1199
+ help='имя администратора кластера', required=False)
1200
+ parser_infobase.add_argument('--cluster-pwd',
1201
+ help='пароль администратора кластера', required=False)
1202
+ infobase_sub_parsers = parser_infobase.add_subparsers(help='Команды администрирования информационных баз',
1203
+ required=True, dest='subcommand1')
1204
+ parser_infobase_summary = infobase_sub_parsers.add_parser('summary',
1205
+ help='управление краткой информацией об информационных базах')
1206
+ infobase_summary_sub_parsers = parser_infobase_summary.add_subparsers(help='Дополнительные команды', required=True,
1207
+ dest='subcommand2')
1208
+ parser_infobase_summary_list = infobase_summary_sub_parsers.add_parser('list',
1209
+ help='получение списка краткой информации об информационных базах')
1210
+ parser_infobase_info = infobase_sub_parsers.add_parser('info', help='получение информации об информационной базе')
1211
+ parser_infobase_info.add_argument('--infobase',
1212
+ help='идентификатор информационной базы', required=True)
1213
+ parser_infobase_info.add_argument('--infobase-user',
1214
+ help='имя администратора информационной базы', required=False)
1215
+ parser_infobase_info.add_argument('--infobase-pwd',
1216
+ help='пароль администратора информационной базы', required=False)
1217
+ parser_infobase_update = infobase_sub_parsers.add_parser('update',
1218
+ help='обновление информации об информационной базе')
1219
+ parser_infobase_update.add_argument('--infobase',
1220
+ help='идентификатор информационной базы', required=True)
1221
+ parser_infobase_update.add_argument('--infobase-user',
1222
+ help='имя администратора информационной базы', required=False)
1223
+ parser_infobase_update.add_argument('--infobase-pwd',
1224
+ help='пароль администратора информационной базы', required=False)
1225
+ parser_infobase_update.add_argument('--descr',
1226
+ help='описание информационной базы', required=False)
1227
+ parser_infobase_update.add_argument('--denied-from',
1228
+ help='начало интервала времени, в течение которого действует режим блокировки сеансов, YYYY-MM-DD HH:mm:ss',
1229
+ type=lambda s: datetime.datetime.fromisoformat(s).replace(
1230
+ tzinfo=datetime.timezone.utc) if len(s) > 0 else 0,
1231
+ required=False)
1232
+ parser_infobase_update.add_argument('--denied-to',
1233
+ help='конец интервала времени, в течение которого действует режим блокировки сеансов, YYYY-MM-DD HH:mm:ss',
1234
+ type=lambda s: datetime.datetime.fromisoformat(s).replace(
1235
+ tzinfo=datetime.timezone.utc) if len(s) > 0 else 0,
1236
+ required=False)
1237
+ parser_infobase_update.add_argument('--denied-message',
1238
+ help='сообщение, выдаваемое при попытке нарушения блокировки сеансов',
1239
+ required=False)
1240
+ parser_infobase_update.add_argument('--denied-parameter',
1241
+ help='параметр блокировки сеансов',
1242
+ required=False)
1243
+ parser_infobase_update.add_argument('--permission-code',
1244
+ help='код разрешения, разрешающий начало сеанса вопреки действующей блокировке сеансов',
1245
+ required=False)
1246
+ parser_infobase_update.add_argument('--sessions-deny', choices=['on', 'off'],
1247
+ help="""управление режимом блокировки сеансов:
1248
+ on - режим блокировки начала сеансов включен
1249
+ off - режим блокировки начала сеансов выключен""",
1250
+ required=False)
1251
+ parser_infobase_update.add_argument('--scheduled-jobs-deny', choices=['on', 'off'],
1252
+ help="""управление блокировкой выполнения регламентных заданий:
1253
+ on - выполнение регламентных заданий запрещено
1254
+ off - выполнение регламентных заданий разрешено""",
1255
+ required=False)
1256
+ parser_infobase_create = infobase_sub_parsers.add_parser('create',
1257
+ help='создание новой информационной базы')
1258
+ parser_infobase_create.add_argument('--create-database', action='store_true',
1259
+ help='при создании информационной базы создать базу данных')
1260
+ parser_infobase_create.add_argument('--name',
1261
+ help='имя информационной базы', required=True)
1262
+ parser_infobase_create.add_argument('--dbms',
1263
+ help="""тип СУБД, в которой размещается информационная база
1264
+ MSSQLServer - MS SQL Server
1265
+ PostgreSQL - PostgreSQL
1266
+ IBMDB2 - IBM DB2
1267
+ OracleDatabase - Oracle Database""",
1268
+ choices=['MSSQLServer', 'PostgreSQL', 'IBMDB2', 'OracleDatabase'],
1269
+ required=True)
1270
+ parser_infobase_create.add_argument('--db-server',
1271
+ help='имя сервера баз данных', required=True)
1272
+ parser_infobase_create.add_argument('--db-name',
1273
+ help='имя базы данных', required=True)
1274
+ parser_infobase_create.add_argument('--locale',
1275
+ help='идентификатор национальных настроек информационной базы', required=True)
1276
+ parser_infobase_create.add_argument('--db-user',
1277
+ help='имя администратора базы данных', required=True)
1278
+ parser_infobase_create.add_argument('--db-pwd',
1279
+ help='пароль администратора базы данных', required=True)
1280
+ parser_infobase_create.add_argument('--descr', default='',
1281
+ help='описание информационной базы', required=False)
1282
+ parser_infobase_create.add_argument('--date-offset', choices=[0, 2000], default=0, type=int,
1283
+ help='смещение дат в информационной базе', required=False)
1284
+ parser_infobase_create.add_argument('--security-level', default=0, type=int,
1285
+ help='уровень безопасности установки соединений с информационной базой',
1286
+ required=False)
1287
+ parser_infobase_create.add_argument('--scheduled-jobs-deny', choices=['on', 'off'],
1288
+ help="""управление блокировкой выполнения регламентных заданий:
1289
+ on - выполнение регламентных заданий запрещено
1290
+ off - выполнение регламентных заданий разрешено""",
1291
+ required=False)
1292
+ parser_infobase_create.add_argument('--license-distribution', choices=['deny', 'allow'],
1293
+ help="""управление выдачей лицензий сервером 1С:Предприятия:
1294
+ deny - выдача лицензий запрещена
1295
+ allow - выдача лицензий разрешена""",
1296
+ required=False)
1297
+ parser_infobase_drop = infobase_sub_parsers.add_parser('drop',
1298
+ help='режим удаления информационной базы')
1299
+ parser_infobase_drop.add_argument('--infobase',
1300
+ help='идентификатор информационной базы', required=True)
1301
+ parser_infobase_drop.add_argument('--infobase-user',
1302
+ help='имя администратора информационной базы', required=False)
1303
+ parser_infobase_drop.add_argument('--infobase-pwd',
1304
+ help='пароль администратора информационной базы', required=False)
1305
+ parser_infobase_drop.add_argument('--drop-database', action='store_true',
1306
+ help='при удалении информационной базы удалить базу данных')
1307
+ parser_infobase_drop.add_argument('--clear-database', action='store_true',
1308
+ help='при удалении информационной базы очистить базу данных')
1309
+ parser_session = sub_parsers.add_parser('session', help='Режим администрирования сеансов информационных баз')
1310
+ parser_session.add_argument('--cluster',
1311
+ help='идентификатор кластера серверов', required=True)
1312
+ parser_session.add_argument('--cluster-user',
1313
+ help='имя администратора кластера', required=False)
1314
+ parser_session.add_argument('--cluster-pwd',
1315
+ help='пароль администратора кластера', required=False)
1316
+ session_sub_parsers = parser_session.add_subparsers(help='Команды администрирования сеансов информационных баз',
1317
+ required=True, dest='subcommand1')
1318
+ parser_session_list = session_sub_parsers.add_parser('list',
1319
+ help='получение списка информации о сеансах')
1320
+ parser_session_list.add_argument('--infobase',
1321
+ help='идентификатор информационной базы')
1322
+ parser_session_list.add_argument('--licenses', action='store_true',
1323
+ help='вывод информации о лицензиях, полученных сеансом')
1324
+ parser_session_terminate = session_sub_parsers.add_parser('terminate',
1325
+ help='принудительное завершение сеанса')
1326
+ parser_session_terminate.add_argument('--session',
1327
+ help='идентификатор сеанса информационной базы')
1328
+ parser_session_terminate.add_argument('--infobase',
1329
+ help='идентификатор информационной базы')
1330
+ parser_session_terminate.add_argument('--error-message',
1331
+ help='сообщение о причине завершения сеанса')
1332
+
1333
+ parser_server = sub_parsers.add_parser('server', help='Режим администрирования рабочего сервера')
1334
+ parser_server.add_argument('--cluster',
1335
+ help='идентификатор кластера серверов', required=True)
1336
+ parser_server.add_argument('--cluster-user',
1337
+ help='имя администратора кластера', required=False)
1338
+ parser_server.add_argument('--cluster-pwd',
1339
+ help='пароль администратора кластера', required=False)
1340
+ server_sub_parsers = parser_server.add_subparsers(help='Команды администрирования рабочих серверов',
1341
+ required=True, dest='subcommand1')
1342
+ parser_server_list = server_sub_parsers.add_parser('list', help='получение списка информации о рабочих серверах')
1343
+ parser_server_info = server_sub_parsers.add_parser('info', help='получение информации о рабочем сервере')
1344
+ parser_server_info.add_argument('--server',
1345
+ help='идентификатор рабочего сервера кластера серверов', required=True)
1346
+ parser_server_insert = server_sub_parsers.add_parser('insert', help='регистрация рабочего сервера')
1347
+ parser_server_insert.add_argument('--agent-host',
1348
+ help='имя хоста или IP-адрес агента сервера', required=True)
1349
+ parser_server_insert.add_argument('--agent-port', type=int,
1350
+ help='основной порт агента сервера', required=True)
1351
+ parser_server_insert.add_argument('--port-range', default='11560:11591',
1352
+ help="""диапазон IP портов для динамического распределения,
1353
+ возможно указание нескольких диапазонов""", required=True, nargs="+")
1354
+ parser_server_insert.add_argument('--name',
1355
+ help='наименование рабочего сервера', required=False)
1356
+ parser_server_insert.add_argument('--using', choices=['main', 'normal'], default='main',
1357
+ help="""вариант использования рабочего сервера
1358
+ main - в качестве центрального сервера
1359
+ normal - в качестве обычного сервера""", required=False)
1360
+ parser_server_insert.add_argument('--infobases-limit', type=int, default=8,
1361
+ help='максимальное количество информационных баз на рабочий процесс',
1362
+ required=False)
1363
+ parser_server_insert.add_argument('--memory-limit', type=int, default=0,
1364
+ help='предел использования памяти рабочими процессами',
1365
+ required=False)
1366
+ parser_server_insert.add_argument('--connections-limit', type=int, default=256,
1367
+ help='максимальное количество соединения на рабочий процесс',
1368
+ required=False)
1369
+ parser_server_insert.add_argument('--cluster-port', type=int, default=1541,
1370
+ help='номер порта главного менеджера кластера',
1371
+ required=False)
1372
+ parser_server_insert.add_argument('--dedicate-managers', choices=['all', 'none'], default='none',
1373
+ help="""вариант размещения менеджеров сервисов
1374
+ all - размещать все сервисы в отдельных менеджерах
1375
+ none - размещать все сервисы в одном менеджере""",
1376
+ required=False)
1377
+ parser_server_insert.add_argument('--safe-working-processes-memory-limit', type=int, default=0,
1378
+ help='максимальный объем памяти рабочих процессов на сервере',
1379
+ required=False)
1380
+ parser_server_insert.add_argument('--safe-call-memory-limit', type=int, default=0,
1381
+ help='безопасный расход памяти за один вызов в байтах',
1382
+ required=False)
1383
+ parser_server_insert.add_argument('--critical-total-memory', type=int, default=0,
1384
+ help='максимальный объем памяти процессов рабочего сервера',
1385
+ required=False)
1386
+ parser_server_insert.add_argument('--temporary-allowed-total-memory', type=int, default=0,
1387
+ help='допустимый объем памяти процессов рабочего сервера',
1388
+ required=False)
1389
+ parser_server_insert.add_argument('--temporary-allowed-total-memory-time-limit', type=int, default=300,
1390
+ help='предел превышения (секунд) допустимого объема памяти процессов',
1391
+ required=False)
1392
+ parser_server_insert.add_argument('--service-principal-name', default='',
1393
+ help='имя службы (Service Principal Name, SPN) сервера 1С:Предприятия',
1394
+ required=False)
1395
+ parser_server_remove = server_sub_parsers.add_parser('remove', help='удаление рабочего сервера')
1396
+ parser_server_remove.add_argument('--server',
1397
+ help='идентификатор рабочего сервера кластера серверов', required=True)
1398
+
1399
+ args = parser.parse_args()
1400
+ asyncio.run(ras_command(args))