Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions changelog/68574.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Adds `alias` state module back in to core.

Restores the module that had been removed as part of the
community module migration. The associated execution module
had not been migrated.
1 change: 1 addition & 0 deletions doc/ref/states/all/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ state modules
:toctree:
:template: autosummary.rst.tmpl

alias
ansiblegate
apache
apache_conf
Expand Down
5 changes: 5 additions & 0 deletions doc/ref/states/all/salt.states.alias.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
salt.states.alias
=================

.. automodule:: salt.states.alias
:members:
87 changes: 87 additions & 0 deletions salt/states/alias.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"""
Configuration of email aliases

The mail aliases file can be managed to contain definitions for specific email
aliases:

.. code-block:: yaml

username:
alias.present:
- target: [email protected]

.. code-block:: yaml

thomas:
alias.present:
- target: [email protected]

The default alias file is set to ``/etc/aliases``, as defined in Salt's
:mod:`config execution module <salt.modules.config>`. To change the alias
file from the default location, set the following in your minion config:

.. code-block:: yaml

aliases.file: /my/alias/file

"""


def present(name, target):
"""
Ensures that the named alias is present with the given target or list of
targets. If the alias exists but the target differs from the previous
entry, the target(s) will be overwritten. If the alias does not exist, the
alias will be created.

name
The local user/address to assign an alias to

target
The forwarding address
"""
ret = {"name": name, "changes": {}, "result": False, "comment": ""}
if __salt__["aliases.has_target"](name, target):
ret["result"] = True
ret["comment"] = f"Alias {name} already present"
return ret
if __opts__["test"]:
ret["result"] = None
ret["comment"] = f"Alias {name} -> {target} is set to be added"
return ret
if __salt__["aliases.set_target"](name, target):
ret["changes"] = {"alias": name}
ret["result"] = True
ret["comment"] = f"Set email alias {name} -> {target}"
return ret
else:
ret["result"] = False
ret["comment"] = f"Failed to set alias {name} -> {target}"
return ret


def absent(name):
"""
Ensure that the named alias is absent

name
The alias to remove
"""
ret = {"name": name, "changes": {}, "result": False, "comment": ""}
if not __salt__["aliases.get_target"](name):
ret["result"] = True
ret["comment"] = f"Alias {name} already absent"
return ret
if __opts__["test"]:
ret["result"] = None
ret["comment"] = f"Alias {name} is set to be removed"
return ret
if __salt__["aliases.rm_alias"](name):
ret["changes"] = {"alias": name}
ret["result"] = True
ret["comment"] = f"Removed alias {name}"
return ret
else:
ret["result"] = False
ret["comment"] = f"Failed to remove alias {name}"
return ret
167 changes: 167 additions & 0 deletions tests/pytests/unit/states/test_alias.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
"""
unit tests for the alias state
"""

import pytest

import salt.states.alias as alias
from tests.support.mock import MagicMock, patch


@pytest.fixture
def configure_loader_modules():
return {alias: {}}


def test_present_has_target():
"""
test alias.present has target already
"""
name = "saltdude"
target = "[email protected]"
ret = {
"comment": f"Alias {name} already present",
"changes": {},
"name": name,
"result": True,
}

has_target = MagicMock(return_value=True)
with patch.dict(alias.__salt__, {"aliases.has_target": has_target}):
assert alias.present(name, target) == ret


def test_present_has_not_target_test():
"""
test alias.present has not target yet test mode
"""
name = "saltdude"
target = "[email protected]"
ret = {
"comment": f"Alias {name} -> {target} is set to be added",
"changes": {},
"name": name,
"result": None,
}

has_target = MagicMock(return_value=False)
with patch.dict(alias.__salt__, {"aliases.has_target": has_target}):
with patch.dict(alias.__opts__, {"test": True}):
assert alias.present(name, target) == ret


def test_present_set_target():
"""
test alias.present set target
"""
name = "saltdude"
target = "[email protected]"
ret = {
"comment": f"Set email alias {name} -> {target}",
"changes": {"alias": name},
"name": name,
"result": True,
}

has_target = MagicMock(return_value=False)
set_target = MagicMock(return_value=True)
with patch.dict(alias.__salt__, {"aliases.has_target": has_target}):
with patch.dict(alias.__opts__, {"test": False}):
with patch.dict(alias.__salt__, {"aliases.set_target": set_target}):
assert alias.present(name, target) == ret


def test_present_set_target_failed():
"""
test alias.present set target failure
"""
name = "saltdude"
target = "[email protected]"
ret = {
"comment": f"Failed to set alias {name} -> {target}",
"changes": {},
"name": name,
"result": False,
}

has_target = MagicMock(return_value=False)
set_target = MagicMock(return_value=False)
with patch.dict(alias.__salt__, {"aliases.has_target": has_target}):
with patch.dict(alias.__opts__, {"test": False}):
with patch.dict(alias.__salt__, {"aliases.set_target": set_target}):
assert alias.present(name, target) == ret


def test_absent_already_gone():
"""
test alias.absent already gone
"""
name = "saltdude"
ret = {
"comment": f"Alias {name} already absent",
"changes": {},
"name": name,
"result": True,
}

get_target = MagicMock(return_value=False)
with patch.dict(alias.__salt__, {"aliases.get_target": get_target}):
assert alias.absent(name) == ret


def test_absent_not_gone_test():
"""
test alias.absent already gone test mode
"""
name = "saltdude"
ret = {
"comment": f"Alias {name} is set to be removed",
"changes": {},
"name": name,
"result": None,
}

get_target = MagicMock(return_value=True)
with patch.dict(alias.__salt__, {"aliases.get_target": get_target}):
with patch.dict(alias.__opts__, {"test": True}):
assert alias.absent(name) == ret


def test_absent_rm_alias():
"""
test alias.absent remove alias
"""
name = "saltdude"
ret = {
"comment": f"Removed alias {name}",
"changes": {"alias": name},
"name": name,
"result": True,
}

get_target = MagicMock(return_value=True)
rm_alias = MagicMock(return_value=True)
with patch.dict(alias.__salt__, {"aliases.get_target": get_target}):
with patch.dict(alias.__opts__, {"test": False}):
with patch.dict(alias.__salt__, {"aliases.rm_alias": rm_alias}):
assert alias.absent(name) == ret


def test_absent_rm_alias_failed():
"""
test alias.absent remove alias failure
"""
name = "saltdude"
ret = {
"comment": f"Failed to remove alias {name}",
"changes": {},
"name": name,
"result": False,
}

get_target = MagicMock(return_value=True)
rm_alias = MagicMock(return_value=False)
with patch.dict(alias.__salt__, {"aliases.get_target": get_target}):
with patch.dict(alias.__opts__, {"test": False}):
with patch.dict(alias.__salt__, {"aliases.rm_alias": rm_alias}):
assert alias.absent(name) == ret