Guest User

kong-setup

a guest
Oct 24th, 2017
31
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.50 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. import subprocess
  4. import traceback
  5. import time
  6. import os
  7. import sys
  8. import socket
  9. import psycopg2
  10. import random
  11. import string
  12.  
  13. from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
  14.  
  15.  
  16. class KongSetup(object):
  17. def __init__(self):
  18. self.hostname = ''
  19. self.ip = ''
  20.  
  21. self.installPostgress = True
  22. self.installRedis = True
  23. self.installOxd = True
  24.  
  25. self.cert_folder = './certs'
  26. self.template_folder = './templates'
  27. self.output_folder = './output'
  28.  
  29. self.logError = 'oxd-kong-setup_error.log'
  30. self.log = 'oxd-kong-setup.log'
  31.  
  32. self.kongConfigFile = '/etc/kong/kong.conf'
  33. self.kongCustomPlugins = 'kong-uma-rs'
  34.  
  35. self.oxdLicense = ''
  36.  
  37. self.kongSslCert = ''
  38. self.kongSslKey = ''
  39. self.templates = {'/etc/kong/kong.conf': True}
  40. self.pgPwd = ''
  41.  
  42. self.cmd_mkdir = '/bin/mkdir'
  43. self.opensslCommand = '/usr/bin/openssl'
  44. self.cmd_chown = '/bin/chown'
  45. self.cmd_chmod = '/bin/chmod'
  46.  
  47. self.countryCode = ''
  48. self.state = ''
  49. self.city = ''
  50. self.orgName = ''
  51. self.admin_email = ''
  52.  
  53. self.distFolder = '/usr/share'
  54. self.distKongGUIFolder = '%s/kongGUI' % self.distFolder
  55. self.distKongAPIGatewayFolder = '%s/kongAPIGateway' % self.distFolder
  56.  
  57. def configureRedis(self):
  58. return True
  59.  
  60. def configurePostgres(self):
  61. con = None
  62. try:
  63. pgPassword = self.getPrompt('Enter postgres password')
  64. self.pgPwd = self.getPrompt('Enter new kong user password')
  65. con = psycopg2.connect("host='localhost' dbname='postgres' user='postgres' password='%s'" % pgPassword)
  66. con.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
  67. cur = con.cursor()
  68. cur.execute("CREATE USER kong")
  69. cur.execute("ALTER USER kong WITH PASSWORD '%s'" % self.pgPwd)
  70. cur.execute("CREATE DATABASE kong OWNER kong")
  71. con.commit()
  72. except psycopg2.DatabaseError, e:
  73. if con:
  74. con.rollback()
  75. self.logIt('Error %s' % e)
  76. finally:
  77. if con:
  78. con.close()
  79.  
  80. def configureOxd(self):
  81. return True
  82.  
  83. def detect_hostname(self):
  84. detectedHostname = None
  85. try:
  86. detectedHostname = socket.gethostbyaddr(socket.gethostname())[0]
  87. except:
  88. try:
  89. detectedHostname = os.popen("/bin/hostname").read().strip()
  90. except:
  91. self.logIt("No detected hostname", True)
  92. self.logIt(traceback.format_exc(), True)
  93. return detectedHostname
  94.  
  95. def getExternalCassandraInfo(self):
  96. return True
  97.  
  98. def getExternalOxdInfo(self):
  99. return True
  100.  
  101. def getExternalPostgressInfo(self):
  102. return True
  103.  
  104. def getExternalRedisInfo(self):
  105. return True
  106.  
  107. def gen_cert(self, serviceName, password, user='root', cn=None):
  108. self.logIt('Generating Certificate for %s' % serviceName)
  109. key_with_password = '%s/%s.key.orig' % (self.cert_folder, serviceName)
  110. key = '%s/%s.key' % (self.cert_folder, serviceName)
  111. csr = '%s/%s.csr' % (self.cert_folder, serviceName)
  112. public_certificate = '%s/%s.crt' % (self.cert_folder, serviceName)
  113. self.run([self.opensslCommand,
  114. 'genrsa',
  115. '-des3',
  116. '-out',
  117. key_with_password,
  118. '-passout',
  119. 'pass:%s' % password,
  120. '2048'
  121. ])
  122. self.run([self.opensslCommand,
  123. 'rsa',
  124. '-in',
  125. key_with_password,
  126. '-passin',
  127. 'pass:%s' % password,
  128. '-out',
  129. key
  130. ])
  131.  
  132. certCn = cn
  133. if certCn == None:
  134. certCn = self.hostname
  135.  
  136. self.run([self.opensslCommand,
  137. 'req',
  138. '-new',
  139. '-key',
  140. key,
  141. '-out',
  142. csr,
  143. '-subj',
  144. '/C=%s/ST=%s/L=%s/O=%s/CN=%s/emailAddress=%s' % (
  145. self.countryCode, self.state, self.city, self.orgName, certCn, self.admin_email)
  146. ])
  147. self.run([self.opensslCommand,
  148. 'x509',
  149. '-req',
  150. '-days',
  151. '365',
  152. '-in',
  153. csr,
  154. '-signkey',
  155. key,
  156. '-out',
  157. public_certificate
  158. ])
  159. self.run([self.cmd_chown, '%s:%s' % (user, user), key_with_password])
  160. self.run([self.cmd_chmod, '700', key_with_password])
  161. self.run([self.cmd_chown, '%s:%s' % (user, user), key])
  162. self.run([self.cmd_chmod, '700', key])
  163.  
  164. def getPW(self, size=12, chars=string.ascii_uppercase + string.digits + string.lowercase):
  165. return ''.join(random.choice(chars) for _ in range(size))
  166.  
  167. def genKongSslCertificate(self):
  168. self.gen_cert('oxd-kong', self.getPW())
  169. self.kongSslCert = os.path.join(self.cert_folder, 'oxd-kong.crt')
  170. self.kongSslKey = os.path.join(self.cert_folder, 'oxd-kong.key')
  171.  
  172. def get_ip(self):
  173. testIP = None
  174. detectedIP = None
  175. try:
  176. testSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  177. detectedIP = [(testSocket.connect(('8.8.8.8', 80)),
  178. testSocket.getsockname()[0],
  179. testSocket.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]
  180. except:
  181. self.logIt("No detected IP address", True)
  182. self.logIt(traceback.format_exc(), True)
  183. if detectedIP:
  184. testIP = self.getPrompt("Enter IP Address", detectedIP)
  185. else:
  186. testIP = self.getPrompt("Enter IP Address")
  187. if not self.isIP(testIP):
  188. testIP = None
  189. print 'ERROR: The IP Address is invalid. Try again\n'
  190. return testIP
  191.  
  192. def getPrompt(self, prompt, defaultValue=None):
  193. try:
  194. if defaultValue:
  195. user_input = raw_input("%s [%s] : " % (prompt, defaultValue)).strip()
  196. if user_input == '':
  197. return defaultValue
  198. else:
  199. return user_input
  200. else:
  201. input = False
  202. while not input:
  203. user_input = raw_input("%s : " % prompt).strip()
  204. if user_input != '':
  205. input = True
  206. return user_input
  207. except KeyboardInterrupt:
  208. sys.exit()
  209. except:
  210. return None
  211.  
  212. def installSample(self):
  213. return True
  214.  
  215. def installKongGUI(self):
  216. # self.run(["cd %s ; sudo npm install; gulp serve" % self.distKongGUIFolder])
  217. self.run(["cd", self.distKongGUIFolder])
  218. self.run(["sudo", "npm", "install"])
  219. self.run(["gulp", "serve"])
  220.  
  221. def isIP(self, address):
  222. try:
  223. socket.inet_aton(address)
  224. return True
  225. except socket.error:
  226. return False
  227.  
  228. def logIt(self, msg, errorLog=False):
  229. if errorLog:
  230. f = open(self.logError, 'a')
  231. f.write('%s %s\n' % (time.strftime('%X %x'), msg))
  232. f.close()
  233. f = open(self.log, 'a')
  234. f.write('%s %s\n' % (time.strftime('%X %x'), msg))
  235. f.close()
  236.  
  237. def makeBoolean(self, c):
  238. if c in ['t', 'T']:
  239. return True
  240. if c in ['f', 'F']:
  241. return False
  242. self.logIt("makeBoolean: invalid value for true|false: " + c, True)
  243.  
  244. def makeFolders(self):
  245. try:
  246. self.run([self.cmd_mkdir, '-p', self.cert_folder])
  247. self.run([self.cmd_mkdir, '-p', self.output_folder])
  248. except:
  249. self.logIt("Error making folders", True)
  250. self.logIt(traceback.format_exc(), True)
  251.  
  252. def promptForProperties(self):
  253. self.ip = self.get_ip()
  254. self.hostname = self.getPrompt('Enter Kong hostname', self.detect_hostname())
  255. print 'The next few questions are used to generate the Kong self-signed certificate'
  256. self.countryCode = self.getPrompt('Country')
  257. self.state = self.getPrompt('State')
  258. self.city = self.getPrompt('City')
  259. self.orgName = self.getPrompt('Organizatoin')
  260. self.admin_email = self.getPrompt('email')
  261. print 'The next few questions will determine which components are installed'
  262. self.installOxd = self.makeBoolean(self.getPrompt("Install oxd?", "True")[0])
  263. self.installPostgress = self.makeBoolean(self.getPrompt("Install Postgress?", "True")[0])
  264. self.installRedis = self.makeBoolean(self.getPrompt("Install Redis?", "True")[0])
  265. if not self.installOxd:
  266. self.getExternalOxdInfo()
  267. if not self.installRedis:
  268. self.getExternalRedisInfo()
  269. if not self.installPostgress:
  270. externalPostgress = self.makeBoolean(self.getPrompt("Configfure External Postgress?", "True")[0])
  271. if externalPostgress:
  272. self.getExternalPostgressInfo()
  273. else:
  274. print "Defaulting to external Cassandra"
  275. self.getExternalCassandraInfo()
  276.  
  277. def render_templates(self):
  278. self.logIt("Rendering templates")
  279. for filePath in self.templates.keys():
  280. try:
  281. self.renderTemplate(filePath)
  282. except:
  283. self.logIt("Error writing template %s" % filePath, True)
  284. self.logIt(traceback.format_exc(), True)
  285.  
  286. def renderTemplate(self, filePath):
  287. self.renderTemplateInOut(filePath, self.template_folder, self.output_folder)
  288.  
  289. def renderTemplateInOut(self, filePath, templateFolder, outputFolder):
  290. self.logIt("Rendering template %s" % filePath)
  291. fn = os.path.split(filePath)[-1]
  292. f = open(os.path.join(templateFolder, fn))
  293. template_text = f.read()
  294. f.close()
  295. newFn = open(os.path.join(outputFolder, fn), 'w+')
  296. newFn.write(template_text % self.__dict__)
  297. newFn.close()
  298.  
  299. def run(self, args, cwd=None, env=None, usewait=False):
  300. self.logIt('Running: %s' % ' '.join(args))
  301. try:
  302. p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd, env=env)
  303. if usewait:
  304. code = p.wait()
  305. self.logIt('Run: %s with result code: %d' % (' '.join(args), code))
  306. else:
  307. output, err = p.communicate()
  308. if output:
  309. self.logIt(output)
  310. if err:
  311. self.logIt(err, True)
  312. except:
  313. self.logIt("Error running command : %s" % " ".join(args), True)
  314. self.logIt(traceback.format_exc(), True)
  315.  
  316. def startKong(self):
  317. self.run(["sudo", "kong", "start", os.path.join(self.output_folder, 'kong.conf')])
  318.  
  319. def stopKong(self):
  320. self.run(["sudo", "kong", "stop"])
  321.  
  322. def migrateKong(self):
  323. self.run(["sudo", "kong", "migrations", "up"])
  324.  
  325. def test(self):
  326. dbCmd = "/bin/echo 'Test'> /tmp/1"
  327. self.run(["sudo",
  328. "-u",
  329. "postgres",
  330. "/bin/bash",
  331. "-c",
  332. "\"" + dbCmd + "\""])
  333.  
  334.  
  335. if __name__ == "__main__":
  336. kongSetup = KongSetup()
  337. try:
  338. # kongSetup.test()
  339. kongSetup.installKongGUI()
  340. # kongSetup.makeFolders()
  341. # kongSetup.promptForProperties()
  342. # kongSetup.configureRedis()
  343. # kongSetup.configurePostgres()
  344. # kongSetup.configureOxd()
  345. # kongSetup.genKongSslCertificate()
  346. # kongSetup.render_templates()
  347. # kongSetup.stopKong()
  348. # kongSetup.migrateKong()
  349. # kongSetup.startKong()
  350. # kongSetup.installSample()
  351. # kongSetup.test()
  352. # print "\n\n oxd Kong installation successful! Point your browser to https://%s\n\n" % kongSetup.hostname
  353. except:
  354. kongSetup.logIt("***** Error caught in main loop *****", True)
  355. kongSetup.logIt(traceback.format_exc(), True)
  356. print "Installation failed. See: \n %s \n %s \nfor more details." % (kongSetup.log, kongSetup.logError)
Add Comment
Please, Sign In to add comment