Fix python-novaclient 8.0.0 related issues

New python-novaclient release has removed support for
network/image/floating_ip apis. This also means
nova-network support would also cease to exist after
this change.

Change-Id: Icbcf279c10720f99a0aed1a3aaaf3945c5442a8a
Closes-Bug: #1690936
This commit is contained in:
rabi 2017-05-16 09:29:07 +05:30 committed by Thomas Herve
parent 320c820ed8
commit e8e0a2483a
23 changed files with 159 additions and 1599 deletions

View File

@ -17,7 +17,6 @@ from neutronclient.common import exceptions as qe
from heat.common import exception from heat.common import exception
from heat.common.i18n import _ from heat.common.i18n import _
from heat.engine.clients.os import nova
from heat.engine import constraints from heat.engine import constraints
CLIENT_NAME = 'neutron' CLIENT_NAME = 'neutron'
@ -30,15 +29,9 @@ class NetworkConstraint(constraints.BaseCustomConstraint):
exception.PhysicalResourceNameAmbiguity) exception.PhysicalResourceNameAmbiguity)
def validate_with_client(self, client, value): def validate_with_client(self, client, value):
try: neutron_plugin = client.client_plugin(CLIENT_NAME)
client.client(CLIENT_NAME) neutron_plugin.find_resourceid_by_name_or_id(
except Exception: 'network', value, cmd_resource=None)
# is not using neutron
client.client_plugin(nova.CLIENT_NAME).get_nova_network_id(value)
else:
neutron_plugin = client.client_plugin(CLIENT_NAME)
neutron_plugin.find_resourceid_by_name_or_id(
'network', value, cmd_resource=None)
class NeutronConstraint(constraints.BaseCustomConstraint): class NeutronConstraint(constraints.BaseCustomConstraint):

View File

@ -24,7 +24,6 @@ from novaclient import exceptions
from oslo_config import cfg from oslo_config import cfg
from oslo_log import log as logging from oslo_log import log as logging
from oslo_serialization import jsonutils from oslo_serialization import jsonutils
from oslo_utils import uuidutils
import six import six
from six.moves.urllib import parse as urlparse from six.moves.urllib import parse as urlparse
import tenacity import tenacity
@ -637,30 +636,6 @@ echo -e '%s\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers
return ConsoleUrls(server) return ConsoleUrls(server)
def get_net_id_by_label(self, label):
try:
net_id = self.client().networks.find(label=label).id
except exceptions.NotFound as ex:
LOG.debug('Nova network (%(net)s) not found: %(ex)s',
{'net': label, 'ex': ex})
raise exception.EntityNotFound(entity='Nova network', name=label)
except exceptions.NoUniqueMatch as exc:
LOG.debug('Nova network (%(net)s) is not unique matched: %(exc)s',
{'net': label, 'exc': exc})
raise exception.PhysicalResourceNameAmbiguity(name=label)
return net_id
def get_nova_network_id(self, net_identifier):
if uuidutils.is_uuid_like(net_identifier):
try:
net_id = self.client().networks.get(net_identifier).id
except exceptions.NotFound:
net_id = self.get_net_id_by_label(net_identifier)
else:
net_id = self.get_net_id_by_label(net_identifier)
return net_id
def attach_volume(self, server_id, volume_id, device): def attach_volume(self, server_id, volume_id, device):
try: try:
va = self.client().volumes.create_server_volume( va = self.client().volumes.create_server_volume(
@ -796,14 +771,6 @@ class FlavorConstraint(NovaBaseConstraint):
resource_getter_name = 'find_flavor_by_name_or_id' resource_getter_name = 'find_flavor_by_name_or_id'
class NetworkConstraint(NovaBaseConstraint):
expected_exceptions = (exception.EntityNotFound,
exception.PhysicalResourceNameAmbiguity)
resource_getter_name = 'get_nova_network_id'
class HostConstraint(NovaBaseConstraint): class HostConstraint(NovaBaseConstraint):
resource_getter_name = 'get_host' resource_getter_name = 'get_host'

View File

@ -12,7 +12,6 @@
# under the License. # under the License.
from oslo_log import log as logging from oslo_log import log as logging
from oslo_utils import excutils
import six import six
from heat.common import exception from heat.common import exception
@ -23,6 +22,7 @@ from heat.engine import properties
from heat.engine import resource from heat.engine import resource
from heat.engine.resources.aws.ec2 import internet_gateway from heat.engine.resources.aws.ec2 import internet_gateway
from heat.engine.resources.aws.ec2 import vpc from heat.engine.resources.aws.ec2 import vpc
from heat.engine import support
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -45,6 +45,12 @@ class ElasticIp(resource.Resource):
properties.Schema.STRING, properties.Schema.STRING,
_('Set to "vpc" to have IP address allocation associated to your ' _('Set to "vpc" to have IP address allocation associated to your '
'VPC.'), 'VPC.'),
support_status=support.SupportStatus(
status=support.DEPRECATED,
message=_('Now we only allow vpc here, so no need to set up '
'this tag anymore.'),
version='9.0.0'
),
constraints=[ constraints=[
constraints.AllowedValues(['vpc']), constraints.AllowedValues(['vpc']),
] ]
@ -76,47 +82,25 @@ class ElasticIp(resource.Resource):
def _ipaddress(self): def _ipaddress(self):
if self.ipaddress is None and self.resource_id is not None: if self.ipaddress is None and self.resource_id is not None:
if self.properties[self.DOMAIN]: try:
try: ips = self.neutron().show_floatingip(self.resource_id)
ips = self.neutron().show_floatingip(self.resource_id) except Exception as ex:
except Exception as ex: self.client_plugin('neutron').ignore_not_found(ex)
self.client_plugin('neutron').ignore_not_found(ex)
else:
self.ipaddress = ips['floatingip']['floating_ip_address']
else: else:
try: self.ipaddress = ips['floatingip']['floating_ip_address']
ips = self.client().floating_ips.get(self.resource_id)
except Exception as e:
self.client_plugin('nova').ignore_not_found(e)
else:
self.ipaddress = ips.ip
return self.ipaddress or '' return self.ipaddress or ''
def handle_create(self): def handle_create(self):
"""Allocate a floating IP for the current tenant.""" """Allocate a floating IP for the current tenant."""
ips = None ips = None
if self.properties[self.DOMAIN]: ext_net = internet_gateway.InternetGateway.get_external_network_id(
ext_net = internet_gateway.InternetGateway.get_external_network_id( self.neutron())
self.neutron()) props = {'floating_network_id': ext_net}
props = {'floating_network_id': ext_net} ips = self.neutron().create_floatingip({
ips = self.neutron().create_floatingip({ 'floatingip': props})['floatingip']
'floatingip': props})['floatingip'] self.ipaddress = ips['floating_ip_address']
self.ipaddress = ips['floating_ip_address'] self.resource_id_set(ips['id'])
self.resource_id_set(ips['id']) LOG.info('ElasticIp create %s', str(ips))
LOG.info('ElasticIp create %s', str(ips))
else:
try:
ips = self.client().floating_ips.create()
except Exception as e:
with excutils.save_and_reraise_exception():
if self.client_plugin('nova').is_not_found(e):
LOG.error("No default floating IP pool configured. "
"Set 'default_floating_pool' in nova.conf.")
if ips:
self.ipaddress = ips.ip
self.resource_id_set(ips.id)
LOG.info('ElasticIp create %s', str(ips))
instance_id = self.properties[self.INSTANCE_ID] instance_id = self.properties[self.INSTANCE_ID]
if instance_id: if instance_id:
@ -145,12 +129,8 @@ class ElasticIp(resource.Resource):
raise raise
# deallocate the eip # deallocate the eip
if self.properties[self.DOMAIN]: with self.client_plugin('neutron').ignore_not_found:
with self.client_plugin('neutron').ignore_not_found: self.neutron().delete_floatingip(self.resource_id)
self.neutron().delete_floatingip(self.resource_id)
else:
with self.client_plugin('nova').ignore_not_found:
self.client().floating_ips.delete(self.resource_id)
def handle_update(self, json_snippet, tmpl_diff, prop_diff): def handle_update(self, json_snippet, tmpl_diff, prop_diff):
if prop_diff: if prop_diff:

View File

@ -11,8 +11,6 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import abc
import six import six
from heat.common import exception from heat.common import exception
@ -21,156 +19,10 @@ from heat.engine import properties
from heat.engine import resource from heat.engine import resource
@six.add_metaclass(abc.ABCMeta) class NeutronSecurityGroup(object):
class BaseSecurityGroup(object):
def __init__(self, sg): def __init__(self, sg):
self.sg = sg self.sg = sg
@abc.abstractmethod
def create(self):
return
@abc.abstractmethod
def delete(self):
return
@abc.abstractmethod
def update(self, props):
return
def diff_rules(self, existing, updated):
ids_to_delete = [id for id, rule in existing.items()
if rule not in updated]
rules_to_create = [rule for rule in updated
if rule not in six.itervalues(existing)]
return ids_to_delete, rules_to_create
class NovaSecurityGroup(BaseSecurityGroup):
def __init__(self, sg):
super(NovaSecurityGroup, self).__init__(sg)
self.client = sg.client('nova')
self.plugin = sg.client_plugin('nova')
def _get_rule_secgroupid_nova(self, prop):
source_group_id = None
if prop.get(self.sg.RULE_SOURCE_SECURITY_GROUP_ID) is not None:
source_group_id = prop[self.sg.RULE_SOURCE_SECURITY_GROUP_ID]
elif prop.get(self.sg.RULE_SOURCE_SECURITY_GROUP_NAME) is not None:
rule_name = prop[self.sg.RULE_SOURCE_SECURITY_GROUP_NAME]
for group in self.client.security_groups.list():
if group.name == rule_name:
source_group_id = group.id
break
else:
raise SecurityGroupNotFound(group_name=rule_name)
return source_group_id
def _prop_rules_to_common(self, props, direction):
rules = []
prs = props.get(direction) or []
for pr in prs:
rule = dict(pr)
rule.pop(self.sg.RULE_SOURCE_SECURITY_GROUP_OWNER_ID)
if rule[self.sg.RULE_FROM_PORT]:
rule[self.sg.RULE_FROM_PORT] = int(
rule[self.sg.RULE_FROM_PORT])
if rule[self.sg.RULE_TO_PORT]:
rule[self.sg.RULE_TO_PORT] = int(rule[self.sg.RULE_TO_PORT])
rule[self.sg.RULE_SOURCE_SECURITY_GROUP_ID
] = self._get_rule_secgroupid_nova(rule)
rule.pop(self.sg.RULE_SOURCE_SECURITY_GROUP_NAME)
rules.append(rule)
return rules
def _res_rules_to_common(self, api_rules):
rules = {}
for nr in api_rules:
rule = {}
rule[self.sg.RULE_CIDR_IP] = nr['ip_range'].get('cidr') or None
rule[self.sg.RULE_IP_PROTOCOL] = nr['ip_protocol']
rule[self.sg.RULE_FROM_PORT] = nr['from_port'] or None
rule[self.sg.RULE_TO_PORT] = nr['to_port'] or None
# set source_group_id as id, not name
group_name = nr['group'].get('name')
group_id = None
if group_name:
for group in self.client.security_groups.list():
if group.name == group_name:
group_id = group.id
break
rule[self.sg.RULE_SOURCE_SECURITY_GROUP_ID] = group_id
rules[nr['id']] = rule
return rules
def create(self):
sec = None
groups = self.client.security_groups.list()
for group in groups:
if group.name == self.sg.physical_resource_name():
sec = group
break
if not sec:
sec = self.client.security_groups.create(
self.sg.physical_resource_name(),
self.sg.properties[self.sg.GROUP_DESCRIPTION])
self.sg.resource_id_set(sec.id)
if self.sg.properties[self.sg.SECURITY_GROUP_INGRESS]:
rules = self._prop_rules_to_common(
self.sg.properties, self.sg.SECURITY_GROUP_INGRESS)
for rule in rules:
self.create_rule(sec, rule)
def create_rule(self, sec, rule):
try:
self.client.security_group_rules.create(
sec.id,
rule.get(self.sg.RULE_IP_PROTOCOL),
rule.get(self.sg.RULE_FROM_PORT),
rule.get(self.sg.RULE_TO_PORT),
rule.get(self.sg.RULE_CIDR_IP),
rule.get(self.sg.RULE_SOURCE_SECURITY_GROUP_ID))
except Exception as ex:
# ignore error if the group already exists
if not (self.plugin.is_bad_request(ex) and
'already exists' in six.text_type(ex)):
raise
def delete(self):
if self.sg.resource_id is not None:
try:
sec = self.client.security_groups.get(self.sg.resource_id)
except Exception as e:
self.plugin.ignore_not_found(e)
else:
for rule in sec.rules:
self.delete_rule(rule['id'])
self.client.security_groups.delete(self.sg.resource_id)
def delete_rule(self, rule_id):
with self.plugin.ignore_not_found:
self.client.security_group_rules.delete(rule_id)
def update(self, props):
sec = self.client.security_groups.get(self.sg.resource_id)
existing = self._res_rules_to_common(sec.rules)
updated = self._prop_rules_to_common(
props, self.sg.SECURITY_GROUP_INGRESS)
ids, new = self.diff_rules(existing, updated)
for id in ids:
self.delete_rule(id)
for rule in new:
self.create_rule(sec, rule)
class NeutronSecurityGroup(BaseSecurityGroup):
def __init__(self, sg):
super(NeutronSecurityGroup, self).__init__(sg)
self.client = sg.client('neutron') self.client = sg.client('neutron')
self.plugin = sg.client_plugin('neutron') self.plugin = sg.client_plugin('neutron')
@ -319,8 +171,11 @@ class NeutronSecurityGroup(BaseSecurityGroup):
rule['direction'] = 'ingress' rule['direction'] = 'ingress'
updated_rules = list(six.itervalues(updated)) updated_rules = list(six.itervalues(updated))
updated_all = updated_rules[0] + updated_rules[1] updated_all = updated_rules[0] + updated_rules[1]
return super(NeutronSecurityGroup, self).diff_rules(existing, ids_to_delete = [id for id, rule in existing.items()
updated_all) if rule not in updated_all]
rules_to_create = [rule for rule in updated_all
if rule not in six.itervalues(existing)]
return ids_to_delete, rules_to_create
class SecurityGroup(resource.Resource): class SecurityGroup(resource.Resource):
@ -398,50 +253,17 @@ class SecurityGroup(resource.Resource):
} }
def handle_create(self): def handle_create(self):
if self.is_using_neutron(): NeutronSecurityGroup(self).create()
impl = NeutronSecurityGroup
else:
impl = NovaSecurityGroup
impl(self).create()
def handle_delete(self): def handle_delete(self):
if self.is_using_neutron(): NeutronSecurityGroup(self).delete()
impl = NeutronSecurityGroup
else:
impl = NovaSecurityGroup
impl(self).delete()
def get_reference_id(self):
if self.is_using_neutron():
return super(SecurityGroup, self).get_reference_id()
else:
return self.physical_resource_name()
def validate(self):
res = super(SecurityGroup, self).validate()
if res:
return res
if (self.properties[self.SECURITY_GROUP_EGRESS] and
not self.is_using_neutron()):
raise exception.EgressRuleNotAllowed()
def handle_update(self, json_snippet, tmpl_diff, prop_diff): def handle_update(self, json_snippet, tmpl_diff, prop_diff):
update = False if (self.SECURITY_GROUP_INGRESS in prop_diff or
if (self.is_using_neutron() and ( self.SECURITY_GROUP_EGRESS in prop_diff):
self.SECURITY_GROUP_INGRESS in prop_diff or
self.SECURITY_GROUP_EGRESS in prop_diff)):
impl = NeutronSecurityGroup
update = True
elif (not self.is_using_neutron() and
self.SECURITY_GROUP_INGRESS in prop_diff):
impl = NovaSecurityGroup
update = True
if update:
props = json_snippet.properties(self.properties_schema, props = json_snippet.properties(self.properties_schema,
self.context) self.context)
impl(self).update(props) NeutronSecurityGroup(self).update(props)
class SecurityGroupNotFound(exception.HeatException): class SecurityGroupNotFound(exception.HeatException):

