github.com/opentofu/opentofu@v1.7.1/internal/checks/status.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package checks 7 8 import ( 9 "fmt" 10 11 "github.com/zclconf/go-cty/cty" 12 ) 13 14 // Status represents the status of an individual check associated with a 15 // checkable object. 16 type Status rune 17 18 //go:generate go run golang.org/x/tools/cmd/stringer -type=Status 19 20 const ( 21 // StatusUnknown represents that there is not yet a conclusive result 22 // for the check, either because we haven't yet visited its associated 23 // object or because the check condition itself depends on a value not 24 // yet known during planning. 25 StatusUnknown Status = 0 26 // NOTE: Our implementation relies on StatusUnknown being the zero value 27 // of Status. 28 29 // StatusPass represents that OpenTofu Core has evaluated the check's 30 // condition and it returned true, indicating success. 31 StatusPass Status = 'P' 32 33 // StatusFail represents that OpenTofu Core has evaluated the check's 34 // condition and it returned false, indicating failure. 35 StatusFail Status = 'F' 36 37 // StatusError represents that OpenTofu Core tried to evaluate the check's 38 // condition but encountered an error while evaluating the check expression. 39 // 40 // This is different than StatusFail because StatusFail indiciates that 41 // the condition was valid and returned false, whereas StatusError 42 // indicates that the condition was not valid at all. 43 StatusError Status = 'E' 44 ) 45 46 // StatusForCtyValue returns the Status value corresponding to the given 47 // cty Value, which must be one of either cty.True, cty.False, or 48 // cty.UnknownVal(cty.Bool) or else this function will panic. 49 // 50 // The current behavior of this function is: 51 // 52 // cty.True StatusPass 53 // cty.False StatusFail 54 // cty.UnknownVal(cty.Bool) StatusUnknown 55 // 56 // Any other input will panic. Note that there's no value that can produce 57 // StatusError, because in case of a condition error there will not typically 58 // be a result value at all. 59 func StatusForCtyValue(v cty.Value) Status { 60 if !v.Type().Equals(cty.Bool) { 61 panic(fmt.Sprintf("cannot use %s as check status", v.Type().FriendlyName())) 62 } 63 if v.IsNull() { 64 panic("cannot use null as check status") 65 } 66 67 switch { 68 case v == cty.True: 69 return StatusPass 70 case v == cty.False: 71 return StatusFail 72 case !v.IsKnown(): 73 return StatusUnknown 74 default: 75 // Should be impossible to get here unless something particularly 76 // weird is going on, like a marked condition result. 77 panic(fmt.Sprintf("cannot use %#v as check status", v)) 78 } 79 }