def delete_service_mesh(namespace, mesh_name):
    # TODO: return 작업
    msg = {}
    data = {"namespace": namespace, "name": mesh_name}
    select_result = conn.select_one(select_service_mesh_sql, data)
    if type(select_result) == tuple and select_result[0] > 0:
        msg['error'] = {'code': 400, 'message': select_result[1]}
    elif select_result:
        services = json.loads(select_result["SERVICES"])
        del_service_names = []
        for s in services:
            if not s["name"] in del_service_names:
                del_service_names.append(s["name"])
            delete_route_result = route_service.delete_route(
                namespace, s["name"])
            if delete_route_result[0] != 0:
                logger.debug('route insert error: ' + delete_route_result[1])
        cmd = f'kubectl delete service {" ".join(del_service_names)} -n {namespace}'
        msg = c_tool.gen_msg(logger, cmd)

        del_deployment_names = [
            s["name"] + ("-" + s["labels"]["version"] if s.get("labels", None)
                         and s["labels"].get("version", None) else "")
            for s in services
        ]
        cmd = f'kubectl delete deployment {" ".join(del_deployment_names)} -n {namespace}'
        result = c_tool.gen_msg(logger, cmd)
        for name in del_deployment_names:
            directory = f"/mnt/data/{namespace}"
            filename = f"{name}-config.yaml"
            file = directory + "/" + filename
            if os.path.isfile(file):
                os.remove(file)

        if result.get("error", None):
            if msg.get("error", None):
                msg["error"] = {'code': 400, 'message': ""}
            else:
                msg["error"]["message"] += "\n"
            msg["error"]["message"] += result["error"]["message"]

        del_service = [{
            "namespace": namespace,
            "name": s["name"]
        } for s in services]
        conn.delete(delete_service_sql, del_service)
        conn.delete(delete_service_mesh_sql, data)
        return msg
    else:
        abort(404, description="not exist service mesh(" + mesh_name + ")")
def get_namespaces(details=False, cnt_from=None, cnt_to=None, search_name=None):
    def fnc(obj):
        result = {
            'namespaces': [
                item['metadata']['name']
                for item in obj['items']
                # if item['metadata']['name'] not in reserved_ns
            ]
        }
        if details:
            result["namespaces"] = [
                item
                for item in obj['items']
                # if item['metadata']['name'] not in reserved_ns
            ]
            if search_name:
                result["namespaces"] = [
                    namespace
                    for namespace in result["namespaces"]
                    if search_name in namespace['metadata']['name']
                ]
            if cnt_from is not None and cnt_to is not None:
                result["namespaces"] = result["namespaces"][cnt_from:cnt_to]
            elif cnt_from is not None:
                result["namespaces"] = result["namespaces"][cnt_from:]
            elif cnt_to is not None:
                result["namespaces"] = result["namespaces"][:cnt_to]

        return result

    cmd = f'kubectl get namespace'
    return c_tool.gen_msg(logger, cmd, fnc)
示例#3
0
def status_service(namespace, service_name):
    def fnc(obj):
        return obj['status']

    # deployment
    cmd = f'kubectl get deployment {service_name} -n {namespace}'
    return c_tool.gen_msg(logger, cmd, fnc)
示例#4
0
def get_namespace(namespace_name):
    def fnc(obj):
        return {'namespace': obj}

    cmd = f'kubectl get namespace {namespace_name}'

    return jsonify(c_tool.gen_msg(logger, cmd, fnc))
示例#5
0
def get_label(namespace, service_name):
    def fnc(obj):
        return obj['metadata']['labels']

    # deployment
    cmd = f'kubectl get svc {service_name} -n {namespace} -o json'
    return c_tool.gen_msg(logger, cmd, fnc)
