diff --git a/grafana-mysql-dashboard-for-ramendemo-new.yaml b/grafana-mysql-dashboard-for-ramendemo-new.yaml new file mode 100644 index 0000000..b74b7cb --- /dev/null +++ b/grafana-mysql-dashboard-for-ramendemo-new.yaml @@ -0,0 +1,1323 @@ +apiVersion: integreatly.org/v1alpha1 +kind: GrafanaDashboard +metadata: + labels: + app: grafana + name: ramendemo-app-dashboard +spec: + json: | + { + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "MySQL-RamenDemo", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 2, + "links": [], + "panels": [ + { + "datasource": "MySQL-RamenDemo", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "displayName": "IO", + "mappings": [], + "max": 2000, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 1500 + }, + { + "color": "red", + "value": 1700 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "reduceOptions": { + "calcs": [], + "fields": "", + "values": false + }, + "showThresholdLabels": true, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "7.5.11", + "targets": [ + { + "format": "time_series", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n count(id) AS \"id\"\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time) AND\n isprimary = 1\nGROUP BY 1\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "id" + ], + "type": "column" + }, + { + "params": [ + "count" + ], + "type": "aggregate" + }, + { + "params": [ + "id" + ], + "type": "alias" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "int", + "name": "", + "params": [ + "isprimary", + "=", + "1" + ], + "type": "expression" + } + ] + } + ], + "title": "Preferred Cluster", + "transparent": true, + "type": "gauge" + }, + { + "datasource": "MySQL-RamenDemo", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "displayName": "IO", + "mappings": [], + "max": 2000, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 1500 + }, + { + "color": "red", + "value": 1700 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 3, + "options": { + "reduceOptions": { + "calcs": [], + "fields": "", + "values": false + }, + "showThresholdLabels": true, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "7.5.11", + "targets": [ + { + "format": "time_series", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n count(id) AS \"id\"\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time) AND\n isprimary = 0\nGROUP BY 1\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "id" + ], + "type": "column" + }, + { + "params": [ + "count" + ], + "type": "aggregate" + }, + { + "params": [ + "id" + ], + "type": "alias" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "int", + "name": "", + "params": [ + "isprimary", + "=", + "0" + ], + "type": "expression" + } + ] + } + ], + "title": "Failover Cluster", + "transparent": true, + "type": "gauge" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0.1, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 5, + "interval": null, + "options": { + "displayMode": "gradient", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showUnfilled": false, + "text": { + "valueSize": 0 + } + }, + "pluginVersion": "7.5.11", + "targets": [ + { + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n submit_time AS \"time\",\n isprimary\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time)\nORDER BY submit_time", + "refId": "A", + "select": [ + [ + { + "params": [ + "isprimary" + ], + "type": "column" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Preferred Active", + "transparent": true, + "type": "bargauge" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0.1, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 6, + "interval": null, + "options": { + "displayMode": "gradient", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showUnfilled": false, + "text": { + "valueSize": 0 + } + }, + "pluginVersion": "7.5.11", + "targets": [ + { + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n submit_time AS \"time\",\n issecondary\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time)\nORDER BY submit_time", + "refId": "A", + "select": [ + [ + { + "params": [ + "issecondary" + ], + "type": "column" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Failover Active", + "transparent": true, + "type": "bargauge" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 0, + "y": 12 + }, + "id": 8, + "interval": null, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^metric$/", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.5.11", + "targets": [ + { + "format": "table", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "gap", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n gap AS metric,\n cluster1\nFROM ramenfsid\nWHERE\n $__timeFilter(submit_time) AND\n prevdate != 0 AND\n cluster1 = 1\nGROUP BY 1,2\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "cluster1" + ], + "type": "column" + } + ] + ], + "table": "ramenfsid", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "varchar", + "name": "", + "params": [ + "prevdate", + "!=", + "0" + ], + "type": "expression" + }, + { + "datatype": "int", + "name": "", + "params": [ + "cluster1", + "=", + "1" + ], + "type": "expression" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Last Gap", + "transformations": [], + "transparent": true, + "type": "stat" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 12, + "y": 12 + }, + "id": 9, + "interval": null, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^metric$/", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.5.11", + "targets": [ + { + "format": "table", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "gap", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n gap AS metric,\n cluster2\nFROM ramenfsid\nWHERE\n $__timeFilter(submit_time) AND\n prevdate != 0 AND\n cluster2 = 1\nGROUP BY 1,2\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "cluster2" + ], + "type": "column" + } + ] + ], + "table": "ramenfsid", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "varchar", + "name": "", + "params": [ + "prevdate", + "!=", + "0" + ], + "type": "expression" + }, + { + "datatype": "int", + "name": "", + "params": [ + "cluster2", + "=", + "1" + ], + "type": "expression" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Last Gap", + "transformations": [], + "transparent": true, + "type": "stat" + } + ], + "refresh": "10s", + "schemaVersion": 27, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "utc", + "title": "Ramen Demo Application Dashboard", + "uid": "EtKB_e2nz", + "version": 2 + } + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "MySQL-RamenDemo", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 2, + "links": [], + "panels": [ + { + "datasource": "MySQL-RamenDemo", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "displayName": "IO", + "mappings": [], + "max": 2000, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 1500 + }, + { + "color": "red", + "value": 1700 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "reduceOptions": { + "calcs": [], + "fields": "", + "values": false + }, + "showThresholdLabels": true, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "time_series", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n count(id) AS \"id\"\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time) AND\n isprimary = 1\nGROUP BY 1\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "id" + ], + "type": "column" + }, + { + "params": [ + "count" + ], + "type": "aggregate" + }, + { + "params": [ + "id" + ], + "type": "alias" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "int", + "name": "", + "params": [ + "isprimary", + "=", + "1" + ], + "type": "expression" + } + ] + } + ], + "title": "Preferred Cluster", + "transparent": true, + "type": "gauge" + }, + { + "datasource": "MySQL-RamenDemo", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "displayName": "IO", + "mappings": [], + "max": 2000, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 1500 + }, + { + "color": "red", + "value": 1700 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 3, + "options": { + "reduceOptions": { + "calcs": [], + "fields": "", + "values": false + }, + "showThresholdLabels": true, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "time_series", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n count(id) AS \"id\"\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time) AND\n isprimary = 0\nGROUP BY 1\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "id" + ], + "type": "column" + }, + { + "params": [ + "count" + ], + "type": "aggregate" + }, + { + "params": [ + "id" + ], + "type": "alias" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "int", + "name": "", + "params": [ + "isprimary", + "=", + "0" + ], + "type": "expression" + } + ] + } + ], + "title": "Failover Cluster", + "transparent": true, + "type": "gauge" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 5, + "interval": null, + "options": { + "displayMode": "gradient", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showUnfilled": false, + "text": { + "valueSize": 0 + } + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n submit_time AS \"time\",\n isprimary\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time)\nORDER BY submit_time", + "refId": "A", + "select": [ + [ + { + "params": [ + "isprimary" + ], + "type": "column" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Preferred Active", + "transparent": true, + "type": "bargauge" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 6, + "interval": null, + "options": { + "displayMode": "gradient", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showUnfilled": false, + "text": { + "valueSize": 0 + } + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n submit_time AS \"time\",\n issecondary\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time)\nORDER BY submit_time", + "refId": "A", + "select": [ + [ + { + "params": [ + "issecondary" + ], + "type": "column" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Failover Active", + "transparent": true, + "type": "bargauge" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 0, + "y": 12 + }, + "id": 8, + "interval": null, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^metric$/", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "table", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "gap", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n gap AS metric,\n cluster1\nFROM ramenfsid\nWHERE\n $__timeFilter(submit_time) AND\n prevdate != 0 AND\n cluster1 = 1\nGROUP BY 1,2\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "cluster1" + ], + "type": "column" + } + ] + ], + "table": "ramenfsid", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "varchar", + "name": "", + "params": [ + "prevdate", + "!=", + "0" + ], + "type": "expression" + }, + { + "datatype": "int", + "name": "", + "params": [ + "cluster1", + "=", + "1" + ], + "type": "expression" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Last Gap", + "transformations": [], + "transparent": true, + "type": "stat" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 12, + "y": 12 + }, + "id": 9, + "interval": null, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^metric$/", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "table", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "gap", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n gap AS metric,\n cluster2\nFROM ramenfsid\nWHERE\n $__timeFilter(submit_time) AND\n prevdate != 0 AND\n cluster2 = 1\nGROUP BY 1,2\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "cluster2" + ], + "type": "column" + } + ] + ], + "table": "ramenfsid", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "varchar", + "name": "", + "params": [ + "prevdate", + "!=", + "0" + ], + "type": "expression" + }, + { + "datatype": "int", + "name": "", + "params": [ + "cluster2", + "=", + "1" + ], + "type": "expression" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Last Gap", + "transformations": [], + "transparent": true, + "type": "stat" + } + ], + "refresh": "10s", + "schemaVersion": 27, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "UTC", + "title": "Ramen Demo Application Dashboard", + "uid": "EtKB_e2nz", + "version": 3 + } diff --git a/grafana-mysql-dashboard-for-ramendemo-old.yaml b/grafana-mysql-dashboard-for-ramendemo-old.yaml new file mode 100644 index 0000000..e4d2df0 --- /dev/null +++ b/grafana-mysql-dashboard-for-ramendemo-old.yaml @@ -0,0 +1,664 @@ +apiVersion: integreatly.org/v1alpha1 +kind: GrafanaDashboard +metadata: + labels: + app: grafana + name: ramendemo-app-dashboard +spec: + json: | + { + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "MySQL-RamenDemo", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 2, + "links": [], + "panels": [ + { + "datasource": "MySQL-RamenDemo", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "displayName": "IO", + "mappings": [], + "max": 2000, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 1500 + }, + { + "color": "red", + "value": 1700 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "reduceOptions": { + "calcs": [], + "fields": "", + "values": false + }, + "showThresholdLabels": true, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "time_series", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n count(id) AS \"id\"\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time) AND\n isprimary = 1\nGROUP BY 1\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "id" + ], + "type": "column" + }, + { + "params": [ + "count" + ], + "type": "aggregate" + }, + { + "params": [ + "id" + ], + "type": "alias" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "int", + "name": "", + "params": [ + "isprimary", + "=", + "1" + ], + "type": "expression" + } + ] + } + ], + "title": "Preferred Cluster", + "transparent": true, + "type": "gauge" + }, + { + "datasource": "MySQL-RamenDemo", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "displayName": "IO", + "mappings": [], + "max": 2000, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 1500 + }, + { + "color": "red", + "value": 1700 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 3, + "options": { + "reduceOptions": { + "calcs": [], + "fields": "", + "values": false + }, + "showThresholdLabels": true, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "time_series", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n count(id) AS \"id\"\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time) AND\n isprimary = 0\nGROUP BY 1\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "id" + ], + "type": "column" + }, + { + "params": [ + "count" + ], + "type": "aggregate" + }, + { + "params": [ + "id" + ], + "type": "alias" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "int", + "name": "", + "params": [ + "isprimary", + "=", + "0" + ], + "type": "expression" + } + ] + } + ], + "title": "Failover Cluster", + "transparent": true, + "type": "gauge" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 5, + "interval": null, + "options": { + "displayMode": "gradient", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showUnfilled": false, + "text": { + "valueSize": 0 + } + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n submit_time AS \"time\",\n isprimary\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time)\nORDER BY submit_time", + "refId": "A", + "select": [ + [ + { + "params": [ + "isprimary" + ], + "type": "column" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Preferred Active", + "transparent": true, + "type": "bargauge" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 6, + "interval": null, + "options": { + "displayMode": "gradient", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showUnfilled": false, + "text": { + "valueSize": 0 + } + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n submit_time AS \"time\",\n issecondary\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time)\nORDER BY submit_time", + "refId": "A", + "select": [ + [ + { + "params": [ + "issecondary" + ], + "type": "column" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Failover Active", + "transparent": true, + "type": "bargauge" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 0, + "y": 12 + }, + "id": 8, + "interval": null, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^metric$/", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "table", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "gap", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n gap AS metric,\n cluster1\nFROM ramenfsid\nWHERE\n $__timeFilter(submit_time) AND\n prevdate != 0 AND\n cluster1 = 1\nGROUP BY 1,2\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "cluster1" + ], + "type": "column" + } + ] + ], + "table": "ramenfsid", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "varchar", + "name": "", + "params": [ + "prevdate", + "!=", + "0" + ], + "type": "expression" + }, + { + "datatype": "int", + "name": "", + "params": [ + "cluster1", + "=", + "1" + ], + "type": "expression" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Last Gap", + "transformations": [], + "transparent": true, + "type": "stat" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 12, + "y": 12 + }, + "id": 9, + "interval": null, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^metric$/", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "table", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "gap", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n gap AS metric,\n cluster2\nFROM ramenfsid\nWHERE\n $__timeFilter(submit_time) AND\n prevdate != 0 AND\n cluster2 = 1\nGROUP BY 1,2\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "cluster2" + ], + "type": "column" + } + ] + ], + "table": "ramenfsid", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "varchar", + "name": "", + "params": [ + "prevdate", + "!=", + "0" + ], + "type": "expression" + }, + { + "datatype": "int", + "name": "", + "params": [ + "cluster2", + "=", + "1" + ], + "type": "expression" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Last Gap", + "transformations": [], + "transparent": true, + "type": "stat" + } + ], + "refresh": "10s", + "schemaVersion": 27, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Ramen Demo Application Dashboard", + "uid": "EtKB_e2nz", + "version": 3 + } diff --git a/guimou-qui-marche-encore.json b/guimou-qui-marche-encore.json new file mode 100644 index 0000000..510b616 --- /dev/null +++ b/guimou-qui-marche-encore.json @@ -0,0 +1,660 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "MySQL-RamenDemo", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 2, + "links": [], + "panels": [ + { + "datasource": "MySQL-RamenDemo", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "displayName": "IO", + "mappings": [], + "max": 2000, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 1500 + }, + { + "color": "red", + "value": 1700 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "reduceOptions": { + "calcs": [], + "fields": "", + "values": false + }, + "showThresholdLabels": true, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "7.5.11", + "targets": [ + { + "format": "time_series", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n count(id) AS \"id\"\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time) AND\n isprimary = 1\nGROUP BY 1\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "id" + ], + "type": "column" + }, + { + "params": [ + "count" + ], + "type": "aggregate" + }, + { + "params": [ + "id" + ], + "type": "alias" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "int", + "name": "", + "params": [ + "isprimary", + "=", + "1" + ], + "type": "expression" + } + ] + } + ], + "title": "Preferred Cluster", + "transparent": true, + "type": "gauge" + }, + { + "datasource": "MySQL-RamenDemo", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "displayName": "IO", + "mappings": [], + "max": 2000, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 1500 + }, + { + "color": "red", + "value": 1700 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 3, + "options": { + "reduceOptions": { + "calcs": [], + "fields": "", + "values": false + }, + "showThresholdLabels": true, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "7.5.11", + "targets": [ + { + "format": "time_series", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n count(id) AS \"id\"\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time) AND\n isprimary = 0\nGROUP BY 1\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "id" + ], + "type": "column" + }, + { + "params": [ + "count" + ], + "type": "aggregate" + }, + { + "params": [ + "id" + ], + "type": "alias" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "int", + "name": "", + "params": [ + "isprimary", + "=", + "0" + ], + "type": "expression" + } + ] + } + ], + "title": "Failover Cluster", + "transparent": true, + "type": "gauge" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0.1, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 5, + "interval": null, + "options": { + "displayMode": "gradient", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showUnfilled": false, + "text": { + "valueSize": 0 + } + }, + "pluginVersion": "7.5.11", + "targets": [ + { + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n submit_time AS \"time\",\n isprimary\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time)\nORDER BY submit_time", + "refId": "A", + "select": [ + [ + { + "params": [ + "isprimary" + ], + "type": "column" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Preferred Active", + "transparent": true, + "type": "bargauge" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0.1, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 6, + "interval": null, + "options": { + "displayMode": "gradient", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showUnfilled": false, + "text": { + "valueSize": 0 + } + }, + "pluginVersion": "7.5.11", + "targets": [ + { + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n submit_time AS \"time\",\n issecondary\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time)\nORDER BY submit_time", + "refId": "A", + "select": [ + [ + { + "params": [ + "issecondary" + ], + "type": "column" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Failover Active", + "transparent": true, + "type": "bargauge" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 0, + "y": 12 + }, + "id": 8, + "interval": null, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^metric$/", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.5.11", + "targets": [ + { + "format": "table", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "gap", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n gap AS metric,\n cluster1\nFROM ramenfsid\nWHERE\n $__timeFilter(submit_time) AND\n prevdate != 0 AND\n cluster1 = 1\nGROUP BY 1,2\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "cluster1" + ], + "type": "column" + } + ] + ], + "table": "ramenfsid", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "varchar", + "name": "", + "params": [ + "prevdate", + "!=", + "0" + ], + "type": "expression" + }, + { + "datatype": "int", + "name": "", + "params": [ + "cluster1", + "=", + "1" + ], + "type": "expression" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Last Gap", + "transformations": [], + "transparent": true, + "type": "stat" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 12, + "y": 12 + }, + "id": 9, + "interval": null, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^metric$/", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.5.11", + "targets": [ + { + "format": "table", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "gap", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n gap AS metric,\n cluster2\nFROM ramenfsid\nWHERE\n $__timeFilter(submit_time) AND\n prevdate != 0 AND\n cluster2 = 1\nGROUP BY 1,2\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "cluster2" + ], + "type": "column" + } + ] + ], + "table": "ramenfsid", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "varchar", + "name": "", + "params": [ + "prevdate", + "!=", + "0" + ], + "type": "expression" + }, + { + "datatype": "int", + "name": "", + "params": [ + "cluster2", + "=", + "1" + ], + "type": "expression" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Last Gap", + "transformations": [], + "transparent": true, + "type": "stat" + } + ], + "refresh": "10s", + "schemaVersion": 27, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "utc", + "title": "Ramen Demo Application Dashboard", + "uid": "EtKB_e2nz", + "version": 2 +} diff --git a/keycloak-odf/README.md b/keycloak-odf/README.md new file mode 100644 index 0000000..46f0e95 --- /dev/null +++ b/keycloak-odf/README.md @@ -0,0 +1,52 @@ +# Demonstrate a sample keycloak application +## Tool Requirements +- OpenShift CLI Version >= 4.3.0
_Needed for kustomize_ + +```bash +oc version +``` + +- OpenShift Data Foundation Version >= 4.4.0
_For general use case_ + +```bash +oc get csv pn openshift-storage +NAME DISPLAY VERSION REPLACES PHASE +ocs-operator.v4.8.0 OpenShift Container Storage 4.8.0 Succeeded +``` + +## Summary +Demonstrate a keycloak application (frontend+backend) leveraging Red Hat OpenShift Data Foundation block device capabilites when deployed using ACM. This application offers a WEB UI while using a PostgreSQL database to store its information. + +## Prerequisite + +- 1+ managed-clusters total +- Those `Managed-Cluster` to target, must have a label with `metadata.labels.usage: development` +- Target clusters must have the PostgreSQL Operator Deployed +- Target clusters must have the Red Hat OpenShift Data Foundation and an operational Ceph cluster deployed + +## Application Console: Create a new application +Using the application console, you can easily create an Application to run this demo. + +#### Console +1. Open the Red Hat Advanced Cluster Management for Kubernetes console +2. Navigate on the left navigation menu to `Managed applications` +3. Click the `Create application` button +4. Enter the following values: + * **Name:** `keycloak-odf` + * **Namespace:** `keycloak-odf` + * **Repository types:** `Git` + * **URL:** `https://github.com/open-cluster-management/application-samples.git` + * **Branch:** `main` + * **Path:** `keycloak-odf` + * Select `Deploy application resources only on clusters matching specified labels` + * **Label name:** `usage` + * **Label value:** `development` +5. Click `Save` + +### Viewing +1. Navigate on the left navigation menu to `Managed applications` +2. Click the `keycloak-odf` Application name. +3. View the Topology +4. Click the `Route` node to obtain the application URL +5. Click the URL to see the keycloak sample application + diff --git a/keycloak-odf/keycloak-app.yaml b/keycloak-odf/keycloak-app.yaml new file mode 100644 index 0000000..8912d41 --- /dev/null +++ b/keycloak-odf/keycloak-app.yaml @@ -0,0 +1,49 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: keycloak-odf-app +# namespace: postgres-operator + namespace: keycloak-odf + labels: + app.kubernetes.io/name: keycloak-odf-app +spec: + selector: + matchLabels: + app.kubernetes.io/name: keycloak-odf-app + template: + metadata: + labels: + app.kubernetes.io/name: keycloak-odf-app + spec: + containers: + - image: quay.io/keycloak/keycloak:latest + name: keycloak + env: + - name: DB_VENDOR + value: "postgres" + - name: DB_ADDR + valueFrom: { secretKeyRef: { name: keycloak-odf-db-pguser-keycloak-odf-db, key: host } } + - name: DB_PORT + valueFrom: { secretKeyRef: { name: keycloak-odf-db-pguser-keycloak-odf-db, key: port } } + - name: DB_DATABASE + valueFrom: { secretKeyRef: { name: keycloak-odf-db-pguser-keycloak-odf-db, key: dbname } } + - name: DB_USER + valueFrom: { secretKeyRef: { name: keycloak-odf-db-pguser-keycloak-odf-db, key: user } } + - name: DB_PASSWORD + valueFrom: { secretKeyRef: { name: keycloak-odf-db-pguser-keycloak-odf-db, key: password } } + - name: KEYCLOAK_USER + value: "admin" + - name: KEYCLOAK_PASSWORD + value: "admin" + - name: PROXY_ADDRESS_FORWARDING + value: "true" + ports: + - name: http + containerPort: 8080 + - name: https + containerPort: 8443 + readinessProbe: + httpGet: + path: /auth/realms/master + port: 8080 + restartPolicy: Always diff --git a/keycloak-odf/keycloak-postgres.yaml b/keycloak-odf/keycloak-postgres.yaml new file mode 100644 index 0000000..a4a695f --- /dev/null +++ b/keycloak-odf/keycloak-postgres.yaml @@ -0,0 +1,38 @@ +apiVersion: postgres-operator.crunchydata.com/v1beta1 +kind: PostgresCluster +metadata: + name: keycloak-odf-db + namespace: keycloak-odf +spec: + image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres-ha:centos8-13.3-1 + postgresVersion: 13 + instances: + - replicas: 1 + dataVolumeClaimSpec: + accessModes: + - "ReadWriteOnce" + resources: + requests: + storage: 10Gi + storageClassName: ocs-storagecluster-ceph-mirror + metadata: + labels: + "appname": "keycloak-odf-app" + backups: + pgbackrest: + image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:centos8-2.33-1 + repoHost: + dedicated: {} + repos: + - name: repo1 + volume: + volumeClaimSpec: + accessModes: + - "ReadWriteOnce" + resources: + requests: + storage: 100Gi + storageClassName: ocs-storagecluster-ceph-mirror + metadata: + labels: + "appname": "keycloak-odf-app" diff --git a/keycloak-odf/keycloak-route.yaml b/keycloak-odf/keycloak-route.yaml new file mode 100644 index 0000000..fa6a12c --- /dev/null +++ b/keycloak-odf/keycloak-route.yaml @@ -0,0 +1,10 @@ +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: frontend +spec: +# host: keycloak-odf.apps.ocpacm.ocstraining.com + tls: + termination: passthrough + to: + name: frontend diff --git a/keycloak-odf/keycloak-service.yaml b/keycloak-odf/keycloak-service.yaml new file mode 100644 index 0000000..7276eb0 --- /dev/null +++ b/keycloak-odf/keycloak-service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: +# name: keycloak-odf + name: frontend + labels: + name: frontend +spec: + type: ClusterIP + ports: + - port: 8443 + targetPort: 8443 + protocol: TCP + selector: + app.kubernetes.io/name: keycloak-odf-app diff --git a/keycloak-odf/kustomization.yaml b/keycloak-odf/kustomization.yaml new file mode 100644 index 0000000..e006161 --- /dev/null +++ b/keycloak-odf/kustomization.yaml @@ -0,0 +1,5 @@ +resources: +- keycloak-postgres.yaml +- keycloak-app.yaml +- keycloak-service.yaml +- keycloak-route.yaml diff --git a/ramendemo/Dockerfile b/ramendemo/Dockerfile new file mode 100644 index 0000000..fc3855a --- /dev/null +++ b/ramendemo/Dockerfile @@ -0,0 +1,22 @@ +FROM registry.access.redhat.com/ubi8/python-38 +#FROM docker.io/centos:centos7 +ENV ENABLE_MICROPIPENV="1" \ + UPGRADE_PIP_TO_LATEST="1" +USER root + +RUN yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -y +RUN wget https://repo.mysql.com/mysql80-community-release-el8-1.noarch.rpm +RUN yum localinstall mysql80-community-release-el8-1.noarch.rpm -y +RUN yum install python3-mysqlclient mysql-connector-odbc gcc unixODBC-devel -y + +RUN python -m pip install --upgrade pip +RUN pip3 install shortuuid mysqlclient mysql-connector mysql-connector-python pyodbc + +#RUN yum install gcc unixODBC-devel python3-mysqlclient mysql-connector-odbc -y +#RUN python -m pip install --upgrade pip +#RUN pip3 install shortuuid mysqlclient mysql-connector mysql-connector-python pyodbc + +WORKDIR /tmp +ADD *.py . + +ENTRYPOINT [ "python3", "/tmp/runloop.py --size --server" ] diff --git a/ramendemo/README.md b/ramendemo/README.md new file mode 100644 index 0000000..2ebc55f --- /dev/null +++ b/ramendemo/README.md @@ -0,0 +1,174 @@ +# RBD demo application with dashboard + +## Prepare your demo +Fork my repo at `https://github.com/jeanchlopez/application-samples`. + +``` +git clone https://github.com/{username}/application-samples +cd application-samples +git checkout ramendemo +git fetch +git pull +``` +Create a new project on OpenShift cluster with ACM installed: + +``` +oc new-project ramendemo-mysql +``` + +## Deploying MySQL Server + +In ACM create new application (**non-AWS**): + +- Name = `ramendemo-mysql` +- Namespace = `ramendemo-mysql` +- Git = `https://github.com/{username}/application-samples` +- Branch = `ramendemo` +- Path = `ramendemo/mysql` +- `Deploy on local cluster` + +If deploying on **AWS** use this method and YAML file to deploy MySQL. + +``` +cd ramendemo/mysql +oc project ramendemo-mysql +oc create -f mysql-aws.yaml +``` + +## Deploying Grafana dashboard + +Due to an issue with the Grafana operator (`https://github.com/grafana-operator/grafana-operator/issues/655`) +the dashboard can not be configured via ACM. + +You will have to deploy the Grafana dashboard in the same namespace as the one where the MySQl server was deployed. +``` +cd ramendemo/grafana +oc project ramendemo-mysql +``` + +Deploy the Grafana operator: + +``` +oc create -f operator.yaml +``` + +Wait for the operator to be deployed and show a `Succeeded` Phase. + +``` +oc get csv -n ramendemo-mysql +``` + +Example output: + +``` +NAME DISPLAY VERSION REPLACES PHASE +grafana-operator.v4.1.1 Grafana Operator 4.1.1 grafana-operator.v4.1.0 Succeeded +``` + +Once the Grafana operator is deployed, create Grafana resources. Order of yaml files is datasource, next dashboard, then grafana instance. + +``` +oc create -f grafana-mysql-datasource-for-ramendemo.yaml -n ramendemo-mysql +oc create -f grafana-mysql-dashboard-for-ramendemo.yaml -n ramendemo-mysql +oc create -f grafana-instance.yaml -n ramendemo-mysql +``` + +Wait for the Grafana pod to restart. If you need to connect with admin privilege use the following credentials. + +- User name = `admin` +- Password = `ramendemo` + +Do this to find the URL to reach the Grafana UI: + +``` +oc get route grafana-route in ramendemo-mysql +``` + +Copy the resulting route into a browser tab to validate you have access to Grafana. + +NOTE: Make sure you sure to use `https` for the Grafana route. + +NOTE: Login to Grafana and check you have a datasource. If there is a no datasource, you need to `oc apply -f grafana-mysql-datasource-for-ramendemo.yaml` and then check again to see of there is a datasource. + +## Configure MySQl address for test application + +Update the `rbdloop.yaml` with parameters matching your environment. + +To do this find the route for your mysql instance (**non-AWS**): + +``` +oc get route ramendemo-mysql -n ramendemo-mysql +``` +Use the resulting route to modify `rbdloop.yaml`as shown below (example SQL_SERVER value). + +NOTE: Make sure you are in the `ramendemo` directory. + +``` +cat rbdloop.yaml +[…] + - name: SQL_SERVER + value: "ramendemo-mysql-ramendemo-mysql.apps.hub.makestoragegreatagain.com" + - name: SQL_PORT + value: "30136" +[…] +``` + +If on using **AWS** do this: + +``` +oc get svc ramendemo-mysql -n ramendemo-mysql +``` + +Use the resulting `LoadBalancer` service `EXTERNAL-IP` to modify `rbdloop.yaml`as shown below (example SQL_SERVER value). + +``` +cat rbdloop.yaml +[…] + - name: SQL_SERVER + value: "a0daa32ed84804c9c88924a734218abc-1519604064.us-east-2.elb.amazonaws.com" + - name: SQL_PORT + value: "3306" +[…] +``` + +Now `rbdloop.yaml` needs to be committed to your forked repo. + +``` +git add rbdloop.yaml +git commit -m "Modified rbdloop.yaml" +git push origin ramendemo +``` + +## Deploy the application + +Create a new project on OpenShift cluster with ACM installed. + +``` +oc new-project rbdloop-dashboard +``` +NOTE: Make sure you are in the `ramendemo` directory. + +You now need to create a DRPlacementControl (DRPC)and PlacementRule for the `rbdloop` application. + +NOTE: Make sure to modify the DRPC YAML file and modify `cluster1` to be accurate for your environment. Modify to use the cluster name in ACM for your preferredCluster. + +``` +oc create -f rbdloop-drpc.yaml -n rbdloop-dashboard +``` + +Now create the PlacementRule: + +``` +oc create -f rbdloop-placementrule.yaml -n rbdloop-dashboard +``` + +In ACM create the new `rbdloop` application. + +- Name = `rbdloop` +- Namespace = `rbdloop-dashboard` +- Git = `https://github.com/{username}/application-samples` +- Branch = `ramendemo` +- Path = `ramendemo` +- Select an existing placement configuration = `rbdloop-placement` + +Go back to Grafana and navigate to the `Ramen Demo Application Dashboard` to monitor cluster Failover and Relocate operations. diff --git a/ramendemo/grafana/grafana-instance.yaml b/ramendemo/grafana/grafana-instance.yaml new file mode 100644 index 0000000..b74b96d --- /dev/null +++ b/ramendemo/grafana/grafana-instance.yaml @@ -0,0 +1,24 @@ +apiVersion: integreatly.org/v1alpha1 +kind: Grafana +metadata: + name: ramendemo-grafana +spec: + ingress: + enabled: true + config: + auth: + disable_signout_menu: true + auth.anonymous: + enabled: true + log: + level: warn + mode: console + security: + admin_password: ramendemo + admin_user: admin + dashboardLabelSelector: + - matchExpressions: + - key: app + operator: In + values: + - grafana diff --git a/ramendemo/grafana/grafana-mysql-dashboard-for-ramendemo.yaml b/ramendemo/grafana/grafana-mysql-dashboard-for-ramendemo.yaml new file mode 100644 index 0000000..d4f2805 --- /dev/null +++ b/ramendemo/grafana/grafana-mysql-dashboard-for-ramendemo.yaml @@ -0,0 +1,668 @@ +apiVersion: integreatly.org/v1alpha1 +kind: GrafanaDashboard +metadata: + labels: + app: grafana + name: ramendemo-app-dashboard +spec: + json: | + { + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "MySQL-RamenDemo", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 2, + "links": [], + "panels": [ + { + "datasource": "MySQL-RamenDemo", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "displayName": "IO", + "mappings": [], + "max": 2000, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 1500 + }, + { + "color": "red", + "value": 1700 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "reduceOptions": { + "calcs": [], + "fields": "", + "values": false + }, + "showThresholdLabels": true, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "time_series", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n count(id) AS \"id\"\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time) AND\n isprimary = 1\nGROUP BY 1\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "id" + ], + "type": "column" + }, + { + "params": [ + "count" + ], + "type": "aggregate" + }, + { + "params": [ + "id" + ], + "type": "alias" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "int", + "name": "", + "params": [ + "isprimary", + "=", + "1" + ], + "type": "expression" + } + ] + } + ], + "title": "Preferred Cluster", + "transparent": true, + "type": "gauge" + }, + { + "datasource": "MySQL-RamenDemo", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "displayName": "IO", + "mappings": [], + "max": 2000, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 1500 + }, + { + "color": "red", + "value": 1700 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 3, + "options": { + "reduceOptions": { + "calcs": [], + "fields": "", + "values": false + }, + "showThresholdLabels": true, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "time_series", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n count(id) AS \"id\"\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time) AND\n isprimary = 0\nGROUP BY 1\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "id" + ], + "type": "column" + }, + { + "params": [ + "count" + ], + "type": "aggregate" + }, + { + "params": [ + "id" + ], + "type": "alias" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "int", + "name": "", + "params": [ + "isprimary", + "=", + "0" + ], + "type": "expression" + } + ] + } + ], + "title": "Failover Cluster", + "transparent": true, + "type": "gauge" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0.1, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 5, + "interval": null, + "options": { + "displayMode": "gradient", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showUnfilled": false, + "text": { + "valueSize": 0 + } + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n submit_time AS \"time\",\n isprimary\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time)\nORDER BY submit_time", + "refId": "A", + "select": [ + [ + { + "params": [ + "isprimary" + ], + "type": "column" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Preferred Active", + "transparent": true, + "type": "bargauge" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0.1, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 6, + "interval": null, + "options": { + "displayMode": "gradient", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showUnfilled": false, + "text": { + "valueSize": 0 + } + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": false, + "rawSql": "SELECT\n submit_time AS \"time\",\n issecondary\nFROM ramendemo\nWHERE\n $__timeFilter(submit_time)\nORDER BY submit_time", + "refId": "A", + "select": [ + [ + { + "params": [ + "issecondary" + ], + "type": "column" + } + ] + ], + "table": "ramendemo", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Failover Active", + "transparent": true, + "type": "bargauge" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 0, + "y": 12 + }, + "id": 8, + "interval": null, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^metric$/", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "table", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "gap", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n gap AS metric,\n cluster1\nFROM ramenfsid\nWHERE\n $__timeFilter(submit_time) AND\n prevdate != 0 AND\n cluster1 = 1\nGROUP BY 1,2\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "cluster1" + ], + "type": "column" + } + ] + ], + "table": "ramenfsid", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "varchar", + "name": "", + "params": [ + "prevdate", + "!=", + "0" + ], + "type": "expression" + }, + { + "datatype": "int", + "name": "", + "params": [ + "cluster1", + "=", + "1" + ], + "type": "expression" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Last Gap", + "transformations": [], + "transparent": true, + "type": "stat" + }, + { + "datasource": "MySQL-RamenDemo", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 12, + "x": 12, + "y": 12 + }, + "id": 9, + "interval": null, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^metric$/", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.5.2", + "targets": [ + { + "format": "table", + "group": [ + { + "params": [ + "$__interval", + "0" + ], + "type": "time" + } + ], + "metricColumn": "gap", + "rawQuery": false, + "rawSql": "SELECT\n $__timeGroupAlias(submit_time,$__interval,0),\n gap AS metric,\n cluster2\nFROM ramenfsid\nWHERE\n $__timeFilter(submit_time) AND\n prevdate != 0 AND\n cluster2 = 1\nGROUP BY 1,2\nORDER BY $__timeGroup(submit_time,$__interval,0)", + "refId": "A", + "select": [ + [ + { + "params": [ + "cluster2" + ], + "type": "column" + } + ] + ], + "table": "ramenfsid", + "timeColumn": "submit_time", + "timeColumnType": "datetime", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + }, + { + "datatype": "varchar", + "name": "", + "params": [ + "prevdate", + "!=", + "0" + ], + "type": "expression" + }, + { + "datatype": "int", + "name": "", + "params": [ + "cluster2", + "=", + "1" + ], + "type": "expression" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Last Gap", + "transformations": [], + "transparent": true, + "type": "stat" + } + ], + "refresh": "10s", + "schemaVersion": 27, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Ramen Demo Application Dashboard", + "uid": "EtKB_e2nz", + "version": 3 + } diff --git a/ramendemo/grafana/grafana-mysql-datasource-for-ramendemo.yaml b/ramendemo/grafana/grafana-mysql-datasource-for-ramendemo.yaml new file mode 100644 index 0000000..1f52f8c --- /dev/null +++ b/ramendemo/grafana/grafana-mysql-datasource-for-ramendemo.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: integreatly.org/v1alpha1 +kind: GrafanaDataSource +metadata: + name: mysql-grafana-datasource-for-ramendemo +spec: + datasources: + - type: mysql + name: MySQL-RamenDemo + access: proxy + url: ramendemo-mysql + database: ramendemo + user: ramendemo + password: ramendemo + isDefault: true + editable: true + name: grafana-mysql-datasource-for-ramendemo.yaml diff --git a/ramendemo/grafana/kustomization.yaml b/ramendemo/grafana/kustomization.yaml new file mode 100644 index 0000000..d7b89c7 --- /dev/null +++ b/ramendemo/grafana/kustomization.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- grafana-mysql-datasource-for-ramendemo.yaml +- grafana-mysql-dashboard-for-ramendemo.yaml +- grafana-instance.yaml diff --git a/ramendemo/grafana/operator.yaml b/ramendemo/grafana/operator.yaml new file mode 100644 index 0000000..92c5718 --- /dev/null +++ b/ramendemo/grafana/operator.yaml @@ -0,0 +1,23 @@ +--- +apiVersion: operators.coreos.com/v1 +kind: OperatorGroup +metadata: + name: ramendemo-mysql-operatorgroup + namespace: ramendemo-mysql +spec: + serviceAccount: + metadata: + creationTimestamp: null + targetNamespaces: + - ramendemo-mysql +--- +apiVersion: operators.coreos.com/v1alpha1 +kind: Subscription +metadata: + name: grafana-operator +spec: + channel: v4 + installPlanApproval: Automatic + name: grafana-operator + source: community-operators + sourceNamespace: openshift-marketplace diff --git a/ramendemo/kustomization.yaml b/ramendemo/kustomization.yaml new file mode 100644 index 0000000..e014edc --- /dev/null +++ b/ramendemo/kustomization.yaml @@ -0,0 +1,3 @@ +resources: +- rbdloop.yaml + diff --git a/ramendemo/mysql/kustomization.yaml b/ramendemo/mysql/kustomization.yaml new file mode 100644 index 0000000..3d0795f --- /dev/null +++ b/ramendemo/mysql/kustomization.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- mysql.yaml diff --git a/ramendemo/mysql/mysql-aws.yaml b/ramendemo/mysql/mysql-aws.yaml new file mode 100644 index 0000000..b745b52 --- /dev/null +++ b/ramendemo/mysql/mysql-aws.yaml @@ -0,0 +1,69 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: ramendemo-mysql + labels: + app: ramendemo +spec: + type: LoadBalancer + ports: + - port: 3306 + selector: + app: ramendemo + tier: mysql +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: ramendemo-mysql-pv-claim + labels: + app: ramendemo +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ramendemo-mysql + labels: + app: ramendemo +spec: + selector: + matchLabels: + app: ramendemo + tier: mysql + strategy: + type: Recreate + template: + metadata: + labels: + app: ramendemo + tier: mysql + spec: + containers: + - image: mysql:5.6 + name: mysql + env: + - name: MYSQL_ROOT_PASSWORD + value: "redhat" + - name: MYSQL_DATABASE + value: "ramendemo" + - name: MYSQL_USER + value: "ramendemo" + - name: MYSQL_PASSWORD + value: "ramendemo" + ports: + - containerPort: 3306 + name: mysql + volumeMounts: + - name: mysql-persistent-storage + mountPath: /var/lib/mysql + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: ramendemo-mysql-pv-claim diff --git a/ramendemo/mysql/mysql.yaml b/ramendemo/mysql/mysql.yaml new file mode 100644 index 0000000..3920755 --- /dev/null +++ b/ramendemo/mysql/mysql.yaml @@ -0,0 +1,88 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: ramendemo-mysql + labels: + app: ramendemo +spec: + type: NodePort + ports: + - port: 3306 + nodePort: 30136 + selector: + app: ramendemo + tier: mysql +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: ramendemo-mysql-pv-claim + labels: + app: ramendemo +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ramendemo-mysql + labels: + app: ramendemo +spec: + selector: + matchLabels: + app: ramendemo + tier: mysql + strategy: + type: Recreate + template: + metadata: + labels: + app: ramendemo + tier: mysql + spec: + containers: + - image: mysql:5.6 + name: mysql + env: + - name: MYSQL_ROOT_PASSWORD + value: "redhat" + - name: MYSQL_DATABASE + value: "ramendemo" + - name: MYSQL_USER + value: "ramendemo" + - name: MYSQL_PASSWORD + value: "ramendemo" + ports: + - containerPort: 3306 + name: mysql + volumeMounts: + - name: mysql-persistent-storage + mountPath: /var/lib/mysql + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: ramendemo-mysql-pv-claim +--- +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + annotations: + openshift.io/host.generated: "true" + labels: + app: ramendemo + name: ramendemo-mysql +spec: +# host: ramendemo-mysql-testjc.apps.perf1.chris.ocs.ninja + port: + targetPort: 3306 + to: + kind: Service + name: ramendemo-mysql + weight: 100 + wildcardPolicy: None diff --git a/ramendemo/rbdloop-drpc.yaml b/ramendemo/rbdloop-drpc.yaml new file mode 100644 index 0000000..4d86808 --- /dev/null +++ b/ramendemo/rbdloop-drpc.yaml @@ -0,0 +1,17 @@ +apiVersion: ramendr.openshift.io/v1alpha1 +kind: DRPlacementControl +metadata: + labels: + appname: rbdloop + name: rbdloop-drpc + namespace: rbdloop-dashboard +spec: + drPolicyRef: + name: odr-policy-5m + placementRef: + kind: PlacementRule + name: rbdloop-placement + preferredCluster: cluster1 + pvcSelector: + matchLabels: + appname: rbdloop diff --git a/ramendemo/rbdloop-placementrule.yaml b/ramendemo/rbdloop-placementrule.yaml new file mode 100644 index 0000000..e484087 --- /dev/null +++ b/ramendemo/rbdloop-placementrule.yaml @@ -0,0 +1,13 @@ +apiVersion: apps.open-cluster-management.io/v1 +kind: PlacementRule +metadata: + labels: + appname: rbdloop + name: rbdloop-placement + namespace: rbdloop-dashboard +spec: + clusterConditions: + - status: "True" + type: ManagedClusterConditionAvailable + clusterReplicas: 1 + schedulerName: ramen diff --git a/ramendemo/rbdloop.yaml b/ramendemo/rbdloop.yaml new file mode 100644 index 0000000..f2b8fbe --- /dev/null +++ b/ramendemo/rbdloop.yaml @@ -0,0 +1,52 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: ramendemo + labels: + appname: rbdloop +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: ocs-storagecluster-ceph-rbdmirror +--- +apiVersion: v1 +kind: Pod +metadata: + name: batch-4k + labels: + appname: rbdloop +spec: + containers: + - name: batch-4k + image: quay.io/vcppds7878/busybox:rbdloop + imagePullPolicy: Always +# command: ["sh"] +# args: +# - '-c' +# - 'sleep 3600' + command: ["python3"] + args: + - '/tmp/runloop.py' + - '--size' + - '--server' + - '--port' + env: + - name: BLOCKSIZE + value: "4096" + - name: SQL_SERVER + value: "a1f3f174920324755951447a31448e16-795488745.us-east-2.elb.amazonaws.com" + - name: SQL_PORT + value: "3306" + volumeMounts: + - name: tmp-store + mountPath: /mnt/test + volumes: + - name: tmp-store + persistentVolumeClaim: + claimName: ramendemo + readOnly: false + restartPolicy: Never diff --git a/ramendemo/runloop.py b/ramendemo/runloop.py new file mode 100755 index 0000000..2cea4f1 --- /dev/null +++ b/ramendemo/runloop.py @@ -0,0 +1,189 @@ +#!/usr/bin/python +import json,sys,os,time,io,pyodbc,shortuuid +from subprocess import Popen, PIPE +from optparse import OptionParser +from random import seed +from random import randint +from time import sleep +from datetime import datetime + +usage = "Usage: %prog -n jobname [-s sqlserver_address] [-f output_file]" +parser = OptionParser() +parser.add_option("-z", "--size", action="store_true",dest="blocksize",help="Block size to use for IOs",default=False) +parser.add_option("-s", "--server", action="store_true",dest="sqlserver",help="SQL server address is in SQL_SERVER environment variable",default=False) +parser.add_option("-p", "--port", action="store_true",dest="sqlport",help="SQL server port exposed through nodePort",default=False) +parser.add_option("-g", "--debug", action="store_true",dest="debugflag",help="Display debugging info",default=False) +parser.add_option("-f", "--file", action="store",dest="writetofile",help="Write output to file",default="/tmp/outfile") + +global writetofile +global sqlserveraddress +global sqlport +global blocksize +global lastuuid +global last1 +global last2 +global sqlurl +global isprimarycluster +global issecondarycluster + +(options, args) = parser.parse_args() + +writetofile = options.writetofile +sqlurl="" +sqlport = "" +lastuuid = "" +last1 = 0 +last2 = 0 +isprimarycluster = 0 +issecondarycluster = 0 + +if (options.blocksize == ""): + printf("%s\n", usage) + exit(1) + +blocksize = options.blocksize + +if (options.blocksize == True): + blocksize = os.getenv('BLOCKSIZE') + +if (options.sqlserver == True): + sqlserveraddress = os.getenv('SQL_SERVER') + +if (options.sqlport == True): + sqlport = os.getenv('SQL_PORT') + sqlserveraddress += ":" + sqlserveraddress += sqlport +# +# See if for automation we are overriding the yaml environment variable +# +sqlurl = os.getenv('SQL_URL', 'ramendemo') +if sqlurl != "": + print ("Overriding environment variable from URL content at "+sqlurl) + tmpval = os.popen("curl "+sqlurl+" 2>/dev/null").read() + if tmpval != "404: Not Found": + sqlserveraddress = tmpval.strip() + +print ("SQL Server Address = "+sqlserveraddress) + +db = os.getenv('DB', 'ramendemo') +user = os.getenv('USER', 'root') +password = os.getenv('PASS', 'redhat') +myname = os.getenv('MYNAME', 'UNKNOWN') + +conn = pyodbc.connect('Driver={MySQL ODBC 8.0 ANSI Driver};' + 'Server='+sqlserveraddress+';' + 'Database='+db+';' + 'uid='+user+';' + 'pwd='+password+';' + 'Trusted_Connection=yes;') + +conn.setdecoding(pyodbc.SQL_CHAR, encoding='utf-8') +conn.setdecoding(pyodbc.SQL_WCHAR, encoding='utf-8') +conn.setencoding(encoding='utf-8') + +cursor = conn.cursor() +#sqlcmd = ("DROP TABLE IF EXISTS ramendemo;") +#cursor.execute(sqlcmd) +# +# Create the table to track the data we write +# +sqlcmd = ("CREATE TABLE IF NOT EXISTS ramendemo (id serial PRIMARY KEY, submit_time DATETIME, complete_time DATETIME, isprimary INT, issecondary INT, fsid VARCHAR(64), stampdate VARCHAR(8), stamptime VARCHAR(6), iosize VARCHAR(16));") +cursor.execute(sqlcmd) +conn.commit() +# +# Create the table to track the current fsid and the previous last stamp writtem +# +sqlcmd = ("CREATE TABLE IF NOT EXISTS ramenfsid (id serial PRIMARY KEY, submit_time DATETIME, cluster1 INT, cluster2 INT, fsid VARCHAR(64), prevdate VARCHAR(8), prevtime VARCHAR(6), gap VARCHAR(12));") +cursor.execute(sqlcmd) +# +# Retrieve the last fsid that was running prior to a failover or failback +# +#sqlcmd = ("SELECT * FROM ramendemo.ramenfsid WHERE id=(SELECT MAX(id) FROM ramendemo.ramenfsid);") +sqlcmd = ("SELECT * FROM ramendemo.ramenfsid;") +records = cursor.execute(sqlcmd).fetchall() +newramendemofsid = len(records) +# +# Check if table is empty (we are the first occurence of the pod) +# +if newramendemofsid != 0: + print ("Table ramenfsid is NOT empty "+str(newramendemofsid)) + for r in records: + print(str(r.id)+" "+str(r.fsid)) + lastuuid = str(r.fsid) + last1 = int(r.cluster1) + last2 = int(r.cluster2) + print ("Saving "+str(lastuuid)+" for later C1="+str(last1)+" C2="+str(last2)) +else: + print ("Table ramenfsid is empty") +# +# Generate uuid for this new occurence +# +tmyuuid = os.popen("cat /proc/sys/kernel/random/uuid").read() +myuuid = tmyuuid.strip() +# +# Now check on disk what is the latest file we have from previous run time +# +tprevious = os.popen("ls -1 -t /mnt/test/file_"+lastuuid+"_* | head -1").read() +lastprevious = tprevious.strip() +print ("Current="+myuuid+" Previous run last file="+lastprevious) +# +# Insert one more row for current fsid +# +if newramendemofsid == 0: + isprimarycluster = 1 + issecondarycluster = 0 + sqlcmd = ("INSERT INTO ramendemo.ramenfsid (id, submit_time, cluster1, cluster2, fsid, prevdate, prevtime, gap) VALUES (?, NOW(), 1, 0, ?, ?, ?, ?);") + values = [ str((int(newramendemofsid) + 1)), str(myuuid), "", "", "None" ] +else: +# +# If last1 is non zero we failed over from Cluster1 to Cluster2 +# + if last1 == 1: + isprimarycluster = 0 + issecondarycluster = 1 + sqlcmd = ("INSERT INTO ramendemo.ramenfsid (id, submit_time, cluster1, cluster2, fsid, prevdate, prevtime, gap) VALUES (?, NOW(), 0, 1, ?, ?, ?, ?);") + else: + isprimarycluster = 1 + issecondarycluster = 0 + sqlcmd = ("INSERT INTO ramendemo.ramenfsid (id, submit_time, cluster1, cluster2, fsid, prevdate, prevtime, gap) VALUES (?, NOW(), 1, 0, ?, ?, ?, ?);") + workstring=lastprevious[-15:-7]+" "+lastprevious[-6:] + previousrun=datetime.strptime(workstring, "%Y%m%d %H%M%S") + currentrun=datetime.now() + gap=currentrun - previousrun + seconds = gap.total_seconds() + hours = seconds // 3600 + minutes = (seconds % 3600) // 60 + seconds = seconds % 60 + formattedgap="{0:02.0f}:{1:02.0f}:{2:02.0f}".format(hours, minutes, seconds) + + values = [ str((int(newramendemofsid) + 1)), str(myuuid), lastprevious[-15:-7], lastprevious[-6:], formattedgap ] +cursor.execute(sqlcmd, values) +# +# Then loop until the pod if failed over or failed back +# +while True: + tdatestamp = os.popen("date +%Y%m%d_%H%M%S").read() + tfilenumber = os.popen("ls /mnt/test/file_* | wc -l").read() + + datestamp = tdatestamp.strip() + filenumber = tfilenumber.strip() + + sqlcmd = ("INSERT INTO ramendemo.ramendemo (submit_time, isprimary, issecondary, fsid, stampdate, stamptime, iosize) VALUES (NOW(), ?, ?, ?, ?, ?, ?);") + values = [ str(isprimarycluster), str(issecondarycluster), str(myuuid), datestamp[0:8], datestamp[-6:], str(blocksize) ] + cursor.execute(sqlcmd, values) + + conn.commit() + + #cmd = "while true; do dd if=/dev/urandom of=/mnt/test/file_"+myuuid+"_"+datestamp+" bs="+blocksize+" count=1 oflag=direct &>/dev/null; echo "+str(int(filenumber) + 1)+","+blocksize+",/mnt/test/file_+"+myuuid+"_"+datestamp+" | tee -a "+writetofile+"; done" + + cmd = "dd if=/dev/urandom of=/mnt/test/file_"+myuuid+"_"+datestamp+" bs="+blocksize+" count=1 oflag=direct &>/dev/null; echo "+str(int(filenumber) + 1)+","+blocksize+",/mnt/test/file_+"+myuuid+"_"+datestamp+" | tee -a "+writetofile + + outputline = os.popen(cmd).read().strip() + #print (outputline) + +# sqlcmd = ("UPDATE ramendemo SET complete_time = NOW() WHERE ID = ?;") +# values = [ int(filenumber) + 1 ] +# cursor.execute(sqlcmd, values) + + conn.commit() + diff --git a/ramendemoapp/Dockerfile b/ramendemoapp/Dockerfile new file mode 100644 index 0000000..fc3855a --- /dev/null +++ b/ramendemoapp/Dockerfile @@ -0,0 +1,22 @@ +FROM registry.access.redhat.com/ubi8/python-38 +#FROM docker.io/centos:centos7 +ENV ENABLE_MICROPIPENV="1" \ + UPGRADE_PIP_TO_LATEST="1" +USER root + +RUN yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -y +RUN wget https://repo.mysql.com/mysql80-community-release-el8-1.noarch.rpm +RUN yum localinstall mysql80-community-release-el8-1.noarch.rpm -y +RUN yum install python3-mysqlclient mysql-connector-odbc gcc unixODBC-devel -y + +RUN python -m pip install --upgrade pip +RUN pip3 install shortuuid mysqlclient mysql-connector mysql-connector-python pyodbc + +#RUN yum install gcc unixODBC-devel python3-mysqlclient mysql-connector-odbc -y +#RUN python -m pip install --upgrade pip +#RUN pip3 install shortuuid mysqlclient mysql-connector mysql-connector-python pyodbc + +WORKDIR /tmp +ADD *.py . + +ENTRYPOINT [ "python3", "/tmp/runloop.py --size --server" ] diff --git a/ramendemoapp/kustomization.yaml b/ramendemoapp/kustomization.yaml new file mode 100644 index 0000000..a009d43 --- /dev/null +++ b/ramendemoapp/kustomization.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- rbdloop.yaml diff --git a/ramendemoapp/rbdloop.yaml b/ramendemoapp/rbdloop.yaml new file mode 100644 index 0000000..c975e2d --- /dev/null +++ b/ramendemoapp/rbdloop.yaml @@ -0,0 +1,50 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: ramendemo + labels: + appname: rbdloop +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: ocs-storagecluster-ceph-rbdmirror +--- +apiVersion: v1 +kind: Pod +metadata: + name: batch-4k + labels: + appname: batch-4k +spec: + containers: + - name: batch-4k + image: quay.io/vcppds7878/busybox:rbdloop + imagePullPolicy: Always + command: ["python3"] + args: + - '/tmp/runloop.py' + - '--size' + - '--server' + - '--port' + env: + - name: BLOCKSIZE + value: "4K" + - name: SQL_SERVER + value: "ramendemo-mysql-testjc.apps.perf1.chris.ocs.ninja" + - name: SQL_PORT + value: "30036" + - name: SQL_URL + value: "https://gist.githubusercontent.com/jeanchlopez/0cdd2a30562b735c3bb384bd734282b7/raw/c5d79fbe37fb6e243908a88bee4e66f7d692003e/sqlserver.url" + volumeMounts: + - name: tmp-store + mountPath: /mnt/test + volumes: + - name: tmp-store + persistentVolumeClaim: + claimName: ramendemo + readOnly: false + restartPolicy: Never diff --git a/ramendemoapp/runloop.py b/ramendemoapp/runloop.py new file mode 100755 index 0000000..a623221 --- /dev/null +++ b/ramendemoapp/runloop.py @@ -0,0 +1,202 @@ +#!/usr/bin/python +import json,sys,os,time,io,pyodbc,shortuuid +from subprocess import Popen, PIPE +from optparse import OptionParser +from random import seed +from random import randint +from time import sleep +from datetime import datetime + +usage = "Usage: %prog -n jobname [-s sqlserver_address] [-f output_file]" +parser = OptionParser() +parser.add_option("-z", "--size", action="store_true",dest="blocksize",help="Block size to use for IOs",default=False) +parser.add_option("-s", "--server", action="store_true",dest="sqlserver",help="SQL server address is in SQL_SERVER environment variable",default=False) +parser.add_option("-p", "--port", action="store_true",dest="sqlport",help="SQL server port exposed through nodePort",default=False) +parser.add_option("-g", "--debug", action="store_true",dest="debugflag",help="Display debugging info",default=False) +parser.add_option("-f", "--file", action="store",dest="writetofile",help="Write output to file",default="/tmp/outfile") + +global writetofile +global sqlserveraddress +global sqlport +global blocksize +global lastuuid +global last1 +global last2 +global sqlurl +global isprimarycluster +global issecondarycluster +global files + +(options, args) = parser.parse_args() + +writetofile = options.writetofile +sqlurl="" +sqlport = "" +lastuuid = "" +last1 = 0 +last2 = 0 +isprimarycluster = 0 +issecondarycluster = 0 +files = [] + +if (options.blocksize == ""): + printf("%s\n", usage) + exit(1) + +blocksize = options.blocksize + +if (options.blocksize == True): + blocksize = os.getenv('BLOCKSIZE') + +if (options.sqlserver == True): + sqlserveraddress = os.getenv('SQL_SERVER') + +if (options.sqlport == True): + sqlport = os.getenv('SQL_PORT') + sqlserveraddress += ":" + sqlserveraddress += sqlport +# +# See if for automation we are overriding the yaml environment variable +# +sqlurl = os.getenv('SQL_URL', 'ramendemo') +if sqlurl != "": + print ("Overriding environment variable from URL content at "+sqlurl) + tmpval = os.popen("curl "+sqlurl+" 2>/dev/null").read() + if tmpval != "404: Not Found": + sqlserveraddress = tmpval.strip() + +print ("SQL Server Address = "+sqlserveraddress) + +db = os.getenv('DB', 'ramendemo') +user = os.getenv('USER', 'root') +password = os.getenv('PASS', 'redhat') +myname = os.getenv('MYNAME', 'UNKNOWN') + +conn = pyodbc.connect('Driver={MySQL ODBC 8.0 ANSI Driver};' + 'Server='+sqlserveraddress+';' + 'Database='+db+';' + 'uid='+user+';' + 'pwd='+password+';' + 'Trusted_Connection=yes;') + +conn.setdecoding(pyodbc.SQL_CHAR, encoding='utf-8') +conn.setdecoding(pyodbc.SQL_WCHAR, encoding='utf-8') +conn.setencoding(encoding='utf-8') + +cursor = conn.cursor() +#sqlcmd = ("DROP TABLE IF EXISTS ramendemo;") +#cursor.execute(sqlcmd) +# +# Create the table to track the data we write +# +sqlcmd = ("CREATE TABLE IF NOT EXISTS ramendemo (id serial PRIMARY KEY, submit_time DATETIME, complete_time DATETIME, isprimary INT, issecondary INT, fsid VARCHAR(64), stampdate VARCHAR(8), stamptime VARCHAR(6), iosize VARCHAR(16));") +cursor.execute(sqlcmd) +conn.commit() +# +# Create the table to track the current fsid and the previous last stamp writtem +# +sqlcmd = ("CREATE TABLE IF NOT EXISTS ramenfsid (id serial PRIMARY KEY, submit_time DATETIME, cluster1 INT, cluster2 INT, fsid VARCHAR(64), prevdate VARCHAR(8), prevtime VARCHAR(6), gap VARCHAR(12));") +cursor.execute(sqlcmd) +# +# Retrieve the last fsid that was running prior to a failover or failback +# +sqlcmd = ("SELECT * FROM ramendemo.ramenfsid;") +records = cursor.execute(sqlcmd).fetchall() +newramendemofsid = len(records) +# +# Check if table is empty (we are the first occurence of the pod) +# +if newramendemofsid != 0: + print ("Table ramenfsid is NOT empty "+str(newramendemofsid)) + for r in records: + print(str(r.id)+" "+str(r.fsid)) + lastuuid = str(r.fsid) + last1 = int(r.cluster1) + last2 = int(r.cluster2) + print ("Saving "+str(lastuuid)+" for later C1="+str(last1)+" C2="+str(last2)) +else: + print ("Table ramenfsid is empty") +# +# Generate uuid for this new occurence +# +tmyuuid = os.popen("cat /proc/sys/kernel/random/uuid").read() +myuuid = tmyuuid.strip() +# +# Now check on disk what is the latest file we have from previous run time +# +files = os.listdir("/mnt/test") # Get list of files in the target directory +os.chdir("/mnt/test") # Change current directory to access time stamps for file +files.sort(key=os.path.getmtime) # Sort file according to last modification time +lastprevious = files[len(files) - 1] # Last file in array has the kast time stamp as it is the last modified +# +# Leave this here for troubleshooting and debugging +# +print ("Current="+myuuid+" Previous run last file="+lastprevious) +# +# Insert one more row for current fsid tracking +# +# +# If array is zero in size this is the first deployment for the application +# +if newramendemofsid == 0: + isprimarycluster = 1 + issecondarycluster = 0 + sqlcmd = ("INSERT INTO ramendemo.ramenfsid (id, submit_time, cluster1, cluster2, fsid, prevdate, prevtime, gap) VALUES (?, NOW(), 1, 0, ?, ?, ?, ?);") + values = [ str((int(newramendemofsid) + 1)), str(myuuid), "", "", "None" ] +else: +# +# If last1 is non zero we failed over from Cluster1 to Cluster2 +# + if last1 == 1: + isprimarycluster = 0 + issecondarycluster = 1 + sqlcmd = ("INSERT INTO ramendemo.ramenfsid (id, submit_time, cluster1, cluster2, fsid, prevdate, prevtime, gap) VALUES (?, NOW(), 0, 1, ?, ?, ?, ?);") + else: + isprimarycluster = 1 + issecondarycluster = 0 + sqlcmd = ("INSERT INTO ramendemo.ramenfsid (id, submit_time, cluster1, cluster2, fsid, prevdate, prevtime, gap) VALUES (?, NOW(), 1, 0, ?, ?, ?, ?);") +# +# Calculate the time difference between now and the time stamp of the last file written to by previous deployment. +# We get this file eventually because of replication over the Ramen setup +# + workstring=lastprevious[-15:-7]+" "+lastprevious[-6:] + print ("Workstring to recompose date and time pickup = "+workstring) + previousrun=datetime.strptime(workstring, "%Y%m%d %H%M%S") + currentrun=datetime.now() + gap=currentrun - previousrun + seconds = gap.total_seconds() + hours = seconds // 3600 + minutes = (seconds % 3600) // 60 + seconds = seconds % 60 + formattedgap="{0:02.0f}:{1:02.0f}:{2:02.0f}".format(hours, minutes, seconds) + + values = [ str((int(newramendemofsid) + 1)), str(myuuid), lastprevious[-15:-7], lastprevious[-6:], formattedgap ] +cursor.execute(sqlcmd, values) +# +# Then loop until the pod if failed over or failed back +# +while True: + tdatestamp = os.popen("date +%Y%m%d_%H%M%S").read() + filenumber = len(files) + + datestamp = tdatestamp.strip() + + sqlcmd = ("INSERT INTO ramendemo.ramendemo (submit_time, isprimary, issecondary, fsid, stampdate, stamptime, iosize) VALUES (NOW(), ?, ?, ?, ?, ?, ?);") + values = [ str(isprimarycluster), str(issecondarycluster), str(myuuid), datestamp[0:8], datestamp[-6:], str(blocksize) ] + cursor.execute(sqlcmd, values) + + conn.commit() + + cmd = "dd if=/dev/urandom of=/mnt/test/file_"+myuuid+"_"+datestamp+" bs="+blocksize+" count=1 oflag=direct &>/dev/null; echo "+str(int(filenumber) + 1)+","+blocksize+",/mnt/test/file_+"+myuuid+"_"+datestamp+" | tee -a "+writetofile + + outputline = os.popen(cmd).read().strip() +# +# This can be placed back in for troubleshotting or to view in the pod log (via the oc logs command) +# + #print (outputline) + +# +# Commit whatever we have left in the pipe +# + conn.commit() + diff --git a/rbdloop-odf/kustomization.yaml b/rbdloop-odf/kustomization.yaml new file mode 100644 index 0000000..963c2ab --- /dev/null +++ b/rbdloop-odf/kustomization.yaml @@ -0,0 +1,4 @@ +resources: +- pod-cephrbd-loop-stamp-4k.yaml +- pod-cephrbd-loop-stamp-4m.yaml + diff --git a/rbdloop-odf/pod-cephrbd-loop-stamp-4k.yaml b/rbdloop-odf/pod-cephrbd-loop-stamp-4k.yaml new file mode 100644 index 0000000..b443b90 --- /dev/null +++ b/rbdloop-odf/pod-cephrbd-loop-stamp-4k.yaml @@ -0,0 +1,35 @@ +--- +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: pvc-cephrbd-4k + labels: + appname: rbdloop +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Gi + storageClassName: ocs-storagecluster-ceph-rbd +--- +apiVersion: v1 +kind: Pod +metadata: + name: batch-4k + labels: + app: batch-4k +spec: + containers: + - name: batch-4k + image: quay.io/vcppds7878/busybox:latest + imagePullPolicy: IfNotPresent + command: ['sh', '-c', 'export myuniqueid=$(cat /proc/sys/kernel/random/uuid);while true; do echo "Creating time-stamped file 4KB urandom based"; export mystamp=$(echo "${myuniqueid}_$(date +%Y%m%d_%H%M%S)"); dd if=/dev/urandom of=/mnt/test/file_${mystamp} bs=4K count=1 oflag=direct &>/dev/null; echo "------------"; echo "Listing last 20 time-stamped archive"; ls -l /mnt/test/file_* | tail -20; echo "------------"; echo "Total number of time-stamped files is $(ls /mnt/test/file_* | wc -l)"; echo "==================================================="; done'] + volumeMounts: + - name: tmp-store + mountPath: /mnt/test + volumes: + - name: tmp-store + persistentVolumeClaim: + claimName: pvc-cephrbd-4k + readOnly: false diff --git a/rbdloop-odf/pod-cephrbd-loop-stamp-4m.yaml b/rbdloop-odf/pod-cephrbd-loop-stamp-4m.yaml new file mode 100644 index 0000000..98bbbdb --- /dev/null +++ b/rbdloop-odf/pod-cephrbd-loop-stamp-4m.yaml @@ -0,0 +1,35 @@ +--- +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: pvc-cephrbd-4m + labels: + appname: rbdloop +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Gi + storageClassName: ocs-storagecluster-ceph-rbd +--- +apiVersion: v1 +kind: Pod +metadata: + name: batch-4m + labels: + app: batch-4m +spec: + containers: + - name: batch-4m + image: quay.io/vcppds7878/busybox:latest + imagePullPolicy: IfNotPresent + command: ['sh', '-c', 'export myuniqueid=$(cat /proc/sys/kernel/random/uuid);while true; do echo "Creating time-stamped file 4MB urandom based"; export mystamp=$(echo "${myuniqueid}_$(date +%Y%m%d_%H%M%S)"); dd if=/dev/urandom of=/mnt/test/file_${mystamp} oflag=direct bs=4M count=1 &>/dev/null; echo "------------"; echo "Listing last 20 time-stamped archive"; ls -l /mnt/test/file_* | tail -20; echo "------------"; echo "Total number of time-stamped files is $(ls /mnt/test/file_* | wc -l)"; echo "==================================================="; done'] + volumeMounts: + - name: tmp-store + mountPath: /mnt/test + volumes: + - name: tmp-store + persistentVolumeClaim: + claimName: pvc-cephrbd-4m + readOnly: false diff --git a/subscriptions/channel/channel.yaml b/subscriptions/channel/channel.yaml index 21e9c3f..f8c12c8 100644 --- a/subscriptions/channel/channel.yaml +++ b/subscriptions/channel/channel.yaml @@ -6,4 +6,4 @@ metadata: namespace: application-samples spec: type: GitHub - pathname: https://github.com/open-cluster-management/application-samples.git + pathname: https://github.com/jeanchlopez/application-samples.git diff --git a/subscriptions/helloworld/channel.yaml b/subscriptions/helloworld/channel.yaml index 10e9a35..60c515a 100755 --- a/subscriptions/helloworld/channel.yaml +++ b/subscriptions/helloworld/channel.yaml @@ -5,4 +5,4 @@ metadata: namespace: helloworld-ch spec: type: GitHub - pathname: https://github.com/open-cluster-management/application-samples.git + pathname: https://github.com/jeanchlopez/application-samples.git diff --git a/subscriptions/helloworld/subscription.yaml b/subscriptions/helloworld/subscription.yaml index dc7a2f6..548d08c 100755 --- a/subscriptions/helloworld/subscription.yaml +++ b/subscriptions/helloworld/subscription.yaml @@ -11,7 +11,8 @@ metadata: spec: channel: helloworld-ch/helloworld-channel placement: - placementRef: - name: helloworld-app-placement - kind: PlacementRule - group: apps.open-cluster-management.io + local: true +# placementRef: +# name: helloworld-app-placement +# kind: PlacementRule +# group: apps.open-cluster-management.io diff --git a/subscriptions/keycloack-odf/application.yaml b/subscriptions/keycloack-odf/application.yaml new file mode 100755 index 0000000..104f36b --- /dev/null +++ b/subscriptions/keycloack-odf/application.yaml @@ -0,0 +1,15 @@ +apiVersion: app.k8s.io/v1beta1 +kind: Application +metadata: + name: keycloak-odf-app + namespace: keycloak-odf +spec: + componentKinds: + - group: apps.open-cluster-management.io + kind: Subscription + selector: + matchExpressions: + - key: app + operator: In + values: + - keycloak-odf-app diff --git a/subscriptions/keycloack-odf/channel.yaml b/subscriptions/keycloack-odf/channel.yaml new file mode 100755 index 0000000..e9b33f0 --- /dev/null +++ b/subscriptions/keycloack-odf/channel.yaml @@ -0,0 +1,8 @@ +apiVersion: apps.open-cluster-management.io/v1 +kind: Channel +metadata: + name: keycloak-odf-channel + namespace: keycloak-odf-ch +spec: + type: GitHub + pathname: https://github.com/jeanchlopez/application-samples.git diff --git a/subscriptions/keycloack-odf/kustomization.yaml b/subscriptions/keycloack-odf/kustomization.yaml new file mode 100644 index 0000000..6741f81 --- /dev/null +++ b/subscriptions/keycloack-odf/kustomization.yaml @@ -0,0 +1,6 @@ +resources: +- namespace.yaml +- channel.yaml +- placement.yaml +- subscription.yaml +- application.yaml diff --git a/subscriptions/keycloack-odf/namespace.yaml b/subscriptions/keycloack-odf/namespace.yaml new file mode 100644 index 0000000..6d11d0a --- /dev/null +++ b/subscriptions/keycloack-odf/namespace.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: keycloak-odf-ch +--- +apiVersion: v1 +kind: Namespace +metadata: + name: keycloak-odf diff --git a/subscriptions/keycloack-odf/placement.yaml b/subscriptions/keycloack-odf/placement.yaml new file mode 100755 index 0000000..a55371f --- /dev/null +++ b/subscriptions/keycloack-odf/placement.yaml @@ -0,0 +1,12 @@ +apiVersion: apps.open-cluster-management.io/v1 +kind: PlacementRule +metadata: + name: keycloak-odf-app-placement + namespace: keycloak-odf + labels: + app: keycloak-odf-app +spec: + clusterReplicas: 1 + clusterSelector: + matchLabels: + usage: development diff --git a/subscriptions/keycloack-odf/subscription.yaml b/subscriptions/keycloack-odf/subscription.yaml new file mode 100755 index 0000000..af2465d --- /dev/null +++ b/subscriptions/keycloack-odf/subscription.yaml @@ -0,0 +1,18 @@ +apiVersion: apps.open-cluster-management.io/v1 +kind: Subscription +metadata: + name: keycloak-odf-app-subscription + namespace: keycloak-odf + labels: + app: keycloak-odf-app + annotations: + apps.open-cluster-management.io/github-path: keycloak-odf + apps.open-cluster-management.io/github-branch: keycload-over-odf +spec: + channel: keycloak-odf-ch/keycloak-odf-channel + placement: + local: true +# placementRef: +# name: helloworld-app-placement +# kind: PlacementRule +# group: apps.open-cluster-management.io