github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/command/plugins_lock.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package command
     5  
     6  import (
     7  	"encoding/json"
     8  	"fmt"
     9  	"io/ioutil"
    10  	"log"
    11  )
    12  
    13  type pluginSHA256LockFile struct {
    14  	Filename string
    15  }
    16  
    17  // Read loads the lock information from the file and returns it. If the file
    18  // cannot be read, an empty map is returned to indicate that _no_ providers
    19  // are acceptable, since the user must run "terraform init" to lock some
    20  // providers before a context can be created.
    21  func (pf *pluginSHA256LockFile) Read() map[string][]byte {
    22  	// Returning an empty map is different than nil because it causes
    23  	// us to reject all plugins as uninitialized, rather than applying no
    24  	// constraints at all.
    25  	//
    26  	// We don't surface any specific errors here because we want it to all
    27  	// roll up into our more-user-friendly error that appears when plugin
    28  	// constraint verification fails during context creation.
    29  	digests := make(map[string][]byte)
    30  
    31  	buf, err := ioutil.ReadFile(pf.Filename)
    32  	if err != nil {
    33  		// This is expected if the user runs any context-using command before
    34  		// running "terraform init".
    35  		log.Printf("[INFO] Failed to read plugin lock file %s: %s", pf.Filename, err)
    36  		return digests
    37  	}
    38  
    39  	var strDigests map[string]string
    40  	err = json.Unmarshal(buf, &strDigests)
    41  	if err != nil {
    42  		// This should never happen unless the user directly edits the file.
    43  		log.Printf("[WARN] Plugin lock file %s failed to parse as JSON: %s", pf.Filename, err)
    44  		return digests
    45  	}
    46  
    47  	for name, strDigest := range strDigests {
    48  		var digest []byte
    49  		_, err := fmt.Sscanf(strDigest, "%x", &digest)
    50  		if err == nil {
    51  			digests[name] = digest
    52  		} else {
    53  			// This should never happen unless the user directly edits the file.
    54  			log.Printf("[WARN] Plugin lock file %s has invalid digest for %q", pf.Filename, name)
    55  		}
    56  	}
    57  
    58  	return digests
    59  }