mirror of
https://github.com/siderolabs/talos.git
synced 2025-08-21 06:31:11 +02:00
This is a rename of the osctl binary. We decided that talosctl is a better name for the Talos CLI. This does not break any APIs, but does make older documentation only accurate for previous versions of Talos. Signed-off-by: Andrew Rynhard <andrew@andrewrynhard.com>
142 lines
2.9 KiB
Go
142 lines
2.9 KiB
Go
// 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 access
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"k8s.io/client-go/kubernetes"
|
|
"k8s.io/client-go/tools/clientcmd"
|
|
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
|
|
|
"github.com/talos-systems/talos/cmd/talosctl/pkg/client"
|
|
"github.com/talos-systems/talos/internal/pkg/provision"
|
|
"github.com/talos-systems/talos/pkg/constants"
|
|
"github.com/talos-systems/talos/pkg/grpc/tls"
|
|
)
|
|
|
|
// NewAdapter returns ClusterAccess object from Cluster.
|
|
func NewAdapter(cluster provision.Cluster, opts ...provision.Option) provision.ClusterAccess {
|
|
options := provision.DefaultOptions()
|
|
|
|
for _, opt := range opts {
|
|
if err := opt(&options); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
adapter := &adapter{
|
|
Cluster: cluster,
|
|
clients: make(map[string]*client.Client),
|
|
options: &options,
|
|
}
|
|
|
|
if options.TalosClient != nil {
|
|
// inject default client if provided
|
|
adapter.clients[""] = options.TalosClient
|
|
}
|
|
|
|
return adapter
|
|
}
|
|
|
|
type adapter struct {
|
|
provision.Cluster
|
|
|
|
clients map[string]*client.Client
|
|
clientset *kubernetes.Clientset
|
|
options *provision.Options
|
|
}
|
|
|
|
func (a *adapter) Client(endpoints ...string) (*client.Client, error) {
|
|
key := strings.Join(endpoints, ",")
|
|
|
|
if cli := a.clients[key]; cli != nil {
|
|
return cli, nil
|
|
}
|
|
|
|
configContext, creds, err := client.NewClientContextAndCredentialsFromParsedConfig(a.options.TalosConfig, "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(endpoints) == 0 {
|
|
endpoints = configContext.Endpoints
|
|
}
|
|
|
|
tlsconfig, err := tls.New(
|
|
tls.WithKeypair(creds.Crt),
|
|
tls.WithClientAuthType(tls.Mutual),
|
|
tls.WithCACertPEM(creds.CA),
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
client, err := client.NewClient(tlsconfig, endpoints, constants.ApidPort)
|
|
if err == nil {
|
|
a.clients[key] = client
|
|
}
|
|
|
|
return client, err
|
|
}
|
|
|
|
func (a *adapter) K8sClient(ctx context.Context) (*kubernetes.Clientset, error) {
|
|
if a.clientset != nil {
|
|
return a.clientset, nil
|
|
}
|
|
|
|
client, err := a.Client()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
kubeconfig, err := client.Kubeconfig(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
config, err := clientcmd.BuildConfigFromKubeconfigGetter("", func() (*clientcmdapi.Config, error) {
|
|
return clientcmd.Load(kubeconfig)
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// patch timeout
|
|
config.Timeout = time.Minute
|
|
|
|
if a.options.ForceEndpoint != "" {
|
|
config.Host = fmt.Sprintf("%s:%d", a.options.ForceEndpoint, 6443)
|
|
}
|
|
|
|
clientset, err := kubernetes.NewForConfig(config)
|
|
if err == nil {
|
|
a.clientset = clientset
|
|
}
|
|
|
|
return clientset, err
|
|
}
|
|
|
|
func (a *adapter) Close() error {
|
|
for _, cli := range a.clients {
|
|
if cli == a.options.TalosClient {
|
|
// this client was provided, don't close it
|
|
continue
|
|
}
|
|
|
|
if err := cli.Close(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
a.clients = nil
|
|
a.clientset = nil
|
|
|
|
return nil
|
|
}
|