#!/usr/bin/python # -*- coding: UTF-8 -*- from __future__ import print_function import os import commands import httplib, urllib import json import time from kubernetes.client.rest import ApiException from pprint import pprint from kubernetes import client, config import sys, getopt, random from aliyunsdkcore.client import AcsClient from aliyunsdkcore.acs_exception.exceptions import ClientException from aliyunsdkcore.acs_exception.exceptions import ServerException from aliyunsdkalidns.request.v20150109.AddDomainRecordRequest import AddDomainRecordRequest from aliyunsdkalidns.request.v20150109.DeleteDomainRecordRequest import DeleteDomainRecordRequest from aliyunsdkalidns.request.v20150109.DescribeDomainRecordsRequest import DescribeDomainRecordsRequest JNLP_ENV = os.getenv('JNLP_ENV') JNLP_TAG = os.getenv('JNLP_TAG') JNLP_CONTAINER_PORT = os.getenv('JNLP_CONTAINER_PORT') # JNLP_WAR = os.getenv('JNLP_WAR') JNLP_INGRESS = os.getenv('JNLP_INGRESS') JNLP_IMAGE = os.getenv('JNLP_IMAGE') JNLP_CONTROL_NAME = os.getenv('DRONE_REPO_NAME') JNLP_STORAGE_CLASS = os.getenv('JNLP_STORAGE_CLASS') JNLP_DOMAIN = os.getenv('JNLP_DOMAIN') JNLP_CONTROL = os.getenv('JNLP_CONTROL') JNLP_REPLICAS = os.getenv('JNLP_REPLICAS') JNLP_STORAGE_CAPACITY = os.getenv('JNLP_STORAGE_CAPACITY') JNLP_MOUNT_PATH = os.getenv('JNLP_MOUNT_PATH') JNLP_SVC_MODE = os.getenv('JNLP_SVC_MODE') NGINX_SVC = str(JNLP_ENV) + '/' + str(JNLP_CONTROL_NAME) + '-svc:' + str(JNLP_CONTAINER_PORT) NGINX_PORT = os.getenv('JNLP_CONTAINER_PORT') RECORD_NAME = os.getenv('JNLP_ENV') + "-" + os.getenv('DRONE_REPO_NAME') INGRESS_LIST_IN = ["10.26.32.137"] INGRESS_LIST_PUB = ["120.192.70.105"] NGINX_RECORD_IP = random.sample(INGRESS_LIST_PUB, 1)[0] DOMAINNAME = os.getenv('JNLP_DOMAIN').strip('.') # 生成deploy.yaml文件 def deployYamlCreate(): tmpctl = ''' config=`env|grep JNLP` template=`cat ./deploy-tmp.yaml` printf "$config\ncat << EOF\n$template\nEOF" | bash > ./deploy.yaml ''' f1 = open("tempshell.sh","w") f1.writelines(tmpctl) f1.close() status,output = commands.getstatusoutput("sh tempshell.sh && rm -f tempshell.sh") print("code:" + str(status) + str(output) + "; create deploy.yaml success !!!") return status,output # 生成Dockerfile文件 def DockerfileCreate(): tmp = ''' onfig=`env|grep JNLP` template=`cat ./Dockerfile` printf "$config\ncat << EOF\n$template\nEOF" | bash > ./Dockerfile ''' f2 = open("tmp.sh","w") f2.writelines(tmp) f2.close() status,output = commands.getstatusoutput("sh tmp.sh && rm -f tmp.sh") print("code:" + str(status) + str(output) + "; create Dockerfile success !!!") return # 更新haproxy configmap.json配置文件,生成TCP服务转发记录 def updateConfigMap(file): if JNLP_SVC_MODE == "tcp": data = {} data[NGINX_PORT] = NGINX_SVC status, output = commands.getstatusoutput("kubectl get cm tcp-services -n ingress-nginx -o=json") tempdict = eval(output) tempdict['data'][NGINX_PORT] = NGINX_SVC newdata = tempdict['data'] print(newdata,status) old_str = "CMDATA" new_str = str(newdata).replace("'",'"') with open(file, "r") as f1,open("%s.bak" % file, "w" ) as f2: for line in f1: if old_str in line: line = line.replace(old_str, new_str) f2.write(line) os.remove(file) os.rename("%s.bak" % file, file) cmStatus = "1" else: print("****** Nginx Tcp Services Configmap.json Do Not Update ******") cmStatus = "0" return cmStatus # 部署应用到kubernetes平台 def deployToKube(): cmStatus = updateConfigMap("configmap.json") appStatus = commands.getoutput("kubectl get sts $JNLP_CONTROL_NAME -n $JNLP_NAMESPACE|grep $JNLP_CONTROL_NAME|wc -l") if appStatus == "1" and cmStatus == "1": print("Warning:" + JNLP_CONTROL_NAME + " is already, i will update it and update nginx tcp proxy !!!") apply_out = commands.getoutput("kubectl apply -f ./deploy.yaml && kubectl apply -f ./configmap.json") print("===>>> kubectl apply output <<<===") print(apply_out) elif appStatus == "1" and cmStatus == "0": print("Warning:" + JNLP_CONTROL_NAME + " is already, i will update it !!!") apply_out = commands.getoutput("kubectl apply -f ./deploy.yaml") print("===>>> kubectl apply output <<<===") print(apply_out) elif appStatus != "1" and cmStatus == "1": apply_out = commands.getoutput("kubectl apply -f ./deploy.yaml && kubectl apply -f ./configmap.json") print("===>>> kubectl apply output <<<===") print(apply_out) print("===>>> apply is successfull <<<===") else: apply_out = commands.getoutput("kubectl apply -f ./deploy.yaml") print("===>>> kubectl apply output <<<===") print(apply_out) print("===>>> apply app successfull <<<===") return # 部署应用状态获取 def deployStatus(): kubeconfig = config.kube_config.load_kube_config(config_file="/root/.kube/config") appsv1_api_instance = client.AppsV1Api(kubeconfig) namespace = JNLP_ENV stsname = JNLP_CONTROL_NAME pretty = "true" for x in range(20): try: sts_response = appsv1_api_instance.read_namespaced_stateful_set_status(stsname, namespace, pretty=pretty) if sts_response.status.replicas == sts_response.status.ready_replicas : print("===>>> " +stsname + " is RUNNING <<<===") chk_status = 1 break else: if x < 40: time.sleep(15) else: chk_status = 0 print(stsname + " status check fail !!! , Please contact kubernetes systen administrator") except ApiException as e: print("Exception when calling CoreV1Api->list_namespaced_pod: %s\n" % e) return chk_status # DNS解析 # 域名由jenkins项目名+命名空间+dns域组合而成 # 如果域名已存在,不会再更新 def dnsAllocation(): if JNLP_INGRESS == "nginx": httpClient = httplib.HTTPConnection("opsadmin.evbj.easou.com", 80, timeout=30) headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain"} 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}) httpClient.request("POST", "/dns/dnsapi/?token=c2d1856be235a3207cd03b6f4d3c4094", params, headers) response = httpClient.getresponse().read() jstr = json.loads(response) nsStatus = jstr['status'] print(NGINX_RECORD_IP) if nsStatus == "-501": print(JNLP_ENV + "-" + JNLP_CONTROL_NAME + JNLP_DOMAIN + " is already exist") elif nsStatus == "0": httpClient = httplib.HTTPConnection("opsadmin.evbj.easou.com", 80, timeout=30) httpClient.request("POST", "/dns/mkconfig/?token=c2d1856be235a3207cd03b6f4d3c4094") response = httpClient.getresponse().read() jstr = json.loads(response) upStatus = jstr['status'] print(JNLP_ENV + "-" + JNLP_CONTROL_NAME + JNLP_DOMAIN + " " +upStatus + " add successfull !!!") else: print("*****Please contact DNS systen administrator*****") else : print(">>> Ingress error, Only nginx !!! <<<") return def cloudDns(): if JNLP_INGRESS == "nginx": client = AcsClient('LTAI4LibOCW5ilIa', 'NiA9OumXJDHp4TwLwXWcCKGoDgDjms', 'cn-hangzhou') # describe record request = DescribeDomainRecordsRequest() request.set_accept_format('json') request.set_DomainName(DOMAINNAME) request.set_RRKeyWord(RECORD_NAME) response = client.do_action_with_exception(request) jsondata = json.loads(response) # print(response) if jsondata['TotalCount'] != 0: print(RECORD_NAME + "." + DOMAINNAME + " is already exists <<<") else : # add record request = AddDomainRecordRequest() request.set_accept_format('json') request.set_Value(NGINX_RECORD_IP) request.set_Type("A") request.set_RR(RECORD_NAME) request.set_DomainName(DOMAINNAME) response = client.do_action_with_exception(request) # print(response) print(RECORD_NAME + "." + DOMAINNAME + " add sucess <<<") else : print(">>> Ingress error, Only nginx !!! <<<") return def main(argv=None): if argv is None: args = sys.argv[1:] for opt_name in args : if opt_name in ('-a','--apply'): print("===>>> deploy app to kubernetes <<<===") deployToKube() time.sleep(10) sys.exit() if opt_name in ('-b','--build'): print("===>>> create deploy.yaml <<<===") deployYamlCreate() sys.exit() if opt_name in ('-c','--check'): print("===>>> app status check <<<===") deployStatus() sys.exit() if opt_name in ('-d','--dns'): print("===>>> add/update dns resolve <<<===") cloudDns() sys.exit() return if __name__ == "__main__": main()