U
    Ad'                  	   @   sx  U d Z ddlZddlZddlmZ ddlmZ ddlmZ ddlm	Z	m
Z
 ddlmZ ddlmZ dd	lmZmZ dd
lmZ ddlmZ dZdddeegeededgdgdZeed< eeZ dZdZdZi Zeed< dZdZdZ dZ!dZ"dZ#dZ$e%e&Z'e(d Z)e(d!Z*efd"d#Z+eed$d%d&Z,d'd( Z-d2d)d*Z.G d+d, d,Z/d3d-d.Z0e1eeee2dd/d0d1Z3dS )4z-Rsyslog: Configure system logging via rsyslog    N)Logger)dedent)log)subputil)Cloud)Config)
MetaSchemaget_meta_doc)ALL_DISTROS)PER_INSTANCEzThis module configures remote system logging using rsyslog.

Configuration for remote servers can be specified in ``configs``, but for
convenience it can be specified as key value pairs in ``remotes``.
Z
cc_rsyslogZRsyslogz$Configure system logging via rsyslogz            rsyslog:
                remotes:
                    maas: 192.168.1.1
                    juju: 10.0.4.1
                service_reload_command: auto
            a7              rsyslog:
                config_dir: /opt/etc/rsyslog.d
                config_filename: 99-late-cloud-config.conf
                configs:
                    - "*.* @@192.158.1.1"
                    - content: "*.*   @@192.0.2.1:10514"
                      filename: 01-example.conf
                    - content: |
                        *.*   @@syslogd.example.com
                remotes:
                    maas: 192.168.1.1
                    juju: 10.0.4.1
                service_reload_command: [your, syslog, restart, command]
            rsyslog)idnametitleZdescriptionZdistrosZ	frequencyZexamplesZactivate_by_schema_keysmetaz20-cloud-config.confz/etc/rsyslog.dautoDEF_REMOTESconfigsZconfig_filenameZ
config_dirZservice_reload_commandZrsyslog_filenameZrsyslog_dirremotesz[ ]*[#]+[ ]*z_^(?P<proto>[@]{0,2})(([\[](?P<bracket_addr>[^\]]*)[\]])|(?P<addr>[^:]*))([:](?P<port>[0-9]+))?$c                 C   s.   |t kr | dd}| d|S tj|ddS )NZrsyslog_svcnamer   z
try-reloadT)Zcapture)
DEF_RELOADZ
get_optionZmanage_servicer   )distrocommandservice r   =/usr/lib/python3/dist-packages/cloudinit/config/cc_rsyslog.pyreload_syslog^   s    r   )cfgreturnc              
   C   s   |  di }t|  dtr\td t|  di}t| krH| t |t< t| kr\| t |t	< tg tft	t
tftttfttttfftttff}|D ]L\}}}||kr|||< qt|| |std| d| dt||  q|S )zReturn an updated config.

    Support converting the old top level format into new format.
    Raise a `ValueError` if some top level entry has an incorrect type.
    r   zDEPRECATION: This rsyslog list format is deprecated and will be removed in a future version of cloud-init. Use documented keys.zInvalid type for key `z`. Expected type(s): z. Current type: )get
isinstancelistLOGwarningKEYNAME_CONFIGSKEYNAME_LEGACY_FILENAMEKEYNAME_FILENAMEKEYNAME_LEGACY_DIRKEYNAME_DIRDEF_DIRstrDEF_FILENAMEKEYNAME_RELOADr   KEYNAME_REMOTESr   dict
ValueErrortype)r   mycfgZfillupkeydefaultZvtypesr   r   r   load_confige   s0    
r4   c           
   	   C   s   g }t | D ]\}}t|trNd|kr8td|d  q|d }|d|}n|}|}| }|sttd|d  qtj	||}d}||krd}|
| z*d}	|d	sd	}	tj|||	 |d
 W q tk
r   ttd| Y qX q|S )Ncontentz%No 'content' entry in config entry %s   filenamezEntry %s has an empty filenameZabwb 
)omodezFailed to write to %s)	enumerater    r.   r"   r#   r   stripospathjoinappendendswithr   Z
write_file	ExceptionZlogexc)
r   	def_fnamecfg_dirfilesZcur_posZentr5   r7   r;   Zendlr   r   r   apply_rsyslog_changes   s<    
 

