HEX
Server: Apache
System: Linux a16-asgard6.hospedagemuolhost.com.br 5.14.0-570.52.1.el9_6.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Oct 15 06:39:08 EDT 2025 x86_64
User: maoristu4c3dbd03 (1436)
PHP: 8.1.33
Disabled: NONE
Upload Files
File: //lib64/python3.9/site-packages/syspurpose/__pycache__/files.cpython-39.opt-1.pyc
a

X�Zh�v�@sTdZddlZddlZddlZddlZddlZddlZddlmZm	Z	ddl
mZmZm
Z
ddlmZdZej�ed�Zej�ed�Zd	Zej�ed�Zd
ZdZdZd
Zed
ededed
iZeeeegZdZe�e �Z!e"e"d�dd�Z#Gdd�d�Z$Gdd�d�Z%Gdd�d�Z&e�'dgd��Z(d$e"e"e"e)ee"d�dd�Z*d%e"e"e)e)e+d!�d"d#�Z,dS)&zW
This module contains utilities for manipulating files pertaining to system syspurpose
�N)�Callable�Union)�
create_dir�create_file�write_to_file_utf8)�ugettextz/etc/rhsm/syspurposezsyspurpose.jsonzvalid_fields.jsonz/var/lib/rhsm/cache�role�addons�service_level_agreement�usageZaddOnsZserviceLevelZunsupported��data�returncCs`d|vr\d|dvr2|dd|dd<|dd=d|dvr\|dd|dd<|dd=|S)z�
    Try to solve conflicts in keys
     - Server returns key "roles", but it should be "role"
     - Server returns key "support_level", but service_level_agreement is used in syspurpose.json
    :return: modified dictionary
    �systemPurposeAttributesZrolesrZ
support_levelr
�)r
rr�6/usr/lib64/python3.9/site-packages/syspurpose/files.py�post_process_received_data8s
�
rc@s�eZdZdZdeedd�dd�Zdd�dd	�Zed�d
d�Zeeed�d
d�Z	eeed�dd�Z
eed�dd�Zeeed�dd�Zdedd�dd�Z
edeedd�dd��ZdS)�SyspurposeStorez9
    Represents and maintains a json syspurpose file
    FN)�path�raise_on_errorrcCs||_i|_||_dS�N)r�contentsr)�selfrrrrr�__init__QszSyspurposeStore.__init__�rc
CszFtj|jddd�� }t�|�|_Wd�WdS1s:0YWn�tyztj�|j�rtt	�
d�|j��YdSt�y}z�|j
t
jkr�|js�t	�
d�|j��WYd}~dS|j
t
jk�r�|j�s�t	�
d	j|j|d
��WYd}~dS|j�r|�WYd}~n
d}~00dS)aN
        Opens & reads the contents of the store's file based on the 'path' provided to the constructor,
        and stores them on this object. If the user doesn't have access rights to the file, the program exits.
        :return: False if the contents of the file were empty, or the file doesn't exist; otherwise, nothing.
        �r�utf-8��encodingNTzMalformed data in file {}FzCannot read syspurpose file {}
z#Unable to read file {file}: {error})�file�error)�io�openr�json�loadr�
ValueError�os�getsize�logr �format�OSError�errnoZEACCESr�ENOENT)r�f�errr�	read_fileVs"&zSyspurposeStore.read_filecCs(ttj�|j��p&|��p&t|j|j�S)zw
        Create the files necessary for this store
        :return: True if changes were made, false otherwise
        )rr&r�dirnamer/rr�rrrr�createos
��zSyspurposeStore.create��key�valuerc	Cs�zj|j|}|dur*t|t�s*|g|j|<|j|durBg|j|<||j|vrb|j|�|�nWdSWn"ttfy�|g|j|<Yn0dS)�R
        Add a value to a list of values specified by key. If the current value
        specified by the key is scalar/non-list, it is not overridden, but
        maintained in the list, along with the new value.
        :param key: The name of the list
        :param value: The value to append to the list
        :return: None
        NFT)r�
isinstance�list�append�AttributeError�KeyError�rr4r5Z
current_valuerrr�addzs	


zSyspurposeStore.addc
CsvzV|j|}|dur2t|t�s2||kr2|�|�WS||vrL|j|�|�nWdSWdStttfypYdS0dS)�N
        Remove a value from a list specified by key.
        If the current value specified by the key is not a list, unset the value.
        :param key: The name of the list parameter to manipulate
        :param value: The value to attempt to remove
        :return: True if the value was in the list, False if it was not
        NFT)rr7r8�unset�remover:r;r%r<rrrr@�s
zSyspurposeStore.remove�r4rcCs8|dkr"|j�|d�}d|j|<n|j�|d�}|duS)�\
        Unsets a key
        :param key: The key to unset
        :return: boolean
        r
N�)r�get�pop�rr4r5rrrr?�s
zSyspurposeStore.unsetcCs(|j�|d�}||j|<||kp&|duS)z�
        Set a key (syspurpose parameter) to value
        :param key: The parameter of the syspurpose file to set
        :param value: The value to set that parameter to
        :return: Whether any change was made
        N)rrD)rr4r5Zexisting_valuerrr�set�s
zSyspurposeStore.set)�fprcCs\|sLtj|jddd��$}t||j�|��Wd�qX1s@0Ynt||j�dS)zG
        Write the current contents to the file at "self.path"
        �wrrN)r!r"rrr�flush)rrHr-rrr�write�s
(zSyspurposeStore.writecCs0|||d�}t�|tj�s$|��n|��|S)aK
        Read the file represented by path. If the file does not exist it is created
        :param path: The path on the file system to read, should be a json file
        :param raise_on_error: When it is set to True, then exceptions are raised as expected.
        :return: new SyspurposeStore with the contents read in
        )r)r&�access�W_OKr2r/)�clsrrZ	new_storerrr�read�s

zSyspurposeStore.read)F)N)F)�__name__�
__module__�__qualname__�__doc__�str�boolrr/r2r=r@r?rGrK�classmethodrOrrrrrLsrc@seZdZdZdd�ZdS)�
SyncResultza
    A container class for the results of a sync operation performed by a SyncedStore class.
    cCs||_||_||_||_dSr)�result�remote_changed�
local_changed�cached_changed)rrXrYrZr[rrrr�szSyncResult.__init__N)rPrQrRrSrrrrrrW�srWc@s�eZdZdZeZeZd:ee	e
dd�dd�Zdd�dd	�Zdd�d
d�Z
dd�dd
�Zed�dd�Zed�dd�Zd;eeeed�dd�Zed�dd�Zed�dd�Zed�dd�Zedd�dd�Zdd�dd�Zedd�d d!�Zdd�d"d#�Zee
d�d$d%�Ze	e	dd&�d'd(�Ze	e	e
d&�d)d*�Ze	e	e
d&�d+d,�Ze	e
d-�d.d/�Ze	e	e
d&�d0d1�Z e!e	dd2�d3d4��Z"e#e	edd5�d6d7��Z$e%edfd�d8d9�Z&dS)<�SyncedStorezz
    Stores values in a local file backed by a cache which is then synced with another source
    of the same values.
    NF)�
on_changed�
consumer_uuid�use_valid_fieldsrcCsx||_|j�d�d|_|j|_|j|_d|_|��|_	d|_
|��|_d|_
||_||_|durn|��|_nd|_dS)a8
        Initialization of SyncedStore
        :param uep: object representing connection to candlepin server
        :param on_changed: optional callback method called, during three-way merge
        :param consumer_uuid: UUID of consumer
        :param use_valid_fields: if valid fields are considered
        �/���NFT)�uep�PATH�split�filenamer�
CACHE_PATH�
cache_pathZ
local_file�get_local_contents�local_contentsZ
cache_file�get_cached_contents�cache_contents�changedr]r^�get_valid_fields�valid_fields)rrbr]r^r_rrrr�s


zSyncedStore.__init__rcCs|Srrr1rrr�	__enter__szSyncedStore.__enter__cCs|��dSr)�finish)r�exc_typeZexc_valZexc_tbrrr�__exit__szSyncedStore.__exit__cCs|jr|��dS)zj
        When local content was changed, then try to synchronize local content with remote server
        N)rl�syncr1rrrrpszSyncedStore.finishc
s�t�d�z*|jr2|j�d�s2t�d�|��WSWn>tyr}z&t�dj|d��|��WYd}~Sd}~00|��}|��}|�	�}|j
|||d���fdd	��D�}t�|�kp�|���|�
|�|����}t�d
�d|_|S)z�
        Try to synchronize local content with remote server
        :return: instance of SyncResult holding result of synchronization
        z(Attempting to sync syspurpose content...�
syspurposez9Server does not support syspurpose, syncing only locally.zDFailed to detect whether the server has syspurpose capability: {err})�errN)�local�remote�basecsi|]}�|r|�|�qSrr)�.0r4�rXrr�
<dictcomp>1�z$SyncedStore.sync.<locals>.<dictcomp>z#Successfully synced system purpose.F)r(�debugrb�has_capability�_sync_local_only�	Exceptionr)�get_remote_contentsrhrj�mergerW�
update_remote�update_local�update_cacherl)rruZremote_contentsriZcached_contentsZlocal_resultZsync_resultrrzrrss,

�
zSyncedStore.synccCs|�|���}t|jd|d�S)z�
        This method synchronize try to read data from file. When it wasn't possible,
        then empty dictionary is used. Finally, write the data back to this same file.
        :return: Instance of SyncResult
        F)r�rhrWri)rZ
local_updatedrrrrCszSyncedStore._sync_local_only)rvrwrxrcCst||||jd�}|S)z�
        Do three-way merge
        :param local: dictionary with local values
        :param remote: dictionary with values from server
        :param base: dictionary witch cached values
        :return: dictionary from three-way merge
        )rvrxrw�	on_change)�three_way_merger])rrvrwrxrXrrrr�MszSyncedStore.mergec
Cs`zt�tj|jddd��|_Wn:tjtt	fyXt
�d|j�|�i�i|_Yn0|jS)zl
        Try to load local content from file
        :return: dictionary with system purpose values
        rrrz+Unable to read local system purpose at "%s")