示例#6
0
def get_nodes(selectors=None,
              details=None,
              cnt_from=None,
              cnt_to=None,
              search_name=None):
    def fnc(obj):
        nodes = [
            item if details else item['metadata']['name']
            for item in obj['items']
            if search_name is None or search_name in item['metadata']['name']
        ]
        if cnt_from is not None and cnt_to is not None:
            nodes = nodes[cnt_from:cnt_to]
        elif cnt_from is not None:
            nodes = nodes[cnt_from:]
        elif cnt_to is not None:
            nodes = nodes[:cnt_to]
        return {'nodes': nodes}

    cmd = f'kubectl get node'
    if selectors:
        for k, v in enumerate(selectors):
            cmd += f' --selector={k}={v}'

    return c_tool.gen_msg(logger, cmd, fnc)
示例#7
0
def get_node(node_name):
    def fnc(obj):
        return obj['status']

    cmd = f'kubectl get node {node_name}'

    return c_tool.gen_msg(logger, cmd, fnc)
示例#8
0
def create_node_selector(namespace, service_name, node_selector):
    temp = {"spec": {"template": {"spec": {"nodeSelector": node_selector}}}}
    # temp = yaml.dump(temp)
    temp = json.dumps(temp)

    cmd = f"""kubectl patch deployment {service_name} -n {namespace} --patch '{temp}'"""
    return c_tool.gen_msg(logger, cmd)
示例#9
0
def delete_node_selector(namespace, service_name):
    temp = {"spec": {"template": {"spec": {"nodeSelector": {}}}}}
    temp = json.dumps(temp)

    # multiline command! : """command"""
    cmd = f"""kubectl patch deployment {service_name} -n {namespace} --patch '{temp}'"""
    return c_tool.gen_msg(logger, cmd)
def create_service_in_service_mesh(service_mesh_name, namespace, name, svc,
                                   created_services):
    cluster_ip = None
    service_obj = kyp.parse_service(namespace, name, svc, True)
    service_yaml = yaml.dump(service_obj)
    # apply
    cmd = f'kubectl get svc {name} -n {namespace}'
    msg = c_tool.gen_msg(logger, cmd, (lambda obj: obj))
    if msg.get("error", None) and "NotFound" in msg["error"]["message"]:
        cmd = f'cat << EOF | kubectl apply -f -\n{service_yaml}\nEOF\n'
        msg = c_tool.gen_msg(logger, cmd)
        if msg.get('error', None):
            abort(400,
                  description="can't create service(" + name + "): " +
                  msg['error'].get("message", ""))
        else:

            def fnc(obj):
                return obj["spec"]["clusterIP"]

            cmd = f'kubectl get service {name} -n {namespace}'
            msg = c_tool.gen_msg(logger, cmd, fnc)
            if msg.get('success', None):
                cluster_ip = msg["success"]
                data = {
                    'namespace': namespace,
                    'name': name,
                    'ip': cluster_ip,
                    'app': name,
                    'service_mesh': service_mesh_name
                }
                insert_result = conn.insert(insert_service_sql, data)
                if insert_result[0] > 0:
                    logger.error(insert_result[1])
                created_services.append(name)
                return cluster_ip
    elif len(created_services) > 0:
        # destination과 service의 이름이 같지 않을 시 해당 서비스메쉬의 생성된 service 삭제
        for created_service in created_services:
            cmd = f'kubectl delete service {created_service} -n {namespace}'
            c_tool.gen_msg(logger, cmd)
        conn.delete(delete_service_sql, created_services)
        abort(
            400,
            description=f"Duplicate service({name}) in namespace({namespace})")
示例#11
0
def get_node_selector(namespace, service_name):
    def fnc(obj):
        if 'nodeSelector' in obj['spec']['template']['spec']:
            return obj['spec']['template']['spec']['nodeSelector']
        else:
            # TODO: service_name이 None일 경우 디버깅(None 오류 안뜨면 주석제거)
            return f'"{service_name}" not found'

    # deployment
    cmd = f'kubectl get deployment {service_name} -n {namespace} -o json'
    return c_tool.gen_msg(logger, cmd, fnc)
示例#12
0
def get_node_labels():
    def fnc(obj):
        return {
            'labels': [{
                "name": item['metadata']['name'],
                "labels": item['metadata']['labels']
            } for item in obj['items']]
        }

    cmd = f'kubectl get node'

    return c_tool.gen_msg(logger, cmd, fnc)
