From 1d2ff5146cb0ed85af7f58afb09126bf7234221c Mon Sep 17 00:00:00 2001 From: lloretgalleg Date: Sat, 1 Aug 2020 06:05:58 +0000 Subject: [PATCH] initial version Signed-off-by: lloretgalleg --- Dockerfile | 50 ++++ osm_ee/__init__.py | 0 osm_ee/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 128 bytes osm_ee/__pycache__/base_ee.cpython-36.pyc | Bin 0 -> 2426 bytes osm_ee/__pycache__/exceptions.cpython-36.pyc | Bin 0 -> 599 bytes .../frontend_client.cpython-36.pyc | Bin 0 -> 1764 bytes .../__pycache__/frontend_grpc.cpython-36.pyc | Bin 0 -> 2074 bytes .../__pycache__/frontend_pb2.cpython-36.pyc | Bin 0 -> 3465 bytes .../frontend_server.cpython-36.pyc | Bin 0 -> 2882 bytes osm_ee/base_ee.py | 105 ++++++++ osm_ee/exceptions.py | 27 ++ osm_ee/frontend.proto | 39 +++ osm_ee/frontend_client.py | 85 +++++++ osm_ee/frontend_grpc.py | 56 +++++ osm_ee/frontend_pb2.py | 233 ++++++++++++++++++ osm_ee/frontend_server.py | 89 +++++++ osm_ee/scripts/ee_start.sh | 30 +++ osm_ee/util/__init__.py | 0 .../util/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 133 bytes .../__pycache__/util_ansible.cpython-36.pyc | Bin 0 -> 866 bytes .../util/__pycache__/util_ee.cpython-36.pyc | Bin 0 -> 996 bytes osm_ee/util/util_ansible.py | 46 ++++ osm_ee/util/util_ee.py | 60 +++++ osm_ee/vnf/__init__.py | 0 .../vnf/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 132 bytes osm_ee/vnf/__pycache__/vnf_ee.cpython-36.pyc | Bin 0 -> 3381 bytes osm_ee/vnf/install.sh | 22 ++ osm_ee/vnf/vnf_ee.py | 54 ++++ setup.py | 59 +++++ 29 files changed, 955 insertions(+) create mode 100644 Dockerfile create mode 100644 osm_ee/__init__.py create mode 100644 osm_ee/__pycache__/__init__.cpython-36.pyc create mode 100644 osm_ee/__pycache__/base_ee.cpython-36.pyc create mode 100644 osm_ee/__pycache__/exceptions.cpython-36.pyc create mode 100644 osm_ee/__pycache__/frontend_client.cpython-36.pyc create mode 100644 osm_ee/__pycache__/frontend_grpc.cpython-36.pyc create mode 100644 osm_ee/__pycache__/frontend_pb2.cpython-36.pyc create mode 100644 osm_ee/__pycache__/frontend_server.cpython-36.pyc create mode 100644 osm_ee/base_ee.py create mode 100644 osm_ee/exceptions.py create mode 100644 osm_ee/frontend.proto create mode 100644 osm_ee/frontend_client.py create mode 100644 osm_ee/frontend_grpc.py create mode 100644 osm_ee/frontend_pb2.py create mode 100644 osm_ee/frontend_server.py create mode 100755 osm_ee/scripts/ee_start.sh create mode 100644 osm_ee/util/__init__.py create mode 100644 osm_ee/util/__pycache__/__init__.cpython-36.pyc create mode 100644 osm_ee/util/__pycache__/util_ansible.cpython-36.pyc create mode 100644 osm_ee/util/__pycache__/util_ee.cpython-36.pyc create mode 100644 osm_ee/util/util_ansible.py create mode 100644 osm_ee/util/util_ee.py create mode 100644 osm_ee/vnf/__init__.py create mode 100644 osm_ee/vnf/__pycache__/__init__.cpython-36.pyc create mode 100644 osm_ee/vnf/__pycache__/vnf_ee.cpython-36.pyc create mode 100644 osm_ee/vnf/install.sh create mode 100644 osm_ee/vnf/vnf_ee.py create mode 100644 setup.py diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d811e1a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,50 @@ +# Copyright 2018 Telefonica S.A. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM ubuntu:18.04 + +# Set the working directory to /app +WORKDIR /app/EE + +# Libraries used by the base osm defined ee +RUN apt-get update && apt-get install -y git python3 python3-pip \ + && python3 -m pip install --upgrade pip \ + && python3 -m pip install -U grpcio-tools \ + && python3 -m pip install -U grpclib \ + && python3 -m pip install -U PyYAML + +# Copy the current directory contents into the container at /app/LCM +ADD . /app/EE + +# Install as module +RUN python3 -m pip install -e /app/EE + +# Install SNMP Generator and its dependencies +#RUN apt-get install -y python3-pip unzip build-essential libsnmp-dev wget curl +#RUN curl -s https://storage.googleapis.com/golang/go1.11.8.linux-amd64.tar.gz| tar -v -C /usr/local -xz +#ENV PATH $PATH:/usr/local/go/bin +#ENV GOPATH /go +#RUN go get github.com/go-logfmt/logfmt \ +# && go get github.com/go-kit/kit/log +#RUN wget -q https://github.com/prometheus/snmp_exporter/archive/v0.17.0.tar.gz -P /tmp/ \ +# && tar -C /tmp -xf /tmp/v0.17.0.tar.gz \ +# && (cd /tmp/snmp_exporter-0.17.0/generator && go build) \ +# && cp /tmp/snmp_exporter-0.17.0/generator/generator /usr/local/bin/snmp_generator + +EXPOSE 50051 + +#CMD python3 -m osm_ee.frontend_server +# For development +CMD [ "bash", "-c", "while true; do /app/EE/osm_ee/scripts/ee_start.sh ; sleep 5; done" ] diff --git a/osm_ee/__init__.py b/osm_ee/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/osm_ee/__pycache__/__init__.cpython-36.pyc b/osm_ee/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..678249a89339d67be2f4fa478230d00ac69bbca2 GIT binary patch literal 128 zcmXr!<>e9+xEjX*1dl-k3@`#24nSPY0whuxf*CX!{Z=v*frJsnFJ1kN{M=Oi{Nh{? wj!(`{N!8CwPfgW#bp;CmS@H3id6^~g@p=W7w>WHa^HWN5Qtd#-6az5>0J!oTYybcN literal 0 HcmV?d00001 diff --git a/osm_ee/__pycache__/base_ee.cpython-36.pyc b/osm_ee/__pycache__/base_ee.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f00b8d440a8d55e6f5b05b748e8ff56771be930b GIT binary patch literal 2426 zcmZuyOK;mo5Z+x;6h%G!$fIdcG;C0$Q0iDn(nApxMI4ujjTmxjIdMW1C1~wRqD+y> zauwK$l#7Di(&Pv9&}$F<75xpp?4g&Q`WJHQ45=hWQ4%{l`d~ytJeJi3uK+cRjA79$QgV;*0yka~Zp@iyiV`m# zG5L$20}D!-o3AJ(f(-0A@hX$Ag$Z?)m%JLcygDy)JEYzcj4zAoU`5nKT`bKDbLy>% z%HWJxox|z_Km)C_b3(~u(A%U@`3F#vR)gx|qqyt39c;e)3ZUGElHLL#2*L;GlrvuF zA$Y?xI6&v7XYvxaUJ|c_K%lmGg;$|2^BQbY*XErd6|Sq5Q+>ar*k?bK2wE(F(^*Sz?@U*sS;|O&Dra<8CBMxJVj~q!Yc-| zD=^9iRc;JwpjGBzBcqOdPxgSe*bE8IQuTZk^d(N!KHFuJL z3pu%rwIhzhRE2TR$&cuCWioWSVI*!j&u5KgU5b)k55{%5C)5t;LTVHHpk_&`jZvWb z+RV(Py0W?3y1RYPzq`HTY9kqmSQ|*1HX_)}v+s_hDBs?z2H&nV`^iu=;dog5PQpbq?g`O!-K+yNJTsns zbfPWa593hz{uOiv1PCFtTBy@HU8N2)*<>ld4(spcz4xL4Q_E2PfRf!h;CSIjN)#J_ zAEBo>r{Fhp3Z8jgpRp+$l;&hsfa|^R(X;^mV691g_fQ34?7$6jj>JjBl6Xbr85C6% zH4xes$D<(T;}lq~w%c3&efLR5s$9llLyCYm40#?K7P1ltL!nLV7Sbz$aUYClMCIaR zoLK=E`irrf(2?38fCpf~1|BA>3l2_A>)`S6!>OxKHo-IL4Y=a(Xc(|5ow8{GBb$H*3z{=vB-2jrd$jS1}tp0(`%vtGx z#I`|{b!4YMKPFQXY?hBo@&&J;&8H8hrn0A{IqkB%O`(^PCr}RHkKe%B%8@PqqGV=K zGP%M{z{z0Wa)!G)EhAcPOv|~216T{04`#oxAfO(=`r48GhRU^tg&X-gUdqo4yIT;3 z1#a>3D~6Wxp8vJRAhTgOR$G%V-DA-iE8zqk6(+G0a*VSz2mP08c|4#lk^8qxTc>i1 zlN?DCd(Umh&w?oAjudJv;X0{6jnm1cjoj=zb55KnCmfC9d~(&5GLaDVhyug@ zJ&sctp3iXmeaID-IPO5;bdv_l(8$kVbI=ikyo`GN)crjR9s10cyRoys>V z&He4&mM+1S3Y3!a94=e|;g!>%D|}1~dbO>R(MEa_cea&~0TQEE_uT!5do91czp?+Y z?eA>2_jMsvQr9=YPIw3$W=GLQfhW>s_qZcQxU^yCalt~ajXW+EImR3c)laxr%MZOs zJzg#6(9b#4%N(#mNO6BC(iF14rb3sqUHoC%`)^R$avb})L41=^WQEZ4j4_*9Mzvtu zYY<%)bLcYEReBL3?Nd5gS;X3h)vbn&X$lehzP5dTnDB9gde!%zj)N#4kzas)xrE{q z6rZEGh{8dEaeWFRrb>yyFY)EP1SLy;7JxJGXI9NBWn;Ma5HgeREF<0%rwB7>QBx$p9Qk1hNC7R2_-=~94>3=@e-Gjny8*SwX*Lj*Z} zJD;N2w_ literal 0 HcmV?d00001 diff --git a/osm_ee/__pycache__/frontend_client.cpython-36.pyc b/osm_ee/__pycache__/frontend_client.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cafe8a14093cf89d080c4f1b6671136c1bc6e871 GIT binary patch literal 1764 zcmZ8hUvC>l5Z~Rqv(M+V<0fvK^slKsC49jtr&ea1S?+Mha+kZ7d)%|U!5hd~+RS|JQ{(HTtt{X{ z*5++1yC{b|%sRYdWiRb!D|`j_4bl9O@E)8I{+PX>@;Z=YRkQ^CiER+R27OqYQ_&g| z`74|i!JJZ({{U-(;ORN!E#&8sw~?oSA!*ZHjFgtz` zSaNAj_~qkkxVr*9I0xrp9WKsYJiQ8+lL1^c9(&jql-`*WN*>{Umu#+_m?l2hq;>Pt zqd3nY-DGv|p&Vr+J$eE=@OT1B*WEWXWjaNh&aOK85~i;V+OI@&O6&e-vdA^$V*4o! zC%TZkda^%s&0Y9wA1uSF_5k=$y^G7xcJ4{YN{Mhx$gv1RXQ^ zP`iSeQmRJc>Bby=?juxRkXci^RWoUtv-}r4^^?||+#!q8pP$Wq9q4uv8jo2Eqc};Y zVwE#rMDvrbUa49Y)4k*jYN>FaJHiu<=WG#ylBaho|CYUL8s1*sxkvKAC3IWR z=>GD~)=`ncR-rPpqG2ImD?bF-+TOMb+#M`mNiJ{#5~ax+gGxA4S|>{xrQp?=# zb_DpEsT|I{dMJgNUCs<=W@o+~ebZ_+?(F>b)48o_ziV5M z3HxV2nGcL>oQ*ZVSeei0UH1)IP2UhKsY#FCtWs+G&Vj~tZd_{I5L!}S8GZvKCa-~{ zw$lA3XG5)H{Q>^9L4%vG(&d}qPPF~Cv^J^rvN~z7AOO#r|P8?Ae zjii~lC;DBD*RL3F@aCoIx3~^bU3L3~oTj-*dH-h-&GV^z9%f=0oXS}=jz?Z5E*F;WkA0IWmp2PL8ff*iv}N=nHZl)1EjLHW`92Eo=qpB3vrQxXv#%5Jr$zc?~?#_ zRmylUZ?;hG;XJKUzlEVFzP`MFQ$f6K>*eu(ug)+#dnFeCTAH;9*5!jmpi_5rY2o4D zFM|Z=YN~!9^1|aMTZj7k#zR%69VW5R5tbbvTrolqD0=}c*AkZK7g}P_&P-~#l>oSi z*H>nxZ zan)Kkkl?SH>sPRbx>BPms1`kH2Einp&EoVl2<~EuZv)eGi29rhOu=e-CG|cBCoEvs@7N)5f7m%e}3m$RBtO&ACVN*hqahAix1i&J!KA{LAiqrN0Hn`h6wg| z$d*`Xidd0&x2bjOQLu-CO@C+<05IY-&V%4FC<}}Mx^(zi%ms`UyX9BcF@}W(j1}K@ zZ22kr{tOv{wLr#w*!gy^?8F0uSFa84XNfTrM literal 0 HcmV?d00001 diff --git a/osm_ee/__pycache__/frontend_pb2.cpython-36.pyc b/osm_ee/__pycache__/frontend_pb2.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0424a29c566cb0e3c5bfae8cb832a583f8d8e660 GIT binary patch literal 3465 zcmb7G&2!sC6qn@B$X~M3ByO5EiCfy5P`hpTXiH$2HcknpZE#YC?hFXoyLMz`Nl0=h z@iph1ICbE}4Tisj8ID|Z<>WIrPP|=xL~)X7YK>NJ-~RS}?R#&%S}2IK(%;{`yv%X` zaIxP!(4WEUTu*Qu<}j~w10D%Hr3Ii9D9Pvq&?%H=bQ0(c%JLk^_NNXwBod*Y!zrA` z8JxvaSUgOjJn#xQhx52V=qvP#xQI(2Rl;R>BrN0UehFVV;BkRHG93Xsb0{(NES>{Y z<(%k?cpk8q-i+=gdK`T~n~XDzTELg_l|u68mtr&%KWv*HH6>09CBj@eto?=qy!kSqATn7y}f{e1TJ_!Aa1@NFh{nn)zyzkqXV94Rwu z5h$5aH-MUE)Cy2ye}?1_c*ulwe-`IRvOm}5iG=UqyT1qr2~+{ZMN)|nivgk>A?6uk zK0@3G5ORdL#1NMv#7cmejt~nBu|N?t63S(W%N4we--m3X=llWw5IBqYBYcm}!MieW z?;mCu_W}MG&a43bP5a!QfY%PQXbGe)lO?8i2|TXi)iv0?&DA~`(*mmTo`{Llu{Fyz zZJ1>S#BtOfp$j(Y>ZIdprUA2(vp;B?x`I_#ZL1C$&6v(WA*9i@O~WMyu3NV0nqJyx zqcoeYIt|bw&UMT|ow$xxht;~?8PG3mewcr3Tbr7XPb|c;0L}uX)&Wx_mj1 zUtJTWEn6FCuJ($w$d5zfxUwh;8m{n5{LLvjFD4CjKq>;86~(lr+UmfmBvE)sk4)c6OhT{XlK?ikJ%-R8mO{gXoL8`x7rp z8$pypU*&Z%-x?Z`5ppF6Nj+i(;^${iSphv&?lv#q7pEQ**Viu3guu`m7M1zwNjBU3 zu<@3s(hg3vmhxC+y^N)Het=Z*($2o&s(YU75L;7qZ3H1REt)qDD#UnJ+dFY)qd7kl zPPqNdgR>mXpRrok@EDSW8&AQo@h=SAC^dAux9-&>I|DOssyozmg{FX)(hN-YytFYK zw2AE{-F=IoY{#+`N_i<=Z4(`pcU4Ehq^k~fS9zuCL*f;VPxC<@ux)6HfIMG9sRJdT zYKCU?{I$I1C}a<+!hs;5Qba0F$FztoQUjA+$Sr2;XyGg`srh4pqJ#7uT{#Qtr}r2x zKyJKDhi_pBf?-QkM3yR~67331?K#RzcQvA8#}gwH9h5hqmf#3!a2&W7LpL2}H!6g_ zVYLko&;x)=Cv;Y^Rig*n(xySouH#9u^N0GfU9TA9K-=&p3Nh>}@q~bcg(PFud0MPs zx$dueCu(+d{bax>ezLa53ivU8O=EJrxpt`b$#WV;#v z1>&{up=7*cZD({X&^WoF9&b*y49ioNMs^t_Avu=uaGtNU4nd-3SVPyZh@3fe!-=2n zM}2Cve3s6rmDRE_g)CdCRwl@%$!%9*pm&wKYhtH%6_t9X+0%)C2epS?n-&eqK|P0e z8#@M+4STtr^Z`eAoSmW^Ntw9kyv(}a6TA#vQg9m;H=vN#k0jUWM)8P&N*lDQju>7V zla7fADl1#9&8M3?n_o9u&97cGw|7t}&f5C&B`PZ0+n+yaz6=5RXiisW;yuVw+WV}< zq1hJcX;8KHansPkV`30ng>v4aw{yqTpZfRv4()uIU}EQ}2c=L($h`_&`z9S$=z2D4 z>g8?!$d5ck(o=R8F-}?8Xgz`Qe7-~3We~?9yOTTgU1FD)1|J`Zq zngh~+yrHi`W7&Wo6MZ MJ29VJFM_Q90p0G@8~^|S literal 0 HcmV?d00001 diff --git a/osm_ee/__pycache__/frontend_server.cpython-36.pyc b/osm_ee/__pycache__/frontend_server.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d3622cb1d48088846f0a131b6602b57b6c374ace GIT binary patch literal 2882 zcmZ`*TaO#J6(;AV8Qm=JI_ve;P6lb3M8RHyBoFPPC>$rM6SUZ-yD01sK?Y-y(vEg6 zGD*3+>L?GDUxW5NPTu<;`qtl2pcv$>PyGvd>N%X%M%f?|NFE*@9`f8i&bysXbF267 z&ks6;{Fki#nn2%&roM%a6HZgY>X9;P<`%PHv{E~Bm_u>RPTkC7Ue;g@Gj~!y3s_)i zH*IDu*2>zfZRQ@#JFJs+S=Y=P>5Z(%dWNRy&B?}OlWjgE+~>h_!UGX3ZFY+{d5gDS zSmGtI#VPN+uz8o?cHN-hGxt|=M;KUT0$O=e=$XuiXg2;lXt$vK z3!2&nhm>?emgHl|?vKdAy7;C9mrNi8r8Tj?g6xOUfzgK1{fd0;VUC?^kn$!Cl)-ge zTiWj!9T&ZK&G?zMuouoFk~bZq{j;X}<}tX}=ypof?3SSSYX|kg9Rl4f?b6}im)4Tj zx1r?eClq2v$*0gB!9O2?uGU%e?^JG3vT!Mxe{`wS+-2>)zHXQ9lCExCpTL8f`@>Tn zfqtlM(D#M=nB*2z4W>ZzXufeg%fsm^?+?R-hjV{7%;QWPhV$lbIE`hTDWJP2P%)tt zYFgwAr! zaD4oS<9?@VOEG-5(jvPM#LDI3$!uI%39lTy8T0B}$s4fBnsSy$@lYp4UTvJ{V*0+i z$cGd@Ee1~iAx@BJu^*LPp#Ev7v-leY*KKg`<_koqi8JDUC# zig^Ngd6m;PNIKdrZBD<0QeWlPWtl^XHZFq#h9V|Z-S-ugI@)i7RQs_7r5-7D8l8y? zc@M;70A1ht-ZwHt?$5EqVqfz|@KER)3V#I)%7+e}(WX5*-}#aGSHk@kmOh3wimGN5 zWd)z5NVlWt=`2p`6}gFrp=%`8w!{$1SFyu$%q`_Fkox{ohQdh67Id#eQ@GW)d}q63 zc=N{F`{ti4!Qqg}&S?RN?@SA+`?l=k-nX!O3A!OP1FPtfHZ&8Xe*%Hpr#QqbX#|pWQ;m} z-7S5j{`LTn#Gl+KAvc!RD$eF?*aiE&k^n+9N<@Vkcl=3jl_%!qB!48w_-bPP`$x>H zpMZJii-UcL{XxPbsp5GE^d98FSmfc}({N9Rzzz3~!Z+Rs_eSAg7V}phiX1CUaFoTI z*#&SwAU2?Xh%!I%zRX+rBqJmgdH5YY?BA5=Q`UkvB^iED0xCR3PKd?)2b=Xr*Y0_kjIrbDr6Sxsxi|Ey!(Rn(qb5=QH($U-vMGM?|?dK zV}}VL@vW#_rDLgC>(4PfJ;St6g7<^9$RqYJe*~x&@kFx5u*fnvlC{?C#8-$HGi^q| zGv?KA=vposz;LoS$?t$(P#!a zBv@cPpksB$HW1%uIffP@FinLPm21Ma=H#n_ul!%vDDoSGZiO)6gSUMPun3#!+jehf MXA}7rc)n}>ADu$wDF6Tf literal 0 HcmV?d00001 diff --git a/osm_ee/base_ee.py b/osm_ee/base_ee.py new file mode 100644 index 0000000..6728c49 --- /dev/null +++ b/osm_ee/base_ee.py @@ -0,0 +1,105 @@ +## +# Copyright 2019 Telefonica Investigacion y Desarrollo, S.A.U. +# This file is part of OSM +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: nfvlabs@tid.es +## + +import asyncio +import logging +import yaml +import os + +from osm_ee.vnf.vnf_ee import VnfEE + + +class BaseEE: + + RETURN_STATUS_LIST = ["OK", "PROCESSING", "ERROR"] + CONFIG_FILE = "/app/storage/config.yaml" + SSH_KEY_FILE = "~/.ssh/id_rsa.pub" + HEALTH_CHECK_ACTION = "health-check" + + def __init__(self): + self.logger = logging.getLogger('osm_ee.base') + + # Check if configuration is stored and load it + if os.path.exists(self.CONFIG_FILE): + with open(self.CONFIG_FILE, 'r') as file: + self.config_params = yaml.load(file, Loader=yaml.FullLoader) + self.logger.debug("Load existing config from file: {}".format(self.config_params)) + else: + self.config_params = {} + + self.vnf_ee = VnfEE(self.config_params) + + async def get_ssh_key(self): + self.logger.debug("Obtain ssh key") + filename = os.path.expanduser(self.SSH_KEY_FILE) + with open(filename) as reader: + ssh_key = reader.read() + return ssh_key + + async def run_action(self, id, name, params): + self.logger.debug("Execute action id: {}, name: {}, params: {}".format(id, name, params)) + + try: + # Health-check + if name == self.HEALTH_CHECK_ACTION: + yield "OK", "Health-check ok" + else: + + # Obtain dynamically code to be executed + method = getattr(self.vnf_ee, name) + + # Convert params from yaml format + action_params = yaml.safe_load(params) + + if name == "config": + self.logger.debug("Store config info in file: {}".format(self.CONFIG_FILE)) + self.config_params.update(action_params) + with open(self.CONFIG_FILE, 'w') as file: + config = yaml.dump(self.config_params, file) + + async for return_status, detailed_message in method(id, action_params): + if return_status not in self.RETURN_STATUS_LIST: + yield "ERROR", "Invalid return status" + else: + yield return_status, str(detailed_message) + except AttributeError as e: + error_msg = "Action name: {} not implemented".format(name) + self.logger.error(error_msg) + yield "ERROR", error_msg + except Exception as e: + self.logger.error("Error executing action id, name: {},{}: {}".format(id, name, str(e)), exc_info=True) + yield "ERROR", str(e) + + +if __name__ == '__main__': + logging.basicConfig(level=logging.DEBUG) + + loop = asyncio.get_event_loop() + try: + ee = BaseEE() + id = "test1" + name = "touch2" + params = {"file_path": "/var/tmp/testfile1.txt"} + action = asyncio.ensure_future(ee.run_action(id, name, params)) + loop.run_until_complete(action) + finally: + loop.close() diff --git a/osm_ee/exceptions.py b/osm_ee/exceptions.py new file mode 100644 index 0000000..4829197 --- /dev/null +++ b/osm_ee/exceptions.py @@ -0,0 +1,27 @@ +## +# Copyright 2019 Telefonica Investigacion y Desarrollo, S.A.U. +# This file is part of OSM +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: nfvlabs@tid.es +## + +class ExecEnvException(Exception): + """Exception thrown by the EE if the actions can't be invoked or there is any generic error""" + +class VnfException(Exception): + """Exception thrown by the Vnf EE code in case of error""" \ No newline at end of file diff --git a/osm_ee/frontend.proto b/osm_ee/frontend.proto new file mode 100644 index 0000000..36d0158 --- /dev/null +++ b/osm_ee/frontend.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "com.etsi.osm.lcm.osm_ee"; +option java_outer_classname = "GrpcExecutor"; +option objc_class_prefix = "OEE"; + +package osm_ee; + +service FrontendExecutor { + + // Execute action leaving open a channel for notifications + rpc RunPrimitive (PrimitiveRequest) returns (stream PrimitiveReply) {} + + // Sends a greeting + rpc GetSshKey (SshKeyRequest) returns (SshKeyReply) {} +} + +// Request parameters +message PrimitiveRequest { + string id=1; + string name=2; + string params=3; +} + +message PrimitiveReply { + string status=1; + string detailed_message=2; +} + +// The request message containing the user's name. +message SshKeyRequest { + // empty +} + +// The response message containing the greetings +message SshKeyReply { + string message = 1; +} diff --git a/osm_ee/frontend_client.py b/osm_ee/frontend_client.py new file mode 100644 index 0000000..0c34580 --- /dev/null +++ b/osm_ee/frontend_client.py @@ -0,0 +1,85 @@ +## +# Copyright 2019 Telefonica Investigacion y Desarrollo, S.A.U. +# This file is part of OSM +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: nfvlabs@tid.es +## + +import sys +import yaml +import asyncio +import uuid +import traceback +import os +import socket + +from grpclib.client import Channel + +from osm_ee.frontend_pb2 import PrimitiveRequest, PrimitiveReply +from osm_ee.frontend_pb2 import SshKeyRequest, SshKeyReply +from osm_ee.frontend_grpc import FrontendExecutorStub + + +async def frontend_client(host_name, port, primitive_name, params): + + ip_addr = socket.gethostbyname(host_name) + channel = Channel(ip_addr, port) + try: + stub = FrontendExecutorStub(channel) + + if (primitive_name == "get_ssh_key"): + print("Get ssh key") + reply: SshKeyReply = await stub.GetSshKey(SshKeyRequest()) + print(reply.message) + else: + async with stub.RunPrimitive.open() as stream: + primitive_id = str(uuid.uuid1()) + print("Execute primitive {}, params: {}".format(primitive_name, params)) + await stream.send_message( + PrimitiveRequest(id=primitive_id, name=primitive_name, params=yaml.dump(params)), end=True) + async for reply in stream: + print(reply) + #replies = [reply async for reply in stream] + #print(replies) + except Exception as e: + print("Error executing primitive {}: {}".format(primitive_name, str(e))) + #print(traceback.format_exc()) + finally: + channel.close() + + +if __name__ == '__main__': + + args = sys.argv[1:] + if (len(args) < 1): + print("Usage: host port primitive_name params") + else: + host_name = args[0] + port = args[1] + primitive_name = args[2] + arg_params = args[3] if len(args) >= 4 else "" + print(primitive_name) + print(arg_params) + params = yaml.safe_load(arg_params) + + loop = asyncio.get_event_loop() + try: + task = asyncio.ensure_future(frontend_client(host_name, port, primitive_name, params)) + loop.run_until_complete(task) + finally: + loop.close() diff --git a/osm_ee/frontend_grpc.py b/osm_ee/frontend_grpc.py new file mode 100644 index 0000000..b2b95d3 --- /dev/null +++ b/osm_ee/frontend_grpc.py @@ -0,0 +1,56 @@ +# Generated by the Protocol Buffers compiler. DO NOT EDIT! +# source: osm_ee/frontend.proto +# plugin: grpclib.plugin.main +import abc +import typing + +import grpclib.const +import grpclib.client +if typing.TYPE_CHECKING: + import grpclib.server + +import osm_ee.frontend_pb2 + + +class FrontendExecutorBase(abc.ABC): + + @abc.abstractmethod + async def RunPrimitive(self, stream: 'grpclib.server.Stream[osm_ee.frontend_pb2.PrimitiveRequest, osm_ee.frontend_pb2.PrimitiveReply]') -> None: + pass + + @abc.abstractmethod + async def GetSshKey(self, stream: 'grpclib.server.Stream[osm_ee.frontend_pb2.SshKeyRequest, osm_ee.frontend_pb2.SshKeyReply]') -> None: + pass + + def __mapping__(self) -> typing.Dict[str, grpclib.const.Handler]: + return { + '/osm_ee.FrontendExecutor/RunPrimitive': grpclib.const.Handler( + self.RunPrimitive, + grpclib.const.Cardinality.UNARY_STREAM, + osm_ee.frontend_pb2.PrimitiveRequest, + osm_ee.frontend_pb2.PrimitiveReply, + ), + '/osm_ee.FrontendExecutor/GetSshKey': grpclib.const.Handler( + self.GetSshKey, + grpclib.const.Cardinality.UNARY_UNARY, + osm_ee.frontend_pb2.SshKeyRequest, + osm_ee.frontend_pb2.SshKeyReply, + ), + } + + +class FrontendExecutorStub: + + def __init__(self, channel: grpclib.client.Channel) -> None: + self.RunPrimitive = grpclib.client.UnaryStreamMethod( + channel, + '/osm_ee.FrontendExecutor/RunPrimitive', + osm_ee.frontend_pb2.PrimitiveRequest, + osm_ee.frontend_pb2.PrimitiveReply, + ) + self.GetSshKey = grpclib.client.UnaryUnaryMethod( + channel, + '/osm_ee.FrontendExecutor/GetSshKey', + osm_ee.frontend_pb2.SshKeyRequest, + osm_ee.frontend_pb2.SshKeyReply, + ) diff --git a/osm_ee/frontend_pb2.py b/osm_ee/frontend_pb2.py new file mode 100644 index 0000000..8cdc485 --- /dev/null +++ b/osm_ee/frontend_pb2.py @@ -0,0 +1,233 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: osm_ee/frontend.proto + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='osm_ee/frontend.proto', + package='osm_ee', + syntax='proto3', + serialized_options=b'\n\027com.etsi.osm.lcm.osm_eeB\014GrpcExecutorP\001\242\002\003OEE', + serialized_pb=b'\n\x15osm_ee/frontend.proto\x12\x06osm_ee\"<\n\x10PrimitiveRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06params\x18\x03 \x01(\t\":\n\x0ePrimitiveReply\x12\x0e\n\x06status\x18\x01 \x01(\t\x12\x18\n\x10\x64\x65tailed_message\x18\x02 \x01(\t\"\x0f\n\rSshKeyRequest\"\x1e\n\x0bSshKeyReply\x12\x0f\n\x07message\x18\x01 \x01(\t2\x93\x01\n\x10\x46rontendExecutor\x12\x44\n\x0cRunPrimitive\x12\x18.osm_ee.PrimitiveRequest\x1a\x16.osm_ee.PrimitiveReply\"\x00\x30\x01\x12\x39\n\tGetSshKey\x12\x15.osm_ee.SshKeyRequest\x1a\x13.osm_ee.SshKeyReply\"\x00\x42/\n\x17\x63om.etsi.osm.lcm.osm_eeB\x0cGrpcExecutorP\x01\xa2\x02\x03OEEb\x06proto3' +) + + + + +_PRIMITIVEREQUEST = _descriptor.Descriptor( + name='PrimitiveRequest', + full_name='osm_ee.PrimitiveRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='osm_ee.PrimitiveRequest.id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='name', full_name='osm_ee.PrimitiveRequest.name', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='params', full_name='osm_ee.PrimitiveRequest.params', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=33, + serialized_end=93, +) + + +_PRIMITIVEREPLY = _descriptor.Descriptor( + name='PrimitiveReply', + full_name='osm_ee.PrimitiveReply', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='status', full_name='osm_ee.PrimitiveReply.status', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='detailed_message', full_name='osm_ee.PrimitiveReply.detailed_message', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=95, + serialized_end=153, +) + + +_SSHKEYREQUEST = _descriptor.Descriptor( + name='SshKeyRequest', + full_name='osm_ee.SshKeyRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=155, + serialized_end=170, +) + + +_SSHKEYREPLY = _descriptor.Descriptor( + name='SshKeyReply', + full_name='osm_ee.SshKeyReply', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='osm_ee.SshKeyReply.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=172, + serialized_end=202, +) + +DESCRIPTOR.message_types_by_name['PrimitiveRequest'] = _PRIMITIVEREQUEST +DESCRIPTOR.message_types_by_name['PrimitiveReply'] = _PRIMITIVEREPLY +DESCRIPTOR.message_types_by_name['SshKeyRequest'] = _SSHKEYREQUEST +DESCRIPTOR.message_types_by_name['SshKeyReply'] = _SSHKEYREPLY +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +PrimitiveRequest = _reflection.GeneratedProtocolMessageType('PrimitiveRequest', (_message.Message,), { + 'DESCRIPTOR' : _PRIMITIVEREQUEST, + '__module__' : 'osm_ee.frontend_pb2' + # @@protoc_insertion_point(class_scope:osm_ee.PrimitiveRequest) + }) +_sym_db.RegisterMessage(PrimitiveRequest) + +PrimitiveReply = _reflection.GeneratedProtocolMessageType('PrimitiveReply', (_message.Message,), { + 'DESCRIPTOR' : _PRIMITIVEREPLY, + '__module__' : 'osm_ee.frontend_pb2' + # @@protoc_insertion_point(class_scope:osm_ee.PrimitiveReply) + }) +_sym_db.RegisterMessage(PrimitiveReply) + +SshKeyRequest = _reflection.GeneratedProtocolMessageType('SshKeyRequest', (_message.Message,), { + 'DESCRIPTOR' : _SSHKEYREQUEST, + '__module__' : 'osm_ee.frontend_pb2' + # @@protoc_insertion_point(class_scope:osm_ee.SshKeyRequest) + }) +_sym_db.RegisterMessage(SshKeyRequest) + +SshKeyReply = _reflection.GeneratedProtocolMessageType('SshKeyReply', (_message.Message,), { + 'DESCRIPTOR' : _SSHKEYREPLY, + '__module__' : 'osm_ee.frontend_pb2' + # @@protoc_insertion_point(class_scope:osm_ee.SshKeyReply) + }) +_sym_db.RegisterMessage(SshKeyReply) + + +DESCRIPTOR._options = None + +_FRONTENDEXECUTOR = _descriptor.ServiceDescriptor( + name='FrontendExecutor', + full_name='osm_ee.FrontendExecutor', + file=DESCRIPTOR, + index=0, + serialized_options=None, + serialized_start=205, + serialized_end=352, + methods=[ + _descriptor.MethodDescriptor( + name='RunPrimitive', + full_name='osm_ee.FrontendExecutor.RunPrimitive', + index=0, + containing_service=None, + input_type=_PRIMITIVEREQUEST, + output_type=_PRIMITIVEREPLY, + serialized_options=None, + ), + _descriptor.MethodDescriptor( + name='GetSshKey', + full_name='osm_ee.FrontendExecutor.GetSshKey', + index=1, + containing_service=None, + input_type=_SSHKEYREQUEST, + output_type=_SSHKEYREPLY, + serialized_options=None, + ), +]) +_sym_db.RegisterServiceDescriptor(_FRONTENDEXECUTOR) + +DESCRIPTOR.services_by_name['FrontendExecutor'] = _FRONTENDEXECUTOR + +# @@protoc_insertion_point(module_scope) diff --git a/osm_ee/frontend_server.py b/osm_ee/frontend_server.py new file mode 100644 index 0000000..079503d --- /dev/null +++ b/osm_ee/frontend_server.py @@ -0,0 +1,89 @@ +## +# Copyright 2019 Telefonica Investigacion y Desarrollo, S.A.U. +# This file is part of OSM +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: nfvlabs@tid.es +## + +import asyncio +import logging +import os + +from grpclib.utils import graceful_exit +from grpclib.server import Server, Stream + +from osm_ee.frontend_grpc import FrontendExecutorBase +from osm_ee.frontend_pb2 import PrimitiveRequest, PrimitiveReply +from osm_ee.frontend_pb2 import SshKeyRequest, SshKeyReply + +from osm_ee.base_ee import BaseEE +import osm_ee.util.util_ee as util_ee + + +class FrontendExecutor(FrontendExecutorBase): + + def __init__(self): + self.logger = logging.getLogger('osm_ee.frontend_server') + self.base_ee = BaseEE() + + async def RunPrimitive(self, stream: Stream[PrimitiveRequest, PrimitiveReply]) -> None: + request = await stream.recv_message() + try: + self.logger.debug(f'Run primitive: id {request.id}, name: {request.name}, params: {request.params}') + async for status, detailed_message in self.base_ee.run_action(request.id, request.name, request.params): + self.logger.debug(f'Send response {status}, {detailed_message}') + await stream.send_message( + PrimitiveReply(status=status, detailed_message=detailed_message)) + except Exception as e: + self.logger.debug(f'Error executing primitive: id {request.id}, name: {request.name}, error_msg: {str(e)}') + await stream.send_message( + PrimitiveReply(status="ERROR", detailed_message=str(e))) + + async def GetSshKey(self, stream: Stream[SshKeyRequest, SshKeyReply]) -> None: + request = await stream.recv_message() + assert request is not None + message = await self.base_ee.get_ssh_key() + await stream.send_message(SshKeyReply(message=message)) + + +async def main(*, host: str = '0.0.0.0', port: int = 50051) -> None: + logging.basicConfig() + logger = logging.getLogger('osm_ee') + logger.setLevel(logging.DEBUG) + + # Generate ssh key + file_dir = os.path.expanduser("~/.ssh/id_rsa") + command = "ssh-keygen -q -t rsa -N '' -f {}".format(file_dir) + return_code, stdout, stderr = await util_ee.local_async_exec(command) + logger.debug("Generated ssh_key, return_code: {}".format(return_code)) + + # Start server + server = Server([FrontendExecutor()]) + with graceful_exit([server]): + await server.start(host, port) + logging.getLogger('osm_ee.frontend_server').debug(f'Serving on {host}:{port}') + await server.wait_closed() + + +if __name__ == '__main__': + loop = asyncio.get_event_loop() + try: + main_task = asyncio.ensure_future(main()) + loop.run_until_complete(main_task) + finally: + loop.close() diff --git a/osm_ee/scripts/ee_start.sh b/osm_ee/scripts/ee_start.sh new file mode 100755 index 0000000..0364dc4 --- /dev/null +++ b/osm_ee/scripts/ee_start.sh @@ -0,0 +1,30 @@ +#!/bin/bash +## +# Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U. +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +## + +# This script is intended for launching RO from a docker container. +# It waits for mysql server ready, normally running on a separate container, ... +# then it checks if database is present and creates it if needed. +# Finally it launches RO server. + +EE_PATH=/app/EE + +# Install vnf vendor additional required libraries +echo "Install additional libraries" +bash ${EE_PATH}/osm_ee/vnf/install.sh + +# Start frontend +echo "Starting frontend server" +python3 -m osm_ee.frontend_server diff --git a/osm_ee/util/__init__.py b/osm_ee/util/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/osm_ee/util/__pycache__/__init__.cpython-36.pyc b/osm_ee/util/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..138334b80a9424ece48476ad22c8761dc661684c GIT binary patch literal 133 zcmXr!<>e9+xEjX*1dl-k3@`#24nSPY0whuxf*CX!{Z=v*frJsnFC+bo{M=Oi{Nh{? zj!(`{N!8CwPfgW#bp;CmS*0bJIr{POnR%Hd@$q^EmA5!-a`RJ4b5iXQlDoJxKu%kj{DPBaqsj|eCokZGAS97P_Y;BZv zz1f3q`iX1AimnNNVgo;kzK_BGp3cry2{XK8Cq8smEdgdHC*FaUEA7?o^&eks?C6Ga zayK;0R=bph#dJX9U=$qDk=ucOfZoZ_Mvl{}TIwER8`kFqtUK!akF0xXNR_+7df;OF zOEB;JKy>UdtBtl?t}@HU_h;!Q+6IN*ZpF0Q9R9A=x$?9{dyk`#Bx7KHKa z$>W{{e}})pORk>$3!Z#QtFD3fl9%u0%X=>`4|jLdz2WyaX^hYhbZLaJehQ+U;)vq{ zO}iOSG1#OaWiSme5-1OOu*K6zP!WUBMZm)g!Xr*UhSP-OV>F6?0t-4AVH@dnu`-*1 z)a6Ww`?XmWBVyxBmgT(SmMURtRb|-u!$?3PkZ&OR3n+scw8bqpI42zEfwQ(4BNOIP zgF(|g?ldPC;(vUpaqRx6v+Mo?#XQz!kPY66w$HSwRHi7!k1bMneE%i7B zoOXB5uD9gA+veG`ea$HSJjfu^?8-8 zbYr|wE zm|QS(DoRhkxzz{reURnEtvO?p_Hb#0urNskQ&KYx0l z2)vG^g18y{!}x literal 0 HcmV?d00001 diff --git a/osm_ee/util/util_ansible.py b/osm_ee/util/util_ansible.py new file mode 100644 index 0000000..8f27875 --- /dev/null +++ b/osm_ee/util/util_ansible.py @@ -0,0 +1,46 @@ +## +# Copyright 2019 Telefonica Investigacion y Desarrollo, S.A.U. +# This file is part of OSM +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: nfvlabs@tid.es +## + +import logging +import json +from shlex import quote + +import osm_ee.util.util_ee as util_ee + +logger = logging.getLogger("osm_ee.util_ansible") + + +async def execute_playbook(playbook_name: str, inventory: str, extra_vars: dict, + ) -> (int, str): + + command = 'ansible-playbook --inventory={} --extra-vars {} {}'.format(quote(inventory), + quote(json.dumps(extra_vars)), + quote(playbook_name)) + + logger.debug("Command to be executed: {}".format(command)) + + return_code, stdout, stderr = await util_ee.local_async_exec(command) + logger.debug("Return code: {}".format(return_code)) + logger.debug("stdout: {}".format(stdout)) + logger.debug("stderr: {}".format(stderr)) + + return return_code, stdout, stderr diff --git a/osm_ee/util/util_ee.py b/osm_ee/util/util_ee.py new file mode 100644 index 0000000..1d0a232 --- /dev/null +++ b/osm_ee/util/util_ee.py @@ -0,0 +1,60 @@ +## +# Copyright 2019 Telefonica Investigacion y Desarrollo, S.A.U. +# This file is part of OSM +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: nfvlabs@tid.es +## + +import logging +import asyncio +from shlex import split + +logger = logging.getLogger("osm_ee.util") + + +async def local_async_exec(command: str + ) -> (int, str, str): + """ + Executed a local command using asyncio. + TODO - do not know yet if return error code, and stdout and strerr or just one of them + """ + scommand = split(command) + + logger.debug("Execute local command: {}".format(command)) + process = await asyncio.create_subprocess_exec( + *scommand, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE + ) + + # wait for command terminate + stdout, stderr = await process.communicate() + + return_code = process.returncode + logger.debug("Return code: {}".format(return_code)) + + output = "" + if stdout: + output = stdout.decode() + logger.debug("Output: {}".format(output)) + + if stderr: + out_err = stderr.decode() + logger.debug("Stderr: {}".format(out_err)) + + return return_code, stdout, stderr diff --git a/osm_ee/vnf/__init__.py b/osm_ee/vnf/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/osm_ee/vnf/__pycache__/__init__.cpython-36.pyc b/osm_ee/vnf/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..70afb9ec13739c41c20094e37b47a1bb98305d86 GIT binary patch literal 132 zcmXr!<>e9+xEjX*1dl-k3@`#24nSPY0whuxf*CX!{Z=v*frJsnFGKx|{M=Oi{Nh{? zj!(`{N!8CwPfgW#bp;CmS!H=?`tk9Zd6^~g@p=W7w>WHa^HWN5Qtd!S6$3E?06Cl; A=>Px# literal 0 HcmV?d00001 diff --git a/osm_ee/vnf/__pycache__/vnf_ee.cpython-36.pyc b/osm_ee/vnf/__pycache__/vnf_ee.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..27ab0d3ebf7c7685100d5da22fbab4ce8ea2ad9b GIT binary patch literal 3381 zcmZu!OK%*<5$>MX&dffzq7}*{oMbIHP&SdcNE{%5BLuc-#xiV^3T0UGz{y~=-CWK- zW>!7DHo2blAryQ|VB}~cKOjFSmp=HCAb|dYPO0jiSyEJ%=vPg5RdscJRmC^k?QpC6 zuRrrmLjFxI{cM=O4Xt<=Iz||slE{oSqIzvb7L3-^o;i_2%{O=KjT=$peZp+!JSEII zw<4d>2c+*l13u)SPgU#F?0Ell$mcT6vmsLJ-&*E-K;Z=CfD9Vh%wqOa5;@FaE{rbo zSOZ3n`7D63!9v!A(dPkcvG!APPNR@@Kwhrv#rDZtoo|d;6z+xRAV;4DtPX=88RY#kYE2t(L8# zIJt9@7cxs`Tv>-7s&G%+VIer{TcQP8h&FV6Pk1mWm+{Aok@AjnF-xR2kMb6CmPoF) z;^7G&PGZ5IEK)dM+tLv}9<@@YJR@6eT-l=yY`PHldPdbg%nKwCx@onjM>}+>U2=cd zY*^b46}<*c+wPRUXgg_Z`)R9vOV7GsFR&rn4{au0oNp89om=8ux!zsnY$eUJRc8W5sW)5oY>;OWiZ}Yg&9Dp;un@4YuzBF zGqJy=B4q6{Jhspmp8Sn4FRdD0bZZ+VTC&zqL>PJwwQ5&__M_#i<g#C?nvCR$a!>{3rWxa> z%Iws!160#SRi3e5w86Mc;54h1q5LY!UHwGA0-41wbcDWYIkaQHu}S*!_o_e-w? zE;V+tKLG0dNhp2*%mr)AQPu*?1qSgNb4?lIsy2rGfIUQ)Am}Id7HebGBu)uZtK`>NIdbM0c zM8A0j3K|3^rL^yV^v-AR9v*%e-+$+md#bgN=`^mGL|w!8;%)--tGI>T&!OvwFL`vD zeZey*D9$3kRzWodmkW{UJg$+FFQj+_&f@~%BhV?Y`s{^0s=DL>Y%1{9n4>J(0T+d4 zZPFbJ+!kCHTy@L1>e`gm(Y4oN=EwA^y>CKWt z`rcVV_$bMwAv_87^_ZGq@)!EV!-Q&z&7F@^bJ4oEF_6=~ZV42jBYxl3VOCrRLe#1E znqujy`j{5b9}4sif-#UTU#rT;|66Pw^qW|ABCO+Bg>gK~*#g2qtXgsWWRXnG7x8Og zCz{y(2)hAxzr_v>rdkMqbU5SkBxeSeSOH(v4z2Y%v;wo4Z#kCl_`ZMBzwQSDzx4z0 zI~W97RQwdW=vq~e^ZI{^Lfa*JwW1@=cQ1ooIk*yUA_ru7Nd>Kut`_~f=9a&|0XuZP N=!2nryJfZP{{fIAT)6-M literal 0 HcmV?d00001 diff --git a/osm_ee/vnf/install.sh b/osm_ee/vnf/install.sh new file mode 100644 index 0000000..e0e56ff --- /dev/null +++ b/osm_ee/vnf/install.sh @@ -0,0 +1,22 @@ +#!/bin/bash +## +# Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U. +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +## + +# This script is intended for launching RO from a docker container. +# It waits for mysql server ready, normally running on a separate container, ... +# then it checks if database is present and creates it if needed. +# Finally it launches RO server. + +echo "Sample install.sh " \ No newline at end of file diff --git a/osm_ee/vnf/vnf_ee.py b/osm_ee/vnf/vnf_ee.py new file mode 100644 index 0000000..10c2e33 --- /dev/null +++ b/osm_ee/vnf/vnf_ee.py @@ -0,0 +1,54 @@ +## +# Copyright 2019 Telefonica Investigacion y Desarrollo, S.A.U. +# This file is part of OSM +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: nfvlabs@tid.es +## + +import asyncio +import logging + +from osm_ee.exceptions import VnfException + + +class VnfEE: + + def __init__(self, config_params): + self.logger = logging.getLogger('osm_ee.vnf') + self.config_params = config_params + + async def config(self, id, params): + self.logger.debug("Execute action config params: {}".format(params)) + # Config action is special, params are merged with previous config calls + self.config_params.update(params) + yield "OK", "Configured" + + async def sleep(self, id, params): + self.logger.debug("Execute action sleep, params: {}".format(params)) + + for i in range(3): + await asyncio.sleep(5) + self.logger.debug("Temporal result return, params: {}".format(params)) + yield "PROCESSING", f"Processing {i} action id {id}" + yield "OK", f"Processed action id {id}" + + @staticmethod + def _check_required_params(params, required_params): + for required_param in required_params: + if required_param not in params: + raise VnfException("Missing required param: {}".format(required_param)) diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..ab68a84 --- /dev/null +++ b/setup.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# Copyright 2018 Telefonica S.A. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from setuptools import setup + +_name = "osm_ee" + +_description = 'OSM Resource Orchestrator' +_author = 'ETSI OSM' +_author_email = 'illoret@indra.es' +_maintainer = 'alfonso.tiernosepulveda' +_maintainer_email = 'alfonso.tiernosepulveda@telefonica.com' +_license = 'Apache 2.0' +_url = 'TOBEDEFINED' +_requirements = [ + # Libraries needed by the code defined by osm + "PyYAML", + "grpcio-tools", + "grpclib", + "protobuf", + + # Libraries defined by the vnf code, they should be in an external file + #"asyncssh", +] + +setup( + name=_name, + #version_command=('0.1'), # TODO - replace for a git command + version='1.0', + description=_description, + long_description=open('README.rst').read(), + author=_author, + author_email=_author_email, + maintainer=_maintainer, + maintainer_email=_maintainer_email, + url=_url, + license=_license, + packages=[_name], + package_dir={_name: _name}, + + install_requires=_requirements, + include_package_data=True, + setup_requires=['setuptools-version-command'], +) \ No newline at end of file -- GitLab