feat: generate secrets bundle from the machine config

This allows to "recover" secrets if the machine config was generated
first without explicitly saving secrets bundle.

Fixes #7895

Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
This commit is contained in:
Andrey Smirnov 2023-10-24 21:47:50 +04:00
parent c7de745f61
commit 8eba4c5999
No known key found for this signature in database
GPG Key ID: FE042E3D4085A811
5 changed files with 26 additions and 14 deletions

View File

@ -13,6 +13,7 @@ import (
"gopkg.in/yaml.v3"
"github.com/siderolabs/talos/pkg/machinery/config"
"github.com/siderolabs/talos/pkg/machinery/config/configloader"
"github.com/siderolabs/talos/pkg/machinery/config/generate/secrets"
)
@ -20,6 +21,7 @@ var genSecretsCmdFlags struct {
outputFile string
talosVersion string
fromKubernetesPki string
fromControlplaneConfig string
kubernetesBootstrapToken string
}
@ -43,19 +45,25 @@ var genSecretsCmd = &cobra.Command{
}
}
if genSecretsCmdFlags.fromKubernetesPki != "" {
switch {
case genSecretsCmdFlags.fromKubernetesPki != "":
secretsBundle, err = secrets.NewBundleFromKubernetesPKI(genSecretsCmdFlags.fromKubernetesPki,
genSecretsCmdFlags.kubernetesBootstrapToken, versionContract)
case genSecretsCmdFlags.fromControlplaneConfig != "":
var cfg config.Provider
cfg, err = configloader.NewFromFile(genSecretsCmdFlags.fromControlplaneConfig)
if err != nil {
return fmt.Errorf("failed to create secrets bundle: %w", err)
return fmt.Errorf("failed to load controlplane config: %w", err)
}
return writeSecretsBundleToFile(secretsBundle)
secretsBundle = secrets.NewBundleFromConfig(secrets.NewFixedClock(time.Now()), cfg)
default:
secretsBundle, err = secrets.NewBundle(secrets.NewFixedClock(time.Now()),
versionContract,
)
}
secretsBundle, err = secrets.NewBundle(secrets.NewFixedClock(time.Now()),
versionContract,
)
if err != nil {
return fmt.Errorf("failed to create secrets bundle: %w", err)
}
@ -80,6 +88,7 @@ func writeSecretsBundleToFile(bundle *secrets.Bundle) error {
func init() {
genSecretsCmd.Flags().StringVarP(&genSecretsCmdFlags.outputFile, "output-file", "o", "secrets.yaml", "path of the output file")
genSecretsCmd.Flags().StringVar(&genSecretsCmdFlags.talosVersion, "talos-version", "", "the desired Talos version to generate secrets bundle for (backwards compatibility, e.g. v0.8)")
genSecretsCmd.Flags().StringVar(&genSecretsCmdFlags.fromControlplaneConfig, "from-controlplane-config", "", "use the provided controlplane Talos machine configuration as input")
genSecretsCmd.Flags().StringVarP(&genSecretsCmdFlags.fromKubernetesPki, "from-kubernetes-pki", "p", "", "use a Kubernetes PKI directory (e.g. /etc/kubernetes/pki) as input")
genSecretsCmd.Flags().StringVarP(&genSecretsCmdFlags.kubernetesBootstrapToken, "kubernetes-bootstrap-token", "t", "", "use the provided bootstrap token as input")

View File

@ -13,7 +13,6 @@ import (
"path/filepath"
"regexp"
"strings"
"time"
"gopkg.in/yaml.v3"
@ -277,14 +276,14 @@ func (suite *GenSuite) TestConfigWithSecrets() {
base.StderrNotEmpty(),
)
config, err := configloader.NewFromFile("controlplane.yaml")
suite.RunCLI([]string{"gen", "secrets", "--from-controlplane-config", "controlplane.yaml", "--output-file", "secrets-from-config.yaml"},
base.StdoutEmpty(),
)
configSecretsBundle, err := os.ReadFile("secrets-from-config.yaml")
suite.Assert().NoError(err)
configSecretsBundle := secrets.NewBundleFromConfig(secrets.NewFixedClock(time.Now()), config)
configSecretsBundleBytes, err := yaml.Marshal(configSecretsBundle)
suite.Assert().NoError(err)
suite.Assert().YAMLEq(string(secretsYaml), string(configSecretsBundleBytes))
suite.Assert().YAMLEq(string(secretsYaml), string(configSecretsBundle))
}
// TestGenConfigWithDeprecatedOutputDirFlag tests that gen config command still works with the deprecated --output-dir flag.

View File

@ -178,7 +178,7 @@ install:
to reflect `vda` instead of `sda`.
>For information on customizing your machine configurations (such as to specify the version of Kubernetes), using [machine configuration patches]({{< relref "../talos-guides/configuration/patching" >}}), or customizing configurations for individual machines (such as setting static IP addresses), see the [Production Notes]({{< relref "prodnotes#customizing-machine-configuration" >}}).
> For information on customizing your machine configurations (such as to specify the version of Kubernetes), using [machine configuration patches]({{< relref "../talos-guides/configuration/patching" >}}), or customizing configurations for individual machines (such as setting static IP addresses), see the [Production Notes]({{< relref "prodnotes#customizing-machine-configuration" >}}).
## Understand talosctl, endpoints and nodes

View File

@ -181,6 +181,9 @@ This bundle can be used to generate machine or client configurations at any time
talosctl gen secrets -o secrets.yaml
```
> The `secrets.yaml` can also be extracted from the existing controlplane machine configuration with
> `talosctl gen secrets --from-controlplane-config controlplane.yaml -o secrets.yaml` command.
Now, we can generate the machine configuration for each node:
```sh

View File

@ -1495,6 +1495,7 @@ talosctl gen secrets [flags]
### Options
```
--from-controlplane-config string use the provided controlplane Talos machine configuration as input
-p, --from-kubernetes-pki string use a Kubernetes PKI directory (e.g. /etc/kubernetes/pki) as input
-h, --help help for secrets
-t, --kubernetes-bootstrap-token string use the provided bootstrap token as input