Skip to content

Commit f498946

Browse files
committed
Merge pull request #117 from QualiSystems/feature/borismod_40_save_vnic
Feature/borismod 40 save vnic
2 parents 4dacc1a + 31f1e35 commit f498946

19 files changed

Lines changed: 171 additions & 105 deletions

File tree

common/utilites/command_result.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from re import search
2+
3+
COMMAND_RESULT_PREFIX = "command_json_result="
4+
COMMAND_RESULT_POSTFIX = "=command_json_result_end"
5+
6+
def get_result_from_command_output(output):
7+
8+
match = search(COMMAND_RESULT_PREFIX + '(?P<result>.*)' + COMMAND_RESULT_POSTFIX, output)
9+
if not match:
10+
return None
11+
return match.group('result')
12+
13+
def set_command_result(output):
14+
print COMMAND_RESULT_PREFIX + str(output) + COMMAND_RESULT_POSTFIX

common/wrappers/command_wrapper.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
DISCONNCTING_VCENERT = 'disconnecting from vcenter: {0}'
2-
COMMAND_ERROR = 'error has occurred while executing command: {0} error: {1}'
2+
COMMAND_ERROR = 'error has occurred while executing command: {0}'
33
DEBUG_COMMAND_RESULT = 'finished executing with the result: {0}'
44
FINISHED_EXECUTING_COMMAND = 'finished executing command: {0}'
55
DEBUG_COMMAND_PARAMS = 'command params: {0}'
@@ -66,7 +66,8 @@ def execute_command_with_connection(self, connection_details, command, *args):
6666

6767
return results
6868
except Exception as e:
69-
logger.error(COMMAND_ERROR.format(command_name, e))
69+
logger.error(COMMAND_ERROR.format(command_name))
70+
logger.exception(e)
7071
raise
7172
finally:
7273
if si:

deployed_app_service/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def main():
1515

1616
vlan_id = helpers.get_user_param('VLAN_ID')
1717
if not vlan_id:
18-
raise ValueError('VLAN_ID is missoing')
18+
raise ValueError('VLAN_ID is missing')
1919

2020
deployed_app_service.connect(vlan_spec_type, vlan_id)
2121

deployed_app_service/connect.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import qualipy.scripts.cloudshell_scripts_helpers as helpers
22
from qualipy.api.cloudshell_api import InputNameValue
3+
from common.utilites.command_result import get_result_from_command_output, set_command_result
4+
from common.logger import getLogger
35

6+
_logger = getLogger('DeployedAppService')
47

