Planet Collab

🔒
❌ About FreshRSS
There are new available articles, click to refresh the page.
Before yesterdayYour RSS feeds

Python Network Automation: pyATS/Genie on GNS3

By italchemy

As network automation is getting hotter in the market, Cisco has been responding with free tools to help the network Engineers to test their tools. The tools is called pyATS/Genie.  These are some short descriptions of the tool.

  • Network and Cisco devices.
  • Operational/Test cases
  • Verification tool
  • “Profile” before change, Change, “Profile” after, DIFF
  • Genie is part opyATS library. A python testing library.
  • Genie extends ATS specific to Networking, has the ability to do many different things. parse, show commands, snapshots and compare, test in virtual environment in VIRL environment.
  • Works best on Linux. 1 core 1GB requirement.

 

Lab topology using both VIRL L2 image and 3725 IOS. Follow along and you will see the true power of this tool, however, this is more of mornitoring and auditing tool than a real programming tool. So you are still a driver and not a mechanic. If you want to become a mechanic too, start learning Python!!! Have a fun.

 

genie_lab1
#### Create a test folder called genie
pynetauto@ubuntu20s:~$ pwd
/home/pynetauto
pynetauto@ubuntu20s:~$ mkdir genie
pynetauto@ubuntu20s:~$ cd genie

#### Install python3-venv using apt-get
pynetauto@ubuntu20s:~/genie$ sudo apt-get install python3-venv
Reading package lists… Done
Building dependency tree
Reading state information… Done
The following additional packages will be installed:
python3.8-venv
[… omitted for brevity]
Setting up python3.8-venv (3.8.2-1ubuntu1.1) …
Setting up python3-venv (3.8.2-0ubuntu2) …
#### Create a virtual environment to run your lab and activate
pynetauto@ubuntu20s:~/genie$ python3 -m venv .
pynetauto@ubuntu20s:~/genie$ source bin/activate
#### Install pyATS with the library
(genie) pynetauto@ubuntu20s:~/genie$ pip3 install pyATS[library]
Collecting pyATS[library]
Downloading pyats-20.6-cp38-cp38-manylinux1_x86_64.whl (2.0 MB)
|████████████████████████████████| 2.0 MB 1.5 MB/s
[… omitted for brevity]
Receiving objects: 100% (688/688), 1.01 MiB | 1.00 MiB/s, done.
Resolving deltas: 100% (355/355), done.
(genie) pynetauto@ubuntu20s:~/genie$
#### Run some basic job examples
(genie) pynetauto@ubuntu20s:~/genie$ pyats run job examples/basic/basic_example_job.py
2020-07-17T02:18:11: %EASYPY-INFO: Starting job run: basic_example_job
[… omitted for brevity]
2020-07-17T02:18:13: %EASYPY-INFO: Done!

Pro Tip
——-
Try the following command to view your logs:
pyats logs view
#### Install extra libraries for excel
(genie) pynetauto@ubuntu20s:~/genie$ pip3 install xlrd xlwt xlsxwriter
Collecting xlrd
Downloading xlrd-1.2.0-py2.py3-none-any.whl (103 kB)
|████████████████████████████████| 103 kB 3.4 MB/s
Collecting xlwt
Downloading xlwt-1.3.0-py2.py3-none-any.whl (99 kB)
|████████████████████████████████| 99 kB 6.5 MB/s
Collecting xlsxwriter
Downloading XlsxWriter-1.2.9-py2.py3-none-any.whl (141 kB)
|████████████████████████████████| 141 kB 6.8 MB/s
Installing collected packages: xlrd, xlwt, xlsxwriter
Successfully installed xlrd-1.2.0 xlsxwriter-1.2.9 xlwt-1.3.0
#### Genie uses a YAMAL testbed json file for device connection and authentication.
#### Install pyats.contrib (This is a requirement)
(genie) pynetauto@ubuntu20s:~/genie$ pip3 install pyats.contrib
Collecting pyats.contrib
Downloading pyats.contrib-20.6-py3-none-any.whl (32 kB)
Requirement already satisfied: xlsxwriter in ./lib/python3.8/site-packages (from pyats.contrib) (1.2.9)
[… omitted for brevity]
Installing collected packages: pycparser, cffi, cryptography, ansible, pyats.contrib
Successfully installed ansible-2.9.10 cffi-1.14.0 cryptography-2.9.2 pyats.contrib-20.6 pycparser-2.20

Create testbed.yml file for authentication
#### This is how the yaml file looks like
(pynetauto) pynetauto@ubuntu20s:~$ pyats create testbed interactive –output testbed.yml –encode-password

Start creating Testbed yaml file …
Do all of the devices have the same username? [y/n] n
Do all of the devices have the same default password? [y/n] n
Do all of the devices have the same enable password? [y/n] n

Device hostname: myrouter1
IP (ip, or ip:port): 192.168.30.254
Username: pynetauto
Default Password (leave blank if you want to enter on demand):
Enable Password (leave blank if you want to enter on demand):
Protocol (ssh, telnet, …): telnet
OS (iosxr, iosxe, ios, nxos, linux, …): ios
More devices to add ? [y/n] n
Testbed file generated:
testbed.yml

(pynetauto) pynetauto@ubuntu20s:~$ cat testbed.yml
devices:
myrouter1:
connections:
cli:
ip: 192.168.30.254
protocol: telnet
credentials:
default:
password: ‘%ENC{w5PDosOUw5fDosKQwpbCmA==}’
username: pynetauto
enable:
password: ‘%ENC{w5PDosOUw5fDosKQwpbCmA==}’
os: ios
type: ios

####Now, run the show command
(pynetauto) pynetauto@ubuntu20s:~$ genie parse “show version” –testbed-file testbed.yml –devices[hostname]
OR
(pynetauto) pynetauto@ubuntu20s:~$ genie parse “show version” –testbed-file testbed.yml –devices myrouter1
0%| | 0/1 [00:00<?, ?it/s]{
“version”: {
“chassis”: “3725”,
“chassis_sn”: “FTX0945W0MY”,
“compiled_by”: “prod_rel_team”,
“compiled_date”: “Tue 17-Aug-10 12:08”,
“curr_config_register”: “0x2102”,
“hostname”: “myrouter1”,
“image_id”: “C3725-ADVENTERPRISEK9-M”,
“image_type”: “production image”,
“main_mem”: “124928”,
“number_of_intfs”: {
“FastEthernet”: “2”
},
“os”: “IOS”,
“platform”: “3700”,
“processor_board_flash”: “55K”,
“processor_type”: “R7000”,
“rom”: “3700 Software (C3725-ADVENTERPRISEK9-M), Version 12.4(15)T14, RELEASE SOFTWARE (fc2)”,
“rtr_type”: “3725”,
“system_image”: “tftp://255.255.255.255/unknown”,
“uptime”: “44 minutes”,
“version”: “12.4(15)T14”,
“version_short”: “12.4”
}
}
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 1.19it/s]

(pynetauto) pynetauto@ubuntu20s:~$

===================================================
#### This is from VIRL

(pynetauto) pynetauto@ubuntu20s:~$ pyats create testbed interactive –output testbed.yml –encode-password
Start creating Testbed yaml file …
Do all of the devices have the same username? [y/n] n
Do all of the devices have the same default password? [y/n] n
Do all of the devices have the same enable password? [y/n] n

Device hostname: switch10
IP (ip, or ip:port): 192.168.30.200
Username: pynetauto
Default Password (leave blank if you want to enter on demand):
Enable Password (leave blank if you want to enter on demand):
Protocol (ssh, telnet, …): telnet
OS (iosxr, iosxe, ios, nxos, linux, …): ios
More devices to add ? [y/n] n
Testbed file generated:
testbed.yml

