3 \me<@sddlZddlZddlZddlZddlmZmZmZddlm Z ddl m Z ej e ZdZd%d&d'd(d)gZGdddejZGdddeZddZddZddZddeddfddZddZGdddeZGdddeZeejffeejejffgZd d!Ze d"krd#d$Z e dS)*N)sources url_helperutil)KlibcNetworkConfigSource)NetworkConfigSourcez 2012-03-01meta-data/instance-idFmeta-data/local-hostnamemeta-data/public-keysTmeta-data/vendor-data vendor-data user-datac@s`eZdZdZdZdZdZddZeddZ dd Z d d Z d d Z ddZ ddZddZdS)DataSourceMAASz DataSourceMAAS reads instance information from MAAS. Given a config metadata_url, and oauth tokens, it expects to find files under the root named: instance-id user-data hostname vendor-data MAASNcCs:tjj||||d|_tjj|jd|_t|j |_ dS)NZmaas) r DataSource__init__base_urlospathjoinseed_dirget_id_from_ds_cfgds_cfgid_hash)selfsys_cfgZdistropathsr$/usr/lib/python3.6/DataSourceMAAS.pyr.szDataSourceMAAS.__init__cCs|jst|j|_|jS)N) _oauth_helperget_oauth_helperr)rrrr oauth_helper4s zDataSourceMAAS.oauth_helpercCstjj|}d||jfS)Nz%s [%s])rr__str__r)rrootrrrr!:s zDataSourceMAAS.__str__cCs|j}y|j|jt|jdStk r2Yn4tk rd}ztjd|j|WYdd}~XnX|jdd}|szdSy0|j |sdS|j|t ||j j |j dddStk rtjtd|dSXdS)NTz%s was malformed: %s metadata_urlF)read_file_or_urlrretriesz$Failed fetching metadata from url %s)r _set_datarread_maas_seed_dirMAASSeedDirNoneMAASSeedDirMalformedLOGwarninggetwait_for_metadata_serviceread_maas_seed_urlr readurlr Exceptionrlogexc)rmcfgexcurlrrr _get_data>s4   zDataSourceMAAS._get_datacCsp||_|\}}}||_||_||_|rlytj||_Wn4tk rj}ztj d|d|_WYdd}~XnXdS)Nz"Invalid content in vendor-data: %s) rZ userdata_rawmetadataZvendordata_purerZconvert_vendordataZvendordata_raw ValueErrorr+r,)rr5dataZudmdvderrrr'es  zDataSourceMAAS._set_datacCs d|jS)z/Return the subplatform metadata source details.z seed-dir (%s))r)rrrr_get_subplatformsszDataSourceMAAS._get_subplatformc Cs |j}d}yt|jd|}Wn"tk r@tjtd|YnX|dkrNdSd}y||krlt|jd|}Wn tk rtjd|YnXtj}|j d r|dd}d |t f}|g}|j j |||d \}}|rtj d |ntjd|ttj|t|S)Nxmax_waitz Failed to get max wait. using %srF2timeoutzFailed to get timeout, using %s/r$z%s/%s/meta-data/instance-id)urlsr?rAzUsing metadata source: '%s'z(Giving up on md from %s after %i seconds)rintr-r1rr2r+r,timeendswith MD_VERSIONr Z wait_for_urldebugZcriticalbool) rr5r3r?rAZ starttimeZ check_urlrCZ _responserrrr.ws8   z(DataSourceMAAS.wait_for_metadata_servicecCs0|jdkrdStj|d|jfi}|jt|kS)alocally check if the current system is the same instance. MAAS doesn't provide a real instance-id, and if it did, it is still only available over the network. We need to check based only on local resources. So compute a hash based on Oauth tokens.NF datasource)rrZget_cfg_by_pathdsnamer)rrZncfgrrrcheck_instance_ids z DataSourceMAAS.check_instance_id)__name__ __module__ __qualname____doc__rLrrrpropertyr r!r6r'r=r.rMrrrrr s  '&r cs0eZdZejejejejfZfddZ Z S)DataSourceMAASLocalcs,tjstjddStjdtjS)NzNo initramfs applicable configFz!Found initramfs applicable config)rZ is_applicabler+rIsuperr6)r) __class__rrr6s    zDataSourceMAASLocal._get_data) rNrOrPrZCMD_LINEZ SYSTEM_CFGZDSZ INITRAMFSZnetwork_config_sourcesr6 __classcell__rr)rUrrSs rScs&d}tfdd|D}tjf|S)zReturn an oauth helper instance for values in cfg. @raises ValueError from OauthUrlHelper if some required fields have true-ish values but others do not. consumer_keyconsumer_secret token_key token_secretcsg|]}|j|fqSr)r-).0r)cfgrr sz$get_oauth_helper..)rWrXrYrZ)dictrZOauthUrlHelper)r]keyskwargsr)r]rrsrcs4d }djfdd|D}dtj|jdjS) z;Given a config, generate a unique identifier for this node.rWrYrZcsg|]}j|dqS))r-)r[f)rrrr^sz&get_id_from_ds_cfg..zv1:zutf-8)rWrYrZ)rhashlibZsha256encodeZ hexdigest)rZfieldsZidstrr)rrrsrcCsN|jdr|dd}tjj| s6ttj|dkr>tdtd|ddS)Nzfile://rz%s: not a directoryz file://%s)version) startswithrrisdirlenlistdirr)r/)Zseed_drrrr(s    r(cCs |dkrtj}|jdr$|dd }i}xtD]\}}} } |dkrPd||f} nd|||f} yXtj|} || ||| d} | jr| r| j||<qtj| j||<nt j d| | j Wq.tj k r}z:|j dkr| rt d ||f|n|j dkr|WYdd}~Xq.Xq.Wt||S) a Read the maas datasource at seed_url. read_file_or_url is a method that should provide an interface like util.read_file_or_url Expected format of seed_url is are the following files: * //meta-data/instance-id * //meta-data/local-hostname * //user-data If version is None, then / will not be used. NrBr$z%s/%sz%s/%s/%s)r&rA ssl_detailsz4Fetching from %s resulted in an invalid http code %sizMissing required %s: %srD)rr%rG DS_FIELDSrZfetch_ssl_detailsokcontentsZ decode_binaryr+r,codeZUrlErrorr*check_seed_contents)Zseed_urlr%rArhrr&r:rZ _dictnameZbinaryoptionalr5rmZrespr<rrrr/s:       r/c Csi}g}xrtD]j\}}}}||kr2|s|j|qd|krl|jd\}} } ||krZi||<||||| <q||||<qWt|dkrtd||rtd||fd} |jdrt} tj |jd| td} | | krtd|jd |jd | fS) zValidate if dictionary content valid as a return for a datasource. Either return a (userdata, metadata, vendordata) tuple or Raise MAASSeedDirMalformed or MAASSeedDirNone rBrz%s: no data files foundz%s: missing files %sNz vendor-data)defaultZallowedz%vendor-data was not loadable as yaml.z user-dataz meta-data) rnappend partitionrkr)r*r-objectrZ load_yaml) ZcontentZseedretZmissingZspathZdpathZ_binaryrstop_pZvd_dataerrrrrrrs2    rrc@s eZdZdS)r)N)rNrOrPrrrrr)9sr)c@s eZdZdS)r*N)rNrOrPrrrrr*=sr*cCs tj|tS)N)rZlist_from_depends datasources)Zdependsrrrget_datasource_listIsr~__main__cs.ddl}ddl}ddl}|jdd}|jddddd|jd d d dd|jd d d dd|jddddd|jddddd|jdddtd|jddd}x0dCD](\}}|j||d }|jd!d"d#dd$qW|j}|j |j |j |j d%} |j dkrJxNdDD]F} d(| d)} tjj| rtj| tjr|jjd*| | |_ qW|j rtj|j } d+| krt| d+d,} x6| jD]*} | | kr~| | dkr~| | | | <q~W|jdkrd-| kr| d-|_|jdkr|jjd.|jd/t| fd0d1fd2d3fd4d5|jdkr|jjd6|jj}|jdd7ks`|jjd8rrt|j\}}}nt|j|j |d9d:\}}}t!d;t!|dkrd|j|dkrd.geturlcstd||jfdS)Nz == %s == %s )printdecode)r5)rrrprinturlszmain..printurlcsx|jdrlxh|jjD]J}|jdr<d||fq|dkrVd|dfqd||fqWn|dS)NrBz%s%sz meta-dataz meta-data/)rGr splitlines)r5line)rrrrrrs  zmain..crawlzChecking seed at %s rBzfile://)rhr%r&z=== user-data ===zN/Az=== meta-data ===z=== vendor-data ===z%s/rrr-rrr)rrr)rr)$argparsepprintsysArgumentParser add_argumentrHZadd_subparsersZ add_parser parse_argsZckeyZtkeyZtsecZcsecconfigrrexistsaccessR_OKstderrwriterZ read_confr`r5exitrrr0rir(r/ZapiverrrrG)rrrparserZsubcmdsnamerr{argsZcredsZfnameZfpathr]rr0Zuserdatar7r;r)rrr rrmainOs                      r)rrFF)rrFF)r r FT)r r TT)r r TT)!reZloggingrrFZ cloudinitrrrZcloudinit.net.cmdlinerZcloudinit.sourcesrZ getLoggerrNr+rHrnrr rSrrr(r/rrr1r)r*ZDEP_FILESYSTEMZ DEP_NETWORKr}r~rrrrr sD        4'