Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions stackstorm-mariadb/actions/query_mariadb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env python3

import pymysql
from tabulate import tabulate
from st2common.runners.base_action import Action

class QueryMariaDB(Action):
def run(self, user, password, host, port, database, sql):
# Try host, then fallback
fallback_hosts = [host, "172.20.10.3"] if host != "172.20.10.3" else [host]

conn = None
error_messages = []
connected_host = None

for h in fallback_hosts:
try:
conn = pymysql.connect(
host=h,
user=user,
password=password,
database=database,
port=port
)
connected_host = h # capture the successful one
break
except Exception as e:
error_messages.append(f"{h}: {e}")

if conn is None:
all_errors = "\n".join(error_messages)
raise Exception(f"❌ Failed to connect to all MariaDB hosts:\n{all_errors}")

# Run SQL
cursor = conn.cursor()
cursor.execute(sql)
cols = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
conn.close()

table = tabulate(rows, headers=cols, tablefmt="github")
return table
36 changes: 36 additions & 0 deletions stackstorm-mariadb/actions/query_mariadb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
name: query_mariadb
runner_type: python-script
description: Run a SQL query against MariaDB and return results formatted for Slack.
entry_point: query_mariadb.py
enabled: true
parameters:
sql:
type: string
required: true
description: The SQL query to execute.

user:
type: string
default: hruser
description: MariaDB username

password:
type: string
default: xxxxxxxxx
description: MariaDB password

host:
type: string
default: 192.168.18.71
description: Primary MariaDB host (will fallback to 172.20.10.3 if fails)

port:
type: integer
default: 3306
description: MariaDB port

database:
type: string
default: hrdb
description: MariaDB database name
64 changes: 64 additions & 0 deletions stackstorm-mariadb/actions/query_mariadb_export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env python3

import os
import uuid
import pymysql
import pandas as pd
from openpyxl.utils import get_column_letter
from openpyxl.styles import Font
from st2common.runners.base_action import Action
import requests

class QueryMariaDBExport(Action):
def run(self, user, password, host, port, database, sql, slack_token, slack_channel):
conn = pymysql.connect(
host=host,
user=user,
password=password,
database=database,
port=port
)
cursor = conn.cursor()
cursor.execute(sql)
cols = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
conn.close()

# Create DataFrame
df = pd.DataFrame(rows, columns=cols)

# Save to Excel
file_id = str(uuid.uuid4())
filename = f"query_result_{file_id}.xlsx"
filepath = f"/tmp/{filename}"
df.to_excel(filepath, index=False)

# Excel formatting
from openpyxl import load_workbook
wb = load_workbook(filepath)
ws = wb.active
for cell in ws[1]:
cell.font = Font(bold=True)
for col in ws.columns:
max_len = max(len(str(cell.value)) if cell.value else 0 for cell in col)
ws.column_dimensions[get_column_letter(col[0].column)].width = max_len + 2
wb.save(filepath)

# Upload to Slack
try:
with open(filepath, 'rb') as f:
response = requests.post(
"https://slack.com/api/files.upload",
headers={"Authorization": f"Bearer {slack_token}"},
data={"channels": slack_channel},
files={"file": (filename, f)},
)
if not response.ok or not response.json().get("ok"):
return f"\u274c Slack upload failed: {response.text}"
finally:
try:
os.remove(filepath)
except Exception as e:
return f"\u2705 Upload OK, cleanup failed: {str(e)}"

return "\u2705 File uploaded to Slack and cleaned up."
47 changes: 47 additions & 0 deletions stackstorm-mariadb/actions/query_mariadb_export.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
name: query_mariadb_export
pack: mariadb
runner_type: python-script
entry_point: query_mariadb_export.py
description: |
Export MariaDB SQL query results to Excel, upload to Slack, and clean up the file.

parameters:
sql:
type: string
required: true
description: "The SQL query to execute."

slack_token:
type: string
required: true
default: "{{st2kv.system.slack_bot_token}}"
secret: false
description: "Slack bot token from encrypted st2kv"

slack_channel:
type: string
required: true
default: "#dbshield-ops-infra-automation-hub"
description: "Slack channel name or ID"

user:
type: string
default: "hruser"

password:
type: string
default: "xxxxxxxx#"

host:
type: string
default: "192.168.18.71"
#default: "172.20.10.3"
#default: ["192.168.18.71", "172.20.10.3"]
port:
type: integer
default: 3306

database:
type: string
default: "hrdb"
19 changes: 19 additions & 0 deletions stackstorm-mariadb/aliases/1
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
name: "query_mariadb_alias"
pack: mariadb
action_ref: mariadb.query_mariadb
description: |
Execute SQL on MariaDB and return results as a table in Slack.

✅ Usage Examples:
• !mariadb query 'SELECT * FROM employees LIMIT 5'
• !mariadb query "SELECT * FROM departments"
• !mariadb query "SELECT * FROM employees WHERE first_name = 'Steven'"
• !mariadb query "SELECT * FROM employees WHERE last_name LIKE '%King%'"

