Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 6 commits into from
Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/18140.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
hcp: Removes requirement for HCP to provide a management token
```
25 changes: 13 additions & 12 deletions agent/hcp/bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,21 +298,25 @@ func persistAndProcessConfig(dataDir string, devMode bool, bsCfg *hcpclient.Boot
return "", fmt.Errorf("failed to persist bootstrap config: %w", err)
}

if err := validateManagementToken(bsCfg.ManagementToken); err != nil {
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)
// HCP only returns the management token if it requires Consul to
// initialize it
if bsCfg.ManagementToken != "" {
lornasong marked this conversation as resolved.
Show resolved Hide resolved
jjacobson93 marked this conversation as resolved.
Show resolved Hide resolved
if err := validateManagementToken(bsCfg.ManagementToken); err != nil {
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 cfgJSON, nil
}

func persistSucessMarker(dir string) error {
func persistSuccessMarker(dir string) error {
name := filepath.Join(dir, successFileName)
return os.WriteFile(name, []byte(""), 0600)

Expand Down Expand Up @@ -352,12 +356,9 @@ func persistTLSCerts(dir string, serverCert, serverKey string, caCerts []string)
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 {
if token == "" {
return errors.New("missing HCP management token")
}

// note: we assume that the token is not an empty string
if _, err := uuid.ParseUUID(token); err != nil {
return errors.New("management token is not a valid UUID")
}
Expand Down
37 changes: 21 additions & 16 deletions agent/hcp/bootstrap/bootstrap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,10 @@ func Test_loadPersistedBootstrapConfig(t *testing.T) {
warning string
}
type testCase struct {
existingCluster bool
mutateFn func(t *testing.T, dir string)
expect expect
existingCluster bool
disableManagementToken bool
mutateFn func(t *testing.T, dir string)
expect expect
}

run := func(t *testing.T, tc testCase) {
Expand All @@ -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.
require.NoError(t, lib.EnsurePath(dir, true))
require.NoError(t, persistSucessMarker(dir))
require.NoError(t, persistSuccessMarker(dir))

if !tc.existingCluster {
caCert, caKey, err := tlsutil.GenerateCA(tlsutil.CAOpts{})
Expand All @@ -333,9 +334,12 @@ func Test_loadPersistedBootstrapConfig(t *testing.T) {
require.NoError(t, persistBootstrapConfig(dir, cfgJSON))
}

token, err := uuid.GenerateUUID()
require.NoError(t, err)
require.NoError(t, persistManagementToken(dir, token))
var token string
if !tc.disableManagementToken {
token, err = uuid.GenerateUUID()
require.NoError(t, err)
require.NoError(t, persistManagementToken(dir, token))
}

// Optionally mutate the persisted data to trigger errors while loading.
if tc.mutateFn != nil {
Expand All @@ -348,7 +352,6 @@ func Test_loadPersistedBootstrapConfig(t *testing.T) {
if loaded {
require.Equal(t, token, cfg.ManagementToken)
require.Empty(t, ui.ErrorWriter.String())

} else {
require.Nil(t, cfg)
require.Contains(t, ui.ErrorWriter.String(), tc.expect.warning)
Expand All @@ -365,15 +368,11 @@ func Test_loadPersistedBootstrapConfig(t *testing.T) {
warning: "",
},
},
"existing cluster missing token": {
existingCluster: true,
mutateFn: func(t *testing.T, dir string) {
// Remove the token file while leaving the existing cluster marker.
require.NoError(t, os.Remove(filepath.Join(dir, tokenFileName)))
},
"existing cluster no token": {
existingCluster: true,
disableManagementToken: true,
expect: expect{
loaded: false,
warning: "configuration files on disk are incomplete",
loaded: false,
},
},
"existing cluster no files": {
Expand All @@ -396,6 +395,12 @@ func Test_loadPersistedBootstrapConfig(t *testing.T) {
warning: "",
},
},
"new cluster with no token": {
disableManagementToken: true,
expect: expect{
loaded: false,
},
},
"new cluster some files": {
mutateFn: func(t *testing.T, dir string) {
// Remove one of the required files
Expand Down