r#r$r!r"rrir&r r%�IOErrorr(r}r�r1rrrrhXs
zSyncedStore.get_local_contentscCs||jdus|jdur"t�d�iS|j�d�s<t�d�iS|j�|j�}i}tD]}|�t|�}|||<qRt�d�|S)zn
        Try to get remote content from server
        :return: dictionary with system purpose values
        NziFailed to read remote syspurpose from server: no available connection, or the consumer is not registered.rtz0Server does not support syspurpose, not syncing.z0Successfully read remote syspurpose from server.)	rbr^r(r}r~ZgetConsumer�
ATTRIBUTESrD�LOCAL_TO_REMOTE)rZconsumerrX�attrr5rrrr�es�


zSyncedStore.get_remote_contentsc
Csjz(t�tj|jddd��|_t�d�Wn:tt	j
tfybt�d|j�i|_|�
i�Yn0|jS)zy
        Try to load cached server response from the file
        :return: dictionary with system purpose values
        rrrz-Successfully read cached syspurpose contents.z2Unable to read cached syspurpose contents at '%s'.)r#r$r!r"rgrkr(r}r%r&r r�rr�r1rrrrjszSyncedStore.get_cached_contentsrcCs||_|��dS)z�
        Rewrite local content with new data and write data to file syspurpose.json
        :param data: new dictionary with local data
        :return: None
        N)ri�_write_local�rr
