Fix a heap of pep8 errors

./run_tests.sh is much cleaner now.

Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
This commit is contained in:
Angus Salkeld 2012-04-16 17:07:07 +10:00
parent b7b29add11
commit dfe12cbaba
25 changed files with 248 additions and 133 deletions

View File

@ -40,7 +40,8 @@ with open(filename) as f:
# Don't immediately see a way to have key name as a parameter and also # Don't immediately see a way to have key name as a parameter and also
# file injection and monitoring # file injection and monitoring
# need to insert key on creation and know what private key is # 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, 'AWS::StackName', stack_name)
setparam(params_dict, 'InstanceType', 'm1.xlarge') setparam(params_dict, 'InstanceType', 'm1.xlarge')

View File

@ -21,10 +21,12 @@ from heat.common import wsgi
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class API(wsgi.Router): 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): def __init__(self, conf, **local_conf):
self.conf = conf self.conf = conf
@ -49,6 +51,7 @@ class API(wsgi.Router):
mapper.connect("/DescribeStackEvents", controller=stacks_resource, mapper.connect("/DescribeStackEvents", controller=stacks_resource,
action="events_list", conditions=dict(method=["GET"])) action="events_list", conditions=dict(method=["GET"]))
mapper.connect("/ValidateTemplate", controller=stacks_resource, 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) super(API, self).__init__(mapper)

View File

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

View File

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

View File

@ -1,8 +1,11 @@
#part-handler #part-handler
def list_types(): def list_types():
return(["text/x-cfninitdata"]) return(["text/x-cfninitdata"])
def handle_part(data,ctype,filename,payload):
def handle_part(data, ctype, filename, payload):
if ctype == "__begin__": if ctype == "__begin__":
return return
if ctype == "__end__": if ctype == "__end__":

View File

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

View File

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

View File

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

View File

@ -27,6 +27,8 @@ supported backend.
''' '''
from heat.openstack.common import utils from heat.openstack.common import utils
def configure(conf): def configure(conf):
global IMPL global IMPL
global SQL_CONNECTION global SQL_CONNECTION
@ -35,12 +37,15 @@ def configure(conf):
SQL_CONNECTION = conf.sql_connection SQL_CONNECTION = conf.sql_connection
SQL_IDLE_TIMEOUT = conf.sql_idle_timeout SQL_IDLE_TIMEOUT = conf.sql_idle_timeout
def raw_template_get(context, template_id): def raw_template_get(context, template_id):
return IMPL.raw_template_get(context, template_id) return IMPL.raw_template_get(context, template_id)
def raw_template_get_all(context): def raw_template_get_all(context):
return IMPL.raw_template_get_all(context) return IMPL.raw_template_get_all(context)
def raw_template_create(context, values): def raw_template_create(context, values):
return IMPL.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): def parsed_template_get(context, template_id):
return IMPL.parsed_template_get(context, template_id) return IMPL.parsed_template_get(context, template_id)
def parsed_template_get_all(context): def parsed_template_get_all(context):
return IMPL.parsed_template_get_all(context) return IMPL.parsed_template_get_all(context)
def parsed_template_create(context, values): def parsed_template_create(context, values):
return IMPL.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): def resource_get(context, resource_id):
return IMPL.resource_get(context, resource_id) return IMPL.resource_get(context, resource_id)
def resource_get_all(context): def resource_get_all(context):
return IMPL.resource_get_all(context) return IMPL.resource_get_all(context)
def resource_create(context, values): def resource_create(context, values):
return IMPL.resource_create(context, values) return IMPL.resource_create(context, values)
def resource_get_all_by_stack(context, stack_id): def resource_get_all_by_stack(context, stack_id):
return IMPL.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): 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): def stack_get(context, stack_id):
return IMPL.stack_get(context, stack_id) return IMPL.stack_get(context, stack_id)
def stack_get_all(context): def stack_get_all(context):
return IMPL.stack_get_all(context) return IMPL.stack_get_all(context)
def stack_create(context, values): def stack_create(context, values):
return IMPL.stack_create(context, values) return IMPL.stack_create(context, values)
def stack_delete(context, stack_name): def stack_delete(context, stack_name):
return IMPL.stack_delete(context, stack_name) return IMPL.stack_delete(context, stack_name)
def event_get(context, event_id): def event_get(context, event_id):
return IMPL.event_get(context, event_id) return IMPL.event_get(context, event_id)
def event_get_all(context): def event_get_all(context):
return IMPL.event_get_all(context) return IMPL.event_get_all(context)
def event_get_all_by_stack(context, stack_id): def event_get_all_by_stack(context, stack_id):
return IMPL.event_get_all_by_stack(context, stack_id) return IMPL.event_get_all_by_stack(context, stack_id)
def event_create(context, values): def event_create(context, values):
return IMPL.event_create(context, values) return IMPL.event_create(context, values)

