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 }