View File

@ -66,7 +66,6 @@ class ManilaShareNetwork(resource.Resource):
properties.Schema.STRING, properties.Schema.STRING,
_('Nova network id.'), _('Nova network id.'),
update_allowed=True, update_allowed=True,
constraints=[constraints.CustomConstraint('nova.network')]
), ),
DESCRIPTION: properties.Schema( DESCRIPTION: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,
@ -156,36 +155,24 @@ class ManilaShareNetwork(resource.Resource):
raise exception.StackValidationFailed(message=msg) raise exception.StackValidationFailed(message=msg)
def translation_rules(self, props): def translation_rules(self, props):
if self.is_using_neutron(): translation_rules = [
translation_rules = [ translation.TranslationRule(
translation.TranslationRule( props,
props, translation.TranslationRule.RESOLVE,
translation.TranslationRule.RESOLVE, [self.NEUTRON_NETWORK],
[self.NEUTRON_NETWORK], client_plugin=self.client_plugin('neutron'),
client_plugin=self.client_plugin('neutron'), finder='find_resourceid_by_name_or_id',
finder='find_resourceid_by_name_or_id', entity='network'
entity='network' ),
), translation.TranslationRule(
translation.TranslationRule( props,
props, translation.TranslationRule.RESOLVE,
translation.TranslationRule.RESOLVE, [self.NEUTRON_SUBNET],
[self.NEUTRON_SUBNET], client_plugin=self.client_plugin('neutron'),
client_plugin=self.client_plugin('neutron'), finder='find_resourceid_by_name_or_id',
finder='find_resourceid_by_name_or_id', entity='subnet'
entity='subnet' )
) ]
]
else:
translation_rules = [
translation.TranslationRule(
props,
translation.TranslationRule.RESOLVE,
[self.NOVA_NETWORK],
client_plugin=self.client_plugin('nova'),
finder='get_nova_network_id'
)
]
return translation_rules return translation_rules
def handle_create(self): def handle_create(self):

View File

@ -35,7 +35,14 @@ class NovaFloatingIp(resource.Resource):
user to have a "static" IP address that can be reassigned when an instance user to have a "static" IP address that can be reassigned when an instance
is upgraded or moved. is upgraded or moved.
""" """
support_status = support.SupportStatus(version='2014.1')
deprecation_msg = _('Please use OS::Neutron::FloatingIP instead.')
support_status = support.SupportStatus(
status=support.DEPRECATED,
message=deprecation_msg,
version='9.0.0',
previous_status=support.SupportStatus(version='2014.1')
)
required_service_extension = 'os-floating-ips' required_service_extension = 'os-floating-ips'
@ -113,7 +120,14 @@ class NovaFloatingIpAssociation(resource.Resource):
Resource for associating existing Nova floating IP and Nova server. Resource for associating existing Nova floating IP and Nova server.
""" """
support_status = support.SupportStatus(version='2014.1') deprecation_msg = _(
'Please use OS::Neutron::FloatingIPAssociation instead.')
support_status = support.SupportStatus(
status=support.DEPRECATED,
message=deprecation_msg,
version='9.0.0',
previous_status=support.SupportStatus(version='2014.1')
)
PROPERTIES = ( PROPERTIES = (
SERVER, FLOATING_IP SERVER, FLOATING_IP

View File

@ -674,38 +674,27 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
self.BLOCK_DEVICE_MAPPING_IMAGE], self.BLOCK_DEVICE_MAPPING_IMAGE],
client_plugin=self.client_plugin('glance'), client_plugin=self.client_plugin('glance'),
finder='find_image_by_name_or_id'), finder='find_image_by_name_or_id'),
] translation.TranslationRule(
if self.is_using_neutron(): props,
rules.extend([ translation.TranslationRule.RESOLVE,
translation.TranslationRule( translation_path=[self.NETWORKS, self.NETWORK_ID],
props, client_plugin=self.client_plugin('neutron'),
translation.TranslationRule.RESOLVE, finder='find_resourceid_by_name_or_id',
translation_path=[self.NETWORKS, self.NETWORK_ID], entity='network'),
client_plugin=self.client_plugin('neutron'), translation.TranslationRule(
finder='find_resourceid_by_name_or_id', props,
entity='network'), translation.TranslationRule.RESOLVE,
translation.TranslationRule( translation_path=[self.NETWORKS, self.NETWORK_SUBNET],
props, client_plugin=self.client_plugin('neutron'),
translation.TranslationRule.RESOLVE, finder='find_resourceid_by_name_or_id',
translation_path=[self.NETWORKS, self.NETWORK_SUBNET], entity='subnet'),
client_plugin=self.client_plugin('neutron'), translation.TranslationRule(
finder='find_resourceid_by_name_or_id', props,
entity='subnet'), translation.TranslationRule.RESOLVE,
translation.TranslationRule( translation_path=[self.NETWORKS, self.NETWORK_PORT],
props, client_plugin=self.client_plugin('neutron'),
translation.TranslationRule.RESOLVE, finder='find_resourceid_by_name_or_id',
translation_path=[self.NETWORKS, self.NETWORK_PORT], entity='port')]
client_plugin=self.client_plugin('neutron'),
finder='find_resourceid_by_name_or_id',
entity='port')])
else:
rules.extend([
translation.TranslationRule(
props,
translation.TranslationRule.RESOLVE,
translation_path=[self.NETWORKS, self.NETWORK_ID],
client_plugin=self.client_plugin('nova'),
finder='get_nova_network_id')])
return rules return rules
def __init__(self, name, json_snippet, stack): def __init__(self, name, json_snippet, stack):
@ -819,9 +808,6 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
if self.properties[self.TAGS]: if self.properties[self.TAGS]:
self._update_server_tags(self.properties[self.TAGS]) self._update_server_tags(self.properties[self.TAGS])
self.store_external_ports() self.store_external_ports()
# Addresses binds to server not immediately, so we need to wait
# until server is created and after that associate floating ip.
self.floating_ips_nova_associate()
return check return check
def _update_server_tags(self, tags): def _update_server_tags(self, tags):
@ -829,15 +815,6 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
self.client(version=self.client_plugin().V2_26 self.client(version=self.client_plugin().V2_26
).servers.set_tags(server, tags) ).servers.set_tags(server, tags)
def floating_ips_nova_associate(self):
# If there is no neutron used, floating_ip still unassociated,
# so need associate it with nova.
if not self.is_using_neutron():
for net in self.properties.get(self.NETWORKS) or []:
if net.get(self.NETWORK_FLOATING_IP):
self._floating_ip_nova_associate(
net.get(self.NETWORK_FLOATING_IP))
def handle_check(self): def handle_check(self):
server = self.client().servers.get(self.resource_id) server = self.client().servers.get(self.resource_id)
status = self.client_plugin().get_status(server) status = self.client_plugin().get_status(server)
@ -891,7 +868,9 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
reality_net_ids = {} reality_net_ids = {}
for net_key in reality_nets: for net_key in reality_nets:
try: try:
net_id = self.client_plugin().get_net_id_by_label(net_key) net_id = self.client_plugin(
'neutron').find_resourceid_by_name_or_id('network',
net_key)
except (exception.EntityNotFound, except (exception.EntityNotFound,
exception.PhysicalResourceNameAmbiguity): exception.PhysicalResourceNameAmbiguity):
net_id = None net_id = None
@ -1057,7 +1036,8 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
nets = copy.deepcopy(networks) nets = copy.deepcopy(networks)
for key in list(nets.keys()): for key in list(nets.keys()):
try: try:
net_id = self.client_plugin().get_net_id_by_label(key) net_id = self.client_plugin(
'neutron').find_resourceid_by_name_or_id('network', key)
except (exception.EntityNotFound, except (exception.EntityNotFound,
exception.PhysicalResourceNameAmbiguity): exception.PhysicalResourceNameAmbiguity):
net_id = None net_id = None
@ -1517,9 +1497,8 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
def check_delete_complete(self, prg): def check_delete_complete(self, prg):
if not prg: if not prg:
return True return True
if not prg.image_complete: if not prg.image_complete:
image = self.client().images.get(prg.image_id) image = self.client_plugin('glance').get_image(prg.image_id)
if image.status in ('DELETED', 'ERROR'): if image.status in ('DELETED', 'ERROR'):
raise exception.Error(image.status) raise exception.Error(image.status)
elif image.status == 'ACTIVE': elif image.status == 'ACTIVE':
@ -1611,7 +1590,7 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
return image_id return image_id
def check_snapshot_complete(self, image_id): def check_snapshot_complete(self, image_id):
image = self.client().images.get(image_id) image = self.client_plugin('glance').get_image(image_id)
if image.status == 'ACTIVE': if image.status == 'ACTIVE':
return True return True
elif image.status == 'ERROR' or image.status == 'DELETED': elif image.status == 'ERROR' or image.status == 'DELETED':
@ -1622,7 +1601,7 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
def handle_delete_snapshot(self, snapshot): def handle_delete_snapshot(self, snapshot):
image_id = snapshot['resource_data'].get('snapshot_image_id') image_id = snapshot['resource_data'].get('snapshot_image_id')
with self.client_plugin().ignore_not_found: with self.client_plugin().ignore_not_found:
self.client().images.delete(image_id) self.client_plugin('glance').images.delete(image_id)
def handle_restore(self, defn, restore_data): def handle_restore(self, defn, restore_data):
image_id = restore_data['resource_data']['snapshot_image_id'] image_id = restore_data['resource_data']['snapshot_image_id']

