Building a custom connector

Overview

You can write a custom connector that can retrieve data from custom sources. You can then use the connector either standalone or within FortiSOAR™ playbooks and perform automated operations. You can write a custom connector manually, or you can use the CyOPs™ Connector SDK to develop your custom connector.

The process of installing, configuring, and using FortiSOAR™-provided connectors is defined in the respective connector-specific documentation.

Writing a custom connector

Perform the following steps to write a custom connector manually:

  1. Create a Connector Template Directory Structure with the required files.
  2. Import the connector into FortiSOAR™.
  3. Check the health of the connector.
  4. Add a connector operation to a playbook.

Connector Template Directory Structure

Create the following folder structure, with a folder with the connector name at the top and files within it:

connectorname folder
--+ playbooks
---+ __init__.py
---+ playbooks.json
--+ connector.py
--+ info.json
--+ images
--+ requirements.txt
--+ packages
---+ <package_name>

Note

Python 3 is required for developing your connectors.

info.json

The info.json file contains information about the name and version of the connector, logo image file names, the configuration parameters, the set of functions supported by the connector, and their input parameters. The name of all the fields in the info.json file must be unique.

Note

Ensure that the name of the connector in the info.json and the name of the connector folder matches exactly.

You can configure the following parameters, fields, and operations while writing connectors: description of connector and actions, tooltip, placeholder, conditional fields, backward compatibility (using visible_onchange parameter), validation using regex, label, apioperations, and grouping of fields. These parameters are explained in the Notes following the sample info.json file.

Following is an example of an info.json file:

{
 "name": "sampleConnector",
 "label": "sampleConnector",
 "description": "sampleConnector connector description",
 "publisher": "publisherName",
 "cs_approved": true/false,
 "cs_compatible": true/false,
 "version": "1.0.0",
 "category": "categoryType",
 "help_online": "link to online documentation",
 "icon_small_name":"small_icon.jpeg",
 "icon_large_name":"large_icon.jpeg",
 "configuration": {
   "fields": [
     {
       "title": "fieldname",
       "required": true/false,
       "editable": true/false,
       "visible": true/false,
       "type": "text",
       "description": "text",
       "name": "user",
       "tooltip": "text for the tooltip",
       "placeholder": "placeholder text",
       "validation":{
            "pattern":"regex pattern for validation",
            "patternError":"text for the error message if validation fails"
          }
     }]
 },
 "operations": [
   {
     "operation": "function_template",
     "title": "Sample Function",
     "description": "description of the operation",
     "category": "categoryType",     
     "annotation": "sample_annotation",
     "parameters": [{
       "title": "Sample Input1",
       "required": true/false,
       "editable": true/false,
       "visible": true/false,
       "type": "text",
       "name": "input1",
       "description": "text",
       "value": "default value1"
       "tooltip": "text",
     },
     {
       "title": "Sample Input2",
       "required": true/false,
       "editable": true/false,
       "visible": true/false,
       "type": "text",
       "name": "input2",
       "description": "text",
       "tooltip": "text",
       "value": "",
       "options": ["A", "B"],
       "onchange": {
            "A": [{
              "title": "User2",
              "required": true/false,
              "editable": true/false,
              "visible": true/false,
              "visible_onchange":false,
              "type": "text",
              "name": "user2",
              "description": "text",
              "tooltip": "text",     
              "value": "admin1"           
            }],
            "B": [{
              "title": "User2",
              "required": true/false,
              "editable": true/false,
              "visible": true/false,
              "type": "integer",
              "name": "user2",
              "description": "text",
              "tooltip": "text",  
              "value": 12345
            },{
              "title": "Comment1",
              "required": true/false,
              "editable": true/false,
              "visible": true/false,
              "type": "text",
              "name": "comment1",
              "description": "text",
              "tooltip": "text",  
              "placeholder": "Add comment1",
              "value": "",
              "onchange": {
                "dummy": [{
                  "title": "dummy",
                  "required": true/false,
                  "editable": true/false,
                  "visible": true/false,
                  "type": "checkbox",
                  "name": "dummy",
                  "description": "text",
                  "tooltip": "text",  
                  "value": false
                }
              ]}
            }]       
       }
     }],
     "enabled": true, 
     "output_schema": {"key1": "", "key2": []}
   },
   {
            "operation": "Sample Operation 2",
            "category": "containment",
            "annotation": "sample_op",
            "title": "title of the operation",
            "description": "description of the operation",
            "parameters": [
                {
                    "title": "title of list",
                    "type": "text",
                    "name": "sample_list",
                    "required": true/false,
                    "editable": true/false,
                    "visible": true/false,
                    "description": "description of the operation",
                    "tooltip": "text"
       },
                {

                    "type": "label",
                    "label": "label text",
                    "visible": true
       },
                {
                    "title": "title of list",
                    "type": "text",
                    "name": "sample_list",
                    "description": "description of the operation",
                    "required": true/false,
                    "editable": true/false,
                    "visible": true/false,
                    "class": "group-element",
                    "tooltip": "text"
       },
                {
                    "title": "title of list",
                    "type": "text",
                    "name": "sample_list",
                    "description": "description of the operation",
                    "required": true/false,
                    "editable": true/false,
                    "visible": true/false,
                    "class": "group-element",
                    "tooltip": "text"
       },
                {
                    "title": "title of list",
                    "type": "text",
                    "name": "sample_list",
                    "description": "description of the operation",
                    "required": true/false,
                    "editable": true/false,
                    "visible": true/false,
                    "class": "group-element last",
                    "tooltip": "text"
       }
      ],
            "enabled": true,
            "output_schema": {}
    }
 ],
 "playbooks": [
   {
   }
 ]
}
Notes:

  • The version of the connector must be in the x.y.z format, for example, 1.0.0. Version must consist of valid integers, for example, "1.15.125" is a valid version.

  • The output_schema defines the keys that are present in the output json on the execution of an operation. The info.json contains some common keys. However, the output json can have additional keys based on the input parameters. You can use these json keys to set the input for subsequent Playbook Steps, using the Dynamic Values. For more information, see the Dynamic Values section in "Playbooks."

  • If you want to add online and/or offline documentation for your connector, add the following to your info.json:
    help_file: "name of pdf file in the connector folder"
    help_online: "link to the online documentation for the connector"

  • Input types supported: text, checkbox, integer, decimal, datetime, phone, email, file, richtext, json, textarea, image, select, and multiselect.
    For select and multiselect, you can provide the list of inputs using the options key.
    For example,

