Skip to content

Commit

Permalink
[AIRFLOW-3303] Deprecate old UI in favor of FAB (apache#4339)
Browse files Browse the repository at this point in the history
  • Loading branch information
verdan authored and kaxil committed Jan 14, 2019
1 parent 08eba52 commit c030729
Show file tree
Hide file tree
Showing 192 changed files with 3,084 additions and 64,453 deletions.
2 changes: 1 addition & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ omit =
scripts/*
dev/*
airflow/migrations/*
airflow/www_rbac/node_modules/**
airflow/www/node_modules/**
10 changes: 5 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,9 +355,9 @@ $ alembic revision -m "add new field to db"
~/airflow/airflow/migrations/versions/12341123_add_new_field_to_db.py
```

## Setting up the node / npm javascript environment (ONLY FOR www_rbac)
## Setting up the node / npm javascript environment

`airflow/www_rbac/` contains all npm-managed, front end assets.
`airflow/www/` contains all npm-managed, front end assets.
Flask-Appbuilder itself comes bundled with jQuery and bootstrap.
While these may be phased out over time, these packages are currently not
managed with npm.
Expand Down Expand Up @@ -389,12 +389,12 @@ export PATH="$HOME/.npm-packages/bin:$PATH"
#### npm packages

To install third party libraries defined in `package.json`, run the
following within the `airflow/www_rbac/` directory which will install them in a
new `node_modules/` folder within `www_rbac/`.
following within the `airflow/www/` directory which will install them in a
new `node_modules/` folder within `www/`.

```bash
# from the root of the repository, move to where our JS package.json lives
cd airflow/www_rbac/
cd airflow/www/
# run npm install to fetch all the dependencies
npm install
```
Expand Down
10 changes: 4 additions & 6 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,12 @@ include LICENSE
include CHANGELOG.txt
include README.md
graft licenses/
graft airflow/www/templates
graft airflow/www
graft airflow/www/static
graft airflow/www_rbac
graft airflow/www_rbac/static
graft airflow/www_rbac/templates
graft airflow/www_rbac/translations
graft airflow/www/templates
graft airflow/www/translations
include airflow/alembic.ini
graft scripts/systemd
graft scripts/upstart
graft airflow/config_templates
recursive-exclude airflow/www_rbac/node_modules *
recursive-exclude airflow/www/node_modules *
7 changes: 7 additions & 0 deletions UPDATING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ assists users migrating to a new version.

## Airflow Master

### Deprecate legacy UI in favor of FAB RBAC UI
Previously we were using two versions of UI, which were hard to maintain as we need to implement/update the same feature
in both versions. With this change we've removed the older UI in favor of Flask App Builder RBAC UI. No need to set the
RBAC UI explicitly in the configuration now as this is the only default UI.
Please note that that custom auth backends will need re-writing to target new FAB based UI.


#### SLUGIFY_USES_TEXT_UNIDECODE or AIRFLOW_GPL_UNIDECODE no longer required

It is no longer required to set one of the environment variables to avoid
Expand Down
28 changes: 9 additions & 19 deletions airflow/bin/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,7 @@
from airflow.utils.net import get_hostname
from airflow.utils.log.logging_mixin import (LoggingMixin, redirect_stderr,
redirect_stdout)
from airflow.www.app import (cached_app, create_app)
from airflow.www_rbac.app import cached_app as cached_app_rbac
from airflow.www_rbac.app import create_app as create_app_rbac
from airflow.www_rbac.app import cached_appbuilder
from airflow.www.app import cached_app, create_app, cached_appbuilder

from sqlalchemy.orm import exc

Expand Down Expand Up @@ -842,16 +839,13 @@ def webserver(args):
print(
"Starting the web server on port {0} and host {1}.".format(
args.port, args.hostname))
if settings.RBAC:
app, _ = create_app_rbac(conf, testing=conf.get('core', 'unit_test_mode'))
else:
app = create_app(conf, testing=conf.get('core', 'unit_test_mode'))
app, _ = create_app(conf, testing=conf.get('core', 'unit_test_mode'))
app.run(debug=True, use_reloader=False if app.config['TESTING'] else True,
port=args.port, host=args.hostname,
ssl_context=(ssl_cert, ssl_key) if ssl_cert and ssl_key else None)
else:
os.environ['SKIP_DAGS_PARSING'] = 'True'
app = cached_app_rbac(conf) if settings.RBAC else cached_app(conf)
app = cached_app(conf)
pid, stdout, stderr, log_file = setup_locations(
"webserver", args.pid, args.stdout, args.stderr, args.log_file)
os.environ.pop('SKIP_DAGS_PARSING')
Expand All @@ -878,7 +872,6 @@ def webserver(args):
'-b', args.hostname + ':' + str(args.port),
'-n', 'airflow-webserver',
'-p', str(pid),
'-c', 'python:airflow.www.gunicorn_config',
]

if args.access_logfile:
Expand All @@ -893,7 +886,7 @@ def webserver(args):
if ssl_cert:
run_args += ['--certfile', ssl_cert, '--keyfile', ssl_key]

webserver_module = 'www_rbac' if settings.RBAC else 'www'
webserver_module = 'www'
run_args += ["airflow." + webserver_module + ".app:cached_app()"]

gunicorn_master_proc = None
Expand Down Expand Up @@ -1078,7 +1071,7 @@ def worker(args):

def initdb(args):
print("DB: " + repr(settings.engine.url))
db.initdb(settings.RBAC)
db.initdb()
print("Done.")


Expand All @@ -1087,7 +1080,7 @@ def resetdb(args):
if args.yes or input("This will drop existing tables "
"if they exist. Proceed? "
"(y/n)").upper() == "Y":
db.resetdb(settings.RBAC)
db.resetdb()
else:
print("Bail.")

Expand Down Expand Up @@ -1445,12 +1438,9 @@ def list_dag_runs(args, dag=None):

@cli_utils.action_logging
def sync_perm(args):
if settings.RBAC:
appbuilder = cached_appbuilder()
print('Update permission, view-menu for all existing roles')
appbuilder.sm.sync_roles()
else:
print('The sync_perm command only works for rbac UI.')
appbuilder = cached_appbuilder()
print('Update permission, view-menu for all existing roles')
appbuilder.sm.sync_roles()


Arg = namedtuple(
Expand Down
3 changes: 0 additions & 3 deletions airflow/config_templates/default_airflow.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,6 @@ hide_paused_dags_by_default = False
# Consistent page size across all listing views in the UI
page_size = 100

# Use FAB-based webserver with RBAC feature
rbac = False

# Define the color of navigation bar
navbar_color = #007A87

Expand Down
1 change: 0 additions & 1 deletion airflow/config_templates/default_test.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ dag_default_view = tree
log_fetch_timeout_sec = 5
hide_paused_dags_by_default = False
page_size = 100
rbac = False

[email]
email_backend = airflow.utils.email.send_email_smtp
Expand Down
14 changes: 6 additions & 8 deletions airflow/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,16 +528,14 @@ def parameterized_config(template):

conf.read(AIRFLOW_CONFIG)

DEFAULT_WEBSERVER_CONFIG = _read_default_config_file('default_webserver_config.py')

if conf.getboolean('webserver', 'rbac'):
DEFAULT_WEBSERVER_CONFIG = _read_default_config_file('default_webserver_config.py')
WEBSERVER_CONFIG = AIRFLOW_HOME + '/webserver_config.py'

WEBSERVER_CONFIG = AIRFLOW_HOME + '/webserver_config.py'

if not os.path.isfile(WEBSERVER_CONFIG):
log.info('Creating new FAB webserver config file in: %s', WEBSERVER_CONFIG)
with open(WEBSERVER_CONFIG, 'w') as f:
f.write(DEFAULT_WEBSERVER_CONFIG)
if not os.path.isfile(WEBSERVER_CONFIG):
log.info('Creating new FAB webserver config file in: %s', WEBSERVER_CONFIG)
with open(WEBSERVER_CONFIG, 'w') as f:
f.write(DEFAULT_WEBSERVER_CONFIG)

if conf.getboolean('core', 'unit_test_mode'):
conf.load_test_config()
Expand Down
7 changes: 4 additions & 3 deletions airflow/contrib/plugins/metastore_browser/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from airflow.hooks.presto_hook import PrestoHook
from airflow.plugins_manager import AirflowPlugin
from airflow.www import utils as wwwutils
from airflow.www.decorators import gzipped

METASTORE_CONN_ID = 'metastore_default'
METASTORE_MYSQL_CONN_ID = 'metastore_mysql'
Expand Down Expand Up @@ -86,7 +87,7 @@ def db(self):
return self.render(
"metastore_browser/db.html", tables=tables, db=db)

@wwwutils.gzipped
@gzipped
@expose('/partitions/')
def partitions(self):
schema, table = request.args.get("table").split('.')
Expand Down Expand Up @@ -114,7 +115,7 @@ def partitions(self):
index=False,
na_rep='',)

@wwwutils.gzipped
@gzipped
@expose('/objects/')
def objects(self):
where_clause = ''
Expand Down Expand Up @@ -142,7 +143,7 @@ def objects(self):
for row in h.get_records(sql)]
return json.dumps(d)

@wwwutils.gzipped
@gzipped
@expose('/data/')
def data(self):
table = request.args.get("table")
Expand Down
50 changes: 16 additions & 34 deletions airflow/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -885,44 +885,26 @@ def log_filepath(self):
@property
def log_url(self):
iso = quote(self.execution_date.isoformat())
BASE_URL = configuration.conf.get('webserver', 'BASE_URL')
if settings.RBAC:
return BASE_URL + (
"/log?"
"execution_date={iso}"
"&task_id={self.task_id}"
"&dag_id={self.dag_id}"
).format(**locals())
else:
return BASE_URL + (
"/admin/airflow/log"
"?dag_id={self.dag_id}"
"&task_id={self.task_id}"
"&execution_date={iso}"
).format(**locals())
base_url = configuration.conf.get('webserver', 'BASE_URL')
return base_url + (
"/log?"
"execution_date={iso}"
"&task_id={self.task_id}"
"&dag_id={self.dag_id}"
).format(**locals())

@property
def mark_success_url(self):
iso = quote(self.execution_date.isoformat())
BASE_URL = configuration.conf.get('webserver', 'BASE_URL')
if settings.RBAC:
return BASE_URL + (
"/success"
"?task_id={self.task_id}"
"&dag_id={self.dag_id}"
"&execution_date={iso}"
"&upstream=false"
"&downstream=false"
).format(**locals())
else:
return BASE_URL + (
"/admin/airflow/success"
"?task_id={self.task_id}"
"&dag_id={self.dag_id}"
"&execution_date={iso}"
"&upstream=false"
"&downstream=false"
).format(**locals())
base_url = configuration.conf.get('webserver', 'BASE_URL')
return base_url + (
"/success"
"?task_id={self.task_id}"
"&dag_id={self.dag_id}"
"&execution_date={iso}"
"&upstream=false"
"&downstream=false"
).format(**locals())

@provide_session
def current_state(self, session=None):
Expand Down
1 change: 0 additions & 1 deletion airflow/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@

log = logging.getLogger(__name__)

RBAC = conf.getboolean('webserver', 'rbac')

TIMEZONE = pendulum.timezone('UTC')
try:
Expand Down
19 changes: 7 additions & 12 deletions airflow/utils/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def merge_conn(conn, session=None):
session.commit()


def initdb(rbac=False):
def initdb():
session = settings.Session()

from airflow import models
Expand Down Expand Up @@ -314,10 +314,8 @@ def initdb(rbac=False):
session.add(chart)
session.commit()

if rbac:
from flask_appbuilder.security.sqla import models
from flask_appbuilder.models.sqla import Base
Base.metadata.create_all(settings.engine)
from flask_appbuilder.models.sqla import Base
Base.metadata.create_all(settings.engine)


def upgradedb():
Expand All @@ -336,7 +334,7 @@ def upgradedb():
command.upgrade(config, 'heads')


def resetdb(rbac):
def resetdb():
"""
Clear out the database
"""
Expand All @@ -352,10 +350,7 @@ def resetdb(rbac):
if mc._version.exists(settings.engine):
mc._version.drop(settings.engine)

if rbac:
# drop rbac security tables
from flask_appbuilder.security.sqla import models
from flask_appbuilder.models.sqla import Base
Base.metadata.drop_all(settings.engine)
from flask_appbuilder.models.sqla import Base
Base.metadata.drop_all(settings.engine)

initdb(rbac)
initdb()
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit c030729

Please sign in to comment.