View File

@ -58,11 +58,6 @@ class ServerNetworkMixin(object):
'at the same time.') % self.ALLOCATE_NETWORK 'at the same time.') % self.ALLOCATE_NETWORK
raise exception.StackValidationFailed(message=msg) raise exception.StackValidationFailed(message=msg)
if port is not None and not self.is_using_neutron():
msg = _('Property "%s" is supported only for '
'Neutron.') % self.NETWORK_PORT
raise exception.StackValidationFailed(message=msg)
# Nova doesn't allow specify ip and port at the same time # Nova doesn't allow specify ip and port at the same time
if fixed_ip and port is not None: if fixed_ip and port is not None:
raise exception.ResourcePropertyConflict( raise exception.ResourcePropertyConflict(
@ -72,7 +67,7 @@ class ServerNetworkMixin(object):
# if user only specifies network and floating ip, floating ip # if user only specifies network and floating ip, floating ip
# can't be associated as the the neutron port isn't created/managed # can't be associated as the the neutron port isn't created/managed
# by heat # by heat
if floating_ip is not None and self.is_using_neutron(): if floating_ip is not None:
if net_id is not None and port is None and subnet is None: if net_id is not None and port is None and subnet is None:
msg = _('Property "%(fip)s" is not supported if only ' msg = _('Property "%(fip)s" is not supported if only '
'"%(net)s" is specified, because the corresponding ' '"%(net)s" is specified, because the corresponding '
@ -82,7 +77,7 @@ class ServerNetworkMixin(object):
raise exception.StackValidationFailed(message=msg) raise exception.StackValidationFailed(message=msg)
def _validate_belonging_subnet_to_net(self, network): def _validate_belonging_subnet_to_net(self, network):
if network.get(self.NETWORK_PORT) is None and self.is_using_neutron(): if network.get(self.NETWORK_PORT) is None:
net = self._get_network_id(network) net = self._get_network_id(network)
# check if there are subnet and network both specified that # check if there are subnet and network both specified that
# subnet belongs to specified network # subnet belongs to specified network
@ -195,9 +190,6 @@ class ServerNetworkMixin(object):
creating. We need to store information about that ports, so store creating. We need to store information about that ports, so store
their IDs to data with key `external_ports`. their IDs to data with key `external_ports`.
""" """
if not self.is_using_neutron():
return
# check if os-attach-interfaces extension is available on this cloud. # check if os-attach-interfaces extension is available on this cloud.
# If it's not, then novaclient's interface_list method cannot be used # If it's not, then novaclient's interface_list method cannot be used
# to get the list of interfaces. # to get the list of interfaces.
@ -238,7 +230,7 @@ class ServerNetworkMixin(object):
nic_info = {'net-id': self._get_network_id(net)} nic_info = {'net-id': self._get_network_id(net)}
if net.get(self.NETWORK_PORT): if net.get(self.NETWORK_PORT):
nic_info['port-id'] = net[self.NETWORK_PORT] nic_info['port-id'] = net[self.NETWORK_PORT]
elif self.is_using_neutron() and net.get(self.NETWORK_SUBNET): elif net.get(self.NETWORK_SUBNET):
nic_info['port-id'] = self._create_internal_port( nic_info['port-id'] = self._create_internal_port(
net, idx, security_groups) net, idx, security_groups)
@ -264,14 +256,8 @@ class ServerNetworkMixin(object):
return nics return nics
def _floating_ip_neutron_associate(self, floating_ip, floating_ip_data): def _floating_ip_neutron_associate(self, floating_ip, floating_ip_data):
if self.is_using_neutron(): self.client('neutron').update_floatingip(
self.client('neutron').update_floatingip( floating_ip, {'floatingip': floating_ip_data})
floating_ip, {'floatingip': floating_ip_data})
def _floating_ip_nova_associate(self, floating_ip):
fl_ip = self.client().floating_ips.get(floating_ip)
if fl_ip and self.resource_id:
self.client().servers.add_floating_ip(self.resource_id, fl_ip.ip)
def _floating_ips_disassociate(self): def _floating_ips_disassociate(self):
networks = self.properties[self.NETWORKS] or [] networks = self.properties[self.NETWORKS] or []
@ -281,15 +267,9 @@ class ServerNetworkMixin(object):
self._floating_ip_disassociate(floating_ip) self._floating_ip_disassociate(floating_ip)
def _floating_ip_disassociate(self, floating_ip): def _floating_ip_disassociate(self, floating_ip):
if self.is_using_neutron(): with self.client_plugin('neutron').ignore_not_found:
with self.client_plugin('neutron').ignore_not_found: self.client('neutron').update_floatingip(
self.client('neutron').update_floatingip( floating_ip, {'floatingip': {'port_id': None}})
floating_ip, {'floatingip': {'port_id': None}})
else:
with self.client_plugin().ignore_conflict_and_not_found:
fl_ip = self.client().floating_ips.get(floating_ip)
self.client().servers.remove_floating_ip(self.resource_id,
fl_ip.ip)
def _exclude_not_updated_networks(self, old_nets, new_nets): def _exclude_not_updated_networks(self, old_nets, new_nets):
# make networks similar by adding None vlues for not used keys # make networks similar by adding None vlues for not used keys
@ -449,7 +429,7 @@ class ServerNetworkMixin(object):
if net.get(self.NETWORK_PORT): if net.get(self.NETWORK_PORT):
handler_kwargs['port_id'] = net.get(self.NETWORK_PORT) handler_kwargs['port_id'] = net.get(self.NETWORK_PORT)
elif self.is_using_neutron() and net.get(self.NETWORK_SUBNET): elif net.get(self.NETWORK_SUBNET):
handler_kwargs['port_id'] = self._create_internal_port( handler_kwargs['port_id'] = self._create_internal_port(
net, idx, security_groups) net, idx, security_groups)
@ -489,10 +469,8 @@ class ServerNetworkMixin(object):
old_nets, new_nets, ifaces, security_groups) old_nets, new_nets, ifaces, security_groups)
def update_floating_ip_association(self, floating_ip, flip_associate): def update_floating_ip_association(self, floating_ip, flip_associate):
if self.is_using_neutron() and flip_associate.get('port_id'): if flip_associate.get('port_id'):
self._floating_ip_neutron_associate(floating_ip, flip_associate) self._floating_ip_neutron_associate(floating_ip, flip_associate)
elif not self.is_using_neutron():
self._floating_ip_nova_associate(floating_ip)
@staticmethod @staticmethod
def get_all_ports(server): def get_all_ports(server):
@ -539,15 +517,9 @@ class ServerNetworkMixin(object):
port=port['id'], server=prev_server_id) port=port['id'], server=prev_server_id)
def prepare_ports_for_replace(self): def prepare_ports_for_replace(self):
if not self.is_using_neutron():
return
self.detach_ports(self) self.detach_ports(self)
def restore_ports_after_rollback(self, convergence): def restore_ports_after_rollback(self, convergence):
if not self.is_using_neutron():
return
# In case of convergence, during rollback, the previous rsrc is # In case of convergence, during rollback, the previous rsrc is
# already selected and is being acted upon. # already selected and is being acted upon.
backup_stack = self.stack._backup_stack() backup_stack = self.stack._backup_stack()

View File

@ -193,24 +193,14 @@ class SaharaCluster(resource.Resource):
translation.TranslationRule.RESOLVE, translation.TranslationRule.RESOLVE,
[self.IMAGE_ID], [self.IMAGE_ID],
client_plugin=self.client_plugin('glance'), client_plugin=self.client_plugin('glance'),
finder='find_image_by_name_or_id')] finder='find_image_by_name_or_id'),
if self.is_using_neutron(): translation.TranslationRule(
rules.extend([ props,
translation.TranslationRule( translation.TranslationRule.RESOLVE,
props, [self.MANAGEMENT_NETWORK],
translation.TranslationRule.RESOLVE, client_plugin=self.client_plugin('neutron'),
[self.MANAGEMENT_NETWORK], finder='find_resourceid_by_name_or_id',
client_plugin=self.client_plugin('neutron'), entity='network')]
finder='find_resourceid_by_name_or_id',
entity='network')])
else:
rules.extend([
translation.TranslationRule(
props,
translation.TranslationRule.RESOLVE,
[self.MANAGEMENT_NETWORK],
client_plugin=self.client_plugin('nova'),
finder='get_nova_network_id')])
return rules return rules
def _cluster_name(self): def _cluster_name(self):

View File

@ -536,15 +536,6 @@ class SaharaClusterTemplate(resource.Resource):
entity = 'cluster_templates' entity = 'cluster_templates'
def translation_rules(self, props): def translation_rules(self, props):
if not self.is_using_neutron():
return [
translation.TranslationRule(
props,
translation.TranslationRule.RESOLVE,
[self.MANAGEMENT_NETWORK],
client_plugin=self.client_plugin('nova'),
finder='get_nova_network_id')
]
return [ return [
translation.TranslationRule( translation.TranslationRule(
props, props,
@ -552,8 +543,7 @@ class SaharaClusterTemplate(resource.Resource):
[self.MANAGEMENT_NETWORK], [self.MANAGEMENT_NETWORK],
client_plugin=self.client_plugin('neutron'), client_plugin=self.client_plugin('neutron'),
finder='find_resourceid_by_name_or_id', finder='find_resourceid_by_name_or_id',
entity='network') entity='network')]
]
def _cluster_template_name(self, name): def _cluster_template_name(self, name):
if name: if name:

View File

@ -349,13 +349,9 @@ class Instance(resource.Resource):
nic_dict = {} nic_dict = {}
net = nic.get(self.NET) net = nic.get(self.NET)
if net: if net:
if self.is_using_neutron(): net_id = self.client_plugin(
net_id = self.client_plugin( 'neutron').find_resourceid_by_name_or_id('network',
'neutron').find_resourceid_by_name_or_id('network', net)
net)
else:
net_id = (self.client_plugin(
'nova').get_nova_network_id(net))
nic_dict['net-id'] = net_id nic_dict['net-id'] = net_id
port = nic.get(self.PORT) port = nic.get(self.PORT)
if port: if port:

View File

