Skip to content

Commit

Permalink
migrage reporting to grafana connector
Browse files Browse the repository at this point in the history
  • Loading branch information
taylorwalton committed Mar 2, 2024
1 parent de58e23 commit 9daa23a
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 131 deletions.
16 changes: 14 additions & 2 deletions backend/app/connectors/grafana/routes/reporting.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
from app.connectors.grafana.schema.reporting import GrafanaGenerateIframeLinksRequest
from app.connectors.grafana.schema.reporting import GrafanaGenerateIframeLinksResponse
from app.connectors.grafana.schema.reporting import GrafanaLinksList
from app.connectors.grafana.schema.reporting import GrafanaOrganizationsResponse
from app.connectors.grafana.schema.reporting import GrafanaOrganizationsResponse, GenerateReportRequest, GenerateReportResponse
from app.connectors.grafana.schema.reporting import Panel
from app.connectors.grafana.schema.reporting import TimeRange
from app.connectors.grafana.services.reporting import get_dashboard_details
from app.connectors.grafana.services.reporting import get_dashboards
from app.connectors.grafana.services.reporting import get_orgs
from app.connectors.grafana.services.reporting import get_orgs, generate_report
from app.connectors.models import Connectors
from app.db.db_session import get_db

Expand Down Expand Up @@ -206,3 +206,15 @@ async def generate_grafana_iframe_links(
links=panel_urls,
success=True,
)


@grafana_reporting_router.post(
"/generate-report",
description="Create a new report.",
)
async def create_report(
request: GenerateReportRequest,
session: AsyncSession = Depends(get_db)
) -> GenerateReportResponse:
logger.info("Generating report")
return await generate_report(request, session)
20 changes: 20 additions & 0 deletions backend/app/connectors/grafana/schema/reporting.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,23 @@ class GrafanaGenerateIframeLinksResponse(BaseModel):
message: str = Field(..., description="The message from the response.")
links: List[GrafanaLinksList] = Field(..., description="The links collected from Grafana.")
success: bool = Field(..., description="The success of the response.")

class GenerateReportRequest(BaseModel):
urls: list[str] = Field(
[
'http://ashdevcopilot01.socfortress.local:3000/d-solo/ab9bab2c-5d86-43e7-bac2-c1d68fc91342/huntress-summary?orgId=1&from=1708725633941&to=1709330433941&panelId=5',
'http://ashdevcopilot01.socfortress.local:3000/d-solo/ab9bab2c-5d86-43e7-bac2-c1d68fc91342/huntress-summary?orgId=1&from=1708725654862&to=1709330454862&panelId=1',
'http://ashdevcopilot01.socfortress.local:3000/d-solo/a1891b09-fba9-498e-807e-1ad774c8557f/sap-users-auth?orgId=44&from=1709303384274&to=1709389784274&panelId=43',
'http://ashdevcopilot01.socfortress.local:3000/d-solo/ab9bab2c-5d86-43e7-bac2-c1d68fc91342/huntress-summary?orgId=1&from=1706799780600&to=1709391780600&panelId=10'
],
description="List of URLs to generate screenshots for",
)

class Base64Image(BaseModel):
base64_image: str
url: str

class GenerateReportResponse(BaseModel):
base64_images: List[Base64Image]
message: str
success: bool
58 changes: 58 additions & 0 deletions backend/app/connectors/grafana/services/reporting.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

from fastapi import HTTPException
from loguru import logger
from playwright.async_api import async_playwright
from loguru import logger
import base64
from sqlalchemy.ext.asyncio import AsyncSession
from app.connectors.grafana.schema.reporting import GenerateReportRequest, GenerateReportResponse, Base64Image
from app.utils import get_connector_attribute

from app.connectors.grafana.schema.reporting import GrafanaDashboardDetails
from app.connectors.grafana.schema.reporting import GrafanaOrganizationDashboards
Expand Down Expand Up @@ -71,3 +77,55 @@ async def get_dashboard_details(dashboard_uid: str) -> GrafanaDashboardDetails:
except Exception as e:
logger.error(f"Failed to collect dashboard details: {e}")
raise HTTPException(status_code=500, detail=f"Failed to collect dashboard details: {e}")

async def login_to_page(page, session: AsyncSession):
# Navigate to the login page
await page.goto(f'{await get_connector_attribute(connector_id=12, column_name="connector_url", session=session)}/login')
# Enter the username and password
await page.fill('input[name="user"]', f'{await get_connector_attribute(connector_id=12, column_name="connector_username", session=session)}')
await page.fill('input[name="password"]', f'{await get_connector_attribute(connector_id=12, column_name="connector_password", session=session)}')
# Click the login button
await page.click('button[data-testid="data-testid Login button"]')
# Wait for navigation to complete
await page.wait_for_load_state(state='networkidle')

async def check_login_success(page):
# Check if login was successful by checking for an element that is only visible when logged in
body_class = await page.evaluate('document.body.className')
if 'app-grafana no-overlay-scrollbar page-dashboard' in body_class:
print("Login successful")
return True
else:
print("Login failed")
return False

async def capture_screenshots(page, urls):
base64_images = []
for url in urls:
await page.goto(url)
await page.wait_for_load_state(state='networkidle')
screenshot = await page.screenshot(type='png')
base64_image = base64.b64encode(screenshot).decode('utf-8')
base64_images.append({"url": url, "base64_image": base64_image})
return base64_images

async def generate_report(
request: GenerateReportRequest,
session: AsyncSession
):
logger.info("Generating report")
async with async_playwright() as p:
browser = await p.chromium.launch(headless=False)
context = await browser.new_context(ignore_https_errors=True)
page = await context.new_page()
await login_to_page(page, session)
if not await check_login_success(page):
await browser.close()
return
base64_images = await capture_screenshots(page, request.urls)
await browser.close()
return GenerateReportResponse(
base64_images=[Base64Image(url=img['url'], base64_image=img['base64_image']) for img in base64_images],
message="Report generated successfully",
success=True
)
31 changes: 0 additions & 31 deletions backend/app/reporting/routes/reporting.py

This file was deleted.

23 changes: 0 additions & 23 deletions backend/app/reporting/schema/reporting.py

This file was deleted.

60 changes: 0 additions & 60 deletions backend/app/reporting/testing.py

This file was deleted.

13 changes: 0 additions & 13 deletions backend/app/routers/reporting.py

This file was deleted.

2 changes: 0 additions & 2 deletions backend/copilot.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
from app.routers import velociraptor
from app.routers import wazuh_indexer
from app.routers import wazuh_manager
from app.routers import reporting
from app.routers import license
from app.schedulers.scheduler import init_scheduler

Expand Down Expand Up @@ -126,7 +125,6 @@
api_router.include_router(active_response.router)
api_router.include_router(huntress.router)
api_router.include_router(license.router)
api_router.include_router(reporting.router)

# Include the APIRouter in the FastAPI app
app.include_router(api_router)
Expand Down

0 comments on commit 9daa23a

Please sign in to comment.