From b0da564ea0f72e32d9584f7f59c8f85900febf72 Mon Sep 17 00:00:00 2001 From: Lior Blobstein Date: Wed, 5 Dec 2018 21:15:46 +0200 Subject: [PATCH] Servicenow OOTB scripts (#2576) * comments * get table names * query script * add scripts, change snow logo * tests * fixes * fixes #2 * fixes --- Integrations/integration-ServiceNow.yml | 69 +++- Scripts/script-ServiceNowCreateIncident.yml | 223 ++++++++++++ Scripts/script-ServiceNowQueryIncident.yml | 192 +++++++++++ Scripts/script-ServiceNowUpdateIncident.yml | 257 ++++++++++++++ .../playbook-ServiceNow_TestScripts.yml | 322 ++++++++++++++++++ .../playbook-ServiceNow_Test_New.yml | 45 ++- 6 files changed, 1096 insertions(+), 12 deletions(-) create mode 100644 Scripts/script-ServiceNowCreateIncident.yml create mode 100644 Scripts/script-ServiceNowQueryIncident.yml create mode 100644 Scripts/script-ServiceNowUpdateIncident.yml create mode 100644 TestPlaybooks/NonCircleTests/playbook-ServiceNow_TestScripts.yml diff --git a/Integrations/integration-ServiceNow.yml b/Integrations/integration-ServiceNow.yml index 2cefa8349b8e..dfd220b756d0 100644 --- a/Integrations/integration-ServiceNow.yml +++ b/Integrations/integration-ServiceNow.yml @@ -4,7 +4,7 @@ commonfields: name: ServiceNow display: ServiceNow category: Case Management -image: data:image/png;base64,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 +image: data:image/png;base64,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 description: IT service management configuration: - display: ServiceNow URL, in the format https://company.service-now.com/ @@ -150,7 +150,7 @@ script: '2': 'On order', '3': 'On maintenance', '6': 'In stock/In transit', - '7': 'Retried', + '7': 'Retired', '100': 'Missing' } @@ -1205,6 +1205,44 @@ script: return res + def get_table_name_command(): + label = demisto.args()['label'] + offset = demisto.args().get('offset', DEFAULTS['offset']) + limit = demisto.args().get('limit', DEFAULTS['limit']) + + table_query = 'label=' + label + + res = query('sys_db_object', limit, offset, table_query) + + if not res or 'result' not in res: + return 'Cannot find table' + + tables = res['result'] + + if len(tables) == 0: + return 'Cannot find table' + + headers = ['ID', 'Name', 'SystemName'] + + mapped_tables = [{ + 'ID': table['sys_id'], + 'Name': table['name'], + 'SystemName': table['sys_name'] + } for table in tables] + + entry = { + 'Type': entryTypes['note'], + 'Contents': res, + 'ContentsFormat': formats['json'], + 'ReadableContentsFormat': formats['markdown'], + 'HumanReadable': tableToMarkdown('ServiceNow Tables for label - ' + label, mapped_tables, headers=headers), + 'EntryContext': { + 'ServiceNow.Table(val.ID===obj.ID)': createContext(mapped_tables), + } + } + + return entry + def fetch_incidents(): query_params = {} @@ -1321,6 +1359,8 @@ script: demisto.results(delete_record_command()) if demisto.command() == 'servicenow-list-table-fields': demisto.results(list_table_fields_command()) + if demisto.command() == 'servicenow-get-table-name': + demisto.results(get_table_name_command()) except Exception as e: LOG(e) LOG.print_log() @@ -3330,8 +3370,29 @@ script: description: User update time type: date description: Query the sys_user table in ServiceNow + - name: servicenow-get-table-name + arguments: + - name: label + required: true + description: The table label, e.g Asset, Incident, IP address etc. + - name: limit + description: Results limit + defaultValue: "10" + - name: offset + description: Starting record index to begin retrieving records from + outputs: + - contextPath: ServiceNow.Table.ID + description: Table system ID + type: string + - contextPath: ServiceNow.Table.Name + description: Table name to use in commands, e.g alm_asset + type: string + - contextPath: ServiceNow.Table.SystemName + description: Table system name, e.g Asset + type: string + description: Get table names by a label to use in commands isfetch: true runonce: false +releaseNotes: "Added command to retrieve table names, new ServiceNow logo" tests: - - No test - No instance -releaseNotes: "-" \ No newline at end of file + - No test - Hibernating instance \ No newline at end of file diff --git a/Scripts/script-ServiceNowCreateIncident.yml b/Scripts/script-ServiceNowCreateIncident.yml new file mode 100644 index 000000000000..96adc17be714 --- /dev/null +++ b/Scripts/script-ServiceNowCreateIncident.yml @@ -0,0 +1,223 @@ +commonfields: + id: ServiceNowCreateIncident + version: 38 +name: ServiceNowCreateIncident +script: | + """ + This script is used to wrap the generic create-record command in ServiceNow. + You can add fields that you want to create the record with as script arguments or in the + code and work with the records easily. + + + Mandatory fields in your ServiceNow table settings should be changed to be mandatory arguments in this script. + You can identify such fields by trying to get a record and receiving a response + stating that a required field is missing. + """ + + """ + Mapping of severity display names to their corresponding values in the API + """ + TICKET_SEVERITY = { + '1 - High': '1' , + '2 - Medium': '2', + '3 - Low': '3' + } + + + """ + Function to use the query command to retrieve records from the users table. + """ + def get_user(query): + user_args = { + 'table_name': 'sys_user', + 'query': query + } + + user_result = demisto.executeCommand('servicenow-query-table', user_args)[0] + user_data = demisto.get(user_result, 'Contents') + if not user_data: + return_error('Could not get the contents from the command result: ' + json.dumps(user_result)) + if not isinstance(user_data, dict): + # In case of string result, e.g "No incidents found" + demisto.results('User not found') + sys.exit(0) + user = user_data['result'] + + if not user or len(user) == 0: + demisto.results('User not found') + sys.exit(0) + + return user + + def get_user_id(user_name): + user_name = user_name.split(' ') + query = 'first_name={}^last_name={}'.format(user_name[0], user_name[1]) + + user = get_user(query) + + return user[0]['sys_id'] + + + """ + Function to use the query command to retrieve records from the groups table. + """ + def get_group(query): + group_args = { + 'table_name': 'sys_user_group', + 'query': query + } + + group_result = demisto.executeCommand('servicenow-query-table', group_args)[0] + group_data = demisto.get(group_result, 'Contents') + if not group_data: + return_error('Could not get the contents from the command result: ' + json.dumps(group_result)) + if not isinstance(group_data, dict): + # In case of string result, e.g "No incidents found" + demisto.results('Group not found') + sys.exit(0) + group = group_data['result'] + + if not group or len(group) == 0: + demisto.results('Group not found') + sys.exit(0) + + return group + + def get_group_id(group_name): + query = 'name=' + group_name + + group = get_group(query) + + return group[0]['sys_id'] + + + """ + The table name is required by the API. To acquire the table name, use the servicenow-get-table-name command. + """ + command_args = { + 'table_name': 'incident' + } + + """ + These record fields(columns) are mapped from their names in ServiceNow to your choice of field names. + To view all fields for a given table, use the servicenow-list-fields command. + The ID field must be included to manage unique context entries. + """ + fields_to_map = { + 'sys_id': 'ID', + 'number': 'Number' + } + + + """ + For each field in the arguments, you need to check if it was provided and apply any operations required (e.g, get a user id from a user name) to send them to the API. + """ + incident_severity = demisto.args().get('severity') + group_name = demisto.args().get('assigned_group') + user_name = demisto.args().get('assignee') + description = demisto.args().get('description') + user_id = None + group_id = None + + if user_name: + # Query the user table to get the system ID of the assignee + user_id = get_user_id(user_name) + if group_name: + # Query the group table to get the system ID of the assigned group + group_id = get_group_id(group_name) + + + """ + Every field that was provided needs to be formatted to the following syntax: 'field1=a;field2=b;...' to create the incident according to the arguments and execute the command. + In order to do that, to each field you need to concatenate the field's corresponding name in the ServiceNow API along with an '=' and the value. In the end each of those fields are joined by a ';'. + To view all the API fields for a record use the servicenow-list-fields-command. + """ + fields = [] + + if incident_severity: + fields.append('severity' + '=' + TICKET_SEVERITY[incident_severity]) + if user_id: + fields.append('assigned_to' + '=' + user_id) + if description: + fields.append('short_description' + '=' + description) + if group_id: + fields.append('assignment_group' + '=' + group_id) + + command_args['fields'] = ';'.join(fields) + + command_res = demisto.executeCommand('servicenow-create-record', command_args) + result = {} + try: + entry = command_res[0] + if isError(entry): + return_error(entry['Contents']) + else: + record_data = demisto.get(entry, 'Contents') + if not record_data: + return_error('Could not get the contents from the command result: ' + json.dumps(entry)) + if not isinstance(record_data, dict): + # In case of string result, e.g "No incidents found" + result = record_data + else: + # Get the actual record + record = record_data['result'] + # Map fields according to fields_to_map that were defined earlier + mapped_record = dict((fields_to_map[key], value) for (key, value) in list(filter(lambda (k,v): k in list(fields_to_map.keys()), record.items()))) + + display_headers = ['ID','Number'] + + # Output entry + result = { + 'Type': entryTypes['note'], + 'Contents': record_data, + 'ContentsFormat': formats['json'], + 'ReadableContentsFormat': formats['markdown'], + 'HumanReadable': tableToMarkdown('Incident successfully created', mapped_record, headers=display_headers, removeNull=True), + 'EntryContext': { + 'ServiceNow.Incident(val.ID===obj.ID)': createContext(mapped_record) + } + } + + except Exception as ex: + return_error(ex.message) + + demisto.results(result) +type: python +tags: +- servicenow +comment: |- + This script is used to wrap the generic create-record command in ServiceNow. + You can add fields that you want to create the record with as script arguments or in the + code and work with the records easily. +enabled: true +args: +- name: severity + auto: PREDEFINED + predefined: + - 1 - High + - 2 - Medium + - 3 - Low + description: Incident severity +- name: assignee + description: Incident assigne name (e.g John Smith) +- name: description + required: true + description: Incident description +- name: assigned_group + description: Incident assigned group name (e.g Incident Management Group) +outputs: +- contextPath: ServiceNow.Incident.ID + description: Incident ID + type: string +- contextPath: ServiceNow.Incident.Number + description: Incident number + type: string +scripttarget: 0 +dependson: + must: + - ServiceNow|||servicenow-create-record + - ServiceNow|||servicenow-query-table +runonce: false +releaseNotes: "ServiceNow create record example" +tests: + - No test - Hibernating instance \ No newline at end of file diff --git a/Scripts/script-ServiceNowQueryIncident.yml b/Scripts/script-ServiceNowQueryIncident.yml new file mode 100644 index 000000000000..d9f38442409c --- /dev/null +++ b/Scripts/script-ServiceNowQueryIncident.yml @@ -0,0 +1,192 @@ +commonfields: + id: ServiceNowQueryIncident + version: 100 +name: ServiceNowQueryIncident +script: | + """ + This script is used to wrap the generic query-table command in ServiceNow. + You can add fields that you want to use as inputs and outputs from the record as script arguments or in the + code and work with the records easily. + + + Mandatory fields in your ServiceNow table settings should be changed to be mandatory arguments in this script. + You can identify such fields by trying to get a record and receiving a response + stating that a required field is missing. + """ + + + """ + Mapping of priority values to their corresponding display in the UI + """ + INCIDENT_PRIORITY = { + '1': '1 - Critical', + '2': '2 - High', + '3': '3 - Moderate', + '4': '4 - Low', + '5': '5 - Planning' + } + + """ + Function to use the query command to retrieve records from the users table. + """ + def get_user(query): + user_args = { + 'table_name': 'sys_user', + 'query': query + } + + user_result = demisto.executeCommand('servicenow-query-table', user_args)[0] + user_data = demisto.get(user_result, 'Contents') + if not user_data: + return_error('Could not get the contents from the command result: ' + json.dumps(user_result)) + if not isinstance(user_data, dict): + # In case of string result, e.g "No incidents found" + demisto.results('User not found') + sys.exit(0) + user = user_data['result'] + + if not user or len(user) == 0: + demisto.results('User not found') + sys.exit(0) + + return user + + def get_user_id(user_name): + user_name = user_name.split(' ') + query = 'first_name={}^last_name={}'.format(user_name[0], user_name[1]) + + user = get_user(query) + + return user[0]['sys_id'] + + def get_user_name(user_id): + query = 'id=' + user_id + + user = get_user(query) + + return '{} {}'.format(user[0]['first_name'], user[0]['last_name']) + + """ + The table name is required by the API. To acquire the table name, use the servicenow-get-table-name command. + """ + command_args = { + 'table_name': 'incident' + } + + """ + These record fields(columns) are mapped from their names in ServiceNow to your choice of field names to be in the output. + To view all fields for a given table, use the servicenow-list-fields command. + The ID field must be included to manage unique context entries. + """ + fields_to_map = { + 'sys_id': 'ID', + 'priority': 'Priority', + 'opened_by': 'Caller', + 'number': 'Number', + 'short_description': 'Description' + } + + command_args['fields'] = list(fields_to_map.keys()) + + """ + For each field in the arguments, you need to check if it was provided and apply any operations required (e.g, get a user id from a user name) to send them to the API. + """ + incident_id = demisto.args().get('id') + incident_number = demisto.args().get('number') + user_name = demisto.args().get('assignee') + user_id = None + + if user_name: + # Query the user table to get the system ID of the assignee + user_id = get_user_id(user_name) + + + """ + Set up the query according to the arguments and execute the command + """ + if incident_id: + query = 'id=' + incident_id + elif incident_number: + query = 'number=' + incident_number + elif user_id: + query = 'assigned_to=' + user_id + + command_args['query'] = query + + command_res = demisto.executeCommand('servicenow-query-table', command_args) + result = {} + try: + entry = command_res[0] + if isError(entry): + return_error(entry['Contents']) + else: + record_data = demisto.get(entry, 'Contents') + if not record_data: + return_error('Could not get the contents from the command result: ' + json.dumps(entry)) + if not isinstance(record_data, dict): + # In case of string result, e.g "No incidents found" + result = record_data + else: + # Get the actual records + records = record_data['result'] + # Map fields according to fields_to_map that were defined earlier + mapped_records = [dict((fields_to_map[key], value) for (key, value) in list(filter(lambda (k,v): k in list(fields_to_map.keys()), r.items()))) for r in records] + for mr in mapped_records: + # Query the user table to get the name of the caller + mr['Caller'] = get_user_name(mr['Caller'].get('value')) + # Map the priority + mr['Priority'] = INCIDENT_PRIORITY.get(mr['Priority'], mr['Priority']) + display_headers = ['ID','Number','Priority', 'Description', 'Caller'] + + # Output entry + result = { + 'Type': entryTypes['note'], + 'Contents': record_data, + 'ContentsFormat': formats['json'], + 'ReadableContentsFormat': formats['markdown'], + 'HumanReadable': tableToMarkdown('ServiceNow Incidents', mapped_records, headers=display_headers, removeNull=True), + 'EntryContext': { + 'ServiceNow.Incident(val.ID===obj.ID)': createContext(mapped_records) + } + } + + except Exception as ex: + return_error(ex.message) + + demisto.results(result) +type: python +tags: +- servicenow +comment: |- + This script is used to wrap the generic query-table command in ServiceNow. + You can add fields that you want to use as inputs and outputs from the record as script arguments or in the + code and work with the records easily. +enabled: true +args: +- name: id + description: Incident System ID +- name: number + description: Incident number +- name: assignee + description: Incident assigne name (e.g John Smith) +outputs: +- contextPath: ServiceNow.Incident.ID + description: Incident ID + type: string +- contextPath: ServiceNow.Incident.Description + description: Incident description + type: string +- contextPath: ServiceNow.Incident.Number + description: Incident number + type: number +- contextPath: ServiceNow.Incident.Caller + description: Incident caller + type: string +scripttarget: 0 +dependson: + must: + - ServiceNow|||servicenow-query-table +runonce: false +releaseNotes: "ServiceNow query table example" +tests: + - No test - Hibernating instance \ No newline at end of file diff --git a/Scripts/script-ServiceNowUpdateIncident.yml b/Scripts/script-ServiceNowUpdateIncident.yml new file mode 100644 index 000000000000..89af4af6d6db --- /dev/null +++ b/Scripts/script-ServiceNowUpdateIncident.yml @@ -0,0 +1,257 @@ +commonfields: + id: ServiceNowUpdateIncident + version: 22 +name: ServiceNowUpdateIncident +script: | + """ + This script is used to wrap the generic update-record command in ServiceNow. + You can add fields that you want to update the record with as script arguments or in the + code and work with the records easily. + + + Mandatory fields in your ServiceNow table settings should be changed to be mandatory arguments in this script. + You can identify such fields by trying to get a record and receiving a response + stating that a required field is missing. + """ + + """ + Mapping of severity display names to their corresponding values in the API + """ + TICKET_SEVERITY = { + '1 - High': '1' , + '2 - Medium': '2', + '3 - Low': '3' + } + + """ + Function to use the query command to retrieve an incident by a query. + """ + def get_incident(query): + incident_args = { + 'table_name': 'incident', + 'query': query + } + + incident_result = demisto.executeCommand('servicenow-query-table', incident_args)[0] + incident_data = demisto.get(incident_result, 'Contents') + if not incident_data: + return_error('Could not get the contents from the command result: ' + json.dumps(incident_result)) + if not isinstance(incident_data, dict): + # In case of string result, e.g "No incidents found" + demisto.results('Incident not found') + sys.exit(0) + incident = incident_data['result'] + + if not incident or len(incident) == 0: + demisto.results('Incident not found') + sys.exit(0) + + return incident + + def get_incident_id(incident_number): + query = 'number=' + incident_number + + incident = get_incident(query) + + return incident[0]['sys_id'] + + """ + Function to use the query command to retrieve records from the users table. + """ + def get_user(query): + user_args = { + 'table_name': 'sys_user', + 'query': query + } + + user_result = demisto.executeCommand('servicenow-query-table', user_args)[0] + user_data = demisto.get(user_result, 'Contents') + if not user_data: + return_error('Could not get the contents from the command result: ' + json.dumps(user_result)) + if not isinstance(user_data, dict): + # In case of string result, e.g "No incidents found" + demisto.results('User not found') + sys.exit(0) + user = user_data['result'] + + if not user or len(user) == 0: + demisto.results('User not found') + sys.exit(0) + + return user + + def get_user_id(user_name): + user_name = user_name.split(' ') + query = 'first_name={}^last_name={}'.format(user_name[0], user_name[1]) + + user = get_user(query) + + return user[0]['sys_id'] + + + """ + Function to use the query command to retrieve records from the groups table. + """ + def get_group(query): + group_args = { + 'table_name': 'sys_user_group', + 'query': query + } + + group_result = demisto.executeCommand('servicenow-query-table', group_args)[0] + group_data = demisto.get(group_result, 'Contents') + if not group_data: + return_error('Could not get the contents from the command result: ' + json.dumps(group_result)) + if not isinstance(group_data, dict): + # In case of string result, e.g "No incidents found" + demisto.results('Group not found') + sys.exit(0) + group = group_data['result'] + + if not group or len(group) == 0: + demisto.results('Group not found') + sys.exit(0) + + return group + + def get_group_id(group_name): + query = 'name=' + group_name + + group = get_group(query) + + return group[0]['sys_id'] + + + """ + The table name is required by the API. To acquire the table name, use the servicenow-get-table-name command. + """ + command_args = { + 'table_name': 'incident' + } + + + """ + For each field in the arguments, you need to check if it was provided and apply any operations required (e.g, get a user id from a user name) to send them to the API. + """ + + incident_id = demisto.args().get('id') + incident_number = demisto.args().get('number') + incident_severity = demisto.args().get('severity') + description = demisto.args().get('description') + group_name = demisto.args().get('assigned_group') + user_name = demisto.args().get('assignee') + user_id = None + group_id = None + + if user_name: + # Query the user table to get the system ID of the assignee + user_id = get_user_id(user_name) + if group_name: + # Query the group table to get the system ID of the assigned group + group_id = get_group_id(group_name) + + + """ + Every field that was provided needs to be formatted to the following syntax: 'field1=a;field2=b;...' to update the incident according to the arguments and execute the command. + In order to do that, to each field you need to concatenate the field's corresponding name in the ServiceNow API along with an '=' and the value. In the end each of those fields are joined by a ';'. + To view all the API fields for a record use the servicenow-list-fields-command. + """ + fields = [] + + if incident_id: + command_args['id'] = incident_id + elif incident_number: + # Query the incident table to get the system ID of the incident + command_args['id'] = get_incident_id(incident_number) + else: + raise ValueError('Incident ID or number must be ') + if incident_severity: + fields.append('severity' + '=' + TICKET_SEVERITY[incident_severity]) + if user_id: + fields.append('assigned_to' + '=' + user_id) + if group_id: + fields.append('assignment_group' + '=' + group_id) + if description: + fields.append('short_description' + '=' + description) + + command_args['fields'] = ';'.join(fields) + + command_res = demisto.executeCommand("servicenow-update-record", command_args) + result = {} + try: + entry = command_res[0] + if isError(entry): + return_error(entry['Contents']) + else: + record_data = demisto.get(entry, 'Contents') + if not record_data: + return_error('Could not get the contents from the command result: ' + json.dumps(entry)) + if not isinstance(record_data, dict): + # In case of string result, e.g "No incidents found" + result = record_data + else: + # Get the actual record + record = record_data['result'] + # Map the ID + mapped_record = {'ID': record['sys_id']} + + # Output entry + result = { + 'Type': entryTypes['note'], + 'Contents': record_data, + 'ContentsFormat': formats['json'], + 'ReadableContentsFormat': formats['markdown'], + 'HumanReadable': 'Incident with ID ' + mapped_record['ID'] + ' successfully updated', + 'EntryContext': { + 'ServiceNow.Incident(val.ID===obj.ID)': createContext(mapped_record) + } + } + + except Exception as ex: + return_error(ex.message) + + demisto.results(result) +type: python +tags: +- servicenow +comment: |- + This script is used to wrap the generic update-record command in ServiceNow. + You can add fields that you want to update the record with as script arguments or in the + code and work with the records easily. +enabled: true +args: +- name: severity + auto: PREDEFINED + predefined: + - 1 - High + - 2 - Medium + - 3 - Low + description: Incident severity +- name: assignee + description: Incident assigne name (e.g John Smith) +- name: description + description: Incident description +- name: assigned_group + description: Incident assigned group name (e.g Incident Management Group) +- name: id + description: Incident ID to update +- name: number + description: Incident number to update +- name: query + description: 'Query to use ' +outputs: +- contextPath: ServiceNow.Incident.ID + description: Incident ID + type: string +- contextPath: ServiceNow.Incident.Number + description: Incident number + type: string +scripttarget: 0 +dependson: + must: + - ServiceNow|||servicenow-update-record + - ServiceNow|||servicenow-query-table +runonce: false +releaseNotes: "ServiceNow update record example" +tests: + - No test - Hibernating instance \ No newline at end of file diff --git a/TestPlaybooks/NonCircleTests/playbook-ServiceNow_TestScripts.yml b/TestPlaybooks/NonCircleTests/playbook-ServiceNow_TestScripts.yml new file mode 100644 index 000000000000..c07fc4c03e4f --- /dev/null +++ b/TestPlaybooks/NonCircleTests/playbook-ServiceNow_TestScripts.yml @@ -0,0 +1,322 @@ +id: test_servicenow_scripts +version: -1 +name: Test ServiceNow Scripts +starttaskid: "0" +tasks: + "0": + id: "0" + taskid: 827504d3-26ce-454d-813b-429d92397786 + type: start + task: + id: 827504d3-26ce-454d-813b-429d92397786 + version: -1 + name: "" + iscommand: false + brand: "" + nexttasks: + '#none#': + - "8" + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 50 + } + } + note: false + timertriggers: [] + "1": + id: "1" + taskid: ee8f6a1c-f531-48f5-8351-01356f8d16f2 + type: regular + task: + id: ee8f6a1c-f531-48f5-8351-01356f8d16f2 + version: -1 + name: ServiceNowCreateIncident + description: |- + This script is used to wrap the generic create-record command in ServiceNow. + You can add fields that you want to create the record with as script arguments or in the + code and work with the records easily. + scriptName: ServiceNowCreateIncident + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "2" + scriptarguments: + assigned_group: + simple: test1 + assignee: + simple: Joe Employee + description: + simple: Test incident + severity: + simple: 3 - Low + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 370 + } + } + note: false + timertriggers: [] + "2": + id: "2" + taskid: e1b4195c-a3f7-4612-8ad2-a79bd5900767 + type: regular + task: + id: e1b4195c-a3f7-4612-8ad2-a79bd5900767 + version: -1 + name: ServiceNowQueryIncidents + description: |- + This script is used to wrap the generic query-table command in ServiceNow. + You can add fields that you want to use as inputs and outputs from the record as script arguments or in the + code and work with the records easily. + scriptName: ServiceNowQueryIncidents + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "3" + scriptarguments: + assignee: {} + id: {} + number: + simple: ${ServiceNow.Incident.Number} + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 545 + } + } + note: false + timertriggers: [] + "3": + id: "3" + taskid: e4cfaf94-65d2-442b-807d-1a60517e2846 + type: regular + task: + id: e4cfaf94-65d2-442b-807d-1a60517e2846 + version: -1 + name: Verify Incident + description: |- + Verifies path in context: + - Verifies path existence + - If matching object is an array: verify fields exists in each of the objects in the array + - If matching object is not an array: verify fields exists in matching object + - if 'expectedValue' is given: ensure that the given value is equal to the context path + scriptName: VerifyContext + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "4" + scriptarguments: + expectedValue: + simple: Test incident + fields: {} + path: + simple: ServiceNow.Incident.Description + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 720 + } + } + note: false + timertriggers: [] + "4": + id: "4" + taskid: 4eb2e521-d191-4669-8d36-c481a0079b27 + type: regular + task: + id: 4eb2e521-d191-4669-8d36-c481a0079b27 + version: -1 + name: ServiceNowUpdateIncident + description: |- + This script is used to wrap the generic update-record command in ServiceNow. + You can add fields that you want to update the record with as script arguments or in the + code and work with the records easily. + scriptName: ServiceNowUpdateIncident + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "5" + scriptarguments: + assigned_group: {} + assignee: {} + description: + simple: Updated test incident + id: + simple: ${ServiceNow.Incident.ID} + number: {} + query: {} + severity: {} + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 895 + } + } + note: false + timertriggers: [] + "5": + id: "5" + taskid: dc3eeca6-fb25-4bba-87a0-ef1552a9e0fa + type: regular + task: + id: dc3eeca6-fb25-4bba-87a0-ef1552a9e0fa + version: -1 + name: ServiceNowQueryIncidents + description: |- + This script is used to wrap the generic query-table command in ServiceNow. + You can add fields that you want to use as inputs and outputs from the record as script arguments or in the + code and work with the records easily. + scriptName: ServiceNowQueryIncidents + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "6" + scriptarguments: + assignee: {} + id: {} + number: + simple: ${ServiceNow.Incident.Number} + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 1070 + } + } + note: false + timertriggers: [] + "6": + id: "6" + taskid: fe013171-97ad-4475-8df3-fdc4ac16e268 + type: regular + task: + id: fe013171-97ad-4475-8df3-fdc4ac16e268 + version: -1 + name: Verify Incident + description: |- + Verifies path in context: + - Verifies path existence + - If matching object is an array: verify fields exists in each of the objects in the array + - If matching object is not an array: verify fields exists in matching object + - if 'expectedValue' is given: ensure that the given value is equal to the context path + scriptName: VerifyContext + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "7" + scriptarguments: + expectedValue: + simple: Updated test incident + fields: {} + path: + simple: ServiceNow.Incident.Description + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 1245 + } + } + note: false + timertriggers: [] + "7": + id: "7" + taskid: a163bb03-60b5-4df8-89ee-36c3754756c1 + type: regular + task: + id: a163bb03-60b5-4df8-89ee-36c3754756c1 + version: -1 + name: Delete the incident + description: Delete a record in a specified ServiceNow table + script: ServiceNow|||servicenow-delete-record + type: regular + iscommand: true + brand: ServiceNow + scriptarguments: + id: + simple: ${ServiceNow.Incident.ID} + table_name: + simple: incident + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 1420 + } + } + note: false + timertriggers: [] + "8": + id: "8" + taskid: 2ab6f040-7fac-44d7-8ffb-45e1347ed9b7 + type: regular + task: + id: 2ab6f040-7fac-44d7-8ffb-45e1347ed9b7 + version: -1 + name: DeleteContext + description: Delete field from context + scriptName: DeleteContext + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "1" + scriptarguments: + all: + simple: "yes" + index: {} + key: {} + keysToKeep: {} + subplaybook: {} + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 195 + } + } + note: false + timertriggers: [] +view: |- + { + "linkLabelsPosition": {}, + "paper": { + "dimensions": { + "height": 1465, + "width": 380, + "x": 50, + "y": 50 + } + } + } +inputs: [] +outputs: [] diff --git a/TestPlaybooks/NonCircleTests/playbook-ServiceNow_Test_New.yml b/TestPlaybooks/NonCircleTests/playbook-ServiceNow_Test_New.yml index 13b8f9d88003..b87fe61019ea 100644 --- a/TestPlaybooks/NonCircleTests/playbook-ServiceNow_Test_New.yml +++ b/TestPlaybooks/NonCircleTests/playbook-ServiceNow_Test_New.yml @@ -1,5 +1,5 @@ -id: servicenow_test_new -version: -1 +id: ad055a1b-edec-4285-8bb6-fbfc558e22e9 +version: 15 name: ServiceNow Test New description: This playbook tests the ServiceNow integration commands. starttaskid: "0" @@ -1633,10 +1633,10 @@ tasks: timertriggers: [] "67": id: "67" - taskid: b5fb1279-37be-432c-8b23-46e33a2507c8 + taskid: f2de40ed-b11f-4d5c-8666-bf16eb5db67d type: regular task: - id: b5fb1279-37be-432c-8b23-46e33a2507c8 + id: f2de40ed-b11f-4d5c-8666-bf16eb5db67d version: -1 name: VerifyContext description: |- @@ -1652,7 +1652,7 @@ tasks: scriptarguments: expectedValue: {} fields: - simple: Field,Computer,Group,User + simple: Field,Computer,Group,User,Table path: simple: ServiceNow separatecontext: false @@ -1660,7 +1660,7 @@ tasks: { "position": { "x": 265, - "y": 7485 + "y": 7660 } } note: false @@ -1680,7 +1680,7 @@ tasks: brand: ServiceNow nexttasks: '#none#': - - "67" + - "70" scriptarguments: limit: simple: "1" @@ -1731,12 +1731,41 @@ tasks: } note: false timertriggers: [] + "70": + id: "70" + taskid: 563001d5-1061-4bb8-8609-648cda6953db + type: regular + task: + id: 563001d5-1061-4bb8-8609-648cda6953db + version: -1 + name: servicenow-get-table-name + description: Get table names by a label to use in commands + script: ServiceNow|||servicenow-get-table-name + type: regular + iscommand: true + brand: ServiceNow + nexttasks: + '#none#': + - "67" + scriptarguments: + label: + simple: Asset + separatecontext: false + view: |- + { + "position": { + "x": 265, + "y": 7485 + } + } + note: false + timertriggers: [] view: |- { "linkLabelsPosition": {}, "paper": { "dimensions": { - "height": 7530, + "height": 7705, "width": 810, "x": 50, "y": 50