rrrr��szSyncedStore.update_localcCs|�|j|j�dS)zD
        Write local data to the file
        :return: None
        N)�_update_filerrir1rrrr��szSyncedStore._write_localcCs||_|��dSr)rk�_write_cacher�rrrr��szSyncedStore.update_cachecCs|�|j|j�dS)z;
        Write cache to file
        :return: None
        N)r�rgrkr1rrrr��szSyncedStore._write_cachecCs||jdus|jdur"t�d�dS|�t�}|jj|j|�t�pBd|durN|ng|�t�p\d|�t	�phdd�t�d�dS)z�
        Send data to candlepin server
        :param data: dictionary with syspurpose values
        :return: True, when it was possible to update syspurpose values. Otherwise, return False.
        NzmFailed to update remote syspurpose on the server: no available connection, or the consumer is not registered.FrC)rr	Z
service_levelrz5Successfully updated remote syspurpose on the server.T)
rbr^r(r}rD�ADDONSZupdateConsumer�ROLE�
SERVICE_LEVEL�USAGE)rr
r	rrrr��s�
�
zSyncedStore.update_remoter3cCs�|jdur�||jvrb||j|vr�ttd�j||d��|j|D]}t|�dkrBtd|�qBn0ttd�j|d��|j��D]}td|�q�dS)z�
        Check validity of provided key and value of it is included in valid fields
        :param key: provided key
        :param value: provided value
        :return: None
        NzaWarning: Provided value "{val}" is not included in the list of valid values for attribute {attr}:)�valr�rz - %szHWarning: Provided key "{key}" is not included in the list of valid keys:)r4)rn�print�_r)�len�keys)rr4r5Zvalid_valueZ	valid_keyrrr�_check_key_value_validity�s(

�����z%SyncedStore._check_key_value_validityc	Cs�z�|j|}|dur*t|t�s*|g|j|<|j|durBg|j|<||j|vrb|j|�|�n t�d||f�d|_|jWSWn"ttfy�|g|j|<Yn0|�	||�d|_t�d||f�|jdur�|�
�|jS)r6Nz$Will not add value '%s' to key '%s'.FTzAdding value '%s' to key '%s'.)rir7r8r9r(r}rlr:r;r�r�r<rrrr=�s&	


