Ejemplo n.º 1
0
def k8s_pod_delete(context=None, dm_name=None):
    if context and dm_name:
        Scheduler = produce.SchedulerPublish()
        Scheduler = Scheduler.Scheduler_mem(k8s_resource.api_delete_pod,
                                            [context, dm_name])
        Scheduler.start()
    return jsonify({'result': 'ok'})
Ejemplo n.º 2
0
def m_image_update():
    try:
        tools.Async_log(g.user, request.url)
        reload(MyForm)
        form = MyForm.FormK8sUpdate()
        if form.submit.data:
            deployment = form.deployment.data
            version = form.version.data
            context = form.contexts.data
            if version:
                new_image = "%s/%s:%s" % (docker_registry, deployment, version)
                new_replicas = form.replicas.data
                redis_key = 'op_k8s_update_%s' % time.strftime(
                    '%Y%m%d%H%M%S', time.localtime())
                Scheduler = produce.SchedulerPublish()
                Scheduler = Scheduler.Scheduler_mem(
                    k8s_resource.object_update, [
                        context, new_image, new_replicas, version, redis_key,
                        'web'
                    ])
                Scheduler.start()
                return render_template('mobile/m_deploy_show.html',
                                       redis_key=redis_key)
    except Exception as e:
        logging.error(e)
    return render_template('mobile/m_k8s_update.html', form=form)
Ejemplo n.º 3
0
def image_update():
    try:
        tools.Async_log(g.user, request.url)
        reload(MyForm)
        form = MyForm.FormK8sUpdate()
        if form.submit.data:
            rollback = False
            deployment = form.deployment.data
            version = form.version.data
            context = form.contexts.data
            rollback_image = form.images.data
            if version or rollback_image:
                new_image = "%s/%s:%s" % (docker_registry, deployment, version)
                if rollback_image:
                    rollback = True
                    new_image = rollback_image
                redis_key = 'op_k8s_update_%s' % time.strftime(
                    '%Y%m%d%H%M%S', time.localtime())
                Scheduler = produce.SchedulerPublish()
                Scheduler = Scheduler.Scheduler_mem(
                    k8s_resource.object_update,
                    [context, new_image, version, rollback, redis_key, 'web'])
                Scheduler.start()
                return render_template('deploy_show.html', redis_key=redis_key)
    except Exception as e:
        logging.error(e)
        return redirect(url_for('error'))
    return render_template('k8s_update.html', form=form)
Ejemplo n.º 4
0
def image_update():
    try:
        tools.Async_log(g.user, request.url)
        reload(MyForm)
        form = MyForm.FormK8sUpdate()
        db_deploy = db_op.k8s_deploy
        rollback = False
        if form.submit.data:
            deployment = form.deployment.data
            version = form.version.data
            context = form.contexts.data
            action = form.action.data
            if version:
                image = "%s/%s:%s" % (docker_registry[context], deployment,
                                      version)
                if action == 'rollback':
                    rollback = True
                    val = db_deploy.query.filter(
                        db_deploy.image == image).all()
                    if not val:
                        flash('%s版本镜像不存在!' % version)
                        return render_template('Message.html')
                redis_key = 'op_k8s_update_%s' % time.strftime(
                    '%Y%m%d%H%M%S', time.localtime())
                Scheduler = produce.SchedulerPublish()
                Scheduler = Scheduler.Scheduler_mem(
                    k8s_resource.object_update,
                    [context, image, version, rollback, redis_key, 'web'])
                Scheduler.start()
                return render_template('deploy_show.html', redis_key=redis_key)
    except Exception as e:
        logging.error(e)
        return redirect(url_for('error'))
    return render_template('k8s_update.html', form=form)
