Skip to content

Commit 6c00094

Browse files
committed
initial commit
0 parents  commit 6c00094

19 files changed

+1251
-0
lines changed

.gitignore

+148
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# OS generated files #
2+
######################
3+
.DS_Store
4+
.DS_Store?
5+
._*
6+
.Spotlight-V100
7+
.Trashes
8+
ehthumbs.db
9+
Thumbs.db
10+
11+
# Byte-compiled / optimized / DLL files
12+
__pycache__/
13+
*.py[cod]
14+
*$py.class
15+
16+
# C extensions
17+
*.so
18+
19+
# Distribution / packaging
20+
.Python
21+
build/
22+
develop-eggs/
23+
dist/
24+
downloads/
25+
eggs/
26+
.eggs/
27+
lib/
28+
lib64/
29+
parts/
30+
sdist/
31+
var/
32+
wheels/
33+
share/python-wheels/
34+
*.egg-info/
35+
.installed.cfg
36+
*.egg
37+
MANIFEST
38+
39+
# PyInstaller
40+
# Usually these files are written by a python script from a template
41+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
42+
*.manifest
43+
*.spec
44+
45+
# Installer logs
46+
pip-log.txt
47+
pip-delete-this-directory.txt
48+
49+
# Unit test / coverage reports
50+
htmlcov/
51+
.tox/
52+
.nox/
53+
.coverage
54+
.coverage.*
55+
.cache
56+
nosetests.xml
57+
coverage.xml
58+
*.cover
59+
*.py,cover
60+
.hypothesis/
61+
.pytest_cache/
62+
cover/
63+
64+
# Translations
65+
*.mo
66+
*.pot
67+
68+
# Django stuff:
69+
*.log
70+
local_settings.py
71+
db.sqlite3
72+
db.sqlite3-journal
73+
74+
# Flask stuff:
75+
instance/
76+
.webassets-cache
77+
78+
# Scrapy stuff:
79+
.scrapy
80+
81+
# Sphinx documentation
82+
docs/_build/
83+
84+
# PyBuilder
85+
.pybuilder/
86+
target/
87+
88+
# Jupyter Notebook
89+
.ipynb_checkpoints
90+
91+
# IPython
92+
profile_default/
93+
ipython_config.py
94+
95+
# pyenv
96+
# For a library or package, you might want to ignore these files since the code is
97+
# intended to run in multiple environments; otherwise, check them in:
98+
# .python-version
99+
100+
# pipenv
101+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
102+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
103+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
104+
# install all needed dependencies.
105+
#Pipfile.lock
106+
107+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
108+
__pypackages__/
109+
110+
# Celery stuff
111+
celerybeat-schedule
112+
celerybeat.pid
113+
114+
# SageMath parsed files
115+
*.sage.py
116+
117+
# Environments
118+
.env
119+
.venv
120+
env/
121+
venv/
122+
ENV/
123+
env.bak/
124+
venv.bak/
125+
126+
# Spyder project settings
127+
.spyderproject
128+
.spyproject
129+
130+
# Rope project settings
131+
.ropeproject
132+
133+
# mkdocs documentation
134+
/site
135+
136+
# mypy
137+
.mypy_cache/
138+
.dmypy.json
139+
dmypy.json
140+
141+
# Pyre type checker
142+
.pyre/
143+
144+
# pytype static type analyzer
145+
.pytype/
146+
147+
# Cython debug symbols
148+
cython_debug/

00_deployment_info.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# 00_deployment_info.py
2+
#
3+
# This script will gather deployment info from your ISE instance. Some of this may be interesting to you,
4+
# but mostly it's just informational. I may modify this playbook in the future to gather
5+
# some useful info that can be used by subsequent playbooks (policy and rule IDs),
6+
# or maybe gather all of the data that we configure for comparison
7+
8+
import yaml # import pyyaml package
9+
10+
# open the credentials yaml file and load it into data
11+
with open('credentials.yaml') as f:
12+
data = yaml.safe_load(f)
13+
14+
# Pull in the Cisco ISE SDK
15+
from ciscoisesdk import IdentityServicesEngineAPI
16+
17+
# define our API with credentials from credentials.yaml
18+
api = IdentityServicesEngineAPI(username=data['ise_username'],
19+
password=data['ise_password'],
20+
uses_api_gateway=True,
21+
base_url='https://' + data['ise_hostname'],
22+
version=data['ise_version'],
23+
verify=data['ise_verify'])
24+
25+
# Get our deployment version and put it in a variable
26+
ise_deployment_version = api.pull_deployment_info.get_version()
27+
28+
# Print the variable plus some deep thoughts
29+
print("Suck it, Python " + ise_deployment_version.text)

