Browse Source

[CC-5718] Remove HCP token requirement during bootstrap (#18140)

* [CC-5718] Remove HCP token requirement during bootstrap

* Re-add error for loading HCP management token

* Remove old comment

* Add changelog entry

* Remove extra validation line

* Apply suggestions from code review

Co-authored-by: lornasong <lornasong@users.noreply.github.com>

---------

Co-authored-by: lornasong <lornasong@users.noreply.github.com>
pull/18214/head^2
Jeremy Jacobson 1 year ago committed by GitHub
parent
commit
6671d7ebd7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .changelog/18140.txt
  2. 25
      agent/hcp/bootstrap/bootstrap.go
  3. 37
      agent/hcp/bootstrap/bootstrap_test.go

3
.changelog/18140.txt

@ -0,0 +1,3 @@
```release-note:improvement
hcp: Removes requirement for HCP to provide a management token
```

25
agent/hcp/bootstrap/bootstrap.go

@ -298,21 +298,25 @@ func persistAndProcessConfig(dataDir string, devMode bool, bsCfg *hcpclient.Boot
return "", fmt.Errorf("failed to persist bootstrap config: %w", err) return "", fmt.Errorf("failed to persist bootstrap config: %w", err)
} }
if err := validateManagementToken(bsCfg.ManagementToken); err != nil { // HCP only returns the management token if it requires Consul to
return "", fmt.Errorf("invalid management token: %w", err) // initialize it
} if bsCfg.ManagementToken != "" {
if err := persistManagementToken(dir, bsCfg.ManagementToken); err != nil { if err := validateManagementToken(bsCfg.ManagementToken); err != nil {
return "", fmt.Errorf("failed to persist HCP management token: %w", err) return "", fmt.Errorf("invalid management token: %w", err)
}
if err := persistManagementToken(dir, bsCfg.ManagementToken); err != nil {
return "", fmt.Errorf("failed to persist HCP management token: %w", err)
}
} }
if err := persistSucessMarker(dir); err != nil { if err := persistSuccessMarker(dir); err != nil {
return "", fmt.Errorf("failed to persist success marker: %w", err) return "", fmt.Errorf("failed to persist success marker: %w", err)
} }
} }
return cfgJSON, nil return cfgJSON, nil
} }
func persistSucessMarker(dir string) error { func persistSuccessMarker(dir string) error {
name := filepath.Join(dir, successFileName) name := filepath.Join(dir, successFileName)
return os.WriteFile(name, []byte(""), 0600) return os.WriteFile(name, []byte(""), 0600)
@ -352,12 +356,9 @@ func persistTLSCerts(dir string, serverCert, serverKey string, caCerts []string)
return nil return nil
} }
// Basic validation to ensure a UUID was loaded. // Basic validation to ensure a UUID was loaded and assumes the token is non-empty
func validateManagementToken(token string) error { func validateManagementToken(token string) error {
if token == "" { // note: we assume that the token is not an empty string
return errors.New("missing HCP management token")
}
if _, err := uuid.ParseUUID(token); err != nil { if _, err := uuid.ParseUUID(token); err != nil {
return errors.New("management token is not a valid UUID") return errors.New("management token is not a valid UUID")
} }

37
agent/hcp/bootstrap/bootstrap_test.go

@ -305,9 +305,10 @@ func Test_loadPersistedBootstrapConfig(t *testing.T) {
warning string warning string
} }
type testCase struct { type testCase struct {
existingCluster bool existingCluster bool
mutateFn func(t *testing.T, dir string) disableManagementToken bool
expect expect mutateFn func(t *testing.T, dir string)
expect expect
} }
run := func(t *testing.T, tc testCase) { run := func(t *testing.T, tc testCase) {
@ -319,7 +320,7 @@ func Test_loadPersistedBootstrapConfig(t *testing.T) {
// Do some common setup as if we received config from HCP and persisted it to disk. // Do some common setup as if we received config from HCP and persisted it to disk.
require.NoError(t, lib.EnsurePath(dir, true)) require.NoError(t, lib.EnsurePath(dir, true))
require.NoError(t, persistSucessMarker(dir)) require.NoError(t, persistSuccessMarker(dir))
if !tc.existingCluster { if !tc.existingCluster {
caCert, caKey, err := tlsutil.GenerateCA(tlsutil.CAOpts{}) caCert, caKey, err := tlsutil.GenerateCA(tlsutil.CAOpts{})
@ -333,9 +334,12 @@ func Test_loadPersistedBootstrapConfig(t *testing.T) {
require.NoError(t, persistBootstrapConfig(dir, cfgJSON)) require.NoError(t, persistBootstrapConfig(dir, cfgJSON))
} }
token, err := uuid.GenerateUUID() var token string
require.NoError(t, err) if !tc.disableManagementToken {
require.NoError(t, persistManagementToken(dir, token)) token, err = uuid.GenerateUUID()
require.NoError(t, err)
require.NoError(t, persistManagementToken(dir, token))
}
// Optionally mutate the persisted data to trigger errors while loading. // Optionally mutate the persisted data to trigger errors while loading.
if tc.mutateFn != nil { if tc.mutateFn != nil {
@ -348,7 +352,6 @@ func Test_loadPersistedBootstrapConfig(t *testing.T) {
if loaded { if loaded {
require.Equal(t, token, cfg.ManagementToken) require.Equal(t, token, cfg.ManagementToken)
require.Empty(t, ui.ErrorWriter.String()) require.Empty(t, ui.ErrorWriter.String())
} else { } else {
require.Nil(t, cfg) require.Nil(t, cfg)
require.Contains(t, ui.ErrorWriter.String(), tc.expect.warning) require.Contains(t, ui.ErrorWriter.String(), tc.expect.warning)
@ -365,15 +368,11 @@ func Test_loadPersistedBootstrapConfig(t *testing.T) {
warning: "", warning: "",
}, },
}, },
"existing cluster missing token": { "existing cluster no token": {
existingCluster: true, existingCluster: true,
mutateFn: func(t *testing.T, dir string) { disableManagementToken: true,
// Remove the token file while leaving the existing cluster marker.
require.NoError(t, os.Remove(filepath.Join(dir, tokenFileName)))
},
expect: expect{ expect: expect{
loaded: false, loaded: false,
warning: "configuration files on disk are incomplete",
}, },
}, },
"existing cluster no files": { "existing cluster no files": {
@ -396,6 +395,12 @@ func Test_loadPersistedBootstrapConfig(t *testing.T) {
warning: "", warning: "",
}, },
}, },
"new cluster with no token": {
disableManagementToken: true,
expect: expect{
loaded: false,
},
},
"new cluster some files": { "new cluster some files": {
mutateFn: func(t *testing.T, dir string) { mutateFn: func(t *testing.T, dir string) {
// Remove one of the required files // Remove one of the required files

Loading…
Cancel
Save