Skip to content

Commit fa5cfb9

Browse files
committed
add policy_operations example to defense
1 parent 87ec238 commit fa5cfb9

File tree

4 files changed

+142
-3
lines changed

4 files changed

+142
-3
lines changed

examples/defense/policy_operations.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#!/usr/bin/env python
2+
#
3+
4+
import sys
5+
from cbapi.defense import Policy
6+
from cbapi.example_helpers import build_cli_parser, get_cb_defense_object, get_object_by_name_or_id
7+
from cbapi.errors import ServerError
8+
import logging
9+
import json
10+
11+
log = logging.getLogger(__name__)
12+
13+
14+
def list_policies(cb, parser, args):
15+
for p in cb.select(Policy):
16+
print("Policy id {0}: {1}".format(p.id, p.name))
17+
print(" {0}".format(p.description))
18+
19+
20+
def import_policy(cb, parser, args):
21+
p = cb.create(Policy)
22+
23+
p.policy = json.load(open(args.policyfile, "r"))
24+
p.description = args.description
25+
p.name = args.name
26+
p.priorityLevel = args.prioritylevel
27+
p.version = 2
28+
29+
try:
30+
p.save()
31+
except ServerError as se:
32+
print("Could not add policy: {0}".format(str(se)))
33+
except Exception as e:
34+
print("Could not add policy: {0}".format(str(e)))
35+
else:
36+
print("Added policy. New policy ID is {0}".format(p.id))
37+
38+
39+
def delete_policy(cb, parser, args):
40+
try:
41+
if args.id:
42+
attempted_to_find = "ID of {0}".format(args.id)
43+
policies = [cb.select(Policy, args.id, force_init=True)]
44+
else:
45+
attempted_to_find = "name {0}".format(args.name)
46+
policies = [p for p in cb.select(Policy) if p.name == args.name]
47+
if not len(policies):
48+
raise Exception("No policies match")
49+
except Exception as e:
50+
print("Could not find policy with {0}: {1}".format(attempted_to_find, str(e)))
51+
return
52+
53+
num_matching_policies = len(policies)
54+
if num_matching_policies > 1 and not args.force:
55+
print("{0:d} policies match {1:s} and --force not specified. No action taken.".format(num_matching_policies,
56+
attempted_to_find))
57+
return
58+
59+
for p in policies:
60+
try:
61+
p.delete()
62+
except Exception as e:
63+
print("Could not delete policy with {0}: {1}".format(attempted_to_find, str(e)))
64+
else:
65+
print("Deleted policy id {0} with name {1}".format(p.id, p.name))
66+
67+
68+
def export_policy(cb, parser, args):
69+
try:
70+
if args.id:
71+
attempted_to_find = "ID of {0}".format(args.id)
72+
policies = [cb.select(Policy, args.id, force_init=True)]
73+
elif args.name:
74+
attempted_to_find = "name {0}".format(args.name)
75+
policies = [p for p in cb.select(Policy) if p.name == args.name]
76+
if not len(policies):
77+
raise Exception("No policies match")
78+
else:
79+
attempted_to_find = "all policies"
80+
policies = list(cb.select(Policy))
81+
82+
except Exception as e:
83+
print("Could not find policy with {0}: {1}".format(attempted_to_find, str(e)))
84+
return
85+
86+
for p in policies:
87+
json.dump(p.policy, open("policy-{0}.json".format(p.id), "w"), indent=2)
88+
print("Wrote policy {0} {1} to file policy-{0}.json".format(p.id, p.name))
89+
90+
91+
def main():
92+
parser = build_cli_parser("Policy operations")
93+
commands = parser.add_subparsers(help="Policy commands", dest="command_name")
94+
95+
list_command = commands.add_parser("list", help="List all configured policies")
96+
97+
import_policy_command = commands.add_parser("import", help="Import policy from JSON file")
98+
import_policy_command.add_argument("-N", "--name", help="Name of new policy", required=True)
99+
import_policy_command.add_argument("-d", "--description", help="Description of new policy", required=True)
100+
import_policy_command.add_argument("-p", "--prioritylevel", help="Priority level (HIGH, MEDIUM, LOW)",
101+
default="LOW")
102+
import_policy_command.add_argument("-f", "--policyfile", help="Filename containing the JSON policy description",
103+
required=True)
104+
105+
export_policy_command = commands.add_parser("export", help="Export policy to JSON file")
106+
export_policy_specifier = export_policy_command.add_mutually_exclusive_group(required=False)
107+
export_policy_specifier.add_argument("-i", "--id", type=int, help="ID of policy")
108+
export_policy_specifier.add_argument("-N", "--name", help="Name of policy")
109+
110+
del_command = commands.add_parser("delete", help="Delete policies")
111+
del_policy_specifier = del_command.add_mutually_exclusive_group(required=True)
112+
del_policy_specifier.add_argument("-i", "--id", type=int, help="ID of policy to delete")
113+
del_policy_specifier.add_argument("-N", "--name", help="Name of policy to delete. Specify --force to delete"
114+
" multiple policies that have the same name")
115+
del_command.add_argument("--force", help="If NAME matches multiple policies, delete all matching policies",
116+
action="store_true", default=False)
117+
118+
args = parser.parse_args()
119+
cb = get_cb_defense_object(args)
120+
121+
if args.command_name == "list":
122+
return list_policies(cb, parser, args)
123+
elif args.command_name == "import":
124+
return import_policy(cb, parser, args)
125+
elif args.command_name == "export":
126+
return export_policy(cb, parser, args)
127+
elif args.command_name == "delete":
128+
return delete_policy(cb, parser, args)
129+
130+
131+
if __name__ == "__main__":
132+
sys.exit(main())

