
    d?                         d dl Z d dlZd dlmc mZ d dlmZ d dlmZm	Z	 d dl
mZ d dlmZmZ d dlmZmZmZ d dlmZ d dlmZ  G d	 d
e      Zy)    N)logger)	add_eventWALAEventOperation)ustr)
get_osutilsystemd)	shellutilfileutiltextutil)AddFirewallRules)CommandErrorc                       e Zd ZdZdZdZdZddgZdZe	d        Z
d	 Ze	d
        Zd Zd Zd Zd Zd Zd Zd Zd Ze	d        Zd Zd Zd Zd Zd Zy)PersistFirewallRulesHandleran  
# This unit file (Version={version}) was created by the Azure VM Agent.
# Do not edit.
[Unit]
Description=Setup network rules for WALinuxAgent 
Before=network-pre.target
Wants=network-pre.target
DefaultDependencies=no
ConditionPathExists={binary_path}

[Service]
Type=oneshot
ExecStart={py_path} {binary_path}
RemainAfterExit=yes

[Install]
WantedBy=network.target
aq  
# This python file was created by the Azure VM Agent. Please do not edit.

import os 


if __name__ == '__main__':
    if os.path.exists("{egg_path}"):
        os.system("{py_path} {egg_path} --setup-firewall --dst_ip={wire_ip} --uid={user_id} {wait}")
    else:
        print("{egg_path} file not found, skipping execution of firewall execution setup for this boot")
z{0}-network-setup.servicezwaagent-network-setup.pyzfirewall-cmdz--statez1.3c                      t               } t        j                  j                  | j	                               }t
        j                  j                  | j                         |      S )N)	r   r    _AGENT_NETWORK_SETUP_NAME_FORMATformatget_service_nameospathjoin"get_systemd_unit_file_install_path)osutilservice_names     O/usr/lib/python3/dist-packages/azurelinuxagent/common/persist_firewall_rules.pyget_service_file_pathz1PersistFirewallRulesHandler.get_service_file_pathJ   sG    2SSZZ[a[r[r[tuww||FEEGVV    c                    t               }| j                  j                  |j                               | _        t        j                         | _        |j                         | _	        || _
        || _        |j                         | _        t        j                  j!                  t        j"                         t$        j&                  d         | _        y)a  
        This class deals with ensuring that Firewall rules are persisted over system reboots.
        It tries to employ using Firewalld.service if present first as it already has provisions for persistent rules.
        If not, it then creates a new agent-network-setup.service file and copy it over to the osutil.get_systemd_unit_file_install_path() dynamically
        On top of it, on every service restart it ensures that the WireIP is overwritten and the new IP is blocked as well.
        r   N)r   r   r   r   _network_setup_service_namer   
