Return-Path: X-Original-To: apmail-libcloud-notifications-archive@www.apache.org Delivered-To: apmail-libcloud-notifications-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id C3A041025E for ; Thu, 19 Feb 2015 16:19:36 +0000 (UTC) Received: (qmail 54169 invoked by uid 500); 19 Feb 2015 16:19:36 -0000 Delivered-To: apmail-libcloud-notifications-archive@libcloud.apache.org Received: (qmail 54142 invoked by uid 500); 19 Feb 2015 16:19:36 -0000 Mailing-List: contact notifications-help@libcloud.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@libcloud.apache.org Delivered-To: mailing list notifications@libcloud.apache.org Received: (qmail 54133 invoked by uid 500); 19 Feb 2015 16:19:36 -0000 Delivered-To: apmail-libcloud-commits@libcloud.apache.org Received: (qmail 54130 invoked by uid 99); 19 Feb 2015 16:19:36 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 19 Feb 2015 16:19:36 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 72187E03EE; Thu, 19 Feb 2015 16:19:36 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: erjohnso@apache.org To: commits@libcloud.apache.org Message-Id: <85e72c37e4c049daabbc47469c1354d7@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: libcloud git commit: [google] Updated demos/gce_demo.py script Date: Thu, 19 Feb 2015 16:19:36 +0000 (UTC) Repository: libcloud Updated Branches: refs/heads/trunk 67dcedf8b -> 0c062d384 [google] Updated demos/gce_demo.py script Signed-off-by: Eric Johnson Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/0c062d38 Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/0c062d38 Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/0c062d38 Branch: refs/heads/trunk Commit: 0c062d384a4f8cc6bea185899973d870544c8557 Parents: 67dcedf Author: Eric Johnson Authored: Sat Feb 7 17:05:58 2015 -0800 Committer: Eric Johnson Committed: Thu Feb 19 16:15:50 2015 +0000 ---------------------------------------------------------------------- demos/gce_demo.py | 409 +++++++++++++++++++++++++++++------ demos/gce_lb_demo.py | 304 -------------------------- libcloud/compute/drivers/gce.py | 3 + 3 files changed, 344 insertions(+), 372 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/0c062d38/demos/gce_demo.py ---------------------------------------------------------------------- diff --git a/demos/gce_demo.py b/demos/gce_demo.py index e3a445e..cde874f 100755 --- a/demos/gce_demo.py +++ b/demos/gce_demo.py @@ -15,9 +15,13 @@ # limitations under the License. -# This example performs several tasks on Google Compute Engine. It can be run -# directly or can be imported into an interactive python session. This can -# also serve as an integration test for the GCE Node Driver. +# This example performs several tasks on Google Compute Platform. It can be +# run directly or can be imported into an interactive python session. This +# can also serve as live integration tests. +# +# To run directly, use python 2.7 or greater: +# - $ python gce_demo.py --help # to see the help screen +# - $ python gce_demo.py # to run all demos / tests # # To run interactively: # - Make sure you have valid values in secrets.py @@ -33,10 +37,22 @@ # gce_demo.CLEANUP = False # optional # gce_demo.MAX_NODES = 4 # optional # gce_demo.DATACENTER = 'us-central1-a' # optional -# gce_demo.main() +# gce_demo.main_compute() # 'compute' only demo +# gce_demo.main_load_balancer() # 'load_balancer' only demo +# gce_demo.main_dns() # 'dns only demo +# gce_demo.main() # all demos / tests import os.path import sys +import datetime +import time + +try: + import argparse +except: + print('This script uses the python "argparse" module. Please use Python ' + '2.7 or greater.') + raise try: import secrets @@ -56,16 +72,26 @@ sys.path.append(os.path.normpath(os.path.join(os.path.dirname(__file__), from libcloud.compute.types import Provider from libcloud.compute.providers import get_driver from libcloud.common.google import ResourceNotFoundError +from libcloud.loadbalancer.types import Provider as Provider_lb +from libcloud.loadbalancer.providers import get_driver as get_driver_lb +from libcloud.dns.types import Provider as Provider_dns +from libcloud.dns.providers import get_driver as get_driver_dns +from libcloud.dns.base import Record, Zone +from libcloud.utils.py3 import PY3 +if PY3: + import urllib.request as url_req +else: + import urllib2 as url_req # Maximum number of 1-CPU nodes to allow to run simultaneously MAX_NODES = 5 # String that all resource names created by the demo will start with # WARNING: Any resource that has a matching name will be destroyed. -DEMO_BASE_NAME = 'libcloud-demo' +DEMO_BASE_NAME = 'lct' # Datacenter to create resources in -DATACENTER = 'us-central1-a' +DATACENTER = 'us-central1-f' # Clean up resources at the end (can be set to false in order to # inspect resources at the end of the run). Resources will be cleaned @@ -86,7 +112,31 @@ def get_gce_driver(): return driver -def display(title, resource_list): +def get_gcelb_driver(gce_driver=None): + # The GCE Load Balancer driver uses the GCE Compute driver for all of its + # API calls. You can either provide the driver directly, or provide the + # same authentication information so the LB driver can get its own + # Compute driver. + if gce_driver: + driver = get_driver_lb(Provider_lb.GCE)(gce_driver=gce_driver) + else: + driver = get_driver_lb(Provider_lb.GCE)(*args, **kwargs) + return driver + + +def get_dns_driver(gce_driver=None): + # The Google DNS driver uses the GCE Compute driver for all of its + # API calls. You can either provide the driver directly, or provide the + # same authentication information so the LB driver can get its own + # Compute driver. + if gce_driver: + driver = get_driver_dns(Provider_dns.GOOGLE)(gce_driver=gce_driver) + else: + driver = get_driver_dns(Provider_dns.GOOGLE)(*args, **kwargs) + return driver + + +def display(title, resource_list=[]): """ Display a list of resources. @@ -96,9 +146,28 @@ def display(title, resource_list): :param resource_list: List of resources to display :type resource_list: Any ``object`` with a C{name} attribute """ - print('%s:' % title) - for item in resource_list[:10]: - print(' %s' % item.name) + print('=> %s' % title) + for item in resource_list: + if isinstance(item, Record): + if item.name.startswith(DEMO_BASE_NAME): + print('=> name=%s, type=%s' % (item.name, item.type)) + else: + print(' name=%s, type=%s' % (item.name, item.type)) + elif isinstance(item, Zone): + if item.domain.startswith(DEMO_BASE_NAME): + print('=> name=%s, dnsname=%s' % (item.id, item.domain)) + else: + print(' name=%s, dnsname=%s' % (item.id, item.domain)) + elif hasattr(item, 'name'): + if item.domain.startswith(DEMO_BASE_NAME): + print('=> %s' % item.domain) + else: + print(' %s' % item.domain) + else: + if item.startswith(DEMO_BASE_NAME): + print('=> %s' % item) + else: + print(' %s' % item) def clean_up(gce, base_name, node_list=None, resource_list=None): @@ -128,9 +197,9 @@ def clean_up(gce, base_name, node_list=None, resource_list=None): result = gce.ex_destroy_multiple_nodes(del_nodes) for i, success in enumerate(result): if success: - print(' Deleted %s' % del_nodes[i].name) + display(' Deleted %s' % del_nodes[i].name) else: - print(' Failed to delete %s' % del_nodes[i].name) + display(' Failed to delete %s' % del_nodes[i].name) # Destroy everything else with just the destroy method for resource in resource_list: @@ -138,66 +207,68 @@ def clean_up(gce, base_name, node_list=None, resource_list=None): try: resource.destroy() except ResourceNotFoundError: - print(' Not found: %s(%s)' % (resource.name, - resource.__class__.__name__)) + display(' Not found: %s(%s)' % (resource.name, + resource.__class__.__name__)) except: class_name = resource.__class__.__name__ - print(' Failed to Delete %s(%s)' % (resource.name, - class_name)) + display(' Failed to Delete %s(%s)' % (resource.name, + class_name)) raise -# ==== DEMO CODE STARTS HERE ==== -def main(): +# ==== COMPUTE CODE STARTS HERE ==== +def main_compute(): + start_time = datetime.datetime.now() + display('Compute demo/test start time: %s' % str(start_time)) gce = get_gce_driver() # Get project info and print name project = gce.ex_get_project() - print('Project: %s' % project.name) + display('Project: %s' % project.name) # == Get Lists of Everything and Display the lists (up to 10) == # These can either just return values for the current datacenter (zone) # or for everything. all_nodes = gce.list_nodes(ex_zone='all') - display('Nodes', all_nodes) + display('Nodes:', all_nodes) all_addresses = gce.ex_list_addresses(region='all') - display('Addresses', all_addresses) + display('Addresses:', all_addresses) all_volumes = gce.list_volumes(ex_zone='all') - display('Volumes', all_volumes) + display('Volumes:', all_volumes) # This can return everything, but there is a large amount of overlap, # so we'll just get the sizes from the current zone. sizes = gce.list_sizes() - display('Sizes', sizes) + display('Sizes:', sizes) # These are global firewalls = gce.ex_list_firewalls() - display('Firewalls', firewalls) + display('Firewalls:', firewalls) networks = gce.ex_list_networks() - display('Networks', networks) + display('Networks:', networks) images = gce.list_images() - display('Images', images) + display('Images:', images) locations = gce.list_locations() - display('Locations', locations) + display('Locations:', locations) zones = gce.ex_list_zones() - display('Zones', zones) + display('Zones:', zones) snapshots = gce.ex_list_snapshots() - display('Snapshots', snapshots) + display('Snapshots:', snapshots) # == Clean up any old demo resources == - print('Cleaning up any "%s" resources:' % DEMO_BASE_NAME) + display('Cleaning up any "%s" resources' % DEMO_BASE_NAME) clean_up(gce, DEMO_BASE_NAME, all_nodes, all_addresses + all_volumes + firewalls + networks + snapshots) # == Create Node with disk auto-created == if MAX_NODES > 1: - print('Creating a node with multiple disks using GCE structure:') + display('Creating a node with boot/local-ssd using GCE structure:') name = '%s-gstruct' % DEMO_BASE_NAME img_url = "projects/debian-cloud/global/images/" img_url += "backports-debian-7-wheezy-v20141205" @@ -227,44 +298,45 @@ def main(): 'us-central1-f', ex_disks_gce_struct=gce_disk_struct) num_disks = len(node_gstruct.extra['disks']) - print(' Node %s created with %d disks' % (node_gstruct.name, + display(' Node %s created with %d disks' % (node_gstruct.name, num_disks)) - print('Creating Node with auto-created SSD:') + display('Creating Node with auto-created SSD:') name = '%s-np-node' % DEMO_BASE_NAME node_1 = gce.create_node(name, 'n1-standard-1', 'debian-7', ex_tags=['libcloud'], ex_disk_type='pd-ssd', ex_disk_auto_delete=False) - print(' Node %s created' % name) + display(' Node %s created' % name) # == Create, and attach a disk == - print('Creating a new disk:') + display('Creating a new disk:') disk_name = '%s-attach-disk' % DEMO_BASE_NAME volume = gce.create_volume(10, disk_name) if volume.attach(node_1): - print (' Attached %s to %s' % (volume.name, node_1.name)) - print (' Disabled auto-delete for %s on %s' % (volume.name, + display(' Attached %s to %s' % (volume.name, node_1.name)) + display(' Disabled auto-delete for %s on %s' % (volume.name, node_1.name)) gce.ex_set_volume_auto_delete(volume, node_1, auto_delete=False) if CLEANUP: # == Detach the disk == if gce.detach_volume(volume, ex_node=node_1): - print(' Detached %s from %s' % (volume.name, node_1.name)) + display(' Detached %s from %s' % (volume.name, + node_1.name)) # == Create Snapshot == - print('Creating a snapshot from existing disk:') + display('Creating a snapshot from existing disk:') # Create a disk to snapshot vol_name = '%s-snap-template' % DEMO_BASE_NAME image = gce.ex_get_image('debian-7') vol = gce.create_volume(None, vol_name, image=image) - print(' Created disk %s to shapshot' % DEMO_BASE_NAME) + display('Created disk %s to shapshot:' % DEMO_BASE_NAME) # Snapshot volume snapshot = vol.snapshot('%s-snapshot' % DEMO_BASE_NAME) - print(' Snapshot %s created' % snapshot.name) + display(' Snapshot %s created' % snapshot.name) # == Create Node with existing disk == - print('Creating Node with existing disk:') + display('Creating Node with existing disk:') name = '%s-persist-node' % DEMO_BASE_NAME # Use objects this time instead of names # Get latest Debian 7 image @@ -274,88 +346,289 @@ def main(): # Create Disk from Snapshot created above volume_name = '%s-boot-disk' % DEMO_BASE_NAME volume = gce.create_volume(None, volume_name, snapshot=snapshot) - print(' Created %s from snapshot' % volume.name) + display(' Created %s from snapshot' % volume.name) # Create Node with Disk node_2 = gce.create_node(name, size, image, ex_tags=['libcloud'], ex_boot_disk=volume, ex_disk_auto_delete=False) - print(' Node %s created with attached disk %s' % (node_2.name, - volume.name)) + display(' Node %s created with attached disk %s' % (node_2.name, + volume.name)) # == Update Tags for Node == - print('Updating Tags for %s' % node_2.name) + display('Updating Tags for %s:' % node_2.name) tags = node_2.extra['tags'] tags.append('newtag') if gce.ex_set_node_tags(node_2, tags): - print(' Tags updated for %s' % node_2.name) + display(' Tags updated for %s' % node_2.name) check_node = gce.ex_get_node(node_2.name) - print(' New tags: %s' % check_node.extra['tags']) + display(' New tags: %s' % check_node.extra['tags']) # == Setting Metadata for Node == - print('Setting Metadata for %s' % node_2.name) + display('Setting Metadata for %s:' % node_2.name) if gce.ex_set_node_metadata(node_2, {'foo': 'bar', 'baz': 'foobarbaz'}): - print(' Metadata updated for %s' % node_2.name) + display(' Metadata updated for %s' % node_2.name) check_node = gce.ex_get_node(node_2.name) - print(' New Metadata: %s' % check_node.extra['metadata']) + display(' New Metadata: %s' % check_node.extra['metadata']) # == Create Multiple nodes at once == base_name = '%s-multiple-nodes' % DEMO_BASE_NAME number = MAX_NODES - 2 if number > 0: - print('Creating Multiple Nodes (%s):' % number) + display('Creating Multiple Nodes (%s):' % number) multi_nodes = gce.ex_create_multiple_nodes(base_name, size, image, number, ex_tags=['libcloud'], ex_disk_auto_delete=True) for node in multi_nodes: - print(' Node %s created.' % node.name) + display(' Node %s created' % node.name) # == Create a Network == - print('Creating Network:') + display('Creating Network:') name = '%s-network' % DEMO_BASE_NAME cidr = '10.10.0.0/16' network_1 = gce.ex_create_network(name, cidr) - print(' Network %s created' % network_1.name) + display(' Network %s created' % network_1.name) # == Create a Firewall == - print('Creating a Firewall:') + display('Creating a Firewall:') name = '%s-firewall' % DEMO_BASE_NAME allowed = [{'IPProtocol': 'tcp', 'ports': ['3141']}] firewall_1 = gce.ex_create_firewall(name, allowed, network=network_1, source_tags=['libcloud']) - print(' Firewall %s created' % firewall_1.name) + display(' Firewall %s created' % firewall_1.name) # == Create a Static Address == - print('Creating an Address:') + display('Creating an Address:') name = '%s-address' % DEMO_BASE_NAME address_1 = gce.ex_create_address(name) - print(' Address %s created with IP %s' % (address_1.name, - address_1.address)) + display(' Address %s created with IP %s' % (address_1.name, + address_1.address)) # == List Updated Resources in current zone/region == - print('Updated Resources in current zone/region:') + display('Updated Resources in current zone/region') nodes = gce.list_nodes() - display('Nodes', nodes) + display('Nodes:', nodes) addresses = gce.ex_list_addresses() - display('Addresses', addresses) + display('Addresses:', addresses) firewalls = gce.ex_list_firewalls() - display('Firewalls', firewalls) + display('Firewalls:', firewalls) networks = gce.ex_list_networks() - display('Networks', networks) + display('Networks:', networks) snapshots = gce.ex_list_snapshots() - display('Snapshots', snapshots) + display('Snapshots:', snapshots) if CLEANUP: - print('Cleaning up %s resources created.' % DEMO_BASE_NAME) + display('Cleaning up %s resources created' % DEMO_BASE_NAME) clean_up(gce, DEMO_BASE_NAME, nodes, addresses + firewalls + networks + snapshots) volumes = gce.list_volumes() clean_up(gce, DEMO_BASE_NAME, None, volumes) + end_time = datetime.datetime.now() + display('Total runtime: %s' % str(end_time - start_time)) + + +# ==== LOAD BALANCER CODE STARTS HERE ==== +def main_load_balancer(): + start_time = datetime.datetime.now() + display('Load-balancer demo/test start time: %s' % str(start_time)) + gce = get_gce_driver() + gcelb = get_gcelb_driver(gce) + + # Get project info and print name + project = gce.ex_get_project() + display('Project: %s' % project.name) + + # Existing Balancers + balancers = gcelb.list_balancers() + display('Load Balancers', balancers) + + # Protocols + protocols = gcelb.list_protocols() + display('Protocols', protocols) + + # Healthchecks + healthchecks = gcelb.ex_list_healthchecks() + display('Health Checks', healthchecks) + + # This demo is based on the GCE Load Balancing Quickstart described here: + # https://developers.google.com/compute/docs/load-balancing/lb-quickstart + + # == Clean-up and existing demo resources == + all_nodes = gce.list_nodes(ex_zone='all') + firewalls = gce.ex_list_firewalls() + display('Cleaning up any "%s" resources' % DEMO_BASE_NAME) + clean_up(gce, DEMO_BASE_NAME, all_nodes, + balancers + healthchecks + firewalls) + + # == Create 3 nodes to balance between == + startup_script = ('apt-get -y update && ' + 'apt-get -y install apache2 && ' + 'hostname > /var/www/index.html') + tag = '%s-www' % DEMO_BASE_NAME + base_name = '%s-www' % DEMO_BASE_NAME + image = gce.ex_get_image('debian-7') + size = gce.ex_get_size('n1-standard-1') + number = 3 + metadata = {'items': [{'key': 'startup-script', + 'value': startup_script}]} + lb_nodes = gce.ex_create_multiple_nodes(base_name, size, image, + number, ex_tags=[tag], + ex_metadata=metadata, + ignore_errors=False) + display('Created Nodes', lb_nodes) + + # == Create a Firewall for instances == + display('Creating a Firewall') + name = '%s-firewall' % DEMO_BASE_NAME + allowed = [{'IPProtocol': 'tcp', + 'ports': ['80']}] + firewall = gce.ex_create_firewall(name, allowed, source_tags=[tag]) + display(' Firewall %s created' % firewall.name) + + # == Create a Health Check == + display('Creating a HealthCheck') + name = '%s-healthcheck' % DEMO_BASE_NAME + + # These are all the default values, but listed here as an example. To + # create a healthcheck with the defaults, only name is required. + hc = gcelb.ex_create_healthcheck(name, host=None, path='/', port='80', + interval=5, timeout=5, + unhealthy_threshold=2, + healthy_threshold=2) + display('Healthcheck %s created' % hc.name) + + # == Create Load Balancer == + display('Creating Load Balancer') + name = '%s-lb' % DEMO_BASE_NAME + port = 80 + protocol = 'tcp' + algorithm = None + members = lb_nodes[:2] # Only attach the first two initially + healthchecks = [hc] + balancer = gcelb.create_balancer(name, port, protocol, algorithm, members, + ex_healthchecks=healthchecks) + display(' Load Balancer %s created' % balancer.name) + + # == Attach third Node == + display('Attaching additional node to Load Balancer') + member = balancer.attach_compute_node(lb_nodes[2]) + display(' Attached %s to %s' % (member.id, balancer.name)) + + # == Show Balancer Members == + members = balancer.list_members() + display('Load Balancer Members') + for member in members: + display(' ID: %s IP: %s' % (member.id, member.ip)) + + # == Remove a Member == + display('Removing a Member') + detached = members[0] + detach = balancer.detach_member(detached) + if detach: + display(' Member %s detached from %s' % (detached.id, + balancer.name)) + + # == Show Updated Balancer Members == + members = balancer.list_members() + display('Updated Load Balancer Members') + for member in members: + display(' ID: %s IP: %s' % (member.id, member.ip)) + + # == Reattach Member == + display('Reattaching Member') + member = balancer.attach_member(detached) + display(' Member %s attached to %s' % (member.id, balancer.name)) + + # == Test Load Balancer by connecting to it multiple times == + PAUSE = 60 + display('Sleeping for %d seconds for LB members to serve...' % PAUSE) + time.sleep(PAUSE) + rounds = 200 + url = 'http://%s/' % balancer.ip + line_length = 75 + display('Connecting to %s %s times' % (url, rounds)) + for x in range(rounds): + response = url_req.urlopen(url) + if PY3: + output = str(response.read(), encoding='utf-8').strip() + else: + output = response.read().strip() + if 'www-001' in output: + padded_output = output.center(line_length) + elif 'www-002' in output: + padded_output = output.rjust(line_length) + else: + padded_output = output.ljust(line_length) + sys.stdout.write('\r%s' % padded_output) + sys.stdout.flush() + time.sleep(.25) + + print "" + if CLEANUP: + balancers = gcelb.list_balancers() + healthchecks = gcelb.ex_list_healthchecks() + nodes = gce.list_nodes(ex_zone='all') + firewalls = gce.ex_list_firewalls() + + display('Cleaning up %s resources created' % DEMO_BASE_NAME) + clean_up(gce, DEMO_BASE_NAME, nodes, + balancers + healthchecks + firewalls) + + end_time = datetime.datetime.now() + display('Total runtime: %s' % str(end_time - start_time)) + + +# ==== GOOGLE DNS CODE STARTS HERE ==== +def main_dns(): + start_time = datetime.datetime.now() + display('DNS demo/test start time: %s' % str(start_time)) + gce = get_gce_driver() + gdns = get_dns_driver() + # Get project info and print name + project = gce.ex_get_project() + display('Project: %s' % project.name) + + # Get list of managed zones + zones = gdns.iterate_zones() + display('Zones', zones) + + # Get list of records + zones = gdns.iterate_zones() + for z in zones: + records = gdns.iterate_records(z) + display('Records for managed zone "%s"' % z.id, records) + + # TODO(erjohnso): Finish this DNS section. Challenging in that you need to + # own a domain, so testing will require user customization. Perhaps a new + # command-line required flag unless --skip-dns is supplied. Also, real + # e2e testing should try to do DNS lookups on new records, but DNS TTL + # and propagation delays will introduce limits on what can be tested. + + end_time = datetime.datetime.now() + display('Total runtime: %s' % str(end_time - start_time)) if __name__ == '__main__': - main() + parser = argparse.ArgumentParser( + description='Google Cloud Platform Demo / Live Test Script') + parser.add_argument("--skip-compute", + help="skip compute demo / live tests", + dest="compute", action="store_false") + parser.add_argument("--skip-load-balancer", + help="skip load-balancer demo / live tests", + dest="lb", action="store_false") + parser.add_argument("--skip-dns", + help="skip DNS demo / live tests", + dest="dns", action="store_false") + cl_args = parser.parse_args() + + if cl_args.compute: + main_compute() + if cl_args.lb: + main_load_balancer() + if cl_args.dns: + main_dns() http://git-wip-us.apache.org/repos/asf/libcloud/blob/0c062d38/demos/gce_lb_demo.py ---------------------------------------------------------------------- diff --git a/demos/gce_lb_demo.py b/demos/gce_lb_demo.py deleted file mode 100755 index 8d0fa53..0000000 --- a/demos/gce_lb_demo.py +++ /dev/null @@ -1,304 +0,0 @@ -#!/usr/bin/env python -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -# This example performs several tasks on Google Compute Engine and the GCE -# Load Balancer. It can be run directly or can be imported into an -# interactive python session. This can also serve as an integration test for -# the GCE Load Balancer Driver. -# -# To run interactively: -# - Make sure you have valid values in secrets.py -# (For more information about setting up your credentials, see the -# libcloud/common/google.py docstring) -# - Run 'python' in this directory, then: -# import gce_lb_demo -# gcelb = gce_lb_demo.get_gcelb_driver() -# gcelb.list_balancers() -# etc. -# - Or, to run the full demo from the interactive python shell: -# import gce_lb_demo -# gce_lb_demo.CLEANUP = False # optional -# gce_lb_demo.MAX_NODES = 4 # optional -# gce_lb_demo.DATACENTER = 'us-central1-a' # optional -# gce_lb_demo.main() - -import os.path -import sys -import time - -try: - import secrets -except ImportError: - print('"demos/secrets.py" not found.\n\n' - 'Please copy secrets.py-dist to secrets.py and update the GCE* ' - 'values with appropriate authentication information.\n' - 'Additional information about setting these values can be found ' - 'in the docstring for:\n' - 'libcloud/common/google.py\n') - sys.exit(1) - -# Add parent dir of this file's dir to sys.path (OS-agnostically) -sys.path.append(os.path.normpath(os.path.join(os.path.dirname(__file__), - os.path.pardir))) - -from libcloud.utils.py3 import PY3 -if PY3: - import urllib.request as url_req -else: - import urllib2 as url_req - -# This demo uses both the Compute driver and the LoadBalancer driver -from libcloud.compute.types import Provider -from libcloud.compute.providers import get_driver -from libcloud.loadbalancer.types import Provider as Provider_lb -from libcloud.loadbalancer.providers import get_driver as get_driver_lb - -# String that all resource names created by the demo will start with -# WARNING: Any resource that has a matching name will be destroyed. -DEMO_BASE_NAME = 'libcloud-lb-demo' - -# Datacenter to create resources in -DATACENTER = 'us-central1-a' - -# Clean up resources at the end (can be set to false in order to -# inspect resources at the end of the run). Resources will be cleaned -# at the beginning regardless. -CLEANUP = True - -args = getattr(secrets, 'GCE_PARAMS', ()) -kwargs = getattr(secrets, 'GCE_KEYWORD_PARAMS', {}) - -# Add datacenter to kwargs for Python 2.5 compatibility -kwargs = kwargs.copy() -kwargs['datacenter'] = DATACENTER - - -# ==== HELPER FUNCTIONS ==== -def get_gce_driver(): - driver = get_driver(Provider.GCE)(*args, **kwargs) - return driver - - -def get_gcelb_driver(gce_driver=None): - # The GCE Load Balancer driver uses the GCE Compute driver for all of its - # API calls. You can either provide the driver directly, or provide the - # same authentication information so the LB driver can get its own - # Compute driver. - if gce_driver: - driver = get_driver_lb(Provider_lb.GCE)(gce_driver=gce_driver) - else: - driver = get_driver_lb(Provider_lb.GCE)(*args, **kwargs) - return driver - - -def display(title, resource_list): - """ - Display a list of resources. - - :param title: String to be printed at the heading of the list. - :type title: ``str`` - - :param resource_list: List of resources to display - :type resource_list: Any ``object`` with a C{name} attribute - """ - print('%s:' % title) - for item in resource_list[:10]: - print(' %s' % item.name) - - -def clean_up(gce, base_name, node_list=None, resource_list=None): - """ - Destroy all resources that have a name beginning with 'base_name'. - - :param base_name: String with the first part of the name of resources - to destroy - :type base_name: ``str`` - - :keyword node_list: List of nodes to consider for deletion - :type node_list: ``list`` of :class:`Node` - - :keyword resource_list: List of resources to consider for deletion - :type resource_list: ``list`` of I{Resource Objects} - """ - if node_list is None: - node_list = [] - if resource_list is None: - resource_list = [] - # Use ex_destroy_multiple_nodes to destroy nodes - del_nodes = [] - for node in node_list: - if node.name.startswith(base_name): - del_nodes.append(node) - - result = gce.ex_destroy_multiple_nodes(del_nodes) - for i, success in enumerate(result): - if success: - print(' Deleted %s' % del_nodes[i].name) - else: - print(' Failed to delete %s' % del_nodes[i].name) - - # Destroy everything else with just the destroy method - for resource in resource_list: - if resource.name.startswith(base_name): - if resource.destroy(): - print(' Deleted %s' % resource.name) - else: - print(' Failed to Delete %s' % resource.name) - - -# ==== DEMO CODE STARTS HERE ==== -def main(): - gce = get_gce_driver() - gcelb = get_gcelb_driver(gce) - - # Existing Balancers - balancers = gcelb.list_balancers() - display('Load Balancers', balancers) - - # Protocols - protocols = gcelb.list_protocols() - print('Protocols:') - for p in protocols: - print(' %s' % p) - - # Healthchecks - healthchecks = gcelb.ex_list_healthchecks() - display('Health Checks', healthchecks) - - # This demo is based on the GCE Load Balancing Quickstart described here: - # https://developers.google.com/compute/docs/load-balancing/lb-quickstart - - # == Clean-up and existing demo resources == - all_nodes = gce.list_nodes(ex_zone='all') - firewalls = gce.ex_list_firewalls() - print('Cleaning up any "%s" resources:' % DEMO_BASE_NAME) - clean_up(gce, DEMO_BASE_NAME, all_nodes, - balancers + healthchecks + firewalls) - - # == Create 3 nodes to balance between == - startup_script = ('apt-get -y update && ' - 'apt-get -y install apache2 && ' - 'hostname > /var/www/index.html') - tag = '%s-www' % DEMO_BASE_NAME - base_name = '%s-www' % DEMO_BASE_NAME - image = gce.ex_get_image('debian-7') - size = gce.ex_get_size('n1-standard-1') - number = 3 - metadata = {'items': [{'key': 'startup-script', - 'value': startup_script}]} - lb_nodes = gce.ex_create_multiple_nodes(base_name, size, image, - number, ex_tags=[tag], - ex_metadata=metadata, - ignore_errors=False) - display('Created Nodes', lb_nodes) - - # == Create a Firewall for instances == - print('Creating a Firewall:') - name = '%s-firewall' % DEMO_BASE_NAME - allowed = [{'IPProtocol': 'tcp', - 'ports': ['80']}] - firewall = gce.ex_create_firewall(name, allowed, source_tags=[tag]) - print(' Firewall %s created' % firewall.name) - - # == Create a Health Check == - print('Creating a HealthCheck:') - name = '%s-healthcheck' % DEMO_BASE_NAME - - # These are all the default values, but listed here as an example. To - # create a healthcheck with the defaults, only name is required. - hc = gcelb.ex_create_healthcheck(name, host=None, path='/', port='80', - interval=5, timeout=5, - unhealthy_threshold=2, - healthy_threshold=2) - print(' Healthcheck %s created' % hc.name) - - # == Create Load Balancer == - print('Creating Load Balancer') - name = '%s-lb' % DEMO_BASE_NAME - port = 80 - protocol = 'tcp' - algorithm = None - members = lb_nodes[:2] # Only attach the first two initially - healthchecks = [hc] - balancer = gcelb.create_balancer(name, port, protocol, algorithm, members, - ex_healthchecks=healthchecks) - print(' Load Balancer %s created' % balancer.name) - - # == Attach third Node == - print('Attaching additional node to Load Balancer:') - member = balancer.attach_compute_node(lb_nodes[2]) - print(' Attached %s to %s' % (member.id, balancer.name)) - - # == Show Balancer Members == - members = balancer.list_members() - print('Load Balancer Members:') - for member in members: - print(' ID: %s IP: %s' % (member.id, member.ip)) - - # == Remove a Member == - print('Removing a Member:') - detached = members[0] - detach = balancer.detach_member(detached) - if detach: - print(' Member %s detached from %s' % (detached.id, balancer.name)) - - # == Show Updated Balancer Members == - members = balancer.list_members() - print('Updated Load Balancer Members:') - for member in members: - print(' ID: %s IP: %s' % (member.id, member.ip)) - - # == Reattach Member == - print('Reattaching Member:') - member = balancer.attach_member(detached) - print(' Member %s attached to %s' % (member.id, balancer.name)) - - # == Test Load Balancer by connecting to it multiple times == - print('Sleeping for 10 seconds to stabilize the balancer...') - time.sleep(10) - rounds = 200 - url = 'http://%s/' % balancer.ip - line_length = 75 - print('Connecting to %s %s times:' % (url, rounds)) - for x in range(rounds): - response = url_req.urlopen(url) - if PY3: - output = str(response.read(), encoding='utf-8').strip() - else: - output = response.read().strip() - if 'www-001' in output: - padded_output = output.center(line_length) - elif 'www-002' in output: - padded_output = output.rjust(line_length) - else: - padded_output = output.ljust(line_length) - sys.stdout.write('\r%s' % padded_output) - sys.stdout.flush() - print('') - - if CLEANUP: - balancers = gcelb.list_balancers() - healthchecks = gcelb.ex_list_healthchecks() - nodes = gce.list_nodes(ex_zone='all') - firewalls = gce.ex_list_firewalls() - - print('Cleaning up %s resources created.' % DEMO_BASE_NAME) - clean_up(gce, DEMO_BASE_NAME, nodes, - balancers + healthchecks + firewalls) - -if __name__ == '__main__': - main() http://git-wip-us.apache.org/repos/asf/libcloud/blob/0c062d38/libcloud/compute/drivers/gce.py ---------------------------------------------------------------------- diff --git a/libcloud/compute/drivers/gce.py b/libcloud/compute/drivers/gce.py index 68314a5..9eabd98 100644 --- a/libcloud/compute/drivers/gce.py +++ b/libcloud/compute/drivers/gce.py @@ -87,6 +87,9 @@ class GCELicense(UuidMixin): self.extra = extra or {} UuidMixin.__init__(self) + def destroy(self): + raise ProviderError("Can not destroy a License resource.") + def __repr__(self): return '' % ( self.id, self.name, self.charges_use_fee)