Skip to content

Commit cb6bdfa

Browse files
Noremac201Alice Berard
authored and
Alice Berard
committed
[AIRFLOW-2657] Add ability to delete dag from web UI
Closes apache#3531 from Noremac201/master
1 parent 4369f9c commit cb6bdfa

File tree

6 files changed

+109
-0
lines changed

6 files changed

+109
-0
lines changed

airflow/www/templates/airflow/dag.html

+13
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@ <h4 class="pull-right">
100100
Refresh
101101
</a>
102102
</li>
103+
<li>
104+
<a href="{{ url_for("airflow.delete", dag_id=dag.dag_id, root=root) }}"
105+
onclick="return confirmDeleteDag('{{ dag.safe_dag_id }}')">
106+
<span class="glyphicon glyphicon-remove-circle" style="color:red" aria-hidden="true"></span>
107+
Delete
108+
</a>
109+
</li>
103110
</ul>
104111
</div>
105112
<hr>
@@ -302,6 +309,12 @@ <h4 class="modal-title" id="dagModalLabel">
302309
$("#dagModal").css("margin-top","0px");
303310
}
304311

312+
function confirmDeleteDag(dag_id){
313+
return confirm("Are you sure you want to delete '"+dag_id+"' now?\n\
314+
This option will delete ALL metadata, DAG runs, etc.\n\
315+
This cannot be undone.");
316+
}
317+
305318
$("#btn_rendered").click(function(){
306319
url = "{{ url_for('airflow.rendered') }}" +
307320
"?task_id=" + encodeURIComponent(task_id) +

airflow/www/templates/airflow/dags.html

+12
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,12 @@ <h2>DAGs</h2>
190190
<span class="glyphicon glyphicon-refresh" aria-hidden="true" data-original-title="Refresh"></span>
191191
</a>
192192

193+
<!-- Delete -->
194+
<a href="{{ url_for('airflow.delete', dag_id=dag.dag_id) }}"
195+
onclick="return confirmDeleteDag('{{ dag.safe_dag_id }}')">
196+
<span class="glyphicon glyphicon-remove-circle" style="color:red" aria-hidden="true" data-original-title="Delete Dag"></span>
197+
</a>
198+
193199
</td>
194200
</tr>
195201
{% endfor %}
@@ -244,6 +250,12 @@ <h2>DAGs</h2>
244250
function confirmTriggerDag(dag_id){
245251
return confirm("Are you sure you want to run '"+dag_id+"' now?");
246252
}
253+
254+
function confirmDeleteDag(dag_id){
255+
return confirm("Are you sure you want to delete '"+dag_id+"' now?\n\
256+
This option will delete ALL metadata, DAG runs, etc.\n\
257+
This cannot be undone.");
258+
}
247259
all_dags = $("[id^=toggle]");
248260
$.each(all_dags, function(i,v) {
249261
$(v).change (function() {

airflow/www/views.py

+30
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,32 @@ def run(self):
10441044
"it should start any moment now.".format(ti))
10451045
return redirect(origin)
10461046

1047+
@expose('/delete')
1048+
@login_required
1049+
@wwwutils.action_logging
1050+
@wwwutils.notify_owner
1051+
def delete(self):
1052+
from airflow.api.common.experimental import delete_dag
1053+
from airflow.exceptions import DagNotFound, DagFileExists
1054+
1055+
dag_id = request.args.get('dag_id')
1056+
origin = request.args.get('origin') or "/admin/"
1057+
1058+
try:
1059+
delete_dag.delete_dag(dag_id)
1060+
except DagNotFound:
1061+
flash("DAG with id {} not found. Cannot delete".format(dag_id))
1062+
return redirect(request.referrer)
1063+
except DagFileExists:
1064+
flash("Dag id {} is still in DagBag. "
1065+
"Remove the DAG file first.".format(dag_id))
1066+
return redirect(request.referrer)
1067+
1068+
flash("Deleting DAG with id {}. May take a couple minutes to fully"
1069+
" disappear.".format(dag_id))
1070+
# Upon successful delete return to origin
1071+
return redirect(origin)
1072+
10471073
@expose('/trigger')
10481074
@login_required
10491075
@wwwutils.action_logging
@@ -1283,6 +1309,10 @@ def tree(self, session=None):
12831309
dag_id = request.args.get('dag_id')
12841310
blur = conf.getboolean('webserver', 'demo_mode')
12851311
dag = dagbag.get_dag(dag_id)
1312+
if dag_id not in dagbag.dags:
1313+
flash('DAG "{0}" seems to be missing.'.format(dag_id), "error")
1314+
return redirect('/admin/')
1315+
12861316
root = request.args.get('root')
12871317
if root:
12881318
dag = dag.sub_dag(

airflow/www_rbac/templates/airflow/dag.html

+13
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ <h4 class="pull-right">
9999
Refresh
100100
</a>
101101
</li>
102+
<li>
103+
<a href="{{ url_for('Airflow.delete', dag_id=dag.dag_id, root=root) }}"
104+
onclick="return confirmDeleteDag('{{ dag.safe_dag_id }}')">
105+
<span class="glyphicon glyphicon-remove-circle" style="color:red" aria-hidden="true"></span>
106+
Delete
107+
</a>
108+
</li>
102109
</ul>
103110
</div>
104111
<hr>
@@ -300,6 +307,12 @@ <h4 class="modal-title" id="dagModalLabel">
300307
$("#dagModal").css("margin-top","0px");
301308
}
302309

310+
function confirmDeleteDag(dag_id){
311+
return confirm("Are you sure you want to delete '"+dag_id+"' now?\n\
312+
This option will delete ALL metadata, DAG runs, etc.\n\
313+
This cannot be undone.");
314+
}
315+
303316
$("#btn_rendered").click(function(){
304317
url = "{{ url_for('Airflow.rendered') }}" +
305318
"?task_id=" + encodeURIComponent(task_id) +

airflow/www_rbac/templates/airflow/dags.html

+11
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@ <h2>DAGs</h2>
191191
<span class="glyphicon glyphicon-refresh" aria-hidden="true" data-original-title="Refresh"></span>
192192
</a>
193193

194+
<!-- Delete -->
195+
<a href="{{ url_for('Airflow.delete', dag_id=dag.dag_id) }}"
196+
onclick="return confirmDeleteDag('{{ dag.safe_dag_id }}')">
197+
<span class="glyphicon glyphicon-remove-circle" style="color:red" aria-hidden="true" data-original-title="Delete Dag"></span>
198+
</a>
194199
</td>
195200
</tr>
196201
{% endfor %}
@@ -242,6 +247,12 @@ <h2>DAGs</h2>
242247
window.location = DAGS_INDEX + "?page_size=" + p_size;
243248
});
244249

250+
function confirmDeleteDag(dag_id){
251+
return confirm("Are you sure you want to delete '"+dag_id+"' now?\n\
252+
This option will delete ALL metadata, DAG runs, etc.\n\
253+
This cannot be undone.");
254+
}
255+
245256
function confirmTriggerDag(dag_id){
246257
return confirm("Are you sure you want to run '"+dag_id+"' now?");
247258
}

airflow/www_rbac/views.py

+30
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,32 @@ def run(self):
728728
"it should start any moment now.".format(ti))
729729
return redirect(origin)
730730

731+
@expose('/delete')
732+
@action_logging
733+
@has_access
734+
def delete(self):
735+
from airflow.api.common.experimental import delete_dag
736+
from airflow.exceptions import DagNotFound, DagFileExists
737+
738+
dag_id = request.args.get('dag_id')
739+
origin = request.args.get('origin') or "/"
740+
741+
try:
742+
delete_dag.delete_dag(dag_id)
743+
except DagNotFound:
744+
flash("DAG with id {} not found. Cannot delete".format(dag_id))
745+
return redirect(request.referrer)
746+
except DagFileExists:
747+
flash("Dag id {} is still in DagBag. "
748+
"Remove the DAG file first.".format(dag_id))
749+
return redirect(request.referrer)
750+
751+
flash("Deleting DAG with id {}. May take a couple minutes to fully"
752+
" disappear.".format(dag_id))
753+
754+
# Upon success return to origin.
755+
return redirect(origin)
756+
731757
@expose('/trigger')
732758
@has_access
733759
@action_logging
@@ -961,6 +987,10 @@ def tree(self, session=None):
961987
dag_id = request.args.get('dag_id')
962988
blur = conf.getboolean('webserver', 'demo_mode')
963989
dag = dagbag.get_dag(dag_id)
990+
if dag_id not in dagbag.dags:
991+
flash('DAG "{0}" seems to be missing.'.format(dag_id), "error")
992+
return redirect('/')
993+
964994
root = request.args.get('root')
965995
if root:
966996
dag = dag.sub_dag(

0 commit comments

Comments
 (0)