Ejemplo n.º 5
0
def k8s_project_update():
    db_token = db_op.platform_token
    params = request.get_json()
    new_replicas = None
    msg = None
    project = None
    version = None
    try:
        if params:
            if 'project' in params and 'version' in params and 'access_token' in params and 'context' in params:
                token = params['access_token']
                project = params['project']
                version = params['version']
                context = params['context']
                new_image = "%s/%s:%s" % (docker_registry[context],
                                          project.split('.')[0], version)
                if 'replicas' in params:
                    new_replicas = params['replicas']
                # 验证token是否有效
                vals = db_token.query.filter(
                    and_(
                        db_token.token == token,
                        db_token.expire > time.strftime(
                            '%Y-%m-%d', time.localtime()))).all()
                if vals:
                    redis_key = 'op_k8s_update_%s' % time.strftime(
                        '%Y%m%d%H%M%S', time.localtime())
                    Scheduler = produce.SchedulerPublish()
                    Scheduler = Scheduler.Scheduler_mem(
                        k8s_resource.object_update, [
                            context, new_image, new_replicas, version,
                            redis_key, 'api'
                        ])
                    Scheduler.start()
                else:
                    msg = '授权验证不通过!'
            else:
                msg = '传递参数错误!'
        else:
            msg = '传递参数不能为空!'
    except Exception as e:
        msg = e
    finally:
        if msg:
            ops_token = app.config.get('OPS_TOKEN')
            text = [
                '**容器平台自动上线:**',
                "项目:%s" % project,
                "版本:%s" % version,
                "Error:%s" % msg, '**请确认请求正确!**'
            ]
            tools.dingding_msg(text, ops_token)
        return jsonify({'result': 'ok'})