示例#13
0
def delete_namespaces(namespace_name):
    if namespace_name not in reserved_ns:
        cmd = f"kubectl delete namespace {namespace_name}"
        result = c_tool.gen_msg(logger, cmd)
    else:
        result = {
            'error': {
                'code': 400,
                'message': f"reserved_ns: {namespace_name}"
            }
        }
    return result
示例#14
0
def create_namespace():
    content_type = request.headers.get("Content-Type")

    if "yaml" in content_type:
        # schema validation
        yamale.validate(require_schema,
                        yamale.make_data(content=request.data.decode('utf-8')))
        body = yaml.load(request.data, Loader=yaml.Loader)
    else:
        body = json.loads(request.data)

    cmd = f"kubectl create namespace {body['namespace']['name']}"

    return jsonify(c_tool.gen_msg(logger, cmd))
示例#15
0
def service_ip_collector(num):
    cmd = f'kubectl get svc -n edge'
    value = conn.select(select_empty_ip_service_list, [])
    if len(value) > 0:
        result = c_tool.gen_msg(logger, cmd, service_parser)
        params = []
        for idx, data in value.iterrows():
            for item in result['success']['items']:
                if data['NAMESPACE'] == item['namespace'] and data[
                        'NAME'] == item['name']:
                    params.append({
                        'ip': item['ip'],
                        'namespace': item['namespace'],
                        'name': item['name']
                    })
        conn.update(update_service, params)
示例#16
0
def delete_service(namespace, service_name):
    delete_yaml = kyp.parse_yaml_delete_service(namespace, service_name)

    # delete deployment & service
    cmd = f'cat << EOF | kubectl delete -f -\n{delete_yaml}\nEOF\n'

    data = {"name": service_name, "namespace": namespace}
    result = c_tool.gen_msg(logger, cmd)
    conn.delete(delete_service_sql, data)
    delete_route_result = route_service.delete_route(namespace, service_name)
    if delete_route_result[0] != 0:
        if not result.get("error", None):
            result["error"] = {'code': 400, 'message': ""}
        result['error']['message'] += '\nroute: ' + delete_route_result[1]

    return result
示例#17
0
def create_service(namespace, svc):
    # for deployment & service
    service_yaml = kyp.parse_yaml_service(namespace, svc['name'], svc)
    # apply
    cmd = f'cat << EOF | kubectl apply -f -\n{service_yaml}\nEOF\n'
    result = c_tool.gen_msg(logger, cmd)

    # todo: insert scheduleHint to schedulehint.db
    # k = f"{namespace}/{service['name']}"
    # v = json.dumps(service['scheduelHint']).encode()
    # mydb.upsert(db_schedulehint_path, k, v)
    data = {"name": svc["name"], "namespace": namespace, "app": svc["name"]}

    if not result.get('error', None):
        cmd = f'kubectl get svc {svc["name"]} -n {namespace} -o json'
        st, res = subprocess.getstatusoutput(cmd)
        if st != 0:
            logger.error(res)
            if not result.get("error", None):
                result["error"] = {'code': 400, 'message': ""}
            result['error']['message'] += '\nservice: ' + res
        else:
            obj = json.loads(res)
            ip = obj["spec"]["clusterIP"]
            data["ip"] = ip
            port = obj["spec"]["ports"][0]["port"]
            output_value = "http://" + ip + ":" + str(port)
            insert_result = conn.insert(insert_service_sql, data)
            result = c_tool.gen_msg_result_query(logger, insert_result)
            if not result.get("error", None):
                create_route_result = route_service.create_route(
                    namespace, svc["name"], output_value)
                if create_route_result[0] != 0:
                    if not result.get("error", None):
                        result["error"] = {'code': 400, 'message': ""}
                    result['error'][
                        'message'] += '\nroute: ' + create_route_result[1]
    return result
