blob: e3a445e2894c1408b5d2d63e918e97c01783edfd [file] [log] [blame]
#!/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. 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.
#
# 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_demo
# gce = gce_demo.get_gce_driver()
# gce.list_nodes()
# etc.
# - Or, to run the full demo from the interactive python shell:
# import gce_demo
# gce_demo.CLEANUP = False # optional
# gce_demo.MAX_NODES = 4 # optional
# gce_demo.DATACENTER = 'us-central1-a' # optional
# gce_demo.main()
import os.path
import sys
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.compute.types import Provider
from libcloud.compute.providers import get_driver
from libcloud.common.google import ResourceNotFoundError
# 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'
# 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 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):
try:
resource.destroy()
except ResourceNotFoundError:
print(' 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))
raise
# ==== DEMO CODE STARTS HERE ====
def main():
gce = get_gce_driver()
# Get project info and print name
project = gce.ex_get_project()
print('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)
all_addresses = gce.ex_list_addresses(region='all')
display('Addresses', all_addresses)
all_volumes = gce.list_volumes(ex_zone='all')
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)
# These are global
firewalls = gce.ex_list_firewalls()
display('Firewalls', firewalls)
networks = gce.ex_list_networks()
display('Networks', networks)
images = gce.list_images()
display('Images', images)
locations = gce.list_locations()
display('Locations', locations)
zones = gce.ex_list_zones()
display('Zones', zones)
snapshots = gce.ex_list_snapshots()
display('Snapshots', snapshots)
# == Clean up any old demo resources ==
print('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:')
name = '%s-gstruct' % DEMO_BASE_NAME
img_url = "projects/debian-cloud/global/images/"
img_url += "backports-debian-7-wheezy-v20141205"
disk_type_url = "projects/graphite-demos/zones/us-central1-f/"
disk_type_url += "diskTypes/local-ssd"
gce_disk_struct = [
{
"type": "PERSISTENT",
"deviceName": '%s-gstruct' % DEMO_BASE_NAME,
"initializeParams": {
"diskName": '%s-gstruct' % DEMO_BASE_NAME,
"sourceImage": img_url
},
"boot": True,
"autoDelete": True
},
{
"type": "SCRATCH",
"deviceName": '%s-gstruct-lssd' % DEMO_BASE_NAME,
"initializeParams": {
"diskType": disk_type_url
},
"autoDelete": True
}
]
node_gstruct = gce.create_node(name, 'n1-standard-1', None,
'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,
num_disks))
print('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)
# == Create, and attach a disk ==
print('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,
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))
# == Create Snapshot ==
print('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)
# Snapshot volume
snapshot = vol.snapshot('%s-snapshot' % DEMO_BASE_NAME)
print(' Snapshot %s created' % snapshot.name)
# == Create Node with existing disk ==
print('Creating Node with existing disk:')
name = '%s-persist-node' % DEMO_BASE_NAME
# Use objects this time instead of names
# Get latest Debian 7 image
image = gce.ex_get_image('debian-7')
# Get Machine Size
size = gce.ex_get_size('n1-standard-1')
# 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)
# 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))
# == Update Tags for Node ==
print('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)
check_node = gce.ex_get_node(node_2.name)
print(' New tags: %s' % check_node.extra['tags'])
# == Setting Metadata for Node ==
print('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)
check_node = gce.ex_get_node(node_2.name)
print(' 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)
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)
# == Create a Network ==
print('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)
# == Create a Firewall ==
print('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)
# == Create a Static Address ==
print('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))
# == List Updated Resources in current zone/region ==
print('Updated Resources in current zone/region:')
nodes = gce.list_nodes()
display('Nodes', nodes)
addresses = gce.ex_list_addresses()
display('Addresses', addresses)
firewalls = gce.ex_list_firewalls()
display('Firewalls', firewalls)
networks = gce.ex_list_networks()
display('Networks', networks)
snapshots = gce.ex_list_snapshots()
display('Snapshots', snapshots)
if CLEANUP:
print('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)
if __name__ == '__main__':
main()