Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ovirt: Cherry picks of recent fixes to devel branch #38341

Merged
merged 4 commits into from Apr 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/ansible/modules/cloud/ovirt/ovirt_cluster.py
Expand Up @@ -485,7 +485,9 @@ def build_entity(self):
name=self.param('network'),
) if self.param('network') else None,
cpu=otypes.Cpu(
architecture=self.param('cpu_arch'),
architecture=otypes.Architecture(
self.param('cpu_arch')
) if self.param('cpu_arch') else None,
type=self.param('cpu_type'),
) if (
self.param('cpu_arch') or self.param('cpu_type')
Expand Down
102 changes: 83 additions & 19 deletions lib/ansible/modules/cloud/ovirt/ovirt_host_networks.py
Expand Up @@ -57,7 +57,7 @@
- "C(name) - Name of the logical network to be assigned to bond or interface."
- "C(boot_protocol) - Boot protocol one of the I(none), I(static) or I(dhcp)."
- "C(address) - IP address in case of I(static) boot protocol is used."
- "C(prefix) - Routing prefix in case of I(static) boot protocol is used."
- "C(netmask) - Subnet mask in case of I(static) boot protocol is used."
- "C(gateway) - Gateway in case of I(static) boot protocol is used."
- "C(version) - IP version. Either v4 or v6. Default is v4."
labels:
Expand Down Expand Up @@ -92,7 +92,7 @@
- name: myvlan
boot_protocol: static
address: 1.2.3.4
prefix: 24
netmask: 255.255.255.0
gateway: 1.2.3.4
version: v4

Expand Down Expand Up @@ -160,8 +160,56 @@
)


def get_mode_type(mode_number):
"""
Adaptive transmit load balancing (balance-tlb): mode=1 miimon=100
Dynamic link aggregation (802.3ad): mode=2 miimon=100
Load balance (balance-xor): mode=3 miimon=100
Active-Backup: mode=4 miimon=100 xmit_hash_policy=2
"""
options = []
if mode_number is None:
return options

def get_type_name(mode_number):
"""
We need to maintain this type strings, for the __compare_options method,
for easier comparision.
"""
return [
'Active-Backup',
'Load balance (balance-xor)',
None,
'Dynamic link aggregation (802.3ad)',
][mode_number]

try:
mode_number = int(mode_number)
if mode_number >= 1 and mode_number <= 4:
if mode_number == 4:
options.append(otypes.Option(name='xmit_hash_policy', value='2'))

options.append(otypes.Option(name='miimon', value='100'))
options.append(
otypes.Option(
name='mode',
type=get_type_name(mode_number - 1),
value=str(mode_number)
)
)
else:
options.append(otypes.Option(name='mode', value=str(mode_number)))
except ValueError:
raise Exception("Bond mode must be a number.")

return options


class HostNetworksModule(BaseModule):

def __compare_options(self, new_options, old_options):
return sorted(get_dict_of_struct(opt) for opt in new_options) != sorted(get_dict_of_struct(opt) for opt in old_options)

def build_entity(self):
return otypes.Host()

Expand All @@ -180,8 +228,8 @@ def update_address(self, attachments_service, attachment, network):
if not equal(network.get('gateway'), ip.ip.gateway):
ip.ip.gateway = network.get('gateway')
changed = True
if not equal(network.get('prefix'), sum([bin(int(x)).count('1') for x in ip.ip.netmask.split('.')]) if ip.ip.netmask else None):
ip.ip.netmask = str(network.get('prefix'))
if not equal(network.get('netmask'), ip.ip.netmask):
ip.ip.netmask = network.get('netmask')
changed = True

if changed:
Expand All @@ -202,17 +250,16 @@ def has_update(self, nic_service):

