feat: make GenerateConfiguration API reuse current node auth
Fixes: https://github.com/talos-systems/talos/issues/2819 Only if requested config type is not `TypeInit`. This functionality will help implementing TUI installer cluster extension workflow. Signed-off-by: Artem Chernyshev <artem.0xD2@gmail.com>
This commit is contained in:
parent
b1c0f99c04
commit
2588e2960b
@ -108,6 +108,39 @@ func (suite *GenerateConfigSuite) TestGenerate() {
|
||||
suite.Require().NotEmpty(context.Key)
|
||||
suite.Require().Greater(len(context.Endpoints), 0)
|
||||
suite.Require().EqualValues(context.Endpoints[0], config.Cluster().Endpoint().Hostname())
|
||||
|
||||
// now generate control plane join config
|
||||
request.MachineConfig.Type = machineapi.MachineConfig_MachineType(machine.TypeControlPlane)
|
||||
|
||||
reply, err = suite.Client.GenerateConfiguration(
|
||||
suite.ctx,
|
||||
request,
|
||||
)
|
||||
|
||||
suite.Require().NoError(err)
|
||||
|
||||
data = reply.GetData()
|
||||
|
||||
joinedConfig, err := configloader.NewFromBytes(data[0])
|
||||
|
||||
suite.Require().NoError(err)
|
||||
|
||||
suite.Require().EqualValues(request.MachineConfig.Type, joinedConfig.Machine().Type())
|
||||
suite.Require().EqualValues(request.ConfigVersion, joinedConfig.Version())
|
||||
suite.Require().EqualValues(request.ClusterConfig.Name, joinedConfig.Cluster().Name())
|
||||
suite.Require().EqualValues(request.ClusterConfig.ControlPlane.Endpoint, joinedConfig.Cluster().Endpoint().String())
|
||||
suite.Require().EqualValues(request.ClusterConfig.ClusterNetwork.DnsDomain, joinedConfig.Cluster().Network().DNSDomain())
|
||||
suite.Require().EqualValues(fmt.Sprintf("%s:v%s", constants.KubeletImage, request.MachineConfig.KubernetesVersion), joinedConfig.Machine().Kubelet().Image())
|
||||
suite.Require().EqualValues(request.MachineConfig.InstallConfig.InstallDisk, joinedConfig.Machine().Install().Disk())
|
||||
suite.Require().EqualValues(request.MachineConfig.InstallConfig.InstallImage, joinedConfig.Machine().Install().Image())
|
||||
suite.Require().EqualValues(request.MachineConfig.NetworkConfig.Hostname, joinedConfig.Machine().Network().Hostname())
|
||||
|
||||
suite.Require().EqualValues(config.Machine().Security().CA(), joinedConfig.Machine().Security().CA())
|
||||
suite.Require().EqualValues(config.Machine().Security().Token(), joinedConfig.Machine().Security().Token())
|
||||
suite.Require().EqualValues(config.Cluster().AESCBCEncryptionSecret(), joinedConfig.Cluster().AESCBCEncryptionSecret())
|
||||
suite.Require().EqualValues(config.Cluster().CA(), joinedConfig.Cluster().CA())
|
||||
suite.Require().EqualValues(config.Cluster().Token(), joinedConfig.Cluster().Token())
|
||||
suite.Require().EqualValues(config.Cluster().Etcd().CA(), config.Cluster().Etcd().CA())
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -8,19 +8,22 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
"github.com/talos-systems/talos/pkg/machinery/api/machine"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/configloader"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/generate"
|
||||
v1alpha1machine "github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/machine"
|
||||
"github.com/talos-systems/talos/pkg/machinery/constants"
|
||||
)
|
||||
|
||||
// Generate config for GenerateConfiguration grpc.
|
||||
//
|
||||
// nolint:gocyclo
|
||||
func Generate(ctx context.Context, in *machine.GenerateConfigurationRequest) (reply *machine.GenerateConfigurationResponse, err error) {
|
||||
var config config.Provider
|
||||
var c config.Provider
|
||||
|
||||
if in.MachineConfig == nil || in.ClusterConfig == nil || in.ClusterConfig.ControlPlane == nil {
|
||||
return nil, fmt.Errorf("invalid generate request")
|
||||
@ -60,12 +63,29 @@ func Generate(ctx context.Context, in *machine.GenerateConfigurationRequest) (re
|
||||
input *generate.Input
|
||||
cfgBytes []byte
|
||||
taloscfgBytes []byte
|
||||
baseConfig config.Provider
|
||||
secrets *generate.SecretsBundle
|
||||
)
|
||||
|
||||
baseConfig, err = configloader.NewFromFile(constants.ConfigPath)
|
||||
|
||||
switch {
|
||||
case os.IsNotExist(err):
|
||||
secrets, err = generate.NewSecretsBundle()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case err != nil:
|
||||
return nil, err
|
||||
default:
|
||||
secrets = generate.NewSecretsBundleFromConfig(baseConfig)
|
||||
}
|
||||
|
||||
input, err = generate.NewInput(
|
||||
in.ClusterConfig.Name,
|
||||
in.ClusterConfig.ControlPlane.Endpoint,
|
||||
in.MachineConfig.KubernetesVersion,
|
||||
secrets,
|
||||
options...,
|
||||
)
|
||||
|
||||
@ -73,7 +93,7 @@ func Generate(ctx context.Context, in *machine.GenerateConfigurationRequest) (re
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config, err = generate.Config(
|
||||
c, err = generate.Config(
|
||||
machineType,
|
||||
input,
|
||||
)
|
||||
@ -82,7 +102,7 @@ func Generate(ctx context.Context, in *machine.GenerateConfigurationRequest) (re
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfgBytes, err = config.Bytes()
|
||||
cfgBytes, err = c.Bytes()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -80,12 +80,18 @@ func NewConfigBundle(opts ...Option) (*v1alpha1.ConfigBundle, error) {
|
||||
fmt.Println("generating PKI and tokens")
|
||||
}
|
||||
|
||||
secrets, err := generate.NewSecretsBundle()
|
||||
if err != nil {
|
||||
return bundle, err
|
||||
}
|
||||
|
||||
var input *generate.Input
|
||||
|
||||
input, err := generate.NewInput(
|
||||
input, err = generate.NewInput(
|
||||
options.InputOptions.ClusterName,
|
||||
options.InputOptions.Endpoint,
|
||||
options.InputOptions.KubeVersion,
|
||||
secrets,
|
||||
options.InputOptions.GenOptions...,
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
stdlibx509 "crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"time"
|
||||
@ -17,6 +18,7 @@ import (
|
||||
"github.com/talos-systems/crypto/x509"
|
||||
tnet "github.com/talos-systems/net"
|
||||
|
||||
"github.com/talos-systems/talos/pkg/machinery/config"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/internal/cis"
|
||||
v1alpha1 "github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/machine"
|
||||
@ -132,7 +134,7 @@ type Certs struct {
|
||||
OS *x509.PEMEncodedCertificateAndKey
|
||||
}
|
||||
|
||||
// Secrets holds the senesitve kubeadm data.
|
||||
// Secrets holds the sensitive kubeadm data.
|
||||
type Secrets struct {
|
||||
BootstrapToken string
|
||||
AESCBCEncryptionSecret string
|
||||
@ -143,6 +145,114 @@ type TrustdInfo struct {
|
||||
Token string
|
||||
}
|
||||
|
||||
// SecretsBundle holds trustd, kubeadm and certs information.
|
||||
type SecretsBundle struct {
|
||||
Secrets *Secrets
|
||||
TrustdInfo *TrustdInfo
|
||||
Certs *Certs
|
||||
}
|
||||
|
||||
// NewSecretsBundle creates secrets bundle generating all secrets.
|
||||
func NewSecretsBundle() (*SecretsBundle, error) {
|
||||
var (
|
||||
etcd *x509.CertificateAuthority
|
||||
kubernetesCA *x509.CertificateAuthority
|
||||
talosCA *x509.CertificateAuthority
|
||||
trustdInfo *TrustdInfo
|
||||
kubeadmTokens *Secrets
|
||||
err error
|
||||
)
|
||||
|
||||
etcd, err = NewEtcdCA()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kubernetesCA, err = NewKubernetesCA()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
talosCA, err = NewTalosCA()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kubeadmTokens = &Secrets{}
|
||||
|
||||
// Gen trustd token strings
|
||||
kubeadmTokens.BootstrapToken, err = genToken(6, 16)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kubeadmTokens.AESCBCEncryptionSecret, err = cis.CreateEncryptionToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
trustdInfo = &TrustdInfo{}
|
||||
|
||||
// Gen trustd token strings
|
||||
trustdInfo.Token, err = genToken(6, 16)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &SecretsBundle{
|
||||
Secrets: kubeadmTokens,
|
||||
TrustdInfo: trustdInfo,
|
||||
Certs: &Certs{
|
||||
Etcd: &x509.PEMEncodedCertificateAndKey{
|
||||
Crt: etcd.CrtPEM,
|
||||
Key: etcd.KeyPEM,
|
||||
},
|
||||
K8s: &x509.PEMEncodedCertificateAndKey{
|
||||
Crt: kubernetesCA.CrtPEM,
|
||||
Key: kubernetesCA.KeyPEM,
|
||||
},
|
||||
OS: &x509.PEMEncodedCertificateAndKey{
|
||||
Crt: talosCA.CrtPEM,
|
||||
Key: talosCA.KeyPEM,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewSecretsBundleFromConfig creates secrets bundle using existing config.
|
||||
func NewSecretsBundleFromConfig(c config.Provider) *SecretsBundle {
|
||||
certs := &Certs{
|
||||
K8s: c.Cluster().CA(),
|
||||
Etcd: c.Cluster().Etcd().CA(),
|
||||
OS: c.Machine().Security().CA(),
|
||||
}
|
||||
|
||||
trustd := &TrustdInfo{
|
||||
Token: c.Machine().Security().Token(),
|
||||
}
|
||||
|
||||
bootstrapToken := fmt.Sprintf(
|
||||
"%s.%s",
|
||||
c.Cluster().Token().ID(),
|
||||
c.Cluster().Token().Secret(),
|
||||
)
|
||||
|
||||
secrets := &Secrets{
|
||||
AESCBCEncryptionSecret: c.Cluster().AESCBCEncryptionSecret(),
|
||||
BootstrapToken: bootstrapToken,
|
||||
}
|
||||
|
||||
return &SecretsBundle{
|
||||
Secrets: secrets,
|
||||
TrustdInfo: trustd,
|
||||
Certs: certs,
|
||||
}
|
||||
}
|
||||
|
||||
// NewEtcdCA generates a CA for the Etcd PKI.
|
||||
func NewEtcdCA() (ca *x509.CertificateAuthority, err error) {
|
||||
opts := []x509.Option{
|
||||
@ -211,7 +321,7 @@ func NewAdminCertificateAndKey(crt, key []byte, loopback string) (p *x509.PEMEnc
|
||||
// NewInput generates the sensitive data required to generate all config
|
||||
// types.
|
||||
// nolint: dupl,gocyclo
|
||||
func NewInput(clustername, endpoint, kubernetesVersion string, opts ...GenOption) (input *Input, err error) {
|
||||
func NewInput(clustername, endpoint, kubernetesVersion string, secrets *SecretsBundle, opts ...GenOption) (input *Input, err error) {
|
||||
options := DefaultGenOptions()
|
||||
|
||||
for _, opt := range opts {
|
||||
@ -232,68 +342,16 @@ func NewInput(clustername, endpoint, kubernetesVersion string, opts ...GenOption
|
||||
serviceNet = constants.DefaultIPv4ServiceNet
|
||||
}
|
||||
|
||||
// Gen trustd token strings
|
||||
kubeadmBootstrapToken, err := genToken(6, 16)
|
||||
secrets.Certs.Admin, err = NewAdminCertificateAndKey(
|
||||
secrets.Certs.OS.Crt,
|
||||
secrets.Certs.OS.Key,
|
||||
loopback,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aescbcEncryptionSecret, err := cis.CreateEncryptionToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Gen trustd token strings
|
||||
trustdToken, err := genToken(6, 16)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kubeadmTokens := &Secrets{
|
||||
BootstrapToken: kubeadmBootstrapToken,
|
||||
AESCBCEncryptionSecret: aescbcEncryptionSecret,
|
||||
}
|
||||
|
||||
trustdInfo := &TrustdInfo{
|
||||
Token: trustdToken,
|
||||
}
|
||||
|
||||
etcdCA, err := NewEtcdCA()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kubernetesCA, err := NewKubernetesCA()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
talosCA, err := NewTalosCA()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
admin, err := NewAdminCertificateAndKey(talosCA.CrtPEM, talosCA.KeyPEM, loopback)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
certs := &Certs{
|
||||
Admin: admin,
|
||||
Etcd: &x509.PEMEncodedCertificateAndKey{
|
||||
Crt: etcdCA.CrtPEM,
|
||||
Key: etcdCA.KeyPEM,
|
||||
},
|
||||
K8s: &x509.PEMEncodedCertificateAndKey{
|
||||
Crt: kubernetesCA.CrtPEM,
|
||||
Key: kubernetesCA.KeyPEM,
|
||||
},
|
||||
OS: &x509.PEMEncodedCertificateAndKey{
|
||||
Crt: talosCA.CrtPEM,
|
||||
Key: talosCA.KeyPEM,
|
||||
},
|
||||
}
|
||||
|
||||
var additionalSubjectAltNames []string
|
||||
|
||||
var additionalMachineCertSANs []string
|
||||
@ -310,7 +368,7 @@ func NewInput(clustername, endpoint, kubernetesVersion string, opts ...GenOption
|
||||
}
|
||||
|
||||
input = &Input{
|
||||
Certs: certs,
|
||||
Certs: secrets.Certs,
|
||||
ControlPlaneEndpoint: endpoint,
|
||||
PodNet: []string{podNet},
|
||||
ServiceNet: []string{serviceNet},
|
||||
@ -318,8 +376,8 @@ func NewInput(clustername, endpoint, kubernetesVersion string, opts ...GenOption
|
||||
ClusterName: clustername,
|
||||
Architecture: options.Architecture,
|
||||
KubernetesVersion: kubernetesVersion,
|
||||
Secrets: kubeadmTokens,
|
||||
TrustdInfo: trustdInfo,
|
||||
Secrets: secrets.Secrets,
|
||||
TrustdInfo: secrets.TrustdInfo,
|
||||
AdditionalSubjectAltNames: additionalSubjectAltNames,
|
||||
AdditionalMachineCertSANs: additionalMachineCertSANs,
|
||||
InstallDisk: options.InstallDisk,
|
||||
|
@ -26,7 +26,9 @@ func TestGenerateSuite(t *testing.T) {
|
||||
|
||||
func (suite *GenerateSuite) SetupSuite() {
|
||||
var err error
|
||||
suite.input, err = genv1alpha1.NewInput("test", "10.0.1.5", constants.DefaultKubernetesVersion)
|
||||
secrets, err := genv1alpha1.NewSecretsBundle()
|
||||
suite.Require().NoError(err)
|
||||
suite.input, err = genv1alpha1.NewInput("test", "10.0.1.5", constants.DefaultKubernetesVersion, secrets)
|
||||
suite.Require().NoError(err)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user