예제 #1
0
    def __init__(self,
                 app_id,
                 monitor_plugin,
                 enable_visualizer,
                 datasource_type,
                 user,
                 password,
                 database_data,
                 timeout=60):
        Plugin.__init__(self, app_id, enable_visualizer, timeout)
        # Compute necessary variables
        kube.config.load_kube_config(api.k8s_conf_path)
        self.LOG = Log(LOG_NAME, LOG_FILE)
        self.visualizer_url = "URL not generated!"
        self.datasource = datasource_type
        self.monitor_plugin = monitor_plugin
        self.enable_visualization = enable_visualizer
        self.app_id = app_id
        self.grafana_user = user
        self.grafana_password = password
        if datasource_type == 'influxdb':
            self.datasource = InfluxDataSource(monitor_plugin, database_data,
                                               app_id)
        elif datasource_type == 'monasca':
            self.datasource = MonascaDataSource(app_id)
        else:
            raise Exception("ERROR: Datasource type unknown...!")

        self.visualizer_type = api.visualizer_type

        # Gets the visualizer ip if the value is not explicitic in the config file
        try:
            self.visualizer_ip = api.visualizer_ip
        except AttributeError:
            self.visualizer_ip = api.get_node_cluster(api.k8s_conf_path)
예제 #2
0
 def __init__(self, app_id):
     Base.__init__(self, app_id, api.monasca_datasource_name,
                   api.monasca_datasource_type)
     # Compute necessary variables
     self.LOG = Log(LOG_NAME, LOG_FILE)
     self.datasource_access = api.monasca_datasource_access
     self.datasource_url = api.monasca_datasource_url
     self.datasource_basic_auth = api.monasca_datasource_basic_auth
     self.datasource_auth_type = api.monasca_datasource_auth_type
     self.datasource_token = api.monasca_datasource_token
     self.dashboard_path = './visualizer/utils/templates/dashboard-job-monasca.template'
     self.image = 'monasca/grafana'
예제 #3
0
 def __init__(self, app_id):
     Base.__init__(self, app_id, api.monasca_datasource_name,
                   api.monasca_datasource_type)
     # Compute necessary variables
     self.LOG = Log(LOG_NAME, LOG_FILE)
     self.datasource_access = api.monasca_datasource_access
     self.datasource_url = api.monasca_datasource_url
     self.datasource_basic_auth = api.monasca_datasource_basic_auth
     self.datasource_auth_type = api.monasca_datasource_auth_type
     self.datasource_token = api.monasca_datasource_token
     self.dashboard_path = MONASCA_FILE_PATH
     self.image = 'monasca/grafana'
예제 #4
0
 def __init__(self, monitor_plugin, database_data, app_id):
     Base.__init__(self, app_id, api.influxdb_datasource_name, api.influxdb_datasource_type)
     # Compute necessary variables
     self.LOG = Log(LOG_NAME, LOG_FILE)
     self.datasource_access = api.influxdb_datasource_access
     self.datasource_url = database_data['url']
     self.datasource_port = database_data['port']
     self.database_name = database_data['name']
     if(monitor_plugin == 'kubejobs'):
         self.dashboard_path = './visualizer/utils/templates/dashboard-job-influxdb-kubejobs.template'
     elif(monitor_plugin == 'external_api'):
         self.dashboard_path = './visualizer/utils/templates/dashboard-job-influxdb-vertical.template'
     self.image = 'grafana/grafana:5.4.2'
    def __init__(self, monitor_plugin, database_data, app_id):
        Base.__init__(self, app_id, api.influxdb_datasource_name,
                      api.influxdb_datasource_type)
        # Compute necessary variables
        self.LOG = Log(LOG_NAME, LOG_FILE)
        self.datasource_access = api.influxdb_datasource_access
        self.datasource_url = database_data['url']
        self.datasource_port = database_data['port']
        self.database_name = database_data['name']
        if (monitor_plugin == 'kubejobs'):
            self.dashboard_path = K8S_TEMPLATE_PATH

        elif (monitor_plugin == 'external_api'):
            self.dashboard_path = VERTICAL_TEMPLATE_PATH

        self.image = 'grafana/grafana:5.4.2'
