remoteRF-server 0.1.57__tar.gz → 0.1.59__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.57 → remoterf_server-0.1.59}/PKG-INFO +60 -2
  2. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/README.md +59 -1
  3. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/pyproject.toml +1 -1
  4. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/server/grpc_server.py +8 -3
  5. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/server/user_group_cli.py +140 -1
  6. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server.egg-info/PKG-INFO +60 -2
  7. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/setup.cfg +0 -0
  8. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/__init__.py +0 -0
  9. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/common/__init__.py +0 -0
  10. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/common/grpc/__init__.py +0 -0
  11. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/common/grpc/grpc_host_pb2.py +0 -0
  12. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/common/grpc/grpc_host_pb2_grpc.py +0 -0
  13. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/common/grpc/grpc_pb2.py +0 -0
  14. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/common/grpc/grpc_pb2_grpc.py +0 -0
  15. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/common/utils/__init__.py +0 -0
  16. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/common/utils/ansi_codes.py +0 -0
  17. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/common/utils/api_token.py +0 -0
  18. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/common/utils/db_connection.py +0 -0
  19. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/common/utils/db_location.py +0 -0
  20. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/common/utils/list_string.py +0 -0
  21. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/common/utils/process_arg.py +0 -0
  22. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/drivers/__init__.py +0 -0
  23. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/drivers/adalm_pluto/__init__.py +0 -0
  24. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/drivers/adalm_pluto/pluto_remote_server.py +0 -0
  25. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/host/__init__.py +0 -0
  26. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/host/host_directory_store.py +0 -0
  27. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/host/host_tunnel_server.py +0 -0
  28. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/server/__init__.py +0 -0
  29. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/server/acc_perms.py +0 -0
  30. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/server/cert_provider.py +0 -0
  31. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/server/device_manager.py +0 -0
  32. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/server/reservation.py +0 -0
  33. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/server/rpc_manager.py +0 -0
  34. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/server/user_group_handler.py +0 -0
  35. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/serverrf_cli.py +0 -0
  36. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/tools/__init__.py +0 -0
  37. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server/tools/gen_certs.py +0 -0
  38. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server.egg-info/SOURCES.txt +0 -0
  39. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server.egg-info/dependency_links.txt +0 -0
  40. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server.egg-info/entry_points.txt +0 -0
  41. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/src/remoteRF_server.egg-info/requires.txt +0 -0
  42. {remoterf_server-0.1.57 → remoterf_server-0.1.59}/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.57
3
+ Version: 0.1.59
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.57"
7
+ version = "0.1.59"
8
8
  dependencies = [
9
9
  "grpcio",
10
10
  "protobuf",
@@ -27,7 +27,8 @@ from .reservation import reservation_handler
27
27
  from .rpc_manager import rpc_manager
28
28
  from .acc_perms import perms
29
29
  from ..common.utils import *
30
- 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
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, export_user_groups_csv_local, export_enrollment_codes_csv_local
31
32
  from .user_group_handler import user_group_handler, start_usergroup_cleanup_loop
32
33
 
33
34
  from pathlib import Path
@@ -478,12 +479,14 @@ def help() -> None:
478
479
  printf(" groups create ", Sty.MAGENTA, "- Create a user group (interactive)", Sty.DEFAULT)
479
480
  printf(" groups edit ", Sty.MAGENTA, "- Edit a user group (interactive)", Sty.DEFAULT)
480
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)
481
483
  print()
482
484
 
483
485
  printf("Enrollment Codes:", Sty.BOLD)
484
486
  printf(" codes list ", Sty.MAGENTA, "- List enrollment codes", Sty.DEFAULT)
485
487
  printf(" codes create ", Sty.MAGENTA, "- Create enrollment codes (interactive)", Sty.DEFAULT)
486
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)
487
490
  print()
488
491
 
489
492
  printf("Database:", Sty.BOLD)
@@ -562,6 +565,7 @@ def server_input(inpu: str) -> bool:
562
565
  "groups list": lambda: _stay(lambda: list_user_groups_local(session)),
563
566
  "show g": lambda: _stay(lambda: list_user_groups_local(session)), # old
564
567
  "show groups": lambda: _stay(lambda: list_user_groups_local(session)), # old
568
+ "groups csv": lambda: _stay(export_user_groups_csv_local),
565
569
 
566
570
  # ---- enrollment codes ----
567
571
  "codes create": lambda: _stay(lambda: make_enrollment_codes_local(session)),
@@ -576,6 +580,8 @@ def server_input(inpu: str) -> bool:
576
580
  "rm codes": lambda: _stay(lambda: remove_enrollment_code_local(session)), # old
577
581
  "rm code": lambda: _stay(lambda: remove_enrollment_code_local(session)), # old
578
582
  "rm c": lambda: _stay(lambda: remove_enrollment_code_local(session)), # old
583
+
584
+ "codes csv": lambda: _stay(export_enrollment_codes_csv_local),
579
585
  }
580
586
 
581
587
  fn = DISPATCH.get(cmd)
@@ -586,8 +592,7 @@ def server_input(inpu: str) -> bool:
586
592
 
587
593
  return fn()
588
594
 
589
- os.system('clear')
590
- from .device_manager import get_all_devices, get_all_devices_str
595
+ # os.system('clear')
591
596
  welcome()
592
597
 
593
598
  def main():
@@ -586,4 +586,143 @@ def list_enrollment_codes_local(session) -> None:
586
586
  print(header)
587
587
  print(sep)
588
588
  for row in table:
589
- print(" ".join(row[i].ljust(widths[cols[i]]) for i in range(len(cols))))
589
+ print(" ".join(row[i].ljust(widths[cols[i]]) for i in range(len(cols))))
590
+
591
+ from __future__ import annotations
592
+
593
+ import csv
594
+ import json
595
+ import os
596
+ import re
597
+ from datetime import datetime
598
+ from pathlib import Path
599
+ from typing import Any, Dict, List, Optional
600
+
601
+ from .user_group_handler import user_group_handler
602
+
603
+
604
+ def _resolve_download_dir() -> Path:
605
+ """
606
+ Best-effort Downloads folder resolution:
607
+ 1) XDG_DOWNLOAD_DIR env (if set)
608
+ 2) ~/.config/user-dirs.dirs XDG_DOWNLOAD_DIR (Linux desktops)
609
+ 3) ~/Downloads
610
+ 4) fallback: cwd
611
+ """
612
+ # 1) Env override (rare, but cheap to support)
613
+ xdg_env = os.getenv("XDG_DOWNLOAD_DIR")
614
+ if xdg_env:
615
+ p = Path(os.path.expandvars(xdg_env)).expanduser()
616
+ return p
617
+
618
+ # 2) user-dirs.dirs (common on Linux w/ xdg-user-dirs)
619
+ try:
620
+ user_dirs = Path.home() / ".config" / "user-dirs.dirs"
621
+ if user_dirs.exists():
622
+ txt = user_dirs.read_text(encoding="utf-8", errors="ignore")
623
+ m = re.search(r'^XDG_DOWNLOAD_DIR\s*=\s*"(.*)"\s*$', txt, flags=re.MULTILINE)
624
+ if m:
625
+ raw = m.group(1)
626
+ raw = raw.replace("$HOME", str(Path.home()))
627
+ p = Path(os.path.expandvars(raw)).expanduser()
628
+ return p
629
+ except Exception:
630
+ pass
631
+
632
+ # 3) Default
633
+ p = Path.home() / "Downloads"
634
+ return p
635
+
636
+
637
+ def _coerce_csv_cell(v: Any) -> str:
638
+ if v is None:
639
+ return ""
640
+ if isinstance(v, (dict, list, tuple)):
641
+ # stable, readable cell content
642
+ return json.dumps(v, ensure_ascii=False, separators=(",", ":"))
643
+ return str(v)
644
+
645
+
646
+ def _write_csv(
647
+ rows: List[Dict[str, Any]],
648
+ out_path: Path,
649
+ *,
650
+ preferred_columns: Optional[List[str]] = None,
651
+ ) -> None:
652
+ if not rows:
653
+ raise ValueError("No rows to write.")
654
+
655
+ preferred_columns = preferred_columns or []
656
+
657
+ present = set().union(*(r.keys() for r in rows))
658
+ columns = [c for c in preferred_columns if c in present]
659
+ columns += [c for c in sorted(present) if c not in columns]
660
+
661
+ out_path.parent.mkdir(parents=True, exist_ok=True)
662
+
663
+ with out_path.open("w", newline="", encoding="utf-8") as f:
664
+ w = csv.DictWriter(f, fieldnames=columns, extrasaction="ignore")
665
+ w.writeheader()
666
+ for r in rows:
667
+ w.writerow({c: _coerce_csv_cell(r.get(c)) for c in columns})
668
+
669
+
670
+ def export_user_groups_csv_local() -> Optional[Path]:
671
+ # include_users=True so CSV truly contains "everything"
672
+ groups: List[Dict[str, Any]] = user_group_handler.get_all_user_groups(include_users=True) or []
673
+ if not groups:
674
+ print("No user groups found.")
675
+ return None
676
+
677
+ ts = datetime.now().strftime("%Y%m%d_%H%M%S")
678
+ out_dir = _resolve_download_dir()
679
+ out_path = out_dir / f"remoterf_user_groups_{ts}.csv"
680
+
681
+ preferred = [
682
+ "group_id", "id",
683
+ "group_name", "name",
684
+ "devices_whitelist",
685
+ "max_reservation_time_sec",
686
+ "max_reservations",
687
+ "lifetime_sec",
688
+ "created_at",
689
+ "users",
690
+ ]
691
+
692
+ try:
693
+ _write_csv(groups, out_path, preferred_columns=preferred)
694
+ print(f"Exported user groups CSV -> {out_path}")
695
+ return out_path
696
+ except Exception as e:
697
+ print(f"Failed to export user groups CSV: {e}")
698
+ return None
699
+
700
+
701
+ def export_enrollment_codes_csv_local() -> Optional[Path]:
702
+ rows: List[Dict[str, Any]] = user_group_handler.get_all_enrollment_codes() or []
703
+ if not rows:
704
+ print("No enrollment codes found.")
705
+ return None
706
+
707
+ ts = datetime.now().strftime("%Y%m%d_%H%M%S")
708
+ out_dir = _resolve_download_dir()
709
+ out_path = out_dir / f"remoterf_enrollment_codes_{ts}.csv"
710
+
711
+ preferred = [
712
+ "code_name",
713
+ "group_id",
714
+ "uses",
715
+ "uses_left",
716
+ "remaining_uses",
717
+ "duration_sec",
718
+ "expires_at",
719
+ "created_at",
720
+ ]
721
+
722
+ try:
723
+ _write_csv(rows, out_path, preferred_columns=preferred)
724
+ print(f"Exported enrollment codes CSV -> {out_path}")
725
+ return out_path
726
+ except Exception as e:
727
+ print(f"Failed to export enrollment codes CSV: {e}")
728
+ return None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: remoteRF-server
3
- Version: 0.1.57
3
+ Version: 0.1.59
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