2015-05-12 12:10:53 +00:00
|
|
|
#!/usr/bin/python
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
# (c) 2015, Chris Long <alcamie@gmail.com> <chlong@redhat.com>
|
2017-07-29 09:35:25 +00:00
|
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
__metaclass__ = type
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
|
2017-08-16 03:16:38 +00:00
|
|
|
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
2017-03-14 16:07:22 +00:00
|
|
|
'status': ['preview'],
|
|
|
|
'supported_by': 'community'}
|
|
|
|
|
2016-12-06 10:35:25 +00:00
|
|
|
|
2017-12-07 16:27:06 +00:00
|
|
|
DOCUMENTATION = '''
|
2015-05-12 12:10:53 +00:00
|
|
|
---
|
|
|
|
module: nmcli
|
2015-06-16 16:30:47 +00:00
|
|
|
author: "Chris Long (@alcamie101)"
|
2015-05-12 12:10:53 +00:00
|
|
|
short_description: Manage Networking
|
2017-04-27 16:38:11 +00:00
|
|
|
requirements: [ nmcli, dbus, NetworkManager-glib ]
|
2015-06-12 18:11:38 +00:00
|
|
|
version_added: "2.0"
|
2015-05-12 12:10:53 +00:00
|
|
|
description:
|
|
|
|
- Manage the network devices. Create, modify, and manage, ethernet, teams, bonds, vlans etc.
|
|
|
|
options:
|
|
|
|
state:
|
|
|
|
required: True
|
|
|
|
choices: [ present, absent ]
|
2015-05-14 15:09:49 +00:00
|
|
|
description:
|
|
|
|
- Whether the device should exist or not, taking action if the state is different from what is stated.
|
|
|
|
autoconnect:
|
2015-05-12 12:10:53 +00:00
|
|
|
required: False
|
|
|
|
default: "yes"
|
|
|
|
choices: [ "yes", "no" ]
|
|
|
|
description:
|
2015-05-14 15:09:49 +00:00
|
|
|
- Whether the connection should start on boot.
|
2015-06-12 18:11:38 +00:00
|
|
|
- Whether the connection profile can be automatically activated
|
2015-05-14 14:45:51 +00:00
|
|
|
conn_name:
|
2015-05-12 12:10:53 +00:00
|
|
|
required: True
|
|
|
|
description:
|
2015-06-12 18:11:38 +00:00
|
|
|
- 'Where conn_name will be the name used to call the connection. when not provided a default name is generated: <type>[-<ifname>][-<num>]'
|
2015-05-12 12:10:53 +00:00
|
|
|
ifname:
|
|
|
|
required: False
|
2015-05-14 14:45:51 +00:00
|
|
|
default: conn_name
|
2015-05-12 12:10:53 +00:00
|
|
|
description:
|
2015-05-14 15:09:49 +00:00
|
|
|
- Where IFNAME will be the what we call the interface name.
|
2015-05-12 12:10:53 +00:00
|
|
|
- interface to bind the connection to. The connection will only be applicable to this interface name.
|
|
|
|
- A special value of "*" can be used for interface-independent connections.
|
|
|
|
- The ifname argument is mandatory for all connection types except bond, team, bridge and vlan.
|
|
|
|
type:
|
|
|
|
required: False
|
|
|
|
choices: [ ethernet, team, team-slave, bond, bond-slave, bridge, vlan ]
|
|
|
|
description:
|
2017-05-26 14:58:00 +00:00
|
|
|
- This is the type of device or network connection that you wish to create or modify.
|
2015-05-12 12:10:53 +00:00
|
|
|
mode:
|
|
|
|
required: False
|
|
|
|
choices: [ "balance-rr", "active-backup", "balance-xor", "broadcast", "802.3ad", "balance-tlb", "balance-alb" ]
|
2015-06-12 18:11:38 +00:00
|
|
|
default: balence-rr
|
2015-05-12 12:10:53 +00:00
|
|
|
description:
|
2015-06-12 18:11:38 +00:00
|
|
|
- This is the type of device or network connection that you wish to create for a bond, team or bridge.
|
2015-05-12 12:10:53 +00:00
|
|
|
master:
|
|
|
|
required: False
|
|
|
|
default: None
|
|
|
|
description:
|
2015-05-14 14:45:51 +00:00
|
|
|
- master <master (ifname, or connection UUID or conn_name) of bridge, team, bond master connection profile.
|
2015-05-12 12:10:53 +00:00
|
|
|
ip4:
|
|
|
|
required: False
|
|
|
|
default: None
|
2015-05-14 15:09:49 +00:00
|
|
|
description:
|
2016-12-08 05:34:16 +00:00
|
|
|
- 'The IPv4 address to this interface using this format ie: "192.0.2.24/24"'
|
2015-05-12 12:10:53 +00:00
|
|
|
gw4:
|
|
|
|
required: False
|
2015-05-14 15:09:49 +00:00
|
|
|
description:
|
2016-12-08 05:34:16 +00:00
|
|
|
- 'The IPv4 gateway for this interface using this format ie: "192.0.2.1"'
|
2015-05-12 12:10:53 +00:00
|
|
|
dns4:
|
|
|
|
required: False
|
|
|
|
default: None
|
2015-05-14 15:09:49 +00:00
|
|
|
description:
|
2017-05-26 14:58:00 +00:00
|
|
|
- 'A list of upto 3 dns servers, ipv4 format e.g. To add two IPv4 DNS server addresses: "192.0.2.53 198.51.100.53"'
|
2015-05-12 12:10:53 +00:00
|
|
|
ip6:
|
|
|
|
required: False
|
|
|
|
default: None
|
|
|
|
description:
|
2015-06-12 18:11:38 +00:00
|
|
|
- 'The IPv6 address to this interface using this format ie: "abbe::cafe"'
|
2015-05-12 12:10:53 +00:00
|
|
|
gw6:
|
|
|
|
required: False
|
|
|
|
default: None
|
2015-05-14 15:09:49 +00:00
|
|
|
description:
|
2015-06-12 18:11:38 +00:00
|
|
|
- 'The IPv6 gateway for this interface using this format ie: "2001:db8::1"'
|
2015-05-12 12:10:53 +00:00
|
|
|
dns6:
|
|
|
|
required: False
|
2015-05-14 15:09:49 +00:00
|
|
|
description:
|
2017-05-26 14:58:00 +00:00
|
|
|
- 'A list of upto 3 dns servers, ipv6 format e.g. To add two IPv6 DNS server addresses: "2001:4860:4860::8888 2001:4860:4860::8844"'
|
2015-05-12 12:10:53 +00:00
|
|
|
mtu:
|
|
|
|
required: False
|
2015-06-12 18:11:38 +00:00
|
|
|
default: 1500
|
2015-05-12 12:10:53 +00:00
|
|
|
description:
|
2015-06-12 18:11:38 +00:00
|
|
|
- The connection MTU, e.g. 9000. This can't be applied when creating the interface and is done once the interface has been created.
|
2015-05-12 12:10:53 +00:00
|
|
|
- Can be used when modifying Team, VLAN, Ethernet (Future plans to implement wifi, pppoe, infiniband)
|
|
|
|
primary:
|
|
|
|
required: False
|
|
|
|
default: None
|
|
|
|
description:
|
|
|
|
- This is only used with bond and is the primary interface name (for "active-backup" mode), this is the usually the 'ifname'
|
|
|
|
miimon:
|
|
|
|
required: False
|
2015-06-12 18:11:38 +00:00
|
|
|
default: 100
|
2015-05-12 12:10:53 +00:00
|
|
|
description:
|
2015-06-12 18:11:38 +00:00
|
|
|
- This is only used with bond - miimon
|
2015-05-12 12:10:53 +00:00
|
|
|
downdelay:
|
|
|
|
required: False
|
|
|
|
default: None
|
|
|
|
description:
|
2015-06-12 18:11:38 +00:00
|
|
|
- This is only used with bond - downdelay
|
2015-05-12 12:10:53 +00:00
|
|
|
updelay:
|
|
|
|
required: False
|
|
|
|
default: None
|
|
|
|
description:
|
2015-06-12 18:11:38 +00:00
|
|
|
- This is only used with bond - updelay
|
2015-05-12 12:10:53 +00:00
|
|
|
arp_interval:
|
|
|
|
required: False
|
|
|
|
default: None
|
|
|
|
description:
|
2015-06-12 18:11:38 +00:00
|
|
|
- This is only used with bond - ARP interval
|
2015-05-12 12:10:53 +00:00
|
|
|
arp_ip_target:
|
|
|
|
required: False
|
|
|
|
default: None
|
|
|
|
description:
|
|
|
|
- This is only used with bond - ARP IP target
|
|
|
|
stp:
|
|
|
|
required: False
|
|
|
|
default: None
|
|
|
|
description:
|
|
|
|
- This is only used with bridge and controls whether Spanning Tree Protocol (STP) is enabled for this bridge
|
|
|
|
priority:
|
|
|
|
required: False
|
2015-06-12 18:11:38 +00:00
|
|
|
default: 128
|
2015-05-12 12:10:53 +00:00
|
|
|
description:
|
2015-06-12 18:11:38 +00:00
|
|
|
- This is only used with 'bridge' - sets STP priority
|
2015-05-12 12:10:53 +00:00
|
|
|
forwarddelay:
|
|
|
|
required: False
|
2015-06-12 18:11:38 +00:00
|
|
|
default: 15
|
2015-05-12 12:10:53 +00:00
|
|
|
description:
|
2015-06-12 18:11:38 +00:00
|
|
|
- This is only used with bridge - [forward-delay <2-30>] STP forwarding delay, in seconds
|
2015-05-12 12:10:53 +00:00
|
|
|
hellotime:
|
|
|
|
required: False
|
2015-06-12 18:11:38 +00:00
|
|
|
default: 2
|
2015-05-12 12:10:53 +00:00
|
|
|
description:
|
2015-06-12 18:11:38 +00:00
|
|
|
- This is only used with bridge - [hello-time <1-10>] STP hello time, in seconds
|
2015-05-12 12:10:53 +00:00
|
|
|
maxage:
|
|
|
|
required: False
|
2015-06-12 18:11:38 +00:00
|
|
|
default: 20
|
2015-05-12 12:10:53 +00:00
|
|
|
description:
|
2015-06-12 18:11:38 +00:00
|
|
|
- This is only used with bridge - [max-age <6-42>] STP maximum message age, in seconds
|
2015-05-12 12:10:53 +00:00
|
|
|
ageingtime:
|
|
|
|
required: False
|
2015-06-12 18:11:38 +00:00
|
|
|
default: 300
|
2015-05-12 12:10:53 +00:00
|
|
|
description:
|
2015-06-12 18:11:38 +00:00
|
|
|
- This is only used with bridge - [ageing-time <0-1000000>] the Ethernet MAC address aging time, in seconds
|
2015-05-12 12:10:53 +00:00
|
|
|
mac:
|
|
|
|
required: False
|
|
|
|
default: None
|
|
|
|
description:
|
2017-03-23 01:50:28 +00:00
|
|
|
- >
|
|
|
|
This is only used with bridge - MAC address of the bridge
|
|
|
|
(note: this requires a recent kernel feature, originally introduced in 3.15 upstream kernel)
|
2015-05-12 12:10:53 +00:00
|
|
|
slavepriority:
|
|
|
|
required: False
|
2015-06-12 18:11:38 +00:00
|
|
|
default: 32
|
2015-05-12 12:10:53 +00:00
|
|
|
description:
|
2015-06-12 18:11:38 +00:00
|
|
|
- This is only used with 'bridge-slave' - [<0-63>] - STP priority of this slave
|
2015-05-12 12:10:53 +00:00
|
|
|
path_cost:
|
|
|
|
required: False
|
2015-06-12 18:11:38 +00:00
|
|
|
default: 100
|
2015-05-12 12:10:53 +00:00
|
|
|
description:
|
2015-06-12 18:11:38 +00:00
|
|
|
- This is only used with 'bridge-slave' - [<1-65535>] - STP port cost for destinations via this slave
|
2015-05-12 12:10:53 +00:00
|
|
|
hairpin:
|
|
|
|
required: False
|
2015-06-12 18:11:38 +00:00
|
|
|
default: yes
|
2015-05-12 12:10:53 +00:00
|
|
|
description:
|
2017-03-23 01:50:28 +00:00
|
|
|
- This is only used with 'bridge-slave' - 'hairpin mode' for the slave, which allows frames to be sent back out through the slave the
|
|
|
|
frame was received on.
|
2015-05-12 12:10:53 +00:00
|
|
|
vlanid:
|
|
|
|
required: False
|
|
|
|
default: None
|
|
|
|
description:
|
|
|
|
- This is only used with VLAN - VLAN ID in range <0-4095>
|
|
|
|
vlandev:
|
|
|
|
required: False
|
|
|
|
default: None
|
|
|
|
description:
|
|
|
|
- This is only used with VLAN - parent device this VLAN is on, can use ifname
|
|
|
|
flags:
|
|
|
|
required: False
|
|
|
|
default: None
|
|
|
|
description:
|
|
|
|
- This is only used with VLAN - flags
|
|
|
|
ingress:
|
|
|
|
required: False
|
|
|
|
default: None
|
|
|
|
description:
|
|
|
|
- This is only used with VLAN - VLAN ingress priority mapping
|
|
|
|
egress:
|
|
|
|
required: False
|
|
|
|
default: None
|
|
|
|
description:
|
|
|
|
- This is only used with VLAN - VLAN egress priority mapping
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
2017-12-07 16:27:06 +00:00
|
|
|
EXAMPLES = '''
|
2017-01-07 16:50:10 +00:00
|
|
|
# These examples are using the following inventory:
|
|
|
|
#
|
|
|
|
# ## Directory layout:
|
|
|
|
#
|
|
|
|
# |_/inventory/cloud-hosts
|
|
|
|
# | /group_vars/openstack-stage.yml
|
|
|
|
# | /host_vars/controller-01.openstack.host.com
|
|
|
|
# | /host_vars/controller-02.openstack.host.com
|
|
|
|
# |_/playbook/library/nmcli.py
|
|
|
|
# | /playbook-add.yml
|
|
|
|
# | /playbook-del.yml
|
|
|
|
# ```
|
|
|
|
#
|
|
|
|
# ## inventory examples
|
|
|
|
# ### groups_vars
|
|
|
|
# ```yml
|
|
|
|
# ---
|
|
|
|
# #devops_os_define_network
|
|
|
|
# storage_gw: "192.0.2.254"
|
|
|
|
# external_gw: "198.51.100.254"
|
|
|
|
# tenant_gw: "203.0.113.254"
|
|
|
|
#
|
|
|
|
# #Team vars
|
|
|
|
# nmcli_team:
|
|
|
|
# - conn_name: tenant
|
|
|
|
# ip4: '{{ tenant_ip }}'
|
|
|
|
# gw4: '{{ tenant_gw }}'
|
|
|
|
# - conn_name: external
|
|
|
|
# ip4: '{{ external_ip }}'
|
|
|
|
# gw4: '{{ external_gw }}'
|
|
|
|
# - conn_name: storage
|
|
|
|
# ip4: '{{ storage_ip }}'
|
|
|
|
# gw4: '{{ storage_gw }}'
|
|
|
|
# nmcli_team_slave:
|
|
|
|
# - conn_name: em1
|
|
|
|
# ifname: em1
|
|
|
|
# master: tenant
|
|
|
|
# - conn_name: em2
|
|
|
|
# ifname: em2
|
|
|
|
# master: tenant
|
|
|
|
# - conn_name: p2p1
|
|
|
|
# ifname: p2p1
|
|
|
|
# master: storage
|
|
|
|
# - conn_name: p2p2
|
|
|
|
# ifname: p2p2
|
|
|
|
# master: external
|
|
|
|
#
|
|
|
|
# #bond vars
|
|
|
|
# nmcli_bond:
|
|
|
|
# - conn_name: tenant
|
|
|
|
# ip4: '{{ tenant_ip }}'
|
|
|
|
# gw4: ''
|
|
|
|
# mode: balance-rr
|
|
|
|
# - conn_name: external
|
|
|
|
# ip4: '{{ external_ip }}'
|
|
|
|
# gw4: ''
|
|
|
|
# mode: balance-rr
|
|
|
|
# - conn_name: storage
|
|
|
|
# ip4: '{{ storage_ip }}'
|
|
|
|
# gw4: '{{ storage_gw }}'
|
|
|
|
# mode: balance-rr
|
|
|
|
# nmcli_bond_slave:
|
|
|
|
# - conn_name: em1
|
|
|
|
# ifname: em1
|
|
|
|
# master: tenant
|
|
|
|
# - conn_name: em2
|
|
|
|
# ifname: em2
|
|
|
|
# master: tenant
|
|
|
|
# - conn_name: p2p1
|
|
|
|
# ifname: p2p1
|
|
|
|
# master: storage
|
|
|
|
# - conn_name: p2p2
|
|
|
|
# ifname: p2p2
|
|
|
|
# master: external
|
|
|
|
#
|
|
|
|
# #ethernet vars
|
|
|
|
# nmcli_ethernet:
|
|
|
|
# - conn_name: em1
|
|
|
|
# ifname: em1
|
|
|
|
# ip4: '{{ tenant_ip }}'
|
|
|
|
# gw4: '{{ tenant_gw }}'
|
|
|
|
# - conn_name: em2
|
|
|
|
# ifname: em2
|
|
|
|
# ip4: '{{ tenant_ip1 }}'
|
|
|
|
# gw4: '{{ tenant_gw }}'
|
|
|
|
# - conn_name: p2p1
|
|
|
|
# ifname: p2p1
|
|
|
|
# ip4: '{{ storage_ip }}'
|
|
|
|
# gw4: '{{ storage_gw }}'
|
|
|
|
# - conn_name: p2p2
|
|
|
|
# ifname: p2p2
|
|
|
|
# ip4: '{{ external_ip }}'
|
|
|
|
# gw4: '{{ external_gw }}'
|
|
|
|
# ```
|
|
|
|
#
|
|
|
|
# ### host_vars
|
|
|
|
# ```yml
|
|
|
|
# ---
|
|
|
|
# storage_ip: "192.0.2.91/23"
|
|
|
|
# external_ip: "198.51.100.23/21"
|
|
|
|
# tenant_ip: "203.0.113.77/23"
|
|
|
|
# ```
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## playbook-add.yml example
|
|
|
|
|
|
|
|
---
|
|
|
|
- hosts: openstack-stage
|
|
|
|
remote_user: root
|
|
|
|
tasks:
|
|
|
|
|
2016-12-01 11:17:32 +00:00
|
|
|
- name: install needed network manager libs
|
|
|
|
yum:
|
|
|
|
name: '{{ item }}'
|
|
|
|
state: installed
|
|
|
|
with_items:
|
|
|
|
- NetworkManager-glib
|
|
|
|
- libnm-qt-devel.x86_64
|
|
|
|
- nm-connection-editor.x86_64
|
|
|
|
- libsemanage-python
|
|
|
|
- policycoreutils-python
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
##### Working with all cloud nodes - Teaming
|
2015-05-14 14:45:51 +00:00
|
|
|
- name: try nmcli add team - conn_name only & ip4 gw4
|
2016-12-01 11:17:32 +00:00
|
|
|
nmcli:
|
|
|
|
type: team
|
|
|
|
conn_name: '{{ item.conn_name }}'
|
|
|
|
ip4: '{{ item.ip4 }}'
|
|
|
|
gw4: '{{ item.gw4 }}'
|
|
|
|
state: present
|
2015-05-12 12:10:53 +00:00
|
|
|
with_items:
|
2016-12-01 11:17:32 +00:00
|
|
|
- '{{ nmcli_team }}'
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
- name: try nmcli add teams-slave
|
2016-12-01 11:17:32 +00:00
|
|
|
nmcli:
|
|
|
|
type: team-slave
|
|
|
|
conn_name: '{{ item.conn_name }}'
|
|
|
|
ifname: '{{ item.ifname }}'
|
|
|
|
master: '{{ item.master }}'
|
|
|
|
state: present
|
2015-05-12 12:10:53 +00:00
|
|
|
with_items:
|
2016-12-01 11:17:32 +00:00
|
|
|
- '{{ nmcli_team_slave }}'
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
###### Working with all cloud nodes - Bonding
|
2017-02-07 21:39:24 +00:00
|
|
|
- name: try nmcli add bond - conn_name only & ip4 gw4 mode
|
|
|
|
nmcli:
|
|
|
|
type: bond
|
|
|
|
conn_name: '{{ item.conn_name }}'
|
|
|
|
ip4: '{{ item.ip4 }}'
|
|
|
|
gw4: '{{ item.gw4 }}'
|
|
|
|
mode: '{{ item.mode }}'
|
|
|
|
state: present
|
|
|
|
with_items:
|
|
|
|
- '{{ nmcli_bond }}'
|
2017-01-07 16:50:10 +00:00
|
|
|
|
2017-02-07 21:39:24 +00:00
|
|
|
- name: try nmcli add bond-slave
|
|
|
|
nmcli:
|
|
|
|
type: bond-slave
|
|
|
|
conn_name: '{{ item.conn_name }}'
|
|
|
|
ifname: '{{ item.ifname }}'
|
|
|
|
master: '{{ item.master }}'
|
|
|
|
state: present
|
|
|
|
with_items:
|
|
|
|
- '{{ nmcli_bond_slave }}'
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
##### Working with all cloud nodes - Ethernet
|
2017-01-07 16:50:10 +00:00
|
|
|
- name: nmcli add Ethernet - conn_name only & ip4 gw4
|
|
|
|
nmcli:
|
|
|
|
type: ethernet
|
|
|
|
conn_name: '{{ item.conn_name }}'
|
|
|
|
ip4: '{{ item.ip4 }}'
|
|
|
|
gw4: '{{ item.gw4 }}'
|
|
|
|
state: present
|
|
|
|
with_items:
|
|
|
|
- '{{ nmcli_ethernet }}'
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
## playbook-del.yml example
|
|
|
|
- hosts: openstack-stage
|
|
|
|
remote_user: root
|
|
|
|
tasks:
|
|
|
|
|
|
|
|
- name: try nmcli del team - multiple
|
2016-12-01 11:17:32 +00:00
|
|
|
nmcli:
|
|
|
|
conn_name: '{{ item.conn_name }}'
|
|
|
|
state: absent
|
2015-05-12 12:10:53 +00:00
|
|
|
with_items:
|
2016-12-01 11:17:32 +00:00
|
|
|
- conn_name: em1
|
|
|
|
- conn_name: em2
|
|
|
|
- conn_name: p1p1
|
|
|
|
- conn_name: p1p2
|
|
|
|
- conn_name: p2p1
|
|
|
|
- conn_name: p2p2
|
|
|
|
- conn_name: tenant
|
|
|
|
- conn_name: storage
|
|
|
|
- conn_name: external
|
|
|
|
- conn_name: team-em1
|
|
|
|
- conn_name: team-em2
|
|
|
|
- conn_name: team-p1p1
|
|
|
|
- conn_name: team-p1p2
|
|
|
|
- conn_name: team-p2p1
|
|
|
|
- conn_name: team-p2p2
|
2017-01-07 16:50:10 +00:00
|
|
|
|
2015-05-12 12:10:53 +00:00
|
|
|
# To add an Ethernet connection with static IP configuration, issue a command as follows
|
2017-05-26 14:58:00 +00:00
|
|
|
- nmcli:
|
2016-12-01 11:17:32 +00:00
|
|
|
conn_name: my-eth1
|
|
|
|
ifname: eth1
|
|
|
|
type: ethernet
|
|
|
|
ip4: 192.0.2.100/24
|
|
|
|
gw4: 192.0.2.1
|
|
|
|
state: present
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
# To add an Team connection with static IP configuration, issue a command as follows
|
2017-05-26 14:58:00 +00:00
|
|
|
- nmcli:
|
2017-12-06 13:48:59 +00:00
|
|
|
conn_name: my-team1
|
|
|
|
ifname: my-team1
|
|
|
|
type: team
|
|
|
|
ip4: 192.0.2.100/24
|
|
|
|
gw4: 192.0.2.1
|
|
|
|
state: present
|
|
|
|
autoconnect: yes
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
# Optionally, at the same time specify IPv6 addresses for the device as follows:
|
2017-05-26 14:58:00 +00:00
|
|
|
- nmcli:
|
2017-12-06 13:48:59 +00:00
|
|
|
conn_name: my-eth1
|
|
|
|
ifname: eth1
|
|
|
|
type: ethernet
|
|
|
|
ip4: 192.0.2.100/24
|
|
|
|
gw4: 192.0.2.1
|
|
|
|
ip6: '2001:db8::cafe'
|
|
|
|
gw6: '2001:db8::1'
|
|
|
|
state: present
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
# To add two IPv4 DNS server addresses:
|
2017-05-26 14:58:00 +00:00
|
|
|
- nmcli:
|
2017-12-06 13:48:59 +00:00
|
|
|
conn_name: my-eth1
|
|
|
|
type: ethernet
|
|
|
|
dns4:
|
|
|
|
- 192.0.2.53
|
|
|
|
- 198.51.100.53
|
|
|
|
state: present
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
# To make a profile usable for all compatible Ethernet interfaces, issue a command as follows
|
2017-05-26 14:58:00 +00:00
|
|
|
- nmcli:
|
2017-12-06 13:48:59 +00:00
|
|
|
ctype: ethernet
|
|
|
|
name: my-eth1
|
|
|
|
ifname: '*'
|
|
|
|
state: present
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
# To change the property of a setting e.g. MTU, issue a command as follows:
|
2017-05-26 14:58:00 +00:00
|
|
|
- nmcli:
|
2017-12-06 13:48:59 +00:00
|
|
|
conn_name: my-eth1
|
|
|
|
mtu: 9000
|
|
|
|
type: ethernet
|
|
|
|
state: present
|
2015-05-12 12:10:53 +00:00
|
|
|
|
2017-12-06 13:48:59 +00:00
|
|
|
# nmcli exits with status 0 if it succeeds and exits with a status greater
|
|
|
|
# than zero when there is a failure. The following list of status codes may be
|
|
|
|
# returned:
|
|
|
|
#
|
2017-01-07 16:50:10 +00:00
|
|
|
# - 0 Success - indicates the operation succeeded
|
|
|
|
# - 1 Unknown or unspecified error
|
|
|
|
# - 2 Invalid user input, wrong nmcli invocation
|
|
|
|
# - 3 Timeout expired (see --wait option)
|
|
|
|
# - 4 Connection activation failed
|
|
|
|
# - 5 Connection deactivation failed
|
|
|
|
# - 6 Disconnecting device failed
|
|
|
|
# - 7 Connection deletion failed
|
|
|
|
# - 8 NetworkManager is not running
|
|
|
|
# - 9 nmcli and NetworkManager versions mismatch
|
|
|
|
# - 10 Connection, device, or access point does not exist.
|
2015-05-12 12:10:53 +00:00
|
|
|
'''
|
2017-07-29 09:35:25 +00:00
|
|
|
|
2017-12-07 16:27:06 +00:00
|
|
|
HAVE_DBUS = False
|
2016-09-06 13:11:36 +00:00
|
|
|
try:
|
|
|
|
import dbus
|
2017-12-07 16:27:06 +00:00
|
|
|
HAVE_DBUS = True
|
2016-09-06 13:11:36 +00:00
|
|
|
except ImportError:
|
|
|
|
pass
|
|
|
|
|
2017-12-07 16:27:06 +00:00
|
|
|
HAVE_NM_CLIENT = False
|
2016-09-06 13:11:36 +00:00
|
|
|
try:
|
|
|
|
from gi.repository import NetworkManager, NMClient
|
2017-12-07 16:27:06 +00:00
|
|
|
HAVE_NM_CLIENT = True
|
2016-09-06 13:11:36 +00:00
|
|
|
except ImportError:
|
|
|
|
pass
|
2015-05-12 12:10:53 +00:00
|
|
|
|
2016-10-19 16:45:33 +00:00
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
|
|
|
|
|
|
|
2015-05-12 12:10:53 +00:00
|
|
|
class Nmcli(object):
|
|
|
|
"""
|
|
|
|
This is the generic nmcli manipulation class that is subclassed based on platform.
|
|
|
|
A subclass may wish to override the following action methods:-
|
|
|
|
- create_connection()
|
|
|
|
- delete_connection()
|
|
|
|
- modify_connection()
|
|
|
|
- show_connection()
|
|
|
|
- up_connection()
|
|
|
|
- down_connection()
|
|
|
|
All subclasses MUST define platform and distribution (which may be None).
|
|
|
|
"""
|
|
|
|
|
2017-12-07 16:27:06 +00:00
|
|
|
platform = 'Generic'
|
|
|
|
distribution = None
|
2016-12-09 22:35:55 +00:00
|
|
|
if HAVE_DBUS:
|
2017-12-07 16:27:06 +00:00
|
|
|
bus = dbus.SystemBus()
|
2015-05-12 12:10:53 +00:00
|
|
|
# The following is going to be used in dbus code
|
2017-12-07 16:27:06 +00:00
|
|
|
DEVTYPES = {1: "Ethernet",
|
|
|
|
2: "Wi-Fi",
|
|
|
|
5: "Bluetooth",
|
|
|
|
6: "OLPC",
|
|
|
|
7: "WiMAX",
|
|
|
|
8: "Modem",
|
|
|
|
9: "InfiniBand",
|
|
|
|
10: "Bond",
|
|
|
|
11: "VLAN",
|
|
|
|
12: "ADSL",
|
|
|
|
13: "Bridge",
|
|
|
|
14: "Generic",
|
|
|
|
15: "Team"
|
2015-05-12 12:10:53 +00:00
|
|
|
}
|
2017-12-07 16:27:06 +00:00
|
|
|
STATES = {0: "Unknown",
|
|
|
|
10: "Unmanaged",
|
|
|
|
20: "Unavailable",
|
|
|
|
30: "Disconnected",
|
|
|
|
40: "Prepare",
|
|
|
|
50: "Config",
|
|
|
|
60: "Need Auth",
|
|
|
|
70: "IP Config",
|
|
|
|
80: "IP Check",
|
|
|
|
90: "Secondaries",
|
|
|
|
100: "Activated",
|
|
|
|
110: "Deactivating",
|
|
|
|
120: "Failed"
|
|
|
|
}
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
def __init__(self, module):
|
2017-12-07 16:27:06 +00:00
|
|
|
self.module = module
|
|
|
|
self.state = module.params['state']
|
|
|
|
self.autoconnect = module.params['autoconnect']
|
|
|
|
self.conn_name = module.params['conn_name']
|
|
|
|
self.master = module.params['master']
|
|
|
|
self.ifname = module.params['ifname']
|
|
|
|
self.type = module.params['type']
|
|
|
|
self.ip4 = module.params['ip4']
|
|
|
|
self.gw4 = module.params['gw4']
|
|
|
|
self.dns4 = ' '.join(module.params['dns4'])
|
|
|
|
self.ip6 = module.params['ip6']
|
|
|
|
self.gw6 = module.params['gw6']
|
|
|
|
self.dns6 = module.params['dns6']
|
|
|
|
self.mtu = module.params['mtu']
|
|
|
|
self.stp = module.params['stp']
|
|
|
|
self.priority = module.params['priority']
|
|
|
|
self.mode = module.params['mode']
|
|
|
|
self.miimon = module.params['miimon']
|
|
|
|
self.downdelay = module.params['downdelay']
|
|
|
|
self.updelay = module.params['updelay']
|
|
|
|
self.arp_interval = module.params['arp_interval']
|
|
|
|
self.arp_ip_target = module.params['arp_ip_target']
|
|
|
|
self.slavepriority = module.params['slavepriority']
|
|
|
|
self.forwarddelay = module.params['forwarddelay']
|
|
|
|
self.hellotime = module.params['hellotime']
|
|
|
|
self.maxage = module.params['maxage']
|
|
|
|
self.ageingtime = module.params['ageingtime']
|
|
|
|
self.mac = module.params['mac']
|
|
|
|
self.vlanid = module.params['vlanid']
|
|
|
|
self.vlandev = module.params['vlandev']
|
|
|
|
self.flags = module.params['flags']
|
|
|
|
self.ingress = module.params['ingress']
|
|
|
|
self.egress = module.params['egress']
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
def execute_command(self, cmd, use_unsafe_shell=False, data=None):
|
|
|
|
return self.module.run_command(cmd, use_unsafe_shell=use_unsafe_shell, data=data)
|
|
|
|
|
|
|
|
def merge_secrets(self, proxy, config, setting_name):
|
|
|
|
try:
|
|
|
|
# returns a dict of dicts mapping name::setting, where setting is a dict
|
|
|
|
# mapping key::value. Each member of the 'setting' dict is a secret
|
2017-12-07 16:27:06 +00:00
|
|
|
secrets = proxy.GetSecrets(setting_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
# Copy the secrets into our connection config
|
|
|
|
for setting in secrets:
|
|
|
|
for key in secrets[setting]:
|
2017-12-07 16:27:06 +00:00
|
|
|
config[setting_name][key] = secrets[setting][key]
|
2017-07-29 09:35:25 +00:00
|
|
|
except:
|
2015-05-12 12:10:53 +00:00
|
|
|
pass
|
|
|
|
|
|
|
|
def dict_to_string(self, d):
|
|
|
|
# Try to trivially translate a dictionary's elements into nice string
|
|
|
|
# formatting.
|
2017-12-07 16:27:06 +00:00
|
|
|
dstr = ""
|
2015-05-12 12:10:53 +00:00
|
|
|
for key in d:
|
2017-12-07 16:27:06 +00:00
|
|
|
val = d[key]
|
|
|
|
str_val = ""
|
|
|
|
add_string = True
|
2016-11-09 20:25:17 +00:00
|
|
|
if isinstance(val, dbus.Array):
|
2015-05-12 12:10:53 +00:00
|
|
|
for elt in val:
|
2016-11-09 20:25:17 +00:00
|
|
|
if isinstance(elt, dbus.Byte):
|
2017-12-07 16:27:06 +00:00
|
|
|
str_val += "%s " % int(elt)
|
2016-11-09 20:25:17 +00:00
|
|
|
elif isinstance(elt, dbus.String):
|
2017-12-07 16:27:06 +00:00
|
|
|
str_val += "%s" % elt
|
2016-11-09 20:25:17 +00:00
|
|
|
elif isinstance(val, dbus.Dictionary):
|
2017-12-07 16:27:06 +00:00
|
|
|
dstr += self.dict_to_string(val)
|
|
|
|
add_string = False
|
2015-05-12 12:10:53 +00:00
|
|
|
else:
|
2017-12-07 16:27:06 +00:00
|
|
|
str_val = val
|
2015-05-12 12:10:53 +00:00
|
|
|
if add_string:
|
2017-12-07 16:27:06 +00:00
|
|
|
dstr += "%s: %s\n" % (key, str_val)
|
2015-05-12 12:10:53 +00:00
|
|
|
return dstr
|
|
|
|
|
|
|
|
def connection_to_string(self, config):
|
|
|
|
# dump a connection configuration to use in list_connection_info
|
2017-12-07 16:27:06 +00:00
|
|
|
setting_list = []
|
2015-05-12 12:10:53 +00:00
|
|
|
for setting_name in config:
|
|
|
|
setting_list.append(self.dict_to_string(config[setting_name]))
|
|
|
|
return setting_list
|
2017-07-29 09:35:25 +00:00
|
|
|
# print("")
|
2015-05-12 12:10:53 +00:00
|
|
|
|
2016-08-17 14:32:49 +00:00
|
|
|
def bool_to_string(self, boolean):
|
|
|
|
if boolean:
|
|
|
|
return "yes"
|
|
|
|
else:
|
|
|
|
return "no"
|
|
|
|
|
2015-05-12 12:10:53 +00:00
|
|
|
def list_connection_info(self):
|
|
|
|
# Ask the settings service for the list of connections it provides
|
2017-12-07 16:27:06 +00:00
|
|
|
bus = dbus.SystemBus()
|
2015-05-12 12:10:53 +00:00
|
|
|
|
2017-12-07 16:27:06 +00:00
|
|
|
service_name = "org.freedesktop.NetworkManager"
|
|
|
|
proxy = bus.get_object(service_name, "/org/freedesktop/NetworkManager/Settings")
|
|
|
|
settings = dbus.Interface(proxy, "org.freedesktop.NetworkManager.Settings")
|
|
|
|
connection_paths = settings.ListConnections()
|
|
|
|
connection_list = []
|
2015-05-12 12:10:53 +00:00
|
|
|
# List each connection's name, UUID, and type
|
|
|
|
for path in connection_paths:
|
2017-12-07 16:27:06 +00:00
|
|
|
con_proxy = bus.get_object(service_name, path)
|
|
|
|
settings_connection = dbus.Interface(con_proxy, "org.freedesktop.NetworkManager.Settings.Connection")
|
|
|
|
config = settings_connection.GetSettings()
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
# Now get secrets too; we grab the secrets for each type of connection
|
|
|
|
# (since there isn't a "get all secrets" call because most of the time
|
|
|
|
# you only need 'wifi' secrets or '802.1x' secrets, not everything) and
|
|
|
|
# merge that into the configuration data - To use at a later stage
|
|
|
|
self.merge_secrets(settings_connection, config, '802-11-wireless')
|
|
|
|
self.merge_secrets(settings_connection, config, '802-11-wireless-security')
|
|
|
|
self.merge_secrets(settings_connection, config, '802-1x')
|
|
|
|
self.merge_secrets(settings_connection, config, 'gsm')
|
|
|
|
self.merge_secrets(settings_connection, config, 'cdma')
|
|
|
|
self.merge_secrets(settings_connection, config, 'ppp')
|
|
|
|
|
|
|
|
# Get the details of the 'connection' setting
|
2017-12-07 16:27:06 +00:00
|
|
|
s_con = config['connection']
|
2015-05-12 12:10:53 +00:00
|
|
|
connection_list.append(s_con['id'])
|
|
|
|
connection_list.append(s_con['uuid'])
|
|
|
|
connection_list.append(s_con['type'])
|
|
|
|
connection_list.append(self.connection_to_string(config))
|
|
|
|
return connection_list
|
|
|
|
|
|
|
|
def connection_exists(self):
|
|
|
|
# we are going to use name and type in this instance to find if that connection exists and is of type x
|
2017-12-07 16:27:06 +00:00
|
|
|
connections = self.list_connection_info()
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
for con_item in connections:
|
2017-12-07 16:27:06 +00:00
|
|
|
if self.conn_name == con_item:
|
2015-05-12 12:10:53 +00:00
|
|
|
return True
|
|
|
|
|
|
|
|
def down_connection(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
# if self.connection_exists():
|
|
|
|
cmd.append('con')
|
|
|
|
cmd.append('down')
|
2015-05-14 14:45:51 +00:00
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
return self.execute_command(cmd)
|
|
|
|
|
|
|
|
def up_connection(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
cmd.append('con')
|
|
|
|
cmd.append('up')
|
2015-05-14 14:45:51 +00:00
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
return self.execute_command(cmd)
|
|
|
|
|
|
|
|
def create_connection_team(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
# format for creating team interface
|
|
|
|
cmd.append('con')
|
|
|
|
cmd.append('add')
|
|
|
|
cmd.append('type')
|
|
|
|
cmd.append('team')
|
|
|
|
cmd.append('con-name')
|
2015-05-14 14:45:51 +00:00
|
|
|
if self.conn_name is not None:
|
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
elif self.ifname is not None:
|
|
|
|
cmd.append(self.ifname)
|
|
|
|
cmd.append('ifname')
|
|
|
|
if self.ifname is not None:
|
|
|
|
cmd.append(self.ifname)
|
2015-05-14 14:45:51 +00:00
|
|
|
elif self.conn_name is not None:
|
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
if self.ip4 is not None:
|
|
|
|
cmd.append('ip4')
|
|
|
|
cmd.append(self.ip4)
|
|
|
|
if self.gw4 is not None:
|
|
|
|
cmd.append('gw4')
|
|
|
|
cmd.append(self.gw4)
|
|
|
|
if self.ip6 is not None:
|
|
|
|
cmd.append('ip6')
|
|
|
|
cmd.append(self.ip6)
|
|
|
|
if self.gw6 is not None:
|
|
|
|
cmd.append('gw6')
|
|
|
|
cmd.append(self.gw6)
|
2015-05-14 15:09:49 +00:00
|
|
|
if self.autoconnect is not None:
|
2015-05-12 12:10:53 +00:00
|
|
|
cmd.append('autoconnect')
|
2016-08-17 14:32:49 +00:00
|
|
|
cmd.append(self.bool_to_string(self.autoconnect))
|
2015-05-12 12:10:53 +00:00
|
|
|
return cmd
|
|
|
|
|
|
|
|
def modify_connection_team(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
# format for modifying team interface
|
|
|
|
cmd.append('con')
|
|
|
|
cmd.append('mod')
|
2015-05-14 14:45:51 +00:00
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
if self.ip4 is not None:
|
|
|
|
cmd.append('ipv4.address')
|
|
|
|
cmd.append(self.ip4)
|
|
|
|
if self.gw4 is not None:
|
|
|
|
cmd.append('ipv4.gateway')
|
|
|
|
cmd.append(self.gw4)
|
|
|
|
if self.dns4 is not None:
|
|
|
|
cmd.append('ipv4.dns')
|
|
|
|
cmd.append(self.dns4)
|
|
|
|
if self.ip6 is not None:
|
|
|
|
cmd.append('ipv6.address')
|
|
|
|
cmd.append(self.ip6)
|
|
|
|
if self.gw6 is not None:
|
|
|
|
cmd.append('ipv6.gateway')
|
2016-05-20 12:46:52 +00:00
|
|
|
cmd.append(self.gw6)
|
2015-05-12 12:10:53 +00:00
|
|
|
if self.dns6 is not None:
|
|
|
|
cmd.append('ipv6.dns')
|
|
|
|
cmd.append(self.dns6)
|
2015-05-14 15:09:49 +00:00
|
|
|
if self.autoconnect is not None:
|
2015-05-12 12:10:53 +00:00
|
|
|
cmd.append('autoconnect')
|
2016-08-17 14:32:49 +00:00
|
|
|
cmd.append(self.bool_to_string(self.autoconnect))
|
2015-05-12 12:10:53 +00:00
|
|
|
# Can't use MTU with team
|
|
|
|
return cmd
|
|
|
|
|
|
|
|
def create_connection_team_slave(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
# format for creating team-slave interface
|
|
|
|
cmd.append('connection')
|
|
|
|
cmd.append('add')
|
|
|
|
cmd.append('type')
|
|
|
|
cmd.append(self.type)
|
|
|
|
cmd.append('con-name')
|
2015-05-14 14:45:51 +00:00
|
|
|
if self.conn_name is not None:
|
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
elif self.ifname is not None:
|
|
|
|
cmd.append(self.ifname)
|
|
|
|
cmd.append('ifname')
|
|
|
|
if self.ifname is not None:
|
|
|
|
cmd.append(self.ifname)
|
2015-05-14 14:45:51 +00:00
|
|
|
elif self.conn_name is not None:
|
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
cmd.append('master')
|
2015-05-14 14:45:51 +00:00
|
|
|
if self.conn_name is not None:
|
2015-05-12 12:10:53 +00:00
|
|
|
cmd.append(self.master)
|
|
|
|
# if self.mtu is not None:
|
|
|
|
# cmd.append('802-3-ethernet.mtu')
|
|
|
|
# cmd.append(self.mtu)
|
|
|
|
return cmd
|
|
|
|
|
|
|
|
def modify_connection_team_slave(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
# format for modifying team-slave interface
|
|
|
|
cmd.append('con')
|
|
|
|
cmd.append('mod')
|
2015-05-14 14:45:51 +00:00
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
cmd.append('connection.master')
|
|
|
|
cmd.append(self.master)
|
|
|
|
if self.mtu is not None:
|
|
|
|
cmd.append('802-3-ethernet.mtu')
|
|
|
|
cmd.append(self.mtu)
|
|
|
|
return cmd
|
|
|
|
|
|
|
|
def create_connection_bond(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
# format for creating bond interface
|
|
|
|
cmd.append('con')
|
|
|
|
cmd.append('add')
|
|
|
|
cmd.append('type')
|
|
|
|
cmd.append('bond')
|
|
|
|
cmd.append('con-name')
|
2015-05-14 14:45:51 +00:00
|
|
|
if self.conn_name is not None:
|
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
elif self.ifname is not None:
|
|
|
|
cmd.append(self.ifname)
|
|
|
|
cmd.append('ifname')
|
|
|
|
if self.ifname is not None:
|
|
|
|
cmd.append(self.ifname)
|
2015-05-14 14:45:51 +00:00
|
|
|
elif self.conn_name is not None:
|
|
|
|
cmd.append(self.conn_name)
|
2017-08-17 18:48:58 +00:00
|
|
|
if self.mode is not None:
|
|
|
|
cmd.append('mode')
|
|
|
|
cmd.append(self.mode)
|
2015-05-12 12:10:53 +00:00
|
|
|
if self.ip4 is not None:
|
|
|
|
cmd.append('ip4')
|
|
|
|
cmd.append(self.ip4)
|
|
|
|
if self.gw4 is not None:
|
|
|
|
cmd.append('gw4')
|
|
|
|
cmd.append(self.gw4)
|
|
|
|
if self.ip6 is not None:
|
|
|
|
cmd.append('ip6')
|
|
|
|
cmd.append(self.ip6)
|
|
|
|
if self.gw6 is not None:
|
|
|
|
cmd.append('gw6')
|
|
|
|
cmd.append(self.gw6)
|
2015-05-14 15:09:49 +00:00
|
|
|
if self.autoconnect is not None:
|
2015-05-12 12:10:53 +00:00
|
|
|
cmd.append('autoconnect')
|
2016-08-17 14:32:49 +00:00
|
|
|
cmd.append(self.bool_to_string(self.autoconnect))
|
2015-05-12 12:10:53 +00:00
|
|
|
if self.miimon is not None:
|
|
|
|
cmd.append('miimon')
|
|
|
|
cmd.append(self.miimon)
|
|
|
|
if self.downdelay is not None:
|
|
|
|
cmd.append('downdelay')
|
|
|
|
cmd.append(self.downdelay)
|
|
|
|
if self.downdelay is not None:
|
|
|
|
cmd.append('updelay')
|
|
|
|
cmd.append(self.updelay)
|
|
|
|
if self.downdelay is not None:
|
|
|
|
cmd.append('arp-interval')
|
|
|
|
cmd.append(self.arp_interval)
|
|
|
|
if self.downdelay is not None:
|
|
|
|
cmd.append('arp-ip-target')
|
|
|
|
cmd.append(self.arp_ip_target)
|
|
|
|
return cmd
|
|
|
|
|
|
|
|
def modify_connection_bond(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
# format for modifying bond interface
|
|
|
|
cmd.append('con')
|
|
|
|
cmd.append('mod')
|
2015-05-14 14:45:51 +00:00
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
if self.ip4 is not None:
|
|
|
|
cmd.append('ipv4.address')
|
|
|
|
cmd.append(self.ip4)
|
|
|
|
if self.gw4 is not None:
|
|
|
|
cmd.append('ipv4.gateway')
|
|
|
|
cmd.append(self.gw4)
|
|
|
|
if self.dns4 is not None:
|
|
|
|
cmd.append('ipv4.dns')
|
|
|
|
cmd.append(self.dns4)
|
|
|
|
if self.ip6 is not None:
|
|
|
|
cmd.append('ipv6.address')
|
|
|
|
cmd.append(self.ip6)
|
|
|
|
if self.gw6 is not None:
|
|
|
|
cmd.append('ipv6.gateway')
|
2016-05-20 12:46:52 +00:00
|
|
|
cmd.append(self.gw6)
|
2015-05-12 12:10:53 +00:00
|
|
|
if self.dns6 is not None:
|
|
|
|
cmd.append('ipv6.dns')
|
|
|
|
cmd.append(self.dns6)
|
2015-05-14 15:09:49 +00:00
|
|
|
if self.autoconnect is not None:
|
2015-05-12 12:10:53 +00:00
|
|
|
cmd.append('autoconnect')
|
2016-08-17 14:32:49 +00:00
|
|
|
cmd.append(self.bool_to_string(self.autoconnect))
|
2015-05-12 12:10:53 +00:00
|
|
|
return cmd
|
|
|
|
|
|
|
|
def create_connection_bond_slave(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
# format for creating bond-slave interface
|
|
|
|
cmd.append('connection')
|
|
|
|
cmd.append('add')
|
|
|
|
cmd.append('type')
|
|
|
|
cmd.append('bond-slave')
|
|
|
|
cmd.append('con-name')
|
2015-05-14 14:45:51 +00:00
|
|
|
if self.conn_name is not None:
|
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
elif self.ifname is not None:
|
|
|
|
cmd.append(self.ifname)
|
|
|
|
cmd.append('ifname')
|
|
|
|
if self.ifname is not None:
|
|
|
|
cmd.append(self.ifname)
|
2015-05-14 14:45:51 +00:00
|
|
|
elif self.conn_name is not None:
|
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
cmd.append('master')
|
2015-05-14 14:45:51 +00:00
|
|
|
if self.conn_name is not None:
|
2015-05-12 12:10:53 +00:00
|
|
|
cmd.append(self.master)
|
|
|
|
return cmd
|
|
|
|
|
|
|
|
def modify_connection_bond_slave(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
# format for modifying bond-slave interface
|
|
|
|
cmd.append('con')
|
|
|
|
cmd.append('mod')
|
2015-05-14 14:45:51 +00:00
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
cmd.append('connection.master')
|
|
|
|
cmd.append(self.master)
|
|
|
|
return cmd
|
|
|
|
|
|
|
|
def create_connection_ethernet(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
# format for creating ethernet interface
|
|
|
|
# To add an Ethernet connection with static IP configuration, issue a command as follows
|
2016-12-08 05:34:16 +00:00
|
|
|
# - nmcli: name=add conn_name=my-eth1 ifname=eth1 type=ethernet ip4=192.0.2.100/24 gw4=192.0.2.1 state=present
|
|
|
|
# nmcli con add con-name my-eth1 ifname eth1 type ethernet ip4 192.0.2.100/24 gw4 192.0.2.1
|
2015-05-12 12:10:53 +00:00
|
|
|
cmd.append('con')
|
|
|
|
cmd.append('add')
|
|
|
|
cmd.append('type')
|
|
|
|
cmd.append('ethernet')
|
|
|
|
cmd.append('con-name')
|
2015-05-14 14:45:51 +00:00
|
|
|
if self.conn_name is not None:
|
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
elif self.ifname is not None:
|
|
|
|
cmd.append(self.ifname)
|
|
|
|
cmd.append('ifname')
|
|
|
|
if self.ifname is not None:
|
|
|
|
cmd.append(self.ifname)
|
2015-05-14 14:45:51 +00:00
|
|
|
elif self.conn_name is not None:
|
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
if self.ip4 is not None:
|
|
|
|
cmd.append('ip4')
|
|
|
|
cmd.append(self.ip4)
|
|
|
|
if self.gw4 is not None:
|
|
|
|
cmd.append('gw4')
|
|
|
|
cmd.append(self.gw4)
|
|
|
|
if self.ip6 is not None:
|
|
|
|
cmd.append('ip6')
|
|
|
|
cmd.append(self.ip6)
|
|
|
|
if self.gw6 is not None:
|
|
|
|
cmd.append('gw6')
|
|
|
|
cmd.append(self.gw6)
|
2015-05-14 15:09:49 +00:00
|
|
|
if self.autoconnect is not None:
|
2015-05-12 12:10:53 +00:00
|
|
|
cmd.append('autoconnect')
|
2016-08-17 14:32:49 +00:00
|
|
|
cmd.append(self.bool_to_string(self.autoconnect))
|
2015-05-12 12:10:53 +00:00
|
|
|
return cmd
|
|
|
|
|
|
|
|
def modify_connection_ethernet(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
# format for modifying ethernet interface
|
|
|
|
# To add an Ethernet connection with static IP configuration, issue a command as follows
|
2016-12-08 05:34:16 +00:00
|
|
|
# - nmcli: name=add conn_name=my-eth1 ifname=eth1 type=ethernet ip4=192.0.2.100/24 gw4=192.0.2.1 state=present
|
|
|
|
# nmcli con add con-name my-eth1 ifname eth1 type ethernet ip4 192.0.2.100/24 gw4 192.0.2.1
|
2015-05-12 12:10:53 +00:00
|
|
|
cmd.append('con')
|
|
|
|
cmd.append('mod')
|
2015-05-14 14:45:51 +00:00
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
if self.ip4 is not None:
|
|
|
|
cmd.append('ipv4.address')
|
|
|
|
cmd.append(self.ip4)
|
|
|
|
if self.gw4 is not None:
|
|
|
|
cmd.append('ipv4.gateway')
|
|
|
|
cmd.append(self.gw4)
|
|
|
|
if self.dns4 is not None:
|
|
|
|
cmd.append('ipv4.dns')
|
|
|
|
cmd.append(self.dns4)
|
|
|
|
if self.ip6 is not None:
|
|
|
|
cmd.append('ipv6.address')
|
|
|
|
cmd.append(self.ip6)
|
|
|
|
if self.gw6 is not None:
|
|
|
|
cmd.append('ipv6.gateway')
|
2016-05-20 12:46:52 +00:00
|
|
|
cmd.append(self.gw6)
|
2015-05-12 12:10:53 +00:00
|
|
|
if self.dns6 is not None:
|
|
|
|
cmd.append('ipv6.dns')
|
|
|
|
cmd.append(self.dns6)
|
|
|
|
if self.mtu is not None:
|
|
|
|
cmd.append('802-3-ethernet.mtu')
|
|
|
|
cmd.append(self.mtu)
|
2015-05-14 15:09:49 +00:00
|
|
|
if self.autoconnect is not None:
|
2015-05-12 12:10:53 +00:00
|
|
|
cmd.append('autoconnect')
|
2016-08-17 14:32:49 +00:00
|
|
|
cmd.append(self.bool_to_string(self.autoconnect))
|
2015-05-12 12:10:53 +00:00
|
|
|
return cmd
|
|
|
|
|
|
|
|
def create_connection_bridge(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
# format for creating bridge interface
|
|
|
|
return cmd
|
|
|
|
|
|
|
|
def modify_connection_bridge(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
# format for modifying bridge interface
|
|
|
|
return cmd
|
|
|
|
|
|
|
|
def create_connection_vlan(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
# format for creating ethernet interface
|
|
|
|
return cmd
|
|
|
|
|
|
|
|
def modify_connection_vlan(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
# format for modifying ethernet interface
|
|
|
|
return cmd
|
|
|
|
|
|
|
|
def create_connection(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = []
|
|
|
|
if self.type == 'team':
|
2015-05-12 12:10:53 +00:00
|
|
|
# cmd=self.create_connection_team()
|
|
|
|
if (self.dns4 is not None) or (self.dns6 is not None):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = self.create_connection_team()
|
2015-05-12 12:10:53 +00:00
|
|
|
self.execute_command(cmd)
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = self.modify_connection_team()
|
2015-05-12 12:10:53 +00:00
|
|
|
self.execute_command(cmd)
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = self.up_connection()
|
2015-05-12 12:10:53 +00:00
|
|
|
return self.execute_command(cmd)
|
|
|
|
elif (self.dns4 is None) or (self.dns6 is None):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = self.create_connection_team()
|
2015-05-12 12:10:53 +00:00
|
|
|
return self.execute_command(cmd)
|
2017-12-07 16:27:06 +00:00
|
|
|
elif self.type == 'team-slave':
|
2015-05-12 12:10:53 +00:00
|
|
|
if self.mtu is not None:
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = self.create_connection_team_slave()
|
2015-05-12 12:10:53 +00:00
|
|
|
self.execute_command(cmd)
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = self.modify_connection_team_slave()
|
2015-05-12 12:10:53 +00:00
|
|
|
self.execute_command(cmd)
|
|
|
|
# cmd=self.up_connection()
|
|
|
|
return self.execute_command(cmd)
|
|
|
|
else:
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = self.create_connection_team_slave()
|
2015-05-12 12:10:53 +00:00
|
|
|
return self.execute_command(cmd)
|
2017-12-07 16:27:06 +00:00
|
|
|
elif self.type == 'bond':
|
2015-05-12 12:10:53 +00:00
|
|
|
if (self.mtu is not None) or (self.dns4 is not None) or (self.dns6 is not None):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = self.create_connection_bond()
|
2015-05-12 12:10:53 +00:00
|
|
|
self.execute_command(cmd)
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = self.modify_connection_bond()
|
2015-05-12 12:10:53 +00:00
|
|
|
self.execute_command(cmd)
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = self.up_connection()
|
2015-05-12 12:10:53 +00:00
|
|
|
return self.execute_command(cmd)
|
|
|
|
else:
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = self.create_connection_bond()
|
2015-05-12 12:10:53 +00:00
|
|
|
return self.execute_command(cmd)
|
2017-12-07 16:27:06 +00:00
|
|
|
elif self.type == 'bond-slave':
|
|
|
|
cmd = self.create_connection_bond_slave()
|
|
|
|
elif self.type == 'ethernet':
|
2015-05-12 12:10:53 +00:00
|
|
|
if (self.mtu is not None) or (self.dns4 is not None) or (self.dns6 is not None):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = self.create_connection_ethernet()
|
2015-05-12 12:10:53 +00:00
|
|
|
self.execute_command(cmd)
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = self.modify_connection_ethernet()
|
2015-05-12 12:10:53 +00:00
|
|
|
self.execute_command(cmd)
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = self.up_connection()
|
2015-05-12 12:10:53 +00:00
|
|
|
return self.execute_command(cmd)
|
|
|
|
else:
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = self.create_connection_ethernet()
|
2015-05-12 12:10:53 +00:00
|
|
|
return self.execute_command(cmd)
|
2017-12-07 16:27:06 +00:00
|
|
|
elif self.type == 'bridge':
|
|
|
|
cmd = self.create_connection_bridge()
|
|
|
|
elif self.type == 'vlan':
|
|
|
|
cmd = self.create_connection_vlan()
|
2015-05-12 12:10:53 +00:00
|
|
|
return self.execute_command(cmd)
|
|
|
|
|
|
|
|
def remove_connection(self):
|
|
|
|
# self.down_connection()
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = [self.module.get_bin_path('nmcli', True)]
|
2015-05-12 12:10:53 +00:00
|
|
|
cmd.append('con')
|
|
|
|
cmd.append('del')
|
2015-05-14 14:45:51 +00:00
|
|
|
cmd.append(self.conn_name)
|
2015-05-12 12:10:53 +00:00
|
|
|
return self.execute_command(cmd)
|
|
|
|
|
|
|
|
def modify_connection(self):
|
2017-12-07 16:27:06 +00:00
|
|
|
cmd = []
|
|
|
|
if self.type == 'team':
|
|
|
|
cmd = self.modify_connection_team()
|
|
|
|
elif self.type == 'team-slave':
|
|
|
|
cmd = self.modify_connection_team_slave()
|
|
|
|
elif self.type == 'bond':
|
|
|
|
cmd = self.modify_connection_bond()
|
|
|
|
elif self.type == 'bond-slave':
|
|
|
|
cmd = self.modify_connection_bond_slave()
|
|
|
|
elif self.type == 'ethernet':
|
|
|
|
cmd = self.modify_connection_ethernet()
|
|
|
|
elif self.type == 'bridge':
|
|
|
|
cmd = self.modify_connection_bridge()
|
|
|
|
elif self.type == 'vlan':
|
|
|
|
cmd = self.modify_connection_vlan()
|
2015-05-12 12:10:53 +00:00
|
|
|
return self.execute_command(cmd)
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
# Parsing argument file
|
2017-12-07 16:27:06 +00:00
|
|
|
module = AnsibleModule(
|
2015-05-12 12:10:53 +00:00
|
|
|
argument_spec=dict(
|
2016-08-17 14:32:49 +00:00
|
|
|
autoconnect=dict(required=False, default=None, type='bool'),
|
2015-05-14 14:45:51 +00:00
|
|
|
state=dict(required=True, choices=['present', 'absent'], type='str'),
|
2015-05-14 15:09:49 +00:00
|
|
|
conn_name=dict(required=True, type='str'),
|
2015-05-12 12:10:53 +00:00
|
|
|
master=dict(required=False, default=None, type='str'),
|
|
|
|
ifname=dict(required=False, default=None, type='str'),
|
|
|
|
type=dict(required=False, default=None, choices=['ethernet', 'team', 'team-slave', 'bond', 'bond-slave', 'bridge', 'vlan'], type='str'),
|
|
|
|
ip4=dict(required=False, default=None, type='str'),
|
|
|
|
gw4=dict(required=False, default=None, type='str'),
|
2017-07-10 06:30:02 +00:00
|
|
|
dns4=dict(required=False, default=None, type='list'),
|
2015-05-12 12:10:53 +00:00
|
|
|
ip6=dict(required=False, default=None, type='str'),
|
|
|
|
gw6=dict(required=False, default=None, type='str'),
|
|
|
|
dns6=dict(required=False, default=None, type='str'),
|
|
|
|
# Bond Specific vars
|
2017-03-23 01:50:28 +00:00
|
|
|
mode=dict(require=False, default="balance-rr", type='str', choices=["balance-rr", "active-backup", "balance-xor", "broadcast", "802.3ad",
|
|
|
|
"balance-tlb", "balance-alb"]),
|
2015-05-12 12:10:53 +00:00
|
|
|
miimon=dict(required=False, default=None, type='str'),
|
|
|
|
downdelay=dict(required=False, default=None, type='str'),
|
|
|
|
updelay=dict(required=False, default=None, type='str'),
|
|
|
|
arp_interval=dict(required=False, default=None, type='str'),
|
|
|
|
arp_ip_target=dict(required=False, default=None, type='str'),
|
|
|
|
# general usage
|
|
|
|
mtu=dict(required=False, default=None, type='str'),
|
|
|
|
mac=dict(required=False, default=None, type='str'),
|
|
|
|
# bridge specific vars
|
2016-08-17 14:32:49 +00:00
|
|
|
stp=dict(required=False, default=True, type='bool'),
|
2015-05-12 12:10:53 +00:00
|
|
|
priority=dict(required=False, default="128", type='str'),
|
|
|
|
slavepriority=dict(required=False, default="32", type='str'),
|
|
|
|
forwarddelay=dict(required=False, default="15", type='str'),
|
|
|
|
hellotime=dict(required=False, default="2", type='str'),
|
|
|
|
maxage=dict(required=False, default="20", type='str'),
|
|
|
|
ageingtime=dict(required=False, default="300", type='str'),
|
|
|
|
# vlan specific vars
|
|
|
|
vlanid=dict(required=False, default=None, type='str'),
|
|
|
|
vlandev=dict(required=False, default=None, type='str'),
|
|
|
|
flags=dict(required=False, default=None, type='str'),
|
|
|
|
ingress=dict(required=False, default=None, type='str'),
|
|
|
|
egress=dict(required=False, default=None, type='str'),
|
|
|
|
),
|
|
|
|
supports_check_mode=True
|
|
|
|
)
|
|
|
|
|
2016-09-06 13:11:36 +00:00
|
|
|
if not HAVE_DBUS:
|
|
|
|
module.fail_json(msg="This module requires dbus python bindings")
|
|
|
|
|
|
|
|
if not HAVE_NM_CLIENT:
|
|
|
|
module.fail_json(msg="This module requires NetworkManager glib API")
|
|
|
|
|
2017-12-07 16:27:06 +00:00
|
|
|
nmcli = Nmcli(module)
|
2015-05-12 12:10:53 +00:00
|
|
|
|
2017-12-07 16:27:06 +00:00
|
|
|
rc = None
|
|
|
|
out = ''
|
|
|
|
err = ''
|
|
|
|
result = {}
|
|
|
|
result['conn_name'] = nmcli.conn_name
|
|
|
|
result['state'] = nmcli.state
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
# check for issues
|
2015-05-14 14:45:51 +00:00
|
|
|
if nmcli.conn_name is None:
|
2015-05-12 12:10:53 +00:00
|
|
|
nmcli.module.fail_json(msg="You haven't specified a name for the connection")
|
|
|
|
# team-slave checks
|
2017-12-07 16:27:06 +00:00
|
|
|
if nmcli.type == 'team-slave' and nmcli.master is None:
|
2015-05-12 12:10:53 +00:00
|
|
|
nmcli.module.fail_json(msg="You haven't specified a name for the master so we're not changing a thing")
|
2017-12-07 16:27:06 +00:00
|
|
|
if nmcli.type == 'team-slave' and nmcli.ifname is None:
|
2015-05-12 12:10:53 +00:00
|
|
|
nmcli.module.fail_json(msg="You haven't specified a name for the connection")
|
|
|
|
|
2017-12-07 16:27:06 +00:00
|
|
|
if nmcli.state == 'absent':
|
2015-05-12 12:10:53 +00:00
|
|
|
if nmcli.connection_exists():
|
|
|
|
if module.check_mode:
|
|
|
|
module.exit_json(changed=True)
|
2017-12-07 16:27:06 +00:00
|
|
|
(rc, out, err) = nmcli.down_connection()
|
|
|
|
(rc, out, err) = nmcli.remove_connection()
|
|
|
|
if rc != 0:
|
|
|
|
module.fail_json(name=('No Connection named %s exists' % nmcli.conn_name), msg=err, rc=rc)
|
2015-05-12 12:10:53 +00:00
|
|
|
|
2017-12-07 16:27:06 +00:00
|
|
|
elif nmcli.state == 'present':
|
2015-05-12 12:10:53 +00:00
|
|
|
if nmcli.connection_exists():
|
|
|
|
# modify connection (note: this function is check mode aware)
|
2015-05-14 14:45:51 +00:00
|
|
|
# result['Connection']=('Connection %s of Type %s is not being added' % (nmcli.conn_name, nmcli.type))
|
2017-12-07 16:27:06 +00:00
|
|
|
result['Exists'] = 'Connections do exist so we are modifying them'
|
2015-05-12 12:10:53 +00:00
|
|
|
if module.check_mode:
|
|
|
|
module.exit_json(changed=True)
|
2017-12-07 16:27:06 +00:00
|
|
|
(rc, out, err) = nmcli.modify_connection()
|
2015-05-12 12:10:53 +00:00
|
|
|
if not nmcli.connection_exists():
|
2017-12-07 16:27:06 +00:00
|
|
|
result['Connection'] = ('Connection %s of Type %s is being added' % (nmcli.conn_name, nmcli.type))
|
2015-05-12 12:10:53 +00:00
|
|
|
if module.check_mode:
|
|
|
|
module.exit_json(changed=True)
|
2017-12-07 16:27:06 +00:00
|
|
|
(rc, out, err) = nmcli.create_connection()
|
|
|
|
if rc is not None and rc != 0:
|
2015-05-14 14:45:51 +00:00
|
|
|
module.fail_json(name=nmcli.conn_name, msg=err, rc=rc)
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
if rc is None:
|
2017-12-07 16:27:06 +00:00
|
|
|
result['changed'] = False
|
2015-05-12 12:10:53 +00:00
|
|
|
else:
|
2017-12-07 16:27:06 +00:00
|
|
|
result['changed'] = True
|
2015-05-12 12:10:53 +00:00
|
|
|
if out:
|
2017-12-07 16:27:06 +00:00
|
|
|
result['stdout'] = out
|
2015-05-12 12:10:53 +00:00
|
|
|
if err:
|
2017-12-07 16:27:06 +00:00
|
|
|
result['stderr'] = err
|
2015-05-12 12:10:53 +00:00
|
|
|
|
|
|
|
module.exit_json(**result)
|
|
|
|
|
2017-07-29 09:35:25 +00:00
|
|
|
|
2016-12-05 16:22:51 +00:00
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|