zSyncedStore.addc
Cs�z�|j|}|dur2t|t�s2||kr2|�|�WS||vrd|j|�|�d|_t�d||f�n d|_t�d||f�|jWSWn0tt	t
fy�t�d||f�d|_Yn0|jdur�|��|jS)r>NTz"Removing value '%s' from key '%s'.Fz)Will not remove value '%s' from key '%s'.)rir7r8r?r@rlr(r}r:r;r%r�)rr4r5Zcurrent_valuesrrrr@	s,
���
zSyncedStore.removerAcCs�|dkr"|j�|d�}d|j|<n0|dkrD|j�|d�}g|j|<n|j�|d�}d|_t�d||f�|du|_|jdur�|��|jS)rBr
NrCr	Tz!Unsetting value '%s' of key '%s'.)rirDrErlr(r}r�rFrrrr?-s

zSyncedStore.unsetcCs�|j�|d�}||j|<||ks(|durN|�||�d|_t�d||f�n
t�d�||kpf|du|_|jdur||��|jS)z�
        Set a key (syspurpose parameter) to value
        :param key: The parameter of the syspurpose file to set
        :type key: str
        :param value: The value to set that parameter to
        :return: Whether any change was made
        NTzSetting value '%s' to key '%s'.z#NOT Setting value '%s' to key '%s'.)rirDr�rlr(r}r�r<rrrrGHs


zSyncedStore.set)�dir_pathrc
Csjtj�|�sft�d|�ztj|ddd�Wn6tyd}zt�d||f�WYd}~n
d}~00dS)zr
        Try to create missing directory
        :param dir_path: path to directory
        :return: None
        zTrying to create directory: %si�T)�mode�exist_okz)Unable to create directory: %s, error: %sN)r&r�isdirr(r}�makedirsr�Zwarning)r�rurrr�_create_missing_dircszSyncedStore._create_missing_dir)rr
rc
Cs�|�t�|�t�ztj|ddd�}Wn2tyZ}z|jtjkrF�WYd}~n6d}~00t||�|�	�|�
�t�d|�dSt�d|�dS)a
        Write the contents of data to file in the first mode we can (effectively to create or update
        the file)
        :param path: The string path to the file location we should update
        :param data: The data to write to the file
        :return: None
        zw+rrNz/Successfully updated syspurpose values at '%s'.z+Failed to update syspurpose values at '%s'.)
