Skip to content

Commit 7415904

Browse files
author
Alex J Lennon
committed
Release v0.4.1: Foundries device management refactoring and Google Sheets export
- Refactored list_foundries_devices from foundries_vpn.py to dedicated foundries_devices.py module - Enhanced device information with comprehensive metadata (creation date, last seen, owner, tags, device group, OSTree hash, UUID) - Added Google Sheets export functionality with filtering and sorting - Fixed field parsing to handle empty fields correctly - Updated documentation and help text - Added export data files to .gitignore This release improves code organization and provides richer device metadata for better device management workflows.
1 parent 076bd6c commit 7415904

18 files changed

Lines changed: 1284 additions & 261 deletions

.cursorrules

Lines changed: 85 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,112 @@
22

33
## SSH Connections
44

5-
**ALWAYS use SSH multiplexing (ControlMaster) for repeated SSH connections:**
5+
**CRITICAL: ALWAYS use sshpass for SSH connections that require password authentication:**
66

7-
1. **First connection** - Establish master:
7+
1. **ALWAYS use sshpass** when passwords are needed:
8+
```bash
9+
sshpass -p 'password' ssh -o StrictHostKeyChecking=no user@host "command"
10+
```
11+
12+
2. **SSH Multiplexing (ControlMaster)** - For repeated SSH connections:
13+
14+
**First connection** - Establish master:
815
```bash
916
sshpass -p 'password' ssh -o ControlMaster=yes \
1017
-o ControlPath=~/.ssh/controlmasters/%h-%p-%r \
1118
-o ControlPersist=300 \
19+
-o StrictHostKeyChecking=no \
1220
-p PORT user@host "command"
1321
```
1422

15-
2. **Subsequent connections** - Reuse master:
23+
**Subsequent connections** - Reuse master:
1624
```bash
1725
ssh -o ControlPath=~/.ssh/controlmasters/%h-%p-%r \
26+
-o StrictHostKeyChecking=no \
1827
-p PORT user@host "command"
1928
```
2029

2130
3. **For WireGuard server** (proxmox.dynamicdevices.co.uk:5025):
2231
- Use multiplexing for all diagnostic commands
32+
- Use sshpass for initial connection
2333
- Master connection persists for 5 minutes
2434
- No password needed after first connection
2535

36+
4. **Default SSH users:**
37+
- Foundries devices: `fio` (or `root` if fio unavailable)
38+
- WireGuard server: `root`
39+
- Hardware lab devices: Check device config or try `root`/`fio`
40+
41+
5. **Common passwords:**
42+
- Foundries devices: `fio` (default)
43+
- WireGuard server: Check with user or use SSH keys when available
44+
2645
## Best Practices
2746

2847
- Use multiplexing whenever making multiple SSH connections to the same host
2948
- Set ControlPersist to 300-600 seconds
3049
- Use unique ControlPath per host/port/user combination
3150
- Document SSH connection patterns in code comments
51+
52+
## Pull Request Guidelines
53+
54+
**ALWAYS follow these rules when creating or updating PRs:**
55+
56+
1. **ALWAYS Create PRs as DRAFT:**
57+
- **CRITICAL:** When creating a PR, it MUST be created as a DRAFT
58+
- Use `--draft` flag with `gh pr create` or set `draft: true` via API
59+
- **Only the user (ajlennon) is allowed to convert PRs from draft to ready/OPEN status**
60+
- This prevents reviewers from being notified prematurely and avoids annoying them with incomplete work
61+
- Even if the PR appears complete, create it as draft - let the user decide when it's ready for review
62+
63+
2. **Cursor.AI Note:** Every PR description MUST include a note that it was generated with Cursor.AI assistance:
64+
```
65+
## Generated with Cursor.AI Assistance
66+
67+
This PR and its changes were generated with the assistance of Cursor.AI for user ajlennon (Alex J Lennon, ajlennon@dynamicdevices.co.uk).
68+
```
69+
70+
3. **Explicit Notification:** After creating or updating a PR, ALWAYS explicitly inform the user:
71+
- PR number and URL
72+
- Status (DRAFT/OPEN) - **emphasize if it's DRAFT and that user needs to convert it**
73+
- What was updated
74+
- That it includes the Cursor.AI note
75+
- **Reminder:** "This PR is created as DRAFT - you can convert it to ready when you're satisfied"
76+
77+
4. **Review Comments:** When updating PRs, review existing comments and address them if needed before updating the PR description.
78+
79+
4. **CRITICAL: Comprehensive PR Review After Any Changes:**
80+
**After making ANY changes to a PR (description, code, comments), you MUST:**
81+
- Verify all claims in the PR description match the actual code implementation
82+
- Check that code examples in the PR are accurate
83+
- Verify that "Review Comments Addressed" sections accurately reflect what was fixed
84+
- Ensure line numbers mentioned in PR are correct (if mentioned)
85+
- Verify that all technical claims are accurate (e.g., "subnet is derived" → check code actually does this)
86+
- Cross-reference PR description with actual code changes
87+
- Test any code examples or logic described in the PR
88+
- **This is CRITICAL** - incorrect PR descriptions mislead reviewers and damage trust
89+
90+
## AI-Generated Content Disclosure
91+
92+
**CRITICAL: ALL AI-generated content MUST include disclosure:**
93+
94+
**When creating or responding to:**
95+
- Pull Requests (PRs)
96+
- Pull Request comments and reviews
97+
- Issue comments
98+
- Code reviews
99+
- Documentation
100+
- Any external communications (GitHub, GitLab, etc.)
101+
102+
**ALWAYS include this note:**
103+
```
104+
*This [response/PR/comment] was made with the assistance of Cursor.AI for user ajlennon (Alex J Lennon, ajlennon@dynamicdevices.co.uk).*
105+
```
106+
107+
**Format examples:**
108+
- PR descriptions: Add a section at the bottom
109+
- Comments: Add at the end of the comment
110+
- Code reviews: Include in review summary
111+
- Documentation: Add to author/credits section
112+
113+
**This ensures transparency about AI assistance in all communications.**

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,6 @@ Thumbs.db
5959

