Skip to content

Install demo security information when running ./gradlew run -PinstalledPlugins="['opensearch-security']"#20372

Merged
cwperks merged 3 commits intoopensearch-project:mainfrom
cwperks:gradle-run-security
Jan 6, 2026
Merged

Install demo security information when running ./gradlew run -PinstalledPlugins="['opensearch-security']"#20372
cwperks merged 3 commits intoopensearch-project:mainfrom
cwperks:gradle-run-security

Conversation

@cwperks
Copy link
Copy Markdown
Member

@cwperks cwperks commented Jan 5, 2026

Description

This PR builds off #19428 to make integration testing simpler with the security plugin. Now when running ./gradlew run -PinstalledPlugins="['opensearch-security']" the changes in this PR will ensure it completes the demo security configuration with demo config (with default admin pw for testing)

> curl -XGET https://localhost:9200/ -k -u 'admin:admin'

{
  "name" : "runTask-0",
  "cluster_name" : "runTask",
  "cluster_uuid" : "zt2EBuv_RySAjK2A0tCZPA",
  "version" : {
    "distribution" : "opensearch",
    "number" : "3.5.0-SNAPSHOT",
    "build_type" : "tar",
    "build_hash" : "ae713e436662ad56bc151d6b8076a1f93321a975",
    "build_date" : "2026-01-05T15:24:21.751914Z",
    "build_snapshot" : true,
    "lucene_version" : "10.3.2",
    "minimum_wire_compatibility_version" : "2.19.0",
    "minimum_index_compatibility_version" : "2.0.0"
  },
  "tagline" : "The OpenSearch Project: https://opensearch.org/"
}

Related Issues

Related to opensearch-project/opensearch-plugins#245

Check List

  • Functionality includes testing.
  • API changes companion pull request created, if applicable.
  • Public documentation issue/PR created, if applicable.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

Summary by CodeRabbit

  • Changed
    • Security configuration is now automatically applied when the security plugin is detected during build.
    • Demo security certificates and related settings are downloaded and configured automatically for security-enabled test runs, removing manual setup steps.

✏️ Tip: You can customize this high-level summary in your review settings.

…lledPlugins="['opensearch-security']"

Signed-off-by: Craig Perkins <cwperx@amazon.com>
@cwperks cwperks requested a review from a team as a code owner January 5, 2026 21:23
@cwperks cwperks changed the title Install demon security information when running ./gradlew run -PinstalledPlugins="['opensearch-security']" Install demo security information when running ./gradlew run -PinstalledPlugins="['opensearch-security']" Jan 5, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 5, 2026

📝 Walkthrough

Walkthrough

Adds a conditional Gradle security setup: if the installedPlugins project property contains opensearch-security, a new Gradle script downloads SSL certificates and injects security configuration into test cluster run tasks.

Changes

