Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
5 changes: 5 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ REPO_ORG=https://github.com/canonical
SQLALCHEMY_DATABASE_URI=postgresql://postgres:postgres@localhost:5432/postgres
TASK_DELAY=30
DIRECTORY_API_TOKEN=token
JIRA_EMAIL=email@example.com
JIRA_TOKEN=token
JIRA_URL=https://warthogs.atlassian.net
JIRA_LABELS=sites_BAU
JIRA_COPY_UPDATES_EPIC=KAN-1
5 changes: 5 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ jobs:
-e GH_TOKEN=token \
-e REPO_ORG=https://github.com/canonical \
-e SQLALCHEMY_DATABASE_URI=postgresql://postgres:postgres@localhost:5432/postgres \
-e JIRA_EMAIL=example@canonical.com \
-e JIRA_TOKEN=jiratoken \
-e JIRA_URL=https://example.atlassian.net \
-e JIRA_LABELS=somelabel \
-e JIRA_COPY_UPDATES_EPIC=WD-9999999 \
--network host \
websites-content-system & sleep 1
curl --head --fail --retry-delay 1 --retry 30 --retry-connrefused http://localhost
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,20 @@ $ docker inspect <postgres-container-id> | grep IPAddress
"name": "/",
"title": null
}
}
```

#### Making a webpage update request

<details>
<summary><code>POST</code> <code><b>/request-changes</b></code>
</details>

```json
{
"due_date": "2022-01-01",
"reporter_id": 1,
"webpage_id": 31,
"type": 1,
"description": "This is a description",
}
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ multiprocess==0.70.16
psycopg2-binary==2.9.9
PyYAML==6.0.2
Flask-Migrate==4.0.7
Flask-Pydantic==0.12.0
Flask-SQLAlchemy==3.1.1
talisker[gunicorn,gevent,flask,prometheus,raven]==0.21.3
valkey==6.0.0b1
Expand Down
4 changes: 4 additions & 0 deletions webapp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from webapp.cache import init_cache
from webapp.context import base_context
from webapp.jira import init_jira
from webapp.models import init_db
from webapp.sso import init_sso
from webapp.tasks import init_tasks
Expand All @@ -26,4 +27,7 @@ def create_app():
# Initialize tasks
init_tasks(app)

# Initialize JIRA
init_jira(app)

return app
61 changes: 39 additions & 22 deletions webapp/app.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
from os import environ

import requests
from flask import jsonify, render_template, request
from flask_pydantic import validate

from webapp import create_app
from webapp.helper import create_jira_task, get_or_create_user_id
from webapp.models import Reviewer, Webpage, db, get_or_create
from webapp.schemas import (
ChangesRequestModel,
)
from webapp.site_repository import SiteRepository
from webapp.sso import login_required
from webapp.tasks import LOCKS
from webapp.models import get_or_create, db, Reviewer, Webpage
from webapp.helper import get_or_create_user_id

import requests

app = create_app()

Expand Down Expand Up @@ -43,7 +46,7 @@ def index(path):
return render_template("index.html")


@app.route('/get-users/<username>', methods=['GET'])
@app.route("/get-users/<username>", methods=["GET"])
@login_required
def get_users(username: str):
query = """
Expand All @@ -59,27 +62,28 @@ def get_users(username: str):
}
"""

headers = {
"Authorization": "token " + environ.get("DIRECTORY_API_TOKEN")
}
headers = {"Authorization": "token " + environ.get("DIRECTORY_API_TOKEN")}

# Currently directory-api only supports strict comparison of field values,
# so we have to send two requests instead of one for first and last names
response = requests.post(
"https://directory.wpe.internal/graphql/", json={
'query': query,
'variables': {'name': username.strip()},
}, headers=headers, verify=False)

if (response.status_code == 200):
users = response.json().get('data', {}).get(
'employees', [])
"https://directory.wpe.internal/graphql/",
json={
"query": query,
"variables": {"name": username.strip()},
},
headers=headers,
verify=False,
)

if response.status_code == 200:
users = response.json().get("data", {}).get("employees", [])
return jsonify(list(users))
else:
return jsonify({"error": "Failed to fetch users"}), 500


@app.route('/set-reviewers', methods=['POST'])
@app.route("/set-reviewers", methods=["POST"])
@login_required
def set_reviewers():
data = request.get_json()
Expand All @@ -99,15 +103,14 @@ def set_reviewers():

# Create new reviewer rows
for user_id in user_ids:
get_or_create(db.session,
Reviewer,
user_id=user_id,
webpage_id=webpage_id)
get_or_create(
db.session, Reviewer, user_id=user_id, webpage_id=webpage_id
)

return jsonify({"message": "Successfully set reviewers"}), 200


@app.route('/set-owner', methods=['POST'])
@app.route("/set-owner", methods=["POST"])
@login_required
def set_owner():
data = request.get_json()
Expand All @@ -123,3 +126,17 @@ def set_owner():
db.session.commit()

return jsonify({"message": "Successfully set owner"}), 200


@app.route("/request-changes", methods=["POST"])
@login_required
@validate()
def request_changes(body: ChangesRequestModel):

# Make a request to JIRA to create a task
try:
create_jira_task(app, body.model_dump())
except Exception as e:
return jsonify(e), 500

return jsonify("Task created successfully"), 201
45 changes: 36 additions & 9 deletions webapp/helper.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,45 @@
from webapp.models import get_or_create, db, User
from webapp.models import JiraTask, User, db, get_or_create


def get_or_create_user_id(user):
# If user does not exist, create a new user in the "users" table
user_hrc_id = user.get("id")
user_exists = User.query.filter_by(hrc_id=user_hrc_id).first()
if not user_exists:
user_exists, _ = get_or_create(db.session,
User,
name=user.get("name"),
email=user.get("email"),
team=user.get("team"),
department=user.get("department"),
job_title=user.get("jobTitle"),
hrc_id=user_hrc_id)
user_exists, _ = get_or_create(
db.session,
User,
name=user.get("name"),
email=user.get("email"),
team=user.get("team"),
department=user.get("department"),
job_title=user.get("jobTitle"),
hrc_id=user_hrc_id,
)

return user_exists.id


def create_jira_task(app, task):
"""
Create a new issue on jira and add a record to the db
"""
# TODO: If an epic already exists for this request, add subtasks to it.

jira = app.config["JIRA"]
issue = jira.create_issue(
due_date=task["due_date"],
reporter_id=task["reporter_id"],
webpage_id=task["webpage_id"],
request_type=task["type"],
description=task["description"],
)

# Create jira task in the database
get_or_create(
db.session,
JiraTask,
jira_id=issue["id"],
webpage_id=task["webpage_id"],
user_id=task["reporter_id"],
)
Loading
Loading