examples/response/watchlist_operations.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def main():
8383
list_actions_command = commands.add_parser("list-actions", help="List actions associated with a watchlist")
8484
list_actions_specifier = list_actions_command.add_mutually_exclusive_group(required=True)
8585
list_actions_specifier.add_argument("-i", "--id", type=int, help="ID of watchlist")
86-
list_actions_specifier.add_argument("-f", "--name", help="Name of watchlist")
86+
list_actions_specifier.add_argument("-N", "--name", help="Name of watchlist")
8787

8888
add_command = commands.add_parser("add", help="Add new watchlist")
8989
add_command.add_argument("-N", "--name", help="Name of watchlist", required=True)

src/cbapi/errors.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
#!/usr/bin/env python
2+
from cbapi.six import python_2_unicode_compatible
23

34

45
class ApiError(Exception):
56
def __init__(self, message=None, original_exception=None):
67
self.original_exception = original_exception
7-
self.message = message
8+
self.message = str(message)
89

910
def __str__(self):
1011
return self.message
1112

1213

14+
@python_2_unicode_compatible
1315
class ServerError(ApiError):
1416
"""A ServerError is raised when an HTTP error code is returned from the Carbon Black server."""
1517

@@ -31,6 +33,7 @@ def __str__(self):
3133
return msg
3234

3335

36+
@python_2_unicode_compatible
3437
class ObjectNotFoundError(ApiError):
3538
"""The requested object could not be found in the Carbon Black datastore."""
3639

@@ -46,6 +49,7 @@ def __str__(self):
4649
return msg
4750

4851

52+
@python_2_unicode_compatible
4953
class TimeoutError(ApiError):
5054
def __init__(self, uri=None, error_code=None, message=None, original_exception=None):
5155
super(TimeoutError, self).__init__(message=message, original_exception=original_exception)
@@ -65,6 +69,7 @@ def __str__(self):
6569
return msg
6670

6771

72+
@python_2_unicode_compatible
6873
class UnauthorizedError(ApiError):
6974
def __init__(self, uri, message=None, action="read", original_exception=None):
7075
super(UnauthorizedError, self).__init__(message=message, original_exception=original_exception)

src/cbapi/example_helpers.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717

1818

1919
# Example scripts: we want to make sure that sys.stdout is using utf-8 encoding. See issue #36.
20-
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
20+
from cbapi.six import PY3
21+
if not PY3:
22+
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
2123

2224

2325
def build_cli_parser(description="Cb Example Script"):

0 commit comments

Comments
 (0)