
    Vh3                        d dl mZmZmZ dZdZdZd dlZd dlm	Z	 d dl
mZmZ d dlmZ d d	lmZ eZ G d
 de      Z G d de      Zd Z ej0                         Zej5                   edd       edd       edd       eddd       edd       ed       edd       edd       edddgd      	       d  Zed!k(  r e        yy)"    )absolute_importdivisionprint_functiona  
module: grafana_silence
author:
  - flkhndlr (@flkhndlr)
version_added: "1.9.0"
short_description: Manage Grafana Silences
description:
  - Create/delete Grafana Silences through the Alertmanager Silence API.
requirements:
  - The Alertmanager API is only available starting Grafana 8 and the module will fail if the server version is lower than version 8.
options:
  org_id:
    description:
      - The Grafana organization ID where the silence will be created or deleted.
      - Not used when I(grafana_api_key) is set, because the grafana_api_key only belongs to one organization.
      - Mutually exclusive with C(org_name).
    default: 1
    type: int
  org_name:
    description:
      - The Grafana organization name where the silence will be created or deleted.
      - Not used when I(grafana_api_key) is set, because the grafana_api_key only belongs to one organization.
      - Mutually exclusive with C(org_id).
    type: str
  comment:
    description:
      - The comment that describes the silence.
    required: true
    type: str
  created_by:
    description:
      - The author that creates the silence.
    required: true
    type: str
  starts_at:
    description:
      - ISO 8601 Timestamp with milliseconds  e.g. "2029-07-29T08:45:45.000Z" when the silence starts.
    type: str
    required: true
  ends_at:
    description:
      - ISO 8601 Timestamp with milliseconds  e.g. "2029-07-29T08:45:45.000Z" when the silence will end.
    type: str
    required: true
  matchers:
    description:
      - List of matchers to select which alerts are affected by the silence.
    type: list
    elements: dict
    required: true
  state:
    description:
      - Delete the first occurrence of a silence with the same settings. Can be "absent" or "present".
    default: present
    type: str
    choices: ["present", "absent"]
  skip_version_check:
    description:
      - Skip Grafana version check and try to reach api endpoint anyway.
      - This parameter can be useful if you enabled `hide_version` in grafana.ini
    required: False
    type: bool
    default: False
extends_documentation_fragment:
- community.grafana.basic_auth
- community.grafana.api_key
aA  
---
- name: Create a silence
  community.grafana.grafana_silence:
    grafana_url: "https://grafana.example.com"
    grafana_api_key: "{{ some_api_token_value }}"
    comment: "a testcomment"
    created_by: "me"
    starts_at: "2029-07-29T08:45:45.000Z"
    ends_at: "2029-07-29T08:55:45.000Z"
    matchers:
      - isEqual: true
        isRegex: true
        name: environment
        value: test
    state: present

- name: Delete a silence
  community.grafana.grafana_silence:
    grafana_url: "https://grafana.example.com"
    grafana_api_key: "{{ some_api_token_value }}"
    comment: "a testcomment"
    created_by: "me"
    starts_at: "2029-07-29T08:45:45.000Z"
    ends_at: "2029-07-29T08:55:45.000Z"
    matchers:
      - isEqual: true
        isRegex: true
        name: environment
        value: test
    state: absent
aO  
---
silence:
  description: Information about the silence
  returned: On success
  type: complex
  contains:
    id:
      description: The id of the silence
      returned: success
      type: str
      sample:
        - ec27df6b-ac3c-412f-ae0b-6e3e1f41c9c3
    comment:
      description: The comment of the silence
      returned: success
      type: str
      sample:
        - this is a test
    createdBy:
      description: The author of the silence
      returned: success
      type: str
      sample:
        - me
    startsAt:
      description: The begin timestamp of the silence
      returned: success
      type: str
      sample:
        - "2029-07-29T08:45:45.000Z"
    endsAt:
      description: The end timestamp of the silence
      returned: success
      type: str
      sample:
        - "2029-07-29T08:55:45.000Z"
    matchers:
      description: The matchers of the silence
      returned: success
      type: list
      sample:
        - [{"isEqual": true, "isRegex": true, "name": "environment", "value": "test"}]
    status:
      description: The status of the silence
      returned: success
      type: dict
      sample:
        - {"state": "pending"}
    updatedAt:
      description: The timestamp of the last update for the silence
      returned: success
      type: str
      sample:
        - "2023-07-27T13:27:33.042Z"