Ejemplo n.º 6
0
def Publish_center(args):
    try:
        INFOS, Msg_Key, secret_key = args
        server_lists_counts = 0
        #获取上线操作参数
        execute = INFOS['execute']
        channel = INFOS['channel']
        flow_number = INFOS['timestamp']
        _flow_log(flow_number,
                  'Publish center(%s) start work ......' % os.getpid())
        _flow_log(flow_number, INFOS)
        _console_out(channel, Msg_Key, '-' * 100)
        _console_out(channel, Msg_Key, "初始化代码分发参数及检测部署环境,检测进行中......")
        #页面回滚操作需要将部分参数回写
        if execute == 'rollback' and channel == 'web':
            project = INFOS['project']
            version = INFOS['version']
            vals = db_publish.query.with_entities(
                db_publish.package_url, db_publish.package_md5,
                db_publish.package_type, db_publish.publish_type,
                db_publish.restart, db_publish.check_url,
                db_publish.gray).filter(
                    and_(db_publish.project == project,
                         db_publish.version == version,
                         db_publish.result == 'Success')).order_by(
                             desc(db_publish.date)).all()
            if vals:
                package_url, package_md5, package_type, publish_type, restart, check_url, gray = vals[
                    0]
                INFOS['package_url'] = package_url
                INFOS['package_md5'] = package_md5
                INFOS['package_type'] = package_type
                INFOS['publish_type'] = publish_type
                INFOS['restart'] = restart
                INFOS['check_url'] = check_url
                INFOS['gray'] = int(gray)
            else:
                _Msg = "project:%s  version:%s        --->not relevant data Fail !" % (
                    project, version)
                _flow_log(flow_number, _Msg)
                raise _console_out(channel, Msg_Key, _Msg)
        project = INFOS['project']
        package_url = INFOS['package_url']
        package_md5 = INFOS['package_md5']
        package_type = INFOS['package_type']
        publish_type = INFOS['publish_type']
        gray = INFOS['gray']
        web_path = '/opt/tomcat-%s/webapps/' % project
        #判断代码包类型
        Package_name = package_url.split('/')[-1]
        os.system("/bin/mkdir -p %s" % web_path)
        os.system("/bin/mkdir -p %s" % bak_path)
        package_path = "%s%s" % (bak_path, Package_name)
        package_name = Package_name.replace('.zip', '')
        s_files = "%s%s" % (web_path, package_name)
        #验证包规则
        if project == '-'.join(package_name.split('-')[:-1]):
            if package_name.endswith('.war'):
                package_name = '%s.war' % project
            else:
                package_name = project
        else:
            _Msg = "%s package format Fail" % Package_name
            _flow_log(flow_number, _Msg)
            raise _console_out(channel, Msg_Key, _Msg)
        if package_name.endswith('.war') and package_type == 'part':
            _Msg = "%s package not allow part publish" % Package_name
            _flow_log(flow_number, _Msg)
            raise _console_out(channel, Msg_Key, _Msg)
        d_files = "%s%s" % (web_path, package_name)
        #删除旧包
        if os.path.exists(package_path):
            os.remove(package_path)
        #获取代码压缩包
        try:
            urlretrieve(package_url, package_path)
        except Exception as e:
            msg = "package_url:%s              --->check package url Fail !" % package_url
            _flow_log(flow_number, 'Error:%s' % str(e))
            _flow_log(flow_number, msg)
            raise _console_out(channel, Msg_Key, msg)
        #对压缩包进行md5对比
        _flow_log(flow_number, "package_md5:%s" % Md5.Md5_file(package_path))
        if package_md5 == Md5.Md5_file(package_path):
            #解压缩代码包
            try:
                zip_file = zipfile.ZipFile(package_path)
                if os.path.exists('%s%s' % (web_path, package_name)):
                    try:
                        shutil.rmtree('%s%s' % (web_path, package_name))
                    except:
                        os.remove('%s%s' % (web_path, package_name))
                zip_file.extractall(web_path)
            except Exception as e:
                msg = "package:%s              --->check unzip package Fail !" % package_name
                _flow_log(flow_number, 'Error:%s' % str(e))
                _flow_log(flow_number, msg)
                raise _console_out(channel, Msg_Key, msg)
        else:
            _Msg = "package:%s              --->check  package md5 Fail !" % package_name
            _flow_log(flow_number, _Msg)
            raise _console_out(channel, Msg_Key, _Msg)
        if os.path.exists(s_files):
            shutil.move(s_files, d_files)
        if os.path.exists(d_files):
            #获取应用部署列表
            vals = db_project.query.with_entities(
                db_project.ip, db_project.ssh_port,
                db_project.app_port).filter(
                    db_project.project == project).all()
            if vals:
                server_lists = [list(val) for val in vals]
                #判断是否为灰度上线,并尝试获取服务器灰度标识
                if int(gray) == 1:
                    gray_vals = db_project.query.with_entities(
                        db_project.ip, db_project.ssh_port,
                        db_project.app_port).filter(
                            and_(db_project.project == project,
                                 db_project.gray == 1)).all()
                    if gray_vals:
                        server_lists = [list(val) for val in gray_vals]
                    else:
                        server_lists = [list(val) for val in vals][0]
                server_lists_counts = len(server_lists)
                #服务器和应用服务连通性检测
                for infos in server_lists:
                    ip, ssh_port, app_port = infos
                    try:
                        try:
                            ssh = paramiko.SSHClient()
                            ssh_key = paramiko.RSAKey.from_private_key_file(
                                key_file)
                            ssh.set_missing_host_key_policy(
                                paramiko.AutoAddPolicy())
                            ssh.connect(ip,
                                        int(ssh_port),
                                        username,
                                        pkey=ssh_key,
                                        timeout=30)
                        except:
                            _Msg = "ip:%s  ssh_port:%s        --->check sshd Fail !" % (
                                ip, ssh_port)
                            _flow_log(flow_number, _Msg)
                            raise _console_out(channel, Msg_Key, _Msg)
                        else:
                            #检测线上代码包路径是否存在
                            cmd = "[ -d %s ] && echo ok" % web_path
                            stdin, stdout, stderr = ssh.exec_command(cmd)
                            result = str(stdout.read().strip(),
                                         encoding='utf8')
                            if result != 'ok':
                                _Msg = "ip:%s  ssh_port:%s   web_path:%s       --->check app path Fail !" % (
                                    ip, ssh_port, web_path)
                                _flow_log(flow_number, _Msg)
                                raise _console_out(channel, Msg_Key, _Msg)
                            #创建备份目录
                            if package_name.endswith('.war'):
                                cmd = "/bin/mkdir -p %s" % bak_path
                            else:
                                cmd = "/bin/mkdir -p %s/%s" % (bak_path,
                                                               package_name)
                            stdin, stdout, stderr = ssh.exec_command(cmd)
                            result = stderr.read()
                            if result:
                                _Msg = "ip:%s  ssh_port:%s   bak_path:%s       --->make bak path Fail !" % (
                                    ip, ssh_port, bak_path)
                                _flow_log(flow_number, "Error:%s" % result)
                                _flow_log(flow_number, _Msg)
                                raise _console_out(channel, Msg_Key, _Msg)
                            ssh.close()
                    except:
                        raise
                    else:
                        if not tcpping(host=ip, port=app_port, timeout=3):
                            _Msg = "ip:%s   app_port:%s        --->check app port Fail !" % (
                                ip, app_port)
                            _flow_log(flow_number, _Msg)
                            raise _console_out(channel, Msg_Key, _Msg)
                #部署列表写入redis队列
                server_lists_key = '%s_server_lists_key' % secret_key
                for info in server_lists:
                    Redis.sadd(server_lists_key, info)
                #启动多个子控制中心并发执行
                _console_out(channel, Msg_Key, "代码分发相关参数及运行环境检测全部通过!")
                _console_out(channel, Msg_Key,
                             "启动代码分发模块,开始部署%s,执行过程稍后输出......" % package_name)
                _console_out(channel, Msg_Key, '-' * 100)
                for i in range(Publish_types[publish_type]):
                    Scheduler = produce.SchedulerPublish()
                    Scheduler = Scheduler.Scheduler_mem(
                        Publish_agent, [
                            server_lists_key, server_lists_counts, d_files,
                            project, package_name, package_path, Msg_Key,
                            secret_key, INFOS
                        ])
                    Scheduler.start()
                    time.sleep(1)
            else:
                _Msg = "Error:not find app service lists!"
                _flow_log(flow_number, _Msg)
                raise _console_out(channel, Msg_Key, _Msg)
        else:
            _Msg = "package:%s              --->move package  Fail !" % package_name
            _flow_log(flow_number, _Msg)
            raise _console_out(channel, Msg_Key, _Msg)
    except Exception as e:
        if 'old-style' not in str(e):
            _flow_log(flow_number, 'Error:%s' % str(e))
        result = "代码分发环境检测到错误,不执行代码分发操作!"
        _console_out(channel, Msg_Key, result)
        _console_out(channel, Msg_Key, '-' * 100)
        _console_out(
            channel, Msg_Key, "_End_:0,0,0,%i,%i:%s" %
            (server_lists_counts, server_lists_counts, flow_number))
        #汇总结果后回调接口
        _result_handle(result, server_lists_counts, INFOS)
        Redis.expire(Msg_Key, 15)
    finally:
        db_op.DB.session.remove()