{  

      "title": "Sample Field",
      "name": "sample",
      "required": "true",
      "editable": "true",
      "visible": "true",
      "type": "select",
      "options": ["A","B","C"]      
}  
  • category and annotation within operations: The category defines the category for the connector that you are adding, and it must be one of the following: investigation, remediation, containment and miscellaneous.
    The annotation defines the operation or function that will be performed. An annotation is unique and belongs to only one category, i.e., you must not add an annotation to multiple categories.
    If you do not define any category in the info.json file, then by default, the annotation is added to the miscellaneous category.
    The category name must contain only lower-case alphabets. The annotation name must contain only lower-case alphabets, underscores, and numbers.
    Category and annotations must always come together.
    Multiple operations within a connector can use the same annotation.

  • description: You can add a description for the connector, which will be visible on the connector page in FortiSOAR™ and you can also add a description for the action or operation, which will be visible on the connector step page in the Playbook Designer.

  • tooltip: You can add the tooltip parameter to any field to display information about that particular field. Note that if you do not want a tooltip against any field, then you must remove the tooltip parameter from that field in the info.json. You must not pass "" or null as values to the tooltip parameter.

  • placeholder: You can add the placeholder parameter for text and select fields, which will display placeholders for those fields on the connector step page in the Playbook Designer.
  • conditional fields (onchange): You can add the onchange parameter to fields, which you can use to display other fields or subfields conditionally based on the user input for that field. For example:
{
  "options": ["Now", "Yesterday"],
  "onchange": {
                "Now": [{
                  "title": "Comment3",
                  "required": true,
                  "editable": true,
                  "visible": true,
                  "type": "text",
                  "name": "comment3",
                  "value": ""
                }], 
                "Yesterday": [{
                  "title": "Comment4",
                  "required": true,
                  "editable": true,
                  "visible": true,
                  "type": "text",
                  "name": "comment4",
                  "value": ""
                }]
  }
}
  • visible_onchange: For backward compatibility of the connector you can use the visible_onchange parameter for conditional fields (onchange parameter).
    If you set visible_onchange to false, then this field will be hidden in FortiSOAR™ UI, and if you set visible_onchange to true, or if it is not present for any field, then this field is visible in FortiSOAR™ UI.

  • validation: You can add regex validation to text and textarea fields. You can also add the error that will be displayed in case the validation fails. For example:

{
 "validation":{
            "pattern":"\\d+",
            "patternError":"this is not a number"
          }
}
  • label: You can add the label field to display text on the connector UI. For example:
{
"type": "label",
"label": "this is my label",
"visible": true
}
  • grouping: You can group fields based on your categorization using "class": "group-element". For the last field in the group, use "class": "group-element last".
    For example:
{
       "operation": "block_applications",
       "parameters": [

          {

              "type": "label",
              "label": "this is my label",
              "visible": true
       },
           {
               "title": "Applications Names(List Format)",
                "type": "text",
                "name": "app_list",
                "required": true,
                "editable": true,
                "visible": true,
                "class": "group-element",
                "tooltip": "Block Applications Names (List Format)"
       },

           {
               "title": "Applications Names(List Format)",
               "type": "text",
                "name": "app_list",
                "required": true,
                "editable": true,
                "visible": true,
               "class": "group-element last",
              "tooltip": "Block Applications Names (List Format)"
       }
     ]
 }
  • apiOperations: You can fetch options for the select and multiselect fields from the API that you have defined in your operation. The parameters to this operation will be what users have entered in the configuration of this operation and the target field. apiOperations is not supported for the connector configuration.
    Note: To hide this operation in the from the Actions drop-down list in the Playbook Designer set "visible": false for this operation.
  • conditional_output_schema: Support for multi-option or dynamic output schema in connectors. In every operation that requires the dynamic output schema, you must add conditional_output_schema as a key in an array of objects. Each object will contain the condition, which you should add within {{ }} and then you must add the corresponding output schema for each condition. It is recommended that you add a default schema, using "condition": "{{true}}", at the end of the defined conditions. The default schema will be used if none of the defined conditions are met.
    Notes:
    1) If you are using multiple conditions for evaluation such as a combination of && and ||, then you must wrap the whole condition within ().
    For example, {{(command === 'ls' || command === 'ssh' )}}
    {{(command === 'ls' && port === 5895 )}}
    2) If you are using the condition with the checkbox field, add the condition as:
    {{ checkbox === true}}
    3) If you are using the condition with the multi-select field, add the condition as:
    {{multsel.toString() === (['option1','option2']).toString()}}
    4) If you are using the condition with the json field, add the condition as:
    {{jsonfieldname === '{\"key\":\"value\"}'}}
    For example, {{jsonfieldname === '{\"name\":\"fortinet\"}'}}
    Important: In order to support versions earlier to the 4.12.0 version, output_schema will also always be present.
    Example of a conditional_output_schema definition:
{
       "conditional_output_schema": [                 
          {
                  "condition": "{{command === 'ls'}}",
                  "output_schema": {
                      "op_result": "",
                      "op_status": ""
                  }
              },
              {
                  "condition": "{{command === 'ssh'}}",
                  "output_schema": {
                      "result": "",
                      "status": ""
                  }
              },                 
              {
                  "condition": "{{true}}",
                  "output_schema": {
                      "result_default": "",
                      "status": ""
                  }
              }
     ]
 }

connector.py

The connector.py class extends the base connector class and implements the check_health and execute functions. Following is a skeleton of this class:

from connectors.core.connector import Connector, get_logger
logger = get_logger('<connector_name>')

class Template(Connector):
   def execute(self, config, operation, params, **kwargs):
    supported_operations = {'operation_1': function_template}
    return supported_operations[operation](config, params)

   def check_health(self, input):
       return True

Notes:

  • All imports for the connector files should be relative. For example, if your util.py is parallel to connector.py and you want to import util.py then you must import it as: import .util.
  • get_logger is a utility function to initialize the logger. You can import get_logger from connectors.core.connector, and then declare the logger as logger = get_logger('<connector name>'). All the connector logs are written to the /var/log/cyops-integrations/connectors.log file and follow the format: %(asctime)s %(levelname)s %(name)s %(module)s %(funcName)s(): %(message)s.
  • In addition to the execute and check_health functions, the following optional and additional functions are also available:
    on_add_config(self, config): Invoked when a new configuration is added to the connector. This is an optional function that can be overridden while setting up a new configuration.
    on_update_config(selfself, old_config, new_config): Invoked when a configuration is updated for the connector. This is an optional function that can be overridden while setting up a configuration edit function.
    on_delete_config(self, config): Invoked when a configuration is deleted from the connector. This is an optional function that can be overridden while setting up a configuration teardown function.
    on_activate(self, config) : Invoked when a configuration is activated.
    on_deactivate(self, config) : Invoked when a configuration is deactivated.
    on_teardown(self) : Invoked when a configuration is deleted. This is an optional function that can be overridden for dismantling a connector.
    You can use these functions to perform specific operations such as starting or stopping of a service at the relevant events. For example, you can use the on_add_config() function to start and stop a service when a configuration is added.

