mirror of https://github.com/status-im/consul.git
[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>
This commit is contained in:
parent
7e01fcf5c0
commit
6671d7ebd7
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:improvement
|
||||||
|
hcp: Removes requirement for HCP to provide a management token
|
||||||
|
```
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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…
Reference in New Issue