Create a Post
cancel
Showing results for 
Search instead for 
Did you mean: 
Bob_Zimmerman
Authority
Authority
Jump to solution

VSX, clish, and bash?

Is there some way to start clish in a particular VSID? I'm tired of switching into a context, doing some troubleshooting, then going into clish to check OSPF neighbors and winding up in VS0.

1 Solution

Accepted Solutions
Bob_Zimmerman
Authority
Authority

And of course, posting that shook loose the realization that it still kind of sucks. Improved version!

#!/bin/env bash
clishScript=$(mktemp)
vsid="$1"
if [[ $vsid =~ '^[0-9]*$' ]];then shift;else vsid=$(cat /proc/self/nsid);fi
echo "set virtual-system ${vsid}" >${clishScript}
echo "$@" >>${clishScript}
clish -f "${clishScript}" | sed -E 's/^Processing .+?\r//g'
rm "${clishScript}"

Now, instead of assuming VS 0, it assumes the VS you're currently in.

[Expert@SomeVsxMember:0 STANDBY]# ./vsClish.sh show router-id
Context is set to vsid 0

Router ID:  10.16.32.64

Done.
[Expert@SomeVsxMember:0 STANDBY]# vsenv 2
Context is set to Virtual Device SomeVsxMember_VsName2 (ID 2).
[Expert@ SomeVsxMember:2 STANDBY]# ./vsClish.sh show router-id
Context is set to vsid 2

Router ID:  10.20.40.80

Done.

Running in a VS you aren't currently in still just takes specifying the VSID as the first argument.

View solution in original post

24 Replies
JozkoMrkvicka
Authority
Authority

set your account as /bin/bash (set user xxx shell /bin/bash)

then once you log in, you are in expert mode.

going into different VSID: vsenv <ID>

checking clish commands: clish -c "<clish command here>" (quotes are part of command)

Kind regards,
Jozko Mrkvicka
Bob_Zimmerman
Authority
Authority

That is, roughly speaking, how I work right now. I don’t know of a way to enter clish for the context I am currently using in bash, though. I don’t see any command line argument for it, and clish clearly ignores /proc/self/vrf when launching a new instance.

clish -c “someCommand” is nice … for running things in VS0. Running multi-line commands like that is irritating, and since clish always goes to VS0 when it launches, all commands in particular VSs would be multi-line.

I’m looking for a way to get into clish for the context I’m currently set to in bash (the other way around would also be good, but less useful to me).

Wolfgang
Authority
Authority

@Bob_Zimmerman 

„set virtual-system VSID“ in clish changes  your context.

Another option is to write your needed commands in a small script in the first line with setting the right context and then execute these script via „clish -f filename“ from bash.

Wolfgang

Bob_Zimmerman
Authority
Authority

I'm aware of how to change the context once in clish. I'm asking for a way to avoid needing to do that.

I'm already in the VS. How do I get clish to recognize this rather than going all amnesiac? For example, if I run:

 

vsenv 2

clish -c "show ospf neighbors"

 

... it shows me the OSPF neighbors for VS0. In what universe is that expected or rational behavior?

Obviously the right thing to do would be for clish to pay attention to the contents of /proc/self/vrf when it launches and to run in that context. Further, it should do the vsenv stuff in the background when you change VSs in it so if you change VSs in bash, enter clish, change to another VS, then exit clish, your bash session will be in the VS you were in in clish. If there was a way to specify on the command line that I want a clish session in <VSID>, that would be acceptable (though still less than ideal), because I could just alias 'clish' to add '-v $(cat /proc/self/vrf)' to the invocation.

Maarten_Sjouw
Champion
Champion

Use clish -f and put your most used commands in some specific txt files that you can simply call like:
clish -f ospfneighbors

On top of that you can use @HeikoAnkenbrand's trick to create a separate command that will use clish -f for a single command, to be found here. 

Regards, Maarten
Wolfgang
Authority
Authority

@Bob_Zimmerman

I understand your pain but it's how it works.

Following @Maarten_Sjouw idea using @HeikoAnkenbrand rewrite....

Create a new "c" script for every context you need:

##############################################

