tools.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. #!/usr/bin/python
  2. # -*- coding: UTF-8 -*-
  3. from __future__ import print_function
  4. import os
  5. import commands
  6. import httplib, urllib
  7. import json
  8. import time
  9. import sys, getopt, random
  10. from kubernetes.client.rest import ApiException
  11. from pprint import pprint
  12. from kubernetes import client, config
  13. from aliyunsdkcore.client import AcsClient
  14. from aliyunsdkcore.acs_exception.exceptions import ClientException
  15. from aliyunsdkcore.acs_exception.exceptions import ServerException
  16. from aliyunsdkalidns.request.v20150109.AddDomainRecordRequest import AddDomainRecordRequest
  17. from aliyunsdkalidns.request.v20150109.DeleteDomainRecordRequest import DeleteDomainRecordRequest
  18. from aliyunsdkalidns.request.v20150109.DescribeDomainRecordsRequest import DescribeDomainRecordsRequest
  19. JNLP_ENV = os.getenv('JNLP_ENV')
  20. JNLP_TAG = os.getenv('JNLP_TAG')
  21. JNLP_VERSION = os.getenv('JNLP_VERSION')
  22. JNLP_CONTAINER_PORT = os.getenv('JNLP_CONTAINER_PORT')
  23. # JNLP_WAR = os.getenv('JNLP_WAR')
  24. JNLP_INGRESS = os.getenv('JNLP_INGRESS')
  25. JNLP_IMAGE = os.getenv('JNLP_IMAGE')
  26. JNLP_CONTROL_NAME = os.getenv('DRONE_REPO_NAME')
  27. JNLP_STORAGE_CLASS = os.getenv('JNLP_STORAGE_CLASS')
  28. JNLP_DOMAIN = os.getenv('JNLP_DOMAIN')
  29. JNLP_CONTROL = os.getenv('JNLP_CONTROL')
  30. JNLP_REPLICAS = os.getenv('JNLP_REPLICAS')
  31. JNLP_STORAGE_CAPACITY = os.getenv('JNLP_STORAGE_CAPACITY')
  32. JNLP_MOUNT_PATH = os.getenv('JNLP_MOUNT_PATH')
  33. JNLP_SVC_MODE = os.getenv('JNLP_SVC_MODE')
  34. NGINX_SVC = str(JNLP_ENV) + '/' + str(JNLP_CONTROL_NAME) + '-svc:' + str(JNLP_CONTAINER_PORT)
  35. NGINX_PORT = os.getenv('JNLP_CONTAINER_PORT')
  36. RECORD_NAME = os.getenv('JNLP_ENV') + "-" + os.getenv('DRONE_REPO_NAME')
  37. INGRESS_LIST_IN = ["10.26.32.137"]
  38. INGRESS_LIST_PUB = ["120.192.70.105"]
  39. NGINX_RECORD_IP = random.sample(INGRESS_LIST_PUB, 1)[0]
  40. DOMAINNAME = os.getenv('JNLP_DOMAIN').strip('.')
  41. # 生成deploy.yaml文件
  42. def deployYamlCreate():
  43. if JNLP_VERSION == "v1":
  44. tmpctl = '''
  45. config=`env|grep JNLP`
  46. template=`cat ./deploy-tmp.yaml`
  47. printf "$config\ncat << EOF\n$template\nEOF" | bash > ./deploy.yaml
  48. '''
  49. f1 = open("tempshell.sh","w")
  50. f1.writelines(tmpctl)
  51. f1.close()
  52. status,output = commands.getstatusoutput("sh tempshell.sh && rm -f tempshell.sh")
  53. print("code:" + str(status) + str(output) + "; create deploy.yaml success !!!")
  54. return status,output
  55. elif JNLP_VERSION == "v2":
  56. tmpctl = '''
  57. config=`env|grep JNLP`
  58. template=`cat ./deploy-tmp-v2.yaml`
  59. printf "$config\ncat << EOF\n$template\nEOF" | bash > ./deploy.yaml
  60. '''
  61. f1 = open("tempshell.sh","w")
  62. f1.writelines(tmpctl)
  63. f1.close()
  64. status,output = commands.getstatusoutput("sh tempshell.sh && rm -f tempshell.sh")
  65. print("code:" + str(status) + str(output) + "; create deploy.yaml success !!!")
  66. return status,output
  67. else:
  68. print("Can Not Find JNLP_VERSION, Please Check !!!")
  69. return "Can Not Find JNLP_VERSION, Please Check !!!"
  70. # 生成Dockerfile文件
  71. def DockerfileCreate():
  72. tmp = '''
  73. onfig=`env|grep JNLP`
  74. template=`cat ./Dockerfile`
  75. printf "$config\ncat << EOF\n$template\nEOF" | bash > ./Dockerfile
  76. '''
  77. f2 = open("tmp.sh","w")
  78. f2.writelines(tmp)
  79. f2.close()
  80. status,output = commands.getstatusoutput("sh tmp.sh && rm -f tmp.sh")
  81. print("code:" + str(status) + str(output) + "; create Dockerfile success !!!")
  82. return
  83. # 更新haproxy configmap.json配置文件,生成TCP服务转发记录
  84. def updateConfigMap(file):
  85. if JNLP_SVC_MODE == "tcp":
  86. data = {}
  87. data[NGINX_PORT] = NGINX_SVC
  88. status, output = commands.getstatusoutput("kubectl get cm tcp-services -n ingress-nginx -o=json")
  89. tempdict = eval(output)
  90. tempdict['data'][NGINX_PORT] = NGINX_SVC
  91. newdata = tempdict['data']
  92. print(newdata,status)
  93. old_str = "CMDATA"
  94. new_str = str(newdata).replace("'",'"')
  95. with open(file, "r") as f1,open("%s.bak" % file, "w" ) as f2:
  96. for line in f1:
  97. if old_str in line:
  98. line = line.replace(old_str, new_str)
  99. f2.write(line)
  100. os.remove(file)
  101. os.rename("%s.bak" % file, file)
  102. cmStatus = "1"
  103. else:
  104. print("****** Nginx Tcp Services Configmap.json Do Not Update ******")
  105. cmStatus = "0"
  106. return cmStatus
  107. # 部署应用到kubernetes平台
  108. def deployToKube():
  109. cmStatus = updateConfigMap("configmap.json")
  110. appStatus = commands.getoutput("kubectl get sts $JNLP_CONTROL_NAME -n $JNLP_NAMESPACE|grep $JNLP_CONTROL_NAME|wc -l")
  111. if appStatus == "1" and cmStatus == "1":
  112. print("Warning:" + JNLP_CONTROL_NAME + " is already, i will update it and update nginx tcp proxy !!!")
  113. apply_out = commands.getoutput("kubectl apply -f ./deploy.yaml && kubectl apply -f ./configmap.json")
  114. print("===>>> kubectl apply output <<<===")
  115. print(apply_out)
  116. elif appStatus == "1" and cmStatus == "0":
  117. print("Warning:" + JNLP_CONTROL_NAME + " is already, i will update it !!!")
  118. apply_out = commands.getoutput("kubectl apply -f ./deploy.yaml")
  119. print("===>>> kubectl apply output <<<===")
  120. print(apply_out)
  121. elif appStatus != "1" and cmStatus == "1":
  122. apply_out = commands.getoutput("kubectl apply -f ./deploy.yaml && kubectl apply -f ./configmap.json")
  123. print("===>>> kubectl apply output <<<===")
  124. print(apply_out)
  125. print("===>>> apply is successfull <<<===")
  126. else:
  127. apply_out = commands.getoutput("kubectl apply -f ./deploy.yaml")
  128. print("===>>> kubectl apply output <<<===")
  129. print(apply_out)
  130. print("===>>> apply app successfull <<<===")
  131. return
  132. # 部署应用状态获取
  133. # 20200615新增
  134. def appStatusCheck():
  135. cmd = "kubedog rollout track statefulset " + JNLP_CONTROL_NAME + " -n " + JNLP_ENV
  136. appStatus = commands.getstatusoutput(cmd)
  137. if appStatus[0] == 0:
  138. print("===>>> statefulset: " + JNLP_ENV + "/" + JNLP_CONTROL_NAME + " is running ... <<<===")
  139. else:
  140. print("===>>> statefulset: " + JNLP_ENV + "/" + JNLP_CONTROL_NAME + " is error, Please Check or Connect Administrator !!! <<<===")
  141. return appStatus
  142. # 不再使用该方法检查服务状态
  143. def deployStatus():
  144. kubeconfig = config.kube_config.load_kube_config(config_file="/root/.kube/config")
  145. appsv1_api_instance = client.AppsV1Api(kubeconfig)
  146. namespace = JNLP_ENV
  147. stsname = JNLP_CONTROL_NAME
  148. pretty = "true"
  149. for x in range(20):
  150. try:
  151. sts_response = appsv1_api_instance.read_namespaced_stateful_set_status(stsname, namespace, pretty=pretty)
  152. if sts_response.status.replicas == sts_response.status.ready_replicas :
  153. print("===>>> " +stsname + " is RUNNING <<<===")
  154. chk_status = 1
  155. break
  156. else:
  157. if x < 40:
  158. time.sleep(15)
  159. else:
  160. chk_status = 0
  161. print(stsname + " status check fail !!! , Please contact kubernetes systen administrator")
  162. except ApiException as e:
  163. print("Exception when calling CoreV1Api->list_namespaced_pod: %s\n" % e)
  164. return chk_status
  165. # DNS解析
  166. # 域名由jenkins项目名+命名空间+dns域组合而成
  167. # 如果域名已存在,不会再更新
  168. def dnsAllocation():
  169. if JNLP_INGRESS == "nginx":
  170. httpClient = httplib.HTTPConnection("opsadmin.evbj.easou.com", 80, timeout=30)
  171. headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain"}
  172. params = urllib.urlencode({'method': 'add', 'type': 'record', 'domain_id': 24, 'record_type': 'A', 'record_name': RECORD_NAME ,'record_ip': NGINX_RECORD_IP , 'record_ttl': 180})
  173. httpClient.request("POST", "/dns/dnsapi/?token=c2d1856be235a3207cd03b6f4d3c4094", params, headers)
  174. response = httpClient.getresponse().read()
  175. jstr = json.loads(response)
  176. nsStatus = jstr['status']
  177. print(NGINX_RECORD_IP)
  178. if nsStatus == "-501":
  179. print(JNLP_ENV + "-" + JNLP_CONTROL_NAME + JNLP_DOMAIN + " is already exist")
  180. elif nsStatus == "0":
  181. httpClient = httplib.HTTPConnection("opsadmin.evbj.easou.com", 80, timeout=30)
  182. httpClient.request("POST", "/dns/mkconfig/?token=c2d1856be235a3207cd03b6f4d3c4094")
  183. response = httpClient.getresponse().read()
  184. jstr = json.loads(response)
  185. upStatus = jstr['status']
  186. print(JNLP_ENV + "-" + JNLP_CONTROL_NAME + JNLP_DOMAIN + " " +upStatus + " add successfull !!!")
  187. else:
  188. print("*****Please contact DNS systen administrator*****")
  189. else :
  190. print(">>> Ingress error, Only nginx !!! <<<")
  191. return
  192. def cloudDns():
  193. if JNLP_INGRESS == "nginx":
  194. client = AcsClient('LTAI4Fv2cVQGqCkscSuxgx49', '9e13VJa66veTCjsNocBxA09CTcVIi5', 'cn-hangzhou')
  195. # describe record
  196. request = DescribeDomainRecordsRequest()
  197. request.set_accept_format('json')
  198. request.set_DomainName(DOMAINNAME)
  199. request.set_RRKeyWord(RECORD_NAME)
  200. response = client.do_action_with_exception(request)
  201. jsondata = json.loads(response)
  202. # print(response)
  203. if jsondata['TotalCount'] != 0:
  204. print(RECORD_NAME + "." + DOMAINNAME + " is already exists <<<")
  205. else :
  206. # add record
  207. request = AddDomainRecordRequest()
  208. request.set_accept_format('json')
  209. request.set_Value(NGINX_RECORD_IP)
  210. request.set_Type("A")
  211. request.set_RR(RECORD_NAME)
  212. request.set_DomainName(DOMAINNAME)
  213. response = client.do_action_with_exception(request)
  214. # print(response)
  215. print(RECORD_NAME + "." + DOMAINNAME + " add sucess <<<")
  216. else :
  217. print(">>> Ingress error, Only nginx !!! <<<")
  218. return
  219. def main(argv=None):
  220. if argv is None:
  221. args = sys.argv[1:]
  222. for opt_name in args :
  223. if opt_name in ('-a','--apply'):
  224. print("===>>> deploy app to kubernetes <<<===")
  225. deployToKube()
  226. time.sleep(10)
  227. sys.exit()
  228. if opt_name in ('-b','--build'):
  229. print("===>>> create deploy.yaml <<<===")
  230. deployYamlCreate()
  231. sys.exit()
  232. if opt_name in ('-c','--check'):
  233. print("===>>> app status check <<<===")
  234. appStatusCheck()
  235. sys.exit()
  236. if opt_name in ('-d','--dns'):
  237. print("===>>> add/update dns resolve <<<===")
  238. cloudDns()
  239. sys.exit()
  240. return
  241. if __name__ == "__main__":
  242. main()