From bcbbede4b0b94afd06217f7fd44ae8f1be71509d Mon Sep 17 00:00:00 2001 From: Andreas Geissler Date: Fri, 15 Nov 2024 10:46:36 +0100 Subject: [PATCH 01/16] Fix SDNC url path (param) in dd.json and CBAs Fixes the CDS workflow calls on SDNC Issue-ID: TEST-404 Change-Id: I73c6ee2fdb3e431f5da61cc79bdee6ce64e185e4 Signed-off-by: Andreas Geissler --- .../templates/artifacts/basic_cnf_cba_enriched.zip | Bin 65149 -> 65150 bytes .../templates/artifacts/basic_vm_cba_enriched.zip | Bin 10584 -> 10585 bytes src/onaptests/templates/artifacts/dd.json | 132 ++++++++++----------- 3 files changed, 66 insertions(+), 66 deletions(-) diff --git a/src/onaptests/templates/artifacts/basic_cnf_cba_enriched.zip b/src/onaptests/templates/artifacts/basic_cnf_cba_enriched.zip index 607146aedd27e77a0a5ecff94ecd495d661e3b9d..3dda66947d0aac7f773931670477b61c63003639 100644 GIT binary patch delta 2484 zcmZ9MdrVVz6vumSh01eP0pTZHyP9<|Y`}?C25?H9(Vx7^E@(|&51d|(fcI_=9hB-tVQfsfBf zy>|avC^sa?+6sf)hIpBsBNegd#jIhid=&RcjihG%iyAbpZz)6r^vM+nE+=ncDUO|o zd}LMhP@EErkzb{FSmf2z8|-Y3rf=Y-FlfwpMo6f?3OVa zpDnZXP-@DMV(oWKMXc)f>?UToawdZmX`~!+s;eD3-)sm+g>L5>{r@Xv4)yEK9`B}Tnuj96*e^t$F{o6TM@o*F%Sw%= ztRR)fa-uF@`Xtbx>V84}t3d@lh6qLL1O0?s3Y=pd7NiZC9E95eW=9NqFF6wVg!NGD zh=Nn=m&n|a5H}!jZ^8b7wdkc1wgIB<*`|WoZ7(SNzD~j&fajfY=%puC;uN@gsB;?8 zOPlU<3hIy)6~w26D4O0nNVwPF;GiC(X~nMxi8?=31(wuR=%?BNLxMUqT?H?tD~CKg zMAT^+)E^Glhe9!@c_@+Z%z)zIa0txw!@{(o-T!J~$`#D51M@I@ue8YT!vY7QHx@cF zm&v4Pj=)>8M7bC+nlxJP?PSb=;&wz`ZGuXtlK$qBhoy|=*Z`ez-w5H~FfE7$gKZ=P zYf*ep#H|Mq8y~V(C_eU(@E_)QannN`W=fOU-dq&GI7u(g6TD-Jr#I=s~4wPmnm+i z(Z%Y~XMNly@bB70WPqDCEe=6j zaf;|*tB9h(Hm!liR<cRU%GOlsoJexchL<{R(<%Y@eHOTfyU2eqQ#@ v67|V06};cYJ}>kfnq~#g0)Nh~z}uj626_bUHpF^XqjI)K=lgdz-LL-uCG5(b delta 2533 zcmZvcc}yI26vuaFpc^g=LL2z8j3ZDf3jxX%A&OkFy2^?yTc|{V5Fw>2=Y}fj2!dk@X~5J3(J)xKbD$-0 zJ6twNOSYNzobf^y+H#~c8K0eV!(_OtKbFW-B?1T?`i1yUhwx#eXq$V6gQZ47hvGmv zT1+Hy?ElxJX;?5ds>K3x!h_?IVR{&XR|_}Cc4fC|U_2hD@Uk4BFl?UTAnDQTB827{ z74$rMO=i1Hkeq{>iBy7fFg}qkvo(_%!dAKPLwV9MX1$YdlB3C2^976538JQ0Ra2-! zp)0C7Rbi}-)MtArl#Pb=Lh-c_16!uppg)Mf)8$6PsWL}=#?J$V;=J0IWt~Edms$al zYCJ`JK@Lt#BPtatr`2SWaC@3%;-VE$5TSzdXfGLyoMEXF(9VPt-bBWdtbpC*K*Gm? z(uycO1X?2quL`QIEY%4e)=0u@Uw9zntx>=+jgRa&l4lW>2YItE5z!ocKZ}?Gtpb{~ z!GvE0?lzY8$%LymKhR_z!l=-eNNM4UZGTB8nCAr}S6r{OqeKDTGQf>Vg!UW(1G zco~xPWFs78JVEsPdI9~U_aSO=@Q_CXCj=Drlx%~8(x-_2G*>{D+~*0ER6SW%y``8B zPW``rIk+&7C@1Ke&m;115V(M7wv<<;K~t$8M%@dE^v%u(<>(v6vG0OMmHjn&j1r)F>N4d+0zFsGwgY}1T zlAR@2Dxe#7&chC zp^HbM(A(wtpLS+>d~%S-L9jQdgswsI7OLQbO_u&$#6g5w1y&w44PoV-A(aeQY_asK z!x;a%CC8gQHjH3w9wE2Zu~SXYSSDgr0o|j%j{CW8CFhBM-JT)loDlGetaQ;f%RIO* z2;s{1iv;6fY8z2Wu(vILS>E13jA2Xxtz+cN;%MW>4ojVZz8!!3LM`niQh!1C?h%|h Ncb7YG&tjkHe*kCH;~)S4 diff --git a/src/onaptests/templates/artifacts/basic_vm_cba_enriched.zip b/src/onaptests/templates/artifacts/basic_vm_cba_enriched.zip index fa87e43ac5f8d7b3f62de13453a39840499be34c..d606cb9260cf5fb8f5e02c3bcf3dcc80555d8e49 100644 GIT binary patch delta 1732 zcmcZ+bTepzG5cXL^Yp!9=9769)FvkAunUNTxf>_*Fu~Z9moeRiu{U=yn=!&U$5|ZN zVVueQJT)-(=1DvzEX*3A`IAoyIM&+$jfCOS3T_5QmY2*73}E8zjQIRp1_B4}|JGcy zqMs!~ezjq5Y2;BaZ`YSgver)UV67-bA+xf@|+zX@M!nu^WUGR zw?9{A(5dGX&yYH#y6J#sg_v{Fgu|@faov}ui9DSpCAe^g!l}n^>s^vAIGo!->U4et!!Rmp*=-bB*<=pyyJ#S%)yC53iJ;?0Ng>Y5ScS4?A{sOpTfPS^SvD^C02quZwmR+Rx@+V|=k{ zv$MU*#dV!a{fg}Z+-*xZLA2Pd!2 zJQls`rPiG1w{9jo?$gtX?&OzK()beaB5hsW`p6XPkIhExeLvp4T_KvcHbG!v)pm|2 z{VU_z9k`~?&2yL1@S4q1vsW^9<)RL@Z)JTd#%q*ciIkn2tDSCRvHAG9voFeOp53Vb z`}$z!w&-go<*JU)`up6;dak=mldApRWXZ`-DwQ`{s#zT9wy5!(RcN6wT?byQB8(!-^`+bqt~3NH7nU7(V{TGPh{1t`h-Pys*SRL2Pu8Ho7wRrWLebVuBN6o ziO|g8ybv8;TOM0JU;eGPc%8r0Y8dYj_ssHIdPcZ6io4)U%niRiUP&i!CHGWvtGvH# zvLp4)mFe-uKYR>kC@O@6?`yv|%g+3e5SwlRW2bz>cmFp}mPnf~@+&rZ<0>Q3^=;PM zq?>CL&FbsiI?|*|+s@r&aad^HuIHb>=E3QT5>7kb{JF0`KFBiKD^pw6_TakmqKwrV zT-}`^U*4@Pf19_vI)7#9a`xbr#?oJ_W%r3ppZae7w4Z7{N@_}pJi)?euCrfmWjXif zK)7_M@TsPx%@a=fZ8!h?r{m}1jNjATj`J!cKRPj|yP=D>{-n(TRn7}L>gT5KmN}R6 z`ReCa4_n{vdwX(i!%uxV*RZpZGgo$9E?RyuI?m~q)zMpv|Aw0GzwX7m-aP7iX=tcb zMR;*_=U$B!)`g;#KUJ=BO3N;kI$ZyjLHD@j4BzLBF^N&X<#QsJ3gzzI6M10kwr7)1 z))>itnd}+-_1WT;>%>!ik9_-;bL-h2CSlE$1}>6$ZGDS6726b#C3XgWc)6dw^;V^k z-S1Be|LvN1+N9@4Gk0573MlR}{AOsoP83lVMIK1FBRG0e!3a)=bTphZ`GLgS$=7A$ z;AYs!okF%C046axMd3f(;*ClQle-k1;Bp}TXGJd*eu|PC5VTxiE1F(4KZhfDj(yV$@^8skZe$x z{0FGxi5SBqaXlmr3X}8Hq?jj3Fic)2p^YMb7byNf5+p7*SwLMBMb1ZEirG<`VREdr z3X1p^bt%Thlh3QGp@_<8NHM>b1zIdQSwRljAh@rYFUm7aek(7D;@;OlZE^|>ldTk# db)gkdI$BK;;LXa$00bgHsKmj*pr{Dq0RYX4vLOHf delta 1741 zcmcZ^bR%ejF?(*jNqTm?$z(nSwTTHj>^=p?AnwM=JWMe5{yy2Qht{g{Bwu+W z*7(Qp>T5xdhl{Si_hfcm>2cut?2A*ix-v8JpLrM^u3F@m`2Nh!qGN}HtKZz|$veKh zuikctoLu_u)V*&WJ_*?TKPF@O=MIkzPo6&sIHppmr($-TrM+UGSNtVeg+7hRTt)7) z_@?Z1zT&&ru2^mM50R}k6aFvz=ymD3N3T;@s$1xVE(uZP!`z3v_kLOwbF)os>$}O7 zw>w2u%9ba|$!Zk^P8FH@F>FCVE{{5o`nOY^L7~$1J|WfqX}RHEEsf^A0`pIWWJd%B zT@YBTmwUQ**3yOT3y<%6xiD;ZV#hxIRJL*@Pv?~(m5TyjGxW`5-`yGRsS{b=WB9(| zN$o7Q?Ok)9eadE^&&j68F3xw^^u_1TvHtkl zp>a#2>rj%CsQUM7yYu$n-oO3IuFK6UFU?&0YcFSf*J-cs*H7=^SlrR+A#wN$%jd5L zzbG{339w}?&T@(j$`KE``LfLLe7|VDNbdcMFDevMd}L-C3kGadte?rgLqSoBf8FPt z@WV56_tnMO?%8m6yX{U;oO0YL0ijm0;qWbWXV4J8oBa#NS$-l%*;gV+JOAv+0LkV{TM_(!! z!ReHahI1xAlz2P&hHM<%3|qNV$QA^^BqpaS{D)iYuck1$ThR$F2jYKG^g`jMD!HNX zFDap_w^nvRkzc0lfW(*K1QvIZkT4Qb@#ID-^d{$P=KrJ-9x9H7n+c5)6~qOK2mBDNMenCdGVT5+p7*Sy)OG zMb1}UirGP$VRD?b3X1qvbt%S0lP{>Np@_X1=%V&IamW>641xY7vvcxzmu0l napfDJdRYaA$<_+Wy3m>ky~+siW@Q5fqzDiyaWF6_D1vwZPLa6O diff --git a/src/onaptests/templates/artifacts/dd.json b/src/onaptests/templates/artifacts/dd.json index dabb9d8..9ac1f79 100644 --- a/src/onaptests/templates/artifacts/dd.json +++ b/src/onaptests/templates/artifacts/dd.json @@ -30,7 +30,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_int_pktgen_private_ip_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vpg_int_pktgen_private_ip_0", "verb": "GET" }, "type": "source-rest" @@ -102,7 +102,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_int_private1_ip_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vpg_int_private1_ip_0", "verb": "GET" }, "type": "source-rest" @@ -193,7 +193,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_onap_private_ip_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vpg_onap_private_ip_0", "verb": "GET" }, "type": "source-rest" @@ -250,7 +250,7 @@ "path": "", "payload": "{\n\"GENERIC-RESOURCE-API:param\": [\n{\n\"GENERIC-RESOURCE-API:name\": \"vdns_vf_module_id\",\n\"GENERIC-RESOURCE-API:value\": \"$vf-module-id\"\n}\n]\n}", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_vf_module_id", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vdns_vf_module_id", "verb": "PUT" }, "type": "source-rest" @@ -322,7 +322,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_onap_private_ip_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vpg_onap_private_ip_0", "verb": "GET" }, "type": "source-rest" @@ -368,7 +368,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_name_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vdns_name_0", "verb": "GET" }, "type": "source-rest" @@ -414,7 +414,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vfw_name_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vfw_name_0", "verb": "GET" }, "type": "source-rest" @@ -460,7 +460,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_int_private_ip_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_int_private_ip_0", "verb": "GET" }, "type": "source-rest" @@ -506,7 +506,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/dcae_collector_ip", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=dcae_collector_ip", "verb": "GET" }, "type": "source-rest" @@ -552,7 +552,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vfw_int_private2_ip_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vfw_int_private2_ip_0", "verb": "GET" }, "type": "source-rest" @@ -598,7 +598,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vfw_onap_private_ip_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vfw_onap_private_ip_0", "verb": "GET" }, "type": "source-rest" @@ -644,7 +644,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vfw_int_private1_ip_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vfw_int_private1_ip_0", "verb": "GET" }, "type": "source-rest" @@ -690,7 +690,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vfw_int_private2_floating_ip", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vfw_int_private2_floating_ip", "verb": "GET" }, "type": "source-rest" @@ -736,7 +736,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vsn_int_private2_ip_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vsn_int_private2_ip_0", "verb": "GET" }, "type": "source-rest" @@ -782,7 +782,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vsn_onap_private_ip_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vsn_onap_private_ip_0", "verb": "GET" }, "type": "source-rest" @@ -828,7 +828,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/dcae_collector_port", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=dcae_collector_port", "verb": "GET" }, "type": "source-rest" @@ -874,7 +874,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/demo_artifacts_version", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=demo_artifacts_version", "verb": "GET" }, "type": "source-rest" @@ -920,7 +920,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/install_script_version", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=install_script_version", "verb": "GET" }, "type": "source-rest" @@ -966,7 +966,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/int_pktgen_private_net_id", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=int_pktgen_private_net_id", "verb": "GET" }, "type": "source-rest" @@ -1012,7 +1012,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/int_pktgen_private_subnet_id", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=int_pktgen_private_subnet_id", "verb": "GET" }, "type": "source-rest" @@ -1058,7 +1058,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/int_private_net_id", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=int_private_net_id", "verb": "GET" }, "type": "source-rest" @@ -1104,7 +1104,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/int_private_subnet_id", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=int_private_subnet_id", "verb": "GET" }, "type": "source-rest" @@ -1150,7 +1150,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/keypair", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=keypair", "verb": "GET" }, "type": "source-rest" @@ -1196,7 +1196,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/nb_api_version", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=nb_api_version", "verb": "GET" }, "type": "source-rest" @@ -1242,7 +1242,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/nexus_artifact_repo", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=nexus_artifact_repo", "verb": "GET" }, "type": "source-rest" @@ -1288,7 +1288,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/onap_private_net_id", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=onap_private_net_id", "verb": "GET" }, "type": "source-rest" @@ -1334,7 +1334,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/onap_private_subnet_id", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=onap_private_subnet_id", "verb": "GET" }, "type": "source-rest" @@ -1380,7 +1380,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/pub_key", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=pub_key", "verb": "GET" }, "type": "source-rest" @@ -1426,7 +1426,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/public_net_id", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=public_net_id", "verb": "GET" }, "type": "source-rest" @@ -1472,7 +1472,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/sec_group", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=sec_group", "verb": "GET" }, "type": "source-rest" @@ -1518,7 +1518,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_flavor_name", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vdns_flavor_name", "verb": "GET" }, "type": "source-rest" @@ -1564,7 +1564,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/flavor_name", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=flavor_name", "verb": "GET" }, "type": "source-rest" @@ -1610,7 +1610,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_image_name", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vdns_image_name", "verb": "GET" }, "type": "source-rest" @@ -1697,7 +1697,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_vf_module_id", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vdns_vf_module_id", "verb": "GET" }, "type": "source-rest" @@ -1756,7 +1756,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vf-naming-policy", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vf-naming-policy", "verb": "GET" }, "type": "source-rest" @@ -1802,7 +1802,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_0_int_pktgen_private_port_0_mac", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_0_int_pktgen_private_port_0_mac", "verb": "GET" }, "type": "source-rest" @@ -1848,7 +1848,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_flavor_name", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_flavor_name", "verb": "GET" }, "type": "source-rest" @@ -1894,7 +1894,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_image_name", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_image_name", "verb": "GET" }, "type": "source-rest" @@ -1940,7 +1940,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_private_net_id", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_private_net_id", "verb": "GET" }, "type": "source-rest" @@ -1986,7 +1986,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_flavor_name", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vpg_flavor_name", "verb": "GET" }, "type": "source-rest" @@ -2032,7 +2032,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_image_name", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vpg_image_name", "verb": "GET" }, "type": "source-rest" @@ -2078,7 +2078,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/image_name", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=image_name", "verb": "GET" }, "type": "source-rest" @@ -2124,7 +2124,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/gre_ipaddr", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=gre_ipaddr", "verb": "GET" }, "type": "source-rest" @@ -2170,7 +2170,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/pg_int", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=pg_int", "verb": "GET" }, "type": "source-rest" @@ -2218,7 +2218,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vf-modules/vf-module=$vdns_vf_module_id/vf-module-data/vf-module-topology/vf-module-parameters/param/vdns_int_private_ip_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vf-modules/vf-module=$vdns_vf_module_id/vf-module-data/vf-module-topology/vf-module-parameters/param=vdns_int_private_ip_0", "verb": "GET" }, "type": "source-rest" @@ -2266,7 +2266,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vf-modules/vf-module=$vdns_vf_module_id/vf-module-data/vf-module-topology/vf-module-parameters/param/vdns_onap_private_ip_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vf-modules/vf-module=$vdns_vf_module_id/vf-module-data/vf-module-topology/vf-module-parameters/param=vdns_onap_private_ip_0", "verb": "GET" }, "type": "source-rest" @@ -2312,7 +2312,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vip", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vip", "verb": "GET" }, "type": "source-rest" @@ -2358,7 +2358,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_int_pktgen_private_ip_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_int_pktgen_private_ip_0", "verb": "GET" }, "type": "source-rest" @@ -2404,7 +2404,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/pktgen_private_net_id", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=pktgen_private_net_id", "verb": "GET" }, "type": "source-rest" @@ -2450,7 +2450,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vnf-id", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vnf-id", "verb": "GET" }, "type": "source-rest" @@ -2496,7 +2496,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vnf_name", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vnf_name", "verb": "GET" }, "type": "source-rest" @@ -2542,7 +2542,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vnf_name", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vnf_name", "verb": "GET" }, "type": "source-rest" @@ -2672,7 +2672,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_name_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_name_0", "verb": "GET" }, "type": "source-rest" @@ -2718,7 +2718,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/key_name", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=key_name", "verb": "GET" }, "type": "source-rest" @@ -2764,7 +2764,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vsn_name_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vsn_name_0", "verb": "GET" }, "type": "source-rest" @@ -2810,7 +2810,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_name_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vpg_name_0", "verb": "GET" }, "type": "source-rest" @@ -3129,7 +3129,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/cloud_env", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=cloud_env", "verb": "GET" }, "type": "source-rest" @@ -3186,7 +3186,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/pktgen_private_net_cidr", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=pktgen_private_net_cidr", "verb": "GET" }, "type": "source-rest" @@ -3243,7 +3243,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/int_private2_net_cidr", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=int_private2_net_cidr", "verb": "GET" }, "type": "source-rest" @@ -3300,7 +3300,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/int_private1_net_cidr", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=int_private1_net_cidr", "verb": "GET" }, "type": "source-rest" @@ -3357,7 +3357,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/onap_private_net_cidr", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=onap_private_net_cidr", "verb": "GET" }, "type": "source-rest" @@ -3414,7 +3414,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_private_net_cidr", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_private_net_cidr", "verb": "GET" }, "type": "source-rest" @@ -3471,7 +3471,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/management-prefix-id", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=management-prefix-id", "verb": "GET" }, "type": "source-rest" @@ -3528,7 +3528,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/private1-prefix-id", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=private1-prefix-id", "verb": "GET" }, "type": "source-rest" @@ -3585,7 +3585,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/private2-prefix-id", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=private2-prefix-id", "verb": "GET" }, "type": "source-rest" @@ -3631,7 +3631,7 @@ }, "path": "/param/0/value", "type": "JSON", - "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_onap_private_ip_0", + "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_onap_private_ip_0", "verb": "GET" }, "type": "source-rest" -- 2.16.6 From 49037058457240084520f5dc8d0544c6351e67f8 Mon Sep 17 00:00:00 2001 From: Andreas Geissler Date: Fri, 15 Nov 2024 16:32:10 +0100 Subject: [PATCH 02/16] Fix SDNC return value mapping (param) in dd.json and CBAs Fixes the CDS workflow calls on SDNC Issue-ID: TEST-404 Change-Id: I3fdf68d4e464c84f283f7d27fc40b816b9e77a65 Signed-off-by: Andreas Geissler --- .../templates/artifacts/basic_cnf_cba_enriched.zip | Bin 65150 -> 65154 bytes .../templates/artifacts/basic_vm_cba_enriched.zip | Bin 10585 -> 10597 bytes src/onaptests/templates/artifacts/dd.json | 130 ++++++++++----------- 3 files changed, 65 insertions(+), 65 deletions(-) diff --git a/src/onaptests/templates/artifacts/basic_cnf_cba_enriched.zip b/src/onaptests/templates/artifacts/basic_cnf_cba_enriched.zip index 3dda66947d0aac7f773931670477b61c63003639..2671d767fc07c1bd37ebd38ad6bf7ad13cee2db3 100644 GIT binary patch delta 5565 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 delta 5584 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 T!@21q=>W$AYT}>cxWoB>VIx-q diff --git a/src/onaptests/templates/artifacts/basic_vm_cba_enriched.zip b/src/onaptests/templates/artifacts/basic_vm_cba_enriched.zip index d606cb9260cf5fb8f5e02c3bcf3dcc80555d8e49..7c26da8242ba8260010d1f0b19678b57c18dea53 100644 GIT binary patch delta 1591 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 a-4)a!h6;*G1n~fnUWE7n diff --git a/src/onaptests/templates/artifacts/dd.json b/src/onaptests/templates/artifacts/dd.json index 9ac1f79..cfd3488 100644 --- a/src/onaptests/templates/artifacts/dd.json +++ b/src/onaptests/templates/artifacts/dd.json @@ -28,7 +28,7 @@ "output-key-mapping": { "vpg_int_pktgen_private_ip_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vpg_int_pktgen_private_ip_0", "verb": "GET" @@ -100,7 +100,7 @@ "output-key-mapping": { "vpg_int_private1_ip_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vpg_int_private1_ip_0", "verb": "GET" @@ -191,7 +191,7 @@ "output-key-mapping": { "vpg_onap_private_ip_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vpg_onap_private_ip_0", "verb": "GET" @@ -320,7 +320,7 @@ "output-key-mapping": { "vpg_onap_private_ip_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vpg_onap_private_ip_0", "verb": "GET" @@ -366,7 +366,7 @@ "output-key-mapping": { "vdns_name_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vdns_name_0", "verb": "GET" @@ -412,7 +412,7 @@ "output-key-mapping": { "vfw_name_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vfw_name_0", "verb": "GET" @@ -458,7 +458,7 @@ "output-key-mapping": { "vlb_int_private_ip_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_int_private_ip_0", "verb": "GET" @@ -504,7 +504,7 @@ "output-key-mapping": { "dcae_collector_ip": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=dcae_collector_ip", "verb": "GET" @@ -550,7 +550,7 @@ "output-key-mapping": { "vfw_int_private2_ip_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vfw_int_private2_ip_0", "verb": "GET" @@ -596,7 +596,7 @@ "output-key-mapping": { "vfw_onap_private_ip_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vfw_onap_private_ip_0", "verb": "GET" @@ -642,7 +642,7 @@ "output-key-mapping": { "vfw_int_private1_ip_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vfw_int_private1_ip_0", "verb": "GET" @@ -688,7 +688,7 @@ "output-key-mapping": { "vfw_int_private2_floating_ip": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vfw_int_private2_floating_ip", "verb": "GET" @@ -734,7 +734,7 @@ "output-key-mapping": { "vsn_int_private2_ip_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vsn_int_private2_ip_0", "verb": "GET" @@ -780,7 +780,7 @@ "output-key-mapping": { "vsn_onap_private_ip_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vsn_onap_private_ip_0", "verb": "GET" @@ -826,7 +826,7 @@ "output-key-mapping": { "dcae_collector_port": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=dcae_collector_port", "verb": "GET" @@ -872,7 +872,7 @@ "output-key-mapping": { "demo_artifacts_version": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=demo_artifacts_version", "verb": "GET" @@ -918,7 +918,7 @@ "output-key-mapping": { "install_script_version": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=install_script_version", "verb": "GET" @@ -964,7 +964,7 @@ "output-key-mapping": { "int_pktgen_private_net_id": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=int_pktgen_private_net_id", "verb": "GET" @@ -1010,7 +1010,7 @@ "output-key-mapping": { "int_pktgen_private_subnet_id": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=int_pktgen_private_subnet_id", "verb": "GET" @@ -1056,7 +1056,7 @@ "output-key-mapping": { "int_private_net_id": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=int_private_net_id", "verb": "GET" @@ -1102,7 +1102,7 @@ "output-key-mapping": { "int_private_subnet_id": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=int_private_subnet_id", "verb": "GET" @@ -1148,7 +1148,7 @@ "output-key-mapping": { "keypair": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=keypair", "verb": "GET" @@ -1194,7 +1194,7 @@ "output-key-mapping": { "nb_api_version": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=nb_api_version", "verb": "GET" @@ -1240,7 +1240,7 @@ "output-key-mapping": { "nexus_artifact_repo": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=nexus_artifact_repo", "verb": "GET" @@ -1286,7 +1286,7 @@ "output-key-mapping": { "onap_private_net_id": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=onap_private_net_id", "verb": "GET" @@ -1332,7 +1332,7 @@ "output-key-mapping": { "onap_private_subnet_id": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=onap_private_subnet_id", "verb": "GET" @@ -1378,7 +1378,7 @@ "output-key-mapping": { "pub_key": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=pub_key", "verb": "GET" @@ -1424,7 +1424,7 @@ "output-key-mapping": { "public_net_id": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=public_net_id", "verb": "GET" @@ -1470,7 +1470,7 @@ "output-key-mapping": { "sec_group": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=sec_group", "verb": "GET" @@ -1516,7 +1516,7 @@ "output-key-mapping": { "vdns_flavor_name": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vdns_flavor_name", "verb": "GET" @@ -1562,7 +1562,7 @@ "output-key-mapping": { "flavor_name": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=flavor_name", "verb": "GET" @@ -1608,7 +1608,7 @@ "output-key-mapping": { "vdns_image_name": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vdns_image_name", "verb": "GET" @@ -1695,7 +1695,7 @@ "output-key-mapping": { "vdns_vf_module_id": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vdns_vf_module_id", "verb": "GET" @@ -1754,7 +1754,7 @@ "output-key-mapping": { "vf-naming-policy": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vf-naming-policy", "verb": "GET" @@ -1800,7 +1800,7 @@ "output-key-mapping": { "vlb_0_int_pktgen_private_port_0_mac": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_0_int_pktgen_private_port_0_mac", "verb": "GET" @@ -1846,7 +1846,7 @@ "output-key-mapping": { "vlb_flavor_name": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_flavor_name", "verb": "GET" @@ -1892,7 +1892,7 @@ "output-key-mapping": { "vlb_image_name": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_image_name", "verb": "GET" @@ -1938,7 +1938,7 @@ "output-key-mapping": { "vlb_private_net_id": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_private_net_id", "verb": "GET" @@ -1984,7 +1984,7 @@ "output-key-mapping": { "vpg_flavor_name": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vpg_flavor_name", "verb": "GET" @@ -2030,7 +2030,7 @@ "output-key-mapping": { "vpg_image_name": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vpg_image_name", "verb": "GET" @@ -2076,7 +2076,7 @@ "output-key-mapping": { "image_name": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=image_name", "verb": "GET" @@ -2122,7 +2122,7 @@ "output-key-mapping": { "gre_ipaddr": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=gre_ipaddr", "verb": "GET" @@ -2168,7 +2168,7 @@ "output-key-mapping": { "pg_int": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=pg_int", "verb": "GET" @@ -2216,7 +2216,7 @@ "output-key-mapping": { "vdns_int_private_ip_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vf-modules/vf-module=$vdns_vf_module_id/vf-module-data/vf-module-topology/vf-module-parameters/param=vdns_int_private_ip_0", "verb": "GET" @@ -2264,7 +2264,7 @@ "output-key-mapping": { "vdns_onap_private_ip_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vf-modules/vf-module=$vdns_vf_module_id/vf-module-data/vf-module-topology/vf-module-parameters/param=vdns_onap_private_ip_0", "verb": "GET" @@ -2310,7 +2310,7 @@ "output-key-mapping": { "vip": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vip", "verb": "GET" @@ -2356,7 +2356,7 @@ "output-key-mapping": { "vlb_int_pktgen_private_ip_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_int_pktgen_private_ip_0", "verb": "GET" @@ -2402,7 +2402,7 @@ "output-key-mapping": { "pktgen_private_net_id": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=pktgen_private_net_id", "verb": "GET" @@ -2448,7 +2448,7 @@ "output-key-mapping": { "vnf-id": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vnf-id", "verb": "GET" @@ -2494,7 +2494,7 @@ "output-key-mapping": { "vnf_name": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vnf_name", "verb": "GET" @@ -2540,7 +2540,7 @@ "output-key-mapping": { "vnf_name": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vnf_name", "verb": "GET" @@ -2670,7 +2670,7 @@ "output-key-mapping": { "vlb_name_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_name_0", "verb": "GET" @@ -2716,7 +2716,7 @@ "output-key-mapping": { "key_name": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=key_name", "verb": "GET" @@ -2762,7 +2762,7 @@ "output-key-mapping": { "vsn_name_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vsn_name_0", "verb": "GET" @@ -2808,7 +2808,7 @@ "output-key-mapping": { "vpg_name_0": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vpg_name_0", "verb": "GET" @@ -3127,7 +3127,7 @@ "output-key-mapping": { "cloud_env": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=cloud_env", "verb": "GET" @@ -3184,7 +3184,7 @@ "output-key-mapping": { "pktgen_private_net_cidr": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=pktgen_private_net_cidr", "verb": "GET" @@ -3241,7 +3241,7 @@ "output-key-mapping": { "int_private2_net_cidr": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=int_private2_net_cidr", "verb": "GET" @@ -3298,7 +3298,7 @@ "output-key-mapping": { "int_private1_net_cidr": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=int_private1_net_cidr", "verb": "GET" @@ -3355,7 +3355,7 @@ "output-key-mapping": { "onap_private_net_cidr": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=onap_private_net_cidr", "verb": "GET" @@ -3412,7 +3412,7 @@ "output-key-mapping": { "vlb_private_net_cidr": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_private_net_cidr", "verb": "GET" @@ -3469,7 +3469,7 @@ "output-key-mapping": { "management-prefix-id": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=management-prefix-id", "verb": "GET" @@ -3526,7 +3526,7 @@ "output-key-mapping": { "private1-prefix-id": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=private1-prefix-id", "verb": "GET" @@ -3583,7 +3583,7 @@ "output-key-mapping": { "private2-prefix-id": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=private2-prefix-id", "verb": "GET" @@ -3629,7 +3629,7 @@ "output-key-mapping": { "private2-prefix-id": "value" }, - "path": "/param/0/value", + "path": "/GENERIC-RESOURCE-API:param/0/value", "type": "JSON", "url-path": "/rests/data/GENERIC-RESOURCE-API:services/service=$service-instance-id/service-data/vnfs/vnf=$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param=vlb_onap_private_ip_0", "verb": "GET" -- 2.16.6 From 4b2596d7ee834cf78f37f9b82f21527e97307c4f Mon Sep 17 00:00:00 2001 From: Andreas Geissler Date: Mon, 20 Jan 2025 14:38:52 +0100 Subject: [PATCH 03/16] Change CDS DB url to jdbc://mariadb CDS DB library is updated from mysql to mariadb Issue-ID: TEST-404 Change-Id: I1167419efaa8f3d32649a105d887d02b9790516d Signed-off-by: Andreas Geissler --- .../cds-resource-resolution/resource-resolution.zip | Bin 6745 -> 7526 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/onaptests/templates/artifacts/cds-resource-resolution/resource-resolution.zip b/src/onaptests/templates/artifacts/cds-resource-resolution/resource-resolution.zip index a20fd9355d60c3187dad6a37efb6b99a9ef19847..e443470beec6edc90b3c7756aed73c520c0ec47d 100644 GIT binary patch delta 4231 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 -- 2.16.6 From de89f83b13a6980eeb1d5e359dde292680b3ece6 Mon Sep 17 00:00:00 2001 From: Andreas Geissler Date: Mon, 10 Mar 2025 15:28:14 +0100 Subject: [PATCH 04/16] Fix zip file for cds-resource-resolution File was wrongly zipped (including directory) Issue-ID: TEST-404 Change-Id: I1ab55939069faa655a02a93e26dab3f1cd2dd035 Signed-off-by: Andreas Geissler --- .../cds-resource-resolution/resource-resolution.zip | Bin 7526 -> 6742 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/onaptests/templates/artifacts/cds-resource-resolution/resource-resolution.zip b/src/onaptests/templates/artifacts/cds-resource-resolution/resource-resolution.zip index e443470beec6edc90b3c7756aed73c520c0ec47d..f42d4ea65b689cbbaf3c501dea84170267823407 100644 GIT binary patch delta 2399 zcmbuAUr1AN6vxkYr_N<=sW|5}Y1khV(_$I@5nD<`GBmeEgpik9w9;+4o0Tuqq9+BZ zALK(l2))%q)WX;3A*hi4JXA`1s35Hed#E%pgwF5&+5NNKskE`X4bJ)e&Y$n^oY{Tv z-R_Py#$*Bdy4p71$^Q@^7N`J!urJ!na=}=Az@HDywS)8Brxst`m?$j+F!LTyj+*X1 zM~_DafNJz0Z#PsCYjK`gG*1#&ak7Fjm7tB_@nZVJ>}~wF6FpplN40EiD0-l>egh+3 z7g}yM1JnxErNmijPkAIRl{6YuE{E%;CcWtLIUisfb-Cc&E}J*lSi>H@oULf?Z}+u$ z>byaY?O{1qo45hUvGQV*gK|d;os_$DXOK;jMB)7gJ**k6eW&|FQBGUPlHHk$PXm!W zqF1=Hk+3$9R0rHkJtw{x0VZ?BdOowH>N%5Guq+z0rYoItKEm~eGN1A;*5&hWbv>P9 z0Bjg9-?fP{{*<5NgX~PACigGnma-3roBg7O_^$%Yr8Rga6b^BrNLZ{u`^P`5LP~Qn z_sPCnyPBpjk$ZRqFQsPt76$8^a2UTD8zuTgV3Tji@%zX$c9?!_8v2gGP?Q(zXj47w zCBv4|xLD%-YJF#HigWKm_r=TWz+n1@$?^}y4bc#?sYL;buT0XpYqbaJ*|ca3#*K_# zMkosYWrJl8{lPak&Z{m*xV~$^SwV?Agt)Y;u_|a>Ggg$;5lU4I89iVQiW`8z_b>c@ zP5(ego1zqH!%IHpxKIn-W4_b=(1!q&CzX1(2|!dFJRWYvr!?tWRWa+r)MHNxJBLh! zRj(4Ho`^~iin%XC`Fghjs>Ik=}uhev-7T|L^t?ERrGUPn8uk%L9pYd1NFC1yw8)ySPo{*oKCKh$M8kAc;in_7-WLrmq$$5_;#yiqw$^ Xiv}5V(GX9iz0it!7(;D7q+!56tW)~t delta 2995 zcmb7_e{2(F7{{OMy4`gv>)emBDH>LAPD3HXW-bV9huQ$mps^*6No2RJo7J_OTSst- zVds#LXb^T0mZ$*&!9v)s) zE@|J-`+cA1z0Y0t&8*oF4CL9%0mtp_zE2I02fEji54kFr@+sCq4dbaMt-9^CJZ{-1KUq$!2x~AGeuDSia=-fCwBJQhhI8&QE zcCw|>w^xzROiso2ysu7Q+52l@yug2W@r2Xa=7BF951Yz1JRJG_$-(zRfznWEp!A|| ze^F=ft+=?QebaNJ9ct`BS=~fi=V-^d>1s!9V0dbL*?#}-k1N_ej#KwfjLq0j*8RBo z?C~A7`*w{uUzx36`FqP`)0#2)-t!07yDqyR7~qBBss|g#paB4PtoH?LadRNsmoE!} z{K2{}$~RRtJZX(5c%VD^wQJhe!V9s(tJh7~0B~Nm({kX>tF*d!UBV!SI{Kr1iFBJr zn(nk^+f=y;;J=th=KQ!<;6{HN*pX>^2?<=!;3;#3%bjGSvqy%c zNn|8zivG^q$qV6UJipu|t;Wgh-R6qf_io}%dd#h28n=DAV4j#SRBADip~pPR|6wCB zeRG{HH%L=(@}tKLZw9fNn%xi1-Si zLzTZ>0N?V3fO}X^*Fd!z6^Y%XV^}^*DrvO`6s?OKMiedmAoev{8sqUp9Qu`xl<3U2 z#^w6Qo=NU_&m9Z)rD-)MsRTh|hHF368 zv1wHpRyHTc!W->sPOdPPP>858c}CQami(_p*2!~-+MFD1Z8R?0nhsTNEw)}lA@0WH z8F#0XZ)cqr)HNL`vBzbNWy{+f8p~}IFdCc=RldNWQ=ik4Yd%j0&zwO-8x3skC~-Pe*-3 Date: Fri, 28 Mar 2025 13:38:33 +0100 Subject: [PATCH 05/16] [BASIC_CNF_MACRO] Fixed SDNC request paths Fixed the return path of new GENERIC-RESOURCE-API calls in basic_cnf_cba_enriched zip-file Issue-ID: TEST-404 Change-Id: I746fd5ef40f0d78e6b58cb885e959cba7e92d3ac Signed-off-by: Andreas Geissler --- .../templates/artifacts/basic_cnf_cba_enriched.zip | Bin 65154 -> 63641 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/onaptests/templates/artifacts/basic_cnf_cba_enriched.zip b/src/onaptests/templates/artifacts/basic_cnf_cba_enriched.zip index 2671d767fc07c1bd37ebd38ad6bf7ad13cee2db3..be5c4daae9ef50ea612b10343a8cf32d769e92a7 100644 GIT binary patch delta 10493 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 -- 2.16.6 From 42ec0fd131151883735554e169246925911beea2 Mon Sep 17 00:00:00 2001 From: Andreas Geissler Date: Tue, 22 Apr 2025 15:13:18 +0200 Subject: [PATCH 06/16] [TESTS] Add additional tests for testkube based testing - aai_initial_data_setup - add_delete_cnf_macro ... Issue-ID: TEST-404 Change-Id: Iaf1c26cd239782156dff2a002947aae687c5049e Signed-off-by: Andreas Geissler --- .gitignore | 4 + pylama.ini | 3 +- requirements.txt | 6 +- run_test.py | 2 +- setup.cfg | 31 +- setup.py | 3 +- .../aai_initial_data_setup_settings.py | 33 ++ .../configuration/add_delete_cnf_macro_settings.py | 4 + .../configuration/basic_cnf_macro_settings.py | 23 +- src/onaptests/configuration/basic_cps_settings.py | 1 + .../configuration/basic_kafka_settings.py | 13 + .../configuration/basic_onboard_settings.py | 1 + .../configuration/basic_policy_settings.py | 109 ++++++ src/onaptests/configuration/basic_prh_settings.py | 30 ++ .../configuration/basic_vm_macro_settings.py | 2 +- .../configuration/cba_enrichment_settings.py | 38 ++ .../configuration/cba_verification_settings.py | 69 ++++ .../cds_resource_resolution_settings.py | 15 +- .../configuration/check_time_sync_settings.py | 12 + .../configuration/generic_network_settings.py | 95 +++++ ...iate_pnf_without_registration_event_settings.py | 5 + ...nstantiate_service_without_resource_settings.py | 43 +++ .../configuration/modify_service_pnf_settings.py | 52 +++ .../configuration/pnf_with_ves_event_settings.py | 4 + src/onaptests/configuration/settings.py | 5 + src/onaptests/configuration/status_settings.py | 3 + .../configuration/ves_publish_settings.py | 15 + src/onaptests/scenario/aai_initial_data_setup.py | 79 ++++ src/onaptests/scenario/add_delete_cnf_macro.py | 17 + src/onaptests/scenario/add_pnf_in_running_svc.py | 98 +++++ src/onaptests/scenario/basic_cds.py | 6 +- src/onaptests/scenario/basic_cnf_macro.py | 17 +- src/onaptests/scenario/basic_kafka.py | 178 +++++++++ src/onaptests/scenario/basic_onboard.py | 12 +- src/onaptests/scenario/basic_policy.py | 11 + src/onaptests/scenario/basic_prh.py | 134 +++++++ src/onaptests/scenario/cba_verification.py | 55 +++ src/onaptests/scenario/check_time_sync.py | 224 +++++++++++ src/onaptests/scenario/generic_network.py | 82 +++++ .../scenario/instantiate_pnf_with_ves_event.py | 91 +++++ .../instantiate_pnf_without_registration_event.py | 92 +++++ .../instantiate_service_without_resource.py | 72 ++++ src/onaptests/scenario/modify_service_pnf.py | 93 +++++ src/onaptests/scenario/pnf_macro.py | 4 +- src/onaptests/scenario/publish_ves_event.py | 136 +++++++ .../steps/AAIInitialSetup/create_operations.py | 46 +++ .../steps/AAIInitialSetup/get_all_operations.py | 62 ++++ .../steps/AAIInitialSetup/get_operations.py | 49 +++ .../steps/AAIInitialSetup/update_operation_step.py | 32 ++ src/onaptests/steps/base.py | 72 +++- src/onaptests/steps/cloud/add_pnf.py | 52 +++ src/onaptests/steps/cloud/check_status.py | 295 ++++++++++++--- src/onaptests/steps/cloud/cloud_region_create.py | 17 +- src/onaptests/steps/cloud/cloud_region_upadte.py | 101 +++++ src/onaptests/steps/cloud/complex_create.py | 22 +- src/onaptests/steps/cloud/complex_update.py | 42 +++ ...connect_service_subscription_to_cloud_region.py | 3 +- src/onaptests/steps/cloud/customer_create.py | 22 +- .../cloud/customer_service_subscription_create.py | 23 +- src/onaptests/steps/cloud/customer_update.py | 36 ++ .../steps/cloud/expose_service_node_port.py | 8 +- src/onaptests/steps/cloud/lineofbusiness_create.py | 53 +++ src/onaptests/steps/cloud/link_cloud_to_complex.py | 24 +- .../steps/cloud/link_cloudregion_to_project.py | 70 ++++ .../steps/cloud/link_lineofbusiness_to_tenant.py | 74 ++++ .../steps/cloud/link_owningentity_to_tenant.py | 74 ++++ src/onaptests/steps/cloud/owning_entity_create.py | 53 +++ src/onaptests/steps/cloud/owning_entity_update.py | 35 ++ src/onaptests/steps/cloud/platform_create.py | 53 +++ src/onaptests/steps/cloud/project_create.py | 53 +++ .../steps/cloud/publish_pnf_reg_event_to_kafka.py | 57 +++ src/onaptests/steps/cloud/register_cloud.py | 31 +- src/onaptests/steps/cloud/resources.py | 47 ++- .../steps/cloud/service_subscription_update.py | 36 ++ src/onaptests/steps/cloud/tenant_create.py | 65 ++++ .../steps/instantiate/k8s_profile_create.py | 19 +- .../steps/instantiate/service_ala_carte.py | 12 +- src/onaptests/steps/instantiate/service_macro.py | 66 +++- .../steps/instantiate/so/add_cnf_in_service.py | 89 +++++ .../instantiate/so/add_delete_cnf_base_step.py | 62 ++++ .../steps/instantiate/so/add_pnf_in_service.py | 125 +++++++ .../steps/instantiate/so/delete_cnf_in_service.py | 77 ++++ .../steps/instantiate/so/delete_pnf_in_service.py | 107 ++++++ .../steps/instantiate/so/generic_network_step.py | 156 ++++++++ .../steps/instantiate/so/modify_pnf_in_service.py | 116 ++++++ src/onaptests/steps/onboard/cds.py | 4 +- src/onaptests/steps/onboard/cps.py | 46 ++- src/onaptests/steps/onboard/service.py | 409 ++++++++++++++------- src/onaptests/steps/onboard/verify_cba.py | 287 +++++++++++++++ src/onaptests/steps/onboard/vsp.py | 50 +++ src/onaptests/steps/policy/policy_operations.py | 141 +++++++ .../templates/artifacts/basic_cnf_cba_enriched.zip | Bin 63641 -> 63637 bytes .../templates/artifacts/cba_enriched_new.zip | Bin 0 -> 15744 bytes .../artifacts/cds-resource-resolution/dd.json | 12 +- .../resource-resolution.zip | Bin 6742 -> 6620 bytes .../artifacts/create_kafka_topic_template.json.j2 | 16 + .../templates/artifacts/ntp_checker_daemon.yml.j2 | 42 +++ .../templates/artifacts/pm_message_file.json | 228 ++++++++++++ .../artifacts/pm_message_negative_file.json | 228 ++++++++++++ .../artifacts/pnf_instantiation_ves_event.json.j2 | 50 +++ .../pnf_registration_dmaap_event_template.json.j2 | 55 +++ .../artifacts/pnf_registration_ves_event.json | 50 +++ .../templates/artifacts/ves_message_file.json | 40 ++ .../artifacts/ves_message_file_negative.json | 40 ++ .../slack-notifications/notifications.jinja | 124 +++++++ .../vnf-services/basic_cnf_macro-service.yaml.j2 | 1 + .../vnf-services/generic_network-service.yaml | 50 +++ .../instantiate_service_without_resource.yaml | 3 + .../templates/vnf-services/modify-service-pnf.yaml | 9 + .../templates/vnf-services/pnf-service.yaml.j2 | 4 - src/onaptests/utils/exceptions.py | 13 + src/onaptests/utils/gitlab.py | 115 ++++++ src/onaptests/utils/kubernetes.py | 16 +- src/onaptests/utils/kubernetes_kafka.py | 117 ++++++ src/onaptests/utils/ntp_checker.py | 35 ++ src/onaptests/utils/slack.py | 43 +++ tox.ini | 12 +- 117 files changed, 6420 insertions(+), 278 deletions(-) create mode 100644 src/onaptests/configuration/aai_initial_data_setup_settings.py create mode 100644 src/onaptests/configuration/add_delete_cnf_macro_settings.py create mode 100644 src/onaptests/configuration/basic_kafka_settings.py create mode 100644 src/onaptests/configuration/basic_policy_settings.py create mode 100644 src/onaptests/configuration/basic_prh_settings.py create mode 100644 src/onaptests/configuration/cba_verification_settings.py create mode 100644 src/onaptests/configuration/check_time_sync_settings.py create mode 100644 src/onaptests/configuration/generic_network_settings.py create mode 100644 src/onaptests/configuration/instantiate_pnf_without_registration_event_settings.py create mode 100644 src/onaptests/configuration/instantiate_service_without_resource_settings.py create mode 100644 src/onaptests/configuration/modify_service_pnf_settings.py create mode 100644 src/onaptests/configuration/pnf_with_ves_event_settings.py create mode 100644 src/onaptests/configuration/ves_publish_settings.py create mode 100644 src/onaptests/scenario/aai_initial_data_setup.py create mode 100644 src/onaptests/scenario/add_delete_cnf_macro.py create mode 100644 src/onaptests/scenario/add_pnf_in_running_svc.py create mode 100644 src/onaptests/scenario/basic_kafka.py create mode 100644 src/onaptests/scenario/basic_policy.py create mode 100644 src/onaptests/scenario/basic_prh.py create mode 100644 src/onaptests/scenario/cba_verification.py create mode 100644 src/onaptests/scenario/check_time_sync.py create mode 100644 src/onaptests/scenario/generic_network.py create mode 100644 src/onaptests/scenario/instantiate_pnf_with_ves_event.py create mode 100644 src/onaptests/scenario/instantiate_pnf_without_registration_event.py create mode 100644 src/onaptests/scenario/instantiate_service_without_resource.py create mode 100644 src/onaptests/scenario/modify_service_pnf.py create mode 100644 src/onaptests/scenario/publish_ves_event.py create mode 100644 src/onaptests/steps/AAIInitialSetup/create_operations.py create mode 100644 src/onaptests/steps/AAIInitialSetup/get_all_operations.py create mode 100644 src/onaptests/steps/AAIInitialSetup/get_operations.py create mode 100644 src/onaptests/steps/AAIInitialSetup/update_operation_step.py create mode 100644 src/onaptests/steps/cloud/add_pnf.py create mode 100644 src/onaptests/steps/cloud/cloud_region_upadte.py create mode 100644 src/onaptests/steps/cloud/complex_update.py create mode 100644 src/onaptests/steps/cloud/customer_update.py create mode 100644 src/onaptests/steps/cloud/lineofbusiness_create.py create mode 100644 src/onaptests/steps/cloud/link_cloudregion_to_project.py create mode 100644 src/onaptests/steps/cloud/link_lineofbusiness_to_tenant.py create mode 100644 src/onaptests/steps/cloud/link_owningentity_to_tenant.py create mode 100644 src/onaptests/steps/cloud/owning_entity_create.py create mode 100644 src/onaptests/steps/cloud/owning_entity_update.py create mode 100644 src/onaptests/steps/cloud/platform_create.py create mode 100644 src/onaptests/steps/cloud/project_create.py create mode 100644 src/onaptests/steps/cloud/publish_pnf_reg_event_to_kafka.py create mode 100644 src/onaptests/steps/cloud/service_subscription_update.py create mode 100644 src/onaptests/steps/cloud/tenant_create.py create mode 100644 src/onaptests/steps/instantiate/so/add_cnf_in_service.py create mode 100644 src/onaptests/steps/instantiate/so/add_delete_cnf_base_step.py create mode 100644 src/onaptests/steps/instantiate/so/add_pnf_in_service.py create mode 100644 src/onaptests/steps/instantiate/so/delete_cnf_in_service.py create mode 100644 src/onaptests/steps/instantiate/so/delete_pnf_in_service.py create mode 100644 src/onaptests/steps/instantiate/so/generic_network_step.py create mode 100644 src/onaptests/steps/instantiate/so/modify_pnf_in_service.py create mode 100644 src/onaptests/steps/onboard/verify_cba.py create mode 100644 src/onaptests/steps/policy/policy_operations.py create mode 100644 src/onaptests/templates/artifacts/cba_enriched_new.zip create mode 100644 src/onaptests/templates/artifacts/create_kafka_topic_template.json.j2 create mode 100644 src/onaptests/templates/artifacts/ntp_checker_daemon.yml.j2 create mode 100644 src/onaptests/templates/artifacts/pm_message_file.json create mode 100644 src/onaptests/templates/artifacts/pm_message_negative_file.json create mode 100644 src/onaptests/templates/artifacts/pnf_instantiation_ves_event.json.j2 create mode 100644 src/onaptests/templates/artifacts/pnf_registration_dmaap_event_template.json.j2 create mode 100644 src/onaptests/templates/artifacts/pnf_registration_ves_event.json create mode 100644 src/onaptests/templates/artifacts/ves_message_file.json create mode 100644 src/onaptests/templates/artifacts/ves_message_file_negative.json create mode 100644 src/onaptests/templates/slack-notifications/notifications.jinja create mode 100644 src/onaptests/templates/vnf-services/generic_network-service.yaml create mode 100644 src/onaptests/templates/vnf-services/instantiate_service_without_resource.yaml create mode 100644 src/onaptests/templates/vnf-services/modify-service-pnf.yaml create mode 100644 src/onaptests/utils/gitlab.py create mode 100644 src/onaptests/utils/kubernetes_kafka.py create mode 100644 src/onaptests/utils/ntp_checker.py create mode 100644 src/onaptests/utils/slack.py diff --git a/.gitignore b/.gitignore index 69cc86e..c07be43 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,7 @@ benchmark/ .tox/ **/__pycache__/ *.pyc +.vscode/launch.json + +.v* +.env \ No newline at end of file diff --git a/pylama.ini b/pylama.ini index aa7fdc5..2886656 100644 --- a/pylama.ini +++ b/pylama.ini @@ -25,7 +25,8 @@ disable = too-many-locals, too-many-statements, too-many-boolean-expressions, - too-many-positional-arguments + too-many-positional-arguments, + too-many-lines bad_functions = print load_plugins = diff --git a/requirements.txt b/requirements.txt index 632cb19..a3392cc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,10 +2,14 @@ cryptography==38.0.4 xtesting==0.91.0 avionix>=0.4.5 openstacksdk>=0.61.0 -onapsdk==13.2.0 +onapsdk==14.1.0 jinja2>3 kubernetes>=22.6.0 setuptools==65.3.0 natural==0.2.0 +slack-sdk==3.21.3 pg8000==1.30.1 mysql-connector-python==8.3.0 +pandas==2.2.1 +matplotlib==3.8.3 +grpcio-health-checking==1.71.0 diff --git a/run_test.py b/run_test.py index 7e5b410..0cd28c0 100644 --- a/run_test.py +++ b/run_test.py @@ -26,7 +26,7 @@ MODULES_TO_RELOAD = [ def get_entrypoints(): config = configparser.ConfigParser() config.read('setup.cfg') - entry_points = config['entry_points']['xtesting.testcase'] + entry_points = config['options.entry_points']['xtesting.testcase'] config = configparser.ConfigParser() config.read_string(f"[entry_points]\n{entry_points}") entry_points = config['entry_points'] diff --git a/setup.cfg b/setup.cfg index 8a75072..68fe394 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 [metadata] name = onaptests -version = 0.0.1 +version = 1.0.0 description = Test SDK to use ONAP Programatically long_description = file: README.md url = https://git.onap.org/testsuite/pythonsdk-tests @@ -21,8 +21,20 @@ packages=find_namespace: setup_requires = pytest-runner==5.2 install_requires = + cryptography==38.0.4 + xtesting==0.91.0 + avionix>=0.4.5 + openstacksdk>=0.61.0 + onapsdk==14.1.0 + jinja2>3 + kubernetes>=22.6.0 + setuptools==65.3.0 + natural==0.2.0 + slack-sdk==3.21.3 pg8000==1.30.1 mysql-connector-python==8.3.0 + pandas==2.2.1 + matplotlib==3.8.3 tests_require = mock pytest @@ -44,8 +56,9 @@ addopts = testpaths = tests -[entry_points] +[options.entry_points] xtesting.testcase = + check_time_sync = onaptests.scenario.check_time_sync:CheckTimeSync basic_vm = onaptests.scenario.basic_vm:BasicVm basic_vm_macro = onaptests.scenario.basic_vm_macro:BasicVmMacro basic_vm_macro_stability = onaptests.scenario.basic_vm_macro_stability:BasicVmMacroStability @@ -55,9 +68,23 @@ xtesting.testcase = clearwater_ims = onaptests.scenario.clearwater_ims:ClearwaterIms basic_onboard = onaptests.scenario.basic_onboard:BasicOnboard pnf_macro = onaptests.scenario.pnf_macro:PnfMacro + instantiate_pnf_without_registration_event = onaptests.scenario.instantiate_pnf_without_registration_event:InstantiatePnfWithoutRegistrationEvent + pnf_with_ves_event = onaptests.scenario.instantiate_pnf_with_ves_event:PnfWithVesEvent + add_pnf_in_running_service = onaptests.scenario.add_pnf_in_running_svc:AddPnfInRunningSvc cds_resource_resolution = onaptests.scenario.cds_resource_resolution:CDSResourceResolution multi_vnf_macro = onaptests.scenario.multi_vnf_macro:MultiVnfUbuntuMacro basic_cnf_macro = onaptests.scenario.basic_cnf_macro:BasicCnfMacro basic_cps = onaptests.scenario.basic_cps:BasicCps status = onaptests.scenario.status:Status basic_sdnc = onaptests.scenario.basic_sdnc:BasicSdnc + ves_publish = onaptests.scenario.publish_ves_event:VesCollectorTestCase + basic_kafka = onaptests.scenario.basic_kafka:KafkaTestCase + generic_network = onaptests.scenario.generic_network:GenericNetwork + cba_verification = onaptests.scenario.cba_verification:CbaVerification + basic_intent = onaptests.scenario.basic_intent:IntentScenario + instantiate_service_without_resource = onaptests.scenario.instantiate_service_without_resource:InstantiateServiceWithoutResource + aai_initial_data_setup = onaptests.scenario.aai_initial_data_setup:AAICrud + basic_prh = onaptests.scenario.basic_prh:PRHBase + modify_service_pnf = onaptests.scenario.modify_service_pnf:ModifyPnf + add_delete_cnf_macro = onaptests.scenario.add_delete_cnf_macro:AddDeleteCnfInRunningSvcScenario + basic_policy = onaptests.scenario.basic_policy:PolicyScenario diff --git a/setup.py b/setup.py index 8b44c49..d95c771 100644 --- a/setup.py +++ b/setup.py @@ -5,6 +5,5 @@ from setuptools import setup setup( - setup_requires=['pbr','setuptools'], - pbr=True + setup_requires=['setuptools'] ) diff --git a/src/onaptests/configuration/aai_initial_data_setup_settings.py b/src/onaptests/configuration/aai_initial_data_setup_settings.py new file mode 100644 index 0000000..ab7e908 --- /dev/null +++ b/src/onaptests/configuration/aai_initial_data_setup_settings.py @@ -0,0 +1,33 @@ +from .settings import * # noqa + +SERVICE_NAME = "AAI_Initial_Data_Setup" +SERVICE_DETAILS = "Verification of various AAI API endpoints" +GLOBAL_CUSTOMER_ID = "basiccnf-macro-customer" +SUBSCRIBER_NAME = "basiccnf-macro-customer" +SUBSCRIBER_TYPE = "INFRA" + +CLEANUP_FLAG = True + +OWNING_ENTITY_ID = "test_owning_entity" +OWNING_ENTITY_NAME = "test_owning_entity_name" +PLATFORM = "test_platform" +COMPLEX_PHYSICAL_LOCATION_ID = "test-lannion" +LINE_OF_BUSINESS = "test_lineofbusiness" +CLOUD_REGION_CLOUD_OWNER = "test_cloud_owner" # must not contain _ +CLOUD_REGION_ID = "test_cloud_region" +CLOUD_REGION_TYPE = "test-cloud-region-type" +CLOUD_REGION_VERSION = "test-cloud-region-version" +CLOUD_OWNER_DEFINED_TYPE = "test-cloud-owner-defined-type" +COMPLEX_DATA_CENTER_CODE = "test-complex-data-center-code" + +SERVICE_INSTANCE_ID = "test_service_instance_id" +TENANT_NAME = "test_tenant_name" +TENANT_ID = "test_tenant_id" + +# update entities +COMPLEX_DATA_CENTER_CODE = "updated_test-complex-data-center-code" +UPDATED_SUBSCRIBER_TYPE = "updated_subscriber_type" +UPDATED_CLOUD_OWNER_DEFINED_TYPE = "updated_cloud_owner_defined_type" +UPDATED_PHYSICAL_LOCATION_TYPE = "updated_physical_location_type" +UPDATED_CLOUD_TYPE = "updated_cloud_type" +UPDATED_OWNING_ENTITY_NAME = "updated_owning_entity_name" diff --git a/src/onaptests/configuration/add_delete_cnf_macro_settings.py b/src/onaptests/configuration/add_delete_cnf_macro_settings.py new file mode 100644 index 0000000..300a81b --- /dev/null +++ b/src/onaptests/configuration/add_delete_cnf_macro_settings.py @@ -0,0 +1,4 @@ +from .basic_cnf_macro_settings import * # noqa + +SERVICE_INSTANCE_NAME = "Add-Delete-Cnf-Macro" +CNF_INSTANCE_NAME = "cnf-macro-test-1" diff --git a/src/onaptests/configuration/basic_cnf_macro_settings.py b/src/onaptests/configuration/basic_cnf_macro_settings.py index d52f8bb..0ebd927 100644 --- a/src/onaptests/configuration/basic_cnf_macro_settings.py +++ b/src/onaptests/configuration/basic_cnf_macro_settings.py @@ -11,13 +11,14 @@ from .settings import * # noqa # Specific basic_cnf_macro with multicloud-k8s and yaml config scenario. SERVICE_DETAILS = ("Onboarding, distribution and instantiation of a Apache CNF " + - "using macro and native CNF path: cnf-adapter + K8sPlugin") + "using macro and native CNF path: cnf-adapter + K8sPlugin" + + "testing Onap Operator by create and check Service Instance Custom Resource.") CLEANUP_FLAG = True # CDS_DD_FILE = Path(get_resource_location("templates/artifacts/dd.json")) CDS_CBA_UNENRICHED = Path("no_such_file") -CDS_CBA_ENRICHED = Path(get_resource_location("templates/artifacts/basic_cnf_cba_enriched.zip")) +CDS_CBA_ENRICHED = get_resource_location("templates/artifacts/basic_cnf_cba_enriched.zip") # This scenario uses multicloud-k8s and not multicloud # (no registration requested) @@ -66,7 +67,7 @@ TENANT_NAME = 'dummy_test' SERVICE_YAML_TEMPLATE = Path(get_resource_location( "templates/vnf-services/basic_cnf_macro-service.yaml")) -generate_service_config_yaml_file(service_name="basic_cnf_macro", # noqa +generate_service_config_yaml_file(service_name="basic_cnf_macro_gnb", # noqa service_template="basic_cnf_macro-service.yaml.j2", service_config=SERVICE_YAML_TEMPLATE) @@ -81,3 +82,19 @@ except (FileNotFoundError, ValueError) as exc: SERVICE_INSTANCE_NAME = f"basic_cnf_macro_{str(uuid4())}" MODEL_YAML_TEMPLATE = None + +TEST_ONAP_OPERATOR = False +GROUP = 'onap.com' +VERSION = 'v1' +SERVICE_INSTANCE_PLURAL = 'serviceinstances' +SERVICE_INSTANCE_CR_NAME = 'cr-test-service-instance' +VNF_PLURAL = 'vnfs' +VNF_CR_NAME = 'cr-test-vnf' +VF_CR_NAME = 'cr-test-vf-lp-2' +MAX_RETRIES_OF_CR_CREATION = 20 +WAIT_FOR_CR = 10 +IN_CLUSTER = True +CLEANUP_FLAG = True +K8S_ADDITIONAL_RESOURCES_NAMESPACE = "onap" +VNF_MODULE_NAME = 'sim_cucp_vnf 0' +VF_MODULE_NAME = 'sim_cucp_vnf0..SimCucpVnf..helm_cucp..module-1' diff --git a/src/onaptests/configuration/basic_cps_settings.py b/src/onaptests/configuration/basic_cps_settings.py index cbf9d4c..6db5c94 100644 --- a/src/onaptests/configuration/basic_cps_settings.py +++ b/src/onaptests/configuration/basic_cps_settings.py @@ -73,4 +73,5 @@ DB_PRIMARY_HOST = "cps-core-pg-primary" DB_PORT = 5432 DB_LOGIN = "login" DB_PASSWORD = "password" +DB_USE_SSL_CONTEXT = False CHECK_POSTGRESQL = False diff --git a/src/onaptests/configuration/basic_kafka_settings.py b/src/onaptests/configuration/basic_kafka_settings.py new file mode 100644 index 0000000..25194a8 --- /dev/null +++ b/src/onaptests/configuration/basic_kafka_settings.py @@ -0,0 +1,13 @@ +from onaptests.configuration.settings import * # noqa + +SERVICE_NAME = "KafkaService" +SERVICE_DETAILS = ("Test Kafka functionality, " + "including dummy event publishing/consumption and topic management") +TOPIC_NAME = "kafka-testing" # If topic name is long please and needed delimiter add it as - only +EVENT_ID = "event121" +EVENT_NAME = "kafka testing event" +CLEANUP_FLAG = True + +KUBERNETES_API_GROUP = "kafka.strimzi.io" +KUBERNETES_API_VERSION = "v1beta2" +KUBERNETES_API_PLURAL = "kafkatopics" diff --git a/src/onaptests/configuration/basic_onboard_settings.py b/src/onaptests/configuration/basic_onboard_settings.py index bf4f40f..7df49f9 100644 --- a/src/onaptests/configuration/basic_onboard_settings.py +++ b/src/onaptests/configuration/basic_onboard_settings.py @@ -22,6 +22,7 @@ MODEL_YAML_TEMPLATE = None CLEANUP_FLAG = True SDC_CLEANUP = True VERIFY_DISTRIBUTION = True +SERVICE_DISTRIBUTION_ENABLED = True SERVICE_YAML_TEMPLATE = get_resource_location("templates/vnf-services/basic-onboard-service.yaml") generate_service_config_yaml_file(service_name="basic_onboard", # noqa diff --git a/src/onaptests/configuration/basic_policy_settings.py b/src/onaptests/configuration/basic_policy_settings.py new file mode 100644 index 0000000..489865a --- /dev/null +++ b/src/onaptests/configuration/basic_policy_settings.py @@ -0,0 +1,109 @@ +import json + +from .settings import * # noqa + +SERVICE_DETAILS = "Policy operations" +SERVICE_NAME = "POLICY" +STORE_POLICY = json.dumps({ + "tosca_definitions_version": "tosca_simple_yaml_1_1_0", + "topology_template": { + "inputs": {}, + "policies": [ + { + "onap.policy.test": { + "type": "onap.policies.native.ToscaXacml", + "type_version": "1.0.0", + "properties": { + "policies": [ + { + "properties": { + "description": "Policy that checks if NRCGI is" + " a specific value", + "rules": [ + { + "condition": { + "apply": { + "operator": "string-equal", + "keys": [ + "sliceData.node.cells.actual.nrcgi" + ], + "compareWith": { + "value": "448903300002" + } + } + }, + "decision": "Permit", + "advice": { + "value": "Cell ID is valid" + } + } + ], + "default": "Deny" + }, + "metadata": { + "policy-id": 1, + "policy-version": "1.0.0" + } + } + ] + }, + "name": "onap.policy.test", + "version": "1.0.0", + "metadata": { + "action": "policy-test", + "description": "Policy that checks if NRCGI is a specific value", + "policy-id": "onap.policy.test", + "policy-version": "1.0.0" + } + } + } + ] + }, + "name": "ToscaServiceTemplateSimple", + "version": "1.0.0" +}) + +DEPLOY_POLICY = json.dumps( + { + "policies": [ + { + "policy-id": "onap.policy.test", + "policy-version": "1.0.0" + } + ] + }) + +POLICY_ID = "onap.policy.test" +POLICY_VERSION = "1.0.0" + +DECISION_REQUEST = json.dumps( + { + "Request": { + "ReturnPolicyIdList": True, + "CombinedDecision": False, + "Action": [ + { + "Attribute": [ + { + "IncludeInResult": False, + "AttributeId": "action-id", + "Value": "policy-test" + } + ] + } + ], + "Resource": [ + { + "Attribute": [ + { + "IncludeInResult": False, + "AttributeId": "sliceData.node.cells.actual.nrcgi", + "Value": "448903300002" + } + ] + } + ] + } + }) + +CLEANUP_FLAG = True diff --git a/src/onaptests/configuration/basic_prh_settings.py b/src/onaptests/configuration/basic_prh_settings.py new file mode 100644 index 0000000..51a2d5e --- /dev/null +++ b/src/onaptests/configuration/basic_prh_settings.py @@ -0,0 +1,30 @@ +from onaptests.configuration.settings import * # noqa + +SERVICE_NAME = "PRHService" +SERVICE_DETAILS = "Validate PNF Registration process standalone" +PNF_REGISTRATION_TOPIC_NAME = "unauthenticated.VES_PNFREG_OUTPUT" +PNFREADY_TOPIC_NAME = "unauthenticated.PNF_READY" + +PNF_NAME = "dummy-ru-PRHTest" +PNF_ID = "321e0ee9-a1ca-4163-9240-4fd0a6992594" +PNF_ORCHESTRATION_STATUS = "Inventoried" +PNF_IN_MAINT = False +PNF_SPARE_EQUIPMENT_INDICATOR = False +PNF_NF_ROLE = "sdn controller" + +PNF_INSTANCE = { + "pnf-name": PNF_NAME, + "pnf-id": "321e0ee9-a1ca-4163-9240-4fd0a6992594", + "orchestration-status": "Inventoried", + "in-maint": False, + "spare-equipment-indicator": False, + "nf-role": "sdn controller" +} + +PNF_IPADDRESS_V4_OAM = "1.2.3.4" +PNF_IPADDRESS_V6_OAM = "0:0:0:0:0:ffff:a0a:011" +PNF_SERIAL_NUMBER = "ORAN_SIM-172.30.1.6-400600927-Simulated Device Melacon" + +MAX_ATTEMPTS_TO_CHECK = 5 +WAIT_TIME_SECONDS_BETWEEN_CHECK = 10 +CLEANUP_FLAG = True diff --git a/src/onaptests/configuration/basic_vm_macro_settings.py b/src/onaptests/configuration/basic_vm_macro_settings.py index 2f262f4..3781511 100644 --- a/src/onaptests/configuration/basic_vm_macro_settings.py +++ b/src/onaptests/configuration/basic_vm_macro_settings.py @@ -17,7 +17,7 @@ CLEANUP_FLAG = True CDS_DD_FILE = Path(get_resource_location("templates/artifacts/dd.json")) CDS_CBA_UNENRICHED = Path(get_resource_location("templates/artifacts/basic_vm_cba.zip")) -CDS_CBA_ENRICHED = Path("/tmp/BASIC_VM_enriched.zip") +CDS_CBA_ENRICHED = "/tmp/BASIC_VM_enriched.zip" ONLY_INSTANTIATE = False USE_MULTICLOUD = False diff --git a/src/onaptests/configuration/cba_enrichment_settings.py b/src/onaptests/configuration/cba_enrichment_settings.py index 72cf647..f287854 100644 --- a/src/onaptests/configuration/cba_enrichment_settings.py +++ b/src/onaptests/configuration/cba_enrichment_settings.py @@ -13,3 +13,41 @@ CLEANUP_FLAG = True CDS_DD_FILE = Path(get_resource_location("templates/artifacts/dd.json")) CDS_CBA_UNENRICHED = Path(get_resource_location("templates/artifacts/PNF_DEMO.zip")) CDS_CBA_ENRICHED = "/tmp/PNF_DEMO_enriched.zip" +CDS_WORKFLOW_NAME = "config-assign" +CDS_WORKFLOW_INPUT = { + "template-prefix": [ + "netconfrpc" + ], + "resolution-key": "day-1", + "config-assign-properties": { + "stream-count": 10 + } +} +CDS_WORKFLOW_EXPECTED_OUTPUT = { + "config-assign-response": { + "resolved-payload": { + "netconfrpc": + "\n " + + "\n \n \n \n \n " + + "\n" + + " \n \n fw_udp_1\n " + + " true\n \n " + + "\n fw_udp_2\n true\n" + + " \n \n fw_udp_3\n " + + " true\n \n " + + "\n fw_udp_4\n true\n" + + " \n \n fw_udp_5\n " + + " true\n \n " + + "\n fw_udp_6\n true\n" + + " \n \n fw_udp_7\n " + + " true\n \n " + + "\n fw_udp_8\n true\n" + + " \n \n fw_udp_9\n " + + " true\n \n " + + "\n fw_udp_10\n " + + "true\n" + + " \n \n \n " + + "\n \n\n" + } + } +} diff --git a/src/onaptests/configuration/cba_verification_settings.py b/src/onaptests/configuration/cba_verification_settings.py new file mode 100644 index 0000000..5205ec5 --- /dev/null +++ b/src/onaptests/configuration/cba_verification_settings.py @@ -0,0 +1,69 @@ +import os + +from .settings import * # noqa + +SERVICE_NAME = "CBA_VERIFICATION" +SERVICE_DETAILS = """Verify if CBAs are deployed and their content is same like in gitlab""" +CLEANUP_FLAG = True +LOCAL_PATH = "/tmp" +B2B_EQUINIX_POC_CBA = { + "name": "B2B_EQUINIX_POC_CBA", + "version": "1.0.0", + "gitlab_project_id": "210484", + "gitlab_repo_cba": "cba", + "enrichment": True, + "gitlab_branch": "master", +} +B2B_POC_CBA = { + "name": "B2B_POC_CBA", + "version": "1.0.0", + "gitlab_project_id": "176661", + "gitlab_repo_cba": "cba", + "enrichment": True, + "gitlab_branch": "develop", +} +INTENT_MGMT_CBA = { + "name": "INTENT-MGMT-CBA", + "version": "1.0.0", + "gitlab_project_id": "199504", + "gitlab_repo_cba": "Intent-Mgmt-CBA/INTENT-MGMT-CBA", + "enrichment": True, + "gitlab_branch": "develop", +} +CBA_GNB_SIM = { + "name": "CBA_GNB_SIM", + "version": "1.0.0", + "gitlab_project_id": "215376", + "gitlab_repo_cba": "gnb-simulator-with-ran-inventory/common-cba", + "enrichment": True, + "gitlab_branch": "main", +} +HUAWEI_EMS_CBA = { + "name": "SLICING_CBA", + "version": "1.1.0", + "gitlab_project_id": "124384", + "gitlab_repo_cba": "cba", + "enrichment": True, + "gitlab_branch": "develop", +} +CBA_LIST = [ + HUAWEI_EMS_CBA +] +test_env_name = os.getenv('TEST_ENV_NAME') +if test_env_name and 'b2b' in test_env_name: + CBA_LIST = [ + B2B_EQUINIX_POC_CBA, + B2B_POC_CBA, + INTENT_MGMT_CBA + ] + +ENRICHMENT_FILES = ['Definitions/data_types.json', + 'Definitions/node_types.json', + 'Definitions/resources_definition_types.json'] +IGNORE_FILES = ['Tests/', + 'pom.xml', + '.DS_Store', + 'Archive.zip', + 'CBA_GNB_SIM.zip'] +GITLAB_BASE_URL = "https://gitlab.devops.telekom.de/api/v4" +GITLAB_ACCESS_TKN = "glpat-nzqxs_HMQLYz7SrhxKi2" diff --git a/src/onaptests/configuration/cds_resource_resolution_settings.py b/src/onaptests/configuration/cds_resource_resolution_settings.py index 7b311a1..140cd27 100644 --- a/src/onaptests/configuration/cds_resource_resolution_settings.py +++ b/src/onaptests/configuration/cds_resource_resolution_settings.py @@ -63,7 +63,7 @@ CDS_DD_FILE = Path(get_resource_location( "templates/artifacts/cds-resource-resolution/dd.json")) CDS_CBA_UNENRICHED = Path(get_resource_location( "templates/artifacts/cds-resource-resolution/resource-resolution.zip")) -CDS_CBA_ENRICHED = Path("/tmp/resource-resolution-enriched.zip") +CDS_CBA_ENRICHED = "/tmp/resource-resolution-enriched.zip" CDS_WORKFLOW_NAME = "resource-resolution" CDS_WORKFLOW_INPUT = { "template-prefix": [ @@ -79,8 +79,17 @@ CDS_WORKFLOW_INPUT = { CDS_WORKFLOW_EXPECTED_OUTPUT = { "resource-resolution-response": { "meshed-template": { - "helloworld-velocity": "{\n \"default\": \"ok\",\n \"input\": \"ok\",\n \"script\": {\n \"python\": \"ok\",\n \"kotlin\": \"ok\"\n },\n \"db\": \"ok\",\n \"rest\": {\n \"GET\": \"A046E51D-44DC-43AE-BBA2-86FCA86C5265\",\n \"POST\": \"post:ok\",\n \"PUT\": \"put:ok\",\n \"PATCH\": \"patch:ok\",\n \"DELETE\": \"delete:ok\"\n }\n}\n", # noqa - "helloworld-jinja": "{\n \"default\": \"ok\",\n \"input\": \"ok\",\n \"script\": {\n \"python\": \"ok\",\n \"kotlin\": {\n \"base\": \"ok\"\n \"from suspend function\": \"ok\"\n }\n },\n \"db\": \"ok\",\n \"rest\": {\n \"GET\": \"A046E51D-44DC-43AE-BBA2-86FCA86C5265\",\n \"GET_ID\": \"74FE67C6-50F5-4557-B717-030D79903908\",\n \"POST\": \"post:ok\",\n \"PUT\": \"put:ok\",\n \"PATCH\": \"patch:ok\",\n \"DELETE\": \"delete:ok\"\n }\n}\n" # noqa + "helloworld-velocity": "{\n \"default\": \"ok\",\n \"input\": \"ok\",\n " + + "\"script\": {\n \"python\": \"ok\",\n \"kotlin\": \"ok\"\n },\n \"rest\": " + + "{\n \"GET\": \"${v_get}\",\n \"POST\": \"${v_post}\",\n" + + " \"PUT\": \"${v_put}\",\n \"PATCH\": \"${v_patch}\",\n " + + "\"DELETE\": \"${v_del}\"\n }\n}\n", + "helloworld-jinja": "{\n \"default\": \"ok\",\n \"input\": \"ok\",\n \"script\": " + + "{\n \"python\": \"ok\",\n \"kotlin\": {\n \"base\": \"ok\"\n " + + "\"from suspend function\": \"ok\"\n }\n },\n \"rest\": " + + "{\n \"GET\": \"${j_get}\",\n \"GET_ID\": \"${j_get_id}\",\n \"POST\": " + + "\"${j_post}\",\n \"PUT\": \"${j_put}\",\n \"PATCH\": \"${j_patch}\",\n " + + "\"DELETE\": \"${j_del}\"\n }\n}\n" } } } diff --git a/src/onaptests/configuration/check_time_sync_settings.py b/src/onaptests/configuration/check_time_sync_settings.py new file mode 100644 index 0000000..2eee7b7 --- /dev/null +++ b/src/onaptests/configuration/check_time_sync_settings.py @@ -0,0 +1,12 @@ +from .settings import * # noqa +from .settings import K8S_TESTS_NAMESPACE + +SERVICE_NAME = "Check Time Sync on Nodes" +SERVICE_DETAILS = "Check Time Sync on K8s Nodes" +DAEMON_NAME = "ntp-checker-test" +DAEMON_NS = K8S_TESTS_NAMESPACE +DAEMON_READY_WAIT_TIMOUT_SEC = 120 +DAEMON_DEPLOYMENT_RATIO = 0.7 +NODE_TIME_QUERIES_NUMBER = 5 +MAX_TIME_DIFF_MS = 5000 +CLEANUP_FLAG = True diff --git a/src/onaptests/configuration/generic_network_settings.py b/src/onaptests/configuration/generic_network_settings.py new file mode 100644 index 0000000..7440fe8 --- /dev/null +++ b/src/onaptests/configuration/generic_network_settings.py @@ -0,0 +1,95 @@ +import os +from pathlib import Path +from uuid import uuid4 + +from yaml import SafeLoader, load + +import onaptests.utils.exceptions as onap_test_exceptions +from onaptests.utils.resources import get_resource_location + +from .settings import * # noqa + +SERVICE_DETAILS = "Add Generic Network resource in service using macro" + + +# CDS_DD_FILE = Path(get_resource_location("templates/artifacts/dd.json")) +CDS_CBA_UNENRICHED = Path("no_such_file") +CDS_CBA_ENRICHED = get_resource_location("templates/artifacts/basic_cnf_cba_enriched.zip") + +# This scenario uses multicloud-k8s and not multicloud +# (no registration requested) +USE_MULTICLOUD = False +# Set ONLY_INSTANTIATE to true to run an instantiation without repeating +# onboarding and related AAI configuration (Cloud config) +ONLY_INSTANTIATE = False +EXPOSE_SERVICES_NODE_PORTS = False +CLEANUP_FLAG = True + +# Relative path to config file to set k8s connectivity information +K8S_CONFIG = get_resource_location("templates/artifacts/config") + +VENDOR_NAME = "g-network_macro_vendor" + +CLOUD_REGION_CLOUD_OWNER = "g-network-cloud-owner" # must not contain _ +CLOUD_REGION_ID = "k8sregion-g-network-macro" +CLOUD_REGION_TYPE = "k8s" +CLOUD_REGION_VERSION = "1.0" +CLOUD_DOMAIN = "Default" +CLOUD_OWNER_DEFINED_TYPE = "t1" + +COMPLEX_PHYSICAL_LOCATION_ID = "lannion" +COMPLEX_DATA_CENTER_CODE = "1234-5" +AVAILABILITY_ZONE_NAME = "g-network-availability-zone" +AVAILABILITY_ZONE_TYPE = "nova" + +GLOBAL_CUSTOMER_ID = "g-network-macro-customer" + +OWNING_ENTITY = "g-network-macro_owning_entity" +PROJECT = "g-network-macro_project" +LINE_OF_BUSINESS = "g-network-macro_lob" +PLATFORM = "g-network-macro_platform" + +# The cloud Part +# Assuming a cloud.yaml is available, use the openstack client +# to retrieve cloud info and avoid data duplication +# For basic_cnf, no tenant information is required but some dummy +# information shall be provided by default +# So it is not requested to set OS_TEST_CLOUD +TEST_CLOUD = os.getenv('OS_TEST_CLOUD') +VIM_USERNAME = 'dummy' +VIM_PASSWORD = 'dummy123' +VIM_SERVICE_URL = 'http://10.12.25.2:5000/v3' +TENANT_ID = '123456' +TENANT_NAME = 'dummy_test' + +TEST_ONAP_OPERATOR = False +GROUP = 'onap.com' +VERSION = 'v1' +SERVICE_INSTANCE_PLURAL = 'serviceinstances' +SERVICE_INSTANCE_CR_NAME = 'cr-test-service-instance' +VNF_PLURAL = 'vnfs' +VNF_CR_NAME = 'cr-test-vnf' +VF_CR_NAME = 'cr-test-vf-lp-2' +MAX_RETRIES_OF_CR_CREATION = 20 +WAIT_FOR_CR = 10 +IN_CLUSTER = True +K8S_ADDITIONAL_RESOURCES_NAMESPACE = "onap" +VNF_MODULE_NAME = 'sim_cucp_vnf 0' +VF_MODULE_NAME = 'sim_cucp_vnf0..SimCucpVnf..helm_cucp..module-1' + +SERVICE_YAML_TEMPLATE = Path(get_resource_location( + "templates/vnf-services/generic_network-service.yaml")) + +try: + # Try to retrieve the SERVICE NAME from the yaml file + with open(SERVICE_YAML_TEMPLATE, "r", encoding="utf-8") as yaml_template: + yaml_config_file = load(yaml_template, SafeLoader) + SERVICE_NAME = next(iter(yaml_config_file.keys())) +except (FileNotFoundError, ValueError) as exc: + raise onap_test_exceptions.TestConfigurationException from exc + +SERVICE_INSTANCE_NAME = f"basic_nw_{str(uuid4())}" + +MODEL_YAML_TEMPLATE = None + +REQUEST_TIMEOUT = 60 diff --git a/src/onaptests/configuration/instantiate_pnf_without_registration_event_settings.py b/src/onaptests/configuration/instantiate_pnf_without_registration_event_settings.py new file mode 100644 index 0000000..9e72cdd --- /dev/null +++ b/src/onaptests/configuration/instantiate_pnf_without_registration_event_settings.py @@ -0,0 +1,5 @@ +from .pnf_macro_settings import * # noqa + +SERVICE_INSTANCE_NAME = "Pnf-Macro-Without-Ves-Event" +PNF_WITHOUT_VES = True +PNF_WITH_VES = False diff --git a/src/onaptests/configuration/instantiate_service_without_resource_settings.py b/src/onaptests/configuration/instantiate_service_without_resource_settings.py new file mode 100644 index 0000000..f3dc570 --- /dev/null +++ b/src/onaptests/configuration/instantiate_service_without_resource_settings.py @@ -0,0 +1,43 @@ +from pathlib import Path +from uuid import uuid4 + +from yaml import SafeLoader, load + +import onaptests.utils.exceptions as onap_test_exceptions +from onaptests.utils.resources import get_resource_location + +from .settings import * # noqa + +CLEANUP_FLAG = True + +GLOBAL_CUSTOMER_ID = "pnf_macrocustomer" +OWNING_ENTITY = "test_owning_entity" +PROJECT = "basicnf_macro_project" +LINE_OF_BUSINESS = "basicnf_macro_lob" + +SERVICE_DETAILS = ("Onboarding, distribution and instantiation of service " + + "without resources using macro") + +CDS_CBA_UNENRICHED = Path("no_such_file") +CDS_CBA_ENRICHED = get_resource_location("templates/artifacts/cba_enriched_new.zip") +SERVICE_YAML_TEMPLATE = Path(get_resource_location( + "templates/vnf-services/instantiate_service_without_resource.yaml")) + +# This scenario uses multicloud-k8s and not multicloud +# (no registration requested) +USE_MULTICLOUD = False +# Set ONLY_INSTANTIATE to true to run an instantiation without repeating +# onboarding and related AAI configuration (Cloud config) +ONLY_INSTANTIATE = False +K8S_CONFIG = get_resource_location("templates/artifacts/config") + +try: + # Try to retrieve the SERVICE NAME from the yaml file + with open(SERVICE_YAML_TEMPLATE, "r", encoding="utf-8") as yaml_template: + yaml_config_file = load(yaml_template, SafeLoader) + SERVICE_NAME = next(iter(yaml_config_file.keys())) +except (FileNotFoundError, ValueError) as exc: + raise onap_test_exceptions.TestConfigurationException from exc + +SERVICE_INSTANCE_NAME = f"svc_without_res_{str(uuid4())}" +MODEL_YAML_TEMPLATE = None diff --git a/src/onaptests/configuration/modify_service_pnf_settings.py b/src/onaptests/configuration/modify_service_pnf_settings.py new file mode 100644 index 0000000..df09580 --- /dev/null +++ b/src/onaptests/configuration/modify_service_pnf_settings.py @@ -0,0 +1,52 @@ +from pathlib import Path +from uuid import uuid4 + +from yaml import SafeLoader, load + +import onaptests.utils.exceptions as onap_test_exceptions +from onaptests.utils.resources import get_resource_location + +from .settings import * # noqa + +ONLY_INSTANTIATE = False +CLEANUP_FLAG = True +USE_MULTICLOUD = False + +VENDOR_NAME = "pnf_macro_vendor" +SERVICE_NAME = "Modify_PNF_Test" +SERVICE_DETAILS = ("Onboarding, distribution and registration of PNF using macro " + + "after creation of empty service first") +SERVICE_YAML_TEMPLATE = Path(get_resource_location( + "templates/vnf-services/modify-service-pnf.yaml")) +SERVICE_INSTANCE_NAME = f"pnf-modify_{str(uuid4())}" + +try: + # Try to retrieve the SERVICE NAME from the yaml file + with open(SERVICE_YAML_TEMPLATE, "r", encoding="utf-8") as yaml_template: + yaml_config_file = load(yaml_template, SafeLoader) + SERVICE_NAME = next(iter(yaml_config_file.keys())) +except (FileNotFoundError, ValueError) as exc: + raise onap_test_exceptions.TestConfigurationException from exc + +PNF_WITHOUT_VES = True +PNF_WITH_VES = False +CDS_DD_FILE = Path(get_resource_location("templates/artifacts/dd.json")) +CDS_CBA_UNENRICHED = Path(get_resource_location("templates/artifacts/PNF_DEMO.zip")) +CDS_CBA_ENRICHED = "/tmp/cba_enriched_new.zip" + +GLOBAL_CUSTOMER_ID = "pnf_macrocustomer" +OWNING_ENTITY = "test_owning_entity" +PROJECT = "basicnf_macro_project" +LOB = "basicnf_macro_lob" +LINE_OF_BUSINESS = "basicnf_macro_lob" +PLATFORM = "basicnf_macro_platform" + +INSTANTIATION_TIMEOUT = 600 +K8S_CONFIG = get_resource_location("templates/artifacts/config") +PNF_WAIT_TIME = 60.0 +PNF_REGISTRATION_NUMBER_OF_TRIES = 30 +CLEANUP_ACTIVITY_TIMER = 10 +ORCHESTRATION_REQUEST_TIMEOUT = 60.0 * 15 # 15 minutes in seconds + +# Disable YAML SDC model definition which means all SDC config reside in SERVICE_YAML_TEMPLATE +MODEL_YAML_TEMPLATE = None diff --git a/src/onaptests/configuration/pnf_with_ves_event_settings.py b/src/onaptests/configuration/pnf_with_ves_event_settings.py new file mode 100644 index 0000000..4bab193 --- /dev/null +++ b/src/onaptests/configuration/pnf_with_ves_event_settings.py @@ -0,0 +1,4 @@ +from .pnf_macro_settings import * # noqa + +SERVICE_INSTANCE_NAME = "Pnf-Macro-With-Ves-Event" +PNF_WITH_VES = True diff --git a/src/onaptests/configuration/settings.py b/src/onaptests/configuration/settings.py index a3aa3b9..b0d1ad3 100644 --- a/src/onaptests/configuration/settings.py +++ b/src/onaptests/configuration/settings.py @@ -8,6 +8,7 @@ import random import string + from jinja2 import Environment, PackageLoader # Variables to set logger information @@ -68,6 +69,10 @@ SDNC_DB_PRIMARY_HOST = "mariadb-galera.onap.svc.cluster.local" SDNC_DB_PORT = 3306 +KAFKA_USER = "strimzi-kafka-admin" +KUBERNETES_NAMESPACE = "onap" + + # We need to create a service file with a random service name, # to be sure that we force onboarding def generate_service_config_yaml_file(service_name: str, diff --git a/src/onaptests/configuration/status_settings.py b/src/onaptests/configuration/status_settings.py index a291c21..2e95cd1 100644 --- a/src/onaptests/configuration/status_settings.py +++ b/src/onaptests/configuration/status_settings.py @@ -3,6 +3,7 @@ from .settings import * # noqa SERVICE_NAME = "Status Check" SERVICE_DETAILS = "Checks status of all k8s resources in the selected namespace" STATUS_RESULTS_DIRECTORY = "/tmp" +STORE_LOGS = True STORE_ARTIFACTS = True CHECK_POD_VERSIONS = True IGNORE_EMPTY_REPLICAS = False @@ -22,6 +23,8 @@ FULL_LOGS_CONTAINERS = [ # patterns to be excluded from the check WAIVER_LIST = ['integration'] +WAIVER_EVENTS = ['PolicyViolation'] + EXCLUDED_LABELS = { } diff --git a/src/onaptests/configuration/ves_publish_settings.py b/src/onaptests/configuration/ves_publish_settings.py new file mode 100644 index 0000000..d590ca9 --- /dev/null +++ b/src/onaptests/configuration/ves_publish_settings.py @@ -0,0 +1,15 @@ +from onaptests.configuration.settings import * # noqa + +SERVICE_NAME = "VesCollectorService" +SERVICE_DETAILS = "Test publishing and reception of ves events" +PNF_REGISTRATION_TOPIC_NAME = "unauthenticated.VES_PNFREG_OUTPUT" +PNF_REGISTRATION_VES_DOMAIN_NAME = "pnfRegistration" +PNF_SOURCE_NAME_IN_VES_EVENT = "dummy-ru-vesCollectorTest" + +DMAAP_USERNAME = "dcae@dcae.onap.org" +DMAAP_PASSWORD = "demo123456!" + +DMAAP_USERNAME = "dcae@dcae.onap.org" +DMAAP_PASSWORD = "demo123456!" + +VES_VERSION = "v7" diff --git a/src/onaptests/scenario/aai_initial_data_setup.py b/src/onaptests/scenario/aai_initial_data_setup.py new file mode 100644 index 0000000..5809fa7 --- /dev/null +++ b/src/onaptests/scenario/aai_initial_data_setup.py @@ -0,0 +1,79 @@ +from onapsdk.configuration import settings + +from onaptests.scenario.scenario_base import BaseScenarioStep, ScenarioBase +from onaptests.steps.AAIInitialSetup.create_operations import \ + CreateOperationStep +from onaptests.steps.AAIInitialSetup.get_operations import GetOperationsStep +from onaptests.steps.AAIInitialSetup.update_operation_step import \ + UpdateOperationStep +from onaptests.steps.base import BaseStep +from onaptests.steps.cloud.link_cloudregion_to_project import \ + LinkCloudRegionToProjectStep +from onaptests.steps.cloud.link_lineofbusiness_to_tenant import \ + LinkLineOfBusinessToTenantStep +from onaptests.steps.cloud.link_owningentity_to_tenant import \ + LinkOwningEntityToTenantStep + + +class AaiInitialDataSetup(BaseScenarioStep): + """Step created to run scenario and generate report.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + self._logger.info("Instantiation started") + + self.add_step(CreateOperationStep()) + self.add_step(GetOperationsStep()) + # self.add_step(GetAllOperationsStep()) + self.add_step(UpdateOperationStep()) + + # create relationship between cloud region and project + self.add_step(LinkCloudRegionToProjectStep()) + # create relationship between owning entity and tenant + self.add_step(LinkOwningEntityToTenantStep()) + # create relationship between line of business and tenant + self.add_step(LinkLineOfBusinessToTenantStep()) + + @property + def description(self) -> str: + """Step description. + + Used for reports + + Returns: + str: Step description + + """ + return "AAIInitialSetup for performing CRUD operations on entities.." + + @property + def component(self) -> str: + """Component name. + + Name of component which step is related with. + Most is the name of ONAP component + + Returns: + str: Component name + """ + return "AAI" + + @property + def service_instance_name(self) -> str: + """Service instance name. + + Returns: + str: Service instance name + + """ + return settings.SERVICE_INSTANCE_NAME + + +class AAICrud(ScenarioBase): + """AaiInitialDataSetup to test CRUD operation for all entities.""" + + def __init__(self, **kwargs): + """Init AaiInitialDataSetup execution started.""" + super().__init__('aai_initial_data_setup', **kwargs) + self.test = AaiInitialDataSetup() diff --git a/src/onaptests/scenario/add_delete_cnf_macro.py b/src/onaptests/scenario/add_delete_cnf_macro.py new file mode 100644 index 0000000..4765ed1 --- /dev/null +++ b/src/onaptests/scenario/add_delete_cnf_macro.py @@ -0,0 +1,17 @@ +"""Instantiate service with CNF using SO macro flow.""" +import logging + +from onaptests.scenario.scenario_base import ScenarioBase +from onaptests.steps.instantiate.so.add_cnf_in_service import AddCnfInService + + +class AddDeleteCnfInRunningSvcScenario(ScenarioBase): + """Instantiate a service with CNF, then add and delete CNF from the service.""" + + __logger = logging.getLogger(__name__) + + def __init__(self, **kwargs): + """Add cnf in running service.""" + super().__init__('add_delete_cnf_macro', **kwargs) + self.__logger.info("CnfMacro init started") + self.test = AddCnfInService() diff --git a/src/onaptests/scenario/add_pnf_in_running_svc.py b/src/onaptests/scenario/add_pnf_in_running_svc.py new file mode 100644 index 0000000..e09b8e6 --- /dev/null +++ b/src/onaptests/scenario/add_pnf_in_running_svc.py @@ -0,0 +1,98 @@ +"""Instantiate service with PNF using SO macro flow.""" +import logging + +import yaml +from onapsdk.configuration import settings + +from onaptests.scenario.scenario_base import (BaseStep, ScenarioBase, + YamlTemplateBaseScenarioStep) +from onaptests.steps.instantiate.service_macro import \ + YamlTemplateServiceMacroInstantiateStep +from onaptests.steps.instantiate.so.add_pnf_in_service import AddPnfInService +from onaptests.steps.instantiate.so.delete_pnf_in_service import \ + DeletePnfMacroInService +from onaptests.steps.onboard.cds import CbaPublishStep + + +class AddPnfInRunningSvcScenario(YamlTemplateBaseScenarioStep): + """Step created to run scenario and generate report.""" + + def __init__(self): + """Initialize step. + + Substeps: + - YamlTemplateServiceMacroInstantiateStep. + """ + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + self._yaml_template = None + self._logger.info("AddPnfInRunningSvcScenario started") + self.add_step(CbaPublishStep()) + self.add_step(YamlTemplateServiceMacroInstantiateStep()) + self.add_step(DeletePnfMacroInService()) + self.add_step(AddPnfInService()) + + @property + def description(self) -> str: + """Step description. + + Used for reports + + Returns: + str: Step description + + """ + return "PNF macro scenario step" + + @property + def component(self) -> str: + """Component name. + + Name of component which step is related with. + Most is the name of ONAP component. + + Returns: + str: Component name + + """ + return "TEST" + + @property + def yaml_template(self) -> dict: + """YAML template abstract property. + + Every YAML template step need to implement that property. + + Returns: + dict: YAML template + + """ + if not self._yaml_template: + with open(settings.SERVICE_YAML_TEMPLATE, "r", encoding="utf-8") as yaml_template: + self._yaml_template: dict = yaml.safe_load(yaml_template) + return self._yaml_template + + @property + def model_yaml_template(self) -> dict: + return {} + + @property + def service_instance_name(self) -> str: + """Service instance name. + + Returns: + str: Service instance name + + """ + return settings.SERVICE_INSTANCE_NAME + + +class AddPnfInRunningSvc(ScenarioBase): + """Run PNF simulator and onboard then instantiate a service with PNF.""" + + __logger = logging.getLogger(__name__) + + def __init__(self, **kwargs): + """Add pnf in running service.""" + super().__init__('add_pnf_in_running_service', **kwargs) + self.__logger.info("PnfMacro init started") + self.test = AddPnfInRunningSvcScenario() diff --git a/src/onaptests/scenario/basic_cds.py b/src/onaptests/scenario/basic_cds.py index 9cb4a54..313584a 100644 --- a/src/onaptests/scenario/basic_cds.py +++ b/src/onaptests/scenario/basic_cds.py @@ -1,13 +1,13 @@ #!/usr/bin/env python """Simple CDS blueprint erichment test scenario.""" from onaptests.scenario.scenario_base import ScenarioBase -from onaptests.steps.onboard.cds import CbaEnrichStep +from onaptests.steps.onboard.cds import CbaProcessStep class CDSBlueprintEnrichment(ScenarioBase): """Enrich simple blueprint using CDS blueprintprocessor.""" def __init__(self, **kwargs): - """Init CDS blueprint enrichment use case.""" + """Init CDS blueprint CbaProcessStep use case.""" super().__init__('basic_cds', **kwargs) - self.test = CbaEnrichStep() + self.test = CbaProcessStep() diff --git a/src/onaptests/scenario/basic_cnf_macro.py b/src/onaptests/scenario/basic_cnf_macro.py index 95fafad..d13053b 100644 --- a/src/onaptests/scenario/basic_cnf_macro.py +++ b/src/onaptests/scenario/basic_cnf_macro.py @@ -4,8 +4,9 @@ from yaml import SafeLoader, load from onaptests.scenario.scenario_base import (BaseStep, ScenarioBase, YamlTemplateBaseScenarioStep) -from onaptests.steps.instantiate.service_macro import \ - YamlTemplateServiceMacroInstantiateStep +from onaptests.steps.instantiate.service_macro import ( + YamlTemplateServiceMacroInstantiateStep, + YamlTemplateServiceOperatorInstantiateStep) from onaptests.steps.onboard.cds import CbaPublishStep @@ -17,12 +18,16 @@ class BasicCnfMacroStep(YamlTemplateBaseScenarioStep): Substeps: - CbaPublishStep - - YamlTemplateServiceMacroInstantiateStep. + - YamlTemplateServiceMacroInstantiateStep + - CheckOnapVnfCr. """ super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) self._yaml_template: dict = None self.add_step(CbaPublishStep()) - self.add_step(YamlTemplateServiceMacroInstantiateStep()) + if not settings.TEST_ONAP_OPERATOR: + self.add_step(YamlTemplateServiceMacroInstantiateStep()) + elif settings.TEST_ONAP_OPERATOR: + self.add_step(YamlTemplateServiceOperatorInstantiateStep()) @property def description(self) -> str: @@ -34,7 +39,9 @@ class BasicCnfMacroStep(YamlTemplateBaseScenarioStep): str: Step description """ - return "Basic CNF macro scenario step" + if not settings.TEST_ONAP_OPERATOR: + return "Basic CNF macro scenario step" + return "Basic CNF macro and Onap-Operator scenario step" @property def component(self) -> str: diff --git a/src/onaptests/scenario/basic_kafka.py b/src/onaptests/scenario/basic_kafka.py new file mode 100644 index 0000000..7afe562 --- /dev/null +++ b/src/onaptests/scenario/basic_kafka.py @@ -0,0 +1,178 @@ +import json + +from onapsdk.configuration import settings +from onapsdk.kafka import onap_kafka + +from onaptests.scenario.scenario_base import BaseScenarioStep, ScenarioBase +from onaptests.steps.base import BaseStep +from onaptests.utils import kubernetes_kafka +from onaptests.utils.exceptions import OnapTestException + + +def get_kafka_password(): + """ + Retrieves the Kafka admin password. + + This method initializes a KubernetesKafka reader object, + reads the Kafka admin secret, and retrieves the Kafka admin password. + + Returns: + str: The Kafka admin password. + """ + reader = kubernetes_kafka.KubernetesKafka() + reader.read_kafka_admin_secret() + kafka_password = reader.get_kafka_admin_password() + return kafka_password + + +class KafkaEventStep(BaseScenarioStep): + """Step to test Kafka functionality, + including dummy event publishing/consumption and topic management.""" + + def __init__(self) -> None: + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + self.add_step(CreateKafkaTopicStep()) + self.add_step(SubmitDummyEventToKafkaStep()) + self.add_step(ReceiveDummyEventFromKafkaStep()) + + @property + def component(self) -> str: + return "KAFKA" + + @property + def description(self) -> str: + return "Kafka Event Handling Step" + + +class CreateKafkaTopicStep(BaseStep): + """Step to create a new topic on Kafka.""" + + def __init__(self) -> None: + super().__init__(cleanup=settings.CLEANUP_FLAG) + + @property + def description(self) -> str: + """Step description.""" + return "Create a new topic on Kafka" + + @property + def component(self) -> str: + """Component name.""" + return "KAFKA" + + @BaseStep.store_state + def execute(self): + """Create a new topic on Kafka""" + super().execute() + + try: + kubernetes_kafka.create_topic(settings.TOPIC_NAME) + except Exception as ce: + self._logger.error("Failed to create topic on Kafka: %s", {str(ce)}) + raise OnapTestException(ce) from ce + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + self._logger.info("Deleting topic if exist on kafka.") + try: + kubernetes_kafka.delete_topic(settings.TOPIC_NAME) + except Exception as e: + self._logger.error("Exception while deleting topic on kafka: %s", e, exc_info=1) + raise OnapTestException(e) from e + + super().cleanup() + + +class SubmitDummyEventToKafkaStep(BaseStep): + """Step to submit a dummy event to a newly created Kafka topic.""" + + def __init__(self) -> None: + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + @property + def description(self) -> str: + """Step description.""" + return "Submit dummy event to Kafka by publishing it" + + @property + def component(self) -> str: + """Component name.""" + return "KAFKA" + + @BaseStep.store_state + def execute(self): + """Submit dummy event to Kafka""" + super().execute() + + try: + event_data = {'event_id': settings.EVENT_ID, 'event_name': settings.EVENT_NAME} + kafka_password = get_kafka_password() + onap_kafka.publish_event_on_topic(settings.KAFKA_USER, kafka_password, + json.dumps(event_data).encode('utf-8'), + settings.TOPIC_NAME) + except Exception as ce: + self._logger.error("Failed to publish event on Kafka: %s", {str(ce)}) + raise OnapTestException(ce) from ce + + +class ReceiveDummyEventFromKafkaStep(BaseStep): + """Step to receive a dummy event from Kafka.""" + + def __init__(self) -> None: + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + @property + def description(self) -> str: + """Step description.""" + return "Receive dummy event from Kafka" + + @property + def component(self) -> str: + """Component name.""" + return "Kafka" + + @BaseStep.store_state + def execute(self): + """Receive dummy event from Kafka""" + super().execute() + + kafka_password = get_kafka_password() + + try: + events = onap_kafka.get_events_for_topic(settings.KAFKA_USER, kafka_password, + settings.TOPIC_NAME) + self._logger.info("Below events are existed on topic.") + self._logger.info(events) + is_event_found = False + for event in events: + event_obj = json.loads(event) + if ((event_obj['event_id']) == + settings.EVENT_ID and + event_obj['event_name'] == + settings.EVENT_NAME): + self._logger.info("Received the required event from Kafka") + is_event_found = True + break + if not is_event_found: + msg = "Did not get the required event from Kafka" + self._logger.error(msg) + raise OnapTestException(msg) + + except Exception as ce: + self._logger.debug("Failed to receive the event from Kafka: %s", {str(ce)}) + raise OnapTestException(ce) from ce + + +class KafkaTestCase(ScenarioBase): + """Test case to test Kafka functionality, + including dummy event publish/consume and topic creation/deletion.""" + + def __init__(self, **kwargs): + super().__init__('basic_kafka', **kwargs) + self.test: BaseStep = KafkaEventStep() + + +if __name__ == '__main__': + tt = KafkaTestCase() + tt.run() + tt.clean() diff --git a/src/onaptests/scenario/basic_onboard.py b/src/onaptests/scenario/basic_onboard.py index ae1ba8c..aa324f2 100644 --- a/src/onaptests/scenario/basic_onboard.py +++ b/src/onaptests/scenario/basic_onboard.py @@ -5,8 +5,9 @@ from yaml import SafeLoader, load from onaptests.scenario.scenario_base import (BaseStep, ScenarioBase, YamlTemplateBaseScenarioStep) -from onaptests.steps.onboard.service import (VerifyServiceDistributionStep, - YamlTemplateServiceOnboardStep) +from onaptests.steps.onboard.service import ( + VerifyServiceDistributionStep, YamlTemplateServiceDistributionStep, + YamlTemplateServiceOnboardStep) class BasicSdcOnboardStep(YamlTemplateBaseScenarioStep): @@ -16,12 +17,17 @@ class BasicSdcOnboardStep(YamlTemplateBaseScenarioStep): """Initialize step. Substeps: + - YamlTemplateServiceDistributionStep - YamlTemplateServiceOnboardStep - VerifyServiceDistributionStep (optional). """ super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) self._yaml_template: dict = None - self.add_step(YamlTemplateServiceOnboardStep()) + if settings.SERVICE_DISTRIBUTION_ENABLED: + self.add_step(YamlTemplateServiceDistributionStep()) + else: + self.add_step(YamlTemplateServiceOnboardStep()) + if settings.VERIFY_DISTRIBUTION: self.add_step(VerifyServiceDistributionStep()) diff --git a/src/onaptests/scenario/basic_policy.py b/src/onaptests/scenario/basic_policy.py new file mode 100644 index 0000000..fe09738 --- /dev/null +++ b/src/onaptests/scenario/basic_policy.py @@ -0,0 +1,11 @@ +from onaptests.scenario.scenario_base import ScenarioBase +from onaptests.steps.policy.policy_operations import GetPolicyDecisionStep + + +class PolicyScenario(ScenarioBase): + """Perform policy operations.""" + + def __init__(self, **kwargs): + """Init policy.""" + super().__init__('basic_policy', **kwargs) + self.test = GetPolicyDecisionStep() diff --git a/src/onaptests/scenario/basic_prh.py b/src/onaptests/scenario/basic_prh.py new file mode 100644 index 0000000..d6d9ab1 --- /dev/null +++ b/src/onaptests/scenario/basic_prh.py @@ -0,0 +1,134 @@ +import json +import threading + +from onapsdk.aai.business.pnf import PnfInstance +from onapsdk.configuration import settings +from onapsdk.kafka import onap_kafka + +from onaptests.scenario.scenario_base import (BaseScenarioStep, BaseStep, + ScenarioBase) +from onaptests.steps.cloud.add_pnf import AAIAddPNFStep +from onaptests.steps.cloud.publish_pnf_reg_event_to_kafka import \ + PublishVESRegistrationEventToKafkaStep +from onaptests.utils.exceptions import OnapTestException +from onaptests.utils.kubernetes_kafka import KubernetesKafka + + +class PRHStep(BaseScenarioStep): + """The testcase to test PRH's handling PNF registration event received over Kafka""" + + def __init__(self) -> None: + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + self.add_step(AAIAddPNFStep()) + self.add_step(PublishVESRegistrationEventToKafkaStep()) + self.add_step(ValidatePRHProcessing()) + + @property + def component(self) -> str: + return "DCAE" + + @property + def description(self) -> str: + return "PRH Registration Event Handling step" + + +class ValidatePRHProcessing(BaseStep): + """Step to validate PRH processing results of PNF Registration Event""" + + pnf = PnfInstance(pnf_name=settings.PNF_NAME, + pnf_id=settings.PNF_ID, + orchestration_status=settings.PNF_ORCHESTRATION_STATUS, + in_maint=settings.PNF_IN_MAINT, + nf_role=settings.PNF_NF_ROLE, + service_instance=None) + + ticker = threading.Event() + + @property + def description(self) -> str: + return "Validate PRH processing results of PNF Registration Event" + + @property + def component(self) -> str: + return "DCAE" + + def validate_aai_changes(self): + """Validate correctness of PNF configuration in AAI""" + prh_get_response_dict = PnfInstance.send_message_json("GET", + f"Get {self.pnf.pnf_name} PNF", + f"{self.pnf.url}") + + updated_pnf = PnfInstance.create_from_api_response(prh_get_response_dict, None) + + if (updated_pnf.serial_number == settings.PNF_SERIAL_NUMBER and + updated_pnf.ipaddress_v4_oam == settings.PNF_IPADDRESS_V4_OAM and + updated_pnf.ipaddress_v6_oam == settings.PNF_IPADDRESS_V6_OAM): + self._logger.info("PNF is updated in AAI as expected") + self.ticker.set() + else: + self._logger.info("PNF is not yet updated in AAI as expected") + + @BaseStep.store_state + def execute(self) -> None: + """Validate AAI changes made and also receive the message published by\ + PRH by calling kakfa methods""" + + super().execute() + + # Check for PNF updates in AAI + count = 0 + while not self.ticker.wait(settings.WAIT_TIME_SECONDS_BETWEEN_CHECK) and\ + count < settings.MAX_ATTEMPTS_TO_CHECK: + self._logger.info("Attempt-%s: Checking if PNF is updated in AAI", count + 1) + self.validate_aai_changes() + count = count + 1 + + if (count == settings.MAX_ATTEMPTS_TO_CHECK and self.ticker.is_set() is False): + msg = "PNF is not updated in AAI as expected in {sec} seconds".format( + sec=settings.WAIT_TIME_SECONDS_BETWEEN_CHECK * settings.MAX_ATTEMPTS_TO_CHECK) + self._logger.info(msg) + raise OnapTestException(msg) + + reader = KubernetesKafka() + reader.read_kafka_admin_secret() + kafka_password = reader.get_kafka_admin_password() + + # Try to receive PNF_READY event + self.ticker.clear() + count = 0 + while not self.ticker.wait(settings.WAIT_TIME_SECONDS_BETWEEN_CHECK) and\ + count < settings.MAX_ATTEMPTS_TO_CHECK: + self._logger.info("Attempt-%s: Checking if PNF_READY event is published", count + 1) + events = onap_kafka.get_events_for_topic(settings.KAFKA_USER, kafka_password, + settings.PNFREADY_TOPIC_NAME) + is_event_found = False + for event in events: + event_obj = json.loads(event) + if event_obj['correlationId'] == settings.PNF_NAME: + self._logger.info("Received required PNF_READY event from Message Router !") + is_event_found = True + self.ticker.set() + break + if is_event_found is False: + self._logger.info("PNF_READY event is not yet received") + count = count + 1 + + if (count == settings.MAX_ATTEMPTS_TO_CHECK and self.ticker.is_set() is False): + msg = "PNF_READY event is not received as expected in {sec} seconds".format( + sec=settings.WAIT_TIME_SECONDS_BETWEEN_CHECK * settings.MAX_ATTEMPTS_TO_CHECK) + self._logger.info(msg) + raise OnapTestException(msg) + + +class PRHBase(ScenarioBase): + """The testcase to test the PRH's functionality of handling PNF registration event""" + + def __init__(self, **kwargs): + super().__init__('basic_prh', **kwargs) + self.test: BaseScenarioStep = PRHStep() + + +if __name__ == "__main__": + vctc = PRHBase() + vctc.run() + vctc.clean() diff --git a/src/onaptests/scenario/cba_verification.py b/src/onaptests/scenario/cba_verification.py new file mode 100644 index 0000000..3640e90 --- /dev/null +++ b/src/onaptests/scenario/cba_verification.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python +"""CBA Verification test case.""" +from onapsdk.configuration import settings + +from onaptests.scenario.scenario_base import BaseScenarioStep, ScenarioBase +from onaptests.steps.base import BaseStep +from onaptests.steps.onboard.verify_cba import TestCbaStep + + +class CbaVerificationStep(BaseScenarioStep): + """Basic cba verification step.""" + + def __init__(self): + """CbaVerification step. + + Substeps: + - TestCbaStep + """ + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + for cba in settings.CBA_LIST: + self.add_step(TestCbaStep(cba)) + + @property + def description(self) -> str: + """Step description. + + Used for reports + + Returns: + str: Step description + + """ + return "Verify CBA deployed into environment" + + @property + def component(self) -> str: + """Component name. + + Name of component which step is related with. + Most is the name of ONAP component. + + Returns: + str: Component name + + """ + return "CBA" + + +class CbaVerification(ScenarioBase): + """CBA verification scenario.""" + + def __init__(self, **kwargs): + """Init CBA Verification.""" + super().__init__('cba_verification', **kwargs) + self.test = CbaVerificationStep() diff --git a/src/onaptests/scenario/check_time_sync.py b/src/onaptests/scenario/check_time_sync.py new file mode 100644 index 0000000..965179a --- /dev/null +++ b/src/onaptests/scenario/check_time_sync.py @@ -0,0 +1,224 @@ +import json +import time +from pathlib import Path + +import yaml +from jinja2 import BaseLoader, Environment, PackageLoader, select_autoescape +from kubernetes import client, config +from kubernetes.client.rest import ApiException +from onapsdk.configuration import settings +from onapsdk.onap_service import OnapService + +from onaptests.scenario.scenario_base import ScenarioBase +from onaptests.steps.base import BaseStep +from onaptests.utils.exceptions import OnapTestException +from onaptests.utils.resources import get_resource_location + + +class CreateTimeSyncChecker(BaseStep): + """Create Time Sync Checker Daemon Step.""" + + def __init__(self) -> None: + """Initialize step.""" + super().__init__(cleanup=settings.CLEANUP_FLAG) + self.config_map = None + self.daemon_set = None + + @property + def component(self) -> str: + return "K8S" + + @property + def description(self) -> str: + return "Create Time Sync Checker Daemon" + + def _build_cm_definition(self): + cm_body = """ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{daemon_name}}-script +data: + checker.py: | +{{script_body|indent(4, True)}} +""" + template = Environment(loader=BaseLoader).from_string(cm_body) + script_body_file = Path(get_resource_location("utils/ntp_checker.py")) + with open(script_body_file, "r", encoding="utf-8") as py_file: + script_body = py_file.read() + cm_final_body = template.render( + daemon_name=settings.DAEMON_NAME, + script_body=script_body) + return cm_final_body + + def _build_daemon_definition(self): + jinja_env_file = Environment(autoescape=select_autoescape(['yml.j2']), + loader=PackageLoader('onaptests.templates', + 'artifacts')) + template = jinja_env_file.get_template("ntp_checker_daemon.yml.j2") + daemon_final_body = template.render( + daemon_name=settings.DAEMON_NAME) + return daemon_final_body + + def _deamon_deployment_ratio(self): + if self.daemon_set.status.desired_number_scheduled <= 0: + return 0 + ratio = 1.0 * (self.daemon_set.status.number_ready / + self.daemon_set.status.desired_number_scheduled) + return ratio + + @BaseStep.store_state + def execute(self): # noqa: C901 + if settings.IN_CLUSTER: + config.load_incluster_config() + else: + config.load_kube_config(config_file=settings.K8S_CONFIG) + + try: + core = client.CoreV1Api() + cm_name = f"{settings.DAEMON_NAME}-script" + try: + self.config_map = core.read_namespaced_config_map( + cm_name, settings.DAEMON_NS) + except ApiException as e: + if e.status != 404: + raise e + self._logger.info( + f"Config map {cm_name} does not exist - creating") + cm_definition = yaml.safe_load(self._build_cm_definition()) + self.config_map = core.create_namespaced_config_map( + settings.DAEMON_NS, cm_definition) + + app = client.AppsV1Api() + try: + self.daemon_set = app.read_namespaced_daemon_set( + settings.DAEMON_NAME, settings.DAEMON_NS) + except ApiException as e: + if e.status != 404: + raise e + self._logger.info( + f"Daemon set {settings.DAEMON_NAME} does not exist - creating") + daemomn_definition = yaml.safe_load(self._build_daemon_definition()) + self.daemon_set = app.create_namespaced_daemon_set( + settings.DAEMON_NS, daemomn_definition) + + start_time = time.time() + while self._deamon_deployment_ratio() < settings.DAEMON_DEPLOYMENT_RATIO: + if (time.time() - start_time) > settings.DAEMON_READY_WAIT_TIMOUT_SEC: + raise OnapTestException( + f"Daemon set {settings.DAEMON_NAME} cannot come up") + self._logger.info( + f"Waiting for daemon set {settings.DAEMON_NAME} to come up") + time.sleep(30) + self.daemon_set = app.read_namespaced_daemon_set( + settings.DAEMON_NAME, settings.DAEMON_NS) + # additional short time to wait for pods to be ready + time.sleep(15) + except ApiException as e: + raise OnapTestException(e) from e + + @BaseStep.store_state(cleanup=True) + def cleanup(self): + if self.daemon_set: + self._logger.info( + f"Deleting daemon set {settings.DAEMON_NAME}") + try: + app = client.AppsV1Api() + app.delete_namespaced_daemon_set( + settings.DAEMON_NAME, settings.DAEMON_NS) + except ApiException as e: + self._logger.exception(e) + if self.config_map: + self._logger.info( + f"Deleting config map {settings.DAEMON_NAME}-script") + try: + core = client.CoreV1Api() + core.delete_namespaced_config_map( + f"{settings.DAEMON_NAME}-script", settings.DAEMON_NS) + except ApiException as e: + self._logger.exception(e) + + +class CheckNtpTimeSyncStep(BaseStep, OnapService): + """Check Local Time of Nodes Step.""" + + def __init__(self) -> None: + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + self.daemon_step = CreateTimeSyncChecker() + self.add_step(self.daemon_step) + + @property + def component(self) -> str: + return "NTP" + + @property + def description(self) -> str: + return "Check status of local time in k8s nodes" + + def _get_host_list(self): + pod_list = [] + if settings.IN_CLUSTER: + config.load_incluster_config() + else: + config.load_kube_config(config_file=settings.K8S_CONFIG) + selector = self.daemon_step.daemon_set.spec.selector.match_labels + raw_selector = '' + for key, value in selector.items(): + raw_selector += key + '=' + value + ',' + raw_selector = raw_selector[:-1] + core = client.CoreV1Api() + pods = core.list_namespaced_pod( + settings.DAEMON_NS, label_selector=raw_selector).items + for pod in pods: + if pod.status.pod_ip: + pod_list.append({"id": pod.metadata.name, + "host_name": pod.status.pod_ip}) + return pod_list + + @BaseStep.store_state + def execute(self): + hosts_to_check = self._get_host_list() + # hosts_to_check = [{"id": "localhost", "host_name": "127.0.0.1"}] + all_time_diffs = [] + for host in hosts_to_check: + host_id = host["id"] + host_name = host["host_name"] + self._logger.info(f"Checking time of {host_id}: {host_name}") + time_diffs = [] + for _ in range(0, settings.NODE_TIME_QUERIES_NUMBER): + # 1 ms for processing on our side + try: + local_time = int(time.time() * 1000) + 1 + executions_response = self.send_message_json( + "POST", + f"Get time status on {host_id}", + f"http://{host_name}:8000/local-time-status", + data=json.dumps({"time": local_time}), + timeout=5 + ) + # 1 ms for processing on server side + response_time = int(time.time() * 1000) - local_time - 1 + time_diff = executions_response["time"] + real_diff = int(time_diff - (response_time / 2.0)) + time_diffs.append(real_diff) + self._logger.debug(f"Diff {time_diff} -> Real Diff {real_diff}") + except Exception as e: + self._logger.exception(e) + if len(time_diffs) > 0: + final_diff = max(time_diffs) + all_time_diffs.append(final_diff) + self._logger.info(f"Final time diff for {host_id} is: {final_diff}") + if len(all_time_diffs) > 1: + overall_diff = max(all_time_diffs) - min(all_time_diffs) + if abs(overall_diff) > settings.MAX_TIME_DIFF_MS: + raise OnapTestException(f"Time diff {overall_diff} ms exceeds max threshold") + + +class CheckTimeSync(ScenarioBase): + """Check time synchronization in the cluster.""" + + def __init__(self, **kwargs): + """Init time sync test case.""" + super().__init__('check_time_sync', **kwargs) + self.test = CheckNtpTimeSyncStep() diff --git a/src/onaptests/scenario/generic_network.py b/src/onaptests/scenario/generic_network.py new file mode 100644 index 0000000..c42f68a --- /dev/null +++ b/src/onaptests/scenario/generic_network.py @@ -0,0 +1,82 @@ +import yaml +from onapsdk.configuration import settings +from yaml import SafeLoader + +from onaptests.scenario.basic_cnf_macro import BasicCnfMacroStep +from onaptests.scenario.scenario_base import (ScenarioBase, + YamlTemplateBaseScenarioStep) +from onaptests.steps.instantiate.so.generic_network_step import \ + GenericNetworkStep + + +class AddGenericNetwork(YamlTemplateBaseScenarioStep): + """Add generic network in existing VNF.""" + + def __init__(self): + """Init Generic Network use case.""" + super().__init__() + self._yaml_template = None + self.add_step(BasicCnfMacroStep()) + self.add_step(GenericNetworkStep()) + + @property + def description(self) -> str: + """Step description. + + Used for reports + + Returns: + str: Step description + + """ + return "Generic Network instantiation step" + + @property + def component(self) -> str: + """Component name. + + Name of component which step is related with. + Most is the name of ONAP component. + + Returns: + str: Component name + + """ + return "SO" + + @property + def yaml_template(self) -> dict: + """YAML template abstract property. + + Every YAML template step need to implement that property. + + Returns: + dict: YAML template + + """ + if not self._yaml_template: + with open(settings.SERVICE_YAML_TEMPLATE, "r", encoding="utf-8") as yaml_template: + self._yaml_template: dict = yaml.load(yaml_template, SafeLoader) + return self._yaml_template + + @property + def model_yaml_template(self) -> dict: + return {} + + @property + def service_instance_name(self) -> str: + """Service instance name. + + Returns: + str: Service instance name + + """ + return settings.SERVICE_INSTANCE_NAME + + +class GenericNetwork(ScenarioBase): + """Instantiate a basic cnf macro.""" + def __init__(self, **kwargs): + """Init GenericNetwork Macro use case.""" + super().__init__('generic_network', **kwargs) + self.test = AddGenericNetwork() diff --git a/src/onaptests/scenario/instantiate_pnf_with_ves_event.py b/src/onaptests/scenario/instantiate_pnf_with_ves_event.py new file mode 100644 index 0000000..12b8b1e --- /dev/null +++ b/src/onaptests/scenario/instantiate_pnf_with_ves_event.py @@ -0,0 +1,91 @@ +import logging + +import yaml +from onapsdk.configuration import settings + +from onaptests.scenario.scenario_base import (BaseStep, ScenarioBase, + YamlTemplateBaseScenarioStep) +from onaptests.steps.instantiate.service_macro import \ + YamlTemplateServiceMacroInstantiateStep +from onaptests.steps.onboard.cds import CbaPublishStep + + +class InstantiatePnfWithVESEvent(YamlTemplateBaseScenarioStep): + """Step created to run pnf instantiation with ves event.""" + + def __init__(self, cleanup=False): + """Initialize step. + + Substeps: + - YamlTemplateServiceMacroInstantiateStep. + """ + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + self._logger.info("InstantiatePnfWithVESEvent started") + self._yaml_template: dict = None + self.add_step(CbaPublishStep()) + self.add_step(YamlTemplateServiceMacroInstantiateStep()) + + @property + def description(self) -> str: + """Step description. + + Used for reports + + Returns: + str: Step description + + """ + return "PNF macro scenario step" + + @property + def component(self) -> str: + """Component name. + + Name of component which step is related with. + Most is the name of ONAP component. + + Returns: + str: Component name + + """ + return "TEST" + + @property + def yaml_template(self) -> dict: + """YAML template abstract property. + + Every YAML template step need to implement that property. + + Returns: + dict: YAML template + + """ + if not self._yaml_template: + with open(settings.SERVICE_YAML_TEMPLATE, "r", encoding="utf-8") as yaml_template: + self._yaml_template: dict = yaml.safe_load(yaml_template) + return self._yaml_template + + @property + def service_instance_name(self) -> str: + """Service instance name. + + Returns: + str: Service instance name + + """ + return settings.SERVICE_INSTANCE_NAME + + @property + def model_yaml_template(self) -> dict: + return {} + + +class PnfWithVesEvent(ScenarioBase): + """Instantiate a service with PNF.""" + + __logger = logging.getLogger(__name__) + + def __init__(self, **kwargs): + super().__init__('pnf_with_ves_event', **kwargs) + self.__logger.info("PnfWithVesEventTestCase init started") + self.test = InstantiatePnfWithVESEvent() diff --git a/src/onaptests/scenario/instantiate_pnf_without_registration_event.py b/src/onaptests/scenario/instantiate_pnf_without_registration_event.py new file mode 100644 index 0000000..2c05da3 --- /dev/null +++ b/src/onaptests/scenario/instantiate_pnf_without_registration_event.py @@ -0,0 +1,92 @@ +"""Instantiate service with PNF using SO macro flow.""" +import logging + +import yaml +from onapsdk.configuration import settings + +from onaptests.scenario.scenario_base import (BaseStep, ScenarioBase, + YamlTemplateBaseScenarioStep) +from onaptests.steps.instantiate.service_macro import \ + YamlTemplateServiceMacroInstantiateStep +from onaptests.steps.onboard.cds import CbaPublishStep + + +class PnfMacroWithoutEventScenarioStep(YamlTemplateBaseScenarioStep): + """Step created to run pnf instantiation without ves event.""" + + def __init__(self): + """Initialize step. + + Substeps: + - YamlTemplateServiceMacroInstantiateStep. + """ + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + self._logger.info("PnfMacroWithoutEventScenarioStep without event started") + self._yaml_template: dict = None + self.add_step(CbaPublishStep()) + self.add_step(YamlTemplateServiceMacroInstantiateStep()) + + @property + def description(self) -> str: + """Step description. + + Used for reports + + Returns: + str: Step description + + """ + return "PNF macro scenario step" + + @property + def component(self) -> str: + """Component name. + + Name of component which step is related with. + Most is the name of ONAP component. + + Returns: + str: Component name + + """ + return "TEST" + + @property + def yaml_template(self) -> dict: + """YAML template abstract property. + + Every YAML template step need to implement that property. + + Returns: + dict: YAML template + + """ + if not self._yaml_template: + with open(settings.SERVICE_YAML_TEMPLATE, "r", encoding="utf-8") as yaml_template: + self._yaml_template: dict = yaml.safe_load(yaml_template) + return self._yaml_template + + @property + def service_instance_name(self) -> str: + """Service instance name. + + Returns: + str: Service instance name + + """ + return settings.SERVICE_INSTANCE_NAME + + @property + def model_yaml_template(self) -> dict: + return {} + + +class InstantiatePnfWithoutRegistrationEvent(ScenarioBase): + """Instantiate a service with PNF.""" + + __logger = logging.getLogger(__name__) + + def __init__(self, **kwargs): + super().__init__('instantiate_pnf_without_registration_event', **kwargs) + self.__logger.info("instantiate_pnf_without_registration_event init started") + self.test = PnfMacroWithoutEventScenarioStep() diff --git a/src/onaptests/scenario/instantiate_service_without_resource.py b/src/onaptests/scenario/instantiate_service_without_resource.py new file mode 100644 index 0000000..f9d4adc --- /dev/null +++ b/src/onaptests/scenario/instantiate_service_without_resource.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python +"""Service Instantiation without the resource..""" +from onapsdk.configuration import settings +from yaml import SafeLoader, load + +from onaptests.scenario.scenario_base import (BaseStep, ScenarioBase, + YamlTemplateBaseScenarioStep) +from onaptests.steps.instantiate.service_macro import \ + YamlTemplateServiceMacroInstantiateStep +from onaptests.steps.onboard.cds import CbaPublishStep + + +class InstantiateServiceWithoutResourceStep(YamlTemplateBaseScenarioStep): + """"Main scenario step""" + + def __init__(self): + """Initialize step.. + + Sub steps: + - CbaPublishStep + - YamlTemplateInstantiateServiceWithoutResourceStep. + """ + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + self._yaml_template: dict = None + self.add_step(CbaPublishStep()) + self.add_step(YamlTemplateServiceMacroInstantiateStep()) + + @property + def component(self) -> str: + return "SO" + + @property + def description(self) -> str: + return "Service Instantiation without the resource step" + + @property + def service_instance_name(self) -> str: + """Service instance name. + + Returns: + str: Service instance name + + """ + return settings.SERVICE_INSTANCE_NAME + + @property + def yaml_template(self) -> dict: + """YAML template abstract property. + + Every YAML template step need to implement that property. + + Returns: + dict: YAML template + + """ + if not self._yaml_template: + with open(settings.SERVICE_YAML_TEMPLATE, "r", encoding="utf-8") as yaml_template: + self._yaml_template: dict = load(yaml_template, SafeLoader) + return self._yaml_template + + @property + def model_yaml_template(self) -> dict: + return {} + + +class InstantiateServiceWithoutResource(ScenarioBase): + """Instantiate a service without resource.""" + + def __init__(self, **kwargs): + """Init a service without resource use case.""" + super().__init__('instantiate_service_without_resource') + self.test = InstantiateServiceWithoutResourceStep() diff --git a/src/onaptests/scenario/modify_service_pnf.py b/src/onaptests/scenario/modify_service_pnf.py new file mode 100644 index 0000000..24a3ef4 --- /dev/null +++ b/src/onaptests/scenario/modify_service_pnf.py @@ -0,0 +1,93 @@ +"""Modify service with PNF using SO macro flow.""" + +import yaml +from onapsdk.configuration import settings + +from onaptests.scenario.scenario_base import (ScenarioBase, + YamlTemplateBaseScenarioStep) +from onaptests.steps.instantiate.service_macro import \ + YamlTemplateServiceMacroInstantiateStep +from onaptests.steps.instantiate.so.modify_pnf_in_service import \ + ModifyPnfInService +from onaptests.steps.onboard.cds import CbaPublishStep + + +class ModifyPnfScenarioStep(YamlTemplateBaseScenarioStep): + """Step created to modify pnf without ves event.""" + + def __init__(self): + """Initialize step. + + Sub steps: + - YamlTemplateServiceMacroInstantiateStep. + """ + super().__init__() + self._logger.info("Modify Pnf Step started") + self._yaml_template: dict = None + self.add_step(CbaPublishStep()) + self.add_step(YamlTemplateServiceMacroInstantiateStep()) + self.add_step(ModifyPnfInService()) + + @property + def description(self) -> str: + """Step description. + + Used for reports + + Returns: + str: Step description + + """ + return "PNF modify scenario step" + + @property + def component(self) -> str: + """Component name. + + Name of component which step is related with. + Most is the name of ONAP component. + + Returns: + str: Component name + + """ + return "PythonSDK-tests" + + @property + def yaml_template(self) -> dict: + """YAML template abstract property. + + Every YAML template step need to implement that property. + + Returns: + dict: YAML template + + """ + if not self._yaml_template: + with open(settings.SERVICE_YAML_TEMPLATE, + "r", encoding="utf-8") as yaml_template: + self._yaml_template: dict = yaml.safe_load(yaml_template) + return self._yaml_template + + @property + def service_instance_name(self) -> str: + """Service instance name. + + Returns: + str: Service instance name + + """ + return settings.SERVICE_INSTANCE_NAME + + @property + def model_yaml_template(self) -> dict: + return {} + + +class ModifyPnf(ScenarioBase): + """Instantiate a service with PNF.""" + + def __init__(self, **kwargs): + """Init a service with PNF use case""" + super().__init__('modify_service_pnf') + self.test = ModifyPnfScenarioStep() diff --git a/src/onaptests/scenario/pnf_macro.py b/src/onaptests/scenario/pnf_macro.py index 10f9866..29f42e1 100644 --- a/src/onaptests/scenario/pnf_macro.py +++ b/src/onaptests/scenario/pnf_macro.py @@ -8,7 +8,7 @@ from onaptests.steps.instantiate.pnf_register_ves import \ SendPnfRegisterVesEvent from onaptests.steps.instantiate.service_macro import \ YamlTemplateServiceMacroInstantiateStep -from onaptests.steps.onboard.cds import CbaEnrichStep +from onaptests.steps.onboard.cds import CbaPublishStep from onaptests.steps.simulator.pnf_simulator_cnf.pnf_register import \ PnfSimulatorCnfRegisterStep @@ -28,7 +28,7 @@ class PnfMacroScenarioStep(YamlTemplateBaseScenarioStep): self.add_step(PnfSimulatorCnfRegisterStep()) else: self.add_step(SendPnfRegisterVesEvent()) - self.add_step(CbaEnrichStep()) + self.add_step(CbaPublishStep()) self.add_step(YamlTemplateServiceMacroInstantiateStep()) @property diff --git a/src/onaptests/scenario/publish_ves_event.py b/src/onaptests/scenario/publish_ves_event.py new file mode 100644 index 0000000..2fe34e8 --- /dev/null +++ b/src/onaptests/scenario/publish_ves_event.py @@ -0,0 +1,136 @@ +import json +from pathlib import Path + +import requests +from onapsdk.configuration import settings +from onapsdk.kafka import onap_kafka +from onapsdk.ves.ves import Ves + +from onaptests.scenario.scenario_base import BaseScenarioStep, ScenarioBase +from onaptests.steps.base import BaseStep +from onaptests.utils.exceptions import OnapTestException +from onaptests.utils.kubernetes_kafka import KubernetesKafka + + +class VESEventStep(BaseScenarioStep): + """Step to test the VES-Collector's functionality to handle VES event received over REST""" + + def __init__(self) -> None: + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + self.add_step(SubmitVESEventToCollectorStep()) + self.add_step(ReceiveVESEventFromKafkaStep()) + + @property + def component(self) -> str: + return "VES-Collector" + + @property + def description(self) -> str: + return "VES Event Handling step" + + +class SubmitVESEventToCollectorStep(BaseStep): + """Submit VES event to Collector step.""" + + def __init__(self) -> None: + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + @property + def description(self) -> str: + """Step description.""" + return "Submit VES event to Collector over REST" + + @property + def component(self) -> str: + """Component name.""" + return "VES-Collector" + + @BaseStep.store_state + def execute(self): + """Submit VES event to Collector over REST""" + super().execute() + + try: + send_event_response = Ves.send_event( + version=settings.VES_VERSION, + json_event=self.get_ves_payload_from_file(), + basic_auth=settings.VES_BASIC_AUTH) + self._logger.info("VES collector response=%s|%s", + send_event_response.status_code, + send_event_response.text) + + except (requests.exceptions.ConnectionError) as ce: + self._logger.error("Can't connect with VES Collector: %s", {str(ce)}) + raise OnapTestException(ce) from ce + except (requests.exceptions.HTTPError) as he: + self._logger.error("HTTP Error from VES Collector: %s", {str(he)}) + raise OnapTestException(he) from he + + def get_ves_payload_from_file(self) -> str: + """Get ves payload from file.""" + + with open(Path(Path(__file__).parent.parent, + "templates/artifacts/pnf_registration_ves_event.json"), + "r", + encoding="utf-8") as ves_event_file: + return ves_event_file.read() + + +class ReceiveVESEventFromKafkaStep(BaseStep): + """Receive VES event from Kafka step.""" + + def __init__(self) -> None: + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + @property + def description(self) -> str: + """Step description.""" + return "Receive VES event from Kafka" + + @property + def component(self) -> str: + """Component name.""" + return "Kafka" + + @BaseStep.store_state + def execute(self): + """Receive VES event from Kafka""" + super().execute() + + reader = KubernetesKafka() + reader.read_kafka_admin_secret() + kafka_password = reader.get_kafka_admin_password() + + try: + events = onap_kafka.get_events_for_topic(settings.KAFKA_USER, kafka_password, + settings.PNF_REGISTRATION_TOPIC_NAME) + is_event_found = False + for event in events: + event_obj = json.loads(event) + if ((event_obj['event']['commonEventHeader']['domain']) == + settings.PNF_REGISTRATION_VES_DOMAIN_NAME and + event_obj['event']['commonEventHeader']['sourceName'] == + settings.PNF_SOURCE_NAME_IN_VES_EVENT): + self._logger.info("Received the required VES event from Message Router !") + is_event_found = True + break + if not is_event_found: + msg = "Did not get the required VES event from Message Router" + self._logger.error(msg) + raise OnapTestException(msg) + + except (requests.exceptions.ConnectionError) as ce: + self._logger.debug("Can't connect with Message Router: %s", {str(ce)}) + raise OnapTestException(ce) from ce + except (requests.exceptions.HTTPError) as he: + self._logger.error("HTTP Error from Message Router: %s", {str(he)}) + raise OnapTestException(he) from he + + +class VesCollectorTestCase(ScenarioBase): + """The testcase to test the VES-Collector's functionality of + handling VES event received over REST""" + + def __init__(self, **kwargs): + super().__init__('ves_publish', **kwargs) + self.test: BaseStep = VESEventStep() diff --git a/src/onaptests/steps/AAIInitialSetup/create_operations.py b/src/onaptests/steps/AAIInitialSetup/create_operations.py new file mode 100644 index 0000000..ff6d639 --- /dev/null +++ b/src/onaptests/steps/AAIInitialSetup/create_operations.py @@ -0,0 +1,46 @@ +from onaptests.scenario.scenario_base import BaseScenarioStep +from onaptests.steps.base import BaseStep +from onaptests.steps.cloud.cloud_region_create import CloudRegionCreateStep +from onaptests.steps.cloud.complex_create import ComplexCreateStep +from onaptests.steps.cloud.customer_service_subscription_create import \ + CustomerServiceSubscriptionCreateStep +from onaptests.steps.cloud.lineofbusiness_create import \ + LineofBusinessCreateStep +from onaptests.steps.cloud.owning_entity_create import OwningEntityCreateStep +from onaptests.steps.cloud.platform_create import PlatformCreateStep +from onaptests.steps.cloud.project_create import ProjectCreateStep + + +class CreateOperationStep(BaseScenarioStep): + """create operations in AAI.""" + + def __init__(self): + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + # Create Complex + self.add_step(ComplexCreateStep()) + # Create CloudRegionCreateStep + self.add_step(CloudRegionCreateStep()) + # create Service Subscription Step + self.add_step(CustomerServiceSubscriptionCreateStep()) + # Create Customer + # CustomerCreate Step + # covered under CustomerServiceSubscriptionCreateStep + # Create platform + self.add_step(PlatformCreateStep()) + # Create project + self.add_step(ProjectCreateStep()) + # Create owning entity + self.add_step(OwningEntityCreateStep()) + # Create line of business + self.add_step(LineofBusinessCreateStep()) + + @property + def description(self) -> str: + """Step description.""" + return "AAI create Operations.." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" diff --git a/src/onaptests/steps/AAIInitialSetup/get_all_operations.py b/src/onaptests/steps/AAIInitialSetup/get_all_operations.py new file mode 100644 index 0000000..50978f3 --- /dev/null +++ b/src/onaptests/steps/AAIInitialSetup/get_all_operations.py @@ -0,0 +1,62 @@ +from typing import List + +from onapsdk.aai.business import (Customer, LineOfBusiness, OwningEntity, + Platform, Project) +from onapsdk.aai.cloud_infrastructure import CloudRegion, Complex + +from onaptests.steps.base import BaseStep +from onaptests.utils.exceptions import OnapTestException + + +class GetAllOperationsStep(BaseStep): + """get all operations in AAI.""" + + @property + def description(self) -> str: + """Step description.""" + return "AAI get all Operations.." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" + + @BaseStep.store_state + def execute(self): + + super().execute() + + # get all Customers + customer_list: List[Customer] = list(Customer.get_all()) + if not customer_list: + raise OnapTestException("Customer list shouldn't be empty") + + # get all Owning Entity + owning_ent_list: List[OwningEntity] = list(OwningEntity.get_all()) + if not owning_ent_list: + raise OnapTestException("OwningEntity list shouldn't be empty") + + # get all Platform + platform_list: List[Platform] = list(Platform.get_all()) + if not platform_list: + raise OnapTestException("Platform list shouldn't be empty") + + # get all Project + project_list: List[Project] = list(Project.get_all()) + if not project_list: + raise OnapTestException("Project list shouldn't be empty") + + # get all LineOfBusiness + lob_list: List[LineOfBusiness] = list(LineOfBusiness.get_all()) + if not lob_list: + raise OnapTestException("Line of business list shouldn't be empty") + + # get all Complex + complex_list: List[Complex] = list(Complex.get_all()) + if not complex_list: + raise OnapTestException("Complex list shouldn't be empty") + + # get all cloud region + cloud_region_list: List[CloudRegion] = list(CloudRegion.get_all()) + if not cloud_region_list: + raise OnapTestException("CloudRegion list shouldn't be empty") diff --git a/src/onaptests/steps/AAIInitialSetup/get_operations.py b/src/onaptests/steps/AAIInitialSetup/get_operations.py new file mode 100644 index 0000000..2217d4c --- /dev/null +++ b/src/onaptests/steps/AAIInitialSetup/get_operations.py @@ -0,0 +1,49 @@ +from onapsdk.aai.business import (Customer, LineOfBusiness, OwningEntity, + Platform, Project) +from onapsdk.aai.cloud_infrastructure import CloudRegion, Complex +from onapsdk.configuration import settings + +from onaptests.steps.base import BaseStep + + +class GetOperationsStep(BaseStep): + """get operations in AAI.""" + + @property + def description(self) -> str: + """Step description.""" + return "AAI get Operations.." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" + + @BaseStep.store_state + def execute(self): + + super().execute() + + # get Customer + Customer.get_by_global_customer_id(settings.GLOBAL_CUSTOMER_ID) + + # get Owning Entity + OwningEntity.get_by_owning_entity_id(settings.OWNING_ENTITY_ID) + + # get Platform + Platform.get_by_name(settings.PLATFORM) + + # get Project + Project.get_by_name(settings.PROJECT) + + # get LineOfBusiness + LineOfBusiness.get_by_name(settings.LINE_OF_BUSINESS) + + # get Complex + Complex.get_by_physical_location_id(settings.COMPLEX_PHYSICAL_LOCATION_ID) + + # get cloud region + CloudRegion.get_by_id( + settings.CLOUD_REGION_CLOUD_OWNER, + settings.CLOUD_REGION_ID, + ) diff --git a/src/onaptests/steps/AAIInitialSetup/update_operation_step.py b/src/onaptests/steps/AAIInitialSetup/update_operation_step.py new file mode 100644 index 0000000..01e04a9 --- /dev/null +++ b/src/onaptests/steps/AAIInitialSetup/update_operation_step.py @@ -0,0 +1,32 @@ +from onaptests.scenario.scenario_base import BaseScenarioStep +from onaptests.steps.base import BaseStep +from onaptests.steps.cloud.cloud_region_upadte import CloudRegionUpdateStep +from onaptests.steps.cloud.complex_update import ComplexUpdateStep +from onaptests.steps.cloud.customer_update import CustomerUpdateStep +from onaptests.steps.cloud.owning_entity_update import OwningEntityUpdateStep + + +class UpdateOperationStep(BaseScenarioStep): + """update operations in AAI.""" + + def __init__(self): + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + # Update Complex + self.add_step(ComplexUpdateStep()) + # Update cloud region + self.add_step(CloudRegionUpdateStep()) + # Update owning entity + self.add_step(OwningEntityUpdateStep()) + # Update customer + self.add_step(CustomerUpdateStep()) + + @property + def description(self) -> str: + """Step description.""" + return "AAI update Operations.." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" diff --git a/src/onaptests/steps/base.py b/src/onaptests/steps/base.py index c615047..9356f4d 100644 --- a/src/onaptests/steps/base.py +++ b/src/onaptests/steps/base.py @@ -146,13 +146,19 @@ class BaseStep(StoreStateHandler, ABC): except SettingsError: pass - def __init__(self, cleanup: bool = False, break_on_error=True) -> None: + def __init__(self, + cleanup: bool = False, + break_on_error: bool = True, + is_optional: bool = False) -> None: """Step initialization. Args: cleanup(bool, optional): Determines if cleanup action should be called. break_on_error(bool, optional): Determines if fail on execution should result with continuation of further steps + is_optional(bool): Determines if step is optional and error should be ignored. + Step would be marked as failed, but still move forward with rest of the + scenario. False by default. """ self._steps: List["BaseStep"] = [] @@ -169,6 +175,7 @@ class BaseStep(StoreStateHandler, ABC): self._state_clean: bool = False self._nesting_level: int = 0 self._break_on_error: bool = break_on_error + self._is_optional: bool = is_optional self._substeps_executed: bool = False self._is_validation_only = settings.IF_VALIDATION self._is_force_cleanup = os.environ.get(IF_FORCE_CLEANUP) is not None @@ -292,6 +299,22 @@ class BaseStep(StoreStateHandler, ABC): """Step name.""" return self.__class__.__name__ + @property + def service_name(self) -> str: + """Service name.""" + return settings.SERVICE_NAME + + @property + def service_type(self) -> str: + """Service type.""" + try: + service_type = getattr(settings, "SERVICE_TYPE") + if service_type: + return service_type + return self.service_name + except (KeyError, AttributeError, SettingsError): + return self.service_name + @property @abstractmethod def description(self) -> str: @@ -362,9 +385,12 @@ class BaseStep(StoreStateHandler, ABC): try: step.execute() except (OnapTestException, SDKException) as substep_err: - if step._break_on_error: + if step._is_optional: + self._logger.info("Step is optional, error ignored, continue test execution") + elif step._break_on_error: raise SubstepExecutionException("", substep_err) # noqa: W0707 - substep_exceptions.append(substep_err) + else: + substep_exceptions.append(substep_err) if self._steps: if len(substep_exceptions) > 0 and self._break_on_error: if len(substep_exceptions) == 1: @@ -482,7 +508,7 @@ class YamlTemplateBaseStep(BaseStep, ABC): Customer.get_by_global_customer_id(settings.GLOBAL_CUSTOMER_ID) if self._service_subscription is None or reload: self._service_subscription: ServiceSubscription = \ - self._customer.get_service_subscription_by_service_type(self.service_name) + self._customer.get_service_subscription_by_service_type(self.service_type) def _load_service_instance(self): if self._service_instance is None: @@ -503,6 +529,23 @@ class YamlTemplateBaseStep(BaseStep, ABC): return next(iter(self.yaml_template.keys())) return self.parent.service_name + @property + def service_type(self) -> str: + """Service type. + + Gets from YAML template if it's a root step, gets from parent otherwise. + If YAML template has no service_type key returns service name otherwise. + + Returns: + str: Service type + + """ + if self.is_root: + if "service_type" in self.yaml_template[self.service_name]: + return self.yaml_template[self.service_name]["service_type"] + return self.service_name + return self.parent.service_type + @property def service_instance_name(self) -> str: """Service instance name. @@ -539,3 +582,24 @@ class YamlTemplateBaseStep(BaseStep, ABC): dict: YAML template """ + + +class DelayStep(BaseStep): + """Delay step -- useful if some delay between two steps is needed.""" + + def __init__(self, delay: int, break_on_error=True): + super().__init__(BaseStep.HAS_NO_CLEANUP, break_on_error) + self.delay: int = delay + + @property + def description(self) -> str: + return f"Wait for {self.delay} seconds." + + @property + def component(self) -> str: + return "Python ONAP SDK" + + @BaseStep.store_state + def execute(self): + super().execute() + time.sleep(self.delay) diff --git a/src/onaptests/steps/cloud/add_pnf.py b/src/onaptests/steps/cloud/add_pnf.py new file mode 100644 index 0000000..2b83206 --- /dev/null +++ b/src/onaptests/steps/cloud/add_pnf.py @@ -0,0 +1,52 @@ +from onapsdk.aai.business.pnf import PnfInstance +from onapsdk.configuration import settings + +from onaptests.utils.exceptions import OnapTestException + +from ..base import BaseStep + + +class AAIAddPNFStep(BaseStep): + """Step to add a PNF in AAI""" + + pnf = PnfInstance(pnf_name=settings.PNF_NAME, + pnf_id=settings.PNF_ID, + orchestration_status=settings.PNF_ORCHESTRATION_STATUS, + in_maint=settings.PNF_IN_MAINT, + nf_role=settings.PNF_NF_ROLE, + service_instance=None) + + def __init__(self) -> None: + super().__init__(cleanup=settings.CLEANUP_FLAG) + + @property + def description(self) -> str: + return "Step to add a PNF in AAI" + + @property + def component(self) -> str: + return "AAI" + + @BaseStep.store_state + def execute(self) -> None: + """Add a PNF in AAI by calling its REST API""" + + super().execute() + + self._logger.info("Put pnf:%s", self.pnf.pnf_name) + try: + self.pnf.put_in_aai() + except Exception as e: + self._logger.error("Exception while adding PNF in AAI: %s", e, exc_info=1) + raise OnapTestException(e) from e + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + self._logger.info("Deleting PNF put in AAI for the test") + try: + self.pnf.delete_from_aai() + except Exception as e: + self._logger.error("Exception while deleting PNF from AAI: %s", e, exc_info=1) + raise OnapTestException(e) from e + + super().cleanup() diff --git a/src/onaptests/steps/cloud/check_status.py b/src/onaptests/steps/cloud/check_status.py index 5a4b962..ae7d80b 100644 --- a/src/onaptests/steps/cloud/check_status.py +++ b/src/onaptests/steps/cloud/check_status.py @@ -9,6 +9,7 @@ from pathlib import Path from jinja2 import Environment, PackageLoader, select_autoescape from kubernetes import client, config +from kubernetes.client.exceptions import ApiException from kubernetes.stream import stream from natural.date import delta from onapsdk.configuration import settings @@ -19,8 +20,16 @@ from onaptests.utils.exceptions import StatusCheckException from ..base import BaseStep from .resources import (ConfigMap, Container, DaemonSet, Deployment, Ingress, - Job, Pod, Pvc, ReplicaSet, Secret, Service, - StatefulSet, Node) + Job, Namespace, Node, Pod, Pvc, ReplicaSet, Secret, + Service, StatefulSet, VulnerabilityReport) + + +class K8sResourceSet(set): + """Customized set with append method""" + + def append(self, item): + """Does the same what add does""" + self.add(item) class CheckK8sResourcesStep(BaseStep): @@ -35,6 +44,7 @@ class CheckK8sResourcesStep(BaseStep): self.batch = client.BatchV1Api() self.app = client.AppsV1Api() self.networking = client.NetworkingV1Api() + self.cr = client.CustomObjectsApi() self.namespace = namespace if settings.STATUS_RESULTS_DIRECTORY: @@ -46,12 +56,16 @@ class CheckK8sResourcesStep(BaseStep): self.res_dir = f"{self.res_dir}/{self.namespace}" self.failing = False + self.k8s_issue = "" self.resource_type = resource_type self.k8s_resources = [] - self.all_resources = [] - self.failing_resources = [] - self.jinja_env = Environment(autoescape=select_autoescape(['html']), - loader=PackageLoader('onaptests.templates', 'status')) + self.all_resources = K8sResourceSet() + self.failing_resources = K8sResourceSet() + self.unstable_resources = K8sResourceSet() + if settings.STORE_ARTIFACTS: + self.jinja_env = Environment(autoescape=select_autoescape(['html']), + loader=PackageLoader('onaptests.templates', + 'status')) @property def component(self) -> str: @@ -71,21 +85,45 @@ class CheckK8sResourcesStep(BaseStep): def _init_resources(self): if self.resource_type != "": self.__logger.debug(f"Loading all k8s {self.resource_type}s" - " in the {NAMESPACE} namespace") + f" in the {self.namespace} namespace") def _parse_resources(self): """Parse the resources.""" return [] - def _add_failing_resource(self, resource): + def _propagate_events(self): + pass + + def _analyze_events(self): + for res in self.all_resources: + for event in res.events: + if event.type != "Normal" and event.reason not in settings.WAIVER_EVENTS: + self._add_unstable_resource(res, str(event.reason)) + + def _is_waiver(self, resource): if (hasattr(resource, 'labels') and resource.labels and settings.EXCLUDED_LABELS and (resource.labels.keys() and settings.EXCLUDED_LABELS.keys())): for label in resource.labels.items(): for waived_label in settings.EXCLUDED_LABELS.items(): if label[0] in waived_label[0] and label[1] in waived_label[1]: - return + return True + return False + + def _add_unstable_resource(self, resource, reason=None): + if self._is_waiver(resource): + return + self.__logger.warning("a {} is unstable: {}".format(self.resource_type, resource.name)) + self.unstable_resources.append(resource) + if reason and reason not in resource.unstability_reasons: + resource.unstability_reasons.append(reason) + + def _add_failing_resource(self, resource, reason=None): + if self._is_waiver(resource): + return self.__logger.warning("a {} is in error: {}".format(self.resource_type, resource.name)) self.failing_resources.append(resource) + if reason and reason not in resource.failing_reasons: + resource.failing_reasons.append(reason) self.failing = True def execute(self): @@ -98,16 +136,27 @@ class CheckK8sResourcesStep(BaseStep): len(self.k8s_resources), self.resource_type) self._parse_resources() - self.__logger.info("%4s %ss parsed, %s failing", + self._propagate_events() + self._analyze_events() + self.__logger.info("%4s %ss parsed, %s failing, %s unstable", len(self.all_resources), self.resource_type, - len(self.failing_resources)) + len(self.failing_resources), + len(self.unstable_resources)) if self.failing: raise StatusCheckException(f"{self.resource_type} test failed") except (ConnectionRefusedError, MaxRetryError, NewConnectionError) as e: self.__logger.error("Test of k8s %ss failed.", self.resource_type) self.__logger.error("Cannot connect to Kubernetes.") - raise StatusCheckException from e + self.failing = True + self.k8s_issue = f"K8s API Connection issue: {str(e)}" + raise StatusCheckException(e) from e + except (ApiException) as e: + self.__logger.error("Test of k8s %ss failed.", self.resource_type) + self.__logger.error("K8s API Access issue.") + self.failing = True + self.k8s_issue = f"K8s API Access issue: {str(e)}" + raise StatusCheckException(e) from e class CheckBasicK8sResourcesStep(CheckK8sResourcesStep): @@ -166,6 +215,68 @@ class CheckK8sIngressesStep(CheckBasicK8sResourcesStep): self.k8s_resources = self.networking.list_namespaced_ingress(self.namespace).items +class CheckTrivyVulnerabilitiesStep(CheckK8sResourcesStep): + """Check for trivy CRITICAL vulnerabilities""" + API_GROUP = "aquasecurity.github.io" + API_VERSION = "v1alpha1" + KIND = "vulnerabilityreports" + READABILITY_THRESHOLD = 999999 + + __logger = logging.getLogger(__name__) + + def __init__(self, namespace: str): + """Init CheckTrivyVulnerabilitiesStep.""" + super().__init__(namespace=namespace, resource_type=self.KIND[:-1]) + + def _init_resources(self): + super()._init_resources() + try: + self.k8s_resources = self.cr.list_namespaced_custom_object(namespace=self.namespace, + group=self.API_GROUP, + version=self.API_VERSION, + plural=self.KIND + )['items'] + except Exception as e: + self.__logger.warning(f"Cannot resolve Vulnerability Reports: {str(e)}") + raise StatusCheckException(e) from e + + def _parse_resources(self): + """Parse the vulnerabilityreports. + Return a list of VulnerabilityReports that were created after trivy scan. + """ + super()._parse_resources() + artifacts = set() + vrs_unique = [] + total_crt = 0 + for v in self.k8s_resources: + vr = VulnerabilityReport(v) + if vr.artifact in artifacts: + continue + if vr.crt_count > 0: + total_crt += vr.crt_count + self.__logger.error(f"Vulnerability Report for {vr.owner_kind} " + f"{vr.owner_name} has {vr.crt_count} CRT Vulnerabilities") + artifacts.add(vr.artifact) + vrs_unique.append(vr) + + if len(vrs_unique) > self.READABILITY_THRESHOLD: + ns = Namespace(self.core.read_namespace(self.namespace)) + if total_crt > 0: + self._add_failing_resource( + ns, f"CVE ({total_crt})") + self.all_resources.append(ns) + else: + for vr in vrs_unique: + if vr.crt_count > 0: + self._add_failing_resource( + vr, f"CVE ({vr.crt_count}) [{vr.owner_kind.lower()}-{vr.owner_name}]") + self.all_resources.append(vr) + + @BaseStep.store_state + def execute(self): + super().execute() + + class CheckK8sPvcsStep(CheckK8sResourcesStep): """Check of k8s pvcs in the selected namespace.""" @@ -217,18 +328,37 @@ class CheckK8sNodesStep(CheckK8sResourcesStep): Return a list of Nodes. """ super()._parse_resources() + metrics = [] + try: + metrics = self.cr.list_cluster_custom_object( + "metrics.k8s.io", "v1beta1", "nodes")['items'] + except Exception as e: + self.__logger.warning(f"Cannot resolve metrics for nodes: {str(e)}") for k8s in self.k8s_resources: node = Node(k8s=k8s) for condition in k8s.status.conditions: failing = False - if condition.status == 'False' and condition.type == 'Ready': + if condition.status != 'True' and condition.type == 'Ready': failing = True - elif condition.status == 'True' and condition.type != 'Ready': + elif condition.status != 'False' and condition.type != 'Ready': failing = True if failing: - self._add_failing_resource(node) + self._add_failing_resource(node, condition.reason) self.__logger.error( f"Node {node.name} {condition.type} status is {condition.status}") + node.events = self.core.list_namespaced_event( + "default", + field_selector="involvedObject.name={}".format(node.name)).items + alloc = k8s.status.allocatable + node.details['allocatable'] = { + 'cpu': alloc['cpu'], + 'memory': alloc['memory'], + 'storage': alloc['ephemeral-storage'] + } + for metric in metrics: + if metric['metadata']['name'] == node.name: + node.details['usage'] = metric['usage'] + break self.all_resources.append(node) @BaseStep.store_state @@ -244,6 +374,14 @@ class CheckK8sResourcesUsingPodsStep(CheckK8sResourcesStep): super().__init__(namespace=namespace, resource_type=resource_type) self.pods_source = pods_source + def _propagate_events(self): + if self.resource_type == "pod": + return + for res in self.all_resources: + for pod in res.pods: + for event in pod.events: + res.events.append(event) + def _get_used_pods(self): pods = [] if self.pods_source is not None: @@ -287,7 +425,7 @@ class CheckK8sJobsStep(CheckK8sResourcesUsingPodsStep): super()._init_resources() self.k8s_resources = self.batch.list_namespaced_job(self.namespace).items - def _parse_resources(self): + def _parse_resources(self): # noqa: C901 """Parse the jobs. Return a list of Pods that were created to perform jobs. """ @@ -307,10 +445,9 @@ class CheckK8sJobsStep(CheckK8sResourcesUsingPodsStep): job.events = self.core.list_namespaced_event( self.namespace, field_selector=field_selector).items - - self.jinja_env.get_template('job.html.j2').stream(job=job).dump( - '{}/job-{}.html'.format(self.res_dir, job.name)) - + if settings.STORE_ARTIFACTS: + self.jinja_env.get_template('job.html.j2').stream(job=job).dump( + '{}/job-{}.html'.format(self.res_dir, job.name)) if not any(waiver_elt in job.name for waiver_elt in settings.WAIVER_LIST): cron_job = self._get_cron_job_name(k8s) if cron_job: @@ -318,8 +455,12 @@ class CheckK8sJobsStep(CheckK8sResourcesUsingPodsStep): cron_jobs[cron_job] = [] cron_jobs[cron_job].append(job) elif not k8s.status.completion_time: - # timemout job - self._add_failing_resource(job) + if k8s.status.active and k8s.status.active > 0: + self.__logger.warning( + "Job %s is still running", job.name) + else: + # timemout or failed job + self._add_failing_resource(job) self.all_resources.append(job) else: self.__logger.warning( @@ -331,7 +472,12 @@ class CheckK8sJobsStep(CheckK8sResourcesUsingPodsStep): key=lambda job: job.k8s.metadata.creation_timestamp, reverse=True) if not jobs[0].k8s.status.completion_time: - self._add_failing_resource(jobs[0]) + if jobs[0].k8s.status.active and jobs[0].k8s.status.active > 0: + self.__logger.warning( + "Job %s is still running", job.name) + else: + # timemout or failed job + self._add_failing_resource(jobs[0]) def _get_cron_job_name(self, k8s): if k8s.metadata.owner_references: @@ -458,17 +604,19 @@ class CheckK8sPodsStep(CheckK8sResourcesUsingPodsStep): for k8s_container in k8s.status.container_statuses: pod.running_containers += self._parse_container( pod, k8s_container) + pod.details['node'] = k8s.spec.node_name pod.events = self.core.list_namespaced_event( self.namespace, field_selector="involvedObject.name={}".format(pod.name)).items - self.jinja_env.get_template('pod.html.j2').stream(pod=pod).dump( - '{}/pod-{}.html'.format(self.res_dir, pod.name)) + if settings.STORE_ARTIFACTS: + self.jinja_env.get_template('pod.html.j2').stream(pod=pod).dump( + '{}/pod-{}.html'.format(self.res_dir, pod.name)) if any(waiver_elt in pod.name for waiver_elt in settings.WAIVER_LIST): self.__logger.warning("Waiver pattern found in pod, exclude %s", pod.name) else: self.all_resources.append(pod) - if settings.CHECK_POD_VERSIONS: + if settings.CHECK_POD_VERSIONS and settings.STORE_ARTIFACTS: self.jinja_env.get_template('version.html.j2').stream( pod_versions=pod_versions).dump('{}/versions.html'.format( self.res_dir)) @@ -516,7 +664,7 @@ class CheckK8sPodsStep(CheckK8sResourcesUsingPodsStep): pod.init_done = False else: pod.restart_count = max(pod.restart_count, container.restart_count) - if settings.STORE_ARTIFACTS: + if settings.STORE_LOGS and settings.STORE_ARTIFACTS: try: log_files = {} logs = self._get_container_logs(pod=pod, container=container, full=False) @@ -564,13 +712,14 @@ class CheckK8sPodsStep(CheckK8sResourcesUsingPodsStep): except client.rest.ApiException as exc: self.__logger.warning("%scontainer %s of pod %s has an exception: %s", prefix, container.name, pod.name, exc.reason) - self.jinja_env.get_template('container_log.html.j2').stream( - container=container, - pod_name=pod.name, - logs=logs, - old_logs=old_logs, - log_files=log_files).dump('{}/pod-{}-{}-logs.html'.format( - self.res_dir, pod.name, container.name)) + if settings.STORE_ARTIFACTS: + self.jinja_env.get_template('container_log.html.j2').stream( + container=container, + pod_name=pod.name, + logs=logs, + old_logs=old_logs, + log_files=log_files).dump('{}/pod-{}-{}-logs.html'.format( + self.res_dir, pod.name, container.name)) if any(waiver_elt in container.name for waiver_elt in settings.WAIVER_LIST): self.__logger.warning( "Waiver pattern found in container, exclude %s", container.name) @@ -601,9 +750,10 @@ class CheckK8sServicesStep(CheckK8sResourcesUsingPodsStep): (service.pods, service.failed_pods) = self._find_child_pods(k8s.spec.selector) - self.jinja_env.get_template('service.html.j2').stream( - service=service).dump('{}/service-{}.html'.format( - self.res_dir, service.name)) + if settings.STORE_ARTIFACTS: + self.jinja_env.get_template('service.html.j2').stream( + service=service).dump('{}/service-{}.html'.format( + self.res_dir, service.name)) self.all_resources.append(service) @@ -636,9 +786,10 @@ class CheckK8sDeploymentsStep(CheckK8sResourcesUsingPodsStep): self.namespace, field_selector=field_selector).items - self.jinja_env.get_template('deployment.html.j2').stream( - deployment=deployment).dump('{}/deployment-{}.html'.format( - self.res_dir, deployment.name)) + if settings.STORE_ARTIFACTS: + self.jinja_env.get_template('deployment.html.j2').stream( + deployment=deployment).dump('{}/deployment-{}.html'.format( + self.res_dir, deployment.name)) if k8s.status.unavailable_replicas: self._add_failing_resource(deployment) @@ -676,9 +827,10 @@ class CheckK8sReplicaSetsStep(CheckK8sResourcesUsingPodsStep): self.namespace, field_selector=field_selector).items - self.jinja_env.get_template('replicaset.html.j2').stream( - replicaset=replicaset).dump('{}/replicaset-{}.html'.format( - self.res_dir, replicaset.name)) + if settings.STORE_ARTIFACTS: + self.jinja_env.get_template('replicaset.html.j2').stream( + replicaset=replicaset).dump('{}/replicaset-{}.html'.format( + self.res_dir, replicaset.name)) if (not k8s.status.ready_replicas or (k8s.status.ready_replicas < k8s.status.replicas)): @@ -717,9 +869,10 @@ class CheckK8sStatefulSetsStep(CheckK8sResourcesUsingPodsStep): self.namespace, field_selector=field_selector).items - self.jinja_env.get_template('statefulset.html.j2').stream( - statefulset=statefulset).dump('{}/statefulset-{}.html'.format( - self.res_dir, statefulset.name)) + if settings.STORE_ARTIFACTS: + self.jinja_env.get_template('statefulset.html.j2').stream( + statefulset=statefulset).dump('{}/statefulset-{}.html'.format( + self.res_dir, statefulset.name)) if ((not k8s.status.ready_replicas) or (k8s.status.ready_replicas < k8s.status.replicas)): @@ -755,9 +908,10 @@ class CheckK8sDaemonSetsStep(CheckK8sResourcesUsingPodsStep): self.namespace, field_selector=field_selector).items - self.jinja_env.get_template('daemonset.html.j2').stream( - daemonset=daemonset).dump('{}/daemonset-{}.html'.format( - self.res_dir, daemonset.name)) + if settings.STORE_ARTIFACTS: + self.jinja_env.get_template('daemonset.html.j2').stream( + daemonset=daemonset).dump('{}/daemonset-{}.html'.format( + self.res_dir, daemonset.name)) if k8s.status.number_ready < k8s.status.desired_number_scheduled: self._add_failing_resource(daemonset) @@ -787,6 +941,7 @@ class CheckNamespaceStatusStep(CheckK8sResourcesStep): self.ingress_list_step = None self.pvc_list_step = None self.node_list_step = None + self.vulnerabilityreports_list_step = None if not settings.IF_VALIDATION: if settings.IN_CLUSTER: config.load_incluster_config() @@ -833,6 +988,7 @@ class CheckNamespaceStatusStep(CheckK8sResourcesStep): ingress_list_step = CheckK8sIngressesStep(namespace) pvc_list_step = CheckK8sPvcsStep(namespace) node_list_step = CheckK8sNodesStep(namespace) + vulnerabilityreports_list_step = CheckTrivyVulnerabilitiesStep(namespace) if namespace == settings.K8S_TESTS_NAMESPACE: self.job_list_step = job_list_step self.pod_list_step = pod_list_step @@ -846,7 +1002,9 @@ class CheckNamespaceStatusStep(CheckK8sResourcesStep): self.ingress_list_step = ingress_list_step self.pvc_list_step = pvc_list_step self.node_list_step = node_list_step + self.vulnerabilityreports_list_step = vulnerabilityreports_list_step self.add_step(node_list_step) + self.add_step(vulnerabilityreports_list_step) self.add_step(job_list_step) self.add_step(pod_list_step) self.add_step(service_list_step) @@ -876,7 +1034,7 @@ class CheckNamespaceStatusStep(CheckK8sResourcesStep): Use settings values: - K8S_TESTS_NAMESPACE - STATUS_RESULTS_DIRECTORY - - STORE_ARTIFACTS + - STORE_LOGS - CHECK_POD_VERSIONS - IGNORE_EMPTY_REPLICAS - INCLUDE_ALL_RES_IN_DETAILS @@ -902,12 +1060,13 @@ class CheckNamespaceStatusStep(CheckK8sResourcesStep): self.failing_daemonsets = self.daemonset_list_step.failing_resources self.failing_pvcs = self.pvc_list_step.failing_resources - self.jinja_env.get_template('index.html.j2').stream( - ns=self, - delta=delta).dump('{}/index.html'.format(self.res_dir)) - self.jinja_env.get_template('raw_output.txt.j2').stream( - ns=self, namespace=self.namespace).dump('{}/onap-k8s.log'.format( - self.res_dir)) + if settings.STORE_ARTIFACTS: + self.jinja_env.get_template('index.html.j2').stream( + ns=self, + delta=delta).dump('{}/index.html'.format(self.res_dir)) + self.jinja_env.get_template('raw_output.txt.j2').stream( + ns=self, namespace=self.namespace).dump('{}/onap-k8s.log'.format( + self.res_dir)) details = {"namespace": { "all": list(self.namespaces_to_check_set - set([self.namespace])), @@ -917,7 +1076,14 @@ class CheckNamespaceStatusStep(CheckK8sResourcesStep): def store_results(result_dict, step): result_dict[step.resource_type] = { 'number_failing': len(step.failing_resources), - 'failing': self.map_by_name(step.failing_resources) + 'failing': self.map_by_name(step.failing_resources), + 'failing_reasons': self.map_by_failing_reasons(step.failing_resources), + 'number_unstable': len(step.unstable_resources), + 'unstable': self.map_by_name(step.unstable_resources), + 'unstable_reasons': self.map_by_unstability_reasons( + step.unstable_resources), + 'details': self.map_by_details(step.all_resources), + 'k8s_issue': step.k8s_issue } if settings.INCLUDE_ALL_RES_IN_DETAILS: result_dict[step.resource_type]['all'] = self.map_by_name(step.all_resources) @@ -947,3 +1113,18 @@ class CheckNamespaceStatusStep(CheckK8sResourcesStep): def map_by_name(self, resources): """Get resources' names.""" return list(map(lambda resource: resource.name, resources)) + + def map_by_failing_reasons(self, resources): + """Get resources' failing reasons.""" + return dict(map(lambda resource: (resource.name, resource.failing_reasons), + resources)) + + def map_by_unstability_reasons(self, resources): + """Get resources' instability reasons.""" + return dict(map(lambda resource: (resource.name, resource.unstability_reasons), + resources)) + + def map_by_details(self, resources): + """Get resources' details.""" + return dict(map(lambda resource: (resource.name, resource.details), + resources)) diff --git a/src/onaptests/steps/cloud/cloud_region_create.py b/src/onaptests/steps/cloud/cloud_region_create.py index fcda251..afed216 100644 --- a/src/onaptests/steps/cloud/cloud_region_create.py +++ b/src/onaptests/steps/cloud/cloud_region_create.py @@ -11,7 +11,7 @@ class CloudRegionCreateStep(BaseStep): def __init__(self): """Initialize step.""" - super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + super().__init__(cleanup=settings.CLEANUP_FLAG) @property def description(self) -> str: @@ -54,3 +54,18 @@ class CloudRegionCreateStep(BaseStep): owner_defined_type=settings.CLOUD_OWNER_DEFINED_TYPE, complex_name=settings.COMPLEX_PHYSICAL_LOCATION_ID ) + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + + """Cleanup created cloud region.""" + self._logger.info("Clean the cloud region") + try: + cloud_region = CloudRegion.get_by_id( + cloud_owner=settings.CLOUD_REGION_CLOUD_OWNER, + cloud_region_id=settings.CLOUD_REGION_ID, + ) + cloud_region.delete() + except ResourceNotFound: + self._logger.info("Resource trying to delete is not available..") + super().cleanup() diff --git a/src/onaptests/steps/cloud/cloud_region_upadte.py b/src/onaptests/steps/cloud/cloud_region_upadte.py new file mode 100644 index 0000000..e9a3c27 --- /dev/null +++ b/src/onaptests/steps/cloud/cloud_region_upadte.py @@ -0,0 +1,101 @@ +"""A&AI cloud region updation module.""" +from onapsdk.aai.cloud_infrastructure import CloudRegion +from onapsdk.configuration import settings +from onapsdk.exceptions import APIError + +from onaptests.utils.exceptions import OnapTestException + +from ..base import BaseStep + + +class CloudRegionUpdateStep(BaseStep): + """Cloud region update step.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + @property + def description(self) -> str: + """Step description.""" + return "Update cloud region." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" + + @BaseStep.store_state + def execute(self): + """Update cloud region. + + Use settings values: + - CLOUD_REGION_CLOUD_OWNER, + - CLOUD_REGION_ID, + - UPDATED_CLOUD_TYPE, + - CLOUD_REGION_VERSION, + - UPDATED_CLOUD_OWNER_DEFINED_TYPE, + - COMPLEX_PHYSICAL_LOCATION_ID. + + """ + super().execute() + self._logger.info("*Check if cloud region exists *") + + cloud_region = CloudRegion.get_by_id( + cloud_owner=settings.CLOUD_REGION_CLOUD_OWNER, + cloud_region_id=settings.CLOUD_REGION_ID, + ) + cloud_region.update( + cloud_owner=settings.CLOUD_REGION_CLOUD_OWNER, + cloud_region_id=settings.CLOUD_REGION_ID, + orchestration_disabled=False, + in_maint=False, + cloud_type=settings.UPDATED_CLOUD_TYPE, + cloud_region_version=settings.CLOUD_REGION_VERSION, + owner_defined_type=settings.UPDATED_CLOUD_OWNER_DEFINED_TYPE, + complex_name=settings.COMPLEX_PHYSICAL_LOCATION_ID + ) + + +class CloudRegionGetByIDStep(BaseStep): + """Cloud region getting by id step.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + @property + def description(self) -> str: + """Step description.""" + return "Get cloud region by ID." + + @property + def component(self) -> str: + """Component name. + + Name of component which step is related with. + Most is the name of ONAP component. + + Returns: + str: Component name + + """ + return "AAI" + + @BaseStep.store_state + def execute(self): + """Get cloud region by id. + + Use settings values: + - CLOUD_REGION_CLOUD_OWNER, + - CLOUD_REGION_ID. + """ + super().execute() + self._logger.info("*Check if cloud region exists *") + try: + CloudRegion.get_by_id( + cloud_owner=settings.CLOUD_REGION_CLOUD_OWNER, + cloud_region_id=settings.CLOUD_REGION_ID + ) + except APIError as exc: + raise OnapTestException("Getting cloud region is failed.") from exc diff --git a/src/onaptests/steps/cloud/complex_create.py b/src/onaptests/steps/cloud/complex_create.py index 7afad16..e9f1069 100644 --- a/src/onaptests/steps/cloud/complex_create.py +++ b/src/onaptests/steps/cloud/complex_create.py @@ -1,6 +1,6 @@ from onapsdk.aai.cloud_infrastructure import Complex from onapsdk.configuration import settings -from onapsdk.exceptions import APIError +from onapsdk.exceptions import APIError, ResourceNotFound from ..base import BaseStep @@ -10,7 +10,7 @@ class ComplexCreateStep(BaseStep): def __init__(self): """Initialize step.""" - super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + super().__init__(cleanup=settings.CLEANUP_FLAG) @property def description(self) -> str: @@ -32,10 +32,28 @@ class ComplexCreateStep(BaseStep): """ super().execute() + self._logger.info("*Check if complex exists *") try: + Complex.get_by_physical_location_id(settings.COMPLEX_PHYSICAL_LOCATION_ID) + self._logger.info("Requested resource Available in AAI .") + except ResourceNotFound: + self._logger.warning("if requested resource not available create it") Complex.create( physical_location_id=settings.COMPLEX_PHYSICAL_LOCATION_ID, data_center_code=settings.COMPLEX_DATA_CENTER_CODE, name=settings.COMPLEX_PHYSICAL_LOCATION_ID) except APIError: self._logger.warning("Try to update the complex failed.") + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + + """Cleanup created complex.""" + self._logger.info("Clean the complex") + try: + complex_instance = Complex.get_by_physical_location_id( + settings.COMPLEX_PHYSICAL_LOCATION_ID) + complex_instance.delete() + except ResourceNotFound: + self._logger.info("Resource trying to delete is not available..") + super().cleanup() diff --git a/src/onaptests/steps/cloud/complex_update.py b/src/onaptests/steps/cloud/complex_update.py new file mode 100644 index 0000000..faa37e1 --- /dev/null +++ b/src/onaptests/steps/cloud/complex_update.py @@ -0,0 +1,42 @@ +from onapsdk.aai.cloud_infrastructure import Complex +from onapsdk.configuration import settings + +from ..base import BaseStep + + +class ComplexUpdateStep(BaseStep): + """Complex update step.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + @property + def description(self) -> str: + """Step description.""" + return "Update complex." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" + + @BaseStep.store_state + def execute(self): + """Update complex. + + Use settings values: + - COMPLEX_PHYSICAL_LOCATION_ID, + - COMPLEX_DATA_CENTER_CODE. + - UPDATED_PHYSICAL_LOCATION_TYPE + + """ + super().execute() + self._logger.info("*Check if complex exists *") + complex_instance = Complex.get_by_physical_location_id( + settings.COMPLEX_PHYSICAL_LOCATION_ID) + complex_instance.update( + physical_location_id=settings.COMPLEX_PHYSICAL_LOCATION_ID, + physical_location_type=settings.UPDATED_PHYSICAL_LOCATION_TYPE, + data_center_code=settings.COMPLEX_DATA_CENTER_CODE, + name=settings.COMPLEX_PHYSICAL_LOCATION_ID) diff --git a/src/onaptests/steps/cloud/connect_service_subscription_to_cloud_region.py b/src/onaptests/steps/cloud/connect_service_subscription_to_cloud_region.py index 2bc206d..1581d34 100644 --- a/src/onaptests/steps/cloud/connect_service_subscription_to_cloud_region.py +++ b/src/onaptests/steps/cloud/connect_service_subscription_to_cloud_region.py @@ -45,7 +45,6 @@ class ConnectServiceSubToCloudRegionStep(BaseStep): Use settings values: - GLOBAL_CUSTOMER_ID, - - SERVICE_NAME, - CLOUD_REGION_CLOUD_OWNER, - CLOUD_REGION_ID. @@ -54,7 +53,7 @@ class ConnectServiceSubToCloudRegionStep(BaseStep): customer: Customer = Customer.get_by_global_customer_id( settings.GLOBAL_CUSTOMER_ID) service_subscription: ServiceSubscription = \ - customer.get_service_subscription_by_service_type(settings.SERVICE_NAME) + customer.get_service_subscription_by_service_type(self.service_type) cloud_region: CloudRegion = CloudRegion.get_by_id( cloud_owner=settings.CLOUD_REGION_CLOUD_OWNER, cloud_region_id=settings.CLOUD_REGION_ID, diff --git a/src/onaptests/steps/cloud/customer_create.py b/src/onaptests/steps/cloud/customer_create.py index 7bffb1a..b86df5d 100644 --- a/src/onaptests/steps/cloud/customer_create.py +++ b/src/onaptests/steps/cloud/customer_create.py @@ -1,6 +1,6 @@ from onapsdk.aai.business import Customer from onapsdk.configuration import settings -from onapsdk.exceptions import APIError +from onapsdk.exceptions import APIError, ResourceNotFound from ..base import BaseStep @@ -10,7 +10,7 @@ class CustomerCreateStep(BaseStep): def __init__(self): """Initialize step.""" - super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + super().__init__(cleanup=settings.CLEANUP_FLAG) @property def description(self) -> str: @@ -29,8 +29,26 @@ class CustomerCreateStep(BaseStep): Use settings values: - GLOBAL_CUSTOMER_ID. """ + super().execute() + self._logger.info("*Check if customer exists *") try: + Customer.get_by_global_customer_id(settings.GLOBAL_CUSTOMER_ID) + self._logger.warning("Requested resource Available in AAI .") + except ResourceNotFound: + self._logger.warning("if requested resource not available, create it") Customer.create(settings.GLOBAL_CUSTOMER_ID, settings.GLOBAL_CUSTOMER_ID, "INFRA") except APIError: self._logger.warning("Try to update the Customer failed.") + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + + """Cleanup created customer.""" + self._logger.info("Clean the customer") + try: + customer = Customer.get_by_global_customer_id(settings.GLOBAL_CUSTOMER_ID) + customer.delete() + except ResourceNotFound: + self._logger.info("Resource trying to delete is not available..") + super().cleanup() diff --git a/src/onaptests/steps/cloud/customer_service_subscription_create.py b/src/onaptests/steps/cloud/customer_service_subscription_create.py index 170f033..9ebd80f 100644 --- a/src/onaptests/steps/cloud/customer_service_subscription_create.py +++ b/src/onaptests/steps/cloud/customer_service_subscription_create.py @@ -1,6 +1,6 @@ -from onapsdk.aai.business import Customer +from onapsdk.aai.business import Customer, ServiceSubscription from onapsdk.configuration import settings -from onapsdk.sdc.service import Service +from onapsdk.exceptions import ResourceNotFound from ..base import BaseStep from .customer_create import CustomerCreateStep @@ -15,7 +15,7 @@ class CustomerServiceSubscriptionCreateStep(BaseStep): Substeps: - CustomerCreateStep. """ - super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + super().__init__(cleanup=settings.CLEANUP_FLAG) self.add_step(CustomerCreateStep()) @property @@ -37,6 +37,19 @@ class CustomerServiceSubscriptionCreateStep(BaseStep): - SERVICE_NAME. """ super().execute() - service = Service(name=settings.SERVICE_NAME) customer = Customer.get_by_global_customer_id(settings.GLOBAL_CUSTOMER_ID) - customer.subscribe_service(service.name) + customer.subscribe_service(self.service_type) + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + + """Cleanup created service subscription.""" + self._logger.info("Clean the service subscription") + try: + customer = Customer.get_by_global_customer_id(settings.GLOBAL_CUSTOMER_ID) + service_subscription: ServiceSubscription = \ + customer.get_service_subscription_by_service_type(self.service_type) + customer.delete_subscribed_service(service_subscription) + except ResourceNotFound: + self._logger.info("Resource trying to delete is not available..") + super().cleanup() diff --git a/src/onaptests/steps/cloud/customer_update.py b/src/onaptests/steps/cloud/customer_update.py new file mode 100644 index 0000000..95cb266 --- /dev/null +++ b/src/onaptests/steps/cloud/customer_update.py @@ -0,0 +1,36 @@ +from onapsdk.aai.business import Customer +from onapsdk.configuration import settings + +from ..base import BaseStep + + +class CustomerUpdateStep(BaseStep): + """Customer update step.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + @property + def description(self) -> str: + """Step description.""" + return "Update customer." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" + + @BaseStep.store_state + def execute(self): + """Update cutomer. + + Use settings values: + - GLOBAL_CUSTOMER_ID, + - UPDATED_SUBSCRIBER_TYPE + """ + + super().execute() + self._logger.info("*Check if customer exists *") + customer = Customer.get_by_global_customer_id(settings.GLOBAL_CUSTOMER_ID) + customer.update(settings.GLOBAL_CUSTOMER_ID, settings.UPDATED_SUBSCRIBER_TYPE, "INFRA") diff --git a/src/onaptests/steps/cloud/expose_service_node_port.py b/src/onaptests/steps/cloud/expose_service_node_port.py index db5b646..6f26da2 100644 --- a/src/onaptests/steps/cloud/expose_service_node_port.py +++ b/src/onaptests/steps/cloud/expose_service_node_port.py @@ -19,7 +19,7 @@ class ExposeServiceNodePortStep(BaseStep): """Initialize step.""" super().__init__(cleanup=settings.CLEANUP_FLAG) self.component_value = component - self.service_name = service_name + self.k8s_service_name = service_name self.port = port self.node_port = node_port self.k8s_client: client.CoreV1Api = None @@ -45,7 +45,7 @@ class ExposeServiceNodePortStep(BaseStep): """ try: service_data: Dict[str, Any] = self.k8s_client.read_namespaced_service( - self.service_name, + self.k8s_service_name, settings.K8S_TESTS_NAMESPACE ) return service_data.spec.type == "NodePort" @@ -72,7 +72,7 @@ class ExposeServiceNodePortStep(BaseStep): if not self.is_service_node_port_type(): try: self.k8s_client.patch_namespaced_service( - self.service_name, + self.k8s_service_name, settings.K8S_TESTS_NAMESPACE, {"spec": {"ports": [{"port": self.port, "nodePort": self.node_port}], @@ -97,7 +97,7 @@ class ExposeServiceNodePortStep(BaseStep): if self.is_service_node_port_type(): try: self.k8s_client.patch_namespaced_service( - self.service_name, + self.k8s_service_name, settings.K8S_TESTS_NAMESPACE, [ { diff --git a/src/onaptests/steps/cloud/lineofbusiness_create.py b/src/onaptests/steps/cloud/lineofbusiness_create.py new file mode 100644 index 0000000..94b8101 --- /dev/null +++ b/src/onaptests/steps/cloud/lineofbusiness_create.py @@ -0,0 +1,53 @@ +from onapsdk.aai.business import LineOfBusiness +from onapsdk.configuration import settings +from onapsdk.exceptions import ResourceNotFound + +from ..base import BaseStep + + +class LineofBusinessCreateStep(BaseStep): + """LineofBusiness creation step.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=settings.CLEANUP_FLAG) + + @property + def description(self) -> str: + """Step description.""" + return "Create LineofBusiness." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" + + @BaseStep.store_state + def execute(self): + """Create LineofBusiness. + + Use settings values: + - LINE_OF_BUSINESS + + """ + super().execute() + self._logger.info("*Check if LOB exists *") + try: + LineOfBusiness.get_by_name(settings.LINE_OF_BUSINESS) + self._logger.warning("Requested Resource Available in AAI .") + except ResourceNotFound: + self._logger.warning("if requested resource not available, create it") + LineOfBusiness.create(settings.LINE_OF_BUSINESS) + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + super().cleanup() + + # Cleanup created line of business. + self._logger.info("Clean the line of business") + try: + line_of_business = LineOfBusiness.get_by_name(settings.LINE_OF_BUSINESS) + line_of_business.delete() + except ResourceNotFound: + self._logger.info("Resource trying to delete is not available..") + super().cleanup() diff --git a/src/onaptests/steps/cloud/link_cloud_to_complex.py b/src/onaptests/steps/cloud/link_cloud_to_complex.py index 8f5dad6..23b757a 100644 --- a/src/onaptests/steps/cloud/link_cloud_to_complex.py +++ b/src/onaptests/steps/cloud/link_cloud_to_complex.py @@ -15,7 +15,7 @@ class LinkCloudRegionToComplexStep(BaseStep): - ComplexCreateStep, - CloudRegionCreateStep. """ - super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + super().__init__(cleanup=settings.CLEANUP_FLAG) self.add_step(ComplexCreateStep()) @property @@ -47,3 +47,25 @@ class LinkCloudRegionToComplexStep(BaseStep): cloud_region_id=settings.CLOUD_REGION_ID, ) cloud_region.link_to_complex(cmplx) + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + """Unlink cloud region and complex. + + Delete previously created relationship + Use settings values: + - COMPLEX_PHYSICAL_LOCATION_ID, + - CLOUD_REGION_CLOUD_OWNER, + - CLOUD_REGION_ID. + + """ + cmplx = Complex( + physical_location_id=settings.COMPLEX_PHYSICAL_LOCATION_ID, + name=settings.COMPLEX_PHYSICAL_LOCATION_ID + ) + cloud_region = CloudRegion.get_by_id( + cloud_owner=settings.CLOUD_REGION_CLOUD_OWNER, + cloud_region_id=settings.CLOUD_REGION_ID, + ) + cloud_region.unlink_complex(cmplx) + return super().cleanup() diff --git a/src/onaptests/steps/cloud/link_cloudregion_to_project.py b/src/onaptests/steps/cloud/link_cloudregion_to_project.py new file mode 100644 index 0000000..6cf253a --- /dev/null +++ b/src/onaptests/steps/cloud/link_cloudregion_to_project.py @@ -0,0 +1,70 @@ +import logging + +from onapsdk.aai.business.project import Project +from onapsdk.aai.cloud_infrastructure import CloudRegion +from onapsdk.configuration import settings +from onapsdk.exceptions import ResourceNotFound + +from ..base import BaseStep +from .cloud_region_create import CloudRegionCreateStep +from .project_create import ProjectCreateStep + + +class LinkCloudRegionToProjectStep(BaseStep): + """Link cloud region to project step""" + + __logger = logging.getLogger(__name__) + + def __init__(self): + """Initialize step. + + Substeps: + - ProjectCreateStep, + - CloudRegionCreateStep. + """ + super().__init__(cleanup=settings.CLEANUP_FLAG) + self.add_step(ProjectCreateStep()) + self.add_step(CloudRegionCreateStep()) + + @property + def description(self) -> str: + """Step description.""" + return "Connect cloud region with project." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" + + @BaseStep.store_state + def execute(self): + """Link cloud region to project. + + Use settings values: + - PROJECT + - CLOUD_REGION_CLOUD_OWNER, + - CLOUD_REGION_ID. + """ + super().execute() + project = Project.get_by_name(settings.PROJECT) + cloud_region = CloudRegion.get_by_id( + cloud_owner=settings.CLOUD_REGION_CLOUD_OWNER, + cloud_region_id=settings.CLOUD_REGION_ID, + ) + self.__logger.info("Link between cloud region and project is going to be created") + cloud_region.link_to_project(project) + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + """Cleanup created platform.""" + self._logger.info("Clean the relationship") + try: + cloud_region = CloudRegion.get_by_id( + cloud_owner=settings.CLOUD_REGION_CLOUD_OWNER, + cloud_region_id=settings.CLOUD_REGION_ID, + ) + project = Project.get_by_name(settings.PROJECT) + cloud_region.delete_project(project) + except ResourceNotFound: + self._logger.info("One of resource from relationship is not available..") + super().cleanup() diff --git a/src/onaptests/steps/cloud/link_lineofbusiness_to_tenant.py b/src/onaptests/steps/cloud/link_lineofbusiness_to_tenant.py new file mode 100644 index 0000000..773a9d1 --- /dev/null +++ b/src/onaptests/steps/cloud/link_lineofbusiness_to_tenant.py @@ -0,0 +1,74 @@ +import logging + +from onapsdk.aai.business import LineOfBusiness +from onapsdk.aai.cloud_infrastructure import CloudRegion +from onapsdk.configuration import settings +from onapsdk.exceptions import ResourceNotFound + +from ..base import BaseStep +from .lineofbusiness_create import LineofBusinessCreateStep +from .tenant_create import TenantCreateStep + + +class LinkLineOfBusinessToTenantStep(BaseStep): + """Link line of busniess to tenant step""" + + __logger = logging.getLogger(__name__) + + def __init__(self) -> None: + """Initialize step. + + Substeps: + - LineofBusinessCreateStep, + - TenantCreateStep. + """ + super().__init__(cleanup=settings.CLEANUP_FLAG) + self.add_step(LineofBusinessCreateStep()) + self.add_step(TenantCreateStep()) + + @property + def description(self) -> str: + """Step description.""" + return "Connect line of business with tenant." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" + + @BaseStep.store_state + def execute(self): + """Link line of business to tenant. + + Use settings values: + - TENANT_ID + - TENANT_NAME, + - CLOUD_REGION_CLOUD_OWNER, + - CLOUD_REGION_ID. + """ + super().execute() + cloud_region = CloudRegion.get_by_id( + cloud_owner=settings.CLOUD_REGION_CLOUD_OWNER, + cloud_region_id=settings.CLOUD_REGION_ID, + ) + tenant = cloud_region.get_tenant(tenant_id=settings.TENANT_ID) + line_of_business = LineOfBusiness.get_by_name(name=settings.LINE_OF_BUSINESS) + self.__logger.info("Creating relationship between line of business and tenant") + line_of_business.link_to_tenant(tenant) + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + + """Cleanup created platform.""" + self._logger.info("Clean the platform") + try: + cloud_region = CloudRegion.get_by_id( + cloud_owner=settings.CLOUD_REGION_CLOUD_OWNER, + cloud_region_id=settings.CLOUD_REGION_ID, + ) + tenant = cloud_region.get_tenant(tenant_id=settings.TENANT_ID) + line_of_business = LineOfBusiness.get_by_name(name=settings.LINE_OF_BUSINESS) + line_of_business.delete_relationship_with_tenant(tenant) + except ResourceNotFound: + self._logger.info("One of resource from relationship is not available..") + super().cleanup() diff --git a/src/onaptests/steps/cloud/link_owningentity_to_tenant.py b/src/onaptests/steps/cloud/link_owningentity_to_tenant.py new file mode 100644 index 0000000..1b05d57 --- /dev/null +++ b/src/onaptests/steps/cloud/link_owningentity_to_tenant.py @@ -0,0 +1,74 @@ +import logging + +from onapsdk.aai.business import OwningEntity +from onapsdk.aai.cloud_infrastructure import CloudRegion +from onapsdk.configuration import settings +from onapsdk.exceptions import ResourceNotFound + +from ..base import BaseStep +from .owning_entity_create import OwningEntityCreateStep +from .tenant_create import TenantCreateStep + + +class LinkOwningEntityToTenantStep(BaseStep): + """Link owning entity to tenant step""" + + __logger = logging.getLogger(__name__) + + def __init__(self) -> None: + """Initialize step. + + Substeps: + - OwningEntityCreateStep, + - TenantCreateStep. + """ + super().__init__(cleanup=settings.CLEANUP_FLAG) + self.add_step(OwningEntityCreateStep()) + self.add_step(TenantCreateStep()) + + @property + def description(self) -> str: + """Step description.""" + return "Connect owning entity with tenant." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" + + @BaseStep.store_state + def execute(self): + """Link owning entity to tenant. + + Use settings values: + - TENANT_ID + - TENANT_NAME, + - CLOUD_REGION_CLOUD_OWNER, + - CLOUD_REGION_ID. + """ + super().execute() + cloud_region = CloudRegion.get_by_id( + cloud_owner=settings.CLOUD_REGION_CLOUD_OWNER, + cloud_region_id=settings.CLOUD_REGION_ID, + ) + tenant = cloud_region.get_tenant(tenant_id=settings.TENANT_ID) + owning_entity = OwningEntity.get_by_owning_entity_id(settings.OWNING_ENTITY_ID) + self.__logger.info("Creating relationship between owning entity and tenant") + owning_entity.link_to_tenant(tenant) + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + + """Cleanup created platform.""" + self._logger.info("Clean the platform") + try: + cloud_region = CloudRegion.get_by_id( + cloud_owner=settings.CLOUD_REGION_CLOUD_OWNER, + cloud_region_id=settings.CLOUD_REGION_ID, + ) + tenant = cloud_region.get_tenant(tenant_id=settings.TENANT_ID) + owning_entity = OwningEntity.get_by_owning_entity_id(settings.OWNING_ENTITY_ID) + owning_entity.delete_relationship_with_tenant(tenant) + except ResourceNotFound: + self._logger.info("One of resource from relationship is not available..") + super().cleanup() diff --git a/src/onaptests/steps/cloud/owning_entity_create.py b/src/onaptests/steps/cloud/owning_entity_create.py new file mode 100644 index 0000000..f1ccd93 --- /dev/null +++ b/src/onaptests/steps/cloud/owning_entity_create.py @@ -0,0 +1,53 @@ +from onapsdk.aai.business import OwningEntity +from onapsdk.configuration import settings +from onapsdk.exceptions import ResourceNotFound + +from ..base import BaseStep + + +class OwningEntityCreateStep(BaseStep): + """OwningEntity creation step.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=settings.CLEANUP_FLAG) + + @property + def description(self) -> str: + """Step description.""" + return "Create OwningEntity." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" + + @BaseStep.store_state + def execute(self): + """Create OwningEntity. + + Use settings values: + - OWNING_ENTITY + + """ + + super().execute() + self._logger.info("*Check if Owning Entity exists *") + try: + OwningEntity.get_by_owning_entity_id(settings.OWNING_ENTITY_ID) + self._logger.warning("Requested Resource Available in AAI .") + except ResourceNotFound: + self._logger.warning("if requested resource not available, create it") + OwningEntity.create(settings.OWNING_ENTITY_NAME, settings.OWNING_ENTITY_ID) + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + super().cleanup() + # Cleanup created owning entity. + self._logger.info("Clean the owning entity") + try: + own_entity = OwningEntity.get_by_owning_entity_id(settings.OWNING_ENTITY_ID) + own_entity.delete() + except ResourceNotFound: + self._logger.info("Resource trying to delete is not available..") + super().cleanup() diff --git a/src/onaptests/steps/cloud/owning_entity_update.py b/src/onaptests/steps/cloud/owning_entity_update.py new file mode 100644 index 0000000..c1665c8 --- /dev/null +++ b/src/onaptests/steps/cloud/owning_entity_update.py @@ -0,0 +1,35 @@ +from onapsdk.aai.business import OwningEntity +from onapsdk.configuration import settings + +from ..base import BaseStep + + +class OwningEntityUpdateStep(BaseStep): + """OwningEntity update step.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + @property + def description(self) -> str: + """Step description.""" + return "Update OwningEntity." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" + + @BaseStep.store_state + def execute(self): + """update OwningEntity. + + Use settings values: + - OWNING_ENTITY + + """ + super().execute() + self._logger.info("*Check if Owning Entity exists *") + owning_entity = OwningEntity.get_by_owning_entity_id(settings.OWNING_ENTITY_ID) + owning_entity.update(settings.UPDATED_OWNING_ENTITY_NAME, owning_entity.owning_entity_id) diff --git a/src/onaptests/steps/cloud/platform_create.py b/src/onaptests/steps/cloud/platform_create.py new file mode 100644 index 0000000..9724885 --- /dev/null +++ b/src/onaptests/steps/cloud/platform_create.py @@ -0,0 +1,53 @@ +from onapsdk.aai.business import Platform +from onapsdk.configuration import settings +from onapsdk.exceptions import ResourceNotFound + +from ..base import BaseStep + + +class PlatformCreateStep(BaseStep): + """Platform creation step.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=settings.CLEANUP_FLAG) + + @property + def description(self) -> str: + """Step description.""" + return "Create Platform." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" + + @BaseStep.store_state + def execute(self): + """Create Platform. + + Use settings values: + - PLATFORM + + """ + + super().execute() + self._logger.info("*Check if Platform exists *") + try: + Platform.get_by_name(settings.PLATFORM) + self._logger.info("Requested Resource Available in AAI .") + except ResourceNotFound: + self._logger.warning("if requested resource not available, create it") + Platform.create(settings.PLATFORM) + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + + """Cleanup created platform.""" + self._logger.info("Clean the platform") + try: + platform = Platform.get_by_name(settings.PLATFORM) + platform.delete() + except ResourceNotFound: + self._logger.info("Resource trying to delete is not available..") + super().cleanup() diff --git a/src/onaptests/steps/cloud/project_create.py b/src/onaptests/steps/cloud/project_create.py new file mode 100644 index 0000000..0943855 --- /dev/null +++ b/src/onaptests/steps/cloud/project_create.py @@ -0,0 +1,53 @@ +from onapsdk.aai.business import Project +from onapsdk.configuration import settings +from onapsdk.exceptions import ResourceNotFound + +from ..base import BaseStep + + +class ProjectCreateStep(BaseStep): + """Project creation step.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=settings.CLEANUP_FLAG) + + @property + def description(self) -> str: + """Step description.""" + return "Create Project." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" + + @BaseStep.store_state + def execute(self): + """Create Project. + + Use settings values: + - PROJECT + + """ + + super().execute() + self._logger.info("*Check if Project exists *") + try: + Project.get_by_name(settings.PROJECT) + self._logger.warning("Requested Resource Available in AAI .") + except ResourceNotFound: + self._logger.warning("if requested resource not available, create it") + Project.create(settings.PROJECT) + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + + """Cleanup created project.""" + self._logger.info("Clean the project") + try: + project = Project.get_by_name(settings.PROJECT) + project.delete() + except ResourceNotFound: + self._logger.info("Resource trying to delete is not available..") + super().cleanup() diff --git a/src/onaptests/steps/cloud/publish_pnf_reg_event_to_kafka.py b/src/onaptests/steps/cloud/publish_pnf_reg_event_to_kafka.py new file mode 100644 index 0000000..14afd48 --- /dev/null +++ b/src/onaptests/steps/cloud/publish_pnf_reg_event_to_kafka.py @@ -0,0 +1,57 @@ +import json +from pathlib import Path + +from jinja2 import Environment, FileSystemLoader +from onapsdk.configuration import settings +from onapsdk.exceptions import (APIError, ConnectionFailed, RequestError, + ResourceNotFound) +from onapsdk.kafka import onap_kafka + +from onaptests.utils.exceptions import OnapTestException +from onaptests.utils.kubernetes_kafka import KubernetesKafka + +from ..base import BaseStep + + +class PublishVESRegistrationEventToKafkaStep(BaseStep): + """Step to publish VES Registration event on kafka""" + + @property + def description(self) -> str: + return "Step to publish VES Registration event on kafka" + + @property + def component(self) -> str: + return "Kafka" + + @BaseStep.store_state + def execute(self) -> None: + """Publish a VES Registration event on kafka by calling its REST API""" + + super().execute() + + environment = Environment(loader=FileSystemLoader((Path(__file__).parent.parent.parent) + .joinpath("templates/artifacts/"))) + template = environment.get_template("pnf_registration_dmaap_event_template.json.j2") + + reg_event_parameters = { + "sourceName": settings.PNF_NAME, + "serialNumber": settings.PNF_SERIAL_NUMBER, + "oamV6IpAddress": settings.PNF_IPADDRESS_V6_OAM, + "oamV4IpAddress": settings.PNF_IPADDRESS_V4_OAM + } + reg_event = template.render(reg_event_parameters) + reg_event_list = json.loads(reg_event) + formatted_json_data = json.dumps(reg_event_list[0], separators=(',', ':')) + + reader = KubernetesKafka() + reader.read_kafka_admin_secret() + kafka_password = reader.get_kafka_admin_password() + + try: + onap_kafka.publish_event_on_topic(settings.KAFKA_USER, kafka_password, + formatted_json_data.encode('utf-8'), + settings.PNF_REGISTRATION_TOPIC_NAME) + except (RequestError, ResourceNotFound, APIError, ConnectionFailed) as exc: + self._logger.error("Error while publishing event via kafka") + raise OnapTestException(exc) from exc diff --git a/src/onaptests/steps/cloud/register_cloud.py b/src/onaptests/steps/cloud/register_cloud.py index 00af163..56b9a28 100644 --- a/src/onaptests/steps/cloud/register_cloud.py +++ b/src/onaptests/steps/cloud/register_cloud.py @@ -2,7 +2,7 @@ import time from uuid import uuid4 -from onapsdk.aai.cloud_infrastructure import CloudRegion +from onapsdk.aai.cloud_infrastructure import CloudRegion, Tenant from onapsdk.configuration import settings from onapsdk.exceptions import ResourceNotFound @@ -20,7 +20,7 @@ class RegisterCloudRegionStep(BaseStep): Substeps: - CloudRegionCreateStep. """ - super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + super().__init__(cleanup=settings.CLEANUP_FLAG) self.add_step(CloudRegionCreateStep()) @property @@ -38,13 +38,17 @@ class RegisterCloudRegionStep(BaseStep): """Register cloud region. Use settings values: + - AVAILABILITY_ZONE_NAME, + - AVAILABILITY_ZONE_TYPE, - CLOUD_REGION_CLOUD_OWNER, - CLOUD_REGION_ID, - CLOUD_DOMAIN, - VIM_USERNAME, - VIM_PASSWORD, - VIM_SERVICE_URL, - - TENANT_NAME. + - TENANT_NAME, + - TENANT_ID, + - USE_MULTICLOUD. """ super().execute() cloud_region: CloudRegion = CloudRegion.get_by_id( @@ -102,3 +106,24 @@ class RegisterCloudRegionStep(BaseStep): cloud_region.add_availability_zone( settings.AVAILABILITY_ZONE_NAME, settings.AVAILABILITY_ZONE_TYPE) + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + """Cleanup cloud region registration step.""" + self._logger.info("Clean after cloud region registration") + try: + cloud_region = CloudRegion.get_by_id( + cloud_owner=settings.CLOUD_REGION_CLOUD_OWNER, + cloud_region_id=settings.CLOUD_REGION_ID, + ) + if settings.USE_MULTICLOUD: + cloud_region.unregister_from_multicloud() + else: + try: + tenant: Tenant = cloud_region.get_tenant(settings.TENANT_ID) + tenant.delete() + except ResourceNotFound: + self._logger.info("Tenant does not exist") + except ResourceNotFound: + self._logger.info("Resource trying to delete is not available..") + return super().cleanup() diff --git a/src/onaptests/steps/cloud/resources.py b/src/onaptests/steps/cloud/resources.py index c0cdfe8..23c01bc 100644 --- a/src/onaptests/steps/cloud/resources.py +++ b/src/onaptests/steps/cloud/resources.py @@ -4,17 +4,25 @@ class K8sResource(): """K8sResource class.""" - def __init__(self, k8s=None): + def __init__(self, k8s=None, cr=False): """Init the k8s resource.""" self.k8s = k8s self.name = "" self.events = [] + self.failing_reasons = [] + self.unstability_reasons = [] + self.details = {} self.labels = None self.annotations = None if self.k8s: - self.name = self.k8s.metadata.name - self.labels = self.k8s.metadata.labels - self.annotations = self.k8s.metadata.annotations + if cr: + self.name = self.k8s['metadata']['name'] + self.labels = self.k8s['metadata'].get('labels', {}) + self.annotations = self.k8s['metadata'].get('annotations', {}) + else: + self.name = self.k8s.metadata.name + self.labels = self.k8s.metadata.labels + self.annotations = self.k8s.metadata.annotations self.specific_k8s_init() if not self.labels: self.labels = {} @@ -35,6 +43,9 @@ class K8sResource(): return self.name == other.name return False + def __hash__(self): + return hash(self.name) + class K8sPodParentResource(K8sResource): """K8sPodParentResource class.""" @@ -130,6 +141,30 @@ class Service(K8sPodParentResource): self.type = self.k8s.spec.type +class VulnerabilityReport(K8sResource): + """VulnerabilityReport class.""" + + def __init__(self, k8s=None): + """Init the service.""" + self.type = "" + super().__init__(k8s=k8s, cr=True) + + def specific_k8s_init(self): + """Do the specific part for VulnerabilityReport when k8s object is present.""" + self.owner_name = "" + self.owner_kind = "" + self.crt_count = 0 + self.artifact = "" + if self.k8s['metadata'].get('ownerReferences'): + self.owner_name = self.k8s['metadata'].get('ownerReferences')[0]['name'] + self.owner_kind = self.k8s['metadata'].get('ownerReferences')[0]['kind'] + if self.k8s['report']['summary'].get('criticalCount'): + self.crt_count = self.k8s['report']['summary'].get('criticalCount', 0) + self.artifact = (f"{self.k8s['report']['artifact']['repository']}:" + f"{self.k8s['report']['artifact']['tag']}" + ) + + class Job(K8sPodParentResource): """Job class.""" @@ -168,3 +203,7 @@ class Ingress(K8sResource): class Node(K8sResource): """Node class.""" + + +class Namespace(K8sResource): + """Namespace class.""" diff --git a/src/onaptests/steps/cloud/service_subscription_update.py b/src/onaptests/steps/cloud/service_subscription_update.py new file mode 100644 index 0000000..9f7d178 --- /dev/null +++ b/src/onaptests/steps/cloud/service_subscription_update.py @@ -0,0 +1,36 @@ +from onapsdk.aai.business import Customer +from onapsdk.configuration import settings + +from ..base import BaseStep + + +class ServiceSubscriptionUpdateStep(BaseStep): + """ServiceSubscription update step.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + @property + def description(self) -> str: + """Step description.""" + return "Update ServiceSubscription." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" + + @BaseStep.store_state + def execute(self): + """Update ServiceSubscription. + + Use settings values: + - GLOBAL_CUSTOMER_ID, + - UPDATED_SUBSCRIBER_TYPE + """ + + super().execute() + self._logger.info("*Check if 5G customer is exists *") + customer = Customer.get_by_global_customer_id(settings.GLOBAL_CUSTOMER_ID) + customer.update(settings.GLOBAL_CUSTOMER_ID, settings.UPDATED_SUBSCRIBER_TYPE, "5G") diff --git a/src/onaptests/steps/cloud/tenant_create.py b/src/onaptests/steps/cloud/tenant_create.py new file mode 100644 index 0000000..eda3ce7 --- /dev/null +++ b/src/onaptests/steps/cloud/tenant_create.py @@ -0,0 +1,65 @@ +from onapsdk.aai.cloud_infrastructure import CloudRegion +from onapsdk.configuration import settings +from onapsdk.exceptions import ResourceNotFound + +from ..base import BaseStep +from .cloud_region_create import CloudRegionCreateStep + + +class TenantCreateStep(BaseStep): + """Tenant creation step.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=settings.CLEANUP_FLAG) + self.add_step(CloudRegionCreateStep()) + + @property + def description(self) -> str: + """Step description.""" + return "Create Tenant." + + @property + def component(self) -> str: + """Component name.""" + return "AAI" + + @BaseStep.store_state + def execute(self): + """Create Tenant. + + Use settings values: + - COMPLEX_PHYSICAL_LOCATION_ID, + - COMPLEX_DATA_CENTER_CODE. + + """ + super().execute() + self._logger.info("*Check if tenant exists *") + cloud_region = CloudRegion.get_by_id( + cloud_owner=settings.CLOUD_REGION_CLOUD_OWNER, + cloud_region_id=settings.CLOUD_REGION_ID, + ) + try: + tenant = cloud_region.get_tenant(tenant_id=settings.TENANT_ID) + self._logger.info("Requested resource Available in AAI .") + tenant.delete() + except ResourceNotFound: + self._logger.warning("if requested resource not available create it") + cloud_region.add_tenant(tenant_id=settings.TENANT_ID, + tenant_name=settings.TENANT_NAME) + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + + """Cleanup created tenant.""" + self._logger.info("Clean the Tenant") + try: + cloud_region = CloudRegion.get_by_id( + cloud_owner=settings.CLOUD_REGION_CLOUD_OWNER, + cloud_region_id=settings.CLOUD_REGION_ID, + ) + tenant = cloud_region.get_tenant(tenant_id=settings.TENANT_ID) + tenant.delete() + except ResourceNotFound: + self._logger.info("Resource trying to delete is not available..") + super().cleanup() diff --git a/src/onaptests/steps/instantiate/k8s_profile_create.py b/src/onaptests/steps/instantiate/k8s_profile_create.py index 9630ec4..6a93f40 100644 --- a/src/onaptests/steps/instantiate/k8s_profile_create.py +++ b/src/onaptests/steps/instantiate/k8s_profile_create.py @@ -68,6 +68,23 @@ class K8SProfileStep(BaseStep): return next(iter(self.yaml_template.keys())) return self.parent.service_name + @property + def service_type(self) -> str: + """Service type. + + Gets from YAML template if it's a root step, gets from parent otherwise. + If YAML template has no service_type key returns service name otherwise. + + Returns: + str: Service type + + """ + if self.is_root: + if "service_type" in self.yaml_template[self.service_name]: + return self.yaml_template[self.service_name]["service_type"] + return self.service_name + return self.parent.service_type + @property def service_instance_name(self) -> str: """Service instance name. @@ -119,7 +136,7 @@ class K8SProfileStep(BaseStep): super().execute() customer: Customer = Customer.get_by_global_customer_id(settings.GLOBAL_CUSTOMER_ID) service_subscription: ServiceSubscription = \ - customer.get_service_subscription_by_service_type(self.service_name) + customer.get_service_subscription_by_service_type(self.service_type) self._service_instance: ServiceInstance = \ service_subscription.get_service_instance_by_name(self.service_instance_name) diff --git a/src/onaptests/steps/instantiate/service_ala_carte.py b/src/onaptests/steps/instantiate/service_ala_carte.py index e3aac8a..a31d3b5 100644 --- a/src/onaptests/steps/instantiate/service_ala_carte.py +++ b/src/onaptests/steps/instantiate/service_ala_carte.py @@ -139,10 +139,12 @@ class YamlTemplateServiceAlaCarteInstantiateStep(YamlTemplateBaseStep): service_instantiation.wait_for_finish(settings.ORCHESTRATION_REQUEST_TIMEOUT) except TimeoutError as exc: self._logger.error("Service instantiation %s timed out", self.service_instance_name) - raise onap_test_exceptions.ServiceCleanupException from exc + raise onap_test_exceptions.ServiceInstantiateException( + "Timeout on instatiation") from exc if service_instantiation.failed: self._logger.error("Service instantiation %s failed", self.service_instance_name) - raise onap_test_exceptions.ServiceInstantiateException + raise onap_test_exceptions.ServiceInstantiateException( + service_instantiation.status_message) self._load_customer_and_subscription(reload=True) self._load_service_instance() @@ -153,12 +155,14 @@ class YamlTemplateServiceAlaCarteInstantiateStep(YamlTemplateBaseStep): service_deletion.wait_for_finish(settings.ORCHESTRATION_REQUEST_TIMEOUT) except TimeoutError as exc: self._logger.error("Service deletion %s timed out", self._service_instance_name) - raise onap_test_exceptions.ServiceCleanupException from exc + raise onap_test_exceptions.ServiceCleanupException( + "Timeout on cleanup") from exc if service_deletion.finished: self._logger.info("Service %s deleted", self._service_instance_name) else: self._logger.error("Service deletion %s failed", self._service_instance_name) - raise onap_test_exceptions.ServiceCleanupException + raise onap_test_exceptions.ServiceCleanupException( + service_deletion.status_message) @YamlTemplateBaseStep.store_state(cleanup=True) def cleanup(self) -> None: diff --git a/src/onaptests/steps/instantiate/service_macro.py b/src/onaptests/steps/instantiate/service_macro.py index 047acb8..0bfab64 100644 --- a/src/onaptests/steps/instantiate/service_macro.py +++ b/src/onaptests/steps/instantiate/service_macro.py @@ -1,6 +1,9 @@ + +import time from typing import List from uuid import uuid4 +from jinja2 import Environment, PackageLoader, select_autoescape from onapsdk.aai.business.owning_entity import OwningEntity from onapsdk.aai.cloud_infrastructure.cloud_region import CloudRegion from onapsdk.aai.cloud_infrastructure.tenant import Tenant @@ -10,14 +13,16 @@ from onapsdk.sdc.service import Service from onapsdk.so.instantiation import (InstantiationParameter, ServiceInstantiation, SoService, VfmoduleParameters, VnfParameters) +from onapsdk.ves.ves import Ves from yaml import SafeLoader, load import onaptests.utils.exceptions as onap_test_exceptions -from onaptests.steps.base import YamlTemplateBaseStep +from onaptests.steps.base import BaseStep, YamlTemplateBaseStep from onaptests.steps.cloud.connect_service_subscription_to_cloud_region import \ ConnectServiceSubToCloudRegionStep from onaptests.steps.cloud.customer_service_subscription_create import \ CustomerServiceSubscriptionCreateStep +from onaptests.steps.cloud.onap_operator_cr_check import CheckOnapVnfCr from onaptests.steps.instantiate.sdnc_service import TestSdncStep from onaptests.steps.onboard.service import (VerifyServiceDistributionStep, YamlTemplateServiceOnboardStep) @@ -144,6 +149,7 @@ class YamlTemplateServiceMacroInstantiateBaseStep(YamlTemplateBaseStep): cloud_region_id=settings.CLOUD_REGION_ID, ) tenant: Tenant = cloud_region.get_tenant(settings.TENANT_ID) + self._logger.info("inside if vnfs/networks ") else: # Only PNF is going to be instantiated so # neither cloud_region nor tenant are needed @@ -158,12 +164,15 @@ class YamlTemplateServiceMacroInstantiateBaseStep(YamlTemplateBaseStep): so_service = None vnf_params_list: List[VnfParameters] = [] if settings.MODEL_YAML_TEMPLATE: + self._logger.info("inside if settings.MODEL_YAML_TEMPLATE ") so_data = self.yaml_template[self.service_name] so_service = SoService(vnfs=so_data.get("vnfs", []), subscription_service_type=so_data.get( 'subscription_service_type')) else: + self._logger.info("inside else settings.MODEL_YAML_TEMPLATE ") for vnf_data in self.yaml_template[self.service_name].get("vnfs", []): + self._logger.info("getting vnf data ") vnf_params_list.append(VnfParameters( vnf_data["vnf_name"], [InstantiationParameter(name=parameter["name"], @@ -187,6 +196,24 @@ class YamlTemplateServiceMacroInstantiateBaseStep(YamlTemplateBaseStep): tenant, owning_entity, so_service, skip_pnf_registration_event, vnf_params_list) +class YamlTemplateServiceOperatorInstantiateStep(YamlTemplateServiceMacroInstantiateBaseStep): + """Instantiate SO service with Operator.""" + + def __init__(self): + """Init YamlTemplateServiceOperatorInstantiateStep.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + self.add_step(CheckOnapVnfCr(service_macro_base=self)) + + @property + def description(self) -> str: + """Step description.""" + return "Instantiate SO service with Operator" + + @YamlTemplateBaseStep.store_state + def execute(self): + super().execute() + + class YamlTemplateServiceMacroInstantiateStep(YamlTemplateServiceMacroInstantiateBaseStep): """Instantiate SO service.""" @@ -203,7 +230,7 @@ class YamlTemplateServiceMacroInstantiateStep(YamlTemplateServiceMacroInstantiat def execute(self): super().execute() (service, _, _, cloud_region, tenant, owning_entity, so_service, - _, vnf_params_list) = self.base_execute() + skip_pnf_registration_event, vnf_params_list) = self.base_execute() # remove leftover self._cleanup_logic() @@ -220,16 +247,27 @@ class YamlTemplateServiceMacroInstantiateStep(YamlTemplateServiceMacroInstantiat service_instance_name=self.service_instance_name, vnf_parameters=vnf_params_list, enable_multicloud=settings.USE_MULTICLOUD, - so_service=so_service + so_service=so_service, + skip_pnf_registration_event=skip_pnf_registration_event ) + try: + if settings.PNF_WITH_VES: + time.sleep(settings.SERVICE_DISTRIBUTION_SLEEP_TIME) + Ves.send_event(version="v7", json_event=self.get_ves_payload_from_file(), + basic_auth={'username': 'sample1', 'password': 'sample1'}) + except SDKException: + self._logger.info("Not required to wait for VES event") + try: service_instantiation.wait_for_finish(timeout=settings.ORCHESTRATION_REQUEST_TIMEOUT) except TimeoutError as exc: self._logger.error("Service instantiation %s timed out", self.service_instance_name) - raise onap_test_exceptions.ServiceInstantiateException from exc + raise onap_test_exceptions.ServiceInstantiateException( + "Timeout on instatiation") from exc if service_instantiation.failed: self._logger.error("Service instantiation %s failed", self.service_instance_name) - raise onap_test_exceptions.ServiceInstantiateException + raise onap_test_exceptions.ServiceInstantiateException( + service_instantiation.status_message) self._load_customer_and_subscription(reload=True) self._load_service_instance() @@ -241,12 +279,14 @@ class YamlTemplateServiceMacroInstantiateStep(YamlTemplateServiceMacroInstantiat service_deletion.wait_for_finish(timeout=settings.ORCHESTRATION_REQUEST_TIMEOUT) except TimeoutError as exc: self._logger.error("Service deletion %s timed out", self._service_instance_name) - raise onap_test_exceptions.ServiceCleanupException from exc + raise onap_test_exceptions.ServiceCleanupException( + "Timeout on cleanup") from exc if service_deletion.finished: self._logger.info("Service %s deleted", self._service_instance_name) else: self._logger.error("Service deletion %s failed", self._service_instance_name) - raise onap_test_exceptions.ServiceCleanupException + raise onap_test_exceptions.ServiceCleanupException( + service_deletion.status_message) @YamlTemplateBaseStep.store_state(cleanup=True) def cleanup(self) -> None: @@ -260,3 +300,15 @@ class YamlTemplateServiceMacroInstantiateStep(YamlTemplateServiceMacroInstantiat self._load_service_instance() self._cleanup_logic() super().cleanup() + + def get_ves_payload_from_file(self) -> str: + """Get ves payload from file.""" + + jinja_env = Environment(autoescape=select_autoescape(['json.j2']), + loader=PackageLoader('onaptests.templates', + 'artifacts')) + template = jinja_env.get_template("pnf_instantiation_ves_event.json.j2") + ves_event_json = template.render( + source_name=self.service_instance_name) + + return ves_event_json diff --git a/src/onaptests/steps/instantiate/so/add_cnf_in_service.py b/src/onaptests/steps/instantiate/so/add_cnf_in_service.py new file mode 100644 index 0000000..8c8265e --- /dev/null +++ b/src/onaptests/steps/instantiate/so/add_cnf_in_service.py @@ -0,0 +1,89 @@ +from onapsdk.aai.business.service import ServiceInstance +from onapsdk.aai.cloud_infrastructure import CloudRegion +from onapsdk.configuration import settings +from onapsdk.sdc.service import Service +from onapsdk.so.instantiation import VnfInstantiation + +import onaptests.utils.exceptions as onap_test_exceptions +from onaptests.steps.base import BaseStep +from onaptests.steps.instantiate.so.add_delete_cnf_base_step import \ + AddDeleteCnfInService +from onaptests.steps.instantiate.so.delete_cnf_in_service import \ + DeleteCnfMacroFromService + + +class AddCnfInService(AddDeleteCnfInService): + """Add CNF in running service using YAML template.""" + + def __init__(self): + """Initialize step.""" + super().__init__() + self._cnf_instantiation: VnfInstantiation = None + self.add_step(DeleteCnfMacroFromService()) + + @property + def description(self) -> str: + """Step description.""" + return "Add CNF in running service using SO macro method." + + @BaseStep.store_state + def execute(self): + + """Instantiate CNF. + Use settings values: + - GLOBAL_CUSTOMER_ID, + - SERVICE_NAME, + - LINE_OF_BUSINESS, + - PLATFORM, + - CLOUD_REGION_ID, + - SERVICE_INSTANCE_NAME, + - TENANT_ID. + + Raises: + Exception: Service instantiation failed + + """ + # global service + super().execute() + service: Service = Service(self.service_name) + self._load_customer_and_subscription() + self._load_service_instance() + cloud_region = (CloudRegion. + get_by_id(settings.CLOUD_REGION_CLOUD_OWNER, settings.CLOUD_REGION_ID)) + + tenant = cloud_region.get_tenant(settings.TENANT_ID) + + # using existing VNF related functions for getting and adding CNF, + # as processing in SO is same for both + cnf = next(service.vnfs) + + self._cnf_instantiation = ServiceInstance.add_vnf( + self=self._service_instance, + vnf=cnf, + line_of_business=settings.LINE_OF_BUSINESS, + platform=settings.PLATFORM, + cloud_region=cloud_region, + tenant=tenant, + vnf_instance_name=settings.CNF_INSTANCE_NAME, + a_la_carte=False + + ) + + try: + self._cnf_instantiation.wait_for_finish(timeout=settings.ORCHESTRATION_REQUEST_TIMEOUT) + except TimeoutError as exc: + self._logger.error("CNF instantiation %s timed out", self._cnf_instantiation.name) + raise onap_test_exceptions.VnfInstantiateException( + "Timeout on instantiation") from exc + if self._cnf_instantiation.failed: + self._logger.error("CNF instantiation %s failed", self._cnf_instantiation.name) + raise onap_test_exceptions.VnfInstantiateException( + self._cnf_instantiation.status_message) + + cnf_inst = next(self._service_instance.vnf_instances) + if cnf_inst.vnf_name == settings.CNF_INSTANCE_NAME: + self._logger.debug("CNF added successfully") + else: + self._logger.debug("CNF not added successfully") + raise onap_test_exceptions.VnfInstantiateException( + self._cnf_instantiation.status_message) diff --git a/src/onaptests/steps/instantiate/so/add_delete_cnf_base_step.py b/src/onaptests/steps/instantiate/so/add_delete_cnf_base_step.py new file mode 100644 index 0000000..870e64d --- /dev/null +++ b/src/onaptests/steps/instantiate/so/add_delete_cnf_base_step.py @@ -0,0 +1,62 @@ +from uuid import uuid4 + +import yaml +from onapsdk.configuration import settings + +from onaptests.steps.base import BaseStep, YamlTemplateBaseStep + + +class AddDeleteCnfInService(YamlTemplateBaseStep): + """Add CNF in running service using YAML template.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + self._yaml_template = None + self._service_instance_name: str = None + + @property + def description(self) -> str: + """Step description.""" + return "Add and Delete CNF in running service using SO macro method." + + @property + def component(self) -> str: + """Component name.""" + return "SO" + + @property + def model_yaml_template(self) -> dict: + return {} + + @property + def service_instance_name(self) -> str: + """Service instance name. + + Generate using `service_name` and `uuid4()` function if it's a root step, + get from parent otherwise. + + Returns: + str: Service instance name + + """ + if self.is_root: + if not self._service_instance_name: + self._service_instance_name: str = f"{self.service_name}-{str(uuid4())}" + return self._service_instance_name + return self.parent.service_instance_name + + @property + def yaml_template(self) -> dict: + """YAML template abstract property. + + Every YAML template step need to implement that property. + + Returns: + dict: YAML template + + """ + if not self._yaml_template: + with open(settings.SERVICE_YAML_TEMPLATE, "r", encoding="utf-8") as yaml_template: + self._yaml_template: dict = yaml.safe_load(yaml_template) + return self._yaml_template diff --git a/src/onaptests/steps/instantiate/so/add_pnf_in_service.py b/src/onaptests/steps/instantiate/so/add_pnf_in_service.py new file mode 100644 index 0000000..36225dd --- /dev/null +++ b/src/onaptests/steps/instantiate/so/add_pnf_in_service.py @@ -0,0 +1,125 @@ +import time + +import yaml +from onapsdk.aai.business import PnfInstance +from onapsdk.aai.business.customer import Customer, ServiceSubscription +from onapsdk.aai.business.service import ServiceInstance +from onapsdk.configuration import settings +from onapsdk.sdc.service import Pnf +from onapsdk.so.instantiation import (PnfInstantiation, + PnfRegistrationParameters, SoServicePnf) + +from onaptests.steps.base import BaseStep, YamlTemplateBaseStep + + +class AddPnfInService(YamlTemplateBaseStep): + """Add PNF in running service using YAML template.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + self._yaml_template = None + self._pnf_instantiation = None + self._service_instance_id: str = None + self._service_instance: ServiceInstance = None + self._pnf_instance: PnfInstance = None + self._pnf_id: str = None + + @property + def description(self) -> str: + """Step description.""" + return "Add PNF in running service using SO macro method." + + @property + def component(self) -> str: + """Component name.""" + return "SO" + + @property + def model_yaml_template(self) -> dict: + return {} + + @property + def yaml_template(self) -> dict: + """YAML template abstract property. + + Every YAML template step need to implement that property. + + Returns: + dict: YAML template + + """ + if not self._yaml_template: + with open(settings.SERVICE_YAML_TEMPLATE, "r", encoding="utf-8") as yaml_template: + self._yaml_template: dict = yaml.safe_load(yaml_template) + return self._yaml_template + + @BaseStep.store_state + def execute(self): + + """Instantiate pnf. + Use settings values: + - GLOBAL_CUSTOMER_ID, + - CLOUD_REGION_CLOUD_OWNER, + - OWNING_ENTITY, + - PROJECT. + + Raises: + Exception: Service instantiation failed + + """ + # global service + super().execute() + self._logger.info("Adding pnf from running service") + customer: Customer = Customer.get_by_global_customer_id(settings.GLOBAL_CUSTOMER_ID) + self._logger.info("got customer") + + service_subscription: ServiceSubscription = \ + customer.get_service_subscription_by_service_type(self.service_type) + + self._logger.info("got service_subscription") + + self._service_instance = \ + service_subscription.get_service_instance_by_name(settings.SERVICE_INSTANCE_NAME) + + self._logger.info("service instance name " + self._service_instance.instance_name) + service = self._service_instance.sdc_service + self._logger.info("sdc service " + service.name) + + pnf: Pnf = next(service.pnfs) + + so_pnf = SoServicePnf( + model_name="test_so_service_pnf_model_name_1", + instance_name="test_so_service_pnf_instance_name_1", + registration_parameters=PnfRegistrationParameters( + model_number="test_model_number", + oam_v4_ip_address="test_ip", + oam_v6_ip_address="test_mac", + serial_number="test_serial_number", + software_version="test_software_version", + unit_type="test_unit_type", + vendor_name="test_vendor" + ) + ) + + self._logger.info("Got pnf and calling add...." + pnf.name) + + self._pnf_instantiation = PnfInstantiation.instantiate_macro( + aai_service_instance=self._service_instance, + pnf_object=pnf, + line_of_business=settings.LINE_OF_BUSINESS, + platform=settings.PLATFORM, + sdc_service=service, + so_pnf=so_pnf + ) + + self._logger.info("after calling add") + if self._pnf_instantiation.status == self._pnf_instantiation.StatusEnum.IN_PROGRESS: + time.sleep(settings.PNF_WAIT_TIME) + + if self._pnf_instantiation.status == self._pnf_instantiation.StatusEnum.COMPLETED: + self._logger.error("Status Completed ") + + if self._pnf_instantiation.status == self._pnf_instantiation.StatusEnum.FAILED: + self._logger.error("Status Failed ") diff --git a/src/onaptests/steps/instantiate/so/delete_cnf_in_service.py b/src/onaptests/steps/instantiate/so/delete_cnf_in_service.py new file mode 100644 index 0000000..7fc5f9d --- /dev/null +++ b/src/onaptests/steps/instantiate/so/delete_cnf_in_service.py @@ -0,0 +1,77 @@ +from onapsdk.aai.business import VnfInstance +from onapsdk.configuration import settings + +import onaptests.utils.exceptions as onap_test_exceptions +from onaptests.scenario.basic_cnf_macro import BasicCnfMacroStep +from onaptests.steps.base import BaseStep +from onaptests.steps.instantiate.so.add_delete_cnf_base_step import \ + AddDeleteCnfInService + + +class DeleteCnfMacroFromService(AddDeleteCnfInService): + """Delete CNF in service.""" + + def __init__(self): + """Initialize step.""" + super().__init__() + self._cnf_instance: VnfInstance = None + self.add_step(BasicCnfMacroStep()) + + @property + def description(self) -> str: + """Step description.""" + return "Delete CNF in running service using SO macro method." + + @BaseStep.store_state + def execute(self): + + """Delete CNF in running service. + + ==== + Args: + + Returns: + cnfDeletion: cnfInstantiation object + ==== + Use settings values: + - GLOBAL_CUSTOMER_ID, + - SERVICE_NAME, + - SERVICE_INSTANCE_NAME. + + Raises: + Exception: Service deletion failed + + """ + # global service + super().execute() + self._load_customer_and_subscription() + self._load_service_instance() + + # using existing VNF related functions for getting and deleting CNF, + # as processing in SO is same for both + self._cnf_instance = next(self._service_instance.vnf_instances) + + cnf_deletion = self._cnf_instance.delete(a_la_carte=False) + + try: + cnf_deletion.wait_for_finish(timeout=settings.ORCHESTRATION_REQUEST_TIMEOUT) + except TimeoutError as exc: + self._logger.error("CNF deletion %s timed out", cnf_deletion.name) + raise onap_test_exceptions.VnfCleanupException( + "Timeout on cleanup") from exc + if cnf_deletion.finished: + self._logger.info("CNF %s deleted", cnf_deletion.name) + else: + self._logger.error("CNF deletion %s failed", cnf_deletion.name) + raise onap_test_exceptions.VnfCleanupException( + cnf_deletion.status_message) + + try: + next(self._service_instance.vnf_instances) + # if control reaches here, throw exception to fail the step as no CNF + # is expected to be present in the service_instance + raise onap_test_exceptions.VnfCleanupException( + cnf_deletion.status_message) + except StopIteration: + # this exception is expected as no CNF should present in servie_instance + self._logger.debug("CNF deleted successfully") diff --git a/src/onaptests/steps/instantiate/so/delete_pnf_in_service.py b/src/onaptests/steps/instantiate/so/delete_pnf_in_service.py new file mode 100644 index 0000000..ddc92ab --- /dev/null +++ b/src/onaptests/steps/instantiate/so/delete_pnf_in_service.py @@ -0,0 +1,107 @@ +import time + +import yaml +from onapsdk.aai.business import PnfInstance +from onapsdk.aai.business.customer import Customer, ServiceSubscription +from onapsdk.aai.business.service import ServiceInstance +from onapsdk.configuration import settings +from onapsdk.so.instantiation import ServiceInstantiation + +from onaptests.steps.base import BaseStep, YamlTemplateBaseStep + + +class DeletePnfMacroInService(YamlTemplateBaseStep): + """Delete pnf in service.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + self._yaml_template = None + self._service_instance_id: str = None + self._service_instance_name = None + self._service_instance: ServiceInstance = None + self._pnf_instance: PnfInstance = None + self._pnf_id: str = None + + @property + def description(self) -> str: + """Step description.""" + return "Delete pnf in running service using SO macro method." + + @property + def component(self) -> str: + """Component name.""" + return "SO" + + @property + def model_yaml_template(self) -> dict: + return {} + + @property + def yaml_template(self) -> dict: + """YAML template abstract property. + + Every YAML template step need to implement that property. + + Returns: + dict: YAML template + + """ + if not self._yaml_template: + with open(settings.SERVICE_YAML_TEMPLATE, "r", encoding="utf-8") as yaml_template: + self._yaml_template: dict = yaml.safe_load(yaml_template) + return self._yaml_template + + @BaseStep.store_state + def execute(self): + + """Delete pnf in running service. + + ==== + Args: + + Returns: + pnfDeletion: pnfInstantiation object +==== + Use settings values: + - GLOBAL_CUSTOMER_ID, + - SERVICE_SUBSCRIPTION, + - OWNING_ENTITY, + - PROJECT. + + Raises: + Exception: Service deletion failed + + """ + # global service + super().execute() + self._logger.info("Deleting pnf from running service") + customer_pnf: Customer = Customer.get_by_global_customer_id(settings.GLOBAL_CUSTOMER_ID) + service_sub_pnf: ServiceSubscription = \ + customer_pnf.get_service_subscription_by_service_type(self.service_type) + + self._logger.info("got customer and sub") + service_instance_pnf = service_sub_pnf.get_service_instance_by_name( + settings.SERVICE_INSTANCE_NAME) + + self._logger.info("got pnf instance " + service_instance_pnf.instance_name) + + self._pnf_instance = service_instance_pnf.pnfs.__next__() + + self._logger.info("pnf instance present" + self._pnf_instance.name) + + pnf_deletion = self._pnf_instance.delete(a_la_carte=False) + + self._logger.info("After pnf_deletion") + + if pnf_deletion.status == ServiceInstantiation.StatusEnum.IN_PROGRESS: + time.sleep(settings.PNF_WAIT_TIME) + + if pnf_deletion.status == ServiceInstantiation.StatusEnum.COMPLETED: + self._logger.error("Status Completed ") + + if pnf_deletion.status == ServiceInstantiation.StatusEnum.FAILED: + self._logger.error("Status Failed ") + + self._logger.info("pnf deleted successfully") diff --git a/src/onaptests/steps/instantiate/so/generic_network_step.py b/src/onaptests/steps/instantiate/so/generic_network_step.py new file mode 100644 index 0000000..0111017 --- /dev/null +++ b/src/onaptests/steps/instantiate/so/generic_network_step.py @@ -0,0 +1,156 @@ +import yaml +from onapsdk.aai.business import VnfInstance +from onapsdk.aai.business.customer import Customer, ServiceSubscription +from onapsdk.aai.business.service import ServiceInstance +from onapsdk.aai.cloud_infrastructure import CloudRegion, Tenant +from onapsdk.configuration import settings +from onapsdk.sdc.service import Network, Vnf +from onapsdk.so.instantiation import NetworkDetails, NetworkDetailsElement + +import onaptests.utils.exceptions as onap_test_exceptions +from onaptests.steps.base import BaseStep, YamlTemplateBaseStep + + +class GenericNetworkStep(YamlTemplateBaseStep): + """Add generic network in existing VNF using YAML template.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + self._service_instance_name = None + self._yaml_template = None + self._service_instance_id: str = None + self._service_instance: ServiceInstance = None + self.network_instantiation = None + self.vnf_id: str = None + self._vnf_instance: VnfInstance = None + + @property + def description(self) -> str: + """Step description.""" + return "Add generic networks in existing VNF." + + @property + def component(self) -> str: + """Component name.""" + return "SO" + + @property + def model_yaml_template(self) -> dict: + return {} + + @property + def yaml_template(self) -> dict: + """YAML template abstract property. + + Every YAML template step need to implement that property. + + Returns: + dict: YAML template + + """ + if not self._yaml_template: + with open(settings.SERVICE_YAML_TEMPLATE, "r", encoding="utf-8") as yaml_template: + self._yaml_template: dict = yaml.safe_load(yaml_template) + return self._yaml_template + + @YamlTemplateBaseStep.store_state + def execute(self): + + """Instantiate pnf. + Use settings values: + - GLOBAL_CUSTOMER_ID, + - CLOUD_REGION_CLOUD_OWNER, + - OWNING_ENTITY, + - PROJECT. + + Raises: + Exception: Service instantiation failed + + """ + # global service + super().execute() + self._logger.info("Generic Network Step") + customer: Customer = Customer.get_by_global_customer_id(settings.GLOBAL_CUSTOMER_ID) + self._logger.info("got customer") + service_subscription: ServiceSubscription = \ + customer.get_service_subscription_by_service_type(self.service_type) + self._logger.info("got service_subscription") + self._service_instance = \ + service_subscription.get_service_instance_by_name(settings.SERVICE_INSTANCE_NAME) + self._vnf_instance = next(self._service_instance.vnf_instances) + self._logger.info("service instance name " + self._service_instance.instance_name) + service = self._service_instance.sdc_service + self._logger.info("sdc service " + service.name) + vnf: Vnf = next(service.vnfs) + vnf_id = self._vnf_instance.vnf_id + # get network details object + network_details: NetworkDetails = self.getnetworkdetails(vnf_id) + self._logger.info("got VNF details " + network_details.vnf_id) + network: Network = next(service.networks) + self._logger.info("Got vnf with name...." + vnf.name) + cloud_region: CloudRegion = CloudRegion.get_by_id( + cloud_owner=settings.CLOUD_REGION_CLOUD_OWNER, + cloud_region_id=settings.CLOUD_REGION_ID, + ) + tenant: Tenant = cloud_region.get_tenant(settings.TENANT_ID) + self.network_instantiation = ServiceInstance.add_network( + self._service_instance, + network=network, + line_of_business=settings.LINE_OF_BUSINESS, + platform=settings.PLATFORM, + cloud_region=cloud_region, + tenant=tenant, + a_la_carte=False, + network_details=network_details + ) + self._logger.info("after calling add") + try: + self.network_instantiation. \ + wait_for_finish(timeout=settings.ORCHESTRATION_REQUEST_TIMEOUT) + except TimeoutError as exc: + self._logger.error("Service instantiation %s timed out", self._service_instance_name) + raise onap_test_exceptions.ServiceInstantiateException( + "Timeout on instatiation") from exc + + if self.network_instantiation.status == self.network_instantiation.StatusEnum.FAILED: + self._logger.error("Service instantiation %s failed", self._service_instance_name) + raise onap_test_exceptions.ServiceInstantiateException( + self.network_instantiation.status_message) + + def getnetworkdetails(self, vnf_id: str = None) -> NetworkDetails: + """Get generic network details. + + Args: + vnf_id(str): vnf id in which we need to add network resources. + + Returns: + NetworkDetails: NetworkDetails object + + """ + return NetworkDetails( + network_type="generic-vnf", + vnf_id=vnf_id, + child_resources=[ + NetworkDetailsElement(network_details_element_type="l-interface", + network_details_element_parameters={ + "interface-name": "equinix-internal_test", + "interface-type": "internal", + "is-port-mirrored": "", + "in-maint": "", + "is-ip-unnumbered": "", + "l2-multicasting": "" + }), + NetworkDetailsElement(network_details_element_type="l-interface", + network_details_element_parameters={ + "interface-name": "equinix-external_test", + "interface-type": "external", + "is-port-mirrored": "", + "in-maint": "", + "is-ip-unnumbered": "", + "l2-multicasting": "" + })], + related_to=[NetworkDetailsElement(network_details_element_type="pserver", + network_details_element_parameters={ + "hostname": "test-pserver"})]) diff --git a/src/onaptests/steps/instantiate/so/modify_pnf_in_service.py b/src/onaptests/steps/instantiate/so/modify_pnf_in_service.py new file mode 100644 index 0000000..f57c82d --- /dev/null +++ b/src/onaptests/steps/instantiate/so/modify_pnf_in_service.py @@ -0,0 +1,116 @@ +import yaml +from onapsdk.aai.business import PnfInstance +from onapsdk.aai.business.customer import Customer, ServiceSubscription +from onapsdk.aai.business.service import ServiceInstance +from onapsdk.configuration import settings +from onapsdk.so.modification import PnfModificationRequest + +import onaptests.utils.exceptions as onap_test_exceptions +from onaptests.steps.base import BaseStep, YamlTemplateBaseStep + + +class ModifyPnfInService(YamlTemplateBaseStep): + """Modify pnf in service.""" + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + self.pnf_modification = None + self._yaml_template = None + self._service_instance: ServiceInstance = None + self._pnf_instance: PnfInstance = None + self._pnf_id: str = None + + @property + def description(self) -> str: + """Step description.""" + return "modification of pnf in running service using SO macro method." + + @property + def component(self) -> str: + """Component name.""" + return "SO" + + @property + def model_yaml_template(self) -> dict: + return {} + + @property + def yaml_template(self) -> dict: + """YAML template abstract property. + + Every YAML template step need to implement that property. + + Returns: + dict: YAML template + + """ + if not self._yaml_template: + with open(settings.SERVICE_YAML_TEMPLATE, + "r", encoding="utf-8") as yaml_template: + self._yaml_template: dict = yaml.safe_load(yaml_template) + return self._yaml_template + + @BaseStep.store_state + def execute(self): + + """modify pnf in running service. + + ==== + Args: + + Returns: + pnf modification: pnfInstantiation object + ==== + Use settings values: + - GLOBAL_CUSTOMER_ID, + - SERVICE_SUBSCRIPTION, + - OWNING_ENTITY, + - PROJECT. + + Raises: + Exception: Service modification failed + + """ + + super().execute() + self._logger.info("modifying pnf from running service") + customer_pnf: Customer = Customer.get_by_global_customer_id(settings.GLOBAL_CUSTOMER_ID) + + service_sub_pnf: ServiceSubscription = \ + customer_pnf.get_service_subscription_by_service_type(self.service_type) + self._logger.info("got service_subscription") + + self._service_instance = \ + service_sub_pnf.get_service_instance_by_name(settings.SERVICE_INSTANCE_NAME) + self._logger.info("service instance name " + self._service_instance.instance_name) + + service = self._service_instance.sdc_service + self._logger.info("sdc service " + service.name) + + self._logger.info("got pnf instance " + self._service_instance.instance_name) + + self._pnf_instance = next(self._service_instance.pnfs) + + self._logger.info("pnf id also found " + self._pnf_instance.pnf_id) + + self.pnf_modification = PnfModificationRequest.send_request( + pnf_object=self._pnf_instance, + sdc_service=service, + aai_service_instance=self._service_instance, + ) + + try: + self.pnf_modification.wait_for_finish(timeout=settings.ORCHESTRATION_REQUEST_TIMEOUT) + except TimeoutError as exc: + self._logger.error("PNF Modification %s timed out", self._pnf_instance) + raise onap_test_exceptions.ServiceInstantiateException( + "Timeout on instatiation") from exc + if self.pnf_modification.failed: + self._logger.error("PNF Modification %s failed hence testcase is failed", + self._pnf_instance) + raise onap_test_exceptions.ServiceInstantiateException( + self.pnf_modification.status_message) + if self.pnf_modification.completed: + self._logger.error("PNF Modification %s completed hence testcase is passed", + self._pnf_instance) diff --git a/src/onaptests/steps/onboard/cds.py b/src/onaptests/steps/onboard/cds.py index b9cc458..e91eb4a 100644 --- a/src/onaptests/steps/onboard/cds.py +++ b/src/onaptests/steps/onboard/cds.py @@ -119,7 +119,9 @@ class CbaEnrichStep(CDSBaseStep): Delete enriched CBA file. """ - Path(settings.CDS_CBA_ENRICHED).unlink() + path = Path(settings.CDS_CBA_ENRICHED) + if path.is_file(): + path.unlink() super().cleanup() diff --git a/src/onaptests/steps/onboard/cps.py b/src/onaptests/steps/onboard/cps.py index 280082b..fcac58b 100644 --- a/src/onaptests/steps/onboard/cps.py +++ b/src/onaptests/steps/onboard/cps.py @@ -8,6 +8,7 @@ import pg8000 from kubernetes import client, config from onapsdk.configuration import settings from onapsdk.cps import Anchor, Dataspace, SchemaSet +from onapsdk.exceptions import APIError from onaptests.utils.exceptions import (EnvironmentPreparationException, OnapTestException) @@ -296,17 +297,21 @@ class CheckPostgressDataBaseConnectionStep(CpsBaseStep): self.get_database_credentials() if self.login and self.password: - ctx = ssl.create_default_context() - ctx.check_hostname = False - ctx.verify_mode = ssl.CERT_NONE + db_params = { "user": self.login, "password": self.password, "host": settings.DB_PRIMARY_HOST, "database": settings.DATABASE, - "port": settings.DB_PORT, - "ssl_context": ctx + "port": settings.DB_PORT } + + if settings.DB_USE_SSL_CONTEXT: + ctx = ssl.create_default_context() + ctx.check_hostname = False + ctx.verify_mode = ssl.CERT_NONE + db_params["ssl_context"] = ctx + try: connection = pg8000.connect(**db_params) cursor = connection.cursor() @@ -336,3 +341,34 @@ class CheckPostgressDataBaseConnectionStep(CpsBaseStep): """ super().execute() self.connect_to_postgress() + + +class RanDoCpsCleanup(CpsBaseStep): + """Back CPS nodes to fresh state.""" + + @property + def description(self) -> str: + """Step description.""" + return "Back CPS nodes into base state" + + @BaseStep.store_state + def execute(self): + """Update all configured CPS nodes back to fresh state. + + It iterates through all configured data files, read them + and update associated node data. + """ + super().execute() + dataspace = Dataspace(settings.DATASPACE_NAME) + for path, anchor_name in settings.CPS_FILE_TO_ANCHOR_MAP.items(): + with path.open("r") as data_file: + try: + anchor: Anchor = dataspace.get_anchor(anchor_name) + except APIError: + self._logger.error("Anchor %s does not exist, needs to be created", anchor_name) + schema_set: SchemaSet = dataspace.get_schema_set(settings.SCHEMA_SET_NAME) + anchor = dataspace.create_anchor( + schema_set, + anchor_name + ) + anchor.update_node("/", data_file.read()) diff --git a/src/onaptests/steps/onboard/service.py b/src/onaptests/steps/onboard/service.py index 9243d97..a35b4da 100644 --- a/src/onaptests/steps/onboard/service.py +++ b/src/onaptests/steps/onboard/service.py @@ -9,6 +9,7 @@ from onapsdk.exceptions import InvalidResponse, ResourceNotFound from onapsdk.sdc2.component_instance import (ComponentInstance, ComponentInstanceInput) from onapsdk.sdc2.pnf import Pnf +from onapsdk.sdc2.sdc_category import ServiceCategory from onapsdk.sdc2.sdc_resource import LifecycleOperation, LifecycleState from onapsdk.sdc2.service import Service, ServiceInstantiationType from onapsdk.sdc2.vf import Vf @@ -17,7 +18,6 @@ from onapsdk.so.catalog_db_adapter import CatalogDbAdapter from yaml import SafeLoader, load import onaptests.utils.exceptions as onap_test_exceptions -from onaptests.scenario.scenario_base import BaseScenarioStep from onaptests.utils.kubernetes import KubernetesHelper from ..base import BaseStep, YamlTemplateBaseStep @@ -37,6 +37,7 @@ class YamlTemplateServiceOnboardStep(YamlTemplateBaseStep): super().__init__(cleanup=settings.CLEANUP_FLAG) self._yaml_template: dict = None self._model_yaml_template: dict = None + self.category: str = None if "vnfs" in self.yaml_template[self.service_name]: self.add_step(YamlTemplateVfOnboardStep()) if "pnfs" in self.yaml_template[self.service_name]: @@ -99,6 +100,12 @@ class YamlTemplateServiceOnboardStep(YamlTemplateBaseStep): @YamlTemplateBaseStep.store_state def execute(self): """Onboard service.""" + category: str = None + if "category" in self.yaml_template[self.service_name]: + category_type = self.yaml_template[self.service_name]["category"] + if category_type == "NSST": + category = ServiceCategory.get_by_name("NSST") + super().execute() if "instantiation_type" in self.yaml_template[self.service_name]: instantiation_type: ServiceInstantiationType = ServiceInstantiationType( @@ -110,12 +117,15 @@ class YamlTemplateServiceOnboardStep(YamlTemplateBaseStep): if service.distributed: return except ResourceNotFound: - service = Service.create(name=self.service_name, instantiation_type=instantiation_type) + self._logger.info("before service create") + service = Service.create(name=self.service_name, + instantiation_type=instantiation_type, + category=category) + self._logger.info("after service create") self.declare_resources(service) self.assign_properties(service) if service.lifecycle_state != LifecycleState.CERTIFIED: service.lifecycle_operation(LifecycleOperation.CERTIFY) - service.distribute() def declare_resources(self, service: Service) -> None: """Declare resources. @@ -193,36 +203,85 @@ class YamlTemplateServiceOnboardStep(YamlTemplateBaseStep): super().cleanup() -class VerifyServiceDistributionStep(BaseScenarioStep): - """Service distribution check step.""" +class YamlTemplateServiceDistributionStep(YamlTemplateBaseStep): + """Step for distributing a service after creation.""" def __init__(self): - """Initialize step.""" + """Initialize distribution step.""" super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) - self.add_step(ServiceDistributionWaitStep()) - for notified_module in settings.SDC_SERVICE_DISTRIBUTION_COMPONENTS: - self.add_step(VerifyServiceDistributionStatusStep( - notified_module=notified_module)) - if settings.IN_CLUSTER: - self.add_step(VerifyServiceDistributionInSoStep()) - self.add_step(VerifyServiceDistributionInSdncStep()) - self.add_step(VerifyServiceDistributionInAaiStep()) + self._yaml_template: dict = None + self._model_yaml_template: dict = None + self.add_step(YamlTemplateServiceOnboardStep()) + + @property + def yaml_template(self) -> dict: + """Step YAML template. + + Load from file if it's a root step, get from parent otherwise. + + Returns: + dict: Step YAML template + + """ + if settings.MODEL_YAML_TEMPLATE: + return self.model_yaml_template + if self.is_root: + if not self._yaml_template: + with open(settings.SERVICE_YAML_TEMPLATE, "r", encoding="utf-8") as yaml_template: + self._yaml_template: dict = load(yaml_template, SafeLoader) + return self._yaml_template + return self.parent.yaml_template + + @property + def model_yaml_template(self) -> dict: + """Step Model YAML template. + + Load from file if it's a root step, get from parent otherwise. + + Returns: + dict: Step YAML template + + """ + if self.is_root: + if not self._model_yaml_template: + with open(settings.MODEL_YAML_TEMPLATE, "r", + encoding="utf-8") as model_yaml_template: + self._model_yaml_template: dict = load(model_yaml_template, SafeLoader) + return self._model_yaml_template + return self.parent.model_yaml_template @property def description(self) -> str: """Step description.""" - return "Verify complete status of distribution" + return "Distribute the service created in the onboard step." @property def component(self) -> str: """Component name.""" return "SDC" + @YamlTemplateBaseStep.store_state + def execute(self): + """Distribute service.""" + super().execute() + service: Service = Service.get_by_name(name=self.service_name) + if service: + if not service.distributed: + service.distribute() + self._logger.info(f"Service {self.service_name} distributed successfully.") + else: + self._logger.info(f"Service {self.service_name} is already distributed.") + else: + raise onap_test_exceptions.OnapTestException(f"Service {self.service_name} " + f"not found for distribution.") + class BaseServiceDistributionComponentCheckStep(BaseStep): """Service distribution check step.""" - def __init__(self, component_name: str, break_on_error: bool = True): + service_model = None + + def __init__(self, component_name: str, break_on_error: bool = True, load_model: bool = True): """Initialize step. Args: @@ -233,6 +292,7 @@ class BaseServiceDistributionComponentCheckStep(BaseStep): break_on_error=break_on_error) self.component_name = component_name self.service: Service = None + self.load_model = load_model @property def description(self) -> str: @@ -244,81 +304,33 @@ class BaseServiceDistributionComponentCheckStep(BaseStep): """Component name.""" return self.component_name - def execute(self): - """Check service distribution status.""" - super().execute() - self.service = Service.get_by_name(name=settings.SERVICE_NAME) - - -class ServiceDistributionWaitStep(BaseServiceDistributionComponentCheckStep): - """Service distribution wait step.""" - - def __init__(self): - """Initialize step.""" - super().__init__(component_name="SDC", break_on_error=False) - - @BaseStep.store_state - def execute(self): - """Wait for service distribution.""" - super().execute() - # Before instantiating, be sure that the service has been distributed - self._logger.info("******** Check Service Distribution *******") - distribution_completed = False - nb_try = 0 - while distribution_completed is False and \ - nb_try < settings.SERVICE_DISTRIBUTION_NUMBER_OF_TRIES: - distribution_completed = self.service.distributed - if distribution_completed is True: - self._logger.info( - "Service Distribution for %s is sucessfully finished", - self.service.name) - break - self._logger.info( - "Service Distribution for %s ongoing, Wait for %d s", - self.service.name, settings.SERVICE_DISTRIBUTION_SLEEP_TIME) - time.sleep(settings.SERVICE_DISTRIBUTION_SLEEP_TIME) - nb_try += 1 - - if distribution_completed is False: - msg = f"Service Distribution for {self.service.name} failed after timeout!!" - self._logger.error(msg) - raise onap_test_exceptions.ServiceDistributionException(msg) - + def check_preconditions(self, cleanup=False) -> bool: + """Check preconditions. -class VerifyServiceDistributionStatusStep(BaseServiceDistributionComponentCheckStep): - """Check service distribution in SO step.""" + Check if step preconditions are satisfied. If not, step is skipped + without further consequences. If yes, execution is initiated - def __init__(self, notified_module: str): - """Initialize step. + Returns: + bool: True if preconditions are satisfied, False otherwise - Args: - notified_module (str): Name of notified module """ + if cleanup: + return True + return self.load_model or BaseServiceDistributionComponentCheckStep.service_model - component_name = notified_module.split("-")[0].upper() - super().__init__(component_name=component_name) - self.component_id = notified_module - - @property - def description(self) -> str: - """Step description.""" - return f"Check service distribution in {self.component_name} \ -{self.component_id}." - - @BaseStep.store_state def execute(self): """Check service distribution status.""" super().execute() - if not self.service.distributed: - latest_distribution = self.service.latest_distribution - for status in latest_distribution.distribution_status_list: - if status.component_id == self.component_id and status.failed: - msg = f"Service {self.service.name} is not \ -distributed into [{self.component_id}]: {status.error_reason}" - self._logger.error(msg) - raise onap_test_exceptions.ServiceDistributionException(msg) - msg = f"Service {self.service.name} is distributed in SO and {self.component_id}." - self._logger.info(msg) + if not BaseServiceDistributionComponentCheckStep.service_model: + BaseServiceDistributionComponentCheckStep.service_model = Service.get_by_name( + name=settings.SERVICE_NAME) + self.service = BaseServiceDistributionComponentCheckStep.service_model + + def _raise_reason(self, reason, exc=None): + self._logger.error(reason) + if exc: + raise onap_test_exceptions.ServiceDistributionException(reason) from exc + raise onap_test_exceptions.ServiceDistributionException(reason) class VerifyServiceDistributionInSoStep(BaseServiceDistributionComponentCheckStep): @@ -326,22 +338,23 @@ class VerifyServiceDistributionInSoStep(BaseServiceDistributionComponentCheckSte def __init__(self): """Initialize step.""" - super().__init__(component_name="SO") + super().__init__(component_name="SO", load_model=False) @BaseStep.store_state def execute(self): """Check service distribution status.""" super().execute() - try: - CatalogDbAdapter.get_service_info(self.service.uuid) - except ResourceNotFound as e: - msg = f"Service {self.service.name} is missing in SO." - self._logger.error(msg) - raise onap_test_exceptions.ServiceDistributionException(msg) from e - except InvalidResponse: - # looks like json returned by SO catalog DB adapter returns wrong json - # but we don't care here. It is important to just know if service is there - pass + if settings.IN_CLUSTER: + try: + CatalogDbAdapter.get_service_info(self.service.uuid) + except ResourceNotFound as e: + msg = "Service model is missing in SO." + self._logger.error(msg) + raise onap_test_exceptions.ServiceDistributionException(msg) from e + except InvalidResponse: + # looks like json returned by SO catalog DB adapter returns wrong json + # but we don't care here. It is important to just know if service is there + pass class VerifyServiceDistributionInAaiStep(BaseServiceDistributionComponentCheckStep): @@ -380,7 +393,7 @@ class VerifyServiceDistributionInAaiStep(BaseServiceDistributionComponentCheckSt def __init__(self): """Initialize step.""" BaseServiceDistributionComponentCheckStep.__init__( - self, component_name="AAI") + self, component_name="AAI", load_model=False) @BaseStep.store_state def execute(self): @@ -393,7 +406,7 @@ class VerifyServiceDistributionInAaiStep(BaseServiceDistributionComponentCheckSt self._logger.info( f"Resolved {aai_service.invariant_id} aai service") except ResourceNotFound as e: - msg = f"Service {self.service.name} is missing in AAI." + msg = "Service model is missing in AAI." self._logger.error(msg) raise onap_test_exceptions.ServiceDistributionException(msg) from e @@ -408,38 +421,184 @@ class VerifyServiceDistributionInSdncStep(BaseServiceDistributionComponentCheckS def __init__(self): """Initialize step.""" BaseServiceDistributionComponentCheckStep.__init__( - self, component_name="SDNC") + self, component_name="SDNC", load_model=False) @BaseStep.store_state def execute(self): """Check service distribution status.""" super().execute() - login, password = KubernetesHelper.get_credentials_from_secret( - settings.SDNC_SECRET_NAME, self.SDNC_DB_LOGIN, self.SDNC_DB_PASSWORD) - conn = None - try: - conn = mysql.connect( - database=self.SDNC_DATABASE, - host=settings.SDNC_DB_PRIMARY_HOST, - port=settings.SDNC_DB_PORT, - user=login, - password=password) - cursor = conn.cursor() - cursor.execute( - f"SELECT * FROM service_model WHERE service_uuid = '{self.service.uuid}';") - cursor.fetchall() - if cursor.rowcount <= 0: + if settings.IN_CLUSTER: + login, password = KubernetesHelper.get_credentials_from_secret( + settings.SDNC_SECRET_NAME, self.SDNC_DB_LOGIN, self.SDNC_DB_PASSWORD) + conn = None + try: + conn = mysql.connect( + database=self.SDNC_DATABASE, + host=settings.SDNC_DB_PRIMARY_HOST, + port=settings.SDNC_DB_PORT, + user=login, + password=password) + cursor = conn.cursor() + cursor.execute( + f"SELECT * FROM service_model WHERE service_uuid = '{self.service.uuid}';") + cursor.fetchall() + if cursor.rowcount <= 0: + msg = "Service model is missing in SDNC." + self._logger.error(msg) + raise onap_test_exceptions.ServiceDistributionException(msg) + self._logger.info("Service found in SDNC") + cursor.close() + except Exception as e: msg = "Service model is missing in SDNC." - self._logger.error(msg) - raise onap_test_exceptions.ServiceDistributionException(msg) - self._logger.info("Service found in SDNC") - cursor.close() - except Exception as e: - msg = f"Service {self.service.name} is missing in SDNC." - raise onap_test_exceptions.ServiceDistributionException(msg) from e - finally: - if conn: - try: - conn.close() - except Exception: - pass + raise onap_test_exceptions.ServiceDistributionException(msg) from e + finally: + if conn: + try: + conn.close() + except Exception: + pass + + +class VerifyServiceDistributionStep(BaseStep): + """Service distribution check step.""" + + COMPONENTS_DISTRIBUTION_VERIFICATION_MAP = { + "AAI": VerifyServiceDistributionInAaiStep, + "SDNC": VerifyServiceDistributionInSdncStep, + "SO": VerifyServiceDistributionInSoStep + } + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + self.add_step(ServiceDistributionWaitStep()) + modules = sorted(settings.SDC_SERVICE_DISTRIBUTION_COMPONENTS, + reverse=True) + for notified_module in modules: + component_name = notified_module.split("-")[0].upper() + self.add_step(VerifyServiceDistributionStatusStep( + notified_module=notified_module, component_name=component_name)) + try: + self.add_step(self.COMPONENTS_DISTRIBUTION_VERIFICATION_MAP[component_name]()) + except KeyError: + pass + + @property + def description(self) -> str: + """Step description.""" + return "Verify complete status of distribution" + + @property + def component(self) -> str: + """Component name.""" + return "TEST" + + @BaseStep.store_state + def execute(self): + """Check service distribution status.""" + super().execute() + # we get here only if previous steps have not failed + # or are not braking on error + for step in self._steps: + # if step failed and do not break on error we want to skip further + # steps anyway. If there was any error it will be reported + # under dedicated step anyway + if not step.is_executed: + raise onap_test_exceptions.ServiceDistributionException( + "Service distribution has failed") + + +class ServiceDistributionWaitStep(BaseServiceDistributionComponentCheckStep): + """Service distribution wait step.""" + + def __init__(self): + """Initialize step.""" + super().__init__(component_name="SDC", break_on_error=False) + + @property + def description(self) -> str: + """Step description.""" + return "Wait for service distribution result" + + @BaseStep.store_state + def execute(self): + """Wait for service distribution.""" + super().execute() + # Before instantiating, be sure that the service has been distributed + self._logger.info("******** Check Service Distribution *******") + distribution_completed = False + nb_try = 0 + while distribution_completed is False and \ + nb_try < settings.SERVICE_DISTRIBUTION_NUMBER_OF_TRIES: + distribution_completed = self.service.distributed + if distribution_completed is True: + self._logger.info( + "Service Distribution for %s is sucessfully finished", + self.service.name) + break + self._logger.info( + "Service Distribution for %s ongoing, Wait for %d s", + self.service.name, settings.SERVICE_DISTRIBUTION_SLEEP_TIME) + time.sleep(settings.SERVICE_DISTRIBUTION_SLEEP_TIME) + nb_try += 1 + + if distribution_completed is False: + msg = f"Service Distribution for {self.service.name} failed after timeout!!" + self._logger.error(msg) + # We don't do it now as it would be reported for dediated component + # in VerifyServiceDistributionStatusStep + # raise onap_test_exceptions.ServiceDistributionException( + # "Service distribution failed after timeout!!") + + +class VerifyServiceDistributionStatusStep(BaseServiceDistributionComponentCheckStep): + """Check service distribution in SO step.""" + + def __init__(self, notified_module: str, component_name: str): + """Initialize step. + + Args: + notified_module (str): Name of notified module + component_name (str): Name of the module's component + """ + + super().__init__( + component_name=component_name, break_on_error=False, load_model=False) + self.component_id = notified_module + + @property + def description(self) -> str: + """Step description.""" + return f"Check service distribution in {self.component_name} \ +{self.component_id}." + + @BaseStep.store_state + def execute(self): + """Check service distribution status.""" + super().execute() + if not self.service.distributed: + latest_distribution = self.service.latest_distribution + present = False + msg = "" + distributed = False + for status in latest_distribution.distribution_status_list: + if status.component_id == self.component_id: + present = True + if status.distributed: + distributed = True + if status.failed: + distributed = False + msg = f"Service model distribution to [{self.component_id}] \ +failed: {status.error_reason}" + break + if not distributed: + if not msg: + if present: + msg = f"Service model distribution to {self.component_id} \ + was not completed" + else: + msg = f"Service model was not distributed to {self.component_id}" + self._raise_reason(msg) + msg = f"Service {self.service.name} is distributed in {self.component_name} \ +and {self.component_id}." + self._logger.info(msg) diff --git a/src/onaptests/steps/onboard/verify_cba.py b/src/onaptests/steps/onboard/verify_cba.py new file mode 100644 index 0000000..7345fe8 --- /dev/null +++ b/src/onaptests/steps/onboard/verify_cba.py @@ -0,0 +1,287 @@ +#!/usr/bin/env python +"""CBA Verification test case.""" +import difflib +import json +import os +import shutil +from io import BytesIO + +from onapsdk.cds.blueprint import Blueprint +from onapsdk.cds.cds_element import CdsElement +from onapsdk.configuration import settings +from onapsdk.exceptions import ResourceNotFound + +from onaptests.steps.base import BaseStep +from onaptests.utils.exceptions import CbaVerificationException +from onaptests.utils.gitlab import GitLabClient + + +class TestCbaBaseStep(BaseStep): + """Test CBA Base Step""" + + def __init__(self, cleanup=BaseStep.HAS_NO_CLEANUP, break_on_error: bool = True): + """TestCbaBaseStep.""" + super().__init__(cleanup=cleanup, break_on_error=break_on_error) + + @property + def component(self) -> str: + """Component name. + + Name of component which step is related with. + Most is the name of ONAP component. + + Returns: + str: Component name + + """ + return "CBA" + + +class DownloadCbaStep(TestCbaBaseStep, CdsElement): + """Step to download CBA content and convert it to zip.""" + + def __init__(self, cba_data): + """Download CBA step.""" + + super().__init__(cleanup=settings.CLEANUP_FLAG, break_on_error=True) + self.cba_data = cba_data + self.cba = None + + def get_details_by_name_and_version(self, name: str, version: str): + """Get CBA details from its name and version.""" + cba_details = self.send_message( + action="Download CBA Details", + method="GET", + url=f"{self._url}/api/v1/blueprint-model/by-name/{name}/version/{version}", + auth=self.auth + ) + return cba_details + + def get_by_name_and_version(self, name: str, version: str) -> Blueprint: + """Get CBA blueprint from its name and version.""" + cba_data = self.send_message( + action="Download CBA Content", + method="GET", + url=f"{self._url}/api/v1/blueprint-model/download/by-name/{name}/version/{version}", + auth=self.auth + ) + return Blueprint(BytesIO(cba_data.content).read()) + + @property + def description(self) -> str: + """Step description. + + Used for reports + + Returns: + str: Step description + + """ + name = self.cba_data["name"] + return f"Downloading CBA {name} from CDS" + + def zip_cba_from_cds(self): + """Check CBA zip downloaded from CDS.""" + name = self.cba_data["name"] + version = self.cba_data["version"] + zip_path = f"{settings.LOCAL_PATH}/{name}/{version}" + os.makedirs(zip_path, exist_ok=True) + zip_file = f"{zip_path}/cba.zip" + try: + self.get_details_by_name_and_version(name, version) + blueprint = self.cba = self.get_by_name_and_version(name, version) + blueprint.save(zip_file) + shutil.unpack_archive(zip_file, zip_path, 'zip') + except ResourceNotFound as exc: + self._logger.error(f"CBA {name}-{version} Not Found") + raise CbaVerificationException("CBA Not Found in CDS") from exc + + def delete_cba_directory(self): + """Delete local CBA content.""" + name = self.cba_data["name"] + delete_path = f"{settings.LOCAL_PATH}/{name}" + if os.path.exists(delete_path): + try: + shutil.rmtree(delete_path) + self._logger.info(f"The directory '{delete_path}' has been successfully deleted.") + except OSError as e: + self._logger.eror(f"Error: {e}") + error_message = f"Error while deleting directory: {e}" + self._logger.error(error_message) + raise CbaVerificationException(error_message) from e + else: + self._logger.info(f"The directory '{delete_path}' does not exist.") + + @BaseStep.store_state + def execute(self) -> None: + """Download CBA content and convert it to zip.""" + super().execute() + self.zip_cba_from_cds() + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + """Delete downloaded cba content directory.""" + self.delete_cba_directory() + super().cleanup() + + +class TestCbaStep(TestCbaBaseStep): + """Step to check if workflow exists and compare CBA from Gitlab with CBA downloaded from CDS.""" + + def __init__(self, cba_data): + """Initialize step. + + Substeps: + - DownloadCbaStep + """ + super().__init__(break_on_error=False) + self.cba_data = cba_data + self.download_cba_step = DownloadCbaStep(cba_data) + self.add_step(self.download_cba_step) + + @property + def description(self) -> str: + """Step description. + + Used for reports + + Returns: + str: Step description + + """ + name = self.cba_data["name"] + return f"Compare CBA {name} Content with Gitlab" + + def show_differences(self, git_file_content, local_file_content, entry_path): + """Show CBA file difference: git and local.""" + diff = difflib.unified_diff( + git_file_content.splitlines(), + local_file_content.splitlines(), + fromfile=entry_path + ' (git)', + tofile=entry_path + ' (local)' + ) + diff_text = "\n".join(diff) + return f"\n\n{diff_text}\n" + + def load_json(self, git_file_content, local_file_path): + """Load CBA json file with formatting.""" + try: + git_file_content = json.loads(git_file_content) + if os.path.exists(local_file_path): + with open(local_file_path, 'r', encoding="utf-8") as local_file: + local_file_content = local_file.read() + local_file_content = json.loads(local_file_content) + git_file_content = dict(sorted(git_file_content.items())) + local_file_content = dict(sorted(local_file_content.items())) + return (json.dumps(git_file_content, indent=4, sort_keys=True), + json.dumps(local_file_content, indent=4, sort_keys=True)) + except json.JSONDecodeError as e: + self._logger.error(f"Error decoding JSON: {e}") + return None, None + + def check_if_path_in_pattern_list(self, path, patterns): + """Check if file path is in the pattern.""" + for pattern in patterns: + if pattern in path: + return True + return False + + def compare_directories_recursive( # noqa: C901 + self, branch, git_directory_path, local_directory_path, gitlab_id): + """Compare local and gitlab CBA directories.""" + enrichment = self.cba_data["enrichment"] + try: + git_directory_entries = GitLabClient.get_directory_entries( + branch, git_directory_path, gitlab_id) + if len(git_directory_entries) == 0: + self._logger.error(f"Folder '{git_directory_path}' on gitlab " + f"with projct ID: {gitlab_id} does not exist") + raise CbaVerificationException("Cannot locate repo folder in gitlab") + except TypeError as exc: + self._logger.error(f"Branch '{branch}' on gitlab " + f"with projct ID: {gitlab_id} does not exist") + raise CbaVerificationException("Cannot locate branch in gitlab") from exc + ident_files = [] + diff_files = [] + git_only_files = [] + differences = {} + for entry in git_directory_entries: + if self.check_if_path_in_pattern_list(entry.path, settings.IGNORE_FILES): + # Check if the path is in ignore_files set + continue + binary_check = False + if entry.type == "tree": + ident, diff, git, show = self.compare_directories_recursive( + branch, entry.path, local_directory_path + '/' + entry.name, gitlab_id) + ident_files.extend(ident) + diff_files.extend(diff) + git_only_files.extend(git) + differences.update(show) + else: # It's a file + git_file_content = GitLabClient.get_text_file_content(branch, entry.path, gitlab_id) + git_file_content = git_file_content.replace("\r\n", "\n").strip() + entry_name = os.path.basename(entry.path) + local_file_path = os.path.join(local_directory_path, entry_name) + if os.path.exists(local_file_path): + try: + with open(local_file_path, 'r', encoding='utf-8') as local_file: + local_file_content = local_file.read().replace("\r\n", "\n").strip() + except UnicodeDecodeError: + binary_check = True + if binary_check is False: + if 'Definitions/' in entry.path: + git_file_content, local_file_content = self.load_json( + git_file_content, local_file_path) + if git_file_content == local_file_content: + ident_files.append(entry.path) + else: + if (not enrichment or + not self.check_if_path_in_pattern_list(entry.path, + settings.ENRICHMENT_FILES)): + diff_files.append(entry.path) + diff_text = self.show_differences( + git_file_content, local_file_content, entry.path + ) + differences[entry.path] = diff_text + else: + git_only_files.append(entry.path) + return ident_files, diff_files, git_only_files, differences + + def summarize_comparison(self, local_path, gitlab_id, branch): + """Summarize CBA comparison.""" + gitlab_repo_cba = self.cba_data["gitlab_repo_cba"] + ident_files, diff_files, git_only_files, differences = self.compare_directories_recursive( + branch, gitlab_repo_cba, + local_path, gitlab_id) + error = False + if ident_files: + self._logger.info(f"Identical files: {ident_files}") + self._logger.info(f"There are {len(ident_files)} identical files") + if diff_files: + dif_error_message = f"Different files: {diff_files}" + self._logger.error(dif_error_message) + self._logger.error(f"There are {len(diff_files)} different files") + error = True + if git_only_files: + git_error_message = f"Files that exists only on Gitlab: {git_only_files}" + self._logger.error(git_error_message) + self._logger.error(f"There are {len(git_only_files)} files that exist only on Gitlab") + error = True + if differences: + for file_path, diff_text in differences.items(): + self._logger.info(f"Differences in file: {file_path}") + self._logger.info(diff_text) + if error: + raise CbaVerificationException( + "CBA content differencies between Gitlab and CDS") + + @BaseStep.store_state + def execute(self) -> None: + """Check if workflow exists and compare CBA from Gitlab with CBA downloaded from CDS.""" + super().execute() + gitlab_id = str(self.cba_data["gitlab_project_id"]) + branch = self.cba_data["gitlab_branch"] + name = self.cba_data["name"] + version = self.cba_data["version"] + local_path = f"{settings.LOCAL_PATH}/{name}/{version}" + self.summarize_comparison(local_path, gitlab_id, branch) diff --git a/src/onaptests/steps/onboard/vsp.py b/src/onaptests/steps/onboard/vsp.py index 75c6c5e..54a3f19 100644 --- a/src/onaptests/steps/onboard/vsp.py +++ b/src/onaptests/steps/onboard/vsp.py @@ -1,8 +1,10 @@ import onapsdk.constants as const from onapsdk.configuration import settings +from onapsdk.exceptions import APIError from onapsdk.sdc.vendor import Vendor from onapsdk.sdc.vsp import Vsp +from onaptests.utils.exceptions import OnapTestException from onaptests.utils.resources import get_resource_location from ..base import BaseStep, YamlTemplateBaseStep @@ -161,3 +163,51 @@ class YamlTemplateVspOnboardStep(YamlTemplateBaseStep): for pnf in self.yaml_template["pnfs"]: self._cleanup_vsp(f"{pnf['pnf_name']}_VSP") super().cleanup() + + +class GetVspLoadStatusStep(BaseStep): + """Getting VSP status step. + + The step shows a status of VSP's (vendor-software-products) status at SDC: + DRAFT --> UPLOADED --> VALIDATED --> COMMITED --> CERTIFIED. + """ + + def __init__(self): + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + @property + def description(self) -> str: + """Step description.""" + return "Get vsp status by ID from SDC." + + @property + def component(self) -> str: + """Component name. + + Name of component which step is related with. + Most is the name of ONAP component. + + Returns: + str: Component name + + """ + return "SDC" + + @BaseStep.store_state + def execute(self) -> None: + super().execute() + self._logger.info("Get VSP status from SDC") + try: + vendor: Vendor = Vendor(name=settings.SDBH_VENDOR_NAME) + vsp: Vsp = Vsp(name=settings.SDBH_VSP_NAME, vendor=vendor) + vsp.load_status() + if vsp.status is not None: + self._logger.info("Getting VSP status is completed.") + if vsp.status == 'Certified': + self._logger.info("VSP status is: " + vsp.status) + return vsp.status + raise OnapTestException("Unexpected VSP status %s" % vsp.status) + raise OnapTestException("vsp.status is NoneType") + except APIError as exc: + raise OnapTestException("Error while accessing SDC") from exc diff --git a/src/onaptests/steps/policy/policy_operations.py b/src/onaptests/steps/policy/policy_operations.py new file mode 100644 index 0000000..b821904 --- /dev/null +++ b/src/onaptests/steps/policy/policy_operations.py @@ -0,0 +1,141 @@ +from abc import ABC + +from onapsdk.configuration import settings +from onapsdk.policy.policy import Policy + +from onaptests.steps.base import BaseStep +from onaptests.utils.exceptions import OnapTestException + + +class PolicyBaseStep(BaseStep, ABC): + """Abstract Policy base step.""" + + @property + def component(self) -> str: + """Component name.""" + return "Policy" + + +class StorePolicyStep(PolicyBaseStep): + """Storage of policy.""" + + def __init__(self) -> None: + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + + @property + def description(self) -> str: + """Step description.""" + return "Storage of policy." + + @BaseStep.store_state + def execute(self) -> None: + """Storage of policy.""" + super().execute() + try: + response = Policy.store(settings.STORE_POLICY) + self._logger.info(response.content) + except Exception as exc: + raise OnapTestException(f"An error occurred while storing policy: {exc}") from exc + + +class DeployPolicyStep(PolicyBaseStep): + """Deployment of policy.""" + + def __init__(self) -> None: + """Initialize step. + + Substeps: + - StorePolicyStep. + """ + super().__init__(cleanup=settings.CLEANUP_FLAG) + self.add_step(StorePolicyStep()) + + @property + def description(self) -> str: + """Step description.""" + return "Deployment of policy." + + @BaseStep.store_state + def execute(self) -> None: + """Deployment of policy.""" + super().execute() + try: + response = Policy.deploy(settings.DEPLOY_POLICY) + self._logger.info(response.content) + except Exception as exc: + raise OnapTestException(f"An error occurred while deploying policy: {exc}") from exc + + @BaseStep.store_state(cleanup=True) + def cleanup(self) -> None: + """Cleanup of deployed policy.""" + self._logger.info("cleanup of deployed policy") + try: + get_response = Policy.get(settings.POLICY_ID, settings.POLICY_VERSION) + if get_response.status_code == 200: + Policy.undeploy(settings.POLICY_ID) + Policy.delete(settings.POLICY_ID, settings.POLICY_VERSION) + self._logger.info("Policy deleted successfully.") + else: + self._logger.error("Policy does not exist.") + except Exception as exc: + self._logger.error(f"Error occurred while deleting policy: {exc}") + raise OnapTestException(exc) from exc + super().cleanup() + + +class GetPolicyStep(PolicyBaseStep): + """Get the policy. + + Substeps: + - DeployPolicyStep. + """ + + def __init__(self) -> None: + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + self.add_step(DeployPolicyStep()) + + @property + def description(self) -> str: + """Step description.""" + return "Get the policy." + + @BaseStep.store_state + def execute(self) -> None: + """Get the policy.""" + super().execute() + try: + response = Policy.get(settings.POLICY_ID, settings.POLICY_VERSION) + self._logger.info(response.content) + except Exception as exc: + raise OnapTestException(f"An error occurred while getting the policy: {exc}") from exc + + +class GetPolicyDecisionStep(PolicyBaseStep): + """Get the decision. + + Substeps: + - GetPolicyStep. + """ + + def __init__(self) -> None: + """Initialize step.""" + super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) + self.add_step(GetPolicyStep()) + + @property + def description(self) -> str: + """Step description.""" + return "Get the decision." + + @BaseStep.store_state + def execute(self) -> None: + """Get the decision.""" + super().execute() + try: + response = Policy.decision(settings.DECISION_REQUEST) + self._logger.info(response.content) + except Exception as exc: + raise OnapTestException(f"An error occurred while getting the policy" + f" decision: {exc}") from exc diff --git a/src/onaptests/templates/artifacts/basic_cnf_cba_enriched.zip b/src/onaptests/templates/artifacts/basic_cnf_cba_enriched.zip index be5c4daae9ef50ea612b10343a8cf32d769e92a7..3df16f37e49b140293c31fa420a0ea473e0516f2 100644 GIT binary patch delta 4292 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 literal 0 HcmV?d00001 diff --git a/src/onaptests/templates/artifacts/cds-resource-resolution/dd.json b/src/onaptests/templates/artifacts/cds-resource-resolution/dd.json index ead7f86..cad6bd0 100644 --- a/src/onaptests/templates/artifacts/cds-resource-resolution/dd.json +++ b/src/onaptests/templates/artifacts/cds-resource-resolution/dd.json @@ -73,7 +73,7 @@ "type": "string" }, "sources": { - "sdnc": { + "rest": { "type": "source-rest", "properties": { "type": "string", @@ -106,7 +106,7 @@ "type": "string" }, "sources": { - "sdnc": { + "rest": { "type": "source-rest", "properties": { "type": "string", @@ -141,7 +141,7 @@ "type": "string" }, "sources": { - "sdnc": { + "rest": { "type": "source-rest", "properties": { "type": "string", @@ -174,7 +174,7 @@ "type": "string" }, "sources": { - "sdnc": { + "rest": { "type": "source-rest", "properties": { "type": "string", @@ -207,7 +207,7 @@ "type": "string" }, "sources": { - "sdnc": { + "rest": { "type": "source-rest", "properties": { "type": "string", @@ -240,7 +240,7 @@ "type": "string" }, "sources": { - "sdnc": { + "rest": { "type": "source-rest", "properties": { "type": "string", diff --git a/src/onaptests/templates/artifacts/cds-resource-resolution/resource-resolution.zip b/src/onaptests/templates/artifacts/cds-resource-resolution/resource-resolution.zip index f42d4ea65b689cbbaf3c501dea84170267823407..7ae504ec80fa46080edc809d35de6946b37cb15e 100644 GIT binary patch delta 1502 zcmca+a>sbGJijr^yk7Q<$ro8AC+G7!vaAMjHgDkSDWzzD{XoE*4pByE-#M_!$>Oc(Eoo%S0}9xCF0T)wHP7ANT2O zXJBBMJTcm!UU)it1_+l{a5FHnykurz0299FE^-}G5Mg`p+qSjhu5gLCuNDVa)b&lv zvezv&`l@uK-2eHNyBz<2{!>04#^B)e`Pu?*g7`LSiz4*N&uSD%{LAD>?3JY(Xb@3)oLdoDDq{+`abd9M7d$Clo!cQ1_S zUAMxKlXLE)i|dN6$_IEevxorw#=+nN^r@EAy9pgYp5Ww0Mm-LBpf^Ey@^;3Uu&$u) zi9SW;yp1b;{B;{=3qFwN5!XMV?>33UwPU&xr*)e}^#N5O?@7iFg7ntety5gb!T;Rh z&Y{rLtPBV{Qh|0@7rNyA0NP>C&cL8OF3^Q z-cPNI`?_IUWkRhv*NfydVcna1U-(F_63}!}&@+-XPC2G37c3mI|35musO0oJq+oLd2Ai23 zn~5SL1H*5QNi4?ooWOwM!VIjtQyudTD+suLw`)BL4J;*>j}|kJu(2Fwa@||q*()60 zd1+bi$}6qnXa4`2ub#4J)vI3<=Iu(0`gUMm_BLVOEk-3r=D9I$#jNe%x=~`|-^;JfatSPk7R?MS0zlsrfe)kG`KU_wM({Z+S~2 zSn_io#aV9IBH;hpN5AHS`}T}xxkLZC@A%~`IHCUa(<#}CN1J!8)^NYvufSq<-7?DR z=Fe1zA3HzgOJEZbyL zi8Q8Y&dGBnf|-|aGEDx-r8-$cQVC?#JkU$ zL@5?f76jR&fSTwS7&K6HGzv~G5YuM?r9+@mE zh!I8cYA1~Zqpuk`v1+UCoTH3*KMGtKgtdI%`}aq~X{(6VX_Zd#>Qe_SM{7!rdIS{{ zj&ZpOHxl>sP}9~7^Y1x7(-RjTYdrMfsZRCp#&wnBAK78ehHtyGwTP!bHT-GD3++CO z-)UvjBwL_Rq#yS=>OSo2^z6J{q^x4o6zm$=Yuw%|FdzmE=k0R~-Zov_Ez)?__bMof z+Ze06+M=YH)Sm5dzG{qoPiyGTaUPl#_D(J}dq|(_!z@)kB1}&F=xg*ma*%a2PuJ}awYwA>262`9Ip!Fpe@rTEo0d&Wv|VMzY(;zp1I3i- z-(9#*8!WBjF*t9}kW`?)3>p(Q{9g-dFIoiE=n^a7SPsFHX9XLby;r&GyX8EgM zorMKGRmjn8YcorwyEq%Bd4r#Q8r^q?&$oE&$L1OlTFW9_S4QkQVb||RxPdik%oL2c z_x5eSW0M`7ez>v=>M~3pt zIFs?rvqmq>@dJA4=`Q=u>+fd;6Q9z;k&G*qI=4b|0(>Tge5dM?F}EFv;6l^@$EAr) ztaNqTh)TIyo54=36PtBuUEr_=BWE6HPPZttX3v;ww%I!-M2eIxwE!EYE{jl6#qHCWl0GfafpHSBEzU%9MM!fryeNdb(;q=T^RB@rsV=w1!&hn6l zgs$krk#$(-cds)h74s}p1kA#}q_N)dGd*W=rq^)Hmg^r^}BxVus(Mi5&Hm{K#)o^>HL(R#T^MWRJ)$<-^ zKfx5KZB|`L8xZ-S=$BCmZP8s_fw1~z!eqVA%;dbmF9G?&HJC=V>a(X(cDxR|nLn@4 zsb8fs;hEp=IQg?iOjCe0x1UvYI7B|;YD=@H(bQ*DeSp_7CA*u+*G@>qA5YIJ$V@Kr z6Jy8d;&!u$C?%(RoS$&H;K}TOh|^@UbuXRXfuvmSWXIRl($JJIhGVM8MK9P2OjgW8A!x`YQDC98;+N!gga&)1*L}4n7j<S>lh;K)!~k zuu#@)F`P9ei%ynfeM=-eSfCjWNj}AwRv>8mg?HBxu@odyX^^diLjeFylyp}u?D`VF z0~E>D10Wd=P#UvUg0dheN&JrhA(^p=Ug`|rqy446pz)ODFqN#ji2iqj0a&+$`$yCQ zT6=+4ZJ~;#GxNmK&47^WrLUzdjXoOLRret#zl!MV^C!|Xbz-n1_I7eo{EkqTRDjs?f b9Z-kxu#D)7y08MOlC)q06^AKa@J8?tLFImn diff --git a/src/onaptests/templates/artifacts/create_kafka_topic_template.json.j2 b/src/onaptests/templates/artifacts/create_kafka_topic_template.json.j2 new file mode 100644 index 0000000..2c9e2f5 --- /dev/null +++ b/src/onaptests/templates/artifacts/create_kafka_topic_template.json.j2 @@ -0,0 +1,16 @@ +{ + "apiVersion":"kafka.strimzi.io/v1beta2", + "kind":"KafkaTopic", + "metadata": { + "name":"{{ topicName }}", + "namespace":"{{ namespace }}", + "labels":{ + "strimzi.io/cluster":"onap-strimzi" + } + }, + "spec": { + "partitions":3, + "replicas":1, + "name":"{{ topicName }}" + } + } \ No newline at end of file diff --git a/src/onaptests/templates/artifacts/ntp_checker_daemon.yml.j2 b/src/onaptests/templates/artifacts/ntp_checker_daemon.yml.j2 new file mode 100644 index 0000000..73d5060 --- /dev/null +++ b/src/onaptests/templates/artifacts/ntp_checker_daemon.yml.j2 @@ -0,0 +1,42 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{daemon_name}} + labels: + k8s-app: {{daemon_name}} +spec: + selector: + matchLabels: + name: {{daemon_name}} + template: + metadata: + labels: + name: {{daemon_name}} + spec: + containers: + - name: {{daemon_name}} + image: dockerhub.devops.telekom.de/python:3.11-slim + command: ["python", "/app/checker.py"] + resources: + limits: + memory: 200Mi + requests: + cpu: 100m + memory: 200Mi + volumeMounts: + - name: varlog + mountPath: /var/log + - name: {{daemon_name}}-script + mountPath: /app/checker.py + subPath: checker.py + ports: + - containerPort: 8000 + terminationGracePeriodSeconds: 30 + volumes: + - name: {{daemon_name}}-script + configMap: + name: {{daemon_name}}-script + defaultMode: 0777 + - name: varlog + hostPath: + path: /var/log diff --git a/src/onaptests/templates/artifacts/pm_message_file.json b/src/onaptests/templates/artifacts/pm_message_file.json new file mode 100644 index 0000000..395f0cb --- /dev/null +++ b/src/onaptests/templates/artifacts/pm_message_file.json @@ -0,0 +1,228 @@ +{ + "event": { + "commonEventHeader": { + "domain": "perf3gpp", + "eventId": "9efa1210-f285-455f-9c6a-3a659b1f1882", + "sequence": 0, + "eventName": "perf3gpp_gnb-Ericsson_pmMeasResult", + "sourceName": "du-1", + "reportingEntityName": "", + "priority": "Normal", + "startEpochMicrosec": 951912000000, + "lastEpochMicrosec": 951912900000, + "version": "4.0", + "vesEventListenerVersion": "7.1", + "timeZoneOffset": "+00:00" + }, + "perf3gppFields": { + "perf3gppFieldsVersion": "1.0", + "measDataCollection": { + "granularityPeriod": 900, + "measuredEntityUserName": "RNC Telecomville", + "measuredEntityDn": "SubNetwork=CountryNN,MeContext=MEC-Gbg-1,ManagedElement=RNC-Gbg-1", + "measuredEntitySoftwareVersion": "", + "measInfoList": [ + { + "measInfoId": { + "sMeasInfoId": "" + }, + "measTypes": { + "sMeasTypesList": [ + "attTCHSeizures", + "succTCHSeizures", + "Cell_Unavailable_Fault", + "Cell_Unavailable_Manual_Intervention" + ] + }, + "measValuesList": [ + { + "measObjInstId": "RncFunction=RF-1,UtranCell=Gbg-997", + "suspectFlag": "false", + "measResults": [ + { + "p": 1, + "sValue": "813" + }, + { + "p": 2, + "sValue": "913" + }, + { + "p": 3, + "sValue": "1013" + }, + { + "p": 4, + "sValue": "1113" + } + ] + }, + { + "measObjInstId": "RncFunction=RF-1,UtranCell=Gbg-998", + "suspectFlag": "false", + "measResults": [ + { + "p": 1, + "sValue": "890" + }, + { + "p": 2, + "sValue": "901" + }, + { + "p": 3, + "sValue": "123" + }, + { + "p": 4, + "sValue": "234" + } + ] + }, + { + "measObjInstId": "RncFunction=RF-1,UtranCell=Gbg-999", + "suspectFlag": "true", + "measResults": [ + { + "p": 1, + "sValue": "456" + }, + { + "p": 2, + "sValue": "567" + }, + { + "p": 3, + "sValue": "678" + }, + { + "p": 4, + "sValue": "789" + } + ] + } + ] + }, + { + "measInfoId": { + "sMeasInfoId": "ENodeBFunction" + }, + "measTypes": { + "sMeasTypesList": [ + "attTCHSeizures", + "succTCHSeizures2", + "attImmediateAssignProcs3", + "succImmediateAssignProcs4" + ] + }, + "measValuesList": [ + { + "measObjInstId": "ManagedElement=RNC-Gbg-1,ENodeBFunction=1", + "suspectFlag": "false", + "measResults": [ + { + "p": 1, + "sValue": "4" + }, + { + "p": 2, + "sValue": "86,87,2,6,77,96,75,33,24" + }, + { + "p": 3, + "sValue": "40" + }, + { + "p": 4, + "sValue": "90" + } + ] + } + ] + }, + { + "measInfoId": { + "sMeasInfoId": "" + }, + "measTypes": { + "sMeasTypesList": [ + "test123", + "succTCHSeizures6", + "attImmediateAssignProcs7", + "succImmediateAssignProcs8" + ] + }, + "measValuesList": [ + { + "measObjInstId": "RncFunction=RF-1,UtranCell=Gbg-997", + "suspectFlag": "false", + "measResults": [ + { + "p": 1, + "sValue": "238" + }, + { + "p": 2, + "sValue": "344" + }, + { + "p": 3, + "sValue": "563" + }, + { + "p": 4, + "sValue": "787" + } + ] + }, + { + "measObjInstId": "RncFunction=RF-1,UtranCell=Gbg-998", + "suspectFlag": "false", + "measResults": [ + { + "p": 1, + "sValue": "898" + }, + { + "p": 2, + "sValue": "905" + }, + { + "p": 3, + "sValue": "127" + }, + { + "p": 4, + "sValue": "238" + } + ] + }, + { + "measObjInstId": "RncFunction=RF-1,UtranCell=Gbg-999", + "suspectFlag": "true", + "measResults": [ + { + "p": 1, + "sValue": "454" + }, + { + "p": 2, + "sValue": "569" + }, + { + "p": 3, + "sValue": "672" + }, + { + "p": 4, + "sValue": "785" + } + ] + } + ] + } + ] + } + } + } +} diff --git a/src/onaptests/templates/artifacts/pm_message_negative_file.json b/src/onaptests/templates/artifacts/pm_message_negative_file.json new file mode 100644 index 0000000..b454a6b --- /dev/null +++ b/src/onaptests/templates/artifacts/pm_message_negative_file.json @@ -0,0 +1,228 @@ +{ + "event": { + "commonEventHeader": { + "domain": "perf3gpp", + "eventId": "9efa1210-f285-455f-9c6a-3a659b1f1882", + "sequence": 0, + "eventName": "perf3gpp_gnb-Ericsson_pmMeasResult", + "sourceName": "empty", + "reportingEntityName": "", + "priority": "Normal", + "startEpochMicrosec": 951912000000, + "lastEpochMicrosec": 951912900000, + "version": "4.0", + "vesEventListenerVersion": "7.1", + "timeZoneOffset": "+00:00" + }, + "perf3gppFields": { + "perf3gppFieldsVersion": "1.0", + "measDataCollection": { + "granularityPeriod": 900, + "measuredEntityUserName": "RNC Telecomville", + "measuredEntityDn": "SubNetwork=CountryNN,MeContext=MEC-Gbg-1,ManagedElement=RNC-Gbg-1", + "measuredEntitySoftwareVersion": "", + "measInfoList": [ + { + "measInfoId": { + "sMeasInfoId": "" + }, + "measTypes": { + "sMeasTypesList": [ + "attTCHSeizures", + "succTCHSeizures", + "Cell_Unavailable_Fault", + "Cell_Unavailable_Manual_Intervention" + ] + }, + "measValuesList": [ + { + "measObjInstId": "RncFunction=RF-1,UtranCell=Gbg-997", + "suspectFlag": "false", + "measResults": [ + { + "p": 1, + "sValue": "813" + }, + { + "p": 2, + "sValue": "913" + }, + { + "p": 3, + "sValue": "1013" + }, + { + "p": 4, + "sValue": "1113" + } + ] + }, + { + "measObjInstId": "RncFunction=RF-1,UtranCell=Gbg-998", + "suspectFlag": "false", + "measResults": [ + { + "p": 1, + "sValue": "890" + }, + { + "p": 2, + "sValue": "901" + }, + { + "p": 3, + "sValue": "123" + }, + { + "p": 4, + "sValue": "234" + } + ] + }, + { + "measObjInstId": "RncFunction=RF-1,UtranCell=Gbg-999", + "suspectFlag": "true", + "measResults": [ + { + "p": 1, + "sValue": "456" + }, + { + "p": 2, + "sValue": "567" + }, + { + "p": 3, + "sValue": "678" + }, + { + "p": 4, + "sValue": "789" + } + ] + } + ] + }, + { + "measInfoId": { + "sMeasInfoId": "ENodeBFunction" + }, + "measTypes": { + "sMeasTypesList": [ + "attTCHSeizures", + "succTCHSeizures2", + "attImmediateAssignProcs3", + "succImmediateAssignProcs4" + ] + }, + "measValuesList": [ + { + "measObjInstId": "ManagedElement=RNC-Gbg-1,ENodeBFunction=1", + "suspectFlag": "false", + "measResults": [ + { + "p": 1, + "sValue": "4" + }, + { + "p": 2, + "sValue": "86,87,2,6,77,96,75,33,24" + }, + { + "p": 3, + "sValue": "40" + }, + { + "p": 4, + "sValue": "90" + } + ] + } + ] + }, + { + "measInfoId": { + "sMeasInfoId": "" + }, + "measTypes": { + "sMeasTypesList": [ + "test123", + "succTCHSeizures6", + "attImmediateAssignProcs7", + "succImmediateAssignProcs8" + ] + }, + "measValuesList": [ + { + "measObjInstId": "RncFunction=RF-1,UtranCell=Gbg-997", + "suspectFlag": "false", + "measResults": [ + { + "p": 1, + "sValue": "238" + }, + { + "p": 2, + "sValue": "344" + }, + { + "p": 3, + "sValue": "563" + }, + { + "p": 4, + "sValue": "787" + } + ] + }, + { + "measObjInstId": "RncFunction=RF-1,UtranCell=Gbg-998", + "suspectFlag": "false", + "measResults": [ + { + "p": 1, + "sValue": "898" + }, + { + "p": 2, + "sValue": "905" + }, + { + "p": 3, + "sValue": "127" + }, + { + "p": 4, + "sValue": "238" + } + ] + }, + { + "measObjInstId": "RncFunction=RF-1,UtranCell=Gbg-999", + "suspectFlag": "true", + "measResults": [ + { + "p": 1, + "sValue": "454" + }, + { + "p": 2, + "sValue": "569" + }, + { + "p": 3, + "sValue": "672" + }, + { + "p": 4, + "sValue": "785" + } + ] + } + ] + } + ] + } + } + } +} diff --git a/src/onaptests/templates/artifacts/pnf_instantiation_ves_event.json.j2 b/src/onaptests/templates/artifacts/pnf_instantiation_ves_event.json.j2 new file mode 100644 index 0000000..892b966 --- /dev/null +++ b/src/onaptests/templates/artifacts/pnf_instantiation_ves_event.json.j2 @@ -0,0 +1,50 @@ +{ + "event": { + "commonEventHeader": { + "domain": "pnfRegistration", + "eventId": "ORAN_SIM_400600927_2020-04-02T17:20:22.2Z", + "eventName": "pnfRegistration_EventType5G", + "eventType": "EventType5G", + "sequence": 0, + "priority": "Low", + "reportingEntityId": "", + "reportingEntityName": "ORAN_SIM_400600927", + "sourceId": "{{ source_name }}", + "sourceName": "{{ source_name }}", + "startEpochMicrosec": 94262132085746, + "lastEpochMicrosec": 94262132085746, + "nfNamingCode": "sdn controller", + "nfVendorName": "sdn", + "timeZoneOffset": "+00:00", + "version": "4.0.1", + "vesEventListenerVersion": "7.0.1" + }, + "pnfRegistrationFields": { + "pnfRegistrationFieldsVersion": "2.0", + "lastServiceDate": "2019-08-16", + "macAddress": "D7:64:C8:CC:E9:32", + "manufactureDate": "2019-08-16", + "modelNumber": "Simulated Device Melacon", + "oamV4IpAddress": "10.42.6.245", + "oamV6IpAddress": "0:0:0:0:0:ffff:a0a:011", + "serialNumber": "ORAN_SIM-172.30.1.6-400600927-Simulated Device Melacon", + "softwareVersion": "2.3.5", + "unitFamily": "Simulated Device", + "unitType": "ntsim_oran", + "vendorName": "Melacon", + "additionalFields": { + "oamPort": "830", + "protocol": "SSH", + "username": "netconf", + "password": "netconf", + "reconnectOnChangedSchema": "false", + "sleep-factor": "1.5", + "tcpOnly": "false", + "connectionTimeout": "20000", + "maxConnectionAttempts": "100", + "betweenAttemptsTimeout": "2000", + "keepaliveDelay": "120" + } + } + } +} diff --git a/src/onaptests/templates/artifacts/pnf_registration_dmaap_event_template.json.j2 b/src/onaptests/templates/artifacts/pnf_registration_dmaap_event_template.json.j2 new file mode 100644 index 0000000..8d79bf4 --- /dev/null +++ b/src/onaptests/templates/artifacts/pnf_registration_dmaap_event_template.json.j2 @@ -0,0 +1,55 @@ +[ + { + "event":{ + "commonEventHeader":{ + "sourceId":"", + "startEpochMicrosec":94262132085746, + "eventId":"ORAN_SIM_400600927_2020-04-02T17:20:22.2Z", + "timeZoneOffset":"+00:00", + "reportingEntityId":"", + "internalHeaderFields":{ + "collectorTimeStamp":"Mon, 06 19 2023 05:59:16 GMT" + }, + "eventType":"EventType5G", + "priority":"Low", + "version":"4.0.1", + "nfVendorName":"sdn", + "reportingEntityName":"ORAN_SIM_400600927", + "sequence":0, + "domain":"pnfRegistration", + "lastEpochMicrosec":94262132085746, + "eventName":"pnfRegistration_EventType5G", + "vesEventListenerVersion":"7.0.1", + "sourceName":"{{ sourceName }}", + "nfNamingCode":"sdn controller" + }, + "pnfRegistrationFields":{ + "serialNumber":"{{ serialNumber}}", + "additionalFields":{ + "protocol":"SSH", + "password":"netconf", + "oamPort":"830", + "betweenAttemptsTimeout":"2000", + "keepaliveDelay":"120", + "sleep-factor":"1.5", + "reconnectOnChangedSchema":"false", + "connectionTimeout":"20000", + "maxConnectionAttempts":"100", + "username":"netconf", + "tcpOnly":"false" + }, + "lastServiceDate":"2019-08-16", + "unitFamily":"Simulated Device", + "vendorName":"Melacon", + "oamV6IpAddress":"{{ oamV6IpAddress }}", + "unitType":"ntsim_oran", + "macAddress":"D7:64:C8:CC:E9:32", + "pnfRegistrationFieldsVersion":"2.0", + "manufactureDate":"2019-08-16", + "modelNumber":"Simulated Device Melacon", + "oamV4IpAddress":"{{ oamV4IpAddress }}", + "softwareVersion":"2.3.5" + } + } + } +] \ No newline at end of file diff --git a/src/onaptests/templates/artifacts/pnf_registration_ves_event.json b/src/onaptests/templates/artifacts/pnf_registration_ves_event.json new file mode 100644 index 0000000..784e50a --- /dev/null +++ b/src/onaptests/templates/artifacts/pnf_registration_ves_event.json @@ -0,0 +1,50 @@ +{ + "event": { + "commonEventHeader": { + "domain": "pnfRegistration", + "eventId": "ORAN_SIM_400600927_2020-04-02T17:20:22.2Z", + "eventName": "pnfRegistration_EventType5G", + "eventType": "EventType5G", + "sequence": 0, + "priority": "Low", + "reportingEntityId": "", + "reportingEntityName": "ORAN_SIM_400600927", + "sourceId": "", + "sourceName": "dummy-ru-vesCollectorTest", + "startEpochMicrosec": 94262132085746, + "lastEpochMicrosec": 94262132085746, + "nfNamingCode": "sdn controller", + "nfVendorName": "sdn", + "timeZoneOffset": "+00:00", + "version": "4.0.1", + "vesEventListenerVersion": "7.0.1" + }, + "pnfRegistrationFields": { + "pnfRegistrationFieldsVersion": "2.0", + "lastServiceDate": "2019-08-16", + "macAddress": "D7:64:C8:CC:E9:32", + "manufactureDate": "2019-08-16", + "modelNumber": "Simulated Device Melacon", + "oamV4IpAddress": "10.42.6.245", + "oamV6IpAddress": "0:0:0:0:0:ffff:a0a:011", + "serialNumber": "ORAN_SIM-172.30.1.6-400600927-Simulated Device Melacon", + "softwareVersion": "2.3.5", + "unitFamily": "Simulated Device", + "unitType": "ntsim_oran", + "vendorName": "Melacon", + "additionalFields": { + "oamPort": "830", + "protocol": "SSH", + "username": "netconf", + "password": "netconf", + "reconnectOnChangedSchema": "false", + "sleep-factor": "1.5", + "tcpOnly": "false", + "connectionTimeout": "20000", + "maxConnectionAttempts": "100", + "betweenAttemptsTimeout": "2000", + "keepaliveDelay": "120" + } + } + } +} diff --git a/src/onaptests/templates/artifacts/ves_message_file.json b/src/onaptests/templates/artifacts/ves_message_file.json new file mode 100644 index 0000000..9b7f65c --- /dev/null +++ b/src/onaptests/templates/artifacts/ves_message_file.json @@ -0,0 +1,40 @@ +{ + "event": { + "commonEventHeader": { + "domain": "notification", + "eventId": "5ed35a0328d2be7ee400345405f7539a", + "eventName": "Notification_notifyMOIChanges", + "eventType": "Cell", + "reportingEntityName": "NonRTRIC-CMS", + "lastEpochMicrosec": 1606197734860, + "priority": "Normal", + "sequence": 0, + "sourceName": "du-1", + "startEpochMicrosec": 1606197734860, + "version": "4.1", + "vesEventListenerVersion": "7.2" + }, + "notificationFields": { + "additionalFields": { + "nfType": "du" + }, + "arrayOfNamedHashMap": [ + { + "name": "value", + "hashMap": { + "nrPCI": "873" + } + }, + { + "name": "oldValue", + "hashMap": { + "nrPCI": "871" + } + } + ], + "changeIdentifier": "479e1247-77e2-308d-9dd5-47fef2a06676", + "changeType": "Notification_NRCellDUCellStateChanged", + "notificationFieldsVersion": "2.0" + } + } +} diff --git a/src/onaptests/templates/artifacts/ves_message_file_negative.json b/src/onaptests/templates/artifacts/ves_message_file_negative.json new file mode 100644 index 0000000..5ddca50 --- /dev/null +++ b/src/onaptests/templates/artifacts/ves_message_file_negative.json @@ -0,0 +1,40 @@ +{ + "event": { + "commonEventHeader": { + "domain": "notification", + "eventId": "5ed35a0328d2be7ee400345405f7539a", + "eventName": "Notification_notifyMOIChanges", + "eventType": "Cell", + "reportingEntityName": "NonRTRIC-CMS", + "lastEpochMicrosec": 1606197734860, + "priority": "Normal", + "sequence": 0, + "sourceName": "empty", + "startEpochMicrosec": 1606197734860, + "version": "4.1", + "vesEventListenerVersion": "7.2" + }, + "notificationFields": { + "additionalFields": { + "nfType": "du" + }, + "arrayOfNamedHashMap": [ + { + "name": "value", + "hashMap": { + "nrPCI": "873" + } + }, + { + "name": "oldValue", + "hashMap": { + "nrPCI": "871" + } + } + ], + "changeIdentifier": "479e1247-77e2-308d-9dd5-47fef2a06676", + "changeType": "Notification_NRCellDUCellStateChanged", + "notificationFieldsVersion": "2.0" + } + } +} diff --git a/src/onaptests/templates/slack-notifications/notifications.jinja b/src/onaptests/templates/slack-notifications/notifications.jinja new file mode 100644 index 0000000..3ac4ee1 --- /dev/null +++ b/src/onaptests/templates/slack-notifications/notifications.jinja @@ -0,0 +1,124 @@ +[ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": ":fire: *{{env}} <{{ test_suite_link }}|{{ test_suite_name}}> FAILURES*" + } + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + {%- if components_failing == 1 %} + "text": ":slam: *1 CATEGORY IS FAILING*" + {%- elif components_failing == "UNDEFINED" %} + "text": ":slam: *DISCOVERED TEST ISSUES*" + {%- else %} + "text": ":slam: *{{ components_failing }} CATEGORIES ARE FAILING*" + {%- endif %} + }, + { + "type": "mrkdwn", + "text": "`{%- for component, failures in result_dict.items() %}{{component}}{%- if not loop.last %}, {% endif %}{%- endfor %}`" + } + ] + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "Check tests' artifacts in Testkube for more details" + } + ] + }, + {%- if has_test_error %} + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "[?] Result requires a verification in test's logs" + } + ] + }, + {%- endif %} + { + "type": "divider" + }, + {%- for component, failures in result_dict.items() %} + { + "type": "section", + "text": { + "type": "mrkdwn", + {%- if failures['since'] > 1 %} + "text": "[{{ component }}] - since {{failures['since']}} days" + {%- else %} + "text": "[{{ component }}]" + {%- endif %} + } + }, + {%- for test_failure in failures['results'] if not (test_failure['cleanup'] and ignore_cleanup_steps) %} + {%- if test_failure['foldable'] %} + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + {%- if test_failure['link'] != "" %} + "text": ":white_small_square: The same in {%- if test_failure['questionable'] %} [?]{%- endif %} <{{ test_failure['link']|safe }}|{{ test_failure['name'] }}>: {{ test_failure['description'] }}" + {%- else %} + "text": ":white_small_square: The same in {%- if test_failure['questionable'] %} [?]{%- endif %} {{ test_failure['name'] }}: {{ test_failure['description'] }}" + {%- endif %} + } + ] + }, + {%- else %} + { + "type": "section", + "text": { + "type": "mrkdwn", + {%- if test_failure['link'] != "" %} + "text": ":black_small_square: {%- if test_failure['questionable'] %} [?]{%- endif %} <{{ test_failure['link']|safe }}|{{ test_failure['name'] }}>: {{ test_failure['description'] }}" + {%- else %} + "text": ":black_small_square: {%- if test_failure['questionable'] %} [?]{%- endif %} {{ test_failure['name'] }}: {{ test_failure['description'] }}" + {%- endif %} + } + }, + {%- endif %} + {%- if (test_failure['reasons'] | length) > 0 and not test_failure['foldable'] %} + { + "type": "context", + "elements": [ + {%- for reason in test_failure['reasons'] %} + {%- if loop.index < 10 %} + { + "type": "mrkdwn", + "text": "`{{ reason[:75] | replace("\n", " ") }}{%- if (reason | length) > 75 %}(...){%- endif %}`" + }{%- if not loop.last and loop.index < 10 %},{%- endif %} + {%- endif %} + {%- if loop.index == 10 %} + { + "type": "mrkdwn", + "text": "`There is more resources failing. Check basic-status status-details.json`" + } + {%- endif %} + {%- endfor %} + ] + }, + {%- endif %} + {%- endfor %} + { + "type": "divider" + }, + {%- endfor %} + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": ":tim: watches You. Good luck!" + } + } +] diff --git a/src/onaptests/templates/vnf-services/basic_cnf_macro-service.yaml.j2 b/src/onaptests/templates/vnf-services/basic_cnf_macro-service.yaml.j2 index b58e9f0..2551660 100644 --- a/src/onaptests/templates/vnf-services/basic_cnf_macro-service.yaml.j2 +++ b/src/onaptests/templates/vnf-services/basic_cnf_macro-service.yaml.j2 @@ -3,6 +3,7 @@ tosca_file_from_SDC: service-basic_cnf_macro-template version: "1.0" subscription_type: "basic_cnf_macro" + instantiation_type: "Macro" vnfs: - vnf_name: {{ service_name }} properties: diff --git a/src/onaptests/templates/vnf-services/generic_network-service.yaml b/src/onaptests/templates/vnf-services/generic_network-service.yaml new file mode 100644 index 0000000..2093c6b --- /dev/null +++ b/src/onaptests/templates/vnf-services/generic_network-service.yaml @@ -0,0 +1,50 @@ +--- +SDBH-Network-svc: + tosca_file_from_SDC: service-basic_cnf_macro-template + version: "1.0" + subscription_type: "basic_cnf_macro" + instantiation_type: "Macro" + vnfs: + - vnf_name: sdbh-vnf + properties: + controller_actor: "CDS" + skip_post_instantiation_configuration: False + sdnc_artifact_name: "vnf" + sdnc_model_version: "1.0.0" + sdnc_model_name: "CBA_GNB_SIM_TEST" + heat_files_to_upload: templates/heat-files/basic_cnf_macro/basic_cnf_macro.zip + vnf_parameters: [ + { + "name": "k8s-rb-profile-namespace", + "value": "onap-tests" + }, + { + "name": "k8s-rb-profile-k8s-version", + "value": "1.19.0" + } + ] + vf_module_parameters: + - vf_module_name: helm_cuup + parameters: [ + { + "name": "vf_module_label", + "value": "helm_apache" + }, + { + "name": "k8s-rb-profile-name", + "value": "node-port-profile" + } + ] + networks: + - network_name: net_internal + vl_name: "Network" + subnets: [ + { + "subnet-name": "net_internal-subnet", + "start-address": "10.200.0.0", + "cidr-mask": "24", + "ip-version": "4", + "dhcp-enabled": False, + "gateway-address": "10.200.0.1", + } + ] diff --git a/src/onaptests/templates/vnf-services/instantiate_service_without_resource.yaml b/src/onaptests/templates/vnf-services/instantiate_service_without_resource.yaml new file mode 100644 index 0000000..4ec70c4 --- /dev/null +++ b/src/onaptests/templates/vnf-services/instantiate_service_without_resource.yaml @@ -0,0 +1,3 @@ +--- +service_without_resources: + instantiation_type: "Macro" diff --git a/src/onaptests/templates/vnf-services/modify-service-pnf.yaml b/src/onaptests/templates/vnf-services/modify-service-pnf.yaml new file mode 100644 index 0000000..ad26b09 --- /dev/null +++ b/src/onaptests/templates/vnf-services/modify-service-pnf.yaml @@ -0,0 +1,9 @@ +--- +testing-1209: + tosca_file_from_SDC: service-Testing1209-template + version: "1.0" + subscription_type: "net" + instantiation_type: "Macro" + pnfs: + - pnf_name: "ru-1309-new" + heat_files_to_upload: templates/artifacts/pNF.csar diff --git a/src/onaptests/templates/vnf-services/pnf-service.yaml.j2 b/src/onaptests/templates/vnf-services/pnf-service.yaml.j2 index 0c13f0a..62d2698 100644 --- a/src/onaptests/templates/vnf-services/pnf-service.yaml.j2 +++ b/src/onaptests/templates/vnf-services/pnf-service.yaml.j2 @@ -7,7 +7,3 @@ pnfs: - pnf_name: "{{ service_name }}" heat_files_to_upload: templates/artifacts/pNF.csar - pnf_artifact_type: "CONTROLLER_BLUEPRINT_ARCHIVE" - pnf_artifact_name: "CBA_enriched.zip" - pnf_artifact_label: "cbapnf" - pnf_artifact_file_path: "/tmp/PNF_DEMO_enriched.zip" diff --git a/src/onaptests/utils/exceptions.py b/src/onaptests/utils/exceptions.py index 0d7ecee..b28c02a 100644 --- a/src/onaptests/utils/exceptions.py +++ b/src/onaptests/utils/exceptions.py @@ -4,6 +4,7 @@ # are made available under the terms of the Apache License, Version 2.0 # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 + """Module to define pythonsdk-test exceptions.""" __author__ = "Morgan Richomme " @@ -170,7 +171,19 @@ class DcaeException(OnapTestException): super().__init__(__message) +class CbaVerificationException(OnapTestException): + """CBA verification Exception.""" + def __init__(self, __message="CBA verification has not succeeded"): + super().__init__(__message) + + class StatusCheckException(OnapTestException): """Status Check exception.""" def __init__(self, __message="Namespace status check has failed"): super().__init__(__message) + + +class DataInconsistentException(OnapTestException): + """Data consistency check exception.""" + def __init__(self, __message="Data inconsistency in AAI and CPS"): + super().__init__(__message) diff --git a/src/onaptests/utils/gitlab.py b/src/onaptests/utils/gitlab.py new file mode 100644 index 0000000..c053c65 --- /dev/null +++ b/src/onaptests/utils/gitlab.py @@ -0,0 +1,115 @@ +"""Helpers for reading data from GitLab.""" + +from dataclasses import dataclass +from typing import Any, Dict, List + +import requests +from dacite import from_dict # type: ignore +from onapsdk.configuration import settings + + +@dataclass +class GitLabDirectoryEntry: + """Dataclass for holding directory items from GitLab.""" + + id: str + name: str + type: str + path: str + mode: str + + @classmethod + def load(cls, data: Dict[str, Any]) -> "GitLabDirectoryEntry": + """Create a GitLabDirectoryEntry object from the dict. + + Returns: + GitLabDirectoryEntry: GitLabDirectoryEntry object created from the dictionary + """ + return from_dict(data_class=cls, data=data) # type: ignore + + +class GitLabClient: + """Class that provides methods to read directory entries and files from GitLab.""" + + TIMEOUT = 60 + + @classmethod + def _get_headers(cls): + """Generates headers for rest request""" + return { + "Accept": "application/json", + "Content-Type": "application/json", + "PRIVATE-TOKEN": settings.GITLAB_ACCESS_TKN, + } + + @classmethod + def get_directory_entries( + cls, commit_ref: str, directory_path: str, gitlab_id: str, + ) -> List[GitLabDirectoryEntry]: + """Get a list of all directory entries from a GitLab project directory. + + Args: + commit_ref (str): The branch name or commit id in GitLab to be read. + directory_path (str): The path to the directory in the GitLab project. + gitlab_id (str): ID of Gitlab project to be read. + Returns: + List[GitLabDirectoryEntry]: A list of directory entries. + """ + gitlab_url = f"{settings.GITLAB_BASE_URL}/projects/{gitlab_id}/repository/tree" + params = {"path": directory_path, "ref": commit_ref} + dir_list = requests.get( + gitlab_url, params=params, headers=cls._get_headers(), timeout=cls.TIMEOUT + ).json() + return [GitLabDirectoryEntry.load(dir_entry) for dir_entry in dir_list] + + @classmethod + def get_text_file_content(cls, commit_ref: str, file_path: str, gitlab_id: str,) -> str: + """Get the content of a text file from a GitLab project directory. + + Args: + commit_ref (str): The branch name or commit id in GitLab to be read. + file_path (str): Path to the file, including file name, in the GitLab project. + gitlab_id (str): ID of Gitlab project to be read. + Returns: + str: The content of the file. + """ + path = file_path.replace("/", "%2F") + gitlab_url = f"{settings.GITLAB_BASE_URL}/projects/{gitlab_id}/repository/files/{path}/raw" + params = {"ref": commit_ref} + return requests.get( + gitlab_url, params=params, headers=cls._get_headers(), timeout=cls.TIMEOUT + ).text + + @classmethod + def download_repo_archive( + cls, + commit_ref: str, + git_directory_path: str, + directory_path: str, + zip_name: str, + gitlab_id: str, + ) -> str: + """Get the content GitLab project directory as zip-archive. + + Args: + commit_ref (str): The branch name or commit id in GitLab to be read. + git_directory_path (str): The path to the directory in gitrepo to be downloaded. + directory_path (str): The path where the zip-file will be stored. + zip_name (str): name of the zip-directory. + gitlab_id (str): ID of Gitlab project to be read. + Returns: + path: Path to zip-archive. + """ + gitlab_url = ( + f"{settings.GITLAB_BASE_URL}/projects/{gitlab_id}/repository/archive.zip" + ) + params = {"sha": commit_ref, "path": git_directory_path} + request = requests.get( + url=gitlab_url, params=params, headers=cls._get_headers(), timeout=cls.TIMEOUT + ) + + path = f"{directory_path}/{zip_name}" + with open(path, "wb") as zip_ref: + zip_ref.write(request.content) + + return path diff --git a/src/onaptests/utils/kubernetes.py b/src/onaptests/utils/kubernetes.py index b86326d..927dfef 100644 --- a/src/onaptests/utils/kubernetes.py +++ b/src/onaptests/utils/kubernetes.py @@ -37,11 +37,21 @@ class KubernetesHelper: try: secret = api_instance.read_namespaced_secret(secret_name, namespace) if secret.data: - if (login_key in secret.data and password_key in secret.data): - login_base64 = secret.data[login_key] - login = base64.b64decode(login_base64).decode("utf-8") + error = False + login = None + password = None + if login_key: + if login_key in secret.data: + login_base64 = secret.data[login_key] + login = base64.b64decode(login_base64).decode("utf-8") + else: + error = True + if password_key in secret.data: password_base64 = secret.data[password_key] password = base64.b64decode(password_base64).decode("utf-8") + else: + error = True + if not error: return login, password raise EnvironmentPreparationException( "Login key or password key not found in secret") diff --git a/src/onaptests/utils/kubernetes_kafka.py b/src/onaptests/utils/kubernetes_kafka.py new file mode 100644 index 0000000..0168c36 --- /dev/null +++ b/src/onaptests/utils/kubernetes_kafka.py @@ -0,0 +1,117 @@ +import base64 +import json +import logging +from pathlib import Path + +from jinja2 import Environment, FileSystemLoader +from kubernetes import client, config +from kubernetes.client.exceptions import ApiException +from onapsdk.configuration import settings + +from onaptests.utils.exceptions import OnapTestException + +logger = logging.getLogger(__name__) + + +def create_topic(topic_name): + """ + Creates a Kafka topic in the Kubernetes cluster. + + Args: + topic_name (str): The name of the Kafka topic to create. + """ + config.load_incluster_config() + api_instance = client.CustomObjectsApi() + + environment = Environment(loader=FileSystemLoader(Path(__file__).parent.parent + .joinpath("templates/artifacts/"))) + template = environment.get_template("create_kafka_topic_template.json.j2") + + create_topic_json_parameter = { + "namespace": settings.KUBERNETES_NAMESPACE, + "topicName": settings.TOPIC_NAME, + } + + create_topic_json = template.render(create_topic_json_parameter) + body = json.loads(create_topic_json) + + try: + api_response = api_instance.create_namespaced_custom_object( + group=settings.KUBERNETES_API_GROUP, + version=settings.KUBERNETES_API_VERSION, + namespace=settings.KUBERNETES_NAMESPACE, + plural=settings.KUBERNETES_API_PLURAL, + body=body + ) + logger.info("Kafka topic created successfully: %s", api_response) + except Exception as ce: + logger.error("Failed to create topic on Kafka: %s", {str(ce)}) + raise OnapTestException(ce) from ce + + +def delete_topic(topic_name): + """ + Deletes a Kafka topic from the Kubernetes cluster. + + Args: + topic_name (str): The name of the Kafka topic to delete. + """ + config.load_incluster_config() + api_instance = client.CustomObjectsApi() + + try: + api_instance.delete_namespaced_custom_object( + group=settings.KUBERNETES_API_GROUP, + version=settings.KUBERNETES_API_VERSION, + namespace=settings.KUBERNETES_NAMESPACE, + plural=settings.KUBERNETES_API_PLURAL, + name=topic_name, + body=client.V1DeleteOptions(), + ) + logger.info("Kafka topic deleted successfully: %s", topic_name) + except ApiException as ce: + logger.error("Failed to delete topic on Kafka: %s", {str(ce)}) + raise OnapTestException(ce) from ce + + +class KubernetesKafka: + """ + Handles operations related to Kafka on Kubernetes. + """ + + def __init__(self): + self.namespace = settings.KUBERNETES_NAMESPACE + self.secret_name = settings.KAFKA_USER + self.secret = None + + def read_kafka_admin_secret(self): + """ + Reads the Kafka admin secret from Kubernetes. + + Returns: + dict: The secret data. + """ + try: + config.load_incluster_config() + v1 = client.CoreV1Api() + self.secret = v1.read_namespaced_secret(name=self.secret_name, namespace=self.namespace) + return self.secret + except ApiException as e: + logger.error("Exception when calling CoreV1Api->read_namespaced_secret: %s", e) + return None + + def get_kafka_admin_password(self): + """ + Retrieves the Kafka admin password from the secret data. + + Returns: + str: The decoded Kafka admin password. + """ + if self.secret: + secret_data = self.secret.data + password_key = "password" + if password_key in secret_data: + encoded_password = secret_data[password_key] + decoded_password = base64.b64decode(encoded_password).decode('utf-8') + return decoded_password + return None diff --git a/src/onaptests/utils/ntp_checker.py b/src/onaptests/utils/ntp_checker.py new file mode 100644 index 0000000..5154b56 --- /dev/null +++ b/src/onaptests/utils/ntp_checker.py @@ -0,0 +1,35 @@ +import http.server +import json +import time + + +class NttpCheckerHandler(http.server.BaseHTTPRequestHandler): + """Basic HTTP server that can provide time difference information""" + + def do_POST(self): # noqa + """"Exposes /local-time-status that returns + time difference with reference to other + time provided as a request payload + """ + if self.path == "/local-time-status": + arrival_time = int(time.time() * 1000) + time_diff = None + if self.headers['Content-Length']: + data_string = self.rfile.read(int(self.headers['Content-Length'])) + data = json.loads(data_string) + if data["time"]: + reference_time = int(data["time"]) + time_diff = int(arrival_time - reference_time) + print(f"Time Diff: {time_diff}") # noqa + self.send_response(200) + self.send_header("Content-type", "application/json") + self.end_headers() + response = {"time": time_diff, "arrival": int(arrival_time * 1000)} + self.wfile.write(json.dumps(response).encode()) + else: + self.send_error(404, "Not Found") + + +server = http.server.HTTPServer(("", 8000), NttpCheckerHandler) +print("Starting server on port 8000") # noqa +server.serve_forever() diff --git a/src/onaptests/utils/slack.py b/src/onaptests/utils/slack.py new file mode 100644 index 0000000..d600d08 --- /dev/null +++ b/src/onaptests/utils/slack.py @@ -0,0 +1,43 @@ +import time + +from slack_sdk import WebClient + + +class SlackHelper: + """"Helper methods to send slack messages""" + + @classmethod + def send_slack_message(cls, channel: str, token: str, text: str, blocks=None, retry=3): + """"Send slack message with retry""" + slack_client = WebClient(token=token) + while True: + try: + slack_client.chat_postMessage( + channel=channel, + text=text, + blocks=blocks + ) + return + except Exception as e: + retry -= 1 + if retry <= 0: + raise e + time.sleep(5) + + @classmethod + def send_slack_file(cls, channel: str, token: str, text: str, file_path: str, retry=3): + """"Send slack message with retry""" + slack_client = WebClient(token=token) + while True: + try: + slack_client.files_upload( + channels=channel, + initial_comment=text, + file=file_path + ) + return + except Exception as e: + retry -= 1 + if retry <= 0: + raise e + time.sleep(5) diff --git a/tox.ini b/tox.ini index 6c1a015..2292c42 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,11 @@ [tox] minversion = 3.2.0 -envlist = json,yaml,md,pylama,validate +envlist = json,yaml,md,pylama,isort-check,validate skipsdist = true requires = pip >= 8 [testenv] -basepython = python3.8 +basepython = python3.9 allowlist_externals = git /bin/sh @@ -40,14 +40,6 @@ commands_pre = commands = /bin/bash -c "coala --non-interactive --disable-caching --no-autoapply-warn py --files $( /tmp/.coalist_rst" -deps = -r ./docs/requirements-docs.txt -commands = - /bin/sh -c "sphinx-build -n -W -b html docs docs/build/html $( Date: Thu, 24 Apr 2025 15:07:37 +0200 Subject: [PATCH 07/16] [BASIC-CNF-MACRO] Revert the CBA file use old CBA file in the artifacts Issue-ID: TEST-404 Change-Id: Icad1e9693675ea2535cc41ab375a41350eb04ee5 Signed-off-by: Andreas Geissler --- .../templates/artifacts/basic_cnf_cba_enriched.zip | Bin 63637 -> 63641 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/onaptests/templates/artifacts/basic_cnf_cba_enriched.zip b/src/onaptests/templates/artifacts/basic_cnf_cba_enriched.zip index 3df16f37e49b140293c31fa420a0ea473e0516f2..be5c4daae9ef50ea612b10343a8cf32d769e92a7 100644 GIT binary patch delta 4061 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 Date: Fri, 25 Apr 2025 14:55:48 +0200 Subject: [PATCH 08/16] [TESTS] Remove CBA-verification test Removed unused test Issue-ID: TEST-404 Change-Id: I1c6e74ce37320f642e238d515ff003277d9cf2d6 Signed-off-by: Andreas Geissler --- setup.cfg | 1 - .../configuration/basic_cnf_macro_settings.py | 4 +- .../configuration/cba_verification_settings.py | 69 ----- .../configuration/generic_network_settings.py | 1 - src/onaptests/scenario/basic_cnf_macro.py | 15 +- src/onaptests/scenario/cba_verification.py | 55 ---- src/onaptests/steps/instantiate/service_macro.py | 19 -- src/onaptests/steps/onboard/verify_cba.py | 287 --------------------- src/onaptests/utils/exceptions.py | 6 - 9 files changed, 5 insertions(+), 452 deletions(-) delete mode 100644 src/onaptests/configuration/cba_verification_settings.py delete mode 100644 src/onaptests/scenario/cba_verification.py delete mode 100644 src/onaptests/steps/onboard/verify_cba.py diff --git a/setup.cfg b/setup.cfg index 68fe394..c51ee26 100644 --- a/setup.cfg +++ b/setup.cfg @@ -80,7 +80,6 @@ xtesting.testcase = ves_publish = onaptests.scenario.publish_ves_event:VesCollectorTestCase basic_kafka = onaptests.scenario.basic_kafka:KafkaTestCase generic_network = onaptests.scenario.generic_network:GenericNetwork - cba_verification = onaptests.scenario.cba_verification:CbaVerification basic_intent = onaptests.scenario.basic_intent:IntentScenario instantiate_service_without_resource = onaptests.scenario.instantiate_service_without_resource:InstantiateServiceWithoutResource aai_initial_data_setup = onaptests.scenario.aai_initial_data_setup:AAICrud diff --git a/src/onaptests/configuration/basic_cnf_macro_settings.py b/src/onaptests/configuration/basic_cnf_macro_settings.py index 0ebd927..7c935a6 100644 --- a/src/onaptests/configuration/basic_cnf_macro_settings.py +++ b/src/onaptests/configuration/basic_cnf_macro_settings.py @@ -11,8 +11,7 @@ from .settings import * # noqa # Specific basic_cnf_macro with multicloud-k8s and yaml config scenario. SERVICE_DETAILS = ("Onboarding, distribution and instantiation of a Apache CNF " + - "using macro and native CNF path: cnf-adapter + K8sPlugin" + - "testing Onap Operator by create and check Service Instance Custom Resource.") + "using macro and native CNF path: cnf-adapter + K8sPlugin" ) CLEANUP_FLAG = True @@ -83,7 +82,6 @@ SERVICE_INSTANCE_NAME = f"basic_cnf_macro_{str(uuid4())}" MODEL_YAML_TEMPLATE = None -TEST_ONAP_OPERATOR = False GROUP = 'onap.com' VERSION = 'v1' SERVICE_INSTANCE_PLURAL = 'serviceinstances' diff --git a/src/onaptests/configuration/cba_verification_settings.py b/src/onaptests/configuration/cba_verification_settings.py deleted file mode 100644 index 5205ec5..0000000 --- a/src/onaptests/configuration/cba_verification_settings.py +++ /dev/null @@ -1,69 +0,0 @@ -import os - -from .settings import * # noqa - -SERVICE_NAME = "CBA_VERIFICATION" -SERVICE_DETAILS = """Verify if CBAs are deployed and their content is same like in gitlab""" -CLEANUP_FLAG = True -LOCAL_PATH = "/tmp" -B2B_EQUINIX_POC_CBA = { - "name": "B2B_EQUINIX_POC_CBA", - "version": "1.0.0", - "gitlab_project_id": "210484", - "gitlab_repo_cba": "cba", - "enrichment": True, - "gitlab_branch": "master", -} -B2B_POC_CBA = { - "name": "B2B_POC_CBA", - "version": "1.0.0", - "gitlab_project_id": "176661", - "gitlab_repo_cba": "cba", - "enrichment": True, - "gitlab_branch": "develop", -} -INTENT_MGMT_CBA = { - "name": "INTENT-MGMT-CBA", - "version": "1.0.0", - "gitlab_project_id": "199504", - "gitlab_repo_cba": "Intent-Mgmt-CBA/INTENT-MGMT-CBA", - "enrichment": True, - "gitlab_branch": "develop", -} -CBA_GNB_SIM = { - "name": "CBA_GNB_SIM", - "version": "1.0.0", - "gitlab_project_id": "215376", - "gitlab_repo_cba": "gnb-simulator-with-ran-inventory/common-cba", - "enrichment": True, - "gitlab_branch": "main", -} -HUAWEI_EMS_CBA = { - "name": "SLICING_CBA", - "version": "1.1.0", - "gitlab_project_id": "124384", - "gitlab_repo_cba": "cba", - "enrichment": True, - "gitlab_branch": "develop", -} -CBA_LIST = [ - HUAWEI_EMS_CBA -] -test_env_name = os.getenv('TEST_ENV_NAME') -if test_env_name and 'b2b' in test_env_name: - CBA_LIST = [ - B2B_EQUINIX_POC_CBA, - B2B_POC_CBA, - INTENT_MGMT_CBA - ] - -ENRICHMENT_FILES = ['Definitions/data_types.json', - 'Definitions/node_types.json', - 'Definitions/resources_definition_types.json'] -IGNORE_FILES = ['Tests/', - 'pom.xml', - '.DS_Store', - 'Archive.zip', - 'CBA_GNB_SIM.zip'] -GITLAB_BASE_URL = "https://gitlab.devops.telekom.de/api/v4" -GITLAB_ACCESS_TKN = "glpat-nzqxs_HMQLYz7SrhxKi2" diff --git a/src/onaptests/configuration/generic_network_settings.py b/src/onaptests/configuration/generic_network_settings.py index 7440fe8..2c0e4c9 100644 --- a/src/onaptests/configuration/generic_network_settings.py +++ b/src/onaptests/configuration/generic_network_settings.py @@ -62,7 +62,6 @@ VIM_SERVICE_URL = 'http://10.12.25.2:5000/v3' TENANT_ID = '123456' TENANT_NAME = 'dummy_test' -TEST_ONAP_OPERATOR = False GROUP = 'onap.com' VERSION = 'v1' SERVICE_INSTANCE_PLURAL = 'serviceinstances' diff --git a/src/onaptests/scenario/basic_cnf_macro.py b/src/onaptests/scenario/basic_cnf_macro.py index d13053b..ee7be6b 100644 --- a/src/onaptests/scenario/basic_cnf_macro.py +++ b/src/onaptests/scenario/basic_cnf_macro.py @@ -4,9 +4,8 @@ from yaml import SafeLoader, load from onaptests.scenario.scenario_base import (BaseStep, ScenarioBase, YamlTemplateBaseScenarioStep) -from onaptests.steps.instantiate.service_macro import ( - YamlTemplateServiceMacroInstantiateStep, - YamlTemplateServiceOperatorInstantiateStep) +from onaptests.steps.instantiate.service_macro import \ + YamlTemplateServiceMacroInstantiateStep from onaptests.steps.onboard.cds import CbaPublishStep @@ -19,15 +18,11 @@ class BasicCnfMacroStep(YamlTemplateBaseScenarioStep): Substeps: - CbaPublishStep - YamlTemplateServiceMacroInstantiateStep - - CheckOnapVnfCr. """ super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) self._yaml_template: dict = None self.add_step(CbaPublishStep()) - if not settings.TEST_ONAP_OPERATOR: - self.add_step(YamlTemplateServiceMacroInstantiateStep()) - elif settings.TEST_ONAP_OPERATOR: - self.add_step(YamlTemplateServiceOperatorInstantiateStep()) + self.add_step(YamlTemplateServiceMacroInstantiateStep()) @property def description(self) -> str: @@ -39,9 +34,7 @@ class BasicCnfMacroStep(YamlTemplateBaseScenarioStep): str: Step description """ - if not settings.TEST_ONAP_OPERATOR: - return "Basic CNF macro scenario step" - return "Basic CNF macro and Onap-Operator scenario step" + return "Basic CNF macro scenario step" @property def component(self) -> str: diff --git a/src/onaptests/scenario/cba_verification.py b/src/onaptests/scenario/cba_verification.py deleted file mode 100644 index 3640e90..0000000 --- a/src/onaptests/scenario/cba_verification.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python -"""CBA Verification test case.""" -from onapsdk.configuration import settings - -from onaptests.scenario.scenario_base import BaseScenarioStep, ScenarioBase -from onaptests.steps.base import BaseStep -from onaptests.steps.onboard.verify_cba import TestCbaStep - - -class CbaVerificationStep(BaseScenarioStep): - """Basic cba verification step.""" - - def __init__(self): - """CbaVerification step. - - Substeps: - - TestCbaStep - """ - super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) - for cba in settings.CBA_LIST: - self.add_step(TestCbaStep(cba)) - - @property - def description(self) -> str: - """Step description. - - Used for reports - - Returns: - str: Step description - - """ - return "Verify CBA deployed into environment" - - @property - def component(self) -> str: - """Component name. - - Name of component which step is related with. - Most is the name of ONAP component. - - Returns: - str: Component name - - """ - return "CBA" - - -class CbaVerification(ScenarioBase): - """CBA verification scenario.""" - - def __init__(self, **kwargs): - """Init CBA Verification.""" - super().__init__('cba_verification', **kwargs) - self.test = CbaVerificationStep() diff --git a/src/onaptests/steps/instantiate/service_macro.py b/src/onaptests/steps/instantiate/service_macro.py index 0bfab64..d81a369 100644 --- a/src/onaptests/steps/instantiate/service_macro.py +++ b/src/onaptests/steps/instantiate/service_macro.py @@ -22,7 +22,6 @@ from onaptests.steps.cloud.connect_service_subscription_to_cloud_region import \ ConnectServiceSubToCloudRegionStep from onaptests.steps.cloud.customer_service_subscription_create import \ CustomerServiceSubscriptionCreateStep -from onaptests.steps.cloud.onap_operator_cr_check import CheckOnapVnfCr from onaptests.steps.instantiate.sdnc_service import TestSdncStep from onaptests.steps.onboard.service import (VerifyServiceDistributionStep, YamlTemplateServiceOnboardStep) @@ -196,24 +195,6 @@ class YamlTemplateServiceMacroInstantiateBaseStep(YamlTemplateBaseStep): tenant, owning_entity, so_service, skip_pnf_registration_event, vnf_params_list) -class YamlTemplateServiceOperatorInstantiateStep(YamlTemplateServiceMacroInstantiateBaseStep): - """Instantiate SO service with Operator.""" - - def __init__(self): - """Init YamlTemplateServiceOperatorInstantiateStep.""" - super().__init__(cleanup=BaseStep.HAS_NO_CLEANUP) - self.add_step(CheckOnapVnfCr(service_macro_base=self)) - - @property - def description(self) -> str: - """Step description.""" - return "Instantiate SO service with Operator" - - @YamlTemplateBaseStep.store_state - def execute(self): - super().execute() - - class YamlTemplateServiceMacroInstantiateStep(YamlTemplateServiceMacroInstantiateBaseStep): """Instantiate SO service.""" diff --git a/src/onaptests/steps/onboard/verify_cba.py b/src/onaptests/steps/onboard/verify_cba.py deleted file mode 100644 index 7345fe8..0000000 --- a/src/onaptests/steps/onboard/verify_cba.py +++ /dev/null @@ -1,287 +0,0 @@ -#!/usr/bin/env python -"""CBA Verification test case.""" -import difflib -import json -import os -import shutil -from io import BytesIO - -from onapsdk.cds.blueprint import Blueprint -from onapsdk.cds.cds_element import CdsElement -from onapsdk.configuration import settings -from onapsdk.exceptions import ResourceNotFound - -from onaptests.steps.base import BaseStep -from onaptests.utils.exceptions import CbaVerificationException -from onaptests.utils.gitlab import GitLabClient - - -class TestCbaBaseStep(BaseStep): - """Test CBA Base Step""" - - def __init__(self, cleanup=BaseStep.HAS_NO_CLEANUP, break_on_error: bool = True): - """TestCbaBaseStep.""" - super().__init__(cleanup=cleanup, break_on_error=break_on_error) - - @property - def component(self) -> str: - """Component name. - - Name of component which step is related with. - Most is the name of ONAP component. - - Returns: - str: Component name - - """ - return "CBA" - - -class DownloadCbaStep(TestCbaBaseStep, CdsElement): - """Step to download CBA content and convert it to zip.""" - - def __init__(self, cba_data): - """Download CBA step.""" - - super().__init__(cleanup=settings.CLEANUP_FLAG, break_on_error=True) - self.cba_data = cba_data - self.cba = None - - def get_details_by_name_and_version(self, name: str, version: str): - """Get CBA details from its name and version.""" - cba_details = self.send_message( - action="Download CBA Details", - method="GET", - url=f"{self._url}/api/v1/blueprint-model/by-name/{name}/version/{version}", - auth=self.auth - ) - return cba_details - - def get_by_name_and_version(self, name: str, version: str) -> Blueprint: - """Get CBA blueprint from its name and version.""" - cba_data = self.send_message( - action="Download CBA Content", - method="GET", - url=f"{self._url}/api/v1/blueprint-model/download/by-name/{name}/version/{version}", - auth=self.auth - ) - return Blueprint(BytesIO(cba_data.content).read()) - - @property - def description(self) -> str: - """Step description. - - Used for reports - - Returns: - str: Step description - - """ - name = self.cba_data["name"] - return f"Downloading CBA {name} from CDS" - - def zip_cba_from_cds(self): - """Check CBA zip downloaded from CDS.""" - name = self.cba_data["name"] - version = self.cba_data["version"] - zip_path = f"{settings.LOCAL_PATH}/{name}/{version}" - os.makedirs(zip_path, exist_ok=True) - zip_file = f"{zip_path}/cba.zip" - try: - self.get_details_by_name_and_version(name, version) - blueprint = self.cba = self.get_by_name_and_version(name, version) - blueprint.save(zip_file) - shutil.unpack_archive(zip_file, zip_path, 'zip') - except ResourceNotFound as exc: - self._logger.error(f"CBA {name}-{version} Not Found") - raise CbaVerificationException("CBA Not Found in CDS") from exc - - def delete_cba_directory(self): - """Delete local CBA content.""" - name = self.cba_data["name"] - delete_path = f"{settings.LOCAL_PATH}/{name}" - if os.path.exists(delete_path): - try: - shutil.rmtree(delete_path) - self._logger.info(f"The directory '{delete_path}' has been successfully deleted.") - except OSError as e: - self._logger.eror(f"Error: {e}") - error_message = f"Error while deleting directory: {e}" - self._logger.error(error_message) - raise CbaVerificationException(error_message) from e - else: - self._logger.info(f"The directory '{delete_path}' does not exist.") - - @BaseStep.store_state - def execute(self) -> None: - """Download CBA content and convert it to zip.""" - super().execute() - self.zip_cba_from_cds() - - @BaseStep.store_state(cleanup=True) - def cleanup(self) -> None: - """Delete downloaded cba content directory.""" - self.delete_cba_directory() - super().cleanup() - - -class TestCbaStep(TestCbaBaseStep): - """Step to check if workflow exists and compare CBA from Gitlab with CBA downloaded from CDS.""" - - def __init__(self, cba_data): - """Initialize step. - - Substeps: - - DownloadCbaStep - """ - super().__init__(break_on_error=False) - self.cba_data = cba_data - self.download_cba_step = DownloadCbaStep(cba_data) - self.add_step(self.download_cba_step) - - @property - def description(self) -> str: - """Step description. - - Used for reports - - Returns: - str: Step description - - """ - name = self.cba_data["name"] - return f"Compare CBA {name} Content with Gitlab" - - def show_differences(self, git_file_content, local_file_content, entry_path): - """Show CBA file difference: git and local.""" - diff = difflib.unified_diff( - git_file_content.splitlines(), - local_file_content.splitlines(), - fromfile=entry_path + ' (git)', - tofile=entry_path + ' (local)' - ) - diff_text = "\n".join(diff) - return f"\n\n{diff_text}\n" - - def load_json(self, git_file_content, local_file_path): - """Load CBA json file with formatting.""" - try: - git_file_content = json.loads(git_file_content) - if os.path.exists(local_file_path): - with open(local_file_path, 'r', encoding="utf-8") as local_file: - local_file_content = local_file.read() - local_file_content = json.loads(local_file_content) - git_file_content = dict(sorted(git_file_content.items())) - local_file_content = dict(sorted(local_file_content.items())) - return (json.dumps(git_file_content, indent=4, sort_keys=True), - json.dumps(local_file_content, indent=4, sort_keys=True)) - except json.JSONDecodeError as e: - self._logger.error(f"Error decoding JSON: {e}") - return None, None - - def check_if_path_in_pattern_list(self, path, patterns): - """Check if file path is in the pattern.""" - for pattern in patterns: - if pattern in path: - return True - return False - - def compare_directories_recursive( # noqa: C901 - self, branch, git_directory_path, local_directory_path, gitlab_id): - """Compare local and gitlab CBA directories.""" - enrichment = self.cba_data["enrichment"] - try: - git_directory_entries = GitLabClient.get_directory_entries( - branch, git_directory_path, gitlab_id) - if len(git_directory_entries) == 0: - self._logger.error(f"Folder '{git_directory_path}' on gitlab " - f"with projct ID: {gitlab_id} does not exist") - raise CbaVerificationException("Cannot locate repo folder in gitlab") - except TypeError as exc: - self._logger.error(f"Branch '{branch}' on gitlab " - f"with projct ID: {gitlab_id} does not exist") - raise CbaVerificationException("Cannot locate branch in gitlab") from exc - ident_files = [] - diff_files = [] - git_only_files = [] - differences = {} - for entry in git_directory_entries: - if self.check_if_path_in_pattern_list(entry.path, settings.IGNORE_FILES): - # Check if the path is in ignore_files set - continue - binary_check = False - if entry.type == "tree": - ident, diff, git, show = self.compare_directories_recursive( - branch, entry.path, local_directory_path + '/' + entry.name, gitlab_id) - ident_files.extend(ident) - diff_files.extend(diff) - git_only_files.extend(git) - differences.update(show) - else: # It's a file - git_file_content = GitLabClient.get_text_file_content(branch, entry.path, gitlab_id) - git_file_content = git_file_content.replace("\r\n", "\n").strip() - entry_name = os.path.basename(entry.path) - local_file_path = os.path.join(local_directory_path, entry_name) - if os.path.exists(local_file_path): - try: - with open(local_file_path, 'r', encoding='utf-8') as local_file: - local_file_content = local_file.read().replace("\r\n", "\n").strip() - except UnicodeDecodeError: - binary_check = True - if binary_check is False: - if 'Definitions/' in entry.path: - git_file_content, local_file_content = self.load_json( - git_file_content, local_file_path) - if git_file_content == local_file_content: - ident_files.append(entry.path) - else: - if (not enrichment or - not self.check_if_path_in_pattern_list(entry.path, - settings.ENRICHMENT_FILES)): - diff_files.append(entry.path) - diff_text = self.show_differences( - git_file_content, local_file_content, entry.path - ) - differences[entry.path] = diff_text - else: - git_only_files.append(entry.path) - return ident_files, diff_files, git_only_files, differences - - def summarize_comparison(self, local_path, gitlab_id, branch): - """Summarize CBA comparison.""" - gitlab_repo_cba = self.cba_data["gitlab_repo_cba"] - ident_files, diff_files, git_only_files, differences = self.compare_directories_recursive( - branch, gitlab_repo_cba, - local_path, gitlab_id) - error = False - if ident_files: - self._logger.info(f"Identical files: {ident_files}") - self._logger.info(f"There are {len(ident_files)} identical files") - if diff_files: - dif_error_message = f"Different files: {diff_files}" - self._logger.error(dif_error_message) - self._logger.error(f"There are {len(diff_files)} different files") - error = True - if git_only_files: - git_error_message = f"Files that exists only on Gitlab: {git_only_files}" - self._logger.error(git_error_message) - self._logger.error(f"There are {len(git_only_files)} files that exist only on Gitlab") - error = True - if differences: - for file_path, diff_text in differences.items(): - self._logger.info(f"Differences in file: {file_path}") - self._logger.info(diff_text) - if error: - raise CbaVerificationException( - "CBA content differencies between Gitlab and CDS") - - @BaseStep.store_state - def execute(self) -> None: - """Check if workflow exists and compare CBA from Gitlab with CBA downloaded from CDS.""" - super().execute() - gitlab_id = str(self.cba_data["gitlab_project_id"]) - branch = self.cba_data["gitlab_branch"] - name = self.cba_data["name"] - version = self.cba_data["version"] - local_path = f"{settings.LOCAL_PATH}/{name}/{version}" - self.summarize_comparison(local_path, gitlab_id, branch) diff --git a/src/onaptests/utils/exceptions.py b/src/onaptests/utils/exceptions.py index b28c02a..5d8a15f 100644 --- a/src/onaptests/utils/exceptions.py +++ b/src/onaptests/utils/exceptions.py @@ -171,12 +171,6 @@ class DcaeException(OnapTestException): super().__init__(__message) -class CbaVerificationException(OnapTestException): - """CBA verification Exception.""" - def __init__(self, __message="CBA verification has not succeeded"): - super().__init__(__message) - - class StatusCheckException(OnapTestException): """Status Check exception.""" def __init__(self, __message="Namespace status check has failed"): -- 2.16.6 From 80f8dc3897df1b84f1845fb8b8507bb85ee0ed15 Mon Sep 17 00:00:00 2001 From: Andreas Geissler Date: Wed, 7 May 2025 13:14:35 +0200 Subject: [PATCH 09/16] Update onapsdk version Use version onapsdk version >= 14.3.0 to support the "kafka" module Issue-ID: TEST-404 Change-Id: I39271909af675616ca8c715af018eeaeaeb9fe25 Signed-off-by: Andreas Geissler --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a3392cc..71d2295 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ cryptography==38.0.4 xtesting==0.91.0 avionix>=0.4.5 openstacksdk>=0.61.0 -onapsdk==14.1.0 +onapsdk>=14.3.0 jinja2>3 kubernetes>=22.6.0 setuptools==65.3.0 -- 2.16.6 From 74efd36530a5ce0aabdf22a9926117a48b95ec71 Mon Sep 17 00:00:00 2001 From: Andreas Geissler Date: Thu, 8 May 2025 10:20:58 +0200 Subject: [PATCH 10/16] [TESTS] Update onapsdk version in setup.cfg update onapsdk version in setup.cfg Issue-ID: TEST-404 Change-Id: I2e1b17ddf503a929fd903a6f57ef950bbd812f7e Signed-off-by: Andreas Geissler --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index c51ee26..9012be5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,7 +25,7 @@ install_requires = xtesting==0.91.0 avionix>=0.4.5 openstacksdk>=0.61.0 - onapsdk==14.1.0 + onapsdk>=14.3.0 jinja2>3 kubernetes>=22.6.0 setuptools==65.3.0 -- 2.16.6 From 28d34e7c039b3d1abc618d91efc53a887237bb41 Mon Sep 17 00:00:00 2001 From: Fiete Ostkamp Date: Thu, 8 May 2025 13:35:11 +0200 Subject: [PATCH 11/16] Use vesclient snapshot image - change vesclient snapshot image (1.0.1 -> 1.0.2-STAGE-20250508T090515Z) before releasing it Issue-ID: TEST-421 Change-Id: I7e19bd69ab3e6667767d285843b22b9b0fc55c6d Signed-off-by: Fiete Ostkamp --- .../templates/artifacts/pnf-simulator.tar.gz | Bin 1366 -> 1282 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/onaptests/templates/artifacts/pnf-simulator.tar.gz b/src/onaptests/templates/artifacts/pnf-simulator.tar.gz index 024f73290211a72b0785f10a6ff95ce942632d18..d15444ce75321fa1aacd4c27ed80c4059e716d43 100644 GIT binary patch literal 1282 zcmV+d1^xOTiwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PI;`bE3!>%`>0k{_+lKFqmI>V-hoy+KpOjX1C_W>cG{Z(sWbZ ztuyY_eD^ItQ80>5cFoQd=OwXe?(Ki)+yf+hV#YL(!qlj=siJtss21|#<};PrTF{uC zy%vNJ(!RXR{t`l}e~EMHp4l!TSGMi6?e-b5+vL(c1M=$32VkZ&m1pGDxvG=#GAH^rJ$VQ(6k4D;N7z zsZ<9%`0LN$<5SmmTK_Wu_Dg`d8blztrV&Tk7gBrRToL=q0GJCli`OID6N4BDpA1)R zUTx;}I&l0tQ!Ptynpi?kJ)00>U!*@Tgq-H>5!X1CG!;yXPl_Pc996&~Vman; zpx8rbuqV%=ZJ?M+!h;d#HeY?=#)H+J|R=-e*h(7 z!MATE-sYU}}b<~%MHYS^bm2w`D6<{^56a~+VP$nRsuj87_ReI=k-}lD% z-TTq)yYa0*^56NxPSFb>E6gt>-c;+=0CvV5^m?Ol-yaVD=nZa<2)?Q3hb4I&b_QMl z;g}h0R+P;oOIhB!FKgfG*q<@h7c2@E9-N;S*J_SpvCBegwYfPJo!$yiy1p4nq7pM1 zpz`3`x;3v~4`Rm4Y2vh{PxWUHE|#7dxt5DWL|mH@k97ECg&T{xV?OKpxE_ndRO|F= zQGE7=F4XdxLOG8D^n)NBKwejiRm+2w#))yF7q^itP3pkWytU>vSmWUOzdRs6@<34M z|6SLq)PLJ;lcxTk0+r|gyz~$Ay*^ppFT{3LM$T*HHJ7I32rbrBPEjAO-evo7;FOi7 zdX`Ov2^zkmjPd|;k$mf&ei;YwKkc%9rbavP(8!uzaQ4OV01GOcist&)Ajje^FDmy15G(#a$WR$_L; zW=f;1bB}v9e20mw*ZuYD*`2dk_9#k@6j}s=c`&-^@AIQ|$q%%pJCYo2en^eC4xveXw(f?DR-@SuE sDDtoTLH3n@rZ9wvuRoJPdO#ZbH)znH!7qZp0{{U3|JZlp3jinp01^R^_y7O^ literal 1366 zcmV-c1*!TUiwFoG&@W{G18{C;EpusYb!=gDZ*nelVR8WNnOkq$HWbJ6tWUxD-Hvs$ zP`#XxVXIdA#?%9w)6kGV|VNSOD=TF)=kIi^&H68P1DdXi2Y-l(di`ByAX;TMxH>Iuiqzh#=bZtIo-^KYAwh4X&~cFljxlR0k(ERFawW{K)7 zX&il{jRW&<=sjz_{%uJ1E+EHpj0@6z(Vp($e?I>-4L>j;L!P*Vrm4JK=-S6H30!hr z&Ak>gMFXm+s}T~>2Nucv7a`z0 zsA2O2t6+ECuN($c?<0 zOe7mU31d3n_Fj?ytl%(uo@;VfaP952r*Va7biCyu( zk>5^v@Esoj2jagDf9v>fI)+ume;bNp{67Qr_+N$oArDTE`Sl0;LjTrsWu$CI$@Uh> zZ@k`6{^Kldi2FWaZ@j-%-=AxH71Em#@!eoNsYStc1Z?dJL#;*?5JIO{H>1hj?cJ3( zxtZP$MpN(o;Q`wpF3J*B$Prv|pGPj4Tn$&-P%7q3og8$UyW&%a zUNV`_wFe^!TL~D(K2M4*aIq)uuNz&)hkTwn4c^j-CO#7wFaCS%KmYqa-7h(G{%hMt zrT^VR|GQ2P_5Um!t^Ysr+;6XfZ$DnyA>Dh?I+`X3(px?%oOeH&Er($3|jcH~etV&izuaKLx8 z@=BtAL>*nN5xWmsej0~_ea@uW;R#JUT+CfPcihW7c?ro?ewZjW7sbA~lgz40ItwQK zC}fFp^-i~=KkrC>)veWcl4keKn>T0I*XH`a%BBCMm;b@|Z}edYaswP7GbK2{eeg34Ez`Nhr#Mgp>P*6gAa%GRi)44luJftg2!b1F-+43{+ax? z%GDO-Mx$FSiOsDCTjnaU-Ul=*)XHOa?U6%!UwhCH1VIo4K@bE%5ClOG1VIo4K@bE% Y5ClOG1VIo4L0*x60Mgw($^cLR0N-=8#Q*>R -- 2.16.6 From 5a95224aeebed8da91780c2d18fcf059ee30be59 Mon Sep 17 00:00:00 2001 From: Andreas Geissler Date: Thu, 8 May 2025 16:38:25 +0200 Subject: [PATCH 12/16] [TEST] Make the simulator's URL and Port configurable - Add URLs and Ports configurable Issue-ID: TEST-404 Change-Id: Iee2ee962000709bd54d453371fb8dfc915917f7f Signed-off-by: Andreas Geissler --- src/onaptests/configuration/cds_resource_resolution_settings.py | 2 ++ src/onaptests/configuration/pnf_macro_settings.py | 2 ++ src/onaptests/steps/simulator/cds_mockserver.py | 6 +++++- src/onaptests/steps/simulator/pnf_simulator_cnf/pnf_register.py | 4 +++- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/onaptests/configuration/cds_resource_resolution_settings.py b/src/onaptests/configuration/cds_resource_resolution_settings.py index 140cd27..fd995cd 100644 --- a/src/onaptests/configuration/cds_resource_resolution_settings.py +++ b/src/onaptests/configuration/cds_resource_resolution_settings.py @@ -26,6 +26,8 @@ MSB_K8S_PROFILE_NAME = f"cds-ms-prof-{str(uuid4())}" K8S_VERSION = "1.0" K8S_CONFIG = get_resource_location("templates/artifacts/config") K8S_ADDITIONAL_RESOURCES_NAMESPACE = "onap-tests" +CDS_MOCKSERVER_URL = "portal.api.simpledemo.onap.org" +CDS_MOCKSERVER_PORT = 30726 CDS_MOCKSERVER_EXPECTATIONS = [ { "method": "GET", diff --git a/src/onaptests/configuration/pnf_macro_settings.py b/src/onaptests/configuration/pnf_macro_settings.py index 7ce67a0..c7f249d 100644 --- a/src/onaptests/configuration/pnf_macro_settings.py +++ b/src/onaptests/configuration/pnf_macro_settings.py @@ -63,6 +63,8 @@ SERVICE_INSTANCE_NAME = f"TestPNFMacroInstantiation_{str(uuid4())}" DCAE_VES_COLLECTOR_POD_NAME = "dcae-ves-collector" PNF_WAIT_TIME = 60.0 PNF_REGISTRATION_NUMBER_OF_TRIES = 20 +PNF_SIMULATOR_URL = "portal.api.simpledemo.onap.org" +PNF_SIMULATOR_PORT = 30999 # Disable YAML SDC model definition which means all SDC config reside in SERVICE_YAML_TEMPLATE MODEL_YAML_TEMPLATE = None diff --git a/src/onaptests/steps/simulator/cds_mockserver.py b/src/onaptests/steps/simulator/cds_mockserver.py index 8773248..927ed36 100644 --- a/src/onaptests/steps/simulator/cds_mockserver.py +++ b/src/onaptests/steps/simulator/cds_mockserver.py @@ -38,14 +38,18 @@ class CdsMockserverCnfConfigureStep(BaseStep): """Create mockserver expectations. Use settings values: + - CDS_MOCKSERVER_URL. + - CDS_MOCKSERVER_PORT. - CDS_MOCKSERVER_EXPECTATIONS. """ super().execute() time.sleep(60) # Wait for mockserver + sim_url = settings.CDS_MOCKSERVER_URL + sim_port = settings.CDS_MOCKSERVER_PORT for expectation in settings.CDS_MOCKSERVER_EXPECTATIONS: try: response = requests.put( - "http://portal.api.simpledemo.onap.org:30726/mockserver/expectation", + f"http://{sim_url}:{sim_port}/mockserver/expectation", json={ "httpRequest": { "method": expectation["method"], diff --git a/src/onaptests/steps/simulator/pnf_simulator_cnf/pnf_register.py b/src/onaptests/steps/simulator/pnf_simulator_cnf/pnf_register.py index 4ef92ef..dee96b8 100644 --- a/src/onaptests/steps/simulator/pnf_simulator_cnf/pnf_register.py +++ b/src/onaptests/steps/simulator/pnf_simulator_cnf/pnf_register.py @@ -107,13 +107,15 @@ class PnfSimulatorCnfRegisterStep(BaseStep): # Let's still wait for PNF simulator to make sure it's initialized time.sleep(settings.PNF_WAIT_TIME) ves_proto, ves_ip, ves_port = self.get_ves_protocol_ip_and_port() + sim_url = settings.PNF_SIMULATOR_URL + sim_port = settings.PNF_SIMULATOR_PORT registration_number: int = 0 registered_successfully: bool = False while (registration_number < settings.PNF_REGISTRATION_NUMBER_OF_TRIES and not registered_successfully): try: response = requests.post( - "http://portal.api.simpledemo.onap.org:30999/simulator/start", + f"http://{sim_url}:{sim_port}/simulator/start", json={ "simulatorParams": { "repeatCount": 9999, -- 2.16.6 From 1e51a3f2daa9e7ccca4af5cb752c3e10ddb8fc3a Mon Sep 17 00:00:00 2001 From: Michal Jagiello Date: Fri, 9 May 2025 11:48:19 +0200 Subject: [PATCH 13/16] Distribute service for macro service instantiation Use distribution step instead of onboard for instantitation Issue-ID: TEST-404 Signed-off-by: Michal Jagiello Change-Id: I8cbd8c6304662b957312e598212053b41d2b9e4a --- src/onaptests/steps/instantiate/service_macro.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/onaptests/steps/instantiate/service_macro.py b/src/onaptests/steps/instantiate/service_macro.py index d81a369..e074a5e 100644 --- a/src/onaptests/steps/instantiate/service_macro.py +++ b/src/onaptests/steps/instantiate/service_macro.py @@ -24,7 +24,7 @@ from onaptests.steps.cloud.customer_service_subscription_create import \ CustomerServiceSubscriptionCreateStep from onaptests.steps.instantiate.sdnc_service import TestSdncStep from onaptests.steps.onboard.service import (VerifyServiceDistributionStep, - YamlTemplateServiceOnboardStep) + YamlTemplateServiceDistributionStep) class YamlTemplateServiceMacroInstantiateBaseStep(YamlTemplateBaseStep): @@ -45,7 +45,7 @@ class YamlTemplateServiceMacroInstantiateBaseStep(YamlTemplateBaseStep): self._model_yaml_template: dict = None self._service_instance_name: str = None if not settings.ONLY_INSTANTIATE: - self.add_step(YamlTemplateServiceOnboardStep()) + self.add_step(YamlTemplateServiceDistributionStep()) if any( filter(lambda x: x in self.yaml_template[self.service_name].keys(), -- 2.16.6 From 63ed47de06ccc7d0ccc404662a0e8890cfa7fef2 Mon Sep 17 00:00:00 2001 From: Fiete Ostkamp Date: Wed, 14 May 2025 10:10:20 +0200 Subject: [PATCH 14/16] Use newer ves-client snapshot image - contains fix for segfault when invoking the java command Issue-ID: INT-2321 Change-Id: Ic30d022a5df21cd8e8b659b2dd94137d1e9b1525 Signed-off-by: Fiete Ostkamp --- .../templates/artifacts/pnf-simulator.tar.gz | Bin 1282 -> 1283 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/onaptests/templates/artifacts/pnf-simulator.tar.gz b/src/onaptests/templates/artifacts/pnf-simulator.tar.gz index d15444ce75321fa1aacd4c27ed80c4059e716d43..4afd6d1f4ddf87b56ad3094189a455127688dad3 100644 GIT binary patch delta 1237 zcmV;`1SHU=CAyV-TO9nMQ)A@0?`bM66RJ~t!kOJQnM+Eih*WK;`zb^VD-ZLMj0d%f^)GSSoeR4|Y@4)uU8i$F>@I2dE`Yo`^AT7oO@HMDd3CPp6w7JkPry}38m?aC>9D~E=2^Br!bBm#TWQ3 zYc-y5{aMIBxrSM}!QeDP7Y-dhW3?R;v4~|GKYEdVVI1WDin1lDe?$Q4_}^{!s{C)+ zt%m>SfN7dWB!BoqxCTHN(FMAY{x$#ts_7$DIM|YPwqxk->R1TAAH7+Dg1b@@w^E`;PLglj%xpr-fSdKZF zdhhzCL!1uj*zGC#Kj}KXkNflM5JHk6iU6~Q7J2jL&A+FB2l=ltiW$|YuF_RB1B{ti zN61e%1vUJ4>~6cvf5&N&hW}?lvHsIIR#z+AcnW#o!cD&6MueIsj84eI=p!fZdU1jICwXl z-3{)hH*aS*-qd^RP5OB+fV40_lennX+W{PmJAWPyr?Zhanfx&v-<%M!4YhHsLj;{Zk1M)o& z1aG-|lpsrv9G;mFNGg^iQ(AK3m<-#dcdpE^FmAlcx9tE!I>nP#>?}W&3gD zl$EA>nNEcX8oZ^9avw91{Lwr8JdWUh(tl<5OcjgZR1K)%zfFj}=l?s6|33?!<^M$}ZV_#`2YJFFC*CGF8moOUABr|FfF1@9lC+Uv|Xrhm&c+1#cYi zzRYb#d07haFzL^(`{U`|?cKFE?ayw9 z5YoQ9%>EKWs(*=d>7LmxAy>BTwC(m8vD@U*Jp=OU%m-kmG=G(627}WWJ=k^ljQMIv#3Gh$y!9ge!r00GIb}0c|A+w8@xOg}Rpo!n zwj2JR0;Xviv47xG;TZr?OsD8U_S*mmsisd(AihQ`dG{|1$vgOMtl=L?F1P5l7hVman; zpx8rbuqV%=ZJ?M+!h;d#HeY?=#)H+J|R=-e*h(7 z!MATlb>H{K z_uc!^?Yr@j8EjUR%_K`%-nuVq-|E<(G1eC>3KkxmpBL9^j$*OPLTa_SITfAW3Q)Sf8A+lN zGZ~=r;M=-2uU`*h#>;8qw53n=XAdrxo*B88i$p|Rn-Pz6_+*6}i@9Sy>-xAJi^Npx z^nYqmeD;Md)bg4_IgbMLgCHG1URR4%%Y&81iE*MAw~;JO>cG*wwdOTgv zKv3uZUDv79f7@-7rv9G-mFNGw^bhmBK3Ux_#CBCi&THj0m!{+hE!I>{Q6H|}W&3g9 zl$EA>mQ95T8or~9@&I#@eCwTl83*t`?SHaavP(8!uzaQ4OV01GOcist&)Ajje^FDmy)D;NSoSDNjucu1f_X5y>F@KSb;%F3r8|~hp-T7K zpG+bi>4gVf!LwIj**mfBa?n4YjZJOvgV?G6gN}du(6Qq1^*QRE|4ExvzW=$cE2q)_ yQ=s3ygF-0sulzywm4Bu%gov*{lR Date: Wed, 14 May 2025 15:31:32 +0200 Subject: [PATCH 15/16] Use newer snapshot image that is smaller - reduced image size (350MB -> 250MB) Issue-ID: INT-2317 Change-Id: Id96a1d7bd9d4355de50e6ec9e9366a99f2cc879a Signed-off-by: Fiete Ostkamp --- .../templates/artifacts/pnf-simulator.tar.gz | Bin 1283 -> 1282 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/onaptests/templates/artifacts/pnf-simulator.tar.gz b/src/onaptests/templates/artifacts/pnf-simulator.tar.gz index 4afd6d1f4ddf87b56ad3094189a455127688dad3..fa483a15da2f6ba1695ad8f7debba2b784458e6f 100644 GIT binary patch delta 1238 zcmV;{1S$K23W5rdJbzttqDU0YGr!_)-XRT&sqn@mW+t^8wbaaR&5PB6t3##frn*~a z+^PBRTY#cq3_960J5!vO#HP8ozs|V_Nchx@X&{BEQE5{}@tjdDF!hU`qhR7eO#@PyI~M4SkPFqI;P(NmNpkK!x* zp0^rLxcnkys64~0++c7TqX+vApRrgEiCDz4jkjK;Ul@D&zo2Z6>R%CnI{tUsmsS3^ zNT=cdDPWqW5q}Fl6P^JO#dL-qWWNo7kZSr!753I-oopDoxjGa=KPZ$rrKJ$Ma&bVF zN_D`4zyAt8KK5*<^_v0kvILmxK?H(p8gY~ZA+-n2C9y9JfQ4Z5cr&sWVh|(Y)6u%k ztIfPw2aaFos$~gI6HCaMXA?r~i}dG(kh8o!;u>d?rhkHI@o5pnTA&J8gj{>JMJ&f0 zjs5ps(;<#aT)RECotEofecGL$O9)AaC_>B|TIA~L>c3OKz5Lf0CyZ)T7uhPBAtp>L zW8}x1f*SricBftDzvDQU4gXJq?fOrXL|rUw<0;~y2RFrr8!>8{GCCy>qmRf``X4}v zSn%x|Sbrb$s*xQTE9Dt{|6VX|ZwHlNkVcf4uqdF)1KR*l$S_z@79gfN`25FK@*~nK zotl{0GQUwT6ZBw+fkdj&09YUORidrQreLL}#UGl{p=dOd)>aes&X{&+I*N25Rc!nxk0kvXEMBZ%#$0cLJ2IZ%2}- z#9RibJovV0&Fj~_nDcU)IBgkF{n>+ym1jn-)$(Aaable4@O^HaNKcuMWtM zJP_3Rf7f*?_1|_~x2gZ9K;`*AFa4u@uTNI@3$b07k@H%4&7~$Zv6jA@GSoa zB0Qe^+ZSGvfM@%ym7wgB&1WoM>GqQIJ1kSh+`VM%O7}mjDZAdTu=Hg|{GmS@Z@J)= z1KyRn)hN$PAs$BE$#r))zPr7<_Q&1HZGSlNAI2a0!@E!Z_^#ipM4eKm@Z8uje1Cm@ zOCvUyxR$B^uPik<5sudXAMk;-`roPQf6Hk#-+xYmgZ&@nT4|;-UufVc*V!hR%e@{Le+u#SWSO14y|K`4H#o_C7)II-`4ykciz-=IN*2EPdY2><~9|16hCv;Zgo0D_r& A2><{9 delta 1239 zcmV;|1StE03WExeJbzzvo46OvGoRxA@(vOB->+STr?*KLi90$AEb+;YPOJX7J)xUG@0b)KkBkD_GYE;@(VYFma3wd?@iArs)X~ZsG z3qlC#w%h4nLP+&5aoU{=yF+Z7w0m8rb3yDbY4%JC>5C{93Sllq1e2#QjvvJr z_$_NSo^btH$UwPlx{&@h00OG%BUL!ql6AIY=qZ?W|Wpf=*qPXFE8BPqdEmlLzTrlMnkI}+$iwI(GL`%X zP$Cw5{eKG9hpcL(N5)Ec2H(Erj62vt#povyCB`iDsdB+K02DIxHUE4RjM0}!H5vfhqrOR0m}~-8%6URofbF~z3%qP zH=NxK?xr_yXE)x|d+Sa5c`typFh7&HsMgy79Dj^E9uB9okvEzAF&y8V5WJ}8$0d1~ z^v475{*)OMD@rlRMwa*POWXH4j+Ts#1PlGO3zwJqwVI=t@3N3u6*s4%(|Z9**Nc%P zDzTJ4Di^-)TC@6fFP6NVCQ4dHRDW{eYU7!aYq^d^$h8^rPzR4zP*}_Z^V!wM-B=_h zT7Rdvi{i1*bgeem6v|cTqv!j{0J6H8uUZzYG)|0Sy}k)$X;Mdy=0|H@gB^~p|CD}$!wKwh0ZinNU_b`1w9N&HPrgy_ZCF-0qg_p*j;eQ+Q zTN<*Z#H~#IcV(%;nQ*fHe}@mO)&Fi)|65M0`Tlbj9PR%o=R&9NIn{Yf0)EjbIb~Bx z=kw6tirF<=Dvh$vJ-(>n2TWwW?(bgD9-PIdM_zKI(83qYh3WO^B|lo1{774RVCfaA zWUsyXJmjHXyD$(ueFc`j6B}#>{ZRAS*aqK;gZe-2dpGxeD+*qpqwe{ibV=p=U#Hb; zH~N1Lj0U%m3q|&o-%r2tFBJw5^4(`LNDfFt{{{^jH26jEcK`qY|Nn98oA3ZA006QX BeDeSR -- 2.16.6 From 524afd1c1bb7c582c9f4274098ef0b4e4acda28e Mon Sep 17 00:00:00 2001 From: Fiete Ostkamp Date: Mon, 19 May 2025 11:21:01 +0200 Subject: [PATCH 16/16] Use ves-client 1.0.2 image in pnf-simulator chart - use the latest ves-client release image Issue-ID: INT-2317 Change-Id: Ie73238bcf38b44177eef6042770c27ca4bc50f78 Signed-off-by: Fiete Ostkamp --- .../templates/artifacts/pnf-simulator.tar.gz | Bin 1282 -> 1261 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/onaptests/templates/artifacts/pnf-simulator.tar.gz b/src/onaptests/templates/artifacts/pnf-simulator.tar.gz index fa483a15da2f6ba1695ad8f7debba2b784458e6f..6ceb8c92fc0d0dfd5b9b98574d2e17b67c6fb5b4 100644 GIT binary patch delta 1217 zcmV;y1U~zM3hfDyJbzzv+PD|Zvp>cC<=u`9flU48Cgj)5Zh!&O-PspLu`kpUS@KAN zmhJSr@7TtF2^g9ky6yP9B*^l;`ghJfwj;hUL+VLkYE;@(LAYX63wd?>iArs4Xvi+! z3PK3!UtcGG2_f~rq;uW7uzSSr^lrNSe*c2lebTotfV?^L5r0@IP2~l7bFTX2eiG0q z_=r*kf;+Ib4Ih;!gGeX8U05PVNj3WL0a*yinSh0m;0x~srRj+<5(;4_VRyC*$UOaA^=VN?{`R@ z|6TjK<^MTgnt!Gd3ceJM0T6_Ai4G*c4FI2N`b-rLGqTPLh89;RLg*)jGNrT>Lf0;i zsZy~HIPmwM-pA*m-Rb_%05~iGW;O^#>RpL-o}B;%lulyQOtK)NUh47Q`rrckZ}4_(iT z2Y-;()qK^`V3l!V80pPjAS;tPax_0$^I8-*y8dqu$oD)DH2MEtuT!i4cJHS3|7St% z`9CfF({!)TR`+wU&C1ASqr9fl6rG^On#v{WTojr_(wWtfq6kZxThHu30X~0$zGnxAD%2JCn;bi^)4u2om zsQ>-C{&zdQ_WRFSaJ2uUoC}@2=Tzq{3HU{$$d5K9Khl=&S$c&k-fMTU2za134h#iPUV$a=#D?2J z|9m#K#dl(_{!a$(-Q&Ot{kP|6dOH3m{rdO6-ZkmB`hO0Lhxd>RMf#QBOTO~26#5YG f;xie<2c)Hcixw?f{37@#009609y#JE04M+ekh5@@ delta 1238 zcmV;{1S$LN34#icJbzttqDU0YGr!_)-XRT&sqn@mW+t^8wbaaR&5PB6t3##frn*~a z+^PBRTY#cq3_960J5!vO#HP8ozs|V_Nchx@X&{BEQE5{}@tjdDF!hU`qhR7eO#@PyI~M4SkPFqI;P(NmNpkK!x* zp0^rLxcnkys64~0++c7TqX+vApRrgEiCDz4jkjK;Ul@D&zo2Z6>R%CnI{tUsmsS3^ zNT=cdDPWqW5q}Fl6P^JO#dL-qWWNo7kZSr!753I-oopDoxjGa=KPZ$rrKJ$Ma&bVF zN_D`4zyAt8KK5*<^_v0kvILmxK?H(p8gY~ZA+-n2C9y9JfQ4Z5cr&sWVh|(Y)6u%k ztIfPw2aaFos$~gI6HCaMXA?r~i}dG(kh8o!;u>d?rhkHI@o5pnTA&J8gj{>JMJ&f0 zjs5ps(;<#aT)RECotEofecGL$O9)AaC_>B|TIA~L>c3OKz5Lf0CyZ)T7uhPBAtp>L zW8}x1f*SricBftDzvDQU4gXJq?fOrXL|rUw<0;~y2RFrr8!>8{GCCy>qmRf``X4}v zSn%x|Sbrb$s*xQTE9Dt{|6VX|ZwHlNkVcf4uqdF)1KR*l$S_z@79gfN`25FK@*~nK zotl{0GQUwT6ZBw+fkdj&09YUORidrQreLL}#UGl{p=dOd)>aes&X{&+I*N25Rc!nxk0kvXEMBZ%#$0cLJ2IZ%2}- z#9RibJovV0&Fj~_nDcU)IBgkF{n>+ym1jn-)$(Aaable4@O^HaNKcuMWtM zJP_3Rf7f*?_1|_~x2gZ9K;`*AFa4u@uTNI@3$b07k@H%4&7~$Zv6jA@GSoa zB0Qe^+ZSGvfM@%ym7wgB&1WoM>GqQIJ1kSh+`VM%O7}mjDZAdTu=Hg|{GmS@Z@J)= z1KyRn)hN$PAs$BE$#r))zPr7<_Q&1HZGSlNAI2a0!@E!Z_^#ipM4eKm@Z8uje1Cm@ zOCvUyxR$B^uPik<5sudXAMk;-`roPQf6Hk#-+xYmgZ&@nT4|;-UufVc*V!hR%e@{Le+u#SWSO14y|K`4H#o_C7)II-`4ykciz-=IN*2EPdY2><~9|16hCv;Zgo0DgXZ AasU7T -- 2.16.6