Ejemplo n.º 1
0
def _fetch_conjur_variable(conjur_variable, token, conjur_url, account):
    token = b64encode(token)
    headers = {'Authorization': 'Token token="{0}"'.format(token)}
    display.vvvv('Header: {0}'.format(headers))

    url = '{0}/secrets/{1}/variable/{2}'.format(conjur_url, account,
                                                quote_plus(conjur_variable))
    display.vvvv('Conjur Variable URL: {0}'.format(url))

    response = open_url(url, headers=headers, method='GET')

    if response.getcode() == 200:
        display.vvvv('Conjur variable {0} was successfully retrieved'.format(
            conjur_variable))
        return [response.read()]
    if response.getcode() == 401:
        raise AnsibleError(
            'Conjur request has invalid authorization credentials')
    if response.getcode() == 403:
        raise AnsibleError(
            'The controlling host\'s Conjur identity does not have authorization to retrieve {0}'
            .format(conjur_variable))
    if response.getcode() == 404:
        raise AnsibleError(
            'The variable {0} does not exist'.format(conjur_variable))

    return {}
Ejemplo n.º 2
0
def waitForNoTask(client, name, timeout):
    currentTimeout = timeout
    while client.get('/ip/{0}/task'.format(quote_plus(name)),
                     function='genericMoveFloatingIp',
                     status='todo'):
        time.sleep(1)  # Delay for 1 sec
        currentTimeout -= 1
        if currentTimeout < 0:
            return False
    return True
Ejemplo n.º 3
0
def _fetch_conjur_token(conjur_url, account, username, api_key,
                        validate_certs):
    conjur_url = '{0}/authn/{1}/{2}/authenticate'.format(
        conjur_url, account, quote_plus(username))
    display.vvvv(
        'Authentication request to Conjur at: {0}, with user: {1}'.format(
            conjur_url, quote_plus(username)))

    response = open_url(conjur_url,
                        data=api_key,
                        method='POST',
                        validate_certs=validate_certs)
    code = response.getcode()
    if code != 200:
        raise AnsibleError(
            'Failed to authenticate as \'{0}\' (got {1} response)'.format(
                username, code))

    return response.read()
Ejemplo n.º 4
0
def waitForTaskDone(client, name, taskId, timeout):
    currentTimeout = timeout
    while True:
        task = client.get('/ip/{0}/task/{1}'.format(quote_plus(name), taskId))
        if task['status'] == 'done':
            return True
        time.sleep(5)  # Delay for 5 sec because it's long to wait completion, do not harass the API
        currentTimeout -= 5
        if currentTimeout < 0:
            return False
Ejemplo n.º 5
0
def set_offense_values(module, qradar_request):
    if module.params["closing_reason"]:
        found_closing_reason = qradar_request.get_by_path(
            "api/siem/offense_closing_reasons?filter={0}".format(
                quote_plus('text="{0}"'.format(
                    module.params["closing_reason"]))))
        if found_closing_reason:
            module.params["closing_reason_id"] = found_closing_reason[0]["id"]
        else:
            module.fail_json("Unable to find closing_reason text: {0}".format(
                module.params["closing_reason"]))

    if module.params["status"]:
        module.params["status"] = module.params["status"].upper()
Ejemplo n.º 6
0
def main():

    argspec = dict(name=dict(required=False, type="str"))

    module = AnsibleModule(argument_spec=argspec, supports_check_mode=True)

    splunk_request = SplunkRequest(
        module, headers={"Content-Type": "application/json"})

    if module.params["name"]:
        try:
            query_dict = splunk_request.get_by_path(
                "servicesNS/nobody/SplunkEnterpriseSecuritySuite/saved/searches/{0}"
                .format(quote_plus(module.params["name"])))
        except HTTPError as e:
            # the data monitor doesn't exist
            query_dict = {}
    else:
        query_dict = splunk_request.get_by_path(
            "servicesNS/nobody/SplunkEnterpriseSecuritySuite/saved/searches")

    module.exit_json(changed=False, splunk_correlation_search_info=query_dict)
Ejemplo n.º 7
0
def _fetch_conjur_variable(conjur_variable, token, conjur_url, account):
    token = b64encode(token)
    headers = {'Authorization': 'Token token="{0}"'.format(token)}
    display.vvvv('Header: {0}'.format(headers))

    url = '{0}/secrets/{1}/variable/{2}'.format(conjur_url, account, quote_plus(conjur_variable))
    display.vvvv('Conjur Variable URL: {0}'.format(url))

    response = open_url(url, headers=headers, method='GET')

    if response.getcode() == 200:
        display.vvvv('Conjur variable {0} was successfully retrieved'.format(conjur_variable))
        return [response.read()]
    if response.getcode() == 401:
        raise AnsibleError('Conjur request has invalid authorization credentials')
    if response.getcode() == 403:
        raise AnsibleError('The controlling host\'s Conjur identity does not have authorization to retrieve {0}'
                           .format(conjur_variable))
    if response.getcode() == 404:
        raise AnsibleError('The variable {0} does not exist'.format(conjur_variable))

    return {}
