Repository: ansible/ansible
Pull request: add old usages to network cluster
##### SUMMARY
<!--- Describe the change below, including rationale and design decisions -->
add old usages to network cluster
<!--- HINT: Include "Fixes #nnn" if you are fixing an existing issue -->
Fixes #35286

##### ISSUE TYPE
<!--- Pick one below and delete the rest -->
- Bugfix Pull Request

##### COMPONENT NAME
<!--- Write the short name of the module, plugin, task or feature below -->

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes -->
```paste below
ansible 2.7.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/mnecas/Desktop/Projects/Redhat/ansible/lib/ansible/modules/cloud/ovirt']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.15 (default, Sep 21 2018, 23:26:48) [GCC 8.1.1 20180712 (Red Hat 8.1.1-5)]
                                                                                                                  
```

##### ADDITIONAL INFORMATION
<!--- Include additional information to help people understand the change here -->
<!--- A step-by-step reproduction of the problem is helpful if there is no related issue -->

<!--- Paste verbatim command output below, e.g. before and after your change -->
```paste below

```


Problem statement:
ovirt_networks: management network modification fails, API complains about unsetting management property
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest -->
 - Bug Report

##### COMPONENT NAME
<!---
Name of the module, plugin, task or feature
Do not include extra details here, e.g. "vyos_command" not "the network module vyos_command" or the full path
-->
ovirt_networks module

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.4.2.0
  config file = /home/djasa/$PROJECT_DIR/ansible.cfg
  configured module search path = [u'/home/djasa/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.14 (default, Jan 11 2018, 14:45:11) [GCC 7.2.1 20170915 (Red Hat 7.2.1-2)]
```

##### CONFIGURATION
<!---
If using Ansible 2.4 or above, paste the results of "ansible-config dump --only-changed"
Otherwise, mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->
```
DEFAULT_HOST_LIST(/home/djasa/$PROJECT_DIR/ansible.cfg) = [u'/home/djasa/$PROJECT_DIR/inventory/hosts']
DEFAULT_ROLES_PATH(/home/djasa/$PROJECT_DIR/ansible.cfg) = [u'/home/djasa/$PROJECT_DIR/roles']
```

##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say "N/A" for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->
N/A

##### SUMMARY
<!--- Explain the problem briefly -->
ovirt_networks: management network modification fails, API complains about unsetting management property

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->

<!--- Paste example playbooks or commands between quotes below -->
Playbook that sets up network:
```yaml
  - name: set up networks
    ovirt_networks:
      auth: "{{ ovirt_auth }}"
      name: "{{ item.name }}"
      data_center: "{{ item.data_center }}"
      state: "{{ item.state | default('present') }}"
      clusters: "{{ item.clusters }}"
      mtu: "{{ item.mtu | default('9000') }}"
      vlan_tag: "{{ item.vlan_tag | default(omit) }}"
      vm_network: "{{ item.vm_network | default(omit) }}"
    with_items: "{{ logical_networks }}"
```
is fed with this configuration file:
```yaml
- name: ovirtmgmt
  data_center: Default
  clusters:
  - name: Default
    assigned: True
    required: True
    display: True
    migration: True
  mtu: 1500
  vm_network: no
```
In other words, playbook doesn't intend to change network's management status, nor does module documentation state that such thing is possible, so…

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
I expected this module would just have vm_network set to False and be noop otherwise. But…

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->
I keep getting this error (with -vvvv). Maybe the module should and maybe expose the management network setting?
<!--- Paste verbatim command output between quotes below -->
```
TASK [set up networks] *****************************************************************************************************************************
task path: /home/djasa/$PROJECT_DIR/playbooks/rhv_setup.yml:84
Using module file /usr/lib/python2.7/site-packages/ansible/modules/cloud/ovirt/ovirt_networks.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: djasa
<127.0.0.1> EXEC /bin/sh -c 'echo ~ && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/djasa/.ansible/tmp/ansible-tmp-1516804483.42-158332527802812 `" && echo ansible-tmp-1516804483.42-158332527802812="` echo /home/djasa/.ansible/tmp/ansible-tmp-1516804483.42-158332527802812 `" ) && sleep 0'
<127.0.0.1> PUT /tmp/tmp4CY5hD TO /home/djasa/.ansible/tmp/ansible-tmp-1516804483.42-158332527802812/ovirt_networks.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/djasa/.ansible/tmp/ansible-tmp-1516804483.42-158332527802812/ /home/djasa/.ansible/tmp/ansible-tmp-1516804483.42-158332527802812/ovirt_networks.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python2 /home/djasa/.ansible/tmp/ansible-tmp-1516804483.42-158332527802812/ovirt_networks.py; rm -rf "/home/djasa/.ansible/tmp/ansible-tmp-1516804483.42-158332527802812/" > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_xNLAwT/ansible_module_ovirt_networks.py", line 254, in main
    ret = cluster_networks_module.create()
  File "/tmp/ansible_xNLAwT/ansible_modlib.zip/ansible/module_utils/ovirt.py", line 550, in create
    **update_params
  File "/usr/lib64/python2.7/site-packages/ovirtsdk4/services.py", line 3620, in update
    return self._internal_update(network, headers, query, wait)
  File "/usr/lib64/python2.7/site-packages/ovirtsdk4/service.py", line 244, in _internal_update
    return future.wait() if wait else future
  File "/usr/lib64/python2.7/site-packages/ovirtsdk4/service.py", line 53, in wait
    return self._code(response)
  File "/usr/lib64/python2.7/site-packages/ovirtsdk4/service.py", line 241, in callback
    self._check_fault(response)
  File "/usr/lib64/python2.7/site-packages/ovirtsdk4/service.py", line 123, in _check_fault
    self._raise_error(response, body)
  File "/usr/lib64/python2.7/site-packages/ovirtsdk4/service.py", line 109, in _raise_error
    raise error
Error: Fault reason is "Operation Failed". Fault detail is "[Cannot edit Network. Unsetting management network property is not allowed. It is done automatically when moving the role to another network.]". HTTP response code is 400.

failed: [localhost] (item={u'clusters': [{u'assigned': True, u'required': True, u'display': True, u'name': u'Default', u'migration': True}], u'data_center': u'Default', u'name': u'ovirtmgmt', u'vm_network': False, u'mtu': 1500}) => {
    "changed": false, 
    "invocation": {
        "module_args": {
            "clusters": [
                {
                    "assigned": true, 
                    "display": true, 
                    "migration": true, 
                    "name": "Default", 
                    "required": true
                }
            ], 
            "comment": null, 
            "data_center": "Default", 
            "description": null, 
            "fetch_nested": false, 
            "mtu": 1500, 
            "name": "ovirtmgmt", 
            "nested_attributes": [], 
            "poll_interval": 3, 
            "state": "present", 
            "timeout": 180, 
            "vlan_tag": null, 
            "vm_network": false, 
            "wait": true
        }
    }, 
    "item": {
        "clusters": [
            {
                "assigned": true, 
                "display": true, 
                "migration": true, 
                "name": "Default", 
                "required": true
            }
        ], 
        "data_center": "Default", 
        "mtu": 1500, 
        "name": "ovirtmgmt", 
        "vm_network": false
    }
}

MSG:

Fault reason is "Operation Failed". Fault detail is "[Cannot edit Network. Unsetting management network property is not allowed. It is done automatically when moving the role to another network.]". HTTP response code is 400.
```

Hints from issue discussion:
Files identified in the description:
* [lib/ansible/modules/cloud/ovirt/ovirt_networks.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/ovirt/ovirt_networks.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @machacekondra @mwperina
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Discovered the same issue yesterday. Will be any further progress on this issue?
Files identified in the description:
* [lib/ansible/modules/cloud/ovirt/_ovirt_networks.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/ovirt/_ovirt_networks.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
Files identified in the description:
* [lib/ansible/modules/cloud/ovirt/ovirt_cluster.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/ovirt/ovirt_cluster.py)
* [lib/ansible/modules/cloud/ovirt/ovirt_host.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/ovirt/ovirt_host.py)
* [lib/ansible/modules/cloud/ovirt/ovirt_host_network.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/ovirt/ovirt_host_network.py)
* [lib/ansible/modules/cloud/ovirt/ovirt_network.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/ovirt/ovirt_network.py)
* [lib/ansible/modules/cloud/ovirt/ovirt_network_facts.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/ovirt/ovirt_network_facts.py)
* [lib/ansible/modules/cloud/ovirt/ovirt_nic.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/ovirt/ovirt_nic.py)
* [lib/ansible/modules/cloud/ovirt/ovirt_nic_facts.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/ovirt/ovirt_nic_facts.py)
* [lib/ansible/modules/cloud/ovirt/ovirt_snapshot.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/ovirt/ovirt_snapshot.py)
* [lib/ansible/modules/cloud/ovirt/ovirt_tag.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/ovirt/ovirt_tag.py)
* [lib/ansible/modules/cloud/ovirt/ovirt_user.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/ovirt/ovirt_user.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
Anyone have a workaround for this?

Commit message: set default value to old usages

Patch to review:
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_network.py b/lib/ansible/modules/cloud/ovirt/ovirt_network.py
index aed2f8ace41333..59a1e9158cccd0 100644
--- a/lib/ansible/modules/cloud/ovirt/ovirt_network.py
+++ b/lib/ansible/modules/cloud/ovirt/ovirt_network.py
@@ -146,6 +146,7 @@
     search_by_name,
     get_id_by_name,
     get_dict_of_struct,
+    get_entity
 )
 
 
@@ -213,6 +214,10 @@ def __init__(self, network_id, cluster_network, *args, **kwargs):
         super(ClusterNetworksModule, self).__init__(*args, **kwargs)
         self._network_id = network_id
         self._cluster_network = cluster_network
+        self._old_usages = []
+        self._cluster_network_service = get_entity(self._service.network_service(network_id))
+        if self._cluster_network_service is not None:
+            self._old_usages = self._cluster_network_service.usages
 
     def build_entity(self):
         return otypes.Network(
@@ -220,11 +225,12 @@ def build_entity(self):
             name=self._module.params['name'],
             required=self._cluster_network.get('required'),
             display=self._cluster_network.get('display'),
-            usages=[
+            usages=list(set([
                 otypes.NetworkUsage(usage)
                 for usage in ['display', 'gluster', 'migration']
                 if self._cluster_network.get(usage, False)
-            ] if (
+            ] + self._old_usages))
+            if (
                 self._cluster_network.get('display') is not None or
                 self._cluster_network.get('gluster') is not None or
                 self._cluster_network.get('migration') is not None


Code review comments:
diff_hunk: @@ -213,18 +214,23 @@ def __init__(self, network_id, cluster_network, *args, **kwargs):
         super(ClusterNetworksModule, self).__init__(*args, **kwargs)
         self._network_id = network_id
         self._cluster_network = cluster_network
+        self._old_usages = []
+        self._cluster_network_service = get_entity(self._service.network_service(network_id))
path: lib/ansible/modules/cloud/ovirt/ovirt_network.py
text: @user1:
This is not service so please rename the variable more reasonable. It can be confusing.