Skip to content

NGINX Configs to Reference Remote External Files#1389

Merged
Akshay2191 merged 32 commits intomainfrom
external-file-mgmt-integration
Jan 23, 2026
Merged

NGINX Configs to Reference Remote External Files#1389
Akshay2191 merged 32 commits intomainfrom
external-file-mgmt-integration

Conversation

@Akshay2191
Copy link
Copy Markdown
Contributor

Extends the ConfigApply capability to manage NGINX configurations that reference external resources hosted at remote URLs. The agent now handles downloading of these files into the NGINX configuration directory before applying the new configuration.

Checklist

Before creating a PR, run through this checklist and mark each as complete.

  • I have read the CONTRIBUTING document
  • I have run make install-tools and have attached any dependency changes to this pull request
  • If applicable, I have added tests that prove my fix is effective or that my feature works
  • If applicable, I have checked that any relevant tests pass after adding my changes
  • If applicable, I have updated any relevant documentation (README.md)
  • If applicable, I have tested my cross-platform changes on Ubuntu 22, Redhat 8, SUSE 15 and FreeBSD 13

@Akshay2191 Akshay2191 requested a review from a team as a code owner November 12, 2025 15:50
@github-actions github-actions bot added the chore Pull requests for routine tasks label Nov 12, 2025
@codecov
Copy link
Copy Markdown

codecov bot commented Nov 12, 2025

Codecov Report

❌ Patch coverage is 80.74324% with 57 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.05%. Comparing base (02f4c36) to head (c74c4dc).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
internal/file/external_file_operator.go 79.67% 19 Missing and 19 partials ⚠️
internal/file/file_manager_service.go 71.79% 9 Missing and 2 partials ⚠️
internal/file/file_plugin.go 0.00% 4 Missing ⚠️
internal/config/config.go 93.75% 2 Missing and 1 partial ⚠️
internal/file/file_service_operator.go 94.44% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1389      +/-   ##
==========================================
- Coverage   85.13%   85.05%   -0.09%     
==========================================
  Files         102      103       +1     
  Lines       13217    13487     +270     
==========================================
+ Hits        11252    11471     +219     
- Misses       1475     1506      +31     
- Partials      490      510      +20     
Files with missing lines Coverage Δ
internal/config/defaults.go 100.00% <ø> (ø)
internal/config/flags.go 100.00% <ø> (ø)
internal/config/types.go 87.65% <ø> (ø)
internal/model/config.go 90.47% <ø> (ø)
internal/file/file_service_operator.go 77.46% <94.44%> (+0.64%) ⬆️
internal/config/config.go 87.70% <93.75%> (+0.26%) ⬆️
internal/file/file_plugin.go 75.08% <0.00%> (-0.74%) ⬇️
internal/file/file_manager_service.go 74.48% <71.79%> (-0.76%) ⬇️
internal/file/external_file_operator.go 79.67% <79.67%> (ø)

... and 1 file with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 02f4c36...c74c4dc. Read the comment docs.

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

@Akshay2191 Akshay2191 self-assigned this Nov 19, 2025
wantErrMsg string
wantErr bool
}{
{
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The following scenarios could increase coverage:

  • No destination specified
  • Restricted directory.
  • Two files to the same destination.

}{
{
name: "Test 1: success",
prepare: func(t *testing.T) (string, string) {
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.

Can this be changed to follow the way other tests are set up and formatted

}

//nolint:gocognit,revive,govet // cognitive complexity is 22
func TestFileManagerService_downloadExternalFiles_Cases(t *testing.T) {
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.

Can this test be simplified and changed to match the way other tests are set up and structured

assert.Equal(t, fileName, dstArg, "RenameExternalFile destination argument mismatch")
}

func TestDownloadFileContent_MaxBytesLimit(t *testing.T) {
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.

Can these tests please be combined

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I tried to consolidate these divergent test scenarios (MaxBytes vs. Proxy Errors) but it spiked the cognitive complexity to 23 due the very different validation steps. Therefore I kept them seperate.

@github-actions github-actions bot added dependencies documentation Improvements or additions to documentation labels Dec 18, 2025
@Akshay2191 Akshay2191 force-pushed the external-file-mgmt-integration branch from e50d100 to 2e981e0 Compare December 19, 2025 00:30
@Akshay2191 Akshay2191 marked this pull request as draft January 6, 2026 15:26
@Akshay2191 Akshay2191 changed the title NGINX Configs to Reference Remote External Files Draft : NGINX Configs to Reference Remote External Files Jan 7, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 9, 2026

✅ All required contributors have signed the F5 CLA for this PR. Thank you!
Posted by the CLA Assistant Lite bot.

@Akshay2191 Akshay2191 force-pushed the external-file-mgmt-integration branch from 52e6aa3 to 99042ad Compare January 12, 2026 11:24
@Akshay2191 Akshay2191 changed the title Draft : NGINX Configs to Reference Remote External Files NGINX Configs to Reference Remote External Files Jan 15, 2026
@Akshay2191 Akshay2191 marked this pull request as ready for review January 15, 2026 10:37
for _, domain := range domains {
// Validating syntax using the RFC-compliant regex
if !domainRegex.MatchString(domain) || domain == "" {
slog.Error("domain specified in allowed_domains is invalid", "domain", domain)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can you remove this log line and have a log message in the resolveExternalDataSource function instead?

}

if err := validateAllowedDomains(externalDataSource.AllowedDomains); err != nil {
return nil
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can you add a log line here like this

slog.Error("External data source not configured due to invalid configuration", "error", err)

permission := fileAction.File.GetFileMeta().GetPermissions()
fileName := fileAction.File.GetFileMeta().GetName()

slog.InfoContext(ctx, "Downloading external file from", "location", location)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
slog.InfoContext(ctx, "Downloading external file from", "location", location)
slog.InfoContext(ctx, "Downloading external file", "location", location)

headers.ETag = resp.Header.Get("ETag")
headers.LastModified = resp.Header.Get("Last-Modified")
case http.StatusNotModified:
slog.DebugContext(ctx, "File content unchanged (304 Not Modified)", "file_name", fileName)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
slog.DebugContext(ctx, "File content unchanged (304 Not Modified)", "file_name", fileName)
slog.InfoContext(ctx, "Received 304 status code in response from external data source, file has not been modified", "file_name", fileName)

I think this would be better as info instead for debug

case model.Delete:
slog.InfoContext(ctx, "Deleting file", "file", fileAction.File.GetFileMeta().GetName())
if err := os.Remove(fileAction.File.GetFileMeta().GetName()); err != nil && !os.IsNotExist(err) {
slog.DebugContext(ctx, "Deleting file", "file", fileMeta.GetName())
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
slog.DebugContext(ctx, "Deleting file", "file", fileMeta.GetName())
slog.InfoContext(ctx, "Deleting file", "file", fileMeta.GetName())

if rollbackErr != nil {
// include both the original apply error and the rollback error so the management plane
// receives actionable information about what failed during apply and what failed during rollback
combinedErr := fmt.Sprintf("apply error: %s; rollback error: %s", err.Error(), rollbackErr.Error())
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Would it be better to use errors.Join function here?

@Akshay2191 Akshay2191 merged commit 9e67328 into main Jan 23, 2026
66 of 70 checks passed
@Akshay2191 Akshay2191 deleted the external-file-mgmt-integration branch January 23, 2026 12:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore Pull requests for routine tasks dependencies documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants