ironic-tempest-plugin/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_advanced_ops.py

150 lines
6.6 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from tempest.common import utils
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from ironic_tempest_plugin.tests.scenario import \
baremetal_standalone_manager as bsm
CONF = config.CONF
class BaremetalRedfishDHCPLessDeploy(bsm.BaremetalStandaloneScenarioTest):
api_microversion = '1.59' # Ussuri for redfish-virtual-media
driver = 'redfish'
deploy_interface = 'direct'
boot_interface = 'redfish-virtual-media'
image_ref = CONF.baremetal.whole_disk_image_ref
image_checksum = CONF.baremetal.whole_disk_image_checksum
wholedisk_image = True
@classmethod
def skip_checks(cls):
super(BaremetalRedfishDHCPLessDeploy, cls).skip_checks()
if CONF.baremetal_feature_enabled.dhcpless_vmedia:
raise cls.skipException("This test requires a full OS image to "
"be deployed, and thus must be "
"explicitly enabled for testing.")
if (not CONF.baremetal.public_subnet_id
or not CONF.baremetal.public_subnet_ip):
raise cls.skipException(
"This test requires a public sunbet ID, and public subnet "
"IP to use on that subnet to execute. Please see the "
"baremetal configuration options public_subnet_id "
"and public_subnet_ip respectively, and populate with "
"appropriate values to execute this test.")
def create_tenant_network(self, clients, tenant_cidr, ip_version):
# NOTE(TheJulia): self.create_network is an internal method
# which just gets the info, doesn't actually create a network.
network = self.create_network(
networks_client=self.os_admin.networks_client,
project_id=clients.credentials.project_id,
shared=True)
router = self.get_router(
client=clients.routers_client,
project_id=clients.credentials.tenant_id,
external_gateway_info={
'network_id': CONF.network.public_network_id,
'external_fixed_ips': [
{'subnet_id': CONF.baremetal.public_subnet_id,
'ip_address': CONF.baremetal.public_subnet_ip}]
})
result = clients.subnets_client.create_subnet(
name=data_utils.rand_name('subnet'),
network_id=network['id'],
tenant_id=clients.credentials.tenant_id,
ip_version=CONF.validation.ip_version_for_ssh,
cidr=tenant_cidr, enable_dhcp=False)
subnet = result['subnet']
clients.routers_client.add_router_interface(router['id'],
subnet_id=subnet['id'])
self.addCleanup(clients.subnets_client.delete_subnet, subnet['id'])
self.addCleanup(clients.routers_client.remove_router_interface,
router['id'], subnet_id=subnet['id'])
return network, subnet, router
def deploy_vmedia_dhcpless(self, rebuild=False):
"""Helper to facilitate vmedia testing.
* Create Network/router without DHCP
* Set provisioning_network for this node.
* Set cleanup to undo the provisionign network setup.
* Launch instance.
* Requirement: Instance OS image supports network config from
network_data embedded in the OS. i.e. a real image, not
cirros.
* If so enabled, rebuild the node, Verify rebuild completed.
* Via cleanup: Teardown Network/Router
"""
# Get the latest state for the node.
self.node = self.get_node(self.node['uuid'])
prior_prov_net = self.node['driver_info'].get('provisioning_network')
ip_version = CONF.validation.ip_version_for_ssh
tenant_cidr = '10.0.6.0/24'
if ip_version == 6:
tenant_cidr = 'fd00:33::/64'
network, subnet, router = self.create_tenant_network(
self.os_admin, tenant_cidr, ip_version=ip_version)
if prior_prov_net:
self.update_node(self.node['uuid'],
[{'op': 'replace',
'path': '/driver_info/provisioning_network',
'value': network['id']}])
self.addCleanup(self.update_node,
self.node['uuid'],
[{'op': 'replace',
'path': '/driver_info/provisioning_network',
'value': prior_prov_net}])
else:
self.update_node(self.node['uuid'],
[{'op': 'add',
'path': '/driver_info/provisioning_network',
'value': network['id']}])
self.addCleanup(self.update_node,
self.node['uuid'],
[{'op': 'remove',
'path': '/driver_info/provisioning_network'}])
self.set_node_to_active(self.image_ref, self.image_checksum,
fallback_network=network['id'],
config_drive_networking=True,
method_to_get_ip=self.get_server_ip)
# node_ip is set by the prior call to set_node_to_active
self.assertTrue(self.ping_ip_address(self.node_ip))
if rebuild:
self.set_node_provision_state(self.node['uuid'], 'rebuild')
self.wait_provisioning_state(self.node['uuid'], 'active',
timeout=CONF.baremetal.active_timeout,
interval=30)
# Assert we were able to ping after rebuilding.
self.assertTrue(self.ping_ip_address(self.node_ip))
# Force delete so we remove the vifs
self.terminate_node(self.node['uuid'], force_delete=True)
@decorators.idempotent_id('1f420ef3-99bd-46c7-b859-ce9c2892697f')
@utils.services('image', 'network')
def test_ip_access_to_server(self):
self.deploy_vmedia_dhcpless(
rebuild=CONF.baremetal.rebuild_remote_dhcpless)