Пример #1
0
    def test_to_parameters(self):
        """Tests property conversion to parameter values."""
        utils.setup_dummy_db()
        stack = parser.Stack(utils.dummy_context(),
                             'test_stack',
                             parser.Template({}),
                             stack_id=uuidutils.generate_uuid())

        class DummyResource(object):
            attributes_schema = {"Foo": "A test attribute"}
            properties_schema = {
                "Foo": {
                    "Type": "String"
                },
                "AList": {
                    "Type": "List"
                },
                "ANum": {
                    "Type": "Number"
                },
                "AMap": {
                    "Type": "Map"
                }
            }

        map_prop_val = {
            "key1": "val1",
            "key2": ["lval1", "lval2", "lval3"],
            "key3": {
                "key4": 4,
                "key5": False
            }
        }
        json_snippet = {
            "Type": "test_resource.template",
            "Properties": {
                "Foo": "Bar",
                "AList": ["one", "two", "three"],
                "ANum": 5,
                "AMap": map_prop_val
            }
        }
        self.m.StubOutWithMock(template_resource.resource, "get_class")
        (template_resource.resource.get_class(
            "test_resource.template").AndReturn(DummyResource))
        self.m.ReplayAll()
        temp_res = template_resource.TemplateResource('test_t_res',
                                                      json_snippet, stack)
        self.m.VerifyAll()
        converted_params = temp_res._to_parameters()
        self.assertTrue(converted_params)
        for key in DummyResource.properties_schema:
            self.assertIn(key, converted_params)
        # verify String conversion
        self.assertEqual("Bar", converted_params.get("Foo"))
        # verify List conversion
        self.assertEqual(
            ",".join(json_snippet.get("Properties", {}).get("AList", [])),
            converted_params.get("AList"))
        # verify Number conversion
        self.assertEqual(5, converted_params.get("ANum"))
        # verify Map conversion
        self.assertEqual(map_prop_val, converted_params.get("AMap"))
