From 0d8359812f149e37ca240ef0e8abca1c70461112 Mon Sep 17 00:00:00 2001 From: Lucas Bajolet Date: Thu, 1 Feb 2024 11:50:19 -0500 Subject: [PATCH] builder: don't log requests/responses by default The logs of the Azure builder are very verbose by default, as they log the contents of every request/response to/from the Azure APIs. For regular debugging of a template, this is not necessary, as just looking at the errors returned by the calls will generally give enough information to proceed with fixing the template. These logs may be relevant when attempting to debug the plugin itself however, so we add one extra environment variable to allow the plugin to print them out, PACKER_AZURE_DEBUG_LOGS. If it is defined, and non empty, the requests and responses will be dumped to stderr, otherwise, they are silent. --- .web-docs/README.md | 12 ++++++ builder/azure/arm/inspector.go | 73 +++++++++++++++++-------------- builder/azure/common/env.go | 14 ++++++ builder/azure/dtl/inspector.go | 79 +++++++++++++++++++--------------- docs/README.md | 10 +++++ 5 files changed, 122 insertions(+), 66 deletions(-) create mode 100644 builder/azure/common/env.go diff --git a/.web-docs/README.md b/.web-docs/README.md index 68676191..0cfd6643 100644 --- a/.web-docs/README.md +++ b/.web-docs/README.md @@ -100,3 +100,15 @@ you should specify `subscription_id`, `client_id` and one of `client_secret`, associated with your service principal principal. See [Azure Active Directory docs](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials) for more information. + +## Troubleshooting + +As with any Packer plugin, you may produce verbose logs if you encounter a problem, and the normal logs don't help narrow down the issue. +To do so, you will need to set the `PACKER_LOG` environment variable to a non-zero value (e.g. "1", "y", or any non-empty string). +This will enable some verbose logs that can help you figure out which part of the process errors, and hopefully why. + +In addition to this, you may also enable the `PACKER_AZURE_DEBUG_LOG` environment variable, in addition to `PACKER_LOG`. +Enabling this will add request/response inspection in the logs, along with the body sent with each request to the Azure APIs. + +~> Warning: the `PACKER_AZURE_DEBUG_LOG` variable is very verbose, and may expose sensitive information in the logs. + For this reason, we strongly advise only enabling this in a trusted environment, and only for a temporary debugging session. diff --git a/builder/azure/arm/inspector.go b/builder/azure/arm/inspector.go index 7bac9576..8eb76b88 100644 --- a/builder/azure/arm/inspector.go +++ b/builder/azure/arm/inspector.go @@ -13,6 +13,7 @@ import ( "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/azure" "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/packer-plugin-azure/builder/azure/common" "github.com/hashicorp/packer-plugin-azure/builder/azure/common/logutil" ) @@ -46,14 +47,16 @@ func handleBody(body io.ReadCloser, maxlen int64) (io.ReadCloser, string) { func withInspection(maxlen int64) autorest.PrepareDecorator { return func(p autorest.Preparer) autorest.Preparer { return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { - body, bodyString := handleBody(r.Body, maxlen) - r.Body = body - - log.Print("Azure request", logutil.Fields{ - "method": r.Method, - "request": r.URL.String(), - "body": bodyString, - }) + if common.IsDebugEnabled() { + body, bodyString := handleBody(r.Body, maxlen) + r.Body = body + + log.Print("Azure request", logutil.Fields{ + "method": r.Method, + "request": r.URL.String(), + "body": bodyString, + }) + } return p.Prepare(r) }) } @@ -61,14 +64,16 @@ func withInspection(maxlen int64) autorest.PrepareDecorator { func withInspectionTrack2(maxlen int64) client.RequestMiddleware { return func(r *http.Request) (*http.Request, error) { - body, bodyString := handleBody(r.Body, maxlen) - r.Body = body + if common.IsDebugEnabled() { + body, bodyString := handleBody(r.Body, maxlen) + r.Body = body - log.Print("Azure request", logutil.Fields{ - "method": r.Method, - "request": r.URL.String(), - "body": bodyString, - }) + log.Print("Azure request", logutil.Fields{ + "method": r.Method, + "request": r.URL.String(), + "body": bodyString, + }) + } return r, nil } } @@ -76,6 +81,26 @@ func withInspectionTrack2(maxlen int64) client.RequestMiddleware { func byInspecting(maxlen int64) autorest.RespondDecorator { return func(r autorest.Responder) autorest.Responder { return autorest.ResponderFunc(func(resp *http.Response) error { + if common.IsDebugEnabled() { + body, bodyString := handleBody(resp.Body, maxlen) + resp.Body = body + + log.Print("Azure response", logutil.Fields{ + "status": resp.Status, + "method": resp.Request.Method, + "request": resp.Request.URL.String(), + "x-ms-request-id": azure.ExtractRequestID(resp), + "body": bodyString, + }) + } + return r.Respond(resp) + }) + } +} + +func byInspectingTrack2(maxlen int64) client.ResponseMiddleware { + return func(req *http.Request, resp *http.Response) (*http.Response, error) { + if common.IsDebugEnabled() { body, bodyString := handleBody(resp.Body, maxlen) resp.Body = body @@ -86,23 +111,7 @@ func byInspecting(maxlen int64) autorest.RespondDecorator { "x-ms-request-id": azure.ExtractRequestID(resp), "body": bodyString, }) - return r.Respond(resp) - }) - } -} - -func byInspectingTrack2(maxlen int64) client.ResponseMiddleware { - return func(req *http.Request, resp *http.Response) (*http.Response, error) { - body, bodyString := handleBody(resp.Body, maxlen) - resp.Body = body - - log.Print("Azure response", logutil.Fields{ - "status": resp.Status, - "method": resp.Request.Method, - "request": resp.Request.URL.String(), - "x-ms-request-id": azure.ExtractRequestID(resp), - "body": bodyString, - }) + } return resp, nil } diff --git a/builder/azure/common/env.go b/builder/azure/common/env.go new file mode 100644 index 00000000..5eb5decd --- /dev/null +++ b/builder/azure/common/env.go @@ -0,0 +1,14 @@ +package common + +import "os" + +const AzureDebugLogsEnvVar string = "PACKER_AZURE_DEBUG_LOG" + +func IsDebugEnabled() bool { + debug, defined := os.LookupEnv(AzureDebugLogsEnvVar) + if !defined { + return false + } + + return debug != "" +} diff --git a/builder/azure/dtl/inspector.go b/builder/azure/dtl/inspector.go index 0ca7279e..6300cb40 100644 --- a/builder/azure/dtl/inspector.go +++ b/builder/azure/dtl/inspector.go @@ -12,6 +12,7 @@ import ( "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/azure" "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/packer-plugin-azure/builder/azure/common" "github.com/hashicorp/packer-plugin-azure/builder/azure/common/logutil" ) @@ -41,14 +42,16 @@ func handleBody(body io.ReadCloser, maxlen int64) (io.ReadCloser, string) { func withInspection(maxlen int64) autorest.PrepareDecorator { return func(p autorest.Preparer) autorest.Preparer { return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { - body, bodyString := handleBody(r.Body, maxlen) - r.Body = body - - log.Print("Azure request", logutil.Fields{ - "method": r.Method, - "request": r.URL.String(), - "body": bodyString, - }) + if common.IsDebugEnabled() { + body, bodyString := handleBody(r.Body, maxlen) + r.Body = body + + log.Print("Azure request", logutil.Fields{ + "method": r.Method, + "request": r.URL.String(), + "body": bodyString, + }) + } return p.Prepare(r) }) } @@ -57,16 +60,19 @@ func withInspection(maxlen int64) autorest.PrepareDecorator { func byInspecting(maxlen int64) autorest.RespondDecorator { return func(r autorest.Responder) autorest.Responder { return autorest.ResponderFunc(func(resp *http.Response) error { - body, bodyString := handleBody(resp.Body, maxlen) - resp.Body = body + if common.IsDebugEnabled() { + body, bodyString := handleBody(resp.Body, maxlen) + resp.Body = body + + log.Print("Azure response", logutil.Fields{ + "status": resp.Status, + "method": resp.Request.Method, + "request": resp.Request.URL.String(), + "x-ms-request-id": azure.ExtractRequestID(resp), + "body": bodyString, + }) + } - log.Print("Azure response", logutil.Fields{ - "status": resp.Status, - "method": resp.Request.Method, - "request": resp.Request.URL.String(), - "x-ms-request-id": azure.ExtractRequestID(resp), - "body": bodyString, - }) return r.Respond(resp) }) } @@ -74,30 +80,35 @@ func byInspecting(maxlen int64) autorest.RespondDecorator { func withInspectionTrack2(maxlen int64) client.RequestMiddleware { return func(r *http.Request) (*http.Request, error) { - body, bodyString := handleBody(r.Body, maxlen) - r.Body = body + if common.IsDebugEnabled() { + body, bodyString := handleBody(r.Body, maxlen) + r.Body = body + + log.Print("Azure request", logutil.Fields{ + "method": r.Method, + "request": r.URL.String(), + "body": bodyString, + }) + } - log.Print("Azure request", logutil.Fields{ - "method": r.Method, - "request": r.URL.String(), - "body": bodyString, - }) return r, nil } } func byInspectingTrack2(maxlen int64) client.ResponseMiddleware { return func(req *http.Request, resp *http.Response) (*http.Response, error) { - body, bodyString := handleBody(resp.Body, maxlen) - resp.Body = body - - log.Print("Azure response", logutil.Fields{ - "status": resp.Status, - "method": resp.Request.Method, - "request": resp.Request.URL.String(), - "x-ms-request-id": azure.ExtractRequestID(resp), - "body": bodyString, - }) + if common.IsDebugEnabled() { + body, bodyString := handleBody(resp.Body, maxlen) + resp.Body = body + + log.Print("Azure response", logutil.Fields{ + "status": resp.Status, + "method": resp.Request.Method, + "request": resp.Request.URL.String(), + "x-ms-request-id": azure.ExtractRequestID(resp), + "body": bodyString, + }) + } return resp, nil } diff --git a/docs/README.md b/docs/README.md index 62efdfd9..d7d6e012 100644 --- a/docs/README.md +++ b/docs/README.md @@ -87,3 +87,13 @@ you should specify `subscription_id`, `client_id` and one of `client_secret`, associated with your service principal principal. See [Azure Active Directory docs](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials) for more information. + +## Troubleshooting + +As with any Packer plugin, you may produce verbose logs to troubleshoot if the default output does not help narrow down the issue. +To do so, you can set the `PACKER_LOG` environment variable to a non-zero value (e.g. "1" or any non-empty string) to enable verbose logs that can help you figure out which part of the process errors, and hopefully why. + +In addition to this, you may also enable the `PACKER_AZURE_DEBUG_LOG` environment variable alongside `PACKER_LOG` for visibility into the API calls being made to the Azure platform. +Enabling this will add HTTP response inspection in the logs and the body sent with each request to the Azure APIs. + +~> Warning: the `PACKER_AZURE_DEBUG_LOG` variable contains a high degree of verbosity and may expose sensitive information in the logs. For this reason, we strongly advise only enabling this in a trusted environment and only for a temporary debugging session.