Skip to content

Commit

Permalink
Merge pull request #16 from electrolux-oss/bump-version-and-minor-cha…
Browse files Browse the repository at this point in the history
…nges

minor refactoring and also fix a hardcoded key
  • Loading branch information
gluckzhang authored Oct 3, 2024
2 parents bbf9691 + d4da42d commit 5229f17
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 21 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Modify the `exporter_config.yaml` file first, then use one of the following meth
### Docker

```
docker run --rm -v ./exporter_config.yaml:/app/exporter_config.yaml -p 9090:9090 -e AWS_ACCESS_KEY=${AWS_ACCESS_KEY} -e AWS_ACCESS_SECRET=${AWS_ACCESS_SECRET} opensourceelectrolux/aws-cost-exporter:v1.0.1
docker run --rm -v ./exporter_config.yaml:/app/exporter_config.yaml -p 9090:9090 -e AWS_ACCESS_KEY=${AWS_ACCESS_KEY} -e AWS_ACCESS_SECRET=${AWS_ACCESS_SECRET} opensourceelectrolux/aws-cost-exporter:v1.0.6
```

### Kubernetes
Expand Down
14 changes: 7 additions & 7 deletions app/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def __init__(
aws_assumed_role_name,
group_by,
targets,
metrics_type,
metric_type,
):
self.polling_interval_seconds = polling_interval_seconds
self.metric_name = metric_name
Expand All @@ -29,7 +29,7 @@ def __init__(
self.aws_access_secret = aws_access_secret
self.aws_assumed_role_name = aws_assumed_role_name
self.group_by = group_by
self.metrics_type = metrics_type # Store metrics
self.metric_type = metric_type # Store metrics
# we have verified that there is at least one target
self.labels = set(targets[0].keys())
# for now we only support exporting one type of cost (Usage)
Expand All @@ -41,7 +41,7 @@ def __init__(

def run_metrics(self):
# every time we clear up all the existing labels before setting new ones
self.aws_daily_cost_usd .clear()
self.aws_daily_cost_usd.clear()

for aws_account in self.targets:
logging.info("querying cost data for aws account %s" % aws_account["Publisher"])
Expand Down Expand Up @@ -70,7 +70,7 @@ def get_aws_account_session_default(self, account_id):
)

assumed_role_object = sts_client.assume_role(
RoleArn=f"arn:aws:iam::{account_id}:role/{self.aws_assumed_role_name}",RoleSessionName="AssumeRoleSession1"
RoleArn=f"arn:aws:iam::{account_id}:role/{self.aws_assumed_role_name}", RoleSessionName="AssumeRoleSession1"
)

return assumed_role_object["Credentials"]
Expand All @@ -87,7 +87,7 @@ def query_aws_cost_explorer(self, aws_client, group_by):
TimePeriod={"Start": start_date.strftime("%Y-%m-%d"), "End": end_date.strftime("%Y-%m-%d")},
Filter={"Dimensions": {"Key": "RECORD_TYPE", "Values": ["Usage"]}},
Granularity="DAILY",
Metrics=self.metrics_type, # Use dynamic metrics
Metrics=[self.metric_type], # Use dynamic metrics
GroupBy=groups,
)

Expand All @@ -110,12 +110,12 @@ def fetch(self, aws_account):

for result in cost_response:
if not self.group_by["enabled"]:
cost = float(result["Total"]["UnblendedCost"]["Amount"])
cost = float(result["Total"][self.metric_type]["Amount"])
self.aws_daily_cost_usd.labels(**aws_account, ChargeType="Usage").set(cost)
else:
merged_minor_cost = 0
for item in result["Groups"]:
cost = float(item["Metrics"]["UnblendedCost"]["Amount"])
cost = float(item["Metrics"][self.metric_type]["Amount"])

