diff --git a/stores/flatten.go b/stores/flatten.go index 16d730380..f961d74d0 100644 --- a/stores/flatten.go +++ b/stores/flatten.go @@ -248,7 +248,14 @@ func DecodeNonStrings(m map[string]interface{}) error { case string: vInt, err := strconv.Atoi(val) if err != nil { - return fmt.Errorf("shamir_threshold is not an integer: %s", err.Error()) + // Older versions of SOPS stored shamir_threshold as a floating point representation + // of the actual integer. Try to parse a floating point number and see whether it + // can be converted without loss to an integer. + vFloat, floatErr := strconv.ParseFloat(val, 64) + vInt = int(vFloat) + if floatErr != nil || float64(vInt) != vFloat { + return fmt.Errorf("shamir_threshold is not an integer: %s", err.Error()) + } } m["shamir_threshold"] = vInt case int: @@ -274,5 +281,11 @@ func EncodeNonStrings(m map[string]interface{}) { if vInt, ok := v.(int); ok { m["shamir_threshold"] = fmt.Sprintf("%d", vInt) } + // FlattenMetadata serializes the input as JSON and then deserializes it. + // The JSON unserializer treats every number as a float, so the above 'if' + // never applies in that situation. + if vFloat, ok := v.(float64); ok { + m["shamir_threshold"] = fmt.Sprintf("%.0f", vFloat) + } } }