echo "echo set virtual-system 4 > /var/log/clish.txt" > /bin/c4
echo "echo \$@ >> /var/log/clish.txt" >> /bin/c4
echo "clish -f /var/log/clish.txt" >> /bin/c4
chmod 770 /bin/c4

##############################################

Now you can execute with "c4" any clish command in VS context 4. Do the same for every other context.

Wolfgang

 

Bob_Zimmerman
Authority
Authority

Rather than a different script for each VSID hard-coded to go to that VSID, it's easier to just "set virtual-system $(cat /proc/self/vrf)". But that gave me an idea for something simple:

 

#!/bin/env bash
printf "set virtual-system $(cat /proc/self/vrf)\n$(echo "$@")\nexit\n" | clish
echo ""

 

It's not the prettiest, but it automatically works in the current VRF. It's a shame clish -c flips out about newlines in the command. Otherwise, it would be possible to do something similar as clish -c "$(echo "set virtual-system $(cat /proc/self/vrf)";echo "$@")", which is slightly more elegant than the printf.

Bob_Zimmerman
Authority
Authority

Turns out this is now broken in R80.40 and up. Possibly R80.30 as well. clish no longer accepts piped input, and still doesn't accept newlines in the command argument.

0 Kudos
Majd_Sharkia
Employee
Employee

Please use the "clish -c" option without using pipe, the pipe is not officially supported.

0 Kudos
Bob_Zimmerman
Authority
Authority

Oh, I know. And clish -c is completely unusable:

[Expert@MyVsxMember1:0]# fw ver
This is Check Point's software version R80.40 - Build 135
[Expert@MyVsxMember1:0]# clish -c "set virtual-system 2;show router-id"
CLINFR0329  Invalid command:'set virtual-system 2;show router-id'.
[Expert@MyVsxMember1:0]# clish -c "set virtual-system 2\nshow router-id" 
CLINFR0329  Invalid command:'set virtual-system 2\nshow router-id'.
[Expert@MyVsxMember1:0]# clish -c "$(echo "set virtual-system 2";echo "show router-id")"
CLINFR0710  Illegal characters
[Expert@MyVsxMember1:0]# printf "set virtual-system 2\nshow router-id\n" | clish
[Expert@MyVsxMember1:0]# 

Can't chain multiple commands together, which means you can't get any information from VSs other than 0, which means comparing the configuration between VSX cluster members is excruciatingly manual. It's worse since the config line order in clish is not stable between cluster members, so you have to sort the lines to be able to use diff, but you can't just log your SSH session and sort everything, since that loses which VS has each line.

Can't use pipes in clish, so it's completely unusable for troubleshooting. I would just use clish -c and pipe it through grep and so on, but again, can't get information from VSs other than 0, making it literally unusable for troubleshooting. For example, there's no way to look for a single entry in the OSPF database of a VS other than 0. No, you have to show the whole OSPF database, then look through it with Notepad or something.

I'm really irritated about this loss of functionality, and I will be complaining through my sales team soon.

0 Kudos
Majd_Sharkia
Employee
Employee

You can use "clish -f" to run multiple commands, if you don't know how to use you can reach me.

Anyway, I suggest opening a ticket for CFG to check that.

0 Kudos
Bob_Zimmerman
Authority
Authority

Yes, but then I have to create a file, write the commands I want to run to the file, run the commands, deal with clish's extraneous output from running commands from a file, then clean up the file afterwards. All to get an approximation of functionality which worked before but which has broken.

This is the extraneous output I mean:

[Expert@MyVsxMember1:0]# cat clishScript.txt 
set virtual-system 12
show router-id
[Expert@MyVsxMember1:0]# clish -f clishScript.txt 
Context is set to vsid 122 
Processing line 2 out of 2 
Router ID:  10.2.3.4

Done.                                                        
[Expert@MyVsxMember1:0]# clish -f clishScript.txt 2>/dev/null
Context is set to vsid 122 
Processing line 2 out of 2 
Router ID:  10.2.3.4

Done.                                                        
[Expert@MyVsxMember1:0]# clish
MyVsxMember1:0> set virtual-system 12
Context is set to vsid 12
MyVsxMember1:12> show router-id

Router ID:  10.2.3.4

MyVsxMember1:12> 

