esp-rainmaker-cli 1.13.0__tar.gz → 1.14.0__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.
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/PKG-INFO +15 -1
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/esp_rainmaker_cli.egg-info/PKG-INFO +15 -1
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rainmaker/rainmaker.py +150 -1
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rainmaker/version.py +1 -1
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_cmd/group.py +218 -2
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_cmd/node.py +10 -2
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/configmanager.py +1 -1
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/session.py +148 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/LICENSE +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/README.md +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/esp_rainmaker_cli.egg-info/SOURCES.txt +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/esp_rainmaker_cli.egg-info/dependency_links.txt +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/esp_rainmaker_cli.egg-info/entry_points.txt +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/esp_rainmaker_cli.egg-info/requires.txt +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/esp_rainmaker_cli.egg-info/top_level.txt +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rainmaker/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_cmd/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_cmd/automation.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_cmd/browserlogin.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_cmd/cache.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_cmd/cmd_response.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_cmd/html/welcome.html +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_cmd/provision.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_cmd/stream.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_cmd/test.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_cmd/user.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/aws_credentials.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/cmd_response.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/constants.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/device.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/envval.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/exceptions.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/kvs_streaming.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/local_control.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/logger.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/node.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/node_cache.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/profile_manager.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/profile_utils.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/schedule_utils.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/serverconfig.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/service.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/session_store.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/simple_local_control.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_lib/user.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/discovery/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/discovery/mdns_discovery.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/prov/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/prov/wifi_ctrl.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/prov/wifi_prov.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/prov/wifi_scan.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/security/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/security/security.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/security/security0.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/security/security1.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/security/security2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/security/srp6a.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/transport/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/transport/ble_cli.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/transport/transport.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/transport/transport_ble.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/transport/transport_console.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/transport/transport_http.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/utils/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/utils/convenience.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_claim/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_claim/claim.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_claim/claim_config.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/constants_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/esp_local_ctrl.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/esp_local_ctrl_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/esp_prov.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/esp_rainmaker_ctrl.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/esp_rmaker_prov_local_ctrl_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/integration.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/proto/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/proto/proto_lc.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/prov/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/prov/custom_prov.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/prov/wifi_ctrl.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/raw_config.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/raw_params.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/sec0_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/sec1_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/sec2_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/security/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/session_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/transport/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/utils/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/challenge_response.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/config/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/config/custom_cloud_config_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/config/esp_rmaker_chal_resp_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/config/esp_rmaker_claim_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/config/esp_rmaker_user_mapping_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/esp_rainmaker_prov.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/on_network_chal_resp.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/proto/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/protocomm/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/protocomm/python/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/protocomm/python/constants_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/protocomm/python/sec0_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/protocomm/python/sec1_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/protocomm/python/sec2_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/protocomm/python/session_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/prov/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/prov/prov_util.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/prov/user_mapping.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/security/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/transport/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/utils/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/wifi_provisioning/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/wifi_provisioning/python/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/wifi_provisioning/python/wifi_config_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/wifi_provisioning/python/wifi_constants_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/wifi_provisioning/python/wifi_ctrl_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/wifi_provisioning/python/wifi_scan_pb2.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/server_cert/__init__.py +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/server_cert/server_cert.pem +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/setup.cfg +0 -0
- {esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: esp-rainmaker-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.14.0
|
|
4
4
|
Summary: A python utility to perform host based claiming
|
|
5
5
|
Home-page: https://github.com/espressif/esp-rainmaker-cli
|
|
6
6
|
Author: Espressif Systems
|
|
@@ -122,6 +122,20 @@ Changelog
|
|
|
122
122
|
|
|
123
123
|
All major changes to ESP RainMaker CLI will be documented in this file.
|
|
124
124
|
|
|
125
|
+
## [1.14.0] - 24-Apr-2026
|
|
126
|
+
### Added
|
|
127
|
+
- New `group sharing` subcommand for sharing device groups / Matter fabrics between users:
|
|
128
|
+
- `add`, `remove`, `list`, `list-requests`, `accept`, `decline`, `cancel` operations
|
|
129
|
+
- Supports primary/secondary roles, sub-roles (1-4), metadata, and ownership transfer (`--transfer`, `--new-role`)
|
|
130
|
+
- Parsed, human-readable output by default; pass `--raw` on any operation to get the underlying JSON response
|
|
131
|
+
|
|
132
|
+
## [1.13.1] - 23-Apr-2026
|
|
133
|
+
### Added
|
|
134
|
+
- Node sharing enhancements:
|
|
135
|
+
- Support for sharing as "primary"
|
|
136
|
+
- Transferring nodes
|
|
137
|
+
- Adding sub-roles
|
|
138
|
+
|
|
125
139
|
## [1.13.0] - 08-Apr-2026
|
|
126
140
|
### Added
|
|
127
141
|
- New `stream` command for WebRTC video streaming from ESP RainMaker camera devices via Amazon Kinesis Video Streams (KVS) signaling:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: esp-rainmaker-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.14.0
|
|
4
4
|
Summary: A python utility to perform host based claiming
|
|
5
5
|
Home-page: https://github.com/espressif/esp-rainmaker-cli
|
|
6
6
|
Author: Espressif Systems
|
|
@@ -122,6 +122,20 @@ Changelog
|
|
|
122
122
|
|
|
123
123
|
All major changes to ESP RainMaker CLI will be documented in this file.
|
|
124
124
|
|
|
125
|
+
## [1.14.0] - 24-Apr-2026
|
|
126
|
+
### Added
|
|
127
|
+
- New `group sharing` subcommand for sharing device groups / Matter fabrics between users:
|
|
128
|
+
- `add`, `remove`, `list`, `list-requests`, `accept`, `decline`, `cancel` operations
|
|
129
|
+
- Supports primary/secondary roles, sub-roles (1-4), metadata, and ownership transfer (`--transfer`, `--new-role`)
|
|
130
|
+
- Parsed, human-readable output by default; pass `--raw` on any operation to get the underlying JSON response
|
|
131
|
+
|
|
132
|
+
## [1.13.1] - 23-Apr-2026
|
|
133
|
+
### Added
|
|
134
|
+
- Node sharing enhancements:
|
|
135
|
+
- Support for sharing as "primary"
|
|
136
|
+
- Transferring nodes
|
|
137
|
+
- Adding sub-roles
|
|
138
|
+
|
|
125
139
|
## [1.13.0] - 08-Apr-2026
|
|
126
140
|
### Added
|
|
127
141
|
- New `stream` command for WebRTC video streaming from ESP RainMaker camera devices via Amazon Kinesis Video Streams (KVS) signaling:
|
|
@@ -15,7 +15,12 @@ from rmaker_cmd.cmd_response import get_cmd_requests, create_cmd_request
|
|
|
15
15
|
from rmaker_cmd.provision import provision
|
|
16
16
|
from rmaker_cmd.test import test
|
|
17
17
|
from rmaker_lib.logger import log
|
|
18
|
-
from rmaker_cmd.group import group_add, group_remove, group_edit, group_list,
|
|
18
|
+
from rmaker_cmd.group import (group_add, group_remove, group_edit, group_list,
|
|
19
|
+
group_show, group_add_nodes, group_remove_nodes,
|
|
20
|
+
group_list_nodes, group_sharing_add,
|
|
21
|
+
group_sharing_remove, group_sharing_list,
|
|
22
|
+
group_sharing_list_requests, group_sharing_accept,
|
|
23
|
+
group_sharing_decline, group_sharing_cancel)
|
|
19
24
|
from rmaker_cmd.automation import automation_add, automation_edit, automation_remove, automation_get
|
|
20
25
|
from rmaker_cmd.cache import cache_manage
|
|
21
26
|
from rmaker_cmd.stream import stream_video
|
|
@@ -668,6 +673,29 @@ def main():
|
|
|
668
673
|
"format: <nodeid1>,<nodeid2>,...",
|
|
669
674
|
required=True)
|
|
670
675
|
|
|
676
|
+
add_op_parser.add_argument('--sub_role',
|
|
677
|
+
type=int,
|
|
678
|
+
metavar='<sub_role>',
|
|
679
|
+
choices=range(1, 5),
|
|
680
|
+
help='Sub-role for the secondary user (1-4)',
|
|
681
|
+
default=None)
|
|
682
|
+
|
|
683
|
+
add_op_parser.add_argument('--primary',
|
|
684
|
+
action='store_true',
|
|
685
|
+
help='Set "primary":true in the sharing request')
|
|
686
|
+
|
|
687
|
+
add_op_parser.add_argument('--transfer',
|
|
688
|
+
action='store_true',
|
|
689
|
+
help='Transfer node ownership to the specified user')
|
|
690
|
+
|
|
691
|
+
add_op_parser.add_argument('--new_role',
|
|
692
|
+
type=str,
|
|
693
|
+
metavar='<new_role>',
|
|
694
|
+
choices=['primary', 'secondary'],
|
|
695
|
+
help='New role for the current user after transfer (primary/secondary).\n'
|
|
696
|
+
'Only used with --transfer',
|
|
697
|
+
default=None)
|
|
698
|
+
|
|
671
699
|
add_profile_argument(add_op_parser)
|
|
672
700
|
add_op_parser.set_defaults(func=node_sharing_ops, parser=add_op_parser)
|
|
673
701
|
|
|
@@ -911,6 +939,127 @@ def main():
|
|
|
911
939
|
add_profile_argument(group_list_nodes_parser)
|
|
912
940
|
group_list_nodes_parser.set_defaults(func=group_list_nodes)
|
|
913
941
|
|
|
942
|
+
# group sharing
|
|
943
|
+
group_sharing_parser = group_subparsers.add_parser(
|
|
944
|
+
'sharing',
|
|
945
|
+
help='Share groups / matter fabrics between users',
|
|
946
|
+
formatter_class=argparse.RawTextHelpFormatter,
|
|
947
|
+
description='Share groups or matter fabrics with other users.\n'
|
|
948
|
+
'Primary users can share groups; secondary users can view '
|
|
949
|
+
'their sharing or leave groups they have access to.')
|
|
950
|
+
group_sharing_parser.set_defaults(
|
|
951
|
+
func=lambda vars=None: group_sharing_parser.print_help())
|
|
952
|
+
group_sharing_subparsers = group_sharing_parser.add_subparsers(
|
|
953
|
+
dest='sharing_command', help='Group sharing operations')
|
|
954
|
+
|
|
955
|
+
# group sharing add
|
|
956
|
+
gs_add_parser = group_sharing_subparsers.add_parser(
|
|
957
|
+
'add', help='Share group(s) with a user (or add self-sharing without --user)',
|
|
958
|
+
formatter_class=argparse.RawTextHelpFormatter)
|
|
959
|
+
gs_add_parser.add_argument('--groups', type=str, required=True,
|
|
960
|
+
metavar='<group_ids>',
|
|
961
|
+
help='Comma separated group ids (max 10)')
|
|
962
|
+
gs_add_parser.add_argument('--user', type=str, metavar='<user_name>',
|
|
963
|
+
help='User name (email) to share with. Optional.')
|
|
964
|
+
gs_add_parser.add_argument('--primary', action='store_true',
|
|
965
|
+
help='Share with primary access (default: secondary)')
|
|
966
|
+
gs_add_parser.add_argument('--sub-role', type=int, choices=range(1, 5),
|
|
967
|
+
metavar='<1-4>',
|
|
968
|
+
help='Custom sub role (1-4)')
|
|
969
|
+
gs_add_parser.add_argument('--metadata', type=str, metavar='<json>',
|
|
970
|
+
help='Custom metadata as a JSON string')
|
|
971
|
+
gs_add_parser.add_argument('--transfer', action='store_true',
|
|
972
|
+
help='Transfer ownership of the group(s) to the user')
|
|
973
|
+
gs_add_parser.add_argument('--new-role', type=str, choices=['secondary'],
|
|
974
|
+
help='Role to assign to self after transfer '
|
|
975
|
+
'(only valid with --transfer)')
|
|
976
|
+
gs_add_parser.add_argument('--raw', action='store_true',
|
|
977
|
+
help='Print the raw JSON response instead of parsed output')
|
|
978
|
+
add_profile_argument(gs_add_parser)
|
|
979
|
+
gs_add_parser.set_defaults(func=group_sharing_add)
|
|
980
|
+
|
|
981
|
+
# group sharing remove
|
|
982
|
+
gs_remove_parser = group_sharing_subparsers.add_parser(
|
|
983
|
+
'remove', help='Remove group sharing with a user',
|
|
984
|
+
formatter_class=argparse.RawTextHelpFormatter)
|
|
985
|
+
gs_remove_parser.add_argument('--groups', type=str, required=True,
|
|
986
|
+
metavar='<group_ids>',
|
|
987
|
+
help='Comma separated group ids')
|
|
988
|
+
gs_remove_parser.add_argument('--user', type=str, required=True,
|
|
989
|
+
metavar='<user_name>',
|
|
990
|
+
help='User name (email) to unshare with')
|
|
991
|
+
gs_remove_parser.add_argument('--raw', action='store_true',
|
|
992
|
+
help='Print the raw JSON response instead of parsed output')
|
|
993
|
+
add_profile_argument(gs_remove_parser)
|
|
994
|
+
gs_remove_parser.set_defaults(func=group_sharing_remove)
|
|
995
|
+
|
|
996
|
+
# group sharing list
|
|
997
|
+
gs_list_parser = group_sharing_subparsers.add_parser(
|
|
998
|
+
'list', help='Show sharing details for groups / matter fabrics',
|
|
999
|
+
formatter_class=argparse.RawTextHelpFormatter)
|
|
1000
|
+
gs_list_parser.add_argument('--group-id', type=str, metavar='<group_id>',
|
|
1001
|
+
help='Fetch sharing details for a single group')
|
|
1002
|
+
gs_list_parser.add_argument('--sub-groups', action='store_true',
|
|
1003
|
+
help='Include sharing details of sub-groups')
|
|
1004
|
+
gs_list_parser.add_argument('--parent-groups', action='store_true',
|
|
1005
|
+
help='Include sharing details of parent groups')
|
|
1006
|
+
gs_list_parser.add_argument('--metadata', action='store_true',
|
|
1007
|
+
help='Include metadata set during sharing')
|
|
1008
|
+
gs_list_parser.add_argument('--raw', action='store_true',
|
|
1009
|
+
help='Print the raw JSON response instead of parsed output')
|
|
1010
|
+
add_profile_argument(gs_list_parser)
|
|
1011
|
+
gs_list_parser.set_defaults(func=group_sharing_list)
|
|
1012
|
+
|
|
1013
|
+
# group sharing list-requests
|
|
1014
|
+
gs_list_req_parser = group_sharing_subparsers.add_parser(
|
|
1015
|
+
'list-requests', help='List pending group sharing requests',
|
|
1016
|
+
formatter_class=argparse.RawTextHelpFormatter,
|
|
1017
|
+
description='List pending group sharing requests.\n'
|
|
1018
|
+
'Use --primary-user to list requests raised by you.\n'
|
|
1019
|
+
'Without the flag, lists requests you have received.')
|
|
1020
|
+
gs_list_req_parser.add_argument('--id', type=str, metavar='<request_id>',
|
|
1021
|
+
help='Fetch a specific request by id')
|
|
1022
|
+
gs_list_req_parser.add_argument('--primary-user', action='store_true',
|
|
1023
|
+
help='List requests raised by current user '
|
|
1024
|
+
'(default: requests received)')
|
|
1025
|
+
gs_list_req_parser.add_argument('--raw', action='store_true',
|
|
1026
|
+
help='Print the raw JSON response instead of parsed output')
|
|
1027
|
+
add_profile_argument(gs_list_req_parser)
|
|
1028
|
+
gs_list_req_parser.set_defaults(func=group_sharing_list_requests)
|
|
1029
|
+
|
|
1030
|
+
# group sharing accept
|
|
1031
|
+
gs_accept_parser = group_sharing_subparsers.add_parser(
|
|
1032
|
+
'accept', help='Accept a pending group sharing request')
|
|
1033
|
+
gs_accept_parser.add_argument('--id', type=str, required=True,
|
|
1034
|
+
metavar='<request_id>',
|
|
1035
|
+
help='Id of the sharing request')
|
|
1036
|
+
gs_accept_parser.add_argument('--raw', action='store_true',
|
|
1037
|
+
help='Print the raw JSON response instead of parsed output')
|
|
1038
|
+
add_profile_argument(gs_accept_parser)
|
|
1039
|
+
gs_accept_parser.set_defaults(func=group_sharing_accept)
|
|
1040
|
+
|
|
1041
|
+
# group sharing decline
|
|
1042
|
+
gs_decline_parser = group_sharing_subparsers.add_parser(
|
|
1043
|
+
'decline', help='Decline a pending group sharing request')
|
|
1044
|
+
gs_decline_parser.add_argument('--id', type=str, required=True,
|
|
1045
|
+
metavar='<request_id>',
|
|
1046
|
+
help='Id of the sharing request')
|
|
1047
|
+
gs_decline_parser.add_argument('--raw', action='store_true',
|
|
1048
|
+
help='Print the raw JSON response instead of parsed output')
|
|
1049
|
+
add_profile_argument(gs_decline_parser)
|
|
1050
|
+
gs_decline_parser.set_defaults(func=group_sharing_decline)
|
|
1051
|
+
|
|
1052
|
+
# group sharing cancel
|
|
1053
|
+
gs_cancel_parser = group_sharing_subparsers.add_parser(
|
|
1054
|
+
'cancel', help='Cancel a pending group sharing request (primary side)')
|
|
1055
|
+
gs_cancel_parser.add_argument('--id', type=str, required=True,
|
|
1056
|
+
metavar='<request_id>',
|
|
1057
|
+
help='Id of the sharing request')
|
|
1058
|
+
gs_cancel_parser.add_argument('--raw', action='store_true',
|
|
1059
|
+
help='Print the raw JSON response instead of parsed output')
|
|
1060
|
+
add_profile_argument(gs_cancel_parser)
|
|
1061
|
+
gs_cancel_parser.set_defaults(func=group_sharing_cancel)
|
|
1062
|
+
|
|
914
1063
|
# Automation Management
|
|
915
1064
|
automation_parser = subparsers.add_parser('automations',
|
|
916
1065
|
help='Manage automation triggers')
|
|
@@ -3,8 +3,17 @@
|
|
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
|
|
5
5
|
from rmaker_lib.profile_utils import get_session_with_profile
|
|
6
|
+
import datetime
|
|
6
7
|
import json
|
|
7
|
-
|
|
8
|
+
import sys
|
|
9
|
+
from rmaker_cmd.node import (
|
|
10
|
+
_get_description,
|
|
11
|
+
_get_request_expiration,
|
|
12
|
+
_get_request_id,
|
|
13
|
+
_get_status,
|
|
14
|
+
_print_api_error,
|
|
15
|
+
_print_node_details,
|
|
16
|
+
)
|
|
8
17
|
|
|
9
18
|
|
|
10
19
|
def _handle_error(e, operation):
|
|
@@ -249,4 +258,211 @@ def group_list_nodes(vars=None):
|
|
|
249
258
|
else:
|
|
250
259
|
print(f"{idx}. {name} (ID: {group_id})")
|
|
251
260
|
except Exception as e:
|
|
252
|
-
_handle_error(e, "list nodes in group")
|
|
261
|
+
_handle_error(e, "list nodes in group")
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def _split_groups(groups_arg):
|
|
265
|
+
return [g.strip() for g in groups_arg.split(',') if g.strip()]
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def _print_group_sharing_request_details(resp, is_primary_user=False):
|
|
269
|
+
requests_in_resp = resp.get('sharing_requests') or []
|
|
270
|
+
if not requests_in_resp:
|
|
271
|
+
print("No pending requests")
|
|
272
|
+
return
|
|
273
|
+
request_exists = False
|
|
274
|
+
for request in requests_in_resp:
|
|
275
|
+
if request.get('request_status', '').lower() == 'declined':
|
|
276
|
+
continue
|
|
277
|
+
request_exists = True
|
|
278
|
+
print("\n{:<15}: {}".format('Request Id', request['request_id']))
|
|
279
|
+
print("{:<15}: {}".format('Group Id(s)', ','.join(request.get('group_ids', []))))
|
|
280
|
+
group_names = request.get('group_names') or []
|
|
281
|
+
if group_names:
|
|
282
|
+
print("{:<15}: {}".format('Group Name(s)', ','.join(group_names)))
|
|
283
|
+
if is_primary_user:
|
|
284
|
+
if 'user_name' in request and request['user_name']:
|
|
285
|
+
print("{:<15}: {}".format('Shared with', request['user_name']))
|
|
286
|
+
else:
|
|
287
|
+
if 'primary_user_name' in request and request['primary_user_name']:
|
|
288
|
+
print("{:<15}: {}".format('Shared by', request['primary_user_name']))
|
|
289
|
+
if 'user_role' in request and request['user_role']:
|
|
290
|
+
print("{:<15}: {}".format('Role', request['user_role']))
|
|
291
|
+
print(_get_request_expiration(request))
|
|
292
|
+
|
|
293
|
+
if not request_exists:
|
|
294
|
+
print("No pending requests")
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def _print_group_sharing_details(resp):
|
|
298
|
+
try:
|
|
299
|
+
groups_in_resp = resp.get('group_sharing') or []
|
|
300
|
+
if not groups_in_resp:
|
|
301
|
+
print("No shared groups")
|
|
302
|
+
return
|
|
303
|
+
for group in groups_in_resp:
|
|
304
|
+
print("\nGroup Id: {}".format(group.get('group_id', '')))
|
|
305
|
+
users = group.get('users') or {}
|
|
306
|
+
primary_users = ','.join(users.get('primary') or [])
|
|
307
|
+
secondary_users = ','.join(users.get('secondary') or [])
|
|
308
|
+
print("{:<7}: {:<9}: {}".format('Users', 'Primary', primary_users), end='')
|
|
309
|
+
if secondary_users:
|
|
310
|
+
print("\n{:>18}: {}".format('Secondary', secondary_users), end='')
|
|
311
|
+
print()
|
|
312
|
+
except KeyError:
|
|
313
|
+
print("Error in displaying details...Please check API Json...Exiting...")
|
|
314
|
+
sys.exit(0)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def _emit(resp, raw, render):
|
|
318
|
+
if raw:
|
|
319
|
+
print(json.dumps(resp, indent=2))
|
|
320
|
+
return
|
|
321
|
+
if isinstance(resp, dict) and resp.get('status', '').lower() != 'success' and 'error_code' in resp:
|
|
322
|
+
_print_api_error(resp)
|
|
323
|
+
return
|
|
324
|
+
render(resp)
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def group_sharing_add(vars=None):
|
|
328
|
+
try:
|
|
329
|
+
s = get_session_with_profile(vars or {})
|
|
330
|
+
groups = _split_groups(vars['groups'])
|
|
331
|
+
if not groups:
|
|
332
|
+
print("At least one group id must be provided in --groups")
|
|
333
|
+
return
|
|
334
|
+
user = vars.get('user')
|
|
335
|
+
primary = vars.get('primary') if vars.get('primary') else None
|
|
336
|
+
sub_role = vars.get('sub_role')
|
|
337
|
+
transfer = vars.get('transfer') if vars.get('transfer') else None
|
|
338
|
+
new_role = vars.get('new_role')
|
|
339
|
+
metadata = None
|
|
340
|
+
metadata_arg = vars.get('metadata')
|
|
341
|
+
if metadata_arg:
|
|
342
|
+
try:
|
|
343
|
+
metadata = json.loads(metadata_arg)
|
|
344
|
+
except Exception as e:
|
|
345
|
+
print("Invalid JSON for --metadata:", e)
|
|
346
|
+
return
|
|
347
|
+
print("Sharing group(s) with user")
|
|
348
|
+
resp = s.add_user_group_sharing(
|
|
349
|
+
groups=groups,
|
|
350
|
+
user_name=user,
|
|
351
|
+
primary=primary,
|
|
352
|
+
sub_role=sub_role,
|
|
353
|
+
metadata=metadata,
|
|
354
|
+
transfer=transfer,
|
|
355
|
+
new_role=new_role,
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
def render(r):
|
|
359
|
+
if r.get('status', '').lower() == 'success':
|
|
360
|
+
print("{:<11}: {}".format('Status', _get_status(r)))
|
|
361
|
+
print("{:<11}: {}".format('Description', _get_description(r)))
|
|
362
|
+
if 'request_id' in r:
|
|
363
|
+
print("{:<11}: {}".format('Request Id', _get_request_id(r)))
|
|
364
|
+
|
|
365
|
+
_emit(resp, vars.get('raw', False), render)
|
|
366
|
+
except Exception as e:
|
|
367
|
+
_handle_error(e, "add group sharing")
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
def group_sharing_remove(vars=None):
|
|
371
|
+
try:
|
|
372
|
+
s = get_session_with_profile(vars or {})
|
|
373
|
+
groups = _split_groups(vars['groups'])
|
|
374
|
+
if not groups:
|
|
375
|
+
print("At least one group id must be provided in --groups")
|
|
376
|
+
return
|
|
377
|
+
print("Removing group sharing")
|
|
378
|
+
resp = s.remove_user_group_sharing(
|
|
379
|
+
groups=','.join(groups),
|
|
380
|
+
user_name=vars['user'],
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
def render(r):
|
|
384
|
+
if r.get('status', '').lower() == 'success':
|
|
385
|
+
print("{}: {}".format(_get_status(r), _get_description(r)))
|
|
386
|
+
|
|
387
|
+
_emit(resp, vars.get('raw', False), render)
|
|
388
|
+
except Exception as e:
|
|
389
|
+
_handle_error(e, "remove group sharing")
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def group_sharing_list(vars=None):
|
|
393
|
+
try:
|
|
394
|
+
s = get_session_with_profile(vars or {})
|
|
395
|
+
resp = s.get_user_group_sharing(
|
|
396
|
+
group_id=vars.get('group_id'),
|
|
397
|
+
sub_groups=vars.get('sub_groups', False),
|
|
398
|
+
parent_groups=vars.get('parent_groups', False),
|
|
399
|
+
metadata=vars.get('metadata', False),
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
def render(r):
|
|
403
|
+
print("Displaying group sharing details")
|
|
404
|
+
_print_group_sharing_details(r)
|
|
405
|
+
|
|
406
|
+
_emit(resp, vars.get('raw', False), render)
|
|
407
|
+
except Exception as e:
|
|
408
|
+
_handle_error(e, "list group sharing")
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def group_sharing_list_requests(vars=None):
|
|
412
|
+
try:
|
|
413
|
+
s = get_session_with_profile(vars or {})
|
|
414
|
+
is_primary = vars.get('primary_user', False)
|
|
415
|
+
resp = s.get_user_group_sharing_requests(
|
|
416
|
+
request_id=vars.get('id'),
|
|
417
|
+
primary_user=is_primary,
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
def render(r):
|
|
421
|
+
print("Displaying pending group sharing requests")
|
|
422
|
+
print("Current (logged-in) user is set as {} user".format(
|
|
423
|
+
'Primary' if is_primary else 'Secondary'))
|
|
424
|
+
_print_group_sharing_request_details(r, is_primary_user=is_primary)
|
|
425
|
+
|
|
426
|
+
_emit(resp, vars.get('raw', False), render)
|
|
427
|
+
except Exception as e:
|
|
428
|
+
_handle_error(e, "list group sharing requests")
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def _respond_group_sharing(vars, accept):
|
|
432
|
+
action = 'accept' if accept else 'decline'
|
|
433
|
+
try:
|
|
434
|
+
s = get_session_with_profile(vars or {})
|
|
435
|
+
resp = s.respond_user_group_sharing_request(
|
|
436
|
+
request_id=vars['id'], accept=accept)
|
|
437
|
+
|
|
438
|
+
def render(r):
|
|
439
|
+
if r.get('status', '').lower() == 'success':
|
|
440
|
+
print("{:<11}: {}".format('Status', _get_status(r)))
|
|
441
|
+
print("{:<11}: {}".format('Description', _get_description(r)))
|
|
442
|
+
|
|
443
|
+
_emit(resp, vars.get('raw', False), render)
|
|
444
|
+
except Exception as e:
|
|
445
|
+
_handle_error(e, "{} group sharing request".format(action))
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
def group_sharing_accept(vars=None):
|
|
449
|
+
_respond_group_sharing(vars, accept=True)
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
def group_sharing_decline(vars=None):
|
|
453
|
+
_respond_group_sharing(vars, accept=False)
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
def group_sharing_cancel(vars=None):
|
|
457
|
+
try:
|
|
458
|
+
s = get_session_with_profile(vars or {})
|
|
459
|
+
print("Cancelling request")
|
|
460
|
+
resp = s.remove_user_group_sharing_request(request_id=vars['id'])
|
|
461
|
+
|
|
462
|
+
def render(r):
|
|
463
|
+
if r.get('status', '').lower() == 'success':
|
|
464
|
+
print("{}: {}".format(_get_status(r), _get_description(r)))
|
|
465
|
+
|
|
466
|
+
_emit(resp, vars.get('raw', False), render)
|
|
467
|
+
except Exception as e:
|
|
468
|
+
_handle_error(e, "cancel group sharing request")
|
|
@@ -897,7 +897,7 @@ def list_sharing_details(node_id=None, primary_user=False, request_id=None, list
|
|
|
897
897
|
|
|
898
898
|
return node_json_resp
|
|
899
899
|
|
|
900
|
-
def add_user_to_share_nodes(nodes=None, user=None, profile_override=None):
|
|
900
|
+
def add_user_to_share_nodes(nodes=None, user=None, sub_role=None, primary=False, transfer=False, new_role=None, profile_override=None):
|
|
901
901
|
"""
|
|
902
902
|
Add user to share nodes
|
|
903
903
|
|
|
@@ -932,6 +932,14 @@ def add_user_to_share_nodes(nodes=None, user=None, profile_override=None):
|
|
|
932
932
|
api_input = {}
|
|
933
933
|
api_input['nodes'] = node_id_list
|
|
934
934
|
api_input['user_name'] = user
|
|
935
|
+
if sub_role is not None:
|
|
936
|
+
api_input['sub_role'] = sub_role
|
|
937
|
+
if primary:
|
|
938
|
+
api_input['primary'] = True
|
|
939
|
+
if transfer:
|
|
940
|
+
api_input['transfer'] = True
|
|
941
|
+
if new_role is not None:
|
|
942
|
+
api_input['new_role'] = new_role
|
|
935
943
|
log.debug("API data set: {}".format(api_input))
|
|
936
944
|
|
|
937
945
|
# API with profile-aware session
|
|
@@ -1116,7 +1124,7 @@ def node_sharing_ops(vars=None):
|
|
|
1116
1124
|
if action == 'add_user':
|
|
1117
1125
|
# Share nodes with user
|
|
1118
1126
|
print("Adding user to share node(s)")
|
|
1119
|
-
node_json_resp = add_user_to_share_nodes(nodes=vars['nodes'], user=vars['user'], profile_override=profile_override)
|
|
1127
|
+
node_json_resp = add_user_to_share_nodes(nodes=vars['nodes'], user=vars['user'], sub_role=vars.get('sub_role'), primary=vars.get('primary', False), transfer=vars.get('transfer', False), new_role=vars.get('new_role'), profile_override=profile_override)
|
|
1120
1128
|
|
|
1121
1129
|
# Print success response
|
|
1122
1130
|
if 'status' in node_json_resp and node_json_resp['status'].lower() == 'success':
|
|
@@ -426,7 +426,7 @@ class Config:
|
|
|
426
426
|
socket.setdefaulttimeout(10)
|
|
427
427
|
log.info("Checking for supported version.")
|
|
428
428
|
path = 'apiversions'
|
|
429
|
-
request_url = self.get_host().
|
|
429
|
+
request_url = self.get_host().rsplit(serverconfig.VERSION, 1)[0] + path
|
|
430
430
|
try:
|
|
431
431
|
log.debug("Version check request url : " + request_url)
|
|
432
432
|
response = requests.get(url=request_url, verify=CERT_FILE,
|
|
@@ -599,6 +599,154 @@ class Session:
|
|
|
599
599
|
log.error(f'Failed to list nodes in group: {e}')
|
|
600
600
|
raise
|
|
601
601
|
|
|
602
|
+
# Group Sharing API methods
|
|
603
|
+
|
|
604
|
+
def add_user_group_sharing(self, groups, user_name=None, primary=None,
|
|
605
|
+
sub_role=None, metadata=None, transfer=None,
|
|
606
|
+
new_role=None):
|
|
607
|
+
"""Share one or more groups/matter fabrics with another user."""
|
|
608
|
+
path = 'user/node_group/sharing'
|
|
609
|
+
payload = {'groups': groups}
|
|
610
|
+
if user_name:
|
|
611
|
+
payload['user_name'] = user_name
|
|
612
|
+
if primary is not None:
|
|
613
|
+
payload['primary'] = primary
|
|
614
|
+
if sub_role is not None:
|
|
615
|
+
payload['sub_role'] = sub_role
|
|
616
|
+
if metadata is not None:
|
|
617
|
+
payload['metadata'] = metadata
|
|
618
|
+
if transfer is not None:
|
|
619
|
+
payload['transfer'] = transfer
|
|
620
|
+
if new_role:
|
|
621
|
+
payload['new_role'] = new_role
|
|
622
|
+
url = self.config.get_host() + path
|
|
623
|
+
log.debug(f"Add group sharing request url : {url}")
|
|
624
|
+
log.debug(f"Add group sharing request payload : {json.dumps(payload)}")
|
|
625
|
+
try:
|
|
626
|
+
response = requests.put(url=url, headers=self.request_header,
|
|
627
|
+
json=payload, verify=configmanager.CERT_FILE)
|
|
628
|
+
log.debug(f"Add group sharing response : {response.text}")
|
|
629
|
+
response.raise_for_status()
|
|
630
|
+
return response.json()
|
|
631
|
+
except Exception as e:
|
|
632
|
+
log.error(f'Failed to add group sharing: {e}')
|
|
633
|
+
raise
|
|
634
|
+
|
|
635
|
+
def remove_user_group_sharing(self, groups, user_name):
|
|
636
|
+
"""Remove sharing of one or more groups/matter fabrics with a user."""
|
|
637
|
+
path = 'user/node_group/sharing'
|
|
638
|
+
params = {'groups': groups, 'user_name': user_name}
|
|
639
|
+
url = self.config.get_host() + path
|
|
640
|
+
log.debug(f"Remove group sharing request url : {url}")
|
|
641
|
+
log.debug(f"Remove group sharing request params : {params}")
|
|
642
|
+
try:
|
|
643
|
+
response = requests.delete(url=url, headers=self.request_header,
|
|
644
|
+
params=params, verify=configmanager.CERT_FILE)
|
|
645
|
+
log.debug(f"Remove group sharing response : {response.text}")
|
|
646
|
+
response.raise_for_status()
|
|
647
|
+
return response.json()
|
|
648
|
+
except Exception as e:
|
|
649
|
+
log.error(f'Failed to remove group sharing: {e}')
|
|
650
|
+
raise
|
|
651
|
+
|
|
652
|
+
def get_user_group_sharing(self, group_id=None, sub_groups=False,
|
|
653
|
+
parent_groups=False, metadata=False):
|
|
654
|
+
"""Fetch group/fabric sharing details for the current user."""
|
|
655
|
+
path = 'user/node_group/sharing'
|
|
656
|
+
params = {}
|
|
657
|
+
if group_id:
|
|
658
|
+
params['group_id'] = group_id
|
|
659
|
+
if sub_groups:
|
|
660
|
+
params['sub_groups'] = 'true'
|
|
661
|
+
if parent_groups:
|
|
662
|
+
params['parent_groups'] = 'true'
|
|
663
|
+
if metadata:
|
|
664
|
+
params['metadata'] = 'true'
|
|
665
|
+
url = self.config.get_host() + path
|
|
666
|
+
log.debug(f"Get group sharing request url : {url}")
|
|
667
|
+
log.debug(f"Get group sharing request params : {params}")
|
|
668
|
+
try:
|
|
669
|
+
response = requests.get(url=url, headers=self.request_header,
|
|
670
|
+
params=params, verify=configmanager.CERT_FILE)
|
|
671
|
+
log.debug(f"Get group sharing response : {response.text}")
|
|
672
|
+
response.raise_for_status()
|
|
673
|
+
return response.json()
|
|
674
|
+
except Exception as e:
|
|
675
|
+
log.error(f'Failed to get group sharing: {e}')
|
|
676
|
+
raise
|
|
677
|
+
|
|
678
|
+
def get_user_group_sharing_requests(self, request_id=None, primary_user=None):
|
|
679
|
+
"""Fetch pending group sharing requests (sent or received).
|
|
680
|
+
|
|
681
|
+
Pagination is handled internally: the server returns at most 10
|
|
682
|
+
records per call along with `next_request_id`/`next_user_name`
|
|
683
|
+
cursors, which are echoed back until the server stops returning
|
|
684
|
+
them. The consolidated list is returned to the caller.
|
|
685
|
+
"""
|
|
686
|
+
path = 'user/node_group/sharing/requests'
|
|
687
|
+
params = {}
|
|
688
|
+
if request_id:
|
|
689
|
+
params['request_id'] = request_id
|
|
690
|
+
if primary_user is not None:
|
|
691
|
+
params['primary_user'] = 'true' if primary_user else 'false'
|
|
692
|
+
url = self.config.get_host() + path
|
|
693
|
+
|
|
694
|
+
all_requests = []
|
|
695
|
+
try:
|
|
696
|
+
while True:
|
|
697
|
+
log.debug(f"Get group sharing requests url : {url}")
|
|
698
|
+
log.debug(f"Get group sharing requests params : {params}")
|
|
699
|
+
response = requests.get(url=url, headers=self.request_header,
|
|
700
|
+
params=params, verify=configmanager.CERT_FILE)
|
|
701
|
+
log.debug(f"Get group sharing requests response : {response.text}")
|
|
702
|
+
response.raise_for_status()
|
|
703
|
+
data = response.json()
|
|
704
|
+
all_requests.extend(data.get('sharing_requests', []))
|
|
705
|
+
next_req = data.get('next_request_id')
|
|
706
|
+
if not next_req:
|
|
707
|
+
break
|
|
708
|
+
params['start_request_id'] = next_req
|
|
709
|
+
next_user = data.get('next_user_name')
|
|
710
|
+
if next_user:
|
|
711
|
+
params['start_user_name'] = next_user
|
|
712
|
+
return {'sharing_requests': all_requests, 'total': len(all_requests)}
|
|
713
|
+
except Exception as e:
|
|
714
|
+
log.error(f'Failed to get group sharing requests: {e}')
|
|
715
|
+
raise
|
|
716
|
+
|
|
717
|
+
def remove_user_group_sharing_request(self, request_id):
|
|
718
|
+
"""Cancel a pending group sharing request (primary side)."""
|
|
719
|
+
path = 'user/node_group/sharing/requests'
|
|
720
|
+
params = {'request_id': request_id}
|
|
721
|
+
url = self.config.get_host() + path
|
|
722
|
+
log.debug(f"Cancel group sharing request url : {url}")
|
|
723
|
+
try:
|
|
724
|
+
response = requests.delete(url=url, headers=self.request_header,
|
|
725
|
+
params=params, verify=configmanager.CERT_FILE)
|
|
726
|
+
log.debug(f"Cancel group sharing request response : {response.text}")
|
|
727
|
+
response.raise_for_status()
|
|
728
|
+
return response.json()
|
|
729
|
+
except Exception as e:
|
|
730
|
+
log.error(f'Failed to cancel group sharing request: {e}')
|
|
731
|
+
raise
|
|
732
|
+
|
|
733
|
+
def respond_user_group_sharing_request(self, request_id, accept):
|
|
734
|
+
"""Accept or decline a group sharing request."""
|
|
735
|
+
path = 'user/node_group/sharing/requests'
|
|
736
|
+
payload = {'accept': accept, 'request_id': request_id}
|
|
737
|
+
url = self.config.get_host() + path
|
|
738
|
+
log.debug(f"Respond group sharing request url : {url}")
|
|
739
|
+
log.debug(f"Respond group sharing request payload : {json.dumps(payload)}")
|
|
740
|
+
try:
|
|
741
|
+
response = requests.put(url=url, headers=self.request_header,
|
|
742
|
+
json=payload, verify=configmanager.CERT_FILE)
|
|
743
|
+
log.debug(f"Respond group sharing response : {response.text}")
|
|
744
|
+
response.raise_for_status()
|
|
745
|
+
return response.json()
|
|
746
|
+
except Exception as e:
|
|
747
|
+
log.error(f'Failed to respond to group sharing request: {e}')
|
|
748
|
+
raise
|
|
749
|
+
|
|
602
750
|
# Automation Trigger API methods
|
|
603
751
|
|
|
604
752
|
def create_automation(self, payload):
|
|
File without changes
|
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/esp_rainmaker_cli.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/esp_rainmaker_cli.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/esp_rainmaker_cli.egg-info/requires.txt
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/esp_rainmaker_cli.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/discovery/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/security/__init__.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/security/security.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/security/security0.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/security/security1.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/security/security2.py
RENAMED
|
File without changes
|
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/transport/__init__.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/transport/ble_cli.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/transport/transport.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/transport/transport_ble.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/common/utils/convenience.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_claim/claim_config.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/esp_prov.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/integration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/raw_config.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/raw_params.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/sec0_pb2.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/sec1_pb2.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/sec2_pb2.py
RENAMED
|
File without changes
|
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_local_ctrl/session_pb2.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/challenge_response.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/config/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/esp_rainmaker_prov.py
RENAMED
|
File without changes
|
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/proto/__init__.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/protocomm/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/prov/__init__.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/prov/prov_util.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/prov/user_mapping.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/security/__init__.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/transport/__init__.py
RENAMED
|
File without changes
|
{esp_rainmaker_cli-1.13.0 → esp_rainmaker_cli-1.14.0}/rmaker_tools/rmaker_prov/utils/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|