EasyVista

EasyVista Service Manager manages the entire process of designing, managing and delivering IT services.

IT Services · EasyVista

Details

IDEasyVista
ProviderEasyVista
CategoryIT Services
From Version5.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

Overview

Use the EasyVista integration to search for incidents and requests, and retrieve their status and information.

This integration was integrated and tested with EasyVista v2016.1.300.2. For more information, visit the EasyVista REST API documentation.


Use Cases

Search for incidents and requests.


Prerequisites

The account you use must be the account Service Manager used, for example, 50004: Production base; 50005: Sandbox base.


Configure EasyVista on Cortex XSOAR

  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for EasyVista.
  3. Click Add instance to create and configure a new integration instance.
    • Name: a textual name for the integration instance
    • Server URL (example: https://your_company.easyvista.com)
    • Username
    • Do not validate server certificate (not secure)
    • Use system proxy settings
  4. Click Test to validate the URLs and connection.

Commands


Search: easy-vista-search

Search for Incidents and requests.

Basic Command

!easy-vista-search

Input
Parameter Description
asset

Asset to search for (example: requestor)

attribute

Attribute to search for (example: last_name)

value

Value to search (example: "Morley, Gaby")

request

Integrated request of assets, attributes, and values (example: requestor.last_name:"Morley, Gaby").

This parameter replaces the other parameters given separately.

 

 Context Output
Path Description
EasyVista.Records.CatalogRequest.CatalogRequestPath Catalog request path
EasyVista.Records.CatalogRequest.Code Catalog request code
EasyVista.Records.CatalogRequest.SdCatalogId SD catalog ID
EasyVista.Records.CatalogRequest.TitleEn Request title
EasyVista.Records.Department.DepartmentCode Department code
EasyVista.Records.Department.DepartmentEn Department name
EasyVista.Records.Department.DepartmentId Department ID
EasyVista.Records.Department.DepratmentLabel Department label
EasyVista.Records.Department.DepartmentPath Department path
EasyVista.Records.KnownProblem.KnownProblemPath Known problem path
EasyVista.Records.KnownProblem.KnownProblemsId Known problems ID
EasyVista.Records.KnownProblem.KpNumber Number of known problems
EasyVista.Records.KnownProblem.QuestionEn Known problem question
EasyVista.Records.Location.City City
EasyVista.Records.Location.LocationCode Location code
EasyVista.Records.Location.LocationEn Location name
EasyVista.Records.Location.LocationId Location ID
EasyVista.Records.Location.LocationPath Location path
EasyVista.Records.Recipient.BeginOfContract Date of beginning of contract
EasyVista.Records.Recipient.CellularNumber Cellular number of recipient
EasyVista.Records.Recipient.DerpartmentPath Department path of recipient
EasyVista.Records.Recipient.EMail Email address of recipient
EasyVista.Records.Recipient.EmployeeId Employee ID of recipient
EasyVista.Records.Recipient.LastName Last name of recipient
EasyVista.Records.Recipient.LocationPath Location of recipient
EasyVista.Records.Recipient.PhoneNumber Phone number of recipient
EasyVista.Records.Status.StatusEn Status of request
EasyVista.Records.Status.StatusGuid Request GUID
EasyVista.Records.Status.StatusId Request ID

 

Command Example

 !easy-vista-search asset=requestor attribute=last_name value="Morley, Gaby"

or

!easy-vista-search request=requestor.last_name:"Morley, Gaby"

Raw Output
{  
   "CATALOG_REQUEST":{  
      "CATALOG_REQUEST_PATH":"Incidents/Equipment/Desktop*/Diskette Drive",
      "CODE":"70",
      "SD_CATALOG_ID":"4710",
      "TITLE_EN":"Diskette Drive"
   },
   "COMMENT":{  

   },
   "DEPARTMENT":{  
      "DEPARTMENT_CODE":"",
      "DEPARTMENT_EN":"Customer Support",
      "DEPARTMENT_ID":"22",
      "DEPARTMENT_LABEL":"",
      "DEPARTMENT_PATH":"Sales/Direct/Customer Support",

   },
   "KNOWN_PROBLEM":{  
      "KNOWN_PROBLEMS_ID":"",
      "KNOWN_PROBLEM_PATH":"",
      "KP_NUMBER":"",
      "QUESTION_EN":""
   },
   "LOCATION":{  
      "CITY":"",
      "LOCATION_CODE":"",
      "LOCATION_EN":"337",
      "LOCATION_ID":"7091",
      "LOCATION_PATH":"Europe/United Kingdom/Plymouth/Bldg 1/Floor 03/337"
   },
   "MAX_RESOLUTION_DATE_UT":"2011-03-15T20:00:00.000-04:00",
   "RECIPIENT":{  
      "BEGIN_OF_CONTRACT":"1988-04-01",
      "CELLULAR_NUMBER":"788-853-418",
      "DEPARTMENT_PATH":"Sales/Direct/Customer Support",
      "EMPLOYEE_ID":"14412",
      "E_MAIL":"test@example.com",
      "LAST_NAME":"Ernst, Walter",
      "LOCATION_PATH":"Europe/United Kingdom/Plymouth/Bldg 1/Floor 03/337",
      "PHONE_NUMBER":"+441442200573"
   },
   "REQUESTOR":{  
      "BEGIN_OF_CONTRACT":"1988-04-01",
      "CELLULAR_NUMBER":"788-853-418",
      "DEPARTMENT_PATH":"Sales/Direct/Customer Support",
      "EMPLOYEE_ID":"14412",
      "E_MAIL":"test@example.com",
      "LAST_NAME":"Ernst, Walter",
      "LOCATION_PATH":"Europe/United Kingdom/Plymouth/Bldg 1/Floor 03/337",
      "PHONE_NUMBER":"+441442200573"
   },
   "RFC_NUMBER":"000216",
   "STATUS":{  
      "STATUS_EN":"Reopened",
      "STATUS_GUID":"{67FC30D6-06DC-4B75-976F-69BE4CE6BDDD}",
      "STATUS_ID":"16"
   },
   "SUBMIT_DATE_UT":"2012-03-12T20:00:00.000-04:00"
}

Configuration parameters

  • server — Server URL (required)
  • account — Account (required)
  • credentials — Credentials
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (1)

  • easy-vista-search

    This method allows a list of incidents / requests (service, change, investment) to be obtained.

import demistomock as demisto  # noqa: F401
from CommonServerPython import *  # noqa: F401

""" IMPORTS """
import os

import requests
import urllib3

if not demisto.params()["proxy"]:
    # Remove proxy environment variables if they exist
    for proxy_var in ["HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy"]:
        os.environ.pop(proxy_var, None)

# Disable insecure warnings
urllib3.disable_warnings()

""" GLOBAL VARS """
ACCOUNT = demisto.params()["account"]
USERNAME = demisto.params()["credentials"]["identifier"]
PASSWORD = demisto.params()["credentials"]["password"]
SERVER = demisto.params()["server"][:-1] if demisto.params()["server"].endswith("/") else demisto.params()["server"]
BASE_URL = f"{SERVER}/api/v1/{ACCOUNT}/"
USE_SSL = not demisto.params().get("insecure", False)

""" HELPER FUNCTIONS """


def http_request(method, url_suffix):
    demisto.debug(f"running request with url={BASE_URL}{url_suffix}")
    try:
        res = requests.request(
            method, BASE_URL + url_suffix, verify=USE_SSL, auth=requests.auth.HTTPBasicAuth(USERNAME, PASSWORD)
        )
        if res.status_code != 200:
            raise Exception(f"Your request failed with the following error: {res.content!s}{res.status_code!s}")
    except Exception as e:
        demisto.debug(f"{e}")
        raise
    return res.json()


def dict_to_str(obj):
    """
    Input - dictionary :
    {
        key1_keya: "valuea",
        key1_keyb: "valueb",
        HREF: "http://link"
    }

    Output - string:
    Key1Keya: Valuea
    Key1Keyb: Valueb
    """
    string_result = ""
    context_result = {}
    for key, value in obj.items():
        if key != "HREF":
            string_result = f"{string_result}{underscoreToCamelCase(key)}:{value}<br>"
            context_result[underscoreToCamelCase(key)] = value
    return string_result, context_result


""" FUNCTIONS """


def search_command():
    request = demisto.args().get("request")
    if request:
        response = search(request=request)
    else:
        asset = demisto.args().get("asset")
        attribute = demisto.args().get("attribute")
        value = demisto.args().get("value")
        if asset and attribute and value:
            response = search(asset, attribute, value)
        else:
            return "Not enough arguments given"
    records = []
    context = []
    for record in response:
        string_record: dict = {}
        context_record = {}
        for header in record:
            current_context = {}
            if isinstance(record[header], dict):
                current_string, current_context = dict_to_str(record[header])
                if len(current_string) == 0:
                    string_record[header] = None
                else:
                    string_record[header] = current_string
                context_record[underscoreToCamelCase(header)] = current_context
        records.append(string_record)
        context.append(context_record)
    if records:
        title = "EasyVista Search Results"
        demisto.results(  # noqa: RET503
            {
                "Type": entryTypes["note"],
                "Contents": records,
                "ContentsFormat": formats["json"],
                "ReadableContentsFormat": formats["markdown"],
                "HumanReadable": tableToMarkdown(title, records, headerTransform=underscoreToCamelCase, removeNull=True),
                "EntryContext": {"EasyVista.Records": context},
            }
        )
    else:
        demisto.results("No records found")  # noqa: RET503


def search(asset=None, attribute=None, value=None, request=None):
    cmd_url = "requests?search="
    if request:
        cmd_url += request
    else:
        cmd_url = f'{cmd_url}{asset}.{attribute}:"{value}"'
    records = http_request("GET", cmd_url)["records"]
    return records


""" EXECUTION CODE """
demisto.debug(f"command is {demisto.command()}")

try:
    if demisto.command() == "test-module":
        http_request("GET", "assets")
        demisto.results("ok")

    elif demisto.command() == "easy-vista-search":
        search_command()

except Exception as e:
    demisto.debug(f"{e}")
    raise e