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.i18n import _
from heat.engine.clients.os import nova
from heat.engine import constraints
CLIENT_NAME = 'neutron'
@ -30,15 +29,9 @@ class NetworkConstraint(constraints.BaseCustomConstraint):
exception.PhysicalResourceNameAmbiguity)
def validate_with_client(self, client, value):
try:
client.client(CLIENT_NAME)
except Exception:
# 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)
neutron_plugin = client.client_plugin(CLIENT_NAME)
neutron_plugin.find_resourceid_by_name_or_id(
'network', value, cmd_resource=None)
class NeutronConstraint(constraints.BaseCustomConstraint):

View File

@ -24,7 +24,6 @@ from novaclient import exceptions
from oslo_config import cfg
from oslo_log import log as logging
from oslo_serialization import jsonutils
from oslo_utils import uuidutils
import six
from six.moves.urllib import parse as urlparse
import tenacity
@ -637,30 +636,6 @@ echo -e '%s\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers
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):
try:
va = self.client().volumes.create_server_volume(
@ -796,14 +771,6 @@ class FlavorConstraint(NovaBaseConstraint):
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):
resource_getter_name = 'get_host'

View File

@ -12,7 +12,6 @@
# under the License.
from oslo_log import log as logging
from oslo_utils import excutils
import six
from heat.common import exception
@ -23,6 +22,7 @@ from heat.engine import properties
from heat.engine import resource
from heat.engine.resources.aws.ec2 import internet_gateway
from heat.engine.resources.aws.ec2 import vpc
from heat.engine import support
LOG = logging.getLogger(__name__)
@ -45,6 +45,12 @@ class ElasticIp(resource.Resource):
properties.Schema.STRING,
_('Set to "vpc" to have IP address allocation associated to your '
'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.AllowedValues(['vpc']),
]
@ -76,47 +82,25 @@ class ElasticIp(resource.Resource):
def _ipaddress(self):
if self.ipaddress is None and self.resource_id is not None:
if self.properties[self.DOMAIN]:
try:
ips = self.neutron().show_floatingip(self.resource_id)
except Exception as ex:
self.client_plugin('neutron').ignore_not_found(ex)
else:
self.ipaddress = ips['floatingip']['floating_ip_address']
try:
ips = self.neutron().show_floatingip(self.resource_id)
except Exception as ex:
self.client_plugin('neutron').ignore_not_found(ex)
else:
try:
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
self.ipaddress = ips['floatingip']['floating_ip_address']
return self.ipaddress or ''
def handle_create(self):
"""Allocate a floating IP for the current tenant."""
ips = None
if self.properties[self.DOMAIN]:
ext_net = internet_gateway.InternetGateway.get_external_network_id(
self.neutron())
props = {'floating_network_id': ext_net}
ips = self.neutron().create_floatingip({
'floatingip': props})['floatingip']
self.ipaddress = ips['floating_ip_address']
self.resource_id_set(ips['id'])
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))
ext_net = internet_gateway.InternetGateway.get_external_network_id(
self.neutron())
props = {'floating_network_id': ext_net}
ips = self.neutron().create_floatingip({
'floatingip': props})['floatingip']
self.ipaddress = ips['floating_ip_address']
self.resource_id_set(ips['id'])
LOG.info('ElasticIp create %s', str(ips))
instance_id = self.properties[self.INSTANCE_ID]
if instance_id:
@ -145,12 +129,8 @@ class ElasticIp(resource.Resource):
raise
# deallocate the eip
if self.properties[self.DOMAIN]:
with self.client_plugin('neutron').ignore_not_found:
self.neutron().delete_floatingip(self.resource_id)
else:
with self.client_plugin('nova').ignore_not_found:
self.client().floating_ips.delete(self.resource_id)
with self.client_plugin('neutron').ignore_not_found:
self.neutron().delete_floatingip(self.resource_id)
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
if prop_diff:

View File

