Skip to content

Commit

Permalink
Allow setting the hostname and authN mechanism through a .env file
Browse files Browse the repository at this point in the history
  • Loading branch information
ddl-s-rodriguez committed Oct 24, 2024
1 parent 0eb05a2 commit 0227465
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 17 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.DS_Store
.vscode/
aux/
.env
audit_trail_export_*.csv
36 changes: 30 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,22 @@ The output is a CSV file containing all the events that matched the query

## Usage

The script requires the `--hostname` parameter to be passed and either a `--jwt` or `--api-key` for authentication. It also accepts optional parameters such as an event name and user information.
The script requires a `Hostname` and either a `JWT` or an `API-Key` for authentication. They can be provided as arguments or can be defined in a `.env` file to be loaded

Example of the .env file
```
HOSTNAME=<A-DOMINO-INSTANCE>
JWT=<A-JWT>
API_KEY=<AN-API-KEY>
```

It also accepts optional parameters such as an event name and user information.

## Arguments

| Argument | Required | Description |
|------------------|----------|------------------------------------------------------------------------|
| `--hostname` | Yes | The hostname to connect to. |
| `--hostname` | Yes* | The hostname to connect to. |
| `--jwt` | Yes* | The JWT token for authentication. |
| `--api-key` | Yes* | The Domino API key for authentication. |
| `--event` | No | The event name. |
Expand All @@ -34,24 +43,39 @@ The script requires the `--hostname` parameter to be passed and either a `--jwt`
python3 export_audit_trail.py --hostname https://domino_instance.com --jwt my-jwt-token
```

### Example 2: Using API key for authentication and specifying an event
### Example 2: Providing the hostname and authentication through the .env file and exporting all available data

`.env` definition
```
HOSTNAME=<A-DOMINO-INSTANCE>
JWT=<A-JWT>
```

Calling the script
```bash
python3 export_audit_trail.py
```

### Example 3: Using API key for authentication and specifying an event
```bash
python3 export_audit_trail.py --hostname https://domino_instance.com --api-key my-api-key --event "Create Dataset"
```

### Example 3: Providing parameters to filter the export data
### Example 4: Providing parameters to filter the export data
```bash
python3 export_audit_trail.py --hostname https://domino_instance.com --jwt my-jwt-token --user_name "Alice" --event "Create Dataset"
```

### Example 4: Providing start and end timestamps
### Example 5: Providing start and end timestamps
```bash
python3 export_audit_trail.py --hostname https://domino_instance.com --jwt my-jwt-token --start_date "2024-10-18 14:10:04" --end_date "2024-10-22 09:04:33"
```

### Notes
* The script runs on Python 3 (Python 2 is not supported)
* If neither --jwt nor --api-key is provided, the script will display an error and exit.
* The hostname and authentication (jwt or api-key) can be defined in an .env file instead of being sent as arguments
* If no hostname is defined, the script will display an error and exit.
* If no authentication mechanism (jwt or api-key) is provided, the script will display an error and exit.
* You can combine optional parameters to customize the behavior and context of the export action.
* Events are exported in time descending order
* The Date & Time of the events is displayed in UTC
50 changes: 39 additions & 11 deletions export_audit_trail.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import argparse
import csv
from datetime import datetime, UTC, timezone
from datetime import datetime, timezone
import os
import requests
import sys

#################### AUXILIARY VARIABLES ####################

ENV_FILE = ".env"
HOSTNAME_ENV = "HOSTNAME"
JWT_ENV = "JWT"
API_KEY_ENV = "API_KEY"

AUDIT_TRAIL_PATH = "api/audittrail/v1/auditevents"
BATCH_LIMIT = 1000

CSV_BASE_FILENAME=f"audit_trail_export_{datetime.now().strftime("%Y-%m-%d:%H-%M-%S")}.csv"
CSV_BASE_FILENAME=f"audit_trail_export_{datetime.now().strftime('%Y-%m-%d:%H-%M-%S')}.csv"

# HEADERS
UTC_TIMESTAMP = "DATE & TIME (UTC)"
Expand Down Expand Up @@ -50,12 +57,17 @@
def main():
parser = argparse.ArgumentParser(description="Script that exports Audit trail events")

# Required parameter
parser.add_argument('--hostname', required=True, help="Hostname (required)")

# Optional parameters
parser.add_argument('--jwt', help="JWT token")
parser.add_argument('--api-key', help="API-Key")
parser.add_argument('--hostname',
help="Hostname. Can be defined in an .env file as HOSTNAME=your-hostname",
default=os.environ.get(HOSTNAME_ENV))
parser.add_argument('--jwt',
help="JWT token. Can be defined in an .env file as JWT=your-jwt",
default=os.environ.get(JWT_ENV))
parser.add_argument('--api-key',
help="API-Key. Can be defined in an .env file as API_KEY=your-api-key",
default=os.environ.get(API_KEY_ENV))

# Arguments for the filters
parser.add_argument('--event', help="Event name")
parser.add_argument('--user_name', dest='actorName', help="User name that performed the action")
parser.add_argument('--target_name', dest='targetName', help="Object that received the action")
Expand All @@ -67,8 +79,8 @@ def main():

print("Exporting Audit trail events using the following arguments:")
print(f"- Hostname: {args.hostname}")
print(f"- JWT: {"*****" if args.jwt else '-'}")
print(f"- API Key: {"*****" if args.api_key else '-'}")
print(f"- JWT: {'*****' if args.jwt else '-'}")
print(f"- API Key: {'*****' if args.api_key else '-'}")
print(f"- Start Date & Time: {args.startTimestamp or '-'}")
print(f"- End Date & Time: {args.endTimestamp or '-'}")
print(f"- Event: {args.event or '-'}")
Expand All @@ -77,6 +89,10 @@ def main():
print(f"- Project Name: {args.withinProjectName or '-'}")

# Validations and clean-up
if not args.hostname:
print("Error: You must provide the hostname.")
sys.exit(1)

# Ensure either jwt or api-key is provided
if not args.jwt and not args.api_key:
print("Error: You must provide either a JWT token or an API key.")
Expand All @@ -100,6 +116,18 @@ def main():
export_audit_trail(args.hostname, request_headers, request_params)


def load_env_file():
try:
with open(ENV_FILE) as f:
# Use a generator to process lines and filter comments and empty lines
env_vars = (line.strip().split('=', 1) for line in f if line.strip() and not line.startswith('#'))
# Set environment variables
for key, value in env_vars:
os.environ[key] = value
except FileNotFoundError:
print(f"No {ENV_FILE} file found. Skipping loading environment variables")


def validate_and_format_timestamp(raw_timestamp):
try:
parsed_start_timestamp = datetime.strptime(raw_timestamp, "%Y-%m-%d %H:%M:%S")
Expand Down Expand Up @@ -196,7 +224,7 @@ def parse_event(raw_event):
COMMAND: None,
}

parsed_event[UTC_TIMESTAMP] = datetime.fromtimestamp(raw_event['timestamp'] / 1000, UTC).strftime('%Y-%m-%d %H:%M:%S')
parsed_event[UTC_TIMESTAMP] = datetime.fromtimestamp(raw_event['timestamp'] / 1000, timezone.utc).strftime('%Y-%m-%d %H:%M:%S')

actor_data = raw_event.get('actor', {})
parsed_event[USER_NAME] = actor_data.get('name', actor_data.get('id'))
Expand Down

0 comments on commit 0227465

Please sign in to comment.