mirror of https://github.com/alibaba/SREWorks.git
				
				
				
			feat: add owner reference to service trait
This commit is contained in:
		
							parent
							
								
									0af2a39f3c
								
							
						
					
					
						commit
						e853b8c431
					
				| 
						 | 
				
			
			@ -4,27 +4,64 @@ import logging
 | 
			
		|||
import os
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
import requests
 | 
			
		||||
from oauthlib.oauth2 import LegacyApplicationClient
 | 
			
		||||
from requests_oauthlib import OAuth2Session
 | 
			
		||||
 | 
			
		||||
CREATOR = "122592"
 | 
			
		||||
logger = logging.getLogger()
 | 
			
		||||
logger.setLevel(logging.INFO)
 | 
			
		||||
 | 
			
		||||
handler = logging.StreamHandler(sys.stdout)
 | 
			
		||||
handler.setLevel(logging.INFO)
 | 
			
		||||
formatter = logging.Formatter('[%(asctime)s] [%(module)s.%(funcName)s:%(lineno)d] [%(levelname)s] - %(message)s')
 | 
			
		||||
handler.setFormatter(formatter)
 | 
			
		||||
logger.addHandler(handler)
 | 
			
		||||
 | 
			
		||||
CURRENT_PATH = os.path.dirname(os.path.abspath(__file__))
 | 
			
		||||
ENDPOINT = 'http://' + os.getenv('ENDPOINT_PAAS_APPMANAGER')
 | 
			
		||||
CLIENT_ID = os.getenv('APPMANAGER_CLIENT_ID')
 | 
			
		||||
CLIENT_SECRET = os.getenv('APPMANAGER_CLIENT_SECRET')
 | 
			
		||||
USERNAME = os.getenv('APPMANAGER_ACCESS_ID')
 | 
			
		||||
PASSWORD = os.getenv('APPMANAGER_ACCESS_SECRET')
 | 
			
		||||
CREATOR = '122592'
 | 
			
		||||
HEADERS = {
 | 
			
		||||
    'X-EmpId': CREATOR
 | 
			
		||||
}
 | 
			
		||||
ENDPOINT = "http://" + os.getenv("ENDPOINT_PAAS_APPMANAGER")
 | 
			
		||||
 | 
			
		||||
formatter = logging.Formatter('[%(asctime)s] - [%(levelname)s] - %(message)s')
 | 
			
		||||
logger = logging.getLogger()
 | 
			
		||||
logger.setLevel(logging.INFO)
 | 
			
		||||
stdout_hdlr = logging.StreamHandler(sys.stdout)
 | 
			
		||||
stdout_hdlr.setFormatter(formatter)
 | 
			
		||||
logger.addHandler(stdout_hdlr)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _insert_cluster(cluster, master_url, oauth_token):
 | 
			
		||||
