mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Refactor encryption configuration (#1387)
Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
This commit is contained in:
parent
4c4d9bca67
commit
586c45fe5a
@ -92,20 +92,17 @@ Finally, the user must reference the method for use in their state file, plan fi
|
||||
terraform {
|
||||
encryption {
|
||||
//...
|
||||
statefile {
|
||||
state {
|
||||
method = method.aes_gcm.abc
|
||||
}
|
||||
planfile {
|
||||
plan {
|
||||
method = method.aes_gcm.cde
|
||||
}
|
||||
backend {
|
||||
method = method.some_derivative_key_provider.efg
|
||||
}
|
||||
remote_data_sources {
|
||||
remote_state_data_sources {
|
||||
default {
|
||||
method = method.aes_gcm.ghi
|
||||
}
|
||||
remote_data_source "some_module.remote_data_source.foo" {
|
||||
remote_state_data_source "some_module.remote_data_source.foo" {
|
||||
method = method.aes_gcm.ijk
|
||||
}
|
||||
}
|
||||
@ -119,7 +116,7 @@ To facilitate key and method rollover, the user can specify a fallback configura
|
||||
terraform {
|
||||
encryption {
|
||||
//...
|
||||
statefile {
|
||||
state {
|
||||
method = method.aes_gcm.bar
|
||||
fallback {
|
||||
method = method.aes_gcm.baz
|
||||
@ -172,7 +169,7 @@ key_provider "static" "my_key" {
|
||||
method "aes_gcm" "foo" {
|
||||
key_provider = key_provider.static.my_key
|
||||
}
|
||||
statefile {
|
||||
state {
|
||||
method = method.aes_gcm.foo
|
||||
}
|
||||
```
|
||||
@ -193,7 +190,7 @@ statefile {
|
||||
}
|
||||
}
|
||||
},
|
||||
"statefile": {
|
||||
"state": {
|
||||
"method": "${method.aes_gcm.foo}"
|
||||
}
|
||||
}
|
||||
@ -202,7 +199,7 @@ statefile {
|
||||
The user can set either of these structures in the `TF_ENCRYPTION` environment variable:
|
||||
|
||||
```bash
|
||||
export TF_ENCRYPTION='{"key_provider":{...},"method":{...},"statefile":{...}}'
|
||||
export TF_ENCRYPTION='{"key_provider":{...},"method":{...},"state":{...}}'
|
||||
```
|
||||
|
||||
When the user specifies both an environment and a code configuration, `tofu` merges the two configurations. If two values conflict, the environment configuration takes precedence.
|
||||
@ -213,13 +210,10 @@ To ensure that the encryption cannot be accidentally forgotten or disabled and t
|
||||
terraform {
|
||||
encryption {
|
||||
//...
|
||||
statefile {
|
||||
state {
|
||||
enforced = true
|
||||
}
|
||||
planfile {
|
||||
enforced = true
|
||||
}
|
||||
backend {
|
||||
plan {
|
||||
enforced = true
|
||||
}
|
||||
}
|
||||
@ -266,23 +260,17 @@ The main component of the library should be the `Encryption` interface. This int
|
||||
|
||||
```go
|
||||
type Encryption interface {
|
||||
StateFile() StateEncryption
|
||||
PlanFile() PlanEncryption
|
||||
Backend() StateEncryption
|
||||
RemoteState(string) ReadOnlyStateEncryption
|
||||
State() StateEncryption
|
||||
Plan() PlanEncryption
|
||||
RemoteState(string) StateEncryption
|
||||
}
|
||||
```
|
||||
|
||||
Each of the returned encryption tools should provide methods to encrypt the data of the specified purpose, such as:
|
||||
|
||||
```go
|
||||
type ReadOnlyStateEncryption interface {
|
||||
DecryptState([]byte) ([]byte, error)
|
||||
}
|
||||
|
||||
type StateEncryption interface {
|
||||
ReadOnlyStateEncryption
|
||||
|
||||
DecryptState([]byte) ([]byte, error)
|
||||
EncryptState([]byte) ([]byte, error)
|
||||
}
|
||||
```
|
||||
|
@ -172,7 +172,7 @@ func (b *Local) opPlan(
|
||||
StateFile: plannedStateFile,
|
||||
Plan: plan,
|
||||
DependencyLocks: op.DependencyLocks,
|
||||
}, op.Encryption.PlanFile())
|
||||
}, op.Encryption.Plan())
|
||||
if err != nil {
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
|
@ -108,7 +108,7 @@ func (c *ApplyCommand) Run(rawArgs []string) int {
|
||||
|
||||
// Prepare the backend, passing the plan file if present, and the
|
||||
// backend-specific arguments
|
||||
be, beDiags := c.PrepareBackend(planFile, args.State, args.ViewType, enc.Backend())
|
||||
be, beDiags := c.PrepareBackend(planFile, args.State, args.ViewType, enc.State())
|
||||
diags = diags.Append(beDiags)
|
||||
if diags.HasErrors() {
|
||||
view.Diagnostics(diags)
|
||||
@ -168,7 +168,7 @@ func (c *ApplyCommand) LoadPlanFile(path string, enc encryption.Encryption) (*pl
|
||||
// Try to load plan if path is specified
|
||||
if path != "" {
|
||||
var err error
|
||||
planFile, err = c.PlanFile(path, enc.PlanFile())
|
||||
planFile, err = c.PlanFile(path, enc.Plan())
|
||||
if err != nil {
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
|
@ -70,7 +70,7 @@ func (c *ConsoleCommand) Run(args []string) int {
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(&BackendOpts{
|
||||
Config: backendConfig,
|
||||
}, enc.Backend())
|
||||
}, enc.State())
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
@ -69,7 +69,7 @@ func (c *GraphCommand) Run(args []string) int {
|
||||
// Try to load plan if path is specified
|
||||
var planFile *planfile.WrappedPlanFile
|
||||
if planPath != "" {
|
||||
planFile, err = c.PlanFile(planPath, enc.PlanFile())
|
||||
planFile, err = c.PlanFile(planPath, enc.Plan())
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
return 1
|
||||
@ -86,7 +86,7 @@ func (c *GraphCommand) Run(args []string) int {
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(&BackendOpts{
|
||||
Config: backendConfig,
|
||||
}, enc.Backend())
|
||||
}, enc.State())
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
@ -175,7 +175,7 @@ func (c *ImportCommand) Run(args []string) int {
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(&BackendOpts{
|
||||
Config: config.Module.Backend,
|
||||
}, enc.Backend())
|
||||
}, enc.State())
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
@ -213,7 +213,7 @@ func (c *InitCommand) Run(args []string) int {
|
||||
back, backendOutput, backDiags = c.initBackend(ctx, rootModEarly, flagConfigExtra, enc)
|
||||
default:
|
||||
// load the previously-stored backend config
|
||||
back, backDiags = c.Meta.backendFromState(ctx, enc.Backend())
|
||||
back, backDiags = c.Meta.backendFromState(ctx, enc.State())
|
||||
}
|
||||
if backendOutput {
|
||||
header = true
|
||||
@ -445,7 +445,7 @@ func (c *InitCommand) initCloud(ctx context.Context, root *configs.Module, extra
|
||||
Init: true,
|
||||
}
|
||||
|
||||
back, backDiags := c.Backend(opts, enc.Backend())
|
||||
back, backDiags := c.Backend(opts, enc.State())
|
||||
diags = diags.Append(backDiags)
|
||||
return back, true, diags
|
||||
}
|
||||
@ -528,7 +528,7 @@ the backend configuration is present and valid.
|
||||
Init: true,
|
||||
}
|
||||
|
||||
back, backDiags := c.Backend(opts, enc.Backend())
|
||||
back, backDiags := c.Backend(opts, enc.State())
|
||||
diags = diags.Append(backDiags)
|
||||
return back, true, diags
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ func (c *OutputCommand) Outputs(statePath string, enc encryption.Encryption) (ma
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil, enc.Backend())
|
||||
b, backendDiags := c.Backend(nil, enc.State())
|
||||
diags = diags.Append(backendDiags)
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
|
@ -140,7 +140,7 @@ func (c *PlanCommand) PrepareBackend(args *arguments.State, viewType arguments.V
|
||||
be, beDiags := c.Backend(&BackendOpts{
|
||||
Config: backendConfig,
|
||||
ViewType: viewType,
|
||||
}, enc.Backend())
|
||||
}, enc.State())
|
||||
diags = diags.Append(beDiags)
|
||||
if beDiags.HasErrors() {
|
||||
return nil, diags
|
||||
|
@ -93,7 +93,7 @@ func (c *ProvidersCommand) Run(args []string) int {
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(&BackendOpts{
|
||||
Config: config.Module.Backend,
|
||||
}, enc.Backend())
|
||||
}, enc.State())
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
@ -137,7 +137,7 @@ func (c *RefreshCommand) PrepareBackend(args *arguments.State, viewType argument
|
||||
be, beDiags := c.Backend(&BackendOpts{
|
||||
Config: backendConfig,
|
||||
ViewType: viewType,
|
||||
}, enc.Backend())
|
||||
}, enc.State())
|
||||
diags = diags.Append(beDiags)
|
||||
if beDiags.HasErrors() {
|
||||
return nil, diags
|
||||
|
@ -170,7 +170,7 @@ func (c *ShowCommand) showFromLatestStateSnapshot(enc encryption.Encryption) (*s
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil, enc.Backend())
|
||||
b, backendDiags := c.Backend(nil, enc.State())
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
return nil, diags
|
||||
@ -281,7 +281,7 @@ func (c *ShowCommand) getPlanFromPath(path string, enc encryption.Encryption) (*
|
||||
var stateFile *statefile.File
|
||||
var config *configs.Config
|
||||
|
||||
pf, err := planfile.OpenWrapped(path, enc.PlanFile())
|
||||
pf, err := planfile.OpenWrapped(path, enc.Plan())
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
@ -298,7 +298,7 @@ func (c *ShowCommand) getPlanFromPath(path string, enc encryption.Encryption) (*
|
||||
|
||||
func (c *ShowCommand) getDataFromCloudPlan(plan *cloudplan.SavedPlanBookmark, redacted bool, enc encryption.Encryption) (*cloudplan.RemotePlanJSON, error) {
|
||||
// Set up the backend
|
||||
b, backendDiags := c.Backend(nil, enc.Backend())
|
||||
b, backendDiags := c.Backend(nil, enc.State())
|
||||
if backendDiags.HasErrors() {
|
||||
return nil, errUnusable(backendDiags.Err(), "cloud plan")
|
||||
}
|
||||
@ -347,7 +347,7 @@ func getStateFromPath(path string, enc encryption.Encryption) (*statefile.File,
|
||||
defer file.Close()
|
||||
|
||||
var stateFile *statefile.File
|
||||
stateFile, err = statefile.Read(file, enc.StateFile())
|
||||
stateFile, err = statefile.Read(file, enc.State())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error reading %s as a statefile: %w", path, err)
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ func (c *StateListCommand) Run(args []string) int {
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil, enc.Backend())
|
||||
b, backendDiags := c.Backend(nil, enc.State())
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(backendDiags)
|
||||
return 1
|
||||
|
@ -38,7 +38,7 @@ func (c *StateMeta) State(enc encryption.Encryption) (statemgr.Full, error) {
|
||||
realState = statemgr.NewFilesystem(c.statePath, encryption.StateEncryptionDisabled()) // User specified state file should not be encrypted
|
||||
} else {
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil, enc.Backend())
|
||||
b, backendDiags := c.Backend(nil, enc.State())
|
||||
if backendDiags.HasErrors() {
|
||||
return nil, backendDiags.Err()
|
||||
}
|
||||
@ -62,7 +62,7 @@ func (c *StateMeta) State(enc encryption.Encryption) (statemgr.Full, error) {
|
||||
}
|
||||
|
||||
// Get a local backend
|
||||
localRaw, backendDiags := c.Backend(&BackendOpts{ForceLocal: true}, enc.Backend())
|
||||
localRaw, backendDiags := c.Backend(&BackendOpts{ForceLocal: true}, enc.State())
|
||||
if backendDiags.HasErrors() {
|
||||
// This should never fail
|
||||
panic(backendDiags.Err())
|
||||
|
@ -77,7 +77,7 @@ func (c *StateMvCommand) Run(args []string) int {
|
||||
}
|
||||
|
||||
if len(setLegacyLocalBackendOptions) > 0 {
|
||||
currentBackend, diags := c.backendFromConfig(&BackendOpts{}, enc.Backend())
|
||||
currentBackend, diags := c.backendFromConfig(&BackendOpts{}, enc.State())
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
@ -399,7 +399,7 @@ func (c *StateMvCommand) Run(args []string) int {
|
||||
return 0 // This is as far as we go in dry-run mode
|
||||
}
|
||||
|
||||
b, backendDiags := c.Backend(nil, enc.Backend())
|
||||
b, backendDiags := c.Backend(nil, enc.State())
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
@ -42,7 +42,7 @@ func (c *StatePullCommand) Run(args []string) int {
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil, enc.Backend())
|
||||
b, backendDiags := c.Backend(nil, enc.State())
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(backendDiags)
|
||||
return 1
|
||||
|
@ -87,7 +87,7 @@ func (c *StatePushCommand) Run(args []string) int {
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil, enc.Backend())
|
||||
b, backendDiags := c.Backend(nil, enc.State())
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(backendDiags)
|
||||
return 1
|
||||
|
@ -175,7 +175,7 @@ func (c *StateReplaceProviderCommand) Run(args []string) int {
|
||||
resource.ProviderConfig.Provider = to
|
||||
}
|
||||
|
||||
b, backendDiags := c.Backend(nil, enc.Backend())
|
||||
b, backendDiags := c.Backend(nil, enc.State())
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
@ -124,7 +124,7 @@ func (c *StateRmCommand) Run(args []string) int {
|
||||
return 0 // This is as far as we go in dry-run mode
|
||||
}
|
||||
|
||||
b, backendDiags := c.Backend(nil, enc.Backend())
|
||||
b, backendDiags := c.Backend(nil, enc.State())
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
@ -58,7 +58,7 @@ func (c *StateShowCommand) Run(args []string) int {
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil, enc.Backend())
|
||||
b, backendDiags := c.Backend(nil, enc.State())
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(backendDiags)
|
||||
return 1
|
||||
|
@ -75,7 +75,7 @@ func (c *TaintCommand) Run(args []string) int {
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil, enc.Backend())
|
||||
b, backendDiags := c.Backend(nil, enc.State())
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
@ -66,7 +66,7 @@ func (c *UntaintCommand) Run(args []string) int {
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil, enc.Backend())
|
||||
b, backendDiags := c.Backend(nil, enc.State())
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
@ -74,7 +74,7 @@ func (c *WorkspaceDeleteCommand) Run(args []string) int {
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(&BackendOpts{
|
||||
Config: backendConfig,
|
||||
}, enc.Backend())
|
||||
}, enc.State())
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
@ -90,7 +90,7 @@ func (c *WorkspaceNewCommand) Run(args []string) int {
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(&BackendOpts{
|
||||
Config: backendConfig,
|
||||
}, enc.Backend())
|
||||
}, enc.State())
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
@ -71,7 +71,7 @@ func (c *WorkspaceSelectCommand) Run(args []string) int {
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(&BackendOpts{
|
||||
Config: backendConfig,
|
||||
}, enc.Backend())
|
||||
}, enc.State())
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
@ -17,10 +17,9 @@ type EncryptionConfig struct {
|
||||
KeyProviderConfigs []KeyProviderConfig `hcl:"key_provider,block"`
|
||||
MethodConfigs []MethodConfig `hcl:"method,block"`
|
||||
|
||||
Backend *EnforcableTargetConfig `hcl:"backend,block"`
|
||||
StateFile *EnforcableTargetConfig `hcl:"statefile,block"`
|
||||
PlanFile *EnforcableTargetConfig `hcl:"planfile,block"`
|
||||
Remote *RemoteConfig `hcl:"remote,block"`
|
||||
State *EnforcableTargetConfig `hcl:"state,block"`
|
||||
Plan *EnforcableTargetConfig `hcl:"plan,block"`
|
||||
Remote *RemoteConfig `hcl:"remote_state_data_sources,block"`
|
||||
|
||||
// Not preserved through merge operations
|
||||
DeclRange hcl.Range
|
||||
@ -61,7 +60,7 @@ func (m MethodConfig) Addr() (method.Addr, hcl.Diagnostics) {
|
||||
// sources.
|
||||
type RemoteConfig struct {
|
||||
Default *TargetConfig `hcl:"default,block"`
|
||||
Targets []NamedTargetConfig `hcl:"remote_state,block"`
|
||||
Targets []NamedTargetConfig `hcl:"remote_state_data_source,block"`
|
||||
}
|
||||
|
||||
// TargetConfig describes the target.encryption.state, target.encryption.plan, etc blocks.
|
||||
|
@ -22,10 +22,9 @@ func MergeConfigs(cfg *EncryptionConfig, override *EncryptionConfig) *Encryption
|
||||
KeyProviderConfigs: mergeKeyProviderConfigs(cfg.KeyProviderConfigs, override.KeyProviderConfigs),
|
||||
MethodConfigs: mergeMethodConfigs(cfg.MethodConfigs, override.MethodConfigs),
|
||||
|
||||
StateFile: mergeEnforcableTargetConfigs(cfg.StateFile, override.StateFile),
|
||||
PlanFile: mergeEnforcableTargetConfigs(cfg.PlanFile, override.PlanFile),
|
||||
Backend: mergeEnforcableTargetConfigs(cfg.Backend, override.Backend),
|
||||
Remote: mergeRemoteConfigs(cfg.Remote, override.Remote),
|
||||
State: mergeEnforcableTargetConfigs(cfg.State, override.State),
|
||||
Plan: mergeEnforcableTargetConfigs(cfg.Plan, override.Plan),
|
||||
Remote: mergeRemoteConfigs(cfg.Remote, override.Remote),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,14 +14,11 @@ import (
|
||||
// Encryption contains the methods for obtaining a StateEncryption or PlanEncryption correctly configured for a specific
|
||||
// purpose. If no encryption configuration is present, it should return a pass through method that doesn't do anything.
|
||||
type Encryption interface {
|
||||
// StateFile produces a StateEncryption overlay for encrypting and decrypting state files for local storage.
|
||||
StateFile() StateEncryption
|
||||
// State produces a StateEncryption overlay for encrypting and decrypting state files for local storage.
|
||||
State() StateEncryption
|
||||
|
||||
// PlanFile produces a PlanEncryption overlay for encrypting and decrypting plan files.
|
||||
PlanFile() PlanEncryption
|
||||
|
||||
// Backend produces a StateEncryption overlay for storing state files on remote backends, such as an S3 bucket.
|
||||
Backend() StateEncryption
|
||||
// Plan produces a PlanEncryption overlay for encrypting and decrypting plan files.
|
||||
Plan() PlanEncryption
|
||||
|
||||
// RemoteState produces a StateEncryption for reading remote states using the terraform_remote_state data
|
||||
// source.
|
||||
@ -29,9 +26,8 @@ type Encryption interface {
|
||||
}
|
||||
|
||||
type encryption struct {
|
||||
statefile StateEncryption
|
||||
planfile PlanEncryption
|
||||
backend StateEncryption
|
||||
state StateEncryption
|
||||
plan PlanEncryption
|
||||
remoteDefault StateEncryption
|
||||
remotes map[string]StateEncryption
|
||||
|
||||
@ -55,25 +51,18 @@ func New(reg registry.Registry, cfg *config.EncryptionConfig) (Encryption, hcl.D
|
||||
var diags hcl.Diagnostics
|
||||
var encDiags hcl.Diagnostics
|
||||
|
||||
if cfg.StateFile != nil {
|
||||
enc.statefile, encDiags = newStateEncryption(enc, cfg.StateFile.AsTargetConfig(), cfg.StateFile.Enforced, "statefile")
|
||||
if cfg.State != nil {
|
||||
enc.state, encDiags = newStateEncryption(enc, cfg.State.AsTargetConfig(), cfg.State.Enforced, "state")
|
||||
diags = append(diags, encDiags...)
|
||||
} else {
|
||||
enc.statefile = StateEncryptionDisabled()
|
||||
enc.state = StateEncryptionDisabled()
|
||||
}
|
||||
|
||||
if cfg.PlanFile != nil {
|
||||
enc.planfile, encDiags = newPlanEncryption(enc, cfg.PlanFile.AsTargetConfig(), cfg.PlanFile.Enforced, "planfile")
|
||||
if cfg.Plan != nil {
|
||||
enc.plan, encDiags = newPlanEncryption(enc, cfg.Plan.AsTargetConfig(), cfg.Plan.Enforced, "plan")
|
||||
diags = append(diags, encDiags...)
|
||||
} else {
|
||||
enc.planfile = PlanEncryptionDisabled()
|
||||
}
|
||||
|
||||
if cfg.Backend != nil {
|
||||
enc.backend, encDiags = newStateEncryption(enc, cfg.Backend.AsTargetConfig(), cfg.Backend.Enforced, "backend")
|
||||
diags = append(diags, encDiags...)
|
||||
} else {
|
||||
enc.backend = StateEncryptionDisabled()
|
||||
enc.plan = PlanEncryptionDisabled()
|
||||
}
|
||||
|
||||
if cfg.Remote != nil && cfg.Remote.Default != nil {
|
||||
@ -97,16 +86,12 @@ func New(reg registry.Registry, cfg *config.EncryptionConfig) (Encryption, hcl.D
|
||||
return enc, diags
|
||||
}
|
||||
|
||||
func (e *encryption) StateFile() StateEncryption {
|
||||
return e.statefile
|
||||
func (e *encryption) State() StateEncryption {
|
||||
return e.state
|
||||
}
|
||||
|
||||
func (e *encryption) PlanFile() PlanEncryption {
|
||||
return e.planfile
|
||||
}
|
||||
|
||||
func (e *encryption) Backend() StateEncryption {
|
||||
return e.backend
|
||||
func (e *encryption) Plan() PlanEncryption {
|
||||
return e.plan
|
||||
}
|
||||
|
||||
func (e *encryption) RemoteState(name string) StateEncryption {
|
||||
@ -122,9 +107,8 @@ type encryptionDisabled struct{}
|
||||
func Disabled() Encryption {
|
||||
return &encryptionDisabled{}
|
||||
}
|
||||
func (e *encryptionDisabled) StateFile() StateEncryption { return StateEncryptionDisabled() }
|
||||
func (e *encryptionDisabled) PlanFile() PlanEncryption { return PlanEncryptionDisabled() }
|
||||
func (e *encryptionDisabled) Backend() StateEncryption { return StateEncryptionDisabled() }
|
||||
func (e *encryptionDisabled) State() StateEncryption { return StateEncryptionDisabled() }
|
||||
func (e *encryptionDisabled) Plan() PlanEncryption { return PlanEncryptionDisabled() }
|
||||
func (e *encryptionDisabled) RemoteState(name string) StateEncryption {
|
||||
return StateEncryptionDisabled()
|
||||
}
|
||||
|
@ -45,16 +45,13 @@ func EncryptionRequired() encryption.Encryption {
|
||||
method "aes_gcm" "example" {
|
||||
keys = key_provider.static.basic
|
||||
}
|
||||
statefile {
|
||||
state {
|
||||
method = method.aes_gcm.example
|
||||
}
|
||||
planfile {
|
||||
plan {
|
||||
method = method.aes_gcm.example
|
||||
}
|
||||
backend {
|
||||
method = method.aes_gcm.example
|
||||
}
|
||||
remote {
|
||||
remote_state_data_sources {
|
||||
default {
|
||||
method = method.aes_gcm.example
|
||||
}
|
||||
@ -70,19 +67,15 @@ func EncryptionWithFallback() encryption.Encryption {
|
||||
method "aes_gcm" "example" {
|
||||
keys = key_provider.static.basic
|
||||
}
|
||||
statefile {
|
||||
state {
|
||||
method = method.aes_gcm.example
|
||||
fallback {}
|
||||
}
|
||||
planfile {
|
||||
plan {
|
||||
method = method.aes_gcm.example
|
||||
fallback {}
|
||||
}
|
||||
backend {
|
||||
method = method.aes_gcm.example
|
||||
fallback {}
|
||||
}
|
||||
remote {
|
||||
remote_state_data_sources {
|
||||
default {
|
||||
method = method.aes_gcm.example
|
||||
fallback {}
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
|
||||
var (
|
||||
ConfigA = `
|
||||
backend {
|
||||
state {
|
||||
enforced = true
|
||||
}
|
||||
`
|
||||
@ -29,11 +29,7 @@ key_provider "static" "basic" {
|
||||
method "aes_gcm" "example" {
|
||||
keys = key_provider.static.basic
|
||||
}
|
||||
statefile {
|
||||
method = method.aes_gcm.example
|
||||
}
|
||||
|
||||
backend {
|
||||
state {
|
||||
method = method.aes_gcm.example
|
||||
}
|
||||
`
|
||||
@ -65,7 +61,7 @@ func Example() {
|
||||
enc, diags := encryption.New(reg, cfg)
|
||||
handleDiags(diags)
|
||||
|
||||
sfe := enc.StateFile()
|
||||
sfe := enc.State()
|
||||
|
||||
// Encrypt the data, for this example we will be using the string "test",
|
||||
// but in a real world scenario this would be the plan file.
|
||||
|
@ -24,7 +24,7 @@ method "aes_gcm" "bar" {
|
||||
keys = key_provider.static.foo
|
||||
}
|
||||
|
||||
planfile {
|
||||
plan {
|
||||
method = method.aes_gcm.bar
|
||||
}
|
||||
`
|
||||
@ -49,7 +49,7 @@ func Example() {
|
||||
panic(diags)
|
||||
}
|
||||
|
||||
encryptor := enc.PlanFile()
|
||||
encryptor := enc.Plan()
|
||||
|
||||
encryptedPlan, err := encryptor.EncryptPlan([]byte("Hello world!"))
|
||||
if err != nil {
|
||||
|
@ -39,7 +39,7 @@ func TestReadErrNoState_nilFile(t *testing.T) {
|
||||
func TestReadEmptyWithEncryption(t *testing.T) {
|
||||
payload := bytes.NewBufferString("")
|
||||
|
||||
_, err := Read(payload, enctest.EncryptionRequired().Backend())
|
||||
_, err := Read(payload, enctest.EncryptionRequired().State())
|
||||
if !errors.Is(err, ErrNoState) {
|
||||
t.Fatalf("expected ErrNoState, got %T", err)
|
||||
}
|
||||
@ -47,7 +47,7 @@ func TestReadEmptyWithEncryption(t *testing.T) {
|
||||
func TestReadEmptyJsonWithEncryption(t *testing.T) {
|
||||
payload := bytes.NewBufferString("{}")
|
||||
|
||||
_, err := Read(payload, enctest.EncryptionRequired().Backend())
|
||||
_, err := Read(payload, enctest.EncryptionRequired().State())
|
||||
|
||||
if err == nil || err.Error() != "unable to determine data structure during decryption: Given payload is not a state file" {
|
||||
t.Fatalf("expected encryption error, got %v", err)
|
||||
|
@ -84,7 +84,7 @@ func TestRoundtrip(t *testing.T) {
|
||||
func TestRoundtripEncryption(t *testing.T) {
|
||||
const path = "testdata/roundtrip/v4-modules.out.tfstate"
|
||||
|
||||
enc := enctest.EncryptionWithFallback().Backend()
|
||||
enc := enctest.EncryptionWithFallback().State()
|
||||
|
||||
unencryptedInput, err := os.Open(path)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user