-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchallenge1.py
More file actions
executable file
·196 lines (172 loc) · 6.64 KB
/
challenge1.py
File metadata and controls
executable file
·196 lines (172 loc) · 6.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Challenge1 - Write a script that builds three 512 MB Cloud Servers that
# following a similar naming convention. (ie., web1, web2, web3) and returns
# the IP and login credentials for each server. Use any image you want.
# Copyright 2013 Scott Gilbert
# All Rights Reserved.
#
# Licensed 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.
# Required Parameters:
# none
#
# Optional Parameters:
# -h, --help show help message and exit
# --flavor FLAVOR Flavor of servers to create
# --image IMAGE Image from which to create servers
# --basename BASENAME Base name to assign to new servers
# --numservers NUMSERVERS Number of servers to create
# --region REGION Region in which to create servers (DFW or ORD)
import os
import sys
import time
import argparse
import pyrax
def valid_regions(service):
"""Return list of valid regions"""
# This is the best I've been able to come up with to get a list of valid
# regions.
return pyrax.identity.services[service]['endpoints'].keys()
def is_valid_region(region, service):
""" Check validity of a region for a specified service """
if region in valid_regions(service):
return True
else:
return False
def is_valid_image(cs, image):
"""Check the validity of a CloudServer image uuid.
Return True if image is valid, False otherwise.
"""
try:
cs.images.get(image)
return True
except:
return False
def is_valid_flavor(cs, flavor):
"""Check the validity of a CloudServer flavor-id.
Return True if flavor-id is valid, False otherwise.
"""
try:
cs.flavors.get(flavor)
return True
except:
return False
def build_some_servers(cs, flavor, image, serverBaseName, numServers,
insertFiles={}, nets={}):
""" Request build of CloudServers of specified flavor and image.
Server hostnames are the combination of serverBaseName and a sequential
counter, starting with 1 and ending with numServers - unless number of
servers is 1, then just the serverBaseName is used.
Returns array of server objects.
Note: Function returns immediately, network info and server build are almost
certainly not complete yet.
"""
# Request build of new servers
servers=[]
if numServers == 1:
print "Requesting build for server %s" % serverBaseName
servers.append(cs.servers.create(serverBaseName, image, flavor,
files=insertFiles, nics=nets))
else:
for server_num in xrange(1, numServers + 1):
print "Requesting build for server %s%d" % (serverBaseName, server_num)
servers.append(cs.servers.create("%s%d" % (serverBaseName, server_num),
image, flavor, files=insertFiles,
nics=nets))
return servers
def wait_for_server_networks(servers):
"""Given an array of pyrax server objects, wait until all of the servers
have network IPs assigned. Print a little activity indicator to let the
user know that we are not stuck.
"""
print "\nWaiting for IP addresses to be assigned..."
networks_assigned = False
while not networks_assigned:
time.sleep(2)
print '.',
networks_assigned = True
for srv in servers:
srv.get()
if srv.networks == {} and srv.status <> 'ERROR':
networks_assigned = False
break
def wait_for_server_builds(servers):
"""Given an array of pyrax server objects, wait until all of the servers
builds have completed. Print a little activity indicator to let the user
know that we are not stuck.
"""
print "\nWaiting for all server builds to complete..."
allBuildsComplete = False
while not allBuildsComplete:
time.sleep(2)
print '.',
allBuildsComplete = True
for srv in servers:
srv.get()
if srv.status not in ['ACTIVE','ERROR']:
allBuildsComplete = False
break
def print_servers_info(servers):
"""Given an array of pyrax server objects, print basic information about
each one.
"""
print "Done!\n"
for srv in servers:
print "\n\nServer Name: %s" % srv.name
print "Status: %s" % srv.status
#print "Region: %s" % srv.region
print "Root Password: %s" % srv.adminPass
print "Networks:"
for net in srv.networks:
print " %s IPs:" % net,
for ip in srv.networks[net]:
print ip,
print
print
if __name__ == "__main__":
print "\nChallenge1 - Write a script that builds three 512 MB Cloud Servers"
print "that following a similar naming convention. (ie., web1, web2, web3)"
print "and returns the IP and login credentials for each server. Use any"
print "image you want.\n\n"
parser = argparse.ArgumentParser()
parser.add_argument("--flavor", default=2,
help="Flavor of servers to create")
parser.add_argument("--image", help="Image from which to create servers",
default='c195ef3b-9195-4474-b6f7-16e5bd86acd0')
parser.add_argument("--basename", default='web',
help="Base name to assign to new servers")
parser.add_argument("--numservers", default=3, type=int,
help="Number of servers to create")
parser.add_argument("--region", default='DFW',
help="Region in which to create servers (DFW or ORD)")
args = parser.parse_args()
credential_file=os.path.expanduser("~/.rackspace_cloud_credentials")
pyrax.set_credential_file(credential_file)
if is_valid_region(args.region, 'compute'):
cs = pyrax.connect_to_cloudservers(region=args.region)
else:
print "The region you requested is not valid: %s" % args.region
sys.exit(2)
if not is_valid_image(cs, args.image):
print "This does not appear to be a valid image-uuid: %s" % args.image
sys.exit(3)
if not is_valid_flavor(cs, args.flavor):
print "This does not appear to be a valid flavor-id: %s" % args.flavor
sys.exit(4)
# unbuffer stdout for pretty output
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
servers = build_some_servers(cs, args.flavor, args.image, args.basename,
args.numservers)
wait_for_server_networks(servers)
print_servers_info(servers)
# vim: ts=2 sw=2 tw=78 expandtab