Airflow 如何在BashOperator中将密码作为参数发送时屏蔽密码

Airflow 如何在BashOperator中将密码作为参数发送时屏蔽密码,airflow,Airflow,我正在使用bash操作符运行一个bash命令,该命令需要多个参数才能工作。在这些参数中,我发送了一个密码 bash_task = BashOperator( task_id='bash_operator_example', bash_command=f'echo {param1} {password}', ) 这里的问题是,即使我是从airflow上的一个连接获取密码的,该连接应该保持密码的机密性,但当操作员运行该命令时,该密码会出现在日志中的clear test中 请参阅下面

我正在使用bash操作符运行一个bash命令,该命令需要多个参数才能工作。在这些参数中,我发送了一个密码

bash_task = BashOperator(
    task_id='bash_operator_example',
    bash_command=f'echo {param1} {password}',
)
这里的问题是,即使我是从airflow上的一个连接获取密码的,该连接应该保持密码的机密性,但当操作员运行该命令时,该密码会出现在日志中的clear test中

请参阅下面生成的日志:

[2021-03-06 17:42:14,079] {bash_operator.py:136} INFO - Temporary script location: /tmp/airflowtmp_mez12q_/bash_operator_examplena7hxdup
[2021-03-06 17:42:14,079] {bash_operator.py:146} INFO - Running command: echo my_param_1 my_password
[2021-03-06 17:42:14,092] {bash_operator.py:153} INFO - Output:
[2021-03-06 17:42:14,094] {bash_operator.py:157} INFO - my_param_1 my_password
[2021-03-06 17:42:14,094] {bash_operator.py:161} INFO - Command exited with return code 0
[2021-03-06 17:42:14,101] {taskinstance.py:1070} INFO - Marking task as SUCCESS.dag_id=TEST_running_DAG, task_id=bash_operator_example, execution_date=20210101T000000, start_date=20210306T174214, end_date=20210306T174214
我尝试了几种方法,例如,使用bash操作符中可用的参数,如:

bash_task = BashOperator(
        task_id='bash_operator_example',
        bash_command='echo {{ params.param1 }} {{ params.password }}',
        params={
            "param1": param1,
            "password": password
        }
    )
但结果仍然是一样的,它被打印在日志中。我也尝试过使用env,但虽然不在日志中,但完整的env可以在UI的“Task Instance Details”选项中找到,因此密码也可以在那里看到

其中一个似乎有效的方法是使用子流程库在PythonOperator中运行bash命令。但我认为气流应该有一个更容易的选择,我只是不知道

如果有气流方面经验的人能为我指出正确的方向,我将不胜感激

2020-03-07更新:

最后,我做的是编写自己的操作符。我仍然认为必须有一个更简单的解决方案,因为这应该是一个非常常见的用例。 这就是我所做的:

创建新的操作员,您可以使用本指南了解如何编写自己的操作员:

然后,我基本上用基本运算符的代码替换initexecute,您可以在这里找到:

最后,我向init方法添加了一个新的参数密码,并使用该参数替换self.bash_命令,如下所示:

with NamedTemporaryFile(dir=tmp_dir, prefix=self.task_id) as f:
        #Custom Code to replace the password
        final_bash_command = self.bash_command.replace(':password', 
        self.password) if self.password else self.bash_command
    
        f.write(bytes(final_bash_command, 'utf_8'))
        ...
基本上,如果param密码存在,它将搜索占位符:password并用参数“password”替换它

这不是最优雅的解决方案,但它做到了这一点,就像后面的代码中日志打印self.bash_命令一样,而不是我的新变量final_bash_命令,这是实际执行的

以下是我使用新操作符的方式:

hello_task = PasswordBashOperator(
        task_id='sample-task',
        bash_command='echo {{ params.param1 }} :password',
        params={
            "param1": param1
        },
        password=password
)
现在,如果我运行它打印的任务:

[2021-03-07 16:16:55,786] {password_bash_operator.py:64} INFO - Temporary script location: /tmp/airflowtmpfos7yapf/sample-task_da9_lrr
[2021-03-07 16:16:55,786] {password_bash_operator.py:74} INFO - Running command: echo my_param_1 :password
[2021-03-07 16:16:55,792] {password_bash_operator.py:83} INFO - Output:
[2021-03-07 16:16:55,793] {password_bash_operator.py:87} INFO - my_param_1 my_password
[2021-03-07 16:16:55,793] {password_bash_operator.py:91} INFO - Command exited with return code 0
[2021-03-07 16:16:55,799] {taskinstance.py:1070} INFO - Marking task as SUCCESS.dag_id=TEST_running_DAG, task_id=sample-task, execution_date=20210101T000000, start_date=20210307T161655, end_date=20210307T161655
因此,该行:

[2021-03-07 16:16:55786]{password_bash_operator.py:74}INFO-运行命令:echo my_param_1:password

不再打印密码

如果有人能找到更好、更优雅的解决方案,我仍然很感兴趣