Added Dockerfile-based entry points to REST API.
[osm/vim-emu.git] / src / emuvim / api / rest / compute.py
index 8d46aa2..78d96da 100755 (executable)
@@ -14,7 +14,7 @@ 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.
 
 See the License for the specific language governing permissions and
 limitations under the License.
 
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
+Neither the name of the SONATA-NFV, Paderborn University
 nor the names of its contributors may be used to endorse or promote
 products derived from this software without specific prior written
 permission.
 nor the names of its contributors may be used to endorse or promote
 products derived from this software without specific prior written
 permission.
@@ -29,12 +29,14 @@ import logging
 from flask_restful import Resource
 from flask import request
 import json
 from flask_restful import Resource
 from flask import request
 import json
+import threading
 from copy import deepcopy
 
 from copy import deepcopy
 
-logging.basicConfig(level=logging.INFO)
+logging.basicConfig()
 
 CORS_HEADER = {'Access-Control-Allow-Origin': '*'}
 
 
 CORS_HEADER = {'Access-Control-Allow-Origin': '*'}
 
+# the dcs dict is set in the rest_api_endpoint.py upon datacenter init
 dcs = {}
 
 
 dcs = {}
 
 
@@ -49,6 +51,7 @@ class Compute(Resource):
     example networks list({"id":"input","ip": "10.0.0.254/8"}, {"id":"output","ip": "11.0.0.254/24"})
     :return: docker inspect dict of deployed docker
     """
     example networks list({"id":"input","ip": "10.0.0.254/8"}, {"id":"output","ip": "11.0.0.254/24"})
     :return: docker inspect dict of deployed docker
     """
+
     global dcs
 
     def put(self, dc_label, compute_name, resource=None, value=None):
     global dcs
 
     def put(self, dc_label, compute_name, resource=None, value=None):
@@ -67,9 +70,30 @@ class Compute(Resource):
         command = data.get("docker_command")
 
         try:
         command = data.get("docker_command")
 
         try:
-            logging.debug("API CALL: compute start")
+            if compute_name is None or compute_name == "None":
+                logging.error("No compute name defined in request.")
+                return "No compute name defined in request.", 500, CORS_HEADER
+            if dc_label is None or dcs.get(dc_label) is None:
+                logging.error("No datacenter defined in request.")
+                return "No datacenter defined in request.", 500, CORS_HEADER
             c = dcs.get(dc_label).startCompute(
                 compute_name, image=image, command=command, network=nw_list)
             c = dcs.get(dc_label).startCompute(
                 compute_name, image=image, command=command, network=nw_list)
+            # (if available) trigger emu. entry point given in Dockerfile
+            try:
+                config = c.dcinfo.get("Config", dict())
+                env = config.get("Env", list())
+                for env_var in env:
+                    var, cmd = map(str.strip, map(str, env_var.split('=', 1)))
+                    logging.debug("%r = %r" % (var , cmd))
+                    if var=="SON_EMU_CMD" or var=="VIM_EMU_CMD":
+                        logging.info("Executing entry point script in %r: %r" % (c.name, cmd))
+                        # execute command in new thread to ensure that API is not blocked by VNF
+                        t = threading.Thread(target=c.cmdPrint, args=(cmd,))
+                        t.daemon = True
+                        t.start()
+            except Exception as ex:
+                logging.warning("Couldn't run Docker entry point VIM_EMU_CMD")
+                logging.exception("Exception:")
             # return docker inspect dict
             return c.getStatus(), 200, CORS_HEADER
         except Exception as ex:
             # return docker inspect dict
             return c.getStatus(), 200, CORS_HEADER
         except Exception as ex:
@@ -123,13 +147,21 @@ class ComputeList(Resource):
             if dc_label is None or dc_label == 'None':
                 # return list with all compute nodes in all DCs
                 all_containers = []
             if dc_label is None or dc_label == 'None':
                 # return list with all compute nodes in all DCs
                 all_containers = []
+                all_extSAPs = []
                 for dc in dcs.itervalues():
                     all_containers += dc.listCompute()
                 for dc in dcs.itervalues():
                     all_containers += dc.listCompute()
-                return [(c.name, c.getStatus()) for c in all_containers], 200, CORS_HEADER
+                    all_extSAPs += dc.listExtSAPs()
+
+                extSAP_list = [(sap.name, sap.getStatus()) for sap in all_extSAPs]
+                container_list = [(c.name, c.getStatus()) for c in all_containers]
+                total_list = container_list + extSAP_list
+                return total_list, 200, CORS_HEADER
             else:
                 # return list of compute nodes for specified DC
             else:
                 # return list of compute nodes for specified DC
-                return [(c.name, c.getStatus())
-                        for c in dcs.get(dc_label).listCompute()], 200, CORS_HEADER
+                container_list = [(c.name, c.getStatus()) for c in dcs.get(dc_label).listCompute()]
+                extSAP_list = [(sap.name, sap.getStatus()) for sap in dcs.get(dc_label).listExtSAPs()]
+                total_list = container_list + extSAP_list
+                return total_list, 200, CORS_HEADER
         except Exception as ex:
             logging.exception("API error.")
             return ex.message, 500, CORS_HEADER
         except Exception as ex:
             logging.exception("API error.")
             return ex.message, 500, CORS_HEADER