def _resolve_attribute(self, name): if name == 'first_address': return nova_utils.server_to_ipaddress(self.nova(), self.resource_id) or '' try: server = self.nova().servers.get(self.resource_id) except clients.novaclient.exceptions.NotFound as ex: logger.warn( _('Instance (%(server)s) not found: %(ex)s') % { 'server': self.resource_id, 'ex': str(ex) }) return '' if name == 'addresses': return self._add_port_for_address(server) if name == 'networks': return server.networks if name == 'instance_name': return server._info.get('OS-EXT-SRV-ATTR:instance_name') if name == 'accessIPv4': return server.accessIPv4 if name == 'accessIPv6': return server.accessIPv6 if name == 'show': return server._info
def handle_update(self, json_snippet, tmpl_diff, prop_diff): if self.MEMBERS in prop_diff: members = set(prop_diff[self.MEMBERS]) rd_members = db_api.resource_data_get_all(self) old_members = set(rd_members.keys()) client = self.neutron() for member in old_members - members: member_id = rd_members[member] try: client.delete_member(member_id) except NeutronClientException as ex: if ex.status_code != 404: raise ex db_api.resource_data_delete(self, member) pool = self.properties[self.POOL_ID] nova_client = self.nova() protocol_port = self.properties[self.PROTOCOL_PORT] for member in members - old_members: address = nova_utils.server_to_ipaddress(nova_client, member) lb_member = client.create_member({ 'member': { 'pool_id': pool, 'address': address, 'protocol_port': protocol_port}})['member'] db_api.resource_data_set(self, member, lb_member['id'])
def _haproxy_config(self, templ, instances): # initial simplifications: # - only one Listener # - only http (no tcp or ssl) # # option httpchk HEAD /check.txt HTTP/1.0 gl = ''' global daemon maxconn 256 stats socket /tmp/.haproxy-stats defaults mode http timeout connect 5000ms timeout client 50000ms timeout server 50000ms ''' listener = self.properties['Listeners'][0] lb_port = listener['LoadBalancerPort'] inst_port = listener['InstancePort'] spaces = ' ' frontend = ''' frontend http bind *:%s ''' % (lb_port) health_chk = self.properties['HealthCheck'] if health_chk: check = 'check inter %ss fall %s rise %s' % ( health_chk['Interval'], health_chk['UnhealthyThreshold'], health_chk['HealthyThreshold']) timeout_check = 'timeout check %ds' % int(health_chk['Timeout']) else: check = '' timeout_check = '' backend = ''' default_backend servers backend servers balance roundrobin option http-server-close option forwardfor option httpchk %s ''' % timeout_check servers = [] n = 1 client = self.nova() for i in instances: ip = nova_utils.server_to_ipaddress(client, i) or '0.0.0.0' logger.debug('haproxy server:%s' % ip) servers.append('%sserver server%d %s:%s %s' % (spaces, n, ip, inst_port, check)) n = n + 1 return '%s%s%s%s\n' % (gl, frontend, backend, '\n'.join(servers))
def handle_update(self, json_snippet, tmpl_diff, prop_diff): if self.MEMBERS in prop_diff: members = set(prop_diff[self.MEMBERS]) rd_members = self.data() old_members = set(rd_members.keys()) client = self.neutron() for member in old_members - members: member_id = rd_members[member] try: client.delete_member(member_id) except NeutronClientException as ex: if ex.status_code != 404: raise ex self.data_delete(member) pool = self.properties[self.POOL_ID] nova_client = self.nova() protocol_port = self.properties[self.PROTOCOL_PORT] for member in members - old_members: address = nova_utils.server_to_ipaddress(nova_client, member) lb_member = client.create_member({ 'member': { 'pool_id': pool, 'address': address, 'protocol_port': protocol_port } })['member'] self.data_set(member, lb_member['id'])
def _resolve_attribute(self, name): if name == self.FIRST_ADDRESS: return nova_utils.server_to_ipaddress(self.nova(), self.resource_id) or '' try: server = self.nova().servers.get(self.resource_id) except nova_exceptions.NotFound as ex: LOG.warn( _('Instance (%(server)s) not found: %(ex)s') % { 'server': self.resource_id, 'ex': ex }) return '' if name == self.NAME_ATTR: return self._server_name() if name == self.ADDRESSES: return self._add_port_for_address(server) if name == self.NETWORKS_ATTR: return server.networks if name == self.INSTANCE_NAME: return server._info.get('OS-EXT-SRV-ATTR:instance_name') if name == self.ACCESSIPV4: return server.accessIPv4 if name == self.ACCESSIPV6: return server.accessIPv6 if name == self.SHOW: return server._info
def handle_update(self, json_snippet, tmpl_diff, prop_diff): if 'members' in prop_diff: members = set(prop_diff['members']) old_members = set(self.t['Properties'].get('members', [])) client = self.neutron() for member in old_members - members: member_id = db_api.resource_data_get(self, member) try: client.delete_member(member_id) except NeutronClientException as ex: if ex.status_code != 404: raise ex db_api.resource_data_delete(self, member) pool = self.properties['pool_id'] nova_client = self.nova() protocol_port = self.properties['protocol_port'] for member in members - old_members: address = nova_utils.server_to_ipaddress(nova_client, member) lb_member = client.create_member({ 'member': { 'pool_id': pool, 'address': address, 'protocol_port': protocol_port } })['member'] db_api.resource_data_set(self, member, lb_member['id'])
def _ipaddress(self): """ Return the server's IP address, fetching it from Nova if necessary """ if self.ipaddress is None: self.ipaddress = nova_utils.server_to_ipaddress(self.nova(), self.resource_id) return self.ipaddress or "0.0.0.0"
def _ipaddress(self): ''' Return the server's IP address, fetching it from Nova if necessary ''' if self.ipaddress is None: self.ipaddress = nova_utils.server_to_ipaddress( self.nova(), self.resource_id) return self.ipaddress or '0.0.0.0'
def handle_create(self): pool = self.properties['pool_id'] client = self.neutron() nova_client = self.nova() protocol_port = self.properties['protocol_port'] for member in self.properties['members']: address = nova_utils.server_to_ipaddress(nova_client, member) lb_member = client.create_member({ 'member': { 'pool_id': pool, 'address': address, 'protocol_port': protocol_port}})['member'] db_api.resource_data_set(self, member, lb_member['id'])
def handle_create(self): pool = self.properties['pool_id'] client = self.neutron() nova_client = self.nova() protocol_port = self.properties['protocol_port'] for member in self.t['Properties'].get('members', []): address = nova_utils.server_to_ipaddress(nova_client, member) lb_member = client.create_member({ 'member': { 'pool_id': pool, 'address': address, 'protocol_port': protocol_port}})['member'] db_api.resource_data_set(self, member, lb_member['id'])
def handle_create(self): pool = self.properties[self.POOL_ID] client = self.neutron() nova_client = self.nova() protocol_port = self.properties[self.PROTOCOL_PORT] for member in self.properties.get(self.MEMBERS): address = nova_utils.server_to_ipaddress(nova_client, member) lb_member = client.create_member({ 'member': { 'pool_id': pool, 'address': address, 'protocol_port': protocol_port}})['member'] self.data_set(member, lb_member['id'])
def handle_create(self): pool = self.properties[self.POOL_ID] client = self.neutron() nova_client = self.nova() protocol_port = self.properties[self.PROTOCOL_PORT] for member in self.properties.get(self.MEMBERS): address = nova_utils.server_to_ipaddress(nova_client, member) lb_member = client.create_member({ 'member': { 'pool_id': pool, 'address': address, 'protocol_port': protocol_port}})['member'] db_api.resource_data_set(self, member, lb_member['id'])
def _resolve_attribute(self, name): if name == 'first_address': return nova_utils.server_to_ipaddress( self.nova(), self.resource_id) or '' server = self.nova().servers.get(self.resource_id) if name == 'addresses': return server.addresses if name == 'networks': return server.networks if name == 'instance_name': return server._info.get('OS-EXT-SRV-ATTR:instance_name') if name == 'accessIPv4': return server.accessIPv4 if name == 'accessIPv6': return server.accessIPv6 if name == 'show': return server._info
def _resolve_attribute(self, name): if name == 'first_address': return nova_utils.server_to_ipaddress(self.nova(), self.resource_id) or '' server = self.nova().servers.get(self.resource_id) if name == 'addresses': return server.addresses if name == 'networks': return server.networks if name == 'instance_name': return server._info.get('OS-EXT-SRV-ATTR:instance_name') if name == 'accessIPv4': return server.accessIPv4 if name == 'accessIPv6': return server.accessIPv6 if name == 'show': return server._info
def _resolve_attribute(self, name): if name == self.FIRST_ADDRESS: return nova_utils.server_to_ipaddress( self.nova(), self.resource_id) or '' try: server = self.nova().servers.get(self.resource_id) except clients.novaclient.exceptions.NotFound as ex: LOG.warn(_('Instance (%(server)s) not found: %(ex)s') % {'server': self.resource_id, 'ex': ex}) return '' if name == self.ADDRESSES: return self._add_port_for_address(server) if name == self.NETWORKS_ATTR: return server.networks if name == self.INSTANCE_NAME: return server._info.get('OS-EXT-SRV-ATTR:instance_name') if name == self.ACCESSIPV4: return server.accessIPv4 if name == self.ACCESSIPV6: return server.accessIPv6 if name == self.SHOW: return server._info
def _resolve_attribute(self, name): if name == 'first_address': return nova_utils.server_to_ipaddress( self.nova(), self.resource_id) or '' try: server = self.nova().servers.get(self.resource_id) except clients.novaclient.exceptions.NotFound as ex: logger.warn(_('Instance (%(server)s) not found: %(ex)s') % { 'server': self.resource_id, 'ex': ex}) return '' if name == 'addresses': return self._add_port_for_address(server) if name == 'networks': return server.networks if name == 'instance_name': return server._info.get('OS-EXT-SRV-ATTR:instance_name') if name == 'accessIPv4': return server.accessIPv4 if name == 'accessIPv6': return server.accessIPv6 if name == 'show': return server._info
def handle_update(self, json_snippet, tmpl_diff, prop_diff): if 'members' in prop_diff: members = set(prop_diff['members']) old_members = set(self.t['Properties'].get('members', [])) client = self.neutron() for member in old_members - members: member_id = db_api.resource_data_get(self, member) try: client.delete_member(member_id) except NeutronClientException as ex: if ex.status_code != 404: raise ex db_api.resource_data_delete(self, member) pool = self.properties['pool_id'] nova_client = self.nova() protocol_port = self.properties['protocol_port'] for member in members - old_members: address = nova_utils.server_to_ipaddress(nova_client, member) lb_member = client.create_member({ 'member': { 'pool_id': pool, 'address': address, 'protocol_port': protocol_port}})['member'] db_api.resource_data_set(self, member, lb_member['id'])
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) 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()
def _haproxy_config(self, templ, instances): # initial simplifications: # - only one Listener # - only http (no tcp or ssl) # # option httpchk HEAD /check.txt HTTP/1.0 gl = ''' global daemon maxconn 256 stats socket /tmp/.haproxy-stats defaults mode http timeout connect 5000ms timeout client 50000ms timeout server 50000ms ''' listener = self.properties[self.LISTENERS][0] lb_port = listener[self.LISTENER_LOAD_BALANCER_PORT] inst_port = listener[self.LISTENER_INSTANCE_PORT] spaces = ' ' frontend = ''' frontend http bind *:%s ''' % (lb_port) health_chk = self.properties[self.HEALTH_CHECK] if health_chk: check = 'check inter %ss fall %s rise %s' % ( health_chk[self.HEALTH_CHECK_INTERVAL], health_chk[self.HEALTH_CHECK_UNHEALTHY_THRESHOLD], health_chk[self.HEALTH_CHECK_HEALTHY_THRESHOLD]) timeout = int(health_chk[self.HEALTH_CHECK_TIMEOUT]) timeout_check = 'timeout check %ds' % timeout else: check = '' timeout_check = '' backend = ''' default_backend servers backend servers balance roundrobin option http-server-close option forwardfor option httpchk %s ''' % timeout_check servers = [] n = 1 client = self.nova() for i in instances: ip = nova_utils.server_to_ipaddress(client, i) or '0.0.0.0' LOG.debug('haproxy server:%s' % ip) servers.append('%sserver server%d %s:%s %s' % (spaces, n, ip, inst_port, check)) n = n + 1 return '%s%s%s%s\n' % (gl, frontend, backend, '\n'.join(servers))
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 image_list = [id_type(id='768b5464-3df5-4abf-be33-63b60f8b99d0', name='foo')] flavor_list = [id_type(id='768b5464-3df5-4abf-be33-63b60f8b99d1', name='bar')] 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) 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(stack.state, (parser.Stack.CREATE, parser.Stack.COMPLETE)) # 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(stack2.state, (parser.Stack.UPDATE, parser.Stack.COMPLETE)) members = db_api.resource_data_get_all(stack['ElasticLoadBalancer']) self.assertEqual(3, len(members.keys())) self.m.VerifyAll()