is_systemd_is_systemdr   _systemd_file_path_dst_ip_uidget_firewall_will_wait_waitr   r   r   getcwdsysargv_current_agent_executable_path)selfdst_ipuidr   s       r   __init__z$PersistFirewallRulesHandler.__init__P   s     +/+P+P+W+WX^XoXoXq+r("--/"("K"K"M	224
.0ggll299;QR.T+r   c            	         t         j                  } 	 t        j                  |       j	                         dk(  S # t
        $ rG}t        j                  dj                  dj                  |       t        |                   Y d }~yd }~ww xY w)Nrunningz{0} command failed: {1} F)r   _FIREWALLD_RUNNING_CMDr	   run_commandrstrip	Exceptionr   verboser   r   r   )firewalld_stateerrors     r   _is_firewall_service_runningz8PersistFirewallRulesHandler._is_firewall_service_runninga   sv     6LL	e((9@@BiOO 	eNN4;;CHH_<UW[\aWbcdd	es   %8 	B=BBc           	         t        j                         s/t        j                  dj	                  | j
                               y | j                         rt        j                  d       | j                          	 t        j                  | j                         t        j                  j                  t        j                          | j"                        g  y t        j                  dj	                  | j
                               | j)                          y # t$        $ rB}t        j                  dj	                  | j
                  t'        |                   Y d }~y d }~ww xY w)Nz)Did not detect Systemd, unable to set {0}zIFirewalld.service present on the VM, setting up permanent rules on the VMz*Unable to delete existing service {0}: {1}z?Firewalld service not running/unavailable, trying to set up {0})r   r   r   warnr   r   r8   info _setup_permanent_firewalld_rulesr
   rm_filesr   r   r   r   confget_lib_dirBINARY_FILE_NAMEr4   r   _setup_network_setup_servicer*   r7   s     r   setupz!PersistFirewallRulesHandler.setupn   s   !!#KKCJJ4KkKklm,,.KKcd 113x!!D$>$>$@"'',,tO_O_OacgcxcxBy#z{ MTTUYUuUuv	x 	))+  x@GGHhHhjnotjuvx xxs   :AD 	E!8EE!c                     	 t        j                  | j                  | j                         y# t        $ r7}t        j                  dj                  t        |                   Y d }~yd }~ww xY w)NzKCheck if Firewall rules already applied using firewalld.service failed: {0}FT)	r   check_firewalld_rule_appliedr"   r#   r4   r   r5   r   r   rB   s     r   __verify_firewall_rules_enabledz;PersistFirewallRulesHandler.__verify_firewall_rules_enabled   s[    	99$,,		R   	NN]ddeijoepqs	   *- 	A--A((A-c                     	 t        j                  | j                  | j                         y # t        $ r7}t        j                  dj                  t        |                   Y d }~y d }~ww xY w)Nz2failed to remove rule using firewalld.service: {0})	r   remove_firewalld_rulesr"   r#   r4   r   r:   r   r   rB   s     r   __remove_firewalld_rulesz4PersistFirewallRulesHandler.__remove_firewalld_rules   sX    	Z33DLL$))L 	ZKKDKKDQVKXZ Z	ZrG   c                    | j                         rt        j                  d       y t        j                  d       | j                          t	        j
                  | j                  | j                         t        j                  d       y )Nz-Firewall rules already set. No change needed.zEFirewall rules not added yet, adding them now using firewalld.servicez@Successfully added the firewall commands using firewalld.service);_PersistFirewallRulesHandler__verify_firewall_rules_enabledr   r;   4_PersistFirewallRulesHandler__remove_firewalld_rulesr   add_firewalld_rulesr"   r#   )r*   s    r   r<   z<PersistFirewallRulesHandler._setup_permanent_firewalld_rules   s\    //1KKGH[\%%',,T\\499EVWr   c                    dd| j                   g}	 t        j                  |      j                         dk(  S # t        $ rV}dj                  | j                   dj                  |      |j                  |j                  |j                        }Y d }~n>d }~wt        $ r/}dj                  | j                   t        |            }Y d }~nd }~ww xY wt        j                  |       y)N	systemctlz
