Example #1
0
def _post_message(webhook, author_icon, title, report):
    """
    Send a message to a Slack room through a webhook
    :param webhook:     The url of the incoming webhook
    :param author_icon: The thumbnail image to be displayed on the right side of the message
    :param title:       The title of the message
    :param report:      The report of the function state
    :return:            Boolean if message was sent successfully
    """

    payload = _generate_payload(author_icon, title, report)

    data = _urlencode({"payload": json.dumps(payload, ensure_ascii=False)})

    webhook_url = _urljoin("https://hooks.slack.com/services/", webhook)
    query_result = salt.utils.http.query(webhook_url, "POST", data=data)

    # Sometimes the status is not available, so status 200 is assumed when it is not present
    if (query_result.get("body", "failed") == "ok"
            and query_result.get("status", 200) == 200):
        return True
    else:
        log.error("Slack incoming webhook message post result: %s",
                  query_result)
        return {
            "res": False,
            "message": query_result.get("body", query_result)
        }
Example #2
0
def call_hook(message,
              attachment=None,
              color='good',
              short=False,
              identifier=None):
    '''
    Send message to Slack incomming webhook.

    :param message:     The topic of message.
    :param attachment:  The message to send to the Slacke WebHook.
    :param color:       The color of border of left side
    :param short:       An optional flag indicating whether the value is short
                        enough to be displayed side-by-side with other values.
    :param identifier:  The identifier of WebHook.
    :return:            Boolean if message was sent successfuly.

    CLI Example:

    .. code-block:: bash

        salt '*' slack.post_hook message='Hello, from SaltStack'

    '''
    base_url = 'https://hooks.slack.com/services/'
    if not identifier:
        identifier = _get_hook_id()

    url = _urljoin(base_url, identifier)

    if not message:
        log.error('message is required option')

    if attachment:
        payload = {
            'attachments': [{
                'fallback': message,
                'color': color,
                'pretext': message,
                'fields': [{
                    "value": attachment,
                    "short": short,
                }]
            }]
        }
    else:
        payload = {
            'text': message,
        }

    data = _urlencode({'payload': json.dumps(payload, ensure_ascii=False)})
    result = salt.utils.http.query(url, 'POST', data=data)

    if result['status'] <= 201:
        return True
    else:
        return {'res': False, 'message': result.get('body', result['status'])}
def _http_request(method,
                  path,
                  data=None,
                  formdata=False,
                  formdata_fieldname=None,
                  stream=False,
                  streaming_callback=None,
                  verify_ssl=True,
                  cert=None):
    """
    Return the result of a query to GitLab API.
    """
    gitlab_config = _get_config()

    api_url = gitlab_config.get('api_url')
    if not api_url:
        raise SaltInvocationError('No GitLab API URL found')

    token = gitlab_config.get('token')
    if not token:
        raise SaltInvocationError('No GitLab Token found')

    decode = True
    if method == 'DELETE':
        decode = False

    ca_bundle = None
    ca_certs = gitlab_config.get('ca_certs', None)
    if ca_certs and verify_ssl == True:
        ca_bundle = ca_certs

    url = _urljoin(api_url, '/api/v4' + six.text_type(path))
    log.warning(url)

    headers = {'PRIVATE-TOKEN': token}
    if method != 'POST':
        headers['Content-Type'] = 'application/json'

    response = salt.utils.http.query(
        url,
        method,
        ca_bundle=ca_bundle,
        data=data,
        decode=decode,
        decode_type='auto',
        formdata=formdata,
        formdata_fieldname=formdata_fieldname,
        header_dict=headers,
        status=True,
        stream=stream,
        streaming_callback=streaming_callback,
        text=True,
        opts=__opts__,
    )
    return response
Example #4
0
def query(hook=None, api_url=None, data=None):
    """
    Mattermost object method function to construct and execute on the API URL.
    :param api_url:     The Mattermost API URL
    :param hook:        The Mattermost hook.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    """
    method = "POST"

    ret = {"message": "", "res": True}

    base_url = _urljoin(api_url, "/hooks/")
    url = _urljoin(base_url, six.text_type(hook))

    result = salt.utils.http.query(url,
                                   method,
                                   data=data,
                                   decode=True,
                                   status=True)

    if result.get("status", None) == salt.ext.six.moves.http_client.OK:
        ret["message"] = "Message posted {0} correctly".format(data)
        return ret
    elif result.get("status",
                    None) == salt.ext.six.moves.http_client.NO_CONTENT:
        return True
    else:
        log.debug(url)
        log.debug(data)
        log.debug(result)
        if "dict" in result:
            _result = result["dict"]
            if "error" in _result:
                ret["message"] = result["error"]
                ret["res"] = False
                return ret
            ret["message"] = "Message not posted"
        else:
            ret["message"] = "invalid_auth"
            ret["res"] = False
    return ret
Example #5
0
def _config():
    '''
    Get configuration items for URL, Username and Password
    '''
    url = __salt__['config.get']('nagios:url', '')
    if not url:
        raise CommandExecutionError('Missing Nagios URL in the configuration.')

    return {
        'url': _urljoin(url.split("cgi-bin")[0], STATUS_URI),
        'username': __salt__['config.get']('nagios:username', ''),
        'password': __salt__['config.get']('nagios:password', ''),
    }
def post_message(message,
                 url=None,
                 channel=None,
                 hook=None,
                 icon_url=None,
                 username=None):
    '''
    Send a message to a Mattermost channel.

    :param message:     The message to send to the Mattermost channel.
    :param url:         The Mattermost url, if not specified in the configuration.
    :param channel:     An optional Mattermost channel ID.
    :param hook:        The Mattermost hook, if not specified in the configuration.
    :param icon_url:    An optional URL to a custom icon to be used.
    :param username:    An optional custom user to be displayed.
    :return:            Boolean if message was sent successfully.

    CLI Example:

    .. code-block:: bash

        salt '*' mattermost.post_message message='Build is done'
    '''

    if not url:
        url = _get_url()

    if not hook:
        hook = _get_hook()

    if not message:
        log.error('message is a required option.')

    base_url = _urljoin(url, '/hooks/')
    url = _urljoin(base_url, six.text_type(hook))

    res = _mattermost_query(url, ':saltstack: ' + message, channel, icon_url,
                            username)
    return res