示例#18
0
def get_service(namespace, service_name):
    # cmd = f"kubectl get svc {app_conf.RouteConf.service_name} -n {app_conf.RouteConf.namespace} -o json " + \
    #       "|jq '{\"ip\":.status.loadBalancer.ingress[0].ip, \"port\":.spec.ports[0].port}'"
    # access_url = ""
    # try:
    #     st, res = subprocess.getstatusoutput(cmd)
    #     if st != 0:
    #         logger.error(res)
    #     else:
    #         obj = json.loads(res)
    #         access_ip = obj.get("ip", None)
    #         access_port = obj.get("port", None)
    #         access_url = "http://" + access_ip + ":" + str(access_port) + "/" + namespace + "/" + service_name
    # except Exception as e:
    #     logger.error(traceback.format_exc())
    def deployment_fnc(_obj):
        deployments = []
        for _item in _obj.get('items', []):
            deployments.append({
                "name":
                _item['metadata']['name'],
                "replicas":
                _item['spec']['replicas'],
                "containers": [
                    container for container in _item['spec']['template']
                    ['spec']['containers'] if container['name'] != 'envoyproxy'
                ],
                "labels":
                _item['metadata'].get("labels", {})
            })
        return deployments

    def service_fnc(_obj):
        success: Dict[str, List[Dict[str, List[Dict]]]] = {'namespaces': []}
        if not _obj:
            abort(404, description="not exist service(" + service_name + ")")
        _idx = next((i for (i, ns) in enumerate(success['namespaces'])
                     if ns['name'] == _obj['metadata']['namespace']), None)
        if _idx is None:
            _idx = len(success['namespaces'])
            success['namespaces'].append({
                'name': _obj['metadata']['namespace'],
                'services': []
            })

        _s_idx = next(
            (i
             for (i, svc) in enumerate(success['namespaces'][_idx]['services'])
             if svc['name'] == _obj['metadata']['name']), None)
        if _s_idx is None:
            _s_idx = len(success['namespaces'][_idx]['services'])
            success['namespaces'][_idx]['services'].append({
                'name':
                _obj['metadata']['name'],
            })

        service_obj = success['namespaces'][_idx]['services'][_s_idx]
        service_obj['clusterIP'] = _obj['spec']['clusterIP']
        service_obj['type'] = _obj['spec']['type']
        try:
            deployment_cmd = f'kubectl get deployment -l app={_obj["spec"]["selector"]["app"]} -n {namespace}'
        except KeyError as e:
            deployment_cmd = f'kubectl get deployment {service_name} -n {namespace}'
        deployment_result = c_tool.gen_msg(logger, deployment_cmd,
                                           deployment_fnc)
        deployments = deployment_result.get("success", None)
        result_routes = get_routes(namespace, service_name)
        filtered_route = [
            result_data for route_i, result_data in result_routes.iterrows()
            if result_data["INPUT_VALUE"] == "/" + namespace + "/" +
            _obj['metadata']['name']
        ]
        if len(filtered_route) > 0:
            service_obj[
                'link'] = 'http://' + app_conf.RouteConf.host + '/' + namespace + '/' + service_name
        if deployments and len(deployments) >= 1:
            if len(deployments) > 1:
                service_obj['containers'] = deployments[0]['containers']
                service_obj['deployments'] = deployments
            elif len(deployments) == 1:
                service_obj['containers'] = deployments[0]['containers']
                service_obj['labels'] = deployments[0].get('labels', {})
            service_obj['replicas'] = deployments[0]['replicas']
        for port in _obj['spec']['ports']:
            for container in service_obj.get('containers', []):
                if container.get('ports', None):
                    for c_port in container['ports']:
                        if str(c_port['containerPort']) == port['name']:
                            c_port['externalPort'] = port['port']

        select_result = conn.select_one(select_service_sql, {
            "name": service_name,
            "namespace": namespace
        })
        if not (type(select_result) == tuple
                and select_result[0] > 0) and select_result:
            service_obj['serviceMesh'] = select_result.get(
                "SERVICE_MESH", None)
        return success

    # deployment & service
    cmd = f'kubectl get services {service_name} -n {namespace}'
    result = c_tool.gen_msg(logger, cmd, service_fnc)
    # try:
    #     select_route_result = route_service.get_route(service_name)
    # except Exception as e:
    #     pass

    # # serviceMonitor
    # cmd = f'kubectl get servicemonitor {service_name} -n {namespace} -o json'
    # st, res = subprocess.getstatusoutput(cmd)
    # if st != 0:
    #     logger.error(res)
    # else:
    #     try:
    #         obj = json.loads(res)
    #         if obj.get('items', None):
    #             for item in obj['items']:
    #                 idx = next((
    #                     i
    #                     for (i, ns) in enumerate(result['success']['namespaces'])
    #                     if ns['name'] == item['metadata']['namespace']
    #                 ), None)
    #                 if idx is not None:
    #                     namespace_obj = result['success']['namespaces'][idx]
    #                     s_idx = next((
    #                         i
    #                         for (i, svc) in enumerate(namespace_obj['services'])
    #                         if svc['name'] == item['metadata']['name']
    #                     ), None)
    #                     if s_idx is not None:
    #                         namespace_obj['services'][s_idx]['monitorPorts'] = [
    #                             int(endpoint['port'])
    #                             for endpoint in item['spec']['endponts']
    #                         ]
    #         else:
    #             idx = next((
    #                 i
    #                 for (i, ns) in enumerate(result['success']['namespaces'])
    #                 if ns['name'] == obj['metadata']['namespace']
    #             ), None)
    #             if idx is not None:
    #                 namespace_obj = result['success']['namespaces'][idx]
    #                 s_idx = next((
    #                     i
    #                     for (i, svc) in enumerate(namespace_obj['services'])
    #                     if svc['name'] == obj['metadata']['name']
    #                 ), None)
    #                 if s_idx is not None:
    #                     namespace_obj['services'][s_idx]['monitorPorts'] = [
    #                         int(endpoint['port'])
    #                         for endpoint in obj['spec']['endpoints']
    #                     ]
    #
    #     except Exception as e:
    #         result.update({'error': {'code': 400, 'message': service_name + ' is not gse service'}})
    return result