@ -14,9 +14,7 @@
import copy import copy
import mock import mock
import mox
from neutronclient.v2_0 import client as neutronclient from neutronclient.v2_0 import client as neutronclient
from novaclient import exceptions as nova_exceptions
import six import six
from heat.common import exception from heat.common import exception
@ -24,7 +22,6 @@ from heat.common import short_id
from heat.common import template_format from heat.common import template_format
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine import node_data from heat.engine import node_data
from heat.engine import resource
from heat.engine.resources.aws.ec2 import eip from heat.engine.resources.aws.ec2 import eip
from heat.engine import rsrc_defn from heat.engine import rsrc_defn
from heat.engine import scheduler from heat.engine import scheduler
@ -205,177 +202,6 @@ class EIPTest(common.HeatTestCase):
else: else:
self.fc.servers.get(server).AndReturn(mock_server) self.fc.servers.get(server).AndReturn(mock_server)
def test_eip(self):
mock_server = self.fc.servers.list()[0]
self._mock_server_get(mock_server=mock_server)
self._mock_server_get(mock_again=True)
self.m.ReplayAll()
t = template_format.parse(eip_template)
stack = utils.parse_stack(t)
rsrc = self.create_eip(t, stack, 'IPAddress')
try:
self.assertEqual('11.0.0.1', rsrc.FnGetRefId())
rsrc.refid = None
self.assertEqual('11.0.0.1', rsrc.FnGetRefId())
self.assertEqual('1', rsrc.FnGetAtt('AllocationId'))
self.assertRaises(exception.InvalidTemplateAttribute,
rsrc.FnGetAtt, 'Foo')
finally:
scheduler.TaskRunner(rsrc.destroy)()
self.m.VerifyAll()
def test_eip_update(self):
server_old = self.fc.servers.list()[0]
self._mock_server_get(mock_server=server_old)
server_update = self.fc.servers.list()[1]
self._mock_server_get(server='5678', mock_server=server_update,
multiple=True, mock_again=True)
self.m.ReplayAll()
t = template_format.parse(eip_template)
stack = utils.parse_stack(t)
rsrc = self.create_eip(t, stack, 'IPAddress')
self.assertEqual('11.0.0.1', rsrc.FnGetRefId())
# update with the new InstanceId
props = copy.deepcopy(rsrc.properties.data)
update_server_id = '5678'
props['InstanceId'] = update_server_id
update_snippet = rsrc_defn.ResourceDefinition(rsrc.name, rsrc.type(),
props)
scheduler.TaskRunner(rsrc.update, update_snippet)()
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
self.assertEqual('11.0.0.1', rsrc.FnGetRefId())
# update without InstanceId
props = copy.deepcopy(rsrc.properties.data)
props.pop('InstanceId')
update_snippet = rsrc_defn.ResourceDefinition(rsrc.name, rsrc.type(),
props)
scheduler.TaskRunner(rsrc.update, update_snippet)()
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
self.m.VerifyAll()
def test_association_eip(self):
server = self.fc.servers.list()[0]
self._mock_server_get(mock_server=server, multiple=True)
self.m.ReplayAll()
t = template_format.parse(eip_template_ipassoc)
stack = utils.parse_stack(t)
rsrc = self.create_eip(t, stack, 'IPAddress')
association = self.create_association(t, stack, 'IPAssoc')
try:
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.assertEqual((association.CREATE, association.COMPLETE),
association.state)
self.assertEqual(utils.PhysName(stack.name, association.name),
association.FnGetRefId())
self.assertEqual('11.0.0.1', association.properties['EIP'])
finally:
scheduler.TaskRunner(association.delete)()
scheduler.TaskRunner(rsrc.delete)()
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
self.assertEqual((association.DELETE, association.COMPLETE),
association.state)
self.m.VerifyAll()
def test_eip_with_exception(self):
self.m.StubOutWithMock(self.fc.floating_ips, 'create')
nova.NovaClientPlugin._create().AndReturn(self.fc)
self.fc.floating_ips.create().AndRaise(fakes_nova.fake_exception())
self.m.ReplayAll()
t = template_format.parse(eip_template)
stack = utils.parse_stack(t)
resource_name = 'IPAddress'
resource_defns = stack.t.resource_definitions(stack)
rsrc = eip.ElasticIp(resource_name,
resource_defns[resource_name],
stack)
self.assertRaises(nova_exceptions.NotFound,
rsrc.handle_create)
self.m.VerifyAll()
def test_delete_eip_with_exception(self):
self.m.StubOutWithMock(self.fc.floating_ips, 'delete')
nova.NovaClientPlugin._create().AndReturn(self.fc)
self.fc.floating_ips.delete(mox.IsA(object)).AndRaise(
fakes_nova.fake_exception())
self.fc.servers.get(mox.IsA(object)).AndReturn(False)
self.m.ReplayAll()
t = template_format.parse(eip_template)
stack = utils.parse_stack(t)
resource_name = 'IPAddress'
resource_defns = stack.t.resource_definitions(stack)
rsrc = eip.ElasticIp(resource_name,
resource_defns[resource_name],
stack)
rsrc.resource_id = 'fake_id'
rsrc.handle_delete()
self.m.VerifyAll()
def test_delete_eip_successful_if_eip_associate_failed(self):
floating_ip = mox.IsA(object)
floating_ip.ip = '172.24.4.13'
floating_ip.id = '9037272b-6875-42e6-82e9-4342d5925da4'
self.m.StubOutWithMock(self.fc.floating_ips, 'create')
self.fc.floating_ips.create().AndReturn(floating_ip)
server = self.fc.servers.list()[0]
self._mock_server_get(mock_server=server, multiple=True)
self.m.StubOutWithMock(self.fc.servers, 'add_floating_ip')
self.fc.servers.add_floating_ip(
server, floating_ip.ip, None
).AndRaise(nova_exceptions.BadRequest(400))
self.m.StubOutWithMock(self.fc.servers, 'remove_floating_ip')
msg = ("ClientException: Floating ip 172.24.4.13 is not associated "
"with instance 1234.")
self.fc.servers.remove_floating_ip(
server, floating_ip.ip
).AndRaise(nova_exceptions.ClientException(422, msg))
self.m.StubOutWithMock(self.fc.floating_ips, 'delete')
self.fc.floating_ips.delete(mox.IsA(object))
self.m.ReplayAll()
t = template_format.parse(eip_template)
stack = utils.parse_stack(t)
resource_name = 'IPAddress'
resource_defns = stack.t.resource_definitions(stack)
rsrc = eip.ElasticIp(resource_name,
resource_defns[resource_name],
stack)
self.assertIsNone(rsrc.validate())
self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
# to delete the eip
scheduler.TaskRunner(rsrc.delete)()
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
self.m.VerifyAll()
@mock.patch.object(eip.ElasticIp, '_ipaddress') @mock.patch.object(eip.ElasticIp, '_ipaddress')
def test_FnGetRefId_resource_name(self, mock_ipaddr): def test_FnGetRefId_resource_name(self, mock_ipaddr):
t = template_format.parse(ipassoc_template_validate) t = template_format.parse(ipassoc_template_validate)
@ -607,31 +433,6 @@ class AllocTest(common.HeatTestCase):
"routers": [] "routers": []
}) })
def test_neutron_eip(self):
mock_server = self.fc.servers.list()[0]
self._mock_server_get(mock_server=mock_server)
self._mock_server_get(mock_again=True)
self.m.ReplayAll()
t = template_format.parse(eip_template)
stack = utils.parse_stack(t)
rsrc = self.create_eip(t, stack, 'IPAddress')
try:
self.assertEqual('11.0.0.1', rsrc.FnGetRefId())
rsrc.refid = None
self.assertEqual('11.0.0.1', rsrc.FnGetRefId())
self.assertEqual('1', rsrc.FnGetAtt('AllocationId'))
self.assertRaises(exception.InvalidTemplateAttribute,
rsrc.FnGetAtt, 'Foo')
finally:
scheduler.TaskRunner(rsrc.destroy)()
self.m.VerifyAll()
def test_association_allocationid(self): def test_association_allocationid(self):
self.mock_create_gateway_attachment() self.mock_create_gateway_attachment()
self.mock_show_network() self.mock_show_network()
@ -747,177 +548,6 @@ class AllocTest(common.HeatTestCase):
six.text_type(exc)) six.text_type(exc))
self.m.VerifyAll() self.m.VerifyAll()
def test_delete_association_successful_if_create_failed(self):
server = self.fc.servers.list()[0]
self._mock_server_get(mock_server=server, multiple=True)
self.m.StubOutWithMock(self.fc.servers, 'add_floating_ip')
self.fc.servers.add_floating_ip(server, '11.0.0.1').AndRaise(
fakes_nova.fake_exception(400))
self.m.ReplayAll()
t = template_format.parse(eip_template_ipassoc)
stack = utils.parse_stack(t)
self.create_eip(t, stack, 'IPAddress')
resource_defns = stack.t.resource_definitions(stack)
rsrc = eip.ElasticIpAssociation('IPAssoc',
resource_defns['IPAssoc'],
stack)
self.assertIsNone(rsrc.validate())
self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
scheduler.TaskRunner(rsrc.delete)()
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
self.m.VerifyAll()
def test_update_association_with_InstanceId(self):
server = self.fc.servers.list()[0]
self._mock_server_get(mock_server=server, multiple=True)
server_update = self.fc.servers.list()[1]
self._mock_server_get(server='5678',
mock_server=server_update,
multiple=True,
mock_again=True)
self.m.ReplayAll()
t = template_format.parse(eip_template_ipassoc)
stack = utils.parse_stack(t)
self.create_eip(t, stack, 'IPAddress')
ass = self.create_association(t, stack, 'IPAssoc')
self.assertEqual('11.0.0.1', ass.properties['EIP'])
# update with the new InstanceId
props = copy.deepcopy(ass.properties.data)
update_server_id = '5678'
props['InstanceId'] = update_server_id
update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(),
stack.t.parse(stack,
props))
scheduler.TaskRunner(ass.update, update_snippet)()
self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state)
self.m.VerifyAll()
def test_update_association_with_EIP(self):
server = self.fc.servers.list()[0]
self._mock_server_get(mock_server=server, multiple=True)
self.m.ReplayAll()
t = template_format.parse(eip_template_ipassoc)
stack = utils.parse_stack(t)
self.create_eip(t, stack, 'IPAddress')
ass = self.create_association(t, stack, 'IPAssoc')
# update with the new EIP
props = copy.deepcopy(ass.properties.data)
update_eip = '11.0.0.2'
props['EIP'] = update_eip
update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(),
stack.t.parse(stack,
props))
scheduler.TaskRunner(ass.update, update_snippet)()
self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state)
self.m.VerifyAll()
def test_update_association_with_AllocationId_or_EIP(self):
server = self.fc.servers.list()[0]
self._mock_server_get(mock_server=server, multiple=True)
self.mock_list_instance_ports('WebServer')
self.mock_show_network()
self.mock_no_router_for_vpc()
self.mock_update_floatingip(
port='a000228d-b40b-4124-8394-a4082ae1b76c')
self.mock_update_floatingip(port=None)
self.m.ReplayAll()
t = template_format.parse(eip_template_ipassoc)
stack = utils.parse_stack(t)
self.create_eip(t, stack, 'IPAddress')
ass = self.create_association(t, stack, 'IPAssoc')
self.assertEqual('11.0.0.1', ass.properties['EIP'])
# change EIP to AllocationId
props = copy.deepcopy(ass.properties.data)
update_allocationId = 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
props['AllocationId'] = update_allocationId
props.pop('EIP')
update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(),
stack.t.parse(stack,
props))
scheduler.TaskRunner(ass.update, update_snippet)()
self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state)
# change AllocationId to EIP
props = copy.deepcopy(ass.properties.data)
update_eip = '11.0.0.2'
props['EIP'] = update_eip
props.pop('AllocationId')
update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(),
stack.t.parse(stack,
props))
scheduler.TaskRunner(ass.update, update_snippet)()
self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state)
self.m.VerifyAll()
def test_update_association_needs_update_InstanceId(self):
server = self.fc.servers.list()[0]
self._mock_server_get(mock_server=server, multiple=True)
server_update = self.fc.servers.list()[1]
self._mock_server_get(server='5678',
mock_server=server_update,
multiple=True,
mock_again=True)
self.m.ReplayAll()
t = template_format.parse(eip_template_ipassoc)
stack = utils.parse_stack(t)
self.create_eip(t, stack, 'IPAddress')
before_props = {'InstanceId': {'Ref': 'WebServer'},
'EIP': '11.0.0.1'}
after_props = {'InstanceId': {'Ref': 'WebServer2'},
'EIP': '11.0.0.1'}
before = self.create_association(t, stack, 'IPAssoc')
after = rsrc_defn.ResourceDefinition(before.name, before.type(),
after_props)
self.assertTrue(resource.UpdateReplace,
before._needs_update(after, before, after_props,
before_props, None))
def test_update_association_needs_update_InstanceId_EIP(self):
server = self.fc.servers.list()[0]
self._mock_server_get(mock_server=server, multiple=True)
server_update = self.fc.servers.list()[1]
self._mock_server_get(server='5678',
mock_server=server_update,
multiple=True,
mock_again=True)
self.m.ReplayAll()
t = template_format.parse(eip_template_ipassoc)
stack = utils.parse_stack(t)
self.create_eip(t, stack, 'IPAddress')
after_props = {'InstanceId': '5678',
'EIP': '11.0.0.2'}
before = self.create_association(t, stack, 'IPAssoc')
after = rsrc_defn.ResourceDefinition(before.name, before.type(),
after_props)
updater = scheduler.TaskRunner(before.update, after)
self.assertRaises(resource.UpdateReplace, updater)
def test_update_association_with_NetworkInterfaceId_or_InstanceId(self): def test_update_association_with_NetworkInterfaceId_or_InstanceId(self):
self.mock_create_floatingip() self.mock_create_floatingip()
self.mock_list_ports() self.mock_list_ports()

View File

