implemetion the office365 create meta entry (#459)
taylor_socfortress committed
Jun 18, 2025 at 14:35 UTC
df582dcef9b988750190385b577f90a17a17bf89
3 files changed
+52
-58
backend/app/connectors/shuffle/routes/organizations.py
+8
-30
@@ -22,9 +22,7 @@ auth_handler = AuthHandler()
22
description="Retrieve all organizations from Shuffle",
23
dependencies=[Depends(auth_handler.require_any_scope("admin", "analyst"))],
24
)
25
-async def list_organizations(
26
- connector_name: str = Query("Shuffle", description="Name of the Shuffle connector to use")
27
-):
25
+async def list_organizations(connector_name: str = Query("Shuffle", description="Name of the Shuffle connector to use")):
26
"""
27
Retrieve all organizations from Shuffle.
28
@@ -44,10 +42,7 @@ async def list_organizations(
42
raise
43
except Exception as e:
44
logger.error(f"Unexpected error in list_organizations endpoint: {e}")
47
- raise HTTPException(
48
- status_code=500,
49
- detail=f"Internal server error: {str(e)}"
50
- )
45
+ raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
46
47
48
@shuffle_organizations_router.get(
@@ -56,10 +51,7 @@ async def list_organizations(
51
description="Retrieve a specific organization by ID",
52
dependencies=[Depends(auth_handler.require_any_scope("admin", "analyst"))],
53
)
59
-async def get_organization_by_id(
60
- org_id: str,
61
- connector_name: str = Query("Shuffle", description="Name of the Shuffle connector to use")
62
-):
54
+async def get_organization_by_id(org_id: str, connector_name: str = Query("Shuffle", description="Name of the Shuffle connector to use")):
55
"""
56
Retrieve a specific organization by ID.
57
@@ -74,19 +66,12 @@ async def get_organization_by_id(
66
67
try:
68
organization = await OrganizationsService.get_organization_by_id(org_id, connector_name)
77
- return OrganizationResponse(
78
- success=True,
79
- message=f"Successfully retrieved organization: {organization.name}",
80
- data=organization
81
- )
69
+ return OrganizationResponse(success=True, message=f"Successfully retrieved organization: {organization.name}", data=organization)
70
except HTTPException:
71
raise
72
except Exception as e:
73
logger.error(f"Unexpected error in get_organization_by_id endpoint: {e}")
86
- raise HTTPException(
87
- status_code=500,
88
- detail=f"Internal server error: {str(e)}"
89
- )
74
+ raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
75
76
77
@shuffle_organizations_router.get(
@@ -97,7 +82,7 @@ async def get_organization_by_id(
82
)
83
async def get_organization_by_name(
84
org_name: str,
100
- connector_name: str = Query("Shuffle", description="Name of the Shuffle connector to use")
85
+ connector_name: str = Query("Shuffle", description="Name of the Shuffle connector to use"),
86
):
87
"""
88
Retrieve a specific organization by name.
@@ -113,16 +98,9 @@ async def get_organization_by_name(
98
99
try:
100
organization = await OrganizationsService.get_organization_by_name(org_name, connector_name)
116
- return OrganizationResponse(
117
- success=True,
118
- message=f"Successfully retrieved organization: {organization.name}",
119
- data=organization
120
- )
101
+ return OrganizationResponse(success=True, message=f"Successfully retrieved organization: {organization.name}", data=organization)
102
except HTTPException:
103
raise
104
except Exception as e:
105
logger.error(f"Unexpected error in get_organization_by_name endpoint: {e}")
125
- raise HTTPException(
126
- status_code=500,
127
- detail=f"Internal server error: {str(e)}"
128
- )
106
+ raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
backend/app/connectors/shuffle/services/organizations.py
+7
-28
@@ -1,6 +1,3 @@
1
-from typing import Dict
2
-from typing import List
3
-
1
from fastapi import HTTPException
2
from loguru import logger
3
@@ -27,27 +24,18 @@ class OrganizationsService:
24
25
try:
26
# Send GET request to Shuffle API
30
- response = await send_get_request(
31
- endpoint="/api/v1/orgs",
32
- connector_name=connector_name
33
- )
27
+ response = await send_get_request(endpoint="/api/v1/orgs", connector_name=connector_name)
28
29
if not response.get("success", False):
30
logger.error(f"Failed to fetch organizations: {response.get('message', 'Unknown error')}")
37
- raise HTTPException(
38
- status_code=500,
39
- detail=f"Failed to fetch organizations: {response.get('message', 'Unknown error')}"
40
- )
31
+ raise HTTPException(status_code=500, detail=f"Failed to fetch organizations: {response.get('message', 'Unknown error')}")
32
33
# Parse the response data
34
organizations_data = response.get("data", [])
35
36
if not isinstance(organizations_data, list):
37
logger.error("Invalid response format: expected list of organizations")
47
- raise HTTPException(
48
- status_code=500,
49
- detail="Invalid response format from Shuffle API"
50
- )
38
+ raise HTTPException(status_code=500, detail="Invalid response format from Shuffle API")
39
40
# Convert to Organization models
41
organizations = []
@@ -65,7 +53,7 @@ class OrganizationsService:
53
success=True,
54
message=f"Successfully retrieved {len(organizations)} organizations",
55
data=organizations,
68
- total_count=len(organizations)
56
+ total_count=len(organizations),
57
)
58
59
except HTTPException:
@@ -73,10 +61,7 @@ class OrganizationsService:
61
raise
62
except Exception as e:
63
logger.error(f"Unexpected error while fetching organizations: {e}")
76
- raise HTTPException(
77
- status_code=500,
78
- detail=f"Unexpected error while fetching organizations: {str(e)}"
79
- )
64
+ raise HTTPException(status_code=500, detail=f"Unexpected error while fetching organizations: {str(e)}")
65
66
@staticmethod
67
async def get_organization_by_id(org_id: str, connector_name: str = "Shuffle") -> Organization:
@@ -101,10 +86,7 @@ class OrganizationsService:
86
return org
87
88
logger.error(f"Organization with ID {org_id} not found")
104
- raise HTTPException(
105
- status_code=404,
106
- detail=f"Organization with ID {org_id} not found"
107
- )
89
+ raise HTTPException(status_code=404, detail=f"Organization with ID {org_id} not found")
90
91
@staticmethod
92
async def get_organization_by_name(org_name: str, connector_name: str = "Shuffle") -> Organization:
@@ -129,7 +111,4 @@ class OrganizationsService:
111
return org
112
113
logger.error(f"Organization with name '{org_name}' not found")
132
- raise HTTPException(
133
- status_code=404,
134
- detail=f"Organization with name '{org_name}' not found"
135
- )
114
+ raise HTTPException(status_code=404, detail=f"Organization with name '{org_name}' not found")
backend/app/integrations/office365/services/provision.py
+37
@@ -55,6 +55,8 @@ from app.integrations.office365.schema.provision import PipelineRuleTitles
55
from app.integrations.office365.schema.provision import PipelineTitles
56
from app.integrations.office365.schema.provision import ProvisionOffice365AuthKeys
57
from app.integrations.office365.schema.provision import ProvisionOffice365Response
58
+from app.integrations.routes import create_integration_meta
59
+from app.integrations.schema import CustomerIntegrationsMetaSchema
60
from app.utils import get_connector_attribute
61
from app.utils import get_customer_default_settings_attribute
62
@@ -953,6 +955,24 @@ async def provision_office365(
955
await update_customer_integration_table(customer_code, session)
956
await update_customermeta_table(customer_code, session, provision_office365_auth_keys.TENANT_ID)
957
958
+ await create_integration_meta_entry(
959
+ CustomerIntegrationsMetaSchema(
960
+ customer_code=customer_code,
961
+ integration_name="Office365",
962
+ graylog_input_id=None,
963
+ graylog_index_id=index_set_id,
964
+ graylog_stream_id=stream_id,
965
+ grafana_org_id=(
966
+ await get_customer_meta(
967
+ customer_code,
968
+ session,
969
+ )
970
+ ).customer_meta.customer_meta_grafana_org_id,
971
+ grafana_dashboard_folder_id=grafana_o365_folder_id,
972
+ ),
973
+ session,
974
+ )
975
+
976
return ProvisionOffice365Response(
977
success=True,
978
message=f"Successfully provisioned Office365 integration for customer {customer_code}.",
@@ -1001,3 +1021,20 @@ async def update_customermeta_table(customer_code: str, session: AsyncSession, t
1021
await session.commit()
1022
1023
return None
1024
+
1025
+
1026
+async def create_integration_meta_entry(
1027
+ customer_integration_meta: CustomerIntegrationsMetaSchema,
1028
+ session: AsyncSession,
1029
+) -> None:
1030
+ """
1031
+ Creates an entry for the customer integration meta in the database.
1032
+
1033
+ Args:
1034
+ customer_integration_meta (CustomerIntegrationsMetaSchema): The customer integration meta object.
1035
+ session (AsyncSession): The async session object for database operations.
1036
+ """
1037
+ await create_integration_meta(customer_integration_meta, session)
1038
+ logger.info(
1039
+ f"Integration meta entry created for customer {customer_integration_meta.customer_code}.",
1040
+ )