Merge "cloud: Trivial fixes"

This commit is contained in:
Zuul 2024-04-26 13:53:55 +00:00 committed by Gerrit Code Review
commit 5041ea8687
7 changed files with 128 additions and 138 deletions

View File

@ -147,10 +147,8 @@ class BlockStorageCloudMixin:
image_obj = self.get_image(image) image_obj = self.get_image(image)
if not image_obj: if not image_obj:
raise exceptions.SDKException( raise exceptions.SDKException(
"Image {image} was requested as the basis for a new" f"Image {image} was requested as the basis for a new "
" volume, but was not found on the cloud".format( f"volume but was not found on the cloud"
image=image
)
) )
kwargs['imageRef'] = image_obj['id'] kwargs['imageRef'] = image_obj['id']
kwargs = self._get_volume_kwargs(kwargs) kwargs = self._get_volume_kwargs(kwargs)

View File

@ -389,13 +389,14 @@ class ComputeCloudMixin:
valid project valid project
""" """
params = {} params = {}
project_id = None
if name_or_id: if name_or_id:
proj = self.get_project(name_or_id) project = self.get_project(name_or_id)
if not proj: if not project:
raise exceptions.SDKException("project does not exist") raise exceptions.SDKException(
project_id = proj.id f"Project {name_or_id} was requested but was not found "
params['tenant_id'] = project_id f"on the cloud"
)
params['tenant_id'] = project.id
return self.compute.get_limits(**params).absolute return self.compute.get_limits(**params).absolute
def get_keypair(self, name_or_id, filters=None): def get_keypair(self, name_or_id, filters=None):
@ -1048,12 +1049,8 @@ class ComputeCloudMixin:
volume = self.get_volume(boot_volume) volume = self.get_volume(boot_volume)
if not volume: if not volume:
raise exceptions.SDKException( raise exceptions.SDKException(
'Volume {boot_volume} is not a valid volume' f"Volume {volume} was requested but was not found "
' in {cloud}:{region}'.format( f"on the cloud"
boot_volume=boot_volume,
cloud=self.name,
region=self._compute_region,
)
) )
block_mapping = { block_mapping = {
'boot_index': '0', 'boot_index': '0',
@ -1069,15 +1066,11 @@ class ComputeCloudMixin:
image_obj = image image_obj = image
else: else:
image_obj = self.get_image(image) image_obj = self.get_image(image)
if not image_obj: if not image_obj:
raise exceptions.SDKException( raise exceptions.SDKException(
'Image {image} is not a valid image in' f"Image {image} was requested but was not found "
' {cloud}:{region}'.format( f"on the cloud"
image=image,
cloud=self.name,
region=self._compute_region,
) )
)
block_mapping = { block_mapping = {
'boot_index': '0', 'boot_index': '0',
@ -1093,23 +1086,19 @@ class ComputeCloudMixin:
# If we're attaching volumes on boot but booting from an image, # If we're attaching volumes on boot but booting from an image,
# we need to specify that in the BDM. # we need to specify that in the BDM.
block_mapping = { block_mapping = {
u'boot_index': 0, 'boot_index': 0,
u'delete_on_termination': True, 'delete_on_termination': True,
u'destination_type': u'local', 'destination_type': 'local',
u'source_type': u'image', 'source_type': 'image',
u'uuid': kwargs['imageRef'], 'uuid': kwargs['imageRef'],
} }
kwargs['block_device_mapping_v2'].append(block_mapping) kwargs['block_device_mapping_v2'].append(block_mapping)
for volume in volumes: for volume in volumes:
volume_obj = self.get_volume(volume) volume_obj = self.get_volume(volume)
if not volume_obj: if not volume_obj:
raise exceptions.SDKException( raise exceptions.SDKException(
'Volume {volume} is not a valid volume' f"Volume {volume} was requested but was not found "
' in {cloud}:{region}'.format( f"on the cloud"
volume=volume,
cloud=self.name,
region=self._compute_region,
)
) )
block_mapping = { block_mapping = {
'boot_index': '-1', 'boot_index': '-1',
@ -1841,7 +1830,8 @@ class ComputeCloudMixin:
proj = self.get_project(name_or_id) proj = self.get_project(name_or_id)
if not proj: if not proj:
raise exceptions.SDKException( raise exceptions.SDKException(
"project does not exist: {name}".format(name=proj.id) f"Project {name_or_id} was requested but was not found "
f"on the cloud"
) )
return self.compute.get_usage(proj, start, end) return self.compute.get_usage(proj, start, end)

View File

@ -144,8 +144,8 @@ class FloatingIPCloudMixin:
else: else:
if filters: if filters:
raise ValueError( raise ValueError(
"Nova-network don't support server-side floating ips " "nova-network doesn't support server-side floating IPs "
"filtering. Use the search_floating_ips method instead" "filtering. Use the 'search_floating_ips' method instead"
) )
floating_ips = self._nova_list_floating_ips() floating_ips = self._nova_list_floating_ips()
@ -159,7 +159,7 @@ class FloatingIPCloudMixin:
neutron. `get_external_ipv4_floating_networks` is what you should neutron. `get_external_ipv4_floating_networks` is what you should
almost certainly be using. almost certainly be using.
:returns: A list of floating IP pools :returns: A list of floating IP pool objects
""" """
if not self._has_nova_extension('os-floating-ip-pools'): if not self._has_nova_extension('os-floating-ip-pools'):
raise exc.OpenStackCloudUnavailableExtension( raise exc.OpenStackCloudUnavailableExtension(
@ -407,11 +407,11 @@ class FloatingIPCloudMixin:
if port: if port:
raise exceptions.SDKException( raise exceptions.SDKException(
"This cloud uses nova-network which does not support" "This cloud uses nova-network which does not support "
" arbitrary floating-ip/port mappings. Please nudge" "arbitrary floating-ip/port mappings. Please nudge "
" your cloud provider to upgrade the networking stack" "your cloud provider to upgrade the networking stack "
" to neutron, or alternately provide the server," "to neutron, or alternately provide the server, "
" fixed_address and nat_destination arguments as appropriate" "fixed_address and nat_destination arguments as appropriate"
) )
# Else, we are using Nova network # Else, we are using Nova network
f_ips = self._normalize_floating_ips( f_ips = self._normalize_floating_ips(
@ -482,8 +482,8 @@ class FloatingIPCloudMixin:
break break
except exceptions.ResourceTimeout: except exceptions.ResourceTimeout:
self.log.error( self.log.error(
"Timed out on floating ip %(fip)s becoming active." "Timed out on floating ip %(fip)s becoming active. "
" Deleting", "Deleting",
{'fip': fip_id}, {'fip': fip_id},
) )
try: try:
@ -499,8 +499,8 @@ class FloatingIPCloudMixin:
if fip['port_id'] != port: if fip['port_id'] != port:
if server: if server:
raise exceptions.SDKException( raise exceptions.SDKException(
"Attempted to create FIP on port {port} for server" "Attempted to create FIP on port {port} for server "
" {server} but FIP has port {port_id}".format( "{server} but FIP has port {port_id}".format(
port=port, port=port,
port_id=fip['port_id'], port_id=fip['port_id'],
server=server['id'], server=server['id'],
@ -508,8 +508,8 @@ class FloatingIPCloudMixin:
) )
else: else:
raise exceptions.SDKException( raise exceptions.SDKException(
"Attempted to create FIP on port {port}" "Attempted to create FIP on port {port} "
" but something went wrong".format(port=port) "but something went wrong".format(port=port)
) )
return fip return fip
@ -542,9 +542,9 @@ class FloatingIPCloudMixin:
:param floating_ip_id: a floating IP address ID. :param floating_ip_id: a floating IP address ID.
:param retry: number of times to retry. Optional, defaults to 1, :param retry: number of times to retry. Optional, defaults to 1,
which is in addition to the initial delete call. which is in addition to the initial delete call.
A value of 0 will also cause no checking of results to A value of 0 will also cause no checking of results to
occur. occur.
:returns: True if the IP address has been deleted, False if the IP :returns: True if the IP address has been deleted, False if the IP
address was not found. address was not found.
@ -566,10 +566,10 @@ class FloatingIPCloudMixin:
return True return True
raise exceptions.SDKException( raise exceptions.SDKException(
"Attempted to delete Floating IP {ip} with ID {id} a total of" "Attempted to delete Floating IP {ip} with ID {id} a total of "
" {retry} times. Although the cloud did not indicate any errors" "{retry} times. Although the cloud did not indicate any errors "
" the floating ip is still in existence. Aborting further" "the floating IP is still in existence. Aborting further "
" operations.".format( "operations.".format(
id=floating_ip_id, id=floating_ip_id,
ip=f_ip['floating_ip_address'], ip=f_ip['floating_ip_address'],
retry=retry + 1, retry=retry + 1,
@ -623,9 +623,8 @@ class FloatingIPCloudMixin:
IPs by passing in a server to the create_floating_ip call. IPs by passing in a server to the create_floating_ip call.
:param retry: number of times to retry. Optional, defaults to 1, :param retry: number of times to retry. Optional, defaults to 1,
which is in addition to the initial delete call. which is in addition to the initial delete call.
A value of 0 will also cause no checking of results to A value of 0 will also cause no checking of results to occur.
occur.
:returns: Number of Floating IPs deleted, False if none :returns: Number of Floating IPs deleted, False if none
:raises: :class:`~openstack.exceptions.SDKException` on operation :raises: :class:`~openstack.exceptions.SDKException` on operation
@ -657,15 +656,15 @@ class FloatingIPCloudMixin:
:param server: Server dict :param server: Server dict
:param floating_ip: Floating IP dict to attach :param floating_ip: Floating IP dict to attach
:param fixed_address: (optional) fixed address to which attach the :param fixed_address: (optional) fixed address to which attach the
floating IP to. floating IP to.
:param wait: (optional) Wait for the address to appear as assigned :param wait: (optional) Wait for the address to appear as assigned
to the server. Defaults to False. to the server. Defaults to False.
:param timeout: (optional) Seconds to wait, defaults to 60. :param timeout: (optional) Seconds to wait, defaults to 60.
See the ``wait`` parameter. See the ``wait`` parameter.
:param skip_attach: (optional) Skip the actual attach and just do :param skip_attach: (optional) Skip the actual attach and just do
the wait. Defaults to False. the wait. Defaults to False.
:param nat_destination: The fixed network the server's port for the :param nat_destination: The fixed network the server's port for the
FIP to attach to will come from. FIP to attach to will come from.
:returns: The server ``openstack.compute.v2.server.Server`` :returns: The server ``openstack.compute.v2.server.Server``
:raises: :class:`~openstack.exceptions.SDKException` on operation :raises: :class:`~openstack.exceptions.SDKException` on operation
@ -859,11 +858,11 @@ class FloatingIPCloudMixin:
:param fixed_address: a fixed address :param fixed_address: a fixed address
:param reuse: Try to reuse existing ips. Defaults to True. :param reuse: Try to reuse existing ips. Defaults to True.
:param wait: (optional) Wait for the address to appear as assigned :param wait: (optional) Wait for the address to appear as assigned
to the server. Defaults to False. to the server. Defaults to False.
:param timeout: (optional) Seconds to wait, defaults to 60. :param timeout: (optional) Seconds to wait, defaults to 60.
See the ``wait`` parameter. See the ``wait`` parameter.
:param nat_destination: (optional) the name of the network of the :param nat_destination: (optional) the name of the network of the
port to associate with the floating ip. port to associate with the floating ip.
:returns: the updated server ``openstack.compute.v2.server.Server`` :returns: the updated server ``openstack.compute.v2.server.Server``
""" """
@ -910,14 +909,13 @@ class FloatingIPCloudMixin:
:param server: a server object :param server: a server object
:param ips: list of floating IP addresses or a single address :param ips: list of floating IP addresses or a single address
:param wait: (optional) Wait for the address to appear as assigned :param wait: (optional) Wait for the address to appear as assigned
to the server. Defaults to False. to the server. Defaults to False.
:param timeout: (optional) Seconds to wait, defaults to 60. :param timeout: (optional) Seconds to wait, defaults to 60.
See the ``wait`` parameter. See the ``wait`` parameter.
:param fixed_address: (optional) Fixed address of the server to :param fixed_address: (optional) Fixed address of the server to
attach the IP to attach the IP to
:param nat_destination: (optional) Name or ID of the network that :param nat_destination: (optional) Name or ID of the network that
the fixed IP to attach the the fixed IP to attach the floating IP should be on
floating IP should be on
:returns: The updated server ``openstack.compute.v2.server.Server`` :returns: The updated server ``openstack.compute.v2.server.Server``
:raises: :class:`~openstack.exceptions.SDKException` on operation :raises: :class:`~openstack.exceptions.SDKException` on operation
@ -953,15 +951,14 @@ class FloatingIPCloudMixin:
:param server: a server dictionary. :param server: a server dictionary.
:param reuse: Whether or not to attempt to reuse IPs, defaults :param reuse: Whether or not to attempt to reuse IPs, defaults
to True. to True.
:param wait: (optional) Wait for the address to appear as assigned :param wait: (optional) Wait for the address to appear as assigned
to the server. Defaults to False. to the server. Defaults to False.
:param timeout: (optional) Seconds to wait, defaults to 60. :param timeout: (optional) Seconds to wait, defaults to 60.
See the ``wait`` parameter. See the ``wait`` parameter.
:param reuse: Try to reuse existing ips. Defaults to True. :param reuse: Try to reuse existing ips. Defaults to True.
:returns: Floating IP address attached to server. :returns: Floating IP address attached to server.
""" """
server = self._add_auto_ip( server = self._add_auto_ip(
server, wait=wait, timeout=timeout, reuse=reuse server, wait=wait, timeout=timeout, reuse=reuse
@ -1004,10 +1001,10 @@ class FloatingIPCloudMixin:
# It failed. Delete so as not to leak an unmanaged # It failed. Delete so as not to leak an unmanaged
# resource # resource
self.log.error( self.log.error(
"Timeout waiting for floating IP to become" "Timeout waiting for floating IP to become "
" active. Floating IP %(ip)s:%(id)s was created for" "active. Floating IP %(ip)s:%(id)s was created for "
" server %(server)s but is being deleted due to" "server %(server)s but is being deleted due to "
" activation failure.", "activation failure.",
{ {
'ip': f_ip['floating_ip_address'], 'ip': f_ip['floating_ip_address'],
'id': f_ip['id'], 'id': f_ip['id'],
@ -1265,7 +1262,7 @@ class FloatingIPCloudMixin:
Neutron. Neutron.
This function extract attributes that are common to Nova and Neutron This function extract attributes that are common to Nova and Neutron
floating IP resource. floating IP resource.
If the whole structure is needed inside shade, shade provides private If the whole structure is needed inside openstacksdk there are private
methods that returns "original" objects (e.g. methods that returns "original" objects (e.g.
_neutron_allocate_floating_ip) _neutron_allocate_floating_ip)

View File

@ -652,8 +652,10 @@ class NetworkCloudMixin:
proj = self.get_project(name_or_id) proj = self.get_project(name_or_id)
if not proj: if not proj:
raise exceptions.SDKException("project does not exist") raise exceptions.SDKException(
f"Project {name_or_id} was requested by was not found "
f"on the cloud"
)
self.network.update_quota(proj.id, **kwargs) self.network.update_quota(proj.id, **kwargs)
def get_network_quotas(self, name_or_id, details=False): def get_network_quotas(self, name_or_id, details=False):
@ -688,7 +690,10 @@ class NetworkCloudMixin:
""" """
proj = self.get_project(name_or_id) proj = self.get_project(name_or_id)
if not proj: if not proj:
raise exceptions.SDKException("project does not exist") raise exceptions.SDKException(
f"Project {name_or_id} was requested by was not found "
f"on the cloud"
)
self.network.delete_quota(proj.id) self.network.delete_quota(proj.id)
@_utils.valid_kwargs( @_utils.valid_kwargs(

View File

@ -146,12 +146,12 @@ class NetworkCommonCloudMixin:
if self._nat_source in (network['name'], network['id']): if self._nat_source in (network['name'], network['id']):
if nat_source: if nat_source:
raise exceptions.SDKException( raise exceptions.SDKException(
'Multiple networks were found matching' 'Multiple networks were found matching '
' {nat_net} which is the network configured' '{nat_net} which is the network configured '
' to be the NAT source. Please check your' 'to be the NAT source. Please check your '
' cloud resources. It is probably a good idea' 'cloud resources. It is probably a good idea '
' to configure this network by ID rather than' 'to configure this network by ID rather than '
' by name.'.format(nat_net=self._nat_source) 'by name.'.format(nat_net=self._nat_source)
) )
external_ipv4_floating_networks.append(network) external_ipv4_floating_networks.append(network)
nat_source = network nat_source = network
@ -164,12 +164,12 @@ class NetworkCommonCloudMixin:
if self._nat_destination in (network['name'], network['id']): if self._nat_destination in (network['name'], network['id']):
if nat_destination: if nat_destination:
raise exceptions.SDKException( raise exceptions.SDKException(
'Multiple networks were found matching' 'Multiple networks were found matching '
' {nat_net} which is the network configured' '{nat_net} which is the network configured '
' to be the NAT destination. Please check your' 'to be the NAT destination. Please check your '
' cloud resources. It is probably a good idea' 'cloud resources. It is probably a good idea '
' to configure this network by ID rather than' 'to configure this network by ID rather than '
' by name.'.format(nat_net=self._nat_destination) 'by name.'.format(nat_net=self._nat_destination)
) )
nat_destination = network nat_destination = network
elif self._nat_destination is None: elif self._nat_destination is None:
@ -199,13 +199,13 @@ class NetworkCommonCloudMixin:
if self._default_network in (network['name'], network['id']): if self._default_network in (network['name'], network['id']):
if default_network: if default_network:
raise exceptions.SDKException( raise exceptions.SDKException(
'Multiple networks were found matching' 'Multiple networks were found matching '
' {default_net} which is the network' '{default_net} which is the network '
' configured to be the default interface' 'configured to be the default interface '
' network. Please check your cloud resources.' 'network. Please check your cloud resources. '
' It is probably a good idea' 'It is probably a good idea '
' to configure this network by ID rather than' 'to configure this network by ID rather than '
' by name.'.format(default_net=self._default_network) 'by name.'.format(default_net=self._default_network)
) )
default_network = network default_network = network
@ -213,8 +213,8 @@ class NetworkCommonCloudMixin:
for net_name in self._external_ipv4_names: for net_name in self._external_ipv4_names:
if net_name not in [net['name'] for net in external_ipv4_networks]: if net_name not in [net['name'] for net in external_ipv4_networks]:
raise exceptions.SDKException( raise exceptions.SDKException(
"Networks: {network} was provided for external IPv4" "Networks: {network} was provided for external IPv4 "
" access and those networks could not be found".format( "access and those networks could not be found".format(
network=net_name network=net_name
) )
) )
@ -222,8 +222,8 @@ class NetworkCommonCloudMixin:
for net_name in self._internal_ipv4_names: for net_name in self._internal_ipv4_names:
if net_name not in [net['name'] for net in internal_ipv4_networks]: if net_name not in [net['name'] for net in internal_ipv4_networks]:
raise exceptions.SDKException( raise exceptions.SDKException(
"Networks: {network} was provided for internal IPv4" "Networks: {network} was provided for internal IPv4 "
" access and those networks could not be found".format( "access and those networks could not be found".format(
network=net_name network=net_name
) )
) )
@ -231,8 +231,8 @@ class NetworkCommonCloudMixin:
for net_name in self._external_ipv6_names: for net_name in self._external_ipv6_names:
if net_name not in [net['name'] for net in external_ipv6_networks]: if net_name not in [net['name'] for net in external_ipv6_networks]:
raise exceptions.SDKException( raise exceptions.SDKException(
"Networks: {network} was provided for external IPv6" "Networks: {network} was provided for external IPv6 "
" access and those networks could not be found".format( "access and those networks could not be found".format(
network=net_name network=net_name
) )
) )
@ -240,31 +240,31 @@ class NetworkCommonCloudMixin:
for net_name in self._internal_ipv6_names: for net_name in self._internal_ipv6_names:
if net_name not in [net['name'] for net in internal_ipv6_networks]: if net_name not in [net['name'] for net in internal_ipv6_networks]:
raise exceptions.SDKException( raise exceptions.SDKException(
"Networks: {network} was provided for internal IPv6" "Networks: {network} was provided for internal IPv6 "
" access and those networks could not be found".format( "access and those networks could not be found".format(
network=net_name network=net_name
) )
) )
if self._nat_destination and not nat_destination: if self._nat_destination and not nat_destination:
raise exceptions.SDKException( raise exceptions.SDKException(
'Network {network} was configured to be the' 'Network {network} was configured to be the '
' destination for inbound NAT but it could not be' 'destination for inbound NAT but it could not be '
' found'.format(network=self._nat_destination) 'found'.format(network=self._nat_destination)
) )
if self._nat_source and not nat_source: if self._nat_source and not nat_source:
raise exceptions.SDKException( raise exceptions.SDKException(
'Network {network} was configured to be the' 'Network {network} was configured to be the '
' source for inbound NAT but it could not be' 'source for inbound NAT but it could not be '
' found'.format(network=self._nat_source) 'found'.format(network=self._nat_source)
) )
if self._default_network and not default_network: if self._default_network and not default_network:
raise exceptions.SDKException( raise exceptions.SDKException(
'Network {network} was configured to be the' 'Network {network} was configured to be the '
' default network interface but it could not be' 'default network interface but it could not be '
' found'.format(network=self._default_network) 'found'.format(network=self._default_network)
) )
self._external_ipv4_networks = external_ipv4_networks self._external_ipv4_networks = external_ipv4_networks

View File

@ -54,15 +54,14 @@ class SecurityGroupCloudMixin:
# pass filters dict to the list to filter as much as possible on # pass filters dict to the list to filter as much as possible on
# the server side # the server side
return list(self.network.security_groups(**filters)) return list(self.network.security_groups(**filters))
# Handle nova security groups # Handle nova security groups
else: else:
data = proxy._json_response( data = proxy._json_response(
self.compute.get('/os-security-groups', params=filters) self.compute.get('/os-security-groups', params=filters)
) )
return self._normalize_secgroups( return self._normalize_secgroups(
self._get_and_munchify('security_groups', data) self._get_and_munchify('security_groups', data)
) )
def get_security_group(self, name_or_id, filters=None): def get_security_group(self, name_or_id, filters=None):
"""Get a security group by name or ID. """Get a security group by name or ID.
@ -109,9 +108,9 @@ class SecurityGroupCloudMixin:
self.compute.get(f'/os-security-groups/{id}'), self.compute.get(f'/os-security-groups/{id}'),
error_message=error_message, error_message=error_message,
) )
return self._normalize_secgroup( return self._normalize_secgroup(
self._get_and_munchify('security_group', data) self._get_and_munchify('security_group', data)
) )
def create_security_group( def create_security_group(
self, name, description, project_id=None, stateful=None self, name, description, project_id=None, stateful=None
@ -155,9 +154,9 @@ class SecurityGroupCloudMixin:
json={'security_group': security_group_json}, json={'security_group': security_group_json},
) )
) )
return self._normalize_secgroup( return self._normalize_secgroup(
self._get_and_munchify('security_group', data) self._get_and_munchify('security_group', data)
) )
def delete_security_group(self, name_or_id): def delete_security_group(self, name_or_id):
"""Delete a security group """Delete a security group
@ -237,9 +236,9 @@ class SecurityGroupCloudMixin:
json={'security_group': kwargs}, json={'security_group': kwargs},
) )
) )
return self._normalize_secgroup( return self._normalize_secgroup(
self._get_and_munchify('security_group', data) self._get_and_munchify('security_group', data)
) )
def create_security_group_rule( def create_security_group_rule(
self, self,
@ -389,9 +388,9 @@ class SecurityGroupCloudMixin:
'/os-security-group-rules', json=security_group_rule_dict '/os-security-group-rules', json=security_group_rule_dict
) )
) )
return self._normalize_secgroup_rule( return self._normalize_secgroup_rule(
self._get_and_munchify('security_group_rule', data) self._get_and_munchify('security_group_rule', data)
) )
def delete_security_group_rule(self, rule_id): def delete_security_group_rule(self, rule_id):
"""Delete a security group rule """Delete a security group rule

View File

@ -110,7 +110,8 @@ class TestFloatingIP(base.TestCase):
def test_list_floating_ips_with_filters(self): def test_list_floating_ips_with_filters(self):
self.assertRaisesRegex( self.assertRaisesRegex(
ValueError, ValueError,
"Nova-network don't support server-side", "nova-network doesn't support server-side floating IPs filtering. "
"Use the 'search_floating_ips' method instead",
self.cloud.list_floating_ips, self.cloud.list_floating_ips,
filters={'Foo': 42}, filters={'Foo': 42},
) )