141 lines
4.8 KiB
Python
141 lines
4.8 KiB
Python
# Configure logger
|
|
import logging
|
|
from fastapi import APIRouter, FastAPI
|
|
from contextlib import asynccontextmanager
|
|
from zoneinfo import ZoneInfo
|
|
|
|
|
|
from modules.connectors.connectorTicketJira import ConnectorTicketJira
|
|
from modules.connectors.connectorSharepoint import ConnectorSharepoint
|
|
from modules.interfaces.interfaceTicketObjects import TicketSharepointSyncInterface
|
|
|
|
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
|
from apscheduler.triggers.cron import CronTrigger
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
scheduler = AsyncIOScheduler(timezone=ZoneInfo("Europe/Zurich"))
|
|
|
|
|
|
@asynccontextmanager
|
|
async def router_lifespan(app: FastAPI):
|
|
# start scheduler when this router is mounted
|
|
scheduler.add_job(
|
|
perform_sync_jira_delta_group,
|
|
CronTrigger(minute="0"), # run at the top of every hour
|
|
id="jira_delta_group_sync",
|
|
replace_existing=True,
|
|
coalesce=True,
|
|
max_instances=1,
|
|
misfire_grace_time=1800,
|
|
)
|
|
scheduler.start()
|
|
logger.info("APScheduler started (jira_delta_group_sync hourly)")
|
|
try:
|
|
yield
|
|
finally:
|
|
if scheduler.running:
|
|
scheduler.shutdown(wait=False)
|
|
logger.info("APScheduler stopped")
|
|
|
|
|
|
router = APIRouter(
|
|
prefix="/api/jira",
|
|
tags=["JIRA Sync"],
|
|
lifespan=router_lifespan,
|
|
)
|
|
|
|
|
|
@router.post("/sync/delta-group")
|
|
async def sync_jira_delta_group():
|
|
"""Endpoint to trigger JIRA-SharePoint sync for Delta Group project."""
|
|
|
|
logger.info("Received request to sync JIRA Delta Group project")
|
|
await perform_sync_jira_delta_group()
|
|
|
|
# Return a response
|
|
return {"status": "Sync completed"}
|
|
|
|
|
|
async def perform_sync_jira_delta_group():
|
|
logger.info("Syncing Jira issues for Delta Group...")
|
|
|
|
# Sharepoint connection parameters
|
|
sharepoint_client_id = None
|
|
sharepoint_client_secret = None
|
|
sharepoint_site_url = None
|
|
|
|
# Jira connection parameters
|
|
jira_username = None
|
|
jira_api_token = None
|
|
jira_url = "https://deltasecurity.atlassian.net"
|
|
project_code = "DCS"
|
|
issue_type = "Task"
|
|
|
|
# Basic validation (credentials will be added later)
|
|
if not all([sharepoint_client_id, sharepoint_client_secret, sharepoint_site_url]):
|
|
raise ValueError("SharePoint credentials not configured")
|
|
|
|
if not all([jira_username, jira_api_token]):
|
|
raise ValueError("JIRA credentials not configured")
|
|
|
|
# Define the task sync definition
|
|
task_sync_definition = {
|
|
# key=excel-header, [get:jira>excel | put: excel>jira, jira-xml-field-list]
|
|
"ID": ["get", ["key"]],
|
|
"Module Category": ["get", ["fields", "customfield_10058", "value"]],
|
|
"Summary": ["get", ["fields", "summary"]],
|
|
"Description": ["get", ["fields", "description"]],
|
|
"References": ["get", ["fields", "customfield_10066"]],
|
|
"Priority": ["get", ["fields", "priority", "name"]],
|
|
"Issue Status": ["get", ["fields", "customfield_10062"]],
|
|
"Assignee": ["get", ["fields", "assignee", "displayName"]],
|
|
"Issue Created": ["get", ["fields", "created"]],
|
|
"Due Date": ["get", ["fields", "duedate"]],
|
|
"DELTA Comments": ["get", ["fields", "customfield_10060"]],
|
|
"SELISE Ticket References": ["put", ["fields", "customfield_10067"]],
|
|
"SELISE Status Values": ["put", ["fields", "customfield_10065"]],
|
|
"SELISE Comments": ["put", ["fields", "customfield_10064"]],
|
|
}
|
|
|
|
# SharePoint file configuration
|
|
sync_folder = "/sites/<YourSite>/Shared Documents/TicketSync"
|
|
sync_file = "delta_group_selise_ticket_exchange_list.csv"
|
|
backup_folder = "/sites/<YourSite>/Shared Documents/TicketSync/Backups"
|
|
audit_folder = "/sites/<YourSite>/Shared Documents/TicketSync/AuditLogs"
|
|
|
|
# Create the jira connector instance
|
|
jira_connector = await ConnectorTicketJira.create(
|
|
jira_username=jira_username,
|
|
jira_api_token=jira_api_token,
|
|
jira_url=jira_url,
|
|
project_code=project_code,
|
|
issue_type=issue_type,
|
|
)
|
|
|
|
# Create the sharepoint connector instance
|
|
ctx = ConnectorSharepoint.get_client_context_from_app(
|
|
site_url=sharepoint_site_url,
|
|
client_id=sharepoint_client_id,
|
|
client_secret=sharepoint_client_secret,
|
|
)
|
|
sharepoint_connector = await ConnectorSharepoint.create(ctx=ctx)
|
|
|
|
# Create the sync interface instance
|
|
sync_interface = await TicketSharepointSyncInterface.create(
|
|
connector_ticket=jira_connector,
|
|
connector_sharepoint=sharepoint_connector,
|
|
task_sync_definition=task_sync_definition,
|
|
sync_folder=sync_folder,
|
|
sync_file=sync_file,
|
|
backup_folder=backup_folder,
|
|
audit_folder=audit_folder,
|
|
)
|
|
|
|
# Sync from JIRA to CSV in Sharepoint
|
|
await sync_interface.sync_from_jira_to_csv()
|
|
|
|
# Sync from CSV in Sharepoint to JIRA
|
|
await sync_interface.sync_from_csv_to_jira()
|