bb89039e9b
it was enabled by commit https://github.com/openstack/nova/commit/b06867c5 Change-Id: Ie28c296e39a88553be945ac4e4238ebc2e51d110
274 lines
11 KiB
Python
274 lines
11 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.
|
|
|
|
from oslo_log import log
|
|
import testtools
|
|
|
|
from ec2api.tests.functional import base
|
|
from ec2api.tests.functional import config
|
|
|
|
CONF = config.CONF
|
|
LOG = log.getLogger(__name__)
|
|
|
|
|
|
class InstanceInVPCTest(base.EC2TestCase):
|
|
|
|
VPC_CIDR = '10.16.0.0/20'
|
|
vpc_id = None
|
|
SUBNET_CIDR = '10.16.0.0/24'
|
|
subnet_id = None
|
|
|
|
@classmethod
|
|
@base.safe_setup
|
|
def setUpClass(cls):
|
|
super(InstanceInVPCTest, 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)
|
|
|
|
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
|
|
def test_create_delete_instance(self):
|
|
instance_id = self.run_instance(SubnetId=self.subnet_id)
|
|
|
|
data = self.client.describe_instances(InstanceIds=[instance_id])
|
|
reservations = data.get('Reservations', [])
|
|
self.assertNotEmpty(reservations)
|
|
instances = reservations[0].get('Instances', [])
|
|
self.assertNotEmpty(instances)
|
|
instance = instances[0]
|
|
self.assertEqual(self.vpc_id, instance['VpcId'])
|
|
self.assertEqual(self.subnet_id, instance['SubnetId'])
|
|
self.assertTrue(instance['SourceDestCheck'])
|
|
self.assertEqual(1, len(instance['NetworkInterfaces']))
|
|
ni = instance['NetworkInterfaces'][0]
|
|
self.assertEqual(1, len(ni['Groups']))
|
|
self.assertIsNotNone(ni['MacAddress'])
|
|
self.assertIsNotNone(ni['PrivateIpAddress'])
|
|
self.assertTrue(ni['SourceDestCheck'])
|
|
self.assertEqual('in-use', ni['Status'])
|
|
self.assertEqual(self.vpc_id, ni['VpcId'])
|
|
self.assertEqual(self.subnet_id, ni['SubnetId'])
|
|
|
|
self.client.terminate_instances(InstanceIds=[instance_id])
|
|
self.get_instance_waiter().wait_delete(instance_id)
|
|
|
|
# NOTE(andrey-mp): There is difference between Openstack and Amazon.
|
|
# Amazon returns instance in 'terminated' state some time after
|
|
# instance deletion. But Openstack doesn't return such instance.
|
|
|
|
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
|
|
def test_describe_instances_filter(self):
|
|
instance_id = self.run_instance(SubnetId=self.subnet_id)
|
|
|
|
data = self.client.describe_instances(InstanceIds=[instance_id])
|
|
self.assert_instance(data, instance_id)
|
|
instances = data['Reservations'][0]['Instances']
|
|
private_dns = instances[0]['PrivateDnsName']
|
|
private_ip = instances[0]['PrivateIpAddress']
|
|
|
|
# NOTE(andrey-mp): by private ip
|
|
data = self.client.describe_instances(
|
|
Filters=[{'Name': 'private-ip-address', 'Values': ['1.2.3.4']}])
|
|
self.assertEqual(0, len(data['Reservations']))
|
|
|
|
data = self.client.describe_instances(
|
|
Filters=[{'Name': 'private-ip-address', 'Values': [private_ip]}])
|
|
self.assert_instance(data, instance_id)
|
|
|
|
# NOTE(andrey-mp): by private dns
|
|
data = self.client.describe_instances(
|
|
Filters=[{'Name': 'private-dns-name', 'Values': ['fake.com']}])
|
|
self.assertEqual(0, len(data['Reservations']))
|
|
|
|
data = self.client.describe_instances(
|
|
Filters=[{'Name': 'private-dns-name', 'Values': [private_dns]}])
|
|
self.assert_instance(data, instance_id)
|
|
|
|
# NOTE(andrey-mp): by subnet id
|
|
data = self.client.describe_instances(
|
|
Filters=[{'Name': 'subnet-id', 'Values': ['subnet-0']}])
|
|
self.assertEqual(0, len(data['Reservations']))
|
|
|
|
data = self.client.describe_instances(
|
|
Filters=[{'Name': 'subnet-id', 'Values': [self.subnet_id]}])
|
|
self.assert_instance(data, instance_id)
|
|
|
|
# NOTE(andrey-mp): by vpc id
|
|
data = self.client.describe_instances(
|
|
Filters=[{'Name': 'vpc-id', 'Values': ['vpc-0']}])
|
|
self.assertEqual(0, len(data['Reservations']))
|
|
|
|
data = self.client.describe_instances(
|
|
Filters=[{'Name': 'vpc-id', 'Values': [self.vpc_id]}])
|
|
self.assert_instance(data, instance_id)
|
|
|
|
self.client.terminate_instances(InstanceIds=[instance_id])
|
|
self.get_instance_waiter().wait_delete(instance_id)
|
|
|
|
def assert_instance(self, data, instance_id):
|
|
reservations = data.get('Reservations', [])
|
|
self.assertNotEmpty(reservations)
|
|
instances = reservations[0].get('Instances', [])
|
|
self.assertNotEmpty(instances)
|
|
self.assertEqual(instance_id, instances[0]['InstanceId'])
|
|
|
|
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
|
|
def test_create_instance_with_two_interfaces(self):
|
|
kwargs = {
|
|
'SubnetId': self.subnet_id,
|
|
}
|
|
data = self.client.create_network_interface(*[], **kwargs)
|
|
ni_id1 = data['NetworkInterface']['NetworkInterfaceId']
|
|
clean_ni1 = self.addResourceCleanUp(
|
|
self.client.delete_network_interface, NetworkInterfaceId=ni_id1)
|
|
self.get_network_interface_waiter().wait_available(ni_id1)
|
|
|
|
kwargs = {
|
|
'SubnetId': self.subnet_id,
|
|
}
|
|
data = self.client.create_network_interface(*[], **kwargs)
|
|
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)
|
|
|
|
instance_id = self.run_instance(
|
|
NetworkInterfaces=[{'NetworkInterfaceId': ni_id1,
|
|
'DeviceIndex': 0},
|
|
{'NetworkInterfaceId': ni_id2,
|
|
'DeviceIndex': 2}])
|
|
|
|
instance = self.get_instance(instance_id)
|
|
nis = instance.get('NetworkInterfaces', [])
|
|
self.assertEqual(2, len(nis))
|
|
|
|
self.client.terminate_instances(InstanceIds=[instance_id])
|
|
self.get_instance_waiter().wait_delete(instance_id)
|
|
|
|
self.get_network_interface_waiter().wait_available(ni_id1)
|
|
self.get_network_interface_waiter().wait_available(ni_id2)
|
|
|
|
self.client.delete_network_interface(
|
|
NetworkInterfaceId=ni_id2)
|
|
self.cancelResourceCleanUp(clean_ni2)
|
|
self.get_network_interface_waiter().wait_delete(ni_id2)
|
|
|
|
self.client.delete_network_interface(
|
|
NetworkInterfaceId=ni_id1)
|
|
self.cancelResourceCleanUp(clean_ni1)
|
|
self.get_network_interface_waiter().wait_delete(ni_id1)
|
|
|
|
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
|
|
def test_create_instance_with_private_ip(self):
|
|
ip = '10.16.0.12'
|
|
|
|
instance_id = self.run_instance(SubnetId=self.subnet_id,
|
|
PrivateIpAddress=ip)
|
|
|
|
instance = self.get_instance(instance_id)
|
|
self.assertEqual(ip, instance['PrivateIpAddress'])
|
|
|
|
self.client.terminate_instances(InstanceIds=[instance_id])
|
|
self.get_instance_waiter().wait_delete(instance_id)
|
|
|
|
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
|
|
def test_create_instance_with_invalid_params(self):
|
|
def _rollback(fn_data):
|
|
self.client.terminate_instances(
|
|
InstanceIds=[fn_data['Instances'][0]['InstanceId']])
|
|
|
|
kwargs = {
|
|
'ImageId': CONF.aws.image_id,
|
|
'InstanceType': CONF.aws.instance_type,
|
|
'MinCount': 1,
|
|
'MaxCount': 1,
|
|
'PrivateIpAddress': '10.16.1.2'
|
|
}
|
|
self.assertRaises('InvalidParameterCombination',
|
|
self.client.run_instances, rollback_fn=_rollback,
|
|
**kwargs)
|
|
|
|
kwargs = {
|
|
'ImageId': CONF.aws.image_id,
|
|
'InstanceType': CONF.aws.instance_type,
|
|
'MinCount': 1,
|
|
'MaxCount': 1,
|
|
'SubnetId': self.subnet_id,
|
|
'PrivateIpAddress': '10.16.1.12'
|
|
}
|
|
self.assertRaises('InvalidParameterValue',
|
|
self.client.run_instances, rollback_fn=_rollback,
|
|
**kwargs)
|
|
|
|
kwargs = {
|
|
'SubnetId': self.subnet_id,
|
|
}
|
|
data = self.client.create_network_interface(*[], **kwargs)
|
|
ni_id1 = data['NetworkInterface']['NetworkInterfaceId']
|
|
self.addResourceCleanUp(self.client.delete_network_interface,
|
|
NetworkInterfaceId=ni_id1)
|
|
self.get_network_interface_waiter().wait_available(ni_id1)
|
|
|
|
kwargs = {
|
|
'SubnetId': self.subnet_id,
|
|
}
|
|
data = self.client.create_network_interface(*[], **kwargs)
|
|
ni_id2 = data['NetworkInterface']['NetworkInterfaceId']
|
|
self.addResourceCleanUp(self.client.delete_network_interface,
|
|
NetworkInterfaceId=ni_id2)
|
|
self.get_network_interface_waiter().wait_available(ni_id2)
|
|
|
|
# NOTE(andrey-mp): A network interface may not specify a network
|
|
# interface ID and delete on termination as true
|
|
kwargs = {
|
|
'ImageId': CONF.aws.image_id,
|
|
'InstanceType': CONF.aws.instance_type,
|
|
'MinCount': 1,
|
|
'MaxCount': 1,
|
|
'NetworkInterfaces': [{'NetworkInterfaceId': ni_id1,
|
|
'DeviceIndex': 0,
|
|
'DeleteOnTermination': True}]
|
|
}
|
|
self.assertRaises('InvalidParameterCombination',
|
|
self.client.run_instances, rollback_fn=_rollback,
|
|
**kwargs)
|
|
|
|
if CONF.aws.run_incompatible_tests:
|
|
# NOTE(andrey-mp): Each network interface requires a device index.
|
|
kwargs = {
|
|
'ImageId': CONF.aws.image_id,
|
|
'InstanceType': CONF.aws.instance_type,
|
|
'MinCount': 1,
|
|
'MaxCount': 1,
|
|
'NetworkInterfaces': [{'NetworkInterfaceId': ni_id1},
|
|
{'NetworkInterfaceId': ni_id2}]
|
|
}
|
|
self.assertRaises('InvalidParameterValue',
|
|
self.client.run_instances, rollback_fn=_rollback,
|
|
**kwargs)
|