This repository was archived by the owner on Jan 10, 2022. It is now read-only.
forked from demisto/content
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathupdate_playbook.py
152 lines (108 loc) · 4.73 KB
/
update_playbook.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import sys
import ntpath
import yaml
import yamlordereddictloader
def add_description(playbook):
"""
add empty description to tasks of type title, start, end
currently demisto exports those tasks without description, but the build hook validations require description
:param playbook: playbook dict loaded from yaml
:return: updated playbook dict
"""
for task_id, task in playbook.get("tasks", {}).items():
if task.get("type") in ["start", "end", "title", "playbook"]:
playbook["tasks"][task_id]["task"]["description"] = ""
return playbook
def update_playbook_task_name(playbook):
"""
update the name of the task to be the same as playbookName it is running
:param playbook: playbook dict loaded from yaml
:return: updated playbook dict
"""
for task_id, task in playbook.get("tasks", {}).items():
if task.get("type") == "playbook":
task["task"]["name"] = task["task"]["playbookName"]
return playbook
def replace_version(playbook):
"""
replace the version of playbook with -1
:param playbook: playbook dict loaded from yaml
:return: updated playbook dict
"""
playbook["version"] = -1
return playbook
def update_id_to_be_equal_name(playbook):
"""
update the id of the playbook to be the same as playbook name
the reason for that, demisto generates id - uuid for playbooks/scripts/integrations
the conventions in the content, that the id and the name should be the same and human readable
:param playbook: playbook dict loaded from yaml
:return: updated playbook dict
"""
playbook["id"] = playbook["name"]
return playbook
def update_replace_copy_dev(playbook):
"""
when developer clones playbook/integration/script it will automatically renamed to be _copy or _dev
this function will replace _copy or _dev with empty string
:param playbook: playbook dict loaded from yaml
:return: updated playbook dict
"""
playbook["name"] = playbook["name"].replace("_copy", "").replace("_dev", "")
playbook["id"] = playbook["id"].replace("_copy", "").replace("_dev", "")
for task_id, playbook_task in playbook.get("tasks", {}).items():
inner_task = playbook_task.get("task", {})
if "scriptName" in inner_task:
playbook["tasks"][task_id]["task"]["scriptName"] = playbook["tasks"][task_id]["task"]["scriptName"]\
.replace("_copy", "")\
.replace("_dev", "")
if "playbookName" in inner_task:
playbook["tasks"][task_id]["task"]["playbookName"] = playbook["tasks"][task_id]["task"]["playbookName"]\
.replace("_copy", "")\
.replace("_dev", "")
if "script" in inner_task:
playbook["tasks"][task_id]["task"]["script"] = playbook["tasks"][task_id]["task"]["script"] \
.replace("_copy", "") \
.replace("_dev", "")
return playbook
def update_playbook(source_path, destination_path):
print("Starting...")
with open(source_path) as f:
playbook = yaml.load(f, Loader=yamlordereddictloader.SafeLoader)
playbook = update_replace_copy_dev(playbook)
# add description to tasks that shouldn't have description like start, end, title
playbook = add_description(playbook)
# update the name of playbooks tasks to be equal to the name of the playbook
playbook = update_playbook_task_name(playbook)
# replace version to be -1
playbook = replace_version(playbook)
playbook = update_id_to_be_equal_name(playbook)
if not destination_path:
destination_path = ntpath.basename(source_path)
if not destination_path.startswith("playbook-"):
destination_path = "playbook-{}".format(destination_path)
# Configure safe dumper (multiline for strings)
yaml.SafeDumper.org_represent_str = yaml.SafeDumper.represent_str
def repr_str(dumper, data):
if '\n' in data:
return dumper.represent_scalar(u'tag:yaml.org,2002:str', data, style='|')
return dumper.org_represent_str(data)
yaml.add_representer(str, repr_str, Dumper=yamlordereddictloader.SafeDumper)
with open(destination_path, 'w') as f:
yaml.dump(
playbook,
f,
Dumper=yamlordereddictloader.SafeDumper,
default_flow_style=False)
print("Finished - new yml saved at {}".format(destination_path))
def main(argv):
if len(argv) < 1:
print("Please provide <source playbook path>, <optional - destination playbook path>")
sys.exit(1)
source_path = argv[0]
destination_path = ""
if len(argv) >= 2:
destination_path = argv[1]
update_playbook(source_path, destination_path)
if __name__ == "__main__":
main(sys.argv[1:])