formats:
- name: "mariadb.query"
display: "mariadb query <sql>"
description: "Run a MariaDB SQL query via Slack using natural syntax. Handles quotes automatically."
representation:
- "mariadb query {{sql=.+}}"
19 changes: 19 additions & 0 deletions stackstorm-mariadb/aliases/query_mariadb_alias.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
name: "query_mariadb_alias"
pack: mariadb
action_ref: mariadb.query_mariadb
description: |
Execute SQL on MariaDB and return results as a table in Slack.

✅ Usage Examples:
• !mariadb query 'SELECT * FROM employees LIMIT 5'
• !mariadb query "SELECT * FROM departments"
• !mariadb query "SELECT * FROM employees WHERE first_name = 'Steven'"
• !mariadb query "SELECT * FROM employees WHERE last_name LIKE '%King%'"

formats:
- name: "mariadb.query"
display: "mariadb query <sql>"
description: "Run a MariaDB SQL query via Slack using natural syntax. Handles quotes automatically."
representation:
- "mariadb query {{sql=.+}}"
19 changes: 19 additions & 0 deletions stackstorm-mariadb/aliases/query_mariadb_export_alias.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
name: "query_mariadb_export_alias"
pack: mariadb
action_ref: mariadb.query_mariadb_export
description: |
Export MariaDB SQL results to an Excel file and send to Slack securely.

✅ Usage Examples:
• !mariadb export "SELECT * FROM employees"
• !mariadb export "SELECT * FROM departments WHERE department_name = 'IT'"
• !mariadb export "SELECT * FROM employees WHERE last_name LIKE '%King%'"
• !mariadb export "SELECT * FROM employees WHERE first_name = 'Steven'"

formats:
- name: "mariadb.export"
display: "mariadb export <sql>"
description: "Run a MariaDB SQL query and receive Excel via Slack"
representation:
- "mariadb export {{sql=.+}}"
5 changes: 5 additions & 0 deletions stackstorm-mariadb/pack.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: mariadb
description: Provides StackStorm actions and chatops aliases for executing mariadb database sql queries, returning results in formatted Slack table views, and enabling Excel file downloads for MariaDB query results.
version: 1.0.0
author: Karunya
email: kaarunyapooven@gmail.com
19 changes: 19 additions & 0 deletions stackstorm-oracle/actions/query_oracle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env python3

import cx_Oracle
from tabulate import tabulate
from st2common.runners.base_action import Action

class QueryOracle(Action):
def run(self, user, password, host, port, service, sql):
dsn = cx_Oracle.makedsn(host, port, service_name=service)
conn = cx_Oracle.connect(user, password, dsn=dsn)
cursor = conn.cursor()
cursor.execute(sql)
cols = [d[0] for d in cursor.description]
rows = cursor.fetchall()
conn.close()

# Format as a GitHub‑style table for Slack
table = tabulate(rows, headers=cols, tablefmt="github")
return table
34 changes: 34 additions & 0 deletions stackstorm-oracle/actions/query_oracle.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
name: query_oracle
pack: oracle
runner_type: python-script
description: Run a specified Oracle SQL against the database.
entry_point: query_oracle.py
parameters:
sql:
type: string
required: true
description: "The SQL query to execute."

user:
type: string
default: "HRUSER"

password:
type: string
# fetched from datastore or st2kv
#default: "{{st2kv.system.oracle_hr_password}}"
default: "xxxxxxxxx"

host:
type: string
default: "172.16.230.130"

port:
type: integer
default: 1521

service:
type: string
#default: "ORCLCDB"
default: "ORCLPDB1"
59 changes: 59 additions & 0 deletions stackstorm-oracle/actions/query_oracle_export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env python3

import os
import uuid
import cx_Oracle
import pandas as pd
from openpyxl.utils import get_column_letter
from openpyxl.styles import Font
from st2common.runners.base_action import Action
import requests

class QueryOracleExport(Action):
def run(self, user, password, host, port, service, sql, slack_token, slack_channel):
dsn = cx_Oracle.makedsn(host, port, service_name=service)
conn = cx_Oracle.connect(user, password, dsn=dsn)
cursor = conn.cursor()
cursor.execute(sql)
cols = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
conn.close()

# Create DataFrame manually (no warning)
df = pd.DataFrame(rows, columns=cols)

# Save to Excel
file_id = str(uuid.uuid4())
filename = f"query_result_{file_id}.xlsx"
filepath = f"/tmp/{filename}"
df.to_excel(filepath, index=False)

# Excel formatting
from openpyxl import load_workbook
wb = load_workbook(filepath)
ws = wb.active
for cell in ws[1]:
cell.font = Font(bold=True)
for col in ws.columns:
max_len = max(len(str(cell.value)) if cell.value else 0 for cell in col)
ws.column_dimensions[get_column_letter(col[0].column)].width = max_len + 2
wb.save(filepath)

# Upload to Slack
try:
with open(filepath, 'rb') as f:
response = requests.post(
"https://slack.com/api/files.upload",
headers={"Authorization": f"Bearer {slack_token}"},
data={"channels": slack_channel},
files={"file": (filename, f)},
)
if not response.ok or not response.json().get("ok"):
return f"❌ Slack upload failed: {response.text}"
finally:
try:
os.remove(filepath)
except Exception as e:
return f"✅ Upload OK, cleanup failed: {str(e)}"

return "✅ File uploaded to Slack and cleaned up."
Loading
Loading