Feature 10885 - K8 Cluster and CNF Monitoring 77/11277/7 release-v11.0-start v11.0.0 v11.0.0rc1 v11.0.0rc2
authorAtul Agarwal <Atul.Agarwal@Altran.com>
Tue, 19 Oct 2021 17:20:52 +0000 (17:20 +0000)
committerpalsus <subhankar.pal@aricent.com>
Fri, 5 Nov 2021 07:14:46 +0000 (08:14 +0100)
Change-Id: I9e589b923f8539f52da14284c67a566104d074cb
Signed-off-by: Atul Agarwal <Atul.Agarwal@Altran.com>
osm_mon/core/common_db.py
osm_mon/core/mon.yaml
osm_mon/dashboarder/backends/grafana.py
osm_mon/dashboarder/service.py
osm_mon/dashboarder/templates/cnf_scoped.json [new file with mode: 0644]

index 1e78bc8..4f6ace0 100644 (file)
@@ -165,6 +165,9 @@ class CommonDbClient:
     def get_project(self, project_id: str):
         return self.common_db.get_one("projects", {"_id": project_id})
 
+    def get_k8sclusters(self):
+        return self.common_db.get_list("k8sclusters")
+
     def create_alarm(self, alarm: Alarm):
         action_data = {"uuid": alarm.uuid, "action": alarm.action}
         self.common_db.create("alarms_action", action_data)
index 85d21e3..68d036f 100644 (file)
@@ -62,6 +62,10 @@ prometheus:
   user: admin
   password: admin
 
+prometheus-operator:
+  port: 9090
+  ds_name_substr: prom-operator
+
 vca:
   host: localhost
   secret: secret
index e5fde98..60e4d7c 100644 (file)
@@ -55,6 +55,19 @@ class GrafanaBackend:
         log.debug("Searching for all dashboard uids: %s", dashboard_uids)
         return dashboard_uids
 
