PageRenderTime 37ms CodeModel.GetById 12ms app.highlight 20ms RepoModel.GetById 1ms app.codeStats 0ms

/boto-2.5.2/boto/mashups/order.py

#
Python | 211 lines | 173 code | 15 blank | 23 comment | 17 complexity | fa5bca9d67ad4de609164ca6edd404f0 MD5 | raw file
  1# Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/
  2#
  3# Permission is hereby granted, free of charge, to any person obtaining a
  4# copy of this software and associated documentation files (the
  5# "Software"), to deal in the Software without restriction, including
  6# without limitation the rights to use, copy, modify, merge, publish, dis-
  7# tribute, sublicense, and/or sell copies of the Software, and to permit
  8# persons to whom the Software is furnished to do so, subject to the fol-
  9# lowing conditions:
 10#
 11# The above copyright notice and this permission notice shall be included
 12# in all copies or substantial portions of the Software.
 13#
 14# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 15# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
 16# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
 17# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
 18# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 19# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 20# IN THE SOFTWARE.
 21
 22"""
 23High-level abstraction of an EC2 order for servers
 24"""
 25
 26import boto
 27import boto.ec2
 28from boto.mashups.server import Server, ServerSet
 29from boto.mashups.iobject import IObject
 30from boto.pyami.config import Config
 31from boto.sdb.persist import get_domain, set_domain
 32import time, StringIO
 33
 34InstanceTypes = ['m1.small', 'm1.large', 'm1.xlarge', 'c1.medium', 'c1.xlarge']
 35
 36class Item(IObject):
 37    
 38    def __init__(self):
 39        self.region = None
 40        self.name = None
 41        self.instance_type = None
 42        self.quantity = 0
 43        self.zone = None
 44        self.ami = None
 45        self.groups = []
 46        self.key = None
 47        self.ec2 = None
 48        self.config = None
 49
 50    def set_userdata(self, key, value):
 51        self.userdata[key] = value
 52
 53    def get_userdata(self, key):
 54        return self.userdata[key]
 55
 56    def set_region(self, region=None):
 57        if region:
 58            self.region = region
 59        else:
 60            l = [(r, r.name, r.endpoint) for r in boto.ec2.regions()]
 61            self.region = self.choose_from_list(l, prompt='Choose Region')
 62
 63    def set_name(self, name=None):
 64        if name:
 65            self.name = name
 66        else:
 67            self.name = self.get_string('Name')
 68
 69    def set_instance_type(self, instance_type=None):
 70        if instance_type:
 71            self.instance_type = instance_type
 72        else:
 73            self.instance_type = self.choose_from_list(InstanceTypes, 'Instance Type')
 74
 75    def set_quantity(self, n=0):
 76        if n > 0:
 77            self.quantity = n
 78        else:
 79            self.quantity = self.get_int('Quantity')
 80
 81    def set_zone(self, zone=None):
 82        if zone:
 83            self.zone = zone
 84        else:
 85            l = [(z, z.name, z.state) for z in self.ec2.get_all_zones()]
 86            self.zone = self.choose_from_list(l, prompt='Choose Availability Zone')
 87            
 88    def set_ami(self, ami=None):
 89        if ami:
 90            self.ami = ami
 91        else:
 92            l = [(a, a.id, a.location) for a in self.ec2.get_all_images()]
 93            self.ami = self.choose_from_list(l, prompt='Choose AMI')
 94
 95    def add_group(self, group=None):
 96        if group:
 97            self.groups.append(group)
 98        else:
 99            l = [(s, s.name, s.description) for s in self.ec2.get_all_security_groups()]
100            self.groups.append(self.choose_from_list(l, prompt='Choose Security Group'))
101
102    def set_key(self, key=None):
103        if key:
104            self.key = key
105        else:
106            l = [(k, k.name, '') for k in self.ec2.get_all_key_pairs()]
107            self.key = self.choose_from_list(l, prompt='Choose Keypair')
108
109    def update_config(self):
110        if not self.config.has_section('Credentials'):
111            self.config.add_section('Credentials')
112            self.config.set('Credentials', 'aws_access_key_id', self.ec2.aws_access_key_id)
113            self.config.set('Credentials', 'aws_secret_access_key', self.ec2.aws_secret_access_key)
114        if not self.config.has_section('Pyami'):
115            self.config.add_section('Pyami')
116        sdb_domain = get_domain()
117        if sdb_domain:
118            self.config.set('Pyami', 'server_sdb_domain', sdb_domain)
119            self.config.set('Pyami', 'server_sdb_name', self.name)
120
121    def set_config(self, config_path=None):
122        if not config_path:
123            config_path = self.get_filename('Specify Config file')
124        self.config = Config(path=config_path)
125
126    def get_userdata_string(self):
127        s = StringIO.StringIO()
128        self.config.write(s)
129        return s.getvalue()
130
131    def enter(self, **params):
132        self.region = params.get('region', self.region)
133        if not self.region:
134            self.set_region()
135        self.ec2 = self.region.connect()
136        self.name = params.get('name', self.name)
137        if not self.name:
138            self.set_name()
139        self.instance_type = params.get('instance_type', self.instance_type)
140        if not self.instance_type:
141            self.set_instance_type()
142        self.zone = params.get('zone', self.zone)
143        if not self.zone:
144            self.set_zone()
145        self.quantity = params.get('quantity', self.quantity)
146        if not self.quantity:
147            self.set_quantity()
148        self.ami = params.get('ami', self.ami)
149        if not self.ami:
150            self.set_ami()
151        self.groups = params.get('groups', self.groups)
152        if not self.groups:
153            self.add_group()
154        self.key = params.get('key', self.key)
155        if not self.key:
156            self.set_key()
157        self.config = params.get('config', self.config)
158        if not self.config:
159            self.set_config()
160        self.update_config()
161
162class Order(IObject):
163
164    def __init__(self):
165        self.items = []
166        self.reservation = None
167
168    def add_item(self, **params):
169        item = Item()
170        item.enter(**params)
171        self.items.append(item)
172
173    def display(self):
174        print 'This Order consists of the following items'
175        print 
176        print 'QTY\tNAME\tTYPE\nAMI\t\tGroups\t\t\tKeyPair'
177        for item in self.items:
178            print '%s\t%s\t%s\t%s\t%s\t%s' % (item.quantity, item.name, item.instance_type,
179                                              item.ami.id, item.groups, item.key.name)
180
181    def place(self, block=True):
182        if get_domain() == None:
183            print 'SDB Persistence Domain not set'
184            domain_name = self.get_string('Specify SDB Domain')
185            set_domain(domain_name)
186        s = ServerSet()
187        for item in self.items:
188            r = item.ami.run(min_count=1, max_count=item.quantity,
189                             key_name=item.key.name, user_data=item.get_userdata_string(),
190                             security_groups=item.groups, instance_type=item.instance_type,
191                             placement=item.zone.name)
192            if block:
193                states = [i.state for i in r.instances]
194                if states.count('running') != len(states):
195                    print states
196                    time.sleep(15)
197                    states = [i.update() for i in r.instances]
198            for i in r.instances:
199                server = Server()
200                server.name = item.name
201                server.instance_id = i.id
202                server.reservation = r
203                server.save()
204                s.append(server)
205        if len(s) == 1:
206            return s[0]
207        else:
208            return s
209        
210
211