def test_get_best_existing_db_resource(self, mock_cr): stack = tools.get_stack('test_stack', utils.dummy_context(), template=tools.string_template_five, convergence=True) stack.store() stack.prev_raw_template_id = 2 stack.t.id = 1 dummy_res = stack.resources['A'] a_res_2 = res.Resource('A', dummy_res.t, stack) a_res_2.current_template_id = 2 a_res_2.id = 2 a_res_3 = res.Resource('A', dummy_res.t, stack) a_res_3.current_template_id = 3 a_res_3.id = 3 a_res_1 = res.Resource('A', dummy_res.t, stack) a_res_1.current_template_id = 1 a_res_1.id = 1 existing_res = {2: a_res_2, 3: a_res_3, 1: a_res_1} stack.ext_rsrcs_db = existing_res best_res = stack._get_best_existing_rsrc_db('A') # should return resource with template id 1 which is current template self.assertEqual(a_res_1.id, best_res.id) # no resource with current template id as 1 existing_res = {2: a_res_2, 3: a_res_3} stack.ext_rsrcs_db = existing_res best_res = stack._get_best_existing_rsrc_db('A') # should return resource with template id 2 which is prev template self.assertEqual(a_res_2.id, best_res.id)
def setUp(self): super(ValidateGetAttTest, self).setUp() resource._register_class('GenericResourceType', generic_rsrc.GenericResource) env = environment.Environment() env.load({ u'resource_registry': { u'OS::Test::GenericResource': u'GenericResourceType' } }) class FakeResource(generic_rsrc.GenericResource): def FnGetAtt(self, name): pass resource._register_class('OverwrittenFnGetAttType', FakeResource) env.load({ u'resource_registry': { u'OS::Test::FakeResource': u'OverwrittenFnGetAttType' } }) self.stack = parser.Stack( utils.dummy_context(), 'test_stack', parser.Template({"HeatTemplateFormatVersion": "2012-12-12"}, env=env), stack_id=str(uuid.uuid4())) res_defn = rsrc_defn.ResourceDefinition('test_rsrc', 'OS::Test::GenericResource') self.rsrc = resource.Resource('test_rsrc', res_defn, self.stack) self.stack.add_resource(self.rsrc)
def __init__(self, context, stack_name, tmpl, env=None, stack_id=None, action=None, status=None, status_reason='', timeout_mins=60, resolve_data=True, disable_rollback=True, parent_resource=None, owner_id=None): ''' Initialise from a context, name, Template object and (optionally) Environment object. The database ID may also be initialised, if the stack is already in the database. ''' if owner_id is None: if re.match("[a-zA-Z][a-zA-Z0-9_.-]*$", stack_name) is None: raise ValueError( _('Invalid stack name %s' ' must contain only alphanumeric or ' '\"_-.\" characters, must start with alpha') % stack_name) self.id = stack_id self.owner_id = owner_id self.context = context self.clients = Clients(context) self.t = tmpl self.name = stack_name self.action = action self.status = status self.status_reason = status_reason self.timeout_mins = timeout_mins self.disable_rollback = disable_rollback self.parent_resource = parent_resource resources.initialise() self.env = env or environment.Environment({}) self.parameters = Parameters(self.name, self.t, user_params=self.env.params) self._set_param_stackid() if resolve_data: self.outputs = self.resolve_static_data(self.t[template.OUTPUTS]) else: self.outputs = {} template_resources = self.t[template.RESOURCES] self.resources = dict((name, resource.Resource(name, data, self)) for (name, data) in template_resources.items()) self.dependencies = self._get_dependencies(self.resources.itervalues())
def _make_launch_config_resource(self, name, props): lc_res_type = 'AWS::AutoScaling::LaunchConfiguration' lc_res_def = rsrc_defn.ResourceDefinition(name, lc_res_type, props) lc_res = resource.Resource(name, lc_res_def, self.stack) return lc_res
def restore(self, snapshot): ''' Restore the given snapshot, invoking handle_restore on all resources. ''' if snapshot.stack_id != self.id: self.state_set(self.RESTORE, self.FAILED, "Can't restore snapshot from other stack") return self.updated_time = datetime.datetime.utcnow() template = tmpl.Template(snapshot.data['template']) for name, defn in six.iteritems(template.resource_definitions(self)): rsrc = resource.Resource(name, defn, self) data = snapshot.data['resources'].get(name) handle_restore = getattr(rsrc, 'handle_restore', None) if callable(handle_restore): defn = handle_restore(defn, data) template.add_resource(defn, name) newstack = self.__class__(self.context, self.name, template, self.env, timeout_mins=self.timeout_mins, disable_rollback=self.disable_rollback) newstack.parameters.set_stack_id(self.identifier()) updater = scheduler.TaskRunner(self.update_task, newstack, action=self.RESTORE) updater()
def resources(self): if self._resources is None: template_resources = self.t[self.t.RESOURCES] self._resources = dict( (name, resource.Resource(name, data, self)) for (name, data) in template_resources.items()) return self._resources
def test_template_as_resource(self): """ Test that the resulting resource has the right prop and attrib schema. Note that this test requires the Wordpress_Single_Instance.yaml template in the templates directory since we want to test using a non-trivial template. """ test_templ_name = "WordPress_Single_Instance.yaml" path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'templates', test_templ_name) # check if its in the directory list vs. exists to work around # case-insensitive file systems self.assertIn(test_templ_name, os.listdir(os.path.dirname(path))) with open(path) as test_templ_file: test_templ = test_templ_file.read() self.assertTrue(test_templ, "Empty test template") self.m.StubOutWithMock(urlfetch, "get") urlfetch.get(test_templ_name, allowed_schemes=('file',))\ .AndRaise(urlfetch.URLFetchError(_('Failed to retrieve template'))) urlfetch.get(test_templ_name, allowed_schemes=('http', 'https')).AndReturn(test_templ) parsed_test_templ = template_format.parse(test_templ) self.m.ReplayAll() json_snippet = { "Type": test_templ_name, "Properties": { "KeyName": "mykeyname", "DBName": "wordpress1", "DBUsername": "******", "DBPassword": "******", "DBRootPassword": "******", "LinuxDistribution": "U10" } } stack = parser.Stack(utils.dummy_context(), 'test_stack', parser.Template(empty_template), stack_id=str(uuid.uuid4())) templ_resource = resource.Resource("test_templ_resource", json_snippet, stack) self.m.VerifyAll() self.assertIsInstance(templ_resource, template_resource.TemplateResource) for prop in parsed_test_templ.get("Parameters", {}): self.assertIn(prop, templ_resource.properties) for attrib in parsed_test_templ.get("Outputs", {}): self.assertIn(attrib, templ_resource.attributes) for k, v in json_snippet.get("Properties").items(): self.assertEqual(v, templ_resource.properties[k]) self.assertEqual( { 'WordPress_Single_Instance.yaml': 'WordPress_Single_Instance.yaml', 'resources': {} }, stack.env.user_env_as_dict()["resource_registry"]) self.assertNotIn('WordPress_Single_Instance.yaml', resources.global_env().registry._registry)
def resources(self): if self._resources is None: self._resources = dict( (name, resource.Resource(name, data, self)) for (name, data) in self.t.resource_definitions(self).items()) # There is no need to continue storing the db resources # after resource creation self._db_resources = None return self._resources
def test_resource_no_attribute_with_overwritten_fn_get_att(self): res_defn = rsrc_defn.ResourceDefinition('test_rsrc', 'OS::Test::FakeResource') self.rsrc = resource.Resource('test_rsrc', res_defn, self.stack) self.stack.add_resource(self.rsrc) self.rsrc.attributes_schema = {} func = functions.GetAtt(self.stack, 'Fn::GetAtt', [self.rsrc.name, 'Foo']) self.assertIsNone(func.validate())
def resources(self): if self._resources is None: template_resources = self.t[self.t.RESOURCES] self._resources = dict( (name, resource.Resource(name, data, self)) for (name, data) in template_resources.items()) # There is no need to continue storing the db resources # after resource creation self._db_resources = None return self._resources
def test_template_as_resource(self): """Test that resulting resource has the right prop and attrib schema. Note that this test requires the Wordpress_Single_Instance.yaml template in the templates directory since we want to test using a non-trivial template. """ test_templ_name = "WordPress_Single_Instance.yaml" path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'templates', test_templ_name) # check if its in the directory list vs. exists to work around # case-insensitive file systems self.assertIn(test_templ_name, os.listdir(os.path.dirname(path))) with open(path) as test_templ_file: test_templ = test_templ_file.read() self.assertTrue(test_templ, "Empty test template") mock_get = self.patchobject(urlfetch, "get", return_value=test_templ) parsed_test_templ = template_format.parse(test_templ) stack = parser.Stack(utils.dummy_context(), 'test_stack', template.Template(empty_template), stack_id=str(uuid.uuid4())) properties = { "KeyName": "mykeyname", "DBName": "wordpress1", "DBUsername": "******", "DBPassword": "******", "DBRootPassword": "******", "LinuxDistribution": "U10" } definition = rsrc_defn.ResourceDefinition("test_templ_resource", test_templ_name, properties) templ_resource = resource.Resource("test_templ_resource", definition, stack) self.assertIsInstance(templ_resource, template_resource.TemplateResource) for prop in parsed_test_templ.get("Parameters", {}): self.assertIn(prop, templ_resource.properties) for attrib in parsed_test_templ.get("Outputs", {}): self.assertIn(attrib, templ_resource.attributes) for k, v in properties.items(): self.assertEqual(v, templ_resource.properties[k]) self.assertEqual( { 'WordPress_Single_Instance.yaml': 'WordPress_Single_Instance.yaml', 'resources': {} }, stack.env.user_env_as_dict()["resource_registry"]) self.assertNotIn('WordPress_Single_Instance.yaml', resources.global_env().registry._registry) mock_get.assert_called_once_with(test_templ_name, allowed_schemes=('http', 'https'))
def __init__(self, context, stack_name, tmpl, parameters=None, stack_id=None, state=None, state_description='', timeout_mins=60, resolve_data=True, disable_rollback=True): ''' Initialise from a context, name, Template object and (optionally) Parameters object. The database ID may also be initialised, if the stack is already in the database. ''' if re.match("[a-zA-Z][a-zA-Z0-9_.-]*$", stack_name) is None: raise ValueError( _("Invalid stack name %s" % stack_name + ", must contain only alphanumeric or " + "\"_-.\" characters, must start with alpha")) self.id = stack_id self.context = context self.clients = Clients(context) self.t = tmpl self.name = stack_name self.state = state self.state_description = state_description self.timeout_mins = timeout_mins self.disable_rollback = disable_rollback resources.initialise() if parameters is None: parameters = Parameters(self.name, self.t) self.parameters = parameters self._set_param_stackid() if resolve_data: self.outputs = self.resolve_static_data(self.t[template.OUTPUTS]) else: self.outputs = {} template_resources = self.t[template.RESOURCES] self.resources = dict((name, resource.Resource(name, data, self)) for (name, data) in template_resources.items()) self.dependencies = self._get_dependencies(self.resources.itervalues())
def test_resource_no_attribute_with_default_fn_get_att(self): res_defn = rsrc_defn.ResourceDefinition('test_rsrc', 'ResWithStringPropAndAttr') self.rsrc = resource.Resource('test_rsrc', res_defn, self.stack) self.stack.add_resource(self.rsrc) stk_defn.update_resource_data(self.stack.defn, self.rsrc.name, self.rsrc.node_data()) self.stack.validate() func = functions.GetAtt(self.stack.defn, 'Fn::GetAtt', [self.rsrc.name, 'Bar']) ex = self.assertRaises(exception.InvalidTemplateAttribute, func.validate) self.assertEqual('The Referenced Attribute (test_rsrc Bar) ' 'is incorrect.', str(ex))
def test_template_as_resource(self): """ Test that the resulting resource has the right prop and attrib schema. Note that this test requires the Wordpress_Single_Instance.yaml template in the templates directory since we want to test using a non-trivial template. """ test_templ_name = "WordPress_Single_Instance.yaml" path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'templates', test_templ_name) # check if its in the directory list vs. exists to work around # case-insensitive file systems self.assertIn(test_templ_name, os.listdir(os.path.dirname(path))) with open(path) as test_templ_file: test_templ = test_templ_file.read() self.assertTrue(test_templ, "Empty test template") self.m.StubOutWithMock(urlfetch, "get") urlfetch.get(test_templ_name).AndReturn(test_templ) parsed_test_templ = template_format.parse(test_templ) self.m.ReplayAll() json_snippet = { "Type": test_templ_name, "Properties": { "KeyName": "mykeyname", "DBName": "wordpress1", "DBUsername": "******", "DBPassword": "******", "DBRootPassword": "******", "LinuxDistribution": "U10" } } stack = parser.Stack(None, 'test_stack', parser.Template({}), stack_id=uuidutils.generate_uuid()) templ_resource = resource.Resource("test_templ_resource", json_snippet, stack) self.m.VerifyAll() self.assertIsInstance(templ_resource, template_resource.TemplateResource) for prop in parsed_test_templ.get("Parameters", {}): self.assertIn(prop, templ_resource.properties) for attrib in parsed_test_templ.get("Outputs", {}): self.assertIn(attrib, templ_resource.attributes) for k, v in json_snippet.get("Properties").items(): self.assertEqual(v, templ_resource.properties[k])
def test_validate_subnetpool_ref_no_cidr(self): t = template_format.parse(neutron_template) props = t['resources']['sub_net']['properties'] del props['cidr'] props['subnetpool'] = {'get_resource': 'subnetpool'} props = t['resources']['sub_net']['properties'] stack = utils.parse_stack(t) snippet = rsrc_defn.ResourceDefinition('subnetpool', 'OS::Neutron::SubnetPool') res = resource.Resource('subnetpool', snippet, stack) stack.add_resource(res) self.patchobject(stack['subnetpool'], 'FnGetRefId', return_value=None) self.patchobject(stack['net'], 'FnGetRefId', return_value='fc68ea2c-b60b-4b4f-bd82-94ec81110766') rsrc = stack['sub_net'] self.assertIsNone(rsrc.validate())
def test_validate_subnetpool_ref_with_cidr(self): t = template_format.parse(neutron_template) props = t['resources']['sub_net']['properties'] props['subnetpool'] = {'get_resource': 'subnetpool'} props = t['resources']['sub_net']['properties'] stack = utils.parse_stack(t) snippet = rsrc_defn.ResourceDefinition('subnetpool', 'OS::Neutron::SubnetPool') res = resource.Resource('subnetpool', snippet, stack) stack.add_resource(res) self.patchobject(stack['subnetpool'], 'FnGetRefId', return_value=None) self.patchobject(stack['net'], 'FnGetRefId', return_value='fc68ea2c-b60b-4b4f-bd82-94ec81110766') rsrc = stack['sub_net'] ex = self.assertRaises(exception.ResourcePropertyConflict, rsrc.validate) msg = ("Cannot define the following properties at the same time: " "subnetpool, cidr.") self.assertEqual(msg, six.text_type(ex))
def test_resource_new_ok(self): snippet = {'Type': 'GenericResourceType'} res = resource.Resource('aresource', snippet, self.stack)