Skip to content

Commit 8d08ef9

Browse files
committed
Adding ipv6 support
1 parent dc6490c commit 8d08ef9

File tree

10 files changed

+108
-18
lines changed

10 files changed

+108
-18
lines changed

cloudshell/cp/vcenter/actions/vm_details.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ def _prepare_vm_network_data(
9191

9292
network_data = [
9393
VmDetailsProperty(key="IP", value=vnic_ip),
94+
VmDetailsProperty(key="IPv6", value=vnic_ip),
9495
VmDetailsProperty(key="MAC Address", value=vnic.mac_address),
9596
VmDetailsProperty(key="Network Adapter", value=vnic.name),
9697
VmDetailsProperty(key="Port Group Name", value=network.name),
@@ -113,10 +114,19 @@ def _get_primary_ip(self, app_model, vm) -> str | None:
113114
with suppress(VMIPNotFoundException):
114115
if isinstance(app_model, StaticVCenterDeployedApp):
115116
# try to get VM IP without waiting
116-
primary_ip = self.get_vm_ip(vm, timeout=0)
117+
primary_ip = self.get_vm_ip(
118+
vm=vm,
119+
timeout=0,
120+
ip_protocol_version=app_model.ip_protocol_version
121+
)
117122
elif vm.power_state is PowerState.ON:
118123
# try to get VM IP without waiting, use IP regex if present
119-
primary_ip = self.get_vm_ip(vm, ip_regex=app_model.ip_regex, timeout=0)
124+
primary_ip = self.get_vm_ip(
125+
vm=vm,
126+
ip_regex=app_model.ip_regex,
127+
timeout=0,
128+
ip_protocol_version=app_model.ip_protocol_version
129+
)
120130
return primary_ip
121131

122132
@staticmethod

cloudshell/cp/vcenter/actions/vm_network.py

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from datetime import datetime, timedelta
88
from typing import TYPE_CHECKING
99

10+
from cloudshell.cp.vcenter.constants import IPProtocol
1011
from cloudshell.cp.vcenter.exceptions import VMIPNotFoundException
1112
from cloudshell.cp.vcenter.handlers.network_handler import NetworkHandler
1213
from cloudshell.cp.vcenter.handlers.vm_handler import VmHandler
@@ -41,20 +42,33 @@ def _find_vm_ip(
4142
vm: VmHandler,
4243
skip_networks: list[NetworkHandler],
4344
is_ip_pass_regex: callable[[str | None], bool],
45+
ip_protocol_version: str = IPProtocol.IPv4,
4446
) -> str | None:
45-
logger.debug(f"Searching for the IPv4 address of the {vm}")
47+
logger.debug(f"Searching for the IP address of the {vm}")
4648
ip = None
47-
primary_ip = vm.primary_ipv4
48-
if is_ip_pass_regex(primary_ip):
49-
ip = primary_ip
50-
logger.debug(f"Use primary IPv4 address of the {vm}")
49+
50+
if ip_protocol_version == IPProtocol.IPv4:
51+
if is_ip_pass_regex(vm.primary_ipv4):
52+
ip = vm.primary_ipv4
53+
logger.debug(f"Use primary IPv4 address of the {vm}")
54+
else:
55+
for vnic in vm.vnics:
56+
logger.debug(f"Checking {vnic} with ip {vnic.ipv4}")
57+
if vnic.network not in skip_networks and is_ip_pass_regex(vnic.ipv4):
58+
logger.debug(f"Found IP {vnic.ipv4} on {vnic}")
59+
ip = vnic.ipv4
60+
break
5161
else:
52-
for vnic in vm.vnics:
53-
logger.debug(f"Checking {vnic} with ip {vnic.ipv4}")
54-
if vnic.network not in skip_networks and is_ip_pass_regex(vnic.ipv4):
55-
logger.debug(f"Found IP {vnic.ipv4} on {vnic}")
56-
ip = vnic.ipv4
57-
break
62+
if is_ip_pass_regex(vm.primary_ipv6):
63+
ip = vm.primary_ipv6
64+
logger.debug(f"Use primary IPv6 address of the {vm}")
65+
else:
66+
for vnic in vm.vnics:
67+
logger.debug(f"Checking {vnic} with ip {vnic.ipv6}")
68+
if vnic.network not in skip_networks and is_ip_pass_regex(vnic.ipv6):
69+
logger.debug(f"Found IP {vnic.ipv6} on {vnic}")
70+
ip = vnic.ipv6
71+
break
5872
return ip
5973

6074
def get_vm_ip(
@@ -63,6 +77,7 @@ def get_vm_ip(
6377
ip_regex: str | None = None,
6478
timeout: int = 0,
6579
skip_networks: list[NetworkHandler] | None = None,
80+
ip_protocol_version: str = IPProtocol.IPv4
6681
) -> str:
6782
logger.info(f"Getting IP address for the VM {vm.name} from the vCenter")
6883
timeout_time = datetime.now() + timedelta(seconds=timeout)
@@ -71,7 +86,12 @@ def get_vm_ip(
7186

7287
while True:
7388
with self._cancellation_manager:
74-
ip = self._find_vm_ip(vm, skip_networks, is_ip_pass_regex)
89+
ip = self._find_vm_ip(
90+
vm=vm,
91+
skip_networks=skip_networks,
92+
is_ip_pass_regex=is_ip_pass_regex,
93+
ip_protocol_version=ip_protocol_version
94+
)
7595
if ip:
7696
break
7797
if datetime.now() > timeout_time:

cloudshell/cp/vcenter/constants.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from enum import Enum
2+
13
SHELL_NAME = "VMware vCenter Cloud Provider 2G"
24
STATIC_SHELL_NAME = "Generic Static vCenter VM 2G"
35

@@ -7,3 +9,8 @@
79
VM_FROM_IMAGE_DEPLOYMENT_PATH = f"{SHELL_NAME}.vCenter VM From Image 2G"
810

911
DEPLOYED_APPS_FOLDER = "Deployed Apps"
12+
13+
14+
class IPProtocol(Enum):
15+
IPv4 = "ipv4"
16+
IPv6 = "ipv6"

cloudshell/cp/vcenter/flows/refresh_ip.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,18 @@ def refresh_ip(
2626

2727
actions = VMNetworkActions(resource_conf, cancellation_manager)
2828
if isinstance(deployed_app, StaticVCenterDeployedApp):
29-
ip = actions.get_vm_ip(vm)
29+
ip = actions.get_vm_ip(
30+
vm=vm,
31+
ip_protocol_version=deployed_app.ip_protocol_version
32+
)
3033
else:
3134
default_net = dc.get_network(resource_conf.holding_network)
3235
ip = actions.get_vm_ip(
3336
vm,
3437
ip_regex=deployed_app.ip_regex,
3538
timeout=deployed_app.refresh_ip_timeout,
3639
skip_networks=[default_net],
40+
ip_protocol_version=deployed_app.ip_protocol_version
3741
)
3842
if ip != deployed_app.private_ip:
3943
deployed_app.update_private_ip(deployed_app.name, ip)

cloudshell/cp/vcenter/handlers/custom_spec_handler.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ def _set_network_params(self, networks: NetworksList, num_vm_nics: int):
9090
network_adapter.ip = vim.vm.customization.FixedIp(
9191
ipAddress=network.ipv4_address
9292
)
93+
94+
if network.ipv6_address is not Empty:
95+
network_adapter.ip = vim.vm.customization.FixedIp(
96+
ipAddress=network.ipv6_address
97+
)
98+
9399
if network.subnet_mask is not Empty:
94100
network_adapter.subnetMask = network.subnet_mask
95101

cloudshell/cp/vcenter/handlers/vm_handler.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
VnicWithMacNotFound,
5050
)
5151
from cloudshell.cp.vcenter.utils.connectivity_helpers import is_correct_vnic
52-
from cloudshell.cp.vcenter.utils.network_helpers import is_ipv4
52+
from cloudshell.cp.vcenter.utils.network_helpers import is_ipv4, is_ipv6
5353
from cloudshell.cp.vcenter.utils.units_converter import BASE_10
5454

5555
logger = logging.getLogger(__name__)
@@ -151,6 +151,11 @@ def primary_ipv4(self) -> str | None:
151151
ip = self._vc_obj.guest.ipAddress
152152
return ip if is_ipv4(ip) else None
153153

154+
@property
155+
def primary_ipv6(self) -> str | None:
156+
ip = self._vc_obj.guest.ipAddress
157+
return ip if is_ipv6(ip) else None
158+
154159
@property
155160
def networks(self) -> list[NetworkHandler | DVPortGroupHandler]:
156161
return [get_network_handler(net, self.si) for net in self._vc_obj.network]

cloudshell/cp/vcenter/handlers/vnic_handler.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
NetworkHandler,
1616
)
1717
from cloudshell.cp.vcenter.handlers.virtual_device_handler import VirtualDevice
18-
from cloudshell.cp.vcenter.utils.network_helpers import is_ipv4
18+
from cloudshell.cp.vcenter.utils.network_helpers import is_ipv4, is_ipv6
1919

2020
if TYPE_CHECKING:
2121
from cloudshell.cp.vcenter.handlers.vm_handler import VmHandler
@@ -97,6 +97,12 @@ def ipv4(self) -> str | None:
9797
ipv4 = next(filter(is_ipv4, ips), None)
9898
return ipv4
9999

100+
@property
101+
def ipv6(self) -> str | None:
102+
ips = self.vm.get_ip_addresses_by_vnic(self)
103+
ipv6 = next(filter(is_ipv6, ips), None)
104+
return ipv6
105+
100106
def connect(self, network: NetworkHandler | DVPortGroupHandler) -> None:
101107
if isinstance(network, NetworkHandler):
102108
nic_spec = self._create_spec_for_connecting_network(network)

cloudshell/cp/vcenter/models/deployed_app.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ class BaseVCenterDeployedApp(DeployedApp):
4545
autogenerated_name = ResourceBoolAttrRODeploymentPath(ATTR_NAMES.autogenerated_name)
4646
copy_source_uuid = ResourceBoolAttrRODeploymentPath(ATTR_NAMES.copy_source_uuid)
4747

48+
@property
49+
def ip_protocol_version(self):
50+
ip_protocol = self.attributes.get(f"{self._namespace}IP Protocol Version")
51+
if ip_protocol and "4" in ip_protocol:
52+
ip_protocol = constants.IPProtocol.IPv4
53+
elif ip_protocol and "6" in ip_protocol:
54+
ip_protocol = constants.IPProtocol.IPv6
55+
else:
56+
ip_protocol = constants.IPProtocol.IPv4
57+
58+
return ip_protocol
59+
4860

4961
class VMFromTemplateDeployedApp(BaseVCenterDeployedApp):
5062
ATTR_NAMES = VCenterVMFromTemplateDeploymentAppAttributeNames
@@ -86,6 +98,16 @@ class StaticVCenterDeployedApp(DeployedApp):
8698
ATTR_NAMES.vcenter_resource_name
8799
)
88100

101+
@property
102+
def ip_protocol_version(self):
103+
ip_protocol = self.attributes.get(f"{self._namespace}IP Protocol Version")
104+
if ip_protocol and "6" in ip_protocol:
105+
ip_protocol = constants.IPProtocol.IPv6
106+
else:
107+
ip_protocol = constants.IPProtocol.IPv4
108+
109+
return ip_protocol
110+
89111

90112
class VCenterGetVMDetailsRequestActions(GetVMDetailsRequestActions):
91113
deployed_app: BaseVCenterDeployedApp

cloudshell/cp/vcenter/utils/network_helpers.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,13 @@ def is_ipv4(ip: str | None) -> bool:
1111
else:
1212
result = True
1313
return result
14+
15+
16+
def is_ipv6(ip: str | None) -> bool:
17+
try:
18+
ipaddress.IPv6Address(ip)
19+
except ipaddress.AddressValueError:
20+
result = False
21+
else:
22+
result = True
23+
return result

version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7.0.0
1+
7.0.1

0 commit comments

Comments
 (0)