@ -11,8 +11,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import abc
import six
from heat.common import exception
@ -21,156 +19,10 @@ from heat.engine import properties
from heat.engine import resource
@six.add_metaclass(abc.ABCMeta)
class BaseSecurityGroup(object):
class NeutronSecurityGroup(object):
def __init__(self, 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.plugin = sg.client_plugin('neutron')
@ -319,8 +171,11 @@ class NeutronSecurityGroup(BaseSecurityGroup):
rule['direction'] = 'ingress'
updated_rules = list(six.itervalues(updated))
updated_all = updated_rules[0] + updated_rules[1]
return super(NeutronSecurityGroup, self).diff_rules(existing,
updated_all)
ids_to_delete = [id for id, rule in existing.items()
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):
@ -398,50 +253,17 @@ class SecurityGroup(resource.Resource):
}
def handle_create(self):
if self.is_using_neutron():
impl = NeutronSecurityGroup
else:
impl = NovaSecurityGroup
impl(self).create()
NeutronSecurityGroup(self).create()
def handle_delete(self):
if self.is_using_neutron():
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()
NeutronSecurityGroup(self).delete()
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
update = False
if (self.is_using_neutron() and (
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:
if (self.SECURITY_GROUP_INGRESS in prop_diff or
self.SECURITY_GROUP_EGRESS in prop_diff):
props = json_snippet.properties(self.properties_schema,
self.context)
impl(self).update(props)
NeutronSecurityGroup(self).update(props)
class SecurityGroupNotFound(exception.HeatException):

View File

@ -66,7 +66,6 @@ class ManilaShareNetwork(resource.Resource):
properties.Schema.STRING,
_('Nova network id.'),
update_allowed=True,
constraints=[constraints.CustomConstraint('nova.network')]
),
DESCRIPTION: properties.Schema(
properties.Schema.STRING,
@ -156,36 +155,24 @@ class ManilaShareNetwork(resource.Resource):
raise exception.StackValidationFailed(message=msg)
def translation_rules(self, props):
if self.is_using_neutron():
translation_rules = [
translation.TranslationRule(
props,
translation.TranslationRule.RESOLVE,
[self.NEUTRON_NETWORK],
client_plugin=self.client_plugin('neutron'),
finder='find_resourceid_by_name_or_id',
entity='network'
),
translation.TranslationRule(
props,
translation.TranslationRule.RESOLVE,
[self.NEUTRON_SUBNET],
client_plugin=self.client_plugin('neutron'),
finder='find_resourceid_by_name_or_id',
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'
)
]
translation_rules = [
translation.TranslationRule(
props,
translation.TranslationRule.RESOLVE,
[self.NEUTRON_NETWORK],
client_plugin=self.client_plugin('neutron'),
finder='find_resourceid_by_name_or_id',
entity='network'
),
translation.TranslationRule(
props,
translation.TranslationRule.RESOLVE,
[self.NEUTRON_SUBNET],
client_plugin=self.client_plugin('neutron'),
finder='find_resourceid_by_name_or_id',
entity='subnet'
)
]
return translation_rules
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
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'
@ -113,7 +120,14 @@ class NovaFloatingIpAssociation(resource.Resource):
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 = (
SERVER, FLOATING_IP

View File

@ -674,38 +674,27 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
self.BLOCK_DEVICE_MAPPING_IMAGE],
client_plugin=self.client_plugin('glance'),
finder='find_image_by_name_or_id'),
]
if self.is_using_neutron():
rules.extend([
translation.TranslationRule(
props,
translation.TranslationRule.RESOLVE,
translation_path=[self.NETWORKS, self.NETWORK_ID],
client_plugin=self.client_plugin('neutron'),
finder='find_resourceid_by_name_or_id',
entity='network'),
translation.TranslationRule(
props,
translation.TranslationRule.RESOLVE,
translation_path=[self.NETWORKS, self.NETWORK_SUBNET],
client_plugin=self.client_plugin('neutron'),
finder='find_resourceid_by_name_or_id',
entity='subnet'),
translation.TranslationRule(
props,
translation.TranslationRule.RESOLVE,
translation_path=[self.NETWORKS, self.NETWORK_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')])
translation.TranslationRule(
props,
translation.TranslationRule.RESOLVE,
translation_path=[self.NETWORKS, self.NETWORK_ID],
client_plugin=self.client_plugin('neutron'),
finder='find_resourceid_by_name_or_id',
entity='network'),
translation.TranslationRule(
props,
translation.TranslationRule.RESOLVE,
translation_path=[self.NETWORKS, self.NETWORK_SUBNET],
client_plugin=self.client_plugin('neutron'),
finder='find_resourceid_by_name_or_id',
entity='subnet'),
translation.TranslationRule(
props,
translation.TranslationRule.RESOLVE,
translation_path=[self.NETWORKS, self.NETWORK_PORT],
client_plugin=self.client_plugin('neutron'),
finder='find_resourceid_by_name_or_id',
entity='port')]
return rules
def __init__(self, name, json_snippet, stack):
@ -819,9 +808,6 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
if self.properties[self.TAGS]:
self._update_server_tags(self.properties[self.TAGS])
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
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
).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):
server = self.client().servers.get(self.resource_id)
status = self.client_plugin().get_status(server)
@ -891,7 +868,9 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
reality_net_ids = {}
for net_key in reality_nets:
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,
exception.PhysicalResourceNameAmbiguity):
net_id = None
@ -1057,7 +1036,8 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
nets = copy.deepcopy(networks)
for key in list(nets.keys()):
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,
exception.PhysicalResourceNameAmbiguity):
net_id = None
@ -1517,9 +1497,8 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
def check_delete_complete(self, prg):
if not prg:
return True
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'):
raise exception.Error(image.status)
elif image.status == 'ACTIVE':
@ -1611,7 +1590,7 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
return 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':
return True
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):
image_id = snapshot['resource_data'].get('snapshot_image_id')
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):
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
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
if fixed_ip and port is not None:
raise exception.ResourcePropertyConflict(
@ -72,7 +67,7 @@ class ServerNetworkMixin(object):
# if user only specifies network and floating ip, floating ip
# can't be associated as the the neutron port isn't created/managed
# 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:
msg = _('Property "%(fip)s" is not supported if only '
'"%(net)s" is specified, because the corresponding '
@ -82,7 +77,7 @@ class ServerNetworkMixin(object):
raise exception.StackValidationFailed(message=msg)
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)
# check if there are subnet and network both specified that
# subnet belongs to specified network
@ -195,9 +190,6 @@ class ServerNetworkMixin(object):
creating. We need to store information about that ports, so store
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.
# If it's not, then novaclient's interface_list method cannot be used
# to get the list of interfaces.
@ -238,7 +230,7 @@ class ServerNetworkMixin(object):
nic_info = {'net-id': self._get_network_id(net)}
if net.get(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(
net, idx, security_groups)
@ -264,14 +256,8 @@ class ServerNetworkMixin(object):
return nics
def _floating_ip_neutron_associate(self, floating_ip, floating_ip_data):
if self.is_using_neutron():
self.client('neutron').update_floatingip(
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)
self.client('neutron').update_floatingip(
floating_ip, {'floatingip': floating_ip_data})
def _floating_ips_disassociate(self):
networks = self.properties[self.NETWORKS] or []
@ -281,15 +267,9 @@ class ServerNetworkMixin(object):
self._floating_ip_disassociate(floating_ip)
def _floating_ip_disassociate(self, floating_ip):
if self.is_using_neutron():
with self.client_plugin('neutron').ignore_not_found:
self.client('neutron').update_floatingip(
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)
with self.client_plugin('neutron').ignore_not_found:
self.client('neutron').update_floatingip(
floating_ip, {'floatingip': {'port_id': None}})
def _exclude_not_updated_networks(self, old_nets, new_nets):
# make networks similar by adding None vlues for not used keys
@ -449,7 +429,7 @@ class ServerNetworkMixin(object):
if 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(
net, idx, security_groups)
@ -489,10 +469,8 @@ class ServerNetworkMixin(object):
old_nets, new_nets, ifaces, security_groups)
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)
elif not self.is_using_neutron():
self._floating_ip_nova_associate(floating_ip)
@staticmethod
def get_all_ports(server):
@ -539,15 +517,9 @@ class ServerNetworkMixin(object):
port=port['id'], server=prev_server_id)
def prepare_ports_for_replace(self):
if not self.is_using_neutron():
return
self.detach_ports(self)
def restore_ports_after_rollback(self, convergence):
if not self.is_using_neutron():
return
# In case of convergence, during rollback, the previous rsrc is
# already selected and is being acted upon.
backup_stack = self.stack._backup_stack()