Example #7
0
def _query(api_version=None, data=None):
    '''
    Slack object method function to construct and execute on the API URL.

    :param api_key:     The Random.org api key.
    :param api_version: The version of Random.org api.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    '''

    if data is None:
        data = {}

    ret = {'res': True}

    api_url = 'https://api.random.org/'
    base_url = _urljoin(api_url, 'json-rpc/' + str(api_version) + '/invoke')

    data = json.dumps(data)

    result = salt.utils.http.query(
        base_url,
        method='POST',
        params={},
        data=data,
        decode=True,
        status=True,
        header_dict={},
        opts=__opts__,
    )

    if result.get('status', None) == salt.ext.six.moves.http_client.OK:
        _result = result['dict']
        if _result.get('result'):
            return _result.get('result')
        if _result.get('error'):
            return _result.get('error')
        return False
    elif result.get('status',
                    None) == salt.ext.six.moves.http_client.NO_CONTENT:
        return False
    else:
        log.debug('base_url {0}'.format(base_url))
        log.debug('data {0}'.format(data))
        log.debug('result {0}'.format(result.text))
        ret['message'] = result.text
        return ret
Example #8
0
def _query(api_version=None, data=None):
    '''
    Slack object method function to construct and execute on the API URL.

    :param api_key:     The Random.org api key.
    :param api_version: The version of Random.org api.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    '''

    if data is None:
        data = {}

    ret = {'res': True}

    api_url = 'https://api.random.org/'
    base_url = _urljoin(api_url, 'json-rpc/' + str(api_version) + '/invoke')

    data = json.dumps(data)

    result = salt.utils.http.query(
        base_url,
        method='POST',
        params={},
        data=data,
        decode=True,
        status=True,
        header_dict={},
        opts=__opts__,
    )

    if result.get('status', None) == salt.ext.six.moves.http_client.OK:
        _result = result['dict']
        if _result.get('result'):
            return _result.get('result')
        if _result.get('error'):
            return _result.get('error')
        return False
    elif result.get('status', None) == salt.ext.six.moves.http_client.NO_CONTENT:
        return False
    else:
        log.debug('base_url {0}'.format(base_url))
        log.debug('data {0}'.format(data))
        log.debug('result {0}'.format(result.text))
        ret['message'] = result.text
        return ret
Example #9
0
def _query(api_version=None, data=None):
    """
    Slack object method function to construct and execute on the API URL.

    :param api_key:     The Random.org api key.
    :param api_version: The version of Random.org api.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    """

    if data is None:
        data = {}

    ret = {"res": True}

    api_url = "https://api.random.org/"
    base_url = _urljoin(api_url,
                        "json-rpc/" + six.text_type(api_version) + "/invoke")

    data = salt.utils.json.dumps(data)

    result = salt.utils.http.query(
        base_url,
        method="POST",
        params={},
        data=data,
        decode=True,
        status=True,
        header_dict={},
        opts=__opts__,
    )

    if result.get("status", None) == salt.ext.six.moves.http_client.OK:
        _result = result["dict"]
        if _result.get("result"):
            return _result.get("result")
        if _result.get("error"):
            return _result.get("error")
        return False
    elif result.get("status",
                    None) == salt.ext.six.moves.http_client.NO_CONTENT:
        return False
    else:
        ret["message"] = result.text if hasattr(result, "text") else ""
        return ret
Example #10
0
def _query(function,
           token=None,
           api_version='1',
           method='POST',
           header_dict=None,
           data=None,
           query_params=None):
    '''
    PushOver object method function to construct and execute on the API URL.

    :param token:       The PushOver api key.
    :param api_version: The PushOver API version to use, defaults to version 1.
    :param function:    The PushOver api function to perform.
    :param method:      The HTTP method, e.g. GET or POST.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    '''

    ret = {'message': '', 'res': True}

    pushover_functions = {
        'message': {
            'request': 'messages.json',
            'response': 'status',
        },
        'validate_user': {
            'request': 'users/validate.json',
            'response': 'status',
        },
        'validate_sound': {
            'request': 'sounds.json',
            'response': 'status',
        },
    }

    api_url = 'https://api.pushover.net'
    base_url = _urljoin(api_url, api_version + '/')
    path = pushover_functions.get(function).get('request')
    url = _urljoin(base_url, path, False)

    if not query_params:
        query_params = {}

    decode = True
    if method == 'DELETE':
        decode = False

    result = salt.utils.http.query(
        url,
        method,
        params=query_params,
        data=data,
        header_dict=header_dict,
        decode=decode,
        decode_type='json',
        text=True,
        status=True,
        cookies=True,
        persist_session=True,
        opts=__opts__,
    )

    if result.get('status', None) == salt.ext.six.moves.http_client.OK:
        response = pushover_functions.get(function).get('response')
        if response in result and result[response] == 0:
            ret['res'] = False
        ret['message'] = result
        return ret
    else:
        try:
            if 'response' in result and result[response] == 0:
                ret['res'] = False
            ret['message'] = result
        except ValueError:
            ret['res'] = False
            ret['message'] = result
        return ret
Example #11
0
def query(
    function,
    token=None,
    api_version="1",
    method="POST",
    header_dict=None,
    data=None,
    query_params=None,
    opts=None,
):
    """
    PushOver object method function to construct and execute on the API URL.

    :param token:       The PushOver api key.
    :param api_version: The PushOver API version to use, defaults to version 1.
    :param function:    The PushOver api function to perform.
    :param method:      The HTTP method, e.g. GET or POST.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    """

    ret = {"message": "", "res": True}

    pushover_functions = {
        "message": {
            "request": "messages.json",
            "response": "status"
        },
        "validate_user": {
            "request": "users/validate.json",
            "response": "status"
        },
        "validate_sound": {
            "request": "sounds.json",
            "response": "status"
        },
    }

    api_url = "https://api.pushover.net"
    base_url = _urljoin(api_url, api_version + "/")
    path = pushover_functions.get(function).get("request")
    url = _urljoin(base_url, path, False)

    if not query_params:
        query_params = {}

    decode = True
    if method == "DELETE":
        decode = False

    result = salt.utils.http.query(
        url,
        method,
        params=query_params,
        data=data,
        header_dict=header_dict,
        decode=decode,
        decode_type="json",
        text=True,
        status=True,
        cookies=True,
        persist_session=True,
        opts=opts,
    )

    if result.get("status", None) == salt.ext.six.moves.http_client.OK:
        response = pushover_functions.get(function).get("response")
        if response in result and result[response] == 0:
            ret["res"] = False
        ret["message"] = result
        return ret
    else:
        try:
            if "response" in result and result[response] == 0:
                ret["res"] = False
            ret["message"] = result
        except ValueError:
            ret["res"] = False
            ret["message"] = result
        return ret
