Skip to content

Commit 57a0095

Browse files
authored
feat: add support for is_default flag on policy collections (ENG-2684) (#34)
* feat: add support for is_default flag on policy collecitons * Add explicit flags for including default collections / policies for projects * Fix tests
1 parent a21efef commit 57a0095

File tree

6 files changed

+182
-29
lines changed

6 files changed

+182
-29
lines changed

scripts/openapi.json

Lines changed: 131 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -424,8 +424,20 @@
424424
"Policy Collections"
425425
],
426426
"summary": "List",
427-
"description": "List all policy collections",
427+
"description": "List all (or just defaults) policy collections",
428428
"operationId": "get_policy_collections_policy_collections_get",
429+
"parameters": [
430+
{
431+
"required": false,
432+
"schema": {
433+
"title": "Only Defaults",
434+
"type": "boolean",
435+
"default": false
436+
},
437+
"name": "only_defaults",
438+
"in": "query"
439+
}
440+
],
429441
"responses": {
430442
"200": {
431443
"description": "Successful Response",
@@ -440,6 +452,16 @@
440452
}
441453
}
442454
}
455+
},
456+
"422": {
457+
"description": "Validation Error",
458+
"content": {
459+
"application/json": {
460+
"schema": {
461+
"$ref": "#/components/schemas/HTTPValidationError"
462+
}
463+
}
464+
}
443465
}
444466
}
445467
},
@@ -564,6 +586,54 @@
564586
}
565587
}
566588
}
589+
},
590+
"patch": {
591+
"tags": [
592+
"Policy Collections"
593+
],
594+
"summary": "Update",
595+
"operationId": "update_policy_collection_policy_collections__name__patch",
596+
"parameters": [
597+
{
598+
"required": true,
599+
"schema": {
600+
"title": "Name",
601+
"type": "string"
602+
},
603+
"name": "name",
604+
"in": "path"
605+
}
606+
],
607+
"requestBody": {
608+
"content": {
609+
"application/json": {
610+
"schema": {
611+
"$ref": "#/components/schemas/UpdatePolicyCollectionInput"
612+
}
613+
}
614+
},
615+
"required": true
616+
},
617+
"responses": {
618+
"200": {
619+
"description": "Successful Response",
620+
"content": {
621+
"application/json": {
622+
"schema": {}
623+
}
624+
}
625+
},
626+
"422": {
627+
"description": "Validation Error",
628+
"content": {
629+
"application/json": {
630+
"schema": {
631+
"$ref": "#/components/schemas/HTTPValidationError"
632+
}
633+
}
634+
}
635+
}
636+
}
567637
}
568638
},
569639
"/policy-collections/{name}/policies": {
@@ -1209,6 +1279,16 @@
12091279
},
12101280
"name": "name",
12111281
"in": "path"
1282+
},
1283+
{
1284+
"required": false,
1285+
"schema": {
1286+
"title": "Include Default Collections",
1287+
"type": "boolean",
1288+
"default": false
1289+
},
1290+
"name": "include_default_collections",
1291+
"in": "query"
12121292
}
12131293
],
12141294
"responses": {
@@ -1357,6 +1437,16 @@
13571437
},
13581438
"name": "name",
13591439
"in": "path"
1440+
},
1441+
{
1442+
"required": false,
1443+
"schema": {
1444+
"title": "Include Defaults",
1445+
"type": "boolean",
1446+
"default": false
1447+
},
1448+
"name": "include_defaults",
1449+
"in": "query"
13601450
}
13611451
],
13621452
"responses": {
@@ -1522,6 +1612,16 @@
15221612
},
15231613
"name": "name",
15241614
"in": "path"
1615+
},
1616+
{
1617+
"required": false,
1618+
"schema": {
1619+
"title": "Include Defaults",
1620+
"type": "boolean",
1621+
"default": false
1622+
},
1623+
"name": "include_defaults",
1624+
"in": "query"
15251625
}
15261626
],
15271627
"responses": {
@@ -2082,6 +2182,11 @@
20822182
},
20832183
"default": []
20842184
},
2185+
"is_default": {
2186+
"title": "Is Default",
2187+
"type": "boolean",
2188+
"default": false
2189+
},
20852190
"created_at": {
20862191
"title": "Created At",
20872192
"type": "string",
@@ -2114,6 +2219,11 @@
21142219
"type": "string"
21152220
},
21162221
"default": []
2222+
},
2223+
"is_default": {
2224+
"title": "Is Default",
2225+
"type": "boolean",
2226+
"default": false
21172227
}
21182228
}
21192229
},
@@ -2194,7 +2304,7 @@
21942304
"added": 0,
21952305
"updated": 0,
21962306
"removed": 0,
2197-
"started_at": "2023-10-11T21:35:58.971771"
2307+
"started_at": "2023-10-13T19:14:36.359196"
21982308
}
21992309
}
22002310
}
@@ -2320,7 +2430,7 @@
23202430
"added": 0,
23212431
"updated": 0,
23222432
"removed": 0,
2323-
"started_at": "2023-10-11T21:35:58.971291"
2433+
"started_at": "2023-10-13T19:14:36.358730"
23242434
}
23252435
}
23262436
}
@@ -2896,6 +3006,24 @@
28963006
}
28973007
}
28983008
},
3009+
"UpdatePolicyCollectionInput": {
3010+
"title": "UpdatePolicyCollectionInput",
3011+
"type": "object",
3012+
"properties": {
3013+
"is_default": {
3014+
"title": "Is Default",
3015+
"type": "boolean"
3016+
},
3017+
"policies": {
3018+
"title": "Policies",
3019+
"uniqueItems": true,
3020+
"type": "array",
3021+
"items": {
3022+
"type": "string"
3023+
}
3024+
}
3025+
}
3026+
},
28993027
"UpdatePolicySource": {
29003028
"title": "UpdatePolicySource",
29013029
"type": "object",

stacklet/client/sinistral/commands/policy_collections.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ class PolicyCollections(Client):
1717
@PolicyCollections.commands.register("list")
1818
class List(ClientCommand):
1919
"""
20-
List all policy collections
20+
List all (or just defaults) policy collections
2121
"""
2222

2323
command = "list"
2424
method = "get"
2525
path = "/policy-collections"
2626
params = {}
27-
query_params = {}
27+
query_params = {"--only_defaults": {"required": False}}
2828
payload_params = {}
2929

3030

@@ -53,6 +53,11 @@ class Create(ClientCommand):
5353
"items": {"type": "string"},
5454
"default": [],
5555
},
56+
"is_default": {
57+
"title": "Is Default",
58+
"type": "boolean",
59+
"default": False,
60+
},
5661
},
5762
}
5863
}
@@ -86,6 +91,34 @@ class Delete(ClientCommand):
8691
payload_params = {}
8792

