
    }fk,                         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m	Z	 ddl
mZ ddlmZmZmZ ddlmZ ddlmZ d	Z ej*                  e      Zdd
Zd ZdefdZdedededefdZd Zd Z edk(  r e         yy)aT  Query 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_helperutil)read_cfg_paths)convert_jinja_instance_dataget_jinja_variable_aliasrender_jinja_payload)REDACT_SENSITIVE_VALUE)JinjaSyntaxParsingExceptionqueryc           	         | st        j                  t        t              } | j	                  ddddd       | j	                  dd	t
        d
t               j                  d              | j	                  ddddd       | j	                  ddt
        d       | j	                  ddt
        d       | j	                  dt
        dd       | j	                  dddddd       | j	                  dd 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)actiondefaulthelpz-iz--instance-dataz,Path to instance-data.json file. Default is instance_data)typer   z-lz--list-keyszBList query keys available at the provided instance-data <varname>.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.txtvarname?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:". )r   nargsr   z-az--alldump_allz Dump all available instance-data)r   r   destr   z-fz--formatformatzOptionally specify a custom output format string. Any instance-data variable can be specified between double-curly braces. For example -f "{{ v2.cloud_name }}")r   r   r   )argparseArgumentParserNAME__doc__add_argumentstrr   get_runpathparsers    5/usr/lib/python3/dist-packages/cloudinit/cmd/query.py
get_parserr&   &   sX    ((dH
:   :++O<=?     	 5   7   3  
 /   <  
 M    c                     t        j                  | d      }	 |j                  d      S # t        $ r t        j                  |dd      cY S w xY w)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.
    T)quietzutf-8F)r)   decode)r   load_binary_filer*   UnicodeDecodeErrordecomp_gzip)ud_file_pathbdatas     r%   load_userdatar0   ~   sQ     !!,d;EA||G$$ AU4@@As   * !AAreturnc                 $   t        j                         }t               }| r| }ne|j                  d      }|dk(  rM|j                  d      }t         j                  j                  |      r|}nt        j                  d||       |}n|}|r|}n*t         j                  j                  |j                  d      }|r|}	n*t         j                  j                  |j                  d      }	|j                  d      }
	 t        j                  |      }t        j"                  |      } 	 t        j"                  t        j                  |
            }|dk7  r/dt$        d|| d<   dt$        d|	| d<   dt$        d|
| d<   | S t'        |      | d<   t'        |	      | d<   || d<   | S # t        t        f$ rF}|j                  t        k(  rt        j!                  d|        t        j!                  d	|        d
}~ww xY w# t        t        f$ r d
}Y w xY w)a  Return 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.
    r   r   instance_data_sensitivez4Missing root-readable %s. Using redacted %s instead.zuser-data.txtzvendor-data.txtcombined_cloud_configz$No read permission on '%s'. Try sudozMissing instance-data file: %sN<z> file:userdata
vendordata)osgetuidr   r"   pathexistsLOGwarningjoininstance_linkr   load_text_fileIOErrorOSErrorerrnor   error	load_jsonr
   r0   )r   	user_datavendor_datauidpathsinstance_data_fnredacted_data_fnsensitive_data_fnuser_data_fnvendor_data_fncombined_cloud_config_fninstance_jsoner4   s                 r%   _read_instance_datarR      s    ))+CE( ,,_=!8 % 1 12K Lww~~/0#4 J%$
 $4 / ww||E$7$7I$e&9&9;LM$001HI++,<= NN=1M% $ 89!
 ax"%
j!
 #'
l#
 #$2
-.  %2,$?j!&3N&Cl#1F-.E W 77fII<>NO 	 II68HI W % !%%s+   9F# $(G; #G82AG33G8;HHjinja_vars_without_aliasesjinja_vars_with_aliasesr   	list_keysc                 2   d}| }|j                  d      D ]:  }	 ||   }||v r||   }n|D ]  }	t	        |	      |k(  s||	   } n |r|dz  }||z  }< |S # t        $ r8}|rdj                  ||      }ndj                  |      }t        |      |d}~ww xY w)a  Return 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}')leafkey_pathz Undefined instance-data key '{}'N)splitKeyErrorr   
ValueErrorr   )
rS   rT   r   rU   walked_key_pathresponsekey_path_partrQ   msgkeys
             r%   (_find_instance_data_leaf_by_varname_pathrc      s     O)H s+ )	) '>m&L# H$.H +C0MA'}H s"O=(-). O%  	)BII& J  9??HS/q(	)s   A	B3BBc                    t        |j                  |j                  |j                  |j                  g      s.t
        j                  d       t               j                          y	 t        |j                  |j                  |j                        }|j                  rIdj                  |j                        }	 t        |d||j                   rdnd      }|rt'        |       yyt)        |      }|j                  r1t)        |d      }	 t+        |||j                  |j                        }|j                  rYt1        |t2              s!t
        j                  d|j                         ydj5                  t7        |j9                                     }t1        |t$              st;        j<                  |      }t'        |       y# t        t        f$ r Y yw xY w# t"        $ r)}t
        j                  d	t%        |             Y d
}~yd
}~ww xY w# t,        t.        f$ r}t
        j                  |       Y d
}~yd
}~ww xY w)z3Handle calls to 'cloud-init query' as a subcommand.zDExpected one of the options: --all, --format, --list-keys or varname   z## template: jinja
{fmt})fmtzquery command lineTF)payload
payload_fnr   debugz#Failed to render templated data. %sNr   )include_key_aliases)rS   rT   r   rU   z+--list-keys provided but '%s' is not a dict
)anyrU   r   r   r   r<   rD   r&   
print_helprR   r   rF   rG   rA   rB   r	   ri   r   r!   printr   rc   r\   r]   
isinstancedictr>   sortedkeysr   
json_dumps)nameargsr   rg   rendered_payloadrQ   r_   rT   s           r%   handle_argsrw     s   dkk4==IJ		&	
 	!+0@0@

 {{-444E	3/+"jjde	  "# +=9H||"=t#
		?+3(?..	H ~~(D)II=t|| 99VHMMO45h$ ++H5	(Og W  + 	II5A 	6 *% 	IIaL	sB   '+G ;G #H GG	H#HHH=H88H=c                  z    t               } t        j                  t        t        | j                                      y)z,Tool to query specific instance-data values.N)r&   sysexitrw   r   
parse_argsr#   s    r%   mainr|   K  s%    \FHH[v00234r'   __main__)N)!r   r   loggingr8   ry   rC   r   	cloudinitr   r   cloudinit.cmd.develr   !cloudinit.handlers.jinja_templater   r   r	   cloudinit.sourcesr
   cloudinit.templaterr   r   	getLogger__name__r<   r&   r0   rp   rR   r!   boolrc   rw   r|    r'   r%   <module>r      s   
   	 
  ) . 
 5 ;g!UpAM$ M`( $(!( ( 	(V@F5 zF r'   