# Check if bond configuration should be updated:
if bond:
update = not (
equal(str(bond.get('mode')), nic.bonding.options[0].value) and
equal(
sorted(bond.get('interfaces')) if bond.get('interfaces') else None,
sorted(get_link_name(self._connection, s) for s in nic.bonding.slaves)
)
update = self.__compare_options(get_mode_type(bond.get('mode')), getattr(nic.bonding, 'options', []))
update = update or not equal(
sorted(bond.get('interfaces')) if bond.get('interfaces') else None,
sorted(get_link_name(self._connection, s) for s in nic.bonding.slaves)
)

# Check if labels need to be updated on interface/bond:
if labels:
net_labels = nic_service.network_labels_service().list()
# If any lables which user passed aren't assigned, relabel the interface:
if sorted(labels) != sorted([lbl.id for lbl in net_labels]):
return True

Expand Down Expand Up @@ -283,29 +330,46 @@ def main():
labels = module.params['labels']
nic_name = bond.get('name') if bond else module.params['interface']

nics_service = hosts_service.host_service(host.id).nics_service()
host_service = hosts_service.host_service(host.id)
nics_service = host_service.nics_service()
nic = search_by_name(nics_service, nic_name)

network_names = [network['name'] for network in networks or []]
state = module.params['state']
if (
state == 'present' and
(nic is None or host_networks_module.has_update(nics_service.service(nic.id)))
):
# Remove networks which are attached to different interface then user want:
attachments_service = host_service.network_attachments_service()

# Append attachment ID to network if needs update:
for a in attachments_service.list():
current_network_name = get_link_name(connection, a.network)
if current_network_name in network_names:
for n in networks:
if n['name'] == current_network_name:
n['id'] = a.id

# Check if we have to break some bonds:
removed_bonds = []
if nic is not None:
for host_nic in nics_service.list():
if host_nic.bonding and nic.id in [slave.id for slave in host_nic.bonding.slaves]:
removed_bonds.append(otypes.HostNic(id=host_nic.id))

# Assign the networks:
host_networks_module.action(
entity=host,
action='setup_networks',
post_action=host_networks_module._action_save_configuration,
check_connectivity=module.params['check'],
removed_bonds=removed_bonds if removed_bonds else None,
modified_bonds=[
otypes.HostNic(
name=bond.get('name'),
bonding=otypes.Bonding(
options=[
otypes.Option(
name="mode",
value=str(bond.get('mode')),
)
],
options=get_mode_type(bond.get('mode')),
slaves=[
otypes.HostNic(name=i) for i in bond.get('interfaces', [])
],
Expand All @@ -322,6 +386,7 @@ def main():
] if labels else None,
modified_network_attachments=[
otypes.NetworkAttachment(
id=network.get('id'),
network=otypes.Network(
name=network['name']
) if network['name'] else None,
Expand Down Expand Up @@ -353,7 +418,6 @@ def main():
attachments = attachments_service.list()
attached_labels = set([str(lbl.id) for lbl in nic_service.network_labels_service().list()])
if networks:
network_names = [network['name'] for network in networks]
attachments = [
attachment for attachment in attachments
if get_link_name(connection, attachment.network) in network_names
Expand All @@ -374,7 +438,7 @@ def main():
] if bond else None,
removed_labels=[
otypes.NetworkLabel(id=str(name)) for name in labels
],
] if labels else None,
removed_network_attachments=list(attachments),
)

Expand Down
4 changes: 2 additions & 2 deletions lib/ansible/modules/cloud/ovirt/ovirt_hosts.py
Expand Up @@ -532,7 +532,7 @@ def main():
action='fence',
action_condition=lambda h: h.status == hoststate.DOWN,
wait_condition=lambda h: h.status in [hoststate.UP, hoststate.MAINTENANCE],
fail_condition=failed_state,
fail_condition=hosts_module.failed_state_after_reinstall,
fence_type='start',
)
elif state == 'stopped':
Expand All @@ -553,7 +553,7 @@ def main():
ret = hosts_module.action(
action='fence',
wait_condition=lambda h: h.status == hoststate.UP,
fail_condition=failed_state,
fail_condition=hosts_module.failed_state_after_reinstall,
fence_type='restart',
)
elif state == 'reinstalled':
Expand Down