Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion airflow/api_fastapi/core_api/openapi/v1-generated.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3790,12 +3790,16 @@ paths:
summary: Get Extra Links
description: Get extra links for task instance.
operationId: get_extra_links
security:
- OAuth2PasswordBearer: []
parameters:
- name: dag_id
in: path
required: true
schema:
type: string
anyOf:
- type: string
- type: 'null'
title: Dag Id
- name: dag_run_id
in: path
Expand Down
4 changes: 3 additions & 1 deletion airflow/api_fastapi/core_api/routes/public/extra_links.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@

from typing import TYPE_CHECKING

from fastapi import HTTPException, Request, status
from fastapi import Depends, HTTPException, Request, status
from sqlalchemy.sql import select

from airflow.api_fastapi.common.db.common import SessionDep
from airflow.api_fastapi.common.router import AirflowRouter
from airflow.api_fastapi.core_api.datamodels.extra_links import ExtraLinksResponse
from airflow.api_fastapi.core_api.openapi.exceptions import create_openapi_http_exception_doc
from airflow.api_fastapi.core_api.security import DagAccessEntity, requires_access_dag
from airflow.exceptions import TaskNotFound

if TYPE_CHECKING:
Expand All @@ -40,6 +41,7 @@
@extra_links_router.get(
"",
responses=create_openapi_http_exception_doc([status.HTTP_404_NOT_FOUND]),
dependencies=[Depends(requires_access_dag("GET", DagAccessEntity.TASK_INSTANCE))],
tags=["Task Instance"],
)
def get_extra_links(
Expand Down
2 changes: 1 addition & 1 deletion airflow/ui/openapi-gen/requests/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2100,7 +2100,7 @@ export type GetEventLogsData = {
export type GetEventLogsResponse = EventLogCollectionResponse;

export type GetExtraLinksData = {
dagId: string;
dagId: string | null;
dagRunId: string;
mapIndex?: number;
taskId: string;
Expand Down
14 changes: 14 additions & 0 deletions tests/api_fastapi/core_api/routes/public/test_extra_links.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,20 @@ def test_should_respond_200_mapped_task_instance(self, test_client):
"Google Custom": "http://google.com/custom_base_link?search=TEST_LINK_VALUE_1"
}

def test_should_respond_401_unauthenticated(self, unauthenticated_test_client):
response = unauthenticated_test_client.get(
f"/public/dags/{self.dag_id}/dagRuns/{self.dag_run_id}/taskInstances/{self.task_single_link}/links",
)

assert response.status_code == 401

def test_should_respond_403_unauthorized(self, unauthorized_test_client):
response = unauthorized_test_client.get(
f"/public/dags/{self.dag_id}/dagRuns/{self.dag_run_id}/taskInstances/{self.task_single_link}/links",
)

assert response.status_code == 403

def test_should_respond_404_invalid_map_index(self, test_client):
response = test_client.get(
f"/public/dags/{self.dag_id}/dagRuns/{self.dag_run_id}/taskInstances/{self.task_mapped}/links",
Expand Down