N)AnsibleModule)	fetch_urlbasic_auth_header)to_text)basec                       e Zd Zy)GrafanaErrorN)__name__
__module____qualname__     u/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/grafana/plugins/modules/grafana_silence.pyr   r      s    r   r   c                   J    e Zd Zd ZddZd Zd Zd Zd Zd Z	d	 Z
d
 Zd Zy)GrafanaSilenceInterfacec                 P   || _         t        j                  |j                  j	                  d            | _        d | _        ddi| _        |j                  j	                  dd       r d|j                  d   z  | j                  d<   nt        |j                  d   |j                  d         | j                  d<   |j                  d	   r| j                  |j                  d	         n|j                  d
   | _        | j                  | j                         |j                  j	                  d      du r8	 | j                         }d   dk  r| j                   j                  dd       y y y # t        $ r0}| j                   j                  dt        |             Y d }~\d }~ww xY w)NurlzContent-Typezapplication/jsongrafana_api_keyz	Bearer %sAuthorizationurl_usernameurl_passwordorg_nameorg_idskip_version_checkFTfailedmsgmajor   z2Silences API is available starting with Grafana v8)_moduler
   	clean_urlparamsgetgrafana_urlr   headersr   organization_by_nameswitch_organizationget_versionr   	fail_jsonr	   )selfmodulegrafana_versiones       r   __init__z GrafanaSilenceInterface.__init__   s   >>&--*;*;E*BC&(:;==.5fmm,=>> LL) ->n-v}}^/L-DLL)
 ==, ))&--
*CD]]8, K
 $$T[[1 ==12e;D"&"2"2"4 w'!+&&L '  , <   D&&d
&CCDs   4E, ,	F%5&F  F%Nc                 <   |t        j                  |      }|sg }dj                  | j                  |      }t	        | j
                  ||||      \  }}|d   }|dk(  ry |dk(  r%| j
                  j                  dd|d	|d
       nr|dk(  r| j
                  j                  dd       nO|dv r)| j
                  j                  |j                               S |dk(  r| j
                  j                  d|       | j
                  j                  dd|z         y )Nz{grafana_url}{path})r'   pathdatar(   methodstatusi  i  Tz Unauthorized to perform action 'z' on ''r   i  zPermission Denied)      i  z*Grafana Silences API answered with HTTP %d)	jsondumpsformatr'   r   r#   r,   	from_jsonread)	r-   r   r5   r(   r6   full_urlrespinfostatus_codes	            r   _send_requestz%GrafanaSilenceInterface._send_request   s   ::d#DG(//D<L<LSV/WLL(wv

d 8n#CLL""EKXV #  CLL""$4G"HJ&<<))$))+66CLL""$D"9IKW 	 	
r   c                 J    d|z  }| j                  || j                  d       y )Nz/api/user/using/%dPOSTr(   r6   rD   r(   )r-   r   r   s      r   r*   z+GrafanaSilenceInterface.switch_organization   s%    "V+3VDr   c                     d}| j                  || j                  d      }t        fd|D              }|r|d   S | j                  j	                  ddz        S )	Nz/api/user/orgsGETrG   c              3   4   K   | ]  }|d    k(  s|  yw)nameNr   ).0orgr   s     r   	<genexpr>z?GrafanaSilenceInterface.organization_by_name.<locals>.<genexpr>  s     MSS[H5LSMs   orgIdTz-Current user isn't member of organization: %sr   )rD   r(   nextr#   r,   )r-   r   r   organizationsorgas    `   r   r)   z,GrafanaSilenceInterface.organization_by_name  sg    **3U*SMMMN= ||%%LxW & 
 	
r   c                     d}| j                  |d | j                  d      }|j                  d      }|6|j                  d      \  }}}t	        |      t	        |      t	        |      dS t        d|z        )Nz/api/healthrJ   r4   version.)r!   minorrevz$Failed to retrieve version from '%s')rD   r(   r&   splitintr   )r-   r   responserU   r!   rW   rX   s          r   r+   z#GrafanaSilenceInterface.get_version  s~    %%dDLL & 
 ,,y) 'c 2E5# Z#e*SXNNACGHHr   c                     d}t        |||||      }| j                  ||| j                  d      }| j                         d   dk(  r|d   |d<   |j	                  dd        |S )	N)/api/alertmanager/grafana/api/v2/silences)comment	createdByendsAtmatchersstartsAtrF   r4   r!   r"   id	silenceID)dictrD   r(   r+   pop)	r-   r^   
