Mini Shell
"""
State module for Cisco NX-OS Switch Proxy and Native minions
.. versionadded:: 2016.11.0
For documentation on setting up the nxos proxy minion look in the documentation
for :mod:`salt.proxy.nxos<salt.proxy.nxos>`.
"""
import re
def __virtual__():
if "nxos.get_user" in __salt__:
return True
return (False, "nxos module could not be loaded")
def user_present(
name,
password=None,
roles=None,
encrypted=False,
crypt_salt=None,
algorithm="sha256",
):
"""
Ensure a user is present with the specified groups
name
Name of user
password
Encrypted or Plain Text password for user
roles
List of roles the user should be assigned. Any roles not in this list will be removed
encrypted
Whether the password is encrypted already or not. Defaults to False
crypt_salt
Salt to use when encrypting the password. Default is None (salt is
randomly generated for unhashed passwords)
algorithm
Algorithm to use for hashing password. Defaults to sha256.
Accepts md5, blowfish, sha256, sha512
.. note: sha512 may make the hash too long to save in NX OS which limits the has to 64 characters
Examples:
.. code-block:: yaml
create:
nxos.user_present:
- name: daniel
- roles:
- vdc-admin
set_password:
nxos.user_present:
- name: daniel
- password: admin
- roles:
- network-admin
update:
nxos.user_present:
- name: daniel
- password: AiN9jaoP
- roles:
- network-admin
- vdc-admin
"""
ret = {"name": name, "result": False, "changes": {}, "comment": ""}
change_password = False
if password is not None:
change_password = not __salt__["nxos.check_password"](
name, password, encrypted=encrypted
)
change_roles = False
if roles is not None:
cur_roles = __salt__["nxos.get_roles"](name)
change_roles = set(roles) != set(cur_roles)
old_user = __salt__["nxos.get_user"](name)
if not any([change_password, change_roles, not old_user]):
ret["result"] = True
ret["comment"] = "User already exists"
return ret
if change_roles is True:
remove_roles = set(cur_roles) - set(roles)
add_roles = set(roles) - set(cur_roles)
if __opts__["test"] is True:
ret["result"] = None
if not old_user:
ret["comment"] = "User will be created"
if password is not None:
ret["changes"]["password"] = True
if roles is not None:
ret["changes"]["role"] = {
"add": roles,
"remove": [],
}
return ret
if change_password is True:
ret["comment"] = "User will be updated"
ret["changes"]["password"] = True
if change_roles is True:
ret["comment"] = "User will be updated"
ret["changes"]["roles"] = {
"add": list(add_roles),
"remove": list(remove_roles),
}
return ret
if change_password is True:
new_user = __salt__["nxos.set_password"](
name,
password,
encrypted=encrypted,
role=roles[0] if roles else None,
crypt_salt=crypt_salt,
algorithm=algorithm,
)
ret["changes"]["password"] = {
"new": new_user,
"old": old_user,
}
if change_roles is True:
for role in add_roles:
__salt__["nxos.set_role"](name, role)
for role in remove_roles:
__salt__["nxos.unset_role"](name, role)
ret["changes"]["roles"] = {
"new": __salt__["nxos.get_roles"](name),
"old": cur_roles,
}
correct_password = True
if password is not None:
correct_password = __salt__["nxos.check_password"](
name, password, encrypted=encrypted
)
correct_roles = True
if roles is not None:
cur_roles = __salt__["nxos.get_roles"](name)
correct_roles = set(roles) == set(cur_roles)
if not correct_roles:
ret["comment"] = "Failed to set correct roles"
elif not correct_password:
ret["comment"] = "Failed to set correct password"
else:
ret["comment"] = "User set correctly"
ret["result"] = True
return ret
def user_absent(name):
"""
Ensure a user is not present
name
username to remove if it exists
Examples:
.. code-block:: yaml
delete:
nxos.user_absent:
- name: daniel
"""
ret = {"name": name, "result": False, "changes": {}, "comment": ""}
old_user = __salt__["nxos.get_user"](name)
if not old_user:
ret["result"] = True
ret["comment"] = "User does not exist"
return ret
if __opts__["test"] is True and old_user:
ret["result"] = None
ret["comment"] = "User will be removed"
ret["changes"]["old"] = old_user
ret["changes"]["new"] = ""
return ret
__salt__["nxos.remove_user"](name)
if __salt__["nxos.get_user"](name):
ret["comment"] = "Failed to remove user"
else:
ret["result"] = True
ret["comment"] = "User removed"
ret["changes"]["old"] = old_user
ret["changes"]["new"] = ""
return ret
def config_present(name):
"""
Ensure a specific configuration line exists in the running config
name
config line to set
Examples:
.. code-block:: yaml
add snmp group:
nxos.config_present:
- names:
- snmp-server community randoSNMPstringHERE group network-operator
- snmp-server community AnotherRandomSNMPSTring group network-admin
add snmp acl:
nxos.config_present:
- names:
- snmp-server community randoSNMPstringHERE use-acl snmp-acl-ro
- snmp-server community AnotherRandomSNMPSTring use-acl snmp-acl-rw
"""
ret = {"name": name, "result": False, "changes": {}, "comment": ""}
matches = __salt__["nxos.find"](name)
if matches:
ret["result"] = True
ret["comment"] = "Config is already set"
elif __opts__["test"] is True:
ret["result"] = None
ret["comment"] = "Config will be added"
ret["changes"]["new"] = name
else:
__salt__["nxos.config"](name)
matches = __salt__["nxos.find"](name)
if matches:
ret["result"] = True
ret["comment"] = "Successfully added config"
ret["changes"]["new"] = name
else:
ret["result"] = False
ret["comment"] = "Failed to add config"
return ret
def config_absent(name):
"""
Ensure a specific configuration line does not exist in the running config
name
config line to remove
Examples:
.. code-block:: yaml
add snmp group:
nxos.config_absent:
- names:
- snmp-server community randoSNMPstringHERE group network-operator
- snmp-server community AnotherRandomSNMPSTring group network-admin
.. note::
For certain cases extra lines could be removed based on dependencies.
In this example, included after the example for config_present, the
ACLs would be removed because they depend on the existence of the
group.
"""
ret = {"name": name, "result": False, "changes": {}, "comment": ""}
matches = __salt__["nxos.find"](name)
if not matches:
ret["result"] = True
ret["comment"] = "Config is already absent"
elif __opts__["test"] is True:
ret["result"] = None
ret["comment"] = "Config will be removed"
ret["changes"]["new"] = name
else:
__salt__["nxos.delete_config"](name)
matches = __salt__["nxos.find"](name)
if not matches:
ret["result"] = True
ret["comment"] = "Successfully deleted config"
ret["changes"]["new"] = name
else:
ret["result"] = False
ret["comment"] = "Failed to delete config"
return ret
def replace(name, repl, full_match=False):
"""
Replace all instances of a string or full line in the running config
name
String to replace
repl
The replacement text
full_match
Whether `name` will match the full line or only a subset of the line.
Defaults to False. When False, .* is added around `name` for matching
in the `show run` config.
Examples:
.. code-block:: yaml
replace snmp string:
nxos.replace:
- name: randoSNMPstringHERE
- repl: NEWrandoSNMPstringHERE
replace full snmp string:
nxos.replace:
- name: ^snmp-server community randoSNMPstringHERE group network-operator$
- repl: snmp-server community NEWrandoSNMPstringHERE group network-operator
- full_match: True
.. note::
The first example will replace the SNMP string on both the group and
the ACL, so you will not lose the ACL setting. Because the second is
an exact match of the line, when the group is removed, the ACL is
removed, but not readded, because it was not matched.
"""
ret = {"name": name, "result": False, "changes": {}, "comment": ""}
if full_match is False:
search = f"^.*{name}.*$"
else:
search = name
matches = __salt__["nxos.find"](search)
if not matches:
ret["result"] = True
ret["comment"] = "Nothing found to replace"
return ret
if __opts__["test"] is True:
ret["result"] = None
ret["comment"] = "Configs will be changed"
ret["changes"]["old"] = matches
ret["changes"]["new"] = [re.sub(name, repl, match) for match in matches]
return ret
ret["changes"] = __salt__["nxos.replace"](name, repl, full_match=full_match)
matches = __salt__["nxos.find"](search)
if matches:
ret["result"] = False
ret["comment"] = f'Failed to replace all instances of "{name}"'
else:
ret["result"] = True
ret["comment"] = 'Successfully replaced all instances of "{}" with "{}"'.format(
name, repl
)
return ret
Zerion Mini Shell 1.0