is-enabledenabledzD{0} not enabled. Command: {1}, ExitCode: {2}
Stdout: {3}
Stderr: {4}r0   z+Ran into error, {0} not enabled. Error: {1}Fr   r	   r2   r3   r   r   r   
returncodestdoutstderrr4   r   r   r5   r*   cmdr7   msgs       r   &__verify_network_setup_service_enabledzBPersistFirewallRulesHandler.__verify_network_setup_service_enabled   s    L$*J*JK	v((-446)CC 	oZaa00#((3-AQAQSXS_S_afamamoC 	v?FFtGgGgimnsituC	v 	s"   %7 	C ABC%CCc                 ^   | j                          | j                         }|rO| j                         s?t        j                  dj                  | j                               | j                          y |s/t        j                  dj                  | j                               n=t        j                  dj                  | j                         | j                               | j                          | j                          t        j                  dj                  | j                               y )Nz/Service: {0} already enabled. No change needed.z'Service: {0} not enabled. Adding it nowz:Unit file {0} version modified to {1}, setting it up againz&Successfully added and enabled the {0})/_PersistFirewallRulesHandler__setup_binary_fileB_PersistFirewallRulesHandler__verify_network_setup_service_enabled8_PersistFirewallRulesHandler__unit_file_version_modifiedr   r;   r   r   <_PersistFirewallRulesHandler__log_network_setup_service_logsr   _UNIT_VERSION3_PersistFirewallRulesHandler__set_service_unit_file1_PersistFirewallRulesHandler__reload_systemd_conf)r*   network_service_enableds     r   rA   z8PersistFirewallRulesHandler._setup_network_setup_service   s    
 	  ""&"M"M"O"4+L+L+NKKIPPQUQqQqrs113 +ELLTMmMmnoPWWX\XrXrXtX\XjXjlm
 ((*&&(KK@GGHhHhijr   c           
      z   t         j                  j                  t        j                         | j
                        }	 t        j                  || j                  j                  | j                  | j                  | j                  | j                  t        j                               t!        j"                  dj                  |             y # t$        $ rd t!        j&                  dj                  | j)                                      | j+                  |       | j+                  | j)                                 w xY w)N)egg_pathwire_ipuser_idwaitpy_pathz;Successfully updated the Binary file {0} for firewall setupzfUnable to setup binary file, removing the service unit file {0} to ensure its not run on system reboot)r   r   r   r>   r?   r@   r
   
write_file-_PersistFirewallRulesHandler__BINARY_CONTENTSr   r)   r"   r#   r%   r'   
executabler   r;   r4   r:   r   9_PersistFirewallRulesHandler__remove_file_without_raising)r*   binary_file_paths     r   __setup_binary_filez/PersistFirewallRulesHandler.__setup_binary_file   s    77<<(8(8(:D<Q<QR	 0 $ 6 6 = =tGjGjFJllFJiiCG::FInn	 !> !VW KKU\\]mno 	KKx..023 ../?@..t/I/I/KL	s   BC A-D:c           	         | j                         }t        j                  j                  t	        j
                         | j                        }	 t        j                  || j                  j                  |t        j                  | j                               t        j                  |d       dd| j                  g}	 t!        j"                  |       y # t$        $ rf}t'        d      j                  | j                  |dj                  |      |j(                  |j*                  |j,                        }t/        |      d }~ww xY w# t.        $ r | j1                  |        w xY w)N)binary_pathri   versioni  rP   enablezpUnable to enable service: {0}; deleting service file: {1}. Command: {2}, Exit-code: {3}.
stdout: {4}
stderr: {5}r0   )r   r   r   r   r>   r?   r@   r
   rj   2_PersistFirewallRulesHandler__SERVICE_FILE_CONTENTr   r'   rl   r`   chmodr   r	   r2   r   r   rS   rT   rU   r4   rm   )r*   service_unit_filerq   rW   r7   rX   s         r   __set_service_unit_filez3PersistFirewallRulesHandler.__set_service_unit_file   sF    668ggll4#3#3#5t7L7LM	 1 $ ; ; B B{KN>>KOK]K] !C !_` NN,e4 $*J*JKC%%%c* % IJ KQ  KQ446GRUX]XhXhjojvjvLLK"   n$%  	../@A	s,   A/E >C 	EA!D>>EE E"c           	          t         j                  j                  |       r	 t        j                  |        y y # t        $ r8}t        j                  dj                  | t        |                   Y d }~y d }~ww xY w)Nz&Unable to delete file: {0}; Error: {1})	r   r   existsremover4   r   r:   r   r   )	file_pathr7   s     r   __remove_file_without_raisingz9PersistFirewallRulesHandler.__remove_file_without_raising   sa    77>>)$e		)$ %  eDKKIW[\aWbcddes   8 	A9.A44A9c                    dd| j                   g}	 t        j                  |      j                         dk(  S # t        $ rV}dj                  | j                   dj                  |      |j                  |j                  |j                        }Y d }~n>d }~wt        $ r/}dj                  | j                   t        |            }Y d }~nd }~ww xY wt        j                  |       y)NrP   z	is-failedfailedzN{0} not in a failed state. Command: {1}, ExitCode: {2}
