Move bootstrapInfo config section to manifests
This is a part of two activities * Refactor config and store all parameters to document model * Implement everything as phases (which are supposed to be purely document driven) This patch removes bootstrapInfo section from the airshipctl config and makes these to commands * airshipctl baremetal isogen * airthipctl baremetal remotedirect to take necessary parameters from documents We introduce two airship API kinds ImageGenerator and RemoteDirect. Instead of storing config parameters in cm/secrets we use these two API objects. Relates-To: #246 Closes: #254 Change-Id: I42903c45dce1c73da184c07277fec76fd88c700f
This commit is contained in:
parent
61633d30fc
commit
e9c8425c30
@ -1,6 +1,5 @@
|
||||
Cluster: clusterBar
|
||||
ephemeral:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterBar_ephemeral
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -10,7 +9,6 @@ server: ""
|
||||
|
||||
Cluster: clusterBar
|
||||
target:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterBar_target
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -20,7 +18,6 @@ server: ""
|
||||
|
||||
Cluster: clusterBaz
|
||||
ephemeral:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterBaz_ephemeral
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -30,7 +27,6 @@ server: ""
|
||||
|
||||
Cluster: clusterBaz
|
||||
target:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterBaz_target
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -40,7 +36,6 @@ server: ""
|
||||
|
||||
Cluster: clusterFoo
|
||||
ephemeral:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterFoo_ephemeral
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -50,7 +45,6 @@ server: ""
|
||||
|
||||
Cluster: clusterFoo
|
||||
target:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterFoo_target
|
||||
managementConfiguration: ""
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
Cluster: clusterBar
|
||||
ephemeral:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterBar_ephemeral
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -10,7 +9,6 @@ server: ""
|
||||
|
||||
Cluster: clusterBar
|
||||
target:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterBar_target
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -20,7 +18,6 @@ server: ""
|
||||
|
||||
Cluster: clusterBaz
|
||||
ephemeral:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterBaz_ephemeral
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -30,7 +27,6 @@ server: ""
|
||||
|
||||
Cluster: clusterBaz
|
||||
target:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterBaz_target
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -40,7 +36,6 @@ server: ""
|
||||
|
||||
Cluster: clusterFoo
|
||||
ephemeral:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterFoo_ephemeral
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -50,7 +45,6 @@ server: ""
|
||||
|
||||
Cluster: clusterFoo
|
||||
target:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterFoo_target
|
||||
managementConfiguration: ""
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
Cluster: clusterFoo
|
||||
ephemeral:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterFoo_ephemeral
|
||||
managementConfiguration: ""
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
Cluster: clusterBar
|
||||
ephemeral:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterBar_ephemeral
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -10,7 +9,6 @@ server: ""
|
||||
|
||||
Cluster: clusterBar
|
||||
target:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterBar_target
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -20,7 +18,6 @@ server: ""
|
||||
|
||||
Cluster: clusterBaz
|
||||
ephemeral:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterBaz_ephemeral
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -30,7 +27,6 @@ server: ""
|
||||
|
||||
Cluster: clusterBaz
|
||||
target:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterBaz_target
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -40,7 +36,6 @@ server: ""
|
||||
|
||||
Cluster: clusterFoo
|
||||
ephemeral:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterFoo_ephemeral
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -50,7 +45,6 @@ server: ""
|
||||
|
||||
Cluster: clusterFoo
|
||||
target:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterFoo_target
|
||||
managementConfiguration: ""
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
Cluster: clusterBar
|
||||
ephemeral:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterBar_ephemeral
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -10,7 +9,6 @@ server: ""
|
||||
|
||||
Cluster: clusterBar
|
||||
target:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterBar_target
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -20,7 +18,6 @@ server: ""
|
||||
|
||||
Cluster: clusterBaz
|
||||
ephemeral:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterBaz_ephemeral
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -30,7 +27,6 @@ server: ""
|
||||
|
||||
Cluster: clusterBaz
|
||||
target:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterBaz_target
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -40,7 +36,6 @@ server: ""
|
||||
|
||||
Cluster: clusterFoo
|
||||
ephemeral:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterFoo_ephemeral
|
||||
managementConfiguration: ""
|
||||
|
||||
@ -50,7 +45,6 @@ server: ""
|
||||
|
||||
Cluster: clusterFoo
|
||||
target:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterFoo_target
|
||||
managementConfiguration: ""
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
Cluster: clusterFoo
|
||||
target:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: clusterFoo_target
|
||||
managementConfiguration: ""
|
||||
|
||||
|
14
manifests/function/ephemeral/image_configuration.yaml
Normal file
14
manifests/function/ephemeral/image_configuration.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: ImageConfiguration
|
||||
metadata:
|
||||
name: default
|
||||
labels:
|
||||
airshipit.org/deploy-k8s: "false"
|
||||
builder:
|
||||
networkConfigFileName: network-config
|
||||
outputMetadataFileName: output-metadata.yaml
|
||||
userDataFileName: user-data
|
||||
container:
|
||||
containerRuntime: docker
|
||||
image: quay.io/airshipit/isogen:latest-ubuntu_focal
|
||||
volume: /srv/iso:/config
|
@ -1,2 +1,4 @@
|
||||
resources:
|
||||
- secret.yaml
|
||||
- image_configuration.yaml
|
||||
- remote_direct_configuration.yaml
|
||||
|
@ -0,0 +1,7 @@
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: RemoteDirectConfiguration
|
||||
metadata:
|
||||
name: default
|
||||
labels:
|
||||
airshipit.org/deploy-k8s: "false"
|
||||
isoUrl: http://localhost:8099/ubuntu-focal.iso
|
@ -46,6 +46,8 @@ func init() {
|
||||
&PhasePlan{},
|
||||
&KubeConfig{},
|
||||
&KubernetesApply{},
|
||||
&ImageConfiguration{},
|
||||
&RemoteDirectConfiguration{},
|
||||
)
|
||||
_ = AddToScheme(Scheme) //nolint:errcheck
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
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
|
||||
@ -14,21 +12,13 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package config
|
||||
package v1alpha1
|
||||
|
||||
import "sigs.k8s.io/yaml"
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// Bootstrap holds configurations for bootstrap steps
|
||||
type Bootstrap struct {
|
||||
// Configuration parameters for container
|
||||
Container *Container `json:"container,omitempty"`
|
||||
// Configuration parameters for ISO builder
|
||||
Builder *Builder `json:"builder,omitempty"`
|
||||
// Configuration parameters for ephemeral node remote management
|
||||
RemoteDirect *RemoteDirect `json:"remoteDirect,omitempty"`
|
||||
}
|
||||
|
||||
// Container parameters
|
||||
// Container structure contains parameters related to Docker runtime, used for building image
|
||||
type Container struct {
|
||||
// Container volume directory binding.
|
||||
Volume string `json:"volume,omitempty"`
|
||||
@ -38,7 +28,7 @@ type Container struct {
|
||||
ContainerRuntime string `json:"containerRuntime,omitempty"`
|
||||
}
|
||||
|
||||
// Builder parameters
|
||||
// Builder structure defines metadata files (including Cloud Init metadata) used for image
|
||||
type Builder struct {
|
||||
// Cloud Init user-data file name placed to the container volume root
|
||||
UserDataFileName string `json:"userDataFileName,omitempty"`
|
||||
@ -48,35 +38,12 @@ type Builder struct {
|
||||
OutputMetadataFileName string `json:"outputMetadataFileName,omitempty"`
|
||||
}
|
||||
|
||||
// RemoteDirect configuration options
|
||||
type RemoteDirect struct {
|
||||
// IsoURL specifies url to download ISO image for ephemeral node
|
||||
IsoURL string `json:"isoUrl,omitempty"`
|
||||
}
|
||||
// ImageConfiguration structure is inherited from apimachinery TypeMeta and ObjectMeta and is a top level
|
||||
// configuration structure for building image
|
||||
type ImageConfiguration struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Bootstrap functions
|
||||
func (b *Bootstrap) String() string {
|
||||
yamlData, err := yaml.Marshal(&b)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(yamlData)
|
||||
}
|
||||
|
||||
// String returns Container object in a serialized string format
|
||||
func (c *Container) String() string {
|
||||
yamlData, err := yaml.Marshal(&c)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(yamlData)
|
||||
}
|
||||
|
||||
// String returns Builder object in a serialized string format
|
||||
func (b *Builder) String() string {
|
||||
yamlData, err := yaml.Marshal(&b)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(yamlData)
|
||||
Container *Container `json:"container,omitempty"`
|
||||
Builder *Builder `json:"builder,omitempty"`
|
||||
}
|
29
pkg/api/v1alpha1/remotedirectconfiguration_types.go
Normal file
29
pkg/api/v1alpha1/remotedirectconfiguration_types.go
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
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
|
||||
|
||||
http://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 v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// RemoteDirectConfiguration structure is inherited from apimachinery TypeMeta and ObjectMeta structures
|
||||
// and defines parameters used to bootstrap the ephemeral node during the remote direct
|
||||
type RemoteDirectConfiguration struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// IsoURL specifies url to download ISO image for ephemeral node
|
||||
IsoURL string `json:"isoUrl,omitempty"`
|
||||
}
|
@ -345,3 +345,85 @@ func (in *Provider) DeepCopy() *Provider {
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ImageConfiguration) DeepCopyInto(out *ImageConfiguration) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Container.DeepCopyInto(out.Container)
|
||||
in.Builder.DeepCopyInto(out.Builder)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Phase.
|
||||
func (in *ImageConfiguration) DeepCopy() *ImageConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ImageConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ImageConfiguration) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Container) DeepCopyInto(out *Container) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PhaseConfig.
|
||||
func (in *Container) DeepCopy() *Container {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Container)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Builder) DeepCopyInto(out *Builder) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PhaseConfig.
|
||||
func (in *Builder) DeepCopy() *Builder {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Builder)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RemoteDirectConfiguration) DeepCopyInto(out *RemoteDirectConfiguration) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Phase.
|
||||
func (in *RemoteDirectConfiguration) DeepCopy() *RemoteDirectConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RemoteDirectConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *RemoteDirectConfiguration) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
api "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||
"opendev.org/airship/airshipctl/pkg/bootstrap/cloudinit"
|
||||
"opendev.org/airship/airshipctl/pkg/config"
|
||||
"opendev.org/airship/airshipctl/pkg/container"
|
||||
@ -43,17 +44,6 @@ func GenerateBootstrapIso(settings *environment.AirshipCTLSettings) error {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg, err := globalConf.CurrentContextBootstrapInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = verifyInputs(cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO (dukov) replace with the appropriate function once it's available
|
||||
// in document module
|
||||
root, err := globalConf.CurrentContextEntryPoint(config.BootstrapPhase)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -63,23 +53,41 @@ func GenerateBootstrapIso(settings *environment.AirshipCTLSettings) error {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Creating ISO builder container")
|
||||
builder, err := container.NewContainer(
|
||||
&ctx, cfg.Container.ContainerRuntime,
|
||||
cfg.Container.Image)
|
||||
imageConfiguration := &api.ImageConfiguration{}
|
||||
selector, err := document.NewSelector().ByObject(imageConfiguration, api.Scheme)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
doc, err := docBundle.SelectOne(selector)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = generateBootstrapIso(docBundle, builder, cfg, log.DebugEnabled())
|
||||
err = doc.ToAPIObject(imageConfiguration, api.Scheme)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = verifyInputs(imageConfiguration); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Creating ISO builder container")
|
||||
builder, err := container.NewContainer(
|
||||
&ctx, imageConfiguration.Container.ContainerRuntime,
|
||||
imageConfiguration.Container.Image)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = generateBootstrapIso(docBundle, builder, doc, imageConfiguration, log.DebugEnabled())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Print("Checking artifacts")
|
||||
return verifyArtifacts(cfg)
|
||||
return verifyArtifacts(imageConfiguration)
|
||||
}
|
||||
|
||||
func verifyInputs(cfg *config.Bootstrap) error {
|
||||
func verifyInputs(cfg *api.ImageConfiguration) error {
|
||||
if cfg.Container.Volume == "" {
|
||||
return config.ErrMissingConfig{
|
||||
What: "Must specify volume bind for ISO builder container",
|
||||
@ -104,19 +112,22 @@ func verifyInputs(cfg *config.Bootstrap) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getContainerCfg(cfg *config.Bootstrap, userData []byte, netConf []byte) map[string][]byte {
|
||||
func getContainerCfg(
|
||||
cfg *api.ImageConfiguration,
|
||||
builderCfgYaml []byte,
|
||||
userData []byte,
|
||||
netConf []byte,
|
||||
) map[string][]byte {
|
||||
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
|
||||
// TODO (dukov) Get rid of this ugly conversion byte -> string -> byte
|
||||
builderData := []byte(cfg.String())
|
||||
fls[filepath.Join(hostVol, builderConfigFileName)] = builderData
|
||||
fls[filepath.Join(hostVol, builderConfigFileName)] = builderCfgYaml
|
||||
return fls
|
||||
}
|
||||
|
||||
func verifyArtifacts(cfg *config.Bootstrap) error {
|
||||
func verifyArtifacts(cfg *api.ImageConfiguration) error {
|
||||
hostVol := strings.Split(cfg.Container.Volume, ":")[0]
|
||||
metadataPath := filepath.Join(hostVol, cfg.Builder.OutputMetadataFileName)
|
||||
_, err := os.Stat(metadataPath)
|
||||
@ -126,7 +137,8 @@ func verifyArtifacts(cfg *config.Bootstrap) error {
|
||||
func generateBootstrapIso(
|
||||
docBundle document.Bundle,
|
||||
builder container.Container,
|
||||
cfg *config.Bootstrap,
|
||||
doc document.Document,
|
||||
cfg *api.ImageConfiguration,
|
||||
debug bool,
|
||||
) error {
|
||||
cntVol := strings.Split(cfg.Container.Volume, ":")[1]
|
||||
@ -136,7 +148,12 @@ func generateBootstrapIso(
|
||||
return err
|
||||
}
|
||||
|
||||
fls := getContainerCfg(cfg, userData, netConf)
|
||||
builderCfgYaml, err := doc.AsYAML()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fls := getContainerCfg(cfg, builderCfgYaml, userData, netConf)
|
||||
if err = util.WriteFiles(fls, 0600); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -21,9 +21,12 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/environment"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
api "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||
"opendev.org/airship/airshipctl/pkg/config"
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
"opendev.org/airship/airshipctl/pkg/log"
|
||||
@ -66,17 +69,26 @@ func TestBootstrapIso(t *testing.T) {
|
||||
defer cleanup(t)
|
||||
|
||||
volBind := tempVol + ":/dst"
|
||||
testErr := fmt.Errorf("testErr")
|
||||
testCfg := &config.Bootstrap{
|
||||
Container: &config.Container{
|
||||
testErr := fmt.Errorf("TestErr")
|
||||
testCfg := &api.ImageConfiguration{
|
||||
Container: &api.Container{
|
||||
Volume: volBind,
|
||||
ContainerRuntime: "docker",
|
||||
},
|
||||
Builder: &config.Builder{
|
||||
Builder: &api.Builder{
|
||||
UserDataFileName: "user-data",
|
||||
NetworkConfigFileName: "net-conf",
|
||||
},
|
||||
}
|
||||
testDoc := &MockDocument{
|
||||
MockAsYAML: func() ([]byte, error) { return []byte("TESTDOC"), nil },
|
||||
}
|
||||
testBuilder := &mockContainer{
|
||||
runCommand: func() error { return nil },
|
||||
getID: func() string { return "TESTID" },
|
||||
rmContainer: func() error { return nil },
|
||||
}
|
||||
|
||||
expOut := []string{
|
||||
"Creating cloud-init for ephemeral K8s",
|
||||
fmt.Sprintf("Running default container command. Mounted dir: [%s]", volBind),
|
||||
@ -87,7 +99,8 @@ func TestBootstrapIso(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
builder *mockContainer
|
||||
cfg *config.Bootstrap
|
||||
cfg *api.ImageConfiguration
|
||||
doc *MockDocument
|
||||
debug bool
|
||||
expectedOut []string
|
||||
expectedErr error
|
||||
@ -97,16 +110,15 @@ func TestBootstrapIso(t *testing.T) {
|
||||
runCommand: func() error { return testErr },
|
||||
},
|
||||
cfg: testCfg,
|
||||
doc: testDoc,
|
||||
debug: false,
|
||||
expectedOut: []string{expOut[0], expOut[1]},
|
||||
expectedErr: testErr,
|
||||
},
|
||||
{
|
||||
builder: &mockContainer{
|
||||
runCommand: func() error { return nil },
|
||||
getID: func() string { return "TESTID" },
|
||||
},
|
||||
builder: testBuilder,
|
||||
cfg: testCfg,
|
||||
doc: testDoc,
|
||||
debug: true,
|
||||
expectedOut: []string{expOut[0], expOut[1], expOut[2], expOut[3]},
|
||||
expectedErr: nil,
|
||||
@ -118,16 +130,27 @@ func TestBootstrapIso(t *testing.T) {
|
||||
rmContainer: func() error { return testErr },
|
||||
},
|
||||
cfg: testCfg,
|
||||
doc: testDoc,
|
||||
debug: false,
|
||||
expectedOut: []string{expOut[0], expOut[1], expOut[2], expOut[4]},
|
||||
expectedErr: testErr,
|
||||
},
|
||||
{
|
||||
builder: testBuilder,
|
||||
cfg: testCfg,
|
||||
doc: &MockDocument{
|
||||
MockAsYAML: func() ([]byte, error) { return nil, testErr },
|
||||
},
|
||||
debug: false,
|
||||
expectedOut: []string{expOut[0]},
|
||||
expectedErr: testErr,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
outBuf := &bytes.Buffer{}
|
||||
log.Init(tt.debug, outBuf)
|
||||
actualErr := generateBootstrapIso(bundle, tt.builder, tt.cfg, tt.debug)
|
||||
actualErr := generateBootstrapIso(bundle, tt.builder, tt.doc, tt.cfg, tt.debug)
|
||||
actualOut := outBuf.String()
|
||||
|
||||
for _, line := range tt.expectedOut {
|
||||
@ -144,14 +167,14 @@ func TestVerifyInputs(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
cfg *config.Bootstrap
|
||||
cfg *api.ImageConfiguration
|
||||
args []string
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "missing-container-field",
|
||||
cfg: &config.Bootstrap{
|
||||
Container: &config.Container{},
|
||||
cfg: &api.ImageConfiguration{
|
||||
Container: &api.Container{},
|
||||
},
|
||||
expectedErr: config.ErrMissingConfig{
|
||||
What: "Must specify volume bind for ISO builder container",
|
||||
@ -159,11 +182,11 @@ func TestVerifyInputs(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "missing-filenames",
|
||||
cfg: &config.Bootstrap{
|
||||
Container: &config.Container{
|
||||
cfg: &api.ImageConfiguration{
|
||||
Container: &api.Container{
|
||||
Volume: tempVol + ":/dst",
|
||||
},
|
||||
Builder: &config.Builder{},
|
||||
Builder: &api.Builder{},
|
||||
},
|
||||
expectedErr: config.ErrMissingConfig{
|
||||
What: "UserDataFileName or NetworkConfigFileName are not specified in ISO builder config",
|
||||
@ -171,11 +194,11 @@ func TestVerifyInputs(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid-host-path",
|
||||
cfg: &config.Bootstrap{
|
||||
Container: &config.Container{
|
||||
cfg: &api.ImageConfiguration{
|
||||
Container: &api.Container{
|
||||
Volume: tempVol + ":/dst:/dst1",
|
||||
},
|
||||
Builder: &config.Builder{
|
||||
Builder: &api.Builder{
|
||||
UserDataFileName: "user-data",
|
||||
NetworkConfigFileName: "net-conf",
|
||||
},
|
||||
@ -186,11 +209,11 @@ func TestVerifyInputs(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "success",
|
||||
cfg: &config.Bootstrap{
|
||||
Container: &config.Container{
|
||||
cfg: &api.ImageConfiguration{
|
||||
Container: &api.Container{
|
||||
Volume: tempVol,
|
||||
},
|
||||
Builder: &config.Builder{
|
||||
Builder: &api.Builder{
|
||||
UserDataFileName: "user-data",
|
||||
NetworkConfigFileName: "net-conf",
|
||||
},
|
||||
@ -207,3 +230,90 @@ func TestVerifyInputs(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateBootstrapIso(t *testing.T) {
|
||||
t.Run("EnsureCompleteError", func(t *testing.T) {
|
||||
settings := &environment.AirshipCTLSettings{
|
||||
Debug: false,
|
||||
AirshipConfigPath: "testdata/config/config",
|
||||
KubeConfigPath: "testdata/config/kubeconfig",
|
||||
Config: &config.Config{},
|
||||
}
|
||||
expectedErr := config.ErrMissingConfig{What: "Current Context is not defined"}
|
||||
settings.InitConfig()
|
||||
settings.Config.CurrentContext = ""
|
||||
actualErr := GenerateBootstrapIso(settings)
|
||||
assert.Equal(t, expectedErr, actualErr)
|
||||
})
|
||||
|
||||
t.Run("ContextEntryPointError", func(t *testing.T) {
|
||||
settings := &environment.AirshipCTLSettings{
|
||||
Debug: false,
|
||||
AirshipConfigPath: "testdata/config/config",
|
||||
KubeConfigPath: "testdata/config/kubeconfig",
|
||||
Config: &config.Config{},
|
||||
}
|
||||
expectedErr := config.ErrMissingPrimaryRepo{}
|
||||
settings.InitConfig()
|
||||
settings.Config.Manifests["default"].Repositories = make(map[string]*config.Repository)
|
||||
actualErr := GenerateBootstrapIso(settings)
|
||||
assert.Equal(t, expectedErr, actualErr)
|
||||
})
|
||||
|
||||
t.Run("NewBundleByPathError", func(t *testing.T) {
|
||||
settings := &environment.AirshipCTLSettings{
|
||||
Debug: false,
|
||||
AirshipConfigPath: "testdata/config/config",
|
||||
KubeConfigPath: "testdata/config/kubeconfig",
|
||||
Config: &config.Config{},
|
||||
}
|
||||
expectedErr := config.ErrMissingPhaseDocument{PhaseName: "bootstrap"}
|
||||
settings.InitConfig()
|
||||
settings.Config.Manifests["default"].TargetPath = "/nonexistent"
|
||||
actualErr := GenerateBootstrapIso(settings)
|
||||
assert.Equal(t, expectedErr, actualErr)
|
||||
})
|
||||
|
||||
t.Run("SelectOneError", func(t *testing.T) {
|
||||
settings := &environment.AirshipCTLSettings{
|
||||
Debug: false,
|
||||
AirshipConfigPath: "testdata/config/config",
|
||||
KubeConfigPath: "testdata/config/kubeconfig",
|
||||
Config: &config.Config{},
|
||||
}
|
||||
expectedErr := document.ErrDocNotFound{
|
||||
Selector: document.NewSelector().ByGvk("airshipit.org", "v1alpha1", "ImageConfiguration")}
|
||||
settings.InitConfig()
|
||||
settings.Config.Manifests["default"].SubPath = "missingkinddoc/site/test-site"
|
||||
actualErr := GenerateBootstrapIso(settings)
|
||||
assert.Equal(t, expectedErr, actualErr)
|
||||
})
|
||||
|
||||
t.Run("ToObjectError", func(t *testing.T) {
|
||||
settings := &environment.AirshipCTLSettings{
|
||||
Debug: false,
|
||||
AirshipConfigPath: "testdata/config/config",
|
||||
KubeConfigPath: "testdata/config/kubeconfig",
|
||||
Config: &config.Config{},
|
||||
}
|
||||
expectedErrMessage := "missing metadata.name in object"
|
||||
settings.InitConfig()
|
||||
settings.Config.Manifests["default"].SubPath = "missingmetadoc/site/test-site"
|
||||
actualErr := GenerateBootstrapIso(settings)
|
||||
assert.Contains(t, actualErr.Error(), expectedErrMessage)
|
||||
})
|
||||
|
||||
t.Run("verifyInputsError", func(t *testing.T) {
|
||||
settings := &environment.AirshipCTLSettings{
|
||||
Debug: false,
|
||||
AirshipConfigPath: "testdata/config/config",
|
||||
KubeConfigPath: "testdata/config/kubeconfig",
|
||||
Config: &config.Config{},
|
||||
}
|
||||
expectedErr := config.ErrMissingConfig{What: "Must specify volume bind for ISO builder container"}
|
||||
settings.InitConfig()
|
||||
settings.Config.Manifests["default"].SubPath = "missingvoldoc/site/test-site"
|
||||
actualErr := GenerateBootstrapIso(settings)
|
||||
assert.Equal(t, expectedErr, actualErr)
|
||||
})
|
||||
}
|
||||
|
127
pkg/bootstrap/isogen/mock_document_test.go
Normal file
127
pkg/bootstrap/isogen/mock_document_test.go
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
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 isogen
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
type MockDocument struct {
|
||||
MockAnnotate func()
|
||||
MockAsYAML func() ([]byte, error)
|
||||
MockGetAnnotations func() map[string]string
|
||||
MockGetBool func() (bool, error)
|
||||
MockGetFloat64 func() (float64, error)
|
||||
MockGetGroup func() string
|
||||
MockGetInt64 func() (int64, error)
|
||||
MockGetKind func() string
|
||||
MockGetLabels func() map[string]string
|
||||
MockGetMap func() (map[string]interface{}, error)
|
||||
MockGetName func() string
|
||||
MockGetNamespace func() string
|
||||
MockGetSlice func() ([]interface{}, error)
|
||||
MockGetString func() (string, error)
|
||||
MockGetStringMap func() (map[string]string, error)
|
||||
MockGetStringSlice func() ([]string, error)
|
||||
MockGetVersion func() string
|
||||
MockLabel func()
|
||||
MockMarshalJSON func() ([]byte, error)
|
||||
MockToObject func() error
|
||||
MockToAPIObject func() error
|
||||
}
|
||||
|
||||
func (md *MockDocument) Annotate(_ map[string]string) {
|
||||
md.MockAnnotate()
|
||||
}
|
||||
|
||||
func (md *MockDocument) AsYAML() ([]byte, error) {
|
||||
return md.MockAsYAML()
|
||||
}
|
||||
|
||||
func (md *MockDocument) GetAnnotations() map[string]string {
|
||||
return md.MockGetAnnotations()
|
||||
}
|
||||
|
||||
func (md *MockDocument) GetBool(_ string) (bool, error) {
|
||||
return md.MockGetBool()
|
||||
}
|
||||
|
||||
func (md *MockDocument) GetFloat64(_ string) (float64, error) {
|
||||
return md.MockGetFloat64()
|
||||
}
|
||||
|
||||
func (md *MockDocument) GetGroup() string {
|
||||
return md.MockGetGroup()
|
||||
}
|
||||
|
||||
func (md *MockDocument) GetInt64(_ string) (int64, error) {
|
||||
return md.MockGetInt64()
|
||||
}
|
||||
|
||||
func (md *MockDocument) GetKind() string {
|
||||
return md.MockGetKind()
|
||||
}
|
||||
|
||||
func (md *MockDocument) GetLabels() map[string]string {
|
||||
return md.MockGetLabels()
|
||||
}
|
||||
|
||||
func (md *MockDocument) GetMap(_ string) (map[string]interface{}, error) {
|
||||
return md.MockGetMap()
|
||||
}
|
||||
|
||||
func (md *MockDocument) GetName() string {
|
||||
return md.MockGetName()
|
||||
}
|
||||
|
||||
func (md *MockDocument) GetNamespace() string {
|
||||
return md.MockGetNamespace()
|
||||
}
|
||||
|
||||
func (md *MockDocument) GetSlice(_ string) ([]interface{}, error) {
|
||||
return md.MockGetSlice()
|
||||
}
|
||||
|
||||
func (md *MockDocument) GetString(_ string) (string, error) {
|
||||
return md.MockGetString()
|
||||
}
|
||||
|
||||
func (md *MockDocument) GetStringMap(_ string) (map[string]string, error) {
|
||||
return md.MockGetStringMap()
|
||||
}
|
||||
|
||||
func (md *MockDocument) GetStringSlice(_ string) ([]string, error) {
|
||||
return md.MockGetStringSlice()
|
||||
}
|
||||
|
||||
func (md *MockDocument) GetVersion() string {
|
||||
return md.MockGetVersion()
|
||||
}
|
||||
|
||||
func (md *MockDocument) Label(_ map[string]string) {
|
||||
md.MockLabel()
|
||||
}
|
||||
|
||||
func (md *MockDocument) MarshalJSON() ([]byte, error) {
|
||||
return md.MockMarshalJSON()
|
||||
}
|
||||
|
||||
func (md *MockDocument) ToObject(_ interface{}) error {
|
||||
return md.MockToObject()
|
||||
}
|
||||
|
||||
func (md *MockDocument) ToAPIObject(obj runtime.Object, scheme *runtime.Scheme) error {
|
||||
return md.MockToAPIObject()
|
||||
}
|
34
pkg/bootstrap/isogen/testdata/config/config
vendored
Normal file
34
pkg/bootstrap/isogen/testdata/config/config
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
clusters:
|
||||
default:
|
||||
clusterType:
|
||||
ephemeral:
|
||||
clusterKubeconf: default_ephemeral
|
||||
managementConfiguration: default
|
||||
contexts:
|
||||
default:
|
||||
contextKubeconf: default_ephemeral
|
||||
manifest: default
|
||||
currentContext: default
|
||||
kind: Config
|
||||
managementConfiguration:
|
||||
default:
|
||||
insecure: true
|
||||
systemActionRetries: 30
|
||||
systemRebootDelay: 30
|
||||
type: redfish
|
||||
manifests:
|
||||
default:
|
||||
primaryRepositoryName: primary
|
||||
repositories:
|
||||
primary:
|
||||
checkout:
|
||||
branch: master
|
||||
commitHash: ""
|
||||
force: false
|
||||
tag: ""
|
||||
url: https://opendev.org/airship/treasuremap
|
||||
subPath: primary/site/test-site
|
||||
targetPath: testdata
|
||||
users:
|
||||
admin: {}
|
17
pkg/bootstrap/isogen/testdata/config/kubeconfig
vendored
Normal file
17
pkg/bootstrap/isogen/testdata/config/kubeconfig
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
server: https://172.17.0.1:6443
|
||||
name: default_ephemeral
|
||||
contexts:
|
||||
- context:
|
||||
cluster: default_ephemeral
|
||||
user: admin
|
||||
name: default
|
||||
current-context: default
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: admin
|
||||
user:
|
||||
username: airship-admin
|
@ -0,0 +1,12 @@
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: FakeImageConfiguration
|
||||
metadata:
|
||||
name: default
|
||||
builder:
|
||||
networkConfigFileName: network-config
|
||||
outputMetadataFileName: output-metadata.yaml
|
||||
userDataFileName: user-data
|
||||
container:
|
||||
containerRuntime: docker
|
||||
image: quay.io/airshipit/isogen:latest-debian_stable
|
||||
volume: /srv/iso:/config
|
@ -0,0 +1,2 @@
|
||||
resources:
|
||||
- image_configuration.yaml
|
@ -0,0 +1,10 @@
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: ImageConfiguration
|
||||
builder:
|
||||
networkConfigFileName: network-config
|
||||
outputMetadataFileName: output-metadata.yaml
|
||||
userDataFileName: user-data
|
||||
container:
|
||||
containerRuntime: docker
|
||||
image: quay.io/airshipit/isogen:latest-debian_stable
|
||||
volume: /srv/iso:/config
|
@ -0,0 +1,2 @@
|
||||
resources:
|
||||
- image_configuration.yaml
|
@ -0,0 +1,11 @@
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: ImageConfiguration
|
||||
metadata:
|
||||
name: default
|
||||
builder:
|
||||
networkConfigFileName: network-config
|
||||
outputMetadataFileName: output-metadata.yaml
|
||||
userDataFileName: user-data
|
||||
container:
|
||||
containerRuntime: docker
|
||||
image: quay.io/airshipit/isogen:latest-debian_stable
|
@ -0,0 +1,2 @@
|
||||
resources:
|
||||
- image_configuration.yaml
|
@ -34,9 +34,6 @@ type Cluster struct {
|
||||
|
||||
// Management configuration which will be used for all hosts in the cluster
|
||||
ManagementConfiguration string `json:"managementConfiguration"`
|
||||
|
||||
// Bootstrap configuration this clusters ephemeral hosts will rely on
|
||||
Bootstrap string `json:"bootstrapInfo"`
|
||||
}
|
||||
|
||||
// ClusterPurpose encapsulates the Cluster Type as an enumeration
|
||||
|
@ -67,9 +67,6 @@ type Config struct {
|
||||
// Management configuration defines management information for all baremetal hosts in a cluster.
|
||||
ManagementConfiguration map[string]*ManagementConfiguration `json:"managementConfiguration"`
|
||||
|
||||
// BootstrapInfo is the configuration for container runtime, ISO builder and remote management
|
||||
BootstrapInfo map[string]*Bootstrap `json:"bootstrapInfo"`
|
||||
|
||||
// loadedConfigPath is the full path to the the location of the config
|
||||
// file from which this config was loaded
|
||||
// +not persisted in file
|
||||
@ -952,26 +949,6 @@ func (c *Config) importAuthInfos(importKubeConfig *clientcmdapi.Config) {
|
||||
}
|
||||
}
|
||||
|
||||
// CurrentContextBootstrapInfo returns bootstrap info for current context
|
||||
func (c *Config) CurrentContextBootstrapInfo() (*Bootstrap, error) {
|
||||
currentCluster, err := c.CurrentContextCluster()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if currentCluster.Bootstrap == "" {
|
||||
return nil, ErrMissingConfig{
|
||||
What: fmt.Sprintf("No bootstrapInfo defined for context %q", c.CurrentContext),
|
||||
}
|
||||
}
|
||||
|
||||
bootstrap, exists := c.BootstrapInfo[currentCluster.Bootstrap]
|
||||
if !exists {
|
||||
return nil, ErrBootstrapInfoNotFound{Name: currentCluster.Bootstrap}
|
||||
}
|
||||
return bootstrap, nil
|
||||
}
|
||||
|
||||
// GetManifests returns all of the Manifests associated with the Config sorted by name
|
||||
func (c *Config) GetManifests() []*Manifest {
|
||||
keys := make([]string, 0, len(c.Manifests))
|
||||
|
@ -80,30 +80,10 @@ func TestString(t *testing.T) {
|
||||
name: "repo-checkout",
|
||||
stringer: testutil.DummyRepoCheckout(),
|
||||
},
|
||||
{
|
||||
name: "bootstrapinfo",
|
||||
stringer: testutil.DummyBootstrapInfo(),
|
||||
},
|
||||
{
|
||||
name: "managementconfiguration",
|
||||
stringer: testutil.DummyManagementConfiguration(),
|
||||
},
|
||||
{
|
||||
name: "builder",
|
||||
stringer: &config.Builder{
|
||||
UserDataFileName: "user-data",
|
||||
NetworkConfigFileName: "netconfig",
|
||||
OutputMetadataFileName: "output-metadata.yaml",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "container",
|
||||
stringer: &config.Container{
|
||||
Volume: "/dummy:dummy",
|
||||
Image: "dummy_image:dummy_tag",
|
||||
ContainerRuntime: "docker",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
@ -258,27 +238,6 @@ func TestEnsureComplete(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCurrentContextBootstrapInfo(t *testing.T) {
|
||||
conf, cleanup := testutil.InitConfig(t)
|
||||
defer cleanup(t)
|
||||
|
||||
clusterName := "def"
|
||||
clusterType := "ephemeral"
|
||||
|
||||
bootstrapInfo, err := conf.CurrentContextBootstrapInfo()
|
||||
require.Error(t, err)
|
||||
assert.Nil(t, bootstrapInfo)
|
||||
|
||||
conf.CurrentContext = currentContextName
|
||||
conf.Clusters[clusterName].ClusterTypes[clusterType].Bootstrap = defaultString
|
||||
conf.Contexts[currentContextName].Manifest = defaultString
|
||||
conf.Contexts[currentContextName].KubeContext().Cluster = clusterName
|
||||
|
||||
bootstrapInfo, err = conf.CurrentContextBootstrapInfo()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, conf.BootstrapInfo[defaultString], bootstrapInfo)
|
||||
}
|
||||
|
||||
func TestCurrentContextManagementConfig(t *testing.T) {
|
||||
conf, cleanup := testutil.InitConfig(t)
|
||||
defer cleanup(t)
|
||||
|
@ -43,7 +43,6 @@ const (
|
||||
AirshipConfigGroup = "airshipit.org"
|
||||
AirshipConfigKind = "Config"
|
||||
AirshipConfigVersion = "v1alpha1"
|
||||
AirshipDefaultBootstrapInfo = "default"
|
||||
AirshipDefaultContext = "default"
|
||||
AirshipDefaultDirectoryPermission = 0750
|
||||
AirshipDefaultFilePermission = 0640
|
||||
@ -57,8 +56,6 @@ const (
|
||||
AirshipPluginPathEnv = "AIRSHIP_KUSTOMIZE_PLUGINS"
|
||||
|
||||
// Modules
|
||||
AirshipDefaultBootstrapImage = "quay.io/airshipit/isogen:latest-ubuntu_focal"
|
||||
AirshipDefaultIsoURL = "http://localhost:8099/ubuntu-focal.iso"
|
||||
AirshipDefaultManagementType = redfish.ClientType
|
||||
)
|
||||
|
||||
|
@ -107,16 +107,6 @@ func (e ErrMissingRepoCheckoutOptions) Error() string {
|
||||
return "Missing repository checkout options."
|
||||
}
|
||||
|
||||
// ErrBootstrapInfoNotFound returned if bootstrap
|
||||
// information is not found for cluster
|
||||
type ErrBootstrapInfoNotFound struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (e ErrBootstrapInfoNotFound) Error() string {
|
||||
return fmt.Sprintf("Bootstrap info %q not found.", e.Name)
|
||||
}
|
||||
|
||||
// ErrInvalidConfig returned in case of incorrect configuration
|
||||
type ErrInvalidConfig struct {
|
||||
What string
|
||||
|
@ -1,8 +0,0 @@
|
||||
builder:
|
||||
networkConfigFileName: netconfig
|
||||
outputMetadataFileName: output-metadata.yaml
|
||||
userDataFileName: user-data
|
||||
container:
|
||||
containerRuntime: docker
|
||||
image: dummy_image:dummy_tag
|
||||
volume: /dummy:dummy
|
3
pkg/config/testdata/builder-string.yaml
vendored
3
pkg/config/testdata/builder-string.yaml
vendored
@ -1,3 +0,0 @@
|
||||
networkConfigFileName: netconfig
|
||||
outputMetadataFileName: output-metadata.yaml
|
||||
userDataFileName: user-data
|
1
pkg/config/testdata/cluster-string.yaml
vendored
1
pkg/config/testdata/cluster-string.yaml
vendored
@ -1,4 +1,3 @@
|
||||
bootstrapInfo: dummy_bootstrap_config
|
||||
clusterKubeconf: dummy_cluster_target
|
||||
managementConfiguration: dummy_management_config
|
||||
|
||||
|
12
pkg/config/testdata/config-string.yaml
vendored
12
pkg/config/testdata/config-string.yaml
vendored
@ -1,23 +1,11 @@
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
bootstrapInfo:
|
||||
dummy_bootstrap_config:
|
||||
builder:
|
||||
networkConfigFileName: netconfig
|
||||
outputMetadataFileName: output-metadata.yaml
|
||||
userDataFileName: user-data
|
||||
container:
|
||||
containerRuntime: docker
|
||||
image: dummy_image:dummy_tag
|
||||
volume: /dummy:dummy
|
||||
clusters:
|
||||
dummy_cluster:
|
||||
clusterType:
|
||||
ephemeral:
|
||||
bootstrapInfo: dummy_bootstrap_config
|
||||
clusterKubeconf: dummy_cluster_ephemeral
|
||||
managementConfiguration: dummy_management_config
|
||||
target:
|
||||
bootstrapInfo: dummy_bootstrap_config
|
||||
clusterKubeconf: dummy_cluster_target
|
||||
managementConfiguration: dummy_management_config
|
||||
contexts:
|
||||
|
@ -1,6 +1,5 @@
|
||||
Cluster: dummy_cluster
|
||||
target:
|
||||
bootstrapInfo: dummy_bootstrap_config
|
||||
clusterKubeconf: dummy_cluster_target
|
||||
managementConfiguration: dummy_management_config
|
||||
|
||||
|
@ -25,24 +25,7 @@ func NewConfig() *Config {
|
||||
return &Config{
|
||||
Kind: AirshipConfigKind,
|
||||
APIVersion: AirshipConfigAPIVersion,
|
||||
BootstrapInfo: map[string]*Bootstrap{
|
||||
AirshipDefaultBootstrapInfo: {
|
||||
Container: &Container{
|
||||
Volume: "/srv/iso:/config",
|
||||
Image: AirshipDefaultBootstrapImage,
|
||||
ContainerRuntime: "docker",
|
||||
},
|
||||
Builder: &Builder{
|
||||
UserDataFileName: "user-data",
|
||||
NetworkConfigFileName: "network-config",
|
||||
OutputMetadataFileName: "output-metadata.yaml",
|
||||
},
|
||||
RemoteDirect: &RemoteDirect{
|
||||
IsoURL: AirshipDefaultIsoURL,
|
||||
},
|
||||
},
|
||||
},
|
||||
Clusters: make(map[string]*ClusterPurpose),
|
||||
Clusters: make(map[string]*ClusterPurpose),
|
||||
Permissions: Permissions{
|
||||
DirectoryPermission: AirshipDefaultDirectoryPermission,
|
||||
FilePermission: AirshipDefaultFilePermission,
|
||||
@ -84,7 +67,6 @@ func NewContext() *Context {
|
||||
func NewCluster() *Cluster {
|
||||
return &Cluster{
|
||||
NameInKubeconf: "",
|
||||
Bootstrap: AirshipDefaultBootstrapInfo,
|
||||
ManagementConfiguration: AirshipDefaultManagementConfiguration,
|
||||
}
|
||||
}
|
||||
|
@ -45,14 +45,13 @@ func (e ErrUnknownManagementType) Error() string {
|
||||
return fmt.Sprintf("unknown management type: %s", e.Type)
|
||||
}
|
||||
|
||||
// ErrMissingBootstrapInfoOption is an error that indicates a bootstrap option is missing in the airshipctl
|
||||
// bootstrapInfo configuration.
|
||||
type ErrMissingBootstrapInfoOption struct {
|
||||
// ErrMissingOption is an error that indicates a remote direct config option is missing
|
||||
type ErrMissingOption struct {
|
||||
What string
|
||||
}
|
||||
|
||||
func (e ErrMissingBootstrapInfoOption) Error() string {
|
||||
return fmt.Sprintf("missing bootstrapInfo option: %s", e.What)
|
||||
func (e ErrMissingOption) Error() string {
|
||||
return fmt.Sprintf("missing option: %s", e.What)
|
||||
}
|
||||
|
||||
// ErrNoHostsFound is an error that indicates that no hosts matched the selection criteria passed to a manager.
|
||||
|
@ -15,7 +15,9 @@
|
||||
package remote
|
||||
|
||||
import (
|
||||
api "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||
"opendev.org/airship/airshipctl/pkg/config"
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
"opendev.org/airship/airshipctl/pkg/environment"
|
||||
"opendev.org/airship/airshipctl/pkg/log"
|
||||
|
||||
@ -25,14 +27,30 @@ import (
|
||||
// DoRemoteDirect bootstraps the ephemeral node.
|
||||
func (b baremetalHost) DoRemoteDirect(settings *environment.AirshipCTLSettings) error {
|
||||
cfg := settings.Config
|
||||
bootstrapSettings, err := cfg.CurrentContextBootstrapInfo()
|
||||
|
||||
root, err := cfg.CurrentContextEntryPoint(config.BootstrapPhase)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
remoteConfig := bootstrapSettings.RemoteDirect
|
||||
if remoteConfig == nil {
|
||||
return config.ErrMissingConfig{What: "RemoteDirect options not defined in bootstrap config"}
|
||||
docBundle, err := document.NewBundleByPath(root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
remoteDirectConfiguration := &api.RemoteDirectConfiguration{}
|
||||
selector, err := document.NewSelector().ByObject(remoteDirectConfiguration, api.Scheme)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
doc, err := docBundle.SelectOne(selector)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = doc.ToAPIObject(remoteDirectConfiguration, api.Scheme)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("Bootstrapping ephemeral host '%s' with ID '%s' and BMC Address '%s'.", b.HostName, b.NodeID(),
|
||||
@ -52,11 +70,11 @@ func (b baremetalHost) DoRemoteDirect(settings *environment.AirshipCTLSettings)
|
||||
}
|
||||
|
||||
// Perform remote direct operations
|
||||
if remoteConfig.IsoURL == "" {
|
||||
return ErrMissingBootstrapInfoOption{What: "isoURL"}
|
||||
if remoteDirectConfiguration.IsoURL == "" {
|
||||
return ErrMissingOption{What: "isoURL"}
|
||||
}
|
||||
|
||||
err = b.SetVirtualMedia(b.Context, remoteConfig.IsoURL)
|
||||
err = b.SetVirtualMedia(b.Context, remoteDirectConfiguration.IsoURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -20,8 +20,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/config"
|
||||
"opendev.org/airship/airshipctl/pkg/environment"
|
||||
"opendev.org/airship/airshipctl/pkg/remote/power"
|
||||
"opendev.org/airship/airshipctl/pkg/remote/redfish"
|
||||
"opendev.org/airship/airshipctl/testutil/redfishutils"
|
||||
@ -35,18 +33,6 @@ const (
|
||||
password = "password"
|
||||
)
|
||||
|
||||
// withRemoteDirectConfig initializes the remote direct settings when used as an argument to "initSettings".
|
||||
func withRemoteDirectConfig(cfg *config.RemoteDirect) Configuration {
|
||||
return func(settings *environment.AirshipCTLSettings) {
|
||||
bootstrapInfo, err := settings.Config.CurrentContextBootstrapInfo()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Unable to initialize remote direct tests. Current Context error %q", err))
|
||||
}
|
||||
|
||||
bootstrapInfo.RemoteDirect = cfg
|
||||
}
|
||||
}
|
||||
|
||||
func TestDoRemoteDirectMissingConfigOpts(t *testing.T) {
|
||||
ctx, rMock, err := redfishutils.NewClient(redfishURL, false, false, username, password)
|
||||
assert.NoError(t, err)
|
||||
@ -60,8 +46,12 @@ func TestDoRemoteDirectMissingConfigOpts(t *testing.T) {
|
||||
password,
|
||||
}
|
||||
|
||||
settings := initSettings(t, withRemoteDirectConfig(nil), withTestDataPath("base"))
|
||||
settings := initSettings(t, withTestDataPath("noremote"))
|
||||
// there must be document.ErrDocNotFound
|
||||
err = ephemeralHost.DoRemoteDirect(settings)
|
||||
expectedErrorMessage := `document filtered by selector [Group="airshipit.org", Version="v1alpha1", ` +
|
||||
`Kind="RemoteDirectConfiguration"] found no documents`
|
||||
assert.Equal(t, expectedErrorMessage, fmt.Sprintf("%s", err))
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
@ -81,10 +71,10 @@ func TestDoRemoteDirectMissingISOURL(t *testing.T) {
|
||||
password,
|
||||
}
|
||||
|
||||
cfg := &config.RemoteDirect{}
|
||||
|
||||
settings := initSettings(t, withRemoteDirectConfig(cfg), withTestDataPath("base"))
|
||||
settings := initSettings(t, withTestDataPath("noisourl"))
|
||||
err = ephemeralHost.DoRemoteDirect(settings)
|
||||
expectedErrorMessage := `missing option: isoURL`
|
||||
assert.Equal(t, expectedErrorMessage, fmt.Sprintf("%s", err))
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
@ -108,11 +98,7 @@ func TestDoRemoteDirectRedfish(t *testing.T) {
|
||||
password,
|
||||
}
|
||||
|
||||
cfg := &config.RemoteDirect{
|
||||
IsoURL: isoURL,
|
||||
}
|
||||
|
||||
settings := initSettings(t, withRemoteDirectConfig(cfg), withTestDataPath("base"))
|
||||
settings := initSettings(t, withTestDataPath("base"))
|
||||
err = ephemeralHost.DoRemoteDirect(settings)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
@ -138,11 +124,7 @@ func TestDoRemoteDirectRedfishNodePoweredOff(t *testing.T) {
|
||||
password,
|
||||
}
|
||||
|
||||
cfg := &config.RemoteDirect{
|
||||
IsoURL: isoURL,
|
||||
}
|
||||
|
||||
settings := initSettings(t, withRemoteDirectConfig(cfg), withTestDataPath("base"))
|
||||
settings := initSettings(t, withTestDataPath("base"))
|
||||
err = ephemeralHost.DoRemoteDirect(settings)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
@ -169,11 +151,7 @@ func TestDoRemoteDirectRedfishVirtualMediaError(t *testing.T) {
|
||||
password,
|
||||
}
|
||||
|
||||
cfg := &config.RemoteDirect{
|
||||
IsoURL: isoURL,
|
||||
}
|
||||
|
||||
settings := initSettings(t, withRemoteDirectConfig(cfg), withTestDataPath("base"))
|
||||
settings := initSettings(t, withTestDataPath("base"))
|
||||
|
||||
err = ephemeralHost.DoRemoteDirect(settings)
|
||||
_, ok := err.(redfish.ErrRedfishClient)
|
||||
@ -202,11 +180,7 @@ func TestDoRemoteDirectRedfishBootSourceError(t *testing.T) {
|
||||
password,
|
||||
}
|
||||
|
||||
cfg := &config.RemoteDirect{
|
||||
IsoURL: isoURL,
|
||||
}
|
||||
|
||||
settings := initSettings(t, withRemoteDirectConfig(cfg), withTestDataPath("base"))
|
||||
settings := initSettings(t, withTestDataPath("base"))
|
||||
|
||||
err = ephemeralHost.DoRemoteDirect(settings)
|
||||
_, ok := err.(redfish.ErrRedfishClient)
|
||||
@ -236,11 +210,7 @@ func TestDoRemoteDirectRedfishRebootError(t *testing.T) {
|
||||
password,
|
||||
}
|
||||
|
||||
cfg := &config.RemoteDirect{
|
||||
IsoURL: isoURL,
|
||||
}
|
||||
|
||||
settings := initSettings(t, withRemoteDirectConfig(cfg), withTestDataPath("base"))
|
||||
settings := initSettings(t, withTestDataPath("base"))
|
||||
|
||||
err = ephemeralHost.DoRemoteDirect(settings)
|
||||
_, ok := err.(redfish.ErrRedfishClient)
|
||||
|
@ -1,2 +1,3 @@
|
||||
resources:
|
||||
- baremetal.yaml
|
||||
- baremetal.yaml
|
||||
- remote_direct_configuration.yaml
|
||||
|
@ -0,0 +1,5 @@
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: RemoteDirectConfiguration
|
||||
metadata:
|
||||
name: default
|
||||
isoUrl: https://localhost:8080/ubuntu.iso
|
74
pkg/remote/testdata/noisourl/manifests/site/test-site/ephemeral/bootstrap/baremetal.yaml
vendored
Normal file
74
pkg/remote/testdata/noisourl/manifests/site/test-site/ephemeral/bootstrap/baremetal.yaml
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
---
|
||||
apiVersion: metal3.io/v1alpha1
|
||||
kind: BareMetalHost
|
||||
metadata:
|
||||
labels:
|
||||
airshipit.org/ephemeral-node: "true"
|
||||
name: master-0
|
||||
spec:
|
||||
online: true
|
||||
bootMACAddress: 00:3b:8b:0c:ec:8b
|
||||
bmc:
|
||||
address: redfish+http://nolocalhost:8888/redfish/v1/Systems/ephemeral
|
||||
credentialsName: master-0-bmc-secret
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
labels:
|
||||
airshipit.org/ephemeral-node: "true"
|
||||
name: master-0-bmc-secret
|
||||
type: Opaque
|
||||
data:
|
||||
username: YWRtaW4=
|
||||
password: cGFzc3dvcmQ=
|
||||
...
|
||||
---
|
||||
apiVersion: metal3.io/v1alpha1
|
||||
kind: BareMetalHost
|
||||
metadata:
|
||||
labels:
|
||||
airshipit.org/test-node: "true"
|
||||
name: master-1
|
||||
spec:
|
||||
online: true
|
||||
bootMACAddress: 00:3b:8b:0c:ec:8b
|
||||
bmc:
|
||||
address: redfish+http://nolocalhost:8888/redfish/v1/Systems/node-master-1
|
||||
credentialsName: master-1-bmc-secret
|
||||
---
|
||||
apiVersion: metal3.io/v1alpha1
|
||||
kind: BareMetalHost
|
||||
metadata:
|
||||
labels:
|
||||
airshipit.org/test-node: "true"
|
||||
name: master-2
|
||||
spec:
|
||||
online: true
|
||||
bootMACAddress: 00:3b:8b:0c:ec:8b
|
||||
bmc:
|
||||
address: redfish+http://nolocalhost:8888/redfish/v1/Systems/node-master-2
|
||||
credentialsName: master-1-bmc-secret
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
labels:
|
||||
airshipit.org/ephemeral-node: "true"
|
||||
name: master-1-bmc-secret
|
||||
type: Opaque
|
||||
data:
|
||||
username: YWRtaW4=
|
||||
password: cGFzc3dvcmQ=
|
||||
...
|
||||
---
|
||||
apiVersion: metal3.io/v1alpha1
|
||||
kind: BareMetalHost
|
||||
metadata:
|
||||
name: no-creds
|
||||
spec:
|
||||
online: true
|
||||
bootMACAddress: 00:3b:8b:0c:ec:8b
|
||||
bmc:
|
||||
address: redfish+http://nolocalhost:8888/redfish/v1/Systems/test-node
|
||||
...
|
3
pkg/remote/testdata/noisourl/manifests/site/test-site/ephemeral/bootstrap/kustomization.yaml
vendored
Normal file
3
pkg/remote/testdata/noisourl/manifests/site/test-site/ephemeral/bootstrap/kustomization.yaml
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
resources:
|
||||
- baremetal.yaml
|
||||
- remote_direct_configuration.yaml
|
@ -0,0 +1,4 @@
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: RemoteDirectConfiguration
|
||||
metadata:
|
||||
name: default
|
74
pkg/remote/testdata/noremote/manifests/site/test-site/ephemeral/bootstrap/baremetal.yaml
vendored
Normal file
74
pkg/remote/testdata/noremote/manifests/site/test-site/ephemeral/bootstrap/baremetal.yaml
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
---
|
||||
apiVersion: metal3.io/v1alpha1
|
||||
kind: BareMetalHost
|
||||
metadata:
|
||||
labels:
|
||||
airshipit.org/ephemeral-node: "true"
|
||||
name: master-0
|
||||
spec:
|
||||
online: true
|
||||
bootMACAddress: 00:3b:8b:0c:ec:8b
|
||||
bmc:
|
||||
address: redfish+http://nolocalhost:8888/redfish/v1/Systems/ephemeral
|
||||
credentialsName: master-0-bmc-secret
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
labels:
|
||||
airshipit.org/ephemeral-node: "true"
|
||||
name: master-0-bmc-secret
|
||||
type: Opaque
|
||||
data:
|
||||
username: YWRtaW4=
|
||||
password: cGFzc3dvcmQ=
|
||||
...
|
||||
---
|
||||
apiVersion: metal3.io/v1alpha1
|
||||
kind: BareMetalHost
|
||||
metadata:
|
||||
labels:
|
||||
airshipit.org/test-node: "true"
|
||||
name: master-1
|
||||
spec:
|
||||
online: true
|
||||
bootMACAddress: 00:3b:8b:0c:ec:8b
|
||||
bmc:
|
||||
address: redfish+http://nolocalhost:8888/redfish/v1/Systems/node-master-1
|
||||
credentialsName: master-1-bmc-secret
|
||||
---
|
||||
apiVersion: metal3.io/v1alpha1
|
||||
kind: BareMetalHost
|
||||
metadata:
|
||||
labels:
|
||||
airshipit.org/test-node: "true"
|
||||
name: master-2
|
||||
spec:
|
||||
online: true
|
||||
bootMACAddress: 00:3b:8b:0c:ec:8b
|
||||
bmc:
|
||||
address: redfish+http://nolocalhost:8888/redfish/v1/Systems/node-master-2
|
||||
credentialsName: master-1-bmc-secret
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
labels:
|
||||
airshipit.org/ephemeral-node: "true"
|
||||
name: master-1-bmc-secret
|
||||
type: Opaque
|
||||
data:
|
||||
username: YWRtaW4=
|
||||
password: cGFzc3dvcmQ=
|
||||
...
|
||||
---
|
||||
apiVersion: metal3.io/v1alpha1
|
||||
kind: BareMetalHost
|
||||
metadata:
|
||||
name: no-creds
|
||||
spec:
|
||||
online: true
|
||||
bootMACAddress: 00:3b:8b:0c:ec:8b
|
||||
bmc:
|
||||
address: redfish+http://nolocalhost:8888/redfish/v1/Systems/test-node
|
||||
...
|
2
pkg/remote/testdata/noremote/manifests/site/test-site/ephemeral/bootstrap/kustomization.yaml
vendored
Normal file
2
pkg/remote/testdata/noremote/manifests/site/test-site/ephemeral/bootstrap/kustomization.yaml
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
resources:
|
||||
- baremetal.yaml
|
@ -46,9 +46,6 @@ func DummyConfig() *config.Config {
|
||||
DirectoryPermission: config.AirshipDefaultDirectoryPermission,
|
||||
FilePermission: config.AirshipDefaultFilePermission,
|
||||
},
|
||||
BootstrapInfo: map[string]*config.Bootstrap{
|
||||
"dummy_bootstrap_config": DummyBootstrapInfo(),
|
||||
},
|
||||
Contexts: map[string]*config.Context{
|
||||
"dummy_context": DummyContext(),
|
||||
},
|
||||
@ -92,7 +89,6 @@ func DummyCluster() *config.Cluster {
|
||||
cluster.CertificateAuthority = "dummy_ca"
|
||||
c.SetKubeCluster(cluster)
|
||||
c.NameInKubeconf = "dummy_cluster_target"
|
||||
c.Bootstrap = "dummy_bootstrap_config"
|
||||
c.ManagementConfiguration = "dummy_management_config"
|
||||
return c
|
||||
}
|
||||
@ -227,26 +223,6 @@ func DummyAuthInfoOptions() *config.AuthInfoOptions {
|
||||
return authinfo
|
||||
}
|
||||
|
||||
// DummyBootstrapInfo creates a dummy BootstrapInfo config object for unit testing
|
||||
func DummyBootstrapInfo() *config.Bootstrap {
|
||||
bs := &config.Bootstrap{}
|
||||
cont := config.Container{
|
||||
Volume: "/dummy:dummy",
|
||||
Image: "dummy_image:dummy_tag",
|
||||
ContainerRuntime: "docker",
|
||||
}
|
||||
builder := config.Builder{
|
||||
UserDataFileName: "user-data",
|
||||
NetworkConfigFileName: "netconfig",
|
||||
OutputMetadataFileName: "output-metadata.yaml",
|
||||
}
|
||||
|
||||
bs.Container = &cont
|
||||
bs.Builder = &builder
|
||||
|
||||
return bs
|
||||
}
|
||||
|
||||
// DummyManagementConfiguration creates a management configuration for unit testing
|
||||
func DummyManagementConfiguration() *config.ManagementConfiguration {
|
||||
return &config.ManagementConfiguration{
|
||||
@ -283,22 +259,18 @@ clusters:
|
||||
def:
|
||||
clusterType:
|
||||
ephemeral:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: def_ephemeral
|
||||
target:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: def_target
|
||||
onlyinkubeconf:
|
||||
clusterType:
|
||||
target:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: onlyinkubeconf_target
|
||||
wrongonlyinconfig:
|
||||
clusterType: {}
|
||||
wrongonlyinkubeconf:
|
||||
clusterType:
|
||||
target:
|
||||
bootstrapInfo: ""
|
||||
clusterKubeconf: wrongonlyinkubeconf_target
|
||||
clustertypenil:
|
||||
clusterType: null
|
||||
|
@ -54,18 +54,6 @@ function generate_airshipconf {
|
||||
|
||||
cat <<EOL > ${AIRSHIPCONFIG}
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
bootstrapInfo:
|
||||
default:
|
||||
builder:
|
||||
networkConfigFileName: network-config
|
||||
outputMetadataFileName: output-metadata.yaml
|
||||
userDataFileName: user-data
|
||||
container:
|
||||
containerRuntime: docker
|
||||
image: quay.io/airshipit/isogen:latest-ubuntu_focal
|
||||
volume: /srv/iso:/config
|
||||
remoteDirect:
|
||||
isoUrl: http://localhost:8099/ubuntu-focal.iso
|
||||
clusters:
|
||||
${CONTEXT}_${cluster}:
|
||||
clusterType:
|
||||
|
Loading…
Reference in New Issue
Block a user