Cohort / File(s) Summary
Changelog
CHANGELOG.md
Added entry noting demo security information is installed when running Gradle tasks with installedPlugins including opensearch-security.
Top-level build file
build.gradle
Conditionally applies gradle/security-setup.gradle when installedPlugins contains opensearch-security.
Gradle security setup
gradle/security-setup.gradle
New script: defines securityEnabled from installedPlugins; adds tasks to download PEM files (esnode, kirk, root-ca, keys) if absent; afterEvaluation injects extraConfigFile per test cluster node, applies SSL/admin/audit/roles/system-index settings; makes run tasks depend on PEM download tasks.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant DevEnv as Gradle (build)
  participant Remote as Cert Server (https://...)
  participant Disk as Local FS
  participant Cluster as Test Cluster Runner
  rect rgb(230, 248, 255)
    Note over DevEnv: Detect `installedPlugins` contains\n`opensearch-security` -> apply security-setup.gradle
  end
  DevEnv->>Disk: Check for PEM files (esnode.pem, kirk.pem, root-ca.pem, keys)
  alt file missing
    DevEnv->>Remote: Download PEM files
    Remote-->>Disk: Write PEM files
  else files present
    Disk-->>DevEnv: Use existing PEMs
  end
  DevEnv->>Cluster: After evaluation, inject `extraConfigFile` and security settings into each node
  DevEnv->>Cluster: Ensure run tasks depend on PEM download tasks
  Cluster-->>Cluster: Start nodes with injected certs and security config
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰
I hopped through Gradle fields at night,
Fetching certs by moonlit light.
If plugins ask for security’s art,
I tuck key and pem into every part.
Now test clusters sleep safe and tight.

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: installing demo security information when running gradlew with the opensearch-security plugin, which matches the changeset's primary objective.
Description check ✅ Passed The description includes all major required sections: a clear description of changes, related issues reference, and the Apache 2.0 license confirmation with DCO statement. The example curl output demonstrates the feature working as intended.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Comment @coderabbitai help to get the list of available commands and usage tips.

Signed-off-by: Craig Perkins <cwperx@amazon.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
gradle/security-setup.gradle (2)

9-10: Use exact string matching to avoid false positives.

The current check uses contains('opensearch-security'), which could match plugin names like opensearch-security-analytics or opensearch-security-extended. Consider using exact matching or a more precise pattern.

🔎 Suggested improvement
-ext.securityEnabled = project.hasProperty('installedPlugins') && 
-    project.property('installedPlugins').toString().contains('opensearch-security')
+ext.securityEnabled = project.hasProperty('installedPlugins') && 
+    project.property('installedPlugins').toString().matches('.*[\\[\\s,\'\"]opensearch-security[\\]\\s,\'\"].*')

This ensures the plugin name is properly delimited within the list.


17-24: Add error handling for certificate download failures.

Network failures during certificate downloads will cause cryptic build errors. Consider adding try-catch blocks with meaningful error messages to help users diagnose issues.

🔎 Proposed error handling
     tasks.register("download${file.replace('-', '').replace('.', '').capitalize()}") {
       doLast {
         if (!local.exists()) {
           local.parentFile.mkdirs()
-          new URL("https://raw.githubusercontent.com/opensearch-project/security/refs/heads/main/bwc-test/src/test/resources/security/" + file).withInputStream { i ->
-            local.withOutputStream { it << i }
-          }
+          try {
+            new URL("https://raw.githubusercontent.com/opensearch-project/security/refs/heads/main/bwc-test/src/test/resources/security/" + file).withInputStream { i ->
+              local.withOutputStream { it << i }
+            }
+          } catch (IOException e) {
+            throw new GradleException("Failed to download security certificate ${file}: ${e.message}. Ensure you have internet connectivity.", e)
+          }
         }
       }
     }
build.gradle (1)

74-78: Consider extracting the plugin check to avoid duplication.

The same contains('opensearch-security') check appears both here and in gradle/security-setup.gradle (lines 9-10). If you improve the matching logic in one place, remember to update both locations, or consider extracting it to a shared function.

Also, as mentioned in the review of security-setup.gradle, the current string matching could have false positives with plugin names containing opensearch-security as a substring.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 66d2482 and 207a4e2.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • build.gradle
  • gradle/security-setup.gradle
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: gradle-check
  • GitHub Check: Analyze (java)
  • GitHub Check: precommit (25, windows-latest)
  • GitHub Check: precommit (25, macos-15)
  • GitHub Check: precommit (25, macos-15-intel)
  • GitHub Check: precommit (21, windows-2025, true)
  • GitHub Check: precommit (21, ubuntu-latest)
  • GitHub Check: precommit (21, ubuntu-24.04-arm)
  • GitHub Check: precommit (21, macos-15)
  • GitHub Check: precommit (25, ubuntu-24.04-arm)
  • GitHub Check: precommit (21, windows-latest)
  • GitHub Check: precommit (21, macos-15-intel)
  • GitHub Check: precommit (25, ubuntu-latest)
  • GitHub Check: assemble (25, ubuntu-24.04-arm)
  • GitHub Check: assemble (25, windows-latest)
  • GitHub Check: assemble (21, ubuntu-latest)
  • GitHub Check: assemble (21, ubuntu-24.04-arm)
  • GitHub Check: assemble (25, ubuntu-latest)
  • GitHub Check: assemble (21, windows-latest)
  • GitHub Check: detect-breaking-change
🔇 Additional comments (4)
CHANGELOG.md (1)

22-22: LGTM!

The CHANGELOG entry accurately describes the feature and follows the established format.

gradle/security-setup.gradle (3)

40-56: Security configuration looks correct for demo setup.

The security settings properly configure SSL/TLS for both transport and HTTP layers, enable demo certificates, and set up appropriate admin permissions. The configuration aligns with the PR's goal of simplifying development/integration testing.

Note: These are demo certificates intended for development only and should never be used in production environments.


59-61: LGTM! Task dependency ensures certificates are available.

The dependency configuration correctly ensures certificate files are downloaded before the run task executes.


20-20: This is test build infrastructure, not production code. Using the main branch for test certificates is appropriate and standard practice—it ensures the test resources align with the current development version of the security plugin. Pinning to a release tag would introduce version mismatch issues and require manual maintenance whenever the security dependency updates. Any structural changes would be caught by CI failures.

Likely an incorrect or invalid review comment.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 5, 2026

❌ Gradle check result for 207a4e2: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 6, 2026

✅ Gradle check result for 207a4e2: SUCCESS

@codecov
Copy link
Copy Markdown

codecov bot commented Jan 6, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.26%. Comparing base (d866be8) to head (0ab4dc8).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main   #20372      +/-   ##
============================================
- Coverage     73.30%   73.26%   -0.04%     
+ Complexity    71777    71740      -37     
============================================
  Files          5784     5784              
  Lines        328141   328145       +4     
  Branches      47269    47270       +1     
============================================
- Hits         240531   240414     -117     
- Misses        68329    68465     +136     
+ Partials      19281    19266      -15     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Signed-off-by: Craig Perkins <cwperx@amazon.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Fix all issues with AI Agents
In @gradle/security-setup.gradle:
- Around line 17-24: The doLast closure that downloads certificates (the block
using local, local.parentFile.mkdirs(), and new URL(...).withInputStream { ...
}) lacks error handling; wrap the download logic in a try-catch that catches
IOException/Exception, log a clear error via Gradle logger (logger.error or
project.logger.error) including the URL and exception message, remove any
partially written local file on failure, and rethrow a GradleException with a
descriptive message so the build fails loudly rather than with a cryptic stack
trace.
- Around line 9-10: The plugin detection using a substring match is fragile;
update the logic that sets ext.securityEnabled to parse the installedPlugins
value and check for an exact match against "opensearch-security" by handling
both Collection and String cases: if project.property('installedPlugins') is a
Collection use .contains('opensearch-security'), if it is a String split on
commas (trim entries) into a list and check for equality, and keep the initial
project.hasProperty guard; apply this change where ext.securityEnabled is
assigned so it reliably detects the exact plugin name.
- Around line 59-61: The current tasks.named('run') dependsOn uses a broad
predicate tasks.matching { it.name.startsWith('download') &&
it.name.contains('pem') } which may match unintended tasks; update it to target
specific task names or stored references instead: either change the predicate to
an explicit name check (e.g., match the exact download PEM task name(s) used
when creating them) or capture the download PEM Task objects when you create
them and call dependsOn with those task references; update the
tasks.named('run') dependency to use those explicit task names or stored Task
references so only the intended download PEM tasks are depended on.
- Around line 14-26: The download loop currently pulls files from the security
repo's "main" branch which is unstable; update the URL used in the
tasks.register block (the new
URL("https://raw.githubusercontent.com/opensearch-project/security/refs/heads/main/..."))
to reference a specific stable release tag (or make it configurable via a gradle
property like opensearchSecurityTag with a default stable tag such as
"2.19.4.0"), so the registered tasks downloadEsnodePem / downloadEsnodekeyPem /
downloadKirkPem / downloadKirkkeyPem / downloadRootcapem use the release tag
path instead of "refs/heads/main".
🧹 Nitpick comments (2)
gradle/security-setup.gradle (2)

20-20: Extract the base URL as a constant for maintainability.

The long URL is hardcoded and repeated across task registrations. Extracting it as a constant would improve maintainability and make it easier to update the reference in the future.

🔎 Proposed refactor
 if (securityEnabled) {
+  def SECURITY_CERTS_BASE_URL = "https://raw.githubusercontent.com/opensearch-project/security/refs/heads/main/bwc-test/src/test/resources/security/"
+
   // Download security certificates
   ['esnode.pem', 'esnode-key.pem', 'kirk.pem', 'kirk-key.pem', 'root-ca.pem'].forEach { file ->
     File local = project.layout.buildDirectory.file(file).get().asFile
     tasks.register("download${file.replace('-', '').replace('.', '').capitalize()}") {
       doLast {
         if (!local.exists()) {
           local.parentFile.mkdirs()
-          new URL("https://raw.githubusercontent.com/opensearch-project/security/refs/heads/main/bwc-test/src/test/resources/security/" + file).withInputStream { i ->
+          new URL(SECURITY_CERTS_BASE_URL + file).withInputStream { i ->
             local.withOutputStream { it << i }
           }
         }
       }
     }
   }

33-37: Consider reducing duplication in certificate file registration.

The pattern of calling node.extraConfigFile() is repeated five times with similar structure. This could be refactored to reduce duplication and make future changes easier.

🔎 Proposed refactor
       testClusters.runTask.nodes.each { node ->
         // Add certificate files
-        node.extraConfigFile("kirk.pem", project.layout.buildDirectory.file("kirk.pem").get().asFile)
-        node.extraConfigFile("kirk-key.pem", project.layout.buildDirectory.file("kirk-key.pem").get().asFile)
-        node.extraConfigFile("esnode.pem", project.layout.buildDirectory.file("esnode.pem").get().asFile)
-        node.extraConfigFile("esnode-key.pem", project.layout.buildDirectory.file("esnode-key.pem").get().asFile)
-        node.extraConfigFile("root-ca.pem", project.layout.buildDirectory.file("root-ca.pem").get().asFile)
+        ['kirk.pem', 'kirk-key.pem', 'esnode.pem', 'esnode-key.pem', 'root-ca.pem'].each { certFile ->
+          node.extraConfigFile(certFile, project.layout.buildDirectory.file(certFile).get().asFile)
+        }
 
         // Security settings
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 207a4e2 and 0ab4dc8.

📒 Files selected for processing (1)
  • gradle/security-setup.gradle
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: gradle-check
  • GitHub Check: precommit (25, macos-15-intel)
  • GitHub Check: precommit (21, ubuntu-latest)
  • GitHub Check: precommit (21, macos-15-intel)
  • GitHub Check: precommit (21, ubuntu-24.04-arm)
  • GitHub Check: precommit (25, ubuntu-24.04-arm)
  • GitHub Check: precommit (21, macos-15)
  • GitHub Check: precommit (21, windows-latest)
  • GitHub Check: precommit (25, macos-15)
  • GitHub Check: precommit (21, windows-2025, true)
  • GitHub Check: precommit (25, windows-latest)
  • GitHub Check: precommit (25, ubuntu-latest)
  • GitHub Check: assemble (25, ubuntu-24.04-arm)
  • GitHub Check: assemble (25, windows-latest)
  • GitHub Check: assemble (21, ubuntu-24.04-arm)
  • GitHub Check: assemble (21, windows-latest)
  • GitHub Check: assemble (21, ubuntu-latest)
  • GitHub Check: assemble (25, ubuntu-latest)
  • GitHub Check: Analyze (java)
  • GitHub Check: detect-breaking-change
🔇 Additional comments (2)
gradle/security-setup.gradle (2)

43-43: The code is correctly configured for test clusters. Setting enforce_hostname_verification to false is appropriate here because:

  1. Test-only scope: Configuration is explicitly scoped to testClusters.runTask (line 30)
  2. Demo certificates in use: Line 48 explicitly enables allow_unsafe_democertificates, and test resources are downloaded from test fixtures
  3. Code structure documents intent: The combination of testClusters, demo certificates, and test resources makes the demo-only nature clear without additional comments

No changes needed.


50-50: The admin DN formatting is correct. The \n - prefix is intentional and represents YAML list syntax as expected by the OpenSearch security plugin. The testClusters node.setting() method properly handles this format for multi-line YAML values. No action required.

Comment on lines +9 to +10
ext.securityEnabled = project.hasProperty('installedPlugins') &&
project.property('installedPlugins').toString().contains('opensearch-security')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Use more robust plugin detection logic.

The current string matching with .toString().contains('opensearch-security') is fragile and could produce false positives (e.g., matching 'my-opensearch-security-fork') or fail if the property structure changes.

Consider parsing installedPlugins as a list and checking for an exact match.

🔎 Proposed fix for robust plugin detection
-ext.securityEnabled = project.hasProperty('installedPlugins') &&
-    project.property('installedPlugins').toString().contains('opensearch-security')
+ext.securityEnabled = project.hasProperty('installedPlugins') &&
+    project.property('installedPlugins').toString()
+        .replaceAll(/[\[\]'\s]/, '')
+        .split(',')
+        .contains('opensearch-security')

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In @gradle/security-setup.gradle around lines 9 - 10, The plugin detection using
a substring match is fragile; update the logic that sets ext.securityEnabled to
parse the installedPlugins value and check for an exact match against
"opensearch-security" by handling both Collection and String cases: if
project.property('installedPlugins') is a Collection use
.contains('opensearch-security'), if it is a String split on commas (trim
entries) into a list and check for equality, and keep the initial
project.hasProperty guard; apply this change where ext.securityEnabled is
assigned so it reliably detects the exact plugin name.

Comment on lines +14 to +26
['esnode.pem', 'esnode-key.pem', 'kirk.pem', 'kirk-key.pem', 'root-ca.pem'].forEach { file ->
File local = project.layout.buildDirectory.file(file).get().asFile
tasks.register("download${file.replace('-', '').replace('.', '').capitalize()}") {
doLast {
if (!local.exists()) {
local.parentFile.mkdirs()
new URL("https://raw.githubusercontent.com/opensearch-project/security/refs/heads/main/bwc-test/src/test/resources/security/" + file).withInputStream { i ->
local.withOutputStream { it << i }
}
}
}
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n gradle/security-setup.gradle

Repository: opensearch-project/OpenSearch

Length of output: 3861


🏁 Script executed:

# Check if the referenced certificate files exist at the specified URL
for file in esnode.pem esnode-key.pem kirk.pem kirk-key.pem root-ca.pem; do
  echo "Checking $file..."
  curl -s -I "https://raw.githubusercontent.com/opensearch-project/security/refs/heads/main/bwc-test/src/test/resources/security/$file" 2>&1 | head -5
done

Repository: opensearch-project/OpenSearch

Length of output: 1376


🌐 Web query:

opensearch-project/security GitHub repository releases tags stable versions

💡 Result:

The opensearch-project/security repo publishes release tags for both the 2.x and 3.x series. Current notable stable tags shown on the repository Releases page include 2.19.4.0 (latest 2.x) and 3.3.0.0 (latest 3.x), with additional 3.2.0.0, 3.1.0.0, 3.0.0.0 and earlier 2.19.0.0 / 2.19.1.0 tags. See the repo Releases for the full tag list and release notes. [1]

Sources:

  • opensearch-project/security Releases (tags and release notes). [1]

Download certificates from a stable release instead of the main branch.

The URL points to the main branch, which is unstable and could break at any time if files are moved, renamed, or removed in the security repository. This creates a fragile dependency that could cause build failures.

The opensearch-project/security repository publishes stable release tags (2.19.4.0, 3.3.0.0, and others). Use a specific stable release tag instead.

🤖 Prompt for AI Agents
In @gradle/security-setup.gradle around lines 14 - 26, The download loop
currently pulls files from the security repo's "main" branch which is unstable;
update the URL used in the tasks.register block (the new
URL("https://raw.githubusercontent.com/opensearch-project/security/refs/heads/main/..."))
to reference a specific stable release tag (or make it configurable via a gradle
property like opensearchSecurityTag with a default stable tag such as
"2.19.4.0"), so the registered tasks downloadEsnodePem / downloadEsnodekeyPem /
downloadKirkPem / downloadKirkkeyPem / downloadRootcapem use the release tag
path instead of "refs/heads/main".

Comment on lines +17 to +24
doLast {
if (!local.exists()) {
local.parentFile.mkdirs()
new URL("https://raw.githubusercontent.com/opensearch-project/security/refs/heads/main/bwc-test/src/test/resources/security/" + file).withInputStream { i ->
local.withOutputStream { it << i }
}
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add error handling for certificate downloads.

The download logic has no error handling for network failures, unavailable URLs, or I/O errors. This will result in cryptic failures when the download fails.

🔎 Proposed fix to add error handling
     tasks.register("download${file.replace('-', '').replace('.', '').capitalize()}") {
       doLast {
         if (!local.exists()) {
           local.parentFile.mkdirs()
-          new URL("https://raw.githubusercontent.com/opensearch-project/security/refs/heads/main/bwc-test/src/test/resources/security/" + file).withInputStream { i ->
-            local.withOutputStream { it << i }
-          }
+          try {
+            def url = new URL("https://raw.githubusercontent.com/opensearch-project/security/refs/heads/main/bwc-test/src/test/resources/security/" + file)
+            def connection = url.openConnection()
+            connection.connectTimeout = 10000
+            connection.readTimeout = 10000
+            connection.inputStream.withStream { i ->
+              local.withOutputStream { it << i }
+            }
+            logger.lifecycle("Downloaded ${file}")
+          } catch (Exception e) {
+            throw new GradleException("Failed to download ${file}: ${e.message}", e)
+          }
         }
       }
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
doLast {
if (!local.exists()) {
local.parentFile.mkdirs()
new URL("https://raw.githubusercontent.com/opensearch-project/security/refs/heads/main/bwc-test/src/test/resources/security/" + file).withInputStream { i ->
local.withOutputStream { it << i }
}
}
}
doLast {
if (!local.exists()) {
local.parentFile.mkdirs()
try {
def url = new URL("https://raw.githubusercontent.com/opensearch-project/security/refs/heads/main/bwc-test/src/test/resources/security/" + file)
def connection = url.openConnection()
connection.connectTimeout = 10000
connection.readTimeout = 10000
connection.inputStream.withStream { i ->
local.withOutputStream { it << i }
}
logger.lifecycle("Downloaded ${file}")
} catch (Exception e) {
throw new GradleException("Failed to download ${file}: ${e.message}", e)
}
}
}
🤖 Prompt for AI Agents
In @gradle/security-setup.gradle around lines 17 - 24, The doLast closure that
downloads certificates (the block using local, local.parentFile.mkdirs(), and
new URL(...).withInputStream { ... }) lacks error handling; wrap the download
logic in a try-catch that catches IOException/Exception, log a clear error via
Gradle logger (logger.error or project.logger.error) including the URL and
exception message, remove any partially written local file on failure, and
rethrow a GradleException with a descriptive message so the build fails loudly
rather than with a cryptic stack trace.

Comment on lines +59 to +61
tasks.named('run') {
dependsOn tasks.matching { it.name.startsWith('download') && it.name.contains('pem') }
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Make the task dependency matching more specific.

The pattern it.name.startsWith('download') && it.name.contains('pem') could match unintended tasks if other download tasks are added in the future.

🔎 Proposed fix for more specific matching
       // Make run task depend on certificate downloads
       tasks.named('run') {
-        dependsOn tasks.matching { it.name.startsWith('download') && it.name.contains('pem') }
+        dependsOn tasks.matching { it.name in ['downloadEsnodepem', 'downloadEsnodekeypem', 'downloadKirkpem', 'downloadKirkkeypem', 'downloadRootcapem'] }
       }

Alternatively, store the task references when creating them:

   // Download security certificates
+  def downloadTasks = []
   ['esnode.pem', 'esnode-key.pem', 'kirk.pem', 'kirk-key.pem', 'root-ca.pem'].forEach { file ->
     File local = project.layout.buildDirectory.file(file).get().asFile
-    tasks.register("download${file.replace('-', '').replace('.', '').capitalize()}") {
+    downloadTasks << tasks.register("download${file.replace('-', '').replace('.', '').capitalize()}") {
       doLast {
         // ...
       }
     }
   }
   
   // Later...
   tasks.named('run') {
-    dependsOn tasks.matching { it.name.startsWith('download') && it.name.contains('pem') }
+    dependsOn downloadTasks
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
tasks.named('run') {
dependsOn tasks.matching { it.name.startsWith('download') && it.name.contains('pem') }
}
// Make run task depend on certificate downloads
tasks.named('run') {
dependsOn tasks.matching { it.name in ['downloadEsnodepem', 'downloadEsnodekeypem', 'downloadKirkpem', 'downloadKirkkeypem', 'downloadRootcapem'] }
}
🤖 Prompt for AI Agents
In @gradle/security-setup.gradle around lines 59 - 61, The current
tasks.named('run') dependsOn uses a broad predicate tasks.matching {
it.name.startsWith('download') && it.name.contains('pem') } which may match
unintended tasks; update it to target specific task names or stored references
instead: either change the predicate to an explicit name check (e.g., match the
exact download PEM task name(s) used when creating them) or capture the download
PEM Task objects when you create them and call dependsOn with those task
references; update the tasks.named('run') dependency to use those explicit task
names or stored Task references so only the intended download PEM tasks are
depended on.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 6, 2026

❌ Gradle check result for 0ab4dc8: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 6, 2026

❌ Gradle check result for 0ab4dc8: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@cwperks
Copy link
Copy Markdown
Member Author

cwperks commented Jan 6, 2026

Last failure again due to flakiness

> Task :test:fixtures:azure-fixture:composeBuild
The command '/bin/sh -c apt-get install -qqy openjdk-21-jre-headless' returned a non-zero code: 100
Service 'azure-fixture' failed to build : Build failed

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 6, 2026

❌ Gradle check result for 0ab4dc8: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 6, 2026

❌ Gradle check result for 0ab4dc8: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 6, 2026

✅ Gradle check result for 0ab4dc8: SUCCESS

@cwperks cwperks merged commit a5081f3 into opensearch-project:main Jan 6, 2026
37 of 45 checks passed
tanyabti pushed a commit to tanyabti/OpenSearch that referenced this pull request Feb 24, 2026
…ledPlugins="['opensearch-security']" (opensearch-project#20372)

* Install demon security information when running ./gradlew run -PinstalledPlugins="['opensearch-security']"

Signed-off-by: Craig Perkins <cwperx@amazon.com>

* Add to CHANGELOG

Signed-off-by: Craig Perkins <cwperx@amazon.com>

* Address review comments

Signed-off-by: Craig Perkins <cwperx@amazon.com>

---------

Signed-off-by: Craig Perkins <cwperx@amazon.com>
tanyabti pushed a commit to tanyabti/OpenSearch that referenced this pull request Feb 24, 2026
…ledPlugins="['opensearch-security']" (opensearch-project#20372)

* Install demon security information when running ./gradlew run -PinstalledPlugins="['opensearch-security']"

Signed-off-by: Craig Perkins <cwperx@amazon.com>

* Add to CHANGELOG

Signed-off-by: Craig Perkins <cwperx@amazon.com>

* Address review comments

Signed-off-by: Craig Perkins <cwperx@amazon.com>

---------

Signed-off-by: Craig Perkins <cwperx@amazon.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants