Spencer Smith 75d9f7b454 feat: support configurable docker-based clusters
This PR will allow users to issue `osctl config generate`, tweak the
configs to their liking, then use those configs to call `osctl cluster
create`.

Example workflow:

```
osctl config generate my-cluster https://10.5.0.2:6443 -o ./my-cluster

** tweaky tweak **

osctl cluster create --name my-cluster --input-dir "$PWD/my-cluster"
```

Signed-off-by: Spencer Smith <robertspencersmith@gmail.com>
2020-01-08 14:11:56 -05:00

120 lines
2.5 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/osctl/pkg/client"
"github.com/talos-systems/talos/internal/pkg/provision"
"github.com/talos-systems/talos/pkg/constants"
)
// 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)
}
}
return &adapter{
Cluster: cluster,
clients: make(map[string]*client.Client),
options: &options,
}
}
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
}
client, err := client.NewClient(creds, 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 err := cli.Close(); err != nil {
return err
}
}
a.clients = nil
a.clientset = nil
return nil
}