f^,dZddlZddlZddlZddlZddlmZddlmZm Z ddl m Z ddl m Z mZmZddlmZddlmZd Zej*eZdd Zd Zd efd ZdedededefdZdZdZ edk(re yy)aTQuery standardized instance metadata provided to machine, returning a JSON structure. Some instance-data values may be binary on some platforms, such as userdata and vendordata. Attempt to decompress and decode UTF-8 any binary values. Any binary values in the instance metadata will be base64-encoded and prefixed with "ci-b64:" in the output. userdata and, where applicable, vendordata may be provided to the machine gzip-compressed (and therefore as binary data). query will attempt to decompress these to a string before emitting the JSON output; if this fails, they are treated as binary. N)EACCES) atomic_helperutil)read_cfg_paths)convert_jinja_instance_dataget_jinja_variable_aliasrender_jinja_payload)REDACT_SENSITIVE_VALUE)JinjaSyntaxParsingExceptionqueryc |stjtt}|j ddddd|j dd t d t jd  |j d dddd|j ddt d |j ddt d |j dt dd|j dddddd|j dd t d!d"#|S)$a#Build or extend an arg parser for query utility. @param parser: Optional existing ArgumentParser instance representing the query subcommand which will be extended to support the args of this utility. @returns: ArgumentParser with proper argument configuration. )prog descriptionz-dz--debug store_trueFz+Add verbose messages during template render)actiondefaulthelpz-iz--instance-dataz,Path to instance-data.json file. Default is instance_data)typerz-lz --list-keyszBList query keys available at the provided instance-data .z-uz --user-datazHPath to user-data file. Default is /var/lib/cloud/instance/user-data.txtz-vz --vendor-datazLPath to vendor-data file. Default is /var/lib/cloud/instance/vendor-data.txtvarname?zA dot-delimited specific variable to query from instance-data. For example: v1.local_hostname. If the value is not JSON serializable, it will be base64-encoded and will contain the prefix "ci-b64:". )rnargsrz-az--alldump_allz Dump all available instance-data)rrdestrz-fz--formatformatzOptionally specify a custom output format string. Any instance-data variable can be specified between double-curly braces. For example -f "{{ v2.cloud_name }}")rrr)argparseArgumentParserNAME__doc__ add_argumentstrr get_runpathparsers 5/usr/lib/python3/dist-packages/cloudinit/cmd/query.py get_parserr&&sX ((dH   :     :++O<= ?          5     7    3      /      <   Mctj|} |jdS#t$rtj|ddcYSwxYw)zAttempt to return a string of user-data from ud_file_path Attempt to decode or decompress if needed. If unable to decode the content, raw bytes will be returned. @returns: String of uncompressed userdata if possible, otherwise bytes. zutf-8FT)quietdecode)rload_binary_filer*UnicodeDecodeError decomp_gzip) ud_file_pathbdatas r% load_userdatar0~sO  ! !, /EA||G$$ AU4@@As(!A  A returnc$tj}t}|r|}ne|jd}|dk(rM|jd}tjj |r|}nt jd|||}n|}|r|}n*tjj|jd}|r|} n*tjj|jd} |jd} tj|} tj"| } tj"tj| } |dk7r/d t$d ||d <d t$d | |d<d t$d | |d<|St'||d <t'| |d<| |d<|S#ttf$rF} | jtk(rt j!d|t j!d |d } ~ wwxYw#ttf$rd } YwxYw)aReturn a dict of merged instance-data, vendordata and userdata. The dict will contain supplemental userdata and vendordata keys sourced from default user-data and vendor-data files. Non-root users will have redacted INSTANCE_JSON_FILE content and redacted vendordata and userdata values. :raise: IOError/OSError on absence of instance-data.json file or invalid access perms. rrinstance_data_sensitivez4Missing root-readable %s. Using redacted %s instead.z user-data.txtzvendor-data.txtcombined_cloud_configz$No read permission on '%s'. Try sudozMissing instance-data file: %sN file:userdata vendordata)osgetuidrr"pathexistsLOGwarningjoin instance_linkrload_text_fileIOErrorOSErrorerrnorerror load_jsonr r0)r user_data vendor_datauidpathsinstance_data_fnredacted_data_fnsensitive_data_fn user_data_fnvendor_data_fncombined_cloud_config_fn instance_jsoner4s r%_read_instance_datarRs  ))+C  E( ,,_= !8 % 1 12K L ww~~/0#4  J%$ $4 /  ww||E$7$7I $e&9&9;LM$001HI++,<= NN=1M% $    8 9!  ax " % j! # ' l# # $2 -. %2,$? j!&3N&C l#1F -. E W  77f  II<>N O  II68H I  W %!%%s+9F#$(G;#G82AG33G8;HHjinja_vars_without_aliasesjinja_vars_with_aliasesr list_keysc2d}|}|jdD]:} ||}||vr||}n|D]} t | |k(s|| }n|r|dz }||z }<|S#t$r8}|rdj||}ndj|}t||d}~wwxYw)aReturn the value of the dot-delimited varname path in instance-data Split a dot-delimited jinja variable name path into components, walk the path components into the instance_data and look up a matching jinja variable name or cloud-init's underscore-delimited key aliases. :raises: ValueError when varname represents an invalid key name or path or if list-keys is provided by varname isn't a dict object. .z*instance-data '{key_path}' has no '{leaf}')leafkey_pathz Undefined instance-data key '{}'N)splitKeyErrorr ValueErrorr) rSrTrrUwalked_key_pathresponse key_path_partrQmsgkeys r%(_find_instance_data_leaf_by_varname_pathrcsO)H s+)  )'>m&L # H $ .H +C0MA'}H   s "O=(-). O% )BII&J9??HS/q ( )sA B3BBct|j|j|j|jgs.t j dtjy t|j|j|j}|jrIdj|j} t|d||j rdnd}|r t'|y yt)|}|jr1t)|d } t+|||j|j }|jrYt1|t2s!t j d|jydj5t7|j9}t1|t$st;j<|}t'|y #ttf$rYywxYw#t"$r)}t j d t%|Yd }~yd }~wwxYw#t,t.f$r}t j |Yd }~yd }~wwxYw)z3Handle calls to 'cloud-init query' as a subcommand.zDExpected one of the options: --all, --format, --list-keys or varnamez## template: jinja {fmt})fmtzquery commandlineTF)payload payload_fnrdebugz#Failed to render templated data. %sNr)include_key_aliases)rSrTrrUz+--list-keys provided but '%s' is not a dict )anyrUrrrr<rDr& print_helprRrrFrGrArBr rir r!printrrcr\r] isinstancedictr>sortedkeysr json_dumps)nameargsrrgrendered_payloadrQr_rTs r% handle_argsrws  dkk4==I J  &   !+   0@0@  {{-444E 3.+"jjde     " # +=9H ||"= t#  ?+3(? .. H ~~(D) II=t|| 99VHMMO45 h $ ++H5 (O g W +  II5A   6*%  IIaL sB'+G;G #HGG H #HH H=H88H=czt}tjtt|j y)z,Tool to query specific instance-data values.N)r&sysexitrwr parse_argsr#s r%mainr|Ks% \FHH[v002 34r'__main__)N)!rrloggingr8ryrCr cloudinitrrcloudinit.cmd.develr!cloudinit.handlers.jinja_templaterrr cloudinit.sourcesr cloudinit.templaterr r getLogger__name__r<r&r0rprRr!boolrcrwr|r'r%rs  ). 5;g!Up AM$M`( $(!(( (V@ F5  zFr'