File: //opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/smartos_nictagadm.py
"""
Module for running nictagadm command on SmartOS
:maintainer: Jorge Schrauwen <sjorge@blackdot.be>
:maturity: new
:depends: nictagadm binary, dladm binary
:platform: smartos
.. versionadded:: 2016.11.0
"""
import logging
import salt.utils.path
import salt.utils.platform
log = logging.getLogger(__name__)
# Function aliases
__func_alias__ = {"list_nictags": "list"}
# Define the module's virtual name
__virtualname__ = "nictagadm"
def __virtual__():
"""
Provides nictagadm on SmartOS
"""
if (
salt.utils.platform.is_smartos_globalzone()
and salt.utils.path.which("dladm")
and salt.utils.path.which("nictagadm")
):
return __virtualname__
return (
False,
f"{__virtualname__} module can only be loaded on SmartOS compute nodes",
)
def list_nictags(include_etherstubs=True):
"""
List all nictags
include_etherstubs : boolean
toggle include of etherstubs
CLI Example:
.. code-block:: bash
salt '*' nictagadm.list
"""
ret = {}
cmd = 'nictagadm list -d "|" -p{}'.format(" -L" if not include_etherstubs else "")
res = __salt__["cmd.run_all"](cmd)
retcode = res["retcode"]
if retcode != 0:
ret["Error"] = (
res["stderr"] if "stderr" in res else "Failed to get list of nictags."
)
else:
header = ["name", "macaddress", "link", "type"]
for nictag in res["stdout"].splitlines():
nictag = nictag.split("|")
nictag_data = {}
for field in header:
nictag_data[field] = nictag[header.index(field)]
ret[nictag_data["name"]] = nictag_data
del ret[nictag_data["name"]]["name"]
return ret
def vms(nictag):
"""
List all vms connect to nictag
nictag : string
name of nictag
CLI Example:
.. code-block:: bash
salt '*' nictagadm.vms admin
"""
ret = {}
cmd = f"nictagadm vms {nictag}"
res = __salt__["cmd.run_all"](cmd)
retcode = res["retcode"]
if retcode != 0:
ret["Error"] = (
res["stderr"] if "stderr" in res else "Failed to get list of vms."
)
else:
ret = res["stdout"].splitlines()
return ret
def exists(*nictag, **kwargs):
"""
Check if nictags exists
nictag : string
one or more nictags to check
verbose : boolean
return list of nictags
CLI Example:
.. code-block:: bash
salt '*' nictagadm.exists admin
"""
ret = {}
if not nictag:
return {"Error": "Please provide at least one nictag to check."}
cmd = "nictagadm exists -l {}".format(" ".join(nictag))
res = __salt__["cmd.run_all"](cmd)
if not kwargs.get("verbose", False):
ret = res["retcode"] == 0
else:
missing = res["stderr"].splitlines()
for nt in nictag:
ret[nt] = nt not in missing
return ret
def add(name, mac, mtu=1500):
"""
Add a new nictag
name : string
name of new nictag
mac : string
mac of parent interface or 'etherstub' to create a ether stub
mtu : int
MTU (ignored for etherstubs)
CLI Example:
.. code-block:: bash
salt '*' nictagadm.add storage0 etherstub
salt '*' nictagadm.add trunk0 'DE:AD:OO:OO:BE:EF' 9000
"""
ret = {}
if mtu > 9000 or mtu < 1500:
return {"Error": "mtu must be a value between 1500 and 9000."}
if mac != "etherstub":
cmd = "dladm show-phys -m -p -o address"
res = __salt__["cmd.run_all"](cmd)
# dladm prints '00' as '0', so account for that.
if mac.replace("00", "0") not in res["stdout"].splitlines():
return {"Error": f"{mac} is not present on this system."}
if mac == "etherstub":
cmd = f"nictagadm add -l {name}"
res = __salt__["cmd.run_all"](cmd)
else:
cmd = f"nictagadm add -p mtu={mtu},mac={mac} {name}"
res = __salt__["cmd.run_all"](cmd)
if res["retcode"] == 0:
return True
else:
return {
"Error": (
"failed to create nictag."
if "stderr" not in res and res["stderr"] == ""
else res["stderr"]
)
}
def update(name, mac=None, mtu=None):
"""
Update a nictag
name : string
name of nictag
mac : string
optional new mac for nictag
mtu : int
optional new MTU for nictag
CLI Example:
.. code-block:: bash
salt '*' nictagadm.update trunk mtu=9000
"""
ret = {}
if name not in list_nictags():
return {"Error": f"nictag {name} does not exists."}
if not mtu and not mac:
return {"Error": "please provide either mac or/and mtu."}
if mtu:
if mtu > 9000 or mtu < 1500:
return {"Error": "mtu must be a value between 1500 and 9000."}
if mac:
if mac == "etherstub":
return {"Error": 'cannot update a nic with "etherstub".'}
else:
cmd = "dladm show-phys -m -p -o address"
res = __salt__["cmd.run_all"](cmd)
# dladm prints '00' as '0', so account for that.
if mac.replace("00", "0") not in res["stdout"].splitlines():
return {"Error": f"{mac} is not present on this system."}
if mac and mtu:
properties = f"mtu={mtu},mac={mac}"
elif mac:
properties = f"mac={mac}" if mac else ""
elif mtu:
properties = f"mtu={mtu}" if mtu else ""
cmd = f"nictagadm update -p {properties} {name}"
res = __salt__["cmd.run_all"](cmd)
if res["retcode"] == 0:
return True
else:
return {
"Error": (
"failed to update nictag."
if "stderr" not in res and res["stderr"] == ""
else res["stderr"]
)
}
def delete(name, force=False):
"""
Delete nictag
name : string
nictag to delete
force : boolean
force delete even if vms attached
CLI Example:
.. code-block:: bash
salt '*' nictagadm.exists admin
"""
ret = {}
if name not in list_nictags():
return True
cmd = "nictagadm delete {}{}".format("-f " if force else "", name)
res = __salt__["cmd.run_all"](cmd)
if res["retcode"] == 0:
return True
else:
return {
"Error": (
"failed to delete nictag."
if "stderr" not in res and res["stderr"] == ""
else res["stderr"]
)
}