playbooks.json

The playbook.json file contains any playbook collection that you want to include with your connector. This could be a set of playbooks that demonstrate the usage of your connector.

images

The images directory must have the connector icon files. The 'icon_small_name' and 'icon_large_name' keys in the info.json must match the names of these icon files inside the images folder. Icon files can be in the .jpg or .png formats.

Once you have created all the files, bundle them into a .tgz file. For example, tar -czvf sampleConnector.tgz sampleConnector/.

requirements.txt and packages

If a connector requires additional python libraries, specify the libraries in the requirements.txt file.

If there is a dependency on any custom packages or if your instance does not have internet access to download packages from the internet, you can add the packages to the packages directory in the connector folder.

During a connector import, the framework first runs pip install -r requirements.txt followed by pip install <package> for every package in the packages directory. The commands are run in a separate thread and import is marked successful even when the dependency installation is still in progress. The dependency install logs are available at /var/log/cyops-integrations/pipinstall_<timestamp>.log on the FortiSOAR™ instance. If more than five dependency install log files get accumulated, the log files that are older than a day get deleted.

If a dependency install fails, then you can install them again by invoking the REST APIs directly. Contact a FortiSOAR™ representative for more details on the APIs.

Import the connector into FortiSOAR™ prior to version 5.0.0

To import connectors into FortiSOAR™, you must be assigned a role that has a minimum of Create access to the Connectors module.

Important

To import and configure a connector in FortiSOAR™ 5.0.0 and later, see the Introduction to connectors chapter.

  1. Log on to FortiSOAR™.
  2. On the left navigation pane, click Automation > Connectors and click Add Connector.
    FortiSOAR™ UI - Add Connector screen
  3. Drag-and-drop the connector package file or click Browse File to import the connector.tgz file.
    FortiSOAR™ will prompt you to enter the configuration inputs that you have defined in the info.json file.
    Note: You can install different versions of a connector, enabling you to reference a specific version of a connector from a playbook. If you want to replace all previous versions of the connector, ensure that you click the Delete all existing versions checkbox while importing the new version of the connector. If you do not click the Delete all existing versions checkbox, then a new version of the connector is added. You must ensure that your playbooks reference a correct and existing version of the connector.
    Following is a sample image:
    Connector - Browse File dialog
    FortiSOAR™ displays the Uploading Connector message and then displays the Connector Configuration popup.
  4. To configure the connector, the Connector Configuration popup enter the required configuration details.
    The configuration details and the details of the connector specified in the info.json file are stored in the FortiSOAR™ database.
    Note: You can add multiple configurations for your connector if you have more than one instance of your third-party server in your environment. You must, therefore, add a unique Name for each configuration.
    If you have previous versions of a connector and you are configuring a newer version of that connector, with the same configuration parameters, then FortiSOAR™ fetches the configuration and input parameters of the latest available version of that connector. For example, If you have 1.0.0, 2.0.0, and 2.3.0 versions of the Fortinet FortiSIEM connector and you are configuring the 2.3.0 version of the Fortinet FortiSIEM connector, then while configuring the 2.3.0 version, FortiSOAR™ will fetch the configuration and input parameters from the 2.0.0 version of the Fortinet FortiSIEM connector. You can review the configuration and input parameters, and then decide to change them or leave them unchanged.
    Following is a sample image:
    Configuring a new connector
    You can activate or deactivate a configured connector by clicking on the Activate Connector or Deactivate Connector Link.
    You can check the Mark As Default Configuration option to make the selected configuration, the default configuration of this connector, on the particular FortiSOAR™ instance.
    The password type fields in FortiSOAR™ include encryption and decryption. Passwords are encrypted before saving them into the database and decrypted when they are used in actions. In case of an upgrade, connectors that are already installed will work with stored passwords.
  5. To save your configuration, click Save.
    To view the list of actions that can be performed by the connector, click the Actions tab.
    To view the playbook file that is bundled with the connector, click the Playbooks tab.
    You can optionally perform a Health Check by clicking the Refresh icon that is present in the Health Check bar. The Health Check checks if the configuration parameters you have specified are correct and if connectivity can be established to the specified server, endpoint or API.
    If all the details are correct and the connectivity to the server can be established, then on the Connectors page, Available is displayed in the health check dialog.
    If any or all the details are incorrect or if the connectivity to the server cannot be established then on the Connectors page, Disconnected is displayed in the health check dialog.
    You can also click the Refresh icon that is present in the Health Check bar to perform the health check at any time.