Ejemplo n.º 8
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            name=dict(required=True),
            service=dict(required=True),
            endpoint=dict(required=True),
            wait_completion=dict(default=True, type='bool'),
            wait_task_completion=dict(default=0, type='int'),
            application_key=dict(required=True, no_log=True),
            application_secret=dict(required=True, no_log=True),
            consumer_key=dict(required=True, no_log=True),
            timeout=dict(default=120, type='int')
        ),
        supports_check_mode=True
    )

    result = dict(
        changed=False
    )

    if not HAS_OVH:
        module.fail_json(msg='ovh-api python module is required to run this module ')

    # Get parameters
    name = module.params.get('name')
    service = module.params.get('service')
    timeout = module.params.get('timeout')
    wait_completion = module.params.get('wait_completion')
    wait_task_completion = module.params.get('wait_task_completion')

    # Connect to OVH API
    client = getOvhClient(module)

    # Check that the load balancing exists
    try:
        ips = client.get('/ip', ip=name, type='failover')
    except APIError as apiError:
        module.fail_json(
            msg='Unable to call OVH api for getting the list of ips, '
                'check application key, secret, consumerkey and parameters. '
                'Error returned by OVH api was : {0}'.format(apiError))

    if name not in ips and '{0}/32'.format(name) not in ips:
        module.fail_json(msg='IP {0} does not exist'.format(name))

    # Check that no task is pending before going on
    try:
        if not waitForNoTask(client, name, timeout):
            module.fail_json(
                msg='Timeout of {0} seconds while waiting for no pending '
                    'tasks before executing the module '.format(timeout))
    except APIError as apiError:
        module.fail_json(
            msg='Unable to call OVH api for getting the list of pending tasks '
                'of the ip, check application key, secret, consumerkey '
                'and parameters. Error returned by OVH api was : {0}'
                .format(apiError))

    try:
        ipproperties = client.get('/ip/{0}'.format(quote_plus(name)))
    except APIError as apiError:
        module.fail_json(
            msg='Unable to call OVH api for getting the properties '
                'of the ip, check application key, secret, consumerkey '
                'and parameters. Error returned by OVH api was : {0}'
            .format(apiError))

    if ipproperties['routedTo']['serviceName'] != service:
        if not module.check_mode:
            if wait_task_completion == 0:
                # Move the IP and get the created taskId
                task = client.post('/ip/{0}/move'.format(quote_plus(name)), to=service)
                taskId = task['taskId']
                result['moved'] = True
            else:
                # Just wait for the given taskId to be completed
                taskId = wait_task_completion
                result['moved'] = False
            result['taskId'] = taskId
            if wait_completion or wait_task_completion != 0:
                if not waitForTaskDone(client, name, taskId, timeout):
                    module.fail_json(
                        msg='Timeout of {0} seconds while waiting for completion '
                            'of move ip to service'.format(timeout))
                result['waited'] = True
            else:
                result['waited'] = False
        result['changed'] = True

    module.exit_json(**result)