Stdout: {3}
Stderr: {4}r0   z*Ran into error, {0} not failed. Error: {1}FrR   rV   s       r   %__verify_network_setup_service_failedzAPersistFirewallRulesHandler.__verify_network_setup_service_failed   s     K)I)IJ	u((-446(BB 	odkk00#((3-AQAQSXS_S_afamamoC 	u>EEdFfFfhlmrhstC	u 	srZ   c                    dd| j                   ddg}| j                         }	 t        j                  |      }t	        d      j                  | j                   |      }t        j                  |       t#        t$        j&                  | |d	
       y # t        $ r`}dj                  dj                  |      |j                  |j                  |j                        }t        j                  |       Y d }~d }~wt        $ rN}dj                  | j                   t        j                   |            }t        j                  |       Y d }~d }~ww xY w)N
journalctlz-uz-bz--utcz)Logs from the {0} since system boot:
 {1}z\Unable to fetch service logs, Command: {0} failed with ExitCode: {1}
Stdout: {2}
Stderr: {3}r0   zGRan into unexpected error when getting logs for {0} service. Error: {1}F)op
is_successmessage	log_event)r   A_PersistFirewallRulesHandler__verify_network_setup_service_failedr	   r2   r   r   r   r;   r   r   rS   rT   rU   r:   r4   r   format_exceptionr   r   PersistFirewallRules)r*   rW   service_failedrT   rX   r7   es          r    __log_network_setup_service_logsz<PersistFirewallRulesHandler.__log_network_setup_service_logs  s   T4#C#CT7SCCE	**3/FCDKKDLlLlntuCKK 	!66**		  	ryyu//u||MCKK 	[bb00(2K2KA2NPCKK	s&   AB 	EAC55EAE

Ec                    	 t        j                  dj                  | j                               t	        j
                  ddg       y # t        $ r7}t        j                  dj                  t        |                   Y d }~y d }~ww xY w)Nz4Executing systemctl daemon-reload for setting up {0}rP   zdaemon-reloadz.Unable to reload systemctl configurations: {0})	r   r;   r   r   r	   r2   r4   r:   r   )r*   	exceptions     r   __reload_systemd_confz1PersistFirewallRulesHandler.__reload_systemd_conf+  sn    	bKKNUUVZVvVvwx!!;"@A 	bKKHOOPTU^P_`aa	bs   AA 	B-BBc                 N   t         j                  j                  | j                               s(t	        dj                  | j                                     t        j                  | j                         d      }|t        d      |j                  d      j                         S )Nz{0} not foundzFThis unit file \(Version=([\d.]+)\) was created by the Azure VM Agent.)line_rez&Version tag not found in the unit file   )r   r   ry   r   OSErrorr   r
   findre_in_file
ValueErrorgroupstrip)r*   matchs     r   __get_unit_file_versionz3PersistFirewallRulesHandler.__get_unit_file_version2  s    ww~~d88:;/001K1K1MNOO''(B(B(D0{}=EFF{{1~##%%r   c                 r   	 | j                         }|| j                  k7  r0t        j                  dj	                  || j                               yt        j                  dj	                  |             y# t        $ r7}t        j                  dj	                  t        |                   Y d}~yd}~ww xY w)z
        Check if the unit file version changed from the expected version
        :return: True if unit file version changed else False
        zDUnable to determine version of unit file: {0}, overwriting unit fileNTzWUnit file version: {0} does not match with expected version: {1}, overwriting unit filezOUnit file version matches with expected version: {0}, not overwriting unit fileF)3_PersistFirewallRulesHandler__get_unit_file_versionr4   r   r;   r   r   r`   )r*   unit_file_versionr7   s      r   __unit_file_version_modifiedz8PersistFirewallRulesHandler.__unit_file_version_modified=  s    	 $ < < >  2 22KKipp%t'9'9;< ]ddevw	y  	KK^eefjkpfqrs	s   A6 6	B6?-B11B6N)__name__
__module____qualname__rt   rk   r   r@   r1   r`   staticmethodr   r-   r8   rC   rL   rM   r<   r]   rA   r\   ra   rm   r   r_   rb   r   r^    r   r   r   r      s    & (C$1,i8 MW W
U" 
 
,0
Z
Xk4$2 e e$2b	&r   r   )r   r'   azurelinuxagent.common.confcommonr>   azurelinuxagent.commonr   azurelinuxagent.common.eventr   r   azurelinuxagent.common.futurer   azurelinuxagent.common.osutilr   r   azurelinuxagent.common.utilsr	   r
   r   (azurelinuxagent.common.utils.networkutilr   &azurelinuxagent.common.utils.shellutilr   objectr   r   r   r   <module>r      s9   $ 
 
 * * ) F . = F F E ?s& sr   