From e8e0a2483a8cd0edbd0ec77d92d638974c72f290 Mon Sep 17 00:00:00 2001 From: rabi Date: Tue, 16 May 2017 09:29:07 +0530 Subject: [PATCH] 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 --- .../clients/os/neutron/neutron_constraints.py | 13 +- heat/engine/clients/os/nova.py | 33 -- heat/engine/resources/aws/ec2/eip.py | 64 +-- .../resources/aws/ec2/security_group.py | 200 +------- .../openstack/manila/share_network.py | 49 +- .../resources/openstack/nova/floatingip.py | 18 +- .../engine/resources/openstack/nova/server.py | 79 ++- .../openstack/nova/server_network_mixin.py | 48 +- .../resources/openstack/sahara/cluster.py | 26 +- .../resources/openstack/sahara/templates.py | 12 +- .../resources/openstack/trove/instance.py | 10 +- heat/tests/aws/test_eip.py | 370 -------------- heat/tests/aws/test_security_group.py | 460 ------------------ heat/tests/clients/test_nova_client.py | 84 ---- heat/tests/common.py | 4 - heat/tests/engine/test_resource_type.py | 4 +- .../openstack/manila/test_share_network.py | 20 - .../neutron/test_neutron_security_group.py | 10 - heat/tests/openstack/nova/test_server.py | 206 +------- heat/tests/openstack/sahara/test_templates.py | 16 +- heat/tests/openstack/trove/test_instance.py | 23 - ...floatingip-resources-d5c9447a199be402.yaml | 7 + setup.cfg | 2 +- 23 files changed, 159 insertions(+), 1599 deletions(-) create mode 100644 releasenotes/notes/deprecate-nova-floatingip-resources-d5c9447a199be402.yaml diff --git a/heat/engine/clients/os/neutron/neutron_constraints.py b/heat/engine/clients/os/neutron/neutron_constraints.py index adee74e99e..27d6449b6b 100644 --- a/heat/engine/clients/os/neutron/neutron_constraints.py +++ b/heat/engine/clients/os/neutron/neutron_constraints.py @@ -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): diff --git a/heat/engine/clients/os/nova.py b/heat/engine/clients/os/nova.py index 6886e4e119..5f36429474 100644 --- a/heat/engine/clients/os/nova.py +++ b/heat/engine/clients/os/nova.py @@ -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' diff --git a/heat/engine/resources/aws/ec2/eip.py b/heat/engine/resources/aws/ec2/eip.py index 0b37860e25..4c3f83d221 100644 --- a/heat/engine/resources/aws/ec2/eip.py +++ b/heat/engine/resources/aws/ec2/eip.py @@ -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: diff --git a/heat/engine/resources/aws/ec2/security_group.py b/heat/engine/resources/aws/ec2/security_group.py index 0ae6c441bc..38b298e8fa 100644 --- a/heat/engine/resources/aws/ec2/security_group.py +++ b/heat/engine/resources/aws/ec2/security_group.py @@ -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): diff --git a/heat/engine/resources/openstack/manila/share_network.py b/heat/engine/resources/openstack/manila/share_network.py index 11464ad6e4..108fa000e7 100644 --- a/heat/engine/resources/openstack/manila/share_network.py +++ b/heat/engine/resources/openstack/manila/share_network.py @@ -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): diff --git a/heat/engine/resources/openstack/nova/floatingip.py b/heat/engine/resources/openstack/nova/floatingip.py index 446a517b82..30a5c13899 100644 --- a/heat/engine/resources/openstack/nova/floatingip.py +++ b/heat/engine/resources/openstack/nova/floatingip.py @@ -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 diff --git a/heat/engine/resources/openstack/nova/server.py b/heat/engine/resources/openstack/nova/server.py index adeaf0568d..515dc7390c 100644 --- a/heat/engine/resources/openstack/nova/server.py +++ b/heat/engine/resources/openstack/nova/server.py @@ -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'] diff --git a/heat/engine/resources/openstack/nova/server_network_mixin.py b/heat/engine/resources/openstack/nova/server_network_mixin.py index a6eaeb62f8..d699eb15fd 100644 --- a/heat/engine/resources/openstack/nova/server_network_mixin.py +++ b/heat/engine/resources/openstack/nova/server_network_mixin.py @@ -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() diff --git a/heat/engine/resources/openstack/sahara/cluster.py b/heat/engine/resources/openstack/sahara/cluster.py index c90ab698b3..c051c57e4b 100644 --- a/heat/engine/resources/openstack/sahara/cluster.py +++ b/heat/engine/resources/openstack/sahara/cluster.py @@ -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): diff --git a/heat/engine/resources/openstack/sahara/templates.py b/heat/engine/resources/openstack/sahara/templates.py index 3be3527404..78a9eb1c21 100644 --- a/heat/engine/resources/openstack/sahara/templates.py +++ b/heat/engine/resources/openstack/sahara/templates.py @@ -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: diff --git a/heat/engine/resources/openstack/trove/instance.py b/heat/engine/resources/openstack/trove/instance.py index 0ef24fb48e..c0d76b8d1d 100644 --- a/heat/engine/resources/openstack/trove/instance.py +++ b/heat/engine/resources/openstack/trove/instance.py @@ -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: diff --git a/heat/tests/aws/test_eip.py b/heat/tests/aws/test_eip.py index a22f8a653f..ff383bf3df 100644 --- a/heat/tests/aws/test_eip.py +++ b/heat/tests/aws/test_eip.py @@ -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() diff --git a/heat/tests/aws/test_security_group.py b/heat/tests/aws/test_security_group.py index a60f6b0495..97dc9ba68a 100644 --- a/heat/tests/aws/test_security_group.py +++ b/heat/tests/aws/test_security_group.py @@ -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()) diff --git a/heat/tests/clients/test_nova_client.py b/heat/tests/clients/test_nova_client.py index ba647a0778..798bfa3097 100644 --- a/heat/tests/clients/test_nova_client.py +++ b/heat/tests/clients/test_nova_client.py @@ -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): diff --git a/heat/tests/common.py b/heat/tests/common.py index e26720f419..54bda0c0f6 100644 --- a/heat/tests/common.py +++ b/heat/tests/common.py @@ -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') diff --git a/heat/tests/engine/test_resource_type.py b/heat/tests/engine/test_resource_type.py index fdc0ede465..f219381b06 100644 --- a/heat/tests/engine/test_resource_type.py +++ b/heat/tests/engine/test_resource_type.py @@ -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') diff --git a/heat/tests/openstack/manila/test_share_network.py b/heat/tests/openstack/manila/test_share_network.py index b5c845efca..36cd1e8f5f 100644 --- a/heat/tests/openstack/manila/test_share_network.py +++ b/heat/tests/openstack/manila/test_share_network.py @@ -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) diff --git a/heat/tests/openstack/neutron/test_neutron_security_group.py b/heat/tests/openstack/neutron/test_neutron_security_group.py index eb2961f078..f25c6d58de 100644 --- a/heat/tests/openstack/neutron/test_neutron_security_group.py +++ b/heat/tests/openstack/neutron/test_neutron_security_group.py @@ -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') diff --git a/heat/tests/openstack/nova/test_server.py b/heat/tests/openstack/nova/test_server.py index 627f5bd249..958438a997 100644 --- a/heat/tests/openstack/nova/test_server.py +++ b/heat/tests/openstack/nova/test_server.py @@ -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) diff --git a/heat/tests/openstack/sahara/test_templates.py b/heat/tests/openstack/sahara/test_templates.py index 34aa388933..952ffa37a7 100644 --- a/heat/tests/openstack/sahara/test_templates.py +++ b/heat/tests/openstack/sahara/test_templates.py @@ -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: " diff --git a/heat/tests/openstack/trove/test_instance.py b/heat/tests/openstack/trove/test_instance.py index 280a645194..68a91931a4 100644 --- a/heat/tests/openstack/trove/test_instance.py +++ b/heat/tests/openstack/trove/test_instance.py @@ -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) diff --git a/releasenotes/notes/deprecate-nova-floatingip-resources-d5c9447a199be402.yaml b/releasenotes/notes/deprecate-nova-floatingip-resources-d5c9447a199be402.yaml new file mode 100644 index 0000000000..af99f17f9e --- /dev/null +++ b/releasenotes/notes/deprecate-nova-floatingip-resources-d5c9447a199be402.yaml @@ -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. diff --git a/setup.cfg b/setup.cfg index 649765b9a3..d32d4b5e77 100644 --- a/setup.cfg +++ b/setup.cfg @@ -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