r��USER_SYSPURPOSE_DIR�	CACHE_DIRr!r"r*r+ZEEXISTrrJ�closer(r})rNrr
r-r.rrrr�rs


zSyncedStore._update_filec
Cs�d}|jdur�|jdur�|j�|j�}d|vr�|d}z|j�|�}Wn2tyx}zt�d|�WYd}~n"d}~00d|vr�t|�}|d}|S)z�
        Try to get valid fields from server using current owner (organization)
        :return: Dictionary with valid fields
        Nr4z*Unable to get valid fields from server: %sr)rbr^ZgetOwnerZgetOwnerSyspurposeValidFieldsr�r(r}r)rrnZ
current_ownerZ	owner_keyZresponserurrrrm�s$zSyncedStore.get_valid_fields)NNF)NNN)'rPrQrRrS�USER_SYSPURPOSErc�CACHED_SYSPURPOSErfrrTrUrrorrrprWrsr�dictr�rhr�rjr�r�r�r�r�r�r=r@r?rG�staticmethodr�rVr�rrmrrrrr\�s@��&

	*$r\�
DiffChange)r4�previous_value�	new_value�source�in_base�	in_resultrw)rvrxrw�on_conflictr�rc	Cs�t�d�i}|pi}|pi}|p$i}|dkr4|}n|dkrB|}ntd��|durZdd�}t|���t|���Bt|���B}|D�]}t|||dd�}	t|||d	d�}
|	p�|
o�|
tk}d
}|	|
kr�|	dur�t�d|�|}||vr�||||<nv|
du�r(t�d
|�d}||v�rj||||<nB|	�s8|
tk�rj|	du�rPt�d|�d}||v�rj||||<|r�|�|�}
t|||
|�|�||v||vd�}||�q�|S)a�
    Performs a three-way merge on the local and remote dictionaries with a given base
    :param local: The dictionary of the current local values
    :param base: The dictionary with the values we've last seen
    :param remote: The dictionary with "their" values
    :param on_conflict: Either "remote" or "local" or None. If "remote", the remote changes
                               will win any conflict. If "local", the local changes will win any
                               conflict. If anything else, an error will be thrown
    :param on_change: This is an optional function which will be given each change as it is
                      detected.
    :return: The dictionary of values as merged between the three provided dictionaries.
    zAttempting a three-way merge...rwrvzAkeyword argument "on_conflict" must be either "remote" or "local"NcSs|Srr)Zchangerrrr��sz"three_way_merge.<locals>.on_change)rx�otherr4r��serverrxTzLThree way merge conflict: both local and remote values changed for key '%s'.z7Three way merge: remote value was changed for key '%s'.z6Three way merge: local value was changed for key '%s'.)r4r�r�r�r�r�)	r(r}r%rGr��detect_changed�UNSUPPORTEDrDr�)rvrxrwr�r�rX�winnerZall_keysr4rZrYrlr��original�diffrrrr��sb
$
�




�
r�r�)rxr�r4r�rcCs�|pi}|pi}||vr$|dkr$tS|�|�}|�|�}||vrP|dkrPt|�St|�turxt|�turxt|�t|�kS|dkr�|dur�|dkr�dS||kS)aF
    Detect the type of change that has occurred between base and other for a given key
    :param base: The dictionary of values we are starting with
    :param other: The dictionary of now current values
    :param key: The key that we are interested in knowing how it changed
    :param source: An optional string which indicates where the "other" values came from. Used to
                   make decisions which are one sided. (i.e. only applicable for changes from the
                   server side).
    :return: True if there was a change, false if there was no change
    rvr�NrCF)r�rDrU�typer8�sorted)rxr�r4r�Zbase_valZ	other_valrrrr��s

r�)rwN)r�)-rS�collectionsZloggingr#r&r+r!�typingrrZsyspurpose.utilsrrrZsubscription_manager.i18nrr�r�r�joinr�ZVALID_FIELDSr�r�r�r�r�r�r�r�r�Z	getLoggerrPr(r�rrrWr\�
namedtupler�rTr�rUr�rrrr�<module>sP
=��
�L