Skip to content

Commit d60815a

Browse files
committed
Add host-info and create-user functions
1 parent 729f630 commit d60815a

File tree

11 files changed

+183
-7
lines changed

11 files changed

+183
-7
lines changed

functions/host-info/main.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from falconfoundry import FoundryFunction, FoundryRequest, FoundryResponse, FoundryAPIError
2+
# The following two lines are necessary to import utils
3+
import sys
4+
sys.path.append('../')
5+
from utils import validate_host_id, format_error_response
6+
from logging import Logger
7+
from typing import Dict
8+
9+
10+
func = FoundryFunction.instance()
11+
12+
# Handler on_post
13+
@func.handler(method='POST', path='/host-info')
14+
def on_post(request: FoundryRequest, config: Dict[str, object] | None, logger: Logger) -> FoundryResponse:
15+
host_id = request.body.get('host_id')
16+
17+
logger.info(f"Host ID: {host_id}")
18+
logger.info(f"Is valid? {validate_host_id(host_id)}")
19+
20+
if not validate_host_id(host_id):
21+
return FoundryResponse(errors=format_error_response("Invalid host ID format"))
22+
23+
return FoundryResponse(
24+
code=200,
25+
body={
26+
"host":host_id
27+
}
28+
)
29+
30+
31+
if __name__ == '__main__':
32+
func.run()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"properties": {
4+
"name": {
5+
"type": "string"
6+
}
7+
},
8+
"required": [
9+
"host_id"
10+
],
11+
"type": "object"
12+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
crowdstrike-falcon-foundry==1.0.0
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"properties": {
4+
"host": {
5+
"type": "string"
6+
}
7+
},
8+
"type": "object"
9+
}

functions/servicenow/main.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
from falconfoundry import FoundryFunction, FoundryRequest, FoundryResponse, FoundryAPIError
22
from falconpy import APIIntegrations
3-
import logging
3+
from logging import Logger
4+
from typing import Dict
45

56

67
func = FoundryFunction.instance()
78

8-
# This configuration for logging will only work when running locally
9-
# See the Add Logging section below for how to log to NG-SIEM
10-
logger = logging.getLogger()
11-
logger.setLevel(logging.INFO)
12-
139
@func.handler(method='POST', path='/ticket')
14-
def on_post(request: FoundryRequest) -> FoundryResponse:
10+
def on_post(request: FoundryRequest, config: Dict[str, object] | None, logger: Logger) -> FoundryResponse:
1511
"""
1612
Create an incident ticket in ServiceNow using the Table API.
1713

functions/user-management/main.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from falconfoundry import FoundryFunction, FoundryRequest, FoundryResponse, FoundryAPIError
2+
# The following two lines are necessary to import utils
3+
import sys
4+
sys.path.append('../')
5+
from utils import validate_email, format_error_response
6+
from logging import Logger
7+
from typing import Dict
8+
9+
10+
func = FoundryFunction.instance()
11+
12+
# Handler on_post
13+
@func.handler(method='POST', path='/create-user')
14+
def on_post(request: FoundryRequest, config: Dict[str, object] | None, logger: Logger) -> FoundryResponse:
15+
email = request.body.get('email')
16+
17+
logger.info(f"Email: {email}")
18+
logger.info(f"Is valid? {validate_email(email)}")
19+
20+
if not validate_email(email):
21+
return FoundryResponse(errors=format_error_response("Invalid email format"))
22+
23+
return FoundryResponse(
24+
code=200,
25+
body={
26+
"email":email
27+
}
28+
)
29+
30+
31+
if __name__ == '__main__':
32+
func.run()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"properties": {
4+
"email": {
5+
"type": "string"
6+
}
7+
},
8+
"required": [
9+
"email"
10+
],
11+
"type": "object"
12+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
crowdstrike-falcon-foundry==1.0.0
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"properties": {
4+
"email": {
5+
"type": "string"
6+
}
7+
},
8+
"type": "object"
9+
}

functions/utils.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import re
2+
import json
3+
from typing import Dict, Any, Optional, Union, List
4+
from falconfoundry import FoundryAPIError
5+
6+
def validate_host_id(host_id: str) -> bool:
7+
"""Validate that a host ID is in the correct format."""
8+
if not host_id or not isinstance(host_id, str):
9+
return False
10+
return len(host_id) == 32 and all(c in '0123456789abcdef' for c in host_id.lower())
11+
12+
def validate_email(email: str) -> bool:
13+
"""Validate email format."""
14+
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
15+
return bool(re.match(pattern, email))
16+
17+
def format_error_response(message: str, code: int = 400) -> list[Any]:
18+
"""Create a standardized error response."""
19+
return [FoundryAPIError(code=code, message=message)]
20+
21+
def safe_json_parse(data: str) -> Optional[Dict[str, Any]]:
22+
"""Safely parse JSON data."""
23+
try:
24+
return json.loads(data)
25+
except (json.JSONDecodeError, TypeError):
26+
return None

0 commit comments

Comments
 (0)