Skip to content

Commit

Permalink
Extend narrative log to implement new jira fields parameters: compone…
Browse files Browse the repository at this point in the history
…nts, primary_software_components and primary_hardware_components
  • Loading branch information
sebastian-aranda committed Aug 17, 2023
1 parent 0b69e20 commit 2636979
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 69 deletions.
3 changes: 2 additions & 1 deletion manager/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@
path(
"tcs/main/docstrings", api.views.tcs_main_docstrings, name="TCS-main-docstrings"
),
path("jira", api.views.jira, name="JIRA-API"),
path("jira-ticket/", api.views.jira_ticket, name="JIRA-API-CREATE"),
path("jira-comment/", api.views.jira_comment, name="JIRA-API-COMMENT"),
path("lfa/", api.views.lfa, name="LFA-API"),
path("lfa/<option>/", api.views.lfa, name="LFA-API"),
path(
Expand Down
190 changes: 122 additions & 68 deletions manager/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1147,30 +1147,46 @@ def execute(self, request, *args, **kwargs):
return Response({"error": "Bad request"}, status=status.HTTP_400_BAD_REQUEST)


def getTitle(request_data):
# Shared params
request_type = request_data["request_type"]
def get_jira_title(request_data):
"""Generate title for Jira ticket
Parameters:
-----------
request_data: dict
Request data
Returns:
--------
title: str
Jira ticket title
"""
request_type = request_data.get("request_type")
jira_title = request_data.get("jira_issue_title")

# # Exposure log params
# if request_type == "exposure":
# try:
# obs_id = request_data["obs_id"]
# return "LOVE generated: " + request_type
# except Exception:
# raise Exception("Error reading params")
# # Narrative log params
# if request_type == "narrative":
# try:
# system = request_data["system"]
# return "LOVE generated: " + request_type
# except Exception:
# raise Exception("Error reading params")
# return ""
if jira_title is not None and jira_title != "":
return jira_title

return "LOVE generated: " + request_type


def makeJiraDescription(request_data):
def get_jira_description(request_data):
"""Generate description for Jira ticket
Parameters:
-----------
request_data: dict
Request data
Returns:
--------
description: str
Jira ticket description
Raises:
-------
Exception
If there is an error reading the request data
"""
# Shared params
request_type = request_data["request_type"]
try:
Expand Down Expand Up @@ -1267,39 +1283,51 @@ def makeJiraDescription(request_data):
return description if description is not None else ""


def jira(request):
def jira_ticket(request):
"""Connects to JIRA API to create a ticket on a specific project.
For more information on issuetypes refer to:
ttps://jira.lsstcorp.org/rest/api/latest/issuetype/?projectId=JIRA_PROJECT_ID
Params
------
request: Request
The Request object
The request object from the Django view
Returns
-------
Response
The response and status code of the request to the JIRA API
"""
full_request = request.data
if "request_type" not in full_request:
Raises
------
Exception
If there is an error reading the request data
"""
request_data = request.data
if "request_type" not in request_data:
return Response({"ack": "Error reading request type"}, status=400)

tags_data = (
request_data.get("tags").split(",")
if request_data.get("tags") != "undefined"
else []
)

try:
jira_payload = {
"fields": {
"project": {"id": os.environ.get("JIRA_PROJECT_ID")},
"labels": [
"LOVE",
*(full_request["tags"].split(",") if full_request["tags"] else []),
*tags_data,
],
"summary": getTitle(full_request),
"description": makeJiraDescription(full_request),
"summary": get_jira_title(request_data),
"description": get_jira_description(request_data),
"customfield_15602": "on"
if int(full_request.get("level", 0)) >= 100
if int(request_data.get("level", 0)) >= 100
else "off", # Is Urgent?
"customfield_16702": float(
full_request.get("time_lost", 0)
request_data.get("time_lost", 0)
), # Obs. time loss
"issuetype": {"id": 12302},
},
Expand All @@ -1323,6 +1351,7 @@ def jira(request):
},
status=200,
)

return Response(
{
"ack": "Jira ticket could not be created",
Expand All @@ -1346,15 +1375,21 @@ def jira_comment(request):
-------
Response
The response and status code of the request to the JIRA API
"""
full_request = request.data
if "issue_id" not in full_request:
Raises
------
Exception
If there is an error reading the request data
"""
request_data = request.data
if "jira_issue_id" not in request_data:
return Response({"ack": "Error reading the JIRA issue ID"}, status=400)

jira_id = request_data.get("jira_issue_id")

try:
jira_payload = {
"body": makeJiraDescription(full_request),
"body": get_jira_description(request_data),
}
except Exception as e:
return Response({"ack": f"Error creating jira payload: {e}"}, status=400)
Expand All @@ -1363,13 +1398,13 @@ def jira_comment(request):
"Authorization": f"Basic {os.environ.get('JIRA_API_TOKEN')}",
"content-type": "application/json",
}
url = f"https://{os.environ.get('JIRA_API_HOSTNAME')}/rest/api/latest/issue/{full_request['issue_id']}/comment"
url = f"https://{os.environ.get('JIRA_API_HOSTNAME')}/rest/api/latest/issue/{jira_id}/comment"
response = requests.post(url, json=jira_payload, headers=headers)
if response.status_code == 201:
return Response(
{
"ack": "Jira comment created",
"url": f"https://jira.lsstcorp.org/browse/{full_request['issue_id']}",
"url": f"https://jira.lsstcorp.org/browse/{jira_id}",
},
status=200,
)
Expand Down Expand Up @@ -1458,7 +1493,6 @@ class ExposurelogViewSet(viewsets.ViewSet):
The API is documented at https://summit-lsp.lsst.codes/exposurelog/docs.
"""

# serializer_class = ExposureLogSerializer
permission_classes = (IsAuthenticated,)
parser_classes = (MultiPartParser,)

Expand All @@ -1474,13 +1508,15 @@ def create(self, request, *args, **kwargs):
query_params_string = urllib.parse.urlencode(request.query_params)
url = f"http://{os.environ.get('OLE_API_HOSTNAME')}/exposurelog/messages?{query_params_string}"

# Upload files to the LFA
lfa_urls = []
if "file" in request.data:
lfa_response = lfa(request, option="upload-file")
if lfa_response.status_code == 400 or lfa_response.status_code == 404:
return Response(lfa_response.json(), lfa_response.status_code)
lfa_urls = lfa_response.data.get("urls")

# Create Jira ticket
jira_url = None
if request.data.get("jira") == "true":
request.data._mutable = True
Expand All @@ -1490,10 +1526,10 @@ def create(self, request, *args, **kwargs):
request.data._mutable = False

jira_response = None
if request.data.get("jira_comment") == "true":
jira_response = jira_comment(request)
if request.data.get("jira_new") == "true":
jira_response = jira_ticket(request)
else:
jira_response = jira(request)
jira_response = jira_comment(request)

if jira_response.status_code == 400:
return Response(
Expand All @@ -1502,23 +1538,26 @@ def create(self, request, *args, **kwargs):
)
jira_url = jira_response.data.get("url")

# Clean some parameters
json_data = request.data.copy()
if "file" in json_data:
del json_data["file"]

if "tags" in json_data:
json_data["tags"] = json_data["tags"].split(",")
array_keys = {"tags"}
for key in array_keys:
if key in json_data:
json_data[key] = json_data[key].split(",")

json_data["urls"] = [jira_url, *lfa_urls]
json_data["urls"] = list(filter(None, json_data["urls"]))

json_data["user_agent"] = "LOVE"
json_data["user_id"] = f"{request.user}@{request.get_host()}"

# Create a exposure log for each obs_id
for obs in request.data.get("obs_id").split(","):
json_data["obs_id"] = obs
response = requests.post(url, json=json_data)
# response = requests.post(url, json=json_data)
return Response(response.json(), status=response.status_code)

@swagger_auto_schema(responses={200: "Exposure log retrieved"})
Expand All @@ -1531,11 +1570,15 @@ def retrieve(self, request, pk=None, *args, **kwargs):
def update(self, request, pk=None, *args, **kwargs):
url = f"http://{os.environ.get('OLE_API_HOSTNAME')}/exposurelog/messages/{pk}"

# Clean some parameters
json_data = request.data.copy()
if "tags" in json_data:
json_data["tags"] = json_data["tags"].split(",")
if "urls" in json_data:
json_data["urls"] = json_data["urls"].split(",")
array_keys = {
"urls",
"tags",
}
for key in array_keys:
if key in json_data:
json_data[key] = json_data[key].split(",")

response = requests.patch(url, json=json_data)
# TODO: allow uploading a file on update
Expand Down Expand Up @@ -1565,8 +1608,8 @@ class NarrativelogViewSet(viewsets.ViewSet):
The API is documented at https://summit-lsp.lsst.codes/narrativelog/docs.
"""

# serializer_class = NarrativeLogSerializer
permission_classes = (IsAuthenticated,)
parser_classes = (MultiPartParser,)

@swagger_auto_schema(responses={200: "Narrative logs listed"})
def list(self, request, *args, **kwargs):
Expand All @@ -1580,13 +1623,15 @@ def create(self, request, *args, **kwargs):
query_params_string = urllib.parse.urlencode(request.query_params)
url = f"http://{os.environ.get('OLE_API_HOSTNAME')}/narrativelog/messages?{query_params_string}"

# Upload files to the LFA
lfa_urls = []
if "file" in request.data:
lfa_response = lfa(request, option="upload-file")
if lfa_response.status_code == 400 or lfa_response.status_code == 404:
return Response(lfa_response.json(), lfa_response.status_code)
lfa_urls = lfa_response.data.get("urls")

# Create JIRA ticket
jira_url = None
if request.data.get("jira") == "true":
request.data._mutable = True
Expand All @@ -1596,10 +1641,10 @@ def create(self, request, *args, **kwargs):
request.data._mutable = False

jira_response = None
if request.data.get("jira_comment") == "true":
jira_response = jira_comment(request)
if request.data.get("jira_new") == "true":
jira_response = jira_ticket(request)
else:
jira_response = jira(request)
jira_response = jira_comment(request)

if jira_response.status_code == 400:
return Response(
Expand All @@ -1608,18 +1653,23 @@ def create(self, request, *args, **kwargs):
)
jira_url = jira_response.data.get("url")

# Clean some parameters
json_data = request.data.copy()
if "file" in json_data:
del json_data["file"]

if "tags" in json_data:
json_data["tags"] = json_data["tags"].split(",")
if "systems" in json_data:
json_data["systems"] = json_data["systems"].split(",")
if "subsystems" in json_data:
json_data["subsystems"] = json_data["subsystems"].split(",")
if "cscs" in json_data:
json_data["cscs"] = json_data["cscs"].split(",")
array_keys = {
"tags",
"systems",
"subsystems",
"cscs",
"components",
"primary_software_components",
"primary_hardware_components",
}
for key in array_keys:
if key in json_data:
json_data[key] = json_data[key].split(",")

json_data["urls"] = [jira_url, *lfa_urls]
json_data["urls"] = list(filter(None, json_data["urls"]))
Expand All @@ -1640,17 +1690,21 @@ def retrieve(self, request, pk=None, *args, **kwargs):
def update(self, request, pk=None, *args, **kwargs):
url = f"http://{os.environ.get('OLE_API_HOSTNAME')}/narrativelog/messages/{pk}"

# Clean some parameters
json_data = request.data.copy()
if "tags" in json_data:
json_data["tags"] = json_data["tags"].split(",")
if "systems" in json_data:
json_data["systems"] = json_data["systems"].split(",")
if "subsystems" in json_data:
json_data["subsystems"] = json_data["subsystems"].split(",")
if "cscs" in json_data:
json_data["cscs"] = json_data["cscs"].split(",")
if "urls" in json_data:
json_data["urls"] = json_data["urls"].split(",")
array_keys = {
"urls",
"tags",
"systems",
"subsystems",
"cscs",
"components",
"primary_software_components",
"primary_hardware_components",
}
for key in array_keys:
if key in json_data:
json_data[key] = json_data[key].split(",")

response = requests.patch(url, json=json_data)
# TODO: allow uploading a file on update
Expand Down

0 comments on commit 2636979

Please sign in to comment.