Context is set to vsid 122? Clearly it's printed on top of "Processing line 1 of 2", but are you kidding me? The only reason the router ID doesn't show up as "10.2.3.4t of 2" is that the clish command 'show router-id' prints an otherwise-unnecessary newline first.

The extra output is in STDOUT, so I can't just use 2>/dev/null to discard it.

The command files don't appear to accept any sort of variable, so if I want to write a script to get the router IDs of all 30 VSs, I have to rewrite the file for every single one. Not insurmountable, but needlessly inconvenient.

XML output helps with some of this, but there aren't tools on-box to deal with it.

 

Previously, to get the router ID on all of my VSs, I just had to run this:

for vsid in $(ip netns list | cut -d' ' -f3 | sed 's/)//' | sort -g);do vsenv "$vsid" 2>&1 >/dev/null;printf "%5s: " "$vsid";echo "$(printf "set virtual-system $vsid\nshow router-id\n" | clish | grep Router | awk '{print $NF}')";done

It's not the prettiest, but it worked well and is relatively clean. Now I need all that plus file handling.

Majd_Sharkia
Employee
Employee

I understand your point and we will try to figure out this.

0 Kudos
Bob_Zimmerman
Authority
Authority

Support suggested a sed expression I had not considered:

sed -E 's/^Processing .+?\r//g'

This works, since the "Processing line X of Y" ends with a carriage return, but not a newline. The expression eats everything from a line starting with Processing to the next carriage return, leaving only the line which was meant to be printed.

This is a passable workaround, but clish desperately needs improvement on VSX.

0 Kudos
YC
Explorer

Hi,

Wrapped your idea's in a little bash script

eclish.sh - support selecting a VS and running multiple commands (comma separated)
chmod +x eclish.sh (to get it running)

run with -h to help

 

#!/bin/bash

############################################
# eclish
# extand checkpoint "clish" to support VSX and multiple commands
#
# @By scriptoman
#

EFILE=/home/admin/ecmds.txt
cmds=()
vsid=0

#Display usage
function display_help {
echo "Usage: eclish [OPTIONS]..."
echo "Extended clish support VS and multiple commands."
echo
echo -e "Arguments:"
echo -e " -v, --vs-id \t\t select virtual system id to run at "
echo -e " -c, --commands \t command/s to run (comma seperated) "
echo -e " -f, --file \t\t load command set from file "
echo -e " -h, --help \t\t display this help"
echo
exit
}

function set_virtual {
vsid="$1"
}

function set_commands {
IFS=',' read -ra cmds <<< "$1"
}

function set_file {
echo "File: $1"
}


function create_cmds_file {
echo "set virtual-system $vsid" > $EFILE

for c in "${cmds[@]}"
do
echo $c >> $EFILE
done
}

function eclish {

create_cmds_file
# cat $EFILE
clish -f "$EFILE" | sed -E 's/^Processing .+?\r//g'

}

parameters=("$@")
pLength="${#parameters[@]}"

if [[ $pLength -eq 0 ]]; then
read -p "Enter parameters:" input
parameters=($input)
pLength="${#parameters[@]}"
fi

#echo "Len:$pLength"

pPlace=0

while [[ $pPlace -lt $pLength ]] ; do

case ${parameters[$pPlace]} in
-v|--vs-id)
set_virtual "${parameters[($pPlace+1)]}"
pPlace=$((pPlace + 2))
;;
-c|--commands)
set_commands "${parameters[($pPlace+1)]}"
pPlace=$((pPlace + 2))
;;
-f|--file)
set_file "${parameters[($pPlace+1)]}"
pPlace=$((pPlace + 2))
;;
-h|--help)
display_help
pPlace=$((pPlace + 1))
;;
*)
break
;;
esac

done

eclish

 

 

 

0 Kudos
Duane_Toler
Advisor

I quasi-solved this with some clever Ansible-fu myself.  It's a bit involved, but the meat of it is:

* Inventory

1a) if you have a vsx cluster, define ansible hosts for each vsx cluster gateway.  Define the IP for "ansible_host: x.x.x.x" 

1b) define a logical ansible group for the VSX cluster (VSX_CLUSTER01, with members: gw1, gw2, gw3)

