hid_data_transfer_lib 0.3.10__tar.gz → 0.4.0__tar.gz
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.
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/PKG-INFO +3 -3
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/README.md +2 -2
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/conf/hid_dt_configuration.py +74 -70
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/hid_dt_lib.py +116 -68
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/keycloak/keycloak_rest.py +4 -2
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/nifi/nifi_client.py +111 -42
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/nifi/nifi_rest.py +157 -16
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/util/util.py +7 -3
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/pyproject.toml +2 -1
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/__init__.py +0 -0
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/conf/__init__.py +0 -0
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/conf/hid_dt.cfg +0 -0
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/conf/hid_dt_local.cfg +0 -0
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/conf/hid_dt_psnc.cfg +0 -0
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/exceptions/__init__.py +0 -0
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/exceptions/hid_dt_exceptions.py +0 -0
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/keycloak/__init__.py +0 -0
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/nifi/__init__.py +0 -0
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/py.typed +0 -0
- {hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/util/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hid_data_transfer_lib
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: HiDALGO Data Transfer library provides methods to transfer data between different data providers and consumers using NIFI pipelines
|
|
5
5
|
License: APL-2.0
|
|
6
6
|
Author: Jesús Gorroñogoitia
|
|
@@ -51,7 +51,7 @@ The Data Transfer Library sends requests to NIFI through its REST API.
|
|
|
51
51
|
To use the Data Transfer library, it is required the following requirements:
|
|
52
52
|
- **Python3** execution environment
|
|
53
53
|
- **Poetry** python package management tool (optional)
|
|
54
|
-
- **NIFI** instance, with a NIFI server SSH account (for keys transfer)
|
|
54
|
+
- **NIFI** instance, with a NIFI 2.X server SSH account (for keys transfer). Latest NIFI supported version: 2.8
|
|
55
55
|
- **Keycloak** instance, with a KEYCLOAK user's account
|
|
56
56
|
- **HDFS** instance, with an user's Kerberos principal account
|
|
57
57
|
- **CKAN** instance, with an user APIKey
|
|
@@ -123,7 +123,7 @@ keycloak_login=<user_name>
|
|
|
123
123
|
keycloak_password=<password>
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
-
Under the Nifi section, you must also specify a user account (username, private_key) that grants to upload/download files to the NIFI server (as requested to upload temporary HPC keys or to support local file transfer). This user's account is provided by Hidalgo2 infrastructure provider and it is user's or service's specific.
|
|
126
|
+
Under the Nifi section, you must also specify a user account (username, private_key) that grants to upload/download files to the NIFI server (as requested to upload temporary HPC keys or to support local file transfer). This user's account is provided by Hidalgo2 infrastructure provider and it is user's or service's specific. Note: this user's account requires to belond to group *users*.
|
|
127
127
|
|
|
128
128
|
Under the Keycloak section, you must specify your Keycloak account (username and password). This account granted with access to the NIFI service.
|
|
129
129
|
|
|
@@ -32,7 +32,7 @@ The Data Transfer Library sends requests to NIFI through its REST API.
|
|
|
32
32
|
To use the Data Transfer library, it is required the following requirements:
|
|
33
33
|
- **Python3** execution environment
|
|
34
34
|
- **Poetry** python package management tool (optional)
|
|
35
|
-
- **NIFI** instance, with a NIFI server SSH account (for keys transfer)
|
|
35
|
+
- **NIFI** instance, with a NIFI 2.X server SSH account (for keys transfer). Latest NIFI supported version: 2.8
|
|
36
36
|
- **Keycloak** instance, with a KEYCLOAK user's account
|
|
37
37
|
- **HDFS** instance, with an user's Kerberos principal account
|
|
38
38
|
- **CKAN** instance, with an user APIKey
|
|
@@ -104,7 +104,7 @@ keycloak_login=<user_name>
|
|
|
104
104
|
keycloak_password=<password>
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
-
Under the Nifi section, you must also specify a user account (username, private_key) that grants to upload/download files to the NIFI server (as requested to upload temporary HPC keys or to support local file transfer). This user's account is provided by Hidalgo2 infrastructure provider and it is user's or service's specific.
|
|
107
|
+
Under the Nifi section, you must also specify a user account (username, private_key) that grants to upload/download files to the NIFI server (as requested to upload temporary HPC keys or to support local file transfer). This user's account is provided by Hidalgo2 infrastructure provider and it is user's or service's specific. Note: this user's account requires to belond to group *users*.
|
|
108
108
|
|
|
109
109
|
Under the Keycloak section, you must specify your Keycloak account (username and password). This account granted with access to the NIFI service.
|
|
110
110
|
|
|
@@ -24,6 +24,7 @@ from hid_data_transfer_lib.exceptions.hid_dt_exceptions import (
|
|
|
24
24
|
HidDataTransferException
|
|
25
25
|
)
|
|
26
26
|
|
|
27
|
+
STATUS_SLEEP_LAPSE = 10 # seconds
|
|
27
28
|
|
|
28
29
|
class HidDataTransferConfiguration:
|
|
29
30
|
"""This class manages the configuration of the Data Transfer library"""
|
|
@@ -44,21 +45,22 @@ class HidDataTransferConfiguration:
|
|
|
44
45
|
__keycloak_login = None
|
|
45
46
|
__keycloak_passwd = None
|
|
46
47
|
|
|
47
|
-
__check_status_sleep_lapse =
|
|
48
|
+
__check_status_sleep_lapse = STATUS_SLEEP_LAPSE # seconds
|
|
48
49
|
|
|
49
50
|
def __init__(self, logging_level: Optional[int] = logging.INFO):
|
|
50
51
|
self.__logging_level = logging_level
|
|
51
52
|
|
|
52
|
-
def check_keycloak_conf(self):
|
|
53
|
+
def check_keycloak_conf(self, use_keycloak_account):
|
|
53
54
|
"""Check if keycloak configuration is valid"""
|
|
54
|
-
if
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
if use_keycloak_account:
|
|
56
|
+
if self.__keycloak_login is None:
|
|
57
|
+
raise HidDataTransferException(
|
|
58
|
+
"Keycloak login must be set in the configuration"
|
|
59
|
+
)
|
|
60
|
+
if self.__keycloak_passwd is None:
|
|
61
|
+
raise HidDataTransferException(
|
|
62
|
+
"Keycloak passwd must be set in the configuration"
|
|
63
|
+
)
|
|
62
64
|
if self.__keycloak_endpoint is None:
|
|
63
65
|
raise HidDataTransferException(
|
|
64
66
|
"Keycloak endpoint must be set in the configuration"
|
|
@@ -195,6 +197,14 @@ class HidDataTransferConfiguration:
|
|
|
195
197
|
"""Returns the NIFI login password"""
|
|
196
198
|
return self.__keycloak_passwd
|
|
197
199
|
|
|
200
|
+
def reset_keycloak_login(self):
|
|
201
|
+
"""Reset the NIFI login name"""
|
|
202
|
+
self.__keycloak_login = None
|
|
203
|
+
|
|
204
|
+
def reset_keycloak_passwd(self):
|
|
205
|
+
"""Reset the NIFI login password"""
|
|
206
|
+
self.__keycloak_passwd = None
|
|
207
|
+
|
|
198
208
|
def logger(self, logger_name):
|
|
199
209
|
"""Returns the logging level"""
|
|
200
210
|
return self.__set_logger(logger_name)
|
|
@@ -256,7 +266,8 @@ class HidDataTransferConfiguration:
|
|
|
256
266
|
self,
|
|
257
267
|
user_config_file: Optional[str] = None,
|
|
258
268
|
user_config_dict: Optional[dict] = None,
|
|
259
|
-
logging_level: Optional[int] = None
|
|
269
|
+
logging_level: Optional[int] = None,
|
|
270
|
+
use_keycloak_account: Bool = True,
|
|
260
271
|
) -> HidDataTransferConfiguration:
|
|
261
272
|
"""
|
|
262
273
|
Reads the configuration and sets this class' configuration values
|
|
@@ -276,38 +287,33 @@ class HidDataTransferConfiguration:
|
|
|
276
287
|
self.load_nifi_configuration(config)
|
|
277
288
|
|
|
278
289
|
# Keycloak section
|
|
279
|
-
self.load_keycloak_configuration(
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
)
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
290
|
+
self.load_keycloak_configuration(
|
|
291
|
+
config, check_configuration = use_keycloak_account)
|
|
292
|
+
|
|
293
|
+
# # Check if either NIFI or Keycloak login and password are set
|
|
294
|
+
# if not use_keycloak_token and (
|
|
295
|
+
# self.__nifi_login is None and self.__nifi_passwd is None
|
|
296
|
+
# ) and (
|
|
297
|
+
# self.__keycloak_login is None and
|
|
298
|
+
# self.__keycloak_passwd is None
|
|
299
|
+
# ):
|
|
300
|
+
# raise HidDataTransferException(
|
|
301
|
+
# "Either (KEYCLOAK_LOGIN and KEYCLOAK_PASSWORD) "
|
|
302
|
+
# "or (NIFI_LOGIN and NIFI_PASSWORD) "
|
|
303
|
+
# "environment variables must be set"
|
|
304
|
+
# )
|
|
291
305
|
|
|
292
306
|
# Logging section
|
|
293
307
|
if logging_level is not None:
|
|
294
308
|
self.__logging_level = logging_level
|
|
295
309
|
else:
|
|
296
|
-
logging_level_str = config.get("Logging", "logging_level")
|
|
310
|
+
logging_level_str = config.get("Logging", "logging_level", fallback="Info")
|
|
297
311
|
self.__logging_level = getattr(
|
|
298
312
|
logging, logging_level_str.upper(), logging.INFO)
|
|
299
313
|
|
|
300
314
|
# Network section
|
|
301
|
-
self.__check_status_sleep_lapse = config.get(
|
|
302
|
-
"Network", "check_status_sleep_lapse")
|
|
303
|
-
|
|
304
|
-
# Network section
|
|
305
|
-
self.__check_status_sleep_lapse = config.get(
|
|
306
|
-
"Network", "check_status_sleep_lapse")
|
|
307
|
-
|
|
308
|
-
# Network section
|
|
309
|
-
self.__check_status_sleep_lapse = config.get(
|
|
310
|
-
"Network", "check_status_sleep_lapse")
|
|
315
|
+
self.__check_status_sleep_lapse = int(config.get(
|
|
316
|
+
"Network", "check_status_sleep_lapse", fallback=STATUS_SLEEP_LAPSE))
|
|
311
317
|
|
|
312
318
|
return self
|
|
313
319
|
|
|
@@ -316,69 +322,67 @@ class HidDataTransferConfiguration:
|
|
|
316
322
|
"Error parsing CLI configuration file"
|
|
317
323
|
) from ex
|
|
318
324
|
|
|
319
|
-
def load_keycloak_configuration(self, config):
|
|
325
|
+
def load_keycloak_configuration(self, config, check_configuration = True):
|
|
320
326
|
"""Load Keycloak configuration from config file"""
|
|
321
327
|
# Read Keycloak login and password from configuration
|
|
322
|
-
self.__keycloak_login = config.get("Keycloak", "keycloak_login")
|
|
323
|
-
self.__keycloak_passwd = config.get("Keycloak", "keycloak_password")
|
|
324
|
-
if
|
|
325
|
-
self.__keycloak_login is None
|
|
326
|
-
):
|
|
328
|
+
self.__keycloak_login = config.get("Keycloak", "keycloak_login", fallback=None)
|
|
329
|
+
self.__keycloak_passwd = config.get("Keycloak", "keycloak_password", fallback=None)
|
|
330
|
+
if check_configuration and (
|
|
331
|
+
self.__keycloak_login is None or self.__keycloak_passwd is None):
|
|
327
332
|
raise HidDataTransferException(
|
|
328
333
|
"Both KEYCLOAK_LOGIN and KEYCLOAK_PASSWORD "
|
|
329
334
|
"environment variables must be set"
|
|
330
335
|
)
|
|
331
336
|
|
|
332
337
|
# Read other keycloak configuration from config file
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
)
|
|
338
|
+
self.__keycloak_endpoint = config.get(
|
|
339
|
+
"Keycloak", "keycloak_endpoint", fallback=None)
|
|
340
|
+
if self.__keycloak_endpoint is None:
|
|
341
|
+
raise HidDataTransferException(
|
|
342
|
+
"Could not find Keycloak endpoint in config file."
|
|
343
|
+
)
|
|
340
344
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
345
|
+
self.__keycloak_client_id = config.get(
|
|
346
|
+
"Keycloak", "keycloak_client_id", fallback=None)
|
|
347
|
+
if self.__keycloak_client_id is None:
|
|
348
|
+
raise HidDataTransferException(
|
|
349
|
+
"Could not find Keycloak client id "
|
|
350
|
+
"for NIFI in config file."
|
|
351
|
+
)
|
|
348
352
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
353
|
+
keycloak_client_secret = config.get(
|
|
354
|
+
"Keycloak", "keycloak_client_secret", fallback=None)
|
|
355
|
+
if keycloak_client_secret is not None:
|
|
356
|
+
self.__keycloak_client_secret = keycloak_client_secret
|
|
357
|
+
else:
|
|
358
|
+
raise HidDataTransferException(
|
|
359
|
+
"Could not find Keycloak client secret "
|
|
360
|
+
"for NIFI in config file."
|
|
361
|
+
)
|
|
358
362
|
|
|
359
363
|
def load_nifi_configuration(self, config):
|
|
360
364
|
"""Load NIFI configuration from config file"""
|
|
361
|
-
self.__nifi_endpoint = config.get("Nifi", "nifi_endpoint")
|
|
365
|
+
self.__nifi_endpoint = config.get("Nifi", "nifi_endpoint", fallback=None)
|
|
362
366
|
if self.__nifi_endpoint is None:
|
|
363
367
|
raise HidDataTransferException(
|
|
364
368
|
"Could not find Nifi endpoint in config file."
|
|
365
369
|
)
|
|
366
370
|
|
|
367
|
-
nifi_secure_connection = config.get("Nifi", "nifi_secure_connection")
|
|
371
|
+
nifi_secure_connection = config.get("Nifi", "nifi_secure_connection", fallback=None)
|
|
368
372
|
if nifi_secure_connection is not None:
|
|
369
373
|
self.__nifi_secure_connection = \
|
|
370
374
|
nifi_secure_connection.lower() == "true"
|
|
371
375
|
else:
|
|
372
376
|
self.__nifi_secure_connection = False
|
|
373
377
|
|
|
374
|
-
self.__nifi_upload_folder = config.get("Nifi", "nifi_upload_folder")
|
|
378
|
+
self.__nifi_upload_folder = config.get("Nifi", "nifi_upload_folder", fallback=None)
|
|
375
379
|
if self.__nifi_upload_folder is None:
|
|
376
380
|
raise HidDataTransferException(
|
|
377
381
|
"Could not find Nifi nifi_upload_folder in config file"
|
|
378
382
|
)
|
|
379
383
|
|
|
380
384
|
self.__nifi_download_folder = config.get(
|
|
381
|
-
"Nifi", "nifi_download_folder")
|
|
385
|
+
"Nifi", "nifi_download_folder", fallback=None)
|
|
382
386
|
if self.__nifi_download_folder is None:
|
|
383
387
|
raise HidDataTransferException(
|
|
384
388
|
"Could not find Nifi nifi_download_folder in config file"
|
|
@@ -386,9 +390,9 @@ class HidDataTransferConfiguration:
|
|
|
386
390
|
|
|
387
391
|
# Optional NIFI server account in case of local file transfer
|
|
388
392
|
self.__nifi_server_user_name = config.get(
|
|
389
|
-
"Nifi", "nifi_server_username")
|
|
393
|
+
"Nifi", "nifi_server_username", fallback=None)
|
|
390
394
|
self.__nifi_server_private_key = config.get(
|
|
391
|
-
"Nifi", "nifi_server_private_key")
|
|
395
|
+
"Nifi", "nifi_server_private_key", fallback=None)
|
|
392
396
|
|
|
393
397
|
if (
|
|
394
398
|
self.__nifi_server_user_name and
|
|
@@ -400,7 +404,7 @@ class HidDataTransferConfiguration:
|
|
|
400
404
|
"environment variables must be set"
|
|
401
405
|
)
|
|
402
406
|
|
|
403
|
-
nifi_concurrent_tasks = config.get("Nifi", "nifi_concurrent_tasks")
|
|
407
|
+
nifi_concurrent_tasks = config.get("Nifi", "nifi_concurrent_tasks", fallback=None)
|
|
404
408
|
if nifi_concurrent_tasks is not None:
|
|
405
409
|
self.__nifi_concurrent_tasks = int(nifi_concurrent_tasks)
|
|
406
410
|
else:
|
{hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/hid_dt_lib.py
RENAMED
|
@@ -34,10 +34,11 @@ from hid_data_transfer_lib.nifi.nifi_client import (
|
|
|
34
34
|
NIFIClient, ExecutionType, AccountingInfo
|
|
35
35
|
)
|
|
36
36
|
|
|
37
|
-
KERBEROS_PRINCIPAL = "kerberos.principal"
|
|
38
37
|
HDFS_DATA_FOLDER = "hdfs.data_folder"
|
|
38
|
+
HDFS_DATA_FILENAME = "hdfs.data_filename"
|
|
39
39
|
HDFS_FILENAME = "hdfs.filename"
|
|
40
40
|
HPC_TARGET_FOLDER = "hpc.target_folder"
|
|
41
|
+
HPC_TARGET_FILENAME = "hpc.target_filename"
|
|
41
42
|
HPC_DATA_FOLDER = "hpc.data_folder"
|
|
42
43
|
HPC_FILENAME = "hpc.filename"
|
|
43
44
|
HPC_FILENAME_REGEX = "hpc.filename.regex"
|
|
@@ -69,13 +70,16 @@ class HIDDataTransfer:
|
|
|
69
70
|
"""
|
|
70
71
|
self.__conf = conf
|
|
71
72
|
self.__secure = secure
|
|
72
|
-
self.
|
|
73
|
+
self.use_keycloak_account = (keycloak_token is None)
|
|
74
|
+
self.__nifi_client = NIFIClient().configure(
|
|
75
|
+
conf, secure, use_keycloak_account=self.use_keycloak_account)
|
|
73
76
|
self.__logger = self.__conf.logger("hid_data_transfer_lib")
|
|
74
77
|
self.__keycloak_token = keycloak_token
|
|
75
78
|
|
|
76
79
|
def reset(self):
|
|
77
80
|
""" Reset NIFIClient configuration"""
|
|
78
|
-
self.__nifi_client = NIFIClient().configure(
|
|
81
|
+
self.__nifi_client = NIFIClient().configure(
|
|
82
|
+
self.__conf, self.__secure, use_keycloak_account=self.use_keycloak_account)
|
|
79
83
|
|
|
80
84
|
# Helper methods
|
|
81
85
|
def process_wildcards(self, name):
|
|
@@ -158,9 +162,13 @@ class HIDDataTransfer:
|
|
|
158
162
|
hpc_secret_key=hpc_secret_key_path,
|
|
159
163
|
data_source=data_source,
|
|
160
164
|
data_target=data_target,
|
|
165
|
+
recursive=recursive,
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
processors_with_kerberos = ["ListHDFS", "FetchHDFS"]
|
|
169
|
+
kerberos_account = SimpleNamespace(
|
|
161
170
|
kerberos_principal=kerberos_principal,
|
|
162
171
|
kerberos_password=kerberos_password,
|
|
163
|
-
recursive=recursive,
|
|
164
172
|
)
|
|
165
173
|
|
|
166
174
|
self.__logger.info(
|
|
@@ -170,12 +178,26 @@ class HIDDataTransfer:
|
|
|
170
178
|
try:
|
|
171
179
|
arguments: Dict[str, Any] = {}
|
|
172
180
|
self.__nifi_client.add_default_hpc_parameters(arguments, args)
|
|
173
|
-
|
|
181
|
+
|
|
174
182
|
arguments[HDFS_DATA_FOLDER] = \
|
|
175
183
|
"/".join(args.data_source.split("/")[:-1])
|
|
176
184
|
arguments[HDFS_FILENAME] = \
|
|
177
185
|
self.process_wildcards(args.data_source.split("/")[-1])
|
|
178
|
-
|
|
186
|
+
|
|
187
|
+
# If multiple data source files are selected, data_target represents a folder
|
|
188
|
+
# Else If data_target ends with / represents a folder, otherwise a file
|
|
189
|
+
arguments[HPC_TARGET_FILENAME] = ""
|
|
190
|
+
if args.data_source and (
|
|
191
|
+
"*" in args.data_source or
|
|
192
|
+
"?" in args.data_source
|
|
193
|
+
):
|
|
194
|
+
arguments[HPC_TARGET_FOLDER] = args.data_target
|
|
195
|
+
elif args.data_target.endswith('/'):
|
|
196
|
+
arguments[HPC_TARGET_FOLDER] = args.data_target[:-1]
|
|
197
|
+
else:
|
|
198
|
+
arguments[HPC_TARGET_FOLDER] = "/".join(args.data_target.split("/")[:-1])
|
|
199
|
+
arguments[HPC_TARGET_FILENAME] = "/".join(args.data_target.split("/")[-1:])
|
|
200
|
+
|
|
179
201
|
arguments[RECURSIVE] = args.recursive
|
|
180
202
|
|
|
181
203
|
execution_type = {
|
|
@@ -197,14 +219,6 @@ class HIDDataTransfer:
|
|
|
197
219
|
args
|
|
198
220
|
)
|
|
199
221
|
|
|
200
|
-
processors_with_hdfs_sensitive_parameters = \
|
|
201
|
-
["ListHDFS", "FetchHDFS"]
|
|
202
|
-
sensitive_parameters.update(
|
|
203
|
-
self.__nifi_client.set_sensitive_hdfs_parameters(
|
|
204
|
-
processors_with_hdfs_sensitive_parameters, args
|
|
205
|
-
)
|
|
206
|
-
)
|
|
207
|
-
|
|
208
222
|
if not args.hpc_secret_key and not args.hpc_password:
|
|
209
223
|
raise HidDataTransferException(HPC_ACCOUNT_MSG)
|
|
210
224
|
|
|
@@ -227,6 +241,8 @@ class HIDDataTransfer:
|
|
|
227
241
|
accounting_target="PutSFTP",
|
|
228
242
|
concurrent_tasks=concurrent_tasks_dict,
|
|
229
243
|
ignore_bulletins_in_processors=["PutSFTP"],
|
|
244
|
+
processors_with_kerberos=processors_with_kerberos,
|
|
245
|
+
kerberos_account=kerberos_account,
|
|
230
246
|
)
|
|
231
247
|
|
|
232
248
|
except Exception as ex:
|
|
@@ -387,6 +403,12 @@ class HIDDataTransfer:
|
|
|
387
403
|
kerberos_password=kerberos_password,
|
|
388
404
|
)
|
|
389
405
|
|
|
406
|
+
processors_with_kerberos = ["ListHDFS", "FetchHDFS"]
|
|
407
|
+
kerberos_account = SimpleNamespace(
|
|
408
|
+
kerberos_principal=kerberos_principal,
|
|
409
|
+
kerberos_password=kerberos_password,
|
|
410
|
+
)
|
|
411
|
+
|
|
390
412
|
self.__logger.info(
|
|
391
413
|
"executing hdfs2hpc_2fa command with args: %s",
|
|
392
414
|
self.__nifi_client.format_args_to_string(args),
|
|
@@ -399,7 +421,6 @@ class HIDDataTransfer:
|
|
|
399
421
|
"/".join(args.data_source.split("/")[:-1])
|
|
400
422
|
arguments[HDFS_FILENAME] = \
|
|
401
423
|
self.process_wildcards(args.data_source.split("/")[-1])
|
|
402
|
-
arguments[KERBEROS_PRINCIPAL] = args.kerberos_principal
|
|
403
424
|
|
|
404
425
|
# set local.data_folder to keep dataset retrieved from HDFS
|
|
405
426
|
__uuid = uuid.uuid4()
|
|
@@ -422,16 +443,6 @@ class HIDDataTransfer:
|
|
|
422
443
|
],
|
|
423
444
|
}
|
|
424
445
|
|
|
425
|
-
sensitive_parameters = {}
|
|
426
|
-
|
|
427
|
-
processors_with_hdfs_sensitive_parameters = \
|
|
428
|
-
["ListHDFS", "FetchHDFS"]
|
|
429
|
-
sensitive_parameters.update(
|
|
430
|
-
self.__nifi_client.set_sensitive_hdfs_parameters(
|
|
431
|
-
processors_with_hdfs_sensitive_parameters, args
|
|
432
|
-
)
|
|
433
|
-
)
|
|
434
|
-
|
|
435
446
|
if not args.hpc_secret_key:
|
|
436
447
|
raise HidDataTransferException(HPC_ACCOUNT_MSG)
|
|
437
448
|
|
|
@@ -450,10 +461,12 @@ class HIDDataTransfer:
|
|
|
450
461
|
execution_type,
|
|
451
462
|
arguments,
|
|
452
463
|
keys_arguments=keys_arguments,
|
|
453
|
-
sensitive_parameters=
|
|
464
|
+
sensitive_parameters=None,
|
|
454
465
|
keycloak_token=self.__keycloak_token,
|
|
455
466
|
accounting_target="PutFile",
|
|
456
467
|
concurrent_tasks=concurrent_tasks_dict,
|
|
468
|
+
processors_with_kerberos=processors_with_kerberos,
|
|
469
|
+
kerberos_account=kerberos_account,
|
|
457
470
|
)
|
|
458
471
|
process_ids.append(process_id)
|
|
459
472
|
|
|
@@ -462,7 +475,7 @@ class HIDDataTransfer:
|
|
|
462
475
|
execution_type,
|
|
463
476
|
arguments,
|
|
464
477
|
keys_arguments=keys_arguments,
|
|
465
|
-
sensitive_parameters=
|
|
478
|
+
sensitive_parameters=None,
|
|
466
479
|
keycloak_token=self.__keycloak_token,
|
|
467
480
|
processor_with_2fa="SftpTransferToHPCWithVPNCode",
|
|
468
481
|
callback_2fa=callback_2fa,
|
|
@@ -536,6 +549,12 @@ class HIDDataTransfer:
|
|
|
536
549
|
recursive=recursive,
|
|
537
550
|
)
|
|
538
551
|
|
|
552
|
+
processors_with_kerberos = ["PutHDFS"]
|
|
553
|
+
kerberos_account = SimpleNamespace(
|
|
554
|
+
kerberos_principal=kerberos_principal,
|
|
555
|
+
kerberos_password=kerberos_password,
|
|
556
|
+
)
|
|
557
|
+
|
|
539
558
|
self.__logger.info(
|
|
540
559
|
"executing hpc2hdfs command with args: %s",
|
|
541
560
|
self.__nifi_client.format_args_to_string(args),
|
|
@@ -548,8 +567,21 @@ class HIDDataTransfer:
|
|
|
548
567
|
arguments[HPC_DATA_FOLDER] = args.data_source[
|
|
549
568
|
: args.data_source.rfind("/")
|
|
550
569
|
]
|
|
551
|
-
|
|
552
|
-
|
|
570
|
+
|
|
571
|
+
# If multiple data source files are selected, data_target represents a folder
|
|
572
|
+
# Else If data_target ends with / represents a folder, otherwise a file
|
|
573
|
+
arguments[HDFS_DATA_FILENAME] = ""
|
|
574
|
+
if args.data_source and (
|
|
575
|
+
"*" in args.data_source or
|
|
576
|
+
"?" in args.data_source
|
|
577
|
+
):
|
|
578
|
+
arguments[HDFS_DATA_FOLDER] = args.data_target
|
|
579
|
+
elif args.data_target.endswith('/'):
|
|
580
|
+
arguments[HDFS_DATA_FOLDER] = args.data_target[:-1]
|
|
581
|
+
else:
|
|
582
|
+
arguments[HDFS_DATA_FOLDER] = "/".join(args.data_target.split("/")[:-1])
|
|
583
|
+
arguments[HDFS_DATA_FILENAME] = "/".join(args.data_target.split("/")[-1:])
|
|
584
|
+
|
|
553
585
|
arguments[RECURSIVE] = args.recursive
|
|
554
586
|
|
|
555
587
|
execution_type = {
|
|
@@ -572,14 +604,6 @@ class HIDDataTransfer:
|
|
|
572
604
|
processors_with_hpc_sensitive_parameters, args
|
|
573
605
|
)
|
|
574
606
|
|
|
575
|
-
processors_with_hdfs_sensitive_parameters = \
|
|
576
|
-
["PutHDFS"]
|
|
577
|
-
sensitive_parameters.update(
|
|
578
|
-
self.__nifi_client.set_sensitive_hdfs_parameters(
|
|
579
|
-
processors_with_hdfs_sensitive_parameters, args
|
|
580
|
-
)
|
|
581
|
-
)
|
|
582
|
-
|
|
583
607
|
if not args.hpc_secret_key and not args.hpc_password:
|
|
584
608
|
raise HidDataTransferException(HPC_ACCOUNT_MSG)
|
|
585
609
|
|
|
@@ -602,6 +626,8 @@ class HIDDataTransfer:
|
|
|
602
626
|
accounting_target="PutHDFS",
|
|
603
627
|
concurrent_tasks=concurrent_tasks_dict,
|
|
604
628
|
ignore_bulletins_in_processors=["FetchSFTP"],
|
|
629
|
+
processors_with_kerberos=processors_with_kerberos,
|
|
630
|
+
kerberos_account=kerberos_account,
|
|
605
631
|
)
|
|
606
632
|
|
|
607
633
|
except Exception as ex:
|
|
@@ -712,6 +738,12 @@ class HIDDataTransfer:
|
|
|
712
738
|
kerberos_password=kerberos_password,
|
|
713
739
|
)
|
|
714
740
|
|
|
741
|
+
processors_with_kerberos = ["PutHDFS"]
|
|
742
|
+
kerberos_account = SimpleNamespace(
|
|
743
|
+
kerberos_principal=kerberos_principal,
|
|
744
|
+
kerberos_password=kerberos_password,
|
|
745
|
+
)
|
|
746
|
+
|
|
715
747
|
self.__logger.info(
|
|
716
748
|
"executing hpc2hdfs_2fa command with args: %s",
|
|
717
749
|
self.__nifi_client.format_args_to_string(args),
|
|
@@ -728,7 +760,6 @@ class HIDDataTransfer:
|
|
|
728
760
|
: args.data_source.rfind("/")
|
|
729
761
|
]
|
|
730
762
|
arguments[HDFS_DATA_FOLDER] = args.data_target
|
|
731
|
-
arguments[KERBEROS_PRINCIPAL] = args.kerberos_principal
|
|
732
763
|
|
|
733
764
|
# set local.data_folder to keep dataset retrieved from HPC
|
|
734
765
|
__uuid = uuid.uuid4()
|
|
@@ -758,14 +789,6 @@ class HIDDataTransfer:
|
|
|
758
789
|
processors_with_hpc_sensitive_parameters, args
|
|
759
790
|
)
|
|
760
791
|
|
|
761
|
-
processors_with_hdfs_sensitive_parameters = \
|
|
762
|
-
["PutHDFS"]
|
|
763
|
-
sensitive_parameters.update(
|
|
764
|
-
self.__nifi_client.set_sensitive_hdfs_parameters(
|
|
765
|
-
processors_with_hdfs_sensitive_parameters, args
|
|
766
|
-
)
|
|
767
|
-
)
|
|
768
|
-
|
|
769
792
|
if not args.hpc_secret_key and not args.hpc_password:
|
|
770
793
|
raise HidDataTransferException(HPC_ACCOUNT_MSG)
|
|
771
794
|
|
|
@@ -788,7 +811,6 @@ class HIDDataTransfer:
|
|
|
788
811
|
keycloak_token=self.__keycloak_token,
|
|
789
812
|
processor_with_2fa="SftpTransferFromHPCWithVPNCode",
|
|
790
813
|
callback_2fa=callback_2fa,
|
|
791
|
-
accounting_target="PutHDFS",
|
|
792
814
|
concurrent_tasks=concurrent_tasks_dict,
|
|
793
815
|
)
|
|
794
816
|
process_ids.append(process_id)
|
|
@@ -802,6 +824,8 @@ class HIDDataTransfer:
|
|
|
802
824
|
keycloak_token=self.__keycloak_token,
|
|
803
825
|
accounting_target="PutHDFS",
|
|
804
826
|
concurrent_tasks=concurrent_tasks_dict,
|
|
827
|
+
processors_with_kerberos=processors_with_kerberos,
|
|
828
|
+
kerberos_account=kerberos_account,
|
|
805
829
|
)
|
|
806
830
|
process_ids.append(process_id)
|
|
807
831
|
|
|
@@ -913,6 +937,12 @@ class HIDDataTransfer:
|
|
|
913
937
|
recursive=recursive,
|
|
914
938
|
)
|
|
915
939
|
|
|
940
|
+
processors_with_kerberos = ["ListHDFS", "FetchHDFS"]
|
|
941
|
+
kerberos_account = SimpleNamespace(
|
|
942
|
+
kerberos_principal=kerberos_principal,
|
|
943
|
+
kerberos_password=kerberos_password,
|
|
944
|
+
)
|
|
945
|
+
|
|
916
946
|
self.__logger.info(
|
|
917
947
|
"executing hdfs2ckan command with args: %s",
|
|
918
948
|
self.__nifi_client.format_args_to_string(args),
|
|
@@ -923,7 +953,6 @@ class HIDDataTransfer:
|
|
|
923
953
|
"/".join(args.data_source.split("/")[:-1])
|
|
924
954
|
arguments[HDFS_FILENAME] = \
|
|
925
955
|
self.process_wildcards(args.data_source.split("/")[-1])
|
|
926
|
-
arguments[KERBEROS_PRINCIPAL] = args.kerberos_principal
|
|
927
956
|
self.__nifi_client.add_default_ckan_parameters(arguments, args)
|
|
928
957
|
arguments[self.__nifi_client.CKAN_RESOURCE] = \
|
|
929
958
|
self.generate_ckan_resource_name(args)
|
|
@@ -943,14 +972,6 @@ class HIDDataTransfer:
|
|
|
943
972
|
processors_with_ckan_sensitive_parameters, args
|
|
944
973
|
)
|
|
945
974
|
|
|
946
|
-
processors_with_hdfs_sensitive_parameters = \
|
|
947
|
-
["ListHDFS", "FetchHDFS"]
|
|
948
|
-
sensitive_parameters.update(
|
|
949
|
-
self.__nifi_client.set_sensitive_hdfs_parameters(
|
|
950
|
-
processors_with_hdfs_sensitive_parameters, args
|
|
951
|
-
)
|
|
952
|
-
)
|
|
953
|
-
|
|
954
975
|
# Set the number of concurrent tasks
|
|
955
976
|
# for parallel processors in the pipeline
|
|
956
977
|
if concurrent_tasks is None:
|
|
@@ -982,6 +1003,8 @@ class HIDDataTransfer:
|
|
|
982
1003
|
accounting_target="MergeContent",
|
|
983
1004
|
concurrent_tasks=concurrent_tasks_dict,
|
|
984
1005
|
synchronization_processor_name="MergeContent",
|
|
1006
|
+
processors_with_kerberos=processors_with_kerberos,
|
|
1007
|
+
kerberos_account=kerberos_account,
|
|
985
1008
|
)
|
|
986
1009
|
|
|
987
1010
|
except Exception as ex:
|
|
@@ -1033,6 +1056,12 @@ class HIDDataTransfer:
|
|
|
1033
1056
|
kerberos_password=kerberos_password,
|
|
1034
1057
|
)
|
|
1035
1058
|
|
|
1059
|
+
processors_with_kerberos = ["PutHDFS"]
|
|
1060
|
+
kerberos_account = SimpleNamespace(
|
|
1061
|
+
kerberos_principal=kerberos_principal,
|
|
1062
|
+
kerberos_password=kerberos_password,
|
|
1063
|
+
)
|
|
1064
|
+
|
|
1036
1065
|
self.__logger.info(
|
|
1037
1066
|
"executing ckan2hdfs command with args: %s",
|
|
1038
1067
|
self.__nifi_client.format_args_to_string(args),
|
|
@@ -1042,8 +1071,20 @@ class HIDDataTransfer:
|
|
|
1042
1071
|
self.__nifi_client.add_default_ckan_parameters(arguments, args)
|
|
1043
1072
|
arguments[self.__nifi_client.CKAN_RESOURCE] = \
|
|
1044
1073
|
self.process_wildcards(args.ckan_resource)
|
|
1045
|
-
|
|
1046
|
-
|
|
1074
|
+
|
|
1075
|
+
# If multiple ckan resource files are selected, data_target represents a folder
|
|
1076
|
+
# Else If data_target ends with / represents a folder, otherwise a file
|
|
1077
|
+
arguments[HDFS_DATA_FILENAME] = ""
|
|
1078
|
+
if args.ckan_resource and (
|
|
1079
|
+
"*" in args.ckan_resource or
|
|
1080
|
+
"?" in args.ckan_resource
|
|
1081
|
+
):
|
|
1082
|
+
arguments[HDFS_DATA_FOLDER] = args.data_target
|
|
1083
|
+
elif args.data_target.endswith('/'):
|
|
1084
|
+
arguments[HDFS_DATA_FOLDER] = args.data_target[:-1]
|
|
1085
|
+
else:
|
|
1086
|
+
arguments[HDFS_DATA_FOLDER] = "/".join(args.data_target.split("/")[:-1])
|
|
1087
|
+
arguments[HDFS_DATA_FILENAME] = "/".join(args.data_target.split("/")[-1:])
|
|
1047
1088
|
|
|
1048
1089
|
execution_type = {
|
|
1049
1090
|
"CKANFileDownloader": ExecutionType.ONCE,
|
|
@@ -1056,14 +1097,6 @@ class HIDDataTransfer:
|
|
|
1056
1097
|
processors_with_ckan_sensitive_parameters, args
|
|
1057
1098
|
)
|
|
1058
1099
|
|
|
1059
|
-
processors_with_hdfs_sensitive_parameters = \
|
|
1060
|
-
["PutHDFS"]
|
|
1061
|
-
sensitive_parameters.update(
|
|
1062
|
-
self.__nifi_client.set_sensitive_hdfs_parameters(
|
|
1063
|
-
processors_with_hdfs_sensitive_parameters, args
|
|
1064
|
-
)
|
|
1065
|
-
)
|
|
1066
|
-
|
|
1067
1100
|
# Set the number of concurrent tasks
|
|
1068
1101
|
# for parallel processors in the pipeline
|
|
1069
1102
|
if concurrent_tasks is None:
|
|
@@ -1095,7 +1128,9 @@ class HIDDataTransfer:
|
|
|
1095
1128
|
sensitive_parameters,
|
|
1096
1129
|
keycloak_token=self.__keycloak_token,
|
|
1097
1130
|
accounting_target="PutHDFS",
|
|
1098
|
-
concurrent_tasks=concurrent_tasks_dict
|
|
1131
|
+
concurrent_tasks=concurrent_tasks_dict,
|
|
1132
|
+
processors_with_kerberos=processors_with_kerberos,
|
|
1133
|
+
kerberos_account=kerberos_account,
|
|
1099
1134
|
)
|
|
1100
1135
|
|
|
1101
1136
|
except Exception as ex:
|
|
@@ -1169,11 +1204,24 @@ class HIDDataTransfer:
|
|
|
1169
1204
|
try:
|
|
1170
1205
|
arguments: Dict[str, Any] = {}
|
|
1171
1206
|
self.__nifi_client.add_default_hpc_parameters(arguments, args)
|
|
1172
|
-
arguments[HPC_TARGET_FOLDER] = args.data_target
|
|
1173
1207
|
self.__nifi_client.add_default_ckan_parameters(arguments, args)
|
|
1174
1208
|
arguments[self.__nifi_client.CKAN_RESOURCE] = \
|
|
1175
1209
|
self.process_wildcards(args.ckan_resource)
|
|
1176
1210
|
|
|
1211
|
+
# If multiple ckan resource files are selected, data_target represents a folder
|
|
1212
|
+
# Else If data_target ends with / represents a folder, otherwise a file
|
|
1213
|
+
arguments[HPC_TARGET_FILENAME] = ""
|
|
1214
|
+
if args.ckan_resource and (
|
|
1215
|
+
"*" in args.ckan_resource or
|
|
1216
|
+
"?" in args.ckan_resource
|
|
1217
|
+
):
|
|
1218
|
+
arguments[HPC_TARGET_FOLDER] = args.data_target
|
|
1219
|
+
elif args.data_target.endswith('/'):
|
|
1220
|
+
arguments[HPC_TARGET_FOLDER] = args.data_target[:-1]
|
|
1221
|
+
else:
|
|
1222
|
+
arguments[HPC_TARGET_FOLDER] = "/".join(args.data_target.split("/")[:-1])
|
|
1223
|
+
arguments[HPC_TARGET_FILENAME] = "/".join(args.data_target.split("/")[-1:])
|
|
1224
|
+
|
|
1177
1225
|
keys_arguments = {
|
|
1178
1226
|
self.__nifi_client.HPC_SECRET_KEY_PATH: arguments[
|
|
1179
1227
|
self.__nifi_client.HPC_SECRET_KEY_PATH
|
|
@@ -69,12 +69,13 @@ class KeycloakRESTClient:
|
|
|
69
69
|
|
|
70
70
|
def configure(
|
|
71
71
|
self, conf: HidDataTransferConfiguration,
|
|
72
|
-
secure: bool = False, refresh: bool = False
|
|
72
|
+
secure: bool = False, refresh: bool = False,
|
|
73
|
+
use_keycloak_account = True,
|
|
73
74
|
) -> KeycloakRESTClient:
|
|
74
75
|
"""constructs a API client,
|
|
75
76
|
with the Keycloak endpoint taken from configuration
|
|
76
77
|
"""
|
|
77
|
-
conf.check_keycloak_conf()
|
|
78
|
+
conf.check_keycloak_conf(use_keycloak_account)
|
|
78
79
|
self.__conf = conf
|
|
79
80
|
self.__refresh = refresh
|
|
80
81
|
self.__keycloak_login = conf.keycloak_login()
|
|
@@ -117,6 +118,7 @@ class KeycloakRESTClient:
|
|
|
117
118
|
|
|
118
119
|
def set_token(self, user, token, expires_in, refresh_token):
|
|
119
120
|
"""Set the given token and renews it every time it expires"""
|
|
121
|
+
self.__keycloak_login = user
|
|
120
122
|
self.__token = token
|
|
121
123
|
self.__refresh_token = refresh_token
|
|
122
124
|
self.__set_expires_in(expires_in)
|
|
@@ -135,14 +135,15 @@ class NIFIClient:
|
|
|
135
135
|
self.check_status_sleep_lapse = 1
|
|
136
136
|
|
|
137
137
|
def configure(self, conf: HidDataTransferConfiguration,
|
|
138
|
-
secure: bool = False) -> NIFIClient:
|
|
138
|
+
secure: bool = False, use_keycloak_account = True) -> NIFIClient:
|
|
139
139
|
"""constructs a NIFI client,
|
|
140
140
|
with the NIFI endpoint taken from configuration
|
|
141
141
|
"""
|
|
142
142
|
self.__conf = conf
|
|
143
143
|
self.nifi_rest_client = NIFIRESTClient().configure(conf, secure)
|
|
144
|
+
self.use_keycloak_account = use_keycloak_account
|
|
144
145
|
self.keycloak_rest_client = KeycloakRESTClient().configure(
|
|
145
|
-
conf, secure, refresh=True)
|
|
146
|
+
conf, secure, refresh=True, use_keycloak_account=self.use_keycloak_account)
|
|
146
147
|
self.__logger = self.__conf.logger("nifi.v2.client")
|
|
147
148
|
self.check_status_sleep_lapse = int(
|
|
148
149
|
self.__conf.check_status_sleep_lapse())
|
|
@@ -152,14 +153,21 @@ class NIFIClient:
|
|
|
152
153
|
"""gets the NIFI access token,
|
|
153
154
|
using NIFI account taken from configuration
|
|
154
155
|
this access token is required for any further request sent to NIFI
|
|
156
|
+
If a taken was provided upon configuration, it gets the latest renewed
|
|
155
157
|
"""
|
|
158
|
+
|
|
156
159
|
if self.__conf.nifi_login() and self.__conf.nifi_passwd():
|
|
157
160
|
return self.nifi_rest_client.get_access_token()
|
|
158
|
-
|
|
161
|
+
# Keycloak token provided, but not an account
|
|
162
|
+
elif not self.use_keycloak_account:
|
|
159
163
|
return self.keycloak_rest_client.get_token()
|
|
160
|
-
|
|
164
|
+
# Keycloak token not provided, check an account is available
|
|
165
|
+
elif self.use_keycloak_account and self.__conf.keycloak_login() and \
|
|
166
|
+
self.__conf.keycloak_passwd():
|
|
167
|
+
return self.keycloak_rest_client.get_token()
|
|
168
|
+
else: # Not valid token provider configuration found
|
|
161
169
|
raise HidDataTransferException(
|
|
162
|
-
"NIFI or Keycloak login and password must be provided"
|
|
170
|
+
"NIFI or Keycloak account (login and password) or Keycloak token must be provided"
|
|
163
171
|
)
|
|
164
172
|
|
|
165
173
|
def set_access_token(self, keycloak_token):
|
|
@@ -192,13 +200,13 @@ class NIFIClient:
|
|
|
192
200
|
def get_process_group_processors(self, group_id) -> dict:
|
|
193
201
|
"""gets the processors of a process group identified by id"""
|
|
194
202
|
return self.nifi_rest_client.process_group_get_request(
|
|
195
|
-
group_id, self.token(), "processors"
|
|
203
|
+
group_id, self.token(), entity="processors"
|
|
196
204
|
)
|
|
197
205
|
|
|
198
206
|
def get_process_group_connections(self, group_id) -> dict:
|
|
199
207
|
"""gets the connetions of a process group identified by id"""
|
|
200
208
|
return self.nifi_rest_client.process_group_get_request(
|
|
201
|
-
group_id, self.token(), "connections"
|
|
209
|
+
group_id, self.token(), entity="connections"
|
|
202
210
|
)
|
|
203
211
|
|
|
204
212
|
def get_processors_sequence(self, group_id) -> list:
|
|
@@ -324,6 +332,22 @@ class NIFIClient:
|
|
|
324
332
|
processor["component"]["config"][configuration_name] = \
|
|
325
333
|
configuration_value
|
|
326
334
|
|
|
335
|
+
def update_kpus_kerberos_account(
|
|
336
|
+
self, kpus, kerberos_account,
|
|
337
|
+
):
|
|
338
|
+
"""updates the Kerberos account of a kpus"""
|
|
339
|
+
kpus["component"]["properties"]['Kerberos Principal'] = \
|
|
340
|
+
kerberos_account.kerberos_principal
|
|
341
|
+
kpus["component"]["properties"]['Kerberos Password'] = \
|
|
342
|
+
kerberos_account.kerberos_password
|
|
343
|
+
|
|
344
|
+
def update_processor_kus(
|
|
345
|
+
self, processor, kus_id,
|
|
346
|
+
):
|
|
347
|
+
"""updates the KUs of a processor"""
|
|
348
|
+
processor["component"]['config']["properties"]['Kerberos User Service'] = \
|
|
349
|
+
kus_id
|
|
350
|
+
|
|
327
351
|
# DELETE requests
|
|
328
352
|
|
|
329
353
|
# MULTI-REQUESTS methods
|
|
@@ -890,6 +914,8 @@ class NIFIClient:
|
|
|
890
914
|
accounting_target: Optional[str] = None,
|
|
891
915
|
concurrent_tasks: Optional[dict] = None,
|
|
892
916
|
ignore_bulletins_in_processors=None,
|
|
917
|
+
processors_with_kerberos=None,
|
|
918
|
+
kerberos_account=None,
|
|
893
919
|
) -> tuple[str, AccountingInfo]:
|
|
894
920
|
"""MAIN method to run a processor from a template identify by name
|
|
895
921
|
The procedure is as follows:
|
|
@@ -946,6 +972,11 @@ class NIFIClient:
|
|
|
946
972
|
self.__logger.info(
|
|
947
973
|
"Process group %s created\n", process_group["id"])
|
|
948
974
|
|
|
975
|
+
# Set Kerberos configuration
|
|
976
|
+
if kerberos_account and processors_with_kerberos:
|
|
977
|
+
self.set_kerberos_configuration(
|
|
978
|
+
process_group["id"], kerberos_account, processors_with_kerberos)
|
|
979
|
+
|
|
949
980
|
# Get ordered list of all processors in the process group
|
|
950
981
|
processors = self.get_ordered_processors_in_group(
|
|
951
982
|
process_group["id"])
|
|
@@ -1102,6 +1133,8 @@ class NIFIClient:
|
|
|
1102
1133
|
concurrent_tasks: Optional[dict] = None,
|
|
1103
1134
|
synchronization_processor_name=None,
|
|
1104
1135
|
ignore_bulletins_in_processors=None,
|
|
1136
|
+
processors_with_kerberos=None,
|
|
1137
|
+
kerberos_account=None,
|
|
1105
1138
|
) -> tuple[str, AccountingInfo]:
|
|
1106
1139
|
"""MAIN method to run a processor from a template identify by name
|
|
1107
1140
|
The procedure is as follows:
|
|
@@ -1127,6 +1160,11 @@ class NIFIClient:
|
|
|
1127
1160
|
self.__logger.info(
|
|
1128
1161
|
"Process group %s created\n", process_group["id"])
|
|
1129
1162
|
|
|
1163
|
+
# Set Kerberos configuration
|
|
1164
|
+
if kerberos_account and processors_with_kerberos:
|
|
1165
|
+
self.set_kerberos_configuration(
|
|
1166
|
+
process_group["id"], kerberos_account, processors_with_kerberos)
|
|
1167
|
+
|
|
1130
1168
|
# Accounting initialization
|
|
1131
1169
|
pipeline_start_time = time.time()
|
|
1132
1170
|
|
|
@@ -1156,7 +1194,8 @@ class NIFIClient:
|
|
|
1156
1194
|
accounting_target,
|
|
1157
1195
|
parameter_context,
|
|
1158
1196
|
synchronization_processor_name=synchronization_processor_name,
|
|
1159
|
-
first_processor_expected_outgoing_flowfiles=
|
|
1197
|
+
first_processor_expected_outgoing_flowfiles=
|
|
1198
|
+
first_processor_expected_outgoing_flowfiles,
|
|
1160
1199
|
ignore_bulletins_in_processors=ignore_bulletins_in_processors,
|
|
1161
1200
|
)
|
|
1162
1201
|
|
|
@@ -1338,21 +1377,21 @@ class NIFIClient:
|
|
|
1338
1377
|
|
|
1339
1378
|
ok, response = self.start_process_group(process_group)
|
|
1340
1379
|
|
|
1341
|
-
# Wait for first processor to find source files
|
|
1342
|
-
if not self.has_processor_executed_once_and_produce_outgoing_flowfiles(
|
|
1343
|
-
processors[0]):
|
|
1344
|
-
raise HidDataTransferException("Source files not found")
|
|
1345
|
-
|
|
1346
|
-
# manage the synchronization point if required
|
|
1347
|
-
if synchronization_processor_name:
|
|
1348
|
-
self.synchronize_processor_execution(
|
|
1349
|
-
process_group['id'],
|
|
1350
|
-
synchronization_processor_name,
|
|
1351
|
-
execution_type,
|
|
1352
|
-
first_processor_expected_outgoing_flowfiles,
|
|
1353
|
-
ignore_bulletins_in_processors)
|
|
1354
|
-
|
|
1355
1380
|
if ok:
|
|
1381
|
+
# Wait for first processor to find source files
|
|
1382
|
+
if not self.has_processor_executed_once_and_produce_outgoing_flowfiles(
|
|
1383
|
+
processors[0]):
|
|
1384
|
+
raise HidDataTransferException("Source files not found")
|
|
1385
|
+
|
|
1386
|
+
# manage the synchronization point if required
|
|
1387
|
+
if synchronization_processor_name:
|
|
1388
|
+
self.synchronize_processor_execution(
|
|
1389
|
+
process_group['id'],
|
|
1390
|
+
synchronization_processor_name,
|
|
1391
|
+
execution_type,
|
|
1392
|
+
first_processor_expected_outgoing_flowfiles,
|
|
1393
|
+
ignore_bulletins_in_processors)
|
|
1394
|
+
|
|
1356
1395
|
self.wait_for_process_group_completion(
|
|
1357
1396
|
process_group['id'], processors,
|
|
1358
1397
|
ignore_bulletins_in_processors)
|
|
@@ -1401,6 +1440,30 @@ class NIFIClient:
|
|
|
1401
1440
|
processor, self.token())
|
|
1402
1441
|
return processor
|
|
1403
1442
|
|
|
1443
|
+
def set_kpus_kerberos_account(
|
|
1444
|
+
self, kpus, kerberos_account):
|
|
1445
|
+
"""Set the Kerberos account of a kpus instance"""
|
|
1446
|
+
|
|
1447
|
+
self.update_kpus_kerberos_account(
|
|
1448
|
+
kpus,
|
|
1449
|
+
kerberos_account,
|
|
1450
|
+
)
|
|
1451
|
+
kpus = self.nifi_rest_client.update_kpus(
|
|
1452
|
+
kpus, self.token())
|
|
1453
|
+
return kpus
|
|
1454
|
+
|
|
1455
|
+
def set_processor_kus(
|
|
1456
|
+
self, processor, kus_id):
|
|
1457
|
+
"""Set the Kerberos User Service of a processor instance"""
|
|
1458
|
+
|
|
1459
|
+
self.update_processor_kus(
|
|
1460
|
+
processor,
|
|
1461
|
+
kus_id,
|
|
1462
|
+
)
|
|
1463
|
+
processor = self.nifi_rest_client.update_processor(
|
|
1464
|
+
processor, self.token())
|
|
1465
|
+
return processor
|
|
1466
|
+
|
|
1404
1467
|
def set_2fa_token(self, processor, parameter_context,
|
|
1405
1468
|
processor_with_2fa, callback_2fa):
|
|
1406
1469
|
'''Set the 2FA token in context parameter
|
|
@@ -1707,19 +1770,25 @@ class NIFIClient:
|
|
|
1707
1770
|
)
|
|
1708
1771
|
return sensitive_parameters
|
|
1709
1772
|
|
|
1710
|
-
def
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1773
|
+
def set_kerberos_configuration(self, process_group_id,
|
|
1774
|
+
kerberos_account, processors_with_kerberos):
|
|
1775
|
+
"""Set Kerberos configuration for processors"""
|
|
1776
|
+
# Implementation to configure Kerberos for specified processors
|
|
1777
|
+
processors = self.get_ordered_processors_in_group(process_group_id)
|
|
1778
|
+
|
|
1779
|
+
# Create a Kerberos Password User Service (KPUS) associated to a process group
|
|
1780
|
+
kpus = self.nifi_rest_client.instantiate_kpus(process_group_id, self.token())
|
|
1781
|
+
# Set principal and password in KPUS
|
|
1782
|
+
kpus = self.set_kpus_kerberos_account(kpus, kerberos_account)
|
|
1783
|
+
# Enable KUPS
|
|
1784
|
+
kpus = self.nifi_rest_client.enable_kpus(kpus, self.token())
|
|
1785
|
+
|
|
1786
|
+
for processor_name in processors_with_kerberos:
|
|
1787
|
+
# Get processor by name
|
|
1788
|
+
processor = self.find_processor_by_name(processors, processor_name)
|
|
1789
|
+
|
|
1790
|
+
# Save changes in processor
|
|
1791
|
+
self.set_processor_kus(processor, kpus['id'])
|
|
1723
1792
|
|
|
1724
1793
|
def clean_process_group_up(self, process_group_id, retry=True):
|
|
1725
1794
|
"""Clean up the process group and associated parameter context"""
|
|
@@ -1729,13 +1798,17 @@ class NIFIClient:
|
|
|
1729
1798
|
try:
|
|
1730
1799
|
# Remove transferred keys
|
|
1731
1800
|
self.__logger.debug("Removing uploaded keys\n")
|
|
1732
|
-
self.remove_uploaded_keys(
|
|
1801
|
+
self.remove_uploaded_keys(process_group_id)
|
|
1733
1802
|
|
|
1734
1803
|
# Stop process_group and wait for all processosr to be stopped
|
|
1735
|
-
self.stop_process_group(
|
|
1804
|
+
self.stop_process_group(process_group_id)
|
|
1805
|
+
|
|
1806
|
+
# Disable controller services
|
|
1807
|
+
self.nifi_rest_client.disable_controller_services(
|
|
1808
|
+
process_group_id, self.token())
|
|
1736
1809
|
|
|
1737
1810
|
# Empty process group queues
|
|
1738
|
-
self.empty_process_group_queues(
|
|
1811
|
+
self.empty_process_group_queues(process_group_id)
|
|
1739
1812
|
|
|
1740
1813
|
# Get parameter context
|
|
1741
1814
|
if "parameterContext" in process_group["component"]:
|
|
@@ -1759,10 +1832,6 @@ class NIFIClient:
|
|
|
1759
1832
|
except HidDataTransferException:
|
|
1760
1833
|
# If case of exception try clean up again
|
|
1761
1834
|
if retry:
|
|
1762
|
-
# self.stop_process_group(
|
|
1763
|
-
# process_group["id"])
|
|
1764
|
-
# self.empty_process_group_queues(
|
|
1765
|
-
# process_group["id"])
|
|
1766
1835
|
self.clean_process_group_up(
|
|
1767
1836
|
process_group["id"], retry=False)
|
|
1768
1837
|
|
{hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/nifi/nifi_rest.py
RENAMED
|
@@ -126,14 +126,16 @@ class NIFIRESTClient:
|
|
|
126
126
|
url = self.build_url("nifi-api", "flow", "process-groups", "root")
|
|
127
127
|
return self._get_entity(url, token)
|
|
128
128
|
|
|
129
|
-
def process_group_get_request(
|
|
129
|
+
def process_group_get_request(
|
|
130
|
+
self, group_id, token, process_group_flow=False, entity=None) -> dict:
|
|
130
131
|
"""helper method to process a get request for a process group
|
|
131
132
|
identified by id"""
|
|
132
|
-
|
|
133
|
-
self.build_url("nifi-api", "process-groups", group_id, entity)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
if entity:
|
|
134
|
+
url = self.build_url("nifi-api", "process-groups", group_id, entity)
|
|
135
|
+
elif process_group_flow:
|
|
136
|
+
url = self.build_url("nifi-api", "flow", "process-groups", group_id)
|
|
137
|
+
else:
|
|
138
|
+
url = self.build_url("nifi-api", "process-groups", group_id)
|
|
137
139
|
return self._get_entity(url, token)
|
|
138
140
|
|
|
139
141
|
def get_templates(self, token) -> dict:
|
|
@@ -318,8 +320,8 @@ class NIFIRESTClient:
|
|
|
318
320
|
"Content-Type": self.__JSON_CONTENT_TYPE,
|
|
319
321
|
"Authorization": f"Bearer {token}",
|
|
320
322
|
}
|
|
321
|
-
x = random.uniform(0,
|
|
322
|
-
y = random.uniform(0,
|
|
323
|
+
x = random.uniform(0, 1000)
|
|
324
|
+
y = random.uniform(0, 1000)
|
|
323
325
|
payload = {
|
|
324
326
|
"revision": {"version": 0},
|
|
325
327
|
"disconnectedNodeAcknowledged": False,
|
|
@@ -353,10 +355,11 @@ class NIFIRESTClient:
|
|
|
353
355
|
if response.ok:
|
|
354
356
|
response_json = response.content.decode()
|
|
355
357
|
process_group = json.loads(response_json)
|
|
358
|
+
|
|
356
359
|
# Rename process_group as flow_definition_name + process_group_id
|
|
357
360
|
process_group_name = process_group["component"]["name"]
|
|
358
361
|
process_group = self.rename_process_group(
|
|
359
|
-
process_group, process_group_name, token
|
|
362
|
+
process_group["id"], process_group_name, token
|
|
360
363
|
)
|
|
361
364
|
return process_group
|
|
362
365
|
else:
|
|
@@ -365,18 +368,34 @@ class NIFIRESTClient:
|
|
|
365
368
|
f"{response.content.decode()}"
|
|
366
369
|
)
|
|
367
370
|
|
|
368
|
-
def rename_process_group(self,
|
|
369
|
-
|
|
371
|
+
def rename_process_group(self, process_group_id, name, token) -> str:
|
|
372
|
+
# TODO Send only what is required to modify the name
|
|
373
|
+
"""rename a process group name"""
|
|
374
|
+
|
|
375
|
+
# Reload process_group
|
|
376
|
+
process_group = self.process_group_get_request(
|
|
377
|
+
process_group_id, token, process_group_flow=True)
|
|
378
|
+
|
|
370
379
|
headers = {
|
|
371
380
|
"Content-Type": self.__JSON_CONTENT_TYPE,
|
|
372
381
|
"Authorization": f"Bearer {token}",
|
|
373
382
|
}
|
|
374
|
-
process_group_id = process_group["id"]
|
|
375
|
-
|
|
376
|
-
payload =
|
|
383
|
+
process_group_id = process_group["processGroupFlow"]["id"]
|
|
384
|
+
|
|
385
|
+
payload = {
|
|
386
|
+
"component": {
|
|
387
|
+
"id": process_group_id,
|
|
388
|
+
"name": name + "_" + process_group_id
|
|
389
|
+
},
|
|
390
|
+
"revision": {"version": process_group["revision"]["version"]},
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
# payload = json.dumps(process_group)
|
|
394
|
+
payload_json = json.dumps(payload)
|
|
395
|
+
|
|
377
396
|
response = requests.put(
|
|
378
397
|
url=self.build_url("nifi-api", "process-groups", process_group_id),
|
|
379
|
-
data=
|
|
398
|
+
data=payload_json,
|
|
380
399
|
verify=self.__conf.nifi_secure_connection(),
|
|
381
400
|
headers=headers,
|
|
382
401
|
timeout=self.__REQUEST_TIMEOUT,
|
|
@@ -472,6 +491,51 @@ class NIFIRESTClient:
|
|
|
472
491
|
f"{response.content.decode()}"
|
|
473
492
|
)
|
|
474
493
|
|
|
494
|
+
def instantiate_kpus(
|
|
495
|
+
self, process_group_id, token
|
|
496
|
+
) -> dict:
|
|
497
|
+
"""creates a Kerberos Password User Service"""
|
|
498
|
+
headers = {
|
|
499
|
+
"Content-Type": self.__JSON_CONTENT_TYPE,
|
|
500
|
+
"Authorization": f"Bearer {token}",
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
payload = {
|
|
504
|
+
"revision": {"version": 0},
|
|
505
|
+
"disconnectedNodeAcknowledged": False,
|
|
506
|
+
"component": {
|
|
507
|
+
"bundle": {
|
|
508
|
+
"group": "org.apache.nifi",
|
|
509
|
+
"artifact": "nifi-kerberos-user-service-nar",
|
|
510
|
+
"version": "2.8.0"
|
|
511
|
+
},
|
|
512
|
+
"type": "org.apache.nifi.kerberos.KerberosPasswordUserService"
|
|
513
|
+
}
|
|
514
|
+
} # /nifi-api/process-groups/e2dde1d0-019c-1000-b433-43f8611cef38/controller-services
|
|
515
|
+
payload_json = json.dumps(payload)
|
|
516
|
+
response = requests.post(
|
|
517
|
+
url=self.build_url(
|
|
518
|
+
"nifi-api",
|
|
519
|
+
"process-groups",
|
|
520
|
+
process_group_id,
|
|
521
|
+
"controller-services",
|
|
522
|
+
),
|
|
523
|
+
data=payload_json,
|
|
524
|
+
verify=self.__conf.nifi_secure_connection(),
|
|
525
|
+
headers=headers,
|
|
526
|
+
timeout=self.__REQUEST_TIMEOUT,
|
|
527
|
+
)
|
|
528
|
+
if response.ok:
|
|
529
|
+
response_json = response.content.decode()
|
|
530
|
+
kpus = json.loads(response_json)
|
|
531
|
+
return kpus
|
|
532
|
+
else:
|
|
533
|
+
raise HidDataTransferException(
|
|
534
|
+
"Instantiate kpus exception: "
|
|
535
|
+
f"{response.content.decode()}"
|
|
536
|
+
)
|
|
537
|
+
|
|
538
|
+
|
|
475
539
|
# PUT requests
|
|
476
540
|
|
|
477
541
|
def associate_parameter_context_to_group(
|
|
@@ -486,7 +550,6 @@ class NIFIRESTClient:
|
|
|
486
550
|
payload = {
|
|
487
551
|
"revision": {
|
|
488
552
|
"version": process_group["revision"]["version"],
|
|
489
|
-
# "clientId": parameter_context['revision']['clientId']
|
|
490
553
|
},
|
|
491
554
|
"disconnectedNodeAcknowledged": False,
|
|
492
555
|
"component": {
|
|
@@ -541,6 +604,84 @@ class NIFIRESTClient:
|
|
|
541
604
|
f"Processor exception: {response.content.decode()}"
|
|
542
605
|
)
|
|
543
606
|
|
|
607
|
+
def update_kpus(self, kpus, token) -> dict:
|
|
608
|
+
"""updates a kpus identified by id"""
|
|
609
|
+
headers = {
|
|
610
|
+
"Content-Type": self.__JSON_CONTENT_TYPE,
|
|
611
|
+
"Authorization": f"Bearer {token}",
|
|
612
|
+
}
|
|
613
|
+
response = requests.put(
|
|
614
|
+
url=self.build_url("nifi-api", "controller-services", kpus["id"]),
|
|
615
|
+
verify=self.__conf.nifi_secure_connection(),
|
|
616
|
+
data=json.dumps(kpus),
|
|
617
|
+
headers=headers,
|
|
618
|
+
timeout=self.__REQUEST_TIMEOUT,
|
|
619
|
+
)
|
|
620
|
+
if response.ok:
|
|
621
|
+
response_json = response.content.decode()
|
|
622
|
+
return json.loads(response_json)
|
|
623
|
+
else:
|
|
624
|
+
raise HidDataTransferException(
|
|
625
|
+
f"Controller service exception: {response.content.decode()}"
|
|
626
|
+
)
|
|
627
|
+
|
|
628
|
+
def enable_kpus(self, kpus, token) -> dict:
|
|
629
|
+
"""updates a kpus identified by id"""
|
|
630
|
+
headers = {
|
|
631
|
+
"Content-Type": self.__JSON_CONTENT_TYPE,
|
|
632
|
+
"Authorization": f"Bearer {token}",
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
payload = {
|
|
636
|
+
"revision":{"version":kpus["revision"]["version"]},
|
|
637
|
+
"state":"ENABLED"
|
|
638
|
+
}
|
|
639
|
+
payload_json = json.dumps(payload)
|
|
640
|
+
|
|
641
|
+
response = requests.put(
|
|
642
|
+
url=self.build_url("nifi-api", "controller-services", kpus['id'], "run-status"),
|
|
643
|
+
verify=self.__conf.nifi_secure_connection(),
|
|
644
|
+
data=payload_json,
|
|
645
|
+
headers=headers,
|
|
646
|
+
timeout=self.__REQUEST_TIMEOUT,
|
|
647
|
+
)
|
|
648
|
+
if response.ok:
|
|
649
|
+
response_json = response.content.decode()
|
|
650
|
+
return json.loads(response_json)
|
|
651
|
+
else:
|
|
652
|
+
raise HidDataTransferException(
|
|
653
|
+
f"Controller service exception: {response.content.decode()}"
|
|
654
|
+
)
|
|
655
|
+
|
|
656
|
+
def disable_controller_services(self, process_group_id, token):
|
|
657
|
+
''' disable the controller services'''
|
|
658
|
+
headers = {
|
|
659
|
+
"Content-Type": self.__JSON_CONTENT_TYPE,
|
|
660
|
+
"Authorization": f"Bearer {token}",
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
payload = {
|
|
664
|
+
"id": process_group_id,
|
|
665
|
+
"state":"DISABLED"
|
|
666
|
+
}
|
|
667
|
+
payload_json = json.dumps(payload)
|
|
668
|
+
|
|
669
|
+
response = requests.put(
|
|
670
|
+
url=self.build_url(
|
|
671
|
+
"nifi-api", "flow", "process-groups", process_group_id, "controller-services"),
|
|
672
|
+
verify=self.__conf.nifi_secure_connection(),
|
|
673
|
+
data=payload_json,
|
|
674
|
+
headers=headers,
|
|
675
|
+
timeout=self.__REQUEST_TIMEOUT,
|
|
676
|
+
)
|
|
677
|
+
if response.ok:
|
|
678
|
+
response_json = response.content.decode()
|
|
679
|
+
return json.loads(response_json)
|
|
680
|
+
else:
|
|
681
|
+
raise HidDataTransferException(
|
|
682
|
+
f"Process group exception: {response.content.decode()}"
|
|
683
|
+
)
|
|
684
|
+
|
|
544
685
|
# DELETE requests
|
|
545
686
|
def delete_update_request(self, entity_name,
|
|
546
687
|
entity_id, request_id, token) -> bool:
|
{hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/util/util.py
RENAMED
|
@@ -127,10 +127,12 @@ def sftp_put(
|
|
|
127
127
|
sftp.put(source, target)
|
|
128
128
|
if target_permissions:
|
|
129
129
|
command = f"chmod {target_permissions} {target}"
|
|
130
|
-
ssh.exec_command(command)
|
|
130
|
+
_, stdout, _ = ssh.exec_command(command)
|
|
131
|
+
stdout.channel.recv_exit_status() # Block until done, drains buffers
|
|
131
132
|
if target_ownership:
|
|
132
133
|
command = f"chown {target_ownership} {target}"
|
|
133
|
-
ssh.exec_command(command)
|
|
134
|
+
_, stdout, _ = ssh.exec_command(command)
|
|
135
|
+
stdout.channel.recv_exit_status() # Block until done, drains buffers
|
|
134
136
|
except Exception as ex:
|
|
135
137
|
msg = "Exception transferring keys with SFTP"
|
|
136
138
|
raise HidDataTransferException(msg) from ex
|
|
@@ -189,8 +191,9 @@ def __ssh_execute_command(server, username, command, private_key=None):
|
|
|
189
191
|
ssh.connect(server, username=username)
|
|
190
192
|
else:
|
|
191
193
|
ssh.connect(server, username=username, key_filename=private_key)
|
|
192
|
-
_,
|
|
194
|
+
_, stdout, stderr = ssh.exec_command(command)
|
|
193
195
|
error = stderr.read().decode("utf-8")
|
|
196
|
+
stdout.channel.recv_exit_status() # Block until done, drains buffers
|
|
194
197
|
if error:
|
|
195
198
|
raise HidDataTransferException(
|
|
196
199
|
f"Error '{error}' executing command '{command}'"
|
|
@@ -217,6 +220,7 @@ def ssh_list(path, server, username, private_key=None, prefix=None) -> list:
|
|
|
217
220
|
else:
|
|
218
221
|
command = f'find {path} -maxdepth 1 -type f -printf "%p\n"'
|
|
219
222
|
_, stdout, _ = ssh.exec_command(command)
|
|
223
|
+
stdout.channel.recv_exit_status() # Block until done, drains buffers
|
|
220
224
|
|
|
221
225
|
# read lines from stdout in a list
|
|
222
226
|
files = []
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "hid_data_transfer_lib"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.0"
|
|
4
4
|
description = "HiDALGO Data Transfer library provides methods to transfer data between different data providers and consumers using NIFI pipelines"
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "Jesús Gorroñogoitia", email = "jesus.gorronogoitia@eviden.com" },
|
|
@@ -28,6 +28,7 @@ include = ["py.typed"]
|
|
|
28
28
|
[tool.poetry.group.dev.dependencies]
|
|
29
29
|
flake8 = "^7.2.0"
|
|
30
30
|
black = "^25.1.0"
|
|
31
|
+
ipykernel = "^7.2.0"
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
[tool.poetry.group.types.dependencies]
|
{hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/__init__.py
RENAMED
|
File without changes
|
{hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/conf/__init__.py
RENAMED
|
File without changes
|
{hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/conf/hid_dt.cfg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/nifi/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{hid_data_transfer_lib-0.3.10 → hid_data_transfer_lib-0.4.0}/hid_data_transfer_lib/util/__init__.py
RENAMED
|
File without changes
|