01_add_groups.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# 01_add_groups.py
2+
#
3+
# This file will create user identity groups in the internal ISE identity store.
4+
# You should not need to modify this file as it will dynamically read all of the groups
5+
# from groupsandusers.yaml.
6+
7+
import yaml # import pyyaml package
8+
9+
# open the credentials.yaml file and load it into data
10+
with open('credentials.yaml') as f:
11+
data = yaml.safe_load(f)
12+
13+
# open the groupsandusers.yaml file and load it into groups
14+
with open('groupsandusers.yaml') as g:
15+
groups = yaml.safe_load(g)
16+
17+
# Pull in the Cisco ISE SDK
18+
from ciscoisesdk import IdentityServicesEngineAPI
19+
20+
# define our API with credentials from credentials.yaml
21+
api = IdentityServicesEngineAPI(username=data['ise_username'],
22+
password=data['ise_password'],
23+
uses_api_gateway=True,
24+
base_url='https://' + data['ise_hostname'],
25+
version=data['ise_version'],
26+
verify=data['ise_verify'])
27+
28+
# iterate through the list of groups and create them using the information in credentials.yaml
29+
for groupname in groups['usergroups']:
30+
api.identity_groups.create_identity_group(name=groupname['name'],
31+
description=groupname['desc'],
32+
parent="NAC Group:NAC:IdentityGroups:User Identity Groups")
33+
print("Creating group:", groupname['name'])

02_add_users.py

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# 02_add_users.py
2+
#
3+
# This file will create users and assign them to the appropriate groups. It should be run after
4+
# 01_add_groups.py as it will query ISE for the created groups and their corresponding ids.
5+
# You should not need to modify this file as it will dynamically read all of the users and groups
6+
# from groupsandusers.yaml.
7+
#
8+
# The group name to group id matching and variable assignment is kind of irritating, but.....
9+
#
10+
# Actually it's more that ISE requires a group id instead of a group name when creating a user.
11+
12+
import yaml # import pyyaml package
13+
14+
# open the yaml file and load it into data
15+
with open('credentials.yaml') as f:
16+
data = yaml.safe_load(f)
17+
18+
# open the groupsandusers.yaml file and load it into groups
19+
with open('groupsandusers.yaml') as g:
20+
groups = yaml.safe_load(g)
21+
22+
# Pull in the Cisco ISE SDK
23+
from ciscoisesdk import IdentityServicesEngineAPI
24+
25+
# define our API
26+
api = IdentityServicesEngineAPI(username=data['ise_username'],
27+
password=data['ise_password'],
28+
uses_api_gateway=True,
29+
base_url='https://' + data['ise_hostname'],
30+
version=data['ise_version'],
31+
verify=data['ise_verify'])
32+
33+
# We're going to iterate through the list of users and create them using the information in credentials.yaml,
34+
# but first we need to get the group id for each group
35+
for groupname in groups['userlist']:
36+
groupinfo = api.identity_groups.get_identity_group_by_name(name=groupname['groups']).response
37+
groupid = groupinfo.IdentityGroup.id
38+
api.internal_user.create_internal_user(name=groupname['name'],
39+
first_name=groupname['firstname'],
40+
last_name=groupname['lastname'],
41+
description=groupname['description'],
42+
password=groups['default_password'],
43+
password_idstore="Internal Users")
44+
print("Creating user:", groupname['name'])

