~ntt-pf-lab/nova/monkey_patch_notification

« back to all changes in this revision

Viewing changes to vendor/boto/boto/mashups/order.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
"""
 
23
High-level abstraction of an EC2 order for servers
 
24
"""
 
25
 
 
26
import boto
 
27
import boto.ec2
 
28
from boto.mashups.server import Server, ServerSet
 
29
from boto.mashups.iobject import IObject
 
30
from boto.pyami.config import Config
 
31
from boto.sdb.persist import get_domain, set_domain
 
32
import time, StringIO
 
33
 
 
34
InstanceTypes = ['m1.small', 'm1.large', 'm1.xlarge', 'c1.medium', 'c1.xlarge']
 
35
 
 
36
class 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
 
 
162
class 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