示例#19
0
def delete_label(namespace, service_name, labels):
    cmd = f"kubectl label svc {service_name} -n {namespace} "
    cmd += " ".join([label + "-" for label in labels])
    return c_tool.gen_msg(logger, cmd)
示例#20
0
def create_label(namespace, service_name, labels):
    cmd = f"kubectl label svc {service_name} -n {namespace} "
    cmd += " ".join([f"{k}={v}" for k, v in labels.items()])
    return c_tool.gen_msg(logger, cmd)
示例#21
0
def list_service(details=False,
                 cnt_from=None,
                 cnt_to=None,
                 search_namespace=None,
                 search_name=None,
                 search_label=None,
                 sort=None):
    def fnc(obj):
        deployments = None
        result_routes = []
        db_services = []
        if details:
            ns = f'-n {search_namespace}' if search_namespace else '--all-namespaces'
            f_cmd = f'kubectl get deployments {ns} -o json'
            try:
                st, res = subprocess.getstatusoutput(f_cmd)
                if st != 0:
                    logger.error(res)
                elif fnc:
                    dep_obj = json.loads(res)
                    deployments = dep_obj["items"]
                select_result = conn.select(select_service_list_sql)
                if len(select_result) > 0:
                    if not (type(select_result) == tuple
                            and select_result[0] > 0):
                        db_services = select_result.to_dict('records')
            except Exception as e:
                logger.error(traceback.format_exc())
            result_routes = get_routes(search_namespace)
            if type(result_routes) == tuple and result_routes[0] > 0:
                logger.error(result_routes[1])
            elif not result_routes.empty:
                pass
        success: Dict[str, List[Dict[str, List]]] = {'namespaces': []}
        services = [
            item for item in obj['items'] if not details
            or filter_for_service(item, search_name, search_label)
        ]
        if sort:
            for s_idx, s in enumerate(sort):
                services = sorted(
                    services,
                    key=lambda service: service['metadata'][s['target']])
                if s['method'] == 'desc':
                    services.reverse()
                if len(sort
                       ) == 2 and s_idx == 0 and sort[1]['method'] == 'desc':
                    services.reverse()
        for i, item in enumerate(services):
            meta = item['metadata']
            idx = next((i for (i, f_ns) in enumerate(success['namespaces'])
                        if f_ns['name'] == meta['namespace']), None)

            if idx is None:
                idx = len(success['namespaces'])
                success['namespaces'].append({
                    'name': meta['namespace'],
                    'services': []
                })
            if details:
                if paging_service(i, cnt_from, cnt_to):
                    filtered_route = [
                        result_data
                        for route_i, result_data in result_routes.iterrows()
                        if result_data["INPUT_VALUE"] == "/" +
                        meta['namespace'] + "/" + meta['name']
                    ]
                    link = ""
                    if not success.get("order", None):
                        success['order'] = []
                    success['order'].append({
                        "namespace": meta['namespace'],
                        "name": meta['name']
                    })
                    if len(filtered_route) > 0:
                        link = "http://" + app_conf.RouteConf.host + "/" + meta['namespace'] + "/" + \
                               meta['name']
                    service = {
                        "service":
                        item,
                        "deployments": [
                            deployment for deployment in deployments
                            if filter_for_deployment(deployment, item,
                                                     search_label)
                        ],
                        "link":
                        link
                    }
                    db_service = [
                        _db_service for _db_service in db_services
                        if _db_service['NAME'] == meta['name']
                        and _db_service['NAMESPACE'] == meta['namespace']
                    ]
                    if len(db_service) == 1:
                        service['serviceMesh'] = db_service[0].get(
                            "SERVICE_MESH", None)
                    success['namespaces'][idx]['services'].append(service)
            else:
                success['namespaces'][idx]['services'].append(meta['name'])
        return success

    ns = f'-n {search_namespace}' if search_namespace else '--all-namespaces'
    cmd = f'kubectl get services {ns}'
    return c_tool.gen_msg(logger, cmd, fnc)
