remoteRF-server 0.1.58__tar.gz → 0.1.60__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/PKG-INFO +60 -2
  2. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/README.md +59 -1
  3. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/pyproject.toml +1 -1
  4. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/server/grpc_server.py +6 -1
  5. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/server/user_group_cli.py +135 -1
  6. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server.egg-info/PKG-INFO +60 -2
  7. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/setup.cfg +0 -0
  8. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/__init__.py +0 -0
  9. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/common/__init__.py +0 -0
  10. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/common/grpc/__init__.py +0 -0
  11. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/common/grpc/grpc_host_pb2.py +0 -0
  12. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/common/grpc/grpc_host_pb2_grpc.py +0 -0
  13. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/common/grpc/grpc_pb2.py +0 -0
  14. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/common/grpc/grpc_pb2_grpc.py +0 -0
  15. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/common/utils/__init__.py +0 -0
  16. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/common/utils/ansi_codes.py +0 -0
  17. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/common/utils/api_token.py +0 -0
  18. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/common/utils/db_connection.py +0 -0
  19. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/common/utils/db_location.py +0 -0
  20. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/common/utils/list_string.py +0 -0
  21. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/common/utils/process_arg.py +0 -0
  22. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/drivers/__init__.py +0 -0
  23. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/drivers/adalm_pluto/__init__.py +0 -0
  24. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/drivers/adalm_pluto/pluto_remote_server.py +0 -0
  25. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/host/__init__.py +0 -0
  26. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/host/host_directory_store.py +0 -0
  27. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/host/host_tunnel_server.py +0 -0
  28. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/server/__init__.py +0 -0
  29. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/server/acc_perms.py +0 -0
  30. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/server/cert_provider.py +0 -0
  31. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/server/device_manager.py +0 -0
  32. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/server/reservation.py +0 -0
  33. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/server/rpc_manager.py +0 -0
  34. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/server/user_group_handler.py +0 -0
  35. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/serverrf_cli.py +0 -0
  36. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/tools/__init__.py +0 -0
  37. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server/tools/gen_certs.py +0 -0
  38. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server.egg-info/SOURCES.txt +0 -0
  39. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server.egg-info/dependency_links.txt +0 -0
  40. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server.egg-info/entry_points.txt +0 -0
  41. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server.egg-info/requires.txt +0 -0
  42. {remoterf_server-0.1.58 → remoterf_server-0.1.60}/src/remoteRF_server.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: remoteRF-server
3
- Version: 0.1.58
3
+ Version: 0.1.60
4
4
  Description-Content-Type: text/markdown
5
5
  Requires-Dist: grpcio
6
6
  Requires-Dist: protobuf
@@ -281,10 +281,66 @@ Note that all device and server config parameters need a 'restart' to take affec
281
281
 
282
282
  ## Server Runtime Configuration
283
283
 
284
- After running 'serverrf --serve', you will have another set of configurations, including managing users and accounts, creating user groups, making registration codes, etc. Below will be a overview of said commands.
284
+ After running `serverrf --serve`, you’ll enter the **RemoteRF Server Shell**. This interactive shell is used for runtime administration: managing users, devices, reservations, user groups, and enrollment codes.
285
285
 
286
+ > Tip: Legacy commands (e.g. `show a`, `rm db`) may still work if enabled, but the commands below are the canonical interface.
286
287
 
288
+ ---
289
+
290
+ #### Server
291
+
292
+ * `help` / `?` — Show help
293
+ * `clear` — Clear the screen
294
+ * `status` — Show server status (uptime / bind info)
295
+ * `quit` / `exit` — Exit the server shell
296
+
297
+ ---
298
+
299
+ #### Users
300
+
301
+ * `users list` — List all accounts
302
+ * `users manage` — Manage a specific user (permissions / deletion / reservations) *(interactive)*
303
+ * `users purge` — Remove **all** users
304
+
305
+ ---
306
+
307
+ #### Devices
308
+
309
+ * `devices list` — List all devices
310
+
311
+ ---
312
+
313
+ #### Reservations
314
+
315
+ * `reservations list` — List all reservations
316
+ * `reservations purge` — Remove **all** reservations
287
317
 
