import nmap

from st2actions.runners.pythonrunner import Action

"""
Note: This action requires nmap binary to be available and needs to run as root.
"""

class PortScanner(Action):

  def run(self, host):
    result = []
    port_details = {}
    ps = nmap.PortScanner()
    scan_res = ps.scan(host, arguments='--min-parallelism 100 -sT -sU -sZ')
    for target_host in ps.all_hosts():
      if target_host in ps.all_hosts():
        for comm in ps[target_host].all_protocols():
           if comm in ['tcp','udp','ip','sctp']:
             ports = ps[target_host][comm].keys()
             ports.sort()
             for port in ports:
               port_details = {port:{'state':ps[host][comm][port]['state'], 'service':ps[host][comm][port]['name'], 'protocol':comm}}
               result.append(port_details)

    return result

@@ -66,16 +66,18 @@
 %22%22%22%0ANote
+ 1
 : This a
@@ -122,40 +122,131 @@
 able
- and needs to run as root
+.%0A%0ANote 2: We only scan for open TCP ports since scanning for open UDP ports%0A        (-sU) requires root priveleges
 .%0A%22%22%22%0A%0A
+%0A
 clas
@@ -268,17 +268,16 @@
 ction):%0A
-%0A
   def ru
@@ -426,16 +426,8 @@
  -sT
- -sU -sZ
 ')%0A 
@@ -891,17 +891,16 @@
 etails)%0A
-%0A
     retu

Modify get_open_ports action to only scan for TCP ports so it doesn't require root privileges.