@ -13,26 +13,17 @@
import collections import collections
import copy import copy
import mock
from neutronclient.common import exceptions as neutron_exc from neutronclient.common import exceptions as neutron_exc
from neutronclient.v2_0 import client as neutronclient from neutronclient.v2_0 import client as neutronclient
from novaclient.v2 import security_group_rules as nova_sgr
from novaclient.v2 import security_groups as nova_sg
from heat.common import exception
from heat.common import short_id
from heat.common import template_format from heat.common import template_format
from heat.engine.clients.os import nova
from heat.engine import node_data
from heat.engine import resource from heat.engine import resource
from heat.engine.resources.aws.ec2 import security_group
from heat.engine import rsrc_defn from heat.engine import rsrc_defn
from heat.engine import scheduler from heat.engine import scheduler
from heat.engine import stack as parser from heat.engine import stack as parser
from heat.engine import template from heat.engine import template
from heat.tests import common from heat.tests import common
from heat.tests.openstack.nova import fakes as fakes_nova
from heat.tests import utils from heat.tests import utils
NovaSG = collections.namedtuple('NovaSG', NovaSG = collections.namedtuple('NovaSG',
@ -46,64 +37,6 @@ NovaSG = collections.namedtuple('NovaSG',
class SecurityGroupTest(common.HeatTestCase): class SecurityGroupTest(common.HeatTestCase):
test_template_nova = '''
HeatTemplateFormatVersion: '2012-12-12'
Resources:
the_sg:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: HTTP and SSH access
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: "22"
ToPort: "22"
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort : "80"
ToPort : "80"
CidrIp : 0.0.0.0/0
- IpProtocol: tcp
SourceSecurityGroupName: test
- IpProtocol: icmp
SourceSecurityGroupId: "1"
'''
test_template_nova_bad_source_group = '''
HeatTemplateFormatVersion: '2012-12-12'
Resources:
the_sg:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: HTTP and SSH access
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: "22"
ToPort: "22"
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort : "80"
ToPort : "80"
CidrIp : 0.0.0.0/0
- IpProtocol: tcp
SourceSecurityGroupName: thisdoesnotexist
- IpProtocol: icmp
SourceSecurityGroupId: "1"
'''
test_template_nova_with_egress = '''
HeatTemplateFormatVersion: '2012-12-12'
Resources:
the_sg:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: HTTP and SSH access
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: "22"
ToPort: "22"
CidrIp: 0.0.0.0/0
'''
test_template_neutron = ''' test_template_neutron = '''
HeatTemplateFormatVersion: '2012-12-12' HeatTemplateFormatVersion: '2012-12-12'
Resources: Resources:
@ -133,15 +66,6 @@ Resources:
def setUp(self): def setUp(self):
super(SecurityGroupTest, self).setUp() super(SecurityGroupTest, self).setUp()
self.fc = fakes_nova.FakeClient()
self.m.StubOutWithMock(nova.NovaClientPlugin, '_create')
self.m.StubOutWithMock(nova_sgr.SecurityGroupRuleManager, 'create')
self.m.StubOutWithMock(nova_sgr.SecurityGroupRuleManager, 'delete')
self.m.StubOutWithMock(nova_sg.SecurityGroupManager, 'create')
self.m.StubOutWithMock(nova_sg.SecurityGroupManager, 'delete')
self.m.StubOutWithMock(nova_sg.SecurityGroupManager, 'get')
self.m.StubOutWithMock(nova_sg.SecurityGroupManager, 'list')
self.m.StubOutWithMock(nova_sg.SecurityGroupManager, 'update')
self.m.StubOutWithMock(neutronclient.Client, 'create_security_group') self.m.StubOutWithMock(neutronclient.Client, 'create_security_group')
self.m.StubOutWithMock( self.m.StubOutWithMock(
neutronclient.Client, 'create_security_group_rule') neutronclient.Client, 'create_security_group_rule')
@ -176,99 +100,6 @@ Resources:
self.assertEqual(ref_id, rsrc.FnGetRefId()) self.assertEqual(ref_id, rsrc.FnGetRefId())
self.assertEqual(metadata, dict(rsrc.metadata_get())) self.assertEqual(metadata, dict(rsrc.metadata_get()))
def stubout_nova_create_security_group(self):
# create script
self.mock_no_neutron()
nova.NovaClientPlugin._create().AndReturn(self.fc)
nova_sg.SecurityGroupManager.list().AndReturn([NovaSG(
id=1,
name='test',
description='FAKE_SECURITY_GROUP',
rules=[],
)])
nova_sg.SecurityGroupManager.list().AndReturn([NovaSG(
id=1,
name='test',
description='FAKE_SECURITY_GROUP',
rules=[],
)])
sg_name = utils.PhysName('test_stack', 'the_sg')
nova_sg.SecurityGroupManager.create(
sg_name,
'HTTP and SSH access').AndReturn(NovaSG(
id=2,
name=sg_name,
description='HTTP and SSH access',
rules=[]))
nova_sgr.SecurityGroupRuleManager.create(
2, 'tcp', 22, 22, '0.0.0.0/0', None).AndReturn(None)
nova_sgr.SecurityGroupRuleManager.create(
2, 'tcp', 80, 80, '0.0.0.0/0', None).AndReturn(None)
nova_sgr.SecurityGroupRuleManager.create(
2, 'tcp', None, None, None, 1).AndReturn(None)
nova_sgr.SecurityGroupRuleManager.create(
2, 'icmp', None, None, None, '1').AndReturn(None)
return sg_name
def stubout_nova_get_security_group(self, sg_name):
nova_sg.SecurityGroupManager.get(2).AndReturn(NovaSG(
id=2,
name=sg_name,
description='',
rules=[{
"from_port": 22,
"group": {},
"ip_protocol": "tcp",
"to_port": 22,
"parent_group_id": 2,
"ip_range": {
"cidr": "0.0.0.0/0"
},
'id': 130
}, {
'from_port': 80,
'group': {},
'ip_protocol': 'tcp',
'to_port': 80,
'parent_group_id': 2,
'ip_range': {
'cidr': '0.0.0.0/0'
},
'id': 131
}, {
'from_port': None,
'group': {
'tenant_id': 'f18ca530cc05425e8bac0a5ff92f7e88',
'name': 'test'
},
'ip_protocol': 'tcp',
'to_port': None,
'parent_group_id': 2,
'ip_range': {},
'id': 132
}, {
'from_port': None,
'group': {
'tenant_id': 'f18ca530cc05425e8bac0a5ff92f7e88',
'name': 'test'
},
'ip_protocol': 'icmp',
'to_port': None,
'parent_group_id': 2,
'ip_range': {},
'id': 133
}]
))
def stubout_nova_delete_security_group_rules(self, sg_name):
self.stubout_nova_get_security_group(sg_name)
nova_sgr.SecurityGroupRuleManager.delete(130).AndReturn(None)
nova_sgr.SecurityGroupRuleManager.delete(131).AndReturn(None)
nova_sgr.SecurityGroupRuleManager.delete(132).AndReturn(None)
nova_sgr.SecurityGroupRuleManager.delete(133).AndReturn(None)
def stubout_neutron_create_security_group(self): def stubout_neutron_create_security_group(self):
sg_name = utils.PhysName('test_stack', 'the_sg') sg_name = utils.PhysName('test_stack', 'the_sg')
neutronclient.Client.create_security_group({ neutronclient.Client.create_security_group({
@ -506,202 +337,6 @@ Resources:
neutronclient.Client.delete_security_group_rule('eeee').AndReturn(None) neutronclient.Client.delete_security_group_rule('eeee').AndReturn(None)
neutronclient.Client.delete_security_group_rule('ffff').AndReturn(None) neutronclient.Client.delete_security_group_rule('ffff').AndReturn(None)
def test_security_group_nova(self):
# create script
sg_name = self.stubout_nova_create_security_group()
# delete script
self.stubout_nova_delete_security_group_rules(sg_name)
nova_sg.SecurityGroupManager.delete(2).AndReturn(None)
self.m.ReplayAll()
stack = self.create_stack(self.test_template_nova)
sg = stack['the_sg']
self.assertResourceState(sg, utils.PhysName('test_stack', 'the_sg'))
stack.delete()
self.m.VerifyAll()
def test_security_group_nova_bad_source_group(self):
# create script
self.mock_no_neutron()
nova.NovaClientPlugin._create().AndReturn(self.fc)
nova_sg.SecurityGroupManager.list().MultipleTimes().AndReturn([NovaSG(
id=1,
name='test',
description='FAKE_SECURITY_GROUP',
rules=[],
)])
sg_name = utils.PhysName('test_stack', 'the_sg')
nova_sg.SecurityGroupManager.create(
sg_name,
'HTTP and SSH access').AndReturn(NovaSG(
id=2,
name=sg_name,
description='HTTP and SSH access',
rules=[]))
# delete script
nova_sg.SecurityGroupManager.get(2).AndReturn(NovaSG(
id=2,
name=sg_name,
description='HTTP and SSH access',
rules=[{
"from_port": 22,
"group": {},
"ip_protocol": "tcp",
"to_port": 22,
"parent_group_id": 2,
"ip_range": {
"cidr": "0.0.0.0/0"
},
'id': 130
}, {
'from_port': 80,
'group': {},
'ip_protocol': 'tcp',
'to_port': 80,
'parent_group_id': 2,
'ip_range': {
'cidr': '0.0.0.0/0'
},
'id': 131
}]
))
nova_sgr.SecurityGroupRuleManager.delete(130).AndReturn(None)
nova_sgr.SecurityGroupRuleManager.delete(131).AndReturn(None)
nova_sg.SecurityGroupManager.delete(2).AndReturn(None)
self.m.ReplayAll()
stack = self.create_stack(self.test_template_nova_bad_source_group)
sg = stack['the_sg']
self.assertEqual(sg.FAILED, sg.status)
self.assertIn('not found', sg.status_reason)
stack.delete()
self.m.VerifyAll()
def test_security_group_nova_exception(self):
# create script
self.mock_no_neutron()
nova.NovaClientPlugin._create().AndReturn(self.fc)
sg_name = utils.PhysName('test_stack', 'the_sg')
nova_sg.SecurityGroupManager.list().MultipleTimes().AndReturn([
NovaSG(
id=2,
name=sg_name,
description='HTTP and SSH access',
rules=[],
),
NovaSG(
id=1,
name='test',
description='FAKE_SECURITY_GROUP',
rules=[],
)
])
nova_sgr.SecurityGroupRuleManager.create(
2, 'tcp', 22, 22, '0.0.0.0/0', None).AndRaise(
fakes_nova.fake_exception(400, 'Rule already exists'))
nova_sgr.SecurityGroupRuleManager.create(
2, 'tcp', 80, 80, '0.0.0.0/0', None).AndReturn(
fakes_nova.fake_exception(400, 'Rule already exists'))
nova_sgr.SecurityGroupRuleManager.create(
2, 'tcp', None, None, None, 1).AndReturn(
fakes_nova.fake_exception(400, 'Rule already exists'))
nova_sgr.SecurityGroupRuleManager.create(
2, 'icmp', None, None, None, '1').AndReturn(
fakes_nova.fake_exception(400, 'Rule already exists'))
# delete script
nova_sg.SecurityGroupManager.get(2).AndReturn(NovaSG(
id=2,
name=sg_name,
description='HTTP and SSH access',
rules=[{
"from_port": 22,
"group": {},
"ip_protocol": "tcp",
"to_port": 22,
"parent_group_id": 2,
"ip_range": {
"cidr": "0.0.0.0/0"
},
'id': 130
}, {
'from_port': 80,
'group': {},
'ip_protocol': 'tcp',
'to_port': 80,
'parent_group_id': 2,
'ip_range': {
'cidr': '0.0.0.0/0'
},
'id': 131
}, {
'from_port': None,
'group': {
'tenant_id': 'f18ca530cc05425e8bac0a5ff92f7e88',
'name': 'test'
},
'ip_protocol': 'tcp',
'to_port': None,
'parent_group_id': 2,
'ip_range': {},
'id': 132
}, {
'from_port': None,
'group': {
'tenant_id': 'f18ca530cc05425e8bac0a5ff92f7e88',
'name': 'test'
},
'ip_protocol': 'icmp',
'to_port': None,
'parent_group_id': 2,
'ip_range': {},
'id': 133
}]
))
nova_sgr.SecurityGroupRuleManager.delete(130).AndRaise(
fakes_nova.fake_exception())
nova_sgr.SecurityGroupRuleManager.delete(131).AndRaise(
fakes_nova.fake_exception())
nova_sgr.SecurityGroupRuleManager.delete(132).AndRaise(
fakes_nova.fake_exception())
nova_sgr.SecurityGroupRuleManager.delete(133).AndRaise(
fakes_nova.fake_exception())
nova_sg.SecurityGroupManager.delete(2).AndReturn(None)
nova_sg.SecurityGroupManager.get(2).AndRaise(
fakes_nova.fake_exception())
self.m.ReplayAll()
stack = self.create_stack(self.test_template_nova)
sg = stack['the_sg']
self.assertResourceState(sg, utils.PhysName('test_stack', 'the_sg'))
scheduler.TaskRunner(sg.delete)()
sg.state_set(sg.CREATE, sg.COMPLETE, 'to delete again')
sg.resource_id = 2
stack.delete()
self.m.VerifyAll()
def test_security_group_nova_with_egress_rules(self):
self.mock_no_neutron()
t = template_format.parse(self.test_template_nova_with_egress)
stack = self.parse_stack(t)
sg = stack['the_sg']
self.assertRaises(exception.EgressRuleNotAllowed, sg.validate)
def test_security_group_neutron(self): def test_security_group_neutron(self):
# create script # create script
self.stubout_neutron_create_security_group() self.stubout_neutron_create_security_group()
@ -898,65 +533,6 @@ Resources:
self.m.VerifyAll() self.m.VerifyAll()
def test_security_group_nova_update(self):
# create script
sg_name = self.stubout_nova_create_security_group()
# update script
nova_sg.SecurityGroupManager.list().MultipleTimes().AndReturn([
NovaSG(id='1',
name='test',
description='FAKE_SECURITY_GROUP',
rules=[]),
NovaSG(id='2',
name=sg_name,
description='HTTPS access',
rules=[]),
NovaSG(id='3',
name='test2',
description='FAKE_SECURITY_GROUP',
rules=[]),
])
# remove deleted groups
self.stubout_nova_get_security_group(sg_name)
nova_sgr.SecurityGroupRuleManager.delete(131).AndReturn(None)
nova_sgr.SecurityGroupRuleManager.delete(132).AndReturn(None)
# create missing groups
nova_sgr.SecurityGroupRuleManager.create(
2, 'tcp', 443, 443, '0.0.0.0/0', None).AndReturn(None)
nova_sgr.SecurityGroupRuleManager.create(
2, 'tcp', None, None, None, '3').AndReturn(None)
self.m.ReplayAll()
stack = self.create_stack(self.test_template_nova)
sg = stack['the_sg']
self.assertResourceState(sg, utils.PhysName('test_stack', 'the_sg'))
# make updated template
props = copy.deepcopy(sg.properties.data)
props['SecurityGroupIngress'] = [
{'IpProtocol': 'tcp',
'FromPort': '22',
'ToPort': '22',
'CidrIp': '0.0.0.0/0'},
{'IpProtocol': 'tcp',
'FromPort': '443',
'ToPort': '443',
'CidrIp': '0.0.0.0/0'},
{'IpProtocol': 'tcp',
'SourceSecurityGroupName': 'test2'},
{'IpProtocol': 'icmp',
'SourceSecurityGroupId': '1'},
]
after = rsrc_defn.ResourceDefinition(sg.name, sg.type(), props)
scheduler.TaskRunner(sg.update, after)()
self.assertEqual((sg.UPDATE, sg.COMPLETE), sg.state)
self.m.VerifyAll()
def test_security_group_neutron_update(self): def test_security_group_neutron_update(self):
# create script # create script
self.stubout_neutron_create_security_group() self.stubout_neutron_create_security_group()
@ -1107,39 +683,3 @@ Resources:
self.assertEqual((sg.UPDATE, sg.COMPLETE), sg.state) self.assertEqual((sg.UPDATE, sg.COMPLETE), sg.state)
self.m.VerifyAll() self.m.VerifyAll()
@mock.patch.object(security_group.SecurityGroup, 'is_using_neutron')
def test_security_group_refid_rsrc_name(self, mock_using_neutron):
mock_using_neutron.return_value = False
t = template_format.parse(self.test_template_nova)
stack = utils.parse_stack(t)
rsrc = stack['the_sg']
rsrc.id = '123'
rsrc.uuid = '9bfb9456-3fe8-41f4-b318-9dba18eeef74'
rsrc.action = 'CREATE'
expected = '%s-%s-%s' % (rsrc.stack.name,
rsrc.name,
short_id.get_id(rsrc.uuid))
self.assertEqual(expected, rsrc.FnGetRefId())
@mock.patch.object(security_group.SecurityGroup, 'is_using_neutron')
def test_security_group_refid_rsrc_id(self, mock_using_neutron):
mock_using_neutron.return_value = True
t = template_format.parse(self.test_template_nova)
stack = utils.parse_stack(t)
rsrc = stack['the_sg']
rsrc.resource_id = 'phy-rsrc-id'
self.assertEqual('phy-rsrc-id', rsrc.FnGetRefId())
def test_security_group_refid_convg_cache_data(self):
t = template_format.parse(self.test_template_nova)
cache_data = {'the_sg': node_data.NodeData.from_dict({
'uuid': mock.ANY,
'id': mock.ANY,
'action': 'CREATE',
'status': 'COMPLETE',
'reference_id': 'convg_xyz'
})}
stack = utils.parse_stack(t, cache_data=cache_data)
rsrc = stack['the_sg']
self.assertEqual('convg_xyz', rsrc.FnGetRefId())

View File

@ -176,57 +176,6 @@ class NovaClientPluginTest(NovaClientPluginTestCase):
mock.call('idontexist')] mock.call('idontexist')]
self.nova_client.servers.get.assert_has_calls(calls) self.nova_client.servers.get.assert_has_calls(calls)
def test_get_network_id_by_label(self):
"""Tests the get_net_id_by_label function."""
net = mock.MagicMock()
net.id = str(uuid.uuid4())
self.nova_client.networks.find.side_effect = [
net, nova_exceptions.NotFound(404),
nova_exceptions.NoUniqueMatch()]
self.assertEqual(net.id,
self.nova_plugin.get_net_id_by_label('net_label'))
exc = self.assertRaises(
exception.EntityNotFound,
self.nova_plugin.get_net_id_by_label, 'idontexist')
expected = 'The Nova network (idontexist) could not be found'
self.assertIn(expected, six.text_type(exc))
exc = self.assertRaises(
exception.PhysicalResourceNameAmbiguity,
self.nova_plugin.get_net_id_by_label, 'notUnique')
expected = ('Multiple physical resources were found '
'with name (notUnique)')
self.assertIn(expected, six.text_type(exc))
calls = [mock.call(label='net_label'),
mock.call(label='idontexist'),
mock.call(label='notUnique')]
self.nova_client.networks.find.assert_has_calls(calls)
def test_get_nova_network_id(self):
"""Tests the get_nova_network_id function."""
net = mock.MagicMock()
net.id = str(uuid.uuid4())
not_existent_net_id = str(uuid.uuid4())
self.nova_client.networks.get.side_effect = [
net, nova_exceptions.NotFound(404)]
self.nova_client.networks.find.side_effect = [
nova_exceptions.NotFound(404)]
self.assertEqual(net.id,
self.nova_plugin.get_nova_network_id(net.id))
exc = self.assertRaises(
exception.EntityNotFound,
self.nova_plugin.get_nova_network_id, not_existent_net_id)
expected = ('The Nova network (%s) could not be found' %
not_existent_net_id)
self.assertIn(expected, six.text_type(exc))
calls = [mock.call(net.id),
mock.call(not_existent_net_id)]
self.nova_client.networks.get.assert_has_calls(calls)
self.nova_client.networks.find.assert_called_once_with(
label=not_existent_net_id)
def test_get_status(self): def test_get_status(self):
server = self.m.CreateMockAnything() server = self.m.CreateMockAnything()
server.status = 'ACTIVE' server.status = 'ACTIVE'
@ -556,39 +505,6 @@ class FlavorConstraintTest(common.HeatTestCase):
self.assertEqual(2, client.flavors.find.call_count) self.assertEqual(2, client.flavors.find.call_count)
class NetworkConstraintTest(common.HeatTestCase):
def test_validate(self):
client = fakes_nova.FakeClient()
self.stub_keystoneclient()
self.patchobject(nova.NovaClientPlugin, '_create', return_value=client)
client.networks = mock.Mock()
network = collections.namedtuple("Network", ['id', 'label'])
network.id = '7f47ff06-0353-4013-b814-123b70b1b27d'
network.label = 'foo'
client.networks.get.return_value = network
constraint = nova.NetworkConstraint()
ctx = utils.dummy_context()
self.assertTrue(constraint.validate(network.id, ctx))
client.networks.get.side_effect = nova_exceptions.NotFound('')
client.networks.find.return_value = network
self.assertTrue(constraint.validate(network.id, ctx))
client.networks.find.side_effect = nova_exceptions.NotFound('')
self.assertFalse(constraint.validate(network.id, ctx))
client.networks.find.side_effect = nova_exceptions.NoUniqueMatch()
self.assertFalse(constraint.validate(network.id, ctx))
network.id = 'nonuuid'
client.networks.find.return_value = network
client.networks.find.side_effect = None
self.assertTrue(constraint.validate(network.id, ctx))
class HostConstraintTest(common.HeatTestCase): class HostConstraintTest(common.HeatTestCase):
def setUp(self): def setUp(self):

View File

@ -298,10 +298,6 @@ class HeatTestCase(testscenarios.WithScenarios,
validate = self.patchobject(neutron.QoSPolicyConstraint, 'validate') validate = self.patchobject(neutron.QoSPolicyConstraint, 'validate')
validate.return_value = True validate.return_value = True
def stub_NovaNetworkConstraint(self):
validate = self.patchobject(nova.NetworkConstraint, 'validate')
validate.return_value = True
def stub_KeystoneProjectConstraint(self): def stub_KeystoneProjectConstraint(self):
validate = self.patchobject(ks_constr.KeystoneProjectConstraint, validate = self.patchobject(ks_constr.KeystoneProjectConstraint,
'validate') 'validate')

View File

@ -47,7 +47,9 @@ class ResourceTypeTest(common.HeatTestCase):
'OS::Designate::Record', 'OS::Designate::Record',
'OS::Heat::HARestarter', 'OS::Heat::HARestarter',
'OS::Magnum::Bay', 'OS::Magnum::Bay',
'OS::Glance::Image']), 'OS::Glance::Image',
'OS::Nova::FloatingIP',
'OS::Nova::FloatingIPAssociation']),
set(resources)) set(resources))
@mock.patch.object(res.Resource, 'is_service_available') @mock.patch.object(res.Resource, 'is_service_available')