2) Define each VS as an inventory host - attach 2 variables:

vs_id: <vsid>

vsx: <name of the hosting vsx> (either the vsx cluster group name [VSX_CLUSTER01], or single vsx gateway )

3) I have my inventory set for different groups, but somewhere you want to define the Check Point connection variables

# cat inventory/group_vars/check_point/vars.yml 
---
ansible_httpapi_validate_certs: false
ansible_httpapi_use_ssl: true
ansible_httpapi_port: "{{ gaia_api_port |default(443) }}"
ansible_network_os: check_point.gaia.checkpoint
...

 

* Playbooks

I chose to do this all with Gaia API [yes Gaia API works on VSX, just VS0, which is all we need]

It's a nested series of loops.  Since the target is a VS, and the VS is on a cluster, the playbooks run the same CLISH command on all VSX gateways of the cluster where that VS is hosted.  "show ospf neighbors" only returns neighbors on the active VSX gateway for the VS.  But you might want "show configuration ospf" to verify configuration evenness.

 

I loop through the group of VSX gateways for the that VS's hosting VSX, and building the variables as it goes:

 

main.yml:

- name: Run CLISH command
  hosts: check_point
  become: false
  gather_facts: false
  connection: httpapi
  serial: 3

  vars:
    ansible_network_os: check_point.gaia.checkpoint
    output_dir: "clish_output/"

  tasks:
  tasks:
    - name: Run CLISH command on gateways
      include_tasks: gaia_clish_cmd.yml
      when: vsx is not defined

    - name: Run CLISH command on VSX VS
      include_tasks: vsx_clish_cmd.yml
      when: vsx is defined
...

 

So if 'vsx' is defined for the inventory host, loop through an inventory group with that name (VSX cluster); no i don't have this really set right to work if the VS is on a single-host VSX; i don't have one of those handy at the moment.  It's not too hard to figure out how to adapt this, tho.

 

# cat vsx_clish_cmd.yml 
---
- include_tasks: clish_script_build.yml
  loop: "{{ groups[vsx] }}"
  loop_control:
    label: "{{ vsx_host }}: {{ inventory_hostname }}"
  vars:
    config_file: "{{ vsx_host }}.{{ inventory_hostname }}.clish"
    config_dir: "vs_configs"
    vsx_host: "{{ item }}"

...

Eventually it gets to a Jinja2 template that does the core work:

 

clish_script_build.yml:

...
...
- name: Generate CLISH script
  ansible.builtin.template:
    src: clish_cmd.j2
    dest: "files/{{ config_dir }}/{{ config_file }}"
    lstrip_blocks: true
  delegate_to: localhost
...
...

 

