diff --git a/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/artifact/repository/HelmRemoteRepository.kt b/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/artifact/repository/HelmRemoteRepository.kt index 369cbfd9e7..07645676fd 100644 --- a/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/artifact/repository/HelmRemoteRepository.kt +++ b/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/artifact/repository/HelmRemoteRepository.kt @@ -31,6 +31,7 @@ package com.tencent.bkrepo.helm.artifact.repository +import com.tencent.bkrepo.common.api.constant.StringPool import com.tencent.bkrepo.common.api.util.readYamlString import com.tencent.bkrepo.common.api.util.toYamlString import com.tencent.bkrepo.common.artifact.api.ArtifactFile @@ -47,6 +48,8 @@ import com.tencent.bkrepo.common.artifact.resolve.response.ArtifactChannel import com.tencent.bkrepo.common.artifact.resolve.response.ArtifactResource import com.tencent.bkrepo.common.artifact.stream.Range import com.tencent.bkrepo.common.artifact.stream.artifactStream +import com.tencent.bkrepo.common.artifact.util.FileNameParser +import com.tencent.bkrepo.common.artifact.util.PackageKeys import com.tencent.bkrepo.helm.config.HelmProperties import com.tencent.bkrepo.helm.constants.CHART import com.tencent.bkrepo.helm.constants.FILE_TYPE @@ -66,6 +69,7 @@ import com.tencent.bkrepo.helm.utils.ChartParserUtil import com.tencent.bkrepo.helm.utils.HelmMetadataUtils import com.tencent.bkrepo.helm.utils.HelmUtils import com.tencent.bkrepo.helm.utils.ObjectBuilderUtil +import com.tencent.bkrepo.repository.constant.PROXY_DOWNLOAD_URL import com.tencent.bkrepo.repository.pojo.download.PackageDownloadRecord import com.tencent.bkrepo.repository.pojo.metadata.MetadataModel import com.tencent.bkrepo.repository.pojo.node.service.NodeCreateRequest @@ -161,10 +165,35 @@ class HelmRemoteRepository( val remoteDomain = remoteConfiguration.url.trimEnd('/') return when (fullPath) { HelmUtils.getIndexCacheYamlFullPath() -> INDEX_REQUEST_URL.format(remoteDomain, INDEX_YAML) - else -> CHART_REQUEST_URL.format(remoteDomain, fullPath) + else -> buildDownloadUrl(context, fullPath, remoteDomain) } } + private fun buildDownloadUrl(context: ArtifactContext, fullPath: String?, remoteDomain: String): String { + val map = FileNameParser.parseNameAndVersionWithRegex(fullPath!!) + val name = map[NAME].toString() + val version = map[VERSION].toString() + val packageVersion = packageService.findVersionByName( + projectId = context.projectId, + repoName = context.repoName, + packageKey = PackageKeys.ofHelm(name), + versionName = version + ) + var downloadUrl = CHART_REQUEST_URL.format(remoteDomain, fullPath) + if (packageVersion != null) { + val proxyDownloadUrl = packageVersion.metadata[PROXY_DOWNLOAD_URL]?.toString() + if (proxyDownloadUrl != null) { + downloadUrl = if (!proxyDownloadUrl.contains(remoteDomain)) { + remoteDomain + StringPool.SLASH + proxyDownloadUrl + } else { + proxyDownloadUrl + } + } + } + logger.info("remote chart download url is $downloadUrl") + return downloadUrl + } + /** * 远程下载响应回调 */ diff --git a/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/pojo/metadata/HelmChartMetadata.kt b/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/pojo/metadata/HelmChartMetadata.kt index 36c82f666d..d1e8f34789 100644 --- a/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/pojo/metadata/HelmChartMetadata.kt +++ b/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/pojo/metadata/HelmChartMetadata.kt @@ -31,6 +31,7 @@ package com.tencent.bkrepo.helm.pojo.metadata +import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.github.zafarkhaja.semver.Version @@ -52,6 +53,8 @@ data class HelmChartMetadata( var name: String, var sources: List = emptyList(), var urls: List = emptyList(), + @JsonIgnore + var proxyDownloadUrl: String? = null, var version: String, var type: String?, var annotations: Map? diff --git a/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/service/impl/AbstractChartService.kt b/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/service/impl/AbstractChartService.kt index bd1516b701..bf9c674568 100644 --- a/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/service/impl/AbstractChartService.kt +++ b/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/service/impl/AbstractChartService.kt @@ -602,10 +602,14 @@ open class AbstractChartService : ArtifactService() { domain: String, projectId: String, repoName: String, - helmIndexYamlMetadata: HelmIndexYamlMetadata + helmIndexYamlMetadata: HelmIndexYamlMetadata, + initProxyUrls: Boolean = true ) { helmIndexYamlMetadata.entries.values.forEach { it.forEach { chart -> + if (initProxyUrls) { + chart.proxyDownloadUrl = chart.urls.firstOrNull() + } chart.urls = listOf( UrlFormatter.format( domain, "$projectId/$repoName/charts/${chart.name}-${chart.version}.tgz" diff --git a/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/service/impl/HelmOperationService.kt b/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/service/impl/HelmOperationService.kt index 4c8e96d666..3f7f71f87b 100644 --- a/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/service/impl/HelmOperationService.kt +++ b/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/service/impl/HelmOperationService.kt @@ -104,10 +104,10 @@ class HelmOperationService( // 删除index文件 nodeService.deleteNode( NodeDeleteRequest( - projectId = projectId, - repoName = repoName, - fullPath = HelmUtils.getIndexCacheYamlFullPath(), - operator = SecurityUtils.getUserId() + projectId = projectId, + repoName = repoName, + fullPath = HelmUtils.getIndexCacheYamlFullPath(), + operator = SecurityUtils.getUserId() ) ) } @@ -213,7 +213,8 @@ class HelmOperationService( domain = helmProperties.domain, projectId = repoDetail.projectId, repoName = repoDetail.name, - helmIndexYamlMetadata = oldIndex + helmIndexYamlMetadata = oldIndex, + initProxyUrls = false ) // 存储新index文件 storeIndex( diff --git a/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/utils/HelmMetadataUtils.kt b/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/utils/HelmMetadataUtils.kt index 8f4e009a16..5dd689a022 100644 --- a/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/utils/HelmMetadataUtils.kt +++ b/src/backend/helm/biz-helm/src/main/kotlin/com/tencent/bkrepo/helm/utils/HelmMetadataUtils.kt @@ -36,6 +36,7 @@ import com.tencent.bkrepo.common.api.util.toJsonString import com.tencent.bkrepo.common.artifact.constant.SOURCE_TYPE import com.tencent.bkrepo.common.artifact.resolve.response.ArtifactChannel import com.tencent.bkrepo.helm.pojo.metadata.HelmChartMetadata +import com.tencent.bkrepo.repository.constant.PROXY_DOWNLOAD_URL import com.tencent.bkrepo.repository.pojo.metadata.MetadataModel object HelmMetadataUtils { @@ -53,6 +54,9 @@ object HelmMetadataUtils { sourceType?.let { mutableMap.add(MetadataModel(SOURCE_TYPE, sourceType)) } + if (!chartInfo.proxyDownloadUrl.isNullOrEmpty()) { + mutableMap.add(MetadataModel(PROXY_DOWNLOAD_URL, chartInfo.proxyDownloadUrl!!)) + } return mutableMap } diff --git a/src/backend/repository/api-repository/src/main/kotlin/com/tencent/bkrepo/repository/constant/Constants.kt b/src/backend/repository/api-repository/src/main/kotlin/com/tencent/bkrepo/repository/constant/Constants.kt index e1e25ab070..a9c71398ee 100644 --- a/src/backend/repository/api-repository/src/main/kotlin/com/tencent/bkrepo/repository/constant/Constants.kt +++ b/src/backend/repository/api-repository/src/main/kotlin/com/tencent/bkrepo/repository/constant/Constants.kt @@ -45,5 +45,7 @@ const val NODE_METADATA = "nodeMetadata" const val MD5 = "md5" const val SHA256 = "sha256" const val PACKAGE_KEY = "key" +const val VERSION = "version" const val NODE_DETAIL_LIST_KEY = "nodeDetailList" +const val PROXY_DOWNLOAD_URL = "proxyDownloadUrl" diff --git a/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/config/CommonRemoteRepository.kt b/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/config/CommonRemoteRepository.kt index 4aec7c4900..62d8a27ed9 100644 --- a/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/config/CommonRemoteRepository.kt +++ b/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/config/CommonRemoteRepository.kt @@ -31,11 +31,17 @@ package com.tencent.bkrepo.repository.config +import com.tencent.bkrepo.common.api.constant.StringPool import com.tencent.bkrepo.common.artifact.api.ArtifactFile import com.tencent.bkrepo.common.artifact.pojo.RepositoryType import com.tencent.bkrepo.common.artifact.repository.context.ArtifactContext import com.tencent.bkrepo.common.artifact.repository.context.ArtifactDownloadContext import com.tencent.bkrepo.common.artifact.repository.remote.RemoteRepository +import com.tencent.bkrepo.common.artifact.util.FileNameParser +import com.tencent.bkrepo.common.artifact.util.PackageKeys +import com.tencent.bkrepo.repository.constant.NAME +import com.tencent.bkrepo.repository.constant.PROXY_DOWNLOAD_URL +import com.tencent.bkrepo.repository.constant.VERSION import com.tencent.bkrepo.repository.pojo.metadata.MetadataModel import com.tencent.bkrepo.repository.pojo.node.service.NodeCreateRequest import org.slf4j.Logger @@ -56,8 +62,7 @@ class CommonRemoteRepository : RemoteRepository() { return if (RepositoryType.HELM != type) { super.createRemoteDownloadUrl(context) } else { - val remoteConfiguration = context.getRemoteConfiguration() - CHART_REQUEST_URL.format(remoteConfiguration.url, context.artifactInfo.getArtifactFullPath()) + buildChartDownloadUrl(context) } } @@ -91,6 +96,36 @@ class CommonRemoteRepository : RemoteRepository() { return redirectManager.redirect(context) } + private fun buildChartDownloadUrl(context: ArtifactContext): String { + val remoteConfiguration = context.getRemoteConfiguration() + val remoteDomain = remoteConfiguration.url.trimEnd('/') + val map = FileNameParser.parseNameAndVersionWithRegex(context.artifactInfo.getArtifactFullPath()) + val name = map[NAME].toString() + val version = map[VERSION].toString() + val packageVersion = packageService.findVersionByName( + projectId = context.projectId, + repoName = context.repoName, + packageKey = PackageKeys.ofHelm(name), + versionName = version + ) + var downloadUrl = CHART_REQUEST_URL.format( + remoteConfiguration.url, + context.artifactInfo.getArtifactFullPath() + ) + if (packageVersion != null) { + val proxyDownloadUrl = packageVersion.metadata[PROXY_DOWNLOAD_URL]?.toString() + if (proxyDownloadUrl != null) { + downloadUrl = if (!proxyDownloadUrl.contains(remoteDomain)) { + remoteDomain + StringPool.SLASH + proxyDownloadUrl + } else { + proxyDownloadUrl + } + } + } + logger.info("remote chart download url is $downloadUrl") + return downloadUrl + } + /** * 如果fullPath已经是完整的url,则直接使用,否则进行拼接 */