diff --git a/clouddriver-api/src/main/java/com/netflix/spinnaker/cats/agent/AgentProvider.java b/clouddriver-api/src/main/java/com/netflix/spinnaker/cats/agent/AgentProvider.java index 80878bf2bc7..a2215136493 100644 --- a/clouddriver-api/src/main/java/com/netflix/spinnaker/cats/agent/AgentProvider.java +++ b/clouddriver-api/src/main/java/com/netflix/spinnaker/cats/agent/AgentProvider.java @@ -16,6 +16,7 @@ package com.netflix.spinnaker.cats.agent; +import com.netflix.spinnaker.credentials.Credentials; import com.netflix.spinnaker.kork.annotations.Beta; import java.util.Collection; @@ -23,5 +24,5 @@ public interface AgentProvider { boolean supports(String providerName); - Collection agents(); + Collection agents(Credentials credentials); } diff --git a/clouddriver-aws/clouddriver-aws.gradle b/clouddriver-aws/clouddriver-aws.gradle index b88927a5f87..0ebbce53444 100644 --- a/clouddriver-aws/clouddriver-aws.gradle +++ b/clouddriver-aws/clouddriver-aws.gradle @@ -21,6 +21,7 @@ dependencies { implementation "com.netflix.spinnaker.kork:kork-aws" implementation "com.netflix.spinnaker.kork:kork-exceptions" implementation "com.netflix.spinnaker.kork:kork-security" + implementation "com.netflix.spinnaker.kork:kork-credentials" implementation "com.netflix.spinnaker.moniker:moniker" implementation "com.squareup.okhttp:okhttp" implementation "com.squareup.okhttp:okhttp-apache" diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/agent/CleanupAlarmsAgent.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/agent/CleanupAlarmsAgent.groovy index d8a0caf35a5..dcd2511ac9d 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/agent/CleanupAlarmsAgent.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/agent/CleanupAlarmsAgent.groovy @@ -29,8 +29,8 @@ import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider import com.netflix.spinnaker.clouddriver.aws.security.AmazonCredentials import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials import com.netflix.spinnaker.clouddriver.cache.CustomScheduledAgent -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository import com.netflix.spinnaker.clouddriver.security.ProviderUtils +import com.netflix.spinnaker.credentials.CredentialsRepository import groovy.util.logging.Slf4j import org.joda.time.DateTime @@ -45,20 +45,20 @@ class CleanupAlarmsAgent implements RunnableAgent, CustomScheduledAgent { public static final Pattern ALARM_NAME_PATTERN = Pattern.compile(".+-v[0-9]{3}-alarm-.+") final AmazonClientProvider amazonClientProvider - final AccountCredentialsRepository accountCredentialsRepository + final CredentialsRepository accountCredentialsRepository final long pollIntervalMillis final long timeoutMillis final int daysToLeave CleanupAlarmsAgent(AmazonClientProvider amazonClientProvider, - AccountCredentialsRepository accountCredentialsRepository, + CredentialsRepository accountCredentialsRepository, int daysToLeave) { this(amazonClientProvider, accountCredentialsRepository, POLL_INTERVAL_MILLIS, DEFAULT_TIMEOUT_MILLIS, daysToLeave) } CleanupAlarmsAgent(AmazonClientProvider amazonClientProvider, - AccountCredentialsRepository accountCredentialsRepository, + CredentialsRepository accountCredentialsRepository, long pollIntervalMillis, long timeoutMills, int daysToLeave) { @@ -120,7 +120,7 @@ class CleanupAlarmsAgent implements RunnableAgent, CustomScheduledAgent { } private Set getAccounts() { - ProviderUtils.buildThreadSafeSetOfAccounts(accountCredentialsRepository, NetflixAmazonCredentials, AmazonCloudProvider.ID) + return accountCredentialsRepository.getAll() } private static Set getAttachedAlarms(AmazonAutoScaling autoScaling) { diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/agent/CleanupDetachedInstancesAgent.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/agent/CleanupDetachedInstancesAgent.groovy index c6bdb4176d6..2b2281c1717 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/agent/CleanupDetachedInstancesAgent.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/agent/CleanupDetachedInstancesAgent.groovy @@ -28,8 +28,8 @@ import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials import com.netflix.spinnaker.clouddriver.cache.CustomScheduledAgent import com.netflix.spinnaker.clouddriver.aws.deploy.ops.DetachInstancesAtomicOperation import com.netflix.spinnaker.clouddriver.aws.provider.AwsCleanupProvider -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository import com.netflix.spinnaker.clouddriver.security.ProviderUtils +import com.netflix.spinnaker.credentials.CredentialsRepository import groovy.util.logging.Slf4j import java.util.concurrent.TimeUnit @@ -40,17 +40,17 @@ class CleanupDetachedInstancesAgent implements RunnableAgent, CustomScheduledAge public static final long DEFAULT_TIMEOUT_MILLIS = TimeUnit.MINUTES.toMillis(20) final AmazonClientProvider amazonClientProvider - final AccountCredentialsRepository accountCredentialsRepository + final CredentialsRepository accountCredentialsRepository final long pollIntervalMillis final long timeoutMillis CleanupDetachedInstancesAgent(AmazonClientProvider amazonClientProvider, - AccountCredentialsRepository accountCredentialsRepository) { + CredentialsRepository accountCredentialsRepository) { this(amazonClientProvider, accountCredentialsRepository, DEFAULT_POLL_INTERVAL_MILLIS, DEFAULT_TIMEOUT_MILLIS) } CleanupDetachedInstancesAgent(AmazonClientProvider amazonClientProvider, - AccountCredentialsRepository accountCredentialsRepository, + CredentialsRepository accountCredentialsRepository, long pollIntervalMillis, long timeoutMills) { this.amazonClientProvider = amazonClientProvider @@ -108,7 +108,7 @@ class CleanupDetachedInstancesAgent implements RunnableAgent, CustomScheduledAge } private Set getAccounts() { - ProviderUtils.buildThreadSafeSetOfAccounts(accountCredentialsRepository, NetflixAmazonCredentials, AmazonCloudProvider.ID) + return accountCredentialsRepository.getAll() } /** diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/controllers/AmazonClusterController.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/controllers/AmazonClusterController.groovy index 4c5c6dcc7ee..aa0ffee5399 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/controllers/AmazonClusterController.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/controllers/AmazonClusterController.groovy @@ -20,7 +20,7 @@ import com.amazonaws.services.autoscaling.model.Activity import com.amazonaws.services.autoscaling.model.DescribeScalingActivitiesRequest import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider +import com.netflix.spinnaker.credentials.CredentialsRepository import org.springframework.beans.factory.annotation.Autowired import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity @@ -31,7 +31,7 @@ import org.springframework.web.bind.annotation.* class AmazonClusterController { @Autowired - AccountCredentialsProvider accountCredentialsProvider + CredentialsRepository credentialsRepository @Autowired AmazonClientProvider amazonClientProvider @@ -40,8 +40,8 @@ class AmazonClusterController { @RequestMapping(value = "/scalingActivities", method = RequestMethod.GET) ResponseEntity getScalingActivities(@PathVariable String account, @PathVariable String serverGroupName, @RequestParam(value = "region", required = true) String region) { - def credentials = accountCredentialsProvider.getCredentials(account) - if (!(credentials instanceof NetflixAmazonCredentials)) { + def credentials = credentialsRepository.getOne(account) + if (credentials == null) { return new ResponseEntity([message: "bad credentials"], HttpStatus.BAD_REQUEST) } def autoScaling = amazonClientProvider.getAutoScaling(credentials, region) diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/handlers/BasicAmazonDeployHandler.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/handlers/BasicAmazonDeployHandler.groovy index 137d9c0262a..0c6a4bb59d7 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/handlers/BasicAmazonDeployHandler.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/handlers/BasicAmazonDeployHandler.groovy @@ -46,7 +46,7 @@ import com.netflix.spinnaker.clouddriver.deploy.DeployDescription import com.netflix.spinnaker.clouddriver.deploy.DeployHandler import com.netflix.spinnaker.clouddriver.deploy.DeploymentResult import com.netflix.spinnaker.clouddriver.orchestration.events.CreateServerGroupEvent -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository +import com.netflix.spinnaker.credentials.CredentialsRepository import com.netflix.spinnaker.kork.dynamicconfig.DynamicConfigService import groovy.transform.PackageScope import groovy.util.logging.Slf4j @@ -74,7 +74,7 @@ class BasicAmazonDeployHandler implements DeployHandler accountCredentialsRepository private final AwsConfiguration.AmazonServerGroupProvider amazonServerGroupProvider private final AwsConfiguration.DeployDefaults deployDefaults private final ScalingPolicyCopier scalingPolicyCopier @@ -84,7 +84,7 @@ class BasicAmazonDeployHandler implements DeployHandler deployEvents = [] BasicAmazonDeployHandler(RegionScopedProviderFactory regionScopedProviderFactory, - AccountCredentialsRepository accountCredentialsRepository, + CredentialsRepository accountCredentialsRepository, AwsConfiguration.AmazonServerGroupProvider amazonServerGroupProvider, AwsConfiguration.DeployDefaults deployDefaults, ScalingPolicyCopier scalingPolicyCopier, diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/AllowLaunchAtomicOperation.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/AllowLaunchAtomicOperation.groovy index 0801fb4c3b8..50e70c55c18 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/AllowLaunchAtomicOperation.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/AllowLaunchAtomicOperation.groovy @@ -18,6 +18,10 @@ package com.netflix.spinnaker.clouddriver.aws.deploy.ops import com.amazonaws.services.ec2.AmazonEC2 import com.amazonaws.services.ec2.model.* +import com.netflix.spinnaker.clouddriver.aws.deploy.AmiIdResolver +import com.netflix.spinnaker.clouddriver.aws.deploy.ResolvedAmiResult +import com.netflix.spinnaker.clouddriver.aws.deploy.description.AllowLaunchDescription +import com.netflix.spinnaker.clouddriver.aws.model.AwsResultsRetriever import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider import com.netflix.spinnaker.clouddriver.aws.security.AmazonCredentials import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials @@ -25,11 +29,7 @@ import com.netflix.spinnaker.clouddriver.data.task.Task import com.netflix.spinnaker.clouddriver.data.task.TaskRepository import com.netflix.spinnaker.clouddriver.helpers.OperationPoller import com.netflix.spinnaker.clouddriver.orchestration.AtomicOperation -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider -import com.netflix.spinnaker.clouddriver.aws.deploy.AmiIdResolver -import com.netflix.spinnaker.clouddriver.aws.deploy.ResolvedAmiResult -import com.netflix.spinnaker.clouddriver.aws.deploy.description.AllowLaunchDescription -import com.netflix.spinnaker.clouddriver.aws.model.AwsResultsRetriever +import com.netflix.spinnaker.credentials.CredentialsRepository import com.netflix.spinnaker.kork.core.RetrySupport import groovy.transform.Canonical import org.springframework.beans.factory.annotation.Autowired @@ -51,14 +51,14 @@ class AllowLaunchAtomicOperation implements AtomicOperation { AmazonClientProvider amazonClientProvider @Autowired - AccountCredentialsProvider accountCredentialsProvider + CredentialsRepository credentialsRepository @Override ResolvedAmiResult operate(List priorOutputs) { task.updateStatus BASE_PHASE, "Initializing Allow Launch Operation..." def sourceCredentials = description.credentials - def targetCredentials = accountCredentialsProvider.getCredentials(description.targetAccount) as NetflixAmazonCredentials + def targetCredentials = credentialsRepository.getOne(description.targetAccount) as NetflixAmazonCredentials def sourceAmazonEC2 = amazonClientProvider.getAmazonEC2(description.credentials, description.region, true) def targetAmazonEC2 = amazonClientProvider.getAmazonEC2(targetCredentials, description.region, true) @@ -83,7 +83,7 @@ class AllowLaunchAtomicOperation implements AtomicOperation { // Spinnaker, switch to using that for modifying the image if (resolvedAmi.ownerId != sourceCredentials.accountId) { if (resolvedAmi.getRegion()) { - ownerCredentials = accountCredentialsProvider.all.find { accountCredentials -> + ownerCredentials = credentialsRepository.getAll().find { accountCredentials -> accountCredentials instanceof NetflixAmazonCredentials && ((AmazonCredentials) accountCredentials).accountId == resolvedAmi.ownerId } as NetflixAmazonCredentials diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/CopyLastAsgAtomicOperation.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/CopyLastAsgAtomicOperation.groovy index 1be231cdeb1..38bee339e81 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/CopyLastAsgAtomicOperation.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/CopyLastAsgAtomicOperation.groovy @@ -15,6 +15,7 @@ */ package com.netflix.spinnaker.clouddriver.aws.deploy.ops + import com.amazonaws.services.autoscaling.model.AutoScalingGroup import com.amazonaws.services.autoscaling.model.DescribeAutoScalingGroupsRequest import com.amazonaws.services.ec2.model.DescribeSubnetsRequest @@ -22,21 +23,21 @@ import com.amazonaws.services.ec2.model.LaunchTemplateVersion import com.amazonaws.services.elasticloadbalancingv2.model.DescribeTargetGroupsRequest import com.netflix.frigga.Names import com.netflix.frigga.autoscaling.AutoScalingGroupNameBuilder +import com.netflix.spinnaker.clouddriver.aws.deploy.description.BasicAmazonDeployDescription +import com.netflix.spinnaker.clouddriver.aws.deploy.handlers.BasicAmazonDeployHandler import com.netflix.spinnaker.clouddriver.aws.deploy.userdata.LocalFileUserDataProperties import com.netflix.spinnaker.clouddriver.aws.deploy.validators.BasicAmazonDeployDescriptionValidator +import com.netflix.spinnaker.clouddriver.aws.model.SubnetData import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials +import com.netflix.spinnaker.clouddriver.aws.services.RegionScopedProviderFactory import com.netflix.spinnaker.clouddriver.data.task.Task import com.netflix.spinnaker.clouddriver.data.task.TaskRepository import com.netflix.spinnaker.clouddriver.deploy.DeploymentResult import com.netflix.spinnaker.clouddriver.deploy.DescriptionValidationErrors import com.netflix.spinnaker.clouddriver.deploy.DescriptionValidationException import com.netflix.spinnaker.clouddriver.orchestration.AtomicOperation -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider -import com.netflix.spinnaker.clouddriver.aws.deploy.description.BasicAmazonDeployDescription -import com.netflix.spinnaker.clouddriver.aws.deploy.handlers.BasicAmazonDeployHandler -import com.netflix.spinnaker.clouddriver.aws.model.SubnetData -import com.netflix.spinnaker.clouddriver.aws.services.RegionScopedProviderFactory +import com.netflix.spinnaker.credentials.CredentialsRepository import org.springframework.beans.factory.annotation.Autowired class CopyLastAsgAtomicOperation implements AtomicOperation { @@ -56,7 +57,7 @@ class CopyLastAsgAtomicOperation implements AtomicOperation { AmazonClientProvider amazonClientProvider @Autowired - AccountCredentialsProvider accountCredentialsProvider + CredentialsRepository credentialsRepository @Autowired RegionScopedProviderFactory regionScopedProviderFactory @@ -90,7 +91,7 @@ class CopyLastAsgAtomicOperation implements AtomicOperation { def sourceAsgCredentials if (description.source.account && description.source.region && description.source.asgName) { sourceRegion = description.source.region - sourceAsgCredentials = accountCredentialsProvider.getCredentials(description.source.account) as NetflixAmazonCredentials + sourceAsgCredentials = credentialsRepository.getOne(description.source.account) as NetflixAmazonCredentials def sourceAutoScaling = amazonClientProvider.getAutoScaling(sourceAsgCredentials, sourceRegion, true) def request = new DescribeAutoScalingGroupsRequest(autoScalingGroupNames: [description.source.asgName]) List ancestorAsgs = sourceAutoScaling.describeAutoScalingGroups(request).autoScalingGroups diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/actions/ModifyServerGroupLaunchTemplate.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/actions/ModifyServerGroupLaunchTemplate.java index 07ad6a78068..9ad5fcc4dd9 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/actions/ModifyServerGroupLaunchTemplate.java +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/actions/ModifyServerGroupLaunchTemplate.java @@ -33,7 +33,7 @@ import com.netflix.spinnaker.clouddriver.saga.SagaCommand; import com.netflix.spinnaker.clouddriver.saga.flow.SagaAction; import com.netflix.spinnaker.clouddriver.saga.models.Saga; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository; +import com.netflix.spinnaker.credentials.CredentialsRepository; import java.util.Collections; import javax.annotation.Nonnull; import lombok.Builder; @@ -46,12 +46,12 @@ public class ModifyServerGroupLaunchTemplate implements SagaAction { private final BlockDeviceConfig blockDeviceConfig; - private final AccountCredentialsRepository credentialsRepository; + private final CredentialsRepository credentialsRepository; private final RegionScopedProviderFactory regionScopedProviderFactory; public ModifyServerGroupLaunchTemplate( BlockDeviceConfig blockDeviceConfig, - AccountCredentialsRepository credentialsRepository, + CredentialsRepository credentialsRepository, RegionScopedProviderFactory regionScopedProviderFactory) { this.blockDeviceConfig = blockDeviceConfig; this.credentialsRepository = credentialsRepository; diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/actions/PrepareModifyServerGroupLaunchTemplate.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/actions/PrepareModifyServerGroupLaunchTemplate.java index 86c1a858439..cd0861a60f3 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/actions/PrepareModifyServerGroupLaunchTemplate.java +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/actions/PrepareModifyServerGroupLaunchTemplate.java @@ -20,7 +20,11 @@ import com.amazonaws.services.autoscaling.model.AutoScalingGroup; import com.amazonaws.services.autoscaling.model.LaunchTemplateSpecification; import com.amazonaws.services.ec2.AmazonEC2; -import com.amazonaws.services.ec2.model.*; +import com.amazonaws.services.ec2.model.LaunchTemplateBlockDeviceMapping; +import com.amazonaws.services.ec2.model.LaunchTemplateIamInstanceProfileSpecification; +import com.amazonaws.services.ec2.model.LaunchTemplateInstanceMarketOptions; +import com.amazonaws.services.ec2.model.LaunchTemplateVersion; +import com.amazonaws.services.ec2.model.ResponseLaunchTemplateData; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; @@ -37,7 +41,7 @@ import com.netflix.spinnaker.clouddriver.saga.SagaCommand; import com.netflix.spinnaker.clouddriver.saga.flow.SagaAction; import com.netflix.spinnaker.clouddriver.saga.models.Saga; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository; +import com.netflix.spinnaker.credentials.CredentialsRepository; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -57,12 +61,12 @@ public class PrepareModifyServerGroupLaunchTemplate implements SagaAction< PrepareModifyServerGroupLaunchTemplate.PrepareModifyServerGroupLaunchTemplateCommand> { private final BlockDeviceConfig blockDeviceConfig; - private final AccountCredentialsRepository credentialsRepository; + private final CredentialsRepository credentialsRepository; private final RegionScopedProviderFactory regionScopedProviderFactory; public PrepareModifyServerGroupLaunchTemplate( BlockDeviceConfig blockDeviceConfig, - AccountCredentialsRepository credentialsRepository, + CredentialsRepository credentialsRepository, RegionScopedProviderFactory regionScopedProviderFactory) { this.blockDeviceConfig = blockDeviceConfig; this.credentialsRepository = credentialsRepository; diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/actions/UpdateAutoScalingGroup.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/actions/UpdateAutoScalingGroup.java index 63bccb51529..272bea7a532 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/actions/UpdateAutoScalingGroup.java +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/actions/UpdateAutoScalingGroup.java @@ -30,7 +30,7 @@ import com.netflix.spinnaker.clouddriver.saga.SagaCommand; import com.netflix.spinnaker.clouddriver.saga.flow.SagaAction; import com.netflix.spinnaker.clouddriver.saga.models.Saga; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository; +import com.netflix.spinnaker.credentials.CredentialsRepository; import javax.annotation.Nonnull; import lombok.Builder; import lombok.Value; @@ -42,11 +42,11 @@ public class UpdateAutoScalingGroup implements SagaAction { private final RegionScopedProviderFactory regionScopedProviderFactory; - private final AccountCredentialsRepository credentialsRepository; + private final CredentialsRepository credentialsRepository; public UpdateAutoScalingGroup( RegionScopedProviderFactory regionScopedProviderFactory, - AccountCredentialsRepository credentialsRepository) { + CredentialsRepository credentialsRepository) { this.regionScopedProviderFactory = regionScopedProviderFactory; this.credentialsRepository = credentialsRepository; } diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/securitygroup/SecurityGroupLookupFactory.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/securitygroup/SecurityGroupLookupFactory.groovy index c1c91184369..740a29d50a4 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/securitygroup/SecurityGroupLookupFactory.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/securitygroup/SecurityGroupLookupFactory.groovy @@ -17,25 +17,12 @@ package com.netflix.spinnaker.clouddriver.aws.deploy.ops.securitygroup import com.amazonaws.services.ec2.AmazonEC2 -import com.amazonaws.services.ec2.model.AuthorizeSecurityGroupIngressRequest -import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest -import com.amazonaws.services.ec2.model.CreateTagsRequest -import com.amazonaws.services.ec2.model.DeleteTagsRequest -import com.amazonaws.services.ec2.model.DescribeSecurityGroupsRequest -import com.amazonaws.services.ec2.model.DescribeTagsRequest -import com.amazonaws.services.ec2.model.Filter -import com.amazonaws.services.ec2.model.IpPermission -import com.amazonaws.services.ec2.model.RevokeSecurityGroupIngressRequest -import com.amazonaws.services.ec2.model.SecurityGroup -import com.amazonaws.services.ec2.model.Tag -import com.amazonaws.services.ec2.model.DescribeTagsResult -import com.amazonaws.services.ec2.model.TagDescription -import com.amazonaws.services.ec2.model.UpdateSecurityGroupRuleDescriptionsIngressRequest +import com.amazonaws.services.ec2.model.* import com.google.common.collect.ImmutableSet import com.netflix.spinnaker.clouddriver.aws.deploy.description.UpsertSecurityGroupDescription import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository +import com.netflix.spinnaker.credentials.CredentialsRepository import com.netflix.spinnaker.kork.core.RetrySupport import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -43,10 +30,10 @@ import org.slf4j.LoggerFactory class SecurityGroupLookupFactory { private final AmazonClientProvider amazonClientProvider - private final AccountCredentialsRepository accountCredentialsRepository + private final CredentialsRepository accountCredentialsRepository SecurityGroupLookupFactory(AmazonClientProvider amazonClientProvider, - AccountCredentialsRepository accountCredentialsRepository) { + CredentialsRepository accountCredentialsRepository) { this.amazonClientProvider = amazonClientProvider this.accountCredentialsRepository = accountCredentialsRepository } diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/AllowLaunchDescriptionValidator.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/AllowLaunchDescriptionValidator.groovy index 6e0cf95d3ef..81c760832cc 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/AllowLaunchDescriptionValidator.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/AllowLaunchDescriptionValidator.groovy @@ -16,17 +16,18 @@ package com.netflix.spinnaker.clouddriver.aws.deploy.validators +import com.netflix.spinnaker.clouddriver.aws.deploy.description.AllowLaunchDescription +import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials import com.netflix.spinnaker.clouddriver.deploy.DescriptionValidator import com.netflix.spinnaker.clouddriver.deploy.ValidationErrors -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider -import com.netflix.spinnaker.clouddriver.aws.deploy.description.AllowLaunchDescription +import com.netflix.spinnaker.credentials.CredentialsRepository import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component @Component("allowLaunchDescriptionValidator") class AllowLaunchDescriptionValidator extends DescriptionValidator { @Autowired - AccountCredentialsProvider accountCredentialsProvider + CredentialsRepository credentialsRepository @Override void validate(List priorDescriptions, AllowLaunchDescription description, ValidationErrors errors) { @@ -38,7 +39,7 @@ class AllowLaunchDescriptionValidator extends DescriptionValidator { @Autowired - AccountCredentialsProvider accountCredentialsProvider + CredentialsRepository credentialsRepository @Override void validate(List priorDescriptions, BasicAmazonDeployDescription description, ValidationErrors errors) { @@ -41,7 +42,7 @@ class BasicAmazonDeployDescriptionValidator extends AmazonDescriptionValidationS if (!description.credentials) { errors.rejectValue "credentials", "basicAmazonDeployDescription.credentials.empty" } else { - credentials = accountCredentialsProvider.getCredentials(description?.credentials?.name) + credentials = credentialsRepository.getOne(description?.credentials?.name) if (!(credentials instanceof AmazonCredentials)) { errors.rejectValue("credentials", "basicAmazonDeployDescription.credentials.invalid") } diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/DeleteAmazonLoadBalancerDescriptionValidator.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/DeleteAmazonLoadBalancerDescriptionValidator.groovy index 49745cd08f6..8f00ade0e46 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/DeleteAmazonLoadBalancerDescriptionValidator.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/DeleteAmazonLoadBalancerDescriptionValidator.groovy @@ -17,9 +17,9 @@ package com.netflix.spinnaker.clouddriver.aws.deploy.validators import com.netflix.spinnaker.clouddriver.aws.AmazonOperation +import com.netflix.spinnaker.clouddriver.aws.deploy.description.DeleteAmazonLoadBalancerDescription import com.netflix.spinnaker.clouddriver.deploy.ValidationErrors import com.netflix.spinnaker.clouddriver.orchestration.AtomicOperations -import com.netflix.spinnaker.clouddriver.aws.deploy.description.DeleteAmazonLoadBalancerDescription import org.springframework.stereotype.Component @AmazonOperation(AtomicOperations.DELETE_LOAD_BALANCER) diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/DeleteAmazonSnapshotDescriptionValidator.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/DeleteAmazonSnapshotDescriptionValidator.java index 91b906342c1..adffabc1e1a 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/DeleteAmazonSnapshotDescriptionValidator.java +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/DeleteAmazonSnapshotDescriptionValidator.java @@ -20,9 +20,10 @@ import com.netflix.spinnaker.clouddriver.aws.AmazonOperation; import com.netflix.spinnaker.clouddriver.aws.deploy.description.DeleteAmazonSnapshotDescription; +import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials; import com.netflix.spinnaker.clouddriver.deploy.ValidationErrors; import com.netflix.spinnaker.clouddriver.orchestration.AtomicOperations; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider; +import com.netflix.spinnaker.credentials.CredentialsRepository; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -32,12 +33,12 @@ public class DeleteAmazonSnapshotDescriptionValidator extends AmazonDescriptionValidationSupport { - AccountCredentialsProvider accountCredentialsProvider; + CredentialsRepository credentialsRepository; @Autowired public DeleteAmazonSnapshotDescriptionValidator( - AccountCredentialsProvider accountCredentialsProvider) { - this.accountCredentialsProvider = accountCredentialsProvider; + CredentialsRepository credentialsRepository) { + this.credentialsRepository = credentialsRepository; } @Override diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/DeleteSecurityGroupDescriptionValidator.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/DeleteSecurityGroupDescriptionValidator.groovy index da49aa485b7..2e48570635e 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/DeleteSecurityGroupDescriptionValidator.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/DeleteSecurityGroupDescriptionValidator.groovy @@ -17,10 +17,10 @@ package com.netflix.spinnaker.clouddriver.aws.deploy.validators import com.netflix.spinnaker.clouddriver.aws.AmazonOperation +import com.netflix.spinnaker.clouddriver.aws.deploy.description.DeleteSecurityGroupDescription import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider import com.netflix.spinnaker.clouddriver.deploy.ValidationErrors import com.netflix.spinnaker.clouddriver.orchestration.AtomicOperations -import com.netflix.spinnaker.clouddriver.aws.deploy.description.DeleteSecurityGroupDescription import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/ModifyAsgLaunchConfigurationDescriptionValidator.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/ModifyAsgLaunchConfigurationDescriptionValidator.groovy index 84bdb717ef9..06aab84ca5e 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/ModifyAsgLaunchConfigurationDescriptionValidator.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/ModifyAsgLaunchConfigurationDescriptionValidator.groovy @@ -17,12 +17,13 @@ package com.netflix.spinnaker.clouddriver.aws.deploy.validators import com.netflix.spinnaker.clouddriver.aws.AmazonOperation +import com.netflix.spinnaker.clouddriver.aws.deploy.description.ModifyAsgLaunchConfigurationDescription +import com.netflix.spinnaker.clouddriver.aws.model.AmazonBlockDevice import com.netflix.spinnaker.clouddriver.aws.security.AmazonCredentials +import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials import com.netflix.spinnaker.clouddriver.deploy.ValidationErrors import com.netflix.spinnaker.clouddriver.orchestration.AtomicOperations -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider -import com.netflix.spinnaker.clouddriver.aws.deploy.description.ModifyAsgLaunchConfigurationDescription -import com.netflix.spinnaker.clouddriver.aws.model.AmazonBlockDevice +import com.netflix.spinnaker.credentials.CredentialsRepository import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component @@ -30,7 +31,7 @@ import org.springframework.stereotype.Component @Component("modifyAsgLaunchConfigurationDescriptionValidator") class ModifyAsgLaunchConfigurationDescriptionValidator extends AmazonDescriptionValidationSupport { @Autowired - AccountCredentialsProvider accountCredentialsProvider + CredentialsRepository credentialsRepository @Override void validate(List priorDescriptions, ModifyAsgLaunchConfigurationDescription description, ValidationErrors errors) { @@ -40,7 +41,7 @@ class ModifyAsgLaunchConfigurationDescriptionValidator extends AmazonDescription if (!description.credentials) { errors.rejectValue "credentials", "modifyAsgLaunchConfigurationDescription.credentials.empty" } else { - def credentials = accountCredentialsProvider.getCredentials(description?.credentials?.name) + def credentials = credentialsRepository.getOne(description?.credentials?.name) if (!(credentials instanceof AmazonCredentials)) { errors.rejectValue("credentials", "modifyAsgLaunchConfigurationDescription.credentials.invalid") } diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/ModifyServerGroupLaunchTemplateValidator.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/ModifyServerGroupLaunchTemplateValidator.java index 32c697fb0bd..bc011520cab 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/ModifyServerGroupLaunchTemplateValidator.java +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/ModifyServerGroupLaunchTemplateValidator.java @@ -20,11 +20,11 @@ import com.netflix.spinnaker.clouddriver.aws.AmazonOperation; import com.netflix.spinnaker.clouddriver.aws.deploy.description.ModifyServerGroupLaunchTemplateDescription; import com.netflix.spinnaker.clouddriver.aws.model.AmazonBlockDevice; -import com.netflix.spinnaker.clouddriver.aws.security.AmazonCredentials; +import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials; import com.netflix.spinnaker.clouddriver.deploy.ValidationErrors; import com.netflix.spinnaker.clouddriver.orchestration.AtomicOperations; import com.netflix.spinnaker.clouddriver.security.AccountCredentials; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider; +import com.netflix.spinnaker.credentials.CredentialsRepository; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -33,12 +33,12 @@ @Component("modifyServerGroupLaunchTemplateDescriptionValidator") public class ModifyServerGroupLaunchTemplateValidator extends AmazonDescriptionValidationSupport { - private final AccountCredentialsProvider accountCredentialsProvider; + private final CredentialsRepository credentialsRepository; @Autowired public ModifyServerGroupLaunchTemplateValidator( - AccountCredentialsProvider accountCredentialsProvider) { - this.accountCredentialsProvider = accountCredentialsProvider; + CredentialsRepository credentialsRepository) { + this.credentialsRepository = credentialsRepository; } @Override @@ -54,8 +54,8 @@ public void validate( "credentials", "modifyservergrouplaunchtemplatedescription.credentials.empty"); } else { AccountCredentials credentials = - accountCredentialsProvider.getCredentials(description.getCredentials().getName()); - if (!(credentials instanceof AmazonCredentials)) { + credentialsRepository.getOne(description.getCredentials().getName()); + if (credentials == null) { errors.rejectValue( "credentials", "modifyservergrouplaunchtemplatedescription.credentials.invalid"); } diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/RebootInstancesDescriptionValidator.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/RebootInstancesDescriptionValidator.groovy index a3c95a9979a..f1e7c187568 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/RebootInstancesDescriptionValidator.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/RebootInstancesDescriptionValidator.groovy @@ -17,9 +17,9 @@ package com.netflix.spinnaker.clouddriver.aws.deploy.validators import com.netflix.spinnaker.clouddriver.aws.AmazonOperation +import com.netflix.spinnaker.clouddriver.aws.deploy.description.RebootInstancesDescription import com.netflix.spinnaker.clouddriver.deploy.ValidationErrors import com.netflix.spinnaker.clouddriver.orchestration.AtomicOperations -import com.netflix.spinnaker.clouddriver.aws.deploy.description.RebootInstancesDescription import org.springframework.stereotype.Component @AmazonOperation(AtomicOperations.REBOOT_INSTANCES) diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/TerminateInstancesDescriptionValidator.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/TerminateInstancesDescriptionValidator.groovy index 86328c9593b..064c7b6bcdf 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/TerminateInstancesDescriptionValidator.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/TerminateInstancesDescriptionValidator.groovy @@ -16,9 +16,9 @@ package com.netflix.spinnaker.clouddriver.aws.deploy.validators import com.netflix.spinnaker.clouddriver.aws.AmazonOperation +import com.netflix.spinnaker.clouddriver.aws.deploy.description.TerminateInstancesDescription import com.netflix.spinnaker.clouddriver.deploy.ValidationErrors import com.netflix.spinnaker.clouddriver.orchestration.AtomicOperations -import com.netflix.spinnaker.clouddriver.aws.deploy.description.TerminateInstancesDescription import org.springframework.stereotype.Component @AmazonOperation(AtomicOperations.TERMINATE_INSTANCES) diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/UpsertAmazonDNSDescriptionValidator.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/UpsertAmazonDNSDescriptionValidator.groovy index 975ce461dd5..81e9b7b40ef 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/UpsertAmazonDNSDescriptionValidator.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/UpsertAmazonDNSDescriptionValidator.groovy @@ -16,9 +16,9 @@ package com.netflix.spinnaker.clouddriver.aws.deploy.validators -import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider import com.netflix.spinnaker.clouddriver.aws.deploy.description.UpsertAmazonDNSDescription import com.netflix.spinnaker.clouddriver.aws.deploy.description.UpsertAmazonLoadBalancerDescription +import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider import com.netflix.spinnaker.clouddriver.deploy.ValidationErrors import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/UpsertSecurityGroupDescriptionValidator.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/UpsertSecurityGroupDescriptionValidator.groovy index 365a4024643..cf9814687e4 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/UpsertSecurityGroupDescriptionValidator.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/UpsertSecurityGroupDescriptionValidator.groovy @@ -17,11 +17,10 @@ package com.netflix.spinnaker.clouddriver.aws.deploy.validators import com.netflix.spinnaker.clouddriver.aws.AmazonOperation -import com.netflix.spinnaker.clouddriver.deploy.ValidationErrors -import com.netflix.spinnaker.clouddriver.orchestration.AtomicOperations import com.netflix.spinnaker.clouddriver.aws.deploy.description.UpsertSecurityGroupDescription -import com.netflix.spinnaker.clouddriver.aws.model.SecurityGroupNotFoundException import com.netflix.spinnaker.clouddriver.aws.services.RegionScopedProviderFactory +import com.netflix.spinnaker.clouddriver.deploy.ValidationErrors +import com.netflix.spinnaker.clouddriver.orchestration.AtomicOperations import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/health/AmazonHealthIndicator.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/health/AmazonHealthIndicator.groovy index 7ac9763930d..ce2ec1c00bd 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/health/AmazonHealthIndicator.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/health/AmazonHealthIndicator.groovy @@ -19,12 +19,10 @@ package com.netflix.spinnaker.clouddriver.aws.health import com.amazonaws.AmazonClientException import com.amazonaws.AmazonServiceException import com.amazonaws.services.ec2.AmazonEC2 -import com.amazonaws.services.ec2.model.AmazonEC2Exception -import com.netflix.spectator.api.Counter import com.netflix.spectator.api.Registry import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider +import com.netflix.spinnaker.credentials.CredentialsRepository import groovy.transform.InheritConstructors import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -44,7 +42,7 @@ class AmazonHealthIndicator implements HealthIndicator { private static final Logger LOG = LoggerFactory.getLogger(AmazonHealthIndicator) - private final AccountCredentialsProvider accountCredentialsProvider + private final CredentialsRepository credentialsRepository private final AmazonClientProvider amazonClientProvider private final AtomicReference lastException = new AtomicReference<>(null) @@ -53,10 +51,10 @@ class AmazonHealthIndicator implements HealthIndicator { private final AtomicLong errors; @Autowired - AmazonHealthIndicator(AccountCredentialsProvider accountCredentialsProvider, + AmazonHealthIndicator(CredentialsRepository credentialsRepository, AmazonClientProvider amazonClientProvider, Registry registry) { - this.accountCredentialsProvider = accountCredentialsProvider + this.credentialsRepository = credentialsRepository this.amazonClientProvider = amazonClientProvider this.errors = registry.gauge("health.amazon.errors", new AtomicLong(0)) @@ -80,7 +78,7 @@ class AmazonHealthIndicator implements HealthIndicator { @Scheduled(fixedDelay = 120000L) void checkHealth() { try { - Set amazonCredentials = accountCredentialsProvider.all.findAll { + Set amazonCredentials = credentialsRepository.getAll().findAll { it instanceof NetflixAmazonCredentials } as Set for (NetflixAmazonCredentials credentials in amazonCredentials) { diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/InstanceTerminationLifecycleWorker.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/InstanceTerminationLifecycleWorker.java index 7ce30ebb6fa..dc4e22a612b 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/InstanceTerminationLifecycleWorker.java +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/InstanceTerminationLifecycleWorker.java @@ -15,7 +15,11 @@ */ package com.netflix.spinnaker.clouddriver.aws.lifecycle; -import com.amazonaws.auth.policy.*; +import com.amazonaws.auth.policy.Condition; +import com.amazonaws.auth.policy.Policy; +import com.amazonaws.auth.policy.Principal; +import com.amazonaws.auth.policy.Resource; +import com.amazonaws.auth.policy.Statement; import com.amazonaws.auth.policy.Statement.Effect; import com.amazonaws.auth.policy.actions.SNSActions; import com.amazonaws.auth.policy.actions.SQSActions; @@ -37,10 +41,16 @@ import com.netflix.spinnaker.clouddriver.eureka.api.Eureka; import com.netflix.spinnaker.clouddriver.eureka.deploy.ops.AbstractEurekaSupport.DiscoveryStatus; import com.netflix.spinnaker.clouddriver.security.AccountCredentials; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider; +import com.netflix.spinnaker.credentials.CredentialsRepository; import java.io.IOException; import java.time.Duration; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import javax.inject.Provider; import org.slf4j.Logger; @@ -59,7 +69,7 @@ public class InstanceTerminationLifecycleWorker implements Runnable { ObjectMapper objectMapper; AmazonClientProvider amazonClientProvider; - AccountCredentialsProvider accountCredentialsProvider; + CredentialsRepository credentialsRepository; InstanceTerminationConfigurationProperties properties; Provider discoverySupport; Registry registry; @@ -72,18 +82,18 @@ public class InstanceTerminationLifecycleWorker implements Runnable { public InstanceTerminationLifecycleWorker( ObjectMapper objectMapper, AmazonClientProvider amazonClientProvider, - AccountCredentialsProvider accountCredentialsProvider, + CredentialsRepository credentialsRepository, InstanceTerminationConfigurationProperties properties, Provider discoverySupport, Registry registry) { this.objectMapper = objectMapper; this.amazonClientProvider = amazonClientProvider; - this.accountCredentialsProvider = accountCredentialsProvider; + this.credentialsRepository = credentialsRepository; this.properties = properties; this.discoverySupport = discoverySupport; this.registry = registry; - Set accountCredentials = accountCredentialsProvider.getAll(); + Set accountCredentials = credentialsRepository.getAll(); this.queueARN = new ARN(accountCredentials, properties.getQueueARN()); this.topicARN = new ARN(accountCredentials, properties.getTopicARN()); } @@ -113,7 +123,7 @@ private void listenForMessages() { AmazonSQS amazonSQS = amazonClientProvider.getAmazonSQS(queueARN.account, queueARN.region); AmazonSNS amazonSNS = amazonClientProvider.getAmazonSNS(topicARN.account, topicARN.region); - Set accountCredentials = accountCredentialsProvider.getAll(); + Set accountCredentials = credentialsRepository.getAll(); List allAccountIds = getAllAccountIds(accountCredentials); this.queueId = @@ -250,7 +260,7 @@ private static void deleteMessage(AmazonSQS amazonSQS, String queueUrl, Message } private NetflixAmazonCredentials getAccountCredentialsById(String accountId) { - for (AccountCredentials credentials : accountCredentialsProvider.getAll()) { + for (AccountCredentials credentials : credentialsRepository.getAll()) { if (credentials.getAccountId() != null && credentials.getAccountId().equals(accountId)) { return (NetflixAmazonCredentials) credentials; } diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/InstanceTerminationLifecycleWorkerProvider.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/InstanceTerminationLifecycleWorkerProvider.java index 20e06b74105..42da9da1b5f 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/InstanceTerminationLifecycleWorkerProvider.java +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/InstanceTerminationLifecycleWorkerProvider.java @@ -21,7 +21,7 @@ import com.netflix.spinnaker.clouddriver.aws.deploy.ops.discovery.AwsEurekaSupport; import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider; import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider; +import com.netflix.spinnaker.credentials.CredentialsRepository; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.RejectedExecutionException; @@ -47,7 +47,7 @@ public class InstanceTerminationLifecycleWorkerProvider { private final ObjectMapper objectMapper; private final AmazonClientProvider amazonClientProvider; - private final AccountCredentialsProvider accountCredentialsProvider; + private final CredentialsRepository credentialsRepository; private final InstanceTerminationConfigurationProperties properties; private final Provider discoverySupport; private final Registry registry; @@ -56,13 +56,13 @@ public class InstanceTerminationLifecycleWorkerProvider { InstanceTerminationLifecycleWorkerProvider( @Qualifier("amazonObjectMapper") ObjectMapper objectMapper, AmazonClientProvider amazonClientProvider, - AccountCredentialsProvider accountCredentialsProvider, + CredentialsRepository credentialsRepository, InstanceTerminationConfigurationProperties properties, Provider discoverySupport, Registry registry) { this.objectMapper = objectMapper; this.amazonClientProvider = amazonClientProvider; - this.accountCredentialsProvider = accountCredentialsProvider; + this.credentialsRepository = credentialsRepository; this.properties = properties; this.discoverySupport = discoverySupport; this.registry = registry; @@ -71,8 +71,7 @@ public class InstanceTerminationLifecycleWorkerProvider { @PostConstruct public void start() { NetflixAmazonCredentials credentials = - (NetflixAmazonCredentials) - accountCredentialsProvider.getCredentials(properties.getAccountName()); + (NetflixAmazonCredentials) credentialsRepository.getOne(properties.getAccountName()); ExecutorService executorService = Executors.newFixedThreadPool( credentials.getRegions().size(), @@ -89,7 +88,7 @@ public void start() { new InstanceTerminationLifecycleWorker( objectMapper, amazonClientProvider, - accountCredentialsProvider, + credentialsRepository, new InstanceTerminationConfigurationProperties( properties.getAccountName(), properties diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/LaunchFailureNotificationAgent.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/LaunchFailureNotificationAgent.java index cec0d53cf6d..91efb792d3c 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/LaunchFailureNotificationAgent.java +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/LaunchFailureNotificationAgent.java @@ -38,8 +38,8 @@ import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials; import com.netflix.spinnaker.clouddriver.cache.CustomScheduledAgent; import com.netflix.spinnaker.clouddriver.security.AccountCredentials; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider; import com.netflix.spinnaker.clouddriver.tags.EntityTagger; +import com.netflix.spinnaker.credentials.CredentialsRepository; import java.io.IOException; import java.util.Collections; import java.util.List; @@ -64,7 +64,7 @@ class LaunchFailureNotificationAgent implements RunnableAgent, CustomScheduledAg private final ObjectMapper objectMapper; private final AmazonClientProvider amazonClientProvider; - private final AccountCredentialsProvider accountCredentialsProvider; + private final CredentialsRepository credentialsRepository; private final LaunchFailureConfigurationProperties properties; private final EntityTagger serverGroupTagger; @@ -77,16 +77,16 @@ class LaunchFailureNotificationAgent implements RunnableAgent, CustomScheduledAg LaunchFailureNotificationAgent( ObjectMapper objectMapper, AmazonClientProvider amazonClientProvider, - AccountCredentialsProvider accountCredentialsProvider, + CredentialsRepository credentialsRepository, LaunchFailureConfigurationProperties properties, EntityTagger serverGroupTagger) { this.objectMapper = objectMapper; this.amazonClientProvider = amazonClientProvider; - this.accountCredentialsProvider = accountCredentialsProvider; + this.credentialsRepository = credentialsRepository; this.properties = properties; this.serverGroupTagger = serverGroupTagger; - Set accountCredentials = accountCredentialsProvider.getAll(); + Set accountCredentials = credentialsRepository.getAll(); this.topicARN = new ARN(accountCredentials, properties.getTopicARN()); this.queueARN = new ARN(accountCredentials, properties.getQueueARN()); } @@ -118,8 +118,7 @@ public long getTimeoutMillis() { @Override public void run() { List allAccountIds = - accountCredentialsProvider.getAll().stream() - .filter(c -> c instanceof NetflixAmazonCredentials) + credentialsRepository.getAll().stream() .map(AccountCredentials::getAccountId) .collect(Collectors.toList()); diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/LaunchFailureNotificationAgentProvider.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/LaunchFailureNotificationAgentProvider.java index 6f5a8c3066e..b80dfab44d3 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/LaunchFailureNotificationAgentProvider.java +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/LaunchFailureNotificationAgentProvider.java @@ -22,8 +22,9 @@ import com.netflix.spinnaker.clouddriver.aws.provider.AwsProvider; import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider; import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider; import com.netflix.spinnaker.clouddriver.tags.EntityTagger; +import com.netflix.spinnaker.credentials.Credentials; +import com.netflix.spinnaker.credentials.CredentialsRepository; import java.util.Collection; import java.util.List; import java.util.regex.Pattern; @@ -35,19 +36,19 @@ public class LaunchFailureNotificationAgentProvider implements AgentProvider { private final ObjectMapper objectMapper; private final AmazonClientProvider amazonClientProvider; - private final AccountCredentialsProvider accountCredentialsProvider; + private final CredentialsRepository credentialsRepository; private final LaunchFailureConfigurationProperties properties; private final EntityTagger entityTagger; LaunchFailureNotificationAgentProvider( ObjectMapper objectMapper, AmazonClientProvider amazonClientProvider, - AccountCredentialsProvider accountCredentialsProvider, + CredentialsRepository credentialsRepository, LaunchFailureConfigurationProperties properties, EntityTagger entityTagger) { this.objectMapper = objectMapper; this.amazonClientProvider = amazonClientProvider; - this.accountCredentialsProvider = accountCredentialsProvider; + this.credentialsRepository = credentialsRepository; this.properties = properties; this.entityTagger = entityTagger; } @@ -58,43 +59,38 @@ public boolean supports(String providerName) { } @Override - public Collection agents() { - NetflixAmazonCredentials credentials = - (NetflixAmazonCredentials) - accountCredentialsProvider.getCredentials(properties.getAccountName()); + public Collection agents(Credentials credentials) { + NetflixAmazonCredentials netflixAmazonCredentials = (NetflixAmazonCredentials) credentials; // an agent for each region in the specified account List agents = - credentials.getRegions().stream() + netflixAmazonCredentials.getRegions().stream() .map( region -> new LaunchFailureNotificationAgent( objectMapper, amazonClientProvider, - accountCredentialsProvider, + credentialsRepository, new LaunchFailureConfigurationProperties( properties.getAccountName(), properties .getTopicARN() .replaceAll(REGION_TEMPLATE_PATTERN, region.getName()) .replaceAll( - ACCOUNT_ID_TEMPLATE_PATTERN, credentials.getAccountId()), + ACCOUNT_ID_TEMPLATE_PATTERN, + netflixAmazonCredentials.getAccountId()), properties .getQueueARN() .replaceAll(REGION_TEMPLATE_PATTERN, region.getName()) .replaceAll( - ACCOUNT_ID_TEMPLATE_PATTERN, credentials.getAccountId()), + ACCOUNT_ID_TEMPLATE_PATTERN, + netflixAmazonCredentials.getAccountId()), properties.getMaxMessagesPerCycle(), properties.getVisibilityTimeout(), properties.getWaitTimeSeconds()), entityTagger)) .collect(Collectors.toList()); - // an agent that will cleanup stale notifications across all accounts + region - agents.add( - new LaunchFailureNotificationCleanupAgent( - amazonClientProvider, accountCredentialsProvider, entityTagger)); - return agents; } } diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/LaunchFailureNotificationCleanupAgent.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/LaunchFailureNotificationCleanupAgent.java index 39b00a2c4ff..9f0021b674f 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/LaunchFailureNotificationCleanupAgent.java +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/LaunchFailureNotificationCleanupAgent.java @@ -29,8 +29,8 @@ import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials; import com.netflix.spinnaker.clouddriver.cache.CustomScheduledAgent; import com.netflix.spinnaker.clouddriver.model.EntityTags; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider; import com.netflix.spinnaker.clouddriver.tags.EntityTagger; +import com.netflix.spinnaker.credentials.CredentialsRepository; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.UndeclaredThrowableException; import java.util.Collection; @@ -47,15 +47,15 @@ public class LaunchFailureNotificationCleanupAgent implements RunnableAgent, Cus private static final int MAX_RESULTS = 10000; private final AmazonClientProvider amazonClientProvider; - private final AccountCredentialsProvider accountCredentialsProvider; + private final CredentialsRepository credentialsRepository; private final EntityTagger serverGroupTagger; LaunchFailureNotificationCleanupAgent( AmazonClientProvider amazonClientProvider, - AccountCredentialsProvider accountCredentialsProvider, + CredentialsRepository credentialsRepository, EntityTagger serverGroupTagger) { this.amazonClientProvider = amazonClientProvider; - this.accountCredentialsProvider = accountCredentialsProvider; + this.credentialsRepository = credentialsRepository; this.serverGroupTagger = serverGroupTagger; } @@ -93,8 +93,7 @@ public void run() { entityTags -> { EntityTags.EntityRef entityRef = entityTags.getEntityRef(); Optional credentials = - Optional.ofNullable(accountCredentialsProvider.getCredentials(entityRef.getAccount())) - .filter((c) -> c instanceof NetflixAmazonCredentials) + Optional.ofNullable(credentialsRepository.getOne(entityRef.getAccount())) .map(NetflixAmazonCredentials.class::cast); if (!credentials.isPresent()) { diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/LifecycleSubscriberConfiguration.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/LifecycleSubscriberConfiguration.java index 6885d38ebf2..4c56554ad8d 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/LifecycleSubscriberConfiguration.java +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/lifecycle/LifecycleSubscriberConfiguration.java @@ -17,9 +17,13 @@ package com.netflix.spinnaker.clouddriver.aws.lifecycle; import com.fasterxml.jackson.databind.ObjectMapper; +import com.netflix.spinnaker.clouddriver.aws.provider.AwsProvider; import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider; +import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials; import com.netflix.spinnaker.clouddriver.tags.EntityTagger; +import com.netflix.spinnaker.credentials.CredentialsRepository; +import java.util.ArrayList; +import java.util.Collections; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -38,10 +42,16 @@ class LifecycleSubscriberConfiguration { LaunchFailureNotificationAgentProvider launchFailureNotificationAgentProvider( @Qualifier("amazonObjectMapper") ObjectMapper objectMapper, AmazonClientProvider amazonClientProvider, - AccountCredentialsProvider accountCredentialsProvider, + CredentialsRepository credentialsRepository, LaunchFailureConfigurationProperties properties, - EntityTagger entityTagger) { + EntityTagger entityTagger, + AwsProvider awsProvider) { + awsProvider.addAgents( + new ArrayList<>( + Collections.singletonList( + new LaunchFailureNotificationCleanupAgent( + amazonClientProvider, credentialsRepository, entityTagger)))); return new LaunchFailureNotificationAgentProvider( - objectMapper, amazonClientProvider, accountCredentialsProvider, properties, entityTagger); + objectMapper, amazonClientProvider, credentialsRepository, properties, entityTagger); } } diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/AwsCleanupProvider.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/AwsCleanupProvider.groovy index 14220624f76..b30a287b084 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/AwsCleanupProvider.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/AwsCleanupProvider.groovy @@ -19,23 +19,15 @@ package com.netflix.spinnaker.clouddriver.aws.provider import com.netflix.spinnaker.cats.agent.Agent import com.netflix.spinnaker.cats.agent.AgentSchedulerAware import com.netflix.spinnaker.cats.provider.Provider +import com.netflix.spinnaker.clouddriver.security.BaseProvider +import org.springframework.stereotype.Component -class AwsCleanupProvider extends AgentSchedulerAware implements Provider { +@Component +class AwsCleanupProvider extends BaseProvider implements Provider { public static final String PROVIDER_NAME = AwsCleanupProvider.name - private final Collection agents - - AwsCleanupProvider(Collection agents) { - this.agents = agents - } - @Override String getProviderName() { return PROVIDER_NAME } - - @Override - Collection getAgents() { - return agents - } } diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/AwsInfrastructureProvider.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/AwsInfrastructureProvider.groovy index d205c2250aa..1a6be946b3f 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/AwsInfrastructureProvider.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/AwsInfrastructureProvider.groovy @@ -17,39 +17,27 @@ package com.netflix.spinnaker.clouddriver.aws.provider import com.fasterxml.jackson.core.type.TypeReference -import com.netflix.spinnaker.cats.agent.Agent -import com.netflix.spinnaker.cats.agent.AgentSchedulerAware -import com.netflix.spinnaker.clouddriver.aws.AmazonCloudProvider import com.netflix.spinnaker.clouddriver.cache.KeyParser import com.netflix.spinnaker.clouddriver.cache.SearchableProvider import com.netflix.spinnaker.clouddriver.aws.cache.Keys +import com.netflix.spinnaker.clouddriver.security.BaseProvider +import org.springframework.stereotype.Component import static com.netflix.spinnaker.clouddriver.aws.cache.Keys.Namespace.SECURITY_GROUPS -import static com.netflix.spinnaker.clouddriver.cache.SearchableProvider.SearchableResource -class AwsInfrastructureProvider extends AgentSchedulerAware implements SearchableProvider { +@Component +class AwsInfrastructureProvider extends BaseProvider implements SearchableProvider { public static final TypeReference> ATTRIBUTES = new TypeReference>() {} public static final String PROVIDER_NAME = AwsInfrastructureProvider.name - private final Collection agents - private final KeyParser keyParser = new Keys() - AwsInfrastructureProvider(Collection agents) { - this.agents = agents - } - @Override String getProviderName() { return PROVIDER_NAME } - @Override - Collection getAgents() { - agents - } - final Set defaultCaches = [SECURITY_GROUPS.ns].asImmutable() final Map urlMappingTemplates = [ diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/AwsProvider.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/AwsProvider.groovy index c790c7a9446..a1024653424 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/AwsProvider.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/AwsProvider.groovy @@ -16,26 +16,26 @@ package com.netflix.spinnaker.clouddriver.aws.provider -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.aws.data.Keys import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials import com.netflix.spinnaker.clouddriver.cache.KeyParser import com.netflix.spinnaker.clouddriver.cache.SearchableProvider -import com.netflix.spinnaker.clouddriver.eureka.provider.agent.EurekaAwareProvider -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository -import com.netflix.spinnaker.clouddriver.aws.data.Keys import com.netflix.spinnaker.clouddriver.core.provider.agent.HealthProvidingCachingAgent +import com.netflix.spinnaker.clouddriver.eureka.provider.agent.EurekaAwareProvider +import com.netflix.spinnaker.clouddriver.security.BaseProvider +import com.netflix.spinnaker.credentials.CredentialsRepository import static com.netflix.spinnaker.clouddriver.core.provider.agent.Namespace.* -class AwsProvider extends AgentSchedulerAware implements SearchableProvider, EurekaAwareProvider { +class AwsProvider extends BaseProvider implements SearchableProvider, EurekaAwareProvider { public static final String PROVIDER_NAME = AwsProvider.name final KeyParser keyParser = new Keys() - final AccountCredentialsRepository accountCredentialsRepository + final CredentialsRepository credentialsRepository final Set defaultCaches = [ LOAD_BALANCERS.ns, @@ -55,12 +55,11 @@ class AwsProvider extends AgentSchedulerAware implements SearchableProvider, Eur (new AmazonSearchableResource(INSTANCES.ns)): new InstanceSearchResultHydrator(), ] - final Collection agents private Collection healthAgents - AwsProvider(AccountCredentialsRepository accountCredentialsRepository, Collection agents) { - this.agents = agents - this.accountCredentialsRepository = accountCredentialsRepository + AwsProvider(CredentialsRepository credentialsRepository) { + super() + this.credentialsRepository = credentialsRepository synchronizeHealthAgents() } @@ -76,9 +75,7 @@ class AwsProvider extends AgentSchedulerAware implements SearchableProvider, Eur } Collection getHealthAgents() { - def allHealthAgents = [] - allHealthAgents.addAll(this.healthAgents) - Collections.unmodifiableCollection(allHealthAgents) + Collections.unmodifiableCollection(this.healthAgents) } @Override @@ -133,14 +130,14 @@ class AwsProvider extends AgentSchedulerAware implements SearchableProvider, Eur private String getCredentialName(String accountId, boolean allowMultipleEurekaPerAccount, String eurekaAccountName) { if (allowMultipleEurekaPerAccount) { - def credentialName = accountCredentialsRepository.all.find { + def credentialName = credentialsRepository.all.find { it instanceof NetflixAmazonCredentials && it.accountId == accountId && it.name == eurekaAccountName }?.name if (credentialName) { return credentialName } } - return accountCredentialsRepository.all.find { + return credentialsRepository.all.find { it instanceof NetflixAmazonCredentials && it.accountId == accountId }?.name } diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/ProviderHelpers.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/ProviderHelpers.java new file mode 100644 index 00000000000..337c649d7f7 --- /dev/null +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/ProviderHelpers.java @@ -0,0 +1,264 @@ +/* + * Copyright 2020 Netflix, 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. + * + */ + +package com.netflix.spinnaker.clouddriver.aws.provider; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.netflix.spectator.api.Registry; +import com.netflix.spinnaker.cats.agent.Agent; +import com.netflix.spinnaker.cats.agent.AgentProvider; +import com.netflix.spinnaker.clouddriver.aws.AmazonCloudProvider; +import com.netflix.spinnaker.clouddriver.aws.AwsConfigurationProperties; +import com.netflix.spinnaker.clouddriver.aws.agent.CleanupAlarmsAgent; +import com.netflix.spinnaker.clouddriver.aws.agent.CleanupDetachedInstancesAgent; +import com.netflix.spinnaker.clouddriver.aws.agent.ReconcileClassicLinkSecurityGroupsAgent; +import com.netflix.spinnaker.clouddriver.aws.edda.EddaApiFactory; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonApplicationLoadBalancerCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonCertificateCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonCloudFormationCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonElasticIpCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonInstanceTypeCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonKeyPairCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonLaunchTemplateCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonLoadBalancerCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonLoadBalancerInstanceStateCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonSecurityGroupCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonSubnetCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonVpcCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.ClusterCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.EddaLoadBalancerCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.ImageCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.InstanceCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.LaunchConfigCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.ReservationReportCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.ReservedInstancesCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.view.AmazonS3DataProvider; +import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider; +import com.netflix.spinnaker.clouddriver.aws.security.EddaTimeoutConfig; +import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials; +import com.netflix.spinnaker.clouddriver.security.ProviderUtils; +import com.netflix.spinnaker.config.AwsConfiguration; +import com.netflix.spinnaker.credentials.CredentialsRepository; +import com.netflix.spinnaker.kork.dynamicconfig.DynamicConfigService; +import java.util.*; +import java.util.concurrent.ExecutorService; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.context.ApplicationContext; + +public class ProviderHelpers { + + @Getter + @RequiredArgsConstructor + public static class BuildResult { + private final List agents; + private final Set regionsToAdd; + } + + public static BuildResult buildAwsInfrastructureAgents( + NetflixAmazonCredentials credentials, + AwsInfrastructureProvider awsInfrastructureProvider, + CredentialsRepository accountCredentialsRepository, + AmazonClientProvider amazonClientProvider, + ObjectMapper amazonObjectMapper, + Registry registry, + EddaTimeoutConfig eddaTimeoutConfig, + Set regions) { + Set scheduledAccounts = ProviderUtils.getScheduledAccounts(awsInfrastructureProvider); + List newlyAddedAgents = new ArrayList<>(); + for (NetflixAmazonCredentials.AWSRegion region : credentials.getRegions()) { + if (!scheduledAccounts.contains(credentials.getName())) { + if (regions.add(region.getName())) { + newlyAddedAgents.add( + new AmazonInstanceTypeCachingAgent(region.getName(), accountCredentialsRepository)); + } + newlyAddedAgents.add( + new AmazonElasticIpCachingAgent(amazonClientProvider, credentials, region.getName())); + newlyAddedAgents.add( + new AmazonKeyPairCachingAgent(amazonClientProvider, credentials, region.getName())); + newlyAddedAgents.add( + new AmazonSecurityGroupCachingAgent( + amazonClientProvider, + credentials, + region.getName(), + amazonObjectMapper, + registry, + eddaTimeoutConfig)); + newlyAddedAgents.add( + new AmazonSubnetCachingAgent( + amazonClientProvider, credentials, region.getName(), amazonObjectMapper)); + newlyAddedAgents.add( + new AmazonVpcCachingAgent( + amazonClientProvider, credentials, region.getName(), amazonObjectMapper)); + } + } + return new BuildResult(newlyAddedAgents, regions); + } + + public static BuildResult buildAwsProviderAgents( + NetflixAmazonCredentials credentials, + CredentialsRepository accountCredentialsRepository, + AmazonClientProvider amazonClientProvider, + ObjectMapper objectMapper, + Registry registry, + EddaTimeoutConfig eddaTimeoutConfig, + AwsProvider awsProvider, + AmazonCloudProvider amazonCloudProvider, + DynamicConfigService dynamicConfigService, + EddaApiFactory eddaApiFactory, + Optional reservationReportPool, + Optional> agentProviders, + ApplicationContext ctx, + AmazonS3DataProvider amazonS3DataProvider, + Set publicRegions) { + Set scheduledAccounts = ProviderUtils.getScheduledAccounts(awsProvider); + List newlyAddedAgents = new ArrayList<>(); + for (NetflixAmazonCredentials.AWSRegion region : credentials.getRegions()) { + if (!scheduledAccounts.contains(credentials.getName())) { + newlyAddedAgents.add( + new ClusterCachingAgent( + amazonCloudProvider, + amazonClientProvider, + credentials, + region.getName(), + objectMapper, + registry, + eddaTimeoutConfig)); + newlyAddedAgents.add( + new LaunchConfigCachingAgent( + amazonClientProvider, credentials, region.getName(), objectMapper, registry)); + boolean publicImages = false; + if (!publicRegions.contains(region.getName())) { + publicImages = true; + publicRegions.add(region.getName()); + } + newlyAddedAgents.add( + new ImageCachingAgent( + amazonClientProvider, + credentials, + region.getName(), + objectMapper, + registry, + publicImages, + dynamicConfigService)); + newlyAddedAgents.add( + new InstanceCachingAgent( + amazonClientProvider, credentials, region.getName(), objectMapper, registry)); + newlyAddedAgents.add( + new AmazonLoadBalancerCachingAgent( + amazonCloudProvider, + amazonClientProvider, + credentials, + region.getName(), + eddaApiFactory.createApi(credentials.getEdda(), region.getName()), + objectMapper, + registry)); + newlyAddedAgents.add( + new AmazonApplicationLoadBalancerCachingAgent( + amazonCloudProvider, + amazonClientProvider, + credentials, + region.getName(), + eddaApiFactory.createApi(credentials.getEdda(), region.getName()), + objectMapper, + registry, + eddaTimeoutConfig)); + newlyAddedAgents.add( + new ReservedInstancesCachingAgent( + amazonClientProvider, credentials, region.getName(), objectMapper, registry)); + newlyAddedAgents.add( + new AmazonCertificateCachingAgent( + amazonClientProvider, credentials, region.getName(), objectMapper, registry)); + + if (dynamicConfigService.isEnabled("aws.features.cloud-formation", false)) { + newlyAddedAgents.add( + new AmazonCloudFormationCachingAgent( + amazonClientProvider, credentials, region.getName(), registry)); + } + if (credentials.getEddaEnabled() + && !eddaTimeoutConfig.getDisabledRegions().contains(region.getName())) { + newlyAddedAgents.add( + new EddaLoadBalancerCachingAgent( + eddaApiFactory.createApi(credentials.getEdda(), region.getName()), + credentials, + region.getName(), + objectMapper)); + } else { + newlyAddedAgents.add( + new AmazonLoadBalancerInstanceStateCachingAgent( + amazonClientProvider, credentials, region.getName(), objectMapper, ctx)); + } + if (dynamicConfigService.isEnabled("aws.features.launch-templates", false)) { + newlyAddedAgents.add( + new AmazonLaunchTemplateCachingAgent( + amazonClientProvider, credentials, region.getName(), objectMapper, registry)); + } + } + } + if (reservationReportPool.isPresent() && awsProvider.getAgentScheduler() == null) { + newlyAddedAgents.add( + new ReservationReportCachingAgent( + registry, + amazonClientProvider, + amazonS3DataProvider, + accountCredentialsRepository, + objectMapper, + reservationReportPool.get(), + ctx)); + } + agentProviders.ifPresent( + providers -> + providers.stream() + .filter(it -> it.supports(AwsProvider.PROVIDER_NAME)) + .forEach(provider -> newlyAddedAgents.addAll(provider.agents(credentials)))); + return new BuildResult(newlyAddedAgents, publicRegions); + } + + public static List buildAwsCleanupAgents( + NetflixAmazonCredentials credentials, + CredentialsRepository accountCredentialsRepository, + AmazonClientProvider amazonClientProvider, + AwsCleanupProvider awsCleanupProvider, + AwsConfiguration.DeployDefaults deployDefaults, + AwsConfigurationProperties awsConfigurationProperties) { + Set scheduledAccounts = ProviderUtils.getScheduledAccounts(awsCleanupProvider); + List newlyAddedAgents = new ArrayList<>(); + if (!scheduledAccounts.contains(credentials.getName())) { + for (NetflixAmazonCredentials.AWSRegion region : credentials.getRegions()) { + if (deployDefaults.isReconcileClassicLinkAccount(credentials)) { + newlyAddedAgents.add( + new ReconcileClassicLinkSecurityGroupsAgent( + amazonClientProvider, credentials, region.getName(), deployDefaults)); + } + } + } + // AccountCredentialsRepository dependency + // Might not be safe when parallel processing + if (awsCleanupProvider.getAgentScheduler() != null) { + if (awsConfigurationProperties.getCleanup().getAlarms().getEnabled()) { + newlyAddedAgents.add( + new CleanupAlarmsAgent( + amazonClientProvider, + accountCredentialsRepository, + awsConfigurationProperties.getCleanup().getAlarms().getDaysToKeep())); + } + newlyAddedAgents.add( + new CleanupDetachedInstancesAgent(amazonClientProvider, accountCredentialsRepository)); + } + return newlyAddedAgents; + } +} diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/AbstractAmazonLoadBalancerCachingAgent.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/AbstractAmazonLoadBalancerCachingAgent.groovy index 120265ff2b1..64c193a8395 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/AbstractAmazonLoadBalancerCachingAgent.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/AbstractAmazonLoadBalancerCachingAgent.groovy @@ -129,7 +129,7 @@ abstract class AbstractAmazonLoadBalancerCachingAgent implements CachingAgent, O abstract CacheResult loadDataInternal(ProviderCache providerCache) @Override - Collection> pendingOnDemandRequests(ProviderCache providerCache) { + Collection> pendingOnDemandRequests(ProviderCache providerCache) { return [] } diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/AmazonApplicationLoadBalancerCachingAgent.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/AmazonApplicationLoadBalancerCachingAgent.groovy index effffbf20f9..2672532ae82 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/AmazonApplicationLoadBalancerCachingAgent.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/AmazonApplicationLoadBalancerCachingAgent.groovy @@ -382,7 +382,7 @@ class AmazonApplicationLoadBalancerCachingAgent extends AbstractAmazonLoadBalanc } @Override - Collection> pendingOnDemandRequests(ProviderCache providerCache) { + Collection> pendingOnDemandRequests(ProviderCache providerCache) { Collection keys = providerCache.filterIdentifiers( ON_DEMAND.ns, Keys.getLoadBalancerKey("*", "*", "*", "*", "*") diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/AmazonInstanceTypeCachingAgent.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/AmazonInstanceTypeCachingAgent.java index b27cabb7117..e60af44ce6a 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/AmazonInstanceTypeCachingAgent.java +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/AmazonInstanceTypeCachingAgent.java @@ -32,8 +32,9 @@ import com.netflix.spinnaker.clouddriver.aws.cache.Keys; import com.netflix.spinnaker.clouddriver.aws.provider.AwsInfrastructureProvider; import com.netflix.spinnaker.clouddriver.aws.security.AmazonCredentials; +import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials; import com.netflix.spinnaker.clouddriver.security.AccountCredentials; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository; +import com.netflix.spinnaker.credentials.CredentialsRepository; import java.io.IOException; import java.io.InputStream; import java.net.URI; @@ -65,7 +66,7 @@ public class AmazonInstanceTypeCachingAgent implements CachingAgent { // https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/us-west-2/index.json private final String region; - private final AccountCredentialsRepository accountCredentialsRepository; + private final CredentialsRepository accountCredentialsRepository; private final URI pricingUri; private final HttpHost pricingHost; private final HttpClient httpClient; @@ -73,14 +74,14 @@ public class AmazonInstanceTypeCachingAgent implements CachingAgent { new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); public AmazonInstanceTypeCachingAgent( - String region, AccountCredentialsRepository accountCredentialsRepository) { + String region, CredentialsRepository accountCredentialsRepository) { this(region, accountCredentialsRepository, HttpClients.createDefault()); } // VisibleForTesting AmazonInstanceTypeCachingAgent( String region, - AccountCredentialsRepository accountCredentialsRepository, + CredentialsRepository accountCredentialsRepository, HttpClient httpClient) { this.region = region; this.accountCredentialsRepository = accountCredentialsRepository; @@ -102,7 +103,6 @@ public CacheResult loadData(ProviderCache providerCache) { try { Set matchingAccounts = accountCredentialsRepository.getAll().stream() - .filter(AmazonCredentials.class::isInstance) .map(AmazonCredentials.class::cast) .filter(ac -> ac.getRegions().stream().anyMatch(r -> region.equals(r.getName()))) .map(AccountCredentials::getName) diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/AmazonSecurityGroupCachingAgent.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/AmazonSecurityGroupCachingAgent.groovy index f80ef116343..09c7a0a4cac 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/AmazonSecurityGroupCachingAgent.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/AmazonSecurityGroupCachingAgent.groovy @@ -165,7 +165,7 @@ class AmazonSecurityGroupCachingAgent implements CachingAgent, OnDemandAgent, Ac } @Override - Collection> pendingOnDemandRequests(ProviderCache providerCache) { + Collection> pendingOnDemandRequests(ProviderCache providerCache) { return [] } diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/ClusterCachingAgent.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/ClusterCachingAgent.groovy index d8e82f3d44e..81f6e1e768d 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/ClusterCachingAgent.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/ClusterCachingAgent.groovy @@ -459,7 +459,7 @@ class ClusterCachingAgent implements CachingAgent, OnDemandAgent, AccountAware, } @Override - Collection> pendingOnDemandRequests(ProviderCache providerCache) { + Collection> pendingOnDemandRequests(ProviderCache providerCache) { def keys = providerCache.filterIdentifiers(ON_DEMAND.ns, Keys.getServerGroupKey("*", "*", account.name, region)) return fetchPendingOnDemandRequests(providerCache, keys) } diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/ReservationReportCachingAgent.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/ReservationReportCachingAgent.groovy index 48c2ab71502..b0e1c24162f 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/ReservationReportCachingAgent.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/agent/ReservationReportCachingAgent.groovy @@ -50,6 +50,7 @@ import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider import com.netflix.spinnaker.clouddriver.aws.security.AmazonCredentials import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials import com.netflix.spinnaker.clouddriver.cache.CustomScheduledAgent +import com.netflix.spinnaker.credentials.CredentialsRepository import groovy.util.logging.Slf4j import org.springframework.context.ApplicationContext @@ -79,7 +80,7 @@ class ReservationReportCachingAgent implements CachingAgent, CustomScheduledAgen final AmazonClientProvider amazonClientProvider final AmazonS3DataProvider amazonS3DataProvider - final Collection accounts + final CredentialsRepository accountCredentialsRepository; final ObjectMapper objectMapper final AccountReservationDetailSerializer accountReservationDetailSerializer final Set vpcOnlyAccounts @@ -90,13 +91,13 @@ class ReservationReportCachingAgent implements CachingAgent, CustomScheduledAgen ReservationReportCachingAgent(Registry registry, AmazonClientProvider amazonClientProvider, AmazonS3DataProvider amazonS3DataProvider, - Collection accounts, + CredentialsRepository accountCredentialsRepository, ObjectMapper objectMapper, ExecutorService reservationReportPool, ApplicationContext ctx) { this.amazonClientProvider = amazonClientProvider this.amazonS3DataProvider = amazonS3DataProvider - this.accounts = accounts + this.accountCredentialsRepository = accountCredentialsRepository def module = new SimpleModule() accountReservationDetailSerializer = new AccountReservationDetailSerializer() @@ -173,7 +174,7 @@ class ReservationReportCachingAgent implements CachingAgent, CustomScheduledAgen } public Collection getAccounts() { - return accounts; + return accountCredentialsRepository.getAll(); } @Override diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/config/AwsInfrastructureProviderConfig.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/config/AwsInfrastructureProviderConfig.groovy deleted file mode 100644 index 8e4bb255e66..00000000000 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/config/AwsInfrastructureProviderConfig.groovy +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2015 Netflix, 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. - */ - -package com.netflix.spinnaker.clouddriver.aws.provider.config - -import com.fasterxml.jackson.databind.ObjectMapper -import com.netflix.spectator.api.Registry -import com.netflix.spinnaker.cats.agent.Agent -import com.netflix.spinnaker.clouddriver.aws.AmazonCloudProvider -import com.netflix.spinnaker.clouddriver.aws.provider.AwsInfrastructureProvider -import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonElasticIpCachingAgent -import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonInstanceTypeCachingAgent -import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonKeyPairCachingAgent -import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonSecurityGroupCachingAgent -import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonSubnetCachingAgent -import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonVpcCachingAgent -import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider -import com.netflix.spinnaker.clouddriver.aws.security.AmazonCredentials -import com.netflix.spinnaker.clouddriver.aws.security.EddaTimeoutConfig -import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository -import com.netflix.spinnaker.clouddriver.security.ProviderUtils -import org.springframework.beans.factory.annotation.Qualifier -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration -import org.springframework.context.annotation.DependsOn - -import java.util.concurrent.ConcurrentHashMap - -@Configuration -class AwsInfrastructureProviderConfig { - @Bean - @DependsOn('netflixAmazonCredentials') - AwsInfrastructureProvider awsInfrastructureProvider(AmazonClientProvider amazonClientProvider, - AccountCredentialsRepository accountCredentialsRepository, - @Qualifier("amazonObjectMapper") ObjectMapper amazonObjectMapper, - Registry registry, - EddaTimeoutConfig eddaTimeoutConfig) { - def awsInfrastructureProvider = - new AwsInfrastructureProvider(Collections.newSetFromMap(new ConcurrentHashMap())) - - synchronizeAwsInfrastructureProvider(awsInfrastructureProvider, - amazonClientProvider, - accountCredentialsRepository, - amazonObjectMapper, - registry, - eddaTimeoutConfig) - - awsInfrastructureProvider - } - - private static void synchronizeAwsInfrastructureProvider(AwsInfrastructureProvider awsInfrastructureProvider, - AmazonClientProvider amazonClientProvider, - AccountCredentialsRepository accountCredentialsRepository, - @Qualifier("amazonObjectMapper") ObjectMapper amazonObjectMapper, - Registry registry, - EddaTimeoutConfig eddaTimeoutConfig) { - def scheduledAccounts = ProviderUtils.getScheduledAccounts(awsInfrastructureProvider) - def allAccounts = ProviderUtils.buildThreadSafeSetOfAccounts(accountCredentialsRepository, NetflixAmazonCredentials, AmazonCloudProvider.ID) - - Set regions = new HashSet<>(); - allAccounts.each { NetflixAmazonCredentials credentials -> - for (AmazonCredentials.AWSRegion region : credentials.regions) { - if (!scheduledAccounts.contains(credentials.name)) { - def newlyAddedAgents = [] - - if (regions.add(region.name)) { - newlyAddedAgents << new AmazonInstanceTypeCachingAgent(region.name, accountCredentialsRepository) - } - - newlyAddedAgents << new AmazonElasticIpCachingAgent(amazonClientProvider, credentials, region.name) - newlyAddedAgents << new AmazonKeyPairCachingAgent(amazonClientProvider, credentials, region.name) - newlyAddedAgents << new AmazonSecurityGroupCachingAgent(amazonClientProvider, credentials, region.name, amazonObjectMapper, registry, eddaTimeoutConfig) - newlyAddedAgents << new AmazonSubnetCachingAgent(amazonClientProvider, credentials, region.name, amazonObjectMapper) - newlyAddedAgents << new AmazonVpcCachingAgent(amazonClientProvider, credentials, region.name, amazonObjectMapper) - - // If there is an agent scheduler, then this provider has been through the AgentController in the past. - // In that case, we need to do the scheduling here (because accounts have been added to a running system). - if (awsInfrastructureProvider.agentScheduler) { - ProviderUtils.rescheduleAgents(awsInfrastructureProvider, newlyAddedAgents) - } - - awsInfrastructureProvider.agents.addAll(newlyAddedAgents) - } - } - } - } -} diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/config/AwsProviderConfig.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/config/AwsProviderConfig.groovy index 2390aa84356..10968d59786 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/config/AwsProviderConfig.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/config/AwsProviderConfig.groovy @@ -16,43 +16,19 @@ package com.netflix.spinnaker.clouddriver.aws.provider.config -import com.fasterxml.jackson.databind.ObjectMapper + import com.google.common.util.concurrent.ThreadFactoryBuilder -import com.netflix.spectator.api.Registry import com.netflix.spinnaker.cats.agent.Agent -import com.netflix.spinnaker.cats.agent.AgentProvider -import com.netflix.spinnaker.clouddriver.aws.AmazonCloudProvider -import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonApplicationLoadBalancerCachingAgent -import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonCertificateCachingAgent -import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonCloudFormationCachingAgent -import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonLaunchTemplateCachingAgent -import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonLoadBalancerCachingAgent - -import com.netflix.spinnaker.clouddriver.aws.provider.agent.ReservedInstancesCachingAgent -import com.netflix.spinnaker.clouddriver.aws.provider.view.AmazonS3DataProvider -import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider -import com.netflix.spinnaker.clouddriver.aws.security.AmazonCredentials -import com.netflix.spinnaker.clouddriver.aws.security.EddaTimeoutConfig +import com.netflix.spinnaker.clouddriver.aws.provider.AwsProvider import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials import com.netflix.spinnaker.clouddriver.model.ReservationReport -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository -import com.netflix.spinnaker.clouddriver.security.ProviderUtils -import com.netflix.spinnaker.clouddriver.aws.edda.EddaApiFactory -import com.netflix.spinnaker.clouddriver.aws.provider.AwsProvider -import com.netflix.spinnaker.clouddriver.aws.provider.agent.AmazonLoadBalancerInstanceStateCachingAgent -import com.netflix.spinnaker.clouddriver.aws.provider.agent.ClusterCachingAgent -import com.netflix.spinnaker.clouddriver.aws.provider.agent.EddaLoadBalancerCachingAgent -import com.netflix.spinnaker.clouddriver.aws.provider.agent.ImageCachingAgent -import com.netflix.spinnaker.clouddriver.aws.provider.agent.InstanceCachingAgent -import com.netflix.spinnaker.clouddriver.aws.provider.agent.LaunchConfigCachingAgent -import com.netflix.spinnaker.clouddriver.aws.provider.agent.ReservationReportCachingAgent -import com.netflix.spinnaker.kork.dynamicconfig.DynamicConfigService +import com.netflix.spinnaker.credentials.CredentialsRepository import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.boot.context.properties.EnableConfigurationProperties -import org.springframework.context.ApplicationContext import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.DependsOn +import org.springframework.context.annotation.Lazy import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ExecutorService @@ -62,37 +38,8 @@ import java.util.concurrent.Executors @EnableConfigurationProperties(ReservationReportConfigurationProperties) class AwsProviderConfig { @Bean - @DependsOn('netflixAmazonCredentials') - AwsProvider awsProvider(AmazonCloudProvider amazonCloudProvider, - AmazonClientProvider amazonClientProvider, - AmazonS3DataProvider amazonS3DataProvider, - AccountCredentialsRepository accountCredentialsRepository, - ObjectMapper objectMapper, - EddaApiFactory eddaApiFactory, - ApplicationContext ctx, - Registry registry, - Optional reservationReportPool, - Optional> agentProviders, - EddaTimeoutConfig eddaTimeoutConfig, - DynamicConfigService dynamicConfigService) { - def awsProvider = - new AwsProvider(accountCredentialsRepository, Collections.newSetFromMap(new ConcurrentHashMap())) - - synchronizeAwsProvider(awsProvider, - amazonCloudProvider, - amazonClientProvider, - amazonS3DataProvider, - accountCredentialsRepository, - objectMapper, - eddaApiFactory, - ctx, - registry, - reservationReportPool, - agentProviders.orElse(Collections.emptyList()), - eddaTimeoutConfig, - dynamicConfigService) - - awsProvider + AwsProvider awsProvider(CredentialsRepository accountCredentialsRepository) { + return new AwsProvider(accountCredentialsRepository) } @Bean @@ -104,113 +51,4 @@ class AwsProviderConfig { .setNameFormat(ReservationReport.class.getSimpleName() + "-%d") .build()); } - - private void synchronizeAwsProvider(AwsProvider awsProvider, - AmazonCloudProvider amazonCloudProvider, - AmazonClientProvider amazonClientProvider, - AmazonS3DataProvider amazonS3DataProvider, - AccountCredentialsRepository accountCredentialsRepository, - ObjectMapper objectMapper, - EddaApiFactory eddaApiFactory, - ApplicationContext ctx, - Registry registry, - Optional reservationReportPool, - Collection agentProviders, - EddaTimeoutConfig eddaTimeoutConfig, - DynamicConfigService dynamicConfigService) { - def scheduledAccounts = ProviderUtils.getScheduledAccounts(awsProvider) - Set allAccounts = ProviderUtils.buildThreadSafeSetOfAccounts(accountCredentialsRepository, NetflixAmazonCredentials, AmazonCloudProvider.ID) - - List newlyAddedAgents = [] - - //only index public images once per region - Set publicRegions = [] - - //sort the accounts in case of a reconfigure, we are more likely to re-index the public images in the same caching agent - //TODO(cfieber)-rework this is after rework of AWS Image/NamedImage keys - allAccounts.sort { it.name }.each { NetflixAmazonCredentials credentials -> - for (AmazonCredentials.AWSRegion region : credentials.regions) { - if (!scheduledAccounts.contains(credentials.name)) { - newlyAddedAgents << new ClusterCachingAgent(amazonCloudProvider, amazonClientProvider, credentials, region.name, objectMapper, registry, eddaTimeoutConfig) - newlyAddedAgents << new LaunchConfigCachingAgent(amazonClientProvider, credentials, region.name, objectMapper, registry) - newlyAddedAgents << new ImageCachingAgent(amazonClientProvider, credentials, region.name, objectMapper, registry, false, dynamicConfigService) - if (!publicRegions.contains(region.name)) { - newlyAddedAgents << new ImageCachingAgent(amazonClientProvider, credentials, region.name, objectMapper, registry, true, dynamicConfigService) - publicRegions.add(region.name) - } - newlyAddedAgents << new InstanceCachingAgent(amazonClientProvider, credentials, region.name, objectMapper, registry) - newlyAddedAgents << new AmazonLoadBalancerCachingAgent(amazonCloudProvider, amazonClientProvider, credentials, region.name, eddaApiFactory.createApi(credentials.edda, region.name), objectMapper, registry) - newlyAddedAgents << new AmazonApplicationLoadBalancerCachingAgent(amazonCloudProvider, amazonClientProvider, credentials, region.name, eddaApiFactory.createApi(credentials.edda, region.name), objectMapper, registry, eddaTimeoutConfig) - newlyAddedAgents << new ReservedInstancesCachingAgent(amazonClientProvider, credentials, region.name, objectMapper, registry) - newlyAddedAgents << new AmazonCertificateCachingAgent(amazonClientProvider, credentials, region.name, objectMapper, registry) - - if (dynamicConfigService.isEnabled("aws.features.cloud-formation", false)) { - newlyAddedAgents << new AmazonCloudFormationCachingAgent(amazonClientProvider, credentials, region.name, registry) - } - - if (credentials.eddaEnabled && !eddaTimeoutConfig.disabledRegions.contains(region.name)) { - newlyAddedAgents << new EddaLoadBalancerCachingAgent(eddaApiFactory.createApi(credentials.edda, region.name), credentials, region.name, objectMapper) - } else { - newlyAddedAgents << new AmazonLoadBalancerInstanceStateCachingAgent( - amazonClientProvider, credentials, region.name, objectMapper, ctx - ) - } - - if (dynamicConfigService.isEnabled("aws.features.launch-templates", false)) { - newlyAddedAgents << new AmazonLaunchTemplateCachingAgent(amazonClientProvider, credentials, region.name, objectMapper, registry) - } - } - } - } - - // If there is an agent scheduler, then this provider has been through the AgentController in the past. - if (reservationReportPool.isPresent()) { - if (awsProvider.agentScheduler) { - synchronizeReservationReportCachingAgentAccounts(awsProvider, allAccounts) - } else { - // This caching agent runs across all accounts in one iteration (to maintain consistency). - newlyAddedAgents << new ReservationReportCachingAgent( - registry, amazonClientProvider, amazonS3DataProvider, allAccounts, objectMapper, reservationReportPool.get(), ctx - ) - } - } - - agentProviders.findAll { it.supports(AwsProvider.PROVIDER_NAME) }.each { - newlyAddedAgents.addAll(it.agents()) - } - - awsProvider.agents.addAll(newlyAddedAgents) - awsProvider.synchronizeHealthAgents() - } - - private static void synchronizeReservationReportCachingAgentAccounts(AwsProvider awsProvider, - Collection allAccounts) { - ReservationReportCachingAgent reservationReportCachingAgent = awsProvider.agents.find { agent -> - agent instanceof ReservationReportCachingAgent - } - - if (reservationReportCachingAgent) { - def reservationReportAccounts = reservationReportCachingAgent.accounts - def oldAccountNames = reservationReportAccounts.collect { it.name } - def newAccountNames = allAccounts.collect { it.name } - def accountNamesToDelete = oldAccountNames - newAccountNames - def accountNamesToAdd = newAccountNames - oldAccountNames - - accountNamesToDelete.each { accountNameToDelete -> - def accountToDelete = reservationReportAccounts.find { it.name == accountNameToDelete } - - if (accountToDelete) { - reservationReportAccounts.remove(accountToDelete) - } - } - - accountNamesToAdd.each { accountNameToAdd -> - def accountToAdd = allAccounts.find { it.name == accountNameToAdd } - - if (accountToAdd) { - reservationReportAccounts.add(accountToAdd) - } - } - } - } } diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/view/AmazonCloudMetricProvider.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/view/AmazonCloudMetricProvider.groovy index 0f82abbe445..a7962b01487 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/view/AmazonCloudMetricProvider.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/view/AmazonCloudMetricProvider.groovy @@ -17,19 +17,14 @@ package com.netflix.spinnaker.clouddriver.aws.provider.view import com.amazonaws.services.cloudwatch.AmazonCloudWatch -import com.amazonaws.services.cloudwatch.model.Dimension -import com.amazonaws.services.cloudwatch.model.DimensionFilter -import com.amazonaws.services.cloudwatch.model.GetMetricStatisticsRequest -import com.amazonaws.services.cloudwatch.model.GetMetricStatisticsResult -import com.amazonaws.services.cloudwatch.model.ListMetricsRequest +import com.amazonaws.services.cloudwatch.model.* import com.netflix.spinnaker.clouddriver.aws.AmazonCloudProvider -import com.netflix.spinnaker.clouddriver.aws.model.AmazonMetricDatapoint import com.netflix.spinnaker.clouddriver.aws.model.AmazonMetricDescriptor import com.netflix.spinnaker.clouddriver.aws.model.AmazonMetricStatistics import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials import com.netflix.spinnaker.clouddriver.model.CloudMetricProvider -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider +import com.netflix.spinnaker.credentials.CredentialsRepository import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component @@ -37,15 +32,15 @@ import org.springframework.stereotype.Component class AmazonCloudMetricProvider implements CloudMetricProvider { final AmazonClientProvider amazonClientProvider - final AccountCredentialsProvider accountCredentialsProvider + final CredentialsRepository credentialsRepository final AmazonCloudProvider amazonCloudProvider @Autowired AmazonCloudMetricProvider(AmazonClientProvider amazonClientProvider, - AccountCredentialsProvider accountCredentialsProvider, + CredentialsRepository credentialsRepository, AmazonCloudProvider amazonCloudProvider) { this.amazonClientProvider = amazonClientProvider - this.accountCredentialsProvider = accountCredentialsProvider + this.credentialsRepository = credentialsRepository this.amazonCloudProvider = amazonCloudProvider } @@ -120,7 +115,7 @@ class AmazonCloudMetricProvider implements CloudMetricProvider { @@ -52,7 +50,7 @@ class AmazonInstanceProvider implements InstanceProvider AmazonClientProvider amazonClientProvider @Autowired - AccountCredentialsProvider accountCredentialsProvider + CredentialsRepository credentialsRepository @Override AmazonInstance getInstance(String account, String region, String id) { @@ -86,7 +84,7 @@ class AmazonInstanceProvider implements InstanceProvider } String getConsoleOutput(String account, String region, String id) { - def credentials = accountCredentialsProvider.getCredentials(account) + def credentials = credentialsRepository.getOne(account) if (!(credentials instanceof NetflixAmazonCredentials)) { throw new IllegalArgumentException("Invalid credentials: ${account}:${region}") } diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/view/AmazonS3DataProvider.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/view/AmazonS3DataProvider.java index d77ffe32fad..9466a58cf2e 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/view/AmazonS3DataProvider.java +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/view/AmazonS3DataProvider.java @@ -16,7 +16,8 @@ package com.netflix.spinnaker.clouddriver.aws.provider.view; -import static com.netflix.spinnaker.clouddriver.aws.provider.view.AmazonS3StaticDataProviderConfiguration.*; +import static com.netflix.spinnaker.clouddriver.aws.provider.view.AmazonS3StaticDataProviderConfiguration.AdhocRecord; +import static com.netflix.spinnaker.clouddriver.aws.provider.view.AmazonS3StaticDataProviderConfiguration.StaticRecord; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.model.S3Object; @@ -29,7 +30,7 @@ import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials; import com.netflix.spinnaker.clouddriver.model.DataProvider; import com.netflix.spinnaker.clouddriver.security.AccountCredentials; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository; +import com.netflix.spinnaker.credentials.CredentialsRepository; import java.io.IOException; import java.io.OutputStream; import java.util.List; @@ -49,7 +50,7 @@ public class AmazonS3DataProvider implements DataProvider { private final ObjectMapper objectMapper; private final AmazonClientProvider amazonClientProvider; - private final AccountCredentialsRepository accountCredentialsRepository; + private final CredentialsRepository accountCredentialsRepository; private final AmazonS3StaticDataProviderConfiguration configuration; private final Set supportedIdentifiers; @@ -84,7 +85,7 @@ public Object load(String id) throws IOException { public AmazonS3DataProvider( @Qualifier("amazonObjectMapper") ObjectMapper objectMapper, AmazonClientProvider amazonClientProvider, - AccountCredentialsRepository accountCredentialsRepository, + CredentialsRepository accountCredentialsRepository, AmazonS3StaticDataProviderConfiguration configuration) { this.objectMapper = objectMapper; this.amazonClientProvider = amazonClientProvider; diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/view/AmazonSecurityGroupProvider.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/view/AmazonSecurityGroupProvider.groovy index 60b971113ef..d548f32432e 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/view/AmazonSecurityGroupProvider.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/view/AmazonSecurityGroupProvider.groovy @@ -28,12 +28,13 @@ import com.netflix.spinnaker.clouddriver.aws.AmazonCloudProvider import com.netflix.spinnaker.clouddriver.aws.cache.Keys import com.netflix.spinnaker.clouddriver.aws.model.AmazonSecurityGroup import com.netflix.spinnaker.clouddriver.aws.security.AmazonCredentials +import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials import com.netflix.spinnaker.clouddriver.model.AddressableRange import com.netflix.spinnaker.clouddriver.model.SecurityGroupProvider import com.netflix.spinnaker.clouddriver.model.securitygroups.IpRangeRule import com.netflix.spinnaker.clouddriver.model.securitygroups.Rule import com.netflix.spinnaker.clouddriver.model.securitygroups.SecurityGroupRule -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider +import com.netflix.spinnaker.credentials.CredentialsRepository import groovy.transform.Canonical import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Qualifier @@ -45,20 +46,20 @@ import static com.netflix.spinnaker.clouddriver.aws.cache.Keys.Namespace.SECURIT class AmazonSecurityGroupProvider implements SecurityGroupProvider { final String cloudProvider = AmazonCloudProvider.ID - final AccountCredentialsProvider accountCredentialsProvider + final CredentialsRepository credentialsRepository final Cache cacheView final ObjectMapper objectMapper final Set accounts @Autowired - AmazonSecurityGroupProvider(AccountCredentialsProvider accountCredentialsProvider, + AmazonSecurityGroupProvider(CredentialsRepository credentialsRepository, Cache cacheView, @Qualifier("amazonObjectMapper") ObjectMapper objectMapper) { - this.accountCredentialsProvider = accountCredentialsProvider + this.credentialsRepository = credentialsRepository this.cacheView = cacheView this.objectMapper = objectMapper - final allAmazonCredentials = (Set) accountCredentialsProvider.all.findAll { + final allAmazonCredentials = (Set) credentialsRepository.getAll().findAll { it instanceof AmazonCredentials } accounts = ImmutableSet.copyOf(allAmazonCredentials) diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/AmazonAccountsSynchronizer.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/AmazonAccountsSynchronizer.groovy deleted file mode 100644 index f00687b46ce..00000000000 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/AmazonAccountsSynchronizer.groovy +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2020 Armory - * - * 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. - */ - -package com.netflix.spinnaker.clouddriver.aws.security - -import com.netflix.spinnaker.cats.module.CatsModule -import com.netflix.spinnaker.clouddriver.aws.security.config.CredentialsConfig -import com.netflix.spinnaker.clouddriver.aws.security.config.CredentialsLoader -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository - -interface AmazonAccountsSynchronizer { - - List synchronize( - CredentialsLoader credentialsLoader, - CredentialsConfig credentialsConfig, AccountCredentialsRepository accountCredentialsRepository, - DefaultAccountConfigurationProperties defaultAccountConfigurationProperties, - CatsModule catsModule) -} diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/AmazonBasicCredentialsLoader.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/AmazonBasicCredentialsLoader.java new file mode 100644 index 00000000000..0f81e88391e --- /dev/null +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/AmazonBasicCredentialsLoader.java @@ -0,0 +1,100 @@ +/* + * Copyright 2020 Netflix, 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. + * + */ + +package com.netflix.spinnaker.clouddriver.aws.security; + +import com.amazonaws.SDKGlobalConfiguration; +import com.amazonaws.regions.Regions; +import com.amazonaws.util.CollectionUtils; +import com.netflix.spinnaker.clouddriver.aws.security.config.CredentialsConfig; +import com.netflix.spinnaker.credentials.CredentialsRepository; +import com.netflix.spinnaker.credentials.definition.BasicCredentialsLoader; +import com.netflix.spinnaker.credentials.definition.CredentialsDefinitionSource; +import com.netflix.spinnaker.credentials.definition.CredentialsParser; +import java.util.*; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; + +public class AmazonBasicCredentialsLoader< + T extends CredentialsConfig.Account, U extends NetflixAmazonCredentials> + extends BasicCredentialsLoader { + protected final CredentialsConfig credentialsConfig; + protected final DefaultAccountConfigurationProperties defaultAccountConfigurationProperties; + protected String defaultEnvironment; + protected String defaultAccountType; + + public AmazonBasicCredentialsLoader( + CredentialsDefinitionSource definitionSource, + CredentialsParser parser, + CredentialsRepository credentialsRepository, + CredentialsConfig credentialsConfig, + DefaultAccountConfigurationProperties defaultAccountConfigurationProperties) { + super(definitionSource, parser, credentialsRepository); + this.credentialsConfig = credentialsConfig; + this.defaultAccountConfigurationProperties = defaultAccountConfigurationProperties; + this.defaultEnvironment = + defaultAccountConfigurationProperties.getEnvironment() != null + ? defaultAccountConfigurationProperties.getEnvironment() + : defaultAccountConfigurationProperties.getEnv(); + this.defaultAccountType = + defaultAccountConfigurationProperties.getAccountType() != null + ? defaultAccountConfigurationProperties.getAccountType() + : defaultAccountConfigurationProperties.getEnv(); + if (!StringUtils.isEmpty(credentialsConfig.getAccessKeyId())) { + System.setProperty( + SDKGlobalConfiguration.ACCESS_KEY_SYSTEM_PROPERTY, credentialsConfig.getAccessKeyId()); + } + if (!StringUtils.isEmpty(credentialsConfig.getSecretAccessKey())) { + System.setProperty( + SDKGlobalConfiguration.SECRET_KEY_SYSTEM_PROPERTY, + credentialsConfig.getSecretAccessKey()); + } + } + + @Override + public void load() { + if (CollectionUtils.isNullOrEmpty(credentialsConfig.getAccounts()) + && (StringUtils.isEmpty(credentialsConfig.getDefaultAssumeRole()))) { + credentialsConfig.setAccounts( + Collections.singletonList( + new CredentialsConfig.Account() { + { + setName(defaultAccountConfigurationProperties.getEnv()); + setEnvironment(defaultEnvironment); + setAccountType(defaultAccountType); + } + })); + if (CollectionUtils.isNullOrEmpty(credentialsConfig.getDefaultRegions())) { + List regions = + new ArrayList<>( + Arrays.asList( + Regions.US_EAST_1, Regions.US_WEST_1, Regions.US_WEST_2, Regions.EU_WEST_1)); + credentialsConfig.setDefaultRegions( + regions.stream() + .map( + it -> + new CredentialsConfig.Region() { + { + setName(it.getName()); + } + }) + .collect(Collectors.toList())); + } + } + this.parse(definitionSource.getCredentialsDefinitions()); + } +} diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/AmazonCredentialsInitializer.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/AmazonCredentialsInitializer.groovy index 4e943cec845..5277f101e4d 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/AmazonCredentialsInitializer.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/AmazonCredentialsInitializer.groovy @@ -17,14 +17,28 @@ package com.netflix.spinnaker.clouddriver.aws.security import com.amazonaws.auth.AWSCredentialsProvider +import com.netflix.spinnaker.clouddriver.aws.AmazonCloudProvider +import com.netflix.spinnaker.clouddriver.aws.security.config.AmazonCredentialsParser import com.netflix.spinnaker.clouddriver.aws.security.config.CredentialsConfig -import com.netflix.spinnaker.clouddriver.aws.security.config.CredentialsLoader -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository +import com.netflix.spinnaker.clouddriver.aws.security.config.CredentialsConfig.Account +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.CredentialsDefinitionSource +import com.netflix.spinnaker.credentials.definition.CredentialsParser +import com.netflix.spinnaker.credentials.poller.Poller import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.context.properties.ConfigurationProperties import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.DependsOn +import org.springframework.context.annotation.Lazy +import org.springframework.context.annotation.Primary + +import javax.annotation.Nullable @Configuration @EnableConfigurationProperties(DefaultAccountConfigurationProperties) @@ -38,7 +52,9 @@ class AmazonCredentialsInitializer { } @Bean - Class credentialsType(CredentialsConfig credentialsConfig) { + Class credentialsType( + CredentialsConfig credentialsConfig + ) { if (!credentialsConfig.accounts && !credentialsConfig.defaultAssumeRole) { NetflixAmazonCredentials } else { @@ -47,28 +63,65 @@ class AmazonCredentialsInitializer { } @Bean - @ConditionalOnMissingBean(CredentialsLoader.class) - CredentialsLoader credentialsLoader(AWSCredentialsProvider awsCredentialsProvider, - AmazonClientProvider amazonClientProvider, - Class credentialsType) { - new CredentialsLoader(awsCredentialsProvider, amazonClientProvider, credentialsType) + CredentialsParser amazonCredentialsParser( + AWSCredentialsProvider awsCredentialsProvider, + AmazonClientProvider amazonClientProvider, + Class credentialsType, CredentialsConfig credentialsConfig + ) { + new AmazonCredentialsParser<>(awsCredentialsProvider, amazonClientProvider, credentialsType, credentialsConfig) } @Bean - @ConditionalOnMissingBean(AmazonAccountsSynchronizer.class) - AmazonAccountsSynchronizer amazonAccountsSynchronizer() { - new DefaultAmazonAccountsSynchronizer() + @Primary + @ConditionalOnMissingBean( + value = NetflixAmazonCredentials.class, + parameterizedContainer = CredentialsRepository.class + ) + CredentialsRepository amazonCredentialsRepository( + @Lazy CredentialsLifecycleHandler eventHandler + ) { + return new MapBackedCredentialsRepository(AmazonCloudProvider.ID, eventHandler) } @Bean - List netflixAmazonCredentials( - CredentialsLoader credentialsLoader, + @ConditionalOnMissingBean( + value = NetflixAmazonCredentials.class, + parameterizedContainer = AbstractCredentialsLoader.class + ) + AbstractCredentialsLoader amazonCredentialsLoader( + CredentialsParser amazonCredentialsParser, + @Nullable CredentialsDefinitionSource amazonCredentialsSource, CredentialsConfig credentialsConfig, - AccountCredentialsRepository accountCredentialsRepository, - DefaultAccountConfigurationProperties defaultAccountConfigurationProperties, - AmazonAccountsSynchronizer amazonAccountsSynchronizer) { - - amazonAccountsSynchronizer.synchronize(credentialsLoader, credentialsConfig, accountCredentialsRepository, defaultAccountConfigurationProperties, null) + CredentialsRepository repository, + DefaultAccountConfigurationProperties defaultAccountConfigurationProperties + ) { + if (amazonCredentialsSource == null) { + amazonCredentialsSource = { -> credentialsConfig.getAccounts() } as CredentialsDefinitionSource + } + return new AmazonBasicCredentialsLoader( + amazonCredentialsSource, + amazonCredentialsParser, + repository, + credentialsConfig, + defaultAccountConfigurationProperties + ) } + @Bean + @DependsOn("amazonCredentialsLifecycleHandler") + @ConditionalOnMissingBean( + value = Account.class, + parameterizedContainer = CredentialsDefinitionSource.class + ) + CredentialsInitializerSynchronizable amazonCredentialsInitializerSynchronizable( + AbstractCredentialsLoader amazonCredentialsLoader + ) { + final Poller poller = new Poller<>(amazonCredentialsLoader); + return new CredentialsInitializerSynchronizable() { + @Override + void synchronize() { + poller.run() + } + } + } } diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/AmazonCredentialsLifecycleHandler.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/AmazonCredentialsLifecycleHandler.java new file mode 100644 index 00000000000..7d85eb352ce --- /dev/null +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/AmazonCredentialsLifecycleHandler.java @@ -0,0 +1,189 @@ +/* + * Copyright 2020 Netflix, 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. + * + */ + +package com.netflix.spinnaker.clouddriver.aws.security; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.netflix.spectator.api.Registry; +import com.netflix.spinnaker.cats.agent.Agent; +import com.netflix.spinnaker.cats.agent.AgentProvider; +import com.netflix.spinnaker.cats.module.CatsModule; +import com.netflix.spinnaker.clouddriver.aws.AmazonCloudProvider; +import com.netflix.spinnaker.clouddriver.aws.AwsConfigurationProperties; +import com.netflix.spinnaker.clouddriver.aws.edda.EddaApiFactory; +import com.netflix.spinnaker.clouddriver.aws.provider.AwsCleanupProvider; +import com.netflix.spinnaker.clouddriver.aws.provider.AwsInfrastructureProvider; +import com.netflix.spinnaker.clouddriver.aws.provider.AwsProvider; +import com.netflix.spinnaker.clouddriver.aws.provider.ProviderHelpers; +import com.netflix.spinnaker.clouddriver.aws.provider.agent.ReservationReportCachingAgent; +import com.netflix.spinnaker.clouddriver.aws.provider.view.AmazonS3DataProvider; +import com.netflix.spinnaker.config.AwsConfiguration.DeployDefaults; +import com.netflix.spinnaker.credentials.CredentialsLifecycleHandler; +import com.netflix.spinnaker.credentials.CredentialsRepository; +import com.netflix.spinnaker.kork.dynamicconfig.DynamicConfigService; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +@Component +@Lazy +@Slf4j +@RequiredArgsConstructor +public class AmazonCredentialsLifecycleHandler + implements CredentialsLifecycleHandler { + private final AwsCleanupProvider awsCleanupProvider; + private final AwsInfrastructureProvider awsInfrastructureProvider; + private final AwsProvider awsProvider; + private final AmazonCloudProvider amazonCloudProvider; + private final AmazonClientProvider amazonClientProvider; + private final AmazonS3DataProvider amazonS3DataProvider; + private final CatsModule catsModule; + + private final AwsConfigurationProperties awsConfigurationProperties; + private final ObjectMapper objectMapper; + private final @Qualifier("amazonObjectMapper") ObjectMapper amazonObjectMapper; + private final EddaApiFactory eddaApiFactory; + private final ApplicationContext ctx; + private final Registry registry; + private final Optional reservationReportPool; + private final Optional> agentProviders; + private final EddaTimeoutConfig eddaTimeoutConfig; + private final DynamicConfigService dynamicConfigService; + private final DeployDefaults deployDefaults; + private final CredentialsRepository + accountCredentialsRepository; // Circular dependency. + private Set publicRegions = new HashSet<>(); + private Set awsInfraRegions = new HashSet<>(); + + @Override + public void credentialsAdded(@NotNull NetflixAmazonCredentials credentials) { + scheduleAgents(credentials); + synchronizeReservationReportCachingAgentAccounts(credentials, true); + } + + @Override + public void credentialsUpdated(@NotNull NetflixAmazonCredentials credentials) { + // TODO(nimak) - ensure that unscheduling does what is exptected in removing the right agents + // TODO - this is to be tested against the old behavior + unscheduleAgents(credentials); + scheduleAgents(credentials); + synchronizeReservationReportCachingAgentAccounts(credentials, true); + } + + @Override + public void credentialsDeleted(NetflixAmazonCredentials credentials) { + // TODO(nimak) - ensure that unscheduling does what is exptected in removing the right agents + // TODO - this is to be tested against the old behavior + unscheduleAgents(credentials); + synchronizeReservationReportCachingAgentAccounts(credentials, false); + } + + private void unscheduleAgents(NetflixAmazonCredentials credentials) { + awsInfrastructureProvider.removeAgentsForAccounts(Collections.singleton(credentials.getName())); + awsCleanupProvider.removeAgentsForAccounts(Collections.singleton(credentials.getName())); + awsProvider.removeAgentsForAccounts(Collections.singleton(credentials.getName())); + } + + private void scheduleAgents(NetflixAmazonCredentials credentials) { + scheduleAWSProviderAgents(credentials); + scheduleAwsInfrastructureProviderAgents(credentials); + scheduleAwsCleanupAgents(credentials); + } + + private void scheduleAwsInfrastructureProviderAgents(NetflixAmazonCredentials credentials) { + ProviderHelpers.BuildResult result = + ProviderHelpers.buildAwsInfrastructureAgents( + credentials, + awsInfrastructureProvider, + accountCredentialsRepository, + amazonClientProvider, + amazonObjectMapper, + registry, + eddaTimeoutConfig, + this.awsInfraRegions); + awsInfrastructureProvider.addAgents(result.getAgents()); + this.awsInfraRegions.addAll(result.getRegionsToAdd()); + } + + private void scheduleAWSProviderAgents(NetflixAmazonCredentials credentials) { + // parallel safe? + ProviderHelpers.BuildResult buildResult = + ProviderHelpers.buildAwsProviderAgents( + credentials, + accountCredentialsRepository, + amazonClientProvider, + objectMapper, + registry, + eddaTimeoutConfig, + awsProvider, + amazonCloudProvider, + dynamicConfigService, + eddaApiFactory, + reservationReportPool, + agentProviders, + ctx, + amazonS3DataProvider, + publicRegions); + + awsProvider.addAgents(buildResult.getAgents()); + this.publicRegions.addAll(buildResult.getRegionsToAdd()); + awsProvider.synchronizeHealthAgents(); + } + + private void scheduleAwsCleanupAgents(NetflixAmazonCredentials credentials) { + List newlyAddedAgents = + ProviderHelpers.buildAwsCleanupAgents( + credentials, + accountCredentialsRepository, + amazonClientProvider, + awsCleanupProvider, + deployDefaults, + awsConfigurationProperties); + + awsCleanupProvider.addAgents(newlyAddedAgents); + } + + // This needs to be moved else where. + private void synchronizeReservationReportCachingAgentAccounts( + NetflixAmazonCredentials credentials, boolean add) { + ReservationReportCachingAgent reservationReportCachingAgent = + awsProvider.getAgents().stream() + .filter(agent -> agent instanceof ReservationReportCachingAgent) + .map(ReservationReportCachingAgent.class::cast) + .findFirst() + .orElse(null); + if (reservationReportCachingAgent != null) { + Collection reservationReportAccounts = + reservationReportCachingAgent.getAccounts(); + reservationReportAccounts.removeIf(it -> it.getName().equals(credentials.getName())); + if (add) { + reservationReportAccounts.add(credentials); + } + } + } +} diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/DefaultAmazonAccountsSynchronizer.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/DefaultAmazonAccountsSynchronizer.groovy deleted file mode 100644 index 3a1113adf40..00000000000 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/DefaultAmazonAccountsSynchronizer.groovy +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2020 Armory - * - * 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. - */ - -package com.netflix.spinnaker.clouddriver.aws.security - -import com.netflix.spinnaker.cats.module.CatsModule -import com.netflix.spinnaker.clouddriver.aws.security.config.CredentialsConfig -import com.netflix.spinnaker.clouddriver.aws.security.config.CredentialsLoader -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository -import com.netflix.spinnaker.clouddriver.security.ProviderUtils - -import static com.amazonaws.regions.Regions.* - -class DefaultAmazonAccountsSynchronizer implements AmazonAccountsSynchronizer { - - List synchronize( - CredentialsLoader credentialsLoader, - CredentialsConfig credentialsConfig, - AccountCredentialsRepository accountCredentialsRepository, - DefaultAccountConfigurationProperties defaultAccountConfigurationProperties, - CatsModule catsModule) { - if (!credentialsConfig.accounts && !credentialsConfig.defaultAssumeRole) { - def defaultEnvironment = defaultAccountConfigurationProperties.environment ?: defaultAccountConfigurationProperties.env - def defaultAccountType = defaultAccountConfigurationProperties.accountType ?: defaultAccountConfigurationProperties.env - credentialsConfig.accounts = [new CredentialsConfig.Account(name: defaultAccountConfigurationProperties.env, environment: defaultEnvironment, accountType: defaultAccountType)] - if (!credentialsConfig.defaultRegions) { - credentialsConfig.defaultRegions = [US_EAST_1, US_WEST_1, US_WEST_2, EU_WEST_1].collect { - new CredentialsConfig.Region(name: it.name) - } - } - } - - List accounts = credentialsLoader.load(credentialsConfig) - - def (ArrayList accountsToAdd, List namesOfDeletedAccounts) = - ProviderUtils.calculateAccountDeltas(accountCredentialsRepository, NetflixAmazonCredentials, accounts) - - accountsToAdd.each { NetflixAmazonCredentials account -> - accountCredentialsRepository.save(account.name, account) - } - - ProviderUtils.unscheduleAndDeregisterAgents(namesOfDeletedAccounts, catsModule) - - accountCredentialsRepository.all.findAll { - it instanceof NetflixAmazonCredentials - } as List - } - -} diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/config/CredentialsLoader.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/config/AmazonCredentialsParser.java similarity index 63% rename from clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/config/CredentialsLoader.java rename to clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/config/AmazonCredentialsParser.java index 7ec05fadddf..b041bba3cc9 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/config/CredentialsLoader.java +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/config/AmazonCredentialsParser.java @@ -1,31 +1,29 @@ /* - * Copyright 2015 Netflix, Inc. + * Copyright 2020 Netflix, 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 + * 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. + * */ package com.netflix.spinnaker.clouddriver.aws.security.config; -import com.amazonaws.SDKGlobalConfiguration; import com.amazonaws.auth.AWSCredentialsProvider; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import com.netflix.spinnaker.clouddriver.aws.security.AWSAccountInfoLookup; -import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider; -import com.netflix.spinnaker.clouddriver.aws.security.AmazonCredentials; -import com.netflix.spinnaker.clouddriver.aws.security.DefaultAWSAccountInfoLookup; +import com.netflix.spinnaker.clouddriver.aws.security.*; import com.netflix.spinnaker.clouddriver.aws.security.config.CredentialsConfig.Account; import com.netflix.spinnaker.clouddriver.aws.security.config.CredentialsConfig.Region; +import com.netflix.spinnaker.credentials.definition.CredentialsParser; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.*; @@ -33,60 +31,31 @@ import java.util.function.Function; import java.util.regex.Pattern; import java.util.stream.Collectors; -import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public class CredentialsLoader { +public class AmazonCredentialsParser + implements CredentialsParser { private final AWSCredentialsProvider credentialsProvider; private final AWSAccountInfoLookup awsAccountInfoLookup; private final Map templateValues; - private final CredentialTranslator credentialTranslator; + private final CredentialTranslator credentialTranslator; private final ObjectMapper objectMapper; + private final CredentialsConfig credentialsConfig; - public CredentialsLoader( - AWSCredentialsProvider credentialsProvider, - AmazonClientProvider amazonClientProvider, - Class credentialsType) { - this( - credentialsProvider, - amazonClientProvider, - credentialsType, - Collections.emptyMap()); - } - - public CredentialsLoader( + public AmazonCredentialsParser( AWSCredentialsProvider credentialsProvider, AmazonClientProvider amazonClientProvider, - Class credentialsType, - Map templateValues) { - this( - credentialsProvider, - new DefaultAWSAccountInfoLookup(credentialsProvider, amazonClientProvider), - credentialsType, - templateValues); - } - - public CredentialsLoader( - AWSCredentialsProvider credentialsProvider, - AWSAccountInfoLookup awsAccountInfoLookup, - Class credentialsType) { - this( - credentialsProvider, - awsAccountInfoLookup, - credentialsType, - Collections.emptyMap()); - } - - public CredentialsLoader( - AWSCredentialsProvider credentialsProvider, - AWSAccountInfoLookup awsAccountInfoLookup, - Class credentialsType, - Map templateValues) { + Class credentialsType, + CredentialsConfig credentialsConfig) { this.credentialsProvider = Objects.requireNonNull(credentialsProvider, "credentialsProvider"); - this.awsAccountInfoLookup = awsAccountInfoLookup; - this.templateValues = templateValues; + this.awsAccountInfoLookup = + new DefaultAWSAccountInfoLookup(credentialsProvider, amazonClientProvider); + this.templateValues = Collections.emptyMap(); this.objectMapper = new ObjectMapper(); this.credentialTranslator = findTranslator(credentialsType, this.objectMapper); + this.credentialsConfig = credentialsConfig; } private Lazy> createDefaults(final List defaults) { @@ -142,7 +111,9 @@ private List initRegions(Lazy> defaults, List toIni } for (Iterator lookups = toLookup.iterator(); lookups.hasNext(); ) { - Region fromDefault = find(defaults.get(), lookups.next()); + List r = defaults.get(); + String a = lookups.next(); + Region fromDefault = find(r, a); if (fromDefault != null) { lookups.remove(); result.add(fromDefault); @@ -200,111 +171,119 @@ private static List toRegion(List src) { return result; } - public T load(String accountName) throws Throwable { + public V load(String accountName) throws Throwable { CredentialsConfig config = new CredentialsConfig(); Account account = new Account(); account.setName(accountName); - config.setAccounts(Arrays.asList(account)); - List result = load(config); + config.setAccounts(Collections.singletonList(account)); + List result = load(config); if (result.size() != 1) { throw new IllegalStateException("failed to create account"); } return result.get(0); } - public List load(CredentialsConfig source) throws Throwable { + public List load(CredentialsConfig source) throws Throwable { final CredentialsConfig config = objectMapper.convertValue(source, CredentialsConfig.class); if (config.getAccounts() == null || config.getAccounts().isEmpty()) { return Collections.emptyList(); } - - if (!StringUtils.isEmpty(config.getAccessKeyId())) { - System.setProperty( - SDKGlobalConfiguration.ACCESS_KEY_SYSTEM_PROPERTY, config.getAccessKeyId()); + List initializedAccounts = new ArrayList<>(config.getAccounts().size()); + for (Account account : config.getAccounts()) { + initializedAccounts.add(parseAccount(config, account)); } - if (!StringUtils.isEmpty(config.getSecretAccessKey())) { - System.setProperty( - SDKGlobalConfiguration.SECRET_KEY_SYSTEM_PROPERTY, config.getSecretAccessKey()); + return initializedAccounts.stream() + .filter(AmazonCredentials::isEnabled) + .collect(Collectors.toList()); + } + + @Nullable + @Override + public V parse(@NotNull U account) { + try { + V a = parseAccount(credentialsConfig, account); + if (a.isEnabled()) { + return a; + } + } catch (Throwable t) { + // t.printStackTrace(); + return null; } + return null; + } + + private V parseAccount(CredentialsConfig config, Account account) throws Throwable { Lazy> defaultRegions = createDefaults(config.getDefaultRegions()); - List initializedAccounts = new ArrayList<>(config.getAccounts().size()); - for (Account account : config.getAccounts()) { - if (account.getAccountId() == null) { - if (!credentialTranslator.resolveAccountId()) { - throw new IllegalArgumentException( - "accountId is required and not resolvable for this credentials type"); - } - account.setAccountId(awsAccountInfoLookup.findAccountId()); + if (account.getAccountId() == null) { + if (!credentialTranslator.resolveAccountId()) { + throw new IllegalArgumentException( + "accountId is required and not resolvable for this credentials type"); } + account.setAccountId(awsAccountInfoLookup.findAccountId()); + } - if (account.getEnvironment() == null) { - account.setEnvironment(account.getName()); - } + if (account.getEnvironment() == null) { + account.setEnvironment(account.getName()); + } - if (account.getAccountType() == null) { - account.setAccountType(account.getName()); - } + if (account.getAccountType() == null) { + account.setAccountType(account.getName()); + } - account.setRegions(initRegions(defaultRegions, account.getRegions())); - account.setDefaultSecurityGroups( - account.getDefaultSecurityGroups() != null - ? account.getDefaultSecurityGroups() - : config.getDefaultSecurityGroups()); - account.setLifecycleHooks( - account.getLifecycleHooks() != null - ? account.getLifecycleHooks() - : config.getDefaultLifecycleHooks()); - account.setEnabled(Optional.ofNullable(account.getEnabled()).orElse(true)); - - Map templateContext = new HashMap<>(templateValues); - templateContext.put("name", account.getName()); - templateContext.put("accountId", account.getAccountId()); - templateContext.put("environment", account.getEnvironment()); - templateContext.put("accountType", account.getAccountType()); - - account.setDefaultKeyPair( - templateFirstNonNull( - templateContext, account.getDefaultKeyPair(), config.getDefaultKeyPairTemplate())); - account.setEdda( - templateFirstNonNull( - templateContext, account.getEdda(), config.getDefaultEddaTemplate())); - account.setFront50( - templateFirstNonNull( - templateContext, account.getFront50(), config.getDefaultFront50Template())); - account.setDiscovery( - templateFirstNonNull( - templateContext, account.getDiscovery(), config.getDefaultDiscoveryTemplate())); - account.setAssumeRole( - templateFirstNonNull( - templateContext, account.getAssumeRole(), config.getDefaultAssumeRole())); - account.setSessionName( - templateFirstNonNull( - templateContext, account.getSessionName(), config.getDefaultSessionName())); - account.setBastionHost( - templateFirstNonNull( - templateContext, account.getBastionHost(), config.getDefaultBastionHostTemplate())); - - if (account.getLifecycleHooks() != null) { - for (CredentialsConfig.LifecycleHook lifecycleHook : account.getLifecycleHooks()) { - lifecycleHook.setRoleARN( - templateFirstNonNull( - templateContext, - lifecycleHook.getRoleARN(), - config.getDefaultLifecycleHookRoleARNTemplate())); - lifecycleHook.setNotificationTargetARN( - templateFirstNonNull( - templateContext, - lifecycleHook.getNotificationTargetARN(), - config.getDefaultLifecycleHookNotificationTargetARNTemplate())); - } + account.setRegions(initRegions(defaultRegions, account.getRegions())); + account.setDefaultSecurityGroups( + account.getDefaultSecurityGroups() != null + ? account.getDefaultSecurityGroups() + : config.getDefaultSecurityGroups()); + account.setLifecycleHooks( + account.getLifecycleHooks() != null + ? account.getLifecycleHooks() + : config.getDefaultLifecycleHooks()); + account.setEnabled(Optional.ofNullable(account.getEnabled()).orElse(true)); + + Map templateContext = new HashMap<>(templateValues); + templateContext.put("name", account.getName()); + templateContext.put("accountId", account.getAccountId()); + templateContext.put("environment", account.getEnvironment()); + templateContext.put("accountType", account.getAccountType()); + + account.setDefaultKeyPair( + templateFirstNonNull( + templateContext, account.getDefaultKeyPair(), config.getDefaultKeyPairTemplate())); + account.setEdda( + templateFirstNonNull(templateContext, account.getEdda(), config.getDefaultEddaTemplate())); + account.setFront50( + templateFirstNonNull( + templateContext, account.getFront50(), config.getDefaultFront50Template())); + account.setDiscovery( + templateFirstNonNull( + templateContext, account.getDiscovery(), config.getDefaultDiscoveryTemplate())); + account.setAssumeRole( + templateFirstNonNull( + templateContext, account.getAssumeRole(), config.getDefaultAssumeRole())); + account.setSessionName( + templateFirstNonNull( + templateContext, account.getSessionName(), config.getDefaultSessionName())); + account.setBastionHost( + templateFirstNonNull( + templateContext, account.getBastionHost(), config.getDefaultBastionHostTemplate())); + + if (account.getLifecycleHooks() != null) { + for (CredentialsConfig.LifecycleHook lifecycleHook : account.getLifecycleHooks()) { + lifecycleHook.setRoleARN( + templateFirstNonNull( + templateContext, + lifecycleHook.getRoleARN(), + config.getDefaultLifecycleHookRoleARNTemplate())); + lifecycleHook.setNotificationTargetARN( + templateFirstNonNull( + templateContext, + lifecycleHook.getNotificationTargetARN(), + config.getDefaultLifecycleHookNotificationTargetARNTemplate())); } - - initializedAccounts.add(credentialTranslator.translate(credentialsProvider, account)); } - return initializedAccounts.stream() - .filter(AmazonCredentials::isEnabled) - .collect(Collectors.toList()); + return credentialTranslator.translate(credentialsProvider, account); } private static class Lazy { diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/config/CredentialsConfig.java b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/config/CredentialsConfig.java index 3b42c7489d3..8ca272a8c4b 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/config/CredentialsConfig.java +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/security/config/CredentialsConfig.java @@ -16,6 +16,7 @@ package com.netflix.spinnaker.clouddriver.aws.security.config; +import com.netflix.spinnaker.credentials.definition.CredentialsDefinition; import com.netflix.spinnaker.fiat.model.resources.Permissions; import java.util.List; @@ -62,7 +63,7 @@ public void setDeprecated(Boolean deprecated) { this.deprecated = deprecated; } - Region copyOf() { + public Region copyOf() { Region clone = new Region(); clone.setName(getName()); clone.setAvailabilityZones(getAvailabilityZones()); @@ -130,7 +131,7 @@ public void setDefaultResult(String defaultResult) { } } - public static class Account { + public static class Account implements CredentialsDefinition { private String name; private String environment; private String accountType; diff --git a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/config/AwsConfiguration.groovy b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/config/AwsConfiguration.groovy index 36d3f0277ed..a3897c8ffaa 100644 --- a/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/config/AwsConfiguration.groovy +++ b/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/config/AwsConfiguration.groovy @@ -22,11 +22,7 @@ import com.fasterxml.jackson.databind.ObjectMapper import com.netflix.awsobjectmapper.AmazonObjectMapperConfigurer import com.netflix.spectator.api.Registry import com.netflix.spinnaker.cats.agent.Agent -import com.netflix.spinnaker.clouddriver.aws.AmazonCloudProvider import com.netflix.spinnaker.clouddriver.aws.AwsConfigurationProperties -import com.netflix.spinnaker.clouddriver.aws.agent.CleanupAlarmsAgent -import com.netflix.spinnaker.clouddriver.aws.agent.CleanupDetachedInstancesAgent -import com.netflix.spinnaker.clouddriver.aws.agent.ReconcileClassicLinkSecurityGroupsAgent import com.netflix.spinnaker.clouddriver.aws.deploy.BlockDeviceConfig import com.netflix.spinnaker.clouddriver.aws.deploy.handlers.BasicAmazonDeployHandler import com.netflix.spinnaker.clouddriver.aws.deploy.ops.securitygroup.SecurityGroupLookupFactory @@ -49,7 +45,7 @@ import com.netflix.spinnaker.clouddriver.core.limits.ServiceLimitConfiguration import com.netflix.spinnaker.clouddriver.event.SpinnakerEvent import com.netflix.spinnaker.clouddriver.saga.config.SagaAutoConfiguration import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository -import com.netflix.spinnaker.clouddriver.security.ProviderUtils +import com.netflix.spinnaker.credentials.CredentialsRepository import com.netflix.spinnaker.kork.aws.AwsComponents import com.netflix.spinnaker.kork.aws.bastion.BastionConfig import com.netflix.spinnaker.kork.dynamicconfig.DynamicConfigService @@ -184,14 +180,16 @@ class AwsConfiguration { } @Bean - @DependsOn('netflixAmazonCredentials') - BasicAmazonDeployHandler basicAmazonDeployHandler(RegionScopedProviderFactory regionScopedProviderFactory, - AccountCredentialsRepository accountCredentialsRepository, - DeployDefaults deployDefaults, - ScalingPolicyCopier scalingPolicyCopier, - BlockDeviceConfig blockDeviceConfig, - DynamicConfigService dynamicConfigService, - AmazonServerGroupProvider amazonServerGroupProvider) { + @DependsOn('amazonCredentialsRepository') + BasicAmazonDeployHandler basicAmazonDeployHandler( + RegionScopedProviderFactory regionScopedProviderFactory, + CredentialsRepository accountCredentialsRepository, + DeployDefaults deployDefaults, + ScalingPolicyCopier scalingPolicyCopier, + BlockDeviceConfig blockDeviceConfig, + DynamicConfigService dynamicConfigService, + AmazonServerGroupProvider amazonServerGroupProvider + ) { new BasicAmazonDeployHandler( regionScopedProviderFactory, accountCredentialsRepository, @@ -210,56 +208,14 @@ class AwsConfiguration { } @Bean - @DependsOn('netflixAmazonCredentials') - AwsCleanupProvider awsOperationProvider(AwsConfigurationProperties awsConfigurationProperties, - AmazonClientProvider amazonClientProvider, - AccountCredentialsRepository accountCredentialsRepository, - DeployDefaults deployDefaults) { - def awsCleanupProvider = new AwsCleanupProvider(Collections.newSetFromMap(new ConcurrentHashMap())) - - synchronizeAwsCleanupProvider(awsConfigurationProperties, awsCleanupProvider, amazonClientProvider, accountCredentialsRepository, deployDefaults) - - awsCleanupProvider - } - - @Bean - @DependsOn('netflixAmazonCredentials') - SecurityGroupLookupFactory securityGroupLookup(AmazonClientProvider amazonClientProvider, - AccountCredentialsRepository accountCredentialsRepository) { + @DependsOn('amazonCredentialsRepository') + SecurityGroupLookupFactory securityGroupLookup( + AmazonClientProvider amazonClientProvider, + CredentialsRepository accountCredentialsRepository + ) { new SecurityGroupLookupFactory(amazonClientProvider, accountCredentialsRepository) } - private static void synchronizeAwsCleanupProvider(AwsConfigurationProperties awsConfigurationProperties, - AwsCleanupProvider awsCleanupProvider, - AmazonClientProvider amazonClientProvider, - AccountCredentialsRepository accountCredentialsRepository, - DeployDefaults deployDefaults) { - def scheduledAccounts = ProviderUtils.getScheduledAccounts(awsCleanupProvider) - Set allAccounts = ProviderUtils.buildThreadSafeSetOfAccounts(accountCredentialsRepository, NetflixAmazonCredentials, AmazonCloudProvider.ID) - - List newlyAddedAgents = [] - - allAccounts.each { account -> - if (!scheduledAccounts.contains(account)) { - account.regions.each { region -> - if (deployDefaults.isReconcileClassicLinkAccount(account)) { - newlyAddedAgents << new ReconcileClassicLinkSecurityGroupsAgent( - amazonClientProvider, account, region.name, deployDefaults - ) - } - } - } - } - - if (!awsCleanupProvider.agentScheduler) { - if (awsConfigurationProperties.cleanup.alarms.enabled) { - awsCleanupProvider.agents.add(new CleanupAlarmsAgent(amazonClientProvider, accountCredentialsRepository, awsConfigurationProperties.cleanup.alarms.daysToKeep)) - } - awsCleanupProvider.agents.add(new CleanupDetachedInstancesAgent(amazonClientProvider, accountCredentialsRepository)) - } - awsCleanupProvider.agents.addAll(newlyAddedAgents) - } - @Bean AmazonServerGroupProvider amazonServerGroupProvider(ApplicationContext applicationContext) { return new AmazonServerGroupProvider(applicationContext) diff --git a/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/agent/CleanupDetachedInstancesAgentSpec.groovy b/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/agent/CleanupDetachedInstancesAgentSpec.groovy index 1a9c3177ffd..8f538821c5f 100644 --- a/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/agent/CleanupDetachedInstancesAgentSpec.groovy +++ b/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/agent/CleanupDetachedInstancesAgentSpec.groovy @@ -27,7 +27,10 @@ import com.amazonaws.services.ec2.model.TerminateInstancesRequest import com.netflix.spinnaker.clouddriver.aws.TestCredential import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider import com.netflix.spinnaker.clouddriver.aws.deploy.ops.DetachInstancesAtomicOperation +import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository +import com.netflix.spinnaker.credentials.CredentialsRepository +import com.netflix.spinnaker.credentials.MapBackedCredentialsRepository import spock.lang.Shared import spock.lang.Specification import spock.lang.Unroll @@ -46,8 +49,7 @@ class CleanupDetachedInstancesAgentSpec extends Specification { 1 * getAmazonEC2(test, "us-east-1", true) >> { amazonEC2USE } 0 * _ } - - def accountCredentialsRepository = Mock(AccountCredentialsRepository) { + def accountCredentialsRepository = Mock(MapBackedCredentialsRepository) { 1 * getAll() >> [test] 0 * _ } diff --git a/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/controllers/AmazonClusterControllerSpec.groovy b/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/controllers/AmazonClusterControllerSpec.groovy index f9a42e0a5ad..80a43e2c6fc 100644 --- a/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/controllers/AmazonClusterControllerSpec.groovy +++ b/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/controllers/AmazonClusterControllerSpec.groovy @@ -40,7 +40,7 @@ class AmazonClusterControllerSpec extends Specification { def provider = Stub(AmazonClientProvider) provider.getAutoScaling(creds, region) >> autoScaling controller.amazonClientProvider = provider - controller.accountCredentialsProvider = credsProvider + controller.credentialsRepository = credsProvider when: def result = controller.getScalingActivities(account, asgName, region) diff --git a/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/AllowLaunchAtomicOperationUnitSpec.groovy b/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/AllowLaunchAtomicOperationUnitSpec.groovy index ac6973aa5fc..c072c743343 100644 --- a/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/AllowLaunchAtomicOperationUnitSpec.groovy +++ b/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/ops/AllowLaunchAtomicOperationUnitSpec.groovy @@ -60,7 +60,7 @@ class AllowLaunchAtomicOperationUnitSpec extends Specification { getCredentials('target') >> target } def op = new AllowLaunchAtomicOperation(new AllowLaunchDescription(amiName: 'super-awesome-ami', targetAccount: 'target', credentials: source)) - op.accountCredentialsProvider = creds + op.credentialsRepository = creds op.amazonClientProvider = provider when: @@ -98,13 +98,13 @@ class AllowLaunchAtomicOperationUnitSpec extends Specification { def description = new AllowLaunchDescription(targetAccount: "prod", amiName: "ami-123456", region: "us-west-1", credentials: testCredentials) def op = new AllowLaunchAtomicOperation(description) op.amazonClientProvider = provider - op.accountCredentialsProvider = Mock(AccountCredentialsProvider) + op.credentialsRepository = Mock(AccountCredentialsProvider) when: op.operate([]) then: - with(op.accountCredentialsProvider){ + with(op.credentialsRepository){ 1 * getCredentials("prod") >> prodCredentials } with(provider) { @@ -129,13 +129,13 @@ class AllowLaunchAtomicOperationUnitSpec extends Specification { def description = new AllowLaunchDescription(targetAccount: "prod", amiName: "ami-123456", region: "us-west-1", credentials: testCredentials) def op = new AllowLaunchAtomicOperation(description) op.amazonClientProvider = provider - op.accountCredentialsProvider = Mock(AccountCredentialsProvider) + op.credentialsRepository = Mock(AccountCredentialsProvider) when: op.operate([]) then: - with(op.accountCredentialsProvider){ + with(op.credentialsRepository){ 1 * getCredentials("prod") >> prodCredentials } with(provider) { @@ -164,13 +164,13 @@ class AllowLaunchAtomicOperationUnitSpec extends Specification { def description = new AllowLaunchDescription(targetAccount: "test", amiName: "ami-123456", region: "us-west-1", credentials: testCredentials) def op = new AllowLaunchAtomicOperation(description) op.amazonClientProvider = provider - op.accountCredentialsProvider = Mock(AccountCredentialsProvider) + op.credentialsRepository = Mock(AccountCredentialsProvider) when: op.operate([]) then: - with(op.accountCredentialsProvider){ + with(op.credentialsRepository){ 1 * getCredentials("test") >> testCredentials } with(provider) { @@ -197,13 +197,13 @@ class AllowLaunchAtomicOperationUnitSpec extends Specification { def description = new AllowLaunchDescription(targetAccount: 'target', amiName: 'ami-123456', region: 'us-west-1', credentials: sourceCredentials) def op = new AllowLaunchAtomicOperation(description) op.amazonClientProvider = Mock(AmazonClientProvider) - op.accountCredentialsProvider = Mock(AccountCredentialsProvider) + op.credentialsRepository = Mock(AccountCredentialsProvider) when: op.operate([]) then: - with(op.accountCredentialsProvider) { + with(op.credentialsRepository) { 1 * getCredentials('target') >> targetCredentials 1 * getAll() >> [sourceCredentials, targetCredentials, ownerCredentials] } @@ -238,14 +238,14 @@ class AllowLaunchAtomicOperationUnitSpec extends Specification { def description = new AllowLaunchDescription(targetAccount: 'target', amiName: 'ami-123456', region: 'us-west-1', credentials: ownerCredentials) def op = new AllowLaunchAtomicOperation(description) op.amazonClientProvider = Mock(AmazonClientProvider) - op.accountCredentialsProvider = Mock(AccountCredentialsProvider) + op.credentialsRepository = Mock(AccountCredentialsProvider) when: op.operate([]) then: - with(op.accountCredentialsProvider) { + with(op.credentialsRepository) { 1 * getCredentials('target') >> targetCredentials } @@ -275,13 +275,13 @@ class AllowLaunchAtomicOperationUnitSpec extends Specification { def description = new AllowLaunchDescription(targetAccount: 'target', amiName: 'ami-123456', region: 'us-west-2', credentials: sourceCredentials) def op = new AllowLaunchAtomicOperation(description) op.amazonClientProvider = Mock(AmazonClientProvider) - op.accountCredentialsProvider = Mock(AccountCredentialsProvider) + op.credentialsRepository = Mock(AccountCredentialsProvider) when: op.operate([]) then: - with(op.accountCredentialsProvider) { + with(op.credentialsRepository) { 1 * getCredentials('target') >> targetCredentials } with(op.amazonClientProvider) { @@ -317,13 +317,13 @@ class AllowLaunchAtomicOperationUnitSpec extends Specification { def description = new AllowLaunchDescription(targetAccount: 'target', amiName: 'ami-123456', region: 'us-west-1', credentials: ownerCredentials) def op = new AllowLaunchAtomicOperation(description) op.amazonClientProvider = Mock(AmazonClientProvider) - op.accountCredentialsProvider = Mock(AccountCredentialsProvider) + op.credentialsRepository = Mock(AccountCredentialsProvider) when: op.operate([]) then: - with(op.accountCredentialsProvider) { + with(op.credentialsRepository) { 1 * getCredentials('target') >> targetCredentials } @@ -359,13 +359,13 @@ class AllowLaunchAtomicOperationUnitSpec extends Specification { def description = new AllowLaunchDescription(targetAccount: 'target', amiName: 'ami-123456', region: 'us-west-1', credentials: sourceCredentials) def op = new AllowLaunchAtomicOperation(description) op.amazonClientProvider = Mock(AmazonClientProvider) - op.accountCredentialsProvider = Mock(AccountCredentialsProvider) + op.credentialsRepository = Mock(AccountCredentialsProvider) when: op.operate([]) then: - with(op.accountCredentialsProvider) { + with(op.credentialsRepository) { 1 * getCredentials('target') >> targetCredentials 1 * getAll() >> [sourceCredentials, targetCredentials] } @@ -392,14 +392,14 @@ class AllowLaunchAtomicOperationUnitSpec extends Specification { def description = new AllowLaunchDescription(targetAccount: 'target', amiName: 'ami-123456', region: 'us-west-1', credentials: sourceCredentials) def op = new AllowLaunchAtomicOperation(description) op.amazonClientProvider = Mock(AmazonClientProvider) - op.accountCredentialsProvider = Mock(AccountCredentialsProvider) + op.credentialsRepository = Mock(AccountCredentialsProvider) when: op.operate([]) then: thrown IllegalArgumentException - with(op.accountCredentialsProvider) { + with(op.credentialsRepository) { 1 * getCredentials('target') >> targetCredentials 1 * getAll() >> [sourceCredentials, targetCredentials] } diff --git a/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/AllowLaunchDescriptionValidatorSpec.groovy b/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/AllowLaunchDescriptionValidatorSpec.groovy index 9b5e52a10ff..d074cff28b5 100644 --- a/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/AllowLaunchDescriptionValidatorSpec.groovy +++ b/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/AllowLaunchDescriptionValidatorSpec.groovy @@ -43,7 +43,7 @@ class AllowLaunchDescriptionValidatorSpec extends Specification { setup: AllowLaunchDescriptionValidator validator = new AllowLaunchDescriptionValidator() def credentialsHolder = Mock(AccountCredentialsProvider) - validator.accountCredentialsProvider = credentialsHolder + validator.credentialsRepository = credentialsHolder def description = new AllowLaunchDescription(targetAccount: "foo") def errors = Mock(ValidationErrors) diff --git a/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/BasicAmazonDeployDescriptionValidatorSpec.groovy b/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/BasicAmazonDeployDescriptionValidatorSpec.groovy index 57a48a3b14b..4f4efbe9a63 100644 --- a/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/BasicAmazonDeployDescriptionValidatorSpec.groovy +++ b/clouddriver-aws/src/test/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/validators/BasicAmazonDeployDescriptionValidatorSpec.groovy @@ -41,7 +41,7 @@ class BasicAmazonDeployDescriptionValidatorSpec extends Specification { def credentialsRepo = new MapBackedAccountCredentialsRepository() def credentialsProvider = new DefaultAccountCredentialsProvider(credentialsRepo) credentialsRepo.save(ACCOUNT_NAME, amazonCredentials) - validator.accountCredentialsProvider = credentialsProvider + validator.credentialsRepository = credentialsProvider } void "pass validation with proper description inputs"() { diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/ContainerInstanceCacheClient.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/ContainerInstanceCacheClient.java index 07ac5f51d69..a3d5e29f12e 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/ContainerInstanceCacheClient.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/ContainerInstanceCacheClient.java @@ -23,13 +23,14 @@ import com.netflix.spinnaker.clouddriver.ecs.cache.model.ContainerInstance; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @Component public class ContainerInstanceCacheClient extends AbstractCacheClient { @Autowired - public ContainerInstanceCacheClient(Cache cacheView) { + public ContainerInstanceCacheClient(@Lazy Cache cacheView) { super(cacheView, CONTAINER_INSTANCES.toString()); } diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsCloudWatchAlarmCacheClient.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsCloudWatchAlarmCacheClient.java index 0635329ef33..eee33010d84 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsCloudWatchAlarmCacheClient.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsCloudWatchAlarmCacheClient.java @@ -27,13 +27,14 @@ import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @Component public class EcsCloudWatchAlarmCacheClient extends AbstractCacheClient { @Autowired - public EcsCloudWatchAlarmCacheClient(Cache cacheView) { + public EcsCloudWatchAlarmCacheClient(@Lazy Cache cacheView) { super(cacheView, ALARMS.toString()); } diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsClusterCacheClient.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsClusterCacheClient.java index 2b48f375b46..e3a616f2511 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsClusterCacheClient.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsClusterCacheClient.java @@ -23,13 +23,14 @@ import com.netflix.spinnaker.clouddriver.ecs.cache.model.EcsCluster; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @Component public class EcsClusterCacheClient extends AbstractCacheClient { @Autowired - public EcsClusterCacheClient(Cache cacheView) { + public EcsClusterCacheClient(@Lazy Cache cacheView) { super(cacheView, ECS_CLUSTERS.toString()); } diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsInstanceCacheClient.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsInstanceCacheClient.java index 4a521d260b2..01a86970daf 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsInstanceCacheClient.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsInstanceCacheClient.java @@ -25,6 +25,7 @@ import java.util.Collection; import java.util.Set; import java.util.stream.Collectors; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @Component @@ -33,7 +34,7 @@ public class EcsInstanceCacheClient { private final Cache cacheView; private final ObjectMapper objectMapper; - public EcsInstanceCacheClient(Cache cacheView, ObjectMapper objectMapper) { + public EcsInstanceCacheClient(@Lazy Cache cacheView, ObjectMapper objectMapper) { this.cacheView = cacheView; this.objectMapper = objectMapper; } diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsLoadbalancerCacheClient.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsLoadbalancerCacheClient.java index 08321e3369a..231bfefb16d 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsLoadbalancerCacheClient.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsLoadbalancerCacheClient.java @@ -28,6 +28,7 @@ import com.netflix.spinnaker.clouddriver.ecs.provider.view.EcsAccountMapper; import java.util.*; import java.util.stream.Collectors; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @Component @@ -38,7 +39,7 @@ public class EcsLoadbalancerCacheClient { private final EcsAccountMapper ecsAccountMapper; public EcsLoadbalancerCacheClient( - Cache cacheView, ObjectMapper objectMapper, EcsAccountMapper ecsAccountMapper) { + @Lazy Cache cacheView, ObjectMapper objectMapper, EcsAccountMapper ecsAccountMapper) { this.cacheView = cacheView; this.objectMapper = objectMapper; this.ecsAccountMapper = ecsAccountMapper; diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsTargetGroupCacheClient.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsTargetGroupCacheClient.java index 82828b86ba9..0b457e02958 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsTargetGroupCacheClient.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/EcsTargetGroupCacheClient.java @@ -32,6 +32,7 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @Component @@ -40,7 +41,7 @@ public class EcsTargetGroupCacheClient { private final Cache cacheView; private final ObjectMapper objectMapper; - public EcsTargetGroupCacheClient(Cache cacheView, ObjectMapper objectMapper) { + public EcsTargetGroupCacheClient(@Lazy Cache cacheView, ObjectMapper objectMapper) { this.cacheView = cacheView; this.objectMapper = objectMapper; } diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/IamRoleCacheClient.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/IamRoleCacheClient.java index a019800520d..818974d8d8c 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/IamRoleCacheClient.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/IamRoleCacheClient.java @@ -29,13 +29,14 @@ import java.util.Set; import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @Component public class IamRoleCacheClient extends AbstractCacheClient { @Autowired - public IamRoleCacheClient(Cache cacheView) { + public IamRoleCacheClient(@Lazy Cache cacheView) { super(cacheView, IAM_ROLE.toString()); } diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/ScalableTargetCacheClient.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/ScalableTargetCacheClient.java index 0304563194f..badb13fbdfb 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/ScalableTargetCacheClient.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/ScalableTargetCacheClient.java @@ -23,6 +23,7 @@ import com.netflix.spinnaker.cats.cache.Cache; import com.netflix.spinnaker.cats.cache.CacheData; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @Component @@ -30,7 +31,7 @@ public class ScalableTargetCacheClient extends AbstractCacheClient { @Autowired - public SecretCacheClient(Cache cacheView) { + public SecretCacheClient(@Lazy Cache cacheView) { super(cacheView, SECRETS.toString()); } diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/ServiceCacheClient.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/ServiceCacheClient.java index 9b9c725d2a6..ac1f48179e3 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/ServiceCacheClient.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/ServiceCacheClient.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @Component @@ -35,7 +36,7 @@ public class ServiceCacheClient extends AbstractCacheClient { private ObjectMapper objectMapper; @Autowired - public ServiceCacheClient(Cache cacheView, ObjectMapper objectMapper) { + public ServiceCacheClient(@Lazy Cache cacheView, ObjectMapper objectMapper) { super(cacheView, SERVICES.toString()); this.objectMapper = objectMapper; } diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/ServiceDiscoveryCacheClient.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/ServiceDiscoveryCacheClient.java index 9ef409dbe52..5edd1f6adbc 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/ServiceDiscoveryCacheClient.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/ServiceDiscoveryCacheClient.java @@ -22,13 +22,14 @@ import com.netflix.spinnaker.clouddriver.ecs.cache.model.ServiceDiscoveryRegistry; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @Component public class ServiceDiscoveryCacheClient extends AbstractCacheClient { @Autowired - public ServiceDiscoveryCacheClient(Cache cacheView) { + public ServiceDiscoveryCacheClient(@Lazy Cache cacheView) { super(cacheView, SERVICE_DISCOVERY_REGISTRIES.toString()); } diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/TargetHealthCacheClient.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/TargetHealthCacheClient.java index 74ba5cde49a..ee01e5245ed 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/TargetHealthCacheClient.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/TargetHealthCacheClient.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @Component @@ -34,7 +35,7 @@ public class TargetHealthCacheClient extends AbstractCacheClient { private ObjectMapper objectMapper; @Autowired - public TaskCacheClient(Cache cacheView, ObjectMapper objectMapper) { + public TaskCacheClient(@Lazy Cache cacheView, ObjectMapper objectMapper) { super(cacheView, TASKS.toString()); this.objectMapper = objectMapper; } diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/TaskDefinitionCacheClient.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/TaskDefinitionCacheClient.java index 07f243b5484..82abd3aabf8 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/TaskDefinitionCacheClient.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/cache/client/TaskDefinitionCacheClient.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @Component @@ -35,7 +36,7 @@ public class TaskDefinitionCacheClient extends AbstractCacheClient { @Autowired - public TaskHealthCacheClient(Cache cacheView) { + public TaskHealthCacheClient(@Lazy Cache cacheView) { super(cacheView, HEALTH.toString()); } diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/provider/EcsProvider.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/provider/EcsProvider.java index bf89b1958ad..e2e9e1af4eb 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/provider/EcsProvider.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/provider/EcsProvider.java @@ -24,12 +24,10 @@ import static com.netflix.spinnaker.clouddriver.ecs.cache.Keys.Namespace.TASKS; import static com.netflix.spinnaker.clouddriver.ecs.cache.Keys.Namespace.TASK_DEFINITIONS; -import com.netflix.spinnaker.cats.agent.Agent; -import com.netflix.spinnaker.cats.agent.AgentSchedulerAware; import com.netflix.spinnaker.clouddriver.cache.SearchableProvider; import com.netflix.spinnaker.clouddriver.core.provider.agent.HealthProvidingCachingAgent; import com.netflix.spinnaker.clouddriver.ecs.cache.Keys; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository; +import com.netflix.spinnaker.clouddriver.security.BaseProvider; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -39,7 +37,7 @@ import java.util.Set; import java.util.stream.Collectors; -public class EcsProvider extends AgentSchedulerAware implements SearchableProvider { +public class EcsProvider extends BaseProvider implements SearchableProvider { public static final String NAME = EcsProvider.class.getName(); private static final Set defaultCaches = @@ -55,17 +53,9 @@ public class EcsProvider extends AgentSchedulerAware implements SearchableProvid private static final Map urlMappingTemplates = new HashMap<>(); - private final Collection agents; - private final AccountCredentialsRepository accountCredentialsRepository; private final Keys keys = new Keys(); private Collection healthAgents; - public EcsProvider( - AccountCredentialsRepository accountCredentialsRepository, Collection agents) { - this.agents = agents; - this.accountCredentialsRepository = accountCredentialsRepository; - } - @Override public Set getDefaultCaches() { return defaultCaches; @@ -93,15 +83,10 @@ public String getProviderName() { return NAME; } - @Override - public Collection getAgents() { - return agents; - } - public void synchronizeHealthAgents() { healthAgents = Collections.unmodifiableCollection( - agents.stream() + getAgents().stream() .filter(a -> a instanceof HealthProvidingCachingAgent) .map(a -> (HealthProvidingCachingAgent) a) .collect(Collectors.toList())); diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/provider/config/EcsProviderConfig.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/provider/config/EcsProviderConfig.java index 9a33adaf5fc..cd405c845df 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/provider/config/EcsProviderConfig.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/provider/config/EcsProviderConfig.java @@ -16,27 +16,11 @@ package com.netflix.spinnaker.clouddriver.ecs.provider.config; -import static com.netflix.spinnaker.clouddriver.aws.security.AmazonCredentials.AWSRegion; - -import com.amazonaws.auth.AWSCredentialsProvider; import com.fasterxml.jackson.databind.ObjectMapper; -import com.netflix.spectator.api.Registry; -import com.netflix.spinnaker.cats.agent.Agent; -import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider; -import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials; -import com.netflix.spinnaker.clouddriver.ecs.EcsCloudProvider; import com.netflix.spinnaker.clouddriver.ecs.provider.EcsProvider; -import com.netflix.spinnaker.clouddriver.ecs.provider.agent.*; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository; -import com.netflix.spinnaker.clouddriver.security.ProviderUtils; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; +import com.netflix.spinnaker.clouddriver.ecs.provider.agent.IamPolicyReader; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.DependsOn; @Configuration public class EcsProviderConfig { @@ -47,130 +31,7 @@ public IamPolicyReader iamPolicyReader(ObjectMapper objectMapper) { } @Bean - @DependsOn("netflixECSCredentials") - public EcsProvider ecsProvider( - AccountCredentialsRepository accountCredentialsRepository, - AmazonClientProvider amazonClientProvider, - AWSCredentialsProvider awsCredentialsProvider, - Registry registry, - IamPolicyReader iamPolicyReader, - ObjectMapper objectMapper) { - EcsProvider provider = - new EcsProvider( - accountCredentialsRepository, - Collections.newSetFromMap(new ConcurrentHashMap())); - synchronizeEcsProvider( - provider, - accountCredentialsRepository, - amazonClientProvider, - awsCredentialsProvider, - registry, - iamPolicyReader, - objectMapper); - return provider; - } - - private void synchronizeEcsProvider( - EcsProvider ecsProvider, - AccountCredentialsRepository accountCredentialsRepository, - AmazonClientProvider amazonClientProvider, - AWSCredentialsProvider awsCredentialsProvider, - Registry registry, - IamPolicyReader iamPolicyReader, - ObjectMapper objectMapper) { - - Set scheduledAccounts = ProviderUtils.getScheduledAccounts(ecsProvider); - Set allAccounts = - ProviderUtils.buildThreadSafeSetOfAccounts( - accountCredentialsRepository, NetflixAmazonCredentials.class, EcsCloudProvider.ID); - List newAgents = new LinkedList<>(); - - for (NetflixAmazonCredentials credentials : allAccounts) { - newAgents.add( - new IamRoleCachingAgent( - credentials, - amazonClientProvider, - awsCredentialsProvider, - iamPolicyReader)); // IAM is region-agnostic, so one caching agent per account is - // enough - - for (AWSRegion region : credentials.getRegions()) { - if (!scheduledAccounts.contains(credentials.getName())) { - newAgents.add( - new EcsClusterCachingAgent( - credentials, region.getName(), amazonClientProvider, awsCredentialsProvider)); - newAgents.add( - new ServiceCachingAgent( - credentials, - region.getName(), - amazonClientProvider, - awsCredentialsProvider, - registry)); - newAgents.add( - new TaskCachingAgent( - credentials, - region.getName(), - amazonClientProvider, - awsCredentialsProvider, - registry)); - newAgents.add( - new ContainerInstanceCachingAgent( - credentials, - region.getName(), - amazonClientProvider, - awsCredentialsProvider, - registry)); - newAgents.add( - new TaskDefinitionCachingAgent( - credentials, - region.getName(), - amazonClientProvider, - awsCredentialsProvider, - registry, - objectMapper)); - newAgents.add( - new TaskHealthCachingAgent( - credentials, - region.getName(), - amazonClientProvider, - awsCredentialsProvider, - objectMapper)); - newAgents.add( - new EcsCloudMetricAlarmCachingAgent( - credentials, region.getName(), amazonClientProvider, awsCredentialsProvider)); - newAgents.add( - new ScalableTargetsCachingAgent( - credentials, - region.getName(), - amazonClientProvider, - awsCredentialsProvider, - objectMapper)); - newAgents.add( - new SecretCachingAgent( - credentials, - region.getName(), - amazonClientProvider, - awsCredentialsProvider, - objectMapper)); - newAgents.add( - new ServiceDiscoveryCachingAgent( - credentials, - region.getName(), - amazonClientProvider, - awsCredentialsProvider, - objectMapper)); - newAgents.add( - new TargetHealthCachingAgent( - credentials, - region.getName(), - amazonClientProvider, - awsCredentialsProvider, - objectMapper)); - } - } - } - - ecsProvider.getAgents().addAll(newAgents); - ecsProvider.synchronizeHealthAgents(); + public EcsProvider ecsProvider() { + return new EcsProvider(); } } diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/provider/view/EcsAccountMapper.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/provider/view/EcsAccountMapper.java index be30d9dd211..96d9d40c174 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/provider/view/EcsAccountMapper.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/provider/view/EcsAccountMapper.java @@ -27,11 +27,10 @@ import java.util.Set; import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; @Component -@DependsOn("netflixECSCredentials") +// @DependsOn("netflixECSCredentials") public class EcsAccountMapper { final AccountCredentialsProvider accountCredentialsProvider; diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/security/ECSCredentialsConfig.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/security/ECSCredentialsConfig.java index 9e2eae8e8af..b1e87b46aa7 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/security/ECSCredentialsConfig.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/security/ECSCredentialsConfig.java @@ -16,15 +16,16 @@ package com.netflix.spinnaker.clouddriver.ecs.security; +import com.netflix.spinnaker.credentials.definition.CredentialsDefinition; import java.util.List; import lombok.Data; @Data public class ECSCredentialsConfig { - List accounts; + List accounts; @Data - public static class Account { + public static class ECSAccount implements CredentialsDefinition { private String name; private String awsAccount; } diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/security/ECSCredentialsLifeCycleHandler.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/security/ECSCredentialsLifeCycleHandler.java new file mode 100644 index 00000000000..6f2ebb8bc56 --- /dev/null +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/security/ECSCredentialsLifeCycleHandler.java @@ -0,0 +1,165 @@ +/* + * Copyright 2020 Netflix, 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. + * + */ + +package com.netflix.spinnaker.clouddriver.ecs.security; + +import com.amazonaws.auth.AWSCredentialsProvider; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.netflix.spectator.api.Registry; +import com.netflix.spinnaker.cats.agent.Agent; +import com.netflix.spinnaker.cats.module.CatsModule; +import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider; +import com.netflix.spinnaker.clouddriver.aws.security.AmazonCredentials; +import com.netflix.spinnaker.clouddriver.ecs.provider.EcsProvider; +import com.netflix.spinnaker.clouddriver.ecs.provider.agent.ContainerInstanceCachingAgent; +import com.netflix.spinnaker.clouddriver.ecs.provider.agent.EcsCloudMetricAlarmCachingAgent; +import com.netflix.spinnaker.clouddriver.ecs.provider.agent.EcsClusterCachingAgent; +import com.netflix.spinnaker.clouddriver.ecs.provider.agent.IamPolicyReader; +import com.netflix.spinnaker.clouddriver.ecs.provider.agent.IamRoleCachingAgent; +import com.netflix.spinnaker.clouddriver.ecs.provider.agent.ScalableTargetsCachingAgent; +import com.netflix.spinnaker.clouddriver.ecs.provider.agent.SecretCachingAgent; +import com.netflix.spinnaker.clouddriver.ecs.provider.agent.ServiceCachingAgent; +import com.netflix.spinnaker.clouddriver.ecs.provider.agent.ServiceDiscoveryCachingAgent; +import com.netflix.spinnaker.clouddriver.ecs.provider.agent.TargetHealthCachingAgent; +import com.netflix.spinnaker.clouddriver.ecs.provider.agent.TaskCachingAgent; +import com.netflix.spinnaker.clouddriver.ecs.provider.agent.TaskDefinitionCachingAgent; +import com.netflix.spinnaker.clouddriver.ecs.provider.agent.TaskHealthCachingAgent; +import com.netflix.spinnaker.clouddriver.security.ProviderUtils; +import com.netflix.spinnaker.credentials.CredentialsLifecycleHandler; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class ECSCredentialsLifeCycleHandler + implements CredentialsLifecycleHandler { + protected final EcsProvider ecsProvider; + protected final AmazonClientProvider amazonClientProvider; + protected final AWSCredentialsProvider awsCredentialsProvider; + protected final Registry registry; + protected final IamPolicyReader iamPolicyReader; + protected final ObjectMapper objectMapper; + protected final CatsModule catsModule; + + @Override + public void credentialsAdded(@NotNull NetflixECSCredentials credentials) { + scheduleAgents(credentials); + } + + @Override + public void credentialsUpdated(@NotNull NetflixECSCredentials credentials) { + ecsProvider.removeAgentsForAccounts(Collections.singleton(credentials.getName())); + scheduleAgents(credentials); + } + + @Override + public void credentialsDeleted(NetflixECSCredentials credentials) { + ecsProvider.removeAgentsForAccounts(Collections.singleton(credentials.getName())); + } + + private void scheduleAgents(NetflixECSCredentials credentials) { + Set scheduledAccounts = ProviderUtils.getScheduledAccounts(ecsProvider); + List newAgents = new LinkedList<>(); + newAgents.add( + new IamRoleCachingAgent( + credentials, amazonClientProvider, awsCredentialsProvider, iamPolicyReader)); + if (!scheduledAccounts.contains(credentials.getName())) { + for (AmazonCredentials.AWSRegion region : credentials.getRegions()) { + newAgents.add( + new EcsClusterCachingAgent( + credentials, region.getName(), amazonClientProvider, awsCredentialsProvider)); + newAgents.add( + new ServiceCachingAgent( + credentials, + region.getName(), + amazonClientProvider, + awsCredentialsProvider, + registry)); + newAgents.add( + new TaskCachingAgent( + credentials, + region.getName(), + amazonClientProvider, + awsCredentialsProvider, + registry)); + newAgents.add( + new ContainerInstanceCachingAgent( + credentials, + region.getName(), + amazonClientProvider, + awsCredentialsProvider, + registry)); + newAgents.add( + new TaskDefinitionCachingAgent( + credentials, + region.getName(), + amazonClientProvider, + awsCredentialsProvider, + registry, + objectMapper)); + newAgents.add( + new TaskHealthCachingAgent( + credentials, + region.getName(), + amazonClientProvider, + awsCredentialsProvider, + objectMapper)); + newAgents.add( + new EcsCloudMetricAlarmCachingAgent( + credentials, region.getName(), amazonClientProvider, awsCredentialsProvider)); + newAgents.add( + new ScalableTargetsCachingAgent( + credentials, + region.getName(), + amazonClientProvider, + awsCredentialsProvider, + objectMapper)); + newAgents.add( + new SecretCachingAgent( + credentials, + region.getName(), + amazonClientProvider, + awsCredentialsProvider, + objectMapper)); + newAgents.add( + new ServiceDiscoveryCachingAgent( + credentials, + region.getName(), + amazonClientProvider, + awsCredentialsProvider, + objectMapper)); + newAgents.add( + new TargetHealthCachingAgent( + credentials, + region.getName(), + amazonClientProvider, + awsCredentialsProvider, + objectMapper)); + } + } + + ecsProvider.addAgents(newAgents); + ecsProvider.synchronizeHealthAgents(); + } +} diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/security/ECSCredentialsParser.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/security/ECSCredentialsParser.java new file mode 100644 index 00000000000..099e6efcbb1 --- /dev/null +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/security/ECSCredentialsParser.java @@ -0,0 +1,61 @@ +/* + * Copyright 2020 Netflix, 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. + * + */ + +package com.netflix.spinnaker.clouddriver.ecs.security; + +import com.netflix.spinnaker.clouddriver.aws.AmazonCloudProvider; +import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials; +import com.netflix.spinnaker.clouddriver.aws.security.NetflixAssumeRoleAmazonCredentials; +import com.netflix.spinnaker.clouddriver.aws.security.config.CredentialsConfig; +import com.netflix.spinnaker.clouddriver.ecs.provider.EcsProvider; +import com.netflix.spinnaker.clouddriver.security.AccountCredentials; +import com.netflix.spinnaker.credentials.CompositeCredentialsRepository; +import com.netflix.spinnaker.credentials.definition.CredentialsParser; +import lombok.AllArgsConstructor; +import org.jetbrains.annotations.NotNull; + +@AllArgsConstructor +public class ECSCredentialsParser + implements CredentialsParser { + + private CompositeCredentialsRepository compositeCredentialsRepository; + private CredentialsParser parser; + + @Override + public NetflixECSCredentials parse(ECSCredentialsConfig.@NotNull ECSAccount credentials) { + NetflixAmazonCredentials netflixAmazonCredentials; + try { + netflixAmazonCredentials = + (NetflixAmazonCredentials) + compositeCredentialsRepository.getCredentials( + credentials.getAwsAccount(), AmazonCloudProvider.ID); + } catch (Throwable throwable) { + throwable.printStackTrace(); + return null; + } + + CredentialsConfig.Account account = + EcsAccountBuilder.build(netflixAmazonCredentials, credentials.getName(), EcsProvider.NAME); + try { + return new NetflixAssumeRoleEcsCredentials( + (NetflixAssumeRoleAmazonCredentials) parser.parse(account), credentials.getName()); + } catch (Throwable throwable) { + throwable.printStackTrace(); + return null; + } + } +} diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/security/EcsCredentialsInitializer.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/security/EcsCredentialsInitializer.java index 4a0fdf1d21f..ca8b5acbb53 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/security/EcsCredentialsInitializer.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/security/EcsCredentialsInitializer.java @@ -17,14 +17,19 @@ package com.netflix.spinnaker.clouddriver.ecs.security; import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials; -import com.netflix.spinnaker.clouddriver.aws.security.NetflixAssumeRoleAmazonCredentials; import com.netflix.spinnaker.clouddriver.aws.security.config.CredentialsConfig; -import com.netflix.spinnaker.clouddriver.aws.security.config.CredentialsLoader; +import com.netflix.spinnaker.clouddriver.ecs.EcsCloudProvider; import com.netflix.spinnaker.clouddriver.security.AccountCredentials; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; +import com.netflix.spinnaker.credentials.CompositeCredentialsRepository; +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.definition.CredentialsParser; +import javax.annotation.Nullable; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -40,55 +45,36 @@ public ECSCredentialsConfig ecsCredentialsConfig() { } @Bean - @DependsOn("netflixAmazonCredentials") - public List netflixECSCredentials( - CredentialsLoader credentialsLoader, - ECSCredentialsConfig credentialsConfig, - AccountCredentialsRepository accountCredentialsRepository) - throws Throwable { - return synchronizeECSAccounts( - credentialsLoader, credentialsConfig, accountCredentialsRepository); + @DependsOn("amazonCredentialsLoader") + @ConditionalOnMissingBean( + value = NetflixECSCredentials.class, + parameterizedContainer = CredentialsRepository.class) + CredentialsRepository amazonECSCredentialsRepository( + CredentialsLifecycleHandler eventHandler) { + return new MapBackedCredentialsRepository<>(EcsCloudProvider.ID, eventHandler); } - private List synchronizeECSAccounts( - CredentialsLoader credentialsLoader, - ECSCredentialsConfig ecsCredentialsConfig, - AccountCredentialsRepository accountCredentialsRepository) - throws Throwable { - - // TODO: add support for mutable accounts. - // List deltaAccounts = ProviderUtils.calculateAccountDeltas(accountCredentialsRepository, - // NetflixAmazonCredentials.class, accounts); - List credentials = new LinkedList<>(); - - for (AccountCredentials accountCredentials : accountCredentialsRepository.getAll()) { - if (accountCredentials instanceof NetflixAmazonCredentials) { - for (ECSCredentialsConfig.Account ecsAccount : ecsCredentialsConfig.getAccounts()) { - if (ecsAccount.getAwsAccount().equals(accountCredentials.getName())) { - - NetflixAmazonCredentials netflixAmazonCredentials = - (NetflixAmazonCredentials) accountCredentials; - - // TODO: accountCredentials should be serializable or somehow cloneable. - CredentialsConfig.Account account = - EcsAccountBuilder.build(netflixAmazonCredentials, ecsAccount.getName(), "ecs"); - - CredentialsConfig ecsCopy = new CredentialsConfig(); - ecsCopy.setAccounts(Collections.singletonList(account)); - - NetflixECSCredentials ecsCredentials = - new NetflixAssumeRoleEcsCredentials( - (NetflixAssumeRoleAmazonCredentials) credentialsLoader.load(ecsCopy).get(0), - ecsAccount.getAwsAccount()); - credentials.add(ecsCredentials); + @Bean + @DependsOn("amazonCredentialsLoader") + CredentialsParser ecsCredentialsParser( + CompositeCredentialsRepository compositeCredentialsRepository, + CredentialsParser + amazonCredentialsParser) { + return new ECSCredentialsParser<>(compositeCredentialsRepository, amazonCredentialsParser); + } - accountCredentialsRepository.save(ecsAccount.getName(), ecsCredentials); - break; - } - } - } + @Bean + @DependsOn("ecsCredentialsParser") + AbstractCredentialsLoader ecsCredentialsLoader( + CredentialsParser + amazonCredentialsParser, + CredentialsRepository repository, + ECSCredentialsConfig ecsCredentialsConfig, + @Nullable CredentialsDefinitionSource ecsCredentialsSource) { + if (ecsCredentialsSource == null) { + ecsCredentialsSource = ecsCredentialsConfig::getAccounts; } - return credentials; + return new BasicCredentialsLoader<>(ecsCredentialsSource, amazonCredentialsParser, repository); } } diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/services/ContainerInformationService.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/services/ContainerInformationService.java index 03762991196..05f5af7d656 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/services/ContainerInformationService.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/services/ContainerInformationService.java @@ -243,7 +243,7 @@ public Instance getEc2Instance(String ecsAccount, String region, Task task) { } private String getAwsAccountName(String ecsAccountName) { - for (ECSCredentialsConfig.Account ecsAccount : ecsCredentialsConfig.getAccounts()) { + for (ECSCredentialsConfig.ECSAccount ecsAccount : ecsCredentialsConfig.getAccounts()) { if (ecsAccount.getName().equals(ecsAccountName)) { return ecsAccount.getAwsAccount(); } diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/view/EcsApplicationProvider.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/view/EcsApplicationProvider.java index d452c65273e..75a82886e55 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/view/EcsApplicationProvider.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/view/EcsApplicationProvider.java @@ -31,6 +31,7 @@ import java.util.Map; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @Component @@ -42,7 +43,7 @@ public class EcsApplicationProvider implements ApplicationProvider { @Autowired public EcsApplicationProvider( AccountCredentialsProvider accountCredentialsProvider, - ServiceCacheClient serviceCacheClient) { + @Lazy ServiceCacheClient serviceCacheClient) { this.accountCredentialsProvider = accountCredentialsProvider; this.serviceCacheClient = serviceCacheClient; } diff --git a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/view/EcsInstanceProvider.java b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/view/EcsInstanceProvider.java index f8bdfeadca6..541e7a6922b 100644 --- a/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/view/EcsInstanceProvider.java +++ b/clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/view/EcsInstanceProvider.java @@ -30,9 +30,11 @@ import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @Component +@Lazy public class EcsInstanceProvider implements InstanceProvider { private final TaskCacheClient taskCacheClient; diff --git a/clouddriver-lambda/src/main/java/com/netflix/spinnaker/clouddriver/lambda/provider/agent/LambdaAgentProvider.java b/clouddriver-lambda/src/main/java/com/netflix/spinnaker/clouddriver/lambda/provider/agent/LambdaAgentProvider.java index 56a645f5d8f..618f44b1f7b 100644 --- a/clouddriver-lambda/src/main/java/com/netflix/spinnaker/clouddriver/lambda/provider/agent/LambdaAgentProvider.java +++ b/clouddriver-lambda/src/main/java/com/netflix/spinnaker/clouddriver/lambda/provider/agent/LambdaAgentProvider.java @@ -24,7 +24,7 @@ import com.netflix.spinnaker.clouddriver.aws.security.AmazonClientProvider; import com.netflix.spinnaker.clouddriver.aws.security.AmazonCredentials; import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials; -import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider; +import com.netflix.spinnaker.credentials.Credentials; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -34,17 +34,11 @@ @Component public class LambdaAgentProvider implements AgentProvider { private final ObjectMapper objectMapper; - - private final AccountCredentialsProvider accountCredentialsProvider; private final AmazonClientProvider amazonClientProvider; @Autowired - public LambdaAgentProvider( - AccountCredentialsProvider accountCredentialsProvider, - AmazonClientProvider amazonClientProvider) { + public LambdaAgentProvider(AmazonClientProvider amazonClientProvider) { this.objectMapper = AmazonObjectMapperConfigurer.createConfigured(); - - this.accountCredentialsProvider = accountCredentialsProvider; this.amazonClientProvider = amazonClientProvider; } @@ -54,24 +48,18 @@ public boolean supports(String providerName) { } @Override - public Collection agents() { + public Collection agents(Credentials credentials) { List agents = new ArrayList<>(); - - accountCredentialsProvider.getAll().stream() - .filter(c -> c instanceof NetflixAmazonCredentials) - .map(c -> (NetflixAmazonCredentials) c) - .filter(NetflixAmazonCredentials::getLambdaEnabled) - .forEach( - credentials -> { - agents.add(new IamRoleCachingAgent(objectMapper, credentials, amazonClientProvider)); - - for (AmazonCredentials.AWSRegion region : credentials.getRegions()) { - agents.add( - new LambdaCachingAgent( - objectMapper, amazonClientProvider, credentials, region.getName())); - } - }); - + NetflixAmazonCredentials netflixAmazonCredentials = (NetflixAmazonCredentials) credentials; + if (netflixAmazonCredentials.getLambdaEnabled()) { + agents.add( + new IamRoleCachingAgent(objectMapper, netflixAmazonCredentials, amazonClientProvider)); + for (AmazonCredentials.AWSRegion region : netflixAmazonCredentials.getRegions()) { + agents.add( + new LambdaCachingAgent( + objectMapper, amazonClientProvider, netflixAmazonCredentials, region.getName())); + } + } return agents; } }