mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
feature: fall back to reading entire state when detailed-type is not available
This commit is contained in:
parent
e1fa690879
commit
0139e75a1a
@ -25,10 +25,13 @@ type State struct {
|
|||||||
delegate remote.State
|
delegate remote.State
|
||||||
}
|
}
|
||||||
|
|
||||||
const ErrStateVersionOutputUpgrade = `
|
var ErrNotEnoughOutputsTypeInformation = errors.New("not enough type information to read outputs")
|
||||||
The remote state version was created by a version of terraform older than
|
var ErrStateVersionOutputsUpgradeState = errors.New(strings.TrimSpace(`
|
||||||
1.3.0 and must be updated before outputs can be read by terraform.
|
You are not authorized to read the full state version containing outputs.
|
||||||
`
|
State versions created by terraform v1.3.0 and newer do not require this level
|
||||||
|
of authorization and therefore this error can be fixed by upgrading the remote
|
||||||
|
state version.
|
||||||
|
`))
|
||||||
|
|
||||||
// Proof that cloud State is a statemgr.Persistent interface
|
// Proof that cloud State is a statemgr.Persistent interface
|
||||||
var _ statemgr.Persistent = (*State)(nil)
|
var _ statemgr.Persistent = (*State)(nil)
|
||||||
@ -70,6 +73,22 @@ func (s *State) WriteState(state *states.State) error {
|
|||||||
return s.delegate.WriteState(state)
|
return s.delegate.WriteState(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *State) fallbackReadOutputsFromFullState() (map[string]*states.OutputValue, error) {
|
||||||
|
if err := s.RefreshState(); err != nil {
|
||||||
|
if strings.HasSuffix(err.Error(), "failed to retrieve state: forbidden") {
|
||||||
|
return nil, ErrStateVersionOutputsUpgradeState
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("failed to load state: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
state := s.State()
|
||||||
|
if state == nil {
|
||||||
|
state = states.NewState()
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.RootModule().OutputValues, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetRootOutputValues fetches output values from Terraform Cloud
|
// GetRootOutputValues fetches output values from Terraform Cloud
|
||||||
func (s *State) GetRootOutputValues() (map[string]*states.OutputValue, error) {
|
func (s *State) GetRootOutputValues() (map[string]*states.OutputValue, error) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
@ -84,7 +103,11 @@ func (s *State) GetRootOutputValues() (map[string]*states.OutputValue, error) {
|
|||||||
|
|
||||||
for _, output := range so.Items {
|
for _, output := range so.Items {
|
||||||
if output.DetailedType == nil {
|
if output.DetailedType == nil {
|
||||||
return nil, errors.New(strings.TrimSpace(ErrStateVersionOutputUpgrade))
|
// If there is no detailed type information available, this state was probably created
|
||||||
|
// with a version of terraform < 1.3.0. In this case, we'll eject completely from this
|
||||||
|
// function and fall back to the old behavior of reading the entire state file, which
|
||||||
|
// requires a higher level of authorization.
|
||||||
|
return s.fallbackReadOutputsFromFullState()
|
||||||
}
|
}
|
||||||
|
|
||||||
if output.Sensitive {
|
if output.Sensitive {
|
||||||
|
Loading…
Reference in New Issue
Block a user