示例#22
0
    def service_fnc(_obj):
        success: Dict[str, List[Dict[str, List[Dict]]]] = {'namespaces': []}
        if not _obj:
            abort(404, description="not exist service(" + service_name + ")")
        _idx = next((i for (i, ns) in enumerate(success['namespaces'])
                     if ns['name'] == _obj['metadata']['namespace']), None)
        if _idx is None:
            _idx = len(success['namespaces'])
            success['namespaces'].append({
                'name': _obj['metadata']['namespace'],
                'services': []
            })

        _s_idx = next(
            (i
             for (i, svc) in enumerate(success['namespaces'][_idx]['services'])
             if svc['name'] == _obj['metadata']['name']), None)
        if _s_idx is None:
            _s_idx = len(success['namespaces'][_idx]['services'])
            success['namespaces'][_idx]['services'].append({
                'name':
                _obj['metadata']['name'],
            })

        service_obj = success['namespaces'][_idx]['services'][_s_idx]
        service_obj['clusterIP'] = _obj['spec']['clusterIP']
        service_obj['type'] = _obj['spec']['type']
        try:
            deployment_cmd = f'kubectl get deployment -l app={_obj["spec"]["selector"]["app"]} -n {namespace}'
        except KeyError as e:
            deployment_cmd = f'kubectl get deployment {service_name} -n {namespace}'
        deployment_result = c_tool.gen_msg(logger, deployment_cmd,
                                           deployment_fnc)
        deployments = deployment_result.get("success", None)
        result_routes = get_routes(namespace, service_name)
        filtered_route = [
            result_data for route_i, result_data in result_routes.iterrows()
            if result_data["INPUT_VALUE"] == "/" + namespace + "/" +
            _obj['metadata']['name']
        ]
        if len(filtered_route) > 0:
            service_obj[
                'link'] = 'http://' + app_conf.RouteConf.host + '/' + namespace + '/' + service_name
        if deployments and len(deployments) >= 1:
            if len(deployments) > 1:
                service_obj['containers'] = deployments[0]['containers']
                service_obj['deployments'] = deployments
            elif len(deployments) == 1:
                service_obj['containers'] = deployments[0]['containers']
                service_obj['labels'] = deployments[0].get('labels', {})
            service_obj['replicas'] = deployments[0]['replicas']
        for port in _obj['spec']['ports']:
            for container in service_obj.get('containers', []):
                if container.get('ports', None):
                    for c_port in container['ports']:
                        if str(c_port['containerPort']) == port['name']:
                            c_port['externalPort'] = port['port']

        select_result = conn.select_one(select_service_sql, {
            "name": service_name,
            "namespace": namespace
        })
        if not (type(select_result) == tuple
                and select_result[0] > 0) and select_result:
            service_obj['serviceMesh'] = select_result.get(
                "SERVICE_MESH", None)
        return success
