diff --git a/ci/roles/network/defaults/main.yml b/ci/roles/network/defaults/main.yml index 8b592206..321ccd97 100644 --- a/ci/roles/network/defaults/main.yml +++ b/ci/roles/network/defaults/main.yml @@ -31,5 +31,6 @@ mtu: 1250 network_external: false network_name: shade_network network_name_newparams: newparams_network +network_name_updates: update_network network_shared: false port_security_enabled: false diff --git a/ci/roles/network/tasks/main.yml b/ci/roles/network/tasks/main.yml index 60078f16..32c4191f 100644 --- a/ci/roles/network/tasks/main.yml +++ b/ci/roles/network/tasks/main.yml @@ -105,3 +105,66 @@ assert: that: - result_nonet.networks == [] + +- name: Create network - updates + openstack.cloud.network: + cloud: "{{ cloud }}" + name: "{{ network_name_updates }}" + state: present + shared: "{{ network_shared }}" + external: "{{ network_external }}" + mtu: "{{ mtu }}" + port_security_enabled: "{{ port_security_enabled }}" + register: result_create_nw_for_updates + +- name: Update network - update failure + openstack.cloud.network: + cloud: "{{ cloud }}" + name: "{{ network_name_updates }}" + state: present + shared: "{{ network_shared }}" + external: "{{ network_external }}" + mtu: "{{ mtu }}" + port_security_enabled: "{{ port_security_enabled }}" + # You cannot update this property. + provider_physical_network: cannot_be_updated + ignore_errors: true + register: result_nw_update_failure + +- name: Verify networks info - update fail + assert: + that: + - result_nw_update_failure is failed + +- name: Update network - update success + openstack.cloud.network: + cloud: "{{ cloud }}" + name: "{{ network_name_updates }}" + state: present + shared: "{{ network_shared }}" + external: "{{ network_external }}" + # NOTE: This property should be updated + mtu: "{{ mtu - 50 }}" + # NOTE: This property should be updated + port_security_enabled: "{{ not port_security_enabled }}" + register: result_nw_update_success + +- name: Gather networks info - updates + openstack.cloud.networks_info: + cloud: "{{ cloud }}" + name: "{{ network_name_updates }}" + register: result_network_updates_info + +- name: Verify networks info - update success + assert: + that: + - result_nw_update_success is changed + - result_network_updates_info.networks.0.name == network_name_updates + - result_network_updates_info.networks.0.mtu == mtu - 50 + - result_network_updates_info.networks.0['is_port_security_enabled'] == (not port_security_enabled) + +- name: Delete network - updates + openstack.cloud.network: + cloud: "{{ cloud }}" + name: "{{ network_name_updates }}" + state: absent diff --git a/plugins/modules/network.py b/plugins/modules/network.py index 65ecba57..af50f17a 100644 --- a/plugins/modules/network.py +++ b/plugins/modules/network.py @@ -234,27 +234,57 @@ class NetworkModule(OpenStackModule): net = self.conn.network.find_network(name, **net_kwargs) if state == 'present': - if not net: - if provider_physical_network: - kwargs['provider_physical_network'] = provider_physical_network - if provider_network_type: - kwargs['provider_network_type'] = provider_network_type - if provider_segmentation_id: - kwargs['provider_segmentation_id'] = provider_segmentation_id + if provider_physical_network: + kwargs['provider_physical_network'] = provider_physical_network + if provider_network_type: + kwargs['provider_network_type'] = provider_network_type + if provider_segmentation_id: + kwargs['provider_segmentation_id'] = provider_segmentation_id - if project_id is not None: - kwargs['project_id'] = project_id - net = self.conn.network.create_network(name=name, - shared=shared, - admin_state_up=admin_state_up, - is_router_external=external, - **kwargs) + if project_id is not None: + kwargs['project_id'] = project_id + + kwargs["shared"] = shared + kwargs["admin_state_up"] = admin_state_up + kwargs["is_router_external"] = external + + if not net: + net = self.conn.network.create_network(name=name, **kwargs) changed = True - net = net.to_dict(computed=False) else: changed = False - self.exit(changed=changed, network=net, id=net['id']) + update_kwargs = {} + # Check we are not trying to update an properties that cannot be modified + non_updatables = [ + "provider_network_type", + "provider_physical_network", + ] + for arg in non_updatables: + if arg in kwargs and kwargs[arg] != net[arg]: + self.fail_json( + msg="The following parameters cannot be updated: " + "%s. You will need to use state: absent and " + "recreate." % ', '.join(non_updatables) + ) + + # Filter args to update call to the ones that have been modifed + # and are updatable. Adapted from: + # https://github.com/openstack/openstacksdk/blob/1ce15c9a8758b4d978eb5239bae100ddc13c8875/openstack/cloud/_network.py#L559-L561 + for arg in ["shared", "admin_state_up", "is_router_external", + "mtu", "port_security_enabled", "dns_domain", + "provider_segmentation_id"]: + if arg in kwargs and kwargs[arg] != net[arg]: + update_kwargs[arg] = kwargs[arg] + + if update_kwargs: + net = self.conn.network.update_network( + net.id, **update_kwargs + ) + changed = True + + net = net.to_dict(computed=False) + self.exit(changed=changed, network=net, id=net['id']) elif state == 'absent': if not net: self.exit(changed=False)