mirror of
				https://github.com/siderolabs/talos.git
				synced 2025-11-04 10:21:13 +01:00 
			
		
		
		
	feat: add RedactSecrets method to v1alpha1.Config
Add a way to strip away the secrets from a config. Signed-off-by: Utku Ozdemir <utku.ozdemir@siderolabs.com>
This commit is contained in:
		
							parent
							
								
									4c31b9b1a3
								
							
						
					
					
						commit
						cf7adc51c9
					
				@ -19,6 +19,8 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Provider defines the configuration consumption interface.
 | 
			
		||||
//
 | 
			
		||||
//nolint:interfacebloat
 | 
			
		||||
type Provider interface {
 | 
			
		||||
	// Config parts accessor.
 | 
			
		||||
	Version() string
 | 
			
		||||
@ -33,6 +35,9 @@ type Provider interface {
 | 
			
		||||
	// Bytes returns source YAML representation (if available) or does default encoding.
 | 
			
		||||
	Bytes() ([]byte, error)
 | 
			
		||||
 | 
			
		||||
	// RedactSecrets returns a copy of the Provider with all secrets replaced with the given string.
 | 
			
		||||
	RedactSecrets(string) Provider
 | 
			
		||||
 | 
			
		||||
	// Encode configuration to YAML using the provided options.
 | 
			
		||||
	EncodeString(encoderOptions ...encoder.Option) (string, error)
 | 
			
		||||
	EncodeBytes(encoderOptions ...encoder.Option) ([]byte, error)
 | 
			
		||||
 | 
			
		||||
@ -102,6 +102,55 @@ func (c *Config) Bytes() ([]byte, error) {
 | 
			
		||||
	return c.EncodeBytes()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RedactSecrets implements the config.Provider interface.
 | 
			
		||||
func (c *Config) RedactSecrets(replacement string) config.Provider {
 | 
			
		||||
	if c == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	redactBytes := func(b []byte) []byte {
 | 
			
		||||
		if len(b) == 0 {
 | 
			
		||||
			return b
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return []byte(replacement)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	redactStr := func(s string) string {
 | 
			
		||||
		return string(redactBytes([]byte(s)))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	clone := c.DeepCopy()
 | 
			
		||||
 | 
			
		||||
	if clone.MachineConfig != nil {
 | 
			
		||||
		clone.MachineConfig.MachineToken = redactStr(clone.MachineConfig.MachineToken)
 | 
			
		||||
		if clone.MachineConfig.MachineCA != nil {
 | 
			
		||||
			clone.MachineConfig.MachineCA.Key = redactBytes(clone.MachineConfig.MachineCA.Key)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if clone.ClusterConfig != nil {
 | 
			
		||||
		clone.ClusterConfig.ClusterSecret = redactStr(clone.ClusterConfig.ClusterSecret)
 | 
			
		||||
		clone.ClusterConfig.BootstrapToken = redactStr(clone.ClusterConfig.BootstrapToken)
 | 
			
		||||
		clone.ClusterConfig.ClusterAESCBCEncryptionSecret = redactStr(clone.ClusterConfig.ClusterAESCBCEncryptionSecret)
 | 
			
		||||
		clone.ClusterConfig.ClusterSecretboxEncryptionSecret = redactStr(clone.ClusterConfig.ClusterSecretboxEncryptionSecret)
 | 
			
		||||
 | 
			
		||||
		if clone.ClusterConfig.ClusterCA != nil {
 | 
			
		||||
			clone.ClusterConfig.ClusterCA.Key = redactBytes(clone.ClusterConfig.ClusterCA.Key)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if clone.ClusterConfig.ClusterAggregatorCA != nil {
 | 
			
		||||
			clone.ClusterConfig.ClusterAggregatorCA.Key = redactBytes(clone.ClusterConfig.ClusterAggregatorCA.Key)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if clone.ClusterConfig.EtcdConfig != nil && clone.ClusterConfig.EtcdConfig.RootCA != nil {
 | 
			
		||||
			clone.ClusterConfig.EtcdConfig.RootCA.Key = redactBytes(clone.ClusterConfig.EtcdConfig.RootCA.Key)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return clone
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Raw implements the config.Provider interface.
 | 
			
		||||
func (c *Config) Raw() interface{} {
 | 
			
		||||
	return c
 | 
			
		||||
 | 
			
		||||
@ -66,6 +66,11 @@ func (r *ReadonlyProvider) Bytes() ([]byte, error) {
 | 
			
		||||
	return r.bytes, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RedactSecrets implements the config.Provider interface.
 | 
			
		||||
func (r *ReadonlyProvider) RedactSecrets(replacement string) config.Provider {
 | 
			
		||||
	return r.cfg.RedactSecrets(replacement)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// EncodeString implements the config.Provider interface.
 | 
			
		||||
func (r *ReadonlyProvider) EncodeString(encoderOptions ...encoder.Option) (string, error) {
 | 
			
		||||
	return r.cfg.EncodeString(encoderOptions...)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										58
									
								
								pkg/machinery/config/types/v1alpha1/v1alpha1_redact_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								pkg/machinery/config/types/v1alpha1/v1alpha1_redact_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,58 @@
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla Public
 | 
			
		||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
			
		||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
package v1alpha1_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/require"
 | 
			
		||||
 | 
			
		||||
	"github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1/generate"
 | 
			
		||||
	"github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1/machine"
 | 
			
		||||
	"github.com/siderolabs/talos/pkg/machinery/constants"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestRedactSecrets(t *testing.T) {
 | 
			
		||||
	bundle, err := generate.NewSecretsBundle(generate.NewClock())
 | 
			
		||||
	require.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
	input, err := generate.NewInput("test", "https://doesntmatter:6443", constants.DefaultKubernetesVersion, bundle)
 | 
			
		||||
	require.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
	config, err := generate.Config(machine.TypeControlPlane, input)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	require.NotEmpty(t, config.MachineConfig.MachineToken)
 | 
			
		||||
	require.NotEmpty(t, config.MachineConfig.MachineCA.Key)
 | 
			
		||||
	require.NotEmpty(t, config.ClusterConfig.ClusterSecret)
 | 
			
		||||
	require.NotEmpty(t, config.ClusterConfig.BootstrapToken)
 | 
			
		||||
	require.Empty(t, config.ClusterConfig.ClusterAESCBCEncryptionSecret)
 | 
			
		||||
	require.NotEmpty(t, config.ClusterConfig.ClusterSecretboxEncryptionSecret)
 | 
			
		||||
	require.NotEmpty(t, config.ClusterConfig.ClusterCA.Key)
 | 
			
		||||
	require.NotEmpty(t, config.ClusterConfig.EtcdConfig.RootCA.Key)
 | 
			
		||||
 | 
			
		||||
	replacement := "**.***"
 | 
			
		||||
 | 
			
		||||
	configBytesBefore, err := config.Bytes()
 | 
			
		||||
	require.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
	redacted := config.RedactSecrets(replacement)
 | 
			
		||||
 | 
			
		||||
	configBytesAfter, err := config.Bytes()
 | 
			
		||||
	require.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
	require.Equal(t, string(configBytesBefore), string(configBytesAfter), "original config is modified")
 | 
			
		||||
 | 
			
		||||
	require.Equal(t, replacement, redacted.Machine().Security().Token())
 | 
			
		||||
	require.Equal(t, replacement, string(redacted.Machine().Security().CA().Key))
 | 
			
		||||
	require.Equal(t, replacement, redacted.Cluster().Secret())
 | 
			
		||||
	require.Equal(t, "***", redacted.Cluster().Token().Secret())
 | 
			
		||||
	require.Equal(t, "", redacted.Cluster().AESCBCEncryptionSecret())
 | 
			
		||||
	require.Equal(t, replacement, redacted.Cluster().SecretboxEncryptionSecret())
 | 
			
		||||
	require.Equal(t, replacement, string(redacted.Cluster().CA().Key))
 | 
			
		||||
	require.Equal(t, replacement, string(redacted.Cluster().Etcd().CA().Key))
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user