示例#23
0
def get_service_detail(namespace, service_name):
    def fnc(_obj):
        success: Dict[str, List[Dict[str, List[Dict]]]] = {'namespaces': []}
        for _item in _obj['items']:
            _idx = next((i for (i, ns) in enumerate(success['namespaces'])
                         if ns['name'] == _item['metadata']['namespace']),
                        None)
            if _idx is None:
                _idx = len(success['namespaces'])
                success['namespaces'].append({
                    'name':
                    _item['metadata']['namespace'],
                    'services': []
                })

            _s_idx = next((i for (
                i, svc) in enumerate(success['namespaces'][_idx]['services'])
                           if svc['name'] == _item['metadata']['name']), None)
            if _s_idx is None:
                _s_idx = len(success['namespaces'][_idx]['services'])
                success['namespaces'][_idx]['services'].append({
                    'name':
                    _item['metadata']['name'],
                })

            service_obj = success['namespaces'][_idx]['services'][_s_idx]
            _kind = _item['kind'][:1].lower() + _item['kind'][1:]
            if not service_obj.get(_kind):
                service_obj[_kind] = []
            service_obj[_kind].append(_item)

        return success

    # deployment & service
    cmd = f'kubectl get deployment,services {service_name} -n {namespace}'
    result = c_tool.gen_msg(logger, cmd, fnc)

    # # serviceMonitor
    cmd = f'kubectl get servicemonitor {service_name} -n {namespace} -o json'
    st, res = subprocess.getstatusoutput(cmd)
    if st != 0:
        logger.error(res)
        result['error']['message'] += '\nserviceMonitor: ' + res
    else:
        obj = json.loads(res)
        if obj.get('items', None):
            for item in obj['items']:
                idx = next(
                    (i
                     for (i, ns) in enumerate(result['success']['namespaces'])
                     if ns['name'] == item['metadata']['namespace']), None)
                if idx is not None:
                    namespace_obj = result['success']['namespaces'][idx]
                    s_idx = next(
                        (i for (i, svc) in enumerate(namespace_obj['services'])
                         if svc['name'] == item['metadata']['name']), None)
                    if s_idx is not None:
                        kind = item['kind'][:1].lower() + item['kind'][1:]
                        if not namespace_obj['services'][s_idx].get(kind):
                            namespace_obj['services'][s_idx][kind] = []
                        namespace_obj['services'][s_idx][kind].append(item)
        else:
            idx = next(
                (i for (i, ns) in enumerate(result['success']['namespaces'])
                 if ns['name'] == obj['metadata']['namespace']), None)
            if idx is not None:
                namespace_obj = result['success']['namespaces'][idx]
                s_idx = next(
                    (i for (i, svc) in enumerate(namespace_obj['services'])
                     if svc['name'] == obj['metadata']['name']), None)
                if s_idx is not None:
                    kind = obj['kind'][:1].lower() + obj['kind'][1:]
                    if not namespace_obj['services'][s_idx].get(kind):
                        namespace_obj['services'][s_idx][kind] = []
                    namespace_obj['services'][s_idx][kind].append(obj)
    return result
