Skip to content

Commit

Permalink
Merge pull request #6 from pusher/product-descriptions-argument
Browse files Browse the repository at this point in the history
Add "products" command line argument
  • Loading branch information
wonderhoss authored Apr 26, 2018
2 parents 5dc5adc + 0077ed0 commit e6c376e
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,24 @@ To fetch Spot Prices, the Spot Price Monitor will need the following IAM role po
}
```

### Product descriptions
For EC2 Classic accounts the default `Linux/UNIX` product description will only
work for non-VPC instance types, and for VPC accounts it will only work for VPC
instance types.

It's possible to override the product descriptions with the `-p`/`--products`
flag to work around this:

```
spot-price-monitor.py --products "Linux/UNIX" "Linux/UNIX (Amazon VPC)"
```

### Flags
```
usage: spot-price-monitor.py [-h] [--running-in-cluster RUNNING_IN_CLUSTER]
[-l LABEL] [-i SCRAPE_INTERVAL] [-m METRICS_PORT]
[-r REGION]
[-l SPOT_LABEL] [-i SCRAPE_INTERVAL]
[-m METRICS_PORT] [-r REGION]
[-p PRODUCTS [PRODUCTS ...]]
Monitors kubernetes for spot instances and exposes the current spot prices as
prometheus metrics
Expand All @@ -86,6 +99,9 @@ optional arguments:
-r REGION, --region REGION
The region that the cluster is running in (Default:
us-east-1)
-p PRODUCTS [PRODUCTS ...], --products PRODUCTS [PRODUCTS ...]
List of product (descriptions) to use for filtering
(Default: Linux/UNIX)
```

## Related
Expand Down
23 changes: 20 additions & 3 deletions spot-price-monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
from time import sleep


ALLOWED_PRODUCTS = [
'Linux/UNIX',
'SUSE Linux',
'Windows',
'Linux/UNIX (Amazon VPC)',
'SUSE Linux (Amazon VPC)',
'Windows (Amazon VPC)'
]

def get_zones_from_k8s(client):
''' Returns a list of unique availability zones used in the cluster'''
nodes = client.list_node(watch=False)
Expand All @@ -30,7 +39,7 @@ def get_instance_types_from_k8s(client, label):
return list(instance_types)


def get_spot_prices(client, instance_types, availability_zones):
def get_spot_prices(client, instance_types, availability_zones, products):
''' Returns a list of spot prices by instance type and availability zone'''
response = client.describe_spot_price_history(
Filters=[
Expand All @@ -41,7 +50,7 @@ def get_spot_prices(client, instance_types, availability_zones):
],
InstanceTypes=instance_types,
StartTime=datetime.now(),
ProductDescriptions=['Linux/UNIX']
ProductDescriptions=products
)
return response['SpotPriceHistory']

Expand Down Expand Up @@ -71,6 +80,10 @@ def get_args():
parser.add_argument('-r', '--region', type=str, default='us-east-1',
help='''The region that the cluster is running
in (Default: us-east-1)''')
parser.add_argument('-p', '--products', type=str, nargs='+', default=['Linux/UNIX'],
help='''List of product (descriptions) to use for filtering, separated
by spaces, e.g. `-p "Linux/UNIX" "Linux/UNIX (Amazon VPC)"`
(Default: Linux/UNIX)''')

return parser.parse_args()

Expand All @@ -87,6 +100,10 @@ def update_spot_price_metrics(metric, prices):
if __name__ == '__main__':
args = get_args()

for p in args.products:
if p not in ALLOWED_PRODUCTS:
raise ValueError('invalid product {}, expected one of {}'.format(p, ALLOWED_PRODUCTS))

if args.running_in_cluster:
config.incluster_config.load_incluster_config()
else:
Expand All @@ -110,7 +127,7 @@ def update_spot_price_metrics(metric, prices):
zones = get_zones_from_k8s(v1)
try:
types = get_instance_types_from_k8s(v1, args.spot_label)
spot_prices = get_spot_prices(ec2, types, zones)
spot_prices = get_spot_prices(ec2, types, zones, args.products)
backoff_multiplier = 1
except ClientError as e:
error.label(code=e.response['Error']['Code']).inc()
Expand Down

0 comments on commit e6c376e

Please sign in to comment.