timeout=timeout)
+@click.command()
+@click.argument('stack_name')
+@click.pass_context
+def cost(ctx, stack_name):
+ """Get Total Stack Cost."""
+ os_stack.cost(
+ ctx.obj['os_cloud'],
+ stack_name)
+
+
@click.command(name='delete-stale')
@click.argument('jenkins_urls', nargs=-1)
@click.pass_context
stack.add_command(create)
stack.add_command(delete)
stack.add_command(delete_stale)
+stack.add_command(cost)
@openstack.group()
__author__ = 'Thanh Ha'
+from datetime import datetime
+import json
import logging
import sys
import time
+import urllib.request
import shade
from lftools.jenkins import Jenkins
+import openstack
log = logging.getLogger(__name__)
print('------------------------------------')
+def cost(os_cloud, stack_name):
+ """Get current cost info for the stack.
+
+ Return the cost in dollars & cents (x.xx).
+ """
+ def get_server_cost(server_id):
+ flavor, seconds = get_server_info(server_id)
+ url = "https://pricing.vexxhost.net/v1/pricing/%s/cost?seconds=%d"
+ with urllib.request.urlopen(url % (flavor, seconds)) as response: # nosec
+ data = json.loads(response.read())
+ return data['cost']
+
+ def parse_iso8601_time(time):
+ return datetime.strptime(time, "%Y-%m-%dT%H:%M:%S.%f")
+
+ def get_server_info(server_id):
+ server = cloud.compute.find_server(server_id)
+ diff = (datetime.utcnow() - parse_iso8601_time(server.launched_at))
+ return server.flavor['original_name'], diff.total_seconds()
+
+ def get_server_ids(stack_name):
+ servers = get_resources_by_type(stack_name, 'OS::Nova::Server')
+ return [s['physical_resource_id'] for s in servers]
+
+ def get_resources_by_type(stack_name, resource_type):
+ resources = get_stack_resources(stack_name)
+ return [r for r in resources if r.resource_type == resource_type]
+
+ def get_stack_resources(stack_name):
+ resources = []
+
+ def _is_nested(resource):
+ link_types = [l['rel'] for l in resource.links]
+ if 'nested' in link_types:
+ return True
+ return False
+
+ for r in cloud.orchestration.resources(stack_name):
+ if _is_nested(r):
+ resources += get_stack_resources(r.physical_resource_id)
+ continue
+ resources.append(r)
+ return resources
+
+ cloud = openstack.connect(os_cloud)
+
+ total_cost = 0.7
+ for server in get_server_ids(stack_name):
+ total_cost += get_server_cost(server)
+ print("total: " + str(total_cost))
+
+
def delete(os_cloud, name_or_id, force, timeout=900):
"""Delete a stack.