VMware: Updates the DRS rule without deletion (#57119)

* The DRS rule will be updated if any changes in the configuration without deleting the existing rule.
The rule itself is updated by the given configuration.
* Lint errors fixed
* VMware: update vmware_vm_vm_drs_rule testcases
This commit is contained in:
Sunil Raj 2019-07-05 17:00:05 +05:30 committed by Abhijeet Kasurde
parent 2fb06650a7
commit 641f7c4ae3
2 changed files with 152 additions and 29 deletions

View file

@ -62,7 +62,7 @@ options:
state:
description:
- If set to C(present), then the DRS rule is created if not present.
- If set to C(present), then the DRS rule is deleted and created if present already.
- If set to C(present), then the DRS rule is already present, it updates to the given configurations.
- If set to C(absent), then the DRS rule is deleted if present.
required: False
default: present
@ -94,11 +94,11 @@ EXAMPLES = r'''
password: "{{ esxi_password }}"
cluster_name: "{{ cluster_name }}"
validate_certs: no
enabled: True
vms:
- vm1
- vm2
drs_rule_name: vm1-vm2-affinity-rule-001
enabled: True
mandatory: True
affinity_rule: False
delegate_to: localhost
@ -169,7 +169,7 @@ class VmwareDrs(PyVmomi):
# Getter
def get_all_vms_info(self, vms_list=None):
"""
Function to get all VM objects using name from given cluster
Get all VM objects using name from given cluster
Args:
vms_list: List of VM names
@ -192,7 +192,7 @@ class VmwareDrs(PyVmomi):
def get_rule_key_by_name(self, cluster_obj=None, rule_name=None):
"""
Function to get a specific DRS rule key by name
Get a specific DRS rule key by name
Args:
rule_name: Name of rule
cluster_obj: Cluster managed object
@ -213,7 +213,7 @@ class VmwareDrs(PyVmomi):
@staticmethod
def normalize_rule_spec(rule_obj=None):
"""
Function to return human readable rule spec
Return human readable rule spec
Args:
rule_obj: Rule managed object
@ -234,29 +234,26 @@ class VmwareDrs(PyVmomi):
# Create
def create(self):
"""
Function to create a DRS rule if rule does not exist
Create a DRS rule if rule does not exist
"""
rule_obj = self.get_rule_key_by_name(rule_name=self.rule_name)
if rule_obj is not None:
# Rule already exists, remove and create again
# Cluster does not allow editing existing rule
existing_rule = self.normalize_rule_spec(rule_obj=rule_obj)
if ((sorted(existing_rule['rule_vms']) == sorted(self.vm_list)) and
(existing_rule['rule_enabled'] == self.enabled) and
(existing_rule['rule_mandatory'] == self.mandatory) and
(existing_rule['rule_affinity'] == self.affinity_rule)):
# Rule is same as existing rule, evacuate
self.module.exit_json(changed=False, result=existing_rule)
# Delete existing rule as we cannot edit it
changed, result = self.delete(rule_name=self.rule_name)
if not changed:
self.module.fail_json(msg="Failed to delete while updating rule %s due to %s" % (self.rule_name, result))
self.module.exit_json(changed=False, result=existing_rule, msg="Rule already exists with the same configuration")
else:
changed, result = self.update_rule_spec(rule_obj)
return changed, result
else:
changed, result = self.create_rule_spec()
return changed, result
def create_rule_spec(self):
"""
Function to create DRS rule
Create DRS rule
"""
changed = False
if self.affinity_rule:
@ -286,10 +283,41 @@ class VmwareDrs(PyVmomi):
return changed, result
def update_rule_spec(self, rule_obj=None):
"""
Update DRS rule
"""
changed = False
rule_obj.vm = self.vm_obj_list
if (rule_obj.mandatory != self.mandatory):
rule_obj.mandatory = self.mandatory
if (rule_obj.enabled != self.enabled):
rule_obj.enabled = self.enabled
rule_spec = vim.cluster.RuleSpec(info=rule_obj, operation='edit')
config_spec = vim.cluster.ConfigSpec(rulesSpec=[rule_spec])
try:
task = self.cluster_obj.ReconfigureCluster_Task(config_spec, modify=True)
changed, result = wait_for_task(task)
except vmodl.fault.InvalidRequest as e:
result = to_native(e.msg)
except Exception as e:
result = to_native(e)
if changed:
rule_obj = self.get_rule_key_by_name(rule_name=self.rule_name)
result = self.normalize_rule_spec(rule_obj)
return changed, result
# Delete
def delete(self, rule_name=None):
"""
Function to delete DRS rule using name
Delete DRS rule using name
"""
changed = False
if rule_name is None:
@ -326,7 +354,7 @@ def main():
)
required_if = [
['state', 'present', ['vms']],
['state', 'present', ['vms']]
]
module = AnsibleModule(argument_spec=argument_spec,
required_if=required_if,
@ -347,7 +375,6 @@ def main():
else:
results['failed'] = True
results['msg'] = "Failed to create DRS rule %s" % vm_drs.rule_name
results['result'] = result
elif state == 'absent':
# Delete Rule

View file

@ -11,7 +11,9 @@
setup_attach_host: true
setup_datastore: true
setup_virtualmachines: true
- name: Create a DRS Affinity rule for vms
- &create_drs_rule
name: Create a DRS Affinity rule for vms
vmware_vm_vm_drs_rule:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
@ -24,12 +26,24 @@
affinity_rule: True
mandatory: True
register: drs_rule_0001_results
- debug: var=drs_rule_0001_results
- assert:
that:
- "{{ drs_rule_0001_results.changed }}"
- name: Create a DRS Anti-Affinity rule for vms
- debug: var=drs_rule_0001_results
- name: Check if changes are made
assert:
that:
- drs_rule_0001_results.changed
- <<: *create_drs_rule
name: Create a DRS Affinity rule for vms again
- name: Check if no changes are made if drs rule is created again
assert:
that:
- not drs_rule_0001_results.changed
- &update_drs_rule
name: Update a DRS Affinity rule for vms
vmware_vm_vm_drs_rule:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
@ -37,12 +51,94 @@
password: "{{ vcenter_password }}"
drs_rule_name: drs_rule_0001
cluster_name: "{{ ccr1 }}"
vms: "{{ virtual_machines | map(attribute='name') | list }}"
vms: "{{ virtual_machines_in_cluster | map(attribute='name') | list }}"
enabled: False
affinity_rule: True
mandatory: False
register: drs_rule_0001_results
- name: Check if changes are made if drs rule is created
assert:
that:
- drs_rule_0001_results.changed
- <<: *update_drs_rule
name: Update a DRS Affinity rule for vms again
- name: Check if no changes are made if drs rule is created again
assert:
that:
- not drs_rule_0001_results.changed
- &delete_drs_rule
name: Delete a DRS Affinity rule for vms
vmware_vm_vm_drs_rule:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
drs_rule_name: drs_rule_0001
cluster_name: "{{ ccr1 }}"
state: absent
register: drs_rule_0001_results
- name: Check if DRS rule is delete
assert:
that:
- drs_rule_0001_results.changed
- <<: *delete_drs_rule
name: Delete a DRS Affinity rule for vms again
- name: Check if DRS rule is not delete again
assert:
that:
- not drs_rule_0001_results.changed
- &create_anti_drs_rule
name: Create a DRS Anti-Affinity rule for vms
vmware_vm_vm_drs_rule:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
drs_rule_name: drs_rule_0002
cluster_name: "{{ ccr1 }}"
vms: "{{ virtual_machines_in_cluster | map(attribute='name') | list }}"
enabled: True
affinity_rule: False
mandatory: False
register: drs_rule_0002_results
- debug: var=drs_rule_0002_results
- assert:
- name: Check if DRS Anti-Affinity rule is created
assert:
that:
- "{{ drs_rule_0002_results.changed }}"
- drs_rule_0002_results.changed
- <<: *create_anti_drs_rule
name: Create a DRS Anti-Affinity rule for vms again
- debug: var=drs_rule_0002_results
- name: Check if no changes are made if DRS Anti-Affinity rule is created again
assert:
that:
- not drs_rule_0002_results.changed
- name: Delete a DRS Anti-Affinity rule for vms
vmware_vm_vm_drs_rule:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
drs_rule_name: drs_rule_0002
cluster_name: "{{ ccr1 }}"
state: absent
register: drs_rule_0002_results
- name: Check if DRS rule is not delete
assert:
that:
- drs_rule_0002_results.changed