Hcf{vddlZddlZddlZddlmZddlmZmZmZm Z m Z ddl m Z m Z mZmZmZmZmZmZmZddlmZddlmZddlmZddlmZdd lmZmZdd l m!Z!dd l"m#Z#d Z$d Z%d Z&dZ'dZ(dZ)dZ*dZ+dZ,dZ-dZ.dddddZ/e j`Z1ejdejfe4Z5edddgZ6Gdde!jnZ8de9fdZ: dd*ej~d%ejfd+ZAd,ZBd ed%eefd-ZCd ed.e;d%ee;effd/ZDd ed%ed4ee;efd5e;d6e;de e;d%eeFee;efff d7ZH d?d'ee;efd8e e;de e;d%dfd9ZId ed:ee;efd%ee6fd;ZJy)@N) namedtuple)AnyDictListOptionalTuple) clouds event_logger exceptionshttpmessagessecret_managersystemutilversion)_enabled_services) _is_attached)UAConfig)ATTACH_FAIL_DATE_FORMAT)attachment_data_filemachine_id_file) serviceclient)get_user_or_root_log_file_pathz/v1/context/machines/tokenz3/v1/contracts/{contract}/context/machines/{machine}z /v1/resourcesz3/v1/resources/{resource}/context/machines/{machine}z/v1/clouds/{cloud_type}/tokenz3/v1/contracts/{contract}/machine-activity/{machine}z /v1/contractz/v1/magic-attach)series_overridesseriescloudvariantEnableByDefaultServicenamer!c eZdZdZej ejgd ddZde e e ffdZ de de e e ffd Z ej ejgdd ejfd Z dd e d e dee de e e ffdZdZde de e e ffdZde e e ffdZde fdZ dd e de dee de e e ffdZ dd e de dee de fdZdZy)UAContractClient contract_url)rrr) retry_sleepsNc<|stj|j}|j}|j ddj |i|j }|j|d<||d}t|}|jt||}|jdk(rtj|jdk(r t||jdk7r0tjt|j|j |j"} t$j&j)| j+d d | j+d gD]1} t$j&j)| j+d d 3| S)a}Requests machine attach to the provided machine_id. @param contract_token: Token string providing authentication to ContractBearer service endpoint. @param machine_id: Optional unique system machine id. When absent, contents of /etc/machine-id will be used. @return: Dict of the JSON response containing the machine-token. Authorization Bearer {}lastAttachment machineId activityInfo)dataheadersiurlcodebody machineTokenresourceTokenstoken)rget_machine_idcfgr0updateformat_get_activity_info isoformat_support_old_machine_info request_urlAPI_V1_ADD_CONTRACT_MACHINEr5r AttachInvalidTokenError_raise_attach_forbidden_messageContractAPIErrorr6 json_dictrsecrets add_secretget) selfcontract_token attachment_dt machine_idr0 activity_infor/backcompat_dataresponse response_jsonr:s 3/usr/lib/python3/dist-packages/uaclient/contract.pyadd_contract_machinez%UAContractClient.add_contract_machineDsl..txx8J,,.););N)KLM//1 *7*A*A*C &''G3D9## 'ow$  ==C 446 6 ]]c ! +H 5 ==C --/]]]]  !** ))   nb 1 #&&'7< FE  " " - -eii.D E Freturnc|j}|jt|d|d|d|dd}|jdk7r0t j t|j|j |jS) z=Requests list of entitlements available to this machine type. architecturerkernelvirtrXrrYrZ) query_paramsr2r3)r?rBAPI_V1_AVAILABLE_RESOURCESr5r rFr6rG)rKrOrQs rSavailable_resourcesz$UAContractClient.available_resourcesos//1 ## & -n ='1'1%f- $  ==C --.]]]]  !!!rUrLc*|j}|jddj|i|jt|}|j dk7r0t jt|j |j|jS)Nr)r*r0r2r3) r0r=r>rBAPI_V1_GET_CONTRACT_USING_TOKENr5r rFr6rG)rKrLr0rQs rSget_contract_using_tokenz)UAContractClient.get_contract_using_tokens,,.););N)KLM## +W$  ==C --3]]]]  !!!rUinstancec|jtj|j|j}|j dk7ry|j jdd}|r+tj|tj|tjt|j |j|j }tjj!|jdd|S) zRequests contract token for auto-attach images for Pro clouds. @param instance: AutoAttachCloudInstance for the cloud. @return: Dict of the JSON response containing the contract-token. ) cloud_type)r/r2messager8) error_msgr3 contractToken)rB,API_V1_GET_CONTRACT_TOKEN_FOR_CLOUD_INSTANCEr>re identity_docr5rGrJLOGdebugr InvalidProImagerFr6rrHrI)rKrcrQmsgrRs rS%get_contract_token_for_cloud_instancez6UAContractClient.get_contract_token_for_cloud_instances## 8 ? ?#.. @ && $  ==C $$((B7C # 003??--@]]]]  !** ))   or 2 rU machine_tokenresourcerNc|stj|j}|j}|j ddj |it j ||}|j||}|jdk7r0tjt |j|j|jjdr|jd|jd<|j}|jdgD]1}tjj!|jd d 3|S) aRequests machine access context for a given resource @param machine_token: The authentication token needed to talk to this contract service endpoint. @param resource: Entitlement name. @param machine_id: Optional unique system machine id. When absent, contents of /etc/machine-id will be used. @return: Dict of the JSON response containing entitlement accessInfo. r)r*)rqmachiner`r2r3expiresr9r:r8)rr;r<r0r=r>"API_V1_GET_RESOURCE_MACHINE_ACCESSrBr5r rFr6rJrGrrHrI) rKrprqrNr0r4rQrRr:s rSget_resource_machine_accessz,UAContractClient.get_resource_machine_accesss# ..txx8J,,.););M)JKL077z8 ##C#9 ==C --6]]]]       *,4,<,r0r=rBr5r rFr6rGwrite)rKr{rprN request_datar4r0rQs rSupdate_activity_tokenz&UAContractClient.update_activity_tokens& hh11== ..22>B **4884 ..0 *11 *2 ,,.););M)JKL##C|#L ==C --hmm(--     HH22M-5,>,>M. ) HH ' ' - -m < rU magic_tokenc.|j}|jddj|i|jt|}|j dk(rt j|j dk(rt j|j dk7r0t jt|j |j|j}gd}|D]1}tjj|j|d 3|S) zRequest magic attach token info. When the magic token is registered, it will contain new fields that will allow us to know that the attach process can proceed r)r*r`r1r2r3r:userCoderhr8)r0r=r>rB"API_V1_GET_MAGIC_ATTACH_TOKEN_INFOr5r MagicAttachTokenErrorMagicAttachUnavailablerFr6rGrrHrIrJ)rKrr0rQrR secret_fieldsfields rSget_magic_attach_token_infoz,UAContractClient.get_magic_attach_token_infos ,,.););K)HIJ## .$  ==C 224 4 ==C 335 5 ==C --6]]]]  !** > " LE  " " - -m.?.?r.J K LrUc|j}|jt|d}|jdk(rt j |jdk7r0t j t|j|j|j}gd}|D]1}tjj|j|d3|S)z)Create a magic attach token for the user.POSTr0methodrr2r3rr8) r0rBAPI_V1_NEW_MAGIC_ATTACHr5r rrFr6rGrrHrIrJ)rKr0rQrRrrs rSnew_magic_attach_tokenz'UAContractClient.new_magic_attach_tokens,,.## #$  ==C 335 5 ==C --+]]]]  !** > " LE  " " - -m.?.?r.J K LrUc|j}|jddj|i|jt|d}|j dk(rt j|j dk(rt j|j dk(rt j|j dk7r0t jt|j |j y ) z)Revoke a magic attach token for the user.r)r*DELETErir1rr2r3N) r0r=r>rBAPI_V1_REVOKE_MAGIC_ATTACHr5r MagicAttachTokenAlreadyActivatedrrrFr6)rKrr0rQs rSrevoke_magic_attach_tokenz*UAContractClient.revoke_magic_attach_token1s,,.););K)HIJ## &$  ==C ==? ? ==C 224 4 ==C 335 5 ==C --.]]]]  rUr{c >|stj|j}|j}|j ddj |it j ||}|j}|j|d||d|d|d|dd  }|jd k7r,tj||j|j |jjd r|jd |jd <|jS)a|Get the updated machine token from the contract server. @param machine_token: The machine token needed to talk to this contract service endpoint. @param contract_id: Unique contract id provided by contract service @param machine_id: Optional unique system machine id. When absent, contents of /etc/machine-id will be used. r)r*rxGETrXrrYrZr[)rr0r\r2r3rt)rr;r<r0r=r>API_V1_GET_CONTRACT_MACHINEr?rBr5r rFr6rJrG)rKrpr{rNr0r4rOrQs rSget_contract_machinez%UAContractClient.get_contract_machineHs..txx8J,,.););M)JKL)00 1 //1 ##  -n ='1'1%f-  $   ==C --hmm(--       *,4,<,r?rAAPI_V1_UPDATE_CONTRACT_MACHINErBr5r rFr6rJrG) rKrpr{rNr0r/rPr4rQs rSupdate_contract_machinez(UAContractClient.update_contract_machiness  ..txx8J,,.););M)JKL# 335 4D9,33 *4 ## o$  ==C --hmm(--       *,4,<,rrAttachFailureDefaultServices!E_ATTACH_FAILURE_DEFAULT_SERVICES)r<rrrrr delta_errorunexpected_errorsrr#new_entitlementdeltasservice_enableders rSprocess_entitlements_deltars*@KO)#.%. .t4O .&?-11$;*)!1 ' #FO86''-K%.L /* !22(+?G0 >G6 D-,D-0G-?F G-AG((G-rrc<ddlm}|r t|tj||}d}|r|j dij d}|s!|j dij d}|st j|||j dij dij d d } |||| } | ||} | j|||}||fS#t j$r} tjd || d } ~ wwxYw)a,Process a entitlement access dictionary deltas if they exist. :param cfg: UAConfig instance :param orig_access: Dict with original entitlement access details before contract refresh deltas :param new_access: Dict with updated entitlement access details after contract refresh :param allow_enable: Boolean set True if allowed to perform the enable operation. When False, a message will be logged to inform the user about the recommended enabled service. :param series_overrides: Boolean set True if series overrides should be applied to the new_access dict. :raise UbuntuProError: on failure to process deltas. :return: A tuple containing a dict of processed deltas and a boolean indicating if the service was fully processed rentitlement_factoryF entitlementr)orignew entitlements obligations use_selectorr8r<r#r!z3Skipping entitlement deltas for "%s". No such classN)r< assume_yesr) rrapply_contract_overridesrget_dict_deltasrJr InvalidContractDeltasServiceTypeEntitlementNotFoundErrorrkrlprocess_contract_deltas) r<rrrrrrretr#r!ent_clsexcrs rSrr9s&0: ,  ! !+z :F C }b155f=::mR044V2 . S # S $   )cgNG#,? 11 l2  3;22  IIEt I  s> C++D>DDrQc|jjd}|r|d}|d}|dk(rB|djt}t j |||djd|dk(rB|djt}t j |||djd |d k(rt j| t j) Ninfo contractIdreasonzno-longer-effectivetimez%m-%d-%Y)r{datecontract_expiry_dateznot-effective-yet)r{rcontract_effective_dateznever-effective)r{) rGrJstrftimerr AttachForbiddenExpiredAttachForbiddenNotYetAttachForbiddenNeverAttachExpiredToken)rQrr{rrs rSrErEus    ! !& )D <( h * *<(()@AD33'%)&\%:%::%F   * *<(()@AD22'(,V (=(=j(I   ( (11kJ J  ' ' ))rUc|jj}|j}|d}|ddd}t|}|j ||}|jj |t jj|jdijdt j|}tj |t|||jjdy ) aRequest contract refresh from ua-contracts service. :param cfg: Instance of UAConfig for this machine. :raise UbuntuProError: on failure to update contract or error processing contract deltas :raise ConnectivityError: On failure during a connection r7machineTokenInfo contractInfoid)rpr{r-FrN) rzrrpr%rr}rr; cache_clearrJrr)r<orig_entitlements orig_tokenrpr{contract_clientresprNs rSrefreshrs..;;""J~.M/0@FK&s+O  2 2# 3 D  & %%',b155V**3/J*%  ++ rUc\t|}|j}|jdgS)zDQuery available resources from the contract server for this machine.r)r%r^rJ)r<clientrs rSget_available_resourcesrs+ c "F**,I ==b ))rUr:c:t|}|j|S)z/Query contract information for a specific token)r%rb)r<r:rs rSget_contract_informationrs c "F  * *5 11rUc|j}|jj}|jdd}|jdijdijdd}|syt |}|j ||}|jdijdijdd}|r|n|jj }|jj |k7ry|jj|} t| jD]/\} } tj|j| i| } | s/yy) Nr7r8r r r F effectiveToT) rprzrrJr%rcontract_expiry_datetimeget_entitlements_from_tokensorteditemsrr) r<rrrpr{rr resp_expiry new_expirycurr_entitlementsr#rrs rSis_contract_changedr"sO""J..;;NN>26M)2. ^R T4 &s+O  / / { KD #R( ^R ]D !    # # < <  66*D..JJ "((9(?(?(A!Bo%%  ! !$ +_    rUoverride_selectorselector_valuesc~d}|jD]'\}}||f|jvry|t|z })|S)Nr)rOVERRIDE_SELECTOR_WEIGHTS)r#r$override_weightselectorvalues rS_get_override_weightr*sVO,224?% e O$9$9$; ;4X>>? rUr series_namerec i}||d}|r||d<|jdij|i}|r ||td<tj|j dg}|D]%}t |jd|} | s!||| <'|S)N)rr r!rr overridesr()popr&copydeepcopyrJr*) rr+rer!r-r$rgeneral_overridesoverrideweights rS_select_overridesr4s I!,zBO%, ""x488bI  +,>?@ kook2&FG%)% LL $o   (If  ) rUrcddlm}tt|td|vgst dj ||tjjn|}|\}}|jdi}t||||}t|jD][\} } | jD]C\} } |dj| } t| tr| j| <| |d| <E]y)aApply series-specific overrides to an entitlement dict. This function mutates orig_access dict by applying any series-overrides to the top-level keys under 'entitlement'. The series-overrides are sparse and intended to supplement existing top-level dict values. So, sub-keys under the top-level directives, obligations and affordance sub-key values will be preserved if unspecified in series-overrides. To more clearly indicate that orig_access in memory has already had the overrides applied, the 'series' key is also removed from the orig_access dict. :param orig_access: Dict with original entitlement access details r)get_cloud_typerz?Expected entitlement access dict. Missing "entitlement" key: {}N)uaclient.clouds.identityr6all isinstancedict RuntimeErrorr>rrrrJr4rrr=)rrr!r6r+re_orig_entitlementr-_weightoverrides_to_applykeyr)currents rSrrs &8  ;-} /KL M &%  -3N!((#$MJ"}b9!+z7I(.ioo.?'@ 8##,224 8JC!-044S9G'4(u%38 M*3/ 8 8rUrcddlm}g}|jD]\}}|jdijdd} ||||}||}|jdijdi} |jd} |j | | s|j\} } | s|jt|| |S#tj $rYwxYw) Nrrrrr8rr resourceToken)r#r!) rrrrJr r_should_enable_by_default can_enablerr") r<rrenable_by_default_servicesent_name ent_valuer!rentrrCrEr<s rSget_enabled_by_default_servicesrJAs:!#+113)-- r266~rJ )hG clmmM26::="M ! o6  ( (m DNN,MJ*11*% '#0 &%#22   s CC'&C')T)FTr)NN)Kr/loggingr collectionsrtypingrrrrruaclientr r r r r rrrr-uaclient.api.u.pro.status.enabled_services.v1r(uaclient.api.u.pro.status.is_attached.v1ruaclient.configruaclient.defaultsruaclient.files.state_filesrr uaclient.httpr uaclient.logrrCrrr]rurir|rarrrr&get_event_loggerr getLoggerreplace_top_level_logger_namerrkr"UAServiceClientr%r:rArboolrr HTTPResponse NamedMessagerErrrr"intr*r4rrJrrUrSr^s1  "33   LA$5L'7;9:-9#0O,9#1%7",/   & %%'g:::8DE$vy1 @ }44@ F D@" W W CH~W 38nW  W  W  W |! 9 9c3h9S#X9 9  9  4: 9x** *:D**d4j*2(2324S>2 #X#$#L CH~ 8!!.8c3h.8 SM.8c].8 .8b& &!%c3h& !&rU