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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion extensions/auth/ranger/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,22 @@ polaris.authorization.ranger.authz.audit.destination.solr.urls=http://solr-servi

```

3. Run or restart Polaris to see that all accesses are authorized by Ranger policies, with access audit records available in Apache Ranger console.
3. Register the Polaris service type with Ranger Admin using the service definition shipped at

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Service-def for Polaris is implicitly registered starting with Ranger 2.9.0. So, in environments using 2.9.0 or above, step 3 is not necessary.

`src/main/resources/polaris-ranger-servicedef.json` (packaged as `polaris-ranger-servicedef.json`
on the classpath of `polaris-extensions-auth-ranger`), for example:
```
curl -u <ranger-admin-user>:<ranger-admin-password> -X POST \
-H "Content-Type: application/json" \
-d @polaris-ranger-servicedef.json \
http://ranger-admin:6080/service/public/v2/api/servicedef
```
This is the same `serviceDef` exercised by `RangerPolarisAuthorizerTest`: its fixture is
generated by embedding this shipped `serviceDef` (see `RangerTestUtils.createConfig` for the
unit test, and the `generateAuthzItTestFixture` Gradle task for the integration test), so any
access type available to grant through Ranger policies is guaranteed to be understood by the
authorizer.

4. Create a Ranger service instance of type `polaris` (matching the `service-name` configured
above), then define policies against it.

5. Run or restart Polaris to see that all accesses are authorized by Ranger policies, with access audit records available in Apache Ranger console.
70 changes: 67 additions & 3 deletions extensions/auth/ranger/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,70 @@ plugins {

val intTestJvmVersion = 21

val polarisRangerServiceDefFile =
layout.projectDirectory.file("src/main/resources/polaris-ranger-servicedef.json")
val servicedefPlaceholder = "@@POLARIS_RANGER_SERVICE_DEF@@"

// Strips the ASF license header (required since these templates are checked-in source files)
// that precedes the "{" starting the actual, not-quite-valid-JSON template content.
fun stripLicenseHeader(text: String) = text.substringAfter("*/").trimStart()

// The intTest authz fixture asserts against the shipped `serviceDef`, so rather than checking
// in a byte-for-byte copy of it (which can silently drift), it's a template with the shipped
// `polaris-ranger-servicedef.json` spliced in at build time. The unit-test equivalent fixture is
// generated the same way, but by test Java code at test-run time (see RangerTestUtils), since
// RangerPolarisAuthorizerTest runs in-process and can just write into a JUnit-managed temp dir.
val generateAuthzItTestFixture =
tasks.register("generateAuthzItTestFixture") {
val templateFile =
layout.projectDirectory.file("src/intTest/resources/authz_it_tests/dev_polaris.json.template")
val rolesFile =
layout.projectDirectory.file("src/intTest/resources/authz_it_tests/dev_polaris_roles.json")
val userStoreFile =
layout.projectDirectory.file(
"src/intTest/resources/authz_it_tests/dev_polaris_userstore.json"
)
val outputDir = layout.buildDirectory.dir("generated/resources/intTest/authz_it_tests")
inputs.file(polarisRangerServiceDefFile)
inputs.file(templateFile)
inputs.file(rolesFile)
inputs.file(userStoreFile)
outputs.dir(outputDir)
doLast {
// The sensitivity-based IT authz test exercises a boolean-expression policy condition
// that isn't part of the operator-facing artifact, so it's appended to the shipped
// serviceDef here rather than shipped in polaris-ranger-servicedef.json itself.
val policyConditions =
"""
,
"policyConditions": [
{
"itemId": 1,
"name": "_expression",
"evaluator": "org.apache.ranger.plugin.conditionevaluator.RangerScriptConditionEvaluator",
"evaluatorOptions": { "engineName": "JavaScript" },
"label": "Enter boolean expression",
"description": "Boolean expression"
}
]
"""
.trimIndent()
val shippedServiceDef = polarisRangerServiceDefFile.asFile.readText().trim()
check(shippedServiceDef.endsWith("}")) {
"unexpected trailing content in $polarisRangerServiceDefFile"
}
val serviceDefWithConditions =
shippedServiceDef.removeSuffix("}").trimEnd() + policyConditions + "\n}"

val template = stripLicenseHeader(templateFile.asFile.readText())
val merged = template.replace(servicedefPlaceholder, serviceDefWithConditions)
val outDir = outputDir.get().asFile.apply { mkdirs() }
outDir.resolve("dev_polaris.json").writeText(merged)
rolesFile.asFile.copyTo(outDir.resolve("dev_polaris_roles.json"), overwrite = true)
userStoreFile.asFile.copyTo(outDir.resolve("dev_polaris_userstore.json"), overwrite = true)
}
}

dependencies {
polarisServer(project(path = ":polaris-server", configuration = "quarkusRunner"))

Expand Down Expand Up @@ -84,9 +148,9 @@ testing {
targets {
all {
val buildDir = project.layout.buildDirectory
val policyDir =
project.layout.projectDirectory.dir("src/intTest/resources/authz_it_tests")
val policyDir = buildDir.dir("generated/resources/intTest/authz_it_tests")
testTask.configure {
dependsOn(generateAuthzItTestFixture)
environment(
"AWS_REGION",
providers.environmentVariable("AWS_REGION").getOrElse("us-west-2"),
Expand Down Expand Up @@ -124,7 +188,7 @@ testing {
"polaris.authorization.ranger.authz.default.enable.implicit.userstore.enricher" to
"true",
"polaris.authorization.ranger.authz.default.policy.source.local_folder.path" to
policyDir.asFile.absolutePath,
policyDir.get().asFile.absolutePath,
"polaris.features.\"SUPPORTED_CATALOG_STORAGE_TYPES\"" to "[\"FILE\"]",
"polaris.features.\"ALLOW_INSECURE_STORAGE_TYPES\"" to "true",
"polaris.readiness.ignore-severe-issues" to "true",
Expand Down
Loading
Loading