./run_tests.sh is much cleaner now.
Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
# 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')
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
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)
{'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)
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}
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':
return None
-
def create(self, req):
"""
Returns the following information for all stacks:
except rpc_common.RemoteError as ex:
return webob.exc.HTTPBadRequest(str(ex))
-
def validate_template(self, req):
con = context.get_admin_context()
else:
return {'DeleteStackResult': res['Error']}
-
def events_list(self, req):
"""
Returns the following information for all stacks:
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)
# 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')
-
#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')
**kwargs)
self.register_cli_opts(rpc_opts)
+
class HeatEngineConfigOpts(cfg.CommonConfigOpts):
service_opts = [
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 '
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
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
return functools.wraps(f)(wrapped)
return inner
+
class MissingCredentialError(OpenstackException):
message = _("Missing required credential: %(required)s")
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.")
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.")
"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 "
else None)
super(ServiceUnavailable, self).__init__(*args, **kwargs)
+
class RequestUriTooLong(OpenstackException):
message = _("The URI was too long.")
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.")
"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.")
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
def generate_uuid():
return str(uuid.uuid4())
+
def gen_uuid():
return uuid.uuid4()
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)
str += ('Z' if tz == 'UTC' else tz)
return str
+
class LoopingCallDone(Exception):
"""Exception to break out and stop a LoopingCall.
def wait(self):
return self.done.wait()
-
'''
from heat.openstack.common import utils
+
+
def configure(conf):
global IMPL
global SQL_CONNECTION
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)
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)
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)
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()
return query
+
def raw_template_get(context, template_id):
result = model_query(context, models.RawTemplate).\
filter_by(id=template_id).first()
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()
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()
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).\
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:
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)
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')
from sqlalchemy import *
from migrate import *
+
def upgrade(migrate_engine):
meta = MetaData()
meta.bind = 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(
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),
)
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
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)
def process_result_value(self, value, dialect):
return loads(value)
+
class HeatBase(object):
"""Base class for Heat Models."""
__table_args__ = {'mysql_engine': 'InnoDB'}
local.update(joined)
return local.iteritems()
+
class RawTemplate(BASE, HeatBase):
"""Represents an unparsed template which should be in JSON format."""
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."""
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."""
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."""
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)
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
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
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.
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
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)
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)
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)
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.
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)
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])
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
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
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
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)
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])
'''
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]
for index, item in enumerate(s):
s[index] = self.resolve_base64(item)
return s
-
-
cloudinit_path = '%s/heat/%s/' % (p, "cloudinit")
break
+
class Resource(object):
CREATE_IN_PROGRESS = 'CREATE_IN_PROGRESS'
CREATE_FAILED = 'CREATE_FAILED'
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'] = {}
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']
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):
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
'''
return base64.b64encode(data)
+
class GenericResource(Resource):
def __init__(self, name, json_snippet, stack):
super(GenericResource, self).__init__(name, json_snippet, stack)
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 = ''
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'],
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)
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):
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)
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'])
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)
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:
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)
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'])
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)
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',
'cc2.8xlarge': 'm1.large',
'cg1.4xlarge': 'm1.large'}
-
def FnGetAtt(self, key):
res = None
Resource.create(self)
props = self.t['Properties']
- if not props.has_key('KeyName'):
+ if not 'KeyName' in props:
raise exception.UserParameterMissing(key='KeyName')
- if not props.has_key('InstanceType'):
+ if not 'InstanceType' in props:
raise exception.UserParameterMissing(key='InstanceType')
- if not props.has_key('ImageId'):
+ if not 'ImageId' in props:
raise exception.UserParameterMissing(key='ImageId')
userdata = self.t['Properties']['UserData']
fp = open('%s/%s' % (cloudinit_path, 'config'), 'r')
msg = MIMEText(fp.read(), _subtype='cloud-config')
fp.close()
- msg.add_header('Content-Disposition', 'attachment', filename='cloud-config')
+ msg.add_header('Content-Disposition', 'attachment',
+ filename='cloud-config')
mime_blob.attach(msg)
fp = open('%s/%s' % (cloudinit_path, 'part-handler.py'), 'r')
msg = MIMEText(fp.read(), _subtype='part-handler')
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)
- msg = MIMEText(json.dumps(self.t['Metadata']), _subtype='x-cfninitdata')
- msg.add_header('Content-Disposition', 'attachment', filename='cfn-init-data')
+ msg = MIMEText(json.dumps(self.t['Metadata']),
+ _subtype='x-cfninitdata')
+ msg.add_header('Content-Disposition', 'attachment',
+ filename='cfn-init-data')
mime_blob.attach(msg)
msg = MIMEText(userdata, _subtype='x-shellscript')
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)
for key in FLAGS:
config[key] = FLAGS.get(key, None)
return config
-
-
_RPCIMPL = None
+
def configure(conf):
"""Delay import of rpc_backend until FLAGS are loaded."""
print 'configuring rpc %s' % conf.rpc_backend
global _RPCIMPL
_RPCIMPL = utils.import_object(conf.rpc_backend)
+
def _get_impl():
"""Delay import of rpc_backend until FLAGS are loaded."""
global _RPCIMPL
print 'rpc not configured'
return _RPCIMPL
-
LOG = logging.getLogger(__name__)
+
class ConsumerBase(object):
"""Consumer base class."""
"""init a 'topic' publisher.
"""
super(TopicPublisher, self).__init__(session,
- "%s/%s" % (config.FLAGS.control_exchange, topic))
+ "%s/%s" % (config.FLAGS.control_exchange, topic))
class FanoutPublisher(Publisher):
"""init a 'topic' publisher.
"""
super(NotifyPublisher, self).__init__(session,
- "%s/%s" % (config.FLAGS.control_exchange, topic),
+ "%s/%s" % (config.FLAGS.control_exchange, topic),
{"durable": True})
LOG = logging.getLogger(__name__)
+
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):
"""Initialize the service launcher.
from nose import with_setup
# module level
+
+
def setUp():
print "test1 setup complete"
+
def tearDown():
print "test1 teardown complete"
+
@with_setup(setUp, tearDown) # test level
@attr(tag=['example', 'func'])
@attr(speed='fast')
assert 'a' == 'a'
print "assert a"
+
def test_b():
assert 'b' == 'b'
print "assert b"
from nose.plugins.attrib import attr
# sets attribute on all test methods
+
+
@attr(tag=['example', 'class'])
@attr(speed='fast')
class TestClass:
def test2(self):
assert 'b' == 'b'
print "assert b"
+
def setUp(self):
print "test2 setup complete"
+
def tearDown(self):
print "test2 teardown complete"
from nose.plugins.attrib import attr
# sets attribute on all test methods
+
+
@attr(tag=['example', 'unittest'])
@attr(speed='fast')
class ExampleTest(unittest.TestCase):
def test_a(self):
self.assert_(1 == 1)
+
def setUp(self):
print "test3 setup complete"
+
def tearDown(self):
print "test3 teardown complete"