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:
parent
320c820ed8
commit
e8e0a2483a
@ -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,12 +29,6 @@ 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)
|
||||
|
@ -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'
|
||||
|
@ -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,26 +82,17 @@ 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']
|
||||
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
|
||||
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}
|
||||
@ -104,19 +101,6 @@ class ElasticIp(resource.Resource):
|
||||
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))
|
||||
|
||||
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)
|
||||
|
||||
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
|
||||
if prop_diff:
|
||||
|
@ -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):
|
||||
|
@ -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,7 +155,6 @@ class ManilaShareNetwork(resource.Resource):
|
||||
raise exception.StackValidationFailed(message=msg)
|
||||
|
||||
def translation_rules(self, props):
|
||||
if self.is_using_neutron():
|
||||
translation_rules = [
|
||||
translation.TranslationRule(
|
||||
props,
|
||||
@ -175,17 +173,6 @@ class ManilaShareNetwork(resource.Resource):
|
||||
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
|
||||
|
||||
def handle_create(self):
|
||||
|
@ -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
|
||||
|
@ -674,9 +674,6 @@ 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,
|
||||
@ -697,15 +694,7 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
|
||||
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')])
|
||||
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']
|
||||
|
@ -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,15 +256,9 @@ 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)
|
||||
|
||||
def _floating_ips_disassociate(self):
|
||||
networks = self.properties[self.NETWORKS] or []
|
||||
for network in networks:
|
||||
@ -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)
|
||||
|
||||
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()
|
||||
|
@ -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([
|
||||
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')])
|
||||
else:
|
||||
rules.extend([
|
||||
translation.TranslationRule(
|
||||
props,
|
||||
translation.TranslationRule.RESOLVE,
|
||||
[self.MANAGEMENT_NETWORK],
|
||||
client_plugin=self.client_plugin('nova'),
|
||||
finder='get_nova_network_id')])
|
||||
entity='network')]
|
||||
return rules
|
||||
|
||||
def _cluster_name(self):
|
||||
|
@ -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:
|
||||
|
@ -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))
|
||||
nic_dict['net-id'] = net_id
|
||||
port = nic.get(self.PORT)
|
||||
if port:
|
||||
|
@ -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()
|
||||
|
@ -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())
|
||||
|
@ -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):
|
||||
|
@ -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')
|
||||
|
@ -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')
|
||||
|
@ -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)
|
||||
|
@ -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')
|
||||
|
@ -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)
|
||||
|
@ -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: "
|
||||
|
@ -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)
|
||||
|
@ -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.
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user