Ejemplo n.º 9
0
def main():

    argspec = dict(
        state=dict(
            required=False,
            choices=["present", "absent", "enabled", "disable"],
            default="present",
            type="str",
        ),
        connection_host=dict(required=False,
                             choices=["ip", "dns", "none"],
                             default="ip",
                             type="str"),
        host=dict(required=False, type="str", default=None),
        index=dict(required=False, type="str", default=None),
        name=dict(required=True, type="str"),
        protocol=dict(required=True, type="str", choices=["tcp", "udp"]),
        queue=dict(
            required=False,
            type="str",
            choices=["parsingQueue", "indexQueue"],
            default="parsingQueue",
        ),
        rawTcpDoneTimeout=dict(required=False, type="int", default=10),
        restrictToHost=dict(required=False, type="str", default=None),
        ssl=dict(required=False, type="bool", default=None),
        source=dict(required=False, type="str", default=None),
        sourcetype=dict(required=False, type="str", default=None),
        datatype=dict(required=False, choices=["cooked", "raw"],
                      default="raw"),
    )

    module = AnsibleModule(argument_spec=argspec, supports_check_mode=True)

    splunk_request = SplunkRequest(
        module,
        headers={"Content-Type": "application/x-www-form-urlencoded"},
        not_rest_data_keys=["state", "datatype", "protocol"],
    )
    # This is where the splunk_* args are processed
    request_data = splunk_request.get_data()

    query_dict = splunk_request.get_by_path(
        "servicesNS/nobody/search/data/inputs/{0}/{1}/{2}".format(
            quote_plus(module.params["protocol"]),
            quote_plus(module.params["datatype"]),
            quote_plus(module.params["name"]),
        ))

    if module.params["state"] in ["present", "enabled", "disabled"]:
        _data = splunk_request.get_data()
        if module.params["state"] in ["present", "enabled"]:
            _data["disabled"] = False
        else:
            _data["disabled"] = True
        if query_dict:
            needs_change = False
            for arg in request_data:
                if arg in query_dict["entry"][0]["content"]:
                    if to_text(
                            query_dict["entry"][0]["content"][arg]) != to_text(
                                request_data[arg]):
                        needs_change = True
            if not needs_change:
                module.exit_json(changed=False,
                                 msg="Nothing to do.",
                                 splunk_data=query_dict)
            if module.check_mode and needs_change:
                module.exit_json(
                    changed=True,
                    msg="A change would have been made if not in check mode.",
                    splunk_data=query_dict,
                )
            if needs_change:
                splunk_data = splunk_request.create_update(
                    "servicesNS/nobody/search/data/inputs/{0}/{1}/{2}".format(
                        quote_plus(module.params["protocol"]),
                        quote_plus(module.params["datatype"]),
                        quote_plus(module.params["name"]),
                        data=urlencode(_data),
                    ))
            if module.params["state"] in ["present", "enabled"]:
                module.exit_json(changed=True,
                                 msg="{0} updated.",
                                 splunk_data=splunk_data)
            else:
                module.exit_json(changed=True,
                                 msg="{0} disabled.",
                                 splunk_data=splunk_data)
        else:
            # Create it
            splunk_data = splunk_request.create_update(
                "servicesNS/nobody/search/data/inputs/{0}/{1}".format(
                    quote_plus(module.params["protocol"]),
                    quote_plus(module.params["datatype"]),
                ),
                data=urlencode(_data),
            )
            module.exit_json(changed=True,
                             msg="{0} created.",
                             splunk_data=splunk_data)
    elif module.params["state"] == "absent":
        if query_dict:
            splunk_data = splunk_request.delete_by_path(
                "servicesNS/nobody/search/data/inputs/{0}/{1}/{2}".format(
                    quote_plus(module.params["protocol"]),
                    quote_plus(module.params["datatype"]),
                    quote_plus(module.params["name"]),
                ))
            module.exit_json(
                changed=True,
                msg="Deleted {0}.".format(module.params["name"]),
                splunk_data=splunk_data,
            )

    module.exit_json(changed=False, msg="Nothing to do.", splunk_data={})
Ejemplo n.º 10
0
def main():

    argspec = dict(
        name=dict(required=True, type='str'),
        description=dict(required=True, type='str'),
        state=dict(choices=['present', 'absent'], required=True),
        search=dict(required=True, type='str'),
        app=dict(type="str",
                 required=False,
                 default="SplunkEnterpriseSecuritySuite"),
        ui_dispatch_context=dict(type="str", required=False),
        time_earliest=dict(type="str", required=False, default="-24h"),
        time_latest=dict(type="str", required=False, default="now"),
        cron_schedule=dict(type="str", required=False, default="*/5 * * * *"),
        scheduling=dict(type="str",
                        required=False,
                        default="real-time",
                        choices=["real-time", "continuous"]),
        schedule_window=dict(type="str", required=False, default="0"),
        schedule_priority=dict(type="str",
                               required=False,
                               default="Default",
                               choices=["Default", "Higher", "Highest"]),
        trigger_alert_when=dict(type="str",
                                required=False,
                                default="number of events",
                                choices=[
                                    "number of events", "number of results",
                                    "number of hosts", "number of sources"
                                ]),
        trigger_alert_when_condition=dict(type="str",
                                          required=False,
                                          default="greater than",
                                          choices=[
                                              "greater than", "less than",
                                              "equal to", "not equal to",
                                              "drops by", "rises by"
                                          ]),
        trigger_alert_when_value=dict(type="str", required=False,
                                      default="10"),
        throttle_window_duration=dict(type="str", required=False),
        throttle_fields_to_group_by=dict(type="str", required=False),
        suppress_alert=dict(type=bool, required=False, default=False),
    )

    module = AnsibleModule(argument_spec=argspec, supports_check_mode=True)

    splunk_request = SplunkRequest(
        module,
        headers={"Content-Type": "application/x-www-form-urlencoded"},
        not_rest_data_keys=['state'])

    try:
        query_dict = splunk_request.get_by_path(
            'servicesNS/nobody/SplunkEnterpriseSecuritySuite/saved/searches/{0}'
            .format(quote_plus(module.params['name'])))
    except HTTPError as e:
        # the data monitor doesn't exist
        query_dict = {}

    # Have to custom craft the data here because they overload the saved searches
    # endpoint in the rest api and we want to hide the nuance from the user
    request_post_data = {}
    request_post_data['name'] = module.params['name']
    request_post_data['action.correlationsearch.enabled'] = "1"
    request_post_data['is_scheduled'] = True
    request_post_data['dispatch.rt_backfill'] = True
    request_post_data['action.correlationsearch.label'] = module.params['name']
    request_post_data['description'] = module.params['description']
    request_post_data['search'] = module.params['search']
    request_post_data['request.ui_dispatch_app'] = module.params['app']
    if module.params['ui_dispatch_context']:
        request_post_data['request.ui_dispatch_context'] = module.params[
            'ui_dispatch_context']
    request_post_data['dispatch.earliest_time'] = module.params[
        'time_earliest']
    request_post_data['dispatch.latest_time'] = module.params['time_latest']
    request_post_data['cron_schedule'] = module.params['cron_schedule']
    if module.params['scheduling'] == 'real-time':
        request_post_data['realtime_schedule'] = True
    else:
        request_post_data['realtime_schedule'] = False
    request_post_data['schedule_window'] = module.params['schedule_window']
    request_post_data['schedule_priority'] = module.params[
        'schedule_priority'].lower()
    request_post_data['alert_type'] = module.params['trigger_alert_when']
    request_post_data['alert_comparator'] = module.params[
        'trigger_alert_when_condition']
    request_post_data['alert_threshold'] = module.params[
        'trigger_alert_when_value']
    request_post_data['alert.suppress'] = module.params['suppress_alert']

    if module.params['state'] == 'present':
        if query_dict:
            needs_change = False
            for arg in request_post_data:
                if arg in query_dict['entry'][0]['content']:
                    if to_text(
                            query_dict['entry'][0]['content'][arg]) != to_text(
                                request_post_data[arg]):
                        needs_change = True
            if not needs_change:
                module.exit_json(changed=False,
                                 msg="Nothing to do.",
                                 splunk_data=query_dict)
            if module.check_mode and needs_change:
                module.exit_json(
                    changed=True,
                    msg="A change would have been made if not in check mode.",
                    splunk_data=query_dict)
            if needs_change:
                # FIXME - need to find a reasonable way to deal with action.correlationsearch.enabled
                del request_post_data[
                    'name']  # If this is present, splunk assumes we're trying to create a new one wit the same name
                splunk_data = splunk_request.create_update(
                    'servicesNS/nobody/SplunkEnterpriseSecuritySuite/saved/searches/{0}'
                    .format(quote_plus(module.params['name'])),
                    data=urlencode(request_post_data))
                module.exit_json(changed=True,
                                 msg="{0} updated.",
                                 splunk_data=splunk_data)
        else:
            # Create it
            splunk_data = splunk_request.create_update(
                'servicesNS/nobody/SplunkEnterpriseSecuritySuite/saved/searches',
                data=urlencode(request_post_data))
            module.exit_json(changed=True,
                             msg="{0} created.",
                             splunk_data=splunk_data)

    if module.params['state'] == 'absent':
        if query_dict:
            splunk_data = splunk_request.delete_by_path(
                'services/saved/searches/{0}'.format(
                    quote_plus(module.params['name'])))
            module.exit_json(changed=True,
                             msg="Deleted {0}.".format(module.params['name']),
                             splunk_data=splunk_data)

    module.exit_json(changed=False,
                     msg="Nothing to do.",
                     splunk_data=query_dict)
