Skip to content

Commit

Permalink
Setup TACACS server on ptf for daily work and none TACACS test case (s…
Browse files Browse the repository at this point in the history
…onic-net#13400)

Setup TACACS server on ptf for daily work and none TACACS test case.

Why I did it
Improve TACACS feature coverage.

How I did it
Setup TACACS server on PTF device and bind to port 49.
Because one test bed may run test case in parallel with multiple DUT:
For none TACACS test case, run test case with new TACACS server on port 49.
For TACACS test case, run test case with old TACACS server on port 59.
Force user login with TACACS account, account name is 'admin' password is the value in 'ansible_altpasswords' variable or 'ansible_altpassword' variable.

How to verify it
Pass all test case.
  • Loading branch information
liuh-80 authored and vikshaw-Nokia committed Oct 23, 2024
1 parent 6be845a commit 59f4410
Show file tree
Hide file tree
Showing 16 changed files with 485 additions and 21 deletions.
33 changes: 33 additions & 0 deletions ansible/config_sonic_basedon_testbed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -413,12 +413,27 @@
become: true
when: proxy_env is defined and deploy is defined and deploy|bool == true

- name: Enable PTF tacacs server by default
set_fact:
use_ptf_tacacs_server: true
tacacs_enabled_by_default: true
when: use_ptf_tacacs_server is not defined

- debug: msg="use_ptf_tacacs_server {{ use_ptf_tacacs_server }}"

- block:
- name: saved original minigraph file in SONiC DUT(ignore errors when file does not exist)
shell: mv /etc/sonic/minigraph.xml /etc/sonic/minigraph.xml.orig
become: true
ignore_errors: true

- name: Update TACACS server address to PTF IP
set_fact:
tacacs_servers: ["{{ testbed_facts['ptf_ip'] }}"]
when: use_ptf_tacacs_server is defined and use_ptf_tacacs_server|bool == true

- debug: msg="tacacs_servers {{ tacacs_servers }}"

- name: create new minigraph file for SONiC device
template: src=templates/minigraph_template.j2
dest=/etc/sonic/minigraph.xml
Expand Down Expand Up @@ -606,6 +621,24 @@
ignore_errors: true
when: tacacs_enabled_by_default is defined and tacacs_enabled_by_default|bool == true

- block:
- name: Configure TACACS with PTF TACACS server
become: true
shell: "{{ tacacs_config_cmd }}"
loop:
- config tacacs authtype login
- config aaa authorization tacacs+
- config aaa accounting "tacacs+ local"
loop_control:
loop_var: tacacs_config_cmd
ignore_errors: true

- name: Configure TACACS with PTF TACACS server for MX
become: true
shell: config aaa authorization "tacacs+ local"
when: topo == "mx"
when: use_ptf_tacacs_server is defined and use_ptf_tacacs_server|bool == true

- name: execute configlet application script, which applies configlets in strict order.
become: true
shell: bash "/etc/sonic/apply_clet.sh"
Expand Down
3 changes: 3 additions & 0 deletions ansible/roles/vm_set/tasks/add_topo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@
nic_simulator_action: start
when: topology.host_interfaces_active_active is defined and topology.host_interfaces_active_active|length > 0

- name: Start tacacs+ daily daemon
include_tasks: start_tacacs_daily_daemon.yml

when: container_type == "PTF"

- name: Save PTF image
Expand Down
114 changes: 114 additions & 0 deletions ansible/roles/vm_set/tasks/start_tacacs_daily_daemon.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---
- name: Include tacacs_passkey
block:
- name: Get inventory folder name
set_fact: inv_file="{{ playbook_dir }}/group_vars/{{ inventory_file.split("/")[-1] }}/{{ inventory_file.split("/")[-1] }}.yml"

- debug: msg="inv_file {{ inv_file }}"

- name: Check inventory file exist
stat:
path: "{{ inv_file }}"
register: inventory_file

- name: Include tacacs_passkey from inventory file
include_vars: "{{ inv_file }}"
when: inventory_file.stat.exists

- name: Include default tacacs_passkey
include_vars: "{{ playbook_dir }}/group_vars/lab/lab.yml"
when: tacacs_passkey is not defined

when: tacacs_passkey is not defined

- debug: msg="tacacs_passkey {{ tacacs_passkey }}"

- name: Set ptf host
set_fact:
ptf_host: "ptf_{{ vm_set_name }}"

- debug: msg="ptf_host {{ ptf_host }}"

- name: Include duthost user name
block:
- name: Set duthost user name
set_fact:
dut_host_user: "{{ secret_group_vars['str']['ansible_ssh_user'] }}"

when:
- secret_group_vars is defined
- secret_group_vars['str'] is defined
- secret_group_vars['str']['ansible_ssh_user'] is defined

- name: Set default duthost user name from group_vars/lab/secrets.yml
block:
- name: Include sonicadmin_user from group_vars/lab/secrets.yml
include_vars: "{{ playbook_dir }}/group_vars/lab/secrets.yml"

- name: Set dut user name
set_fact:
dut_host_user: "{{ sonicadmin_user }}"

when:
- dut_host_user is not defined

- debug: msg="dut_host_user {{ dut_host_user }}"

- name: Include duthost password
block:
- name: Encrypt encrypted_sonic_password from secret_group_vars
block:

- name: Encrypt TACACS password from secret_group_vars
shell: python3 -c "import crypt; print(crypt.crypt('{{secret_group_vars['str']['altpasswords'][0]}}', 'abc'))"
register: encrypted_sonic_password
delegate_to: "{{ ptf_host }}"

when:
- secret_group_vars is defined
- secret_group_vars['str'] is defined
- secret_group_vars['str']['altpasswords'] is defined

- name: Encrypt default encrypted_sonic_password from group_vars/lab/secrets.yml
block:
- name: Include sonicadmin_password from group_vars/lab/secrets.yml
include_vars: "{{ playbook_dir }}/group_vars/lab/secrets.yml"

- name: Encrypt TACACS password from sonicadmin_password
shell: python3 -c "import crypt; print(crypt.crypt('{{sonicadmin_password}}', 'abc'))"
register: encrypted_sonic_password
delegate_to: "{{ ptf_host }}"

when:
- tacacs_user_passwd is not defined

- name: Set TACACS password from encrypted_sonic_password
set_fact:
tacacs_user_passwd: '{{ encrypted_sonic_password.stdout }}'

- debug: msg="tacacs_user_passwd {{ tacacs_user_passwd }}"

- block:
- name: Generate tacacs daily daemon config file
template:
src: tac_plus_daily.conf.j2
dest: /etc/tac_plus_daily.conf
delegate_to: "{{ ptf_host }}"

- name: Upload tacacs daily daemon file
copy:
src: 'scripts/tacacs_daily_daemon'
dest: /root/tacacs_daily_daemon
mode: "0755"
delegate_to: "{{ ptf_host }}"

- name: Upload tacacs daily start script
copy:
src: 'scripts/start_tacacs.sh'
dest: /root/start_tacacs.sh
mode: "0755"
delegate_to: "{{ ptf_host }}"

- name: Start tacacs daily daemon
shell: /root/start_tacacs.sh
delegate_to: "{{ptf_host}}"
22 changes: 22 additions & 0 deletions ansible/roles/vm_set/templates/tac_plus_daily.conf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Created by Henry-Nicolas Tourneur(henry.nicolas@tourneur.be)
# See man(5) tac_plus.conf for more details

# Define where to log accounting data, this is the default.

accounting file = /var/log/tac_plus_daily.acct

# This is the key that clients have to use to access Tacacs+

key = {{ tacacs_passkey }}

group = netadmin {
default service = permit
service = exec {
priv-lvl = 15
}
}

user = {{ dut_host_user }} {
login = des {{ tacacs_user_passwd }}
member = netadmin
}
3 changes: 3 additions & 0 deletions ansible/scripts/start_tacacs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

/root/tacacs_daily_daemon &
36 changes: 36 additions & 0 deletions ansible/scripts/tacacs_daily_daemon
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/bin/sh

# This TACACS server need bind to port 49, because SONiC load_minigraph only support port 49
TACPLUS_PORT=49

# Always kill running tac_plus process on port $TACPLUS_PORT to reload config
# It will be start later by tacacs_daily_daemon
TACPLUS_PID=$(ps -ef | grep "tac_plus .* -p $TACPLUS_PORT" | grep -v "grep" | awk '{print $2}')
if [ $TACPLUS_PID ]; then
echo "tac_plus already running on port $TACPLUS_PORT, stop it to reload config"
kill -9 $TACPLUS_PID
fi

# Exit if tacacs_daily_daemon already running
PROCESS_NUM=$(pgrep -l tacacs_daily_daemon | wc -l)
if [ $PROCESS_NUM -ge 1 ]; then
echo "tacacs_daily_daemon already running"
exit 0
fi

# Exit if tacacs_daily_daemon already running in background
# need check -ge3, because every grep command will create a process with same name
PROCESS_NUM=$(ps -ef | grep "/bin/sh .*tacacs_daily_daemon" | grep -v "grep" | wc -l)
if [ $PROCESS_NUM -ge 3 ]; then
echo "tacacs_daily_daemon already running in background" $PROCESS_NUM
exit 0
fi

echo "starting tac_plus for daily work"
while true;
do
# start tac_plus will kill existed tac_plus instance bind to same port
# Enable Authentication/Authorization/Accounting debug by: -d 88
/usr/sbin/tac_plus -d 88 -l /var/log/tac_plus_daily.log -C /etc/tac_plus_daily.conf -p $TACPLUS_PORT -G
echo "tac_plus existed, restarting"
done
1 change: 1 addition & 0 deletions docs/testbed/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@
- [Internal](README.testbed.Internal.md)
- [Kubernetes Setup](README.testbed.k8s.Setup.md)
- [SAI Test Setup](./sai_quality/README.md)
- [TACACS](README.testbed.TACACS.md)
16 changes: 16 additions & 0 deletions docs/testbed/README.testbed.Example.Config.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,21 @@ grep 'vlab-01' -A 2 ./veos_vtb
```
this is the IP for the DUT.

#### DUT user name and password
The DUT may enable TACACS AAA, if you can't login DUT with local user, please find TACACS user name and password by following steps:

##### User name:
```
1. If secret_group_vars['str']['ansible_ssh_user'] defined, the DUT user name is the value of secret_group_vars['str']['ansible_ssh_user']
2. If secret_group_vars['str']['ansible_ssh_user'] not defined, the DUT user name is the value of sonicadmin_user variable defined in group_vars/lab/secrets.yml
```

##### Password:
```
1. If secret_group_vars['str']['altpasswords'] defined, the DUT user name is the value of secret_group_vars['str']['altpasswords'][0]
2. If secret_group_vars['str']['altpasswords'] not defined, the DUT user name is the value of sonicadmin_password variable defined in group_vars/lab/secrets.yml
```


Then, you can use this IP `10.250.0.101` to access that DUT.

Expand Down Expand Up @@ -153,3 +168,4 @@ For this article, some of the reference docs as:
- [```Testbed Configuration```](/docs/testbed/README.testbed.Config.md): Introduction about Testbed configuration, mainly about the testbed.csv (Will be replaced by testbed.yaml).
- [```New Testbed Configuration```](/docs/testbed/README.new.testbed.Configuration.md): Introduction about Testbed configuration, mainly about the Testbed.yaml.
- [```KVM Testbed Setup```](/docs/testbed/README.testbed.VsSetup.md)
- [```Testbed TACACS server```](/docs/testbed/README.testbed.TACACS.md)
Loading

0 comments on commit 59f4410

Please sign in to comment.