Kostiantyn Kalynovskyi 1f932861d4 Add kubeconfig builder
Kubeconfig builder will be a single source of kubeconfig, allowing
to make a decision how to build kubeconfig based on different
parameters, such as path to kubeconfig, dynamic kubeconfig
options, or kubeconfig based on document bundle.

Change-Id: Ia63e11a6f0b327e283d3e7fce169a35d54684dfb
2020-09-02 17:18:19 -05:00

150 lines
3.9 KiB
Go

/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package client
import (
"io"
"path/filepath"
"k8s.io/apimachinery/pkg/runtime/schema"
airshipv1 "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
"opendev.org/airship/airshipctl/pkg/document"
"opendev.org/airship/airshipctl/pkg/errors"
"opendev.org/airship/airshipctl/pkg/events"
"opendev.org/airship/airshipctl/pkg/k8s/kubeconfig"
"opendev.org/airship/airshipctl/pkg/log"
"opendev.org/airship/airshipctl/pkg/phase/ifc"
)
var _ ifc.Executor = &ClusterctlExecutor{}
// ClusterctlExecutor phase executor
type ClusterctlExecutor struct {
clusterName string
dumpRoot string
Interface
bundle document.Bundle
options *airshipv1.Clusterctl
kubecfg kubeconfig.Interface
}
// RegisterExecutor adds executor to phase executor registry
func RegisterExecutor(registry map[schema.GroupVersionKind]ifc.ExecutorFactory) error {
obj := &airshipv1.Clusterctl{}
gvks, _, err := airshipv1.Scheme.ObjectKinds(obj)
if err != nil {
return err
}
registry[gvks[0]] = NewExecutor
return nil
}
// NewExecutor creates instance of 'clusterctl init' phase executor
func NewExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) {
options := &airshipv1.Clusterctl{}
if err := cfg.ExecutorDocument.ToAPIObject(options, airshipv1.Scheme); err != nil {
return nil, err
}
tgtPath, err := cfg.AirshipSettings.Config.CurrentContextTargetPath()
if err != nil {
return nil, err
}
client, err := NewClient(tgtPath, log.DebugEnabled(), options)
if err != nil {
return nil, err
}
return &ClusterctlExecutor{
clusterName: cfg.ClusterName,
Interface: client,
bundle: cfg.ExecutorBundle,
options: options,
kubecfg: cfg.KubeConfig,
dumpRoot: filepath.Dir(cfg.AirshipSettings.AirshipConfigPath),
}, nil
}
// Run clusterctl init as a phase runner
func (c *ClusterctlExecutor) Run(evtCh chan events.Event, opts ifc.RunOptions) {
defer close(evtCh)
switch c.options.Action {
case airshipv1.Move:
c.move(opts, evtCh)
case airshipv1.Init:
c.init(opts, evtCh)
default:
c.handleErr(ErrUnknownExecutorAction{Action: string(c.options.Action)}, evtCh)
}
}
func (c *ClusterctlExecutor) move(_ ifc.RunOptions, evtCh chan events.Event) {
c.handleErr(errors.ErrNotImplemented{}, evtCh)
}
func (c *ClusterctlExecutor) init(opts ifc.RunOptions, evtCh chan events.Event) {
evtCh <- events.Event{
ClusterctlEvent: events.ClusterctlEvent{
Operation: events.ClusterctlInitStart,
},
}
kubeConfigFile, cleanup, err := c.kubecfg.WriteTempFile(c.dumpRoot)
if err != nil {
c.handleErr(err, evtCh)
return
}
defer cleanup()
if opts.DryRun {
// TODO (dukov) add more details to dry-run
log.Print("command 'clusterctl init' is going to be executed")
evtCh <- events.Event{
ClusterctlEvent: events.ClusterctlEvent{
Operation: events.ClusterctlInitEnd,
},
}
return
}
err = c.Init(kubeConfigFile, "")
if err != nil {
c.handleErr(err, evtCh)
}
evtCh <- events.Event{
ClusterctlEvent: events.ClusterctlEvent{
Operation: events.ClusterctlInitEnd,
},
}
}
func (c *ClusterctlExecutor) handleErr(err error, evtCh chan events.Event) {
evtCh <- events.Event{
Type: events.ErrorType,
ErrorEvent: events.ErrorEvent{
Error: err,
},
}
}
// Validate executor configuration and documents
func (c *ClusterctlExecutor) Validate() error {
return errors.ErrNotImplemented{}
}
// Render executor documents
func (c *ClusterctlExecutor) Render(_ io.Writer, _ ifc.RenderOptions) error {
return errors.ErrNotImplemented{}
}