【问题标题】:Apache Airflow 2.0.0 Trigger a DAG Run via the Stable REST API fails with FORBIDDENApache Airflow 2.0.0 通过稳定的 REST API 触发 DAG 运行失败并出现 FORBIDDEN
【发布时间】:2021-04-22 16:31:55
【问题描述】:

Apache Airflow 版本

2.0.0

环境

  • 云提供商或硬件配置:OpenStack -> VM -> Docker 容器
  • 操作系统(例如来自 /etc/os-release):Debian GNU/Linux 10(buster)
  • 内核(例如uname -a):Linux 77f8efd77516 4.4.0-193-generic #224-Ubuntu

发生了什么

我正在尝试使用基于 Java 的客户端通过新的稳定 REST-API 1.0.0 触发 DAG 运行。 Java 客户端由 Airflow OpenAPI 规范生成,OpenAPI 生成器版本为5.0.0

我的airflow.cfg中的自定义配置:

web_server_host = 0.0.0.0
web_server_port = 8080
auth_backend = airflow.api.auth.backend.default

另外我创建了一个管理员用户:

airflow users create \
    --username admin \
    --password secret \
    --firstname john \
    --lastname doe \
    --role Admin \
    --email john.doe@example.com

在 Airflow 中,我有一个活跃的 DAG demo

我通过java客户端触发DAG执行,代码如下:sn-p:

ApiClient defaultClient = Configuration.getDefaultApiClient();
defaultClient.setBasePath("http://1.2.3.4:8080/api/v1);
DagRunApi dagRunApi = new DagRunApi(defaultClient);
DAGRun dagRun = new DAGRun();
try {
      DAGRun result = dagRunApi.postDagRun("demo", dagRun);

      LOGGER.debug(result);

    } catch (ApiException e) {
      e.printStackTrace();
    }

但是,我收到以下异常:

org.openapitools.client.ApiException: FORBIDDEN
    at org.openapitools.client.ApiClient.handleResponse(ApiClient.java:1012)
    at org.openapitools.client.ApiClient.execute(ApiClient.java:925)
    at org.openapitools.client.api.DagRunApi.postDagRunWithHttpInfo(DagRunApi.java:740)
    at org.openapitools.client.api.DagRunApi.postDagRun(DagRunApi.java:715)
    at de.baas.evaluation.scheduler.airflow.ExternalTrigger.triggerDAGRun(ExternalTrigger.java:46)
    at de.baas.evaluation.scheduler.service.BaaSScheduler$1.message(BaaSScheduler.java:60)
    at de.baas.evaluation.scheduler.service.BaaSScheduler$1.message(BaaSScheduler.java:53)
    at io.lettuce.core.pubsub.PubSubEndpoint.notifyListeners(PubSubEndpoint.java:217)
    at io.lettuce.core.pubsub.PubSubEndpoint.notifyMessage(PubSubEndpoint.java:206)
    at io.lettuce.core.pubsub.PubSubCommandHandler.doNotifyMessage(PubSubCommandHandler.java:292)
    at io.lettuce.core.pubsub.PubSubCommandHandler.notifyPushListeners(PubSubCommandHandler.java:223)
    at io.lettuce.core.protocol.CommandHandler.decode(CommandHandler.java:606)
    at io.lettuce.core.pubsub.PubSubCommandHandler.decode(PubSubCommandHandler.java:112)
    at io.lettuce.core.protocol.CommandHandler.channelRead(CommandHandler.java:560)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(Thread.java:748)

Airflow 日志不显示任何错误消息。

您预期会发生什么

以前,我也使用过时的实验性 REST-API 从外部触发任务(没有客户端,但使用自定义 REST 调用),它可以正常工作。

使用新的稳定 API,即使通过 airflow.api.auth.backend.default 停用身份验证,我的客户端似乎也没有足够的权限

还可以通过添加用户名和密码来创建客户端

defaultClient.setUsername("admin");
defaultClient.setPassword("secret");

导致同样的错误:FORBIDDEN

我是否需要创建一个专门的 REST-API 用户,如果需要,是否有关于此主题的任何文档?

如何重现它

通过 OpenAPI 生成器创建 Java 客户端(可能任何客户端都会产生此错误):

  1. java -jar codegen/openapi-generator-cli-5.0.0.jar generate -i openapi.yaml -g java -o .
  2. 创建一个简单的 java 类并应用上面的代码 sn-ps

【问题讨论】:

    标签: java airflow openapi


    【解决方案1】:

    如果其他人遇到此问题,我可以按如下方式解决:

    1. 将身份验证后端更改为 auth_backend = airflow.api.auth.backend.basic_auth,因为 airflow.api.auth.backend.default 不适用于新的 REST-API

    2. 将以下更改应用于正确生成客户端代码所需的 Airflow openapi.yaml(否则用户名/密码)不会正确传输,另请参阅:https://github.com/apache/airflow/issues/13739

    # The API will provide support for plugins to support various authorization mechanisms.
    # Detailed information will be available in the plugin specification.
    security:
      - Basic: []
    
    1. 在java代码中设置用户名/密码如下:
    // Configure HTTP basic authorization: Basic
        HttpBasicAuth Basic = (HttpBasicAuth) defaultClient.getAuthentication("Basic");
        Basic.setUsername("admin");
        Basic.setPassword("secret");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多