def main():

    argspec = dict(
        name=dict(required=True, type="str"),
        correlation_search_name=dict(required=True, type="str"),
        description=dict(required=True, type="str"),
        state=dict(choices=["present", "absent"], required=True),
        security_domain=dict(
            choices=["access", "endpoint", "network", "threat", "identity", "audit"],
            required=False,
            default="threat",
        ),
        severity=dict(
            choices=["informational", "low", "medium", "high", "critical", "unknown"],
            required=False,
            default="high",
        ),
        default_owner=dict(required=False, type="str"),
        default_status=dict(
            choices=[
                "unassigned",
                "new",
                "in progress",
                "pending",
                "resolved",
                "closed",
            ],
            required=False,
            default="",
        ),
        drill_down_name=dict(required=False, type="str"),
        drill_down_search=dict(required=False, type="str"),
        drill_down_earliest_offset=dict(
            required=False, type="str", default="$info_min_time$"
        ),
        drill_down_latest_offset=dict(
            required=False, type="str", default="$info_max_time$"
        ),
        investigation_profiles=dict(required=False, type="str"),
        next_steps=dict(required=False, type="list", default=[]),
        recommended_actions=dict(required=False, type="list", default=[]),
        asset_extraction=dict(
            required=False,
            type="list",
            default=["src", "dest", "dvc", "orig_host"],
            choices=["src", "dest", "dvc", "orig_host"],
        ),
        identity_extraction=dict(
            required=False,
            type="list",
            default=["user", "src_user"],
            choices=["user", "src_user"],
        ),
    )

    module = AnsibleModule(argument_spec=argspec, supports_check_mode=True)

    splunk_request = SplunkRequest(
        module,
        headers={"Content-Type": "application/x-www-form-urlencoded"},
        not_rest_data_keys=["state"],
    )

    query_dict = splunk_request.get_by_path(
        "servicesNS/nobody/SplunkEnterpriseSecuritySuite/saved/searches/{0}".format(
            quote_plus(module.params["correlation_search_name"])
        )
    )

    # Have to custom craft the data here because they overload the saved searches
    # endpoint in the rest api and we want to hide the nuance from the user
    request_post_data = {}

    # FIXME  need to figure out how to properly support these, the possible values appear to
    #       be dynamically created based on what the search is indexing
    # request_post_data['action.notable.param.extract_assets'] = '[\"src\",\"dest\",\"dvc\",\"orig_host\"]'
    # request_post_data['action.notable.param.extract_identities'] = [\"src_user\",\"user\"]
    if module.params["next_steps"]:
        if len(module.params["next_steps"]) == 1:
            next_steps = "[[action|{0}]]".format(module.params["next_steps"][0])
        else:
            next_steps = ""
            for next_step in module.params["next_steps"]:
                if next_steps:
                    next_steps += "\n[[action|{0}]]".format(next_step)
                else:
                    next_steps = "[[action|{0}]]".format(next_step)

        # NOTE: version:1 appears to be hard coded when you create this via the splunk web UI
        #       but I don't know what it is/means because there's no docs on it
        next_steps_dict = {"version": 1, "data": next_steps}
        request_post_data["action.notable.param.next_steps"] = json.dumps(
            next_steps_dict
        )

    if module.params["recommended_actions"]:
        if len(module.params["recommended_actions"]) == 1:
            request_post_data[
                "action.notable.param.recommended_actions"
            ] = module.params["recommended_actions"][0]
        else:
            request_post_data["action.notable.param.recommended_actions"] = ",".join(
                module.params["recommended_actions"]
            )

    request_post_data["action.notable.param.rule_description"] = module.params[
        "description"
    ]
    request_post_data["action.notable.param.rule_title"] = module.params["name"]
    request_post_data["action.notable.param.security_domain"] = module.params[
        "security_domain"
    ]
    request_post_data["action.notable.param.severity"] = module.params["severity"]
    request_post_data["action.notable.param.asset_extraction"] = module.params[
        "asset_extraction"
    ]
    request_post_data["action.notable.param.identity_extraction"] = module.params[
        "identity_extraction"
    ]

    # NOTE: this field appears to be hard coded when you create this via the splunk web UI
    #       but I don't know what it is/means because there's no docs on it
    request_post_data["action.notable.param.verbose"] = "0"

    if module.params["default_owner"]:
        request_post_data["action.notable.param.default_owner"] = module.params[
            "default_owner"
        ]

    if module.params["default_status"]:
        request_post_data["action.notable.param.default_status"] = module.params[
            "default_status"
        ]

    if query_dict:
        request_post_data["search"] = query_dict["entry"][0]["content"]["search"]
        if "actions" in query_dict["entry"][0]["content"]:
            if query_dict["entry"][0]["content"]["actions"] == "notable":
                pass
            elif (
                len(query_dict["entry"][0]["content"]["actions"].split(",")) > 0
                and "notable" not in query_dict["entry"][0]["content"]["actions"]
            ):
                request_post_data["actions"] = (
                    query_dict["entry"][0]["content"]["actions"] + ", notable"
                )
            else:
                request_post_data["actions"] = "notable"
    else:
        module.fail_json(
            msg="Unable to find correlation search: {0}", splunk_data=splunk_data
        )

    if module.params["state"] == "present":
        needs_change = False
        for arg in request_post_data:
            if arg in query_dict["entry"][0]["content"]:
                if to_text(query_dict["entry"][0]["content"][arg]) != to_text(
                    request_post_data[arg]
                ):
                    needs_change = True
        if not needs_change:
            module.exit_json(
                changed=False, msg="Nothing to do.", splunk_data=query_dict
            )
        if module.check_mode and needs_change:
            module.exit_json(
                changed=True,
                msg="A change would have been made if not in check mode.",
                splunk_data=query_dict,
            )
        if needs_change:
            splunk_data = splunk_request.create_update(
                "servicesNS/nobody/SplunkEnterpriseSecuritySuite/saved/searches/{0}".format(
                    quote_plus(module.params["correlation_search_name"])
                ),
                data=urlencode(request_post_data),
            )
            module.exit_json(
                changed=True,
                msg="{0} updated.".format(module.params["correlation_search_name"]),
                splunk_data=splunk_data,
            )

    if module.params["state"] == "absent":
        # FIXME - need to figure out how to clear the action.notable.param fields from the api endpoint
        module.exit_json(
            changed=True,
            msg="Deleted {0}.".format(module.params["name"]),
            splunk_data=splunk_data,
        )
        for arg in request_post_data:
            if arg in query_dict["entry"][0]["content"]:
                needs_change = True
                del query_dict["entry"][0]["content"][arg]
        if not needs_change:
            module.exit_json(
                changed=False, msg="Nothing to do.", splunk_data=query_dict
            )
        if module.check_mode and needs_change:
            module.exit_json(
                changed=True,
                msg="A change would have been made if not in check mode.",
                splunk_data=query_dict,
            )
        if needs_change:
            splunk_data = splunk_request.create_update(
                "servicesNS/nobody/SplunkEnterpriseSecuritySuite/saved/searches/{0}".format(
                    quote_plus(module.params["correlation_search_name"])
                ),
                data=urlencode(request_post_data),
            )
            module.exit_json(
                changed=True,
                msg="{0} updated.".format(module.params["correlation_search_name"]),
                splunk_data=splunk_data,
            )

    module.exit_json(changed=False, msg="Nothing to do.", splunk_data=query_dict)