View File

@ -15,7 +15,6 @@ import mock
from heat.common import exception from heat.common import exception
from heat.common import template_format from heat.common import template_format
from heat.engine.clients.os import nova
from heat.engine.resources.openstack.manila import share_network from heat.engine.resources.openstack.manila import share_network
from heat.engine import scheduler from heat.engine import scheduler
from heat.tests import common from heat.tests import common
@ -68,17 +67,10 @@ class ManilaShareNetworkTest(common.HeatTestCase):
def resolve_neutron(resource_type, name): def resolve_neutron(resource_type, name):
return name return name
def resolve_nova(name):
return name
self.client_plugin.find_resourceid_by_name_or_id.side_effect = ( self.client_plugin.find_resourceid_by_name_or_id.side_effect = (
resolve_neutron resolve_neutron
) )
self.client_plugin.get_nova_network_id.side_effect = (
resolve_nova
)
self.patchobject(share_network.ManilaShareNetwork, 'client_plugin', self.patchobject(share_network.ManilaShareNetwork, 'client_plugin',
return_value=self.client_plugin) return_value=self.client_plugin)
@ -89,7 +81,6 @@ class ManilaShareNetworkTest(common.HeatTestCase):
return_network return_network
) )
self.stub_NetworkConstraint_validate() self.stub_NetworkConstraint_validate()
self.stub_NovaNetworkConstraint()
self.stub_SubnetConstraint_validate() self.stub_SubnetConstraint_validate()
def _create_network(self, name, snippet, stack, use_neutron=True): def _create_network(self, name, snippet, stack, use_neutron=True):
@ -275,17 +266,6 @@ class ManilaShareNetworkTest(common.HeatTestCase):
self.assertRaisesRegexp(exception.ResourcePropertyDependency, msg, self.assertRaisesRegexp(exception.ResourcePropertyDependency, msg,
net.validate) net.validate)
def test_nova_constraint_fail(self):
validate = self.patchobject(nova.NetworkConstraint, 'validate')
validate.return_value = False
t = template_format.parse(stack_template)
t['resources']['share_network']['properties']['nova_network'] = 1
stack = utils.parse_stack(t)
rsrc_defn = stack.t.resource_definitions(stack)['share_network']
self.assertRaises(exception.ResourceFailure,
self._create_network, 'share_network',
rsrc_defn, stack)
def test_attributes(self): def test_attributes(self):
net = self._create_network('share_network', self.rsrc_defn, net = self._create_network('share_network', self.rsrc_defn,
self.stack) self.stack)

View File