class AppManagerClient(object):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, endpoint, client_id, client_secret, username, password):
 | 
			
		||||
        os.environ.setdefault('OAUTHLIB_INSECURE_TRANSPORT', '1')
 | 
			
		||||
        self._endpoint = endpoint
 | 
			
		||||
        self._client_id = client_id
 | 
			
		||||
        self._client_secret = client_secret
 | 
			
		||||
        self._username = username
 | 
			
		||||
        self._password = password
 | 
			
		||||
        self._token = self._fetch_token()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def client(self):
 | 
			
		||||
        return OAuth2Session(self._client_id, token=self._token)
 | 
			
		||||
 | 
			
		||||
    def _fetch_token(self):
 | 
			
		||||
        """
 | 
			
		||||
        获取 appmanager access token
 | 
			
		||||
        """
 | 
			
		||||
        oauth = OAuth2Session(client=LegacyApplicationClient(client_id=CLIENT_ID))
 | 
			
		||||
        return oauth.fetch_token(
 | 
			
		||||
            token_url=os.path.join(ENDPOINT, 'oauth/token'),
 | 
			
		||||
            username=self._username,
 | 
			
		||||
            password=self._password,
 | 
			
		||||
            client_id=self._client_id,
 | 
			
		||||
            client_secret=self._client_secret
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _insert_cluster(r, cluster, master_url, oauth_token):
 | 
			
		||||
    """
 | 
			
		||||
    插入集群
 | 
			
		||||
    """
 | 
			
		||||
    response = requests.post("%s/clusters" % ENDPOINT, headers=HEADERS, json={
 | 
			
		||||
    response = r.post("%s/clusters" % ENDPOINT, headers=HEADERS, json={
 | 
			
		||||
        'clusterId': cluster,
 | 
			
		||||
        'clusterName': cluster,
 | 
			
		||||
        'clusterType': 'kubernetes',
 | 
			
		||||
| 
						 | 
				
			
			@ -43,11 +80,11 @@ def _insert_cluster(cluster, master_url, oauth_token):
 | 
			
		|||
        sys.exit(1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _update_cluster(cluster, master_url, oauth_token):
 | 
			
		||||
def _update_cluster(r, cluster, master_url, oauth_token):
 | 
			
		||||
    """
 | 
			
		||||
    更新集群
 | 
			
		||||
    """
 | 
			
		||||
    response = requests.put("%s/clusters/%s" % (ENDPOINT, cluster), headers=HEADERS, json={
 | 
			
		||||
    response = r.put("%s/clusters/%s" % (ENDPOINT, cluster), headers=HEADERS, json={
 | 
			
		||||
        'clusterName': cluster,
 | 
			
		||||
        'clusterType': 'kubernetes',
 | 
			
		||||
        'clusterConfig': {
 | 
			
		||||
| 
						 | 
				
			
			@ -65,13 +102,13 @@ def _update_cluster(cluster, master_url, oauth_token):
 | 
			
		|||
        sys.exit(1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def init_cluster():
 | 
			
		||||
def init_cluster(r):
 | 
			
		||||
    """
 | 
			
		||||
    初始化 appmanager 集群
 | 
			
		||||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
    cluster_mapping = {}
 | 
			
		||||
    items = requests.get("%s/clusters" % ENDPOINT, headers=HEADERS).json().get('data', {}).get('items', [])
 | 
			
		||||
    items = r.get("%s/clusters" % ENDPOINT, headers=HEADERS).json().get('data', {}).get('items', [])
 | 
			
		||||
    for item in items:
 | 
			
		||||
        cluster_mapping[item['clusterId']] = {
 | 
			
		||||
            'masterUrl': item.get('clusterConfig', {}).get('masterUrl'),
 | 
			
		||||
| 
						 | 
				
			
			@ -87,13 +124,14 @@ def init_cluster():
 | 
			
		|||
    clusters = ["master"]
 | 
			
		||||
    for cluster in clusters:
 | 
			
		||||
        if not cluster_mapping.get(cluster):
 | 
			
		||||
            _insert_cluster(cluster, master_url, oauth_token)
 | 
			
		||||
        elif cluster_mapping[cluster].get('masterUrl') != master_url or cluster_mapping[cluster].get('oauthToken') != oauth_token:
 | 
			
		||||
            _update_cluster(cluster, master_url, oauth_token)
 | 
			
		||||
            _insert_cluster(r, cluster, master_url, oauth_token)
 | 
			
		||||
        elif cluster_mapping[cluster].get('masterUrl') != master_url \
 | 
			
		||||
                or cluster_mapping[cluster].get('oauthToken') != oauth_token:
 | 
			
		||||
            _update_cluster(r, cluster, master_url, oauth_token)
 | 
			
		||||
        else:
 | 
			
		||||
            logger.info('no need to update cluster %s' % cluster)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    init_cluster()
 | 
			
		||||
    logger.info("initjob success")
 | 
			
		||||
    init_cluster(AppManagerClient(ENDPOINT, CLIENT_ID, CLIENT_SECRET, USERNAME, PASSWORD).client)
 | 
			
		||||
    logger.info("cluster initjob success")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
create index idx_cluster_type
 | 
			
		||||
    on am_cluster (cluster_type);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,110 @@
 | 
			
		|||
# coding: utf-8
 | 
			
		||||
 | 
			
		||||
import json
 | 
			
		||||
import logging
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
import requests
 | 
			
		||||
from oauthlib.oauth2 import LegacyApplicationClient
 | 
			
		||||
from requests_oauthlib import OAuth2Session
 | 
			
		||||
 | 
			
		||||
logger = logging.getLogger()
 | 
			
		||||
logger.setLevel(logging.INFO)
 | 
			
		||||
 | 
			
		||||
handler = logging.StreamHandler(sys.stdout)
 | 
			
		||||
handler.setLevel(logging.INFO)
 | 
			
		||||
formatter = logging.Formatter('[%(asctime)s] [%(module)s.%(funcName)s:%(lineno)d] [%(levelname)s] - %(message)s')
 | 
			
		||||
handler.setFormatter(formatter)
 | 
			
		||||
logger.addHandler(handler)
 | 
			
		||||
 | 
			
		||||
CURRENT_PATH = os.path.dirname(os.path.abspath(__file__))
 | 
			
		||||
ENDPOINT = 'http://' + os.getenv('ENDPOINT_PAAS_APPMANAGER')
 | 
			
		||||
CLIENT_ID = os.getenv('APPMANAGER_CLIENT_ID')
 | 
			
		||||
CLIENT_SECRET = os.getenv('APPMANAGER_CLIENT_SECRET')
 | 
			
		||||
USERNAME = os.getenv('APPMANAGER_ACCESS_ID')
 | 
			
		||||
PASSWORD = os.getenv('APPMANAGER_ACCESS_SECRET')
 | 
			
		||||
NAMESPACE = 'apsara-bigdata-manager'
 | 
			
		||||
STAGE = 'prod'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AppManagerClient(object):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, endpoint, client_id, client_secret, username, password):
 | 
			
		||||
        os.environ.setdefault('OAUTHLIB_INSECURE_TRANSPORT', '1')
 | 
			
		||||
        self._endpoint = endpoint
 | 
			
		||||
        self._client_id = client_id
 | 
			
		||||
        self._client_secret = client_secret
 | 
			
		||||
        self._username = username
 | 
			
		||||
        self._password = password
 | 
			
		||||
        self._token = self._fetch_token()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def client(self):
 | 
			
		||||
        return OAuth2Session(self._client_id, token=self._token)
 | 
			
		||||
 | 
			
		||||
    def _fetch_token(self):
 | 
			
		||||
        """
 | 
			
		||||
        获取 appmanager access token
 | 
			
		||||
        """
 | 
			
		||||
        oauth = OAuth2Session(client=LegacyApplicationClient(client_id=CLIENT_ID))
 | 
			
		||||
        return oauth.fetch_token(
 | 
			
		||||
            token_url=os.path.join(ENDPOINT, 'oauth/token'),
 | 
			
		||||
            username=self._username,
 | 
			
		||||
            password=self._password,
 | 
			
		||||
            client_id=self._client_id,
 | 
			
		||||
            client_secret=self._client_secret
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def apply(r, url, post_body):
 | 
			
		||||
    """
 | 
			
		||||
    导入 post_body 对应 URL
 | 
			
		||||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
    response = r.post(ENDPOINT + url, json=post_body)
 | 
			
		||||
    response_json = response.json()
 | 
			
		||||
    code = response_json.get('code')
 | 
			
		||||
    if code != 200 and code != 10002:
 | 
			
		||||
        logger.error('import to appmanager failed, url=%s, body=%s, response=%s' % (url, post_body, response.text))
 | 
			
		||||
        sys.exit(1)
 | 
			
		||||
    logger.info('import to appmanager success, url=%s, body=%s' % (url, post_body))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def apply_all():
 | 
			
		||||
    try:
 | 
			
		||||
        r = AppManagerClient(ENDPOINT, CLIENT_ID, CLIENT_SECRET, USERNAME, PASSWORD).client
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        logger.error("cannot find appmanager client auth info, skip")
 | 
			
		||||
        r = requests
 | 
			
		||||
 | 
			
		||||
    apply(r, '/namespaces', {
 | 
			
		||||
        'namespaceId': 'apsara-bigdata-manager',
 | 
			
		||||
        'namespaceName': '服务专用(apsara-bigdata-manager)',
 | 
			
		||||
        'namespaceExt': {}
 | 
			
		||||
    })
 | 
			
		||||
    apply(r, '/namespaces', {
 | 
			
		||||
        'namespaceId': 'default',
 | 
			
		||||
        'namespaceName': '前端配置专用(default)',
 | 
			
		||||
        'namespaceExt': {}
 | 
			
		||||
    })
 | 
			
		||||
    apply(r, '/namespaces/apsara-bigdata-manager/stages', {
 | 
			
		||||
        'stageId': 'master',
 | 
			
		||||
        'stageName': '服务专用(master)',
 | 
			
		||||
        'stageExt': {}
 | 
			
		||||
    })
 | 
			
		||||
    apply(r, '/namespaces/apsara-bigdata-manager/stages', {
 | 
			
		||||
        'stageId': 'slave',
 | 
			
		||||
        'stageName': '服务专用(slave)',
 | 
			
		||||
        'stageExt': {}
 | 
			
		||||
    })
 | 
			
		||||
    apply(r, '/namespaces/default/stages', {
 | 
			
		||||
        'stageId': 'prod',
 | 
			
		||||
        'stageName': '前端配置专用',
 | 
			
		||||
        'stageExt': {}
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    if os.getenv("SREWORKS_INIT") != "enable":
 | 
			
		||||
        apply_all()
 | 
			
		||||
| 
						 | 
				
			
			@ -6,5 +6,5 @@ COPY ./APP-META-PRIVATE/cluster-init /app/sbin
 | 
			
		|||
 | 
			
		||||
# 安装依赖,构建镜像
 | 
			
		||||
RUN sed -i 's/mirrors.tuna.tsinghua.edu.cn/mirrors.aliyun.com/g' /etc/apk/repositories \
 | 
			
		||||
    && pip install -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com requests
 | 
			
		||||
    && pip install -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com requests requests_oauthlib
 | 
			
		||||
ENTRYPOINT ["/app/sbin/cluster_run.sh"]
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +19,9 @@ COPY --from=build /app/${APP_NAME}-start-standalone/target/${APP_NAME}/BOOT-INF/
 | 
			
		|||
RUN wget -O /app/helm "https://abm-storage.oss-cn-zhangjiakou.aliyuncs.com/lib/helm" \
 | 
			
		||||
    && chmod +x /app/helm \
 | 
			
		||||
    && wget -O /app/kustomize "https://abm-storage.oss-cn-zhangjiakou.aliyuncs.com/lib/kustomize" \
 | 
			
		||||
    && chmod +x /app/kustomize
 | 
			
		||||
    && chmod +x /app/kustomize \
 | 
			
		||||
    && wget -O /app/kubectl "https://abm-storage.oss-cn-zhangjiakou.aliyuncs.com/lib/kubectl" \
 | 
			
		||||
    && chmod +x /app/kubectl
 | 
			
		||||
 | 
			
		||||
WORKDIR /app
 | 
			
		||||
ENTRYPOINT ["/app/sbin/run_sreworks.sh"]
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
FROM ${MAVEN_IMAGE} AS build
 | 
			
		||||
COPY . /app
 | 
			
		||||
WORKDIR /app
 | 
			
		||||
RUN mkdir /root/.m2/ && curl ${MAVEN_SETTINGS_XML} -o /root/.m2/settings.xml
 | 
			
		||||
RUN mvn -Dmaven.test.skip=true clean package -U
 | 
			
		||||
 | 
			
		||||
# Release
 | 
			
		||||
FROM ${MAVEN_IMAGE} AS release
 | 
			
		||||
USER root
 | 
			
		||||
WORKDIR /root
 | 
			
		||||
ARG APP_NAME=tesla-appmanager
 | 
			
		||||
# Copy Jars
 | 
			
		||||
COPY --from=build /app/${APP_NAME}-start-standalone/target/${APP_NAME}.jar /app/${APP_NAME}-standalone.jar
 | 
			
		||||
COPY --from=build /app/${APP_NAME}-start-standalone/target/${APP_NAME}/BOOT-INF/classes/application-docker.properties /app/config/application.properties
 | 
			
		||||
# Copy Resources
 | 
			
		||||
COPY --from=build /app/${APP_NAME}-start-standalone/target/${APP_NAME}/BOOT-INF/classes/dynamicscripts /app/dynamicscripts
 | 
			
		||||
COPY --from=build /app/${APP_NAME}-start-standalone/target/${APP_NAME}/BOOT-INF/classes/jinja /app/jinja
 | 
			
		||||
RUN wget -O /app/helm "${HELM_BIN_URL}" \
 | 
			
		||||
    && chmod +x /app/helm \
 | 
			
		||||
    && wget -O /app/kustomize "${KUSTOMIZE_BIN_URL}"  \
 | 
			
		||||
    && chmod +x /app/kustomize
 | 
			
		||||
 | 
			
		||||
WORKDIR /app
 | 
			
		||||
ENTRYPOINT ["/app/sbin/run_sreworks.sh"]
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +57,7 @@
 | 
			
		|||
        <hikaricp.version>5.0.1</hikaricp.version>
 | 
			
		||||
 | 
			
		||||
        <!-- tesla -->
 | 
			
		||||
        <tesla.spring.boot.version>2.1.7</tesla.spring.boot.version>
 | 
			
		||||
        <tesla.spring.boot.version>2.1.9</tesla.spring.boot.version>
 | 
			
		||||
        <task-flow-service.version>1.1.0</task-flow-service.version>
 | 
			
		||||
 | 
			
		||||
        <!-- other -->
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,8 +47,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
 | 
			
		|||
            web.ignoring()
 | 
			
		||||
                    .antMatchers("/status.taobao")
 | 
			
		||||
                    .antMatchers("/actuator/**")
 | 
			
		||||
                    .antMatchers("/clusters**")
 | 
			
		||||
                    .antMatchers("/clusters/**")
 | 
			
		||||
                    .antMatchers("/traits**")
 | 
			
		||||
                    .antMatchers("/flow-manager/**")
 | 
			
		||||
                    .antMatchers("/traits/**")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,50 @@
 | 
			
		|||
package com.alibaba.tesla.appmanager.common.enums;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 集群类型
 | 
			
		||||
 *
 | 
			
		||||
 * @author yaoxing.gyx@alibaba-inc.com
 | 
			
		||||
 */
 | 
			
		||||
public enum ClusterTypeEnum {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 普通 K8S 集群
 | 
			
		||||
     */
 | 
			
		||||
    KUBERNETES("kubernetes"),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 资源集群
 | 
			
		||||
     */
 | 
			
		||||
    RESOURCE_CLUSTER("resource-cluster"),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 虚拟集群
 | 
			
		||||
     */
 | 
			
		||||
    VC("vc");
 | 
			
		||||
 | 
			
		||||
    private final String text;
 | 
			
		||||
 | 
			
		||||
    ClusterTypeEnum(final String text) {
 | 
			
		||||
        this.text = text;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return text;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * String to Enum
 | 
			
		||||
     *
 | 
			
		||||
     * @param text String
 | 
			
		||||
     * @return Enum
 | 
			
		||||
     */
 | 
			
		||||
    public static ClusterTypeEnum fromString(String text) {
 | 
			
		||||
        for (ClusterTypeEnum item : ClusterTypeEnum.values()) {
 | 
			
		||||
            if (item.text.equalsIgnoreCase(text)) {
 | 
			
		||||
                return item;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +74,12 @@ public enum ComponentTypeEnum {
 | 
			
		|||
    /**
 | 
			
		||||
     * ABM Helm Component
 | 
			
		||||
     */
 | 
			
		||||
    ABM_HELM;
 | 
			
		||||
    ABM_HELM,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * ABM Status Component
 | 
			
		||||
     */
 | 
			
		||||
    ABM_STATUS;
 | 
			
		||||
 | 
			
		||||
    public static ComponentTypeEnum parse(String value) {
 | 
			
		||||
        ComponentTypeEnum result = Enums.getIfPresent(ComponentTypeEnum.class, value).orNull();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,6 +77,16 @@ public enum DynamicScriptKindEnum {
 | 
			
		|||
     */
 | 
			
		||||
    DEPLOY_ABM_HELM_COMPONENT,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 构建 ABM Status 模块
 | 
			
		||||
     */
 | 
			
		||||
    BUILD_ABM_STATUS_COMPONENT,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 部署 ABM Status 模块
 | 
			
		||||
     */
 | 
			
		||||
    DEPLOY_ABM_STATUS_COMPONENT,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 通用构建 Resource Addon 模块
 | 
			
		||||
     */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -424,8 +424,8 @@ public class DeployConfigServiceImpl implements DeployConfigService {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
        throw new AppException(AppErrorCode.DEPLOY_ERROR,
 | 
			
		||||
                String.format("cannot find best deploy config with given condition|clusterId=%s|namespaceId=%s|" +
 | 
			
		||||
                        "stageId=%s", clusterId, namespaceId, stageId));
 | 
			
		||||
                String.format("cannot find best deploy config with given condition(general type)|" +
 | 
			
		||||
                        "clusterId=%s|namespaceId=%s|stageId=%s", clusterId, namespaceId, stageId));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -469,7 +469,7 @@ public class DeployConfigServiceImpl implements DeployConfigService {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 兜底
 | 
			
		||||
        // 通过无 appId 的部署配置记录进行二次查找
 | 
			
		||||
        List<DeployConfigDO> filteredAppRecords = appRecords.stream()
 | 
			
		||||
                .filter(item -> StringUtils.isEmpty(item.getEnvId()))
 | 
			
		||||
                .collect(Collectors.toList());
 | 
			
		||||
| 
						 | 
				
			
			@ -496,9 +496,11 @@ public class DeployConfigServiceImpl implements DeployConfigService {
 | 
			
		|||
            }
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 再不行就报错了
 | 
			
		||||
        throw new AppException(AppErrorCode.DEPLOY_ERROR,
 | 
			
		||||
                String.format("cannot find best deploy config with given condition|clusterId=%s|namespaceId=%s|" +
 | 
			
		||||
                        "stageId=%s", clusterId, namespaceId, stageId));
 | 
			
		||||
                String.format("cannot find best deploy config with given condition(specified name)|clusterId=%s|" +
 | 
			
		||||
                        "namespaceId=%s|stageId=%s", clusterId, namespaceId, stageId));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,6 +46,15 @@ public class DeployConfigEnvId {
 | 
			
		|||
        return String.format("Unit:%s", unitId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 返回空环境字符串标识(通用类型)
 | 
			
		||||
     *
 | 
			
		||||
     * @return 字符串标识
 | 
			
		||||
     */
 | 
			
		||||
    public static String emptyUnitStr() {
 | 
			
		||||
        return "Unit";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 返回 Stage 字符串标识
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,13 @@ public interface WorkloadBinder {
 | 
			
		|||
     */
 | 
			
		||||
    void setOwnerReference(String ownerReference);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 返回 Owner Reference 字符串
 | 
			
		||||
     *
 | 
			
		||||
     * @return Owner Reference JSON Object String
 | 
			
		||||
     */
 | 
			
		||||
    String getOwnerReference();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取当前被绑定的 Component 对象
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +1,10 @@
 | 
			
		|||
package com.alibaba.tesla.appmanager.domain.req.cluster;
 | 
			
		||||
 | 
			
		||||
import com.alibaba.tesla.appmanager.common.BaseRequest;
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
import lombok.Builder;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.NoArgsConstructor;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import lombok.experimental.SuperBuilder;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Cluster 查询请求
 | 
			
		||||
| 
						 | 
				
			
			@ -13,10 +12,10 @@ import java.io.Serializable;
 | 
			
		|||
 * @author yaoxing.gyx@alibaba-inc.com
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@Builder
 | 
			
		||||
@SuperBuilder
 | 
			
		||||
@NoArgsConstructor
 | 
			
		||||
@AllArgsConstructor
 | 
			
		||||
public class ClusterQueryReq implements Serializable {
 | 
			
		||||
public class ClusterQueryReq extends BaseRequest {
 | 
			
		||||
 | 
			
		||||
    private static final long serialVersionUID = -1872143932301240289L;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -29,4 +28,9 @@ public class ClusterQueryReq implements Serializable {
 | 
			
		|||
     * Cluster 名称
 | 
			
		||||
     */
 | 
			
		||||
    private String clusterName;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Cluster 类型
 | 
			
		||||
     */
 | 
			
		||||
    private String clusterType;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -258,6 +258,16 @@ public class GroovyHandlerFactory {
 | 
			
		|||
                            DynamicScriptKindEnum.DEPLOY_ABM_HELM_COMPONENT.toString(),
 | 
			
		||||
                            DefaultConstant.DEFAULT_GROOVY_HANDLER);
 | 
			
		||||
                }
 | 
			
		||||
            case ABM_STATUS:
 | 
			
		||||
                if (ComponentActionEnum.BUILD.equals(action)) {
 | 
			
		||||
                    return get(scriptClass,
 | 
			
		||||
                            DynamicScriptKindEnum.BUILD_ABM_STATUS_COMPONENT.toString(),
 | 
			
		||||
                            DefaultConstant.DEFAULT_GROOVY_HANDLER);
 | 
			
		||||
                } else {
 | 
			
		||||
                    return get(scriptClass,
 | 
			
		||||
                            DynamicScriptKindEnum.DEPLOY_ABM_STATUS_COMPONENT.toString(),
 | 
			
		||||
                            DefaultConstant.DEFAULT_GROOVY_HANDLER);
 | 
			
		||||
                }
 | 
			
		||||
            case INTERNAL_ADDON:
 | 
			
		||||
                if ("productops".equals(componentName)) {
 | 
			
		||||
                    if (ComponentActionEnum.BUILD.equals(action)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -356,7 +356,7 @@ public class K8sMicroServiceMetaDO implements Serializable {
 | 
			
		|||
        if (StringUtils.isNotEmpty(kind)) {
 | 
			
		||||
            microServiceExtJson.put("kind", kind);
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new AppException(AppErrorCode.INVALID_USER_ARGS, "kind parameter is required");
 | 
			
		||||
            microServiceExtJson.put("kind", "AdvancedStatefulSet");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (CollectionUtils.isNotEmpty(envList)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -450,7 +450,7 @@ public class K8sMicroServiceMetaDO implements Serializable {
 | 
			
		|||
        if (StringUtils.isNotEmpty(initContainerListString)) {
 | 
			
		||||
            initContainerList = JSON.parseArray(initContainerListString, InitContainerDTO.class);
 | 
			
		||||
        } else {
 | 
			
		||||
            containerObjectList = Collections.emptyList();
 | 
			
		||||
            initContainerList = Collections.emptyList();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String repoString = microServiceExtJson.getString("repo");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -136,6 +136,10 @@ public class AppController extends BaseController {
 | 
			
		|||
        if (StringUtils.isEmpty(appId)) {
 | 
			
		||||
            return buildSucceedResult(Boolean.TRUE);
 | 
			
		||||
        }
 | 
			
		||||
        String cloudType = System.getenv("CLOUD_TYPE");
 | 
			
		||||
        if ("Internal".equals(cloudType)) {
 | 
			
		||||
            return buildClientErrorResult("Deleting apps is now prohibited");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        boolean result = appMetaProvider.delete(appId);
 | 
			
		||||
        return buildSucceedResult(result);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,33 +24,14 @@ public class DeployAppComponentRunnerScene extends AbstractLocalDagBase {
 | 
			
		|||
        node("DeployAppTraitNode");
 | 
			
		||||
 | 
			
		||||
        edge("DeployAppDeciderNode", "DeployAppCreateComponentNode",
 | 
			
		||||
                String.format("#DeployAppDeciderNode['output']['%s'] == '%s' || " +
 | 
			
		||||
                                "#DeployAppDeciderNode['output']['%s'] == '%s' || " +
 | 
			
		||||
                                "#DeployAppDeciderNode['output']['%s'] == '%s' || " +
 | 
			
		||||
                                "#DeployAppDeciderNode['output']['%s'] == '%s' || " +
 | 
			
		||||
                                "#DeployAppDeciderNode['output']['%s'] == '%s' || " +
 | 
			
		||||
                                "#DeployAppDeciderNode['output']['%s'] == '%s' || " +
 | 
			
		||||
                                "#DeployAppDeciderNode['output']['%s'] == '%s' || " +
 | 
			
		||||
                                "#DeployAppDeciderNode['output']['%s'] == '%s' || " +
 | 
			
		||||
                                "#DeployAppDeciderNode['output']['%s'] == '%s'",
 | 
			
		||||
                        AppFlowParamKey.COMPONENT_TYPE,
 | 
			
		||||
                        ComponentTypeEnum.K8S_MICROSERVICE,
 | 
			
		||||
                        AppFlowParamKey.COMPONENT_TYPE,
 | 
			
		||||
                        ComponentTypeEnum.INTERNAL_ADDON,
 | 
			
		||||
                        AppFlowParamKey.COMPONENT_TYPE,
 | 
			
		||||
                        ComponentTypeEnum.ABM_CHART,
 | 
			
		||||
                        AppFlowParamKey.COMPONENT_TYPE,
 | 
			
		||||
                        ComponentTypeEnum.HELM,
 | 
			
		||||
                        AppFlowParamKey.COMPONENT_TYPE,
 | 
			
		||||
                        ComponentTypeEnum.ABM_OPERATOR_TVD,
 | 
			
		||||
                        AppFlowParamKey.COMPONENT_TYPE,
 | 
			
		||||
                        ComponentTypeEnum.ABM_KUSTOMIZE,
 | 
			
		||||
                        AppFlowParamKey.COMPONENT_TYPE,
 | 
			
		||||
                        ComponentTypeEnum.ABM_HELM,
 | 
			
		||||
                        AppFlowParamKey.COMPONENT_TYPE,
 | 
			
		||||
                        ComponentTypeEnum.ASI_COMPONENT,
 | 
			
		||||
                        AppFlowParamKey.COMPONENT_TYPE,
 | 
			
		||||
                        ComponentTypeEnum.K8S_JOB));
 | 
			
		||||
                String.format("#DeployAppDeciderNode['output']['%s'] != '%s' && " +
 | 
			
		||||
                                "#DeployAppDeciderNode['output']['%s'] != '%s' && " +
 | 
			
		||||
                                "#DeployAppDeciderNode['output']['%s'] != '%s' && " +
 | 
			
		||||
                                "#DeployAppDeciderNode['output']['%s'] != '%s'",
 | 
			
		||||
                        AppFlowParamKey.COMPONENT_TYPE, ComponentTypeEnum.RESOURCE_ADDON,
 | 
			
		||||
                        AppFlowParamKey.COMPONENT_TYPE, ComponentTypeEnum.TRAIT_ADDON,
 | 
			
		||||
                        AppFlowParamKey.COMPONENT_TYPE, ComponentTypeEnum.CUSTOM_ADDON,
 | 
			
		||||
                        AppFlowParamKey.COMPONENT_TYPE, ""));
 | 
			
		||||
        edge("DeployAppDeciderNode", "DeployAppCreateResourceAddonNode",
 | 
			
		||||
                String.format("#DeployAppDeciderNode['output']['%s'] == '%s'",
 | 
			
		||||
                        AppFlowParamKey.COMPONENT_TYPE,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,6 @@ import org.springframework.stereotype.Service;
 | 
			
		|||
import org.springframework.transaction.annotation.Transactional;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Cluster 服务
 | 
			
		||||
| 
						 | 
				
			
			@ -48,8 +47,8 @@ public class ClusterProviderImpl implements ClusterProvider {
 | 
			
		|||
    public Pagination<ClusterDTO> queryByCondition(ClusterQueryReq request) {
 | 
			
		||||
        ClusterQueryCondition condition = new ClusterQueryCondition();
 | 
			
		||||
        ClassUtil.copy(request, condition);
 | 
			
		||||
        List<ClusterDO> results = clusterService.list(condition);
 | 
			
		||||
        return Pagination.valueOf(results, item -> clusterConvert.to(item));
 | 
			
		||||
        Pagination<ClusterDO> results = clusterService.list(condition);
 | 
			
		||||
        return Pagination.transform(results, item -> clusterConvert.to(item));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -117,8 +116,9 @@ public class ClusterProviderImpl implements ClusterProvider {
 | 
			
		|||
 | 
			
		||||
        // 如果设置某个集群的 masterFlag 为 true,那么设置其余所有 cluster 的 masterFlag 为 false
 | 
			
		||||
        if (request.getMasterFlag() != null && request.getMasterFlag()) {
 | 
			
		||||
            List<ClusterDO> allClusters = clusterService.list(ClusterQueryCondition.builder().build());
 | 
			
		||||
            for (ClusterDO cluster : allClusters) {
 | 
			
		||||
            ClusterQueryCondition condition = ClusterQueryCondition.builder().build();
 | 
			
		||||
            Pagination<ClusterDO> allClusters = clusterService.list(condition);
 | 
			
		||||
            for (ClusterDO cluster : allClusters.getItems()) {
 | 
			
		||||
                if (cluster.getClusterId().equals(clusterId)) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,4 +20,6 @@ public class ClusterQueryCondition extends BaseCondition {
 | 
			
		|||
    private String clusterId;
 | 
			
		||||
 | 
			
		||||
    private String clusterName;
 | 
			
		||||
 | 
			
		||||
    private String clusterType;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,12 +3,11 @@ package com.alibaba.tesla.appmanager.server.repository.condition;
 | 
			
		|||
import com.alibaba.tesla.appmanager.common.BaseCondition;
 | 
			
		||||
import com.alibaba.tesla.appmanager.common.enums.DeployComponentStateEnum;
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
import lombok.Builder;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.NoArgsConstructor;
 | 
			
		||||
import lombok.experimental.SuperBuilder;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component 部署单查询条件类
 | 
			
		||||
| 
						 | 
				
			
			@ -37,6 +36,8 @@ public class DeployComponentQueryCondition extends BaseCondition {
 | 
			
		|||
 | 
			
		||||
    private DeployComponentStateEnum deployStatus;
 | 
			
		||||
 | 
			
		||||
    private List<DeployComponentStateEnum> deployStatusList;
 | 
			
		||||
 | 
			
		||||
    private Long deployProcessId;
 | 
			
		||||
 | 
			
		||||
    private String orderBy;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,6 +36,7 @@ public class ClusterRepositoryImpl implements ClusterRepository {
 | 
			
		|||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<ClusterDO> selectByCondition(ClusterQueryCondition condition) {
 | 
			
		||||
        condition.doPagination();
 | 
			
		||||
        return clusterDOMapper.selectByExample(buildExample(condition));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +54,9 @@ public class ClusterRepositoryImpl implements ClusterRepository {
 | 
			
		|||
        if (StringUtils.isNotEmpty(condition.getClusterName())) {
 | 
			
		||||
            criteria.andClusterNameEqualTo(condition.getClusterName());
 | 
			
		||||
        }
 | 
			
		||||
        if (StringUtils.isNotEmpty(condition.getClusterType())) {
 | 
			
		||||
            criteria.andClusterTypeEqualTo(condition.getClusterType());
 | 
			
		||||
        }
 | 
			
		||||
        return example;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,7 @@ import org.springframework.stereotype.Service;
 | 
			
		|||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
@Service
 | 
			
		||||
@Slf4j
 | 
			
		||||
| 
						 | 
				
			
			@ -89,6 +90,11 @@ public class DeployComponentRepositoryImpl implements DeployComponentRepository
 | 
			
		|||
        if (condition.getDeployStatus() != null) {
 | 
			
		||||
            criteria.andDeployStatusEqualTo(condition.getDeployStatus().name());
 | 
			
		||||
        }
 | 
			
		||||
        if (condition.getDeployStatusList() != null && condition.getDeployStatusList().size() > 0) {
 | 
			
		||||
            criteria.andDeployStatusIn(condition.getDeployStatusList().stream()
 | 
			
		||||
                    .map(Enum::name)
 | 
			
		||||
                    .collect(Collectors.toList()));
 | 
			
		||||
        }
 | 
			
		||||
        if (condition.getDeployProcessId() != null && condition.getDeployProcessId() > 0) {
 | 
			
		||||
            criteria.andDeployProcessIdEqualTo(String.valueOf(condition.getDeployProcessId()));
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,9 @@
 | 
			
		|||
package com.alibaba.tesla.appmanager.server.service.cluster;
 | 
			
		||||
 | 
			
		||||
import com.alibaba.tesla.appmanager.common.pagination.Pagination;
 | 
			
		||||
import com.alibaba.tesla.appmanager.server.repository.condition.ClusterQueryCondition;
 | 
			
		||||
import com.alibaba.tesla.appmanager.server.repository.domain.ClusterDO;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 集群服务
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +17,7 @@ public interface ClusterService {
 | 
			
		|||
     * @param condition 请求数据
 | 
			
		||||
     * @return 查询结果
 | 
			
		||||
     */
 | 
			
		||||
    List<ClusterDO> list(ClusterQueryCondition condition);
 | 
			
		||||
    Pagination<ClusterDO> list(ClusterQueryCondition condition);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取指定 clusterId 对应的数据
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ package com.alibaba.tesla.appmanager.server.service.cluster.impl;
 | 
			
		|||
import com.alibaba.fastjson.JSONObject;
 | 
			
		||||
import com.alibaba.tesla.appmanager.common.exception.AppErrorCode;
 | 
			
		||||
import com.alibaba.tesla.appmanager.common.exception.AppException;
 | 
			
		||||
import com.alibaba.tesla.appmanager.common.pagination.Pagination;
 | 
			
		||||
import com.alibaba.tesla.appmanager.server.repository.ClusterRepository;
 | 
			
		||||
import com.alibaba.tesla.appmanager.server.repository.condition.ClusterQueryCondition;
 | 
			
		||||
import com.alibaba.tesla.appmanager.server.repository.domain.ClusterDO;
 | 
			
		||||
| 
						 | 
				
			
			@ -14,6 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		|||
import org.springframework.stereotype.Service;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
 | 
			
		||||
@Service
 | 
			
		||||
@Slf4j
 | 
			
		||||
| 
						 | 
				
			
			@ -29,8 +31,9 @@ public class ClusterServiceImpl implements ClusterService {
 | 
			
		|||
     * @return 查询结果
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<ClusterDO> list(ClusterQueryCondition condition) {
 | 
			
		||||
        return clusterRepository.selectByCondition(condition);
 | 
			
		||||
    public Pagination<ClusterDO> list(ClusterQueryCondition condition) {
 | 
			
		||||
        List<ClusterDO> result = clusterRepository.selectByCondition(condition);
 | 
			
		||||
        return Pagination.valueOf(result, Function.identity());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ import java.util.concurrent.ConcurrentMap;
 | 
			
		|||
 **/
 | 
			
		||||
@Service
 | 
			
		||||
@Slf4j
 | 
			
		||||
public class ComponentPackageManager implements ApplicationListener<ComponentPackageLoadEvent> {
 | 
			
		||||
public class ComponentPackageBuilderExecutorManager implements ApplicationListener<ComponentPackageLoadEvent> {
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private ApplicationContext context;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ import com.alibaba.tesla.appmanager.server.repository.condition.ComponentPackage
 | 
			
		|||
import com.alibaba.tesla.appmanager.server.repository.domain.ComponentPackageDO;
 | 
			
		||||
import com.alibaba.tesla.appmanager.server.repository.domain.ComponentPackageTaskDO;
 | 
			
		||||
import com.alibaba.tesla.appmanager.server.service.componentpackage.ComponentPackageBuilderService;
 | 
			
		||||
import com.alibaba.tesla.appmanager.server.service.componentpackage.ComponentPackageManager;
 | 
			
		||||
import com.alibaba.tesla.appmanager.server.service.componentpackage.ComponentPackageBuilderExecutorManager;
 | 
			
		||||
import com.alibaba.tesla.appmanager.server.service.componentpackage.handler.BuildComponentHandler;
 | 
			
		||||
import com.alibaba.tesla.appmanager.server.service.componentpackage.instance.ComponentPackageBase;
 | 
			
		||||
import com.alibaba.tesla.appmanager.server.storage.Storage;
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +49,7 @@ public class ComponentPackageBuilderServiceImpl implements ComponentPackageBuild
 | 
			
		|||
    @Autowired
 | 
			
		||||
    private PackageProperties packageProperties;
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private ComponentPackageManager componentPackageManager;
 | 
			
		||||
    private ComponentPackageBuilderExecutorManager componentPackageBuilderExecutorManager;
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private ComponentPackageTaskRepository componentPackageTaskRepository;
 | 
			
		||||
    @Autowired
 | 
			
		||||
| 
						 | 
				
			
			@ -178,7 +178,7 @@ public class ComponentPackageBuilderServiceImpl implements ComponentPackageBuild
 | 
			
		|||
        switch (componentType) {
 | 
			
		||||
            case K8S_MICROSERVICE:
 | 
			
		||||
            case K8S_JOB: {
 | 
			
		||||
                ComponentPackageBase instance = componentPackageManager.getInstance(componentType.name());
 | 
			
		||||
                ComponentPackageBase instance = componentPackageBuilderExecutorManager.getInstance(componentType.name());
 | 
			
		||||
                instance.exportComponentPackage(taskDO);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -266,10 +266,14 @@ public class ImageBuilderServiceImpl implements ImageBuilderService {
 | 
			
		|||
            throws IOException {
 | 
			
		||||
        Jinjava jinjava = new Jinjava();
 | 
			
		||||
        Path dockerfileTemplate;
 | 
			
		||||
        String dockerfileTemplateStr = request.getDockerfileTemplate();
 | 
			
		||||
        if (StringUtils.isEmpty(dockerfileTemplateStr)) {
 | 
			
		||||
            dockerfileTemplateStr = "Dockerfile";
 | 
			
		||||
        }
 | 
			
		||||
        if (StringUtils.isEmpty(request.getRepoPath())) {
 | 
			
		||||
            dockerfileTemplate = Paths.get(cloneDir.toString(), request.getDockerfileTemplate());
 | 
			
		||||
            dockerfileTemplate = Paths.get(cloneDir.toString(), dockerfileTemplateStr);
 | 
			
		||||
        } else {
 | 
			
		||||
            dockerfileTemplate = Paths.get(cloneDir.toString(), request.getRepoPath(), request.getDockerfileTemplate());
 | 
			
		||||
            dockerfileTemplate = Paths.get(cloneDir.toString(), request.getRepoPath(), dockerfileTemplateStr);
 | 
			
		||||
        }
 | 
			
		||||
        String template = FileUtils.readFileToString(dockerfileTemplate.toFile(), StandardCharsets.UTF_8);
 | 
			
		||||
        String renderedTemplate = jinjava.render(template, request.getDockerfileTemplateArgs());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,10 @@
 | 
			
		|||
package com.alibaba.tesla.appmanager.server.service.informer;
 | 
			
		||||
 | 
			
		||||
import com.alibaba.tesla.appmanager.common.enums.ClusterTypeEnum;
 | 
			
		||||
import com.alibaba.tesla.appmanager.common.enums.DynamicScriptKindEnum;
 | 
			
		||||
import com.alibaba.tesla.appmanager.common.exception.AppErrorCode;
 | 
			
		||||
import com.alibaba.tesla.appmanager.common.exception.AppException;
 | 
			
		||||
import com.alibaba.tesla.appmanager.common.pagination.Pagination;
 | 
			
		||||
import com.alibaba.tesla.appmanager.dynamicscript.core.GroovyHandlerFactory;
 | 
			
		||||
import com.alibaba.tesla.appmanager.dynamicscript.core.GroovyHandlerItem;
 | 
			
		||||
import com.alibaba.tesla.appmanager.kubernetes.KubernetesClientFactory;
 | 
			
		||||
| 
						 | 
				
			
			@ -61,14 +63,16 @@ public class InformerManager {
 | 
			
		|||
    @Scheduled(cron = "${appmanager.cron-job.informer-manager-refresh:0 * * * * *}")
 | 
			
		||||
    @SchedulerLock(name = "informerManagerFactoryRefresh")
 | 
			
		||||
    public void init() throws IOException {
 | 
			
		||||
        List<ClusterDO> clusters = clusterService.list(ClusterQueryCondition.builder().build());
 | 
			
		||||
        for (ClusterDO cluster : clusters) {
 | 
			
		||||
        Pagination<ClusterDO> clusters = clusterService.list(ClusterQueryCondition.builder()
 | 
			
		||||
                .clusterType(ClusterTypeEnum.KUBERNETES.toString())
 | 
			
		||||
                .build());
 | 
			
		||||
        for (ClusterDO cluster : clusters.getItems()) {
 | 
			
		||||
            initCluster(cluster);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 通过差值确认需要删除的集群
 | 
			
		||||
        HashSet<String> clusterIdSet = new HashSet<>(clusterMd5Map.keySet());
 | 
			
		||||
        clusterIdSet.removeAll(clusters.stream().map(ClusterDO::getClusterId).collect(Collectors.toSet()));
 | 
			
		||||
        clusterIdSet.removeAll(clusters.getItems().stream().map(ClusterDO::getClusterId).collect(Collectors.toSet()));
 | 
			
		||||
        for (String clusterId : clusterIdSet) {
 | 
			
		||||
            removeCluster(clusterId);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -523,7 +523,7 @@ public class RtAppInstanceServiceImpl implements RtAppInstanceService {
 | 
			
		|||
                    .build());
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            log.error("cannot getOrCreate application cr|clusterId={}|namespaceId={}|appInstanceId={}|" +
 | 
			
		||||
                    "exception={}", clusterId, namespaceId, appInstanceName, e.getMessage());
 | 
			
		||||
                    "exception={}", clusterId, namespaceId, appInstanceName, ExceptionUtils.getStackTrace(e));
 | 
			
		||||
            return "";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,14 @@ public interface RtComponentInstanceService {
 | 
			
		|||
     * 上报 Component 实例状态
 | 
			
		||||
     *
 | 
			
		||||
     * @param request     上报数据请求
 | 
			
		||||
     * @param ignoreError 是否忽略错误 true or false,错误时抛出 AppException
 | 
			
		||||
     */
 | 
			
		||||
    void report(ReportRtComponentInstanceStatusReq request, boolean ignoreError);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 上报 Component 实例状态 (忽略错误)
 | 
			
		||||
     *
 | 
			
		||||
     * @param request 上报数据请求
 | 
			
		||||
     */
 | 
			
		||||
    void report(ReportRtComponentInstanceStatusReq request);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,9 +81,10 @@ public class RtComponentInstanceServiceImpl implements RtComponentInstanceServic
 | 
			
		|||
     * 上报 Component 实例状态
 | 
			
		||||
     *
 | 
			
		||||
     * @param request     上报数据请求
 | 
			
		||||
     * @param ignoreError 是否忽略错误 true or false,错误时抛出 AppException
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public void report(ReportRtComponentInstanceStatusReq request) {
 | 
			
		||||
    public void report(ReportRtComponentInstanceStatusReq request, boolean ignoreError) {
 | 
			
		||||
        String componentInstanceId = request.getComponentInstanceId();
 | 
			
		||||
        RtComponentInstanceQueryCondition condition = RtComponentInstanceQueryCondition.builder()
 | 
			
		||||
                .componentInstanceId(componentInstanceId)
 | 
			
		||||
| 
						 | 
				
			
			@ -105,12 +106,18 @@ public class RtComponentInstanceServiceImpl implements RtComponentInstanceServic
 | 
			
		|||
                .stageId(request.getStageId())
 | 
			
		||||
                .build());
 | 
			
		||||
        if (appInstance == null) {
 | 
			
		||||
            log.warn("action=componentInstanceStatusReport|cannot find app instance by component instance query " +
 | 
			
		||||
                            "condition|appInstanceId={}|componentInstanceId={}|appId={}|clusterId={}|namespaceId={}|" +
 | 
			
		||||
                            "componentName={}|status={}", appInstanceId, componentInstanceId,
 | 
			
		||||
            String errorMessage = String.format("action=componentInstanceStatusReport|cannot find app instance by " +
 | 
			
		||||
                            "component instance query condition|appInstanceId=%s|componentInstanceId=%s|appId=%s|" +
 | 
			
		||||
                            "clusterId=%s|namespaceId=%s|componentName=%s|status=%s",
 | 
			
		||||
                    appInstanceId, componentInstanceId,
 | 
			
		||||
                    request.getAppId(), request.getClusterId(), request.getNamespaceId(), request.getComponentName(),
 | 
			
		||||
                    request.getStatus());
 | 
			
		||||
            if (ignoreError) {
 | 
			
		||||
                log.warn(errorMessage);
 | 
			
		||||
                return;
 | 
			
		||||
            } else {
 | 
			
		||||
                throw new AppException(AppErrorCode.UNKNOWN_ERROR, errorMessage);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 获取 component type 对象实例
 | 
			
		||||
| 
						 | 
				
			
			@ -131,7 +138,13 @@ public class RtComponentInstanceServiceImpl implements RtComponentInstanceServic
 | 
			
		|||
            record.setConditions(JSONObject.toJSONString(request.getConditions()));
 | 
			
		||||
            int updated = repository.updateByCondition(record, condition);
 | 
			
		||||
            if (updated == 0) {
 | 
			
		||||
                if (ignoreError) {
 | 
			
		||||
                    log.debug("report request has ignored because of lock version|condition={}", conditionStr);
 | 
			
		||||
                } else {
 | 
			
		||||
                    throw new AppException(AppErrorCode.LOCKER_VERSION_EXPIRED,
 | 
			
		||||
                            String.format("report request has ignored because of lock version|condition=%s",
 | 
			
		||||
                                    conditionStr));
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                log.debug("report request has processed|condition={}", conditionStr);
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -154,7 +167,13 @@ public class RtComponentInstanceServiceImpl implements RtComponentInstanceServic
 | 
			
		|||
            try {
 | 
			
		||||
                repository.insert(record);
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                if (ignoreError) {
 | 
			
		||||
                    log.info("report request has ignored because of race condition|condition={}", conditionStr);
 | 
			
		||||
                } else {
 | 
			
		||||
                    throw new AppException(AppErrorCode.LOCKER_VERSION_EXPIRED,
 | 
			
		||||
                            String.format("report request has ignored becuase of race condition|condition=%s",
 | 
			
		||||
                                    conditionStr));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        log.info("action=componentInstanceStatusReport|component instance status has reported|appInstanceId={}|" +
 | 
			
		||||
| 
						 | 
				
			
			@ -166,6 +185,16 @@ public class RtComponentInstanceServiceImpl implements RtComponentInstanceServic
 | 
			
		|||
        rtAppInstanceService.asyncTriggerStatusUpdate(appInstanceId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 上报 Component 实例状态 (忽略错误)
 | 
			
		||||
     *
 | 
			
		||||
     * @param request 上报数据请求
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public void report(ReportRtComponentInstanceStatusReq request) {
 | 
			
		||||
        report(request, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取实时 component instance 状态列表
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,67 @@
 | 
			
		|||
apiVersion: core.oam.dev/v1alpha2
 | 
			
		||||
kind: ApplicationConfiguration
 | 
			
		||||
metadata:
 | 
			
		||||
  annotations:
 | 
			
		||||
    appId: testapp
 | 
			
		||||
    appInstanceName: "test-app-instance"
 | 
			
		||||
  name: deploy-abm-status
 | 
			
		||||
spec:
 | 
			
		||||
  parameterValues:
 | 
			
		||||
    - name: "kubeconfig"
 | 
			
		||||
      value: "fake_config"
 | 
			
		||||
    - name: "namespaceId"
 | 
			
		||||
      value: "default"
 | 
			
		||||
  components:
 | 
			
		||||
    - revisionName: ABM_KUSTOMIZE|kustomize-demo-chart@0.0.2@test|_
 | 
			
		||||
      scopes:
 | 
			
		||||
        - scopeRef:
 | 
			
		||||
            apiVersion: flyadmin.alibaba.com/v1alpha1
 | 
			
		||||
            kind: Cluster
 | 
			
		||||
            name: "{{ Global.clusterId }}"
 | 
			
		||||
        - scopeRef:
 | 
			
		||||
            apiVersion: flyadmin.alibaba.com/v1alpha1
 | 
			
		||||
            kind: Namespace
 | 
			
		||||
            name: "{{ Global.namespaceId }}"
 | 
			
		||||
      parameterValues:
 | 
			
		||||
        - name: kubeconfig
 | 
			
		||||
          value: "{{ Global.kubeconfig }}"
 | 
			
		||||
          toFieldPaths:
 | 
			
		||||
            - spec.base64Kubeconfig
 | 
			
		||||
        - name: path
 | 
			
		||||
          value: "overlays/staging"
 | 
			
		||||
          toFieldPaths:
 | 
			
		||||
            - spec.path
 | 
			
		||||
    - revisionName: ABM_STATUS|general-status@kustomize-demo-chart|_
 | 
			
		||||
      scopes:
 | 
			
		||||
        - scopeRef:
 | 
			
		||||
            apiVersion: flyadmin.alibaba.com/v1alpha1
 | 
			
		||||
            kind: Cluster
 | 
			
		||||
            name: "{{ Global.clusterId }}"
 | 
			
		||||
        - scopeRef:
 | 
			
		||||
            apiVersion: flyadmin.alibaba.com/v1alpha1
 | 
			
		||||
            kind: Namespace
 | 
			
		||||
            name: "{{ Global.namespaceId }}"
 | 
			
		||||
      dependencies:
 | 
			
		||||
        - component: ABM_KUSTOMIZE|kustomize-demo-chart@0.0.2@test
 | 
			
		||||
      parameterValues:
 | 
			
		||||
        - name: kubeconfig
 | 
			
		||||
          value: "{{ Global.kubeconfig }}"
 | 
			
		||||
          toFieldPaths:
 | 
			
		||||
            - spec.base64Kubeconfig
 | 
			
		||||
        - name: options
 | 
			
		||||
          value:
 | 
			
		||||
            groups:
 | 
			
		||||
              - namespace: default
 | 
			
		||||
                labels:
 | 
			
		||||
                  a: b
 | 
			
		||||
                  c: d
 | 
			
		||||
                resources:
 | 
			
		||||
                  - v1/pods
 | 
			
		||||
                  - batch/v1/jobs
 | 
			
		||||
              - namespace: n1
 | 
			
		||||
                labels:
 | 
			
		||||
                  e: f
 | 
			
		||||
                resources:
 | 
			
		||||
                  - pods
 | 
			
		||||
          toFieldPaths:
 | 
			
		||||
            - spec.options
 | 
			
		||||
| 
						 | 
				
			
			@ -4,9 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 | 
			
		|||
import com.alibaba.tesla.appmanager.domain.core.WorkloadResource;
 | 
			
		||||
import com.alibaba.tesla.appmanager.domain.schema.DeployAppSchema;
 | 
			
		||||
import com.alibaba.tesla.appmanager.domain.schema.TraitDefinition;
 | 
			
		||||
import io.fabric8.kubernetes.api.model.OwnerReference;
 | 
			
		||||
import org.apache.commons.lang3.NotImplementedException;
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Trait 实现基类
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +36,7 @@ public class BaseTrait implements Trait {
 | 
			
		|||
    /**
 | 
			
		||||
     * Owner Reference
 | 
			
		||||
     */
 | 
			
		||||
    private OwnerReference ownerReference;
 | 
			
		||||
    private String ownerReference;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 绑定到当前 Trait 的 SpecComponent 对象
 | 
			
		||||
| 
						 | 
				
			
			@ -81,12 +79,13 @@ public class BaseTrait implements Trait {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setOwnerReference(String ownerReference) {
 | 
			
		||||
        if (StringUtils.isNotEmpty(ownerReference)) {
 | 
			
		||||
            this.ownerReference = JSONObject.parseObject(ownerReference, OwnerReference.class);
 | 
			
		||||
        } else {
 | 
			
		||||
            this.ownerReference = null;
 | 
			
		||||
    public String getOwnerReference() {
 | 
			
		||||
        return this.ownerReference;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setOwnerReference(String ownerReference) {
 | 
			
		||||
        this.ownerReference = ownerReference;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@ package com.alibaba.tesla.appmanager.trait;
 | 
			
		|||
import com.alibaba.fastjson.JSONObject;
 | 
			
		||||
import com.alibaba.tesla.appmanager.domain.core.TaskExecutor;
 | 
			
		||||
import com.alibaba.tesla.appmanager.domain.core.WorkloadBinder;
 | 
			
		||||
import io.fabric8.kubernetes.api.model.OwnerReference;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Trait 接口定义
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,8 +11,10 @@ import com.alibaba.tesla.appmanager.domain.schema.TraitDefinition;
 | 
			
		|||
import com.alibaba.tesla.appmanager.kubernetes.KubernetesClientFactory;
 | 
			
		||||
import com.alibaba.tesla.appmanager.spring.util.SpringBeanUtil;
 | 
			
		||||
import com.alibaba.tesla.appmanager.trait.BaseTrait;
 | 
			
		||||
import com.fasterxml.jackson.core.JsonProcessingException;
 | 
			
		||||
import com.fasterxml.jackson.databind.ObjectMapper;
 | 
			
		||||
import com.google.common.collect.ImmutableMap;
 | 
			
		||||
import io.fabric8.kubernetes.api.model.OwnerReference;
 | 
			
		||||
import io.fabric8.kubernetes.api.model.Service;
 | 
			
		||||
import io.fabric8.kubernetes.api.model.ServiceBuilder;
 | 
			
		||||
import io.fabric8.kubernetes.api.model.ServiceSpec;
 | 
			
		||||
| 
						 | 
				
			
			@ -48,6 +50,7 @@ public class ServiceTrait extends BaseTrait {
 | 
			
		|||
 | 
			
		||||
        // 获取基本信息
 | 
			
		||||
        String namespace = workloadRef.getMetadata().getNamespace();
 | 
			
		||||
        String ownerReference = getOwnerReference();
 | 
			
		||||
 | 
			
		||||
        // 支持多个 Service 配置
 | 
			
		||||
        JSONArray services = getSpec().getJSONArray("services");
 | 
			
		||||
| 
						 | 
				
			
			@ -70,8 +73,8 @@ public class ServiceTrait extends BaseTrait {
 | 
			
		|||
                if (spec == null) {
 | 
			
		||||
                    throw new AppException(AppErrorCode.INVALID_USER_ARGS, "spec is required in service trait");
 | 
			
		||||
                }
 | 
			
		||||
                JSONObject cr = generateService(namespace, name, labels, annotations, spec);
 | 
			
		||||
                applyService(clusterId, cr, namespace, name, labels, annotations);
 | 
			
		||||
                JSONObject cr = generateService(namespace, name, labels, annotations, ownerReference, spec);
 | 
			
		||||
                applyService(clusterId, cr, namespace, name, labels, annotations, ownerReference);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            String name = workloadRef.getMetadata().getName();
 | 
			
		||||
| 
						 | 
				
			
			@ -87,8 +90,8 @@ public class ServiceTrait extends BaseTrait {
 | 
			
		|||
            if (annotations.size() == 0) {
 | 
			
		||||
                annotations = (JSONObject) workloadRef.getMetadata().getAnnotations();
 | 
			
		||||
            }
 | 
			
		||||
            JSONObject cr = generateService(namespace, name, labels, annotations, getSpec());
 | 
			
		||||
            applyService(clusterId, cr, namespace, name, labels, annotations);
 | 
			
		||||
            JSONObject cr = generateService(namespace, name, labels, annotations, ownerReference, getSpec());
 | 
			
		||||
            applyService(clusterId, cr, namespace, name, labels, annotations, ownerReference);
 | 
			
		||||
 | 
			
		||||
            // 写入暴露值
 | 
			
		||||
            getSpec().put("serviceName", name);
 | 
			
		||||
| 
						 | 
				
			
			@ -97,15 +100,18 @@ public class ServiceTrait extends BaseTrait {
 | 
			
		|||
 | 
			
		||||
    /**
 | 
			
		||||
     * 应用 Service 到集群中
 | 
			
		||||
     *
 | 
			
		||||
     * @param clusterId      集群 ID
 | 
			
		||||
     * @param cr             CR
 | 
			
		||||
     * @param namespace      Namespace
 | 
			
		||||
     * @param name           Name
 | 
			
		||||
     * @param labels         Labels
 | 
			
		||||
     * @param annotations    Annotations
 | 
			
		||||
     * @param ownerReference Owner Reference
 | 
			
		||||
     */
 | 
			
		||||
    private void applyService(
 | 
			
		||||
            String clusterId, JSONObject cr, String namespace, String name, JSONObject labels, JSONObject annotations) {
 | 
			
		||||
            String clusterId, JSONObject cr, String namespace, String name, JSONObject labels,
 | 
			
		||||
            JSONObject annotations, String ownerReference) {
 | 
			
		||||
        KubernetesClientFactory clientFactory = SpringBeanUtil.getBean(KubernetesClientFactory.class);
 | 
			
		||||
        DefaultKubernetesClient client = clientFactory.get(clusterId);
 | 
			
		||||
        // 应用到集群
 | 
			
		||||
| 
						 | 
				
			
			@ -135,7 +141,24 @@ public class ServiceTrait extends BaseTrait {
 | 
			
		|||
                    Service result = client.services()
 | 
			
		||||
                            .inNamespace(namespace)
 | 
			
		||||
                            .withName(name)
 | 
			
		||||
                            .edit(s -> new ServiceBuilder(s)
 | 
			
		||||
                            .edit(s -> {
 | 
			
		||||
                                if (StringUtils.isNotEmpty(ownerReference)) {
 | 
			
		||||
                                    try {
 | 
			
		||||
                                        return new ServiceBuilder(s)
 | 
			
		||||
                                                .editMetadata()
 | 
			
		||||
                                                .withLabels(JSON.parseObject(finalLabels.toJSONString(), new TypeReference<Map<String, String>>() {
 | 
			
		||||
                                                }))
 | 
			
		||||
                                                .withAnnotations(JSON.parseObject(finalAnnotations.toJSONString(), new TypeReference<Map<String, String>>() {
 | 
			
		||||
                                                }))
 | 
			
		||||
                                                .withOwnerReferences(mapper.readValue(ownerReference, OwnerReference.class))
 | 
			
		||||
                                                .endMetadata()
 | 
			
		||||
                                                .withSpec(newSpec)
 | 
			
		||||
                                                .build();
 | 
			
		||||
                                    } catch (JsonProcessingException e) {
 | 
			
		||||
                                        throw new RuntimeException(e);
 | 
			
		||||
                                    }
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    return new ServiceBuilder(s)
 | 
			
		||||
                                            .editMetadata()
 | 
			
		||||
                                            .withLabels(JSON.parseObject(finalLabels.toJSONString(), new TypeReference<Map<String, String>>() {
 | 
			
		||||
                                            }))
 | 
			
		||||
| 
						 | 
				
			
			@ -143,7 +166,9 @@ public class ServiceTrait extends BaseTrait {
 | 
			
		|||
                                            }))
 | 
			
		||||
                                            .endMetadata()
 | 
			
		||||
                                            .withSpec(newSpec)
 | 
			
		||||
                                    .build());
 | 
			
		||||
                                            .build();
 | 
			
		||||
                                }
 | 
			
		||||
                            });
 | 
			
		||||
                    log.info("cr yaml has updated in kubernetes|cluster={}|namespace={}|name={}|labels={}|" +
 | 
			
		||||
                                    "annotations={}|newSpec={}|result={}", clusterId, namespace, name,
 | 
			
		||||
                            JSONObject.toJSONString(labels), JSONObject.toJSONString(annotations),
 | 
			
		||||
| 
						 | 
				
			
			@ -170,11 +195,14 @@ public class ServiceTrait extends BaseTrait {
 | 
			
		|||
     *
 | 
			
		||||
     * @param namespace   命名空间
 | 
			
		||||
     * @param name        标识名称
 | 
			
		||||
     * @param labels      Labels
 | 
			
		||||
     * @param annotations Annotations
 | 
			
		||||
     * @param spec        spec 定义
 | 
			
		||||
     * @return JSONObject
 | 
			
		||||
     */
 | 
			
		||||
    private JSONObject generateService(
 | 
			
		||||
            String namespace, String name, JSONObject labels, JSONObject annotations, JSONObject spec) {
 | 
			
		||||
            String namespace, String name, JSONObject labels, JSONObject annotations, String ownerReference,
 | 
			
		||||
            JSONObject spec) {
 | 
			
		||||
        String serviceStr = JSONObject.toJSONString(ImmutableMap.of(
 | 
			
		||||
                "apiVersion", "v1",
 | 
			
		||||
                "kind", "Service",
 | 
			
		||||
| 
						 | 
				
			
			@ -191,6 +219,11 @@ public class ServiceTrait extends BaseTrait {
 | 
			
		|||
                )
 | 
			
		||||
        ));
 | 
			
		||||
        JSONObject service = JSONObject.parseObject(serviceStr);
 | 
			
		||||
        if (StringUtils.isNotEmpty(ownerReference)) {
 | 
			
		||||
            service.getJSONObject("metadata").put("ownerReferences", new JSONArray());
 | 
			
		||||
            service.getJSONObject("metadata").getJSONArray("ownerReferences")
 | 
			
		||||
                    .add(JSONObject.parseObject(ownerReference));
 | 
			
		||||
        }
 | 
			
		||||
        service.getJSONObject("spec").putAll(spec);
 | 
			
		||||
        return service;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue