U
    Ld5                  
   @   s  U d Z ddlZddlZddlZddl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mZ dd
lmZ dZdddeegeedededgdgdZeed< eeZ dddi i ddgddZddgdddgdddgddZe	eZe d Z!e d!Z"ed"d#d$Z#d:d%d&Z$d;d'd(Z%e&ee&d)d*d+Z'd,d- Z(d<d.d/Z)G d0d1 d1Z*d=d2d3Z+edd4d5d6Z,e-eee.dd7d8d9Z/dS )>z-Rsyslog: Configure system logging via rsyslog    N)dedent)log)subputil)Cloud)Config)
MetaSchemaget_meta_doc)ALL_DISTROSDistro)PER_INSTANCEam  This 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``.

This module can install rsyslog if not already present on the system using the
``install_rsyslog``, ``packages``, and ``check_exe`` options. Installation
may not work on systems where this module runs before networking is up.

.. note::
    On BSD cloud-init will attempt to disable and stop the base system syslogd.
    This may fail on a first run.
    We recommend creating images with ``service syslogd disable``.
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]
            a              # default (no) configuration with package installation on FreeBSD
            rsyslog:
                config_dir: /usr/local/etc/rsyslog.d
                check_exe: "rsyslogd"
                packages: ["rsyslogd"]
                install_rsyslog: True
            rsyslog)idnametitleZdescriptionZdistrosZ	frequencyZexamplesZactivate_by_schema_keysmetaz/etc/rsyslog.dz20-cloud-config.confautoZrsyslogdF)
config_dirconfig_filenameservice_reload_commandremotesconfigs	check_exepackagesinstall_rsyslogz/usr/local/etc/rsyslog.d)r   r   zsysutils/rsyslogz/usr/pkg/etc/rsyslog.d)ZfreebsdZopenbsdZnetbsdz[ ]*[#]+[ ]*z_^(?P<proto>[@]{0,2})(([\[](?P<bracket_addr>[^\]]*)[\]])|(?P<addr>[^:]*))([:](?P<port>[0-9]+))?$)distroc                 C   s4   t }tt}| j|kr0tj||| j gdd}|S )zConstruct a distro-specific rsyslog config dictionary by merging
       distro specific changes into base config.

    @param distro: String providing the distro class name.
    @returns: Dict of distro configurations for ntp clients.
    T)reverse)DISTRO_OVERRIDEScopyRSYSLOG_CONFIGZosfamilyr   Zmergemanydictr   )r   Zdcfgcfg r!   =/usr/lib/python3/dist-packages/cloudinit/config/cc_rsyslog.pydistro_default_rsyslog_config   s
    

r#   c                 C   s(   t |rdS |dkrdg}| | dS )ai  Install rsyslog package if not already installed.

    @param install_func: function.  This parameter is invoked with the contents
    of the packages parameter.
    @param packages: list.  This parameter defaults to ['rsyslog'].
    @param check_exe: string.  The name of a binary that indicates the package
    the specified package is already installed.
    Nr   )r   Zwhich)Zinstall_funcr   r   r!   r!   r"   r      s
    	
r   c                 C   s.   |dkr |  dd}| d|S tj|ddS )Nr   rsyslog_svcnamer   z
try-reloadT)Zcapture)
get_optionmanage_servicer   )r   commandservicer!   r!   r"   reload_syslog   s    r)   )r    r   returnc              
   C   s"  |  di }t|}t|  dtrhtjddd d|  di}d| krT| d |d< d| krh| d |d	< dg tfd	|d	 tfd|d tfd
|d
 tfd|d ttffd|d tfd|d tfd|d 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)The rsyslog key with value of type 'list'z22.2)Z
deprecatedZdeprecated_versionr   Zrsyslog_filenamer   Zrsyslog_dirr   r   r   r   r   r   zInvalid type for key `z`. Expected type(s): z. Current type: )getr#   
isinstancelistr   Z	deprecatestrdictbool
ValueErrortype)r    r   mycfgZdistro_configZfillupkeydefaultZvtypesr!   r!   r"   load_config   s@    
r6   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/   LOGwarningr+   stripospathjoinappendendswithr   Z
write_file	ExceptionZlogexc)
r   	def_fnamecfg_dirfilesZcur_posZentr7   r9   r=   Zendlr!   r!   r"   apply_rsyslog_changes   s<    
 

rK   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 )Nr8      zline had multiple spaces: %szInvalid host specification '%s'protoaddrZbracket_addrport[]z"host spec had invalid brackets: %sr   matchrM   rN   rO   )
COMMENT_REsplitrA   r1   lenHOST_PORT_RErS   group
startswithrF   SyslogRemotesLinevalidate)liner   dataZcommentZtoksrS   Z	host_portrM   rN   rO   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 )rZ   Nc                 C   s\   |sd}|| _ || _|sd}|dkr*d}n|dkr6d}|| _|| _|rRt|| _nd | _d S )Nz*.*udp@@@tcp)r   rS   rM   rN   intrO   )selfr   rS   rM   rN   rO   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)rO   rd   r1   rN   )re   er!   r!   r"   r[   ;  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]rR   )re   r!   r!   r"   __repr__G  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`   ra   rc   rb   :rP   rQ   z:%sz # %s)rS   rM   rN   rO   r   )re   Zbufr!   r!   r"   __str__P  s    





zSyslogRemotesLine.__str__)NNNNN)__name__
__module____qualname__rf   r[   rh   rk   r!   r!   r!   r"   rZ   %  s            
	rZ   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<   )rE   itemsr.   r_   r1   r?   r@   rD   )r   headerfooterlinesr   r\   rg   r!   r!   r"   remotes_to_rsyslog_cfgd  s    
$
rs   )cloudr*   c              	   C   sx   z| j dd W n tjk
r*   Y dS X | j dd | j   ttj | j dd td W 5 Q R X dS )z
    This helper function bundles the necessary steps to disable BSD base syslog
    ``rc(8)`` reads its configuration on start, so after disabling syslogd, we
    need to tell rc to reload its config
    enabledZsyslogdNdisableZonestopzOsyslogd is running before cloud-init! Please report this as bug to the porters!)	r   r&   r   ProcessExecutionErrorZreload_init
contextlibsuppressr?   error)rt   r!   r!   r"    disable_and_stop_bsd_base_syslogv  s    
r{   )r   r    rt   argsr*   c           
   
   C   sR  d|krt d|  d S t||j}|d }|d rL|t|d ddd |jdd}|d	 d
krt|jj|d |d d t	
 r|jd| t| |d st d d S t|d |d |d d}|st d d S zt|j|d d}W n: tjk
r0 }	 zd}t dt|	 W 5 d }	~	X Y nX |rN|  t d| | d S )Nr   z;Skipping module named %s, no 'rsyslog' key in configurationr   r   z# begin remotesz# end remotes)rp   rq   r$   r   Tr   r   )r   r   enablez.Empty config rsyslog['configs'], nothing to dor   r   )r   rH   rI   z0restart of syslog not necessary, no changes mader   )r'   FzFailed to reload syslog %sz%s configured %s files)r?   debugr6   r   rE   rs   r%   r   Zinstall_packagesr   Zis_BSDr&   r{   rK   r)   r   rw   r@   r.   Zcycle_logging)
r   r    rt   r|   r3   r   r(   ZchangesZ	restartedrg   r!   r!   r"   handle  s`     

 
"r   )Nr   )r   )N)NN)0__doc__rx   r   rB   retextwrapr   Z	cloudinitr   Zloggingr   r   Zcloudinit.cloudr   Zcloudinit.configr   Zcloudinit.config.schemar   r	   Zcloudinit.distrosr
   r   Zcloudinit.settingsr   ZMODULE_DESCRIPTIONr   __annotations__r   r   Z	getLoggerrl   r?   compilerT   rW   r#   r   r)   r/   r6   rK   r_   rZ   rs   r{   r.   r-   r   r!   r!   r!   r"   <module>   s   	&0



/)
&?