created_by	starts_atends_atra   r   silencer[   s	            r   create_silencez&GrafanaSilenceInterface.create_silence  s}    9 
 %%gt||F & 
 g&!+$,TNH[!LLt$r   c                     d}| j                  || j                  d      }|D ]2  }|d   |k(  s|d   |k(  s|d   |k(  s|d   |k(  s'|d   |k(  s0|c S  y )	Nr]   rJ   rG   r^   r_   rb   r`   ra   rH   )	r-   r^   rg   rh   ri   ra   r   	responsesr[   s	            r   get_silencez#GrafanaSilenceInterface.get_silence+  s|    9&&sDLL&O	! 	 H#w.[)Z7Z(I5X&'1Z(H4	  r   c                 f    dj                  |      }| j                  || j                  d      }|S )N4/api/alertmanager/grafana/api/v2/silence/{SilenceId}	SilenceIdrJ   rG   r=   rD   r(   r-   
silence_idr   r[   s       r   get_silence_by_idz)GrafanaSilenceInterface.get_silence_by_id;  s=    DKK  L 
 %%c4<<%Nr   c                 F    d}| j                  || j                  d      }|S )Nr]   rJ   rG   rH   )r-   r   r[   s      r   get_silencesz$GrafanaSilenceInterface.get_silencesB  s'    9%%c4<<%Nr   c                 f    dj                  |      }| j                  || j                  d      }|S )Nrp   rq   DELETErG   rs   rt   s       r   delete_silencez&GrafanaSilenceInterface.delete_silenceG  s=    DKK  L 
 %%c4<<%Qr   )NNrJ   )r   r   r   r1   rD   r*   r)   r+   rk   rn   rv   rx   r{   r   r   r   r   r      s7    B
8E	
	I" 
r   r   c                  t    t        t        dt        j                         t        j                               } | S )NF)argument_specsupports_check_moderequired_togethermutually_exclusive)r   r}   r
   grafana_required_togethergrafana_mutually_exclusive)r.   s    r   setup_module_objectr   O  s1    #!88:::<	F Mr   strT)typerequiredlistre   )r   elementsr      rZ   )defaultr   )r   boolF)r   r   presentabsent)r   choicesr   )	r^   rg   ri   ra   r   r   r   rh   statec                  <   t               } | j                  d   }| j                  d   }| j                  d   }| j                  d   }| j                  d   }| j                  d   }d}d}t        |       }	|	j                  |||||      }
|dk(  rI|
s,|	j	                  |||||      }
|	j                  |
d	         }
d
}nM| j                  ||d|
d   z         n2|dk(  r-|
r|	j                  |
d          d
}n| j                  d|d       | j                  |||
       y )Nr^   rg   ri   ra   rh   r   Fr   rd   Tz5Silence with same parameters already exists! eg. '%s'rc   )r   changedr    r   zSilence does not exist)r   r   rj   )r   r%   r   rn   rk   rv   	exit_jsonr{   )r.   r^   rg   ri   ra   rh   r   r   r   grafana_ifacerj   s              r   mainr   g  sP    "FmmI&G|,JmmI&G}}Z(Hk*IMM'"EGF+F3M''YG 	#22YG $55gk6JKGGK$-    
(	((7G,   FGWEr   __main__)
__future__r   r   r   DOCUMENTATIONEXAMPLESRETURNr;   ansible.module_utils.basicr   ansible.module_utils.urlsr   r   ansible.module_utils._textr	   :ansible_collections.community.grafana.plugins.module_utilsr
   r   __metaclass__	Exceptionr   objectr   r   grafana_argument_specr}   updatere   r   r   r   r   r   <module>r      s   ( A @BHB7
r  4 B . K	9 	Jf JZ +**,   ed+.ed+v>&u7-
EIx#8)
L  
*FZ zF r   