mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
1214 lines
53 KiB
Python
1214 lines
53 KiB
Python
# Licensed to the Apache Software Foundation (ASF) under one
|
|
# or more contributor license agreements. See the NOTICE file
|
|
# distributed with this work for additional information
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
# to you 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.
|
|
|
|
""" Component tests for user data, meta data, ssh keys
|
|
and password reset functionality with
|
|
ConfigDrive and Nuage VSP SDN plugin
|
|
"""
|
|
import base64
|
|
import copy
|
|
import os
|
|
import threading
|
|
|
|
from datetime import datetime
|
|
from marvin.lib.base import (Account,
|
|
NetworkServiceProvider,
|
|
PublicIpRange,
|
|
PublicIPAddress,
|
|
VirtualMachine)
|
|
# Import System Modules
|
|
from nose.plugins.attrib import attr
|
|
from nuage_lib import GherkinMetaClass
|
|
|
|
# Import Local Modules
|
|
from component.test_configdrive import ConfigDriveUtils
|
|
from nuageTestCase import nuageTestCase
|
|
|
|
NO_SUCH_FILE = "No such file or directory"
|
|
|
|
|
|
class TestNuageConfigDrive(nuageTestCase, ConfigDriveUtils):
|
|
"""Test user data and password reset functionality
|
|
using configDrive with Nuage VSP SDN plugin
|
|
"""
|
|
|
|
__metaclass__ = GherkinMetaClass
|
|
|
|
class StartVM(threading.Thread):
|
|
|
|
def __init__(self, nuagetestcase, network, index):
|
|
threading.Thread.__init__(self)
|
|
self.network = network
|
|
self.nuagetestcase = nuagetestcase
|
|
self.vm = None
|
|
self.index = index
|
|
|
|
def run(self):
|
|
self.vm = self.nuagetestcase.create_VM(
|
|
self.network,
|
|
account=self.nuagetestcase.account,
|
|
cleanup=False)
|
|
self.nuagetestcase.check_VM_state(self.vm, state="Running")
|
|
self.nuagetestcase.debug("[Concurrency]VM %d running, name = %s"
|
|
% (self.index + 1, self.vm.name))
|
|
|
|
def get_vm(self):
|
|
return self.vm
|
|
|
|
def stop(self):
|
|
self.vm.delete(self.nuagetestcase.api_client)
|
|
|
|
def update(self):
|
|
expected_user_data = "hello world vm %s" % self.vm.name
|
|
user_data = base64.b64encode(expected_user_data)
|
|
self.vm.update(self.nuagetestcase.api_client, userdata=user_data)
|
|
|
|
class StopVM(threading.Thread):
|
|
|
|
def __init__(self, nuagetestcase, vm, **kwargs):
|
|
threading.Thread.__init__(self)
|
|
self.vm = vm
|
|
self.nuagetestcase = nuagetestcase
|
|
|
|
def run(self):
|
|
self.vm.delete(self.nuagetestcase.api_client)
|
|
if self.vm in self.nuagetestcase.cleanup:
|
|
self.nuagetestcase.cleanup.remove(self.vm)
|
|
|
|
def get_vm(self):
|
|
return self.vm
|
|
|
|
@staticmethod
|
|
def get_name():
|
|
return "delete"
|
|
|
|
class UpdateVM(threading.Thread):
|
|
|
|
def __init__(self, nuagetestcase, vm, **kwargs):
|
|
threading.Thread.__init__(self)
|
|
self.vm = vm
|
|
self.nuagetestcase = nuagetestcase
|
|
self.idx = kwargs["idx"]
|
|
|
|
def run(self):
|
|
self.expected_user_data = "hello world vm %s" % self.vm.name
|
|
self.end = None
|
|
self.start = datetime.now()
|
|
self.nuagetestcase.when_I_update_userdata(self.vm,
|
|
self.expected_user_data)
|
|
self.end = datetime.now()
|
|
self.nuagetestcase.debug("[Concurrency]Update userdata idx=%d "
|
|
"for vm: %s. Duration in seconds: %s " %
|
|
(self.idx, self.vm.name,
|
|
(self.end - self.start).total_seconds()))
|
|
return self.expected_user_data
|
|
|
|
def get_vm(self):
|
|
return self.vm
|
|
|
|
def get_timestamps(self):
|
|
if not self.end:
|
|
self.end = datetime.now()
|
|
return [self.start, self.end]
|
|
|
|
def get_userdata(self):
|
|
return self.expected_user_data
|
|
|
|
@staticmethod
|
|
def get_name():
|
|
return "userdata"
|
|
|
|
class ResetPassword(threading.Thread):
|
|
|
|
def __init__(self, nuagetestcase, vm, **kwargs):
|
|
threading.Thread.__init__(self)
|
|
self.vm = vm
|
|
self.nuagetestcase = nuagetestcase
|
|
|
|
def run(self):
|
|
self.start = datetime.now()
|
|
self.nuagetestcase.when_I_reset_the_password(self.vm)
|
|
self.end = datetime.now()
|
|
self.nuagetestcase.debug("[Concurrency]Reset password for vm: %s. "
|
|
"Duration in seconds: %s "
|
|
%
|
|
(self.vm.name,
|
|
(self.end - self.start).total_seconds()))
|
|
|
|
def get_vm(self):
|
|
return self.vm
|
|
|
|
def get_timestamps(self):
|
|
if not self.end:
|
|
self.end = datetime.now()
|
|
return [self.start, self.end]
|
|
|
|
def get_password(self):
|
|
return self.vm.password
|
|
|
|
@staticmethod
|
|
def get_name():
|
|
return "reset password"
|
|
|
|
def __init__(self, methodName='runTest'):
|
|
super(TestNuageConfigDrive, self).__init__(methodName)
|
|
ConfigDriveUtils.__init__(self)
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(TestNuageConfigDrive, cls).setUpClass()
|
|
return
|
|
|
|
def setUp(self):
|
|
# Create an account
|
|
self.account = Account.create(self.api_client,
|
|
self.test_data["account"],
|
|
admin=True,
|
|
domainid=self.domain.id
|
|
)
|
|
self.tmp_files = []
|
|
self.cleanup = [self.account]
|
|
self.generate_ssh_keys()
|
|
return
|
|
|
|
def tearDown(self):
|
|
super(TestNuageConfigDrive, self).tearDown()
|
|
for tmp_file in self.tmp_files:
|
|
os.remove(tmp_file)
|
|
|
|
self.update_template(passwordenabled=False)
|
|
return
|
|
|
|
def validate_acl_rule(self, fw_rule):
|
|
self.verify_vsd_firewall_rule(fw_rule)
|
|
|
|
def validate_StaticNat_rule_For_VM(self, public_ip, network, vm):
|
|
self.verify_vsd_floating_ip(network, vm, public_ip.ipaddress, self.vpc)
|
|
|
|
def validate_vm_networking(self, vm):
|
|
self.verify_vsd_vm(vm)
|
|
|
|
def validate_network_networking(self, network, vpc):
|
|
self.verify_vsd_network(self.domain.id, network, vpc=vpc)
|
|
|
|
def validate_shared_networking(self, network, vm):
|
|
# Verify shared Network and VM in VSD
|
|
subnet_id = self.get_subnet_id(network.id, network.gateway)
|
|
|
|
self.verify_vsd_shared_network(self.domain.id, network,
|
|
gateway=network.gateway)
|
|
self.verify_vsd_enterprise_vm(self.domain.id, network, vm,
|
|
sharedsubnetid=subnet_id)
|
|
|
|
def _get_test_data(self, key):
|
|
return self.test_data["nuagevsp"][key]
|
|
|
|
def get_configdrive_provider(self):
|
|
return NetworkServiceProvider.list(
|
|
self.api_client,
|
|
name="ConfigDrive",
|
|
physicalnetworkid=self.vsp_physical_network.id)[0]
|
|
|
|
def get_vpc_offering_name(self):
|
|
return "vpc_offering_configdrive_withoutdns"
|
|
|
|
def get_network_offering_name(self):
|
|
return "isolated_configdrive_network_offering_withoutdns"
|
|
|
|
def get_network_offering_name_for_vpc(self):
|
|
return "vpc_network_offering_configdrive_withoutdns"
|
|
|
|
# =========================================================================
|
|
# --- Gherkin style helper methods ---
|
|
# =========================================================================
|
|
|
|
def then_vr_is_as_expected(self, network):
|
|
"""Then there is a VR or not in network {network.id}"""
|
|
if "Dns" in [s.name for s in network.service]:
|
|
vr = self.check_Router_state(network=network, state="Running")
|
|
self.verify_vsd_router(vr)
|
|
else:
|
|
with self.assertRaises(Exception):
|
|
self.get_Router(network)
|
|
self.debug("+++Verified no VR is spawned for this network ")
|
|
|
|
def when_I_change_the_network_offering_to(self, network, offering_name):
|
|
updated_network =\
|
|
self.upgrade_Network(self._get_test_data(offering_name), network)
|
|
network.service = updated_network.service
|
|
|
|
# =========================================================================
|
|
# --- TEST CASES ---
|
|
# =========================================================================
|
|
|
|
@attr(tags=["advanced", "nuagevsp", "isonw"], required_hardware="true")
|
|
def test_nuage_config_drive_isolated_network_with_vr(self):
|
|
self.debug("+++Test user data & password reset functionality "
|
|
"using configdrive in an Isolated network with VR")
|
|
|
|
self.given_config_drive_provider_is("Enabled")
|
|
self.given_template_password_enabled_is(True)
|
|
self.given_a_network_offering("isolated_configdrive_network_offering")
|
|
create_vrnetwork =\
|
|
self.when_I_create_a_network_with_that_offering(gateway='10.1.3.1')
|
|
self.then_the_network_is_successfully_created(create_vrnetwork)
|
|
self.then_the_network_has(create_vrnetwork, state="Allocated")
|
|
|
|
vrnetwork = create_vrnetwork.network
|
|
|
|
vm = self.when_I_deploy_a_vm(vrnetwork)
|
|
self.then_vr_is_as_expected(network=vrnetwork)
|
|
|
|
# We need to have the vm password
|
|
self.when_I_reset_the_password(vm)
|
|
public_ip = self.when_I_create_a_static_nat_ip_to(vm, vrnetwork)
|
|
|
|
self.then_config_drive_is_as_expected(vm, public_ip, metadata=True)
|
|
|
|
self.update_and_validate_userdata(vm, "helloworld vm", public_ip)
|
|
self.then_config_drive_is_as_expected(vm, public_ip)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"verify config drive after restart Isolated network without"
|
|
" cleanup...")
|
|
self.when_I_restart_the_network_with(vrnetwork, cleanup=False)
|
|
self.then_config_drive_is_as_expected(vm, public_ip, metadata=True)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"verify config drive after restart Isolated network with"
|
|
" cleanup...")
|
|
self.when_I_restart_the_network_with(vrnetwork, cleanup=True)
|
|
self.then_config_drive_is_as_expected(vm, public_ip, metadata=True)
|
|
|
|
self.debug("+++ Upgrade offering of created Isolated network with "
|
|
"an offering which removes the VR...")
|
|
self.when_I_change_the_network_offering_to(
|
|
vrnetwork, "isolated_configdrive_network_offering_withoutdns")
|
|
self.then_vr_is_as_expected(network=vrnetwork)
|
|
self.then_config_drive_is_as_expected(vm, public_ip, metadata=True)
|
|
|
|
vm.delete(self.api_client, expunge=True)
|
|
vrnetwork.delete(self.api_client)
|
|
|
|
@attr(tags=["advanced", "nuagevsp", "isonw"], required_hardware="true")
|
|
def test_nuage_configdrive_isolated_network(self):
|
|
"""Test Configdrive as provider for isolated Networks
|
|
to provide userdata and password reset functionality
|
|
with Nuage VSP SDN plugin
|
|
"""
|
|
|
|
# 1. Given ConfigDrive provider is disabled in zone
|
|
# And a network offering which has
|
|
# user data provided by ConfigDrive
|
|
# Then creating an Isolated Network
|
|
# using that network offering fails
|
|
|
|
# 2. Given ConfigDrive provider is enabled in zone
|
|
# And a network offering which has
|
|
# * user data provided by ConfigDrive
|
|
# * No DNS
|
|
# When I create an Isolated Network using that network offering
|
|
# Then the network is successfully created,
|
|
# And is in the "Allocated" state.
|
|
|
|
# 3. When I deploy a VM in the created Isolated network with user data,
|
|
# Then the Isolated network state is changed to "Implemented"
|
|
# And the VM is successfully deployed and is in the "Running" state
|
|
# And there is no VR is deployed.
|
|
# 4. And the user data in the ConfigDrive device is as expected
|
|
# 5. And the the vm's password in the ConfigDrive device is as expected
|
|
|
|
# 6. When I stop, reset the password, and start the VM
|
|
# 7. Then I can login into the VM using the new password.
|
|
# 8. SSH into the VM for verifying its new password
|
|
# after its password reset.
|
|
|
|
# 9. Verify various scenarios and check the data in configdriveIso
|
|
# 10. Delete all the created objects (cleanup).
|
|
|
|
self.debug("+++ Scenario: creating an Isolated network with "
|
|
"config drive fails when config drive provider is "
|
|
"disabled.")
|
|
self.given_config_drive_provider_is("Disabled")
|
|
self.given_a_network_offering_with_configdrive()
|
|
self.then_creating_a_network_with_that_offering_fails()
|
|
|
|
self.debug("+++ Preparation Scenario: "
|
|
"creating an Isolated networks with "
|
|
"config drive when config drive provider is "
|
|
"enabled.")
|
|
|
|
self.given_config_drive_provider_is("Enabled")
|
|
|
|
create_network1 = self.when_I_create_a_network_with_that_offering()
|
|
self.then_the_network_is_successfully_created(create_network1)
|
|
self.then_the_network_has(create_network1, state="Allocated")
|
|
|
|
create_network2 = self.when_I_create_a_network_with_that_offering()
|
|
self.then_the_network_is_successfully_created(create_network2)
|
|
self.then_the_network_has(create_network2, state="Allocated")
|
|
|
|
network1 = create_network1.network
|
|
network2 = create_network2.network
|
|
|
|
self.given_template_password_enabled_is(True)
|
|
|
|
self.debug("+++Deploy VM in the created Isolated network "
|
|
"with user data provider as configdrive")
|
|
|
|
vm1 = self.when_I_deploy_a_vm_with_keypair_in(network1)
|
|
public_ip_1 = \
|
|
self.when_I_create_a_static_nat_ip_to(vm1, network1)
|
|
|
|
self.then_vr_is_as_expected(network=network1)
|
|
self.then_config_drive_is_as_expected(
|
|
vm1, public_ip_1,
|
|
metadata=True)
|
|
|
|
self.update_and_validate_userdata(vm1, "helloworld vm1", public_ip_1)
|
|
self.update_and_validate_sshkeypair(vm1, public_ip_1)
|
|
|
|
# =====================================================================
|
|
|
|
self.debug("Adding a non-default nic to the VM "
|
|
"making it a multi-nic VM...")
|
|
self.plug_nic(vm1, network2)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip_1,
|
|
metadata=True, reconnect=False)
|
|
|
|
with self.stopped_vm(vm1):
|
|
self.when_I_reset_the_password(vm1)
|
|
self.when_I_update_userdata(vm1, "hellomultinicvm1")
|
|
|
|
self.then_config_drive_is_as_expected(vm1, public_ip_1)
|
|
|
|
# =====================================================================
|
|
# Test using network2 as default network
|
|
# =====================================================================
|
|
|
|
self.debug("updating non-default nic as the default nic "
|
|
"of the multi-nic VM and enable staticnat...")
|
|
self.update_default_nic(vm1, network2)
|
|
|
|
public_ip_2 = \
|
|
self.when_I_create_a_static_nat_ip_to(vm1, network2)
|
|
self.stop_and_start_vm(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip_2, metadata=True)
|
|
|
|
self.when_I_reset_the_password(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip_2)
|
|
|
|
user_data = "hellomultinicvm1again"
|
|
self.update_and_validate_userdata(vm1, user_data, public_ip_2)
|
|
|
|
self.debug("Updating the default nic of the multi-nic VM, "
|
|
"deleting the non-default nic...")
|
|
self.update_default_nic(vm1, network1)
|
|
self.stop_and_start_vm(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip_1, metadata=True)
|
|
|
|
self.delete(public_ip_2)
|
|
self.unplug_nic(vm1, network2)
|
|
|
|
# =====================================================================
|
|
# Another Multinic VM
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"Reset password and update userdata on a multi nic vm")
|
|
multinicvm1 = self.when_I_deploy_a_vm([network2, network1])
|
|
self.when_I_reset_the_password(multinicvm1)
|
|
public_ip_3 = self.when_I_create_a_static_nat_ip_to(multinicvm1,
|
|
network2)
|
|
self.then_config_drive_is_as_expected(
|
|
multinicvm1, public_ip_3,
|
|
metadata=True)
|
|
|
|
user_data2 = "hello multinicvm1"
|
|
self.update_and_validate_userdata(multinicvm1, user_data2, public_ip_3)
|
|
|
|
self.delete(multinicvm1, expunge=True)
|
|
self.delete(public_ip_3)
|
|
self.delete(network2)
|
|
|
|
# =====================================================================
|
|
# Network restart tests
|
|
# =====================================================================
|
|
|
|
self.debug("+++ Scenario: "
|
|
"verify config drive after restart Isolated network without"
|
|
" cleanup...")
|
|
self.when_I_reset_the_password(vm1)
|
|
self.when_I_restart_the_network_with(network1, cleanup=False)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip_1,
|
|
metadata=True, reconnect=False)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"verify config drive after restart Isolated network with"
|
|
" cleanup...")
|
|
self.when_I_restart_the_network_with(network1, cleanup=True)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip_1,
|
|
metadata=True, reconnect=False)
|
|
|
|
# =====================================================================
|
|
# Nuage --
|
|
# Update offering to VR
|
|
# =====================================================================
|
|
self.debug("+++ Upgrade offering of created Isolated network with "
|
|
"a dns offering which spins a VR")
|
|
self.upgrade_Network(self.test_data["nuagevsp"][
|
|
"isolated_configdrive_network_offering"],
|
|
create_network1.network)
|
|
vr = self.get_Router(create_network1.network)
|
|
self.check_Router_state(vr, state="Running")
|
|
# VSD verification
|
|
self.verify_vsd_network(self.domain.id, create_network1.network)
|
|
self.verify_vsd_router(vr)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"update userdata and reset password after reboot")
|
|
vm1.reboot(self.api_client)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip_1, metadata=True)
|
|
self.update_and_validate_userdata(vm1, "hello afterboot", public_ip_1)
|
|
self.when_I_reset_the_password(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip_1)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"update userdata and reset password after migrate")
|
|
self.migrate_VM(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip_1, metadata=True)
|
|
self.debug("Updating userdata after migrating VM - %s" % vm1.name)
|
|
self.update_and_validate_userdata(vm1, "hello after migrate",
|
|
public_ip_1)
|
|
self.when_I_reset_the_password(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip_1)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"update userdata and reset password after stop/start")
|
|
self.stop_and_start_vm(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip_1, metadata=True)
|
|
self.update_and_validate_userdata(vm1, "hello afterstopstart",
|
|
public_ip_1)
|
|
self.when_I_reset_the_password(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip_1)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"verify config drive after delete/recover")
|
|
self.delete_and_recover_vm(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip_1,
|
|
metadata=True)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"Start VM fails when ConfigDrive provider is disabled")
|
|
self.given_config_drive_provider_is("Disabled")
|
|
with self.assertRaises(Exception):
|
|
self.when_I_update_userdata(vm1, "hi with provider state Disabled")
|
|
self.given_config_drive_provider_is("Enabled")
|
|
|
|
self.delete(vm1, expunge=True)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"Update Userdata on a VM that is not password enabled")
|
|
self.update_template(passwordenabled=False)
|
|
vm1 = self.when_I_deploy_a_vm_with_keypair_in(network1)
|
|
|
|
public_ip_1 = \
|
|
self.when_I_create_a_static_nat_ip_to(vm1, network1)
|
|
|
|
self.update_and_validate_userdata(vm1,
|
|
"This is sample data",
|
|
public_ip_1,
|
|
metadata=True)
|
|
|
|
@attr(tags=["advanced", "nuagevsp", "vpc"], required_hardware="true")
|
|
def test_nuage_configdrive_vpc_network_with_vr(self):
|
|
self.debug("Testing user data & password reset functionality "
|
|
" using configdrive in a VPC network with VR...")
|
|
|
|
self.given_config_drive_provider_is("Enabled")
|
|
self.given_template_password_enabled_is(True)
|
|
self.given_a_vpc_with_offering("vpc_offering_configdrive_withdns")
|
|
self.given_a_network_offering(
|
|
"vpc_network_offering_configdrive_withdns")
|
|
create_tier = self.when_I_create_a_vpc_tier_with_that_offering(
|
|
gateway='10.1.3.1')
|
|
self.then_the_network_is_successfully_created(create_tier)
|
|
self.then_the_network_has(create_tier, state="Implemented")
|
|
|
|
tier = create_tier.network
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"Deploy VM in the Tier 1 with user data")
|
|
vm = self.when_I_deploy_a_vm(tier)
|
|
self.then_vr_is_as_expected(network=tier)
|
|
|
|
public_ip = \
|
|
self.when_I_create_a_static_nat_ip_to(vm, tier)
|
|
self.then_config_drive_is_as_expected(vm, public_ip, metadata=True)
|
|
|
|
self.when_I_reset_the_password(vm)
|
|
self.then_config_drive_is_as_expected(vm, public_ip)
|
|
|
|
self.update_and_validate_userdata(vm, "helloworld vm2", public_ip,
|
|
metadata=True)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"Restarting the created vpc without cleanup...")
|
|
self.when_I_restart_the_vpc_with(cleanup=False)
|
|
self.then_config_drive_is_as_expected(vm, public_ip, metadata=True)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"verify config drive after Restart VPC with cleanup...")
|
|
self.when_I_restart_the_vpc_with(cleanup=True)
|
|
self.then_config_drive_is_as_expected(vm, public_ip,
|
|
metadata=True, reconnect=False)
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"verify config drive after Restart tier without cleanup...")
|
|
self.when_I_restart_the_network_with(tier, cleanup=False)
|
|
self.then_config_drive_is_as_expected(vm, public_ip,
|
|
metadata=True, reconnect=False)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"verify config drive after restart tier with cleanup...")
|
|
self.when_I_restart_the_network_with(tier, cleanup=True)
|
|
self.then_config_drive_is_as_expected(vm, public_ip,
|
|
metadata=True, reconnect=False)
|
|
|
|
self.debug("+++ Upgrade offering of created VPC network with "
|
|
"an offering which removes the VR...")
|
|
self.when_I_change_the_network_offering_to(
|
|
tier, "vpc_network_offering_configdrive_withoutdns")
|
|
self.then_vr_is_as_expected(network=tier)
|
|
self.then_config_drive_is_as_expected(vm, public_ip,
|
|
metadata=True, reconnect=False)
|
|
|
|
vm.delete(self.api_client, expunge=True)
|
|
tier.delete(self.api_client)
|
|
self.vpc.delete(self.api_client)
|
|
|
|
@attr(tags=["advanced", "nuagevsp", "vpc"], required_hardware="true")
|
|
def test_nuage_configdrive_vpc_network(self):
|
|
"""Test Configdrive for VPC Networks
|
|
choose user data with configDrive as service provider
|
|
and test password reset functionality using ConfigDrive
|
|
with Nuage VSP SDN plugin
|
|
"""
|
|
|
|
# 1. Given ConfigDrive provider is disabled in zone
|
|
# And a network offering for VPC which has
|
|
# user data provided by ConfigDrive
|
|
# And a VPC
|
|
# Then creating an VPC Tier in the VPC
|
|
# using that network offering fails
|
|
|
|
# 2. Given ConfigDrive provider is enabled in zone
|
|
# And a network offering for VPC which has
|
|
# user data provided by ConfigDrive
|
|
# And a VPC
|
|
# When I create an VPC Tier in the VPC using that network offering
|
|
# Then the network is successfully created,
|
|
# And is in the "Allocated" state.
|
|
|
|
# 3. When I deploy a VM in the created VPC tier with user data,
|
|
# Then the network state is changed to "Implemented"
|
|
# And the VM is successfully deployed and is in the "Running" state
|
|
|
|
# 4. And the user data in the ConfigDrive device is as expected
|
|
# 5. And the the vm password in the ConfigDrive device is as expected
|
|
|
|
# 6. When I stop, reset the password, and start the VM
|
|
# 7. Then I can login into the VM using the new password.
|
|
# 8. And the the vm password in the ConfigDrive device is the new one
|
|
|
|
# 9. Verify various scenarios and check the data in configdriveIso
|
|
# 10. Delete all the created objects (cleanup).
|
|
|
|
self.debug("+++ Scenario: creating an VPC tier with "
|
|
"config drive fails when config drive provider is "
|
|
"disabled.")
|
|
self.given_a_vpc()
|
|
self.given_config_drive_provider_is("Disabled")
|
|
self.given_a_network_offering_for_vpc_with_configdrive()
|
|
self.then_creating_a_vpc_tier_with_that_offering_fails()
|
|
|
|
self.debug("+++ Preparation Scenario: "
|
|
"Create 2 tier with config drive "
|
|
"when config drive provider is enabled.")
|
|
|
|
self.given_config_drive_provider_is("Enabled")
|
|
|
|
create_network1 = self.when_I_create_a_vpc_tier_with_that_offering(
|
|
gateway='10.1.1.1')
|
|
self.then_the_network_is_successfully_created(create_network1)
|
|
self.then_the_network_has(create_network1, state="Implemented")
|
|
|
|
create_network2 = self.when_I_create_a_vpc_tier_with_that_offering(
|
|
gateway='10.1.2.1')
|
|
self.then_the_network_is_successfully_created(create_network2)
|
|
self.then_the_network_has(create_network2, state="Implemented")
|
|
|
|
network1 = create_network1.network
|
|
network2 = create_network2.network
|
|
|
|
self.given_template_password_enabled_is(True)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"Deploy VM in the Tier 1 with user data")
|
|
vm = self.when_I_deploy_a_vm(network1,
|
|
keypair=self.keypair.name)
|
|
public_ip_1 = \
|
|
self.when_I_create_a_static_nat_ip_to(vm, network1)
|
|
self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)
|
|
|
|
self.update_and_validate_userdata(vm, "helloworld vm1",
|
|
public_ip_1,
|
|
metadata=True)
|
|
|
|
self.when_I_reset_the_password(vm)
|
|
self.then_config_drive_is_as_expected(vm, public_ip_1)
|
|
|
|
self.update_and_validate_sshkeypair(vm, public_ip_1)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"Restarting the created vpc without cleanup...")
|
|
self.when_I_restart_the_vpc_with(cleanup=False)
|
|
self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)
|
|
|
|
# =====================================================================
|
|
self.debug("Adding a non-default nic to the VM "
|
|
"making it a multi-nic VM...")
|
|
self.plug_nic(vm, network2)
|
|
self.then_config_drive_is_as_expected(vm, public_ip_1,
|
|
metadata=True, reconnect=False)
|
|
with self.stopped_vm(vm):
|
|
self.when_I_reset_the_password(vm)
|
|
self.when_I_update_userdata(vm, "hellomultinicvm1")
|
|
|
|
self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)
|
|
|
|
self.unplug_nic(vm, network2)
|
|
self.delete(network2)
|
|
|
|
self.debug("+++ Scenario: "
|
|
"verify config drive after Restart VPC with cleanup...")
|
|
self.when_I_restart_the_vpc_with(cleanup=True)
|
|
self.then_config_drive_is_as_expected(vm, public_ip_1,
|
|
metadata=True, reconnect=False)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"verify config drive after Restart tier without cleanup...")
|
|
self.when_I_restart_the_network_with(network1, cleanup=False)
|
|
self.then_config_drive_is_as_expected(vm, public_ip_1,
|
|
metadata=True, reconnect=False)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"verify config drive after restart tier with cleanup...")
|
|
self.when_I_restart_the_network_with(network1, cleanup=True)
|
|
self.then_config_drive_is_as_expected(vm, public_ip_1,
|
|
metadata=True, reconnect=False)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"update userdata and reset password after reboot")
|
|
vm.reboot(self.api_client)
|
|
self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)
|
|
self.update_and_validate_userdata(vm, "hello reboot", public_ip_1)
|
|
|
|
self.when_I_reset_the_password(vm)
|
|
self.then_config_drive_is_as_expected(vm, public_ip_1)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"update userdata and reset password after migrate")
|
|
self.migrate_VM(vm)
|
|
self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)
|
|
self.update_and_validate_userdata(vm, "hello migrate", public_ip_1)
|
|
|
|
self.when_I_reset_the_password(vm)
|
|
self.then_config_drive_is_as_expected(vm, public_ip_1)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"update userdata and reset password after stop/start")
|
|
self.stop_and_start_vm(vm)
|
|
self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)
|
|
|
|
self.update_and_validate_userdata(vm, "hello stop/start", public_ip_1)
|
|
|
|
self.when_I_reset_the_password(vm)
|
|
self.then_config_drive_is_as_expected(vm, public_ip_1)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"verify config drive after delete/recover")
|
|
self.delete_and_recover_vm(vm)
|
|
self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"Verify configdrive when template is not password enabled")
|
|
self.given_config_drive_provider_is("Disabled")
|
|
self.then_config_drive_is_as_expected(vm, public_ip_1,
|
|
metadata=True, reconnect=False)
|
|
self.given_config_drive_provider_is("Enabled")
|
|
|
|
self.delete(vm, expunge=True)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"Update Userdata on a VM that is not password enabled")
|
|
|
|
self.update_template(passwordenabled=False)
|
|
|
|
vm = self.when_I_deploy_a_vm(network1,
|
|
keypair=self.keypair.name)
|
|
public_ip_1 = \
|
|
self.when_I_create_a_static_nat_ip_to(vm, network1)
|
|
self.update_and_validate_userdata(vm, "This is sample data",
|
|
public_ip_1,
|
|
metadata=True)
|
|
|
|
self.delete(vm, expunge=True)
|
|
self.delete(network1)
|
|
|
|
def handle_threads(self, source_threads, thread_class, **kwargs):
|
|
my_threads = []
|
|
for aThread in source_threads:
|
|
my_vm = aThread.get_vm()
|
|
self.debug("[Concurrency]%s in vm: %s"
|
|
% (thread_class.get_name(), my_vm.name))
|
|
new_thread = thread_class(self, my_vm, **kwargs)
|
|
my_threads.append(new_thread)
|
|
new_thread.start()
|
|
#
|
|
# Wait until all threads are finished
|
|
self.wait_until_done(my_threads, thread_class.get_name())
|
|
return my_threads
|
|
|
|
@attr(
|
|
tags=["advanced", "nuagevsp", "concurrency"], required_hardware="true")
|
|
def test_nuage_configDrive_concurrency(self):
|
|
""" Verify concurrency of ConfigDrive userdata update & password reset
|
|
"""
|
|
|
|
# Validate the following
|
|
# 1. When ConfigDrive is enabled as provider in zone
|
|
# Create an Isolated Network with Nuage VSP Isolated Network
|
|
# offering specifying ConfigDrive as serviceProvider for userdata,
|
|
# make sure no Dns is in the offering so no VR is spawned.
|
|
# check if it is successfully created and is in the "Allocated"
|
|
# state.
|
|
# 2. Concurrently create a number of VM's in the above isolated network
|
|
# 3. Wait until all VM's are running
|
|
# 4. Concurrently update the userdata of all the VM's
|
|
# 5. Wait util all updates are finished
|
|
# 6. Repeat above (5-6) x times
|
|
# 7. Check userdata in all VM's
|
|
# 8. Concurrently reset password on all VM's
|
|
# 9. Wait until all resets are finished
|
|
# 10. Verify all passwords
|
|
# 11. Concurrently delete all VM's.
|
|
# 12. Restore ConfigDrive provider state
|
|
# 13. Delete all the created objects (cleanup).
|
|
|
|
#
|
|
# 1. When ConfigDrive enabled create network
|
|
default_state = self.given_config_drive_provider_is("Enabled")
|
|
create_network = self.verify_network_creation(
|
|
offering_name="isolated_configdrive_network_offering_withoutdns",
|
|
gateway='10.1.1.1')
|
|
#
|
|
# 2. Concurrently create all VMs
|
|
self.password_enabled = self.given_template_password_enabled_is(False)
|
|
my_create_threads = []
|
|
nbr_vms = 5
|
|
for i in range(nbr_vms):
|
|
# Add VM
|
|
self.debug("+++ [Concurrency]Going to verify %d VM's, starting "
|
|
"the %d VM" % (nbr_vms, i + 1))
|
|
vm_thread = self.StartVM(self, create_network.network, i)
|
|
my_create_threads.append(vm_thread)
|
|
vm_thread.start()
|
|
#
|
|
# 3. Wait until all VM's are running
|
|
self.wait_until_done(my_create_threads, "creation")
|
|
self.assertEqual(
|
|
nbr_vms, len(my_create_threads), "Not all VM's are up")
|
|
|
|
try:
|
|
for i in range(2):
|
|
self.debug("\n+++ [Concurrency]Start update on all VM's")
|
|
#
|
|
# 5. Concurrently update all VM's
|
|
my_update_threads = self.handle_threads(my_create_threads,
|
|
self.UpdateVM, idx=i)
|
|
|
|
first = my_update_threads[0].get_timestamps()
|
|
last = my_update_threads[-1].get_timestamps()
|
|
self.debug("[Concurrency] Update report: first start %s, "
|
|
"last start %s. Duration in seconds: %s" %
|
|
(first[0].strftime("%H:%M:%S-%f"),
|
|
last[0].strftime("%H:%M:%S-%f"),
|
|
(last[0] - first[0]).total_seconds()))
|
|
self.debug("[Concurrency] Update report: first end %s, "
|
|
"last end %s. Duration in seconds: %s" %
|
|
(first[1].strftime("%H:%M:%S-%f"),
|
|
last[1].strftime("%H:%M:%S-%f"),
|
|
(last[0] - first[0]).total_seconds()))
|
|
#
|
|
# 7. Check userdata in all VM's
|
|
self.debug("\n+++ [Concurrency]Check userdata")
|
|
public_ip_1 = self.acquire_PublicIPAddress(create_network.network)
|
|
for aThread in my_update_threads:
|
|
#
|
|
# create floating ip
|
|
self.when_I_create_a_static_nat_ip_to(aThread.get_vm(),
|
|
create_network.network,
|
|
public_ip_1)
|
|
#
|
|
# verify userdata
|
|
self.debug("[Concurrency]verify userdata for vm %s"
|
|
% aThread.get_vm().name)
|
|
self.then_config_drive_is_as_expected(
|
|
aThread.get_vm(), public_ip_1)
|
|
self.delete_StaticNatRule_For_VM(public_ip_1)
|
|
#
|
|
# 8. Concurrently reset password on all VM's
|
|
self.given_template_password_enabled_is(True)
|
|
my_reset_threads = self.handle_threads(my_create_threads,
|
|
self.ResetPassword)
|
|
#
|
|
# 10. Verify the passwords
|
|
self.debug("\n+++ [Concurrency]Verify passwords on all VM's")
|
|
for aThread in my_reset_threads:
|
|
# create floating ip
|
|
self.when_I_create_a_static_nat_ip_to(aThread.get_vm(),
|
|
create_network.network,
|
|
public_ip_1)
|
|
|
|
# verify password
|
|
self.debug("[Concurrency]verify password for vm %s"
|
|
% aThread.get_vm().name)
|
|
self.then_config_drive_is_as_expected(
|
|
aThread.get_vm(), public_ip_1)
|
|
self.delete_StaticNatRule_For_VM(public_ip_1)
|
|
public_ip_1.delete(self.api_client)
|
|
|
|
self.debug("\n+++ [Concurrency]Stop all VM's")
|
|
|
|
finally:
|
|
self.given_template_password_enabled_is(self.password_enabled)
|
|
#
|
|
# 11. Concurrently delete all VM's.
|
|
self.handle_threads(my_create_threads, self.StopVM)
|
|
#
|
|
# 12. Restore ConfigDrive provider state
|
|
self.given_config_drive_provider_is(default_state)
|
|
#
|
|
# 13. Delete all the created objects (cleanup).
|
|
self.delete_Network(create_network.network)
|
|
|
|
@attr(tags=["advanced", "nuagevsp", "shared"], required_hardware="true")
|
|
def test_nuage_configdrive_shared_network(self):
|
|
"""Test Configdrive as provider for shared Networks
|
|
to provide userdata and password reset functionality
|
|
with Nuage VSP SDN plugin
|
|
"""
|
|
|
|
# 1. When ConfigDrive is disabled as provider in zone
|
|
# Verify Shared Network creation with a network offering
|
|
# which has userdata provided by ConfigDrive fails
|
|
# 2. When ConfigDrive is enabled as provider in zone
|
|
# Create a shared Network with Nuage VSP Isolated Network
|
|
# offering specifying ConfigDrive as serviceProvider
|
|
# for userdata,
|
|
# make sure no Dns is in the offering so no VR is spawned.
|
|
# check if it is successfully created and
|
|
# is in the "Allocated" state.
|
|
# 3. Deploy a VM in the created Shared network with user data,
|
|
# check if the Shared network state is changed to
|
|
# "Implemented", and the VM is successfully deployed and
|
|
# is in the "Running" state.
|
|
# Check that no VR is deployed.
|
|
# 4. SSH into the deployed VM and verify its user data in the iso
|
|
# (expected user data == actual user data).
|
|
# 5. Verify that the guest VM's password in the iso.
|
|
# 6. Reset VM password, and start the VM.
|
|
# 7. Verify that the new guest VM template is password enabled by
|
|
# checking the VM's password (password != "password").
|
|
# 8. SSH into the VM for verifying its new password
|
|
# after its password reset.
|
|
# 9. Verify various scenarios and check the data in configdriveIso
|
|
# 10. Delete all the created objects (cleanup).
|
|
|
|
if not self.isNuageInfraUnderlay:
|
|
self.skipTest(
|
|
"Configured Nuage VSP SDN platform infrastructure "
|
|
"does not support underlay networking: "
|
|
"skipping test")
|
|
|
|
self.debug("+++Testing configdrive in an shared network fails..."
|
|
"as provider configdrive is still disabled...")
|
|
self.given_config_drive_provider_is("Disabled")
|
|
shared_test_data = self.test_data["nuagevsp"]["network_all"]
|
|
shared_network = self.verify_network_creation(
|
|
offering_name="shared_nuage_network_config_drive_offering",
|
|
testdata=shared_test_data)
|
|
self.assertFalse(shared_network.success,
|
|
'Network found success = %s, expected success =%s'
|
|
% (str(shared_network.success), 'False'))
|
|
|
|
self.given_config_drive_provider_is("Enabled")
|
|
shared_network = self.verify_network_creation(
|
|
offering=shared_network.offering, testdata=shared_test_data)
|
|
self.assertTrue(shared_network.success,
|
|
'Network found success = %s, expected success = %s'
|
|
% (str(shared_network.success), 'True'))
|
|
|
|
shared_nw_1 = shared_network.network
|
|
|
|
self.validate_Network(shared_nw_1, state="Allocated")
|
|
|
|
shared_test_data2 = self.test_data["nuagevsp"]["network_all2"]
|
|
shared_network2 = self.verify_network_creation(
|
|
offering=shared_network.offering,
|
|
testdata=shared_test_data2)
|
|
self.assertTrue(shared_network2.success,
|
|
'Network found success = %s, expected success = %s'
|
|
% (str(shared_network2.success), 'True'))
|
|
|
|
shared_nw_1 = shared_network.network
|
|
shared_nw_2 = shared_network2.network
|
|
shared_nw_ids = [shared_nw_1.id, shared_nw_2.id]
|
|
self.validate_Network(shared_nw_2, state="Allocated")
|
|
|
|
self.debug("+++Test user data & password reset functionality "
|
|
"using configdrive in an Isolated network without VR")
|
|
|
|
self.given_template_password_enabled_is(True)
|
|
public_ip_ranges = PublicIpRange.list(self.api_client)
|
|
for ip_range in public_ip_ranges:
|
|
if ip_range.networkid in shared_nw_ids:
|
|
self.enable_NuageUnderlayPublicIpRange(ip_range.id)
|
|
|
|
self.debug("+++Deploy of a VM on a shared network with multiple "
|
|
"ip ranges, all should have the same value for the "
|
|
"underlay flag.")
|
|
# Add subnet of different gateway
|
|
self.debug("+++ Adding subnet of different gateway")
|
|
|
|
subnet = self.add_subnet_to_shared_network_and_verify(
|
|
shared_nw_1,
|
|
self.test_data["nuagevsp"]["publiciprange2"])
|
|
tmp_test_data = copy.deepcopy(
|
|
self.test_data["virtual_machine"])
|
|
|
|
tmp_test_data["ipaddress"] = \
|
|
self.test_data["nuagevsp"]["network_all"]["endip"]
|
|
|
|
with self.assertRaises(Exception):
|
|
self.create_VM([shared_nw_1], testdata=tmp_test_data)
|
|
|
|
self.debug("+++ In a shared network with multiple ip ranges, "
|
|
"userdata with config drive must be allowed.")
|
|
|
|
self.enable_NuageUnderlayPublicIpRange(subnet.vlan.id)
|
|
|
|
vm1 = self.when_I_deploy_a_vm_with_keypair_in([shared_nw_1])
|
|
|
|
self.then_vr_is_as_expected(shared_nw_1)
|
|
|
|
public_ip = self.get_public_shared_ip(vm1, shared_nw_1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip, metadata=True)
|
|
|
|
self.update_and_validate_userdata(vm1, "helloworld vm1", public_ip)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip)
|
|
|
|
# =====================================================================
|
|
# Test using network2 as default network
|
|
# =====================================================================
|
|
|
|
self.debug("+++ Adding a non-default nic to the VM "
|
|
"making it a multi-nic VM...")
|
|
self.plug_nic(vm1, shared_nw_2)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip, metadata=True)
|
|
|
|
self.when_I_reset_the_password(vm1)
|
|
self.update_and_validate_userdata(vm1, "hellomultinicvm1", public_ip)
|
|
|
|
self.debug("+++ Updating non-default nic as the default nic "
|
|
"of the multi-nic VM...")
|
|
self.update_default_nic(vm1, shared_nw_2)
|
|
self.stop_and_start_vm(vm1)
|
|
|
|
public_ip_2 = self.get_public_shared_ip(vm1, shared_nw_2)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip_2, metadata=True)
|
|
|
|
self.when_I_reset_the_password(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip_2)
|
|
|
|
self.update_and_validate_userdata(vm1, "hellomultinicvm1again",
|
|
public_ip_2)
|
|
|
|
self.debug("+++ Updating the default nic of the multi-nic VM, "
|
|
"deleting the non-default nic...")
|
|
self.update_default_nic(vm1, shared_nw_1)
|
|
self.stop_and_start_vm(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip, metadata=True)
|
|
|
|
self.unplug_nic(vm1, shared_nw_2)
|
|
|
|
# =====================================================================
|
|
# Another Multinic VM
|
|
# =====================================================================
|
|
|
|
multinicvm1 = self.when_I_deploy_a_vm([shared_nw_2, shared_nw_1])
|
|
public_ip_3 = self.get_public_shared_ip(multinicvm1, shared_nw_2)
|
|
self.then_config_drive_is_as_expected(
|
|
multinicvm1, public_ip_3,
|
|
metadata=True)
|
|
self.update_and_validate_userdata(multinicvm1, "hello multinicvm1",
|
|
public_ip)
|
|
self.then_config_drive_is_as_expected(multinicvm1, public_ip_3)
|
|
multinicvm1.delete(self.api_client, expunge=True)
|
|
shared_nw_2.delete(self.api_client)
|
|
|
|
# =====================================================================
|
|
|
|
self.debug("+++ Scenario: "
|
|
"update userdata and reset password after reboot")
|
|
vm1.reboot(self.api_client)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip, metadata=True)
|
|
self.update_and_validate_userdata(vm1, "hello afterboot", public_ip)
|
|
self.when_I_reset_the_password(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"update userdata and reset password after migrate")
|
|
self.migrate_VM(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip, metadata=True)
|
|
self.update_and_validate_userdata(vm1, "hello after migrate",
|
|
public_ip)
|
|
self.when_I_reset_the_password(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"update userdata and reset password after stop/start")
|
|
self.stop_and_start_vm(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip, metadata=True)
|
|
|
|
self.update_and_validate_userdata(vm1, "hello afterstopstart",
|
|
public_ip)
|
|
self.when_I_reset_the_password(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"verify config drive after delete/recover")
|
|
self.delete_and_recover_vm(vm1)
|
|
self.then_config_drive_is_as_expected(vm1, public_ip,
|
|
metadata=True)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"Start VM fails when ConfigDrive provider is disabled")
|
|
self.given_config_drive_provider_is("Disabled")
|
|
with self.assertRaises(Exception):
|
|
self.when_I_update_userdata(vm1, "hi with provider state Disabled")
|
|
self.given_config_drive_provider_is("Enabled")
|
|
|
|
self.delete(vm1, expunge=True)
|
|
|
|
# =====================================================================
|
|
self.debug("+++ Scenario: "
|
|
"Update Userdata on a VM that is not password enabled")
|
|
self.update_template(passwordenabled=False)
|
|
|
|
vm1 = self.create_VM(
|
|
[shared_nw_1],
|
|
testdata=self.test_data["virtual_machine_userdata"],
|
|
keypair=self.keypair.name)
|
|
|
|
self.update_and_validate_userdata(vm1, "This is sample data",
|
|
public_ip)
|
|
public_ip = PublicIPAddress({"ipaddress": vm1})
|
|
self.then_config_drive_is_as_expected(vm1, public_ip,
|
|
metadata=True)
|
|
|
|
self.delete(vm1, expunge=True)
|
|
self.delete(shared_nw_1)
|
|
|
|
@attr(tags=["advanced", "nuagevsp", "endurance"], required_hardware="true")
|
|
def test_nuage_configdrive_endurance(self):
|
|
""" Verify endurance of ConfigDrive userdata update
|
|
"""
|
|
# Validate the following
|
|
# 1. When ConfigDrive is enabled as provider in zone
|
|
# Create an Isolated Network with Nuage VSP Isolated Network
|
|
# offering specifying ConfigDrive as serviceProvider for userdata,
|
|
# make sure no Dns is in the offering so no VR is spawned.
|
|
# 2. create a VM in the above isolated network
|
|
# 3. Wait until VM is running
|
|
# 4. Concurrently update the userdata for the VM
|
|
# 5. Wait util all updates are finished
|
|
# 6. Check userdata in VM
|
|
# 7. Delete all the created objects (cleanup).
|
|
|
|
self.given_config_drive_provider_is("Enabled")
|
|
self.given_template_password_enabled_is(True)
|
|
self.given_a_network_offering_with_configdrive()
|
|
create_network = self.when_I_create_a_network_with_that_offering(
|
|
gateway='10.5.1.1'
|
|
)
|
|
self.then_the_network_is_successfully_created(create_network)
|
|
self.then_the_network_has(create_network, state="Allocated")
|
|
|
|
network = create_network.network
|
|
|
|
vm = self.when_I_deploy_a_vm(network, keypair=self.keypair.name)
|
|
self.then_vr_is_as_expected(network=network)
|
|
|
|
public_ip = \
|
|
self.when_I_create_a_static_nat_ip_to(vm, create_network.network)
|
|
self.then_config_drive_is_as_expected(vm, public_ip, metadata=True)
|
|
|
|
for i in range(0, 30):
|
|
self.update_and_validate_userdata(vm, 'This is sample data %s' % i,
|
|
public_ip)
|
|
|
|
if __name__ == "__main__" and __package__ is None:
|
|
__package__ = "integration.plugins.nuage"
|