Ejemplo n.º 12
0
def main():

    argspec = dict(
        name=dict(required=True, type='str'),
        state=dict(choices=['present', 'absent'], required=True),
        blacklist=dict(required=False, type='str', default=None),
        check_indexed=dict(required=False, type='bool', default=None),
        check_path=dict(required=False, type='bool', default=None),
        crc_salt=dict(required=False, type='str', default=None),
        disabled=dict(required=False, type='str', default=None),
        followTail=dict(required=False, type='str', default=None),
        host=dict(required=False, type='str', default=None),
        host_segment=dict(required=False, type='int', default=None),
        host_regex=dict(required=False, type='int', default=None),
        ignore_older_than=dict(required=False, type='str', default=None),
        index=dict(required=False, type='str', default=None),
        recursive=dict(required=False, type='str', default=None),
        rename_source=dict(required=False, type='str', default=None),
        sourcetype=dict(required=False, type='str', default=None),
        time_before_close=dict(required=False, type='int', default=None),
        whitelist=dict(required=False, type='str', default=None),
    )

    module = AnsibleModule(
        argument_spec=argspec,
        supports_check_mode=True
    )

    # map of keys for the splunk REST API that aren't pythonic so we have to
    # handle the substitutes
    keymap = {
        'check_index': 'check-index',
        'check_path': 'check-path',
        'crc_salt': 'crc-salt',
        'ignore_older_than': 'ignore-older-than',
        'rename_source': 'rename-source',
        'time_before_close': 'time-before-close'

    }

    splunk_request = SplunkRequest(
        module,
        headers={"Content-Type": "application/x-www-form-urlencoded"},
        keymap=keymap,
        not_rest_data_keys=['state']
    )
    # This is where the splunk_* args are processed
    request_data = splunk_request.get_data()

    query_dict = splunk_request.get_by_path('servicesNS/nobody/search/data/inputs/monitor/{0}'.format(quote_plus(module.params['name'])))

    if module.params['state'] == 'present':
        if query_dict:
            needs_change = False
            for arg in request_data:
                if arg in query_dict['entry'][0]['content']:
                    if to_text(query_dict['entry'][0]['content'][arg]) != to_text(request_data[arg]):
                        needs_change = True
            if not needs_change:
                module.exit_json(changed=False, msg="Nothing to do.", splunk_data=query_dict)
            if module.check_mode and needs_change:
                module.exit_json(changed=True, msg="A change would have been made if not in check mode.", splunk_data=query_dict)
            if needs_change:
                splunk_data = splunk_request.create_update(
                    'servicesNS/nobody/search/data/inputs/monitor/{0}'.format(
                        quote_plus(module.params['name'])
                    )
                )
                module.exit_json(changed=True, msg="{0} updated.", splunk_data=splunk_data)
        else:
            # Create it
            _data = splunk_request.get_data()
            _data['name'] = module.params['name']
            splunk_data = splunk_request.create_update('servicesNS/nobody/search/data/inputs/monitor', data=urlencode(_data))
            module.exit_json(changed=True, msg="{0} created.", splunk_data=splunk_data)

    if module.params['state'] == 'absent':
        if query_dict:
            splunk_data = splunk_request.delete_by_path('servicesNS/nobody/search/data/inputs/monitor/{0}'.format(quote_plus(module.params['name'])))
            module.exit_json(changed=True, msg="Deleted {0}.".format(module.params['name']), splunk_data=splunk_data)

    module.exit_json(changed=False, msg="Nothing to do.", splunk_data=query_dict)
