[DCAE] Remove OTI component
[dcaegen2/platform.git] / oti / event-handler / otihandler / web_server.py
diff --git a/oti/event-handler/otihandler/web_server.py b/oti/event-handler/otihandler/web_server.py
deleted file mode 100644 (file)
index 45c407f..0000000
+++ /dev/null
@@ -1,605 +0,0 @@
-# ================================================================================
-# Copyright (c) 2019-2020 AT&T Intellectual Property. 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.
-# ============LICENSE_END=========================================================
-
-"""web-service for oti_handler"""
-
-import json
-import logging
-import os
-import time
-from datetime import datetime
-
-import cherrypy
-
-from otihandler.cbs_rest import CBSRest
-from otihandler.config import Config
-from otihandler.dti_processor import DTIProcessor
-from otihandler.onap.audit import Audit
-
-
-class DTIWeb(object):
-    """run REST API of OTI Handler"""
-
-    logger = logging.getLogger("oti_handler.web_server")
-    HOST_INADDR_ANY = ".".join("0"*4)
-
-    @staticmethod
-    def run_forever(audit):
-        """run the web-server of OTI Handler forever"""
-
-        cherrypy.config.update({"server.socket_host": DTIWeb.HOST_INADDR_ANY,
-                                "server.socket_port": Config.wservice_port})
-
-        protocol = "http"
-        tls_info = ""
-        if Config.tls_server_cert_file and Config.tls_private_key_file:
-            tm_cert = os.path.getmtime(Config.tls_server_cert_file)
-            tm_key  = os.path.getmtime(Config.tls_private_key_file)
-            #cherrypy.server.ssl_module = 'builtin'
-            cherrypy.server.ssl_module = 'pyOpenSSL'
-            cherrypy.server.ssl_certificate = Config.tls_server_cert_file
-            cherrypy.server.ssl_private_key = Config.tls_private_key_file
-            if Config.tls_server_ca_chain_file:
-                cherrypy.server.ssl_certificate_chain = Config.tls_server_ca_chain_file
-            protocol = "https"
-            tls_info = "cert: {} {} {}".format(Config.tls_server_cert_file,
-                                               Config.tls_private_key_file,
-                                               Config.tls_server_ca_chain_file)
-
-        cherrypy.tree.mount(_DTIWeb(), '/')
-
-        DTIWeb.logger.info(
-            "%s with config: %s", audit.info("running oti_handler as {}://{}:{} {}".format(
-                protocol, cherrypy.server.socket_host, cherrypy.server.socket_port, tls_info)),
-            json.dumps(cherrypy.config))
-        cherrypy.engine.start()
-
-        # If HTTPS server certificate changes, exit to let kubernetes restart us
-        if Config.tls_server_cert_file and Config.tls_private_key_file:
-            while True:
-                time.sleep(600)
-                c_tm_cert = os.path.getmtime(Config.tls_server_cert_file)
-                c_tm_key  = os.path.getmtime(Config.tls_private_key_file)
-                if c_tm_cert > tm_cert or c_tm_key > tm_key:
-                    DTIWeb.logger.info("cert or key file updated")
-                    cherrypy.engine.stop()
-                    cherrypy.engine.exit()
-                    break
-
-
-class _DTIWeb(object):
-    """REST API of DTI Handler"""
-
-    VALID_EVENT_TYPES = ['deploy', 'undeploy', 'add', 'delete', 'update', 'notify']
-
-    @staticmethod
-    def _get_request_info(request):
-        """Returns info about the http request."""
-
-        return "{} {}{}".format(request.method, request.script_name, request.path_info)
-
-
-    #----- Common endpoint methods
-
-    @cherrypy.expose
-    @cherrypy.tools.json_out()
-    def healthcheck(self):
-        """Returns healthcheck results."""
-
-        req_info = _DTIWeb._get_request_info(cherrypy.request)
-        audit = Audit(req_message=req_info, headers=cherrypy.request.headers)
-
-        DTIWeb.logger.info("%s", req_info)
-
-        result = Audit.health()
-
-        DTIWeb.logger.info("healthcheck %s: result=%s", req_info, json.dumps(result))
-
-        audit.audit_done(result=json.dumps(result))
-        return result
-
-    @cherrypy.expose
-    def shutdown(self):
-        """Shutdown the web server."""
-
-        req_info = _DTIWeb._get_request_info(cherrypy.request)
-        audit = Audit(req_message=req_info, headers=cherrypy.request.headers)
-
-        DTIWeb.logger.info("%s: --- stopping REST API of DTI Handler ---", req_info)
-
-        cherrypy.engine.exit()
-
-        health = json.dumps(Audit.health())
-        audit.info("oti_handler health: {}".format(health))
-        DTIWeb.logger.info("oti_handler health: %s", health)
-        DTIWeb.logger.info("%s: --------- the end -----------", req_info)
-        result = str(datetime.now())
-        audit.info_requested(result)
-        return "goodbye! shutdown requested {}".format(result)
-
-    # ----- DTI Handler mock endpoint methods
-    @cherrypy.expose
-    @cherrypy.tools.json_out()
-    @cherrypy.tools.json_in()
-    def mockevents(self):
-
-        result = {"KubeNamespace":"com-my-dcae-test", "KubePod":"pod-0", "KubeServiceName":"pod-0.service.local", "KubeServicePort":"8880", "KubeClusterFqdn":"fqdn-1"}
-
-        return result
-
-    #----- DTI Handler endpoint methods
-
-    @cherrypy.expose
-    @cherrypy.tools.json_out()
-    @cherrypy.tools.json_in()
-    def events(self, notify="y"):
-        """
-        Run dti reconfig script in service component instances configured to accept the DTI Event.
-
-        POST /events < <dcae_event>
-
-        POST /events?ndtify="n" < <dcae_event>
-
-        where <dcae_event> is the entire DTI Event passed as a JSON object and contains at least these top-level keys:
-            dcae_service_action : string
-                required, 'deploy' or 'undeploy'
-            dcae_target_name : string
-                required, VNF Instance ID
-            dcae_target_type : string
-                required, VNF Type of the VNF Instance
-            dcae_service_location : string
-                optional, CLLI location.  Not provided or '' infers all locations.
-
-        Parameters
-        ----------
-        notify : string
-            optional, default "y", any of these will not notify components: [ "f", "false", "False", "FALSE", "n", "no" ]
-            When "n" will **not** notify components of this DTI Event update to Consul.
-
-        Returns
-        -------
-        dict
-            JSON object containing success or error of executing the dti reconfig script on
-            each component instance's docker container, keyed by service_component_name.
-
-        """
-
-        if cherrypy.request.method != "POST":
-            raise cherrypy.HTTPError(404, "unexpected method {}".format(cherrypy.request.method))
-
-        msg = ""
-
-        dti_event = cherrypy.request.json or {}
-        str_dti_event = json.dumps(dti_event)
-
-        req_info = _DTIWeb._get_request_info(cherrypy.request)
-        audit = Audit(req_message="{}: {}".format(req_info, str_dti_event), \
-            headers=cherrypy.request.headers)
-        DTIWeb.logger.info("%s: dti_event=%s headers=%s", \
-            req_info, str_dti_event, json.dumps(cherrypy.request.headers))
-
-        dcae_service_action = dti_event.get('dcae_service_action')
-        if not dcae_service_action:
-            msg = 'dcae_service_action is missing'
-        elif dcae_service_action.lower() not in self.VALID_EVENT_TYPES:
-            msg = 'dcae_service_action is invalid'
-
-        dcae_target_name = dti_event.get('dcae_target_name')
-        if not msg and not dcae_target_name:
-            msg = 'dcae_target_name is missing'
-
-        dcae_target_type = dti_event.get('dcae_target_type', '')
-        if not msg and not dcae_target_type:
-            msg = 'dcae_target_type is missing'
-
-        if msg:
-            result = {"ERROR": msg}
-
-            DTIWeb.logger.error("%s: dti_event=%s result=%s", \
-                req_info, str_dti_event, json.dumps(result))
-        else:
-            send_notification = True
-            if (isinstance(notify, bool) and not notify) or \
-               (isinstance(notify, str) and notify.lower() in [ "f", "false", "n", "no" ]):
-                send_notification = False
-
-            prc = DTIProcessor(dti_event, send_notification=send_notification)
-            result = prc.get_result()
-
-            DTIWeb.logger.info("%s: dti_event=%s result=%s", \
-                req_info, str_dti_event, json.dumps(result))
-
-        success, http_status_code, _ = audit.audit_done(result=json.dumps(result))
-        if msg:
-            cherrypy.response.status = "400 Bad Request"
-        elif not success:
-            cherrypy.response.status = http_status_code
-
-        return result
-
-    def get_docker_events(self, request, service, location):
-        """
-        common routine for dti_docker_events and oti_docker_events
-
-        :param request: HTTP GET request
-        :param service: HTTP request query parameter for service name
-        :param location: HTTP request query parameter for location CLLI
-        :return:
-        """
-
-        if request.method != "GET":
-            raise cherrypy.HTTPError(404, "unexpected method {}".format(request.method))
-
-        req_info = _DTIWeb._get_request_info(request)
-        audit = Audit(req_message=req_info, headers=request.headers)
-
-        return DTIProcessor.get_docker_raw_events(service, location)
-
-    def get_k8s_events(self, request, **params):
-        """
-        common routine for dti_k8s_events and oti_k8s_events
-
-        :param request: HTTP GET request
-        :param params: HTTP request query parameters
-        :return:
-        """
-        if request.method != "GET":
-            raise cherrypy.HTTPError(404, "unexpected method {}".format(request.method))
-
-        req_info = _DTIWeb._get_request_info(request)
-        audit = Audit(req_message=req_info, headers=request.headers)
-
-        pod = request.params['pod']
-        namespace = request.params['namespace']
-        cluster = request.params['cluster']
-
-        return DTIProcessor.get_k8_raw_events(pod, cluster, namespace)
-
-    @cherrypy.expose
-    @cherrypy.tools.json_out()
-    def oti_k8s_events(self, **params):
-        """
-        Retrieve raw JSON events from application events database
-
-        GET /oti_k8_events?pod=<sts-1>&namespace=<ns1>&cluster=<cluster1>
-
-        Parameters
-        ----------
-        pod ID : string
-            POD ID of the stateful set POD
-        namespace: string
-            kubernetes namespace
-        cluster: string
-            kubernetes cluster FQDN
-
-        Returns
-        -------
-        dict
-            JSON object containing the fully-bound configuration.
-
-        """
-
-        return self.get_k8s_events(cherrypy.request, params)
-
-    @cherrypy.expose
-    @cherrypy.tools.json_out()
-    def dti_k8s_events(self, **params):
-        """
-        Retrieve raw JSON events from application events database
-
-        GET /dti_k8_events?pod=<sts-1>&namespace=<ns1>&cluster=<cluster1>
-
-        Parameters
-        ----------
-        pod ID : string
-            POD ID of the stateful set POD
-        namespace: string
-            kubernetes namespace
-        cluster: string
-            kubernetes cluster FQDN
-
-        Returns
-        -------
-        dict
-            JSON object containing the fully-bound configuration.
-
-        """
-
-        return self.get_k8s_events(cherrypy.request, params)
-
-    @cherrypy.expose
-    @cherrypy.tools.json_out()
-    def oti_docker_events(self, service, location=None):
-        """
-        Retrieve raw JSON events from application events database related to docker deployments
-
-        GET /oti_docker_events?service=<svc>&location=<location>
-
-        Parameters
-        ----------
-        service : string
-            The service component name assigned by dockerplugin to the component
-            that is unique to the cloudify node instance and used in its Consul key(s).
-        location : string
-            optional.  allows multiple values separated by commas.  Filters DTI events with dcae_service_location in service_location.
-            If service_location is not provided, then defaults to dockerhost or k8s cluster master node service Consul TAGs if service_name is provided,
-            otherwise results are not location filtered.
-
-        Returns
-        -------
-        dict
-            JSON object containing the fully-bound configuration.
-
-        """
-
-        return self.get_docker_events(cherrypy.request, service, location)
-
-    @cherrypy.expose
-    @cherrypy.tools.json_out()
-    def dti_docker_events(self, service, location=None):
-        """
-        Retrieve raw JSON events from application events database related to docker deployments
-
-        GET /dti_docker_events?service=<svc>&location=<location>
-
-        Parameters
-        ----------
-        service : string
-            The service component name assigned by dockerplugin to the component
-            that is unique to the cloudify node instance and used in its Consul key(s).
-        location : string
-            optional.  allows multiple values separated by commas.  Filters DTI events with dcae_service_location in service_location.
-            If service_location is not provided, then defaults to dockerhost or k8s cluster master node service Consul TAGs if service_name is provided,
-            otherwise results are not location filtered.
-
-        Returns
-        -------
-        dict
-            JSON object containing the fully-bound configuration.
-
-        """
-
-        return self.get_docker_events(cherrypy.request, service, location)
-
-    #----- Config Binding Service (CBS) endpoint methods
-
-    @cherrypy.expose
-    @cherrypy.popargs('service_name')
-    @cherrypy.tools.json_out()
-    def service_component(self, service_name):
-        """
-        Retrieve fully-bound configuration for service_name from Consul KVs.
-
-        GET /service_component/<service_name>
-
-        Parameters
-        ----------
-        service_name : string
-            The service component name assigned by dockerplugin to the component
-            that is unique to the cloudify node instance and used in its Consul key(s).
-
-        Returns
-        -------
-        dict
-            JSON object containing the fully-bound configuration.
-
-        """
-
-        if cherrypy.request.method != "GET":
-            raise cherrypy.HTTPError(404, "unexpected method {}".format(cherrypy.request.method))
-
-        req_info = _DTIWeb._get_request_info(cherrypy.request)
-        audit = Audit(req_message=req_info, headers=cherrypy.request.headers)
-        DTIWeb.logger.info("%s: service_name=%s headers=%s", \
-            req_info, service_name, json.dumps(cherrypy.request.headers))
-
-        try:
-            result = CBSRest.get_service_component(service_name)
-        except Exception as e:
-            result = {"ERROR": "exception {}: {!s}".format(type(e).__name__, e)}
-            audit.set_http_status_code(404)
-
-        DTIWeb.logger.info("%s: service_name=%s result=%s", \
-            req_info, service_name, json.dumps(result))
-
-        success, http_status_code, _ = audit.audit_done(result=json.dumps(result))
-        if not success:
-            cherrypy.response.status = http_status_code
-
-        return result
-
-    @cherrypy.expose
-    @cherrypy.popargs('service_name')
-    @cherrypy.tools.json_out()
-    def service_component_all(self, service_name, service_location=None, policy_ids="y"):
-        """
-        Retrieve all information for service_name (config, dti, dti_events, and policies) from Consul KVs.
-
-        GET /service_component_all/<service_name>
-
-        GET /service_component_all/<service_name>?service_location=<service_location>
-
-        GET /service_component_all/<service_name>?service_location=<service_location>;policy_ids=n
-
-        Parameters
-        ----------
-        service_name : string
-            The service component name assigned by dockerplugin to the component
-            that is unique to the cloudify node instance and used in its Consul key(s).
-        service_location : string
-            optional, allows multiple values separated by commas.
-            Filters DTI events with dcae_service_location in service_location.
-        policy_ids : string
-            optional, default "y", any of these will unset: [ "f", "false", "False", "FALSE", "n", "no" ]
-            When unset, formats policies items as a list (without policy_ids) rather than as an object indexed by policy_id.
-
-        Returns
-        -------
-        dict
-            JSON object containing all information for component service_name.
-            The top-level keys may include the following:
-            config : dict
-                The cloudify node's application_config property from when the start workflow was executed.
-            dti : dict
-                Keys are VNF Types that the component currently is assigned to monitor.  Policy can change them.
-            dti_events : dict
-                The latest deploy DTI events, keyed by VNF Type and sub-keyed by VNF Instance ID.
-            policies : dict
-                event : dict
-                    Contains information about when the policies folder was last written.
-                items : dict
-                    Contains all policy bodies for the service_name component, keyed by policy_id.
-
-        """
-
-        if cherrypy.request.method != "GET":
-            raise cherrypy.HTTPError(404, "unexpected method {}".format(cherrypy.request.method))
-
-        req_info = _DTIWeb._get_request_info(cherrypy.request)
-        audit = Audit(req_message=req_info, headers=cherrypy.request.headers)
-        DTIWeb.logger.info("%s: service_name=%s headers=%s", \
-            req_info, service_name, json.dumps(cherrypy.request.headers))
-
-        policies_as_list = False
-        if (isinstance(policy_ids, bool) and not policy_ids) or \
-           (isinstance(policy_ids, str) and policy_ids.lower() in [ "f", "false", "n", "no" ]):
-            policies_as_list = True
-        try:
-            result = CBSRest.get_service_component_all(service_name, service_location=service_location, policies_as_list=policies_as_list)
-        except Exception as e:
-            result = {"ERROR": "exception {}: {!s}".format(type(e).__name__, e)}
-            audit.set_http_status_code(404)
-
-        DTIWeb.logger.info("%s: service_name=%s result=%s", \
-            req_info, service_name, json.dumps(result))
-
-        success, http_status_code, _ = audit.audit_done(result=json.dumps(result))
-        if not success:
-            cherrypy.response.status = http_status_code
-
-        return result
-
-    @cherrypy.expose
-    @cherrypy.popargs('service_name')
-    @cherrypy.tools.json_out()
-    def dti(self, service_name=None, vnf_type=None, vnf_id=None, service_location=None):
-        """
-        Retrieve current (latest, not undeployed) DTI events from Consul KVs.
-
-        GET /dti/<service_name>
-
-        GET /dti/<service_name>?vnf_type=<vnf_type>;vnf_id=<vnf_id>;service_location=<service_location>
-
-        GET /dti
-
-        GET /dti?vnf_type=<vnf_type>;vnf_id=<vnf_id>;service_location=<service_location>
-
-        Parameters
-        ----------
-        service_name : string
-            optional.  The service component name assigned by dockerplugin to the component
-            that is unique to the cloudify node instance and used in its Consul key(s).
-        vnf_type : string
-            optional, allows multiple values separated by commas.  Gets DTI events for these vnf_type(s).
-        vnf_id : string
-            optional.  Requires vnf_type also.  Gets DTI event for this vnf_id.
-        service_location : string
-            optional, allows multiple values separated by commas.
-            Filters DTI events with dcae_service_location in service_location.
-
-        Returns
-        -------
-        dict
-            Dictionary of DTI event(s).
-            If one vnf_type and vnf_id are both specified, then object returned will be just the one DTI event.
-            If one vnf_type is specified but not vnf_id, then DTI events will be keyed by vnf_id.
-            Otherwise the DTI events will be keyed by vnf_type, sub-keyed by vnf_id.
-
-        """
-
-        if cherrypy.request.method != "GET":
-            raise cherrypy.HTTPError(404, "unexpected method {}".format(cherrypy.request.method))
-
-        req_info = _DTIWeb._get_request_info(cherrypy.request)
-        audit = Audit(req_message=req_info, headers=cherrypy.request.headers)
-        DTIWeb.logger.info("%s: service_name=%s headers=%s", \
-            req_info, service_name, json.dumps(cherrypy.request.headers))
-
-        try:
-            result = CBSRest.get_oti(service_name=service_name, vnf_type=vnf_type, vnf_id=vnf_id, service_location=service_location)
-        except Exception as e:
-            result = {"ERROR": "exception {}: {!s}".format(type(e).__name__, e)}
-            audit.set_http_status_code(404)
-
-        DTIWeb.logger.info("%s: service_name=%s result=%s", \
-            req_info, service_name, json.dumps(result))
-
-        success, http_status_code, _ = audit.audit_done(result=json.dumps(result))
-        if not success:
-            cherrypy.response.status = http_status_code
-
-        return result
-
-    @cherrypy.expose
-    @cherrypy.popargs('service_name')
-    @cherrypy.tools.json_out()
-    def policies(self, service_name, policy_id=None):
-        """
-        Retrieve policies for service_name from Consul KVs.
-
-        GET /policies/<service_name>
-
-        GET /policies/<service_name>?policy_id=<policy_id>
-
-        Parameters
-        ---------- 
-        service_name : string
-            The service component name assigned by dockerplugin to the component
-            that is unique to the cloudify node instance and used in its Consul key(s).
-        policy_id : string
-            optional.  Limits returned policy to this policy_id.
-
-        Returns
-        -------
-        dict
-            JSON object containing policy bodies for the service_name component.
-            If policy_id is specified, then object returned will be just the one policy body.
-            If policy_id is not specified, then object will contain all policy bodies, keyed by policy_id.
-
-        """
-
-        if cherrypy.request.method != "GET":
-            raise cherrypy.HTTPError(404, "unexpected method {}".format(cherrypy.request.method))
-
-        req_info = _DTIWeb._get_request_info(cherrypy.request)
-        audit = Audit(req_message=req_info, headers=cherrypy.request.headers)
-        DTIWeb.logger.info("%s: service_name=%s headers=%s", \
-            req_info, service_name, json.dumps(cherrypy.request.headers))
-
-        try:
-            result = CBSRest.get_policies(service_name, policy_id=policy_id)
-        except Exception as e:
-            result = {"ERROR": "exception {}: {!s}".format(type(e).__name__, e)}
-            audit.set_http_status_code(404)
-
-        DTIWeb.logger.info("%s: service_name=%s result=%s", \
-            req_info, service_name, json.dumps(result))
-
-        success, http_status_code, _ = audit.audit_done(result=json.dumps(result))
-        if not success:
-            cherrypy.response.status = http_status_code
-
-        return result