Skip to content

Commit bcabe72

Browse files
committed
Add signer details to the prompt shown to users
1 parent 8d6d165 commit bcabe72

4 files changed

Lines changed: 40 additions & 12 deletions

File tree

internal/command/init.go

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ const (
375375
// The method downloads any missing providers that aren't already downloaded and then returns
376376
// dependency lock data based on the configuration.
377377
// The dependency lock file itself isn't updated here.
378-
func (c *InitCommand) getProvidersFromConfig(ctx context.Context, config *configs.Config, upgrade bool, pluginDirs []string, flagLockfile string, view views.Init) (output bool, resultingLocks *depsfile.Locks, safeInitAction SafeInitAction, diags tfdiags.Diagnostics) {
378+
func (c *InitCommand) getProvidersFromConfig(ctx context.Context, config *configs.Config, upgrade bool, pluginDirs []string, flagLockfile string, view views.Init) (output bool, resultingLocks *depsfile.Locks, safeInitAction SafeInitAction, authResult *getproviders.PackageAuthenticationResult, diags tfdiags.Diagnostics) {
379379
ctx, span := tracer.Start(ctx, "install providers from config")
380380
defer span.End()
381381

@@ -391,7 +391,7 @@ func (c *InitCommand) getProvidersFromConfig(ctx context.Context, config *config
391391
reqs, hclDiags := config.ProviderRequirements()
392392
diags = diags.Append(hclDiags)
393393
if hclDiags.HasErrors() {
394-
return false, nil, SafeInitActionInvalid, diags
394+
return false, nil, SafeInitActionInvalid, nil, diags
395395
}
396396

397397
reqs = c.removeDevOverrides(reqs)
@@ -409,7 +409,7 @@ func (c *InitCommand) getProvidersFromConfig(ctx context.Context, config *config
409409
}
410410
}
411411
if diags.HasErrors() {
412-
return false, nil, SafeInitActionInvalid, diags
412+
return false, nil, SafeInitActionInvalid, nil, diags
413413
}
414414

415415
var inst *providercache.Installer
@@ -435,10 +435,14 @@ func (c *InitCommand) getProvidersFromConfig(ctx context.Context, config *config
435435
// These allow us to send output to the terminal as events happen, catch
436436
// diagnostics, etc.
437437
//
438-
// One of the things we capture via these callbacks is the location of
438+
// The callbacks help create diagnostics based on installation events, output
439+
// messages to the user,
440+
//
441+
// of the things we capture via these callbacks is the location of
439442
// providers as we install them. This allows the calling code to determine
440443
// what 'safe init' actions need to take place.
441444
providerLocations := make(map[addrs.Provider]getproviders.PackageLocation)
445+
var stateStoreProviderAuthResult *getproviders.PackageAuthenticationResult
442446

443447
initMsg := views.InitializingProviderPluginFromConfigMessage
444448
reuseMsg := views.ReusingPreviousVersionInfo
@@ -674,6 +678,13 @@ func (c *InitCommand) getProvidersFromConfig(ctx context.Context, config *config
674678
}
675679
},
676680
FetchPackageSuccess: func(provider addrs.Provider, version getproviders.Version, localDir string, authResult *getproviders.PackageAuthenticationResult) {
681+
// 1. Capture auth result if this provider is used for state storage.
682+
if config.Module.StateStore != nil && provider.Equals(config.Module.StateStore.ProviderAddr) {
683+
log.Printf("[TRACE] getProvidersFromConfig: state storage provider %s (%q) auth result: %q", config.Module.StateStore.ProviderAddr.Type, config.Module.StateStore.ProviderAddr.ForDisplay(), stateStoreProviderAuthResult.String())
684+
stateStoreProviderAuthResult = authResult
685+
}
686+
687+
// 2. Log a message about the installed provider.
677688
var keyID string
678689
if authResult != nil && authResult.ThirdPartySigned() {
679690
keyID = authResult.KeyID
@@ -739,7 +750,7 @@ func (c *InitCommand) getProvidersFromConfig(ctx context.Context, config *config
739750
if flagLockfile == "readonly" {
740751
diags = diags.Append(fmt.Errorf("The -upgrade flag conflicts with -lockfile=readonly."))
741752
view.Diagnostics(diags)
742-
return true, nil, SafeInitActionInvalid, diags
753+
return true, nil, SafeInitActionInvalid, nil, diags
743754
}
744755

745756
mode = providercache.InstallUpgrades
@@ -749,7 +760,7 @@ func (c *InitCommand) getProvidersFromConfig(ctx context.Context, config *config
749760
previousLocks, moreDiags := c.lockedDependencies()
750761
diags = diags.Append(moreDiags)
751762
if diags.HasErrors() {
752-
return false, nil, SafeInitActionInvalid, diags
763+
return false, nil, SafeInitActionInvalid, nil, diags
753764
}
754765

755766
// Determine which required providers are already downloaded, and download any
@@ -758,7 +769,7 @@ func (c *InitCommand) getProvidersFromConfig(ctx context.Context, config *config
758769
if ctx.Err() == context.Canceled {
759770
diags = diags.Append(fmt.Errorf("Provider installation was canceled by an interrupt signal."))
760771
view.Diagnostics(diags)
761-
return true, nil, SafeInitActionInvalid, diags
772+
return true, nil, SafeInitActionInvalid, nil, diags
762773
}
763774
if err != nil {
764775
// The errors captured in "err" should be redundant with what we
@@ -768,7 +779,7 @@ func (c *InitCommand) getProvidersFromConfig(ctx context.Context, config *config
768779
diags = diags.Append(err)
769780
}
770781

771-
return true, nil, SafeInitActionInvalid, diags
782+
return true, nil, SafeInitActionInvalid, nil, diags
772783
}
773784

774785
// Return advice to the calling code about what to do regarding safe init feature related to state storage providers
@@ -804,7 +815,7 @@ func (c *InitCommand) getProvidersFromConfig(ctx context.Context, config *config
804815
}
805816
}
806817

807-
return true, configLocks, safeInitAction, diags
818+
return true, configLocks, safeInitAction, authResult, diags
808819
}
809820

810821
// getProvidersFromState determines what providers are required by the given state data.

internal/command/init_run.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ func (c *InitCommand) run(initArgs *arguments.Init, view views.Init) int {
214214
previousLocks, moreDiags := c.lockedDependencies()
215215
diags = diags.Append(moreDiags)
216216

217-
configProvidersOutput, configLocks, safeInitAction, configProviderDiags := c.getProvidersFromConfig(ctx, config, initArgs.Upgrade, initArgs.PluginPath, initArgs.Lockfile, view)
217+
configProvidersOutput, configLocks, safeInitAction, stateStoreProviderAuthResult, configProviderDiags := c.getProvidersFromConfig(ctx, config, initArgs.Upgrade, initArgs.PluginPath, initArgs.Lockfile, view)
218218
diags = diags.Append(configProviderDiags)
219219
if configProviderDiags.HasErrors() {
220220
view.Diagnostics(diags)
@@ -232,7 +232,7 @@ func (c *InitCommand) run(initArgs *arguments.Init, view views.Init) int {
232232
case SafeInitActionProceed:
233233
// do nothing; provider is already trusted and there's no need to notify the user.
234234
case SafeInitActionPromptForInput:
235-
diags = diags.Append(c.promptStateStorageProviderApproval(config.Module.StateStore.ProviderAddr, configLocks))
235+
diags = diags.Append(c.promptStateStorageProviderApproval(config.Module.StateStore.ProviderAddr, configLocks, stateStoreProviderAuthResult))
236236
if diags.HasErrors() {
237237
view.Output(views.StateStoreProviderRejectedMessage)
238238
view.Diagnostics(diags)
@@ -418,7 +418,7 @@ If you do not intend to upgrade the state store provider, please update your con
418418

419419
// promptStateStorageProviderApproval is used when Terraform is unsure about the safety of the provider downloaded for state storage
420420
// purposes, and we need to prompt the user to approve or reject using it.
421-
func (c *InitCommand) promptStateStorageProviderApproval(stateStorageProvider addrs.Provider, configLocks *depsfile.Locks) tfdiags.Diagnostics {
421+
func (c *InitCommand) promptStateStorageProviderApproval(stateStorageProvider addrs.Provider, configLocks *depsfile.Locks, authResult *getproviders.PackageAuthenticationResult) tfdiags.Diagnostics {
422422
var diags tfdiags.Diagnostics
423423

424424
// If we can receive input then we prompt for ok from the user
@@ -433,13 +433,15 @@ func (c *InitCommand) promptStateStorageProviderApproval(stateStorageProvider ad
433433
Id: "approve",
434434
Query: fmt.Sprintf(`Do you want to use provider %q (%s), version %s, for managing state?
435435
Platform: %s
436+
Authentication: %s
436437
Hashes:
437438
%s
438439
`,
439440
lock.Provider().Type,
440441
lock.Provider(),
441442
lock.Version(),
442443
getproviders.CurrentPlatform.String(),
444+
authResult.String(),
443445
hashList.String(),
444446
),
445447
Description: fmt.Sprintf(`Check the details above for provider %q and confirm that you trust the provider.

internal/command/init_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3995,6 +3995,7 @@ func TestInit_stateStore_newWorkingDir(t *testing.T) {
39953995
expectedInputPromptMsg := []string{
39963996
"Do you want to use provider \"test\" (registry.terraform.io/hashicorp/test), version 1.2.3, for managing state?",
39973997
getproviders.CurrentPlatform.String(),
3998+
"Authentication: unauthenticated",
39983999
"h1:wlbEC2mChQZ2hhgUhl6SeVLPP7fMqOFUZAQhQ9GIIno=",
39994000
}
40004001
for _, expected := range expectedInputPromptMsg {
@@ -4072,6 +4073,7 @@ func TestInit_stateStore_newWorkingDir(t *testing.T) {
40724073
expectedInputPromptMsg := []string{
40734074
"Do you want to use provider \"test\" (registry.terraform.io/hashicorp/test), version 1.2.3, for managing state?",
40744075
getproviders.CurrentPlatform.String(),
4076+
"Authentication: unauthenticated",
40754077
"h1:wlbEC2mChQZ2hhgUhl6SeVLPP7fMqOFUZAQhQ9GIIno=",
40764078
}
40774079
for _, expected := range expectedInputPromptMsg {

internal/getproviders/package_authentication.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,19 @@ func (t *PackageAuthenticationResult) SignedByHashiCorp() bool {
7171
return false
7272
}
7373

74+
// SignedByHashiCorpPartner returns whether the package was authenticated as signed
75+
// by a HashiCorp partner.
76+
func (t *PackageAuthenticationResult) SignedByHashiCorpPartner() bool {
77+
if t == nil {
78+
return false
79+
}
80+
if t.result == partnerProvider {
81+
return true
82+
}
83+
84+
return false
85+
}
86+
7487
// SignedByAnyParty returns whether the package was authenticated as signed
7588
// by either HashiCorp or by a third-party.
7689
func (t *PackageAuthenticationResult) SignedByAnyParty() bool {

0 commit comments

Comments
 (0)