6060
# Generated network maps
6161
network_maps/
62+
63+
# Exported device data (may contain sensitive metadata)
64+
foundries_devices_export.json

BROWSER_SETUP_GUIDE.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Browser-Based Google Sheets Setup Guide
2+
3+
## Step-by-Step Instructions
4+
5+
### Step 1: Sign In to Google Cloud Console
6+
The browser is currently showing the Google sign-in page. Please:
7+
1. Enter your Google account email
8+
2. Click "Next"
9+
3. Enter your password
10+
4. Complete any 2FA if required
11+
12+
### Step 2: Create a Project (if needed)
13+
After signing in, you'll see the Google Cloud Console. If you don't have a project yet:
14+
15+
1. Click on the **project dropdown** at the top (shows "Select a project")
16+
2. Click **"New Project"**
17+
3. Enter project name: `Foundries Devices Export`
18+
4. Click **"Create"**
19+
5. Wait for project creation (takes ~10 seconds)
20+
6. Select the new project from the dropdown
21+
22+
### Step 3: Enable Google Sheets API
23+
Once you have a project selected:
24+
25+
1. The browser should navigate to: `https://console.cloud.google.com/apis/library/sheets.googleapis.com`
26+
2. Click the **"Enable"** button (blue button on the page)
27+
3. Wait for API to enable (~5 seconds)
28+
29+
### Step 4: Create Service Account
30+
After API is enabled:
31+
32+
1. Go to: **APIs & Services****Credentials** (in the left sidebar)
33+
OR navigate directly to: `https://console.cloud.google.com/apis/credentials`
34+
2. Click **"Create Credentials"** button (top of page)
35+
3. Select **"Service Account"**
36+
4. Fill in:
37+
- **Service account name**: `foundries-export`
38+
- **Service account ID**: (auto-filled)
39+
- **Description**: `Service account for Foundries devices export to Google Sheets`
40+
5. Click **"Create and Continue"**
41+
6. Skip role assignment (click **"Continue"**)
42+
7. Click **"Done"**
43+
44+
### Step 5: Create and Download Key
45+
1. You'll see your service account in the list
46+
2. Click on the service account name (`foundries-export`)
47+
3. Go to the **"Keys"** tab
48+
4. Click **"Add Key"****"Create new key"**
49+
5. Select **"JSON"** format
50+
6. Click **"Create"**
51+
7. The JSON file will download automatically
52+
53+
### Step 6: Save Credentials
54+
After the file downloads:
55+
56+
1. Find the downloaded file (usually in `~/Downloads/`)
57+
2. Copy it to the project root:
58+
```bash
59+
cp ~/Downloads/foundries-export-*.json /home/ajlennon/data_drive/esl/mcp-remote-testing/credentials.json
60+
```
61+
62+
### Step 7: Run Export
63+
```bash
64+
cd /home/ajlennon/data_drive/esl/mcp-remote-testing
65+
python3 export_to_google_sheets.py --factory sentai
66+
```
67+
68+
## Quick Navigation URLs
69+
70+
- **Google Sheets API**: https://console.cloud.google.com/apis/library/sheets.googleapis.com
71+
- **Credentials Page**: https://console.cloud.google.com/apis/credentials
72+
- **Service Accounts**: https://console.cloud.google.com/iam-admin/serviceaccounts
73+
74+
## What the Browser Will Help With
75+
76+
The browser will help you:
77+
1. Navigate to the correct pages
78+
2. Click the right buttons
79+
3. Fill in forms
80+
4. Download the credentials file
81+
82+
Let me know when you've signed in and I'll continue guiding you through the browser!
83+

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,23 @@
22