Example #12
0
def _query(function, api_key=None, api_version=None, method='GET', data=None):
    '''
    HipChat object method function to construct and execute on the API URL.

    :param api_key:     The HipChat api key.
    :param function:    The HipChat api function to perform.
    :param api_version: The HipChat api version (v1 or v2).
    :param method:      The HTTP method, e.g. GET or POST.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    '''
    headers = {}
    query_params = {}

    if data is None:
        data = {}

    if data.get('room_id'):
        room_id = str(data.get('room_id'))
    else:
        room_id = '0'

    hipchat_functions = {
        'v1': {
            'rooms': {
                'request': 'rooms/list',
                'response': 'rooms',
            },
            'users': {
                'request': 'users/list',
                'response': 'users',
            },
            'message': {
                'request': 'rooms/message',
                'response': 'status',
            },
        },
        'v2': {
            'rooms': {
                'request': 'room',
                'response': 'items',
            },
            'users': {
                'request': 'user',
                'response': 'items',
            },
            'message': {
                'request': 'room/' + room_id + '/notification',
                'response': None,
            },
        },
    }

    if not api_key or not api_version:
        try:
            options = __salt__['config.option']('hipchat')
            if not api_key:
                api_key = options.get('api_key')
            if not api_version:
                api_version = options.get('api_version')
        except (NameError, KeyError, AttributeError):
            log.error("No HipChat api key or version found.")
            return False

    api_url = 'https://api.hipchat.com'
    base_url = _urljoin(api_url, api_version + '/')
    path = hipchat_functions.get(api_version).get(function).get('request')
    url = _urljoin(base_url, path, False)

    if api_version == 'v1':
        query_params['format'] = 'json'
        query_params['auth_token'] = api_key

        if method == 'POST':
            headers['Content-Type'] = 'application/x-www-form-urlencoded'

        if data.get('notify'):
            data['notify'] = 1
        else:
            data['notify'] = 0
    elif api_version == 'v2':
        headers['Authorization'] = 'Bearer {0}'.format(api_key)
        data = json.dumps(data)
    else:
        log.error('Unsupported HipChat API version')
        return False

    try:
        result = requests.request(
            method=method,
            url=url,
            headers=headers,
            params=query_params,
            data=data,
            verify=True,
        )
    except ConnectionError as e:
        log.error(e)
        return False

    if result.status_code == salt.ext.six.moves.http_client.OK:
        result = result.json()
        response = hipchat_functions.get(api_version).get(function).get('response')
        return result.get(response)
    elif result.status_code == salt.ext.six.moves.http_client.NO_CONTENT:
        return True
    else:
        log.debug(url)
        log.debug(query_params)
        log.debug(data)
        log.debug(result)
        if result.json().get('error'):
            log.error(result.json())
        return False
Example #13
0
def query(
    function,
    api_key=None,
    args=None,
    method="GET",
    header_dict=None,
    data=None,
    opts=None,
):
    """
    Slack object method function to construct and execute on the API URL.

    :param api_key:     The Slack api key.
    :param function:    The Slack api function to perform.
    :param method:      The HTTP method, e.g. GET or POST.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    """

    ret = {"message": "", "res": True}

    slack_functions = {
        "rooms": {"request": "channels.list", "response": "channels"},
        "users": {"request": "users.list", "response": "members"},
        "message": {"request": "chat.postMessage", "response": "channel"},
    }

    if not api_key:
        api_key = __salt__["config.get"]("slack.api_key") or __salt__["config.get"](
            "slack:api_key"
        )

        if not api_key:
            log.error("No Slack api key found.")
            ret["message"] = "No Slack api key found."
            ret["res"] = False
            return ret

    api_url = "https://slack.com"
    base_url = _urljoin(api_url, "/api/")
    path = slack_functions.get(function).get("request")
    url = _urljoin(base_url, path, False)

    if not isinstance(args, dict):
        query_params = {}
    else:
        query_params = args.copy()
    query_params["token"] = api_key

    if header_dict is None:
        header_dict = {}

    if method != "POST":
        header_dict["Accept"] = "application/json"

    result = salt.utils.http.query(
        url,
        method,
        params=query_params,
        data=data,
        decode=True,
        status=True,
        header_dict=header_dict,
        opts=opts,
    )

    if result.get("status", None) == salt.ext.six.moves.http_client.OK:
        _result = result["dict"]
        response = slack_functions.get(function).get("response")
        if "error" in _result:
            ret["message"] = _result["error"]
            ret["res"] = False
            return ret
        ret["message"] = _result.get(response)
        return ret
    elif result.get("status", None) == salt.ext.six.moves.http_client.NO_CONTENT:
        return True
    else:
        log.debug(url)
        log.debug(query_params)
        log.debug(data)
        log.debug(result)
        if "dict" in result:
            _result = result["dict"]
            if "error" in _result:
                ret["message"] = result["error"]
                ret["res"] = False
                return ret
            ret["message"] = _result.get(response)
        else:
            ret["message"] = "invalid_auth"
            ret["res"] = False
        return ret
