terraform-provider-gitea/vendor/github.com/hashicorp/terraform-plugin-go/internal/logging/protocol_data.go
dependabot[bot] 84c9110a24
Bump github.com/hashicorp/terraform-plugin-sdk/v2 from 2.24.1 to 2.26.0
Bumps [github.com/hashicorp/terraform-plugin-sdk/v2](https://github.com/hashicorp/terraform-plugin-sdk) from 2.24.1 to 2.26.0.
- [Release notes](https://github.com/hashicorp/terraform-plugin-sdk/releases)
- [Changelog](https://github.com/hashicorp/terraform-plugin-sdk/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/terraform-plugin-sdk/compare/v2.24.1...v2.26.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/terraform-plugin-sdk/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 20:25:53 +00:00

145 lines
4.1 KiB
Go

package logging
import (
"context"
"fmt"
"os"
"path"
"sync"
"time"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
)
const (
// fileExtEmpty is the file extension for empty data.
// Empty data may be expected, depending on the RPC.
fileExtEmpty = "empty"
// fileExtJson is the file extension for JSON data.
fileExtJson = "json"
// fileExtMsgpack is the file extension for MessagePack data.
fileExtMsgpack = "msgpack"
)
var protocolDataSkippedLog sync.Once
// ProtocolData emits raw protocol data to a file, if given a directory.
//
// The directory must exist and be writable, prior to invoking this function.
//
// File names are in the format: {TIME}_{RPC}_{MESSAGE}_{FIELD}.{EXT}
func ProtocolData(ctx context.Context, dataDir string, rpc string, message string, field string, data interface{}) {
if dataDir == "" {
// Write a log, only once, that explains how to enable this functionality.
protocolDataSkippedLog.Do(func() {
ProtocolTrace(ctx, "Skipping protocol data file writing because no data directory is set. "+
fmt.Sprintf("Use the %s environment variable to enable this functionality.", EnvTfLogSdkProtoDataDir))
})
return
}
var fileContents []byte
var fileExtension string
switch data := data.(type) {
case *tfprotov5.DynamicValue:
fileExtension, fileContents = protocolDataDynamicValue5(ctx, data)
case *tfprotov6.DynamicValue:
fileExtension, fileContents = protocolDataDynamicValue6(ctx, data)
default:
ProtocolError(ctx, fmt.Sprintf("Skipping unknown protocol data type: %T", data))
return
}
writeProtocolFile(ctx, dataDir, rpc, message, field, fileExtension, fileContents)
}
// ProtocolPrivateData emits raw protocol private data to a file, if given a
// directory. This data is "private" in the sense that it is provider-owned,
// rather than something managed by Terraform.
//
// The directory must exist and be writable, prior to invoking this function.
//
// File names are in the format: {TIME}_{RPC}_{MESSAGE}_{FIELD}(.empty)
func ProtocolPrivateData(ctx context.Context, dataDir string, rpc string, message string, field string, data []byte) {
if dataDir == "" {
// Write a log, only once, that explains how to enable this functionality.
protocolDataSkippedLog.Do(func() {
ProtocolTrace(ctx, "Skipping protocol data file writing because no data directory is set. "+
fmt.Sprintf("Use the %s environment variable to enable this functionality.", EnvTfLogSdkProtoDataDir))
})
return
}
var fileExtension string
if len(data) == 0 {
fileExtension = fileExtEmpty
}
writeProtocolFile(ctx, dataDir, rpc, message, field, fileExtension, data)
}
func protocolDataDynamicValue5(_ context.Context, value *tfprotov5.DynamicValue) (string, []byte) {
if value == nil {
return fileExtEmpty, nil
}
// (tfprotov5.DynamicValue).Unmarshal() prefers JSON first, so prefer to
// output JSON if found.
if len(value.JSON) > 0 {
return fileExtJson, value.JSON
}
if len(value.MsgPack) > 0 {
return fileExtMsgpack, value.MsgPack
}
return fileExtEmpty, nil
}
func protocolDataDynamicValue6(_ context.Context, value *tfprotov6.DynamicValue) (string, []byte) {
if value == nil {
return fileExtEmpty, nil
}
// (tfprotov6.DynamicValue).Unmarshal() prefers JSON first, so prefer to
// output JSON if found.
if len(value.JSON) > 0 {
return fileExtJson, value.JSON
}
if len(value.MsgPack) > 0 {
return fileExtMsgpack, value.MsgPack
}
return fileExtEmpty, nil
}
func writeProtocolFile(ctx context.Context, dataDir string, rpc string, message string, field string, fileExtension string, fileContents []byte) {
fileName := fmt.Sprintf("%d_%s_%s_%s", time.Now().UnixMilli(), rpc, message, field)
if fileExtension != "" {
fileName += "." + fileExtension
}
filePath := path.Join(dataDir, fileName)
ctx = ProtocolSetField(ctx, KeyProtocolDataFile, filePath)
ProtocolTrace(ctx, "Writing protocol data file")
err := os.WriteFile(filePath, fileContents, 0644)
if err != nil {
ProtocolError(ctx, "Unable to write protocol data file", map[string]any{KeyError: err.Error()})
return
}
ProtocolTrace(ctx, "Wrote protocol data file")
}