Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TACACS+] Add config command for AAA authorization and accounting. #1889

Merged
Merged
38 changes: 38 additions & 0 deletions config/aaa.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,44 @@ def login(auth_protocol):
add_table_kv('AAA', 'authentication', 'login', val)
authentication.add_command(login)

# cmd: aaa authorization
liuh-80 marked this conversation as resolved.
Show resolved Hide resolved
@click.command()
@click.argument('protocol', nargs=-1, type=click.Choice([ "tacacs+", "local", "tacacs+ local"]))
def authorization(protocol):
"""Switch AAA authorization [tacacs+ | local | '\"tacacs+ local\"']"""
if len(protocol) is 0:
click.echo('Argument "protocol" is required')
return

if len(protocol) is 1 and (protocol[0] == 'tacacs+' or protocol[0] == 'local'):
liuh-80 marked this conversation as resolved.
Show resolved Hide resolved
add_table_kv('AAA', 'authorization', 'login', protocol[0])
elif len(protocol) == 1 and protocol[0] == 'tacacs+ local':
add_table_kv('AAA', 'authorization', 'login', 'tacacs+,local')
else:
click.echo('Not a valid command')
aaa.add_command(authorization)

# cmd: aaa accounting
@click.command()
@click.argument('protocol', nargs=-1, type=click.Choice(["disable", "tacacs+", "local", "tacacs+ local"]))
def accounting(protocol):
"""Switch AAA accounting [disable | tacacs+ | local | '\"tacacs+ local\"']"""
if len(protocol) is 0:
click.echo('Argument "protocol" is required')
return

if len(protocol) is 1:
if protocol[0] == 'tacacs+' or protocol[0] == 'local':
add_table_kv('AAA', 'accounting', 'login', protocol[0])
elif protocol[0] == 'tacacs+ local':
add_table_kv('AAA', 'accounting', 'login', 'tacacs+,local')
elif protocol[0] == 'disable':
del_table_key('AAA', 'accounting', 'login')
else:
click.echo('Not a valid command')
else:
click.echo('Not a valid command')
aaa.add_command(accounting)

@click.group()
def tacacs():
Expand Down
10 changes: 10 additions & 0 deletions show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1478,10 +1478,20 @@ def aaa(db):
'authentication': {
'login': 'local (default)',
'failthrough': 'False (default)'
},
'authorization': {
'login': 'local (default)'
},
'accounting': {
'login': 'disable (default)'
}
}
if 'authentication' in data:
aaa['authentication'].update(data['authentication'])
if 'authorization' in data:
aaa['authorization'].update(data['authorization'])
if 'accounting' in data:
aaa['accounting'].update(data['accounting'])
for row in aaa:
entry = aaa[row]
for key in entry:
Expand Down
144 changes: 144 additions & 0 deletions tests/aaa_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,24 @@
show_aaa_default_output="""\
AAA authentication login local (default)
AAA authentication failthrough False (default)
AAA authorization login local (default)
AAA accounting login disable (default)

"""

show_aaa_radius_output="""\
AAA authentication login radius
AAA authentication failthrough False (default)
AAA authorization login local (default)
AAA accounting login disable (default)

"""

show_aaa_radius_local_output="""\
AAA authentication login radius,local
AAA authentication failthrough False (default)
AAA authorization login local (default)
AAA accounting login disable (default)

"""

Expand All @@ -40,6 +46,54 @@
Not a valid command
"""

show_aaa_tacacs_authentication_output="""\
AAA authentication login tacacs+
AAA authentication failthrough False (default)
AAA authorization login local (default)
AAA accounting login disable (default)

"""

show_aaa_tacacs_authorization_output="""\
AAA authentication login tacacs+
AAA authentication failthrough False (default)
AAA authorization login tacacs+
AAA accounting login disable (default)

"""

show_aaa_tacacs_local_authorization_output="""\
AAA authentication login tacacs+
AAA authentication failthrough False (default)
AAA authorization login tacacs+,local
AAA accounting login disable (default)