Пример #2
0
    def _create_test_instance_with_nic(self, return_server, name):
        stack_name = '%s_s' % name
        t = template_format.parse(wp_template_with_nic)
        template = parser.Template(t)
        kwargs = {
            'KeyName': 'test',
            'InstanceType': 'm1.large',
            'SubnetId': '4156c7a5-e8c4-4aff-a6e1-8f3c7bc83861'
        }
        stack = parser.Stack(utils.dummy_context(),
                             stack_name,
                             template,
                             environment.Environment(kwargs),
                             stack_id=str(uuid.uuid4()))

        t['Resources']['WebServer']['Properties']['ImageId'] = 'CentOS 5.2'

        nic = network_interfaces.NetworkInterface('%s_nic' % name,
                                                  t['Resources']['nic1'],
                                                  stack)

        instance = instances.Instance('%s_name' % name,
                                      t['Resources']['WebServer'], stack)

        self.m.StubOutWithMock(nic, 'neutron')
        nic.neutron().MultipleTimes().AndReturn(FakeNeutron())

        self.m.StubOutWithMock(instance, 'nova')
        instance.nova().MultipleTimes().AndReturn(self.fc)
        self.m.StubOutWithMock(clients.OpenStackClients, 'nova')
        clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc)

        # need to resolve the template functions
        server_userdata = nova_utils.build_userdata(
            instance, instance.t['Properties']['UserData'], 'ec2-user')
        self.m.StubOutWithMock(nova_utils, 'build_userdata')
        nova_utils.build_userdata(instance,
                                  instance.t['Properties']['UserData'],
                                  'ec2-user').AndReturn(server_userdata)

        self.m.StubOutWithMock(self.fc.servers, 'create')
        self.fc.servers.create(image=1,
                               flavor=3,
                               key_name='test',
                               name=utils.PhysName(stack_name, instance.name),
                               security_groups=None,
                               userdata=server_userdata,
                               scheduler_hints=None,
                               meta=None,
                               nics=[{
                                   'port-id':
                                   '64d913c1-bcb1-42d2-8f0a-9593dbcaf251'
                               }],
                               availability_zone=None).AndReturn(return_server)
        self.m.ReplayAll()

        # create network interface
        scheduler.TaskRunner(nic.create)()
        stack["nic1"] = nic

        scheduler.TaskRunner(instance.create)()
        return instance
    def test_to_parameters(self):
        """Tests property conversion to parameter values."""
        provider = {
            'HeatTemplateFormatVersion': '2012-12-12',
            'Parameters': {
                'Foo': {
                    'Type': 'String'
                },
                'AList': {
                    'Type': 'CommaDelimitedList'
                },
                'ListEmpty': {
                    'Type': 'CommaDelimitedList'
                },
                'ANum': {
                    'Type': 'Number'
                },
                'AMap': {
                    'Type': 'Json'
                },
            },
            'Outputs': {
                'Foo': {
                    'Value': 'bar'
                },
            },
        }

        files = {'test_resource.template': json.dumps(provider)}

        class DummyResource(object):
            attributes_schema = {"Foo": "A test attribute"}
            properties_schema = {
                "Foo": {
                    "Type": "String"
                },
                "AList": {
                    "Type": "List"
                },
                "ListEmpty": {
                    "Type": "List"
                },
                "ANum": {
                    "Type": "Number"
                },
                "AMap": {
                    "Type": "Map"
                }
            }

        env = environment.Environment()
        resource._register_class('DummyResource', DummyResource)
        env.load(
            {'resource_registry': {
                'DummyResource': 'test_resource.template'
            }})
        stack = parser.Stack(utils.dummy_context(),
                             'test_stack',
                             parser.Template({}, files=files),
                             env=env,
                             stack_id=str(uuid.uuid4()))

        map_prop_val = {
            "key1": "val1",
            "key2": ["lval1", "lval2", "lval3"],
            "key3": {
                "key4": 4,
                "key5": False
            }
        }
        json_snippet = {
            "Type": "DummyResource",
            "Properties": {
                "Foo": "Bar",
                "AList": ["one", "two", "three"],
                "ListEmpty": [],
                "ANum": 5,
                "AMap": map_prop_val
            }
        }
        temp_res = template_resource.TemplateResource('test_t_res',
                                                      json_snippet, stack)
        temp_res.validate()
        converted_params = temp_res.child_params()
        self.assertTrue(converted_params)
        for key in DummyResource.properties_schema:
            self.assertIn(key, converted_params)
        # verify String conversion
        self.assertEqual("Bar", converted_params.get("Foo"))
        # verify List conversion
        self.assertEqual(
            ",".join(json_snippet.get("Properties", {}).get("AList", [])),
            converted_params.get("AList"))
        # verify Number conversion
        self.assertEqual(5, converted_params.get("ANum"))
        # verify Map conversion
        self.assertEqual(map_prop_val, converted_params.get("AMap"))
Пример #4
0
    def test_validate_volumeattach_valid(self):
        t = template_format.parse(test_template_volumeattach % 'vdq')
        stack = parser.Stack(self.ctx, 'test_stack', parser.Template(t))

        volumeattach = stack['MountPoint']
        self.assertIsNone(volumeattach.validate())
