From d860f3d9f29b761afbe61dc91910bb6df16af554 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Fri, 15 Mar 2024 09:54:58 -0700 Subject: [PATCH] feat(logs): Adding tflog support --- v2/api/client.go | 139 ++++++++--------------------------------------- v2/go.mod | 4 +- v2/go.sum | 36 ++++++++++-- 3 files changed, 56 insertions(+), 123 deletions(-) diff --git a/v2/api/client.go b/v2/api/client.go index 08d10ce..b71a093 100644 --- a/v2/api/client.go +++ b/v2/api/client.go @@ -2,12 +2,13 @@ package api import ( "bytes" + "context" "encoding/base64" "encoding/json" "errors" "fmt" - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" + "github.com/hashicorp/terraform-plugin-log/tflog" + "log" "net/http" "net/http/httputil" "net/url" @@ -47,17 +48,15 @@ type AuthConfig struct { Timeout int } -func initLogger() { - zerolog.TimeFieldFormat = zerolog.TimeFormatUnix - log.Logger = log.With().Caller().Logger() - log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339}) - zerolog.SetGlobalLevel(zerolog.DebugLevel) -} - // NewKeyfactorClient creates a new Keyfactor client instance. A configured Client is returned with methods used to // interact with Keyfactor. func NewKeyfactorClient(auth *AuthConfig) (*Client, error) { - initLogger() + // set log to stdout + log.SetOutput(os.Stdout) + log.Printf("[INFO] Logging into Keyfactor at host %s", auth.Hostname) + ctx := context.Background() + tflog.SetField(ctx, "hostname", auth.Hostname) + tflog.Info(ctx, "Logging into Keyfactor Command") c, err := loginToKeyfactor(auth) if err != nil { return nil, err @@ -75,8 +74,6 @@ func NewKeyfactorClient(auth *AuthConfig) (*Client, error) { // loginToKeyfactor is a helper function that creates a new Keyfactor client instance. A configured Client is returned // with methods used to interact with Keyfactor. func loginToKeyfactor(auth *AuthConfig) (*Client, error) { - initLogger() - log.Debug().Msg("Entering loginToKeyfactor") if auth.Hostname == "" { envHostname := os.Getenv(EnvCommandHostname) if envHostname != "" { @@ -85,7 +82,6 @@ func loginToKeyfactor(auth *AuthConfig) (*Client, error) { return nil, fmt.Errorf("%s is required", EnvCommandHostname) } } - log.Debug().Str("hostname", auth.Hostname).Send() if auth.APIPath == "" { envAPIPath := os.Getenv(EnvCommandAPI) if envAPIPath != "" { @@ -107,11 +103,9 @@ func loginToKeyfactor(auth *AuthConfig) (*Client, error) { auth.Username = envUsername } } else { - log.Error().Msgf("%s is required", EnvCommandUsername) return nil, fmt.Errorf("%s is required", EnvCommandUsername) } } - log.Debug().Str("username", auth.Username).Send() if auth.Password == "" { envPassword := os.Getenv(EnvCommandPassword) if envPassword != "" { @@ -120,10 +114,6 @@ func loginToKeyfactor(auth *AuthConfig) (*Client, error) { return nil, fmt.Errorf("%s is required", EnvCommandPassword) } } - if auth.Password != "" { - log.Debug().Str("password", "********").Msg("Password is set") - } - log.Trace().Str("password", auth.Password).Send() headers := &apiHeaders{ Headers: []StringTuple{ @@ -131,7 +121,6 @@ func loginToKeyfactor(auth *AuthConfig) (*Client, error) { {"x-keyfactor-requested-with", "APIClient"}, }, } - log.Trace().Interface("headers", headers).Msg("Request headers for Keyfactor API call") keyfactorAPIStruct := &request{ Method: "GET", @@ -150,15 +139,7 @@ func loginToKeyfactor(auth *AuthConfig) (*Client, error) { } else if auth.Timeout > 0 { timeout = auth.Timeout } - log.Debug(). - Int("timeout", timeout). - Msg("Timeout for Keyfactor API call in seconds") - - log.Debug(). - Str("hostname", auth.Hostname). - Int("timeout", timeout). - Str("apiPath", auth.APIPath). - Msg("Creating Keyfactor Command client") + c := &Client{ Hostname: auth.Hostname, httpClient: &http.Client{Timeout: time.Duration(timeout) * time.Second}, @@ -166,15 +147,13 @@ func loginToKeyfactor(auth *AuthConfig) (*Client, error) { ApiPath: auth.APIPath, } - log.Debug().Msg("Calling sendRequest...") _, err := c.sendRequest(keyfactorAPIStruct) if err != nil { - log.Error().Err(err).Msg("Keyfactor Command returned an error.") return nil, err } - log.Info().Msg("Successfully connected to Keyfactor Command") - log.Debug().Msg("Exiting loginToKeyfactor") + log.Printf("[INFO] Successfully logged into Keyfactor at host %s", c.Hostname) + return c, nil } @@ -182,68 +161,43 @@ func loginToKeyfactor(auth *AuthConfig) (*Client, error) { // using the configuration data inside. It returns a pointer to an http response // struct and an error, if applicable. func (c *Client) sendRequest(request *request) (*http.Response, error) { - initLogger() if c == nil { return nil, errors.New("invalid Keyfactor client, please check your configuration") } u, err := url.Parse(c.Hostname) // Parse raw Hostname into URL structure if err != nil { - log.Error().Err(err).Msg("Error parsing Keyfactor hostname") return nil, err - } if u.Scheme != "https" { - log.Warn().Str("scheme", u.Scheme).Msg("Keyfactor hostname is not using HTTPS, this is not allowed.") u.Scheme = "https" } endpoint := fmt.Sprintf("%s/", strings.Trim(c.ApiPath, "/")) + request.Endpoint - log.Debug().Str("endpoint", endpoint).Msg("Endpoint for Keyfactor API call") u.Path = path.Join(u.Path, endpoint) // Attach enroll endpoint - log.Debug().Str("path", u.Path).Msg("Path for Keyfactor API call") // Set request query if request.Query != nil { - log.Debug().Msg("Query passed to Keyfactor API call") - log.Trace().Interface("query", request.Query).Msg("Query for Keyfactor API call") queryString := u.Query() - log.Debug().Interface("query", queryString).Msg("Query string for Keyfactor API call") for _, query := range request.Query.Query { queryString.Set(query.Elem1, query.Elem2) } - log.Debug().Interface("query", queryString).Msg("Encoding query string") u.RawQuery = queryString.Encode() - log.Trace().Str("rawQuery", u.RawQuery).Msg("Raw query string for Keyfactor API call") u.RawQuery = strings.ReplaceAll(u.RawQuery, "+", "%20") - log.Trace().Str("rawQuery", u.RawQuery).Msg("Raw query string w/ replacements for Keyfactor API call") } keyfactorPath := u.String() // Convert absolute path to string - //log.Printf("[INFO] Preparing a %s request to path '%s'", request.Method, keyfactorPath) - log.Info(). - Str("method", request.Method). - Str("hostname", c.Hostname). - Str("endpoint", request.Endpoint). - Str("apiPath", c.ApiPath). - Str("path", keyfactorPath). - Str("query", u.RawQuery). - Msg("Preparing JSON payload for Keyfactor API call") - log.Trace().Interface("payload", request.Payload).Msg("Payload for Keyfactor API call") + log.Printf("[INFO] Preparing a %s request to path '%s'", request.Method, keyfactorPath) jsonByes, mErr := json.Marshal(request.Payload) if mErr != nil { - log.Error().Err(mErr).Msg("Error marshalling JSON payload for Keyfactor API call") return nil, mErr } - log.Trace().Bytes("json", jsonByes).Msg("JSON payload for Keyfactor API call") + //log.Printf("[TRACE] Request body: %s", jsonByes) - log.Debug().Msg("Creating HTTP request for Keyfactor API call") req, reqErr := http.NewRequest(request.Method, keyfactorPath, bytes.NewBuffer(jsonByes)) if reqErr != nil { - log.Error().Err(reqErr).Msg("Error creating HTTP request for Keyfactor API call") return nil, reqErr } - log.Debug().Msg("Setting request headers for Keyfactor API call") req.Header.Set("Content-Type", "application/json") req.Header.Set("Accept", "application/json") req.Header.Set("Authorization", c.basicAuthString) @@ -252,123 +206,82 @@ func (c *Client) sendRequest(request *request) (*http.Response, error) { for _, headers := range request.Headers.Headers { req.Header.Set(headers.Elem1, headers.Elem2) } - log.Trace().Interface("headers", req.Header).Msg("Request headers for Keyfactor API call") - log.Info().Str("method", request.Method).Str("path", keyfactorPath).Msg("Sending HTTP request to Keyfactor API") resp, respErr := c.httpClient.Do(req) // check if context deadline exceeded switch { case respErr != nil && (strings.Contains(respErr.Error(), "context deadline exceeded")): sleepDuration := time.Duration(1) * time.Second - log.Warn(). - Err(respErr). - Str("sleep_duration", sleepDuration.String()). - Msg("Context deadline exceeded, retrying...") for i := 0; i < MAX_CONTEXT_DEADLINE_RETRIES; i++ { // sleep for exponential backoff - if i > 0 { sleepDuration *= 2 if sleepDuration > time.Duration(MAX_WAIT_SECONDS)*time.Second { sleepDuration = time.Duration(MAX_WAIT_SECONDS) * time.Second } - //log.Printf("[DEBUG] %s request to %s failed with error %s, retrying in %s seconds...", request.Method, keyfactorPath, respErr.Error(), sleepDuration) - log.Debug(). - Str("sleep_duration", sleepDuration.String()).Int("retry_count", i). - Msg("Sleeping for exponential backoff") + log.Printf("[DEBUG] %s request to %s failed with error %s, retrying in %s seconds...", request.Method, keyfactorPath, respErr.Error(), sleepDuration) time.Sleep(sleepDuration) } - //log.Printf("[DEBUG] %s request to %s failed with error %s, retrying...", request.Method, keyfactorPath, respErr.Error()) - log.Trace().Msg("Rebuilding HTTP request for Keyfactor API call") + log.Printf("[DEBUG] %s request to %s failed with error %s, retrying...", request.Method, keyfactorPath, respErr.Error()) req, reqErr = http.NewRequest(request.Method, keyfactorPath, bytes.NewBuffer(jsonByes)) if reqErr != nil { - log.Error().Err(reqErr).Msg("Error creating HTTP request for Keyfactor API call") return nil, reqErr } - log.Debug(). - Str("method", request.Method). - Str("path", keyfactorPath). - Str("query", u.RawQuery). - Msg("Retrying HTTP request to Keyfactor API") resp2, respErr2 := c.httpClient.Do(req) if respErr2 == nil { - log.Debug().Msg("Request succeeded after retry") resp = resp2 break } - log.Error().Err(respErr2).Msg("Error sending HTTP request to Keyfactor API") } case respErr != nil: - log.Error().Err(respErr).Msg("Error sending HTTP request to Keyfactor API") return nil, respErr case resp == nil: - log.Error().Msg("No response from Keyfactor Command") return nil, errors.New("no response from Keyfactor Command") } var stringMessage string if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNoContent { - //log.Printf("[DEBUG] %s succeeded with response code %d", request.Method, resp.StatusCode) - log.Debug().Int("statusCode", resp.StatusCode).Msg("Request succeeded") + log.Printf("[DEBUG] %s succeeded with response code %d", request.Method, resp.StatusCode) return resp, nil } else if resp.StatusCode == http.StatusNotFound { - stringMessage = fmt.Sprintf("http%d: the requested resource was not found, please check the request and try again.", resp.StatusCode) - log.Error().Msg(stringMessage) - //log.Printf("[ERROR] Call to %s returned status %d. %s", keyfactorPath, resp.StatusCode, stringMessage) + stringMessage = fmt.Sprintf("Error %d - the requested resource was not found. Please check the request and try again.", resp.StatusCode) + log.Printf("[ERROR] Call to %s returned status %d. %s", keyfactorPath, resp.StatusCode, stringMessage) return nil, errors.New(stringMessage) } else if resp.StatusCode == http.StatusUnauthorized { - dmp, derr := httputil.DumpResponse(resp, true) - //convert dmp from bytes to string - dmpStr := string(dmp) - log.Error().Err(derr).Str("response", dmpStr).Msg("Unauthorized request to Keyfactor Command") + _, derr := httputil.DumpResponse(resp, true) if derr != nil { - log.Error().Err(derr).Msg("Error dumping response from Keyfactor Command") return nil, derr } - err = errors.New(fmt.Sprintf("http%d - Unauthorized: Access is denied due to invalid credentials", resp.StatusCode)) + err = errors.New("401 - Unauthorized: Access is denied due to invalid credentials") return nil, err } else { - log.Error().Msg("Request failed") var errorMessage map[string]interface{} // Decode JSON body to handle issue - log.Debug().Msg("Decoding JSON response from Keyfactor Command") err = json.NewDecoder(resp.Body).Decode(&errorMessage) if err != nil { - log.Error().Err(err).Msg("Error decoding JSON response from Keyfactor Command") _, derr := httputil.DumpResponse(resp, true) if derr != nil { - log.Error().Err(derr).Msg("Error dumping response from Keyfactor Command") return nil, derr } uerr := errors.New(fmt.Sprintf("%d - Unknown error connecting to Keyfactor %s, please check your connection.", resp.StatusCode, endpoint)) - log.Error(). - Err(uerr). - Str("method", req.Method). - Str("path", keyfactorPath). - Msg("Unknown error connecting to Keyfactor") return nil, uerr } - //log.Printf("[DEBUG] Request failed with code %d and message %v", resp.StatusCode, errorMessage) - log.Debug().Int("statusCode", resp.StatusCode).Interface("errorMessage", errorMessage).Msg("Request failed") + log.Printf("[DEBUG] Request failed with code %d and message %v", resp.StatusCode, errorMessage) _, hasFailedOps := errorMessage["FailedOperations"] if hasFailedOps { - log.Debug().Msg("Failed operations found in response") var fOps []string for _, v := range errorMessage["FailedOperations"].([]interface{}) { - log.Trace().Interface("failedOperation", v).Msg("reason") fOps = append(fOps, fmt.Sprintf("%s", v.(map[string]interface{})["Reason"])) } fOpsStr := strings.Join(fOps, ", ") stringMessage += fmt.Sprintf("%s. %s", errorMessage["Message"], fOpsStr) - log.Trace().Str("failedOperations", stringMessage).Msg("Failed operations") } _, hasMsg := errorMessage["Message"] if hasMsg { stringMessage += fmt.Sprintf("%s", errorMessage["Message"]) } - log.Error().Msg(stringMessage) return nil, errors.New(stringMessage) } } @@ -376,9 +289,8 @@ func (c *Client) sendRequest(request *request) (*http.Response, error) { // buildBasicAuthString constructs a basic authorization string necessary for basic authorization to Keyfactor. It // returns a base-64 encoded auth string including the 'Basic ' prefix. func buildBasicAuthString(auth *AuthConfig) string { - initLogger() - log.Debug().Msg("Entering buildBasicAuthString") var authString string + //log.Println("[TRACE] Building Authorization field") if auth.Domain != "" && !strings.Contains(auth.Username, auth.Domain) { authString = strings.Join([]string{auth.Domain, "\\", auth.Username, ":", auth.Password}, "") } else { @@ -387,11 +299,6 @@ func buildBasicAuthString(auth *AuthConfig) string { authBytes := []byte(authString) authDigest := base64.StdEncoding.EncodeToString(authBytes) authField := strings.Join([]string{"Basic ", authDigest}, "") - //log.Trace().Str("authField", authField).Msg("Basic auth string") //INSECURE: authField contains sensitive information - if authField == "" || authField == "Basic " { - log.Error().Msg("Basic auth string is empty") - } - log.Debug().Msg("Exiting buildBasicAuthString") return authField } diff --git a/v2/go.mod b/v2/go.mod index fe17c55..e92e68f 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -5,12 +5,14 @@ go 1.21 require ( github.com/Keyfactor/keyfactor-go-client v1.4.3 github.com/Keyfactor/keyfactor-go-client-sdk v1.0.1 - github.com/rs/zerolog v1.32.0 + github.com/hashicorp/terraform-plugin-log v0.9.0 github.com/spbsoluble/go-pkcs12 v0.3.3 go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 ) require ( + github.com/fatih/color v1.13.0 // indirect + github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect golang.org/x/crypto v0.11.0 // indirect diff --git a/v2/go.sum b/v2/go.sum index cf538d7..f747893 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -2,24 +2,48 @@ github.com/Keyfactor/keyfactor-go-client v1.4.3 h1:CmGvWcuIbDRFM0PfYOQH6UdtAgplv github.com/Keyfactor/keyfactor-go-client v1.4.3/go.mod h1:3ZymLNCaSazglcuYeNfm9nrzn22wcwLjIWURrnUygBo= github.com/Keyfactor/keyfactor-go-client-sdk v1.0.1 h1:cs8hhvsY3MJ2o1K11HLTRCjRT8SbsKhhi73Y4By2CI0= github.com/Keyfactor/keyfactor-go-client-sdk v1.0.1/go.mod h1:Z5pSk8YFGXHbKeQ1wTzVN8A4P/fZmtAwqu3NgBHbDOs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= +github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= +github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= -github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/spbsoluble/go-pkcs12 v0.3.3 h1:3nh7IKn16RDpmrSMtOu1JvbB0XHYq1j+IsICdU1c7J4= github.com/spbsoluble/go-pkcs12 v0.3.3/go.mod h1:MAxKIUEIl/QVcua/I1L4Otyxl9UvLCCIktce2Tjz6Nw= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 h1:CCriYyAfq1Br1aIYettdHZTy8mBTIPo7We18TuO/bak= go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=