Ejemplo n.º 7
0
def deployment_create():
    tools.Async_log(g.user, request.url)
    reload(MyForm)
    form = MyForm.FormK8sDeploy()
    mounts = defaultdict()
    if form.submit.data:
        context = form.contexts.data
        project = form.projects.data
        version = form.version.data
        object = form.object.data
        container_port = form.container_port.data
        ingress_port = form.ingress_port.data
        replicas = form.replicas.data
        request_cpu = form.request_cpu.data
        limit_cpu = form.limit_cpu.data
        request_mem = form.request_mem.data
        limit_mem = form.limit_mem.data
        domain = form.domain.data
        healthcheck = form.healthcheck.data
        mount_path2 = form.mount_path2.data
        mount_name2 = form.mount_name2.data
        sidecar = form.sidecar.data
        run_args = form.run_args.data
        run_args = run_args.splitlines()
        re_requests = {}
        re_limits = {}
        if mount_path2:
            mounts[mount_path2] = mount_name2
        try:
            if object and version and container_port and replicas:
                if object.endswith('.war') or object.endswith(
                        '.tar.gz') or object.endswith('.jar'):
                    dm_name = object.split('.')[0]
                    image = "%s/%s:%s" % (docker_registry, dm_name, version)
                    docker_file = "%s/%s" % (dockerfile_path, dm_name)
                    if os.path.exists(docker_file):
                        container_port = [
                            int(port) for port in container_port.split(',')
                        ]
                        if request_cpu and limit_cpu and request_mem and limit_mem:
                            if float(request_cpu) > float(limit_cpu) or float(
                                    request_mem) > float(limit_mem):
                                raise flash('限制资源不能小于请求资源!')
                            else:
                                re_requests = {
                                    'cpu': request_cpu,
                                    'memory': '%sG' % request_mem
                                }
                                re_limits = {
                                    'cpu': limit_cpu,
                                    'memory': '%sG' % limit_mem
                                }
                        if domain and not ingress_port:
                            raise flash('域名配置后还需配置容器对外服务端口!')
                        redis_key = 'op_k8s_create_%s' % time.strftime(
                            '%Y%m%d%H%M%S', time.localtime())
                        Scheduler = produce.SchedulerPublish()
                        Scheduler = Scheduler.Scheduler_mem(
                            k8s_resource.object_deploy, [
                                context, project, object, version, image,
                                run_args, container_port, ingress_port,
                                replicas, domain, re_requests, mounts,
                                healthcheck, sidecar, re_limits, redis_key
                            ])
                        Scheduler.start()
                        return render_template('deploy_show.html',
                                               redis_key=redis_key)
                    else:
                        flash("%s文件路径不存在!" % docker_file)
                else:
                    flash("%s包名应以.war或者.tar.gz结尾或者.jar结尾!" % object)
            else:
                flash('必填项参数不完整!')
            return render_template('Message.html')
        except Exception as e:
            logging.error(e)
            return redirect(url_for('error'))
    return render_template('k8s_deploy.html', form=form)