(pynetauto) pynetauto@ubuntu20s:~$ genie parse “show version” –testbed-file testbed.yml –devices[hostname]
0%| | 0/1 [00:00<?, ?it/s]{
“version”: {
“chassis_sn”: “9XSH5U9XEOH”,
“compiled_by”: “mmen”,
“compiled_date”: “Wed 22-Mar-17 08:38”,
“curr_config_register”: “0x101”,
“hostname”: “switch10”,
“image_id”: “vios_l2-ADVENTERPRISEK9-M”,
“image_type”: “developer image”,
“last_reload_reason”: “Unknown reason”,
“mem_size”: {
“non-volatile configuration”: “256”
},
“number_of_intfs”: {
“Gigabit Ethernet”: “16”,
“Virtual Ethernet”: “1”
},
“os”: “IOS”,
“platform”: “vios_l2”,
“processor_board_flash”: “0K”,
“returned_to_rom_by”: “reload”,
“rom”: “Bootstrap program is IOSv”,
“system_image”: “flash0:/vios_l2-adventerprisek9-m”,
“uptime”: “55 minutes”,
“version”: “15.2(20170321:233949)”,
“version_short”: “15.2”
}
}
100%|██████████████████████████████████████████████████████

 

=============== THE TRUE POWER is in PYTON =======================

Now, here’s the power of Python. You combine this with python regular expression and use any of the values as a varialbes or store them into excel files as you wish. This example will only demonstrate an re example to fish out an information.

 

>> import os
>>> show_ver = os.popen(‘genie parse “show version” –testbed-file testbed.yml –devices[hostname]’)
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 1.81it/s]

>>> output =show_ver.read()
>>> print(output)
{
“version”: {
“chassis_sn”: “9XSH5U9XEOH”,
“compiled_by”: “mmen”,
“compiled_date”: “Wed 22-Mar-17 08:38”,
“curr_config_register”: “0x101”,
“hostname”: “switch10”,
“image_id”: “vios_l2-ADVENTERPRISEK9-M”,
“image_type”: “developer image”,
“last_reload_reason”: “Unknown reason”,
“mem_size”: {
“non-volatile configuration”: “256”
},
“number_of_intfs”: {
“Gigabit Ethernet”: “16”,
“Virtual Ethernet”: “1”
},
“os”: “IOS”,
“platform”: “vios_l2”,
“processor_board_flash”: “0K”,
“returned_to_rom_by”: “reload”,
“rom”: “Bootstrap program is IOSv”,
“system_image”: “flash0:/vios_l2-adventerprisek9-m”,
“uptime”: “1 hour, 19 minutes”,
“version”: “15.2(20170321:233949)”,
“version_short”: “15.2”
}
}

 

### The output is a long string.

>>> type(output)
<class ‘str’>

# Import re module and use one of the cool regular expressions to capture only the information you require. Here I am using look behind feature (?<=). Lookbehind will bes used in string search but some parts will not be included. I am trying to capture the uptime for this device only.
>>> import re

