How to add ping module in aws lambda using python - python-3.x

I want to monitor a server using AWS Lambda function with Python 3.9 version.
I'm using ping test connection and here's my code
import subprocess
import platform
def lambda_handler(event, context):
SERVERS = [
('203.124.136.164', 'Local Host 1')
]
for (server, name) in SERVERS:
check_connection(server, name)
def check_connection(server, name):
if ping(server):
print("%s is UP" % (name))
else:
print("%s is DOWN" % (name))
def ping(server):
try:
output = subprocess.check_output("ping -{} 1 {}".format('n' if platform.system().lower() == "windows" else 'c', server ), shell=True, universal_newlines=True)
if 'unreachable' in output:
print('unreachable')
return False
elif 'timed out' in output:
print('timed out')
return False
else:
print('success')
return True
except Exception as err:
print("An error occurred: %s" % (err.__str__()))
return False
But I got an error:
/bin/sh: ping: command not found
An error occurred: Command 'ping -c 1 203.124.136.164' returned non-zero exit status 127.
Why I got that error and what is the right implementation to monitor a server using IP?
I'm just a beginner. Please help!
Disclaimer: the IP provided on the code is just dummy.

I think AWS Lambda doesn't allow for ICMP to go outbound. It only allows for TCP or UDP outbound so since ping is neither it doesn't work. Even if you try to make a custom layer and import to Lambda you will get a permissions error since ICMP is not allowed.
Sorry my friend, the easiest work around I believe would to make a T1.micro to run the full python code.

Related

Odd behavior with threads

I'm developping a little script in PYTHON3 for pinging IPs ranges with multiples threads.
I only ping my localhost for now.
Here is my code:
#!/usr/bin/python3
import _thread
import os
# Define a function for the thread
def pingBox( threadName, value):
range='127.0.0.'
host=''+str(range)+str(value)
response = os.system("ping -c 1 "+host +"2>&1 >/dev/null") #to don't show the output
print('response for pinging %s is %s' %(threadName, response))
if response == 0:
print ('%s : is up' %host)
else:
print ('%s : is down' %host)
# Create one thread by ping
try:
for x in range (1,100):
_thread.start_new_thread( pingBox, ("Thread-"+str(x), x) )
except Exception as e: print(e)
while 1:
pass
With this code, I get some strange answer, like for instance :
response for pinging Thread-89 is 512
Why 512? I don't understand why response has this value.
PS: I know that for now, this code is a completely massacre regarding the threading aspect.
Here's a few mistakes I found:
Use threading library in python3. Read more about threading interfaces here.
The while loop at end makes no sense, please remove that.
Replacing with _thread with threading interfaces, your program will now look like:
#!/usr/bin/python3
import threading
import os
# Define a function for the thread
def pingBox( threadName, value):
range='127.0.0.'
host=''+str(range)+str(value)
response = os.system("ping -c 1 "+host +"2>&1 >/dev/null") #to don't show the output
print('response for pinging %s is %s' %(threadName, response))
if response == 0:
print ('%s : is up' %host)
else:
print ('%s : is down' %host)
# Create one thread by ping
try:
tlist = []
for x in range (1,100):
tlist.append(
threading.Thread(
target=pingBox,
kwargs={
"threadName": "Thread:{0}".format(x),
"value":x
}
))
for t in tlist:
t.start()
for t in tlist:
t.join()
except Exception as e:
print(e)

Sending COMMANDS and receiving respones(Reading) from RADWAG WTC 2000 Scale with Pyserial/Python3

I am so sorry for asking similar questions. But I managed to get some stuff yet I cannot make it work properly.
import serial
ser = serial.Serial(port='COM3', baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, timeout=1)
try:
ser.isOpen()
print("Serial port is open")
except:
print("ERROR")
exit()
if (ser.isOpen()):
try:
while (True):
ser.write("S CR LF")
print(ser.read())
except:
print("error")
else:
print("Cannot open serial port")
I learned that I should send some commands in order to receive information. https://imgur.com/Tburb5x https://imgur.com/ctRowoA https://imgur.com/WmkUOSe These are the Commands that I should use and then parse them in order to get the result only. This is what I get when I run this code. (I know, I should change the "ser.Write(this part)" but I don't know how?)
Serial port is open
error
Process finished with exit code 0
You can use the exceptions to know what is causing the error:
import serial
import sys
try:
ser = serial.Serial(port='COM3', baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, timeout=1)
while (True):
ser.write(str.encode("S\r\n"))
print(ser.read())
except serial.SerialException as e:
print("serial error:", e)
except:
print("other error:", sys.exc_info()[0])
So if, for example, you are using the wrong port, it will print:
error: could not open port 'COM3': FileNotFoundError(2, 'The system cannot find the file specified.', None, 2)
Edit: so the issue was that write wants a byte array and not a string. Though the docs say a string is ok (version 2.5).
The important thing is to not hide the exceptions. See: About catching ANY exception

At what point is the following Python socket-level-programming code stuck?

This is the server.py file which runs a basic server:
import socket
import sys
sockett = socket.socket()
sockett.bind(('127.0.0.1', 123))
sockett.listen(10)
while True:
print('1', end='')
while True:
print('2', end='')
try:
client, addr = sockett.accept()
print(client,addr)
break
except Exception as e:
print(e)
print(client.recv(400))
print(client.recv(1024))
print('3')
print('4')
And this is the client.py code that I am running:
import socket
import sys
sockett = socket.socket()
sockett.connect(('127.0.0.1', 123))
sockett.send(b'0')
print("Hello")
The doubt I have is that when I run the server.py (let S) file and then the client.py (let C) file, S keeps on running but C stops running which should be the case but the point at which S is stuck is the main problem. It prints 3 for the first time and then does not print anything, not 4 (so not out of the loop) not 1 (so not still looping). What could the reason be? Where is the code after it has printed 3?
This is the output I am getting:
12<socket......>(...)
b'0'
b''
3
_ (keeps on running indefinitely)
According to me, it should print 1 first, then 2, then run into an error which would be handled by try-except, and then print:
b''
b''
3
and then keep on looping like this.
The server is actually looping, but the reason you don't see the 1 or 2 when you're running this script is because you're not flushing your output:
import socket
import sys
sockett = socket.socket()
sockett.bind(('127.0.0.1', 123))
sockett.listen(10)
while True:
print('1', end='')
while True:
print('2', end='', flush=True)
try:
client, addr = sockett.accept()
print(client,addr)
break
except Exception as e:
print(e)
print(client.recv(400))
print(client.recv(1024))
print('3')
print('4')
You'll notice that with flush=True, in print('2', end='', flush=True) you'll see the 12 appear prior to the client's connection, and once again after the client disconnects.
12<socket...> (...)
b'0'
b''
3
12_ (keeps on running indefinitely)
With this, you can see that it's waiting again at client, addr = sockett.accept()
while True:
print('1', end='')
while True:
print('2', end='')
try:
client, addr = sockett.accept()
print(client,addr)
break
except Exception as e:
print(e)
This part will succeed (and not run into an error as you assume) once the client has connected.
print(client.recv(400))
This will read the b'0' send by the client.
print(client.recv(1024))
print('3')
This will wait for more data. Since the client closes the connection it will return with '', i.e. no data.
Then it will go to the beginning of the loop and from there into the inner loop where it is calling accept again. accept will block until it gets a new connection. Since you don't run the client again accept will block forever.

Unable to capture hostname on ping with gethostname

I'm new to python and I'm trying to ping my office network and trying to get the hostnames for an inventory system I'm trying to build for work. When I run the script below, I get the IP Address and get either Online or Offline, but I don't get the correct hostname. I only get the hostname of the computer sending out the ping. I think I need to capture it with a string but not sure how to do that. Ultimately this will be run in a GUI with the push of a button.
import ipaddress
from subprocess import PIPE, Popen
import socket
network = ipaddress.ip_network('192.168.1.0/24')
for i in network.hosts():
i = str(i)
h = socket.gethostname()
toping = Popen(['ping', '-c', '5', '-w', '100', i], stdout=PIPE)
output = toping.communicate()[0]
hostalive = toping.returncode
if hostalive == 0:
print(i)
print(h)
print("Is Online")
else:
print(i)
print("Is Offline")

Python 3.4 Socket and Threading issues

import sys
import socket
import threading
import time
QUIT = False
class ClientThread(threading.Thread): # Class that implements the client threads in this server
def __init__(self, client_sock): # Initialize the object, save the socket that this thread will use.
threading.Thread.__init__(self)
self.client = client_sock
def run(self): # Thread's main loop. Once this function returns, the thread is finished and dies.
global QUIT # Need to declare QUIT as global, since the method can change it/
done = False
cmd = self.readline() #Read data from the socket and process it
while not done:
if 'quit' == cmd:
self.writeline('Ok, bye')
QUIT = True
done = True
elif 'bye' == cmd:
self.writeline('Ok, bye')
done = True
else:
self.writeline(self.name)
cmd = self.readline()
self.client.close() # Make sure socket is closed when we're done with it
return
def readline(self): # Helper function, read up to 1024 chars from the socket, and returns them as a string
result = self.client.recv(1024)
if None != result: # All letters in lower case and without and end of line markers
result = result.strip().lower()
return result
def writeline(self, text): # Helper function, writes the given string to the socket with and end of line marker at end
self.client.send(text.strip() + '\n')
class Server: # Server class. Opens up a socket and listens for incoming connections.
def __init__(self): # Every time a new connection arrives, new thread object is created and
self.sock = None # defers the processing of the connection to it
self.thread_list = []
def run(self): # Server main loop: Creates the server (incoming) socket, listens > creates thread to handle it
all_good = False
try_count = 0 # Attempt to open the socket
while not all_good:
if 3 < try_count: # Tried more than 3 times without success, maybe post is in use by another program
sys.exit(1)
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Create the socket
port = 80
self.sock.bind(('127.0.0.1', port)) # Bind to the interface and port we want to listen on
self.sock.listen(5)
all_good = True
break
except socket.error, err:
print('Socket connection error... Waiting 10 seconds to retry.')
del self.sock
time.sleep(10)
try_count += 1
print( 'Server is listening for incoming connections.')
print('Try to connect through the command line with:')
print('telnet localhost 80')
print('and then type whatever you want.')
print()
print("typing 'bye' finishes the thread. but not the server",)
print("eg. you can quit telnet, run it again and get a different ",)
print("thread name")
print("typing 'quit' finishes the server")
try:
while not QUIT:
try:
self.sock.settimeout(0.500)
client = self.sock.accept()[0]
except socket.timeout:
time.sleep(1)
if QUIT:
print('Received quit command. Shutting down...')
break
continue
new_thread = ClientThread(client)
print('Incoming Connection. Started thread ',)
print(new_thread.getName())
self.thread_list.append(new_thread)
new_thread.start()
for thread in self.thread_list:
if not thread.isAlive():
self.thread_list.remove(thread)
thread.join()
except KeyboardInterrupt:
print('Ctrl+C pressed... Shutting Down')
except Exception as err:
print('Exception caught: %s\nClosing...' % err)
for thread in self.thread_list:
thread.join(1.0)
self.sock.close()
if "__main__" == __name__:
server = Server()
server.run()
print('Terminated')
Resolved many issues, these are the ones left, thank you guys!
1st error: socket.error, err.This specifically tells me that this no longer works in Python 3.4, but does not offer an alternative.
2nd Error: except socket.error, err: Python 3.4 does not support this syntax
3rd Error: self.readline(), I also have to assume writeline does not work also.
In this case, self.readline() is totally not working, I get an error that says AttributeError: 'ClientThread' object has no attribute 'readline'
This only happens after the thread is created. Console shows:
Incoming connection. Started thread.
Thread-1
Then flags that error.
4th Error: Cannot get 2to3 to run? Terminal says not recognised as internal command, and python console gives a big FU.
Can I get any rectification suggestions for the following errors please?
There are multiple issues that prevent your code from woring on python3
you're using python2 print statements, so your code can't possibly run on python3 where print() is a function.
the recv and send methods require/return bytes in python3, not str
the syntax for catching errors is except ExceptionClass as name
The first step in porting Python 2 code to Python 3 is to run it though the 2to3 program that comes with Python.
If you run your code through 2to3 with the -w option, it will fix a lot of your problems automagically.
> 2to3 -w --no-diffs socktest1.py
If you want to see what would be changed, but not change anything;
> 2to3 socktest1.py |less

Resources