+    def get_all_datasource_names(self, datasource_name_substr):
+        # Gets only dashboards that were created for prom-operator
+        response = requests.request(
+            "GET", self.url + "/api/datasources", headers=self.headers
+        )
+        datasources = response.json()
+        datasource_names = []
+        for datasource in datasources:
+            if datasource["name"].startswith(datasource_name_substr):
+                datasource_names.append(datasource["name"])
+        log.debug("Searching for all datasource names: %s", datasource_names)
+        return datasource_names
+
     def get_dashboard_status(self, uid):
         response = requests.request(
             "GET", self.url + "/api/dashboards/uid/" + uid, headers=self.headers
@@ -62,7 +75,7 @@ class GrafanaBackend:
         log.debug("Searching for dashboard result: %s", response.text)
         return response
 
-    def create_dashboard(self, uid, name, json_file, project_name=None):
+    def create_dashboard(self, uid, name, json_file, project_name=None, datasource_name=None):
         try:
             with open(json_file) as f:
                 dashboard_data = f.read()
@@ -70,6 +83,8 @@ class GrafanaBackend:
             dashboard_data = dashboard_data.replace("OSM_ID", uid).replace(
                 "OSM_NAME", name
             )
+            if datasource_name:
+                dashboard_data = dashboard_data.replace("OSM_DATASOURCE_NAME", datasource_name)
             dashboard_json_data = json.loads(dashboard_data)
             # Get folder id
             if project_name:
@@ -123,6 +138,28 @@ class GrafanaBackend:
         except Exception:
             log.exception("Exception processing message: ")
 
+    def create_datasource(self, datasource_name, datasource_type, datasource_url):
+        try:
+            datasource_data = {
+                "name": datasource_name,
+                "type": datasource_type,
+                "url": datasource_url,
+                "access": "proxy",
+                "readOnly": False,
+                "basicAuth": False
+            }
+            response = requests.request(
+                "POST",
+                self.url + "/api/datasources",
+                data=json.dumps(datasource_data),
+                headers=self.headers,
+            )
+            log.info("Datasource %s is created in Grafana", datasource_name)
+            log.info("************* response: {}".format(response.__dict__))
+            return response
+        except Exception:
+            log.exception("Exception processing request for creating datasource: ")
+
     def send_request_for_creating_dashboard(self, dashboard_data):
         response = requests.request(
             "POST",
@@ -139,6 +176,13 @@ class GrafanaBackend:
         log.debug("Dashboard %s deleted from Grafana", uid)
         return response
 
+    def delete_datasource(self, datasource_name):
+        response = requests.request(
+            "DELETE", self.url + "/api/datasources/name/" + datasource_name, headers=self.headers
+        )
+        log.debug("Datasource %s deleted from Grafana", datasource_name)
+        return response
+
     def delete_admin_dashboard(self):
         requests.request(
             "DELETE",
index 0a1f947..a0a80a7 100644 (file)
@@ -28,6 +28,7 @@ from osm_mon.core.keystone import KeystoneConnection
 from osm_mon.dashboarder.backends.grafana import GrafanaBackend
 from osm_mon import __path__ as mon_path
 from osm_mon.core.utils import find_in_list, create_filter_from_nsr
+import re
 
 log = logging.getLogger(__name__)
 
@@ -46,8 +47,12 @@ class DashboarderService:
     def create_dashboards(self):
         # TODO lavado: migrate these methods to mongo change streams
         # Lists all dashboards and OSM resources for later comparisons
+        datasource_name_substr = self.conf.get("prometheus-operator", "ds_name_substr")
+        prom_operator_port = self.conf.get("prometheus-operator", "port")
         dashboard_uids = self.grafana.get_all_dashboard_uids()
+        datasource_names = self.grafana.get_all_datasource_names(datasource_name_substr)
         osm_resource_uids = []
+        osm_datasource_names = []
         projects = []
 
         # Check if keystone is the auth/projects backend and get projects from there
@@ -72,6 +77,9 @@ class DashboarderService:
             dashboard_path = "{}/dashboarder/templates/project_scoped.json".format(
                 mon_path[0]
             )
+            cnf_dashboard_path = "{}/dashboarder/templates/cnf_scoped.json".format(
+                mon_path[0]
+            )
             if project_id not in dashboard_uids:
                 project_name = project["name"]
                 if project_name != "admin":
@@ -83,6 +91,42 @@ class DashboarderService:
             else:
                 log.debug("Dashboard already exists")
 
+            # Read existing k8s cluster list and creates a dashboard for each
+            k8sclusters = self.common_db.get_k8sclusters()
+            for k8scluster in k8sclusters:
+                k8scluster_id = k8scluster["_id"]
+                k8scluster_name = k8scluster["name"]
+                osm_resource_uids.append(k8scluster_id)
+                osm_datasource_names.append("{}-{}".format(datasource_name_substr, k8scluster_name))
+                if k8scluster_id not in dashboard_uids:
+                    projects_read = k8scluster["_admin"]["projects_read"]
+                    if len(projects_read) and projects_read[0] == project_id:
+                        # Collect K8S Cluster IDs for periodical dashboard clean-up
+                        k8scluster_address = k8scluster["credentials"]["clusters"][0]["cluster"]["server"]
+                        # Extract K8S Cluster ip from url
+                        k8scluster_ip = re.findall(r'://([\w\-\.]+)', k8scluster_address)[0]
+
+                        # prometheus-operator url
+                        datasource_url = "http://{}:{}".format(k8scluster_ip, prom_operator_port)
+
+                        # Create datsource for prometheus-operator in grafana
+                        datasource_type = "prometheus"
+                        datasource_name = "{}-{}".format(datasource_name_substr, k8scluster_name)
+                        if datasource_name not in datasource_names:
+                            self.grafana.create_datasource(datasource_name, datasource_type, datasource_url)
+                            log.debug("Created datasource for k8scluster: %s", k8scluster_id)
+
+                        if project["name"] != "admin":
+                            self.grafana.create_dashboard(
+                                k8scluster_id, k8scluster_name, cnf_dashboard_path, project_name=project["name"],
+                                datasource_name=datasource_name)
+                        else:
+                            self.grafana.create_dashboard(
+                                k8scluster_id, k8scluster_name, cnf_dashboard_path, datasource_name=datasource_name)
+                        log.debug("Created dashboard for k8scluster: %s", k8scluster_id)
+                else:
+                    log.debug("Dashboard already exist for k8scluster: %s", k8scluster_id)
+
         # Reads existing NS list and creates a dashboard for each
         # TODO lavado: only create for ACTIVE NSRs
         nsrs = self.common_db.get_nsrs()
@@ -124,7 +168,7 @@ class DashboarderService:
                                     log.info("Project %s not found", project_id)
                                     log.debug("Exception %s" % e)
                             self.grafana.create_dashboard(
-                                nsr_id, nsr_name, dashboard_path, project_name
+                                nsr_id, nsr_name, dashboard_path, project_name=project_name
                             )
                             log.debug("Created dashboard for NS: %s", nsr_id)
                         else:
@@ -144,6 +188,14 @@ class DashboarderService:
             else:
                 log.debug("All dashboards in use")
 
+        # Delete obsolute datasources
+        for datasource_name in datasource_names:
+            if datasource_name not in osm_datasource_names:
+                self.grafana.delete_datasource(datasource_name)
+                log.debug("Deleted obsolete datasource: %s", datasource_name)
+            else:
+                log.debug("All dashboards in use")
+
     def create_grafana_user(self, user):
         self.grafana.create_grafana_users(user)
 
diff --git a/osm_mon/dashboarder/templates/cnf_scoped.json b/osm_mon/dashboarder/templates/cnf_scoped.json
new file mode 100644 (file)
index 0000000..aeb1c37
--- /dev/null
@@ -0,0 +1,1062 @@
+{
+    "dashboard": {
+        "annotations": {
+            "list": [{
+                    "builtIn": 1,
+                    "datasource": "-- Grafana --",
+                    "enable": true,
+                    "hide": true,
+                    "iconColor": "rgba(0, 211, 255, 1)",
+                    "name": "Annotations & Alerts",
+                    "type": "dashboard"
+                }
+            ]
+        },
+        "editable": true,
+        "gnetId": null,
+        "graphTooltip": 0,
+        "id": null,
+        "iteration": 1635943559726,
+        "links": [],
+        "panels": [{
+                "cacheTimeout": null,
+                "colorBackground": false,
+                "colorPrefix": false,
+                "colorValue": true,
+                "colors": [
+                    "#d44a3a",
+                    "rgba(237, 129, 40, 0.89)",
+                    "#73BF69"
+                ],
+                "datasource": "OSM_DATASOURCE_NAME",
+                "decimals": 0,
+                "format": "none",
+                "gauge": {
+                    "maxValue": 100,
+                    "minValue": 0,
+                    "show": false,
+                    "thresholdLabels": false,
+                    "thresholdMarkers": true
+                },
+                "gridPos": {
+                    "h": 6,
+                    "w": 6,
+                    "x": 0,
+                    "y": 0
+                },
+                "id": 1,
+                "interval": null,
+                "links": [],
+                "mappingType": 1,
+                "mappingTypes": [{
+                        "name": "value to text",
+                        "value": 1
+                    }, {
+                        "name": "range to text",
+                        "value": 2
+                    }
+                ],
+                "maxDataPoints": 100,
+                "nullPointMode": "connected",
+                "nullText": null,
+                "options": {},
+                "postfix": "",
+                "postfixFontSize": "100%",
+                "prefix": "",
+                "prefixFontSize": "100%",
+                "rangeMaps": [{
+                        "from": "null",
+                        "text": "N/A",
+                        "to": "null"
+                    }
+                ],
+                "sparkline": {
+                    "fillColor": "rgba(31, 118, 189, 0.18)",
+                    "full": false,
+                    "lineColor": "rgb(31, 120, 193)",
+                    "show": false,
+                    "ymax": null,
+                    "ymin": null
+                },
+                "tableColumn": "",
+                "targets": [{
+                        "expr": "sum(kube_pod_info{namespace=~\"$namespace\", cluster=\"$cluster\",pod=~\"$pod\"})",
+                        "format": "time_series",
+                        "instant": true,
+                        "intervalFactor": 2,
+                        "legendFormat": "{{container}}",
+                        "legendLink": null,
+                        "refId": "A",
+                        "step": 10
+                    }
+                ],
+                "thresholds": "",
+                "timeFrom": null,
+                "timeShift": null,
+                "title": "Pods",
+                "type": "singlestat",
+                "valueFontSize": "200%",
+                "valueMaps": [{
+                        "op": "=",
+                        "text": "N/A",
+                        "value": "null"
+                    }
+                ],
+                "valueName": "current"
+            }, {
+                "cacheTimeout": null,
+                "colorBackground": false,
+                "colorPrefix": false,
+                "colorValue": true,
+                "colors": [
+                    "#d44a3a",
+                    "rgba(237, 129, 40, 0.89)",
+                    "#73BF69"
+                ],
+                "datasource": "OSM_DATASOURCE_NAME",
+                "decimals": 2,
+                "format": "none",
+                "gauge": {
+                    "maxValue": 100,
+                    "minValue": 0,
+                    "show": false,
+                    "thresholdLabels": false,
+                    "thresholdMarkers": true
+                },
+                "gridPos": {
+                    "h": 3,
+                    "w": 6,
+                    "x": 6,
+                    "y": 0
+                },
+                "id": 31,
+                "interval": null,
+                "links": [],
+                "mappingType": 1,
+                "mappingTypes": [{
+                        "name": "value to text",
+                        "value": 1
+                    }, {
+                        "name": "range to text",
+                        "value": 2
+                    }
+                ],
+                "maxDataPoints": 100,
+                "nullPointMode": "connected",
+                "nullText": null,
+                "options": {},
+                "postfix": "",
+                "postfixFontSize": "100%",
+                "prefix": "",
+                "prefixFontSize": "100%",
+                "rangeMaps": [{
+                        "from": "null",
+                        "text": "N/A",
+                        "to": "null"
+                    }
+                ],
+                "sparkline": {
+                    "fillColor": "rgba(31, 118, 189, 0.18)",
+                    "full": false,
+                    "lineColor": "rgb(31, 120, 193)",
+                    "show": false,
+                    "ymax": null,
+                    "ymin": null
+                },
+                "tableColumn": "",
+                "targets": [{
+                        "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"})",
+                        "format": "time_series",
+                        "instant": true,
+                        "intervalFactor": 2,
+                        "legendFormat": "{{container}}",
+                        "legendLink": null,
+                        "refId": "A",
+                        "step": 10
+                    }
+                ],
+                "thresholds": "",
+                "timeFrom": null,
+                "timeShift": null,
+                "title": "Total CPU Usage",
+                "type": "singlestat",
+                "valueFontSize": "120%",
+                "valueMaps": [{
+                        "op": "=",
+                        "text": "N/A",
+                        "value": "null"
+                    }
+                ],
+                "valueName": "current"
+            }, {
+                "cacheTimeout": null,
+                "datasource": "OSM_DATASOURCE_NAME",
+                "gridPos": {
+                    "h": 3,
+                    "w": 12,
+                    "x": 12,
+                    "y": 0
+                },
+                "id": 24,
+                "links": [],
+                "options": {
+                    "displayMode": "lcd",
+                    "fieldOptions": {
+                        "calcs": [
+                            "mean"
+                        ],
+                        "defaults": {
+                            "mappings": [],
+                            "max": 1000,
+                            "min": 0,
+                            "thresholds": [{
+                                    "color": "green",
+                                    "value": null
+                                }, {
+                                    "color": "#EAB839",
+                                    "value": 100
+                                }, {
+                                    "color": "red",
+                                    "value": 200
+                                }
+                            ],
+                            "unit": "none"
+                        },
+                        "override": {},
+                        "values": false
+                    },
+                    "orientation": "horizontal"
+                },
+                "pluginVersion": "6.3.5",
+                "targets": [{
+                        "expr": "sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}[$__interval]))",
+                        "format": "time_series",
+                        "instant": false,
+                        "intervalFactor": 2,
+                        "legendFormat": "{{pod}}",
+                        "legendLink": null,
+                        "refId": "A",
+                        "step": 10
+                    }
+                ],
+                "timeFrom": null,
+                "timeShift": null,
+                "title": "Total Receive Bandwidth",
+                "type": "bargauge"
+            }, {
+                "cacheTimeout": null,
+                "colorBackground": false,
+                "colorPrefix": false,
+                "colorValue": true,
+                "colors": [
+                    "#d44a3a",
+                    "rgba(237, 129, 40, 0.89)",
+                    "#73BF69"
+                ],
+                "datasource": "OSM_DATASOURCE_NAME",
+                "decimals": 2,
+                "format": "decbytes",
+                "gauge": {
+                    "maxValue": 100,
+                    "minValue": 0,
+                    "show": false,
+                    "thresholdLabels": false,
+                    "thresholdMarkers": true
+                },
+                "gridPos": {
+                    "h": 3,
+                    "w": 6,
+                    "x": 6,
+                    "y": 3
+                },
+                "id": 30,
+                "interval": null,
+                "links": [],
+                "mappingType": 1,
+                "mappingTypes": [{
+                        "name": "value to text",
+                        "value": 1
+                    }, {
+                        "name": "range to text",
+                        "value": 2
+                    }
+                ],
+                "maxDataPoints": 100,
+                "nullPointMode": "connected",
+                "nullText": null,
+                "options": {},
+                "postfix": "",
+                "postfixFontSize": "100%",
+                "prefix": "",
+                "prefixFontSize": "100%",
+                "rangeMaps": [{
+                        "from": "null",
+                        "text": "N/A",
+                        "to": "null"
+                    }
+                ],
+                "sparkline": {
+                    "fillColor": "rgba(31, 118, 189, 0.18)",
+                    "full": false,
+                    "lineColor": "rgb(31, 120, 193)",
+                    "show": false,
+                    "ymax": null,
+                    "ymin": null
+                },
+                "tableColumn": "",
+                "targets": [{
+                        "expr": "sum(container_memory_working_set_bytes{cluster=\"$cluster\", namespace=~\"$namespace\", container!=\"\", image!=\"\", pod=~\"$pod\"})",
+                        "format": "time_series",
+                        "instant": true,
+                        "intervalFactor": 2,
+                        "legendFormat": "{{container}}",
+                        "legendLink": null,
+                        "refId": "A",
+                        "step": 10
+                    }
+                ],
+                "thresholds": "",
+                "timeFrom": null,
+                "timeShift": null,
+                "title": "Total Memory Usage",
+                "type": "singlestat",
+                "valueFontSize": "120%",
+                "valueMaps": [{
+                        "op": "=",
+                        "text": "N/A",
+                        "value": "null"
+                    }
+                ],
+                "valueName": "current"
+            }, {
+                "cacheTimeout": null,
+                "datasource": "OSM_DATASOURCE_NAME",
+                "gridPos": {
+                    "h": 3,
+                    "w": 12,
+                    "x": 12,
+                    "y": 3
+                },
+                "id": 25,
+                "links": [],
+                "options": {
+                    "displayMode": "lcd",
+                    "fieldOptions": {
+                        "calcs": [
+                            "mean"
+                        ],
+                        "defaults": {
+                            "mappings": [],
+                            "max": 1000,
+                            "min": 0,
+                            "thresholds": [{
+                                    "color": "green",
+                                    "value": null
+                                }, {
+                                    "color": "#EAB839",
+                                    "value": 100
+                                }, {
+                                    "color": "red",
+                                    "value": 200
+                                }
+                            ]
+                        },
+                        "override": {},
+                        "values": false
+                    },
+                    "orientation": "horizontal"
+                },
+                "pluginVersion": "6.3.5",
+                "targets": [{
+                        "expr": "sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}[$__interval]))",
+                        "format": "time_series",
+                        "intervalFactor": 2,
+                        "legendFormat": "{{pod}}",
+                        "legendLink": null,
+                        "refId": "A",
+                        "step": 10
+                    }
+                ],
+                "timeFrom": null,
+                "timeShift": null,
+                "title": "Total Transmit Bandwidth",
+                "type": "bargauge"
+            }, {
+                "aliasColors": {},
+                "bars": false,
+                "dashLength": 10,
+                "dashes": false,
+                "datasource": "OSM_DATASOURCE_NAME",
+                "fill": 0,
+                "fillGradient": 0,
+                "gridPos": {
+                    "h": 6,
+                    "w": 12,
+                    "x": 0,
+                    "y": 6
+                },
+                "id": 27,
+                "legend": {
+                    "alignAsTable": false,
+                    "avg": false,
+                    "current": false,
+                    "max": false,
+                    "min": false,
+                    "rightSide": false,
+                    "show": true,
+                    "sideWidth": 300,
+                    "total": false,
+                    "values": false
+                },
+                "lines": true,
+                "linewidth": 1,
+                "nullPointMode": "null",
+                "options": {
+                    "dataLinks": []
+                },
+                "percentage": false,
+                "pointradius": 2,
+                "points": false,
+                "renderer": "flot",
+                "seriesOverrides": [],
+                "spaceLength": 10,
+                "stack": false,
+                "steppedLine": false,
+                "targets": [{
+                        "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}) by (pod)",
+                        "format": "time_series",
+                        "intervalFactor": 2,
+                        "legendFormat": "{{pod}}",
+                        "refId": "A"
+                    }, {
+                        "expr": "",
+                        "refId": "B"
+                    }, {
+                        "refId": "C"
+                    }, {
+                        "refId": "D"
+                    }
+                ],
+                "thresholds": [],
+                "timeFrom": null,
+                "timeRegions": [],
+                "timeShift": null,
+                "title": "CPU Usage",
+                "tooltip": {
+                    "shared": true,
+                    "sort": 0,
+                    "value_type": "individual"
+                },
+                "type": "graph",
+                "xaxis": {
+                    "buckets": null,
+                    "mode": "time",
+                    "name": null,
+                    "show": true,
+                    "values": []
+                },
+                "yaxes": [{
+                        "format": "short",
+                        "label": null,
+                        "logBase": 1,
+                        "max": null,
+                        "min": null,
+                        "show": true
+                    }, {
+                        "format": "short",
+                        "label": null,
+                        "logBase": 1,
+                        "max": null,
+                        "min": null,
+                        "show": true
+                    }
+                ],
+                "yaxis": {
+                    "align": false,
+                    "alignLevel": null
+                }
+            }, {
+                "aliasColors": {},
+                "bars": false,
+                "dashLength": 10,
+                "dashes": false,
+                "datasource": "OSM_DATASOURCE_NAME",
+                "fill": 0,
+                "fillGradient": 0,
+                "gridPos": {
+                    "h": 6,
+                    "w": 12,
+                    "x": 12,
+                    "y": 6
+                },
+                "id": 29,
+                "legend": {
+                    "avg": false,
+                    "current": false,
+                    "max": false,
+                    "min": false,
+                    "show": true,
+                    "total": false,
+                    "values": false
+                },
+                "lines": true,
+                "linewidth": 1,
+                "nullPointMode": "null",
+                "options": {
+                    "dataLinks": []
+                },
+                "percentage": false,
+                "pointradius": 2,
+                "points": false,
+                "renderer": "flot",
+                "seriesOverrides": [],
+                "spaceLength": 10,
+                "stack": false,
+                "steppedLine": false,
+                "targets": [{
+                        "expr": "sum(container_memory_working_set_bytes{cluster=\"$cluster\", namespace=~\"$namespace\", container!=\"\", image!=\"\", pod=~\"$pod\"}) by (pod)",
+                        "intervalFactor": 2,
+                        "legendFormat": "{{pod}}",
+                        "refId": "A"
+                    }
+                ],
+                "thresholds": [],
+                "timeFrom": null,
+                "timeRegions": [],
+                "timeShift": null,
+                "title": "Memory Usage",
+                "tooltip": {
+                    "shared": true,
+                    "sort": 0,
+                    "value_type": "individual"
+                },
+                "type": "graph",
+                "xaxis": {
+                    "buckets": null,
+                    "mode": "time",
+                    "name": null,
+                    "show": true,
+                    "values": []
+                },
+                "yaxes": [{
+                        "format": "decbytes",
+                        "label": null,
+                        "logBase": 1,
+                        "max": null,
+                        "min": null,
+                        "show": true
+                    }, {
+                        "format": "decbytes",
+                        "label": null,
+                        "logBase": 1,
+                        "max": null,
+                        "min": null,
+                        "show": true
+                    }
+                ],
+                "yaxis": {
+                    "align": false,
+                    "alignLevel": null
+                }
+            }, {
+                "aliasColors": {},
+                "bars": false,
+                "dashLength": 10,
+                "dashes": false,
+                "datasource": "OSM_DATASOURCE_NAME",
+                "fieldConfig": {
+                    "defaults": {
+                        "custom": {}
+                    },
+                    "overrides": []
+                },
+                "fill": 0,
+                "fillGradient": 0,
+                "gridPos": {
+                    "h": 6,
+                    "w": 12,
+                    "x": 0,
+                    "y": 12
+                },
+                "hiddenSeries": false,
+                "id": 6,
+                "interval": "1m",
+                "legend": {
+                    "avg": false,
+                    "current": false,
+                    "max": false,
+                    "min": false,
+                    "show": true,
+                    "total": false,
+                    "values": false
+                },
+                "lines": true,
+                "linewidth": 1,
+                "links": [],
+                "nullPointMode": "null as zero",
+                "options": {
+                    "dataLinks": []
+                },
+                "percentage": false,
+                "pointradius": 5,
+                "points": false,
+                "renderer": "flot",
+                "seriesOverrides": [],
+                "spaceLength": 10,
+                "stack": false,
+                "steppedLine": false,
+                "targets": [{
+                        "expr": "sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}[$__interval])) by (pod)",
+                        "format": "time_series",
+                        "intervalFactor": 2,
+                        "legendFormat": "{{pod}}",
+                        "legendLink": null,
+                        "refId": "A",
+                        "step": 10
+                    }
+                ],
+                "thresholds": [],
+                "timeFrom": null,
+                "timeRegions": [],
+                "timeShift": null,
+                "title": "Receive Bandwidth",
+                "tooltip": {
+                    "shared": false,
+                    "sort": 0,
+                    "value_type": "individual"
+                },
+                "type": "graph",
+                "xaxis": {
+                    "buckets": null,
+                    "mode": "time",
+                    "name": null,
+                    "show": true,
+                    "values": []
+                },
+                "yaxes": [{
+                        "format": "Bps",
+                        "label": null,
+                        "logBase": 1,
+                        "max": null,
+                        "min": 0,
+                        "show": true
+                    }, {
+                        "format": "short",
+                        "label": null,
+                        "logBase": 1,
+                        "max": null,
+                        "min": null,
+                        "show": false
+                    }
+                ],
+                "yaxis": {
+                    "align": false,
+                    "alignLevel": null
+                }
+            }, {
+                "aliasColors": {},
+                "bars": false,
+                "dashLength": 10,
+                "dashes": false,
+                "datasource": "OSM_DATASOURCE_NAME",
+                "fieldConfig": {
+                    "defaults": {
+                        "custom": {}
+                    },
+                    "overrides": []
+                },
+                "fill": 0,
+                "fillGradient": 0,
+                "gridPos": {
+                    "h": 6,
+                    "w": 12,
+                    "x": 12,
+                    "y": 12
+                },
+                "hiddenSeries": false,
+                "id": 7,
+                "interval": "1m",
+                "legend": {
+                    "avg": false,
+                    "current": false,
+                    "max": false,
+                    "min": false,
+                    "show": true,
+                    "total": false,
+                    "values": false
+                },
+                "lines": true,
+                "linewidth": 1,
+                "links": [],
+                "nullPointMode": "null as zero",
+                "options": {
+                    "dataLinks": []
+                },
+                "percentage": false,
+                "pointradius": 5,
+                "points": false,
+                "renderer": "flot",
+                "seriesOverrides": [],
+                "spaceLength": 10,
+                "stack": false,
+                "steppedLine": false,
+                "targets": [{
+                        "expr": "sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}[$__interval])) by (pod)",
+                        "format": "time_series",
+                        "intervalFactor": 2,
+                        "legendFormat": "{{pod}}",
+                        "legendLink": null,
+                        "refId": "A",
+                        "step": 10
+                    }
+                ],
+                "thresholds": [],
+                "timeFrom": null,
+                "timeRegions": [],
+                "timeShift": null,
+                "title": "Transmit Bandwidth",
+                "tooltip": {
+                    "shared": false,
+                    "sort": 0,
+                    "value_type": "individual"
+                },
+                "type": "graph",
+                "xaxis": {
+                    "buckets": null,
+                    "mode": "time",
+                    "name": null,
+                    "show": true,
+                    "values": []
+                },
+                "yaxes": [{
+                        "format": "Bps",
+                        "label": null,
+                        "logBase": 1,
+                        "max": null,
+                        "min": 0,
+                        "show": true
+                    }, {
+                        "format": "short",
+                        "label": null,
+                        "logBase": 1,
+                        "max": null,
+                        "min": null,
+                        "show": false
+                    }
+                ],
+                "yaxis": {
+                    "align": false,
+                    "alignLevel": null
+                }
+            }, {
+                "aliasColors": {},
+                "bars": false,
+                "dashLength": 10,
+                "dashes": false,
+                "datasource": "OSM_DATASOURCE_NAME",
+                "fieldConfig": {
+                    "defaults": {
+                        "custom": {}
+                    },
+                    "overrides": []
+                },
+                "fill": 0,
+                "fillGradient": 0,
+                "gridPos": {
+                    "h": 6,
+                    "w": 12,
+                    "x": 0,
+                    "y": 18
+                },
+                "hiddenSeries": false,
+                "id": 8,
+                "interval": "1m",
+                "legend": {
+                    "avg": false,
+                    "current": false,
+                    "max": false,
+                    "min": false,
+                    "show": true,
+                    "total": false,
+                    "values": false
+                },
+                "lines": true,
+                "linewidth": 1,
+                "links": [],
+                "nullPointMode": "null as zero",
+                "options": {
+                    "dataLinks": []
+                },
+                "percentage": false,
+                "pointradius": 5,
+                "points": false,
+                "renderer": "flot",
+                "seriesOverrides": [],
+                "spaceLength": 10,
+                "stack": false,
+                "steppedLine": false,
+                "targets": [{
+                        "expr": "sum(irate(container_network_receive_packets_total{cluster=\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}[$__interval])) by (pod)",
+                        "format": "time_series",
+                        "intervalFactor": 2,
+                        "legendFormat": "{{pod}}",
+                        "legendLink": null,
+                        "refId": "A",
+                        "step": 10
+                    }
+                ],
+                "thresholds": [],
+                "timeFrom": null,
+                "timeRegions": [],
+                "timeShift": null,
+                "title": "Rate of Received Packets",
+                "tooltip": {
+                    "shared": false,
+                    "sort": 0,
+                    "value_type": "individual"
+                },
+                "type": "graph",
+                "xaxis": {
+                    "buckets": null,
+                    "mode": "time",
+                    "name": null,
+                    "show": true,
+                    "values": []
+                },
+                "yaxes": [{
+                        "format": "Bps",
+                        "label": null,
+                        "logBase": 1,
+                        "max": null,
+                        "min": 0,
+                        "show": true
+                    }, {
+                        "format": "short",
+                        "label": null,
+                        "logBase": 1,
+                        "max": null,
+                        "min": null,
+                        "show": false
+                    }
+                ],
+                "yaxis": {
+                    "align": false,
+                    "alignLevel": null
+                }
+            }, {
+                "aliasColors": {},
+                "bars": false,
+                "dashLength": 10,
+                "dashes": false,
+                "datasource": "OSM_DATASOURCE_NAME",
+                "fieldConfig": {
+                    "defaults": {
+                        "custom": {}
+                    },
+                    "overrides": []
+                },
+                "fill": 0,
+                "fillGradient": 0,
+                "gridPos": {
+                    "h": 6,
+                    "w": 12,
+                    "x": 12,
+                    "y": 18
+                },
+                "hiddenSeries": false,
+                "id": 9,
+                "interval": "1m",
+                "legend": {
+                    "avg": false,
+                    "current": false,
+                    "max": false,
+                    "min": false,
+                    "show": true,
+                    "total": false,
+                    "values": false
+                },
+                "lines": true,
+                "linewidth": 1,
+                "links": [],
+                "nullPointMode": "null as zero",
+                "options": {
+                    "dataLinks": []
+                },
+                "percentage": false,
+                "pointradius": 5,
+                "points": false,
+                "renderer": "flot",
+                "seriesOverrides": [],
+                "spaceLength": 10,
+                "stack": false,
+                "steppedLine": false,
+                "targets": [{
+                        "expr": "sum(irate(container_network_receive_packets_total{cluster=\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}[$__interval])) by (pod)",
+                        "format": "time_series",
+                        "intervalFactor": 2,
+                        "legendFormat": "{{pod}}",
+                        "legendLink": null,
+                        "refId": "A",
+                        "step": 10
+                    }
+                ],
+                "thresholds": [],
+                "timeFrom": null,
+                "timeRegions": [],
+                "timeShift": null,
+                "title": "Rate of Transmitted Packets",
+                "tooltip": {
+                    "shared": false,
+                    "sort": 0,
+                    "value_type": "individual"
+                },
+                "type": "graph",
+                "xaxis": {
+                    "buckets": null,
+                    "mode": "time",
+                    "name": null,
+                    "show": true,
+                    "values": []
+                },
+                "yaxes": [{
+                        "format": "Bps",
+                        "label": null,
+                        "logBase": 1,
+                        "max": null,
+                        "min": 0,
+                        "show": true
+                    }, {
+                        "format": "short",
+                        "label": null,
+                        "logBase": 1,
+                        "max": null,
+                        "min": null,
+                        "show": false
+                    }
+                ],
+                "yaxis": {
+                    "align": false,
+                    "alignLevel": null
+                }
+            }
+        ],
+        "refresh": "5s",
+        "schemaVersion": 19,
+        "style": "dark",
+        "tags": [
+            "osm_automated"
+        ],
+        "templating": {
+            "list": [{
+                    "allValue": null,
+                    "current": {
+                        "isNone": true,
+                        "selected": true,
+                        "text": "None",
+                        "value": ""
+                    },
+                    "datasource": "OSM_DATASOURCE_NAME",
+                    "definition": "",
+                    "hide": 2,
+                    "includeAll": false,
+                    "label": null,
+                    "multi": false,
+                    "name": "cluster",
+                    "options": [],
+                    "query": "label_values(kube_pod_info, cluster)",
+                    "refresh": 1,
+                    "regex": "",
+                    "skipUrlSync": false,
+                    "sort": 1,
+                    "tagValuesQuery": "",
+                    "tags": [],
+                    "tagsQuery": "",
+                    "type": "query",
+                    "useTags": false
+                }, {
+                    "allValue": null,
+                    "current": {
+                        "tags": [],
+                        "text": "None",
+                        "value": []
+                    },
+                    "datasource": "OSM_DATASOURCE_NAME",
+                    "definition": "",
+                    "hide": 0,
+                    "includeAll": false,
+                    "label": null,
+                    "multi": true,
+                    "name": "namespace",
+                    "options": [],
+                    "query": "label_values(kube_pod_info{cluster=\"$cluster\"}, namespace)",
+                    "refresh": 1,
+                    "regex": "",
+                    "skipUrlSync": false,
+                    "sort": 1,
+                    "tagValuesQuery": "",
+                    "tags": [],
+                    "tagsQuery": "",
+                    "type": "query",
+                    "useTags": false
+                }, {
+                    "allValue": null,
+                    "current": {
+                        "text": "None",
+                        "value": ""
+                    },
+                    "datasource": "OSM_DATASOURCE_NAME",
+                    "definition": "label_values(kube_pod_info{cluster=\"$cluster\", namespace=~\"$namespace\"}, pod)",
+                    "hide": 0,
+                    "includeAll": false,
+                    "label": null,
+                    "multi": true,
+                    "name": "pod",
+                    "options": [],
+                    "query": "label_values(kube_pod_info{cluster=\"$cluster\", namespace=~\"$namespace\"}, pod)",
+                    "refresh": 2,
+                    "regex": "",
+                    "skipUrlSync": false,
+                    "sort": 1,
+                    "tagValuesQuery": "",
+                    "tags": [],
+                    "tagsQuery": "",
+                    "type": "query",
+                    "useTags": false
+                }
+            ]
+        },
+        "time": {
+            "from": "now-30m",
+            "to": "now"
+        },
+        "timepicker": {
+            "refresh_intervals": [
+                "5s",
+                "10s",
+                "30s",
+                "1m",
+                "5m",
+                "15m",
+                "30m",
+                "1h",
+                "2h",
+                "1d"
+            ],
+            "time_options": [
+                "5m",
+                "15m",
+                "1h",
+                "6h",
+                "12h",
+                "24h",
+                "2d",
+                "7d",
+                "30d"
+            ]
+        },
+        "timezone": "",
+        "title": "OSM K8S Metrics - OSM_NAME",
+        "uid": "OSM_ID",
+        "version": 1
+    }
+}