View File

@ -19,6 +19,7 @@ from sqlalchemy.orm.session import Session
from heat.db.sqlalchemy import models from heat.db.sqlalchemy import models
from heat.db.sqlalchemy.session import get_session from heat.db.sqlalchemy.session import get_session
def model_query(context, *args, **kwargs): def model_query(context, *args, **kwargs):
""" """
:param session: if present, the session to use :param session: if present, the session to use
@ -29,6 +30,7 @@ def model_query(context, *args, **kwargs):
return query return query
def raw_template_get(context, template_id): def raw_template_get(context, template_id):
result = model_query(context, models.RawTemplate).\ result = model_query(context, models.RawTemplate).\
filter_by(id=template_id).first() filter_by(id=template_id).first()
@ -38,6 +40,7 @@ def raw_template_get(context, template_id):
return result return result
def raw_template_get_all(context): def raw_template_get_all(context):
results = model_query(context, models.RawTemplate).all() results = model_query(context, models.RawTemplate).all()
@ -46,12 +49,14 @@ def raw_template_get_all(context):
return results return results
def raw_template_create(context, values): def raw_template_create(context, values):
raw_template_ref = models.RawTemplate() raw_template_ref = models.RawTemplate()
raw_template_ref.update(values) raw_template_ref.update(values)
raw_template_ref.save() raw_template_ref.save()
return raw_template_ref return raw_template_ref
def parsed_template_get(context, template_id): def parsed_template_get(context, template_id):
result = model_query(context, models.ParsedTemplate).\ result = model_query(context, models.ParsedTemplate).\
filter_by(id=template_id).first() filter_by(id=template_id).first()
@ -61,6 +66,7 @@ def parsed_template_get(context, template_id):
return result return result
def parsed_template_get_all(context): def parsed_template_get_all(context):
results = model_query(context, models.ParsedTemplate).all() results = model_query(context, models.ParsedTemplate).all()
@ -69,12 +75,14 @@ def parsed_template_get_all(context):
return results return results
def parsed_template_create(context, values): def parsed_template_create(context, values):
parsed_template_ref = models.ParsedTemplate() parsed_template_ref = models.ParsedTemplate()
parsed_template_ref.update(values) parsed_template_ref.update(values)
parsed_template_ref.save() parsed_template_ref.save()
return parsed_template_ref return parsed_template_ref
def resource_get(context, resource_id): def resource_get(context, resource_id):
result = model_query(context, models.Resource).\ result = model_query(context, models.Resource).\
filter_by(id=resource_id).first() filter_by(id=resource_id).first()
@ -84,6 +92,7 @@ def resource_get(context, resource_id):
return result return result
def resource_get_by_name_and_stack(context, resource_name, stack_id): def resource_get_by_name_and_stack(context, resource_name, stack_id):
result = model_query(context, models.Resource).\ result = model_query(context, models.Resource).\
filter_by(name=resource_name).\ filter_by(name=resource_name).\
@ -91,6 +100,7 @@ def resource_get_by_name_and_stack(context, resource_name, stack_id):
return result return result
def resource_get_all(context): def resource_get_all(context):
results = model_query(context, models.Resource).all() results = model_query(context, models.Resource).all()
@ -99,12 +109,14 @@ def resource_get_all(context):
return results return results
def resource_create(context, values): def resource_create(context, values):
resource_ref = models.Resource() resource_ref = models.Resource()
resource_ref.update(values) resource_ref.update(values)
resource_ref.save() resource_ref.save()
return resource_ref return resource_ref
def resource_get_all_by_stack(context, stack_id): def resource_get_all_by_stack(context, stack_id):
results = model_query(context, models.Resource).\ results = model_query(context, models.Resource).\
filter_by(stack_id=stack_id).all() filter_by(stack_id=stack_id).all()
@ -114,21 +126,25 @@ def resource_get_all_by_stack(context, stack_id):
return results return results
def stack_get(context, stack_id): def stack_get(context, stack_id):
result = model_query(context, models.Stack).\ result = model_query(context, models.Stack).\
filter_by(name=stack_id).first() filter_by(name=stack_id).first()
return result return result
def stack_get_all(context): def stack_get_all(context):
results = model_query(context, models.Stack).all() results = model_query(context, models.Stack).all()
return results return results
def stack_create(context, values): def stack_create(context, values):
stack_ref = models.Stack() stack_ref = models.Stack()
stack_ref.update(values) stack_ref.update(values)
stack_ref.save() stack_ref.save()
return stack_ref return stack_ref
def stack_delete(context, stack_name): def stack_delete(context, stack_name):
s = stack_get(context, stack_name) s = stack_get(context, stack_name)
if not s: if not s:
@ -145,23 +161,27 @@ def stack_delete(context, stack_name):
session.delete(s) session.delete(s)
session.flush() session.flush()
def event_get(context, event_id): def event_get(context, event_id):
result = model_query(context, models.Event).\ result = model_query(context, models.Event).\
filter_by(id=event_id).first() filter_by(id=event_id).first()
return result return result
def event_get_all(context): def event_get_all(context):
results = model_query(context, models.Event).all() results = model_query(context, models.Event).all()
return results return results
def event_get_all_by_stack(context, stack_id): def event_get_all_by_stack(context, stack_id):
results = model_query(context, models.Event).\ results = model_query(context, models.Event).\
filter_by(stack_id=stack_id).all() filter_by(stack_id=stack_id).all()
return results return results
def event_create(context, values): def event_create(context, values):
event_ref = models.Event() event_ref = models.Event()
event_ref.update(values) event_ref.update(values)

