Skip to content

Commit

Permalink
feat(cloudfoundry): Migrate to kork-credentials (#4959)
Browse files Browse the repository at this point in the history
* feat(cloudfoundry): Migrate to kork-credentials

* feat(credentials): Remove AccountCredentialsProvider

* feat(credentials): Use proper exception and not nullable result

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
ncknt and mergify[bot] committed Sep 30, 2020
1 parent c9c9608 commit 19725e1
Show file tree
Hide file tree
Showing 19 changed files with 230 additions and 572 deletions.
1 change: 1 addition & 0 deletions clouddriver-cloudfoundry/clouddriver-cloudfoundry.gradle
Expand Up @@ -44,6 +44,7 @@ dependencies {
implementation "com.github.ben-manes.caffeine:guava"
implementation "com.netflix.frigga:frigga"
implementation "com.netflix.spinnaker.kork:kork-artifacts"
implementation "com.netflix.spinnaker.kork:kork-credentials"
implementation "com.netflix.spinnaker.kork:kork-annotations"
implementation "com.netflix.spinnaker.moniker:moniker"
implementation "com.netflix.spectator:spectator-api"
Expand Down
Expand Up @@ -16,6 +16,7 @@

package com.netflix.spinnaker.clouddriver.cloudfoundry.config;

import com.netflix.spinnaker.credentials.definition.CredentialsDefinition;
import com.netflix.spinnaker.fiat.model.resources.Permissions;
import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -52,7 +53,7 @@ public void destroy() {
@Getter
@Setter
@ToString(exclude = "password")
public static class ManagedAccount {
public static class ManagedAccount implements CredentialsDefinition {
private String name;
private String api;
private String appsManagerUri;
Expand Down
Expand Up @@ -19,12 +19,12 @@
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.CloudFoundryClient;
import com.netflix.spinnaker.clouddriver.cloudfoundry.model.CloudFoundrySpace;
import com.netflix.spinnaker.clouddriver.cloudfoundry.security.CloudFoundryCredentials;
import com.netflix.spinnaker.clouddriver.security.AbstractAtomicOperationsCredentialsSupport;
import com.netflix.spinnaker.clouddriver.security.AbstractAtomicOperationsCredentialsConverter;
import java.util.Map;
import java.util.Optional;

public abstract class AbstractCloudFoundryAtomicOperationConverter
extends AbstractAtomicOperationsCredentialsSupport {
extends AbstractAtomicOperationsCredentialsConverter<CloudFoundryCredentials> {

protected Optional<CloudFoundrySpace> findSpace(String region, CloudFoundryClient client) {
return client.getOrganizations().findSpaceByRegion(region);
Expand Down
Expand Up @@ -21,12 +21,10 @@
import static java.util.Collections.singletonMap;
import static java.util.stream.Collectors.toSet;

import com.netflix.spinnaker.cats.agent.Agent;
import com.netflix.spinnaker.cats.agent.AgentSchedulerAware;
import com.netflix.spinnaker.cats.cache.Cache;
import com.netflix.spinnaker.clouddriver.cache.SearchableProvider;
import com.netflix.spinnaker.clouddriver.cloudfoundry.cache.Keys;
import java.util.Collection;
import com.netflix.spinnaker.clouddriver.security.BaseProvider;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
Expand All @@ -36,7 +34,7 @@

@RequiredArgsConstructor
@Getter
public class CloudFoundryProvider extends AgentSchedulerAware implements SearchableProvider {
public class CloudFoundryProvider extends BaseProvider implements SearchableProvider {
private final Set<String> defaultCaches =
Stream.of(
APPLICATIONS.getNs(),
Expand All @@ -56,8 +54,6 @@ public class CloudFoundryProvider extends AgentSchedulerAware implements Searcha
public static final String PROVIDER_ID = "cloudfoundry";
private final String providerName = CloudFoundryProvider.class.getName();

private final Collection<Agent> agents;

static class ApplicationSearchResultHydrator implements SearchableProvider.SearchResultHydrator {
@Override
public Map<String, String> hydrateResult(
Expand Down
Expand Up @@ -16,55 +16,86 @@

package com.netflix.spinnaker.clouddriver.cloudfoundry.provider.config;

import com.netflix.spectator.api.Registry;
import com.netflix.spinnaker.clouddriver.cloudfoundry.cache.CacheRepository;
import com.netflix.spinnaker.clouddriver.cloudfoundry.config.CloudFoundryConfigurationProperties;
import com.netflix.spinnaker.clouddriver.cloudfoundry.provider.CloudFoundryProvider;
import com.netflix.spinnaker.clouddriver.cloudfoundry.provider.agent.CloudFoundryLoadBalancerCachingAgent;
import com.netflix.spinnaker.clouddriver.cloudfoundry.provider.agent.CloudFoundryServerGroupCachingAgent;
import com.netflix.spinnaker.clouddriver.cloudfoundry.provider.agent.CloudFoundrySpaceCachingAgent;
import com.netflix.spinnaker.clouddriver.cloudfoundry.security.CloudFoundryCredentials;
import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository;
import com.netflix.spinnaker.clouddriver.security.ProviderUtils;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import com.netflix.spinnaker.clouddriver.security.CredentialsInitializerSynchronizable;
import com.netflix.spinnaker.credentials.CredentialsLifecycleHandler;
import com.netflix.spinnaker.credentials.CredentialsRepository;
import com.netflix.spinnaker.credentials.MapBackedCredentialsRepository;
import com.netflix.spinnaker.credentials.definition.AbstractCredentialsLoader;
import com.netflix.spinnaker.credentials.definition.BasicCredentialsLoader;
import com.netflix.spinnaker.credentials.definition.CredentialsDefinitionSource;
import com.netflix.spinnaker.credentials.poller.Poller;
import javax.annotation.Nullable;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

@Configuration
public class CloudFoundryProviderConfig {

@Bean
@DependsOn("cloudFoundryAccountCredentials")
public CloudFoundryProvider cloudFoundryProvider(
AccountCredentialsRepository accountCredentialsRepository, Registry registry) {
CloudFoundryProvider provider =
new CloudFoundryProvider(Collections.newSetFromMap(new ConcurrentHashMap<>()));
synchronizeCloudFoundryProvider(provider, accountCredentialsRepository, registry);
return provider;
public CloudFoundryProvider cloudFoundryProvider() {
return new CloudFoundryProvider();
}

private void synchronizeCloudFoundryProvider(
CloudFoundryProvider cloudFoundryProvider,
AccountCredentialsRepository accountCredentialsRepository,
Registry registry) {
Set<String> scheduledAccounts = ProviderUtils.getScheduledAccounts(cloudFoundryProvider);
Set<CloudFoundryCredentials> allAccounts =
ProviderUtils.buildThreadSafeSetOfAccounts(
accountCredentialsRepository, CloudFoundryCredentials.class);
allAccounts.forEach(
credentials -> {
if (!scheduledAccounts.contains(credentials.getName())) {
cloudFoundryProvider
.getAgents()
.add(new CloudFoundryServerGroupCachingAgent(credentials, registry));
cloudFoundryProvider
.getAgents()
.add(new CloudFoundryLoadBalancerCachingAgent(credentials, registry));
cloudFoundryProvider
.getAgents()
.add(new CloudFoundrySpaceCachingAgent(credentials, registry));
}
});
@Bean
@ConditionalOnMissingBean(
value = CloudFoundryCredentials.class,
parameterizedContainer = AbstractCredentialsLoader.class)
public AbstractCredentialsLoader<CloudFoundryCredentials> cloudFoundryCredentialsLoader(
@Nullable
CredentialsDefinitionSource<CloudFoundryConfigurationProperties.ManagedAccount>
cloudFoundryCredentialSource,
CloudFoundryConfigurationProperties configurationProperties,
CacheRepository cacheRepository,
CredentialsRepository<CloudFoundryCredentials> cloudFoundryCredentialsRepository) {

if (cloudFoundryCredentialSource == null) {
cloudFoundryCredentialSource = configurationProperties::getAccounts;
}
return new BasicCredentialsLoader<>(
cloudFoundryCredentialSource,
a ->
new CloudFoundryCredentials(
a.getName(),
a.getAppsManagerUri(),
a.getMetricsUri(),
a.getApi(),
a.getUser(),
a.getPassword(),
a.getEnvironment(),
a.isSkipSslValidation(),
a.getResultsPerPage(),
a.getMaxCapiConnectionsForCache(),
cacheRepository,
a.getPermissions().build()),
cloudFoundryCredentialsRepository);
}

@Bean
@ConditionalOnMissingBean(
value = CloudFoundryCredentials.class,
parameterizedContainer = CredentialsRepository.class)
public CredentialsRepository<CloudFoundryCredentials> cloudFoundryCredentialsRepository(
CredentialsLifecycleHandler<CloudFoundryCredentials> eventHandler) {
return new MapBackedCredentialsRepository<>(CloudFoundryProvider.PROVIDER_ID, eventHandler);
}

@Bean
@ConditionalOnMissingBean(
value = CloudFoundryConfigurationProperties.ManagedAccount.class,
parameterizedContainer = CredentialsDefinitionSource.class)
public CredentialsInitializerSynchronizable cloudFoundryCredentialsInitializerSynchronizable(
AbstractCredentialsLoader<CloudFoundryCredentials> loader) {
final Poller<CloudFoundryCredentials> poller = new Poller<>(loader);
return new CredentialsInitializerSynchronizable() {
@Override
public void synchronize() {
poller.run();
}
};
}
}
Expand Up @@ -25,8 +25,7 @@
import com.netflix.spinnaker.clouddriver.cloudfoundry.model.CloudFoundryInstance;
import com.netflix.spinnaker.clouddriver.cloudfoundry.security.CloudFoundryCredentials;
import com.netflix.spinnaker.clouddriver.model.InstanceProvider;
import com.netflix.spinnaker.clouddriver.security.AccountCredentials;
import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider;
import com.netflix.spinnaker.credentials.CredentialsRepository;
import javax.annotation.Nullable;
import lombok.Data;
import lombok.RequiredArgsConstructor;
Expand All @@ -38,7 +37,7 @@ public class CloudFoundryInstanceProvider
implements InstanceProvider<CloudFoundryInstance, String> {

private final CacheRepository repository;
private final AccountCredentialsProvider accountCredentialsProvider;
private final CredentialsRepository<CloudFoundryCredentials> credentialsRepository;

@Nullable
@Override
Expand All @@ -48,11 +47,11 @@ public CloudFoundryInstance getInstance(String account, String region, String id

@Override
public String getConsoleOutput(String account, String region, String id) {
AccountCredentials credentials = accountCredentialsProvider.getCredentials(account);
if (!(credentials instanceof CloudFoundryCredentials)) {
CloudFoundryCredentials credentials = credentialsRepository.getOne(account);
if (credentials == null) {
return null;
}
final CloudFoundryClient client = ((CloudFoundryCredentials) credentials).getClient();
final CloudFoundryClient client = credentials.getClient();
final Logs logsService = client.getLogs();

final CloudFoundryConsoleOutputIdParameter idParam =
Expand Down
Expand Up @@ -22,8 +22,7 @@
import com.netflix.spinnaker.clouddriver.cloudfoundry.model.CloudFoundryJobStatus;
import com.netflix.spinnaker.clouddriver.cloudfoundry.security.CloudFoundryCredentials;
import com.netflix.spinnaker.clouddriver.model.JobProvider;
import com.netflix.spinnaker.clouddriver.security.AccountCredentials;
import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider;
import com.netflix.spinnaker.credentials.CredentialsRepository;
import java.util.Map;
import lombok.Getter;
import org.springframework.stereotype.Component;
Expand All @@ -32,20 +31,21 @@
public class CloudFoundryJobProvider implements JobProvider<CloudFoundryJobStatus> {

@Getter private String platform = CloudFoundryCloudProvider.ID;
private final AccountCredentialsProvider accountCredentialsProvider;
private final CredentialsRepository<CloudFoundryCredentials> credentialsRepository;

public CloudFoundryJobProvider(AccountCredentialsProvider accountCredentialsProvider) {
this.accountCredentialsProvider = accountCredentialsProvider;
public CloudFoundryJobProvider(
CredentialsRepository<CloudFoundryCredentials> credentialsRepository) {
this.credentialsRepository = credentialsRepository;
}

@Override
public CloudFoundryJobStatus collectJob(String account, String location, String id) {
AccountCredentials credentials = accountCredentialsProvider.getCredentials(account);
if (!(credentials instanceof CloudFoundryCredentials)) {
CloudFoundryCredentials credentials = credentialsRepository.getOne(account);
if (credentials == null) {
return null;
}

Task task = ((CloudFoundryCredentials) credentials).getClient().getTasks().getTask(id);
Task task = credentials.getClient().getTasks().getTask(id);
return CloudFoundryJobStatus.fromTask(task, account, location);
}

Expand All @@ -57,11 +57,10 @@ public Map<String, Object> getFileContents(

@Override
public void cancelJob(String account, String location, String taskGuid) {
AccountCredentials credentials = accountCredentialsProvider.getCredentials(account);
if (!(credentials instanceof CloudFoundryCredentials)) {
CloudFoundryCredentials credentials = credentialsRepository.getOne(account);
if (credentials == null) {
return;
}

((CloudFoundryCredentials) credentials).getClient().getTasks().cancelTask(taskGuid);
credentials.getClient().getTasks().cancelTask(taskGuid);
}
}
Expand Up @@ -21,32 +21,40 @@
import com.netflix.spinnaker.clouddriver.cloudfoundry.security.CloudFoundryCredentials;
import com.netflix.spinnaker.clouddriver.model.ServiceInstance;
import com.netflix.spinnaker.clouddriver.model.ServiceProvider;
import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider;
import com.netflix.spinnaker.credentials.CredentialsRepository;
import java.util.Collection;
import java.util.Collections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class CloudFoundryServiceProvider implements ServiceProvider {
private final AccountCredentialsProvider accountCredentialsProvider;
private final CredentialsRepository<CloudFoundryCredentials> credentialsRepository;

@Autowired
public CloudFoundryServiceProvider(AccountCredentialsProvider accountCredentialsProvider) {
this.accountCredentialsProvider = accountCredentialsProvider;
public CloudFoundryServiceProvider(
CredentialsRepository<CloudFoundryCredentials> credentialsRepository) {
this.credentialsRepository = credentialsRepository;
}

@Override
public Collection<CloudFoundryService> getServices(String account, String region) {
CloudFoundryCredentials credentials =
(CloudFoundryCredentials) accountCredentialsProvider.getCredentials(account);
CloudFoundryCredentials credentials = credentialsRepository.getOne(account);
if (credentials == null) {
return Collections.emptyList();
}

return credentials.getCredentials().getServiceInstances().findAllServicesByRegion(region);
}

@Override
public ServiceInstance getServiceInstance(
String account, String region, String serviceInstanceName) {
CloudFoundryCredentials credentials =
(CloudFoundryCredentials) accountCredentialsProvider.getCredentials(account);
CloudFoundryCredentials credentials = credentialsRepository.getOne(account);
if (credentials == null) {
return null;
}

return credentials
.getCredentials()
.getServiceInstances()
Expand Down

0 comments on commit 19725e1

Please sign in to comment.