mirror of
https://github.com/lingble/talos.git
synced 2025-12-05 15:15:35 +00:00
feat(init): Add initToken parameter to userdata (#664)
Signed-off-by: Brad Beam <brad.beam@talos-systems.com>
This commit is contained in:
@@ -7,6 +7,7 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
stdlibx509 "crypto/x509"
|
stdlibx509 "crypto/x509"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"path"
|
"path"
|
||||||
@@ -16,6 +17,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/talos-systems/talos/cmd/osctl/pkg/helpers"
|
"github.com/talos-systems/talos/cmd/osctl/pkg/helpers"
|
||||||
"github.com/talos-systems/talos/pkg/crypto/x509"
|
"github.com/talos-systems/talos/pkg/crypto/x509"
|
||||||
|
"github.com/talos-systems/talos/pkg/userdata/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// genCmd represents the gen command
|
// genCmd represents the gen command
|
||||||
@@ -39,13 +41,13 @@ var caCmd = &cobra.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
helpers.Fatalf("error generating CA: %s", err)
|
helpers.Fatalf("error generating CA: %s", err)
|
||||||
}
|
}
|
||||||
if err := ioutil.WriteFile(organization+".crt", ca.CrtPEM, 0400); err != nil {
|
if err := ioutil.WriteFile(organization+".crt", ca.CrtPEM, 0600); err != nil {
|
||||||
helpers.Fatalf("error writing CA certificate: %s", err)
|
helpers.Fatalf("error writing CA certificate: %s", err)
|
||||||
}
|
}
|
||||||
if err := ioutil.WriteFile(organization+".sha256", []byte(x509.Hash(ca.Crt)), 0400); err != nil {
|
if err := ioutil.WriteFile(organization+".sha256", []byte(x509.Hash(ca.Crt)), 0600); err != nil {
|
||||||
helpers.Fatalf("error writing certificate hash: %s", err)
|
helpers.Fatalf("error writing certificate hash: %s", err)
|
||||||
}
|
}
|
||||||
if err := ioutil.WriteFile(organization+".key", ca.KeyPEM, 0400); err != nil {
|
if err := ioutil.WriteFile(organization+".key", ca.KeyPEM, 0600); err != nil {
|
||||||
helpers.Fatalf("error writing key: %s", err)
|
helpers.Fatalf("error writing key: %s", err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -61,7 +63,7 @@ var keyCmd = &cobra.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
helpers.Fatalf("error generating key: %s", err)
|
helpers.Fatalf("error generating key: %s", err)
|
||||||
}
|
}
|
||||||
if err := ioutil.WriteFile(name+".key", key.KeyPEM, 0400); err != nil {
|
if err := ioutil.WriteFile(name+".key", key.KeyPEM, 0600); err != nil {
|
||||||
helpers.Fatalf("error writing key: %s", err)
|
helpers.Fatalf("error writing key: %s", err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -97,7 +99,7 @@ var csrCmd = &cobra.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
helpers.Fatalf("error generating CSR: %s", err)
|
helpers.Fatalf("error generating CSR: %s", err)
|
||||||
}
|
}
|
||||||
if err := ioutil.WriteFile(strings.TrimSuffix(key, path.Ext(key))+".csr", csr.X509CertificateRequestPEM, 0400); err != nil {
|
if err := ioutil.WriteFile(strings.TrimSuffix(key, path.Ext(key))+".csr", csr.X509CertificateRequestPEM, 0600); err != nil {
|
||||||
helpers.Fatalf("error writing CSR: %s", err)
|
helpers.Fatalf("error writing CSR: %s", err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -149,7 +151,7 @@ var crtCmd = &cobra.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
helpers.Fatalf("error signing certificate: %s", err)
|
helpers.Fatalf("error signing certificate: %s", err)
|
||||||
}
|
}
|
||||||
if err := ioutil.WriteFile(name+".crt", signedCrt.X509CertificatePEM, 0400); err != nil {
|
if err := ioutil.WriteFile(name+".crt", signedCrt.X509CertificatePEM, 0600); err != nil {
|
||||||
helpers.Fatalf("error writing certificate: %s", err)
|
helpers.Fatalf("error writing certificate: %s", err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -177,15 +179,29 @@ var keypairCmd = &cobra.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
helpers.Fatalf("error generating CA: %s", err)
|
helpers.Fatalf("error generating CA: %s", err)
|
||||||
}
|
}
|
||||||
if err := ioutil.WriteFile(organization+".crt", ca.CrtPEM, 0400); err != nil {
|
if err := ioutil.WriteFile(organization+".crt", ca.CrtPEM, 0600); err != nil {
|
||||||
helpers.Fatalf("error writing certificate: %s", err)
|
helpers.Fatalf("error writing certificate: %s", err)
|
||||||
}
|
}
|
||||||
if err := ioutil.WriteFile(organization+".key", ca.KeyPEM, 0400); err != nil {
|
if err := ioutil.WriteFile(organization+".key", ca.KeyPEM, 0600); err != nil {
|
||||||
helpers.Fatalf("error writing key: %s", err)
|
helpers.Fatalf("error writing key: %s", err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// inittoken represents the gen token command
|
||||||
|
var inittokenCmd = &cobra.Command{
|
||||||
|
Use: "token",
|
||||||
|
Short: "Generates a UUIDv1 token",
|
||||||
|
Long: ``,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
initToken, err := token.NewToken()
|
||||||
|
if err != nil {
|
||||||
|
helpers.Fatalf("Failed to generate new init token: %s", err)
|
||||||
|
}
|
||||||
|
fmt.Println(initToken.String())
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// Certificate Authorities
|
// Certificate Authorities
|
||||||
caCmd.Flags().StringVar(&organization, "organization", "", "X.509 distinguished name for the Organization")
|
caCmd.Flags().StringVar(&organization, "organization", "", "X.509 distinguished name for the Organization")
|
||||||
@@ -213,6 +229,6 @@ func init() {
|
|||||||
csrCmd.Flags().StringVar(&ip, "ip", "", "generate the certificate for this IP address")
|
csrCmd.Flags().StringVar(&ip, "ip", "", "generate the certificate for this IP address")
|
||||||
helpers.Should(cobra.MarkFlagRequired(csrCmd.Flags(), "ip"))
|
helpers.Should(cobra.MarkFlagRequired(csrCmd.Flags(), "ip"))
|
||||||
|
|
||||||
genCmd.AddCommand(caCmd, keypairCmd, keyCmd, csrCmd, crtCmd)
|
genCmd.AddCommand(caCmd, keypairCmd, keyCmd, csrCmd, crtCmd, inittokenCmd)
|
||||||
rootCmd.AddCommand(genCmd)
|
rootCmd.AddCommand(genCmd)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/talos-systems/talos/cmd/osctl/pkg/helpers"
|
"github.com/talos-systems/talos/cmd/osctl/pkg/helpers"
|
||||||
"github.com/talos-systems/talos/pkg/crypto/x509"
|
"github.com/talos-systems/talos/pkg/crypto/x509"
|
||||||
"github.com/talos-systems/talos/pkg/userdata"
|
"github.com/talos-systems/talos/pkg/userdata"
|
||||||
|
"github.com/talos-systems/talos/pkg/userdata/token"
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -61,6 +62,19 @@ var injectKubernetesCmd = &cobra.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// injectTokenCmd represents the inject token command
|
||||||
|
// nolint: dupl
|
||||||
|
var injectTokenCmd = &cobra.Command{
|
||||||
|
Use: "token",
|
||||||
|
Short: "inject token data.",
|
||||||
|
Long: ``,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
if err := inject(args, "", "", injectTokenData); err != nil {
|
||||||
|
helpers.Fatalf("%s", err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// nolint: dupl
|
// nolint: dupl
|
||||||
func injectOSData(u *userdata.UserData, crt, key string) (err error) {
|
func injectOSData(u *userdata.UserData, crt, key string) (err error) {
|
||||||
if u.Security == nil {
|
if u.Security == nil {
|
||||||
@@ -89,6 +103,21 @@ func injectIdentityData(u *userdata.UserData, crt, key string) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nolint: dupl
|
||||||
|
func injectTokenData(u *userdata.UserData, crt, key string) (err error) {
|
||||||
|
if u.Services.Kubeadm == nil {
|
||||||
|
helpers.Fatalf("[services.kubeadm] must be defined in userdata")
|
||||||
|
}
|
||||||
|
|
||||||
|
tok, err := token.NewToken()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
u.Services.Kubeadm.Token = tok
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// nolint: dupl
|
// nolint: dupl
|
||||||
func injectKubernetesData(u *userdata.UserData, crt, key string) (err error) {
|
func injectKubernetesData(u *userdata.UserData, crt, key string) (err error) {
|
||||||
if u.Security == nil {
|
if u.Security == nil {
|
||||||
@@ -142,10 +171,20 @@ func newSecurity() *userdata.Security {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
injectCmd.PersistentFlags().StringVar(&crt, "crt", "", "the path to the PKI certificate")
|
injectOSCmd.Flags().StringVar(&crt, "crt", "", "the path to the PKI certificate")
|
||||||
helpers.Should(injectCmd.MarkPersistentFlagRequired("crt"))
|
injectIdentityCmd.Flags().StringVar(&crt, "crt", "", "the path to the PKI certificate")
|
||||||
injectCmd.PersistentFlags().StringVar(&key, "key", "", "the path to the PKI key")
|
injectKubernetesCmd.Flags().StringVar(&crt, "crt", "", "the path to the PKI certificate")
|
||||||
helpers.Should(injectCmd.MarkPersistentFlagRequired("key"))
|
helpers.Should(injectOSCmd.MarkFlagRequired("crt"))
|
||||||
injectCmd.AddCommand(injectOSCmd, injectIdentityCmd, injectKubernetesCmd)
|
helpers.Should(injectIdentityCmd.MarkFlagRequired("crt"))
|
||||||
|
helpers.Should(injectKubernetesCmd.MarkFlagRequired("crt"))
|
||||||
|
|
||||||
|
injectOSCmd.Flags().StringVar(&key, "key", "", "the path to the PKI key")
|
||||||
|
injectIdentityCmd.Flags().StringVar(&key, "key", "", "the path to the PKI key")
|
||||||
|
injectKubernetesCmd.Flags().StringVar(&key, "key", "", "the path to the PKI key")
|
||||||
|
helpers.Should(injectOSCmd.MarkFlagRequired("key"))
|
||||||
|
helpers.Should(injectIdentityCmd.MarkFlagRequired("key"))
|
||||||
|
helpers.Should(injectKubernetesCmd.MarkFlagRequired("key"))
|
||||||
|
|
||||||
|
injectCmd.AddCommand(injectOSCmd, injectIdentityCmd, injectKubernetesCmd, injectTokenCmd)
|
||||||
rootCmd.AddCommand(injectCmd)
|
rootCmd.AddCommand(injectCmd)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ up: talosconfig
|
|||||||
down:
|
down:
|
||||||
@$(DOCKER_COMPOSE) down -v $(SERVICES)
|
@$(DOCKER_COMPOSE) down -v $(SERVICES)
|
||||||
|
|
||||||
|
.PHONY: talosconfig
|
||||||
talosconfig:
|
talosconfig:
|
||||||
@mkdir -p pki
|
@mkdir -p pki
|
||||||
@./gen.sh $(IP_ADDR)
|
@./gen.sh $(IP_ADDR)
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ ${OSCTL} inject os \
|
|||||||
--key talos.key \
|
--key talos.key \
|
||||||
../userdata/master-1.yaml
|
../userdata/master-1.yaml
|
||||||
|
|
||||||
|
# Inject bootstrap/init token
|
||||||
|
echo "Injecting init token"
|
||||||
|
${OSCTL} inject token ../userdata/master-1.yaml
|
||||||
|
|
||||||
# Inject Kubernetes PKI
|
# Inject Kubernetes PKI
|
||||||
|
|
||||||
|
|||||||
@@ -36,4 +36,7 @@ services:
|
|||||||
trustd:
|
trustd:
|
||||||
username: 'dev'
|
username: 'dev'
|
||||||
password: 'talos_trust_dev'
|
password: 'talos_trust_dev'
|
||||||
|
endpoints:
|
||||||
|
- 10.5.0.7
|
||||||
|
- 10.5.0.8
|
||||||
debug: true
|
debug: true
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ services:
|
|||||||
password: talos_trust_dev
|
password: talos_trust_dev
|
||||||
endpoints:
|
endpoints:
|
||||||
- 10.5.0.6
|
- 10.5.0.6
|
||||||
- 10.5.0.7
|
|
||||||
bootstrapNode: 10.5.0.6
|
bootstrapNode: 10.5.0.6
|
||||||
proxyd: null
|
proxyd: null
|
||||||
osd: null
|
osd: null
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ func Prepare(s string, inContainer bool, data *userdata.UserData) (err error) {
|
|||||||
|
|
||||||
func generatePKI(data *userdata.UserData) (err error) {
|
func generatePKI(data *userdata.UserData) (err error) {
|
||||||
log.Println("generating node identity PKI")
|
log.Println("generating node identity PKI")
|
||||||
if data.IsBootstrap() {
|
if data.Services.Kubeadm.IsBootstrap() {
|
||||||
log.Println("generating PKI locally")
|
log.Println("generating PKI locally")
|
||||||
var csr *x509.CertificateSigningRequest
|
var csr *x509.CertificateSigningRequest
|
||||||
if csr, err = data.NewIdentityCSR(); err != nil {
|
if csr, err = data.NewIdentityCSR(); err != nil {
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ func startSystemServices(startupErrCh chan<- error, data *userdata.UserData) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if !data.IsWorker() {
|
if data.Services.Kubeadm.IsControlPlane() {
|
||||||
masterReqs := []*ctrdrunner.ImportRequest{
|
masterReqs := []*ctrdrunner.ImportRequest{
|
||||||
{
|
{
|
||||||
Path: "/usr/images/proxyd.tar",
|
Path: "/usr/images/proxyd.tar",
|
||||||
@@ -338,7 +338,7 @@ func startSystemServices(startupErrCh chan<- error, data *userdata.UserData) {
|
|||||||
&services.NTPd{},
|
&services.NTPd{},
|
||||||
)
|
)
|
||||||
// Start the services common to all master nodes.
|
// Start the services common to all master nodes.
|
||||||
if data.IsMaster() {
|
if data.Services.Kubeadm.IsControlPlane() {
|
||||||
svcs.Start(
|
svcs.Start(
|
||||||
&services.Trustd{},
|
&services.Trustd{},
|
||||||
&services.Proxyd{},
|
&services.Proxyd{},
|
||||||
@@ -374,7 +374,7 @@ func startKubernetesServices(startupErrCh chan<- error, data *userdata.UserData)
|
|||||||
Path: "/usr/images/pause.tar",
|
Path: "/usr/images/pause.tar",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if !data.IsWorker() {
|
if data.Services.Kubeadm.IsControlPlane() {
|
||||||
reqs = append(reqs, &ctrdrunner.ImportRequest{Path: "/usr/images/etcd.tar"})
|
reqs = append(reqs, &ctrdrunner.ImportRequest{Path: "/usr/images/etcd.tar"})
|
||||||
}
|
}
|
||||||
if err := ctrdrunner.Import(criconstants.K8sContainerdNamespace, reqs...); err != nil {
|
if err := ctrdrunner.Import(criconstants.K8sContainerdNamespace, reqs...); err != nil {
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func (k *Kubeadm) PreFunc(data *userdata.UserData) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if data.IsBootstrap() {
|
if data.Services.Kubeadm.IsBootstrap() {
|
||||||
// Write out all certs we've been provided
|
// Write out all certs we've been provided
|
||||||
certs := []struct {
|
certs := []struct {
|
||||||
Cert *x509.PEMEncodedCertificateAndKey
|
Cert *x509.PEMEncodedCertificateAndKey
|
||||||
@@ -87,7 +87,7 @@ func (k *Kubeadm) PreFunc(data *userdata.UserData) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if data.IsControlPlane() {
|
} else if data.Services.Kubeadm.IsControlPlane() {
|
||||||
if data.Services.Trustd == nil || data.Services.Trustd.BootstrapNode == "" {
|
if data.Services.Trustd == nil || data.Services.Trustd.BootstrapNode == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -156,7 +156,7 @@ func (k *Kubeadm) Runner(data *userdata.UserData) (runner.Runner, error) {
|
|||||||
certificateKey := "--certificate-key=" + encoded
|
certificateKey := "--certificate-key=" + encoded
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case data.IsBootstrap():
|
case data.Services.Kubeadm.IsBootstrap():
|
||||||
args.ProcessArgs = []string{
|
args.ProcessArgs = []string{
|
||||||
"kubeadm",
|
"kubeadm",
|
||||||
"init",
|
"init",
|
||||||
@@ -167,7 +167,7 @@ func (k *Kubeadm) Runner(data *userdata.UserData) (runner.Runner, error) {
|
|||||||
"--skip-certificate-key-print",
|
"--skip-certificate-key-print",
|
||||||
"--experimental-upload-certs",
|
"--experimental-upload-certs",
|
||||||
}
|
}
|
||||||
case data.IsControlPlane():
|
case data.Services.Kubeadm.IsControlPlane():
|
||||||
args.ProcessArgs = []string{
|
args.ProcessArgs = []string{
|
||||||
"kubeadm",
|
"kubeadm",
|
||||||
"join",
|
"join",
|
||||||
@@ -228,7 +228,7 @@ func enforceMasterOverrides(initConfiguration *kubeadmapi.InitConfiguration) {
|
|||||||
|
|
||||||
func writeKubeadmConfig(data *userdata.UserData) (err error) {
|
func writeKubeadmConfig(data *userdata.UserData) (err error) {
|
||||||
var b []byte
|
var b []byte
|
||||||
if data.IsBootstrap() {
|
if data.Services.Kubeadm.IsBootstrap() {
|
||||||
initConfiguration, ok := data.Services.Kubeadm.Configuration.(*kubeadmapi.InitConfiguration)
|
initConfiguration, ok := data.Services.Kubeadm.Configuration.(*kubeadmapi.InitConfiguration)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("expected InitConfiguration")
|
return errors.New("expected InitConfiguration")
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
|
|
||||||
"github.com/talos-systems/talos/internal/pkg/constants"
|
"github.com/talos-systems/talos/internal/pkg/constants"
|
||||||
"github.com/talos-systems/talos/pkg/crypto/x509"
|
"github.com/talos-systems/talos/pkg/crypto/x509"
|
||||||
|
"github.com/talos-systems/talos/pkg/userdata/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CertStrings holds the string representation of a certificate and key.
|
// CertStrings holds the string representation of a certificate and key.
|
||||||
@@ -38,6 +39,7 @@ type Input struct {
|
|||||||
KubernetesVersion string
|
KubernetesVersion string
|
||||||
KubeadmTokens *KubeadmTokens
|
KubeadmTokens *KubeadmTokens
|
||||||
TrustdInfo *TrustdInfo
|
TrustdInfo *TrustdInfo
|
||||||
|
InitToken *token.Token
|
||||||
}
|
}
|
||||||
|
|
||||||
// Certs holds the base64 encoded keys and certificates.
|
// Certs holds the base64 encoded keys and certificates.
|
||||||
@@ -99,6 +101,12 @@ func NewInput(clustername string, masterIPs []string) (input *Input, err error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the init token
|
||||||
|
tok, err := token.NewToken()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// Generate the admin talosconfig.
|
// Generate the admin talosconfig.
|
||||||
adminKey, err := x509.NewKey()
|
adminKey, err := x509.NewKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -167,6 +175,7 @@ func NewInput(clustername string, masterIPs []string) (input *Input, err error)
|
|||||||
KubernetesVersion: constants.KubernetesVersion,
|
KubernetesVersion: constants.KubernetesVersion,
|
||||||
KubeadmTokens: kubeadmTokens,
|
KubeadmTokens: kubeadmTokens,
|
||||||
TrustdInfo: trustdInfo,
|
TrustdInfo: trustdInfo,
|
||||||
|
InitToken: tok,
|
||||||
}
|
}
|
||||||
|
|
||||||
return input, nil
|
return input, nil
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ services:
|
|||||||
init:
|
init:
|
||||||
cni: flannel
|
cni: flannel
|
||||||
kubeadm:
|
kubeadm:
|
||||||
|
initToken: {{ .InitToken }}
|
||||||
certificateKey: '{{ .KubeadmTokens.CertKey }}'
|
certificateKey: '{{ .KubeadmTokens.CertKey }}'
|
||||||
configuration: |
|
configuration: |
|
||||||
apiVersion: kubeadm.k8s.io/v1beta1
|
apiVersion: kubeadm.k8s.io/v1beta1
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package userdata
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
|
"github.com/talos-systems/talos/pkg/userdata/token"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
@@ -23,10 +24,10 @@ type Kubeadm struct {
|
|||||||
Configuration runtime.Object `yaml:"-"`
|
Configuration runtime.Object `yaml:"-"`
|
||||||
ConfigurationStr string `yaml:"configuration"`
|
ConfigurationStr string `yaml:"configuration"`
|
||||||
|
|
||||||
ExtraArgs []string `yaml:"extraArgs,omitempty"`
|
ExtraArgs []string `yaml:"extraArgs,omitempty"`
|
||||||
CertificateKey string `yaml:"certificateKey,omitempty"`
|
CertificateKey string `yaml:"certificateKey,omitempty"`
|
||||||
IgnorePreflightErrors []string `yaml:"ignorePreflightErrors,omitempty"`
|
IgnorePreflightErrors []string `yaml:"ignorePreflightErrors,omitempty"`
|
||||||
bootstrap bool
|
Token *token.Token `yaml:"initToken,omitempty"`
|
||||||
controlPlane bool
|
controlPlane bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,18 +38,6 @@ func (kdm *Kubeadm) MarshalYAML() (interface{}, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
gvks, err := kubeadmutil.GroupVersionKindsFromBytes(b)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if kubeadmutil.GroupVersionKindsHasInitConfiguration(gvks...) {
|
|
||||||
kdm.bootstrap = true
|
|
||||||
}
|
|
||||||
if kubeadmutil.GroupVersionKindsHasJoinConfiguration(gvks...) {
|
|
||||||
kdm.bootstrap = false
|
|
||||||
}
|
|
||||||
|
|
||||||
kdm.ConfigurationStr = string(b)
|
kdm.ConfigurationStr = string(b)
|
||||||
|
|
||||||
type KubeadmAlias Kubeadm
|
type KubeadmAlias Kubeadm
|
||||||
@@ -82,7 +71,7 @@ func (kdm *Kubeadm) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
kdm.Configuration = cfg
|
kdm.Configuration = cfg
|
||||||
kdm.bootstrap = true
|
kdm.controlPlane = true
|
||||||
}
|
}
|
||||||
if kubeadmutil.GroupVersionKindsHasJoinConfiguration(gvks...) {
|
if kubeadmutil.GroupVersionKindsHasJoinConfiguration(gvks...) {
|
||||||
cfg, err := kubeadmutil.UnmarshalFromYamlForCodecs(b, kubeadmapi.SchemeGroupVersion, kubeadmscheme.Codecs)
|
cfg, err := kubeadmutil.UnmarshalFromYamlForCodecs(b, kubeadmapi.SchemeGroupVersion, kubeadmscheme.Codecs)
|
||||||
@@ -90,7 +79,6 @@ func (kdm *Kubeadm) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
kdm.Configuration = cfg
|
kdm.Configuration = cfg
|
||||||
kdm.bootstrap = false
|
|
||||||
joinConfiguration, ok := cfg.(*kubeadm.JoinConfiguration)
|
joinConfiguration, ok := cfg.(*kubeadm.JoinConfiguration)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("expected JoinConfiguration")
|
return errors.New("expected JoinConfiguration")
|
||||||
@@ -107,3 +95,21 @@ func (kdm *Kubeadm) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsControlPlane indicates if the current kubeadm configuration is a worker
|
||||||
|
// acting as a master.
|
||||||
|
func (kdm *Kubeadm) IsControlPlane() bool {
|
||||||
|
return kdm.controlPlane
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsBootstrap indicates if the current kubeadm configuration is a master init
|
||||||
|
// configuration.
|
||||||
|
func (kdm *Kubeadm) IsBootstrap() bool {
|
||||||
|
return kdm.Token != nil && kdm.IsControlPlane() && !kdm.Token.Expired()
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsWorker indicates if the current kubeadm configuration is a worker
|
||||||
|
// configuration.
|
||||||
|
func (kdm *Kubeadm) IsWorker() bool {
|
||||||
|
return !kdm.IsControlPlane()
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ func NewToken() (*Token, error) {
|
|||||||
|
|
||||||
// FromString returns a token parsed from a string.
|
// FromString returns a token parsed from a string.
|
||||||
func FromString(input string) (*Token, error) {
|
func FromString(input string) (*Token, error) {
|
||||||
uuid, err := uuid.FromBytes([]byte(input))
|
uuid, err := uuid.Parse(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -57,3 +57,32 @@ func (t *Token) Expired() bool {
|
|||||||
|
|
||||||
return t2-t1 < BootstrapTTL
|
return t2-t1 < BootstrapTTL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Token) String() string {
|
||||||
|
return t.uuid.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalYAML implements the unmarshaller interface so we can
|
||||||
|
// represent a UUID v1 token as a string.
|
||||||
|
func (t *Token) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||||
|
var stoken string
|
||||||
|
|
||||||
|
if err := unmarshal(&stoken); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err := FromString(stoken)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*t = *token
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalYAML implements the marshaller interface so we can
|
||||||
|
// represent a UUID v1 token as a string.
|
||||||
|
func (t *Token) MarshalYAML() (interface{}, error) {
|
||||||
|
return t.uuid.String(), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -43,20 +43,6 @@ type UserData struct {
|
|||||||
func (data *UserData) Validate() error {
|
func (data *UserData) Validate() error {
|
||||||
var result *multierror.Error
|
var result *multierror.Error
|
||||||
|
|
||||||
var nodeType string
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case data.IsBootstrap():
|
|
||||||
nodeType = "init"
|
|
||||||
case data.IsMaster():
|
|
||||||
nodeType = "master"
|
|
||||||
case data.IsWorker():
|
|
||||||
nodeType = "worker"
|
|
||||||
default:
|
|
||||||
// TODO make an error
|
|
||||||
return result.ErrorOrNil()
|
|
||||||
}
|
|
||||||
|
|
||||||
// All nodeType checks
|
// All nodeType checks
|
||||||
result = multierror.Append(result, data.Services.Validate(CheckServices()))
|
result = multierror.Append(result, data.Services.Validate(CheckServices()))
|
||||||
result = multierror.Append(result, data.Services.Trustd.Validate(CheckTrustdAuth(), CheckTrustdEndpointsAreValidIPs()))
|
result = multierror.Append(result, data.Services.Trustd.Validate(CheckTrustdAuth(), CheckTrustdEndpointsAreValidIPs()))
|
||||||
@@ -69,13 +55,13 @@ func (data *UserData) Validate() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch nodeType {
|
switch {
|
||||||
case "init":
|
case data.Services.Kubeadm.IsBootstrap():
|
||||||
result = multierror.Append(result, data.Security.OS.Validate(CheckOSCA()))
|
result = multierror.Append(result, data.Security.OS.Validate(CheckOSCA()))
|
||||||
result = multierror.Append(result, data.Security.Kubernetes.Validate(CheckKubernetesCA()))
|
result = multierror.Append(result, data.Security.Kubernetes.Validate(CheckKubernetesCA()))
|
||||||
case "master":
|
case data.Services.Kubeadm.IsControlPlane():
|
||||||
result = multierror.Append(result, data.Services.Trustd.Validate(CheckTrustdEndpointsArePresent()))
|
result = multierror.Append(result, data.Services.Trustd.Validate(CheckTrustdEndpointsArePresent()))
|
||||||
case "worker":
|
case data.Services.Kubeadm.IsWorker():
|
||||||
result = multierror.Append(result, data.Services.Trustd.Validate(CheckTrustdEndpointsArePresent()))
|
result = multierror.Append(result, data.Services.Trustd.Validate(CheckTrustdEndpointsArePresent()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,30 +108,6 @@ func (data *UserData) WriteFiles() (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsBootstrap indicates if the current kubeadm configuration is a master init
|
|
||||||
// configuration.
|
|
||||||
func (data *UserData) IsBootstrap() bool {
|
|
||||||
return data.Services.Kubeadm.bootstrap
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsControlPlane indicates if the current kubeadm configuration is a worker
|
|
||||||
// acting as a master.
|
|
||||||
func (data *UserData) IsControlPlane() bool {
|
|
||||||
return data.Services.Kubeadm.controlPlane
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsMaster indicates if the current kubeadm configuration is a master
|
|
||||||
// configuration.
|
|
||||||
func (data *UserData) IsMaster() bool {
|
|
||||||
return data.Services.Kubeadm.bootstrap || data.Services.Kubeadm.controlPlane
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsWorker indicates if the current kubeadm configuration is a worker
|
|
||||||
// configuration.
|
|
||||||
func (data *UserData) IsWorker() bool {
|
|
||||||
return !data.IsMaster()
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewIdentityCSR creates a new CSR for the node's identity certificate.
|
// NewIdentityCSR creates a new CSR for the node's identity certificate.
|
||||||
func (data *UserData) NewIdentityCSR() (csr *x509.CertificateSigningRequest, err error) {
|
func (data *UserData) NewIdentityCSR() (csr *x509.CertificateSigningRequest, err error) {
|
||||||
var key *x509.Key
|
var key *x509.Key
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ func testUDServer() *httptest.Server {
|
|||||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
count++
|
count++
|
||||||
log.Printf("Request %d\n", count)
|
log.Printf("Request %d\n", count)
|
||||||
if count == 4 {
|
if count == 3 {
|
||||||
// nolint: errcheck
|
// nolint: errcheck
|
||||||
w.Write([]byte(testConfig))
|
w.Write([]byte(testConfig))
|
||||||
return
|
return
|
||||||
@@ -97,6 +97,7 @@ services:
|
|||||||
init:
|
init:
|
||||||
cni: flannel
|
cni: flannel
|
||||||
kubeadm:
|
kubeadm:
|
||||||
|
initToken: 528d1ad6-3485-49ad-94cd-0f44a35877ac
|
||||||
certificateKey: 'test'
|
certificateKey: 'test'
|
||||||
configuration: |
|
configuration: |
|
||||||
apiVersion: kubeadm.k8s.io/v1beta1
|
apiVersion: kubeadm.k8s.io/v1beta1
|
||||||
@@ -225,4 +226,5 @@ const kubeadmConfig = `configuration: |
|
|||||||
networkName: ""
|
networkName: ""
|
||||||
sourceVip: ""
|
sourceVip: ""
|
||||||
certificateKey: test
|
certificateKey: test
|
||||||
|
initToken: 528d1ad6-3485-49ad-94cd-0f44a35877ac
|
||||||
`
|
`
|
||||||
|
|||||||
Reference in New Issue
Block a user