@ -16,8 +16,6 @@ import mox
from neutronclient.common import exceptions as neutron_exc from neutronclient.common import exceptions as neutron_exc
from neutronclient.neutron import v2_0 as neutronV20 from neutronclient.neutron import v2_0 as neutronV20
from neutronclient.v2_0 import client as neutronclient from neutronclient.v2_0 import client as neutronclient
from novaclient.v2 import security_group_rules as nova_sgr
from novaclient.v2 import security_groups as nova_sg
from heat.common import exception from heat.common import exception
from heat.common import template_format from heat.common import template_format
@ -26,7 +24,6 @@ from heat.engine import scheduler
from heat.engine import stack as parser from heat.engine import stack as parser
from heat.engine import template from heat.engine import template
from heat.tests import common from heat.tests import common
from heat.tests.openstack.nova import fakes as fakes_nova
from heat.tests import utils from heat.tests import utils
@ -89,13 +86,6 @@ resources:
def setUp(self): def setUp(self):
super(SecurityGroupTest, self).setUp() super(SecurityGroupTest, self).setUp()
self.fc = fakes_nova.FakeClient()
self.m.StubOutWithMock(nova_sgr.SecurityGroupRuleManager, 'create')
self.m.StubOutWithMock(nova_sgr.SecurityGroupRuleManager, 'delete')
self.m.StubOutWithMock(nova_sg.SecurityGroupManager, 'create')
self.m.StubOutWithMock(nova_sg.SecurityGroupManager, 'delete')
self.m.StubOutWithMock(nova_sg.SecurityGroupManager, 'get')
self.m.StubOutWithMock(nova_sg.SecurityGroupManager, 'list')
self.m.StubOutWithMock(neutronclient.Client, 'create_security_group') self.m.StubOutWithMock(neutronclient.Client, 'create_security_group')
self.m.StubOutWithMock( self.m.StubOutWithMock(
neutronclient.Client, 'create_security_group_rule') neutronclient.Client, 'create_security_group_rule')

View File

