%PDF- %PDF-
Direktori : /lib/python2.7/site-packages/salt/modules/ |
Current File : //lib/python2.7/site-packages/salt/modules/statuspage.py |
# -*- coding: utf-8 -*- ''' StatusPage ========== Handle requests for the StatusPage_ API_. .. _StatusPage: https://www.statuspage.io/ .. _API: http://doers.statuspage.io/api/v1/ In the minion configuration file, the following block is required: .. code-block:: yaml statuspage: api_key: <API_KEY> page_id: <PAGE_ID> .. versionadded:: 2017.7.0 ''' from __future__ import absolute_import, unicode_literals, print_function # import python std lib import logging # import third party try: import requests HAS_REQUESTS = True except ImportError: HAS_REQUESTS = False # import salt from salt.ext import six # ---------------------------------------------------------------------------------------------------------------------- # module properties # ---------------------------------------------------------------------------------------------------------------------- __virtualname__ = 'statuspage' log = logging.getLogger(__file__) BASE_URL = 'https://api.statuspage.io' DEFAULT_VERSION = 1 UPDATE_FORBIDDEN_FILEDS = [ 'id', # can't rewrite this 'created_at', 'updated_at', # updated_at and created_at are handled by the backend framework of the API 'page_id' # can't move it to a different page ] INSERT_FORBIDDEN_FILEDS = UPDATE_FORBIDDEN_FILEDS[:] # they are the same for the moment METHOD_OK_STATUS = { 'POST': 201, 'DELETE': 204 } # ---------------------------------------------------------------------------------------------------------------------- # property functions # ---------------------------------------------------------------------------------------------------------------------- def __virtual__(): ''' Return the execution module virtualname. ''' if HAS_REQUESTS is False: return False, 'The requests python package is not installed' return __virtualname__ def _default_ret(): ''' Default dictionary returned. ''' return { 'result': False, 'comment': '', 'out': None } def _get_api_params(api_url=None, page_id=None, api_key=None, api_version=None): ''' Retrieve the API params from the config file. ''' statuspage_cfg = __salt__['config.get']('statuspage') if not statuspage_cfg: statuspage_cfg = {} return { 'api_url': api_url or statuspage_cfg.get('api_url') or BASE_URL, # optional 'api_page_id': page_id or statuspage_cfg.get('page_id'), # mandatory 'api_key': api_key or statuspage_cfg.get('api_key'), # mandatory 'api_version': api_version or statuspage_cfg.get('api_version') or DEFAULT_VERSION } def _validate_api_params(params): ''' Validate the API params as specified in the config file. ''' # page_id and API key are mandatory and they must be string/unicode return (isinstance(params['api_page_id'], (six.string_types, six.text_type)) and isinstance(params['api_key'], (six.string_types, six.text_type))) def _get_headers(params): ''' Return HTTP headers required. ''' return { 'Authorization': 'OAuth {oauth}'.format(oauth=params['api_key']) } def _http_request(url, method='GET', headers=None, data=None): ''' Make the HTTP request and return the body as python object. ''' req = requests.request(method, url, headers=headers, data=data) ret = _default_ret() ok_status = METHOD_OK_STATUS.get(method, 200) if req.status_code != ok_status: ret.update({ 'comment': req.json().get('error', '') }) return ret ret.update({ 'result': True, 'out': req.json() if method != 'DELETE' else None # no body when DELETE }) return ret # ---------------------------------------------------------------------------------------------------------------------- # callable functions # ---------------------------------------------------------------------------------------------------------------------- def create(endpoint='incidents', api_url=None, page_id=None, api_key=None, api_version=None, **kwargs): ''' Insert a new entry under a specific endpoint. endpoint: incidents Insert under this specific endpoint. page_id Page ID. Can also be specified in the config file. api_key API key. Can also be specified in the config file. api_version: 1 API version. Can also be specified in the config file. api_url Custom API URL in case the user has a StatusPage service running in a custom environment. CLI Example: .. code-block:: bash salt 'minion' statuspage.create endpoint='components' name='my component' group_id='993vgplshj12' Example output: .. code-block:: bash minion: ---------- comment: out: ---------- created_at: 2017-01-05T19:35:27.135Z description: None group_id: 993vgplshj12 id: mjkmtt5lhdgc name: my component page_id: ksdhgfyiuhaa position: 7 status: operational updated_at: 2017-01-05T19:35:27.135Z result: True ''' params = _get_api_params(api_url=api_url, page_id=page_id, api_key=api_key, api_version=api_version) if not _validate_api_params(params): log.error('Invalid API params.') log.error(params) return { 'result': False, 'comment': 'Invalid API params. See log for details' } endpoint_sg = endpoint[:-1] # singular headers = _get_headers(params) create_url = '{base_url}/v{version}/pages/{page_id}/{endpoint}.json'.format( base_url=params['api_url'], version=params['api_version'], page_id=params['api_page_id'], endpoint=endpoint ) change_request = {} for karg, warg in six.iteritems(kwargs): if warg is None or karg.startswith('__') or karg in INSERT_FORBIDDEN_FILEDS: continue change_request_key = '{endpoint_sg}[{karg}]'.format( endpoint_sg=endpoint_sg, karg=karg ) change_request[change_request_key] = warg return _http_request(create_url, method='POST', headers=headers, data=change_request) def retrieve(endpoint='incidents', api_url=None, page_id=None, api_key=None, api_version=None): ''' Retrieve a specific endpoint from the Statuspage API. endpoint: incidents Request a specific endpoint. page_id Page ID. Can also be specified in the config file. api_key API key. Can also be specified in the config file. api_version: 1 API version. Can also be specified in the config file. api_url Custom API URL in case the user has a StatusPage service running in a custom environment. CLI Example: .. code-block:: bash salt 'minion' statuspage.retrieve components Example output: .. code-block:: bash minion: ---------- comment: out: |_ ---------- backfilled: False created_at: 2015-01-26T20:25:02.702Z id: kh2qwjbheqdc36 impact: major impact_override: None incident_updates: |_ ---------- affected_components: None body: We are currently investigating this issue. created_at: 2015-01-26T20:25:02.849Z display_at: 2015-01-26T20:25:02.849Z id: zvx7xz2z5skr incident_id: kh2qwjbheqdc36 status: investigating twitter_updated_at: None updated_at: 2015-01-26T20:25:02.849Z wants_twitter_update: False monitoring_at: None name: just testing some stuff page_id: ksdhgfyiuhaa postmortem_body: None postmortem_body_last_updated_at: None postmortem_ignored: False postmortem_notified_subscribers: False postmortem_notified_twitter: False postmortem_published_at: None resolved_at: None scheduled_auto_completed: False scheduled_auto_in_progress: False scheduled_for: None scheduled_remind_prior: False scheduled_reminded_at: None scheduled_until: None shortlink: http://stspg.io/voY status: investigating updated_at: 2015-01-26T20:25:13.379Z result: True ''' params = _get_api_params(api_url=api_url, page_id=page_id, api_key=api_key, api_version=api_version) if not _validate_api_params(params): log.error('Invalid API params.') log.error(params) return { 'result': False, 'comment': 'Invalid API params. See log for details' } headers = _get_headers(params) retrieve_url = '{base_url}/v{version}/pages/{page_id}/{endpoint}.json'.format( base_url=params['api_url'], version=params['api_version'], page_id=params['api_page_id'], endpoint=endpoint ) return _http_request(retrieve_url, headers=headers) def update(endpoint='incidents', id=None, api_url=None, page_id=None, api_key=None, api_version=None, **kwargs): ''' Update attribute(s) of a specific endpoint. id The unique ID of the enpoint entry. endpoint: incidents Endpoint name. page_id Page ID. Can also be specified in the config file. api_key API key. Can also be specified in the config file. api_version: 1 API version. Can also be specified in the config file. api_url Custom API URL in case the user has a StatusPage service running in a custom environment. CLI Example: .. code-block:: bash salt 'minion' statuspage.update id=dz959yz2nd4l status=resolved Example output: .. code-block:: bash minion: ---------- comment: out: ---------- created_at: 2017-01-03T15:25:30.718Z description: None group_id: 993vgplshj12 id: dz959yz2nd4l name: Management Portal page_id: xzwjjdw87vpf position: 11 status: resolved updated_at: 2017-01-05T15:34:27.676Z result: True ''' endpoint_sg = endpoint[:-1] # singular if not id: log.error('Invalid %s ID', endpoint_sg) return { 'result': False, 'comment': 'Please specify a valid {endpoint} ID'.format(endpoint=endpoint_sg) } params = _get_api_params(api_url=api_url, page_id=page_id, api_key=api_key, api_version=api_version) if not _validate_api_params(params): log.error('Invalid API params.') log.error(params) return { 'result': False, 'comment': 'Invalid API params. See log for details' } headers = _get_headers(params) update_url = '{base_url}/v{version}/pages/{page_id}/{endpoint}/{id}.json'.format( base_url=params['api_url'], version=params['api_version'], page_id=params['api_page_id'], endpoint=endpoint, id=id ) change_request = {} for karg, warg in six.iteritems(kwargs): if warg is None or karg.startswith('__') or karg in UPDATE_FORBIDDEN_FILEDS: continue change_request_key = '{endpoint_sg}[{karg}]'.format( endpoint_sg=endpoint_sg, karg=karg ) change_request[change_request_key] = warg return _http_request(update_url, method='PATCH', headers=headers, data=change_request) def delete(endpoint='incidents', id=None, api_url=None, page_id=None, api_key=None, api_version=None): ''' Remove an entry from an endpoint. endpoint: incidents Request a specific endpoint. page_id Page ID. Can also be specified in the config file. api_key API key. Can also be specified in the config file. api_version: 1 API version. Can also be specified in the config file. api_url Custom API URL in case the user has a StatusPage service running in a custom environment. CLI Example: .. code-block:: bash salt 'minion' statuspage.delete endpoint='components' id='ftgks51sfs2d' Example output: .. code-block:: bash minion: ---------- comment: out: None result: True ''' params = _get_api_params(api_url=api_url, page_id=page_id, api_key=api_key, api_version=api_version) if not _validate_api_params(params): log.error('Invalid API params.') log.error(params) return { 'result': False, 'comment': 'Invalid API params. See log for details' } endpoint_sg = endpoint[:-1] # singular if not id: log.error('Invalid %s ID', endpoint_sg) return { 'result': False, 'comment': 'Please specify a valid {endpoint} ID'.format(endpoint=endpoint_sg) } headers = _get_headers(params) delete_url = '{base_url}/v{version}/pages/{page_id}/{endpoint}/{id}.json'.format( base_url=params['api_url'], version=params['api_version'], page_id=params['api_page_id'], endpoint=endpoint, id=id ) return _http_request(delete_url, method='DELETE', headers=headers)