From 401268b7a7dc10616c4a7151da530edcffd64b5c Mon Sep 17 00:00:00 2001 From: Saar Dagan Date: Wed, 11 Feb 2026 16:34:32 +0200 Subject: [PATCH 1/4] add support for file-based-vcap feature --- .../Dynatrace/libbuildpack-dynatrace/hook.go | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/vendor/github.com/Dynatrace/libbuildpack-dynatrace/hook.go b/vendor/github.com/Dynatrace/libbuildpack-dynatrace/hook.go index bef46b816..95a502ce1 100644 --- a/vendor/github.com/Dynatrace/libbuildpack-dynatrace/hook.go +++ b/vendor/github.com/Dynatrace/libbuildpack-dynatrace/hook.go @@ -25,8 +25,9 @@ type Command interface { Execute(string, io.Writer, io.Writer, string, ...string) error } -// credentials represent the user settings extracted from the environment. -type credentials struct { +// Credentials represent the user settings extracted from the environment. +// Exported for testing purposes. +type Credentials struct { ServiceName string EnvironmentID string CustomOneAgentURL string @@ -38,6 +39,9 @@ type credentials struct { AddTechnologies string } +// credentials is an alias for backward compatibility +type credentials = Credentials + // Hook implements libbuildpack.Hook. It downloads and install the Dynatrace OneAgent. type Hook struct { libbuildpack.DefaultHook @@ -139,6 +143,11 @@ func (h *Hook) AfterCompile(stager *libbuildpack.Stager) error { // getCredentials returns the configuration from the environment, or nil if not found. The credentials are represented // as a JSON object in the VCAP_SERVICES environment variable. +// GetCredentials is exported for testing purposes. +func (h *Hook) GetCredentials() *credentials { + return h.getCredentials() +} + func (h *Hook) getCredentials() *credentials { // Represent the structure of the JSON object in VCAP_SERVICES for parsing. @@ -147,7 +156,23 @@ func (h *Hook) getCredentials() *credentials { Credentials map[string]interface{} `json:"credentials"` } - if err := json.Unmarshal([]byte(os.Getenv("VCAP_SERVICES")), &vcapServices); err != nil { + var vcapServicesContent string + + // Check if VCAP_SERVICES_FILE_PATH is set + if filePath := os.Getenv("VCAP_SERVICES_FILE_PATH"); filePath != "" { + h.Log.Debug("Reading VCAP_SERVICES from file: %s", filePath) + fileContent, err := os.ReadFile(filePath) + if err != nil { + h.Log.Debug("Failed to read VCAP_SERVICES file at %s: %s", filePath, err) + return nil + } + vcapServicesContent = string(fileContent) + } else { + // Fall back to VCAP_SERVICES environment variable + vcapServicesContent = os.Getenv("VCAP_SERVICES") + } + + if err := json.Unmarshal([]byte(vcapServicesContent), &vcapServices); err != nil { h.Log.Debug("Failed to unmarshal VCAP_SERVICES: %s", err) return nil } From 6fb862a8b69c3fcee73ceadb2dc4e2aab7f8fd5c Mon Sep 17 00:00:00 2001 From: Saar Dagan Date: Wed, 11 Feb 2026 16:42:32 +0200 Subject: [PATCH 2/4] added tests for file-based-vcap --- src/nodejs/integration/dynatrace_test.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/nodejs/integration/dynatrace_test.go b/src/nodejs/integration/dynatrace_test.go index dd04a196f..0666ab91d 100644 --- a/src/nodejs/integration/dynatrace_test.go +++ b/src/nodejs/integration/dynatrace_test.go @@ -176,5 +176,28 @@ func testDynatrace(platform switchblade.Platform, fixtures, uri string) func(*te )) }) }) + + context("when VCAP_SERVICES_FILE_PATH environment variable is set", func() { + it("reads VCAP_SERVICES from the file path", func() { + vcapServicesFile := filepath.Join(fixtures, "util", "dynatrace", "vcap_services.json") + + _, logs, err := platform.Deploy. + WithEnv(map[string]string{ + "BP_DEBUG": "true", + "VCAP_SERVICES_FILE_PATH": vcapServicesFile, + }). + Execute(name, filepath.Join(fixtures, "simple")) + Expect(err).NotTo(HaveOccurred()) + + Expect(logs.String()).To(SatisfyAll( + ContainSubstring("Reading VCAP_SERVICES from file"), + ContainSubstring("Dynatrace service credentials found. Setting up Dynatrace OneAgent."), + ContainSubstring("Starting Dynatrace OneAgent installer"), + ContainSubstring("Copy dynatrace-env.sh"), + ContainSubstring("Dynatrace OneAgent installed."), + ContainSubstring("Dynatrace OneAgent injection is set up."), + )) + }) + }) } } From 56d839469f9acdea7dda83196a1b4689c457461b Mon Sep 17 00:00:00 2001 From: Saar Dagan Date: Wed, 11 Feb 2026 16:45:46 +0200 Subject: [PATCH 3/4] added mock file --- src/nodejs/integration/vcap_services.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/nodejs/integration/vcap_services.json diff --git a/src/nodejs/integration/vcap_services.json b/src/nodejs/integration/vcap_services.json new file mode 100644 index 000000000..27c5c1612 --- /dev/null +++ b/src/nodejs/integration/vcap_services.json @@ -0,0 +1,12 @@ +{ + "some-dynatrace": [ + { + "name": "some-dynatrace", + "credentials": { + "apitoken": "secretpaastoken", + "apiurl": "http://localhost:8080", + "environmentid": "envid" + } + } + ] +} From 20d8097ff9cc18a27a364fea9f5a7ba5984dce59 Mon Sep 17 00:00:00 2001 From: Saar Dagan Date: Wed, 11 Feb 2026 16:48:25 +0200 Subject: [PATCH 4/4] changed location for mock file --- .../integration => fixtures/util/dynatrace}/vcap_services.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {src/nodejs/integration => fixtures/util/dynatrace}/vcap_services.json (100%) diff --git a/src/nodejs/integration/vcap_services.json b/fixtures/util/dynatrace/vcap_services.json similarity index 100% rename from src/nodejs/integration/vcap_services.json rename to fixtures/util/dynatrace/vcap_services.json