>>> p = re.compile(r'(?<=\”uptime\”: ).+’)
>>> m = p.findall(output)
>>> m
[‘”1 hour, 19 minutes”,’]

 

 

Linux TIP – How To Create a Sudo User on Ubuntu 20 LTS

By italchemy

How To Create a Sudo User on Ubuntu 20 LTS

The sudo command is reserved for sudo users only and usually, the normal users are granted sudo user privilages with a care. The sudo commands provide a mechanism for granting administrator privileges only available to the root user. This is a three step process to create a new user account with sudo privilages on Ubuntu 20 LTS server, without having to modify the server’s sudoers file. The sudoers file is located under “/etc/sudoers”. If you want to configure sudo for an existing user, simply skip to step 3.

pynetauto@ubuntu20s:~$ sudo ls -la /etc/sudoers
-r–r—– 1 root root 755 Feb 3 14:32 /etc/sudoers

 

Step 1. Creating a new sudo user. Log in to your server as the root or root user.

ssh root@server_ip OR
ssh youruserid@server_ip

ssh pynetauto@192.168.30.130
Step 2. Use the adduser command to add a new user to your system. Make sure to replace user_name with your user name that you want to create.

adduser use_rname

#Creating a user called netadmin and create user’s password.
pynetauto@ubuntu20s:~$ sudo adduser netadmin
Adding user `netadmin’ …
Adding new group `netadmin’ (1001) …
Adding new user `netadmin’ (1001) with group `netadmin’ …
Creating home directory `/home/netadmin’ …
Copying files from `/etc/skel’ …
New password:**********
Retype new password:**********
passwd: password updated successfully
Changing the user information for netadmin
Enter the new value, or press ENTER for the default
Full Name []: Network Admin
Room Number []: 100
Work Phone []: +61 2 9988 7766
Home Phone []:
Other []:
Is the information correct? [Y/n] Y
Step 3. By default, on Ubuntu, members of the sudo group have sudo privileges. Use “usermod -aG sudo” command to add the user to sudo group.

usermod -aG sudo username
pynetauto@ubuntu20s:~$ sudo usermod -aG sudo netadmin
Verifiction A. To test sudo access of the new user. First, use the “su -” command to switch to the new user’s account.

su – username

pynetauto@ubuntu20s:~$ su – netadmin
Password:**********
To run a command as administrator (user “root”), use “sudo <command>”.
See “man sudo_root” for details.

Verification B. Check that the user has been added to sudoer group by running a grep command.

pynetauto@ubuntu20s:~$ grep ‘sudo’ /etc/group
sudo:x:27:pynetauto,netadmin

Verifiction C. As the new user, verify that you can use sudo by prepending “sudo” to the command that you want to run with superuser privileges.
For example, you can list the contents of “/root” directory, which is only accessible to the root users.

sudo ls -la /root

pynetauto@ubuntu20s:~$ sudo ls -la /root
[sudo] password for netadmin:**********
total 24
drwx—— 4 root root 4096 Jul 16 08:09 .
drwxr-xr-x 20 root root 4096 Jul 16 07:57 ..
-rw-r–r– 1 root root 3106 Dec 5 2019 .bashrc
-rw-r–r– 1 root root 161 Dec 5 2019 .profile
drwxr-xr-x 3 root root 4096 Jul 16 08:09 snap
drwx—— 2 root root 4096 Jul 16 08:08 .ssh

The first time you use sudo in a session, you will be prompted for the password. And as long as the session is opened, you do not have to enter the password to proceed. If your user is in the correct group and you entered the password correctly, the command that you issued with sudo should run with root privileges.
Step 4. To remove a user from sudo. Use deluser command in the command line, like so:

pynetauto@ubuntu20s:~$ sudo deluser netadmin sudo
[sudo] password for pynetauto:**********
Removing user `netadmin’ from group `sudo’ …
Done.

Verifiction
pynetauto@ubuntu20s:~$ grep ‘sudo’ /etc/group
sudo:x:27:pynetauto
Step 5. To add a user to the sudo group, use adduser command in the command line, like so:

pynetauto@ubuntu20s:~$ sudo adduser netadmin sudo
Adding user `netadmin’ to group `sudo’ …
Adding user netadmin to group sudo
Done.

Verifiction
bchoi@ubuntu20s:~$ grep ‘sudo’ /etc/group
sudo:x:27:pynetauto,netadmin

Python Network Automation: pyATS/Genie on GNS3

By italchemy

As network automation is getting hotter in the market, Cisco has been responding with free tools to help the network Engineers to test their tools. The tools is called pyATS/Genie.  These are some short descriptions of the tool.

  • Network and Cisco devices.
  • Operational/Test cases
  • Verification tool
  • “Profile” before change, Change, “Profile” after, DIFF
  • Genie is part opyATS library. A python testing library.
  • Genie extends ATS specific to Networking, has the ability to do many different things. parse, show commands, snapshots and compare, test in virtual environment in VIRL environment.
  • Works best on Linux. 1 core 1GB requirement.

 

Lab topology using both VIRL L2 image and 3725 IOS. Follow along and you will see the true power of this tool, however, this is more of mornitoring and auditing tool than a real programming tool. So you are still a driver and not a mechanic. If you want to become a mechanic too, start learning Python!!! Have a fun.

 

genie_lab1
#### Create a test folder called genie
pynetauto@ubuntu20s:~$ pwd
/home/pynetauto
pynetauto@ubuntu20s:~$ mkdir genie
pynetauto@ubuntu20s:~$ cd genie

#### Install python3-venv using apt-get
pynetauto@ubuntu20s:~/genie$ sudo apt-get install python3-venv
Reading package lists… Done
Building dependency tree
Reading state information… Done
The following additional packages will be installed:
python3.8-venv
[… omitted for brevity]
Setting up python3.8-venv (3.8.2-1ubuntu1.1) …
Setting up python3-venv (3.8.2-0ubuntu2) …
#### Create a virtual environment to run your lab and activate
pynetauto@ubuntu20s:~/genie$ python3 -m venv .
pynetauto@ubuntu20s:~/genie$ source bin/activate
#### Install pyATS with the library
(genie) pynetauto@ubuntu20s:~/genie$ pip3 install pyATS[library]
Collecting pyATS[library]
Downloading pyats-20.6-cp38-cp38-manylinux1_x86_64.whl (2.0 MB)
|████████████████████████████████| 2.0 MB 1.5 MB/s
[… omitted for brevity]
Receiving objects: 100% (688/688), 1.01 MiB | 1.00 MiB/s, done.
Resolving deltas: 100% (355/355), done.
(genie) pynetauto@ubuntu20s:~/genie$
#### Run some basic job examples
(genie) pynetauto@ubuntu20s:~/genie$ pyats run job examples/basic/basic_example_job.py
2020-07-17T02:18:11: %EASYPY-INFO: Starting job run: basic_example_job
[… omitted for brevity]
2020-07-17T02:18:13: %EASYPY-INFO: Done!

Pro Tip
——-
Try the following command to view your logs:
pyats logs view
#### Install extra libraries for excel
(genie) pynetauto@ubuntu20s:~/genie$ pip3 install xlrd xlwt xlsxwriter
Collecting xlrd
Downloading xlrd-1.2.0-py2.py3-none-any.whl (103 kB)
|████████████████████████████████| 103 kB 3.4 MB/s
Collecting xlwt
Downloading xlwt-1.3.0-py2.py3-none-any.whl (99 kB)
|████████████████████████████████| 99 kB 6.5 MB/s
Collecting xlsxwriter
Downloading XlsxWriter-1.2.9-py2.py3-none-any.whl (141 kB)
|████████████████████████████████| 141 kB 6.8 MB/s
Installing collected packages: xlrd, xlwt, xlsxwriter
Successfully installed xlrd-1.2.0 xlsxwriter-1.2.9 xlwt-1.3.0
#### Genie uses a YAMAL testbed json file for device connection and authentication.
#### Install pyats.contrib (This is a requirement)
(genie) pynetauto@ubuntu20s:~/genie$ pip3 install pyats.contrib
Collecting pyats.contrib
Downloading pyats.contrib-20.6-py3-none-any.whl (32 kB)
Requirement already satisfied: xlsxwriter in ./lib/python3.8/site-packages (from pyats.contrib) (1.2.9)
[… omitted for brevity]
Installing collected packages: pycparser, cffi, cryptography, ansible, pyats.contrib
Successfully installed ansible-2.9.10 cffi-1.14.0 cryptography-2.9.2 pyats.contrib-20.6 pycparser-2.20

Create testbed.yml file for authentication
#### This is how the yaml file looks like
(pynetauto) pynetauto@ubuntu20s:~$ pyats create testbed interactive –output testbed.yml –encode-password

Start creating Testbed yaml file …
Do all of the devices have the same username? [y/n] n
Do all of the devices have the same default password? [y/n] n
Do all of the devices have the same enable password? [y/n] n

Device hostname: myrouter1
IP (ip, or ip:port): 192.168.30.254
Username: pynetauto
Default Password (leave blank if you want to enter on demand):
Enable Password (leave blank if you want to enter on demand):
Protocol (ssh, telnet, …): telnet
OS (iosxr, iosxe, ios, nxos, linux, …): ios
More devices to add ? [y/n] n
Testbed file generated:
testbed.yml

(pynetauto) pynetauto@ubuntu20s:~$ cat testbed.yml
devices:
myrouter1:
connections:
cli:
ip: 192.168.30.254
protocol: telnet
credentials:
default:
password: ‘%ENC{w5PDosOUw5fDosKQwpbCmA==}’
username: pynetauto
enable:
password: ‘%ENC{w5PDosOUw5fDosKQwpbCmA==}’
os: ios
type: ios

####Now, run the show command
(pynetauto) pynetauto@ubuntu20s:~$ genie parse “show version” –testbed-file testbed.yml –devices[hostname]
OR
(pynetauto) pynetauto@ubuntu20s:~$ genie parse “show version” –testbed-file testbed.yml –devices myrouter1
0%| | 0/1 [00:00<?, ?it/s]{
“version”: {
“chassis”: “3725”,
“chassis_sn”: “FTX0945W0MY”,
“compiled_by”: “prod_rel_team”,
“compiled_date”: “Tue 17-Aug-10 12:08”,
“curr_config_register”: “0x2102”,
“hostname”: “myrouter1”,
“image_id”: “C3725-ADVENTERPRISEK9-M”,
“image_type”: “production image”,
“main_mem”: “124928”,
“number_of_intfs”: {
“FastEthernet”: “2”
},
“os”: “IOS”,
“platform”: “3700”,
“processor_board_flash”: “55K”,
“processor_type”: “R7000”,
“rom”: “3700 Software (C3725-ADVENTERPRISEK9-M), Version 12.4(15)T14, RELEASE SOFTWARE (fc2)”,
“rtr_type”: “3725”,
“system_image”: “tftp://255.255.255.255/unknown”,
“uptime”: “44 minutes”,
“version”: “12.4(15)T14”,
“version_short”: “12.4”
}
}
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 1.19it/s]

(pynetauto) pynetauto@ubuntu20s:~$

===================================================
#### This is from VIRL

(pynetauto) pynetauto@ubuntu20s:~$ pyats create testbed interactive –output testbed.yml –encode-password
Start creating Testbed yaml file …
Do all of the devices have the same username? [y/n] n
Do all of the devices have the same default password? [y/n] n
Do all of the devices have the same enable password? [y/n] n

Device hostname: switch10
IP (ip, or ip:port): 192.168.30.200
Username: pynetauto
Default Password (leave blank if you want to enter on demand):
Enable Password (leave blank if you want to enter on demand):
Protocol (ssh, telnet, …): telnet
OS (iosxr, iosxe, ios, nxos, linux, …): ios
More devices to add ? [y/n] n
Testbed file generated:
testbed.yml

(pynetauto) pynetauto@ubuntu20s:~$ genie parse “show version” –testbed-file testbed.yml –devices[hostname]
0%| | 0/1 [00:00<?, ?it/s]{
“version”: {
“chassis_sn”: “9XSH5U9XEOH”,
“compiled_by”: “mmen”,
“compiled_date”: “Wed 22-Mar-17 08:38”,
“curr_config_register”: “0x101”,
“hostname”: “switch10”,
“image_id”: “vios_l2-ADVENTERPRISEK9-M”,
“image_type”: “developer image”,
“last_reload_reason”: “Unknown reason”,
“mem_size”: {
“non-volatile configuration”: “256”
},
“number_of_intfs”: {
“Gigabit Ethernet”: “16”,
“Virtual Ethernet”: “1”
},
“os”: “IOS”,
“platform”: “vios_l2”,
“processor_board_flash”: “0K”,
“returned_to_rom_by”: “reload”,
“rom”: “Bootstrap program is IOSv”,
“system_image”: “flash0:/vios_l2-adventerprisek9-m”,
“uptime”: “55 minutes”,
“version”: “15.2(20170321:233949)”,
“version_short”: “15.2”
}
}
100%|██████████████████████████████████████████████████████

 

=============== THE TRUE POWER is in PYTON =======================

