diff --git a/airflow/www/forms.py b/airflow/www/forms.py index 45c9dd5f58cc2..8a28e546ceece 100644 --- a/airflow/www/forms.py +++ b/airflow/www/forms.py @@ -30,21 +30,12 @@ from flask_babel import lazy_gettext from flask_wtf import FlaskForm from wtforms import widgets -from wtforms.fields import ( - BooleanField, - Field, - IntegerField, - PasswordField, - SelectField, - StringField, - TextAreaField, -) +from wtforms.fields import Field, IntegerField, PasswordField, SelectField, StringField, TextAreaField from wtforms.validators import InputRequired, Optional from airflow.configuration import conf from airflow.utils import timezone from airflow.utils.types import DagRunType -from airflow.www.validators import ValidJson from airflow.www.widgets import ( AirflowDateTimePickerROWidget, AirflowDateTimePickerWidget, @@ -130,32 +121,22 @@ class DateTimeWithNumRunsWithDagRunsForm(DateTimeWithNumRunsForm): execution_date = SelectField("DAG run") -class DagRunForm(DynamicForm): - """Form for adding DAG Run""" +class DagRunEditForm(DynamicForm): + """Form for editing DAG Run. - dag_id = StringField(lazy_gettext('Dag Id'), validators=[InputRequired()], widget=BS3TextFieldWidget()) - start_date = DateTimeWithTimezoneField(lazy_gettext('Start Date'), widget=AirflowDateTimePickerWidget()) - end_date = DateTimeWithTimezoneField(lazy_gettext('End Date'), widget=AirflowDateTimePickerWidget()) - run_id = StringField(lazy_gettext('Run Id'), validators=[InputRequired()], widget=BS3TextFieldWidget()) - state = SelectField( - lazy_gettext('State'), - choices=( - ('success', 'success'), - ('running', 'running'), - ('failed', 'failed'), - ), - widget=Select2Widget(), - validators=[InputRequired()], - ) + We don't actually want to allow editing, so everything is read-only here. + """ + + dag_id = StringField(lazy_gettext('Dag Id'), widget=BS3TextFieldROWidget()) + start_date = DateTimeWithTimezoneField(lazy_gettext('Start Date'), widget=AirflowDateTimePickerROWidget()) + end_date = DateTimeWithTimezoneField(lazy_gettext('End Date'), widget=AirflowDateTimePickerROWidget()) + run_id = StringField(lazy_gettext('Run Id'), widget=BS3TextFieldROWidget()) + state = StringField(lazy_gettext('State'), widget=BS3TextFieldROWidget()) execution_date = DateTimeWithTimezoneField( lazy_gettext('Execution Date'), - widget=AirflowDateTimePickerWidget(), - validators=[InputRequired()], - ) - external_trigger = BooleanField(lazy_gettext('External Trigger')) - conf = TextAreaField( - lazy_gettext('Conf'), validators=[ValidJson(), Optional()], widget=BS3TextAreaFieldWidget() + widget=AirflowDateTimePickerROWidget(), ) + conf = TextAreaField(lazy_gettext('Conf'), widget=BS3TextAreaROWidget()) def populate_obj(self, item): """Populates the attributes of the passed obj with data from the form’s fields.""" @@ -165,23 +146,6 @@ def populate_obj(self, item): item.conf = json.loads(item.conf) -class DagRunEditForm(DagRunForm): - """Form for editing DAG Run""" - - dag_id = StringField(lazy_gettext('Dag Id'), validators=[InputRequired()], widget=BS3TextFieldROWidget()) - start_date = DateTimeWithTimezoneField(lazy_gettext('Start Date'), widget=AirflowDateTimePickerROWidget()) - end_date = DateTimeWithTimezoneField(lazy_gettext('End Date'), widget=AirflowDateTimePickerROWidget()) - run_id = StringField(lazy_gettext('Run Id'), validators=[InputRequired()], widget=BS3TextFieldROWidget()) - execution_date = DateTimeWithTimezoneField( - lazy_gettext('Execution Date'), - widget=AirflowDateTimePickerROWidget(), - validators=[InputRequired()], - ) - conf = TextAreaField( - lazy_gettext('Conf'), validators=[ValidJson(), Optional()], widget=BS3TextAreaROWidget() - ) - - class TaskInstanceEditForm(DynamicForm): """Form for editing TaskInstance""" diff --git a/airflow/www/views.py b/airflow/www/views.py index e6af96a906645..032232d4f4c42 100644 --- a/airflow/www/views.py +++ b/airflow/www/views.py @@ -117,7 +117,6 @@ from airflow.www.forms import ( ConnectionForm, DagRunEditForm, - DagRunForm, DateTimeForm, DateTimeWithNumRunsForm, DateTimeWithNumRunsWithDagRunsForm, @@ -3436,7 +3435,6 @@ class DagRunModelView(AirflowModelView): class_permission_name = permissions.RESOURCE_DAG_RUN method_permission_name = { - 'add': 'create', 'list': 'read', 'action_clear': 'delete', 'action_muldelete': 'delete', @@ -3445,14 +3443,12 @@ class DagRunModelView(AirflowModelView): 'action_set_success': 'edit', } base_permissions = [ - permissions.ACTION_CAN_CREATE, permissions.ACTION_CAN_READ, permissions.ACTION_CAN_EDIT, permissions.ACTION_CAN_DELETE, permissions.ACTION_CAN_ACCESS_MENU, ] - add_columns = ['state', 'dag_id', 'execution_date', 'run_id', 'external_trigger', 'conf'] list_columns = [ 'state', 'dag_id', @@ -3481,7 +3477,6 @@ class DagRunModelView(AirflowModelView): base_filters = [['dag_id', DagFilter, lambda: []]] - add_form = DagRunForm edit_form = DagRunEditForm formatters_columns = { diff --git a/tests/www/views/test_views_dagrun.py b/tests/www/views/test_views_dagrun.py index 3a6da369928a2..aa989cf7631f1 100644 --- a/tests/www/views/test_views_dagrun.py +++ b/tests/www/views/test_views_dagrun.py @@ -15,14 +15,11 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -import json - import pytest from airflow.models import DagBag, DagRun, TaskInstance from airflow.utils import timezone from airflow.utils.session import create_session -from tests.test_utils.config import conf_vars from tests.test_utils.www import check_content_in_response @@ -45,97 +42,6 @@ def reset_dagrun(): session.query(TaskInstance).delete() -@pytest.mark.parametrize( - "post_date, expected", - [ - ("2018-07-06 05:04:03Z", timezone.datetime(2018, 7, 6, 5, 4, 3)), - ("2018-07-06 05:04:03-04:00", timezone.datetime(2018, 7, 6, 9, 4, 3)), - ("2018-07-06 05:04:03-08:00", timezone.datetime(2018, 7, 6, 13, 4, 3)), - ("2018-07-06 05:04:03", timezone.datetime(2018, 7, 6, 5, 4, 3)), - ], - ids=["UTC", "EDT", "PST", "naive"], -) -def test_create_dagrun(session, admin_client, post_date, expected): - data = { - "state": "running", - "dag_id": "example_bash_operator", - "execution_date": post_date, - "run_id": "test_create_dagrun", - } - resp = admin_client.post('/dagrun/add', data=data, follow_redirects=True) - check_content_in_response('Added Row', resp) - - dr = session.query(DagRun).one() - - assert dr.execution_date == expected - - -@conf_vars({("core", "default_timezone"): "America/Toronto"}) -def test_create_dagrun_without_timezone_default(session, admin_client): - data = { - "state": "running", - "dag_id": "example_bash_operator", - "execution_date": "2018-07-06 05:04:03", - "run_id": "test_create_dagrun", - } - resp = admin_client.post('/dagrun/add', data=data, follow_redirects=True) - check_content_in_response('Added Row', resp) - - dr = session.query(DagRun).one() - - assert dr.execution_date == timezone.datetime(2018, 7, 6, 9, 4, 3) - - -def test_create_dagrun_valid_conf(session, admin_client): - conf_value = dict(Valid=True) - data = { - "state": "running", - "dag_id": "example_bash_operator", - "execution_date": "2018-07-06 05:05:03-02:00", - "run_id": "test_create_dagrun_valid_conf", - "conf": json.dumps(conf_value), - } - - resp = admin_client.post('/dagrun/add', data=data, follow_redirects=True) - check_content_in_response('Added Row', resp) - dr = session.query(DagRun).one() - assert dr.conf == conf_value - - -def test_create_dagrun_invalid_conf(session, admin_client): - data = { - "state": "running", - "dag_id": "example_bash_operator", - "execution_date": "2018-07-06 05:06:03", - "run_id": "test_create_dagrun_invalid_conf", - "conf": "INVALID: [JSON", - } - - resp = admin_client.post('/dagrun/add', data=data, follow_redirects=True) - check_content_in_response('JSON Validation Error:', resp) - dr = session.query(DagRun).all() - assert not dr - - -def test_list_dagrun_includes_conf(session, admin_client): - data = { - "state": "running", - "dag_id": "example_bash_operator", - "execution_date": "2018-07-06 05:06:03", - "run_id": "test_list_dagrun_includes_conf", - "conf": '{"include": "me"}', - } - admin_client.post('/dagrun/add', data=data, follow_redirects=True) - dr = session.query(DagRun).one() - - expect_date = timezone.convert_to_utc(timezone.datetime(2018, 7, 6, 5, 6, 3)) - assert dr.execution_date == expect_date - assert dr.conf == {"include": "me"} - - resp = admin_client.get('/dagrun/list', follow_redirects=True) - check_content_in_response("{"include": "me"}", resp) - - def test_clear_dag_runs_action(session, admin_client): dag = DagBag().get_dag("example_bash_operator") task0 = dag.get_task("runme_0")