View File

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

View File

@ -536,15 +536,6 @@ class SaharaClusterTemplate(resource.Resource):
entity = 'cluster_templates'
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 [
translation.TranslationRule(
props,
@ -552,8 +543,7 @@ class SaharaClusterTemplate(resource.Resource):
[self.MANAGEMENT_NETWORK],
client_plugin=self.client_plugin('neutron'),
finder='find_resourceid_by_name_or_id',
entity='network')
]
entity='network')]
def _cluster_template_name(self, name):
if name:

View File

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

View File

@ -14,9 +14,7 @@
import copy
import mock
import mox
from neutronclient.v2_0 import client as neutronclient
from novaclient import exceptions as nova_exceptions
import six
from heat.common import exception
@ -24,7 +22,6 @@ from heat.common import short_id
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.resources.aws.ec2 import eip
from heat.engine import rsrc_defn
from heat.engine import scheduler
@ -205,177 +202,6 @@ class EIPTest(common.HeatTestCase):
else:
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')
def test_FnGetRefId_resource_name(self, mock_ipaddr):
t = template_format.parse(ipassoc_template_validate)
@ -607,31 +433,6 @@ class AllocTest(common.HeatTestCase):
"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):
self.mock_create_gateway_attachment()
self.mock_show_network()
@ -747,177 +548,6 @@ class AllocTest(common.HeatTestCase):
six.text_type(exc))
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):
self.mock_create_floatingip()
self.mock_list_ports()