Now, here’s the power of Python. You combine this with python regular expression and use any of the values as a varialbes or store them into excel files as you wish. This example will only demonstrate an re example to fish out an information.

 

>> import os
>>> show_ver = os.popen(‘genie parse “show version” –testbed-file testbed.yml –devices[hostname]’)
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 1.81it/s]

>>> output =show_ver.read()
>>> print(output)
{
“version”: {
“chassis_sn”: “9XSH5U9XEOH”,
“compiled_by”: “mmen”,
“compiled_date”: “Wed 22-Mar-17 08:38”,
“curr_config_register”: “0x101”,
“hostname”: “switch10”,
“image_id”: “vios_l2-ADVENTERPRISEK9-M”,
“image_type”: “developer image”,
“last_reload_reason”: “Unknown reason”,
“mem_size”: {
“non-volatile configuration”: “256”
},
“number_of_intfs”: {
“Gigabit Ethernet”: “16”,
“Virtual Ethernet”: “1”
},
“os”: “IOS”,
“platform”: “vios_l2”,
“processor_board_flash”: “0K”,
“returned_to_rom_by”: “reload”,
“rom”: “Bootstrap program is IOSv”,
“system_image”: “flash0:/vios_l2-adventerprisek9-m”,
“uptime”: “1 hour, 19 minutes”,
“version”: “15.2(20170321:233949)”,
“version_short”: “15.2”
}
}

 

### The output is a long string.

>>> type(output)
<class ‘str’>

# Import re module and use one of the cool regular expressions to capture only the information you require. Here I am using look behind feature (?<=). Lookbehind will bes used in string search but some parts will not be included. I am trying to capture the uptime for this device only.
>>> import re