Example #14
0
def query(
    function,
    api_key=None,
    args=None,
    method="GET",
    header_dict=None,
    data=None,
    opts=None,
):
    """
    Slack object method function to construct and execute on the API URL.

    :param api_key:     The Slack api key.
    :param function:    The Slack api function to perform.
    :param method:      The HTTP method, e.g. GET or POST.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    """

    ret = {"message": "", "res": True}

    slack_functions = {
        "rooms": {"request": "channels.list", "response": "channels"},
        "users": {"request": "users.list", "response": "members"},
        "message": {"request": "chat.postMessage", "response": "channel"},
    }

    if not api_key:
        api_key = __salt__["config.get"]("slack.api_key") or __salt__["config.get"](
            "slack:api_key"
        )

        if not api_key:
            log.error("No Slack api key found.")
            ret["message"] = "No Slack api key found."
            ret["res"] = False
            return ret

    api_url = "https://slack.com"
    base_url = _urljoin(api_url, "/api/")
    path = slack_functions.get(function).get("request")
    url = _urljoin(base_url, path, False)

    if not isinstance(args, dict):
        query_params = {}
    else:
        query_params = args.copy()

    if header_dict is None:
        header_dict = {}

    if method != "POST":
        header_dict["Accept"] = "application/json"

    # https://api.slack.com/changelog/2020-11-no-more-tokens-in-querystrings-for
    # -newly-created-apps
    # Apps created after February 24, 2021 may no longer send tokens as query
    # parameters and must instead use an HTTP authorization header or
    # send the token in an HTTP POST body.
    # Apps created before February 24, 2021 will continue functioning no
    # matter which way you pass your token.
    header_dict["Authorization"] = "Bearer {}".format(api_key)
    result = salt.utils.http.query(
        url,
        method,
        params=query_params,
        data=data,
        decode=True,
        status=True,
        header_dict=header_dict,
        opts=opts,
    )

    if result.get("status", None) == salt.ext.six.moves.http_client.OK:
        _result = result["dict"]
        response = slack_functions.get(function).get("response")
        if "error" in _result:
            ret["message"] = _result["error"]
            ret["res"] = False
            return ret
        ret["message"] = _result.get(response)
        return ret
    elif result.get("status", None) == salt.ext.six.moves.http_client.NO_CONTENT:
        return True
    else:
        log.debug(url)
        log.debug(query_params)
        log.debug(data)
        log.debug(result)
        if "dict" in result:
            _result = result["dict"]
            if "error" in _result:
                ret["message"] = result["error"]
                ret["res"] = False
                return ret
            ret["message"] = "Unknown response"
            ret["res"] = False
        else:
            ret["message"] = "invalid_auth"
            ret["res"] = False
        return ret
Example #15
0
def _status_query(query,
                  hostname,
                  retcode=True,
                  service=None,
                  method='GET',
                  **kwargs):
    '''
    Send query along to Nagios.
    '''
    data = {}
    req_params = {
        'hostname': hostname,
        'query': query,
    }

    ret = {'result': True}

    if not retcode:
        req_params['formatoptions'] = 'enumerate'
    if service:
        req_params['servicedescription'] = service

    url = kwargs.get('url')
    username = kwargs.get('username')
    password = kwargs.get('password')

    # Make sure "cgi-bin/" in the URL
    if not url.endswith(('cgi-bin', 'cgi-bin/')):
        url += 'cgi-bin/'

    if not url.endswith('/'):
        url += '/'
    url = _urljoin(url, 'statusjson.cgi')

    try:
        if username and password:
            auth = (
                username,
                password,
            )
        else:
            auth = None
        result = requests.request(method=method,
                                  url=url,
                                  params=req_params,
                                  data=data,
                                  verify=True,
                                  auth=auth)
        if result.status_code == salt.ext.six.moves.http_client.OK:
            try:
                data = result.json()
                ret['json_data'] = result.json()
            except ValueError:
                ret['error'] = 'Please ensure Nagios is running.'
                ret['result'] = False
        elif result.status_code == salt.ext.six.moves.http_client.UNAUTHORIZED:
            ret['error'] = 'Nagios authentication failed. Please check the configuration.'
            ret['result'] = False
        elif result.status_code == salt.ext.six.moves.http_client.NOT_FOUND:
            ret['error'] = 'URL {0} for Nagios was not found.'.format(url)
            ret['result'] = False
        else:
            ret['error'] = 'Results: {0}'.format(result.text)
            ret['result'] = False
    except ConnectionError as conn_err:
        ret['error'] = 'Error {0}'.format(conn_err)
        ret['result'] = False
    return ret
Example #16
0
def call_hook(
    message,
    attachment=None,
    color="good",
    short=False,
    identifier=None,
    channel=None,
    username=None,
    icon_emoji=None,
):
    """
    Send message to Slack incoming webhook.

    :param message:     The topic of message.
    :param attachment:  The message to send to the Slack WebHook.
    :param color:       The color of border of left side
    :param short:       An optional flag indicating whether the value is short
                        enough to be displayed side-by-side with other values.
    :param identifier:  The identifier of WebHook.
    :param channel:     The channel to use instead of the WebHook default.
    :param username:    Username to use instead of WebHook default.
    :param icon_emoji:  Icon to use instead of WebHook default.
    :return:            Boolean if message was sent successfully.

    CLI Example:

    .. code-block:: bash

        salt '*' slack.call_hook message='Hello, from SaltStack'

    """
    base_url = "https://hooks.slack.com/services/"
    if not identifier:
        identifier = _get_hook_id()

    url = _urljoin(base_url, identifier)

    if not message:
        log.error("message is required option")

    if attachment:
        payload = {
            "attachments": [{
                "fallback": message,
                "color": color,
                "pretext": message,
                "fields": [{
                    "value": attachment,
                    "short": short
                }],
            }]
        }
    else:
        payload = {
            "text": message,
        }

    if channel:
        payload["channel"] = channel

    if username:
        payload["username"] = username

    if icon_emoji:
        payload["icon_emoji"] = icon_emoji

    data = _urlencode({"payload": salt.utils.json.dumps(payload)})
    result = salt.utils.http.query(url, method="POST", data=data, status=True)

    if result["status"] <= 201:
        return True
    else:
        return {"res": False, "message": result.get("body", result["status"])}