Пример #5
0
    def _create_test_instance_with_nic(self, return_server, name):
        stack_name = '%s_s' % name
        t = template_format.parse(wp_template_with_nic)
        kwargs = {
            'KeyName': 'test',
            'InstanceType': 'm1.large',
            'SubnetId': '4156c7a5-e8c4-4aff-a6e1-8f3c7bc83861'
        }
        template = parser.Template(t, env=environment.Environment(kwargs))
        stack = parser.Stack(utils.dummy_context(),
                             stack_name,
                             template,
                             stack_id=str(uuid.uuid4()))
        image_id = 'CentOS 5.2'
        t['Resources']['WebServer']['Properties']['ImageId'] = image_id

        resource_defns = stack.t.resource_definitions(stack)
        nic = net_interfaces.NetworkInterface('%s_nic' % name,
                                              resource_defns['nic1'], stack)

        instance = instances.Instance('%s_name' % name,
                                      resource_defns['WebServer'], stack)
        metadata = instance.metadata_get()

        self._mock_get_image_id_success(image_id, 1)
        self.stub_SubnetConstraint_validate()
        self.m.StubOutWithMock(nic, 'neutron')
        nic.neutron().MultipleTimes().AndReturn(FakeNeutron())

        self.m.StubOutWithMock(neutron.NeutronClientPlugin, '_create')
        neutron.NeutronClientPlugin._create().MultipleTimes().AndReturn(
            FakeNeutron())

        self.m.StubOutWithMock(nova.NovaClientPlugin, '_create')
        nova.NovaClientPlugin._create().AndReturn(self.fc)

        # need to resolve the template functions
        server_userdata = instance.client_plugin().build_userdata(
            metadata, instance.t['Properties']['UserData'], 'ec2-user')
        self.m.StubOutWithMock(nova.NovaClientPlugin, 'build_userdata')
        nova.NovaClientPlugin.build_userdata(
            metadata, instance.t['Properties']['UserData'],
            'ec2-user').AndReturn(server_userdata)

        self.m.StubOutWithMock(self.fc.servers, 'create')
        self.fc.servers.create(
            image=1,
            flavor=3,
            key_name='test',
            name=utils.PhysName(stack_name, instance.name),
            security_groups=None,
            userdata=server_userdata,
            scheduler_hints=None,
            meta=None,
            nics=[{
                'port-id': '64d913c1-bcb1-42d2-8f0a-9593dbcaf251'
            }],
            availability_zone=None,
            block_device_mapping=None).AndReturn(return_server)
        self.m.ReplayAll()

        # create network interface
        scheduler.TaskRunner(nic.create)()
        stack.resources["nic1"] = nic

        scheduler.TaskRunner(instance.create)()
        return instance