8893

94+
@PolicyCollections.commands.register("update")
95+
class Update(ClientCommand):
96+
"""
97+
None
98+
"""
99+
100+
command = "update"
101+
method = "patch"
102+
path = "/policy-collections/{name}"
103+
params = {"--name": {"required": True}}
104+
query_params = {}
105+
payload_params = {
106+
"schema": {
107+
"title": "UpdatePolicyCollectionInput",
108+
"type": "object",
109+
"properties": {
110+
"is_default": {"title": "Is Default", "type": "boolean"},
111+
"policies": {
112+
"title": "Policies",
113+
"uniqueItems": True,
114+
"type": "array",
115+
"items": {"type": "string"},
116+
},
117+
},
118+
}
119+
}
120+
121+
89122
@PolicyCollections.commands.register("get-policies")
90123
class GetPolicies(ClientCommand):
91124
"""

stacklet/client/sinistral/commands/projects.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class Get(ClientCommand):
7979
method = "get"
8080
path = "/projects/{name}"
8181
params = {"--name": {"required": True}}
82-
query_params = {}
82+
query_params = {"--include_default_collections": {"required": False}}
8383
payload_params = {}
8484

8585

@@ -146,7 +146,7 @@ class GetCollections(ClientCommand):
146146
method = "get"
147147
path = "/projects/{name}/collections"
148148
params = {"--name": {"required": True}}
149-
query_params = {}
149+
query_params = {"--include_defaults": {"required": False}}
150150
payload_params = {}
151151

152152

@@ -203,7 +203,7 @@ class GetPolicies(ClientCommand):
203203
method = "get"
204204
path = "/projects/{name}/policies"
205205
params = {"--name": {"required": True}}
206-
query_params = {}
206+
query_params = {"--include_defaults": {"required": False}}
207207
payload_params = {}
208208

209209

stacklet/client/sinistral/commands/run.py

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -76,26 +76,21 @@ def run(ctx, project, dryrun, *args, **kwargs):
7676
sinistral = sinistral_client()
7777

7878
projects_client = sinistral.client("projects")
79-
policy_collections_client = sinistral.client("policy-collections")
80-
81-
results = []
8279
try:
83-
project_data = projects_client.get(name=project)
80+
policies = projects_client.get_policies(name=project, include_defaults=True)
8481
except Exception as e:
8582
click.echo(f"Unable to get project: {e}", err=True)
8683
sys.exit(1)
8784

88-
if not project_data.get("collections"):
85+
if not policies:
8986
click.echo("Project has no policy collections", err=True)
9087
sys.exit(1)
9188

92-
for c in project_data["collections"]:
93-
policies = policy_collections_client.get_policies(name=c)
94-
raw_policies = [p["raw_policy"] for p in policies]
95-
with TemporaryDirectory() as tempdir:
96-
with open(f"{tempdir}/policy.yaml", "w+") as f:
97-
yaml.dump({"policies": raw_policies}, f)
98-
ctx.params["policy_dir"] = tempdir
99-
results.append(int(left_run.invoke(ctx)))
100-
89+
raw_policies = [p["raw_policy"] for p in policies]
90+
results = []
91+
with TemporaryDirectory() as tempdir:
92+
with open(f"{tempdir}/policy.yaml", "w+") as f:
93+
yaml.dump({"policies": raw_policies}, f)
94+
ctx.params["policy_dir"] = tempdir
95+
results.append(int(left_run.invoke(ctx)))
10196
sys.exit(int(sorted(results)[-1]))

tests/test_run.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77

88

99
from .utils import (
10-
get_project_response,
11-
get_policies_for_collection_response,
10+
get_policies_for_project_response,
1211
create_scan_response,
1312
get_mock_response,
1413
)
@@ -33,8 +32,7 @@ def test_submit_run():
3332
RestExecutor,
3433
"get",
3534
side_effect=[
36-
get_mock_response(json=get_project_response),
37-
get_mock_response(json=get_policies_for_collection_response),
35+
get_mock_response(json=get_policies_for_project_response),
3836
],
3937
):
4038
with patch.object(
@@ -68,8 +66,7 @@ def test_submit_run_fail():
6866
RestExecutor,
6967
"get",
7068
side_effect=[
71-
get_mock_response(json=get_project_response),
72-
get_mock_response(json=get_policies_for_collection_response),
69+
get_mock_response(json=get_policies_for_project_response),
7370
],
7471
):
7572
with patch.object(

tests/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def get_mock_response(status_code=200, json={}):
2323
"updated_at": "2023-02-17T14:40:49.394311+00:00",
2424
}
2525

26-
get_policies_for_collection_response = [
26+
get_policies_for_project_response = [
2727
{
2828
"name": "check-tags",
2929
"source_name": "csd-policies",

0 commit comments

Comments
 (0)