View File

@ -2,4 +2,5 @@
from migrate.versioning.shell import main from migrate.versioning.shell import main
if __name__ == '__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')

View File

@ -1,6 +1,7 @@
from sqlalchemy import * from sqlalchemy import *
from migrate import * from migrate import *
def upgrade(migrate_engine): def upgrade(migrate_engine):
meta = MetaData() meta = MetaData()
meta.bind = migrate_engine meta.bind = migrate_engine
@ -21,7 +22,8 @@ def upgrade(migrate_engine):
Column('name', String(length=255, convert_unicode=False, Column('name', String(length=255, convert_unicode=False,
assert_unicode=None, assert_unicode=None,
unicode_error=None, _warn_on_bytestring=False)), 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( event = Table(
@ -55,7 +57,8 @@ def upgrade(migrate_engine):
assert_unicode=None, assert_unicode=None,
unicode_error=None, unicode_error=None,
_warn_on_bytestring=False)), _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('stack_id', Integer, ForeignKey("stack.id"), nullable=False),
Column('depends_on', Integer), Column('depends_on', Integer),
) )
@ -63,7 +66,8 @@ def upgrade(migrate_engine):
parsedtemplate = Table( parsedtemplate = Table(
'parsed_template', meta, 'parsed_template', meta,
Column('id', Integer, primary_key=True), 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()), Column('template', Text()),
) )
@ -75,6 +79,7 @@ def upgrade(migrate_engine):
meta.drop_all(tables=tables) meta.drop_all(tables=tables)
raise raise
def downgrade(migrate_engine): def downgrade(migrate_engine):
meta = MetaData() meta = MetaData()
meta.bind = migrate_engine meta.bind = migrate_engine

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -49,6 +49,7 @@ else:
cloudinit_path = '%s/heat/%s/' % (p, "cloudinit") cloudinit_path = '%s/heat/%s/' % (p, "cloudinit")
break break
class Resource(object): class Resource(object):
CREATE_IN_PROGRESS = 'CREATE_IN_PROGRESS' CREATE_IN_PROGRESS = 'CREATE_IN_PROGRESS'
CREATE_FAILED = 'CREATE_FAILED' CREATE_FAILED = 'CREATE_FAILED'
@ -77,7 +78,7 @@ class Resource(object):
self.id = None self.id = None
self._nova = {} 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 # make a dummy entry to prevent having to check all over the
# place for it. # place for it.
self.t['Properties'] = {} self.t['Properties'] = {}
@ -86,7 +87,7 @@ class Resource(object):
stack.resolve_find_in_map(self.t) stack.resolve_find_in_map(self.t)
def nova(self, service_type='compute'): def nova(self, service_type='compute'):
if self._nova.has_key(service_type): if service_type in self._nova:
return self._nova[service_type] return self._nova[service_type]
username = self.stack.creds['username'] username = self.stack.creds['username']
@ -98,9 +99,10 @@ class Resource(object):
else: else:
service_name = None service_name = None
self._nova[service_type] = client.Client(username, password, tenant,
self._nova[service_type] = client.Client(username, password, tenant, auth_url, auth_url,
service_type=service_type, service_name=service_name) service_type=service_type,
service_name=service_name)
return self._nova[service_type] return self._nova[service_type]
def create(self): def create(self):
@ -146,8 +148,10 @@ class Resource(object):
self.state = new_state self.state = new_state
def delete(self): def delete(self):
print 'deleting %s name:%s inst:%s db_id:%s' % (self.t['Type'], self.name, print 'deleting %s name:%s inst:%s db_id:%s' % (self.t['Type'],
self.instance_id, str(self.id)) self.name,
self.instance_id,
str(self.id))
def reload(self): def reload(self):
pass pass
@ -173,6 +177,7 @@ http://docs.amazonwebservices.com/AWSCloudFormation/latest/UserGuide/intrinsic-f
''' '''
return base64.b64encode(data) return base64.b64encode(data)
class GenericResource(Resource): class GenericResource(Resource):
def __init__(self, name, json_snippet, stack): def __init__(self, name, json_snippet, stack):
super(GenericResource, self).__init__(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 print 'creating GenericResource %s' % self.name
self.state_set(self.CREATE_COMPLETE) self.state_set(self.CREATE_COMPLETE)
class SecurityGroup(Resource): class SecurityGroup(Resource):
def __init__(self, name, json_snippet, stack): def __init__(self, name, json_snippet, stack):
super(SecurityGroup, self).__init__(name, json_snippet, stack) super(SecurityGroup, self).__init__(name, json_snippet, stack)
self.instance_id = '' self.instance_id = ''
if self.t['Properties'].has_key('GroupDescription'): if 'GroupDescription' in self.t['Properties']:
self.description = self.t['Properties']['GroupDescription'] self.description = self.t['Properties']['GroupDescription']
else: else:
self.description = '' self.description = ''
@ -205,7 +211,7 @@ class SecurityGroup(Resource):
sec = self.nova().security_groups.create(self.name, self.description) sec = self.nova().security_groups.create(self.name, self.description)
self.instance_id_set(sec.id) 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']: for i in self.t['Properties']['SecurityGroupIngress']:
rule = self.nova().security_group_rules.create(sec.id, rule = self.nova().security_group_rules.create(sec.id,
i['IpProtocol'], i['IpProtocol'],
@ -215,7 +221,8 @@ class SecurityGroup(Resource):
self.state_set(self.CREATE_COMPLETE) self.state_set(self.CREATE_COMPLETE)
def delete(self): 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 return
self.state_set(self.DELETE_IN_PROGRESS) self.state_set(self.DELETE_IN_PROGRESS)
@ -235,13 +242,14 @@ class SecurityGroup(Resource):
def FnGetRefId(self): def FnGetRefId(self):
return unicode(self.name) return unicode(self.name)
class ElasticIp(Resource): class ElasticIp(Resource):
def __init__(self, name, json_snippet, stack): def __init__(self, name, json_snippet, stack):
super(ElasticIp, self).__init__(name, json_snippet, stack) super(ElasticIp, self).__init__(name, json_snippet, stack)
self.instance_id = '' self.instance_id = ''
self.ipaddress = '' 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'])) logger.warn('*** can\'t support Domain %s yet' % (self.t['Properties']['Domain']))
def create(self): def create(self):
@ -259,7 +267,8 @@ class ElasticIp(Resource):
def delete(self): def delete(self):
"""De-allocate a floating IP.""" """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 return
self.state_set(self.DELETE_IN_PROGRESS) self.state_set(self.DELETE_IN_PROGRESS)
@ -279,12 +288,13 @@ class ElasticIp(Resource):
else: else:
raise exception.InvalidTemplateAttribute(resource=self.name, key=key) raise exception.InvalidTemplateAttribute(resource=self.name, key=key)
class ElasticIpAssociation(Resource): class ElasticIpAssociation(Resource):
def __init__(self, name, json_snippet, stack): def __init__(self, name, json_snippet, stack):
super(ElasticIpAssociation, self).__init__(name, json_snippet, stack) super(ElasticIpAssociation, self).__init__(name, json_snippet, stack)
def FnGetRefId(self): def FnGetRefId(self):
if not self.t['Properties'].has_key('EIP'): if not 'EIP' in self.t['Properties']:
return unicode('0.0.0.0') return unicode('0.0.0.0')
else: else:
return unicode(self.t['Properties']['EIP']) return unicode(self.t['Properties']['EIP'])
@ -306,7 +316,8 @@ class ElasticIpAssociation(Resource):
def delete(self): def delete(self):
"""Remove a floating IP address from a server.""" """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 return
self.state_set(self.DELETE_IN_PROGRESS) self.state_set(self.DELETE_IN_PROGRESS)
@ -342,7 +353,8 @@ class Volume(Resource):
self.state_set(self.CREATE_FAILED) self.state_set(self.CREATE_FAILED)
def delete(self): 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 return
if self.instance_id != None: if self.instance_id != None:
@ -358,6 +370,7 @@ class Volume(Resource):
self.nova('volume').volumes.delete(self.instance_id) self.nova('volume').volumes.delete(self.instance_id)
self.state_set(self.DELETE_COMPLETE) self.state_set(self.DELETE_COMPLETE)
class VolumeAttachment(Resource): class VolumeAttachment(Resource):
def __init__(self, name, json_snippet, stack): def __init__(self, name, json_snippet, stack):
super(VolumeAttachment, self).__init__(name, json_snippet, stack) super(VolumeAttachment, self).__init__(name, json_snippet, stack)
@ -369,7 +382,8 @@ class VolumeAttachment(Resource):
self.state_set(self.CREATE_IN_PROGRESS) self.state_set(self.CREATE_IN_PROGRESS)
super(VolumeAttachment, self).create() super(VolumeAttachment, self).create()
print 'Attaching InstanceId %s VolumeId %s Device %s' % (self.t['Properties']['InstanceId'], print 'Attaching InstanceId %s VolumeId %s Device %s' % \
(self.t['Properties']['InstanceId'],
self.t['Properties']['VolumeId'], self.t['Properties']['VolumeId'],
self.t['Properties']['Device']) self.t['Properties']['Device'])
va = self.nova().volumes.create_server_volume(server_id=self.t['Properties']['InstanceId'], va = self.nova().volumes.create_server_volume(server_id=self.t['Properties']['InstanceId'],
@ -387,7 +401,8 @@ class VolumeAttachment(Resource):
self.state_set(self.CREATE_FAILED) self.state_set(self.CREATE_FAILED)
def delete(self): 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 return
self.state_set(self.DELETE_IN_PROGRESS) self.state_set(self.DELETE_IN_PROGRESS)
Resource.delete(self) Resource.delete(self)
@ -411,13 +426,14 @@ class VolumeAttachment(Resource):
self.state_set(self.DELETE_COMPLETE) self.state_set(self.DELETE_COMPLETE)
class Instance(Resource): class Instance(Resource):
def __init__(self, name, json_snippet, stack): def __init__(self, name, json_snippet, stack):
super(Instance, self).__init__(name, json_snippet, stack) super(Instance, self).__init__(name, json_snippet, stack)
self.ipaddress = '0.0.0.0' 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.t['Properties']['AvailabilityZone'] = 'nova'
self.itype_oflavor = {'t1.micro': 'm1.tiny', self.itype_oflavor = {'t1.micro': 'm1.tiny',
'm1.small': 'm1.small', 'm1.small': 'm1.small',
@ -432,7 +448,6 @@ class Instance(Resource):
'cc2.8xlarge': 'm1.large', 'cc2.8xlarge': 'm1.large',
'cg1.4xlarge': 'm1.large'} 'cg1.4xlarge': 'm1.large'}
def FnGetAtt(self, key): def FnGetAtt(self, key):
res = None res = None
@ -461,11 +476,11 @@ class Instance(Resource):
Resource.create(self) Resource.create(self)
props = self.t['Properties'] props = self.t['Properties']
if not props.has_key('KeyName'): if not 'KeyName' in props:
raise exception.UserParameterMissing(key='KeyName') raise exception.UserParameterMissing(key='KeyName')
if not props.has_key('InstanceType'): if not 'InstanceType' in props:
raise exception.UserParameterMissing(key='InstanceType') raise exception.UserParameterMissing(key='InstanceType')
if not props.has_key('ImageId'): if not 'ImageId' in props:
raise exception.UserParameterMissing(key='ImageId') raise exception.UserParameterMissing(key='ImageId')
userdata = self.t['Properties']['UserData'] userdata = self.t['Properties']['UserData']
@ -505,17 +520,21 @@ class Instance(Resource):
fp = open('%s/%s' % (cloudinit_path, 'config'), 'r') fp = open('%s/%s' % (cloudinit_path, 'config'), 'r')
msg = MIMEText(fp.read(), _subtype='cloud-config') msg = MIMEText(fp.read(), _subtype='cloud-config')
fp.close() fp.close()
msg.add_header('Content-Disposition', 'attachment', filename='cloud-config') msg.add_header('Content-Disposition', 'attachment',
filename='cloud-config')
mime_blob.attach(msg) mime_blob.attach(msg)
fp = open('%s/%s' % (cloudinit_path, 'part-handler.py'), 'r') fp = open('%s/%s' % (cloudinit_path, 'part-handler.py'), 'r')
msg = MIMEText(fp.read(), _subtype='part-handler') msg = MIMEText(fp.read(), _subtype='part-handler')
fp.close() fp.close()
msg.add_header('Content-Disposition', 'attachment', filename='part-handler.py') msg.add_header('Content-Disposition', 'attachment',
filename='part-handler.py')
mime_blob.attach(msg) mime_blob.attach(msg)
msg = MIMEText(json.dumps(self.t['Metadata']), _subtype='x-cfninitdata') msg = MIMEText(json.dumps(self.t['Metadata']),
msg.add_header('Content-Disposition', 'attachment', filename='cfn-init-data') _subtype='x-cfninitdata')
msg.add_header('Content-Disposition', 'attachment',
filename='cfn-init-data')
mime_blob.attach(msg) mime_blob.attach(msg)
msg = MIMEText(userdata, _subtype='x-shellscript') msg = MIMEText(userdata, _subtype='x-shellscript')
@ -539,7 +558,8 @@ class Instance(Resource):
self.state_set(self.CREATE_FAILED) self.state_set(self.CREATE_FAILED)
def delete(self): 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 return
self.state_set(self.DELETE_IN_PROGRESS) self.state_set(self.DELETE_IN_PROGRESS)
Resource.delete(self) Resource.delete(self)

View File

@ -171,5 +171,3 @@ class Manager(object):
for key in FLAGS: for key in FLAGS:
config[key] = FLAGS.get(key, None) config[key] = FLAGS.get(key, None)
return config return config

View File

@ -184,12 +184,14 @@ def fanout_cast_to_server(context, server_params, topic, msg):
_RPCIMPL = None _RPCIMPL = None
def configure(conf): def configure(conf):
"""Delay import of rpc_backend until FLAGS are loaded.""" """Delay import of rpc_backend until FLAGS are loaded."""
print 'configuring rpc %s' % conf.rpc_backend print 'configuring rpc %s' % conf.rpc_backend
global _RPCIMPL global _RPCIMPL
_RPCIMPL = utils.import_object(conf.rpc_backend) _RPCIMPL = utils.import_object(conf.rpc_backend)
def _get_impl(): def _get_impl():
"""Delay import of rpc_backend until FLAGS are loaded.""" """Delay import of rpc_backend until FLAGS are loaded."""
global _RPCIMPL global _RPCIMPL
@ -197,4 +199,3 @@ def _get_impl():
print 'rpc not configured' print 'rpc not configured'
return _RPCIMPL return _RPCIMPL

View File

@ -33,6 +33,7 @@ from heat.rpc import common as rpc_common
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class ConsumerBase(object): class ConsumerBase(object):
"""Consumer base class.""" """Consumer base class."""

View File

@ -38,8 +38,11 @@ from heat import version
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class Launcher(object): class Launcher(object):
"""Launch one or more services and wait for them to complete.""" """
Launch one or more services and wait for them to complete.
"""
def __init__(self): def __init__(self):
"""Initialize the service launcher. """Initialize the service launcher.

View File

@ -10,12 +10,16 @@ from nose.plugins.attrib import attr
from nose import with_setup from nose import with_setup
# module level # module level
def setUp(): def setUp():
print "test1 setup complete" print "test1 setup complete"
def tearDown(): def tearDown():
print "test1 teardown complete" print "test1 teardown complete"
@with_setup(setUp, tearDown) # test level @with_setup(setUp, tearDown) # test level
@attr(tag=['example', 'func']) @attr(tag=['example', 'func'])
@attr(speed='fast') @attr(speed='fast')
@ -23,6 +27,7 @@ def test_a():
assert 'a' == 'a' assert 'a' == 'a'
print "assert a" print "assert a"
def test_b(): def test_b():
assert 'b' == 'b' assert 'b' == 'b'
print "assert b" print "assert b"

View File

@ -9,14 +9,18 @@ import nose
from nose.plugins.attrib import attr from nose.plugins.attrib import attr
# sets attribute on all test methods # sets attribute on all test methods
@attr(tag=['example', 'class']) @attr(tag=['example', 'class'])
@attr(speed='fast') @attr(speed='fast')
class TestClass: class TestClass:
def test2(self): def test2(self):
assert 'b' == 'b' assert 'b' == 'b'
print "assert b" print "assert b"
def setUp(self): def setUp(self):
print "test2 setup complete" print "test2 setup complete"
def tearDown(self): def tearDown(self):
print "test2 teardown complete" print "test2 teardown complete"

View File

@ -9,13 +9,17 @@ import unittest
from nose.plugins.attrib import attr from nose.plugins.attrib import attr
# sets attribute on all test methods # sets attribute on all test methods
@attr(tag=['example', 'unittest']) @attr(tag=['example', 'unittest'])
@attr(speed='fast') @attr(speed='fast')
class ExampleTest(unittest.TestCase): class ExampleTest(unittest.TestCase):
def test_a(self): def test_a(self):
self.assert_(1 == 1) self.assert_(1 == 1)
def setUp(self): def setUp(self):
print "test3 setup complete" print "test3 setup complete"
def tearDown(self): def tearDown(self):
print "test3 teardown complete" print "test3 teardown complete"