318
+ ---
319
+
320
+ #### Groups
321
+
322
+ * `groups list` — List user groups
323
+ * `groups create` — Create a user group *(interactive)*
324
+ * `groups edit` — Edit a user group *(interactive)*
325
+ * `groups delete` — Delete a user group *(interactive)*
326
+
327
+ ---
328
+
329
+ #### Enrollment Codes
330
+
331
+ * `codes list` — List enrollment codes
332
+ * `codes create` — Create enrollment codes *(interactive)*
333
+ * `codes delete` — Delete an enrollment code *(interactive)*
334
+
335
+ ---
336
+
337
+ #### Database
338
+
339
+ * `db reset` — Remove all database entries
340
+
341
+ ---
342
+
343
+ ##
288
344
  todo:
289
345
  <!-- Adding plutos via the CLI -->
290
346
  <!-- Testing functionality (disregarding Host pipeline) -->
@@ -295,6 +351,8 @@ Ability to remotely manage groups and codes as admin.
295
351
 
296
352
  HostRF integration -> Host directory, device routing, dynamic reservation pulling, with activity/status (online, offline, etc.)
297
353
 
354
+ Cleanup code comments.
355
+
298
356
  Update Ian with installation demo (try myself first on the NUC once!) for both server and host.
299
357
 
300
358
 
@@ -270,10 +270,66 @@ Note that all device and server config parameters need a 'restart' to take affec
270
270
 
271
271
  ## Server Runtime Configuration
272
272
 
273
- After running 'serverrf --serve', you will have another set of configurations, including managing users and accounts, creating user groups, making registration codes, etc. Below will be a overview of said commands.
273
+ After running `serverrf --serve`, you’ll enter the **RemoteRF Server Shell**. This interactive shell is used for runtime administration: managing users, devices, reservations, user groups, and enrollment codes.
274
274
 
275
+ > Tip: Legacy commands (e.g. `show a`, `rm db`) may still work if enabled, but the commands below are the canonical interface.
275
276
 
277
+ ---
278
+
279
+ #### Server
280
+
281
+ * `help` / `?` — Show help
282
+ * `clear` — Clear the screen
283
+ * `status` — Show server status (uptime / bind info)
284
+ * `quit` / `exit` — Exit the server shell
285
+
286
+ ---
287
+
288
+ #### Users
289
+
290
+ * `users list` — List all accounts
291
+ * `users manage` — Manage a specific user (permissions / deletion / reservations) *(interactive)*
292
+ * `users purge` — Remove **all** users
293
+
294
+ ---
295
+
296
+ #### Devices
297
+
298
+ * `devices list` — List all devices
299
+
300
+ ---
301
+
302
+ #### Reservations
303
+
304
+ * `reservations list` — List all reservations
305
+ * `reservations purge` — Remove **all** reservations
276
306
 
307
+ ---
308
+
309
+ #### Groups
310
+
311
+ * `groups list` — List user groups
312
+ * `groups create` — Create a user group *(interactive)*
313
+ * `groups edit` — Edit a user group *(interactive)*
314
+ * `groups delete` — Delete a user group *(interactive)*
315
+
316
+ ---
317
+
318
+ #### Enrollment Codes
319
+
320
+ * `codes list` — List enrollment codes
321
+ * `codes create` — Create enrollment codes *(interactive)*
322
+ * `codes delete` — Delete an enrollment code *(interactive)*
323
+
324
+ ---
325
+
326
+ #### Database
327
+
328
+ * `db reset` — Remove all database entries
329
+
330
+ ---
331
+
332
+ ##
277
333
  todo:
278
334
  <!-- Adding plutos via the CLI -->
279
335
  <!-- Testing functionality (disregarding Host pipeline) -->
@@ -284,6 +340,8 @@ Ability to remotely manage groups and codes as admin.
284
340
 
285
341
  HostRF integration -> Host directory, device routing, dynamic reservation pulling, with activity/status (online, offline, etc.)
286
342
 
343
+ Cleanup code comments.
344
+
287
345
  Update Ian with installation demo (try myself first on the NUC once!) for both server and host.
288
346
 