View File

@ -13,26 +13,17 @@
import collections
import copy
import mock
from neutronclient.common import exceptions as neutron_exc
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.engine.clients.os import nova
from heat.engine import node_data
from heat.engine import resource
from heat.engine.resources.aws.ec2 import security_group
from heat.engine import rsrc_defn
from heat.engine import scheduler
from heat.engine import stack as parser
from heat.engine import template
from heat.tests import common
from heat.tests.openstack.nova import fakes as fakes_nova
from heat.tests import utils
NovaSG = collections.namedtuple('NovaSG',
@ -46,64 +37,6 @@ NovaSG = collections.namedtuple('NovaSG',
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 = '''
HeatTemplateFormatVersion: '2012-12-12'
Resources:
@ -133,15 +66,6 @@ Resources:
def setUp(self):
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_rule')
@ -176,99 +100,6 @@ Resources:
self.assertEqual(ref_id, rsrc.FnGetRefId())
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):
sg_name = utils.PhysName('test_stack', 'the_sg')
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('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):
# create script
self.stubout_neutron_create_security_group()
@ -898,65 +533,6 @@ Resources:
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):
# create script
self.stubout_neutron_create_security_group()
@ -1107,39 +683,3 @@ Resources:
self.assertEqual((sg.UPDATE, sg.COMPLETE), sg.state)
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')]
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):
server = self.m.CreateMockAnything()
server.status = 'ACTIVE'
@ -556,39 +505,6 @@ class FlavorConstraintTest(common.HeatTestCase):
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):
def setUp(self):

View File

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

View File

@ -47,7 +47,9 @@ class ResourceTypeTest(common.HeatTestCase):
'OS::Designate::Record',
'OS::Heat::HARestarter',
'OS::Magnum::Bay',
'OS::Glance::Image']),
'OS::Glance::Image',
'OS::Nova::FloatingIP',
'OS::Nova::FloatingIPAssociation']),
set(resources))
@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 template_format
from heat.engine.clients.os import nova
from heat.engine.resources.openstack.manila import share_network
from heat.engine import scheduler
from heat.tests import common
@ -68,17 +67,10 @@ class ManilaShareNetworkTest(common.HeatTestCase):
def resolve_neutron(resource_type, name):
return name
def resolve_nova(name):
return name
self.client_plugin.find_resourceid_by_name_or_id.side_effect = (
resolve_neutron
)
self.client_plugin.get_nova_network_id.side_effect = (
resolve_nova
)
self.patchobject(share_network.ManilaShareNetwork, 'client_plugin',
return_value=self.client_plugin)
@ -89,7 +81,6 @@ class ManilaShareNetworkTest(common.HeatTestCase):
return_network
)
self.stub_NetworkConstraint_validate()
self.stub_NovaNetworkConstraint()
self.stub_SubnetConstraint_validate()
def _create_network(self, name, snippet, stack, use_neutron=True):
@ -275,17 +266,6 @@ class ManilaShareNetworkTest(common.HeatTestCase):
self.assertRaisesRegexp(exception.ResourcePropertyDependency, msg,
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):
net = self._create_network('share_network', self.rsrc_defn,
self.stack)

View File

@ -16,8 +16,6 @@ import mox
from neutronclient.common import exceptions as neutron_exc
from neutronclient.neutron import v2_0 as neutronV20
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 template_format
@ -26,7 +24,6 @@ from heat.engine import scheduler
from heat.engine import stack as parser
from heat.engine import template
from heat.tests import common
from heat.tests.openstack.nova import fakes as fakes_nova
from heat.tests import utils
@ -89,13 +86,6 @@ resources:
def setUp(self):
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_rule')

View File

@ -224,9 +224,7 @@ class ServersTest(common.HeatTestCase):
self.limits = self.m.CreateMockAnything()
self.limits.absolute = self._limits_absolute()
self.mock_flavor = mock.Mock(ram=4, disk=4)
self.mock_image = mock.Mock(min_ram=1, min_disk=1, status='active')
self.patchobject(resource.Resource, 'is_using_neutron',
return_value=True)
self.mock_image = mock.Mock(min_ram=1, min_disk=1, status='ACTIVE')
def flavor_side_effect(*args):
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(nova.NovaClientPlugin, '_create',
return_value=self.fc)
self.patchobject(glance.GlanceClientPlugin, 'get_image',
return_value=self.mock_image)
if stub_create:
self.patchobject(self.fc.servers, 'create',
return_value=return_server)
@ -1413,46 +1413,6 @@ class ServersTest(common.HeatTestCase):
"time: networks/fixed_ip, networks/port.",
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):
stack_name = 'srv_net'
(tmpl, stack) = self._setup_test_stack(stack_name)
@ -1896,10 +1856,11 @@ class ServersTest(common.HeatTestCase):
self.patchobject(return_server, 'interface_list',
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',
'private_id'])
reality = server.get_live_state(server.properties)
reality = server.get_live_state(server.properties.data)
expected = {'flavor': '1',
'image': '2',
@ -2483,7 +2444,6 @@ class ServersTest(common.HeatTestCase):
return_server = self.fc.servers.list()[1]
server = self._create_test_server(return_server,
'test_server_create')
self.patchobject(server, 'is_using_neutron', return_value=True)
self.patchobject(neutronclient.Client, 'create_port',
return_value={'port': {'id': '4815162342'}})
@ -2509,12 +2469,6 @@ class ServersTest(common.HeatTestCase):
[{'network':
'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):
stack_name = 'net_err'
(tmpl, stack) = self._setup_test_stack(stack_name,
@ -2540,11 +2494,13 @@ class ServersTest(common.HeatTestCase):
return_server.id = '9102'
server = self._create_test_server(return_server,
'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(return_server, 'interface_list', return_value=[])
mock_detach = self.patchobject(return_server, 'interface_detach')
mock_attach = self.patchobject(return_server, 'interface_attach')
self.assertEqual({'empty_net': []}, server.FnGetAtt('addresses'))
self.assertEqual({'empty_net': []}, server.FnGetAtt('networks'))
self.assertEqual(0, mock_detach.call_count)
@ -3164,7 +3120,8 @@ class ServersTest(common.HeatTestCase):
server.resource_id = '1234'
server.networks = {"fake_net": ["10.0.0.3"]}
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')
expect_networks = {"fake_uuid": ["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]
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_id = server._get_network_id(net)
self.assertIsNone(net_id)
@ -3226,25 +3181,6 @@ class ServersTest(common.HeatTestCase):
net_id = server._get_network_id(net)
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):
return_server = self.fc.servers.list()[3]
server = self._create_test_server(return_server, 'networks_update')
@ -3904,7 +3840,9 @@ class ServersTest(common.HeatTestCase):
'test_server_snapshot')
image_in_error = mock.Mock()
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,
scheduler.TaskRunner(server.snapshot))
@ -3979,6 +3917,8 @@ class ServersTest(common.HeatTestCase):
stack.store()
self.patchobject(nova.NovaClientPlugin, '_create',
return_value=self.fc)
self.patchobject(glance.GlanceClientPlugin, 'get_image',
return_value=self.mock_image)
self.patchobject(stack['server'], 'store_external_ports')
return_server = self.fc.servers.list()[1]
return_server.id = '1234'
@ -4031,6 +3971,9 @@ class ServersTest(common.HeatTestCase):
create_image = self.patchobject(self.fc.servers, 'create_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.side_effect = nova_exceptions.NotFound(404)
@ -4058,7 +4001,8 @@ class ServersTest(common.HeatTestCase):
mock_plugin = self.patchobject(nova.NovaClientPlugin, '_create')
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.id = '1234'
mock_create = self.patchobject(self.fc.servers, 'create')
@ -4077,15 +4021,16 @@ class ServersTest(common.HeatTestCase):
self.assertEqual((stack.CREATE, stack.COMPLETE), stack.state)
failed_image = {
failed_image = mock.Mock(**{
'id': 456,
'name': 'CentOS 5.2',
'updated': '2010-10-10T12:00:00Z',
'created': '2010-08-10T12:00:00Z',
'status': 'ERROR'}
self.fc.client.get_images_456 = lambda **kw: (
200, {'image': failed_image})
'status': 'ERROR'})
self.patchobject(glance.GlanceClientPlugin, 'get_image',
return_value=failed_image)
return_server = self.fc.servers.list()[1]
scheduler.TaskRunner(stack.delete)()
self.assertEqual((stack.DELETE, stack.FAILED), stack.state)
@ -4450,74 +4395,6 @@ class ServerInternalPortTest(ServersTest):
mock.call('internal_ports', '[]'),
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):
tmpl = """
heat_template_version: 2015-10-15
@ -4621,37 +4498,6 @@ class ServerInternalPortTest(ServersTest):
self.assertIsNone(server._floating_ip_disassociate('flip123'))
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):
t, stack, server = self._return_template_stack_and_rsrc_defn(
'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'
).return_value = 'someflavorid'
self.patchobject(neutron.NeutronClientPlugin, '_create')
self.patchobject(neutron.NeutronClientPlugin,
'find_resourceid_by_name_or_id',
return_value='some_pool_id')
@ -171,8 +172,6 @@ class SaharaNodeGroupTemplateTest(common.HeatTestCase):
def test_validate_floatingippool_on_neutron_fails(self):
ngt = self._init_ngt(self.t)
self.patchobject(ngt, 'is_using_neutron').return_value = True
self.patchobject(
neutron.NeutronClientPlugin,
'find_resourceid_by_name_or_id'
@ -188,25 +187,12 @@ class SaharaNodeGroupTemplateTest(common.HeatTestCase):
self.assertEqual('Not found',
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):
self.t['resources']['node-group']['properties'].pop('floating_ip_pool')
self.t['resources']['node-group']['properties'].pop('volume_type')
ngt = self._init_ngt(self.t)
self.patchobject(nova.FlavorConstraint, 'validate'
).return_value = False
self.patchobject(ngt, 'is_using_neutron').return_value = False
ex = self.assertRaises(exception.StackValidationFailed, ngt.validate)
self.assertEqual(u"Property error: "
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 template_format
from heat.engine.clients.os import neutron
from heat.engine.clients.os import nova
from heat.engine.clients.os import trove
from heat.engine import resource
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,
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):
t = template_format.parse(db_template_with_replication)
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.host = heat.engine.clients.os.nova:HostConstraint
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
sahara.cluster = heat.engine.clients.os.sahara:ClusterConstraint
sahara.cluster_template = heat.engine.clients.os.sahara:ClusterTemplateConstraint