rG   c                 C   s
  zt | \}}| }W n tk
r8   | d  }}Y nX |  }d }t|dkr\|}n"t|dkrr|\}}ntd| t|}|std| |d}|dp|d}|d}	|d	r|	d
std| |r|s|}t
|||||	d}
|
  |
S )Nr6      zline had multiple spaces: %szInvalid host specification '%s'protoaddrZbracket_addrport[]z"host spec had invalid brackets: %sr   matchrI   rJ   rK   )
COMMENT_REsplitr=   r/   lenHOST_PORT_RErO   group
startswithrB   SyslogRemotesLinevalidate)liner   dataZcommentZtoksrO   Z	host_portrI   rJ   rK   tr   r   r   parse_remotes_line   s>    



    r[   c                   @   s.   e Zd Zd
ddZdd Zdd Zdd	 ZdS )rV   Nc                 C   s\   |sd}|| _ || _|sd}|dkr*d}n|dkr6d}|| _|| _|rRt|| _nd | _d S )Nz*.*udp@@@tcp)r   rO   rI   rJ   intrK   )selfr   rO   rI   rJ   rK   r   r   r   __init__   s    zSyslogRemotesLine.__init__c              
   C   sZ   | j rHzt| j  W n2 tk
rF } ztd| j  |W 5 d }~X Y nX | jsVtdd S )Nzport '%s' is not an integerzaddress is required)rK   r`   r/   rJ   )ra   er   r   r   rW      s    zSyslogRemotesLine.validatec                 C   s   d| j | j| j| j| jf S )Nz.[name=%s match=%s proto=%s address=%s port=%s]rN   )ra   r   r   r   __repr__   s    zSyslogRemotesLine.__repr__c                 C   s   | j d }| jdkr|d7 }n| jdkr0|d7 }d| jkrN|d| j d 7 }n
|| j7 }| jrl|d	| j 7 }| jr|d
| j 7 }|S )N r\   r]   r_   r^   :rL   rM   z:%sz # %s)rO   rI   rJ   rK   r   )ra   Zbufr   r   r   __str__  s    





zSyslogRemotesLine.__str__)NNNNN)__name__
__module____qualname__rb   rW   rd   rg   r   r   r   r   rV      s            
	rV   c                 C   s   | sd S g }|d k	r| | |  D ]\\}}|s4q&z| tt||d W q& tk
r } ztd||| W 5 d }~X Y q&X q&|d k	r| | d|d S )N)r   z!failed loading remote %s: %s [%s]r:   )rA   itemsr*   r[   r/   r"   r#   r@   )r   headerfooterlinesr   rX   rc   r   r   r   remotes_to_rsyslog_cfg  s    
$
ro   )r   r   cloudr   argsr   c           
   
   C   s   d|kr| d|  d S t|}|t }|t rH|t|t ddd |d s^| d d S t|t |t |t d}|s| d	 d S zt	|j
|t d
}W n4 tjk
r }	 zd}|d|	 W 5 d }	~	X Y nX |r|  | d| | d S )Nr   z;Skipping module named %s, no 'rsyslog' key in configurationz# begin remotesz# end remotes)rl   rm   r   z.Empty config rsyslog['configs'], nothing to do)r   rD   rE   z0restart of syslog not necessary, no changes made)r   FzFailed to reload syslogz%s configured %s files)debugr4   r$   r-   rA   ro   rG   r&   r(   r   r   r,   r   ZProcessExecutionErrorr#   Zcycle_logging)
r   r   rp   r   rq   r1   r   ZchangesZ	restartedrc   r   r   r   handle,  sF     

rs   )N)NN)4__doc__r>   reZloggingr   textwrapr   Z	cloudinitr   r   r   Zcloudinit.cloudr   Zcloudinit.configr   Zcloudinit.config.schemar	   r
   Zcloudinit.distrosr   Zcloudinit.settingsr   ZMODULE_DESCRIPTIONr   __annotations__r+   r)   r   r   r.   r$   r&   r(   r,   r%   r'   r-   Z	getLoggerrh   r"   compilerP   rS   r   r4   rG   r[   rV   ro   r*   r!   rs   r   r   r   r   <module>	   sr   	&

')
&?
    