Пример #6
0
 def parse_stack(self, t):
     stack_name = 'test_stack'
     tmpl = parser.Template(t)
     self.stack = parser.Stack(self.ctx, stack_name, tmpl)
     self.stack.validate()
     self.stack.store()
    def test_lb(self):

        tmpl = template_format.parse(as_template)

        network_body = {
            "network": {
                "id": str(uuid.uuid4()),
                "name": "testnet",
                "admin_state_up": True
            }
        }
        subnet_body = {
            "subnet": {
                "name": "testsubnet",
                "id": str(uuid.uuid4()),
                "network_id": network_body['network']['id'],
                "ip_version": 4,
                "cidr": "10.0.3.0/24",
                "allocation_pools": [{
                    "start": "10.0.3.20",
                    "end": "10.0.3.150"
                }],
                "gateway_ip": "10.0.3.1"
            }
        }

        self.params["SubnetId"] = subnet_body['subnet']['id']
        mon_block = {
            'health_monitor': tmpl['Resources']['myMonitor']['Properties']
        }
        mon_block['health_monitor']['admin_state_up'] = True
        mon_ret_block = copy.deepcopy(mon_block)
        mon_ret_block['health_monitor']['id'] = str(uuid.uuid4())
        mon_ret_block['health_monitor']['status'] = 'ACTIVE'

        pool_block = {'pool': {}}
        tmp_pool_block = tmpl['Resources']['myPool']['Properties']
        for val in ['lb_method', 'protocol', 'name', 'description']:
            pool_block['pool'][val] = tmp_pool_block[val]
        pool_block['pool']['admin_state_up'] = True
        pool_block['pool']['subnet_id'] = self.params['SubnetId']
        pool_block['pool']['admin_state_up'] = True
        pool_ret_block = copy.deepcopy(pool_block)
        pool_ret_block['pool']['id'] = str(uuid.uuid4())
        pool_ret_block['pool']['status'] = 'ACTIVE'

        tmp_vip_block = tmp_pool_block.pop('vip')
        vip_block = {
            'vip': {
                'protocol': pool_block['pool']['protocol'],
                'description': tmp_vip_block['description'],
                'admin_state_up': True,
                'subnet_id': self.params['SubnetId'],
                'connection_limit': tmp_vip_block['connection_limit'],
                'pool_id': pool_ret_block['pool']['id'],
                'address': tmp_vip_block['address'],
                'protocol_port': tmp_vip_block['protocol_port'],
                'name': tmp_vip_block['name']
            }
        }
        vip_ret_block = copy.deepcopy(vip_block)
        vip_ret_block['vip']['id'] = str(uuid.uuid4())
        vip_ret_block['vip']['status'] = 'ACTIVE'

        port_block = {
            'port': {
                'network_id': network_body['network']['id'],
                'fixed_ips': [{
                    'subnet_id': subnet_body['subnet']['id'],
                }],
                'admin_state_up': True
            }
        }
        port_ret_block = copy.deepcopy(port_block)
        port_ret_block['port']['id'] = str(uuid.uuid4())

        membera_block = {
            'member': {
                'protocol_port': 8080,
                'pool_id': pool_ret_block['pool']['id'],
                'address': '1.2.3.4'
            }
        }
        membera_ret_block = copy.deepcopy(membera_block)
        membera_ret_block['member']['id'] = str(uuid.uuid4())

        memberb_block = {
            'member': {
                'protocol_port': 8080,
                'pool_id': pool_ret_block['pool']['id'],
                'address': '1.2.3.5'
            }
        }
        memberb_ret_block = copy.deepcopy(memberb_block)
        memberb_ret_block['member']['id'] = str(uuid.uuid4())

        memberc_block = {
            'member': {
                'protocol_port': 8080,
                'pool_id': pool_ret_block['pool']['id'],
                'address': '1.2.3.6'
            }
        }
        memberc_ret_block = copy.deepcopy(memberc_block)
        memberc_ret_block['member']['id'] = str(uuid.uuid4())

        class id_type(object):
            def __init__(self, id, name):
                self.id = id
                self.name = name

        instances = {}

        clients.OpenStackClients.keystone().AndReturn(
            fakes.FakeKeystoneClient())

        clients.neutronclient.Client.create_health_monitor(mon_block).\
            AndReturn(mon_ret_block)

        clients.neutronclient.Client.create_pool(pool_block).\
            AndReturn(pool_ret_block)

        clients.neutronclient.Client.associate_health_monitor(
            pool_ret_block['pool']['id'], {
                'health_monitor': {
                    'id': mon_ret_block['health_monitor']['id']
                }
            }).AndReturn(None)

        clients.neutronclient.Client.create_vip(vip_block).\
            AndReturn(vip_ret_block)

        clients.neutronclient.Client.show_pool(pool_ret_block['pool']['id']).\
            AndReturn(pool_ret_block)

        clients.neutronclient.Client.show_vip(vip_ret_block['vip']['id']).\
            AndReturn(vip_ret_block)

        clients.OpenStackClients.keystone().AndReturn(
            fakes.FakeKeystoneClient())

        clients.OpenStackClients.keystone().AndReturn(
            fakes.FakeKeystoneClient())

        parser.Stack.validate()
        instid = str(uuid.uuid4())
        instance.Instance.handle_create().AndReturn(instid)
        instance.Instance.check_create_complete(mox.IgnoreArg())\
            .AndReturn(False)
        instance.Instance.check_create_complete(mox.IgnoreArg())\
            .AndReturn(True)

        image.ImageConstraint.validate(
            mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(True)

        nova_utils.server_to_ipaddress(mox.IgnoreArg(),
                                       mox.IgnoreArg()).AndReturn('1.2.3.4')

        clients.neutronclient.Client.create_member(membera_block).\
            AndReturn(membera_ret_block)

        instances[instid] = membera_ret_block['member']['id']

        # Start of update
        clients.OpenStackClients.keystone().AndReturn(
            fakes.FakeKeystoneClient())

        parser.Stack.validate()
        instid = str(uuid.uuid4())
        instance.Instance.handle_create().AndReturn(instid)
        instance.Instance.check_create_complete(mox.IgnoreArg())\
            .AndReturn(False)
        instance.Instance.check_create_complete(mox.IgnoreArg())\
            .AndReturn(True)
        instances[instid] = memberb_ret_block['member']['id']

        instid = str(uuid.uuid4())
        instance.Instance.handle_create().AndReturn(instid)
        instance.Instance.check_create_complete(mox.IgnoreArg())\
            .AndReturn(False)
        instance.Instance.check_create_complete(mox.IgnoreArg())\
            .AndReturn(True)

        nova_utils.server_to_ipaddress(mox.IgnoreArg(),
                                       mox.IgnoreArg()).AndReturn('1.2.3.5')

        clients.neutronclient.Client.create_member(memberb_block).\
            AndReturn(memberb_ret_block)

        nova_utils.server_to_ipaddress(mox.IgnoreArg(),
                                       mox.IgnoreArg()).AndReturn('1.2.3.6')

        clients.neutronclient.Client.create_member(memberc_block).\
            AndReturn(memberc_ret_block)

        self.m.ReplayAll()

        # Start of stack create
        env = {'parameters': self.params}
        tmpl = template_format.parse(as_template)

        stack = parser.Stack(self.ctx, 'update_test_stack',
                             template.Template(tmpl),
                             environment.Environment(env))

        stack.store()
        stack.create()
        self.assertEqual((parser.Stack.CREATE, parser.Stack.COMPLETE),
                         stack.state)

        # Start of stack update
        stack2 = parser.Stack.load(self.ctx, stack_id=stack.id)

        tmpl2 = copy.deepcopy(tmpl)
        tmpl2['Resources']['SvrGrp']['Properties']['DesiredCapacity'] = '3'

        update_stack = parser.Stack(self.ctx, 'update_test_stack',
                                    template.Template(tmpl2),
                                    environment.Environment(env))
        stack2.update(update_stack)
        self.assertEqual((parser.Stack.UPDATE, parser.Stack.COMPLETE),
                         stack2.state)

        members = db_api.resource_data_get_all(stack['ElasticLoadBalancer'])
        self.assertEqual(3, len(members.keys()))

        self.m.VerifyAll()
Пример #8
0
    def create_stack(self, cnxt, stack_name, template, params, files, args):
        """
        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.

        :param cnxt: RPC context.
        :param stack_name: Name of the stack you want to create.
        :param template: Template of stack you want to create.
        :param params: Stack Input Params
        :param files: Files referenced from the template
        :param args: Request parameters/args passed from API
        """
        logger.info(_('template is %s') % template)

        def _stack_create(stack):
            # Create/Adopt a stack, and create the periodic task if successful
            if stack.adopt_stack_data:
                stack.adopt()
            else:
                stack.create()

            if (stack.action in (stack.CREATE, stack.ADOPT)
                    and stack.status == stack.COMPLETE):
                # Schedule a periodic watcher task for this stack
                self._start_watch_task(stack.id, cnxt)
            else:
                logger.warning(_("Stack create failed, status %s") %
                               stack.status)

        if db_api.stack_get_by_name(cnxt, stack_name):
            raise exception.StackExists(stack_name=stack_name)
        tenant_limit = cfg.CONF.max_stacks_per_tenant
        if db_api.stack_count_all_by_tenant(cnxt) >= tenant_limit:
            message = _("You have reached the maximum stacks per tenant, %d."
                        " Please delete some stacks.") % tenant_limit
            raise exception.RequestLimitExceeded(message=message)

        tmpl = parser.Template(template, files=files)

        if len(tmpl[tmpl.RESOURCES]) > cfg.CONF.max_resources_per_stack:
            raise exception.RequestLimitExceeded(
                message=exception.StackResourceLimitExceeded.msg_fmt)

        # Extract the common query parameters
        common_params = api.extract_args(args)
        env = environment.Environment(params)
        stack = parser.Stack(cnxt, stack_name, tmpl,
                             env, **common_params)

        self._validate_deferred_auth_context(cnxt, stack)

        stack.validate()

        stack.store()

        self.thread_group_mgr.start_with_lock(cnxt, stack, self.engine_id,
                                              _stack_create, stack)

        return dict(stack.identifier())
Пример #9
0
 def test_state_defaults(self):
     stack = parser.Stack(None, 'test_stack', parser.Template({}))
     self.assertEqual(stack.state, None)
     self.assertEqual(stack.state_description, '')
Пример #10
0
 def test_created_time(self):
     self.stack = parser.Stack(self.ctx, 'creation_time_test',
                               parser.Template({}))
     self.assertEqual(self.stack.created_time, None)
     self.stack.store()
     self.assertNotEqual(self.stack.created_time, None)
Пример #11
0
    def test_update_by_reference_and_rollback_2(self):
        '''
        assertion:
        check that rollback still works with dynamic metadata
        this test fails the second instance
        '''
        # patch in a dummy property schema for GenericResource
        dummy_schema = {'Foo': {'Type': 'String'}}
        generic_rsrc.GenericResource.properties_schema = dummy_schema
        tmpl = {
            'Resources': {
                'AResource': {
                    'Type': 'GenericResourceType',
                    'Properties': {
                        'Foo': 'abc'
                    }
                },
                'BResource': {
                    'Type': 'GenericResourceType',
                    'Properties': {
                        'Foo': {
                            'Ref': 'AResource'
                        }
                    }
                }
            }
        }
        tmpl2 = {
            'Resources': {
                'AResource': {
                    'Type': 'GenericResourceType',
                    'Properties': {
                        'Foo': 'smelly'
                    }
                },
                'BResource': {
                    'Type': 'GenericResourceType',
                    'Properties': {
                        'Foo': {
                            'Ref': 'AResource'
                        }
                    }
                }
            }
        }

        self.stack = parser.Stack(self.ctx,
                                  'update_test_stack',
                                  template.Template(tmpl),
                                  disable_rollback=False)

        self.m.StubOutWithMock(scheduler.TaskRunner, '_sleep')
        scheduler.TaskRunner._sleep(mox.IsA(int)).AndReturn(None)
        self.m.ReplayAll()

        self.stack.store()
        self.stack.create()
        self.m.VerifyAll()

        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
        self.assertEqual(self.stack['AResource'].properties['Foo'], 'abc')
        self.assertEqual(self.stack['BResource'].properties['Foo'],
                         'AResource')

        self.m.StubOutWithMock(generic_rsrc.GenericResource, 'FnGetRefId')
        self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_create')

        # Calls to GenericResource.handle_update will raise
        # resource.UpdateReplace because we've not specified the modified
        # key/property in update_allowed_keys/update_allowed_properties

        generic_rsrc.GenericResource.FnGetRefId().AndReturn('AResource')
        generic_rsrc.GenericResource.FnGetRefId().AndReturn('inst-007')
        # self.state_set(self.UPDATE_IN_PROGRESS)
        generic_rsrc.GenericResource.FnGetRefId().AndReturn('inst-007')
        # self.state_set(self.DELETE_IN_PROGRESS)
        generic_rsrc.GenericResource.FnGetRefId().AndReturn('inst-007')
        # self.state_set(self.DELETE_COMPLETE)
        generic_rsrc.GenericResource.FnGetRefId().AndReturn('inst-007')
        # self.properties.validate()
        generic_rsrc.GenericResource.FnGetRefId().AndReturn('inst-007')
        # self.state_set(self.CREATE_IN_PROGRESS)
        generic_rsrc.GenericResource.FnGetRefId().AndReturn('inst-007')

        # mock to make the replace fail when creating the second
        # replacement resource
        generic_rsrc.GenericResource.handle_create().AndReturn(None)
        generic_rsrc.GenericResource.handle_create().AndRaise(Exception)

        # Calls to GenericResource.handle_update will raise
        # resource.UpdateReplace because we've not specified the modified
        # key/property in update_allowed_keys/update_allowed_properties

        # self.state_set(self.DELETE_IN_PROGRESS)
        generic_rsrc.GenericResource.FnGetRefId().AndReturn('inst-007')
        # self.state_set(self.DELETE_IN_PROGRESS)
        generic_rsrc.GenericResource.FnGetRefId().AndReturn('inst-007')

        generic_rsrc.GenericResource.handle_create().AndReturn(None)
        generic_rsrc.GenericResource.handle_create().AndReturn(None)

        # reverting to AResource
        generic_rsrc.GenericResource.FnGetRefId().MultipleTimes().AndReturn(
            'AResource')

        self.m.ReplayAll()

        updated_stack = parser.Stack(self.ctx,
                                     'updated_stack',
                                     template.Template(tmpl2),
                                     disable_rollback=False)
        self.stack.update(updated_stack)
        self.assertEqual(self.stack.state, parser.Stack.ROLLBACK_COMPLETE)
        self.assertEqual(self.stack['AResource'].properties['Foo'], 'abc')

        self.m.VerifyAll()
Пример #12
0
    def test_update_replace_by_reference(self):
        '''
        assertion:
        changes in dynamic attributes, due to other resources been updated
        are not ignored and can cause dependant resources to be updated.
        '''
        # patch in a dummy property schema for GenericResource
        dummy_schema = {'Foo': {'Type': 'String'}}
        generic_rsrc.GenericResource.properties_schema = dummy_schema
        tmpl = {
            'Resources': {
                'AResource': {
                    'Type': 'GenericResourceType',
                    'Properties': {
                        'Foo': 'abc'
                    }
                },
                'BResource': {
                    'Type': 'GenericResourceType',
                    'Properties': {
                        'Foo': {
                            'Ref': 'AResource'
                        }
                    }
                }
            }
        }
        tmpl2 = {
            'Resources': {
                'AResource': {
                    'Type': 'GenericResourceType',
                    'Properties': {
                        'Foo': 'smelly'
                    }
                },
                'BResource': {
                    'Type': 'GenericResourceType',
                    'Properties': {
                        'Foo': {
                            'Ref': 'AResource'
                        }
                    }
                }
            }
        }

        self.stack = parser.Stack(self.ctx, 'update_test_stack',
                                  template.Template(tmpl))

        self.m.StubOutWithMock(scheduler.TaskRunner, '_sleep')
        scheduler.TaskRunner._sleep(mox.IsA(int)).AndReturn(None)
        self.m.ReplayAll()

        self.stack.store()
        self.stack.create()
        self.m.VerifyAll()
        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
        self.assertEqual(self.stack['AResource'].properties['Foo'], 'abc')
        self.assertEqual(self.stack['BResource'].properties['Foo'],
                         'AResource')

        # Calls to GenericResource.handle_update will raise
        # resource.UpdateReplace because we've not specified the modified
        # key/property in update_allowed_keys/update_allowed_properties

        self.m.StubOutWithMock(generic_rsrc.GenericResource, 'FnGetRefId')
        generic_rsrc.GenericResource.FnGetRefId().AndReturn('AResource')
        generic_rsrc.GenericResource.FnGetRefId().MultipleTimes().AndReturn(
            'inst-007')
        self.m.ReplayAll()

        updated_stack = parser.Stack(self.ctx, 'updated_stack',
                                     template.Template(tmpl2))
        self.stack.update(updated_stack)
        self.assertEqual(self.stack.state, parser.Stack.UPDATE_COMPLETE)
        self.assertEqual(self.stack['AResource'].properties['Foo'], 'smelly')
        self.assertEqual(self.stack['BResource'].properties['Foo'], 'inst-007')
        self.m.VerifyAll()
Пример #13
0
    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()

        stack = parser.Stack(utils.dummy_context(),
                             'test_stack',
                             parser.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.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 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)
Пример #14
0
    def test_to_parameters(self):
        """Tests property conversion to parameter values."""
        provider = {
            'HeatTemplateFormatVersion': '2012-12-12',
            'Parameters': {
                'Foo': {'Type': 'String'},
                'AList': {'Type': 'CommaDelimitedList'},
                'ListEmpty': {'Type': 'CommaDelimitedList'},
                'ANum': {'Type': 'Number'},
                'AMap': {'Type': 'Json'},
            },
            'Outputs': {
                'Foo': {'Value': 'bar'},
            },
        }

        files = {'test_resource.template': json.dumps(provider)}

        class DummyResource(object):
            support_status = support.SupportStatus()

            attributes_schema = {"Foo": attributes.Schema("A test attribute")}
            properties_schema = {
                "Foo": {"Type": "String"},
                "AList": {"Type": "List"},
                "ListEmpty": {"Type": "List"},
                "ANum": {"Type": "Number"},
                "AMap": {"Type": "Map"}
            }

        env = environment.Environment()
        resource._register_class('DummyResource', DummyResource)
        env.load({'resource_registry':
                  {'DummyResource': 'test_resource.template'}})
        stack = parser.Stack(utils.dummy_context(), 'test_stack',
                             parser.Template(empty_template, files=files),
                             env=env,
                             stack_id=str(uuid.uuid4()))

        map_prop_val = {
            "key1": "val1",
            "key2": ["lval1", "lval2", "lval3"],
            "key3": {
                "key4": 4,
                "key5": False
            }
        }
        prop_vals = {
            "Foo": "Bar",
            "AList": ["one", "two", "three"],
            "ListEmpty": [],
            "ANum": 5,
            "AMap": map_prop_val,
        }
        definition = rsrc_defn.ResourceDefinition('test_t_res',
                                                  'DummyResource',
                                                  prop_vals)
        temp_res = template_resource.TemplateResource('test_t_res',
                                                      definition, stack)
        temp_res.validate()
        converted_params = temp_res.child_params()
        self.assertTrue(converted_params)
        for key in DummyResource.properties_schema:
            self.assertIn(key, converted_params)
        # verify String conversion
        self.assertEqual("Bar", converted_params.get("Foo"))
        # verify List conversion
        self.assertEqual("one,two,three", converted_params.get("AList"))
        # verify Number conversion
        self.assertEqual(5, converted_params.get("ANum"))
        # verify Map conversion
        self.assertEqual(map_prop_val, converted_params.get("AMap"))

        with mock.patch.object(properties.Properties, '__getitem__') as m_get:
            m_get.side_effect = ValueError('boom')

            # If the property doesn't exist on INIT, return default value
            temp_res.action = temp_res.INIT
            converted_params = temp_res.child_params()
            for key in DummyResource.properties_schema:
                self.assertIn(key, converted_params)
            self.assertEqual({}, converted_params['AMap'])
            self.assertEqual(0, converted_params['ANum'])

            # If the property doesn't exist past INIT, then error out
            temp_res.action = temp_res.CREATE
            self.assertRaises(ValueError, temp_res.child_params)
Пример #15
0
    def check_user_data(self, template_file):
        return  # until TODO is fixed

#        transport = self.ssh.get_transport()
#        channel = transport.open_session()
#        channel.get_pty()
#        channel.invoke_shell()  # sudo requires tty
#        channel.sendall('sudo chmod 777 \
#            sudo chmod 777 /var/lib/cloud/instance/user-data.txt.i\n')
#        time.sleep(1)  # necessary for sendall to complete

        f = open(basepath + '/templates/' + template_file)
        t = json.loads(f.read())
        f.close()

        template = parser.Template(t)
        params = parser.Parameters('test', t,
                                   {'KeyName': 'required_parameter',
                                    'DBUsername': self.dbusername,
                                    'DBPassword': self.creds['password']})

        stack = parser.Stack(None, 'test', template, params)
        parsed_t = stack.resolve_static_data(t)
        remote_file = self.sftp.open('/var/lib/cloud/data/cfn-userdata')
        remote_file_list = remote_file.read().split('\n')
        remote_file_list_u = map(unicode, remote_file_list)
        remote_file.close()

        # TODO: make server name generic
        t_data = parsed_t['Resources']['WikiDatabase']['Properties']
        t_data = t_data['UserData']['Fn::Base64']['Fn::Join'].pop()
        joined_t_data = ''.join(t_data)
        t_data_list = joined_t_data.split('\n')
        # must match user data injection
        t_data_list.insert(len(t_data_list) - 1,
                u'touch /var/lib/cloud/instance/provision-finished')

        self.testcase.assertEqual(t_data_list, remote_file_list_u)

        remote_file = self.sftp.open('/var/lib/cloud/instance/user-data.txt.i')
        msg = email.message_from_file(remote_file)
        remote_file.close()

        filepaths = {
            'cloud-config': basepath + '/heat/cloudinit/config',
            'part-handler.py': basepath +
            '/heat/cloudinit/part-handler.py'
        }

        # check multipart mime accuracy
        for part in msg.walk():
            # multipart/* are just containers
            if part.get_content_maintype() == 'multipart':
                continue

            file = part.get_filename()
            data = part.get_payload()

            if file in filepaths.keys():
                with open(filepaths[file]) as f:
                    self.testcase.assertEqual(data, f.read())
Пример #16
0
 def parse_stack(self, t):
     stack_name = 'test_stack'
     tmpl = parser.Template(t)
     stack = parser.Stack(utils.dummy_context(), stack_name, tmpl)
     stack.store()
     return stack
Пример #17
0
 def setUp(self):
     self.stack = parser.Stack(None,
                               'test_stack',
                               parser.Template({}),
                               stack_id=-1)