예제 #6
0
class K8sGrafanaProgress(Plugin):
    def __init__(self,
                 app_id,
                 monitor_plugin,
                 enable_visualizer,
                 datasource_type,
                 user,
                 password,
                 database_data,
                 timeout=60):
        Plugin.__init__(self, app_id, enable_visualizer, timeout)
        # Compute necessary variables
        kube.config.load_kube_config(api.k8s_conf_path)
        self.LOG = Log(LOG_NAME, LOG_FILE)
        self.visualizer_url = "URL not generated!"
        self.datasource = datasource_type
        self.monitor_plugin = monitor_plugin
        self.enable_visualization = enable_visualizer
        self.app_id = app_id
        self.grafana_user = user
        self.grafana_password = password
        if datasource_type == 'influxdb':
            self.datasource = InfluxDataSource(monitor_plugin, database_data,
                                               app_id)
        elif datasource_type == 'monasca':
            self.datasource = MonascaDataSource(app_id)
        else:
            raise Exception("ERROR: Datasource type unknown...!")

        self.visualizer_type = api.visualizer_type

        # Gets the visualizer ip if the value is not explicitic in the config file
        try:
            self.visualizer_ip = api.visualizer_ip
        except AttributeError:
            self.visualizer_ip = api.get_node_cluster(api.k8s_conf_path)

    def start_visualization(self):
        """ Starts the visualization of the job
        
        Arguments:
            None
        
        Returns:
            None
        """

        try:
            self._create_grafana_components(self.app_id,
                                            self.grafana_user,
                                            self.grafana_password,
                                            timeout=self.timeout)

        except Exception as e:
            self.LOG.log(e)

    def stop_visualization(self):
        """ Stop visualizer service and delete all resources
        
        Arguments: 
            None
        Returns: 
            None
        """
        self.LOG.log("The %s is stopping for %s..." %
                     (type(self).__name__, self.app_id))
        self.running = False
        self._delete_visualizer_resources()

    def get_visualizer_url(self):
        """ Gets the url to the visualizer of the specific job
        
        Arguments: 
            None
        Returns:
          String -- The url of the visualizer
        """
        return self.visualizer_url

    def _delete_visualizer_resources(self, visualizer_type='grafana'):
        """Delete visualizer resources (Pod and Service) of a specific job
        
        Arguments:
            None or visualizer_type {string} -- Type of visualizer service
        Returns:
            None
        """
        self.datasource.delete_visualizer_resources(visualizer_type)

    def _get_grafana_pod_spec(self, grafana_port=3000):
        """ Create the Pod spec for grafana
        
        Arguments:
            grafana_port {int} -- Port that the grafana will serve
        
        Returns:
            Dict -- Dict with specs of grafana pod
        """
        grafana_pod_spec = {
            "apiVersion": "v1",
            "kind": "Pod",
            "metadata": {
                "name": "grafana-%s" % self.app_id,
                "labels": {
                    "app": "grafana-%s" % self.app_id
                }
            },
            "spec": {
                "containers": [{
                    "name":
                    "grafana-master",
                    "image":
                    self.datasource.image,
                    "env": [{
                        "name": "MASTER",
                        "value": str(True)
                    }, {
                        "name": "GF_SECURITY_ADMIN_PASSWORD",
                        "value": self.grafana_password
                    }],
                    "ports": [{
                        "containerPort": grafana_port
                    }]
                }]
            }
        }

        return grafana_pod_spec

    def _get_grafana_service_spec(self, port=3000):
        """ Create the Service spec for grafana
        
        Arguments:
            grafana_port {int} -- Port that the grafana will serve
        
        Returns:
            Dict -- Dict with specs of grafana service
        """
        # Create the Service object for grafana
        visualizer_svc_spec = {
            "apiVersion": "v1",
            "kind": "Service",
            "metadata": {
                "name": "grafana-%s" % self.app_id,
                "labels": {
                    "app": "grafana-%s" % self.app_id
                }
            },
            "spec": {
                "ports": [{
                    "protocol": "TCP",
                    "port": port,
                    "targetPort": port
                }],
                "selector": {
                    "app": "grafana-%s" % self.app_id
                },
                "type": "NodePort"
            }
        }

        return visualizer_svc_spec

    def _create_grafana_pod(self, namespace='default'):
        """ Create the Pod for grafana
        
        Arguments:
            namespace {string} -- Namespace that the grafana pod will be created
        
        Returns:
            None
        """
        grafana_pod_spec = self._get_grafana_pod_spec()
        CoreV1Api = kube.client.CoreV1Api()
        try:
            self.LOG.log("Creating Grafana Pod...")
            CoreV1Api.create_namespaced_pod(namespace=namespace,
                                            body=grafana_pod_spec)
            self.LOG.log("Grafana Pod Created...!")
        except kube.client.rest.ApiException as e:
            self.LOG.log(e)

    def _create_grafana_service(self, namespace='default'):
        """ Create the Service for grafana
        
        Arguments:
            namespace {string} -- Namespace that the grafana service will be created
        
        Returns:
            None
        """
        grafana_svc_spec = self._get_grafana_service_spec()
        CoreV1Api = kube.client.CoreV1Api()
        node_port = None
        try:
            self.LOG.log("Creating Grafana Service...")
            s = CoreV1Api.create_namespaced_service(namespace=namespace,
                                                    body=grafana_svc_spec)
            node_port = s.spec.ports[0].node_port
        except kube.client.rest.ApiException as e:
            self.LOG.log(e)
        return node_port

    def _create_datasource(self, grafana_user, grafana_password, visualizer_ip,
                           node_port, timeout):
        """ Create the Datasource in grafana
        
        Arguments:
            grafana_user {string} -- Grafana's user with the necessary permissions
            grafana_password {string} -- Password of the Grafana user
            visualizer_ip {string} -- IP of one of the slaves that will be used to access the visualizer
            node_port {string} -- Port where the visualizer will be running
            timeout {int} -- Max time that will try create datasource
        
        Returns:
            Boolean -- State of creation of datasource
        """
        start = time.time()
        ready = False
        self.LOG.log("Trying Grafana on %s:%s..." % (visualizer_ip, node_port))
        while time.time() - start < timeout:
            time.sleep(5)
            datasource_result = self.datasource.create_grafana_datasource(
                grafana_user, grafana_password, visualizer_ip, node_port)
            if (datasource_result):
                self.LOG.log("Connected to Grafana on %s:%s!" %
                             (visualizer_ip, node_port))
                self.LOG.log("Data source created on Grafana")
                ready = True
                break
            else:
                self.LOG.log("Grafana is not ready yet!")
        return ready

    def _create_dashboard(self, grafana_user, grafana_password, visualizer_ip,
                          node_port, timeout):
        """ Create the Datasource in grafana
        
        Arguments:
            grafana_user {string} -- Grafana's user with the necessary permissions
            grafana_password {string} -- Password of the Grafana user
            visualizer_ip {string} -- IP of one of the slaves that will be used to access the visualizer
            node_port {string} -- Port where the visualizer will be running
            timeout {int} -- Max time that will try create dashboard
            
        Returns:
            Boolean -- State of creation of dashboard
        """
        start = time.time()
        ready = False
        self.LOG.log("Trying to generate dashboard for Grafana on %s:%d..." %
                     (visualizer_ip, node_port))
        while time.time() - start < timeout:
            time.sleep(5)
            dashboard_result = self.datasource.create_grafana_dashboard(
                grafana_user, grafana_password, visualizer_ip, node_port)
            if (dashboard_result):
                self.LOG.log("Dashboard of the job created on: http://%s:%s" %
                             (visualizer_ip, node_port))
                self.visualizer_url = "http://%s:%s" % (visualizer_ip,
                                                        node_port)
                ready = True
                break
            else:
                self.LOG.log("Grafana is not ready yet!")
        return ready

    def _create_grafana_components(self,
                                   app_id,
                                   grafana_user,
                                   grafana_password,
                                   namespace="default",
                                   visualizer_port=3000,
                                   timeout=60):
        """ Generates a individual visualizer dashboard for the Job.
        Create a Pod for the visualizer and expose it through a NodePort Service.
        
        Arguments:
            app_id {string} -- Id of the job launched
            img {string} -- Image grafana of the container
            namespace {string} -- pods's namespace
            visualizer_port {int} -- container's port
            timeout_id {int} -- timeout of the function
        
        Returns:
            tuple -- A pair with the ip and port running the grafana service
        """

        self._create_grafana_pod()
        node_port = self._create_grafana_service()

        visualizer_ip = self.visualizer_ip
        self.LOG.log("Created Grafana on address: %s:%d" %
                     (visualizer_ip, node_port))

        # Check when the visualizer is ready to create the datasource and dashboard

        try:
            datasource_created = self._create_datasource(
                grafana_user, grafana_password, visualizer_ip, node_port,
                timeout)

            dashboard_created = self._create_dashboard(grafana_user,
                                                       grafana_password,
                                                       visualizer_ip,
                                                       node_port, timeout)

            if datasource_created and dashboard_created:
                return visualizer_ip, node_port

            else:
                raise Exception("Could not provision Grafana!")

        except Exception as ex:
            self.LOG.log("Timed out waiting for Grafana to be available.")
            self.LOG.log("Grafana address: %s:%d" % (visualizer_ip, node_port))
            self.datasource.delete_visualizer_resources(app_id)
