From 9f629ff62c270fd3771c381f78aa36f473e65bb5 Mon Sep 17 00:00:00 2001 From: Lianhao Lu Date: Fri, 10 Aug 2018 17:04:14 +0800 Subject: [PATCH] Added the logic to validate HPA Added the code logic to validate HPA for opnfv tosca parser. Also corrected some hpa validation schema errors introduced by the previous patch. Change-Id: Icd61d34d7915aa965ec32adfc3c0f1a117dd6f3e Issue-ID: VNFSDK-194 Signed-off-by: Lianhao Lu --- tests/resources/hpa.csar | Bin 0 -> 7984 bytes tests/resources/hpa_bad.csar | Bin 0 -> 7984 bytes tests/validator/test_toscaparser_validator.py | 16 ++++ vnfsdk_pkgtools/validator/hpa.yaml | 55 ++++++------ vnfsdk_pkgtools/validator/toscaparser_validator.py | 99 ++++++++++++++++++++- 5 files changed, 141 insertions(+), 29 deletions(-) create mode 100644 tests/resources/hpa.csar create mode 100644 tests/resources/hpa_bad.csar diff --git a/tests/resources/hpa.csar b/tests/resources/hpa.csar new file mode 100644 index 0000000000000000000000000000000000000000..a9558aea931357d2eb103011151982da0489231b GIT binary patch literal 7984 zcmeI1Wl&t*viAoM5(w@Z++9O(3lbo>4=}(0gAVQlNg%-B65QP-IKc_-gg}4*g9poC zL0+DF-&5x~x#xVm-|pJA_O9Ml>sPy0uj=0YZ%tJcR3ZQX@C48lilr`r^g~7i2>^gS zPMXKJGHy_?4bTee&f@^`apwVgK<%8}z`h`B^S^B3;ZaXHX+ZEsKu*42i4qL8ed5V` zld?HpiBv7iX9C=Ouh%Zt0;G1fF*ZjeuCVR(;|;zflwC-9^A#BO@=vdtnLnB{l{5KnUE%W(S`V5(nCKoMMKW{-93D((Kg&% z3%riR2lSGf>)|_&r|pvSazjGmGwa*rHo7s-Khj`|-39aF!BgJX(K?+?6>6a?!v^16 zm2z06Z+<9H^?pAs!mg?k0&qGg?Q|zagd#X<(nv-$r<`cYvoF=1>?4<0kBBGfqN(16 z(+<;dn_y`BL94ID2o1mD#u3#RNjiIKLEiOQY+M-~ATlYMZZ(vQm>}uUoTOOVqck?> zZq0x3L`NbO2?iPf5Qh!`5dTk4fUV8l+<}nfmikOAfSg}fujD3uNiUk1ZOYu|1h0|w znxMt%93x`!=fpR6zm+msD;9VrZG*(JDe6P6R7n%N2c3I#bX_fVV?iF-9tsymqpu}$ z6g&BW10sE)@ILDk15s>c%3uyTekGk=`AF~HD^ZD)732%UN^$>A?1WF6i}U#kQ`7dJ zRu`LhS`)2yrYTObMyALe#`b;)!aDsV+aoIc|}~3wKS!=Q}Ds z84S<#lVJE2lb&y}{#L+z7n1zpes@KOAsbJ$jURC=_F-NHmuEaK($l)=s>z;FeO%Q= z6C7tzdA6s8qVfd6t8d6xsDWj@#}R|638@}UNtEv);u+^qaY9y{9s-67K^V{TU(4y5 zlot4=XC!{9A(TyT9(5%V*#-=pHdFoMGkODYBgTS?O?Bj;e!i&0 z1-||<*G;w6Ab+$=f|I9oO1@N-6g=n8Vf~3OsXi^d33ue=Gzcdrx~Utl3}WT+C&a!* za#ttC#*iw;+?gFlBRgDA7w&tjJCEaF0N(a@Au8<3-%YN_F61{(y8Z?N*V91Z=PcGQN`zU))F3T z%&|p~#-J_e$tRybGbkj*>Me}q3cte6j#z)%d6`rorvFv~d-{j}^wtX_mWike*S*)} zrsv<#8RmcDYHc0JTZ3OL$Z@)-NXrX3F~#l}Vh-|WJ!352My*l$l;yC1nTp)bJr{m% z4`4m3kC_bZZKp5>S;&_4>MFN^JPylJ$=(>oRP1D&%SmNgA5S$gVIy1?lpK5mvqE0m zljtk#%;L^6Aoxt53dIH2QzmM5I2U%k_{7onL5~LcRMEfD-HxJcQp$2^1an<_3OepT zkhG5Wz%K}IO!i>zjLNU7i26vH+pCK~D^t^&JKAZh;a4|e@Yx!YNkeX-J4-ny#99C< zc3U|SbkHE)9ny=iGcEky4}YyBINsYfApE9Tnf`T_*okMfGTo*GtlB^^`Mxvms6~?q z91HgSaA*CrOIMi|C91P{*84&3+X^XrlGbaUno0+4S(Q1*R)W1in2iI;M0~IwNx8wIt_nl9!uVh zGLg%`_4658cl>TLfabr6QM({8&A~0PpcEVcsPoOu7g^$p^CBJVpWWHy)Sjp`?N?DL z`I!BxyJY{2Pb#5hISk)ft|-K~XA^`n9sn6@iQZ6q>)#QtP@hM~A1KpO+UR4IlAoOK zEhEkH{I*{sk7TAi{YA!EW=A!D4~ocu+rG&WR&gL>T8}z-v5+Yd$I}%0=~#Us9ds~S zQ;Tyx%P7{Q8I?q6x0O* zhkc8*4uq%UAjys|F(9F)n$ZJUrxUV8KSfS%7Z1z-OJDzc>FaUd0my&d9tYLq{O6AZ z7y`5fx$}5fdN@Hn_=LH61yTNRpnYto95WsO5Mc!XkUg%I2ibs~z)-NWlRJ;I6VS!n z8p7=ZggCBJnL2+HJzMP#742L>ij8md^NZ{%Qm=Q&b*%>*QPn;{Rm`U{W71O9(&+5I zkC1EU5VOA ze_r>tZiS*R5$?L?z@Qr)Lu{w`(bIjDPzCL_m`T)_C%$xSqo0(f=DE&fL#=eA72AV& zT#)*S35MIzzUUh#ug&UG9qQ$nE#iMCxE7FoxdB!37g^`@U8D?DNPrzZCx}kYXfP0^ zbqUP@Ke3M2q4#@M?aWPLhH1B^u;{><$9pf^I_z?lJ@_&Z7lYS%+}}d2M_FLWm_ZZ~ zi&iClh7z5irq++27uFEwa?O?VUURs4t}l;LASY?f!qq|-b7TmaW1$Qo1>Y3my~PSF zwQ)I9QWQH~%L7ERv32>0WjLKy5V*i1b4+Y`}S(wdfRCDo+6{AzjNQc>}`vED0R+@A!JN8&NSQ2Fm2Mjez>kv&j?R#YT0-u*N*7zHpU`OtXswP4J3*{!tX2 zF}+XO_VXO6tQK6-@dl|*9YRTgu5PD(BO=T3>GL8iiFSUabSgIb$1z@VPVA2m8S5an}P zUYH>95GF6Whgg0+6=On#&Joj$3-)LP|BF1Mue~D4QCGwep_c{O*kbSG-!HwTnqCXM z4igqJpSppc-Tpuh5Hr7XKwLOKPk6efp_B`5V?HS*r*G79k?ZH!G+)dOrgGCcn;JF8 zO?CZH@E)!gje46o1ZJ51@Rn0}JR!_=Ly^qQByU8l(m(Rt+sh*|u(O+!?Mv(SOoD02 z#3jY2{yBFxN)s0|3J1+3JkHqnzj|QXl6niipY+1K@qRuFd^Tpa0fywfBkh&3Q$_tI z#~TEuq z;(oTvdIP;Yy`}1^3^dEai$@)yGR#-fSU)yS=z5XPB$8H3%RV^6zdU%9TVow(KsQ1n zE$C93cR$28_-^p$Nw%$dG8%5YVXum`sQ=47cB@(zv2k=SRJbv68T}R0V8}H4&=vp( zdZm-C5!{b!aPXtw|he zgD#jpD~N@f%fj#GU@5)$n!LautecuVAB6@lGBrfp|LfZ6sKM0P0}a0g>i$m4vg5+^ zx4=4ea+3ngzA)y6iTm&dPQ%|BRQ_Z`v7u>;0Rz2$r(a3*KH=;ME7s_Av145y{&MBV zPGjNQa5A0g$S=UV(rvRXm3BnY&4<$A$xu3>Q}?U+5)rYnyIe318Xt+!`aMqRw11wM z2Z>YEVptxAP~99%BVA4oh+pGt($_s$(bc0B_znD~MM+O`EZXMyoe135Aw%3X;}>m# za>_G+)nBBLQ?V+v5ks^9YHPLqc;=divs1SQdGmXehcW@*hXK{<=+zeHkc=q5pl&Dm zK++#q@tdORys0cumdz4kjffY(DuP7@?f^y!0vaaZ6b*;kM5Bcg^{b>`O&J|zHyXIc zzc;5MLf3orzD^S9+e;y%tJ1CEEzxO#v`{|T?890De4TN23EZ(ToZWe?$~F0rSiq@l#Jkcala$%) zOQ(L(-QU=;rX++S#Eh=dZ!0}NcaR<_F7eqtm15TCjqKzedWI8aRs7<193J^KHc0KI zx2WoSr{Aj-;l+mz<74EfDoPbnPGT3zuyCh6!EK~4$78GXDcEvMQ9XL!`yqyh* z&+B8EWY9tZj`0RD7yFxvFni`a_Q002YNR}d-#988US%_1(#e|Rx}K`EmT_n&F1!W= z&nEfsue`dheR?HqP5uI>9pG8*qbsm&g2bx@7t$YfEj644PWLvLvUc+ObPxB!C^r76~+e2F)(tHZGnAt z116VJTz%#!nOn}%d~a7Sok{>$9k$~wEp^}}3X1*H1 zdKGnxp`RDxqwSsSn!a(ob+ohjlbcP4t5m ztue{@o15Z75Kh><7%GmL?-IWpHV=e~MMEh(b}no^+k!J%)&`A2IOD$Ttn#{)r<{|g ze&C)U_26j!G14B@K948n=jB?91(xoR>@k3ZW~G0QNhgl{7%r|p^M2tpHURBc1L{fW z5g>$itC^q{LgYS`IRIyr#Mn$X7!FV z`~-D-4%y0!p@1c=*=%YRj@61+qH*F9Aj%MW5Zq5;p$&b8p{_eZvg)pt8Rj`hx$eWm zj{<%B?6}95xqkg^Mx}vEB8px7S_I^^uU|H967`6UC_nlcLrbX>7nS0z2huCoJReNi zA*`deMDl`g{;n~`;`Bw#=_SvRE z)7a{guRzmrF!h|lkIHgx$-;B_H3|oz4!&tzXCV@yVqII=$OJkv?QpiITug`W<#o@Y zxy-PyVVlFs2XZ7#WM1wL+Af(ix$U7dS)AlR1xq2qvLkz74F67qb(Oe}Y0S$~7+y>DY)qk_m9F^jz1nUf?#*B~ujb0GQHiv*1emXmvQ47% z?y;Nf{c%uf7|9Ct;S}E*&%6+mPd2?SkF$fQhLJHZ>ynnfann>L2^FyOxu+7|@jA}< zcl6fep~8A|2C!E^Y@;xdWPaZbY;DAAyQkb7pA&w_PQ59wdPVfgm zxj&kn$M}^A;o7ZQBdJ|-+Ci{xB^f)1h4%!<@(3Ab0|QzW)~%x)ykp!dIZx zolM82Hp=lxtT~M9IUxG_j6}(|2Wf&ub}9{Fc)yH4%yoX(UM&LO991jEbY#yWAvg=- z_g+mbImpa2!hOhhsRK(h^t74l{!(Ct24?+=ucws?GeaFPO zj9;W4jwQa<>?Jetze;Mjt8$9n+zgs1J#XBmx*VJA<|-qeWyfoaHfm{j5=HA|)Rk%_ zahXZVOo;O=)$v9T6V%!61*h)!JG{@{M(d96L-J{WKFOJ2ngd$2Vf&%2AKzpq)wJW; zn=jLznWDe^N}1i{>(yjjv(o9c)JSnppPo0}$6}&Ko?AEI{Zj(t0&7O|&BT^2kCK@q z3_OR}Eb%zcOU&|pj0Gbo4*l;8FAT{FU#Qb`Vu@XL!n8G)&$}?MZ?4$(c~duXPW44* zI<#yNipaQf7v(hmr8N6Ua#JOP)B8PRS9X!PRTlhC5HX&o7sV8F%U*SDRE>ThFbl1b zma)m6tVXYRyTlwpoPWCnU9X&%NTOK6Yf)kbPa4_H=az=Qa8u7tTe5ma2(E*>ap02% z>>;r3?VO1(4qU3lDXbFMWI+Q7pRFc}aI9vtAJX@PIBD!CWWIrkRjE3ss5c#}$TCf^ zj5T_eM0ZQD6G597tqL?WGgl5AJ%%hB+k_Fb4JW>V_KD#`GFIs2G^pYN$63X&>2GrC zjB*n#3HppjUv~#Dq4JM(-P+vajun>G0jeGo*oP>k8bm9d&0_c=XTMPjS4+ei!GjiJT%lxrkk>6pjh0yTDZtL47*JFFlJtr?MMq3vt2!MfAyyWEAAi@! zhWydK8_ifyZOW`_P*LQ|*9MI(DpNZ*#n8mtRTiM@H9F^ExK9-s%XRJqpRkAzxh9Mi zb9DCZq2{)p&%dMB*sCa+QBU2`w1~ zhNu7l?qhw;_(yH64g@>B0l9gCtw1^;h>If-3i_`)dqCgV`I|6N;AIWnVPw}_eI`g| zr^O^fSh@k#JtGxJXLmLXXNadzVRL5S~1e@LC3sk`u#}nX=}- z%n*DS;KBZZJo1I}b%>K;%8Xcy61gaInpHGDJuYmJN^^kU0Csi@*Eg!BZA;So=1nuO z$sJDYR4^WDH*gjY7>yY-wSXW#Of?Hn_!`glC@YZouolG6wrU`JRVl->RlrC`3eTQz zy|`?%(|e(PI~>D_V(CImjt_A!?TqO_rYtM`@KfG3dy%SjT8xZ^GWovH5gUCTT+*sR zx`mgXIuz7wZHwjcT0p0T4pWt@F-b8@Sj%xDiPxbOPH>7TK6gCtm4*qFC9A#Q5HdB| z&KLs+@L8w^x4)9s}}It2ac248wl?SeD}C6GUoBciiZ?$JYi(^a?5U zcv^3+U4!YB^@U{GikZ1dBA!S|=QrmT8q04ks}YQyJ`~1XAs^HaQpl|)`!`$0A?0H3 z2%+ycSg#vLinXsk3bFDgJkJZ4taj;UvZ~f)SPaKJn@uP}^G@GBo*g}CKTQ=0U|}rL zrj?I{u(ZZCA2-W=FgP^%9zw8e5_Jq`xF&ts6}^^)BU$NcD$OR=K~U|3lOI>XrW_yr zTfa<63d!jMeCfkde@Uhs7V%-68z`;icb`4fJk6gsyRVV*uJPzTSqC|fXLxm>g!gW|P0&DWU_EihQ`0CT(762a!h^Ys^#xlz8x&hCF{+%wcw@gmSQ$k9 zW+i%}UG4A`REz!cm+X*YCU(W=d*A!MZWV4sf?c2w z>}lH1Q4j(Aay@<0brCJT79?Kd|4{R};SvsBZ$!u!o+q;YyjS0MYA5ku@*a&G1yuMc z{yj8#{S}((LgnoqLz4gF{7bjhdHqIChD#j;1zH24K%W0Hxgn3HJFX|r%u`h^_KC5{ z25n7|IRTv=H||&JoGR+m9_5YNCztLx>u%#5Y~^zvD(a(Sqnt?WoXy(OKX!jJ+rZIE zNRmO!B@u;ik}ZJHfi5!~?($edNJ#A86sIumw}Ie=`Ab&06KIdBBoZ{f|Ave~b7__5Ks{ z*RsDWwg130hNwLGJLZ4twttfT)NTJs3V$U1Cl&Yalz*3@{z=&&{a4C=%2$6U{=0+q h4`MKq|D!bhACH-)D%#^d0st6~*TbVzD5?Ll{vX=uwIcuk literal 0 HcmV?d00001 diff --git a/tests/resources/hpa_bad.csar b/tests/resources/hpa_bad.csar new file mode 100644 index 0000000000000000000000000000000000000000..4431d61980057cd07cba65773a8a330ad6e7531d GIT binary patch literal 7984 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 g^oR3)mZtyXF;kXDdfrC>0Ok35dUgs4*<{9 literal 0 HcmV?d00001 diff --git a/tests/validator/test_toscaparser_validator.py b/tests/validator/test_toscaparser_validator.py index c35d1ed..3348d60 100644 --- a/tests/validator/test_toscaparser_validator.py +++ b/tests/validator/test_toscaparser_validator.py @@ -15,13 +15,29 @@ import os +import pytest + from vnfsdk_pkgtools.packager import csar from vnfsdk_pkgtools.validator import toscaparser_validator CSAR_PATH = 'tests/resources/test_import.csar' +HPA_PATH = 'tests/resources/hpa.csar' +BAD_HPA_PATH = 'tests/resources/hpa_bad.csar' def test_validate(tmpdir): reader = csar._CSARReader(CSAR_PATH, str(tmpdir.mkdir('validate'))) validator = toscaparser_validator.ToscaparserValidator() validator.validate(reader) assert hasattr(validator, 'tosca') + +def test_validate_hpa(tmpdir): + reader = csar._CSARReader(HPA_PATH, str(tmpdir.mkdir('validate'))) + validator = toscaparser_validator.ToscaparserValidator() + validator.validate(reader) + assert hasattr(validator, 'tosca') + +def test_validate_hpa_bad(tmpdir): + reader = csar._CSARReader(BAD_HPA_PATH, str(tmpdir.mkdir('validate'))) + validator = toscaparser_validator.ToscaparserValidator() + with pytest.raises(toscaparser_validator.HpaValueError): + validator.validate(reader) diff --git a/vnfsdk_pkgtools/validator/hpa.yaml b/vnfsdk_pkgtools/validator/hpa.yaml index bc551c6..98ac42b 100644 --- a/vnfsdk_pkgtools/validator/hpa.yaml +++ b/vnfsdk_pkgtools/validator/hpa.yaml @@ -7,11 +7,11 @@ schemas: # hpa key name cpuModelSpecificationBinding: # json encoded key name: reg expression for the valid value - schema-version: &any r'.*' + schema-version: &any '.*' schema-location: *any - platform-id: &generic r'generic' - mandatory: &bool r'true|false|TRUE|FALSE|True|False' - configuration-value: r'strictBinding|equalOrBetterBinding' + platform-id: &generic 'generic' + mandatory: &bool 'true|false|TRUE|FALSE|True|False' + configuration-value: 'strictBinding|equalOrBetterBinding' instructionSetRequirements: schema-version: *any schema-location: *any @@ -23,7 +23,7 @@ schemas: schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'enabled|disabled' + configuration-value: 'enabled|disabled' hypervisorConfiguration: schema-version: *any schema-location: *any @@ -35,7 +35,7 @@ schemas: schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'pciDetectedAndCorrectedErrors|pciDetectedAndUncorrectedErrors' + configuration-value: 'pciDetectedAndCorrectedErrors|pciDetectedAndUncorrectedErrors' cpuModel: schema-version: *any schema-location: *any @@ -71,44 +71,44 @@ schemas: schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'\d+' + configuration-value: '\d+' virtualCpuClock: schema-version: *any schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'\d+\w*(Hz|kHz|MHz|GHz)' + configuration-value: '\d+\s*(Hz|kHz|MHz|GHz)' logicalCpuPinningPolicy: schema-version: *any schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'dedicated|shared' + configuration-value: 'dedicated|shared' logicalCpuThreadPinningPolicy: schema-version: *any schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'require|isolate|prefer' + configuration-value: 'require|isolate|prefer' vduMemRequirements: memoryPageSize: schema-version: *any schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'\d+\w*(B|kB|KB|KiB|MB|MiB|GB|GiB|TB|TiB)' + configuration-value: '\d+\s*(B|kB|KB|KiB|MB|MiB|GB|GiB|TB|TiB)' numberOfPages: schema-version: *any schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'\d+' + configuration-value: '\d+' memoryAllocationPolicy: schema-version: *any schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'strictLocalAffinity|preferredLocalAffinity' + configuration-value: 'strictLocalAffinity|preferredLocalAffinity' memoryType: schema-version: *any schema-location: *any @@ -132,7 +132,7 @@ schemas: schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'\d+' + configuration-value: '\d+' processorCacheAllocationType: schema-version: *any schema-location: *any @@ -151,13 +151,13 @@ schemas: schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'\d+' + configuration-value: '\d+' storageResilencyMechanism: schema-version: *any schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'erasure|tripleReplication' + configuration-value: 'erasure|tripleReplication' processorCacheAllocationSize: schema-version: *any schema-location: *any @@ -176,13 +176,13 @@ schemas: schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'\d+' + configuration-value: '\d+' localNumaMemorySize: schema-version: *any schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'\d+\w*(B|kB|KB|KiB|MB|MiB|GB|GiB|TB|TiB)' + configuration-value: '\d+\s*(B|kB|KB|KiB|MB|MiB|GB|GiB|TB|TiB)' logicalNodeIoRequirements: pciVendorId: schema-version: *any @@ -201,7 +201,7 @@ schemas: schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'\d+' + configuration-value: '\d+' pciAddress: schema-version: *any schema-location: *any @@ -213,7 +213,7 @@ schemas: schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'required|notRequired' + configuration-value: 'required|notRequired' networkInterfaceRequirements: nicFeature: schema-version: *any @@ -221,13 +221,13 @@ schemas: platform-id: *generic mandatory: *bool configuration-value: *any - dataProcessingAccelerationLibray: + dataProcessingAccelerationLibrary: schema-version: *any schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'DPDK' - dataProcessingAccelerationLibrayVersion: + configuration-value: 'DPDK|dpdk' + dataProcessingAccelerationLibraryVersion: schema-version: *any schema-location: *any platform-id: *generic @@ -238,14 +238,13 @@ schemas: schema-location: *any platform-id: *generic mandatory: *bool - configuration-value: r'virtio|PCI-Passthrough|SR-IOV|E1000|RTL8139|PCNET' + configuration-value: 'virtio|PCI-Passthrough|SR-IOV|E1000|RTL8139|PCNET' mappings: # mapping between property value of a tosca node type and the valid hpa schema # type: tosca node type # key: prop1##prop2##...##propN # Property hierachy within that node type. Prefix of '(capability:)' # in propI means the value is from capability instead of property. -# Suffix '[] in propI means the value is a list of propI+1. # schema: schema defined in the above schemas section - type: tosca.nodes.nfv.Vdu.Compute key: capability:virtual_compute##logical_node##logical_node_requirements @@ -255,13 +254,13 @@ mappings: schema: vduCpuRequirements - type: tosca.nodes.nfv.Vdu.Compute key: capability:virtual_compute##virtual_memory##vdu_memory_requirements - schema: vduCpuRequirements + schema: vduMemRequirements - type: tosca.nodes.nfv.Vdu.VirtualStorage key: vdu_storage_requirements schema: vduStorageRequirements - type: tosca.nodes.nfv.VduCp - key: virtual_network_interface_requirements[]##network_interface_requirements##logical_node_requirements + key: virtual_network_interface_requirements##network_interface_requirements schema: networkInterfaceRequirements - type: tosca.nodes.nfv.VduCp - key: virtual_network_interface_requirements[]##nic_io_requirements##logical_node_requirements + key: virtual_network_interface_requirements##nic_io_requirements##logical_node_requirements schema: logicalNodeIoRequirements diff --git a/vnfsdk_pkgtools/validator/toscaparser_validator.py b/vnfsdk_pkgtools/validator/toscaparser_validator.py index d1aad30..dfe44b8 100644 --- a/vnfsdk_pkgtools/validator/toscaparser_validator.py +++ b/vnfsdk_pkgtools/validator/toscaparser_validator.py @@ -13,9 +13,12 @@ # under the License. # +import functools +import json import logging import os import pkg_resources +import re from toscaparser.common.exception import ValidationError from toscaparser.tosca_template import ToscaTemplate @@ -30,6 +33,10 @@ class HpaSchemaDefError(ValueError): pass +class HpaValueError(ValueError): + pass + + class ToscaparserValidator(validator.ValidatorBase): def __init__(self): super(ToscaparserValidator, self).__init__() @@ -66,5 +73,95 @@ class ToscaparserValidator(validator.ValidatorBase): except ValidationError as e: LOG.error(e.message) raise e + self.validate_hpa() + + def is_type(self, node, tosca_type): + if node is None: + return False + elif node.type == tosca_type: + return True + else: + return self.is_type(node.parent_type, tosca_type) + + def extract_value(self, node, key): + if node is None: + return None + + (cur_key, _, pending) = key.partition('##') + + prefix = None + prop = cur_key + if ':' in cur_key: + (prefix, prop) = cur_key.split(':', 1) + if prefix == 'capability': + getter = getattr(node, 'get_capability', None) + if not getter: + raise HpaSchemaDefError("not find capability %s" % prop) + elif prefix == 'property' or prefix is None: + getter = getattr(node, 'get_property_value', None) + if not getter and isinstance(node, dict): + getter = getattr(node, 'get') + else: + raise HpaSchemaDefError("unknown prefix in mapping " + "key %s" % cur_key) + value = getter(prop) + + if not pending: + return value + elif isinstance(value, list): + return list(map(functools.partial(self.extract_value, + key=pending), + value)) + else: + return self.extract_value(value, pending) + + @staticmethod + def validate_value(refkey, hpa_schema, value): + if value is None: + return + if not isinstance(value, dict): + msg = "node %s: value %s is not a map of string" + raise HpaValueError(msg % (refkey, value)) + for (key, hpa_value) in value.iteritems(): + if key not in hpa_schema: + msg = "node %s: %s is NOT a valid HPA key" + raise HpaValueError(msg % (refkey, key)) + try: + hpa_dict = json.loads(hpa_value) + except: + msg = "node %s, HPA key %s: %s is NOT a valid json encoded string" + raise HpaValueError(msg % (refkey, key, hpa_value.encode('ascii', 'replace'))) + if not isinstance(hpa_dict, dict): + msg = "node %s, HPA key %s: %s is NOT a valid json encoded string of dict" + raise HpaValueError(msg % (refkey, key, hpa_value.encode('ascii', 'replace'))) + for (attr, val) in hpa_dict.iteritems(): + if attr not in hpa_schema[key]: + msg = "node %s, HPA key %s: %s is NOT valid HPA attribute" + raise HpaValueError(msg % (refkey, key, attr)) + attr_schema = hpa_schema[key][attr] + if not re.match(attr_schema, str(val)): + msg = ("node %s, HPA key %s, attr %s: %s is not a valid HPA " + "attr value, expected re pattern is %s") + raise HpaValueError(msg % (refkey, key, attr, val.encode('ascii','replace'), attr_schema)) + + def validate_hpa_value(self, refkey, hpa_schema, values): + if isinstance(values, list): + for value in values: + self.validate_value(refkey, hpa_schema, value) + elif isinstance(values, dict): + self.validate_value(refkey, hpa_schema, values) + + def validate_hpa(self): + for node in getattr(self.tosca, 'nodetemplates', []): + for mapping in self.hpa_mappings: + if self.is_type(node, mapping['type']): + value = self.extract_value(node, mapping['key']) + if value: + refkey = node.name + '->' + mapping['key'] + LOG.debug("Checking HPA values %s of node %s " + "against schema %s", value, refkey, mapping['schema']) + self.validate_hpa_value(refkey, + self.hpa_schemas[mapping['schema']], + value) + - print self.tosca -- 2.16.6