"""

show_aaa_tacacs_accounting_output="""\
AAA authentication login tacacs+
AAA authentication failthrough False (default)
AAA authorization login tacacs+,local
AAA accounting login tacacs+

"""

show_aaa_tacacs_local_accounting_output="""\
AAA authentication login tacacs+
AAA authentication failthrough False (default)
AAA authorization login tacacs+,local
AAA accounting login tacacs+,local

"""

show_aaa_disable_accounting_output="""\
AAA authentication login tacacs+
AAA authentication failthrough False (default)
AAA authorization login tacacs+,local
AAA accounting login disable

"""

class TestAaa(object):
@classmethod
def setup_class(cls):
Expand Down Expand Up @@ -136,3 +190,93 @@ def test_config_aaa_radius_invalid(self):
assert result.exit_code == 0
assert result.output == config_aaa_not_a_valid_command_output

def test_config_aaa_tacacs(self, get_cmd_module):
(config, show) = get_cmd_module
runner = CliRunner()
db = Db()
db.cfgdb.delete_table("AAA")

# test tacacs authentication
result = runner.invoke(config.config.commands["aaa"],\
["authentication", "login", "tacacs+"], obj=db)
print(result.exit_code)
print(result.output)
assert result.exit_code == 0
assert result.output == config_aaa_empty_output

db.cfgdb.mod_entry("AAA", "authentication", {'login' : 'tacacs+'})

result = runner.invoke(show.cli.commands["aaa"], [], obj=db)
assert result.exit_code == 0
assert result.output == show_aaa_tacacs_authentication_output

# test tacacs authorization
result = runner.invoke(config.config.commands["aaa"],\
["authorization", "tacacs+"], obj=db)
print(result.exit_code)
print(result.output)
assert result.exit_code == 0
assert result.output == config_aaa_empty_output

db.cfgdb.mod_entry("AAA", "authorization", {'login' : 'tacacs+'})

result = runner.invoke(show.cli.commands["aaa"], [], obj=db)
assert result.exit_code == 0
assert result.output == show_aaa_tacacs_authorization_output

# test tacacs + local authorization
result = runner.invoke(config.config.commands["aaa"],\
["authorization", "tacacs+ local"], obj=db)
print(result.exit_code)
print(result.output)
assert result.exit_code == 0
assert result.output == config_aaa_empty_output

db.cfgdb.mod_entry("AAA", "authorization", {'login' : 'tacacs+,local'})

result = runner.invoke(show.cli.commands["aaa"], [], obj=db)
assert result.exit_code == 0
assert result.output == show_aaa_tacacs_local_authorization_output

# test tacacs accounting
result = runner.invoke(config.config.commands["aaa"],\
["accounting", "tacacs+"], obj=db)
print(result.exit_code)
print(result.output)
assert result.exit_code == 0
assert result.output == config_aaa_empty_output

db.cfgdb.mod_entry("AAA", "accounting", {'login' : 'tacacs+'})

result = runner.invoke(show.cli.commands["aaa"], [], obj=db)
assert result.exit_code == 0
assert result.output == show_aaa_tacacs_accounting_output

# test tacacs + local accounting
result = runner.invoke(config.config.commands["aaa"],\
["accounting", "tacacs+ local"], obj=db)
print(result.exit_code)
print(result.output)
assert result.exit_code == 0
assert result.output == config_aaa_empty_output

db.cfgdb.mod_entry("AAA", "accounting", {'login' : 'tacacs+,local'})

result = runner.invoke(show.cli.commands["aaa"], [], obj=db)
assert result.exit_code == 0
assert result.output == show_aaa_tacacs_local_accounting_output

# test disable accounting
result = runner.invoke(config.config.commands["aaa"],\
["accounting", "disable"], obj=db)
print(result.exit_code)
print(result.output)
assert result.exit_code == 0
assert result.output == config_aaa_empty_output

db.cfgdb.mod_entry("AAA", "accounting", {'login' : 'disable'})

result = runner.invoke(show.cli.commands["aaa"], [], obj=db)
assert result.exit_code == 0
assert result.output == show_aaa_disable_accounting_output