Reimporting a connector

After importing a connector, any changes done in the python files of the connector automatically get reflected the next time you run a command on the connector. However, if changes are made in the info.json, then you need to reimport the connector, using the following command, for the updates to take effect:
/opt/cyops-integrations/.env/bin/python /opt/cyops-integrations/integrations/manage.py reimport_connector -n <connector_name> -cv <connector_version> -migrate

If you only want to update the info.json changes and not retain the previous connector configuration, then you can omit the -migrate attribute as follows:
/opt/cyops-integrations/.env/bin/python /opt/cyops-integrations/integrations/manage.py reimport_connector -n <connector_name> -cv <connector_version>

You can also reimport all connectors at a single time using the following command by omitting the -n <connector_name> and -cv <connector_version> attributes as follows:
/opt/cyops-integrations/.env/bin/python /opt/cyops-integrations/integrations/manage.py reimport_connector -migrate

Check_Health function

The check_health function of the connector is invoked when you click the Refresh icon. This function takes the dictionary of the configuration parameters as the input. For example: {‘url: https://xyz.com, 'user': 'admin', 'password': 'password'}.

You must throw the ConnectorError from the function if you want the check_health function to fail in a given scenario, such as issues with connectivity or with the provided credentials. To throw the ConnectorError, you must import it from the connectors.core.connector module as follows:

from connectors.core.connector import ConnectorError

Add connector operation to a playbook

Once you have completed configuring and deploying your connector, you can add a connector operation to a playbook, by adding the connector as a step in the playbook, as shown in the following image:

Adding a connector operation to a playbook

You can install different versions of a connector, and while adding a connector operation, you specify a specific version of a connector within a Playbook. In case you have installed multiple connectors, and if the version of the connector specified in the playbook is not found, then the playbook by default uses the latest version. FortiSOAR™ checks for the latest version of the connector in the format "major version.minor version.patch version". For example, version 2.0.2 is a later version than 1.2.0.

The execute function of connector.py is called when an operation on the connector is invoked. This function takes the dictionary containing the config, operation and params fields. For example:

{'config': {'password': password, 'server_url': 'https://xyz.com', 'user': 'admin'}, 
'params': {'input1': 'value1', 'input2': 'value2'}, 
'operation': 'function_template'}

The return from the execute function is set in the results.data variable of the playbook step. A sample execute function is present in the connector.py section.

The info.json contains output_schema, which defines the keys that are present in the output json on the execution of an operation. The info.json contains some common keys. However, the output json can have additional keys based on the input parameters. You can use these json keys to set the input for subsequent Playbook Steps, using Dynamic Values. For more information, see the Dynamic Values section in the "Playbooks Guide."

Configuring a connector to return a response

If you want to return a response from any action of a connector, then you can import the Result class from the connectors framework to your connector.py and then you can set message attributes such as status, message, etc.

Following is the python snippet for the same:

Result class import from the connectors framework

Updating a connector configuration using the update_connnector_config() function

The update_connnector_config() function can be internally called from any connector to update the configuration of any connector by providing the name and version of that connector. Steps to be followed for updating a connector configuration:

  1. Import the update_connnector_config() function from /opt/cyops-integrations/integrations/connectors/core/utils.py.
  2. Call the update_connnector_config function with the following parameters: <connector_name>, <connector_version>, <update_config>, and <config_id>.
    update_connnector_config(<connector_name>,<connector_version>,<update_config>,<config_id>)
    For example, update_connnector_config("imap","3.2.0",{"username":"csdamin","password":"changeme"},"5785130913212321")
    Notes:
    If you do not provide the <config_id>, then the connector configuration that you have marked as default configuration will be updated.
    If you have not marked any connector configuration as the default configuration, and you have also not provided the <config_id>, then the following error is raised: No configuration found to update. Please add a config_id or mark a configuration as the default. in the /var/log/cyops/cyops-integrations/connectors.log. To resolve this error, either mark a connector configuration as the default configuration or provide the <config_id>.

CyOPs™ Connector SDK

The CyOPs™ Connector SDK consists of a simulator for writing and testing your connector. You can use this CyOPs™-provided CLI to help you develop your custom connector, without having a CyOPs™ instance.

You can use the CyOPs™ Connector SDK to write a custom connector and also to perform these additional functions:

  • Add or update the connector metadata, the configuration details, and operations supported for the connector.
  • Import with the SDK and configure the connector.
  • List all connectors imported with the SDK.
  • Run health check on these installed connectors.
  • List the supported operations for a given connector.
  • List the configurations for a given connector.
  • Execute an operation on a connector.
  • Remove a connector.

If you want to use the CyOPs™ Connector SDK to develop a custom connector, you can request your CyOPs™ Customer Success Representative to provide you with an installable. The CyOPs™ Connector SDK will be provided to you in a .tgz format. You can also download the CyOPs™ Connector SDK from the Fortinet Support Site. You must log onto the support site to view information.

Dependencies while deploying the Connector SDK on a standalone Centos 7 - Minimal Edition

  • Python3.6+ compiled with sqlite-devel and openssl-devel
  • virtualenv-15.1.0
  • openssl-devel

Setting up the CyOPs™ Connector SDK project

Copy and extract the CyOPs™ Connector SDK that your CyOPs™ Customer Success Representative has provided to you .tgz format. Ensure that the .tgz file is extracted in your SDK Folder.

You must perform the following steps for a one-time setup of the CyOPs™ Connector SDK project:

  1. Create a virtual environment with python 3.6+ using the following command:
    virtualenv -p <path_to_python> <path_to_virtualenv>
    For example: virtualenv -p /usr/local/bin/python3/3.6.3/bin/python3 ~/workspace/integrations-sdk/.env
  2. Activate the environment.
    For example, source ~/workspace/integrations-sdk/.env/bin/activate
  3. Install the requirements
    cd integrations
    pip install -r requirements.txt
  4. Setup the database
    cd integrations
    ./setupsdk.py

Using the CyOPs™ Connector SDK

  1. To get started with building and testing new connectors, and create the connector directory, run the following command:
    ./cs_sdk.py --option create_template --name <connector_name> --version <connector version>
    For more details on the options available with cs_sdk.py, use the help command: ./cs_sdk.py -h or ./cs_sdk.py --help.
    By default, the connector directory gets created in the same location as your cs_sdk.py file. If you want to override the default location, you must enter the target directory.
    Once the connector directory is created, the CyOPs™ Connector SDK displays the following message:
    Well done! Your directory <directory name> is created. Use --option add_info --name <connector_name> --version <connector version>’ to add the connector metadata.
  2. To add the info.json for your connector, run the following command:
    ./cs_sdk.py --option add_info --name <connector_name> --version <connector version>
    Enter the following details for creating the info.json for your connector:
    Connector Name:
    Description:
    Version:
    Publisher:
    Category:
    Is the connector approved by Cybersponse (Y/Yes/N/No):
    Is the connector compatible with Cybersponse (Y/Yes/N/No):
    File path to a small icon for the connector:
    File path to a large icon for the connector:
    Once the info.json for your connector is updated based on the information you have provided, the CyOPs™ Connector SDK displays the following message:
    Well done! The connector info.json has been updated with the above information for the connector. Use--option add_config_params --name <connector_name> --version <connector version>to add the connector configuration parameters.
  3. To add configuration parameters for your connector, run the following command:
    ./cs_sdk.py --option add_config_params --name <connector_name> --version <connector version>
    Enter the following details for adding the configuration input parameters for your connector:
    Field Name:
    Is it a required field (Y/Yes/N/No:
    Is it a user-editable field (Y/Yes/N/No):
    Is it a field visible to the user (Y/Yes/N/No):
    Would you like to add another field (Y/Yes/N/No):
    //Repeats till the user enters No for the 'Would you like to add another field' option
    Once you have added input parameters required to configure your connector, the CyOPs™ Connector SDK displays the following message:
    Well done! The configuration input parameters have been added successfully.
    Implement the health check function for the connector at <connector_locn>/health_check.py.
    Use --option add_operation --name <connector_name> --version <connector version>’ to add operations on the connector.
  4. To add operations that would be supported by your connector, run the following command:
    ./cs_sdk.py --option add_operation --name <connector_name> --version <connector version>
    Enter the following details for adding the operations that would be supported by your connector:
    Operation Name:
    Operation description:
    Is the operation enabled on the connector (Y/Yes/N/No):
    //Specify the input parameters required for the above operations:
    Parameter name:
    Is a required parameter (Y/Yes/N/No):
    Is a visible parameter (Y/Yes/N/No):
    Is an editable parameter (Y/Yes/N/No):
    Default value for the parameter:
    Add another parameter (Y/Yes/N/No):
    //Repeats till the user enters No for the 'Add another parameter' option
    Once you have completed adding all the parameters for the supported operation, displays CyOPs™ Connector SDK following message:
    Well done! The operation has been added. Add the operations implementation in <connector_location>/<operation_name>.py:
    To add another operation that is supported by your connector:
    Add another operation (Y/Yes/N/No):
    //This adds another operation that would be supported by your connector. It repeats till the user enters No for the 'Add another operation' option
    Once you have added all the operations supported by your connector, the CyOPs™ Connector SDK displays the following message:
    Well done! The supported operations have been added successfully.
    Ensure that you add the function implementations for the supported operations before importing the connector with the SDK.
  5. Start the application server using the following command:
    python manage.py runserver
  6. To import your connector with the CyOPs™ Connector SDK, run the following command:
    ./cs_sdk.py --option import --name <connector_name> --bundle <path to connector archive> --path <path to connector folder>
    <path to connector archive> : The .tgz file of the connector bundle.
    Or
    <path to connector folder> : The absolute path to the connector folder. The SDK will create a .tar file and import it into CyOPs™.
    If you have used cs_sdk.py to generate the connector template, then the SDK already has the path. In that case, this is an optional parameter that takes precedence over the existing path.
    Once your connector is imported with the SDK, the CyOPs™ Connector SDK displays the following message:
    Well done! The connector has been successfully imported.
    You can use the following commands for various operations:
    Use --option configure --name <connector_name> --version <connector version>’ to provide the configuration inputs and set up the connector.
    Use --option remove --name <connector_name> --version <connector version>’ to remove the connector.
    Use --option export --name <connector_name> --version <connector version>’ to export the connector into a .tgz file.
  7. To set up the connector and provide configuration inputs, run the following command:
    ./cs_sdk.py --option configure --name <connector_name> --version <connector version>
    Enter the following details for adding configuration inputs for your connector:
    Field 1:
    Field 2: . . .
    The field names that you are prompted for are based on the data provided in the info.json of the connector.
    Once your connector is configured, the CyOPs™ Connector SDK displays the following message:
    Well done! The connector has been configured.
    The check_health response is: <output from health check function>
    You can use the following commands for various operations:
    --option check_health--name <connector_name> --version <connector_version> --config <config_name>’ to check the connector health again
    --option execute’ to execute any operation on the connector
    --option list_operation’ to list operations available on any connector
    --option list_connectors’ to list all imported connectors
    --option list_configsto list all configurations for all imported connectors
    --option list_configs --name <connector_name> --version <connector version>to list all configurations for the specified connector
  8. To execute an operation supported by your connector, run the following command:
    ./cs_sdk.py --option execute --name <connector_name> --version <connector_version> --config <config_name> --operation <operation_name>
    Enter the configuration parameters required to execute the operation:
    Field 1:
    Field 2: . . .
    Once the operation has been executed, the CyOPs™ Connector SDK displays the <output from the execute function>.
  9. To export the connector, run the following command:
    ./cs_sdk.py --option export --name <connector_name> --version <connector_version>
    This creates a .tgz file of the exported connector.
  10. To remove the connector from the CyOPs™ Connector SDK, run the following command:
    ./cs_sdk.py --option remove ---name <connector_name> --version <connector_version>
  11. To list the connectors available within the CyOPs™ Connector SDK, run the following command:
    ./cs_sdk.py --option list_connectors
  12. To list the operations available for a connector, run the following command:
    ./cs_sdk.py --option list_operations --name <connector_name> --version <connector_version>