Skip to content

Commit

Permalink
feat: generate secrets bundle from the machine config
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
smira committed Oct 25, 2023
1 parent c7de745 commit 8eba4c5
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 14 deletions.
21 changes: 15 additions & 6 deletions cmd/talosctl/cmd/mgmt/gen/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ 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"
)

var genSecretsCmdFlags struct {
outputFile string
talosVersion string
fromKubernetesPki string
fromControlplaneConfig string
kubernetesBootstrapToken string
}

Expand All @@ -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)
}
Expand All @@ -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")

Expand Down
13 changes: 6 additions & 7 deletions internal/integration/cli/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"path/filepath"
"regexp"
"strings"
"time"

"gopkg.in/yaml.v3"

Expand Down Expand Up @@ -277,14 +276,14 @@ func (suite *GenSuite) TestConfigWithSecrets() {
base.StderrNotEmpty(),
)

config, err := configloader.NewFromFile("controlplane.yaml")
suite.Assert().NoError(err)

configSecretsBundle := secrets.NewBundleFromConfig(secrets.NewFixedClock(time.Now()), config)
configSecretsBundleBytes, err := yaml.Marshal(configSecretsBundle)
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)
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.
Expand Down
2 changes: 1 addition & 1 deletion website/content/v1.6/introduction/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
3 changes: 3 additions & 0 deletions website/content/v1.6/introduction/prodnotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions website/content/v1.6/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 8eba4c5

Please sign in to comment.