def create_service_mesh(namespace, sm):
    msg = {}
    data = [{"name": s["template"]} for s in sm['services']]
    select_result = conn.select(select_in_template_sql, data)
    if type(select_result) == tuple and select_result[0] > 0:
        msg['error'] = {'code': 400, 'message': select_result[1]}
    elif not select_result.empty:
        apps = []
        svcs = []
        cluster_ip_dict = {}
        created_services = []
        for s in sm['services']:
            # for deployment & service
            for idx, result_data in select_result.iterrows():
                if result_data['NAME'] == s['template']:
                    service_name = s['name']
                    if not s.get('labels', None):
                        s['labels'] = {'app': service_name}
                    else:
                        s['labels']['app'] = service_name
                    deployment_name = s['name']
                    if s["labels"].get("version", None):
                        deployment_name += "-" + s["labels"]["version"]
                    svc_spec = json.loads(result_data["SERVICE"])

                    svc = {
                        'name': deployment_name,
                        'service': svc_spec,
                        'labels': s['labels']
                    }
                    if service_name not in apps:
                        apps.append(service_name)
                        cluster_ip = create_service_in_service_mesh(
                            sm['name'], namespace, service_name, svc_spec,
                            created_services)
                        cluster_ip_dict[service_name] = cluster_ip
                        for route in sm["serviceRoutes"]:
                            if route.get("hosts", None) is None:
                                route['hosts'] = []
                            if service_name == route["destination"]['host']:
                                route["ip"] = cluster_ip
                                route['hosts'].append(
                                    route["destination"]['host'])
                                route['hosts'].append(cluster_ip)
                                for c in svc_spec['containers']:
                                    for p in c['ports']:
                                        if cluster_ip:
                                            route['hosts'].append(
                                                cluster_ip + ":" +
                                                str(p['externalPort']))
                        svc['cluster_ip'] = cluster_ip
                        if s.get("externalAccess", False) and cluster_ip:
                            port = svc_spec['containers'][0]['ports'][0][
                                "externalPort"]
                            output_value = "http://" + cluster_ip + ":" + str(
                                port)
                            create_route_result = route_service.create_route(
                                namespace, service_name, output_value)
                            if create_route_result[0] != 0:
                                logger.debug('route insert error: ' +
                                             create_route_result[1])
                    else:
                        svc['cluster_ip'] = cluster_ip_dict.get(
                            service_name, None)
                    svcs.append(svc)

        created_deployments = []
        for svc in svcs:
            deployment_obj = kyp.parse_deployment(namespace, svc["name"],
                                                  svc["service"],
                                                  sm["serviceRoutes"])
            # destination과 service의 이름이 같지 않을 시 해당 서비스메쉬의 생성된 service, deployment 삭제
            if type(deployment_obj) == str:
                if len(created_services) > 0:
                    for created_service in created_services:
                        cmd = f'kubectl delete service {" ".join(created_service)} -n {namespace}'
                        c_tool.gen_msg(logger, cmd)
                    conn.delete(delete_service_sql, created_services)
                for created_deployment in created_deployments:
                    cmd = f'kubectl delete deployment {" ".join(created_deployment)} -n {namespace}'
                    c_tool.gen_msg(logger, cmd)
                abort(400, deployment_obj)

            deployment_obj["metadata"]["labels"] = svc["labels"].copy()
            deployment_obj["spec"]["selector"]["matchLabels"] = svc[
                "labels"].copy()
            deployment_obj["spec"]["template"]["metadata"]["labels"] = svc[
                "labels"].copy()
            deployment_yaml = yaml.dump(deployment_obj)
            cmd = f'cat << EOF | kubectl apply -f -\n{deployment_yaml}\nEOF\n'
            result = c_tool.gen_msg(logger, cmd)

            if result.get("error", None):
                if msg.get("error", None):
                    msg["error"]["message"] += "\n"
                else:
                    msg["error"] = result['error']
                msg["error"]["message"] += result["error"]["message"]
            else:
                created_deployments.append(svc["name"])
    insert_result = conn.insert(
        insert_service_mesh_sql, {
            "namespace": namespace,
            "name": sm["name"],
            "services": json.dumps(sm["services"]),
            "serviceRoutes": json.dumps(sm["serviceRoutes"])
        })
    return msg