289
347
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "remoteRF-server"
7
- version = "0.1.58"
7
+ version = "0.1.60"
8
8
  dependencies = [
9
9
  "grpcio",
10
10
  "protobuf",
@@ -28,7 +28,7 @@ from .rpc_manager import rpc_manager
28
28
  from .acc_perms import perms
29
29
  from ..common.utils import *
30
30
  from .device_manager import get_all_devices, get_all_devices_str
31
- from .user_group_cli import make_user_group_local, edit_user_group_local, list_user_groups_local, remove_user_group_local, make_enrollment_codes_local, remove_enrollment_code_local, list_enrollment_codes_local
31
+ from .user_group_cli import make_user_group_local, edit_user_group_local, list_user_groups_local, remove_user_group_local, make_enrollment_codes_local, remove_enrollment_code_local, list_enrollment_codes_local, export_user_groups_csv_local, export_enrollment_codes_csv_local
32
32
  from .user_group_handler import user_group_handler, start_usergroup_cleanup_loop
33
33
 
34
34
  from pathlib import Path
@@ -479,12 +479,14 @@ def help() -> None:
479
479
  printf(" groups create ", Sty.MAGENTA, "- Create a user group (interactive)", Sty.DEFAULT)
480
480
  printf(" groups edit ", Sty.MAGENTA, "- Edit a user group (interactive)", Sty.DEFAULT)
481
481
  printf(" groups delete ", Sty.MAGENTA, "- Delete a user group (interactive)", Sty.DEFAULT)
482
+ printf("'groups csv' ", Sty.MAGENTA, " - Export ALL user groups as CSV to Downloads", Sty.DEFAULT)
482
483
  print()
483
484
 
484
485
  printf("Enrollment Codes:", Sty.BOLD)
485
486
  printf(" codes list ", Sty.MAGENTA, "- List enrollment codes", Sty.DEFAULT)
486
487
  printf(" codes create ", Sty.MAGENTA, "- Create enrollment codes (interactive)", Sty.DEFAULT)
487
488
  printf(" codes delete ", Sty.MAGENTA, "- Delete an enrollment code (interactive)", Sty.DEFAULT)
489
+ printf("'codes csv' ", Sty.MAGENTA, " - Export ALL enrollment codes as CSV to Downloads", Sty.DEFAULT)
488
490
  print()
489
491
 
490
492
  printf("Database:", Sty.BOLD)
@@ -563,6 +565,7 @@ def server_input(inpu: str) -> bool:
563
565
  "groups list": lambda: _stay(lambda: list_user_groups_local(session)),
564
566
  "show g": lambda: _stay(lambda: list_user_groups_local(session)), # old
565
567
  "show groups": lambda: _stay(lambda: list_user_groups_local(session)), # old
568
+ "groups csv": lambda: _stay(export_user_groups_csv_local),
566
569
 
567
570
  # ---- enrollment codes ----
568
571
  "codes create": lambda: _stay(lambda: make_enrollment_codes_local(session)),
@@ -577,6 +580,8 @@ def server_input(inpu: str) -> bool:
577
580
  "rm codes": lambda: _stay(lambda: remove_enrollment_code_local(session)), # old
578
581
  "rm code": lambda: _stay(lambda: remove_enrollment_code_local(session)), # old
579
582
  "rm c": lambda: _stay(lambda: remove_enrollment_code_local(session)), # old
583
+
584
+ "codes csv": lambda: _stay(export_enrollment_codes_csv_local),
580
585
  }
581
586
 
582
587
  fn = DISPATCH.get(cmd)
@@ -1,5 +1,13 @@
1
1
  from __future__ import annotations
2
2
  from typing import Any, Dict, List, Optional
3
+ import csv
4
+ import json
5
+ import os
6
+ import re
7
+ from datetime import datetime
8
+ from pathlib import Path
9
+
10
+ from .user_group_handler import user_group_handler
3
11
 
4
12
  from .user_group_handler import user_group_handler
5
13
 
@@ -586,4 +594,130 @@ def list_enrollment_codes_local(session) -> None:
586
594
  print(header)
587
595
  print(sep)
588
596
  for row in table:
589
- print(" ".join(row[i].ljust(widths[cols[i]]) for i in range(len(cols))))
597
+ print(" ".join(row[i].ljust(widths[cols[i]]) for i in range(len(cols))))
598
+
599
+ def _resolve_download_dir() -> Path:
600
+ """
601
+ Best-effort Downloads folder resolution:
602
+ 1) XDG_DOWNLOAD_DIR env (if set)
603
+ 2) ~/.config/user-dirs.dirs XDG_DOWNLOAD_DIR (Linux desktops)
604
+ 3) ~/Downloads
605
+ 4) fallback: cwd
606
+ """
607
+ # 1) Env override (rare, but cheap to support)
608
+ xdg_env = os.getenv("XDG_DOWNLOAD_DIR")
609
+ if xdg_env:
610
+ p = Path(os.path.expandvars(xdg_env)).expanduser()
611
+ return p
612
+
613
+ # 2) user-dirs.dirs (common on Linux w/ xdg-user-dirs)
614
+ try:
615
+ user_dirs = Path.home() / ".config" / "user-dirs.dirs"
616
+ if user_dirs.exists():
617
+ txt = user_dirs.read_text(encoding="utf-8", errors="ignore")
618
+ m = re.search(r'^XDG_DOWNLOAD_DIR\s*=\s*"(.*)"\s*$', txt, flags=re.MULTILINE)
619
+ if m:
620
+ raw = m.group(1)
621
+ raw = raw.replace("$HOME", str(Path.home()))
622
+ p = Path(os.path.expandvars(raw)).expanduser()
623
+ return p
624
+ except Exception:
625
+ pass
626
+
627
+ # 3) Default
628
+ p = Path.home() / "Downloads"
629
+ return p
630
+
631
+
632
+ def _coerce_csv_cell(v: Any) -> str:
633
+ if v is None:
634
+ return ""
635
+ if isinstance(v, (dict, list, tuple)):
636
+ # stable, readable cell content
637
+ return json.dumps(v, ensure_ascii=False, separators=(",", ":"))
638
+ return str(v)
639
+
640
+
641
+ def _write_csv(
642
+ rows: List[Dict[str, Any]],
643
+ out_path: Path,
644
+ *,
645
+ preferred_columns: Optional[List[str]] = None,
646
+ ) -> None:
647
+ if not rows:
648
+ raise ValueError("No rows to write.")
649
+
650
+ preferred_columns = preferred_columns or []
651
+
652
+ present = set().union(*(r.keys() for r in rows))
653
+ columns = [c for c in preferred_columns if c in present]
654
+ columns += [c for c in sorted(present) if c not in columns]
655
+
656
+ out_path.parent.mkdir(parents=True, exist_ok=True)
657
+
658
+ with out_path.open("w", newline="", encoding="utf-8") as f:
659
+ w = csv.DictWriter(f, fieldnames=columns, extrasaction="ignore")
660
+ w.writeheader()
661
+ for r in rows:
662
+ w.writerow({c: _coerce_csv_cell(r.get(c)) for c in columns})
663
+
664
+
665
+ def export_user_groups_csv_local() -> Optional[Path]:
666
+ # include_users=True so CSV truly contains "everything"
667
+ groups: List[Dict[str, Any]] = user_group_handler.get_all_user_groups(include_users=True) or []
668
+ if not groups:
669
+ print("No user groups found.")
670
+ return None
671
+
672
+ ts = datetime.now().strftime("%Y%m%d_%H%M%S")
673
+ out_dir = _resolve_download_dir()
674
+ out_path = out_dir / f"remoterf_user_groups_{ts}.csv"
675
+
676
+ preferred = [
677
+ "group_id", "id",
678
+ "group_name", "name",
679
+ "devices_whitelist",
680
+ "max_reservation_time_sec",
681
+ "max_reservations",
682
+ "lifetime_sec",
683
+ "created_at",
684
+ "users",
685
+ ]
686
+
687
+ try:
688
+ _write_csv(groups, out_path, preferred_columns=preferred)
689
+ print(f"Exported user groups CSV -> {out_path}")
690
+ return out_path
691
+ except Exception as e:
692
+ print(f"Failed to export user groups CSV: {e}")
693
+ return None
694
+
695
+
696
+ def export_enrollment_codes_csv_local() -> Optional[Path]:
697
+ rows: List[Dict[str, Any]] = user_group_handler.get_all_enrollment_codes() or []
698
+ if not rows:
699
+ print("No enrollment codes found.")
700
+ return None
701
+
702
+ ts = datetime.now().strftime("%Y%m%d_%H%M%S")
703
+ out_dir = _resolve_download_dir()
704
+ out_path = out_dir / f"remoterf_enrollment_codes_{ts}.csv"
705
+
706
+ preferred = [
707
+ "code_name",
708
+ "group_id",
709
+ "uses",
710
+ "uses_left",
711
+ "remaining_uses",
712
+ "duration_sec",
713
+ "expires_at",
714
+ "created_at",
715
+ ]
716
+
717
+ try:
718
+ _write_csv(rows, out_path, preferred_columns=preferred)
719
+ print(f"Exported enrollment codes CSV -> {out_path}")
720
+ return out_path
721
+ except Exception as e:
722
+ print(f"Failed to export enrollment codes CSV: {e}")
723
+ return None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: remoteRF-server
3
- Version: 0.1.58
3
+ Version: 0.1.60
4
4
  Description-Content-Type: text/markdown
