Fix a heap of pep8 errors

./run_tests.sh is much cleaner now.

Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
changes/40/40/1
Angus Salkeld 11 years ago
parent b7b29add11
commit dfe12cbaba
  1. 3
      bin/run-parser.py
  2. 9
      heat/api/v1/__init__.py
  3. 20
      heat/api/v1/stacks.py
  4. 6
      heat/cloudformations.py
  5. 9
      heat/cloudinit/part-handler.py
  6. 5
      heat/common/config.py
  7. 15
      heat/common/exception.py
  8. 5
      heat/common/utils.py
  9. 22
      heat/db/api.py
  10. 32
      heat/db/sqlalchemy/api.py
  11. 3
      heat/db/sqlalchemy/manage.py
  12. 17
      heat/db/sqlalchemy/migrate_repo/versions/001_norwhal.py
  13. 24
      heat/db/sqlalchemy/models.py
  14. 2
      heat/db/sqlalchemy/session.py
  15. 1
      heat/engine/__init__.py
  16. 14
      heat/engine/manager.py
  17. 86
      heat/engine/parser.py
  18. 80
      heat/engine/resources.py
  19. 2
      heat/manager.py
  20. 3
      heat/rpc/__init__.py
  21. 5
      heat/rpc/impl_qpid.py
  22. 5
      heat/service.py
  23. 5
      heat/tests/examples/test1.py
  24. 4
      heat/tests/examples/test2.py
  25. 4
      heat/tests/examples/test3.py

@ -40,7 +40,8 @@ with open(filename) as f:
# Don't immediately see a way to have key name as a parameter and also
# file injection and monitoring
# need to insert key on creation and know what private key is
setparam(params_dict, 'KeyName', 'sdake_key') # <- that gets inserted into image
setparam(params_dict, 'KeyName', 'sdake_key')
# ^ that gets inserted into image
setparam(params_dict, 'AWS::StackName', stack_name)
setparam(params_dict, 'InstanceType', 'm1.xlarge')

@ -21,10 +21,12 @@ from heat.common import wsgi
logger = logging.getLogger(__name__)
class API(wsgi.Router):
"""WSGI router for Heat v1 API requests."""
#TODO GetTemplate, ValidateTemplate
"""
WSGI router for Heat v1 API requests.
"""
def __init__(self, conf, **local_conf):
self.conf = conf
@ -49,6 +51,7 @@ class API(wsgi.Router):
mapper.connect("/DescribeStackEvents", controller=stacks_resource,
action="events_list", conditions=dict(method=["GET"]))
mapper.connect("/ValidateTemplate", controller=stacks_resource,
action="validate_template", conditions=dict(method=["GET"]))
action="validate_template",
conditions=dict(method=["GET"]))
super(API, self).__init__(mapper)

@ -56,8 +56,10 @@ class StackController(object):
{'method': 'list_stacks',
'args': {'params': dict(req.params)}})
res = {'ListStacksResponse': {'ListStacksResult': {'StackSummaries': [] } } }
summaries = res['ListStacksResponse']['ListStacksResult']['StackSummaries']
res = {'ListStacksResponse': {
'ListStacksResult': {'StackSummaries': []}}}
results = res['ListStacksResponse']['ListStacksResult']
summaries = results['StackSummaries']
if stack_list != None:
for s in stack_list['stacks']:
summaries.append(s)
@ -79,7 +81,7 @@ class StackController(object):
except rpc_common.RemoteError as ex:
return webob.exc.HTTPBadRequest(str(ex))
res = {'DescribeStacksResult': {'Stacks': [] } }
res = {'DescribeStacksResult': {'Stacks': []}}
stacks = res['DescribeStacksResult']['Stacks']
for s in stack_list['stacks']:
mem = {'member': s}
@ -88,10 +90,10 @@ class StackController(object):
return res
def _get_template(self, req):
if req.params.has_key('TemplateBody'):
if 'TemplateBody' in req.params:
logger.info('TemplateBody ...')
return req.params['TemplateBody']
elif req.params.has_key('TemplateUrl'):
elif 'TemplateUrl' in req.params:
logger.info('TemplateUrl %s' % req.params['TemplateUrl'])
url = urlparse.urlparse(req.params['TemplateUrl'])
if url.scheme == 'https':
@ -110,7 +112,6 @@ class StackController(object):
return None
def create(self, req):
"""
Returns the following information for all stacks:
@ -142,7 +143,6 @@ class StackController(object):
except rpc_common.RemoteError as ex:
return webob.exc.HTTPBadRequest(str(ex))
def validate_template(self, req):
con = context.get_admin_context()
@ -187,7 +187,6 @@ class StackController(object):
else:
return {'DeleteStackResult': res['Error']}
def events_list(self, req):
"""
Returns the following information for all stacks:
@ -205,8 +204,11 @@ class StackController(object):
return {'DescribeStackEventsResult': {'StackEvents': events}}
def create_resource(options):
"""Stacks resource factory method."""
"""
Stacks resource factory method.
"""
deserializer = wsgi.JSONRequestDeserializer()
serializer = wsgi.JSONResponseSerializer()
return wsgi.Resource(StackController(options), deserializer, serializer)