58
class DeployedAppService(object):
69
def __init__(self, resource_model_parser):
@@ -28,11 +31,18 @@ def connect(self, access_mode, virtual_network):
2831
def execute_command_on_vcenter_resource(access_mode, generic_deployed_app_resource_model, virtual_network):
2932
session = helpers.get_api_session()
3033
reservation_id = helpers.get_reservation_context_details().id
31-
session.ExecuteCommand(reservation_id, generic_deployed_app_resource_model.cloud_provider,
34+
35+
_logger.debug('Executing Connect VM command on ' + generic_deployed_app_resource_model.cloud_provider)
36+
37+
command_result = session.ExecuteCommand(reservation_id, generic_deployed_app_resource_model.cloud_provider,
3238
'Resource',
3339
'Connect VM',
3440
[InputNameValue('COMMAND', "connect"),
3541
InputNameValue('VLAN_ID', virtual_network),
3642
InputNameValue('VLAN_SPEC_TYPE', access_mode),
3743
InputNameValue('VM_UUID', generic_deployed_app_resource_model.vm_uuid)],
3844
True)
45+
46+
result = get_result_from_command_output(command_result.Output)
47+
_logger.debug('Transferring result to the caller ' + result)
48+
set_command_result(result)

environment_scripts/connect_all.py

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1+
import re
2+
13
import qualipy.scripts.cloudshell_scripts_helpers as helpers
2-
from qualipy.api.cloudshell_api import InputNameValue
3-
from common.utilites.common_utils import first_or_default
4+
from qualipy.api.cloudshell_api import InputNameValue, AttributeNameValue
5+
from common.utilites.command_result import get_result_from_command_output
46

5-
from common.model_factory import ResourceModelParser
7+
from common.logger.service import getLogger
8+
_logger = getLogger('EnvironmentConnector')
69

10+
VIRTUAL_NETWORK_ATTRIBUTE = 'Virtual Network'
11+
ACCESS_MODE_ATTRIBUTE = 'Access Mode'
712

8-
class EnvironmentConnector(object):
913

14+
class EnvironmentConnector(object):
1015
def connect_all(self):
1116
"""
1217
Connects all the VLAN Auto services to all the Deployed Apps in the same Environment
@@ -26,26 +31,39 @@ def connect_all(self):
2631

2732
for vlan_service in vlan_services:
2833

29-
if not len(vlan_service.Attributes):
30-
raise ValueError('No attributes on service {0}'.format(vlan_service.ServiceName))
34+
_logger.debug('Connecting \'{0}\' '.format(vlan_service.ServiceName))
3135

32-
access_mode = self._get_attribute(vlan_service.Attributes, 'Access Mode')
33-
virtual_network = self._get_attribute(vlan_service.Attributes, 'Virtual Network')
36+
access_mode = self._get_attribute(vlan_service.Attributes, ACCESS_MODE_ATTRIBUTE)
37+
virtual_network = self._get_attribute(vlan_service.Attributes, VIRTUAL_NETWORK_ATTRIBUTE)
3438

3539
# Get Deployed App connected to VLAN Auto service
3640
connected_resources = self._get_connected_resources(connectors, vlan_service)
3741

3842
if not connected_resources:
3943
continue
4044

45+
if not virtual_network or virtual_network == '':
46+
47+
_logger.debug('Executing Auto Resolve Vlan on \'{0}\''.format(vlan_service.ServiceName))
48+
49+
command_result = session.ExecuteCommand(reservation_id, vlan_service.ServiceName, 'Service',
50+
'Auto Resolve Vlan', [], True)
51+
52+
virtual_network = get_result_from_command_output(command_result.Output)
53+
54+
_logger.debug('Auto Resolve Vlan returned Virtual Network \'{0}\''.format(virtual_network))
55+
56+
if not virtual_network or virtual_network == '':
57+
raise ValueError('Auto Resolve Vlan command did not return Virtual Network')
58+
4159
for connected_resource in connected_resources:
4260
self._execute_connect_command_on_connected_resource(access_mode, connected_resource, reservation_id,
43-
session, virtual_network)
61+
session, virtual_network, vlan_service.ServiceName)
4462

4563
@staticmethod
4664
def _get_attribute(attributes, attribute_name):
4765
attribute = next(item for item in attributes if item.Name == attribute_name)
48-
if not attribute or not attribute.Value:
66+
if not attribute:
4967
raise ValueError('Attribute {0} is missing'.format(attribute_name))
5068
return attribute.Value
5169

@@ -57,16 +75,32 @@ def _get_connectors(reservation_details):
5775
@staticmethod
5876
def _get_vlan_auto_services(reservation_details):
5977
vlan_services = [service for service in reservation_details.ReservationDescription.Services
60-
if service.ServiceName == 'VLAN Auto']
78+
if VIRTUAL_NETWORK_ATTRIBUTE in [attr.Name for attr in service.Attributes]]
6179
return vlan_services
6280

6381
@staticmethod
6482
def _execute_connect_command_on_connected_resource(access_mode, connected_resource, reservation_id, session,
65-
virtual_network):
66-
session.ExecuteCommand(reservation_id, connected_resource, 'Resource', 'Connect',
67-
[InputNameValue('VLAN_ID', virtual_network),
68-
InputNameValue('VLAN_SPEC_TYPE', access_mode)],
69-
True)
83+
virtual_network, vlan_service_name):
84+
85+
_logger.debug('Executing Connect command on: ' + connected_resource)
86+
87+
command_result = session.ExecuteCommand(reservation_id, connected_resource, 'Resource', 'Connect',
88+
[InputNameValue('VLAN_ID', virtual_network),
89+
InputNameValue('VLAN_SPEC_TYPE', access_mode)], True)
90+
91+
result = get_result_from_command_output(command_result.Output)
92+
93+
if not result:
94+
_logger.debug('Connect command did not return any result')
95+
return
96+
97+
mac_address = result.replace('[\'', '').replace('\']', '')
98+
_logger.debug('Setting Target Interface to: ' + mac_address)
99+
100+
session.SetConnectorAttributes(reservation_id,
101+
connected_resource,
102+
vlan_service_name,
103+
[AttributeNameValue('Target Interface', mac_address)])
70104

71105
@staticmethod
72106
def _get_connected_resources(connectors, vlan_service):

integration/integration_commands/integration_test_connect.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
from vCenterShell.network.vlan.factory import VlanSpecFactory
1313
from vCenterShell.network.vlan.range_parser import VLanIdRangeParser
1414
from vCenterShell.network.vnic.vnic_service import VNicService
15-
from vCenterShell.network.vnic.vnic_updater import VnicUpdater
1615
from vCenterShell.vm.dvswitch_connector import VmNetworkMapping, VirtualSwitchToMachineConnector
1716
from vCenterShell.vm.portgroup_configurer import VirtualMachinePortGroupConfigurer
1817
from vCenterShell.vm.vnic_to_network_mapper import VnicToNetworkMapper

integration/integration_commands/integration_test_vnic_updater.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,47 @@
1+
import os
12
from unittest import TestCase
23

34
from pyVim.connect import SmartConnect, Disconnect
45

56
from common.vcenter.vmomi_service import pyVmomiService
67
from tests.utils.testing_credentials import TestCredentials
7-
from vCenterShell.network.vnic.vnic_updater import VnicUpdater
8+
from vCenterShell.bootstrap import Bootstrapper
89
import qualipy.scripts.cloudshell_scripts_helpers as helpers
9-
import qualipy.scripts.cloudshell_dev_helpers as dev_helpers
10+
from pyVmomi import vim
1011

1112
class VirtualSwitchToMachineCommandIntegrationTest(TestCase):
1213

14+
def integration_test(self):
15+
16+
py_vmomi_service = pyVmomiService(SmartConnect, Disconnect)
17+
cred = TestCredentials()
18+
si = py_vmomi_service.connect(cred.host, cred.username, cred.password, cred.port)
19+
vm = py_vmomi_service.find_vm_by_name(si, 'QualiSB/Alex', 'Ubuntu_a287f573')
20+
21+
os.environ['VM_UUID'] = vm.config.uuid
22+
os.environ['VLAN_ID'] = '25'
23+
os.environ['VLAN_SPEC_TYPE'] = 'Access'
24+
25+
bootstrapper = Bootstrapper()
26+
executer_service = bootstrapper.get_command_executer_service()
27+
executer_service.connect()
28+
1329
def integration_test_update_vnics(self):
1430

15-
dev_helpers.attach_to_cloudshell_as("admin", "admin", "Global", "4571b4fe-be5d-4556-aed9-54c91b9b1bb1")
31+
32+
dev_helpers.attach_to_cloudshell_as("admin", "admin", "Global", "1205e711-edf7-4b12-8a5e-e0ff53768ce7")
1633
details = helpers.get_reservation_context_details()
1734
py_vmomi_service = pyVmomiService(SmartConnect, Disconnect)
1835
cred = TestCredentials()
1936
si = py_vmomi_service.connect(cred.host, cred.username, cred.password, cred.port)
37+
vm = py_vmomi_service.find_vm_by_name(si, 'QualiSB/Alex', 'Ubuntu_a287f573')
38+
39+
nics = [x for x in vm.config.hardware.device
40+
if isinstance(x, vim.vm.device.VirtualEthernetCard)]
41+
42+
for nic in nics:
43+
network_name = nic.backing.network.name
44+
mac_address = nic.macAddress
45+
46+
print network_name + mac_address
2047

21-
vnic_updater = VnicUpdater(helpers)

tests/test_commands/test_connect_vm.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from unittest import TestCase
2-
3-
from mock import Mock
4-
2+
from mock import Mock, create_autospec
53
from common.logger.service import LoggingService
64
from vCenterShell.commands.connect_dvswitch import VirtualSwitchConnectCommand
75
from vCenterShell.vm.dvswitch_connector import VmNetworkMapping
6+
from vCenterShell.vm.portgroup_configurer import VNicDeviceMapper
7+
from pyVmomi import vim
88

99

1010
class TestVirtualSwitchToMachineDisconnectCommand(TestCase):
@@ -25,8 +25,13 @@ def setUp(self):
2525
self.vcenter_context.default_dvswitch_path = 'default_dvswitch_path'
2626
self.vcenter_context.default_dvswitch_name = 'default_dvswitch_name'
2727
self.vcenter_context.default_port_group_path = 'default_port_group_path'
28+
29+
vnic_device_mapper = create_autospec(spec=VNicDeviceMapper)
30+
vnic_device_mapper.vnic = create_autospec(spec=vim.vm.device.VirtualEthernetCard)
31+
vnic_device_mapper.vnic.macAddress = 'AA-BB'
32+
2833
self.dv_connector = Mock()
29-
self.dv_connector.connect_by_mapping = Mock(return_value=True)
34+
self.dv_connector.connect_by_mapping = Mock(return_value=[vnic_device_mapper])
3035
self.dv_port_name_gen = Mock()
3136
self.vlan_spec_factory = Mock()
3237
self.vlan_id_range_parser = Mock()
@@ -37,22 +42,23 @@ def setUp(self):
3742
def test_connect_vnic_to_network(self):
3843
# arrange
3944
connect_command = VirtualSwitchConnectCommand(self.pv_service, self.dv_connector, self.dv_port_name_gen,
40-
self.vlan_spec_factory, self.vlan_id_range_parser, Mock(), Mock())
45+
self.vlan_spec_factory, self.vlan_id_range_parser, Mock())
4146
mapping = VmNetworkMapping()
4247
mapping.vnic_name = 'name'
4348
mapping.vlan_id = 'vlan_id'
4449
mapping.vlan_spec = 'trunc'
4550
mapping.dv_port_name = 'port_name'
4651

4752
# act
48-
connect_command.connect_to_networks(self.si, self.vm_uuid, [mapping], 'default_network')
53+
mac_addresses = connect_command.connect_to_networks(self.si, self.vm_uuid, [mapping], 'default_network')
4954

5055
mapping.dv_switch_path = self.vcenter_context.default_dvswitch_path
5156
mapping.dv_switch_name = self.vcenter_context.default_dvswitch_name
5257
mapping.port_group_path = self.vcenter_context.default_port_group_path
58+
5359
# assert
5460
self.assertTrue(self.vlan_id_range_parser.parse_vlan_id.called_with(self.vlan_id))
5561
self.assertTrue(self.dv_port_name_gen.generate_port_group_name.called_with(self.vlan_id))
5662
self.assertTrue(self.vlan_spec_factory.get_vlan_spec.called_with(self.spec_type))
57-
5863
self.assertTrue(self.dv_connector.connect_by_mapping.called_with(self.si, self.vm, [mapping]))
64+
self.assertSequenceEqual(mac_addresses, ['AA-BB'])
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from unittest import TestCase
2+
from common.utilites.command_result import get_result_from_command_output
3+
4+
5+
class TestCommandResult(TestCase):
6+
7+
def test_command_result_with_result(self):
8+
result = get_result_from_command_output('command_json_result=MY RESULT=command_json_result_end')
9+
self.assertEqual(result, 'MY RESULT')
10+
11+
def test_command_result_empty(self):
12+
result = get_result_from_command_output('')
13+
self.assertEqual(result, None)

tests/test_network/test_dvswitch/test_connector.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,11 @@ def test_map_vnc(self):
9494
self.connector.connect_and_get_vm = Mock(return_value=(1, 1,))
9595

9696
res = self.connector.connect_by_mapping(self.si, self.vm, [], 'default_network')
97-
self.assertIsNone(res)
97+
self.assertEqual(res, 'OK')
9898
res = self.connector.connect_by_mapping(self.si, self.vm, [], None)
99-
#self.assertEqual(res, 'OK')
100-
self.assertIsNone(res)
99+
self.assertEqual(res, 'OK')
101100

102101
res = self.connector.connect_by_mapping(self.si, self.vm, mapp, 'default_network')
103-
self.assertIsNone(res)
102+
self.assertEqual(res, 'OK')
104103
res = self.connector.connect_by_mapping(self.si, self.vm, mapp, None)
105-
#self.assertEqual(res, 'OK')
106-
self.assertIsNone(res)
104+
self.assertEqual(res, 'OK')

0 commit comments

Comments
 (0)