Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions agent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
<groupId>com.walmartlabs.concord</groupId>
<artifactId>concord-common</artifactId>
</dependency>
<dependency>
<groupId>com.walmartlabs.concord</groupId>
<artifactId>concord-github-app-installation</artifactId>
</dependency>
<dependency>
<groupId>com.walmartlabs.concord</groupId>
<artifactId>concord-client2</artifactId>
Expand Down Expand Up @@ -143,6 +147,11 @@
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>

<!-- dependency tree fix for mvnd -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.walmartlabs.concord.agent;

/*-
* *****
* Concord
* -----
* Copyright (C) 2017 - 2025 Walmart Inc.
* -----
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =====
*/

import com.typesafe.config.Config;
import com.walmartlabs.concord.agent.remote.ApiClientFactory;
import com.walmartlabs.concord.common.AuthTokenProvider;
import com.walmartlabs.concord.common.ExternalAuthToken;
import com.walmartlabs.concord.github.appinstallation.GitHubAppInstallation;
import com.walmartlabs.concord.sdk.Secret;

import javax.annotation.Nullable;
import javax.inject.Inject;
import java.net.URI;
import java.util.List;
import java.util.Optional;

public class AgentAuthTokenProvider implements AuthTokenProvider {
private final List<AuthTokenProvider> authTokenProviders;

@Inject
public AgentAuthTokenProvider(GitHubAppInstallation githubProvider,
OauthTokenProvider oauthTokenProvider) {

this.authTokenProviders = List.of(githubProvider, oauthTokenProvider);
}

@Override
public boolean supports(URI repo, @Nullable Secret secret) {
return authTokenProviders.stream()
.anyMatch(p -> p.supports(repo, secret));
}

public Optional<ExternalAuthToken> getToken(URI repo, @Nullable Secret secret) {
for (var tokenProvider : authTokenProviders) {
if (tokenProvider.supports(repo, secret)) {
return tokenProvider.getToken(repo, secret);
}
}

return Optional.empty();
}

public static class ConcordServerTokenProvider implements AuthTokenProvider {
private final ApiClientFactory apiClientFactory;
private final Config config;

@Inject
public ConcordServerTokenProvider(ApiClientFactory apiClientFactory, Config config) {
this.apiClientFactory = apiClientFactory;
this.config = config;
}


@Override
public boolean supports(URI repo, @Nullable Secret secret) {
// TODO implement
return false;
}

@Override
public Optional<ExternalAuthToken> getToken(URI repo, @Nullable Secret secret) {
// TODO implement
return Optional.empty();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
import com.walmartlabs.concord.agent.remote.ApiClientFactory;
import com.walmartlabs.concord.agent.remote.QueueClientProvider;
import com.walmartlabs.concord.common.ObjectMapperProvider;
import com.walmartlabs.concord.common.cfg.OauthTokenConfig;
import com.walmartlabs.concord.config.ConfigModule;
import com.walmartlabs.concord.github.appinstallation.cfg.GitHubAppInstallationConfig;
import com.walmartlabs.concord.server.queueclient.QueueClient;

import javax.inject.Named;
Expand Down Expand Up @@ -59,6 +61,10 @@ public void configure(Binder binder) {
binder.bind(DockerConfiguration.class).in(SINGLETON);
binder.bind(RuntimeConfiguration.class).asEagerSingleton();
binder.bind(GitConfiguration.class).in(SINGLETON);
binder.bind(OauthTokenConfig.class).to(GitConfiguration.class).in(SINGLETON);
binder.bind(GitHubConfiguration.class).in(SINGLETON);
binder.bind(GitHubAppInstallationConfig.class).to(GitHubConfiguration.class).in(SINGLETON);
binder.bind(AgentAuthTokenProvider.ConcordServerTokenProvider.class).in(SINGLETON);
binder.bind(ImportConfiguration.class).in(SINGLETON);
binder.bind(PreForkConfiguration.class).in(SINGLETON);
binder.bind(RepositoryCacheConfiguration.class).in(SINGLETON);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import javax.inject.Inject;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;

public class RepositoryManager {
Expand All @@ -51,13 +50,13 @@ public RepositoryManager(SecretClient secretClient,
GitConfiguration gitCfg,
RepositoryCacheConfiguration cacheCfg,
ObjectMapper objectMapper,
DependencyManager dependencyManager) throws IOException {
DependencyManager dependencyManager,
AgentAuthTokenProvider agentAuthTokenProvider) throws IOException {

this.secretClient = secretClient;
this.gitCfg = gitCfg;

GitClientConfiguration clientCfg = GitClientConfiguration.builder()
.oauthToken(gitCfg.getToken())
.defaultOperationTimeout(gitCfg.getDefaultOperationTimeout())
.fetchTimeout(gitCfg.getFetchTimeout())
.httpLowSpeedLimit(gitCfg.getHttpLowSpeedLimit())
Expand All @@ -66,9 +65,10 @@ public RepositoryManager(SecretClient secretClient,
.sshTimeoutRetryCount(gitCfg.getSshTimeoutRetryCount())
.build();

List<RepositoryProvider> providers = Arrays.asList(new MavenRepositoryProvider(dependencyManager), new GitCliRepositoryProvider(clientCfg));
this.providers = new RepositoryProviders(providers);

this.providers = new RepositoryProviders(List.of(
new MavenRepositoryProvider(dependencyManager),
new GitCliRepositoryProvider(clientCfg, agentAuthTokenProvider)
));
this.repositoryCache = new RepositoryCache(cacheCfg.getCacheDir(),
cacheCfg.getInfoDir(),
cacheCfg.getLockTimeout(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,21 @@
*/

import com.typesafe.config.Config;
import com.walmartlabs.concord.common.cfg.MappingAuthConfig;
import com.walmartlabs.concord.common.cfg.OauthTokenConfig;

import javax.inject.Inject;
import java.time.Duration;
import java.util.List;
import java.util.Optional;

import static com.walmartlabs.concord.agent.cfg.Utils.getStringOrDefault;

public class GitConfiguration {
public class GitConfiguration implements OauthTokenConfig {

private final String token;
private final String oauthUsername;
private final String oauthUrlPattern;
private final boolean shallowClone;
private final boolean checkAlreadyFetched;
private final Duration defaultOperationTimeout;
Expand All @@ -39,10 +45,13 @@ public class GitConfiguration {
private final Duration sshTimeout;
private final int sshTimeoutRetryCount;
private final boolean skip;
private final List<? extends Config> authConfigs;

@Inject
public GitConfiguration(Config cfg) {
this.token = getStringOrDefault(cfg, "git.oauth", () -> null);
this.oauthUsername = getStringOrDefault(cfg, "git.oauthUsername", () -> null);
this.oauthUrlPattern = getStringOrDefault(cfg, "git.oauthUrlPattern", () -> null);
this.shallowClone = cfg.getBoolean("git.shallowClone");
this.checkAlreadyFetched = cfg.getBoolean("git.checkAlreadyFetched");
this.defaultOperationTimeout = cfg.getDuration("git.defaultOperationTimeout");
Expand All @@ -52,10 +61,22 @@ public GitConfiguration(Config cfg) {
this.sshTimeout = cfg.getDuration("git.sshTimeout");
this.sshTimeoutRetryCount = cfg.getInt("git.sshTimeoutRetryCount");
this.skip = cfg.getBoolean("git.skip");
this.authConfigs = cfg.getConfigList("git.systemAuth");
}

public String getToken() {
return token;
@Override
public Optional<String> getOauthToken() {
return Optional.ofNullable(token);
}

@Override
public Optional<String> getOauthUsername() {
return Optional.ofNullable(oauthUsername);
}

@Override
public Optional<String> getOauthUrlPattern() {
return Optional.ofNullable(oauthUrlPattern);
}

public boolean isShallowClone() {
Expand Down Expand Up @@ -93,4 +114,46 @@ public int getSshTimeoutRetryCount() {
public boolean isSkip() {
return skip;
}

public List<MappingAuthConfig> getSystemAuth() {
return authConfigs.stream()
.map(o -> {
AuthSource type = AuthSource.valueOf(o.getString("type").toUpperCase());

return (AuthConfig) switch (type) {
case OAUTH_TOKEN -> OauthConfig.from(o);
};
})
.map(AuthConfig::toGitAuth)
.toList();

}

enum AuthSource {
OAUTH_TOKEN
}

public interface AuthConfig {
MappingAuthConfig toGitAuth();
}

public record OauthConfig(String id, String urlPattern, String token) implements AuthConfig {

static OauthConfig from(Config cfg) {
return new OauthConfig(
getStringOrDefault(cfg, "id", () -> "system-oauth-token"),
cfg.getString("urlPattern"),
cfg.getString("token")
);
}

@Override
public MappingAuthConfig.OauthAuthConfig toGitAuth() {
return MappingAuthConfig.OauthAuthConfig.builder()
.id(this.id())
.urlPattern(MappingAuthConfig.assertBaseUrlPattern(this.urlPattern()))
.token(this.token())
.build();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.walmartlabs.concord.agent.cfg;

/*-
* *****
* Concord
* -----
* Copyright (C) 2017 - 2025 Walmart Inc.
* -----
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =====
*/

import com.walmartlabs.concord.common.cfg.MappingAuthConfig;
import com.walmartlabs.concord.github.appinstallation.cfg.GitHubAppInstallationConfig;

import javax.inject.Inject;
import java.time.Duration;
import java.util.List;

public class GitHubConfiguration implements GitHubAppInstallationConfig {

private static final String CFG_APP_INSTALLATION = "github.appInstallation";

private final GitHubAppInstallationConfig appInstallation;

@Inject
public GitHubConfiguration(com.typesafe.config.Config config) {
if (config.hasPath(CFG_APP_INSTALLATION)) {
var raw = config.getConfig(CFG_APP_INSTALLATION);
this.appInstallation = GitHubAppInstallationConfig.fromConfig(raw);
} else {
this.appInstallation = GitHubAppInstallationConfig.builder()
.authConfigs(List.of())
.build();
}
}

@Override
public List<MappingAuthConfig> getAuthConfigs() {
return appInstallation.getAuthConfigs();
}

@Override
public Duration getSystemAuthCacheDuration() {
return appInstallation.getSystemAuthCacheDuration();
}

@Override
public long getSystemAuthCacheMaxWeight() {
return appInstallation.getSystemAuthCacheMaxWeight();
}

}
Loading