main
py 942 lines 36.6 KB
Raw
1 from typing import List
2 from typing import Optional
3
4 from fastapi import APIRouter
5 from fastapi import Depends
6 from fastapi import HTTPException
7 from fastapi import Security
8 from loguru import logger
9 from sqlalchemy import delete
10 from sqlalchemy import update
11 from sqlalchemy.exc import NoResultFound
12 from sqlalchemy.ext.asyncio import AsyncSession
13 from sqlalchemy.future import select
14 from sqlalchemy.orm import joinedload
15
16 from app.auth.utils import AuthHandler
17 from app.db.db_session import get_db
18 from app.db.universal_models import Customers
19 from app.db.universal_models import CustomersMeta
20 from app.integrations.alert_creation_settings.models.alert_creation_settings import (
21 AlertCreationSettings,
22 )
23 from app.network_connectors.models.network_connectors import AvailableNetworkConnectors
24 from app.network_connectors.models.network_connectors import CustomerNetworkConnectors
25 from app.network_connectors.models.network_connectors import (
26 CustomerNetworkConnectorsMeta,
27 )
28 from app.network_connectors.models.network_connectors import NetworkConnectorsConfig
29 from app.network_connectors.models.network_connectors import NetworkConnectorsKeys
30 from app.network_connectors.models.network_connectors import NetworkConnectorsService
31 from app.network_connectors.models.network_connectors import (
32 NetworkConnectorsSubscription,
33 )
34 from app.network_connectors.schema import AuthKey
35 from app.network_connectors.schema import AvailableNetworkConnectorsResponse
36 from app.network_connectors.schema import CreateNetworkConnectorsAuthKeys
37 from app.network_connectors.schema import CreateNetworkConnectorsService
38 from app.network_connectors.schema import CustomerNetworkConnectorsCreate
39 from app.network_connectors.schema import CustomerNetworkConnectorsCreateResponse
40 from app.network_connectors.schema import CustomerNetworkConnectorsDeleteResponse
41 from app.network_connectors.schema import CustomerNetworkConnectorsMetaResponse
42 from app.network_connectors.schema import CustomerNetworkConnectorsMetaSchema
43 from app.network_connectors.schema import CustomerNetworkConnectorsResponse
44 from app.network_connectors.schema import DeleteCustomerNetworkConnectors
45 from app.network_connectors.schema import NetworkConnectorsWithAuthKeys
46 from app.network_connectors.schema import UpdateCustomerNetworkConnectors
47
48 network_connector_settings_router = APIRouter()
49
50
51 async def fetch_available_network_connectors(session: AsyncSession):
52 """
53 Fetches available network_connectors and their auth keys from the database.
54
55 Args:
56 session (AsyncSession): The database session.
57
58 Returns:
59 List[NetworkConnectorsWithAuthKeys]: A list of available network_connectors with their auth keys.
60 """
61 stmt = select(AvailableNetworkConnectors).options(
62 joinedload(AvailableNetworkConnectors.network_connector_keys),
63 )
64 result = await session.execute(stmt)
65
66 # Use unique() to avoid duplicates caused by joined eager loading
67 unique_network_connectors = result.unique().scalars().all()
68
69 network_connectors_with_auth_keys = []
70 for network_connector in unique_network_connectors:
71 auth_keys = [AuthKey(auth_key_name=key.auth_key_name) for key in network_connector.network_connector_keys]
72 network_connector_data = NetworkConnectorsWithAuthKeys(
73 id=network_connector.id,
74 network_connector_name=network_connector.network_connector_name,
75 description=network_connector.description,
76 network_connector_details=network_connector.network_connector_details,
77 network_connector_keys=auth_keys,
78 )
79 network_connectors_with_auth_keys.append(network_connector_data)
80
81 return network_connectors_with_auth_keys
82
83
84 async def validate_network_connector_name(network_connector_name: str, session: AsyncSession):
85 """
86 Validate if the network_connector name exists in available network_connectors.
87 """
88 available_network_connectors = await fetch_available_network_connectors(session)
89 if network_connector_name not in [ai.network_connector_name for ai in available_network_connectors]:
90 raise HTTPException(
91 status_code=400,
92 detail=f"NetworkConnectors {network_connector_name} is not a valid network_connector.",
93 )
94
95
96 async def validate_network_connector_auth_keys(
97 network_connector_name: str,
98 network_connector_auth_keys: List[AuthKey],
99 session: AsyncSession,
100 ):
101 """
102 Validate if the network_connector auth keys are valid.
103 """
104 available_network_connectors = await fetch_available_network_connectors(session)
105 network_connector = [ai for ai in available_network_connectors if ai.network_connector_name == network_connector_name][0]
106 available_auth_keys = [ak.auth_key_name for ak in network_connector.network_connector_keys]
107 # loop through the `available_auth_keys` and check if the `network_connector_auth_keys` contains the `auth_key_name`
108 for auth_key in available_auth_keys:
109 if auth_key not in [iak.auth_key_name for iak in network_connector_auth_keys]:
110 raise HTTPException(
111 status_code=400,
112 detail=f"NetworkConnectors auth key {auth_key} does not exist.",
113 )
114
115
116 async def validate_network_connector_auth_key_update(
117 network_connector_name: str,
118 network_connector_auth_key: List[AuthKey],
119 session: AsyncSession,
120 ):
121 """
122 Validate if the network_connector auth key is valid.
123 """
124 logger.info(f"network_connector_auth_key: {network_connector_auth_key}")
125 available_network_connectors = await fetch_available_network_connectors(session)
126 network_connector = [ai for ai in available_network_connectors if ai.network_connector_name == network_connector_name][0]
127 available_auth_keys = [ak.auth_key_name for ak in network_connector.auth_keys]
128 for auth_key in network_connector_auth_key:
129 if auth_key.auth_key_name not in available_auth_keys:
130 raise HTTPException(
131 status_code=400,
132 detail=f"NetworkConnectors auth key {auth_key.auth_key_name} does not exist.",
133 )
134
135
136 async def validate_customer_code(customer_code: str, session: AsyncSession):
137 """
138 Validate if the customer code exists in the customers table.
139 """
140 stmt = select(Customers).where(Customers.customer_code == customer_code)
141 result = await session.execute(stmt)
142 if result.scalars().first() is None:
143 raise HTTPException(
144 status_code=400,
145 detail=f"Customer {customer_code} does not exist.",
146 )
147
148
149 async def validate_customer_meta(customer_code: str, session: AsyncSession):
150 """
151 Validate if the customer code exists in the customers_meta table.
152 """
153 stmt = select(CustomersMeta).where(CustomersMeta.customer_code == customer_code)
154 result = await session.execute(stmt)
155 if result.scalars().first() is None:
156 raise HTTPException(
157 status_code=400,
158 detail=f"Customer {customer_code} meta does not exist. Please provision the customer before creating an network_connector.",
159 )
160
161
162 async def check_existing_customer_network_connector(
163 customer_code: str,
164 network_connector_name: str,
165 session: AsyncSession,
166 ):
167 """
168 Check if the customer network_connector already exists.
169 """
170 # Assuming NetworkConnectorsService has an 'network_connector_name' field or similar
171 stmt = (
172 select(CustomerNetworkConnectors)
173 .join(CustomerNetworkConnectors.network_connectors_subscriptions)
174 .join(NetworkConnectorsSubscription.network_connectors_service)
175 .where(
176 CustomerNetworkConnectors.customer_code == customer_code,
177 NetworkConnectorsService.service_name == network_connector_name,
178 )
179 )
180 result = await session.execute(stmt)
181 if result.scalars().first() is not None:
182 raise HTTPException(
183 status_code=400,
184 detail=f"Customer network_connector {customer_code} {network_connector_name} already exists.",
185 )
186
187
188 async def check_existing_customer_network_connector_meta(
189 customer_code: str,
190 network_connector_name: str,
191 session: AsyncSession,
192 ):
193 """
194 Check if the customer network_connector meta already exists for the customer code and network_connector name.
195 """
196 stmt = select(CustomerNetworkConnectorsMeta).where(
197 CustomerNetworkConnectorsMeta.customer_code == customer_code,
198 CustomerNetworkConnectorsMeta.network_connector_name == network_connector_name,
199 )
200 result = await session.execute(stmt)
201 if result.scalars().first() is not None:
202 raise HTTPException(
203 status_code=400,
204 detail=f"Customer network_connector meta {customer_code} {network_connector_name} already exists.",
205 )
206
207
208 async def create_network_connector_service(
209 network_connector_name: str,
210 settings: CreateNetworkConnectorsService,
211 session: AsyncSession,
212 ) -> NetworkConnectorsService:
213 """
214 Create or fetch NetworkConnectorsService instance with custom configuration.
215 """
216 network_connector_service = NetworkConnectorsService(
217 service_name=network_connector_name,
218 auth_type=settings.auth_type,
219 configs=[
220 NetworkConnectorsConfig(
221 config_key=settings.config_key,
222 config_value=settings.config_value,
223 ),
224 ],
225 )
226 session.add(network_connector_service)
227 await session.flush()
228 return network_connector_service
229
230
231 async def create_customer_network_connectors(
232 customer_code: str,
233 customer_name: str,
234 network_connector_service_id: int,
235 network_connector_service_name: str,
236 session: AsyncSession,
237 ) -> CustomerNetworkConnectors:
238 """
239 Create CustomerNetworkConnectors instance.
240 """
241 customer_network_connectors = CustomerNetworkConnectors(
242 customer_code=customer_code,
243 customer_name=customer_name,
244 network_connector_service_id=network_connector_service_id,
245 network_connector_service_name=network_connector_service_name,
246 deployed=False,
247 )
248 session.add(customer_network_connectors)
249 await session.flush()
250 return customer_network_connectors
251
252
253 async def create_network_connector_subscription(
254 customer_network_connectors: CustomerNetworkConnectors,
255 network_connector_service: NetworkConnectorsService,
256 network_connector_auth_keys: List[CreateNetworkConnectorsAuthKeys],
257 session: AsyncSession,
258 ):
259 """
260 Create NetworkConnectorsSubscription instance.
261 """
262 for auth_key in network_connector_auth_keys:
263 new_network_connector_subscription = NetworkConnectorsSubscription(
264 customer_network_connectors=customer_network_connectors,
265 network_connectors_service=network_connector_service,
266 network_connectors_keys=[
267 NetworkConnectorsKeys(
268 auth_key_name=auth_key.auth_key_name,
269 auth_value=auth_key.auth_value,
270 ),
271 ],
272 )
273 session.add(new_network_connector_subscription)
274 await session.commit()
275
276
277 async def get_customer_and_service_ids(session, customer_code, network_connector_name):
278 try:
279 result = await session.execute(
280 select(CustomerNetworkConnectors.id, NetworkConnectorsService.id)
281 .join(
282 NetworkConnectorsSubscription,
283 CustomerNetworkConnectors.id == NetworkConnectorsSubscription.customer_id,
284 )
285 .join(
286 NetworkConnectorsService,
287 NetworkConnectorsSubscription.network_connectors_service_id == NetworkConnectorsService.id,
288 )
289 .where(
290 CustomerNetworkConnectors.customer_code == customer_code,
291 NetworkConnectorsService.service_name == network_connector_name,
292 ),
293 )
294 return result.all()
295 except NoResultFound:
296 raise HTTPException(status_code=404, detail="Customer network_connector not found")
297
298
299 async def get_subscription_ids(session, customer_id, network_connector_service_id):
300 result = await session.execute(
301 select(NetworkConnectorsSubscription.id).where(
302 NetworkConnectorsSubscription.customer_id == customer_id,
303 NetworkConnectorsSubscription.network_connectors_service_id == network_connector_service_id,
304 ),
305 )
306 # Fetch all results
307 subscription_ids_raw = result.scalars().all()
308
309 # Process the results
310 # If the result is a list of tuples (even with one element), extract the first element
311 if subscription_ids_raw and isinstance(subscription_ids_raw[0], tuple):
312 return [id_tuple[0] for id_tuple in subscription_ids_raw]
313 # If the result is a list of integers
314 elif subscription_ids_raw and isinstance(subscription_ids_raw[0], int):
315 return subscription_ids_raw
316 # If there are no results
317 else:
318 return []
319
320
321 async def delete_metadata(session, subscription_ids):
322 await session.execute(
323 delete(NetworkConnectorsKeys).where(
324 NetworkConnectorsKeys.subscription_id.in_(subscription_ids),
325 ),
326 )
327
328
329 async def delete_subscriptions(session, subscription_ids):
330 await session.execute(
331 delete(NetworkConnectorsSubscription).where(
332 NetworkConnectorsSubscription.id.in_(subscription_ids),
333 ),
334 )
335
336
337 async def delete_configs(session, network_connector_service_id):
338 await session.execute(
339 delete(NetworkConnectorsConfig).where(
340 NetworkConnectorsConfig.network_connector_service_id == network_connector_service_id,
341 ),
342 )
343
344
345 async def delete_network_connector_service(session, network_connector_service_id):
346 await session.execute(
347 delete(NetworkConnectorsService).where(
348 NetworkConnectorsService.id == network_connector_service_id,
349 ),
350 )
351
352
353 async def delete_customer_network_connector_record(session, customer_id):
354 await session.execute(
355 delete(CustomerNetworkConnectors).where(CustomerNetworkConnectors.id == customer_id),
356 )
357
358
359 async def find_customer_network_connector(
360 customer_code: str,
361 network_connector_name: str,
362 customer_network_connector_response,
363 ) -> Optional[CustomerNetworkConnectors]:
364 for ci in customer_network_connector_response.available_network_connectors:
365 for subscription in ci.network_connectors_subscriptions:
366 if subscription.network_connectors_service.service_name == network_connector_name:
367 return ci
368 return None
369
370
371 def get_subscription_id(
372 customer_network_connector,
373 network_connector_name: str,
374 auth_key_name: str,
375 ) -> Optional[int]:
376 logger.info(f"Getting subscription id for {network_connector_name} {auth_key_name}")
377 for subscription in customer_network_connector.network_connectors_subscriptions:
378 if subscription.network_connectors_service.service_name == network_connector_name:
379 for auth_key in subscription.network_connector_keys:
380 if auth_key.auth_key_name == auth_key_name:
381 return subscription.id
382 return None
383
384
385 async def get_tenant_id(
386 customer_network_connector: CustomerNetworkConnectorsCreate,
387 session: AsyncSession,
388 ) -> str:
389 """
390 Retrieves the Tenant ID for a given customer network_connector. This is the Office365 organization ID and
391 is used to create alerts for the customer in DFIR-IRIS.
392 """
393 stmt = (
394 select(NetworkConnectorsKeys)
395 .join(
396 NetworkConnectorsSubscription,
397 NetworkConnectorsKeys.subscription_id == NetworkConnectorsSubscription.id,
398 )
399 .join(
400 CustomerNetworkConnectors,
401 NetworkConnectorsSubscription.customer_id == CustomerNetworkConnectors.id,
402 )
403 .join(
404 NetworkConnectorsService,
405 NetworkConnectorsSubscription.network_connector_service_id == NetworkConnectorsService.id,
406 )
407 .where(
408 CustomerNetworkConnectors.customer_code == customer_network_connector.customer_code,
409 NetworkConnectorsService.service_name == customer_network_connector.network_connector_name,
410 NetworkConnectorsKeys.auth_key_name == "TENANT_ID",
411 )
412 )
413
414 result = await session.execute(stmt)
415 tenant_id = result.scalars().first()
416 if tenant_id is None:
417 raise HTTPException(
418 status_code=404,
419 detail=f"Tenant ID for customer {customer_network_connector.customer_code} not found.",
420 )
421 logger.info(f"tenant_id: {tenant_id.auth_value}")
422 return tenant_id.auth_value
423
424
425 async def update_office365_organization_id(
426 customer_code: str,
427 tenant_id: str,
428 session: AsyncSession,
429 ):
430 """
431 Updates the Office365 organization ID in the alert_creation_settings table.
432 """
433 stmt = (
434 update(AlertCreationSettings)
435 .where(AlertCreationSettings.customer_code == customer_code)
436 .values(office365_organization_id=tenant_id)
437 )
438 await session.execute(stmt)
439 await session.commit()
440
441
442 async def get_network_connector_service_id(
443 network_connector_name: str,
444 session: AsyncSession,
445 ) -> int:
446 """
447 Retrieves the AvailableNetworkConnectorss ID for a given network_connector name.
448 """
449 stmt = select(AvailableNetworkConnectors).where(
450 AvailableNetworkConnectors.network_connector_name == network_connector_name,
451 )
452 result = await session.execute(stmt)
453 network_connector_service = result.scalars().first()
454 if network_connector_service is None:
455 raise HTTPException(
456 status_code=404,
457 detail=f"NetworkConnectors service {network_connector_name} not found.",
458 )
459 return network_connector_service.id
460
461
462 async def get_network_connector_service_name(
463 network_connector_name: str,
464 session: AsyncSession,
465 ) -> str:
466 """
467 Retrieves the AvailableNetworkConnectors ID for a given network_connector name.
468 """
469 stmt = select(AvailableNetworkConnectors).where(
470 AvailableNetworkConnectors.network_connector_name == network_connector_name,
471 )
472 result = await session.execute(stmt)
473 network_connector_service = result.scalars().first()
474 if network_connector_service is None:
475 raise HTTPException(
476 status_code=404,
477 detail=f"NetworkConnectors service {network_connector_name} not found.",
478 )
479 return network_connector_service.network_connector_name
480
481
482 async def fetch_customer_network_connectors_data(session: AsyncSession):
483 """
484 Fetches customer network_connectors data from the database.
485 """
486 stmt = select(CustomerNetworkConnectors).options(
487 joinedload(CustomerNetworkConnectors.network_connectors_subscriptions).joinedload(
488 NetworkConnectorsSubscription.network_connectors_service,
489 ),
490 joinedload(CustomerNetworkConnectors.network_connectors_subscriptions).subqueryload(
491 NetworkConnectorsSubscription.network_connectors_keys,
492 ),
493 )
494 result = await session.execute(stmt)
495 return result.scalars().unique().all()
496
497
498 def process_customer_network_connectors(customer_network_connectors_data):
499 """
500 Processes customer network_connectors data and returns a list of CustomerNetworkConnectors objects.
501 """
502 processed_customer_network_connectors = []
503 for ci in customer_network_connectors_data:
504 first_service_id = (
505 ci.network_connectors_subscriptions[0].network_connectors_service_id if ci.network_connectors_subscriptions else None
506 )
507 customer_network_connector_obj = CustomerNetworkConnectors(
508 id=ci.id,
509 customer_code=ci.customer_code,
510 customer_name=ci.customer_name,
511 network_connectors_subscriptions=ci.network_connectors_subscriptions,
512 network_connector_service_id=first_service_id,
513 network_connector_service_name=ci.network_connectors_subscriptions[0].network_connectors_service.service_name
514 if ci.network_connectors_subscriptions
515 else None,
516 deployed=ci.deployed,
517 )
518 processed_customer_network_connectors.append(customer_network_connector_obj)
519 return processed_customer_network_connectors
520
521
522 @network_connector_settings_router.get(
523 "/available_network_connectors",
524 response_model=AvailableNetworkConnectorsResponse,
525 description="Get a list of available network_connectors.",
526 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
527 )
528 async def get_available_network_connectors(
529 session: AsyncSession = Depends(get_db),
530 ):
531 """
532 Endpoint to get a list of available network_connectors.
533 """
534 available_network_connectors = await fetch_available_network_connectors(session)
535 return AvailableNetworkConnectorsResponse(
536 network_connector_keys=available_network_connectors,
537 message="Available network_connectors successfully retrieved.",
538 success=True,
539 )
540
541
542 @network_connector_settings_router.get(
543 "/customer_network_connectors",
544 response_model=CustomerNetworkConnectorsResponse,
545 description="Get a list of customer network_connectors.",
546 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
547 )
548 async def get_customer_network_connectors(session: AsyncSession = Depends(get_db)):
549 """
550 Endpoint to get a list of customer network_connectors.
551 """
552 customer_network_connectors_data = await fetch_customer_network_connectors_data(session)
553 processed_customer_network_connectors = process_customer_network_connectors(
554 customer_network_connectors_data,
555 )
556
557 return CustomerNetworkConnectorsResponse(
558 available_network_connectors=processed_customer_network_connectors,
559 message="Customer network_connectors successfully retrieved.",
560 success=True,
561 )
562
563
564 @network_connector_settings_router.get(
565 "/customer_network_connectors_meta",
566 response_model=CustomerNetworkConnectorsMetaResponse,
567 description="Get a list of customer network_connectors metadata.",
568 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
569 )
570 async def get_customer_network_connectors_meta(session: AsyncSession = Depends(get_db)):
571 """
572 Endpoint to get a list of customer network_connectors metadata.
573 """
574 try:
575 stmt = select(CustomerNetworkConnectorsMeta)
576 result = await session.execute(stmt)
577 customer_network_connectors_meta = result.scalars().all()
578 except Exception as e:
579 logger.error(f"Error while fetching customer network_connectors metadata: {e}")
580 customer_network_connectors_meta = []
581
582 logger.info(f"customer_network_connectors_meta: {customer_network_connectors_meta}")
583 return CustomerNetworkConnectorsMetaResponse(
584 customer_network_connectors_meta=customer_network_connectors_meta,
585 message="Customer network_connectors metadata successfully retrieved.",
586 success=True,
587 )
588
589
590 @network_connector_settings_router.get(
591 "/customer_network_connectors/{customer_code}",
592 response_model=CustomerNetworkConnectorsResponse,
593 description="Get a list of customer network_connectors for a specific customer.",
594 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
595 )
596 async def get_customer_network_connectors_by_customer_code(
597 customer_code: str,
598 session: AsyncSession = Depends(get_db),
599 ):
600 """
601 Endpoint to get a list of customer network_connectors for a specific customer.
602 """
603 stmt = (
604 select(CustomerNetworkConnectors)
605 .options(
606 joinedload(CustomerNetworkConnectors.network_connectors_subscriptions).joinedload(
607 NetworkConnectorsSubscription.network_connectors_service,
608 ),
609 joinedload(CustomerNetworkConnectors.network_connectors_subscriptions).subqueryload(
610 NetworkConnectorsSubscription.network_connectors_keys,
611 ),
612 )
613 .where(CustomerNetworkConnectors.customer_code == customer_code)
614 )
615 result = await session.execute(stmt)
616 customer_network_connectors = result.scalars().unique().all()
617 return CustomerNetworkConnectorsResponse(
618 available_network_connectors=customer_network_connectors,
619 message="Customer network_connectors successfully retrieved.",
620 success=True,
621 )
622
623
624 @network_connector_settings_router.get(
625 "/customer_network_connectors_meta/{customer_code}",
626 response_model=CustomerNetworkConnectorsMetaResponse,
627 description="Get a list of customer network_connectors metadata for a specific customer.",
628 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
629 )
630 async def get_customer_network_connectors_meta_by_customer_code(
631 customer_code: str,
632 session: AsyncSession = Depends(get_db),
633 ):
634 """
635 Endpoint to get a list of customer network_connectors metadata for a specific customer.
636 """
637 stmt = select(CustomerNetworkConnectorsMeta).where(
638 CustomerNetworkConnectorsMeta.customer_code == customer_code,
639 )
640 result = await session.execute(stmt)
641 customer_network_connectors_meta = result.scalars().all()
642 logger.info(f"customer_network_connectors_meta: {customer_network_connectors_meta}")
643 return CustomerNetworkConnectorsMetaResponse(
644 customer_network_connectors_meta=customer_network_connectors_meta,
645 message="Customer network_connectors metadata successfully retrieved.",
646 success=True,
647 )
648
649
650 @network_connector_settings_router.post(
651 "/create_network_connector",
652 response_model=CustomerNetworkConnectorsCreateResponse,
653 description="Create a new customer network_connector.",
654 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
655 )
656 async def create_network_connector(
657 customer_network_connector_create: CustomerNetworkConnectorsCreate,
658 session: AsyncSession = Depends(get_db),
659 ):
660 """
661 Endpoint to create a new customer network_connector.
662 """
663 await validate_network_connector_name(
664 customer_network_connector_create.network_connector_name,
665 session,
666 )
667 await validate_network_connector_auth_keys(
668 customer_network_connector_create.network_connector_name,
669 customer_network_connector_create.network_connector_auth_keys,
670 session,
671 )
672 await validate_customer_code(customer_network_connector_create.customer_code, session)
673 await validate_customer_meta(customer_network_connector_create.customer_code, session)
674 await check_existing_customer_network_connector(
675 customer_network_connector_create.customer_code,
676 customer_network_connector_create.network_connector_name,
677 session,
678 )
679 network_connector_service_id = await get_network_connector_service_id(
680 customer_network_connector_create.network_connector_name,
681 session,
682 )
683 network_connector_service_name = await get_network_connector_service_name(
684 customer_network_connector_create.network_connector_name,
685 session,
686 )
687
688 network_connector_service = await create_network_connector_service(
689 customer_network_connector_create.network_connector_name,
690 settings=customer_network_connector_create.network_connector_config,
691 session=session,
692 )
693 customer_network_connectors = await create_customer_network_connectors(
694 customer_network_connector_create.customer_code,
695 customer_network_connector_create.customer_name,
696 network_connector_service_id=network_connector_service_id,
697 network_connector_service_name=network_connector_service_name,
698 session=session,
699 )
700 logger.info("Getting customer network_connector auth keys for subscription creation.")
701 logger.info(f"Customer Network Connectors: {customer_network_connectors}")
702 await create_network_connector_subscription(
703 customer_network_connectors,
704 network_connector_service,
705 network_connector_auth_keys=customer_network_connector_create.network_connector_auth_keys,
706 session=session,
707 )
708
709 return CustomerNetworkConnectorsCreateResponse(
710 message=f"Customer network_connector {customer_network_connector_create.customer_code} {customer_network_connector_create.network_connector_name} successfully created.",
711 success=True,
712 )
713
714
715 @network_connector_settings_router.post(
716 "/create_network_connector_meta",
717 response_model=CustomerNetworkConnectorsMetaResponse,
718 description="Create a new customer network_connector metadata.",
719 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
720 )
721 async def create_network_connector_meta(
722 customer_network_connector_meta: CustomerNetworkConnectorsMetaSchema,
723 session: AsyncSession = Depends(get_db),
724 ):
725 """
726 Endpoint to create a new customer network_connector metadata.
727 """
728 await validate_customer_code(customer_network_connector_meta.customer_code, session)
729 await validate_customer_meta(customer_network_connector_meta.customer_code, session)
730 await check_existing_customer_network_connector_meta(
731 customer_network_connector_meta.customer_code,
732 customer_network_connector_meta.network_connector_name,
733 session,
734 )
735 try:
736 new_customer_network_connector_meta = CustomerNetworkConnectorsMeta(
737 **customer_network_connector_meta.model_dump(),
738 )
739 session.add(new_customer_network_connector_meta)
740 await session.commit()
741 return CustomerNetworkConnectorsMetaResponse(
742 message="Customer network_connector metadata successfully created.",
743 success=True,
744 )
745 except Exception as e:
746 logger.error(f"Error while creating customer network_connector metadata: {e}")
747 return CustomerNetworkConnectorsMetaResponse(
748 customer_network_connectors_meta=None,
749 message="Error while creating customer network_connector metadata.",
750 success=False,
751 )
752
753
754 @network_connector_settings_router.put(
755 "/update_network_connector/{customer_code}",
756 response_model=CustomerNetworkConnectorsCreateResponse,
757 description="Update a customer network_connector.",
758 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
759 )
760 async def update_network_connector(
761 customer_code: str,
762 customer_network_connector_update: UpdateCustomerNetworkConnectors,
763 session: AsyncSession = Depends(get_db),
764 ):
765 await validate_network_connector_name(
766 customer_network_connector_update.network_connector_name,
767 session,
768 )
769 customer_network_connector_response = await get_customer_network_connectors_by_customer_code(
770 customer_code,
771 session,
772 )
773
774 if not customer_network_connector_response:
775 raise HTTPException(status_code=404, detail="Customer network_connectors not found")
776
777 customer_network_connector = await find_customer_network_connector(
778 customer_code,
779 customer_network_connector_update.network_connector_name,
780 customer_network_connector_response,
781 )
782
783 if not customer_network_connector:
784 raise HTTPException(
785 status_code=404,
786 detail="Customer network_connector with specified service name not found.",
787 )
788
789 await validate_network_connector_auth_key_update(
790 customer_network_connector_update.network_connector_name,
791 customer_network_connector_update.network_connector_auth_keys,
792 session,
793 )
794
795 subscription_id = get_subscription_id(
796 customer_network_connector,
797 customer_network_connector_update.network_connector_name,
798 customer_network_connector_update.network_connector_auth_keys[0].auth_key_name,
799 )
800
801 if not subscription_id:
802 raise HTTPException(
803 status_code=404,
804 detail=f"NetworkConnectors auth key {customer_network_connector_update.network_connector_auth_keys[0].auth_key_name} not found.",
805 )
806
807 await session.execute(
808 update(NetworkConnectorsKeys)
809 .where(NetworkConnectorsKeys.subscription_id == subscription_id)
810 .values(
811 auth_value=customer_network_connector_update.network_connector_auth_keys[0].auth_value,
812 ),
813 )
814
815 await session.commit()
816
817 return CustomerNetworkConnectorsCreateResponse(
818 message=f"Customer network_connector {customer_code} {customer_network_connector_update.network_connector_name} successfully updated.",
819 success=True,
820 )
821
822
823 @network_connector_settings_router.put(
824 "/available_network_connectors",
825 response_model=AvailableNetworkConnectorsResponse,
826 description="Update an available network_connector.",
827 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
828 )
829 async def update_available_network_connectors(
830 available_network_connectors: List[AvailableNetworkConnectors],
831 session: AsyncSession = Depends(get_db),
832 ):
833 """
834 Endpoint to update an available network_connector.
835 """
836 for network_connector in available_network_connectors:
837 stmt = select(AvailableNetworkConnectors).where(
838 AvailableNetworkConnectors.network_connector_name == network_connector.network_connector_name,
839 )
840 result = await session.execute(stmt)
841 existing_network_connector = result.scalars().first()
842
843 if existing_network_connector is None:
844 raise HTTPException(
845 status_code=404,
846 detail=f"NetworkConnectors {network_connector.network_connector_name} not found.",
847 )
848
849 existing_network_connector.description = network_connector.description
850 existing_network_connector.network_connector_details = network_connector.network_connector_details
851
852 await session.commit()
853
854 return AvailableNetworkConnectorsResponse(
855 available_network_connectors=available_network_connectors,
856 message="Available network_connectors successfully updated.",
857 success=True,
858 )
859
860
861 @network_connector_settings_router.delete(
862 "/delete_network_connector",
863 response_model=CustomerNetworkConnectorsDeleteResponse,
864 description="Delete a customer network_connector.",
865 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
866 )
867 async def delete_network_connector(
868 delete_customer_network_connector: DeleteCustomerNetworkConnectors,
869 session: AsyncSession = Depends(get_db),
870 ):
871 customer_code = delete_customer_network_connector.customer_code
872 network_connector_name = delete_customer_network_connector.network_connector_name
873
874 results = await get_customer_and_service_ids(
875 session,
876 customer_code,
877 network_connector_name,
878 )
879 # Check if results is not empty
880 if results:
881 # Unpack the first tuple in results
882 customer_id, network_connector_service_id = results[0]
883 else:
884 # Handle the case where results is empty
885 raise HTTPException(status_code=404, detail="Customer network_connector not found")
886
887 subscription_ids = await get_subscription_ids(
888 session,
889 customer_id,
890 network_connector_service_id,
891 )
892 if not subscription_ids:
893 raise HTTPException(
894 status_code=404,
895 detail="No subscriptions found for customer network_connector",
896 )
897
898 await delete_metadata(session, subscription_ids)
899 await delete_subscriptions(session, subscription_ids)
900 await delete_configs(session, network_connector_service_id)
901 await delete_network_connector_service(session, network_connector_service_id)
902 await delete_customer_network_connector_record(session, customer_id)
903
904 await session.commit()
905
906 return CustomerNetworkConnectorsDeleteResponse(
907 message=f"Customer network_connector {customer_code} {network_connector_name} successfully deleted.",
908 success=True,
909 )
910
911
912 @network_connector_settings_router.delete(
913 "/delete_network_connector_meta",
914 response_model=CustomerNetworkConnectorsMetaResponse,
915 description="Delete a customer network_connector metadata.",
916 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
917 )
918 async def delete_network_connector_meta(
919 customer_network_connector_meta: CustomerNetworkConnectorsMetaSchema,
920 session: AsyncSession = Depends(get_db),
921 ):
922 """
923 Endpoint to delete a customer network_connector metadata.
924 """
925 try:
926 stmt = delete(CustomerNetworkConnectorsMeta).where(
927 CustomerNetworkConnectorsMeta.customer_code == customer_network_connector_meta.customer_code,
928 CustomerNetworkConnectorsMeta.network_connector_name == customer_network_connector_meta.network_connector_name,
929 )
930 await session.execute(stmt)
931 await session.commit()
932 return CustomerNetworkConnectorsMetaResponse(
933 message="Customer network_connector metadata successfully deleted.",
934 success=True,
935 )
936 except Exception as e:
937 logger.error(f"Error while deleting customer network_connector metadata: {e}")
938 return CustomerNetworkConnectorsMetaResponse(
939 customer_network_connectors_meta=None,
940 message="Error while deleting customer network_connector metadata.",
941 success=False,
942 )