Ejemplo n.º 8
0
def publish():
    try:
        tools.Async_log(g.user, request.url)
        importlib.reload(MyForm)
        secret_key = tools.Produce(length=12, chars=string.digits)
        Msg_Key = 'op_publish_msg_%s' % secret_key
        form = MyForm.MyFormPublish()
        if form.submit.data:
            try:
                if Redis.exists(Msg_Key):
                    raise flash('上线操作过于频繁,请稍等%s秒......' % Redis.ttl(Msg_Key))
                package_url = form.package_url.data
                describe = form.describe.data
                package_md5 = form.package_md5.data
                package_type = form.package_type.data
                publish_type = form.publish_type.data
                check_url = form.check_url.data
                restart = form.restart.data
                execute = form.execute.data
                rb_project = form.project.data
                rb_version = form.version.data
                gray = form.gray.data
                if execute == 'rollback':
                    if not rb_project and not rb_version:
                        raise logging.error("choice can not be empty!")
                if execute == 'publish':
                    if not package_url or not package_md5 or not check_url or not describe:
                        raise logging.error("input can not be empty!")
                    Package_name = package_url.split('/')[-1]
                    package_name = Package_name.replace('.zip', '')
                    rb_project = '-'.join(package_name.split('-')[:-1])
                INFOS = {
                    'package_url': package_url,
                    'package_md5': package_md5,
                    'package_type': package_type,
                    'publish_type': publish_type,
                    'user': g.user,
                    'describe': describe.replace('"', '').replace("'", ''),
                    'gray': int(gray),
                    'restart': restart,
                    'execute': execute,
                    'check_url': check_url.replace('https', 'http'),
                    'project': rb_project,
                    'version': rb_version,
                    'channel': 'web',
                    'callback_url': 'None',
                    'token': 'None',
                    'timestamp': int(time.time())
                }
                #启动代码分发控制中心
                Scheduler = produce.SchedulerPublish()
                Scheduler = Scheduler.Scheduler_mem(
                    task_publish.Publish_center, [INFOS, Msg_Key, secret_key])
                Scheduler.start()
                return render_template('publish_show.html',
                                       secret_key=secret_key)
            except Exception as e:
                if 'old-style' not in str(e):
                    logging.error(e)
    except Exception as e:
        logging.error(e)
        return redirect(url_for('error'))
    return render_template('publish.html', form=form)