fun getVaultFeatureSettings()

in agent/src/main/kotlin/org/jetbrains/teamcity/vault/agent/VaultFeatureSettingsFetcher.kt [30:95]


    fun getVaultFeatureSettings(namespace: String, build: AgentRunningBuild): VaultFeatureSettings? {
        val logger = build.buildLogger
        val errorPrefix = "Failed to get HashiCorp Vault wrapped token from TeamCity server for the project connection with ID '$namespace':"

        return try {
            val configuration = build.agentConfiguration as BuildAgentConfigurationEx
            val requestBuilder = HTTPRequestBuilder("${configuration.serverUrl}/app/${VaultConstants.ControllerSettings.URL}/${VaultConstants.ControllerSettings.WRAP_TOKEN_PATH}")
                .withMethod(HttpMethod.GET)
                .addParameters(
                    Pair("buildId", build.buildId.toString()),
                    Pair("namespace", namespace)
                )
                .withCredentials(SimpleCredentials(build.accessUser, build.accessCode))
                .withTimeout(configuration.serverConnectionTimeout * 1000)
                .allowNonSecureConnection(true)
                .withPreemptiveAuthentication(true)
                .withTrustStore(sslTrustStoreProvider.trustStore)

            if (configuration.serverProxyHost != null) {
                requestBuilder.withProxyHost(
                    URIBuilder()
                        .setHost(configuration.serverProxyHost).setPort(configuration.serverProxyPort).build()
                )

                val serverProxyCredentials = configuration.serverProxyCredentials
                if (serverProxyCredentials != null) {
                    requestBuilder.withProxyCredentials(serverProxyCredentials)
                }
            }

            val retrier = VaultAgentRetrier.getAgentRetrier(build,"fetching the vault credentials from TeamCity server")
            val response = retrier.execute(Callable {
                HTTPRequestBuilder.DelegatingRequestHandler().doSyncRequest(requestBuilder.build())
            }
            )

            response.use {
                if (response == null || response.statusCode != HttpStatus.OK.value()) {
                    val errorMessage = "$errorPrefix ${response?.bodyAsString.orEmpty()}"
                    VaultBuildFeature.LOG.error(errorMessage)
                    logger.logBuildProblem(BuildProblemData.createBuildProblem("VC_${build.buildTypeId}_${namespace}_A", "VaultConnection", errorMessage))
                    build.interruptBuild(errorMessage, false)
                    return null
                }

                val contentStream = response.contentStream
                if (contentStream == null) {
                    val errorMessage = "$errorPrefix empty response from server"
                    VaultBuildFeature.LOG.error(errorMessage)
                    logger.logBuildProblem(BuildProblemData.createBuildProblem("VC_${build.buildTypeId}_${namespace}_A", "VaultConnection", errorMessage))
                    build.interruptBuild(errorMessage, false)
                    return null
                }

                val featureSettingsParams = objectMapper.readValue<Map<String, String>>(contentStream)

                VaultFeatureSettings.getAgentFeatureFromProperties(featureSettingsParams)
            }
        } catch (e: Throwable) {
            val errorMessage = "$errorPrefix internal error"
            VaultBuildFeature.LOG.error(errorMessage, e)
            logger.internalError(VaultConstants.FeatureSettings.FEATURE_TYPE, errorMessage, e)
            build.stopBuild(errorMessage)
            null
        }
    }