Example #17
0
def call_hook(message,
              attachment=None,
              color='good',
              short=False,
              identifier=None,
              channel=None,
              username=None,
              icon_emoji=None):
    '''
    Send message to Slack incoming webhook.

    :param message:     The topic of message.
    :param attachment:  The message to send to the Slacke WebHook.
    :param color:       The color of border of left side
    :param short:       An optional flag indicating whether the value is short
                        enough to be displayed side-by-side with other values.
    :param identifier:  The identifier of WebHook.
    :param channel:     The channel to use instead of the WebHook default.
    :param username:    Username to use instead of WebHook default.
    :param icon_emoji:  Icon to use instead of WebHook default.
    :return:            Boolean if message was sent successfully.

    CLI Example:

    .. code-block:: bash

        salt '*' slack.call_hook message='Hello, from SaltStack'

    '''
    base_url = 'https://hooks.slack.com/services/'
    if not identifier:
        identifier = _get_hook_id()

    url = _urljoin(base_url, identifier)

    if not message:
        log.error('message is required option')

    if attachment:
        payload = {
            'attachments': [
                {
                    'fallback': message,
                    'color': color,
                    'pretext': message,
                    'fields': [
                        {
                            "value": attachment,
                            "short": short,
                        }
                    ]
                }
            ]
        }
    else:
        payload = {
            'text': message,
        }

    if channel:
        payload['channel'] = channel

    if username:
        payload['username'] = username

    if icon_emoji:
        payload['icon_emoji'] = icon_emoji

    data = _urlencode(
        {
            'payload': salt.utils.json.dumps(payload)
        }
    )
    result = salt.utils.http.query(url, method='POST', data=data, status=True)

    if result['status'] <= 201:
        return True
    else:
        return {
            'res': False,
            'message': result.get('body', result['status'])
        }
Example #18
0
def _query(api_key=None, endpoint=None, arguments=None, method='GET', data=None):
    '''
    Heroku object method function to construct and execute on the API URL.

    :param api_key:     The Heroku api key.
    :param endpoint:    The Heroku api function to perform.
    :param arguments:   The Heroku arguments to pass.
    :param method:      The HTTP method, e.g. GET, POST, or PATCH.
    :param data:        The data to be sent for POST/PATCH method.
    :return:            The json response from the API call or False.
    '''
    headers = {}
    query_params = {}

    if not api_key or not endpoint:
        try:
            options = __salt__['config.option']('heroku')
            if not api_key:
                api_key = options.get('api_key')
            if not endpoint:
                endpoint = options['endpoint']
        except (NameError, KeyError, AttributeError):
            log.error("No Heroku api key or endpoint found.")
            return False

    api_url = 'https://api.heroku.com'  # default API URL
    url = _urljoin(api_url, endpoint)
    if arguments:
        url = url + '/'
        url = _urljoin(url, arguments)

    if endpoint:
        headers['Authorization'] = 'Bearer {0}'.format(api_key)
        headers['Accept'] = 'application/vnd.heroku+json; version=3'
        if data:
          data = json.dumps(data)

        if method in ['POST', 'PATCH']:
          headers['Content-Type'] = 'application/json'
    else:
      log.error('Heroku endpoint not specified')
      return False

    result = salt.utils.http.query(
        url,
        method,
        params=query_params,
        data=data,
        decode=True,
        status=True,
        header_dict=headers,
        opts=__opts__,
    )

    if result.get('status', None) == salt.ext.six.moves.http_client.OK:
        return result.get('dict', {})
    elif result.get('status', None) == salt.ext.six.moves.http_client.NO_CONTENT:
        return False
    else:
        log.debug(url)
        log.debug(query_params)
        log.debug(data)
        log.debug(result)
        if result.get('error'):
            log.error(result)
        return False
Example #19
0
def _query(function, api_key=None, api_version=None, room_id=None, method="GET", data=None):
    """
    HipChat object method function to construct and execute on the API URL.

    :param api_key:     The HipChat api key.
    :param function:    The HipChat api function to perform.
    :param api_version: The HipChat api version (v1 or v2).
    :param method:      The HTTP method, e.g. GET or POST.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    """
    headers = {}
    query_params = {}

    if not api_key or not api_version:
        try:
            options = __salt__["config.option"]("hipchat")
            if not api_key:
                api_key = options.get("api_key")
            if not api_version:
                api_version = options.get("api_version")
        except (NameError, KeyError, AttributeError):
            log.error("No HipChat api key or version found.")
            return False

    if room_id:
        room_id = "room/{0}/notification".format(str(room_id))
    else:
        room_id = "room/0/notification"

    hipchat_functions = {
        "v1": {
            "rooms": {"request": "rooms/list", "response": "rooms"},
            "users": {"request": "users/list", "response": "users"},
            "message": {"request": "rooms/message", "response": "status"},
        },
        "v2": {
            "rooms": {"request": "room", "response": "items"},
            "users": {"request": "user", "response": "items"},
            "message": {"request": room_id, "response": None},
        },
    }

    api_url = "https://api.hipchat.com"
    base_url = _urljoin(api_url, api_version + "/")
    path = hipchat_functions.get(api_version).get(function).get("request")
    url = _urljoin(base_url, path, False)

    if api_version == "v1":
        query_params["format"] = "json"
        query_params["auth_token"] = api_key

        if method == "POST":
            headers["Content-Type"] = "application/x-www-form-urlencoded"

        if data:
            if data.get("notify", None):
                data["notify"] = 1
            data = _urlencode(data)
    elif api_version == "v2":
        headers["Authorization"] = "Bearer {0}".format(api_key)
        if data:
            data = json.dumps(data)

        if method == "POST":
            headers["Content-Type"] = "application/json"
    else:
        log.error("Unsupported HipChat API version")
        return False

    result = salt.utils.http.query(
        url, method, params=query_params, data=data, decode=True, status=True, header_dict=headers, opts=__opts__
    )

    if result.get("status", None) == salt.ext.six.moves.http_client.OK:
        response = hipchat_functions.get(api_version).get(function).get("response")
        return result.get("dict", {}).get(response, None)
    elif result.get("status", None) == salt.ext.six.moves.http_client.NO_CONTENT:
        return False
    else:
        log.debug(url)
        log.debug(query_params)
        log.debug(data)
        log.debug(result)
        if result.get("error"):
            log.error(result)
        return False
def _query(function,
           api_key=None,
           args=None,
           method='GET',
           header_dict=None,
           data=None):
    '''
    Slack object method function to construct and execute on the API URL.

    :param api_key:     The Slack api key.
    :param function:    The Slack api function to perform.
    :param method:      The HTTP method, e.g. GET or POST.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    '''
    query_params = {}

    ret = {'message': '',
           'res': True}

    slack_functions = {
        'rooms': {
            'request': 'channels.list',
            'response': 'channels',
        },
        'users': {
            'request': 'users.list',
            'response': 'members',
        },
        'message': {
            'request': 'chat.postMessage',
            'response': 'channel',
        },
    }

    if not api_key:
        try:
            options = __salt__['config.option']('slack')
            if not api_key:
                api_key = options.get('api_key')
        except (NameError, KeyError, AttributeError):
            log.error('No Slack api key found.')
            ret['message'] = 'No Slack api key found.'
            ret['res'] = False
            return ret

    api_url = 'https://slack.com'
    base_url = _urljoin(api_url, '/api/')
    path = slack_functions.get(function).get('request')
    url = _urljoin(base_url, path, False)

    if not isinstance(args, dict):
        query_params = {}
    query_params['token'] = api_key

    if header_dict is None:
        header_dict = {}

    if method != 'POST':
        header_dict['Accept'] = 'application/json'

    result = salt.utils.http.query(
        url,
        method,
        params=query_params,
        data=data,
        decode=True,
        status=True,
        header_dict=header_dict,
        opts=__opts__,
    )

    if result.get('status', None) == salt.ext.six.moves.http_client.OK:
        _result = result['dict']
        response = slack_functions.get(function).get('response')
        if 'error' in _result:
            ret['message'] = _result['error']
            ret['res'] = False
            return ret
        ret['message'] = _result.get(response)
        return ret
    elif result.get('status', None) == salt.ext.six.moves.http_client.NO_CONTENT:
        return True
    else:
        log.debug(url)
        log.debug(query_params)
        log.debug(data)
        log.debug(result)
        _result = result['dict']
        if 'error' in _result:
            ret['message'] = _result['error']
            ret['res'] = False
            return ret
        ret['message'] = _result.get(response)
        return ret
Example #21
0
def call_hook(message,
              attachment=None,
              color='good',
              short=False,
              identifier=None,
              channel=None,
              username=None,
              icon_emoji=None):
    '''
    Send message to Slack incomming webhook.

    :param message:     The topic of message.
    :param attachment:  The message to send to the Slacke WebHook.
    :param color:       The color of border of left side
    :param short:       An optional flag indicating whether the value is short
                        enough to be displayed side-by-side with other values.
    :param identifier:  The identifier of WebHook.
    :param channel:     The channel to use instead of the WebHook default.
    :param username:    Username to use instead of WebHook default.
    :param icon_emoji:  Icon to use instead of WebHook default.
    :return:            Boolean if message was sent successfuly.

    CLI Example:

    .. code-block:: bash

        salt '*' slack.post_hook message='Hello, from SaltStack'

    '''
    base_url = 'https://hooks.slack.com/services/'
    if not identifier:
        identifier = _get_hook_id()

    url = _urljoin(base_url, identifier)

    if not message:
        log.error('message is required option')

    if attachment:
        payload = {
            'attachments': [
                {
                    'fallback': message,
                    'color': color,
                    'pretext': message,
                    'fields': [
                        {
                            "value": attachment,
                            "short": short,
                        }
                    ]
                }
            ]
        }
    else:
        payload = {
            'text': message,
        }

    if channel:
        payload['channel'] = channel

    if username:
        payload['username'] = username

    if icon_emoji:
        payload['icon_emoji'] = icon_emoji

    data = _urlencode(
        {
            'payload': json.dumps(payload, ensure_ascii=False)
        }
    )
    result = salt.utils.http.query(url, 'POST', data=data)

    if result['status'] <= 201:
        return True
    else:
        return {
            'res': False,
            'message': result.get('body', result['status'])
        }
Example #22
0
def _query(function, api_key=None, method='GET', data=None):
    '''
    Slack object method function to construct and execute on the API URL.

    :param api_key:     The Slack api key.
    :param function:    The Slack api function to perform.
    :param method:      The HTTP method, e.g. GET or POST.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    '''
    headers = {}
    query_params = {}

    if data is None:
        data = {}

    ret = {'message': '',
           'res': True}

    slack_functions = {
        'rooms': {
            'request': 'channels.list',
            'response': 'channels',
        },
        'users': {
            'request': 'users.list',
            'response': 'members',
        },
        'message': {
            'request': 'chat.postMessage',
            'response': 'channel',
        },
    }

    if not api_key:
        try:
            options = __salt__['config.option']('slack')
            if not api_key:
                api_key = options.get('api_key')
        except (NameError, KeyError, AttributeError):
            log.error('No Slack api key found.')
            ret['message'] = 'No Slack api key found.'
            ret['res'] = False
            return ret

    api_url = 'https://slack.com'
    base_url = _urljoin(api_url, '/api/')
    path = slack_functions.get(function).get('request')
    url = _urljoin(base_url, path, False)
    query_params['token'] = api_key

    try:
        result = requests.request(
            method=method,
            url=url,
            headers=headers,
            params=query_params,
            data=data,
            verify=True,
        )
    except ConnectionError as e:
        ret['message'] = e
        ret['res'] = False
        return ret

    if result.status_code == 200:
        result = result.json()
        response = slack_functions.get(function).get('response')
        if 'error' in result:
            ret['message'] = result['error']
            ret['res'] = False
            return ret
        ret['message'] = result.get(response)
        return ret
    elif result.status_code == 204:
        return True
    else:
        log.debug(url)
        log.debug(query_params)
        log.debug(data)
        log.debug(result)
        if 'error' in result:
            ret['message'] = result['error']
            ret['res'] = False
            return ret
        ret['message'] = result
        return ret
