[AIR-145] Generate cloud init settings
Settins are generated based on a secret data Change-Id: Ib4c25e720759694432e03796ae5d1b4f2f2a1a1b
This commit is contained in:
parent
915c47506b
commit
6b82a529fc
78
pkg/bootstrap/cloudinit/cloud-init.go
Normal file
78
pkg/bootstrap/cloudinit/cloud-init.go
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package cloudinit
|
||||||
|
|
||||||
|
import (
|
||||||
|
b64 "encoding/base64"
|
||||||
|
|
||||||
|
"opendev.org/airship/airshipctl/pkg/document"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// TODO (dukov) This should depend on cluster api version once it is
|
||||||
|
// fully available for Metal3. In other words:
|
||||||
|
// - Sectet for v1alpha1
|
||||||
|
// - KubeAdmConfig for v1alpha2
|
||||||
|
EphemeralClusterConfKind = "Secret"
|
||||||
|
)
|
||||||
|
|
||||||
|
func decodeData(cfg document.Document, key string) ([]byte, error) {
|
||||||
|
data, err := cfg.GetStringMap("data")
|
||||||
|
if err != nil {
|
||||||
|
return nil, ErrDataNotSupplied{DocName: cfg.GetName(), Key: key}
|
||||||
|
}
|
||||||
|
|
||||||
|
res, ok := data[key]
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrDataNotSupplied{DocName: cfg.GetName(), Key: key}
|
||||||
|
}
|
||||||
|
|
||||||
|
return b64.StdEncoding.DecodeString(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getDataFromSecret extracts data from Secret with respect to overrides
|
||||||
|
func getDataFromSecret(cfg document.Document, key string) ([]byte, error) {
|
||||||
|
data, err := cfg.GetStringMap("stringData")
|
||||||
|
if err != nil {
|
||||||
|
return decodeData(cfg, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, ok := data[key]
|
||||||
|
if !ok {
|
||||||
|
return decodeData(cfg, key)
|
||||||
|
}
|
||||||
|
return []byte(res), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCloudData reads YAML document input and generates cloud-init data for
|
||||||
|
// node (i.e. Cluster API Machine) with bootstrap annotation.
|
||||||
|
func GetCloudData(docBundle document.Bundle, bsAnnotation string) ([]byte, []byte, error) {
|
||||||
|
var userData []byte
|
||||||
|
var netConf []byte
|
||||||
|
docs, err := docBundle.GetByAnnotation(bsAnnotation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
var ephemeralCfg document.Document
|
||||||
|
for _, doc := range docs {
|
||||||
|
if doc.GetKind() == EphemeralClusterConfKind {
|
||||||
|
ephemeralCfg = doc
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ephemeralCfg == nil {
|
||||||
|
return nil, nil, document.ErrDocNotFound{
|
||||||
|
Annotation: bsAnnotation,
|
||||||
|
Kind: EphemeralClusterConfKind,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
netConf, err = getDataFromSecret(ephemeralCfg, "netconfig")
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
userData, err = getDataFromSecret(ephemeralCfg, "userdata")
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return userData, netConf, nil
|
||||||
|
}
|
67
pkg/bootstrap/cloudinit/cloud-init_test.go
Normal file
67
pkg/bootstrap/cloudinit/cloud-init_test.go
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package cloudinit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"opendev.org/airship/airshipctl/pkg/document"
|
||||||
|
"opendev.org/airship/airshipctl/testutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetCloudData(t *testing.T) {
|
||||||
|
|
||||||
|
fSys := testutil.SetupTestFs(t, "testdata")
|
||||||
|
bundle, err := document.NewBundle(fSys, "/", "/")
|
||||||
|
require.NoError(t, err, "Building Bundle Failed")
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
ann string
|
||||||
|
expectedUserData []byte
|
||||||
|
expectedNetData []byte
|
||||||
|
expectedErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
ann: "test=test",
|
||||||
|
expectedUserData: nil,
|
||||||
|
expectedNetData: nil,
|
||||||
|
expectedErr: document.ErrDocNotFound{
|
||||||
|
Annotation: "test=test",
|
||||||
|
Kind: "Secret",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ann: "airshipit.org/clustertype=nodata",
|
||||||
|
expectedUserData: nil,
|
||||||
|
expectedNetData: nil,
|
||||||
|
expectedErr: ErrDataNotSupplied{
|
||||||
|
DocName: "node1-bmc-secret1",
|
||||||
|
Key: "netconfig",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ann: "test=nodataforcfg",
|
||||||
|
expectedUserData: nil,
|
||||||
|
expectedNetData: nil,
|
||||||
|
expectedErr: ErrDataNotSupplied{
|
||||||
|
DocName: "node1-bmc-secret2",
|
||||||
|
Key: "netconfig",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ann: "airshipit.org/clustertype=ephemeral",
|
||||||
|
expectedUserData: []byte("cloud-init"),
|
||||||
|
expectedNetData: []byte("netconfig\n"),
|
||||||
|
expectedErr: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
actualUserData, actualNetData, actualErr := GetCloudData(bundle, tt.ann)
|
||||||
|
|
||||||
|
assert.Equal(t, tt.expectedUserData, actualUserData)
|
||||||
|
assert.Equal(t, tt.expectedNetData, actualNetData)
|
||||||
|
assert.Equal(t, tt.expectedErr, actualErr)
|
||||||
|
}
|
||||||
|
}
|
16
pkg/bootstrap/cloudinit/errors.go
Normal file
16
pkg/bootstrap/cloudinit/errors.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package cloudinit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrDataNotSupplied error returned of no user-data or network configuration
|
||||||
|
// in the Secret
|
||||||
|
type ErrDataNotSupplied struct {
|
||||||
|
DocName string
|
||||||
|
Key string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrDataNotSupplied) Error() string {
|
||||||
|
return fmt.Sprintf("Document %s has no key %s", e.DocName, e.Key)
|
||||||
|
}
|
2
pkg/bootstrap/cloudinit/testdata/kustomization.yaml
vendored
Normal file
2
pkg/bootstrap/cloudinit/testdata/kustomization.yaml
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
resources:
|
||||||
|
- secret.yaml
|
29
pkg/bootstrap/cloudinit/testdata/secret.yaml
vendored
Normal file
29
pkg/bootstrap/cloudinit/testdata/secret.yaml
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
airshipit.org/clustertype: ephemeral
|
||||||
|
name: node1-bmc-secret
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
netconfig: bmV0Y29uZmlnCg==
|
||||||
|
stringData:
|
||||||
|
userdata: cloud-init
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
airshipit.org/clustertype: nodata
|
||||||
|
name: node1-bmc-secret1
|
||||||
|
type: Opaque
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
test: nodataforcfg
|
||||||
|
name: node1-bmc-secret2
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
foo: bmV0Y29uZmlnCg==
|
@ -4,10 +4,20 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"opendev.org/airship/airshipctl/pkg/bootstrap/cloudinit"
|
||||||
"opendev.org/airship/airshipctl/pkg/container"
|
"opendev.org/airship/airshipctl/pkg/container"
|
||||||
|
"opendev.org/airship/airshipctl/pkg/document"
|
||||||
"opendev.org/airship/airshipctl/pkg/errors"
|
"opendev.org/airship/airshipctl/pkg/errors"
|
||||||
"opendev.org/airship/airshipctl/pkg/util"
|
"opendev.org/airship/airshipctl/pkg/util"
|
||||||
|
|
||||||
|
"sigs.k8s.io/kustomize/v3/pkg/fs"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
builderConfigFileName = "builder-conf.yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GenerateBootstrapIso will generate data for cloud init and start ISO builder container
|
// GenerateBootstrapIso will generate data for cloud init and start ISO builder container
|
||||||
@ -24,6 +34,15 @@ func GenerateBootstrapIso(settings *Settings, args []string, out io.Writer) erro
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := verifyInputs(cfg, args, out); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
docBundle, err := document.NewBundle(fs.MakeRealFS(), args[0], "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Fprintln(out, "Creating ISO builder container")
|
fmt.Fprintln(out, "Creating ISO builder container")
|
||||||
builder, err := container.NewContainer(
|
builder, err := container.NewContainer(
|
||||||
&ctx, cfg.Container.ContainerRuntime,
|
&ctx, cfg.Container.ContainerRuntime,
|
||||||
@ -32,17 +51,78 @@ func GenerateBootstrapIso(settings *Settings, args []string, out io.Writer) erro
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return generateBootstrapIso(builder, cfg, out, settings.Debug)
|
return generateBootstrapIso(docBundle, builder, cfg, out, settings.Debug)
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateBootstrapIso(builder container.Container, cfg *Config, out io.Writer, debug bool) error {
|
func verifyInputs(cfg *Config, args []string, out io.Writer) error {
|
||||||
|
if len(args) == 0 {
|
||||||
|
fmt.Fprintln(out, "Specify path to document model. Config param from global settings is not supported")
|
||||||
|
return errors.ErrNotImplemented{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.Container.Volume == "" {
|
||||||
|
fmt.Fprintln(out, "Specify volume bind for ISO builder container")
|
||||||
|
return errors.ErrWrongConfig{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg.Builder.UserDataFileName == "") || (cfg.Builder.NetworkConfigFileName == "") {
|
||||||
|
fmt.Fprintln(out, "UserDataFileName or NetworkConfigFileName are not specified in ISO builder config")
|
||||||
|
return errors.ErrWrongConfig{}
|
||||||
|
}
|
||||||
|
|
||||||
|
vols := strings.Split(cfg.Container.Volume, ":")
|
||||||
|
switch {
|
||||||
|
case len(vols) == 1:
|
||||||
|
cfg.Container.Volume = fmt.Sprintf("%s:%s", vols[0], vols[0])
|
||||||
|
case len(vols) > 2:
|
||||||
|
fmt.Fprintln(out, "Bad container volume format. Use hostPath:contPath")
|
||||||
|
return errors.ErrWrongConfig{}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getContainerCfg(cfg *Config, userData []byte, netConf []byte) (map[string][]byte, error) {
|
||||||
|
hostVol := strings.Split(cfg.Container.Volume, ":")[0]
|
||||||
|
|
||||||
|
fls := make(map[string][]byte)
|
||||||
|
fls[filepath.Join(hostVol, cfg.Builder.UserDataFileName)] = userData
|
||||||
|
fls[filepath.Join(hostVol, cfg.Builder.NetworkConfigFileName)] = netConf
|
||||||
|
builderData, err := cfg.ToYAML()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fls[filepath.Join(hostVol, builderConfigFileName)] = builderData
|
||||||
|
return fls, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateBootstrapIso(
|
||||||
|
docBubdle document.Bundle,
|
||||||
|
builder container.Container,
|
||||||
|
cfg *Config,
|
||||||
|
out io.Writer,
|
||||||
|
debug bool,
|
||||||
|
) error {
|
||||||
|
cntVol := strings.Split(cfg.Container.Volume, ":")[1]
|
||||||
|
fmt.Fprintln(out, "Creating cloud-init for ephemeral K8s")
|
||||||
|
userData, netConf, err := cloudinit.GetCloudData(docBubdle, EphemeralClusterAnnotation)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var fls map[string][]byte
|
||||||
|
fls, err = getContainerCfg(cfg, userData, netConf)
|
||||||
|
if err = util.WriteFiles(fls, 0600); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
vols := []string{cfg.Container.Volume}
|
vols := []string{cfg.Container.Volume}
|
||||||
|
builderCfgLocation := filepath.Join(cntVol, builderConfigFileName)
|
||||||
fmt.Fprintf(out, "Running default container command. Mounted dir: %s\n", vols)
|
fmt.Fprintf(out, "Running default container command. Mounted dir: %s\n", vols)
|
||||||
if err := builder.RunCommand(
|
if err := builder.RunCommand(
|
||||||
[]string{},
|
[]string{},
|
||||||
nil,
|
nil,
|
||||||
vols,
|
vols,
|
||||||
[]string{},
|
[]string{fmt.Sprintf("BUILDER_CONFIG=%s", builderCfgLocation)},
|
||||||
debug,
|
debug,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -7,6 +7,11 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"opendev.org/airship/airshipctl/pkg/document"
|
||||||
|
"opendev.org/airship/airshipctl/pkg/errors"
|
||||||
|
"opendev.org/airship/airshipctl/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mockContainer struct {
|
type mockContainer struct {
|
||||||
@ -38,9 +43,25 @@ func (mc *mockContainer) GetId() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBootstrapIso(t *testing.T) {
|
func TestBootstrapIso(t *testing.T) {
|
||||||
|
fSys := testutil.SetupTestFs(t, "testdata")
|
||||||
|
bundle, err := document.NewBundle(fSys, "/", "/")
|
||||||
|
require.NoError(t, err, "Building Bundle Failed")
|
||||||
|
|
||||||
|
volBind := "/tmp:/dst"
|
||||||
testErr := fmt.Errorf("TestErr")
|
testErr := fmt.Errorf("TestErr")
|
||||||
|
testCfg := &Config{
|
||||||
|
Container: Container{
|
||||||
|
Volume: volBind,
|
||||||
|
ContainerRuntime: "docker",
|
||||||
|
},
|
||||||
|
Builder: Builder{
|
||||||
|
UserDataFileName: "user-data",
|
||||||
|
NetworkConfigFileName: "net-conf",
|
||||||
|
},
|
||||||
|
}
|
||||||
expOut := []string{
|
expOut := []string{
|
||||||
"Running default container command. Mounted dir: []\n",
|
"Creating cloud-init for ephemeral K8s\n",
|
||||||
|
fmt.Sprintf("Running default container command. Mounted dir: [%s]\n", volBind),
|
||||||
"ISO successfully built.\n",
|
"ISO successfully built.\n",
|
||||||
"Debug flag is set. Container TESTID stopped but not deleted.\n",
|
"Debug flag is set. Container TESTID stopped but not deleted.\n",
|
||||||
"Removing container.\n",
|
"Removing container.\n",
|
||||||
@ -57,9 +78,9 @@ func TestBootstrapIso(t *testing.T) {
|
|||||||
builder: &mockContainer{
|
builder: &mockContainer{
|
||||||
runCommand: func() error { return testErr },
|
runCommand: func() error { return testErr },
|
||||||
},
|
},
|
||||||
cfg: &Config{},
|
cfg: testCfg,
|
||||||
debug: false,
|
debug: false,
|
||||||
expectedOut: expOut[0],
|
expectedOut: expOut[0] + expOut[1],
|
||||||
expectdErr: testErr,
|
expectdErr: testErr,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -67,9 +88,9 @@ func TestBootstrapIso(t *testing.T) {
|
|||||||
runCommand: func() error { return nil },
|
runCommand: func() error { return nil },
|
||||||
getId: func() string { return "TESTID" },
|
getId: func() string { return "TESTID" },
|
||||||
},
|
},
|
||||||
cfg: &Config{},
|
cfg: testCfg,
|
||||||
debug: true,
|
debug: true,
|
||||||
expectedOut: expOut[0] + expOut[1] + expOut[2],
|
expectedOut: expOut[0] + expOut[1] + expOut[2] + expOut[3],
|
||||||
expectdErr: nil,
|
expectdErr: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -78,16 +99,16 @@ func TestBootstrapIso(t *testing.T) {
|
|||||||
getId: func() string { return "TESTID" },
|
getId: func() string { return "TESTID" },
|
||||||
rmContainer: func() error { return testErr },
|
rmContainer: func() error { return testErr },
|
||||||
},
|
},
|
||||||
cfg: &Config{},
|
cfg: testCfg,
|
||||||
debug: false,
|
debug: false,
|
||||||
expectedOut: expOut[0] + expOut[1] + expOut[3],
|
expectedOut: expOut[0] + expOut[1] + expOut[2] + expOut[4],
|
||||||
expectdErr: testErr,
|
expectdErr: testErr,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
actualOut := bytes.NewBufferString("")
|
actualOut := bytes.NewBufferString("")
|
||||||
actualErr := generateBootstrapIso(tt.builder, tt.cfg, actualOut, tt.debug)
|
actualErr := generateBootstrapIso(bundle, tt.builder, tt.cfg, actualOut, tt.debug)
|
||||||
|
|
||||||
errS := fmt.Sprintf("generateBootstrapIso should have return error %s, got %s", tt.expectdErr, actualErr)
|
errS := fmt.Sprintf("generateBootstrapIso should have return error %s, got %s", tt.expectdErr, actualErr)
|
||||||
assert.Equal(t, actualErr, tt.expectdErr, errS)
|
assert.Equal(t, actualErr, tt.expectdErr, errS)
|
||||||
@ -96,3 +117,63 @@ func TestBootstrapIso(t *testing.T) {
|
|||||||
assert.Equal(t, actualOut.String(), tt.expectedOut, errS)
|
assert.Equal(t, actualOut.String(), tt.expectedOut, errS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestVerifyInputs(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
cfg *Config
|
||||||
|
args []string
|
||||||
|
expectedErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
cfg: &Config{},
|
||||||
|
args: []string{},
|
||||||
|
expectedErr: errors.ErrNotImplemented{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
cfg: &Config{},
|
||||||
|
args: []string{"."},
|
||||||
|
expectedErr: errors.ErrWrongConfig{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
cfg: &Config{
|
||||||
|
Container: Container{
|
||||||
|
Volume: "/tmp:/dst",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
args: []string{"."},
|
||||||
|
expectedErr: errors.ErrWrongConfig{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
cfg: &Config{
|
||||||
|
Container: Container{
|
||||||
|
Volume: "/tmp",
|
||||||
|
},
|
||||||
|
Builder: Builder{
|
||||||
|
UserDataFileName: "user-data",
|
||||||
|
NetworkConfigFileName: "net-conf",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
args: []string{"."},
|
||||||
|
expectedErr: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
cfg: &Config{
|
||||||
|
Container: Container{
|
||||||
|
Volume: "/tmp:/dst:/dst1",
|
||||||
|
},
|
||||||
|
Builder: Builder{
|
||||||
|
UserDataFileName: "user-data",
|
||||||
|
NetworkConfigFileName: "net-conf",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
args: []string{"."},
|
||||||
|
expectedErr: errors.ErrWrongConfig{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
actualErr := verifyInputs(tt.cfg, tt.args, bytes.NewBufferString(""))
|
||||||
|
assert.Equal(t, tt.expectedErr, actualErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -8,6 +8,11 @@ import (
|
|||||||
"opendev.org/airship/airshipctl/pkg/environment"
|
"opendev.org/airship/airshipctl/pkg/environment"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// TODO this should be part of a airshipctl config
|
||||||
|
EphemeralClusterAnnotation = "airshipit.org/clustertype=ephemeral"
|
||||||
|
)
|
||||||
|
|
||||||
// Settings settings for isogen command
|
// Settings settings for isogen command
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
*environment.AirshipCTLSettings
|
*environment.AirshipCTLSettings
|
||||||
|
2
pkg/bootstrap/isogen/testdata/kustomization.yaml
vendored
Normal file
2
pkg/bootstrap/isogen/testdata/kustomization.yaml
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
resources:
|
||||||
|
- secret.yaml
|
11
pkg/bootstrap/isogen/testdata/secret.yaml
vendored
Normal file
11
pkg/bootstrap/isogen/testdata/secret.yaml
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
airshipit.org/clustertype: ephemeral
|
||||||
|
name: node1-bmc-secret
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
netconfig: bmV0Y29uZmlnCg==
|
||||||
|
stringData:
|
||||||
|
userdata: cloud-init
|
15
pkg/document/errors.go
Normal file
15
pkg/document/errors.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package document
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrDocNotFound returned if desired document not found
|
||||||
|
type ErrDocNotFound struct {
|
||||||
|
Annotation string
|
||||||
|
Kind string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrDocNotFound) Error() string {
|
||||||
|
return fmt.Sprintf("Document annotated by %s with Kind %s not found", e.Annotation, e.Kind)
|
||||||
|
}
|
@ -7,3 +7,11 @@ type ErrNotImplemented struct {
|
|||||||
func (e ErrNotImplemented) Error() string {
|
func (e ErrNotImplemented) Error() string {
|
||||||
return "Error. Not implemented"
|
return "Error. Not implemented"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrWrongConfig returned in case of incorrect configuration
|
||||||
|
type ErrWrongConfig struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrWrongConfig) Error() string {
|
||||||
|
return "Error. Wrong configuration"
|
||||||
|
}
|
||||||
|
17
pkg/util/writefiles.go
Normal file
17
pkg/util/writefiles.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WriteFiles write multiple files described in a map
|
||||||
|
func WriteFiles(fls map[string][]byte, mode os.FileMode) error {
|
||||||
|
for fileName, data := range fls {
|
||||||
|
if err := ioutil.WriteFile(fileName, data, mode); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user