class InfluxDataSource(Base):
    def __init__(self, monitor_plugin, database_data, app_id):
        Base.__init__(self, app_id, api.influxdb_datasource_name,
                      api.influxdb_datasource_type)
        # Compute necessary variables
        self.LOG = Log(LOG_NAME, LOG_FILE)
        self.datasource_access = api.influxdb_datasource_access
        self.datasource_url = database_data['url']
        self.datasource_port = database_data['port']
        self.database_name = database_data['name']
        if (monitor_plugin == 'kubejobs'):
            self.dashboard_path = K8S_TEMPLATE_PATH

        elif (monitor_plugin == 'external_api'):
            self.dashboard_path = VERTICAL_TEMPLATE_PATH

        self.image = 'grafana/grafana:5.4.2'

    def create_grafana_datasource(self, user, password, visualizer_ip,
                                  node_port):

        url = "http://%s:%s@%s:%d/api/datasources" %\
            (user, password, visualizer_ip, node_port)

        data_ds = {
            "name": self.datasource_name,
            "type": self.datasource_type,
            "url":
            "http://%s:%d" % (self.datasource_url, self.datasource_port),
            "access": self.datasource_access,
            "database": self.database_name
        }

        data = json.dumps(data_ds)
        headers = {'content-type': 'application/json'}

        successful_request = True
        try:
            requests.post(url, data=data, headers=headers)
        except requests.exceptions.ConnectionError:
            successful_request = False
        return successful_request

    def create_grafana_dashboard(self, user, password, visualizer_ip,
                                 node_port):

        url = "http://%s:%s@%s:%s/api/dashboards/db" %\
            (user, password, visualizer_ip, node_port)

        opened = open(self.dashboard_path)

        template = opened.read().replace("app_id", self.app_id)
        dashboard_data = json.loads(template)
        data = json.dumps(dashboard_data)

        headers = {'content-type': 'application/json'}

        successful_request = True
        try:
            requests.post(url, data=data, headers=headers)
        except requests.exceptions.ConnectionError:
            successful_request = False

        return successful_request

    def delete_visualizer_resources(self,
                                    visualizer_type='grafana',
                                    namespace="default"):

        # load kubernetes config
        kube.config.load_kube_config(api.k8s_conf_path)

        CoreV1Api = kube.client.CoreV1Api()
        # Create generic ``V1DeleteOptions``
        delete = kube.client.V1DeleteOptions()

        name = "%s-%s" % (visualizer_type, self.app_id)

        # Deleting Pod
        self.LOG.log("Deleting %s Pod for job %s..." %
                     (visualizer_type, self.app_id))
        CoreV1Api.delete_namespaced_pod(name=name,
                                        namespace=namespace,
                                        body=delete)

        # Deleting service
        self.LOG.log("Deleting %s Service for job %s" %
                     (visualizer_type, self.app_id))
        CoreV1Api.delete_namespaced_service(name=name,
                                            namespace=namespace,
                                            body=delete)

        influxdb_name = "%s-%s" % (self.datasource_type, self.app_id)
        # Deleting Pod
        self.LOG.log("Deleting InfluxDB resources...")
        CoreV1Api.\
            delete_namespaced_pod(name=influxdb_name,
                                  namespace=namespace,
                                  body=delete)

        # Deleting service
        CoreV1Api.\
            delete_namespaced_service(name=influxdb_name,
                                      namespace=namespace,
                                      body=delete)
예제 #8
0
#    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 visualizer.service import api
from visualizer.utils.logger import Log
from visualizer import exceptions as ex
from visualizer.plugins.builder import VisualizerBuilder


API_LOG = Log("APIv10", "logs/APIv10.log")

visualized_apps = {}
builder = VisualizerBuilder()

def start_visualization(data, app_id):
    """Starts the visualization of a job
    
    Arguments:
        app_id {string} -- Id of the job
    
    Returns:
        None
    """

    if 'plugin' not in data or 'enable_visualizer' not in data or \
예제 #9
0
class MonascaDataSource(Base):
    def __init__(self, app_id):
        Base.__init__(self, app_id, api.monasca_datasource_name,
                      api.monasca_datasource_type)
        # Compute necessary variables
        self.LOG = Log(LOG_NAME, LOG_FILE)
        self.datasource_access = api.monasca_datasource_access
        self.datasource_url = api.monasca_datasource_url
        self.datasource_basic_auth = api.monasca_datasource_basic_auth
        self.datasource_auth_type = api.monasca_datasource_auth_type
        self.datasource_token = api.monasca_datasource_token
        self.dashboard_path = './visualizer/utils/templates/dashboard-job-monasca.template'
        self.image = 'monasca/grafana'

    def create_grafana_datasource(self, user, password, visualizer_ip,
                                  node_port):

        url = "http://%s:%s@%s:%d/api/datasources" % (user, password,
                                                      visualizer_ip, node_port)

        data_ds = {
            "name": self.datasource_name,
            "type": self.datasource_type,
            "url": self.datasource_url,
            "access": self.datasource_access,
            "basicAuth": self.datasource_basic_auth,
            "jsonData": {
                "authType": self.datasource_auth_type,
                "token": self.datasource_token
            }
        }

        data = json.dumps(data_ds)
        headers = {'content-type': 'application/json'}

        successful_request = True
        try:
            requests.post(url, data=data, headers=headers)
        except requests.exceptions.ConnectionError:
            successful_request = False
        return successful_request

    def create_grafana_dashboard(self, user, password, visualizer_ip,
                                 node_port):

        url = "http://%s:%s@%s:%s/api/dashboards/db" % (
            user, password, visualizer_ip, node_port)

        opened = open(self.dashboard_path)

        template = opened.read().replace("app_id", self.app_id)
        dashboard_data = json.loads(template)
        data = json.dumps(dashboard_data)

        headers = {'content-type': 'application/json'}

        successful_request = True
        try:
            requests.post(url, data=data, headers=headers)
        except requests.exceptions.ConnectionError:
            successful_request = False

        return successful_request

    def delete_visualizer_resources(self,
                                    visualizer_type='grafana',
                                    namespace="default"):

        # load kubernetes config
        kube.config.load_kube_config(api.k8s_conf_path)

        CoreV1Api = kube.client.CoreV1Api()
        # Create generic ``V1DeleteOptions``
        delete = kube.client.V1DeleteOptions()

        name = "%s-%s" % (visualizer_type, self.app_id)

        # Deleting Pod
        self.LOG.log("Deleting %s Pod for job %s..." %
                     (visualizer_type, self.app_id))
        CoreV1Api.delete_namespaced_pod(name=name,
                                        namespace=namespace,
                                        body=delete)

        # Deleting service
        self.LOG.log("Deleting %s Service for job %s" %
                     (visualizer_type, self.app_id))
        CoreV1Api.delete_namespaced_service(name=name,
                                            namespace=namespace,
                                            body=delete)