Mount kubeconfig to GenericContainer executor
Change-Id: Ide647fc0cfd9d281d57eeeaf8b3f9c33f59e7fdf
This commit is contained in:
parent
e2af947337
commit
63e6012133
@ -27,6 +27,14 @@ const (
|
||||
GenericContainerTypeAirship GenericContainerType = "airship"
|
||||
// GenericContainerTypeKrm specifies that kustomize krm function will be used
|
||||
GenericContainerTypeKrm GenericContainerType = "krm"
|
||||
// KubeConfigEnvKey uses as a key for kubeconfig env variable
|
||||
KubeConfigEnvKey = "KUBECONFIG"
|
||||
// KubeConfigPath is a path for mounted kubeconfig inside container
|
||||
KubeConfigPath = "/kubeconfig"
|
||||
// KubeConfigEnvKeyContext uses as a key for kubectl context env variable
|
||||
KubeConfigEnvKeyContext = "KCTL_CONTEXT"
|
||||
// KubeConfigEnv uses as a kubeconfig env variable
|
||||
KubeConfigEnv = KubeConfigEnvKey + "=" + KubeConfigPath
|
||||
)
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
9
pkg/container/testdata/single/cluster-map.yaml
vendored
Normal file
9
pkg/container/testdata/single/cluster-map.yaml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: ClusterMap
|
||||
metadata:
|
||||
labels:
|
||||
airshipit.org/deploy-k8s: "false"
|
||||
name: main-map
|
||||
map:
|
||||
testCluster: {}
|
@ -1,2 +1,3 @@
|
||||
resources:
|
||||
- secret.yaml
|
||||
- cluster-map.yaml
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
"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"
|
||||
)
|
||||
@ -40,6 +41,7 @@ type ContainerExecutor struct {
|
||||
ExecutorBundle document.Bundle
|
||||
ExecutorDocument document.Document
|
||||
Helper ifc.Helper
|
||||
Options ifc.ExecutorConfig
|
||||
}
|
||||
|
||||
// NewContainerExecutor creates instance of phase executor
|
||||
@ -70,6 +72,7 @@ func NewContainerExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) {
|
||||
ClientFunc: container.NewClientV1Alpha1,
|
||||
Helper: cfg.Helper,
|
||||
Container: apiObj,
|
||||
Options: cfg,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -82,6 +85,14 @@ func (c *ContainerExecutor) Run(evtCh chan events.Event, opts ifc.RunOptions) {
|
||||
Message: "starting generic container",
|
||||
})
|
||||
|
||||
if c.Options.ClusterName != "" {
|
||||
cleanup, err := c.SetKubeConfig()
|
||||
if err != nil {
|
||||
handleError(evtCh, err)
|
||||
}
|
||||
defer cleanup()
|
||||
}
|
||||
|
||||
input, err := bundleReader(c.ExecutorBundle)
|
||||
if err != nil {
|
||||
// TODO move bundleFactory here, and make sure that if executorDoc is not defined, we dont fail
|
||||
@ -121,6 +132,31 @@ func (c *ContainerExecutor) Run(evtCh chan events.Event, opts ifc.RunOptions) {
|
||||
})
|
||||
}
|
||||
|
||||
// SetKubeConfig adds env variable and mounts kubeconfig to container
|
||||
func (c *ContainerExecutor) SetKubeConfig() (kubeconfig.Cleanup, error) {
|
||||
clusterMap, err := c.Helper.ClusterMap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
context, err := clusterMap.ClusterKubeconfigContext(c.Options.ClusterName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kubeConfigSrc, cleanup, err := c.Options.KubeConfig.GetFile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.Container.Spec.StorageMounts = append(c.Container.Spec.StorageMounts, v1alpha1.StorageMount{
|
||||
MountType: "bind",
|
||||
Src: kubeConfigSrc,
|
||||
DstPath: v1alpha1.KubeConfigPath,
|
||||
})
|
||||
envs := []string{v1alpha1.KubeConfigEnv, v1alpha1.KubeConfigEnvKeyContext + "=" + context}
|
||||
c.Container.Spec.EnvVars = append(c.Container.Spec.EnvVars, envs...)
|
||||
|
||||
return cleanup, nil
|
||||
}
|
||||
|
||||
// bundleReader sets input for function
|
||||
func bundleReader(bundle document.Bundle) (io.Reader, error) {
|
||||
buf := &bytes.Buffer{}
|
||||
|
@ -14,6 +14,7 @@ package executors_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -24,6 +25,7 @@ import (
|
||||
"opendev.org/airship/airshipctl/pkg/container"
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
"opendev.org/airship/airshipctl/pkg/events"
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/kubeconfig"
|
||||
"opendev.org/airship/airshipctl/pkg/phase/executors"
|
||||
"opendev.org/airship/airshipctl/pkg/phase/ifc"
|
||||
)
|
||||
@ -174,6 +176,14 @@ type: Opaque
|
||||
Container: tt.containerAPI,
|
||||
ClientFunc: tt.clientFunc,
|
||||
Helper: makeDefaultHelper(t, tt.targetPath, "../metadata.yaml"),
|
||||
Options: ifc.ExecutorConfig{
|
||||
ClusterName: "testCluster",
|
||||
KubeConfig: fakeKubeConfig{
|
||||
getFile: func() (string, kubeconfig.Cleanup, error) {
|
||||
return "testPath", func() {}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ch := make(chan events.Event)
|
||||
@ -199,3 +209,60 @@ type: Opaque
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetKubeConfig(t *testing.T) {
|
||||
getFileErr := fmt.Errorf("failed to get file")
|
||||
testCases := []struct {
|
||||
name string
|
||||
opts ifc.ExecutorConfig
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "Set valid kubeconfig",
|
||||
opts: ifc.ExecutorConfig{
|
||||
ClusterName: "testCluster",
|
||||
KubeConfig: fakeKubeConfig{
|
||||
getFile: func() (string, kubeconfig.Cleanup, error) {
|
||||
return "testPath", func() {}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Failed to get kubeconfig file",
|
||||
opts: ifc.ExecutorConfig{
|
||||
ClusterName: "testCluster",
|
||||
KubeConfig: fakeKubeConfig{
|
||||
getFile: func() (string, kubeconfig.Cleanup, error) {
|
||||
return "", func() {}, getFileErr
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedErr: getFileErr,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tt := tc
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
e := executors.ContainerExecutor{
|
||||
Options: tt.opts,
|
||||
Container: &v1alpha1.GenericContainer{},
|
||||
Helper: makeDefaultHelper(t, singleExecutorBundlePath, "../metadata.yaml"),
|
||||
}
|
||||
_, err := e.SetKubeConfig()
|
||||
assert.Equal(t, tt.expectedErr, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type fakeKubeConfig struct {
|
||||
getFile func() (string, kubeconfig.Cleanup, error)
|
||||
}
|
||||
|
||||
func (k fakeKubeConfig) GetFile() (string, kubeconfig.Cleanup, error) { return k.getFile() }
|
||||
func (k fakeKubeConfig) Write(_ io.Writer) error { return nil }
|
||||
func (k fakeKubeConfig) WriteFile(path string) error { return nil }
|
||||
func (k fakeKubeConfig) WriteTempFile(dumpRoot string) (string, kubeconfig.Cleanup, error) {
|
||||
return k.getFile()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user