5
5
  Requires-Dist: grpcio
6
6
  Requires-Dist: protobuf
@@ -281,10 +281,66 @@ Note that all device and server config parameters need a 'restart' to take affec
281
281
 
282
282
  ## Server Runtime Configuration
283
283
 
284
- After running 'serverrf --serve', you will have another set of configurations, including managing users and accounts, creating user groups, making registration codes, etc. Below will be a overview of said commands.
284
+ After running `serverrf --serve`, you’ll enter the **RemoteRF Server Shell**. This interactive shell is used for runtime administration: managing users, devices, reservations, user groups, and enrollment codes.
285
285
 
286
+ > Tip: Legacy commands (e.g. `show a`, `rm db`) may still work if enabled, but the commands below are the canonical interface.
286
287
 
288
+ ---
289
+
290
+ #### Server
291
+
292
+ * `help` / `?` — Show help
293
+ * `clear` — Clear the screen
294
+ * `status` — Show server status (uptime / bind info)
295
+ * `quit` / `exit` — Exit the server shell
296
+
297
+ ---
298
+
299
+ #### Users
300
+
301
+ * `users list` — List all accounts
302
+ * `users manage` — Manage a specific user (permissions / deletion / reservations) *(interactive)*
303
+ * `users purge` — Remove **all** users
304
+
305
+ ---
306
+
307
+ #### Devices
308
+
309
+ * `devices list` — List all devices
310
+
311
+ ---
312
+
313
+ #### Reservations
314
+
315
+ * `reservations list` — List all reservations
316
+ * `reservations purge` — Remove **all** reservations
287
317
 
318
+ ---
319
+
320
+ #### Groups
321
+
322
+ * `groups list` — List user groups
323
+ * `groups create` — Create a user group *(interactive)*
324
+ * `groups edit` — Edit a user group *(interactive)*
325
+ * `groups delete` — Delete a user group *(interactive)*
326
+
327
+ ---
328
+
329
+ #### Enrollment Codes
330
+
331
+ * `codes list` — List enrollment codes
332
+ * `codes create` — Create enrollment codes *(interactive)*
333
+ * `codes delete` — Delete an enrollment code *(interactive)*
334
+
335
+ ---
336
+
337
+ #### Database
338
+
339
+ * `db reset` — Remove all database entries
340
+
341
+ ---
342
+
343
+ ##
288
344
  todo:
289
345
  <!-- Adding plutos via the CLI -->
290
346
  <!-- Testing functionality (disregarding Host pipeline) -->
@@ -295,6 +351,8 @@ Ability to remotely manage groups and codes as admin.
295
351
 
296
352
  HostRF integration -> Host directory, device routing, dynamic reservation pulling, with activity/status (online, offline, etc.)
297
353
 
354
+ Cleanup code comments.
355
+
298
356
  Update Ian with installation demo (try myself first on the NUC once!) for both server and host.
299
357
 
300
358