-
Notifications
You must be signed in to change notification settings - Fork 298
Disable custom namespace locations #2422
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c8aa4ba
b3985fd
8f058a0
68e83ff
81e7fc6
a02197e
7fc8180
27dc824
32ba495
386c608
b62ab27
b92c7b7
6bc11ab
2a708f4
435d24a
24ea0c3
23b331d
c0a3d2f
98ce3f9
43b0b95
414fc6b
a43c7aa
9595ab1
6548829
d623f6b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -508,6 +508,10 @@ private void createNamespaceInternal( | |
} else { | ||
LOGGER.debug("Skipping location overlap validation for namespace '{}'", namespace); | ||
} | ||
if (!realmConfig.getConfig( | ||
BehaviorChangeConfiguration.ALLOW_NAMESPACE_CUSTOM_LOCATION, catalogEntity)) { | ||
validateNamespaceLocation(entity, resolvedParent); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor: It'd be nice to wrap this into a method, so that we don't duplicate them in two different places.
|
||
PolarisEntity returnedEntity = | ||
PolarisEntity.of( | ||
getMetaStoreManager() | ||
|
@@ -671,6 +675,12 @@ public boolean setProperties(Namespace namespace, Map<String, String> properties | |
} else { | ||
LOGGER.debug("Skipping location overlap validation for namespace '{}'", namespace); | ||
} | ||
if (!realmConfig.getConfig( | ||
BehaviorChangeConfiguration.ALLOW_NAMESPACE_CUSTOM_LOCATION, catalogEntity)) { | ||
if (properties.containsKey(PolarisEntityConstants.ENTITY_BASE_LOCATION)) { | ||
validateNamespaceLocation(NamespaceEntity.of(entity), resolvedEntities); | ||
} | ||
} | ||
|
||
List<PolarisEntity> parentPath = resolvedEntities.getRawFullPath(); | ||
PolarisEntity returnedEntity = | ||
|
@@ -1085,6 +1095,76 @@ private void validateNoLocationOverlap( | |
} | ||
} | ||
|
||
/** Checks whether the location of a namespace is valid given its parent */ | ||
private void validateNamespaceLocation( | ||
NamespaceEntity namespace, PolarisResolvedPathWrapper resolvedParent) { | ||
StorageLocation namespaceLocation = | ||
StorageLocation.of( | ||
StorageLocation.ensureTrailingSlash( | ||
resolveNamespaceLocation(namespace.asNamespace(), namespace.getPropertiesAsMap()))); | ||
PolarisEntity parent = resolvedParent.getResolvedLeafEntity().getEntity(); | ||
Preconditions.checkArgument( | ||
parent.getType().equals(PolarisEntityType.CATALOG) | ||
|| parent.getType().equals(PolarisEntityType.NAMESPACE), | ||
"Invalid parent type"); | ||
if (parent.getType().equals(PolarisEntityType.CATALOG)) { | ||
CatalogEntity parentEntity = CatalogEntity.of(parent); | ||
LOGGER.debug( | ||
"Validating namespace {} given parent catalog {}", | ||
namespace.getName(), | ||
parentEntity.getName()); | ||
var storageConfigInfo = parentEntity.getStorageConfigurationInfo(); | ||
if (storageConfigInfo == null) { | ||
throw new IllegalArgumentException( | ||
"Cannot create namespace without a parent storage configuration"); | ||
} | ||
List<StorageLocation> defaultLocations = | ||
parentEntity.getStorageConfigurationInfo().getAllowedLocations().stream() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AllowedLocations in the StorageConfig are an independent concept vs either of:
The most important one is validating that anything that can vend credentials resides under the allowedLocations. Overlap and custom hierarchies in general are more common to disable validation for. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This PR isn't related to credential vending, but the location that a namespace is created at. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, I was explaining why your PR description is misleading:
Is this PR fixing assumptions around credential vending, or just adding an option for whether to enforce "standard" locations for namespaces? In general we shouldn't need namespaces to be standard to still provide the intended guarantees about enforcement of ALLOWED_LOCATIONS. The more important bug to fix is enforcement of ALLOWED_LOCATIONS. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That clause is part of a sentence:
and is used in that sentence to articulate why we care that namespaces reside within their parent's location. Indeed, if you remove the clause from that context it could be misleading. If there's another (more important) bugfix, let's submit that in parallel with this existing bugfix. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My clause was also part of a paragraph: AllowedLocations in the StorageConfig are an independent concept vs either of:
The most important one is validating that anything that can vend credentials resides under the allowedLocations. Overlap and custom hierarchies in general are more common to disable validation for. |
||
.filter(java.util.Objects::nonNull) | ||
.map( | ||
l -> | ||
StorageLocation.ensureTrailingSlash( | ||
StorageLocation.ensureTrailingSlash(l) + namespace.getName())) | ||
.map(StorageLocation::of) | ||
.toList(); | ||
if (!defaultLocations.contains(namespaceLocation)) { | ||
throw new IllegalArgumentException( | ||
"Namespace " | ||
+ namespace.getName() | ||
+ " has a custom location, " | ||
eric-maynard marked this conversation as resolved.
Show resolved
Hide resolved
|
||
+ "which is not enabled. Expected a location in: [" | ||
+ String.join( | ||
", ", defaultLocations.stream().map(StorageLocation::toString).toList()) | ||
+ "]. Got location: " | ||
+ namespaceLocation | ||
+ "]"); | ||
} | ||
} else if (parent.getType().equals(PolarisEntityType.NAMESPACE)) { | ||
NamespaceEntity parentEntity = NamespaceEntity.of(parent); | ||
LOGGER.debug( | ||
"Validating namespace {} given parent namespace {}", | ||
namespace.getName(), | ||
parentEntity.getName()); | ||
String parentLocation = | ||
resolveNamespaceLocation(parentEntity.asNamespace(), parentEntity.getPropertiesAsMap()); | ||
StorageLocation defaultLocation = | ||
StorageLocation.of( | ||
StorageLocation.ensureTrailingSlash( | ||
StorageLocation.ensureTrailingSlash(parentLocation) + namespace.getName())); | ||
if (!defaultLocation.equals(namespaceLocation)) { | ||
throw new IllegalArgumentException( | ||
"Namespace " | ||
+ namespace.getName() | ||
+ " has a custom location, " | ||
+ "which is not enabled. Expected location: [" | ||
+ defaultLocation | ||
+ "]. Got location: [" | ||
+ namespaceLocation | ||
+ "]"); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Validate no location overlap exists between the entity path and its sibling entities. This | ||
* resolves all siblings at the same level as the target entity (namespaces if the target entity | ||
|
Uh oh!
There was an error while loading. Please reload this page.