Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

json 2 csv script for cluster-sizing #23

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# kubecost-utilities

Various utilities for more easily administering/maintaining/supporting a Kubecost install.

# ETL-BACKUP
## ETL-BACKUP
Instructions to use the [ETL Backup Scripts](./etl-backup/README.md). Use the tools by switching to `etl-backup` folder and uset he scripts there.

## API-SCRIPTS

[nodeGroup-json-2-csv.py](./api-scripts/nodeGroup-json-2-csv.py) is a script that converts a Kubecost nodeGroup JSON file to a CSV file.

Usage: `python3 nodeGroup-json-2-csv.py <.json file or url>`

When passing a url, the output is printed to stdout in csv format.

When passing a file, a csv file is created in the current working directory with .csv appended to the filename.
105 changes: 105 additions & 0 deletions api-scripts/nodeGroup-json-2-csv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# usage: python3 nodeGroup-json-2-csv.py <.json file or url>
# when passing a url, the output is printed to stdout in csv format
# when passing a file, a csv file is created in the current working directory with .csv appended to the filename

import json
import csv
import sys

def flatten_data(json_data):
flattened = []
data = json_data.get('data', {})
for cluster, node_groups in data.items():
for node_group, details in node_groups.items():
# print(cluster,"/",node_group,details.get('warning', '').replace('\n', '').replace('\t', ''))
if details.get('recommendation', {}) is None:
row = {
'Cluster': cluster,
'NodeGroup': node_group,
'MonthlySavings': '',
'CurrentCount': details.get('current', {}).get('count', ''),
'CurrentNodeType': details.get('current', {}).get('name', ''),
'CurrentMonthlyRate': details.get('current', {}).get('monthlyRate', ''),
'CurrentTotalVCPUs': details.get('current', {}).get('totalVCPUs', ''),
'CurrentTotalRAMGiB': details.get('current', {}).get('totalRAMGiB', ''),
'CurrentVCPUUtilization': details.get('current', {}).get('vCPUUtilization', ''),
'CurrentRAMGiBUtilization': details.get('current', {}).get('RAMGiBUtilization', ''),
'RecommendedCount': '',
'RecommendedNodeType': details.get('warning', '').replace('\n', '').replace('\t', ''),
'RecommendedMonthlyRate': '',
'RecommendedTotalVCPUs': '',
'RecommendedTotalRAMGiB': '',
'RecommendedVCPUUtilization': '',
'RecommendedRAMGiBUtilization': ''
}
else:
row = {
'Cluster': cluster,
'NodeGroup': node_group,
'MonthlySavings': details.get('recommendation', {}).get('monthlyRate', '') - details.get('current', {}).get('monthlyRate', ''),
'CurrentCount': details.get('current', {}).get('count', ''),
'CurrentNodeType': details.get('current', {}).get('name', ''),
'CurrentMonthlyRate': details.get('current', {}).get('monthlyRate', ''),
'CurrentTotalVCPUs': details.get('current', {}).get('totalVCPUs', ''),
'CurrentTotalRAMGiB': details.get('current', {}).get('totalRAMGiB', ''),
'CurrentVCPUUtilization': details.get('current', {}).get('vCPUUtilization', ''),
'CurrentRAMGiBUtilization': details.get('current', {}).get('RAMGiBUtilization', ''),
'RecommendedCount': details.get('recommendation', {}).get('count', ''),
'RecommendedNodeType': details.get('recommendation', {}).get('name', ''),
'RecommendedMonthlyRate': details.get('recommendation', {}).get('monthlyRate', ''),
'RecommendedTotalVCPUs': details.get('recommendation', {}).get('totalVCPUs', ''),
'RecommendedTotalRAMGiB': details.get('recommendation', {}).get('totalRAMGiB', ''),
'RecommendedVCPUUtilization': details.get('recommendation', {}).get('vCPUUtilization', ''),
'RecommendedRAMGiBUtilization': details.get('recommendation', {}).get('RAMGiBUtilization', '')
}
flattened.append(row)
return flattened

def json_to_csv():
if "http" in sys.argv[1].lower():
import requests

try:
response = requests.get(sys.argv[1])
response.raise_for_status() # Raise an exception for bad status codes
json_data = response.json()
except requests.RequestException as e:
print(f"Error fetching data from URL: {e}")
return
else:
try:
json_file = sys.argv[1]
csv_file = sys.argv[1] + ".csv"
with open(json_file, 'r') as f:
json_data = json.load(f)
except IOError as e:
print(f"Error reading JSON file: {e}")
return

flattened_data = flatten_data(json_data)

# with open(json_file, 'r') as f:
# json_data = json.load(f)

# flattened_data = flatten_data(json_data)

if flattened_data:
keys = flattened_data[0].keys()
if "http" in sys.argv[1]:
import io
csv_output = io.StringIO()
writer = csv.DictWriter(csv_output, fieldnames=keys)
writer.writeheader()
writer.writerows(flattened_data)
print(csv_output.getvalue())
else:
with open(csv_file, 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=keys)
writer.writeheader()
writer.writerows(flattened_data)
print(f"CSV file '{csv_file}' has been written.")
else:
print("No data to write to CSV.")

# Usage
json_to_csv()