>>> p = re.compile(r'(?<=\”uptime\”: ).+’)
>>> m = p.findall(output)
>>> m
[‘”1 hour, 19 minutes”,’]

 

 

Linux TIP – How To Create a Sudo User on Ubuntu 20 LTS

By italchemy

How To Create a Sudo User on Ubuntu 20 LTS

The sudo command is reserved for sudo users only and usually, the normal users are granted sudo user privilages with a care. The sudo commands provide a mechanism for granting administrator privileges only available to the root user. This is a three step process to create a new user account with sudo privilages on Ubuntu 20 LTS server, without having to modify the server’s sudoers file. The sudoers file is located under “/etc/sudoers”. If you want to configure sudo for an existing user, simply skip to step 3.

pynetauto@ubuntu20s:~$ sudo ls -la /etc/sudoers
-r–r—– 1 root root 755 Feb 3 14:32 /etc/sudoers

 

Step 1. Creating a new sudo user. Log in to your server as the root or root user.

ssh root@server_ip OR
ssh youruserid@server_ip

ssh pynetauto@192.168.30.130
Step 2. Use the adduser command to add a new user to your system. Make sure to replace user_name with your user name that you want to create.

adduser use_rname

#Creating a user called netadmin and create user’s password.
pynetauto@ubuntu20s:~$ sudo adduser netadmin
Adding user `netadmin’ …
Adding new group `netadmin’ (1001) …
Adding new user `netadmin’ (1001) with group `netadmin’ …
Creating home directory `/home/netadmin’ …
Copying files from `/etc/skel’ …
New password:**********
Retype new password:**********
passwd: password updated successfully
Changing the user information for netadmin
Enter the new value, or press ENTER for the default
Full Name []: Network Admin
Room Number []: 100
Work Phone []: +61 2 9988 7766
Home Phone []:
Other []:
Is the information correct? [Y/n] Y
Step 3. By default, on Ubuntu, members of the sudo group have sudo privileges. Use “usermod -aG sudo” command to add the user to sudo group.

usermod -aG sudo username
pynetauto@ubuntu20s:~$ sudo usermod -aG sudo netadmin
Verifiction A. To test sudo access of the new user. First, use the “su -” command to switch to the new user’s account.

su – username

pynetauto@ubuntu20s:~$ su – netadmin
Password:**********
To run a command as administrator (user “root”), use “sudo <command>”.
See “man sudo_root” for details.

Verification B. Check that the user has been added to sudoer group by running a grep command.

pynetauto@ubuntu20s:~$ grep ‘sudo’ /etc/group
sudo:x:27:pynetauto,netadmin

Verifiction C. As the new user, verify that you can use sudo by prepending “sudo” to the command that you want to run with superuser privileges.
For example, you can list the contents of “/root” directory, which is only accessible to the root users.

sudo ls -la /root

pynetauto@ubuntu20s:~$ sudo ls -la /root
[sudo] password for netadmin:**********
total 24
drwx—— 4 root root 4096 Jul 16 08:09 .
drwxr-xr-x 20 root root 4096 Jul 16 07:57 ..
-rw-r–r– 1 root root 3106 Dec 5 2019 .bashrc
-rw-r–r– 1 root root 161 Dec 5 2019 .profile
drwxr-xr-x 3 root root 4096 Jul 16 08:09 snap
drwx—— 2 root root 4096 Jul 16 08:08 .ssh

The first time you use sudo in a session, you will be prompted for the password. And as long as the session is opened, you do not have to enter the password to proceed. If your user is in the correct group and you entered the password correctly, the command that you issued with sudo should run with root privileges.
Step 4. To remove a user from sudo. Use deluser command in the command line, like so:

pynetauto@ubuntu20s:~$ sudo deluser netadmin sudo
[sudo] password for pynetauto:**********
Removing user `netadmin’ from group `sudo’ …
Done.

Verifiction
pynetauto@ubuntu20s:~$ grep ‘sudo’ /etc/group
sudo:x:27:pynetauto
Step 5. To add a user to the sudo group, use adduser command in the command line, like so:

pynetauto@ubuntu20s:~$ sudo adduser netadmin sudo
Adding user `netadmin’ to group `sudo’ …
Adding user netadmin to group sudo
Done.

Verifiction
bchoi@ubuntu20s:~$ grep ‘sudo’ /etc/group
sudo:x:27:pynetauto,netadmin

VMware ovf to ova conversion using OVFTool

By italchemy

Sometime you have to change ovf files to ova or ova to ovf.

Step 1: OVFTool is installed in workstation by default. Start CLI Prompt line as admin and drill down to the folder with OVFTool.exe

cd C:\Program Files (x86)\VMware\VMware Workstation\OVFTool

 

Step 2a: To change ovf file to ova, run 

ovftool.exe C:\file_path2\vm..ovf C:\file_path1\vm.ova

Step 2b: To change ova file to ovf, run

ovftool.exe C:\file_path1\vm.ova C:\file_path2\vm.ovf

The following example is conversion from ovf file to ova file.  

C:\Program Files (x86)\VMware\VMware Workstation\OVFTool>ovftool.exe C:\pams_v0\ubuntu20.ovf C:\pams_v1\ubuntu20.ova

Opening OVF source: C:\ubuntu20_v0\ubuntu20.ovf
The manifest validates
Opening OVA target: C:\ubuntu20_v0\ubuntu20.ova
Writing OVA package: C:\ubuntu20_v1\ubuntu20.ova
Transfer Completed
Completed successfully

C:\Program Files (x86)\VMware\VMware Workstation\OVFTool> cd /ubuntu20_v1

C:\ubuntu20_v1>dir
Volume in drive C has no label.
Volume Serial Number is 54B2-806B

Directory of C:\pams_v1

23/06/2020 07:13 PM <DIR> .
23/06/2020 07:13 PM <DIR> ..
23/06/2020 07:16 PM 2,934,892,032 ubuntu20.ova
1 File(s) 2,934,892,032 bytes
2 Dir(s) 24,086,020,096 bytes free

 

VMware ovf to ova conversion using OVFTool

By italchemy

Sometime you have to change ovf files to ova or ova to ovf.

Step 1: OVFTool is installed in workstation by default. Start CLI Prompt line as admin and drill down to the folder with OVFTool.exe

cd C:\Program Files (x86)\VMware\VMware Workstation\OVFTool

 

Step 2a: To change ovf file to ova, run 

ovftool.exe C:\file_path2\vm..ovf C:\file_path1\vm.ova

Step 2b: To change ova file to ovf, run

ovftool.exe C:\file_path1\vm.ova C:\file_path2\vm.ovf

The following example is conversion from ovf file to ova file.  

C:\Program Files (x86)\VMware\VMware Workstation\OVFTool>ovftool.exe C:\pams_v0\ubuntu20.ovf C:\pams_v1\ubuntu20.ova

Opening OVF source: C:\ubuntu20_v0\ubuntu20.ovf
The manifest validates
Opening OVA target: C:\ubuntu20_v0\ubuntu20.ova
Writing OVA package: C:\ubuntu20_v1\ubuntu20.ova
Transfer Completed
Completed successfully

C:\Program Files (x86)\VMware\VMware Workstation\OVFTool> cd /ubuntu20_v1

C:\ubuntu20_v1>dir
Volume in drive C has no label.
Volume Serial Number is 54B2-806B

Directory of C:\pams_v1

23/06/2020 07:13 PM <DIR> .
23/06/2020 07:13 PM <DIR> ..
23/06/2020 07:16 PM 2,934,892,032 ubuntu20.ova
1 File(s) 2,934,892,032 bytes
2 Dir(s) 24,086,020,096 bytes free

 

1. Python – navigating to working directory using os module

By italchemy

# Import os
>>> import os

# Check current workind directory
>>> cwd = os.getcwd()
>>> cwd
‘/root’

# Check the directories and files
>>> os.listdir(‘.’)
[‘.bash_logout’, ‘.bash_profile’, ‘.bashrc’, ‘.cshrc’, ‘.tcshrc’, ‘anaconda-ks.cfg’, ‘.cache’, ‘.dbus’, ‘.config’, ‘initial-setup-ks.cfg’, ‘.esd_auth’, ‘.ICEauthority’, ‘.local’, ‘Desktop’, ‘Downloads’, ‘Templates’, ‘Public’, ‘Documents’, ‘Music’, ‘Pictures’, ‘Videos’, ‘.pki’, ‘.bash_history’, ‘.python_history’, ‘.mozilla’, ‘.docker’, ‘dockerfile1’, ‘Dockerfile1’, ‘Dockerfile001’, ‘Dockerfile002’, ‘Dockerfile’, ‘pan_set_test’, ‘animal_list.txt’, ‘convert_txt2excel.py’, ‘animal_list.xlsx’, ‘test01.xlsx’, ‘pan_config_diff.xlsx’, ‘pan_config_old.xlsx’, ‘pan_config.xlsx’, ‘pan_config_df1_diff.xlsx’, ‘pan_config_df3_diff.xlsx’, ‘panda_test01’, ‘t1’]

# Change the workind directory to your desired location.
>>> os.chdir(“/root/pan_set_test”)

# Check the files and directories under your workind directory.
>>> os.listdir(‘.’)
[‘pan_set1.py’, ‘tools1.py’, ‘__pycache__’, ‘pan_set2.py’, ‘pan_set3.py’, ‘pan_set4.py’, ‘pan_set5.py’, ‘txt_to_xlsx.py’, ‘txt_to_xlsx1.py’, ‘compare_2_xlsx.py’, ‘excelcompare.py’, ‘excelcompare1.py’, ‘txt_to_xlsx2.py’, ‘pan_set6.py’, ‘pan1_session.out’, ‘pan1_config.out’, ‘pan2_config.out’, ‘192.168.30.154_vs_192.168.30.157_compared.html’, ‘pan2_session.out’, ‘pan_config.xlsx’, ‘pan_config_test1.xlsx’, ‘pan1_config.xlsx’, ‘pan2_config.xlsx’, ‘compare_test100.py’, ‘where_am_i.py’]

1. Python – navigating to working directory using os module

By italchemy

# Import os
>>> import os

# Check current workind directory
>>> cwd = os.getcwd()
>>> cwd
‘/root’

# Check the directories and files
>>> os.listdir(‘.’)
[‘.bash_logout’, ‘.bash_profile’, ‘.bashrc’, ‘.cshrc’, ‘.tcshrc’, ‘anaconda-ks.cfg’, ‘.cache’, ‘.dbus’, ‘.config’, ‘initial-setup-ks.cfg’, ‘.esd_auth’, ‘.ICEauthority’, ‘.local’, ‘Desktop’, ‘Downloads’, ‘Templates’, ‘Public’, ‘Documents’, ‘Music’, ‘Pictures’, ‘Videos’, ‘.pki’, ‘.bash_history’, ‘.python_history’, ‘.mozilla’, ‘.docker’, ‘dockerfile1’, ‘Dockerfile1’, ‘Dockerfile001’, ‘Dockerfile002’, ‘Dockerfile’, ‘pan_set_test’, ‘animal_list.txt’, ‘convert_txt2excel.py’, ‘animal_list.xlsx’, ‘test01.xlsx’, ‘pan_config_diff.xlsx’, ‘pan_config_old.xlsx’, ‘pan_config.xlsx’, ‘pan_config_df1_diff.xlsx’, ‘pan_config_df3_diff.xlsx’, ‘panda_test01’, ‘t1’]

# Change the workind directory to your desired location.
>>> os.chdir(“/root/pan_set_test”)

# Check the files and directories under your workind directory.
>>> os.listdir(‘.’)
[‘pan_set1.py’, ‘tools1.py’, ‘__pycache__’, ‘pan_set2.py’, ‘pan_set3.py’, ‘pan_set4.py’, ‘pan_set5.py’, ‘txt_to_xlsx.py’, ‘txt_to_xlsx1.py’, ‘compare_2_xlsx.py’, ‘excelcompare.py’, ‘excelcompare1.py’, ‘txt_to_xlsx2.py’, ‘pan_set6.py’, ‘pan1_session.out’, ‘pan1_config.out’, ‘pan2_config.out’, ‘192.168.30.154_vs_192.168.30.157_compared.html’, ‘pan2_session.out’, ‘pan_config.xlsx’, ‘pan_config_test1.xlsx’, ‘pan1_config.xlsx’, ‘pan2_config.xlsx’, ‘compare_test100.py’, ‘where_am_i.py’]

Python os module – prepend first line before converting to xlsx file

By italchemy

 

import os

#This adds the first line header to  animal_list.txt file.
os.system(“sed -i ‘1s/^/DOMESTIC_ANIMALS\\n/’ /root/animal_list.txt”)

 

[root@localhost ~]# cat animal_list.txt
1. dog
2. cat
3. cow
4. sheep
5. pig

 

>>> import os
>>> #This adds the first line header to  animal_list.txt file.

>>> os.system(“sed -i ‘1s/^/DOMESTIC_ANIMALS\\n/’ /root/animal_list.txt”)
0
>>>

[root@localhost ~]# cat animal_list.txt
DOMESTIC_ANIMALS <<< New line prepended
1. dog
2. cat
3. cow
4. sheep
5. pig

Python os module – prepend first line before converting to xlsx file

By italchemy

 

import os

#This adds the first line header to  animal_list.txt file.
os.system(“sed -i ‘1s/^/DOMESTIC_ANIMALS\\n/’ /root/animal_list.txt”)

 

[root@localhost ~]# cat animal_list.txt
1. dog
2. cat
3. cow
4. sheep
5. pig

 

>>> import os
>>> #This adds the first line header to  animal_list.txt file.

>>> os.system(“sed -i ‘1s/^/DOMESTIC_ANIMALS\\n/’ /root/animal_list.txt”)
0
>>>

[root@localhost ~]# cat animal_list.txt
DOMESTIC_ANIMALS <<< New line prepended
1. dog
2. cat
3. cow
4. sheep
5. pig

Install FTP server (vsftpd) on Ubuntu 20.04 – Six Steps

By italchemy

Step 1: Update repository and install vsftpd
sudo apt update && sudo apt install vsftpd

To check enable & status:
sudo systemctl enable vsftpd
sudo systemctl status vsftpd

step 2: Configure firewall
sudo ufw allow OpenSSH
sudo ufw allow 20/tcp
sudo ufw allow 21/tcp
sudo ufw allow 49000:49999/tcp
sudo ufw allow 990/tcp (Optional, if using TLS)

sudo ufw enable
sudo ufw status

Step 3: Create FTP User
sudo adduser ftpuser1

Modify sshd_config file:
sudo nano /etc/ssh/sshd_config
# Add the following line at the end to block ftpuser1 using SSH and SFTP.
DenyUsers ftpuser1

sudo service sshd restart
Step 4: Give directory permissions
Two options here, 1. to user1 home folder, 2. use web server.
Only using home folder.

# Create a dedicate directory, ftp
sudo mkdir /home/ftpuser1/ftp

# Set the ownership to nogody:nogroup so, other users cannot access this directory. Lockind down 2.
sudo chown nobody:nogroup /home/ftpuser1/ftp

# Remove (-), all(a), write(w) permission from everyone. Locking down 1
sudo chmod a-w /home/ftpuser1/ftp

# Now create new directories to upload/download files
sudo mkdir /home/ftpuser1/ftp/ios
sudo mkdir /home/ftpuser1/ftp/backups
sudo mkdir /home/ftpuser1/ftp/logs

# Assign ownership to ftpuser1 to provide write access.
sudo chown ftpuser2:ftpuser1 /home/ftpuser1/ftp/ios
sudo chown ftpuser2:ftpuser1 /home/ftpuser1/ftp/backups
sudo chown ftpuser2:ftpuser1 /home/ftpuser1/ftp/logs

Step 4: vsftpd server configuration
# make a backup of the original vsftpd.conf file by renaming it.
sudo mv /etc/vsftpd.conf /etc/vsftpd.conf.bak

# create new vsftpd.conf file
sudo nano /etc/vsftpd.conf

# Cut and paste the following:

listen=NO
listen_ipv6=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
chroot_local_user=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
force_dot_files=YES
pasv_min_port=49000
pasv_max_port=49999
# ADDED BY SYSTEM ADMIN
# Tell vsftpd know that the root FTP folder is /ftp under /home/ftpuser1/.
user_sub_token=$USER
local_root=/home/$USER/ftp

# Restare vsftpd server
sudo systemctl restart vsftpd

Step 6: Download FileZilla Client and login.
# *Make sure that you are logging in “Active” transfer mode. Got to FileZilla Settings.

Edit >>> Settings >>> Connection >>> FTP >>> under “Transfer Mode”, change Passive to Active. OK

*** At this point, you should be able to upload/download files with no issues. ***

# To check vsftpd server logs
sudo tail /var/log/vsftpd.log -n 100

Install FTP server (vsftpd) on Ubuntu 20.04 – Six Steps

By italchemy

Step 1: Update repository and install vsftpd
sudo apt update && sudo apt install vsftpd

To check enable & status:
sudo systemctl enable vsftpd
sudo systemctl status vsftpd

step 2: Configure firewall
sudo ufw allow OpenSSH
sudo ufw allow 20/tcp
sudo ufw allow 21/tcp
sudo ufw allow 49000:49999/tcp
sudo ufw allow 990/tcp (Optional, if using TLS)

sudo ufw enable
sudo ufw status

Step 3: Create FTP User
sudo adduser ftpuser1

Modify sshd_config file:
sudo nano /etc/ssh/sshd_config
# Add the following line at the end to block ftpuser1 using SSH and SFTP.
DenyUsers ftpuser1

sudo service sshd restart
Step 4: Give directory permissions
Two options here, 1. to user1 home folder, 2. use web server.
Only using home folder.

# Create a dedicate directory, ftp
sudo mkdir /home/ftpuser1/ftp

# Set the ownership to nogody:nogroup so, other users cannot access this directory. Lockind down 2.
sudo chown nobody:nogroup /home/ftpuser1/ftp

# Remove (-), all(a), write(w) permission from everyone. Locking down 1
sudo chmod a-w /home/ftpuser1/ftp

# Now create new directories to upload/download files
sudo mkdir /home/ftpuser1/ftp/ios
sudo mkdir /home/ftpuser1/ftp/backups
sudo mkdir /home/ftpuser1/ftp/logs

# Assign ownership to ftpuser1 to provide write access.
sudo chown ftpuser2:ftpuser1 /home/ftpuser1/ftp/ios
sudo chown ftpuser2:ftpuser1 /home/ftpuser1/ftp/backups
sudo chown ftpuser2:ftpuser1 /home/ftpuser1/ftp/logs

Step 4: vsftpd server configuration
# make a backup of the original vsftpd.conf file by renaming it.
sudo mv /etc/vsftpd.conf /etc/vsftpd.conf.bak

# create new vsftpd.conf file
sudo nano /etc/vsftpd.conf

# Cut and paste the following:

listen=NO
listen_ipv6=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
chroot_local_user=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
force_dot_files=YES
pasv_min_port=49000
pasv_max_port=49999
# ADDED BY SYSTEM ADMIN
# Tell vsftpd know that the root FTP folder is /ftp under /home/ftpuser1/.
user_sub_token=$USER
local_root=/home/$USER/ftp

# Restare vsftpd server
sudo systemctl restart vsftpd

Step 6: Download FileZilla Client and login.
# *Make sure that you are logging in “Active” transfer mode. Got to FileZilla Settings.

Edit >>> Settings >>> Connection >>> FTP >>> under “Transfer Mode”, change Passive to Active. OK

*** At this point, you should be able to upload/download files with no issues. ***

# To check vsftpd server logs
sudo tail /var/log/vsftpd.log -n 100

Python 3 – Send emails from python script using (Ubuntu 20.04) Sendmail

By italchemy

Requirements:

  • sendmail is installed & port 25 is on listening mode on 127.0.0.1 (Ubuntu 20.04, you have to install this manually)
  • smtplib module is available (installed on Python3 by default)

 

Step 1: Check sendmail is available from Ubuntu 20.04. I did not have sendmail after the installation and also, no “tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN” statement available. This means, you have to install sendmail.
Before installing Sendmail on Ubuntu, not listening on port 25.
bchoi@ubuntu20:~$ netstat -tuna
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.1:10256 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:1338 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:40541 0.0.0.0:* LISTEN

Step 2: INSTALL sendmail on Ubuntu 20:
bchoi@ubuntu20:~$ sudo apt install sendmail
[sudo] password for bchoi:
Reading package lists… Done
Building dependency tree
Reading state information… Done

After installation finishes, run the following command and say Y[yes] to all responses.

bchoi@ubuntu20:~$sudosendmailconfig 

 

Step 3: Check the port 25 port
After installing Sendmail on Ubuntu 20, now listening to port 25:
bchoi@ubuntu20:~$ ls /usr/sbin/send*
/usr/sbin/sendmail /usr/sbin/sendmailconfig /usr/sbin/sendmail-msp /usr/sbin/sendmail-mta
bchoi@ubuntu20:~$ netstat -tuna
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.1:10256 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:1338 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:40541 0.0.0.0:* LISTEN

 

Step 4: Send a quick test email using echo command from Linux command line.
bchoi@ubuntu20:~$ echo “This is my first test email 1.” | sendmail -v pynetauto3@gmail.com

pynetauto3@gmail.com… Connecting to [127.0.0.1] via relay…
220 localhost.localdomain ESMTP Sendmail 8.15.2/8.15.2/Debian-18; Wed, 13 May 2020 02:15:02 GMT; (No UCE/UBE) logging access from: localhost(OK)-localhost [127.0.0.1]
>>> EHLO localhost.localdomain
250-localhost.localdomain Hello localhost [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
[… ommitted for brevity]
050 354 Go ahead i1si3191776pld.30 – gsmtp
050 >>> .
050 250 2.0.0 OK 1589336105 i1si3191776pld.30 – gsmtp
050 <pynetauto3@gmail.com>… Sent (OK 1589336105 i1si3191776pld.30 – gsmtp)
250 2.0.0 04D2F2su1433710 Message accepted for delivery
pynetauto3@gmail.com… Sent (04D2F2su1433710 Message accepted for delivery)
Closing connection to [127.0.0.1]
>>> QUIT
221 2.0.0 localhost.localdomain closing connection

 

Step 5: Check your email in SPAM:

send_e1-1

Step 6: Write an email sending script and send a test email from Python

#bchoi@ubuntu20:~$ nano send_e1.py

import smtplib

sender = ‘no_reply@italchemy.com’
receivers = [‘pynetauto3@gmail.com’]

message = “””From: No Reply <no_reply@italchemy.com>
To: Brendan Choi <pynetauto3@gmail.com>
Subject: Sendmail SMTP Email test 001

This is a Sendmail test e-mail message 1.
“””

try:
smtpObj = smtplib.SMTP(‘localhost’)
smtpObj.sendmail(sender, receivers, message)
print(“Successfully sent email”)
except SMTPException:
print(“Error: unable to send email”)

send_e1-2

 

Step 7: Send another test email using Python command
bchoi@ubuntu20:~$ python3 send_e1.py
Successfully sent email

 

Step 8: Check your email spam box again. Now you have successfully sent an email from your Python script. 

send_e1-3

Python 3 – Send emails from python script using (Ubuntu 20.04) Sendmail

By italchemy

Requirements:

  • sendmail is installed & port 25 is on listening mode on 127.0.0.1 (Ubuntu 20.04, you have to install this manually)
  • smtplib module is available (installed on Python3 by default)

 

Step 1: Check sendmail is available from Ubuntu 20.04. I did not have sendmail after the installation and also, no “tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN” statement available. This means, you have to install sendmail.
Before installing Sendmail on Ubuntu, not listening on port 25.
bchoi@ubuntu20:~$ netstat -tuna
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.1:10256 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:1338 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:40541 0.0.0.0:* LISTEN

Step 2: INSTALL sendmail on Ubuntu 20:
bchoi@ubuntu20:~$ sudo apt install sendmail
[sudo] password for bchoi:
Reading package lists… Done
Building dependency tree
Reading state information… Done

After installation finishes, run the following command and say Y[yes] to all responses.

bchoi@ubuntu20:~$sudosendmailconfig 

 

Step 3: Check the port 25 port
After installing Sendmail on Ubuntu 20, now listening to port 25:
bchoi@ubuntu20:~$ ls /usr/sbin/send*
/usr/sbin/sendmail /usr/sbin/sendmailconfig /usr/sbin/sendmail-msp /usr/sbin/sendmail-mta
bchoi@ubuntu20:~$ netstat -tuna
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.1:10256 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:1338 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:40541 0.0.0.0:* LISTEN

 

Step 4: Send a quick test email using echo command from Linux command line.
bchoi@ubuntu20:~$ echo “This is my first test email 1.” | sendmail -v pynetauto3@gmail.com

pynetauto3@gmail.com… Connecting to [127.0.0.1] via relay…
220 localhost.localdomain ESMTP Sendmail 8.15.2/8.15.2/Debian-18; Wed, 13 May 2020 02:15:02 GMT; (No UCE/UBE) logging access from: localhost(OK)-localhost [127.0.0.1]
>>> EHLO localhost.localdomain
250-localhost.localdomain Hello localhost [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
[… ommitted for brevity]
050 354 Go ahead i1si3191776pld.30 – gsmtp
050 >>> .
050 250 2.0.0 OK 1589336105 i1si3191776pld.30 – gsmtp
050 <pynetauto3@gmail.com>… Sent (OK 1589336105 i1si3191776pld.30 – gsmtp)
250 2.0.0 04D2F2su1433710 Message accepted for delivery
pynetauto3@gmail.com… Sent (04D2F2su1433710 Message accepted for delivery)
Closing connection to [127.0.0.1]
>>> QUIT
221 2.0.0 localhost.localdomain closing connection

 

Step 5: Check your email in SPAM:

send_e1-1

Step 6: Write an email sending script and send a test email from Python

#bchoi@ubuntu20:~$ nano send_e1.py

import smtplib

sender = ‘no_reply@italchemy.com’
receivers = [‘pynetauto3@gmail.com’]

message = “””From: No Reply <no_reply@italchemy.com>
To: Brendan Choi <pynetauto3@gmail.com>
Subject: Sendmail SMTP Email test 001

This is a Sendmail test e-mail message 1.
“””

try:
smtpObj = smtplib.SMTP(‘localhost’)
smtpObj.sendmail(sender, receivers, message)
print(“Successfully sent email”)
except SMTPException:
print(“Error: unable to send email”)

send_e1-2

 

Step 7: Send another test email using Python command
bchoi@ubuntu20:~$ python3 send_e1.py
Successfully sent email

 

Step 8: Check your email spam box again. Now you have successfully sent an email from your Python script. 

send_e1-3

Python code run timer 2– make your own tool

By italchemy

You can use datetime module to get both the date and difference in time. Follow this in Python IDLE or Interpreter to comprehend datetime module.

 

Import datetime

# >>> start_time = datetime.datetime.now().strftime(‘%y-%m-%d %a %H:%M:%S’) #When you want to format the string
# >>> start_time
# ’20-04-30 Thu 07:17:21′

# To get the date only as string
>>> yyyymmdd = datetime.date.today().strftime(‘%Y_%m_%d’)
>>> yyyymmdd
‘2020_04_30’

# To get the start time before the script runs
>>> start_time = datetime.datetime.now()
>>> start_time
datetime.datetime(2020, 4, 30, 7, 18, 19, 578317)
### PUT YOUR SCRIPT HERE

# I am using the date to create a new file. A single file will be created each day as it is using w+ privilages.

with open(“/home/” + yyyymmdd + “_hello_monkey.txt”, “w+”) as f:
f.write(“Hello World! Hello Mr. Mokey”)

 

# To get the end time after the script finishes
>>> end_time = datetime.datetime.now()
>>> end_time
datetime.datetime(2020, 4, 30, 7, 18, 35, 799375)

# If you simply print the difference, it will print in full module format.
>>> x = end_time – start_time
>>> x
datetime.timedelta(0, 16, 221058)

# To conver the timedelta to total seconds
>>> y = datetime.timedelta.total_seconds(end_time-start_time)
>>> y
16.221058

Python code run timer 2– make your own tool

By italchemy

You can use datetime module to get both the date and difference in time. Follow this in Python IDLE or Interpreter to comprehend datetime module.

 

Import datetime

# >>> start_time = datetime.datetime.now().strftime(‘%y-%m-%d %a %H:%M:%S’) #When you want to format the string
# >>> start_time
# ’20-04-30 Thu 07:17:21′

# To get the date only as string
>>> yyyymmdd = datetime.date.today().strftime(‘%Y_%m_%d’)
>>> yyyymmdd
‘2020_04_30’

# To get the start time before the script runs
>>> start_time = datetime.datetime.now()
>>> start_time
datetime.datetime(2020, 4, 30, 7, 18, 19, 578317)
### PUT YOUR SCRIPT HERE

# I am using the date to create a new file. A single file will be created each day as it is using w+ privilages.

with open(“/home/” + yyyymmdd + “_hello_monkey.txt”, “w+”) as f:
f.write(“Hello World! Hello Mr. Mokey”)

 

# To get the end time after the script finishes
>>> end_time = datetime.datetime.now()
>>> end_time
datetime.datetime(2020, 4, 30, 7, 18, 35, 799375)

# If you simply print the difference, it will print in full module format.
>>> x = end_time – start_time
>>> x
datetime.timedelta(0, 16, 221058)

# To conver the timedelta to total seconds
>>> y = datetime.timedelta.total_seconds(end_time-start_time)
>>> y
16.221058

Python Netmiko – Cisco router/switch ‘[reload]’

By italchemy

Things are getting more interesting using Netmiko. Thanks to Kirk Byers for maintaining Netmiko library up to date!

Step 1: Create a connection handler

import netmiko

connection = netmiko.ConnectHandler(ip=”192.168.30.161″, device_type=’cisco_ios’, username=’cisco’, password=’cisco123′)

 

Step 2: Check connection

connection

<netmiko.cisco.cisco_ios.CiscoIosSSH object at 0x7f6d862718e0>

 

Step 3: Save your configuration before reload.

connection.send_command_expect(‘write mem’)

‘Building configuration…\nCompressed configuration from 4115 bytes to 1979 bytes[OK]’

 

Step 4: For Cisco routers and switches, You are expecting expect_string='[confirm]’ Any response will trigger the device to reload after reload command is sent properly.

connection.send_command(‘reload’, expect_string='[confirm]’)

‘Proceed with reload? [confirm]’

connection.send_command(‘\n’)

OR

connection.send_command(‘y’)

OR

connection.disconnect()

Traceback (most recent call last): File “”, line 1, in File “/usr/local/lib/python3.8/dist-packages/netmiko/utilities.py”, line 347, in wrapper_decorator return func(self, *args, **kwargs) File “/usr/local/lib/python3.8/dist-packages/netmiko/base_connection.py”, line 1368, in send_command prompt = self.find_prompt(delay_factor=delay_factor) File “/usr/local/lib/python3.8/dist-packages/netmiko/base_connection.py”, line 1107, in find_prompt self.write_channel(self.RETURN) File “/usr/local/lib/python3.8/dist-packages/netmiko/base_connection.py”, line 436, in write_channel self._write_channel(out_data) File “/usr/local/lib/python3.8/dist-packages/netmiko/base_connection.py”, line 394, in _write_channel self.remote_conn.sendall(write_bytes(out_data, encoding=self.encoding)) File “/usr/local/lib/python3.8/dist-packages/paramiko/channel.py”, line 846, in sendall sent = self.send(s) File “/usr/local/lib/python3.8/dist-packages/paramiko/channel.py”, line 801, in send return self._send(s, m) File “/usr/local/lib/python3.8/dist-packages/paramiko/channel.py”, line 1198, in _send raise socket.error(“Socket is closed”) OSError: Socket is closed

 

Outcome:

Your Cisco router or switch should reload.

*Apr 14 08:06:18.842: %SYS-5-RELOAD: Reload requested by cisco on vty0 (192.168.30.181). Reload Reason: Reload command.

*Apr 14 08:06:21.873 Reload requested

 

Python Netmiko – Cisco router/switch ‘[reload]’

By italchemy

Things are getting more interesting using Netmiko. Thanks to Kirk Byers for maintaining Netmiko library up to date!

Step 1: Create a connection handler

import netmiko

connection = netmiko.ConnectHandler(ip=”192.168.30.161″, device_type=’cisco_ios’, username=’cisco’, password=’cisco123′)

 

Step 2: Check connection

connection

<netmiko.cisco.cisco_ios.CiscoIosSSH object at 0x7f6d862718e0>

 

Step 3: Save your configuration before reload.

connection.send_command_expect(‘write mem’)

‘Building configuration…\nCompressed configuration from 4115 bytes to 1979 bytes[OK]’

 

Step 4: For Cisco routers and switches, You are expecting expect_string='[confirm]’ Any response will trigger the device to reload after reload command is sent properly.

connection.send_command(‘reload’, expect_string='[confirm]’)

‘Proceed with reload? [confirm]’

connection.send_command(‘\n’)

OR

connection.send_command(‘y’)

OR

connection.disconnect()

Traceback (most recent call last): File “”, line 1, in File “/usr/local/lib/python3.8/dist-packages/netmiko/utilities.py”, line 347, in wrapper_decorator return func(self, *args, **kwargs) File “/usr/local/lib/python3.8/dist-packages/netmiko/base_connection.py”, line 1368, in send_command prompt = self.find_prompt(delay_factor=delay_factor) File “/usr/local/lib/python3.8/dist-packages/netmiko/base_connection.py”, line 1107, in find_prompt self.write_channel(self.RETURN) File “/usr/local/lib/python3.8/dist-packages/netmiko/base_connection.py”, line 436, in write_channel self._write_channel(out_data) File “/usr/local/lib/python3.8/dist-packages/netmiko/base_connection.py”, line 394, in _write_channel self.remote_conn.sendall(write_bytes(out_data, encoding=self.encoding)) File “/usr/local/lib/python3.8/dist-packages/paramiko/channel.py”, line 846, in sendall sent = self.send(s) File “/usr/local/lib/python3.8/dist-packages/paramiko/channel.py”, line 801, in send return self._send(s, m) File “/usr/local/lib/python3.8/dist-packages/paramiko/channel.py”, line 1198, in _send raise socket.error(“Socket is closed”) OSError: Socket is closed

 

Outcome:

Your Cisco router or switch should reload.

*Apr 14 08:06:18.842: %SYS-5-RELOAD: Reload requested by cisco on vty0 (192.168.30.181). Reload Reason: Reload command.

*Apr 14 08:06:21.873 Reload requested

 

Python + Regex 2 – Ask user input in correct IPv4 address format

By italchemy

Enforce user to input IPv4 address between 1.0.0.1 – 255.255.255.255. Until a valid ipv4 address is entered, the code loops.

 

/code

# user_input_ipv4.py

import re

 

def get_ftp_ip():

ip = input(“Enter FTP IP address: “)

while True:

#while not re.match(r”^\d+\.\d+\.\d+\.\d+$”,ip):

#while not [0<=int(x)<256 for x in re.split(‘\.’,re.match(r’^\d+\.\d+\.\d+\.\d+$’,ip).group(0))].count(True)==4:

while not re.match(r^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$”, ip)

ip = input(“Enter a valid FTP IP address: “)

else:

break

print(ip)

 

get_ftp_ip()

/code

 

===========

# Output

[root@localhost ]# nano user_input_ipv4.py
[root@localhost nuggets]# python3 test12345a.py
Enter FTP IP address: 10.10.10.256
Enter a valid FTP IP address: 1.1.1.257
Enter a valid FTP IP address: 1.1.1.255
1.1.1.255

[root@localhost ]# python3 user_input_ipv4.py
Enter FTP IP address: 255.255.255.256
Enter a valid FTP IP address: 255.255.255.255
255.255.255.255

[root@localhost ]# python3 user_input_ipv4.py
Enter FTP IP address: 10.10.10.1234
Enter a valid FTP IP address: 10.10.1
Enter a valid FTP IP address: 999.999.999.999
Enter a valid FTP IP address: 255.255.255.254
255.255.255.254

Python + Regex 1 – Ask user input in correct format, ending with specific string/text fotmat type

By italchemy

You expect users to enter specific response. In this example, I am expecting the first letter of the response to only include lower or upper A-Z and ends with .txt file format.

# user_input_sp1.py

import re

def get_new_ios():
new_ios = input(“Enter new text file name: “)
while True:
while not re.match(“^[a-zA-Z].*\.txt$”, new_ios):
new_ios = input(“Enter a valid text file name: “)
else:
break
print(new_ios)

get_new_ios()

# Output

[root@localhost ]# python3 user_input_sp1.py
Enter new text file name: abc.txt
abc.txt
[root@localhost ]# python3 user_input_sp1.py
Enter new IOS file name: abc
Enter a valid IOS file name: abcd
Enter a valid IOS file name: abcde.ppt
Enter a valid IOS file name: abcdef.bak
Enter a valid IOS file name: abcdefgtxt
Enter a valid IOS file name: abcdefgh.txt
abcdefgh.txt

[root@localhost ]# python3 user_input_sp1.py
Enter new text file name: 123abc.txt
Enter a valid text file name: 8abcde.txt
Enter a valid text file name: Abcde8.txt
Abcde8.txt

❌