# cat templates/clish_cmd.j2 
{# VSX CLISH command #}

set virtual-system {{ hostvars[inventory_hostname]['vs_id'] }}
{{ clish_cmd }}

 

Send it over with put_file API:

- name: Copy CLISH script
  check_point.gaia.cp_gaia_put_file:
    file_name: "/home/admin/{{ config_dir }}/{{ config_file }}"
    text_content: "{{ lookup('file', [ 'files', config_dir, config_file ] |join('/') ) }}\n"
    override: true
  delegate_to: "{{ vsx_host |default(inventory_hostname) }}"

 

Run it:

- name: Apply CLISH script
  check_point.gaia.cp_gaia_run_script:
    description: 'CLISH script: {{ config_file }}'
    script: |
      clish -c 'lock database override'
      clish -c 'unlock database'
      clish -f /home/admin/{{ config_dir }}/{{ config_file }}
    wait_for_task: "{{ wait_for_api_task |default(true) }}"
  delegate_to: "{{ vsx_host }}"
  register: script_res

 

Granted, I use and abuse put_file and run_script API to do the dirty work.  This helps (but does not eliminate) with the frustrating CLISH lock.  You also can run your playbook with 'admin' user if you want, and either do ansible-vault for the password, or prompt for it.  Or do other trickery.

 

I run this with a shell script:

 

./run_clish_command.sh -u admin_user_name -c 'show bgp peers' -l RTP_VS_1

 

The shell script uses 'getopts' to parse the variables and send to the playbook.  

 

# ./run_clish_command.sh -u admin_user_name -c 'show bgp peers' -l RTP_VS_1
Vault password: 

PLAY [Run CLISH command] *****************************************************************************************************************************

TASK [Run CLISH command on gateways] *****************************************************************************************************************
skipping: [RTP_VS_1]

TASK [Run CLISH command on VSX VS] *******************************************************************************************************************
included: /iac/playbooks/run_clish_command/vsx_clish_cmd.yml for RTP_VS_1

TASK [include_tasks] *********************************************************************************************************************************
included: /iac/playbooks/run_clish_command/clish_script_build.yml for RTP_VS_1 => (item=usdc2-gw1: RTP_VS_1)
included: /iac/playbooks/run_clish_command/clish_script_build.yml for RTP_VS_1 => (item=usdc2-gw2: RTP_VS_1)
included: /iac/playbooks/run_clish_command/clish_script_build.yml for RTP_VS_1 => (item=usdc2-gw3: RTP_VS_1)

...
..
...

TASK [Copy CLISH script] *****************************************************************************************************************************
changed: [RTP_VS_1 -> usdc2-gw3(192.0.2.113)]

TASK [include_tasks] *********************************************************************************************************************************
included: /iac/playbooks/run_clish_command/clish_script_apply.yml for RTP_VS_1

TASK [Apply CLISH script] ****************************************************************************************************************************
changed: [RTP_VS_1 -> usdc2-gw3(192.0.2.113)]

TASK [Check for run-time errors] *********************************************************************************************************************
skipping: [RTP_VS_1]

TASK [Save output] ***********************************************************************************************************************************
included: /iac/playbooks/run_clish_command/save_output.yml for RTP_VS_1

TASK [Parse output] **********************************************************************************************************************************
ok: [RTP_VS_1]

TASK [Show command output] ***************************************************************************************************************************
ok: [RTP_VS_1] => {
    "msg": [
        "Flags: R - Peer restarted, W - Waiting for End-Of-RIB from Peer",
        "",
        "PeerID           AS           Routes  ActRts  State             InUpds  OutUpds  Uptime  ",
        "100.64.0.2       64950        0       0       Idle              0       0        00:00:00  ",
        "100.64.0.3       64950        0       0       Idle              0       0        00:00:00  "
    ]
}

...
..
...


TASK [Copy CLISH script] *****************************************************************************************************************************
changed: [RTP_VS_1 -> usdc2-gw2(192.0.2.112)]

TASK [include_tasks] *********************************************************************************************************************************
included: /iac/playbooks/run_clish_command/clish_script_apply.yml for RTP_VS_1

TASK [Apply CLISH script] ****************************************************************************************************************************
changed: [RTP_VS_1 -> usdc2-gw2(192.0.2.112)]

TASK [Check for run-time errors] *********************************************************************************************************************
skipping: [RTP_VS_1]

TASK [Save output] ***********************************************************************************************************************************
included: /iac/playbooks/run_clish_command/save_output.yml for RTP_VS_1

TASK [Parse output] **********************************************************************************************************************************
ok: [RTP_VS_1]

TASK [Show command output] ***************************************************************************************************************************
ok: [RTP_VS_1] => {
    "msg": [
        "Flags: R - Peer restarted, W - Waiting for End-Of-RIB from Peer",
        "",
        "PeerID           AS           Routes  ActRts  State             InUpds  OutUpds  Uptime  ",
        "100.64.0.2       64950        2399    2391    Established       7429    1        8w2d    ",
        "100.64.0.3       64950        2399    6       Established       7453    1        8w2d    "
    ]
}

 

Anyhoo... yes, it's serial, because of the loop.

But, you can still run the Ansible host target against any VS, or all of them. 🙂  You can also see that I have a companion (very similar) playbook to do this for non-VSX gateways.  Blast that all out in a playbook run, and I can pull "show bgp peers" for 150 different systems if I wanted.

 

Hope this helps.  No I don't have this on a github, but I could be convinced...

 

0 Kudos
Bob_Zimmerman
Authority
Authority

For the specific case of running a single command via clish (e.g, 'show ospf neighbors' during troubleshooting), I eventually arrived at this:

#!/bin/env bash
clishScript=$(mktemp)
vsid="$1"
if [[ $vsid =~ '^[0-9]*$' ]];then shift;else vsid=0;fi
echo "set virtual-system ${vsid}" >${clishScript}
echo "$@" >>${clishScript}
clish -f "${clishScript}" | sed -E 's/^Processing .+?\r//g'
rm "${clishScript}"

You just put the VSID in as the first argument. If the first argument is non-numeric, it assumes VS 0. The rest can be quotes or not. The script handles creating a temp file, building the clish script, running it, suppressing the "Processing ..." output, and cleaning up the temp file after it's run.

[Expert@SomeVsxMember:0 STANDBY]# ./vsClish.sh show router-id
Context is set to vsid 0

Router ID:  10.16.32.64

Done.
[Expert@ SomeVsxMember:0 STANDBY]# ./vsClish.sh 0 show router-id
Context is set to vsid 0

Router ID:  10.16.32.64

Done.
[Expert@ SomeVsxMember:0 STANDBY]# ./vsClish.sh 2 show router-id
Context is set to vsid 2

Router ID:  10.20.40.80

Done.

 

0 Kudos
Bob_Zimmerman
Authority
Authority

And of course, posting that shook loose the realization that it still kind of sucks. Improved version!

#!/bin/env bash
clishScript=$(mktemp)
vsid="$1"
if [[ $vsid =~ '^[0-9]*$' ]];then shift;else vsid=$(cat /proc/self/nsid);fi
echo "set virtual-system ${vsid}" >${clishScript}
echo "$@" >>${clishScript}
clish -f "${clishScript}" | sed -E 's/^Processing .+?\r//g'
rm "${clishScript}"

Now, instead of assuming VS 0, it assumes the VS you're currently in.

[Expert@SomeVsxMember:0 STANDBY]# ./vsClish.sh show router-id
Context is set to vsid 0

Router ID:  10.16.32.64

Done.
[Expert@SomeVsxMember:0 STANDBY]# vsenv 2
Context is set to Virtual Device SomeVsxMember_VsName2 (ID 2).
[Expert@ SomeVsxMember:2 STANDBY]# ./vsClish.sh show router-id
Context is set to vsid 2

Router ID:  10.20.40.80

Done.

Running in a VS you aren't currently in still just takes specifying the VSID as the first argument.

Duane_Toler
Advisor

Here's my Ansible version of this, also now on GitHub, that will run CLISH commands on all VSX hosts for a specified VS (or any number of Virtual Systems), also in parallel:

https://community.checkpoint.com/t5/Toolbox-Contest-2024/Run-Gaia-CLISH-commands-with-Ansible/cns-p/...

It will run the command on all VSX gateways of a cluster, too, in case you need to look for configuration variances across the gateways.

The git repo includes a sample inventory and shell script to kick it off.  It requires Gaia API on the VSX gateway(s) and the Check Point Gaia Ansible modules.  You'll need a rule on VS0 to allow HTTPS access from whatever host you use for Ansible.

 

VSX gateway hosts are defined as hosts (obviously).

Virtual Systems are defined as hosts (not so obvious) with variables that define the VS ID and the VSX gateway (or cluster group) hosting the VS.  The playbooks take care of running the commands on the gateways for the VS.

This also works for any Gaia host (gateway cluster, single gateway, management, or standalone management+gateway.

 

0 Kudos
Andrew_Rawlinso
Participant

Just wanted to thank you for this little gem! I have been trying to come up with a way to grep ARP entries on a particular VS without having to go into clish and sift through the entire output.

This will be a gamechanger for troubleshooting for me. Appreciate it!

0 Kudos
Duane_Toler
Advisor

Did you use my Ansible pieces, or the pieces from @Bob_Zimmerman above?

0 Kudos
Andrew_Rawlinso
Participant

The script from Bob 🙂

0 Kudos
PhoneBoy
Admin
Admin
Pretty sure this is an RFE.
0 Kudos
Bob_Zimmerman
Authority
Authority

Those are the magic words I was looking for. 😜 My sales team suggested I post here in case it was already possible and they just weren't aware.

0 Kudos

Leaderboard

Epsum factorial non deposit quid pro quo hic escorol.

Upcoming Events

    CheckMates Events