diff --git a/.gitignore b/.gitignore index 76b5235..9705037 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ cfg/* !cfg/sample.cfg +!cfg/sample.env ### From https://github.com/github/gitignore/blob/main/Node.gitignore # Logs diff --git a/README.md b/README.md index 363f101..3042876 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,27 @@ If desired, the script will also create the Jira cards for the new cases. Link to script usage: [telco5g-jira.py readme](https://github.com/RHsyseng/t5g-field-support-team-utils/blob/main/telco5g-jira.py.md) +## Dashboard Development Setup +In the `dashboard` directory, you can use the `Dockerfile` and `docker-compose.yml` to +set up a development environment. + +Note: If you are only interested in the frontend, you can comment out everything in +`docker-compose.yml` under the "Backend" header, except for the "volumes" section at +the bottom. + +Prerequisites: +- [Podman](https://podman.io/get-started) or [Docker](https://docs.docker.com/engine/install/) +- [podman-compose](https://podman-desktop.io/docs/compose/setting-up-compose) or [docker-compose](https://docs.docker.com/compose/) + +#### Steps +1. If you are interested in setting up the backend services, fill out `cfg/sample.env` +with any relevant details. +2. Run `cd dashboard` and `podman-compose up -d` + +After it's built, you can access the dashboard at , and the Flower +frontend at . + + ## CI This project has a CI that is triggered on every push. diff --git a/cfg/sample.env b/cfg/sample.env new file mode 100644 index 0000000..a735da6 --- /dev/null +++ b/cfg/sample.env @@ -0,0 +1,39 @@ +# For use with dashboard/docker-compose.yml + +# The following information is only necessary if you are interested in setting up the +# backend services and populating your local instance of the dashboard with real data. +# In that case, you should try to provide as much information below as possible. +# However, if some information is omitted, it shouldn't affect other data gathering +# scripts. For example, if bz_key is omitted, other data should still be gathered. + + +# Don't change this, unless you want the scripts to make changes to the Jira Board that +# you've defined below. Shouldn't need to change this for most development work. +READ_ONLY=true + +### Red Hat API +# Offline token https://access.redhat.com/management/api +# How to use it https://access.redhat.com/articles/3626371 +offline_token='' +redhat_api='https://access.redhat.com/hydra/rest' +watchlist_url= + +# search query +case_query='case_tags:*shift_telco5g*' + +### Bugzilla API +# Python Wrapper for BZ API: https://github.com/python-bugzilla/python-bugzilla +bz_key="" + +# Jira +jira_sprint='T5GFE' +jira_server='https://issues.redhat.com' +jira_project='KNIECO' +jira_component='KNI Labs & Field' +jira_board='KNI-ECO Labs & Field' +jira_query='field' +jira_pass='' + +# Jira escalations +jira_escalations_project='RHOCPPRIO' +jira_escalations_label='Telco5g' diff --git a/dashboard/docker-compose.yml b/dashboard/docker-compose.yml new file mode 100644 index 0000000..d652373 --- /dev/null +++ b/dashboard/docker-compose.yml @@ -0,0 +1,63 @@ +--- +version: '3.9' +services: + redis: + image: redis:alpine + # Persist redis data so that you don't have to regather data + volumes: + - redis_data:/data + + ### Frontend + dashboard-ui: + image: localhost/dashboard + build: . + command: gunicorn --bind 0.0.0.0:8080 --timeout 1200 wsgi:app + ports: + - 8080:8080 + environment: + - FLASK_LOGIN_DISABLED=true # Disable SSO Login for dev environments + depends_on: + - redis + + ### Backend (can remove if only developing front end) + + # Gathers data if cache is empty + init-cache: + image: localhost/dashboard + command: flask init-cache + env_file: + - ../cfg/sample.env + depends_on: + - redis + + # Gathers data on timed basis + celery-worker: + image: localhost/dashboard + command: celery -A t5gweb.taskmgr worker --loglevel=info -E + env_file: + - ../cfg/sample.env + depends_on: + - redis + + # Schedules celery-worker + celery-beat: + image: localhost/dashboard + command: celery -A t5gweb.taskmgr beat -s /tmp/schedule + env_file: + - ../cfg/sample.env + depends_on: + - redis + + # Frontend for celery tasks + flower: + image: localhost/dashboard + command: celery -A t5gweb.taskmgr flower --address=0.0.0.0 --port=8080 --purge_offline_workers=300 + ports: + - 8000:8080 + env_file: + - ../cfg/sample.env + depends_on: + - redis + +volumes: + redis_data: \ No newline at end of file diff --git a/dashboard/src/t5gweb/__init__.py b/dashboard/src/t5gweb/__init__.py index cf88f88..76cbc1e 100644 --- a/dashboard/src/t5gweb/__init__.py +++ b/dashboard/src/t5gweb/__init__.py @@ -12,6 +12,7 @@ def create_app(test_config=None): # create and configure the app app = Flask(__name__, instance_relative_config=True) app.config["SECRET_KEY"] = os.environ.get("secret_key") + app.config.from_prefixed_env() ui.login_manager.init_app(app) if test_config is None: # load the instance config, if it exists, when not testing diff --git a/dashboard/src/t5gweb/taskmgr.py b/dashboard/src/t5gweb/taskmgr.py index 94c4a3b..134aac8 100644 --- a/dashboard/src/t5gweb/taskmgr.py +++ b/dashboard/src/t5gweb/taskmgr.py @@ -21,19 +21,35 @@ def setup_scheduled_tasks(sender, **kwargs): cfg = set_cfg() - # check for new cases - sender.add_periodic_task( - crontab(hour="*", minute="10"), # 10 mins after every hour - portal_jira_sync.s(), - name="portal2jira_sync", - ) + # Anything except for 'true' will be set to False + read_only = (os.getenv("READ_ONLY", 'false') == 'true') - # ensure case severities match card priorities - sender.add_periodic_task( - crontab(hour="3", minute="12"), # everyday at 3:12 - t_sync_priority.s(), - name="priority_sync", - ) + if read_only is False: + # Run tasks that alter Jira cards, send emails, or send Slack messages + logging.warning("Not read only: making changes to Jira Boards") + # check for new cases + sender.add_periodic_task( + crontab(hour="*", minute="10"), # 10 mins after every hour + portal_jira_sync.s(), + name="portal2jira_sync", + ) + + # ensure case severities match card priorities + sender.add_periodic_task( + crontab(hour="3", minute="12"), # everyday at 3:12 + t_sync_priority.s(), + name="priority_sync", + ) + + # tag telco5g bugzillas and JIRAs with 'Telco' and/or 'Telco:Case' + if "telco5g" in cfg["query"]: + sender.add_periodic_task( + crontab(hour="*/24", minute="33"), # once a day + 33 for randomness + tag_bz.s(), + name="tag_bz", + ) + else: + logging.warning("Read only - Not making changes to Jira boards.") # update card cache sender.add_periodic_task( @@ -88,14 +104,6 @@ def setup_scheduled_tasks(sender, **kwargs): name="escalations_sync", ) - # tag telco5g bugzillas and JIRAs with 'Telco' and/or 'Telco:Case' - if "telco5g" in cfg["query"]: - sender.add_periodic_task( - crontab(hour="*/24", minute="33"), # once a day + 33 for randomness - tag_bz.s(), - name="tag_bz", - ) - # update watchlist cache if cfg["watchlist_url"] is not None and cfg["watchlist_url"] != "": sender.add_periodic_task(