Example #23
0
def _query(function, api_key=None, api_version=None, method='GET', data=None):
    '''
    HipChat object method function to construct and execute on the API URL.

    :param api_key:     The HipChat api key.
    :param function:    The HipChat api function to perform.
    :param api_version: The HipChat api version (v1 or v2).
    :param method:      The HTTP method, e.g. GET or POST.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    '''
    headers = {}
    query_params = {}

    if data is None:
        data = {}

    if data.get('room_id'):
        room_id = str(data.get('room_id'))
    else:
        room_id = '0'

    hipchat_functions = {
        'v1': {
            'rooms': {
                'request': 'rooms/list',
                'response': 'rooms',
            },
            'users': {
                'request': 'users/list',
                'response': 'users',
            },
            'message': {
                'request': 'rooms/message',
                'response': 'status',
            },
        },
        'v2': {
            'rooms': {
                'request': 'room',
                'response': 'items',
            },
            'users': {
                'request': 'user',
                'response': 'items',
            },
            'message': {
                'request': 'room/' + room_id + '/notification',
                'response': None,
            },
        },
    }

    if not api_key or not api_version:
        try:
            options = __salt__['config.option']('hipchat')
            if not api_key:
                api_key = options.get('api_key')
            if not api_version:
                api_version = options.get('api_version')
        except (NameError, KeyError, AttributeError):
            log.error("No HipChat api key or version found.")
            return False

    api_url = 'https://api.hipchat.com'
    base_url = _urljoin(api_url, api_version + '/')
    path = hipchat_functions.get(api_version).get(function).get('request')
    url = _urljoin(base_url, path, False)

    if api_version == 'v1':
        query_params['format'] = 'json'
        query_params['auth_token'] = api_key

        if method == 'POST':
            headers['Content-Type'] = 'application/x-www-form-urlencoded'

        if data.get('notify'):
            data['notify'] = 1
        else:
            data['notify'] = 0
    elif api_version == 'v2':
        headers['Authorization'] = 'Bearer {0}'.format(api_key)
        data = json.dumps(data)
    else:
        log.error('Unsupported HipChat API version')
        return False

    try:
        result = requests.request(
            method=method,
            url=url,
            headers=headers,
            params=query_params,
            data=data,
            verify=True,
        )
    except ConnectionError as e:
        log.error(e)
        return False

    if result.status_code == 200:
        result = result.json()
        response = hipchat_functions.get(api_version).get(function).get('response')
        return result.get(response)
    elif result.status_code == 204:
        return True
    else:
        log.debug(url)
        log.debug(query_params)
        log.debug(data)
        log.debug(result)
        if result.json().get('error'):
            log.error(result.json())
        return False
Example #24
0
def _query(function,
           token=None,
           api_version='1',
           method='POST',
           data=None,
           query_params=None):
    '''
    PushOver object method function to construct and execute on the API URL.

    :param token:       The PushOver api key.
    :param api_version: The PushOver API version to use, defaults to version 1.
    :param function:    The PushOver api function to perform.
    :param method:      The HTTP method, e.g. GET or POST.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    '''
    headers = {}

    if query_params is None:
        query_params = {}

    if data is None:
        data = {}

    ret = {'message': '',
           'res': True}

    pushover_functions = {
        'message': {
            'request': 'messages.json',
            'response': 'status',
        },
        'validate_user': {
            'request': 'users/validate.json',
            'response': 'status',
        },
        'validate_sound': {
            'request': 'sounds.json',
            'response': 'status',
        },
    }

    if not token:
        try:
            options = __salt__['config.option']('pushover')
            if not token:
                token = options.get('token')
        except (NameError, KeyError, AttributeError):
            log.error('No PushOver token found.')
            ret['message'] = 'No PushOver token found.'
            ret['res'] = False
            return ret

    api_url = 'https://api.pushover.net'
    base_url = _urljoin(api_url, api_version + '/')
    path = pushover_functions.get(function).get('request')
    url = _urljoin(base_url, path, False)

    try:
        result = requests.request(
            method=method,
            url=url,
            headers=headers,
            params=query_params,
            data=data,
            verify=True,
        )
    except ConnectionError as e:
        ret['message'] = e
        ret['res'] = False
        return ret

    if result.status_code == 200:
        result = result.json()
        response = pushover_functions.get(function).get('response')
        if response in result and result[response] == 0:
            ret['res'] = False
        ret['message'] = result
        return ret
    else:
        try:
            result = result.json()
            if response in result and result[response] == 0:
                ret['res'] = False
            ret['message'] = result
            return ret
        except ValueError:
            ret['res'] = False
            ret['message'] = result
            return ret
Example #25
0
def _query(function,
           token=None,
           api_version='1',
           method='POST',
           data=None,
           query_params=None):
    '''
    PushOver object method function to construct and execute on the API URL.

    :param token:       The PushOver api key.
    :param api_version: The PushOver API version to use, defaults to version 1.
    :param function:    The PushOver api function to perform.
    :param method:      The HTTP method, e.g. GET or POST.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    '''
    headers = {}

    if query_params is None:
        query_params = {}

    if data is None:
        data = {}

    ret = {'message': '',
           'res': True}

    pushover_functions = {
        'message': {
            'request': 'messages.json',
            'response': 'status',
        },
        'validate_user': {
            'request': 'users/validate.json',
            'response': 'status',
        },
        'validate_sound': {
            'request': 'sounds.json',
            'response': 'status',
        },
    }

    if not token:
        try:
            options = __salt__['config.option']('pushover')
            if not token:
                token = options.get('token')
        except (NameError, KeyError, AttributeError):
            log.error('No PushOver token found.')
            ret['message'] = 'No PushOver token found.'
            ret['res'] = False
            return ret

    api_url = 'https://api.pushover.net'
    base_url = _urljoin(api_url, api_version + '/')
    path = pushover_functions.get(function).get('request')
    url = _urljoin(base_url, path, False)

    try:
        result = requests.request(
            method=method,
            url=url,
            headers=headers,
            params=query_params,
            data=data,
            verify=True,
        )
    except ConnectionError as e:
        ret['message'] = e
        ret['res'] = False
        return ret

    if result.status_code == salt.ext.six.moves.http_client.OK:
        result = result.json()
        response = pushover_functions.get(function).get('response')
        if response in result and result[response] == 0:
            ret['res'] = False
        ret['message'] = result
        return ret
    else:
        try:
            result = result.json()
            if response in result and result[response] == 0:
                ret['res'] = False
            ret['message'] = result
            return ret
        except ValueError:
            ret['res'] = False
            ret['message'] = result
            return ret