@ -224,9 +224,7 @@ class ServersTest(common.HeatTestCase):
self.limits = self.m.CreateMockAnything() self.limits = self.m.CreateMockAnything()
self.limits.absolute = self._limits_absolute() self.limits.absolute = self._limits_absolute()
self.mock_flavor = mock.Mock(ram=4, disk=4) self.mock_flavor = mock.Mock(ram=4, disk=4)
self.mock_image = mock.Mock(min_ram=1, min_disk=1, status='active') self.mock_image = mock.Mock(min_ram=1, min_disk=1, status='ACTIVE')
self.patchobject(resource.Resource, 'is_using_neutron',
return_value=True)
def flavor_side_effect(*args): def flavor_side_effect(*args):
return 2 if args[0] == 'm1.small' else 1 return 2 if args[0] == 'm1.small' else 1
@ -329,6 +327,8 @@ class ServersTest(common.HeatTestCase):
self.patchobject(server, 'store_external_ports') self.patchobject(server, 'store_external_ports')
self.patchobject(nova.NovaClientPlugin, '_create', self.patchobject(nova.NovaClientPlugin, '_create',
return_value=self.fc) return_value=self.fc)
self.patchobject(glance.GlanceClientPlugin, 'get_image',
return_value=self.mock_image)
if stub_create: if stub_create:
self.patchobject(self.fc.servers, 'create', self.patchobject(self.fc.servers, 'create',
return_value=return_server) return_value=return_server)
@ -1413,46 +1413,6 @@ class ServersTest(common.HeatTestCase):
"time: networks/fixed_ip, networks/port.", "time: networks/fixed_ip, networks/port.",
six.text_type(error)) six.text_type(error))
def test_server_validate_with_port_not_using_neutron(self):
test_templ = with_port_template.replace('fixed_ip: 10.0.0.99', '')
stack_name = 'with_port_in_nova_network'
(tmpl, stack) = self._setup_test_stack(stack_name,
test_templ=test_templ)
self.patchobject(servers.Server,
'is_using_neutron', return_value=False)
resource_defns = tmpl.resource_definitions(stack)
server = servers.Server('port_reference_use_nova_network',
resource_defns['server'], stack)
self.patchobject(glance.GlanceClientPlugin, 'get_image',
return_value=self.mock_image)
self.patchobject(nova.NovaClientPlugin, 'get_flavor',
return_value=self.mock_flavor)
error = self.assertRaises(exception.StackValidationFailed,
server.validate)
self.assertEqual('Property "port" is supported only for Neutron.',
six.text_type(error))
# test if port doesn't reference with non-created resource
tmpl['Resources']['server']['Properties']['networks'] = (
[{'port': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'}])
# We're patching neutron finder here as constraint validation
# does not check if neutron is enabled or not. This would be
# fixed in a subsequent patch.
self.patchobject(neutron.NeutronClientPlugin,
'find_resourceid_by_name_or_id')
resource_defns = tmpl.resource_definitions(stack)
server = servers.Server('validate_port_in_nova_network',
resource_defns['server'], stack)
error = self.assertRaises(exception.StackValidationFailed,
server.validate)
self.assertEqual('Property "port" is supported only for Neutron.',
six.text_type(error))
def test_server_validate_with_uuid_fixed_ip(self): def test_server_validate_with_uuid_fixed_ip(self):
stack_name = 'srv_net' stack_name = 'srv_net'
(tmpl, stack) = self._setup_test_stack(stack_name) (tmpl, stack) = self._setup_test_stack(stack_name)
@ -1896,10 +1856,11 @@ class ServersTest(common.HeatTestCase):
self.patchobject(return_server, 'interface_list', self.patchobject(return_server, 'interface_list',
return_value=[iface, iface1, iface2]) return_value=[iface, iface1, iface2])
self.patchobject(nova.NovaClientPlugin, 'get_net_id_by_label', self.patchobject(neutron.NeutronClientPlugin,
'find_resourceid_by_name_or_id',
side_effect=['public_id', side_effect=['public_id',
'private_id']) 'private_id'])
reality = server.get_live_state(server.properties) reality = server.get_live_state(server.properties.data)
expected = {'flavor': '1', expected = {'flavor': '1',
'image': '2', 'image': '2',
@ -2483,7 +2444,6 @@ class ServersTest(common.HeatTestCase):
return_server = self.fc.servers.list()[1] return_server = self.fc.servers.list()[1]
server = self._create_test_server(return_server, server = self._create_test_server(return_server,
'test_server_create') 'test_server_create')
self.patchobject(server, 'is_using_neutron', return_value=True)
self.patchobject(neutronclient.Client, 'create_port', self.patchobject(neutronclient.Client, 'create_port',
return_value={'port': {'id': '4815162342'}}) return_value={'port': {'id': '4815162342'}})
@ -2509,12 +2469,6 @@ class ServersTest(common.HeatTestCase):
[{'network': [{'network':
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'}])) 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'}]))
self.patchobject(server, 'is_using_neutron', return_value=False)
self.assertEqual([{'net-id': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'}],
server._build_nics(
[{'network':
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'}]))
def test_server_network_errors(self): def test_server_network_errors(self):
stack_name = 'net_err' stack_name = 'net_err'
(tmpl, stack) = self._setup_test_stack(stack_name, (tmpl, stack) = self._setup_test_stack(stack_name,
@ -2540,11 +2494,13 @@ class ServersTest(common.HeatTestCase):
return_server.id = '9102' return_server.id = '9102'
server = self._create_test_server(return_server, server = self._create_test_server(return_server,
'wo_ipaddr') 'wo_ipaddr')
self.patchobject(neutron.NeutronClientPlugin,
'find_resourceid_by_name_or_id',
return_value=None)
self.patchobject(self.fc.servers, 'get', return_value=return_server) self.patchobject(self.fc.servers, 'get', return_value=return_server)
self.patchobject(return_server, 'interface_list', return_value=[]) self.patchobject(return_server, 'interface_list', return_value=[])
mock_detach = self.patchobject(return_server, 'interface_detach') mock_detach = self.patchobject(return_server, 'interface_detach')
mock_attach = self.patchobject(return_server, 'interface_attach') mock_attach = self.patchobject(return_server, 'interface_attach')
self.assertEqual({'empty_net': []}, server.FnGetAtt('addresses')) self.assertEqual({'empty_net': []}, server.FnGetAtt('addresses'))
self.assertEqual({'empty_net': []}, server.FnGetAtt('networks')) self.assertEqual({'empty_net': []}, server.FnGetAtt('networks'))
self.assertEqual(0, mock_detach.call_count) self.assertEqual(0, mock_detach.call_count)
@ -3164,7 +3120,8 @@ class ServersTest(common.HeatTestCase):
server.resource_id = '1234' server.resource_id = '1234'
server.networks = {"fake_net": ["10.0.0.3"]} server.networks = {"fake_net": ["10.0.0.3"]}
self.patchobject(self.fc.servers, 'get', return_value=server) self.patchobject(self.fc.servers, 'get', return_value=server)
self.patchobject(nova.NovaClientPlugin, 'get_net_id_by_label', self.patchobject(neutron.NeutronClientPlugin,
'find_resourceid_by_name_or_id',
return_value='fake_uuid') return_value='fake_uuid')
expect_networks = {"fake_uuid": ["10.0.0.3"], expect_networks = {"fake_uuid": ["10.0.0.3"],
"fake_net": ["10.0.0.3"]} "fake_net": ["10.0.0.3"]}
@ -3209,8 +3166,6 @@ class ServersTest(common.HeatTestCase):
return_server = self.fc.servers.list()[3] return_server = self.fc.servers.list()[3]
server = self._create_test_server(return_server, 'networks_update') server = self._create_test_server(return_server, 'networks_update')
self.patchobject(server, 'is_using_neutron', return_value=True)
net = {'port': '2a60cbaa-3d33-4af6-a9ce-83594ac546fc'} net = {'port': '2a60cbaa-3d33-4af6-a9ce-83594ac546fc'}
net_id = server._get_network_id(net) net_id = server._get_network_id(net)
self.assertIsNone(net_id) self.assertIsNone(net_id)
@ -3226,25 +3181,6 @@ class ServersTest(common.HeatTestCase):
net_id = server._get_network_id(net) net_id = server._get_network_id(net)
self.assertIsNone(net_id) self.assertIsNone(net_id)
def test_get_network_id_nova(self):
return_server = self.fc.servers.list()[3]
server = self._create_test_server(return_server, 'networks_update')
self.patchobject(server, 'is_using_neutron', return_value=False)
net = {'port': '2a60cbaa-3d33-4af6-a9ce-83594ac546fc'}
net_id = server._get_network_id(net)
self.assertIsNone(net_id)
net = {'network': 'f3ef5d2f-d7ba-4b27-af66-58ca0b81e032',
'fixed_ip': '1.2.3.4'}
self.patchobject(nova.NovaClientPlugin, 'get_nova_network_id',
return_value='f3ef5d2f-d7ba-4b27-af66-58ca0b81e032')
net_id = server._get_network_id(net)
self.assertEqual('f3ef5d2f-d7ba-4b27-af66-58ca0b81e032', net_id)
def test_exclude_not_updated_networks_no_matching(self): def test_exclude_not_updated_networks_no_matching(self):
return_server = self.fc.servers.list()[3] return_server = self.fc.servers.list()[3]
server = self._create_test_server(return_server, 'networks_update') server = self._create_test_server(return_server, 'networks_update')
@ -3904,7 +3840,9 @@ class ServersTest(common.HeatTestCase):
'test_server_snapshot') 'test_server_snapshot')
image_in_error = mock.Mock() image_in_error = mock.Mock()
image_in_error.status = image_status image_in_error.status = image_status
self.fc.images.get = mock.Mock(return_value=image_in_error)
self.patchobject(glance.GlanceClientPlugin, 'get_image',
return_value=image_in_error)
self.assertRaises(exception.ResourceFailure, self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(server.snapshot)) scheduler.TaskRunner(server.snapshot))
@ -3979,6 +3917,8 @@ class ServersTest(common.HeatTestCase):
stack.store() stack.store()
self.patchobject(nova.NovaClientPlugin, '_create', self.patchobject(nova.NovaClientPlugin, '_create',
return_value=self.fc) return_value=self.fc)
self.patchobject(glance.GlanceClientPlugin, 'get_image',
return_value=self.mock_image)
self.patchobject(stack['server'], 'store_external_ports') self.patchobject(stack['server'], 'store_external_ports')
return_server = self.fc.servers.list()[1] return_server = self.fc.servers.list()[1]
return_server.id = '1234' return_server.id = '1234'
@ -4031,6 +3971,9 @@ class ServersTest(common.HeatTestCase):
create_image = self.patchobject(self.fc.servers, 'create_image') create_image = self.patchobject(self.fc.servers, 'create_image')
create_image.return_value = image create_image.return_value = image
self.patchobject(glance.GlanceClientPlugin, 'get_image',
return_value=self.mock_image)
delete_server = self.patchobject(self.fc.servers, 'delete') delete_server = self.patchobject(self.fc.servers, 'delete')
delete_server.side_effect = nova_exceptions.NotFound(404) delete_server.side_effect = nova_exceptions.NotFound(404)
@ -4058,7 +4001,8 @@ class ServersTest(common.HeatTestCase):
mock_plugin = self.patchobject(nova.NovaClientPlugin, '_create') mock_plugin = self.patchobject(nova.NovaClientPlugin, '_create')
mock_plugin.return_value = self.fc mock_plugin.return_value = self.fc
self.patchobject(glance.GlanceClientPlugin, 'get_image',
return_value=self.mock_image)
return_server = self.fc.servers.list()[1] return_server = self.fc.servers.list()[1]
return_server.id = '1234' return_server.id = '1234'
mock_create = self.patchobject(self.fc.servers, 'create') mock_create = self.patchobject(self.fc.servers, 'create')
@ -4077,15 +4021,16 @@ class ServersTest(common.HeatTestCase):
self.assertEqual((stack.CREATE, stack.COMPLETE), stack.state) self.assertEqual((stack.CREATE, stack.COMPLETE), stack.state)
failed_image = { failed_image = mock.Mock(**{
'id': 456, 'id': 456,
'name': 'CentOS 5.2', 'name': 'CentOS 5.2',
'updated': '2010-10-10T12:00:00Z', 'updated': '2010-10-10T12:00:00Z',
'created': '2010-08-10T12:00:00Z', 'created': '2010-08-10T12:00:00Z',
'status': 'ERROR'} 'status': 'ERROR'})
self.fc.client.get_images_456 = lambda **kw: (
200, {'image': failed_image})
self.patchobject(glance.GlanceClientPlugin, 'get_image',
return_value=failed_image)
return_server = self.fc.servers.list()[1]
scheduler.TaskRunner(stack.delete)() scheduler.TaskRunner(stack.delete)()
self.assertEqual((stack.DELETE, stack.FAILED), stack.state) self.assertEqual((stack.DELETE, stack.FAILED), stack.state)
@ -4450,74 +4395,6 @@ class ServerInternalPortTest(ServersTest):
mock.call('internal_ports', '[]'), mock.call('internal_ports', '[]'),
mock.call('internal_ports', '[{"id": "7788"}]'))) mock.call('internal_ports', '[{"id": "7788"}]')))
def test_calculate_networks_nova_with_fipa(self):
tmpl = """
heat_template_version: 2015-10-15
resources:
server:
type: OS::Nova::Server
properties:
flavor: m1.small
image: F17-x86_64-gold
networks:
- network: 4321
subnet: 1234
fixed_ip: 127.0.0.1
floating_ip: 1199
- network: 8765
subnet: 5678
fixed_ip: 127.0.0.2
"""
t, stack, server = self._return_template_stack_and_rsrc_defn('test',
tmpl)
# NOTE(prazumovsky): this method update old_net and new_net with
# interfaces' ports. Because of uselessness of checking this method,
# we can afford to give port as part of calculate_networks args.
self.patchobject(server, 'update_networks_matching_iface_port')
self.patchobject(server.client_plugin(), 'get_nova_network_id',
side_effect=['4321', '8765'])
self.patchobject(server, 'is_using_neutron', return_value=False)
self.patchobject(resource.Resource, 'data_set')
FakeFIP = collections.namedtuple('FakeFip', ['ip'])
self.patchobject(server.client().floating_ips, 'get',
side_effect=[FakeFIP('192.168.0.1'),
FakeFIP('192.168.0.2'),
FakeFIP('192.168.0.1')])
fipa = self.patchobject(server.client().servers, 'add_floating_ip')
fip_disa = self.patchobject(server.client().servers,
'remove_floating_ip')
server.resource_id = '1234567890'
old_net = [{'network': '4321',
'subnet': '1234',
'fixed_ip': '127.0.0.1',
'floating_ip': '1199'},
{'network': '8765',
'subnet': '5678',
'fixed_ip': '127.0.0.2'}]
new_net = [{'network': '8765',
'subnet': '5678',
'fixed_ip': '127.0.0.2',
'floating_ip': '11910'},
{'network': '0912',
'subnet': '9021',
'fixed_ip': '127.0.0.1',
'floating_ip': '1199'}]
server.calculate_networks(old_net, new_net, [])
fip_disa.assert_called_once_with('1234567890',
'192.168.0.1')
fipa.assert_has_calls((
mock.call('1234567890', '192.168.0.2'),
mock.call('1234567890', '192.168.0.1')
))
def test_calculate_networks_internal_ports_with_fipa(self): def test_calculate_networks_internal_ports_with_fipa(self):
tmpl = """ tmpl = """
heat_template_version: 2015-10-15 heat_template_version: 2015-10-15
@ -4621,37 +4498,6 @@ class ServerInternalPortTest(ServersTest):
self.assertIsNone(server._floating_ip_disassociate('flip123')) self.assertIsNone(server._floating_ip_disassociate('flip123'))
self.assertEqual(1, delete_flip.call_count) self.assertEqual(1, delete_flip.call_count)
def test_delete_fipa_with_exception_not_found_nova(self):
tmpl = """
heat_template_version: 2015-10-15
resources:
server:
type: OS::Nova::Server
properties:
flavor: m1.small
image: F17-x86_64-gold
networks:
- network: 4321
subnet: 1234
fixed_ip: 127.0.0.1
floating_ip: 1199
- network: 8765
subnet: 5678
fixed_ip: 127.0.0.2
floating_ip: 9911
"""
t, stack, server = self._return_template_stack_and_rsrc_defn('test',
tmpl)
self.patchobject(server, 'is_using_neutron', return_value=False)
flip = mock.MagicMock()
flip.ip = 'flip123'
server.client().floating_ips = flip
server.client().servers.remove_floating_ip = mock.MagicMock(
side_effect=[nova_exceptions.NotFound(404)])
self.assertIsNone(server._floating_ip_disassociate('flip123'))
def test_delete_internal_ports(self): def test_delete_internal_ports(self):
t, stack, server = self._return_template_stack_and_rsrc_defn( t, stack, server = self._return_template_stack_and_rsrc_defn(
'test', tmpl_server_with_network_id) 'test', tmpl_server_with_network_id)

View File

@ -114,6 +114,7 @@ class SaharaNodeGroupTemplateTest(common.HeatTestCase):
self.patchobject(nova.NovaClientPlugin, 'find_flavor_by_name_or_id' self.patchobject(nova.NovaClientPlugin, 'find_flavor_by_name_or_id'
).return_value = 'someflavorid' ).return_value = 'someflavorid'
self.patchobject(neutron.NeutronClientPlugin, '_create') self.patchobject(neutron.NeutronClientPlugin, '_create')
self.patchobject(neutron.NeutronClientPlugin, self.patchobject(neutron.NeutronClientPlugin,
'find_resourceid_by_name_or_id', 'find_resourceid_by_name_or_id',
return_value='some_pool_id') return_value='some_pool_id')
@ -171,8 +172,6 @@ class SaharaNodeGroupTemplateTest(common.HeatTestCase):
def test_validate_floatingippool_on_neutron_fails(self): def test_validate_floatingippool_on_neutron_fails(self):
ngt = self._init_ngt(self.t) ngt = self._init_ngt(self.t)
self.patchobject(ngt, 'is_using_neutron').return_value = True
self.patchobject( self.patchobject(
neutron.NeutronClientPlugin, neutron.NeutronClientPlugin,
'find_resourceid_by_name_or_id' 'find_resourceid_by_name_or_id'
@ -188,25 +187,12 @@ class SaharaNodeGroupTemplateTest(common.HeatTestCase):
self.assertEqual('Not found', self.assertEqual('Not found',
six.text_type(ex)) six.text_type(ex))
def test_validate_floatingippool_on_novanetwork_fails(self):
ngt = self._init_ngt(self.t)
self.patchobject(ngt, 'is_using_neutron').return_value = False
nova_mock = mock.MagicMock()
nova_mock.floating_ip_pools.find.side_effect = (
nova.exceptions.NotFound(404, message='Not found'))
self.patchobject(nova.NovaClientPlugin,
'_create').return_value = nova_mock
ex = self.assertRaises(exception.StackValidationFailed, ngt.validate)
self.assertEqual('Not found (HTTP 404)', six.text_type(ex))
def test_validate_flavor_constraint_return_false(self): def test_validate_flavor_constraint_return_false(self):
self.t['resources']['node-group']['properties'].pop('floating_ip_pool') self.t['resources']['node-group']['properties'].pop('floating_ip_pool')
self.t['resources']['node-group']['properties'].pop('volume_type') self.t['resources']['node-group']['properties'].pop('volume_type')
ngt = self._init_ngt(self.t) ngt = self._init_ngt(self.t)
self.patchobject(nova.FlavorConstraint, 'validate' self.patchobject(nova.FlavorConstraint, 'validate'
).return_value = False ).return_value = False
self.patchobject(ngt, 'is_using_neutron').return_value = False
ex = self.assertRaises(exception.StackValidationFailed, ngt.validate) ex = self.assertRaises(exception.StackValidationFailed, ngt.validate)
self.assertEqual(u"Property error: " self.assertEqual(u"Property error: "
u"resources.node-group.properties.flavor: " u"resources.node-group.properties.flavor: "

View File

@ -22,7 +22,6 @@ from troveclient.v1 import users
from heat.common import exception from heat.common import exception
from heat.common import template_format from heat.common import template_format
from heat.engine.clients.os import neutron from heat.engine.clients.os import neutron
from heat.engine.clients.os import nova
from heat.engine.clients.os import trove from heat.engine.clients.os import trove
from heat.engine import resource from heat.engine import resource
from heat.engine.resources.openstack.trove import instance as dbinstance from heat.engine.resources.openstack.trove import instance as dbinstance
@ -541,28 +540,6 @@ class InstanceTest(common.HeatTestCase):
datastore_version=None, nics=[{'net-id': net_id}], replica_of=None, datastore_version=None, nics=[{'net-id': net_id}], replica_of=None,
replica_count=None) replica_count=None)
def test_instance_create_with_net_name(self):
t = template_format.parse(db_template_with_nics)
t['resources']['MySqlCloudDB']['properties']['networks'] = [
{'network': 'somenetname'}]
instance = self._setup_test_instance('dbinstance_test', t)
self.stub_NetworkConstraint_validate()
self.patchobject(instance, 'is_using_neutron', return_value=False)
novaclient = mock.Mock()
self.patchobject(nova.NovaClientPlugin, '_create',
return_value=novaclient)
fake_net = mock.Mock()
fake_net.id = 'somenetid'
novaclient.networks.find.return_value = fake_net
scheduler.TaskRunner(instance.create)()
self.assertEqual((instance.CREATE, instance.COMPLETE), instance.state)
self.client.instances.create.assert_called_once_with(
'test', '1', volume={'size': 30}, databases=[], users=[],
restorePoint=None, availability_zone=None, datastore=None,
datastore_version=None, nics=[{'net-id': 'somenetid'}],
replica_of=None, replica_count=None)
def test_instance_create_with_replication(self): def test_instance_create_with_replication(self):
t = template_format.parse(db_template_with_replication) t = template_format.parse(db_template_with_replication)
instance = self._setup_test_instance('dbinstance_test', t) instance = self._setup_test_instance('dbinstance_test', t)

View File

@ -0,0 +1,7 @@
---
deprecations:
- nova-network is no longer supported in OpenStack. Please use
OS::Neutron::FloatingIPAssociation and OS::Neutron::FloatingIP in place of
OS::Nova::FloatingIPAssociation and OS::Nova::FloatingIP
- The AWS::EC2::EIP domain is always assumed to be 'vpc', since nova-network
is not supported in OpenStack any longer.

View File

@ -139,7 +139,7 @@ heat.constraints =
nova.flavor = heat.engine.clients.os.nova:FlavorConstraint nova.flavor = heat.engine.clients.os.nova:FlavorConstraint
nova.host = heat.engine.clients.os.nova:HostConstraint nova.host = heat.engine.clients.os.nova:HostConstraint
nova.keypair = heat.engine.clients.os.nova:KeypairConstraint nova.keypair = heat.engine.clients.os.nova:KeypairConstraint
nova.network = heat.engine.clients.os.nova:NetworkConstraint nova.network = heat.engine.constraint.common_constraints:TestConstraintDelay
nova.server = heat.engine.clients.os.nova:ServerConstraint nova.server = heat.engine.clients.os.nova:ServerConstraint
sahara.cluster = heat.engine.clients.os.sahara:ClusterConstraint sahara.cluster = heat.engine.clients.os.sahara:ClusterConstraint
sahara.cluster_template = heat.engine.clients.os.sahara:ClusterTemplateConstraint sahara.cluster_template = heat.engine.clients.os.sahara:ClusterTemplateConstraint