summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2022-02-02 16:11:22 +0100
committerBjørn Christian Seime <bjorncs@verizonmedia.com>2022-02-02 16:11:27 +0100
commitd4d045124ce173c513dd88ec14efa3cc792d341c (patch)
treec9c4b026bdbb97c5365211dc302ca3a6ac7f2219
parent3c0146091cb7d06b8a436b5051a356894b0166c5 (diff)
Only update policy for a key once
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/ArchiveService.java5
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/MockArchiveService.java14
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveAccessMaintainer.java16
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveAccessMaintainerTest.java7
4 files changed, 35 insertions, 7 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/ArchiveService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/ArchiveService.java
index 5363e8d0150..c939055ffa5 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/ArchiveService.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/ArchiveService.java
@@ -5,6 +5,7 @@ import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.zone.ZoneId;
import java.util.Map;
+import java.util.Set;
/**
* Service that manages archive storage URIs for tenant nodes.
@@ -16,5 +17,7 @@ public interface ArchiveService {
ArchiveBucket createArchiveBucketFor(ZoneId zoneId, boolean sharded);
- void updateBucketAndKeyPolicy(ZoneId zoneId, ArchiveBucket bucket, Map<TenantName, String> authorizeIamRoleByTenantName);
+ void updateBucketPolicy(ZoneId zoneId, ArchiveBucket bucket, Map<TenantName, String> authorizeIamRoleByTenantName);
+
+ void updateKeyPolicy(ZoneId zoneId, String keyArn, Set<String> tenantAuthorizedIamRoles);
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/MockArchiveService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/MockArchiveService.java
index 5c979ddfc7b..796ca46ae4e 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/MockArchiveService.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/MockArchiveService.java
@@ -6,6 +6,8 @@ import com.yahoo.config.provision.zone.ZoneId;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
/**
* @author freva
@@ -13,7 +15,8 @@ import java.util.Map;
*/
public class MockArchiveService implements ArchiveService {
- public Map<ArchiveBucket, Map<TenantName, String>> authorizedIamRoles = new HashMap<>();
+ public Map<ArchiveBucket, Map<TenantName, String>> authorizedIamRolesForBucket = new HashMap<>();
+ public Map<String, Set<String>> authorizedIamRolesForKey = new TreeMap<>();
@Override
public ArchiveBucket createArchiveBucketFor(ZoneId zoneId, boolean sharded) {
@@ -21,7 +24,12 @@ public class MockArchiveService implements ArchiveService {
}
@Override
- public void updateBucketAndKeyPolicy(ZoneId zoneId, ArchiveBucket bucket, Map<TenantName, String> authorizeIamRoleByTenantName) {
- authorizedIamRoles.put(bucket, authorizeIamRoleByTenantName);
+ public void updateBucketPolicy(ZoneId zoneId, ArchiveBucket bucket, Map<TenantName, String> authorizeIamRoleByTenantName) {
+ authorizedIamRolesForBucket.put(bucket, authorizeIamRoleByTenantName);
+ }
+
+ @Override
+ public void updateKeyPolicy(ZoneId zoneId, String keyArn, Set<String> tenantAuthorizedIamRoles) {
+ authorizedIamRolesForKey.put(keyArn, tenantAuthorizedIamRoles);
}
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveAccessMaintainer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveAccessMaintainer.java
index 8156a2e9f3b..e3f69f59d24 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveAccessMaintainer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveAccessMaintainer.java
@@ -6,6 +6,7 @@ import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.jdisc.Metric;
import com.yahoo.vespa.hosted.controller.Controller;
+import com.yahoo.vespa.hosted.controller.api.integration.archive.ArchiveBucket;
import com.yahoo.vespa.hosted.controller.api.integration.archive.ArchiveService;
import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneRegistry;
import com.yahoo.vespa.hosted.controller.archive.CuratorArchiveBucketDb;
@@ -15,8 +16,11 @@ import com.yahoo.vespa.hosted.controller.tenant.Tenant;
import java.time.Duration;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.stream.Collectors;
+import static java.util.stream.Collectors.groupingBy;
+
/**
* Update archive access permissions with roles from tenants
*
@@ -52,10 +56,20 @@ public class ArchiveAccessMaintainer extends ControllerMaintainer {
try {
var tenantArchiveAccessRoles = cloudTenantArchiveExternalAccessRoles();
archiveBucketDb.buckets(zoneId).forEach(archiveBucket ->
- archiveService.updateBucketAndKeyPolicy(zoneId, archiveBucket,
+ archiveService.updateBucketPolicy(zoneId, archiveBucket,
Maps.filterEntries(tenantArchiveAccessRoles,
entry -> archiveBucket.tenants().contains(entry.getKey())))
);
+ Map<String, List<ArchiveBucket>> bucketsPerKey = archiveBucketDb.buckets(zoneId).stream()
+ .collect(groupingBy(ArchiveBucket::keyArn));
+ bucketsPerKey.forEach((keyArn, buckets) -> {
+ Set<String> authorizedIamRolesForKey = buckets.stream()
+ .flatMap(b -> b.tenants().stream())
+ .filter(tenantArchiveAccessRoles::containsKey)
+ .map(tenantArchiveAccessRoles::get)
+ .collect(Collectors.toSet());
+ archiveService.updateKeyPolicy(zoneId, keyArn, authorizedIamRolesForKey);
+ });
} catch (Exception e) {
throw new RuntimeException("Failed to maintain archive access in " + zoneId.value(), e);
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveAccessMaintainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveAccessMaintainerTest.java
index fe8dc0b1e29..df2b462914e 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveAccessMaintainerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveAccessMaintainerTest.java
@@ -15,6 +15,7 @@ import org.junit.Test;
import java.time.Duration;
import java.util.Map;
import java.util.Optional;
+import java.util.Set;
import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals;
@@ -39,10 +40,12 @@ public class ArchiveAccessMaintainerTest {
var testBucket = new ArchiveBucket("bucketName", "keyArn").withTenant(tenant1);
MockArchiveService archiveService = (MockArchiveService) tester.controller().serviceRegistry().archiveService();
- assertNull(archiveService.authorizedIamRoles.get(testBucket));
+ assertNull(archiveService.authorizedIamRolesForBucket.get(testBucket));
+ assertNull(archiveService.authorizedIamRolesForKey.get(testBucket.keyArn()));
MockMetric metric = new MockMetric();
new ArchiveAccessMaintainer(tester.controller(), metric, Duration.ofMinutes(10)).maintain();
- assertEquals(Map.of(tenant1, tenant1role), archiveService.authorizedIamRoles.get(testBucket));
+ assertEquals(Map.of(tenant1, tenant1role), archiveService.authorizedIamRolesForBucket.get(testBucket));
+ assertEquals(Set.of(tenant1role), archiveService.authorizedIamRolesForKey.get(testBucket.keyArn()));
var expected = Map.of("archive.bucketCount",
tester.controller().zoneRegistry().zones().all().ids().stream()