agilicus 1.286.5__py3-none-any.whl → 1.287.1__py3-none-any.whl
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.
- agilicus/agilicus_api/api_client.py +1 -1
- agilicus/agilicus_api/configuration.py +1 -1
- agilicus/agilicus_api_README.md +1 -1
- agilicus/main.py +17 -0
- agilicus/pagination/__init__.py +0 -0
- agilicus/pagination/pagination.py +26 -9
- agilicus/pagination/pagination_test.py +93 -0
- agilicus/tokens.py +58 -0
- {agilicus-1.286.5.dist-info → agilicus-1.287.1.dist-info}/METADATA +1 -1
- {agilicus-1.286.5.dist-info → agilicus-1.287.1.dist-info}/RECORD +13 -11
- {agilicus-1.286.5.dist-info → agilicus-1.287.1.dist-info}/LICENSE.txt +0 -0
- {agilicus-1.286.5.dist-info → agilicus-1.287.1.dist-info}/WHEEL +0 -0
- {agilicus-1.286.5.dist-info → agilicus-1.287.1.dist-info}/entry_points.txt +0 -0
@@ -77,7 +77,7 @@ class ApiClient(object):
|
|
77
77
|
self.default_headers[header_name] = header_value
|
78
78
|
self.cookie = cookie
|
79
79
|
# Set default User-Agent.
|
80
|
-
self.user_agent = 'OpenAPI-Generator/1.
|
80
|
+
self.user_agent = 'OpenAPI-Generator/1.287.1/python'
|
81
81
|
|
82
82
|
def __enter__(self):
|
83
83
|
return self
|
@@ -387,7 +387,7 @@ class Configuration(object):
|
|
387
387
|
"OS: {env}\n"\
|
388
388
|
"Python Version: {pyversion}\n"\
|
389
389
|
"Version of the API: 2025.04.17\n"\
|
390
|
-
"SDK Package Version: 1.
|
390
|
+
"SDK Package Version: 1.287.1".\
|
391
391
|
format(env=sys.platform, pyversion=sys.version)
|
392
392
|
|
393
393
|
def get_host_settings(self):
|
agilicus/agilicus_api_README.md
CHANGED
@@ -4,7 +4,7 @@ Agilicus is API-first. Modern software is controlled by other software, is open,
|
|
4
4
|
The `agilicus_api` package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
5
5
|
|
6
6
|
- API version: 2025.04.17
|
7
|
-
- Package version: 1.
|
7
|
+
- Package version: 1.287.1
|
8
8
|
- Build package: org.openapitools.codegen.languages.PythonClientCodegen
|
9
9
|
For more information, please visit [https://www.agilicus.com/api](https://www.agilicus.com/api)
|
10
10
|
|
agilicus/main.py
CHANGED
@@ -5222,6 +5222,23 @@ def list_api_keys(ctx, scope, **kwargs):
|
|
5222
5222
|
output_entry(ctx, page_details)
|
5223
5223
|
|
5224
5224
|
|
5225
|
+
@cli.command(name="clean-api-keys")
|
5226
|
+
@click.option("--user-id", type=str, default=None)
|
5227
|
+
@click.option("--org-id", type=str, default=None)
|
5228
|
+
@click.option("--expires-at", type=custom_types.DateTime(), default=None)
|
5229
|
+
@click.option("--no-expiry", is_flag=True, default=None)
|
5230
|
+
@click.option("--older-than", type=custom_types.DateTime(), default=None)
|
5231
|
+
@click.pass_context
|
5232
|
+
def clear_api_keys(ctx, **kwargs):
|
5233
|
+
api_keys = tokens.clean_api_keys(ctx, **kwargs)
|
5234
|
+
if context.output_json(ctx):
|
5235
|
+
output_formatted(ctx, api_keys)
|
5236
|
+
return
|
5237
|
+
|
5238
|
+
table = tokens.format_api_keys_as_text(ctx, api_keys)
|
5239
|
+
print(table)
|
5240
|
+
|
5241
|
+
|
5225
5242
|
@cli.command(name="show-api-key-introspection")
|
5226
5243
|
@click.argument("email")
|
5227
5244
|
@click.argument("api_key")
|
File without changes
|
@@ -1,3 +1,5 @@
|
|
1
|
+
import inspect
|
2
|
+
|
1
3
|
from typing import Callable
|
2
4
|
|
3
5
|
|
@@ -7,6 +9,7 @@ def get_many_entries(
|
|
7
9
|
page_size=100,
|
8
10
|
maximum=None,
|
9
11
|
page_callback=None,
|
12
|
+
page_key="page_at_id",
|
10
13
|
**kwargs,
|
11
14
|
):
|
12
15
|
"""Implements the generic pagination strategy
|
@@ -20,25 +23,39 @@ def get_many_entries(
|
|
20
23
|
if "limit" in kwargs:
|
21
24
|
del kwargs["limit"]
|
22
25
|
kwargs["limit"] = page_size
|
23
|
-
if
|
24
|
-
kwargs[
|
26
|
+
if page_key not in kwargs:
|
27
|
+
kwargs[page_key] = ""
|
28
|
+
|
29
|
+
retval = []
|
30
|
+
|
31
|
+
def apply_page(page):
|
32
|
+
retval.extend(page)
|
33
|
+
if not page_callback:
|
34
|
+
return
|
35
|
+
if len(inspect.getfullargspec(page_callback).args) > 0:
|
36
|
+
page_callback(page=page)
|
37
|
+
return
|
38
|
+
|
39
|
+
page_callback()
|
25
40
|
|
26
41
|
list_resp = api_func(**kwargs)
|
27
|
-
|
42
|
+
page_items = list_resp.get(response_list_key) or []
|
43
|
+
apply_page(page_items)
|
44
|
+
|
28
45
|
# loop quits when the list is < the page_size
|
29
46
|
while len(list_resp.get(response_list_key, [])) >= page_size and _list_at_max_size(
|
30
47
|
len(retval), maximum
|
31
48
|
):
|
32
|
-
page_at_id = list_resp.get(
|
49
|
+
page_at_id = list_resp.get(page_key, None)
|
33
50
|
if page_at_id is None:
|
34
51
|
raise Exception(
|
35
|
-
"
|
52
|
+
f"{page_key} cannot be None for pagination to continue processing"
|
36
53
|
)
|
37
|
-
kwargs[
|
54
|
+
kwargs[page_key] = list_resp.get(page_key, None)
|
38
55
|
list_resp = api_func(**kwargs)
|
39
|
-
|
40
|
-
|
41
|
-
|
56
|
+
page_items = list_resp.get(response_list_key, [])
|
57
|
+
apply_page(page_items)
|
58
|
+
|
42
59
|
return _get_max_retval(retval, maximum)
|
43
60
|
|
44
61
|
|
@@ -0,0 +1,93 @@
|
|
1
|
+
from .pagination import get_many_entries
|
2
|
+
|
3
|
+
|
4
|
+
class fakeAPI:
|
5
|
+
def __init__(self, item_key, page_key, start_page=""):
|
6
|
+
self.item_key = item_key
|
7
|
+
self.page_key = page_key
|
8
|
+
self.pages = {}
|
9
|
+
self.next_page = start_page
|
10
|
+
|
11
|
+
def _make_page(self, items, next_page):
|
12
|
+
return {
|
13
|
+
"limit": len(items),
|
14
|
+
self.item_key: items,
|
15
|
+
self.page_key: next_page,
|
16
|
+
}
|
17
|
+
|
18
|
+
def add_page(self, items, next_page):
|
19
|
+
self.pages[self.next_page] = self._make_page(items, next_page)
|
20
|
+
|
21
|
+
self.next_page = next_page
|
22
|
+
|
23
|
+
def do_list(self, **kwargs):
|
24
|
+
page = kwargs[self.page_key]
|
25
|
+
result = self.pages.get(page)
|
26
|
+
if not result:
|
27
|
+
return self._make_page([], page)
|
28
|
+
return result
|
29
|
+
|
30
|
+
|
31
|
+
def make_test_page(items, item_key, page_key, next_page):
|
32
|
+
return {
|
33
|
+
"limit": len(items),
|
34
|
+
item_key: items,
|
35
|
+
page_key: next_page,
|
36
|
+
}
|
37
|
+
|
38
|
+
|
39
|
+
def test_get_many_entries_gets_all():
|
40
|
+
api = fakeAPI("items", "page_at_id")
|
41
|
+
api.add_page([10, 8, 6], 6)
|
42
|
+
api.add_page([4, 3, 2], 2)
|
43
|
+
api.add_page([1, 0], 0)
|
44
|
+
|
45
|
+
result = get_many_entries(api.do_list, api.item_key, page_size=3)
|
46
|
+
assert [10, 8, 6, 4, 3, 2, 1, 0] == result
|
47
|
+
|
48
|
+
|
49
|
+
def test_get_many_entries_limits_to_max():
|
50
|
+
api = fakeAPI("items", "page_at_id")
|
51
|
+
api.add_page([10, 8, 6], 6)
|
52
|
+
api.add_page([4, 3, 2], 2)
|
53
|
+
api.add_page([1, 0], 0)
|
54
|
+
|
55
|
+
result = get_many_entries(api.do_list, api.item_key, page_size=3, maximum=4)
|
56
|
+
assert [10, 8, 6, 4] == result
|
57
|
+
|
58
|
+
|
59
|
+
def test_get_many_entries_invokes_callback():
|
60
|
+
api = fakeAPI("items", "page_at_id")
|
61
|
+
api.add_page([10, 8, 6], 6)
|
62
|
+
api.add_page([4, 3, 2], 2)
|
63
|
+
api.add_page([1, 0], 0)
|
64
|
+
|
65
|
+
calls = []
|
66
|
+
|
67
|
+
def callback():
|
68
|
+
calls.append(None)
|
69
|
+
|
70
|
+
result = get_many_entries(
|
71
|
+
api.do_list, api.item_key, page_size=3, page_callback=callback
|
72
|
+
)
|
73
|
+
assert [10, 8, 6, 4, 3, 2, 1, 0] == result
|
74
|
+
assert len(calls) == 3
|
75
|
+
|
76
|
+
|
77
|
+
def test_get_many_entries_invokes_callback_with_page():
|
78
|
+
api = fakeAPI("items", "page_at_id")
|
79
|
+
api.add_page([10, 8, 6], 6)
|
80
|
+
api.add_page([4, 3, 2], 2)
|
81
|
+
api.add_page([1, 0], 0)
|
82
|
+
|
83
|
+
calls = []
|
84
|
+
|
85
|
+
def callback(page):
|
86
|
+
calls.append(page)
|
87
|
+
|
88
|
+
result = get_many_entries(
|
89
|
+
api.do_list, api.item_key, page_size=3, page_callback=callback
|
90
|
+
)
|
91
|
+
assert [10, 8, 6, 4, 3, 2, 1, 0] == result
|
92
|
+
|
93
|
+
assert [[10, 8, 6], [4, 3, 2], [1, 0]] == calls
|
agilicus/tokens.py
CHANGED
@@ -3,6 +3,7 @@ import json
|
|
3
3
|
import urllib.parse
|
4
4
|
import datetime
|
5
5
|
import jwt
|
6
|
+
import sys
|
6
7
|
|
7
8
|
import requests
|
8
9
|
import agilicus
|
@@ -13,6 +14,7 @@ from .input_helpers import get_user_id_from_input_or_ctx
|
|
13
14
|
from .input_helpers import build_updated_model
|
14
15
|
from .input_helpers import strip_none
|
15
16
|
from .input_helpers import update_if_present
|
17
|
+
from .pagination import pagination
|
16
18
|
|
17
19
|
from .output import output_if_console
|
18
20
|
|
@@ -595,3 +597,59 @@ def update_session_challenge(ctx, token=None):
|
|
595
597
|
apiclient = context.get_apiclient_from_ctx(ctx, token=token)
|
596
598
|
body = agilicus.SessionChallenge()
|
597
599
|
return apiclient.tokens_api.update_session_challenge(body)
|
600
|
+
|
601
|
+
|
602
|
+
def clean_api_keys(
|
603
|
+
ctx, expires_at=None, no_expiry=False, older_than=None, max_failures=5, **kwargs
|
604
|
+
):
|
605
|
+
apiclient = context.get_apiclient_from_ctx(ctx)
|
606
|
+
update_org_from_input_or_ctx(kwargs, ctx, **kwargs)
|
607
|
+
kwargs["user_id"] = get_user_id_from_input_or_ctx(ctx, **kwargs)
|
608
|
+
kwargs = strip_none(kwargs)
|
609
|
+
to_delete = []
|
610
|
+
|
611
|
+
def should_delete(api_key):
|
612
|
+
if older_than is not None and api_key.metadata.created >= older_than:
|
613
|
+
return False
|
614
|
+
|
615
|
+
if api_key.spec.expiry is None:
|
616
|
+
return no_expiry
|
617
|
+
|
618
|
+
if expires_at is not None:
|
619
|
+
return api_key.spec.expiry < expires_at
|
620
|
+
|
621
|
+
return False
|
622
|
+
|
623
|
+
def deleter(page: list):
|
624
|
+
for api_key in page:
|
625
|
+
if should_delete(api_key):
|
626
|
+
to_delete.append(api_key)
|
627
|
+
|
628
|
+
pagination.get_many_entries(
|
629
|
+
apiclient.tokens_api.list_api_keys,
|
630
|
+
"api_keys",
|
631
|
+
100,
|
632
|
+
None,
|
633
|
+
page_callback=deleter,
|
634
|
+
page_key="page_at_created_date",
|
635
|
+
page_at_created_date=None,
|
636
|
+
sort_order="descending",
|
637
|
+
search_direction="forwards",
|
638
|
+
**kwargs,
|
639
|
+
)
|
640
|
+
failures = 0
|
641
|
+
deleted = []
|
642
|
+
for key in to_delete:
|
643
|
+
token_id = key.metadata.id
|
644
|
+
org_id = key.spec.org_id
|
645
|
+
try:
|
646
|
+
apiclient.tokens_api.delete_api_key(token_id, org_id=org_id)
|
647
|
+
except Exception as exc:
|
648
|
+
print(f"failed deleting {token_id}: {exc}", file=sys.stderr)
|
649
|
+
failures += 1
|
650
|
+
if failures >= max_failures:
|
651
|
+
print("too many failures. Exiting early", file=sys.stderr)
|
652
|
+
return
|
653
|
+
deleted.append(key)
|
654
|
+
|
655
|
+
return deleted
|
@@ -71,9 +71,9 @@ agilicus/agilicus_api/api/users_api.py,sha256=vc1a6U7o4Pg_2A_FjPVIpiyRTIREZ58jpt
|
|
71
71
|
agilicus/agilicus_api/api/users_api_mock.py,sha256=aMSUc12JQAo1O9rp2YnyQldANFGlfi57fMnQyCIrJuE,17209
|
72
72
|
agilicus/agilicus_api/api/whoami_api.py,sha256=RNGWCYPit1iT7qrxDdOzyIKJkIdMuDryyKVmoxeg0qI,7941
|
73
73
|
agilicus/agilicus_api/api/whoami_api_mock.py,sha256=rlvZoWnMCqORMZBg7SOv6d3xp52kELdh6wXcCaIZ93w,346
|
74
|
-
agilicus/agilicus_api/api_client.py,sha256=
|
74
|
+
agilicus/agilicus_api/api_client.py,sha256=WZ4wYE6o-RY7hhg_bhPGA2qPI_k-qvyuuTaI5Vjqejs,38845
|
75
75
|
agilicus/agilicus_api/apis/__init__.py,sha256=aJZD7x-umdSni6ZBr4XxzpH8pwtU9hA5LlCDxcqa1Q8,2224
|
76
|
-
agilicus/agilicus_api/configuration.py,sha256=
|
76
|
+
agilicus/agilicus_api/configuration.py,sha256=6gnetAAoozBXZHwaunB0P2fotR1u0uKZ2rX39-Oh6zU,18447
|
77
77
|
agilicus/agilicus_api/docs/APIKey.md,sha256=4cKuz4_l9HcEDnUrLwYbEnn9C2WoDayrjfrY1Ixgaf4,1747
|
78
78
|
agilicus/agilicus_api/docs/APIKeyIntrospect.md,sha256=nJ-zkuFm3JMbWFDYYN_vYyQk1snGBtBvIxtCQxamhAU,1019
|
79
79
|
agilicus/agilicus_api/docs/APIKeyIntrospectAuthorizationInfo.md,sha256=7RApOOLjvWQs5sw2jb25g7i3Kta1BiEY-s8VRXfppH8,725
|
@@ -2667,7 +2667,7 @@ agilicus/agilicus_api/test/test_x509_root_certificate.py,sha256=LV5_rQa2jhob7DzH
|
|
2667
2667
|
agilicus/agilicus_api/test/test_x509_root_certificate_spec.py,sha256=_csieI3dVbNe1oyoXCMPytlRUkatdg3rqVHNUASODf0,2832
|
2668
2668
|
agilicus/agilicus_api/test/test_x509_root_certificate_status.py,sha256=0vDt4PephnpGCV7pw8JSOcvJ9ifukwyE5zYlFFF-Z7c,2846
|
2669
2669
|
agilicus/agilicus_api/test/test_xss_settings.py,sha256=naM6PzbbiE5gF030lL5Ci5zfFcT-CVJzYZdMS9UNM8A,2746
|
2670
|
-
agilicus/agilicus_api_README.md,sha256
|
2670
|
+
agilicus/agilicus_api_README.md,sha256=-Z5nxFclI4EfIcyfDgZNGDTuuWhpFN2yX2abQipR11M,171736
|
2671
2671
|
agilicus/aliases.ini,sha256=MxqiVo2f2xdUDVF1YDkNW36AIqN8hrYjlTVfraEUZXY,455
|
2672
2672
|
agilicus/amq.py,sha256=yxi-YTbJPVl10s78Hlr1dmrQR63iaSIoROGVILzFPmE,1775
|
2673
2673
|
agilicus/apps.py,sha256=Mdc_pRXyfa-IvIFH7gNbx0Ob64gUHggZyeSyLUDpjMs,54048
|
@@ -2722,7 +2722,7 @@ agilicus/labels/labels_main.py,sha256=l2z_41X3sMJoSM483LmAzJE6bKKHVAEvrPjfz7QvFg
|
|
2722
2722
|
agilicus/launchers.py,sha256=r4nctnVtfP-Ho_HXEfAiMaMqJI0u7pbieHSS3Vd0QBE,11361
|
2723
2723
|
agilicus/logs.py,sha256=Y4XVcLctY-2O-Q_CXbJs9sAqu0NknHKSsqilKiDM_A0,804
|
2724
2724
|
agilicus/lookups.py,sha256=MNmNsKpP7Fq_poLAnL9xo_iptFilKM9ziGLyIe8VKaw,669
|
2725
|
-
agilicus/main.py,sha256=
|
2725
|
+
agilicus/main.py,sha256=PvQ_Hmmy4qI83q0_7PeGECHm01Xhbq5qo8nKHQyV8rs,289990
|
2726
2726
|
agilicus/messages/__init__.py,sha256=cVqfaKUndO-AYfppkdFICM5WvYFFB1hRjXihFWmiGPQ,174
|
2727
2727
|
agilicus/messages/messages.py,sha256=b2eO6BaWI9UZTLETcdy1NotyuNlKIJf6CS_TUzehuk4,9175
|
2728
2728
|
agilicus/messages/messages_main.py,sha256=A0xucYwwUZFIuUc0bAyAqVwofErakmyawq5bwhZKcOU,1598
|
@@ -2735,7 +2735,9 @@ agilicus/output/json.py,sha256=-5bX7ud1hIxux4l3P-K2gJXrE2gdZ0Ua1hfUOCX9MUM,899
|
|
2735
2735
|
agilicus/output/table.py,sha256=o5kYgAtIAhei4ex7YZrTK9tDVarJQHzF2Yj42TXt21g,8744
|
2736
2736
|
agilicus/output/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2737
2737
|
agilicus/output/tests/column_builder_test.py,sha256=fKP4V5sqXtmEIr-Q0gWVSFdBqCUtugZkP6G5gML_T7I,2130
|
2738
|
-
agilicus/pagination/
|
2738
|
+
agilicus/pagination/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2739
|
+
agilicus/pagination/pagination.py,sha256=4OcBy0kC7J4r3ofEBrYX4ZvCoDpUXTSxHHpsuVwPTJs,1970
|
2740
|
+
agilicus/pagination/pagination_test.py,sha256=f28x57SoBz9xGp8Go1k-77Fvzbz9c2HPVeNlxkNcsK8,2409
|
2739
2741
|
agilicus/patches.py,sha256=qTqLOgCAcFZPcPOkgfqMnK9bnqTXMvj_0ERsjRFcZug,1384
|
2740
2742
|
agilicus/permissions.py,sha256=uB65yuDFICp1N10m0cdUjgizx9MQzAbLbAsBSTw1Rcc,2117
|
2741
2743
|
agilicus/policy/policies.py,sha256=eAy1iRlYKvkuc-10ssw_iuchY-I24LvtHiruvyzo5Pg,11440
|
@@ -2760,15 +2762,15 @@ agilicus/ssh.py,sha256=mVqMlDM2zAcUphehyz9djXjrRPSIxR1qJr2Ehvl3Rvw,2925
|
|
2760
2762
|
agilicus/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2761
2763
|
agilicus/tests/keyring_test.py,sha256=Uwp2VS2_NffYBgHAS9bXuXnIxRoK0_VOWaaYCZKv0lg,1452
|
2762
2764
|
agilicus/tests/test_pop_utils.py,sha256=gdSMOmE0pNSDA0UgUWdbLKpFzUGwfBwkFSrk1p1JdSo,1083
|
2763
|
-
agilicus/tokens.py,sha256=
|
2765
|
+
agilicus/tokens.py,sha256=0zckgaZxYF8PFNBhUnV6yrrmVGru3dmh1qSH6YZQhsE,20515
|
2764
2766
|
agilicus/transfers.py,sha256=PYr_fW7dyXNUXzi5Wp5mUjZOvU7MbRzoN-D8Omo-YSQ,1523
|
2765
2767
|
agilicus/trusted_certs/trusted_certs.py,sha256=HCAvYxOA3ooaee2_KbYJd6Yt_dxDEn8hjhy1upVJUYE,7951
|
2766
2768
|
agilicus/trusted_certs/trusted_certs_main.py,sha256=6dHHWXvNIcUa_nA9ptigL4Vibe4nB2wnWFTTJ8AOgXo,5155
|
2767
2769
|
agilicus/users.py,sha256=bUFtVlTjUeEoQlzsQcfS8ChN0X9mbHs8v0xbkK-cldQ,41772
|
2768
2770
|
agilicus/version.py,sha256=G9OFdL1v_4dLDfk6I6taDNypM5bbO-JHAwilsu9LYgg,23
|
2769
2771
|
agilicus/whoami.py,sha256=kqghtWMgZOd2rhKmfguDwCTm6A3gNS8Kj-S2IBxBtl0,206
|
2770
|
-
agilicus-1.
|
2771
|
-
agilicus-1.
|
2772
|
-
agilicus-1.
|
2773
|
-
agilicus-1.
|
2774
|
-
agilicus-1.
|
2772
|
+
agilicus-1.287.1.dist-info/LICENSE.txt,sha256=Zq4tqiCroC2CVrBB_PWjapRdvpae23nljdiaSkOzUho,1061
|
2773
|
+
agilicus-1.287.1.dist-info/METADATA,sha256=PWk0MyfBdFFkjNo85KaMnBDwOc8YrmDPkfeJCjGTINw,3878
|
2774
|
+
agilicus-1.287.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
2775
|
+
agilicus-1.287.1.dist-info/entry_points.txt,sha256=a66hGozzLkHu0IewFzIMbSAhMTNTddUaA2T3_16Gb_s,51
|
2776
|
+
agilicus-1.287.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|