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.