pbs_cliutils.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. # coding: utf-8
  2. # Copyright (C) 1994-2018 Altair Engineering, Inc.
  3. # For more information, contact Altair at www.altair.com.
  4. #
  5. # This file is part of the PBS Professional ("PBS Pro") software.
  6. #
  7. # Open Source License Information:
  8. #
  9. # PBS Pro is free software. You can redistribute it and/or modify it under the
  10. # terms of the GNU Affero General Public License as published by the Free
  11. # Software Foundation, either version 3 of the License, or (at your option) any
  12. # later version.
  13. #
  14. # PBS Pro is distributed in the hope that it will be useful, but WITHOUT ANY
  15. # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  16. # FOR A PARTICULAR PURPOSE.
  17. # See the GNU Affero General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU Affero General Public License
  20. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. #
  22. # Commercial License Information:
  23. #
  24. # For a copy of the commercial license terms and conditions,
  25. # go to: (http://www.pbspro.com/UserArea/agreement.html)
  26. # or contact the Altair Legal Department.
  27. #
  28. # Altair’s dual-license business model allows companies, individuals, and
  29. # organizations to create proprietary derivative works of PBS Pro and
  30. # distribute them - whether embedded or bundled with other software -
  31. # under a commercial license agreement.
  32. #
  33. # Use of Altair’s trademarks, including but not limited to "PBS™",
  34. # "PBS Professional®", and "PBS Pro™" and Altair’s logos is subject to Altair's
  35. # trademark licensing policies.
  36. import logging
  37. import os
  38. import re
  39. class CliUtils(object):
  40. """
  41. Command line interface utility
  42. """
  43. @classmethod
  44. def get_logging_level(cls, level):
  45. """
  46. Get the logging levels
  47. :param level: Name of the logging level
  48. :type level: str
  49. """
  50. logging.DEBUG2 = logging.DEBUG - 1
  51. logging.INFOCLI = logging.INFO - 1
  52. logging.INFOCLI2 = logging.INFOCLI - 1
  53. l = None
  54. level = str(level).upper()
  55. if level == 'INFO':
  56. l = logging.INFO
  57. elif level == 'INFOCLI':
  58. l = logging.INFOCLI
  59. elif level == 'INFOCLI2':
  60. l = logging.INFOCLI2
  61. elif level == 'DEBUG':
  62. l = logging.DEBUG
  63. elif level == 'DEBUG2':
  64. l = logging.DEBUG2
  65. elif level == 'WARNING':
  66. l = logging.WARNING
  67. elif level == 'ERROR':
  68. l = logging.ERROR
  69. elif level == 'FATAL':
  70. l = logging.FATAL
  71. return l
  72. @staticmethod
  73. def check_bin(bin_name):
  74. """
  75. Check for command exist
  76. :param bin_name: Command to be checked
  77. :type bin_name: str
  78. :returns: True if command exist else return False
  79. """
  80. ec = os.system("/usr/bin/which " + bin_name + " > /dev/null")
  81. if ec == 0:
  82. return True
  83. return False
  84. @staticmethod
  85. def __json__(data):
  86. try:
  87. import json
  88. return json.dumps(data, sort_keys=True, indent=4)
  89. except:
  90. # first escape any existing double quotes
  91. _pre = str(data).replace('"', '\\"')
  92. # only then, replace the single quotes with double quotes
  93. return _pre.replace('\'', '"')
  94. @staticmethod
  95. def expand_abs_path(path):
  96. """
  97. Expand the path to absolute path
  98. """
  99. if path.startswith('~'):
  100. return os.path.expanduser(path)
  101. return os.path.abspath(path)
  102. @staticmethod
  103. def priv_ports_info(hostname=None):
  104. """
  105. Return a list of privileged ports in use on a given host
  106. :param hostname: The host on which to query privilege ports
  107. usage. Defaults to the local host
  108. :type hostname: str or None
  109. """
  110. from ptl.utils.pbs_dshutils import DshUtils
  111. netstat_tag = re.compile("tcp[\s]+[\d]+[\s]+[\d]+[\s]+"
  112. "(?P<srchost>[\w\*\.]+):(?P<srcport>[\d]+)"
  113. "[\s]+(?P<desthost>[\.\w\*:]+):"
  114. "(?P<destport>[\d]+)"
  115. "[\s]+(?P<state>[\w]+).*")
  116. du = DshUtils()
  117. ret = du.run_cmd(hostname, ['netstat', '-at', '--numeric-ports'])
  118. if ret['rc'] != 0:
  119. return False
  120. msg = []
  121. lines = ret['out']
  122. resv_ports = {}
  123. source_hosts = []
  124. for line in lines:
  125. m = netstat_tag.match(line)
  126. if m:
  127. srcport = int(m.group('srcport'))
  128. srchost = m.group('srchost')
  129. destport = int(m.group('destport'))
  130. desthost = m.group('desthost')
  131. if srcport < 1024:
  132. if srchost not in source_hosts:
  133. source_hosts.append(srchost)
  134. msg.append(line)
  135. if srchost not in resv_ports:
  136. resv_ports[srchost] = [srcport]
  137. elif srcport not in resv_ports[srchost]:
  138. resv_ports[srchost].append(srcport)
  139. if destport < 1024:
  140. msg.append(line)
  141. if desthost not in resv_ports:
  142. resv_ports[desthost] = [destport]
  143. elif destport not in resv_ports[desthost]:
  144. resv_ports[desthost].append(destport)
  145. if len(resv_ports) > 0:
  146. msg.append('\nPrivilege ports in use: ')
  147. for k, v in resv_ports.items():
  148. msg.append('\t' + k + ': ' +
  149. str(",".join(map(lambda l: str(l), v))))
  150. for sh in source_hosts:
  151. msg.append('\nTotal on ' + sh + ': ' +
  152. str(len(resv_ports[sh])))
  153. else:
  154. msg.append('No privileged ports currently allocated')
  155. return msg