Example #26
0
def _query(function,
           api_key=None,
           api_version=None,
           room_id=None,
           api_url=None,
           method='GET',
           data=None):
    '''
    HipChat object method function to construct and execute on the API URL.

    :param api_key:     The HipChat api key.
    :param function:    The HipChat api function to perform.
    :param api_version: The HipChat api version (v1 or v2).
    :param method:      The HTTP method, e.g. GET or POST.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    '''
    headers = {}
    query_params = {}

    if room_id:
        room_id = 'room/{0}/notification'.format(str(room_id))
    else:
        room_id = 'room/0/notification'

    hipchat_functions = {
        'v1': {
            'rooms': {
                'request': 'rooms/list',
                'response': 'rooms',
            },
            'users': {
                'request': 'users/list',
                'response': 'users',
            },
            'message': {
                'request': 'rooms/message',
                'response': 'status',
            },
        },
        'v2': {
            'rooms': {
                'request': 'room',
                'response': 'items',
            },
            'users': {
                'request': 'user',
                'response': 'items',
            },
            'message': {
                'request': room_id,
                'response': None,
            },
        },
    }

    api_url = 'https://{0}'.format(api_url)
    base_url = _urljoin(api_url, api_version + '/')
    path = hipchat_functions.get(api_version).get(function).get('request')
    url = _urljoin(base_url, path, False)

    if api_version == 'v1':
        query_params['format'] = 'json'
        query_params['auth_token'] = api_key

        if method == 'POST':
            headers['Content-Type'] = 'application/x-www-form-urlencoded'

        if data:
            if data.get('notify'):
                data['notify'] = 1
            else:
                data['notify'] = 0
            data = _urlencode(data)
    elif api_version == 'v2':
        headers['Content-Type'] = 'application/json'
        headers['Authorization'] = 'Bearer {0}'.format(api_key)
        if data:
            data = json.dumps(data)
    else:
        log.error('Unsupported HipChat API version')
        return False

    result = salt.utils.http.query(
        url,
        method,
        params=query_params,
        data=data,
        decode=True,
        status=True,
        header_dict=headers,
        opts=__opts__,
    )

    if result.get('status', None) == salt.ext.six.moves.http_client.OK:
        response = hipchat_functions.get(api_version).get(function).get('response')
        return result.get('dict', {}).get(response, None)
    elif result.get('status', None) == salt.ext.six.moves.http_client.NO_CONTENT:
        return False
    else:
        log.debug(url)
        log.debug(query_params)
        log.debug(data)
        log.debug(result)
        if result.get('error'):
            log.error(result)
        return False
Example #27
0
def query(function,
          token=None,
          api_version='1',
          method='POST',
          header_dict=None,
          data=None,
          query_params=None,
          opts=None):
    '''
    PushOver object method function to construct and execute on the API URL.

    :param token:       The PushOver api key.
    :param api_version: The PushOver API version to use, defaults to version 1.
    :param function:    The PushOver api function to perform.
    :param method:      The HTTP method, e.g. GET or POST.
    :param data:        The data to be sent for POST method.
    :return:            The json response from the API call or False.
    '''

    ret = {'message': '',
           'res': True}

    pushover_functions = {
        'message': {
            'request': 'messages.json',
            'response': 'status',
        },
        'validate_user': {
            'request': 'users/validate.json',
            'response': 'status',
        },
        'validate_sound': {
            'request': 'sounds.json',
            'response': 'status',
        },
    }

    api_url = 'https://api.pushover.net'
    base_url = _urljoin(api_url, api_version + '/')
    path = pushover_functions.get(function).get('request')
    url = _urljoin(base_url, path, False)

    if not query_params:
        query_params = {}

    decode = True
    if method == 'DELETE':
        decode = False

    result = salt.utils.http.query(
        url,
        method,
        params=query_params,
        data=data,
        header_dict=header_dict,
        decode=decode,
        decode_type='json',
        text=True,
        status=True,
        cookies=True,
        persist_session=True,
        opts=opts,
    )

    if result.get('status', None) == salt.ext.six.moves.http_client.OK:
        response = pushover_functions.get(function).get('response')
        if response in result and result[response] == 0:
            ret['res'] = False
        ret['message'] = result
        return ret
    else:
        try:
            if 'response' in result and result[response] == 0:
                ret['res'] = False
            ret['message'] = result
        except ValueError:
            ret['res'] = False
            ret['message'] = result
        return ret
Example #28
0
def _status_query(query, method='GET', **kwargs):
    '''
    Send query along to Nagios
    '''
    headers = {}
    parameters = {}
    data = {}

    nagios_url = kwargs.get('nagios_url')
    nagios_username = kwargs.get('nagios_username')
    nagios_password = kwargs.get('nagios_password')

    query_params = {
        'service': [
            'hostname',
            'servicedescription',
        ],
        'host': [
            'hostname',
        ],
    }
    parameters['query'] = query
    for param in query_params[query]:
        parameters[param] = kwargs[param]

    if not nagios_url.endswith('/'):
        nagios_url = nagios_url + '/'

    if 'cgi-bin' in nagios_url:
        url = _urljoin(nagios_url, 'statusjson.cgi')
    else:
        url = _urljoin(nagios_url, 'cgi-bin/statusjson.cgi')

    try:
        if nagios_username and nagios_password:
            result = requests.request(method=method,
                                      url=url,
                                      headers=headers,
                                      params=parameters,
                                      data=data,
                                      verify=True,
                                      auth=(nagios_username, nagios_password))
        else:
            result = requests.request(
                method=method,
                url=url,
                headers=headers,
                params=parameters,
                data=data,
                verify=True,
            )
        if result.status_code == 200:
            data = result.json()
        elif result.status_code == 401:
            log.info(
                'Authentication failed. Check nagios_username and nagios_password.'
            )
        elif result.status_code == 404:
            log.info('Url {0} not found.'.format(url))
        else:
            log.info('Results: {0}'.format(result.text))
    except ConnectionError as _error:
        log.info('Error {0}'.format(_error))
    return data