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/__init__.py +4 -0
- pyrac/__main__.py +4 -0
- pyrac/cli.py +921 -0
- pyrac/client.py +2382 -0
- pyrac/desktop.py +5003 -0
- pyrac/legacy.py +8 -0
- pyrac/mcp_server.py +3845 -0
- pyrac/protocol/__init__.py +0 -0
- pyrac/protocol/v851.py +32 -0
- pyrac/protocol/v851_client.py +3453 -0
- pyrac/read_service.py +831 -0
- pyrac/v8311.py +1400 -0
- pyrac/web/__init__.py +0 -0
- pyrac/web/__main__.py +355 -0
- pyrac/web/app.py +2835 -0
- pyrac/web/workspace.py +1905 -0
- python_rac-0.2.0.dist-info/METADATA +843 -0
- python_rac-0.2.0.dist-info/RECORD +22 -0
- python_rac-0.2.0.dist-info/WHEEL +5 -0
- python_rac-0.2.0.dist-info/entry_points.txt +5 -0
- python_rac-0.2.0.dist-info/licenses/LICENSE +21 -0
- python_rac-0.2.0.dist-info/top_level.txt +1 -0
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))
|