Ejemplo n.º 13
0
def main():

    argspec = dict(
        name=dict(required=True, type='str'),
        correlation_search_name=dict(required=True, type='str'),
        description=dict(required=True, type='str'),
        state=dict(choices=['present', 'absent'], required=True),
        security_domain=dict(choices=[
            'access', 'endpoint', 'network', 'threat', 'identity', 'audit'
        ],
                             required=False,
                             default='threat'),
        severity=dict(choices=[
            'informational', 'low', 'medium', 'high', 'critical', 'unknown'
        ],
                      required=False,
                      default='high'),
        default_owner=dict(required=False, type='str'),
        default_status=dict(choices=[
            'unassigned', 'new', 'in progress', 'pending', 'resolved',
            'closed', ''
        ],
                            required=False,
                            default=''),
        drill_down_name=dict(required=False, type='str'),
        drill_down_search=dict(required=False, type='str'),
        drill_down_earliest_offset=dict(required=False,
                                        type='str',
                                        default='$info_min_time$'),
        drill_down_latest_offset=dict(required=False,
                                      type='str',
                                      default='$info_max_time$'),
        investigation_profiles=dict(required=False, type='str'),
        next_steps=dict(required=False, type='list', default=[]),
        recommended_actions=dict(required=False, type='list', default=[]),
        asset_extraction=dict(required=False,
                              type='list',
                              default=['src', 'dest', 'dvc', 'orig_host'],
                              choices=['src', 'dest', 'dvc', 'orig_host']),
        identity_extraction=dict(required=False,
                                 type='list',
                                 default=['user', 'src_user'],
                                 choices=['user', 'src_user']),
    )

    module = AnsibleModule(argument_spec=argspec, supports_check_mode=True)

    splunk_request = SplunkRequest(
        module,
        headers={"Content-Type": "application/x-www-form-urlencoded"},
        not_rest_data_keys=['state'])

    query_dict = splunk_request.get_by_path(
        'servicesNS/nobody/SplunkEnterpriseSecuritySuite/saved/searches/{0}'.
        format(quote_plus(module.params['correlation_search_name'])))

    # Have to custom craft the data here because they overload the saved searches
    # endpoint in the rest api and we want to hide the nuance from the user
    request_post_data = {}

    #FIXME  need to figure out how to properly support these, the possible values appear to
    #       be dynamically created based on what the search is indexing
    #request_post_data['action.notable.param.extract_assets'] = '[\"src\",\"dest\",\"dvc\",\"orig_host\"]'
    #request_post_data['action.notable.param.extract_identities'] = [\"src_user\",\"user\"]
    if module.params['next_steps']:
        if len(module.params['next_steps']) == 1:
            next_steps = "[[action|{0}]]".format(
                module.params['next_steps'][0])
        else:
            next_steps = ""
            for next_step in module.params['next_steps']:
                if next_steps:
                    next_steps += "\n[[action|{0}]]".format(next_step)
                else:
                    next_steps = "[[action|{0}]]".format(next_step)

        # NOTE: version:1 appears to be hard coded when you create this via the splunk web UI
        #       but I don't know what it is/means because there's no docs on it
        next_steps_dict = {"version": 1, "data": next_steps}
        request_post_data['action.notable.param.next_steps'] = json.dumps(
            next_steps_dict)

    if module.params['recommended_actions']:
        if len(module.params['recommended_actions']) == 1:
            request_post_data[
                'action.notable.param.recommended_actions'] = module.params[
                    'recommended_actions'][0]
        else:
            request_post_data[
                'action.notable.param.recommended_actions'] = ','.join(
                    module.params['recommended_actions'])

    request_post_data['action.notable.param.rule_description'] = module.params[
        'description']
    request_post_data['action.notable.param.rule_title'] = module.params[
        'name']
    request_post_data['action.notable.param.security_domain'] = module.params[
        'security_domain']
    request_post_data['action.notable.param.severity'] = module.params[
        'severity']
    request_post_data['action.notable.param.asset_extraction'] = module.params[
        'asset_extraction']
    request_post_data[
        'action.notable.param.identity_extraction'] = module.params[
            'identity_extraction']

    # NOTE: this field appears to be hard coded when you create this via the splunk web UI
    #       but I don't know what it is/means because there's no docs on it
    request_post_data['action.notable.param.verbose'] = '0'

    if module.params['default_owner']:
        request_post_data[
            'action.notable.param.default_owner'] = module.params[
                'default_owner']

    if module.params['default_status']:
        request_post_data[
            'action.notable.param.default_status'] = module.params[
                'default_status']

    if query_dict:
        request_post_data['search'] = query_dict['entry'][0]['content'][
            'search']
        if 'actions' in query_dict['entry'][0]['content']:
            if query_dict['entry'][0]['content']['actions'] == "notable":
                pass
            elif len(query_dict['entry'][0]['content']['actions'].split(
                    ',')) > 0 and "notable" not in query_dict['entry'][0][
                        'content']['actions']:
                request_post_data['actions'] = query_dict['entry'][0][
                    'content']['actions'] + ", notable"
            else:
                request_post_data['actions'] = "notable"
    else:
        module.fail_json(msg="Unable to find correlation search: {0}",
                         splunk_data=splunk_data)

    if module.params['state'] == 'present':
        needs_change = False
        for arg in request_post_data:
            if arg in query_dict['entry'][0]['content']:
                if to_text(query_dict['entry'][0]['content'][arg]) != to_text(
                        request_post_data[arg]):
                    needs_change = True
        if not needs_change:
            module.exit_json(changed=False,
                             msg="Nothing to do.",
                             splunk_data=query_dict)
        if module.check_mode and needs_change:
            module.exit_json(
                changed=True,
                msg="A change would have been made if not in check mode.",
                splunk_data=query_dict)
        if needs_change:
            splunk_data = splunk_request.create_update(
                'servicesNS/nobody/SplunkEnterpriseSecuritySuite/saved/searches/{0}'
                .format(quote_plus(module.params['correlation_search_name'])),
                data=urlencode(request_post_data))
            module.exit_json(changed=True,
                             msg="{0} updated.".format(
                                 module.params['correlation_search_name']),
                             splunk_data=splunk_data)

    if module.params['state'] == 'absent':
        #FIXME - need to figure out how to clear the action.notable.param fields from the api endpoint
        module.exit_json(changed=True,
                         msg="Deleted {0}.".format(module.params['name']),
                         splunk_data=splunk_data)
        for arg in request_post_data:
            if arg in query_dict['entry'][0]['content']:
                needs_change = True
                del query_dict['entry'][0]['content'][arg]
        if not needs_change:
            module.exit_json(changed=False,
                             msg="Nothing to do.",
                             splunk_data=query_dict)
        if module.check_mode and needs_change:
            module.exit_json(
                changed=True,
                msg="A change would have been made if not in check mode.",
                splunk_data=query_dict)
        if needs_change:
            splunk_data = splunk_request.create_update(
                'servicesNS/nobody/SplunkEnterpriseSecuritySuite/saved/searches/{0}'
                .format(quote_plus(module.params['correlation_search_name'])),
                data=urlencode(request_post_data))
            module.exit_json(changed=True,
                             msg="{0} updated.".format(
                                 module.params['correlation_search_name']),
                             splunk_data=splunk_data)

    module.exit_json(changed=False,
                     msg="Nothing to do.",
                     splunk_data=query_dict)