@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
SUPPORTED_PARAMS = ('StackName', 'TemplateBody', 'TemplateUrl','NotificationARNs', 'Parameters',
'Version', 'SignatureVersion', 'Timestamp', 'AWSAccessKeyId',
SUPPORTED_PARAMS = ('StackName', 'TemplateBody', 'TemplateUrl',
'NotificationARNs', 'Parameters', 'Version',
'SignatureVersion', 'Timestamp', 'AWSAccessKeyId',
'Signature', 'KeyStoneCreds')

@ -1,12 +1,15 @@
#part-handler
def list_types():
return(["text/x-cfninitdata"])
def handle_part(data,ctype,filename,payload):
def handle_part(data, ctype, filename, payload):
if ctype == "__begin__":
return
return
if ctype == "__end__":
return
return
if ctype == 'text/x-cfninitdata':
f = open('/var/lib/cloud/data/%s' % filename, 'w')

@ -140,6 +140,7 @@ class HeatConfigOpts(cfg.CommonConfigOpts):
**kwargs)
self.register_cli_opts(rpc_opts)
class HeatEngineConfigOpts(cfg.CommonConfigOpts):
service_opts = [
@ -178,7 +179,8 @@ class HeatEngineConfigOpts(cfg.CommonConfigOpts):
help='port for os volume api to listen'),
]
db_opts = [
cfg.StrOpt('db_backend', default='heat.db.sqlalchemy.api', help='The backend to use for db'),
cfg.StrOpt('db_backend', default='heat.db.sqlalchemy.api',
help='The backend to use for db'),
cfg.StrOpt('sql_connection',
default='mysql://heat:heat@localhost/heat',
help='The SQLAlchemy connection string used to connect to the '
@ -209,6 +211,7 @@ class HeatEngineConfigOpts(cfg.CommonConfigOpts):
self.register_cli_opts(self.service_opts)
self.register_cli_opts(rpc_opts)
def setup_logging(conf):
"""
Sets up the logging options for a log with supplied name

@ -21,10 +21,12 @@ import functools
import urlparse
from heat.openstack.common.exception import *
class RedirectException(Exception):
def __init__(self, url):
self.url = urlparse.urlparse(url)
def wrap_exception(notifier=None, publisher_id=None, event_type=None,
level=None):
"""This decorator wraps a method to catch any exceptions that may
@ -71,6 +73,7 @@ def wrap_exception(notifier=None, publisher_id=None, event_type=None,
return functools.wraps(f)(wrapped)
return inner
class MissingCredentialError(OpenstackException):
message = _("Missing required credential: %(required)s")
@ -79,6 +82,7 @@ class BadAuthStrategy(OpenstackException):
message = _("Incorrect auth strategy, expected \"%(expected)s\" but "
"received \"%(received)s\"")
class AuthBadRequest(OpenstackException):
message = _("Connect error/bad request to Auth service at URL %(url)s.")
@ -94,9 +98,11 @@ class AuthorizationFailure(OpenstackException):
class NotAuthenticated(OpenstackException):
message = _("You are not authenticated.")
class Forbidden(OpenstackException):
message = _("You are not authorized to complete this action.")
#NOTE(bcwaldon): here for backwards-compatability, need to deprecate.
class NotAuthorized(Forbidden):
message = _("You are not authorized to complete this action.")
@ -119,6 +125,7 @@ class MultipleChoices(OpenstackException):
"means that you have not included a version indicator in a "
"request URI.\n\nThe body of response returned:\n%(body)s")
class LimitExceeded(OpenstackException):
message = _("The request returned a 413 Request Entity Too Large. This "
"generally means that rate limiting or a quota threshold was "
@ -140,6 +147,7 @@ class ServiceUnavailable(OpenstackException):
else None)
super(ServiceUnavailable, self).__init__(*args, **kwargs)
class RequestUriTooLong(OpenstackException):
message = _("The URI was too long.")
@ -148,6 +156,7 @@ class ServerError(OpenstackException):
message = _("The request returned 500 Internal Server Error"
"\n\nThe response body:\n%(body)s")
class MaxRedirectsExceeded(OpenstackException):
message = _("Maximum redirects (%(redirects)s) was exceeded.")
@ -165,11 +174,15 @@ class RegionAmbiguity(OpenstackException):
"generally means that a region is required and you have not "
"supplied one.")
class UserParameterMissing(OpenstackException):
message = _("The Parameter (%(key)s) was not provided.")
class InvalidTemplateAttribute(OpenstackException):
message = _("The Referenced Attribute (%(resource)s %(key)s) is incorrect.")
message = _("The Referenced Attribute (%(resource)s %(key)s)"
" is incorrect.")
class UserKeyPairMissing(OpenstackException):
message = _("The Key (%(key_name)s) could not be found.")

@ -33,6 +33,7 @@ from heat.openstack.common import exception
PERFECT_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%f"
def chunkreadable(iter, chunk_size=65536):
"""
Wrap a readable iterator with a reader yielding chunks of
@ -62,6 +63,7 @@ def chunkiter(fp, chunk_size=65536):
def generate_uuid():
return str(uuid.uuid4())
def gen_uuid():
return uuid.uuid4()
@ -72,6 +74,7 @@ def strtime(at=None, fmt=PERFECT_TIME_FORMAT):
at = utcnow()
return at.strftime(fmt)
def parse_strtime(timestr, fmt=PERFECT_TIME_FORMAT):
"""Turn a formatted time back into a datetime."""
return datetime.datetime.strptime(timestr, fmt)
@ -86,6 +89,7 @@ def isotime(at=None):
str += ('Z' if tz == 'UTC' else tz)
return str
class LoopingCallDone(Exception):
"""Exception to break out and stop a LoopingCall.
@ -143,4 +147,3 @@ class LoopingCall(object):
def wait(self):
return self.done.wait()

@ -27,6 +27,8 @@ supported backend.
'''
from heat.openstack.common import utils
def configure(conf):
global IMPL
global SQL_CONNECTION
@ -35,12 +37,15 @@ def configure(conf):
SQL_CONNECTION = conf.sql_connection
SQL_IDLE_TIMEOUT = conf.sql_idle_timeout
def raw_template_get(context, template_id):
return IMPL.raw_template_get(context, template_id)
def raw_template_get_all(context):
return IMPL.raw_template_get_all(context)
def raw_template_create(context, values):
return IMPL.raw_template_create(context, values)
@ -48,9 +53,11 @@ def raw_template_create(context, values):
def parsed_template_get(context, template_id):
return IMPL.parsed_template_get(context, template_id)
def parsed_template_get_all(context):
return IMPL.parsed_template_get_all(context)
def parsed_template_create(context, values):
return IMPL.parsed_template_create(context, values)
@ -58,38 +65,51 @@ def parsed_template_create(context, values):
def resource_get(context, resource_id):
return IMPL.resource_get(context, resource_id)
def resource_get_all(context):
return IMPL.resource_get_all(context)
def resource_create(context, values):
return IMPL.resource_create(context, values)
def resource_get_all_by_stack(context, stack_id):
return IMPL.resource_get_all_by_stack(context, stack_id)
def resource_get_by_name_and_stack(context, resource_name, stack_id):
return IMPL.resource_get_by_name_and_stack(context, resource_name, stack_id)
return IMPL.resource_get_by_name_and_stack(context,
resource_name, stack_id)
def stack_get(context, stack_id):
return IMPL.stack_get(context, stack_id)
def stack_get_all(context):
return IMPL.stack_get_all(context)
def stack_create(context, values):
return IMPL.stack_create(context, values)
def stack_delete(context, stack_name):
return IMPL.stack_delete(context, stack_name)
def event_get(context, event_id):
return IMPL.event_get(context, event_id)
def event_get_all(context):
return IMPL.event_get_all(context)
def event_get_all_by_stack(context, stack_id):
return IMPL.event_get_all_by_stack(context, stack_id)
def event_create(context, values):
return IMPL.event_create(context, values)

@ -19,8 +19,9 @@ from sqlalchemy.orm.session import Session
from heat.db.sqlalchemy import models
from heat.db.sqlalchemy.session import get_session
def model_query(context, *args, **kwargs):
"""
"""
:param session: if present, the session to use
"""
session = kwargs.get('session') or get_session()
@ -29,6 +30,7 @@ def model_query(context, *args, **kwargs):
return query
def raw_template_get(context, template_id):
result = model_query(context, models.RawTemplate).\
filter_by(id=template_id).first()
@ -38,20 +40,23 @@ def raw_template_get(context, template_id):
return result
def raw_template_get_all(context):
results = model_query(context, models.RawTemplate).all()
if not results:
raise Exception('no raw templates were found')
return results
def raw_template_create(context, values):
raw_template_ref = models.RawTemplate()
raw_template_ref.update(values)
raw_template_ref.save()
return raw_template_ref
def parsed_template_get(context, template_id):
result = model_query(context, models.ParsedTemplate).\
filter_by(id=template_id).first()
@ -61,20 +66,23 @@ def parsed_template_get(context, template_id):
return result
def parsed_template_get_all(context):
results = model_query(context, models.ParsedTemplate).all()
if not results:
raise Exception('no parsed templates were found')
return results
def parsed_template_create(context, values):
parsed_template_ref = models.ParsedTemplate()
parsed_template_ref.update(values)
parsed_template_ref.save()
return parsed_template_ref
def resource_get(context, resource_id):
result = model_query(context, models.Resource).\
filter_by(id=resource_id).first()
@ -84,6 +92,7 @@ def resource_get(context, resource_id):
return result
def resource_get_by_name_and_stack(context, resource_name, stack_id):
result = model_query(context, models.Resource).\
filter_by(name=resource_name).\
@ -91,44 +100,51 @@ def resource_get_by_name_and_stack(context, resource_name, stack_id):
return result
def resource_get_all(context):
results = model_query(context, models.Resource).all()
if not results:
raise Exception('no resources were found')
return results
def resource_create(context, values):
resource_ref = models.Resource()
resource_ref.update(values)
resource_ref.save()
return resource_ref
def resource_get_all_by_stack(context, stack_id):
results = model_query(context, models.Resource).\
filter_by(stack_id=stack_id).all()
if not results:
raise Exception("no resources for stack_id %s were found" % stack_id)
return results
def stack_get(context, stack_id):
result = model_query(context, models.Stack).\
filter_by(name=stack_id).first()
return result
def stack_get_all(context):
results = model_query(context, models.Stack).all()
return results
def stack_create(context, values):
stack_ref = models.Stack()
stack_ref.update(values)
stack_ref.save()
return stack_ref
def stack_delete(context, stack_name):
s = stack_get(context, stack_name)
if not s:
@ -145,23 +161,27 @@ def stack_delete(context, stack_name):
session.delete(s)
session.flush()
def event_get(context, event_id):
result = model_query(context, models.Event).\
filter_by(id=event_id).first()
return result
def event_get_all(context):
results = model_query(context, models.Event).all()
return results
def event_get_all_by_stack(context, stack_id):
results = model_query(context, models.Event).\
filter_by(stack_id=stack_id).all()
return results
def event_create(context, values):
event_ref = models.Event()
event_ref.update(values)

@ -2,4 +2,5 @@
from migrate.versioning.shell import main
if __name__ == '__main__':
main(url='mysql://heat:heat@localhost/heat', debug='False', repository='migrate_repo')
main(url='mysql://heat:heat@localhost/heat', debug='False',
repository='migrate_repo')

@ -1,6 +1,7 @@
from sqlalchemy import *
from migrate import *
def upgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
@ -21,7 +22,8 @@ def upgrade(migrate_engine):
Column('name', String(length=255, convert_unicode=False,
assert_unicode=None,
unicode_error=None, _warn_on_bytestring=False)),
Column('raw_template_id', Integer, ForeignKey("raw_template.id"), nullable=False),
Column('raw_template_id', Integer, ForeignKey("raw_template.id"),
nullable=False),
)
event = Table(
@ -49,13 +51,14 @@ def upgrade(migrate_engine):
Column('updated_at', DateTime(timezone=False)),
Column('state', String(length=255, convert_unicode=False,
assert_unicode=None,
unicode_error=None,
unicode_error=None,
_warn_on_bytestring=False)),
Column('state_description', String(length=255, convert_unicode=False,
assert_unicode=None,
unicode_error=None,
unicode_error=None,
_warn_on_bytestring=False)),
Column('parsed_template_id', Integer, ForeignKey("parsed_template.id"), nullable=True),
Column('parsed_template_id', Integer, ForeignKey("parsed_template.id"),
nullable=True),
Column('stack_id', Integer, ForeignKey("stack.id"), nullable=False),
Column('depends_on', Integer),
)
@ -63,18 +66,20 @@ def upgrade(migrate_engine):
parsedtemplate = Table(
'parsed_template', meta,
Column('id', Integer, primary_key=True),
Column('raw_template_id', Integer, ForeignKey("raw_template.id"), nullable=False),
Column('raw_template_id', Integer, ForeignKey("raw_template.id"),
nullable=False),
Column('template', Text()),
)
tables = [rawtemplate, stack, event, parsedtemplate, resource]
for table in tables:
try:
try:
table.create()
except Exception:
meta.drop_all(tables=tables)
raise
def downgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine

@ -27,8 +27,9 @@ from heat.db.sqlalchemy.session import get_session
BASE = declarative_base()
class Json(types.TypeDecorator, types.MutableType):
impl=types.Text
impl = types.Text
def process_bind_param(self, value, dialect):
return dumps(value)
@ -36,6 +37,7 @@ class Json(types.TypeDecorator, types.MutableType):
def process_result_value(self, value, dialect):
return loads(value)
class HeatBase(object):
"""Base class for Heat Models."""
__table_args__ = {'mysql_engine': 'InnoDB'}
@ -94,6 +96,7 @@ class HeatBase(object):
local.update(joined)
return local.iteritems()
class RawTemplate(BASE, HeatBase):
"""Represents an unparsed template which should be in JSON format."""
@ -101,17 +104,21 @@ class RawTemplate(BASE, HeatBase):
id = Column(Integer, primary_key=True)
template = Column(Json)
parsed_template = relationship("ParsedTemplate",\
uselist=False, backref="raw_template", cascade="all, delete", passive_deletes=True)
uselist=False, backref="raw_template",
cascade="all, delete",
passive_deletes=True)
class ParsedTemplate(BASE, HeatBase):
"""Represents a parsed template."""
__tablename__ = 'parsed_template'
id = Column(Integer, primary_key=True)
id = Column(Integer, primary_key=True)
template = Column(Json)
raw_template_id = Column(Integer, ForeignKey('raw_template.id'),\
nullable=False)
class Stack(BASE, HeatBase):
"""Represents an generated by the heat engine."""
@ -124,6 +131,7 @@ class Stack(BASE, HeatBase):
raw_template = relationship(RawTemplate,
backref=backref('stack'), cascade="all, delete", passive_deletes=True)
class Event(BASE, HeatBase):
"""Represents an event generated by the heat engine."""
@ -134,9 +142,10 @@ class Event(BASE, HeatBase):
nullable=False)
stack = relationship(Stack,
backref=backref('events'), cascade="all, delete", passive_deletes=True)
name = Column(String)
class Resource(BASE, HeatBase):
"""Represents a resource created by the heat engine."""
@ -149,11 +158,12 @@ class Resource(BASE, HeatBase):
state_description = Column('state_description', String)
parsed_template_id = Column(Integer, ForeignKey('parsed_template.id'),\
nullable=True)
parsed_template = relationship(ParsedTemplate,
parsed_template = relationship(ParsedTemplate,
backref=backref('resources'))
stack_id = Column(Integer, ForeignKey('stack.id'),\
nullable=False)
stack = relationship(Stack, backref=backref('resources'), cascade="all, delete", passive_deletes=True)
stack = relationship(Stack, backref=backref('resources'),
cascade="all, delete", passive_deletes=True)
depends_on = Column(Integer)

@ -90,8 +90,10 @@ def get_maker(engine, autocommit=True, expire_on_commit=False):
autocommit=autocommit,
expire_on_commit=expire_on_commit)
def _get_sql_connection():
return db_api.SQL_CONNECTION
def _get_sql_idle_timeout():
return db_api.SQL_IDLE_TIMEOUT

@ -1,2 +1 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4

@ -29,6 +29,7 @@ from heat.engine import parser
from heat.db import api as db_api
logger = logging.getLogger('heat.engine.manager')
class EngineManager(manager.Manager):
"""
Manages the running instances from creation to destruction.
@ -52,7 +53,7 @@ class EngineManager(manager.Manager):
arg2 -> Dict of http request parameters passed in from API side.
"""
logger.info('context is %s' % context)
res = {'stacks': [] }
res = {'stacks': []}
stacks = db_api.stack_get_all(None)
if stacks == None:
return res
@ -62,7 +63,8 @@ class EngineManager(manager.Manager):
mem['stack_id'] = s.id
mem['stack_name'] = s.name
mem['created_at'] = str(s.created_at)
mem['template_description'] = ps.t.get('Description', 'No description')
mem['template_description'] = ps.t.get('Description',
'No description')
mem['stack_status'] = ps.t.get('StackStatus', 'unknown')
res['stacks'].append(mem)
@ -75,7 +77,7 @@ class EngineManager(manager.Manager):
arg2 -> Name of the stack you want to see.
arg3 -> Dict of http request parameters passed in from API side.
"""
res = {'stacks': [] }
res = {'stacks': []}
s = db_api.stack_get(None, stack_name)
if s:
ps = parser.Stack(s.name, s.raw_template.template, params)
@ -89,7 +91,8 @@ class EngineManager(manager.Manager):
mem['Parameters'] = ps.t['Parameters']
mem['StackStatusReason'] = 'TODO'
mem['TimeoutInMinutes'] = 'TODO'
mem['TemplateDescription'] = ps.t.get('Description', 'No description')
mem['TemplateDescription'] = ps.t.get('Description',
'No description')
mem['StackStatus'] = ps.t.get('StackStatus', 'unknown')
res['stacks'].append(mem)
@ -97,7 +100,8 @@ class EngineManager(manager.Manager):
def create_stack(self, context, stack_name, template, params):
"""
The create_stack method creates a new stack using the template provided.
The create_stack method creates a new stack using the template
provided.
Note that at this stage the template has already been fetched from the
heat-api process if using a template-url.
arg1 -> RPC context.

@ -23,30 +23,25 @@ from heat.db import api as db_api
logger = logging.getLogger('heat.engine.parser')
class Stack(object):
def __init__(self, stack_name, template, parms=None):
self.id = 0
self.t = template
if self.t.has_key('Parameters'):
self.parms = self.t['Parameters']
else:
self.parms = {}
if self.t.has_key('Mappings'):
self.maps = self.t['Mappings']
else:
self.maps = {}
if self.t.has_key('Outputs'):
self.outputs = self.t['Outputs']
else:
self.outputs = {}
self.parms = self.t.get('Parameters', {})
self.maps = self.t.get('Mappings', {})
self.outputs = self.t.get('Outputs', {})
self.res = {}
self.doc = None
self.name = stack_name
self.parms['AWS::Region'] = {"Description" : "AWS Regions", "Type" : "String", "Default" : "ap-southeast-1",
"AllowedValues" : ["us-east-1","us-west-1","us-west-2","sa-east-1","eu-west-1","ap-southeast-1","ap-northeast-1"],
"ConstraintDescription" : "must be a valid EC2 instance type." }
self.parms['AWS::Region'] = {"Description": "AWS Regions",
"Type": "String",
"Default": "ap-southeast-1",
"AllowedValues": ["us-east-1", "us-west-1", "us-west-2",
"sa-east-1", "eu-west-1", "ap-southeast-1",
"ap-northeast-1"],
"ConstraintDescription": "must be a valid EC2 instance type." }
if parms != None:
self._apply_user_parameters(parms)
@ -63,19 +58,26 @@ class Stack(object):
for r in self.t['Resources']:
type = self.t['Resources'][r]['Type']
if type == 'AWS::EC2::Instance':
self.resources[r] = resources.Instance(r, self.t['Resources'][r], self)
self.resources[r] = resources.Instance(r,
self.t['Resources'][r], self)
elif type == 'AWS::EC2::Volume':
self.resources[r] = resources.Volume(r, self.t['Resources'][r], self)
self.resources[r] = resources.Volume(r,
self.t['Resources'][r], self)
elif type == 'AWS::EC2::VolumeAttachment':
self.resources[r] = resources.VolumeAttachment(r, self.t['Resources'][r], self)
self.resources[r] = resources.VolumeAttachment(r,
self.t['Resources'][r], self)
elif type == 'AWS::EC2::EIP':
self.resources[r] = resources.ElasticIp(r, self.t['Resources'][r], self)
self.resources[r] = resources.ElasticIp(r,
self.t['Resources'][r], self)
elif type == 'AWS::EC2::EIPAssociation':
self.resources[r] = resources.ElasticIpAssociation(r, self.t['Resources'][r], self)
self.resources[r] = resources.ElasticIpAssociation(r,
self.t['Resources'][r], self)
elif type == 'AWS::EC2::SecurityGroup':
self.resources[r] = resources.SecurityGroup(r, self.t['Resources'][r], self)
self.resources[r] = resources.SecurityGroup(r,
self.t['Resources'][r], self)
else:
self.resources[r] = resources.GenericResource(r, self.t['Resources'][r], self)
self.resources[r] = resources.GenericResource(r,
self.t['Resources'][r], self)
self.calulate_dependencies(self.t['Resources'][r], self.resources[r])
@ -96,14 +98,8 @@ class Stack(object):
res = jp['member']
res['NoEcho'] = 'false'
res['ParameterKey'] = p
if self.parms[p].has_key('Description'):
res['Description'] = self.parms[p]['Description']
else:
res['Description'] = ''
if self.parms[p].has_key('Default'):
res['DefaultValue'] = self.parms[p]['Default']
else:
res['DefaultValue'] = ''
res['Description'] = self.parms[p].get('Description', '')
res['DefaultValue'] = self.parms[p].get('Default', '')
response['ValidateTemplateResult']['Parameters'].append(res)
return response
@ -185,15 +181,10 @@ class Stack(object):
outs = []
for o in self.outputs:
out = {}
if self.outputs[o].has_key('Description'):
out['Description'] = self.outputs[o]['Description']
else:
out['Description'] = 'No description given'
out['Description'] = self.outputs[o].get('Description',
'No description given')
out['OutputKey'] = o
if self.outputs[o].has_key('Value'):
out['OutputValue'] = self.outputs[o]['Value']
else:
out['OutputValue'] = ''
out['OutputValue'] = self.outputs[o].get('Value', '')
outs.append(out)
return outs
@ -220,7 +211,7 @@ class Stack(object):
def _apply_user_parameter(self, key, value):
logger.debug('appling user parameter %s=%s ' % (key, value))
if not self.parms.has_key(key):
if not key in self.parms:
self.parms[key] = {}
self.parms[key]['Value'] = value
@ -231,16 +222,17 @@ class Stack(object):
try:
key_name = 'Parameters.member.%s.ParameterKey' % s[2]
value_name = 'Parameters.member.%s.ParameterValue' % s[2]
self._apply_user_parameter(parms[key_name], parms[value_name])
self._apply_user_parameter(parms[key_name],
parms[value_name])
except Exception:
logger.error('Could not apply parameter %s' % p)
def parameter_get(self, key):
if self.parms[key] == None:
raise exception.UserParameterMissing(key=key)
elif self.parms[key].has_key('Value'):
elif 'Value' in self.parms[key]:
return self.parms[key]['Value']
elif self.parms[key].has_key('Default'):
elif 'Default' in self.parms[key]:
return self.parms[key]['Default']
else:
raise exception.UserParameterMissing(key=key)
@ -253,7 +245,7 @@ class Stack(object):
for i in s:
if i == 'Ref' and \
isinstance(s[i], (basestring, unicode)) and \
self.parms.has_key(s[i]):
s[i] in self.parms:
return self.parameter_get(s[i])
else:
s[i] = self.resolve_static_refs(s[i])
@ -298,7 +290,7 @@ class Stack(object):
'''
if isinstance(s, dict):
for i in s:
if i == 'Ref' and self.resources.has_key(s[i]):
if i == 'Ref' and s[i] in self.resources:
return self.resources[s[i]].FnGetRefId()
elif i == 'Fn::GetAtt':
resource_name = s[i][0]
@ -351,5 +343,3 @@ class Stack(object):
for index, item in enumerate(s):
s[index] = self.resolve_base64(item)
return s

@ -49,6 +49,7 @@ else:
cloudinit_path = '%s/heat/%s/' % (p, "cloudinit")
break
class Resource(object):
CREATE_IN_PROGRESS = 'CREATE_IN_PROGRESS'
CREATE_FAILED = 'CREATE_FAILED'
@ -77,7 +78,7 @@ class Resource(object):
self.id = None
self._nova = {}
if not self.t.has_key('Properties'):
if not 'Properties' in self.t:
# make a dummy entry to prevent having to check all over the
# place for it.
self.t['Properties'] = {}
@ -86,7 +87,7 @@ class Resource(object):
stack.resolve_find_in_map(self.t)
def nova(self, service_type='compute'):
if self._nova.has_key(service_type):
if service_type in self._nova:
return self._nova[service_type]
username = self.stack.creds['username']
@ -98,9 +99,10 @@ class Resource(object):
else:
service_name = None
self._nova[service_type] = client.Client(username, password, tenant, auth_url,
service_type=service_type, service_name=service_name)
self._nova[service_type] = client.Client(username, password, tenant,
auth_url,
service_type=service_type,
service_name=service_name)
return self._nova[service_type]
def create(self):
@ -146,8 +148,10 @@ class Resource(object):
self.state = new_state
def delete(self):
print 'deleting %s name:%s inst:%s db_id:%s' % (self.t['Type'], self.name,
self.instance_id, str(self.id))
print 'deleting %s name:%s inst:%s db_id:%s' % (self.t['Type'],
self.name,
self.instance_id,
str(self.id))
def reload(self):
pass
@ -173,6 +177,7 @@ http://docs.amazonwebservices.com/AWSCloudFormation/latest/UserGuide/intrinsic-f
'''
return base64.b64encode(data)
class GenericResource(Resource):
def __init__(self, name, json_snippet, stack):
super(GenericResource, self).__init__(name, json_snippet, stack)
@ -185,13 +190,14 @@ class GenericResource(Resource):
print 'creating GenericResource %s' % self.name
self.state_set(self.CREATE_COMPLETE)
class SecurityGroup(Resource):
def __init__(self, name, json_snippet, stack):
super(SecurityGroup, self).__init__(name, json_snippet, stack)
self.instance_id = ''
if self.t['Properties'].has_key('GroupDescription'):
if 'GroupDescription' in self.t['Properties']:
self.description = self.t['Properties']['GroupDescription']
else:
self.description = ''
@ -205,7 +211,7 @@ class SecurityGroup(Resource):
sec = self.nova().security_groups.create(self.name, self.description)
self.instance_id_set(sec.id)
if self.t['Properties'].has_key('SecurityGroupIngress'):
if 'SecurityGroupIngress' in self.t['Properties']:
for i in self.t['Properties']['SecurityGroupIngress']:
rule = self.nova().security_group_rules.create(sec.id,
i['IpProtocol'],
@ -215,7 +221,8 @@ class SecurityGroup(Resource):
self.state_set(self.CREATE_COMPLETE)
def delete(self):
if self.state == self.DELETE_IN_PROGRESS or self.state == self.DELETE_COMPLETE:
if self.state == self.DELETE_IN_PROGRESS or \
self.state == self.DELETE_COMPLETE:
return
self.state_set(self.DELETE_IN_PROGRESS)
@ -235,13 +242,14 @@ class SecurityGroup(Resource):
def FnGetRefId(self):
return unicode(self.name)
class ElasticIp(Resource):
def __init__(self, name, json_snippet, stack):
super(ElasticIp, self).__init__(name, json_snippet, stack)
self.instance_id = ''
self.ipaddress = ''
if self.t.has_key('Properties') and self.t['Properties'].has_key('Domain'):
if 'Domain' in self.t['Properties']:
logger.warn('*** can\'t support Domain %s yet' % (self.t['Properties']['Domain']))
def create(self):
@ -259,7 +267,8 @@ class ElasticIp(Resource):
def delete(self):
"""De-allocate a floating IP."""
if self.state == self.DELETE_IN_PROGRESS or self.state == self.DELETE_COMPLETE:
if self.state == self.DELETE_IN_PROGRESS or \
self.state == self.DELETE_COMPLETE:
return
self.state_set(self.DELETE_IN_PROGRESS)
@ -279,12 +288,13 @@ class ElasticIp(Resource):
else:
raise exception.InvalidTemplateAttribute(resource=self.name, key=key)
class ElasticIpAssociation(Resource):
def __init__(self, name, json_snippet, stack):
super(ElasticIpAssociation, self).__init__(name, json_snippet, stack)
def FnGetRefId(self):
if not self.t['Properties'].has_key('EIP'):
if not 'EIP' in self.t['Properties']:
return unicode('0.0.0.0')
else:
return unicode(self.t['Properties']['EIP'])
@ -306,7 +316,8 @@ class ElasticIpAssociation(Resource):
def delete(self):
"""Remove a floating IP address from a server."""
if self.state == self.DELETE_IN_PROGRESS or self.state == self.DELETE_COMPLETE:
if self.state == self.DELETE_IN_PROGRESS or \
self.state == self.DELETE_COMPLETE:
return
self.state_set(self.DELETE_IN_PROGRESS)
@ -342,7 +353,8 @@ class Volume(Resource):
self.state_set(self.CREATE_FAILED)
def delete(self):
if self.state == self.DELETE_IN_PROGRESS or self.state == self.DELETE_COMPLETE:
if self.state == self.DELETE_IN_PROGRESS or \
self.state == self.DELETE_COMPLETE:
return
if self.instance_id != None:
@ -358,6 +370,7 @@ class Volume(Resource):
self.nova('volume').volumes.delete(self.instance_id)
self.state_set(self.DELETE_COMPLETE)
class VolumeAttachment(Resource):
def __init__(self, name, json_snippet, stack):
super(VolumeAttachment, self).__init__(name, json_snippet, stack)
@ -369,9 +382,10 @@ class VolumeAttachment(Resource):
self.state_set(self.CREATE_IN_PROGRESS)
super(VolumeAttachment, self).create()
print 'Attaching InstanceId %s VolumeId %s Device %s' % (self.t['Properties']['InstanceId'],
self.t['Properties']['VolumeId'],
self.t['Properties']['Device'])
print 'Attaching InstanceId %s VolumeId %s Device %s' % \
(self.t['Properties']['InstanceId'],
self.t['Properties']['VolumeId'],
self.t['Properties']['Device'])
va = self.nova().volumes.create_server_volume(server_id=self.t['Properties']['InstanceId'],
volume_id=self.t['Properties']['VolumeId'],
device=self.t['Properties']['Device'])
@ -387,7 +401,8 @@ class VolumeAttachment(Resource):
self.state_set(self.CREATE_FAILED)
def delete(self):
if self.state == self.DELETE_IN_PROGRESS or self.state == self.DELETE_COMPLETE:
if self.state == self.DELETE_IN_PROGRESS or \
self.state == self.DELETE_COMPLETE:
return
self.state_set(self.DELETE_IN_PROGRESS)
Resource.delete(self)
@ -411,19 +426,20 @@ class VolumeAttachment(Resource):
self.state_set(self.DELETE_COMPLETE)
class Instance(Resource):
def __init__(self, name, json_snippet, stack):
super(Instance, self).__init__(name, json_snippet, stack)
self.ipaddress = '0.0.0.0'
if not self.t['Properties'].has_key('AvailabilityZone'):
if not 'AvailabilityZone' in self.t['Properties']:
self.t['Properties']['AvailabilityZone'] = 'nova'
self.itype_oflavor = {'t1.micro': 'm1.tiny',
'm1.small': 'm1.small',
'm1.medium': 'm1.medium',
'm1.large': 'm1.large',
'm1.xlarge': 'm1.tiny', # TODO(sdake)
'm1.xlarge': 'm1.tiny', # TODO(sdake)
'm2.xlarge': 'm1.xlarge',
'm2.2xlarge': 'm1.large',
'm2.4xlarge': 'm1.large',
@ -432,7 +448,6 @@ class Instance(Resource):
'cc2.8xlarge