oB]c@sddlZddlZddlZddlZddlZddlZddlmZddlmZej e Z dZ ddddgZ id d d gd6Zd d dddddddddddddgZiidd6dd6dd6d d!6d"d#6d$d%6d&d'6d(d)6d*d+6d,d-6d.d/6d0d16d2d36d4d56d6d76d86i d9d:6d;d<6d=d>6ed?6d@dA6dBdC6edD6dEdF6dGdH6dIdJ6edK6dL6ZedMZedNZdOZdPZdQefdRYZdSZdTefdUYZdVefdWYZejedXefdYYZdZZ fd[Z!d\Z"d]Z#d^Z$d_Z%d`Z&daZ'dbZ(dcZ)ddZ*dS(eiN(tsafeyaml(tutilitdhcp6t ipv6_slaacsipv6_dhcpv6-statelesssipv6_dhcpv6-statefultversiontconfigt network_statet addressestdhcp4sdhcp4-overridessdhcp6-overridestgateway4tgateway6t interfacestmatchtmtut nameserverstrenderersset-namet wakeonlans accept-ras ad-selectsbond-ad-selects arp-intervalsbond-arp-intervals arp-ip-targetsbond-arp-ip-targets arp-validatesbond-arp-validates down-delaysbond-downdelaysfail-over-mac-policysbond-fail-over-macs lacp-ratesbond-lacp-ratesmii-monitor-intervals bond-miimons min-linkssbond-min-linkstmodes bond-modesgratuitious-arpsbond-num-grat-arptprimarys bond-primarysprimary-reselect-policysbond-primary-reselectsup-delays bond-updelaystransmit-hash-policysbond-xmit-hash-policytbonds ageing-timet bridge_ageingtprioritytbridge_bridgeprios forward-delayt bridge_fdt bridge_gcints hello-timet bridge_hellosmax-aget bridge_maxagetbridge_maxwaits path-costtbridge_pathcosts port-prioritytbridge_portpriotstpt bridge_stptbridge_waitporttbridgecCsd}|jd}|jd}|dkr9|}n|r|dk rtd|d|}|jd||j}n|S(sfParses the config, returns NetworkState object :param net_config: curtin network config dict RRit skip_brokenN(tNonetgettNetworkStateInterpretert parse_configtget_network_state(t net_configR"tstateRRtnsi((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pytparse_net_config_data?s  cCsCd}tj|}d|kr?t|jdd|}n|S(sJParses a curtin network configuration file and return network statetnetworkR"N(R#Rt read_confR+R$(tpathR"tnsR(((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pytparse_net_configTs   cCs)tj|}t}|j||S(N(RR-R%tload(t state_fileR)R*((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pytfrom_state_file_s  cCs.t|}x|D]}|j|qW|S(N(tsettdiscard(texpectedtactualtmissingtkey((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyt diff_keysfs  tInvalidCommandcBseZRS((t__name__t __module__(((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyR;mscsfd}|S(Ncs%tjfd}|S(NcsJr7t|}|r7td|fq7n||||S(Ns&Command missing %s of required keys %s(R:R;(tselftcommandtargstkwargst missing_keys(tfunct required_keys(s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyt decoratorus(t functoolstwraps(RCRE(RD(RCs?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pytwrapperss! ((RDRH((RDs?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pytensure_command_keysqstCommandHandlerMetacBseZdZdZRS(sMetaclass that dynamically creates a 'command_handlers' attribute. This will scan the to-be-created class for methods that start with 'handle_' and on finding those will populate a class attribute mapping so that those methods can be quickly located and called. cCsi}x[|jD]M\}}t|r|jdr|td}|r`|||RR((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyt__init__s cCs |jdS(NR(R_(R>((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyRscCs|jS(N(R`(R>((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyRscCs,y|jddSWntk r'gSXdS(NtdnsR(R_tKeyError(R>((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pytdns_nameserverss cCs,y|jddSWntk r'gSXdS(NRdtsearch(R_Re(R>((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pytdns_searchdomainss cCs(|jdkr!|j|_n|jS(N(RbR#t_maybe_has_default_route(R>((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pythas_default_routesccs[|jjdi}x?tj|D].}|dkr?|Vq%||r%|Vq%q%WdS(NR (R_R$tsixt itervaluesR#(R>t filter_functifacestiface((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pytiter_interfacess   ccsLxE|jjdgD].}|dk r?||rD|VqDq|VqWdS(Ntroutes(R_R$R#(R>Rmtroute((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyt iter_routess    cCsx'|jD]}|j|r tSq Wxa|jD]S}xJ|jdgD]6}x-|jdgD]}|j|ritSqiWqPWq7WtS(NtsubnetsRq(Rst_is_default_routetTrueRpR$Ra(R>RrRotsubnet((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyRiscCs.d}|jddko-|jd|kS(Ns::s0.0.0.0tprefixiR,(s::s0.0.0.0(R$(R>Rrt default_nets((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyRusN(R<R=tNETWORK_STATE_VERSIONRctpropertyRRRfRhRjR#RpRsRiRu(((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyR[s   R%cBseZiid6gd6igd6gd6d6ed6d+d6Zed+dZedZed Z e j d Z d Z d Z d Z dZdZedZedZedZedgdZedgdZedddgdZedddgdZeddgdZedgdZedgd Zed!gd"Zd#Zd$Zd%Zd&Z d'Z!d(Z"d+d)Z#d*Z$RS(,R RqRRgRdR\RcCsA||_||_tj|j|_||jdRR((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyRcs    cCst|jd|jS(NR(R[R_R`(R>((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyRscCs|jjdS(NR\(R_R$(R>((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyR\scCs|jji|d6dS(NR\(R_tupdate(R>tval((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyR\scCs1i|jd6|jd6|jd6}tj|S(NRRR(R`R|R_Rtdumps(R>R)((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pytdumps    cCsd|kr(tjdtdnt|d}t||}|rqd|}tj|t|nxAg|D]}|dkr{|^q{D]}t||||qWdS(NRs$Invalid state, missing version fieldsInvalid state, missing keys: %s(sversion(tLOGterrort ValueErrortNETWORK_STATE_REQUIRED_KEYSR:tsetattr(R>R)RDRBtmsgtkR9((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyR1s    ,cCstj|jS(N(RRR_(R>((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pytdump_network_statescCsi|jd6|jd6S(NRR(R`R|(R>((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pytas_dictscCs |j}|S(N(R(R>R/((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyR's cCsZ|jdkr+|jd|t|_n+|jdkrV|jd|t|_ndS(NiR"i(R`tparse_config_v1RvR~tparse_config_v2(R>R"((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyR&"s  cCsx|jD]}|d}y|j|}Wn!tk rNtd|nXy|||Wq tk r|s|qtjd|dttj|j q Xq WdS(Nttypes!No handler found for command '%s'sSkipping invalid command: %stexc_info( R|RLRet RuntimeErrorR;RtwarningRvtdebugR(R>R"R?t command_typethandler((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyR*s   cCsx|jjD]\}}|dkr.qny|j|}Wn!tk rbtd|nXy||||j|Wqtk r|sqtjd|dt tj |j qXqWdS(NRs!No handler found for command '%s'sSkipping invalid command: %sR( R|RMRLReRt _v2_commonR;RRRvRR(R>R"RR?R((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyR<s"    RTcCs |j|S(N(thandle_physical(R>R?((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pythandle_loopbackPsc Cs|jjdi}|j|di}x:|jdijD] \}}|ji||6qDWt|jd}|jsxK|D]@}|jdjdst|jdrt|_PqqWn|jdd}|dk rt j |}n|ji |jdd6|jdd6|jd d 6d d 6d d 6|jd d 6dd6dd6|d6|d6|jdji||jd6|j dS(s command = { 'type': 'physical', 'mac_address': 'c0:d6:9f:2c:e8:80', 'name': 'eth0', 'subnets': [ {'type': 'dhcp4'} ], 'accept-ra': 'true' } R RTtparamsRtRt6taddresss accept-rat mac_addresstinettmanualRR tgatewayN( R_R$RMRt_normalize_subnetsR\tendswitht is_ipv6_addrRvR#Rtis_trueR( R>R?R RotparamRRtRwt accept_ra((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyRTs6%       $tvlan_idt vlan_linkcCs|jjdi}|j||j|jdi}|jd|d<|jd|d<|ji||d6dS(s auto eth0.222 iface eth0.222 inet static address 10.10.10.1 netmask 255.255.255.0 hwaddress ether BC:76:4E:06:96:B3 vlan-raw-device eth0 R RTRsvlan-raw-deviceRN(R_R$RR(R>R?R Ro((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyt handle_vlans  tbond_interfacesRc Cs|j||jjd}|j|jdi}x7|jdjD] \}}|ji||6qPW|jidd6|jdji||d6x|jdD]}||kri|d6dd6}|j|n|jjdi}|j|}|jd|d R?R RoRRtifnametcmdtbond_if((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyt handle_bonds& "  "tbridge_interfacesc Cs|jjdi}xC|jdD]2}||kr=q%ni|d6}|j|q%W|jjdi}|j||j|jdi}|d|dR?R RRRoRRR((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyt handle_bridges0   %      cCs|j|dS(N(R(R>R?((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pythandle_infiniband sRcCs|jjd}d|krk|d}t|tksF|g}nx"|D]}|dj|qMWnd|kr|d}t|ts|g}nx"|D]}|dj|qWndS(NRdRRRg(R_R$Rtlisttappendt isinstance(R>R?RdtaddrstaddrtpathsR.((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pythandle_nameservers        t destinationcCs|jdjt|dS(NRq(R_Rt_normalize_route(R>R?((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyt handle_routescCs|j|dddS(s v2_command = { bond0: { 'interfaces': ['interface0', 'interface1'], 'parameters': { 'mii-monitor-interval': 100, 'mode': '802.3ad', 'xmit_hash_policy': 'layer3+4'}}, bond1: { 'bond-slaves': ['interface2', 'interface7'], 'parameters': { 'mode': 1, } } } v1_command = { 'type': 'bond' 'name': 'bond0', 'bond_interfaces': [interface0, interface1], 'params': { 'bond-mode': '802.3ad', 'bond_miimon: 100, 'bond_xmit_hash_policy': 'layer3+4', } } tcmd_typeRN(t_handle_bond_bridge(R>R?((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyt handle_bonds#scCs|j|dddS(s v2_command = { br0: { 'interfaces': ['interface0', 'interface1'], 'forward-delay': 0, 'stp': False, 'maxwait': 0, } } v1_command = { 'type': 'bridge' 'name': 'br0', 'bridge_interfaces': [interface0, interface1], 'params': { 'bridge_stp': 'off', 'bridge_fd: 0, 'bridge_maxwait': 0 } } RR!N(R(R>R?((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pythandle_bridgesBsc CsLxE|jD]7\}}idd6|jd|d6}|jdi}|jdd}|stjd|t|n||d<|jd d}|ri|d 6|d v1(physical): %sN( RMR$R#RRtstrt_v2_to_v1_ipcfgRPRR( R>R?tethtcfgtphy_cmdR RRR9Rt((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pythandle_ethernets\s*&   cCsx|jD]\}}idd6|d6|jdd6|jdd6}d|krj|d|d v1(vlan): %sN(RMR$RRPRRRR(R>R?RRtvlan_cmdRt((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyt handle_vlanss cCstjddS(NsNWifi configuration is only available to distros withnetplan rendering support.(RR(R>R?((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyt handle_wifisscCstjd|d|kr|jdjdg}|jdjdg}idd6}t|dkr|ji|d6nt|dkr|ji|d6ntjd||j|ndS( Nsv2_common: handling config: %sRRgRt nameserverRis$v2(nameserver) -> v1(nameserver): %s(RRR$RPRR(R>RRgRdtname_cmd((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyRs  c stdtj|jDxw|jD]i\}}td|jD}|d}|jdd}|r||dscss-|]#\}}|tkr||fVqdS(N(tNETWORK_V2_KEY_FILTER(RR9tvalue((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pys s t parameterssgratuitous-arpsgratuitious-arpRRTR t _interfacesc3s%|]\}}||fVqdS(N((RRR(t v2key_to_v1(s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pys sRR iRtsv2(%s) -> v1(%s): %sR!Rs Unknown command type: {cmd_type}RN(tdicttNET_CONFIG_TO_V2R$RMtpopR#RRPRRRRRRR( R>R?Rt item_nametitem_cfgt item_paramsRt grat_valuetv1_cmdRt((Rs?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyRs6    #    c Csyd}g}|jdrTidd6}||jdi||j|n|jdridd6}t|_||jdi||j|nd}d}i}x?|jdgD]+}idd6|d 6}d |kr.d |krl|dkrl|jd }|ji|d 6qln>d |krl|dkrl|jd }|ji|d 6nd|kr| r|jdjd} | r| |dRRRtRwR R RRRRgRqRr((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyRsR         .N(%R<R=RaR#R}RzRcR{RR\tsetterRR1RRR'RvR&RRRIRRRRRRRRRRRRRRRR(((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyR%sH          05@   ? !  )cCstj|}td|jD}|jdd kr\|jt|dd ng|jdgD]}t|^qo|d5sRRtstatic6t address_keysRRqcSs;||kr7t||t r7||j||Rss/No config network address keys [%s] found in %st,tnetmaskt/Rxi@is;Overwriting existing 'prefix' with '%s' in network info: %sN(RRMR#R$tjoinRRRRt partitiontinttmask_to_net_prefixRRtnet_prefix_to_ipv4_mask( R,Rtnettaddr_keyR9tmessageRtipv6Rt addr_partt_t maybe_prefixRx((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyRGsF        (     cCstd|jD}d|kr@|d|d<|d=n|jt|dd|jd}|ryt||ds RR,RRs(Route config metric {} is not an integer(snetworks destination( RRMRRR$RRt TypeErrorR(Rrt normal_routeR((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyRs    cCs,|sg}ng|D]}t|^qS(N(R(Rtts((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyRs cCs|s tSdt|kS(NR(RaR(R((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyRscCsT|djds#|dtkr'tS|ddkrPt|jdrPtStS(s:Common helper for checking network_state subnets for ipv6.RRRR(RtIPV6_DYNAMIC_TYPESRvRR$Ra(Rw((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pytsubnet_is_ipv6s #%cCs1tjtjdddt|>d@}|S(sConvert a network prefix to an ipv4 netmask. This is the inverse of ipv4_mask_to_net_prefix. 24 -> "255.255.255.0" Also supports input as a string.s>IIi (tsockett inet_ntoatstructtpackR(Rxtmask((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyRs'cCst|tr|St|tjrJyt|SWqVtk rFqVXn tdd|krutd|n|jd}t|dkrtd|t|fntg|D]!}t t|j d^qS(sConvert an ipv4 netmask into a network prefix length. If the input is already an integer or a string representation of an integer, then int(mask) will be returned. "255.255.255.0" => 24 str(24) => 24 "24" => 24 s mask '%s' is not a string or intt.s#netmask '%s' does not contain a '.'isnetmask '%s' had only %d partsR( RRRkt string_typesRRRRPtsumtbintcount(Rttokstx((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pytipv4_mask_to_net_prefixs    cCs t|tr|St|tjrJyt|SWqVtk rFqVXn tdd|krqtdndddddd d d d d dddddddg}d}xS|jdD]B}| st|ddkrPn||jt|d7}qW|S(sConvert an ipv6 netmask (very uncommon) or prefix (64) to prefix. If 'mask' is an integer or string representation of one then int(mask) will be returned. s mask '%s' is not a string or intRsmask '%s' does not have a ':'iiiiiiiiiiiiiiiiii(RRRkRRRRtindex(RtbitCountRxtword((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pytipv6_mask_to_net_prefixs&     cCsFyt|SWntk r!nXt|r8t|St|SdS(sXReturn the network prefix for the netmask provided. Supports ipv4 or ipv6 netmasks.N(RRRRR(R((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyRs   cCstdjg|jdD] }tt|dd^qd}t|}|dd|dB}djgtdd d d D]}t||d>?d @^q}|S( sZCalculate the broadcast address from the subnet mask and ip addr. Supports ipv4 only.RRiiii iiNii(RRRRRtrangeR(RtipRtip_bintmask_dect bcast_bintit bcast_str((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pytmask_and_ipv4_to_bcast_addrs H  >(+R]RFtloggingR RRkt cloudinitRRt getLoggerR<RRzR RRR#RRvR+R0R3R:t ExceptionR;RIRRJtobjectR[t add_metaclassR%RRRRRR RRRRR%(((s?/usr/lib/python2.7/site-packages/cloudinit/net/network_state.pyts              HT  :