github.com/opentofu/opentofu@v1.7.1/internal/encryption/keyprovider/openbao/config.go (about) 1 package openbao 2 3 import ( 4 "fmt" 5 6 openbao "github.com/openbao/openbao/api" 7 "github.com/opentofu/opentofu/internal/encryption/keyprovider" 8 ) 9 10 type Config struct { 11 Address string `hcl:"address,optional"` 12 Token string `hcl:"token,optional"` 13 14 KeyName string `hcl:"key_name"` 15 KeyLength DataKeyLength `hcl:"key_length,optional"` 16 TransitEnginePath string `hcl:"transit_engine_path,optional"` 17 } 18 19 const ( 20 defaultDataKeyLength DataKeyLength = 32 21 defaultTransitEnginePath string = "/transit" 22 ) 23 24 func (c Config) Build() (keyprovider.KeyProvider, keyprovider.KeyMeta, error) { 25 if c.KeyName == "" { 26 return nil, nil, &keyprovider.ErrInvalidConfiguration{ 27 Message: "no key name found", 28 } 29 } 30 31 if c.KeyLength == 0 { 32 c.KeyLength = defaultDataKeyLength 33 } 34 35 if err := c.KeyLength.Validate(); err != nil { 36 return nil, nil, &keyprovider.ErrInvalidConfiguration{ 37 Cause: err, 38 } 39 } 40 41 if c.TransitEnginePath == "" { 42 c.TransitEnginePath = defaultTransitEnginePath 43 } 44 45 // DefaultConfig reads BAO_ADDR and some other optional env variables. 46 config := openbao.DefaultConfig() 47 if config.Error != nil { 48 return nil, nil, &keyprovider.ErrInvalidConfiguration{ 49 Cause: config.Error, 50 } 51 } 52 53 // Address from HCL supersedes BAO_ADDR. 54 if c.Address != "" { 55 config.Address = c.Address 56 } 57 58 client, err := newClient(config, c.Token) 59 if err != nil { 60 return nil, nil, &keyprovider.ErrInvalidConfiguration{ 61 Cause: err, 62 } 63 } 64 65 return &keyProvider{ 66 svc: service{ 67 c: client, 68 transitPath: c.TransitEnginePath, 69 }, 70 keyName: c.KeyName, 71 keyLength: c.KeyLength, 72 }, new(keyMeta), nil 73 } 74 75 type DataKeyLength int 76 77 func (l DataKeyLength) Validate() error { 78 switch l { 79 case 16, 32, 64: 80 return nil 81 default: 82 return fmt.Errorf("data key length should one of 16, 32 or 64 bytes: got %v", l) 83 } 84 } 85 86 func (l DataKeyLength) Bits() int { 87 return int(l) * 8 88 } 89 90 type clientConstructor func(config *openbao.Config, token string) (client, error) 91 92 // newClient variable allows to inject different client implementations. 93 // In order to keep client interface simple, token setting is in this function as well. 94 // It's not possible to pass token in config. 95 var newClient clientConstructor = newOpenBaoClient 96 97 func newOpenBaoClient(config *openbao.Config, token string) (client, error) { 98 // NewClient reads BAO_TOKEN and some other optional env variables. 99 c, err := openbao.NewClient(config) 100 if err != nil { 101 return nil, fmt.Errorf("error creating OpenBao client: %w", err) 102 } 103 104 // Token from HCL supersedes BAO_TOKEN. 105 if token != "" { 106 c.SetToken(token) 107 } 108 109 return c.Logical(), nil 110 }