Ejemplo n.º 14
0
def main():

    argspec = dict(state=dict(
        required=False,
        choices=['present', 'absent', 'enabled', 'disable'],
        default='present',
        type='str'),
                   connection_host=dict(required=False,
                                        choices=['ip', 'dns', 'none'],
                                        default='none',
                                        type='str'),
                   host=dict(required=False, type='str', default=None),
                   index=dict(required=False, type='str', default=None),
                   name=dict(required=True, type='str'),
                   protocol=dict(required=True,
                                 type='str',
                                 choices=['tcp', 'udp']),
                   queue=dict(required=False,
                              type='str',
                              choices=['parsingQueue', 'indexQueue'],
                              default='parsingQueue'),
                   rawTcpDoneTimeout=dict(required=False,
                                          type='int',
                                          default=10),
                   restrictToHost=dict(required=False,
                                       type='str',
                                       default=None),
                   ssl=dict(required=False, type='bool', default=None),
                   source=dict(required=False, type='str', default=None),
                   sourcetype=dict(required=False, type='str', default=None),
                   datatype=dict(required=False,
                                 choices=["cooked", "raw"],
                                 default="raw"))

    module = AnsibleModule(argument_spec=argspec, supports_check_mode=True)

    splunk_request = SplunkRequest(
        module,
        headers={"Content-Type": "application/x-www-form-urlencoded"},
        not_rest_data_keys=['state', 'datatype', 'protocol'])
    # This is where the splunk_* args are processed
    request_data = splunk_request.get_data()

    query_dict = splunk_request.get_by_path(
        'servicesNS/nobody/search/data/inputs/{0}/{1}/{2}'.format(
            quote_plus(module.params['protocol']),
            quote_plus(module.params['datatype']),
            quote_plus(module.params['name']),
        ))

    if module.params['state'] in ['present', 'enabled', 'disabled']:
        _data = splunk_request.get_data()
        if module.params['state'] in ['present', 'enabled']:
            _data['disabled'] = False
        else:
            _data['disabled'] = True
        if query_dict:
            needs_change = False
            for arg in request_data:
                if arg in query_dict['entry'][0]['content']:
                    if to_text(
                            query_dict['entry'][0]['content'][arg]) != to_text(
                                request_data[arg]):
                        needs_change = True
            if not needs_change:
                module.exit_json(changed=False,
                                 msg="Nothing to do.",
                                 splunk_data=query_dict)
            if module.check_mode and needs_change:
                module.exit_json(
                    changed=True,
                    msg="A change would have been made if not in check mode.",
                    splunk_data=query_dict)
            if needs_change:
                splunk_data = splunk_request.create_update(
                    'servicesNS/nobody/search/data/inputs/{0}/{1}/{2}'.format(
                        quote_plus(module.params['protocol']),
                        quote_plus(module.params['datatype']),
                        quote_plus(module.params['name']),
                        data=urlencode(_data)))
            if module.params['state'] in ['present', 'enabled']:
                module.exit_json(changed=True,
                                 msg="{0} updated.",
                                 splunk_data=splunk_data)
            else:
                module.exit_json(changed=True,
                                 msg="{0} disabled.",
                                 splunk_data=splunk_data)
        else:
            # Create it
            splunk_data = splunk_request.create_update(
                'servicesNS/nobody/search/data/inputs/{0}/{1}'.format(
                    quote_plus(module.params['protocol']),
                    quote_plus(module.params['datatype']),
                ),
                data=urlencode(_data))
            module.exit_json(changed=True,
                             msg="{0} created.",
                             splunk_data=splunk_data)
    elif module.params['state'] == 'absent':
        if query_dict:
            splunk_data = splunk_request.delete_by_path(
                'servicesNS/nobody/search/data/inputs/{0}/{1}/{2}'.format(
                    quote_plus(module.params['protocol']),
                    quote_plus(module.params['datatype']),
                    quote_plus(module.params['name']),
                ))
            module.exit_json(changed=True,
                             msg="Deleted {0}.".format(module.params['name']),
                             splunk_data=splunk_data)

    module.exit_json(changed=False, msg="Nothing to do.", splunk_data={})