1#!/usr/bin/env python
2
3# Copyright 2015 Google Inc. All Rights Reserved.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#    http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""Example of using the Compute Engine API to create and delete instances.
18
19Creates a new compute engine instance and uses it to apply a caption to
20an image.
21
22For more information, see the README.md under samples/compute.
23"""
24
25import argparse
26import os
27import time
28
29import googleapiclient.discovery
30
31
32# [START compute_apiary_list_instances]
33def list_instances(compute, project, zone):
34    result = compute.instances().list(project=project, zone=zone).execute()
35    return result['items'] if 'items' in result else None
36# [END compute_apiary_list_instances]
37
38
39# [START compute_apiary_create_instance]
40def create_instance(compute, project, zone, name, bucket):
41    # Get the latest Debian Jessie image.
42    image_response = compute.images().getFromFamily(
43        project='debian-cloud', family='debian-9').execute()
44    source_disk_image = image_response['selfLink']
45
46    # Configure the machine
47    machine_type = "zones/%s/machineTypes/n1-standard-1" % zone
48    startup_script = open(
49        os.path.join(
50            os.path.dirname(__file__), 'startup-script.sh'), 'r').read()
51    image_url = "http://storage.googleapis.com/gce-demo-input/photo.jpg"
52    image_caption = "Ready for dessert?"
53
54    config = {
55        'name': name,
56        'machineType': machine_type,
57
58        # Specify the boot disk and the image to use as a source.
59        'disks': [
60            {
61                'boot': True,
62                'autoDelete': True,
63                'initializeParams': {
64                    'sourceImage': source_disk_image,
65                }
66            }
67        ],
68
69        # Specify a network interface with NAT to access the public
70        # internet.
71        'networkInterfaces': [{
72            'network': 'global/networks/default',
73            'accessConfigs': [
74                {'type': 'ONE_TO_ONE_NAT', 'name': 'External NAT'}
75            ]
76        }],
77
78        # Allow the instance to access cloud storage and logging.
79        'serviceAccounts': [{
80            'email': 'default',
81            'scopes': [
82                'https://www.googleapis.com/auth/devstorage.read_write',
83                'https://www.googleapis.com/auth/logging.write'
84            ]
85        }],
86
87        # Metadata is readable from the instance and allows you to
88        # pass configuration from deployment scripts to instances.
89        'metadata': {
90            'items': [{
91                # Startup script is automatically executed by the
92                # instance upon startup.
93                'key': 'startup-script',
94                'value': startup_script
95            }, {
96                'key': 'url',
97                'value': image_url
98            }, {
99                'key': 'text',
100                'value': image_caption
101            }, {
102                'key': 'bucket',
103                'value': bucket
104            }]
105        }
106    }
107
108    return compute.instances().insert(
109        project=project,
110        zone=zone,
111        body=config).execute()
112# [END compute_apiary_create_instance]
113
114
115# [START compute_apiary_delete_instance]
116def delete_instance(compute, project, zone, name):
117    return compute.instances().delete(
118        project=project,
119        zone=zone,
120        instance=name).execute()
121# [END compute_apiary_delete_instance]
122
123
124# [START compute_apiary_wait_for_operation]
125def wait_for_operation(compute, project, zone, operation):
126    print('Waiting for operation to finish...')
127    while True:
128        result = compute.zoneOperations().get(
129            project=project,
130            zone=zone,
131            operation=operation).execute()
132
133        if result['status'] == 'DONE':
134            print("done.")
135            if 'error' in result:
136                raise Exception(result['error'])
137            return result
138
139        time.sleep(1)
140# [END compute_apiary_wait_for_operation]
141
142
143# [START compute_apiary_run]
144def main(project, bucket, zone, instance_name, wait=True):
145    compute = googleapiclient.discovery.build('compute', 'v1')
146
147    print('Creating instance.')
148
149    operation = create_instance(compute, project, zone, instance_name, bucket)
150    wait_for_operation(compute, project, zone, operation['name'])
151
152    instances = list_instances(compute, project, zone)
153
154    print('Instances in project %s and zone %s:' % (project, zone))
155    for instance in instances:
156        print(' - ' + instance['name'])
157
158    print("""
159Instance created.
160It will take a minute or two for the instance to complete work.
161Check this URL: http://storage.googleapis.com/{}/output.png
162Once the image is uploaded press enter to delete the instance.
163""".format(bucket))
164
165    if wait:
166        input()
167
168    print('Deleting instance.')
169
170    operation = delete_instance(compute, project, zone, instance_name)
171    wait_for_operation(compute, project, zone, operation['name'])
172
173
174if __name__ == '__main__':
175    parser = argparse.ArgumentParser(
176        description=__doc__,
177        formatter_class=argparse.RawDescriptionHelpFormatter)
178    parser.add_argument('project_id', help='Your Google Cloud project ID.')
179    parser.add_argument(
180        'bucket_name', help='Your Google Cloud Storage bucket name.')
181    parser.add_argument(
182        '--zone',
183        default='us-central1-f',
184        help='Compute Engine zone to deploy to.')
185    parser.add_argument(
186        '--name', default='demo-instance', help='New instance name.')
187
188    args = parser.parse_args()
189
190    main(args.project_id, args.bucket_name, args.zone, args.name)
191# [END compute_apiary_run]
192