Skip to content

Commit ec2193c

Browse files
authored
feat: implemented new Policy Exceptions API endpoint (#85)
* feat: implemented new Policy Exceptions API endpoint * docs: updated docs for new endpoint
1 parent 91095c3 commit ec2193c

File tree

10 files changed

+1542
-431
lines changed

10 files changed

+1542
-431
lines changed

docs/laceworksdk/api.html

Lines changed: 405 additions & 401 deletions
Large diffs are not rendered by default.

docs/laceworksdk/api/crud_endpoint.html

Lines changed: 21 additions & 21 deletions
Large diffs are not rendered by default.

docs/laceworksdk/api/v2.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ <h2>Submodules</h2>
4949
<li><a href="v2/inventory.html">inventory</a></li>
5050
<li><a href="v2/organization_info.html">organization_info</a></li>
5151
<li><a href="v2/policies.html">policies</a></li>
52+
<li><a href="v2/policy_exceptions.html">policy_exceptions</a></li>
5253
<li><a href="v2/queries.html">queries</a></li>
5354
<li><a href="v2/report_definitions.html">report_definitions</a></li>
5455
<li><a href="v2/report_rules.html">report_rules</a></li>

docs/laceworksdk/api/v2/policy_exceptions.html

Lines changed: 869 additions & 0 deletions
Large diffs are not rendered by default.

docs/laceworksdk/version.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ <h1 class="modulename">
5151
<div class="pdoc-code codehilite"><pre><span></span><span id="L-1"><a href="#L-1"><span class="linenos">1</span></a><span class="c1"># coding: utf-8</span>
5252
</span><span id="L-2"><a href="#L-2"><span class="linenos">2</span></a><span class="c1"># file generated by setuptools_scm</span>
5353
</span><span id="L-3"><a href="#L-3"><span class="linenos">3</span></a><span class="c1"># don&#39;t change, don&#39;t track in version control</span>
54-
</span><span id="L-4"><a href="#L-4"><span class="linenos">4</span></a><span class="n">version</span> <span class="o">=</span> <span class="s1">&#39;1.0.1.dev1+gfd44171.d20220203&#39;</span>
55-
</span><span id="L-5"><a href="#L-5"><span class="linenos">5</span></a><span class="n">version_tuple</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;dev1&#39;</span><span class="p">,</span> <span class="s1">&#39;gfd44171.d20220203&#39;</span><span class="p">)</span>
54+
</span><span id="L-4"><a href="#L-4"><span class="linenos">4</span></a><span class="n">version</span> <span class="o">=</span> <span class="s1">&#39;1.6.0&#39;</span>
55+
</span><span id="L-5"><a href="#L-5"><span class="linenos">5</span></a><span class="n">version_tuple</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;dev1&#39;</span><span class="p">,</span> <span class="s1">&#39;gb2da4df&#39;</span><span class="p">)</span>
5656
</span></pre></div>
5757

5858

docs/search.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

laceworksdk/api/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
from .v2.inventory import InventoryAPI
4040
from .v2.organization_info import OrganizationInfoAPI
4141
from .v2.policies import PoliciesAPI
42+
from .v2.policy_exceptions import PolicyExceptionsAPI
4243
from .v2.queries import QueriesAPI
4344
from .v2.report_definitions import ReportDefinitionsAPI
4445
from .v2.report_rules import ReportRulesAPI
@@ -160,6 +161,7 @@ def __init__(self,
160161
self.integrations = IntegrationsAPI(self._session)
161162
self.organization_info = OrganizationInfoAPI(self._session)
162163
self.policies = PoliciesAPI(self._session)
164+
self.policy_exceptions = PolicyExceptionsAPI(self._session)
163165
self.queries = QueriesAPI(self._session)
164166
self.recommendations = RecommendationsAPI(self._session)
165167
self.report_definitions = ReportDefinitionsAPI(self._session)

laceworksdk/api/crud_endpoint.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def __init__(self,
2020

2121
super().__init__(session, object_type, endpoint_root)
2222

23-
def create(self, **request_params):
23+
def create(self, params=None, **request_params):
2424
"""
2525
A method to create a new object.
2626
@@ -33,7 +33,7 @@ def create(self, **request_params):
3333
request_params
3434
)
3535

36-
response = self._session.post(self.build_url(), json=json)
36+
response = self._session.post(self.build_url(), json=json, params=params)
3737

3838
return response.json()
3939

@@ -70,7 +70,7 @@ def search(self, json=None, **kwargs):
7070

7171
return response.json()
7272

73-
def update(self, id=None, **request_params):
73+
def update(self, id=None, params=None, **request_params):
7474
"""
7575
A method to update an object.
7676
@@ -84,11 +84,11 @@ def update(self, id=None, **request_params):
8484
request_params
8585
)
8686

87-
response = self._session.patch(self.build_url(id=id), json=json)
87+
response = self._session.patch(self.build_url(id=id), json=json, params=params)
8888

8989
return response.json()
9090

91-
def delete(self, id):
91+
def delete(self, id, params=None):
9292
"""
9393
A method to delete an object.
9494
@@ -97,7 +97,7 @@ def delete(self, id):
9797
:return response json
9898
"""
9999

100-
response = self._session.delete(self.build_url(id=id))
100+
response = self._session.delete(self.build_url(id=id), params=params)
101101

102102
return response
103103

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Lacework Exceptions API wrapper.
4+
"""
5+
6+
from laceworksdk.api.crud_endpoint import CrudEndpoint
7+
8+
9+
class PolicyExceptionsAPI(CrudEndpoint):
10+
11+
def __init__(self, session):
12+
"""
13+
Initializes the PolicyExceptionsAPI object.
14+
15+
:param session: An instance of the HttpSession class
16+
17+
:return PolicyExceptionsAPI object.
18+
"""
19+
20+
super().__init__(session, "Exceptions")
21+
22+
def create(self,
23+
policy_id,
24+
description,
25+
constraints,
26+
**request_params):
27+
"""
28+
A method to create a new Exceptions object.
29+
30+
:param policy_id: A string representing the object policy ID.
31+
:param description: A string representing the object description.
32+
:param constraints: A string representing the object contraints.
33+
:obj
34+
:param field_key: A string representing the contraint key
35+
('accountIds', 'resourceNames', 'regionNames' and 'resourceTags')
36+
:param field_values: An array of strings representing constraint values
37+
:param request_params: Additional request parameters.
38+
(provides support for parameters that may be added in the future)
39+
40+
:return response json
41+
"""
42+
43+
params = self.build_dict_from_items(
44+
policy_id=policy_id
45+
)
46+
47+
return super().create(
48+
params=params,
49+
description=description,
50+
constraints=constraints,
51+
**request_params
52+
)
53+
54+
def get(self,
55+
exception_id=None,
56+
policy_id=None):
57+
"""
58+
A method to get Exceptions objects.
59+
60+
:param exception_id: A string representing the exception ID.
61+
:param policy_id: A string representing the object policy ID.
62+
63+
:return response json
64+
"""
65+
66+
return super().get(id=exception_id, policy_id=policy_id)
67+
68+
def get_by_id(self,
69+
exception_id,
70+
policy_id):
71+
"""
72+
A method to get a Exceptions object by policy ID.
73+
74+
:param exception_id: A string representing the exception ID.
75+
:param policy_id: A string representing the object policy ID.
76+
77+
:return response json
78+
"""
79+
80+
return self.get(
81+
exception_id=exception_id,
82+
policy_id=policy_id
83+
)
84+
85+
def update(self,
86+
exception_id,
87+
policy_id,
88+
description=None,
89+
constraints=None,
90+
**request_params):
91+
"""
92+
A method to create a new Exceptions object.
93+
94+
:param exception_id: A string representing the exception ID.
95+
:param policy_id: A string representing the object policy ID.
96+
:param description: A string representing the object description.
97+
:param constraints: A string representing the object contraints.
98+
:obj
99+
:param field_key: A string representing the contraint key
100+
('accountIds', 'resourceNames', 'regionNames' and 'resourceTags')
101+
:param field_values: An array of strings representing constraint values
102+
:param request_params: Additional request parameters.
103+
(provides support for parameters that may be added in the future)
104+
105+
:return response json
106+
"""
107+
108+
params = self.build_dict_from_items(
109+
policy_id=policy_id
110+
)
111+
112+
return super().update(
113+
id=exception_id,
114+
params=params,
115+
description=description,
116+
constraints=constraints,
117+
**request_params
118+
)
119+
120+
def delete(self,
121+
exception_id,
122+
policy_id):
123+
"""
124+
A method to delete an Exceptions object.
125+
126+
:param exception_id: A string representing the exception ID.
127+
:param policy_id: A string representing the object policy ID.
128+
129+
:return response json
130+
"""
131+
132+
params = self.build_dict_from_items(
133+
policy_id=policy_id
134+
)
135+
136+
return super().delete(id=exception_id, params=params)
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Test suite for the community-developed Python SDK for interacting with Lacework APIs.
4+
"""
5+
6+
import pytest
7+
8+
from laceworksdk.api.v2.policy_exceptions import PolicyExceptionsAPI
9+
from tests.api.test_crud_endpoint import CrudEndpoint
10+
11+
12+
# Tests
13+
14+
@pytest.fixture(scope="module")
15+
def api_object(api):
16+
return api.policy_exceptions
17+
18+
19+
@pytest.fixture(scope="module")
20+
def policy_id():
21+
return "lacework-global-270"
22+
23+
24+
@pytest.fixture(scope="module")
25+
def api_object_create_body(random_text):
26+
return {
27+
"description": f"Test Policy Exception {random_text}",
28+
"constraints": [
29+
{
30+
"fieldKey": "resourceLabel",
31+
"fieldValues": [
32+
{"key": "TestKey", "value": "TestValue"}
33+
]
34+
}
35+
]
36+
}
37+
38+
39+
@pytest.fixture(scope="module")
40+
def api_object_update_body(random_text):
41+
return {
42+
"description": f"Test Policy Exception {random_text} (Updated)",
43+
"constraints": [
44+
{
45+
"fieldKey": "resourceLabel",
46+
"fieldValues": []
47+
}
48+
]
49+
}
50+
51+
52+
class TestPolicyExceptions(CrudEndpoint):
53+
54+
OBJECT_ID_NAME = "exceptionId"
55+
OBJECT_TYPE = PolicyExceptionsAPI
56+
57+
def test_api_get(self, api_object, policy_id):
58+
response = api_object.get(policy_id=policy_id)
59+
60+
assert "data" in response.keys()
61+
62+
def test_api_create(self, api_object, policy_id, api_object_create_body, request):
63+
response = api_object.create(policy_id, **api_object_create_body)
64+
65+
assert "data" in response.keys()
66+
self._check_object_values(api_object_create_body, response)
67+
68+
request.config.cache.set(self.OBJECT_ID_NAME, response["data"][self.OBJECT_ID_NAME])
69+
70+
def test_api_get_by_guid(self, api_object, policy_id, request):
71+
guid = request.config.cache.get(self.OBJECT_ID_NAME, None)
72+
assert guid is not None
73+
if guid:
74+
response = api_object.get(guid, policy_id)
75+
assert "data" in response.keys()
76+
77+
def test_api_search(self):
78+
pass
79+
80+
def test_api_update(self, api_object, policy_id, api_object_update_body, request):
81+
guid = request.config.cache.get(self.OBJECT_ID_NAME, None)
82+
83+
if guid is None:
84+
guid = self._get_random_object(api_object, self.OBJECT_ID_NAME)
85+
86+
assert guid is not None
87+
if guid:
88+
response = api_object.update(guid, policy_id, **api_object_update_body)
89+
90+
assert "data" in response.keys()
91+
92+
self._check_object_values(api_object_update_body, response)
93+
94+
def test_api_delete(self, api_object, policy_id, request):
95+
guid = request.config.cache.get(self.OBJECT_ID_NAME, None)
96+
assert guid is not None
97+
if guid:
98+
response = api_object.delete(guid, policy_id)
99+
assert response.status_code == 204

0 commit comments

Comments
 (0)