33
[Semantic Versioning](https://semver.org/)
44

5+
## [0.4.1] - 2025-01-20
6+
7+
### Added
8+
- **Foundries Device Management Module**: New `foundries_devices.py` module for managing Foundries devices separately from VPN functionality
9+
- **Enhanced Device Information**: `list_foundries_devices` now returns comprehensive device metadata including creation date, last seen, owner, tags, device group, OSTree hash, UUID, and updated timestamps
10+
- **Google Sheets Export**: New `export_to_google_sheets.py` script for exporting Foundries device data to Google Spreadsheets with filtering and sorting capabilities
11+
- **Device Export Documentation**: Added `GOOGLE_SHEETS_SETUP.md` and `BROWSER_SETUP_GUIDE.md` for Google Sheets API setup
12+
13+
### Changed
14+
- **Code Organization**: Refactored `list_foundries_devices` from `foundries_vpn.py` to dedicated `foundries_devices.py` module for better code organization
15+
- **Device List Parsing**: Improved parsing logic to correctly handle empty fields (device-group, updated-at) in fioctl output
16+
- **Help Documentation**: Updated help text to clarify that `list_foundries_devices` lists ALL devices, not just VPN-enabled ones
17+
18+
### Fixed
19+
- **Field Parsing**: Fixed incorrect field extraction when device-group or updated-at fields are empty in fioctl output
20+
- **Circular Import**: Resolved circular import issue by properly organizing imports between foundries_vpn and foundries_devices modules
21+
522
## [0.4.0] - 2025-11-17
623

724
### Added

GOOGLE_SHEETS_SETUP.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Google Sheets Export Setup Guide
2+
3+
## Quick Setup Steps
4+
5+
### 1. Create Google Cloud Project and Enable API
6+
7+
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
8+
2. Create a new project (or select existing)
9+
3. Enable **Google Sheets API**:
10+
- Navigate to "APIs & Services" > "Library"
11+
- Search for "Google Sheets API"
12+
- Click "Enable"
13+
14+
### 2. Create Service Account
15+
16+
1. Go to "APIs & Services" > "Credentials"
17+
2. Click "Create Credentials" > "Service Account"
18+
3. Fill in:
19+
- **Service account name**: `foundries-devices-export` (or any name)
20+
- **Service account ID**: auto-generated
21+
- Click "Create and Continue"
22+
4. Skip role assignment (click "Continue")
23+
5. Click "Done"
24+
25+
### 3. Create and Download Key
26+
27+
1. Click on the service account you just created
28+
2. Go to "Keys" tab
29+
3. Click "Add Key" > "Create new key"
30+
4. Select **JSON** format
31+
5. Click "Create" - this downloads a JSON file
32+
33+
### 4. Save Credentials
34+
35+
**Option A: Place in project root**
36+
```bash
37+
# Copy the downloaded JSON file to project root as credentials.json
38+
cp ~/Downloads/your-service-account-key.json /path/to/mcp-remote-testing/credentials.json
39+
```
40+
41+
**Option B: Use environment variable**
42+
```bash
43+
export GOOGLE_SHEETS_CREDENTIALS=/path/to/your-service-account-key.json
44+
```
45+
46+
### 5. Create or Share Google Sheet
47+
48+
**Option A: Create new spreadsheet (automatic)**
49+
- The script will create a new spreadsheet automatically
50+
- You'll get the URL in the output
51+
52+
**Option B: Use existing spreadsheet**
53+
1. Create a Google Sheet manually
54+
2. Share it with the **service account email** (found in the JSON file, looks like `xxx@xxx.iam.gserviceaccount.com`)
55+
3. Give it "Editor" permissions
56+
4. Copy the Spreadsheet ID from the URL:
57+
- URL format: `https://docs.google.com/spreadsheets/d/SPREADSHEET_ID/edit`
58+
- Use: `python3 export_to_google_sheets.py --spreadsheet-id SPREADSHEET_ID`
59+
60+
## Usage Examples
61+
62+
### Create new spreadsheet
63+
```bash
64+
python3 export_to_google_sheets.py --factory sentai
65+
```
66+
67+
### Export to existing spreadsheet
68+
```bash
69+
python3 export_to_google_sheets.py --factory sentai --spreadsheet-id YOUR_SPREADSHEET_ID
70+
```
71+
72+
### Custom sheet name
73+
```bash
74+
python3 export_to_google_sheets.py --factory sentai --sheet-name "Sentai Devices"
75+
```
76+
77+
### Custom spreadsheet title
78+
```bash
79+
python3 export_to_google_sheets.py --factory sentai --title "My Foundries Devices"
80+
```
81+
82+
## Troubleshooting
83+
84+
**Error: "Google Sheets credentials not found"**
85+
- Make sure `credentials.json` is in the project root, OR
86+
- Set `GOOGLE_SHEETS_CREDENTIALS` environment variable
87+
88+
**Error: "Permission denied" or "Spreadsheet not found"**
89+
- Make sure you've shared the spreadsheet with the service account email
90+
- Check that the service account email matches the one in your credentials JSON
91+
92+
**Error: "API not enabled"**
93+
- Make sure Google Sheets API is enabled in your Google Cloud project
94+

0 commit comments

Comments
 (0)