group_key_values = dict()
for i in range(len(self.group_by["groups"])):
Expand Down
2 changes: 1 addition & 1 deletion deployment/k8s-with-eks/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ spec:
serviceAccountName: aws-cost-exporter
containers:
- name: aws-cost-exporter
image: "opensourceelectrolux/aws-cost-exporter:v1.0.1"
image: "opensourceelectrolux/aws-cost-exporter:v1.0.6"
command: [ "python", "main.py", "-c", "/exporter_config.yaml" ]
imagePullPolicy: Always
ports:
Expand Down
4 changes: 2 additions & 2 deletions deployment/k8s/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
app.kubernetes.io/name: aws-cost-exporter
app.kubernetes.io/part-of: finops
app.kubernetes.io/component: backend
app.kubernetes.io/version: "v1.0.1"
app.kubernetes.io/version: "v1.0.6"
app.kubernetes.io/language: python
spec:
replicas: 1
Expand All @@ -24,7 +24,7 @@ spec:
spec:
containers:
- name: aws-cost-exporter
image: "opensourceelectrolux/aws-cost-exporter:v1.0.1"
image: "opensourceelectrolux/aws-cost-exporter:v1.0.6"
command: [ "python", "main.py", "-c", "/exporter_config.yaml" ]
imagePullPolicy: Always
env:
Expand Down
3 changes: 2 additions & 1 deletion exporter_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ metrics:
tag_value: other
# Allowed values for metric type are AmortizedCost, BlendedCost, NetAmortizedCost, NetUnblendedCost, NormalizedUsageAmount, UnblendedCost, and UsageQuantity
metrics_type: AmortizedCost

- metric_name: aws_daily_cost_usd # change the metric name if needed
group_by:
# Cost data can be groupped using up to two different groups: DIMENSION, TAG, COST_CATEGORY.
Expand All @@ -44,6 +44,7 @@ metrics:
enabled: false
threshold: 10
tag_value: other
# Allowed values for metric type are AmortizedCost, BlendedCost, NetAmortizedCost, NetUnblendedCost, NormalizedUsageAmount, UnblendedCost, and UsageQuantity
metrics_type: AmortizedCost

target_aws_accounts:
Expand Down
28 changes: 20 additions & 8 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import argparse
import logging
import os
import signal
import sys
import time

Expand All @@ -14,6 +15,10 @@
from app.exporter import MetricExporter


def handle_sigint(sig, frame):
exit()


def get_configs():
parser = argparse.ArgumentParser(description="AWS Cost Exporter, exposing AWS cost data as Prometheus metrics.")
parser.add_argument(
Expand All @@ -34,9 +39,14 @@ def get_configs():

def validate_configs(config):

valid_metrics_types = [
"AmortizedCost", "BlendedCost", "NetAmortizedCost", "NetUnblendedCost",
"NormalizedUsageAmount", "UnblendedCost", "UsageQuantity"
valid_metric_types = [
"AmortizedCost",
"BlendedCost",
"NetAmortizedCost",
"NetUnblendedCost",
"NormalizedUsageAmount",
"UnblendedCost",
"UsageQuantity",
]

if len(config["target_aws_accounts"]) == 0:
Expand Down Expand Up @@ -71,9 +81,11 @@ def validate_configs(config):
logging.error("Some label names in group_by are the same as AWS account labels!")
sys.exit(1)

# Validate metrics_type
if config_metric["metrics_type"] not in valid_metrics_types:
logging.error(f"Invalid metrics_type: {config_metric['metrics_type']}. It must be one of {', '.join(valid_metrics_types)}.")
# Validate metric_type
if config_metric["metric_type"] not in valid_metric_types:
logging.error(
f"Invalid metric_type: {config_metric['metric_type']}. It must be one of {', '.join(valid_metric_types)}."
)
sys.exit(1)

for i in range(1, len(config["target_aws_accounts"])):
Expand All @@ -99,7 +111,6 @@ def validate_configs(config):
sys.exit(1)



def main(config):
start_http_server(config["exporter_port"])
while True:
Expand All @@ -112,7 +123,7 @@ def main(config):
targets=config["target_aws_accounts"],
metric_name=config_metric["metric_name"],
group_by=config_metric["group_by"],
metrics_type=[config_metric["metrics_type"]],
metric_type=config_metric["metric_type"],
)
app_metrics.run_metrics()
time.sleep(config["polling_interval_seconds"])
Expand All @@ -121,6 +132,7 @@ def main(config):
if __name__ == "__main__":
logger_format = "%(asctime)-15s %(levelname)-8s %(message)s"
logging.basicConfig(level=logging.INFO, format=logger_format)
signal.signal(signal.SIGINT, handle_sigint)
config = get_configs()
validate_configs(config)
main(config)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"name": "aws-cost-exporter",
"version": "v1.0.4"
"version": "v1.0.6"
}

0 comments on commit 5229f17

Please sign in to comment.