ec2-api/ec2api/tests/functional/api/test_network_interfaces.py

583 lines
26 KiB
Python

# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# 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.
import time
import botocore.exceptions
from oslo_log import log
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
import testtools
from ec2api.tests.functional import base
from ec2api.tests.functional import config
CONF = config.CONF
LOG = log.getLogger(__name__)
class NetworkInterfaceTest(base.EC2TestCase):
VPC_CIDR = '10.7.0.0/20'
vpc_id = None
SUBNET_CIDR = '10.7.0.0/28'
subnet_id = None
@classmethod
@base.safe_setup
def setUpClass(cls):
super(NetworkInterfaceTest, cls).setUpClass()
if not base.TesterStateHolder().get_vpc_enabled():
raise cls.skipException('VPC is disabled')
data = cls.client.create_vpc(CidrBlock=cls.VPC_CIDR)
cls.vpc_id = data['Vpc']['VpcId']
cls.addResourceCleanUpStatic(cls.client.delete_vpc, VpcId=cls.vpc_id)
cls.get_vpc_waiter().wait_available(cls.vpc_id)
aws_zone = CONF.aws.aws_zone
data = cls.client.create_subnet(VpcId=cls.vpc_id,
CidrBlock=cls.SUBNET_CIDR,
AvailabilityZone=aws_zone)
cls.subnet_id = data['Subnet']['SubnetId']
cls.addResourceCleanUpStatic(cls.client.delete_subnet,
SubnetId=cls.subnet_id)
cls.get_subnet_waiter().wait_available(cls.subnet_id)
def _wait_assignment(self, ni_id, data):
# NOTE(andrey-mp): Amazon don't do it quickly and there is no way
# to wait this request
time.sleep(5)
@decorators.idempotent_id('d03f49b1-a77e-439b-96e2-5e152b968863')
def test_delete_subnet_with_network_interface(self):
data = self.client.create_subnet(VpcId=self.vpc_id,
CidrBlock='10.7.1.0/28')
subnet_id = data['Subnet']['SubnetId']
res_clean_subnet = self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_id)
self.get_subnet_waiter().wait_available(subnet_id)
data = self.client.create_network_interface(SubnetId=subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean_ni = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
time.sleep(2)
self.assertRaises('DependencyViolation',
self.client.delete_subnet,
SubnetId=subnet_id)
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean_ni)
self.get_network_interface_waiter().wait_delete(ni_id)
self.client.delete_subnet(SubnetId=subnet_id)
self.cancelResourceCleanUp(res_clean_subnet)
self.get_subnet_waiter().wait_delete(subnet_id)
@decorators.idempotent_id('e19e450d-5c24-47b1-9814-4a65a78e5a31')
def test_create_network_interface(self):
desc = data_utils.rand_name('ni')
data = self.client.create_network_interface(SubnetId=self.subnet_id,
Description=desc)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
ni = data['NetworkInterface']
self.assertEqual(self.vpc_id, ni['VpcId'])
self.assertEqual(self.subnet_id, ni['SubnetId'])
self.assertEqual(desc, ni['Description'])
self.assertNotEmpty(ni.get('Groups'))
self.assertEqual('default', ni['Groups'][0]['GroupName'])
address = ni.get('PrivateIpAddress')
self.assertIsNotNone(address)
addresses = ni.get('PrivateIpAddresses')
self.assertIsNotNone(addresses)
self.assertEqual(1, len(addresses))
self.assertTrue(addresses[0]['Primary'])
self.assertEqual(address, addresses[0]['PrivateIpAddress'])
self.assertIsNotNone(ni.get('MacAddress'))
self.assertIsNotNone(ni.get('OwnerId'))
self.assertIsNotNone(ni.get('RequesterManaged'))
self.assertIsNotNone(ni.get('SourceDestCheck'))
self.get_network_interface_waiter().wait_available(ni_id)
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
self.assertRaises('InvalidNetworkInterfaceID.NotFound',
self.client.describe_network_interfaces,
NetworkInterfaceIds=[ni_id])
# TODO(andrey-mp): add creation with addresses
@decorators.idempotent_id('61e16648-7736-4647-b618-27d3f4f0c9c6')
def test_create_max_network_interface(self):
# NOTE(andrey-mp): wait some time while all ports will be deleted
# for this subnet(that are deleting after previous test)
time.sleep(5)
data = self.client.describe_subnets(SubnetIds=[self.subnet_id])
count_before = data['Subnets'][0]['AvailableIpAddressCount']
addresses = []
while True:
try:
data = self.client.create_network_interface(
SubnetId=self.subnet_id)
except botocore.exceptions.ClientError as e:
error_code = e.response['Error']['Code']
self.assertEqual('InsufficientFreeAddressesInSubnet',
error_code, e.message)
break
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface,
NetworkInterfaceId=ni_id)
addresses.append((ni_id, res_clean))
data = self.client.describe_subnets(SubnetIds=[self.subnet_id])
count_after = data['Subnets'][0]['AvailableIpAddressCount']
# NOTE(andrey-mp): This is strange but Amazon can't create last NI
# and Openstack can
self.assertIn(count_after, [0, 1])
self.assertEqual(len(addresses), count_before - count_after)
for addr in addresses:
self.client.delete_network_interface(NetworkInterfaceId=addr[0])
self.cancelResourceCleanUp(addr[1])
self.get_network_interface_waiter().wait_delete(addr[0])
@decorators.idempotent_id('8c174e5f-e377-4bf2-9315-b868a8199c17')
def test_unassign_primary_addresses(self):
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
primary_address = data['NetworkInterface'].get('PrivateIpAddress')
self.get_network_interface_waiter().wait_available(ni_id)
self.assertRaises('InvalidParameterValue',
self.client.unassign_private_ip_addresses,
NetworkInterfaceId=ni_id,
PrivateIpAddresses=[primary_address])
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
@decorators.idempotent_id('de0d0375-d99a-476c-939a-0e15c4e431a8')
def test_assign_unassign_private_addresses_by_count(self):
data = self.client.describe_subnets(SubnetIds=[self.subnet_id])
count = data['Subnets'][0]['AvailableIpAddressCount']
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
data = self.client.assign_private_ip_addresses(
NetworkInterfaceId=ni_id,
SecondaryPrivateIpAddressCount=2)
self._wait_assignment(ni_id, data)
data = self.client.describe_subnets(SubnetIds=[self.subnet_id])
count_after = data['Subnets'][0]['AvailableIpAddressCount']
self.assertEqual(count - 3, count_after)
data = self.client.describe_network_interfaces(
NetworkInterfaceIds=[ni_id])
addresses = []
for addr in data['NetworkInterfaces'][0]['PrivateIpAddresses']:
if not addr['Primary']:
addresses.append(addr['PrivateIpAddress'])
self.assertEqual(2, len(addresses))
data = self.client.unassign_private_ip_addresses(
NetworkInterfaceId=ni_id,
PrivateIpAddresses=addresses)
self._wait_assignment(ni_id, data)
data = self.client.describe_subnets(SubnetIds=[self.subnet_id])
count_after = data['Subnets'][0]['AvailableIpAddressCount']
self.assertEqual(count - 1, count_after)
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
@decorators.idempotent_id('5d7bda42-d23e-4cbf-9e66-8ca052ac28ff')
def test_assign_unassign_private_addresses_by_addresses(self):
data = self.client.describe_subnets(SubnetIds=[self.subnet_id])
count = data['Subnets'][0]['AvailableIpAddressCount']
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
ni = self.client.describe_network_interfaces(
NetworkInterfaceIds=[ni_id])['NetworkInterfaces']
ni_addr = ni[0]['PrivateIpAddresses'][0]['PrivateIpAddress']
# add two more addresses to interface.
# check that they does not equal to current.
addresses = []
for i in range(10, 13):
addr = '10.7.0.%d' % i
if addr != ni_addr:
addresses.append(addr)
if len(addresses) >= 2:
break
data = self.client.assign_private_ip_addresses(
NetworkInterfaceId=ni_id,
PrivateIpAddresses=addresses)
self._wait_assignment(ni_id, data)
data = self.client.describe_subnets(SubnetIds=[self.subnet_id])
count_after = data['Subnets'][0]['AvailableIpAddressCount']
# NOTE(Alex): Amazon misses 1 IP address by some reason.
self.assertIn(count_after, [count - 3, count - 4])
data = self.client.describe_network_interfaces(
NetworkInterfaceIds=[ni_id])
assigned_addresses = []
for addr in data['NetworkInterfaces'][0]['PrivateIpAddresses']:
if not addr['Primary']:
self.assertIn(addr['PrivateIpAddress'], addresses)
assigned_addresses.append(addr['PrivateIpAddress'])
self.assertEqual(2, len(assigned_addresses))
data = self.client.unassign_private_ip_addresses(
NetworkInterfaceId=ni_id,
PrivateIpAddresses=addresses)
self._wait_assignment(ni_id, data)
data = self.client.describe_subnets(SubnetIds=[self.subnet_id])
count_after = data['Subnets'][0]['AvailableIpAddressCount']
self.assertIn(count_after, [count - 1, count - 2])
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
@decorators.idempotent_id('0c514bb4-5800-4db0-9032-0aa3ab998612')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_attach_network_interface(self):
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
self.addResourceCleanUp(self.client.delete_network_interface,
NetworkInterfaceId=ni_id)
ni = data['NetworkInterface']
address = ni.get('PrivateIpAddress')
self.assertIsNotNone(address)
self.get_network_interface_waiter().wait_available(ni_id)
instance_id = self.run_instance(SubnetId=self.subnet_id)
# NOTE(andrey-mp): Amazon can't attach to device index = 0
kwargs = {
'DeviceIndex': 0,
'InstanceId': instance_id,
'NetworkInterfaceId': ni_id
}
self.assertRaises('InvalidParameterValue',
self.client.attach_network_interface,
**kwargs)
kwargs = {
'DeviceIndex': 2,
'InstanceId': instance_id,
'NetworkInterfaceId': ni_id
}
data = self.client.attach_network_interface(*[], **kwargs)
attachment_id = data['AttachmentId']
instance = self.get_instance(instance_id)
nis = instance.get('NetworkInterfaces', [])
self.assertEqual(2, len(nis))
ids = [nis[0]['Attachment']['AttachmentId'],
nis[1]['Attachment']['AttachmentId']]
self.assertIn(attachment_id, ids)
self.assertRaises('InvalidParameterValue',
self.client.delete_network_interface,
NetworkInterfaceId=ni_id)
self.client.detach_network_interface(AttachmentId=attachment_id)
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('381c9995-bc83-4e7e-b716-25a451660ace')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_network_interfaces_are_not_deleted_on_termination(self):
instance_id = self.run_instance(SubnetId=self.subnet_id)
instance = self.get_instance(instance_id)
nis = instance.get('NetworkInterfaces', [])
self.assertEqual(1, len(nis))
self.assertTrue(nis[0]['Attachment']['DeleteOnTermination'])
ni_id = nis[0]['NetworkInterfaceId']
attachment_id = nis[0]['Attachment']['AttachmentId']
kwargs = {
'NetworkInterfaceId': ni_id,
'Attachment': {
'AttachmentId': attachment_id,
'DeleteOnTermination': False,
}
}
self.client.modify_network_interface_attribute(*[], **kwargs)
clean_ni = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id2 = data['NetworkInterface']['NetworkInterfaceId']
clean_ni2 = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id2)
self.get_network_interface_waiter().wait_available(ni_id2)
kwargs = {
'DeviceIndex': 2,
'InstanceId': instance_id,
'NetworkInterfaceId': ni_id2
}
data = self.client.attach_network_interface(*[], **kwargs)
attachment_id = data['AttachmentId']
instance = self.get_instance(instance_id)
nis = instance.get('NetworkInterfaces', [])
self.assertEqual(2, len(nis))
ni = nis[0]
if ni['Attachment']['AttachmentId'] != attachment_id:
ni = nis[1]
self.assertEqual(attachment_id, ni['Attachment']['AttachmentId'])
self.assertFalse(ni['Attachment']['DeleteOnTermination'])
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
self.get_network_interface_waiter().wait_available(ni_id)
self.get_network_interface_waiter().wait_available(ni_id2)
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(clean_ni)
self.get_network_interface_waiter().wait_delete(ni_id)
self.client.delete_network_interface(NetworkInterfaceId=ni_id2)
self.cancelResourceCleanUp(clean_ni2)
self.get_network_interface_waiter().wait_delete(ni_id2)
@decorators.idempotent_id('de910bc7-008a-40c2-b4b2-4587a489fc1c')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_network_interfaces_are_deleted_on_termination(self):
instance_id = self.run_instance(SubnetId=self.subnet_id)
instance = self.get_instance(instance_id)
nis = instance.get('NetworkInterfaces', [])
self.assertEqual(1, len(nis))
self.assertTrue(nis[0]['Attachment']['DeleteOnTermination'])
ni_id = nis[0]['NetworkInterfaceId']
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id2 = data['NetworkInterface']['NetworkInterfaceId']
self.addResourceCleanUp(self.client.delete_network_interface,
NetworkInterfaceId=ni_id2)
self.get_network_interface_waiter().wait_available(ni_id2)
kwargs = {
'DeviceIndex': 2,
'InstanceId': instance_id,
'NetworkInterfaceId': ni_id2
}
data = self.client.attach_network_interface(*[], **kwargs)
attachment_id = data['AttachmentId']
kwargs = {
'NetworkInterfaceId': ni_id2,
'Attachment': {
'AttachmentId': attachment_id,
'DeleteOnTermination': True,
}
}
self.client.modify_network_interface_attribute(*[], **kwargs)
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
self.get_network_interface_waiter().wait_delete(ni_id)
self.get_network_interface_waiter().wait_delete(ni_id2)
@decorators.idempotent_id('028eb864-59e9-4ed6-a062-9d5de9eba652')
def test_network_interface_attribute_description(self):
desc = data_utils.rand_name('ni')
data = self.client.create_network_interface(
SubnetId=self.subnet_id, Description=desc)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
data = self.client.describe_network_interface_attribute(
NetworkInterfaceId=ni_id, Attribute='description')
self.assertEqual(desc, data['Description']['Value'])
new_desc = data_utils.rand_name('new-ni')
self.client.modify_network_interface_attribute(
NetworkInterfaceId=ni_id, Description={'Value': new_desc})
data = self.client.describe_network_interface_attribute(
NetworkInterfaceId=ni_id, Attribute='description')
self.assertEqual(new_desc, data['Description']['Value'])
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
@decorators.idempotent_id('9428b5e6-42f2-495f-a535-df53d1fcf4af')
def test_network_interface_attribute_source_dest_check(self):
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
self.client.modify_network_interface_attribute(
NetworkInterfaceId=ni_id, SourceDestCheck={'Value': False})
data = self.client.describe_network_interface_attribute(
NetworkInterfaceId=ni_id, Attribute='sourceDestCheck')
self.assertFalse(data['SourceDestCheck']['Value'])
# NOTE(andrey-mp): ResetNetworkInterfaceAttribute had inadequate json
# scheme in botocore and doesn't work against Amazon.
self.client.modify_network_interface_attribute(
NetworkInterfaceId=ni_id, SourceDestCheck={'Value': True})
data = self.client.describe_network_interface_attribute(
NetworkInterfaceId=ni_id, Attribute='sourceDestCheck')
self.assertEqual(True, data['SourceDestCheck']['Value'])
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
@decorators.idempotent_id('19d25f59-5b32-4314-b4da-7c8f679b7a96')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_network_interface_attribute_attachment(self):
instance_id = self.run_instance(SubnetId=self.subnet_id)
instance = self.get_instance(instance_id)
nis = instance.get('NetworkInterfaces', [])
self.assertEqual(1, len(nis))
self.assertTrue(nis[0]['Attachment']['DeleteOnTermination'])
ni_id = nis[0]['NetworkInterfaceId']
data = self.client.describe_network_interface_attribute(
NetworkInterfaceId=ni_id, Attribute='attachment')
self.assertIn('Attachment', data)
self.assertTrue(data['Attachment'].get('AttachmentId'))
self.assertTrue(data['Attachment'].get('DeleteOnTermination'))
self.assertEqual(0, data['Attachment'].get('DeviceIndex'))
self.assertEqual(instance_id, data['Attachment'].get('InstanceId'))
self.assertEqual('attached', data['Attachment'].get('Status'))
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('74967cd0-155f-4cfe-994e-2c6803dad04c')
def test_network_interface_attribute_empty_attachment(self):
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
data = self.client.describe_network_interface_attribute(
NetworkInterfaceId=ni_id, Attribute='attachment')
self.assertNotIn('Attachment', data)
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
@decorators.idempotent_id('a55f1169-d302-4166-b74e-e84a0d79129c')
def test_network_interface_attribute_group_set(self):
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
data = self.client.describe_network_interface_attribute(
NetworkInterfaceId=ni_id, Attribute='groupSet')
self.assertIn('Groups', data)
self.assertEqual(1, len(data['Groups']))
self.assertEqual('default', data['Groups'][0]['GroupName'])
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
@decorators.idempotent_id('7832976f-27cb-405e-ab05-466b102d86f8')
def test_instance_attributes_negative(self):
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
self.assertRaises('InvalidParameterCombination',
self.client.describe_network_interface_attribute,
NetworkInterfaceId=ni_id)
self.assertRaises('InvalidParameterValue',
self.client.describe_network_interface_attribute,
NetworkInterfaceId=ni_id, Attribute='fake')
self.assertRaises('InvalidNetworkInterfaceID.NotFound',
self.client.describe_network_interface_attribute,
NetworkInterfaceId='eni-0', Attribute='description')
self.assertRaises('InvalidParameterCombination',
self.client.modify_network_interface_attribute,
NetworkInterfaceId=ni_id)
self.assertRaises('MissingParameter',
self.client.modify_network_interface_attribute,
NetworkInterfaceId=ni_id,
Attachment={'AttachmentId': 'fake'})
self.assertRaises('InvalidAttachmentID.NotFound',
self.client.modify_network_interface_attribute,
NetworkInterfaceId=ni_id,
Attachment={'AttachmentId': 'eni-attach-0',
'DeleteOnTermination': True})
self.assertRaises('InvalidGroup.NotFound',
self.client.modify_network_interface_attribute,
NetworkInterfaceId=ni_id, Groups=['sg-0'])
self.assertRaises('InvalidParameterCombination',
self.client.modify_network_interface_attribute,
NetworkInterfaceId=ni_id, Description={})
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)