03_create_tacacs_profiles.py

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# 03_create_tacacs_profiles.py
2+
#
3+
# This file will create a TACACS profile and command set that will be assigned to authenticated users.
4+
# For the purposes of this repo, the profile and command set are basic. It will simply assign privilege
5+
# 15 and allow all commands for an authenticated user.
6+
7+
import yaml # import pyyaml package
8+
9+
# open the yaml file and load it into data
10+
with open('credentials.yaml') as f:
11+
data = yaml.safe_load(f)
12+
13+
# Pull in the Cisco ISE SDK
14+
from ciscoisesdk import IdentityServicesEngineAPI
15+
16+
# define our API
17+
api = IdentityServicesEngineAPI(username=data['ise_username'],
18+
password=data['ise_password'],
19+
uses_api_gateway=True,
20+
base_url='https://' + data['ise_hostname'],
21+
version=data['ise_version'],
22+
verify=data['ise_verify'])
23+
24+
25+
# Define our session attributes to send TACACS privilege 15
26+
# I broke this out to separate lines to silence John
27+
#
28+
# Also, since we're name-dropping in comments, shoutout to Sue
29+
#
30+
# https://twitter.com/sueinphilly/status/1457748734218055686?s=20
31+
#
32+
# 10 REM For Sue
33+
# 20 PRINT Hi Sue
34+
# 30 GOTO 20
35+
36+
attributes = {"sessionAttributeList": [{"type": "MANDATORY",
37+
"name": "priv-lvl",
38+
"value": "15"},
39+
{"type": "MANDATORY",
40+
"name": "max_priv_lvl",
41+
"value": "15"}]}
42+
43+
# Create a new TACACS profile called "PermitAllShell" which will give TACACS privilege 15
44+
api.tacacs_profile.create_tacacs_profile(name="PermitAllShell",
45+
description="Permit all",
46+
session_attributes=attributes
47+
)
48+
49+
# Create a new TACACS command set called "PermitAllCommands" which will allow all commands
50+
api.tacacs_command_sets.create_tacacs_command_sets(name="PermitAllCommands",
51+
description="PermitAllCommands Command Set",
52+
permit_unmatched=True
53+
)

04_change_tacacs_authc_source.py

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# 04_change_tacacs_authc_source.py
2+
#
3+
# This file will simply change the identity source of the default device administration policy to use
4+
# internal users instead of all user stores
5+
#
6+
# It's not strictly necessary to do this, but it can sometimes speed up authc for a lab environment
7+
# that isn't talking to an AD or LDAP for device administrator user information.
8+
#
9+
# This was also the second most annoying script to develop because there are two settings that we need
10+
# from ISE (policy id and rule id) in order to change the setting. ISE's API also required a bunch of
11+
# seemingly random fields to be sent all so we can set this: identitySourceName: "Internal Users"
12+
13+
import yaml # import pyyaml package
14+
15+
# open the yaml file and load it into data
16+
with open('credentials.yaml') as f:
17+
data = yaml.safe_load(f)
18+
19+
# Pull in the Cisco ISE SDK
20+
from ciscoisesdk import IdentityServicesEngineAPI
21+
22+
# define our API
23+
api = IdentityServicesEngineAPI(username=data['ise_username'],
24+
password=data['ise_password'],
25+
uses_api_gateway=True,
26+
base_url='https://' + data['ise_hostname'],
27+
version=data['ise_version'],
28+
verify=data['ise_verify'])
29+
30+
# First we have to get the information for all device admin policy sets
31+
policysets = api.device_administration_policy_set.get_device_admin_policy_sets()
32+
33+
# Then we have to pull the policy ID for the Default policy set
34+
policyId = policysets.response.response[0].id
35+
36+
# Then we use the policy ID to grab all of the device administration authc rules
37+
rulesets = api.device_administration_authentication_rules.get_device_admin_authentication_rules(policy_id=policyId)
38+
39+
# And finally we pull the rule ID from the "Default" policy set rule
40+
ruleId = rulesets.response.response[0].rule.id
41+
42+
# But wait, the ISE API needs some mandatory fields for some reason
43+
mandatorydata = {
44+
"default": True,
45+
"name": "Default"
46+
}
47+
48+
# And now, after all of that work, we can change the identity source in the default authc policy to "Internal Users"
49+
api.device_administration_authentication_rules.update_device_admin_authentication_rule_by_id(id=ruleId,
50+
policy_id=policyId,
51+
rule=mandatorydata,
52+
identity_source_name="Internal Users")

0 commit comments

Comments
 (0)